/*!
 * Volty v0.1.3
 * Modern CSS theme library — typed design tokens, native Shadow DOM theming, zero build step
 * MIT License
 * Built: 2026-04-20T23:24:19.334Z
 */

/* ==============================================================================
   1. LAYERS — src/core/layers.css
   ======================================================================= */

/* Establish layer order — later layers win */
@layer volty.reset, volty.tokens, volty.base, volty.components, volty.utilities;


/* ==============================================================================
   2. PROPERTIES — src/core/properties.css
   =================================================================== */

/* =============================================================================
   @property token registrations
   Typed syntax enables: animation, transition, validation, and computed fallbacks.
   These are the things no untyped custom property can do.
   ============================================================================= */

/* --- Surface colors -------------------------------------------------------- */
@property --vt-color-brand {
  syntax: "<color>";
  inherits: true;
  initial-value: oklch(55% 0.2 250);
}
@property --vt-color-surface {
  syntax: "<color>";
  inherits: true;
  initial-value: oklch(98% 0 0);
}
@property --vt-color-surface-raised {
  syntax: "<color>";
  inherits: true;
  initial-value: oklch(96% 0 0);
}
@property --vt-color-surface-overlay {
  syntax: "<color>";
  inherits: true;
  initial-value: oklch(100% 0 0);
}
@property --vt-color-text {
  syntax: "<color>";
  inherits: true;
  initial-value: oklch(15% 0 0);
}
@property --vt-color-text-muted {
  syntax: "<color>";
  inherits: true;
  initial-value: oklch(45% 0 0);
}
@property --vt-color-border {
  syntax: "<color>";
  inherits: true;
  initial-value: oklch(85% 0 0);
}
@property --vt-color-brand-text {
  syntax: "<color>";
  inherits: true;
  initial-value: white;
}

/* --- Derived brand colors (registered so they can be transitioned) --------- */
@property --vt-color-brand-hover {
  syntax: "<color>";
  inherits: true;
  initial-value: oklch(45% 0.2 250);
}
@property --vt-color-brand-active {
  syntax: "<color>";
  inherits: true;
  initial-value: oklch(38% 0.2 250);
}
@property --vt-color-brand-subtle {
  syntax: "<color>";
  inherits: true;
  initial-value: oklch(97% 0.03 250);
}
@property --vt-color-brand-ring {
  syntax: "<color>";
  inherits: true;
  initial-value: oklch(55% 0.2 250 / 40%);
}

/* --- Semantic colors ------------------------------------------------------- */
@property --vt-color-success {
  syntax: "<color>";
  inherits: true;
  initial-value: oklch(55% 0.15 145);
}
@property --vt-color-warning {
  syntax: "<color>";
  inherits: true;
  initial-value: oklch(70% 0.18 70);
}
@property --vt-color-danger {
  syntax: "<color>";
  inherits: true;
  initial-value: oklch(55% 0.22 25);
}
@property --vt-color-info {
  syntax: "<color>";
  inherits: true;
  initial-value: oklch(60% 0.15 240);
}
@property --vt-color-success-subtle {
  syntax: "<color>";
  inherits: true;
  initial-value: oklch(97% 0.03 145);
}
@property --vt-color-warning-subtle {
  syntax: "<color>";
  inherits: true;
  initial-value: oklch(97% 0.03 70);
}
@property --vt-color-danger-subtle {
  syntax: "<color>";
  inherits: true;
  initial-value: oklch(97% 0.03 25);
}
@property --vt-color-info-subtle {
  syntax: "<color>";
  inherits: true;
  initial-value: oklch(97% 0.03 240);
}

/* --- Spacing tokens — typed as <length> ----------------------------------- */
@property --vt-space-1  { syntax: "<length>"; inherits: true; initial-value: 4px; }
@property --vt-space-2  { syntax: "<length>"; inherits: true; initial-value: 8px; }
@property --vt-space-3  { syntax: "<length>"; inherits: true; initial-value: 12px; }
@property --vt-space-4  { syntax: "<length>"; inherits: true; initial-value: 16px; }
@property --vt-space-5  { syntax: "<length>"; inherits: true; initial-value: 24px; }
@property --vt-space-6  { syntax: "<length>"; inherits: true; initial-value: 32px; }
@property --vt-space-8  { syntax: "<length>"; inherits: true; initial-value: 48px; }
@property --vt-space-10 { syntax: "<length>"; inherits: true; initial-value: 64px; }

/* --- Radius tokens --------------------------------------------------------- */
@property --vt-radius-sm   { syntax: "<length>"; inherits: true; initial-value: 4px; }
@property --vt-radius-md   { syntax: "<length>"; inherits: true; initial-value: 8px; }
@property --vt-radius-lg   { syntax: "<length>"; inherits: true; initial-value: 12px; }
@property --vt-radius-xl   { syntax: "<length>"; inherits: true; initial-value: 16px; }
@property --vt-radius-full { syntax: "<length>"; inherits: true; initial-value: 9999px; }

/* --- Font size tokens ------------------------------------------------------ */
@property --vt-text-xs   { syntax: "<length>"; inherits: true; initial-value: 12px; }
@property --vt-text-sm   { syntax: "<length>"; inherits: true; initial-value: 14px; }
@property --vt-text-base { syntax: "<length>"; inherits: true; initial-value: 16px; }
@property --vt-text-lg   { syntax: "<length>"; inherits: true; initial-value: 18px; }
@property --vt-text-xl   { syntax: "<length>"; inherits: true; initial-value: 20px; }
@property --vt-text-2xl  { syntax: "<length>"; inherits: true; initial-value: 24px; }
@property --vt-text-3xl  { syntax: "<length>"; inherits: true; initial-value: 30px; }
@property --vt-text-4xl  { syntax: "<length>"; inherits: true; initial-value: 36px; }

/* --- Transition speed tokens —typed as <time> ------------------------------ */
@property --vt-duration-fast { syntax: "<time>"; inherits: true; initial-value: 100ms; }
@property --vt-duration-base { syntax: "<time>"; inherits: true; initial-value: 200ms; }
@property --vt-duration-slow { syntax: "<time>"; inherits: true; initial-value: 350ms; }


/* ==============================================================================
   3. COLORS — src/core/colors.css
   ======================================================================= */

@layer volty.tokens {
  :root, [data-theme] {
    /* --- Brand scale ------------------------------------------------------- */
    /* Mixes toward surface (not white) so it works correctly in dark mode too */
    --vt-brand-50:  color-mix(in oklch, var(--vt-color-brand) 10%, var(--vt-color-surface));
    --vt-brand-100: color-mix(in oklch, var(--vt-color-brand) 20%, var(--vt-color-surface));
    --vt-brand-200: color-mix(in oklch, var(--vt-color-brand) 35%, var(--vt-color-surface));
    --vt-brand-300: color-mix(in oklch, var(--vt-color-brand) 55%, var(--vt-color-surface));
    --vt-brand-400: color-mix(in oklch, var(--vt-color-brand) 75%, var(--vt-color-surface));
    --vt-brand-500: var(--vt-color-brand);
    --vt-brand-600: color-mix(in oklch, var(--vt-color-brand) 85%, black);
    --vt-brand-700: color-mix(in oklch, var(--vt-color-brand) 70%, black);
    --vt-brand-800: color-mix(in oklch, var(--vt-color-brand) 55%, black);
    --vt-brand-900: color-mix(in oklch, var(--vt-color-brand) 35%, black);
    --vt-brand-950: color-mix(in oklch, var(--vt-color-brand) 20%, black);

    /* --- Interactive brand states ----------------------------------------- */
    /* light-dark() so hover LIGHTENS in dark mode instead of darkening */
    --vt-color-brand-hover:  light-dark(
      color-mix(in oklch, var(--vt-color-brand) 85%, black),
      color-mix(in oklch, var(--vt-color-brand) 80%, white)
    );
    --vt-color-brand-active: light-dark(
      color-mix(in oklch, var(--vt-color-brand) 70%, black),
      color-mix(in oklch, var(--vt-color-brand) 65%, white)
    );

    /* Subtle tint — blends into the current surface, not hardcoded white */
    --vt-color-brand-subtle: color-mix(in oklch, var(--vt-color-brand) 15%, var(--vt-color-surface));

    /* Focus ring — semi-transparent, works on any background */
    --vt-color-brand-ring: color-mix(in oklch, var(--vt-color-brand) 40%, transparent);

    /* --- Semantic colors --------------------------------------------------- */
    --vt-color-success: light-dark(oklch(52% 0.15 145), oklch(68% 0.15 145));
    --vt-color-warning: light-dark(oklch(60% 0.18 70),  oklch(75% 0.18 70));
    --vt-color-danger:  light-dark(oklch(52% 0.22 25),  oklch(67% 0.22 25));
    --vt-color-info:    light-dark(oklch(55% 0.15 240), oklch(70% 0.15 240));

    /* Semantic subtle — mixes into surface, correct in both modes */
    --vt-color-success-subtle: color-mix(in oklch, var(--vt-color-success) 15%, var(--vt-color-surface));
    --vt-color-warning-subtle: color-mix(in oklch, var(--vt-color-warning) 15%, var(--vt-color-surface));
    --vt-color-danger-subtle:  color-mix(in oklch, var(--vt-color-danger)  15%, var(--vt-color-surface));
    --vt-color-info-subtle:    color-mix(in oklch, var(--vt-color-info)    15%, var(--vt-color-surface));
  }
}


/* ==============================================================================
   4. TYPOGRAPHY — src/core/typography.css
   =================================================================== */

@layer volty.base {
  :root {
    --vt-font-sans: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
    --vt-font-mono: ui-monospace, "Cascadia Code", "Fira Code", monospace;
    --vt-font-weight-normal: 400;
    --vt-font-weight-medium: 500;
    --vt-font-weight-semibold: 600;
    --vt-font-weight-bold: 700;
    --vt-line-height-tight: 1.25;
    --vt-line-height-base: 1.5;
    --vt-line-height-relaxed: 1.75;

    /* Fluid type scale — scales between viewport breakpoints */
    --vt-text-xs:   clamp(0.69rem,  0.66rem + 0.14vw, 0.75rem);
    --vt-text-sm:   clamp(0.83rem,  0.78rem + 0.24vw, 0.875rem);
    --vt-text-base: clamp(1rem,     0.95rem + 0.28vw, 1rem);
    --vt-text-lg:   clamp(1.13rem,  1.06rem + 0.35vw, 1.25rem);
    --vt-text-xl:   clamp(1.25rem,  1.14rem + 0.54vw, 1.5rem);
    --vt-text-2xl:  clamp(1.5rem,   1.32rem + 0.89vw, 1.875rem);
    --vt-text-3xl:  clamp(1.75rem,  1.51rem + 1.2vw,  2.25rem);
    --vt-text-4xl:  clamp(2rem,     1.67rem + 1.65vw, 3rem);
    --vt-text-5xl:  clamp(2.5rem,   2rem + 2.5vw,     4rem);
  }

  html {
    font-family: var(--vt-font-sans);
    font-size: var(--vt-text-base);
    line-height: var(--vt-line-height-base);
    color: var(--vt-color-text);
    background-color: var(--vt-color-surface);
    -webkit-font-smoothing: antialiased;
  }
}


