/*
    robonxt design system
    v2 — three-layer architecture: identity / palette / semantic roles
    Single distributable. Consumers: <link rel="stylesheet" href=".../robonxt.css">
    Optional companion: robonxt.js (Web Components)

    Axes:
        [data-color-scheme="light" | "dark"]   color mode; varies surfaces/text only
        [data-theme="default" | ...]           brand palette; varies primary/accent only

    Brand colors are intentionally unified across light and dark modes.
*/

/* ==========================================================================
   LAYER 1 — IDENTITY TOKENS
   Spacing, typography, shape, motion. These never change per theme or mode.
   ========================================================================== */
:root {
    color-scheme: light dark;
    scroll-behavior: smooth;

    /* Typography */
    --font-family: 'Inter', system-ui, -apple-system, sans-serif;
    --font-family-mono: ui-monospace, 'SF Mono', Menlo, Consolas, 'Liberation Mono', monospace;

    --font-size-h1: 2.25rem;     /* 36px */
    --font-size-h2: 1.5rem;      /* 24px */
    --font-size-h3: 1.25rem;     /* 20px */
    --font-size-body: 1rem;      /* 16px */
    --font-size-label: 0.875rem; /* 14px */
    --font-size-caption: 0.75rem;/* 12px */

    --font-weight-bold: 700;
    --font-weight-semibold: 600;
    --font-weight-medium: 500;
    --font-weight-regular: 400;

    --line-height-heading: 1.3;
    --line-height-body: 1.6;
    --letter-spacing-heading: -0.02em;

    --font-h1: var(--font-weight-bold) var(--font-size-h1)/var(--line-height-heading) var(--font-family);
    --font-h2: var(--font-weight-semibold) var(--font-size-h2)/var(--line-height-heading) var(--font-family);
    --font-h3: var(--font-weight-semibold) var(--font-size-h3)/var(--line-height-heading) var(--font-family);
    --font-body: var(--font-weight-regular) var(--font-size-body)/var(--line-height-body) var(--font-family);
    --font-label: var(--font-weight-medium) var(--font-size-label)/var(--line-height-body) var(--font-family);
    --font-caption: var(--font-weight-regular) var(--font-size-caption)/var(--line-height-body) var(--font-family);

    /* Spacing
       Base unit is --space-2xs (4px). Dense mobile-first surfaces should
       default to 2xs/xs; floating contextual UI to sm; decorative breathing
       room to md/lg/xl. The 8-point rhythm holds above xs. */
    --space-2xs: 4px;
    --space-xs:  8px;
    --space-sm:  16px;
    --space-md:  24px;
    --space-lg:  32px;
    --space-xl:  48px;

    /* Radius */
    --radius-sm: 4px;
    --radius-md: 8px;
    --radius-lg: 16px;
    --radius-full: 9999px;

    /* Stroke */
    --stroke-sm: 1.5px;
    --stroke-md: 3px;

    /* Elevation */
    --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
    --shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
    --shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);

    /* Motion */
    --duration-quick: 150ms;
    --duration-medium: 300ms;
    --duration-slow: 500ms;
    --easing: cubic-bezier(0.4, 0, 0.2, 1);
    --easing-decelerate: cubic-bezier(0, 0, 0.2, 1);

    /* Component sizing */
    --touch-target: 48px;
    --icon-size-sm: 16px;
    --icon-size-md: 24px;
    --icon-size-lg: 32px;
    --avatar-size-sm: 32px;
    --avatar-size-md: 48px;
    --avatar-size-lg: 64px;
    --progress-height: 8px;
    --switch-track-width: 44px;
    --switch-track-height: 24px;
    --switch-thumb-size: 16px;
    --switch-thumb-offset: var(--space-2xs);
    --pill-padding: var(--space-2xs);
    --pill-gap: 2px;
    --scrollbar-width: 8px;
    --header-height: 64px;

    /* Z-index scale */
    --z-dropdown: 50;
    --z-header: 100;
    --z-modal: 1100;
}

/* ==========================================================================
   LAYER 2 — PALETTE TOKENS
   Raw color scales. To create a new brand theme, override these (or a subset)
   inside a [data-theme="..."] block. Identity tokens above must NOT be overridden.
   ========================================================================== */
