/* ───────────────────────────────────────────────
   Vamos Design System - "Concierge Index"
   A light instrument panel floating over a map, with
   one warm accent and a technical-label voice.

   Sources: three references, distilled on /references, 
   R-01 tool-ui (floating chrome, segmented controls,
   readouts) · R-02 showcase-grid (tile grid, color from
   content) · R-03 recent (diffuse lift, quiet metadata).
   The distillation block below is where they land.

   One accent = now / committed / active. The accent is graphite
   (#141414), set by the Gleap block at the foot of this file, and it
   is deliberately NOT a brand hue. Do not "restore" terracotta here:
   the --primary ramp is neutral on purpose and the Gleap :root wins.
   THIS FILE IS THE TRUTH. ../DESIGN-SYSTEM.md is the prose
   and /design-system renders it live by loading this file.
   If either disagrees with this file, they are the bug.
   ─────────────────────────────────────────────── */

/* ═══════════════════════════════════════════════
   PRIMITIVE SCALE - Untitled UI conventions.
   Raw values. Never referenced directly by the app;
   the semantic aliases below point at these. This is
   the canonical scale documented on the worldsite.
   ═══════════════════════════════════════════════ */
:root{
  /* ── Neutral gray: TRUE neutral, chroma 0.
     Was the stock Untitled UI ramp, which is navy: every step measured
     hue 216-240° at 13-43% saturation, so --ink (#181818) was 43%-saturated
     navy and all "black" text in the app was actually blue. The refs are
     achromatic, and the distillation had already caught this for --page
     ("the prior #f5f6f8 carried a blue cast") without fixing the ramp under it.
     Rebuilt by preserving each step's OKLCH lightness and driving chroma to 0,
     so every contrast relationship survives. Note --gray-100 lands on #f4f4f4:
     r01's own Backgrounds field. The ramp was always trying to be this. ── */
  /* The ramp IS the Gleap palette: its named colors were always a scale:
     linen -> stone -> quartz -> pebble -> ash -> slate -> iron -> charcoal ->
     graphite. Chroma is warm (hue 60) at the paper end and falls to 0 at the
     ink end, which is exactly Gleap's rule: warm the surface, keep the ink
     neutral. Every semantic alias below inherits this, so the system is
     Gleap-native rather than Gleap painted on top. */
  /* Rebuilt as an actual ramp. The previous version mapped Gleap's NAMED ROLES
     (linen/stone/quartz/pebble/ash/slate/iron/charcoal/graphite) onto steps
     25-900 on the theory that the palette "was already a scale". It was not:
     they are discrete roles, and forcing them into slots produced lightness
     steps ranging +1.8 to +19.9 (an 11x variance) and a warmth cliff: warm
     through 300, DEAD neutral at 400, faintly warm at 500-600, neutral after.
     The ramp stuttered twice, which is what "not tonally cohesive" looks like.
     Now: one hue (107°, linen's own), lightness stepping evenly (1.7 fine at
     the paper end where values need separating, ~10 through mid and ink), and
     chroma on a single taper to 0: warm paper, neutral ink, no cliff.
     Anchors held exactly: 100 = linen (the canvas), 900 = graphite (the accent). */
  --gray-25:#f8f9f6; --gray-50:#f3f3ef; --gray-100:#edede8; --gray-200:#dbdbd4;
  --gray-300:#cbcbc4; --gray-400:#a6a6a0; --gray-500:#888883; --gray-600:#6a6a67;
  --gray-700:#4e4e4d; --gray-800:#2f2f2e; --gray-900:#141414;

  /* ── Primary: RETIRED.
     Was terracotta #f5501e, then a hand-built ink ramp. Both were wrong for
     different reasons. The terracotta was the stock Untitled UI signature; the
     ink ramp measured step gaps of 2.4 to 23.5 with five values crammed into
     the last 12% of lightness, because near-black is the END of a scale, not
     its middle. A "primary ramp" only coheres when the brand is a hue.
     Ours is ink, so --gray-* IS the primary ramp and --accent is --gray-900.
     Two neutral ramps was the incoherence itself.
     To introduce a brand hue: add the ramp back here and repoint --accent. ── */

  /* ── Semantic state ── */
  --success-50:#ecfdf3; --success-100:#d1fadf; --success-500:#17b26a; --success-600:#079455; --success-700:#067647;
  --error-50:#fef3f2; --error-500:#f04438; --error-600:#d92d20; --error-700:#b42318;
  --warning-50:#fffaeb; --warning-500:#f79009; --warning-600:#dc6803; --warning-700:#b54708;
  --blue-50:#eff8ff; --blue-500:#2e90fa; --blue-600:#1570ef; --blue-700:#175cd3;

  /* ── Spacing (Untitled UI rem steps) ── */
  --space-0:0; --space-1:2px; --space-2:4px; --space-3:6px; --space-4:8px;
  --space-5:12px; --space-6:16px; --space-7:20px; --space-8:24px;
  --space-10:32px; --space-12:40px; --space-14:48px; --space-16:64px;

  /* ── Radius ── */
  --radius-xs:4px; --radius-sm:6px; --radius-md:8px; --radius-lg:10px;
  --radius-xl:12px; --radius-2xl:16px; --radius-full:9999px;
  /* pill/chip corner: squircle (superellipse-ish), NOT fully-round ends */
  --r-pill:13px;

  /* ── Shadow / elevation - flat by default; only true overlays get a soft diffuse lift ── */
  --shadow-xs:none;
  --shadow-sm:none;
  --shadow-md:0 6px 18px -8px rgba(24,24,24,.06);
  --shadow-lg:0 12px 32px -14px rgba(24,24,24,.09);
  --shadow-xl:0 22px 50px -20px rgba(24,24,24,.11);

  /* ── Elevation ladder: depth as hierarchy, not per-element shadow soup.
     --elev-edge is the lit top lip that gives glass surfaces dimensionality;
     pair it with a tier. base=map · 1=resting chips · 2=sheet · 3=floating omnibar ── */
  --elev-edge:inset 0 1px 0 rgba(255,255,255,.7);
  --elev-1:0 1px 2px -1px rgba(24,24,24,.12),0 2px 6px -2px rgba(24,24,24,.08);
  --elev-2:0 3px 8px -4px rgba(24,24,24,.12),0 10px 24px -8px rgba(24,24,24,.12);
  --elev-3:0 6px 14px -6px rgba(24,24,24,.16),0 18px 40px -12px rgba(24,24,24,.22);

  /* The Untitled UI type ramp (display/lh/tracking/text-sm..xl) was imported
     wholesale and never adopted — Vamos sets type in literal px at each use.
     Only --text-xs is consumed. The dead scales were removed. */
  --text-xs:12px;
  /* Font weights */
  --fw-regular:400; --fw-medium:500; --fw-semibold:600; --fw-bold:700;

  /* ═══ ADDED - extended spacing (4px base; complements --space-0..16) ═══ */
  --space-9:28px; --space-20:80px; --space-24:96px;
  /* gutter (container-* scale was imported unused and removed) */
  --gutter:24px;
}

