/* ============================================================================
   WeiiGo — Daybreak (Navy & Gold) brand stylesheet  (WYG-322)
   Palette mirrors the app's Colors.xaml + docs/design-system.md.
   ========================================================================== */

/* ── Self-hosted fonts (privacy-friendly; no third-party requests) ─────────── */
/* Audit finding 7.3 — LATIN-SUBSET builds. The full-glyph originals are still on disk
   under their old names, so a rollback is reverting the eight urls below and nothing else.

     Work Sans, 5 weights    307,304 -> 152,664 bytes   (50%)
     Instrument Serif italic  27,968 ->  25,092 bytes   (90% — a 377-glyph face to begin with)
     IBM Plex Mono, 2 weights  79,312 ->  44,104 bytes   (56%)
     ─────────────────────────────────────────────────
     8 faces                  414,584 -> 221,860 bytes   (53%)

   🔑 THE SIGNAL REDESIGN REPLACED Inter + Playfair WITH THESE, AND THE LANDING PATH GOT
   LIGHTER RATHER THAN HEAVIER: the previous shipped set (5 Inter + 2 Playfair) was 264,116
   bytes across 7 faces; this is 221,860 across 8, so a first visit is 42,256 bytes SMALLER
   despite carrying one more face. Measured, not estimated — Inter and Playfair remain in git
   history if the direction is ever reverted.

   ⚠️ THE COVERAGE IS THE RISK, NOT THE SAVING, and it was verified rather than assumed:
   each font's cmap was read BEFORE subsetting and intersected with every codepoint the
   swept content of Waygo.Web + Waygo.Core actually uses; that intersection was named
   explicitly in the subset command and re-read from the cmap AFTERWARDS. All present, on all
   eight faces (602 codepoints on each Work Sans weight, 508 on IBM Plex Mono, 322 on
   Instrument Serif — that last is lower because the face itself carries only 377 glyphs). OS/2 + hhea metrics and the family names
   are byte-identical before and after, so no line height moves.

   🔑 WHY THE LATIN BLOCKS ARE GENEROUS AND THE OTHERS ARE GONE ENTIRELY: font fallback is
   per-CHARACTER, so PARTIAL coverage of a script is worse than none — a face carrying
   B-u-c-r-e-t-i but not ș/ț renders "București" split across two typefaces mid-word.
   Latin therefore covers Latin-1 + Extended-A + the precomposed half of Extended-B +
   Extended Additional (Vietnamese), because the site's CHROME is en-US but its DATA is
   worldwide place names that no source sweep can enumerate. Greek, Cyrillic, CJK and emoji
   are dropped wholesale, which falls back cleanly on whole words. ✅ Measured, not assumed:
   ✦ ✈ ✅ ⏰ ＋ and every emoji were never in these faces' cmaps to begin with and already fell
   back before this change — subsetting cannot make those worse. ★ ☆ ✓ ⚠ ⌫ ฿ π were, and
   are kept.

   ⛔ Deliberately NO `unicode-range` descriptor. It would let the browser skip a download
   the page has no characters for, but a range that disagrees with the file's real cmap
   hides glyphs that ARE present — a silent, per-character failure for a saving the
   per-glyph fallback already gets us.

   🔑 WYG-1841 — THE FULL-GLYPH `*.woff2` FILES BESIDE THESE ARE BUILD INPUT, NOT DEAD WEIGHT.
   The kept set is the documented blocks INTERSECTED with what each original actually carries,
   so they are the SOURCE these are derived from, not superseded copies of them. Delete them
   and a wider subset can no longer be produced and these faces cannot be reproduced at all.
   (The WYG-1834 review proposed removing them as "superseded ~754 KB"; they are not.)

   Regenerate or verify with `scripts/subset-web-fonts.py` — it derives the used set,
   intersects with each cmap, subsets to the blocks PLUS that intersection, then re-reads the
   cmap and asserts. `--check` verifies these files without writing.
   ⚠️ This pointer used to read "scripts under the audit's Phase 2 notes", and no such script
   was ever committed — the recipe existed only as this prose. */
@font-face { font-family: 'Work Sans'; font-weight: 400; font-display: swap; src: url('/fonts/WorkSans-Regular.latin.woff2') format('woff2'); }
@font-face { font-family: 'Work Sans'; font-weight: 500; font-display: swap; src: url('/fonts/WorkSans-Medium.latin.woff2') format('woff2'); }
@font-face { font-family: 'Work Sans'; font-weight: 600; font-display: swap; src: url('/fonts/WorkSans-SemiBold.latin.woff2') format('woff2'); }
@font-face { font-family: 'Work Sans'; font-weight: 700; font-display: swap; src: url('/fonts/WorkSans-Bold.latin.woff2') format('woff2'); }
/* 800 is NOT a Signal weight — the design's heaviest is 700. It ships because 52 existing
   rules (mostly /app chrome) already ask for it, and a missing face renders as SYNTHETIC
   bold over the 700, which is visibly worse than either real weight. */
@font-face { font-family: 'Work Sans'; font-weight: 800; font-display: swap; src: url('/fonts/WorkSans-ExtraBold.latin.woff2') format('woff2'); }
/* Signal: ONE italic serif word per page ("together." on Home, "careful." on About) and
   nowhere else. 400 italic is the only face this family ships and the only one used. */
@font-face { font-family: 'Instrument Serif'; font-style: italic; font-weight: 400; font-display: swap; src: url('/fonts/InstrumentSerif-Italic.latin.woff2') format('woff2'); }
/* Eyebrows, footer column headings, PRO chips, "Last updated". */
@font-face { font-family: 'IBM Plex Mono'; font-weight: 400; font-display: swap; src: url('/fonts/IBMPlexMono-Regular.latin.woff2') format('woff2'); }
@font-face { font-family: 'IBM Plex Mono'; font-weight: 500; font-display: swap; src: url('/fonts/IBMPlexMono-Medium.latin.woff2') format('woff2'); }

