/* ============================================================================
   Luminous / Midnight — design system
   ----------------------------------------------------------------------------
   Two themes, one set of class names.

     • Luminous Pro  (light, default) — off-white gradient ground, deep ink
       primary, hairline edges, satin buttons, glass navigation, soft
       diffused shadows. "Calm authority."
     • Midnight Pro  (dark, variant)  — obsidian ground with ultra-fine
       glassmorphism, crisp high-contrast text. "Command-center depth."

   The token cascade
   -----------------
   The bare `:root` block is the Luminous Pro default — light is the
   *default* per the design contract. `@media (prefers-color-scheme: dark)`
   flips to Midnight Pro unless the user has explicitly chosen a theme via
   the in-app toggle (`data-theme` on <html>). The `[data-theme="..."]`
   selector always wins, in either direction.

   The Tailwind config in index.html references these same variables, so
   every utility (bg-primary, text-on-surface-variant, etc.) resolves
   through this cascade. No colour is declared inside a media query that
   doesn't also live in :root — that's the rule that prevents one theme's
   text rendering on the other theme's background.

   Material model
   --------------
   - Glass panels: semi-transparent surface + backdrop-blur + 1px border
   - Satin buttons: vertical gradient + top inner highlight
   - Pill shapes: 9999px for buttons, chips, nav items, search
   - Luminous tables: no vertical borders, hairline horizontal dividers,
     rows lift on hover (translateY(-2px) + shadow + solid surface)
   - Status chips: neutral pill + coloured dot
   - Diffused elevation: 0 32px 64px -12px rgba(0,0,0,0.06) for the
     floating data containers

   Non-negotiables honoured by this file
   -------------------------------------
   - Motion: every entrance is gated behind the `.tz-motion` class that
     motion.js adds on load; a 1.2s failsafe force-reveals anything the
     IntersectionObserver missed. No content is hidden by default.
   - Reduced motion: every transition / animation collapses to instant
     under the OS preference *and* the in-app toggle.
   - Contrast: body text and secondary text both clear 4.5:1 in both
     themes. The `verified` tokens are the body / secondary pairs and
     have been numerically checked (see comments next to each).
   ========================================================================== */

:root {
  /* ----- Luminous Pro / light theme (default) ----- */
  /* Body / surface tokens. Stored as raw R G B triplets so Tailwind's
     `<alpha-value>` placeholder still works for `bg-primary/10` etc. */
  --color-bg:                       249 249 250;     /* #f9f9fa */
  --color-bg-end:                   240 241 242;     /* #f0f1f2 - gradient terminus */
  --color-bg-start:                 252 252 253;     /* #FCFCFD - gradient origin */
  --color-surface:                  255 255 255;     /* pure white panel */
  --color-surface-lowest:           255 255 255;
  --color-surface-low:              243 243 244;     /* #f3f3f4 */
  --color-surface-high:             238 238 239;     /* #eeeeef */
  --color-surface-highest:          232 232 233;     /* #e8e8e9 */
  --color-surface-raised:           255 255 255;
  --color-surface-dim:              218 218 219;     /* #dadadb */
  --color-surface-bright:           255 255 255;
  --color-surface-variant:          226 226 227;     /* #e2e2e3 */
  --color-surface-tint:             245 245 247;     /* #f5f5f7 */

  /* Foreground — verified contrast:
     --color-on-surface on --color-bg:        ~16.0:1  ✓
     --color-on-surface-variant on --color-bg: ~5.74:1 ✓ (passes WCAG AA) */
  --color-on-surface:               29 29 31;        /* #1d1d1f */
  --color-on-surface-variant:       110 110 115;     /* #6e6e73 */
  --color-on-surface-ghost:         174 174 178;     /* #aeaeb2 — labels only, not body */
  --color-on-background:            29 29 31;

  /* Brand — deep ink primary, white foreground. */
  --color-primary:                  29 29 31;        /* #1d1d1f */
  --color-on-primary:               255 255 255;
  --color-primary-container:        232 232 233;     /* soft tint */
  --color-on-primary-container:     29 29 31;
  --color-primary-fixed:            245 245 247;
  --color-primary-fixed-dim:        110 110 115;

  /* Secondary / tertiary / inverse (kept so existing markup resolves). */
  --color-secondary:                110 110 115;
  --color-on-secondary:             255 255 255;
  --color-secondary-container:      232 232 233;
  --color-on-secondary-container:   29 29 31;
  --color-tertiary:                 58 58 60;
  --color-on-tertiary:              255 255 255;
  --color-tertiary-container:       226 226 227;
  --color-on-tertiary-container:    29 29 31;
  --color-inverse-surface:          245 245 247;
  --color-inverse-on-surface:       29 29 31;
  --color-inverse-primary:          29 29 31;

  /* Edges / hairlines. */
  --color-outline:                  210 210 215;     /* #d2d2d7 */
  --color-outline-variant:          232 232 237;     /* #e8e8ed */
  --color-border-subtle:            0 0 0;           /* used as rgb(.../0.08) */

  /* Status — semantic only, separate from accent. */
  --color-success:                  52 199 89;       /* #34c759 */
  --color-on-success:               255 255 255;
  --color-success-soft:             52 199 89;       /* for tinted backgrounds */
  --color-error:                    255 59 48;       /* #ff3b30 */
  --color-on-error:                 255 255 255;
  --color-error-soft:               255 59 48;
  --color-warning:                  245 158 11;      /* #f59e0b */
  --color-warning-soft:             245 158 11;
  --color-processing:               59 130 246;      /* #3b82f6 */
  --color-processing-soft:          59 130 246;

  /* Glass surfaces. */
  --color-glass:                    255 255 255;     /* base white */
  --color-glass-opacity:            0.72;
  --color-glass-border:             0 0 0;
  --color-glass-border-opacity:     0.06;

  /* Satin — vertical gradient with top inner highlight.
     The "secondary" / default satin is the soft, recessive treatment:
     white-to-light-grey gradient, dark ink label. */
  --lum-satin-from:                 #ffffff;
  --lum-satin-to:                   #dcdce2;
  --lum-satin-border:               rgba(0, 0, 0, 0.14);
  --lum-satin-shadow:               0 1px 2px rgba(15, 17, 21, 0.10), inset 0 1px 0 rgba(255, 255, 255, 1);
  --lum-satin-shadow-hover:         0 2px 6px rgba(15, 17, 21, 0.08), inset 0 1px 0 rgba(255, 255, 255, 0.95);
  --lum-satin-shadow-pressed:        inset 0 1px 2px rgba(15, 17, 21, 0.08);
  /* Primary satin — Luminous Pro.
     The dominant action surface: ink-to-deep gradient with a hairline inner
     highlight, white label. This is the "satin finish" applied at full
     intensity — same material as the secondary variant, inverted in
     lightness so it reads as the primary action. Verified label contrast
     is ~17:1 (white #ffffff on the mid-gradient stop ~#0c0c0e). */
  /* Brushed light-grey satin with an inner white glow at the top, per
     DESIGN.md's Components section. A near-black slab was shipped here twice
     and rejected twice — primary earns prominence from the border, the
     elevation and the inner highlight, not from going dark. */
  --lum-primary-satin-from:         #fdfdfe;
  --lum-primary-satin-to:           #dedee4;
  --lum-primary-satin-border:       rgba(0, 0, 0, 0.16);
  --lum-primary-satin-label:        #3a3a40;   /* dark grey, not near-black */
  --lum-primary-satin-shadow:       0 1px 2px rgba(0, 0, 0, 0.10), inset 0 1px 0 rgba(255, 255, 255, 0.95);
  --lum-primary-satin-shadow-hover: 0 6px 18px rgba(0, 0, 0, 0.13), inset 0 1px 0 rgba(255, 255, 255, 1);
  --lum-primary-satin-shadow-pressed: inset 0 2px 4px rgba(0, 0, 0, 0.16);
  /* Focus halo — sits on top of any satin button regardless of theme. */
  --lum-focus-ring:                 rgba(255, 255, 255, 0.55);

  /* Elevation — diffused, not hard. */
  --lum-elev-1:                     0 1px 2px rgba(15, 17, 21, 0.04), 0 1px 0 rgba(15, 17, 21, 0.02);
  --lum-elev-2:                     0 4px 12px -2px rgba(15, 17, 21, 0.06), 0 1px 2px rgba(15, 17, 21, 0.04);
  --lum-elev-3:                     0 8px 24px -8px rgba(15, 17, 21, 0.08), 0 1px 0 rgba(15, 17, 21, 0.02);
  --lum-elev-floating:              0 32px 64px -12px rgba(15, 17, 21, 0.10), 0 1px 0 rgba(15, 17, 21, 0.04);
  --lum-elev-hover-lift:            0 12px 24px -8px rgba(15, 17, 21, 0.14), 0 1px 2px rgba(15, 17, 21, 0.06);

  /* Radii. */
  --lum-radius-sm:                  0.5rem;
  --lum-radius:                     1rem;
  --lum-radius-md:                  1.5rem;
  --lum-radius-lg:                  2rem;
  --lum-radius-pill:                9999px;

  /* Motion. */
  --lum-ease:                       cubic-bezier(0.22, 1, 0.36, 1);
  --lum-ease-in-out:                cubic-bezier(0.65, 0, 0.35, 1);
  --lum-dur:                        320ms;
  --lum-dur-fast:                   180ms;
  --lum-dur-slow:                   560ms;

  /* Background composition. */
  --lum-page-bg:                    linear-gradient(180deg, rgb(var(--color-bg-start)) 0%, rgb(var(--color-bg-end)) 100%);
}

/* ============================================================== Dark theme */

/* OS preference — Midnight Pro. The `data-theme` attribute below wins
   over this, in either direction. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --color-bg:                     10 10 11;       /* #0a0a0b */
    --color-bg-end:                 10 10 11;
    --color-bg-start:               18 18 20;       /* slightly lifted origin */
    --color-surface:                24 24 27;       /* #18181b */
    --color-surface-lowest:         0 0 0;          /* #000 */
    --color-surface-low:            18 18 20;       /* #121214 */
    --color-surface-high:           36 36 39;       /* #242427 */
    --color-surface-highest:        44 44 48;       /* #2c2c30 */
    --color-surface-raised:         24 24 27;
    --color-surface-dim:            10 10 11;
    --color-surface-bright:         28 28 30;       /* #1c1c1e */
    --color-surface-variant:        36 36 39;
    --color-surface-tint:           28 28 30;

    /* Foreground — verified:
       --color-on-surface on --color-bg:        ~17.5:1 ✓
       --color-on-surface-variant on --color-bg: ~7.88:1 ✓ */
    --color-on-surface:             245 245 247;    /* #f5f5f7 */
    --color-on-surface-variant:     161 161 166;    /* #a1a1a6 */
    --color-on-surface-ghost:       110 110 115;
    --color-on-background:          245 245 247;

    --color-primary:                245 245 247;    /* invert: text becomes the action */
    --color-on-primary:             10 10 11;
    --color-primary-container:      44 44 48;
    --color-on-primary-container:   245 245 247;
    --color-primary-fixed:          245 245 247;
    --color-primary-fixed-dim:      161 161 166;

    --color-secondary:              161 161 166;
    --color-on-secondary:           10 10 11;
    --color-secondary-container:    36 36 39;
    --color-on-secondary-container: 245 245 247;
    --color-tertiary:               28 28 30;
    --color-on-tertiary:            245 245 247;
    --color-tertiary-container:     36 36 39;
    --color-on-tertiary-container:  245 245 247;
    --color-inverse-surface:        245 245 247;
    --color-inverse-on-surface:     29 29 31;
    --color-inverse-primary:        29 29 31;

    --color-outline:                58 58 60;       /* #3a3a3c */
    --color-outline-variant:        44 44 46;       /* #2c2c2e */
    --color-border-subtle:          255 255 255;

    --color-success:                50 215 75;      /* #32d74b */
    --color-on-success:             0 0 0;
    --color-error:                  255 69 58;      /* #ff453a */
    --color-on-error:               255 255 255;
    --color-warning:                255 214 10;     /* #ffd60a */
    --color-processing:             10 132 255;     /* #0a84ff */

    --color-glass:                  24 24 27;
    --color-glass-opacity:          0.55;
    --color-glass-border:           255 255 255;
    --color-glass-border-opacity:   0.10;

    --lum-satin-from:               #3a3a41;
    --lum-satin-to:                 #1b1b1f;
    --lum-satin-border:             rgba(255, 255, 255, 0.16);
    --lum-satin-shadow:             0 1px 2px rgba(0, 0, 0, 0.5), inset 0 1px 0 rgba(255, 255, 255, 0.18);
    --lum-satin-shadow-hover:       0 2px 10px rgba(0, 0, 0, 0.5), inset 0 1px 0 rgba(255, 255, 255, 0.10);
    --lum-satin-shadow-pressed:     inset 0 1px 2px rgba(0, 0, 0, 0.4);
    /* Primary satin — Midnight Pro.
       Inverse of Luminous Pro: the dominant action surface is a bright
       light-to-cool-grey gradient with a hairline inner highlight, dark
       label. Verified label contrast is ~13:1 (dark #0a0a0b on the mid-
       gradient stop ~#cdcdd2). */
    --lum-primary-satin-from:       #55555e;
    --lum-primary-satin-to:         #2a2a30;
    --lum-primary-satin-border:     rgba(255, 255, 255, 0.22);
    --lum-primary-satin-label:      #f5f5f7;
    --lum-primary-satin-shadow:     0 1px 2px rgba(0, 0, 0, 0.5), inset 0 1px 0 rgba(255, 255, 255, 0.55);
    --lum-primary-satin-shadow-hover: 0 4px 14px rgba(0, 0, 0, 0.6), inset 0 1px 0 rgba(255, 255, 255, 0.70);
    --lum-primary-satin-shadow-pressed: inset 0 1px 2px rgba(0, 0, 0, 0.6);
    --lum-focus-ring:               rgba(0, 0, 0, 0.55);

    --lum-elev-1:                   0 1px 2px rgba(0, 0, 0, 0.4), 0 1px 0 rgba(255, 255, 255, 0.02);
    --lum-elev-2:                   0 4px 16px -2px rgba(0, 0, 0, 0.5), 0 1px 0 rgba(255, 255, 255, 0.02);
    --lum-elev-3:                   0 12px 32px -8px rgba(0, 0, 0, 0.6), 0 1px 0 rgba(255, 255, 255, 0.04);
    --lum-elev-floating:            0 32px 80px -12px rgba(0, 0, 0, 0.7), 0 1px 0 rgba(255, 255, 255, 0.04);
    --lum-elev-hover-lift:          0 16px 32px -8px rgba(0, 0, 0, 0.7), 0 1px 0 rgba(255, 255, 255, 0.04);

    --lum-page-bg:                  linear-gradient(180deg, rgb(18 18 20) 0%, rgb(10 10 11) 100%);
  }
}

/* Explicit theme attribute wins in both directions. */
:root[data-theme="dark"] {
  --color-bg:                     10 10 11;
  --color-bg-end:                 10 10 11;
  --color-bg-start:               18 18 20;
  --color-surface:                24 24 27;
  --color-surface-lowest:         0 0 0;
  --color-surface-low:            18 18 20;
  --color-surface-high:           36 36 39;
  --color-surface-highest:        44 44 48;
  --color-surface-raised:         24 24 27;
  --color-surface-dim:            10 10 11;
  --color-surface-bright:         28 28 30;
  --color-surface-variant:        36 36 39;
  --color-surface-tint:           28 28 30;

  --color-on-surface:             245 245 247;
  --color-on-surface-variant:     161 161 166;
  --color-on-surface-ghost:       110 110 115;
  --color-on-background:          245 245 247;

  --color-primary:                245 245 247;
  --color-on-primary:             10 10 11;
  --color-primary-container:      44 44 48;
  --color-on-primary-container:   245 245 247;
  --color-primary-fixed:          245 245 247;
  --color-primary-fixed-dim:      161 161 166;

  --color-secondary:              161 161 166;
  --color-on-secondary:           10 10 11;
  --color-secondary-container:    36 36 39;
  --color-on-secondary-container: 245 245 247;
  --color-tertiary:               28 28 30;
  --color-on-tertiary:            245 245 247;
  --color-tertiary-container:     36 36 39;
  --color-on-tertiary-container:  245 245 247;
  --color-inverse-surface:        245 245 247;
  --color-inverse-on-surface:     29 29 31;
  --color-inverse-primary:        29 29 31;

  --color-outline:                58 58 60;
  --color-outline-variant:        44 44 46;
  --color-border-subtle:          255 255 255;

  --color-success:                50 215 75;
  --color-on-success:             0 0 0;
  --color-error:                  255 69 58;
  --color-on-error:               255 255 255;
  --color-warning:                255 214 10;
  --color-processing:             10 132 255;

  --color-glass:                  24 24 27;
  --color-glass-opacity:          0.55;
  --color-glass-border:           255 255 255;
  --color-glass-border-opacity:   0.10;

    --lum-satin-from:               #3a3a41;
    --lum-satin-to:                 #1b1b1f;
    --lum-satin-border:             rgba(255, 255, 255, 0.16);
    --lum-satin-shadow:             0 1px 2px rgba(0, 0, 0, 0.5), inset 0 1px 0 rgba(255, 255, 255, 0.18);
    --lum-satin-shadow-hover:       0 2px 10px rgba(0, 0, 0, 0.5), inset 0 1px 0 rgba(255, 255, 255, 0.10);
    --lum-satin-shadow-pressed:     inset 0 1px 2px rgba(0, 0, 0, 0.4);
    --lum-primary-satin-from:       #55555e;
    --lum-primary-satin-to:         #2a2a30;
    --lum-primary-satin-border:     rgba(255, 255, 255, 0.22);
    --lum-primary-satin-label:      #f5f5f7;
    --lum-primary-satin-shadow:     0 1px 2px rgba(0, 0, 0, 0.5), inset 0 1px 0 rgba(255, 255, 255, 0.55);
    --lum-primary-satin-shadow-hover: 0 4px 14px rgba(0, 0, 0, 0.6), inset 0 1px 0 rgba(255, 255, 255, 0.70);
    --lum-primary-satin-shadow-pressed: inset 0 1px 2px rgba(0, 0, 0, 0.6);
    --lum-focus-ring:               rgba(0, 0, 0, 0.55);

  --lum-elev-1:                   0 1px 2px rgba(0, 0, 0, 0.4), 0 1px 0 rgba(255, 255, 255, 0.02);
  --lum-elev-2:                   0 4px 16px -2px rgba(0, 0, 0, 0.5), 0 1px 0 rgba(255, 255, 255, 0.02);
  --lum-elev-3:                   0 12px 32px -8px rgba(0, 0, 0, 0.6), 0 1px 0 rgba(255, 255, 255, 0.04);
  --lum-elev-floating:            0 32px 80px -12px rgba(0, 0, 0, 0.7), 0 1px 0 rgba(255, 255, 255, 0.04);
  --lum-elev-hover-lift:          0 16px 32px -8px rgba(0, 0, 0, 0.7), 0 1px 0 rgba(255, 255, 255, 0.04);

  --lum-page-bg:                  linear-gradient(180deg, rgb(18 18 20) 0%, rgb(10 10 11) 100%);
}