/* ═══════════════════════════════════════════════
   SEMANTIC ALIASES - the names the app consumes.
   Every one references a primitive above. Do not
   rename; the app's CSS/JS binds to these exactly.
   ═══════════════════════════════════════════════ */
:root{
  /* surfaces & chrome */
  --wall:#c9d2c6; --page:#f4f4f4; --panel:#ffffff; --panel-2:#f4f4f4;
  --sage:#66a63a; --sage-soft:#eef6e2; --sage-plate:#c3d38a;
  --sidebar:var(--gray-100); --sidebar-2:var(--gray-200); --raise:var(--gray-100);
  /* text */
  --ink:var(--gray-900); --ink-2:var(--gray-600); --ink-3:var(--gray-400); --ink-4:rgba(24,24,24,.16);
  /* borders & hairlines */
  --border:var(--gray-200); --border-2:var(--gray-300); --hover:rgba(24,24,24,.04);
  --line-dashed:rgba(24,24,24,.12); --line-dotted:rgba(24,24,24,.16);
  /* chip + elevation. Was var(--shadow-sm), which resolves to `none`: so all 11
     raised chips (active dock item, active filter chip, segmented thumb) rendered
     FLAT in light while dark overrode to a real shadow. A raised thumb is exactly
     what --elev-1 is for, and it matches .ds-seg's [aria-selected] rule below. */
  --chip:rgba(255,255,255,.72); --chip-sh:inset 0 1px 0 rgba(255,255,255,.6),0 1px 3px -1px rgba(24,24,24,.10);
  /* success / live */
  --live:var(--success-500); --live-soft:var(--success-50);
  /* accent = ink. now / committed / primary action.
     --accent-soft is an ink WASH, not a fixed tint: it sits on both --panel
     (#fff) and --page (#f4f4f4), and a neutral hex legible on one is invisible
     on the other (the old light-terracotta fill was carried by hue, which
     achromatic chrome no longer has). Transparency adapts to its ground, 
     the same move the dark theme already makes. */
  --accent:var(--primary-500); --accent-soft:rgba(31,31,31,.07); --accent-ink:#fff;
  /* type - fonts are brand identity: do not touch these stacks or the @font-face rules. */
  --sans:"Tekio Grotesk","ABC Diatype","Helvetica Neue",Helvetica,Arial,sans-serif;
  --mono:"ABC Favorit Mono","Fragment Mono",ui-monospace,"SF Mono",Menlo,Consolas,monospace;
  --serif:"Society","Softcore","Newsreader",Georgia,"Times New Roman",serif;
  /* radius aliases. --r-panel now lives in the RADIUS LADDER below (16px);
     it was 0px here, which is why the shell used to read square. */
  --r:var(--radius-md); --r-lg:14px;
  /* button system - one size + type for all pill/ghost buttons */
  --btn-h:38px; --btn-px:16px; --btn-r:var(--radius-lg); --btn-fz:13px; --btn-fw:600;
  /* Avatar / collaborator palette: high-saturation identity hues.
     Fill with color-mix(in srgb, <token> var(--av-tint), #fff); text uses the token direct. */
  --av-orange:#e07a1e; --av-green:#6fbf1f; --av-pink:#cc2e7d;
  --av-indigo:#4d4de6; --av-teal:#12a89a;
  --av-tint:18%; /* fill = color-mix(in srgb, <hue> var(--av-tint), #fff); text = the hue direct */
  /* Category palette: the single source of truth for map pins, filter chips AND itinerary badges.
     One hue per travel category, high-saturation (used only as a small glyph accent). */
  --cat-lodging:#1f5cff; --cat-activities:#ff1493; --cat-food:#ff8c00;
  --cat-travel:#7a5af8; --cat-guide:#707070;
  /* Z-index layer scale: one ladder, semantic rungs. Never hardcode a z-index;
     pick the rung. map < chrome < panel < overlay < sheet < popover < toast.
     Local component stacking (a badge over a thumbnail) uses 0/1/2 and is exempt. */
  --z-map:1; --z-chrome:100; --z-panel:150; --z-overlay:200;
  --z-sheet:300; --z-popover:400; --z-toast:500;
  --wrap:1180px;
  font-synthesis:none; /* real weights only: NHG has them; Softcore ships Thin only */
}

/* ═══════════════════════════════════════════════
   ADDED - Untitled UI COMPONENT layer (light).
   Semantic surface/text/border/fg + button + focus
   tokens mapped onto the primitive ramps above.
   Additive: the app need not consume these yet.
   Dark equivalents live in [data-theme="dark"].
   ═══════════════════════════════════════════════ */
:root{
  /* Surfaces */
  --bg-primary:var(--panel); --bg-secondary:var(--gray-50); --bg-tertiary:var(--gray-100);
  --bg-active:var(--gray-100); --bg-disabled:var(--gray-100);
  /* Text */
  --text-primary:var(--gray-800); --text-secondary:var(--gray-600); --text-tertiary:var(--gray-500);
  --text-placeholder:var(--gray-400); --text-disabled:var(--gray-400);
  --text-brand:var(--primary-600); --text-white:#ffffff;
  /* Borders */
  --border-primary:var(--gray-300); --border-secondary:var(--gray-200);
  --border-disabled:var(--gray-200); --border-brand:var(--primary-500);
  /* Foreground / icon */
  --fg-primary:var(--gray-900); --fg-secondary:var(--gray-600); --fg-tertiary:var(--gray-500);
  --fg-quaternary:var(--gray-400); --fg-brand:var(--primary-600); --fg-white:#ffffff;
  /* Buttons - primary (terracotta), secondary (outlined), tertiary (ghost) */
  --button-primary-bg:var(--primary-500); --button-primary-hover:var(--primary-600); --button-primary-text:#ffffff;
  --button-secondary-bg:var(--panel); --button-secondary-hover:var(--gray-50);
  --button-secondary-border:var(--gray-300); --button-secondary-text:var(--gray-700);
  --button-tertiary-bg:transparent; --button-tertiary-hover:var(--gray-50); --button-tertiary-text:var(--gray-600);
  /* Focus ring (Untitled UI: 4px primary alpha) */
  --focus-ring:0 0 0 4px rgba(31,31,31,.20);
}

:root[data-theme="dark"]{
  /* Surfaces - cocoa ramp */
  --bg-primary:var(--panel); --bg-secondary:var(--panel-2); --bg-tertiary:var(--raise);
  --bg-active:var(--raise); --bg-disabled:#1a1611;
  /* Text */
  --text-primary:var(--ink); --text-secondary:var(--ink-2); --text-tertiary:var(--ink-3);
  --text-placeholder:var(--ink-3); --text-disabled:var(--ink-3);
  --text-brand:var(--accent); --text-white:#ffffff;
  /* Borders */
  --border-primary:var(--border-2); --border-secondary:var(--border);
  --border-disabled:var(--border); --border-brand:var(--accent);
  /* Foreground / icon */
  --fg-primary:var(--ink); --fg-secondary:var(--ink-2); --fg-tertiary:var(--ink-3);
  --fg-quaternary:var(--ink-3); --fg-brand:var(--accent); --fg-white:#ffffff;
  /* Buttons - warm stone accent on cocoa */
  --button-primary-bg:var(--accent); --button-primary-hover:#f0e8da; --button-primary-text:var(--accent-ink);
  --button-secondary-bg:var(--panel); --button-secondary-hover:var(--raise);
  --button-secondary-border:var(--border-2); --button-secondary-text:var(--ink-2);
  --button-tertiary-bg:transparent; --button-tertiary-hover:var(--raise); --button-tertiary-text:var(--ink-2);
  /* Focus ring - warm stone alpha */
  --focus-ring:0 0 0 4px rgba(230,220,203,.28);
}

