/** * Shoelace CSS theming variables and component overrides * https://github.com/shoelace-style/shoelace/blob/next/src/themes/light.css * * To make new variables available to Tailwind, update * `theme` in tailwind.config.js */ @tailwind base; @tailwind components; @tailwind utilities; @layer base { :root { /* Custom contextual variables */ --primary: theme(colors.primary.DEFAULT); --success: var(--sl-color-success-600); --warning: var(--sl-color-warning-600); --danger: var(--sl-color-danger-600); /* Custom font variables */ --font-monostyle-family: var(--sl-font-mono); --font-monostyle-variation: "MONO" 0.51, "CASL" 0, "slnt" 0, "CRSV" 0; --font-monospace-variation: "MONO" 1, "CASL" 0, "slnt" 0, "CRSV" 0; --font-size-base: 1rem; /* Custom screen widths */ --btrix-screen-desktop: 82.5rem; /* Should match tailwind.config.screens.desktop */ /* * Shoelace Theme Tokens */ /* Primary */ --sl-color-primary-50: theme(colors.primary.50); --sl-color-primary-100: theme(colors.primary.100); --sl-color-primary-200: theme(colors.primary.200); --sl-color-primary-300: theme(colors.primary.300); --sl-color-primary-400: theme(colors.primary.400); --sl-color-primary-500: theme(colors.primary.500); --sl-color-primary-600: theme(colors.primary.600); --sl-color-primary-700: theme(colors.primary.700); --sl-color-primary-800: theme(colors.primary.800); --sl-color-primary-900: theme(colors.primary.900); --sl-color-primary-950: theme(colors.primary.900); /* * Typography */ /* Fonts */ --sl-font-mono: "Recursive var", SFMono-Regular, Consolas, "Liberation Mono", Menlo, monospace; --sl-font-sans: "Inter var", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; /* Font sizes */ --sl-font-size-medium: 0.875rem; /* 14px */ --sl-font-size-2x-large: 2rem; /* 32px */ /* Font weights */ --sl-font-weight-medium: 500; --sl-font-weight-semibold: 600; /* Focus rings */ --sl-focus-ring-color: var(--sl-color-primary-200); --sl-focus-ring-width: 2px; /* * Forms */ /* Buttons */ --sl-button-font-size-small: var(--sl-font-size-small); --sl-button-font-size-medium: var(--sl-font-size-small); --sl-button-font-size-large: var(--sl-font-size-medium); /* Inputs */ --sl-input-height-small: 2rem; /* 32px */ --sl-input-font-size-small: var(--sl-font-size-small); --sl-input-font-size-medium: var(--sl-font-size-small); --sl-input-font-size-large: var(--sl-font-size-medium); --sl-input-placeholder-color: var(--sl-color-neutral-400); /* From GitHub Primer https://github.com/primer/primitives/blob/8b767947e35a79db17b9d7970836f03c904c8afe/data/colors/vars/global_light.ts#L47 */ /* TODO replace hardcoded color */ --sl-input-required-content-color: #9a6700; /* Labels */ --sl-input-label-font-size-small: var(--sl-font-size-x-small); --sl-input-label-font-size-medium: var(--sl-font-size-small); --sl-input-label-font-size-large: var(--sl-font-size-medium); --sl-input-label-color: var(--sl-color-neutral-800); /* Help text */ --sl-input-help-text-font-size-medium: var(--sl-font-size-x-small); --sl-shadow-x-small: 0px 1px 2px rgba(0, 0, 0, 0.15); /* Transition */ --sl-transition-x-fast: 100ms; /* * * Browsertrix theme tokens * */ /* Overflow scrim */ --btrix-overflow-scroll-scrim-color: var(--sl-panel-background-color); --btrix-overflow-scrim-width: 3rem; } body { font-size: var(--sl-font-size-medium); } :focus-visible { outline: var(--sl-focus-ring); outline-offset: var(--sl-focus-ring-offset); } } @layer components { sl-avatar::part(base) { transition: var(--sl-transition-x-fast) background-color; } sl-avatar:hover::part(base) { background-color: var(--sl-color-primary-500); } /* Add more spacing between label, input and help text */ .form-label, btrix-tag-input::part(form-control-label), sl-input::part(form-control-label), sl-textarea::part(form-control-label), sl-select::part(form-control-label) { --sl-spacing-3x-small: 0.375rem; line-height: 1.4; } .form-label { display: inline-block; margin-bottom: var(--sl-spacing-3x-small); } .form-help-text, btrix-tag-input::part(form-control-help-text), sl-input::part(form-control-help-text), sl-textarea::part(form-control-help-text), sl-select::part(form-control-help-text) { margin-top: var(--sl-spacing-x-small); font-weight: 400; /* Enable controlling help text text alignment from parent */ text-align: var(--help-text-align, left); } .form-help-text { color: var(--sl-input-help-text-color); font-size: var(--sl-input-help-text-font-size-medium); } /* Update button colors */ sl-button[variant="primary"]:not([outline])::part(base) { background-color: theme(colors.primary.400); } sl-button[variant="primary"]:not([outline])::part(base):hover { background-color: theme(colors.primary.500); } sl-radio-button[checked]::part(button) { background-color: theme(colors.primary.500); } /* Elevate select and buttons */ sl-select::part(combobox), sl-button:not([variant="text"])::part(base) { box-shadow: var(--sl-shadow-x-small); } /* Prevent horizontal scrollbar */ sl-select::part(menu) { overflow-x: hidden; } /* Decrease control spacing on small select */ sl-select[size="small"]::part(control) { --sl-input-spacing-small: var(--sl-spacing-x-small); line-height: 1.5; } /* Align left edge with prefix icon */ sl-menu sl-menu-label::part(base) { padding-left: 25px; } /* Align left edge with selected item */ sl-select sl-menu-label::part(base) { padding-left: var(--sl-spacing-medium); } sl-menu-label::part(base) { font-weight: var(--sl-font-weight-medium); } /* Add border to menu */ sl-menu { border: 1px solid var(--sl-panel-border-color); } /* Validation styles */ /** * FIXME Use [data-user-invalid] selector exclusion table is migrated * https://github.com/webrecorder/browsertrix/issues/2542 */ .invalid[data-invalid]:not([disabled])::part(base), btrix-url-input[data-user-invalid]:not([disabled])::part(base), sl-input[data-user-invalid]:not([disabled])::part(base), sl-textarea[data-user-invalid]:not([disabled])::part(base) { border-color: var(--sl-color-danger-400); } .invalid[data-invalid]:focus-within::part(base), btrix-url-input[data-user-invalid]:focus-within::part(base), sl-input[data-user-invalid]:focus-within::part(base), sl-textarea[data-user-invalid]:focus-within::part(base) { box-shadow: 0 0 0 var(--sl-focus-ring-width) var(--sl-color-danger-100); } [data-user-invalid]:not([disabled])::part(form-control-label), /* Required asterisk color */ [data-user-invalid]:not([disabled])::part(form-control-label)::after { color: var(--sl-color-danger-700); } [data-user-invalid]:not([disabled])::part(form-control-help-text), [data-user-invalid]:not([disabled]) .form-help-text { color: var(--sl-color-danger-700); } /* TODO tailwind sets border-width: 0, see if this can be fixed in tw */ sl-divider { border-top-width: var(--sl-panel-border-width); } /* Add more spacing between radio options */ sl-radio-group sl-radio:first-of-type { margin-top: var(--sl-spacing-x-small); } sl-radio-group sl-radio:not(:first-of-type) { margin-top: var(--sl-spacing-small); } /* Have button group take up whole width */ sl-radio-group:not([size="small"])::part(button-group), sl-radio-group:not([size="small"]) sl-radio-button { width: 100%; min-width: min-content; } /* Style tooltip with white background */ /* TODO Replace instances with `` */ sl-tooltip.invert-tooltip { --sl-tooltip-arrow-size: 0; --sl-tooltip-background-color: var(--sl-color-neutral-50); --sl-tooltip-color: var(--sl-color-neutral-700); } sl-tooltip.invert-tooltip::part(body) { outline: 1px solid var(--sl-panel-border-color); box-shadow: var(--sl-shadow-large); } sl-tab-group { --indicator-color: var(--sl-color-primary-500); } sl-tab::part(base) { padding: var(--sl-spacing-small) var(--sl-spacing-medium); } sl-tab:not([active]):not(:hover)::part(base) { color: var(--sl-color-neutral-500); } sl-tab:not([active]):hover::part(base) { color: var(--sl-color-neutral-600); } sl-tab[active]::part(base) { color: var(--sl-color-primary-500); } /* For single-input forms with submit button inline */ /* Requires form control and button to be direct children */ .inline-control-input, .inline-control-input::part(form-control) { display: contents; } .inline-control-form { display: grid; grid-template-areas: "label ." "input button" "help-text ."; grid-template-columns: 1fr max-content; column-gap: var(--sl-spacing-small); } .inline-control-input::part(form-control-label) { grid-area: label; } .inline-control-input::part(form-control-input) { grid-area: input; } .inline-control-input::part(form-control-help-text) { grid-area: help-text; } .inline-control-button { grid-area: button; } /* Inputs with "Max N characters" help text */ .with-max-help-text { --help-text-align: right; } /* Wrap internal textarea input, e.g. for URL lists */ .textarea-wrap::part(textarea) { white-space: pre; } /** Render label to the side of the input **/ .label-same-line::part(form-control) { display: grid; grid-template-columns: auto 1fr; gap: var(--sl-spacing-x-small); align-items: center; } .label-same-line::part(form-control-label) { margin: 0; } .label-same-line::part(form-control-help-text) { grid-column-start: 2; } /* Button group tweaks */ [data-sl-button-group__button--first][variant="primary"]:has( + [data-sl-button-group__button][variant="default"] ) { /* Move primary button above secondary button in button group */ z-index: 1; } [data-sl-button-group__button--first][variant="primary"] + [data-sl-button-group__button][variant="default"]:not(:hover)::part( base ) { /* Ensure left border color matches primary button's right border color so that no flash of default variant border color shows on hover */ border-left-color: var(--sl-color-primary-600); } } @layer utilities { /* Aesthetically closer to monospaced font: */ .font-monostyle { @apply font-mono; font-variation-settings: var(--font-monostyle-variation); } /* Actually monospaced font */ .font-monospace { @apply font-mono; font-variation-settings: var(--font-monospace-variation); } .truncate { /* Fix tailwind clipping vertical */ overflow: clip visible; /* Fix for if flex item: */ min-width: 0; } .offscreen { position: absolute; left: -100vw; bottom: -100vh; visibility: hidden; width: 0; height: 0; overflow: hidden; } .scrollbar-hidden { scrollbar-width: none; } .scrollbar-hidden::-webkit-scrollbar { display: none; } .fade-out-r { mask-image: linear-gradient( to right, var(--sl-panel-background-color) calc(100% - 1rem), transparent ); } } @layer components { /* Hide asterisk (`*`) required indicator */ sl-input.hide-required-content { --sl-input-required-content-color: transparent; } sl-input.input-font-monostyle::part(input) { @apply font-monostyle; } sl-input[filled]::part(form-control-input) { --sl-input-filled-background-color: theme(colors.slate.50); --sl-input-filled-background-color-hover: var( --sl-input-filled-background-color ); } sl-input[filled]::part(base) { border: 1px solid theme(colors.gray.200); border-radius: var(--sl-input-border-radius-small); } sl-textarea::part(textarea)::placeholder, sl-input::part(input)::placeholder { font-weight: var(--sl-font-weight-light); } sl-drawer::part(header) { --header-spacing: var(--sl-spacing-small); } sl-drawer::part(title) { font-size: var(--font-size-base); font-weight: var(--sl-font-weight-medium); line-height: 1.5; } sl-drawer::part(footer) { border-top: 1px solid var(--sl-panel-border-color); } sl-button.button-card { @apply w-full; } sl-button.button-card::part(base) { @apply min-h-20 justify-between leading-none; } sl-button.button-card::part(label) { @apply flex flex-1 flex-col justify-center gap-2 text-left; } .scrim:before { @apply pointer-events-none absolute -z-10; } .scrim-to-b:before { @apply w-full bg-gradient-to-b from-white; height: var(--btrix-overflow-scrim-width); --tw-gradient-from: var(--btrix-overflow-scroll-scrim-color, white); } } /* Following styles won't work with layers */ .sl-toast-stack { bottom: 0; top: auto; } /* Ensure buttons in shadow dom inherit hover color */ [class^="hover\:text-"]::part(base):hover, [class*=" hover\:text-"]::part(base):hover { color: inherit; } /* Fix scrollbar gutter not actually */ html { overflow: auto; scrollbar-gutter: stable; } body.sl-scroll-lock { scrollbar-gutter: auto !important; } /* Leave document scrollable now for replay.ts embedded dialogs */ /* html:has(body.sl-scroll-lock) { overflow: hidden; } */