/* ── Design tokens ──────────────────────────────────────────────────────────*/
:root {
  /* ── Signal (1b) palette ────────────────────────────────────────────────────
     The redesign inverts the old proportion: white and pale-sky are the page base,
     navy is a deliberate structural panel used two or three times per page, and gold
     is the single action colour. The generic names below (--navy, --ink, --mist, --gold)
     are RE-POINTED rather than duplicated, so /app inherits the same palette instead of
     the site and the trip planner drifting into two blues.
     ⚠️ --blue is deliberately KEPT and is still /app's primary action. Signal retires blue
     as an action colour on the MARKETING pages only; /app has had no design pass. */
  --navy: #0E2A52;
  --navy-600: #123A74;
  --navy-deep: #0B2140;
  --navy-hover: #0A2144;
  --body-on-navy: #C7D2E6;
  --body-strong: #3F4A58;
  --muted-2: #8A94A3;
  --disabled: #AAB3C0;
  --gold-hover: #A97624;
  --gold-light: #F3D18B;
  --gold-ink: #1A1206;
  --sky: #F2F6FC;
  --sky-border: #DFE7F2;
  --cream: #F7F4EA;
  --cream-border: #E7E1D3;
  --line: #DFE4EA;
  --line-soft: #EEF1F5;
  --input-border: #D3DDEC;
  --error: #B3261E;
  --page-top: linear-gradient(180deg, #F2F6FC 0%, #FFFFFF 100%);
  /* Primary action (blue) */
  --blue: #1D4ED8;
  --blue-bright: #5B8DEF;
  --blue-deep: #122C7A;
  --on-primary: #FFFFFF;
  /* Accent gold */
  --gold: #C08A2E;
  --gold-bright: #DCB152;
  --gold-soft: #FBF1D9;
  /* ⚠️ SIGNAL DEVIATION, AND IT IS AN ACCESSIBILITY ONE. The handoff puts eyebrows in
     --gold (#C08A2E) at 10–11px. Measured, that is 3.04:1 on white — AA-large only, so it
     fails for text under ~18.66px, which is every eyebrow the design draws. --gold-text is
     5.37:1 on white and 4.95:1 on sky and reads as the same gold at eyebrow size.
     RULE: --gold for FILLS, borders, pills and large accents; --gold-text for small TEXT. */
  --gold-text: #8C6312;
  --on-accent: #0C2347;
  /* WYG-828: the app's colorful category palette (Home/Tools/Profile icon tiles).
     Canonical set for the site's colored feature-card / row icon tiles. */
  --cat-blue: #2F6DF6;   --cat-blue-soft: rgba(47,109,246,.13);
  --cat-amber: #E39A16;  --cat-amber-soft: rgba(227,154,22,.14);
  --cat-green: #1FA155;  --cat-green-soft: rgba(31,161,85,.13);
  --cat-purple: #7B5CF0; --cat-purple-soft: rgba(123,92,240,.13);
  --cat-red: #E0455A;    --cat-red-soft: rgba(224,69,90,.12);
  /* Neutrals / surfaces */
  --paper: #FFFFFF;
  --surface-wash: #F2F6FC;
  --slate: #EEF3FA;
  --slate-2: #E4EBF5;
  --bone: #F1F4F9;
  --ink: #0D1622;        /* primary text (14.98:1) */
  --mist: #4C5765;       /* secondary text (AA 5.4:1) */
  --text-tertiary: #6B7787;
  --hairline: #DFE4EA;
  --hairline-strong: #D3DDEC;
  /* Feedback */
  --success: #1F9D57;
  --success-text: #147A43;
  --success-soft: #E3F4EA;
  --danger: #C53A28;
  --danger-text: #B0341F;
  --danger-soft: #FBE7E3;
  --warning-text: #7A5212;
  --warning-soft: #FCEFD0;
  /* Type */
  --font-sans: 'Work Sans', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  /* Signal has no serif heading voice — headings are Work Sans 700. --font-display is kept
     as a token because /app still asks for it, and it now resolves to the same family so the
     site and the trip planner cannot drift into two typefaces. */
  --font-display: 'Work Sans', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  /* The one-accent-word device. Never a heading font. */
  --font-accent: 'Instrument Serif', Georgia, 'Times New Roman', serif;
  --font-mono: 'IBM Plex Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
  /* Spacing / radii / shadow */
  --container: 1140px;
  --radius-sm: 8px;
  --radius: 14px;
  --radius-lg: 22px;
  --shadow-sm: 0 1px 2px rgba(11,37,80,.06), 0 1px 3px rgba(11,37,80,.10);
  --shadow: 0 6px 18px rgba(11,37,80,.10);
  --shadow-lg: 0 18px 48px rgba(11,37,80,.16);
  --header-h: 68px;

  /* ── Plan palette (WYG-1420) ─────────────────────────────────────────────
     The /app trip-management section is a deliberate hybrid: the site's Daybreak
     navy/gold chrome carrying the MOBILE APP's Plan-a-Trip / Trip-Itinerary
     component vocabulary. These mirror Waygo.App's Colors.xaml Plan* tokens
     verbatim so the web and the app never render the same component differently.

     Two blues are intentional and must stay split: --blue (#1D4ED8) is the site's
     single big-CTA primary (login, "Generate with Janet"); --plan-blue (#2B4BE0)
     is the in-app component blue (chips, modals, selected states, user bubbles).
     Violet = Janet/AI — a mobile convention this token set brings to the web. */
  /* Plan surface / ink */
  --plan-surface: #F5F8FE;
  --plan-ink: #14203C;
  --plan-muted: #5B6B8C;
  --plan-input-fill: #EEF3FB;
  --plan-card-stroke: #E3E9F5;
  --plan-control-stroke: #DCE4F2;
  /* Plan blue (in-app components) */
  --plan-blue: #2B4BE0;
  --plan-blue-pressed: #1E38B8;
  --plan-blue-tint: #E7EDFC;
  --plan-blue-dashed: #9DB4F2;
  /* Violet — Janet / AI */
  --plan-violet: #7857E0;
  --plan-violet-deep: #5B36C4;
  --plan-violet-tint: #EEEAFC;
  --plan-violet-border: #E0D6F8;
  --plan-violet-chip: #8A6DF0;
  --plan-violet-chip-text: #C9B8FA;
  /* Teal — dates */
  --plan-teal: #0F9B8E;
  --plan-teal-dark: #0B7268;
  --plan-teal-tint: #DFF4F1;
  --plan-teal-stroke: #B5E0DA;
  /* Coral — travelers */
  --plan-coral: #E0603F;
  --plan-coral-tint: #FCE9E2;
  --plan-coral-stroke: #F0C4B4;
  --plan-coral-sub: #B5654A;
  /* Amber — eyebrows / price markers / comfort */
  --plan-amber: #B8790B;
  --plan-amber-stroke: #E3C77E;
  --plan-price: #E9A13B;
  /* Green — selected day / SAFE ring */
  --plan-green: #3E9C57;
  --plan-green-tint: #E3F4E7;
  --plan-green-stroke: #B7E0C2;
  --plan-green-ink: #215C33;
  --plan-green-track: #CDE7CF;
  /* Dark day bar */
  --plan-daybar-from: #16294A;
  --plan-daybar-to: #0F1B33;
  --plan-daybar-sub: #AFC0E2;
  /* Status dots (trip pills) */
  --plan-status-confirmed: #4ADE80;
  --plan-status-planning: #5B8DEF;
  --plan-status-tentative: #DCB152;
  /* Shell */
  --app-sidebar-w: 232px;
}

/* ── Reset / base ───────────────────────────────────────────────────────────*/
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
body {
  margin: 0;
  font-family: var(--font-sans);
  font-size: 1rem;
  line-height: 1.6;
  color: var(--ink);
  background: var(--paper);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
body.nav-open { overflow: hidden; }
img, svg, video { max-width: 100%; height: auto; display: block; }
a { color: var(--blue); text-decoration: none; }
a:hover { text-decoration: underline; }
h1, h2, h3, h4 { line-height: 1.15; color: var(--navy); margin: 0 0 .5em; font-weight: 800; letter-spacing: -.02em; }
h1 { font-size: clamp(2.1rem, 5vw, 3.4rem); }
h2 { font-size: clamp(1.6rem, 3.5vw, 2.4rem); }
h3 { font-size: 1.25rem; }
p { margin: 0 0 1rem; }
.lead { font-size: 1.18rem; color: var(--mist); }
.display { font-family: var(--font-display); }

/* ── Accessibility helpers ──────────────────────────────────────────────────*/
.visually-hidden {
  position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0;
}
.skip-link {
  position: absolute; left: 12px; top: -48px; z-index: 1000;
  background: var(--navy); color: #fff; padding: 10px 16px; border-radius: var(--radius-sm);
  transition: top .15s ease;
}
.skip-link:focus { top: 12px; text-decoration: none; }
:focus-visible { outline: 3px solid var(--blue-bright); outline-offset: 2px; border-radius: 4px; }

/* ── Layout primitives ──────────────────────────────────────────────────────*/
.container { width: 100%; max-width: var(--container); margin-inline: auto; padding-inline: 20px; }
.section { padding-block: clamp(48px, 8vw, 96px); }
.section--wash { background: var(--surface-wash); }
.section--navy { background: var(--navy); color: #EAF0FB; }
.section--navy h1, .section--navy h2, .section--navy h3 { color: #fff; }

/* WYG-1718: the landing page's white background carries the WeiiGo shield
   faintly instead of being flat #FFFFFF.

   Painted by a FIXED PSEUDO-ELEMENT rather than a background on `body`, for two
   reasons: it stays scoped to the one page that opts in via `.watermarked`, and
   the other way to hold a mark still while the page scrolls —
   `background-attachment: fixed` — is the one iOS Safari renders badly.

   `z-index: -1` puts the layer behind all in-flow content while still painting
   above the root canvas, so it IS visible. It only works because `.watermarked`
   deliberately establishes NO stacking context (no z-index, no transform, no
   filter, no opacity) — add one and the layer gets trapped behind its own
   wrapper and the watermark silently disappears.

   Only the transparent `.section` bands reveal it: `.hero`, `.section--wash`
   and `.section--navy` paint their own opaque backgrounds over the top. That
   intermittency is what makes it read as a watermark rather than wallpaper.

   The art is already at opacity .13 inside the SVG, and its opaque white
   backing rect was stripped on the way into wwwroot, so tone is controlled here
   by `var(--paper)` showing through — not by an `opacity` on this element,
   which would fade the white too and re-introduce the stacking-context trap
   described above. */
.watermarked::before {
  content: '';
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  /* WYG-1844: the URL arrives from MARKUP as --watermark-shield, so it can be the
     FINGERPRINTED one. @Assets[] cannot reach inside a stylesheet, so referenced from
     here the file served max-age=3600, must-revalidate — revalidated hourly, forever,
     for a decorative asset that never changes.

     ⚠️ The fallback is load-bearing, not politeness. `background` is a shorthand: if
     --watermark-shield were undefined and had no fallback, the whole declaration would
     be invalid at computed-value time and the element would lose var(--paper) TOO,
     not merely the shield. Any future page that adds .watermarked without setting the
     property still paints correctly — just on the hourly-revalidated URL. */
  background: var(--paper) var(--watermark-shield, url('../img/watermark-shield.svg')) no-repeat center / auto min(88vh, 940px);
}

/* Narrow viewports: height-driven sizing would push the shield wider than the
   screen and crop it, so fit it to whichever axis runs out first. */
@media (max-width: 640px) {
  .watermarked::before { background-size: contain; }
}

/* Decorative only — never worth a print. */
@media print {
  .watermarked::before { display: none; }
}
.section__head { max-width: 720px; margin: 0 auto clamp(28px, 4vw, 48px); text-align: center; }
.section__eyebrow { color: var(--gold-text); font-weight: 700; text-transform: uppercase; letter-spacing: .08em; font-size: .82rem; margin-bottom: .5rem; }
/* WYG-826: eyebrows on the navy page-hero use the brighter gold (readable on navy). */
.page-hero .section__eyebrow { color: var(--gold-bright); }
/* WYG-826: off-screen honeypot field shared by the anti-spam forms. */
.hp { position: absolute; left: -9999px; }
.grid { display: grid; gap: 24px; }
.grid--2 { grid-template-columns: repeat(2, 1fr); }
.grid--3 { grid-template-columns: repeat(3, 1fr); }
.grid--4 { grid-template-columns: repeat(4, 1fr); }
.text-center { text-align: center; }
.stack > * + * { margin-top: 1rem; }

/* ── Buttons ────────────────────────────────────────────────────────────────*/
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .5rem;
  font: inherit; font-weight: 600; line-height: 1; cursor: pointer;
  padding: 14px 24px; border-radius: 999px; border: 2px solid transparent;
  transition: transform .08s ease, background .15s ease, box-shadow .15s ease, color .15s ease;
  text-decoration: none; white-space: nowrap;
}
.btn:hover { text-decoration: none; }
/* Signal: buttons do not lift. `transform: none`, background-only transition. */
.btn:active { transform: none; }
.btn:focus-visible { outline: none; box-shadow: 0 0 0 3px rgba(192,138,46,.45); }
.btn--primary { background: var(--navy); color: #fff; }
.btn--primary:hover { background: var(--navy-hover); }
.btn--secondary { background: #fff; color: var(--ink); border-color: #CDD6E2; }
.btn--secondary:hover { border-color: var(--navy); background: #fff; }
.btn--gold { background: var(--gold); color: var(--gold-ink); }
.btn--gold:hover { background: var(--gold-hover); color: var(--gold-ink); }
/* The header pill is the lighter gold on navy; the page CTAs are the saturated one. */
.btn--gold-light { background: var(--gold-light); color: var(--gold-ink); }
.btn--gold-light:hover { background: var(--gold); color: var(--gold-ink); }
/* ⚠️ /app keeps BLUE as its primary action. Signal retires blue on the marketing pages only —
   the trip planner has had no design pass, and silently restyling its primary action would be
   a redesign of a section the handoff never saw. */
.app-shell .btn--primary { background: var(--blue); color: var(--on-primary); }
.app-shell .btn--primary:hover { background: var(--blue-deep); }
.btn--ghost { background: transparent; color: var(--navy); }
.btn--ghost:hover { background: rgba(255,255,255,.12); }
.btn--on-navy { background: #fff; color: var(--navy); }
.btn--on-navy:hover { background: var(--gold-soft); }
.btn--lg { padding: 16px 30px; font-size: 1.05rem; }
.btn--block { width: 100%; }

/* ── Site header / nav ──────────────────────────────────────────────────────*/
/* Signal: the header is NAVY on every page, Home included — it is no longer a white bar,
   and the pale-blue pill active state is replaced by white/600 on the current route. */
.site-header {
  position: sticky; top: 0; z-index: 100; background: var(--navy);
  border-bottom: 1px solid transparent;
  transition: box-shadow .2s ease;
}
.site-header.is-scrolled { box-shadow: 0 1px 0 rgba(255,255,255,.10); }
.site-header__inner { display: flex; align-items: center; gap: 16px; min-height: var(--header-h); padding-block: 18px; }
.brand { display: inline-flex; align-items: center; gap: 10px; color: #fff; }
.brand:hover { text-decoration: none; }
.brand__shield { height: 26px; width: auto; }
/* Set in TYPE, not an image — the wordmark svg has an opaque background and would render as a
   white box on navy (the same reason the footer has always used type here). */
.brand__word { font-size: 19px; font-weight: 700; letter-spacing: -.02em; color: #fff; }
.brand__word-accent { color: var(--gold-light); }
.nav { margin-left: auto; display: flex; align-items: center; gap: 20px; }
.nav__links { display: flex; align-items: center; gap: 20px; list-style: none; margin: 0; padding: 0; }
.nav__links a { color: var(--body-on-navy); font-weight: 400; font-size: 14px; padding: 4px 0; border-radius: 0; }
.nav__links a:hover { color: #fff; background: none; text-decoration: none; }
.nav__links a.active { color: #fff; font-weight: 600; background: none; }
.nav__cta { display: flex; align-items: center; gap: 16px; margin-left: 4px; }
.nav__cta .nav__login { color: #fff; font-weight: 500; font-size: 14px; }
.nav__cta .nav__login:hover { text-decoration: underline; }
.nav__user { color: var(--body-on-navy); font-size: 14px; }
.nav-toggle {
  display: none; margin-left: auto; width: 44px; height: 44px; border: 1px solid rgba(255,255,255,.30);
  background: transparent; border-radius: var(--radius-sm); cursor: pointer; align-items: center; justify-content: center;
}
.nav-toggle span, .nav-toggle span::before, .nav-toggle span::after {
  content: ''; display: block; width: 20px; height: 2px; background: #fff; position: relative; transition: .2s;
}
.nav-toggle span::before { position: absolute; top: -6px; }
.nav-toggle span::after { position: absolute; top: 6px; }

/* ── Footer ─────────────────────────────────────────────────────────────────*/
.site-footer { background: var(--navy-deep); color: #A9BCD8; padding-block: 56px 40px; }
.site-footer a { color: #A9BCD8; font-size: 14.5px; }
.site-footer a:hover { color: var(--gold-light); text-decoration: none; }
.site-footer p { font-size: 14.5px; color: #A9BCD8; }
.footer-grid { display: grid; grid-template-columns: 1.2fr 1fr 1fr 1fr; gap: 40px; }
.footer-col h4 {
  color: #fff; font-family: var(--font-mono); font-size: 10px; font-weight: 400;
  text-transform: uppercase; letter-spacing: .16em; margin-bottom: 14px;
}
.footer-col ul { list-style: none; margin: 0; padding: 0; }
.footer-col li { margin-bottom: 10px; }
.footer-brand img { height: 40px; filter: brightness(0) invert(1); margin-bottom: 14px; }
/* Shield + name lockup (WYG-690). The wordmark SVG has an opaque background, so the old
   brightness/invert filter rendered it as a solid white box on the navy footer — the footer
   uses the shield + styled text instead. The shield keeps its own colors (no filter). */
.footer-brand__lockup { display: flex; align-items: center; gap: 10px; margin-bottom: 14px; }
.footer-brand__lockup img { margin-bottom: 0; }
.footer-brand img.footer-brand__shield { height: 36px; filter: none; }
.footer-brand__name { font-size: 1.45rem; font-weight: 800; color: #fff; letter-spacing: -.01em; }
.footer-brand__name-accent { color: var(--gold-bright); }
.footer-bottom { display: flex; flex-wrap: wrap; gap: 12px 24px; justify-content: space-between; align-items: center;
  margin-top: 40px; padding-top: 24px; border-top: 1px solid rgba(255,255,255,.12); font-size: .88rem; color: #92A3C2; }
.footer-social { display: flex; gap: 12px; }

/* ── Hero ───────────────────────────────────────────────────────────────────*/
.hero { position: relative; overflow: hidden; background: linear-gradient(160deg, var(--navy) 0%, var(--navy-600) 60%, var(--navy-deep) 100%); color: #EAF0FB; }
.hero__inner { display: grid; grid-template-columns: 1.1fr .9fr; gap: 48px; align-items: center; padding-block: clamp(56px, 9vw, 110px); }
.hero h1 { color: #fff; }
.hero__lead { font-size: 1.2rem; color: #C8D6F0; max-width: 38ch; }
.hero__cta { display: flex; flex-wrap: wrap; gap: 14px; margin-top: 28px; }
.hero__visual { position: relative; }
.hero__visual img { border-radius: var(--radius-lg); box-shadow: var(--shadow-lg); }
.hero__mock { max-width: 300px; margin-inline: auto; border: 1px solid rgba(255,255,255,.18);
  border-radius: 36px; box-shadow: var(--shadow-lg); overflow: hidden; }
.hero__mock img { width: 100%; height: auto; display: block; }

/* ── Shield brand mark (WYG-690) ────────────────────────────────────────────*/
.hero__emblem { height: clamp(96px, 12vw, 130px); width: auto; margin-bottom: 20px;
  filter: drop-shadow(0 10px 24px rgba(2, 8, 23, .45)); }
.cta-shield { height: 72px; width: auto; margin-bottom: 14px;
  filter: drop-shadow(0 6px 18px rgba(2, 8, 23, .4)); }
.about-shield { text-align: center; margin: 36px 0 8px; }
.about-shield img { height: 140px; width: auto; margin-inline: auto; }

/* ── Cards ──────────────────────────────────────────────────────────────────*/
.card { background: var(--paper); border: 1px solid var(--hairline); border-radius: var(--radius); padding: 26px; box-shadow: var(--shadow-sm); }
.card--link { transition: transform .12s ease, box-shadow .15s ease; }
a.card--link:hover, .card--link:hover { transform: translateY(-3px); box-shadow: var(--shadow); text-decoration: none; }
.card__icon { width: 48px; height: 48px; border-radius: 12px; display: grid; place-items: center; background: var(--gold-soft); color: var(--gold-text); font-size: 1.4rem; margin-bottom: 16px; }
/* WYG-828: per-category colored icon tiles (matches the app's icon-tile language). */
.card__icon--blue   { background: var(--cat-blue-soft); }
.card__icon--amber  { background: var(--cat-amber-soft); }
.card__icon--green  { background: var(--cat-green-soft); }
.card__icon--purple { background: var(--cat-purple-soft); }
.card__icon--red    { background: var(--cat-red-soft); }
.card h3 { color: var(--navy); }
.card p { color: var(--mist); margin-bottom: 0; }

/* feature row (alternating) */
.feature-row { display: grid; grid-template-columns: 1fr 1fr; gap: 48px; align-items: center; }
.feature-row + .feature-row { margin-top: clamp(40px, 6vw, 80px); }
.feature-row--reverse .feature-row__media { order: -1; }
.feature-row__media { background: var(--slate); border: 1px solid var(--hairline); border-radius: var(--radius-lg); aspect-ratio: 16/10; display: grid; place-items: center; color: var(--text-tertiary); }
/* media holding a real app screenshot (portrait phone) — let the shot drive the height */
.feature-row__media--shot { aspect-ratio: auto; padding: 32px 0; overflow: hidden;
  background: radial-gradient(120% 120% at 50% 0%, var(--gold-soft), transparent 60%), var(--slate); }
.feature-row__media--shot img { display: block; width: auto; height: auto; max-width: 64%; max-height: 540px;
  margin-inline: auto; border-radius: 32px; border: 1px solid var(--hairline); box-shadow: var(--shadow-lg); }

/* ── Store badges ───────────────────────────────────────────────────────────*/
.store-badges { display: flex; flex-wrap: wrap; gap: 14px; align-items: center; }
.store-badge { display: inline-flex; align-items: center; gap: 12px; padding: 10px 18px; border-radius: 12px;
  background: var(--navy); color: #fff; min-width: 200px; }
.store-badge:hover { background: var(--navy-deep); text-decoration: none; }
.store-badge svg, .store-badge .store-badge__glyph { width: 28px; height: 28px; flex: none; }
/* WYG-2016: the badge is DRAWN as two lines — sub-line over store name — and a label that
   wraps is a different badge. So the text never wraps; where a badge has less room than its
   label needs, the fix is to give it the room (see `.dl-stores .store-badge`), never to let the
   words fold. Measured on /download: with wrapping allowed the Apple badge rendered on FOUR
   lines at 94px; with nowrap both badges are 57px, the footer's height. */
.store-badge__sub { font-size: .72rem; line-height: 1; opacity: .85; display: block; white-space: nowrap; }
.store-badge__name { font-size: 1.12rem; font-weight: 700; line-height: 1.15; white-space: nowrap; }
.store-badge--disabled { background: var(--slate-2); color: var(--mist); cursor: default; }
.store-badge--disabled:hover { background: var(--slate-2); }
.store-badge__soon { font-size: .68rem; font-weight: 700; text-transform: uppercase; letter-spacing: .05em;
  background: var(--gold-soft); color: var(--gold-text); padding: 2px 6px; border-radius: 5px; margin-left: auto; }
.qr { background: #fff; border: 1px solid var(--hairline); border-radius: var(--radius); padding: 14px; width: max-content; }
.qr img, .qr svg { width: 160px; height: 160px; }

/* ── Pricing ────────────────────────────────────────────────────────────────*/
.price-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 24px; align-items: stretch; }
.price-card { display: flex; flex-direction: column; background: var(--paper); border: 1px solid var(--hairline); border-radius: var(--radius-lg); padding: 30px; box-shadow: var(--shadow-sm); position: relative; }
.price-card--featured { border-color: var(--gold); box-shadow: var(--shadow); }
.price-card__flag { position: absolute; top: -13px; left: 50%; transform: translateX(-50%); background: var(--gold); color: var(--on-accent); font-weight: 700; font-size: .75rem; text-transform: uppercase; letter-spacing: .05em; padding: 5px 14px; border-radius: 999px; }
.price-card__name { font-size: 1.3rem; font-weight: 800; color: var(--navy); }
.price-card__price { font-size: 2.4rem; font-weight: 800; color: var(--navy); margin: 8px 0 2px; }
.price-card__price small { font-size: .95rem; font-weight: 500; color: var(--mist); }
.price-card__tagline { color: var(--mist); min-height: 2.6em; }
.price-card ul { list-style: none; margin: 18px 0 24px; padding: 0; flex: 1; }
.price-card li { display: flex; gap: 10px; padding: 7px 0; color: var(--ink); }
.price-card li::before { content: '✓'; color: var(--success-text); font-weight: 800; }

/* ── Monthly/Yearly billing toggle (WYG-703) — CSS-only, no JS ───────────────*/
.billing-radio { position: absolute; opacity: 0; pointer-events: none; }
.billing-toggle { display: flex; width: fit-content; gap: 4px; margin: 0 auto 28px; padding: 4px;
  background: var(--slate); border-radius: 999px; }
.billing-toggle label { padding: 8px 22px; border-radius: 999px; font-weight: 600;
  color: var(--mist); cursor: pointer; user-select: none; transition: background .15s, color .15s; }
.billing-toggle__save { font-size: .72rem; font-weight: 700; color: var(--gold-text);
  background: var(--gold-soft); border-radius: 999px; padding: 1px 7px; margin-left: 4px; }
/* the toggle sits centered; the section container is text-centered where used */
#billing-monthly:checked ~ .billing-toggle label[for="billing-monthly"],
#billing-yearly:checked ~ .billing-toggle label[for="billing-yearly"] {
  background: var(--paper); color: var(--navy); box-shadow: var(--shadow-sm); }
/* Price swap: monthly shown by default; the yearly radio flips it. Free (.price--always) is exempt.
   🔴 WYG-1936: these were `#billing-yearly:checked ~ .price-grid …` and matched NOTHING, so the
   yearly price was unreachable — `.price--yearly` below hid it and no rule ever unhid it.

   `~` is the general SIBLING combinator, so it only reaches elements sharing the radio's parent.
   WYG-703 wrote these when the radios and the cards were siblings; the Signal redesign
   (574596eb) moved the radios into `.price-head`, inside the header SECTION, leaving the cards in
   the next section's own `.container`. Measured on the running page: the selector matched 0
   elements. Nothing failed — the label pill still highlighted, because `.billing-toggle` IS a
   sibling of the radios, so the toggle looked alive while the prices never moved. That is why the
   redesign restated every toggle rule below and not these two: the breakage it caused was the one
   its own screenshot could not show.

   `:has()` reads the checked state from anywhere in the document, so it does not care where the
   markup puts the radio. Already used in this stylesheet (see `.section:has(…)`), so no new
   browser-support decision. */
.price--yearly { display: none; }
body:has(#billing-yearly:checked) .price--monthly { display: none; }
body:has(#billing-yearly:checked) .price--yearly { display: inline; }

/* ── Plan comparison table (WYG-691) ────────────────────────────────────────*/
.compare-wrap { overflow-x: auto; background: var(--paper); border: 1px solid var(--hairline);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-sm); }
.compare { width: 100%; border-collapse: collapse; min-width: 620px; }
.compare th, .compare td { padding: 12px 18px; text-align: center; border-bottom: 1px solid var(--hairline); }
.compare thead th { background: var(--navy); color: #fff; font-size: .95rem; }
.compare thead th:first-child { border-top-left-radius: var(--radius-lg); }
.compare thead th:last-child { border-top-right-radius: var(--radius-lg); }
.compare tbody th[scope="row"] { text-align: left; font-weight: 500; color: var(--ink); }
.compare__group th { text-align: left; background: var(--surface-wash); color: var(--navy);
  font-size: .8rem; font-weight: 800; text-transform: uppercase; letter-spacing: .06em; }
.compare__banner td { background: var(--gold-soft); color: var(--warning-text); font-weight: 600;
  text-align: left; }
.compare__yes { color: var(--success-text); font-weight: 800; }
.compare__no { color: var(--text-tertiary); }

/* ── Tier badge chips (WYG-691) ─────────────────────────────────────────────*/
.tier-badge { display: inline-block; padding: 3px 10px; border-radius: 999px; font-size: .72rem;
  font-weight: 700; text-transform: uppercase; letter-spacing: .05em; vertical-align: middle; }
.tier-badge--free { background: var(--slate); color: var(--mist); }
.tier-badge--pro { background: rgba(29, 78, 216, .12); color: var(--blue); }

/* IAP disclosure under the store badges (WYG-691). The block wrapper keeps badges + caption
   stacked as ONE item inside the flex-row containers pages wrap around <StoreBadges>. */
.store-badges-block { display: inline-flex; flex-direction: column; align-items: center; }
.store-badges__iap { margin: 8px 0 0; font-size: .85rem; color: inherit; opacity: .75; text-align: center; }

/* ── Beta band (WYG-692) ────────────────────────────────────────────────────*/
.beta-band { display: flex; align-items: center; justify-content: space-between; gap: 28px;
  background: var(--gold-soft); border: 1px solid var(--gold); border-radius: var(--radius-lg);
  padding: clamp(24px, 4vw, 40px); }
.beta-band h2 { color: var(--navy); }
@media (max-width: 720px) {
  .beta-band { flex-direction: column; align-items: flex-start; }
  .beta-band .btn { width: 100%; }
}

/* ── Demo video (WYG-693) ───────────────────────────────────────────────────*/
.video-frame { max-width: 760px; margin-inline: auto; border-radius: var(--radius-lg);
  overflow: hidden; box-shadow: var(--shadow-lg); background: #000; line-height: 0; }
.video-frame video { width: 100%; height: auto; display: block; }

/* ── Forms ──────────────────────────────────────────────────────────────────*/
.form { max-width: 460px; }
.form--wide { max-width: 620px; }
.field { margin-bottom: 18px; }
.field label { display: block; font-weight: 600; color: var(--navy); margin-bottom: 6px; }
/* WYG-826: applies to hints anywhere (was scoped to .field, leaving standalone
   class="hint" elements unstyled). Paragraph hints get a touch more top space. */
.hint { font-size: .85rem; color: var(--mist); margin-top: 4px; }
p.hint { margin-top: 10px; }
.input, .textarea, select.input {
  width: 100%; font: inherit; color: var(--ink); background: #fff;
  border: 1.5px solid var(--hairline-strong); border-radius: var(--radius-sm); padding: 12px 14px;
}
.input:focus, .textarea:focus { border-color: var(--blue); outline: none; box-shadow: 0 0 0 3px rgba(91,141,239,.3); }
.textarea { min-height: 130px; resize: vertical; }
.validation-message, .field-error { color: var(--danger-text); font-size: .88rem; margin-top: 4px; display: block; }
/* WYG-1491: marketing-consent checkboxes on the account sign-up form.
   .checkbox overrides .field label's display:block — a consent line has to read as one
   sentence with its box, not a label stacked above a control. align-items:flex-start keeps
   the box on the FIRST line when the sentence wraps, which it does at phone widths. */
.field__optional { font-weight: 400; color: var(--mist); }
.field--consent { display: grid; gap: 10px; }
/* ⚠️ Must out-specify `.field label { display: block }` (0,0,1,1). A bare `.checkbox`
   (0,0,1,0) LOSES that fight and the row renders as a stacked block — caught only by
   reading the computed style in a browser, since the markup itself looks correct. */
.field--consent .checkbox {
  display: flex; align-items: flex-start; gap: 10px;
  font-weight: 400; color: var(--ink); line-height: 1.45; cursor: pointer;
  margin-bottom: 0;
}
.field--consent .checkbox input[type="checkbox"] { width: 18px; height: 18px; margin: 2px 0 0; flex: 0 0 auto; accent-color: var(--blue); }
.hint--consent { margin-top: 2px; }
.alert { padding: 12px 16px; border-radius: var(--radius-sm); margin-bottom: 18px; border: 1px solid; }
.alert--error { background: var(--danger-soft); border-color: var(--danger); color: var(--danger-text); }
.alert--success { background: var(--success-soft); border-color: var(--success); color: var(--success-text); }
.alert--info { background: var(--gold-soft); border-color: var(--gold); color: var(--warning-text); }
.auth-card { max-width: 460px; margin: clamp(32px,6vw,72px) auto; }
.auth-card .card { padding: 32px; }
/* WYG-826: one heading size across all auth cards (were inline 1.7rem / 1.8rem). */
.auth-card h1 { font-size: 1.7rem; }
.auth-switch { text-align: center; color: var(--mist); margin-top: 18px; }

/* ── FAQ accordion (native <details>) ───────────────────────────────────────*/
.faq { max-width: 760px; margin-inline: auto; }
.faq details { border: 1px solid var(--hairline); border-radius: var(--radius); background: #fff; margin-bottom: 12px; box-shadow: var(--shadow-sm); }
.faq summary { cursor: pointer; padding: 18px 20px; font-weight: 600; color: var(--navy); list-style: none; display: flex; justify-content: space-between; gap: 12px; align-items: center; }
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after { content: '+'; font-size: 1.4rem; color: var(--gold-text); line-height: 1; }
.faq details[open] summary::after { content: '−'; }
.faq details > div { padding: 0 20px 18px; color: var(--mist); }

/* ── Cookie consent ─────────────────────────────────────────────────────────*/
.cookie-consent { position: fixed; left: 16px; right: 16px; bottom: 16px; z-index: 200; max-width: 640px; margin-inline: auto;
  background: #fff; border: 1px solid var(--hairline-strong); border-radius: var(--radius); box-shadow: var(--shadow-lg);
  padding: 20px 22px; display: flex; flex-wrap: wrap; gap: 14px; align-items: center; }
/* WYG-2078: site.js hides the banner with the `hidden` attribute, and the `display: flex` above
   outranks the browser's own `[hidden] { display: none }` — so without this rule the banner never
   left the screen, and after a reload its buttons were not even wired. */
.cookie-consent[hidden] { display: none; }
.cookie-consent p { margin: 0; flex: 1 1 280px; color: var(--ink); font-size: .92rem; }
.cookie-consent .actions { display: flex; gap: 10px; margin-left: auto; }

/* ── Legal / prose ──────────────────────────────────────────────────────────*/
.prose { max-width: 760px; margin-inline: auto; }
.prose h2 { margin-top: 2em; }
.prose h3 { margin-top: 1.4em; }
.prose ul { padding-left: 1.2em; color: var(--ink); }
.prose li { margin-bottom: .4em; }
.prose .updated { color: var(--mist); font-size: .9rem; }
.toc { background: var(--surface-wash); border: 1px solid var(--hairline); border-radius: var(--radius); padding: 18px 22px; }
.toc ul { list-style: none; padding: 0; margin: 0; }
.toc li { margin-bottom: 6px; }

/* page hero (compact, for inner pages) */
.page-hero { background: linear-gradient(160deg, var(--navy) 0%, var(--navy-600) 100%); color: #EAF0FB; padding-block: clamp(40px,7vw,80px); }
.page-hero h1 { color: #fff; }
.page-hero p { color: #C8D6F0; max-width: 60ch; margin-inline: auto; }

.trust-strip { display: flex; flex-wrap: wrap; gap: 28px 48px; justify-content: center; align-items: center; color: var(--mist); }
.trust-strip strong { color: var(--navy); font-size: 1.6rem; display: block; }
/* WYG-828: tint each stat with a category color (Worldwide/languages/offline/safety). */
.trust-strip > div:nth-child(1) strong { color: var(--cat-green); }
.trust-strip > div:nth-child(2) strong { color: var(--cat-blue); }
.trust-strip > div:nth-child(3) strong { color: var(--cat-amber); }
.trust-strip > div:nth-child(4) strong { color: var(--cat-red); }

/* ── Responsive ─────────────────────────────────────────────────────────────*/
@media (max-width: 900px) {
  .hero__inner { grid-template-columns: 1fr; gap: 32px; }
  .hero__visual { order: -1; }
  .feature-row, .feature-row--reverse .feature-row__media { grid-template-columns: 1fr; order: 0; }
  .grid--3, .grid--4, .price-grid { grid-template-columns: repeat(2, 1fr); }
  .footer-grid { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 760px) {
  .nav-toggle { display: inline-flex; }
  .nav { position: fixed; inset: var(--header-h) 0 auto 0; background: #fff; border-bottom: 1px solid var(--hairline);
    flex-direction: column; align-items: stretch; gap: 0; padding: 12px 20px 20px; margin: 0;
    transform: translateY(-12px); opacity: 0; visibility: hidden; pointer-events: none; transition: .18s ease; box-shadow: var(--shadow); }
  /* visibility:hidden when closed also removes the links from the tab order on mobile (a11y). */
  .nav.is-open { transform: none; opacity: 1; visibility: visible; pointer-events: auto; }
  .nav__links { flex-direction: column; align-items: stretch; gap: 2px; }
  .nav__links a { padding: 12px; }
  .nav__cta { flex-direction: column; align-items: stretch; margin: 12px 0 0; }
  .nav__cta .btn { width: 100%; }
}
@media (max-width: 560px) {
  .grid--2, .grid--3, .grid--4, .price-grid, .footer-grid { grid-template-columns: 1fr; }
  .btn { width: 100%; }
  .hero__cta .btn, .store-badge { width: 100%; }
}

/* ── Reduced motion ─────────────────────────────────────────────────────────*/
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: .001ms !important; animation-iteration-count: 1 !important; transition-duration: .001ms !important; }
}

/* ============================================================================
   Redesign refinements (WYG-web-redesign) — a light, reversible layer on top of
   the existing Daybreak system. Adds editorial distinctiveness + a little depth
   without changing the component architecture. Delete this block to revert.
   ========================================================================== */

/* 1. Editorial display serif for the marketing hero + section headlines
      (Playfair Display is already self-hosted). Body, UI, legal prose stay Inter. */
.hero h1,
.page-hero h1,
.section__head h2 {
  font-family: var(--font-display);
  font-weight: 700;
  letter-spacing: -.005em;
  line-height: 1.08;
}
.hero h1 { font-size: clamp(2.3rem, 5.2vw, 3.6rem); }

/* 2. Hero depth: a soft gold glow behind the phone mock so the visual reads as a
      designed focal point rather than a flat screenshot. */
.hero__visual::before {
  content: '';
  position: absolute;
  inset: -10% -8%;
  z-index: 0;
  background: radial-gradient(58% 52% at 55% 42%, rgba(220,177,82,.24), transparent 72%);
  filter: blur(4px);
  pointer-events: none;
}
.hero__visual > * { position: relative; z-index: 1; }

/* 3. Trust strip: give it structure with hairline dividers so it reads as a band. */
.trust-strip { gap: 0 0; }
.trust-strip > div { padding: 6px 44px; position: relative; }
.trust-strip > div + div::before {
  content: '';
  position: absolute; left: 0; top: 50%; transform: translateY(-50%);
  width: 1px; height: 44px; background: var(--hairline-strong);
}
@media (max-width: 560px) {
  .trust-strip { gap: 18px 0; }
  .trust-strip > div { padding: 4px 0; }
  .trust-strip > div + div::before { display: none; }
}

/* 4. Section eyebrow: a touch more presence (small gold rule under the label). */
.section__head .section__eyebrow { display: inline-flex; align-items: center; gap: 10px; }
.section__head .section__eyebrow::after {
  content: ''; width: 26px; height: 2px; background: var(--gold-bright); border-radius: 2px;
}

/* 5. Kill the stray focus ring on the page headline. Blazor's <FocusOnNavigate>
      programmatically focuses the h1 (tabindex=-1) after each navigation for
      screen-reader users; that painted a visible 3px outline box around the main
      heading for everyone. A -1 heading is never keyboard-tabbed to, so hiding the
      VISIBLE ring keeps the a11y focus behaviour while removing the artifact. */
h1[tabindex="-1"]:focus,
h1[tabindex="-1"]:focus-visible { outline: none; }

/* ── Blazor framework UI (error + reconnect) ────────────────────────────────*/
#blazor-error-ui {
  color: #fff; background: var(--danger); position: fixed; bottom: 0; left: 0; right: 0;
  box-shadow: 0 -1px 2px rgba(0,0,0,.2); padding: 12px 20px; display: none; z-index: 1000;
}
#blazor-error-ui .dismiss { cursor: pointer; position: absolute; right: 14px; top: 10px; }
#blazor-error-ui .reload { color: #fff; text-decoration: underline; }
.blazor-error-boundary { background: var(--danger-soft); padding: 16px; border-radius: var(--radius-sm); color: var(--danger-text); }

/* ============================================================================
   /app — Trip management shell (WYG-1420, epic WYG-1419)
   Desktop-first per decision D3 (~1100px+); narrower viewports get the
   .app-narrow-notice below rather than a reflowed layout (responsive is a
   documented v1 follow-up).
   ========================================================================== */

/* ── Shell ────────────────────────────────────────────────────────────────*/
.app-shell { min-height: 100vh; display: flex; background: var(--plan-surface); }
.app-main { flex: 1; margin-left: var(--app-sidebar-w); min-width: 0; }

/* Screen containers. Widths are per-screen (Trips 1060 / Create 1080 / Itinerary 1000). */
.app-screen { margin: 0 auto; padding: 40px 36px 64px; animation: appFade .35s ease; }
.app-screen--trips { max-width: 1060px; }
.app-screen--create { max-width: 1080px; }
.app-screen--itinerary { max-width: 1000px; }
.app-screen--narrow { max-width: 720px; }

@keyframes appFade { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .app-screen { animation: none; } }

/* ── Sidebar ──────────────────────────────────────────────────────────────*/
.app-sidebar {
  width: var(--app-sidebar-w); flex: none; position: fixed; inset: 0 auto 0 0;
  background: linear-gradient(180deg, var(--navy) 0%, var(--navy-deep) 100%);
  display: flex; flex-direction: column; z-index: 30;
}
.app-sidebar__brand { display: flex; align-items: center; gap: 10px; padding: 22px 20px 18px; text-decoration: none; }
.app-sidebar__brand:hover { text-decoration: none; }
.app-sidebar__brand img { height: 32px; width: auto; }
/* The wordmark SVG has an opaque background (WYG-690) — the shield + styled text
   lockup is the established treatment on dark surfaces (same as the site footer). */
.app-sidebar__wordmark { font-size: 21px; font-weight: 800; letter-spacing: -.01em; color: #fff; }
.app-sidebar__wordmark span { color: var(--gold-bright); }

.app-nav { padding: 4px 12px; display: flex; flex-direction: column; gap: 4px; }
.app-nav__item {
  display: flex; align-items: center; gap: 11px; padding: 11px 12px; border-radius: 11px;
  border: none; background: transparent; text-align: left; cursor: pointer; width: 100%;
  font-family: inherit; font-size: 14.5px; font-weight: 500; color: #C8D6F0; text-decoration: none;
  transition: background .12s ease;
}
.app-nav__item:hover { background: rgba(255,255,255,.12); color: #C8D6F0; text-decoration: none; }
.app-nav__item svg { width: 20px; height: 20px; flex: none; }
.app-nav__item--active { background: rgba(255,255,255,.1); color: #fff; font-weight: 800; }
.app-nav__item--active:hover { background: rgba(255,255,255,.14); color: #fff; }
.app-nav__item--active svg { color: var(--gold-bright); }
.app-nav__dot { margin-left: auto; width: 7px; height: 7px; border-radius: 50%; background: var(--gold-bright); }

.app-sidebar__section { margin: 18px 20px 0; padding-top: 16px; border-top: 1px solid rgba(255,255,255,.12); }
.app-sidebar__label { font-size: 11px; font-weight: 700; letter-spacing: .1em; color: #5B76A8; text-transform: uppercase; margin-bottom: 10px; }

.app-janet-pill {
  display: flex; align-items: center; gap: 9px; width: 100%;
  background: rgba(138,109,240,.18); border: 1px solid rgba(138,109,240,.5);
  color: var(--plan-violet-chip-text); border-radius: 12px; padding: 10px 12px;
  font-family: inherit; font-size: 13.5px; font-weight: 700; cursor: pointer; text-align: left;
  transition: background .12s ease;
}
.app-janet-pill:hover { background: rgba(138,109,240,.3); color: #fff; }
.app-janet-pill:disabled { cursor: default; opacity: .75; }

.app-sidebar__foot { margin-top: auto; padding: 16px 20px 20px; border-top: 1px solid rgba(255,255,255,.12); }
.app-user { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; }
.app-user__initials {
  width: 36px; height: 36px; flex: none; border-radius: 50%; background: var(--gold); color: var(--on-accent);
  display: inline-flex; align-items: center; justify-content: center; font-weight: 800; font-size: 14px;
}
.app-user__meta { min-width: 0; }
.app-user__name { display: block; color: #fff; font-size: 13.5px; font-weight: 700; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.app-user__email { display: block; color: #92A3C2; font-size: 11.5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.app-logout {
  width: 100%; background: transparent; border: 1px solid rgba(255,255,255,.25); color: #C7D3E8;
  border-radius: 999px; padding: 8px; font-family: inherit; font-size: 13px; font-weight: 600; cursor: pointer;
  transition: background .12s ease;
}
.app-logout:hover { background: rgba(255,255,255,.1); }

/* ── Shared /app primitives ───────────────────────────────────────────────*/
.app-eyebrow { color: var(--gold-text); font-weight: 700; text-transform: uppercase; letter-spacing: .09em; font-size: 12.5px; margin-bottom: 6px; }
.app-title { margin: 0; font-family: var(--font-display); font-size: 40px; font-weight: 700; color: var(--navy); letter-spacing: -.01em; line-height: 1.1; }
.app-sub { margin: 6px 0 0; color: var(--mist); font-size: 15px; }

.app-pill {
  display: inline-flex; align-items: center; gap: 8px; border: none; border-radius: 999px;
  padding: 14px 24px; font-family: inherit; font-size: 15px; font-weight: 600; cursor: pointer;
  text-decoration: none; transition: background .12s ease;
}
.app-pill:hover { text-decoration: none; }
.app-pill--primary { background: var(--blue); color: #fff; }
.app-pill--primary:hover { background: var(--blue-deep); color: #fff; }
.app-pill--plan { background: var(--plan-blue); color: #fff; }
.app-pill--plan:hover { background: var(--plan-blue-pressed); color: #fff; }
.app-pill--tint { background: var(--plan-blue-tint); color: var(--plan-blue); }
.app-pill--sm { padding: 9px 16px; font-size: 13.5px; }

.app-card { background: var(--paper); border: 1px solid var(--hairline); border-radius: 18px; box-shadow: var(--shadow); }
.app-card--flat { box-shadow: none; }

/* Dashed "plan a new trip" call-to-action card. */
.app-dashed {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 10px;
  border: 1.5px dashed var(--gold); background: var(--gold-soft); border-radius: 18px;
  padding: 26px; text-decoration: none; color: var(--gold-text); font-size: 14.5px; font-weight: 700;
  transition: background .12s ease;
}
.app-dashed:hover { background: #F7E7C2; text-decoration: none; color: var(--gold-text); }
.app-dashed__tile { width: 44px; height: 44px; border-radius: 12px; background: var(--gold); color: var(--on-accent); display: grid; place-items: center; }

/* Locked / upsell card — decision D1: AI affordances render locked below Pro with a
   consistent "upgrade in the WeiiGo app" message (no web purchase path in v1). */
.app-upsell { background: var(--plan-violet-tint); border: 1px solid var(--plan-violet-border); border-radius: 16px; padding: 18px 20px; }
.app-upsell__title { font-size: 14.5px; font-weight: 800; color: var(--plan-violet); margin: 0 0 6px; display: flex; align-items: center; gap: 8px; }
.app-upsell__body { margin: 0; font-size: 13.5px; color: var(--plan-muted); line-height: 1.5; }

/* ── Desktop-first notice (decision D3) ───────────────────────────────────*/
.app-narrow-notice { display: none; }
@media (max-width: 1099px) {
  .app-narrow-notice {
    display: block; margin: 0 0 22px; padding: 16px 18px; border-radius: 14px;
    background: var(--gold-soft); border: 1px solid var(--plan-amber-stroke); color: var(--gold-text);
    font-size: 14px; line-height: 1.55;
  }
  .app-narrow-notice strong { display: block; font-weight: 800; margin-bottom: 4px; }
  .app-screen { padding: 28px 20px 56px; }

  /* The notice is the honest answer to a narrow viewport, but a 232px rail still eating half a
     phone screen leaves the page behind it visibly broken — one word per line — which reads as a
     bug rather than as a stated limitation. Unpinning the sidebar into a normal block above the
     content gives the page its full width back without pretending to be a mobile layout. */
  .app-shell { display: block; }
  .app-main { margin-left: 0; }
  .app-sidebar { position: static; width: auto; }
  .app-sidebar__foot { margin-top: 0; }
  .app-nav { flex-direction: row; flex-wrap: wrap; padding: 4px 12px 12px; }
  .app-nav__item { width: auto; }
  .app-sidebar__section { display: none; }   /* Ask Janet lives on the pages themselves */
}

/* ── Login navy hero (WYG-1420) ───────────────────────────────────────────
   The login page is the gate into /app, so it carries the section's chrome: a
   full-height navy hero behind the existing (unchanged) login form semantics. */
.auth-hero {
  min-height: calc(100vh - var(--header-h));
  display: grid; place-items: center; padding: 48px 20px 72px;
  background: linear-gradient(160deg, var(--navy) 0%, var(--navy-600) 60%, var(--navy-deep) 100%);
}
.auth-hero__col { width: 100%; max-width: 440px; }
.auth-hero__mark { display: flex; justify-content: center; margin-bottom: 14px; }
.auth-hero__mark img { height: 64px; width: auto; filter: drop-shadow(0 8px 20px rgba(0,0,0,.35)); }
.auth-hero__eyebrow {
  text-align: center; color: var(--gold-bright); font-size: 12.5px; font-weight: 700;
  letter-spacing: .08em; text-transform: uppercase; margin-bottom: 16px;
}
.auth-hero__card {
  background: var(--paper); border: 1px solid var(--hairline); border-radius: 22px;
  padding: 32px; box-shadow: var(--shadow-lg);
}
.auth-hero__card h1 { font-size: 27px; font-weight: 800; color: var(--navy); margin: 0 0 6px; letter-spacing: -.01em; }
.auth-hero__card .auth-hero__sub { font-size: 15px; color: var(--mist); margin: 0 0 20px; }
.auth-hero__row { display: flex; justify-content: space-between; align-items: center; gap: 12px; margin-bottom: 16px; }
.auth-hero__row .hint { font-size: 13.5px; color: var(--mist); }
.auth-hero__inline-error { font-size: 13px; font-weight: 600; color: var(--danger-text); text-align: right; }
.auth-hero__switch { text-align: center; color: var(--mist); margin: 18px 0 0; font-size: 14.5px; }

/* ── My Trips (WYG-1422) ──────────────────────────────────────────────────*/
.trips-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 20px; margin-bottom: 26px; }

/* Status pill — the design's Confirmed/Planning/Tentative vocabulary plus Generating,
   which the API emits while an AI job is still building the itinerary. */
.trip-status { display: inline-flex; align-items: center; gap: 7px; border-radius: 999px; padding: 5px 11px; font-size: 11.5px; font-weight: 700; }
.trip-status__dot { width: 7px; height: 7px; border-radius: 50%; }
.trip-status--on-dark { background: rgba(7,15,31,.4); color: #fff; }
.trip-status--on-light { background: var(--slate); color: var(--plan-ink); }
.trip-status--confirmed .trip-status__dot { background: var(--plan-status-confirmed); }
.trip-status--planning  .trip-status__dot { background: var(--plan-status-planning); }
.trip-status--tentative .trip-status__dot { background: var(--plan-status-tentative); }
.trip-status--generating .trip-status__dot { background: var(--plan-violet-chip); animation: tripPulse 1.4s ease-in-out infinite; }
@keyframes tripPulse { 0%,100% { opacity: 1; } 50% { opacity: .35; } }
@media (prefers-reduced-motion: reduce) { .trip-status--generating .trip-status__dot { animation: none; } }

.trip-countdown { display: inline-flex; align-items: center; gap: 6px; background: var(--gold-bright); color: var(--on-accent); border-radius: 999px; padding: 6px 12px; font-size: 12.5px; font-weight: 700; }

/* Next-up hero */
.trip-hero {
  position: relative; border-radius: 24px; overflow: hidden; height: 280px; display: block;
  background: linear-gradient(120deg,#1A2C60 0%,#0C1737 100%);
  box-shadow: var(--shadow-lg); margin-bottom: 28px; text-decoration: none;
}
.trip-hero:hover { text-decoration: none; }
.trip-hero__stretch { position: absolute; inset: 0; z-index: 1; }
.trip-hero__top, .trip-hero__body { z-index: 2; }
.trip-hero__glow { display: block; position: absolute; inset: 0; background: radial-gradient(90% 120% at 85% 10%, rgba(91,141,239,.35), transparent 55%), radial-gradient(60% 80% at 10% 90%, rgba(220,177,82,.18), transparent 60%); }
.trip-hero__scrim { display: block; position: absolute; inset: 0; background: linear-gradient(180deg, rgba(10,20,50,.15) 0%, rgba(12,23,55,.94) 100%); }
.trip-hero__cover { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.trip-hero__top { display: flex; position: absolute; top: 16px; left: 18px; right: 18px; display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.trip-hero__text { display: block; min-width: 0; }
.trip-hero__body { display: flex; position: absolute; left: 22px; right: 22px; bottom: 20px; display: flex; align-items: flex-end; justify-content: space-between; gap: 20px; }
.trip-hero__eyebrow { display: block; color: var(--gold-bright); font-size: 11.5px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; margin-bottom: 6px; }
.trip-hero__name { display: block; font-family: var(--font-display); font-size: 38px; font-weight: 700; color: #fff; margin: 0; line-height: 1.05; letter-spacing: -.01em; }
.trip-hero__meta { display: block; color: #C8D6F0; font-size: 14px; margin: 8px 0 0; }
.trip-hero__actions { display: inline-flex; align-items: center; gap: 10px; flex: none; }
.trip-hero__ghost { background: rgba(255,255,255,.12); border: 1px solid rgba(255,255,255,.3); color: #fff; border-radius: 999px; padding: 10px 18px; font-size: 13px; font-weight: 600; text-decoration: none; }
.trip-hero__ghost:hover { background: rgba(255,255,255,.2); color: #fff; text-decoration: none; }
.trip-hero__cta { background: #fff; color: var(--navy); border-radius: 999px; padding: 10px 18px; font-size: 13px; font-weight: 700; text-decoration: none; }
.trip-hero__cta:hover { background: var(--gold-soft); color: var(--navy); text-decoration: none; }

/* Grid */
.trip-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; }
@media (max-width: 1099px) { .trip-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 719px)  { .trip-grid { grid-template-columns: 1fr; } }

.trip-card {
  display: block; background: var(--paper); border: 1px solid var(--hairline); border-radius: 18px;
  overflow: hidden; text-decoration: none; transition: transform .12s ease, box-shadow .15s ease;
}
.trip-card:hover { transform: translateY(-3px); box-shadow: var(--shadow); text-decoration: none; }
.trip-card__banner { display: block; position: relative; height: 110px; }
.trip-card__banner img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.trip-card__banner-scrim { display: block; position: absolute; inset: 0; background: linear-gradient(180deg, rgba(10,20,50,.05), rgba(12,23,55,.45)); }
.trip-card__banner-top { display: block; position: absolute; top: 10px; left: 10px; }
.trip-card__banner-bottom { display: block; position: absolute; right: 10px; bottom: 10px; }
.trip-card__body { display: block; padding: 14px 16px 16px; }
.trip-card__name { display: block; font-size: 18px; font-weight: 800; color: var(--navy); margin: 0 0 4px; }
.trip-card__meta { display: block; font-size: 12.5px; font-weight: 600; color: var(--mist); margin: 0; }
.trip-card__owner { display: block; font-size: 12px; color: var(--plan-muted); margin: 6px 0 0; }

.trips-section-label { font-size: 11.5px; font-weight: 800; letter-spacing: .1em; text-transform: uppercase; color: var(--plan-muted); margin: 34px 0 14px; }

/* ── Create a Trip (WYG-1423) ─────────────────────────────────────────────*/
.create-layout { display: grid; grid-template-columns: minmax(0,1fr) 320px; gap: 26px; align-items: start; }
@media (max-width: 1099px) { .create-layout { grid-template-columns: 1fr; } }

/* Numbered step cards (the mobile Plan-a-Trip v2 vocabulary) */
.step-card { background: var(--slate); border: 1px solid #DCE5F2; border-radius: 22px; padding: 22px; margin-bottom: 20px; }
.step-card--plain { background: var(--paper); }
.step-head { display: flex; align-items: flex-start; gap: 12px; margin-bottom: 16px; }
.step-num { width: 26px; height: 26px; flex: none; border-radius: 9px; display: grid; place-items: center; color: #fff; font-size: 13.5px; font-weight: 800; }
.step-title { font-size: 17px; font-weight: 800; color: var(--plan-ink); margin: 0; }
.step-sub { font-size: 12.5px; color: #5B6B8C; margin: 2px 0 0; }

.dest-search { position: relative; margin-bottom: 14px; }
.dest-search input { width: 100%; background: var(--paper); border: 1px solid var(--plan-control-stroke); border-radius: 14px; padding: 12px 14px 12px 40px; font-family: inherit; font-size: 14.5px; color: var(--plan-ink); }
.dest-search input:focus { outline: none; border-color: var(--plan-blue); box-shadow: 0 0 0 3px rgba(91,141,239,.3); }
.dest-search__icon { position: absolute; left: 14px; top: 50%; transform: translateY(-50%); color: #8A98AD; pointer-events: none; }
.dest-ac { list-style: none; margin: 6px 0 0; padding: 6px; background: var(--paper); border: 1px solid var(--plan-control-stroke); border-radius: 12px; box-shadow: var(--shadow); max-height: 260px; overflow-y: auto; }
.dest-ac li { margin: 0; }
.dest-ac button { display: block; width: 100%; text-align: left; background: none; border: 0; border-radius: 8px; padding: 9px 10px; font-family: inherit; font-size: 14px; color: var(--plan-ink); cursor: pointer; }
.dest-ac button:hover, .dest-ac button:focus-visible { background: var(--plan-blue-tint); }
.dest-ac small { display: block; color: var(--plan-muted); font-size: 12px; }

.chip-row { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 16px; }
.region-chip { display: inline-flex; align-items: center; gap: 7px; background: var(--paper); border: 1px solid var(--plan-control-stroke); border-radius: 999px; padding: 7px 13px; font-family: inherit; font-size: 13px; font-weight: 600; color: var(--plan-ink); cursor: pointer; }
.region-chip:hover { border-color: var(--plan-blue-dashed); }
.region-chip__dot { width: 8px; height: 8px; border-radius: 50%; }
.region-chip--on { background: var(--plan-blue-tint); border-color: var(--plan-blue); color: var(--plan-blue); }

.dest-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.dest-card { position: relative; background: var(--paper); border: 1px solid var(--hairline); border-radius: 18px; overflow: hidden; text-align: left; padding: 0; cursor: pointer; font-family: inherit; }
.dest-card:hover { border-color: var(--plan-blue-dashed); }
.dest-card--on { border: 2px solid var(--plan-blue); }
.dest-card__banner { display: block; position: relative; height: 96px; }
.dest-card__banner img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.dest-card__safety { display: block; position: absolute; top: 8px; right: 8px; border-radius: 999px; padding: 4px 9px; font-size: 11px; font-weight: 800; }
.dest-card__check { display: grid; position: absolute; right: 8px; bottom: 8px; width: 28px; height: 28px; border-radius: 50%; background: var(--plan-blue); color: #fff; display: grid; place-items: center; border: 2px solid var(--paper); }
.dest-card__body { display: block; padding: 12px 14px 14px; }
.dest-card__city { display: block; font-size: 16px; font-weight: 800; color: var(--plan-ink); margin: 0 0 2px; }
.dest-card__desc { display: block; font-size: 12.5px; color: var(--plan-muted); margin: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Dates (teal) */
.date-panels { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.date-panel { background: var(--plan-teal-tint); border-radius: 14px; padding: 12px; }
.date-panel label { display: block; font-size: 10.5px; font-weight: 800; letter-spacing: .1em; color: var(--plan-teal-dark); text-transform: uppercase; margin-bottom: 6px; }
.date-panel input { width: 100%; background: var(--paper); border: 1px solid var(--plan-teal-stroke); border-radius: 10px; padding: 9px 10px; font-family: inherit; font-size: 15px; font-weight: 700; color: var(--plan-ink); }
.nights-pill { display: inline-block; margin-top: 12px; background: var(--paper); border-radius: 999px; padding: 7px 14px; font-size: 13px; font-weight: 800; color: var(--plan-teal); }

/* Travelers (coral) */
.traveler-row { display: flex; align-items: center; gap: 12px; background: var(--plan-coral-tint); border-radius: 16px; padding: 14px; }
.traveler-tile { width: 42px; height: 42px; flex: none; border-radius: 12px; background: var(--paper); display: grid; place-items: center; color: var(--plan-coral); }
.traveler-copy { flex: 1; min-width: 0; }
.traveler-copy strong { display: block; font-size: 16px; font-weight: 800; color: var(--plan-ink); }
.traveler-copy span { font-size: 12.5px; color: var(--plan-coral-sub); }
.stepper { display: inline-flex; align-items: center; background: var(--paper); border: 1px solid var(--plan-coral-stroke); border-radius: 999px; }
.stepper button { width: 40px; height: 40px; border: 0; background: none; border-radius: 999px; font-family: inherit; font-size: 20px; font-weight: 700; color: var(--plan-coral); cursor: pointer; }
.stepper button:disabled { opacity: .35; cursor: default; }
.stepper span { min-width: 34px; text-align: center; font-size: 20px; font-weight: 800; color: var(--plan-coral); }

/* Sticky right rail */
.rail { position: sticky; top: 32px; display: flex; flex-direction: column; gap: 14px; }
.rail-card { background: var(--paper); border-radius: 18px; box-shadow: var(--shadow); padding: 18px; }
.rail-label { font-size: 11px; font-weight: 800; letter-spacing: .1em; text-transform: uppercase; margin-bottom: 10px; }
.rail-label--gold { color: var(--gold-text); }
.rail-label--amber { color: var(--plan-amber); }
.rail-row { display: flex; justify-content: space-between; gap: 12px; padding: 9px 0; border-bottom: 1px solid var(--hairline); font-size: 14px; }
.rail-row:last-of-type { border-bottom: 0; }
.rail-row dt { color: var(--plan-muted); margin: 0; }
.rail-row dd { color: var(--plan-ink); font-weight: 700; margin: 0; text-align: right; }
.rail-stars { color: var(--plan-amber); letter-spacing: 2px; font-size: 15px; }
.rail-slider { width: 100%; accent-color: var(--plan-amber); }
.rail-estimate { font-size: 15px; font-weight: 800; color: var(--plan-ink); margin: 8px 0 2px; }
.rail-caption { font-size: 12px; color: var(--plan-muted); margin: 0; }
.rail-cta { width: 100%; justify-content: center; border: 0; cursor: pointer; font-family: inherit; }
.rail-cta--generate { background: var(--blue); color: #fff; border-radius: 999px; padding: 15px 20px; font-size: 16px; font-weight: 800; box-shadow: 0 10px 24px rgba(29,78,216,.3); display: inline-flex; align-items: center; gap: 9px; }
.rail-cta--generate:hover:not(:disabled) { background: var(--blue-deep); }
.rail-cta--save { background: var(--plan-blue-tint); color: var(--plan-blue); border-radius: 999px; padding: 13px 20px; font-size: 14.5px; font-weight: 700; }
.rail-cta--save:hover:not(:disabled) { background: #D8E3FB; }
.rail-cta:disabled { opacity: .6; cursor: default; }
.validation-chip { background: var(--plan-coral-tint); color: var(--danger-text); border-radius: 12px; padding: 10px 12px; font-size: 13px; font-weight: 600; }

/* ── Janet pre-fill + generation (WYG-1424) ───────────────────────────────*/
.janet-card { background: var(--plan-violet-tint); border: 1px solid var(--plan-violet); border-radius: 16px; padding: 18px; margin-bottom: 20px; }
.janet-card__title { display: flex; align-items: center; gap: 8px; font-size: 14.5px; font-weight: 800; color: var(--plan-violet); margin: 0 0 10px; }
.janet-card textarea { width: 100%; min-height: 64px; background: var(--paper); border: 1px solid var(--plan-control-stroke); border-radius: 10px; padding: 11px 12px; font-family: inherit; font-size: 14.5px; color: var(--plan-ink); resize: vertical; }
.janet-card textarea:focus { outline: none; border-color: var(--plan-violet); box-shadow: 0 0 0 3px rgba(120,87,224,.25); }
.janet-actions { display: flex; gap: 10px; margin-top: 12px; flex-wrap: wrap; }
.janet-btn { border-radius: 12px; padding: 10px 16px; font-family: inherit; font-size: 14px; font-weight: 700; cursor: pointer; border: 1px solid transparent; }
.janet-btn--solid { background: var(--plan-violet); color: #fff; }
.janet-btn--solid:hover:not(:disabled) { background: var(--plan-violet-deep); }
.janet-btn--outline { background: transparent; border-color: var(--plan-violet); color: var(--plan-violet); }
.janet-btn--outline:hover:not(:disabled) { background: rgba(120,87,224,.08); }
.janet-btn:disabled { opacity: .55; cursor: default; }
.janet-note { display: flex; align-items: flex-start; gap: 7px; margin: 12px 0 0; font-size: 13px; font-weight: 600; color: var(--plan-violet); }
.janet-note--muted { color: var(--plan-muted); font-weight: 500; }

/* Ambiguous-destination picker */
.alt-picker { margin-top: 12px; background: var(--paper); border: 1px solid var(--plan-violet-border); border-radius: 12px; padding: 12px; }
.alt-picker p { margin: 0 0 8px; font-size: 13px; font-weight: 700; color: var(--plan-ink); }
.alt-options { display: flex; flex-wrap: wrap; gap: 8px; }
.alt-option { background: var(--plan-violet-tint); border: 1px solid var(--plan-violet-border); color: var(--plan-violet); border-radius: 999px; padding: 8px 14px; font-family: inherit; font-size: 13.5px; font-weight: 700; cursor: pointer; }
.alt-option:hover { background: #E2DAFA; }

/* Generation overlay */
.gen-overlay { position: fixed; inset: 0; z-index: 200; display: grid; place-items: center; background: rgba(7,15,31,.55); backdrop-filter: blur(4px); padding: 20px; }
.gen-card { width: 100%; max-width: 420px; background: var(--paper); border-radius: 24px; padding: 30px 28px; text-align: center; box-shadow: 0 24px 64px rgba(20,32,60,.35); }
.gen-disc { width: 64px; height: 64px; margin: 0 auto 18px; border-radius: 50%; display: grid; place-items: center; background: linear-gradient(150deg,#8A6DF0,#6A4CD8); color: #fff; }
.gen-disc svg { animation: genPulse 1.8s ease-in-out infinite; }
@keyframes genPulse { 0%,100% { transform: scale(1); opacity: 1; } 50% { transform: scale(1.12); opacity: .75; } }
@media (prefers-reduced-motion: reduce) { .gen-disc svg { animation: none; } }
.gen-title { font-size: 19px; font-weight: 800; color: var(--navy); margin: 0 0 6px; }
.gen-status { font-size: 14px; color: var(--plan-muted); margin: 0 0 18px; min-height: 21px; }
.gen-bar { height: 6px; border-radius: 999px; background: var(--plan-input-fill); overflow: hidden; }
.gen-bar__fill { height: 100%; border-radius: 999px; background: linear-gradient(90deg,var(--plan-violet),var(--plan-blue)); transition: width .4s ease; }
.gen-error { background: var(--danger-soft); color: var(--danger-text); border-radius: 12px; padding: 12px; font-size: 13.5px; font-weight: 600; text-align: left; margin-bottom: 14px; }
.gen-actions { display: flex; gap: 10px; justify-content: center; margin-top: 16px; }

/* ── Itinerary viewer (WYG-1425) ──────────────────────────────────────────*/
.itin-bar { background: var(--paper); border: 1.5px solid var(--plan-amber-stroke); border-radius: 20px; box-shadow: 0 4px 14px rgba(20,32,60,.06); padding: 16px 18px; margin-bottom: 16px; }
.itin-hero { display: flex; align-items: center; gap: 14px; }
.itin-back { width: 40px; height: 40px; flex: none; border-radius: 50%; background: var(--plan-surface); border: 1px solid var(--plan-control-stroke); display: grid; place-items: center; color: var(--plan-ink); text-decoration: none; }
.itin-back:hover { background: var(--plan-blue-tint); text-decoration: none; }
.itin-hero__text { flex: 1; min-width: 0; }
.itin-eyebrow { font-size: 11px; font-weight: 800; letter-spacing: .16em; text-transform: uppercase; color: var(--plan-amber); }
.itin-title { font-size: 24px; font-weight: 800; color: var(--plan-ink); margin: 2px 0 3px; }
.itin-meta { font-size: 12.5px; font-weight: 700; color: var(--plan-muted); margin: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.itin-hero__actions { display: flex; align-items: center; gap: 10px; flex: none; }
.itin-settings { display: inline-flex; align-items: center; gap: 7px; background: transparent; border: 1px solid var(--plan-control-stroke); border-radius: 999px; padding: 9px 15px; font-family: inherit; font-size: 13px; font-weight: 700; color: var(--plan-ink); cursor: pointer; }
.itin-settings:hover { background: var(--plan-input-fill); }

/* SAFE ring */
.safe-pill { display: inline-flex; align-items: center; gap: 8px; background: var(--plan-green-tint); border-radius: 999px; padding: 5px 12px 5px 6px; }
.safe-ring { position: relative; width: 28px; height: 28px; flex: none; }
.safe-ring svg { transform: rotate(-90deg); }
.safe-ring__score { position: absolute; inset: 0; display: grid; place-items: center; font-size: 10.5px; font-weight: 800; color: var(--plan-green-ink); }
.safe-pill__label { font-size: 12px; font-weight: 800; color: var(--plan-green-ink); }
/* Audit finding 7.2: the ring is fetched AFTER first render (a cold safety index is a paid
   generation), so the itinerary hero now has a state where the pill exists and has no number
   in it yet. It reserves the loaded pill's width so nothing reflows when the score lands —
   and that width is a CONSTANT, not an average: every SafetyTier.FromScore ShortLabel is
   exactly four characters (VERY / SAFE / CAUT / ELEV / RISK). Track-only ring, no score, no
   label: a pill with no number makes no claim, which is the whole point of the state. */
.safe-pill--pending { min-width: 86px; opacity: .5; }

/* Day pill strip */
.day-strip { display: flex; gap: 8px; overflow-x: auto; padding-bottom: 2px; }
.day-pill { min-width: 62px; flex: none; background: var(--paper); border: 1.5px solid var(--plan-control-stroke); border-radius: 14px; padding: 9px 6px 7px; text-align: center; font-family: inherit; cursor: pointer; }
.day-pill:hover { border-color: var(--plan-blue-dashed); }
.day-pill__wd { display: block; font-size: 11px; font-weight: 800; color: #8A93A6; }
.day-pill__num { display: block; font-size: 20px; font-weight: 800; color: var(--plan-ink); line-height: 1.15; }
.day-pill__dots { display: flex; gap: 3px; justify-content: center; height: 7px; margin-top: 3px; }
.day-pill__dot { width: 5px; height: 5px; border-radius: 50%; }
.day-pill--on { background: var(--plan-green-tint); border-color: var(--plan-green-stroke); }
.day-pill--on .day-pill__wd, .day-pill--on .day-pill__num { color: var(--plan-green-ink); }

/* Dark day bar */
.day-bar { background: linear-gradient(120deg,var(--plan-daybar-from),var(--plan-daybar-to)); border-radius: 16px; box-shadow: 0 10px 24px rgba(15,27,51,.22); padding: 16px 18px; display: flex; align-items: center; gap: 14px; margin: 16px 0 8px; }
.day-bar__text { flex: 1; min-width: 0; }
.day-bar__title { font-size: 17px; font-weight: 800; color: #fff; margin: 0; }
.day-bar__sub { font-size: 13px; font-weight: 600; color: var(--plan-daybar-sub); margin: 3px 0 0; }
.day-bar__actions { display: flex; align-items: center; gap: 8px; flex: none; }
.janet-chip { display: inline-flex; align-items: center; gap: 7px; background: rgba(138,109,240,.2); border: 1px solid rgba(138,109,240,.55); color: var(--plan-violet-chip-text); border-radius: 999px; padding: 8px 14px; font-family: inherit; font-size: 12.5px; font-weight: 800; cursor: pointer; }
.janet-chip:hover:not(:disabled) { background: rgba(138,109,240,.32); }
.janet-chip:disabled { opacity: .7; cursor: default; }
.day-bar__icon-btn { width: 44px; height: 44px; border-radius: 13px; border: 1px solid rgba(175,192,226,.4); background: rgba(175,192,226,.08); color: var(--plan-daybar-sub); display: grid; place-items: center; cursor: pointer; }
.day-bar__icon-btn:hover { background: rgba(175,192,226,.18); }
.day-bar__icon-btn--on { background: rgba(175,192,226,.24); color: #fff; }

.itin-hint { font-size: 12px; color: #8A98AD; margin: 0 0 12px; }

/* Timeline */
.stop { display: flex; gap: 12px; }
.stop__rail { width: 64px; flex: none; display: flex; flex-direction: column; align-items: center; padding-top: 2px; }
.stop__time { font-size: 13px; font-weight: 800; color: var(--plan-ink); }
.stop__dot { width: 11px; height: 11px; border-radius: 50%; background: var(--plan-blue); margin: 6px 0 0; }
.stop__connector { flex: 1; width: 2px; background: #DDE3EE; margin-top: 4px; min-height: 12px; }
.stop__card { flex: 1; min-width: 0; background: #F1ECFB; border-radius: 18px; padding: 15px 16px; margin-bottom: 10px; display: flex; gap: 12px; }
.stop__card--agenda { background: var(--paper); border: 1px solid var(--hairline); }
.stop__tile { width: 40px; height: 40px; flex: none; border-radius: 12px; display: grid; place-items: center; color: #fff; }
.stop__body { flex: 1; min-width: 0; }
.stop__title { font-size: 17px; font-weight: 800; color: var(--plan-ink); margin: 0; }
.stop__price { color: var(--plan-price); margin-left: 6px; }
.stop__desc { font-size: 14.5px; line-height: 1.55; color: #4A4368; margin: 5px 0 0; }
.stop__note { display: inline-block; margin-top: 6px; background: var(--warning-soft); color: var(--warning-text); border-radius: 8px; padding: 4px 9px; font-size: 12px; font-weight: 700; }
.stop--anchor .stop__card { background: var(--plan-input-fill); padding: 10px 14px; }
.stop--anchor .stop__title { font-size: 14px; font-weight: 700; color: var(--plan-muted); }

/* Transfer row */
.transfer { display: flex; align-items: center; gap: 10px; padding: 2px 0 12px 76px; }
.transfer__label { font-size: 14px; font-weight: 600; color: var(--plan-muted); flex: 1; min-width: 0; }
.transfer__pill { background: var(--plan-blue-tint); color: var(--plan-blue); border-radius: 999px; padding: 6px 13px; font-size: 12.5px; font-weight: 700; text-decoration: none; }
.transfer__pill:hover { background: #D8E3FB; text-decoration: none; color: var(--plan-blue); }

.itin-empty { text-align: center; font-size: 14.5px; font-weight: 600; color: #8A93A6; padding: 26px 10px; }

/* In-progress interstitial for a Generating trip */
.itin-generating { background: var(--paper); border: 1px solid var(--hairline); border-radius: 18px; padding: 34px; text-align: center; box-shadow: var(--shadow); }

/* ── Itinerary editing (WYG-1426) ─────────────────────────────────────────*/
.stop__controls { display: flex; gap: 6px; flex: none; align-self: flex-start; }
.stop__icon-btn:disabled { opacity: .35; cursor: default; }
.stop__icon-btn { width: 32px; height: 32px; border-radius: 9px; background: var(--paper); border: 1px solid var(--plan-control-stroke); display: grid; place-items: center; color: var(--plan-ink); cursor: pointer; }
.stop__icon-btn:hover { background: var(--plan-blue-tint); }
.stop__icon-btn--danger { border-color: var(--plan-coral-stroke); color: #C0392B; }
.stop__icon-btn--danger:hover { background: var(--plan-coral-tint); }

/* Drag & drop */
.stop[draggable="true"] { cursor: grab; }
.stop--dragging { opacity: .35; }
.stop--drop-before .stop__card { box-shadow: inset 0 3px 0 var(--plan-blue); }
.day-pill--drop { background: var(--plan-blue-tint); border-color: var(--plan-blue); }
.day-pill--drop .day-pill__wd, .day-pill--drop .day-pill__num { color: var(--plan-blue); }

/* Dashed add buttons */
.add-row { display: flex; gap: 10px; margin-top: 14px; flex-wrap: wrap; }
.add-btn { display: inline-flex; align-items: center; gap: 8px; background: var(--paper); border: 1.5px dashed var(--plan-blue-dashed); color: var(--plan-blue); border-radius: 14px; padding: 12px 18px; font-family: inherit; font-size: 14px; font-weight: 700; cursor: pointer; box-shadow: var(--shadow-sm); }
.add-btn:hover:not(:disabled) { background: var(--plan-blue-tint); }
.add-btn--janet { border-color: #C4B2F5; color: var(--plan-violet); }
.add-btn--janet:hover:not(:disabled) { background: var(--plan-violet-tint); }
.add-btn:disabled { opacity: .6; cursor: default; }

/* Modals */
.modal-scrim { position: fixed; inset: 0; z-index: 150; background: rgba(20,30,46,.45); display: grid; place-items: center; padding: 20px; }
.modal { width: 100%; background: var(--paper); border-radius: 24px; padding: 24px; box-shadow: 0 24px 64px rgba(20,32,60,.35); max-height: 90vh; overflow-y: auto; }
.modal--stop { max-width: 480px; }
.modal--settings { max-width: 460px; }
.modal__head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 18px; }
.modal__title { font-size: 20px; font-weight: 800; color: var(--plan-ink); margin: 0; }
.modal__close { width: 34px; height: 34px; border-radius: 50%; border: 1px solid var(--plan-control-stroke); background: var(--paper); color: var(--plan-ink); cursor: pointer; font-size: 17px; line-height: 1; }
.modal__close:hover { background: var(--plan-input-fill); }
.modal__field { margin-bottom: 14px; }
.modal__label { display: block; font-size: 11px; font-weight: 800; letter-spacing: .1em; text-transform: uppercase; color: var(--plan-muted); margin-bottom: 6px; }
.modal__input, .modal__textarea { width: 100%; background: var(--plan-input-fill); border: 1px solid var(--plan-control-stroke); border-radius: 12px; padding: 11px 13px; font-family: inherit; font-size: 14.5px; color: var(--plan-ink); }
.modal__input:focus, .modal__textarea:focus { outline: none; border-color: var(--plan-blue); box-shadow: 0 0 0 3px rgba(91,141,239,.3); }
.modal__textarea { min-height: 76px; resize: vertical; }
.price-chips { display: flex; gap: 8px; flex-wrap: wrap; }
.price-chip { background: var(--plan-input-fill); border: 1px solid var(--plan-control-stroke); border-radius: 999px; padding: 8px 16px; font-family: inherit; font-size: 13.5px; font-weight: 700; color: var(--plan-ink); cursor: pointer; }
.price-chip--on { background: var(--plan-blue-tint); border-color: var(--plan-blue); color: var(--plan-blue); }
.modal__foot { display: flex; justify-content: flex-end; gap: 10px; margin-top: 20px; }
.modal__btn { border-radius: 999px; padding: 11px 20px; font-family: inherit; font-size: 14px; font-weight: 700; cursor: pointer; border: 1px solid transparent; }
.modal__btn--cancel { background: #EEF3FB; border-color: var(--plan-control-stroke); color: var(--plan-ink); }
.modal__btn--primary { background: var(--plan-blue); color: #fff; }
.modal__btn--primary:hover:not(:disabled) { background: var(--plan-blue-pressed); }
.modal__btn:disabled { opacity: .6; cursor: default; }
.modal__error { background: var(--danger-soft); color: var(--danger-text); border-radius: 10px; padding: 10px 12px; font-size: 13px; font-weight: 600; margin-bottom: 14px; }
.modal__caption { font-size: 12px; color: #8A98AD; margin: 10px 0 0; }

/* Undo toast */
.undo-toast { position: fixed; left: 50%; bottom: 26px; transform: translateX(-50%); z-index: 180; display: flex; align-items: center; gap: 14px; background: var(--plan-ink); color: #fff; border-radius: 999px; padding: 12px 16px 12px 20px; box-shadow: 0 12px 30px rgba(11,37,80,.3); font-size: 14px; }
.undo-toast button { background: transparent; border: 0; color: var(--gold-bright); font-family: inherit; font-size: 14px; font-weight: 800; cursor: pointer; }

/* ── Janet slide-in panel (WYG-1427) ──────────────────────────────────────*/
/* visibility (not just the off-screen transform) is what takes the closed panel out of the tab
   order — otherwise its input and buttons stay focusable behind the page, which is both a keyboard
   trap and focusable content inside an aria-hidden subtree. It is delayed by the slide duration on
   close so the animation still plays, and applied instantly on open. */
.janet-panel { position: fixed; top: 0; right: 0; bottom: 0; width: 390px; max-width: 100vw; z-index: 160; display: flex; flex-direction: column; background: var(--plan-surface); border-left: 1px solid var(--hairline); box-shadow: -18px 0 48px rgba(11,37,80,.14); transform: translateX(100%); visibility: hidden; transition: transform .28s cubic-bezier(.4,0,.2,1), visibility 0s linear .28s; }
.janet-panel--open { transform: translateX(0); visibility: visible; transition: transform .28s cubic-bezier(.4,0,.2,1), visibility 0s; }
@media (prefers-reduced-motion: reduce) {
  .janet-panel { transition: visibility 0s; }
  .janet-panel--open { transition: visibility 0s; }
}

.janet-panel__head { display: flex; align-items: center; gap: 12px; padding: 16px 18px; background: linear-gradient(120deg,var(--plan-daybar-from),var(--plan-daybar-to)); flex: none; }
.janet-panel__avatar { width: 40px; height: 40px; flex: none; border-radius: 50%; background: linear-gradient(150deg,#8A6DF0,#6A4CD8); color: #fff; display: grid; place-items: center; }
.janet-panel__id { flex: 1; min-width: 0; }
.janet-panel__name { font-size: 16px; font-weight: 800; color: #fff; margin: 0; }
.janet-panel__scope { font-size: 12px; color: var(--plan-daybar-sub); margin: 1px 0 0; }
.janet-panel__close { width: 32px; height: 32px; flex: none; border-radius: 50%; border: 1px solid rgba(175,192,226,.4); background: rgba(175,192,226,.1); color: var(--plan-daybar-sub); cursor: pointer; font-size: 16px; line-height: 1; }
.janet-panel__close:hover { background: rgba(175,192,226,.24); color: #fff; }

.janet-panel__body { flex: 1; overflow-y: auto; padding: 16px; display: flex; flex-direction: column; gap: 10px; }
.janet-bubble { border-radius: 16px; padding: 11px 14px; font-size: 14px; line-height: 1.5; max-width: 88%; white-space: pre-wrap; }
.janet-bubble--janet { background: var(--paper); border: 1px solid var(--plan-violet-border); color: var(--plan-ink); align-self: flex-start; }
.janet-bubble--user { background: var(--plan-blue); color: #fff; align-self: flex-end; }
.janet-activity { font-size: 12.5px; font-weight: 600; color: var(--plan-muted); align-self: flex-start; padding-left: 4px; }
.janet-typing { display: inline-flex; gap: 5px; align-self: flex-start; padding: 10px 4px; }
.janet-typing span { width: 8px; height: 8px; border-radius: 50%; background: var(--plan-violet); animation: janetDot 1.2s ease-in-out infinite; }
.janet-typing span:nth-child(2) { animation-delay: .18s; }
.janet-typing span:nth-child(3) { animation-delay: .36s; }
@keyframes janetDot { 0%,60%,100% { opacity: .3; } 30% { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .janet-typing span { animation: none; opacity: .6; } }

.janet-suggestion { background: var(--paper); border: 1px solid var(--plan-violet-border); border-radius: 16px; padding: 13px; align-self: stretch; }
.janet-suggestion__head { display: flex; gap: 10px; margin-bottom: 8px; }
.janet-suggestion__tile { width: 34px; height: 34px; flex: none; border-radius: 10px; background: linear-gradient(150deg,#8A6DF0,#6A4CD8); color: #fff; display: grid; place-items: center; }
.janet-suggestion__title { font-size: 14.5px; font-weight: 800; color: var(--plan-ink); margin: 0; }
.janet-suggestion__price { color: var(--plan-price); margin-left: 5px; }
.janet-suggestion__desc { font-size: 12.5px; color: var(--plan-muted); margin: 0; }
.janet-suggestion__add { width: 100%; margin-top: 10px; background: var(--plan-violet-tint); border: 0; border-radius: 999px; padding: 9px; font-family: inherit; font-size: 13.5px; font-weight: 700; color: var(--plan-violet); cursor: pointer; }
.janet-suggestion__add:hover:not(:disabled) { background: #E2DAFA; }
.janet-suggestion__add:disabled { opacity: .6; cursor: default; }

/* Proposal cards — Confirm ONLY for the web's commit set; everything else is an info card. */
.janet-proposal { background: var(--paper); border: 1px solid var(--plan-violet-border); border-left: 3px solid var(--plan-violet); border-radius: 14px; padding: 13px; align-self: stretch; }
.janet-proposal__summary { font-size: 13.5px; font-weight: 700; color: var(--plan-ink); margin: 0 0 10px; }
.janet-proposal__actions { display: flex; gap: 8px; }
.janet-proposal__btn { border-radius: 999px; padding: 8px 15px; font-family: inherit; font-size: 13px; font-weight: 700; cursor: pointer; border: 1px solid transparent; }
.janet-proposal__btn--confirm { background: var(--plan-violet); color: #fff; }
.janet-proposal__btn--confirm:hover:not(:disabled) { background: var(--plan-violet-deep); }
.janet-proposal__btn--dismiss { background: var(--plan-input-fill); border-color: var(--plan-control-stroke); color: var(--plan-ink); }
.janet-proposal__note { font-size: 12.5px; color: var(--plan-muted); margin: 0 0 10px; }
/* Travel hand-off card (WYG-1480): the same proposal shell, but the primary action is a
   link OUT rather than a Confirm — WeiiGo never books and never takes payment. */
.janet-proposal__details { list-style: none; margin: 0 0 10px; padding: 0; display: flex; flex-direction: column; gap: 3px; }
.janet-proposal__details li { font-size: 12.5px; color: var(--plan-ink); }
.janet-proposal__btn--book { background: var(--plan-violet); color: #fff; text-decoration: none; display: inline-flex; align-items: center; }
.janet-proposal__btn--book:hover { background: var(--plan-violet-deep); color: #fff; text-decoration: none; }

.janet-panel__foot { flex: none; padding: 12px 14px; background: var(--paper); border-top: 1px solid var(--hairline); display: flex; gap: 10px; align-items: center; }
.janet-panel__input { flex: 1; min-width: 0; background: var(--bone); border: 1px solid var(--plan-control-stroke); border-radius: 999px; padding: 11px 16px; font-family: inherit; font-size: 14px; color: var(--plan-ink); }
.janet-panel__input:focus { outline: none; border-color: var(--plan-violet); box-shadow: 0 0 0 3px rgba(120,87,224,.22); }
.janet-panel__send { width: 44px; height: 44px; flex: none; border-radius: 50%; border: 0; background: var(--plan-violet); color: #fff; display: grid; place-items: center; cursor: pointer; }
.janet-panel__send:hover:not(:disabled) { background: var(--plan-violet-deep); }
.janet-panel__send:disabled { opacity: .5; cursor: default; }
.janet-panel__state { margin: auto; text-align: center; color: var(--plan-muted); font-size: 13.5px; padding: 20px; }


/* ==========================================================================
   TRAVEL SEARCH — /app/travel (WYG-1479)
   Flights · Stays · Cars. Every result ends in a link-out: WeiiGo never books and
   never takes payment, so there is no checkout chrome here by design.
   ========================================================================== */
.app-screen--travel { max-width: 1000px; }

/* Vertical switch. Each vertical is configured independently server-side, so a tab can be
   live while its neighbour is dormant — the tabs never carry an availability state
   themselves, because the honest answer only arrives with the search. */
.travel-tabs { display: inline-flex; gap: 4px; background: var(--plan-input-fill); border-radius: 999px; padding: 4px; margin-bottom: 18px; }
.travel-tab { border: 0; background: transparent; border-radius: 999px; padding: 9px 20px; font-family: inherit; font-size: 14px; font-weight: 700; color: var(--plan-muted); cursor: pointer; }
.travel-tab--on { background: var(--paper); color: var(--plan-blue); box-shadow: var(--shadow); }

.travel-form { background: var(--paper); border: 1px solid var(--hairline); border-radius: 20px; padding: 20px; box-shadow: var(--shadow); display: flex; flex-direction: column; gap: 14px; }
.travel-row { display: flex; flex-wrap: wrap; gap: 12px; }
.travel-field { display: flex; flex-direction: column; gap: 6px; flex: 1 1 190px; min-width: 0; font-size: 12.5px; font-weight: 700; color: var(--plan-muted); text-transform: uppercase; letter-spacing: .06em; }
.travel-field--wide { flex-basis: 100%; }
.travel-field--time { flex: 0 0 120px; }
.travel-field--stepper { justify-content: flex-start; }
.travel-field input { border: 1px solid var(--plan-control-stroke); border-radius: 12px; padding: 11px 12px; font-family: inherit; font-size: 15px; font-weight: 500; color: var(--plan-ink); background: var(--paper); text-transform: none; letter-spacing: normal; }
.travel-field input:focus { outline: none; border-color: var(--plan-blue); box-shadow: 0 0 0 3px var(--plan-blue-tint); }
.travel-field input:disabled { background: var(--plan-input-fill); color: var(--plan-muted); }

.travel-check { display: inline-flex; align-items: center; gap: 8px; font-size: 13.5px; font-weight: 600; color: var(--plan-ink); }
.travel-toggle { display: inline-flex; gap: 4px; background: var(--plan-input-fill); border-radius: 999px; padding: 3px; align-self: flex-start; }
.travel-toggle button { border: 0; background: transparent; border-radius: 999px; padding: 7px 16px; font-family: inherit; font-size: 13px; font-weight: 700; color: var(--plan-muted); cursor: pointer; }
.travel-toggle button.on { background: var(--paper); color: var(--plan-blue); }

/* Shares the destination autocomplete's shape so the two search surfaces read as one app. */
.travel-ac { list-style: none; margin: -6px 0 0; padding: 6px; background: var(--paper); border: 1px solid var(--plan-control-stroke); border-radius: 12px; box-shadow: var(--shadow); max-height: 260px; overflow-y: auto; }
.travel-ac li { margin: 0; }
.travel-ac button { display: block; width: 100%; text-align: left; background: none; border: 0; border-radius: 8px; padding: 9px 10px; font-family: inherit; font-size: 14px; color: var(--plan-ink); cursor: pointer; }
.travel-ac button:hover, .travel-ac button:focus-visible { background: var(--plan-blue-tint); }
.travel-ac small { display: block; color: var(--plan-muted); font-size: 12px; }

.travel-search { align-self: flex-start; }

.travel-results { margin-top: 22px; display: flex; flex-direction: column; gap: 12px; }
/* Indicative-price caveat. Sits ABOVE the rows on purpose: a cached fare can be 48h old, and
   a note under the list is a note most people never reach. */
.travel-caveat { margin: 0; padding: 11px 14px; border-radius: 12px; background: var(--gold-soft); border: 1px solid var(--plan-amber-stroke); color: var(--gold-text); font-size: 13px; font-weight: 600; }

.travel-card { display: flex; gap: 14px; align-items: stretch; background: var(--paper); border: 1px solid var(--hairline); border-radius: 16px; padding: 14px; }
.travel-card__img { width: 108px; height: 84px; flex: none; border-radius: 12px; object-fit: cover; background: var(--plan-input-fill); }
.travel-card__body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.travel-card__title { margin: 0; font-size: 16px; font-weight: 800; color: var(--navy); }
.travel-card__sub { margin: 0; font-size: 13.5px; color: var(--plan-ink); }
.travel-card__meta { margin: 0; font-size: 13px; color: var(--plan-muted); }
.travel-card__badges { margin: 4px 0 0; display: flex; flex-wrap: wrap; gap: 6px; }
.travel-card__badges span { background: var(--plan-blue-tint); color: var(--plan-blue); border-radius: 999px; padding: 3px 10px; font-size: 11.5px; font-weight: 700; }
.travel-card__buy { flex: none; display: flex; flex-direction: column; align-items: flex-end; justify-content: center; gap: 4px; text-align: right; min-width: 150px; }
.travel-card__price { margin: 0; font-size: 21px; font-weight: 800; color: var(--navy); }
.travel-card__caption { margin: 0; font-size: 12px; color: var(--plan-muted); }
.travel-book { margin-top: 6px; background: var(--plan-blue); color: #fff; border-radius: 999px; padding: 9px 18px; font-size: 13.5px; font-weight: 700; text-decoration: none; }
.travel-book:hover { background: var(--plan-blue-pressed); color: #fff; text-decoration: none; }

.travel-foot { margin: 4px 0 0; font-size: 12.5px; color: var(--plan-muted); }

/* WYG-1568: the AI answer card, shown when a vertical is dormant. Deliberately DOESN'T look
   like .travel-card — a prose answer and a priced row are different kinds of claim, and the two
   must never be confusable at a glance. */
.travel-ai { background: var(--paper); border: 1px solid var(--hairline); border-radius: 16px; padding: 16px; display: flex; flex-direction: column; gap: 12px; }
.travel-ai__by { margin: 0; font-size: 11px; font-weight: 800; letter-spacing: .6px; text-transform: uppercase; color: var(--plan-violet); }
.travel-ai__answer { display: flex; flex-direction: column; gap: 7px; color: var(--plan-ink); font-size: 14.5px; line-height: 1.45; }
.travel-ai__answer p { margin: 0; }
.travel-ai__answer h3, .travel-ai__answer h4, .travel-ai__answer h5, .travel-ai__answer h6 { margin: 6px 0 0; color: var(--navy); font-weight: 800; }
.travel-ai__answer h3 { font-size: 16px; }
.travel-ai__answer h4 { font-size: 15px; }
.travel-ai__answer h5, .travel-ai__answer h6 { font-size: 14px; }
.travel-ai__answer code { background: var(--plan-input-fill); border-radius: 5px; padding: 1px 5px; font-size: 13px; }
.travel-ai__answer hr { border: 0; border-top: 1px solid var(--hairline); margin: 4px 0; }
.travel-ai__li { padding-left: 2px; }

.travel-ai__hotel { border: 1px solid var(--hairline); border-radius: 13px; padding: 12px; display: flex; flex-direction: column; gap: 3px; }
.travel-ai__hotel-name { margin: 0; font-size: 15px; font-weight: 800; color: var(--navy); }
.travel-ai__hotel-sub { margin: 0; font-size: 13px; color: var(--plan-muted); }
.travel-ai__hotel-meta { margin: 3px 0 0; display: flex; flex-wrap: wrap; gap: 10px; font-size: 13px; font-weight: 700; color: var(--gold-text); }

.travel-ai__sources-heading { margin: 2px 0 0; font-size: 11px; font-weight: 800; letter-spacing: .6px; text-transform: uppercase; color: var(--plan-muted); }
.travel-ai__sources { margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 6px; }
.travel-ai__sources li { display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px; font-size: 13.5px; }
.travel-ai__host { color: var(--plan-muted); font-size: 12px; }

/* Dormant / empty / rate-limited / failed all share one shell — they differ in COPY and in
   whether a Retry is offered, never in weight. A dormant provider must not look like a fault. */
.travel-state { background: var(--slate); border: 1px solid var(--hairline); border-radius: 16px; padding: 22px; text-align: center; }
.travel-state__title { margin: 0 0 6px; font-size: 16px; font-weight: 800; color: var(--navy); }
.travel-state__body { margin: 0 0 12px; font-size: 14px; color: var(--mist); line-height: 1.55; }
.travel-state__body:last-child { margin-bottom: 0; }

/* Create-a-Trip rail entry point. */
.rail-travel { display: block; text-decoration: none; }
.rail-travel:hover { text-decoration: none; }
.rail-label--blue { color: var(--plan-blue); }
.rail-travel__cta { display: block; font-size: 15px; font-weight: 800; color: var(--navy); margin-bottom: 4px; }

@media (max-width: 1099px) {
  .travel-card { flex-wrap: wrap; }
  .travel-card__buy { align-items: flex-start; text-align: left; min-width: 0; }
}

/* ============================================================================
   SIGNAL (direction 1b) — marketing primitives
   ----------------------------------------------------------------------------
   The redesign's vocabulary. Every public page is a recombination of these, which
   is the handoff's own instruction: "build the Header and Footer first… then Home,
   Features and Pricing, which carry all the novel layout patterns."

   ⚠️ These are deliberately NOT applied inside `.app-shell`. The trip planner keeps
   its own Plan palette and layout; see the --blue note at the token block.
   ========================================================================== */

/* ── Section rhythm ──────────────────────────────────────────────────────────
   Five backgrounds, alternating, never more than three of the same in a row. The
   navy panel is used at most TWICE per long page — it is punctuation, not a theme. */
.sig-sec { padding: 64px 36px; }
.sig-sec--hero { padding: 80px 36px 72px; }
.sig-sec--short { padding: 56px 36px; }
.sig-sec--top { background: var(--page-top); }
.sig-sec--sky { background: var(--sky); }
.sig-sec--cream { background: var(--cream); border-top: 1px solid var(--cream-border); }
.sig-sec--navy { background: var(--navy); color: #fff; }
.sig-sec--navy p { color: var(--body-on-navy); }
.sig-sec--navy h1, .sig-sec--navy h2, .sig-sec--navy h3 { color: #fff; }

/* ── Type ────────────────────────────────────────────────────────────────────*/
.sig-eyebrow {
  font-family: var(--font-mono); font-size: 11px; font-weight: 400; letter-spacing: .2em;
  text-transform: uppercase; color: var(--gold-text); margin: 0 0 14px;
}
.sig-sec--navy .sig-eyebrow { color: var(--gold-light); }
.sig-h1 { font-size: clamp(40px, 7vw, 82px); line-height: 1; letter-spacing: -.04em; font-weight: 700; color: var(--ink); margin: 0; text-wrap: balance; }
.sig-h1--page { font-size: clamp(34px, 5.4vw, 58px); line-height: 1.03; }
.sig-h1--legal { font-size: clamp(32px, 4.6vw, 50px); line-height: 1.05; }
.sig-h2 { font-size: clamp(28px, 4vw, 50px); line-height: 1.04; letter-spacing: -.03em; font-weight: 700; color: var(--ink); margin: 0; }
.sig-h2--block { font-size: clamp(28px, 3.4vw, 42px); line-height: 1.06; letter-spacing: -.035em; }
.sig-h3 { font-size: 19px; line-height: 1.2; letter-spacing: -.03em; font-weight: 600; color: var(--ink); margin: 0; }
/* The one-accent-word device. Home ("together.") and About ("careful.") ONLY. */
.sig-accent { font-family: var(--font-accent); font-style: italic; font-weight: 400; letter-spacing: -.01em; color: var(--navy); }
.sig-lead { font-size: 18px; line-height: 1.6; color: var(--mist); margin: 18px 0 0; }
.sig-body { font-size: 16px; line-height: 1.6; color: var(--mist); }
.sig-small { font-size: 13px; line-height: 1.7; color: var(--text-tertiary); }

/* ── Pills, chips, buttons ───────────────────────────────────────────────────*/
.btn--sm { padding: 9px 18px; font-size: 13px; }
.sig-status {
  display: inline-flex; align-items: center; gap: 8px; background: #fff;
  border: 1px solid var(--input-border); border-radius: 999px; padding: 7px 14px;
  font-size: 13px; font-weight: 500; color: var(--navy);
}
.sig-status::before { content: ''; width: 7px; height: 7px; border-radius: 50%; background: var(--gold); }
.sig-chip {
  display: inline-block; font-family: var(--font-mono); font-size: 9px; letter-spacing: .14em;
  text-transform: uppercase; background: var(--navy); color: var(--gold-light);
  border-radius: 3px; padding: 3px 6px; vertical-align: middle; margin-left: 8px;
}
.sig-cat { display: inline-block; border-radius: 999px; padding: 9px 16px; font-size: 13.5px; font-weight: 500;
  border: 1px solid rgba(255,255,255,.30); color: #fff; text-decoration: none; }
.sig-cat:hover { color: #fff; text-decoration: none; border-color: rgba(255,255,255,.6); }
.sig-cat.is-active { background: var(--gold-light); color: var(--gold-ink); border-color: var(--gold-light); }

/* ── Cards & capability pills ────────────────────────────────────────────────*/
.sig-card { border: 1px solid var(--line); border-radius: 12px; padding: 26px; background: #fff; }
.sig-card--lg { border-radius: 14px; padding: 32px; }
.sig-card--sky { background: var(--sky); border-color: var(--sky-border); }
.sig-card--cream { background: var(--cream); border-color: var(--cream-border); }
.sig-card--navy { background: var(--navy); border-color: var(--navy); color: #fff; }
.sig-card--navy p, .sig-card--navy li { color: var(--body-on-navy); }
.sig-card--navy h2, .sig-card--navy h3 { color: #fff; }
.sig-card--float { border-radius: 14px; padding: 32px; box-shadow: 0 18px 40px -28px rgba(16,24,40,.40); }
/* Hover is the SIX Home capability cards only — every other card is static. */
.sig-card--hover { transition: border-color 140ms ease, box-shadow 140ms ease; }
.sig-card--hover:hover { border-color: var(--input-border); box-shadow: 0 10px 24px -18px rgba(16,24,40,.35); }
.sig-pillgrid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px; margin: 22px 0 0; padding: 0; list-style: none; }
.sig-pill { background: var(--sky); border-radius: 8px; padding: 12px 14px; font-size: 14.5px; color: #243043; }
.sig-sec--navy .sig-pill, .sig-card--navy .sig-pill { background: rgba(255,255,255,.08); color: #fff; }

/* ── Image slots ─────────────────────────────────────────────────────────────
   The handoff draws these striped and lists five as "still needed from the client".
   We ship the real app screenshots the site already has; only About's photograph
   has no candidate and keeps the empty treatment. */
.sig-img { border: 1px solid var(--input-border); border-radius: 14px; overflow: hidden; background: var(--sky); }
.sig-img img { display: block; width: 100%; height: 100%; object-fit: cover; }
.sig-img--inner { border-radius: 8px; }
/* WYG-2013: .sig-img--empty / ::after { content: attr(data-slot) } is GONE. It was the design
   handoff's placeholder mechanism — a slot with no image printed its own caption — and it shipped
   to visitors on /about for the redesign's whole life. A slot with nothing in it now shows the
   sky field and nothing else; NoDesignPlaceholderReachesAVisitorTests refuses the class on any
   rendered page, so a future handoff cannot re-add it and ship the caption again. */

/* ── Home stat strip ─────────────────────────────────────────────────────────*/
.sig-stats { display: grid; grid-template-columns: repeat(4, 1fr); background: var(--navy); }
.sig-stat { padding: 26px 28px; border-left: 1px solid rgba(255,255,255,.14); }
.sig-stat:first-child { border-left: 0; }
.sig-stat__v { font-size: 34px; font-weight: 700; letter-spacing: -.03em; color: #fff; line-height: 1.1; }
.sig-stat__v--gold { color: var(--gold-light); }
.sig-stat__l { font-size: 13px; color: var(--body-on-navy); margin-top: 4px; }

/* ── Numbered rows (Beta benefits) ───────────────────────────────────────────*/
.sig-numrow { display: grid; grid-template-columns: 26px 1fr; gap: 14px; margin-bottom: 18px; }
.sig-numrow__n { font-family: var(--font-mono); font-size: 13px; color: var(--gold-text); padding-top: 2px; }

/* ── Left-rule callout (Download launch notice) ──────────────────────────────*/
.sig-callout { background: var(--cream); border-left: 3px solid var(--gold); border-radius: 0 10px 10px 0; padding: 16px 20px; font-size: 15px; line-height: 1.6; }

/* ── Comparison table ────────────────────────────────────────────────────────*/
.sig-tablewrap { overflow-x: auto; }
.sig-table { background: #fff; border: 1px solid var(--line); border-radius: 12px; overflow: hidden; min-width: 560px; }
.sig-table__group { display: grid; grid-template-columns: 1fr 100px 100px; padding: 14px 22px; font-size: 13px; font-weight: 600; background: var(--navy); color: #fff; }
.sig-table__group--free { background: var(--cream); color: var(--ink); }
.sig-table__row { display: grid; grid-template-columns: 1fr 100px 100px; padding: 13px 22px; border-bottom: 1px solid var(--line-soft); font-size: 14.5px; color: #243043; }
.sig-table__row:last-child { border-bottom: 0; }
.sig-table__cell { text-align: center; }
.sig-yes-free { color: var(--navy); font-weight: 600; }
.sig-yes-pro { color: var(--gold-text); font-weight: 600; }
.sig-no { color: var(--disabled); }

/* ── FAQ accordion ───────────────────────────────────────────────────────────*/
.sig-acc { display: grid; gap: 10px; }
.sig-acc__item { border: 1px solid var(--line-soft); border-radius: 12px; background: #fff; }
.sig-acc__item[open] { background: var(--sky); border-color: var(--line); }
.sig-acc__q {
  display: flex; align-items: flex-start; justify-content: space-between; gap: 16px;
  padding: 22px 24px; font-size: 18px; font-weight: 600; color: var(--ink); cursor: pointer; list-style: none;
}
.sig-acc__q::-webkit-details-marker { display: none; }
.sig-acc__q::after { content: '+'; font-size: 22px; line-height: 1; color: var(--gold-text); flex: none; }
.sig-acc__item[open] .sig-acc__q::after { content: '\2212'; }
.sig-acc__a { padding: 0 24px 22px; font-size: 15.5px; line-height: 1.7; color: var(--mist); max-width: 720px; }

/* ── Sticky jump list / legal TOC ────────────────────────────────────────────*/
.sig-jump { position: sticky; top: 96px; align-self: start; }
.sig-jump ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 4px; }
.sig-jump a { display: block; padding: 9px 14px; border-radius: 999px; font-size: 14px; color: var(--mist); }
.sig-jump a:hover { color: var(--ink); text-decoration: none; }
.sig-jump a.is-active { background: var(--navy); color: #fff; font-weight: 600; }
.sig-toc { background: var(--sky); border: 1px solid var(--sky-border); border-radius: 12px; padding: 24px; }
/* Without this the entries get the browser's disc and 40px indent, and the active
   row shows a bullet AND the gold rule (WYG-2018). Mirrors `.sig-jump ul` above. */
.sig-toc ul { list-style: none; margin: 0; padding: 0; }
.sig-toc a { display: block; padding: 6px 0 6px 12px; font-size: 14px; color: var(--mist); border-left: 2px solid transparent; }
.sig-toc a:hover { text-decoration: none; color: var(--ink); }
.sig-toc a.is-active { color: var(--navy); font-weight: 600; border-left-color: var(--gold); }

/* ── Legal prose ─────────────────────────────────────────────────────────────
   One step larger and looser than before — the legal pages were the least readable
   part of the site. */
/* Not a grid — the gap belongs BETWEEN sections, and a grid would space every paragraph. */
.sig-prose { max-width: 720px; }
.sig-prose > h2:not(:first-child) { margin-top: 34px; }
.legal-updated { font-family: var(--font-mono); font-size: 12px; color: var(--text-tertiary); margin-top: 18px; }
.sig-prose h2 { font-size: 30px; font-weight: 700; letter-spacing: -.03em; color: var(--ink); margin: 0 0 14px; scroll-margin-top: 96px; }
.sig-prose p, .sig-prose li { font-size: 16.5px; line-height: 1.75; color: var(--body-strong); }
.sig-defs { list-style: none; margin: 0; padding: 0; display: grid; gap: 12px; }
.sig-defs li { display: grid; grid-template-columns: 14px 1fr; gap: 10px; }
.sig-defs li::before { content: '\25C6'; color: var(--gold); font-size: 11px; line-height: 1.9; }
.sig-defs b { color: var(--ink); }

/* ── Forms ───────────────────────────────────────────────────────────────────*/
.sig-field { display: grid; gap: 6px; margin-bottom: 16px; }
.sig-field label { font-size: 14px; font-weight: 600; color: var(--ink); }
.sig-field input, .sig-field select, .sig-field textarea {
  width: 100%; min-height: 46px; border: 1px solid var(--input-border); border-radius: 10px;
  padding: 12px 14px; font: inherit; font-size: 15px; color: var(--ink); background: #fff;
}
.sig-field textarea { min-height: 150px; resize: vertical; }
.sig-field input::placeholder, .sig-field textarea::placeholder { color: #9AA4B2; }
.sig-field input:focus, .sig-field select:focus, .sig-field textarea:focus {
  outline: none; border-color: var(--navy); box-shadow: 0 0 0 3px rgba(14,42,82,.12);
}
.sig-field .sig-err { font-size: 13px; color: var(--error); }
.sig-field.has-error input, .sig-field.has-error textarea, .sig-field.has-error select { border-color: var(--error); }
.sig-fieldrow { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }

/* ── Layout helpers ──────────────────────────────────────────────────────────*/
.sig-split { display: grid; grid-template-columns: 1fr 1fr; gap: 48px; align-items: center; }
.sig-split--beta { grid-template-columns: 1.05fr .95fr; gap: 48px; align-items: start; }
.sig-aside { display: grid; grid-template-columns: 1fr 320px; gap: 40px; align-items: start; }
.sig-side { display: grid; grid-template-columns: 280px 1fr; gap: 48px; align-items: start; }
.sig-grid3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; }
.sig-grid2 { display: grid; grid-template-columns: repeat(2, 1fr); gap: 20px; }
.sig-stack { display: grid; gap: 14px; }
.sig-actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 28px; }

/* ── Responsive ──────────────────────────────────────────────────────────────*/
@media (max-width: 900px) {
  .sig-split, .sig-split--beta, .sig-aside, .sig-side, .sig-grid3, .sig-grid2 { grid-template-columns: 1fr; gap: 28px; }
  /* Spec: the image slot follows the text when a two-column block collapses. */
  .sig-split > .sig-img, .sig-split > .sig-media { order: 2; }
  .sig-jump { position: static; }
}
@media (max-width: 720px) { .sig-stats { grid-template-columns: repeat(2, 1fr); } .sig-stat:nth-child(3) { border-left: 0; } }
@media (max-width: 600px) { .sig-sec, .sig-sec--hero, .sig-sec--short { padding-left: 20px; padding-right: 20px; } }
@media (max-width: 560px) { .sig-pillgrid, .sig-fieldrow { grid-template-columns: 1fr; } }
@media (prefers-reduced-motion: reduce) {
  .sig-acc__item, .btn, .sig-card--hover { transition: none !important; }
  html { scroll-behavior: auto !important; }
}

/* ── Home ────────────────────────────────────────────────────────────────────*/
.home-hero { text-align: center; display: grid; justify-items: center; }
.home-hero__h1 { max-width: 900px; margin-top: 22px; }
.home-hero__lead { max-width: 660px; }
.home-hero__cta { justify-content: center; }
/* The hero slot: three portrait screens, the middle one larger, on a bordered field.
   Spec height is 420px; the phones are sized from that rather than fixed, so the block
   scales down cleanly instead of clipping. */
.home-phones {
  width: 100%; margin-top: 44px; height: 420px; border: 1px solid var(--input-border);
  border-radius: 14px; background: linear-gradient(180deg, #fff, var(--sky));
  display: flex; align-items: center; justify-content: center; gap: 22px; overflow: hidden; padding: 0 20px;
}
.home-phone { border-radius: 30px; overflow: hidden; background: #0d1622; flex: none; }
.home-phone img { display: block; width: 100%; height: 100%; object-fit: cover; object-position: top center; }
.home-phone--side { width: 186px; height: 330px; }
.home-phone--lead {
  width: 210px; height: 390px; border: 8px solid #0d1622; border-radius: 34px;
  box-shadow: 0 24px 44px -18px rgba(13,22,34,.50);
}
.sig-stats-wrap { padding: 0 36px; }
.home-head { display: grid; grid-template-columns: 1fr 1fr; gap: 48px; align-items: end; }
.home-cta { display: grid; grid-template-columns: 1fr auto; gap: 32px; align-items: center; }
/* Row A's two feature cards. The grid stretches them to one height, but their descriptions wrap
   to different line counts, so a screenshot that simply followed its text sat lower in whichever
   card wrapped more (25px at a 1024 viewport). A flex column with the slot on `margin-top:auto`
   pins both screenshots to the card bottom, so they line up at every width.
   ⚠️ The slot's 22px minimum gap is the paragraph's bottom margin (inline, on Home), because an
   auto margin resolves to 0 when there is no spare height — every single-column layout.
   ⚠️ Flex margins do not collapse: the heading's 13px bottom margin would ADD to the paragraph's
   14px top margin (27px) where block layout collapsed the two to 14px. */
.home-feature { display: flex; flex-direction: column; }
.home-feature > h3 { margin-bottom: 0; }
.home-feature > .sig-img { margin-top: auto; }

@media (max-width: 900px) {
  .home-head, .home-cta { grid-template-columns: 1fr; gap: 24px; align-items: start; }
  .home-phones { height: 340px; gap: 14px; }
  .home-phone--side { width: 140px; height: 250px; }
  .home-phone--lead { width: 168px; height: 300px; }
}
@media (max-width: 600px) {
  .sig-stats-wrap { padding: 0 20px; }
  /* Below 600 the flankers would each be under ~110px, which reads as clutter rather than
     context — the lead screen alone is the honest thing to show. */
  .home-phone--side { display: none; }
  .home-phones { height: 380px; }
}

/* ── Features ────────────────────────────────────────────────────────────────*/
.feat-chips { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 28px; }
/* Alternating image side. `order` rather than `direction` so the DOM order stays
   text-then-image, which is also the order the 900px collapse wants. */
.sig-split--flip > *:first-child { order: 2; }
.sig-split--flip > *:last-child { order: 1; }
.sig-pill { display: grid; gap: 4px; }
/* ⚠️ The Pro chip must share this cell with the title. .sig-pill is a GRID, and grid
   blockifies its children and stretches them across the column — so a direct-child
   .sig-chip rendered the 16px word "Pro" as a 214px bar in a 250px card, on all 13 Pro
   cards (measured 2026-09-05, live since the Signal redesign). That also made
   .sig-chip's own inline-block, margin-left and vertical-align inert. The same class
   renders correctly at 32px on Home, where it sits in an h3 rather than a grid item.
   Keep the wrapper: unwrapping it brings the bar straight back. */
.sig-pill__title { display: block; text-wrap: balance; }
/* text-wrap:balance evens the two lines of a wrapping card title. It must sit on THIS
   block, not on .sig-pill b — balancing applies to the element that establishes the line
   boxes, and <b> is inline, so the same declaration there is INERT (measured: 0 of 8
   wrapped titles moved). Measured here: 7 of 8 improve, e.g. "Booking import from email &"
   / "documents" (204/80) becomes "Booking import from" / "email & documents" (147/137),
   and "Briefed before and during the" / "trip" loses a 26px widow. Card heights unchanged.
   Unsupported browsers ignore it and fall back to today's breaks. */
.sig-pill b { font-weight: 600; color: var(--ink); }
.sig-sec--navy .sig-pill b { color: #fff; }
.sig-pill__sum { font-size: 13.5px; line-height: 1.5; color: var(--mist); }
.sig-sec--navy .sig-pill__sum { color: var(--body-on-navy); }
/* ⚠️ No max-height on the BOX. The screenshot inside it is what is bounded now — see "Portrait
   screenshots in landscape slots" below. A cap here never shrank the picture, it cropped it. */
@media (max-width: 900px) {
  /* The collapse puts the image AFTER the text on every block, flipped or not. */
  .sig-split--flip > *:first-child, .sig-split--flip > *:last-child { order: initial; }
}

/* ── Pricing (Signal) ────────────────────────────────────────────────────────*/
.price-head { display: flex; flex-wrap: wrap; align-items: center; gap: 20px; margin-top: 28px; }
.billing-toggle {
  display: inline-flex; align-items: center; gap: 4px; background: #fff;
  border: 1px solid var(--input-border); border-radius: 999px; padding: 4px;
}
.billing-toggle label {
  cursor: pointer; border-radius: 999px; padding: 8px 20px; font-size: 14px; font-weight: 600;
  color: var(--mist); transition: background-color 140ms ease, color 140ms ease; margin: 0;
}
.billing-toggle__save { color: var(--gold-text); font-size: 12px; font-weight: 600; }
#billing-monthly:checked ~ .billing-toggle label[for="billing-monthly"],
#billing-yearly:checked ~ .billing-toggle label[for="billing-yearly"] { background: var(--navy); color: #fff; }
#billing-monthly:checked ~ .billing-toggle label[for="billing-monthly"] .billing-toggle__save,
#billing-yearly:checked ~ .billing-toggle label[for="billing-yearly"] .billing-toggle__save { color: var(--gold-light); }

.price-grid { align-items: start; }
.price-card { position: relative; border: 1px solid var(--line); border-radius: 14px; padding: 32px; background: #fff; }
/* Signal: the flag sits at the LEFT edge, not centred. */
.price-card--featured { border: 2px solid var(--gold); background: #FFFDF7; }
.price-card__flag {
  position: absolute; top: -13px; left: 32px; transform: none; background: var(--gold);
  color: var(--gold-ink); font-weight: 600; font-size: 12px; text-transform: none;
  letter-spacing: .06em; padding: 5px 14px; border-radius: 999px;
}
.price-card__name { font-size: 16px; font-weight: 600; color: var(--ink); }
.price-card__price .price { font-size: 52px; font-weight: 700; letter-spacing: -.04em; color: var(--ink); line-height: 1.1; }
.price-card__price .price small { font-size: 15px; font-weight: 500; color: var(--text-tertiary); letter-spacing: 0; margin-left: 4px; }
.price-card__tagline { color: var(--mist); font-size: 15px; margin: 6px 0 22px; }
.price-card .btn { margin-bottom: 22px; }
.price-card ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; }
.price-card li { font-size: 15px; line-height: 1.5; color: #243043; }
.price-card li:first-child { font-weight: 600; }

.compare-wrap { overflow-x: auto; }
.compare {
  width: 100%; min-width: 560px; border-collapse: collapse; background: #fff;
  border: 1px solid var(--line); border-radius: 12px; overflow: hidden; table-layout: fixed;
}
.compare thead th { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.compare col, .compare th:not(:first-child), .compare td { width: 100px; }
.compare th:first-child { width: auto; }
.compare__group th {
  background: var(--navy); color: #fff; font-size: 13px; font-weight: 600;
  padding: 14px 22px; text-align: left;
}
/* The safety group is cream, not navy — it is the one group whose claim is that it is free. */
.compare__group--free th { background: var(--cream); color: var(--ink); }
.compare__claim { font-weight: 400; }
.compare tbody th[scope="row"] { font-weight: 400; text-align: left; padding: 13px 22px; font-size: 14.5px; color: #243043; }
.compare tbody td { padding: 13px 22px; text-align: center; font-size: 14.5px; }
.compare tbody tr:not(.compare__group) { border-bottom: 1px solid var(--line-soft); }
.compare__yes { color: var(--navy); font-weight: 600; }
.compare__yes--pro { color: var(--gold-text); font-weight: 600; }
.compare__no { color: var(--disabled); }
@media (max-width: 900px) { .price-grid { gap: 28px; } }

/* ── About / Download (Signal) ───────────────────────────────────────────────*/
.about-shieldrow { display: grid; grid-template-columns: 220px 1fr; gap: 40px; align-items: center; }
.about-shieldbox { background: rgba(255,255,255,.06); border-radius: 14px; display: grid; place-items: center; padding: 24px; min-height: 180px; }
.about-shieldbox img { width: 121px; height: auto; }
.dl-stores { gap: 20px; }
.dl-stores .qr img, .dl-stores .qr canvas, .dl-stores .qr svg { width: 130px; height: 130px; }
/* WYG-2016: the two store cards sit in the hero split's right column, so at the container cap
   each card is 254px and the 200px badge has ~65px for its label — which is why the label
   wrapped. `1fr` tracks cannot shrink below their content, so with `white-space: nowrap` on the
   label the grid GROWS to fit instead: left alone that made the two cards unequal (281 / 291px,
   each sized by its own label). A fixed badge width makes the cards equal (306px each) and
   holds 15px of slack over the wider "Get it on / Google Play" label — measured in headless
   Chrome, and the widths differ by font stack, hence the slack rather than a tight fit.
   Below 560px the phone rule (`.store-badge { width: 100% }`) takes over, restated here because
   this selector is more specific than that one.
   `justify-content: center` is for the state the badge spends its life in: once a store URL is
   set there is no Soon pill, and an inline-flex badge packs glyph + label to the LEFT of its
   fixed width — measured at 75–84px of empty navy right of the label. Centred it is 37–42px
   each side. The Soon state is unchanged: the pill's `margin-left: auto` absorbs the free space
   before justify-content is consulted (WYG-2016 review, finding 1). */
.dl-stores .store-badge { width: 252px; min-width: 0; justify-content: center; }
/* WYG-2016: with the cards at their honest width the right column needs 632px, and below the
   container's own cap (1140px) the hero's text column pays for it — at 1101px the h1 was on
   THREE lines in 309px, and at 1024px the right column overflowed the container. So this page's
   split stacks below the container width rather than at the shared 900px breakpoint; the cards
   then sit two-up under the text at 446–484px each. */
@media (max-width: 1140px) { .dl-split { grid-template-columns: 1fr; } }
@media (max-width: 900px) {
  .about-shieldrow { grid-template-columns: 1fr; gap: 24px; }
  .dl-stores { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 560px) {
  .dl-stores { grid-template-columns: 1fr; }
  .dl-stores .store-badge { width: 100%; }
}
/* WYG-2016: the one place the label may fold. A full-width badge at 320px has ~226px inside the
   card and the wider label needs ~236px unwrapped, so on the narrowest phones the words wrap as
   they did before this ticket rather than overflow the card. ⚠️ Reasoned from the measured
   widths, not measured: headless Chrome will not open a window under 500px. */
@media (max-width: 360px) { .store-badge__sub, .store-badge__name { white-space: normal; } }

/* ── Press kit + Founding Testers wall (WYG-1398) ────────────────────────────*/
/* The fact sheet is a definition list on the navy band: terms in the on-navy muted, definitions
   in white, two columns down to the shared 900px breakpoint. */
.press-facts { display: grid; grid-template-columns: 150px 1fr; gap: 14px 28px; margin: 0; max-width: 900px; }
.press-facts dt { font-size: 13px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--body-on-navy); padding-top: 3px; }
.press-facts dd { margin: 0; font-size: 16px; line-height: 1.65; color: #fff; }
.press-facts dd a { color: #fff; text-decoration: underline; }
/* An asset card is a whole-card link: the image sits on a light well so a transparent logo
   reads, and the name/meta stack below it. `download` on the anchor saves rather than opens. */
.press-asset { display: grid; gap: 10px; align-content: start; text-decoration: none; color: inherit; }
.press-asset img { width: 100%; height: 150px; object-fit: contain; background: var(--sky); border-radius: 12px; padding: 14px; box-sizing: border-box; }
.press-asset__name { font-size: 16px; font-weight: 700; color: var(--ink); }
.press-asset__meta { font-size: 13px; color: var(--mist); }
/* 28 portrait screenshots as a thumbnail grid — 6-up at the container cap, stepping down. */
.press-shots { display: grid; grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); gap: 12px; }
.press-shots img { width: 100%; height: auto; aspect-ratio: 921 / 2000; object-fit: cover; border-radius: 10px; box-shadow: 0 10px 22px -16px rgba(13,22,34,.5); }
/* The wall: names as gold-edged pills that wrap. Each is a <li>, so a screen reader hears a
   list of N names rather than one run-on line. */
.wall { list-style: none; margin: 32px 0 0; padding: 0; display: flex; flex-wrap: wrap; gap: 10px 12px; }
.wall li { padding: 9px 16px; border-radius: 999px; border: 1px solid var(--gold); background: #fff; font-size: 15px; font-weight: 600; color: var(--ink); }
@media (max-width: 900px) {
  .press-facts { grid-template-columns: 1fr; gap: 4px 0; }
  .press-facts dd { margin-bottom: 12px; }
}

/* ── Auth split (Login, and the Register sibling) ────────────────────────────*/
.auth-split { display: grid; grid-template-columns: 1fr 1fr; min-height: 600px; }
.auth-split__panel { background: var(--navy); color: #fff; padding: 64px 44px; display: flex; flex-direction: column; justify-content: center; }
.auth-split__panel .sig-eyebrow { color: var(--gold-light); }
.auth-split__form { background: #fff; display: grid; place-items: center; padding: 64px 36px; }
.auth-form { width: 100%; max-width: 380px; }
.auth-hero__row { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 18px; flex-wrap: wrap; }
.auth-hero__inline-error { color: var(--error); font-size: 13px; }
/* A single centred card for the auth pages the handoff never drew (forgot/reset/confirm/
   invite/404/error). Same shell, no split — they have no supporting story to tell. */
.auth-solo { display: grid; place-items: center; padding: 72px 20px; background: var(--page-top); min-height: 60vh; }
.auth-solo__card { width: 100%; max-width: 460px; background: #fff; border: 1px solid var(--line); border-radius: 14px; padding: 32px; box-shadow: 0 18px 40px -28px rgba(16,24,40,.40); }
@media (max-width: 900px) {
  .auth-split { grid-template-columns: 1fr; min-height: 0; }
  .auth-split__panel { padding: 48px 24px; }
  .auth-split__form { padding: 40px 24px; }
}

/* ── The seven pages the handoff never drew ──────────────────────────────────
   Register, ForgotPassword, ResetPassword, ConfirmEmail, Invite, NotFound and Error are
   reachable, shipping pages that the design (built from a signed-out public crawl of the 12
   marketing routes) simply did not cover. They are brought onto the Signal language rather
   than left looking like the old site beside the new one.

   ⚠️ Restyled through CSS wherever possible rather than by rewriting markup: four of them are
   auth forms, and their field wiring, tokens and redirect guards are not worth disturbing for
   a visual pass.

   ⛔ Register takes the SOLO card, not Login's split panel. The handoff itself marks Login's
   left-hand story as optional ("cut it if you'd rather keep the page to the form"), and making
   Register match its three auth siblings is more coherent than making it match Login alone. */
.section:has(> .container > .auth-card),
.section:has(> .container > .auth-card-wide) {
  background: var(--page-top); padding-block: 72px;
}
.auth-card {
  background: #fff; border: 1px solid var(--line); border-radius: 14px; padding: 32px;
  box-shadow: 0 18px 40px -28px rgba(16,24,40,.40); max-width: 460px; margin-inline: auto;
}
.auth-card h1, .auth-card h2 {
  font-family: var(--font-sans); font-weight: 700; letter-spacing: -.03em; color: var(--ink);
}
.auth-card .field { display: grid; gap: 6px; margin-bottom: 16px; }
.auth-card .field label { font-size: 14px; font-weight: 600; color: var(--ink); }
.auth-card .input, .auth-card input[type="text"], .auth-card input[type="email"], .auth-card input[type="password"] {
  width: 100%; min-height: 46px; border: 1px solid var(--input-border); border-radius: 10px;
  padding: 12px 14px; font: inherit; font-size: 15px;
}
.auth-card .input:focus, .auth-card input:focus {
  outline: none; border-color: var(--navy); box-shadow: 0 0 0 3px rgba(14,42,82,.12);
}
/* NotFound / Error / Invite: centred on the page-top gradient, same voice. */
.section.text-center:has(h1) { background: var(--page-top); }

/* ── Portrait screenshots in landscape slots ─────────────────────────────────
   Every screenshot we ship is a 921×2000 PHONE screen and the handoff draws these slots for
   landscape photographs. These rules size the IMAGE; they must never size the box.

   🔴 The previous `object-fit: contain` fix here was INERT, measurably so. `.sig-img img` is
   `width:100%; height:100%`, and these boxes carry no height of their own — so `height:100%`
   resolves against an auto-height parent, computes to `auto`, and the img element takes the
   picture's own 921:2000 ratio. `object-fit` then has nothing left to do (its box already matches
   its content), the img overflows, and `.sig-img { overflow:hidden }` crops the overflow away.
   Measured at a 1440px viewport: a Features slot rendered its img 524×1174 inside a 440px box —
   the bottom 734px of every screenshot was cut off — and a Home row-A card, which has no cap at
   all, rendered one at 1032×2265. That second one is the "way too big" this was reported as, and
   the two are the SAME defect: a box cap changes which symptom you get, not whether you have it.

   ⚠️ So the HEIGHT is what is declared and the width follows it, which is the inverse of what was
   here. That lands these at phone proportions at roughly the height of the hero phones
   (330–390px) rather than at the height of whatever column they happen to sit in. Declaring a
   width instead ties the rendered height to the column, which is how this went wrong twice.

   🔴 `aspect-ratio` is load-bearing, not decoration. The `width`/`height` HTML attributes are
   only PRESENTATIONAL HINTS, so `width: auto` here beats them — which means a lazy image that has
   not loaded yet has no intrinsic size at all and collapses to 0×0. Measured: without this line
   both Home row-A slots rendered their img at 0×0 and the card fell back to its 180px min-height,
   then jumped on load. The ratio is every app screenshot we ship (921×2000), and `object-fit`
   below is the backstop if one ever isn't — it letterboxes rather than distorting. */
.sig-media { background: var(--sky); }
.sig-media, .sig-img--inner { padding: 22px 18px; }
.sig-media img, .sig-img--inner img {
  width: auto; max-width: 100%; margin-inline: auto;
  aspect-ratio: 921 / 2000; object-fit: contain;
  border-radius: 16px; box-shadow: 0 18px 34px -20px rgba(13,22,34,.45);
}
/* Sized against the hero phones on Home (lead 390, flankers 330), which is the reference a
   reader has already seen by the time they scroll to either slot. */
.sig-media img { height: 400px; }
.sig-img--inner img { height: 340px; }
.sig-sec--navy .sig-media { background: rgba(255,255,255,.05); }
.sig-card--navy .sig-img--inner { background: rgba(255,255,255,.05); }
/* The hero phones step down at 900 (lead 390→300, flankers 330→250); these follow them, so the
   reference the reader has already seen and these slots stay the same size as each other. */
@media (max-width: 900px) {
  .sig-media img { height: 340px; }
  .sig-img--inner img { height: 300px; }
}
/* ⚠️ Register/ConfirmEmail nest a .card INSIDE .auth-card — the old .auth-card was a bare
   centring wrapper, so the inner card carried the chrome. Now that .auth-card IS the card,
   the inner one has to stop being one or the page renders a box inside a box. */
.auth-card > .card { background: none; border: 0; box-shadow: none; padding: 0; border-radius: 0; }