:root[data-theme="dark"]{
  /* warm cocoa dark - a parallel semantic mapping. Chrome tokens overridden so
     nothing orphans to the light gray ramp; primitives stay available for docs. */
  --page:#17130f; --panel:#211c17; --panel-2:#1a1611; --raise:#2a241d;
  --sidebar:#1c1712; --sidebar-2:#171310; --wall:#0f0c08;
  --ink:#f3ece1; --ink-2:#a89e90; --ink-3:#6f665b; --ink-4:rgba(243,236,225,.2);
  --border:rgba(243,236,225,.11); --border-2:rgba(243,236,225,.18); --hover:rgba(243,236,225,.05);
  --line-dashed:rgba(243,236,225,.2); --line-dotted:rgba(243,236,225,.24);
  --chip:#2a241d; --chip-sh:0 1px 2px rgba(0,0,0,.3);
  /* dark elevation: near-invisible lit edge, deeper contact shadows */
  --elev-edge:inset 0 1px 0 rgba(255,255,255,.08);
  --elev-1:0 1px 2px -1px rgba(0,0,0,.5),0 2px 6px -2px rgba(0,0,0,.4);
  --elev-2:0 3px 8px -4px rgba(0,0,0,.5),0 10px 24px -8px rgba(0,0,0,.45);
  --elev-3:0 6px 14px -6px rgba(0,0,0,.55),0 18px 40px -12px rgba(0,0,0,.6);
  --glass-bg:rgba(18,18,20,.60); --glass-bg-strong:rgba(18,18,20,.80);
  --glass-brd:rgba(255,255,255,.14);
  --glass-edge:inset 0 1px 0 rgba(255,255,255,.08); --glass-shadow:var(--elev-3);
  --live:#5fd987; --live-soft:rgba(95,217,135,.14);
  /* dark theme: warm stone accent so primary/committed stays visible on cocoa */
  --accent:#e6dccb; --accent-soft:rgba(230,220,203,.12); --accent-ink:#221d18;
}

/* ── ABC Favorit Mono - the technical-label voice. Always all-caps; carries
   every machine-known fact (clocks, date ranges, counts). Wired to --mono. ── */
@font-face{font-family:"ABC Favorit Mono";src:url("/fonts/favorit-mono-regular.otf") format("opentype");font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:"ABC Favorit Mono";src:url("/fonts/favorit-mono-medium.otf") format("opentype");font-weight:500;font-style:normal;font-display:swap}
/* Regular + Medium supplied; keep body dead quiet: 600 and 700 synthesize where the UI asks for bold */

/* ── ABC Diatype (main body sans - light) ── */
@font-face{font-family:"ABC Diatype";src:url("/fonts/abc-diatype-light.ttf") format("truetype");font-weight:300;font-style:normal;font-display:swap}
@font-face{font-family:"ABC Diatype";src:url("/fonts/abc-diatype-regular.otf") format("opentype");font-weight:400;font-style:normal;font-display:swap}


/* ── Society (serif · the user's own content). Replaces Softcore: still three
   faces, three jobs, no fourth. Regular + Italic at 400, which is what every serif element actually asks
   for (.tt and .sh-peektitle are font-weight:400). Light was being matched to
   those requests by proximity. font-synthesis:none still means no faked bold:
   ask for 600 and you get Regular. Correct here; headlines whisper. ── */
@font-face{font-family:"Society";src:url("/fonts/society-regular.otf") format("opentype");font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:"Society";src:url("/fonts/society-italic.otf") format("opentype");font-weight:400;font-style:italic;font-display:swap}

/* ── Softcore (previous serif · kept in /fonts, unwired) ── */
@font-face{font-family:"Softcore";src:url("/fonts/softcore-thin.otf") format("opentype");font-weight:100;font-style:normal;font-display:swap}
@font-face{font-family:"Softcore";src:url("/fonts/softcore-thin-italic.otf") format("opentype");font-weight:100;font-style:italic;font-display:swap}
@font-face{font-family:"Softcore";src:url("/fonts/softcore-light.otf") format("opentype");font-weight:300;font-style:normal;font-display:swap}
@font-face{font-family:"Softcore";src:url("/fonts/softcore-regular.otf") format("opentype");font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:"Softcore";src:url("/fonts/softcore-light-italic.otf") format("opentype");font-weight:300;font-style:italic;font-display:swap}

/* ── Tekio Grotesk (product body) ──
   The split: Tekio is the PRODUCT voice, Neue Haas is EDITORIAL/BRAND. This is
   the app, so it speaks Tekio. The worldsite (design system, references) speaks
   Neue Haas and does not load this face. That means this file and its worldsite
   twin now differ by more than the viewport tail, on purpose. See DESIGN-SYSTEM
   §9: the font block and the viewport rule are the two sanctioned differences.
   Tekio ships three weights, 400/500/600, which is exactly the ramp this file
   declares minus --fw-bold. Nothing here asks for 700 or for an italic, and
   font-synthesis is none, so do not reach for either: there is no face to serve
   it and it will silently fall back. */
@font-face{font-family:"Tekio Grotesk";src:url("/fonts/tekio-regular.woff") format("woff");font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:"Tekio Grotesk";src:url("/fonts/tekio-medium.woff") format("woff");font-weight:500;font-style:normal;font-display:swap}
@font-face{font-family:"Tekio Grotesk";src:url("/fonts/tekio-semibold.woff") format("woff");font-weight:600;font-style:normal;font-display:swap}

/* ── Society (serif · the user's own content). Replaces Softcore: still three
   faces, three jobs, no fourth. Regular + Italic at 400, which is what every serif element actually asks
   for (.tt and .sh-peektitle are font-weight:400). Light was being matched to
   those requests by proximity. font-synthesis:none still means no faked bold:
   ask for 600 and you get Regular. Correct here; headlines whisper. ── */
@font-face{font-family:"Society";src:url("/fonts/society-regular.otf") format("opentype");font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:"Society";src:url("/fonts/society-italic.otf") format("opentype");font-weight:400;font-style:italic;font-display:swap}