[data-theme="default"],
:root {
    /* Indigo (primary brand) */
    --indigo-50:  #EEF2FF;
    --indigo-100: #E0E7FF;
    --indigo-200: #C7D2FE;
    --indigo-300: #A5B4FC;
    --indigo-400: #818CF8;
    --indigo-500: #6366F1;
    --indigo-600: #4F46E5;
    --indigo-700: #4338CA;
    --indigo-800: #3730A3;
    --indigo-900: #312E81;

    /* Fuchsia accent — two shades only, used for rare contrast moments */
    --fuchsia-600: #C026D3;
    --fuchsia-700: #A21CAF;

    /* Neutrals */
    --white:    #FFFFFF;
    --gray-50:  #FAFAFA;
    --gray-100: #F5F5F5;
    --gray-150: #E0E0E0;
    --gray-300: #D4D4D4;
    --gray-400: #A3A3A3;
    --gray-500: #737373;
    --gray-600: #525252;
    --gray-700: #404040;
    --gray-800: #262626;
    --gray-900: #0A0A0A;
    --gray-950: #171717;

    /* Functional */
    --success: #059669;
    --warning: #D97706;
    --danger:  #DC2626;

    /* Logo (brand marks — DO NOT theme, do not use for UI) */
    --logo-teal:  #14B8A6;
    --logo-red:   #B91C1C;
    --logo-slate: #343F4B;
    --logo-ink:   #111827;
}

/* ==========================================================================
   LAYER 3 — SEMANTIC ROLE TOKENS  (the "theme contract")
   Components reference ONLY these tokens. Any custom theme must define this
   full set to remain robonxt-compliant.
   ========================================================================== */

/* Brand roles — unified across light/dark by design. */
:root {
    --color-primary:        var(--indigo-600);
    --color-primary-hover:  var(--indigo-700);
    --color-primary-active: var(--indigo-800);
    --color-on-primary:     var(--white);

    --color-accent:         var(--fuchsia-600);
    --color-accent-hover:   var(--fuchsia-700);
    --color-on-accent:      var(--white);

    --color-border-focus:   var(--indigo-500);

    --color-success: var(--success);
    --color-warning: var(--warning);
    --color-error:   var(--danger);

    --color-on-success: var(--white);
    --color-on-warning: var(--white);
    --color-on-error:   var(--white);
}

/* Light mode (default). Override only surface/text/border roles. */
:root,
[data-color-scheme="light"] {
    --color-background:      var(--gray-150);
    --color-surface:         var(--white);
    --color-surface-hover:   var(--gray-100);
    --color-surface-subtle:  var(--gray-50);
    --color-header-bg:       var(--white);

    --color-text-high:   var(--gray-900);
    --color-text-medium: var(--gray-600);
    --color-text-low:    var(--gray-500);

    --color-border-default: var(--gray-300);

    /* Functional subtle backgrounds — tint of functional color over surface. */
    --color-success-subtle: color-mix(in srgb, var(--color-success) 12%, var(--color-surface));
    --color-warning-subtle: color-mix(in srgb, var(--color-warning) 12%, var(--color-surface));
    --color-error-subtle:   color-mix(in srgb, var(--color-error)   12%, var(--color-surface));
}

/* Dark mode. */
[data-color-scheme="dark"] {
    --color-background:      var(--gray-950);
    --color-surface:         var(--gray-800);
    --color-surface-hover:   var(--gray-700);
    --color-surface-subtle:  var(--gray-900);
    --color-header-bg:       var(--gray-800);

    --color-text-high:   var(--white);
    --color-text-medium: var(--gray-400);
    --color-text-low:    var(--gray-500);

    --color-border-default: var(--gray-600);

    --color-success-subtle: color-mix(in srgb, var(--color-success) 20%, var(--color-surface));
    --color-warning-subtle: color-mix(in srgb, var(--color-warning) 20%, var(--color-surface));
    --color-error-subtle:   color-mix(in srgb, var(--color-error)   20%, var(--color-surface));
}

/* System preference fallback — applies dark roles when no explicit attribute is set. */
@media (prefers-color-scheme: dark) {
    :root:not([data-color-scheme="light"]) {
        --color-background:      var(--gray-950);
        --color-surface:         var(--gray-800);
        --color-surface-hover:   var(--gray-700);
        --color-surface-subtle:  var(--gray-900);
        --color-header-bg:       var(--gray-800);

        --color-text-high:   var(--white);
        --color-text-medium: var(--gray-400);
        --color-text-low:    var(--gray-500);

        --color-border-default: var(--gray-600);

        --color-success-subtle: color-mix(in srgb, var(--color-success) 20%, var(--color-surface));
        --color-warning-subtle: color-mix(in srgb, var(--color-warning) 20%, var(--color-surface));
        --color-error-subtle:   color-mix(in srgb, var(--color-error)   20%, var(--color-surface));
    }
}

/* ==========================================================================
   BASE
   ========================================================================== */
*,
*::before,
*::after {
    box-sizing: border-box;
}