:root[data-theme="light"] {
  /* Luminous Pro explicit override — same as :root, but in case a parent
     theme tried to flip it. */
  --color-bg:                     249 249 250;
  --color-bg-end:                 240 241 242;
  --color-bg-start:               252 252 253;
  --color-on-surface:             29 29 31;
  --color-on-surface-variant:     110 110 115;
  --color-on-surface-ghost:       174 174 178;
  --color-primary:                29 29 31;
  --color-on-primary:             255 255 255;
  --color-outline:                210 210 215;
  --color-outline-variant:        232 232 237;
  --color-border-subtle:          0 0 0;
  --color-glass:                  255 255 255;
  --color-glass-opacity:          0.72;
  --color-glass-border:           0 0 0;
  --color-glass-border-opacity:   0.06;
  --color-success:                52 199 89;
  --color-error:                  255 59 48;
  --color-warning:                245 158 11;
  --color-processing:             59 130 246;
}

/* ================================================================== base */
* { box-sizing: border-box; }
html { background: var(--lum-page-bg); background-attachment: fixed; }
body {
  background: var(--lum-page-bg);
  background-attachment: fixed;
  color: rgb(var(--color-on-surface));
  font-family: 'Public Sans', system-ui, -apple-system, sans-serif;
  font-feature-settings: 'ss01' on, 'cv11' on;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  min-height: 100vh;
  letter-spacing: -0.005em;
}
h1, h2, h3, h4, h5, h6 { font-family: 'Public Sans', system-ui, -apple-system, sans-serif; letter-spacing: -0.015em; }
code, kbd, pre, .font-mono, .tz-mono {
  font-family: 'JetBrains Mono', ui-monospace, Menlo, monospace;
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'liga' 0, 'tnum' 1;
  letter-spacing: 0;
}

a {
  color: rgb(var(--color-primary));
  text-decoration: none;
  transition: color var(--lum-dur-fast) var(--lum-ease), opacity var(--lum-dur-fast) var(--lum-ease);
}
a:hover { opacity: 0.78; }
a:focus-visible { outline: 2px solid rgb(var(--color-primary) / 0.5); outline-offset: 2px; border-radius: 0.25rem; }

/* ============================================================================
   Scrollbar — slim, neutral, never an instrument.
   ========================================================================== */
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
  background: rgb(var(--color-border-subtle) / 0.18);
  border-radius: var(--lum-radius-pill);
  border: 2px solid transparent;
  background-clip: content-box;
}
::-webkit-scrollbar-thumb:hover { background: rgb(var(--color-border-subtle) / 0.32); background-clip: content-box; }
::-webkit-scrollbar-corner { background: transparent; }
.tz-scrollbar { scrollbar-width: thin; scrollbar-color: rgb(var(--color-border-subtle) / 0.25) transparent; }

/* ============================================================================
   Glass — the persistent chrome (sidebar, topbar, drawers) uses real
   backdrop blur. The key constraint: it's expensive, so it's only used
   on the chrome and the largest surfaces, not on every row.
   ========================================================================== */
.tz-glass {
  background: rgb(var(--color-glass) / var(--color-glass-opacity));
  -webkit-backdrop-filter: blur(20px) saturate(180%);
  backdrop-filter: blur(20px) saturate(180%);
  border: 1px solid rgb(var(--color-glass-border) / var(--color-glass-border-opacity));
}
.tz-glass--strong {
  background: rgb(var(--color-glass) / 0.85);
  -webkit-backdrop-filter: blur(28px) saturate(200%);
  backdrop-filter: blur(28px) saturate(200%);
  border: 1px solid rgb(var(--color-glass-border) / calc(var(--color-glass-border-opacity) + 0.04));
}
.tz-glass-sidebar {
  background: rgb(var(--color-glass) / var(--color-glass-opacity));
  -webkit-backdrop-filter: blur(24px) saturate(180%);
  backdrop-filter: blur(24px) saturate(180%);
  border-right: 1px solid rgb(var(--color-glass-border) / var(--color-glass-border-opacity));
}
.tz-glass-topbar {
  background: rgb(var(--color-glass) / calc(var(--color-glass-opacity) - 0.08));
  -webkit-backdrop-filter: blur(24px) saturate(180%);
  backdrop-filter: blur(24px) saturate(180%);
  border-bottom: 1px solid rgb(var(--color-glass-border) / var(--color-glass-border-opacity));
}

/* ============================================================================
   Header — topbar structure.

   The header carries four regions in a single flex row, ordered by visual
   weight left-to-right:

     1. mobile-nav-button + brand — only visible on mobile
     2. page-title — the current route's label, sourced from the route
                     registry. Single source of truth, no duplicate map.
     3. (reserved space) — used by the brand lockup on desktop
     4. control-cluster — project switcher, theme toggle, notifications,
                          settings, avatar. Pushed to the extreme right
                          edge with `margin-left: auto`, respecting the
                          design's 64px desktop / 20px mobile margin.

   The cluster uses the same 38px icon-button height as the sidebar nav
   for visual rhythm. On viewports under 768px the title slot is hidden
   so the brand takes over.
   ========================================================================== */
.tz-topbar {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0 1.25rem;
  /* Compacted to match the tightened content + sidebar. */
  height: 52px;
  /* No max-width, and no auto margins.
     The console canvas below is full-bleed with the same horizontal padding, so
     capping the bar at 1280px and centring it left the control cluster floating
     ~300px short of the content's right edge at 1920px, and pushed the page
     title toward the middle of the screen. The bar and the canvas must share
     one width and one gutter or their edges cannot line up. */
  width: 100%;
}
@media (min-width: 768px) {
  .tz-topbar {
    gap: 1rem;
    /* Must equal the content gutter (spacing.margin-desktop in the Tailwind
       config) so the bar and the canvas below share one edge. Kept in sync:
       both are 36px. */
    padding: 0 36px;
  }
}

/* --------------------------------------------------------------------------
   Console content scale.
   The page content read as oversized (huge readouts, tall cards, a wide gap
   above each page title). `zoom` shrinks the whole content column uniformly —
   type, cards, spacing and padding together — without touching the topbar or
   sidebar chrome, and without the viewport-height quirks that hit `zoom` on an
   h-screen element. Tune this one number to taste. Modals and toasts render
   in body-level roots, so they are unaffected.
   -------------------------------------------------------------------------- */
.tz-console-page {
  zoom: 0.9;
}
.tz-topbar__brand-slot {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  min-width: 0;
}
@media (min-width: 768px) { .tz-topbar__brand-slot { display: none; } }
.tz-topbar__title {
  display: none;
  /* Matches the TezzInc logotype face so the bar reads as one lockup:
     script mark on the left, script page name beside it. */
  font-family: 'Kaushan Script', 'Public Sans', cursive;
  font-size: 19px;
  font-weight: 400;
  letter-spacing: 0.005em;
  color: rgb(var(--color-on-surface));
  margin: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}
@media (min-width: 768px) { .tz-topbar__title { display: inline-flex; align-items: center; } }
.tz-topbar__spacer { flex: 1 1 auto; min-width: 0; }
.tz-topbar__cluster {
  display: flex;
  align-items: center;
  gap: 0.375rem;
  margin-left: auto;
  flex-shrink: 0;
}
@media (min-width: 768px) { .tz-topbar__cluster { gap: 0.5rem; } }
.tz-topbar__divider {
  width: 1px;
  height: 22px;
  background: rgb(var(--color-glass-border) / calc(var(--color-glass-border-opacity) + 0.06));
  margin: 0 0.25rem;
  flex-shrink: 0;
}

/* ---------------------------------------------------------------------------
   Wallet chip
   ---------------------------------------------------------------------------
   A pill rendered in the topbar cluster that shows the current wallet
   balance. Hidden by default (the boot script unhides it once it knows
   there is a session and a balance to show). It is an anchor so that
   click-to-top-up lands on the usage page where the rest of the wallet
   controls live; we deliberately do not open Razorpay straight from
   here, because the user is one click away from the topup form and the
   direct-launch path skipped the amount selector in a previous draft.

   The chip uses the same satin material as the icon buttons so it sits
   flush in the cluster without competing with the avatar. */
.tz-wallet-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  height: 30px;
  padding: 0 0.7rem 0 0.6rem;
  border-radius: var(--lum-radius-pill);
  background: linear-gradient(180deg, var(--lum-satin-from) 0%, var(--lum-satin-to) 100%);
  border: 1px solid var(--lum-satin-border);
  box-shadow: var(--lum-satin-shadow);
  color: rgb(var(--color-on-surface));
  text-decoration: none;
  font-size: 11.5px;
  line-height: 1;
  cursor: pointer;
  transition: background var(--lum-dur-fast) var(--lum-ease), color var(--lum-dur-fast) var(--lum-ease);
  white-space: nowrap;
}
.tz-wallet-chip:hover {
  background: rgb(var(--color-on-surface) / 0.05);
  color: rgb(var(--color-on-surface));
}
.tz-wallet-chip:focus-visible {
  outline: 2px solid rgb(var(--color-primary) / 0.5);
  outline-offset: 1px;
}
.tz-wallet-chip__glyph {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: rgb(var(--color-primary));
  flex-shrink: 0;
}
.tz-wallet-chip__label {
  font-weight: 500;
  color: rgb(var(--color-on-surface-variant));
}
.tz-wallet-chip__value {
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  color: rgb(var(--color-on-surface));
}
.tz-wallet-chip[data-low="1"] .tz-wallet-chip__value {
  color: rgb(var(--color-warning));
}
.tz-wallet-chip[data-empty="1"] {
  opacity: 0.85;
}
.tz-wallet-chip[data-loading="1"] .tz-wallet-chip__value {
  color: rgb(var(--color-on-surface-variant));
  font-weight: 500;
}
@media (max-width: 640px) {
  .tz-wallet-chip__label { display: none; }
}

/* Project switcher (already styled via .tz-project-switcher) — small
   height adjustment to match the icon-button rhythm of the cluster. */
.tz-project-switcher { height: 30px; padding: 0 0.5rem 0 0.8rem; font-size: 12.5px; }

/* ============================================================================
   Logotype — the brand lockup.

   A single component (.tz-logotype) renders both the mark and the wordmark
   on a shared optical baseline. The lockup is size-driven: pass a size via
   the inline custom property --tz-logo-size and the mark and wordmark
   scale together while preserving their relative weight.

   Default size is 22px (sidebar). Mobile header and the public surface use
   the size attribute to render larger or smaller variants.

   The mark is a video frame holding three ascending signal bars — a
   visible frame around the data that's flowing through it, like an
   oscilloscope on an encode pipeline. It reads as video infrastructure,
   not a generic glyph. No gradient text; emphasis comes from weight,
   scale, and the mark itself.
   ========================================================================== */
.tz-logotype {
  display: inline-flex;
  align-items: flex-end; /* frame's bottom edge ↔ wordmark's baseline */
  gap: calc(var(--tz-logo-size, 22px) * 0.36);
  font-family: 'Public Sans', system-ui, sans-serif;
  color: rgb(var(--color-on-surface));
  text-decoration: none;
  user-select: none;
  -webkit-user-select: none;
  line-height: 0;
}
.tz-logotype:hover { opacity: 0.82; }
.tz-logotype:focus-visible {
  outline: 2px solid var(--lum-focus-ring);
  outline-offset: 4px;
  border-radius: 0.25rem;
}
.tz-logotype__mark {
  /* Slight overshoot above the wordmark so the frame's cap-line clears the
     ascender of letters like 't'. The frame's bottom edge is the baseline. */
  width: calc(var(--tz-logo-size, 22px) * 1.20);
  height: calc(var(--tz-logo-size, 22px) * 1.20);
  flex-shrink: 0;
  display: block;
}
.tz-logotype__mark svg { width: 100%; height: 100%; display: block; }
.tz-logotype__word {
  /* Script logotype, matching the owner's supplied "TezzInc" reference: a
     connected brush script rather than the geometric sans used for UI text.
     Kaushan Script is loaded for this element ONLY — nothing else in the
     product uses it, so the personality stays in the mark and never leaks
     into interface copy.

     Script faces sit optically small at a given px size and carry a long
     descender, so the size multiplier is larger than a sans would need and
     the baseline is nudged to keep the lockup aligned with the frame mark. */
  font-family: 'Kaushan Script', 'Public Sans', cursive;
  font-size: calc(var(--tz-logo-size, 22px) * 1.05);
  font-weight: 400;
  letter-spacing: 0.005em;
  line-height: 1;
  padding-right: 0.06em;      /* room for the terminal flourish */
  transform: translateY(0.06em);
  color: rgb(var(--color-on-surface));
}

/* ============================================================================
   Satin — the shared button material.

   Every interactive surface in the console wears the satin finish. The
   finish is one material with three calibrated weights:

     secondary   — the default. Soft white-to-cool-grey gradient, hairline
                   inner highlight, dark-ink label. The recessive action
                   surface; recedes into the page.
     primary     — the dominant action. Deep ink-to-near-black gradient
                   (light theme) or light-to-cool-grey gradient (dark
                   theme), hairline inner highlight, inverted label. The
                   high-contrast action that draws the eye.
     ghost       — no fill. Transparent background, no border, secondary
                   text. Hover lifts a faint surface tint.

   Variants share the same base styles (radius, padding, transition,
   focus ring). The label colour rides --color-on-surface so it stays
   verified against its own background in every state.

   The button system is exposed twice for backwards compatibility —
   the .tz-satin / .tz-satin--* vocabulary and the legacy .tz-btn /
   .tz-btn--* vocabulary — but they resolve to the same cascade.
   ========================================================================== */
.tz-satin,
.tz-btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  border-radius: var(--lum-radius-pill);
  background: linear-gradient(180deg, var(--lum-satin-from) 0%, var(--lum-satin-to) 100%);
  border: 1px solid var(--lum-satin-border);
  box-shadow: var(--lum-satin-shadow);
  color: rgb(var(--color-on-surface));
  font-family: 'Public Sans', system-ui, sans-serif;
  font-weight: 500;
  font-size: 14px;
  line-height: 1;
  letter-spacing: -0.005em;
  padding: 0.625rem 1.125rem;
  cursor: pointer;
  user-select: none;
  text-decoration: none;
  transition:
    transform var(--lum-dur-fast) var(--lum-ease),
    box-shadow var(--lum-dur-fast) var(--lum-ease),
    background var(--lum-dur-fast) var(--lum-ease),
    border-color var(--lum-dur-fast) var(--lum-ease),
    color var(--lum-dur-fast) var(--lum-ease);
  -webkit-user-select: none;
}
.tz-satin:hover,
.tz-btn:hover {
  box-shadow: var(--lum-satin-shadow-hover);
  transform: translateY(-1px);
}
.tz-satin:active,
.tz-btn:active {
  box-shadow: var(--lum-satin-shadow-pressed);
  transform: translateY(0);
}
.tz-satin:focus-visible,
.tz-btn:focus-visible {
  outline: 2px solid var(--lum-focus-ring);
  outline-offset: 2px;
}

/* --- primary: the dominant action surface --------------------------------
   Same satin finish as secondary, inverted in lightness. Applied to both
   .tz-satin--primary and .tz-btn--primary, plus bare button[type="submit"]
   so any unclassed submit button still gets the right finish. */