/* ── Softcore (previous serif · kept in /fonts, unwired) ── */
@font-face{font-family:"Softcore";src:url("/fonts/softcore-thin.otf") format("opentype");font-weight:100;font-style:normal;font-display:swap}
@font-face{font-family:"Softcore";src:url("/fonts/softcore-thin-italic.otf") format("opentype");font-weight:100;font-style:italic;font-display:swap}
@font-face{font-family:"Softcore";src:url("/fonts/softcore-light.otf") format("opentype");font-weight:300;font-style:normal;font-display:swap}
@font-face{font-family:"Softcore";src:url("/fonts/softcore-regular.otf") format("opentype");font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:"Softcore";src:url("/fonts/softcore-light-italic.otf") format("opentype");font-weight:300;font-style:italic;font-display:swap}

/* ── Neue Haas Grotesk (body) ── */

/* ═══════════════════════════════════════════════
   REFERENCE DISTILLATION: "soft light workshop"
   Source: /references · r01 tool-ui · r02 showcase-grid · r03 recent-index.
   Three refs, one register. What they agree on:
     1. Near-white ground, white cards floating on it. Light only.
     2. Generous soft radius. Nothing structural is square.
     3. Chrome is achromatic. Every color comes from content.
     4. Elevation is a diffuse lift, never a hard edge or a hairline.
     5. The tile grid is the layout. Content centered, given air.
     6. Metadata is quiet: small, muted, factual.
   These override the aliases above. Dark theme re-overrides below.
   ═══════════════════════════════════════════════ */
:root{
  /* ground. #f4f4f4 is verbatim from r01's own Backgrounds field. The prior
     #f5f6f8 carried a blue cast; the refs are a true neutral. */
  --page:#f4f4f4;
  /* tile ground - r02's showcase cells and r01's material swatches */
  --tile:#f1f1f0;
  /* RADIUS LADDER - one rung per role, never an arbitrary px.
     The app had eight values (8·9·10·11·12·14·16·18) doing three jobs.
     Rungs stay concentric: a child is always rounder-inward than its parent,
     panel(16) > tile(12) > ctl(8), so nested corners never collide.
       ctl   - controls inside chrome: icon buttons, checkboxes, small inputs
       tile  - content: cards, list rows, notes, the askbar
       panel - floating surfaces: docks, menus, popovers, hovercards
       sheet - large overlays; top corners only
     Avatars keep 30% (identity squircle) and dots keep 50%. Those are not radii,
     they are shapes. --r-pill:13px is the chip and is unchanged. */
  --r-ctl:8px; --r-tile:12px; --r-panel:16px; --r-sheet:20px;
  --r-card:var(--r-panel);
  /* diffuse lift - r01/r03 cards float, they do not cut */
  --elev-soft:0 1px 2px rgba(24,24,24,.04),0 8px 24px -12px rgba(24,24,24,.10);
  /* segmented control - r01: Isometric/Perspective, Design/Animation */
  --seg-track:#ececed; --seg-thumb:#ffffff;
}

/* ═══════════════════════════════════════════════
   GLEAP: warm-paper product language.
   Applied over the r01/r02/r03 distillation above. Where they disagree,
   this wins; the disagreements are called out so they stay visible:

   · SURFACE gets warm, INK stays neutral. Gleap's warmth is only in the
     paper (linen/stone/quartz sit at hue 60, 8-12% sat); every ink is
     chroma 0. So this keeps the achromatic chrome and warms the ground.
   · DEPTH IS TONE, NOT SHADOW. This is the real unlock. A white card on
     the old #f4f4f4 was 1.10:1: invisible, which is exactly why it needed
     a shadow. On linen it is 1.175:1 and reads unaided. ds-vamos already
     said "flat by default; only true overlays get a soft diffuse lift", 
     Gleap agrees; the --elev-soft-on-every-card pass did not. Reverted.
   · PILLS ARE SQUIRCLES (13px), NOT CAPSULES. This block used to force
     --r-pill and --btn-r to 200px, overriding the canon note above
     ("squircle, NOT fully-round ends") on the grounds that Gleap called the
     capsule non-negotiable. Reverted: the house rule wins over the borrowed
     one, and a 200px radius made a button's corner a function of its height,
     so a 32px and a 52px button drew different curves as one component.
     Buttons now take --radius-lg (10px), the input rung.
   · COLOR IS RATIONED TO ONE. --live is the only hue in the system and is
     status-only: dots and checkmarks. Never a fill, never decoration.
   ═══════════════════════════════════════════════ */