::-webkit-scrollbar { width: var(--scrollbar-width); }
::-webkit-scrollbar-track { background: var(--color-background); }
::-webkit-scrollbar-thumb {
    background: var(--color-border-default);
    border-radius: var(--radius-full);
}
::-webkit-scrollbar-thumb:hover { background: var(--color-text-medium); }

body {
    margin: 0;
    background-color: var(--color-background);
    color: var(--color-text-high);
    font: var(--font-body);
    transition: background-color var(--duration-slow), color var(--duration-slow);
    overflow-x: hidden;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

h1, h2, h3, h4, h5, h6 {
    margin: 0;
    letter-spacing: var(--letter-spacing-heading);
    overflow-wrap: anywhere;
}
h1 { font: var(--font-h1); }
h2 { font: var(--font-h2); }
h3 { font: var(--font-h3); }

p { margin-block-start: 0; }

/* ==========================================================================
   ICONOGRAPHY
   ========================================================================== */
.material-symbols-rounded {
    font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 24;
    font-size: var(--icon-size-md);
    vertical-align: middle;
}

/* ==========================================================================
   ACCESSIBILITY — REDUCED MOTION
   Honors `prefers-reduced-motion: reduce` by disabling only the things the
   spec considers motion: transforms, large position changes, decorative
   infinite animations, and smooth scroll. Color, opacity, and border
   transitions are PRESERVED — per WCAG guidance, fades are not "motion".
   Functional indicators (e.g. the loading spinner) are kept intentionally;
   users still need to know work is in progress.
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }

    /* Decorative loops — kill them. */
    .progress-indicator-active::after { animation: none; }

    /* Modal: keep the opacity fade, drop the scale. */
    .modal-dialog,
    .modal-backdrop.is-visible .modal-dialog { transform: none; }

    /* Dropdown: keep the opacity fade, drop the slide. */
    .dropdown-menu,
    .dropdown-menu.is-above { transform: none; }
    .header-nav.is-compact .header-nav-items { transform: none; }

    /* Pill selector track: large horizontal slide → snap. */
    .pill-selector-track { transition: none; }

    /* Card lift on hover: pure motion → suppress. */
    .card-interactive:hover { transform: none; }
}

/* ==========================================================================
   UTILITIES
   ========================================================================== */
.text-high    { color: var(--color-text-high); }
.text-medium  { color: var(--color-text-medium); }
.text-low     { color: var(--color-text-low); }
.text-success { color: var(--color-success); }
.text-warning { color: var(--color-warning); }
.text-error   { color: var(--color-error); }

.bg-background     { background-color: var(--color-background); }
.bg-surface        { background-color: var(--color-surface); }
.bg-surface-hover  { background-color: var(--color-surface-hover); }

.border-default { border-color: var(--color-border-default); }
.border-focus   { border-color: var(--color-border-focus); }

.shadow-sm { box-shadow: var(--shadow-sm); }
.shadow-md { box-shadow: var(--shadow-md); }
.shadow-lg { box-shadow: var(--shadow-lg); }

.radius-sm   { border-radius: var(--radius-sm); }
.radius-md   { border-radius: var(--radius-md); }
.radius-lg   { border-radius: var(--radius-lg); }
.radius-full { border-radius: var(--radius-full); }

/* Anchor target offset for sticky-header layouts. Apply to scroll targets
   so their top edge clears the sticky header on jump-to-anchor. */
.scroll-anchor { scroll-margin-top: var(--header-height); }

/* ==========================================================================
   BUTTONS
   ========================================================================== */
.btn {
    display: inline-flex;
    align-items: center;
    gap: var(--space-xs);
    font: var(--font-label);
    padding: var(--space-xs) var(--space-sm);
    border-radius: var(--radius-md);
    border: var(--stroke-sm) solid transparent;
    cursor: pointer;
    text-decoration: none;
    transition: all var(--duration-quick) var(--easing);
}

.btn:focus-visible {
    outline: var(--stroke-md) solid var(--color-border-focus);
    outline-offset: 2px;
}

.btn:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

.btn-loading {
    pointer-events: none;
    position: relative;
}

.btn-loading .material-symbols-rounded {
    animation: rx-spin 1s linear infinite;
}

@keyframes rx-spin {
    from { transform: rotate(0deg); }
    to   { transform: rotate(360deg); }
}

.btn-primary {
    background-color: var(--color-primary);
    color: var(--color-on-primary);
}
.btn-primary:hover:not(:disabled)  { background-color: var(--color-primary-hover); }
.btn-primary:active:not(:disabled) { background-color: var(--color-primary-active); }