.tz-satin--primary,
.tz-btn--primary,
button[type="submit"] {
  background: linear-gradient(180deg, var(--lum-primary-satin-from) 0%, var(--lum-primary-satin-to) 100%);
  border-color: var(--lum-primary-satin-border);
  box-shadow: var(--lum-primary-satin-shadow);
  /* The label colour rides --color-on-primary, the inverse of the primary
     ink in the current theme. Verified:
       Luminous: #ffffff on #0f0f11 mid-stop ≈ 17:1
       Midnight: #0a0a0b on #cdcdd2 mid-stop ≈ 13:1 */
  color: var(--lum-primary-satin-label);
  font-weight: 600;
  letter-spacing: -0.01em;
}
.tz-satin--primary:hover,
.tz-btn--primary:hover,
button[type="submit"]:hover {
  box-shadow: var(--lum-primary-satin-shadow-hover);
  transform: translateY(-1px);
}
.tz-satin--primary:active,
.tz-btn--primary:active,
button[type="submit"]:active {
  box-shadow: var(--lum-primary-satin-shadow-pressed);
  transform: translateY(0);
}

/* --- secondary: explicit alias. Same finish as the default .tz-satin but
   declared so markup can be unambiguous. */
.tz-satin--secondary,
.tz-btn--secondary { /* inherits the default .tz-satin / .tz-btn rules */ }

/* --- ghost: no fill, transparent border, secondary text. The faint hover
   tint uses --color-on-surface at 4% so it reads on both themes. */
.tz-satin--ghost,
.tz-btn--ghost {
  background: transparent;
  border-color: transparent;
  box-shadow: none;
  color: rgb(var(--color-on-surface-variant));
  font-weight: 500;
}
.tz-satin--ghost:hover,
.tz-btn--ghost:hover {
  background: rgb(var(--color-on-surface) / 0.05);
  color: rgb(var(--color-on-surface));
  box-shadow: none;
  transform: none;
}
.tz-satin--ghost:focus-visible,
.tz-btn--ghost:focus-visible {
  outline: 2px solid var(--lum-focus-ring);
  outline-offset: 2px;
}

/* --- danger: secondary satin but with the error token for label and
   border so a destructive action reads as such on hover/active without
   leaving the satin vocabulary. */
.tz-satin--danger,
.tz-btn--danger {
  color: rgb(var(--color-error));
  border-color: rgb(var(--color-error) / 0.30);
}
.tz-satin--danger:hover,
.tz-btn--danger:hover {
  background: rgb(var(--color-error) / 0.08);
  border-color: rgb(var(--color-error) / 0.45);
  box-shadow: 0 2px 8px rgb(var(--color-error) / 0.18), inset 0 1px 0 rgb(var(--color-on-surface) / 0.06);
}

/* --- sizes: shared across both vocabularies */
.tz-satin--sm,
.tz-btn--sm { padding: 0.4rem 0.875rem; font-size: 13px; }
.tz-satin--lg,
.tz-btn--lg { padding: 0.85rem 1.5rem; font-size: 15px; }

/* ============================================================================
   Pill-link — a smaller text-link variant for nav and inline references.
   ========================================================================== */
.tz-pill-link {
  display: inline-flex;
  align-items: center;
  padding: 0.5rem 0.875rem;
  border-radius: var(--lum-radius-pill);
  color: rgb(var(--color-on-surface-variant));
  font-weight: 500;
  font-size: 14px;
  transition: background var(--lum-dur-fast) var(--lum-ease), color var(--lum-dur-fast) var(--lum-ease);
}
.tz-pill-link:hover {
  background: rgb(var(--color-on-surface) / 0.04);
  color: rgb(var(--color-on-surface));
  opacity: 1;
}
.tz-pill-link:focus-visible {
  outline: 2px solid rgb(var(--color-primary) / 0.5);
  outline-offset: 2px;
  opacity: 1;
}

/* ============================================================================
   Icon button — circular for the chrome.
   ========================================================================== */
.tz-icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: var(--lum-radius-pill);
  /* Same satin material as every other control. These were transparent, which
     is why the header icons read as flat next to the project switcher. */
  background: linear-gradient(180deg, var(--lum-satin-from) 0%, var(--lum-satin-to) 100%);
  border: 1px solid var(--lum-satin-border);
  box-shadow: var(--lum-satin-shadow);
  color: rgb(var(--color-on-surface-variant));
  cursor: pointer;
  transition: background var(--lum-dur-fast) var(--lum-ease), color var(--lum-dur-fast) var(--lum-ease);
}
.tz-icon-btn:hover {
  background: rgb(var(--color-on-surface) / 0.05);
  color: rgb(var(--color-on-surface));
}
.tz-icon-btn:focus-visible {
  outline: 2px solid rgb(var(--color-primary) / 0.5);
  outline-offset: 1px;
}
.tz-icon-btn .material-symbols-outlined { font-size: 18px; }

.tz-avatar-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: var(--lum-radius-pill);
  background: linear-gradient(180deg, var(--lum-satin-from) 0%, var(--lum-satin-to) 100%);
  border: 1px solid rgb(var(--color-glass-border) / calc(var(--color-glass-border-opacity) + 0.04));
  color: rgb(var(--color-on-surface-variant));
  cursor: pointer;
  box-shadow: var(--lum-elev-1);
  transition: background var(--lum-dur-fast) var(--lum-ease), color var(--lum-dur-fast) var(--lum-ease);
}
.tz-avatar-btn:hover {
  color: rgb(var(--color-on-surface));
}

/* ============================================================================
   Sidebar nav — pill-shaped items, active = filled primary pill.
   ========================================================================== */
.tz-nav-item {
  display: flex;
  align-items: center;
  gap: 0.625rem;
  /* Compact rows so the full nav fits without scrolling on normal laptop
     heights — the list is ~16 links plus group labels. */
  padding: 0.34rem 0.7rem;
  border-radius: var(--lum-radius-pill);
  color: rgb(var(--color-on-surface-variant));
  font-family: 'Public Sans', system-ui, sans-serif;
  font-size: 13px;
  font-weight: 500;
  letter-spacing: -0.005em;
  transition: background var(--lum-dur-fast) var(--lum-ease), color var(--lum-dur-fast) var(--lum-ease);
  text-decoration: none;
}
.tz-nav-item:hover {
  background: rgb(var(--color-on-surface) / 0.04);
  color: rgb(var(--color-on-surface));
  opacity: 1;
}
.sidebar-link { position: relative; }
.sidebar-link.active {
  background: linear-gradient(180deg, var(--lum-primary-satin-from) 0%, var(--lum-primary-satin-to) 100%);
  /* Same label token as the satin buttons. This previously used
     --color-on-primary, which is WHITE in the light theme — a leftover from
     when primary was near-black — so the active item read as white-on-light
     and was effectively invisible. */
  color: var(--lum-primary-satin-label);
  font-weight: 600;
  box-shadow: var(--lum-primary-satin-shadow);
}
.sidebar-link.active:hover { opacity: 1; }

/* ============================================================================
   Status chip — pill + coloured dot. Lives in the topbar (env) and
   inside lists (per-row status).
   ========================================================================== */
.tz-status-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.3rem 0.75rem;
  border-radius: var(--lum-radius-pill);
  background: rgb(var(--color-on-surface) / 0.04);
  color: rgb(var(--color-on-surface-variant));
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.01em;
  border: 1px solid rgb(var(--color-glass-border) / var(--color-glass-border-opacity));
}

/* ============================================================================
   Project switcher — the tenant's project picker in the header. Pill
   shape, gloss top highlight, hairline border; expands a menu of
   projects. Active item is signified by a tinted background, not a check,
   so the active row's full label stays readable.
   ========================================================================== */
.tz-project-switcher {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  height: 30px;
  max-width: 240px;
  padding: 0 0.5rem 0 0.8rem;
  border-radius: var(--lum-radius-pill);
  background: linear-gradient(180deg, var(--lum-satin-from) 0%, var(--lum-satin-to) 100%);
  border: 1px solid var(--lum-satin-border);
  box-shadow: var(--lum-satin-shadow);
  color: rgb(var(--color-on-surface));
  font-family: 'Public Sans', system-ui, sans-serif;
  font-size: 13px;
  font-weight: 500;
  letter-spacing: -0.005em;
  cursor: pointer;
  transition:
    transform var(--lum-dur-fast) var(--lum-ease),
    box-shadow var(--lum-dur-fast) var(--lum-ease),
    background var(--lum-dur-fast) var(--lum-ease);
  -webkit-user-select: none; user-select: none;
}
.tz-project-switcher:hover { box-shadow: var(--lum-satin-shadow-hover); transform: translateY(-1px); }
.tz-project-switcher[aria-expanded="true"] { transform: translateY(0); }
.tz-project-switcher__caret { transition: transform var(--lum-dur-fast) var(--lum-ease); }
.tz-project-switcher[aria-expanded="true"] .tz-project-switcher__caret { transform: rotate(180deg); }

.tz-project-menu {
  position: fixed;
  z-index: 71;
  min-width: 260px;
  max-width: 320px;
  display: flex;
  flex-direction: column;
  padding: 8px;
  background: rgb(var(--color-glass) / calc(var(--color-glass-opacity) + 0.08));
  -webkit-backdrop-filter: blur(20px) saturate(180%);
  backdrop-filter: blur(20px) saturate(180%);
  border: 1px solid rgb(var(--color-glass-border) / var(--color-glass-border-opacity));
  border-radius: 1rem;
  box-shadow: var(--lum-elev-floating);
}
.tz-project-menu__head {
  padding: 8px 10px 6px 10px;
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  border-bottom: 1px solid rgb(var(--color-glass-border) / var(--color-glass-border-opacity));
  margin-bottom: 6px;
}
.tz-project-menu__empty {
  padding: 14px;
  font-family: 'Public Sans', system-ui, sans-serif;
  font-size: 13px;
  line-height: 1.45;
  color: rgb(var(--color-on-surface-variant));
}
.tz-project-menu__item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  border-radius: 0.625rem;
  background: transparent;
  border: 0;
  text-align: left;
  font-family: 'Public Sans', system-ui, sans-serif;
  font-size: 14px;
  font-weight: 500;
  color: rgb(var(--color-on-surface));
  cursor: pointer;
  width: 100%;
  transition: background var(--lum-dur-fast) var(--lum-ease);
}
.tz-project-menu__item:hover { background: rgb(var(--color-on-surface) / 0.05); }
.tz-project-menu__item[aria-current="true"] {
  background: rgb(var(--color-on-surface) / 0.06);
}
.tz-project-menu__slug {
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 11px;
  color: rgb(var(--color-on-surface-variant));
  margin-top: 2px;
}
.tz-project-menu__new {
  margin-top: 4px;
  padding: 8px 10px;
  border-top: 1px solid rgb(var(--color-glass-border) / var(--color-glass-border-opacity));
}

.tz-pulse-dot {
  display: inline-block;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: rgb(var(--color-success));
  box-shadow: 0 0 0 0 rgb(var(--color-success) / 0.4);
  animation: lum-pulse 2.4s var(--lum-ease-in-out) infinite;
}
.tz-pulse-dot[data-state="warn"] { background: rgb(var(--color-warning)); }
.tz-pulse-dot[data-state="alert"] { background: rgb(var(--color-error)); }
.tz-pulse-dot[data-state="processing"] { background: rgb(var(--color-processing)); }
.tz-pulse-dot[data-state="off"] { background: rgb(var(--color-on-surface-ghost)); box-shadow: none; animation: none; }
@keyframes lum-pulse {
  0%, 100% { transform: scale(1); opacity: 1; box-shadow: 0 0 0 0 rgb(var(--color-success) / 0.4); }
  50%      { transform: scale(0.9); opacity: 0.7; box-shadow: 0 0 0 4px rgb(var(--color-success) / 0); }
}

/* ============================================================================
   Cards / panels — glass surface with hairline border, 1rem radius.
   .tz-panel re-uses the same primitives as .tz-card.
   ========================================================================== */
.tz-card,
.tz-panel {
  background: rgb(var(--color-surface));
  border: 1px solid rgb(var(--color-glass-border) / calc(var(--color-glass-border-opacity) + 0.04));
  border-radius: var(--lum-radius);
  box-shadow: var(--lum-elev-2);
  padding: 1.25rem 1.5rem;
  position: relative;
  transition: box-shadow var(--lum-dur) var(--lum-ease);
}
.tz-card--floating { box-shadow: var(--lum-elev-floating); }
.tz-card--glass {
  background: rgb(var(--color-glass) / var(--color-glass-opacity));
  -webkit-backdrop-filter: blur(16px) saturate(180%);
  backdrop-filter: blur(16px) saturate(180%);
  border: 1px solid rgb(var(--color-glass-border) / calc(var(--color-glass-border-opacity) + 0.04));
}
.tz-card--well {
  background: rgb(var(--color-surface-low));
  box-shadow: inset 0 1px 0 rgb(var(--color-glass-border) / calc(var(--color-glass-border-opacity) + 0.02));
}
.tz-card__header {
  display: flex; align-items: center; justify-content: space-between; gap: 0.75rem;
  margin: -0.25rem 0 1rem -0.25rem;
  padding: 0 0.25rem 0.875rem 0.25rem;
  border-bottom: 1px solid rgb(var(--color-glass-border) / var(--color-glass-border-opacity));
}
.tz-card__title {
  font-family: 'Public Sans', system-ui, sans-serif;
  font-weight: 600;
  font-size: 16px;
  letter-spacing: -0.015em;
  color: rgb(var(--color-on-surface));
  margin: 0;
}
.tz-card__kicker {
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-size: 10px;
  font-weight: 500;
  color: rgb(var(--color-on-surface-variant));
}

/* ============================================================================
   Well — recessed input surface. Used for code blocks, log panels,
   and the pill-shaped search bar. The Luminous spec calls for this
   darker recessed look as a contrast against glass panels.
   ========================================================================== */
.tz-well {
  background: rgb(var(--color-surface-low));
  border: 1px solid rgb(var(--color-glass-border) / calc(var(--color-glass-border-opacity) + 0.04));
  border-radius: var(--lum-radius);
  box-shadow: inset 0 1px 0 rgb(var(--color-glass-border) / 0.04);
}

/* ============================================================================
   Forms — pill-shaped inputs, pill-shaped submit.
   ========================================================================== */
input[type="text"],
input[type="email"],
input[type="password"],
input[type="number"],
input[type="search"],
input[type="url"],
input[type="tel"],
textarea,
select {
  background: rgb(var(--color-surface-low));
  border: 1px solid rgb(var(--color-glass-border) / calc(var(--color-glass-border-opacity) + 0.06));
  color: rgb(var(--color-on-surface));
  font-family: 'Public Sans', system-ui, sans-serif;
  font-size: 14px;
  font-weight: 400;
  line-height: 1.5;
  padding: 0.625rem 1rem;
  border-radius: var(--lum-radius-pill);
  caret-color: rgb(var(--color-primary));
  transition: border-color var(--lum-dur-fast) var(--lum-ease), box-shadow var(--lum-dur-fast) var(--lum-ease), background var(--lum-dur-fast) var(--lum-ease);
  width: 100%;
}
textarea { border-radius: 1rem; min-height: 96px; resize: vertical; }
input:focus, textarea:focus, select:focus {
  outline: none;
  border-color: rgb(var(--color-primary) / 0.5);
  box-shadow: 0 0 0 4px rgb(var(--color-primary) / 0.12);
  background: rgb(var(--color-surface));
}
input::placeholder, textarea::placeholder { color: rgb(var(--color-on-surface-ghost)); }

select {
  -webkit-appearance: none;
  appearance: none;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12' fill='none'><path d='M3 4.5L6 7.5L9 4.5' stroke='%236e6e73' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'/></svg>");
  background-repeat: no-repeat;
  background-position: right 0.875rem center;
  padding-right: 2.25rem;
  cursor: pointer;
}

/* ============================================================================
   Disabled — honest rules. Same visual treatment for [disabled] and
   [aria-disabled="true"]. Applies to every button vocabulary: bare
   <button>, .tz-btn (legacy), and .tz-satin. Disabled buttons collapse
   to the surface-low well, regardless of which variant they wore when
   active — a disabled primary should not still draw the eye.
   ========================================================================== */
button:disabled,
button[aria-disabled="true"],
.tz-btn:disabled,
.tz-btn[aria-disabled="true"],
.tz-satin:disabled,
.tz-satin[aria-disabled="true"],
a[aria-disabled="true"].tz-btn,
a[aria-disabled="true"].tz-satin {
  cursor: not-allowed !important;
  pointer-events: auto;
  opacity: 0.55;
  transform: none !important;
  background: rgb(var(--color-surface-low)) !important;
  color: rgb(var(--color-on-surface-variant)) !important;
  border-color: rgb(var(--color-glass-border) / var(--color-glass-border-opacity)) !important;
  box-shadow: none !important;
}
button:disabled:hover,
button[aria-disabled="true"]:hover,
.tz-btn:disabled:hover,
.tz-btn[aria-disabled="true"]:hover,
.tz-satin:disabled:hover,
.tz-satin[aria-disabled="true"]:hover,
a[aria-disabled="true"].tz-btn:hover,
a[aria-disabled="true"].tz-satin:hover {
  background: rgb(var(--color-surface-low)) !important;
  color: rgb(var(--color-on-surface-variant)) !important;
  border-color: rgb(var(--color-glass-border) / var(--color-glass-border-opacity)) !important;
  box-shadow: none !important;
  transform: none !important;
}
button:disabled:focus-visible,
button[aria-disabled="true"]:focus-visible,
.tz-btn:disabled:focus-visible,
.tz-btn[aria-disabled="true"]:focus-visible,
.tz-satin:disabled:focus-visible,
.tz-satin[aria-disabled="true"]:focus-visible {
  outline: 2px solid rgb(var(--color-outline));
  outline-offset: 2px;
}