:root{
  /* surfaces: canvas · white · stone · pebble (never stack more than 3) */
  --page:var(--gray-100); --panel:#ffffff; --panel-2:var(--gray-100);
  --tile:var(--gray-200); --pebble:var(--gray-400); --quartz:var(--gray-300); --raise:var(--gray-200);
  --wall:var(--gray-300);
  /* ink: true neutral, softer than black so long copy is not harsh */
  /* Gleap pairs slate #6f6f6e with the linen canvas, but that measures
     4.28:1: under the 4.5 floor, on the color it calls "the most volume of
     any text". Nudged 4 points to #6b6b6a: 4.54:1 on linen, 5.33:1 on white,
     visually identical. --ink-3 (ash) stays as-specified: it is decorative
     labeling, never body, and must not be used for prose. */
  --ink:var(--gray-800); --ink-2:var(--gray-600); --ink-3:var(--gray-500); --ink-nav:var(--gray-700);
  --border:rgba(0,0,0,.12); --border-2:rgba(0,0,0,.22); --hover:rgba(0,0,0,.04);
  /* graphite CTA: the anchor. not a brand hue. */
  --accent:var(--gray-900); --accent-soft:color-mix(in srgb, var(--gray-900) 8%, transparent); --accent-ink:#ffffff;
  /* the entire chromatic budget: one status green */
  --live:#4cc02b; --live-soft:rgba(76,192,43,.12);
  /* radius. --btn-r was 200px here and again below, which made every button a
     fully-round capsule and, worse, made its corner a function of its HEIGHT:
     a 32px button and a 52px button drew visibly different curves while claiming
     to be one component. Buttons take --radius-lg (10px), the input rung, so a
     button and the field above it share one corner at every size. The system
     already says --r-pill is a 13px squircle, "NOT fully-round ends"; 200px was
     contradicting that in the token it named. */
  --r-pill:13px; --r-panel:12px; --r-card:12px; --r-tile:6px; --r-ctl:6px;
  --r-sheet:12px; --btn-r:var(--radius-lg); --radius-full:9999px;
  /* depth: tone first, but every floating thing now carries a real lift.
     Two fixes and one deliberate override:
     1. BUG: --elev-2 was rgba(16,24,40,.12), which is the NAVY the gray ramp
        rebuild removed everywhere else. A blue-cast shadow survived in the
        elevation ladder and tinted every sheet, menu and popover cool. Neutral now.
     2. BUG: single-layer shadows read as a smudge. Real lift is two layers: a
        tight contact shadow that anchors the edge + a wide diffuse one that
        carries the height. That is what --elev-1 already did and 2/3 did not.
     3. OVERRIDE: --elev-soft was `none`, per "only floating overlays carry a
        shadow". Cards read flat as a result. Restored to a genuine diffuse lift
        on request. This is a deliberate departure from tone-first depth: if the
        vellum is doing its job, this is the knob to turn back down. */
  --elev-soft:0 1px 2px -1px rgba(24,24,24,.07),0 10px 28px -10px rgba(24,24,24,.16);
  --shadow-xs:none; --shadow-sm:none;
  --elev-1:0 1px 2px -1px rgba(24,24,24,.16),0 4px 10px -3px rgba(24,24,24,.13);
  --elev-2:0 4px 10px -4px rgba(24,24,24,.17),0 16px 40px -10px rgba(24,24,24,.20);
  --elev-3:0 8px 18px -6px rgba(24,24,24,.22),0 28px 62px -14px rgba(24,24,24,.30);
  --chip-sh:inset 0 1px 0 rgba(255,255,255,.6),0 1px 3px -1px rgba(24,24,24,.10);
  /* glass: transparency is a first-class surface here */
  /* Button vocabulary, taken from the app rather than from the reference deck.
     On /app there is exactly one dark object on screen at a time (the "Plan my
     day" capsule, 28px tall) and everything else is a light glass control on a
     white hairline. The tokens below are that screen, stated:

       primary   ink capsule, one per view, small
       secondary the glass control (this is the workhorse, not a filled slab)
       tertiary  type only, no ground until hover

     Primary was --gray-900 (#141414). Graphite is the map-pin ink, and a
     button-sized field of it outweighs everything around it on a linen page.
     It now rests on --gray-800, the same ink the body copy is set in, and
     deepens to graphite on hover: the press gets darker, not lighter. */
  --button-primary-bg:var(--gray-800); --button-primary-hover:var(--gray-900); --button-primary-text:#ffffff;
  /* Secondary is frosted glass: translucent white over the shared blur, the
     same material as the fields and the map controls. It has gone stone-fill ->
     glass -> stone-fill across earlier passes; glass is the resting state now,
     and it takes NO border (the hairline that suited a control over the map is
     the loudest line on paper). States move opacity: .76 -> .88 -> a stronger
     stone-tinted frost, so the press deepens the glass instead of swapping to a
     hard fill. */
  --button-secondary-bg:var(--glass-bg);
  --button-secondary-hover:var(--glass-bg-strong);
  --button-secondary-press:rgba(219,219,212,.88);
  --button-secondary-border:transparent; --button-secondary-text:var(--ink);
  --button-tertiary-bg:transparent;
  --button-tertiary-hover:var(--glass-bg);
  --button-tertiary-text:var(--ink-2);
  /* A soft ink halo, no hard edge and no gap-drawn second line. The gapped
     two-ring version read as a heavy double outline on the grey fields, the
     one thing that made focus feel welded on. One diffuse ring now. */
  --focus-ring:0 0 0 3px rgba(20,20,20,.13);
  --seg-track:var(--gray-200); --seg-thumb:#ffffff;
  /* type: weight 400 dominates, even at display. headlines whisper. */
  --fw-regular:400; --fw-medium:500; --fw-semibold:600;
}
/* ═══════════════════════════════════════════════
   VELLUM: paper, not screen.
   Two facts make this read as a sheet rather than a color:
     1. TEXTURE. A fine fractal grain (the tooth) over a slow low-frequency
        mottle (how vellum pools light unevenly). One flat noise layer reads
        as digital dirt; the two together read as stock.
     2. TRANSLUCENCY. Surfaces are no longer opaque fills: every sheet is
        semi-transparent, so the textured ground shows through it. That IS
        vellum: you see the paper under the paper. Stacking sheets deepens
        tone without a single shadow, which is exactly Gleap's depth rule.
   The grain paints once on a fixed ::before overlay rather than per-element,
   so it never tiles-per-card, never scrolls out of register, and costs one
   composited layer for the whole page.
   ═══════════════════════════════════════════════ */
:root{
  --tex-grain:url("data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20width%3D%27150%27%20height%3D%27150%27%3E%3Cfilter%20id%3D%27g%27%3E%3CfeTurbulence%20type%3D%27fractalNoise%27%20baseFrequency%3D%270.9%27%20numOctaves%3D%274%27%20seed%3D%277%27%20stitchTiles%3D%27stitch%27%2F%3E%3CfeColorMatrix%20type%3D%27saturate%27%20values%3D%270%27%2F%3E%3C%2Ffilter%3E%3Crect%20width%3D%27150%27%20height%3D%27150%27%20filter%3D%27url%28%23g%29%27%20opacity%3D%270.62%27%2F%3E%3C%2Fsvg%3E");
  --tex-mottle:url("data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20width%3D%27300%27%20height%3D%27300%27%3E%3Cfilter%20id%3D%27m%27%3E%3CfeTurbulence%20type%3D%27fractalNoise%27%20baseFrequency%3D%270.055%27%20numOctaves%3D%273%27%20seed%3D%273%27%20stitchTiles%3D%27stitch%27%2F%3E%3CfeColorMatrix%20type%3D%27saturate%27%20values%3D%270%27%2F%3E%3C%2Ffilter%3E%3Crect%20width%3D%27300%27%20height%3D%27300%27%20filter%3D%27url%28%23m%29%27%20opacity%3D%270.16%27%2F%3E%3C%2Fsvg%3E");
  /* ── glass ──
     Promoted from the nav pill, which had invented its own treatment in ds.css
     (rgba(255,255,255,.72) + blur(20px) saturate(1.4)) while --glass-* said
     something else entirely. --glass-bg was declared FOUR times across this
     file and cascaded to .62/blur(12px), so the app's 40 glass surfaces and the
     pill had quietly diverged. One definition now; the pill consumes it like
     everything else.
     The saturate() is load-bearing: blur alone grays out what it samples, and
     nudging saturation back up is what keeps vellum reading as warm paper
     through the panel rather than as fog. */
  /* control glass: for buttons and fields that float over IMAGERY (a map, a
     photo). Distinct from --glass-bg, which follows the page theme: a control
     sitting on a photo has no theme to follow, so it must carry its own scrim
     or the label drops out the instant the image behind it goes light.
     Ink-based and theme-independent by design. */
  --glass-ink:rgba(20,20,20,.42);
  --glass-ink-strong:rgba(20,20,20,.60);
  --glass-ink-brd:rgba(255,255,255,.20);
  --glass-bg:rgba(255,255,255,.76);
  --glass-bg-strong:rgba(255,255,255,.88);
  --glass-brd:rgba(255,255,255,.55);
  --glass-blur:blur(26px) saturate(1.5);
  --glass-edge:inset 0 1px 0 rgba(255,255,255,.7);
  --glass-shadow:var(--elev-2);
  /* halftone: a dot screen, the thing that makes paper read as PRINTED rather
     than merely textured. Rotated 15°, the classic screen angle: on-axis dots
     fight the pixel grid and moiré. 5px pitch, low opacity: tooth, not polka
     dots. Sits with the grain and mottle on the same fixed plate layer. */
  --tex-halftone:url("data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20width%3D%275%27%20height%3D%275%27%3E%3Cg%20transform%3D%27rotate%2815%202.5%202.5%29%27%3E%3Ccircle%20cx%3D%271.25%27%20cy%3D%271.25%27%20r%3D%270.62%27%20fill%3D%27%23292929%27%20opacity%3D%270.30%27%2F%3E%3Ccircle%20cx%3D%273.75%27%20cy%3D%273.75%27%20r%3D%270.62%27%20fill%3D%27%23292929%27%20opacity%3D%270.30%27%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E");
  --tex-halftone-size:5px 5px;
  --tex-grain-size:150px 150px; --tex-mottle-size:300px 300px;
  --tex-strength:.16;
  /* translucent sheets: the ground reads through each one */
  --vellum-1:rgba(255,255,255,.72);   /* frosted sheet  · primary content */
  --vellum-2:rgba(231,231,224,.55);   /* stone sheet    · de-emphasised */
  --vellum-3:rgba(222,222,214,.5);   /* quartz sheet   · quietest */
  --panel:var(--vellum-1); --tile:var(--vellum-2); --raise:var(--vellum-1);
  /* radii: one tight cluster. was 16/12/8/20/13 fighting 12/6/6/12/200
     across two blocks; nested corners collided at 6/6. Now concentric and
     close enough to read as one family: ctl 6 < tile 8 < panel 12. */
  --r-ctl:6px; --r-tile:8px; --r-panel:12px; --r-card:12px; --r-sheet:12px;
  --r-lg:12px; --r-pill:13px; --btn-r:var(--radius-lg);
  /* Weight. This block used to flatten all four rungs to 400 ("Gleap: headlines
     whisper"), which left one weight and forced every hierarchy to be built by
     shrinking type and fading it toward --ink-3. That is what read as soft, and
     the flattened rungs had zero consumers, so the ramp was dead rather than
     quiet. Real values, matching the weights the sign-in already ships. */
  --fw-regular:400; --fw-medium:500; --fw-semibold:600; --fw-bold:700;
}
/* ── plate ──
   A photogravure reference: type is a whisper, the paper carries the image.
   Two additions the even grain could not give us:
     · VIGNETTE. A printed plate is never uniform. It falls off toward the
       edges where the light pooled. Radial, multiplied, weighted slightly
       above center so it reads as optics, not a CSS gradient.
     · FOG. The low-frequency mottle I pulled earlier for reading as staining
       is exactly what a gravure plate has; it just has to be soft and large
       rather than blotchy. It returns as its own layer at low strength.
   Type: letterspaced serif caps. That is the single most identifiable trait of
   the register: the title is smaller than the body copy of most sites, and the
   tracking is what makes it read as pressed rather than set. */