/* ==============================================================================
   5. SPACING — src/core/spacing.css
   ====================================================================== */

@layer volty.base {
  *, *::before, *::after {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
  }

  :root {
    /* Fluid spacing scale */
    --vt-space-1:  clamp(0.25rem, 0.23rem + 0.09vw, 0.25rem);
    --vt-space-2:  clamp(0.5rem,  0.47rem + 0.14vw, 0.5rem);
    --vt-space-3:  clamp(0.75rem, 0.69rem + 0.28vw, 0.875rem);
    --vt-space-4:  clamp(1rem,    0.94rem + 0.28vw, 1.125rem);
    --vt-space-5:  clamp(1.5rem,  1.36rem + 0.68vw, 1.75rem);
    --vt-space-6:  clamp(2rem,    1.84rem + 0.8vw,  2.25rem);
    --vt-space-8:  clamp(3rem,    2.72rem + 1.4vw,  3.5rem);
    --vt-space-10: clamp(4rem,    3.62rem + 1.9vw,  5rem);
  }
}


/* ==============================================================================
   6. THEME — BASE — src/themes/base.css
   ================================================================= */

@layer volty.tokens {
  /* System preference — no JS needed */
  :root {
    color-scheme: light dark;

    --vt-color-brand:           light-dark(oklch(55% 0.2 250),  oklch(65% 0.2 250));
    --vt-color-surface:         light-dark(oklch(98% 0 0),      oklch(14% 0 0));
    --vt-color-surface-raised:  light-dark(oklch(96% 0 0),      oklch(18% 0 0));
    --vt-color-surface-overlay: light-dark(oklch(100% 0 0),     oklch(20% 0 0));
    --vt-color-text:            light-dark(oklch(15% 0 0),      oklch(92% 0 0));
    --vt-color-text-muted:      light-dark(oklch(50% 0 0),      oklch(60% 0 0));
    --vt-color-border:          light-dark(oklch(88% 0 0),      oklch(28% 0 0));
    --vt-color-brand-text:      light-dark(white,               oklch(10% 0 0));
  }

  /* ==========================================================================
     CSS custom property transitions — the @property differentiator.

     Because all surface/text/border tokens are registered as typed <color>
     via @property, the browser knows HOW to interpolate them. Setting
     transition: --vt-color-* on :root means every element in the page
     inherits those transitions automatically — no per-element transition
     rules needed, and no JavaScript animation loops.

     Try this with untyped variables: it won't work. The browser can't
     interpolate an untyped string like "oklch(98% 0 0)".
     ========================================================================== */
  @media (prefers-reduced-motion: no-preference) {
    :root, [data-theme] {
      transition:
        --vt-color-surface         var(--vt-duration-slow) ease,
        --vt-color-surface-raised  var(--vt-duration-slow) ease,
        --vt-color-surface-overlay var(--vt-duration-slow) ease,
        --vt-color-text            var(--vt-duration-slow) ease,
        --vt-color-text-muted      var(--vt-duration-slow) ease,
        --vt-color-border          var(--vt-duration-slow) ease,
        --vt-color-brand           var(--vt-duration-slow) ease,
        --vt-color-brand-text      var(--vt-duration-slow) ease;
    }
  }

  /* Explicit light theme override */
  [data-theme="light"] {
    color-scheme: light;
    --vt-color-brand:           oklch(55% 0.2 250);
    --vt-color-surface:         oklch(98% 0 0);
    --vt-color-surface-raised:  oklch(96% 0 0);
    --vt-color-surface-overlay: oklch(100% 0 0);
    --vt-color-text:            oklch(15% 0 0);
    --vt-color-text-muted:      oklch(50% 0 0);
    --vt-color-border:          oklch(88% 0 0);
    --vt-color-brand-text:      white;
  }

  /* Explicit dark theme override */
  [data-theme="dark"] {
    color-scheme: dark;
    --vt-color-brand:           oklch(65% 0.2 250);
    --vt-color-surface:         oklch(14% 0 0);
    --vt-color-surface-raised:  oklch(18% 0 0);
    --vt-color-surface-overlay: oklch(20% 0 0);
    --vt-color-text:            oklch(92% 0 0);
    --vt-color-text-muted:      oklch(60% 0 0);
    --vt-color-border:          oklch(28% 0 0);
    --vt-color-brand-text:      oklch(10% 0 0);
  }

  /* Contextual brand themes — scope to any element with data-brand */
  /* Brand tokens also transition because they're @property registered */
  [data-brand="violet"]  { --vt-color-brand: light-dark(oklch(55% 0.22 290), oklch(68% 0.22 290)); }
  [data-brand="emerald"] { --vt-color-brand: light-dark(oklch(52% 0.18 155), oklch(65% 0.18 155)); }
  [data-brand="rose"]    { --vt-color-brand: light-dark(oklch(55% 0.22 10),  oklch(67% 0.22 10)); }
  [data-brand="amber"]   { --vt-color-brand: light-dark(oklch(65% 0.2 65),   oklch(75% 0.2 65)); }
  [data-brand="cyan"]    { --vt-color-brand: light-dark(oklch(58% 0.18 200), oklch(70% 0.18 200)); }
}


/* ==============================================================================
   7. THEME — DARK — src/themes/dark.css
   ================================================================= */

/*
 * Volty Dark Theme Overrides
 *
 * This file can be imported separately if you want to apply the dark theme
 * exclusively without light-dark() auto-switching. The base.css file already
 * includes [data-theme="dark"] overrides; this file provides additional
 * dark-specific refinements and serves as a standalone reference.
 *
 * Usage: Import after base.css if you need manual dark-only control.
 */

@layer volty.tokens {
  /* Dark-mode semantic color adjustments — warmer tones for better contrast */
  [data-theme="dark"] {
    --vt-color-success: oklch(62% 0.15 145);
    --vt-color-warning: oklch(75% 0.18 70);
    --vt-color-danger:  oklch(62% 0.22 25);
    --vt-color-info:    oklch(67% 0.15 240);

    /* In dark mode, subtle colors mix with dark surface instead of white */
    --vt-color-success-subtle: color-mix(in oklch, var(--vt-color-success) 18%, oklch(18% 0 0));
    --vt-color-warning-subtle: color-mix(in oklch, var(--vt-color-warning) 18%, oklch(18% 0 0));
    --vt-color-danger-subtle:  color-mix(in oklch, var(--vt-color-danger) 18%, oklch(18% 0 0));
    --vt-color-info-subtle:    color-mix(in oklch, var(--vt-color-info) 18%, oklch(18% 0 0));

    /* Brand scale also mixes with dark surface */
    --vt-brand-50:  color-mix(in oklch, var(--vt-color-brand) 10%, oklch(14% 0 0));
    --vt-brand-100: color-mix(in oklch, var(--vt-color-brand) 20%, oklch(14% 0 0));
    --vt-brand-200: color-mix(in oklch, var(--vt-color-brand) 35%, oklch(14% 0 0));
    --vt-color-brand-subtle: color-mix(in oklch, var(--vt-color-brand) 18%, oklch(14% 0 0));
  }
}


/* ==============================================================================
   8. COMPONENT — NAV — src/components/nav.css
   ============================================================== */

@layer volty.components {
  /*
    Nav — sticky top navigation bar.
    Used directly as .vt-nav markup, or rendered by the <vt-nav> custom element.

    Manual usage:
      <nav class="vt-nav">
        <div class="vt-nav__inner">
          <a href="/" class="vt-nav__logo">
            <div class="vt-nav__logo-mark">A</div>
            <span class="vt-nav__logo-name">App</span>
          </a>
          <div class="vt-nav__links">
            <a href="/" class="vt-nav__link">Home</a>
          </div>
          <div class="vt-nav__controls">...</div>
        </div>
      </nav>

    Custom element (auto-rendered):
      <vt-nav logo="My App" version="v1.0"
              links='[{"href":"/","label":"Home"},{"href":"/docs","label":"Docs"}]'>
      </vt-nav>

    Data attribute:
      <div data-vt-insert="nav" data-logo="My App"
           data-links='[{"href":"/","label":"Home"}]'></div>

    JS API:
      Volty.insert('nav', target, { logo: 'My App', links: [...] });
  */

  .vt-nav {
    position: sticky;
    top: 0;
    z-index: 100;
    background-color: color-mix(in oklch, var(--vt-color-surface) 88%, transparent);
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
    border-block-end: 1px solid var(--vt-color-border);
    padding-block: var(--vt-space-3);
    transition:
      background-color var(--vt-duration-base) ease,
      border-color var(--vt-duration-base) ease;
  }

  .vt-nav__inner {
    max-width: 1280px;
    margin-inline: auto;
    padding-inline: var(--vt-space-5);
    display: grid;
    grid-template-columns: auto 1fr auto;
    align-items: center;
    gap: var(--vt-space-4);
  }

  /* ---- Logo -------------------------------------------------------------- */
  .vt-nav__logo {
    display: flex;
    align-items: center;
    gap: var(--vt-space-2);
    text-decoration: none;
    flex-shrink: 0;
  }

  .vt-nav__logo-mark {
    width: 32px;
    height: 32px;
    border-radius: var(--vt-radius-md);
    background: var(--vt-color-brand);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 16px;
    font-weight: 700;
    color: var(--vt-color-brand-text);
    letter-spacing: -0.03em;
    flex-shrink: 0;
    transition: background-color var(--vt-duration-base) ease;
  }

  .vt-nav__logo-img {
    height: 32px;
    width: auto;
    flex-shrink: 0;
    display: block;
  }

  .vt-nav__logo-name {
    font-size: var(--vt-text-lg);
    font-weight: var(--vt-font-weight-bold);
    color: var(--vt-color-text);
    letter-spacing: -0.02em;
    transition: color var(--vt-duration-base) ease;
  }

  /* ---- Links ------------------------------------------------------------- */
  .vt-nav__links {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--vt-space-1);
    flex-wrap: wrap;
  }

  .vt-nav__link {
    padding-block: var(--vt-space-1);
    padding-inline: var(--vt-space-3);
    border-radius: var(--vt-radius-md);
    font-size: var(--vt-text-sm);
    font-weight: var(--vt-font-weight-medium);
    color: var(--vt-color-text-muted);
    text-decoration: none;
    transition:
      color var(--vt-duration-fast) ease,
      background-color var(--vt-duration-fast) ease;
  }

  .vt-nav__link:hover {
    color: var(--vt-color-text);
    background-color: var(--vt-color-surface-raised);
  }

  .vt-nav__link.is-active {
    color: var(--vt-color-brand);
    background-color: var(--vt-color-brand-subtle);
  }

  /* ---- Controls ---------------------------------------------------------- */
  .vt-nav__controls {
    display: flex;
    align-items: center;
    gap: var(--vt-space-3);
    flex-wrap: wrap;
  }

  .vt-nav__theme-toggle {
    display: flex;
    align-items: center;
    gap: var(--vt-space-1);
    background-color: var(--vt-color-surface-raised);
    border: 1px solid var(--vt-color-border);
    border-radius: var(--vt-radius-lg);
    padding: 3px;
    transition:
      background-color var(--vt-duration-base) ease,
      border-color var(--vt-duration-base) ease;
  }

  .vt-nav__theme-btn {
    padding-block: 5px;
    padding-inline: var(--vt-space-3);
    border-radius: var(--vt-radius-md);
    font-size: var(--vt-text-xs);
    font-weight: var(--vt-font-weight-medium);
    color: var(--vt-color-text-muted);
    background: transparent;
    border: none;
    cursor: pointer;
    transition:
      background-color var(--vt-duration-fast) ease,
      color var(--vt-duration-fast) ease;
  }

  .vt-nav__theme-btn:hover {
    color: var(--vt-color-text);
    background-color: var(--vt-color-surface-overlay);
  }

  .vt-nav__theme-btn.is-active {
    background-color: var(--vt-color-surface-overlay);
    color: var(--vt-color-text);
    box-shadow: 0 1px 3px color-mix(in oklch, var(--vt-color-text) 10%, transparent);
  }

  /* ---- Responsive -------------------------------------------------------- */
  @media (max-width: 700px) {
    .vt-nav__inner {
      grid-template-columns: 1fr auto;
      grid-template-rows: auto auto;
    }
    .vt-nav__links {
      grid-column: 1 / -1;
      justify-content: flex-start;
    }
  }
}