/* ============================================================================
   Banners — soft alert/warn/lock treatments. Pill-shaped, not bezeled.
   ========================================================================== */
.tz-banner {
  border: 1px solid rgb(var(--color-glass-border) / calc(var(--color-glass-border-opacity) + 0.04));
  background: rgb(var(--color-surface-low));
  padding: 0.875rem 1.125rem;
  border-radius: 1rem;
  font-family: 'Public Sans', system-ui, sans-serif;
  font-size: 14px;
  line-height: 1.5;
  color: rgb(var(--color-on-surface));
  display: flex; gap: 0.75rem; align-items: flex-start;
}
.tz-banner--alert {
  background: rgb(var(--color-error) / 0.08);
  color: rgb(var(--color-on-surface));
  border-color: rgb(var(--color-error) / 0.2);
}
.tz-banner--alert .tz-banner__glyph { color: rgb(var(--color-error)); }
.tz-banner--warn {
  background: rgb(var(--color-warning) / 0.08);
  border-color: rgb(var(--color-warning) / 0.2);
}
.tz-banner--warn .tz-banner__glyph { color: rgb(var(--color-warning)); }
.tz-banner--lock {
  background: rgb(var(--color-success) / 0.08);
  border-color: rgb(var(--color-success) / 0.2);
}
.tz-banner--lock .tz-banner__glyph { color: rgb(var(--color-success)); }
.tz-banner--info {
  background: rgb(var(--color-processing) / 0.08);
  border-color: rgb(var(--color-processing) / 0.2);
}
.tz-banner--info .tz-banner__glyph { color: rgb(var(--color-processing)); }
.tz-banner__glyph { flex-shrink: 0; width: 18px; height: 18px; display: inline-flex; align-items: center; justify-content: center; }

/* ============================================================================
   Status — pill-shaped state badge. The coloured dot is always present;
   the colour follows meaning, never decoration.
   ========================================================================== */
.tz-status {
  display: inline-flex; align-items: center; gap: 0.5rem;
  font-family: 'Public Sans', system-ui, sans-serif;
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.01em;
  padding: 0.25rem 0.625rem 0.25rem 0.5rem;
  border-radius: var(--lum-radius-pill);
  border: 1px solid rgb(var(--color-glass-border) / calc(var(--color-glass-border-opacity) + 0.04));
  background: rgb(var(--color-surface-low));
  color: rgb(var(--color-on-surface));
  white-space: nowrap;
}
.tz-status::before {
  content: ""; width: 6px; height: 6px; border-radius: 50%;
  background: rgb(var(--color-on-surface-variant));
}
.tz-status[data-state="queued"]      { color: rgb(var(--color-on-surface-variant)); }
.tz-status[data-state="queued"]::before { background: rgb(var(--color-on-surface-variant)); }
.tz-status[data-state="processing"]  { color: rgb(var(--color-on-surface)); background: rgb(var(--color-processing) / 0.10); border-color: rgb(var(--color-processing) / 0.25); }
.tz-status[data-state="processing"]::before { background: rgb(var(--color-processing)); animation: lum-pulse-dot 1.8s var(--lum-ease-in-out) infinite; }
.tz-status[data-state="completed"]   { color: rgb(var(--color-on-surface)); background: rgb(var(--color-success) / 0.10); border-color: rgb(var(--color-success) / 0.25); }
.tz-status[data-state="completed"]::before { background: rgb(var(--color-success)); }
.tz-status[data-state="delivered"]   { color: rgb(var(--color-on-surface)); background: rgb(var(--color-success) / 0.10); border-color: rgb(var(--color-success) / 0.25); }
.tz-status[data-state="delivered"]::before { background: rgb(var(--color-success)); }
.tz-status[data-state="succeeded"]   { color: rgb(var(--color-on-surface)); background: rgb(var(--color-success) / 0.10); border-color: rgb(var(--color-success) / 0.25); }
.tz-status[data-state="succeeded"]::before { background: rgb(var(--color-success)); }
.tz-status[data-state="ready"]       { color: rgb(var(--color-on-surface)); background: rgb(var(--color-success) / 0.10); border-color: rgb(var(--color-success) / 0.25); }
.tz-status[data-state="ready"]::before { background: rgb(var(--color-success)); }
.tz-status[data-state="failed"]      { color: rgb(var(--color-on-surface)); background: rgb(var(--color-error) / 0.10); border-color: rgb(var(--color-error) / 0.25); }
.tz-status[data-state="failed"]::before { background: rgb(var(--color-error)); }
.tz-status[data-state="cancelled"]   { color: rgb(var(--color-on-surface-variant)); background: rgb(var(--color-on-surface) / 0.04); }
.tz-status[data-state="cancelled"]::before { background: rgb(var(--color-on-surface-ghost)); }
.tz-status[data-state="warn"],
.tz-status[data-state="degraded"],
.tz-status[data-state="warning"]     { color: rgb(var(--color-on-surface)); background: rgb(var(--color-warning) / 0.10); border-color: rgb(var(--color-warning) / 0.25); }
.tz-status[data-state="warn"]::before,
.tz-status[data-state="degraded"]::before,
.tz-status[data-state="warning"]::before { background: rgb(var(--color-warning)); }
.tz-status[data-state="error"]       { color: rgb(var(--color-on-surface)); background: rgb(var(--color-error) / 0.10); border-color: rgb(var(--color-error) / 0.25); }
.tz-status[data-state="error"]::before { background: rgb(var(--color-error)); }
.tz-status[data-state="pending"]     { color: rgb(var(--color-on-surface)); background: rgb(var(--color-warning) / 0.10); border-color: rgb(var(--color-warning) / 0.25); }
.tz-status[data-state="pending"]::before { background: rgb(var(--color-warning)); }
.tz-status[data-state="active"],
.tz-status[data-state="online"],
.tz-status[data-state="healthy"]     { color: rgb(var(--color-on-surface)); background: rgb(var(--color-success) / 0.10); border-color: rgb(var(--color-success) / 0.25); }
.tz-status[data-state="active"]::before,
.tz-status[data-state="online"]::before,
.tz-status[data-state="healthy"]::before { background: rgb(var(--color-success)); }
.tz-status[data-state="offline"]     { color: rgb(var(--color-on-surface)); background: rgb(var(--color-error) / 0.10); border-color: rgb(var(--color-error) / 0.25); }
.tz-status[data-state="offline"]::before { background: rgb(var(--color-error)); }
@keyframes lum-pulse-dot {
  0%, 100% { transform: scale(1); opacity: 1; }
  50%      { transform: scale(1.3); opacity: 0.5; }
}

.tz-status-inline {
  display: inline-flex; align-items: center; gap: 0.5rem;
  font-family: 'Public Sans', system-ui, sans-serif;
  font-size: 13px;
  font-weight: 500;
  color: rgb(var(--color-on-surface-variant));
}
.tz-status-inline .dot {
  width: 7px; height: 7px; border-radius: 50%;
  background: rgb(var(--color-on-surface-variant));
}
.tz-status-inline[data-state="live"] .dot { background: rgb(var(--color-success)); animation: lum-pulse-dot 1.8s var(--lum-ease-in-out) infinite; }
.tz-status-inline[data-state="warn"] .dot { background: rgb(var(--color-warning)); }
.tz-status-inline[data-state="alert"] .dot { background: rgb(var(--color-error)); }

/* ============================================================================
   Tiles — preset cards, cluster cards. Hover-lift into a card.
   ========================================================================== */
.tz-tile {
  background: rgb(var(--color-surface));
  border: 1px solid rgb(var(--color-glass-border) / calc(var(--color-glass-border-opacity) + 0.04));
  border-radius: 1rem;
  box-shadow: var(--lum-elev-1);
  padding: 1rem 1.125rem;
  display: flex;
  flex-direction: column;
  gap: 0.375rem;
  text-decoration: none;
  color: inherit;
  transition: transform var(--lum-dur-fast) var(--lum-ease), box-shadow var(--lum-dur-fast) var(--lum-ease), border-color var(--lum-dur-fast) var(--lum-ease), background var(--lum-dur-fast) var(--lum-ease);
}
.tz-tile:hover {
  transform: translateY(-2px);
  box-shadow: var(--lum-elev-hover-lift);
  border-color: rgb(var(--color-primary) / 0.18);
  opacity: 1;
}
.tz-tile[aria-disabled="true"],
.tz-tile[aria-disabled="true"]:hover {
  cursor: not-allowed;
  opacity: 0.55;
  transform: none;
  box-shadow: var(--lum-elev-1);
  border-color: rgb(var(--color-glass-border) / var(--color-glass-border-opacity));
}

/* ============================================================================
   Section — rail-headed heading for grouped content.
   ========================================================================== */
.tz-section { display: flex; flex-direction: column; gap: 1rem; }
.tz-section__head {
  display: flex; align-items: baseline; justify-content: space-between; gap: 1rem; flex-wrap: wrap;
}
.tz-section__title {
  font-family: 'Public Sans', system-ui, sans-serif;
  font-weight: 600; font-size: 20px; letter-spacing: -0.015em;
  color: rgb(var(--color-on-surface)); margin: 0;
}
.tz-section__rail {
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 11px; letter-spacing: 0.04em; text-transform: uppercase;
  color: rgb(var(--color-on-surface-variant));
}

/* ============================================================================
   Luminous Tables — no vertical borders, hairline dividers, hover-lift
   rows. The Luminous Pro spec calls this out explicitly: rows lift into
   a card on hover.
   ========================================================================== */
.tz-table-wrap {
  background: rgb(var(--color-surface));
  border: 1px solid rgb(var(--color-glass-border) / calc(var(--color-glass-border-opacity) + 0.04));
  border-radius: 1rem;
  overflow: hidden;
  box-shadow: var(--lum-elev-2);
}
.tz-card table,
.tz-table-wrap table {
  width: 100%; text-align: left; border-collapse: collapse;
  font-feature-settings: "tnum" 1;
}
.tz-card thead,
.tz-table-wrap thead {
  background: rgb(var(--color-surface-low));
  border-bottom: 1px solid rgb(var(--color-glass-border) / var(--color-glass-border-opacity));
}
.tz-card thead th,
.tz-table-wrap thead th {
  font-family: 'Public Sans', system-ui, sans-serif;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-weight: 600;
  color: rgb(var(--color-on-surface-variant));
  padding: 0.875rem 1.25rem;
  text-align: left;
}
.tz-card tbody tr,
.tz-table-wrap tbody tr {
  border-top: 1px solid rgb(var(--color-glass-border) / 0.06);
  transition: background var(--lum-dur-fast) var(--lum-ease), transform var(--lum-dur-fast) var(--lum-ease), box-shadow var(--lum-dur-fast) var(--lum-ease);
  position: relative;
}
.tz-card tbody tr:first-child,
.tz-table-wrap tbody tr:first-child { border-top: 0; }
.tz-card tbody td,
.tz-table-wrap tbody td {
  padding: 0.875rem 1.25rem;
  font-family: 'Public Sans', system-ui, sans-serif;
  font-size: 14px;
  color: rgb(var(--color-on-surface));
  vertical-align: middle;
}
.tz-card tbody tr:hover,
.tz-table-wrap tbody tr:hover {
  background: rgb(var(--color-surface-low));
}

/* The hover-lift table — when set, the row lifts and reads as a card
   instead of just changing colour. */
.tz-table-wrap--lift tbody tr {
  background: transparent;
}
.tz-table-wrap--lift tbody tr:hover {
  background: rgb(var(--color-surface));
  transform: translateY(-2px);
  box-shadow: var(--lum-elev-hover-lift);
  border-radius: 0.75rem;
  position: relative;
  z-index: 1;
}

/* ============================================================================
   Stat strip — engraved-label / large-value / dim-hint cells separated
   by hairlines. Big numbers, no phosphor glow.
   ========================================================================== */
.tz-statstrip {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  background: rgb(var(--color-surface));
  border: 1px solid rgb(var(--color-glass-border) / calc(var(--color-glass-border-opacity) + 0.04));
  border-radius: 1rem;
  box-shadow: var(--lum-elev-2);
  overflow: hidden;
}
.tz-statstrip > * {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.25rem;
  padding: 1.125rem 1.5rem;
  border-left: 1px solid rgb(var(--color-glass-border) / var(--color-glass-border-opacity));
  min-width: 0;
  background: rgb(var(--color-surface));
}
.tz-statstrip > *:first-child { border-left: 0; }
.tz-statstrip__label {
  display: block;
  font-family: 'Public Sans', system-ui, sans-serif;
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: rgb(var(--color-on-surface-variant));
  line-height: 1.2;
}
.tz-statstrip__value {
  display: block;
  font-family: 'Public Sans', system-ui, sans-serif;
  font-size: 28px;
  font-weight: 600;
  letter-spacing: -0.025em;
  color: rgb(var(--color-on-surface));
  font-variant-numeric: tabular-nums;
  line-height: 1.1;
  min-height: 32px;
}
.tz-statstrip__value[data-state="lock"]   { color: rgb(var(--color-success)); }
.tz-statstrip__value[data-state="warn"]   { color: rgb(var(--color-warning)); }
.tz-statstrip__value[data-state="alert"]  { color: rgb(var(--color-error)); }
.tz-statstrip__value[data-state="processing"] { color: rgb(var(--color-processing)); }
.tz-statstrip__hint {
  display: block;
  font-family: 'Public Sans', system-ui, sans-serif;
  font-size: 12px;
  font-weight: 400;
  color: rgb(var(--color-on-surface-variant));
  line-height: 1.3;
}

/* ============================================================================
   Readout — the big tabular number. No phosphor bloom, but the strong
   weight and tight tracking carry the data read.
   ========================================================================== */
.tz-readout {
  font-family: 'Public Sans', system-ui, sans-serif;
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  letter-spacing: -0.03em;
  color: rgb(var(--color-on-surface));
  line-height: 1;
  display: inline-flex;
  align-items: baseline;
}
.tz-readout--xl { font-size: 56px; }
.tz-readout--l  { font-size: 40px; }
.tz-readout--m  { font-size: 28px; }
.tz-readout--s  { font-size: 18px; }
.tz-readout-unit {
  font-family: 'Public Sans', system-ui, sans-serif;
  font-size: 11px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  font-weight: 500;
  color: rgb(var(--color-on-surface-variant));
  margin-left: 0.5rem;
}

/* ============================================================================
   Hero — page hero / landing hero. Soft surface, no scanlines, no
   oscilloscope. The Luminous aesthetic: gradient ground, hairline edge,
   a faint internal glow, and the title typography doing the work.
   ========================================================================== */
.tz-hero {
  position: relative;
  background: rgb(var(--color-surface));
  border: 1px solid rgb(var(--color-glass-border) / calc(var(--color-glass-border-opacity) + 0.04));
  border-radius: 1.5rem;
  box-shadow: var(--lum-elev-3);
  overflow: hidden;
  isolation: isolate;
}
.tz-hero::before {
  content: "";
  position: absolute; inset: 0;
  background:
    radial-gradient(ellipse 80% 60% at 50% 0%, rgb(var(--color-primary) / 0.04), transparent 60%),
    radial-gradient(ellipse 60% 80% at 100% 100%, rgb(var(--color-primary) / 0.02), transparent 70%);
  pointer-events: none;
  z-index: 0;
}
.tz-hero--glass {
  background: rgb(var(--color-glass) / var(--color-glass-opacity));
  -webkit-backdrop-filter: blur(28px) saturate(180%);
  backdrop-filter: blur(28px) saturate(180%);
}
.tz-hero__content {
  position: relative;
  z-index: 2;
}

/* ============================================================================
   Timeline — linear stage indicator. Soft circles connected by hairline,
   the reached state is a filled primary dot. No phosphor.
   ========================================================================== */
.tz-timeline {
  display: flex; align-items: stretch; gap: 0;
  position: relative;
  padding: 0.5rem 0;
}
.tz-timeline__node {
  flex: 1; display: flex; flex-direction: column; align-items: center; gap: 0.5rem;
  position: relative;
}
.tz-timeline__node::after {
  content: ""; position: absolute; top: 11px; left: 50%; right: -50%;
  height: 1px; background: rgb(var(--color-glass-border) / calc(var(--color-glass-border-opacity) + 0.04));
}
.tz-timeline__node:last-child::after { display: none; }
.tz-timeline__node[data-state="reached"]::after { background: rgb(var(--color-primary) / 0.5); }
.tz-timeline__node[data-state="alert"]::after { background: rgb(var(--color-error) / 0.5); }
.tz-timeline__glyph {
  width: 22px; height: 22px;
  border: 1px solid rgb(var(--color-outline));
  background: rgb(var(--color-surface));
  color: rgb(var(--color-on-surface-variant));
  border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 12px;
  z-index: 1;
  transition: all var(--lum-dur-fast) var(--lum-ease);
}
.tz-timeline__node[data-state="reached"] .tz-timeline__glyph {
  background: rgb(var(--color-primary));
  color: rgb(var(--color-on-primary));
  border-color: rgb(var(--color-primary));
}
.tz-timeline__node[data-state="alert"] .tz-timeline__glyph {
  background: rgb(var(--color-error));
  color: rgb(var(--color-on-error));
  border-color: rgb(var(--color-error));
}
.tz-timeline__label {
  font-family: 'Public Sans', system-ui, sans-serif;
  font-size: 11px; font-weight: 500; text-transform: uppercase; letter-spacing: 0.04em;
  color: rgb(var(--color-on-surface-variant));
}
.tz-timeline__node[data-state="reached"] .tz-timeline__label { color: rgb(var(--color-on-surface)); }