:root{

  --tex-vignette:radial-gradient(125% 95% at 50% 42%, transparent 38%, rgba(41,41,41,.07) 72%, rgba(41,41,41,.16) 100%);
  /* plate type: the whisper */
  --plate-tracking:.30em;
  --plate-size:clamp(15px,1.5vw,19px);
}
body::after{content:"";position:fixed;inset:0;pointer-events:none;z-index:0;
  background:var(--tex-vignette);mix-blend-mode:multiply}
@media (prefers-reduced-transparency:reduce){ body::after{opacity:.4} }

/* the sheet the whole product is printed on. Halftone dropped from the full-page
   ground (reads as on-screen noise at viewport scale); it stays only on the wash
   swatches. The ground carries just the grain (tooth) and the slow mottle. */
body::before{content:"";position:fixed;inset:0;pointer-events:none;z-index:0;
  background-image:var(--tex-grain),var(--tex-mottle);
  background-size:var(--tex-grain-size),var(--tex-mottle-size);
  background-repeat:repeat,repeat;
  opacity:var(--tex-strength);mix-blend-mode:multiply}
body>*{position:relative;z-index:1}
@media (prefers-reduced-transparency:reduce){
  :root{--vellum-1:#ffffff;--vellum-2:var(--gray-200);--vellum-3:var(--gray-300);--tex-strength:.14}
}

/* Gleap: circular accent tile: quiet marker, never a CTA */
.ds-dot-tile{background:var(--pebble);border-radius:50%;display:grid;place-items:center;
  width:40px;height:40px;color:var(--ink-nav);flex:none}
.ds-dot-tile svg{width:18px;height:18px;display:block}
/* Gleap: status dot: the only chromatic element */
.ds-status{width:8px;height:8px;border-radius:50%;background:var(--live);flex:none;display:inline-block}
/* Gleap: glass overlay: floats over imagery, stays legible */
.ds-glass{background:var(--glass-bg);backdrop-filter:var(--glass-blur);-webkit-backdrop-filter:var(--glass-blur);
  border-radius:var(--r-tile);padding:18px;box-shadow:var(--glass-shadow),var(--glass-edge)}

/* ── tile grid: uniform cells, content centered with air (r02) ── */
.ds-tilegrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(180px,1fr));gap:12px}
.ds-tile{background:var(--tile);border-radius:var(--r-tile);display:grid;place-items:center;
  padding:20px;aspect-ratio:1;overflow:hidden}
.ds-tile>img{max-width:100%;height:auto;display:block}

/* ── card: the floating white surface everything else sits on (r01/r03) ──
   No shadow. On /app the cards (.mctrl, .datewidget, the ask bar) are
   translucent white over a white hairline and cast nothing; only the solid
   chips carry --elev-1. A shadow under a translucent sheet reads as two
   depth systems arguing, which is what made these look heavy. The hairline
   went too: a card is a sheet, and a sheet on paper is separated by tone and
   radius, not by an outline. Hairlines belong on chrome that floats over the
   map, where there is no reliable ground to sit against. */
.ds-card{background:var(--panel);border:0;border-radius:var(--r-card);
  box-shadow:none;padding:16px}

/* ── segmented control: gray track, white raised thumb (r01) ── */
.ds-seg{display:inline-flex;background:var(--seg-track);border-radius:var(--r-pill);padding:3px;gap:2px}
.ds-seg>button{appearance:none;border:0;background:transparent;cursor:pointer;
  font:var(--fw-medium) var(--btn-fz)/1 var(--sans);color:var(--ink-2);
  padding:8px 14px;border-radius:calc(var(--r-pill) - 3px);transition:background .16s ease,color .16s ease}
.ds-seg>button[aria-selected="true"]{background:var(--seg-thumb);color:var(--ink);box-shadow:var(--elev-1)}
.ds-seg>button:focus-visible{outline:2px solid var(--accent);outline-offset:1px}

/* ── readout: a number with its unit, in its own pill (r01: 0.283 · 100% · 8s) ── */
.ds-readout{display:inline-flex;align-items:center;gap:6px;background:var(--panel);
  border:1px solid var(--border);border-radius:var(--r-pill);padding:6px 10px;
  font:var(--fw-medium) var(--text-xs)/1 var(--mono);color:var(--ink)}
.ds-readout svg{width:12px;height:12px;color:var(--ink-3);fill:none;stroke:currentColor}


/* ── base ──
   NOTE: this file is duplicated per project (worldsite + url-fk-vamos). Everything
   above this line must stay byte-identical; only the body rule below legitimately
   differs, because the app locks to a map viewport and the editorial pages scroll.
   THIS COPY = app (url-fk-vamos). Viewport-locked: the map owns the screen. */