.btn-secondary {
    background-color: var(--color-accent);
    color: var(--color-on-accent);
}
.btn-secondary:hover:not(:disabled)  { background-color: var(--color-accent-hover); }
.btn-secondary:active:not(:disabled) { filter: brightness(0.95); }

.btn-outline {
    background-color: transparent;
    border-color: var(--color-border-default);
    color: var(--color-text-high);
}
.btn-outline:hover:not(:disabled) {
    background-color: var(--color-surface-hover);
    border-color: var(--color-text-medium);
}

.btn-ghost {
    background-color: transparent;
    color: var(--color-text-high);
}
.btn-ghost:hover:not(:disabled) { background-color: var(--color-surface-hover); }

.btn-danger {
    background-color: var(--color-error);
    color: var(--color-on-error);
}
.btn-danger:hover:not(:disabled)  { filter: brightness(0.95); }
.btn-danger:active:not(:disabled) { filter: brightness(0.9); }

.btn-icon {
    padding: 0;
    width: var(--touch-target);
    height: var(--touch-target);
    justify-content: center;
    background-color: transparent;
    border: none;
    border-radius: var(--radius-md);
    color: var(--color-text-medium);
}
.btn-icon:hover:not(:disabled) {
    background-color: var(--color-surface-hover);
    color: var(--color-primary);
}
.btn-icon.btn-primary {
    background-color: var(--color-primary);
    color: var(--color-on-primary);
}
.btn-icon.btn-primary:hover:not(:disabled) { background-color: var(--color-primary-hover); }
.btn-icon.btn-secondary {
    background-color: var(--color-accent);
    color: var(--color-on-accent);
}
.btn-icon.btn-secondary:hover:not(:disabled) { background-color: var(--color-accent-hover); }
.btn-icon.btn-outline {
    background-color: transparent;
    border: var(--stroke-sm) solid var(--color-border-default);
    color: var(--color-text-high);
}
.btn-icon.btn-outline:hover:not(:disabled) {
    background-color: var(--color-surface-hover);
    border-color: var(--color-text-medium);
}
.btn-icon.btn-danger {
    background-color: var(--color-error);
    color: var(--color-on-error);
}
.btn-icon.btn-danger:hover:not(:disabled) { filter: brightness(0.95); }

/* ==========================================================================
   INPUTS
   ========================================================================== */
.input-group {
    display: flex;
    flex-direction: column;
    gap: var(--space-xs);
}
.input-group label {
    font: var(--font-label);
    color: var(--color-text-high);
}

.input-field {
    font: var(--font-body);
    padding: var(--space-xs) var(--space-sm);
    border: var(--stroke-sm) solid var(--color-border-default);
    border-radius: var(--radius-md);
    background: var(--color-surface);
    color: var(--color-text-high);
    transition: border-color var(--duration-quick) var(--easing);
}
.input-field:hover { border-color: var(--color-text-medium); }
.input-field:focus-visible {
    outline: none;
    border-width: var(--stroke-md);
    border-color: var(--color-border-focus);
}

.input-group.error .input-field,
.input-group.error .input-field:focus-visible { border-color: var(--color-error); }

.input-group.error label,
.input-group.error .helper-text { color: var(--color-error); }

.input-field:disabled {
    background: var(--color-surface-hover);
    cursor: not-allowed;
    opacity: 0.7;
}

.helper-text {
    font: var(--font-caption);
    color: var(--color-text-medium);
}

/* ==========================================================================
   ALERTS
   ========================================================================== */
.alert {
    display: flex;
    align-items: flex-start;
    gap: var(--space-sm);
    padding: var(--space-sm);
    border-radius: var(--radius-md);
    border: var(--stroke-sm) solid;
}
.alert-content     { flex: 1; }
.alert-title {
    font: var(--font-label);
    margin-bottom: var(--space-xs);
}
.alert-description {
    font: var(--font-caption);
    color: var(--color-text-medium);
    margin: 0;
}

.alert-success {
    background-color: var(--color-success-subtle);
    border-color: var(--color-success);
    color: var(--color-success);
}
.alert-warning {
    background-color: var(--color-warning-subtle);
    border-color: var(--color-warning);
    color: var(--color-warning);
}
.alert-error {
    background-color: var(--color-error-subtle);
    border-color: var(--color-error);
    color: var(--color-error);
}
.alert-info {
    background-color: var(--color-surface-hover);
    border-color: var(--color-border-default);
    color: var(--color-text-medium);
}

/* ==========================================================================
   MODALS
   ========================================================================== */
body.scroll-lock { overflow: hidden; }

