1532 lines
30 KiB
CSS
1532 lines
30 KiB
CSS
:root {
|
|
/* Make it easy for stuff to match the width of <body> */
|
|
--width-body-margins: 30%;
|
|
|
|
/**********
|
|
* Colors
|
|
**********/
|
|
--color-twitter-blue: hsl(204, 78%, 49%);
|
|
--color-twitter-blue-light: hsl(204, 87%, 73%);
|
|
--color-twitter-blue-extra-light: hsl(204, 95%, 85%);
|
|
|
|
--color-twitter-off-white: hsl(180, 14%, 97%);
|
|
--color-twitter-off-white-dark: hsl(180, 17%, 88%);
|
|
--color-outline-gray: hsl(204, 0%, 86%);
|
|
--color-twitter-text-gray: hsl(204, 15%, 38%);
|
|
|
|
--color-twitter-danger-red: hsl(356, 91%, 54%);
|
|
--color-twitter-danger-red2: hsl(356, 78%, 49%);
|
|
--color-twitter-danger-red2-light: hsl(356, 87%, 73%);
|
|
--color-twitter-danger-red2-hover: hsl(356, 75%, 80%);
|
|
|
|
--color-space-purple: hsl(246, 96%, 80%);
|
|
--color-space-purple-outline: hsl(246, 97%, 65%);
|
|
}
|
|
|
|
|
|
/***************************************************************************************************
|
|
*
|
|
* Base styles
|
|
* -----------
|
|
*
|
|
* Page global / default styles. Should only use tag selectors or attribute selectors. No ID or
|
|
* class selectors; those are purpose-specific, i.e., non-default.
|
|
*
|
|
***************************************************************************************************/
|
|
|
|
html {
|
|
/*
|
|
* Force scrollbar, even when it fits on 1 page. Prevents viewport from resizing -> flickering
|
|
* and stuff moving between page loads
|
|
*/
|
|
overflow-y: scroll;
|
|
}
|
|
body {
|
|
/* So that toasts can be positioned relative to `body` (rather than `html`).
|
|
* This is useful because it wil then use the `body`'s width (i.e., accounting for the big fat margins).
|
|
*/
|
|
position: relative;
|
|
|
|
margin: 0 var(--width-body-margins);
|
|
min-height: 100vh;
|
|
|
|
border-color: var(--color-twitter-off-white-dark);
|
|
border-right-style: solid;
|
|
border-left-style: solid;
|
|
border-width: 1px;
|
|
|
|
font-family: "Titillium Web";
|
|
}
|
|
input, select {
|
|
font-family: inherit;
|
|
font-size: 1em;
|
|
padding: 0.2em 0.6em;
|
|
box-sizing: border-box;
|
|
border-radius: 0.5em;
|
|
}
|
|
input[type="submit"] {
|
|
background-color: var(--color-twitter-blue-light);
|
|
width: 10em;
|
|
border-radius: 1em;
|
|
font-size: 1em;
|
|
cursor: pointer;
|
|
}
|
|
a {
|
|
text-decoration: none;
|
|
color: inherit;
|
|
cursor: pointer;
|
|
}
|
|
ul {
|
|
list-style: none;
|
|
}
|
|
h1 {
|
|
margin: 0.5em 0;
|
|
text-align: center;
|
|
}
|
|
h3 {
|
|
margin: 0.5em 0;
|
|
}
|
|
|
|
|
|
/***************************************************************************************************
|
|
*
|
|
* Utility styles
|
|
* --------------
|
|
*
|
|
* Generic or reusable styles. Should use only class selectors. Should *not* actually be modules
|
|
* (anything application specific).
|
|
*
|
|
***************************************************************************************************/
|
|
|
|
.row {
|
|
display: flex;
|
|
flex-direction: row;
|
|
align-items: center;
|
|
}
|
|
.row--spread {
|
|
justify-content: space-between;
|
|
}
|
|
|
|
/* A list of items separated by interpuncts */
|
|
.inline-dotted-list {
|
|
margin: 0;
|
|
|
|
& > * {
|
|
display: inline;
|
|
}
|
|
& > *:after {
|
|
content: " ⋅";
|
|
}
|
|
& > *:last-child:after {
|
|
content: "";
|
|
}
|
|
}
|
|
|
|
.rounded-gray-outline {
|
|
outline-color: lightgray;
|
|
outline-style: solid;
|
|
outline-width: 1px;
|
|
overflow: hidden;
|
|
border-radius: 1.5em;
|
|
}
|
|
|
|
.circle-outline {
|
|
display: flex;
|
|
border-radius: 50%;
|
|
outline: 1px solid #777;
|
|
margin: 0 0.4em;
|
|
font-size: 0.8em;
|
|
padding: 0.2em;
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
.button {
|
|
display: flex; /* Prevent <a class="button"><img></a> from having extra space at the bottom, looking weird*/
|
|
padding: 0.5em;
|
|
margin: 0.2em;
|
|
border-radius: 100em; /* any large amount, just don't use % because then it makes an ellipse */
|
|
cursor: pointer;
|
|
|
|
&:hover {
|
|
background-color: var(--color-twitter-blue-light);
|
|
}
|
|
&:active {
|
|
transform: translate(0.1em, 0.1em);
|
|
background-color: var(--color-twitter-blue);
|
|
}
|
|
|
|
&.button--danger {
|
|
background-color: var(--color-twitter-danger-red2);
|
|
|
|
&:hover {
|
|
background-color: var(--color-twitter-danger-red2-light);
|
|
}
|
|
&:active {
|
|
background-color: var(--color-twitter-danger-red2);
|
|
}
|
|
}
|
|
}
|
|
|
|
.labelled-icon {
|
|
display: flex;
|
|
flex-direction: row;
|
|
align-items: center;
|
|
|
|
& label {
|
|
padding: 0 0.3em;
|
|
white-space: nowrap;
|
|
cursor: unset; /* <label> sets cursor to "default" by default */
|
|
}
|
|
}
|
|
|
|
.svg-icon {
|
|
width: 1.5em;
|
|
height: auto;
|
|
}
|
|
|
|
.disappearing {
|
|
transition: opacity 2s ease;
|
|
opacity: 0;
|
|
}
|
|
|
|
|
|
/***************************************************************************************************
|
|
*
|
|
* Layout styles
|
|
* -------------
|
|
*
|
|
* Major page elements. Can use semantic HTML tag names and IDs. Class selectors are for modules.
|
|
*
|
|
***************************************************************************************************/
|
|
|
|
header {
|
|
/* Sticky to top of page */
|
|
position: fixed;
|
|
z-index: 2; /* Pin icon in a pinned tweet has z-index=1 */
|
|
|
|
/* Match layout width of `body` */
|
|
left: var(--width-body-margins);
|
|
right: var(--width-body-margins);
|
|
|
|
height: 4em;
|
|
padding: 0.5em 1em;
|
|
border: 1px solid var(--color-outline-gray);
|
|
box-sizing: border-box;
|
|
|
|
background-color: white;
|
|
}
|
|
|
|
main {
|
|
/* Space taken up by the header search bar */
|
|
padding-top: 4em;
|
|
}
|
|
|
|
#nav-sidebar {
|
|
display: flex;
|
|
flex-direction: column;
|
|
position: fixed;
|
|
transform: translate(-100%, 0);
|
|
font-size: 1.4em;
|
|
}
|
|
|
|
/**
|
|
* Layout for the Messages page
|
|
*/
|
|
.messages-page {
|
|
display: flex;
|
|
flex-direction: row;
|
|
|
|
/** Setup to allow the two panes to scroll independently **/
|
|
height: 100vh;
|
|
padding-top: 4em;
|
|
margin-top: -4em;
|
|
box-sizing: border-box;
|
|
|
|
.chat-list {
|
|
flex-basis: 0;
|
|
flex-grow: 4;
|
|
display: flex;
|
|
flex-direction: column;
|
|
overflow-y: scroll;
|
|
}
|
|
#chat-view {
|
|
flex-basis: 0;
|
|
flex-grow: 7;
|
|
border-left: 1px solid var(--color-outline-gray);
|
|
box-sizing: border-box;
|
|
display: flex;
|
|
flex-direction: column;
|
|
|
|
/* To position the participants list page */
|
|
position: relative;
|
|
|
|
.chat-messages {
|
|
flex-grow: 1;
|
|
overflow-y: auto;
|
|
padding: 0 0.5em;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Layout for the Login page
|
|
*/
|
|
.login-page {
|
|
width: 60%;
|
|
margin: 5% auto;
|
|
|
|
& hr {
|
|
margin: 3em 2em;
|
|
}
|
|
}
|
|
|
|
|
|
/***************************************************************************************************
|
|
*
|
|
* Module styles
|
|
* -------------
|
|
*
|
|
* Normal page elements. Should only use classes; no IDs or tag names.
|
|
*
|
|
***************************************************************************************************/
|
|
|
|
|
|
/******************************************************
|
|
* General modules
|
|
******************************************************/
|
|
|
|
/**
|
|
* Toast notification popup that gets sent on HTTP 500
|
|
*/
|
|
.toast {
|
|
border-radius: 1em;
|
|
padding: 1em;
|
|
text-align: center;
|
|
word-wrap: break-word;
|
|
margin: 1em;
|
|
width: 90%;
|
|
|
|
/* Default: use "success" toast */
|
|
background-color: #efe;
|
|
border: 1px solid green;
|
|
color: green;
|
|
|
|
&.toast--error {
|
|
color: red;
|
|
background-color: #fee;
|
|
border-color: red;
|
|
}
|
|
&.toast--warning {
|
|
color: hsl(50.59deg 75% 40%);
|
|
background-color: #ffe;
|
|
border-color: hsl(50.59deg 75% 40%);
|
|
}
|
|
}
|
|
.toasts {
|
|
position: fixed;
|
|
left: var(--width-body-margins);
|
|
top: 10em;
|
|
right: var(--width-body-margins);
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
}
|
|
|
|
/**
|
|
* HTMX spinner module
|
|
*/
|
|
.htmx-spinner {
|
|
/* Hidden by default, unless `.htmx-request` is active on parent component */
|
|
display: none;
|
|
|
|
/* Cover the parent element completely */
|
|
position: absolute;
|
|
top: 0;
|
|
bottom: 0;
|
|
left: 0;
|
|
right: 0;
|
|
z-index: 2; /* On top of the search bar, which is z-index of 1 */
|
|
|
|
font-size: 3em;
|
|
|
|
/* When `.htmx-request` is applied to the parent element, show the spinner */
|
|
.htmx-request > & {
|
|
display: revert;
|
|
}
|
|
|
|
.htmx-spinner__fullscreen-forcer {
|
|
/*
|
|
* This can optionally be stuck inside a `.htmx-spinner` to make its contents sticky to
|
|
* full-screen size. Child elements will be positioned according to this rather than to the
|
|
* `.htmx-spinner` element.
|
|
*/
|
|
position: fixed;
|
|
top: 0;
|
|
height: 100vh;
|
|
left: var(--width-body-margins);
|
|
right: var(--width-body-margins);
|
|
}
|
|
.htmx-spinner__background {
|
|
opacity: 0.3;
|
|
background-color: #7cc5f6;
|
|
width: 100%;
|
|
height: 100%;
|
|
}
|
|
.htmx-spinner__icon {
|
|
/* Put the icon in the middle of the HTMX overlay */
|
|
position: absolute;
|
|
top: 50%;
|
|
left: 50%;
|
|
transform: translate(-50%,-50%);
|
|
|
|
/* https://codepen.io/sosuke/pen/Pjoqqp */
|
|
filter: invert(54%) sepia(17%) saturate(4210%) hue-rotate(176deg) brightness(89%) contrast(98%);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Image carousel module
|
|
*/
|
|
.image-carousel {
|
|
border-radius: 2em;
|
|
border: 0.3em solid var(--color-twitter-blue);
|
|
box-shadow: 0 0 1em var(--color-twitter-blue);
|
|
outline: none;
|
|
overflow: visible;
|
|
padding: 0;
|
|
line-height: 0;
|
|
|
|
.image-carousel__padding {
|
|
padding: 1.4em;
|
|
}
|
|
|
|
&::backdrop {
|
|
background: hsla(204, 87%, 73%, 0.3); /* based on --color-twitter-blue-light */
|
|
}
|
|
.image-carousel__close-button {
|
|
position: absolute;
|
|
right: -1.3em;
|
|
top: -1.5em;
|
|
|
|
width: 1em;
|
|
line-height: 1em;
|
|
font-size: 2em;
|
|
justify-content: center;
|
|
border: 0.1em solid black;
|
|
}
|
|
.image-carousel__close-button:not(:hover):not(:active) {
|
|
background-color: var(--color-twitter-blue-extra-light);
|
|
}
|
|
.image-carousel__active-image {
|
|
max-height: 85vh;
|
|
max-width: 90vw;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Tabs module
|
|
*/
|
|
.tabs {
|
|
margin-top: 2px;
|
|
border-top: 1px solid var(--color-outline-gray);
|
|
border-bottom: 1px solid var(--color-outline-gray);
|
|
|
|
.tabs__tab {
|
|
flex-grow: 1;
|
|
text-align: center;
|
|
font-size: 1.1em;
|
|
font-weight: bold;
|
|
color: var(--color-twitter-text-gray);
|
|
padding: 0.8em;
|
|
|
|
&:hover {
|
|
color: var(--color-twitter-blue);
|
|
}
|
|
}
|
|
|
|
.tabs__tab--active {
|
|
color: var(--color-twitter-blue);
|
|
border-bottom: 0.2em solid var(--color-twitter-blue);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Clickable entities
|
|
*/
|
|
.entity {
|
|
color: var(--color-twitter-blue);
|
|
}
|
|
|
|
/**
|
|
* Text module. For both Tweets and DM messages
|
|
*/
|
|
.text {
|
|
display: block;
|
|
margin-bottom: 0.5em;
|
|
margin-top: 0;
|
|
overflow-wrap: anywhere;
|
|
cursor: text;
|
|
/* Prevent empty paragraphs from being collapsed into each other (i.e., `margin-bottom`s overlapping) */
|
|
padding-bottom: 0.1em;
|
|
|
|
&:last-child {
|
|
margin-bottom: 0;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Profile image module
|
|
*/
|
|
.profile-image {
|
|
line-height: 0;
|
|
|
|
.profile-image__image {
|
|
border-radius: 50%;
|
|
width: 3em;
|
|
height: 3em;
|
|
display: inline;
|
|
border: 0.1em solid var(--color-outline-gray);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Author info module
|
|
*/
|
|
.author-info {
|
|
display: flex;
|
|
align-items: center;
|
|
cursor: default;
|
|
|
|
.author-info__name-and-handle {
|
|
padding: 0 0.6em !important; /* !important to make the ".button .span" rule in the login button not overrule it */
|
|
}
|
|
.author-info__display-name {
|
|
font-weight: bold;
|
|
white-space: nowrap;
|
|
}
|
|
.author-info__handle {
|
|
color: var(--color-twitter-text-gray);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* List (i.e.,, of users) module
|
|
*/
|
|
.users-list {
|
|
display: flex;
|
|
flex-direction: column;
|
|
border-color: var(--color-twitter-off-white-dark);
|
|
border-top-style: double;
|
|
border-width: 4px;
|
|
|
|
.author-info .profile-image__image {
|
|
width: 4em;
|
|
height: 4em;
|
|
}
|
|
.user {
|
|
border-color: var(--color-twitter-off-white-dark);
|
|
border-bottom-style: solid;
|
|
border-width: 1px;
|
|
padding: 1em;
|
|
}
|
|
.user p.bio {
|
|
margin: 0 5.3em;
|
|
font-size: 0.9em;
|
|
color: var(--color-twitter-text-gray);
|
|
}
|
|
}
|
|
|
|
/******************************************************
|
|
* Tweets
|
|
******************************************************/
|
|
|
|
/**
|
|
* Tweet module
|
|
*/
|
|
.tweet, .notification {
|
|
padding: 0 1.5em;
|
|
position: relative;
|
|
z-index: 0; /* Dunno why, but without it, hovering a tweet with a Poll hides the poll fill bars */
|
|
overflow: hidden; /* Otherwise HTMX spinner sticks over the rounded edges in a quoted tweet */
|
|
|
|
/**
|
|
* Set padding and borders around the tweet based on what type of tweet it is, and where it occurs
|
|
*/
|
|
.timeline &, .tweet__quoted-tweet &, .dm-message & {
|
|
/* Timeline tweets and quoted tweets, but not tweets in a thread */
|
|
/* TODO: what about DM tweet-previews? */
|
|
padding-top: 0.6em;
|
|
padding-bottom: 0.6em;
|
|
}
|
|
/**
|
|
* Create some extra space for the pin icon at the top of a pinned tweet
|
|
*/
|
|
.pinned-tweet & {
|
|
margin-top: -2em;
|
|
padding-top: 1.5em;
|
|
}
|
|
.timeline > &, .pinned-tweet & {
|
|
/* not for nested (i.e., quoted) tweets */
|
|
border-bottom: 1px solid var(--color-twitter-off-white-dark);
|
|
}
|
|
|
|
/**
|
|
* Mouse-over effects
|
|
*/
|
|
:not(.focused-tweet) > &:hover:not(:has(&:hover)) {
|
|
/* Add mouse-over background effect */
|
|
background-color: var(--color-twitter-off-white);
|
|
}
|
|
:not(.focused-tweet) > & {
|
|
/* Clickable tweets should make the cursor indicate an on-click action ("pointer" cursor) */
|
|
cursor: pointer;
|
|
}
|
|
|
|
.tweet__header-container {
|
|
display: flex;
|
|
align-items: center;
|
|
}
|
|
|
|
.tweet__vertical-container {
|
|
flex-grow: 1;
|
|
flex-shrink: 1;
|
|
}
|
|
|
|
/**
|
|
* Tweet content
|
|
*/
|
|
.tweet__embedded-image {
|
|
max-width: 95%;
|
|
max-height: 30em;
|
|
width: auto;
|
|
height: auto;
|
|
}
|
|
& video {
|
|
max-height: 25em;
|
|
max-width: 100%;
|
|
}
|
|
.tombstone {
|
|
outline: 1px solid var(--color-outline-gray);
|
|
background-color: var(--color-twitter-off-white);
|
|
padding: 0.5em 1em;
|
|
border-radius: 0.5em;
|
|
color: var(--color-twitter-text-gray);
|
|
}
|
|
.tweet__quoted-tweet {
|
|
margin: 1em 0;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Video module
|
|
*/
|
|
.video {
|
|
position: relative;
|
|
display: flex;
|
|
width: fit-content;
|
|
border-radius: 1.5em;
|
|
overflow: hidden;
|
|
|
|
.video__gif-controls {
|
|
position: absolute;
|
|
bottom: 1.2em;
|
|
left: 1em;
|
|
background-color: #999;
|
|
font-weight: bold;
|
|
padding: 0 0.2em 0 0.4em;
|
|
border-radius: 0.3em;
|
|
border: 1px solid #444;
|
|
|
|
.svg-icon {
|
|
font-size: 0.6em;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Retweet info module
|
|
*/
|
|
.retweet-info {
|
|
margin-left: 3.5em;
|
|
display: flex;
|
|
align-items: center;
|
|
opacity: 0.8;
|
|
cursor: default;
|
|
|
|
.retweet-info__retweeted-by-label {
|
|
margin: 0 0.2em 0 0.5em;
|
|
}
|
|
.svg-icon {
|
|
width: 1.2em; /* override default from .svg-icon of 1.5em */
|
|
opacity: 0.6; /* Probably not the right way to change the color from black to gray */
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Reply-mentions module
|
|
*/
|
|
.reply-mentions {
|
|
display: flex;
|
|
align-items: center;
|
|
cursor: default;
|
|
flex-grow: 1;
|
|
justify-content: center;
|
|
flex-wrap: wrap;
|
|
|
|
.reply-mentions__list {
|
|
padding: 0 0.5em;
|
|
}
|
|
.reply-mentions__dm-message__replying-to-label {
|
|
color: var(--color-twitter-text-gray);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Embedded link module
|
|
*/
|
|
.embedded-link {
|
|
padding: 1.3em;
|
|
margin-top: 1em;
|
|
display: flex;
|
|
flex-direction: column;
|
|
background-color: var(--color-twitter-off-white);
|
|
|
|
.embedded-link__preview-image {
|
|
border-radius: 1em;
|
|
max-width: 100%;
|
|
height: auto; /* preserve aspect ratio */
|
|
}
|
|
.embedded-link__description {
|
|
color: var(--color-twitter-text-gray);
|
|
font-size: 0.8em;
|
|
margin: 0;
|
|
}
|
|
.embedded-link__domain {
|
|
margin-top: 0.2em;
|
|
}
|
|
.embedded-link__domain__contents {
|
|
margin-left: 0.3em;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Poll module
|
|
*/
|
|
.poll {
|
|
padding: 1em;
|
|
|
|
.poll__choice {
|
|
position: relative;
|
|
margin: 0.3em 0;
|
|
}
|
|
.poll__choice-info {
|
|
width: 100%;
|
|
line-height: 2em;
|
|
margin: 0 0.5em;
|
|
}
|
|
.poll__choice-label {
|
|
width: 50%;
|
|
}
|
|
.poll__choice-votes {
|
|
width: 50%;
|
|
}
|
|
.poll__choice-fill-bar {
|
|
position: absolute;
|
|
height: 100%;
|
|
z-index: -1;
|
|
background-color: var(--color-twitter-off-white-dark);
|
|
|
|
&.poll__choice-fill-bar--winner {
|
|
background-color: var(--color-twitter-blue-light);
|
|
}
|
|
}
|
|
.poll__metadata {
|
|
color: var(--color-twitter-text-gray);
|
|
margin: 0;
|
|
font-size: 0.9em;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Space module
|
|
*/
|
|
.space {
|
|
outline: 1px solid var(--color-space-purple-outline);
|
|
background-color: var(--color-space-purple);
|
|
border-radius: 1.5em;
|
|
padding: 1.5em;
|
|
|
|
.space__title {
|
|
padding-top: 0.5em;
|
|
}
|
|
.space__host__label {
|
|
color: var(--color-space-purple-outline);
|
|
}
|
|
.space__date {
|
|
color: var(--color-space-purple-outline);
|
|
font-size: 0.8em;
|
|
}
|
|
.space__info__list {
|
|
padding: 0;
|
|
}
|
|
.space__layout-spacer {
|
|
flex-grow: 1;
|
|
}
|
|
|
|
.space__participants-list {
|
|
padding: 0;
|
|
|
|
/* List items */
|
|
& > * {
|
|
padding: 0.5em 0;
|
|
display: inline-block;
|
|
width: 24%;
|
|
font-size: 0.9em;
|
|
line-height: 1.2em;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Posted-at module
|
|
*/
|
|
.posted-at {
|
|
flex-grow: 1;
|
|
min-width: 5em;
|
|
width: fit-content;
|
|
|
|
.posted-at__text {
|
|
float: right;
|
|
color: var(--color-twitter-text-gray);
|
|
font-size: 0.875em;
|
|
white-space: nowrap;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Interactions bar module
|
|
*/
|
|
.interactions {
|
|
display: flex;
|
|
flex-direction: row;
|
|
margin: 0.5em 0;
|
|
|
|
.interactions__stat {
|
|
flex-grow: 1;
|
|
display: flex;
|
|
|
|
& span {
|
|
line-height: 1.5em;
|
|
padding: 0 0.5em;
|
|
}
|
|
}
|
|
|
|
/* Empty <div> used to make the spacing more good */
|
|
.interactions__dummy {
|
|
flex-grow: 5;
|
|
}
|
|
|
|
.interactions__like-icon {
|
|
cursor: pointer;
|
|
&.liked, &:hover {
|
|
filter: invert(20%) sepia(97%) saturate(4383%) hue-rotate(321deg) brightness(101%) contrast(95%);
|
|
}
|
|
}
|
|
|
|
/* Make the buttons slightly smaller */
|
|
.button {
|
|
margin: 0;
|
|
font-size: 0.8em;
|
|
}
|
|
}
|
|
|
|
/******************************************************
|
|
* Conversation thread / tweet detail
|
|
******************************************************/
|
|
|
|
.tweet-detail {
|
|
& :first-child > .tweet {
|
|
/* The tweet at the top of a thread should have some top-padding */
|
|
padding-top: 1em;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Focused tweets
|
|
*/
|
|
.focused-tweet {
|
|
& > .tweet {
|
|
border-bottom: 1px solid var(--color-twitter-off-white-dark);
|
|
padding-bottom: 0.5em;
|
|
}
|
|
|
|
/* Make font bigger in focused tweets, unless it's in a quoted tweet */
|
|
.text {
|
|
font-size: 1.4em;
|
|
}
|
|
.tweet__quoted-tweet .text {
|
|
font-size: unset;
|
|
}
|
|
}
|
|
|
|
.reply-chain > :last-child > .tweet {
|
|
/* Last tweet in a reply chain should have bottom-padding */
|
|
padding-bottom: 1em;
|
|
border-bottom: 1px solid var(--color-twitter-off-white-dark);
|
|
}
|
|
|
|
/**
|
|
* Threaded conversation string (visual thread indicator) module
|
|
*/
|
|
.string-box {
|
|
width: 3em;
|
|
margin-right: 0.5em;
|
|
flex-grow: 0;
|
|
flex-shrink: 0;
|
|
|
|
/* Make the .string take up 100% of vertical space */
|
|
flex-direction: column;
|
|
align-self: stretch;
|
|
|
|
/* Only show it in parent threads and reply chains */
|
|
display: none;
|
|
.thread-parent-tweet &, .reply-chain & {
|
|
/* Not if it's in a quoted tweet */
|
|
&:not(.tweet__quoted-tweet &) {
|
|
display: flex; /* Show it */
|
|
}
|
|
}
|
|
|
|
.string {
|
|
width: 2px;
|
|
flex-grow: 1;
|
|
margin: auto;
|
|
background-color: var(--color-twitter-off-white-dark);
|
|
|
|
/* All parent tweets, and all but the last reply */
|
|
display: none;
|
|
.thread-parent-tweet &, .reply-chain > :not(:last-child) & {
|
|
display: revert;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/******************************************************
|
|
* Timeline
|
|
******************************************************/
|
|
|
|
/**
|
|
* Show more button and EOF indicator module
|
|
*/
|
|
.show-more {
|
|
text-align: center;
|
|
font-size: 1.2em;
|
|
padding: 1em 0;
|
|
.show-more__eof-label {
|
|
color: var(--color-twitter-text-gray);
|
|
}
|
|
.show-more__button {
|
|
padding: 0em 0.8em;
|
|
display: inline-block;
|
|
border: 2px solid var(--color-twitter-blue);
|
|
color: var(--color-twitter-text-gray);
|
|
font-size: 0.9em;
|
|
|
|
&:not(:hover):not(:active) {
|
|
/* TODO: maybe this should be a reusable button style */
|
|
background-color: var(--color-twitter-blue-extra-light);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/******************************************************
|
|
* Notifications
|
|
******************************************************/
|
|
|
|
.notifications-header {
|
|
border-bottom: 1px solid var(--color-outline-gray);
|
|
}
|
|
|
|
/**
|
|
* Notification module
|
|
*/
|
|
.notification {
|
|
.notification__users {
|
|
font-size: 0.8em; /* Make the profile images smaller */
|
|
}
|
|
}
|
|
|
|
|
|
/******************************************************
|
|
* Navigation and base page
|
|
******************************************************/
|
|
|
|
/**
|
|
* Nav-sidebar module
|
|
*/
|
|
.nav-sidebar {
|
|
.nav-sidebar__buttons {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: flex-start;
|
|
padding: 0 2em;
|
|
}
|
|
/* Enable positioning the notifications indicator relative to this */
|
|
.labelled-icon {
|
|
position: relative;
|
|
}
|
|
.nav-sidebar__notifications-count {
|
|
position: absolute;
|
|
left: 0.3em;
|
|
top: 0.3em;
|
|
background-color: var(--color-twitter-blue);
|
|
min-width: 1em;
|
|
line-height: 1em;
|
|
/* height: 1.2em; */
|
|
border-radius: 1em;
|
|
font-size: 0.7em;
|
|
color: white;
|
|
text-align: center;
|
|
padding: 0.2em;
|
|
}
|
|
#logged-in-user-info {
|
|
font-size: 0.8em;
|
|
margin-top: 1em;
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
}
|
|
|
|
.button .author-info {
|
|
pointer-events: none;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Search bar module
|
|
*/
|
|
.search-bar {
|
|
.search-bar__back-button {
|
|
flex-grow: 0;
|
|
border-radius: 50%;
|
|
border: 2px solid black;
|
|
width: 2em;
|
|
position: relative;
|
|
height: 2em;
|
|
box-sizing: border-box;
|
|
cursor: pointer;
|
|
|
|
& img {
|
|
color: rgb(239, 243, 244);
|
|
position: absolute;
|
|
top: 50%;
|
|
left: 50%;
|
|
transform: translate(-50%, -50%);
|
|
}
|
|
}
|
|
.search-bar__form {
|
|
margin-left: 1em;
|
|
flex-grow: 1;
|
|
display: flex;
|
|
}
|
|
.search-bar__input {
|
|
flex-grow: 1;
|
|
}
|
|
}
|
|
|
|
/******************************************************
|
|
* User feeds
|
|
******************************************************/
|
|
|
|
/**
|
|
* User-feed header module
|
|
*/
|
|
.user-header {
|
|
border-bottom: 1px solid var(--color-outline-gray);
|
|
|
|
.user-header__profile-banner-image {
|
|
width: 100%;
|
|
}
|
|
|
|
.user-header__info-container {
|
|
padding: 2em;
|
|
}
|
|
|
|
.user-header__bio {
|
|
margin: 1.5em 0;
|
|
}
|
|
|
|
/* Special settings for profile images in user headers */
|
|
.author-info {
|
|
font-size: 1.3em;
|
|
padding: 1em;
|
|
}
|
|
.profile-image__image {
|
|
width: 8em;
|
|
height: 8em;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Followers + followees module
|
|
*/
|
|
.followers-followees {
|
|
margin-top: 1em;
|
|
gap: 4em;
|
|
|
|
.followers-followees__count {
|
|
font-weight: bold;
|
|
}
|
|
& label {
|
|
color: var(--color-twitter-text-gray);
|
|
cursor: unset;
|
|
}
|
|
.spacer {
|
|
flex-grow: 1;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Pinned tweet mini-module
|
|
*/
|
|
.pinned-tweet__pin-container {
|
|
margin: 0.5em 0em 0em 3em;
|
|
z-index: 1; /* Otherwise it disappears behind the tweet background color on mouse-over */
|
|
position: relative; /* z-index is ignored if `position` is "static" */
|
|
width: fit-content;
|
|
|
|
.pinned-tweet__pin-icon {
|
|
filter: invert(43%) saturate(30%);
|
|
width: 1em;
|
|
height: auto;
|
|
}
|
|
}
|
|
|
|
/******************************************************
|
|
* Search page
|
|
******************************************************/
|
|
|
|
/**
|
|
* Search page sort-order module
|
|
*/
|
|
.sort-order {
|
|
padding: 1em 1em 1em 3em;
|
|
border-bottom: 1px solid var(--color-outline-gray);
|
|
.sort-order__label {
|
|
font-weight: bold;
|
|
}
|
|
.sort-order__dropdown {
|
|
text-transform: capitalize;
|
|
margin: 0 1em;
|
|
}
|
|
}
|
|
|
|
/******************************************************
|
|
* Login page
|
|
******************************************************/
|
|
|
|
/**
|
|
* Login form module
|
|
*/
|
|
.login-form {
|
|
.login-form__field-container {
|
|
padding: 0.5em 0;
|
|
}
|
|
.login-form__submit-container {
|
|
text-align: right;
|
|
}
|
|
.login-form__error-label {
|
|
color: #C0392B;
|
|
font-weight: bold;
|
|
|
|
& + input {
|
|
border-color: #C0392B;
|
|
border-width: 2px;
|
|
}
|
|
}
|
|
.login-form__input {
|
|
width: 100%;
|
|
border-radius: 0.5em;
|
|
padding: 0.5em 0.6em;
|
|
flex-grow:;
|
|
}
|
|
& input[type="submit"] {
|
|
padding: 1em;
|
|
}
|
|
}
|
|
.choose-session {
|
|
margin-top: 2em;
|
|
|
|
.choose-session__form-contents {
|
|
padding-top: 1em;
|
|
gap: 3em;
|
|
|
|
}
|
|
.choose-session__dropdown {
|
|
flex-grow: 1;
|
|
}
|
|
}
|
|
|
|
/******************************************************
|
|
* Lists pages
|
|
******************************************************/
|
|
|
|
.list-of-lists {
|
|
border-color: var(--color-twitter-off-white-dark);
|
|
border-top-style: double;
|
|
border-width: 4px;
|
|
}
|
|
|
|
/**
|
|
* List preview module
|
|
*/
|
|
.list-preview {
|
|
padding: 0.5em 1em;
|
|
border-color: var(--color-twitter-off-white-dark);
|
|
border-bottom-style: solid;
|
|
border-width: 1px;
|
|
|
|
.list-preview__info-container{
|
|
display: flex;
|
|
align-items: center;
|
|
font-size: 1.5em;
|
|
cursor: pointer;
|
|
}
|
|
.list-preview__num-users {
|
|
margin-left: 1em;
|
|
color: var(--color-twitter-text-gray);
|
|
}
|
|
.list-preview__first-N-profile-images {
|
|
display: flex;
|
|
align-items: flex-end;
|
|
margin-left: 1.5em;
|
|
|
|
.profile-image {
|
|
/* Make profile images in the list preview stack up on each other */
|
|
margin-right: -1.2em;
|
|
}
|
|
.ellipsis {
|
|
/* Counteract the above; the ellipsis should be spaced normally */
|
|
margin-left: 1.5em;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/******************************************************
|
|
* Bookmarks pages
|
|
******************************************************/
|
|
|
|
.bookmarks-feed-header {
|
|
border-bottom: 1px solid var(--color-outline-gray);
|
|
}
|
|
|
|
.add-users-container {
|
|
padding: 1em;
|
|
text-align: center;
|
|
}
|
|
|
|
/******************************************************
|
|
* DMs / Messages
|
|
******************************************************/
|
|
|
|
/**
|
|
* Chat list entry module
|
|
*/
|
|
.chat-list-entry {
|
|
border-bottom: 1px solid var(--color-outline-gray);
|
|
padding: 1em 1em 0 1em;
|
|
box-sizing: border-box;
|
|
cursor: pointer;
|
|
|
|
&.chat-list-entry--active-chat {
|
|
color: var(--color-twitter-blue);
|
|
border-left: 0.2em solid var(--color-twitter-blue);
|
|
background-color: var(--color-twitter-off-white);
|
|
|
|
.profile-image__image {
|
|
box-shadow: 0 0 1em 0em var(--color-twitter-blue);
|
|
}
|
|
}
|
|
.chat-list-entry__header {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
}
|
|
.chat-list-entry__preview-and-unread-container {
|
|
justify-content: space-between;
|
|
}
|
|
.chat-list-entry__message-preview {
|
|
font-size: 0.9em;
|
|
color: var(--color-twitter-text-gray);
|
|
padding: 0 1em;
|
|
border-left: 1px solid var(--color-outline-gray);
|
|
|
|
.chat-list-entry--unread & {
|
|
font-weight: bold;
|
|
}
|
|
}
|
|
.chat-list-entry__unread-indicator {
|
|
display: none;
|
|
background-color: var(--color-twitter-blue);
|
|
height: 0.5em;
|
|
width: 0.5em;
|
|
border-radius: 50%;
|
|
flex: auto 0 0; /* Otherwise it gets squished if the message preview is long */
|
|
|
|
.chat-list-entry--unread & {
|
|
display: revert;
|
|
}
|
|
}
|
|
.chat-list-entry__preview-no-text {
|
|
font-style: italic;
|
|
}
|
|
|
|
.posted-at__text {
|
|
margin: 0;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Groupchat info module (like Author Info but for group chats)
|
|
*/
|
|
.groupchat-info {
|
|
.groupchat-info__display-name {
|
|
padding: 0.6em;
|
|
font-style: italic;
|
|
font-weight: bold; /* TODO: redundancy check `.author-info__display-name` */
|
|
white-space: nowrap;
|
|
cursor: default; /* TODO: redundancy check `.author-info` */
|
|
}
|
|
}
|
|
|
|
.chat-header {
|
|
border-bottom: 1px solid var(--color-outline-gray);
|
|
padding: 0.5em;
|
|
display: flex;
|
|
justify-content: space-around;
|
|
background-color: var(--color-twitter-off-white);
|
|
}
|
|
|
|
.groupchat-participants-list {
|
|
position: absolute;
|
|
background-color: white;
|
|
top: 4.2em; /* TODO: wtf is this number */
|
|
left: 0;
|
|
right: 0;
|
|
bottom: 0;
|
|
overflow-y: scroll;
|
|
display: none;
|
|
|
|
&.unhidden {
|
|
display: revert;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* DM message module
|
|
*/
|
|
.dm-message {
|
|
display: flex;
|
|
flex-direction: column;
|
|
margin: 1em 0;
|
|
/**
|
|
* Compact mode:
|
|
* margin: 0.5em 0;
|
|
*/
|
|
|
|
/* When a replying-to box is clicked, it scrolls that message into view and highlights it for a second */
|
|
transition: background-color 2s ease;
|
|
&.highlighted {
|
|
background-color: var(--color-twitter-off-white-dark);
|
|
transition: background-color 0.5s ease;
|
|
}
|
|
|
|
.dm-message__row {
|
|
align-items: stretch;
|
|
|
|
.our-message & {
|
|
flex-direction: row-reverse;
|
|
}
|
|
|
|
.dm-message__button-container {
|
|
display: flex;
|
|
flex-direction: column;
|
|
justify-content: center;
|
|
}
|
|
}
|
|
.dm-message__sender-profile-img {
|
|
display: flex;
|
|
align-items: flex-end;
|
|
}
|
|
.dm-message__sender-profile-img a {
|
|
line-height: 0; /* TODO: This is redundant with ".author-info a" rule above */
|
|
}
|
|
.dm-message__contents {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: flex-start;
|
|
max-width: 80%;
|
|
margin: 0 0.5em;
|
|
|
|
.our-message & {
|
|
align-items: flex-end;
|
|
}
|
|
}
|
|
|
|
.dm-message__tweet-preview {
|
|
border-radius: 1em;
|
|
overflow: hidden; /* TODO: redundancy check-- why is this necessary? check .rounded-gray-outline */
|
|
border: 1px solid var(--color-outline-gray);
|
|
max-width: 100%;
|
|
}
|
|
.dm-message__embedded-image, .dm-message__embedded-video {
|
|
max-width: 100%;
|
|
height: auto; /* preserve aspect ratio */
|
|
cursor: pointer;
|
|
}
|
|
.dm-message__text-content {
|
|
display: inline-block;
|
|
padding: 1em;
|
|
background-color: #ddd;
|
|
border-radius: 1em;
|
|
margin: 0;
|
|
|
|
/**
|
|
* Compact mode:
|
|
*
|
|
display: inline-block;
|
|
padding: 0.5em 1em;
|
|
background-color: #ddd;
|
|
border-radius: 1em;
|
|
margin: auto;
|
|
min-height: 2em;
|
|
display: flex;
|
|
flex-direction: column;
|
|
justify-content: space-around;
|
|
*/
|
|
.our-message & {
|
|
background-color: var(--color-twitter-blue-light);
|
|
}
|
|
}
|
|
|
|
.sent-at {
|
|
flex-grow: 1;
|
|
min-width: 5em;
|
|
width: fit-content;
|
|
|
|
.sent-at__text {
|
|
float: right;
|
|
color: var(--color-twitter-text-gray);
|
|
font-size: 0.875em;
|
|
white-space: nowrap;
|
|
}
|
|
}
|
|
.sent-at__text {
|
|
margin: 0 4.5em;
|
|
}
|
|
.dm-message__reactions {
|
|
display: flex;
|
|
font-size: 1.1em;
|
|
padding: 0 3.5em;
|
|
cursor: default;
|
|
|
|
.our-message & {
|
|
flex-direction: row-reverse;
|
|
}
|
|
}
|
|
.dm-message__reacc {
|
|
padding: 0em 0.1em;
|
|
|
|
&.dm-message__reacc--ours {
|
|
border-radius: 50%;
|
|
text-shadow: 0 0 3px black;
|
|
outline: 1px solid var(--color-twitter-blue);
|
|
background-color: var(--color-twitter-blue-extra-light);
|
|
}
|
|
}
|
|
|
|
&.our-message {
|
|
align-items: flex-end;
|
|
}
|
|
}
|
|
|
|
.dm-replying-to {
|
|
background-color: #f0f0f0f0;
|
|
border-radius: 1em 1em 1em 0em;
|
|
padding: 0.5em 1.2em 2em 1.2em;
|
|
margin: 0 0 -2em 0.2em;
|
|
font-size: 0.9em;
|
|
|
|
.our-message & {
|
|
border-radius: 1em 1em 0em 1em;
|
|
margin: 0 0.2em -2em;
|
|
}
|
|
|
|
.dm-replying-to__label {
|
|
font-size: 0.8em;
|
|
color: var(--color-twitter-text-gray);
|
|
|
|
& img.svg-icon {
|
|
width: 1em;
|
|
}
|
|
}
|
|
|
|
.dm-replying-to__preview-text, .dm-replying-to__username {
|
|
cursor: pointer;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Messages page DM composer module
|
|
*/
|
|
.dm-composer {
|
|
& form {
|
|
display: flex;
|
|
gap: 1em;
|
|
padding: 0.8em 1em;
|
|
align-items: center;
|
|
border-top: 1px solid var(--color-outline-gray);
|
|
background-color: white;
|
|
}
|
|
[role="textbox"] {
|
|
flex-grow: 1;
|
|
border: 1px solid #ccc;
|
|
font-family: inherit;
|
|
font-size: inherit;
|
|
padding: 1px 6px;
|
|
max-height: 10em;
|
|
min-height: 3em;
|
|
overflow-wrap: anywhere;
|
|
overflow-y: auto; /* scrollbar only if needed */
|
|
border: 2px solid var(--color-outline-gray);
|
|
border-radius: 0.5em;
|
|
}
|
|
& input[type="submit"] {
|
|
flex-shrink: 0;
|
|
flex-grow: 0;
|
|
height: 3em;
|
|
width: 6em;
|
|
}
|
|
|
|
|
|
.dm-composer__replying-to-container {
|
|
display: none;
|
|
&.unhidden {
|
|
display: revert;
|
|
}
|
|
|
|
/* This is gross; it's to counter the left margin on `dm-replying-to`, which is meant for the one on DMs specifically */
|
|
margin-left: -0.2em;
|
|
|
|
.dm-composer__replying-to {
|
|
position: absolute;
|
|
top: 0;
|
|
transform: translate(0, -100%);
|
|
width: 100%;
|
|
}
|
|
}
|
|
}
|