*{box-sizing:border-box;-webkit-tap-highlight-color:transparent}
html,body{margin:0;height:100%}
body{background:var(--page);color:var(--ink);font-family:var(--sans);font-size:14px;-webkit-font-smoothing:antialiased;height:100vh;overflow:hidden}
/* Was a global svg{fill:currentColor;stroke:none}. CSS beats the fill=
   attribute, so it filled every shape and erased every stroke, and the
   icon set is Feather, which is 100% stroked. Every glyph rendered as a
   blob. :not([fill]) / :not([stroke]) keeps the original intent for glyphs
   that declare nothing, while any icon that states fill="none"
   stroke="currentColor" now keeps what it asked for. */
svg{width:18px;height:18px;flex:none}
svg:not([fill]){fill:currentColor}
svg:not([stroke]){stroke:none}

/* ── shared primitives ── */
.ds-eyebrow{font-family:var(--mono);font-size:11px;font-weight:400;letter-spacing:.08em;text-transform:uppercase;color:var(--ink-3)}
.ds-btn{display:inline-flex;align-items:center;gap:7px;height:34px;padding:0 14px;border-radius:999px;border:1px solid var(--ink);background:transparent;color:var(--ink);font-family:var(--mono);font-size:11px;letter-spacing:.06em;text-transform:uppercase;cursor:pointer;transition:background .12s,color .12s}
.ds-btn:hover{background:var(--ink);color:var(--page)}
.ds-btn--solid{background:var(--accent);border-color:var(--accent);color:var(--accent-ink)}
.ds-badge{font-family:var(--mono);color:var(--ink-3);font-size:11px;letter-spacing:.04em}

/* ── badge / tag (Untitled UI) - categorical only; the hue carries the category ── */
/* The primary action, as shipped on the sign-in. Sentence case, not mono
   uppercase: a CTA is speech, not a readout. --radius-lg (10px) is the input
   rung, so a button and the field above it share one corner. */
/* The sign-in CTA is the same primary as every other primary. It was painted
   from --accent (graphite) at weight 600, which made the one button on a
   sign-in screen heavier than anything in the app it signs you into. It now
   reads --button-primary-* at weight 400, and its ghost partner is the glass
   secondary rather than a panel on an iron hairline. */
.ds-btn-cta{display:inline-flex;align-items:center;justify-content:center;gap:10px;width:100%;height:46px;padding:0 16px;border:1px solid transparent;border-radius:var(--radius-lg);background:var(--button-primary-bg);color:var(--button-primary-text);font-family:var(--sans);font-size:15px;font-weight:var(--fw-regular);cursor:pointer;transition:background .14s ease}
.ds-btn-cta:hover{background:var(--button-primary-hover)}
.ds-btn-cta--ghost{background:var(--button-secondary-bg);border-color:var(--button-secondary-border);
  color:var(--button-secondary-text);backdrop-filter:var(--glass-blur);-webkit-backdrop-filter:var(--glass-blur)}
.ds-btn-cta--ghost:hover{background:var(--button-secondary-hover)}
.ds-badge{font-family:var(--mono);color:var(--ink-3);font-size:11px;letter-spacing:.04em}