.modal-backdrop {
    position: fixed;
    inset: 0;
    background-color: rgb(0 0 0 / 0.5);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--space-md);
    opacity: 0;
    visibility: hidden;
    transition: opacity var(--duration-medium) var(--easing), visibility 0s var(--duration-medium);
    backdrop-filter: blur(2px);
    z-index: var(--z-modal);
}

/* Two-deep stacking max — beyond that is a usability smell. */
.modal-backdrop.is-visible ~ .modal-backdrop { z-index: calc(var(--z-modal) + 100); }

.modal-backdrop.is-visible {
    opacity: 1;
    visibility: visible;
    transition-delay: 0s;
}

.modal-dialog {
    background-color: var(--color-surface);
    border: var(--stroke-sm) solid var(--color-border-default);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg);
    padding: var(--space-sm);
    max-width: 560px;
    width: 90%;
    max-height: calc(100vh - (var(--space-md) * 2));
    display: flex;
    flex-direction: column;
    transform: scale(0.95);
    opacity: 0;
    transition:
        transform var(--duration-medium) var(--easing-decelerate),
        opacity   var(--duration-medium) var(--easing-decelerate);
}
.modal-backdrop.is-visible .modal-dialog {
    transform: scale(1);
    opacity: 1;
}

.modal-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding-bottom: var(--space-sm);
    border-bottom: var(--stroke-sm) solid var(--color-border-default);
}
.modal-title { font: var(--font-h3); }

.modal-titlebar {
    display: inline-flex;
    align-items: center;
    gap: var(--space-xs);
}
.modal-titlebar img {
    height: var(--icon-size-lg);
    width: auto;
    display: block;
}

.modal-body {
    padding: var(--space-sm) 0;
    overflow: auto;
    flex: 1 1 auto;
}
.modal-body h3 { color: var(--color-text-high); margin: 0 0 var(--space-xs) 0; }
.modal-body h4 {
    color: var(--color-text-high);
    font-weight: var(--font-weight-semibold);
    margin: var(--space-sm) 0 var(--space-xs) 0;
}
.modal-body p {
    color: var(--color-text-medium);
    margin-bottom: var(--space-sm);
}
.modal-body ul {
    margin: var(--space-xs) 0;
    padding-left: var(--space-md);
}
.modal-body li { margin-bottom: var(--space-xs); color: var(--color-text-medium); }
.modal-body li:last-child { margin-bottom: 0; }
.modal-body hr {
    border: 0;
    height: var(--stroke-sm);
    background-color: var(--color-border-default);
    margin: var(--space-sm) 0;
}
.modal-body pre {
    background-color: var(--color-background);
    border: var(--stroke-sm) solid var(--color-border-default);
    border-radius: var(--radius-md);
    padding: var(--space-sm);
    overflow: auto;
    margin: var(--space-sm) 0;
}
.modal-body code {
    font-family: var(--font-family-mono);
    font-size: var(--font-size-label);
    color: var(--color-text-high);
}

.modal-footer {
    display: flex;
    justify-content: flex-end;
    gap: var(--space-sm);
    padding-top: var(--space-sm);
    border-top: var(--stroke-sm) solid var(--color-border-default);
}
.modal-footer.has-credit {
    display: grid;
    grid-template-columns: 1fr auto;
    align-items: center;
    gap: var(--space-sm);
}
.modal-credit {
    color: var(--color-text-medium);
    font: var(--font-caption);
}
.modal-credit a {
    color: inherit;
    text-decoration: underline;
    text-underline-offset: 2px;
}

@media (max-width: 480px) {
    .modal-footer.has-credit {
        grid-template-columns: 1fr;
        justify-items: stretch;
    }
    .modal-footer.has-credit .btn {
        width: 100%;
        justify-self: stretch;
    }
}

/* ==========================================================================
   AVATARS
   ========================================================================== */
.avatar {
    display: inline-block;
    border-radius: var(--radius-full);
    background-color: var(--color-primary);
    color: var(--color-on-primary);
    text-align: center;
    font-weight: var(--font-weight-medium);
    object-fit: cover;
}
.avatar-sm {
    width: var(--avatar-size-sm); height: var(--avatar-size-sm);
    line-height: var(--avatar-size-sm); font-size: 0.875rem;
}
.avatar-md {
    width: var(--avatar-size-md); height: var(--avatar-size-md);
    line-height: var(--avatar-size-md); font-size: 1.25rem;
}
.avatar-lg {
    width: var(--avatar-size-lg); height: var(--avatar-size-lg);
    line-height: var(--avatar-size-lg); font-size: 1.75rem;
}

