/* brand.css — shared design tokens + primitives for the CLIENT ride surfaces
   (/confirm, /trip, /r). Values mirror app/src/theme.ts `palettes.client` EXACTLY —
   that file is the design-system source of truth; reconcile here when it moves.
   Loaded root-absolute (<link href="/brand.css">) because both pages are served
   at nested rewrite paths (/confirm/<token>, /trip/<token>).
   Marketing surfaces (index/join: dark charcoal + Fraunces) intentionally differ. */

@import url('https://fonts.googleapis.com/css2?family=Cormorant+Garamond:ital,wght@0,500;0,600;0,700;1,600&family=Hanken+Grotesk:wght@400;500;600;700;800&display=swap');

/* GENERATED:design-tokens:start — from app/src/theme.ts via scripts/release/sync-design-tokens.mjs. DO NOT EDIT. */
:root {
  /* palettes.client */
  --bg: #FFFFFF;
  --bg2: #F7F7F7;
  --surface: #FFFFFF;
  --card: #F1F1F1;
  --ink: #191919;
  --ink2: #555555;
  --ink3: #626262;
  --ink4: #A3A3A3;
  --line: #C9C9C9;
  --line2: #909090;
  --gold: #B6924F;
  --gold-deep: #775B2D;
  --wash: #F3EAD6;
  --on-gold: #191919;
  --ok: #3E7C5A;
  --danger: #A8392B;

  /* radius — theme.ts `radius` */
  --r-badge: 6px;  --r-chip: 8px;  --r-input: 10px; --r-media: 12px;
  --r-button: 16px; --r-button-lg: 22px; --r-card: 22px; --r-sheet: 30px; --r-pill: 999px;
  /* the card radius, kept under its original name for existing call sites */
  --radius: 22px;

  /* typography — theme.ts `typography`. Native ships a family per weight; the web
     maps each to a stack + numeric weight (see FAMILY in the generator). */
  --ff-display: var(--serif); --fw-display: 600; --fs-display: 30px; --lh-display: 31px; --ls-display: -0.3px;
  --ff-h1: var(--sans); --fw-h1: 700; --fs-h1: 26px; --lh-h1: 29px; --ls-h1: -0.52px;
  --ff-h2: var(--sans); --fw-h2: 700; --fs-h2: 18px; --ls-h2: -0.18px;
  --ff-h3: var(--sans); --fw-h3: 700; --fs-h3: 15px; --ls-h3: -0.08px;
  --ff-body: var(--sans); --fw-body: 400; --fs-body: 14px; --lh-body: 20px;
  --ff-sub: var(--sans); --fw-sub: 400; --fs-sub: 13px; --lh-sub: 18px;
  --ff-cap: var(--sans); --fw-cap: 500; --fs-cap: 11.5px;
  --ff-eyebrow: var(--sans); --fw-eyebrow: 700; --fs-eyebrow: 11px; --ls-eyebrow: 1.76px;
  --ff-brand: var(--serif); --fw-brand: 600; --fs-brand: 22px; --lh-brand: 24px; --ls-brand: 0.1px;

  /* spacing — theme.ts `spacing` + `gutter` */
  --s-xs: 4px; --s-sm: 8px; --s-md: 12px; --s-lg: 16px; --s-xl: 24px; --s-xxl: 32px;
  --gutter: 22px;
}
/* GENERATED:design-tokens:end */

/* Hand-written, web-only: font stacks (the app loads families per weight; the browser loads one
   family and picks a weight) and the page's max content width. Not derived from theme.ts. */
:root {
  --maxw: 460px;
  --serif: "Cormorant Garamond", Georgia, "Times New Roman", serif;
  --sans: "Hanken Grotesk", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}

* { box-sizing: border-box; }
html, body { margin: 0; background: var(--bg); color: var(--ink); font-family: var(--sans); -webkit-font-smoothing: antialiased; }
body { min-height: 100dvh; display: flex; flex-direction: column; align-items: center; padding: 22px 16px 40px; }