/* ==============================================================================
   9. COMPONENT — BUTTON — src/components/button.css
   =========================================================== */

@layer volty.components {
  .vt-btn {
    /* Layout */
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--vt-space-2);

    /* Sizing */
    padding-block: var(--vt-space-2);
    padding-inline: var(--vt-space-4);
    border-radius: var(--vt-radius-md);

    /* Typography */
    font-family: var(--vt-font-sans);
    font-size: var(--vt-text-sm);
    font-weight: var(--vt-font-weight-medium);
    line-height: var(--vt-line-height-tight);
    white-space: nowrap;
    text-decoration: none;

    /* Colors */
    background-color: var(--vt-color-brand);
    color: var(--vt-color-brand-text);
    border: 1px solid transparent;

    /* Interaction */
    cursor: pointer;
    user-select: none;

    /*
      Transition background-color, not the custom property directly here —
      @property transitions on :root already handle theme-level color changes.
      Component-level transitions handle per-interaction state changes.
    */
    transition:
      background-color var(--vt-duration-fast) ease,
      color var(--vt-duration-fast) ease,
      border-color var(--vt-duration-fast) ease,
      box-shadow var(--vt-duration-fast) ease,
      outline-offset var(--vt-duration-fast) ease,
      translate var(--vt-duration-fast) ease;

    /* Focus ring */
    outline: 2px solid transparent;
    outline-offset: 0px;
  }

  .vt-btn:hover:not(:disabled) {
    background-color: var(--vt-color-brand-hover);
  }

  .vt-btn:active:not(:disabled) {
    background-color: var(--vt-color-brand-active);
    translate: 0 1px;
  }

  .vt-btn:focus-visible {
    outline-color: var(--vt-color-brand-ring);
    outline-offset: 3px;
  }

  /* Size variants */
  .vt-btn--sm {
    padding-block: calc(var(--vt-space-1) + 1px);
    padding-inline: var(--vt-space-3);
    font-size: var(--vt-text-xs);
    border-radius: var(--vt-radius-sm);
  }

  .vt-btn--lg {
    padding-block: var(--vt-space-3);
    padding-inline: var(--vt-space-6);
    font-size: var(--vt-text-base);
    border-radius: var(--vt-radius-lg);
  }

  /* Style variants */
  .vt-btn--outline {
    background-color: transparent;
    color: var(--vt-color-brand);
    border-color: var(--vt-color-brand);
  }
  .vt-btn--outline:hover:not(:disabled) {
    background-color: var(--vt-color-brand-subtle);
  }
  .vt-btn--outline:active:not(:disabled) {
    background-color: color-mix(in oklch, var(--vt-color-brand) 20%, var(--vt-color-surface));
  }

  .vt-btn--ghost {
    background-color: transparent;
    color: var(--vt-color-brand);
    border-color: transparent;
  }
  .vt-btn--ghost:hover:not(:disabled) {
    background-color: var(--vt-color-brand-subtle);
  }

  .vt-btn--surface {
    background-color: var(--vt-color-surface-raised);
    color: var(--vt-color-text);
    border-color: var(--vt-color-border);
  }
  .vt-btn--surface:hover:not(:disabled) {
    background-color: var(--vt-color-surface-overlay);
  }

  /* Danger variant — scopes brand token locally so all derived colors update */
  .vt-btn--danger {
    --vt-color-brand:      var(--vt-color-danger);
    --vt-color-brand-hover: light-dark(
      color-mix(in oklch, var(--vt-color-danger) 85%, black),
      color-mix(in oklch, var(--vt-color-danger) 80%, white)
    );
    --vt-color-brand-active: light-dark(
      color-mix(in oklch, var(--vt-color-danger) 70%, black),
      color-mix(in oklch, var(--vt-color-danger) 65%, white)
    );
    --vt-color-brand-text: white;
  }

  /* Disabled state */
  .vt-btn:disabled,
  .vt-btn[aria-disabled="true"] {
    opacity: 0.45;
    cursor: not-allowed;
    pointer-events: none;
  }

  /* Icon-only button */
  .vt-btn--icon {
    padding: var(--vt-space-2);
    aspect-ratio: 1;
    border-radius: var(--vt-radius-md);
  }

  /*
    Container query — when a button lives in a narrow container
    (e.g. a sidebar or stacked form), it expands to full width automatically.
    No media query needed, no JavaScript.
  */
  @container (max-width: 280px) {
    .vt-btn:not(.vt-btn--icon) {
      width: 100%;
      justify-content: center;
    }
  }
}


/* ==============================================================================
   10. COMPONENT — CARD — src/components/card.css
   ============================================================= */

@layer volty.components {
  .vt-card {
    container-type: inline-size;
    container-name: card;

    background-color: var(--vt-color-surface-overlay);
    border: 1px solid var(--vt-color-border);
    border-radius: var(--vt-radius-xl);
    padding: var(--vt-space-6);
    transition:
      background-color var(--vt-duration-base) ease,
      border-color var(--vt-duration-base) ease;
  }

  .vt-card--raised {
    background-color: var(--vt-color-surface-overlay);
    box-shadow:
      0 1px 3px color-mix(in oklch, var(--vt-color-text) 8%, transparent),
      0 4px 16px color-mix(in oklch, var(--vt-color-text) 6%, transparent);
  }

  .vt-card--interactive {
    cursor: pointer;
  }
  .vt-card--interactive:hover {
    border-color: var(--vt-color-brand);
    box-shadow:
      0 0 0 1px var(--vt-color-brand),
      0 4px 16px color-mix(in oklch, var(--vt-color-brand) 15%, transparent);
  }

  .vt-card__header {
    margin-block-end: var(--vt-space-4);
  }

  .vt-card__title {
    font-size: var(--vt-text-lg);
    font-weight: var(--vt-font-weight-semibold);
    color: var(--vt-color-text);
    line-height: var(--vt-line-height-tight);
  }

  .vt-card__description {
    font-size: var(--vt-text-sm);
    color: var(--vt-color-text-muted);
    margin-block-start: var(--vt-space-1);
    line-height: var(--vt-line-height-relaxed);
  }

  .vt-card__body {
    color: var(--vt-color-text);
  }

  .vt-card__footer {
    margin-block-start: var(--vt-space-4);
    padding-block-start: var(--vt-space-4);
    border-block-start: 1px solid var(--vt-color-border);
    display: flex;
    align-items: center;
    gap: var(--vt-space-2);
    flex-wrap: wrap;
  }

  /* Container-aware layout — card adapts its own internals based on its width */
  @container card (min-width: 420px) {
    .vt-card__footer {
      justify-content: flex-end;
    }
  }
}


/* ==============================================================================
   11. COMPONENT — BADGE — src/components/badge.css
   ============================================================ */

@layer volty.components {
  .vt-badge {
    display: inline-flex;
    align-items: center;
    gap: var(--vt-space-1);
    padding-block: 2px;
    padding-inline: var(--vt-space-2);
    border-radius: var(--vt-radius-full);
    font-size: var(--vt-text-xs);
    font-weight: var(--vt-font-weight-medium);
    line-height: var(--vt-line-height-tight);
    white-space: nowrap;

    /* Default: brand subtle */
    background-color: var(--vt-color-brand-subtle);
    color: var(--vt-color-brand);
    border: 1px solid color-mix(in oklch, var(--vt-color-brand) 25%, transparent);
  }

  .vt-badge--solid {
    background-color: var(--vt-color-brand);
    color: var(--vt-color-brand-text);
    border-color: transparent;
  }

  .vt-badge--surface {
    background-color: var(--vt-color-surface-raised);
    color: var(--vt-color-text-muted);
    border-color: var(--vt-color-border);
  }

  .vt-badge--success {
    background-color: var(--vt-color-success-subtle);
    color: var(--vt-color-success);
    border-color: color-mix(in oklch, var(--vt-color-success) 25%, transparent);
  }

  .vt-badge--warning {
    background-color: var(--vt-color-warning-subtle);
    color: color-mix(in oklch, var(--vt-color-warning) 80%, black);
    border-color: color-mix(in oklch, var(--vt-color-warning) 30%, transparent);
  }

  .vt-badge--danger {
    background-color: var(--vt-color-danger-subtle);
    color: var(--vt-color-danger);
    border-color: color-mix(in oklch, var(--vt-color-danger) 25%, transparent);
  }
}


/* ==============================================================================
   12. COMPONENT — INPUT — src/components/input.css
   ============================================================ */