/* ==========================================================================
   TABS  (in-content view switcher; distinct from header navigation)
   ========================================================================== */
.tabs-list {
    display: flex;
    border-bottom: var(--stroke-sm) solid var(--color-border-default);
}

.tab-trigger {
    font: var(--font-label);
    padding: var(--space-xs) var(--space-sm);
    border: none;
    background: none;
    cursor: pointer;
    color: var(--color-text-medium);
    position: relative;
}
.tab-trigger::after {
    content: '';
    position: absolute;
    bottom: -1px;
    left: 0;
    right: 0;
    height: 2px;
    background: var(--color-primary);
    transform: scaleX(0);
    transition: transform var(--duration-medium) var(--easing);
}
.tab-trigger:hover { color: var(--color-text-high); }
.tab-trigger.active { color: var(--color-primary); }
.tab-trigger.active::after { transform: scaleX(1); }

.tab-content { padding-top: var(--space-md); }
.tab-pane { display: none; }
.tab-pane.active { display: block; }

/* ==========================================================================
   DROPDOWNS
   ========================================================================== */
.dropdown {
    position: relative;
    display: inline-block;
}

.dropdown-menu {
    position: absolute;
    top: calc(100% + var(--space-xs));
    right: 0;
    background-color: var(--color-surface);
    border: var(--stroke-sm) solid var(--color-border-default);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-md);
    padding: var(--space-xs);
    min-width: 200px;
    z-index: var(--z-dropdown);
    opacity: 0;
    visibility: hidden;
    transform: translateY(-8px);
    transition:
        opacity   var(--duration-medium) var(--easing),
        transform var(--duration-medium) var(--easing),
        visibility 0s var(--duration-medium);
}
.dropdown-menu.is-visible {
    opacity: 1;
    visibility: visible;
    transform: translateY(0);
    transition-delay: 0s;
}

/* Directional variants. JS toggles these based on viewport collision so
   the menu always lands inside the viewport. Defaults open down-right. */
.dropdown-menu.is-above {
    top: auto;
    bottom: calc(100% + var(--space-xs));
    transform: translateY(8px);
}
.dropdown-menu.is-above.is-visible { transform: translateY(0); }

.dropdown-menu.is-aligned-left {
    right: auto;
    left: 0;
}

.dropdown-item {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
    width: 100%;
    padding: var(--space-xs) var(--space-sm);
    border: none;
    background: none;
    text-align: left;
    font: var(--font-label);
    color: var(--color-text-high);
    border-radius: var(--radius-md);
    cursor: pointer;
}
.dropdown-item:hover { background-color: var(--color-surface-hover); }
.dropdown-item:focus-visible {
    outline: var(--stroke-md) solid var(--color-border-focus);
    outline-offset: 2px;
    background-color: var(--color-surface-hover);
}
.dropdown-item .material-symbols-rounded {
    font-size: var(--icon-size-md);
    color: currentColor;
}
.dropdown-divider {
    height: var(--stroke-sm);
    background-color: var(--color-border-default);
    margin: var(--space-xs) 0;
}

/* ==========================================================================
   PROGRESS
   ========================================================================== */
.progress-bar {
    width: 100%;
    height: var(--progress-height);
    background-color: var(--color-border-default);
    border-radius: var(--radius-full);
    overflow: hidden;
}
.progress-indicator {
    height: 100%;
    background-color: var(--color-primary);
    border-radius: var(--radius-full);
    transition: width var(--duration-medium) var(--easing);
}
.progress-indicator-active {
    position: relative;
    overflow: hidden;
}
.progress-indicator-active::after {
    content: '';
    position: absolute;
    inset: 0;
    background: linear-gradient(90deg, transparent, rgb(255 255 255 / 0.3), transparent);
    animation: rx-shimmer 2s infinite;
}
@keyframes rx-shimmer {
    0%   { transform: translateX(-100%); }
    100% { transform: translateX(100%);  }
}

/* ==========================================================================
   PILL SELECTOR  (canonical names; previously also .pill-group / .pill-selector-group)
   ========================================================================== */
.pill-selector {
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: var(--pill-gap);
    background-color: var(--color-background);
    border-radius: var(--radius-full);
    padding: var(--pill-padding);
    border: var(--stroke-sm) solid var(--color-border-default);
}

.pill-selector-track {
    position: absolute;
    background-color: var(--color-primary);
    border-radius: var(--radius-full);
    transition:
        left  var(--duration-medium) var(--easing),
        width var(--duration-medium) var(--easing);
    z-index: 2;
    pointer-events: none;
    height: 32px;
    top: var(--pill-padding);
    margin: 0;
}
.pill-selector-track.hidden { display: none !important; }

