actual-css 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/CHANGELOG.md +53 -1
  2. package/README.md +2 -0
  3. package/dist/actual.css +356 -124
  4. package/dist/actual.js +2 -2
  5. package/dist/actual.js.map +13 -13
  6. package/dist/actual.min.css +1 -1
  7. package/docs/README.md +2 -0
  8. package/docs/components.md +2 -2
  9. package/docs/design-notes/browser-support.md +9 -0
  10. package/docs/design-notes/enhancement-contract.md +104 -0
  11. package/docs/design-notes/naming.md +1 -0
  12. package/docs/design-notes/widget-primitives.md +83 -0
  13. package/docs/forms.md +4 -4
  14. package/docs/javascript.md +104 -34
  15. package/docs/patterns.md +89 -0
  16. package/docs/ui.md +22 -30
  17. package/llms.txt +6 -0
  18. package/package.json +14 -8
  19. package/src/css/base.css +0 -4
  20. package/src/css/components/alert.css +88 -2
  21. package/src/css/components/badge.css +30 -7
  22. package/src/css/components/busy.css +1 -0
  23. package/src/css/components/button.css +6 -8
  24. package/src/css/components/flyout.css +0 -1
  25. package/src/css/components/join.css +1 -2
  26. package/src/css/components/scrollspy.css +2 -2
  27. package/src/css/components/spinner.css +4 -4
  28. package/src/css/components/status-bar.css +3 -4
  29. package/src/css/components/tab.css +1 -0
  30. package/src/css/focus.css +37 -0
  31. package/src/css/forms/choice-card.css +1 -2
  32. package/src/css/forms/choice.css +1 -2
  33. package/src/css/forms/control.css +1 -10
  34. package/src/css/forms/index.css +1 -0
  35. package/src/css/forms/native.css +8 -32
  36. package/src/css/forms/range.css +95 -0
  37. package/src/css/forms/switch.css +1 -2
  38. package/src/css/optional/scroller.css +6 -0
  39. package/src/css/theme.css +9 -9
  40. package/src/css/themes/edge.css +3 -27
  41. package/src/css/tokens.css +9 -3
  42. package/src/js/context-menu.js +21 -34
  43. package/src/js/enhance.js +26 -0
  44. package/src/js/flyout.js +12 -19
  45. package/src/js/menu.js +15 -14
  46. package/src/js/scrollspy.js +125 -62
  47. package/src/js/selectors.js +14 -24
  48. package/src/js/status.js +13 -13
  49. package/src/js/surface.js +57 -12
  50. package/src/js/tab.js +10 -13
  51. package/src/js/validation.js +11 -43