@layer volty.components {
  .vt-field {
    display: flex;
    flex-direction: column;
    gap: var(--vt-space-1);
    container-type: inline-size;
    container-name: field;
  }

  .vt-label {
    font-size: var(--vt-text-sm);
    font-weight: var(--vt-font-weight-medium);
    color: var(--vt-color-text);
    line-height: var(--vt-line-height-tight);
  }

  .vt-label--required::after {
    content: " *";
    color: var(--vt-color-danger);
  }

  .vt-input {
    display: block;
    width: 100%;
    padding-block: var(--vt-space-2);
    padding-inline: var(--vt-space-3);
    border-radius: var(--vt-radius-md);
    border: 1px solid var(--vt-color-border);
    background-color: var(--vt-color-surface-overlay);
    color: var(--vt-color-text);
    font-family: var(--vt-font-sans);
    font-size: var(--vt-text-sm);
    line-height: var(--vt-line-height-base);
    transition:
      border-color var(--vt-duration-fast) ease,
      box-shadow var(--vt-duration-fast) ease,
      background-color var(--vt-duration-fast) ease;
    outline: none;
    /* Prevent system accent color from bleeding through on autofill */
    -webkit-text-fill-color: var(--vt-color-text);
  }

  /* Override browser autofill background which ignores our colors */
  .vt-input:-webkit-autofill,
  .vt-input:-webkit-autofill:hover,
  .vt-input:-webkit-autofill:focus {
    -webkit-box-shadow: 0 0 0 100px var(--vt-color-surface-overlay) inset;
    -webkit-text-fill-color: var(--vt-color-text);
    caret-color: var(--vt-color-text);
  }

  .vt-input::placeholder {
    color: var(--vt-color-text-muted);
    opacity: 0.7;
  }

  .vt-input:hover:not(:disabled) {
    border-color: color-mix(in oklch, var(--vt-color-border) 50%, var(--vt-color-brand));
  }

  .vt-input:focus {
    border-color: var(--vt-color-brand);
    box-shadow: 0 0 0 3px var(--vt-color-brand-ring);
  }

  .vt-input:disabled {
    opacity: 0.5;
    cursor: not-allowed;
    background-color: var(--vt-color-surface-raised);
    -webkit-text-fill-color: var(--vt-color-text-muted);
  }

  .vt-input--error {
    border-color: var(--vt-color-danger);
  }
  .vt-input--error:focus {
    border-color: var(--vt-color-danger);
    box-shadow: 0 0 0 3px color-mix(in oklch, var(--vt-color-danger) 30%, transparent);
  }

  .vt-hint {
    font-size: var(--vt-text-xs);
    color: var(--vt-color-text-muted);
    line-height: var(--vt-line-height-base);
  }

  .vt-hint--error {
    color: var(--vt-color-danger);
  }

  /*
    Container query — in narrow containers (mobile, sidebar) stack label
    and hint differently. The field knows its own width; no viewport media query.
  */
  @container field (min-width: 400px) {
    .vt-field--inline {
      flex-direction: row;
      align-items: center;
      flex-wrap: wrap;
    }
    .vt-field--inline .vt-label {
      flex: 0 0 auto;
      min-width: 120px;
    }
    .vt-field--inline .vt-input {
      flex: 1;
    }
    .vt-field--inline .vt-hint {
      flex: 0 0 100%;
      padding-inline-start: 120px;
    }
  }
}


/* ==============================================================================
   13. COMPONENT — SWITCH — src/components/switch.css
   =========================================================== */

@layer volty.components {
  .vt-switch {
    --vt-switch-width: 44px;
    --vt-switch-height: 24px;
    --vt-switch-thumb: 18px;
    --vt-switch-gap: calc((var(--vt-switch-height) - var(--vt-switch-thumb)) / 2);

    display: inline-flex;
    align-items: center;
    gap: var(--vt-space-2);
    cursor: pointer;
    user-select: none;
  }

  .vt-switch__track {
    position: relative;
    width: var(--vt-switch-width);
    height: var(--vt-switch-height);
    border-radius: var(--vt-radius-full);
    background-color: var(--vt-color-border);
    transition: background-color var(--vt-duration-base) ease;
    flex-shrink: 0;
  }

  .vt-switch__thumb {
    position: absolute;
    inset-block-start: var(--vt-switch-gap);
    inset-inline-start: var(--vt-switch-gap);
    width: var(--vt-switch-thumb);
    height: var(--vt-switch-thumb);
    border-radius: var(--vt-radius-full);
    background-color: white;
    box-shadow: 0 1px 4px rgba(0,0,0,0.2);
    transition: translate var(--vt-duration-base) cubic-bezier(0.34, 1.56, 0.64, 1);
  }

  /* Checked state via :has() — no JS needed */
  .vt-switch:has(input:checked) .vt-switch__track {
    background-color: var(--vt-color-brand);
  }

  .vt-switch:has(input:checked) .vt-switch__thumb {
    translate: calc(var(--vt-switch-width) - var(--vt-switch-thumb) - var(--vt-switch-gap) * 2) 0;
  }

  .vt-switch input {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0,0,0,0);
    white-space: nowrap;
    border: 0;
  }

  .vt-switch:has(input:focus-visible) .vt-switch__track {
    outline: 2px solid var(--vt-color-brand-ring);
    outline-offset: 2px;
  }

  .vt-switch:has(input:disabled) {
    opacity: 0.5;
    cursor: not-allowed;
  }

  .vt-switch__label {
    font-size: var(--vt-text-sm);
    color: var(--vt-color-text);
    line-height: var(--vt-line-height-tight);
  }
}


/* ==============================================================================
   14. COMPONENT — ALERT — src/components/alert.css
   ============================================================ */

@layer volty.components {
  .vt-alert {
    display: grid;
    grid-template-columns: auto 1fr auto;
    gap: var(--vt-space-3);
    align-items: start;
    padding: var(--vt-space-4);
    border-radius: var(--vt-radius-lg);
    border: 1px solid;
    font-size: var(--vt-text-sm);
    line-height: var(--vt-line-height-relaxed);

    /* Default: info */
    background-color: var(--vt-color-info-subtle);
    border-color: color-mix(in oklch, var(--vt-color-info) 30%, transparent);
    color: var(--vt-color-text);
  }

  /* Icon column */
  .vt-alert__icon {
    display: flex;
    align-items: center;
    color: var(--vt-color-info);
    flex-shrink: 0;
    padding-block-start: 1px;
  }

  /* Content column */
  .vt-alert__body {
    display: flex;
    flex-direction: column;
    gap: var(--vt-space-1);
    min-width: 0;
  }

  .vt-alert__title {
    font-weight: var(--vt-font-weight-semibold);
    color: var(--vt-color-text);
    line-height: var(--vt-line-height-tight);
  }

  .vt-alert__desc {
    color: var(--vt-color-text-muted);
  }

  /* Dismiss button column */
  .vt-alert__dismiss {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 24px;
    height: 24px;
    border-radius: var(--vt-radius-sm);
    border: none;
    background: transparent;
    cursor: pointer;
    color: var(--vt-color-text-muted);
    flex-shrink: 0;
    transition: background-color var(--vt-duration-fast) ease,
                color var(--vt-duration-fast) ease;
    padding: 0;
  }

  .vt-alert__dismiss:hover {
    background-color: color-mix(in oklch, var(--vt-color-text) 10%, transparent);
    color: var(--vt-color-text);
  }

  .vt-alert__dismiss:focus-visible {
    outline: 2px solid var(--vt-color-brand-ring);
    outline-offset: 2px;
  }

  /* When there's no dismiss button, collapse the last column */
  .vt-alert:not(:has(.vt-alert__dismiss)) {
    grid-template-columns: auto 1fr;
  }

  /* When there's no icon, collapse the first column */
  .vt-alert:not(:has(.vt-alert__icon)) {
    grid-template-columns: 1fr auto;
  }

  .vt-alert:not(:has(.vt-alert__icon)):not(:has(.vt-alert__dismiss)) {
    grid-template-columns: 1fr;
  }

  /* Semantic variants */
  .vt-alert--success {
    background-color: var(--vt-color-success-subtle);
    border-color: color-mix(in oklch, var(--vt-color-success) 30%, transparent);
  }
  .vt-alert--success .vt-alert__icon { color: var(--vt-color-success); }

  .vt-alert--warning {
    background-color: var(--vt-color-warning-subtle);
    border-color: color-mix(in oklch, var(--vt-color-warning) 30%, transparent);
  }
  .vt-alert--warning .vt-alert__icon {
    color: color-mix(in oklch, var(--vt-color-warning) 80%, black);
  }

  .vt-alert--danger {
    background-color: var(--vt-color-danger-subtle);
    border-color: color-mix(in oklch, var(--vt-color-danger) 30%, transparent);
  }
  .vt-alert--danger .vt-alert__icon { color: var(--vt-color-danger); }

  /* Solid variant — higher contrast */
  .vt-alert--solid {
    background-color: var(--vt-color-info);
    border-color: transparent;
    color: white;
  }
  .vt-alert--solid .vt-alert__icon { color: white; }
  .vt-alert--solid .vt-alert__title,
  .vt-alert--solid .vt-alert__desc { color: white; }
  .vt-alert--solid .vt-alert__dismiss { color: white; }
  .vt-alert--solid .vt-alert__dismiss:hover {
    background-color: color-mix(in oklch, white 20%, transparent);
  }

  .vt-alert--solid.vt-alert--success { background-color: var(--vt-color-success); }
  .vt-alert--solid.vt-alert--warning { background-color: var(--vt-color-warning); }
  .vt-alert--solid.vt-alert--danger  { background-color: var(--vt-color-danger); }
}


/* ==============================================================================
   15. COMPONENT — TOOLTIP — src/components/tooltip.css
   ========================================================== */

