/* ───────────────────────────────────────────────────────────────
 * @glasskit-ui/react — additive-lens design system for the
 * 600×600 Meta Ray-Ban Display surface.
 *
 * The Display is additive: black (#000) emits no light and shows the
 * real world through it. So the canvas is pure black and everything
 * drawn is *emitted light* — luminous hairline edges, specular
 * highlights, and soft glow, never fills or backdrop-blur. Built to
 * the spec in `docs/design/apple-feel.md` (§4–5).
 *
 * SCOPING — read this before importing.
 * The entire system is scoped under `.glass-viewport`. Nothing leaks
 * to the host document, so this stylesheet can be imported into ANY
 * page (including the light-mode marketing site) and only takes effect
 * inside a <GlassViewport>. Tokens are plain CSS custom properties on
 * the viewport (no global `@theme`), so they never collide with a
 * host's color tokens. Override the accent by re-declaring a token in
 * your own rule, e.g. `.glass-viewport { --accent: #6ad; }`.
 *
 *   @import "tailwindcss";
 *   @import "@glasskit-ui/react/styles.css";
 * ─────────────────────────────────────────────────────────────── */

/* ── The 600×600 surface + scoped design tokens ─────────────────── */
.glass-viewport {
  /* ── Design tokens — the theming contract ────────────────────────
   * Source-of-truth tokens are `--gk-*` (shadcn role names + the glasses
   * extras). They live here on `.glass-viewport` so they never collide with a
   * host site's tokens; the Tailwind `@theme` map in theme.css wires utilities
   * (bg-surface, text-foreground, border-border, ring-ring, text-readout …) to
   * them. Re-theme by re-declaring any `--gk-*` on `.glass-viewport` (or a
   * wrapper above it) — that is how a brand DESIGN.md is applied; one block of
   * overrides reskins every component. The old `--accent`, `--ink` and
   * `--surface` names are kept as aliases below so not-yet-converted code works.
   * (GlowIcon plate tones are a separate per-icon system; they do not follow
   * these tokens.) */

  /* Core roles */
  --gk-background: #0a0d14; /* the calm additive black canvas */
  --gk-foreground: #ffffff; /* primary emitted ink */
  --gk-muted-foreground: #d2d7d5; /* secondary text */
  --gk-foreground-faint: #888f8b; /* captions, idle labels (3rd ink tier) */
  --gk-surface: linear-gradient(
    180deg,
    rgba(255, 255, 255, 0.075),
    rgba(255, 255, 255, 0.028)
  ); /* popping surface fill */
  --gk-border: rgba(255, 255, 255, 0.1); /* lit surface edge */
  --gk-input: rgba(255, 255, 255, 0.1);
  --gk-rule: #2a2f37; /* dim hairline for inert edges */
  --gk-elevation:
    inset 0 1px 0 rgba(255, 255, 255, 0.14),
    0 14px 30px -18px rgba(0, 0, 0, 0.85); /* surface depth */

  /* Primary / accent + the waveguide bloom ramp */
  --gk-primary: #4c8dff; /* base accent, primary action + focus */
  --gk-primary-foreground: #ffffff; /* ink on filled accent */
  --gk-ring: var(--gk-primary); /* focus ring color */
  --gk-accent-active: #8fb6ff; /* focused/hot, brightest */
  --gk-accent-muted: #2f5fb0; /* idle-but-present edges */
  --gk-accent-faint: #1b3056; /* trailing edges (never #000) */
  --gk-primary-grad-hi: #5b9dff; /* filled-surface gradient, lit stop */
  --gk-primary-grad-lo: #3567e6; /* filled-surface gradient, deep stop */
  --gk-primary-surface: linear-gradient(
    180deg,
    var(--gk-primary-grad-hi) 0%,
    var(--gk-primary-grad-lo) 100%
  ); /* the "on/primary" fill */
  --gk-accent-glow: rgba(47, 95, 224, 0.6); /* bloom under accent surfaces */
  --gk-accent-glow-strong: rgba(47, 95, 224, 0.7); /* hotter, focused state */

  /* Semantic action colors — fixed meanings (accept/confirm vs decline/destroy)
   * that read clearer than the single brand accent. Still themeable: override
   * these to match a brand's success/danger palette. */
  --gk-positive: #2fb86a; /* accept / confirm */
  --gk-positive-surface: linear-gradient(180deg, #38cf79 0%, #1f9d57 100%);
  --gk-positive-glow: rgba(31, 157, 87, 0.55);
  --gk-danger: #e5484d; /* decline / destroy */
  --gk-danger-surface: linear-gradient(180deg, #f2595e 0%, #c93b40 100%);
  --gk-danger-glow: rgba(201, 59, 64, 0.5);

  /* Shape + type */
  --gk-radius: 18px;
  --gk-font-sans:
    ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;

  /* Back-compat aliases — old names → new tokens (re-theme via --gk-* only). */
  --accent: var(--gk-primary);
  --accent-active: var(--gk-accent-active);
  --accent-muted: var(--gk-accent-muted);
  --accent-faint: var(--gk-accent-faint);
  --accent-grad-hi: var(--gk-primary-grad-hi);
  --accent-grad-lo: var(--gk-primary-grad-lo);
  --accent-glow: var(--gk-accent-glow);
  --accent-glow-strong: var(--gk-accent-glow-strong);
  --accent-surface: var(--gk-primary-surface);
  --ink-primary: var(--gk-foreground);
  --ink-secondary: var(--gk-muted-foreground);
  --ink-tertiary: var(--gk-foreground-faint);
  --surface-fill: var(--gk-surface);
  --surface-edge: var(--gk-border);
  --surface-lift: var(--gk-elevation);
  --rule: var(--gk-rule);
  --color-bg: var(--gk-background);
  --color-accent: var(--gk-primary);
  --color-ink: var(--gk-foreground);
  --color-ink-dim: var(--gk-foreground-faint);
  --color-rule: var(--gk-rule);
  --color-surface: #14171c;
  --color-room: #07080a;
  --font-sans: var(--gk-font-sans);

  position: relative;
  height: 600px;
  width: 600px;
  overflow: hidden;
  background:
    radial-gradient(
      100% 72% at 50% -10%,
      rgba(86, 116, 196, 0.14) 0%,
      transparent 55%
    ),
    linear-gradient(168deg, #0b0e16 0%, #090b11 100%);
  color: var(--ink-primary);
  font-family: var(--font-sans);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* Scoped reset — lens content matches device metrics without touching
 * the host's box model. */
.glass-viewport *,
.glass-viewport *::before,
.glass-viewport *::after {
  box-sizing: border-box;
  margin: 0;
}

/* Local-dev frame so you can see the 600×600 bounds (drop with frame={false}). */
.glass-viewport--frame {
  outline: 1px solid #1c2230;
  border-radius: 16px;
}

.glass-viewport h1 {
  font-size: 56px;
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.05;
}

/* Emitted-light bleed — large luminous text on an additive lens isn't painted,
 * it glows; the real Display's content "mildly bleeds into the empty space
 * around it." A soft, low-alpha halo (never on body/caption — keeps prose
 * crisp). currentColor so white reads white-warm, the accent reads accent. */
.glass-viewport h1,
.glass-viewport .t-title,
.glass-viewport .t-readout {
  text-shadow: 0 0 14px color-mix(in oklab, currentColor 20%, transparent);
}

/* ── Type ramp — 4 emitted tiers (apple-feel §4), scaled up for glance ── */
.glass-viewport .t-title {
  font-size: 56px;
  font-weight: 700;
  line-height: 1.04;
  letter-spacing: -0.015em;
}
.glass-viewport .t-readout {
  font-size: 38px;
  font-weight: 600;
  line-height: 1.1;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}
.glass-viewport .t-body {
  font-size: 24px;
  font-weight: 500;
  line-height: 1.3;
  letter-spacing: 0.002em;
}
.glass-viewport .t-caption {
  font-size: 18px;
  font-weight: 500;
  line-height: 1.3;
  letter-spacing: 0.01em;
}

/* ── Tailwind @utility recipes ────────────────────────────────────
 * The token-driven looks that plain utilities can't express (gradient fills,
 * the elevation shadow, the press/focus transition). Components opt in with a
 * single class instead of a soup of arbitrary values, and the look stays in one
 * auditable place. These resolve through `--gk-*`, so they re-theme for free. */

/* A popping surface: gradient fill + 1px lit edge + soft depth. */
@utility surface {
  background: var(--gk-surface);
  border: 1px solid var(--gk-border);
  box-shadow: var(--gk-elevation);
}

/* The pressable transition + Enter/pinch press-scale (focus engine sets
 * data-gk-press). Honors reduced-motion. */
@utility press-scale {
  transition:
    transform 0.14s cubic-bezier(0.23, 1, 0.32, 1),
    box-shadow 0.2s cubic-bezier(0.23, 1, 0.32, 1),
    border-color 0.2s cubic-bezier(0.23, 1, 0.32, 1);
  &:active,
  &[data-gk-press] {
    transform: scale(0.97);
  }
  @media (prefers-reduced-motion: reduce) {
    transition: none;
    &:active,
    &[data-gk-press] {
      transform: none;
    }
  }
}

/* The filled "on/primary" treatment: accent gradient + edge + glow, brighter
 * on focus. The meaning is "pinch me" — only primary actions wear it. */
@utility btn-primary {
  background: var(--gk-primary-surface);
  border: 1px solid rgba(255, 255, 255, 0.2);
  color: var(--gk-primary-foreground);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.38),
    0 10px 24px -10px var(--gk-accent-glow);
  &:focus,
  &:focus-visible {
    border-color: rgba(255, 255, 255, 0.42);
    box-shadow:
      inset 0 1px 0 rgba(255, 255, 255, 0.42),
      0 0 0 1px color-mix(in oklab, var(--gk-primary) 55%, transparent),
      0 12px 28px -10px var(--gk-accent-glow-strong);
  }
}

/* Semantic filled actions — same depth/edge/press stack as btn-primary, but
 * carrying a fixed meaning: positive = accept/confirm, danger = decline/destroy.
 * Reach for these only on calls and irreversible decisions, never as decoration. */
@utility btn-positive {
  /* Re-point the shared focus ring (it reads var(--gk-accent-active)) to the
   * positive hue, so a focused accept button rings green, not blue. */
  --gk-accent-active: #6fe0a6;
  background: var(--gk-positive-surface);
  border: 1px solid rgba(255, 255, 255, 0.2);
  color: #fff;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.38),
    0 10px 24px -10px var(--gk-positive-glow);
  &:focus,
  &:focus-visible {
    border-color: rgba(255, 255, 255, 0.42);
    box-shadow:
      inset 0 1px 0 rgba(255, 255, 255, 0.42),
      0 0 0 1px color-mix(in oklab, var(--gk-positive) 55%, transparent),
      0 12px 28px -10px var(--gk-positive-glow);
  }
}
@utility btn-danger {
  --gk-accent-active: #ff9a9d;
  background: var(--gk-danger-surface);
  border: 1px solid rgba(255, 255, 255, 0.2);
  color: #fff;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.38),
    0 10px 24px -10px var(--gk-danger-glow);
  &:focus,
  &:focus-visible {
    border-color: rgba(255, 255, 255, 0.42);
    box-shadow:
      inset 0 1px 0 rgba(255, 255, 255, 0.42),
      0 0 0 1px color-mix(in oklab, var(--gk-danger) 55%, transparent),
      0 12px 28px -10px var(--gk-danger-glow);
  }
}

/* ── Recipe utilities — the "premium without blur" stack (§5) ────── */

/* Luminous gradient hairline: a 1.25px stroke that *is* the surface,
 * lit from a fixed top-left virtual light (white corner → green
 * trailing). Rendered as a masked pseudo so the interior stays pure
 * black — no fill. Apply to a rounded element; it inherits the radius. */
.glass-viewport .hairline {
  position: relative;
}
.glass-viewport .hairline::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  padding: 1px;
  background: linear-gradient(
    135deg,
    rgba(255, 255, 255, 0.5) 0%,
    color-mix(in oklab, var(--accent) 28%, transparent) 100%
  );
  -webkit-mask:
    linear-gradient(#000 0 0) content-box,
    linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask:
    linear-gradient(#000 0 0) content-box,
    linear-gradient(#000 0 0);
  mask-composite: exclude;
  pointer-events: none;
}

/* Lift — neutral depth + a soft, low-alpha emitted halo. This is the real
 * waveguide bleed (the Display's content glows into the space around it), NOT
 * the old neon-green ring: large radius, single-digit alpha, accent-tinted. */
.glass-viewport .glow-lift {
  box-shadow:
    0 8px 28px -18px rgba(0, 0, 0, 0.85),
    0 0 26px -6px color-mix(in oklab, var(--accent) 15%, transparent);
}
/* Inner — a faint top-edge emission, like light caught on a rim. */
.glass-viewport .glow-inner {
  box-shadow: inset 0 1px 12px -6px
    color-mix(in oklab, var(--ink-primary) 16%, transparent);
}

/* ── Premium surfaces + gradient icon plates (2026-06 direction) ─────
 * docs/design/meta-hud-language.md. Background stays calm; surfaces + icons
 * pop. */

/* Gradient icon plate — an app-icon squircle: white glyph, inner top highlight,
 * soft colored shadow. The gradient comes from a .gk-grad-* class. */
.glass-viewport .gk-plate {
  display: grid;
  place-items: center;
  border-radius: 28%;
  position: relative;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.32),
    0 9px 22px -10px rgba(0, 0, 0, 0.75);
}
.glass-viewport .gk-plate::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.1);
  pointer-events: none;
}
.glass-viewport .gk-plate .gk-icon {
  color: #fff;
}
.glass-viewport .gk-plate .gk-icon svg {
  stroke-width: 2;
  filter: drop-shadow(0 1px 1px rgba(0, 0, 0, 0.25));
}
.glass-viewport .gk-plate.gk-icon--active .gk-icon,
.glass-viewport .gk-plate .gk-icon--active {
  color: #fff;
  filter: none;
}

/* Tasteful gradient palette (≈150°), cycled per app or picked by tone. */
.glass-viewport .gk-grad-blue {
  background: linear-gradient(150deg, #5b9dff, #2f5fe0);
}
.glass-viewport .gk-grad-green {
  background: linear-gradient(150deg, #3fe0a3, #11a36f);
}
.glass-viewport .gk-grad-peach {
  background: linear-gradient(150deg, #ff7eb3, #ff8a5b);
}
.glass-viewport .gk-grad-violet {
  background: linear-gradient(150deg, #b08bff, #7c3aed);
}
.glass-viewport .gk-grad-cyan {
  background: linear-gradient(150deg, #36d6ee, #0e8fc7);
}
.glass-viewport .gk-grad-amber {
  background: linear-gradient(150deg, #ffd66b, #f5a623);
}

/* ── `.focusable` — joins D-pad navigation; :focus shows the ring ──
 * The RESTING chrome lives in @layer components so a converted component's
 * Tailwind utilities (utilities layer) override it, while the not-yet-converted
 * gk-* components (unlayered) still win. The focus ring + disabled rules stay
 * unlayered so the ring always reads. The class itself is the focus-engine
 * hook (getFocusables selects `.focusable`); keep it on every interactive
 * element regardless of styling. */
@layer components {
  .glass-viewport .focusable {
    cursor: pointer;
    border-radius: 18px;
    border: 1px solid var(--rule);
    background: transparent; /* additive — no gray fills (apple-feel §9) */
    padding-block: 16px;
    padding-inline: 24px;
    color: var(--ink-primary);
    font: inherit;
    font-size: 22px;
    font-weight: 500;
    transition:
      color 0.25s ease,
      border-color 0.3s ease,
      box-shadow 0.3s ease,
      opacity 0.25s ease;
  }
}
.glass-viewport .focusable:focus,
.glass-viewport .focusable:focus-visible {
  outline: none;
  color: #fff;
  border-color: var(--gk-accent-active);
  /* An INSET ring + outer bloom — reads on ANY fill without changing the
   * element's footprint. Inset means no opaque "moat" is carved around the
   * element, so tightly-stacked rows (List, gap:10px) stay flush; the bright
   * accent line still pops on a filled blue primary button. */
  box-shadow:
    inset 0 0 0 2px var(--gk-accent-active),
    0 0 18px -3px color-mix(in oklab, var(--gk-primary) 52%, transparent);
}
.glass-viewport .focusable:disabled,
.glass-viewport .focusable[aria-disabled="true"] {
  cursor: default;
  opacity: 0.45;
}

/* Pressable — a transparent focusable wrapper for custom UI. Strips the generic
 * .focusable chrome (border/padding/fill) so the consumer's content shows; the
 * focus ring still blooms via box-shadow, and Enter / pinch presses scale it.
 * The resting chrome lives in @layer components so a consumer's utility classes
 * (flex, surface, rounded, padding) win — same model as .focusable. */
@layer components {
  .glass-viewport .gk-pressable {
    display: block;
    padding: 0;
    border: 0;
    border-radius: 16px;
    background: transparent;
    color: inherit;
    text-align: start;
    transition:
      transform 0.12s ease,
      box-shadow 0.3s ease,
      opacity 0.25s ease;
  }
}
.glass-viewport .gk-pressable[data-gk-press] {
  transform: scale(0.97);
}

/* ── Legacy semantic classes (kept working, additive-corrected) ──── */

/* Standard centered content layout. */
.glass-viewport .screen {
  display: flex;
  height: 100%;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 22px;
  padding: 52px;
  text-align: center;
}

.glass-viewport .dim {
  max-width: 32ch;
  color: var(--ink-tertiary);
  font-size: 16px;
  line-height: 1.55;
}

.glass-viewport .label {
  text-transform: uppercase;
  color: var(--accent);
  font-size: 12px;
  letter-spacing: 0.18em;
}

.glass-viewport .readout {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-variant-numeric: tabular-nums;
}
.glass-viewport .readout span {
  text-transform: uppercase;
  color: var(--ink-tertiary);
  font-size: 12px; /* label floor — type ramp caps captions at 12–13px */
  letter-spacing: 0.18em;
}
.glass-viewport .readout strong {
  font-size: 40px;
  font-weight: 700;
}

.glass-viewport .row {
  display: flex;
  gap: 12px;
}

.glass-viewport .app-head {
  display: flex;
  width: 100%;
  justify-content: space-between;
  text-transform: uppercase;
  color: var(--ink-tertiary);
  font-size: 12px;
  letter-spacing: 0.16em;
}
.glass-viewport .app-meta {
  display: flex;
  gap: 16px;
  font-variant-numeric: tabular-nums;
  color: var(--ink-tertiary);
  font-size: 13px;
}

/* Launcher — pick-an-app menu (the multi-demo showcase pattern). */
.glass-viewport .launcher {
  display: flex;
  height: 100%;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 12px;
  padding: 36px 28px;
}
.glass-viewport .launcher-title {
  font-size: 36px;
  font-weight: 700;
  letter-spacing: -0.02em;
}
.glass-viewport .launcher-tagline {
  margin-bottom: 12px;
  color: var(--ink-tertiary);
}
.glass-viewport .launcher-grid {
  display: grid;
  width: 100%;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 14px;
}
.glass-viewport .launcher-card {
  display: flex;
  cursor: pointer;
  flex-direction: column;
  align-items: flex-start;
  gap: 6px;
  border-radius: 20px;
  border: 1px solid var(--rule);
  background: transparent;
  padding: 18px 20px;
  text-align: start;
  color: var(--ink-primary);
  font: inherit;
}
.glass-viewport .launcher-card:focus,
.glass-viewport .launcher-card:focus-visible {
  outline: none;
  color: #fff;
  border-color: var(--accent);
  box-shadow:
    0 0 0 1.5px var(--accent),
    0 0 34px -2px color-mix(in oklab, var(--accent) 16%, transparent);
}
.glass-viewport .launcher-card__label {
  font-size: 17px;
  font-weight: 700;
}
.glass-viewport .launcher-card__tagline {
  color: var(--ink-tertiary);
  font-size: 12.5px;
}

/* ── Wave 1 spine components (registry/ui) ──────────────────────────
 * Bespoke semantic classes so the styled components render from this
 * stylesheet alone — no Tailwind content-scan required by consumers.
 * All logical properties (block/inline) for RTL safety.
 * ─────────────────────────────────────────────────────────────── */

/* Button styling moved into the component (Tailwind + tokens): the `surface` /
 * `btn-primary` / `press-scale` @utility recipes (see top of file). */

/* GlowIcon — 2-tier luminance; inert near-white, active green (§7). */
.glass-viewport .gk-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--ink-primary);
  line-height: 0;
}
.glass-viewport .gk-icon--sm {
  inline-size: 16px;
  block-size: 16px;
}
.glass-viewport .gk-icon--md {
  inline-size: 20px;
  block-size: 20px;
}
.glass-viewport .gk-icon--lg {
  inline-size: 28px;
  block-size: 28px;
}
.glass-viewport .gk-icon--active {
  color: var(--accent);
  filter: drop-shadow(
    0 0 5px color-mix(in oklab, var(--accent) 32%, transparent)
  );
}
.glass-viewport .gk-icon svg {
  display: block;
  width: 100%;
  height: 100%;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* ── Wave 2 spine components ─────────────────────────────────────── */

/* List — a full-height stack of focusable rows that scrolls (D-pad
 * scrollIntoView) and fills the stage instead of floating centered. A thin
 * accent rail on the inline-end edge shows scroll progress. */
.glass-viewport .gk-list {
  position: relative;
  inline-size: 100%;
  block-size: 100%;
  align-self: stretch;
}
.glass-viewport .gk-list__scroll {
  display: flex;
  flex-direction: column;
  gap: 10px;
  block-size: 100%;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding-inline-end: 14px;
  /* Hide the native bar; the List component draws its own JS-driven thumb
   * (works in every browser, sized to the content). */
  scrollbar-width: none;
}
.glass-viewport .gk-list__scroll::-webkit-scrollbar {
  display: none;
}
/* Position indicator — a thin rail with a thumb the component sizes + moves via
 * scrollTop. Shown only when the list overflows (data-show). */
.glass-viewport .gk-list__rail {
  position: absolute;
  inset-block: 8px;
  inset-inline-end: 2px;
  inline-size: 4px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.06);
  opacity: 0;
  transition: opacity 0.2s ease;
}
.glass-viewport .gk-list__rail[data-show="true"] {
  opacity: 1;
}
.glass-viewport .gk-list__bar {
  position: absolute;
  inset-inline: 0;
  inset-block-start: 0;
  block-size: 30%;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.34);
  will-change: transform;
}
/* Progress (linear) — a styled native <progress>, so the dynamic fill
 * needs no inline style. Track is faint; fill is emitted green. */
.glass-viewport .gk-progress {
  display: flex;
  flex-direction: column;
  gap: 8px;
  inline-size: 100%;
}
.glass-viewport .gk-progress__el {
  -webkit-appearance: none;
  appearance: none;
  inline-size: 100%;
  block-size: 10px;
  border: none;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.08);
  box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.4);
  overflow: hidden;
}
.glass-viewport .gk-progress__el::-webkit-progress-bar {
  background: transparent;
}
.glass-viewport .gk-progress__el::-webkit-progress-value {
  border-radius: 999px;
  background: linear-gradient(90deg, var(--accent), var(--accent-active));
  box-shadow: 0 0 10px color-mix(in oklab, var(--accent) 50%, transparent);
}
.glass-viewport .gk-progress__el::-moz-progress-bar {
  border-radius: 999px;
  background: linear-gradient(90deg, var(--accent), var(--accent-active));
}
.glass-viewport .gk-progress__meta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  color: var(--ink-tertiary);
  font-variant-numeric: tabular-nums;
}

/* AsyncView — placeholder → loading → success/error. */
.glass-viewport .gk-async {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 12px;
  text-align: center;
}
@keyframes gk-pulse {
  0%,
  100% {
    opacity: 1;
  }
  50% {
    opacity: 0.3;
  }
}
.glass-viewport .gk-spinner {
  display: inline-flex;
  gap: 9px;
}
.glass-viewport .gk-spinner span {
  inline-size: 11px;
  block-size: 11px;
  border-radius: 999px;
  background: var(--accent);
  box-shadow: 0 0 7px color-mix(in oklab, var(--accent) 45%, transparent);
  animation: gk-pulse 1.2s ease-in-out infinite;
}
.glass-viewport .gk-spinner span:nth-child(2) {
  animation-delay: 0.15s;
}
.glass-viewport .gk-spinner span:nth-child(3) {
  animation-delay: 0.3s;
}
@media (prefers-reduced-motion: reduce) {
  .glass-viewport .gk-spinner span {
    animation: none;
  }
}

/* ── Wave 3 spatial / world-anchored components ─────────────────────
 * Rotations use SVG `transform` *attributes* (absolute), so these are
 * never mirrored under RTL — a flipped bearing points the wrong way.
 * ─────────────────────────────────────────────────────────────── */

/* DirectionArrow / Compass — premium instrument discs: a surface "puck" with a
 * top-lit fill, depth, and a faint inner accent ring; a bold glowing indicator
 * on top. */
.glass-viewport .gk-direction,
.glass-viewport .gk-compass {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 18px;
}
.glass-viewport .gk-direction__dial,
.glass-viewport .gk-compass__dial {
  inline-size: 212px;
  block-size: 212px;
  border-radius: 50%;
  background:
    radial-gradient(
      115% 115% at 50% 0%,
      rgba(255, 255, 255, 0.12) 0%,
      rgba(255, 255, 255, 0.02) 52%,
      transparent 100%
    ),
    radial-gradient(100% 100% at 50% 55%, #121a2e 0%, #0a0e18 100%);
  border: 1px solid var(--surface-edge);
  box-shadow:
    var(--surface-lift),
    inset 0 0 36px -12px rgba(0, 0, 0, 0.85);
}
.glass-viewport .gk-direction__ring {
  fill: none;
  stroke: color-mix(in oklab, var(--accent) 26%, transparent);
  stroke-width: 1.5;
}
.glass-viewport .gk-direction__needle {
  fill: var(--accent-active);
  filter: drop-shadow(
    0 0 12px color-mix(in oklab, var(--accent) 65%, transparent)
  );
}
.glass-viewport .gk-direction__label,
.glass-viewport .gk-compass__label {
  color: var(--ink-secondary);
}
.glass-viewport .gk-compass__label {
  font-variant-numeric: tabular-nums;
}

/* Compass — outer rim + a faint inner ring; the bearing marker rides the rim,
 * the cardinals an inner ring (so they never overlap), big center heading. */
.glass-viewport .gk-compass__ring {
  fill: none;
  stroke: rgba(255, 255, 255, 0.1);
  stroke-width: 1.5;
}
.glass-viewport .gk-compass__inner {
  fill: none;
  stroke: rgba(255, 255, 255, 0.05);
  stroke-width: 1;
}
.glass-viewport .gk-compass__marker {
  fill: var(--accent-active);
  filter: drop-shadow(
    0 0 7px color-mix(in oklab, var(--accent) 60%, transparent)
  );
}
.glass-viewport .gk-compass__n,
.glass-viewport .gk-compass__tick {
  text-anchor: middle;
  dominant-baseline: middle;
  font-family: var(--font-sans);
  font-size: 9px;
}
.glass-viewport .gk-compass__n {
  fill: var(--accent-active);
  font-weight: 800;
}
.glass-viewport .gk-compass__tick {
  fill: var(--ink-tertiary);
  font-weight: 600;
}
.glass-viewport .gk-compass__deg {
  text-anchor: middle;
  dominant-baseline: middle;
  fill: #fff;
  font-family: var(--font-sans);
  font-size: 19px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.glass-viewport .gk-compass__card {
  text-anchor: middle;
  dominant-baseline: middle;
  fill: var(--ink-tertiary);
  font-family: var(--font-sans);
  font-size: 8px;
  font-weight: 600;
  letter-spacing: 0.1em;
}

/* ── Wave 4 action / input components ───────────────────────────────
 * Controls (not world-anchored): logical CSS, mirror correctly under RTL.
 * State is class-driven, so the knob/selection need no inline style.
 * ─────────────────────────────────────────────────────────────── */

/* Toggle — a binary switch row; the knob slides to inline-end when on. */
.glass-viewport .gk-toggle {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  inline-size: 100%;
}
.glass-viewport .gk-toggle__label {
  flex: 1 1 auto;
  text-align: start;
}
.glass-viewport .gk-toggle__track {
  display: flex;
  flex: none;
  align-items: center;
  inline-size: 48px;
  block-size: 28px;
  padding: 3px;
  border: 1px solid var(--surface-edge);
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.06);
  box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.4);
  transition:
    background 0.25s cubic-bezier(0.23, 1, 0.32, 1),
    border-color 0.25s cubic-bezier(0.23, 1, 0.32, 1);
}
.glass-viewport .gk-toggle__knob {
  inline-size: 22px;
  block-size: 22px;
  border-radius: 999px;
  background: #fff;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.45);
  transition: margin 0.25s cubic-bezier(0.23, 1, 0.32, 1);
}
.glass-viewport .gk-toggle--on .gk-toggle__track {
  background: var(--accent-surface);
  border-color: rgba(255, 255, 255, 0.28);
}
.glass-viewport .gk-toggle--on .gk-toggle__knob {
  margin-inline-start: auto; /* slide to inline-end — RTL-correct */
  background: #fff;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.5);
}
@media (prefers-reduced-motion: reduce) {
  .glass-viewport .gk-toggle__track,
  .glass-viewport .gk-toggle__knob {
    transition: none;
  }
}

/* ── Wave 5 monitor / feedback components ─────────────────────────── */

/* StatusDot — state from luminance + motion, not a second hue. */
.glass-viewport .gk-statusdot {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}
.glass-viewport .gk-statusdot__dot {
  inline-size: 8px;
  block-size: 8px;
  border-radius: 999px;
  background: var(--accent);
  box-shadow: none;
}
.glass-viewport .gk-statusdot__label {
  color: var(--ink-secondary);
}
.glass-viewport .gk-statusdot--off .gk-statusdot__dot {
  background: var(--ink-tertiary);
  box-shadow: none;
}
@keyframes gk-dot-pulse {
  0%,
  100% {
    opacity: 1;
  }
  50% {
    opacity: 0.25;
  }
}
.glass-viewport .gk-statusdot--live .gk-statusdot__dot {
  animation: gk-dot-pulse 1.8s ease-in-out infinite;
}

@media (prefers-reduced-motion: reduce) {
  .glass-viewport .gk-statusdot--live .gk-statusdot__dot {
    animation: none;
  }
}

/* ── Wave 6 navigation / comms / structure ──────────────────────── */

/* Launcher — a glanceable app grid (phone/watch home-screen spirit): 2 columns
 * of app tiles, each a rounded icon plate + label. No idle card border (clean
 * grid); focus lights the plate, not the whole card. Motion: ease-out, sub-200ms,
 * with a press scale (Emil). */
.glass-viewport .gk-launcher {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 16px;
  inline-size: 100%;
}
.glass-viewport .gk-launcher-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 9px;
  border-color: transparent; /* clean grid — the plate carries structure */
  border-radius: 22px;
  padding-block: 14px;
  padding-inline: 10px;
  text-align: center;
  transition:
    color 0.2s cubic-bezier(0.23, 1, 0.32, 1),
    transform 0.14s cubic-bezier(0.23, 1, 0.32, 1);
}
.glass-viewport .gk-launcher-card:active,
.glass-viewport .gk-launcher-card[data-gk-press] {
  transform: scale(0.97);
}
/* Cancel the generic focus ring on the card — the plate below carries focus. */
.glass-viewport .gk-launcher-card:focus,
.glass-viewport .gk-launcher-card:focus-visible {
  border-color: transparent;
  box-shadow: none;
}
/* The app plate — a gradient squircle (composes .gk-plate .gk-grad-*) holding a
 * white glyph. Size only here; the gradient/shadow live on .gk-plate. */
.glass-viewport .gk-launcher-card__icon {
  inline-size: 94px;
  block-size: 94px;
  margin-block-end: 2px;
  transition:
    transform 0.18s cubic-bezier(0.23, 1, 0.32, 1),
    box-shadow 0.2s cubic-bezier(0.23, 1, 0.32, 1);
}
.glass-viewport .gk-launcher-card__icon .gk-icon {
  inline-size: 46px;
  block-size: 46px;
}
/* Focused tile: the plate lifts and the accent does the highlighting — a soft
 * accent ring hugging the squircle + an accent halo around it (the focus
 * signal everywhere else is accent; the launcher is no exception). The black
 * depth shadow is held back so it never drowns the accent. */
.glass-viewport .gk-launcher-card:focus .gk-launcher-card__icon,
.glass-viewport .gk-launcher-card:focus-visible .gk-launcher-card__icon {
  transform: translateY(-3px) scale(1.04);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.4),
    0 0 0 3px color-mix(in oklab, var(--accent) 70%, transparent),
    0 10px 22px -14px rgba(0, 0, 0, 0.6),
    0 0 30px -2px color-mix(in oklab, var(--accent) 55%, transparent);
}
.glass-viewport .gk-launcher-card:focus .gk-launcher-card__label,
.glass-viewport .gk-launcher-card:focus-visible .gk-launcher-card__label {
  color: #fff;
}
.glass-viewport .gk-launcher-card__label {
  font-weight: 600;
}
.glass-viewport .gk-launcher-card__tagline {
  color: var(--ink-tertiary);
}
@media (prefers-reduced-motion: reduce) {
  .glass-viewport .gk-launcher-card,
  .glass-viewport .gk-launcher-card__icon {
    transition: none;
  }
  .glass-viewport .gk-launcher-card:active,
  .glass-viewport .gk-launcher-card[data-gk-press] {
    transform: none;
  }
}