.pill-selector-button {
    font: var(--font-label);
    padding: var(--space-xs) var(--space-sm);
    border-radius: var(--radius-full);
    border: none;
    background-color: transparent;
    color: var(--color-text-medium);
    cursor: pointer;
    transition:
        color            var(--duration-medium) var(--easing),
        background-color var(--duration-medium) var(--easing);
    z-index: 3;
    white-space: nowrap;
    position: relative;
}
.pill-selector-button::before {
    content: '';
    position: absolute;
    inset: 0;
    background-color: transparent;
    border-radius: var(--radius-full);
    transition: background-color var(--duration-medium) var(--easing);
    z-index: -1;
}
.pill-selector-button:hover:not(.active)::before { background-color: var(--color-surface-hover); }
.pill-selector-button:hover:not(.active)         { color: var(--color-text-high); }
.pill-selector-button.active                     { color: var(--color-on-primary); }

/* ==========================================================================
   SLIDER
   ========================================================================== */
.slider,
.slider-filled {
    -webkit-appearance: none;
    appearance: none;
    width: 100%;
    height: var(--progress-height);
    background: var(--color-border-default);
    border-radius: var(--radius-full);
    outline: none;
    opacity: 0.9;
    transition: opacity var(--duration-quick) var(--easing);
}
.slider:hover, .slider-filled:hover { opacity: 1; }

.slider::-webkit-slider-thumb,
.slider-filled::-webkit-slider-thumb {
    -webkit-appearance: none;
    appearance: none;
    width: var(--icon-size-md);
    height: var(--icon-size-md);
    background: var(--color-primary);
    border-radius: 50%;
    cursor: pointer;
    border: 2px solid var(--color-surface);
    box-shadow: var(--shadow-sm);
}
.slider::-moz-range-thumb,
.slider-filled::-moz-range-thumb {
    width: var(--icon-size-md);
    height: var(--icon-size-md);
    background: var(--color-primary);
    border-radius: 50%;
    cursor: pointer;
    border: 2px solid var(--color-surface);
    box-shadow: var(--shadow-sm);
}

.slider-filled::-moz-range-track { background: transparent; }

.slider:focus-visible::-webkit-slider-thumb,
.slider-filled:focus-visible::-webkit-slider-thumb {
    outline: var(--stroke-md) solid var(--color-border-focus);
    outline-offset: 2px;
}

.slider-value-label {
    position: absolute;
    top: -8px;
    background-color: var(--color-text-high);
    color: var(--color-surface);
    padding: var(--space-xs);
    border-radius: var(--radius-sm);
    font: var(--font-caption);
    transform: translateX(-50%);
    white-space: nowrap;
    opacity: 0;
    transition: opacity var(--duration-quick);
}

/* ==========================================================================
   SWITCH
   ========================================================================== */
.switch {
    display: inline-flex;
    align-items: center;
    gap: var(--space-sm);
    cursor: pointer;
}
.switch input {
    opacity: 0;
    width: 0;
    height: 0;
    position: absolute;
}
.switch-track {
    position: relative;
    width: var(--switch-track-width);
    height: var(--switch-track-height);
    background: var(--color-border-default);
    border-radius: var(--radius-full);
    transition: background-color var(--duration-quick) var(--easing);
}
.switch-thumb {
    position: absolute;
    top: var(--switch-thumb-offset);
    left: var(--switch-thumb-offset);
    width: var(--switch-thumb-size);
    height: var(--switch-thumb-size);
    background: var(--white);
    border-radius: 50%;
    box-shadow: var(--shadow-sm);
    transition: transform var(--duration-quick) var(--easing);
}
.switch input:focus-visible + .switch-track {
    outline: var(--stroke-md) solid var(--color-border-focus);
    outline-offset: 2px;
}
.switch input:checked + .switch-track { background: var(--color-primary); }
.switch input:checked + .switch-track .switch-thumb {
    transform: translateX(calc(var(--switch-track-width) - var(--switch-thumb-size) - (2 * var(--switch-thumb-offset))));
}
.switch-label {
    font: var(--font-label);
    color: var(--color-text-high);
}

/* ==========================================================================
   CARDS
   ========================================================================== */
.card {
    background-color: var(--color-surface);
    border: var(--stroke-sm) solid var(--color-border-default);
    border-radius: var(--radius-lg);
    padding: var(--space-md);
    box-shadow: var(--shadow-md);
}

