/* ===========================================================================
   CarrySafe design tokens — dark only.

   GENERATED FILE. DO NOT EDIT BY HAND.
   Regenerate:  node design-kit/generate.mjs
   Generator:   design-kit/generate.mjs
   Sources:     lib/theme.ts · components/Glass.tsx · components/CarrySafeTabBar.tsx
                components/Sheet.tsx · lib/status.ts · the z-index ladder in app/+components/

   A hand-edit here is a token that no longer matches the app, which is the exact
   failure this kit exists to end. Change lib/theme.ts and re-run the generator.

   UNITS: 1 CSS px in this kit == 1 React Native point. There are no rem/em/vh/vw
   anywhere in the app; everything is points.

   NAMING: --color-text-muted is COLORS.textMuted, --radius-lg is RADIUS.lg, and so on.
   Every line carries the repo symbol it came from so the importer can map back.
   =========================================================================== */

:root {

  /* ── Font ────────────────────────────────────────────────────────────────
     There is no custom font file. Everything is SF Pro, styled by numeric weight.
     Weights are numeric STRINGS in RN ('600'|'700'|'800'|'900') — never keywords. */
  --font: -apple-system, BlinkMacSystemFont, "SF Pro Text", "SF Pro Display", "Helvetica Neue", system-ui, sans-serif;

  /* ── Colour · lib/theme.ts COLORS ────────────────────────────────────────
     Intent, from the file header: calm, factual, institutional. Deliberately NOT
     tactical — no black/orange, no camo, no aggressive iconography.
     Surfaces stay ONE step above bg, never more. Borders are felt, not seen. */
  /* ground */
  --color-bg: #0B1120;                     /* COLORS.bg */
  --color-surface: #0F1626;                /* COLORS.surface */
  --color-surface-alt: #131B2D;            /* COLORS.surfaceAlt */
  --color-border: #1D2740;                 /* COLORS.border */
  /* text */
  --color-text: #F2F5FA;                   /* COLORS.text */
  --color-text-muted: #9AA6BF;             /* COLORS.textMuted */
  --color-text-faint: #75819F;             /* COLORS.textFaint  — kept above 4.5:1 on surface, so 'faint' never means unreadable */
  /* brand */
  --color-accent: #4F8DF7;                 /* COLORS.accent  — interactive / brand chrome — AND a legend tone ('Permit recognised') */
  --color-accent-soft: #16233D;            /* COLORS.accentSoft */
  /* status */
  --color-danger: #F0555F;                 /* COLORS.danger  — prohibited / not recognised */
  --color-danger-soft: #2A1620;            /* COLORS.dangerSoft */
  --color-warn: #E8A33D;                   /* COLORS.warn  — restricted / conditions apply */
  --color-warn-soft: #2A2116;              /* COLORS.warnSoft */
  --color-ok: #3FB984;                     /* COLORS.ok  — no known restriction ON RECORD — never an affirmative claim */
  --color-ok-soft: #14261F;                /* COLORS.okSoft */
  --color-unknown: #8C93A8;                /* COLORS.unknown  — unclear / not reviewed — never green, never red */
  --color-unknown-soft: #1C2233;           /* COLORS.unknownSoft */

  /* ── Tone pairs · lib/theme.ts toneColors(tone) ──────────────────────────
     STATUS COLOUR IS LEGAL INFORMATION, NEVER DECORATION. In the app you must call
     toneColors(tone) and never type a status hex, so a 'prohibited' red cannot drift
     between the map, the list and the detail page. Its default branch returns
     `unknown`, so an unmapped tone can never come out green.
     Every tone must ALSO carry a word on screen. Colour is never the sole signal. */
  --tone-danger-fg: #F0555F;               /* toneColors("danger").fg */
  --tone-danger-bg: #2A1620;               /* toneColors("danger").bg */
  --tone-warn-fg: #E8A33D;                 /* toneColors("warn").fg */
  --tone-warn-bg: #2A2116;                 /* toneColors("warn").bg */
  --tone-ok-fg: #3FB984;                   /* toneColors("ok").fg */
  --tone-ok-bg: #14261F;                   /* toneColors("ok").bg */
  --tone-unknown-fg: #8C93A8;              /* toneColors("unknown").fg */
  --tone-unknown-bg: #1C2233;              /* toneColors("unknown").bg */
  --tone-accent-fg: #4F8DF7;               /* legend tone 'Permit recognised' (lib/onboarding.ts:202) */
  --tone-accent-bg: #16233D;               /* the MAP never paints this — legendShadeOf() collapses it onto `ok` */

  /* ── Surface ladder · components/Glass.tsx surfaceAt() ───────────────────
     All four are COLORS.surface (#0F1626) at different alphas, so the sheets stay
     in the palette by construction. They used to be three unrelated literals, which is
     why surfaces once read as a grey family. In the browser these are the COMPOSITED
     result — there is no backdrop-filter in this kit, because there is none in RN. */
  --surface-solid: rgba(15,22,38,0.98);        /* <Glass solid> · ALPHA.solid 0.98 */
  --surface-glass: rgba(15,22,38,0.94);        /* <Glass> default · ALPHA.blur 0.94 */
  --surface-glass-clear: rgba(15,22,38,0.82);  /* <Glass variant="clear"> · ALPHA.blurClear 0.82 */
  --surface-nav: rgba(15,22,38,0.78);          /* <NavigationGlass> tint · 0.78 */

  /* ── Alpha fills · lib/theme.ts withAlpha(hex, a) ────────────────────────
     Cards hosted INSIDE a Glass are built from WHITE alphas, not surface tokens. */
  --fill-card: rgba(255,255,255,0.05);        /* card on glass (0.035–0.06 observed) */
  --fill-card-hi: rgba(255,255,255,0.06);     /* the brighter card step */
  --fill-quiet: rgba(255,255,255,0.10);       /* quiet CTA, close button */
  --fill-quiet-hi: rgba(255,255,255,0.12);
  --border-on-glass: rgba(255,255,255,0.10);  /* border on a translucent card (0.08–0.12) */
  --border-on-glass-soft: rgba(255,255,255,0.08);
  --grabber: rgba(255,255,255,0.24);           /* components/Sheet.tsx grabber */
  --press-dim: 0.62;                          /* <Tap> pressed opacity */
  --accent-fill: rgba(79,141,247,0.17);        /* tab indicator fill · withAlpha(accent,0.17) */
  --accent-border: rgba(79,141,247,0.34);      /* tab indicator border · 0.34 */
  --accent-wash: rgba(79,141,247,0.22);        /* screen wash / featured ring · 0.22 */
  --accent-tint: rgba(79,141,247,0.06);        /* StateShowcase hero tile · 0.06 */
  --accent-emph: rgba(79,141,247,0.55);        /* emphasis fill: Silhouette, lit atlas state, home marker */

  /* ── Radius · lib/theme.ts RADIUS ────────────────────────────────────────
     EVERY radius in the app ships with borderCurve:'continuous' (148 pairings).
     iOS corners are squircles; a circular arc kinks where it meets the straight edge
     and reads as 'not a real iOS app'. The browser cannot draw a squircle — annotate
     'continuous corner' beside every rounded box in a mock instead.
     CONCENTRIC RULE: a card inset by `pad` inside an `outer`-radius parent uses
     outer − pad. innerRadius(outer,pad) exists in lib/theme.ts and has ZERO call sites;
     the rule is applied by hand everywhere, so apply it by hand too. */
  --radius-xs: 8px;                        /* RADIUS.xs */
  --radius-sm: 12px;                       /* RADIUS.sm */
  --radius-md: 16px;                       /* RADIUS.md */
  --radius-lg: 20px;                       /* RADIUS.lg */
  --radius-xl: 26px;                       /* RADIUS.xl */
  --radius-xxl: 32px;                      /* RADIUS.xxl */
  --radius-pill: 999px;                    /* RADIUS.pill */
  /* named surface defaults — these are component defaults, not scale steps */
  --radius-glass: 22px;                     /* <Glass radius> default */
  --radius-nav: 28px;                       /* <NavigationGlass radius> default */
  --radius-rail: 29px;                      /* tab bar rail + action capsule */
  --radius-indicator: 23px;                 /* tab indicator = 29 − 4 padding (concentric) */
  --radius-sheet: 30px;                     /* <BottomSheet radius> default */
  --radius-grabber: 2.5px;                 /* components/Sheet.tsx */

  /* ── Elevation · lib/theme.ts SHADOW ─────────────────────────────────────
     Wide radius, low opacity, small offset. A hard shadow reads as Material Design.
     RN has no spread, no inset and no multiple shadows — do not reach for them.
     md = bars and panels (Glass default) · lg = sheets and navigation · none = opt out. */
  --shadow-sm: 0px 2px 8px rgba(0,0,0,0.18);               /* SHADOW.sm — shadowOpacity 0.18, shadowRadius 8, offset {0,2}, elevation 3 */
  --shadow-md: 0px 6px 18px rgba(0,0,0,0.28);              /* SHADOW.md — shadowOpacity 0.28, shadowRadius 18, offset {0,6}, elevation 8 */
  --shadow-lg: 0px 12px 30px rgba(0,0,0,0.38);             /* SHADOW.lg — shadowOpacity 0.38, shadowRadius 30, offset {0,12}, elevation 16 */

  /* ── Optical tracking · lib/theme.ts tracking(size) ──────────────────────
     SF Pro tightens as it grows. Sentence-case text uses letterSpacing: tracking(ITS OWN
     fontSize) — passing a different size is a bug. letterSpacing is in POINTS, never em.
     ALL-CAPS micro-labels are the exception: NEVER pass tracking() to an uppercase label,
     hand-set a POSITIVE value instead (--track-caps-*). Breakpoints:
       <=11 → 0.06 · <=13 → -0.08 · <=15 → -0.24 · <=17 → -0.41 · <=20 → -0.45 · <=24 → -0.6 · <=28 → -0.8 · >28 → -0.9 */
  --track-8: 0.06px;           /* tracking(8) */
  --track-8-5: 0.06px;         /* tracking(8.5) */
  --track-9: 0.06px;           /* tracking(9) */
  --track-9-5: 0.06px;         /* tracking(9.5) */
  --track-10: 0.06px;          /* tracking(10) */
  --track-10-5: 0.06px;        /* tracking(10.5) */
  --track-11: 0.06px;          /* tracking(11) */
  --track-11-5: -0.08px;       /* tracking(11.5) */
  --track-12: -0.08px;         /* tracking(12) */
  --track-12-5: -0.08px;       /* tracking(12.5) */
  --track-13: -0.08px;         /* tracking(13) */
  --track-13-5: -0.24px;       /* tracking(13.5) */
  --track-14: -0.24px;         /* tracking(14) */
  --track-14-5: -0.24px;       /* tracking(14.5) */
  --track-15: -0.24px;         /* tracking(15) */
  --track-15-5: -0.41px;       /* tracking(15.5) */
  --track-16: -0.41px;         /* tracking(16) */
  --track-16-5: -0.41px;       /* tracking(16.5) */
  --track-17: -0.41px;         /* tracking(17) */
  --track-17-5: -0.45px;       /* tracking(17.5) */
  --track-18: -0.45px;         /* tracking(18) */
  --track-18-5: -0.45px;       /* tracking(18.5) */
  --track-19: -0.45px;         /* tracking(19) */
  --track-19-5: -0.45px;       /* tracking(19.5) */
  --track-20: -0.45px;         /* tracking(20) */
  --track-20-5: -0.6px;        /* tracking(20.5) */
  --track-21: -0.6px;          /* tracking(21) */
  --track-21-5: -0.6px;        /* tracking(21.5) */
  --track-22: -0.6px;          /* tracking(22) */
  --track-22-5: -0.6px;        /* tracking(22.5) */
  --track-23: -0.6px;          /* tracking(23) */
  --track-23-5: -0.6px;        /* tracking(23.5) */
  --track-24: -0.6px;          /* tracking(24) */
  --track-24-5: -0.8px;        /* tracking(24.5) */
  --track-25: -0.8px;          /* tracking(25) */
  --track-25-5: -0.8px;        /* tracking(25.5) */
  --track-26: -0.8px;          /* tracking(26) */
  --track-26-5: -0.8px;        /* tracking(26.5) */
  --track-27: -0.8px;          /* tracking(27) */
  --track-27-5: -0.8px;        /* tracking(27.5) */
  --track-28: -0.8px;          /* tracking(28) */
  --track-28-5: -0.9px;        /* tracking(28.5) */
  --track-29: -0.9px;          /* tracking(29) */
  --track-29-5: -0.9px;        /* tracking(29.5) */
  --track-30: -0.9px;          /* tracking(30) */
  --track-30-5: -0.9px;        /* tracking(30.5) */
  --track-31: -0.9px;          /* tracking(31) */
  --track-31-5: -0.9px;        /* tracking(31.5) */
  --track-32: -0.9px;          /* tracking(32) */
  --track-32-5: -0.9px;        /* tracking(32.5) */
  --track-33: -0.9px;          /* tracking(33) */
  --track-33-5: -0.9px;        /* tracking(33.5) */
  --track-34: -0.9px;          /* tracking(34) */
  /* hand-set uppercase tracking — the three that dominate; observed set is
     0.2 0.3 0.4 0.5 0.6 0.7 0.75 0.8 0.9 1 1.1 1.15 1.2 1.4 1.6 2.4 */
  --track-caps-sm: 0.6px;
  --track-caps-md: 0.9px;
  --track-caps-lg: 1.2px;

  /* ── Borders ─────────────────────────────────────────────────────────────
     StyleSheet.hairlineWidth is THE DEFAULT (71 uses). 1 when the border must be a
     visible ring (selected state, accent chip). 1.5 only for a featured ring, a radio
     ring or a legend swatch. Colour is --color-border on solid surfaces and
     --border-on-glass on translucent cards hosted inside a Glass. */
  --hairline: 0.5px;                        /* StyleSheet.hairlineWidth (1/scale: 0.5 @2x, ~0.33 @3x) */
  --border-ring: 1px;
  --border-featured: 1.5px;

  /* ── Navigation and sheet geometry ───────────────────────────────────────
     Exported from components/CarrySafeTabBar.tsx — import them, never hardcode. */
  --nav-bar-height: 64px;                  /* NAV_BAR_HEIGHT */
  --nav-bar-bottom-gap: 12px;              /* NAV_BAR_BOTTOM_GAP */
  --nav-sheet-gap: 12px;                   /* NAV_SHEET_GAP */
  --nav-sheet-offset: 88px;                /* NAV_SHEET_OFFSET = height + gap + gap */
  --nav-rail-padding: 4px;
  --nav-tab-height: 56px;
  --nav-action-width: 60px;                 /* compact (width<350 || fontScale>1.35): 54 */
  --nav-inner-gap: 10px;                    /* NavigationGlassGroup spacing={10} */
  --detent-peek: 92px;                     /* detentsFor()[0] — a FLOOR: glyph tile + title + one clean subtitle line */
  --detent-short: 232px;                   /* min(232, max) */
  --detent-half: 430px;                    /* min(430, max) */
  --detent-clearance: 104px;               /* max = windowHeight − insetTop − insetBottom − 104 */
  --sheet-gutter: 14px;                     /* peek row + content paddingHorizontal */
  --sheet-side-inset: 12px;                 /* animates to 0 at full screen */
  --grabber-w: 36px;                       /* hitSlop { top:14, bottom:18 } — drags were missing it */
  --grabber-h: 5px;
  --min-tap: 44px;                         /* lib/status.ts MIN_TAP — the visual may be smaller, the responder cannot */

  /* ── Gutters (observed, no scale constant exists) ────────────────────────
     gap: 8 and 10 dominate · 3 is icon↔label in a tab · 12 separates card blocks.
     Card padding is 12–14. paddingVertical clusters at 7–12. */
  --gutter-sheet: 14px;
  --gutter-paywall: 18px;
  --gutter-onboarding: 20px;

  /* ── z-index ladder ──────────────────────────────────────────────────────
     zIndex orders SIBLINGS ONLY — you cannot escape a parent. This is a fixed
     vocabulary, not a scale: reuse a level, never invent one. Each is asserted
     against its owning file by the generator. */
  --z-review-desk: 300;        /* components/ReviewDesk.tsx — staff review desk — top of the ladder */
  --z-onboarding: 100;         /* components/Onboarding.tsx — onboarding, absoluteFill over COLORS.bg */
  --z-corner-sheet: 80;        /* components/Sheet.tsx — CornerSheet (the profile) */
  --z-tab-bar: 60;             /* components/CarrySafeTabBar.tsx — the floating tab bar */
  --z-modal-scrim: 50;         /* components/UpgradeSheet.tsx — modal backdrop / scrim */
  --z-drive: 48;               /* components/DriveMode.tsx — drive-mode chrome */
  --z-bottom-sheet: 45;        /* components/Sheet.tsx — BottomSheet */
  --z-map-controls: 43;        /* components/MapControls.tsx — map controls stack */
  --z-top-bar: 40;             /* app/index.tsx — map top bar */

  /* ── Status severities · lib/status.ts STATUS ────────────────────────────
     Four redundant signals per severity, because four of six statuses once collapsed
     to the same amber ring and red/amber is exactly the pair a deuteranope loses:
     a WORD, a SHAPE (border width + style, readable in greyscale), a GLYPH, and a
     SPOKEN sentence. The border style below IS the shape signal — keep it. */
  --status-prohibited-width: 3px;      /* "Prohibited" · glyph ✕ · tone danger */
  --status-prohibited-style: solid;
  --status-restricted-width: 2px;      /* "Restricted" · glyph ! · tone warn */
  --status-restricted-style: solid;
  --status-verify-width: 2px;          /* "Verify locally" · glyph ? · tone warn */
  --status-verify-style: dashed;
  --status-allowed-width: 1px;         /* "No restriction on record" · glyph ○ · tone ok */
  --status-allowed-style: solid;
  --status-unreviewed-width: 2px;      /* "Not reviewed" · glyph – · tone unknown */
  --status-unreviewed-style: dotted;

  /* ── Gradients — FOUR sanctioned jobs, and there is no fifth ─────────────
     THERE IS NO BRAND GRADIENT. In RN these are <LinearGradient> at
     StyleSheet.absoluteFill inside a clipped parent. Job 4 (wallet / permit card
     faces) is the only DECORATIVE gradient and lives only in the wallet, where
     nothing sits over the map — it is deliberately not exposed here. */
  --gradient-specular: linear-gradient(180deg, rgba(255,255,255,0.06) 0%, rgba(255,255,255,0.012) 34%, rgba(255,255,255,0) 100%);  /* job 1 — the ONLY light treatment on a Glass */
  --gradient-wash: linear-gradient(180deg, rgba(79,141,247,0.22) 0%, rgba(11,17,32,0) 45%, rgba(11,17,32,0) 100%);  /* job 2 — screen wash */
  --gradient-scrim: linear-gradient(180deg, rgba(11,17,32,0.15) 0%, rgba(11,17,32,0.78) 55%, rgba(11,17,32,0.97) 100%);  /* job 3 — image scrim for legibility */

  /* ── Device geometry — NOT FROM THE REPO ─────────────────────────────────
     ⚠ These are Apple platform values quoted from docs/ONBOARDING-HANDOFF.md §8.2–8.3.
     The app NEVER hardcodes an inset — it calls useSafeAreaInsets(), and insets are
     runtime values. Use these to SIZE A MOCK and for nothing else. Never type 47 or 34
     into a stylesheet: making a card full-screen once removed the centred inset without
     adding a safe-area one, and the title printed over the status-bar clock.
     Design 375 × 667 FIRST — the step column spans 548px there and 761px on a 16 Pro Max. */
  --device-375x667-w: 375px;       /* iPhone SE 2/3, 8 — THE PRACTICAL DESIGN FLOOR */
  --device-375x667-h: 667px;
  --device-375x667-top: 20px;      /* safe-area top — MOCK SIZING ONLY */
  --device-375x667-bottom: 0px;    /* safe-area bottom — the CTA and Restore row must clear this */
  --device-375x812-w: 375px;       /* X, XS, 11 Pro, 12/13 mini */
  --device-375x812-h: 812px;
  --device-375x812-top: 44px;      /* safe-area top — MOCK SIZING ONLY */
  --device-375x812-bottom: 34px;   /* safe-area bottom — the CTA and Restore row must clear this */
  --device-393x852-w: 393px;       /* 14 Pro, 15, 15 Pro, 16 */
  --device-393x852-h: 852px;
  --device-393x852-top: 59px;      /* safe-area top — MOCK SIZING ONLY */
  --device-393x852-bottom: 34px;   /* safe-area bottom — the CTA and Restore row must clear this */
  --device-402x874-w: 402px;       /* 16 Pro, 17 */
  --device-402x874-h: 874px;
  --device-402x874-top: 59px;      /* safe-area top — MOCK SIZING ONLY */
  --device-402x874-bottom: 34px;   /* safe-area bottom — the CTA and Restore row must clear this */
  --device-440x956-w: 440px;       /* 16 Pro Max */
  --device-440x956-h: 956px;
  --device-440x956-top: 62px;      /* safe-area top — MOCK SIZING ONLY */
  --device-440x956-bottom: 34px;   /* safe-area bottom — the CTA and Restore row must clear this */
  --device-320x568-w: 320px;       /* iPhone SE 1st gen — theoretical floor at iOS 15.1 */
  --device-320x568-h: 568px;
  --device-320x568-top: 20px;      /* safe-area top — MOCK SIZING ONLY */
  --device-320x568-bottom: 0px;    /* safe-area bottom — the CTA and Restore row must clear this */
}