/* ── Wave 7 world-anchored markers (Pin) ────────────────────────────
 * Full-bleed SVG overlays; markers placed by `transform` attributes, so
 * they're never mirrored under RTL. Non-interactive over the content.
 * ─────────────────────────────────────────────────────────────── */
.glass-viewport .gk-worldlayer {
  position: absolute;
  inset: 0;
  inline-size: 100%;
  block-size: 100%;
  overflow: visible;
  pointer-events: none;
}

/* Pin — bold glowing waypoint marker, name/distance stacked above. Labels get a
 * dark stroke halo (paint-order) so they stay legible over any real-world view. */
.glass-viewport .gk-pin__dot {
  fill: var(--accent-active);
  filter: drop-shadow(
    0 0 9px color-mix(in oklab, var(--accent) 75%, transparent)
  );
}
.glass-viewport .gk-pin__ring {
  fill: none;
  stroke: var(--accent);
  stroke-width: 2.5;
  filter: drop-shadow(
    0 0 9px color-mix(in oklab, var(--accent) 55%, transparent)
  );
}
.glass-viewport .gk-pin__label {
  fill: #fff;
  font-family: var(--font-sans);
  font-size: 23px;
  font-weight: 700;
  text-anchor: middle;
  paint-order: stroke;
  stroke: rgba(0, 0, 0, 0.55);
  stroke-width: 5px;
  stroke-linejoin: round;
}
.glass-viewport .gk-pin__dist {
  fill: var(--ink-secondary);
  font-family: var(--font-sans);
  font-size: 16px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  text-anchor: middle;
  paint-order: stroke;
  stroke: rgba(0, 0, 0, 0.5);
  stroke-width: 4px;
  stroke-linejoin: round;
}