.card-interactive {
    cursor: pointer;
    transition:
        transform  var(--duration-quick) var(--easing),
        box-shadow var(--duration-quick) var(--easing);
}
.card-interactive:hover {
    transform: translateY(-4px);
    box-shadow: var(--shadow-lg);
}
.card-interactive:focus-visible {
    outline: var(--stroke-md) solid var(--color-border-focus);
    outline-offset: 2px;
}

/* ==========================================================================
   HEADER BRAND  (pill-shaped wordmark wrapper that rhymes with header nav)
   ========================================================================== */
.header-brand {
    display: inline-flex;
    align-items: center;
    font: var(--font-h3);
    letter-spacing: var(--letter-spacing-heading);
    color: var(--color-text-high);
    white-space: nowrap;
    padding: var(--space-2xs) var(--space-sm);
    border-radius: var(--radius-full);
    border: var(--stroke-sm) solid var(--color-border-default);
    flex-shrink: 0;
}

/* ==========================================================================
   HEADER NAV  (pill-selector + hamburger fallback for narrow containers)
   ========================================================================== */
.header-nav {
    display: flex;
    align-items: stretch;
    gap: 0;
    flex: 1;
    min-width: 0;
    position: relative;
}

/* Brand and pill-selector sit flush to read as one continuous pill. */
.header-nav > .header-brand {
    background-color: var(--color-background);
    border-top-right-radius: 0;
    border-bottom-right-radius: 0;
    border-right: none;
}
.header-nav > .header-nav-items {
    border-top-left-radius: 0;
    border-bottom-left-radius: 0;
}

/* Center the toggle + title vertically when nav stretches. */
.header-nav-toggle,
.header-nav-title { align-self: center; }

.header-nav-toggle {
    display: none;
    flex-shrink: 0;
}

.header-nav-title {
    display: none;
    color: var(--color-text-high);
    font: var(--font-label);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    flex: 1;
    min-width: 0;
}

.header-nav-items { display: inline-flex; }

/* Compact mode: hamburger replaces inline pills */
.header-nav.is-compact .header-nav-toggle { display: inline-flex; }
.header-nav.is-compact .header-nav-title  { display: block; }

/* Compact mode: hamburger becomes the right cap of the brand pill. */
.header-nav.is-compact > .header-nav-toggle {
    width: auto;
    height: auto;
    align-self: stretch;
    padding: 0 var(--space-sm);
    background-color: var(--color-background);
    border: var(--stroke-sm) solid var(--color-border-default);
    border-left: none;
    border-top-left-radius: 0;
    border-bottom-left-radius: 0;
    border-top-right-radius: var(--radius-full);
    border-bottom-right-radius: var(--radius-full);
    color: var(--color-text-medium);
}
.header-nav.is-compact > .header-nav-toggle:hover:not(:disabled) {
    background-color: var(--color-surface-hover);
}

/* Title gets breathing room after the unified pill. */
.header-nav.is-compact > .header-nav-title { margin-left: var(--space-sm); }

.header-nav.is-compact .header-nav-items {
    position: absolute;
    top: calc(100% + var(--space-xs));
    left: 0;
    display: flex;
    flex-direction: column;
    align-items: stretch;
    background: var(--color-surface);
    border: var(--stroke-sm) solid var(--color-border-default);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-md);
    padding: var(--space-xs);
    min-width: 200px;
    z-index: var(--z-dropdown);
    opacity: 0;
    visibility: hidden;
    transform: translateY(-8px);
    transition:
        opacity   var(--duration-quick) var(--easing),
        transform var(--duration-quick) var(--easing),
        visibility 0s var(--duration-quick);
}
.header-nav.is-compact .header-nav-items.is-visible {
    opacity: 1;
    visibility: visible;
    transform: translateY(0);
    transition-delay: 0s;
}

/* Hide the animated track in compact mode (vertical list, no slider). */
.header-nav.is-compact .pill-selector-track { display: none; }

/* Stack pills vertically in compact mode. */
.header-nav.is-compact .pill-selector-button {
    width: 100%;
    text-align: left;
    justify-content: flex-start;
    border-radius: var(--radius-md);
    padding: var(--space-xs) var(--space-sm);
}
.header-nav.is-compact .pill-selector-button.active {
    background-color: var(--color-surface-hover);
    color: var(--color-text-high);
}

/* ==========================================================================
   MOBILE DENSITY OVERRIDES
   Components with desktop-comfortable padding tighten on narrow viewports.
   Mirrors the dense mobile-first rhythm proven in production (web-kmap).
   ========================================================================== */
@media (max-width: 640px) {
    .card { padding: var(--space-sm); }              /* 24 → 16 */
    .modal-backdrop { padding: var(--space-2xs); }   /* 24 → 4, maximizes dialog room */
}