/* Brand mark — Private Chauffeur serif wordmark. */
.brand { width: 100%; max-width: var(--maxw); padding: 2px 4px 20px; }
.brand .logo { display: inline-flex; align-items: center; min-height: 34px; padding: 6px 10px; border-radius: 7px; background: #292929; }
.brand .logo::before { content: ""; display: block; width: 96px; height: 30px; background: center / contain no-repeat url("/vlad-wordmark-cream.png"); }
.brand .logo small { display: none; }

.shell { width: 100%; max-width: var(--maxw); }
.card { background: var(--card); border: 1px solid var(--line); border-radius: var(--radius); padding: 24px 22px; box-shadow: var(--shadow-raised); }
.card + .card { margin-top: 14px; }
.state { display: none; }
.state.active { display: block; }

/* Uppercase eyebrow + restrained-brass status dot. The eyebrow TEXT names the
   state, so status never relies on color alone. */
.eyebrow { display: flex; align-items: center; gap: 9px; font-family: var(--ff-eyebrow); font-size: var(--fs-eyebrow); font-weight: var(--fw-eyebrow); letter-spacing: var(--ls-eyebrow); text-transform: uppercase; color: var(--ink3); margin: 0 0 14px; }
.dot { width: 8px; height: 8px; border-radius: 50%; background: var(--gold); flex: none; }
.dot.live { animation: pulse 1.8s ease-in-out infinite; }
@keyframes pulse { 0%,100% { opacity: 1; } 50% { opacity: 0.35; } }

h1 { font-family: var(--serif); font-weight: 600; font-size: 34px; line-height: 1.12; letter-spacing: -0.3px; margin: 2px 0 12px; }
.sub { color: var(--ink2); font-family: var(--ff-sub); font-size: var(--fs-sub); line-height: var(--lh-sub); margin: 0; }

.rows { border-top: 1px solid var(--line); margin-top: 6px; }
.row { display: flex; justify-content: space-between; gap: var(--s-lg); padding: 11px 0; border-bottom: 1px solid var(--line); font-size: var(--fs-body); }
.row .k { color: var(--ink3); white-space: nowrap; }
.row .v { color: var(--ink); text-align: right; font-weight: 500; }

/* Shared ride-facts block for the booker (/trip) and pickup-person (/r) status rails.
   Status stays conversational; immutable itinerary facts stay consistently scannable. */
.trip { margin-top: var(--s-lg); background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-media); padding: 4px 14px; }
.trip .row { display: flex; gap: 12px; padding: 12px 0; border-bottom: 1px dashed var(--line); }
.trip .row:last-child { border-bottom: 0; }
.trip .k { color: var(--ink3); font-size: 11px; font-weight: 700; letter-spacing: 0.6px; text-transform: uppercase; min-width: 62px; }
.trip .v { flex: 1; color: var(--ink); font-size: var(--fs-body); font-weight: 600; text-align: right; }

.btn { display: block; width: 100%; min-height: 60px; border: 0; border-radius: var(--r-button-lg); padding: 15px 16px; font-size: 16px; font-weight: 600; cursor: pointer; font-family: inherit; text-align: center; text-decoration: none; }
.btn-gold { background: var(--gold); color: var(--on-gold); }
.btn-gold:active { background: var(--gold-deep); }
.btn-gold:disabled { opacity: 0.55; cursor: default; }
.btn-ghost { background: transparent; color: var(--ink2); padding: 12px; font-size: 14px; }
.btn:focus-visible, .field:focus-visible, a:focus-visible { outline: 2px solid var(--gold-deep); outline-offset: 2px; }

.field { width: 100%; padding: 13px 14px; border: 1px solid var(--line); border-radius: var(--r-input); font-size: 16px; font-family: inherit; margin: 0 0 12px; background: var(--card); color: var(--ink); }
.err { color: var(--danger); font-size: var(--fs-sub); margin: 4px 2px 10px; min-height: 1px; }

/* Chauffeur block — the human in the flow: avatar (photo or serif monogram),
   name, vehicle line, optional vehicle photo. Shared by /confirm and /trip. */
.chauffeur .label { font-family: var(--ff-eyebrow); font-size: var(--fs-eyebrow); font-weight: var(--fw-eyebrow); letter-spacing: var(--ls-eyebrow); text-transform: uppercase; color: var(--ink3); margin: 0 0 10px; }
.chauffeur .person { display: flex; align-items: center; gap: 12px; }
.avatar { width: 44px; height: 44px; border-radius: 50%; flex: none; background: var(--wash); color: var(--gold-deep); border: 1px solid var(--line); display: flex; align-items: center; justify-content: center; font-family: var(--serif); font-weight: 600; font-size: 19px; overflow: hidden; }
.avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }
.chauffeur .who { flex: 1; min-width: 0; }
.chauffeur .name { font-family: var(--serif); font-weight: 600; font-size: 24px; line-height: 1.1; }
.chauffeur .veh { color: var(--ink2); font-size: var(--fs-body); margin-top: 3px; }
.vehicle-photo { width: 100%; border-radius: var(--r-media); margin-top: 14px; display: block; border: 1px solid var(--line); }
/* The plate pill under the vehicle line — the app's `platePill`/`plateText`, to the pixel. Tabular
   figures so a plate never reflows between polls, and the wide tracking is what makes six
   characters readable at a glance from a curb. */