/* ── Wave 8 — app-surface components (comms / media / AI) ──────────── */

/* NowPlaying styling moved into the component (Tailwind + tokens); the scrub
 * bar keeps the shared `.gk-progress__el` primitive (native <progress>
 * pseudo-elements can't be utilities). */

/* AssistantOrb — a glowing gradient orb with per-state motion (Meta-AI presence). */
.glass-viewport .gk-orb {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 22px;
}
.glass-viewport .gk-orb__core {
  inline-size: 120px;
  block-size: 120px;
  border-radius: 50%;
  background: radial-gradient(
    circle at 36% 30%,
    #aecbff 0%,
    #4c8dff 38%,
    #7b5cff 72%,
    #b56bff 100%
  );
  box-shadow:
    inset 0 3px 10px rgba(255, 255, 255, 0.45),
    inset 0 -6px 16px rgba(40, 30, 120, 0.5),
    0 0 60px -6px rgba(123, 92, 255, 0.6);
}
.glass-viewport .gk-orb__label {
  color: var(--ink-secondary);
  text-align: center;
  max-inline-size: 26ch;
}
@keyframes gk-orb-breathe {
  0%,
  100% {
    transform: scale(1);
  }
  50% {
    transform: scale(1.05);
  }
}
@keyframes gk-orb-pulse {
  0%,
  100% {
    transform: scale(1);
    box-shadow:
      inset 0 3px 10px rgba(255, 255, 255, 0.45),
      0 0 60px -6px rgba(123, 92, 255, 0.6);
  }
  50% {
    transform: scale(1.09);
    box-shadow:
      inset 0 3px 10px rgba(255, 255, 255, 0.5),
      0 0 80px -2px rgba(123, 92, 255, 0.8);
  }
}
@keyframes gk-orb-swirl {
  to {
    background-position: 200% 50%;
  }
}
.glass-viewport .gk-orb--idle .gk-orb__core {
  animation: gk-orb-breathe 3.4s ease-in-out infinite;
}
.glass-viewport .gk-orb--listening .gk-orb__core {
  animation: gk-orb-pulse 1.4s ease-in-out infinite;
}
.glass-viewport .gk-orb--speaking .gk-orb__core {
  animation: gk-orb-pulse 0.7s ease-in-out infinite;
}
.glass-viewport .gk-orb--thinking .gk-orb__core {
  background-size: 200% 200%;
  animation: gk-orb-swirl 2.4s linear infinite;
}
@media (prefers-reduced-motion: reduce) {
  .glass-viewport .gk-orb__core {
    animation: none !important;
  }
}