/* ============================================================================
   Code block — recessed well + monospace + token classes. The Luminous
   palette's "ink" colour is the foreground; the token colours are
   semantic, not phosphor.
   ========================================================================== */
.tz-codeblock {
  background: rgb(var(--color-surface-low));
  border: 1px solid rgb(var(--color-glass-border) / calc(var(--color-glass-border-opacity) + 0.04));
  border-radius: 1rem;
  box-shadow: inset 0 1px 0 rgb(var(--color-glass-border) / 0.06);
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 13px;
  line-height: 1.6;
  color: rgb(var(--color-on-surface));
  overflow: auto;
}
.tz-codeblock__header {
  display: flex; align-items: center; justify-content: space-between;
  padding: 0.625rem 1.125rem;
  border-bottom: 1px solid rgb(var(--color-glass-border) / var(--color-glass-border-opacity));
  background: rgb(var(--color-surface));
  font-family: 'Public Sans', system-ui, sans-serif;
  font-size: 12px; font-weight: 500;
  letter-spacing: 0.02em; color: rgb(var(--color-on-surface-variant));
  border-top-left-radius: 1rem; border-top-right-radius: 1rem;
}
.tz-codeblock__dots { display: inline-flex; gap: 0.375rem; margin-right: 0.625rem; }
.tz-codeblock__dots span {
  width: 9px; height: 9px; border-radius: 50%;
  background: rgb(var(--color-on-surface-ghost) / 0.5);
  display: inline-block;
}
.tz-codeblock pre {
  padding: 1.125rem 1.375rem;
  margin: 0;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 13px; line-height: 1.6;
  color: rgb(var(--color-on-surface));
}
.tz-codeblock .tok-key { color: rgb(var(--color-processing)); font-weight: 500; }
.tz-codeblock .tok-str { color: rgb(var(--color-success)); }
.tz-codeblock .tok-num { color: rgb(var(--color-warning)); }
.tz-codeblock .tok-com { color: rgb(var(--color-on-surface-ghost)); font-style: italic; }
.tz-codeblock .tok-fn  { color: rgb(var(--color-primary)); }
.tz-codeblock .tok-pun { color: rgb(var(--color-on-surface-variant)); }
.tz-codeblock .tok-hd  { color: rgb(var(--color-on-surface)); font-weight: 600; }

.tz-doc-code {
  background: rgb(var(--color-surface-low));
  border: 1px solid rgb(var(--color-glass-border) / calc(var(--color-glass-border-opacity) + 0.04));
  border-radius: 1rem;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 13px; line-height: 1.6;
  color: rgb(var(--color-on-surface));
  overflow: auto;
  padding: 1.125rem 1.375rem;
  white-space: pre;
  tab-size: 2;
}
.tz-doc-code .tok-com { color: rgb(var(--color-on-surface-ghost)); }
.tz-doc-code .tok-key { color: rgb(var(--color-processing)); }
.tz-doc-code .tok-str { color: rgb(var(--color-success)); }
.tz-doc-code .tok-num { color: rgb(var(--color-warning)); }
.tz-doc-code .tok-fn  { color: rgb(var(--color-primary)); }
.tz-doc-code .tok-pun { color: rgb(var(--color-on-surface-variant)); }
.tz-doc-code .tok-hd  { color: rgb(var(--color-on-surface)); font-weight: 600; }

/* ============================================================================
   Form panel — the auth form's housing. Glass card, pill radius, no
   corner ticks (the Signal bezel pattern is gone).
   ========================================================================== */
.tz-formpanel {
  background: rgb(var(--color-surface));
  border: 1px solid rgb(var(--color-glass-border) / calc(var(--color-glass-border-opacity) + 0.04));
  box-shadow: var(--lum-elev-floating);
  padding: 2rem;
  border-radius: 1.5rem;
  max-width: 460px;
  width: 100%;
  position: relative;
}
.tz-formrow { display: flex; align-items: center; gap: 0.5rem; }
.tz-formrow--end { justify-content: flex-end; }
.tz-formrow--between { justify-content: space-between; }

.tz-pw { position: relative; }
.tz-pw__toggle {
  position: absolute; top: 50%; right: 0.5rem; transform: translateY(-50%);
  font-family: 'Public Sans', system-ui, sans-serif;
  font-size: 11px; letter-spacing: 0.04em; text-transform: uppercase; font-weight: 500;
  color: rgb(var(--color-on-surface-variant));
  background: transparent;
  border: 0; padding: 0.25rem 0.625rem; border-radius: var(--lum-radius-pill);
  cursor: pointer;
  transition: background var(--lum-dur-fast) var(--lum-ease), color var(--lum-dur-fast) var(--lum-ease);
}
.tz-pw__toggle:hover { color: rgb(var(--color-on-surface)); background: rgb(var(--color-on-surface) / 0.04); }

.tz-check { display: inline-flex; align-items: center; gap: 0.5rem; cursor: pointer; }
.tz-check input { width: 16px; height: 16px; padding: 0; accent-color: rgb(var(--color-primary)); }
.tz-check span { font-family: 'Public Sans', system-ui, sans-serif; font-size: 13px; color: rgb(var(--color-on-surface)); }

.tz-field { display: flex; flex-direction: column; gap: 0.375rem; }
.tz-field__hint { font-size: 12px; color: rgb(var(--color-on-surface-variant)); font-family: 'Public Sans', system-ui, sans-serif; }
.tz-field__error { font-size: 12px; color: rgb(var(--color-error)); font-family: 'Public Sans', system-ui, sans-serif; }
.tz-field--error input { border-color: rgb(var(--color-error) / 0.5); }

.tz-label {
  font-family: 'Public Sans', system-ui, sans-serif;
  font-size: 11px; font-weight: 500;
  letter-spacing: 0.04em; text-transform: uppercase;
  color: rgb(var(--color-on-surface-variant));
  display: inline-flex; align-items: center; gap: 0.5rem;
}
.tz-label--inline { display: inline-flex; }
.tz-rule { height: 1px; background: rgb(var(--color-glass-border) / var(--color-glass-border-opacity)); border: 0; margin: 1rem 0; width: 100%; }
.tz-doc-hr { height: 1px; background: rgb(var(--color-glass-border) / var(--color-glass-border-opacity)); border: 0; margin: 2rem 0; }

/* ============================================================================
   Skeleton / spinners / toast / modal — utility primitives.
   ========================================================================== */
.tz-skeleton {
  background: linear-gradient(90deg, rgb(var(--color-surface-low)) 0%, rgb(var(--color-surface-high)) 50%, rgb(var(--color-surface-low)) 100%);
  background-size: 200% 100%;
  animation: lum-shimmer 1.4s ease infinite;
  border-radius: 0.75rem;
  border: 1px solid rgb(var(--color-glass-border) / var(--color-glass-border-opacity));
}
@keyframes lum-shimmer {
  from { background-position: 100% 50%; }
  to   { background-position: 0% 50%; }
}

.tz-spin { animation: lum-spin 0.9s linear infinite; }
@keyframes lum-spin {
  to { transform: rotate(360deg); }
}

.tz-toast-in  { animation: lum-toast-in 380ms var(--lum-ease) forwards; }
.tz-toast-out { animation: lum-toast-out 260ms var(--lum-ease-in-out) forwards; }
@keyframes lum-toast-in {
  from { opacity: 0; transform: translateY(8px) scale(0.98); }
  to   { opacity: 1; transform: none; }
}
@keyframes lum-toast-out {
  to { opacity: 0; transform: translateY(4px) scale(0.98); }
}

#toast-root > * {
  background: rgb(var(--color-surface));
  border: 1px solid rgb(var(--color-glass-border) / calc(var(--color-glass-border-opacity) + 0.04));
  box-shadow: var(--lum-elev-3);
  color: rgb(var(--color-on-surface));
  font-family: 'Public Sans', system-ui, sans-serif;
  font-size: 13px;
  font-weight: 500;
  padding: 0.75rem 1rem 0.75rem 1.125rem;
  border-radius: var(--lum-radius-pill);
  display: flex; align-items: center; gap: 0.625rem;
  min-width: 240px;
  max-width: 360px;
}
#toast-root > *[data-kind="error"]   { border-color: rgb(var(--color-error) / 0.3); }
#toast-root > *[data-kind="error"]::before   { content: ""; width: 8px; height: 8px; border-radius: 50%; background: rgb(var(--color-error)); flex-shrink: 0; }
#toast-root > *[data-kind="success"] { border-color: rgb(var(--color-success) / 0.3); }
#toast-root > *[data-kind="success"]::before { content: ""; width: 8px; height: 8px; border-radius: 50%; background: rgb(var(--color-success)); flex-shrink: 0; }
#toast-root > *[data-kind="warning"] { border-color: rgb(var(--color-warning) / 0.3); }
#toast-root > *[data-kind="warning"]::before { content: ""; width: 8px; height: 8px; border-radius: 50%; background: rgb(var(--color-warning)); flex-shrink: 0; }
#toast-root > *[data-kind="info"] { border-color: rgb(var(--color-processing) / 0.3); }
#toast-root > *[data-kind="info"]::before { content: ""; width: 8px; height: 8px; border-radius: 50%; background: rgb(var(--color-processing)); flex-shrink: 0; }

.tz-modal-backdrop { animation: lum-fade 200ms var(--lum-ease) forwards; }
.tz-modal-card     { animation: lum-modal-in 340ms var(--lum-ease) forwards; }
@keyframes lum-fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes lum-modal-in {
  from { opacity: 0; transform: translateY(8px) scale(0.98); }
  to   { opacity: 1; transform: none; }
}
#modal-root { background: rgb(0 0 0 / 0.4); -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px); }
#modal-root > * {
  background: rgb(var(--color-surface));
  border: 1px solid rgb(var(--color-glass-border) / calc(var(--color-glass-border-opacity) + 0.04));
  box-shadow: var(--lum-elev-floating);
  border-radius: 1.25rem;
}

.tz-page-enter { animation: lum-page-in 420ms var(--lum-ease) forwards; }
@keyframes lum-page-in {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: none; }
}

.tz-drawer { animation: lum-drawer-in 320ms var(--lum-ease) forwards; transform-origin: right; }
.tz-palette { animation: lum-modal-in 240ms var(--lum-ease) forwards; }
@keyframes lum-drawer-in {
  from { opacity: 0; transform: translateX(8px); }
  to   { opacity: 1; transform: none; }
}

.tz-press { transition: transform var(--lum-dur-fast) var(--lum-ease), box-shadow var(--lum-dur-fast) var(--lum-ease), background var(--lum-dur-fast) var(--lum-ease); }
.tz-press:hover { transform: translateY(-1px); }
.tz-press:active { transform: translateY(0); }

/* ============================================================================
   Drop surface — react to a drag.
   ========================================================================== */
.tz-drop { transition: border-color var(--lum-dur-fast) var(--lum-ease), background var(--lum-dur-fast) var(--lum-ease); border-style: dashed !important; }
.tz-drop.tz-drop-active {
  border-color: rgb(var(--color-primary) / 0.5) !important;
  background: rgb(var(--color-primary) / 0.04) !important;
}

/* ============================================================================
   Public surface — landing, login, signup
   ========================================================================== */
/* Selection state — a persistent, non-colour-only indicator for the job
   composer. Cards and buttons carry `tz-choice`; the check mark is only
   visible on the selected option. */
.tz-choice { position: relative; padding-right: 2.25rem !important; }
.tz-choice .tz-select-mark {
  position: absolute;
  top: 50%;
  right: 0.7rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  flex: 0 0 22px;
  margin-left: 0;
  border: 1px solid rgb(var(--color-primary) / 0.26);
  border-radius: var(--lum-radius-pill);
  background: rgb(var(--color-primary) / 0.10);
  color: rgb(var(--color-primary));
  font-size: 14px;
  line-height: 1;
  opacity: 0;
  transform: translateY(-50%) scale(0.72);
  transition: opacity var(--lum-dur-fast) var(--lum-ease), transform var(--lum-dur-fast) var(--lum-ease);
  pointer-events: none;
}
.tz-choice .tz-select-mark[data-selected="1"] { opacity: 1; transform: translateY(-50%) scale(1); }
.tz-choice--selected { border-color: rgb(var(--color-primary) / 0.32); }
.tz-media-preview {
  display: block;
  width: 100%;
  height: auto;
  max-height: 480px;
  object-fit: contain;
  background: rgb(var(--color-surface-low));
}
.tz-media-preview--image {
  max-width: 100%;
  max-height: 480px;
  object-fit: contain;
}

@media (max-width: 767px) {
  .tz-choice .tz-select-mark { width: 20px; height: 20px; flex-basis: 20px; }
}

/* Public chrome controls: the landing header keeps account and theme actions
   together so the signed-in state can swap links for a welcome dropdown
   without changing the page layout. */
.tz-public-actions {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 0.75rem;
  min-width: 0;
  flex-shrink: 0;
}
.tz-public-auth-links {
  display: none;
  align-items: center;
  gap: 0.5rem;
}
.tz-public-account {
  display: flex;
  align-items: center;
  min-width: 0;
}
.tz-public-account[hidden],
.tz-public-auth-links[hidden] { display: none !important; }
.tz-public-actions .tz-icon-btn { flex: 0 0 38px; }
.tz-public-account-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  min-height: 38px;
  max-width: min(260px, 45vw);
  padding: 0.5rem 0.75rem 0.5rem 0.875rem;
  border-radius: var(--lum-radius-pill);
  background: linear-gradient(180deg, var(--lum-satin-from) 0%, var(--lum-satin-to) 100%);
  border: 1px solid var(--lum-satin-border);
  box-shadow: var(--lum-satin-shadow);
  color: rgb(var(--color-on-surface));
  font-family: 'Public Sans', sans-serif;
  font-size: 13px;
  font-weight: 600;
  line-height: 1;
  white-space: nowrap;
  flex: 0 1 auto;
  cursor: pointer;
  transition: transform var(--lum-dur-fast) var(--lum-ease), box-shadow var(--lum-dur-fast) var(--lum-ease), background var(--lum-dur-fast) var(--lum-ease);
}
.tz-public-account-btn:hover {
  transform: translateY(-1px);
  box-shadow: var(--lum-satin-shadow-hover);
}
.tz-public-account-btn:active { transform: translateY(0); }
.tz-public-account-btn:focus-visible { outline: 2px solid var(--lum-focus-ring); outline-offset: 2px; }
.tz-public-account__greeting {
  min-width: 0;
  max-width: 190px;
  overflow: hidden;
  text-overflow: ellipsis;
}
.tz-public-account__caret { transition: transform var(--lum-dur-fast) var(--lum-ease); }
.tz-public-account-btn[aria-expanded="true"] .tz-public-account__caret { transform: rotate(180deg); }
@media (min-width: 768px) {
  .tz-public-auth-links { display: flex; }
}
@media (max-width: 767px) {
  .tz-public-actions { gap: 0.5rem; }
  .tz-public-auth-links { display: flex; }
  .tz-public-auth-links .tz-pill-link { display: none; }
  .tz-public-auth-links .tz-satin { padding-inline: 0.875rem; }
  .tz-public-account-btn { max-width: 52vw; padding-inline: 0.75rem; }
  .tz-public-account__greeting { max-width: 34vw; }
}
@media (max-width: 420px) {
  #public-shell > header > .tz-logotype { --tz-logo-size: 24px !important; }
  .tz-public-account-btn { max-width: 42vw; }
  .tz-public-account__greeting { max-width: 100px; }
  .tz-public-auth-links .tz-satin { font-size: 13px; }
}
@media (max-width: 360px) {
  .tz-public-actions { gap: 0.375rem; }
  .tz-public-account-btn { max-width: 110px; padding-inline: 0.6rem; font-size: 12px; }
  .tz-public-account__greeting { max-width: 70px; }
  .tz-public-auth-links .tz-satin { padding-inline: 0.7rem; }
  .tz-public-auth-links .tz-satin .tz-glyph { display: none; }
}

/* ---------------------------------------------------------------------------
   Public header nav
   ---------------------------------------------------------------------------
   The five primary links (Why, Pricing, Docs, Features, Contact) sit between
   the logotype and the account controls. The Docs link is a button that
   opens a menu rather than a navigation, because the docs surface has
   sub-routes that a flat anchor would force the user to navigate to first.
   The other four are flat anchors.

   On viewports < 1024px the nav collapses into a single "Menu" button. We
   keep the nav inline at md+ because the logotype + nav + actions row is
   the densest layout that still has a single line of text per item. The
   break point is set at 1024px rather than 768px because at 768px the
   links still have headroom; at 1024px they wrap and the row stops being
   one line.
*/
.tz-public-nav {
  display: none;
  align-items: center;
  gap: 0.25rem;
  margin: 0 1rem;
  min-width: 0;
  flex: 1 1 auto;
  justify-content: center;
}
.tz-public-nav__link,
.tz-public-nav__trigger {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  padding: 0.55rem 0.85rem;
  border-radius: var(--lum-radius-pill);
  background: transparent;
  border: 0;
  color: rgb(var(--color-on-surface-variant));
  font-family: 'Public Sans', sans-serif;
  font-size: 14px;
  font-weight: 500;
  line-height: 1;
  text-decoration: none;
  cursor: pointer;
  transition: background var(--lum-dur-fast) var(--lum-ease), color var(--lum-dur-fast) var(--lum-ease);
  white-space: nowrap;
}
.tz-public-nav__link:hover,
.tz-public-nav__trigger:hover,
.tz-public-nav__link:focus-visible,
.tz-public-nav__trigger:focus-visible {
  background: rgb(var(--color-on-surface) / 0.06);
  color: rgb(var(--color-on-surface));
  outline: none;
}
.tz-public-nav__link[aria-current="page"] {
  color: rgb(var(--color-on-surface));
  background: rgb(var(--color-on-surface) / 0.08);
}
.tz-public-nav__caret {
  display: inline-flex;
  align-items: center;
  color: rgb(var(--color-on-surface-variant));
  transition: transform var(--lum-dur-fast) var(--lum-ease);
}
.tz-public-nav__group { position: relative; }
.tz-public-nav__group[data-open="1"] .tz-public-nav__caret { transform: rotate(180deg); }

