// Copyright 2016-2022 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only // Fonts @mixin font-family { font-family: $inter; &:lang(ja) { font-family: 'SF Pro JP', 'Hiragino Kaku Gothic Pro', 'ヒラギノ角ゴ Pro W3', メイリオ, Meiryo, 'MS Pゴシック', 'Helvetica Neue', Helvetica, Arial, sans-serif; } } @mixin font-title-1 { @include font-family; font-weight: 600; font-size: 26px; line-height: 32px; letter-spacing: -0.56px; } @mixin font-title-2 { @include font-family; font-weight: 600; font-size: 20px; line-height: 26px; letter-spacing: -0.34px; } @mixin font-body-1 { @include font-family; font-size: 14px; line-height: 20px; letter-spacing: -0.08px; } @mixin font-body-1-bold { @include font-body-1; font-weight: 600; } @mixin font-body-1-italic { @include font-body-1; font-style: italic; } @mixin font-body-1-bold-italic { @include font-body-1; font-weight: 600; font-style: italic; } @mixin font-body-2 { @include font-family; font-size: 13px; line-height: 18px; letter-spacing: -0.03px; } @mixin font-body-2-bold { @include font-body-2; font-weight: 600; } @mixin font-body-2-italic { @include font-body-2; font-style: italic; } @mixin font-body-2-bold-italic { @include font-body-2; font-weight: 600; font-style: italic; } @mixin font-subtitle { @include font-family; font-size: 11px; line-height: 16px; letter-spacing: 0; } @mixin font-caption { @include font-family; font-size: 11px; line-height: 14px; letter-spacing: 0.06px; } @mixin font-caption-bold { @include font-caption; font-weight: 600; } @mixin font-caption-bold-italic { @include font-caption; font-weight: 600; font-style: italic; } // Themes @mixin light-theme() { @content; } @mixin explicit-light-theme() { .light-theme & { @content; } } @mixin dark-theme() { .dark-theme & { @content; } } // Utilities @mixin rounded-corners() { // This ensures the borders are completely rounded. (A value like 100% would make it an ellipse.) border-radius: 9999px; } @mixin smooth-scroll() { scroll-behavior: smooth; @media (prefers-reduced-motion) { scroll-behavior: auto; } } // NOTE: As of this writing, this mixin only works in the main window, because this class // is only applied there. @mixin only-when-page-is-visible { .page-is-visible & { @content; } } // Search results loading @mixin search-results-loading-pulsating-background { animation: search-results-loading-pulsating-background-animation 2s infinite; @media (prefers-reduced-motion) { animation: none; } @include light-theme { background: $color-gray-05; } @include dark-theme { background: $color-gray-65; } } @keyframes search-results-loading-pulsating-background-animation { 0% { opacity: 1; } 50% { opacity: 0.55; } 100% { opacity: 1; } } @mixin search-results-loading-box($width) { width: $width; height: 12px; border-radius: 4px; @include search-results-loading-pulsating-background; } // Icons @mixin color-svg($svg, $color, $stretch: true, $mask-origin: null) { -webkit-mask: url($svg) no-repeat center; @if $stretch { -webkit-mask-size: 100%; } @if $mask-origin { -webkit-mask-origin: $mask-origin; } background-color: $color; @media (forced-colors: active) { background-color: WindowText; } } // Keyboard @mixin keyboard-mode() { .keyboard-mode & { @content; } } @mixin mouse-mode() { .mouse-mode & { @content; } } @mixin dark-keyboard-mode() { .dark-theme.keyboard-mode & { @content; } } @mixin dark-mouse-mode() { .dark-theme.mouse-mode & { @content; } } // Other @mixin popper-shadow() { box-shadow: 0px 8px 20px rgba(0, 0, 0, 0.3), 0px 0px 8px rgba(0, 0, 0, 0.05); @media (forced-colors: active) { border: 1px solid WindowText; } } @mixin button-reset { background: none; color: inherit; border: none; padding: 0; margin: 0; font: inherit; cursor: pointer; outline: inherit; text-align: inherit; @media (forced-colors: active) { border: 1px solid WindowText; } } @mixin staged-attachment-close-button { @include button-reset; position: absolute; top: 8px; right: 8px; width: 18px; height: 18px; z-index: $z-index-above-base; } @mixin calling-text-shadow { text-shadow: 0 0 4px $color-black-alpha-40; } @mixin lonely-local-video-preview { max-height: calc(100% - 24px); height: auto; transform: rotateY(180deg); width: calc(100% - 24px); border-radius: 8px; } // --- Buttons // Individual traits @mixin button-focus-outline { &:focus { @include keyboard-mode { box-shadow: 0px 0px 0px 3px $color-ultramarine; } @include dark-keyboard-mode { box-shadow: 0px 0px 0px 3px $color-ultramarine-light; } } } @mixin button-blue-text { @include light-theme { color: $color-ultramarine; } @include dark-theme { color: $color-ultramarine-light; } } // Complete button styles @mixin button-primary { background-color: $color-ultramarine; // Note: the background colors here need to match the parent component @include light-theme { color: $color-white; border: 1px solid white; } @include dark-theme { color: $color-white-alpha-90; border: 1px solid $color-gray-95; } &:hover { @include mouse-mode { background-color: mix($color-black, $color-ultramarine, 15%); } @include dark-mouse-mode { background-color: mix($color-white, $color-ultramarine, 15%); } } &:active { // We need to include all four here for specificity precedence @include mouse-mode { background-color: mix($color-black, $color-ultramarine, 25%); } @include dark-mouse-mode { background-color: mix($color-white, $color-ultramarine, 25%); } @include keyboard-mode { background-color: mix($color-black, $color-ultramarine, 25%); } @include dark-keyboard-mode { background-color: mix($color-black, $color-ultramarine, 25%); } } @include button-focus-outline; } @mixin button-secondary { @include light-theme { color: $color-gray-90; background-color: $color-gray-05; } @include dark-theme { color: $color-gray-05; background-color: $color-gray-65; } &:hover { @include mouse-mode { background-color: mix($color-black, $color-gray-05, 15%); } @include dark-mouse-mode { background-color: mix($color-white, $color-gray-65, 15%); } } &:active { // We need to include all four here for specificity precedence @include mouse-mode { background-color: mix($color-black, $color-gray-05, 25%); } @include dark-mouse-mode { background-color: mix($color-white, $color-gray-65, 25%); } @include keyboard-mode { background-color: mix($color-black, $color-gray-05, 25%); } @include dark-keyboard-mode { background-color: mix($color-white, $color-gray-65, 25%); } } @include button-focus-outline; } @mixin button-secondary-blue-text { @include button-secondary; @include button-blue-text; } @mixin button-light { @include light-theme { color: $color-gray-90; background-color: $color-gray-02; } @include dark-theme { color: $color-gray-05; background-color: $color-gray-75; } &:hover { @include mouse-mode { background-color: mix($color-black, $color-gray-02, 10%); } @include dark-mouse-mode { background-color: mix($color-white, $color-gray-75, 10%); } } &:active { // We need to include all four here for specificity precedence @include mouse-mode { background-color: mix($color-black, $color-gray-02, 20%); } @include dark-mouse-mode { background-color: mix($color-white, $color-gray-75, 20%); } @include keyboard-mode { background-color: mix($color-black, $color-gray-02, 20%); } @include dark-keyboard-mode { background-color: mix($color-white, $color-gray-75, 20%); } } @include button-focus-outline; } @mixin button-light-blue-text { @include button-light; @include button-blue-text; } @mixin button-destructive { @include light-theme { color: $color-white; background-color: $color-accent-red; } @include dark-theme { color: $color-white-alpha-90; background-color: $color-accent-red; } &:hover { @include mouse-mode { background-color: mix($color-black, $color-accent-red, 15%); } @include dark-mouse-mode { background-color: mix($color-white, $color-accent-red, 15%); } } &:active { // We need to include all four here for specificity precedence @include mouse-mode { background-color: mix($color-black, $color-accent-red, 25%); } @include dark-mouse-mode { background-color: mix($color-white, $color-accent-red, 25%); } @include keyboard-mode { background-color: mix($color-black, $color-accent-red, 25%); } @include dark-keyboard-mode { background-color: mix($color-white, $color-accent-red, 25%); } } @include button-focus-outline; } @mixin button-green { $background-color: $color-accent-green; background-color: $background-color; color: $color-white; &:active { // We need to include all four here for specificity precedence @include mouse-mode { background-color: mix($color-black, $background-color, 25%); } @include dark-mouse-mode { background-color: mix($color-white, $background-color, 25%); } @include keyboard-mode { background-color: mix($color-black, $background-color, 25%); } @include dark-keyboard-mode { background-color: mix($color-white, $background-color, 25%); } } &[disabled] { opacity: 0.6; } @include button-focus-outline; } @mixin button-small { @include rounded-corners; padding: 7px 14px; } // Modals @mixin modal-reset { @include popper-shadow(); border-radius: 8px; margin: 0 auto; max-height: 100%; max-width: 360px; padding: 16px; position: relative; width: 95%; display: flex; flex-direction: column; @include light-theme() { background: $color-white; color: $color-gray-90; } @include dark-theme() { background: $color-gray-95; color: $color-gray-05; } } @mixin modal-close-button { @include button-reset; position: absolute; right: 12px; top: 12px; height: 24px; width: 24px; @include light-theme { @include color-svg('../images/icons/v2/x-24.svg', $color-gray-75); } @include dark-theme { @include color-svg('../images/icons/v2/x-24.svg', $color-gray-15); } &:focus { @include keyboard-mode { background-color: $color-ultramarine; } @include dark-keyboard-mode { background-color: $color-ultramarine-light; } } } @mixin color-bubble($bubble-size) { background-clip: content-box; border-color: transparent; border-radius: $bubble-size + 12px; border-style: solid; border-width: 4px; cursor: pointer; height: $bubble-size + 12px; padding: 2px; width: $bubble-size + 12px; @each $color, $value in $conversation-colors { &--#{$color} { background-color: $value; } } @each $color, $value in $conversation-colors-gradient { &--#{$color} { background-image: linear-gradient( map-get($value, 'deg'), map-get($value, 'start'), map-get($value, 'end') ); } } } @mixin avatar-colors { @each $color, $value in $avatar-colors { &--#{$color} { --bg: #{map-get($value, 'bg')}; --fg: #{map-get($value, 'fg')}; background-color: var(--bg); color: var(--fg); &--icon { background-color: var(--fg); @include dark-theme { // For specificity background-color: var(--fg); } } } } } @mixin scrollbar { &::-webkit-scrollbar-thumb { border-radius: 4px; visibility: hidden; width: 6px; @include light-theme { background: $color-black-alpha-40; } @include dark-theme { background: $color-white-alpha-40; } } &::-webkit-scrollbar { background: transparent; } &::-webkit-scrollbar-track { background: transparent; } &:hover::-webkit-scrollbar-thumb { visibility: visible; } } @mixin normal-input { @include font-body-1; padding: 8px 12px; border-radius: 6px; border-width: 2px; border-style: solid; width: 100%; @include light-theme { background: $color-white; color: $color-black; border-color: $color-gray-15; &:disabled { background: $color-gray-02; border-color: $color-gray-05; color: $color-gray-90; } } @include dark-theme { background: $color-gray-80; color: $color-gray-05; border-color: $color-gray-45; &:disabled { background: $color-gray-95; border-color: $color-gray-60; color: $color-gray-20; } } &:focus { outline: none; @include light-theme { border-color: $color-ultramarine; } @include dark-theme { border-color: $color-ultramarine-light; } } } @mixin install-screen { align-items: center; display: flex; width: var(--window-width); height: var(--window-height); justify-content: center; line-height: 30px; user-select: none; @include light-theme { background: $color-gray-02; color: $color-black; } @include dark-theme { background: $color-gray-95; color: $color-white; } h1 { @include font-title-2; } h2 { @include font-body-1; font-weight: normal; } } @mixin timeline-floating-header-node { @include rounded-corners; box-shadow: 0 1px 4px $color-black-alpha-20; @include light-theme { background: $color-white; } @include dark-theme { background: $color-gray-80; } }