/* ── Toaster (Sonner) ───────────────────────────────────────────────
 * The toast/notification SYSTEM portals to the window edge — OUTSIDE any
 * .glass-viewport — so these rules are intentionally UNSCOPED and use literal
 * values (the surface look without the scoped tokens). The one accent use
 * (the action button) reads the grad-stop tokens with blue fallbacks: when
 * retheming, re-declare `--accent-grad-hi/-lo` on `:root` too so portaled
 * toasts match the lens. Applied via `toastOptions.classNames`. */
.gk-toaster__toast {
  display: flex;
  align-items: center;
  gap: 13px;
  /* Sonner renders in place (no body portal), so a centered ancestor — e.g.
   * a Screen — would center the title. Toast copy always reads from the
   * start edge. */
  text-align: start;
  inline-size: 100%;
  padding: 16px 18px;
  border-radius: 20px;
  background: linear-gradient(180deg, #1b2230 0%, #131a26 100%);
  border: 1px solid rgba(255, 255, 255, 0.12);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.14),
    0 18px 40px -18px rgba(0, 0, 0, 0.9);
  color: #fff;
  font-family:
    ui-sans-serif,
    system-ui,
    -apple-system,
    "Segoe UI",
    sans-serif;
  -webkit-font-smoothing: antialiased;
}
.gk-toaster__icon {
  display: inline-flex;
  flex: none;
}
.gk-toaster__title {
  font-size: 21px;
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: -0.01em;
}
.gk-toaster__desc {
  margin-block-start: 2px;
  font-size: 17px;
  font-weight: 500;
  line-height: 1.3;
  color: #cdd2dd;
}
.gk-toaster__action {
  margin-inline-start: auto;
  flex: none;
  padding: 10px 16px;
  border: 1px solid rgba(255, 255, 255, 0.2);
  border-radius: 14px;
  background: linear-gradient(
    180deg,
    var(--accent-grad-hi, #5b9dff) 0%,
    var(--accent-grad-lo, #3567e6) 100%
  );
  color: #fff;
  font: inherit;
  font-size: 16px;
  font-weight: 600;
  cursor: pointer;
}
.gk-toaster__cancel {
  margin-inline-start: 8px;
  flex: none;
  padding: 10px 16px;
  border: 1px solid rgba(255, 255, 255, 0.16);
  border-radius: 14px;
  background: rgba(255, 255, 255, 0.06);
  color: #cdd2dd;
  font: inherit;
  font-size: 16px;
  font-weight: 600;
  cursor: pointer;
}

/* ── Wave 9 — comms / media app surfaces ──────────────────────────── */

/* CallCard accept/decline buttons (semantic green/red — the one justified
 * two-colour case). The card container/name/status moved to Tailwind. */
.glass-viewport .gk-callbtn {
  display: inline-grid;
  place-items: center;
  inline-size: 76px;
  block-size: 76px;
  padding: 0;
  border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, 0.22);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.34),
    0 10px 22px -10px rgba(0, 0, 0, 0.7);
  color: #fff;
  transition: transform 0.14s cubic-bezier(0.23, 1, 0.32, 1);
}
.glass-viewport .gk-callbtn:active,
.glass-viewport .gk-callbtn[data-gk-press] {
  transform: scale(0.95);
}
.glass-viewport .gk-callbtn .gk-icon {
  inline-size: 32px;
  block-size: 32px;
}
.glass-viewport .gk-callbtn--accept {
  background: linear-gradient(180deg, #3fe0a3 0%, #11a36f 100%);
}
.glass-viewport .gk-callbtn--decline {
  background: linear-gradient(180deg, #ff6b6b 0%, #e03131 100%);
}

/* Dictation waveform animation — the @keyframes is kept as part of the shared
 * motion vocabulary; the Dictation component's resting styles moved to Tailwind. */
@keyframes gk-wave {
  0%,
  100% {
    block-size: 14px;
  }
  50% {
    block-size: 42px;
  }
}

/* MediaThumb — photo / reel tile with optional duration + caption overlays. */
.glass-viewport .gk-mediathumb {
  position: relative;
  overflow: hidden;
  border-radius: 18px;
  border: 1px solid var(--surface-edge);
  box-shadow: var(--surface-lift);
}
.glass-viewport .gk-mediathumb--square {
  inline-size: 168px;
  aspect-ratio: 1;
}
.glass-viewport .gk-mediathumb--portrait {
  inline-size: 150px;
  aspect-ratio: 3 / 4;
}
.glass-viewport .gk-mediathumb__img,
.glass-viewport .gk-mediathumb__ph {
  display: block;
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
}
.glass-viewport .gk-mediathumb__dur {
  position: absolute;
  inset-block-start: 9px;
  inset-inline-end: 9px;
  padding: 4px 9px;
  border-radius: 999px;
  background: rgba(0, 0, 0, 0.55);
  color: #fff;
  font-variant-numeric: tabular-nums;
}
.glass-viewport .gk-mediathumb__label {
  position: absolute;
  inset-block-end: 9px;
  inset-inline-start: 11px;
  color: #fff;
  font-weight: 600;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.6);
}

/* A focusable MediaThumb (gallery tile): cancel the generic .focusable padding
 * so the image still fills the tile, keep the tile's own edge, and let focus
 * brighten it with the accent ring. */
.glass-viewport .gk-mediathumb.focusable {
  display: block;
  padding: 0;
  border: 1px solid var(--surface-edge);
  background: transparent;
  transition:
    transform 0.12s ease,
    box-shadow 0.3s ease,
    border-color 0.3s ease;
}
.glass-viewport .gk-mediathumb.focusable:focus,
.glass-viewport .gk-mediathumb.focusable:focus-visible {
  outline: none;
  border-color: var(--accent);
  box-shadow:
    0 0 0 2px color-mix(in oklab, var(--accent) 70%, transparent),
    0 0 22px -4px color-mix(in oklab, var(--accent) 42%, transparent);
}
.glass-viewport .gk-mediathumb.focusable[data-gk-press] {
  transform: scale(0.96);
}

/* Masonry — a staggered multi-column layout (Pinterest-style) that scrolls
 * vertically. Real column stacks sit side by side; because items vary in height
 * the columns never line up. The D-pad moves a focused item into view; the
 * native scrollbar is hidden. */
.glass-viewport .gk-masonry {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  inline-size: 100%;
  block-size: 100%;
  align-self: stretch;
  overflow-y: auto;
  overflow-x: hidden;
  padding-block: 2px;
  scrollbar-width: none;
}
.glass-viewport .gk-masonry::-webkit-scrollbar {
  display: none;
}
.glass-viewport .gk-masonry__col {
  display: flex;
  flex: 1 1 0;
  min-inline-size: 0;
  flex-direction: column;
  gap: 12px;
}
.glass-viewport .gk-masonry__item {
  inline-size: 100%;
}
.glass-viewport .gk-masonry .gk-mediathumb {
  inline-size: 100%;
}

/* Grid — an aligned, uniform multi-column layout (every cell the same track),
 * scrolling vertically. The aligned counterpart to Masonry. Column count rides
 * on data-cols so the lens needs no inline style. */
.glass-viewport .gk-grid {
  display: grid;
  gap: 12px;
  inline-size: 100%;
  block-size: 100%;
  align-self: stretch;
  align-content: start;
  overflow-y: auto;
  overflow-x: hidden;
  padding-block: 2px;
  scrollbar-width: none;
}
.glass-viewport .gk-grid::-webkit-scrollbar {
  display: none;
}
.glass-viewport .gk-grid[data-cols="2"] {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
.glass-viewport .gk-grid[data-cols="3"] {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}
.glass-viewport .gk-grid[data-cols="4"] {
  grid-template-columns: repeat(4, minmax(0, 1fr));
}
.glass-viewport .gk-grid .gk-mediathumb {
  inline-size: 100%;
}

/* ── Wave 10 — capture / shell ────────────────────────────────────── */

/* Tabs — top-level tab strip. Two distinct affordances, neither fighting the
 * other: SELECTED is a short rounded accent indicator centered under the
 * label (no full-width border, so nothing curves around the corners); FOCUSED
 * is the system ring/bloom (where the D-pad is). */
/* Selected: brighter label + a short rounded accent bar under it. The Tabs
 * container + base tab styling moved to Tailwind; only the selected-pill
 * ::after pseudo (which utilities can't express) stays. */
.glass-viewport .gk-tab--on {
  color: #fff;
}
.glass-viewport .gk-tab--on::after {
  content: "";
  position: absolute;
  inset-block-end: 5px;
  inset-inline-start: 50%;
  transform: translateX(-50%);
  inline-size: 38%;
  block-size: 3px;
  border-radius: 999px;
  background: var(--accent);
  box-shadow: 0 0 8px -1px color-mix(in oklab, var(--accent) 60%, transparent);
}

/* ── Wave 11 — shell / input / system ─────────────────────────────── */

/* Slider — native range tinted with accent-color (fill + thumb, no inline
 * style); arrow keys / pinch-twist adjust. */
.glass-viewport .gk-slider {
  display: flex;
  align-items: center;
  gap: 16px;
  inline-size: 100%;
}
.glass-viewport .gk-slider__icon .gk-icon {
  inline-size: 30px;
  block-size: 30px;
  color: var(--ink-secondary);
}
.glass-viewport .gk-slider__input {
  flex: 1 1 auto;
  inline-size: 100%;
  block-size: 16px;
  padding: 0;
  border: none;
  border-radius: 999px;
  background: transparent;
  box-shadow: none;
  cursor: pointer;
  accent-color: var(--accent);
}
.glass-viewport .gk-slider__input:focus,
.glass-viewport .gk-slider__input:focus-visible {
  outline: none;
  border-radius: 999px;
  box-shadow: 0 0 0 3px color-mix(in oklab, var(--accent) 32%, transparent);
}
.glass-viewport .gk-slider__label {
  flex: none;
  color: var(--ink-tertiary);
}

/* Navigator — screen stack. The incoming screen rises in with a short
 * luminance + slide entrance (sub-200ms, spec easing); back pops render
 * instantly so leaving never lags the gesture. */
.glass-viewport .gk-nav {
  display: contents;
}
.glass-viewport .gk-nav > * {
  animation: gk-nav-enter 0.18s cubic-bezier(0.23, 1, 0.32, 1);
}
@keyframes gk-nav-enter {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}
@media (prefers-reduced-motion: reduce) {
  .glass-viewport .gk-nav > * {
    animation: none;
  }
}

/* ── Wave 12 — quality pass ───────────────────────────────────────── */

/* MapView — a real Leaflet map filling the lens, dark tiles, chrome trimmed
 * to a tiny attribution (no zoom buttons — there's no touch). */
.glass-viewport .gk-mapview {
  position: absolute;
  inset: 0;
  inline-size: 100%;
  block-size: 100%;
  background: #0a0d14;
  z-index: 0;
}
.glass-viewport .gk-mapview.leaflet-container {
  font-family: inherit;
}
.glass-viewport .gk-mapview .leaflet-control-attribution {
  padding: 1px 6px;
  border-radius: 6px 0 0 0;
  background: rgba(0, 0, 0, 0.45);
  font-size: 9px;
  color: rgba(255, 255, 255, 0.45);
}
.glass-viewport .gk-mapview .leaflet-control-attribution a {
  color: rgba(255, 255, 255, 0.6);
}
/* Photo place markers (restaurants/stops): a circular image + a name chip
 * floating above, a little tail pointing at the location. */
.glass-viewport .gk-mapview__pinwrap {
  background: transparent;
  border: 0;
}
/* The pin is a focusable button — strip the generic .focusable chrome; the
 * accent focus/selected state rings the photo instead (cf. Launcher). */
.glass-viewport .gk-mapview__pin.focusable {
  position: relative;
  display: block;
  inline-size: 46px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: transparent;
}
.glass-viewport .gk-mapview__pin.focusable:focus,
.glass-viewport .gk-mapview__pin.focusable:focus-visible {
  border: 0;
  box-shadow: none;
}
.glass-viewport .gk-mapview__pin-photo {
  display: block;
  inline-size: 46px;
  block-size: 46px;
  border-radius: 50%;
  background-size: cover;
  background-position: center;
  border: 2px solid #fff;
  box-shadow: 0 3px 9px rgba(0, 0, 0, 0.55);
  transition:
    transform 0.15s cubic-bezier(0.23, 1, 0.32, 1),
    box-shadow 0.2s ease,
    border-color 0.2s ease;
}
.glass-viewport .gk-mapview__pin:focus .gk-mapview__pin-photo,
.glass-viewport .gk-mapview__pin:focus-visible .gk-mapview__pin-photo {
  border-color: var(--accent);
  transform: scale(1.1);
  box-shadow:
    0 0 0 3px color-mix(in oklab, var(--accent) 55%, transparent),
    0 4px 12px rgba(0, 0, 0, 0.6);
}
.glass-viewport .gk-mapview__pin.is-selected .gk-mapview__pin-photo {
  border-color: var(--accent);
  box-shadow:
    0 0 0 3px var(--accent),
    0 0 22px -2px color-mix(in oklab, var(--accent) 60%, transparent);
}
.glass-viewport .gk-mapview__pin[data-gk-press] .gk-mapview__pin-photo {
  transform: scale(0.94);
}
.glass-viewport .gk-mapview__pin-photo::after {
  content: "";
  position: absolute;
  bottom: -6px;
  left: 50%;
  transform: translateX(-50%);
  border-left: 5px solid transparent;
  border-right: 5px solid transparent;
  border-top: 7px solid #fff;
}
.glass-viewport .gk-mapview__pin-name {
  position: absolute;
  bottom: calc(100% + 5px);
  left: 50%;
  transform: translateX(-50%);
  white-space: nowrap;
  background: rgba(10, 13, 20, 0.92);
  color: #fff;
  font-size: 12px;
  font-weight: 600;
  padding: 3px 9px;
  border-radius: 9px;
  border: 1px solid rgba(255, 255, 255, 0.16);
}
.glass-viewport .gk-mapview__pin-rating {
  margin-inline-start: 6px;
  color: var(--accent-active);
  font-variant-numeric: tabular-nums;
}

/* Timer — countdown readout: big tabular time + a bar draining to zero. */
.glass-viewport .gk-timer {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  text-align: center;
}
.glass-viewport .gk-timer__time {
  font-size: 72px;
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
  text-shadow: 0 0 18px rgba(255, 255, 255, 0.18);
}
.glass-viewport .gk-timer__label {
  color: var(--ink-tertiary);
  text-transform: uppercase;
  letter-spacing: 0.1em;
}
.glass-viewport .gk-timer__bar {
  inline-size: 220px;
}