@layer volty.components {
  /*
    Tooltip — CSS anchor positioning.
    Requires: anchor-name on trigger, position-anchor on tooltip.
    Falls back gracefully in non-supporting browsers (tooltip just won't position).

    Usage:
      <span class="vt-tooltip-wrap">
        <button class="vt-btn" style="anchor-name: --my-tip">Hover me</button>
        <span class="vt-tooltip" style="position-anchor: --my-tip" role="tooltip">
          Helpful text
        </span>
      </span>

    Or use data-tooltip for the simple single-line case (no anchor API needed):
      <span class="vt-tooltip-wrap">
        <button class="vt-btn" data-tooltip="Helpful text">Hover me</button>
      </span>
  */

  /* Wrapper establishes position context for the simple (data-tooltip) path */
  .vt-tooltip-wrap {
    position: relative;
    display: inline-flex;
  }

  /* ---- Tooltip element (anchor positioning path) -------------------------- */
  .vt-tooltip {
    /* Positioning */
    position: fixed;
    position-try-fallbacks: --below, --left, --right;
    bottom: calc(anchor(top) - var(--vt-space-2));
    justify-self: anchor-center;

    /* Sizing */
    max-width: 220px;
    padding-block: var(--vt-space-1);
    padding-inline: var(--vt-space-3);

    /* Appearance */
    background-color: light-dark(
      color-mix(in oklch, var(--vt-color-text) 92%, transparent),
      oklch(26% 0 0)
    );
    color: light-dark(var(--vt-color-surface), var(--vt-color-text));
    border-radius: var(--vt-radius-sm);
    font-size: var(--vt-text-xs);
    font-weight: var(--vt-font-weight-medium);
    line-height: var(--vt-line-height-relaxed);
    white-space: normal;
    pointer-events: none;

    /* Visibility — hidden by default, shown on trigger focus/hover */
    opacity: 0;
    visibility: hidden;
    transition:
      opacity var(--vt-duration-fast) ease,
      visibility var(--vt-duration-fast) ease;

    /* Popover reset if used as popover */
    border: none;
    margin: 0;
    padding-block: var(--vt-space-1);
    padding-inline: var(--vt-space-3);
  }

  @position-try --below {
    top: calc(anchor(bottom) + var(--vt-space-2));
    bottom: unset;
    justify-self: anchor-center;
  }

  @position-try --left {
    right: calc(anchor(left) - var(--vt-space-2));
    left: unset;
    align-self: anchor-center;
    bottom: unset;
  }

  @position-try --right {
    left: calc(anchor(right) + var(--vt-space-2));
    align-self: anchor-center;
    bottom: unset;
  }

  /* Show tooltip when sibling trigger is hovered or focused */
  .vt-tooltip-wrap:hover .vt-tooltip,
  .vt-tooltip-wrap:focus-within .vt-tooltip {
    opacity: 1;
    visibility: visible;
  }

  /* ---- Simple data-tooltip path (no anchor API) --------------------------- */
  [data-tooltip] {
    position: relative;
  }

  [data-tooltip]::after {
    content: attr(data-tooltip);
    position: absolute;
    bottom: calc(100% + var(--vt-space-2));
    left: 50%;
    translate: -50% 0;
    white-space: nowrap;
    max-width: 220px;
    padding-block: var(--vt-space-1);
    padding-inline: var(--vt-space-3);
    background-color: light-dark(
      color-mix(in oklch, var(--vt-color-text) 92%, transparent),
      oklch(26% 0 0)
    );
    color: light-dark(var(--vt-color-surface), var(--vt-color-text));
    border-radius: var(--vt-radius-sm);
    font-size: var(--vt-text-xs);
    font-weight: var(--vt-font-weight-medium);
    line-height: var(--vt-line-height-relaxed);
    pointer-events: none;
    z-index: 100;
    opacity: 0;
    visibility: hidden;
    transition:
      opacity var(--vt-duration-fast) ease,
      visibility var(--vt-duration-fast) ease;
  }

  [data-tooltip]:hover::after,
  [data-tooltip]:focus-visible::after {
    opacity: 1;
    visibility: visible;
  }

  /* Placement modifiers for data-tooltip */
  [data-tooltip-placement="bottom"]::after {
    bottom: unset;
    top: calc(100% + var(--vt-space-2));
  }

  [data-tooltip-placement="left"]::after {
    bottom: unset;
    top: 50%;
    left: unset;
    right: calc(100% + var(--vt-space-2));
    translate: 0 -50%;
  }

  [data-tooltip-placement="right"]::after {
    bottom: unset;
    top: 50%;
    left: calc(100% + var(--vt-space-2));
    translate: 0 -50%;
  }
}


/* ==============================================================================
   16. COMPONENT — SELECT — src/components/select.css
   =========================================================== */

@layer volty.components {
  /*
    Select — styled native <select> wrapper.
    The wrapper div provides the custom chevron and container query sizing.

    Usage:
      <div class="vt-select">
        <select>
          <option>Option</option>
        </select>
      </div>

    With label:
      <div class="vt-field">
        <label class="vt-label" for="my-select">Label</label>
        <div class="vt-select">
          <select id="my-select">...</select>
        </div>
      </div>
  */

  .vt-select {
    position: relative;
    display: inline-flex;
    align-items: center;
    container-type: inline-size;
  }

  .vt-select select {
    /* Reset */
    appearance: none;
    -webkit-appearance: none;
    width: 100%;

    /* Sizing */
    padding-block: var(--vt-space-2);
    padding-inline-start: var(--vt-space-3);
    padding-inline-end: var(--vt-space-8); /* room for chevron */
    border-radius: var(--vt-radius-md);

    /* Typography */
    font-family: var(--vt-font-sans);
    font-size: var(--vt-text-sm);
    font-weight: var(--vt-font-weight-normal);
    color: var(--vt-color-text);
    line-height: var(--vt-line-height-tight);

    /* Colors */
    background-color: var(--vt-color-surface-overlay);
    border: 1px solid var(--vt-color-border);

    /* Interaction */
    cursor: pointer;
    transition:
      border-color var(--vt-duration-fast) ease,
      box-shadow var(--vt-duration-fast) ease,
      background-color var(--vt-duration-fast) ease;

    /* Focus ring */
    outline: 2px solid transparent;
    outline-offset: 0;
  }

  .vt-select select:hover:not(:disabled) {
    border-color: color-mix(in oklch, var(--vt-color-brand) 60%, var(--vt-color-border));
  }

  .vt-select select:focus-visible {
    outline-color: var(--vt-color-brand-ring);
    outline-offset: 2px;
    border-color: var(--vt-color-brand);
  }

  /* Chevron icon — drawn with CSS, no SVG needed */
  .vt-select::after {
    content: "";
    position: absolute;
    inset-inline-end: var(--vt-space-3);
    width: 10px;
    height: 6px;
    pointer-events: none;
    background-color: var(--vt-color-text-muted);
    clip-path: polygon(0 0, 100% 0, 50% 100%);
    transition: background-color var(--vt-duration-fast) ease;
  }

  .vt-select:has(select:focus-visible)::after {
    background-color: var(--vt-color-brand);
  }

  /* Disabled */
  .vt-select select:disabled {
    opacity: 0.45;
    cursor: not-allowed;
  }

  .vt-select:has(select:disabled)::after {
    opacity: 0.45;
  }

  /* Error state */
  .vt-select--error select {
    border-color: var(--vt-color-danger);
  }
  .vt-select--error select:focus-visible {
    outline-color: color-mix(in oklch, var(--vt-color-danger) 40%, transparent);
    border-color: var(--vt-color-danger);
  }

  /* Size variants */
  .vt-select--sm select {
    padding-block: calc(var(--vt-space-1) + 1px);
    padding-inline-start: var(--vt-space-2);
    padding-inline-end: var(--vt-space-6);
    font-size: var(--vt-text-xs);
    border-radius: var(--vt-radius-sm);
  }

  .vt-select--lg select {
    padding-block: var(--vt-space-3);
    padding-inline-start: var(--vt-space-4);
    padding-inline-end: var(--vt-space-10);
    font-size: var(--vt-text-base);
    border-radius: var(--vt-radius-lg);
  }

  /* Full width when in a narrow container */
  @container (max-width: 320px) {
    .vt-select {
      width: 100%;
    }
    .vt-select select {
      width: 100%;
    }
  }

  /* ---- Field layout helper -------------------------------------------- */

  .vt-field-hint {
    font-size: var(--vt-text-xs);
    color: var(--vt-color-text-muted);
  }

  .vt-field-error {
    font-size: var(--vt-text-xs);
    color: var(--vt-color-danger);
  }
}


/* ==============================================================================
   17. COMPONENT — MODAL — src/components/modal.css
   ============================================================ */

@layer volty.components {
  /*
    Modal — built on native <dialog>.
    No JS library needed for show/close; use dialog.showModal() / dialog.close().
    @starting-style provides entry animation without JS.

    Usage:
      <dialog class="vt-modal" id="my-modal">
        <div class="vt-modal__header">
          <h2 class="vt-modal__title">Title</h2>
          <button class="vt-modal__close" aria-label="Close" autofocus>
            <svg .../>
          </button>
        </div>
        <div class="vt-modal__body">Content</div>
        <div class="vt-modal__footer">
          <button class="vt-btn vt-btn--surface">Cancel</button>
          <button class="vt-btn">Confirm</button>
        </div>
      </dialog>

    JS: document.getElementById('my-modal').showModal()
    Close on backdrop click:
      modal.addEventListener('click', e => { if (e.target === modal) modal.close() })
  */

  .vt-modal {
    /* Reset dialog defaults */
    padding: 0;
    border: none;
    outline: none;
    background: transparent;

    /* Sizing */
    width: min(calc(100vw - var(--vt-space-8)), 560px);
    max-height: calc(100dvh - var(--vt-space-10));
    margin: auto;

    /* Panel */
    background-color: var(--vt-color-surface-overlay);
    border: 1px solid var(--vt-color-border);
    border-radius: var(--vt-radius-xl);
    box-shadow:
      0 4px 24px color-mix(in oklch, var(--vt-color-text) 12%, transparent),
      0 1px 4px color-mix(in oklch, var(--vt-color-text) 8%, transparent);
    overflow: hidden;

    /* Entry animation */
    transition:
      opacity var(--vt-duration-base) ease,
      translate var(--vt-duration-base) ease,
      display var(--vt-duration-base) ease allow-discrete,
      overlay var(--vt-duration-base) ease allow-discrete;

    @starting-style {
      opacity: 0;
      translate: 0 -12px;
    }
  }

  /* Exit: when closed, dialog hides — transition out */
  .vt-modal:not([open]) {
    opacity: 0;
    translate: 0 -12px;
    pointer-events: none;
  }

  /* Backdrop */
  .vt-modal::backdrop {
    background-color: color-mix(in oklch, var(--vt-color-text) 50%, transparent);
    backdrop-filter: blur(2px);
    transition:
      opacity var(--vt-duration-base) ease,
      display var(--vt-duration-base) ease allow-discrete,
      overlay var(--vt-duration-base) ease allow-discrete;

    @starting-style {
      opacity: 0;
    }
  }

  /* ---- Structure --------------------------------------------------------- */
  .vt-modal__header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--vt-space-4);
    padding: var(--vt-space-6);
    padding-block-end: var(--vt-space-4);
    border-block-end: 1px solid var(--vt-color-border);
  }

  .vt-modal__title {
    font-size: var(--vt-text-lg);
    font-weight: var(--vt-font-weight-semibold);
    color: var(--vt-color-text);
    line-height: var(--vt-line-height-tight);
    margin: 0;
  }

  .vt-modal__close {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 28px;
    height: 28px;
    border-radius: var(--vt-radius-sm);
    border: none;
    background: transparent;
    cursor: pointer;
    color: var(--vt-color-text-muted);
    transition:
      background-color var(--vt-duration-fast) ease,
      color var(--vt-duration-fast) ease;
    padding: 0;
  }

  .vt-modal__close:hover {
    background-color: color-mix(in oklch, var(--vt-color-text) 8%, transparent);
    color: var(--vt-color-text);
  }

  .vt-modal__close:focus-visible {
    outline: 2px solid var(--vt-color-brand-ring);
    outline-offset: 2px;
  }

  .vt-modal__body {
    padding: var(--vt-space-6);
    color: var(--vt-color-text);
    font-size: var(--vt-text-sm);
    line-height: var(--vt-line-height-relaxed);
    overflow-y: auto;
    overscroll-behavior: contain;
  }

  .vt-modal__footer {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: var(--vt-space-3);
    padding: var(--vt-space-4) var(--vt-space-6);
    border-block-start: 1px solid var(--vt-color-border);
    flex-wrap: wrap;
  }

  /* Size variants */
  .vt-modal--sm {
    width: min(calc(100vw - var(--vt-space-8)), 400px);
  }

  .vt-modal--lg {
    width: min(calc(100vw - var(--vt-space-8)), 760px);
  }

  .vt-modal--full {
    width: calc(100vw - var(--vt-space-8));
    max-height: calc(100dvh - var(--vt-space-8));
  }

  /* Danger variant — colors the header accent */
  .vt-modal--danger .vt-modal__title {
    color: var(--vt-color-danger);
  }

  /* Reduce motion */
  @media (prefers-reduced-motion: reduce) {
    .vt-modal,
    .vt-modal::backdrop {
      transition: none;
    }
  }
}