/* Dropdown menu. The trigger owns the open state via `data-open`; the menu
   itself toggles `hidden`. We position it absolutely below the trigger so
   the trigger is the clickable target on every device. The menu is rendered
   with the same satin material as the rest of the chrome. */
.tz-public-nav__menu {
  position: absolute;
  top: calc(100% + 0.5rem);
  left: 50%;
  transform: translateX(-50%);
  min-width: 320px;
  padding: 0.4rem;
  background: linear-gradient(180deg, var(--lum-satin-from) 0%, var(--lum-satin-to) 100%);
  border: 1px solid var(--lum-satin-border);
  border-radius: 14px;
  box-shadow: var(--lum-satin-shadow-hover);
  z-index: 60;
  display: flex;
  flex-direction: column;
  gap: 1px;
}
.tz-public-nav__menu[hidden] { display: none; }
.tz-public-nav__menu-item {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 0.65rem 0.85rem;
  border-radius: 10px;
  color: rgb(var(--color-on-surface));
  text-decoration: none;
  transition: background var(--lum-dur-fast) var(--lum-ease);
}
.tz-public-nav__menu-item:hover,
.tz-public-nav__menu-item:focus-visible {
  background: rgb(var(--color-on-surface) / 0.06);
  outline: none;
}
.tz-public-nav__menu-title {
  font-family: 'Public Sans', sans-serif;
  font-size: 14px;
  font-weight: 600;
  line-height: 1.3;
}
.tz-public-nav__menu-sub {
  font-family: 'Public Sans', sans-serif;
  font-size: 12px;
  font-weight: 400;
  line-height: 1.4;
  color: rgb(var(--color-on-surface-variant));
}

@media (min-width: 1024px) {
  .tz-public-nav { display: flex; }
  .tz-public-nav-toggle { display: none !important; }
}

/* Mobile menu: a panel that slides down from the header. Implemented as
   a single hidden-by-default div under the header. Toggled by the
   `tz-public-nav-toggle` button. */
.tz-public-mobile {
  display: none;
  padding: 0 1.25rem 1rem;
  flex-direction: column;
  gap: 0.25rem;
  border-bottom: 1px solid rgb(var(--color-outline-variant));
  background: rgb(var(--color-bg));
}
.tz-public-mobile[data-open="1"] { display: flex; }
.tz-public-mobile .tz-public-nav__link { width: 100%; justify-content: flex-start; }
.tz-public-mobile .tz-public-nav__menu { position: static; transform: none; min-width: 0; box-shadow: none; background: rgb(var(--color-surface-low)); }
.tz-public-mobile .tz-public-nav__group { display: flex; flex-direction: column; gap: 0.25rem; }
.tz-public-mobile .tz-public-nav__group > .tz-public-nav__trigger { width: 100%; justify-content: space-between; }
.tz-public-nav-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  border-radius: var(--lum-radius-pill);
  background: linear-gradient(180deg, var(--lum-satin-from) 0%, var(--lum-satin-to) 100%);
  border: 1px solid var(--lum-satin-border);
  box-shadow: var(--lum-satin-shadow);
  color: rgb(var(--color-on-surface-variant));
  cursor: pointer;
}
.tz-public-nav-toggle:hover { background: rgb(var(--color-on-surface) / 0.05); color: rgb(var(--color-on-surface)); }
.tz-public-nav-toggle:focus-visible { outline: 2px solid rgb(var(--color-primary) / 0.5); outline-offset: 1px; }
@media (min-width: 1024px) { .tz-public-nav-toggle { display: none; } }

/* ---------------------------------------------------------------------------
   Public footer
   ---------------------------------------------------------------------------
   Four columns at md+, two on tablet, single column on mobile. We keep the
   link text on a single line so the column widths do not have to flex with
   the longest link per column. The legal bar at the bottom is its own row
   because it carries the copyright and the three links that appear in the
   site-wide privacy/terms flow. */
.tz-public-footer {
  margin-top: 4rem;
  border-top: 1px solid rgb(var(--color-outline-variant));
  background: rgb(var(--color-surface-low));
  color: rgb(var(--color-on-surface-variant));
  font-family: 'Public Sans', sans-serif;
}
.tz-public-footer__inner {
  max-width: var(--tz-container-max, 1280px);
  margin: 0 auto;
  padding: 3rem 1.25rem 2rem;
  display: grid;
  grid-template-columns: 1fr;
  gap: 2rem;
}
@media (min-width: 720px) {
  .tz-public-footer__inner {
    grid-template-columns: 2fr 1fr 1fr 1fr;
    gap: 2.5rem;
  }
}
.tz-public-footer__brand .tz-logotype { color: rgb(var(--color-on-surface)); }
.tz-public-footer__tagline {
  font-size: 13px;
  line-height: 1.5;
  margin: 0.75rem 0 0 0;
  max-width: 28ch;
}
.tz-public-footer__col {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  min-width: 0;
}
.tz-public-footer__col-title {
  font-size: 12px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: rgb(var(--color-on-surface));
  margin-bottom: 0.4rem;
}
.tz-public-footer__col a {
  color: rgb(var(--color-on-surface-variant));
  text-decoration: none;
  font-size: 14px;
  line-height: 1.5;
  transition: color var(--lum-dur-fast) var(--lum-ease);
}
.tz-public-footer__col a:hover { color: rgb(var(--color-on-surface)); }
.tz-public-footer__bar {
  border-top: 1px solid rgb(var(--color-outline-variant));
  padding: 1.25rem;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  align-items: center;
  justify-content: space-between;
  font-size: 13px;
  max-width: var(--tz-container-max, 1280px);
  margin: 0 auto;
}
@media (min-width: 720px) {
  .tz-public-footer__bar { flex-direction: row; padding-inline: 1.25rem; }
}
.tz-public-footer__bar a { color: inherit; text-decoration: none; }
.tz-public-footer__bar a:hover { color: rgb(var(--color-on-surface)); text-decoration: underline; }
.tz-public-footer__legal { display: inline-flex; align-items: center; gap: 0.5rem; }

.tz-screen {
  flex: 1; display: flex; flex-direction: column;
  padding: 3rem 1.25rem 4rem;
  position: relative;
}
.tz-screen__inner { width: 100%; max-width: 1280px; margin: 0 auto; }

/* Chain steps (was the signal chain — kept vocabulary, new look). */
.tz-chain {
  display: grid; grid-template-columns: 1fr; gap: 0;
  border: 1px solid rgb(var(--color-glass-border) / calc(var(--color-glass-border-opacity) + 0.04));
  border-radius: 1.5rem;
  overflow: hidden;
  background: rgb(var(--color-surface));
  box-shadow: var(--lum-elev-2);
}
@media (min-width: 720px) { .tz-chain { grid-template-columns: repeat(4, 1fr); } }
.tz-chain__step {
  padding: 1.75rem 1.5rem;
  border-top: 1px solid rgb(var(--color-glass-border) / var(--color-glass-border-opacity));
  background: rgb(var(--color-surface));
  position: relative;
}
@media (min-width: 720px) {
  .tz-chain__step { border-top: 0; border-left: 1px solid rgb(var(--color-glass-border) / var(--color-glass-border-opacity)); }
  .tz-chain__step:first-child { border-left: 0; }
}
.tz-chain__step__num {
  font-family: 'Public Sans', system-ui, sans-serif;
  font-size: 11px;
  letter-spacing: 0.06em; text-transform: uppercase; font-weight: 500;
  color: rgb(var(--color-on-surface-variant));
  margin-bottom: 0.75rem; display: flex; align-items: center; gap: 0.5rem;
}
.tz-chain__step__num span {
  width: 24px; height: 24px;
  border-radius: var(--lum-radius-pill);
  background: rgb(var(--color-surface-low));
  border: 1px solid rgb(var(--color-outline));
  display: inline-flex; align-items: center; justify-content: center;
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  font-weight: 500;
  color: rgb(var(--color-on-surface));
}
.tz-chain__step__title {
  font-family: 'Public Sans', system-ui, sans-serif;
  font-weight: 600; font-size: 16px; letter-spacing: -0.015em;
  color: rgb(var(--color-on-surface)); margin: 0 0 0.375rem 0;
}
.tz-chain__step__body  {
  font-family: 'Public Sans', system-ui, sans-serif;
  font-size: 14px; line-height: 1.5; color: rgb(var(--color-on-surface-variant));
  margin: 0;
}
.tz-chain__step__meta  {
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px; color: rgb(var(--color-on-surface-ghost));
  margin-top: 0.875rem;
  padding-top: 0.875rem;
  border-top: 1px solid rgb(var(--color-glass-border) / var(--color-glass-border-opacity));
}

/* ============================================================================
   Wordmark — Public Sans semibold, slight tracking in. No glow, no mono.
   ========================================================================== */
.tz-wordmark, .tz-mark {
  font-family: 'Public Sans', system-ui, sans-serif;
  font-weight: 600;
  letter-spacing: -0.025em;
  color: rgb(var(--color-on-surface));
}

/* ============================================================================
   Avatar default glyph.
   ========================================================================== */
.tz-glyph { display: inline-block; vertical-align: middle; line-height: 0; }

/* ============================================================================
   Drawer row — used in the activity panel.
   ========================================================================== */
.tz-drawer-row {
  display: flex; align-items: flex-start; gap: 0.75rem;
  padding: 0.75rem 0.875rem;
  background: rgb(var(--color-surface));
  border: 1px solid rgb(var(--color-glass-border) / var(--color-glass-border-opacity));
  border-radius: 0.875rem;
}
.tz-drawer-row + .tz-drawer-row { margin-top: 0.5rem; }

/* ============================================================================
   Tooltip / kbd
   ========================================================================== */
kbd, .tz-kbd {
  display: inline-block;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 11px; font-weight: 500;
  padding: 0.125rem 0.5rem;
  border: 1px solid rgb(var(--color-outline));
  background: rgb(var(--color-surface-low));
  color: rgb(var(--color-on-surface-variant));
  border-radius: 0.375rem;
  letter-spacing: 0.04em;
}

/* ============================================================================
   Settings drawer — theme chips, avatar menu items, palette items.
   ========================================================================== */
.tz-theme-chip {
  display: inline-flex; align-items: center; gap: 0.375rem;
  padding: 0.375rem 0.75rem;
  font-family: 'Public Sans', system-ui, sans-serif;
  font-size: 13px;
  font-weight: 500;
  border-radius: var(--lum-radius-pill);
  border: 0;
  background: transparent;
  color: rgb(var(--color-on-surface-variant));
  cursor: pointer;
  transition: background var(--lum-dur-fast) var(--lum-ease), color var(--lum-dur-fast) var(--lum-ease);
}
.tz-theme-chip:hover { color: rgb(var(--color-on-surface)); }
.tz-theme-chip[data-active="1"] {
  background: rgb(var(--color-surface));
  color: rgb(var(--color-on-surface));
  box-shadow: var(--lum-elev-1);
}
.tz-theme-chip .material-symbols-outlined { font-size: 16px; }

.tz-avatar-item {
  display: flex; align-items: center; gap: 0.625rem;
  padding: 0.625rem 0.75rem;
  font-family: 'Public Sans', system-ui, sans-serif;
  font-size: 14px;
  font-weight: 500;
  color: rgb(var(--color-on-surface));
  background: transparent;
  border: 0;
  border-radius: 0.625rem;
  width: 100%;
  text-align: left;
  text-decoration: none;
  cursor: pointer;
  transition: background var(--lum-dur-fast) var(--lum-ease);
}
.tz-avatar-item:hover { background: rgb(var(--color-on-surface) / 0.05); }

.tz-palette-item[data-selected="1"] {
  background: rgb(var(--color-on-surface) / 0.06);
  color: rgb(var(--color-on-surface));
}
.tz-palette-item:hover { background: rgb(var(--color-on-surface) / 0.04); }

/* ============================================================================
   Auth indicator in the sidebar.
   ========================================================================== */
#auth-info {
  display: block;
  font-family: 'Public Sans', system-ui, sans-serif;
  font-size: 11px;
  font-weight: 500;
  text-transform: none;
  letter-spacing: 0;
  color: rgb(var(--color-on-surface-variant));
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* ============================================================================
   Motion — gate behind the .tz-motion class that motion.js adds on
   module load. Content is fully visible by default; the gate ensures
   the entrance animations never paint over a slow load. A 1.2s
   failsafe force-reveals anything the IntersectionObserver missed.
   ========================================================================== */
.tz-motion .tz-reveal {
  opacity: 0;
  transform: translateY(8px);
  transition: opacity 480ms var(--lum-ease), transform 480ms var(--lum-ease);
  transition-delay: var(--tz-delay, 0ms);
}
.tz-motion .tz-reveal.tz-in { opacity: 1; transform: none; }
.tz-motion .tz-hero__in {
  opacity: 0;
  transform: translateY(6px);
  animation: lum-rise var(--lum-dur-slow) var(--lum-ease) forwards;
  animation-delay: calc(var(--lum-i, 0) * 80ms + 60ms);
}
@keyframes lum-rise {
  to { opacity: 1; transform: none; }
}

/* ============================================================================
   Reduced motion — both the OS preference and the in-app class collapse
   every animation to instant and force-reveal hidden content.
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
  .tz-reveal, .tz-hero__in { opacity: 1 !important; transform: none !important; }
  .tz-pulse-dot, .tz-status[data-state="processing"]::before { animation: none !important; }
}
html.tz-reduced-motion *, html.tz-reduced-motion *::before, html.tz-reduced-motion *::after {
  animation-duration: 0.001ms !important;
  transition-duration: 0.001ms !important;
}
html.tz-reduced-motion .tz-reveal, html.tz-reduced-motion .tz-hero__in {
  opacity: 1 !important; transform: none !important;
}
html.tz-reduced-motion .tz-pulse-dot,
html.tz-reduced-motion .tz-status[data-state="processing"]::before { animation: none !important; }

/* ============================================================================
   Token-name compatibility shims. Pages written against the old phosphor
   world use `text-on-surface`, `bg-surface-raised`, etc. The Tailwind
   config above remaps them, but inline `var(--sig-*)` references still
   appear in a handful of pages. The aliases below resolve to ready-to-use
   CSS colour values (rgb() form) so they work in any context — color,
   background, border-color, accent-color, stroke, fill — without the
   page having to wrap them. No visible effect; both themes already
   define both families.
   ========================================================================== */
:root {
  --sig-void:          rgb(var(--color-on-primary));
  --sig-panel:         rgb(var(--color-surface));
  --sig-panel-raised:  rgb(var(--color-surface));
  --sig-panel-high:    rgb(var(--color-surface-high));
  --sig-well:          rgb(var(--color-surface-low));
  --sig-bezel:         rgb(var(--color-outline));
  --sig-bezel-hot:     rgb(var(--color-outline));
  --sig-phosphor:      rgb(var(--color-primary));
  --sig-phosphor-dim:  rgb(var(--color-on-surface-variant));
  --sig-lock:          rgb(var(--color-success));
  --sig-warn:          rgb(var(--color-warning));
  --sig-alert:         rgb(var(--color-error));
  --sig-text:          rgb(var(--color-on-surface));
  --sig-text-dim:      rgb(var(--color-on-surface-variant));
  --sig-text-ghost:    rgb(var(--color-on-surface-ghost));
  --sig-top-highlight:  none;
  --sig-bottom-shade:  none;
  --sig-inset-deep:    none;
  --sig-bloom-phosphor: none;
  --sig-bloom-lock:    none;
  --sig-bloom-warn:    none;
  --sig-bloom-alert:   none;
  --sig-ease:          var(--lum-ease);
  --sig-ease-in-out:   var(--lum-ease-in-out);
  --sig-dur:           var(--lum-dur);
  --sig-dur-fast:      var(--lum-dur-fast);
  --sig-dur-slow:      var(--lum-dur-slow);
}

/* Screen-reader-only. Used by pageHeader(): the visible page title lives in the
   topbar, but each page keeps a real <h1> here so the document outline and
   assistive tech are unaffected by that purely visual decision. */
.tz-visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* ============================================================================
   Console shell layout — one full-width header above a sidebar + canvas row.
   The topbar used to be a sibling of the sidebar, so it only spanned the
   content column and the two read as disconnected strips. Now the header spans
   the full width and this row sits beneath it.
   ========================================================================== */
.tz-console-body {
  flex: 1 1 auto;
  display: flex;
  gap: 0.875rem;
  min-height: 0;          /* lets the canvas scroll instead of the page */
  width: 100%;
  padding: 0.875rem;
}