@@ -1 +1 @@
1
- *, *::before, *::after { box-sizing: border-box; } html { -webkit-text-size-adjust: 100%; } body { margin: 0; } button, input, textarea, select { font: inherit; } [hidden]:not([hidden="until-found"]) { display: none !important; } @supports not (selector(dialog:modal)) { dialog:not([open]) { display: none; } } :where(img, svg, video) { max-inline-size: 100%; block-size: auto; } @media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto !important; } *, *::before, *::after { animation-duration: 0.01ms !important; animation-delay: 0s !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; transition-delay: 0s !important; } } @supports not (selector(dialog:modal)) { dialog[open]:where(.dialog-fallback) { position: absolute; inset-inline: 0; width: -moz-fit-content; width: fit-content; max-inline-size: calc(100% - 2rem); margin: auto; padding: var(--space-4, 1em); border: var(--border-width, 1px) solid var(--border, currentColor); background: var(--surface-raised, #fff); color: var(--text, inherit); } dialog[open].is-fallback-modal { position: fixed; inset-block: 8vh auto; max-block-size: 84vh; overflow: auto; z-index: 40; box-shadow: 0 0 0 100vmax var(--backdrop-fill, rgb(0 0 0 / 35%)); } dialog[open].is-fallback-modal::before { content: ""; position: fixed; inset: 0; z-index: -1; } } :root { --font-sans: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; --font-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; --line-height: 1.5; --line-height-tight: 1.25; --line-height-relaxed: 1.75; --font-weight: 400; --font-weight-medium: 500; --font-weight-strong: 650; --font-weight-bold: 700; --font-size-xs: 0.8125rem; --font-size-sm: 0.875rem; --font-size-md: 1rem; --font-size-lg: 1.125rem; --gap: 0.75rem; --variant-space: var(--space-4); --space-1: 0.25rem; --space-2: 0.5rem; --space-3: 0.75rem; --space-4: 1rem; --space-5: 1.5rem; --space-6: 2rem; --border-width: 1px; --radius-full: 9999px; --shadow: 0 0.5rem 1.5rem rgb(0 0 0 / 0.08); --shadow-popout: 0 0.25rem 0.75rem rgb(0 0 0 / 0.15); --duration: 150ms; --duration-fast: 100ms; --duration-slow: 200ms; --duration-spin: 0.75s; --duration-shimmer: 1.2s; --ease: ease; --focus-outline: calc(var(--border-width) * 2) solid var(--focus); --focus-outline-offset: 2px; --indicator-offset: 14.65%; --indicator-ring: var(--surface); --backdrop-color: rgb(0 0 0); --backdrop-opacity: 0.45; --backdrop-fill: rgb(0 0 0 / var(--backdrop-opacity)); --bar-height: 0.65rem; --control-size-sm: 2rem; --control-size-md: 2.375rem; --control-size-lg: 2.75rem; --control-size: var(--control-size-md); --control-pad-x: 1em; --control-font-size: var(--font-size-md); --disabled-opacity: 0.65; --soft-bg-mix: 88%; --soft-border-mix: 65%; --soft-hover-alpha: 12%; --icon-chevron-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E"); --icon-check-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'/%3E%3C/svg%3E"); --icon-chevron-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%238a8594' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E"); --viewport-block: 100vh; --viewport-inline: 100vw; --z-sticky: 10; --z-menu: 20; --z-tooltip: 50; --z-status: 60; } @supports (block-size: 100dvh) { :root { --viewport-block: 100dvh; } } @supports (inline-size: 100vi) { :root { --viewport-inline: 100vi; } } @supports (color: color-mix(in oklch, red, white)) { :root { --shadow: 0 0.5rem 1.5rem color-mix(in oklch, var(--shadow-color) 8%, transparent); --shadow-popout: 0 0.25rem 0.75rem color-mix(in oklch, var(--shadow-color) 15%, transparent); --backdrop-fill: color-mix( in oklch, var(--backdrop-color) calc(var(--backdrop-opacity) * 100%), transparent ); } } :root { color-scheme: light dark; } [data-theme="light"] { color-scheme: light; } [data-theme="dark"] { color-scheme: dark; } @supports not (color: light-dark(red, blue)) { :root, [data-theme="light"], [data-theme="dark"] { color-scheme: light; } } :root, [data-theme="light"] { --primary: hsl(268 32% 33%); --primary-fg: hsl(0 0% 98%); --secondary: hsl(16 38% 38%); --secondary-fg: hsl(0 0% 98%); --success: hsl(150 40% 31%); --success-fg: hsl(0 0% 98%); --warning: hsl(36 68% 34%); --warning-fg: hsl(0 0% 98%); --danger: hsl(5 58% 43%); --danger-fg: hsl(0 0% 98%); --neutral: hsl(258 7% 43%); --neutral-fg: hsl(0 0% 98%); --surface: hsl(0 0% 100%); --surface-raised: hsl(0 0% 100%); --surface-subtle: hsl(262 24% 96%); --surface-solid: hsl(261 16% 13%); --text: hsl(261 20% 13%); --text-muted: hsl(259 9% 42%); --text-subtle: hsl(258 7% 57%); --border: hsl(260 15% 88%); --focus: var(--primary); --focus-ring: hsl(268 32% 33% / 0.22); --focus-ring-shadow: 0 0 0 3px var(--focus-ring); --hover-overlay: hsl(260 20% 10% / 0.04); --radius: 0.5rem; --radius-sm: 0.25rem; --radius-lg: 0.75rem; --shadow-color: hsl(260 25% 10%); --heading: var(--text); --selection-bg: var(--primary); --selection-fg: var(--primary-fg); --hgroup-gap: 0.25em; } [data-tone="dark"] { --tone-fg: white; } [data-tone="light"] { --tone-fg: var(--text); } @supports (color: color-mix(in oklch, red, white)) { :root, [data-theme="light"], [data-theme="dark"] { --focus-ring: color-mix(in oklch, var(--focus) 22%, transparent); } } @supports (color: light-dark(red, blue)) { :root, [data-theme="light"] { --primary: light-dark(hsl(268 32% 33%), hsl(268 42% 76%)); --primary-fg: light-dark(hsl(0 0% 98%), hsl(268 30% 12%)); --secondary: light-dark(hsl(16 38% 38%), hsl(18 45% 72%)); --secondary-fg: light-dark(hsl(0 0% 98%), hsl(18 32% 11%)); --success: light-dark(hsl(150 40% 31%), hsl(150 38% 62%)); --success-fg: light-dark(hsl(0 0% 98%), hsl(150 35% 8%)); --warning: light-dark(hsl(36 68% 34%), hsl(40 62% 64%)); --warning-fg: light-dark(hsl(0 0% 98%), hsl(38 35% 10%)); --danger: light-dark(hsl(5 58% 43%), hsl(4 60% 70%)); --danger-fg: light-dark(hsl(0 0% 98%), hsl(4 35% 10%)); --neutral: light-dark(hsl(258 7% 43%), hsl(258 10% 72%)); --neutral-fg: light-dark(hsl(0 0% 98%), hsl(260 18% 10%)); --surface: light-dark(hsl(0 0% 100%), hsl(263 17% 9%)); --surface-raised: light-dark(hsl(0 0% 100%), hsl(263 15% 12%)); --surface-subtle: light-dark(hsl(262 24% 96%), hsl(263 13% 16%)); --surface-solid: light-dark(hsl(261 16% 13%), hsl(0 0% 96%)); --text: light-dark(hsl(261 20% 13%), hsl(260 12% 95%)); --text-muted: light-dark(hsl(259 9% 42%), hsl(259 9% 67%)); --text-subtle: light-dark(hsl(258 7% 57%), hsl(258 7% 54%)); --border: light-dark(hsl(260 15% 88%), hsl(262 12% 24%)); --focus-ring: light-dark(hsl(268 32% 33% / 0.22), hsl(268 42% 76% / 0.28)); --hover-overlay: light-dark(hsl(260 20% 10% / 0.04), hsl(0 0% 100% / 0.06)); --shadow-color: light-dark(hsl(260 25% 10%), hsl(262 40% 2%)); } } @supports (color: color-mix(in oklch, red, white)) and (color: light-dark(red, blue)) { :root, [data-theme="light"] { --focus-ring: light-dark( color-mix(in oklch, var(--focus) 22%, transparent), color-mix(in oklch, var(--focus) 28%, transparent) ); } } @media (forced-colors: active) { :root, [data-theme="light"], [data-theme="dark"] { --focus-outline: calc(var(--border-width) * 2) solid Highlight; --focus-ring-shadow: none; --backdrop-fill: Canvas; } } @media (prefers-contrast: more) { :root, [data-theme="light"], [data-theme="dark"] { --border-width: 2px; --focus-outline-offset: 3px; --focus-ring-shadow: 0 0 0 4px var(--focus-ring); --text-muted: var(--text); --text-subtle: var(--text); } } body { background: var(--surface); color: var(--text); font-family: var(--font-sans); line-height: var(--line-height); } a { color: inherit; text-underline-offset: 0.18em; } a:focus-visible { box-shadow: var(--focus-ring-shadow); } @media (hover: hover) { a:hover { text-decoration-thickness: 0.12em; } } :where(h1, h2, h3, h4, h5, h6) { color: var(--heading, inherit); line-height: var(--line-height-tight); text-wrap: balance; } hgroup { display: grid; gap: var(--hgroup-gap); } hgroup > * { margin-block: 0; } hr { border: 0; border-block-start: var(--border-width) solid var(--border); margin-block: var(--space-6); } code, kbd, samp, pre { font-family: var(--font-mono); } small { font-size: 0.875em; } ::selection { background: var(--selection-bg, var(--primary)); color: var(--selection-fg, var(--primary-fg)); } .primary { --intent: var(--primary); --intent-fg: var(--primary-fg); } .secondary { --intent: var(--secondary); --intent-fg: var(--secondary-fg); } .success { --intent: var(--success); --intent-fg: var(--success-fg); } .warning { --intent: var(--warning); --intent-fg: var(--warning-fg); } .danger { --intent: var(--danger); --intent-fg: var(--danger-fg); } .neutral { --intent: var(--neutral); --intent-fg: var(--neutral-fg); } .container-query { container-type: inline-size; } .stack { display: flex; flex-direction: column; gap: var(--gap); } .stack > * { margin: 0; } .cluster { display: flex; flex-wrap: wrap; align-items: var(--cluster-align, center); justify-content: var(--cluster-justify, flex-start); gap: var(--gap); } .center { box-sizing: content-box; max-inline-size: var(--center-size, 72rem); margin-inline: auto; padding-inline: var(--center-pad, 1rem); } .frame { overflow: hidden; aspect-ratio: var(--frame-ratio, 16 / 9); } .frame > :where(img, video, iframe, canvas, svg) { inline-size: 100%; block-size: 100%; object-fit: cover; } .app-shell { min-block-size: var(--viewport-block); display: flex; flex-direction: column; } .media { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: var(--gap); align-items: start; } .sidebar-layout { display: grid; gap: var(--gap); grid-template-columns: minmax(0, 1fr); } @container (width >= 64rem) { .container-query .sidebar-layout { grid-template-columns: minmax(0, 1fr) var(--sidebar-layout-size, 18rem); align-items: start; } } @supports not (container-type: inline-size) { @media (min-width: 64rem) { .container-query .sidebar-layout { grid-template-columns: minmax(0, 1fr) var(--sidebar-layout-size, 18rem); align-items: start; } } } .grid { display: grid; gap: var(--gap); grid-template-columns: repeat(auto-fit, minmax(min(100%, var(--grid-min, 16rem)), 1fr)); } .grid-2, .grid-3, .grid-4, .grid-6 { display: grid; gap: var(--gap); } .grid-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); } .grid-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); } .grid-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); } .grid-6 { grid-template-columns: repeat(6, minmax(0, 1fr)); } @container (width < 28rem) { .container-query .grid-2, .container-query .grid-3, .container-query .grid-4 { grid-template-columns: 1fr; } .container-query .grid-6 { grid-template-columns: repeat(2, minmax(0, 1fr)); } } @container (28rem <= width < 48rem) { .container-query .grid-3, .container-query .grid-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); } } @container (28rem <= width < 64rem) { .container-query .grid-6 { grid-template-columns: repeat(3, minmax(0, 1fr)); } } @supports not (container-type: inline-size) { @media (max-width: 63.999rem) { .container-query .grid-6 { grid-template-columns: repeat(3, minmax(0, 1fr)); } } @media (max-width: 47.999rem) { .container-query .grid-3, .container-query .grid-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); } } @media (max-width: 27.999rem) { .container-query .grid-2, .container-query .grid-3, .container-query .grid-4 { grid-template-columns: 1fr; } .container-query .grid-6 { grid-template-columns: repeat(2, minmax(0, 1fr)); } } } .solid { --ui-bg: var(--intent, var(--neutral)); --ui-fg: var(--intent-fg, var(--neutral-fg)); --ui-border: transparent; } .soft { --ui-bg: var(--surface-subtle); --ui-border: var(--border); --ui-fg: var(--intent, var(--text)); } .outline { --ui-bg: transparent; --ui-fg: var(--intent, var(--text)); --ui-border: var(--intent, var(--border)); } .sm { --gap: var(--space-2); --variant-space: var(--space-2); --control-size: var(--control-size-sm); --control-font-size: var(--font-size-sm); --variant-font-size: var(--font-size-sm); --variant-icon-size: 1rem; --variant-pad-block: var(--space-3); --variant-compact-size: 1.25rem; --variant-compact-font-size: 0.75rem; } .lg { --gap: var(--space-5); --variant-space: var(--space-5); --control-size: var(--control-size-lg); --control-font-size: var(--font-size-lg); --variant-font-size: var(--font-size-lg); --variant-icon-size: 1.5rem; --variant-pad-block: var(--space-5); --variant-compact-size: 1.875rem; --variant-compact-font-size: var(--font-size-sm); } @supports (color: color-mix(in oklch, red, white)) { .soft { --ui-bg: color-mix(in oklch, var(--surface) var(--soft-bg-mix), var(--intent, var(--neutral))); --ui-border: color-mix( in oklch, var(--surface) var(--soft-border-mix), var(--intent, var(--neutral)) ); } } :is(.btn, a.badge, button.badge):is(.outline, .ghost) { --ui-hover-bg: var(--surface-subtle); } @supports (color: color-mix(in oklch, red, white)) { :is(.btn, a.badge, button.badge):not(:where(.soft, .outline, .ghost, .link)) { --ui-hover-bg: color-mix(in oklch, var(--intent, var(--neutral)) 88%, black); } :is(.btn, a.badge, button.badge):is(.soft) { --ui-hover-bg: color-mix( in oklch, var(--surface) calc(var(--soft-bg-mix) - var(--soft-hover-alpha)), var(--intent, var(--neutral)) ); } :is(.btn, a.badge, button.badge):is(.outline) { --ui-hover-bg: color-mix(in oklch, var(--surface-subtle) 92%, var(--intent, var(--neutral))); } :is(.btn, a.badge, button.badge):is(.ghost) { --ui-hover-bg: color-mix(in oklch, var(--intent, var(--text)) 8%, transparent); } } .prose { --prose-size: 1rem; --prose-line-height: 1.7; --prose-measure: 70ch; --prose-flow: 1em; --prose-heading-line-height: 1.2; --prose-h1: 2rem; --prose-h2: 1.5rem; --prose-h3: 1.25rem; --prose-h4: 1.125rem; max-inline-size: var(--prose-measure); color: var(--text); font-size: var(--prose-size); line-height: var(--prose-line-height); overflow-wrap: break-word; } .prose :where(p, ul, ol, dl, blockquote, pre, table, figure) { margin-block: var(--prose-flow) 0; } .prose :where(h1, h2, h3, h4, h5, h6) { margin-block: 1.5em 0; color: var(--text); font-weight: var(--font-weight-strong); line-height: var(--prose-heading-line-height); } .prose :where(p, li, blockquote) { text-wrap: pretty; } .prose > :first-child { margin-block-start: 0; } .prose h1 { font-size: var(--prose-h1); } .prose h2 { font-size: var(--prose-h2); } .prose h3 { font-size: var(--prose-h3); } .prose h4 { font-size: var(--prose-h4); } .prose a { color: var(--primary); text-decoration-line: underline; text-decoration-thickness: 0.08em; text-underline-offset: 0.18em; } @media (hover: hover) { .prose a:hover { text-decoration-thickness: 0.12em; } @supports (color: color-mix(in oklch, red, white)) { .prose a:hover { color: color-mix(in oklch, var(--primary), var(--text) 15%); } } } .prose :where(ul, ol) { padding-inline-start: 1.5em; } .prose li + li { margin-block-start: 0.35em; } .prose code { padding: 0.15em 0.3em; border-radius: var(--radius-sm); background: var(--surface-subtle); color: var(--text); font-size: 0.875em; } .prose kbd { display: inline-flex; align-items: center; justify-content: center; min-inline-size: 1.75em; min-block-size: 1.6em; padding-inline: 0.45em; border: var(--border-width) solid var(--border); border-block-end-width: calc(var(--border-width) * 2); border-radius: var(--radius-sm); background: var(--surface-raised); color: var(--text); font-family: var(--font-mono); font-size: 0.875em; font-weight: var(--font-weight-medium); line-height: 1; white-space: nowrap; vertical-align: 0.08em; } .prose pre { overflow-x: auto; padding: 1em; border: var(--border-width) solid var(--border); border-radius: var(--radius); background: var(--surface-subtle); } .prose pre code { padding: 0; background: transparent; } .prose blockquote { padding-inline-start: 1em; border-inline-start: var(--border-width) solid var(--border); color: var(--text-muted); } .prose figure { margin-inline: 0; } .prose figcaption { margin-block-start: 0.5em; color: var(--text-muted); font-size: 0.875em; } .prose table { inline-size: 100%; border-collapse: collapse; } .prose th, .prose td { padding: 0.5em; border-block-end: var(--border-width) solid var(--border); text-align: start; } .lead { font-size: 1.125em; line-height: var(--line-height-relaxed); } .measure { max-inline-size: var(--prose-measure, 70ch); } .prose.sm { --prose-size: 0.9375rem; --prose-h1: 1.75rem; --prose-h2: 1.375rem; --prose-h3: 1.125rem; --prose-h4: 1rem; } .prose.lg { --prose-size: 1.125rem; --prose-measure: 72ch; --prose-h1: 2.25rem; --prose-h2: 1.625rem; --prose-h3: 1.375rem; --prose-h4: 1.25rem; } :where(.btn) { --intent: initial; --intent-fg: initial; --ui-bg: initial; --ui-fg: initial; --ui-border: initial; --ui-hover-bg: initial; } .btn { --btn-font-size: var(--control-font-size); --btn-min-size: var(--control-size); --btn-pad-x: var(--control-pad-x, 1em); --btn-bg: var(--ui-bg, var(--btn-default-bg, var(--intent, var(--neutral)))); --btn-fg: var(--ui-fg, var(--btn-default-fg, var(--intent-fg, var(--neutral-fg)))); --btn-border: var(--ui-border, var(--btn-default-border, transparent)); --btn-radius: var(--radius); --btn-focus-color: var(--intent, var(--focus)); --btn-focus-outline-width: calc(var(--border-width) * 2); --btn-hover-bg: var(--ui-hover-bg, var(--btn-bg)); --btn-hover-overlay: var(--hover-overlay, rgb(0 0 0 / 0.08)); position: relative; display: inline-flex; align-items: center; justify-content: center; gap: 0.5em; min-block-size: var(--btn-min-size); padding-block: var(--space-2); padding-block: max(var(--space-1), calc((var(--btn-min-size) - 1lh) / 2)); padding-inline: var(--btn-pad-x); border: var(--border-width) solid var(--btn-border-color, var(--btn-border)); border-block-end-color: var( --btn-border-block-end-color, var(--btn-border-color, var(--btn-border)) ); border-block-end-width: var(--btn-border-block-end-width, var(--border-width)); border-radius: var(--btn-radius); background: var(--btn-bg); color: var(--btn-fg); font: inherit; font-size: var(--btn-font-size); font-weight: var(--font-weight-strong); line-height: 1; text-decoration: none; cursor: pointer; transition: background-color var(--duration), border-color var(--duration), color var(--duration), box-shadow var(--duration), transform var(--duration); } @supports (color: color-mix(in oklch, red, white)) { .btn { --btn-focus-ring-color: color-mix(in oklch, var(--btn-focus-color) 28%, transparent); } } .btn.ghost { --ui-bg: transparent; --ui-fg: var(--intent, var(--text)); --ui-border: transparent; } .btn.outline, .btn.ghost, .btn.link { --btn-hover-overlay: transparent; } @media (hover: hover) { .btn:not(:where(:disabled, [aria-disabled="true"])):hover { background: var(--btn-hover-bg); box-shadow: inset 0 0 0 999px var(--btn-hover-overlay); } } .btn:not(:where(:disabled, [aria-disabled="true"])):active { transform: translateY(1px); } .btn.link { --ui-bg: transparent; --ui-fg: var(--intent, var(--text)); --ui-border: transparent; --btn-radius: var(--radius-sm); --btn-border-block-end-color: transparent; --btn-border-block-end-width: var(--border-width); min-block-size: auto; padding-inline: 0; border-color: transparent; text-decoration: underline; text-underline-offset: 0.18em; } @media (hover: hover) { .btn.link:not(:where(:disabled, [aria-disabled="true"])):hover { background: transparent; color: var(--intent, var(--text)); text-decoration-thickness: 0.12em; } } .btn:focus-visible { outline: var(--btn-focus-outline-width) solid var(--btn-focus-color); outline-offset: var(--focus-outline-offset); box-shadow: 0 0 0 3px var(--btn-focus-ring-color, var(--focus-ring)); } .btn.link:focus-visible { outline-color: currentColor; outline-offset: 0.2em; } .btn:disabled { cursor: not-allowed; opacity: var(--disabled-opacity); } a.btn[aria-disabled="true"] { cursor: not-allowed; opacity: var(--disabled-opacity); pointer-events: none; } .btn[aria-busy="true"]:not(:disabled) { cursor: progress; } .btn[aria-busy="true"] > .spinner { --spinner-size: 1em; --spinner-width: 0.15em; } .btn:is([aria-pressed="true"], [aria-current]:not([aria-current="false"])):not(.link) { --btn-bg: var(--intent, var(--primary)); --btn-fg: var(--intent-fg, var(--primary-fg)); --btn-border: var(--intent, var(--primary)); --ui-hover-bg: var(--btn-bg); } @media (forced-colors: active) { .btn { border-color: ButtonText; background: ButtonFace; color: ButtonText; box-shadow: none; } .btn.link { border-color: transparent; background: Canvas; color: LinkText; } .btn:is([aria-pressed="true"], [aria-current]:not([aria-current="false"])):not(.link) { border-color: Highlight; background: Highlight; color: HighlightText; forced-color-adjust: none; } @media (hover: hover) { .btn:hover:not(:where(:disabled, [aria-disabled="true"], .link)) { outline: var(--border-width) solid ButtonText; outline-offset: 2px; } } .btn:disabled, a.btn[aria-disabled="true"] { border-color: GrayText; background: Canvas; color: GrayText; forced-color-adjust: auto; } } :where(.badge) { --intent: initial; --intent-fg: initial; --ui-bg: initial; --ui-fg: initial; --ui-border: initial; --ui-hover-bg: initial; } .badge { --badge-size: var(--variant-compact-size, 1.5rem); --badge-pad-x: 0.55em; --badge-font-size: var(--variant-compact-font-size, 0.8125rem); --badge-dot-size: 0.5rem; --badge-bg: var(--ui-bg, var(--intent, var(--neutral))); --badge-fg: var(--ui-fg, var(--intent-fg, var(--neutral-fg))); --badge-border: var(--ui-border, transparent); --badge-radius: 999px; display: inline-flex; align-items: center; justify-content: center; gap: 0.35em; min-block-size: var(--badge-size); padding-inline: var(--badge-pad-x); border: var(--border-width) solid var(--badge-border); border-radius: var(--badge-radius); background: var(--badge-bg); color: var(--badge-fg); font-size: var(--badge-font-size); font-weight: var(--font-weight-strong); line-height: 1; text-decoration: none; white-space: nowrap; transition: background-color var(--duration), border-color var(--duration), color var(--duration), box-shadow var(--duration); } .badge:empty { --badge-size: var(--badge-dot-size); padding: 0; border: 0; inline-size: var(--badge-size); block-size: var(--badge-size); } .badge > button { display: inline-grid; place-items: center; flex: 0 0 auto; min-inline-size: 1.5rem; min-block-size: 1.5rem; margin-block: -0.25rem; margin-inline-start: -0.15em; margin-inline-end: -0.45em; padding: 0.25rem; border: 0; border-radius: var(--radius-full); background: transparent; color: inherit; font: inherit; line-height: 1; cursor: pointer; } @media (hover: hover) { .badge > button:not(:disabled):hover { background: var(--hover-overlay); } } @media (hover: hover) { :where(a.badge, button.badge):not(:where(:disabled, [aria-disabled="true"])):hover { background: var(--ui-hover-bg, var(--badge-bg)); } :where(a.badge, button.badge):not(:where(:disabled, [aria-disabled="true"], .outline)):hover { box-shadow: inset 0 0 0 999px var(--hover-overlay); } } button.badge { cursor: pointer; font: inherit; } button.badge:disabled, .badge[aria-disabled="true"] { opacity: var(--disabled-opacity); cursor: not-allowed; } a.badge[aria-disabled="true"] { pointer-events: none; } @media (forced-colors: active) { .badge { border-color: ButtonText; background: Canvas; color: CanvasText; box-shadow: none; } .badge:empty { background: ButtonText; } @media (hover: hover) { :where(a.badge, button.badge):hover:not(:where(:disabled, [aria-disabled="true"])) { outline: var(--border-width) solid ButtonText; outline-offset: 2px; } .badge > button:not(:disabled):hover { outline: var(--border-width) solid currentColor; outline-offset: 1px; } } button.badge:disabled, .badge[aria-disabled="true"] { border-color: GrayText; background: Canvas; color: GrayText; } } :where(.alert) { --intent: initial; --intent-fg: initial; --ui-bg: initial; --ui-fg: initial; --ui-border: initial; --ui-hover-bg: initial; } .alert { --alert-pad-block: var(--variant-pad-block, var(--space-4)); --alert-pad-inline: var(--space-4); --alert-font-size: var(--variant-font-size, var(--font-size-md)); --alert-icon-size: var(--variant-icon-size, 1.25rem); --alert-bg: var(--surface-subtle); --alert-border: var(--border); --ui-bg: var(--alert-bg); --ui-border: var(--alert-border); --ui-fg: var(--intent, var(--text)); padding-block: var(--alert-pad-block); padding-inline: var(--alert-pad-inline); background: var(--ui-bg, transparent); color: var(--ui-fg, var(--text)); border: var(--border-width) solid var(--ui-border, var(--border)); border-inline-start-color: var( --alert-border-inline-start-color, var(--ui-border, var(--border)) ); border-inline-start-width: var(--alert-border-inline-start-width, var(--border-width)); border-radius: var(--radius-lg); font-size: var(--alert-font-size); } .alert > * { min-inline-size: 0; } .alert > :first-child { margin-block-start: 0; } .alert > :last-child { margin-block-end: 0; } .alert.solid { --ui-bg: var(--intent, var(--neutral)); --ui-fg: var(--intent-fg, var(--neutral-fg)); --ui-border: transparent; } .alert.outline { --ui-bg: transparent; --ui-fg: var(--intent, var(--text)); --ui-border: var(--intent, var(--border)); } @supports (color: color-mix(in oklch, red, white)) { .alert:where(:not(.solid, .outline)) { --ui-bg: color-mix(in oklch, var(--surface) var(--soft-bg-mix), var(--intent, var(--neutral))); --ui-border: color-mix( in oklch, var(--surface) var(--soft-border-mix), var(--intent, var(--neutral)) ); } } .alert > :first-child[aria-hidden="true"] { display: inline-block; flex: none; inline-size: var(--alert-icon-size); block-size: var(--alert-icon-size); font-size: var(--alert-icon-size); line-height: 1; vertical-align: -0.125em; } @supports selector(.alert:has(> *)) { .alert:has(> :first-child[aria-hidden="true"]) { display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: var(--items-align, start); column-gap: var(--space-3); } .alert:has(> :first-child[aria-hidden="true"]) > :first-child { grid-column: 1; grid-row: 1 / -1; display: inline-grid; place-items: center; inline-size: var(--alert-icon-size); block-size: var(--alert-icon-size); margin-block-start: 0.125em; font-size: var(--alert-icon-size); line-height: 1; } .alert:has(> :first-child[aria-hidden="true"]) > :first-child:is(svg, i) { inline-size: var(--alert-icon-size); block-size: var(--alert-icon-size); } .alert:has(> :first-child[aria-hidden="true"]) > :not(:first-child) { grid-column: 2; } } .alert :where(a:not(.btn)) { color: inherit; font-weight: var(--font-weight-strong); } .actions { --gap: var(--space-2); display: flex; flex-wrap: wrap; align-items: center; gap: var(--gap); margin: 0; padding: 0; list-style: none; } .actions > li { margin: 0; } :where(.card) { --intent: initial; --intent-fg: initial; --ui-bg: initial; --ui-fg: initial; --ui-border: initial; --ui-hover-bg: initial; } .card { --card-pad: var(--space-4); --card-radius: var(--radius-lg); --card-max-inline-size: none; max-inline-size: var(--card-max-inline-size); padding: var(--card-pad); background: var(--ui-bg, var(--surface)); color: var(--ui-fg, var(--text)); border: var(--border-width) solid var(--ui-border, var(--border)); border-radius: var(--card-radius); } .card > * { min-inline-size: 0; } .card > :where(header, footer) { display: flex; flex-wrap: wrap; align-items: var(--items-align, center); justify-content: space-between; gap: var(--space-3); min-inline-size: 0; } .card > :where(header, footer) > * { min-inline-size: 0; margin-block: 0; } .card > header { align-items: var(--items-align, flex-start); } .card > :first-child { margin-block-start: 0; } .card > :last-child { margin-block-end: 0; } .card.raised { box-shadow: var(--shadow); } .card.subtle { background: var(--surface-subtle); } .card.inverted { background: var(--surface-solid); color: var(--surface); border-color: transparent; --heading: var(--surface); --busy-overlay-bg: var(--surface-solid); } .card.compact { --card-pad: var(--space-2); } .card > .bleed { margin-inline: calc(var(--card-pad) * -1); max-inline-size: none; } .card > .bleed:first-child { margin-block-start: calc(var(--card-pad) * -1); border-start-start-radius: inherit; border-start-end-radius: inherit; } .card > .bleed:last-child { margin-block-end: calc(var(--card-pad) * -1); border-end-start-radius: inherit; border-end-end-radius: inherit; } .card > :where(img, picture, video, canvas, svg).bleed { display: block; inline-size: calc(100% + var(--card-pad) * 2); max-inline-size: none; } .card > picture.bleed { overflow: hidden; } .card > picture.bleed > img { display: block; inline-size: 100%; block-size: auto; } .card > :where(header, footer, figure).bleed { padding: var(--card-pad); } @media (forced-colors: active) { .card { border-color: ButtonText; background: Canvas; color: CanvasText; } .card.raised { box-shadow: none; } .card.inverted { --heading: CanvasText; border-color: ButtonText; background: Canvas; color: CanvasText; } } .surface-backdrop { position: fixed; inset: 0; z-index: calc(var(--z-menu) - 1); background: var(--backdrop-fill); opacity: 1; transition: opacity var(--duration) var(--ease, ease); } .surface-backdrop[hidden] { display: none; opacity: 0; } @starting-style { .surface-backdrop:not([hidden]) { opacity: 0; } } @supports (transition-behavior: allow-discrete) { .surface-backdrop { transition: opacity var(--duration) var(--ease, ease), display var(--duration) allow-discrete; } } @media (forced-colors: active) { .surface-backdrop { background: Canvas; } } dialog.modal { --modal-size: 32rem; max-inline-size: min(100% - 2rem, var(--modal-size)); max-block-size: calc(var(--viewport-block) - 2rem); border: var(--border-width) solid var(--border); border-radius: var(--radius-lg); background: var(--surface-raised); color: var(--text); box-shadow: var(--shadow); padding: 0; overflow: visible; opacity: 0; transform: translateY(0.35rem) scale(0.98); transition: opacity var(--duration), transform var(--duration); } dialog.modal > form, dialog.modal > .stack { display: grid; gap: var(--space-4); max-block-size: calc(var(--viewport-block) - 2rem); overflow: auto; overscroll-behavior: contain; padding: var(--space-4); } dialog.modal.scrollable > form, dialog.modal.scrollable > .stack { grid-template-rows: auto minmax(0, 1fr) auto; overflow: hidden; } dialog.modal.scrollable > form > :not(header, footer), dialog.modal.scrollable > .stack > :not(header, footer) { min-block-size: 0; overflow: auto; overscroll-behavior: contain; } dialog.modal header > :first-child, dialog.modal footer > :first-child { margin-block-start: 0; } dialog.modal header > :last-child, dialog.modal footer > :last-child { margin-block-end: 0; } dialog.modal footer { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: var(--gap); } dialog.modal[open] { opacity: 1; transform: none; } @starting-style { dialog.modal[open] { opacity: 0; transform: translateY(0.35rem) scale(0.98); } } dialog.modal::backdrop { background: var(--backdrop-fill); opacity: 0; transition: opacity var(--duration); } @supports (transition-behavior: allow-discrete) { dialog.modal { transition: opacity var(--duration), transform var(--duration), overlay var(--duration) allow-discrete, display var(--duration) allow-discrete; } dialog.modal::backdrop { transition: opacity var(--duration), overlay var(--duration) allow-discrete, display var(--duration) allow-discrete; } } dialog.modal[open]::backdrop { opacity: 1; } html.has-modal-open { overflow: hidden; } html.has-modal-open.had-scrollbar { scrollbar-gutter: stable; } @starting-style { dialog.modal[open]::backdrop { opacity: 0; } } @media (prefers-reduced-motion: no-preference) { dialog.modal.is-static { animation: actual-modal-static 180ms var(--ease); } ::view-transition-group(actual-dialog) { animation-duration: var(--duration); animation-timing-function: var(--ease); } } @keyframes actual-modal-static { 0%, 100% { transform: none; } 35% { transform: translateX(-0.35rem); } 70% { transform: translateX(0.35rem); } } @media (forced-colors: active) { dialog.modal { border-color: ButtonText; background: Canvas; color: CanvasText; box-shadow: none; } dialog.modal::backdrop { background: Canvas; } } dialog.drawer { --drawer-size: 20rem; --drawer-pad: var(--space-4); --drawer-closed-translate: -100%; inline-size: min(calc(var(--viewport-inline) * 0.9), var(--drawer-size)); block-size: var(--viewport-block); max-inline-size: none; max-block-size: var(--viewport-block); margin: 0; padding: var(--drawer-pad); border: 0; border-inline-end: var(--border-width) solid var(--border); border-radius: 0; background: var(--surface-raised); color: var(--text); box-shadow: var(--shadow); opacity: 0; transform: translateX(var(--drawer-closed-translate)); transition: opacity var(--duration-slow), transform var(--duration-slow); } dialog.drawer[open] { display: grid; grid-template-rows: auto minmax(0, 1fr) auto; gap: var(--space-4); opacity: 1; transform: translateX(0); } dialog.drawer::backdrop { background: var(--backdrop-fill); opacity: 0; transition: opacity var(--duration-slow); } dialog.drawer[data-side="end"] { --drawer-closed-translate: 100%; margin-inline-start: auto; margin-inline-end: 0; border-inline-end: 0; border-inline-start: var(--border-width) solid var(--border); } dialog.drawer[open]::backdrop { opacity: 1; } @starting-style { dialog.drawer[open] { opacity: 0; transform: translateX(var(--drawer-closed-translate)); } dialog.drawer[open]::backdrop { opacity: 0; } } dialog.drawer nav { min-block-size: 0; overflow-y: auto; } @supports (transition-behavior: allow-discrete) { dialog.drawer { transition: opacity var(--duration-slow), transform var(--duration-slow), overlay var(--duration-slow) allow-discrete, display var(--duration-slow) allow-discrete; } dialog.drawer::backdrop { transition: opacity var(--duration-slow), overlay var(--duration-slow) allow-discrete, display var(--duration-slow) allow-discrete; } } [dir="rtl"] dialog.drawer { --drawer-closed-translate: 100%; } [dir="rtl"] dialog.drawer[data-side="end"] { --drawer-closed-translate: -100%; } @media (forced-colors: active) { dialog.drawer { border-inline-end-color: ButtonText; background: Canvas; color: CanvasText; box-shadow: none; } dialog.drawer[data-side="end"] { border-inline-start-color: ButtonText; } dialog.drawer::backdrop { background: Canvas; } } .flyout-trigger { position: relative; display: inline-block; } .flyout-trigger.stretch { display: block; inline-size: 100%; } .flyout-trigger.stretch > [aria-haspopup="menu"] { inline-size: 100%; } .flyout { z-index: var(--z-menu); position: absolute; inset-block-start: calc(100% + var(--space-1)); inset-inline-start: 0; display: grid; gap: var(--space-1); inline-size: var(--flyout-inline-size, max-content); min-inline-size: min( var(--flyout-trigger-width, 0px), min(var(--flyout-max-inline-size, 20rem), calc(var(--viewport-inline) - var(--space-6))) ); max-inline-size: min( var(--flyout-max-inline-size, 20rem), calc(var(--viewport-inline) - var(--space-6)) ); max-block-size: min(24rem, var(--available-height, calc(var(--viewport-block) - var(--space-6)))); overflow: auto; margin: 0; padding: var(--space-1); border: var(--border-width) solid var(--border); border-radius: var(--radius); background: var(--surface-raised); box-shadow: var(--shadow-popout); list-style: none; opacity: 1; scale: 1; transition: opacity var(--duration-fast, var(--duration)) var(--ease, ease), scale var(--duration-fast, var(--duration)) var(--ease, ease), translate var(--duration-fast, var(--duration)) var(--ease, ease); } .flyout.is-open:not(.is-sheet) { inset: auto; } @starting-style { .flyout.is-open { opacity: 0; scale: 0.98; } } .flyout.is-sheet { position: fixed; inset-inline: 0; inset-block-start: auto; inset-block-end: 0; inline-size: auto; min-inline-size: 0; max-inline-size: none; max-block-size: min(calc(var(--viewport-block) * 0.75), 32rem); overflow: auto; grid-template-columns: 1fr; padding: max(var(--space-3), env(safe-area-inset-top)) var(--space-3) max(var(--space-3), env(safe-area-inset-bottom)); border-end-start-radius: 0; border-end-end-radius: 0; } .flyout[hidden] { display: none; opacity: 0; scale: 0.98; } .flyout.is-sheet[hidden] { scale: 1; translate: 0 var(--space-3); } @starting-style { .flyout.is-sheet.is-open { scale: 1; translate: 0 var(--space-3); } } @supports (transition-behavior: allow-discrete) { .flyout { transition: opacity var(--duration-fast, var(--duration)) var(--ease, ease), scale var(--duration-fast, var(--duration)) var(--ease, ease), translate var(--duration-fast, var(--duration)) var(--ease, ease), display var(--duration-fast, var(--duration)) allow-discrete; } } .flyout > li { margin: 0; } .flyout > :where(section, footer) { min-inline-size: 0; padding: var(--space-2); } .flyout > section > :where(h1, h2, h3, h4, h5, h6) { margin: 0; color: var(--text-muted); font-size: var(--font-size-xs); font-weight: var(--font-weight-strong); } .flyout > section > ul { display: grid; gap: var(--space-1); margin: var(--space-1) 0 0; padding: 0; list-style: none; } .flyout > section > ul > li { margin: 0; } :is(.flyout, .flyout :where(li)) > :where(button, a, [role="menuitem"]) { display: flex; align-items: center; justify-content: flex-start; gap: var(--space-2); inline-size: 100%; min-block-size: var(--control-size); padding-inline: var(--space-2); border: 0; border-radius: var(--radius-sm); background: none; color: var(--text); font: inherit; font-weight: var(--font-weight); text-decoration: none; text-align: start; white-space: nowrap; cursor: pointer; } :is(.flyout.is-sheet, .flyout.is-sheet :where(li)) > :where(button, a, [role="menuitem"]) { min-block-size: var(--control-size-lg); } :is(.flyout, .flyout :where(li)) > :where(button, a, [role="menuitem"]):focus-visible { background: var(--surface-subtle); outline: var(--focus-outline); outline-offset: var(--focus-outline-offset); box-shadow: var(--focus-ring-shadow); } :is(.flyout, .flyout :where(li)) > :where(button, a, [role="menuitem"]):is(:disabled, [aria-disabled="true"]) { cursor: not-allowed; opacity: var(--disabled-opacity); } :is(.flyout, .flyout :where(li)) > :where(a, [role="menuitem"])[aria-disabled="true"] { pointer-events: none; } @media (hover: hover) { :is(.flyout, .flyout :where(li)) > :where(button, a, [role="menuitem"]):hover:not( :where(:focus-visible, :disabled, [aria-disabled="true"]) ) { background: var(--surface-subtle); outline: none; } } .flyout > hr, .flyout > li > hr { inline-size: 100%; margin: 0; margin-block: var(--space-1); border: 0; border-block-start: var(--border-width) solid var(--border); } @media (forced-colors: active) { .flyout { border-color: ButtonText; background: Canvas; color: CanvasText; box-shadow: none; } :is(.flyout, .flyout :where(li)) > :where(button, a, [role="menuitem"]):focus-visible { background: Canvas; color: CanvasText; } @media (hover: hover) { :is(.flyout, .flyout :where(li)) > :where(button, a, [role="menuitem"]):hover:not(:where(:disabled, [aria-disabled="true"])) { outline: var(--border-width) solid ButtonText; outline-offset: -1px; background: Canvas; color: CanvasText; } } } .tooltip { --tooltip-bg: var(--surface-solid); --tooltip-fg: var(--surface); --tooltip-arrow-size: 5px; position: fixed; z-index: var(--z-tooltip); max-inline-size: min(24rem, calc(var(--viewport-inline) - 2rem)); padding: 0.25em 0.6em; border-radius: var(--radius-sm); background: var(--tooltip-bg); color: var(--tooltip-fg); font-size: var(--font-size-xs); line-height: var(--line-height-tight); overflow-wrap: anywhere; pointer-events: auto; user-select: none; opacity: 1; scale: 1; transition: opacity var(--duration-fast, var(--duration)) var(--ease, ease), scale var(--duration-fast, var(--duration)) var(--ease, ease); } .tooltip[hidden] { display: none; opacity: 0; scale: 0.96; } @starting-style { .tooltip:not([hidden]) { opacity: 0; scale: 0.96; } } @supports (transition-behavior: allow-discrete) { .tooltip { transition: opacity var(--duration-fast, var(--duration)) var(--ease, ease), scale var(--duration-fast, var(--duration)) var(--ease, ease), display var(--duration-fast, var(--duration)) allow-discrete; } } .tooltip::before { content: ""; position: absolute; inline-size: calc(var(--tooltip-arrow-size) * 2); block-size: var(--tooltip-arrow-size); background: var(--tooltip-bg); } .tooltip[data-placement^="top"]::before { bottom: calc(-0.98 * var(--tooltip-arrow-size)); left: var(--arrow-x, 50%); translate: -50% 0; clip-path: polygon(50% 100%, 0 0, 100% 0); } .tooltip[data-placement^="bottom"]::before { top: calc(-0.98 * var(--tooltip-arrow-size)); left: var(--arrow-x, 50%); translate: -50% 0; clip-path: polygon(50% 0, 0 100%, 100% 100%); } .tooltip[data-placement^="left"]::before { right: calc(-0.98 * var(--tooltip-arrow-size)); top: var(--arrow-y, 50%); inline-size: var(--tooltip-arrow-size); block-size: calc(var(--tooltip-arrow-size) * 2); translate: 0 -50%; clip-path: polygon(100% 50%, 0 0, 0 100%); } .tooltip[data-placement^="right"]::before { left: calc(-0.98 * var(--tooltip-arrow-size)); top: var(--arrow-y, 50%); inline-size: var(--tooltip-arrow-size); block-size: calc(var(--tooltip-arrow-size) * 2); translate: 0 -50%; clip-path: polygon(0 50%, 100% 0, 100% 100%); } @media (forced-colors: active) { .tooltip { --tooltip-bg: Canvas; --tooltip-fg: CanvasText; border: var(--border-width) solid ButtonText; } .tooltip::before { display: none; } } .accordion { --accordion-radius: var(--radius); border: var(--border-width) solid var(--border); border-radius: var(--accordion-radius); background: var(--surface-raised); } .accordion > details + details { border-block-start: var(--border-width) solid var(--border); } .accordion summary { display: flex; align-items: center; gap: var(--space-3); cursor: pointer; list-style: none; padding: var(--space-4); color: var(--text); font-weight: var(--font-weight-bold); } .accordion summary::-webkit-details-marker { display: none; } .accordion summary::after { content: ""; flex: 0 0 auto; margin-inline-start: auto; inline-size: 1rem; block-size: 1rem; background-color: var(--text-muted); -webkit-mask-image: var(--icon-chevron-mask); mask-image: var(--icon-chevron-mask); -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat; -webkit-mask-size: contain; mask-size: contain; -webkit-mask-position: center; mask-position: center; transition: transform var(--duration); } .accordion details[open] summary::after { transform: rotate(180deg); } .accordion details > summary + * { padding-block: 0 var(--space-4); padding-inline: var(--space-4); color: var(--text-muted); margin-block: 0; } .accordion details[open] > summary + * { padding-block-start: var(--space-1); } .accordion details > summary + * > :first-child { margin-block-start: 0; } .accordion details > summary + ul, .accordion details > summary + ol { margin: 0; padding-inline-start: 2rem; } @media (forced-colors: active) { .accordion { border-color: ButtonText; background: Canvas; color: CanvasText; } .accordion > details + details { border-block-start-color: ButtonText; } .accordion summary { color: CanvasText; } .accordion summary::after { background-color: ButtonText; forced-color-adjust: none; } } :where(.spinner) { --intent: initial; --intent-fg: initial; --ui-bg: initial; --ui-fg: initial; --ui-border: initial; --ui-hover-bg: initial; } .spinner { --spinner-size: 1.5rem; --spinner-width: 2px; --spinner-track: currentColor; --spinner-value: transparent; color: var(--intent, currentColor); display: inline-block; flex-shrink: 0; inline-size: var(--spinner-size); block-size: var(--spinner-size); border: var(--spinner-width) solid var(--spinner-track); border-inline-end-color: var(--spinner-value); border-radius: var(--radius-full); opacity: 0.85; animation: actual-spin var(--duration-spin) linear infinite; vertical-align: text-bottom; } @supports (color: color-mix(in oklch, red, white)) { .spinner { --spinner-track: color-mix(in oklch, currentColor, transparent 70%); --spinner-value: currentColor; opacity: 1; } } .spinner.sm { --spinner-size: 1rem; } .spinner.lg { --spinner-size: 3rem; --spinner-width: 3px; } @keyframes actual-spin { to { transform: rotate(360deg); } } .skeleton { --skeleton-size: 1rem; --skeleton-width: 100%; --skeleton-radius: var(--radius); --skeleton-track: var(--surface-subtle); --skeleton-highlight: var(--surface-raised); display: block; inline-size: var(--skeleton-width); max-inline-size: 100%; block-size: var(--skeleton-size); border-radius: var(--skeleton-radius); background: linear-gradient(90deg, var(--skeleton-track), var(--skeleton-highlight), var(--skeleton-track)) 0 0 / 200% 100%; } @media (prefers-reduced-motion: no-preference) { .skeleton { animation: actual-skeleton var(--duration-shimmer) ease-in-out infinite; } } .skeleton[data-shape="text"] { --skeleton-size: 0.85rem; --skeleton-width: 32rem; } .skeleton[data-shape="title"] { --skeleton-size: 1.4rem; --skeleton-width: 18rem; } .skeleton[data-shape="avatar"] { --skeleton-size: var(--avatar-size, 2.25rem); --skeleton-width: var(--skeleton-size); --skeleton-radius: var(--radius-full); flex: 0 0 auto; } .skeleton[data-shape="box"] { --skeleton-size: 8rem; } @media (forced-colors: active) { .skeleton { border: var(--border-width) solid ButtonText; background: GrayText; } } @keyframes actual-skeleton { from { background-position: 200% 0; } to { background-position: -200% 0; } } [aria-busy] > .spinner:last-child { display: none; } [aria-busy="true"] > .spinner:last-child { display: inline-block; } @supports selector([aria-busy="true"]:has(> .spinner:last-child)) { [aria-busy="true"]:not(.btn):has(> .spinner:last-child) { position: relative; } [aria-busy="true"]:not(.btn):has(> .spinner:last-child)::before { content: ""; position: absolute; inset: 0; z-index: 1; border-radius: inherit; background: var(--busy-overlay-bg, var(--surface)); } [aria-busy="true"]:not(.btn) > .spinner:last-child { position: absolute; inset: 0; z-index: 2; margin: auto; display: block; } } @supports (selector([aria-busy="true"]:has(> .spinner:last-child))) and (color: color-mix(in oklch, red, white)) { [aria-busy="true"]:not(.btn):has(> .spinner:last-child)::before { background: color-mix(in oklch, var(--busy-overlay-bg, var(--surface)), transparent 20%); } } :where(.progress) { --intent: initial; --intent-fg: initial; --ui-bg: initial; --ui-fg: initial; --ui-border: initial; --ui-hover-bg: initial; } .progress { --progress-track: var(--surface-subtle); --progress-value: var(--intent, var(--primary)); } .progress { appearance: none; -webkit-appearance: none; display: block; inline-size: 100%; block-size: var(--bar-height); overflow: hidden; border: 0; border-radius: var(--radius-full); background: var(--progress-track); } .progress::-webkit-progress-bar { block-size: var(--bar-height); border-radius: var(--radius-full); background: var(--progress-track); } .progress::-webkit-progress-value { block-size: var(--bar-height); border-radius: var(--radius-full); background: var(--progress-value); } .progress::-moz-progress-bar { block-size: var(--bar-height); border-radius: var(--radius-full); background: var(--progress-value); } .progress:indeterminate { background: linear-gradient(to right, var(--progress-value) 30%, var(--progress-track) 30%) top left / 150% 150% no-repeat, var(--progress-track); } .progress:indeterminate::-webkit-progress-bar { background: transparent; } .progress:indeterminate::-webkit-progress-value { background: transparent; } .progress:indeterminate::-moz-progress-bar { background: transparent; } @media (prefers-reduced-motion: no-preference) { .progress:indeterminate { animation: actual-progress-indeterminate var(--duration-shimmer) ease-in-out infinite; } :where([dir="rtl"] .progress:indeterminate) { animation-direction: reverse; } } @keyframes actual-progress-indeterminate { 0% { background-position: 200% 0; } 20% { background-position: 100% 0; } 80% { background-position: -100% 0; } 100% { background-position: -200% 0; } } @media (forced-colors: active) { .progress { border: var(--border-width) solid ButtonText; background: Canvas; } .progress::-webkit-progress-bar { background: Canvas; } .progress::-webkit-progress-value { background: Highlight; forced-color-adjust: none; } .progress::-moz-progress-bar { background: Highlight; forced-color-adjust: none; } .progress:indeterminate { background: Canvas; } } :where(.status-bar) { --intent: initial; --intent-fg: initial; --ui-bg: initial; --ui-fg: initial; --ui-border: initial; --ui-hover-bg: initial; } .status-bar { --status-bg: var(--intent, var(--text)); --status-fg: var(--intent-fg, var(--surface)); position: fixed; inset-block-end: var(--space-4); inset-inline: var(--space-4); z-index: var(--z-status, 60); display: inline-flex; align-items: center; justify-content: center; gap: var(--space-2); inline-size: fit-content; max-inline-size: min(calc(100vw - var(--space-6)), 32rem); margin-inline: auto; overflow-wrap: anywhere; padding-block: var(--space-2); padding-inline: var(--space-3); border-radius: var(--radius-full); background: var(--status-bg); color: var(--status-fg); box-shadow: var(--shadow-popout); opacity: 1; scale: 1; translate: 0 0; pointer-events: none; transition: opacity var(--duration-slow) var(--ease, ease), scale var(--duration-slow) var(--ease, ease), translate var(--duration-slow) var(--ease, ease); } .status-bar:empty { opacity: 0; scale: 0.96; translate: 0 var(--space-2); pointer-events: none; } @media (forced-colors: active) { .status-bar { border: var(--border-width) solid ButtonText; box-shadow: none; } } :where(.avatar) { --intent: initial; --intent-fg: initial; --ui-bg: initial; --ui-fg: initial; --ui-border: initial; --ui-hover-bg: initial; } .avatar { --avatar-size: var(--avatar-stack-size, 2.25rem); --avatar-radius: var(--radius-full); --avatar-font-size: var(--avatar-stack-font-size, var(--font-size-sm)); --avatar-bg: var(--intent, var(--surface-subtle)); --avatar-fg: var(--intent-fg, var(--tone-fg, var(--text-muted))); position: relative; display: inline-grid; place-items: center; inline-size: var(--avatar-size); block-size: var(--avatar-size); overflow: visible; padding: 0; border: 0; border-radius: var(--avatar-radius); background: var(--avatar-bg); color: var(--avatar-fg); font: inherit; font-size: var(--avatar-font-size); font-weight: var(--font-weight-strong); line-height: 1; text-decoration: none; vertical-align: middle; user-select: none; transition: box-shadow var(--duration), opacity var(--duration), transform var(--duration); } @media (forced-colors: active) { .avatar { border: var(--border-width) solid CanvasText; } :where(a.avatar, button.avatar)::after { display: none; } } .avatar > :first-child:not(:where(img, picture, .badge)) { display: inline-grid; place-items: center; inline-size: 100%; block-size: 100%; overflow: hidden; border-radius: inherit; } .avatar > img, .avatar > picture { display: block; inline-size: 100%; block-size: 100%; overflow: hidden; border-radius: inherit; } .avatar > img, .avatar > picture > img { inline-size: 100%; block-size: 100%; object-fit: cover; border-radius: inherit; } .avatar > picture > img { display: block; } button.avatar { appearance: none; cursor: pointer; } :where(a.avatar, button.avatar)::after { content: ""; position: absolute; inset: 0; border-radius: inherit; background: var(--hover-overlay); opacity: 0; pointer-events: none; transition: opacity var(--duration); } @media (hover: hover) { :where(a.avatar, button.avatar):not(:where(:disabled, [aria-disabled="true"])):hover::after { opacity: 1; } } :where(a.avatar, button.avatar):not(:where(:disabled, [aria-disabled="true"])):active { transform: translateY(1px); } button.avatar:disabled, a.avatar[aria-disabled="true"] { cursor: not-allowed; opacity: var(--disabled-opacity); } a.avatar[aria-disabled="true"] { pointer-events: none; } .avatar.sm { --avatar-stack-size: 1.75rem; --avatar-stack-font-size: var(--font-size-xs); } .avatar.lg { --avatar-stack-size: 3rem; --avatar-stack-font-size: var(--font-size-lg); } .avatar > .badge:empty { --avatar-status-translate-x: 50%; position: absolute; inset-block-end: var(--indicator-offset); inset-inline-end: var(--indicator-offset); z-index: 1; box-shadow: 0 0 0 2px var(--indicator-ring); transform: translate(var(--avatar-status-translate-x), 50%); } .avatar:dir(rtl) > .badge:empty { --avatar-status-translate-x: -50%; } .avatar-stack { --avatar-stack-overlap: calc(var(--avatar-stack-size, 2.25rem) / -4); --avatar-stack-ring: 2px; display: inline-flex; align-items: center; } .avatar-stack.sm { --avatar-stack-size: 1.75rem; --avatar-stack-font-size: var(--font-size-xs); } .avatar-stack.lg { --avatar-stack-size: 3rem; --avatar-stack-font-size: var(--font-size-lg); } @supports selector(:has(> .avatar)) { .avatar-stack:has(> .avatar.sm) { --avatar-stack-size: 1.75rem; --avatar-stack-font-size: var(--font-size-xs); } .avatar-stack:has(> .avatar.lg) { --avatar-stack-size: 3rem; --avatar-stack-font-size: var(--font-size-lg); } } .avatar-stack > .avatar { box-shadow: 0 0 0 var(--avatar-stack-ring) var(--surface); } .avatar-stack > .avatar + .avatar { margin-inline-start: var(--avatar-stack-overlap); } .avatar-stack > .avatar:is(:hover, :focus-visible) { z-index: 1; } .key { display: inline-flex; align-items: center; justify-content: center; min-inline-size: 1.75em; min-block-size: 1.6em; padding-inline: 0.45em; border: var(--border-width) solid var(--border); border-block-end-width: calc(var(--border-width) * 2); border-radius: var(--radius-sm); background: var(--surface-raised); color: var(--text); font-family: var(--font-mono); font-size: 0.875em; font-weight: var(--font-weight-medium); line-height: 1; white-space: nowrap; vertical-align: 0.08em; } :where(.overline) { --intent: initial; --intent-fg: initial; --ui-bg: initial; --ui-fg: initial; --ui-border: initial; --ui-hover-bg: initial; } .overline { align-self: flex-start; color: var(--text-muted); font-size: var(--font-size-sm); font-weight: var(--font-weight-medium); letter-spacing: 0.04em; text-transform: uppercase; } .overline.pill { display: inline-flex; align-items: center; gap: 0.5em; padding-inline: 0.6em; padding-block: 0.25em; color: var(--intent, var(--text-muted)); border: var(--border-width) solid var(--border); border-radius: var(--radius-full); background: var(--surface); } @supports (color: color-mix(in oklch, red, white)) { .overline.pill { border-color: color-mix(in oklch, var(--intent, var(--border)) 35%, var(--border)); background: color-mix(in oklch, var(--intent, transparent) 6%, var(--surface)); } } .navbar { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--gap); padding-block: var(--space-3); padding-inline: var(--space-4); border: var(--border-width) solid var(--border); border-radius: var(--radius-lg); background: var(--surface-raised); color: var(--text); } .navbar-brand { display: inline-flex; align-items: center; gap: var(--space-2); color: var(--text); font-weight: var(--font-weight-bold); text-decoration: none; } .navbar-brand:focus-visible { border-radius: var(--radius-sm); } .navbar-nav { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-1); margin: 0; padding: 0; list-style: none; } .nav-link { display: inline-flex; align-items: center; min-block-size: var(--control-size-sm); padding-inline: var(--space-2); border-radius: var(--radius); color: var(--text-muted); font-weight: var(--font-weight-medium); text-decoration: none; } .nav-link:where([aria-current]:not([aria-current="false"])) { background: var(--surface-subtle); color: var(--text); } @media (hover: hover) { .nav-link:hover { background: var(--surface-subtle); color: var(--text); } } .nav-list { display: grid; gap: var(--gap); margin: 0; padding: 0; list-style: none; --gap: var(--space-2); } .nav-list > li { margin: 0; } @media (forced-colors: active) { .nav-link:where([aria-current]:not([aria-current="false"])) { outline: var(--border-width) solid Highlight; background: Highlight; color: HighlightText; forced-color-adjust: none; } @media (hover: hover) { .nav-link:hover:not(:where([aria-current]:not([aria-current="false"]))) { outline: var(--border-width) solid ButtonText; outline-offset: 2px; background: Canvas; color: CanvasText; } } } .breadcrumb { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-1); margin: 0; padding: 0; color: var(--text-subtle); font-size: var(--font-size-sm); list-style: none; } .breadcrumb li { display: inline-flex; align-items: center; gap: var(--space-1); } .breadcrumb li + li::before { content: "/"; color: var(--text-subtle); } .breadcrumb a { color: var(--text-muted); text-decoration: none; } @media (hover: hover) { .breadcrumb li:not(:where([aria-current]:not([aria-current="false"]))) > a:hover:not(:where([aria-current]:not([aria-current="false"]))) { color: var(--text); text-decoration: underline; } } .breadcrumb a:focus-visible { border-radius: var(--radius-sm); } .breadcrumb a:where([aria-current]:not([aria-current="false"])) { color: var(--text); font-weight: var(--font-weight-medium); } .breadcrumb li:where([aria-current]:not([aria-current="false"])) > :where(a, span) { color: var(--text); font-weight: var(--font-weight-medium); } .pagination { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-1); margin: 0; padding: 0; list-style: none; } .pagination .btn { min-inline-size: var(--control-size); } .pagination > li > [aria-hidden="true"] { display: inline-flex; align-items: center; justify-content: center; min-inline-size: var(--control-size); } :where(.tab) { --intent: initial; --intent-fg: initial; --ui-bg: initial; --ui-fg: initial; --ui-border: initial; --ui-hover-bg: initial; } .tabs { display: flex; flex-wrap: wrap; gap: var(--space-1); margin: 0; padding: 0; border-block-end: var(--border-width) solid var(--border); list-style: none; } .tabs[aria-orientation="vertical"] { display: grid; align-content: start; justify-items: stretch; border-block-end: 0; border-inline-end: var(--border-width) solid var(--border); } .tab { display: inline-flex; align-items: center; min-block-size: var(--control-size); padding-inline: var(--space-3); border: 0; border-block-end: 2px solid transparent; border-radius: 0; background: transparent; color: var(--text-muted); font: inherit; font-weight: var(--font-weight-strong); text-decoration: none; cursor: pointer; } .tabs[aria-orientation="vertical"] .tab { justify-content: flex-start; border-block-end: 0; border-inline-end: 2px solid transparent; padding-inline-end: var(--space-4); } .tab:is(:disabled, [aria-disabled="true"]) { cursor: not-allowed; opacity: var(--disabled-opacity); } @media (hover: hover) { .tab:hover:not(:where(:disabled, [aria-disabled="true"])) { color: var(--text); } } .tab:focus-visible { outline: var(--focus-outline); outline-offset: -2px; border-radius: var(--radius-sm) var(--radius-sm) 0 0; } .tab[aria-selected="true"], .tab[aria-current]:not([aria-current="false"]), .tab[aria-pressed="true"] { border-block-end-color: var(--intent, var(--primary)); color: var(--intent, var(--primary)); } .tabs[aria-orientation="vertical"] .tab[aria-selected="true"], .tabs[aria-orientation="vertical"] .tab[aria-current]:not([aria-current="false"]), .tabs[aria-orientation="vertical"] .tab[aria-pressed="true"] { border-block-end-color: transparent; border-inline-end-color: var(--intent, var(--primary)); } @media (forced-colors: active) { .tabs { border-block-end-color: ButtonText; } .tabs[aria-orientation="vertical"] { border-block-end-color: transparent; border-inline-end-color: ButtonText; } .tab { color: ButtonText; } @media (hover: hover) { .tab:hover:not(:where(:disabled, [aria-disabled="true"])) { color: ButtonText; text-decoration: underline; text-underline-offset: 0.18em; } } .tab[aria-selected="true"], .tab[aria-current]:not([aria-current="false"]), .tab[aria-pressed="true"] { border-block-end-color: Highlight; color: Highlight; } .tabs[aria-orientation="vertical"] .tab[aria-selected="true"], .tabs[aria-orientation="vertical"] .tab[aria-current]:not([aria-current="false"]), .tabs[aria-orientation="vertical"] .tab[aria-pressed="true"] { border-block-end-color: transparent; border-inline-end-color: Highlight; } } @supports selector(.scrollspy a:target-current) { .scrollspy { scroll-target-group: auto; } .scrollspy a:target-current { color: var(--text); font-weight: var(--font-weight-medium); } } .table-wrap { inline-size: 100%; max-inline-size: 100%; min-inline-size: 0; overflow-x: auto; border: var(--border-width) solid var(--border); border-radius: var(--radius-lg); background: var(--surface-raised); } .table { --table-min: 100%; --table-cell-pad: var(--space-3); inline-size: max(var(--table-min), 100%); border-collapse: collapse; background: transparent; color: var(--text); font-size: var(--font-size-md); } .table caption { padding: var(--table-cell-pad); color: var(--text-muted); text-align: var(--text-align, start); } .table th, .table td { padding: var(--table-cell-pad); border-block-end: var(--border-width) solid var(--border); text-align: var(--text-align, start); vertical-align: baseline; } .table thead th { vertical-align: bottom; } .table th { color: var(--text-muted); font-weight: var(--font-weight-strong); } .table thead { background: var(--surface-subtle); } @media (hover: hover) { .table tbody tr:hover { background-color: var(--hover-overlay); } } .table > tr:last-child > *, .table > :last-child > tr:last-child > * { border-block-end: 0; } :where(.meter) { --intent: initial; --intent-fg: initial; --ui-bg: initial; --ui-fg: initial; --ui-border: initial; --ui-hover-bg: initial; } .meter { appearance: none; -webkit-appearance: none; display: block; inline-size: 100%; block-size: var(--bar-height); overflow: hidden; border: 0; border-radius: var(--radius-full); background: var(--surface-subtle); } .meter::-webkit-meter-bar { -webkit-appearance: none; block-size: var(--bar-height); border: 0; border-radius: var(--radius-full); background: var(--surface-subtle); } .meter::-webkit-meter-optimum-value { block-size: var(--bar-height); border-radius: var(--radius-full); background: var(--success); } .meter::-webkit-meter-suboptimum-value { block-size: var(--bar-height); border-radius: var(--radius-full); background: var(--warning); } .meter::-webkit-meter-even-less-good-value { block-size: var(--bar-height); border-radius: var(--radius-full); background: var(--danger); } .meter::-moz-meter-bar { block-size: var(--bar-height); border-radius: var(--radius-full); } @media (forced-colors: active) { .meter { border: var(--border-width) solid ButtonText; background: Canvas; } .meter::-webkit-meter-bar { border: 0; background: Canvas; } .meter::-webkit-meter-optimum-value, .meter::-webkit-meter-suboptimum-value, .meter::-webkit-meter-even-less-good-value, .meter::-moz-meter-bar { background: Highlight; forced-color-adjust: none; } } .field { display: grid; gap: var(--space-1); color: var(--text); } .field-group { min-inline-size: 0; margin: 0; padding: var(--space-3); border: var(--border-width) solid var(--border); border-radius: var(--radius); } .field-group + .field-group { margin-block-start: var(--space-4); } .field-label, .field-group > legend { color: var(--text); font-weight: var(--font-weight-strong); } .field-group > legend { padding-block: 0; padding-inline: var(--fieldset-legend-padding-inline, var(--space-1)); font-size: var(--font-size-xs); } .field-help { color: var(--text-muted); font-size: var(--font-size-sm); } .field-error { display: none; color: var(--danger); font-size: var(--font-size-sm); } .required-mark { color: var(--danger); } .field.danger .field-help { color: var(--danger); } .input, .textarea, .select { --control-border: var(--border); --control-bg: var(--surface); --control-fg: var(--text); --control-ring: none; --control-cursor: auto; --control-opacity: 1; appearance: none; inline-size: 100%; min-block-size: var(--control-size); padding-inline: var(--space-3); border: var(--border-width) solid var(--form-invalid-border, var(--control-border)); border-block-end-color: var( --form-invalid-border, var(--control-border-block-end-color, var(--control-border)) ); border-block-end-width: var(--control-border-block-end-width, var(--border-width)); border-radius: var(--radius); background: var(--control-bg); color: var(--control-fg); font-size: var(--control-font-size); box-shadow: var(--control-ring); cursor: var(--control-cursor); opacity: var(--control-opacity); outline: none; transition: border-color var(--duration), box-shadow var(--duration), background-color var(--duration), color var(--duration); } .textarea { min-block-size: 6rem; padding-block: var(--space-2); resize: vertical; } @media (hover: hover) { .input:hover:not(:disabled), .textarea:hover:not(:disabled) { --control-border: var(--text-subtle); } .select:hover:not(:disabled) { --control-bg: var(--surface-subtle); } } .input:focus-visible, .textarea:focus-visible, .select:focus-visible { --control-border: var(--focus); outline: var(--focus-outline); outline-offset: var(--focus-outline-offset); box-shadow: var(--focus-ring-shadow); } .input[readonly], .textarea[readonly] { --control-bg: var(--surface-subtle); --control-border: var(--border); } .input:disabled, .textarea:disabled, .select:disabled { --control-bg: var(--surface-subtle); --control-fg: var(--text-subtle); --control-border: var(--border); --control-cursor: not-allowed; --control-opacity: 1; } .input::placeholder, .textarea::placeholder { color: var(--text-muted); } @media (forced-colors: active) { .input:focus-visible, .textarea:focus-visible, .select:focus-visible { box-shadow: none; } } .input-icon { --input-icon-size: var(--variant-icon-size, 1.25rem); display: block; position: relative; } .input-icon > :first-child { position: absolute; inset-block-start: 50%; inset-inline-start: var(--space-3); transform: translateY(-50%); font-size: var(--input-icon-size); color: var(--text-muted); pointer-events: none; } .input-icon > svg:first-child { inline-size: var(--input-icon-size); block-size: var(--input-icon-size); } .input-icon > .input { padding-inline-start: calc(var(--space-3) * 2 + var(--input-icon-size)); } :where(.choice, .check, .radio) { --intent: initial; --intent-fg: initial; --ui-bg: initial; --ui-fg: initial; --ui-border: initial; --ui-hover-bg: initial; } :where(.choice) :where(input[type="checkbox"]:not([role="switch"]), input[type="radio"]) { --intent: inherit; --intent-fg: inherit; } .choice { --choice-control-offset: 0.25em; display: inline-flex; align-items: flex-start; gap: var(--space-2); color: var(--text); font-size: var(--control-font-size); cursor: pointer; } .choice > :is(input[type="checkbox"]:not([role="switch"]), input[type="radio"]) { flex: 0 0 auto; margin-block-start: var(--choice-control-offset); } .choice > span > .field-help { display: block; } .choice:has(:disabled) { color: var(--text-subtle); cursor: not-allowed; } .check, .radio { --choice-border: var(--border); --choice-bg: var(--surface); --choice-mark: var(--primary-fg); position: relative; vertical-align: middle; display: inline-grid; place-content: center; inline-size: 1.125em; block-size: 1.125em; margin-inline: 0; margin-block-end: 0; border: var(--border-width) solid var(--form-invalid-border, var(--choice-border)); background: var(--choice-bg); color: var(--choice-mark); appearance: none; cursor: pointer; } .check { border-radius: var(--radius-sm); } .radio { border-radius: var(--radius-full); } .check::before, .radio::before { content: ""; position: absolute; inset: 0; margin: auto; transform: scale(0); transition: transform var(--duration); } .check::before { inline-size: 0.58em; block-size: 0.34em; border-inline-start: 2px solid currentColor; border-block-end: 2px solid currentColor; transform: translateY(-0.06em) rotate(-45deg) scale(0); } .radio::before { inline-size: 0.5em; block-size: 0.5em; border-radius: var(--radius-full); background: currentColor; } .check:checked, .radio:checked { --choice-border: var(--intent, var(--primary)); --choice-bg: var(--intent, var(--primary)); --choice-mark: var(--intent-fg, var(--primary-fg)); } .check:checked::before { transform: translateY(-0.06em) rotate(-45deg) scale(1); } .check:indeterminate { --choice-border: var(--intent, var(--primary)); --choice-bg: var(--intent, var(--primary)); --choice-mark: var(--intent-fg, var(--primary-fg)); } .check:indeterminate::before { border-inline-start: 0; inline-size: 0.6em; block-size: 0; border-block-end: 2px solid currentColor; transform: scale(1); } .radio:checked::before { transform: scale(1); } @media (hover: hover) { .check:hover:not(:checked, :indeterminate, :disabled), .radio:hover:not(:checked, :indeterminate, :disabled) { --choice-border: var(--text-subtle); } } .check:focus-visible, .radio:focus-visible { --choice-border: var(--focus); outline: var(--focus-outline); outline-offset: var(--focus-outline-offset); box-shadow: var(--focus-ring-shadow); } .check:disabled, .radio:disabled { --choice-bg: var(--surface-subtle); --choice-border: var(--border); --choice-mark: var(--text-subtle); cursor: not-allowed; opacity: 1; } @media (forced-colors: active) { .check, .radio { --choice-border: ButtonText; --choice-bg: Canvas; --choice-mark: ButtonText; } .check:checked, .radio:checked, .check:indeterminate { --choice-border: Highlight; --choice-bg: Highlight; --choice-mark: HighlightText; forced-color-adjust: none; } .check:disabled, .radio:disabled { --choice-border: GrayText; --choice-bg: Canvas; --choice-mark: GrayText; } } :where(.choice-card) { --intent: initial; --intent-fg: initial; --ui-bg: initial; --ui-fg: initial; --ui-border: initial; --ui-hover-bg: initial; } .choice-card { --choice-card-pad: var(--variant-space, var(--space-4)); --choice-card-radius: var(--radius); --choice-card-border: var(--border); --choice-card-bg: var(--surface); --choice-card-check-size: 1.5em; position: relative; display: block; padding: var(--choice-card-pad); border: var(--border-width) solid var(--choice-card-border); border-radius: var(--choice-card-radius); background: var(--choice-card-bg); color: var(--text); cursor: pointer; transition: border-color var(--duration), background-color var(--duration), box-shadow var(--duration); } .choice-card > input { position: absolute; inline-size: 1px; block-size: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; } .choice-card:has(:focus-visible) { outline: var(--focus-outline); outline-offset: var(--focus-outline-offset); box-shadow: var(--focus-ring-shadow); } .choice-card:has(:disabled) { opacity: var(--disabled-opacity); cursor: not-allowed; } @media (hover: hover) { .choice-card:hover:not(:has(:disabled)) { --choice-card-border: var(--text-subtle); } } .choice-card:has(:checked) { --choice-card-border: var(--intent, var(--primary)); } @supports (color: color-mix(in oklch, red, white)) { .choice-card:has(:checked) { --choice-card-bg: color-mix(in oklch, var(--surface) 96%, var(--intent, var(--primary))); } } .choice-card:has(:checked)::before { content: ""; position: absolute; inset-inline-end: -0.375em; inset-block-start: -0.375em; inline-size: var(--choice-card-check-size); block-size: var(--choice-card-check-size); background: var(--intent, var(--primary)); z-index: 1; box-shadow: 0 0 0 2px var(--surface); } .choice-card:has(input[type="radio"]:checked)::before { border-radius: var(--radius-full); } .choice-card:has(input[type="checkbox"]:checked)::before { border-radius: var(--radius-sm); } .choice-card:has(:checked)::after { content: ""; position: absolute; inset-inline-end: -0.375em; inset-block-start: -0.375em; inline-size: var(--choice-card-check-size); block-size: var(--choice-card-check-size); background: var(--intent-fg, var(--primary-fg)); mask: var(--icon-check-mask) center / 60% no-repeat; -webkit-mask: var(--icon-check-mask) center / 60% no-repeat; z-index: 2; } @media (forced-colors: active) { .choice-card { --choice-card-border: ButtonText; --choice-card-bg: Canvas; } .choice-card:has(:checked) { --choice-card-border: Highlight; forced-color-adjust: none; } .choice-card:has(:checked)::before { background: Highlight; box-shadow: 0 0 0 2px Canvas; } .choice-card:has(input[type="radio"]:checked)::before { border-radius: var(--radius-full); } .choice-card:has(input[type="checkbox"]:checked)::before { border-radius: var(--radius-sm); } .choice-card:has(:checked)::after { background: HighlightText; } } .select:is(:not([multiple], [size]), :not([multiple])[size="1"]) { appearance: none; padding-inline-end: calc(var(--space-3) + var(--space-6)); background-image: var(--icon-chevron-image); background-position: center right var(--space-3); background-size: 1rem auto; background-repeat: no-repeat; } .select:is(:not([multiple], [size]), :not([multiple])[size="1"]):dir(rtl) { background-position: center left var(--space-3); } @media (forced-colors: active), (prefers-contrast: more) { .select:is(:not([multiple], [size]), :not([multiple])[size="1"]) { appearance: auto; background-image: none; padding-inline-end: var(--space-3); } } @media (forced-colors: none) and (prefers-contrast: no-preference) and (hover: hover) and ( pointer: fine ) { @supports (appearance: base-select) { .select:not([multiple], .native, [size]:not([size="1"])) { appearance: base-select; align-items: center; &::picker(select) { appearance: base-select; max-height: min(24rem, calc(var(--viewport-block) * 0.7)); margin-block: var(--space-2); padding: 0; border: var(--border-width) solid var(--border); border-radius: var(--radius); background-color: var(--surface-raised); color: inherit; box-shadow: var(--shadow-popout); } &:open { --control-border: var(--border); --control-bg: var(--surface-raised); outline: none; box-shadow: var(--focus-ring-shadow); } &::picker-icon { display: none; } & option { position: relative; padding-block: var(--space-2); padding-inline: var(--space-3); white-space: normal; transition-property: color, background-color; transition-duration: var(--duration); &:not(:disabled):hover { background-color: var(--surface-subtle); color: var(--text); cursor: pointer; } &:not(:disabled):focus-visible { background-color: var(--primary); color: var(--primary-fg); outline: none; } &:active { background-color: var(--surface-subtle); color: var(--text); } &::checkmark { content: ""; display: block; inline-size: 1rem; block-size: 1rem; background-color: currentColor; -webkit-mask-image: var(--icon-check-mask); mask-image: var(--icon-check-mask); -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat; -webkit-mask-size: contain; mask-size: contain; -webkit-mask-position: center; mask-position: center; } } & optgroup { padding-block-start: 0.5em; & option:first-child { margin-block-start: 0.5em; } } } } } :where(.range) { --intent: initial; --intent-fg: initial; --ui-bg: initial; --ui-fg: initial; --ui-border: initial; --ui-hover-bg: initial; } .file { color: var(--text-muted); } .file::file-selector-button { margin-inline-end: var(--space-3); padding-block: var(--space-1); padding-inline: var(--space-2); border: var(--border-width) solid var(--border); border-radius: var(--radius-sm); background: var(--surface-subtle); color: var(--text); font: inherit; font-size: var(--font-size-sm); font-weight: var(--font-weight-medium); cursor: pointer; transition: background-color var(--duration), border-color var(--duration), color var(--duration); } .file:disabled::file-selector-button { cursor: not-allowed; } @media (hover: hover) { .file:not(:disabled)::file-selector-button:hover { background: var(--border); } } .range { inline-size: 100%; accent-color: var(--intent, var(--primary)); } .file:focus-visible, .range:focus-visible { outline: var(--focus-outline); outline-offset: var(--focus-outline-offset); box-shadow: var(--focus-ring-shadow); } @media (forced-colors: active) { .file:focus-visible, .range:focus-visible { box-shadow: none; } } :where(.switch) { --intent: initial; --intent-fg: initial; --ui-bg: initial; --ui-fg: initial; --ui-border: initial; --ui-hover-bg: initial; } .switch { --switch-bg: var(--border); --switch-border: var(--border); --switch-knob: var(--surface-raised); --switch-width: calc(var(--control-size) * 1.16); --switch-block-size: calc(var(--control-size) * 0.63); --switch-knob-margin: calc(var(--switch-block-size) * 0.12); --switch-knob-size: calc(var(--switch-block-size) - 2 * var(--switch-knob-margin)); --switch-travel: calc( var(--switch-width) - var(--switch-knob-size) - 2 * var(--border-width) - 2 * var(--switch-knob-margin) ); position: relative; display: inline-grid; align-items: center; justify-content: start; inline-size: var(--switch-width); block-size: var(--switch-block-size); margin: 0; border: var(--border-width) solid var(--form-invalid-border, var(--switch-border)); border-radius: var(--radius-full); background: var(--switch-bg); appearance: none; cursor: pointer; } .switch::before { content: ""; inline-size: var(--switch-knob-size); block-size: var(--switch-knob-size); margin-inline: var(--switch-knob-margin); border-radius: var(--radius-full); background: var(--switch-knob); box-shadow: var(--shadow); transition: transform var(--duration), background-color var(--duration), box-shadow var(--duration); } @media (hover: hover) { .switch:hover:not(:disabled) { --switch-border: var(--intent, var(--primary)); } } .switch:checked { --switch-bg: var(--intent, var(--primary)); --switch-border: var(--intent, var(--primary)); --switch-knob: var(--intent-fg, var(--primary-fg)); } .switch:checked::before { transform: translateX(var(--switch-travel)); } .switch:checked:dir(rtl)::before { transform: translateX(calc(var(--switch-travel) * -1)); } .switch:focus-visible { --switch-border: var(--focus); outline: var(--focus-outline); outline-offset: var(--focus-outline-offset); box-shadow: var(--focus-ring-shadow); } .switch:disabled { --switch-bg: var(--surface-subtle); --switch-border: var(--border); --switch-knob: var(--text-subtle); opacity: 1; cursor: not-allowed; } @media (forced-colors: active) { .switch { --switch-border: ButtonText; --switch-knob: ButtonText; } .switch::before { box-shadow: none; } .switch:checked { --switch-bg: Highlight; --switch-border: Highlight; --switch-knob: HighlightText; forced-color-adjust: none; } .switch:disabled { --switch-bg: Canvas; --switch-border: GrayText; --switch-knob: GrayText; forced-color-adjust: auto; } } .field.danger { --form-invalid-border: var(--danger); } .field.danger > .field-error { display: block; } @supports selector(:has(*)) { .field:has([aria-invalid="true"]) > .field-error, .needs-validation.was-validated .field:has(:invalid) > .field-error { display: block; } } :where(.input, .textarea, .select, .check, .radio, .switch)[aria-invalid="true"], .needs-validation.was-validated :is(.input, .textarea, .select, .check, .radio, .switch):invalid { --form-invalid-border: var(--danger); } .check[aria-invalid="true"]:is(:checked, :indeterminate), .radio[aria-invalid="true"]:checked { --choice-bg: var(--danger); } .switch[aria-invalid="true"]:checked { --switch-bg: var(--danger); } @supports selector(:user-invalid) { .needs-validation :is(.input, .textarea, .select, .check, .radio, .switch):user-invalid { --form-invalid-border: var(--danger); } } @supports selector(:has(:user-invalid)) { .needs-validation .field:has(:user-invalid) > .field-error { display: block; } } .form-actions { display: flex; flex-wrap: wrap; gap: var(--gap); align-items: center; margin-block-start: var(--form-actions-margin-block-start, var(--space-5)); } .form-actions.sticky { position: sticky; inset-block-end: var(--form-actions-sticky-block-offset, 0px); z-index: var(--z-sticky); isolation: isolate; margin-inline: calc(var(--form-actions-sticky-inline-offset, 0px) * -1); padding: var(--form-actions-sticky-padding, var(--space-3)); border-block-start: var(--border-width) solid var(--border); background: var(--surface); -webkit-backdrop-filter: blur(1rem); backdrop-filter: blur(1rem); } @supports (background: color-mix(in oklch, red 50%, transparent)) { .form-actions.sticky { background: color-mix(in oklch, var(--surface) 88%, transparent); } } .sr-only { position: absolute; inline-size: 1px; block-size: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; } .overflow-auto { overflow: auto; } .fit { inline-size: fit-content; max-inline-size: 100%; } .grow { flex: 1 1 auto; min-inline-size: 0; } .nowrap { white-space: nowrap; } .truncate { min-inline-size: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .items-start { --items-align: start; align-items: start; } .items-center { --items-align: center; align-items: center; } .items-end { --items-align: end; align-items: end; } .muted { color: var(--text-muted); } .circle { border-radius: var(--radius-full); } .text-start { --text-align: start; text-align: start; } .text-center { --text-align: center; text-align: center; } .text-end { --text-align: end; text-align: end; } .text-balance { text-wrap: balance; } .text-pretty { text-wrap: pretty; } .list-reset { margin: 0; padding: 0; list-style: none; } .dot { flex: none; inline-size: 0.25rem; block-size: 0.25rem; border-radius: var(--radius-full); background: var(--text-subtle); } .link-plain { color: inherit; text-decoration: none; } .link-muted { color: var(--text-muted); text-decoration: none; } @media (hover: hover) { .link-muted:hover { color: var(--text); } } .gap-none { gap: 0; } .py { padding-block: var(--variant-space); } .px { padding-inline: var(--variant-space); } .mbs { margin-block-start: var(--variant-space); } .mbe { margin-block-end: var(--variant-space); } .join { --join-radius: var(--radius); --join-ss: 0; --join-se: 0; --join-es: 0; --join-ee: 0; align-items: stretch; display: inline-flex; } .join.circle { --join-radius: var(--radius-full); } .join-addon { --control-border: var(--border); --control-bg: var(--surface-subtle); --control-fg: var(--text-muted); align-items: center; display: inline-flex; justify-content: center; min-block-size: var(--control-size); padding-inline: var(--space-3); border: var(--border-width) solid var(--control-border); border-radius: var(--radius); background: var(--control-bg); color: var(--control-fg); font-size: var(--control-font-size); line-height: 1; white-space: nowrap; } .join > * { border-start-start-radius: var(--join-ss); border-start-end-radius: var(--join-se); border-end-end-radius: var(--join-ee); border-end-start-radius: var(--join-es); } .join > :first-child { --join-ss: var(--join-radius); --join-es: var(--join-radius); } .join > :last-child { --join-se: var(--join-radius); --join-ee: var(--join-radius); } .join > :only-child { --join-ss: var(--join-radius); --join-se: var(--join-radius); --join-es: var(--join-radius); --join-ee: var(--join-radius); } .join > * + * { margin-inline-start: calc(var(--border-width) * -1); } .join > :is(:hover, :focus, :focus-within) { z-index: 1; } .join > :is(:focus, :focus-within) { z-index: 2; } .join > :is(.input, .textarea, .select) { z-index: 3; } .join:has(> :is(.input, .textarea, .select):focus-visible) { border-radius: var(--join-radius); outline: var(--focus-outline); outline-offset: var(--focus-outline-offset); box-shadow: var(--focus-ring-shadow); } .join:has(> :is(.input, .textarea, .select)) > :is(.input, .textarea, .select):focus-visible { outline: none; box-shadow: none; } :focus { outline: var(--focus-outline); outline-offset: var(--focus-outline-offset); } @supports selector(:focus-visible) { :focus:not(:focus-visible) { outline: none; } } @media print { :root, body { color-scheme: light; background: #fff; color: #000; } .flyout, .tooltip, .surface-backdrop, .status-bar, .spinner, dialog.modal[open], dialog.drawer[open] { display: none !important; } button.btn, input[type="button"].btn, input[type="submit"].btn, input[type="reset"].btn { display: none !important; } a.btn[href^="http"]::after { content: " (" attr(href) ")"; font-size: 0.875em; } .card, .alert, .badge { border: var(--border-width) solid CanvasText; break-inside: avoid; } h1, h2, h3, h4, h5, h6 { break-after: avoid; } }
1
+ *, *::before, *::after { box-sizing: border-box; } html { -webkit-text-size-adjust: 100%; } body { margin: 0; } button, input, textarea, select { font: inherit; } [hidden]:not([hidden="until-found"]) { display: none !important; } @supports not (selector(dialog:modal)) { dialog:not([open]) { display: none; } } :where(img, svg, video) { max-inline-size: 100%; block-size: auto; } @media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto !important; } *, *::before, *::after { animation-duration: 0.01ms !important; animation-delay: 0s !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; transition-delay: 0s !important; } } @supports not (selector(dialog:modal)) { dialog[open]:where(.dialog-fallback) { position: absolute; inset-inline: 0; width: -moz-fit-content; width: fit-content; max-inline-size: calc(100% - 2rem); margin: auto; padding: var(--space-4, 1em); border: var(--border-width, 1px) solid var(--border, currentColor); background: var(--surface-raised, #fff); color: var(--text, inherit); } dialog[open].is-fallback-modal { position: fixed; inset-block: 8vh auto; max-block-size: 84vh; overflow: auto; z-index: 40; box-shadow: 0 0 0 100vmax var(--backdrop-fill, rgb(0 0 0 / 35%)); } dialog[open].is-fallback-modal::before { content: ""; position: fixed; inset: 0; z-index: -1; } } :root { --font-sans: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; --font-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; --line-height: 1.5; --line-height-tight: 1.25; --line-height-relaxed: 1.75; --font-weight: 400; --font-weight-medium: 500; --font-weight-strong: 650; --font-weight-bold: 700; --font-size-xs: 0.8125rem; --font-size-sm: 0.875rem; --font-size-md: 1rem; --font-size-lg: 1.125rem; --gap: 0.75rem; --variant-space: var(--space-4); --space-1: 0.25rem; --space-2: 0.5rem; --space-3: 0.75rem; --space-4: 1rem; --space-5: 1.5rem; --space-6: 2rem; --border-width: 1px; --radius-full: 9999px; --shadow-xs: 0 1px 2px rgb(0 0 0 / 0.04); --shadow: 0 1px 3px rgb(0 0 0 / 0.05), 0 4px 12px rgb(0 0 0 / 0.04); --shadow-popout: 0 0.25rem 0.75rem rgb(0 0 0 / 0.15); --duration: 150ms; --duration-fast: 100ms; --duration-slow: 200ms; --duration-spin: 0.75s; --duration-shimmer: 1.2s; --ease: ease; --focus-outline-color: currentColor; --focus-outline: calc(var(--border-width) * 2) solid var(--focus-outline-color); --focus-outline-offset: 2px; --focus-ring-width: 3px; --indicator-offset: 14.65%; --indicator-ring: var(--surface); --backdrop-color: rgb(0 0 0); --backdrop-opacity: 0.45; --backdrop-fill: rgb(0 0 0 / var(--backdrop-opacity)); --bar-height: 0.65rem; --control-size-sm: 2rem; --control-size-md: 2.375rem; --control-size-lg: 2.75rem; --control-size: var(--control-size-md); --control-pad-x: 1em; --control-font-size: var(--font-size-md); --disabled-opacity: 0.65; --soft-bg-mix: 88%; --soft-border-mix: 65%; --soft-hover-alpha: 12%; --icon-chevron-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E"); --icon-check-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'/%3E%3C/svg%3E"); --icon-chevron-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%238a8594' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E"); --viewport-block: 100vh; --viewport-inline: 100vw; --z-sticky: 10; --z-menu: 20; --z-tooltip: 50; --z-status: 60; } @supports (block-size: 100dvh) { :root { --viewport-block: 100dvh; } } @supports (inline-size: 100vi) { :root { --viewport-inline: 100vi; } } @supports (color: color-mix(in oklch, red, white)) { :root { --shadow-xs: 0 1px 2px color-mix(in oklch, var(--shadow-color) 4%, transparent); --shadow: 0 1px 3px color-mix(in oklch, var(--shadow-color) 5%, transparent), 0 4px 12px color-mix(in oklch, var(--shadow-color) 4%, transparent); --shadow-popout: 0 0.25rem 0.75rem color-mix(in oklch, var(--shadow-color) 15%, transparent); --backdrop-fill: color-mix( in oklch, var(--backdrop-color) calc(var(--backdrop-opacity) * 100%), transparent ); } } :root { color-scheme: light dark; } [data-theme="light"] { color-scheme: light; } [data-theme="dark"] { color-scheme: dark; } @supports not (color: light-dark(red, blue)) { :root, [data-theme="light"], [data-theme="dark"] { color-scheme: light; } } :root, [data-theme="light"] { --primary: hsl(268 32% 33%); --primary-fg: hsl(0 0% 98%); --secondary: hsl(16 38% 38%); --secondary-fg: hsl(0 0% 98%); --success: hsl(150 40% 31%); --success-fg: hsl(0 0% 98%); --warning: hsl(36 68% 34%); --warning-fg: hsl(0 0% 98%); --danger: hsl(5 58% 43%); --danger-fg: hsl(0 0% 98%); --neutral: hsl(258 7% 43%); --neutral-fg: hsl(0 0% 98%); --surface: hsl(0 0% 100%); --surface-raised: hsl(0 0% 100%); --surface-subtle: hsl(262 24% 96%); --surface-solid: hsl(261 16% 13%); --text: hsl(261 20% 13%); --text-muted: hsl(259 9% 42%); --text-subtle: hsl(258 7% 57%); --border: hsl(260 15% 88%); --focus: var(--neutral); --focus-ring: hsl(258 7% 43% / 0.3); --focus-ring-shadow: 0 0 0 var(--focus-ring-width) var(--focus-ring); --hover-overlay: hsl(260 20% 10% / 0.04); --radius: 0.5rem; --radius-sm: 0.25rem; --radius-lg: 0.75rem; --shadow-color: hsl(260 25% 10%); --heading: var(--text); --selection-bg: var(--primary); --selection-fg: var(--primary-fg); --hgroup-gap: 0.25em; } [data-tone="dark"] { --tone-fg: white; } [data-tone="light"] { --tone-fg: var(--text); } @supports (color: color-mix(in oklch, red, white)) { :root, [data-theme="light"], [data-theme="dark"] { --focus-ring: color-mix(in oklch, var(--focus) 30%, transparent); } } @supports (color: light-dark(red, blue)) { :root, [data-theme="light"] { --primary: light-dark(hsl(268 32% 33%), hsl(268 42% 76%)); --primary-fg: light-dark(hsl(0 0% 98%), hsl(268 30% 12%)); --secondary: light-dark(hsl(16 38% 38%), hsl(18 45% 72%)); --secondary-fg: light-dark(hsl(0 0% 98%), hsl(18 32% 11%)); --success: light-dark(hsl(150 40% 31%), hsl(150 38% 62%)); --success-fg: light-dark(hsl(0 0% 98%), hsl(150 35% 8%)); --warning: light-dark(hsl(36 68% 34%), hsl(40 62% 64%)); --warning-fg: light-dark(hsl(0 0% 98%), hsl(38 35% 10%)); --danger: light-dark(hsl(5 58% 43%), hsl(4 60% 70%)); --danger-fg: light-dark(hsl(0 0% 98%), hsl(4 35% 10%)); --neutral: light-dark(hsl(258 7% 43%), hsl(258 10% 72%)); --neutral-fg: light-dark(hsl(0 0% 98%), hsl(260 18% 10%)); --surface: light-dark(hsl(0 0% 100%), hsl(263 17% 9%)); --surface-raised: light-dark(hsl(0 0% 100%), hsl(263 15% 12%)); --surface-subtle: light-dark(hsl(262 24% 96%), hsl(263 13% 16%)); --surface-solid: light-dark(hsl(261 16% 13%), hsl(0 0% 96%)); --text: light-dark(hsl(261 20% 13%), hsl(260 12% 95%)); --text-muted: light-dark(hsl(259 9% 42%), hsl(259 9% 67%)); --text-subtle: light-dark(hsl(258 7% 57%), hsl(258 7% 54%)); --border: light-dark(hsl(260 15% 88%), hsl(262 12% 24%)); --focus-ring: light-dark(hsl(258 7% 43% / 0.3), hsl(258 10% 72% / 0.28)); --hover-overlay: light-dark(hsl(260 20% 10% / 0.04), hsl(0 0% 100% / 0.06)); --shadow-color: light-dark(hsl(260 25% 10%), hsl(262 40% 2%)); } } @supports (color: color-mix(in oklch, red, white)) and (color: light-dark(red, blue)) { :root, [data-theme="light"] { --focus-ring: light-dark( color-mix(in oklch, var(--focus) 30%, transparent), color-mix(in oklch, var(--focus) 28%, transparent) ); } } @media (forced-colors: active) { :root, [data-theme="light"], [data-theme="dark"] { --focus-outline-color: Highlight; --focus-ring-shadow: none; --backdrop-fill: Canvas; } } @media (prefers-contrast: more) { :root, [data-theme="light"], [data-theme="dark"] { --border-width: 2px; --focus-outline-offset: 3px; --focus-ring-width: 4px; --text-muted: var(--text); --text-subtle: var(--text); } } body { background: var(--surface); color: var(--text); font-family: var(--font-sans); line-height: var(--line-height); } a { color: inherit; text-underline-offset: 0.18em; } @media (hover: hover) { a:hover { text-decoration-thickness: 0.12em; } } :where(h1, h2, h3, h4, h5, h6) { color: var(--heading, inherit); line-height: var(--line-height-tight); text-wrap: balance; } hgroup { display: grid; gap: var(--hgroup-gap); } hgroup > * { margin-block: 0; } hr { border: 0; border-block-start: var(--border-width) solid var(--border); margin-block: var(--space-6); } code, kbd, samp, pre { font-family: var(--font-mono); } small { font-size: 0.875em; } ::selection { background: var(--selection-bg, var(--primary)); color: var(--selection-fg, var(--primary-fg)); } .primary { --intent: var(--primary); --intent-fg: var(--primary-fg); } .secondary { --intent: var(--secondary); --intent-fg: var(--secondary-fg); } .success { --intent: var(--success); --intent-fg: var(--success-fg); } .warning { --intent: var(--warning); --intent-fg: var(--warning-fg); } .danger { --intent: var(--danger); --intent-fg: var(--danger-fg); } .neutral { --intent: var(--neutral); --intent-fg: var(--neutral-fg); } .container-query { container-type: inline-size; } .stack { display: flex; flex-direction: column; gap: var(--gap); } .stack > * { margin: 0; } .cluster { display: flex; flex-wrap: wrap; align-items: var(--cluster-align, center); justify-content: var(--cluster-justify, flex-start); gap: var(--gap); } .center { box-sizing: content-box; max-inline-size: var(--center-size, 72rem); margin-inline: auto; padding-inline: var(--center-pad, 1rem); } .frame { overflow: hidden; aspect-ratio: var(--frame-ratio, 16 / 9); } .frame > :where(img, video, iframe, canvas, svg) { inline-size: 100%; block-size: 100%; object-fit: cover; } .app-shell { min-block-size: var(--viewport-block); display: flex; flex-direction: column; } .media { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: var(--gap); align-items: start; } .sidebar-layout { display: grid; gap: var(--gap); grid-template-columns: minmax(0, 1fr); } @container (width >= 64rem) { .container-query .sidebar-layout { grid-template-columns: minmax(0, 1fr) var(--sidebar-layout-size, 18rem); align-items: start; } } @supports not (container-type: inline-size) { @media (min-width: 64rem) { .container-query .sidebar-layout { grid-template-columns: minmax(0, 1fr) var(--sidebar-layout-size, 18rem); align-items: start; } } } .grid { display: grid; gap: var(--gap); grid-template-columns: repeat(auto-fit, minmax(min(100%, var(--grid-min, 16rem)), 1fr)); } .grid-2, .grid-3, .grid-4, .grid-6 { display: grid; gap: var(--gap); } .grid-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); } .grid-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); } .grid-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); } .grid-6 { grid-template-columns: repeat(6, minmax(0, 1fr)); } @container (width < 28rem) { .container-query .grid-2, .container-query .grid-3, .container-query .grid-4 { grid-template-columns: 1fr; } .container-query .grid-6 { grid-template-columns: repeat(2, minmax(0, 1fr)); } } @container (28rem <= width < 48rem) { .container-query .grid-3, .container-query .grid-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); } } @container (28rem <= width < 64rem) { .container-query .grid-6 { grid-template-columns: repeat(3, minmax(0, 1fr)); } } @supports not (container-type: inline-size) { @media (max-width: 63.999rem) { .container-query .grid-6 { grid-template-columns: repeat(3, minmax(0, 1fr)); } } @media (max-width: 47.999rem) { .container-query .grid-3, .container-query .grid-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); } } @media (max-width: 27.999rem) { .container-query .grid-2, .container-query .grid-3, .container-query .grid-4 { grid-template-columns: 1fr; } .container-query .grid-6 { grid-template-columns: repeat(2, minmax(0, 1fr)); } } } .solid { --ui-bg: var(--intent, var(--neutral)); --ui-fg: var(--intent-fg, var(--neutral-fg)); --ui-border: transparent; } .soft { --ui-bg: var(--surface-subtle); --ui-border: var(--border); --ui-fg: var(--intent, var(--text)); } .outline { --ui-bg: transparent; --ui-fg: var(--intent, var(--text)); --ui-border: var(--intent, var(--border)); } .sm { --gap: var(--space-2); --variant-space: var(--space-2); --control-size: var(--control-size-sm); --control-font-size: var(--font-size-sm); --variant-font-size: var(--font-size-sm); --variant-icon-size: 1rem; --variant-pad-block: var(--space-3); --variant-compact-size: 1.25rem; --variant-compact-font-size: 0.75rem; } .lg { --gap: var(--space-5); --variant-space: var(--space-5); --control-size: var(--control-size-lg); --control-font-size: var(--font-size-lg); --variant-font-size: var(--font-size-lg); --variant-icon-size: 1.5rem; --variant-pad-block: var(--space-5); --variant-compact-size: 1.875rem; --variant-compact-font-size: var(--font-size-sm); } @supports (color: color-mix(in oklch, red, white)) { .soft { --ui-bg: color-mix(in oklch, var(--surface) var(--soft-bg-mix), var(--intent, var(--neutral))); --ui-border: color-mix( in oklch, var(--surface) var(--soft-border-mix), var(--intent, var(--neutral)) ); } } :is(.btn, a.badge, button.badge):is(.outline, .ghost) { --ui-hover-bg: var(--surface-subtle); } @supports (color: color-mix(in oklch, red, white)) { :is(.btn, a.badge, button.badge):not(:where(.soft, .outline, .ghost, .link)) { --ui-hover-bg: color-mix(in oklch, var(--intent, var(--neutral)) 88%, black); } :is(.btn, a.badge, button.badge):is(.soft) { --ui-hover-bg: color-mix( in oklch, var(--surface) calc(var(--soft-bg-mix) - var(--soft-hover-alpha)), var(--intent, var(--neutral)) ); } :is(.btn, a.badge, button.badge):is(.outline) { --ui-hover-bg: color-mix(in oklch, var(--surface-subtle) 92%, var(--intent, var(--neutral))); } :is(.btn, a.badge, button.badge):is(.ghost) { --ui-hover-bg: color-mix(in oklch, var(--intent, var(--text)) 8%, transparent); } } .prose { --prose-size: 1rem; --prose-line-height: 1.7; --prose-measure: 70ch; --prose-flow: 1em; --prose-heading-line-height: 1.2; --prose-h1: 2rem; --prose-h2: 1.5rem; --prose-h3: 1.25rem; --prose-h4: 1.125rem; max-inline-size: var(--prose-measure); color: var(--text); font-size: var(--prose-size); line-height: var(--prose-line-height); overflow-wrap: break-word; } .prose :where(p, ul, ol, dl, blockquote, pre, table, figure) { margin-block: var(--prose-flow) 0; } .prose :where(h1, h2, h3, h4, h5, h6) { margin-block: 1.5em 0; color: var(--text); font-weight: var(--font-weight-strong); line-height: var(--prose-heading-line-height); } .prose :where(p, li, blockquote) { text-wrap: pretty; } .prose > :first-child { margin-block-start: 0; } .prose h1 { font-size: var(--prose-h1); } .prose h2 { font-size: var(--prose-h2); } .prose h3 { font-size: var(--prose-h3); } .prose h4 { font-size: var(--prose-h4); } .prose a { color: var(--primary); text-decoration-line: underline; text-decoration-thickness: 0.08em; text-underline-offset: 0.18em; } @media (hover: hover) { .prose a:hover { text-decoration-thickness: 0.12em; } @supports (color: color-mix(in oklch, red, white)) { .prose a:hover { color: color-mix(in oklch, var(--primary), var(--text) 15%); } } } .prose :where(ul, ol) { padding-inline-start: 1.5em; } .prose li + li { margin-block-start: 0.35em; } .prose code { padding: 0.15em 0.3em; border-radius: var(--radius-sm); background: var(--surface-subtle); color: var(--text); font-size: 0.875em; } .prose kbd { display: inline-flex; align-items: center; justify-content: center; min-inline-size: 1.75em; min-block-size: 1.6em; padding-inline: 0.45em; border: var(--border-width) solid var(--border); border-block-end-width: calc(var(--border-width) * 2); border-radius: var(--radius-sm); background: var(--surface-raised); color: var(--text); font-family: var(--font-mono); font-size: 0.875em; font-weight: var(--font-weight-medium); line-height: 1; white-space: nowrap; vertical-align: 0.08em; } .prose pre { overflow-x: auto; padding: 1em; border: var(--border-width) solid var(--border); border-radius: var(--radius); background: var(--surface-subtle); } .prose pre code { padding: 0; background: transparent; } .prose blockquote { padding-inline-start: 1em; border-inline-start: var(--border-width) solid var(--border); color: var(--text-muted); } .prose figure { margin-inline: 0; } .prose figcaption { margin-block-start: 0.5em; color: var(--text-muted); font-size: 0.875em; } .prose table { inline-size: 100%; border-collapse: collapse; } .prose th, .prose td { padding: 0.5em; border-block-end: var(--border-width) solid var(--border); text-align: start; } .lead { font-size: 1.125em; line-height: var(--line-height-relaxed); } .measure { max-inline-size: var(--prose-measure, 70ch); } .prose.sm { --prose-size: 0.9375rem; --prose-h1: 1.75rem; --prose-h2: 1.375rem; --prose-h3: 1.125rem; --prose-h4: 1rem; } .prose.lg { --prose-size: 1.125rem; --prose-measure: 72ch; --prose-h1: 2.25rem; --prose-h2: 1.625rem; --prose-h3: 1.375rem; --prose-h4: 1.25rem; } :where(.btn) { --intent: initial; --intent-fg: initial; --ui-bg: initial; --ui-fg: initial; --ui-border: initial; --ui-hover-bg: initial; } .btn { --btn-font-size: var(--control-font-size); --btn-min-size: var(--control-size); --btn-pad-x: var(--control-pad-x, 1em); --btn-bg: var(--ui-bg, var(--btn-default-bg, var(--intent, var(--neutral)))); --btn-fg: var(--ui-fg, var(--btn-default-fg, var(--intent-fg, var(--neutral-fg)))); --btn-border: var(--ui-border, var(--btn-default-border, transparent)); --btn-radius: var(--radius); --btn-focus-color: var(--intent, var(--focus)); --btn-hover-bg: var(--ui-hover-bg, var(--btn-bg)); --btn-hover-overlay: var(--hover-overlay, rgb(0 0 0 / 0.08)); position: relative; display: inline-flex; align-items: center; justify-content: center; gap: 0.375em; min-block-size: var(--btn-min-size); padding-block: var(--space-2); padding-block: max(var(--space-1), calc((var(--btn-min-size) - 1lh) / 2)); padding-inline: var(--btn-pad-x); border: var(--border-width) solid var(--btn-border-color, var(--btn-border)); border-block-end-color: var( --btn-border-block-end-color, var(--btn-border-color, var(--btn-border)) ); border-block-end-width: var(--btn-border-block-end-width, var(--border-width)); border-radius: var(--btn-radius); background: var(--btn-bg); color: var(--btn-fg); font: inherit; font-size: var(--btn-font-size); font-weight: var(--font-weight-medium); line-height: 1; text-decoration: none; cursor: pointer; transition: background-color var(--duration), border-color var(--duration), color var(--duration), box-shadow var(--duration), transform var(--duration); } @supports (color: color-mix(in oklch, red, white)) { .btn { --btn-focus-ring-color: color-mix(in oklch, var(--btn-focus-color) 28%, transparent); } } .btn.ghost { --ui-bg: transparent; --ui-fg: var(--intent, var(--text)); --ui-border: transparent; } .btn.outline, .btn.ghost, .btn.link { --btn-hover-overlay: transparent; } @media (hover: hover) { .btn:not(:where(:disabled, [aria-disabled="true"])):hover { background: var(--btn-hover-bg); box-shadow: inset 0 0 0 999px var(--btn-hover-overlay); } } .btn:not(:where(:disabled, [aria-disabled="true"])):active { transform: translateY(1px); } .btn.link { --ui-bg: transparent; --ui-fg: var(--intent, var(--text)); --ui-border: transparent; --btn-radius: var(--radius-sm); --btn-border-block-end-color: transparent; --btn-border-block-end-width: var(--border-width); min-block-size: auto; padding-inline: 0; border-color: transparent; text-decoration: underline; text-underline-offset: 0.18em; } @media (hover: hover) { .btn.link:not(:where(:disabled, [aria-disabled="true"])):hover { background: transparent; color: var(--intent, var(--text)); text-decoration-thickness: 0.12em; } } .btn:focus-visible { outline: none; box-shadow: 0 0 0 var(--focus-ring-width) var(--btn-focus-ring-color, var(--focus-ring)); } .btn.link:focus-visible { outline: var(--focus-outline); outline-offset: 0.2em; box-shadow: none; } .btn:disabled { cursor: not-allowed; opacity: var(--disabled-opacity); } a.btn[aria-disabled="true"] { cursor: not-allowed; opacity: var(--disabled-opacity); pointer-events: none; } .btn[aria-busy="true"]:not(:disabled) { cursor: progress; } .btn[aria-busy="true"] > .spinner { --spinner-width: 0.15em; } .btn:is([aria-pressed="true"], [aria-current]:not([aria-current="false"])):not(.link) { --btn-bg: var(--intent, var(--primary)); --btn-fg: var(--intent-fg, var(--primary-fg)); --btn-border: var(--intent, var(--primary)); --ui-hover-bg: var(--btn-bg); } @media (forced-colors: active) { .btn { border-color: ButtonText; background: ButtonFace; color: ButtonText; box-shadow: none; } .btn.link { border-color: transparent; background: Canvas; color: LinkText; } .btn:is([aria-pressed="true"], [aria-current]:not([aria-current="false"])):not(.link) { border-color: Highlight; background: Highlight; color: HighlightText; forced-color-adjust: none; } @media (hover: hover) { .btn:hover:not(:where(:disabled, [aria-disabled="true"], .link)) { outline: var(--border-width) solid ButtonText; outline-offset: 2px; } } .btn:disabled, a.btn[aria-disabled="true"] { border-color: GrayText; background: Canvas; color: GrayText; forced-color-adjust: auto; } } :where(.badge) { --intent: initial; --intent-fg: initial; --ui-bg: initial; --ui-fg: initial; --ui-border: initial; --ui-hover-bg: initial; } .badge { --badge-size: var(--variant-compact-size, 1.5rem); --badge-pad-x: 0.55em; --badge-font-size: var(--variant-compact-font-size, 0.8125rem); --badge-dot-size: 0.5rem; --badge-bg: var(--ui-bg, transparent); --badge-fg: var(--ui-fg, var(--intent, var(--text))); --badge-border: var(--ui-border, var(--intent, var(--border))); --badge-radius: 999px; display: inline-flex; align-items: center; justify-content: center; gap: 0.35em; min-block-size: var(--badge-size); padding-inline: var(--badge-pad-x); border: var(--border-width) solid var(--badge-border); border-radius: var(--badge-radius); background: var(--badge-bg); color: var(--badge-fg); font-size: var(--badge-font-size); font-weight: var(--font-weight-strong); line-height: 1; text-decoration: none; white-space: nowrap; transition: background-color var(--duration), border-color var(--duration), color var(--duration), box-shadow var(--duration); } @supports (color: color-mix(in oklch, red, white)) { .badge:where(:not(.solid, .outline)) { --badge-bg: color-mix( in oklch, var(--surface) var(--soft-bg-mix), var(--intent, var(--neutral)) ); --badge-fg: var(--intent, var(--text)); --badge-border: color-mix( in oklch, var(--surface) var(--soft-border-mix), var(--intent, var(--neutral)) ); } } .badge:empty { --badge-size: var(--badge-dot-size); --badge-bg: var(--intent, var(--neutral)); --badge-fg: var(--intent-fg, var(--neutral-fg)); --badge-border: transparent; padding: 0; border: 0; inline-size: var(--badge-size); block-size: var(--badge-size); } .badge > button { display: inline-grid; place-items: center; flex: 0 0 auto; min-inline-size: 1.5rem; min-block-size: 1.5rem; margin-block: -0.25rem; margin-inline-start: -0.15em; margin-inline-end: -0.45em; padding: 0.25rem; border: 0; border-radius: var(--radius-full); background: transparent; color: inherit; font: inherit; line-height: 1; cursor: pointer; } @media (hover: hover) { .badge > button:not(:disabled):hover { background: var(--hover-overlay); } } @media (hover: hover) { :where(a.badge, button.badge):not(:where(:disabled, [aria-disabled="true"])):hover { background: var(--ui-hover-bg, var(--badge-bg)); } :where(a.badge, button.badge):not(:where(:disabled, [aria-disabled="true"], .outline)):hover { box-shadow: inset 0 0 0 999px var(--hover-overlay); } } button.badge { cursor: pointer; font: inherit; } button.badge:disabled, .badge[aria-disabled="true"] { opacity: var(--disabled-opacity); cursor: not-allowed; } a.badge[aria-disabled="true"] { pointer-events: none; } @media (forced-colors: active) { .badge { border-color: ButtonText; background: Canvas; color: CanvasText; box-shadow: none; } .badge:empty { background: ButtonText; } @media (hover: hover) { :where(a.badge, button.badge):hover:not(:where(:disabled, [aria-disabled="true"])) { outline: var(--border-width) solid ButtonText; outline-offset: 2px; } .badge > button:not(:disabled):hover { outline: var(--border-width) solid currentColor; outline-offset: 1px; } } button.badge:disabled, .badge[aria-disabled="true"] { border-color: GrayText; background: Canvas; color: GrayText; } } :where(.alert) { --intent: initial; --intent-fg: initial; --ui-bg: initial; --ui-fg: initial; --ui-border: initial; --ui-hover-bg: initial; } .alert { --alert-pad-block: var(--variant-pad-block, var(--space-3)); --alert-pad-inline: var(--space-4); --alert-font-size: var(--variant-font-size, var(--font-size-md)); --alert-icon-size: var(--variant-icon-size, 1.25rem); --alert-bg: var(--surface-subtle); --alert-border: var(--border); --ui-bg: var(--alert-bg); --ui-border: var(--alert-border); --ui-fg: var(--intent, var(--text)); padding-block: var(--alert-pad-block); padding-inline: var(--alert-pad-inline); background: var(--ui-bg, transparent); color: var(--ui-fg, var(--text)); border: var(--border-width) solid var(--ui-border, var(--border)); border-inline-start-color: var( --alert-border-inline-start-color, var(--ui-border, var(--border)) ); border-inline-start-width: var(--alert-border-inline-start-width, var(--border-width)); border-radius: var(--radius-lg); font-size: var(--alert-font-size); } .alert > * { min-inline-size: 0; } .alert > :first-child { margin-block-start: 0; } .alert > :last-child { margin-block-end: 0; } .alert.solid { --ui-bg: var(--intent, var(--neutral)); --ui-fg: var(--intent-fg, var(--neutral-fg)); --ui-border: transparent; } .alert.outline { --ui-bg: transparent; --ui-fg: var(--intent, var(--text)); --ui-border: var(--intent, var(--border)); } @supports (color: color-mix(in oklch, red, white)) { .alert:where(:not(.solid, .outline, .callout)) { --ui-bg: color-mix(in oklch, var(--surface) var(--soft-bg-mix), var(--intent, var(--neutral))); --ui-border: color-mix( in oklch, var(--surface) var(--soft-border-mix), var(--intent, var(--neutral)) ); } } .alert > :first-child[aria-hidden="true"] { display: inline-block; flex: none; inline-size: var(--alert-icon-size); block-size: var(--alert-icon-size); font-size: var(--alert-icon-size); line-height: 1; vertical-align: -0.125em; } @supports selector(.alert:has(> *)) { .alert:has(> :first-child[aria-hidden="true"]) { display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: var(--items-align, start); column-gap: var(--space-3); } .alert:has(> :first-child[aria-hidden="true"]) > :first-child { grid-column: 1; grid-row: 1 / -1; display: inline-grid; place-items: center; inline-size: var(--alert-icon-size); block-size: var(--alert-icon-size); margin-block-start: 0.125em; font-size: var(--alert-icon-size); line-height: 1; } .alert:has(> :first-child[aria-hidden="true"]) > :first-child:is(svg, i) { inline-size: var(--alert-icon-size); block-size: var(--alert-icon-size); } .alert:has(> :first-child[aria-hidden="true"]) > :not(:first-child) { grid-column: 2; } } .alert :where(a:not(.btn)) { color: inherit; font-weight: var(--font-weight-strong); } .alert.callout { --alert-bg: var(--surface-subtle); --ui-bg: var(--alert-bg); --ui-fg: var(--text); --ui-border: var(--border); position: relative; padding-inline-start: calc(var(--alert-pad-inline) + var(--space-3)); } .alert.callout::before { content: ""; position: absolute; inset-block: var(--space-2); inset-inline-start: var(--space-2); inline-size: 0.25rem; border-radius: var(--radius-full); background: var(--intent, var(--neutral)); } .alert.admonition { padding: 0; gap: 0; display: block; overflow: clip; } .alert-title { padding-block: var(--alert-pad-block); padding-inline: var(--alert-pad-inline); @supports (color: color-mix(in oklch, red, white)) { background: color-mix( in oklch, var(--surface) var(--soft-bg-mix), var(--intent, var(--neutral)) ); } @supports not (color: color-mix(in oklch, red, white)) { background: var(--intent, var(--neutral)); } border-start-start-radius: calc(var(--radius-lg) - var(--border-width)); border-start-end-radius: calc(var(--radius-lg) - var(--border-width)); } .alert-title:where(summary) { cursor: pointer; user-select: none; list-style: none; } .alert-title:where(summary)::-webkit-details-marker { display: none; } .alert-title[aria-hidden] { display: inline-flex; gap: var(--space-2); align-items: center; } .alert-body { padding-block: var(--alert-pad-block); padding-inline: var(--alert-pad-inline); color: var(--text); } .alert-body > :first-child { margin-block-start: 0; } .alert-body > :last-child { margin-block-end: 0; } details.alert.admonition[open] .alert-title { border-end-start-radius: 0; border-end-end-radius: 0; } .actions { --gap: var(--space-2); display: flex; flex-wrap: wrap; align-items: center; gap: var(--gap); margin: 0; padding: 0; list-style: none; } .actions > li { margin: 0; } :where(.card) { --intent: initial; --intent-fg: initial; --ui-bg: initial; --ui-fg: initial; --ui-border: initial; --ui-hover-bg: initial; } .card { --card-pad: var(--space-4); --card-radius: var(--radius-lg); --card-max-inline-size: none; max-inline-size: var(--card-max-inline-size); padding: var(--card-pad); background: var(--ui-bg, var(--surface)); color: var(--ui-fg, var(--text)); border: var(--border-width) solid var(--ui-border, var(--border)); border-radius: var(--card-radius); } .card > * { min-inline-size: 0; } .card > :where(header, footer) { display: flex; flex-wrap: wrap; align-items: var(--items-align, center); justify-content: space-between; gap: var(--space-3); min-inline-size: 0; } .card > :where(header, footer) > * { min-inline-size: 0; margin-block: 0; } .card > header { align-items: var(--items-align, flex-start); } .card > :first-child { margin-block-start: 0; } .card > :last-child { margin-block-end: 0; } .card.raised { box-shadow: var(--shadow); } .card.subtle { background: var(--surface-subtle); } .card.inverted { background: var(--surface-solid); color: var(--surface); border-color: transparent; --heading: var(--surface); --busy-overlay-bg: var(--surface-solid); } .card.compact { --card-pad: var(--space-2); } .card > .bleed { margin-inline: calc(var(--card-pad) * -1); max-inline-size: none; } .card > .bleed:first-child { margin-block-start: calc(var(--card-pad) * -1); border-start-start-radius: inherit; border-start-end-radius: inherit; } .card > .bleed:last-child { margin-block-end: calc(var(--card-pad) * -1); border-end-start-radius: inherit; border-end-end-radius: inherit; } .card > :where(img, picture, video, canvas, svg).bleed { display: block; inline-size: calc(100% + var(--card-pad) * 2); max-inline-size: none; } .card > picture.bleed { overflow: hidden; } .card > picture.bleed > img { display: block; inline-size: 100%; block-size: auto; } .card > :where(header, footer, figure).bleed { padding: var(--card-pad); } @media (forced-colors: active) { .card { border-color: ButtonText; background: Canvas; color: CanvasText; } .card.raised { box-shadow: none; } .card.inverted { --heading: CanvasText; border-color: ButtonText; background: Canvas; color: CanvasText; } } .surface-backdrop { position: fixed; inset: 0; z-index: calc(var(--z-menu) - 1); background: var(--backdrop-fill); opacity: 1; transition: opacity var(--duration) var(--ease, ease); } .surface-backdrop[hidden] { display: none; opacity: 0; } @starting-style { .surface-backdrop:not([hidden]) { opacity: 0; } } @supports (transition-behavior: allow-discrete) { .surface-backdrop { transition: opacity var(--duration) var(--ease, ease), display var(--duration) allow-discrete; } } @media (forced-colors: active) { .surface-backdrop { background: Canvas; } } dialog.modal { --modal-size: 32rem; max-inline-size: min(100% - 2rem, var(--modal-size)); max-block-size: calc(var(--viewport-block) - 2rem); border: var(--border-width) solid var(--border); border-radius: var(--radius-lg); background: var(--surface-raised); color: var(--text); box-shadow: var(--shadow); padding: 0; overflow: visible; opacity: 0; transform: translateY(0.35rem) scale(0.98); transition: opacity var(--duration), transform var(--duration); } dialog.modal > form, dialog.modal > .stack { display: grid; gap: var(--space-4); max-block-size: calc(var(--viewport-block) - 2rem); overflow: auto; overscroll-behavior: contain; padding: var(--space-4); } dialog.modal.scrollable > form, dialog.modal.scrollable > .stack { grid-template-rows: auto minmax(0, 1fr) auto; overflow: hidden; } dialog.modal.scrollable > form > :not(header, footer), dialog.modal.scrollable > .stack > :not(header, footer) { min-block-size: 0; overflow: auto; overscroll-behavior: contain; } dialog.modal header > :first-child, dialog.modal footer > :first-child { margin-block-start: 0; } dialog.modal header > :last-child, dialog.modal footer > :last-child { margin-block-end: 0; } dialog.modal footer { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: var(--gap); } dialog.modal[open] { opacity: 1; transform: none; } @starting-style { dialog.modal[open] { opacity: 0; transform: translateY(0.35rem) scale(0.98); } } dialog.modal::backdrop { background: var(--backdrop-fill); opacity: 0; transition: opacity var(--duration); } @supports (transition-behavior: allow-discrete) { dialog.modal { transition: opacity var(--duration), transform var(--duration), overlay var(--duration) allow-discrete, display var(--duration) allow-discrete; } dialog.modal::backdrop { transition: opacity var(--duration), overlay var(--duration) allow-discrete, display var(--duration) allow-discrete; } } dialog.modal[open]::backdrop { opacity: 1; } html.has-modal-open { overflow: hidden; } html.has-modal-open.had-scrollbar { scrollbar-gutter: stable; } @starting-style { dialog.modal[open]::backdrop { opacity: 0; } } @media (prefers-reduced-motion: no-preference) { dialog.modal.is-static { animation: actual-modal-static 180ms var(--ease); } ::view-transition-group(actual-dialog) { animation-duration: var(--duration); animation-timing-function: var(--ease); } } @keyframes actual-modal-static { 0%, 100% { transform: none; } 35% { transform: translateX(-0.35rem); } 70% { transform: translateX(0.35rem); } } @media (forced-colors: active) { dialog.modal { border-color: ButtonText; background: Canvas; color: CanvasText; box-shadow: none; } dialog.modal::backdrop { background: Canvas; } } dialog.drawer { --drawer-size: 20rem; --drawer-pad: var(--space-4); --drawer-closed-translate: -100%; inline-size: min(calc(var(--viewport-inline) * 0.9), var(--drawer-size)); block-size: var(--viewport-block); max-inline-size: none; max-block-size: var(--viewport-block); margin: 0; padding: var(--drawer-pad); border: 0; border-inline-end: var(--border-width) solid var(--border); border-radius: 0; background: var(--surface-raised); color: var(--text); box-shadow: var(--shadow); opacity: 0; transform: translateX(var(--drawer-closed-translate)); transition: opacity var(--duration-slow), transform var(--duration-slow); } dialog.drawer[open] { display: grid; grid-template-rows: auto minmax(0, 1fr) auto; gap: var(--space-4); opacity: 1; transform: translateX(0); } dialog.drawer::backdrop { background: var(--backdrop-fill); opacity: 0; transition: opacity var(--duration-slow); } dialog.drawer[data-side="end"] { --drawer-closed-translate: 100%; margin-inline-start: auto; margin-inline-end: 0; border-inline-end: 0; border-inline-start: var(--border-width) solid var(--border); } dialog.drawer[open]::backdrop { opacity: 1; } @starting-style { dialog.drawer[open] { opacity: 0; transform: translateX(var(--drawer-closed-translate)); } dialog.drawer[open]::backdrop { opacity: 0; } } dialog.drawer nav { min-block-size: 0; overflow-y: auto; } @supports (transition-behavior: allow-discrete) { dialog.drawer { transition: opacity var(--duration-slow), transform var(--duration-slow), overlay var(--duration-slow) allow-discrete, display var(--duration-slow) allow-discrete; } dialog.drawer::backdrop { transition: opacity var(--duration-slow), overlay var(--duration-slow) allow-discrete, display var(--duration-slow) allow-discrete; } } [dir="rtl"] dialog.drawer { --drawer-closed-translate: 100%; } [dir="rtl"] dialog.drawer[data-side="end"] { --drawer-closed-translate: -100%; } @media (forced-colors: active) { dialog.drawer { border-inline-end-color: ButtonText; background: Canvas; color: CanvasText; box-shadow: none; } dialog.drawer[data-side="end"] { border-inline-start-color: ButtonText; } dialog.drawer::backdrop { background: Canvas; } } .flyout-trigger { position: relative; display: inline-block; } .flyout-trigger.stretch { display: block; inline-size: 100%; } .flyout-trigger.stretch > [aria-haspopup="menu"] { inline-size: 100%; } .flyout { z-index: var(--z-menu); position: absolute; inset-block-start: calc(100% + var(--space-1)); inset-inline-start: 0; display: grid; gap: var(--space-1); inline-size: var(--flyout-inline-size, max-content); min-inline-size: min( var(--flyout-trigger-width, 0px), min(var(--flyout-max-inline-size, 20rem), calc(var(--viewport-inline) - var(--space-6))) ); max-inline-size: min( var(--flyout-max-inline-size, 20rem), calc(var(--viewport-inline) - var(--space-6)) ); max-block-size: min(24rem, var(--available-height, calc(var(--viewport-block) - var(--space-6)))); overflow: auto; margin: 0; padding: var(--space-1); border: var(--border-width) solid var(--border); border-radius: var(--radius); background: var(--surface-raised); box-shadow: var(--shadow-popout); list-style: none; opacity: 1; scale: 1; transition: opacity var(--duration-fast, var(--duration)) var(--ease, ease), scale var(--duration-fast, var(--duration)) var(--ease, ease), translate var(--duration-fast, var(--duration)) var(--ease, ease); } .flyout.is-open:not(.is-sheet) { inset: auto; } @starting-style { .flyout.is-open { opacity: 0; scale: 0.98; } } .flyout.is-sheet { position: fixed; inset-inline: 0; inset-block-start: auto; inset-block-end: 0; inline-size: auto; min-inline-size: 0; max-inline-size: none; max-block-size: min(calc(var(--viewport-block) * 0.75), 32rem); overflow: auto; grid-template-columns: 1fr; padding: max(var(--space-3), env(safe-area-inset-top)) var(--space-3) max(var(--space-3), env(safe-area-inset-bottom)); border-end-start-radius: 0; border-end-end-radius: 0; } .flyout[hidden] { display: none; opacity: 0; scale: 0.98; } .flyout.is-sheet[hidden] { scale: 1; translate: 0 var(--space-3); } @starting-style { .flyout.is-sheet.is-open { scale: 1; translate: 0 var(--space-3); } } @supports (transition-behavior: allow-discrete) { .flyout { transition: opacity var(--duration-fast, var(--duration)) var(--ease, ease), scale var(--duration-fast, var(--duration)) var(--ease, ease), translate var(--duration-fast, var(--duration)) var(--ease, ease), display var(--duration-fast, var(--duration)) allow-discrete; } } .flyout > li { margin: 0; } .flyout > :where(section, footer) { min-inline-size: 0; padding: var(--space-2); } .flyout > section > :where(h1, h2, h3, h4, h5, h6) { margin: 0; color: var(--text-muted); font-size: var(--font-size-xs); font-weight: var(--font-weight-strong); } .flyout > section > ul { display: grid; gap: var(--space-1); margin: var(--space-1) 0 0; padding: 0; list-style: none; } .flyout > section > ul > li { margin: 0; } :is(.flyout, .flyout :where(li)) > :where(button, a, [role="menuitem"]) { display: flex; align-items: center; justify-content: flex-start; gap: var(--space-2); inline-size: 100%; min-block-size: var(--control-size); padding-inline: var(--space-2); border: 0; border-radius: var(--radius-sm); background: none; color: var(--text); font: inherit; font-weight: var(--font-weight); text-decoration: none; text-align: start; white-space: nowrap; cursor: pointer; } :is(.flyout.is-sheet, .flyout.is-sheet :where(li)) > :where(button, a, [role="menuitem"]) { min-block-size: var(--control-size-lg); } :is(.flyout, .flyout :where(li)) > :where(button, a, [role="menuitem"]):focus-visible { background: var(--surface-subtle); outline: var(--focus-outline); outline-offset: var(--focus-outline-offset); } :is(.flyout, .flyout :where(li)) > :where(button, a, [role="menuitem"]):is(:disabled, [aria-disabled="true"]) { cursor: not-allowed; opacity: var(--disabled-opacity); } :is(.flyout, .flyout :where(li)) > :where(a, [role="menuitem"])[aria-disabled="true"] { pointer-events: none; } @media (hover: hover) { :is(.flyout, .flyout :where(li)) > :where(button, a, [role="menuitem"]):hover:not( :where(:focus-visible, :disabled, [aria-disabled="true"]) ) { background: var(--surface-subtle); outline: none; } } .flyout > hr, .flyout > li > hr { inline-size: 100%; margin: 0; margin-block: var(--space-1); border: 0; border-block-start: var(--border-width) solid var(--border); } @media (forced-colors: active) { .flyout { border-color: ButtonText; background: Canvas; color: CanvasText; box-shadow: none; } :is(.flyout, .flyout :where(li)) > :where(button, a, [role="menuitem"]):focus-visible { background: Canvas; color: CanvasText; } @media (hover: hover) { :is(.flyout, .flyout :where(li)) > :where(button, a, [role="menuitem"]):hover:not(:where(:disabled, [aria-disabled="true"])) { outline: var(--border-width) solid ButtonText; outline-offset: -1px; background: Canvas; color: CanvasText; } } } .tooltip { --tooltip-bg: var(--surface-solid); --tooltip-fg: var(--surface); --tooltip-arrow-size: 5px; position: fixed; z-index: var(--z-tooltip); max-inline-size: min(24rem, calc(var(--viewport-inline) - 2rem)); padding: 0.25em 0.6em; border-radius: var(--radius-sm); background: var(--tooltip-bg); color: var(--tooltip-fg); font-size: var(--font-size-xs); line-height: var(--line-height-tight); overflow-wrap: anywhere; pointer-events: auto; user-select: none; opacity: 1; scale: 1; transition: opacity var(--duration-fast, var(--duration)) var(--ease, ease), scale var(--duration-fast, var(--duration)) var(--ease, ease); } .tooltip[hidden] { display: none; opacity: 0; scale: 0.96; } @starting-style { .tooltip:not([hidden]) { opacity: 0; scale: 0.96; } } @supports (transition-behavior: allow-discrete) { .tooltip { transition: opacity var(--duration-fast, var(--duration)) var(--ease, ease), scale var(--duration-fast, var(--duration)) var(--ease, ease), display var(--duration-fast, var(--duration)) allow-discrete; } } .tooltip::before { content: ""; position: absolute; inline-size: calc(var(--tooltip-arrow-size) * 2); block-size: var(--tooltip-arrow-size); background: var(--tooltip-bg); } .tooltip[data-placement^="top"]::before { bottom: calc(-0.98 * var(--tooltip-arrow-size)); left: var(--arrow-x, 50%); translate: -50% 0; clip-path: polygon(50% 100%, 0 0, 100% 0); } .tooltip[data-placement^="bottom"]::before { top: calc(-0.98 * var(--tooltip-arrow-size)); left: var(--arrow-x, 50%); translate: -50% 0; clip-path: polygon(50% 0, 0 100%, 100% 100%); } .tooltip[data-placement^="left"]::before { right: calc(-0.98 * var(--tooltip-arrow-size)); top: var(--arrow-y, 50%); inline-size: var(--tooltip-arrow-size); block-size: calc(var(--tooltip-arrow-size) * 2); translate: 0 -50%; clip-path: polygon(100% 50%, 0 0, 0 100%); } .tooltip[data-placement^="right"]::before { left: calc(-0.98 * var(--tooltip-arrow-size)); top: var(--arrow-y, 50%); inline-size: var(--tooltip-arrow-size); block-size: calc(var(--tooltip-arrow-size) * 2); translate: 0 -50%; clip-path: polygon(0 50%, 100% 0, 100% 100%); } @media (forced-colors: active) { .tooltip { --tooltip-bg: Canvas; --tooltip-fg: CanvasText; border: var(--border-width) solid ButtonText; } .tooltip::before { display: none; } } .accordion { --accordion-radius: var(--radius); border: var(--border-width) solid var(--border); border-radius: var(--accordion-radius); background: var(--surface-raised); } .accordion > details + details { border-block-start: var(--border-width) solid var(--border); } .accordion summary { display: flex; align-items: center; gap: var(--space-3); cursor: pointer; list-style: none; padding: var(--space-4); color: var(--text); font-weight: var(--font-weight-bold); } .accordion summary::-webkit-details-marker { display: none; } .accordion summary::after { content: ""; flex: 0 0 auto; margin-inline-start: auto; inline-size: 1rem; block-size: 1rem; background-color: var(--text-muted); -webkit-mask-image: var(--icon-chevron-mask); mask-image: var(--icon-chevron-mask); -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat; -webkit-mask-size: contain; mask-size: contain; -webkit-mask-position: center; mask-position: center; transition: transform var(--duration); } .accordion details[open] summary::after { transform: rotate(180deg); } .accordion details > summary + * { padding-block: 0 var(--space-4); padding-inline: var(--space-4); color: var(--text-muted); margin-block: 0; } .accordion details[open] > summary + * { padding-block-start: var(--space-1); } .accordion details > summary + * > :first-child { margin-block-start: 0; } .accordion details > summary + ul, .accordion details > summary + ol { margin: 0; padding-inline-start: 2rem; } @media (forced-colors: active) { .accordion { border-color: ButtonText; background: Canvas; color: CanvasText; } .accordion > details + details { border-block-start-color: ButtonText; } .accordion summary { color: CanvasText; } .accordion summary::after { background-color: ButtonText; forced-color-adjust: none; } } :where(.spinner) { --intent: initial; --intent-fg: initial; --ui-bg: initial; --ui-fg: initial; --ui-border: initial; --ui-hover-bg: initial; } .spinner { --spinner-size: 1em; --spinner-width: 0.125em; --spinner-track: currentColor; --spinner-value: transparent; color: var(--intent, currentColor); display: inline-block; flex-shrink: 0; inline-size: var(--spinner-size); block-size: var(--spinner-size); border: var(--spinner-width) solid var(--spinner-track); border-inline-end-color: var(--spinner-value); border-radius: var(--radius-full); opacity: 0.85; animation: actual-spin var(--duration-spin) linear infinite; vertical-align: text-bottom; } @supports (color: color-mix(in oklch, red, white)) { .spinner { --spinner-track: color-mix(in oklch, currentColor, transparent 70%); --spinner-value: currentColor; opacity: 1; } } .spinner.sm { --spinner-size: 0.75em; } .spinner.lg { --spinner-size: 2rem; --spinner-width: 3px; } @keyframes actual-spin { to { transform: rotate(360deg); } } .skeleton { --skeleton-size: 1rem; --skeleton-width: 100%; --skeleton-radius: var(--radius); --skeleton-track: var(--surface-subtle); --skeleton-highlight: var(--surface-raised); display: block; inline-size: var(--skeleton-width); max-inline-size: 100%; block-size: var(--skeleton-size); border-radius: var(--skeleton-radius); background: linear-gradient(90deg, var(--skeleton-track), var(--skeleton-highlight), var(--skeleton-track)) 0 0 / 200% 100%; } @media (prefers-reduced-motion: no-preference) { .skeleton { animation: actual-skeleton var(--duration-shimmer) ease-in-out infinite; } } .skeleton[data-shape="text"] { --skeleton-size: 0.85rem; --skeleton-width: 32rem; } .skeleton[data-shape="title"] { --skeleton-size: 1.4rem; --skeleton-width: 18rem; } .skeleton[data-shape="avatar"] { --skeleton-size: var(--avatar-size, 2.25rem); --skeleton-width: var(--skeleton-size); --skeleton-radius: var(--radius-full); flex: 0 0 auto; } .skeleton[data-shape="box"] { --skeleton-size: 8rem; } @media (forced-colors: active) { .skeleton { border: var(--border-width) solid ButtonText; background: GrayText; } } @keyframes actual-skeleton { from { background-position: 200% 0; } to { background-position: -200% 0; } } [aria-busy] > .spinner:last-child { display: none; } [aria-busy="true"] > .spinner:last-child { display: inline-block; } @supports selector([aria-busy="true"]:has(> .spinner:last-child)) { [aria-busy="true"]:not(.btn):has(> .spinner:last-child) { position: relative; } [aria-busy="true"]:not(.btn):has(> .spinner:last-child)::before { content: ""; position: absolute; inset: 0; z-index: 1; border-radius: inherit; background: var(--busy-overlay-bg, var(--surface)); } [aria-busy="true"]:not(.btn) > .spinner:last-child { --spinner-size: 2rem; position: absolute; inset: 0; z-index: 2; margin: auto; display: block; } } @supports (selector([aria-busy="true"]:has(> .spinner:last-child))) and (color: color-mix(in oklch, red, white)) { [aria-busy="true"]:not(.btn):has(> .spinner:last-child)::before { background: color-mix(in oklch, var(--busy-overlay-bg, var(--surface)), transparent 20%); } } :where(.progress) { --intent: initial; --intent-fg: initial; --ui-bg: initial; --ui-fg: initial; --ui-border: initial; --ui-hover-bg: initial; } .progress { --progress-track: var(--surface-subtle); --progress-value: var(--intent, var(--primary)); } .progress { appearance: none; -webkit-appearance: none; display: block; inline-size: 100%; block-size: var(--bar-height); overflow: hidden; border: 0; border-radius: var(--radius-full); background: var(--progress-track); } .progress::-webkit-progress-bar { block-size: var(--bar-height); border-radius: var(--radius-full); background: var(--progress-track); } .progress::-webkit-progress-value { block-size: var(--bar-height); border-radius: var(--radius-full); background: var(--progress-value); } .progress::-moz-progress-bar { block-size: var(--bar-height); border-radius: var(--radius-full); background: var(--progress-value); } .progress:indeterminate { background: linear-gradient(to right, var(--progress-value) 30%, var(--progress-track) 30%) top left / 150% 150% no-repeat, var(--progress-track); } .progress:indeterminate::-webkit-progress-bar { background: transparent; } .progress:indeterminate::-webkit-progress-value { background: transparent; } .progress:indeterminate::-moz-progress-bar { background: transparent; } @media (prefers-reduced-motion: no-preference) { .progress:indeterminate { animation: actual-progress-indeterminate var(--duration-shimmer) ease-in-out infinite; } :where([dir="rtl"] .progress:indeterminate) { animation-direction: reverse; } } @keyframes actual-progress-indeterminate { 0% { background-position: 200% 0; } 20% { background-position: 100% 0; } 80% { background-position: -100% 0; } 100% { background-position: -200% 0; } } @media (forced-colors: active) { .progress { border: var(--border-width) solid ButtonText; background: Canvas; } .progress::-webkit-progress-bar { background: Canvas; } .progress::-webkit-progress-value { background: Highlight; forced-color-adjust: none; } .progress::-moz-progress-bar { background: Highlight; forced-color-adjust: none; } .progress:indeterminate { background: Canvas; } } :where(.status-bar) { --intent: initial; --intent-fg: initial; --ui-bg: initial; --ui-fg: initial; --ui-border: initial; --ui-hover-bg: initial; } .status-bar { --status-bg: var(--intent, var(--text)); --status-fg: var(--intent-fg, var(--surface)); position: fixed; inset-block-end: var(--space-4); inset-inline: var(--space-4); z-index: var(--z-status, 60); display: inline-flex; align-items: center; justify-content: center; gap: var(--space-2); inline-size: fit-content; max-inline-size: min(calc(100vw - var(--space-6)), 32rem); margin-inline: auto; overflow-wrap: anywhere; padding-block: var(--space-2); padding-inline: var(--space-3); border-radius: var(--radius-full); background: var(--status-bg); color: var(--status-fg); box-shadow: var(--shadow-popout); opacity: 1; scale: 1; translate: 0 0; pointer-events: none; transition: opacity var(--duration-slow) var(--ease, ease), scale var(--duration-slow) var(--ease, ease), translate var(--duration-slow) var(--ease, ease); } .status-bar:empty { opacity: 0; scale: 0.96; translate: 0 var(--space-2); pointer-events: none; } @media (forced-colors: active) { .status-bar { border: var(--border-width) solid ButtonText; box-shadow: none; } } :where(.avatar) { --intent: initial; --intent-fg: initial; --ui-bg: initial; --ui-fg: initial; --ui-border: initial; --ui-hover-bg: initial; } .avatar { --avatar-size: var(--avatar-stack-size, 2.25rem); --avatar-radius: var(--radius-full); --avatar-font-size: var(--avatar-stack-font-size, var(--font-size-sm)); --avatar-bg: var(--intent, var(--surface-subtle)); --avatar-fg: var(--intent-fg, var(--tone-fg, var(--text-muted))); position: relative; display: inline-grid; place-items: center; inline-size: var(--avatar-size); block-size: var(--avatar-size); overflow: visible; padding: 0; border: 0; border-radius: var(--avatar-radius); background: var(--avatar-bg); color: var(--avatar-fg); font: inherit; font-size: var(--avatar-font-size); font-weight: var(--font-weight-strong); line-height: 1; text-decoration: none; vertical-align: middle; user-select: none; transition: box-shadow var(--duration), opacity var(--duration), transform var(--duration); } @media (forced-colors: active) { .avatar { border: var(--border-width) solid CanvasText; } :where(a.avatar, button.avatar)::after { display: none; } } .avatar > :first-child:not(:where(img, picture, .badge)) { display: inline-grid; place-items: center; inline-size: 100%; block-size: 100%; overflow: hidden; border-radius: inherit; } .avatar > img, .avatar > picture { display: block; inline-size: 100%; block-size: 100%; overflow: hidden; border-radius: inherit; } .avatar > img, .avatar > picture > img { inline-size: 100%; block-size: 100%; object-fit: cover; border-radius: inherit; } .avatar > picture > img { display: block; } button.avatar { appearance: none; cursor: pointer; } :where(a.avatar, button.avatar)::after { content: ""; position: absolute; inset: 0; border-radius: inherit; background: var(--hover-overlay); opacity: 0; pointer-events: none; transition: opacity var(--duration); } @media (hover: hover) { :where(a.avatar, button.avatar):not(:where(:disabled, [aria-disabled="true"])):hover::after { opacity: 1; } } :where(a.avatar, button.avatar):not(:where(:disabled, [aria-disabled="true"])):active { transform: translateY(1px); } button.avatar:disabled, a.avatar[aria-disabled="true"] { cursor: not-allowed; opacity: var(--disabled-opacity); } a.avatar[aria-disabled="true"] { pointer-events: none; } .avatar.sm { --avatar-stack-size: 1.75rem; --avatar-stack-font-size: var(--font-size-xs); } .avatar.lg { --avatar-stack-size: 3rem; --avatar-stack-font-size: var(--font-size-lg); } .avatar > .badge:empty { --avatar-status-translate-x: 50%; position: absolute; inset-block-end: var(--indicator-offset); inset-inline-end: var(--indicator-offset); z-index: 1; box-shadow: 0 0 0 2px var(--indicator-ring); transform: translate(var(--avatar-status-translate-x), 50%); } .avatar:dir(rtl) > .badge:empty { --avatar-status-translate-x: -50%; } .avatar-stack { --avatar-stack-overlap: calc(var(--avatar-stack-size, 2.25rem) / -4); --avatar-stack-ring: 2px; display: inline-flex; align-items: center; } .avatar-stack.sm { --avatar-stack-size: 1.75rem; --avatar-stack-font-size: var(--font-size-xs); } .avatar-stack.lg { --avatar-stack-size: 3rem; --avatar-stack-font-size: var(--font-size-lg); } @supports selector(:has(> .avatar)) { .avatar-stack:has(> .avatar.sm) { --avatar-stack-size: 1.75rem; --avatar-stack-font-size: var(--font-size-xs); } .avatar-stack:has(> .avatar.lg) { --avatar-stack-size: 3rem; --avatar-stack-font-size: var(--font-size-lg); } } .avatar-stack > .avatar { box-shadow: 0 0 0 var(--avatar-stack-ring) var(--surface); } .avatar-stack > .avatar + .avatar { margin-inline-start: var(--avatar-stack-overlap); } .avatar-stack > .avatar:is(:hover, :focus-visible) { z-index: 1; } .key { display: inline-flex; align-items: center; justify-content: center; min-inline-size: 1.75em; min-block-size: 1.6em; padding-inline: 0.45em; border: var(--border-width) solid var(--border); border-block-end-width: calc(var(--border-width) * 2); border-radius: var(--radius-sm); background: var(--surface-raised); color: var(--text); font-family: var(--font-mono); font-size: 0.875em; font-weight: var(--font-weight-medium); line-height: 1; white-space: nowrap; vertical-align: 0.08em; } :where(.overline) { --intent: initial; --intent-fg: initial; --ui-bg: initial; --ui-fg: initial; --ui-border: initial; --ui-hover-bg: initial; } .overline { align-self: flex-start; color: var(--text-muted); font-size: var(--font-size-sm); font-weight: var(--font-weight-medium); letter-spacing: 0.04em; text-transform: uppercase; } .overline.pill { display: inline-flex; align-items: center; gap: 0.5em; padding-inline: 0.6em; padding-block: 0.25em; color: var(--intent, var(--text-muted)); border: var(--border-width) solid var(--border); border-radius: var(--radius-full); background: var(--surface); } @supports (color: color-mix(in oklch, red, white)) { .overline.pill { border-color: color-mix(in oklch, var(--intent, var(--border)) 35%, var(--border)); background: color-mix(in oklch, var(--intent, transparent) 6%, var(--surface)); } } .navbar { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--gap); padding-block: var(--space-3); padding-inline: var(--space-4); border: var(--border-width) solid var(--border); border-radius: var(--radius-lg); background: var(--surface-raised); color: var(--text); } .navbar-brand { display: inline-flex; align-items: center; gap: var(--space-2); color: var(--text); font-weight: var(--font-weight-bold); text-decoration: none; } .navbar-brand:focus-visible { border-radius: var(--radius-sm); } .navbar-nav { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-1); margin: 0; padding: 0; list-style: none; } .nav-link { display: inline-flex; align-items: center; min-block-size: var(--control-size-sm); padding-inline: var(--space-2); border-radius: var(--radius); color: var(--text-muted); font-weight: var(--font-weight-medium); text-decoration: none; } .nav-link:where([aria-current]:not([aria-current="false"])) { background: var(--surface-subtle); color: var(--text); } @media (hover: hover) { .nav-link:hover { background: var(--surface-subtle); color: var(--text); } } .nav-list { display: grid; gap: var(--gap); margin: 0; padding: 0; list-style: none; --gap: var(--space-2); } .nav-list > li { margin: 0; } @media (forced-colors: active) { .nav-link:where([aria-current]:not([aria-current="false"])) { outline: var(--border-width) solid Highlight; background: Highlight; color: HighlightText; forced-color-adjust: none; } @media (hover: hover) { .nav-link:hover:not(:where([aria-current]:not([aria-current="false"]))) { outline: var(--border-width) solid ButtonText; outline-offset: 2px; background: Canvas; color: CanvasText; } } } .breadcrumb { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-1); margin: 0; padding: 0; color: var(--text-subtle); font-size: var(--font-size-sm); list-style: none; } .breadcrumb li { display: inline-flex; align-items: center; gap: var(--space-1); } .breadcrumb li + li::before { content: "/"; color: var(--text-subtle); } .breadcrumb a { color: var(--text-muted); text-decoration: none; } @media (hover: hover) { .breadcrumb li:not(:where([aria-current]:not([aria-current="false"]))) > a:hover:not(:where([aria-current]:not([aria-current="false"]))) { color: var(--text); text-decoration: underline; } } .breadcrumb a:focus-visible { border-radius: var(--radius-sm); } .breadcrumb a:where([aria-current]:not([aria-current="false"])) { color: var(--text); font-weight: var(--font-weight-medium); } .breadcrumb li:where([aria-current]:not([aria-current="false"])) > :where(a, span) { color: var(--text); font-weight: var(--font-weight-medium); } .pagination { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-1); margin: 0; padding: 0; list-style: none; } .pagination .btn { min-inline-size: var(--control-size); } .pagination > li > [aria-hidden="true"] { display: inline-flex; align-items: center; justify-content: center; min-inline-size: var(--control-size); } :where(.tab) { --intent: initial; --intent-fg: initial; --ui-bg: initial; --ui-fg: initial; --ui-border: initial; --ui-hover-bg: initial; } .tabs { display: flex; flex-wrap: wrap; gap: var(--space-1); margin: 0; padding: 0; border-block-end: var(--border-width) solid var(--border); list-style: none; } .tabs[aria-orientation="vertical"] { display: grid; align-content: start; justify-items: stretch; border-block-end: 0; border-inline-end: var(--border-width) solid var(--border); } .tab { display: inline-flex; align-items: center; min-block-size: var(--control-size); padding-inline: var(--space-3); border: 0; border-block-end: 2px solid transparent; border-radius: 0; background: transparent; color: var(--text-muted); font: inherit; font-weight: var(--font-weight-strong); text-decoration: none; cursor: pointer; } .tabs[aria-orientation="vertical"] .tab { justify-content: flex-start; border-block-end: 0; border-inline-end: 2px solid transparent; padding-inline-end: var(--space-4); } .tab:is(:disabled, [aria-disabled="true"]) { cursor: not-allowed; opacity: var(--disabled-opacity); } @media (hover: hover) { .tab:hover:not(:where(:disabled, [aria-disabled="true"])) { color: var(--text); } } .tab:focus-visible { outline: var(--focus-outline); outline-color: var(--focus); outline-offset: -2px; border-radius: var(--radius-sm) var(--radius-sm) 0 0; } .tab[aria-selected="true"], .tab[aria-current]:not([aria-current="false"]), .tab[aria-pressed="true"] { border-block-end-color: var(--intent, var(--primary)); color: var(--intent, var(--primary)); } .tabs[aria-orientation="vertical"] .tab[aria-selected="true"], .tabs[aria-orientation="vertical"] .tab[aria-current]:not([aria-current="false"]), .tabs[aria-orientation="vertical"] .tab[aria-pressed="true"] { border-block-end-color: transparent; border-inline-end-color: var(--intent, var(--primary)); } @media (forced-colors: active) { .tabs { border-block-end-color: ButtonText; } .tabs[aria-orientation="vertical"] { border-block-end-color: transparent; border-inline-end-color: ButtonText; } .tab { color: ButtonText; } @media (hover: hover) { .tab:hover:not(:where(:disabled, [aria-disabled="true"])) { color: ButtonText; text-decoration: underline; text-underline-offset: 0.18em; } } .tab[aria-selected="true"], .tab[aria-current]:not([aria-current="false"]), .tab[aria-pressed="true"] { border-block-end-color: Highlight; color: Highlight; } .tabs[aria-orientation="vertical"] .tab[aria-selected="true"], .tabs[aria-orientation="vertical"] .tab[aria-current]:not([aria-current="false"]), .tabs[aria-orientation="vertical"] .tab[aria-pressed="true"] { border-block-end-color: transparent; border-inline-end-color: Highlight; } } @supports selector(.scrollspy a:target-current) { .scrollspy { scroll-target-group: auto; } .scrollspy a:target-current { color: var(--text); font-weight: var(--font-weight-medium); } } .table-wrap { inline-size: 100%; max-inline-size: 100%; min-inline-size: 0; overflow-x: auto; border: var(--border-width) solid var(--border); border-radius: var(--radius-lg); background: var(--surface-raised); } .table { --table-min: 100%; --table-cell-pad: var(--space-3); inline-size: max(var(--table-min), 100%); border-collapse: collapse; background: transparent; color: var(--text); font-size: var(--font-size-md); } .table caption { padding: var(--table-cell-pad); color: var(--text-muted); text-align: var(--text-align, start); } .table th, .table td { padding: var(--table-cell-pad); border-block-end: var(--border-width) solid var(--border); text-align: var(--text-align, start); vertical-align: baseline; } .table thead th { vertical-align: bottom; } .table th { color: var(--text-muted); font-weight: var(--font-weight-strong); } .table thead { background: var(--surface-subtle); } @media (hover: hover) { .table tbody tr:hover { background-color: var(--hover-overlay); } } .table > tr:last-child > *, .table > :last-child > tr:last-child > * { border-block-end: 0; } :where(.meter) { --intent: initial; --intent-fg: initial; --ui-bg: initial; --ui-fg: initial; --ui-border: initial; --ui-hover-bg: initial; } .meter { appearance: none; -webkit-appearance: none; display: block; inline-size: 100%; block-size: var(--bar-height); overflow: hidden; border: 0; border-radius: var(--radius-full); background: var(--surface-subtle); } .meter::-webkit-meter-bar { -webkit-appearance: none; block-size: var(--bar-height); border: 0; border-radius: var(--radius-full); background: var(--surface-subtle); } .meter::-webkit-meter-optimum-value { block-size: var(--bar-height); border-radius: var(--radius-full); background: var(--success); } .meter::-webkit-meter-suboptimum-value { block-size: var(--bar-height); border-radius: var(--radius-full); background: var(--warning); } .meter::-webkit-meter-even-less-good-value { block-size: var(--bar-height); border-radius: var(--radius-full); background: var(--danger); } .meter::-moz-meter-bar { block-size: var(--bar-height); border-radius: var(--radius-full); } @media (forced-colors: active) { .meter { border: var(--border-width) solid ButtonText; background: Canvas; } .meter::-webkit-meter-bar { border: 0; background: Canvas; } .meter::-webkit-meter-optimum-value, .meter::-webkit-meter-suboptimum-value, .meter::-webkit-meter-even-less-good-value, .meter::-moz-meter-bar { background: Highlight; forced-color-adjust: none; } } .field { display: grid; gap: var(--space-1); color: var(--text); } .field-group { min-inline-size: 0; margin: 0; padding: var(--space-3); border: var(--border-width) solid var(--border); border-radius: var(--radius); } .field-group + .field-group { margin-block-start: var(--space-4); } .field-label, .field-group > legend { color: var(--text); font-weight: var(--font-weight-strong); } .field-group > legend { padding-block: 0; padding-inline: var(--fieldset-legend-padding-inline, var(--space-1)); font-size: var(--font-size-xs); } .field-help { color: var(--text-muted); font-size: var(--font-size-sm); } .field-error { display: none; color: var(--danger); font-size: var(--font-size-sm); } .required-mark { color: var(--danger); } .field.danger .field-help { color: var(--danger); } .input, .textarea, .select { --control-border: var(--border); --control-bg: var(--surface); --control-fg: var(--text); --control-ring: none; --control-cursor: auto; --control-opacity: 1; appearance: none; inline-size: 100%; min-block-size: var(--control-size); padding-inline: var(--space-3); border: var(--border-width) solid var(--form-invalid-border, var(--control-border)); border-block-end-color: var( --form-invalid-border, var(--control-border-block-end-color, var(--control-border)) ); border-block-end-width: var(--control-border-block-end-width, var(--border-width)); border-radius: var(--radius); background: var(--control-bg); color: var(--control-fg); font-size: var(--control-font-size); box-shadow: var(--control-ring); cursor: var(--control-cursor); opacity: var(--control-opacity); outline: none; transition: border-color var(--duration), box-shadow var(--duration), background-color var(--duration), color var(--duration); } .textarea { min-block-size: 6rem; padding-block: var(--space-2); resize: vertical; } @media (hover: hover) { .input:hover:not(:disabled), .textarea:hover:not(:disabled) { --control-border: var(--text-subtle); } .select:hover:not(:disabled) { --control-bg: var(--surface-subtle); } } .input:focus-visible, .textarea:focus-visible, .select:focus-visible { --control-border: var(--focus); outline: none; box-shadow: var(--focus-ring-shadow); } .input[readonly], .textarea[readonly] { --control-bg: var(--surface-subtle); --control-border: var(--border); } .input:disabled, .textarea:disabled, .select:disabled { --control-bg: var(--surface-subtle); --control-fg: var(--text-subtle); --control-border: var(--border); --control-cursor: not-allowed; --control-opacity: 1; } .input::placeholder, .textarea::placeholder { color: var(--text-muted); } .input-icon { --input-icon-size: var(--variant-icon-size, 1.25rem); display: block; position: relative; } .input-icon > :first-child { position: absolute; inset-block-start: 50%; inset-inline-start: var(--space-3); transform: translateY(-50%); font-size: var(--input-icon-size); color: var(--text-muted); pointer-events: none; } .input-icon > svg:first-child { inline-size: var(--input-icon-size); block-size: var(--input-icon-size); } .input-icon > .input { padding-inline-start: calc(var(--space-3) * 2 + var(--input-icon-size)); } :where(.choice, .check, .radio) { --intent: initial; --intent-fg: initial; --ui-bg: initial; --ui-fg: initial; --ui-border: initial; --ui-hover-bg: initial; } :where(.choice) :where(input[type="checkbox"]:not([role="switch"]), input[type="radio"]) { --intent: inherit; --intent-fg: inherit; } .choice { --choice-control-offset: 0.25em; display: inline-flex; align-items: flex-start; gap: var(--space-2); color: var(--text); font-size: var(--control-font-size); cursor: pointer; } .choice > :is(input[type="checkbox"]:not([role="switch"]), input[type="radio"]) { flex: 0 0 auto; margin-block-start: var(--choice-control-offset); } .choice > span > .field-help { display: block; } .choice:has(:disabled) { color: var(--text-subtle); cursor: not-allowed; } .check, .radio { --choice-border: var(--border); --choice-bg: var(--surface); --choice-mark: var(--primary-fg); position: relative; vertical-align: middle; display: inline-grid; place-content: center; inline-size: 1.125em; block-size: 1.125em; margin-inline: 0; margin-block-end: 0; border: var(--border-width) solid var(--form-invalid-border, var(--choice-border)); background: var(--choice-bg); color: var(--choice-mark); appearance: none; cursor: pointer; } .check { border-radius: var(--radius-sm); } .radio { border-radius: var(--radius-full); } .check::before, .radio::before { content: ""; position: absolute; inset: 0; margin: auto; transform: scale(0); transition: transform var(--duration); } .check::before { inline-size: 0.58em; block-size: 0.34em; border-inline-start: 2px solid currentColor; border-block-end: 2px solid currentColor; transform: translateY(-0.06em) rotate(-45deg) scale(0); } .radio::before { inline-size: 0.5em; block-size: 0.5em; border-radius: var(--radius-full); background: currentColor; } .check:checked, .radio:checked { --choice-border: var(--intent, var(--primary)); --choice-bg: var(--intent, var(--primary)); --choice-mark: var(--intent-fg, var(--primary-fg)); } .check:checked::before { transform: translateY(-0.06em) rotate(-45deg) scale(1); } .check:indeterminate { --choice-border: var(--intent, var(--primary)); --choice-bg: var(--intent, var(--primary)); --choice-mark: var(--intent-fg, var(--primary-fg)); } .check:indeterminate::before { border-inline-start: 0; inline-size: 0.6em; block-size: 0; border-block-end: 2px solid currentColor; transform: scale(1); } .radio:checked::before { transform: scale(1); } @media (hover: hover) { .check:hover:not(:checked, :indeterminate, :disabled), .radio:hover:not(:checked, :indeterminate, :disabled) { --choice-border: var(--text-subtle); } } .check:focus-visible, .radio:focus-visible { --choice-border: var(--focus); outline: none; box-shadow: var(--focus-ring-shadow); } .check:disabled, .radio:disabled { --choice-bg: var(--surface-subtle); --choice-border: var(--border); --choice-mark: var(--text-subtle); cursor: not-allowed; opacity: 1; } @media (forced-colors: active) { .check, .radio { --choice-border: ButtonText; --choice-bg: Canvas; --choice-mark: ButtonText; } .check:checked, .radio:checked, .check:indeterminate { --choice-border: Highlight; --choice-bg: Highlight; --choice-mark: HighlightText; forced-color-adjust: none; } .check:disabled, .radio:disabled { --choice-border: GrayText; --choice-bg: Canvas; --choice-mark: GrayText; } } :where(.choice-card) { --intent: initial; --intent-fg: initial; --ui-bg: initial; --ui-fg: initial; --ui-border: initial; --ui-hover-bg: initial; } .choice-card { --choice-card-pad: var(--variant-space, var(--space-4)); --choice-card-radius: var(--radius); --choice-card-border: var(--border); --choice-card-bg: var(--surface); --choice-card-check-size: 1.5em; position: relative; display: block; padding: var(--choice-card-pad); border: var(--border-width) solid var(--form-invalid-border, var(--choice-card-border)); border-radius: var(--choice-card-radius); background: var(--choice-card-bg); color: var(--text); cursor: pointer; transition: border-color var(--duration), background-color var(--duration), box-shadow var(--duration); } @supports selector(:has(*)) { .choice-card > :is(input[type="radio"], input[type="checkbox"]) { position: absolute; inline-size: 1px; block-size: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; } } .choice-card:has(:focus-visible) { outline: none; box-shadow: var(--focus-ring-shadow); } .choice-card:has(:disabled) { opacity: var(--disabled-opacity); cursor: not-allowed; } @media (hover: hover) { .choice-card:hover:not(:has(:disabled)) { --choice-card-border: var(--text-subtle); } } .choice-card:has(:checked) { --choice-card-border: var(--intent, var(--primary)); } @supports (color: color-mix(in oklch, red, white)) { .choice-card:has(:checked) { --choice-card-bg: color-mix(in oklch, var(--surface) 96%, var(--intent, var(--primary))); } } .choice-card::before, .choice-card::after { content: ""; position: absolute; inset-inline-end: -0.375em; inset-block-start: -0.375em; inline-size: var(--choice-card-check-size); block-size: var(--choice-card-check-size); transform: scale(0); transition: transform var(--duration); } .choice-card::before { background: var(--intent, var(--primary)); box-shadow: 0 0 0 2px var(--surface); z-index: 1; } .choice-card:has(input[type="radio"])::before { border-radius: var(--radius-full); } .choice-card:has(input[type="checkbox"])::before { border-radius: var(--radius-sm); } .choice-card::after { background: var(--intent-fg, var(--primary-fg)); -webkit-mask: var(--icon-check-mask) center / 60% no-repeat; mask: var(--icon-check-mask) center / 60% no-repeat; z-index: 2; } .choice-card:has(:checked)::before, .choice-card:has(:checked)::after { transform: scale(1); } @media (forced-colors: active) { .choice-card { --choice-card-border: ButtonText; --choice-card-bg: Canvas; } .choice-card:has(:checked) { --choice-card-border: Highlight; --choice-card-bg: Canvas; forced-color-adjust: none; } .choice-card:has(:checked)::before { background: Highlight; box-shadow: 0 0 0 2px Canvas; } .choice-card:has(:checked)::after { background: HighlightText; } } .select:is(:not([multiple], [size]), :not([multiple])[size="1"]) { appearance: none; padding-inline-end: calc(var(--space-3) + var(--space-6)); background-image: var(--icon-chevron-image); background-position: center right var(--space-3); background-size: 1rem auto; background-repeat: no-repeat; } .select:is(:not([multiple], [size]), :not([multiple])[size="1"]):dir(rtl) { background-position: center left var(--space-3); } @media (forced-colors: active), (prefers-contrast: more) { .select:is(:not([multiple], [size]), :not([multiple])[size="1"]) { appearance: auto; background-image: none; padding-inline-end: var(--space-3); } } @media (forced-colors: none) and (prefers-contrast: no-preference) and (hover: hover) and ( pointer: fine ) { @supports (appearance: base-select) { .select:not([multiple], .native, [size]:not([size="1"])) { appearance: base-select; align-items: center; &::picker(select) { appearance: base-select; max-height: min(24rem, calc(var(--viewport-block) * 0.7)); margin-block: var(--space-2); padding: 0; border: var(--border-width) solid var(--border); border-radius: var(--radius); background-color: var(--surface-raised); color: inherit; box-shadow: var(--shadow-popout); } &:open { --control-border: var(--border); --control-bg: var(--surface-raised); outline: none; box-shadow: var(--focus-ring-shadow); } &::picker-icon { display: none; } & option { position: relative; padding-block: var(--space-2); padding-inline: var(--space-3); white-space: normal; transition-property: color, background-color; transition-duration: var(--duration); &:not(:disabled):hover { background-color: var(--surface-subtle); color: var(--text); cursor: pointer; } &:not(:disabled):focus-visible { background-color: var(--primary); color: var(--primary-fg); outline: none; } &:active { background-color: var(--surface-subtle); color: var(--text); } &::checkmark { content: ""; display: block; inline-size: 1rem; block-size: 1rem; background-color: currentColor; -webkit-mask-image: var(--icon-check-mask); mask-image: var(--icon-check-mask); -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat; -webkit-mask-size: contain; mask-size: contain; -webkit-mask-position: center; mask-position: center; } } & optgroup { padding-block-start: 0.5em; & option:first-child { margin-block-start: 0.5em; } } } } } .file { color: var(--text-muted); } .file::file-selector-button { margin-inline-end: var(--space-3); padding-block: var(--space-1); padding-inline: var(--space-2); border: var(--border-width) solid var(--border); border-radius: var(--radius-sm); background: var(--surface-subtle); color: var(--text); font: inherit; font-size: var(--font-size-sm); font-weight: var(--font-weight-medium); cursor: pointer; transition: background-color var(--duration), border-color var(--duration), color var(--duration); } .file:disabled::file-selector-button { cursor: not-allowed; } @media (hover: hover) { .file:not(:disabled)::file-selector-button:hover { background: var(--border); } } .file:focus-visible { outline: none; box-shadow: var(--focus-ring-shadow); } :where(.range) { --intent: initial; --intent-fg: initial; --ui-bg: initial; --ui-fg: initial; --ui-border: initial; --ui-hover-bg: initial; } .range { --range-thumb-size: 1.25rem; --range-track-height: 0.25rem; --range-thumb-bg: var(--intent, var(--primary)); --range-track-bg: var(--border); appearance: none; inline-size: 100%; block-size: var(--range-thumb-size); background: transparent; cursor: pointer; } .range::-webkit-slider-runnable-track { block-size: var(--range-track-height); border-radius: var(--radius-full); background: var(--range-track-bg); } .range::-moz-range-track { block-size: var(--range-track-height); border-radius: var(--radius-full); background: var(--range-track-bg); } .range::-webkit-slider-thumb { appearance: none; inline-size: var(--range-thumb-size); block-size: var(--range-thumb-size); border-radius: var(--radius-full); border: 0; background: var(--range-thumb-bg); margin-block-start: calc((var(--range-track-height) - var(--range-thumb-size)) / 2); cursor: inherit; transition: box-shadow var(--duration); } .range::-moz-range-thumb { inline-size: var(--range-thumb-size); block-size: var(--range-thumb-size); border-radius: var(--radius-full); border: 0; background: var(--range-thumb-bg); cursor: inherit; transition: box-shadow var(--duration); } .range:focus-visible { outline: none; } .range:focus-visible::-webkit-slider-thumb { box-shadow: 0 0 0 1px var(--surface), 0 0 0 calc(1px + var(--focus-ring-width)) var(--focus-ring); } .range:focus-visible::-moz-range-thumb { box-shadow: 0 0 0 1px var(--surface), 0 0 0 calc(1px + var(--focus-ring-width)) var(--focus-ring); } .range:disabled { --range-thumb-bg: var(--text-subtle); cursor: not-allowed; opacity: var(--disabled-opacity); } :where(.switch) { --intent: initial; --intent-fg: initial; --ui-bg: initial; --ui-fg: initial; --ui-border: initial; --ui-hover-bg: initial; } .switch { --switch-bg: var(--border); --switch-border: var(--border); --switch-knob: var(--surface-raised); --switch-width: calc(var(--control-size) * 1.16); --switch-block-size: calc(var(--control-size) * 0.63); --switch-knob-margin: calc(var(--switch-block-size) * 0.12); --switch-knob-size: calc(var(--switch-block-size) - 2 * var(--switch-knob-margin)); --switch-travel: calc( var(--switch-width) - var(--switch-knob-size) - 2 * var(--border-width) - 2 * var(--switch-knob-margin) ); position: relative; display: inline-grid; align-items: center; justify-content: start; inline-size: var(--switch-width); block-size: var(--switch-block-size); margin: 0; border: var(--border-width) solid var(--form-invalid-border, var(--switch-border)); border-radius: var(--radius-full); background: var(--switch-bg); appearance: none; cursor: pointer; } .switch::before { content: ""; inline-size: var(--switch-knob-size); block-size: var(--switch-knob-size); margin-inline: var(--switch-knob-margin); border-radius: var(--radius-full); background: var(--switch-knob); box-shadow: var(--shadow); transition: transform var(--duration), background-color var(--duration), box-shadow var(--duration); } @media (hover: hover) { .switch:hover:not(:disabled) { --switch-border: var(--intent, var(--primary)); } } .switch:checked { --switch-bg: var(--intent, var(--primary)); --switch-border: var(--intent, var(--primary)); --switch-knob: var(--intent-fg, var(--primary-fg)); } .switch:checked::before { transform: translateX(var(--switch-travel)); } .switch:checked:dir(rtl)::before { transform: translateX(calc(var(--switch-travel) * -1)); } .switch:focus-visible { --switch-border: var(--focus); outline: none; box-shadow: var(--focus-ring-shadow); } .switch:disabled { --switch-bg: var(--surface-subtle); --switch-border: var(--border); --switch-knob: var(--text-subtle); opacity: 1; cursor: not-allowed; } @media (forced-colors: active) { .switch { --switch-border: ButtonText; --switch-knob: ButtonText; } .switch::before { box-shadow: none; } .switch:checked { --switch-bg: Highlight; --switch-border: Highlight; --switch-knob: HighlightText; forced-color-adjust: none; } .switch:disabled { --switch-bg: Canvas; --switch-border: GrayText; --switch-knob: GrayText; forced-color-adjust: auto; } } .field.danger { --form-invalid-border: var(--danger); } .field.danger > .field-error { display: block; } @supports selector(:has(*)) { .field:has([aria-invalid="true"]) > .field-error, .needs-validation.was-validated .field:has(:invalid) > .field-error { display: block; } } :where(.input, .textarea, .select, .check, .radio, .switch)[aria-invalid="true"], .needs-validation.was-validated :is(.input, .textarea, .select, .check, .radio, .switch):invalid { --form-invalid-border: var(--danger); } .check[aria-invalid="true"]:is(:checked, :indeterminate), .radio[aria-invalid="true"]:checked { --choice-bg: var(--danger); } .switch[aria-invalid="true"]:checked { --switch-bg: var(--danger); } @supports selector(:has(*)) { .choice-card:has([aria-invalid="true"]), .needs-validation.was-validated .choice-card:has(:invalid) { --form-invalid-border: var(--danger); } } @supports selector(:user-invalid) { .needs-validation :is(.input, .textarea, .select, .check, .radio, .switch):user-invalid { --form-invalid-border: var(--danger); } } @supports selector(:has(:user-invalid)) { .needs-validation .field:has(:user-invalid) > .field-error { display: block; } .needs-validation .choice-card:has(:user-invalid) { --form-invalid-border: var(--danger); } } .form-actions { display: flex; flex-wrap: wrap; gap: var(--gap); align-items: center; margin-block-start: var(--form-actions-margin-block-start, var(--space-5)); } .form-actions.sticky { position: sticky; inset-block-end: var(--form-actions-sticky-block-offset, 0px); z-index: var(--z-sticky); isolation: isolate; margin-inline: calc(var(--form-actions-sticky-inline-offset, 0px) * -1); padding: var(--form-actions-sticky-padding, var(--space-3)); border-block-start: var(--border-width) solid var(--border); background: var(--surface); -webkit-backdrop-filter: blur(1rem); backdrop-filter: blur(1rem); } @supports (background: color-mix(in oklch, red 50%, transparent)) { .form-actions.sticky { background: color-mix(in oklch, var(--surface) 88%, transparent); } } .sr-only { position: absolute; inline-size: 1px; block-size: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; } .overflow-auto { overflow: auto; } .fit { inline-size: fit-content; max-inline-size: 100%; } .grow { flex: 1 1 auto; min-inline-size: 0; } .nowrap { white-space: nowrap; } .truncate { min-inline-size: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .items-start { --items-align: start; align-items: start; } .items-center { --items-align: center; align-items: center; } .items-end { --items-align: end; align-items: end; } .muted { color: var(--text-muted); } .circle { border-radius: var(--radius-full); } .text-start { --text-align: start; text-align: start; } .text-center { --text-align: center; text-align: center; } .text-end { --text-align: end; text-align: end; } .text-balance { text-wrap: balance; } .text-pretty { text-wrap: pretty; } .list-reset { margin: 0; padding: 0; list-style: none; } .dot { flex: none; inline-size: 0.25rem; block-size: 0.25rem; border-radius: var(--radius-full); background: var(--text-subtle); } .link-plain { color: inherit; text-decoration: none; } .link-muted { color: var(--text-muted); text-decoration: none; } @media (hover: hover) { .link-muted:hover { color: var(--text); } } .gap-none { gap: 0; } .py { padding-block: var(--variant-space); } .px { padding-inline: var(--variant-space); } .mbs { margin-block-start: var(--variant-space); } .mbe { margin-block-end: var(--variant-space); } .join { --join-radius: var(--radius); --join-ss: 0; --join-se: 0; --join-es: 0; --join-ee: 0; align-items: stretch; display: inline-flex; } .join.circle { --join-radius: var(--radius-full); } .join-addon { --control-border: var(--border); --control-bg: var(--surface-subtle); --control-fg: var(--text-muted); align-items: center; display: inline-flex; justify-content: center; min-block-size: var(--control-size); padding-inline: var(--space-3); border: var(--border-width) solid var(--control-border); border-radius: var(--radius); background: var(--control-bg); color: var(--control-fg); font-size: var(--control-font-size); line-height: 1; white-space: nowrap; } .join > * { border-start-start-radius: var(--join-ss); border-start-end-radius: var(--join-se); border-end-end-radius: var(--join-ee); border-end-start-radius: var(--join-es); } .join > :first-child { --join-ss: var(--join-radius); --join-es: var(--join-radius); } .join > :last-child { --join-se: var(--join-radius); --join-ee: var(--join-radius); } .join > :only-child { --join-ss: var(--join-radius); --join-se: var(--join-radius); --join-es: var(--join-radius); --join-ee: var(--join-radius); } .join > * + * { margin-inline-start: calc(var(--border-width) * -1); } .join > :is(:hover, :focus, :focus-within) { z-index: 1; } .join > :is(:focus, :focus-within) { z-index: 2; } .join > :is(.input, .textarea, .select) { z-index: 3; } .join:has(> :is(.input, .textarea, .select):focus-visible) { border-radius: var(--join-radius); outline: none; box-shadow: var(--focus-ring-shadow); } .join:has(> :is(.input, .textarea, .select)) > :is(.input, .textarea, .select):focus-visible { outline: none; box-shadow: none; } :focus { outline: var(--focus-outline); outline-offset: var(--focus-outline-offset); } @supports selector(:focus-visible) { :focus:not(:focus-visible) { outline: none; } } @media (forced-colors: active) { :focus:focus-visible:not(.range), .choice-card:has(:focus-visible), .join:has(> :is(.input, .textarea, .select):focus-visible) { outline: var(--focus-outline); outline-offset: var(--focus-outline-offset); box-shadow: none; } .range:focus-visible::-webkit-slider-thumb { outline: var(--focus-outline); outline-offset: var(--focus-outline-offset); } .range:focus-visible::-moz-range-thumb { outline: var(--focus-outline); outline-offset: var(--focus-outline-offset); } } @media print { :root, body { color-scheme: light; background: #fff; color: #000; } .flyout, .tooltip, .surface-backdrop, .status-bar, .spinner, dialog.modal[open], dialog.drawer[open] { display: none !important; } button.btn, input[type="button"].btn, input[type="submit"].btn, input[type="reset"].btn { display: none !important; } a.btn[href^="http"]::after { content: " (" attr(href) ")"; font-size: 0.875em; } .card, .alert, .badge { border: var(--border-width) solid CanvasText; break-inside: avoid; } h1, h2, h3, h4, h5, h6 { break-after: avoid; } }
package/docs/README.md CHANGED
@@ -22,5 +22,7 @@ Start here when using or changing Actual CSS.
22
22
 
23
23
  - [References](design-notes/references.md): positioning, tradeoffs, non-goals, and research links.
24
24
  - [Browser support](design-notes/browser-support.md): progressive enhancement strategy, feature gating, and fallbacks.
25
+ - [Enhancement contract](design-notes/enhancement-contract.md): the class/data-enhance/ARIA split, token grammar, and design decisions.
25
26
  - [Naming conventions](design-notes/naming.md): class grammar, component naming rules, and JS attribute namespacing.
27
+ - [Widget primitives](design-notes/widget-primitives.md): composition guide for building custom widgets on Actual's runtime.
26
28
  - [Accessibility decisions](design-notes/accessibility-decisions.md): guarantees, author responsibilities, and interactive states.
@@ -208,7 +208,7 @@ Variants
208
208
  aria-label="Jane Doe, open profile menu">
209
209
  <img src="https://mockmind-api.uifaces.co/content/human/219.jpg" alt="" />
210
210
  </button>
211
- <menu class="flyout" id="profile-menu" aria-labelledby="profile-trigger" hidden>
211
+ <menu class="flyout" data-enhance="flyout" id="profile-menu" aria-labelledby="profile-trigger" hidden>
212
212
  <li><a href="#profile">View profile</a></li>
213
213
  <li><button type="button">Sign out</button></li>
214
214
  </menu>
@@ -262,7 +262,7 @@ Composed
262
262
  ```html
263
263
  <button type="button" class="btn ghost" aria-label="Notifications">
264
264
  <i class="ti ti-bell" aria-hidden="true"></i>
265
- <span class="badge danger" aria-label="12 unread notifications">12</span>
265
+ <span class="badge danger solid" aria-label="12 unread notifications">12</span>
266
266
  </button>
267
267
 
268
268
  <button type="button" class="btn secondary soft" aria-label="Notifications">
@@ -90,4 +90,13 @@ only through background color.
90
90
 
91
91
  - Grouping works with `role="group"` and `:has()`: it is a progressive enhancement; UI should still be functional without it.
92
92
  - Keep `:has()` out of selector lists that also contain legacy-safe selectors. Put the `:has()` branch in `@supports selector(...)` if necessary.
93
+
94
+ ## Native-first audit (0.2)
95
+
96
+ `dialog.js`, `surface.js`, and the drawer keep the modern path thin
97
+ (`<dialog>` with `showModal` / `close`) and the fallback contained
98
+ (`dialog-fallback.js` shim). The JS runtime's baseline is far below
99
+ Chrome 130 / Safari 18: no `FocusTrap` or `ScrollBarHelper` shim deletion,
100
+ no `@property { inherits: false }` for utility locals. Every native-feature
101
+ removal must clear a stated floor — not follow a competitor's.
93
102
  - Use `:has()` to improve simple structure, but do not turn it into a monolithic selector.
@@ -0,0 +1,104 @@
1
+ # Enhancement contract
2
+
3
+ Actual CSS 0.2 splits CSS and JavaScript into two independent layers with a shared
4
+ opt-in mechanism. Every component uses the same grammar.
5
+
6
+ ## The four-layer contract
7
+
8
+ ```text
9
+ class = presentation (.tabs, .flyout, .needs-validation)
10
+ data-enhance = JavaScript behavior (data-enhance="tabs")
11
+ ARIA / HTML = semantics (role="tab", aria-controls, hidden)
12
+ data-* = behavior configuration (data-mask, data-tooltip, data-filter)
13
+ ```
14
+
15
+ The duplication is deliberate:
16
+
17
+ ```html
18
+ <div class="tabs" data-enhance="tabs" role="tablist">
19
+ ```
20
+
21
+ - `.tabs` opts into the Actual CSS presentation;
22
+ - `data-enhance="tabs"` opts into the JavaScript behavior;
23
+ - `role="tablist"` declares semantics to assistive technology.
24
+
25
+ Each layer can be removed independently:
26
+
27
+ ```html
28
+ <!-- CSS only: no JS behavior, just styling -->
29
+ <div class="tabs" role="tablist">…</div>
30
+
31
+ <!-- JS only: custom CSS, Actual behavior -->
32
+ <div class="my-tabs" data-enhance="tabs" role="tablist">…</div>
33
+
34
+ <!-- Both: standard Actual look and behavior -->
35
+ <div class="tabs" data-enhance="tabs" role="tablist">…</div>
36
+
37
+ <!-- Semantic only: author handles everything else -->
38
+ <div role="tablist">…</div>
39
+ ```
40
+
41
+ ## `data-enhance` grammar
42
+
43
+ Tokens are whitespace-separated, matched with the `~=` attribute selector, case-sensitive,
44
+ and must match `[a-z][a-z0-9-]*`. Order is irrelevant; duplicates are harmless.
45
+
46
+ ```html
47
+ <form data-enhance="validation autosubmit"> <!-- two behaviors -->
48
+ ```
49
+
50
+ ## When a token, when a `data-*`
51
+
52
+ > `data-enhance` is a generic opt-in for when HTML does not already provide an unambiguous one.
53
+
54
+ - **A token** is for a root controller — a behavior that owns a subtree and manages
55
+ descendants (tabs, flyout, scrollspy, validation).
56
+ - **A self-describing `data-*`** is for a leaf whose attribute is simultaneously the opt-in
57
+ and the configuration (`data-tooltip`, `data-mask`, `data-filter`,
58
+ `data-context-menu`).
59
+ - **Elements that are their own opt-in** need nothing (`<dialog>`).
60
+
61
+ `data-enhance` is explicitly **not** a mandatory prefix for every module.
62
+
63
+ ## One registration per enhancement per root
64
+
65
+ No core mechanism prevents registering the same token twice on the same root; doing so
66
+ creates two independent records that both run. This is documented behaviour, not guarded
67
+ at runtime.
68
+
69
+ ## CSS must never select on `data-enhance`
70
+
71
+ CSS rules must not select on `data-enhance` or the runtime marker
72
+ `data-actual-surface`. Selecting on either would make the CSS API depend on the JS API,
73
+ defeating the split.
74
+
75
+ ## Design decisions recorded
76
+
77
+ | # | Decision | Rationale |
78
+ |---|----------|-----------|
79
+ | D2 | `selectors.js` drops its 5 discovery entries, keeps 11 write-side state entries | The file's job changes from *CSS↔init bridge* to *state vocabulary the runtime writes*. It stays the single file to alias for another CSS framework. |
80
+ | D4 | `status.js` uses `[data-status][role="status"]` — no class, no token | The markup already carries `role="status"` everywhere. Semantics alone scope the document-wide lookup. |
81
+ | D5 | `<dialog>` gets no token | `<dialog>` is its own opt-in: semantic, native, CSS-agnostic. |
82
+ | D6 | `validation.js` accepts `[data-field-error]` as an alias for `.field-error` and keeps `.field` / `.danger` as an optional, degrading presentation adapter | Validation is the one module with intentional, optional CSS coupling. The adapter degrades to a no-op under foreign CSS while `aria-invalid`, focus management, custom rules, and server errors all keep working. |
83
+ | D7 | Context-menu reuses `surface`, not `flyout` | The panel gets no token; `menuFor()` validates semantically (`menu, [role="menu"]`). A context menu may legitimately want the flyout *look* without the flyout *behavior*. |
84
+ | D9 | Orphaned mounted surfaces closed from the origin's disconnect handler | A `fix:`, not part of the contract itself. Landed independently. |
85
+
86
+ ### Accepted debt
87
+
88
+ `flyout.js`'s trigger selector `[aria-controls][aria-expanded]` is the broadest selector
89
+ in the runtime and matches unrelated application disclosures (`connectTrigger` bails
90
+ afterwards via `flyoutFor()`). It is already ARIA-only and stays as-is:
91
+
92
+ > Broad trigger discovery is intentional for dynamically inserted triggers.
93
+ > Revisit only if profiling or interoperability shows a real problem.
94
+
95
+ ## Token vocabulary (0.2.0)
96
+
97
+ | Token | Behavior | Existing class |
98
+ |-------|----------|---------------|
99
+ | `tabs` | Tab panel switching, arrow-key navigation | `.tabs` |
100
+ | `flyout` | Trigger → panel positioning, open/close | `.flyout` |
101
+ | `scrollspy` | Scroll-driven nav highlighting | `.scrollspy` |
102
+ | `validation` | Form validation, focus management, server errors | `.needs-validation` |
103
+
104
+ Four tokens. Everything else stays self-describing.
@@ -34,4 +34,5 @@ Actual CSS is intended for new projects. Existing projects with class collisions
34
34
  - Classes name roles and boolean modifiers; `data-*` carries configurable values.
35
35
  - `is-*` classes are runtime internals, not author API.
36
36
  - Public JS data attributes are namespaced by feature (`data-flyout-*`, `data-context-menu-*`, `data-dialog-*`, `data-tooltip-*`; `data-toast-*` is reserved). Do not expose shared implementation names such as `surface` unless they are meant as a stable author concept.
37
+ - `data-enhance` is the one un-namespaced attribute — it carries *opt-in* for any feature, not *configuration* for one feature. Feature-namespaced attributes carry configuration.
37
38
  - Custom events use the `actual:*` namespace.