.tag{display:inline-flex;align-items:center;gap:5px;padding:2px 9px;border-radius:999px;font-family:var(--sans);font-size:11px;font-weight:600;border:1px solid;line-height:1.5;white-space:nowrap}
.tag .d{width:6px;height:6px;border-radius:50%;background:currentColor;flex:none}
.tag.gray{color:#5a5a62;background:#f5f5f4;border-color:#e6e6e3}
.tag.purple{color:#7a5af8;background:#f5f3ff;border-color:#e6ddff}
.tag.green{color:#3a9e5a;background:#ecfaf1;border-color:#cbeed9}
.tag.blue{color:#3a6ee8;background:#eff4ff;border-color:#d6e2ff}
.tag.orange{color:#c26a1f;background:#fdf4ec;border-color:#f5e0cb}
.tag.pink{color:#bf3a86;background:#fdeff8;border-color:#f6d5ea}
.tag.yellow{color:#9a7716;background:#fdf9e8;border-color:#f0e6b6}

/* ── announcement pill (Untitled UI) - chip + message + arrow ── */
.announce{display:inline-flex;align-items:center;gap:11px;padding:4px 13px 4px 4px;background:var(--raise);border:1px solid var(--border);border-radius:999px;box-shadow:var(--chip-sh);cursor:pointer;transition:background .12s;font-family:var(--sans);white-space:nowrap}
.announce:hover{background:#e9e9e6}
.announce .chip{display:inline-flex;align-items:center;gap:6px;padding:3px 10px;background:var(--chip);border:1px solid var(--border-2);border-radius:999px;font-size:12px;font-weight:600;color:var(--ink)}
.announce .chip .d{width:7px;height:7px;border-radius:50%;background:var(--live)}
.announce .msg{font-size:13px;font-weight:500;color:var(--ink-2)}
.announce .arr{color:var(--ink-3);display:flex}
.announce .arr svg{width:16px;height:16px}

/* ── editorial tabs (ref 3) ──
   A serif tab bar: the active item is ink, the rest recede to ash. No pill, no
   track, no underline. The weight of the word is the state. This is what an
   editorial register does instead of chrome. */
.ds-tabs{display:flex;align-items:baseline;gap:22px;flex-wrap:wrap}
.ds-tabs button{appearance:none;border:0;background:none;cursor:pointer;padding:0;
  font-family:var(--serif);font-weight:400;font-size:clamp(20px,2.4vw,27px);
  letter-spacing:-.01em;color:var(--ink-3);transition:color .18s ease}
.ds-tabs button:hover{color:var(--ink-2)}
.ds-tabs button[aria-selected="true"]{color:var(--ink)}
.ds-tabs sup{font-family:var(--serif);font-style:italic;font-size:11px;color:var(--ink-3);
  margin-left:2px;vertical-align:super}


/* ── watercolor wash ──
   Pigment on paper, not a flat tint. The tile was color-mix(hue 14%, #fff):
   one even film, which is why it read as a plastic swatch.
   Three things make it a wash instead:
     · POOLING. Three offset radial fields at different densities. Pigment
       settles unevenly and darkest where it sat longest, never uniformly.
     · BLEED. A small blur on the pigment layer only, so edges feather into
       each other the way wet color does. The container stays crisp.
     · TOOTH. The vellum grain is multiplied back ON TOP of the color, not
       under it. That is the whole trick: watercolor is transparent, so you
       see the paper THROUGH the pigment. Grain underneath would just be a
       textured background wearing a gradient.
   --wash-hue is set per instance from the category (content) color, so the
   chrome stays achromatic and the pigment is the only hue, rule 3 intact. */
.ds-wash{position:relative;overflow:hidden;background:var(--quartz);isolation:isolate}
.ds-wash::before{content:"";position:absolute;inset:-12%;z-index:0;
  background:
    radial-gradient(66% 60% at 28% 26%, color-mix(in srgb, var(--wash-hue) 34%, var(--quartz)) 0%, transparent 70%),
    radial-gradient(56% 64% at 76% 72%, color-mix(in srgb, var(--wash-hue) 22%, var(--quartz)) 0%, transparent 66%),
    radial-gradient(92% 86% at 58% 48%, color-mix(in srgb, var(--wash-hue) 12%, var(--quartz)) 0%, transparent 78%);
  filter:blur(4px)}
.ds-wash::after{content:"";position:absolute;inset:0;z-index:1;
  background-image:var(--tex-grain);background-size:var(--tex-grain-size);
  opacity:.55;mix-blend-mode:multiply;pointer-events:none}
.ds-wash>*{position:relative;z-index:2}
@media (prefers-reduced-transparency:reduce){
  .ds-wash::before{filter:none} .ds-wash::after{opacity:.25}
}

/* ── the wash at pin scale ──
   Same three ideas as .ds-wash (pooling, bleed, tooth) at full pigment. The
   swatch recipe mixes the hue 34/22/12% into --quartz because it describes a
   pale field; a pin has to carry a white glyph, so the pigment stays dense and
   the pools modulate it instead of tinting paper.
   Two things change at 34px:
     · The blur drops 4px -> 1.6px. A 4px feather on a 34px disc is most of the
       disc: the pools smear into one flat film and the wash is gone.
     · The halftone joins the grain. At swatch size the 5px dot screen is texture;
       at pin size it is the thing that reads as PRINTED rather than rendered,
       which is the whole point of the treatment. Opacity is lower than the
       swatch's .55 because a dot screen over a saturated fill darkens fast.
   --wash-hue is the only input, so a pin and its swatch on the design system
   resolve the same --cat-* token and cannot drift apart. */
/* clip-path, not just overflow:hidden. The wash pools are a blurred pseudo-element
   at inset:-18%, which gives them their own compositing layer, and Safari does not
   clip a composited child to a rounded overflow:hidden parent: the pigment escapes
   as a hard SQUARE behind every pin. It clips correctly in headless Chrome, which
   is exactly why this shipped. clip-path clips regardless of compositing.
   --ds-wash-clip lets each consumer state its own shape: a pin is circle(50%), the
   hover-card chip is a rounded rect. */
.ds-wash{clip-path:var(--ds-wash-clip,none)}
/* The pin is the SWATCH recipe, not a second invention: same --quartz paper,
   same three pools, same order. Only the blur scales (4px on a 64px tile is
   1.4px on a 34px disc; 4px here smears the pools into one film) and the
   pigment sits at 68/44/24% instead of the tile's 34/22/12%, which is roughly
   double: enough that a 34px disc still reads as its category, not so much that
   the paper stops showing.
   THE GLYPH IS INK, NOT WHITE, AND THAT IS WHAT BUYS THE WASH. A white glyph
   needs dense pigment behind it; dense pigment is opaque; opaque pigment is a
   fill, not a wash. Three attempts died on that contradiction before the glyph
   was allowed to go dark. If a future change wants a white glyph back, it is
   asking for a flat fill again: say so out loud and pick one.
   Two earlier attempts are worth not repeating:
     · A FLAT FILL. background:var(--wash-hue) with pools that were mixes OF
       THAT SAME HUE fading to transparent, i.e. back to the identical base.
       One pool was the hue painted on itself. That is a two-stop gradient, and
       no stop tuning makes it a wash.
     · A BLOB. Pigment biased hard to the centre-bottom to protect the glyph,
       which left the top-left as bare paper: the disc read as a crescent plus a
       blob and stopped looking circular at all. The pools must cover the WHOLE
       disc and vary in density across it, which is what the tile does.
   Watercolor is transparent: the paper reads through the pigment. That is why
   the base is --quartz and not the hue. */
.ds-wash--pin::before{inset:-12%;
  background:
    radial-gradient(66% 60% at 28% 26%, color-mix(in srgb, var(--wash-hue) 68%, var(--quartz)) 0%, transparent 70%),
    radial-gradient(56% 64% at 76% 72%, color-mix(in srgb, var(--wash-hue) 44%, var(--quartz)) 0%, transparent 66%),
    radial-gradient(92% 86% at 58% 48%, color-mix(in srgb, var(--wash-hue) 24%, var(--quartz)) 0%, transparent 78%);
  filter:blur(1.4px)}
/* the screens read here because there is paper under them to modulate */
.ds-wash--pin::after{
  background-image:var(--tex-halftone),var(--tex-grain);
  background-size:var(--tex-halftone-size),var(--tex-grain-size);
  opacity:.5}
@media (prefers-reduced-transparency:reduce){
  .ds-wash--pin::before{filter:none} .ds-wash--pin::after{opacity:.18}
}

/* ── glass controls (over imagery) ──
   The label is white on a scrim, so it holds whether the photo under it is a
   snow field or a night street, which a translucent-white control cannot do.
   Blur carries saturate() for the same reason the nav does: blur alone grays
   out what it samples. */
.ds-btn-glass{display:inline-flex;align-items:center;justify-content:center;gap:var(--space-4);
  height:38px;padding:0 var(--space-6);border:1px solid var(--glass-ink-brd);
  border-radius:var(--btn-r);background:var(--glass-ink);
  backdrop-filter:var(--glass-blur);-webkit-backdrop-filter:var(--glass-blur);
  color:#fff;font-family:var(--sans);font-weight:var(--fw-regular);font-size:13px;
  line-height:1;cursor:pointer;white-space:nowrap;
  transition:background .16s ease,border-color .16s ease}
.ds-btn-glass:hover{background:var(--glass-ink-strong);border-color:rgba(255,255,255,.32)}
.ds-btn-glass:focus-visible{outline:2px solid #fff;outline-offset:2px}
.ds-btn-glass .ic{width:15px;height:15px;flex:none}
.ds-btn-glass .ic svg{width:100%;height:100%;display:block}

.ds-field-glass{display:inline-flex;align-items:center;gap:var(--space-4);width:100%;max-width:240px;
  height:40px;padding:0 var(--space-5);border:1px solid var(--glass-ink-brd);
  border-radius:var(--r-tile);background:var(--glass-ink);
  backdrop-filter:var(--glass-blur);-webkit-backdrop-filter:var(--glass-blur);
  color:#fff;font-family:var(--sans);font-size:14px}
.ds-field-glass input{border:0;outline:0;background:none;font:inherit;color:inherit;width:100%;padding:0}
.ds-field-glass input::placeholder{color:rgba(255,255,255,.62)}
.ds-field-glass:focus-within{border-color:rgba(255,255,255,.46);background:var(--glass-ink-strong)}
.ds-field-glass .ic{width:16px;height:16px;color:rgba(255,255,255,.72);flex:none}
.ds-field-glass .ic svg{width:100%;height:100%;display:block}
@media (prefers-reduced-transparency:reduce){
  .ds-btn-glass,.ds-field-glass{background:rgba(20,20,20,.88);backdrop-filter:none;-webkit-backdrop-filter:none}
}
