zulip/web/styles/app_components.css

1380 lines
31 KiB
CSS

/* Reusable, object-oriented CSS base components for the Zulip web app
(not included in the portico CSS) */
.flex,
.show.flex {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.hide {
display: none;
}
.show {
display: block;
}
.hidden {
display: none;
visibility: hidden;
}
kbd {
display: inline-block;
border: 1px solid var(--color-kbd-border);
border-radius: 4px;
font-weight: 600;
white-space: nowrap;
background-color: var(--color-kbd-background);
color: var(--color-kbd-text);
margin: 0.25em 0.1em;
padding: 0.1em 0.4em;
text-shadow: 0 1px 0 hsl(0deg 0% 100%);
/* Prevent selection */
user-select: none;
}
@media (width < $sm_min) {
.hide-sm {
display: none !important;
}
#settings_page .save-button-controls {
display: block;
margin: 10px 0 0;
}
}
.light {
font-weight: 300;
}
.inline-block {
display: inline-block;
}
.display-block {
display: block !important;
}
.box-shadow {
box-shadow: 0 0 10px hsl(0deg 0% 0% / 10%);
}
.clear-float {
clear: both;
}
.invisible {
visibility: hidden;
}
.order-1 {
order: 1;
}
.order-2 {
order: 2;
}
.order-3 {
order: 3;
}
.lowercase {
text-transform: lowercase;
}
/*
Consistent placeholder styling, introduced to allow us to style the
Reply box like a placeholder. Chrome uses color to set placeholder,
while Firefox uses opacity, so we need to set both properties to avoid
mixed styling.
While we usually prefer opacity for text color in Zulip, there's some
evidence Edge may have bugs in its handling of placeholder opacity
CSS: https://github.com/necolas/normalize.css/issues/741
*/
.placeholder {
color: hsl(0deg 0% 45%);
opacity: 1;
}
textarea::placeholder,
input::placeholder {
@extend .placeholder;
}
/* -- base button styling -- */
.button {
padding: 7px 14px;
margin: 0;
min-width: 130px;
font-weight: 400;
line-height: normal;
text-align: center;
background-color: var(--color-background-zulip-button);
color: inherit;
outline: none;
border: 1px solid var(--color-border-zulip-button);
border-radius: 2px;
box-shadow: none;
cursor: pointer;
/* -- button style variations -- */
&.no-style {
padding: 0;
background-color: transparent;
border: none;
min-width: 0;
width: auto;
outline: none;
box-shadow: none !important;
}
&.rounded {
border-radius: 4px;
}
&.green {
background-color: hsl(150deg 31% 53%);
}
&.grey {
background-color: hsl(0deg 0% 67%);
}
&.small {
/* This value was 0.8rem in the past. When using rem,
the root font size was 16px when the base font-size was
14px. Now, we have two modes, one with 14px base
font-size and one with 16px base font-size. We multiply
by (16 / 14 * 0.8 = 0.9143) so rem equivalent value
will remain the same in the legacy 14px mode, while
scaling the size up for 16px mode. The font-size will
resolve in pixels.
TODO: Refactor this part to either use `em` or `rem`
and not this temporary hack of using calc() and
variables. */
font-size: calc(0.9143 * var(--base-font-size-px));
min-width: inherit;
padding: 6px 10px;
}
&:hover,
&:focus,
&:active {
border-color: var(--color-border-zulip-button-interactive);
}
&:hover {
background-color: var(--color-background-zulip-button-hover);
}
&:focus {
/* Maintain no outline for pointer focus. */
outline: 0;
}
&:focus-visible {
/* Set Zulip outline style with keyboard/assistive focus. */
outline: 2px solid var(--color-outline-focus);
}
&:active {
color: inherit;
background-color: var(--color-background-zulip-button-active);
}
&.add-subscription-button {
&:focus-visible {
border: 1px solid;
border-color: var(
--color-border-add-subscription-button-focus
) !important;
}
}
&.sea-green {
color: hsl(156deg 41% 40%);
border-color: hsl(156deg 28% 70%);
&:hover,
&:focus {
border-color: hsl(156deg 30% 50%);
}
&:active {
border-color: hsl(156deg 30% 40%);
color: hsl(156deg 44% 43%);
background-color: hsl(154deg 33% 96%);
}
}
&.btn-warning {
color: hsl(35deg 70% 56%);
border-color: hsl(35deg 98% 84%);
&:hover,
&:focus {
border-color: hsl(35deg 55% 70%);
}
&:active {
color: hsl(35deg 82% 40%);
border-color: hsl(35deg 55% 70%);
background-color: hsl(33deg 48% 96%);
}
}
&.btn-danger {
color: hsl(357deg 64% 72%);
border-color: hsl(4deg 56% 82%);
&:hover,
&:focus {
border-color: hsl(2deg 46% 68%);
}
&:active {
color: hsl(357deg 55% 63%);
border-color: hsl(2deg 46% 68%);
background-color: hsl(7deg 82% 98%);
}
}
&:disabled {
cursor: not-allowed;
filter: saturate(0);
background-color: var(--color-background-zulip-button-disabled);
color: hsl(0deg 3% 52%);
&:hover {
background-color: var(--color-background-zulip-button-disabled);
color: hsl(156deg 39% 54%);
border-color: hsl(156deg 39% 77%);
}
}
}
/* -- tab switcher -- */
.tab-switcher {
font-weight: initial;
margin: 2px 4px;
display: inline-block;
.ind-tab {
display: inline-block;
width: 90px;
margin: 0 -0.5px;
text-align: center;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
vertical-align: bottom; /* See https://stackoverflow.com/a/43266155/ */
padding: 3px 10px;
background-color: var(--color-background-tab-switcher-ind-tab);
cursor: pointer;
justify-content: center;
align-items: center;
&:focus {
outline: none;
}
&:not(.selected) {
border: 1px solid var(--color-border-tab-switcher-ind-tab);
}
&.first {
border-radius: 5px 0 0 5px;
border-right: 1px solid transparent;
}
&.middle {
border-right: 1px solid transparent;
}
&.last {
border-radius: 0 5px 5px 0;
}
&.selected {
position: relative;
background-color: var(
--color-background-tab-switcher-ind-tab-selected
);
color: hsl(0deg 0% 100%);
border: 1px solid var(--color-border-tab-switcher-ind-tab-selected);
z-index: 2;
}
&.disabled {
cursor: default;
color: var(--color-text-tab-switcher-ind-tab-disabled);
border-color: var(--color-border-tab-switcher-ind-tab-disabled);
}
}
&.large .ind-tab {
width: 100%;
}
&.allow-overflow {
display: flex;
.ind-tab {
display: flex;
text-overflow: initial;
white-space: initial;
vertical-align: middle;
}
}
}
.stream_sorter_toggle {
margin-left: auto;
}
/* -- unified overlay design component -- */
div.overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
-webkit-overflow-scrolling: touch;
background-color: hsl(0deg 0% 13% / 80%);
z-index: 105;
pointer-events: none;
opacity: 0;
visibility: hidden;
transition: all 0.2s ease-in;
overflow: hidden;
.overlay-content {
transform: translateY(20px);
transition: transform 0.2s ease-in;
z-index: 102;
}
&.show {
opacity: 1;
pointer-events: all;
visibility: visible;
transition: opacity 0.2s ease-out;
.overlay-content {
transform: translateY(0);
transition-timing-function: ease-out;
}
}
.overlay-scroll-container {
max-height: 60vh;
padding: 15px;
}
.overlay-container {
background-color: var(--color-background-modal);
}
}
.input-append {
font-size: 90%;
letter-spacing: -0.3em;
display: block;
}
.input-append input[type="text"],
input.settings_text_input {
border-radius: 5px;
box-shadow: none;
margin: 0;
}
/* TODO: Once all layouts using this button
are modernized, the Font Awesome icon
should be replaced with a Zulip icon,
and its formatting should have no extra
space around its viewbox in SVG. */
.clear_search_button {
&:hover {
color: var(--color-text-clear-search-button-hover);
}
&:disabled {
visibility: hidden;
}
&,
&:focus,
&:active,
&:disabled:hover {
position: relative;
right: 20px;
background: none;
border: none;
text-align: center;
padding-top: 8px;
padding-left: 4px;
color: var(--color-text-clear-search-button);
text-shadow: none;
outline: none !important;
box-shadow: none;
z-index: 5;
#set-user-status-modal & {
margin-left: -26px;
right: 0;
padding-top: 6px;
}
}
}
.grey-box {
margin: 0;
padding: 5px 10px;
background-color: hsl(0deg 0% 98%);
border: 1px solid hsl(0deg 0% 87%);
border-radius: 4px;
list-style-type: none;
}
.white-box {
background-color: hsl(0deg 0% 100%);
border: 1px solid hsl(0deg 0% 87%);
}
.guest-avatar {
position: relative;
overflow: hidden;
&::after {
content: " ";
background-color: hsl(0deg 0% 47%);
position: absolute;
bottom: -30%;
right: -30%;
width: 50%;
height: 50%;
transform: rotate(45deg);
}
}
.dependent-settings-block {
margin: 15px 0 -5px 23px;
}
.topic-list-filter {
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
& input {
padding-right: 20px;
}
}
.stream-selection-header-colorblock {
/* box-shadow: 0px 2px 3px hsl(0, 0%, 80%); */
box-shadow:
inset 0 2px 1px -2px hsl(0deg 0% 20%),
inset 2px 0 1px -2px hsl(0deg 0% 20%),
inset 0 -2px 1px -2px hsl(0deg 0% 20%);
width: 10px;
border-radius: 3px 0 0 3px;
border-bottom: 0;
}
.edit-controls .fa-angle-right,
.topic_stream_edit_header .fa-angle-right {
font-size: 0.9em;
-webkit-text-stroke: 0.05em;
position: relative;
margin: 0 5px;
top: 9px;
}
/* Standard loading indicators generated by the loading.ts API */
.loading_indicator_spinner {
/* If you change these, make sure to adjust the constants in
loading.make_indicator as well */
height: 38px;
width: 38px;
float: left;
}
.loading_indicator_text {
/* If you change these, make sure to adjust the constants in
loading.make_indicator as well */
margin-left: 5px;
font-size: 1.2em;
font-weight: 300;
line-height: 38px;
}
.upgrade-tip,
.upgrade-or-sponsorship-tip {
width: fit-content;
&::before {
content: "\f135";
margin-right: 6px;
}
}
.upgrade-tip:hover {
color: hsl(0deg 0% 20%);
border: 1px solid hsl(49deg 20% 60%);
box-shadow: 0 0 4px hsl(199deg 79% 56% / 20%);
text-decoration: none;
}
.upgrade-tip,
.upgrade-or-sponsorship-tip,
.tip,
.invite-stream-notice {
position: relative;
display: block;
background-color: var(--color-background-tip);
border: 1px solid var(--color-border-tip);
border-radius: 4px;
padding: 10px;
font-size: 1rem;
line-height: 1.5;
color: hsl(0deg 0% 40%);
&::before {
display: inline;
font-family: FontAwesome;
font-weight: 600;
}
}
.upgrade-tip,
.upgrade-or-sponsorship-tip,
.tip {
margin: 10px 0;
}
.invite-stream-notice {
margin-bottom: 20px;
}
.tip::before {
content: "\f0a2";
margin-right: 8px;
}
.demo-organization-warning {
position: relative;
display: block;
background-color: var(
--color-background-settings-demo-organization-warning
);
border: 1px solid var(--color-border-settings-demo-organization-warning);
border-radius: 4px;
padding: 10px;
margin: 10px 0;
font-size: 1rem;
line-height: 1.5;
color: var(--color-text-settings-demo-organization-warning);
a {
text-decoration: none;
}
.convert-demo-organization-button {
&:focus {
outline: 1px solid
var(--color-focus-outline-settings-convert-demo-organization);
outline-offset: 0;
}
}
}
/* We are mostly consistent in how we style
unread counts, except for starred messages.
This is the common section.
*/
.unread_count {
float: right;
padding: 0 4px;
/* 12px at 14px/em */
font-size: 0.8571em;
/* 16px at 12px/em, owing to font-size above. */
height: 1.3333em;
line-height: 1.3333em;
font-weight: normal;
border-radius: 4px;
background-color: var(--color-background-unread-counter);
color: hsl(0deg 0% 100%);
}
.unread_mention_info:not(:empty) {
margin-right: 5px;
margin-left: 2px;
opacity: 0.7;
}
.masked_unread_count {
float: right;
width: 8px;
height: 8px;
border-radius: 50%;
background-color: var(--color-masked-unread-marker);
display: none;
}
/* Implement the web app's default-hidden convention for alert
elements. Portico pages lack this CSS and thus show them by
default. */
.alert {
display: none;
&.show {
display: block;
}
&#organization-status {
margin: 20px;
}
&.stream_create_info {
margin: 10px 10px 0;
}
.bankruptcy_unread_count {
font-weight: 600;
}
}
.only-visible-for-spectators {
display: none;
}
.spectator-view {
/* Add this class to elements which a
* spectator cannot use. */
.hidden-for-spectators {
display: none !important;
}
.only-visible-for-spectators {
display: revert;
}
}
.animated-purple-button {
color: hsl(0deg 0% 100%);
transition: all 80ms linear;
box-shadow: none;
/* This color just passes WCAG AA */
background-color: hsl(240deg 96% 68%);
cursor: pointer;
border: none;
border-radius: 4px;
text-align: center;
white-space: nowrap;
&:hover {
/* This color passes WCAG AAA */
background-color: hsl(240deg 41% 50%);
box-shadow: 0 1px 4px hsl(0deg 0% 0% / 30%);
}
&:focus {
background-color: hsl(240deg 41% 50%);
box-shadow: 0 1px 4px 0
var(--color-box-shadow-animated-purple-button-focus);
outline: none;
}
&:disabled {
cursor: not-allowed;
opacity: 0.5;
}
}
.color_animated_button {
display: flex;
justify-content: center;
background-color: var(--color-background-animated-button);
color: hsl(0deg 0% 0%);
border-radius: 4px;
.color-animated-button-text {
color: var(--color-animated-button-text);
}
&:hover {
cursor: pointer;
background-color: var(--color-background-animated-button-hover);
color: hsl(0deg 0% 100%);
.color-animated-button-text {
color: hsl(0deg 0% 100%);
transition: all 0.2s ease;
}
transition: all 0.2s ease;
}
.zulip-icon,
.color-animated-button-text {
padding: 6px 3px;
}
.fa {
position: relative;
top: 3px;
}
}
.table-striped {
table-layout: auto;
border-collapse: separate;
border-spacing: 0;
margin-bottom: 20px;
width: 100%;
&:not(.table-bordered) {
thead th {
border-top: 1px solid hsl(0deg 0% 0% / 20%) !important;
border-bottom: 1px solid hsl(0deg 0% 0% / 20%) !important;
}
tbody tr:first-child td {
border-top: 0;
}
}
& thead th {
color: inherit;
background-color: hsl(0deg 0% 100%);
word-break: normal;
&[data-sort] {
padding-right: var(--table-header-sortable-column-padding-right);
}
&.active::after,
&[data-sort]:hover::after {
content: " \f0d8";
white-space: pre;
display: inline-block;
position: absolute;
padding-top: 3px;
font: normal normal normal 12px/1 FontAwesome;
font-size: inherit;
}
&.active {
opacity: 1;
transition: opacity 100ms ease-out;
&.descend::after {
content: " \f0d7";
}
}
&[data-sort]:hover {
cursor: pointer;
background-color: hsl(0deg 0% 95%) !important;
transition: background-color 100ms ease-in-out;
&:not(.active)::after {
opacity: 0.3;
}
}
}
tbody > tr:nth-child(odd) > td {
background-color: var(--color-background-modal);
}
/* Force the actions column to use the minimum space necessary */
.actions {
width: 1%;
white-space: nowrap;
}
th.actions {
padding-right: 1em;
}
& th,
td {
padding: 4px 5px;
}
& th {
text-align: left;
}
& td {
border-top: 1px solid var(--color-border-table-striped);
}
}
.table-bordered {
border: 1px solid var(--color-border-table-bordered);
border-collapse: separate;
border-left: 0;
border-radius: 4px;
border-spacing: 0;
width: 100%;
margin-bottom: 20px;
& th,
td {
border-left: 1px solid var(--color-border-table-bordered);
border-top: 1px solid var(--color-border-table-bordered);
padding: 4px 5px;
text-align: left;
}
thead tr:first-child th {
border-top: 0;
}
thead tr:first-child > th:first-child {
border-top-left-radius: 4px;
}
thead tr:first-child > th:last-child {
border-top-right-radius: 4px;
}
tbody:last-child tr:last-child > td:first-child {
border-bottom-left-radius: 4px;
}
tbody:last-child tr:last-child > td:last-child {
border-bottom-right-radius: 4px;
}
}
#stream_settings .save-button-controls,
#settings_page .save-button-controls,
#user_group_settings .save-button-controls {
display: inline;
margin-left: 15px;
&.hide {
display: none;
}
.save-discard-widget-button {
border-radius: 5px;
border: 1px solid hsl(0deg 0% 80%);
padding: 3px 14px 4px 11px;
text-decoration: none;
color: hsl(0deg 0% 47%);
min-width: 80px;
/* Limit the height of the button */
line-height: 1.2;
vertical-align: text-bottom;
&:hover,
&:focus {
border: 1px solid hsl(0deg 0% 61%);
.discard-button.save-discard-widget-button-text {
color: hsl(0deg 0% 18%);
}
}
&.primary {
background-color: hsl(156deg 30% 50%);
color: hsl(0deg 0% 100%);
border: 1px solid hsl(155deg 30% 50%);
&:hover,
&:focus {
background-color: hsl(166deg 35% 57%);
border: 1px solid hsl(166deg 35% 57%);
}
.save-discard-widget-button-icon {
font-weight: 400;
color: hsl(0deg 0% 100%);
}
&.saving {
background-color: hsl(156deg 14% 40%);
border-color: hsl(156deg 14% 40%);
}
}
&.save-button {
margin-right: 5px;
.save-discard-widget-button-loading {
display: none;
}
&.saving {
.save-discard-widget-button-icon {
display: none;
}
.save-discard-widget-button-loading {
display: inline-block;
margin-right: 2px;
}
}
}
.save-discard-widget-button-icon {
vertical-align: middle;
margin-right: 3px;
font-size: 15px;
font-weight: 400;
}
.save-discard-widget-button-text {
vertical-align: middle;
line-height: 1;
}
}
}
.stream-privacy-type-icon {
position: relative;
top: 0.06rem;
padding-right: 1px;
width: 12px;
&.zulip-icon-globe,
&.zulip-icon-hashtag {
font-size: 0.75em;
}
&.zulip-icon-lock,
&.zulip-icon-users {
font-size: 0.8em;
}
}
.zulip-icon-lock {
/* The lock icon is bottom heavy, so to make it
appear better aligned, we pull it up by a
uniform margin throughout the UI. */
/* 3.5px at 16px/1em */
margin-top: -0.2188em !important;
}
.dropdown-list-container
.dropdown-list
.dropdown-list-item-common-styles
.zulip-icon-lock {
/* We do not need to pull up lock icons in dropdowns
so we reset their margin-top to the original value
for a dropdown's .zulip-icon */
margin-top: 2px !important;
}
/* This includes css needed to display messages in an overlay. */
.overlay-messages-container {
position: relative;
height: 95%;
background-color: var(--color-background-modal);
border-radius: 4px;
padding: 0;
width: 58%;
overflow: hidden;
max-width: 1200px;
max-height: 1000px;
display: flex;
flex-direction: column;
@media (width < $md_min) {
height: 95%;
max-width: none;
width: 90%;
}
.overlay-messages-header {
padding-top: 4px;
padding-bottom: 8px;
text-align: center;
border-bottom: 1px solid hsl(0deg 0% 87%);
& h1 {
margin: 0;
font-size: 1.1em;
text-transform: uppercase;
}
.exit {
font-weight: 400;
position: absolute;
top: 10px;
right: 10px;
color: hsl(0deg 0% 67%);
cursor: pointer;
.exit-sign {
position: relative;
top: 1px;
margin-left: 3px;
font-size: 1.5rem;
line-height: 1;
font-weight: 600;
cursor: pointer;
}
}
}
.overlay-messages-list {
padding: 10px 25px;
overflow: auto;
.no-overlay-messages {
display: block;
margin-top: calc(45vh - 30px - 1.5em);
text-align: center;
font-size: 1.5em;
color: hsl(0deg 0% 67%);
pointer-events: none;
}
}
}
.overlay-messages-container .overlay-message-row {
padding: 5px 0;
.overlay-message-info-box {
width: 100%;
margin-bottom: 10px;
&.active {
outline: 2px solid var(--color-outline-focus);
border-radius: 7px;
}
.message_row {
border-radius: 0 0 7px 7px;
border: 1px solid var(--color-message-list-border);
border-top: 0;
}
.messagebox-content {
grid-template: auto / auto max-content;
grid-template-areas:
"message controls"
"message . ";
/* to space from restore draft button */
column-gap: 5px;
padding: 10px;
.message_content {
cursor: pointer;
grid-area: message;
}
.message_top_line {
grid-area: controls;
}
}
.messagebox {
cursor: auto;
box-shadow: none;
border-radius: 0 0 7px 7px;
}
.overlay_message_controls {
display: flex;
align-items: center;
justify-content: center;
gap: 10px;
font-size: 0.9em;
[data-tippy-root] {
width: max-content;
word-wrap: unset;
}
.restore-overlay-message {
cursor: pointer;
color: hsl(170deg 48% 54%);
opacity: 0.7;
&:hover {
opacity: 1;
}
}
.delete-overlay-message {
cursor: pointer;
color: hsl(357deg 52% 57%);
opacity: 0.7;
&:hover {
opacity: 1;
}
}
}
.message_header {
/* We don't need these effects applied for message list in the drafts overlay. */
box-shadow: none !important;
border: 0 !important;
background: transparent;
}
}
}
.dropdown-widget-button {
background-color: var(--color-background-dropdown-widget-button);
padding: 4px 6px;
border: 1px solid var(--color-border-dropdown-widget-button);
border-radius: 4px;
display: flex;
align-items: center;
justify-content: space-between;
outline: none;
color: var(--color-text-default);
&:disabled {
cursor: not-allowed;
background-color: var(
--color-background-disabled-dropdown-widget-button
);
opacity: 0.7;
}
}
.dropdown_widget_with_label_wrapper {
margin-top: 0 !important;
}
.dropdown-current-value-not-in-options,
.setting-disabled-option {
color: hsl(38deg 46% 54%);
.setting-disabled-option-icon {
/* Values set to match text alignment in stream dropdown. */
padding: 0 5px 0 1px;
}
}
.empty-list-message,
.empty-table-message {
background-color: inherit;
color: var(--color-text-default);
font-size: 1.5em;
padding: 3em 1em !important;
text-align: center;
}
.filter_text_input {
padding: 4px 6px;
color: hsl(0deg 0% 33%);
border: 1px solid hsl(0deg 0% 80%);
transition:
border linear 0.2s,
box-shadow linear 0.2s;
box-shadow: inset 0 1px 1px hsl(0deg 0% 0% / 7.5%);
border-radius: 4px;
&: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%);
}
}
/**
* Use the "tab-picker-vertical" class in conjunction
* for a vertical tab picker.
*/
.tab-picker {
position: relative;
display: grid;
grid-auto-flow: column;
grid-auto-columns: 1fr;
gap: var(--grid-gap-tab-picker);
box-sizing: border-box;
border-radius: 5px;
/* Using max-content ensures equal width tabs. */
min-width: max-content;
padding: 1px;
background-color: var(--color-background-tab-picker-container);
/* 16px at 15px/1em */
font-size: 1.0666em;
input[type="radio"] {
display: none;
}
.tab-option-content {
z-index: 2;
display: flex;
justify-content: center;
align-items: center;
/* Avoids layout shift while showing a border when pressed. */
border: 1px solid transparent;
border-radius: 4px;
box-sizing: border-box;
padding: 3px 7px;
color: var(--color-text-dropdown-menu);
& .zulip-icon {
/* Clear inherited position. */
position: static;
color: var(--color-icon-purple);
}
}
.tab-option:not(:checked) + .tab-option-content {
&:hover,
&:focus-visible {
background-color: var(
--color-background-tab-picker-tab-option-hover
);
}
&:active {
background-color: var(
--color-background-tab-picker-tab-option-active
);
}
}
.tab-option {
&:nth-of-type(1):checked ~ .slider {
--tab-selected-tab-picker: 0;
}
&:nth-of-type(2):checked ~ .slider {
--tab-selected-tab-picker: 1;
}
&:nth-of-type(3):checked ~ .slider {
--tab-selected-tab-picker: 2;
}
&:nth-of-type(4):checked ~ .slider {
--tab-selected-tab-picker: 3;
}
&:nth-of-type(5):checked ~ .slider {
--tab-selected-tab-picker: 4;
}
/* If a tab picker with more than 5 tabs is required,
extend this using the same pattern as above. */
}
.slider {
position: absolute;
z-index: 1;
inset: 0;
grid-column: 1 / 2;
grid-row: 1 / 2;
/* Move along X-axis: own width + gap between two tabs. */
transform: translateX(
calc(
(100% + var(--grid-gap-tab-picker)) *
var(--tab-selected-tab-picker)
)
);
transition: transform 0.25s cubic-bezier(0.64, 0, 0.78, 0);
box-sizing: border-box;
border: 1px solid var(--color-outline-tab-picker-tab-option);
border-radius: 4px;
background-color: var(--color-background-tab-picker-selected-tab);
}
/* Detect if a user has enabled a setting on their device
to minimize the amount of non-essential motion. */
@media (prefers-reduced-motion) {
.slider {
transition: none;
}
.tab-option:not(:checked) + .tab-option-content:active {
border-color: var(--color-outline-tab-picker-tab-option);
}
}
/* Related to vertical tab picker. */
&.tab-picker-vertical {
grid-auto-flow: row;
grid-auto-rows: 1fr;
.slider {
/* Move along Y-axis: own height + gap between two tabs. */
transform: translateY(
calc(
(100% + var(--grid-gap-tab-picker)) *
var(--tab-selected-tab-picker)
)
);
}
}
}
.copy-btn {
display: flex;
border-radius: 4px;
color: var(--color-copy-btn);
/* 2px at 16px/1em */
padding: 0.125em;
cursor: pointer;
&:hover,
&:focus-visible {
color: var(--color-copy-btn-hover);
}
&:active {
color: var(--color-copy-btn-active);
}
&.copy-btn-square {
&:hover,
:focus-visible {
background-color: var(--color-copy-btn-square-bg-hover);
}
&:active {
background-color: var(--color-copy-btn-square-bg-active);
color: var(--color-copy-btn-square-active);
}
}
&.copy-btn-success {
color: var(--color-copy-btn-success);
}
}
.text-success {
color: hsl(120.91deg 32.04% 40.39%);
}
.text-error {
color: hsl(1.06deg 44.66% 50.39%);
}