/* The sidebar is a FLOATING PANEL inset from the window edges, not a flush
   full-bleed rail — that separation is what gives the shell its depth in the
   reference layout. */
.tz-glass-sidebar {
  width: 216px;
  flex: 0 0 216px;
  min-height: 0;
  overflow: hidden;
  border-radius: 1rem;
  border: 0;
  background: rgb(var(--color-surface-lowest));
  box-shadow: var(--lum-elev-2);
}

/* The canvas is a panel too, so the two read as a matched pair. Borderless:
   a drawn 1px edge reads as a hard outline at this scale; the elevation
   already separates the panel from the page ground. */
.tz-console-body > main {
  border-radius: 1rem;
  border: 0;
  background: rgb(var(--color-surface-lowest));
  box-shadow: var(--lum-elev-2);
  overflow: hidden;
  min-width: 0;
}

/* Centre the search between the brand and the control cluster. It previously
   sat hard against the logotype because the only spacer was after it. */
.tz-topbar { position: relative; }
.tz-topbar__search {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  width: min(560px, 46vw);
  margin-inline: 0;
}
@media (max-width: 900px) {
  .tz-topbar__search { position: static; transform: none; width: auto; margin-inline: auto; }
}
.tz-topbar__spacer { display: none; }

/* The hamburger is the mobile nav trigger and must not appear on desktop. */
.tz-topbar__mobile-nav { display: none; }
@media (max-width: 767px) {
  .tz-topbar__mobile-nav { display: inline-flex; }
  .tz-console-body { padding: 0.5rem; gap: 0.5rem; }
}

/* --- sidebar sections ---------------------------------------------------- */
.tz-sidebar__context { padding: 0.7rem 0.75rem 0.55rem; display: flex; flex-direction: column; gap: 0.4rem; }
.tz-sidebar__org,
.tz-sidebar__project { display: flex; flex-direction: column; gap: 0.1rem; min-width: 0; }
.tz-sidebar__org-label {
  font-size: 10px; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase;
  color: rgb(var(--color-on-surface-variant));
}
.tz-sidebar__org-value {
  font-size: 13.5px; font-weight: 600; color: rgb(var(--color-on-surface));
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.tz-sidebar__new-project { margin-top: 0.5rem; width: 100%; }

.tz-sidebar__divider { height: 1px; background: rgb(var(--color-border-subtle)); margin: 0 0.875rem; flex: 0 0 auto; }

.tz-sidebar__nav { padding: 0.4rem 0.5rem; min-height: 0; }
.tz-sidebar__group-label {
  padding: 0.55rem 0.55rem 0.2rem;
  font-size: 10px; font-weight: 600; letter-spacing: 0.09em; text-transform: uppercase;
  color: rgb(var(--color-on-surface-variant));
}
.tz-sidebar__bottom { padding: 0.5rem; display: flex; flex-direction: column; gap: 0.125rem; flex: 0 0 auto; }

/* Fit the whole nav without scrolling on shorter viewports too. The item
   metrics step down with the available height so the ~16 links + labels stay
   visible rather than forcing a scroll on a 13" laptop or a split screen. */
@media (max-height: 780px) {
  .tz-nav-item { padding: 0.26rem 0.7rem; font-size: 12.5px; }
  .tz-sidebar__group-label { padding: 0.4rem 0.55rem 0.16rem; }
  .tz-sidebar__nav { padding: 0.3rem 0.5rem; }
  .tz-sidebar__context { padding: 0.5rem 0.75rem 0.45rem; }
}
@media (max-height: 660px) {
  .tz-nav-item { padding: 0.2rem 0.65rem; font-size: 12px; gap: 0.5rem; }
  .tz-nav-item .tz-glyph svg { width: 16px; height: 16px; }
  .tz-sidebar__group-label { padding: 0.28rem 0.55rem 0.12rem; font-size: 9.5px; }
}
.tz-sidebar__account {
  padding: 0.6rem 0.625rem 0.2rem;
  font-size: 11.5px; color: rgb(var(--color-on-surface-variant));
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* --- header search ------------------------------------------------------- */
.tz-topbar__search {
  position: relative;
  display: flex;
  align-items: center;
  flex: 0 1 420px;
  margin-inline: 0.75rem;
}
.tz-topbar__search-icon {
  position: absolute; left: 0.75rem; display: inline-flex;
  color: rgb(var(--color-on-surface-variant)); pointer-events: none;
}
.tz-topbar__search input {
  width: 100%;
  height: 34px;
  padding: 0 3rem 0 2.25rem;
  font-size: 13px;
  border-radius: var(--lum-radius-pill);
  /* Satin, like every other interactive control (see DESIGN.md). */
  background: linear-gradient(180deg, var(--lum-satin-from) 0%, var(--lum-satin-to) 100%);
  border: 1px solid var(--lum-satin-border);
  box-shadow: var(--lum-satin-shadow);
  color: rgb(var(--color-on-surface));
  font-size: 13px;
  font-family: inherit;
  outline: none;
}
.tz-topbar__search input::placeholder { color: rgb(var(--color-on-surface-variant)); }
.tz-topbar__search input:hover { box-shadow: var(--lum-satin-shadow-hover); }
.tz-topbar__search input:focus-visible { outline: 2px solid var(--lum-focus-ring); outline-offset: 2px; }
.tz-topbar__search input::-webkit-search-cancel-button { display: none; }
.tz-topbar__search-hint { position: absolute; right: 0.6rem; display: inline-flex; pointer-events: none; }
.tz-kbd {
  font-family: var(--lum-font-mono, ui-monospace, monospace);
  font-size: 10px; line-height: 1;
  padding: 0.25rem 0.35rem;
  border-radius: 0.35rem;
  border: 1px solid rgb(var(--color-border-subtle));
  color: rgb(var(--color-on-surface-variant));
  background: rgb(var(--color-surface-lowest));
}

@media (max-width: 767px) {
  .tz-glass-sidebar { display: none; }
  .tz-topbar__search { flex: 1 1 auto; margin-inline: 0.5rem; }
  .tz-topbar__search-hint { display: none; }
}


/* ============================================================================
   Satin sweep — anything clickable that had escaped the material.
   DESIGN.md: if it responds to a click, it is satin, in both themes.
   ========================================================================== */
#console-shell select,
#console-shell .tz-select,
#console-shell input[type="text"],
#console-shell input[type="search"],
#console-shell input[type="url"],
#console-shell input[type="email"],
#console-shell .tz-chip-btn,
#console-shell .tz-pager button,
#console-shell .tz-tab,
#console-shell button.tz-plain,
#console-shell .tz-table button:not(.tz-satin):not(.tz-btn--ghost) {
  border-radius: var(--lum-radius-pill);
  background: linear-gradient(180deg, var(--lum-satin-from) 0%, var(--lum-satin-to) 100%);
  border: 1px solid var(--lum-satin-border);
  box-shadow: var(--lum-satin-shadow);
  color: rgb(var(--color-on-surface));
}
select:hover,
.tz-select:hover,
.tz-chip-btn:hover,
.tz-pager button:hover,
.tz-tab:hover { box-shadow: var(--lum-satin-shadow-hover); }


/* ============================================================================
   Borderless satin.
   Definition comes from the gradient, the inner top highlight and the soft
   drop shadow — not from a drawn 1px edge. This matches the active sidebar
   item, which is the reference the owner pointed at.
   ========================================================================== */
.tz-satin,
.tz-satin--primary,
.tz-satin--secondary,
.tz-btn,
.tz-btn--primary,
.tz-btn--secondary,
.tz-icon-btn,
.tz-project-switcher,
.tz-topbar__search input,
select,
.tz-select,
.tz-chip-btn,
.tz-pager button,
.tz-tab,
button[type="submit"] {
  border: 0;
}

/* ============================================================================
   Public home page.
   ========================================================================== */
.tz-home { max-width: 1180px; margin: 0 auto; padding: 0 var(--lum-gutter, 24px) 96px; }

.tz-home__hero { padding: 88px 0 64px; text-align: center; display: flex; flex-direction: column; align-items: center; }
.tz-home__pill {
  display: inline-flex; align-items: center; gap: 0.5rem;
  padding: 0.35rem 0.85rem; border-radius: var(--lum-radius-pill);
  background: linear-gradient(180deg, var(--lum-satin-from) 0%, var(--lum-satin-to) 100%);
  box-shadow: var(--lum-satin-shadow);
  font-size: 11.5px; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase;
  color: rgb(var(--color-on-surface-variant)); margin-bottom: 1.75rem;
}
.tz-home__title {
  font-size: clamp(34px, 5.2vw, 58px); line-height: 1.08; font-weight: 700;
  letter-spacing: -0.03em; margin: 0 0 1.25rem; max-width: 20ch; text-wrap: balance;
  color: rgb(var(--color-on-surface));
}
.tz-home__title-accent { display: block; color: rgb(var(--color-on-surface-variant)); }
.tz-home__lede {
  font-size: 17.5px; line-height: 1.6; color: rgb(var(--color-on-surface-variant));
  max-width: 62ch; margin: 0 0 2rem;
}
.tz-home__ctas { display: flex; flex-wrap: wrap; gap: 0.75rem; justify-content: center; margin-bottom: 4rem; }
.tz-home__cta { height: 44px; padding: 0 1.5rem; display: inline-flex; align-items: center; font-size: 14.5px; }

.tz-home__pipeline {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 1px;
  width: 100%; border-radius: 1rem; overflow: hidden;
  background: rgb(var(--color-border-subtle)); box-shadow: var(--lum-elev-2);
}
.tz-home__stage {
  background: rgb(var(--color-surface-lowest));
  padding: 1.5rem 1.25rem; display: flex; flex-direction: column; gap: 0.3rem; text-align: left;
}
.tz-home__stage-n { font-family: var(--lum-font-mono, ui-monospace, monospace); font-size: 11px; color: rgb(var(--color-on-surface-variant)); }
.tz-home__stage-label { font-size: 16px; font-weight: 650; color: rgb(var(--color-on-surface)); }
.tz-home__stage-note { font-size: 13px; color: rgb(var(--color-on-surface-variant)); }

.tz-home__section { padding: 72px 0; border-top: 1px solid rgb(var(--color-border-subtle)); }
.tz-home__section-head { max-width: 62ch; margin-bottom: 2.5rem; display: flex; flex-direction: column; gap: 0.65rem; }
.tz-home__kicker {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  align-self: flex-start;
  padding: 0.3rem 0.7rem;
  border-radius: var(--lum-radius-pill);
  background: linear-gradient(180deg, var(--lum-satin-from) 0%, var(--lum-satin-to) 100%);
  border: 1px solid var(--lum-satin-border);
  box-shadow: var(--lum-satin-shadow);
  font-family: 'Public Sans', system-ui, sans-serif;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: rgb(var(--color-on-surface-variant));
}
.tz-home__h2 { font-size: clamp(24px, 3vw, 32px); font-weight: 650; letter-spacing: -0.02em; margin: 0; color: rgb(var(--color-on-surface)); text-wrap: balance; }
.tz-home__body { font-size: 16px; line-height: 1.65; color: rgb(var(--color-on-surface-variant)); margin: 0; max-width: 62ch; }

.tz-home__split { display: grid; grid-template-columns: 1fr; gap: 2.5rem; align-items: start; }
@media (min-width: 1024px) { .tz-home__split { grid-template-columns: 1.05fr 1fr; gap: 3.5rem; } }

.tz-home__code-panel { border-radius: 1rem; overflow: hidden; background: rgb(var(--color-surface-lowest)); box-shadow: var(--lum-elev-2); }
.tz-home__code-head {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  padding: 0.7rem 0.9rem 0.7rem 1.1rem; border-bottom: 1px solid rgb(var(--color-border-subtle));
}
.tz-home__code-name { font-family: var(--lum-font-mono, ui-monospace, monospace); font-size: 12px; color: rgb(var(--color-on-surface-variant)); }
.tz-home__copy { height: 30px; padding: 0 0.85rem; font-size: 12px; }
.tz-home__code {
  margin: 0; padding: 1.25rem; overflow-x: auto;
  font-family: var(--lum-font-mono, ui-monospace, monospace);
  font-size: 12.5px; line-height: 1.75; color: rgb(var(--color-on-surface-variant));
}

.tz-home__feature-list { display: flex; flex-direction: column; gap: 1.5rem; margin-top: 2rem; }
.tz-home__feature { display: flex; gap: 1rem; }
.tz-home__feature-glyph {
  width: 38px; height: 38px; flex: 0 0 38px; border-radius: 0.7rem;
  display: inline-flex; align-items: center; justify-content: center;
  background: linear-gradient(180deg, var(--lum-satin-from) 0%, var(--lum-satin-to) 100%);
  box-shadow: var(--lum-satin-shadow); color: rgb(var(--color-on-surface));
}
.tz-home__feature-title { font-size: 15.5px; font-weight: 650; margin: 0 0 0.2rem; color: rgb(var(--color-on-surface)); }
.tz-home__feature-body { font-size: 14px; line-height: 1.6; color: rgb(var(--color-on-surface-variant)); margin: 0; }

.tz-home__pricing { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 1rem; }
.tz-home__price-card { border-radius: 1rem; padding: 1.5rem; background: rgb(var(--color-surface-lowest)); box-shadow: var(--lum-elev-2); display: flex; flex-direction: column; gap: 0.75rem; }
.tz-home__price-head { display: flex; align-items: center; gap: 0.75rem; }
.tz-home__price-label { font-size: 16px; font-weight: 650; margin: 0; color: rgb(var(--color-on-surface)); }
.tz-home__price-amount { display: flex; align-items: baseline; gap: 0.4rem; }
.tz-home__price-figure { font-size: 34px; font-weight: 700; letter-spacing: -0.02em; font-variant-numeric: tabular-nums; color: rgb(var(--color-on-surface)); }
.tz-home__price-unit { font-size: 13.5px; color: rgb(var(--color-on-surface-variant)); }
.tz-home__fineprint { margin: 1.5rem 0 0; font-size: 12.5px; color: rgb(var(--color-on-surface-variant)); }

.tz-home__footer {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 1rem;
  padding-top: 2.5rem; border-top: 1px solid rgb(var(--color-border-subtle));
}
.tz-home__footer-brand { font-family: 'Kaushan Script', 'Public Sans', cursive; font-size: 20px; color: rgb(var(--color-on-surface)); }
.tz-home__footer-nav { display: flex; gap: 1.5rem; }
.tz-home__footer-nav a { font-size: 14px; color: rgb(var(--color-on-surface-variant)); text-decoration: none; }
.tz-home__footer-nav a:hover { color: rgb(var(--color-on-surface)); }

/* ============================================================================
   Select control.
   Native selects ship a UA chevron that ignores the theme, and mono type on a
   product control reads as debug output rather than UI. Public Sans, satin
   surface, and a drawn chevron that follows currentColor.
   ========================================================================== */
#console-shell select,
#console-shell .tz-select {
  appearance: none;
  -webkit-appearance: none;
  font-family: 'Public Sans', system-ui, sans-serif;
  font-size: 14px;
  font-weight: 500;
  height: 42px;
  padding: 0 2.5rem 0 1rem;
  max-width: 340px;
  cursor: pointer;
  color: rgb(var(--color-on-surface));
  background-image:
    url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 14 14' fill='none'%3E%3Cpath d='M3.5 5.5 7 9l3.5-3.5' stroke='%236e6e73' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E"),
    linear-gradient(180deg, var(--lum-satin-from) 0%, var(--lum-satin-to) 100%);
  background-repeat: no-repeat, no-repeat;
  background-position: right 0.9rem center, 0 0;
  background-size: 14px 14px, 100% 100%;
}
#console-shell select:hover,
#console-shell .tz-select:hover { box-shadow: var(--lum-satin-shadow-hover); }

/* ============================================================================
   Ingest: mode switcher, bulk rows, URL field.
   ========================================================================== */
#console-shell .tz-mode { height: 34px; padding: 0 0.9rem; font-size: 13px; }
#console-shell .tz-mode[aria-pressed="true"] {
  background: linear-gradient(180deg, var(--lum-primary-satin-from) 0%, var(--lum-primary-satin-to) 100%);
  color: var(--lum-primary-satin-label);
  box-shadow: var(--lum-primary-satin-shadow);
}

.tz-bulk-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto 120px;
  align-items: center;
  gap: 0.75rem;
  padding: 0.55rem 0.75rem;
  border-radius: 0.6rem;
  background: rgb(var(--color-surface-low));
}
.tz-bulk-name { font-size: 13.5px; color: rgb(var(--color-on-surface)); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tz-bulk-state { font-size: 11.5px; letter-spacing: 0.04em; text-transform: uppercase; color: rgb(var(--color-on-surface-variant)); }
.tz-bulk-state[data-kind="ok"]    { color: rgb(var(--color-success)); }
.tz-bulk-state[data-kind="error"] { color: rgb(var(--color-error)); text-transform: none; letter-spacing: 0; }
.tz-bulk-track { height: 5px; border-radius: 999px; background: rgb(var(--color-surface-highest)); overflow: hidden; }
.tz-bulk-fill  { display: block; height: 100%; width: 0; background: rgb(var(--color-on-surface-variant)); transition: width 180ms ease; }

#console-shell #url-input {
  height: 42px; padding: 0 1rem; max-width: 560px;
  font-family: 'Public Sans', system-ui, sans-serif; font-size: 14px;
  border-radius: var(--lum-radius-pill);
  background: linear-gradient(180deg, var(--lum-satin-from) 0%, var(--lum-satin-to) 100%);
  box-shadow: var(--lum-satin-shadow);
  color: rgb(var(--color-on-surface));
}