/* ==============================================================================
   18. COMPONENT — TOAST — src/components/toast.css
   ============================================================ */

@layer volty.components {
  /*
    Toast — stacked notification toasts.
    The region is a fixed container; toasts are added/removed via JS (see volty.js).
    Pure CSS entry/exit animation via @starting-style + allow-discrete.

    Usage (HTML structure — managed by Volty.toast()):
      <div class="vt-toast-region" aria-live="polite" aria-atomic="false"></div>

    Programmatic:
      Volty.toast({ message: "Saved!", variant: "success" })
      Volty.toast({ message: "Error", variant: "danger", duration: 0 }) // persistent
  */

  /* ---- Region (fixed viewport container) --------------------------------- */
  .vt-toast-region {
    position: fixed;
    inset-block-end: var(--vt-space-5);
    inset-inline-end: var(--vt-space-5);
    display: flex;
    flex-direction: column-reverse;
    gap: var(--vt-space-2);
    z-index: 9999;
    pointer-events: none;
    max-width: min(360px, calc(100vw - var(--vt-space-6)));
  }

  /* ---- Individual toast -------------------------------------------------- */
  .vt-toast {
    display: grid;
    grid-template-columns: auto 1fr auto;
    align-items: start;
    gap: var(--vt-space-3);
    padding: var(--vt-space-3) var(--vt-space-4);
    border-radius: var(--vt-radius-lg);
    border: 1px solid var(--vt-color-border);
    background-color: var(--vt-color-surface-overlay);
    box-shadow:
      0 2px 12px color-mix(in oklch, var(--vt-color-text) 12%, transparent),
      0 1px 3px color-mix(in oklch, var(--vt-color-text) 8%, transparent);
    font-size: var(--vt-text-sm);
    line-height: var(--vt-line-height-relaxed);
    color: var(--vt-color-text);
    pointer-events: all;
    width: 100%;

    /* Entry/exit animation */
    transition:
      opacity var(--vt-duration-base) ease,
      translate var(--vt-duration-base) ease,
      display var(--vt-duration-base) ease allow-discrete,
      overlay var(--vt-duration-base) ease allow-discrete;

    @starting-style {
      opacity: 0;
      translate: 0 var(--vt-space-4);
    }
  }

  .vt-toast.is-dismissing {
    opacity: 0;
    translate: 0 var(--vt-space-4);
    pointer-events: none;
  }

  /* ---- Toast parts ------------------------------------------------------- */
  .vt-toast__icon {
    display: flex;
    align-items: center;
    padding-block-start: 2px;
    flex-shrink: 0;
    color: var(--vt-color-info);
  }

  .vt-toast__body {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
  }

  .vt-toast__title {
    font-weight: var(--vt-font-weight-semibold);
    color: var(--vt-color-text);
    line-height: var(--vt-line-height-tight);
  }

  .vt-toast__message {
    color: var(--vt-color-text-muted);
  }

  /* When there is only a message (no title) */
  .vt-toast:not(:has(.vt-toast__title)) .vt-toast__message {
    color: var(--vt-color-text);
  }

  .vt-toast__dismiss {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 22px;
    border-radius: var(--vt-radius-sm);
    border: none;
    background: transparent;
    cursor: pointer;
    color: var(--vt-color-text-muted);
    flex-shrink: 0;
    padding: 0;
    transition:
      background-color var(--vt-duration-fast) ease,
      color var(--vt-duration-fast) ease;
  }

  .vt-toast__dismiss:hover {
    background-color: color-mix(in oklch, var(--vt-color-text) 10%, transparent);
    color: var(--vt-color-text);
  }

  .vt-toast__dismiss:focus-visible {
    outline: 2px solid var(--vt-color-brand-ring);
    outline-offset: 2px;
  }

  /* When no dismiss button */
  .vt-toast:not(:has(.vt-toast__dismiss)) {
    grid-template-columns: auto 1fr;
  }

  /* When no icon */
  .vt-toast:not(:has(.vt-toast__icon)) {
    grid-template-columns: 1fr auto;
  }

  .vt-toast:not(:has(.vt-toast__icon)):not(:has(.vt-toast__dismiss)) {
    grid-template-columns: 1fr;
  }

  /* ---- Semantic variants ------------------------------------------------- */
  .vt-toast--success .vt-toast__icon { color: var(--vt-color-success); }
  .vt-toast--success {
    border-color: color-mix(in oklch, var(--vt-color-success) 30%, var(--vt-color-border));
  }

  .vt-toast--warning .vt-toast__icon {
    color: color-mix(in oklch, var(--vt-color-warning) 85%, black);
  }
  .vt-toast--warning {
    border-color: color-mix(in oklch, var(--vt-color-warning) 30%, var(--vt-color-border));
  }

  .vt-toast--danger .vt-toast__icon { color: var(--vt-color-danger); }
  .vt-toast--danger {
    border-color: color-mix(in oklch, var(--vt-color-danger) 30%, var(--vt-color-border));
  }

  /* ---- Progress bar (auto-dismiss countdown) ----------------------------- */
  .vt-toast__progress {
    grid-column: 1 / -1;
    height: 2px;
    border-radius: var(--vt-radius-full);
    background-color: var(--vt-color-border);
    overflow: hidden;
    margin-block-start: var(--vt-space-2);
  }

  .vt-toast__progress-bar {
    height: 100%;
    width: 100%;
    background-color: var(--vt-color-brand);
    transform-origin: left;
    animation: vt-toast-countdown linear forwards;
    animation-duration: var(--vt-toast-duration, 4s);
  }

  .vt-toast--success .vt-toast__progress-bar { background-color: var(--vt-color-success); }
  .vt-toast--warning .vt-toast__progress-bar { background-color: var(--vt-color-warning); }
  .vt-toast--danger  .vt-toast__progress-bar { background-color: var(--vt-color-danger); }

  @keyframes vt-toast-countdown {
    from { scale: 1 1; }
    to   { scale: 0 1; }
  }

  /* Reduce motion */
  @media (prefers-reduced-motion: reduce) {
    .vt-toast,
    .vt-toast__progress-bar {
      transition: none;
      animation: none;
    }
  }
}


/* ==============================================================================
   19. COMPONENT — TABS — src/components/tabs.css
   ============================================================= */

@layer volty.components {
  /*
    Tabs — keyboard accessible, ARIA-managed via Volty.initTabs()

    Usage:
      <div class="vt-tabs" role="tablist">
        <div class="vt-tabs__list" role="tablist" aria-label="My tabs">
          <button class="vt-tabs__trigger" role="tab" aria-selected="true" aria-controls="tab-1">Tab 1</button>
          <button class="vt-tabs__trigger" role="tab" aria-selected="false" aria-controls="tab-2">Tab 2</button>
        </div>
        <div class="vt-tabs__panel" id="tab-1" role="tabpanel">Content 1</div>
        <div class="vt-tabs__panel" id="tab-2" role="tabpanel" hidden>Content 2</div>
      </div>

    JS: Volty.initTabs() — called automatically on DOMContentLoaded
  */

  .vt-tabs {
    display: flex;
    flex-direction: column;
  }

  .vt-tabs__list {
    display: flex;
    gap: var(--vt-space-1);
    border-bottom: 1px solid var(--vt-color-border);
    overflow-x: auto;
    scrollbar-width: none;
  }

  .vt-tabs__list::-webkit-scrollbar {
    display: none;
  }

  .vt-tabs__trigger {
    /* Reset */
    appearance: none;
    border: none;
    background: none;
    cursor: pointer;

    /* Layout */
    display: inline-flex;
    align-items: center;
    gap: var(--vt-space-2);
    padding-block: var(--vt-space-3);
    padding-inline: var(--vt-space-4);
    white-space: nowrap;

    /* Typography */
    font-family: var(--vt-font-sans);
    font-size: var(--vt-text-sm);
    font-weight: var(--vt-font-weight-medium);
    color: var(--vt-color-text-muted);

    /* Active indicator */
    border-bottom: 2px solid transparent;
    margin-bottom: -1px;

    /* Interaction */
    transition:
      color var(--vt-duration-fast) ease,
      border-color var(--vt-duration-fast) ease,
      background-color var(--vt-duration-fast) ease;

    border-radius: var(--vt-radius-sm) var(--vt-radius-sm) 0 0;

    outline: 2px solid transparent;
    outline-offset: -2px;
  }

  .vt-tabs__trigger:hover {
    color: var(--vt-color-text);
    background-color: color-mix(in oklch, var(--vt-color-text) 5%, transparent);
  }

  .vt-tabs__trigger[aria-selected="true"] {
    color: var(--vt-color-brand);
    border-bottom-color: var(--vt-color-brand);
  }

  .vt-tabs__trigger:focus-visible {
    outline-color: var(--vt-color-brand-ring);
    outline-offset: -2px;
  }

  .vt-tabs__trigger:disabled {
    opacity: 0.45;
    cursor: not-allowed;
  }

  .vt-tabs__panel {
    padding-block: var(--vt-space-5);
    color: var(--vt-color-text);
    font-size: var(--vt-text-sm);
    line-height: var(--vt-line-height-relaxed);
  }

  .vt-tabs__panel[hidden] {
    display: none;
  }

  /* Pill variant — tabs look like a segmented control */
  .vt-tabs--pills .vt-tabs__list {
    border-bottom: none;
    background-color: var(--vt-color-surface-raised);
    border-radius: var(--vt-radius-md);
    padding: var(--vt-space-1);
    gap: var(--vt-space-1);
  }

  .vt-tabs--pills .vt-tabs__trigger {
    border-bottom: none;
    border-radius: var(--vt-radius-sm);
    margin-bottom: 0;
  }

  .vt-tabs--pills .vt-tabs__trigger[aria-selected="true"] {
    background-color: var(--vt-color-surface-overlay);
    color: var(--vt-color-text);
    box-shadow: 0 1px 3px color-mix(in oklch, var(--vt-color-text) 10%, transparent);
  }

  .vt-tabs--pills .vt-tabs__panel {
    padding-block-start: var(--vt-space-4);
  }
}


