mirror of
https://github.com/zulip/zulip.git
synced 2026-06-30 21:11:04 +08:00
Updates a chunk of translated strings that overlap between files, with the streams settings overlay being the starting point for finding these strings, to use channel instead of stream. Part of stream to channel rename project.
1453 lines
37 KiB
CSS
1453 lines
37 KiB
CSS
/* The width of the empty space in the sidebar to separate
|
|
content from the edge of the window */
|
|
$far_left_gutter_size: 10px;
|
|
/* This represents the space in the sidebar reserved for symbols like
|
|
the #; labels like the the stream name go to the right of this. */
|
|
$left_col_size: 19px;
|
|
/* The full topic indentation includes 4px of indent in addition to
|
|
the above (and another 5px of padding not measured here) */
|
|
$topic_indent: calc($far_left_gutter_size + $left_col_size + 4px);
|
|
$topic_resolve_width: 13px;
|
|
/* Space between section in the left sidebar. */
|
|
$sections_vertical_gutter: 8px;
|
|
$bottom_scrolling_buffer: 25px;
|
|
/* space direct message / stream / topic names from unread counters
|
|
and @ mention indicators by 3px on the right */
|
|
$before_unread_count_padding: 3px;
|
|
|
|
.hashtag {
|
|
&:empty {
|
|
&::after {
|
|
content: "#";
|
|
line-height: 0;
|
|
font-size: 18px;
|
|
font-weight: 700;
|
|
}
|
|
}
|
|
}
|
|
|
|
#streams_list .stream-privacy {
|
|
height: 16px;
|
|
font-weight: 700;
|
|
text-align: center;
|
|
|
|
.zulip-icon.zulip-icon-globe {
|
|
font-size: 12px;
|
|
}
|
|
|
|
.zulip-icon.zulip-icon-hashtag {
|
|
font-size: 13px;
|
|
}
|
|
|
|
.zulip-icon.zulip-icon-lock {
|
|
font-size: 13px;
|
|
/* Slight vertical adjustment so the lock
|
|
doesn't sit too high, relative to the
|
|
other stream icons. */
|
|
padding-top: 2px;
|
|
}
|
|
}
|
|
|
|
.left-sidebar-title {
|
|
color: var(--color-text-sidebar-heading);
|
|
font-size: inherit;
|
|
font-weight: normal;
|
|
display: inline;
|
|
/* Override heading margin from Bootstrap. */
|
|
margin: 0;
|
|
/* Show an ellipsis on a heading when
|
|
it won't sit adjacent other icons
|
|
or controls in the row. */
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
}
|
|
|
|
.sidebar-topic-check,
|
|
.topic-markers-and-controls {
|
|
cursor: pointer;
|
|
}
|
|
|
|
#left-sidebar-navigation-list .filter-icon i {
|
|
color: var(--color-left-sidebar-navigation-icon);
|
|
}
|
|
|
|
#stream_filters,
|
|
#left-sidebar-navigation-list {
|
|
margin-right: 12px;
|
|
}
|
|
|
|
li.show-more-topics {
|
|
& a {
|
|
font-size: 12px;
|
|
}
|
|
}
|
|
|
|
#streams_inline_icon,
|
|
.streams_filter_icon {
|
|
opacity: 0.5;
|
|
|
|
&:hover {
|
|
opacity: 1;
|
|
cursor: pointer;
|
|
}
|
|
}
|
|
|
|
.streams_filter_icon.web_public {
|
|
margin-right: 10px;
|
|
}
|
|
|
|
.tooltip {
|
|
max-width: 18em;
|
|
}
|
|
|
|
#stream_filters {
|
|
overflow: visible;
|
|
margin-bottom: 5px;
|
|
margin-right: 12px;
|
|
padding: 0;
|
|
font-weight: normal;
|
|
|
|
.input-append.topic_search_section {
|
|
padding: 2px 0 2px calc($topic_indent - $topic_resolve_width);
|
|
margin-bottom: 3px;
|
|
margin-left: 3px;
|
|
|
|
& input {
|
|
width: calc(100% - 50px);
|
|
}
|
|
|
|
.clear_search_button {
|
|
margin-left: -1px;
|
|
}
|
|
}
|
|
|
|
& li {
|
|
& a:hover {
|
|
text-decoration: none;
|
|
}
|
|
|
|
& ul {
|
|
margin-left: 0;
|
|
|
|
&.topic-list li {
|
|
padding: 2px 0;
|
|
|
|
&.filter-topics {
|
|
padding-bottom: 0;
|
|
position: sticky;
|
|
top: calc($sections_vertical_gutter + 43px);
|
|
z-index: 2;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
.stream-with-count.hide_unread_counts {
|
|
.masked_unread_count {
|
|
display: block;
|
|
/* Shift masked dot to align with
|
|
the least-significant digit on
|
|
unreads in other rows.
|
|
We have to do this with margin,
|
|
because width or padding will
|
|
distort the CSS-created dot. */
|
|
margin-right: 3px;
|
|
}
|
|
|
|
.unread_count {
|
|
display: none;
|
|
}
|
|
}
|
|
|
|
.narrow-filter
|
|
> .bottom_left_row:hover
|
|
> .stream-with-count.hide_unread_counts {
|
|
.masked_unread_count {
|
|
display: none;
|
|
}
|
|
|
|
.unread_count {
|
|
display: inline;
|
|
}
|
|
}
|
|
|
|
.stream-expanded {
|
|
.stream-with-count.hide_unread_counts {
|
|
.masked_unread_count {
|
|
display: none;
|
|
}
|
|
|
|
.unread_count {
|
|
display: inline;
|
|
}
|
|
}
|
|
}
|
|
|
|
.has-unmuted-unreads.hide_unread_counts {
|
|
.masked_unread_count {
|
|
display: none;
|
|
}
|
|
|
|
.unread_count {
|
|
display: inline;
|
|
}
|
|
}
|
|
|
|
.inactive_stream:not(.active-filter) {
|
|
opacity: 0.5;
|
|
}
|
|
|
|
.toggle_stream_mute {
|
|
margin-right: 3px;
|
|
opacity: 0.5;
|
|
|
|
&:hover {
|
|
opacity: 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
.left-sidebar-navigation-area {
|
|
& li a {
|
|
&:hover {
|
|
text-decoration: none;
|
|
}
|
|
}
|
|
}
|
|
|
|
#left_sidebar_scroll_container {
|
|
outline: none;
|
|
overflow: hidden auto;
|
|
position: relative;
|
|
z-index: 0;
|
|
width: 100%;
|
|
|
|
.direct-messages-container {
|
|
/* TODO: Clean up this value and the
|
|
analogous one on #stream-filters;
|
|
this could be done alongside the
|
|
--left-sidebar-collapse-widget-gutter
|
|
cleanup so that all of the left sidebar
|
|
space is better, more uniformly handled.
|
|
That will be an essential pre-condition
|
|
for a resizable left sidebar. */
|
|
margin-right: 12px;
|
|
margin-left: 0;
|
|
}
|
|
}
|
|
|
|
.direct-messages-container {
|
|
/* Properly offset all the grid rows
|
|
in the DM section. */
|
|
margin-right: 12px;
|
|
|
|
#private_messages_section_header {
|
|
grid-template-columns: 0 15px minmax(0, 1fr) max-content 30px 0;
|
|
grid-template-rows: 24px;
|
|
/* TODO: Rewrite the `--left-sidebar-collapse-widget-gutter`
|
|
value and the styles dependent on it so that this kind of
|
|
1990s layout shenanigans is made unnecessary. */
|
|
margin-left: -3px;
|
|
cursor: pointer;
|
|
white-space: nowrap;
|
|
|
|
#toggle_private_messages_section_icon {
|
|
grid-area: starting-anchor-element;
|
|
}
|
|
|
|
.left-sidebar-title {
|
|
grid-area: row-content;
|
|
}
|
|
|
|
.heading-markers-and-controls {
|
|
grid-area: markers-and-controls;
|
|
display: flex;
|
|
gap: 5px;
|
|
align-items: center;
|
|
}
|
|
|
|
#show_all_private_messages {
|
|
width: var(--left-sidebar-header-icon-width);
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
opacity: 0.7;
|
|
text-decoration: none;
|
|
color: inherit;
|
|
|
|
&:hover {
|
|
opacity: 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
& ul.dm-list {
|
|
list-style-type: none;
|
|
font-weight: 400;
|
|
margin-left: 0;
|
|
margin-bottom: 0;
|
|
|
|
& span.fa-group {
|
|
font-size: 90%;
|
|
}
|
|
|
|
& li.dm-list-item {
|
|
& a {
|
|
text-decoration: none;
|
|
color: inherit;
|
|
}
|
|
|
|
.fa-group,
|
|
.zulip-icon {
|
|
opacity: 0.7;
|
|
}
|
|
}
|
|
|
|
& li#show-more-direct-messages {
|
|
cursor: pointer;
|
|
padding-right: 26px;
|
|
/* TODO: Rewrite the show-more and show-less
|
|
buttons as grids alongside the left sidebar
|
|
header rewrites. This padding value
|
|
is a stopgap to provide the same lefthand
|
|
alignment as the "more topics" text, which
|
|
aligns with the topic above--just as this
|
|
aligns with the DM row above. */
|
|
padding-left: 29px;
|
|
|
|
& a {
|
|
font-size: 12px;
|
|
}
|
|
|
|
.unread_count {
|
|
margin-top: 2px;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#toggle_private_messages_section_icon,
|
|
#toggle-top-left-navigation-area-icon {
|
|
opacity: 0.7;
|
|
|
|
&.fa-caret-right {
|
|
position: relative;
|
|
left: 3px;
|
|
}
|
|
|
|
&:hover {
|
|
opacity: 1;
|
|
}
|
|
|
|
&:focus {
|
|
outline: 0;
|
|
}
|
|
|
|
/* This renders an outline when the caret is reached
|
|
with the keyboard, although that is not at present
|
|
easily accomplished. */
|
|
&:focus-visible {
|
|
outline: 2px solid var(--color-outline-focus);
|
|
}
|
|
}
|
|
|
|
.active_private_messages_section {
|
|
#private_messages_section,
|
|
#direct-messages-list,
|
|
#hide-more-direct-messages {
|
|
background-color: hsl(202deg 56% 91%);
|
|
}
|
|
|
|
#private_messages_section {
|
|
border-radius: 4px 4px 0 0;
|
|
}
|
|
|
|
#direct-messages-list {
|
|
border-radius: 0 0 4px 4px;
|
|
}
|
|
|
|
#more_private_messages_sidebar_title {
|
|
font-weight: 600;
|
|
}
|
|
}
|
|
|
|
:not(.active-sub-filter) {
|
|
&.top_left_row:hover,
|
|
&.bottom_left_row:hover {
|
|
background-color: var(--color-background-hover-narrow-filter);
|
|
}
|
|
}
|
|
|
|
.top_left_row,
|
|
.bottom_left_row {
|
|
/* Ensure a border radius on any interactive
|
|
state that might show a highlight. */
|
|
border-radius: 4px;
|
|
}
|
|
|
|
#stream_filters .narrow-filter.highlighted_stream {
|
|
&.active-filter > .bottom_left_row {
|
|
background-color: var(--color-background-hover-narrow-filter);
|
|
}
|
|
|
|
&.active-filter .topic-list .bottom_left_row {
|
|
background-color: var(--color-background-active-narrow-filter);
|
|
}
|
|
|
|
.bottom_left_row:not(.active-sub-filter) {
|
|
background-color: var(--color-background-hover-narrow-filter);
|
|
}
|
|
}
|
|
|
|
#login-link-container,
|
|
#subscribe-to-more-streams {
|
|
text-decoration: none;
|
|
margin: 5px auto 5.5px 10px;
|
|
margin-bottom: $bottom_scrolling_buffer;
|
|
|
|
& i {
|
|
min-width: 19px;
|
|
text-align: center;
|
|
|
|
&::before {
|
|
padding-right: 3px;
|
|
}
|
|
}
|
|
}
|
|
|
|
#login-link-container .login_button {
|
|
display: flex;
|
|
align-items: center;
|
|
}
|
|
|
|
ul.filters {
|
|
list-style-type: none;
|
|
margin-left: 0;
|
|
color: hsl(0deg 0% 20% / 100%);
|
|
|
|
& a {
|
|
color: inherit;
|
|
|
|
&:focus {
|
|
text-decoration: none;
|
|
}
|
|
}
|
|
|
|
& hr {
|
|
margin-top: 10px;
|
|
margin-bottom: 10px;
|
|
}
|
|
|
|
.has-only-muted-unreads {
|
|
.unread_count {
|
|
opacity: 0.5;
|
|
}
|
|
}
|
|
|
|
.has-only-muted-mentions .unread_mention_info {
|
|
opacity: 0.5;
|
|
}
|
|
|
|
/* This is a noop in the current design, because unread counts for
|
|
muted streams have the same opacity, but the logic is here to
|
|
be explicit and because the design may change in the future. */
|
|
.more_topic_unreads_muted_only .unread_count {
|
|
opacity: 0.5;
|
|
}
|
|
|
|
.zulip-icon-follow {
|
|
opacity: 0.6;
|
|
}
|
|
|
|
& li.muted_topic,
|
|
li.out_of_home_view {
|
|
color: hsl(0deg 0% 20% / 50%);
|
|
|
|
.has-unmuted-mentions .unread_mention_info {
|
|
color: hsl(0deg 0% 20%);
|
|
}
|
|
|
|
.stream-privacy {
|
|
opacity: 0.5;
|
|
}
|
|
|
|
& .unread_count {
|
|
opacity: 0.5;
|
|
}
|
|
|
|
& .masked_unread_count {
|
|
opacity: 0.5;
|
|
}
|
|
|
|
.has-unmuted-unreads {
|
|
.unread_count {
|
|
opacity: 1;
|
|
}
|
|
}
|
|
|
|
& li.unmuted_or_followed_topic {
|
|
color: var(--color-unmuted-or-followed-topic-list-item);
|
|
|
|
.unread_count {
|
|
opacity: 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
& li.out_of_home_view {
|
|
&:hover {
|
|
color: hsla(0deg 0% 20% / 75%);
|
|
|
|
.stream-privacy {
|
|
opacity: 0.75;
|
|
}
|
|
|
|
.unread_count {
|
|
opacity: 0.75;
|
|
}
|
|
|
|
.has-unmuted-unreads {
|
|
.unread_count {
|
|
opacity: 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
& li.muted_topic {
|
|
/* If stream is muted, this resets opacity of muted topics in muted
|
|
stream to 1; since opacity is multiplied down through child
|
|
elements, this avoids an unreadably low opacity. */
|
|
opacity: 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
li.active-filter,
|
|
li.active-sub-filter {
|
|
font-weight: 600 !important;
|
|
position: relative;
|
|
border-radius: 4px;
|
|
background-color: var(--color-background-active-narrow-filter);
|
|
}
|
|
|
|
#stream_filters .narrow-filter.active-filter {
|
|
.topic-list .filter-topics,
|
|
> .bottom_left_row {
|
|
background-color: var(--color-background-active-narrow-filter);
|
|
border-radius: 4px;
|
|
}
|
|
}
|
|
|
|
#left-sidebar-navigation-list-condensed {
|
|
display: flex;
|
|
justify-content: center;
|
|
|
|
.left-sidebar-navigation-condensed-item {
|
|
/* 24px minimum width from Vlad's design. */
|
|
flex: 1 0 24px;
|
|
/* Unset padding from individual top_left items */
|
|
padding: 0;
|
|
border-radius: 4px;
|
|
/* Set a positioning context for the unread dot. */
|
|
position: relative;
|
|
|
|
.unread_count {
|
|
position: absolute;
|
|
}
|
|
|
|
/* Show the same styles when each item is
|
|
hovered or, via the keyboard, the `<a>`
|
|
element within receives focus. */
|
|
&:hover,
|
|
&:focus-within {
|
|
background: var(--color-background-hover-narrow-filter);
|
|
|
|
.unread_count {
|
|
top: -6px;
|
|
right: -6px;
|
|
background: var(--color-background-unread-counter-no-alpha);
|
|
}
|
|
}
|
|
|
|
&:not(:hover) .unread_count {
|
|
top: 2px;
|
|
right: 2px;
|
|
width: 6px;
|
|
height: 6px;
|
|
font-size: 0;
|
|
padding: 0;
|
|
background-color: var(--color-background-unread-counter-dot);
|
|
}
|
|
|
|
&.top_left_starred_messages .unread_count {
|
|
display: none;
|
|
}
|
|
}
|
|
|
|
.left-sidebar-navigation-icon-container {
|
|
/* Unset margin from full nav list anchor elements. */
|
|
margin: 0;
|
|
/* Horizontally center icons within their boxes. */
|
|
text-align: center;
|
|
|
|
&:focus {
|
|
/* Unset inherited :focus outline. */
|
|
outline: 0;
|
|
}
|
|
}
|
|
|
|
.active-filter {
|
|
/* Don't display a background on condensed icons. */
|
|
background: unset;
|
|
}
|
|
|
|
.filter-icon {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
/* TODO: Set this 24px height value as a variable.
|
|
Keep filter-icon height the full height of the box. */
|
|
height: 24px;
|
|
/* Enlarge icons slightly in condensed views. */
|
|
font-size: 15px;
|
|
color: var(--color-left-sidebar-navigation-icon);
|
|
}
|
|
}
|
|
|
|
#left-sidebar-navigation-list {
|
|
margin-bottom: $sections_vertical_gutter;
|
|
/* We display this as a grid only to control
|
|
the order of home views, using a single
|
|
named grid area. */
|
|
display: grid;
|
|
grid-template-areas: "selected-home-view";
|
|
|
|
.left-sidebar-navigation-label-container {
|
|
.left-sidebar-navigation-label {
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
}
|
|
}
|
|
}
|
|
|
|
.selected-home-view {
|
|
/* This bumps the selected view to the
|
|
top of the grid (expanded list).
|
|
Others items will auto place in the
|
|
remaining auto-generated grid rows. */
|
|
grid-area: selected-home-view;
|
|
/* The condensed view is a flexbox, so
|
|
here we'll use a negative order to
|
|
bump the selected home view to the
|
|
start of the flexbox (lefthand side). */
|
|
order: -1;
|
|
}
|
|
|
|
.top_left_starred_messages .unread_count,
|
|
.top_left_drafts .unread_count,
|
|
.top_left_scheduled_messages .unread_count,
|
|
.condensed-views-popover-menu .unread_count {
|
|
background-color: unset;
|
|
color: inherit;
|
|
border: 0.5px solid var(--color-border-unread-counter);
|
|
}
|
|
|
|
/* Don't show unread counts on views... */
|
|
.top_left_inbox,
|
|
.top_left_recent_view,
|
|
.top_left_all_messages {
|
|
.unread_count {
|
|
visibility: hidden;
|
|
}
|
|
/* ...unless it's the selected home view. */
|
|
&.selected-home-view .unread_count {
|
|
visibility: visible;
|
|
}
|
|
}
|
|
|
|
/* Don't show the scheduled messages item... */
|
|
li.top_left_scheduled_messages {
|
|
display: none;
|
|
/* ...unless there are scheduled messages to show. */
|
|
&.show-with-scheduled-messages {
|
|
/* Use display: grid to preserve the grid
|
|
layout when visible. */
|
|
display: grid;
|
|
}
|
|
}
|
|
|
|
.top_left_row {
|
|
/* The row grid for the outer .top_left_row
|
|
is chiefly for lefthand spacing and placing
|
|
the inner row content and vdots. */
|
|
grid-template-columns: 7px 0 minmax(0, 1fr) 0 30px 0;
|
|
|
|
.sidebar-menu-icon {
|
|
grid-area: ending-anchor-element;
|
|
}
|
|
}
|
|
|
|
.left-sidebar-navigation-label-container {
|
|
grid-area: row-content;
|
|
/* The label container itself is also a grid,
|
|
for laying out the items that are its
|
|
children. Same template areas, different
|
|
column widths. */
|
|
grid-template-columns: 0 22px minmax(0, 1fr) max-content 0 0;
|
|
/* This is a legacy value, from a former
|
|
1px of top padding on top_left_row plus
|
|
an inner 1px top margin on `<a>` elements.
|
|
|
|
These are added here, rather than on the label
|
|
container, to keep all hovered/highlighted areas
|
|
clickable.
|
|
|
|
This complicates true centering within a
|
|
row highlight. It might be better to make
|
|
these both 2px.
|
|
*/
|
|
padding-top: 2px;
|
|
padding-bottom: 1px;
|
|
|
|
.filter-icon {
|
|
grid-area: starting-anchor-element;
|
|
/* Use a flex container to handle
|
|
icon centering within the grid area. */
|
|
display: flex;
|
|
justify-content: center;
|
|
}
|
|
|
|
.left-sidebar-navigation-label {
|
|
grid-area: row-content;
|
|
padding-right: $before_unread_count_padding;
|
|
}
|
|
|
|
.unread_count {
|
|
grid-area: markers-and-controls;
|
|
}
|
|
}
|
|
|
|
.conversation-partners {
|
|
grid-area: row-content;
|
|
/* Set an 18px line-height to better vertically
|
|
center user circles and icons (both of which
|
|
have even heights). */
|
|
line-height: 18px;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
/* Use an inline grid to provide a modern layout
|
|
for status emoji in DM rows, while preserving
|
|
the expected ellipsis behavior on long usernames
|
|
or large DM groups.
|
|
The 16px-tall emoji will also align well
|
|
vertically with the 18px line-height here. */
|
|
display: inline-grid;
|
|
/* Provide a two-column grid, sized to accommodate
|
|
the content of the conversation list and status
|
|
emoji, if any. */
|
|
grid-template-columns: repeat(2, minmax(0, max-content));
|
|
align-items: center;
|
|
}
|
|
|
|
.conversation-partners .status-emoji {
|
|
/* Prevent status emoji from colliding
|
|
with unread counts. */
|
|
margin-right: 3px;
|
|
}
|
|
|
|
/* New .topic-box grid definitions here. */
|
|
#views-label-container,
|
|
.top_left_row,
|
|
.left-sidebar-navigation-label-container,
|
|
.dm-box,
|
|
.subscription_block,
|
|
.topic-box {
|
|
display: grid;
|
|
align-items: center;
|
|
/* This general pattern of elements applies to every single row in the left
|
|
sidebar, to some degree or another. Eventually, these template areas
|
|
could be applied to all rows, with different `grid-template-column`
|
|
values applied as needed (and shared as needed). For example, an element
|
|
with no "starting-offset" sets that area to `0`; so too with other non-
|
|
existent elements.
|
|
|
|
The offsets themselves are meant to greedily assign all of the available
|
|
horizontal space to the content area of the row. That space can then be
|
|
modified or reassigned as needed, without running up against `padding`
|
|
(which alters the box size) or `margin` (which notoriously bleeds outside
|
|
of the element it's defined on). */
|
|
grid-template-areas: "starting-offset starting-anchor-element row-content markers-and-controls ending-anchor-element ending-offset";
|
|
}
|
|
|
|
#private_messages_section_header,
|
|
#streams_header,
|
|
#topics_header {
|
|
display: grid;
|
|
align-items: center;
|
|
/* This extends the general pattern of left sidebar rows, but includes a
|
|
second grid row for placing filter boxes. This pattern keeps the box
|
|
aligned with the text content in `row-content` and includes the
|
|
`ending-anchor-element` space.
|
|
|
|
There is currently no filter box on DM rows, but we can prepare for
|
|
that now by having it share this grid template. Its row and column
|
|
definitions have the final say about dimensions and placement. */
|
|
grid-template-areas:
|
|
"starting-offset starting-anchor-element row-content markers-and-controls ending-anchor-element ending-offset"
|
|
". . filter-box filter-box filter-box . ";
|
|
}
|
|
|
|
#views-label-container {
|
|
grid-template-columns:
|
|
0 15px minmax(0, 0.5fr) minmax(0, 1fr)
|
|
30px 12px;
|
|
/* Base height on 24px icon-target area from Vlad's design. */
|
|
grid-template-rows: 24px;
|
|
/* TODO: Rewrite the `--left-sidebar-collapse-widget-gutter`
|
|
value and the styles dependent on it so that this kind of
|
|
1990s layout shenanigans is made unnecessary. */
|
|
margin-left: -3px;
|
|
cursor: pointer;
|
|
|
|
&.showing-expanded-navigation {
|
|
/* When the expanded navigation is visible,
|
|
hide the condensed navigation's controls. */
|
|
#left-sidebar-navigation-list-condensed,
|
|
.left-sidebar-navigation-menu-icon {
|
|
display: none;
|
|
}
|
|
/* Give the sidebar title through the end of the markers
|
|
area, if needed. */
|
|
.left-sidebar-title {
|
|
grid-column: row-content-start / markers-and-controls-end;
|
|
}
|
|
}
|
|
|
|
/* Use a next-sibling combinator (+) to use CSS to show and hide
|
|
filter rows as needed, based on the narrow. */
|
|
&.showing-condensed-navigation {
|
|
+ #left-sidebar-navigation-list {
|
|
/* When the navigation area is condensed, hide all
|
|
the rows in the full navigation list... */
|
|
& .top_left_row {
|
|
display: none;
|
|
}
|
|
/* ...except when there is an active filter in place:
|
|
that row should still be shown. */
|
|
& .top_left_row.active-filter {
|
|
display: grid;
|
|
}
|
|
}
|
|
}
|
|
|
|
#toggle-top-left-navigation-area-icon {
|
|
grid-area: starting-anchor-element;
|
|
}
|
|
|
|
.left-sidebar-title {
|
|
grid-area: row-content;
|
|
}
|
|
|
|
#left-sidebar-navigation-list-condensed {
|
|
margin: 0;
|
|
grid-area: markers-and-controls;
|
|
}
|
|
|
|
.left-sidebar-navigation-menu-icon {
|
|
grid-area: ending-anchor-element;
|
|
/* Horizontally center vdots. */
|
|
justify-self: center;
|
|
/* Properly size vdots. */
|
|
font-size: 17px;
|
|
/* Occupy same clickable height as
|
|
other condensed-view icons */
|
|
height: 24px;
|
|
/* Vertically center dots with
|
|
flexbox. */
|
|
display: flex;
|
|
align-items: center;
|
|
color: var(--color-left-sidebar-header-vdots-visible);
|
|
|
|
&:hover {
|
|
color: var(--color-vdots-hover);
|
|
}
|
|
}
|
|
}
|
|
|
|
.condensed-views-popover-menu {
|
|
.left-sidebar-popover-icon-label-count {
|
|
display: flex;
|
|
align-items: baseline;
|
|
}
|
|
|
|
.filter-icon {
|
|
align-self: center;
|
|
height: 15px;
|
|
}
|
|
|
|
.left-sidebar-navigation-label {
|
|
flex: 1 0 0;
|
|
margin-left: 3px;
|
|
}
|
|
|
|
.unread_count {
|
|
margin-left: 6px;
|
|
border-color: var(--color-border-unread-counter-popover-menu);
|
|
}
|
|
}
|
|
|
|
.subscription_block {
|
|
grid-template-columns:
|
|
7px 22px minmax(0, 1fr) minmax(0, max-content)
|
|
30px 0;
|
|
white-space: nowrap;
|
|
|
|
.stream-privacy {
|
|
grid-area: starting-anchor-element;
|
|
}
|
|
|
|
.stream-name {
|
|
grid-area: row-content;
|
|
}
|
|
}
|
|
|
|
.topic-box {
|
|
/* Padding from original .topic-box definition. */
|
|
padding-top: 1px;
|
|
grid-template-columns:
|
|
25px $topic_resolve_width minmax(0, 1fr) minmax(0, max-content)
|
|
30px 0;
|
|
|
|
.topic-name {
|
|
cursor: pointer;
|
|
grid-area: row-content;
|
|
padding: 1px $before_unread_count_padding 1px 0;
|
|
|
|
/* TODO: We should figure out how to remove this without changing the spacing */
|
|
line-height: 1.1;
|
|
|
|
/* TODO: Consolidate these styles with conversation partners and stream name
|
|
once grid rewrite is complete on all sidebar rows.
|
|
|
|
Also: note that these styles will be moot for topic names once we allow
|
|
for multiline topics. If we hold multiline topics to a certain number
|
|
of lines, we'll likely need a JavaScript-based solution like Clamp.js
|
|
to display an ellipsis on the final visible line. */
|
|
white-space: nowrap;
|
|
/* Both `hidden` and `clip` are shown for the sake
|
|
of older browsers that do not support `clip`. */
|
|
overflow-x: hidden;
|
|
overflow-x: clip;
|
|
text-overflow: ellipsis;
|
|
}
|
|
}
|
|
|
|
.topic-box .zero_count {
|
|
display: none;
|
|
}
|
|
|
|
.sidebar-topic-check {
|
|
grid-area: starting-anchor-element;
|
|
font-size: 15px;
|
|
height: 20px;
|
|
}
|
|
|
|
.stream-markers-and-controls,
|
|
.topic-markers-and-controls {
|
|
grid-area: markers-and-controls;
|
|
display: flex;
|
|
/* Present a uniform space between icons */
|
|
gap: 5px;
|
|
align-items: center;
|
|
|
|
.unread_mention_info {
|
|
/* Unset margin in favor of flex gap. */
|
|
margin: 0;
|
|
}
|
|
|
|
.unread_count {
|
|
/* Height is set here by the flexbox; this
|
|
decouples .unread_count from the app-wide
|
|
definition. */
|
|
height: auto;
|
|
}
|
|
}
|
|
|
|
.bottom_left_row .sidebar-menu-icon {
|
|
grid-area: ending-anchor-element;
|
|
}
|
|
|
|
.conversation-partners-list,
|
|
.stream-name {
|
|
white-space: nowrap;
|
|
overflow-x: hidden;
|
|
overflow-x: clip;
|
|
text-overflow: ellipsis;
|
|
padding: 1px $before_unread_count_padding 1px 0;
|
|
}
|
|
|
|
.conversation-partners-list {
|
|
/* TODO: See about consolidating or re-expressing
|
|
.stream-name spacing so as to not require
|
|
padding there, either. */
|
|
padding: 0;
|
|
}
|
|
|
|
/*
|
|
All of our left sidebar handlers use absolute
|
|
positioning. We should fix that.
|
|
*/
|
|
.bottom_left_row .sidebar-menu-icon,
|
|
.top_left_row .sidebar-menu-icon {
|
|
display: none;
|
|
width: 100%;
|
|
cursor: pointer;
|
|
/* Use a flex container to handle
|
|
icon centering within the grid area.
|
|
:hover actually sets the `display: flex`,
|
|
so it remains hidden otherwise. */
|
|
justify-content: center;
|
|
text-align: center;
|
|
/* Set the icon size, which will be inherited
|
|
by .zulip-icon */
|
|
font-size: 17px;
|
|
|
|
/*
|
|
If you hover directly over the ellipsis itself,
|
|
show it in black.
|
|
*/
|
|
|
|
&:hover {
|
|
color: var(--color-vdots-hover);
|
|
}
|
|
|
|
/*
|
|
Hover does not work for touch-based devices like mobile phones.
|
|
Hence the the icons does not appear, making the user unaware of its
|
|
presence on such devices. The following media property displays the
|
|
icon by default for such behaviour.
|
|
*/
|
|
|
|
@media (hover: none) {
|
|
display: flex;
|
|
/* Show dots on touchscreens in a less distracting,
|
|
lighter shade. */
|
|
color: var(--color-vdots-hint);
|
|
}
|
|
}
|
|
|
|
/*
|
|
When you hover over list items, we hover
|
|
the vdots in light gray.
|
|
|
|
The stream icon should always display when
|
|
any topic is hovered, which is why it gets
|
|
a more specific selector here.
|
|
*/
|
|
#stream_filters li:hover .stream-sidebar-menu-icon,
|
|
.top_left_row:hover .sidebar-menu-icon,
|
|
.bottom_left_row:hover .sidebar-menu-icon,
|
|
.app-main .column-left .left-sidebar .left_sidebar_menu_icon_visible {
|
|
/* We push against `display: none` with
|
|
`display: flex` because the sidebar vdots
|
|
all expect to be displayed as flex items
|
|
when visible. Their vertical alignment
|
|
depends on it, too. */
|
|
display: flex;
|
|
color: var(--color-vdots-visible);
|
|
|
|
/*
|
|
If you hover directly over the vdots icon,
|
|
show it in black.
|
|
*/
|
|
&:hover {
|
|
color: var(--color-vdots-hover);
|
|
}
|
|
}
|
|
|
|
/*
|
|
For topic ellipsis-v(vertical 3 dots) we use a slightly smaller
|
|
font to show they're "lower" in the hierarchy,
|
|
which also affects it positioning.
|
|
*/
|
|
.topic-sidebar-menu-icon {
|
|
/* 0.9em, but with a pixel value because the
|
|
ordinary 17px vdots size is not inherited
|
|
here, so we can't express an em-value
|
|
directly. Pixels are easier to reason
|
|
about with icons, anyway. */
|
|
font-size: 15.3px;
|
|
}
|
|
|
|
ul.topic-list {
|
|
list-style-type: none;
|
|
font-weight: normal;
|
|
}
|
|
|
|
li.topic-list-item {
|
|
position: relative;
|
|
padding-right: 5px;
|
|
}
|
|
|
|
.dm-box {
|
|
grid-template-columns: 7px 22px minmax(0, 1fr) minmax(0, max-content) 30px 0;
|
|
/* This padding maintains a 22px height on DM rows. */
|
|
padding: 2px 0;
|
|
|
|
.conversation-partners-icon {
|
|
grid-area: starting-anchor-element;
|
|
place-self: center;
|
|
}
|
|
|
|
.user_circle {
|
|
width: 8px;
|
|
height: 8px;
|
|
/* TODO: Remove these after right-sidebar
|
|
row rewrites. */
|
|
float: none;
|
|
position: static;
|
|
}
|
|
|
|
.zulip-icon.zulip-icon-bot {
|
|
font-size: 90%; /* Reduce the bulkiness of this icon */
|
|
}
|
|
|
|
.unread_count {
|
|
grid-area: markers-and-controls;
|
|
/* TODO: This is an alternative method
|
|
for presenting a 16px-tall unread
|
|
counter, regardless of context. This
|
|
method could be used app-wide once
|
|
all of the layout methods for presenting
|
|
unreads have been modernized.
|
|
|
|
Set the line-height to match the
|
|
font-size, so that the numerals sit in
|
|
a 12px box. */
|
|
line-height: 12px;
|
|
/* Use flexbox to vertically center
|
|
the 12px-high text node within the
|
|
16px-high unread box. */
|
|
display: flex;
|
|
align-items: center;
|
|
}
|
|
}
|
|
|
|
.zoom-out {
|
|
#topics_header {
|
|
display: none;
|
|
}
|
|
|
|
.zoom-out-hide {
|
|
display: none;
|
|
}
|
|
}
|
|
|
|
#topics_header {
|
|
position: sticky;
|
|
top: 0;
|
|
z-index: 2;
|
|
grid-template-columns: 0 0 minmax(0, 1fr) max-content 0 42px;
|
|
grid-template-rows: 24px;
|
|
padding-top: $sections_vertical_gutter;
|
|
color: hsl(0deg 0% 43%);
|
|
background-color: var(--color-background);
|
|
|
|
.show-all-streams {
|
|
grid-area: row-content;
|
|
color: inherit;
|
|
text-decoration: none;
|
|
text-transform: uppercase;
|
|
margin-left: calc($far_left_gutter_size + 2px);
|
|
|
|
& i {
|
|
margin: 0 6px 0 13px;
|
|
position: relative;
|
|
top: 1px;
|
|
}
|
|
}
|
|
|
|
.unread_count {
|
|
grid-area: markers-and-controls;
|
|
}
|
|
}
|
|
|
|
#streams_header {
|
|
grid-template-columns: 0 0 minmax(0, 1fr) minmax(17px, max-content) 30px 12px;
|
|
/* Keep the stream-search area rows collapsed. */
|
|
grid-template-rows: 24px 0 0;
|
|
cursor: pointer;
|
|
padding: $sections_vertical_gutter 0 3px calc($far_left_gutter_size + 2px);
|
|
position: sticky;
|
|
/* Keep sticky within SimpleBar context. */
|
|
top: 0;
|
|
background-color: var(--color-background);
|
|
/* Ideally, 0px should work here, but maybe simplebar is doing something
|
|
that is creating `0.5px` extra gap in zoomed-in windows. */
|
|
z-index: 1;
|
|
|
|
&.showing-stream-search-section {
|
|
/* Open up the stream-search rows. The 10px
|
|
row maintains space with the streams list
|
|
below. */
|
|
grid-template-rows: 24px 28px 10px;
|
|
}
|
|
|
|
.left-sidebar-title {
|
|
grid-area: row-content;
|
|
}
|
|
|
|
.heading-markers-and-controls {
|
|
grid-area: markers-and-controls;
|
|
height: 100%;
|
|
display: flex;
|
|
align-items: center;
|
|
grid-gap: 5px;
|
|
}
|
|
|
|
#filter_streams_tooltip {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
width: var(--left-sidebar-header-icon-width);
|
|
}
|
|
|
|
#add_streams_tooltip {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
width: var(--left-sidebar-header-icon-width);
|
|
}
|
|
|
|
.input-append {
|
|
grid-area: filter-box;
|
|
display: flex;
|
|
justify-content: stretch;
|
|
/* Set an even line-height for better
|
|
vertical centering. */
|
|
line-height: 20px;
|
|
white-space: nowrap;
|
|
|
|
& input {
|
|
/* Use the border-box model so flex
|
|
can do its thing despite whatever
|
|
padding and border we specify. */
|
|
box-sizing: border-box;
|
|
flex: 1 0 100%;
|
|
/* Match the input height exactly
|
|
with the row height for a perfect
|
|
fit and better vertical alignment. */
|
|
height: 28px;
|
|
/* Pad the entire clear-button area,
|
|
so that input text does not bleed
|
|
into there. */
|
|
padding-right: 30px;
|
|
}
|
|
|
|
.clear_search_button {
|
|
/* Use the border-box model so flex
|
|
can do its thing despite whatever
|
|
padding and border we specify. */
|
|
box-sizing: border-box;
|
|
/* Clear inherited positioning. */
|
|
position: static;
|
|
/* We're going to use flexbox, not
|
|
positioning, to get the clear button
|
|
over top of the input. This -30px
|
|
margin accomplishes that, in tandem
|
|
with the 30px width of this element,
|
|
which is shared with the ending
|
|
anchor element in left sidebar header
|
|
rows. */
|
|
width: 30px;
|
|
margin-left: -30px;
|
|
/* Flexbox respects z-index; this just
|
|
ensures the button remains over top
|
|
of the input. */
|
|
z-index: 1;
|
|
/* Make the button itself a flex container,
|
|
so we can perfectly center the X icon. */
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
/* Flexbox will pull the element open
|
|
to make a generous clickable area. */
|
|
padding: 0;
|
|
}
|
|
}
|
|
|
|
&.hide_unread_counts {
|
|
.unread_count,
|
|
.unread_count.hide,
|
|
.masked_unread_count {
|
|
display: none;
|
|
}
|
|
|
|
/* When an empty unread count is hidden,
|
|
hide the masked unread count, too. */
|
|
.unread_count.hide + .masked_unread_count {
|
|
display: none;
|
|
}
|
|
|
|
.masked_unread_count {
|
|
display: block;
|
|
/* Hold space enough so single-digit
|
|
unreads don't shift on hover. */
|
|
margin: 0 3px;
|
|
}
|
|
|
|
&:hover {
|
|
.unread_count {
|
|
display: block;
|
|
}
|
|
|
|
.hide,
|
|
.masked_unread_count {
|
|
display: none;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Prepare an adjusted grid for the logged-out state,
|
|
one that reassigns the vdots space to markers and
|
|
controls. */
|
|
.spectator-view #streams_header {
|
|
grid-template-columns: 0 0 minmax(0, 1fr) minmax(30px, max-content) 0 12px;
|
|
|
|
/* With markers and controls now sized the same
|
|
as the ordinary vdots area (but allowed to grow,
|
|
care of `minmax(30px, max-content)`, should
|
|
additional logged-out icons be added in the
|
|
future), let's center the icon in that area,
|
|
just like vdots would be. */
|
|
.heading-markers-and-controls {
|
|
justify-content: center;
|
|
}
|
|
}
|
|
|
|
.streams_subheader {
|
|
font-size: 0.8em;
|
|
font-weight: normal;
|
|
padding-left: $far_left_gutter_size;
|
|
cursor: pointer;
|
|
text-align: center;
|
|
margin-right: 12px;
|
|
color: hsl(240deg 10% 50%);
|
|
|
|
& span {
|
|
display: flex;
|
|
flex-direction: row;
|
|
width: 100%;
|
|
left: 0.5em;
|
|
right: 0.5em;
|
|
opacity: 0.5;
|
|
}
|
|
|
|
& span::before,
|
|
span::after {
|
|
content: " ";
|
|
flex: 1 1;
|
|
vertical-align: middle;
|
|
margin: auto;
|
|
border: 0.5px solid hsl(240deg 10% 50%);
|
|
opacity: 0.2;
|
|
}
|
|
|
|
& span::before {
|
|
margin-right: 0.5em;
|
|
}
|
|
|
|
& span::after {
|
|
margin-left: 0.5em;
|
|
}
|
|
}
|
|
|
|
.stream-list-filter {
|
|
white-space: nowrap;
|
|
text-overflow: ellipsis;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.topic-list-filter {
|
|
/* Input width = 100% - 30px right-margin - 6px right-padding */
|
|
/* To keep the right edge of input along with its borders inline with other
|
|
topic items we consider to subtract the space given for right margin of
|
|
other items, and right padding of input element. */
|
|
width: calc(100% - 36px);
|
|
}
|
|
|
|
.zero_count {
|
|
visibility: hidden;
|
|
}
|
|
|
|
.zero-topic-unreads.show-more-topics .topic-box {
|
|
margin-right: 30px;
|
|
}
|
|
|
|
.searching-for-more-topics img {
|
|
height: 16px;
|
|
margin-left: 6px;
|
|
}
|
|
|
|
.zoom-in {
|
|
.narrow-filter > .bottom_left_row {
|
|
position: sticky;
|
|
top: calc($sections_vertical_gutter + 20px);
|
|
z-index: 2;
|
|
padding-bottom: 1px;
|
|
background-color: var(--color-background);
|
|
}
|
|
|
|
#streams_header,
|
|
#subscribe-to-more-streams,
|
|
.show-more-topics {
|
|
display: none;
|
|
}
|
|
|
|
&.direct-messages-container ul.dm-list {
|
|
margin-bottom: $bottom_scrolling_buffer;
|
|
}
|
|
|
|
#more_private_messages_sidebar_title {
|
|
display: inline;
|
|
}
|
|
|
|
#hide-more-direct-messages {
|
|
display: block;
|
|
text-decoration: none;
|
|
color: inherit;
|
|
font-size: 12px;
|
|
|
|
& span {
|
|
display: block;
|
|
/* TODO: Rewrite the show-more and show-less
|
|
buttons as grids alongside the left sidebar
|
|
header rewrites. The 12px left padding here
|
|
aligns the "back to channels" text with the
|
|
DIRECT MESSAGES heading above, which itself
|
|
is offset -3 px to the left, but reserves
|
|
15px for the arrow marker. 15px - 3px = 12px. */
|
|
padding: 2px 0 2px 12px;
|
|
}
|
|
|
|
&:hover {
|
|
& span {
|
|
background-color: hsl(120deg 12.3% 71.4% / 38%);
|
|
border-radius: 4px;
|
|
}
|
|
}
|
|
}
|
|
|
|
.zoom-in-hide {
|
|
display: none;
|
|
}
|
|
|
|
.zoom-in-sticky {
|
|
position: sticky;
|
|
top: 0;
|
|
z-index: 1;
|
|
}
|
|
}
|