/* ============================================================================
   Home: 3D hero canvas.
   The canvas sits behind the hero copy and is masked at the edges so the
   frame stack fades out rather than colliding with the section boundary.
   ========================================================================== */
.tz-home__hero { position: relative; }
/* A real flex container, not `display: contents`. */
.tz-home__hero-inner {
  position: relative; z-index: 1;
  display: flex; flex-direction: column; align-items: center; width: 100%;
}

/* ============================================================================
   Home: plans.
   ========================================================================== */
.tz-home__interval { display: flex; gap: 0.5rem; margin-bottom: 2rem; }
.tz-home__save-tag { font-variant-numeric: tabular-nums; opacity: 0.75; margin-left: 0.35rem; }

.tz-home__plans { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 1rem; }
.tz-home__plan {
  position: relative; border-radius: 1rem; padding: 1.75rem 1.5rem;
  background: rgb(var(--color-surface-lowest)); box-shadow: var(--lum-elev-2);
  display: flex; flex-direction: column; gap: 0.5rem;
}
.tz-home__plan--featured { box-shadow: var(--lum-elev-3, var(--lum-elev-2)); }
.tz-home__plan-flag {
  position: absolute; top: -0.65rem; left: 1.5rem;
  padding: 0.2rem 0.7rem; border-radius: var(--lum-radius-pill);
  font-size: 10.5px; font-weight: 650; letter-spacing: 0.06em; text-transform: uppercase;
  background: linear-gradient(180deg, var(--lum-primary-satin-from) 0%, var(--lum-primary-satin-to) 100%);
  color: var(--lum-primary-satin-label); box-shadow: var(--lum-primary-satin-shadow);
}
.tz-home__plan-name { font-size: 15px; font-weight: 650; margin: 0; color: rgb(var(--color-on-surface-variant)); letter-spacing: 0.02em; }
.tz-home__plan-price { display: flex; align-items: baseline; gap: 0.4rem; }
.tz-home__plan-annual { margin: -0.25rem 0 0; font-size: 12.5px; color: rgb(var(--color-on-surface-variant)); }
.tz-home__plan-included { margin: 0.25rem 0 0; font-size: 14.5px; font-weight: 600; color: rgb(var(--color-on-surface)); }
.tz-home__plan-rate { margin: 0; font-size: 14px; font-variant-numeric: tabular-nums; color: rgb(var(--color-on-surface)); }
.tz-home__plan-rate span { font-variant-numeric: normal; color: rgb(var(--color-on-surface-variant)); }
/* Storage tier slider. Uses the existing --color-* / --lum-* tokens only —
   the plan cards define no palette of their own, and this must not introduce
   one. */
.tz-home__plan-storage { margin: 0.75rem 0 0.25rem; padding-top: 0.75rem; border-top: 1px solid rgb(var(--color-outline-variant, var(--color-outline)) / 0.5); }
.tz-home__storage-label { display: flex; align-items: baseline; justify-content: space-between; font-size: 13px; color: rgb(var(--color-on-surface-variant)); margin-bottom: 0.4rem; }
.tz-home__storage-value { font-size: 14.5px; font-weight: 650; font-variant-numeric: tabular-nums; color: rgb(var(--color-on-surface)); }
.tz-home__storage-range { width: 100%; accent-color: rgb(var(--color-primary)); cursor: pointer; }
/* A visible focus ring: the slider is keyboard-operable and its native
   outline is easy to lose against the card surface. */
.tz-home__storage-range:focus-visible { outline: 2px solid rgb(var(--color-primary)); outline-offset: 3px; border-radius: 4px; }
.tz-home__storage-note { margin: 0.35rem 0 0; font-size: 12.5px; min-height: 1.1em; color: rgb(var(--color-on-surface-variant)); }

.tz-home__plan-cta { margin-top: auto; height: 40px; display: inline-flex; align-items: center; justify-content: center; font-size: 14px; }

.tz-home__meters { margin-top: 2.5rem; }
.tz-home__meters-title { font-size: 13px; font-weight: 650; letter-spacing: 0.06em; text-transform: uppercase; color: rgb(var(--color-on-surface-variant)); margin: 0 0 1rem; }
.tz-home__meter-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 1rem; margin: 0; }
.tz-home__meter dt { font-size: 13px; color: rgb(var(--color-on-surface-variant)); margin-bottom: 0.15rem; }
.tz-home__meter dd { margin: 0; font-size: 19px; font-weight: 650; font-variant-numeric: tabular-nums; color: rgb(var(--color-on-surface)); }
.tz-home__meter dd span { font-size: 12.5px; font-weight: 400; font-variant-numeric: normal; color: rgb(var(--color-on-surface-variant)); }

/* ============================================================================
   Home: AWS savings calculator.
   ========================================================================== */
.tz-home__calc { display: grid; grid-template-columns: 1fr; gap: 2rem; align-items: start; }
@media (min-width: 900px) { .tz-home__calc { grid-template-columns: 300px 1fr; gap: 2.5rem; } }

.tz-home__calc-inputs { display: flex; flex-direction: column; gap: 1rem; }
.tz-home__calc-field { display: flex; flex-direction: column; gap: 0.35rem; }
.tz-home__calc-label { font-size: 12.5px; color: rgb(var(--color-on-surface-variant)); }
.tz-home__calc-input {
  height: 42px; padding: 0 1rem; width: 100%;
  font-family: 'Public Sans', system-ui, sans-serif; font-size: 14px;
  font-variant-numeric: tabular-nums;
  border: 0; border-radius: var(--lum-radius-pill);
  background: linear-gradient(180deg, var(--lum-satin-from) 0%, var(--lum-satin-to) 100%);
  box-shadow: var(--lum-satin-shadow);
  color: rgb(var(--color-on-surface));
}
.tz-home__calc-input:hover { box-shadow: var(--lum-satin-shadow-hover); }
.tz-home__calc-section select.tz-select {
  appearance: none; -webkit-appearance: none;
  font-family: 'Public Sans', system-ui, sans-serif; font-size: 14px; font-weight: 500;
  height: 42px; padding: 0 2.5rem 0 1rem; width: 100%; cursor: pointer;
  border: 0; border-radius: var(--lum-radius-pill);
  color: rgb(var(--color-on-surface));
  background-image:
    url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 14 14' fill='none'%3E%3Cpath d='M3.5 5.5 7 9l3.5-3.5' stroke='%236e6e73' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E"),
    linear-gradient(180deg, var(--lum-satin-from) 0%, var(--lum-satin-to) 100%);
  background-repeat: no-repeat, no-repeat;
  background-position: right 0.9rem center, 0 0;
  background-size: 14px 14px, 100% 100%;
  box-shadow: var(--lum-satin-shadow);
}
.tz-home__calc-check { display: flex; align-items: center; gap: 0.6rem; font-size: 14px; color: rgb(var(--color-on-surface)); cursor: pointer; }

.tz-home__verdict {
  border-radius: 1rem; padding: 1.5rem 1.75rem; margin-bottom: 1.25rem;
  background: rgb(var(--color-surface-lowest)); box-shadow: var(--lum-elev-2);
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.35rem 0.75rem;
}
.tz-home__verdict-label { font-size: 12.5px; letter-spacing: 0.06em; text-transform: uppercase; color: rgb(var(--color-on-surface-variant)); width: 100%; }
.tz-home__verdict-figure { font-size: clamp(32px, 5vw, 46px); font-weight: 700; letter-spacing: -0.03em; font-variant-numeric: tabular-nums; color: rgb(var(--color-on-surface)); }
.tz-home__verdict-unit { font-size: 14px; color: rgb(var(--color-on-surface-variant)); font-variant-numeric: tabular-nums; }
.tz-home__verdict-year { margin-left: auto; font-size: 13.5px; font-variant-numeric: tabular-nums; color: rgb(var(--color-on-surface-variant)); }
.tz-home__verdict--neutral .tz-home__verdict-figure { color: rgb(var(--color-on-surface-variant)); }

.tz-home__calc-table { width: 100%; border-collapse: collapse; font-variant-numeric: tabular-nums; }
.tz-home__calc-table th, .tz-home__calc-table td { padding: 0.7rem 0.75rem; text-align: right; font-size: 14px; }
.tz-home__calc-table thead th { font-size: 11.5px; letter-spacing: 0.06em; text-transform: uppercase; color: rgb(var(--color-on-surface-variant)); font-weight: 600; }
.tz-home__calc-table tbody th[scope="row"], .tz-home__calc-table tfoot th { text-align: left; font-weight: 500; color: rgb(var(--color-on-surface)); }
.tz-home__calc-table small { display: block; font-size: 11.5px; font-weight: 400; color: rgb(var(--color-on-surface-variant)); margin-top: 0.15rem; }
.tz-home__calc-table td { color: rgb(var(--color-on-surface)); }
.tz-home__calc-table tbody tr + tr th, .tz-home__calc-table tbody tr + tr td { border-top: 1px solid rgb(var(--color-border-subtle)); }
.tz-home__calc-table tfoot th, .tz-home__calc-table tfoot td { border-top: 1.5px solid rgb(var(--color-border-subtle)); font-weight: 700; }
.tz-home__cell--worse { color: rgb(var(--color-on-surface-variant)); }
.tz-home__calc-note { margin: 1rem 0 0; font-size: 13px; line-height: 1.6; color: rgb(var(--color-on-surface-variant)); }

/* ============================================================================
   Formats showcase (Phase A)

   Pulled live from GET /v1/capabilities — every chip is rendered from
   the API response, never hard-coded in JS. The visual language
   matches the rest of the page: satin material on the column cards
   (vertical gradient + top inner highlight + soft shadow), a quieter
   satin on the pills themselves. The earlier per-family chip tinting
   made 26 input pills read as a rainbow; that broke the luxe feel of
   the rest of the landing page. Streaming / broadcast containers get
   a primary-tinted border as a subtle hint that they are the
   differentiated surface; everything else is the default tone.

   Three modes share the same primitives:
     .tz-fmt-showcase  — full marketing grid (home page)
     .tz-fmt-compact   — single-line strip (API Explorer)
     .tz-fmt-dense     — single column for dense surfaces (composer)
   ============================================================================ */
.tz-fmt-pill {
  display: inline-flex;
  align-items: center;
  padding: 0.28rem 0.7rem;
  border-radius: var(--lum-radius-pill);
  font-family: 'Public Sans', system-ui, sans-serif;
  font-size: 12.5px;
  font-weight: 500;
  letter-spacing: -0.005em;
  line-height: 1.1;
  white-space: nowrap;
  color: rgb(var(--color-on-surface));
  /* Satin finish: matches the .tz-satin button material so the chips
     read as part of the page. The vertical gradient + inset top
     highlight is the same recipe that makes the page's buttons
     feel considered rather than utilitarian. */
  background: linear-gradient(180deg, var(--lum-satin-from) 0%, var(--lum-satin-to) 100%);
  border: 1px solid var(--lum-satin-border);
  box-shadow: var(--lum-satin-shadow);
  transition:
    transform var(--lum-dur-fast) var(--lum-ease),
    box-shadow var(--lum-dur-fast) var(--lum-ease),
    border-color var(--lum-dur-fast) var(--lum-ease);
}
.tz-fmt-pill:hover {
  box-shadow: var(--lum-satin-shadow-hover);
  transform: translateY(-1px);
}

/* Streaming / broadcast chips: a single primary-tinted border so the
   streaming surface (HLS, DASH) and the professional ingest surface
   (MXF, ProRes, XDCAM, DNX) read as related-to-action without
   becoming a rainbow. One accent only, used twice — the rest of the
   chips stay neutral so the page's visual hierarchy is preserved. */
.tz-fmt-pill--primary {
  border-color: var(--lum-primary-satin-border);
  color: var(--lum-primary-satin-label);
}
.tz-fmt-pill--neutral {
  /* Default — uses the base .tz-fmt-pill satin finish. */
}

/* ----- Marketing grid (home page) ----- */
.tz-fmt-showcase {
  display: flex;
  flex-direction: column;
  gap: 1.75rem;
}
.tz-fmt-showcase__grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1rem;
}
@media (min-width: 768px) {
  .tz-fmt-showcase__grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 1.25rem;
  }
}
.tz-fmt-col {
  display: flex;
  flex-direction: column;
  gap: 0.85rem;
  padding: 1.25rem 1.4rem 1.4rem;
  border-radius: var(--lum-radius);
  /* Satin finish on the column card too — same recipe as the page's
     primary buttons, so the column looks like a polished surface
     rather than a flat bordered box. */
  background: linear-gradient(180deg, var(--lum-satin-from) 0%, var(--lum-satin-to) 100%);
  border: 1px solid var(--lum-satin-border);
  box-shadow: var(--lum-satin-shadow);
}
.tz-fmt-col__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.5rem;
}
.tz-fmt-col__title {
  font-family: 'Public Sans', system-ui, sans-serif;
  font-weight: 600;
  font-size: 11.5px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: rgb(var(--color-on-surface-variant));
  margin: 0;
}
.tz-fmt-col__count {
  font-family: 'JetBrains Mono', ui-monospace, Menlo, monospace;
  font-size: 11px;
  font-weight: 500;
  color: rgb(var(--color-on-surface-variant));
  font-variant-numeric: tabular-nums;
}
.tz-fmt-col__hint {
  font-family: 'Public Sans', system-ui, sans-serif;
  font-size: 13px;
  line-height: 1.5;
  color: rgb(var(--color-on-surface));
  margin: 0;
  font-weight: 400;
}
.tz-fmt-col__chips {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
}
.tz-fmt-showcase__source {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  margin: 0;
  font-size: 12.5px;
  color: rgb(var(--color-on-surface-variant));
  font-family: 'Public Sans', system-ui, sans-serif;
}
.tz-fmt-showcase__source .material-symbols-outlined { font-size: 16px; }
.tz-fmt-showcase__source code {
  font-family: 'JetBrains Mono', ui-monospace, Menlo, monospace;
  font-size: 11.5px;
  padding: 0.1rem 0.45rem;
  border-radius: var(--lum-radius-sm);
  background: linear-gradient(180deg, var(--lum-satin-from) 0%, var(--lum-satin-to) 100%);
  border: 1px solid var(--lum-satin-border);
  box-shadow: var(--lum-satin-shadow);
  color: rgb(var(--color-on-surface));
}

/* ----- Compact strip (API Explorer) ----- */
.tz-fmt-compact {
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
}
.tz-fmt-compact__label {
  font-family: 'Public Sans', system-ui, sans-serif;
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: rgb(var(--color-on-surface-variant));
  min-width: 4.5rem;
}
.tz-fmt-compact__row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem;
  align-items: center;
}
.tz-fmt-compact__chips { display: contents; }
.tz-fmt-compact .tz-fmt-pill {
  padding: 0.18rem 0.55rem;
  font-size: 11px;
}

/* ----- Dense (transcode composer) ----- */
.tz-fmt-dense {
  display: flex;
  flex-direction: column;
  gap: 0.85rem;
}
.tz-fmt-dense .tz-fmt-col { padding: 0.95rem 1.1rem 1.1rem; }
.tz-fmt-dense .tz-fmt-col__chips { gap: 0.3rem; }
.tz-fmt-dense .tz-fmt-col__title { font-size: 10.5px; }
.tz-fmt-dense .tz-fmt-pill { font-size: 11.5px; padding: 0.22rem 0.6rem; }


/* ============================================================================
   Transcode composer: source-asset picker list.

   Two per row, and capped so the list scrolls instead of growing without
   bound — an account with dozens of ready assets pushed every step of the
   composer below the fold.

   Written here rather than as Tailwind utilities because this markup is
   injected after first paint, and the CDN build was not emitting the
   responsive `md:grid-cols-2` variant for it, so the list rendered one-up at
   every width. A plain rule has no such dependency.
   ========================================================================== */
.tz-picker-list {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  /* ~4 rows before scrolling. `contain` keeps a trackpad flick inside the
     list instead of chaining to the page once it bottoms out. */
  max-height: 21rem;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding-right: 4px;
}
@media (max-width: 900px) {
  .tz-picker-list { grid-template-columns: minmax(0, 1fr); }
}

/* Delete control on an asset picker row.
   Sits outside the select <button> — nesting a button inside a button is
   invalid and browsers recover from it unpredictably. Revealed on hover or
   keyboard focus rather than always visible, so a destructive action is not
   the most prominent thing in a list you are meant to be choosing from, but
   is always reachable without a pointer. */
.tz-picker-delete {
  position: absolute;
  top: 8px;
  right: 8px;
  width: 26px;
  height: 26px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid rgb(var(--color-border-subtle) / 0.14);
  border-radius: 7px;
  background: rgb(var(--color-surface-lowest));
  color: rgb(var(--color-on-surface-variant));
  cursor: pointer;
  opacity: 0;
  transition: opacity 140ms ease, color 140ms ease, border-color 140ms ease;
}
.tz-picker-row:hover .tz-picker-delete,
.tz-picker-delete:focus-visible {
  opacity: 1;
}
.tz-picker-delete:hover {
  color: rgb(var(--color-error));
  border-color: rgb(var(--color-error) / 0.4);
}
.tz-picker-delete:disabled { opacity: 0.4; cursor: default; }
/* Touch devices have no hover, so the control would be unreachable. */
@media (hover: none) {
  .tz-picker-delete { opacity: 1; }
}