/* ==============================================================================
   20. COMPONENT — ACCORDION — src/components/accordion.css
   ======================================================== */

@layer volty.components {
  /*
    Accordion — built on native <details>/<summary> for zero-JS collapsing.
    @starting-style provides open animation.

    Usage:
      <div class="vt-accordion">
        <details class="vt-accordion__item">
          <summary class="vt-accordion__trigger">Question one?</summary>
          <div class="vt-accordion__body">Answer text goes here.</div>
        </details>
        <details class="vt-accordion__item">
          <summary class="vt-accordion__trigger">Question two?</summary>
          <div class="vt-accordion__body">Another answer.</div>
        </details>
      </div>
  */

  .vt-accordion {
    border: 1px solid var(--vt-color-border);
    border-radius: var(--vt-radius-lg);
    overflow: hidden;
    container-type: inline-size;
  }

  .vt-accordion__item {
    border-bottom: 1px solid var(--vt-color-border);
  }

  .vt-accordion__item:last-child {
    border-bottom: none;
  }

  .vt-accordion__trigger {
    /* Reset <summary> defaults */
    list-style: none;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--vt-space-4);

    /* Layout */
    padding: var(--vt-space-4) var(--vt-space-5);
    width: 100%;
    cursor: pointer;

    /* Typography */
    font-family: var(--vt-font-sans);
    font-size: var(--vt-text-sm);
    font-weight: var(--vt-font-weight-medium);
    color: var(--vt-color-text);

    /* Background */
    background-color: var(--vt-color-surface-raised);
    transition: background-color var(--vt-duration-fast) ease;

    outline: 2px solid transparent;
  }

  /* Remove default marker in all browsers */
  .vt-accordion__trigger::-webkit-details-marker { display: none; }
  .vt-accordion__trigger::marker { display: none; }

  .vt-accordion__trigger:hover {
    background-color: color-mix(in oklch, var(--vt-color-surface-raised) 60%, var(--vt-color-surface-overlay));
  }

  .vt-accordion__trigger:focus-visible {
    outline-color: var(--vt-color-brand-ring);
    outline-offset: -2px;
  }

  /* Chevron icon — CSS-drawn, no SVG dependency */
  .vt-accordion__trigger::after {
    content: '';
    flex-shrink: 0;
    width: 10px;
    height: 10px;
    border-right: 2px solid var(--vt-color-text-muted);
    border-bottom: 2px solid var(--vt-color-text-muted);
    transform: rotate(45deg) translate(-2px, -2px);
    transition: transform var(--vt-duration-base) ease;
  }

  .vt-accordion__item[open] > .vt-accordion__trigger::after {
    transform: rotate(-135deg) translate(-2px, -2px);
  }

  .vt-accordion__body {
    padding: var(--vt-space-4) var(--vt-space-5);
    color: var(--vt-color-text-muted);
    font-size: var(--vt-text-sm);
    line-height: var(--vt-line-height-relaxed);

    /* Entry animation */
    @starting-style {
      opacity: 0;
      padding-block: 0;
    }

    transition:
      opacity var(--vt-duration-base) ease,
      padding-block var(--vt-duration-base) ease;
  }

  @media (prefers-reduced-motion: reduce) {
    .vt-accordion__trigger::after {
      transition: none;
    }
    .vt-accordion__body {
      transition: none;
    }
  }
}


/* ==============================================================================
   21. COMPONENT — DROPDOWN — src/components/dropdown.css
   ========================================================= */

@layer volty.components {
  /*
    Dropdown / Menu — toggleable menu anchored to a trigger button.
    Requires Volty.initDropdowns() (auto-called on DOMContentLoaded).

    Usage:
      <div class="vt-dropdown">
        <button class="vt-btn vt-btn--surface vt-dropdown__trigger" aria-haspopup="true" aria-expanded="false">
          Options
        </button>
        <div class="vt-dropdown__menu" hidden>
          <a href="#" class="vt-dropdown__item">Edit</a>
          <a href="#" class="vt-dropdown__item">Duplicate</a>
          <div class="vt-dropdown__separator"></div>
          <button class="vt-dropdown__item vt-dropdown__item--danger">Delete</button>
        </div>
      </div>
  */

  .vt-dropdown {
    position: relative;
    display: inline-block;
  }

  .vt-dropdown__menu {
    /* Positioning */
    position: absolute;
    top: calc(100% + var(--vt-space-1));
    left: 0;
    z-index: 200;

    /* Sizing */
    min-width: max(160px, 100%);
    max-height: 320px;
    overflow-y: auto;
    overscroll-behavior: contain;

    /* Appearance */
    background-color: var(--vt-color-surface-overlay);
    border: 1px solid var(--vt-color-border);
    border-radius: var(--vt-radius-md);
    box-shadow:
      0 4px 16px color-mix(in oklch, var(--vt-color-text) 8%, transparent),
      0 1px 4px color-mix(in oklch, var(--vt-color-text) 6%, transparent);
    padding: var(--vt-space-1);

    /* Entry animation */
    transition:
      opacity var(--vt-duration-fast) ease,
      translate var(--vt-duration-fast) ease;

    @starting-style {
      opacity: 0;
      translate: 0 -4px;
    }
  }

  /* Align to the right edge of the trigger */
  .vt-dropdown--end .vt-dropdown__menu {
    left: auto;
    right: 0;
  }

  .vt-dropdown__item {
    /* Reset */
    appearance: none;
    border: none;
    background: none;

    /* Layout */
    display: flex;
    align-items: center;
    gap: var(--vt-space-2);
    width: 100%;
    padding: var(--vt-space-2) var(--vt-space-3);
    border-radius: var(--vt-radius-sm);

    /* Typography */
    font-family: var(--vt-font-sans);
    font-size: var(--vt-text-sm);
    color: var(--vt-color-text);
    text-decoration: none;
    text-align: start;
    white-space: nowrap;
    cursor: pointer;

    transition: background-color var(--vt-duration-fast) ease;
    outline: 2px solid transparent;
  }

  .vt-dropdown__item:hover {
    background-color: color-mix(in oklch, var(--vt-color-text) 6%, transparent);
  }

  .vt-dropdown__item:focus-visible {
    outline-color: var(--vt-color-brand-ring);
    outline-offset: -1px;
  }

  .vt-dropdown__item--danger {
    color: var(--vt-color-danger);
  }

  .vt-dropdown__item--danger:hover {
    background-color: var(--vt-color-danger-subtle);
  }

  .vt-dropdown__item:disabled,
  .vt-dropdown__item[aria-disabled="true"] {
    opacity: 0.45;
    cursor: not-allowed;
    pointer-events: none;
  }

  .vt-dropdown__separator {
    height: 1px;
    background-color: var(--vt-color-border);
    margin: var(--vt-space-1) calc(-1 * var(--vt-space-1));
  }

  .vt-dropdown__label {
    display: block;
    padding: var(--vt-space-1) var(--vt-space-3);
    font-size: var(--vt-text-xs);
    font-weight: var(--vt-font-weight-medium);
    color: var(--vt-color-text-muted);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    cursor: default;
  }

  @media (prefers-reduced-motion: reduce) {
    .vt-dropdown__menu {
      transition: none;
    }
  }
}


/* ==============================================================================
   22. COMPONENT — SKELETON — src/components/skeleton.css
   ========================================================= */

@layer volty.components {
  /*
    Skeleton loader — shimmer placeholder for loading states.

    Usage:
      <!-- Text line -->
      <span class="vt-skeleton vt-skeleton--text" style="width: 60%"></span>

      <!-- Avatar circle -->
      <span class="vt-skeleton vt-skeleton--circle" style="width: 40px"></span>

      <!-- Card placeholder -->
      <div class="vt-skeleton vt-skeleton--card"></div>

      <!-- Composed layout -->
      <div class="vt-skeleton-group" style="display:flex;gap:var(--vt-space-3);align-items:center">
        <span class="vt-skeleton vt-skeleton--circle" style="width:40px;flex-shrink:0"></span>
        <div style="flex:1;display:flex;flex-direction:column;gap:var(--vt-space-2)">
          <span class="vt-skeleton vt-skeleton--text" style="width:40%"></span>
          <span class="vt-skeleton vt-skeleton--text" style="width:70%"></span>
        </div>
      </div>
  */

  @keyframes vt-shimmer {
    0%   { background-position: 200% center; }
    100% { background-position: -200% center; }
  }

  .vt-skeleton {
    display: block;
    border-radius: var(--vt-radius-sm);
    background: linear-gradient(
      90deg,
      var(--vt-color-surface-raised) 25%,
      color-mix(in oklch, var(--vt-color-surface-overlay) 80%, var(--vt-color-border)) 50%,
      var(--vt-color-surface-raised) 75%
    );
    background-size: 400% 100%;
    animation: vt-shimmer 1.8s ease-in-out infinite;
  }

  /* Variants */
  .vt-skeleton--text {
    height: 1em;
    border-radius: var(--vt-radius-full);
    display: block;
  }

  .vt-skeleton--circle {
    border-radius: var(--vt-radius-full);
    aspect-ratio: 1 / 1;
  }

  .vt-skeleton--card {
    height: 120px;
    border-radius: var(--vt-radius-lg);
  }

  .vt-skeleton--avatar {
    width: 40px;
    height: 40px;
    border-radius: var(--vt-radius-full);
  }

  .vt-skeleton--button {
    height: 36px;
    width: 100px;
    border-radius: var(--vt-radius-md);
  }

  @media (prefers-reduced-motion: reduce) {
    .vt-skeleton {
      animation: none;
      background: var(--vt-color-surface-raised);
    }
  }
}


/* ==============================================================================
   23. COMPONENT — PROGRESS — src/components/progress.css
   ========================================================= */