.chauffeur .plate { display: none; margin-top: 7px; align-self: flex-start; width: fit-content; border: 1px solid var(--line2); border-radius: var(--r-chip); padding: 3px 9px; font-family: var(--sans); font-weight: 700; font-size: 12px; letter-spacing: 1.6px; font-variant-numeric: tabular-nums; color: var(--ink2); }
.contact-actions { display: flex; gap: 10px; margin-top: 14px; }
.contact-btn { flex: 1; display: inline-flex; align-items: center; justify-content: center; gap: 7px; border: 1px solid var(--line); border-radius: var(--r-media); padding: 12px 10px; font-size: var(--fs-body); font-weight: 600; color: var(--ink); background: var(--card); text-decoration: none; }
.contact-btn:active { background: var(--bg2); }
.contact-btn svg { width: 15px; height: 15px; flex: none; color: var(--gold-deep); }

/* Quiet notice strip (hold explainers, card-on-file notes). */
.notice { display: flex; gap: 9px; align-items: flex-start; margin: 14px 0 0; padding: 13px 14px; background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-media); color: var(--ink2); font-size: var(--fs-sub); line-height: var(--lh-sub); }
.notice strong { color: var(--ink); font-weight: 700; }
.notice .ic { color: var(--gold-deep); flex: none; display: inline-flex; }
.notice .ic svg { width: 14px; height: 14px; }

.muted { color: var(--ink3); font-size: 12px; text-align: center; margin-top: 22px; }
.spin { width: 22px; height: 22px; border: 2px solid var(--line); border-top-color: var(--gold); border-radius: 50%; animation: s 0.8s linear infinite; margin: 30px auto; }
@keyframes s { to { transform: rotate(360deg); } }

@media (prefers-reduced-motion: reduce) {
  .dot.live { animation: none; }
  .spin { animation: none; }
}

/* ---- Depth + motion. NOT generated, deliberately:
   • depth — React Native's shadowRadius and CSS's blur radius are different models (iOS ≈ blur/2),
     so a mechanical conversion from theme.ts `depth` would change the look rather than preserve it.
     These stay hand-tuned for the browser; what IS shared is the ink tint (#281E0C, never neutral
     grey), which tests/designTokens.test.ts locks.
   • motion — app/src/motion.ts already exports `cssTokens` as its CSS mirror, but that module
     imports react-native at runtime so the generator cannot load it. Mirrored by hand. ---- */
:root {
  /* ink-tinted depth (#281E0C on cream) — never neutral grey */
  --shadow-raised:   0 1px 2px rgba(40,30,12,0.08);
  --shadow-card:     0 8px 16px rgba(40,30,12,0.10), 0 1px 2px rgba(40,30,12,0.06);
  --shadow-floating: 0 12px 24px rgba(40,30,12,0.16), 0 2px 6px rgba(40,30,12,0.08);
  --shadow-pop:      0 18px 34px rgba(40,30,12,0.24), 0 4px 10px rgba(40,30,12,0.10);
  --glow-focus:      0 0 0 2px rgba(182,146,79,0.35);
  --glow-accent:     0 0 18px rgba(182,146,79,0.28);

  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-in: cubic-bezier(0.7, 0, 0.84, 0);
  --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
  --t-instant: 80ms; --t-fast: 140ms; --t-base: 220ms; --t-slow: 360ms;
  --press-scale: 0.98;
}
@media (prefers-reduced-motion: reduce) {
  :root { --t-instant: 0ms; --t-fast: 0ms; --t-base: 0ms; --t-slow: 0ms; --press-scale: 1; }
}

/* CM05F — opt-in adaptive itinerary. Existing .trip consumers keep their defaults.
   Stack first: labels and values remain paired in DOM order, and large text keeps
   the full row width. A container-relative, rem-based threshold permits compact
   rows only when there is room relative to the user's text size. Browsers without
   container queries retain the stacked layout. Controller-set display:flex on
   optional rows is preserved; this modifier only changes their direction/sizing. */
.trip[data-layout="adaptive"] {
  container-type: inline-size;
  container-name: driven-itinerary;
}
.trip[data-layout="adaptive"] .row {
  flex-direction: column;
  align-items: stretch;
  gap: var(--s-sm);
}
.trip[data-layout="adaptive"] .k {
  flex: none;
  min-width: 0;
  max-width: none;
  white-space: normal;
}
.trip[data-layout="adaptive"] .v {
  flex: none;
  min-width: 0;
  text-align: left;
  overflow-wrap: anywhere;
}
@container driven-itinerary (min-width: 18rem) {
  .trip[data-layout="adaptive"] .row {
    flex-direction: row;
    column-gap: var(--s-md);
  }
  .trip[data-layout="adaptive"] .k { flex: 0 0 4.5rem; }
  .trip[data-layout="adaptive"] .v { flex: 1; text-align: right; }
}
