mirror of
https://github.com/zulip/zulip.git
synced 2025-10-23 04:52:12 +00:00
Non-color values are not permitted inside light-dark(). This commit fixes that for --color-invalid-input-box-shadow.
2056 lines
59 KiB
CSS
2056 lines
59 KiB
CSS
#compose_buttons {
|
|
text-align: right;
|
|
display: flex;
|
|
column-gap: 4px;
|
|
flex-direction: row;
|
|
/* With precisely controlled line-heights
|
|
in this area, stretch will both center
|
|
and maintain uniform heights between the
|
|
reply button and the new-message button. */
|
|
align-items: stretch;
|
|
|
|
.compose_mobile_button {
|
|
/* Keep the new message button sized to match
|
|
adjacent buttons. */
|
|
min-width: inherit;
|
|
padding: 3px 10px;
|
|
border-radius: 4px;
|
|
outline: none;
|
|
/* This is ugly, but necessary to use the
|
|
text + for the compose button. An icon
|
|
would likely be a better choice here.
|
|
1.2em is 16.8px at 14px em. */
|
|
font-size: 1.2em;
|
|
/* 1.2em is 16.8px at 14px em; this
|
|
maintains the 20px em-equivalent compose
|
|
line height, but at a 16.8px em. */
|
|
line-height: 1.19em;
|
|
font-weight: 400;
|
|
color: var(--color-text-default);
|
|
background-color: var(--color-background-compose-new-message-button);
|
|
border: 1px solid var(--color-border-compose-new-message-button);
|
|
|
|
&:hover {
|
|
background-color: var(
|
|
--color-background-compose-new-message-button-hover
|
|
);
|
|
border-color: var(--color-border-compose-new-message-button-hover);
|
|
}
|
|
|
|
&:active {
|
|
background-color: var(
|
|
--color-background-compose-new-message-button-active
|
|
);
|
|
border-color: var(--color-border-compose-new-message-button-hover);
|
|
}
|
|
}
|
|
|
|
.reply_button_container {
|
|
display: flex;
|
|
flex-grow: 1;
|
|
|
|
/* Adjust flexbox default `min-width` to allow smaller container sizes. */
|
|
min-width: 0;
|
|
|
|
/* Button-like styling */
|
|
border-radius: 4px;
|
|
background-color: var(
|
|
--color-compose-collapsed-reply-button-area-background
|
|
);
|
|
border: 1px solid
|
|
var(--color-compose-collapsed-reply-button-area-border);
|
|
|
|
&:hover,
|
|
&:focus {
|
|
background-color: var(
|
|
--color-compose-collapsed-reply-button-area-background-interactive
|
|
);
|
|
border-color: var(
|
|
--color-compose-collapsed-reply-button-area-border-interactive
|
|
);
|
|
}
|
|
|
|
#left_bar_compose_reply_button_big,
|
|
#new_conversation_button {
|
|
/* Keep the new message button sized to match
|
|
adjacent buttons. */
|
|
font-size: inherit;
|
|
min-width: inherit;
|
|
padding: 3px 10px;
|
|
outline: none;
|
|
border: none;
|
|
color: var(--color-text-default);
|
|
background: var(--color-compose-embedded-button-background);
|
|
border-radius: 3px;
|
|
line-height: var(--line-height-compose-buttons);
|
|
}
|
|
|
|
.compose-reply-button-wrapper {
|
|
flex-grow: 1;
|
|
display: flex;
|
|
overflow: hidden;
|
|
}
|
|
|
|
#left_bar_compose_reply_button_big {
|
|
width: 100%;
|
|
text-align: left;
|
|
overflow: hidden;
|
|
white-space: nowrap;
|
|
text-overflow: ellipsis;
|
|
}
|
|
|
|
#new_conversation_button {
|
|
/* Remove the `padding` to prevent margin from affecting parent height. */
|
|
padding: 0 10px;
|
|
min-width: inherit;
|
|
margin: 1px;
|
|
flex-shrink: 0;
|
|
align-self: stretch;
|
|
|
|
color: var(--color-compose-embedded-button-text-color);
|
|
|
|
&:hover {
|
|
background-color: var(
|
|
--color-compose-embedded-button-background-hover
|
|
);
|
|
color: var(--color-compose-embedded-button-text-color-hover);
|
|
}
|
|
}
|
|
}
|
|
|
|
.mobile_button_container {
|
|
@media (width >= $sm_min) {
|
|
display: none;
|
|
}
|
|
}
|
|
|
|
#new_conversation_button,
|
|
.new_direct_message_button_container {
|
|
flex-shrink: 0;
|
|
line-height: var(--line-height-compose-buttons);
|
|
|
|
@media (width < $sm_min) {
|
|
/* Override inline style injected by jQuery hide() */
|
|
display: none !important;
|
|
}
|
|
}
|
|
|
|
.new_direct_message_button_container {
|
|
display: flex;
|
|
}
|
|
|
|
#new_direct_message_button {
|
|
/* Keep the new message button sized to match
|
|
adjacent buttons. */
|
|
align-self: stretch;
|
|
font-size: inherit;
|
|
min-width: inherit;
|
|
line-height: var(--line-height-compose-buttons);
|
|
padding: 3px 10px;
|
|
border-radius: 4px;
|
|
outline: none;
|
|
color: var(--color-text-default);
|
|
background-color: var(--color-background-compose-new-message-button);
|
|
border: 1px solid var(--color-border-compose-new-message-button);
|
|
|
|
&:hover {
|
|
background-color: var(
|
|
--color-background-compose-new-message-button-hover
|
|
);
|
|
border-color: var(--color-border-compose-new-message-button-hover);
|
|
}
|
|
|
|
&:active {
|
|
background-color: var(
|
|
--color-background-compose-new-message-button-active
|
|
);
|
|
border-color: var(--color-border-compose-new-message-button-hover);
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Main geometry for this element is in zulip.css */
|
|
#compose-content {
|
|
background-color: var(--color-compose-box-background);
|
|
padding: 4px 4px 6px;
|
|
border: 1px solid var(--color-border-compose-content);
|
|
border-radius: 9px 9px 0 0;
|
|
box-shadow: 0 0 0 hsl(236deg 11% 28%);
|
|
height: 100%;
|
|
display: flex;
|
|
flex-flow: column;
|
|
box-sizing: border-box;
|
|
|
|
&:hover {
|
|
.composebox-buttons > button {
|
|
opacity: 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
.message_comp {
|
|
display: none;
|
|
padding: 0 7px 0 0;
|
|
|
|
#compose_banners {
|
|
max-height: min(25vh, 240px);
|
|
overflow-y: auto;
|
|
/* Align to compose controls; that's 112px width,
|
|
plus 4px of grid gap for 116px here. */
|
|
margin-right: calc(var(--compose-send-controls-width) + 4px);
|
|
}
|
|
}
|
|
|
|
.compose_table {
|
|
height: 100%;
|
|
display: flex;
|
|
flex-flow: column;
|
|
|
|
#compose-recipient {
|
|
&.compose-recipient-direct-selected {
|
|
#compose_select_recipient_widget_wrapper {
|
|
/* As the DM-pill area expands, we want to
|
|
hold the DM picker to the first line. */
|
|
align-self: flex-start;
|
|
}
|
|
|
|
#compose_select_recipient_widget {
|
|
border-radius: 4px !important;
|
|
/* This height is necessary only for the
|
|
DM picker, so that it does not stretch
|
|
open taller with multiple rows of user
|
|
pills. */
|
|
height: var(--compose-recipient-box-min-height);
|
|
}
|
|
|
|
.topic-marker-container {
|
|
/* As the DM-pill area expands, we likewise
|
|
want to keep the topic marker aligned with
|
|
the DM picker. */
|
|
align-self: flex-start;
|
|
}
|
|
}
|
|
|
|
.topic-marker-container {
|
|
/* Ensure the marker ( < ) stays centered vertically
|
|
with the dropdown, even when adjacent stacking pills
|
|
in, e.g., a group DM. */
|
|
align-self: center;
|
|
display: flex;
|
|
align-items: center;
|
|
/* Ensure horizontal centering, too. */
|
|
justify-content: center;
|
|
/* Disallow shrinking or growth, which can cause
|
|
little layout shifts with pills. */
|
|
flex: 0 0 auto;
|
|
height: var(--compose-recipient-box-min-height);
|
|
|
|
.conversation-arrow {
|
|
font-size: 1.1429em; /* 16px / 14px em */
|
|
/* Fix the line-height to the font size
|
|
to maintain a circle that scales. */
|
|
line-height: 1;
|
|
border-radius: 50%;
|
|
padding: 2px;
|
|
margin: 0 3px;
|
|
color: var(--color-compose-chevron-arrow);
|
|
text-decoration: none;
|
|
cursor: default;
|
|
transition: 0.2s ease-in-out;
|
|
transition-property: background, color;
|
|
|
|
&.narrow_to_compose_recipients {
|
|
background: var(
|
|
--color-narrow-to-compose-recipients-background
|
|
);
|
|
color: var(--color-narrow-to-compose-recipients);
|
|
cursor: pointer;
|
|
|
|
&:hover {
|
|
background: var(
|
|
--color-narrow-to-compose-recipients-background-hover
|
|
);
|
|
color: var(--color-narrow-to-compose-recipients-hover);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#compose-direct-recipient {
|
|
flex-grow: 1;
|
|
display: grid;
|
|
grid-template-columns: 1fr;
|
|
align-items: stretch;
|
|
}
|
|
|
|
.message_header {
|
|
background: none;
|
|
background-color: hsl(0deg 0% 92%);
|
|
border: none;
|
|
border-radius: 0;
|
|
box-shadow: none !important;
|
|
}
|
|
|
|
.messagebox {
|
|
box-shadow: none !important;
|
|
}
|
|
}
|
|
|
|
#send_message_form {
|
|
margin: 0;
|
|
height: 100%;
|
|
|
|
.messagebox {
|
|
/* normally 5px 14px; pull in the right and bottom a bit */
|
|
cursor: default;
|
|
flex: 1;
|
|
padding: 0;
|
|
background: none;
|
|
box-shadow: none;
|
|
border: none;
|
|
height: 100%;
|
|
display: grid;
|
|
/* Vlad's design calls for 122px for the send column
|
|
at its widest; 112px accounts for 6px of gap and
|
|
4px outside padding. */
|
|
grid-template:
|
|
minmax(0, 1fr) var(--compose-formatting-buttons-row-height)
|
|
/ minmax(0, 1fr) var(--compose-send-controls-width);
|
|
grid-template-areas:
|
|
"message-content-container message-send-controls-container"
|
|
"message-formatting-controls-container message-send-controls-container";
|
|
gap: 0 4px;
|
|
}
|
|
|
|
.message_content {
|
|
margin-right: 0;
|
|
}
|
|
}
|
|
|
|
#message-content-container {
|
|
grid-area: message-content-container;
|
|
display: grid;
|
|
grid-template: minmax(0, 1fr) / minmax(0, 1fr) var(
|
|
--composebox-buttons-width
|
|
);
|
|
grid-template-areas: "message-content composebox-buttons";
|
|
border-radius: 4px;
|
|
border: 1px solid var(--color-message-content-container-border);
|
|
|
|
&:has(.new_message_textarea:focus) {
|
|
border-color: var(--color-message-content-container-border-focus);
|
|
}
|
|
|
|
&:has(.new_message_textarea.invalid),
|
|
&:has(.new_message_textarea.invalid:focus) {
|
|
border-color: var(--color-invalid-input-border);
|
|
box-shadow: var(--invalid-input-box-shadow);
|
|
}
|
|
}
|
|
|
|
#message-content-container:has(.new_message_textarea.textarea-over-limit),
|
|
.edit-content-container:has(.message_edit_content.textarea-over-limit) {
|
|
box-shadow: 0 0 0 1pt
|
|
var(--color-message-content-container-border-over-limit);
|
|
}
|
|
|
|
#message-content-container:has(
|
|
.new_message_textarea.textarea-approaching-limit
|
|
),
|
|
.edit-content-container:has(.message_edit_content.textarea-approaching-limit) {
|
|
box-shadow: 0 0 0 1pt
|
|
var(--color-message-content-container-border-approaching-limit);
|
|
}
|
|
|
|
#message-content-container:has(.new_message_textarea.textarea-over-limit.flash),
|
|
#message-content-container:has(
|
|
.new_message_textarea.textarea-approaching-limit.flash
|
|
),
|
|
.edit-content-container:has(.message_edit_content.textarea-over-limit.flash),
|
|
.edit-content-container:has(
|
|
.message_edit_content.textarea-approaching-limit.flash
|
|
) {
|
|
/* This should align with the timing in compose_validate.validate_message_length. */
|
|
animation: message-limit-flash 0.5s ease-in-out 1;
|
|
}
|
|
|
|
#message-content-container .composebox-buttons {
|
|
grid-area: composebox-buttons;
|
|
/* z-index is needed to avoid flickering of cursor and the
|
|
button when hovering it in preview mode. */
|
|
z-index: 1;
|
|
height: max-content;
|
|
|
|
button {
|
|
width: 24px;
|
|
/* Override any UA stylesheet padding, such as that
|
|
added by mobile Safari. */
|
|
padding: 0;
|
|
border: none;
|
|
aspect-ratio: 1 / 1;
|
|
background-color: var(--color-composebox-button-background);
|
|
color: var(--color-composebox-button);
|
|
border-radius: 3px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
opacity: 0;
|
|
transition:
|
|
opacity 0.4s ease-in,
|
|
color 0.1s ease-in,
|
|
background-color 0.1s ease-in;
|
|
|
|
&:hover {
|
|
background-color: var(--color-composebox-button-background-hover);
|
|
color: var(--color-composebox-button-hover);
|
|
}
|
|
|
|
&:focus {
|
|
outline: 0;
|
|
}
|
|
|
|
&:focus-visible {
|
|
outline: 2px solid var(--color-outline-focus);
|
|
}
|
|
}
|
|
|
|
.collapse-composebox-button,
|
|
.maximize-composebox-button {
|
|
display: none;
|
|
}
|
|
}
|
|
|
|
#compose-textarea,
|
|
#preview-message-area-container {
|
|
grid-area: message-content;
|
|
}
|
|
|
|
#compose-textarea,
|
|
#preview_message_area {
|
|
margin-right: calc(var(--composebox-buttons-width) * -1);
|
|
padding-right: var(--composebox-buttons-width);
|
|
background-color: var(--color-compose-message-content-background);
|
|
color: var(--color-text-default);
|
|
|
|
&.textarea-over-limit {
|
|
background-color: var(
|
|
--color-compose-message-content-background-over-limit
|
|
);
|
|
}
|
|
|
|
&.textarea-approaching-limit {
|
|
background-color: var(
|
|
--color-compose-message-content-background-approaching-limit
|
|
);
|
|
}
|
|
}
|
|
|
|
.surround-formatting-buttons-row {
|
|
/* This is to extend it under the formatting buttons
|
|
row, so that any border / box-shadow styles applied
|
|
to it surround the formatting buttons row as well. */
|
|
padding-bottom: var(--compose-formatting-buttons-row-height);
|
|
/* The extra 1px of margin-bottom is to ensure the 1px of
|
|
border-bottom shows below the formatting buttons row. */
|
|
margin-bottom: calc(
|
|
(var(--compose-formatting-buttons-row-height) + 1px) * -1
|
|
);
|
|
|
|
textarea {
|
|
/* Flatten the bottom edge of the textarea to
|
|
merge with the flat top edge of the buttons row */
|
|
border-radius: 3px 3px 0 0;
|
|
}
|
|
}
|
|
|
|
#preview-message-area-container {
|
|
/* Keep preview container invisible outside
|
|
of preview mode. */
|
|
display: none;
|
|
}
|
|
|
|
#message-send-controls-container {
|
|
grid-area: message-send-controls-container;
|
|
/* A columnar flex does a nice job here
|
|
holding Drafts to the top of the
|
|
container, and the send button to
|
|
the bottom--even as the compose box
|
|
expands or contracts. */
|
|
display: flex;
|
|
flex-direction: column;
|
|
/* With a columnar flex, this ensures that
|
|
send controls occupy the same space as
|
|
the adjacent textbox. */
|
|
justify-content: space-between;
|
|
/* We add 6px of margin to the grid-gap of
|
|
6px, for 12px of space between the Send
|
|
button and the textarea. */
|
|
margin-left: 6px;
|
|
|
|
@media (width < $sm_min), ((width >= $sm_min) and (width < $mc_min)) {
|
|
margin-left: 0;
|
|
}
|
|
}
|
|
|
|
#message-formatting-controls-container {
|
|
grid-area: message-formatting-controls-container;
|
|
border-radius: 0 0 3px 3px;
|
|
background-color: var(--color-message-formatting-controls-container);
|
|
/* margin on either side to let the border of
|
|
.message-content-container show through. */
|
|
margin: 0 1px;
|
|
}
|
|
|
|
.compose-scrolling-buttons-container {
|
|
display: grid;
|
|
/* The scroller buttons are set to a 48px width that does not scale;
|
|
the idea being that that's a generous target area, and that it
|
|
would be better not to consume more space at larger font sizes
|
|
under narrower screen sizes. */
|
|
grid-template-columns:
|
|
[scroller-backward-start buttons-start] 48px [scroller-backward-end] minmax(
|
|
0,
|
|
1fr
|
|
)
|
|
[scroller-forward-start] 48px [scroller-forward-end buttons-end];
|
|
grid-template-rows: auto;
|
|
}
|
|
|
|
.compose-scrollable-buttons {
|
|
grid-area: buttons;
|
|
overflow-x: scroll;
|
|
scrollbar-width: none;
|
|
scroll-behavior: smooth;
|
|
}
|
|
|
|
.formatting-control-scroller-button {
|
|
z-index: 5;
|
|
display: flex;
|
|
align-items: center;
|
|
|
|
border-radius: 0;
|
|
border: 0;
|
|
|
|
color: var(--color-compose-scroll-icon);
|
|
background: transparent;
|
|
|
|
opacity: 0;
|
|
pointer-events: none;
|
|
transition: opacity 0.2s;
|
|
|
|
&:focus {
|
|
outline: 0;
|
|
}
|
|
}
|
|
|
|
.formatting-scroller-backward {
|
|
grid-area: scroller-backward;
|
|
justify-content: flex-start;
|
|
border-radius: 0 0 0 3px;
|
|
background: var(--gradient-compose-scroll-backward);
|
|
|
|
&:hover {
|
|
background: var(--gradient-compose-scroll-backward-hover);
|
|
}
|
|
|
|
&:active {
|
|
background: var(--gradient-compose-scroll-backward-active);
|
|
|
|
.scroller-backward-icon {
|
|
/* Subtly shift arrow in scroll direction. */
|
|
margin-left: -2px;
|
|
}
|
|
}
|
|
}
|
|
|
|
.formatting-scroller-forward {
|
|
grid-area: scroller-forward;
|
|
justify-content: flex-end;
|
|
border-radius: 0 0 3px;
|
|
background: var(--gradient-compose-scroll-forward);
|
|
|
|
&:hover {
|
|
background: var(--gradient-compose-scroll-forward-hover);
|
|
}
|
|
|
|
&:active {
|
|
background: var(--gradient-compose-scroll-forward-active);
|
|
|
|
.scroller-forward-icon {
|
|
/* Subtly shift arrow in scroll direction. */
|
|
margin-right: -2px;
|
|
}
|
|
}
|
|
}
|
|
|
|
.can-scroll-backward .formatting-scroller-backward,
|
|
.can-scroll-forward .formatting-scroller-forward {
|
|
opacity: 1;
|
|
pointer-events: all;
|
|
}
|
|
|
|
/* Hide the scroller buttons when someone has reached
|
|
the formatting bar via Tab. Scroller-button state
|
|
silently updates despite their being hidden, and
|
|
scroller buttons reappear once focus has moved out
|
|
of the formatting bar. */
|
|
.compose-scrolling-buttons-container:has(
|
|
.compose-scrollable-buttons:focus-within
|
|
) {
|
|
.formatting-scroller-backward,
|
|
.formatting-scroller-forward {
|
|
opacity: 0;
|
|
pointer-events: none;
|
|
}
|
|
}
|
|
|
|
.message-limit-indicator:not(:empty) {
|
|
font-size: 0.8571em; /* 12px at 14px/em */
|
|
color: var(--color-limit-indicator);
|
|
width: max-content;
|
|
|
|
/* Keep the limit indicator just above
|
|
and aligned with the send button.
|
|
`:not(:empty)` prevents the padding
|
|
and margin-top from affecting layout
|
|
in the controls area when no indicator
|
|
is present. */
|
|
margin-top: auto;
|
|
padding: 3px 3px 3px 0;
|
|
|
|
&.textarea-over-limit {
|
|
color: var(--color-limit-indicator-over-limit);
|
|
font-weight: bold;
|
|
}
|
|
}
|
|
|
|
#compose {
|
|
position: fixed;
|
|
bottom: 0;
|
|
left: 0;
|
|
z-index: 4;
|
|
}
|
|
|
|
#compose-container {
|
|
display: flex;
|
|
flex-direction: column;
|
|
width: 100%;
|
|
margin: auto;
|
|
}
|
|
|
|
#compose_top {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: flex-start;
|
|
/* Matched to 4px grid-gap on .messagebox grid. */
|
|
padding-bottom: 4px;
|
|
/* Align to compose controls; that's 112px width,
|
|
plus 4px of grid gap for 116px here. */
|
|
margin-right: calc(var(--compose-send-controls-width) + 4px);
|
|
}
|
|
|
|
#compose_close {
|
|
position: absolute;
|
|
top: 0;
|
|
right: 0;
|
|
color: var(--color-compose-send-control-button);
|
|
background: transparent;
|
|
/* 12.5px at 14px em */
|
|
font-size: 0.8928em;
|
|
font-weight: normal;
|
|
/* 3px 7px at 12.5px font size at 14px em */
|
|
line-height: 1.6em;
|
|
opacity: 0.7;
|
|
border: 0;
|
|
/* 3px 7px at 12.5px font size at 14px em */
|
|
padding: 0.24em 0.56em;
|
|
border-radius: 8px;
|
|
vertical-align: unset;
|
|
text-shadow: none;
|
|
|
|
&:hover {
|
|
opacity: 1;
|
|
background: var(--color-compose-embedded-button-background-hover);
|
|
color: var(--color-compose-send-control-button-interactive);
|
|
}
|
|
|
|
&:active {
|
|
background-color: var(
|
|
--color-compose-embedded-button-background-interactive
|
|
);
|
|
}
|
|
|
|
&:focus:not(:focus-visible) {
|
|
outline: none;
|
|
}
|
|
|
|
&:focus-visible {
|
|
outline-color: var(--color-compose-focus-ring);
|
|
}
|
|
}
|
|
|
|
.main-view-banner {
|
|
/* This is same spatial value as the 4px of padding around
|
|
the edge of the compose box. */
|
|
margin-bottom: 4px;
|
|
border-radius: 5px;
|
|
border: 1px solid;
|
|
display: flex;
|
|
align-items: center;
|
|
line-height: 1.2em; /* 18px at 15px/1em. */
|
|
|
|
.above_compose_banner_action_link {
|
|
color: var(--color-main-view-banner-action-link);
|
|
}
|
|
|
|
.main-view-banner-elements-wrapper {
|
|
display: flex;
|
|
align-items: center;
|
|
/* Allow this flex container to grow or
|
|
shrink to fit the outer container. */
|
|
flex: 1 1 auto;
|
|
/* Allow items to wrap; this supports an
|
|
intrinsic layout for banner text and
|
|
buttons, which will always occupy the
|
|
space available, without our having
|
|
to fiddle with tons of media queries. */
|
|
flex-wrap: wrap;
|
|
}
|
|
|
|
& .banner_content {
|
|
/* Override Bootstrap when .banner_content is
|
|
a paragraph element. */
|
|
margin: 0;
|
|
/* 5px right padding + 10px left-margin of the neighbouring button will match the left padding */
|
|
padding: 8px 5px 8px 15px;
|
|
/* The banner text uses a flex-basis of 150px,
|
|
which is roughly the width at which banner
|
|
text lines are still comfortably readable.
|
|
Still, it can grow and shrink as needed. */
|
|
flex: 1 1 150px;
|
|
|
|
& .banner_message {
|
|
/* Override Bootstrap when .banner_content
|
|
contains an inner .banner_message
|
|
paragraph. */
|
|
margin: 0;
|
|
}
|
|
}
|
|
|
|
.main-view-banner-action-button,
|
|
.upload_banner_cancel_button {
|
|
border: none;
|
|
border-radius: 4px;
|
|
padding: 5px 10px;
|
|
font-weight: 600;
|
|
margin-top: 4.5px;
|
|
margin-bottom: 4.5px;
|
|
/* Buttons take a minimum height for
|
|
when their text fits on a single
|
|
line. 2.1333em is 32px at 15px/1em. */
|
|
min-height: 2.1333em;
|
|
/* When we're larger than large mobile
|
|
scales ($ml_min), flex the button to
|
|
its max-content, i.e., all its text
|
|
on a single line. But do not grow in
|
|
order to avoid awkward, oversized
|
|
buttons within the flex group. */
|
|
flex: 0 1 max-content;
|
|
/* Use this margin-left hack to keep
|
|
the button to the righthand side of
|
|
the banner. */
|
|
margin-left: auto;
|
|
|
|
@media (width < $ml_min) {
|
|
/* When we're smaller than large mobile
|
|
scales, we allow the button to grow,
|
|
so that it can span the full width of
|
|
narrow, mobile-scale banners as it
|
|
wraps onto a second line.
|
|
|
|
We also allow the button to shrink,
|
|
so that, for example, the text can
|
|
wrap on the schedule-message button
|
|
that appears when undoing a scheduled
|
|
message. */
|
|
flex: 1 1 max-content;
|
|
/* Use a 10px left margin to keep the
|
|
button away from the edge of the
|
|
banner box to match the banner text;
|
|
we need this only at small scales,
|
|
when the button grows to the full
|
|
width of the flex container. */
|
|
margin-left: 10px;
|
|
}
|
|
/* Extra margin to ensure the layout is identical when there is no
|
|
close button. */
|
|
&.right_edge {
|
|
margin-right: 10px;
|
|
}
|
|
}
|
|
|
|
.main-view-banner-action-button {
|
|
/* Establish a uniform top and bottom
|
|
space around the button, which also
|
|
works with the space around the message
|
|
text. */
|
|
margin-top: 8px;
|
|
margin-bottom: 8px;
|
|
/* Make as tall as two lines of banner message
|
|
text, which have a line-height of 18px, but
|
|
no more. 2.4em is two 1.2em lines in the
|
|
banner area. */
|
|
max-height: 2.4em;
|
|
/* Keep to the top of the box, but stretch
|
|
taller based on how the box is flexing. */
|
|
min-height: 0;
|
|
align-self: stretch;
|
|
}
|
|
|
|
.main-view-banner-close-button {
|
|
text-decoration: none;
|
|
/* Set same top and bottom margin
|
|
as action buttons. */
|
|
margin: 8px 0;
|
|
padding: 0 8px;
|
|
/* Let the close button's box stretch,
|
|
but no larger than the height of the
|
|
banner box when the action button
|
|
achieves its full height (margin,
|
|
padding, and height), which keeps
|
|
the X vertically centered with it. */
|
|
align-self: stretch;
|
|
/* 2.4em is two 1.2em lines in the
|
|
banner area. */
|
|
max-height: 2.4em;
|
|
/* Display as flexbox to better control
|
|
the X icon's position. This creates
|
|
an anonymous flexbox item out of the
|
|
::before content where the icon sits. */
|
|
display: flex;
|
|
align-items: center;
|
|
}
|
|
|
|
.banner_content + .main-view-banner-close-button {
|
|
/* When there's no action button, set the max
|
|
height for the typical height of the box
|
|
when it contains only banner message text.
|
|
This will keep the action button aligned
|
|
with the first or only line of text.
|
|
2.2667 is 34px at 15px/1em; */
|
|
max-height: 2.2667em;
|
|
}
|
|
|
|
&.success {
|
|
background-color: var(--color-background-success-main-view-banner);
|
|
border: 1px solid var(--color-border-success-main-view-banner);
|
|
color: var(--color-success-main-view-banner);
|
|
|
|
.main-view-banner-close-button {
|
|
color: var(--color-success-main-view-banner-close-button);
|
|
|
|
&:hover {
|
|
color: var(--color-success-main-view-banner-close-button-hover);
|
|
}
|
|
|
|
&:active {
|
|
color: var(
|
|
--color-success-main-view-banner-close-button-active
|
|
);
|
|
}
|
|
}
|
|
|
|
.main-view-banner-action-button {
|
|
background-color: var(
|
|
--color-background-success-main-view-banner-action-button
|
|
);
|
|
color: inherit;
|
|
|
|
&:hover {
|
|
background-color: var(
|
|
--color-background-success-main-view-banner-action-button-hover
|
|
);
|
|
}
|
|
|
|
&:active {
|
|
background-color: var(
|
|
--color-background-success-main-view-banner-action-button-active
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
/* warning and warning-style classes have the same CSS; this is since
|
|
the warning class has some associated javascript which we do not want
|
|
for some of the banners, for which we use the warning-style class. */
|
|
&.warning,
|
|
&.warning-style {
|
|
background-color: var(--color-background-warning-main-view-banner);
|
|
border-color: var(--color-border-warning-main-view-banner);
|
|
color: var(--color-warning-main-view-banner);
|
|
|
|
.main-view-banner-close-button {
|
|
color: var(--color-warning-main-view-banner-close-button);
|
|
|
|
&:hover {
|
|
color: var(--color-warning-main-view-banner-close-button-hover);
|
|
}
|
|
|
|
&:active {
|
|
color: var(
|
|
--color-warning-main-view-banner-close-button-active
|
|
);
|
|
}
|
|
}
|
|
|
|
.main-view-banner-action-button {
|
|
background-color: var(
|
|
--color-background-warning-main-view-banner-action-button
|
|
);
|
|
color: var(--color-warning-main-view-banner-action-button);
|
|
|
|
&:hover {
|
|
background-color: var(
|
|
--color-background-warning-main-view-banner-action-button-hover
|
|
);
|
|
}
|
|
|
|
&:active {
|
|
background-color: var(
|
|
--color-background-warning-main-view-banner-action-button-active
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
&.error {
|
|
background-color: var(--color-background-error-main-view-banner);
|
|
border-color: var(--color-border-error-main-view-banner);
|
|
color: var(--color-error-main-view-banner);
|
|
|
|
.main-view-banner-close-button {
|
|
color: var(--color-error-main-view-banner-close-button);
|
|
|
|
&:hover {
|
|
color: var(--color-error-main-view-banner-close-button-hover);
|
|
}
|
|
|
|
&:active {
|
|
color: var(--color-error-main-view-banner-close-button-active);
|
|
}
|
|
}
|
|
|
|
.main-view-banner-action-button {
|
|
background-color: var(
|
|
--color-background-error-main-view-banner-action-button
|
|
);
|
|
color: var(--color-error-main-view-banner-action-button);
|
|
|
|
&:hover {
|
|
background-color: var(
|
|
--color-background-error-main-view-banner-action-button-hover
|
|
);
|
|
}
|
|
|
|
&:active {
|
|
background-color: var(
|
|
--color-background-error-main-view-banner-action-button-active
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
&.info {
|
|
position: relative;
|
|
background-color: var(--color-background-info-main-view-banner);
|
|
border-color: var(--color-border-info-main-view-banner);
|
|
color: var(--color-info-main-view-banner);
|
|
|
|
.main-view-banner-close-button {
|
|
color: var(--color-info-main-view-banner-close-button);
|
|
|
|
&:hover {
|
|
color: var(--color-info-main-view-banner-close-button-hover);
|
|
}
|
|
|
|
&:active {
|
|
color: var(--color-info-main-view-banner-close-button-active);
|
|
}
|
|
}
|
|
|
|
.main-view-banner-action-button,
|
|
.upload_banner_cancel_button {
|
|
background-color: var(
|
|
--color-background-info-main-view-banner-action-button
|
|
);
|
|
color: var(--color-info-main-view-banner-action-button);
|
|
|
|
&:hover {
|
|
background-color: var(
|
|
--color-background-info-main-view-banner-action-button-hover
|
|
);
|
|
}
|
|
|
|
&:active {
|
|
background-color: var(
|
|
--color-background-info-main-view-banner-action-button-active
|
|
);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
.upload_banner {
|
|
overflow: hidden;
|
|
|
|
&.hidden {
|
|
display: none;
|
|
}
|
|
|
|
.moving_bar {
|
|
position: absolute;
|
|
width: 0;
|
|
/* The progress updates seem to come every second or so,
|
|
so this is the smoothest it can probably get. */
|
|
transition: width 1s ease-in-out; /* stylelint-disable-line plugin/no-low-performance-animation-properties */
|
|
background: var(--color-background-main-view-banner-moving-bar);
|
|
top: 0;
|
|
bottom: 0;
|
|
}
|
|
|
|
/* Keep these elements visible above the
|
|
.moving_bar element on file uploads. */
|
|
.upload_msg,
|
|
.main-view-banner-close-button,
|
|
.upload_banner_cancel_button {
|
|
z-index: 1;
|
|
position: relative;
|
|
}
|
|
}
|
|
|
|
.composition-area {
|
|
position: relative;
|
|
flex: 1;
|
|
}
|
|
|
|
@keyframes message-limit-flash {
|
|
0% {
|
|
box-shadow: none;
|
|
}
|
|
|
|
100% {
|
|
box-shadow: 0 0 0 1pt
|
|
var(--color-message-content-container-border-over-limit);
|
|
}
|
|
}
|
|
|
|
textarea.new_message_textarea {
|
|
display: table-cell;
|
|
padding: 5px 5px 0;
|
|
height: 1.5em;
|
|
max-height: 22em;
|
|
margin: 0;
|
|
resize: none !important;
|
|
border-radius: 3px 3px 0 0;
|
|
border: none;
|
|
scrollbar-width: thin;
|
|
scrollbar-color: hsl(0deg 0% 50%) transparent;
|
|
box-shadow: none;
|
|
|
|
&:focus {
|
|
outline: 0;
|
|
}
|
|
|
|
&:read-only,
|
|
&:disabled {
|
|
background-color: hsl(0deg 0% 93%);
|
|
}
|
|
}
|
|
|
|
#message-content-container,
|
|
#compose_recipient_box {
|
|
color: var(--color-text-default);
|
|
}
|
|
|
|
#compose_recipient_box {
|
|
display: grid;
|
|
/* When displaying #topic-not-mandatory-placeholder,
|
|
we let it occupy the entire topic box. Otherwise,
|
|
we set and preserve named areas for the ordinary
|
|
topic text and the clear-topic button. */
|
|
grid-template-columns:
|
|
[topic-box-start topic-start] minmax(0, 1fr)
|
|
[topic-end topic-clear-button-start] auto [topic-clear-button-end topic-box-end];
|
|
grid-template-rows: [topic-box-start topic-start topic-clear-button-start] auto [topic-clear-button-end topic-end topic-box-end];
|
|
align-content: center;
|
|
align-items: stretch;
|
|
flex: 1 1 0;
|
|
border: 1px solid var(--color-compose-recipient-box-border-color);
|
|
border-radius: 4px;
|
|
background: var(--color-compose-recipient-box-background-color);
|
|
|
|
&:hover {
|
|
border-color: var(--color-compose-recipient-box-hover);
|
|
}
|
|
|
|
/* Give the recipient box, a `<div>`, the
|
|
correct styles when focus is in the
|
|
#stream_message_recipient_topic `<input>` */
|
|
&:focus-within {
|
|
border-color: var(--color-compose-recipient-box-has-focus);
|
|
}
|
|
|
|
#stream_message_recipient_topic,
|
|
#recipient_box_clear_topic_button {
|
|
background: none;
|
|
border: none;
|
|
|
|
&:disabled {
|
|
cursor: default;
|
|
opacity: 1;
|
|
}
|
|
}
|
|
|
|
/* Styles for input in the recipient_box */
|
|
#stream_message_recipient_topic {
|
|
grid-area: topic;
|
|
color: var(--color-compose-recipient-box-text-color);
|
|
/* Keep the line-height matched to the font-size
|
|
for a more predictable box height.
|
|
This will have to be watched very closely for
|
|
possible regressions, such as when Unicode emoji
|
|
appear in the topic box. */
|
|
line-height: 1;
|
|
/* Override grid's effective `max-content` min-width */
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
|
|
box-shadow: none;
|
|
outline: none;
|
|
|
|
padding: 0 6px;
|
|
/* Reset height to let `align-items: stretch` on the grid parent handle this. */
|
|
height: auto;
|
|
|
|
&.empty-topic-display::placeholder {
|
|
color: var(--color-compose-recipient-box-text-color);
|
|
}
|
|
}
|
|
|
|
#topic-not-mandatory-placeholder {
|
|
grid-area: topic-box;
|
|
align-self: center;
|
|
white-space: nowrap;
|
|
overflow-x: hidden;
|
|
text-overflow: ellipsis;
|
|
padding: 5px 6px;
|
|
display: none;
|
|
visibility: hidden;
|
|
pointer-events: none;
|
|
|
|
&.visible {
|
|
visibility: visible;
|
|
}
|
|
}
|
|
|
|
/* Styles for new conversation button in the recipient_box */
|
|
#recipient_box_clear_topic_button {
|
|
grid-area: topic-clear-button;
|
|
/* Set the border radius smaller, relative to the parent */
|
|
border-radius: 2px;
|
|
padding: 6px;
|
|
margin: 1px;
|
|
color: var(--color-compose-embedded-button-text-color);
|
|
|
|
.zulip-icon {
|
|
display: block;
|
|
}
|
|
|
|
&:hover {
|
|
background-color: var(
|
|
--color-compose-embedded-button-background-hover
|
|
);
|
|
color: var(--color-compose-embedded-button-text-color-hover);
|
|
}
|
|
|
|
&:focus {
|
|
outline: 0;
|
|
}
|
|
}
|
|
|
|
#stream_message_recipient_topic:not(.empty-topic-display):placeholder-shown
|
|
~ #recipient_box_clear_topic_button {
|
|
visibility: hidden;
|
|
}
|
|
|
|
#stream_message_recipient_topic:disabled
|
|
~ #recipient_box_clear_topic_button {
|
|
visibility: hidden;
|
|
}
|
|
/* This will reset the bootstrap margin-bottom: 10px value for the inputs */
|
|
& input {
|
|
margin-bottom: 0;
|
|
}
|
|
|
|
&.disabled {
|
|
background-color: transparent;
|
|
border-color: transparent;
|
|
max-width: fit-content;
|
|
}
|
|
}
|
|
|
|
#compose_select_recipient_widget {
|
|
/* We set width to 100% to get the ellipsis when
|
|
needed, but the flex and max-width properties
|
|
on the widget wrapper ultimately determine
|
|
how much space the channel picker occupies. */
|
|
width: 100%;
|
|
outline: none;
|
|
/* We override the component-level colors to
|
|
ensure concord with the topic box. */
|
|
color: var(--color-compose-recipient-box-text-color);
|
|
background-color: var(--color-compose-recipient-box-background-color);
|
|
border-color: var(--color-compose-recipient-box-border-color);
|
|
|
|
&:hover,
|
|
&.widget-open {
|
|
border-color: var(--color-compose-recipient-box-hover);
|
|
}
|
|
|
|
&.dropdown-widget-button {
|
|
/* We control the surrounding space through the
|
|
grid on `.dropdown_widget_value`. */
|
|
padding: 0;
|
|
border-radius: 4px;
|
|
}
|
|
|
|
.dropdown_widget_value {
|
|
text-overflow: ellipsis;
|
|
overflow: hidden;
|
|
}
|
|
}
|
|
|
|
#private_message_recipient.recipient_box {
|
|
width: 100%;
|
|
}
|
|
|
|
#compose-direct-recipient .pill-container .pill {
|
|
/* This is necessary to avoid an otherwise unstyled
|
|
flash of outline around pills when focus shifts out
|
|
of the recipient row and transitions are in effect. */
|
|
outline-color: transparent;
|
|
}
|
|
|
|
/* We want transitions to run only on user interactions with
|
|
the mouse, once the compose box is open. Any keyboard
|
|
interactions (e.g., Shift-Tabbing from the compose textarea
|
|
to the topic box) show instant changes, so we don't need to
|
|
accommodate them here, which we prevent by applying the
|
|
transitions only when focus isn't within the recipient row,
|
|
or hasn't recently been within the topic box. */
|
|
#compose.compose-box-open {
|
|
.low-attention-recipient-row:not(.recently-focused, :focus-within) {
|
|
#compose_select_recipient_widget,
|
|
#compose_recipient_box,
|
|
#compose-direct-recipient .pill-container {
|
|
transition: var(--compose-recipient-row-transition);
|
|
transition-delay: var(--compose-recipient-row-transition-delay);
|
|
transition-property: background-color, border-color;
|
|
}
|
|
|
|
#compose_select_recipient_widget .channel-privacy-type-icon {
|
|
transition: var(--compose-recipient-row-transition);
|
|
transition-delay: var(--compose-recipient-row-transition-delay);
|
|
transition-property: color;
|
|
}
|
|
|
|
#recipient_box_clear_topic_button {
|
|
transition: var(--compose-recipient-row-transition);
|
|
transition-delay: var(--compose-recipient-row-transition-delay);
|
|
transition-property: color, background-color, opacity;
|
|
}
|
|
|
|
#compose-direct-recipient .pill {
|
|
transition: var(--compose-recipient-row-transition);
|
|
transition-delay: var(--compose-recipient-row-transition-delay);
|
|
transition-property: outline-color;
|
|
}
|
|
|
|
&#compose-recipient {
|
|
.decorated-channel-name,
|
|
.zulip-icon-chevron-down,
|
|
.conversation-arrow,
|
|
#stream_message_recipient_topic {
|
|
transition: var(--compose-recipient-row-transition);
|
|
transition-delay: var(--compose-recipient-row-transition-delay);
|
|
transition-property: opacity;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/* For the sake of keyboard use, we do not want to apply
|
|
these styles when any element (the picker, user pills)
|
|
has focus. */
|
|
.low-attention-recipient-row:not(:focus-within) {
|
|
&#compose-recipient {
|
|
.decorated-channel-name,
|
|
.conversation-arrow,
|
|
#stream_message_recipient_topic {
|
|
opacity: 0.9;
|
|
}
|
|
|
|
.zulip-icon-chevron-down {
|
|
opacity: 0;
|
|
}
|
|
}
|
|
|
|
#compose_select_recipient_widget,
|
|
#compose_recipient_box,
|
|
#compose-direct-recipient .pill-container {
|
|
background-color: transparent;
|
|
border-color: transparent;
|
|
|
|
/* Particularly in light mode, pill colors are almost identical
|
|
to the compose-box background. We place a higher-contrast
|
|
outline on them in the low-attention state. */
|
|
.pill {
|
|
outline: 1px solid var(--color-outline-low-attention-input-pill);
|
|
/* We offset the outline so that pills do not appear to touch,
|
|
especially in dark mode where the outline color is otherwise
|
|
the same as the pill color (the opacity makes it brighter
|
|
when so offset, too). */
|
|
outline-offset: -1px;
|
|
}
|
|
|
|
&:hover:not(.disabled) {
|
|
background-color: var(
|
|
--color-compose-recipient-box-background-color
|
|
);
|
|
border-color: var(--color-compose-recipient-box-border-color);
|
|
opacity: 1;
|
|
|
|
.decorated-channel-name,
|
|
.zulip-icon-chevron-down,
|
|
.conversation-arrow,
|
|
#stream_message_recipient_topic {
|
|
opacity: 1;
|
|
}
|
|
|
|
.pill {
|
|
outline-color: transparent;
|
|
}
|
|
}
|
|
|
|
#recipient_box_clear_topic_button:hover {
|
|
opacity: 1;
|
|
}
|
|
}
|
|
|
|
#compose_select_recipient_widget {
|
|
.channel-privacy-type-icon.zulip-icon {
|
|
color: var(--privacy-icon-color-modified);
|
|
}
|
|
|
|
&:hover .channel-privacy-type-icon.zulip-icon {
|
|
color: var(--privacy-icon-color-original);
|
|
}
|
|
|
|
&.widget-open {
|
|
background-color: var(--color-background-dropdown-widget-button);
|
|
border-color: var(--color-compose-recipient-box-border-color);
|
|
|
|
.channel-privacy-type-icon {
|
|
color: var(--privacy-icon-color-original);
|
|
}
|
|
|
|
.decorated-channel-name,
|
|
.zulip-icon-chevron-down {
|
|
opacity: 1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
.compose-send-or-save-button {
|
|
border-radius: 4px;
|
|
border: 0;
|
|
margin-bottom: 0;
|
|
color: var(--color-compose-send-button-icon-color);
|
|
background-color: var(--color-compose-send-button-background);
|
|
|
|
&:active {
|
|
transition: transform 80ms;
|
|
transform: scale(0.96);
|
|
}
|
|
|
|
&:focus {
|
|
outline: 0;
|
|
}
|
|
|
|
&:focus-visible {
|
|
border: 1px solid var(--color-compose-send-button-focus-border);
|
|
box-shadow: 0 0 5px var(--color-compose-send-button-focus-shadow);
|
|
/* Override default browser ring. */
|
|
outline: 0;
|
|
}
|
|
|
|
&:hover {
|
|
background-color: var(
|
|
--color-compose-send-button-background-interactive
|
|
);
|
|
}
|
|
}
|
|
|
|
#compose-send-button {
|
|
width: 74px;
|
|
height: var(--compose-formatting-buttons-row-height);
|
|
/* Allow to grow but not shrink */
|
|
flex: 1 0 auto;
|
|
/* Override inherited styles
|
|
so that flexbox can do the
|
|
job of positioning the icon. */
|
|
padding: 0;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
/* Flex items respect z-index values;
|
|
this is needed to keep the send
|
|
button over top of the vdots
|
|
background */
|
|
z-index: 1;
|
|
|
|
@media (width < $sm_min), ((width >= $sm_min) and (width < $mc_min)) {
|
|
/* Drop to a square button,
|
|
and don't flex any wider. */
|
|
width: 30px;
|
|
flex-grow: 0;
|
|
}
|
|
|
|
.zulip-icon-send {
|
|
display: block;
|
|
font-size: 1.2143em; /* 17px at 14px/em */
|
|
line-height: 0.9412; /* 16px at 17px/em */
|
|
}
|
|
|
|
.loader {
|
|
display: none;
|
|
}
|
|
}
|
|
|
|
.enter_sends_choices {
|
|
display: flex;
|
|
flex-direction: column;
|
|
color: var(--color-text-popover-menu);
|
|
|
|
.enter_sends_choice {
|
|
padding: 4px 10px;
|
|
gap: 0 8px;
|
|
display: grid;
|
|
/* 1em and 1.5em were chosen from playing around with different values
|
|
and picking some that looked reasonable. */
|
|
grid-template:
|
|
"radio-button instructions" 1.5em
|
|
". instructions" auto / 1em auto;
|
|
|
|
&:hover {
|
|
background: var(--color-background-hover-popover-menu);
|
|
outline: none;
|
|
}
|
|
|
|
&:active {
|
|
background: var(--color-background-active-popover-menu);
|
|
}
|
|
|
|
&:focus-visible {
|
|
background: var(--color-background-hover-popover-menu);
|
|
border-radius: 4px;
|
|
outline: 1px solid var(--color-outline-focus) !important;
|
|
outline-offset: -1px;
|
|
}
|
|
|
|
& .enter_sends_choice_radio {
|
|
width: auto;
|
|
cursor: pointer;
|
|
/* Radio buttons scale with height, and here we're just
|
|
matching that to the active font-size. */
|
|
height: 1em;
|
|
accent-color: hsl(217deg 100% 60%);
|
|
grid-area: radio-button;
|
|
align-self: center;
|
|
|
|
&:focus {
|
|
outline: 1px dotted hsl(0deg 0% 20%);
|
|
outline: 5px auto -webkit-focus-ring-color;
|
|
outline-offset: -2px;
|
|
}
|
|
|
|
&:checked
|
|
+ .enter_sends_choice_text_container
|
|
.popover-menu-hotkey-hint {
|
|
color: hsl(217deg 100% 60%);
|
|
border: 1px solid hsl(217deg 100% 60% / 50%);
|
|
}
|
|
}
|
|
}
|
|
|
|
.enter_sends_choice_text_container {
|
|
display: flex;
|
|
flex-direction: column;
|
|
flex-shrink: 0;
|
|
gap: 3px;
|
|
white-space: nowrap;
|
|
grid-area: instructions;
|
|
}
|
|
|
|
.enter_sends_choice_text {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 3px;
|
|
}
|
|
|
|
.popover-menu-hotkey-hints {
|
|
margin: 0;
|
|
padding: 0;
|
|
|
|
.popover-menu-hotkey-hint {
|
|
padding: 2px 5px;
|
|
display: flex;
|
|
}
|
|
}
|
|
|
|
.enter_sends_major {
|
|
/* 15px at 14px/1em */
|
|
font-size: 1.0714em;
|
|
}
|
|
|
|
.enter_sends_minor {
|
|
/* 12px at 14px/1em */
|
|
font-size: 0.8571em;
|
|
|
|
.popover-menu-hotkey-hint {
|
|
/* 12px at 14px/1em */
|
|
font-size: 0.8571em;
|
|
padding: 1px 4px;
|
|
}
|
|
}
|
|
}
|
|
|
|
.drafts-item-in-popover {
|
|
display: none;
|
|
/* Only show the Drafts item in the popover when it's not visible
|
|
in the compose box. */
|
|
@media (width < $sm_min) {
|
|
display: block;
|
|
}
|
|
|
|
.unread_count {
|
|
margin: 1px 0 0 6px;
|
|
}
|
|
}
|
|
|
|
#compose-recipient {
|
|
/* Set a line-height equal to the font-size to
|
|
make a compact, predictably tall recipient row. */
|
|
line-height: 1;
|
|
display: flex;
|
|
flex: 1 1 0;
|
|
/* Use this containing flex element to
|
|
establish the minimum height of all its
|
|
children; the default `align-items: stretch`
|
|
(which is set on any flexbox without specifying
|
|
it) ensures that the child flex items will
|
|
always stretch to fit the height set here;
|
|
larger heights, such as on group-DM pills,
|
|
will allow this to grow as needed.
|
|
Child flex items like chevrons take
|
|
`align-self: center` to center only
|
|
themselves, where necessary. */
|
|
min-height: var(--compose-recipient-box-min-height);
|
|
min-width: 0;
|
|
}
|
|
|
|
.compose-control-buttons-container {
|
|
display: flex;
|
|
align-items: center;
|
|
/* 30px at 15px/1em */
|
|
height: var(--compose-formatting-buttons-row-height);
|
|
|
|
.compose_control_button {
|
|
/* 22px at 15px/1em */
|
|
font-size: 1.4667em;
|
|
/* Constrain icon fonts to a perfect
|
|
box (22px at 15px/1em) to sit centered
|
|
in the 30px by 30px button area. */
|
|
line-height: 1;
|
|
/* Coordinate with the value of
|
|
--compose-formatting-buttons-row-height */
|
|
/* 30px at 22px/1em */
|
|
height: 1.3636em;
|
|
width: 1.3636em;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
opacity: 0.7;
|
|
color: inherit;
|
|
text-decoration: none;
|
|
|
|
&:hover {
|
|
opacity: 1;
|
|
background-color: var(
|
|
--color-compose-control-button-background-hover
|
|
);
|
|
}
|
|
|
|
&:focus:not(:focus-visible) {
|
|
outline: none;
|
|
}
|
|
|
|
&:focus-visible {
|
|
outline-color: var(--color-compose-focus-ring);
|
|
}
|
|
}
|
|
|
|
.compose_control_button_container.disabled-on-hover:hover {
|
|
opacity: 0.3;
|
|
|
|
.compose_control_button {
|
|
pointer-events: none;
|
|
}
|
|
}
|
|
|
|
.fa-eye {
|
|
position: relative;
|
|
top: -0.7px;
|
|
}
|
|
|
|
.divider {
|
|
margin: 0 5px;
|
|
/* Coordinate with the value of
|
|
--compose-formatting-buttons-row-height */
|
|
/* 16px at 14px/1em */
|
|
height: 1.1429em;
|
|
width: 1.5px;
|
|
/* Prevent dividers from growing or shrinking. */
|
|
flex: 0 0 auto;
|
|
background-color: var(--color-compose-formatting-button-divider);
|
|
|
|
@media (width < 400px) {
|
|
/* Remove at mobile widths to make more space
|
|
for compose buttons */
|
|
display: none;
|
|
}
|
|
}
|
|
}
|
|
|
|
.message-send-controls {
|
|
display: flex;
|
|
|
|
@media (width < $sm_min) {
|
|
/* At small widths, we display the
|
|
diminutive Send button and vdots
|
|
in a column, using `column-reverse`
|
|
to put the vdots above Send. */
|
|
flex-direction: column-reverse;
|
|
}
|
|
|
|
.compose-button-disabled {
|
|
pointer-events: none;
|
|
}
|
|
}
|
|
|
|
#compose-send-button.disabled-message-send-controls {
|
|
cursor: default;
|
|
opacity: 0.5;
|
|
}
|
|
|
|
.drag {
|
|
display: none;
|
|
height: 18px;
|
|
width: 100%;
|
|
top: 23px;
|
|
position: relative;
|
|
cursor: ns-resize;
|
|
}
|
|
|
|
.preview_message_area {
|
|
padding: 5px 5px 0;
|
|
overflow: auto;
|
|
}
|
|
|
|
.markdown_preview_spinner {
|
|
margin: auto;
|
|
}
|
|
|
|
#compose_select_recipient_widget_wrapper {
|
|
display: flex;
|
|
/* Allow the contents wrapped here to
|
|
expand the available space... */
|
|
white-space: nowrap;
|
|
/* And follow the fitted content on the
|
|
flexbox. */
|
|
flex: 0 0 fit-content;
|
|
/* But force an ellipsis here, rather than
|
|
just on an inner element. */
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
/* Finally, hold this to a maximum width of
|
|
40% of the recipient row. */
|
|
max-width: 40%;
|
|
|
|
&:focus-visible {
|
|
outline: 0;
|
|
|
|
#compose_select_recipient_widget {
|
|
border-color: var(--color-compose-recipient-box-has-focus);
|
|
}
|
|
}
|
|
|
|
.dropdown_widget_value {
|
|
flex-grow: 1;
|
|
display: grid;
|
|
align-items: baseline;
|
|
/* This is a bit of eyeball work, based on balancing
|
|
out the size and spatial relationships between the
|
|
privacy icon and the channel name, and the
|
|
surrounding negative space. */
|
|
/* 7px at 20px/1em; 4px at 20px/1em. */
|
|
grid-template:
|
|
"lefthand-offset privacy-icon privacy-icon-gap channel-name righthand-offset" auto / 0.35em [select-label-start] auto 0.2em minmax(
|
|
0,
|
|
1fr
|
|
)
|
|
[select-label-end]
|
|
0.35em;
|
|
|
|
.channel-privacy-type-icon {
|
|
grid-area: privacy-icon;
|
|
place-self: center;
|
|
font-size: 0.95em; /* 19px at 20px/1em */
|
|
margin-top: -0.0579em; /* Eyeball work; 1.1px at 19px/1em */
|
|
color: var(--privacy-icon-color-original);
|
|
/* Eliminate inherited component styles. */
|
|
position: static;
|
|
padding: 0;
|
|
width: 1em;
|
|
height: 1em;
|
|
|
|
&.zulip-icon-lock {
|
|
/* The lock looks better centered without
|
|
a negative margin-top adjustment. */
|
|
margin-top: 0;
|
|
}
|
|
}
|
|
|
|
.select-channel-label,
|
|
.decorated-dm-label,
|
|
.decorated-channel-name {
|
|
grid-area: channel-name;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
color: var(--color-text-default);
|
|
}
|
|
|
|
.select-channel-label {
|
|
grid-area: select-label;
|
|
}
|
|
}
|
|
|
|
/* We suppress the chevron on the channel picker. */
|
|
.zulip-icon-chevron-down {
|
|
display: none;
|
|
}
|
|
}
|
|
|
|
/* Class for send-area buttons, such as
|
|
Drafts and the send-adjacent vdots */
|
|
.send-control-button {
|
|
border: 0;
|
|
outline: 0;
|
|
padding: 0;
|
|
margin: 0;
|
|
border-radius: 4px;
|
|
color: var(--color-compose-send-control-button);
|
|
background-color: var(--color-compose-send-control-button-background);
|
|
font-weight: 450;
|
|
|
|
&:active {
|
|
transition: transform 80ms;
|
|
transform: scale(0.96);
|
|
}
|
|
|
|
&:focus:not(:focus-visible) {
|
|
outline: none;
|
|
}
|
|
|
|
&:focus-visible {
|
|
outline-color: var(--color-compose-focus-ring);
|
|
}
|
|
|
|
&:hover {
|
|
/* We need to use !important here, regrettably, to keep the default
|
|
dark-mode hover colors from showing. */
|
|
color: var(--color-compose-send-control-button-interactive) !important;
|
|
background-color: var(
|
|
--color-compose-send-control-button-background-interactive
|
|
);
|
|
text-decoration: none;
|
|
}
|
|
}
|
|
|
|
/* vdots icon located next to `Send` button which shows
|
|
options to schedule the message. */
|
|
#send_later {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
width: 40px;
|
|
/* Allow to grow but not shrink */
|
|
flex: 1 0 auto;
|
|
height: var(--compose-formatting-buttons-row-height);
|
|
/* Make the vdots appear to extend from
|
|
beneath the send button when an
|
|
interactive background is present.
|
|
Compensatory padding for this negative
|
|
margin is handled on the vdots icon
|
|
below, so as to make for a maximum
|
|
clickable vdots area. */
|
|
margin-left: -4px;
|
|
border-radius: 0 4px 4px 0;
|
|
/* Flex items respect z-index values;
|
|
this is needed to keep the vdots
|
|
background beneath the send button. */
|
|
z-index: 0;
|
|
|
|
&:focus-visible {
|
|
/* Use a border, not an outline, to preserve the
|
|
conjoined layout with the Send button. Flexbox
|
|
will handle the dimension change, so there won't
|
|
be any movement of the vdots in this state. */
|
|
outline: 0;
|
|
border: 2px solid var(--color-compose-focus-ring);
|
|
}
|
|
|
|
@media ((width >= $sm_min) and (width < $mc_min)) {
|
|
width: 32px;
|
|
}
|
|
|
|
@media (width < $sm_min) {
|
|
/* Drop to a square, rounded button. */
|
|
width: 30px;
|
|
/* This reduces the vdots button so that
|
|
it and the send button fit within the
|
|
53px height the compose textarea occupies,
|
|
including its top border. */
|
|
height: 25px;
|
|
margin-left: 0;
|
|
border-radius: 4px;
|
|
}
|
|
|
|
.zulip-icon {
|
|
padding: 5px 0 5px 4px;
|
|
/* 17px at 14px/1em */
|
|
font-size: 1.2143em;
|
|
flex-grow: 1;
|
|
|
|
@media (width < $sm_min) {
|
|
/* Keep vdots centered above the
|
|
Send button at smallest sizes. */
|
|
padding-left: 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
#compose-drafts-button {
|
|
/* Use border-box sizing to make
|
|
width calculations more predictable
|
|
in a flex context. */
|
|
box-sizing: border-box;
|
|
/* In a columnar flex, we need to
|
|
use alignment to keep the Drafts
|
|
button from expanding the full
|
|
width of the column. */
|
|
align-self: flex-start;
|
|
/* Keep the Drafts button text
|
|
aligned with the Send button's
|
|
lefthand edge */
|
|
padding: 0 8px;
|
|
margin-left: -8px;
|
|
/* Allow the button to occupy as much
|
|
as 100% of the container width, plus
|
|
the 8px from the negative left margin. */
|
|
max-width: calc(100% + 8px);
|
|
display: flex;
|
|
gap: 2px;
|
|
|
|
.compose-drafts-text {
|
|
/* Set an ellipsis when the translated
|
|
version of `Drafts` exceeds the width,
|
|
and keep button text to a single line. */
|
|
white-space: nowrap;
|
|
overflow-x: hidden;
|
|
text-overflow: ellipsis;
|
|
flex-grow: 1;
|
|
}
|
|
|
|
@media (width < $mc_min) {
|
|
/* Reduce the padding on the sides so the
|
|
button's edge isn't too close to the textarea */
|
|
margin-left: -3px;
|
|
max-width: calc(100% + 3px);
|
|
/* Align the `Drafts` text with the
|
|
send icon below. */
|
|
padding: 0 3px;
|
|
}
|
|
}
|
|
|
|
.saved_snippets-dropdown-list-container {
|
|
width: 17.8571em; /* 250px at 14px/em */
|
|
|
|
.dropdown-list .dropdown-list-item-common-styles {
|
|
padding: 0.3571em 0.7143em; /* 5px 10px at 14px/em */
|
|
/* Make content appear more distinct from
|
|
the snippet name. */
|
|
border-bottom: solid 1px var(--color-border-popover-menu-separator);
|
|
|
|
.dropdown-list-item-name {
|
|
line-height: 1.2em;
|
|
}
|
|
|
|
.dropdown-list-item-description {
|
|
font-weight: 400;
|
|
font-size: 0.9283em; /* 13px at 14px/em */
|
|
opacity: 0.8;
|
|
padding: 0;
|
|
text-overflow: ellipsis;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.dropdown-list-text-selected {
|
|
font-weight: 500;
|
|
max-width: 210px;
|
|
display: inline-block;
|
|
text-overflow: ellipsis;
|
|
overflow: hidden;
|
|
white-space: nowrap;
|
|
}
|
|
}
|
|
}
|
|
|
|
#add-new-saved-snippet-modal,
|
|
#edit-saved-snippet-modal {
|
|
& .saved-snippet-title {
|
|
width: 97%;
|
|
margin-bottom: 20px;
|
|
}
|
|
|
|
& .saved-snippet-content {
|
|
width: 97%;
|
|
resize: vertical;
|
|
}
|
|
}
|
|
|
|
#compose.compose-fullscreen,
|
|
#compose.compose-intermediate {
|
|
z-index: 99;
|
|
|
|
#compose-container {
|
|
height: 100%;
|
|
}
|
|
|
|
.message_comp {
|
|
flex: 1;
|
|
display: flex !important;
|
|
flex-flow: column;
|
|
}
|
|
|
|
#compose-textarea,
|
|
#preview_message_area {
|
|
/* When in full screen, override max-height
|
|
properties set from manually resizing. */
|
|
max-height: none !important;
|
|
}
|
|
|
|
#compose-textarea {
|
|
/* Additionally, override the height properties
|
|
on the textarea. This is essential if the
|
|
textarea has been manually resized prior
|
|
to going into fullscreen. */
|
|
height: auto !important;
|
|
}
|
|
|
|
#preview_message_area {
|
|
/* Setting height to 0 is necessary to make the flex+Simplebar
|
|
combination work correctly, without pushing the compose
|
|
controls offscreen when previewing a very tall message. */
|
|
height: 0;
|
|
flex: 1;
|
|
}
|
|
}
|
|
|
|
#compose.compose-fullscreen {
|
|
.maximize-composebox-button,
|
|
.expand-composebox-button {
|
|
display: none;
|
|
}
|
|
|
|
.collapse-composebox-button {
|
|
display: flex;
|
|
}
|
|
}
|
|
|
|
#compose.compose-intermediate,
|
|
#compose.automatically-expanded {
|
|
.collapse-composebox-button,
|
|
.expand-composebox-button {
|
|
display: none;
|
|
}
|
|
|
|
.maximize-composebox-button {
|
|
display: flex;
|
|
}
|
|
}
|
|
|
|
#compose.compose-intermediate {
|
|
height: var(--max-unmaximized-compose-height);
|
|
}
|
|
|
|
.preview_mode {
|
|
#preview-message-area-container {
|
|
/* When in preview mode, we display the
|
|
preview container as a columnar flexbox.
|
|
This containing element is necessary
|
|
because Simplebar on its own will cause
|
|
a grid blowout despite a minmax(0, 1fr)
|
|
row definition. */
|
|
display: flex;
|
|
flex-flow: column;
|
|
}
|
|
|
|
.preview_mode_disabled {
|
|
opacity: 0.3;
|
|
|
|
.compose_control_button {
|
|
pointer-events: none;
|
|
}
|
|
}
|
|
|
|
.message-textarea,
|
|
.message-edit-textbox {
|
|
/* In preview mode, we hide the message edit
|
|
textbox to prevent it from appearing behind
|
|
the preview container. We cannot set its
|
|
display to none or visibility to hidden, as
|
|
that would prevent us from modifying the
|
|
textarea's value.
|
|
|
|
The !important use here in necessary to be sure
|
|
we override the inline styles set on the
|
|
compose textarea. */
|
|
height: 0 !important;
|
|
overflow: hidden !important;
|
|
}
|
|
}
|