@layer volty.components {
  /*
    Progress bar — styled native <progress> element.
    Spinner — CSS-only loading indicator.

    Usage:
      <!-- Determinate -->
      <progress class="vt-progress" value="60" max="100"></progress>

      <!-- With label -->
      <div class="vt-progress-wrap">
        <span class="vt-progress-wrap__label">Uploading…</span>
        <span class="vt-progress-wrap__value">60%</span>
      </div>
      <progress class="vt-progress vt-progress--success" value="60" max="100"></progress>

      <!-- Indeterminate -->
      <progress class="vt-progress vt-progress--indeterminate"></progress>

      <!-- Spinner -->
      <span class="vt-spinner" aria-label="Loading" role="status"></span>
      <span class="vt-spinner vt-spinner--sm"></span>
      <span class="vt-spinner vt-spinner--lg vt-spinner--success"></span>
  */

  /* ---- Progress bar -------------------------------------------------------- */

  .vt-progress {
    /* Reset */
    appearance: none;
    -webkit-appearance: none;
    display: block;
    width: 100%;
    border: none;

    /* Sizing */
    height: var(--vt-space-2);
    border-radius: var(--vt-radius-full);

    /* Track */
    background-color: var(--vt-color-surface-raised);
    overflow: hidden;
  }

  /* Track (WebKit) */
  .vt-progress::-webkit-progress-bar {
    background-color: var(--vt-color-surface-raised);
    border-radius: var(--vt-radius-full);
  }

  /* Fill (WebKit) */
  .vt-progress::-webkit-progress-value {
    background-color: var(--vt-color-brand);
    border-radius: var(--vt-radius-full);
    transition: width var(--vt-duration-base) ease;
  }

  /* Fill (Firefox) */
  .vt-progress::-moz-progress-bar {
    background-color: var(--vt-color-brand);
    border-radius: var(--vt-radius-full);
    transition: width var(--vt-duration-base) ease;
  }

  /* Semantic color variants */
  .vt-progress--success::-webkit-progress-value { background-color: var(--vt-color-success); }
  .vt-progress--warning::-webkit-progress-value { background-color: var(--vt-color-warning); }
  .vt-progress--danger::-webkit-progress-value  { background-color: var(--vt-color-danger); }
  .vt-progress--success::-moz-progress-bar      { background-color: var(--vt-color-success); }
  .vt-progress--warning::-moz-progress-bar      { background-color: var(--vt-color-warning); }
  .vt-progress--danger::-moz-progress-bar       { background-color: var(--vt-color-danger); }

  /* Size variants */
  .vt-progress--sm { height: calc(var(--vt-space-2) / 2); }
  .vt-progress--lg { height: var(--vt-space-3); }

  /* Indeterminate */
  @keyframes vt-progress-slide {
    0%   { transform: translateX(-100%) scaleX(0.5); }
    50%  { transform: translateX(50%)  scaleX(0.6); }
    100% { transform: translateX(300%) scaleX(0.3); }
  }

  .vt-progress--indeterminate::-webkit-progress-value {
    width: 100% !important;
    animation: vt-progress-slide 1.6s cubic-bezier(0.4, 0, 0.6, 1) infinite;
    transform-origin: left center;
  }

  /* Label wrapper */
  .vt-progress-wrap {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    margin-block-end: var(--vt-space-2);
  }

  .vt-progress-wrap__label {
    font-size: var(--vt-text-sm);
    color: var(--vt-color-text);
    font-weight: var(--vt-font-weight-medium);
  }

  .vt-progress-wrap__value {
    font-size: var(--vt-text-xs);
    color: var(--vt-color-text-muted);
    font-family: var(--vt-font-mono);
  }

  /* ---- Spinner ------------------------------------------------------------- */

  @keyframes vt-spin {
    to { transform: rotate(360deg); }
  }

  .vt-spinner {
    display: inline-block;
    flex-shrink: 0;
    width: 1.25rem;
    height: 1.25rem;
    border: 2px solid var(--vt-color-border);
    border-top-color: var(--vt-color-brand);
    border-radius: var(--vt-radius-full);
    animation: vt-spin 0.7s linear infinite;
    vertical-align: middle;
  }

  /* Sizes */
  .vt-spinner--xs { width: 0.75rem;  height: 0.75rem;  border-width: 1.5px; }
  .vt-spinner--sm { width: 1rem;     height: 1rem; }
  .vt-spinner--lg { width: 2rem;     height: 2rem;     border-width: 3px; }
  .vt-spinner--xl { width: 3rem;     height: 3rem;     border-width: 4px; }

  /* Semantic color variants */
  .vt-spinner--success { border-top-color: var(--vt-color-success); }
  .vt-spinner--warning { border-top-color: var(--vt-color-warning); }
  .vt-spinner--danger  { border-top-color: var(--vt-color-danger); }

  @media (prefers-reduced-motion: reduce) {
    .vt-progress::-webkit-progress-value,
    .vt-progress::-moz-progress-bar {
      transition: none;
    }
    .vt-progress--indeterminate::-webkit-progress-value {
      animation: none;
    }
    .vt-spinner {
      animation-duration: 1.5s;
    }
  }
}


/* ==============================================================================
   24. LAYOUT UTILITIES — src/layout/layout.css
   ============================================================= */

@layer volty.utilities {

  /* ── vt-stack ──────────────────────────────────────────────────────────────
     Vertical flex column. Children stack top-to-bottom with a uniform gap.
     Default gap: --vt-space-4.

     Override with a gap modifier or inline style:
       style="--vt-stack-gap: var(--vt-space-6)"
  ─────────────────────────────────────────────────────────────────────────── */

  .vt-stack {
    display: flex;
    flex-direction: column;
    gap: var(--vt-stack-gap, var(--vt-space-4));
  }

  /* Gap modifiers — keyed to the spacing token scale */
  .vt-stack--gap-1 { --vt-stack-gap: var(--vt-space-1); }
  .vt-stack--gap-2 { --vt-stack-gap: var(--vt-space-2); }
  .vt-stack--gap-3 { --vt-stack-gap: var(--vt-space-3); }
  .vt-stack--gap-4 { --vt-stack-gap: var(--vt-space-4); }
  .vt-stack--gap-5 { --vt-stack-gap: var(--vt-space-5); }
  .vt-stack--gap-6 { --vt-stack-gap: var(--vt-space-6); }
  .vt-stack--gap-8 { --vt-stack-gap: var(--vt-space-8); }

  /* Cross-axis alignment */
  .vt-stack--center { align-items: center; }
  .vt-stack--end    { align-items: flex-end; }


  /* ── vt-cluster ────────────────────────────────────────────────────────────
     Horizontal flex row, wrapping. For inline groups: buttons, tags,
     breadcrumbs, form action rows.
     Default gap: --vt-space-3.

     Override gap inline:
       style="--vt-cluster-gap: var(--vt-space-5)"
  ─────────────────────────────────────────────────────────────────────────── */

  .vt-cluster {
    display: flex;
    flex-wrap: wrap;
    gap: var(--vt-cluster-gap, var(--vt-space-3));
    align-items: center;
  }

  /* Gap modifiers */
  .vt-cluster--gap-1 { --vt-cluster-gap: var(--vt-space-1); }
  .vt-cluster--gap-2 { --vt-cluster-gap: var(--vt-space-2); }
  .vt-cluster--gap-3 { --vt-cluster-gap: var(--vt-space-3); }
  .vt-cluster--gap-4 { --vt-cluster-gap: var(--vt-space-4); }
  .vt-cluster--gap-5 { --vt-cluster-gap: var(--vt-space-5); }
  .vt-cluster--gap-6 { --vt-cluster-gap: var(--vt-space-6); }

  /* Main-axis alignment */
  .vt-cluster--center  { justify-content: center; }
  .vt-cluster--end     { justify-content: flex-end; }
  .vt-cluster--between { justify-content: space-between; }


  /* ── vt-grid ───────────────────────────────────────────────────────────────
     Responsive CSS grid with auto-fit columns by default. Columns collapse
     naturally once they'd be narrower than --vt-grid-min (default 16rem) —
     no media queries needed.

     container-type: inline-size lets child components (e.g. vt-card) run
     their own @container queries relative to each grid cell width.

     Use --cols-N modifiers for a fixed column count when you explicitly
     don't want responsive collapsing.

     Override min column width inline:
       style="--vt-grid-min: 12rem"
  ─────────────────────────────────────────────────────────────────────────── */

  .vt-grid {
    container-type: inline-size;
    display: grid;
    gap: var(--vt-grid-gap, var(--vt-space-5));
    /* min(..., 100%) prevents overflow when the container is narrower than
       --vt-grid-min — the RAM (Repeat, Auto, Minmax) overflow fix. */
    grid-template-columns: repeat(
      auto-fit,
      minmax(min(var(--vt-grid-min, 16rem), 100%), 1fr)
    );
  }

  /* Fixed column counts — opt out of auto-fit */
  .vt-grid--cols-2 { grid-template-columns: repeat(2, 1fr); }
  .vt-grid--cols-3 { grid-template-columns: repeat(3, 1fr); }
  .vt-grid--cols-4 { grid-template-columns: repeat(4, 1fr); }

  /* Gap modifiers */
  .vt-grid--gap-1 { --vt-grid-gap: var(--vt-space-1); }
  .vt-grid--gap-2 { --vt-grid-gap: var(--vt-space-2); }
  .vt-grid--gap-3 { --vt-grid-gap: var(--vt-space-3); }
  .vt-grid--gap-4 { --vt-grid-gap: var(--vt-space-4); }
  .vt-grid--gap-5 { --vt-grid-gap: var(--vt-space-5); }
  .vt-grid--gap-6 { --vt-grid-gap: var(--vt-space-6); }
  .vt-grid--gap-8 { --vt-grid-gap: var(--vt-space-8); }


  /* ── vt-container ──────────────────────────────────────────────────────────
     Centered page-width wrapper with horizontal padding. Defaults to 72rem
     (~1152px). Horizontal padding prevents edge-to-edge content on narrow
     viewports without breakpoint math.

     Override width inline:
       style="--vt-container-width: 60rem"
  ─────────────────────────────────────────────────────────────────────────── */

  .vt-container {
    width: 100%;
    max-width: var(--vt-container-width, 72rem);
    margin-inline: auto;
    padding-inline: var(--vt-space-5);
  }

  .vt-container--sm   { --vt-container-width: 40rem; } /*  640px */
  .vt-container--md   { --vt-container-width: 56rem; } /*  896px */
  .vt-container--lg   { --vt-container-width: 80rem; } /* 1280px */
  .vt-container--xl   { --vt-container-width: 96rem; } /* 1536px */
  .vt-container--full { max-width: none; }

}