zulip/web/styles/zulip.css

3298 lines
74 KiB
CSS

html {
overflow-y: scroll;
overflow-x: hidden;
overscroll-behavior-y: none;
width: calc(100% - var(--disabled-scrollbar-width));
}
body,
html {
height: 100%;
touch-action: manipulation;
}
.column-middle,
#main_div {
background-color: var(--color-background);
}
#app-loading.loaded {
display: none !important; /* We are now loaded, by definition. */
}
body {
width: 100%;
font-size: 14px;
line-height: calc(20 / 14);
font-family: "Source Sans 3 VF", sans-serif;
color: var(--color-text-default);
background-color: var(--color-background);
transition: background-color 200ms linear;
/* Implementation for fluid layout width setting. */
.header-main,
.app .app-main,
#compose-container {
max-width: 1400px;
}
&.fluid_layout_width {
.header-main,
.app .app-main,
#compose-container {
max-width: inherit;
}
}
}
:root {
color-scheme: light;
/*
This is the header, aka the navbar.
*/
--header-height: 40px;
@media (width < $sm_min) {
--header-height: 30px;
}
/*
Since #navbar_alerts_wrapper can take variable height depending upon
window width / language, we sync its height in navbar_alerts.js
*/
--navbar-alerts-wrapper-height: 0px;
--navbar-fixed-height: calc(
var(--header-height) + var(--navbar-alerts-wrapper-height)
);
/*
We have a 10px gutter below the header,
which often needs to be respected by both
the elements above it and below it on
the y-axis, due to absolute positioning.
*/
--header-padding-bottom: 10px;
/*
Our sidebars (and anything that top-align
with them) go beneath the header.
*/
--left-sidebar-collapse-widget-gutter: 10px;
--left-sidebar-width: 270px;
--right-sidebar-width: 250px;
/*
Message box elements and values.
*/
--message-box-avatar-width: 35px;
--message-box-avatar-height: var(--message-box-avatar-width);
--message-box-line-height: 1.214;
--message-box-icon-width: 26px;
--message-box-icon-height: 25px;
/*
Left position of unread marker. Only needs to be tracked if it is negative so that
it doesn't leak through message header.
*/
--unread-marker-left: -1px;
/*
Compose-recipient box minimum height. Used in a flexbox context to
allow elements like DM pills to stack without breaking out of their
flex item.
*/
--compose-recipient-box-min-height: 30.5px;
/*
Width to be reserved for document scrollbar when scrolling is disabled.
Using `scrollbar-gutter` would be more appropriate but doesn't has wide
support and doesn't work for `fixed` elements.
*/
--disabled-scrollbar-width: 0px;
/*
Right offset of simplebar scrollbar for `.column-right` when browser has
overlay scrollbars which don't occupy any space. Currently only
known to present on Mac (all browsers) and Firefox (all OS?). This seems
more than enough to differentiate right sidebar scrollbar and browser
scrollbar even if the browser scrollbar is wider.
*/
--browser-overlay-scrollbar-width: 10px;
/* This is a rough estimate for height occupied by Recent Conversations filters.
We expect `resize.js` to update this once UI is initialized. */
--recent-topics-filters-height: 50px;
/* Overlay heights for streams modal */
--modal-container-height: 95vh;
--modal-container-max-height: 1000px;
/* .subscriptions-header */
--modal-container-subscriptions-header-height: 45px;
/* .display-type */
--modal-container-subscriptions-display-type-height: 44px;
/* .modal-footer */
--modal-container-subscriptions-modal-footer-height: 60px;
/*
Maximum height of the compose box when it is not in expanded state. This
is equal to the height of `#bottom_whitespace`. We expect resize.js to
replace it with its pixel calculation since even if `vh` has great support,
it can change depending on browser / OS on mobile devices.
*/
--max-unexpanded-compose-height: 40vh;
/* Colors used across the app */
--color-date: hsl(0deg 0% 15% / 75%);
--color-background-private-message-header: hsl(46deg 35% 93%);
--color-background-private-message-content: hsl(45deg 20% 96%);
--color-background-stream-message-content: hsl(0deg 0% 100%);
--color-message-list-border: hsl(0deg 0% 0% / 16%);
--color-message-header-contents-border: hsl(0deg 0% 0% / 10%);
--color-private-message-header-border: hsl(0deg 0% 0% / 10%);
--color-message-header-contents-border-bottom: hsl(0deg 0% 0% / 5%);
--color-private-message-header-border-bottom: hsl(0deg 0% 0% / 7%);
--color-message-header-icon-non-interactive: hsl(0deg 0% 0% / 30%);
--color-message-header-icon-interactive: hsl(0deg 0% 0%);
--color-background: hsl(0deg 0% 94%);
--color-background-widget-input: hsl(0deg 0% 100%);
--color-background-navbar: hsl(0deg 0% 96%);
--color-background-active-narrow-filter: hsl(202deg 56% 91%);
--color-background-hover-narrow-filter: hsl(120deg 12.3% 71.4% / 38%);
--color-navbar-bottom-border: hsl(0deg 0% 80%);
--color-unread-marker: hsl(217deg 64% 59%);
--color-failed-message-send-icon: hsl(3.88deg 98.84% 66.27%);
--color-background-modal: hsl(0deg 0% 98%);
--color-unmuted-or-followed-topic-list-item: hsl(0deg 0% 20%);
--color-outline-focus: hsl(215deg 47% 50%);
/* Text colors */
--color-text-default: hsl(0deg 0% 20%);
--color-text-message-default: hsl(0deg 0% 15%);
--color-text-message-view-header: hsl(0deg 0% 20% / 100%);
--color-text-message-header: hsl(0deg 0% 15%);
--color-text-dropdown-input: hsl(0deg 0% 13.33%);
--color-text-self-direct-mention: hsl(240deg 52% 45% / 100%);
--color-text-self-group-mention: hsl(183deg 52% 26% / 100%);
--color-text-show-more-less-button: hsl(240deg 52% 53%);
/* Icon colors */
--color-icon-bot: hsl(180deg 8% 65% / 100%);
--color-message-action-visible: hsl(216deg 43% 20% / 50%);
--color-message-action-interactive: hsl(216deg 43% 20% / 100%);
--color-message-star-action: hsl(41deg 100% 47% / 100%);
/* Message feed loading indicator colors */
--color-zulip-logo: hsl(0deg 0% 0% / 34%);
--color-zulip-logo-loading: hsl(0deg 0% 27%);
--color-zulip-logo-z: hsl(0deg 0% 100%);
/* Message collapsing/condensing button colors */
--color-show-more-less-button-background: hsl(240deg 44% 56% / 8%);
--color-show-more-less-button-background-hover: hsl(240deg 44% 56% / 15%);
--color-show-more-less-button-background-active: hsl(240deg 44% 56% / 20%);
/* Mention pill colors */
--color-background-direct-mention: hsl(240deg 52% 95%);
--color-background-group-mention: hsl(180deg 40% 94%);
--color-background-text-direct-mention: hsl(240deg 70% 70% / 20%);
--color-background-text-hover-direct-mention: hsl(240deg 70% 70% / 30%);
--color-background-text-group-mention: hsl(183deg 60% 45% / 18%);
--color-background-text-hover-group-mention: hsl(183deg 60% 45% / 30%);
/* Inbox view constants - Values from Figma design */
--height-inbox-search: 26px;
--width-inbox-search: 346px;
--color-background-inbox: hsl(0deg 0% 100% / 50%);
--color-background-inbox-search: hsl(0deg 0% 0% / 5%);
--color-icon-search-inbox: hsl(0deg 0% 0% / 50%);
--color-background-inbox-search-focus: hsl(0deg 0% 100%);
--color-border-inbox-search-focus: hsl(0deg 0% 100% / 20%);
--color-background-inbox-row: hsl(0deg 0% 100%);
--color-background-inbox-row-hover: linear-gradient(
0deg,
hsl(0deg 0% 0% / 5%) 0%,
hsl(0deg 0% 0% / 5%) 100%
),
hsl(0deg 0% 100%);
--color-background-btn-inbox-selected: hsl(0deg 0% 0% / 5%);
--color-background-btn-inbox-focus: hsl(0deg 0% 80%);
--color-border-inbox: hsl(0deg 0% 84.31%);
}
%dark-theme {
--color-date: hsl(0deg 0% 100% / 75%);
--color-background-private-message-header: hsl(46deg 15% 20%);
--color-background-private-message-content: hsl(46deg 7% 16%);
--color-background-stream-message-content: hsl(0deg 0% 15%);
--color-message-header-icon-non-interactive: hsl(0deg 0% 100% / 30%);
--color-message-header-icon-interactive: hsl(0deg 0% 100%);
--color-message-header-contents-border: hsl(0deg 0% 0% / 60%);
--color-private-message-header-border: hsl(0deg 0% 0% / 48%);
--color-message-header-contents-border-bottom: hsl(0deg 0% 0% / 50%);
--color-private-message-header-border-bottom: hsl(0deg 0% 0% / 37%);
--color-message-list-border: hsl(0deg 0% 0% / 40%);
--color-background: hsl(0deg 0% 11%);
--color-background-widget-input: hsl(225deg 6% 10%);
--color-background-navbar: hsl(0deg 0% 13%);
--color-background-active-narrow-filter: hsl(200deg 17% 18%);
--color-background-hover-narrow-filter: hsl(136deg 25% 73% / 20%);
--color-navbar-bottom-border: hsl(0deg 0% 0% / 60%);
--color-unread-marker: hsl(217deg 64% 59%);
--color-background-modal: hsl(212deg 28% 18%);
--color-unmuted-or-followed-topic-list-item: hsl(236deg 33% 90%);
/* Text colors */
--color-text-default: hsl(0deg 0% 100% / 75%);
/* Unlike the light theme, the dark theme renders message
text in the default color. */
--color-text-message-default: var(--color-text-default);
--color-text-message-view-header: hsl(0deg 0% 100% / 80%);
--color-text-message-header: hsl(0deg 0% 100% / 80%);
--color-text-sender-name: hsl(0deg 0% 100% / 85%);
--color-text-dropdown-input: hsl(0deg 0% 95%);
--color-text-other-mention: hsl(0deg 0% 100% / 80%);
--color-text-self-direct-mention: hsl(240deg 100% 88% / 100%);
--color-text-self-group-mention: hsl(184deg 52% 63% / 100%);
--color-text-show-more-less-button: hsl(240deg 30% 65%);
/* Icon colors */
--color-icon-bot: hsl(180deg 5% 50% / 100%);
--color-message-action-visible: hsl(217deg 41% 90% / 50%);
--color-message-action-interactive: hsl(217deg 41% 90% / 100%);
/* Message feed loading indicator colors */
--color-zulip-logo: hsl(0deg 0% 100% / 50%);
--color-zulip-logo-loading: hsl(0deg 0% 100%);
--color-zulip-logo-z: hsl(214deg 27% 18%);
/* Message collapsing/condensing button colors */
--color-show-more-less-button-background: hsla(240deg 44% 56% / 15%);
--color-show-more-less-button-background-hover: hsl(240deg 44% 56% / 25%);
--color-show-more-less-button-background-active: hsl(240deg 44% 56% / 15%);
/* Mention pill colors */
--color-background-direct-mention: hsl(240deg 13% 20%);
--color-background-group-mention: hsl(180deg 13% 15%);
--color-background-text-direct-mention: hsl(240deg 52% 60% / 25%);
--color-background-text-hover-direct-mention: hsl(240deg 52% 60% / 45%);
--color-background-text-group-mention: hsl(183deg 52% 40% / 20%);
--color-background-text-hover-group-mention: hsl(183deg 52% 40% / 30%);
/* Inbox view */
--color-background-inbox: var(--color-background);
--color-background-inbox-search: hsl(0deg 0% 20%);
--color-icon-search-inbox: hsl(0deg 0% 100% / 50%);
--color-background-inbox-search-focus: hsl(0deg 0% 0%);
--color-border-inbox-search-focus: hsl(0deg 0% 0% / 20%);
--color-background-inbox-row: hsl(0deg 0% 14%);
--color-background-inbox-row-hover: linear-gradient(
0deg,
hsl(0deg 0% 100% / 5%) 0%,
hsl(0deg 0% 100% / 5%) 100%
),
hsl(0deg 0% 14.12%);
--color-background-btn-inbox-selected: hsl(0deg 0% 100% / 5%);
--color-background-btn-inbox-focus: hsl(0deg 0% 20%);
--color-border-inbox: hsl(0deg 0% 0% / 60%);
}
@media screen {
:root.dark-theme {
@extend %dark-theme;
}
}
@media screen and (prefers-color-scheme: dark) {
:root.color-scheme-automatic {
@extend %dark-theme;
}
}
input,
button,
select,
textarea {
font-family: "Source Sans 3 VF", sans-serif;
/* Disable bootstrap size CSS; we want to use our default font size on
body for input elements. */
line-height: normal;
font-size: inherit;
}
blockquote p {
font-weight: normal;
}
a {
cursor: pointer;
&.message_label_clickable:hover {
cursor: pointer;
color: hsl(200deg 100% 40%);
}
}
code,
pre {
font-family: "Source Code Pro", monospace;
}
.no-select {
user-select: none;
}
.auto-select {
user-select: auto;
}
.text-select {
user-select: text;
}
p.n-margin {
margin: 10px 0 0;
}
.small-line-height {
line-height: 1.1;
}
.float-left {
float: left;
}
.float-right {
float: right;
}
.float-clear {
clear: both;
}
.no-margin {
margin: 0;
}
.history-limited-box {
color: hsl(16deg 60% 45%);
border: 1px solid hsl(16deg 60% 45%);
box-shadow: 0 0 2px hsl(16deg 60% 45%);
}
.all-messages-search-caution {
border: 1px solid hsl(192deg 19% 75% / 20%);
box-shadow: 0 0 2px hsl(192deg 19% 75% / 20%);
}
.history-limited-box,
.all-messages-search-caution {
border-radius: 4px;
display: none;
font-size: 16px;
margin: 0 auto 12px;
padding: 5px;
/* Difference should be 16px to accommodate the icon. */
/* This emulates hanging indent. */
padding-left: 26px;
text-indent: -10px;
& i {
margin: 0 3px 0 1px;
}
& p {
margin: 0;
padding: 4px;
}
}
.bottom-messages-logo {
display: none;
}
.alert-zulip-logo,
.top-messages-logo,
.bottom-messages-logo {
width: 24px;
height: 24px;
margin: 0 auto 12px;
& svg {
& circle {
fill: var(--color-zulip-logo);
stroke: var(--color-zulip-logo);
}
& path {
fill: var(--color-zulip-logo-z);
stroke: var(--color-zulip-logo-z);
}
}
&.loading circle {
fill: var(--color-zulip-logo-loading);
stroke: var(--color-zulip-logo-loading);
}
}
.top-messages-logo {
/* Since padding under message header is not transparent
we need to position it below the padding. */
padding-top: var(--header-padding-bottom);
margin-bottom: 0;
/* To fit the logo inside the spinner. */
position: relative;
top: -2px;
}
/* See https://web.dev/animations-guide/#triggers before adding any funny animation properties here. */
@keyframes feedback-slide-in {
from {
transform: translateY(-120%);
opacity: 0;
}
to {
transform: translateY(50px);
opacity: 1;
}
}
@keyframes feedback-slide-out {
from {
transform: translateY(50px);
opacity: 1;
}
to {
transform: translateY(-120%);
opacity: 0;
}
}
#feedback_container {
display: none;
position: fixed;
width: 400px;
top: 0;
left: calc(50vw - 220px);
padding: 15px;
background-color: hsl(0deg 0% 98%);
border-radius: 5px;
box-shadow: 0 0 30px hsl(0deg 0% 0% / 25%);
z-index: 110;
&.show-feedback-container {
display: block;
animation: feedback-slide-in 0.6s forwards;
}
&.slide-out-feedback-container {
animation: feedback-slide-out 0.6s;
}
& h3 {
font-size: 16pt;
margin-top: 2px;
}
.exit-me {
font-size: 20pt;
font-weight: 200;
margin: 0 0 0 10px;
cursor: pointer;
}
}
.fade-in-message {
animation-name: fadeInMessage;
animation-duration: 1s;
animation-iteration-count: 1;
.message_edit_notice {
animation-name: fadeInEditNotice;
animation-duration: 1s;
animation-iteration-count: 1;
}
}
.message_edit_notice_hover:hover {
opacity: 1;
}
#navbar-fixed-container {
position: fixed;
top: 0;
z-index: 102;
}
/* Adjust width of any fixed / absolute positioned elements that might be visible in
the background when a overlay / modal is open. */
#navbar-fixed-container,
#compose {
width: calc(100% - var(--disabled-scrollbar-width));
}
.header {
width: 100%;
height: var(--header-height);
/* Since the headers are sticky, we need non-transparent background. */
background-color: var(--color-background);
/* Add 1px box-shadow below header so that if there is a gap between sticky header
and header at some zoom level, it is covered by this */
box-shadow: 0 1px 0 0 var(--color-background);
}
#navbar-middle .column-middle-inner,
#userlist-toggle-button,
.header,
#message_view_header {
background-color: var(--color-background-navbar);
box-shadow: inset 0 -1px 0 var(--color-navbar-bottom-border);
}
#navbar_alerts_wrapper {
font-size: 1rem;
position: relative;
.alert {
/* Since alerts are only rendered into the DOM when they are first
displayed, display: block is the right default for this setting. */
display: block;
margin: 0;
padding-top: 12px;
padding-bottom: 12px;
border: none;
border-radius: 0;
text-align: center;
text-shadow: none;
color: hsl(0deg 0% 100%);
&.alert-info {
background-color: hsl(170deg 46% 54%);
&.red {
background-color: hsl(0deg 46% 54%);
}
}
.close {
line-height: 24px;
position: absolute;
right: 18px;
top: 50%;
transform: translateY(-50%);
}
.alert-link {
color: hsl(169deg 100% 88%);
font-weight: 600;
}
&.red .alert-link {
color: hsl(0deg 100% 88%);
}
.buttons .alert-link {
margin: 0 5px;
}
}
}
#gear-menu .dropdown-menu {
.org-name,
.org-url {
padding: 0 20px;
}
.org-info {
text-align: center;
& a {
white-space: normal;
}
}
.org-name {
font-size: large;
font-weight: bold;
}
.org-url {
line-height: 100%;
color: hsl(0deg 0% 52%);
}
.org-version {
padding-top: 3px;
white-space: normal;
}
.org-upgrade {
color: hsl(226deg 82% 60%);
& a {
padding: 0;
}
}
.org-plan,
.org-upgrade {
& a {
line-height: 16px;
}
}
.plan-separator {
line-height: 8px;
}
.small-font-size {
font-size: 12px;
}
}
.recent_view_container #recent_view_table {
margin-top: var(--navbar-fixed-height);
}
.app {
width: 100%;
height: 100%;
z-index: 99;
}
.app-main,
.header-main {
width: 100%;
min-width: 950px;
margin: 0 auto;
padding: 0;
position: relative;
}
body.has-overlay-scrollbar {
/* Move simplebar scrollbar to the left so that
browser scrollbar doesn't overlap with it. */
.column-right .simplebar-track.simplebar-vertical {
right: var(--browser-overlay-scrollbar-width);
}
}
/* Styles for popovers rendered as an overlay at the
center of the screen, primarily used in mobile sizes. */
#popover-overlay-background {
position: fixed;
inset: 0;
/* Needs to be higher than the 105 for div.overlay so that the
emoji picker can render on top of the user status picker. */
z-index: 106;
background-color: hsl(0deg 0% 0% / 70%);
}
.column-right {
width: var(--right-sidebar-width);
max-width: var(--right-sidebar-width);
position: absolute;
right: 0;
top: 0;
.spectator_login_buttons {
display: flex;
justify-content: space-evenly;
position: absolute;
top: 10px;
/* width of right column - width of gear icon(250px - 45px) */
width: 205px;
& a {
font-size: calc(16em / 14);
font-weight: 600;
color: hsl(0deg 0% 20%);
&:hover {
text-decoration: none;
color: hsl(0deg 0% 0%);
}
& i {
margin-right: 3px;
}
}
.divider {
color: hsl(0deg 0% 88%);
font-size: 20px;
line-height: 1;
}
}
.spectator_narrow_login_button {
position: absolute;
top: 0;
right: 0;
/* Height of navbar in tablet sizes */
height: 40px;
/* Width of userlist-toggle button. */
width: 45px;
border-left: 1px solid hsl(0deg 0% 88%);
.login_button {
display: flex;
justify-content: center;
align-items: center;
height: 100%;
opacity: 0.5;
&:hover {
opacity: 1;
text-decoration: none;
}
& i {
color: hsl(0deg 0% 20%);
font-size: 1.6em;
}
}
}
}
.column-left {
width: var(--left-sidebar-width);
max-width: var(--left-sidebar-width);
position: absolute;
left: 0;
top: 0;
}
#message_feed_container,
.column-left .left-sidebar,
.column-right .right-sidebar {
padding-top: calc(
var(--navbar-fixed-height) + var(--header-padding-bottom)
);
}
.app-main {
height: 100%;
min-height: 100%;
.column-left .left-sidebar,
.column-right .right-sidebar {
position: fixed;
z-index: 100;
}
.column-left .left-sidebar {
width: var(--left-sidebar-width);
padding-left: var(--left-sidebar-collapse-widget-gutter);
}
.column-right .right-sidebar {
padding-left: 10px;
width: 240px;
}
.column-middle {
min-height: 100%;
/* We need `overflow-y: visible` for sticky headers to work. */
}
}
.column-middle,
#compose-content {
margin-right: var(--right-sidebar-width);
margin-left: calc(
var(--left-sidebar-width) + var(--left-sidebar-collapse-widget-gutter)
);
position: relative;
}
textarea,
input {
font-family: "Source Sans 3 VF", sans-serif;
}
/* Override Bootstrap's fixed sizes for various elements */
textarea,
label {
font-size: inherit;
line-height: inherit;
}
/* Bootstrap's focus outline uses -webkit-focus-ring-color which doesn't exist in Firefox */
a:not(:active):focus,
button:focus,
.new-style label.checkbox input[type="checkbox"]:focus ~ span,
i.fa:focus,
i.zulip-icon:focus-visible,
.auto-select:focus,
[role="button"]:focus {
outline: 2px solid var(--color-outline-focus);
/* TODO: change solid to auto once the Chromium bug #1105822 is fixed */
}
/* List of text-like input types taken from Bootstrap */
input {
&[type="text"],
&[type="password"],
&[type="datetime"],
&[type="datetime-local"],
&[type="date"],
&[type="month"],
&[type="time"],
&[type="week"],
&[type="number"],
&[type="email"],
&[type="url"],
&[type="search"],
&[type="tel"],
&[type="color"] {
font-size: inherit;
height: 1.4em;
}
}
li,
.table th,
.table td {
line-height: inherit;
}
.btn {
font-size: inherit;
height: auto;
line-height: 100%;
}
/* Classes which style copy buttons */
.copy_button_base {
outline-color: hsl(0deg 0% 73%);
height: 18px;
width: 10px;
padding: 6px;
display: block;
/* The below two avoids the padded element from displaying
its own border and background color */
border: none;
background-clip: content-box;
/* The z-index here ensures that the copy-message
icon is clickable and is needed because of reduced
opacity of readonly textarea */
z-index: 2;
&:hover svg path {
fill: hsl(200deg 100% 40%);
}
}
.copy_message {
float: right;
position: relative;
cursor: pointer;
top: 30px;
/* To make sure the svg doesn't occupy any vertical space. */
margin-top: -30px;
right: 2px;
padding-top: 2px;
#clipboard_image {
margin: 0;
}
}
#copy_generated_invite_link {
position: relative;
margin-right: -32px;
margin-top: -1px;
padding: 6px 3px 6px 13px;
float: right;
/* This property nullifies the box-shadow rendered by .btn class */
&:active {
box-shadow: none;
}
}
#clipboard_image {
margin-top: -5px;
margin-left: -8px;
}
/* Classes for hiding and showing controls */
.notdisplayed {
display: none !important;
}
.notvisible {
visibility: hidden !important;
width: 0 !important;
min-width: 0 !important;
min-height: 0 !important;
height: 0 !important;
overflow: hidden !important;
position: absolute !important;
}
/* Lighter strong */
strong {
font-weight: 600;
}
.preserve_spaces {
white-space: pre-wrap;
}
.sp-input {
width: calc(100% - 14px);
box-sizing: initial !important;
}
.logout {
white-space: nowrap;
}
.sidebar-title {
color: hsl(0deg 0% 43%);
font-size: inherit;
font-weight: normal;
display: inline;
}
.tooltip {
&.in {
font-size: 12px;
line-height: 1.3;
opacity: 1;
&.left {
margin-left: -12px;
margin-top: 3px;
}
}
.tooltip-inner {
background-color: hsl(0deg 0% 7% / 80%);
padding: 3px 5px;
}
/*
Since hover and click are activated together on touchscreen
devices, the hover state persists until the next click, creating
awkward UI where the tooltip sticks around forever :(.
To resolve this, we just hide the tooltip for touch-events on
touch-enabled devices resolving the above problem. This means
that tooltips will never appear on touchscreen devices, but that's
probably a reasonable tradeoff here.
Source: https://drafts.csswg.org/mediaqueries-4/#mf-interaction
*/
@media (hover: none) {
visibility: hidden !important;
}
}
.buddy_list_tooltip_content {
text-align: left;
word-wrap: break-word;
}
#message_edit_tooltip {
float: right;
color: hsl(0deg 0% 0%);
margin-top: 2px;
margin-left: 6px;
opacity: 0.5;
cursor: pointer;
&:hover {
opacity: 1;
}
}
#change_visibility_policy_button_tooltip {
text-align: center;
}
.narrow-filter {
display: block;
position: relative;
}
#gear-menu .light-theme {
display: none;
}
/* .dropdown-menu from v2.3.2
+ https://github.com/zulip/zulip/commit/7a3a3be7e547d3e8f0ed00820835104867f2433d
basic idea of this fix is to remove decorations from :hover and apply them only
on :focus. */
.typeahead-menu {
& li {
& a {
display: block;
padding: 3px 20px;
clear: both;
font-weight: normal;
line-height: 20px;
color: hsl(0deg 0% 20%);
white-space: nowrap;
&:hover {
text-decoration: none;
}
&:focus {
color: hsl(0deg 0% 100%);
text-decoration: none;
background-color: hsl(200deg 100% 38%);
background-image: linear-gradient(
to bottom,
hsl(200deg 100% 40%),
hsl(200deg 100% 35%)
);
}
/* styles defined for user_circle here only deal with positioning of user_presence_circle
in typeahead list in order to ensure they are rendered correctly in in all screen sizes.
Most of the style rules related to color, gradient etc. which are generally common throughout
the app are defined in user_circles.css and are not overridden here. */
.user_circle {
width: 8px;
height: 8px;
margin: 0 5px 0 -6px;
position: relative;
top: 6px;
right: 8px;
display: inline-block;
}
}
}
.active > a {
color: hsl(0deg 0% 100%);
text-decoration: none;
background-color: hsl(200deg 100% 38%);
background-image: linear-gradient(
to bottom,
hsl(200deg 100% 40%),
hsl(200deg 100% 35%)
);
outline: 0;
.user_circle_empty {
border-color: hsl(0deg 0% 25%);
}
}
.active > a:hover {
text-decoration: none;
}
}
/* Copied from bootstrap 2.1.1 CSS for dropdown-menu li > a:focus */
li.actual-dropdown-menu > a:focus {
color: hsl(0deg 0% 100%);
text-decoration: none;
background-color: transparent;
background-image: none;
filter: none;
outline: 0;
}
li.actual-dropdown-menu i {
/* In gear menu, make icons the same width so labels line up. */
display: inline-block;
width: 14px;
text-align: center;
margin-right: 3px;
}
#gear_menu_about_zulip {
.white_zulip_icon_without_text {
position: relative;
top: 3px;
width: 14px;
height: 14px;
margin-right: 3px;
filter: invert(20%) sepia(11%) saturate(0%) hue-rotate(272deg)
brightness(20%) contrast(95%);
}
.about_zulip_text {
position: relative;
top: 1.4px;
}
:hover {
.white_zulip_icon_without_text {
filter: none;
}
}
}
.settings-dropdown-cog {
padding: 6px 12px;
}
td.pointer {
vertical-align: top;
padding-top: 10px;
background-color: hsl(0deg 0% 100%);
}
.new_messages {
background-color: hsl(194deg 53% 79%);
}
.new_messages,
.new_messages_fadeout {
transition: all 3s ease-in-out;
}
.sender-status {
display: inline-block;
margin: 8px 0 8px -3px;
/* this normalizes the margin of the emoji reactions with normal messages. */
padding-bottom: 5px;
vertical-align: middle;
position: relative;
max-width: calc(100% - 50px);
.message_edit_notice {
vertical-align: middle;
}
&.sender-status-edit {
/* Hackery to place the textarea for the message edit form nicely
for /me messages. */
vertical-align: top;
line-height: 0;
margin-top: 4px !important;
.message_edit_notice {
line-height: 0;
}
}
}
.message_edit_notice {
font-size: 10px;
opacity: 0.5;
user-select: none;
white-space: nowrap;
overflow-x: hidden;
overflow-x: clip;
}
.messagebox-content .message_time {
display: block;
font-size: 13px;
font-weight: 350;
text-align: right;
opacity: 0.8;
color: var(--color-text-default);
letter-spacing: 0.02em;
/* Disable blue link styling for the message timestamp link. */
&:hover {
text-decoration: none;
color: var(--color-message-action-interactive);
}
}
.messagebox-content .slow-send-spinner {
display: block;
font-size: 12px;
text-align: right;
opacity: 0.8;
color: var(--color-text-default);
animation: rotate 1s infinite linear;
}
.status-time {
top: 8px !important;
}
.message_controls {
display: flex;
align-items: baseline;
font-size: 16px;
/* This is a bit tricky; we need to reserve space for the message
controls even when the message isn't hovered, so that hover
doesn't disturb the layout. Usually that would be just
visibility: hidden, but that cannot be animated, so we set
opacity as well, which can be animated. */
.message_control_button {
opacity: 0;
visibility: hidden;
transition: all 0.2s ease;
width: var(--message-box-icon-width);
height: var(--message-box-icon-height);
text-align: center;
color: var(--color-message-action-visible);
& i {
vertical-align: middle;
/* TODO: Math for these values, possibly with variables.
In short, the icon body is 16px square; the current
area for the icon is 26px wide by 25px tall, so these
values ensure a 26px x 25px clickable area for the icon. */
padding: 2.5px 3px;
&:active {
transform: scale(0.92);
transform-origin: center;
outline: 0;
transition: unset;
}
&:focus {
/* Remove the outline but do not color on focus;
focus-visible is more appropriate for the color
changes, as it only applies color when focus
is achieved from a keyboard or other pointerless
device. */
outline: 0;
}
&:hover,
&:focus-visible {
outline: 0;
color: var(--color-message-action-interactive);
}
/* Separate hover colors for stars */
&.star:hover,
&.star:focus-visible {
color: var(--color-message-star-action);
}
}
.zulip-icon-more-vertical {
/* Increase visual prominence of the vdots. */
font-size: 21px;
}
}
.actions_hover {
line-height: 1;
.zulip-icon-ellipsis-v-solid {
padding: 2px 5.33px;
}
}
/* Tooltips should not follow the width restrictions of their parent element. */
[data-tippy-root] {
width: max-content;
word-wrap: unset;
}
> .view_read_receipts {
font-size: 14px;
height: 16px;
&:hover {
color: hsl(200deg 100% 40%);
}
}
.edit_content {
/* Icons for editing content are determined on message hover;
we set an empty `.edit_content` to have 0 height in order to
preserve the layout of the other icons prior to any hovering. */
&:empty {
height: 0;
}
&:hover {
cursor: pointer;
}
}
&.sender-status-controls {
top: 8px;
}
.message_failed {
display: inline-flex;
justify-content: space-between;
cursor: pointer;
position: relative;
vertical-align: middle;
padding-left: 2px;
&.hide {
display: none;
}
.rotating {
display: inline-block;
outline: none;
animation: rotate 1s infinite linear;
}
.failed_message_action {
opacity: 1 !important;
color: var(--color-failed-message-send-icon);
font-weight: bold;
padding: 1px;
}
.message_control_button {
visibility: inherit;
}
}
.star_container {
&:not(.empty-star) {
/* Color, opacity, and visibility, as though the message is hovered. */
color: var(--color-message-star-action);
opacity: 1;
visibility: visible !important;
}
}
}
.star {
&:hover {
cursor: pointer;
}
}
.message_header {
vertical-align: middle;
text-align: left;
/* We can overflow-y if the font size gets big */
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
font-weight: 600;
font-size: calc(15em / 14);
line-height: 120%;
position: relative;
z-index: 0;
background-color: var(--color-background);
.message-header-contents {
display: flex;
align-items: center;
justify-content: space-between;
height: 28px;
border: 1px solid var(--color-message-header-contents-border);
border-bottom-color: var(--color-message-header-contents-border-bottom);
border-radius: 7px 7px 0 0;
}
&.message_header_stream {
/* Add box shadow to hide message border (first one) and message
selected box shadow (second one) that are visible
due to top borders of sticky recipient bar being curved. */
box-shadow:
-1px -5px 0 5px var(--color-background),
1px -5px 0 0 var(--color-background);
& a.message_label_clickable {
color: var(--color-text-message-header);
&:hover {
color: var(--color-text-message-header) !important;
text-decoration: none;
}
}
.stream_topic_separator {
line-height: 0;
color: var(--color-message-header-icon-non-interactive);
position: relative;
top: 0.5px;
}
.stream_topic {
display: inline-block;
padding: 5px 6px 5px 2px;
height: 17px;
line-height: 17px;
overflow: hidden;
text-overflow: ellipsis;
.message_label_clickable.narrows_by_topic {
position: relative;
top: 0.5px;
overflow: hidden;
text-overflow: ellipsis;
}
}
.stream-privacy i {
font-size: 15px;
&.zulip-icon-globe,
&.zulip-icon-hashtag {
position: relative;
top: -0.5px;
}
}
}
}
.message-feed {
.recipient_row {
/* Browser overlaps extra top padding of message header and
the bottom border message if this margin is not present. */
margin-bottom: 1px;
border-radius: 5px;
.message_row:last-of-type {
border-radius: 0 0 7px 7px;
border-bottom: 1px solid var(--color-message-list-border);
.unread-marker-fill {
border-radius: 0 0 0 7px;
height: calc(100% - 2px);
}
.messagebox {
border-radius: 0 0 7px 7px;
padding-bottom: 4px;
}
}
.message_header + .message_row {
.messagebox {
padding-top: 5px;
}
}
}
.message_header {
position: sticky;
top: var(--navbar-fixed-height);
/* Needs to be higher than the z-index of date_row. */
z-index: 4;
box-shadow: 0 -1px 0 0 var(--color-background);
.message-header-contents {
margin-top: var(--header-padding-bottom);
}
&.sticky_header {
box-shadow: var(--unread-marker-left) 0 0 0 var(--color-background);
.recipient_row_date {
display: block;
}
}
}
}
.stream_label {
display: flex;
align-items: center;
gap: 5px;
padding: 5px 2px 5px 10px;
height: 17px;
line-height: 17px;
position: relative;
top: 0.5px;
text-decoration: none;
font-weight: 600;
overflow: hidden;
.recipient-row-stream-icon {
font-size: 12px;
line-height: 12px;
}
.zulip-icon.zulip-icon-globe {
position: relative;
top: 1px;
}
&:hover {
text-decoration: none;
}
.stream-privacy {
min-width: unset;
width: 16px;
height: 16px;
.hashtag {
padding-right: 0;
&::after {
font-size: 16px;
}
}
}
}
.recipient_bar_controls {
display: flex;
flex-grow: 1;
align-items: center;
.change_visibility_policy {
cursor: pointer;
i {
font-size: 17px;
display: block;
}
}
}
.recipient_row_date {
color: var(--color-date);
font-size: calc(12em / 14);
padding: 0 10px;
text-align: right;
display: flex;
align-items: center;
font-style: normal;
font-weight: 600;
line-height: 17px; /* identical to box height, or 131% */
letter-spacing: 0.04em;
text-transform: uppercase;
padding-top: 1px;
/* Display the date when unchanged only for sticky headers. */
&.recipient_row_date_unchanged {
display: none;
.sticky_header & {
display: block;
}
}
&.hide-date-separator-header {
display: none;
}
}
.recipient_bar_icon {
color: var(--color-message-header-icon-interactive);
opacity: 0.2;
padding-left: 6px;
padding-right: 6px;
&:hover {
opacity: 0.4 !important;
cursor: pointer;
}
}
.copy-paste-text {
/* Hide the text that we want copy paste to capture */
position: absolute;
text-indent: -99999px;
float: left;
width: 0;
}
@keyframes rotate {
from {
transform: rotate(0deg);
}
to {
transform: rotate(359deg);
}
}
@keyframes fadeInMessage {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
@keyframes fadeInEditNotice {
0% {
transform: translateX(-10px);
}
100% {
transform: translateX(0);
}
}
.message_header_private_message {
/* This is required for box-shadow appear above the message content. */
z-index: 1;
box-shadow:
-1px -5px 0 5px var(--color-background),
1px -5px 0 0 var(--color-background);
background-color: var(--color-background);
.message-header-contents {
border-color: var(--color-private-message-header-border);
border-bottom-color: var(--color-private-message-header-border-bottom);
background-color: var(--color-background-private-message-header);
}
.message_label_clickable {
display: flex;
padding: 5px 0 5px 10px;
font-weight: 600;
height: 17px;
line-height: 17px;
color: var(--color-text-message-header);
&:hover {
color: var(--color-text-message-header) !important;
text-decoration: none;
}
.private_message_header_icon {
font-size: 15px;
position: relative;
top: 1px;
width: 16px;
height: 16px;
}
.private_message_header_name {
overflow: hidden;
text-overflow: ellipsis;
}
}
}
.message_row.private-message {
background-color: var(--color-background-private-message-content);
.date_row {
background-color: var(--color-background-private-message-content);
}
}
.selected_message {
.messagebox-content {
/* We add an outline and shift it inside the message so that without
any vertical padding changes, we can have the outline surrounding
the message without overflowing the boundary of the message in any case. */
outline: 1px solid hsl(217deg 64% 59%);
border-radius: 5px;
outline-offset: -1px;
}
}
.message_sender {
& i.zulip-icon.zulip-icon-bot {
font-size: 12px;
}
}
.sender_name {
display: inline-block;
font-weight: 700;
color: var(--color-text-sender-name);
}
.sender_name_hovered {
.sender_name {
color: hsl(200deg 100% 40%);
}
}
.always_visible_topic_edit,
.on_hover_topic_read,
.stream_unmuted.on_hover_topic_unmute,
.stream_muted.on_hover_topic_mute {
opacity: 0.7;
&:hover {
cursor: pointer;
opacity: 1;
}
}
.on_hover_topic_edit,
.on_hover_topic_unresolve,
.on_hover_topic_resolve,
.stream_unmuted.on_hover_topic_mute,
.stream_muted.on_hover_topic_unmute {
opacity: 0.2;
&:hover {
cursor: pointer;
opacity: 0.7;
}
}
/* Make the action icon on the message row
always visible while the popover is open */
.has_actions_popover .actions_hover {
visibility: visible !important;
pointer-events: all !important;
opacity: 1 !important;
& i:focus {
/* Avoid displaying a focus outline outside the popover on the \vdots
icon when opened via the mouse. */
outline: 0 !important;
}
}
.has_actions_popover .info {
opacity: 1;
visibility: visible;
}
.small {
font-size: 80%;
}
.tiny {
font-size: 60%;
}
.settings-forgot-password {
display: inline-block;
position: relative;
color: hsl(0deg 0% 73%);
bottom: 4px;
}
div.message-list {
border-collapse: separate;
margin-left: auto;
display: none;
width: 100%;
}
div.focused-message-list {
display: block;
}
.rtl {
direction: rtl;
}
.message_edit_content {
line-height: 18px;
resize: vertical !important;
max-height: 24em;
}
.message_edit_countdown_timer {
text-align: right;
display: inline;
color: hsl(0deg 0% 63%);
&.expired {
color: hsl(4deg 58% 33%);
}
}
.message_edit_tooltip {
display: inline;
color: hsl(0deg 0% 63%);
}
.message-edit-timer {
float: right;
display: none;
margin-top: 5px;
}
.message-edit-feature-group {
display: inline-flex;
margin: 0 auto -5px 10px;
align-items: baseline;
}
.message_edit_save .loader {
display: none;
vertical-align: top;
position: relative;
height: 28px;
margin-top: -10px;
top: 6px;
width: 30px;
}
.edit-controls {
.btn-wrapper {
cursor: not-allowed;
}
.disable-btn {
pointer-events: none;
}
}
.topic_edit {
display: none;
line-height: 22px;
.alert {
display: inline-block;
margin: 0;
padding: 0 10px;
line-height: 17px;
}
}
.inline_topic_edit {
margin-bottom: 5px;
width: 206px;
&.header-v {
height: 18px;
display: inline-block;
padding: 0 3px;
vertical-align: baseline;
line-height: 0px;
box-shadow: none;
color: hsl(0deg 0% 33%);
border-radius: 4px;
border: 1px solid hsl(0deg 0% 80%);
transition:
border linear 0.2s,
box-shadow linear 0.2s;
&:focus {
border-color: hsl(206deg 80% 62% / 80%);
outline: 0;
box-shadow:
inset 0 1px 1px hsl(0deg 0% 0% / 7.5%),
0 0 8px hsl(206deg 80% 62% / 60%);
}
}
}
#message_edit_topic {
margin: 0 5px 10px 0;
}
.message_edit_header {
display: flex;
flex-wrap: wrap;
justify-content: flex-start;
}
.inline_topic_edit:focus,
#message_edit_topic:focus {
outline: none;
}
#move_topic_modal select {
width: auto;
margin-bottom: 10px;
max-width: 100%;
}
.topic_move_breadcrumb_messages,
.message_edit_breadcrumb_messages {
margin: 0 5px 5px 0;
align-self: center;
width: 100%;
white-space: nowrap;
& label.checkbox {
/* Place the checkboxes on their own lines. */
display: block;
& input {
margin: 0;
vertical-align: baseline;
}
& + label.checkbox {
margin-top: 10px;
}
}
& label {
display: inline-block;
margin-right: 10px;
}
}
.message_edit_breadcrumb_messages {
margin-bottom: 10px;
}
.message_length_controller {
.message_length_toggle {
display: none;
width: 100%;
height: 24px;
margin-bottom: 4px;
color: var(--color-text-show-more-less-button);
background-color: var(--color-show-more-less-button-background);
border-radius: 4px;
border: none;
outline: none;
font-variant: all-small-caps;
&:hover {
background-color: var(
--color-show-more-less-button-background-hover
);
}
&:active {
background-color: var(
--color-show-more-less-button-background-active
);
scale: 0.98;
}
}
}
.bookend {
margin-top: 10px;
background-color: transparent;
}
.inline_profile_picture {
display: inline-block;
width: var(--message-box-avatar-width);
height: var(--message-box-avatar-height);
/* Don't inherit the line-height from message-avatar;
this preserves the dimensions and rounded corners
on the image itself. */
line-height: 1;
margin-right: 11px;
vertical-align: top;
border-radius: 4px;
overflow: hidden;
&.guest-avatar::after {
outline: 2px solid hsl(0deg 0% 100%);
}
}
.home-error-bar {
margin-top: 5px;
display: none;
.alert {
margin-bottom: auto;
}
}
.streamname {
font-weight: bold;
}
.search_icon {
/* These rules match the .dropdown-toggle CSS for the gear menu. */
color: inherit;
opacity: 0.5;
text-decoration: none;
&:hover {
opacity: 1;
}
}
#message_view_header {
color: var(--color-text-message-view-header);
z-index: 2;
float: left;
height: var(--header-height);
width: 100%;
line-height: var(--header-height);
font-size: 16px;
display: flex;
align-content: flex-start;
flex-wrap: nowrap;
margin: 0;
border: none;
white-space: nowrap;
cursor: default;
.hidden {
display: none;
}
.sub_count,
.message-header-stream-settings-button,
& > span {
white-space: nowrap;
list-style-type: none;
display: inline-block;
vertical-align: top;
position: relative;
font-weight: 600;
font-size: 16px;
line-height: 16px;
margin: 0 -4px 0 0;
padding: 12px 6px;
overflow: hidden;
text-overflow: ellipsis;
@media (width < $sm_min) {
padding: 7px 3.5px; /* based on having ~41.66% decrease */
}
& i {
margin: 0 3px 0 5px;
}
.fa {
.fa-envelope {
font-size: 14px;
margin: 0 5px;
}
.fa-hashtag {
font-size: 1.2rem;
margin: 0 2px 0 5px;
}
}
.zulip-icon-inbox {
position: relative;
top: 2px;
}
}
.message-header-stream-settings-button {
text-overflow: clip;
color: inherit;
text-decoration: none;
/* The first ~3px of padding here overlaps with the left padding from sub_count for some reason. */
padding-right: calc(3px + 10px);
.zulip-icon {
font-size: 14px;
position: relative;
top: 1px;
}
}
.divider {
color: hsl(0deg 0% 88%);
font-size: 20px;
margin: 0 3px;
}
.sub_count,
.narrow_description {
background: none;
font-size: 14px;
color: inherit;
font-weight: 400;
line-height: 20px;
}
.sub_count {
padding-left: 10px;
margin-left: 1px;
padding-right: 10px;
margin-right: 1px;
overflow: visible;
.fa.fa-user-o {
margin-left: 0;
}
&::before,
&::after {
content: "|";
position: absolute;
top: 25%;
height: 50%;
color: hsl(0deg 0% 88%);
font-size: 20px;
@media (width < $sm_min) {
top: 10%;
}
}
&::before {
left: -3px;
@media (width < $sm_min) {
/* this ensures the before "|" doesn't overlap
with the stream name text on small narrows */
left: 0;
}
}
&::after {
right: -3px;
}
}
.narrow_description {
/* the actual value of flex shrink does not matter, it is the
ratio of this value to other flex items that determines the
behavior while shrinking, here the other item has the .stream
class and a flex of 1, so the value here *is* the ratio, and
is chosen such that the narrow description shrinks to close
before the stream name must begin to shrink */
flex-shrink: 100;
white-space: nowrap;
margin: 0;
padding: 12px 0;
padding-left: 10px;
@media (width < $sm_min) {
padding: 7px 0;
padding-left: 10px;
}
& > a {
padding: 12px 0;
}
}
.search_closed {
overflow: visible;
flex: 0; /* makes sure search icon is always visible */
cursor: pointer;
font-size: 20px;
padding: 10px 15px 0 0;
@media (width < $sm_min) {
padding: 0 15px 0 0;
}
}
/* The very last element in the navbar is the search icon, the second
last element is either the narrow description (for stream narrows) or
the "title" (for other narrows). The flex-grow property ensures these
elements take up the entirety of the white space. */
.navbar-click-opens-search {
flex-grow: 1;
/* Provide the visual cue that clicking this will work as expected. */
cursor: pointer;
&:hover ~ .search_closed {
opacity: 1;
}
}
}
#navbar-buttons {
white-space: nowrap;
margin-left: 15px;
margin-top: 7px;
display: inline-block;
float: right;
& ul.nav {
margin: 0;
.dropdown-toggle,
li.active .dropdown-toggle {
font-size: 20px;
color: inherit;
opacity: 0.5;
text-shadow: none;
padding-left: 0 !important;
background-color: inherit;
box-shadow: inherit;
display: block;
position: absolute;
right: 6px;
top: -3px;
}
.dropdown-toggle:hover,
li.active .dropdown-toggle:hover {
opacity: 1;
}
& li.dropdown.open .dropdown-toggle {
background: none;
opacity: 1;
text-shadow: none;
}
& li.dropdown li.divider {
margin-left: 15px;
margin-right: 15px;
}
}
}
#streamlist-toggle {
display: none;
position: absolute;
top: 0;
left: 0;
text-align: center;
vertical-align: middle;
/* border-right: 2px solid hsl(204, 20%, 74%); */
}
.hide-streamlist-toggle-visibility,
.hide-navbar-buttons-visibility {
visibility: hidden;
}
#streamlist-toggle-button {
text-decoration: none;
color: hsl(0deg 0% 52%);
display: block;
position: relative;
width: 40px;
height: 19px;
padding-top: 12px;
padding-bottom: 9px;
}
#streamlist-toggle-unreadcount,
#userlist-toggle-unreadcount {
position: absolute;
display: none;
height: 12px;
min-width: 12px;
line-height: 12px;
background-color: hsl(0deg 100% 20%);
top: 4px;
right: 4px;
border: 1px solid hsl(0deg 0% 93%);
box-shadow: 0 0 1px hsl(0deg 0% 0% / 20%);
border-radius: 12px;
padding: 1px;
font-size: 9px;
z-index: 15;
font-weight: normal;
color: hsl(0deg 0% 100%);
}
.nav .dropdown-menu {
left: auto;
right: 0;
top: 30px;
/* Match the width of the right sidebar so that we don't have
the presence dots distracting you when looking at this. */
min-width: 240px;
box-shadow: 0 0 5px hsl(0deg 0% 0% / 20%);
&::after {
position: absolute;
width: 0;
height: 0;
top: -7px;
right: 19px;
display: inline-block;
border-right: 7px solid transparent;
border-bottom: 7px solid hsl(0deg 0% 67%);
border-left: 7px solid transparent;
content: "";
z-index: 10;
}
}
#gear-menu .zulip-icon-language {
position: relative;
top: 2.5px;
left: -0.5px;
}
.nav .dropdown-menu a,
.typeahead.dropdown-menu a {
color: inherit;
}
.typeahead.dropdown-menu {
.active {
color: hsl(0deg 0% 100%);
.unsubscribed_icon {
display: block;
float: right;
margin-top: 5px;
margin-right: -12px;
font-size: 0.8em;
color: hsl(96deg 7% 73%);
}
}
.unsubscribed_icon {
display: none;
}
}
.typeahead-image {
display: inline-block;
height: 21px;
width: 21px;
position: relative;
margin-top: -4px;
vertical-align: middle;
top: 2px;
right: 8px;
border-radius: 4px;
/* For FontAwesome icons used in place of images for some users. */
font-size: 19px;
text-align: center;
&.no-presence-circle {
margin-left: 9px;
top: 3px;
}
}
nav {
.column-left {
margin-left: 15px;
.nav-logo {
display: inline-block;
vertical-align: top;
margin-top: 8px;
height: 25px;
max-width: 200px;
}
}
& a {
&.no-style:hover {
text-decoration: none;
cursor: pointer;
}
.no-style {
text-decoration: none;
}
}
}
#bottom_whitespace {
display: block;
height: var(--max-unexpanded-compose-height);
}
.operator_value {
font-family: "Source Code Pro", monospace;
color: hsl(353deg 70% 65%);
}
.operator {
font-family: "Source Code Pro", monospace;
}
#loading_older_messages_indicator,
#loading_newer_messages_indicator {
margin: 10px;
}
#loading_older_messages_indicator_box_container,
#loading_newer_messages_indicator_box_container {
position: absolute;
left: 50%;
}
#loading_older_messages_indicator_box,
#loading_newer_messages_indicator_box {
position: relative;
left: -50%;
top: -43px;
z-index: 1;
border-radius: 6px;
}
#page_loading_indicator {
margin: 10px auto;
}
#page_loading_indicator_box_container {
position: absolute;
left: 50%;
}
#page_loading_indicator_box {
position: relative;
left: -50%;
top: -43px;
z-index: 1;
border-radius: 6px;
}
#create_stream_subscribers {
margin-top: 10px;
.checkbox {
display: block;
& input[type="checkbox"] {
margin: 5px 0;
float: none;
}
}
}
.sub_button_row {
text-align: center;
}
.small_square_button {
padding: 0;
border: none;
font-size: 12px;
width: 18px;
height: 18px;
border-radius: 4px;
margin-bottom: 3px;
&:focus {
outline: none;
}
&.small_square_x {
background-color: hsl(0deg 0% 100%);
color: hsl(0deg 0% 47%);
&:hover {
color: hsl(0deg 0% 18%);
}
}
}
div.topic_edit_spinner {
display: inline-block;
width: 18px;
height: 18px;
margin-top: -1px;
padding: 2px;
vertical-align: middle;
}
div.topic_edit_spinner .loading_indicator_spinner {
width: 14px;
height: 14px;
}
.message_edit_spinner {
margin-right: 8px;
padding-top: 5px;
}
.message_edit_spinner .loading_indicator_spinner {
width: 20px;
height: 20px;
}
textarea.invitee_emails {
min-height: 40px;
max-height: 300px;
width: 96%;
max-width: 96%;
resize: vertical !important;
color: hsl(0deg 0% 33%);
background-color: hsl(0deg 0% 100%);
border-radius: 4px;
vertical-align: middle;
border: 1px solid hsl(0deg 0% 80%);
padding: 4px 6px;
box-shadow: inset 0 1px 1px hsl(0deg 0% 0% / 7.5%);
transition:
border linear 0.2s,
box-shadow linear 0.2s;
&:focus {
border-color: hsl(206.5deg 80% 62% / 80%);
outline: 0;
box-shadow:
inset 0 1px 1px hsl(0deg 0% 0% / 7.5%),
0 0 8px hsl(206.5deg 80% 62% / 60%);
}
&:disabled {
cursor: not-allowed;
background-color: hsl(0deg 0% 93%);
}
}
#custom-expiration-time-input,
#invite-user-form {
margin: 0;
}
select.invite-expires-in,
select.custom-expiration-time,
select.invite-as {
width: 220px;
height: 30px;
padding: 0 6px;
color: hsl(0deg 0% 33%);
border-radius: 4px;
border: 1px solid hsl(0deg 0% 80%);
cursor: pointer;
background-color: hsl(0deg 0% 100%);
vertical-align: middle;
}
#multiuse_invite_link {
width: 370px;
text-overflow: ellipsis;
white-space: nowrap;
display: inline-block;
overflow: hidden;
vertical-align: bottom;
}
#invite-stream-checkboxes {
& i.zulip-icon-globe {
font-size: 80%;
}
}
.invite_type_radio_section {
margin: 2px 2px 2px 5px;
& div {
width: fit-content;
}
& input[type="radio"] {
cursor: pointer;
&:disabled {
cursor: not-allowed;
}
}
.control-label-disabled label {
pointer-events: none;
cursor: not-allowed;
}
}
#custom-expiration-time-input {
width: 5ch;
margin-right: 15px;
padding: 4px 6px;
color: hsl(0deg 0% 33%);
border-radius: 4px;
border: 1px solid hsl(0deg 0% 80%);
box-shadow: inset 0 1px 1px hsl(0deg 0% 0% / 7.5%);
transition:
border linear 0.2s,
box-shadow linear 0.2s;
&:focus {
border-color: hsl(206deg 80% 62% / 80%);
outline: 0;
box-shadow:
inset 0 1px 1px hsl(0deg 0% 0% / 7.5%),
0 0 8px hsl(206deg 80% 62% / 60%);
}
}
#custom-expiration-time-unit {
width: auto;
}
.empty_feed_notice {
padding: 3em 1em;
text-align: center;
}
.message-fade,
.user_sidebar_entry.user-fade {
opacity: 0.4;
}
.emoji {
height: 25px;
width: 25px;
position: relative;
margin-top: -7px;
vertical-align: middle;
top: 3px;
}
.status-emoji {
height: 16px;
width: 16px;
/* We are setting minimum width here because when the user's name is very long,
emoji's width decreases and causes it to break. */
min-width: 16px;
/* In most contexts, status emoji appear immediately after a name
field with no margin. Position the status emoji with 3px of left
margin to space it from the name, and set no right margin so
that any components to the right appear equally distant as they
would be from a name. */
margin-left: 3px;
margin-right: 0;
}
/* FIXME: Combine this rule with the one in portico.css somehow? */
#pw_strength {
width: 100%;
height: 10px;
margin-bottom: 0;
}
#pw_change_controls {
display: none;
}
.sub-unsub-message,
.date_row {
padding-bottom: 10px;
}
.date_row {
text-align: right;
}
.sub-unsub-message span,
.date_row span {
display: block;
padding: 4px;
overflow: hidden;
text-transform: uppercase;
}
.sub-unsub-message .stream-status {
opacity: 0.6;
& i {
font-size: 10px;
position: relative;
top: 1px;
margin-left: 2px;
}
.zulip-icon.zulip-icon-lock {
font-size: 12px;
}
}
.sub-unsub-message {
text-align: center;
}
.sub-unsub-message span {
font-size: 1em;
text-transform: none;
}
.sub-unsub-message span::before,
.sub-unsub-message span::after,
.date_row span::before,
.date_row span::after {
display: inline-block;
position: relative;
content: " ";
vertical-align: middle;
height: 0;
opacity: 0.15;
border-bottom: 1px solid hsl(0deg 0% 0%);
}
.sub-unsub-message span::before,
.sub-unsub-message span::after {
width: 50%;
}
.date_row span::before {
width: 100%;
}
.date_row span::after {
width: 6px;
left: 0.25em;
/* Align date with message time and recipient bar date. */
margin-right: -1px;
}
.sub-unsub-message span::before,
.date_row span::before {
right: 0.25em;
margin-left: -50%;
}
.sub-unsub-message span::after {
left: 0.25em;
margin-right: -50%;
}
.message_edit {
display: none;
}
/* Reduce some of the heavy padding from Bootstrap. */
.message_edit_form {
margin-bottom: 10px;
cursor: default;
.edit-controls {
margin-left: 0;
margin-top: 0;
}
/* Override the default border-radius to properly align
the button corners with `stream_header_colorblock`. */
.dropdown-toggle {
border-radius: 1px 4px 4px 1px !important;
}
.dropdown-list-widget,
.stream_header_colorblock {
margin-bottom: 10px;
}
& textarea {
width: 100%;
min-width: 206px;
box-sizing: border-box;
/* Setting resize as none hides the bottom right diagonal box
(which even has a background color of its own!). */
resize: none !important;
color: hsl(0deg 0% 33%);
background-color: hsl(0deg 0% 100%);
border-radius: 4px;
vertical-align: middle;
border: 1px solid hsl(0deg 0% 80%);
padding: 4px 6px;
margin-bottom: 10px;
box-shadow: inset 0 1px 1px hsl(0deg 0% 0% / 7.5%);
transition:
border linear 0.2s,
box-shadow linear 0.2s;
&:focus {
border-color: hsl(206.5deg 80% 62% / 80%);
outline: 0;
box-shadow:
inset 0 1px 1px hsl(0deg 0% 0% / 7.5%),
0 0 8px hsl(206.5deg 80% 62% / 60%);
}
&:read-only,
&:disabled {
cursor: not-allowed;
background-color: hsl(0deg 0% 93%);
}
}
}
#topic_edit_form {
display: inline-block;
margin: 0;
height: 22px;
padding-left: 20px;
padding-right: 3px;
line-height: 22px;
margin-left: -15px;
}
.screen {
position: absolute;
left: 0;
top: 0;
background-color: hsl(0deg 0% 0%);
z-index: 20000;
}
.deactivated_user .deactivated-user-icon {
color: inherit;
margin-left: 2px;
font-size: 0.9em;
}
.no-drag {
-webkit-user-drag: none;
user-select: none;
}
.user_popover_email {
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
transition: all 0.4s ease;
& i {
cursor: pointer;
&.hide_copy_icon {
display: none;
}
}
}
.email_copied,
.user_popover_email i:hover {
color: hsl(170deg 48% 54%);
}
.email_copied i {
display: none !important;
}
.flatpickr-calendar {
/* Hide the up and down arrows in the Flatpickr datepicker year */
.flatpickr-months .numInputWrapper span {
display: none;
}
.flatpickr-time-separator {
position: relative;
left: 5px;
}
.flatpickr-time input {
margin: 0 5px;
min-height: 30px;
}
.flatpickr-confirm {
color: hsl(0deg 0% 100%);
background-color: hsl(213deg 90% 65%);
font-size: 18px;
font-weight: 600;
}
@media (width < $md_min) {
/* Center align flatpickr on mobile
* devices so that it doesn't go out of
* the viewport. */
left: 0 !important;
right: 0 !important;
margin: auto;
&::after,
&::before {
border-top-width: 0 !important;
}
}
}
#about-zulip {
.exit {
font-size: 1.5rem;
font-weight: 600;
background-color: transparent;
border: none;
position: absolute;
right: 8px;
z-index: 1;
color: hsl(0deg 0% 67%);
}
.overlay-content {
width: 440px;
border-radius: 4px;
}
.about-zulip-logo {
text-align: center;
margin: 30px;
}
.about-zulip-logo img {
height: 40px;
}
& i.fa-copy {
cursor: pointer;
}
.fa-copy:hover {
color: hsl(170deg 48% 54%);
}
}
@media (width < $xl_min) {
.app-main,
.header-main {
min-width: 750px;
}
.column-right {
display: none;
&.expanded {
display: block;
position: absolute;
float: none;
right: 15px;
top: 0;
.simplebar-track.simplebar-vertical {
right: 0;
}
.right-sidebar {
box-shadow: 0 -2px 3px 0 hsl(0deg 0% 0% / 10%);
border-left: 1px solid hsl(0deg 0% 87%);
padding-right: 15px;
padding-left: 15px;
height: 100%;
right: 0;
background-color: var(--color-background);
}
}
}
.header-main .column-right {
display: inline-block;
width: 30px;
}
#top_navbar #navbar-buttons {
margin-right: 41px;
}
.nav .dropdown-menu {
min-width: 180px;
box-shadow: 0 0 5px hsl(0deg 0% 0% / 20%);
&::after {
right: 21px;
}
}
.column-middle {
margin-right: 7px;
}
#navbar-middle {
margin-right: 87px;
}
.search_closed .zulip-icon-search {
right: 115px;
}
}
@media (width < $md_min) {
body {
padding: 0;
}
.column-left {
display: none;
&.expanded {
display: block;
position: absolute;
float: none;
left: 0;
top: 0;
.left-sidebar {
background-color: var(--color-background);
box-shadow: 0 2px 3px 0 hsl(0deg 0% 0% / 10%);
border-right: 1px solid hsl(0deg 0% 87%);
height: 100%;
padding-left: 10px;
width: var(--left-sidebar-width);
}
}
}
body,
html,
.app-main,
.header-main {
min-width: 350px;
}
.column-middle,
.app-main .column-middle {
margin-left: 7px;
margin-right: 7px;
}
.header-main .column-middle {
margin-left: 0;
}
.column-middle-inner {
margin-left: 0;
}
.app-main .column-middle .column-middle-inner {
margin-right: 0;
}
#streamlist-toggle {
display: block;
}
.top-navbar-border {
margin-left: 40px;
}
.search_closed .zulip-icon-search {
right: 115px;
}
}
@media (width < $sm_min) {
.column-right.expanded .right-sidebar,
.column-left.expanded .left-sidebar {
margin-top: 31px;
}
.column-left.expanded {
.left-sidebar {
/* For very small sizes, skip the relatively large top padding. */
padding-top: 0;
#streams_header {
padding-right: 10px;
}
}
.narrows_panel {
margin-top: 10px;
}
}
/* Usually the styling is applied directly to the icon, but here
the icon is `position: static`, so we can't. */
.search_closed {
top: 5px;
}
#streamlist-toggle,
#navbar-buttons,
.navbar-search,
#message_view_header,
#searchbox,
.header {
line-height: var(--header-height);
height: var(--header-height);
}
#searchbox_form {
height: calc(var(--header-height) - 1px);
}
.spectator_narrow_login_button {
height: var(--header-height) !important;
}
#streamlist-toggle-button {
height: var(--header-height);
padding-top: 0;
padding-bottom: 0;
}
#navbar-buttons ul.nav .dropdown-toggle,
#navbar-buttons ul.nav li.active .dropdown-toggle {
top: -8px;
}
.include-sender .message_controls {
background: none !important;
padding: 0 !important;
border: none !important;
}
}
@media (width < $mm_min) {
html {
overflow-x: hidden;
}
body,
html,
.app-main,
.header-main {
min-width: 320px;
}
}
@media (width < $md_min) {
#feedback_container {
width: calc(90% - 30px);
left: 5%;
top: 5%;
}
}
#scroll-to-bottom-button-container {
display: block;
position: absolute;
bottom: 41px;
right: 0;
visibility: hidden;
opacity: 0;
transition:
visibility 500ms,
opacity 500ms ease-in-out;
&.show {
visibility: visible;
opacity: 1;
}
#scroll-to-bottom-button-clickable-area {
width: 60px;
height: 60px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
&:hover #scroll-to-bottom-button {
background: hsl(240deg 96% 68%);
}
#scroll-to-bottom-button {
text-align: center;
width: 40px;
height: 40px;
background: hsl(240deg 96% 68% / 50%);
border-radius: 50%;
& i {
color: hsl(0deg 0% 100%);
margin: 0 auto;
font-size: 21px;
position: relative;
top: 8px;
}
}
}
}
.tooltip_right_arrow {
position: relative;
top: -1px;
font-weight: 600;
}
.spectator_login_for_image_button {
max-width: 250px;
height: 50px;
:hover {
text-decoration: none;
}
.login_button {
padding: 5px;
margin-top: 5px;
.fa {
top: 1px;
}
}
}
.simplebar-content-wrapper {
/* `simplebar-content-wrapper` has `tabindex=0` set, which makes it focusable
but we don't want it to have an outline when focused anywhere in the app. */
outline: none;
/* This prevents the popover from closing once the top/bottom is reached */
overscroll-behavior: contain;
}
.dropdown-list-container {
.dropdown-list-search {
display: flex;
.dropdown-list-search-input {
background: var(--color-background-widget-input);
color: var(--color-text-dropdown-input);
width: 100%;
margin: 4px 4px 2px;
&:focus {
background: hsl(0deg 0% 100%);
border: 1px solid hsl(229.09deg 21.57% 10% / 80%);
box-shadow: 0 0 6px hsl(228deg 9.8% 20% / 30%);
}
}
}
.dropdown-list-item-common-styles {
padding: 3px 10px 3px 8px;
font-weight: 400;
line-height: 20px;
white-space: normal;
}
.dropdown-list-wrapper {
/* Sync with `max-height` in dropdown_widget. */
max-height: 210px;
min-width: 200px;
.dropdown-list {
list-style: none;
margin: 0;
.list-item:focus {
background-color: hsl(220deg 12% 4.9% / 5%);
outline: none;
}
.list-item a {
display: block;
color: hsl(0deg 0% 20%);
.stream-privacy-type-icon {
font-size: 13px;
width: 13px;
height: 13px;
padding-right: 2px;
}
&:hover {
text-decoration: none;
background-color: hsl(220deg 12% 4.9% / 5%);
}
&:focus {
text-decoration: none;
outline: none;
}
}
}
}
.no-dropdown-items {
color: hsl(0deg 0% 60%);
display: none;
}
}
#scheduled_messages_overlay .error-icon-message-recipient {
width: 15px;
height: 100%;
display: flex;
align-items: center;
justify-content: flex-end;
flex-grow: 1;
color: var(--color-failed-message-send-icon);
.zulip-icon {
padding: 5px;
}
}