/* ============================================================================
   Atlas — component stylesheet
   ----------------------------------------------------------------------------
   Flat, editorial award/cash flight UI. No glow, no gradients-as-decoration.
   Consumes design tokens defined elsewhere (e.g. tokens.css / :root):

     Surfaces   --bg --surface --surface-raised
     Ink        --ink --muted-1 --muted-2 --muted-3
     Lines      --border --border-soft
     Brass      --brass --brass-deep --brass-tint-bg --brass-tint-bd
     Seat pill  --seat-bg --seat-fg
     Category   --cat-<name>-line  (swatch / arc color)
                --cat-<name>-bg    (soft fill)
     Radii      --r-card --r-pill --r-input --r-tile
     Shadow     --shadow-card --shadow-float

   Type:
     Newsreader  — headlines, destinations, prices/miles (editorial serif)
     DM Mono     — eyebrows, programs, metadata (monospace)

   Layout philosophy: mobile-first. Base rules target a phone; progressive
   `min-width` media queries layer on the desktop topbar + rail + list grid.
   ========================================================================== */

/* ----------------------------------------------------------------------------
   0. Local component scales
   These are *component* knobs, not global theme tokens. Kept here so the
   stylesheet drops in standalone; override in :root if you want to retune.
   -------------------------------------------------------------------------- */
.atlas {
  --atlas-rail-w: 222px;          /* left filter rail width (212–230 range)   */
  --atlas-topbar-h: 60px;         /* top bar height                            */
  --atlas-gap: 16px;              /* default content gutter                     */
  --atlas-tile: 34px;            /* airline logo tile size                     */
  /* --atlas-eyebrow lives once in atlas.css :root (11px) — do not re-declare here */

  font-family: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  color: var(--ink);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* Shared type primitives ---------------------------------------------------- */
.atlas-serif   { font-family: "Newsreader", Georgia, "Times New Roman", serif; }
.atlas-mono    { font-family: "DM Mono", ui-monospace, "SFMono-Regular", Menlo, monospace; }

/* The eyebrow: small, uppercase, tracked-out mono label that heads a section. */
.atlas-eyebrow {
  font-family: "DM Mono", ui-monospace, monospace;
  font-size: var(--atlas-eyebrow);
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted-2);
}

/* ============================================================================
   1. TOP BAR  (.atlas-topbar)
   Wordmark · Award/Cash segmented · prominent search · From-selector ·
   day/night toggle · avatar. Single flat row; search flex-grows to fill.
   ========================================================================== */
.atlas-topbar {
  display: flex;
  align-items: center;
  /* P1 (topbar overflow): allow the row to absorb slack instead of clipping the right-edge controls off
     the viewport. flex-wrap is load-bearing — it clears a residual 1100-1154px work-view overflow that the
     mid-desktop media query (max-width:1099.98px) and the landing-only sheds do NOT cover. The .atlas-search
     flex element fills the work view so the bar stays a single row in practice; row-gap only applies if it
     ever does wrap. */
  flex-wrap: wrap;
  row-gap: 8px;
  gap: 14px;
  /* Standalone PWA on a notched iPhone: grow the bar by the status-bar inset and pad the content down,
     so the wordmark/search/toggles clear the notch instead of sliding under it (viewport-fit=cover). */
  height: calc(var(--atlas-topbar-h) + env(safe-area-inset-top, 0px));
  padding: env(safe-area-inset-top, 0px) var(--atlas-gap) 0;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
}

/* Logo — a violet "outlier" mark (a cluster ring + one standout dot) + the editorial-serif wordmark. */
.atlas-topbar .wordmark {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: "Newsreader", Georgia, serif;
  font-size: 23px;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--brand);
  line-height: 1;
  flex: 0 0 auto;
  user-select: none;
}
.atlas-topbar .brand-mark { width: 22px; height: 22px; flex: 0 0 auto; display: block; }

/* --- Award / Cash segmented control ------------------------------------- */
.segmented {
  display: inline-flex;
  flex: 0 0 auto;
  padding: 3px;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--r-pill);
}
.segmented button {
  appearance: none;
  border: 0;
  background: transparent;
  cursor: pointer;
  font-family: "DM Mono", ui-monospace, monospace;
  font-size: 12px;
  letter-spacing: 0.04em;
  color: var(--muted-1);
  padding: 6px 16px;
  border-radius: var(--r-pill);
  transition: color 120ms ease, background 120ms ease;
}
.segmented button:hover { color: var(--ink); }
.segmented button[aria-pressed="true"],
.segmented button.is-active {
  background: var(--ink);
  color: var(--surface);     /* paper text on ink fill */
}

/* --- Prominent search input ---------------------------------------------- */
.atlas-search {
  position: relative;
  flex: 1 1 auto;             /* the star of the bar — eats remaining width  */
  min-width: 120px;
}
.atlas-search input {
  width: 100%;
  box-sizing: border-box;
  height: 40px;
  padding: 0 14px 0 38px;     /* room for the leading search glyph           */
  font-family: ui-sans-serif, system-ui, sans-serif;
  font-size: 15px;
  color: var(--ink);
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--r-input);
  outline: none;
  transition: border-color 120ms ease, box-shadow 120ms ease;
}
/* Editorial italic placeholder — invites a question, not a keyword. */
.atlas-search input::placeholder {
  font-family: "Newsreader", Georgia, serif;
  font-style: italic;
  font-size: 16px;
  color: var(--muted-2);
  opacity: 1;
}
/* Brass focus ring — the only "active" accent in the chrome. */
.atlas-search input:focus {
  border-color: var(--brass);
  box-shadow: 0 0 0 3px var(--brass-tint-bg);
}
.atlas-search .search-glyph {
  position: absolute;
  left: 13px;
  top: 50%;
  transform: translateY(-50%);
  width: 15px;
  height: 15px;
  color: var(--muted-2);
  pointer-events: none;
}

/* --- "From New York" origin selector ------------------------------------ */
/* Owner-only (pilot scope): hidden via the attribute for members. A class-level `display` outranks
   the UA [hidden] rule, so this pairing is what actually removes it from the topbar. */
.origin-select[hidden] { display: none !important; }
.origin-select {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  flex: 0 0 auto;
  height: 40px;
  padding: 0 13px;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--r-input);
  cursor: pointer;
  color: var(--ink);
  white-space: nowrap;
  transition: border-color 120ms ease;
}
.origin-select:hover { border-color: var(--muted-3); }
.origin-select .label { font-size: 12px; color: var(--muted-1); }   /* "From" */
.origin-select .value { font-size: 14px; font-weight: 500; }        /* "New York" */
.origin-select .caret { width: 12px; height: 12px; color: var(--muted-2); }

/* --- Day / night toggle --------------------------------------------------- */
.daynight {
  flex: 0 0 auto;
  width: 38px;
  height: 38px;
  display: inline-grid;
  place-items: center;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--r-pill);
  color: var(--muted-1);
  cursor: pointer;
  transition: color 120ms ease, border-color 120ms ease;
}
.daynight:hover { color: var(--ink); border-color: var(--muted-3); }
.daynight svg { width: 17px; height: 17px; }

/* --- Avatar --------------------------------------------------------------- */
.atlas-topbar .avatar {
  flex: 0 0 auto;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: var(--surface-raised);
  border: 1px solid var(--border);
  overflow: hidden;
  display: inline-grid;
  place-items: center;
  font-family: "DM Mono", ui-monospace, monospace;
  font-size: 12px;
  color: var(--muted-1);
  cursor: pointer;
}
.atlas-topbar .avatar img { width: 100%; height: 100%; object-fit: cover; }

/* ============================================================================
   2. LEFT FILTER RAIL  (.atlas-rail)
   Sections headed by mono eyebrows: trip-length legend, cabin 2x2 grid,
   transfer-from program chips. Hidden on mobile (filters live in the sheet).
   ========================================================================== */
.atlas-rail {
  display: none;                          /* mobile: rail collapses           */
  flex: 0 0 var(--atlas-rail-w);
  width: var(--atlas-rail-w);
  box-sizing: border-box;
  padding: 18px 16px;
  background: var(--surface);
  border-right: 1px solid var(--border);
  overflow-y: auto;
}

.rail-section { margin-bottom: 22px; }
.rail-section:last-child { margin-bottom: 0; }
.rail-section > .atlas-eyebrow { display: block; margin-bottom: 10px; }

/* --- Trip-length LEGEND rows --------------------------------------------- */
/* Each row: a thin color line-swatch (category) + label + count pushed right. */
.legend-row {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  box-sizing: border-box;
  padding: 7px 9px;
  border: 0;
  background: transparent;
  border-radius: var(--r-pill);
  cursor: pointer;
  color: var(--ink);
  text-align: left;
  transition: background 110ms ease, box-shadow 110ms ease;
}
.legend-row:hover { background: var(--bg); }

/* The swatch is the editorial signature: a 16x3 hairline, not a dot. */
.legend-row .swatch {
  flex: 0 0 auto;
  width: 16px;
  height: 3px;
  border-radius: 2px;
  background: var(--muted-3);             /* fallback; overridden per category */
}
.legend-row .label { font-size: 13.5px; line-height: 1; }
/* Count floats to the right edge of the row. */
.legend-row .count {
  margin-left: auto;
  font-family: "DM Mono", ui-monospace, monospace;
  font-size: 11px;
  color: var(--muted-2);
  font-variant-numeric: tabular-nums;
}

/* Selected row = faint inset hairline (ink for default, brass for emphasis). */
.legend-row[aria-pressed="true"],
.legend-row.is-selected {
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--ink) 22%, transparent);
}
.legend-row.is-selected .count { color: var(--ink); }

/* Per-category swatch colors. Class per trip-length bucket; the swatch inherits
   the matching --cat-*-line token. Bucket names MIRROR THE REAL DATA
   (routes.json primary_bucket): all / weekend / one_week / two_weeks, plus the
   purple-flare "outlier" standout. (Tokens defined in atlas.css.) */
.legend-row.cat-all       .swatch { background: var(--cat-all-line); }
.legend-row.cat-weekend   .swatch { background: var(--cat-weekend-line); }
.legend-row.cat-one_week  .swatch { background: var(--cat-one_week-line); }
.legend-row.cat-two_weeks .swatch { background: var(--cat-two_weeks-line); }
.legend-row.cat-outlier .swatch { background: var(--cat-outlier-line); }
/* Selected category rows pick up the soft category fill for a quiet wash. */
.legend-row.cat-all.is-selected        { background: var(--cat-all-bg); }
.legend-row.cat-weekend.is-selected    { background: var(--cat-weekend-bg); }
.legend-row.cat-one_week.is-selected   { background: var(--cat-one_week-bg); }
.legend-row.cat-two_weeks.is-selected  { background: var(--cat-two_weeks-bg); }
.legend-row.cat-outlier.is-selected{ background: var(--cat-outlier-bg); }

/* --- Cabin 2x2 grid ------------------------------------------------------- */
.cabin-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 7px;
}
.cabin-grid button {
  appearance: none;
  cursor: pointer;
  font-family: ui-sans-serif, system-ui, sans-serif;
  font-size: 12.5px;
  color: var(--ink);
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--r-input);
  padding: 9px 8px;
  text-align: center;
  transition: background 110ms ease, color 110ms ease, border-color 110ms ease;
}
.cabin-grid button:hover { border-color: var(--muted-3); }
/* Selected = ink fill, paper text (matches the segmented control). */
.cabin-grid button[aria-pressed="true"],
.cabin-grid button.is-selected {
  background: var(--ink);
  color: var(--surface);
  border-color: var(--ink);
}

/* --- "Transfer from" bank chips (a real toggle filter) ------------------- */
.program-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
/* Clickable bank chips: pick the points you HAVE to show only routes you can book. Disabled when the
   bank reaches no award space in the current feed (so it's never a silent no-op). */
.program-chips .chip {
  appearance: none;
  cursor: pointer;
  font-family: "DM Mono", ui-monospace, monospace;
  font-size: 11px;
  letter-spacing: 0.02em;
  color: var(--muted-1);
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--r-pill);
  padding: 5px 11px;
  transition: background 110ms ease, color 110ms ease, border-color 110ms ease;
}
.program-chips button.chip:hover:not(:disabled) { border-color: var(--muted-3); }
.program-chips button.chip.is-selected,
.program-chips button.chip[aria-pressed="true"] {
  background: var(--ink); color: var(--surface); border-color: var(--ink);
}
.program-chips button.chip:disabled { opacity: .42; cursor: not-allowed; }
.program-chips span.chip { cursor: default; }   /* graceful fallback when the transfer map is unavailable */

/* Per-cabin route-count badge — grounds the cabin filter (e.g. Economy · 96, Business · 93). */
.cabin-grid button .cabin-count {
  margin-left: 5px;
  font-family: "DM Mono", ui-monospace, monospace;
  font-size: 10px;
  opacity: .6;
}
.cabin-grid button .cabin-count:empty { display: none; }

/* ============================================================================
   3. TICKET CARD  (.ticket)
   Logo tile · airline + program · miles + cash · flight timeline · footer.
   The .outlier variant tints purple (the "flare") and adds a tag + context line.
   ========================================================================== */
.ticket {
  position: relative;
  display: block;
  box-sizing: border-box;
  --card-bg: var(--surface);   /* itinerary layover label sits over this to break the hairline cleanly */
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-card);
  box-shadow: var(--shadow-card);
  padding: 14px 16px 12px;
  text-align: left;
  width: 100%;
}

/* Clickable ticket (chat results) -> draws the flight's routing on the globe. */
.ticket.tp-clickable { cursor: pointer; transition: border-color .15s ease, box-shadow .15s ease, transform .15s ease; }
.ticket.tp-clickable:hover { border-color: var(--brass, #b08a3e); box-shadow: 0 4px 16px rgba(0,0,0,.12); }
.ticket.tp-clickable:active { transform: translateY(1px); }
.ticket.tp-clickable:focus-visible { outline: 2px solid var(--brass, #b08a3e); outline-offset: 2px; }

/* Discovery shortlist (Jake "where can my points go?") — tappable city rows */
.disco { display: flex; flex-direction: column; gap: 6px; margin: 8px 0 4px; }
/* nowrap + city-truncates: a long city name (e.g. "Buenos Aires Argentina") ellipsizes rather than
   shoving the cost onto a second line on a ~320px phone — matches the proven classic.html behavior. */
.disco-row { display: flex; flex-wrap: nowrap; justify-content: space-between; align-items: baseline; gap: 10px;
  width: 100%; text-align: left; padding: 9px 12px; border: 1px solid var(--border); border-radius: 10px;
  background: var(--surface); color: var(--ink); cursor: pointer; font: inherit;
  transition: border-color .15s ease, box-shadow .15s ease, transform .1s ease; }
.disco-row:hover { border-color: var(--brass, #b08a3e); box-shadow: 0 3px 12px rgba(0,0,0,.10); }
.disco-row:active { transform: translateY(1px); }
.disco-row:focus-visible { outline: 2px solid var(--brass, #b08a3e); outline-offset: 2px; }
.disco-city { font-weight: 600; font-size: 14px; flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.disco-cc { color: var(--muted-1); font-weight: 400; font-size: 12px; margin-left: 5px; }
.disco-cost { color: var(--muted-1); font-size: 12.5px; text-align: right; flex: 0 0 auto; white-space: nowrap; }
.disco-cost b { color: var(--ink); }
.disco-more { color: var(--muted-1); font-size: 12px; margin: 4px 2px 0; }

/* H6: per-award bookability badge (shows when the user's balances were entered + a transfer path exists) */
.ticket-book { margin-top: 9px; font-size: 12.5px; font-weight: 600; padding: 7px 10px; border-radius: 8px; line-height: 1.4; }
.ticket-book.ok { color: var(--book-deep); background: var(--book-tint-bg); border: 1px solid var(--book-tint-bd); }
/* SHORT-BY: the user holds the right currency but is short — amber/brass (distinct from green "ok"),
   reusing the AAA-contrast brass tokens so it stays theme-safe in light + dark. */
.ticket-book.short { color: var(--brass-deep); background: color-mix(in srgb, var(--brass) 12%, transparent); border: 1px solid color-mix(in srgb, var(--brass) 32%, transparent); }
.ticket-book.no { color: var(--muted-1); background: var(--surface-raised); }
/* The "Purchasable with your points" FLARE pill — green/teal, distinct from the purple OUTLIER tag.
   Sits as a banner row under the ticket head so it never collides with the corner OUTLIER tag. */
.book-flare { display: inline-flex; align-items: center; gap: 5px; margin: 0 0 10px; font-size: 10.5px; font-weight: 600;
  letter-spacing: .05em; text-transform: uppercase; color: var(--book-deep); background: var(--book-tint-bg);
  border: 1px solid var(--book-tint-bd); border-radius: var(--r-pill, 999px); padding: 3px 10px; }
/* v279 (THE ONE THING): the CONSTRAINT-VIOLATION tag ("⚠ taxes $1,589 over your $200 cap") — renders
   BEFORE any green flare with visual weight >= it (heavier weight + the error tokens), so an over-cap
   card can never read as "satisfies your constraints" just because the user's points can afford it. */
.constraint-flare { display: inline-flex; align-items: center; gap: 5px; margin: 0 6px 10px 0; font-size: 10.5px; font-weight: 700;
  letter-spacing: .05em; text-transform: uppercase; color: var(--error); background: color-mix(in srgb, var(--error) 10%, transparent);
  border: 1px solid color-mix(in srgb, var(--error) 40%, transparent); border-radius: var(--r-pill, 999px); padding: 3px 10px; }
/* NS-2a: the SOFT personal tag — an ask-relative note (e.g. "arrives ONT, not LAX") that belongs at
   the same personal altitude as the ⚠ constraint tags but isn't a hard violation: amber, not error-red. */
.constraint-flare--soft { color: var(--trust-warn-deep); background: color-mix(in srgb, var(--trust-warn-line) 12%, transparent);
  border-color: color-mix(in srgb, var(--trust-warn-line) 38%, transparent); }
.coverage-ref-note { color: var(--trust-warn-deep); text-transform: none; letter-spacing: .015em; }

/* ==========================================================================
   NS-2a (northstar Phase 2a) — CERTAINTY AS ONE COMPONENT
   One trust vocabulary, sized as hygiene: the tier header, the card-head
   verdict slot, the below-the-fold trust zone, and the calm strip of checked
   facts. Token-driven only (--trust-* in atlas.css) — no inline styles.
   ========================================================================== */

/* --- Trust-tier header (.trust-tier) — the ONE designed certainty header.
   Three non-overlapping variants (verified / overcap / ideas) replacing the thrice-repeated
   inline-styled mono dividers. Calm section headers in the Atlas voice — the legend's 16x3
   line-swatch signature, a DM Mono eyebrow, a hairline rule, and an optional Newsreader subtitle
   that frames scarcity as rigor ("We hold N to the full bookable contract today…"). Never a banner. */
.trust-tier { display: flex; flex-direction: column; gap: 3px; margin: 10px 0 4px; }
.trust-tier .tt-row { display: flex; align-items: center; gap: 8px; min-width: 0; }
.trust-tier .tt-swatch { flex: 0 0 auto; width: 16px; height: 3px; border-radius: 2px; background: var(--trust-idea-line); }
.trust-tier .tt-label { font-family: "DM Mono", ui-monospace, monospace; font-size: 10px; font-weight: 600;
  letter-spacing: .1em; text-transform: uppercase; color: var(--trust-idea-deep); }
.trust-tier .tt-rule { flex: 1 1 auto; height: 1px; min-width: 12px; background: var(--border-soft); }
.trust-tier .tt-sub { font-family: "Newsreader", Georgia, serif; font-size: 13px; font-style: italic;
  line-height: 1.45; color: var(--muted-1); }
.trust-tier--verified .tt-swatch { background: var(--trust-ok-line); }
.trust-tier--verified .tt-label { color: var(--trust-ok-deep); }
.trust-tier--overcap .tt-swatch { background: var(--trust-warn-line); }
.trust-tier--overcap .tt-label { color: var(--trust-warn-deep); }
.trust-tier--ideas .tt-swatch { background: var(--trust-idea-line); }
.trust-tier--ideas .tt-label { color: var(--trust-idea-deep); }

/* --- Card-head verdict slot (.ticket-verdict) — ALTITUDE DISCIPLINE (§3, non-negotiable): the head
   carries exactly two trust signals — the verdict-tier chip (bound to the bucket the render-time
   predicates placed the row in) and the Phase-3a "Round trip solved" chip in the reserved .rt-slot
   (Tier A only, consumed from the worker rt contract). Nothing else — affordability, freshness,
   routing, taxes, seats all live below the fold, so an affordability signal can never impersonate
   the verdict. Wraps at phone widths (two chips can share the head without widening a 390px card). */
.ticket .ticket-verdict { flex: 0 1 auto; margin-left: auto; display: inline-flex; align-items: center;
  justify-content: flex-end; flex-wrap: wrap; gap: 3px 5px; min-width: 0; max-width: 100%; }
.ticket .rt-slot { display: inline-flex; align-items: center; justify-content: flex-end; flex-wrap: wrap;
  gap: 2px 4px; min-width: 0; max-width: 100%; }
.tier-chip { display: inline-flex; align-items: center; font-family: "DM Mono", ui-monospace, monospace;
  font-size: 9px; font-weight: 600; letter-spacing: .09em; text-transform: uppercase; white-space: nowrap;
  border-radius: var(--r-pill); padding: 3px 8px; color: var(--trust-idea-deep);
  background: var(--surface-raised); border: 1px solid var(--border); }
.tier-chip--verified { color: var(--trust-ok-deep); background: var(--trust-ok-bg); border-color: var(--trust-ok-bd); }
.tier-chip--overcap { color: var(--trust-warn-deep); background: var(--trust-warn-bg); border-color: var(--trust-warn-bd); }
/* .tier-chip--ideas keeps the muted base look */
.ticket .rt-slot:empty { display: none; }

/* --- Below-the-fold trust zone (.ticket-trust) — the visual fold line. Everything that is not the
   fare itself (the affordability flare, the checked-facts strip, the transfer detail) renders under
   this hairline, one altitude below the verdict. */
.ticket .ticket-trust { margin-top: 10px; padding-top: 9px; border-top: 1px solid var(--border-soft); }
.ticket.outlier .ticket-trust { border-top-color: var(--flare-tint-bd); }
.ticket.bookable:not(.outlier) .ticket-trust { border-top-color: var(--book-tint-bd); }
.ticket .ticket-trust .book-flare { margin: 0 0 8px; }
.ticket .ticket-trust .ticket-book { margin-top: 8px; }
.ticket .ticket-trust .xfer-bonus { margin-top: 6px; }

/* --- ONE calm trust strip (.trust-strip) — routing · freshness · seats · taxes · transfer path as
   uniform small chips: "we checked all of these" energy, never a stack of yellow tape. A passing
   check reads "✓ fact" on the quiet chip; a failing/unknown check renders the SAME chip in the amber
   state wearing the honest word ("routing unconfirmed"). Green is reserved for the live-reconfirmed
   freshness stamp — the one affirmative "now" claim the data can back. Wraps at phone widths. */
.trust-strip { display: flex; flex-wrap: wrap; gap: 5px; }
.trust-strip .tc { display: inline-flex; align-items: center; gap: 4px; max-width: 100%; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; font-family: "DM Mono", ui-monospace, monospace;
  font-size: 10.5px; letter-spacing: .02em; line-height: 1.3; color: var(--muted-1);
  background: var(--surface-raised); border: 1px solid var(--border-soft); border-radius: var(--r-pill);
  padding: 4px 9px; }
.trust-strip .tc--ok { color: var(--trust-ok-deep); background: var(--trust-ok-bg); border-color: var(--trust-ok-bd); }
.trust-strip .tc--warn { color: var(--trust-warn-deep); background: var(--trust-warn-bg); border-color: var(--trust-warn-bd); }

/* --- NS-3a — the round-trip verdict chip (.rt-chip, in the v286-reserved head slot). Tier A ONLY —
   the one earned moat claim ("Round trip solved · <the one funding bank>"), on the trust-ok family
   (it is a verified-family claim: computed by the worker rt contract, consumed here). The open-jaw
   disclosure (.rt-jaw) rides beside it whenever the data can't prove the return lands at the
   departure airport — the claim never outruns its predicate. Below Tier A renders at STRIP altitude
   (the honest "two award one-ways" chip in .trust-strip), never here. */
.rt-chip { display: inline-block; font-family: "DM Mono", ui-monospace, monospace;
  font-size: 9px; font-weight: 600; letter-spacing: .09em; text-transform: uppercase; white-space: nowrap;
  min-width: 0; max-width: 100%; overflow: hidden; text-overflow: ellipsis; box-sizing: border-box;
  border-radius: var(--r-pill); padding: 3px 8px; line-height: 1.35;
  color: var(--trust-ok-deep); background: var(--trust-ok-bg); border: 1px solid var(--trust-ok-bd); }
.rt-jaw { font-family: "DM Mono", ui-monospace, monospace; font-size: 9px; letter-spacing: .05em;
  text-transform: uppercase; white-space: nowrap; color: var(--muted-2); }

/* --- NS-2b — the confidence line (.ticket-spark): a QUIET price-history sparkline + the render-time
   cue ("tracked N days"). Calm by design: the histogram inherits the muted ink, the bin holding THIS
   fare takes the brass accent the palette already owns, and the cue is the strip's mono voice. One
   altitude below the verdict (it renders in the fold zone with the strip); max-width guards keep it
   inside a 390px card. Thin history ("new — N days tracked") wears the amber deep, honestly. */
.ticket .ticket-spark { display: flex; align-items: center; gap: 7px; margin-top: 7px; min-width: 0; max-width: 100%; }
.ticket-spark .spark { flex: 0 0 auto; display: block; max-width: 100%; color: var(--muted-3); }
.ticket-spark .spark .sp { fill: currentColor; }
.ticket-spark .spark .sp-you { fill: var(--brass-deep); }
.spark-cue { font-family: "DM Mono", ui-monospace, monospace; font-size: 10.5px; letter-spacing: .02em;
  line-height: 1.3; color: var(--muted-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.spark-cue--thin { color: var(--trust-warn-deep); }

/* ==========================================================================
   POINTS UP FRONT  (#ptsSection in the rail) — "Add your points" hero / "Your points" chip
   ========================================================================== */
.pts-hero { position: relative; overflow: hidden; background: var(--surface-raised);
  border: 1px solid var(--brass-tint-bd); border-radius: var(--r-card, 12px); padding: 13px 14px 14px; }
.pts-hero::before { content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 3px; background: var(--brass); }
.pts-eyebrow { margin: 0 0 3px; font-size: 10px; font-weight: 600; letter-spacing: .14em; text-transform: uppercase; color: var(--brass-deep); }
.pts-h { margin: 0 0 3px; font-family: "Newsreader", Georgia, serif; font-weight: 500; font-size: 18px; color: var(--ink); }
.pts-sub { margin: 0 0 12px; font-size: 12px; line-height: 1.4; color: var(--muted-2); }
.pts-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 8px 9px; }
.pts-field { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.pts-field:last-child:nth-child(odd) { grid-column: 1 / -1; }   /* Bilt (5th) spans full width */
.pts-field label { font-size: 10px; font-weight: 600; color: var(--muted-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pts-field input { font-family: "Newsreader", Georgia, serif; font-variant-numeric: tabular-nums; font-size: 14px;
  color: var(--ink); background: var(--surface-raised); border: 1px solid var(--border); border-radius: 8px; padding: 6px 8px; width: 100%; }
.pts-field input:focus-visible { outline: 2px solid var(--brass-deep); outline-offset: 1px; border-color: var(--brass-deep); }
.pts-save { margin-top: 11px; width: 100%; background: var(--ink); color: var(--bg); border: 0; border-radius: 9px;
  padding: 9px; font-weight: 600; font-size: 12.5px; cursor: pointer; }
.pts-save:hover { background: color-mix(in srgb, var(--ink) 88%, var(--brass)); }
.pts-note { margin: 8px 0 0; font-size: 10.5px; color: var(--muted-3); }
/* collapsed chip (balances set) */
.pts-chip { display: flex; align-items: center; gap: 8px; background: var(--surface-raised);
  border: 1px solid var(--border); border-radius: var(--r-pill, 999px); padding: 8px 12px; }
.pts-chip .pts-star { color: var(--book-deep); font-size: 13px; flex: 0 0 auto; }
.pts-chip .pts-chip-lbl { font-size: 9.5px; font-weight: 600; letter-spacing: .12em; text-transform: uppercase; color: var(--muted-2); flex: 0 0 auto; }
.pts-chip .pts-vals { flex: 1 1 auto; min-width: 0; font-family: "Newsreader", Georgia, serif; font-variant-numeric: tabular-nums;
  font-size: 13px; color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pts-chip .pts-edit { flex: 0 0 auto; background: none; border: 0; color: var(--brass-deep); font-size: 11px; font-weight: 600; cursor: pointer; padding: 2px; }
.pts-chip .pts-edit:hover { text-decoration: underline; }

/* --- Header: logo tile + airline name + program -------------------------- */
.ticket-head {
  display: flex;
  align-items: center;
  gap: 11px;
  margin-bottom: 12px;
}
/* Airline logo tile: light square, rounded 8, hairline border, contained img. The backing must stay
   LIGHT because avs.io logos are colored/dark artwork meant for white — a dark tile makes many vanish
   (verified). In dark mode we drop pure-#fff (a harsh blown-out square on near-black) to the brand's
   warm paper so it reads as an intentional logo card, not a glare. */
.ticket .logo-tile {
  flex: 0 0 auto;
  width: var(--atlas-tile);
  height: var(--atlas-tile);
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 8px;
  display: grid;
  place-items: center;
  overflow: hidden;
}
[data-theme="dark"] .ticket .logo-tile { background: #efe9dd; }
.ticket .logo-tile img {
  width: 26px;
  height: 26px;
  object-fit: contain;
}
.ticket .airline { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.ticket .airline-name {
  font-size: 14px;
  font-weight: 500;
  color: var(--ink);
  line-height: 1.15;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* Award program label — mono, muted, ONLY shown in award mode. */
.ticket .program {
  font-family: "DM Mono", ui-monospace, monospace;
  font-size: 10.5px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted-2);
  line-height: 1;
}
/* AP-0 PARTNER redemption: the program line reads as a sentence qualifier ("booked with Alaska miles"),
   NOT a brand code — drop the mono/uppercase so it can't be mistaken for the operating carrier's own metal. */
.ticket .program.program--partner {
  font-family: inherit;
  text-transform: none;
  letter-spacing: 0.01em;
  font-style: italic;
}
/* Cash mode hides the program line entirely (toggle this class on the root). */
.atlas[data-mode="cash"] .ticket .program { display: none; }

/* --- Price block: miles (big serif) + "+ $cash" right-aligned ------------ */
.ticket-price {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 13px;
}
.ticket .miles {
  font-family: "Newsreader", Georgia, serif;
  font-size: 27px;
  font-weight: 600;
  line-height: 1;
  letter-spacing: -0.01em;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}
.ticket .miles .unit {
  font-family: "DM Mono", ui-monospace, monospace;
  font-size: 11px;
  font-weight: 400;
  letter-spacing: 0.06em;
  color: var(--muted-2);
  margin-left: 5px;
}
.ticket .cash {
  font-family: "Newsreader", Georgia, serif;
  font-size: 15px;
  color: var(--muted-1);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.ticket .cash::before { content: "+ "; color: var(--muted-2); }
/* Hedge for an unknown award co-pay / an unconfirmed premium cabin — muted, no "+" prefix. */
.ticket .tx-hedge { font-size: 12px; color: var(--muted-2); font-style: italic; white-space: nowrap; margin-left: 6px; }
/* Direct booking link (cash rows from Travelpayouts/Aviasales). */
/* --brass-deep is the designated TEXT/link brass (7.4:1 on --surface in light); bare --brass is the
   fill/arc accent and only 2.85:1 as text in light — WCAG AA fail. Border tint keeps --brass (non-text). */
.ticket-booklink { display: inline-block; margin-top: 8px; font-size: 12.5px; font-weight: 600; color: var(--brass-deep);
  text-decoration: none; border: 1px solid color-mix(in srgb, var(--brass) 45%, transparent); border-radius: 8px; padding: 5px 10px; }
.ticket-booklink:hover { background: color-mix(in srgb, var(--brass) 12%, transparent); }

/* CASH business-class comparison: what business costs on the SAME route+dates, rendered only when
   every leg proved business. Deliberately quiet — it is context beneath the headline economy fare,
   not a competing verdict, so it takes muted text and never the brass accent. */
.ticket-biz { margin-top: 6px; font-size: 12px; color: var(--muted-1); font-variant-numeric: tabular-nums; }
.ticket-biz span { color: var(--muted-2); }

/* FTC 16 CFR Part 255 affiliate disclosure — sits directly under the cash "Book ↗" it discloses.
   Deliberately NOT muted into invisibility: "clear and conspicuous" is the legal standard, so this
   takes --muted-1 (the readable muted) rather than the fainter --muted-2, holds 11.5px (never below
   the 11px floor), and is never hidden, collapsed, or tucked behind a disclosure toggle. */
.affil-note { display: block; margin-top: 6px; font-size: 11.5px; line-height: 1.45;
  color: var(--muted-1); max-width: 46ch; }

/* --- Itinerary: per-leg date + endpoints (code + time) + layover (airport · length). Shows the
   departure date, departure/arrival times, and layover location & length the chat now carries; each
   field renders only when known and gracefully omits otherwise. --- */
.itin { display: flex; flex-direction: column; gap: 9px; margin: 2px 0 1px; }
.itin .il-leg { display: flex; flex-direction: column; gap: 3px; }
.itin .il-date { font: 500 10px/1 "DM Mono", ui-monospace, monospace; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--muted-2); }
.itin .il-row { display: flex; align-items: center; gap: 8px; }
.itin .il-ep { flex: 0 0 auto; display: flex; flex-direction: column; }
.itin .il-ep:last-child { align-items: flex-end; text-align: right; }
.itin .il-ep b { font-family: "Newsreader", Georgia, serif; font-size: 16px; font-weight: 600;
  line-height: 1.05; color: var(--ink); letter-spacing: 0.01em; }
.itin .il-ep .il-t, .itin .il-ep .il-c { font: 500 10.5px/1 "DM Mono", ui-monospace, monospace;
  font-style: normal; letter-spacing: 0.04em; margin-top: 3px; font-variant-numeric: tabular-nums; }
.itin .il-ep .il-t { color: var(--ink); }
.itin .il-ep .il-c { color: var(--muted-2); }
.itin .il-mid { flex: 1 1 auto; min-width: 0; text-align: center; position: relative; }
.itin .il-mid::before { content: ""; position: absolute; left: 0; right: 0; top: 50%; height: 1px; background: var(--border); }
.itin .il-via { position: relative; padding: 0 7px; background: var(--card-bg, var(--surface));
  font: 500 10px/1.3 "DM Mono", ui-monospace, monospace; letter-spacing: 0.02em; color: var(--muted-1);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; display: inline-block; }
.itin .il-mid.ns .il-via { color: var(--muted-2); }

/* --- Footer: seat pill + cabin + nights ---------------------------------- */
.ticket-foot {
  display: flex;
  align-items: center;
  gap: 9px;
  margin-top: 13px;
  padding-top: 11px;
  border-top: 1px solid var(--border-soft);
}
/* Seat-availability pill — uses dedicated seat tokens. */
.ticket .seat-pill {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-family: "DM Mono", ui-monospace, monospace;
  font-size: 10.5px;
  letter-spacing: 0.03em;
  color: var(--seat-fg);
  background: var(--seat-bg);
  border-radius: var(--r-pill);
  padding: 3px 9px;
}
.ticket .foot-meta {
  font-family: "DM Mono", ui-monospace, monospace;
  font-size: 11px;
  color: var(--muted-2);
}
/* dot separator between cabin and nights metadata. */
/* --muted-2 == --muted-3 by design (both tuned to clear AA), so the dot separator needs its own
   step-down to read one notch quieter than the meta text it sits between. */
.ticket .foot-meta .sep { margin: 0 6px; color: var(--muted-3); opacity: .7; }
.ticket .foot-meta .nights { color: var(--muted-1); }

/* --- OUTLIER variant -------------------------------------------------- */
/* Purple "flare": tint surface + a soft outer glow + tag + context line ("21% below median"). */
.ticket.outlier {
  --card-bg: var(--flare-tint-bg);
  background: var(--flare-tint-bg);
  border-color: var(--flare-tint-bd);
  box-shadow: 0 0 0 1px var(--flare-tint-bd), 0 6px 22px var(--flare-glow);
}
.ticket.outlier .ticket-foot { border-top-color: var(--flare-tint-bd); }
/* --- BOOKABLE variant (green) — "you can book this with your points". Mirrors the outlier flare in
   green, but OUTLIER (purple) wins the card tint when a fare is both, so the two signals never blur. */
.ticket.bookable:not(.outlier) {
  --card-bg: var(--book-tint-bg);
  background: color-mix(in srgb, var(--book-tint-bg) 55%, var(--surface));
  border-color: var(--book-tint-bd);
  box-shadow: 0 0 0 1px var(--book-tint-bd), 0 6px 22px var(--book-glow);
}
.ticket.bookable:not(.outlier) .ticket-foot { border-top-color: var(--book-tint-bd); }
/* The OUTLIER tag — top-right corner, mono, purple flare. */
.ticket.outlier .outlier-tag {
  position: absolute;
  top: 12px;
  right: 14px;
  font-family: "DM Mono", ui-monospace, monospace;
  font-size: 9px;
  font-weight: 500;
  letter-spacing: 0.14em;   /* match the spec's eyebrow tracking (§2) */
  text-transform: uppercase;
  color: var(--flare-deep);
  background: var(--surface);
  border: 1px solid var(--flare-tint-bd);
  border-radius: var(--r-pill);
  padding: 3px 8px;
}
/* (The outlier "context line" is rendered as .outlier-note and styled inline in index.html; the
   former .outlier-context rules here were dead — the markup never used that class — so they're removed.) */

/* ============================================================================
   4. LIST VIEW table  (.atlas-list)
   Columns: Destination · Route · Airline · Schedule · Seats · +Cash · Miles.
   Outlier rows tint brass with a 3px brass inset left bar. Sort control.
   ========================================================================== */
.atlas-list { width: 100%; }

/* --- Sort control (Best value / Miles / Cash) ---------------------------- */
.list-sort {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 12px;
}
.list-sort .label {
  font-family: "DM Mono", ui-monospace, monospace;
  font-size: 10px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted-2);
}
.list-sort .options { display: inline-flex; gap: 4px; }
.list-sort button {
  appearance: none;
  cursor: pointer;
  font-family: "DM Mono", ui-monospace, monospace;
  font-size: 11.5px;
  color: var(--muted-1);
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--r-pill);
  padding: 4px 11px;
  transition: color 110ms ease, background 110ms ease, border-color 110ms ease;
}
.list-sort button:hover { color: var(--ink); }
.list-sort button[aria-pressed="true"],
.list-sort button.is-active {
  color: var(--ink);
  background: var(--surface-raised);
  border-color: var(--border);
}

/* --- The table ----------------------------------------------------------- */
.atlas-list table {
  width: 100%;
  border-collapse: collapse;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-card);
  overflow: hidden;            /* clip the rounded corners over rows         */
}
.atlas-list thead th {
  font-family: "DM Mono", ui-monospace, monospace;
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted-2);
  text-align: left;
  padding: 11px 14px;
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}
/* Numeric columns right-align. */
.atlas-list th.num,
.atlas-list td.num { text-align: right; font-variant-numeric: tabular-nums; }
/* Sortable column headers: click / keyboard to sort; the active column shows a direction caret. */
.atlas-list th.sortable { cursor: pointer; user-select: none; }
.atlas-list th.sortable:hover { color: var(--ink); }
.atlas-list th.sortable:focus-visible { outline: 2px solid var(--brass-deep); outline-offset: -2px; }
.atlas-list th.sortable.sorted { color: var(--brass-deep); }
.atlas-list th .sort-caret { font-size: 9px; }

.atlas-list tbody td {
  padding: 13px 14px;
  border-bottom: 1px solid var(--border-soft);
  font-size: 13px;
  color: var(--ink);
  vertical-align: middle;
}
.atlas-list tbody tr:last-child td { border-bottom: 0; }
.atlas-list tbody tr { transition: background 100ms ease; }
.atlas-list tbody tr:hover { background: var(--bg); }

/* Destination cell — editorial serif, the column you read first. */
.atlas-list td.destination {
  font-family: "Newsreader", Georgia, serif;
  font-size: 16px;
  font-weight: 500;
  letter-spacing: -0.005em;
}
.atlas-list td.route,
.atlas-list td.schedule {
  font-family: "DM Mono", ui-monospace, monospace;
  font-size: 11.5px;
  color: var(--muted-1);
  letter-spacing: 0.02em;
}
.atlas-list td.miles {
  font-family: "Newsreader", Georgia, serif;
  font-size: 16px;
  font-weight: 600;
}
.atlas-list td.cash { color: var(--muted-1); }
/* Airline cell — carrier LOGO + full name, with the loyalty program as an eyebrow beneath (award). */
.atlas-list .al { display: inline-flex; align-items: center; gap: 7px; max-width: 100%; }
.atlas-list .al-logo { width: 18px; height: 18px; border-radius: 4px; flex: 0 0 auto;
  object-fit: contain; background: var(--surface-raised); }
.atlas-list .al-name { font-size: 13px; color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.atlas-list .al-prog { display: block; margin-top: 3px; }
/* AP-0 partner redemption: "booked with <brand> miles" reads as a qualifier (normal case, italic), so the
   list never juxtaposes a carrier with a program that isn't its own metal as if they were the same brand. */
.atlas-list .al-prog--partner { font-style: italic; text-transform: none; letter-spacing: normal; }
/* Seats cell hosts a compact seat pill. */
.atlas-list td.seats .seat-pill {
  display: inline-flex;
  align-items: center;
  font-family: "DM Mono", ui-monospace, monospace;
  font-size: 10px;
  color: var(--seat-fg);
  background: var(--seat-bg);
  border-radius: var(--r-pill);
  padding: 2px 7px;
}

/* Outlier row: purple-flare tint + a 3px purple inset left bar. */
.atlas-list tr.outlier td { background: var(--flare-tint-bg); }
.atlas-list tr.outlier:hover td { background: var(--flare-tint-bg); }
.atlas-list tr.outlier td:first-child {
  box-shadow: inset 3px 0 0 0 var(--flare-line);
}
.atlas-list tr.outlier td.miles { color: var(--flare-deep); }

/* ============================================================================
   5. MOBILE
   Phone-frame helper · draggable bottom sheet · bottom tab bar ·
   route-detail screen (fare, itinerary, transfer paths, sticky book bar).
   ========================================================================== */

/* --- Phone-frame layout helper ------------------------------------------- */
/* Wraps a mobile mock; on large screens it renders a device chrome, on a real
   phone it just fills the viewport. Purely a presentation helper. */
.phone-frame {
  position: relative;
  width: 100%;
  max-width: 390px;
  margin: 0 auto;
  min-height: 100dvh;
  background: var(--bg);
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
@media (min-width: 760px) {
  /* Show an actual device shell when there's room to frame it. */
  .phone-frame {
    min-height: auto;
    height: 780px;
    border: 10px solid var(--ink);
    border-radius: 44px;
    box-shadow: var(--shadow-float);
  }
}

/* --- Draggable bottom sheet  (.sheet) ------------------------------------ */
/* Holds the deal stack; slides up over the globe. JS drives the drag and the
   .is-peek / .is-open / .is-full state classes; CSS owns the look + motion. */
.sheet {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 20;
  display: flex;
  flex-direction: column;
  max-height: 92%;
  background: var(--surface);
  border-top-left-radius: var(--r-card);
  border-top-right-radius: var(--r-card);
  box-shadow: var(--shadow-float);
  transform: translateY(calc(100% - 132px));   /* default peek height        */
  transition: transform 240ms cubic-bezier(.32, .72, 0, 1);
  touch-action: none;          /* let JS own the drag gesture                 */
}
.sheet.is-peek { transform: translateY(calc(100% - 132px)); }
.sheet.is-open { transform: translateY(25%); }
.sheet.is-full { transform: translateY(0); }
/* While the user is actively dragging, kill the transition for 1:1 tracking. */
.sheet.is-dragging { transition: none; }

/* Grab handle. */
.sheet .grabber {
  flex: 0 0 auto;
  align-self: center;
  width: 38px;
  height: 4px;
  margin: 9px 0 6px;
  border-radius: 2px;
  background: var(--muted-3);
  cursor: grab;
}
.sheet.is-dragging .grabber { cursor: grabbing; }
.sheet .sheet-head {
  flex: 0 0 auto;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  padding: 2px 16px 10px;
  border-bottom: 1px solid var(--border-soft);
}
.sheet .sheet-title {
  font-family: "Newsreader", Georgia, serif;
  font-size: 18px;
  font-weight: 600;
  color: var(--ink);
}
.sheet .sheet-count {
  font-family: "DM Mono", ui-monospace, monospace;
  font-size: 11px;
  color: var(--muted-2);
}
/* Scrollable body; momentum scroll only takes over once the sheet is open. */
.sheet .sheet-body {
  flex: 1 1 auto;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  padding: 12px 14px calc(16px + env(safe-area-inset-bottom));
  display: flex;
  flex-direction: column;
  gap: 11px;
}

/* --- Bottom tab bar  (.tabbar): Globe / List / Watched / You ------------- */
.tabbar {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 30;
  display: grid;
  grid-auto-flow: column;          /* one row, N equal columns — adapts to 4 OR 5 tabs (Filters added on mobile) */
  grid-auto-columns: 1fr;
  background: var(--surface);
  border-top: 1px solid var(--border);
  padding-bottom: env(safe-area-inset-bottom);
}
.tabbar .tab {
  appearance: none;
  border: 0;
  background: transparent;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
  padding: 9px 0 7px;
  color: var(--muted-2);
  transition: color 110ms ease;
}
.tabbar .tab svg { width: 21px; height: 21px; }
.tabbar .tab .tab-label {
  font-family: "DM Mono", ui-monospace, monospace;
  font-size: 10.5px;     /* >= ~11px so labels stay legible on low-DPI phones */
  letter-spacing: 0.03em;
}
.tabbar .tab:hover { color: var(--muted-1); }
.tabbar .tab[aria-current="page"],
.tabbar .tab.is-active { color: var(--ink); }       /* active tab = full ink (icon + label) */
/* (brass is reserved for outlier fares — the active tab uses ink, not a brass icon accent) */

/* --- Outlier-fares entry points (topbar pill · rail call-to-action · list header) ---------
   Brass is the app's outlier-fare accent, so these standouts wear it. They were buried in the
   filter rail; these surface them "up top". */
.outlier-star { color: var(--flare-line); }
.outlier-link {
  appearance: none; cursor: pointer; white-space: nowrap;
  display: inline-flex; align-items: center; gap: 5px;
  font-family: 'DM Mono', ui-monospace, monospace; font-size: 12px; letter-spacing: .03em;
  color: var(--flare-deep); background: var(--flare-tint-bg);
  border: 1px solid var(--flare-tint-bd); border-radius: var(--r-pill);
  padding: 7px 13px; transition: background .15s, border-color .15s;
}
.outlier-link:hover { background: var(--flare-tint-bd); }

/* Item 2: the active feed's last-refreshed + next-update stamp (build version in its title tooltip). */
.feed-stamp {
  white-space: nowrap; cursor: default;
  font-family: 'DM Mono', ui-monospace, monospace; font-size: 11px; letter-spacing: .02em;
  color: var(--muted-2);
}
.feed-stamp[hidden] { display: none; }

/* iOS-Safari "Add to Home Screen" hint — a dismissible bottom banner sitting above the mobile tab bar. */
.ios-hint {
  position: fixed; z-index: 1800; left: 12px; right: 12px;
  bottom: calc(56px + env(safe-area-inset-bottom, 0px) + 10px);
  display: flex; align-items: center; gap: 10px;
  max-width: 460px; margin: 0 auto; padding: 11px 13px;
  background: var(--surface-raised, var(--surface)); color: var(--ink);
  border: 1px solid var(--border); border-radius: 14px;
  box-shadow: 0 8px 28px rgba(0, 0, 0, .18);
  font: 500 13px/1.4 -apple-system, system-ui, sans-serif;
}
.ios-hint .ios-hint-txt { flex: 1 1 auto; }
.ios-hint b { color: var(--brass-deep, var(--ink)); font-weight: 700; }
.ios-hint .ios-hint-x {
  flex: 0 0 auto; appearance: none; cursor: pointer; border: 0; background: none;
  color: var(--muted-2); font-size: 20px; line-height: 1; padding: 2px 4px; border-radius: 8px;
}
.ios-hint .ios-hint-x:hover { color: var(--ink); }
.outlier-rail {
  appearance: none; cursor: pointer; width: 100%; text-align: left;
  display: flex; align-items: center; gap: 10px;
  background: var(--flare-tint-bg); border: 1px solid var(--flare-tint-bd);
  border-radius: var(--r-card); padding: 11px 13px; margin: 0 0 14px;
  color: var(--flare-deep); transition: background .15s, border-color .15s;
}
.outlier-rail:hover { background: var(--flare-tint-bd); }
.outlier-rail .outlier-star { font-size: 17px; flex: 0 0 auto; }
.outlier-rail-txt { display: flex; flex-direction: column; flex: 1; min-width: 0;
  font-family: 'DM Mono', ui-monospace, monospace; font-size: 12.5px; }
.outlier-rail-txt small { font-family: -apple-system, system-ui, sans-serif; font-size: 11px;
  color: var(--muted-1); margin-top: 2px; letter-spacing: 0; }
.outlier-go { color: var(--flare-line); flex: 0 0 auto; font-size: 15px; }
.outlier-head {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  background: var(--flare-tint-bg); border: 1px solid var(--flare-tint-bd);
  border-radius: var(--r-card); padding: 12px 14px; margin: 0 0 12px;
}
.outlier-head-txt { display: flex; flex-direction: column; min-width: 0;
  font-family: 'Newsreader', Georgia, serif; font-size: 17px; color: var(--ink); }
.outlier-head-txt small { font-family: 'DM Mono', ui-monospace, monospace; font-size: 11px;
  color: var(--muted-1); text-transform: uppercase; letter-spacing: .04em; margin-top: 4px; }
.outlier-clear {
  appearance: none; cursor: pointer; white-space: nowrap;
  font-family: 'DM Mono', ui-monospace, monospace; font-size: 11.5px;
  color: var(--flare-deep); background: transparent;
  border: 1px solid var(--flare-tint-bd); border-radius: var(--r-pill); padding: 8px 12px;
}
.outlier-clear:hover { background: var(--flare-tint-bg); }
.outlier-ledger-link { color: var(--flare-deep); text-decoration: none; }
.outlier-ledger-link:hover, .outlier-ledger-link:focus-visible { text-decoration: underline; text-underline-offset: 2px; }

/* --- Route-detail screen ------------------------------------------------- */
/* Full-bleed mobile screen: fare header, itinerary timeline, transfer-path
   rows, then a sticky book bar pinned to the bottom. */
.route-detail {
  display: flex;
  flex-direction: column;
  min-height: 100%;
  background: var(--bg);
}
.route-detail .rd-scroll {
  flex: 1 1 auto;
  overflow-y: auto;
  padding: 16px 16px 96px;     /* leave room for the sticky book bar         */
}

/* Fare header. */
.route-detail .rd-fare {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  padding-bottom: 16px;
  border-bottom: 1px solid var(--border-soft);
}
.route-detail .rd-fare .miles {
  font-family: "Newsreader", Georgia, serif;
  font-size: 30px;
  font-weight: 600;
  line-height: 1;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}
.route-detail .rd-fare .miles .unit {
  font-family: "DM Mono", ui-monospace, monospace;
  font-size: 11px;
  font-weight: 400;
  color: var(--muted-2);
  margin-left: 5px;
}
.route-detail .rd-fare .cash {
  font-family: "Newsreader", Georgia, serif;
  font-size: 16px;
  color: var(--muted-1);
}

/* Section eyebrow inside the detail screen. */
.route-detail .rd-section { margin-top: 22px; }
.route-detail .rd-section > .atlas-eyebrow { display: block; margin-bottom: 12px; }

/* Itinerary timeline — vertical leg list (dep/arr stacked with a spine). */
.itinerary { display: flex; flex-direction: column; }
.itinerary .leg {
  position: relative;
  display: grid;
  grid-template-columns: 56px 1fr;
  gap: 12px;
  padding-left: 4px;
}
/* Vertical spine connecting legs. */
.itinerary .leg::before {
  content: "";
  position: absolute;
  left: 60px;                  /* aligns with the node column                 */
  top: 18px;
  bottom: -4px;
  width: 1px;
  background: var(--border);
}
.itinerary .leg:last-child::before { display: none; }
.itinerary .leg-time {
  font-family: "Newsreader", Georgia, serif;
  font-size: 15px;
  font-weight: 500;
  color: var(--ink);
  text-align: right;
  font-variant-numeric: tabular-nums;
  padding-top: 1px;
}
.itinerary .leg-body { padding-bottom: 18px; position: relative; }
/* The node dot sits on the spine. */
.itinerary .leg-body::before {
  content: "";
  position: absolute;
  left: -16px;
  top: 5px;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--surface);
  border: 1.5px solid var(--muted-2);
}
.itinerary .leg-airport {
  font-family: "DM Mono", ui-monospace, monospace;
  font-size: 12px;
  letter-spacing: 0.04em;
  color: var(--ink);
}
.itinerary .leg-sub {
  font-size: 12px;
  color: var(--muted-2);
  margin-top: 2px;
}
/* Layover row between legs. */
.itinerary .layover {
  grid-column: 2;
  font-family: "DM Mono", ui-monospace, monospace;
  font-size: 10.5px;
  color: var(--muted-2);
  padding: 4px 0 14px;
}

/* Transfer-path rows — "Amex MR -> Air France/KLM · 1:1 · instant". */
.transfer-path { display: flex; flex-direction: column; gap: 8px; }
.transfer-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 11px 12px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-tile);
}
.transfer-row .from,
.transfer-row .to { font-size: 13px; color: var(--ink); font-weight: 500; }
.transfer-row .arrow { color: var(--muted-3); flex: 0 0 auto; }
.transfer-row .meta {
  margin-left: auto;
  font-family: "DM Mono", ui-monospace, monospace;
  font-size: 10.5px;
  color: var(--muted-2);
  text-align: right;
  white-space: nowrap;
}
.transfer-row .meta .ratio { color: var(--ink); }
.transfer-row .meta .speed.instant { color: var(--brass-deep); }

/* Sticky book bar — pinned to the bottom of the detail screen. */
.book-bar {
  position: sticky;
  bottom: 0;
  z-index: 10;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 16px calc(12px + env(safe-area-inset-bottom));
  background: var(--surface);
  border-top: 1px solid var(--border);
}
.book-bar .bb-fare { display: flex; flex-direction: column; line-height: 1.2; }
.book-bar .bb-miles {
  font-family: "Newsreader", Georgia, serif;
  font-size: 18px;
  font-weight: 600;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}
.book-bar .bb-cash {
  font-family: "DM Mono", ui-monospace, monospace;
  font-size: 11px;
  color: var(--muted-2);
}
/* Primary action — brass fill, the one solid-accent button in the system. */
.book-bar .bb-cta {
  appearance: none;
  margin-left: auto;
  cursor: pointer;
  font-family: ui-sans-serif, system-ui, sans-serif;
  font-size: 14px;
  font-weight: 600;
  color: var(--seat-fg);
  background: var(--brass);
  border: 1px solid var(--brass-deep);
  border-radius: var(--r-pill);
  padding: 11px 22px;
  transition: background 120ms ease;
}
.book-bar .bb-cta:hover { background: var(--brass-deep); }

/* ============================================================================
   6. RESPONSIVE LAYOUT
   Mobile-first: base is the phone. Layer the desktop topbar + rail + list
   grid at progressively wider breakpoints. The app shell composes pieces;
   this just decides when the rail appears and how dense the chrome gets.
   ========================================================================== */

/* App shell: rail beside content once there's room. */
.atlas-shell { display: flex; min-height: 0; }

/* --- Small tablets / large phones (>= 640px) ----------------------------- */
@media (min-width: 640px) {
  /* Topbar can breathe; show all controls inline (already inline by default). */
  .atlas-topbar { gap: 16px; }
}

/* --- Mid desktop (880-1099px): the topbar is single-row but cramped, so the flex-grow search ate the
   space and shoved the fixed "New York ▾" origin selector under its own right edge ("…York ▾" clipped
   behind the search). Tighten the gap + let the search shrink further so every fixed control (origin,
   view toggle, day/night) stays fully visible. */
@media (min-width: 880px) and (max-width: 1099.98px) {
  .atlas-topbar { gap: 10px; }
  .atlas-search { min-width: 90px; flex: 1 1 90px; }
  .origin-select { flex: 0 0 auto; }   /* never shrink the origin pill — it must read in full */
  /* P1 (topbar overflow): at this tight width shed the two fattest DISCRETIONARY items so the right-edge
     controls (day/night, settings, avatar) can't be pushed off the viewport. The feed-stamp's info lives in
     its title tooltip + the account panel; Install stays reachable from the account panel (#acctInstall). */
  .atlas-topbar .feed-stamp { display: none; }
  .atlas-topbar .install-btn { display: none; }
}

/* --- Tablet / small desktop (>= 880px): rail appears ---------------------- */
@media (min-width: 880px) {
  .atlas-rail { display: block; }     /* the left filter rail comes in        */
  /* Bottom sheet + tab bar are mobile-only affordances — hide on desktop. */
  .sheet,
  .tabbar { display: none; }
  /* On desktop the deal stack flows as cards in a grid instead of a sheet. */
  .ticket-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
    gap: 14px;
    padding: var(--atlas-gap);
  }
}

/* --- Desktop (>= 1100px): roomier rail + multi-col cards ------------------ */
@media (min-width: 1100px) {
  .atlas { --atlas-rail-w: 230px; }
  .ticket-grid { grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); }
}

/* On true mobile, the list view collapses to stacked cards instead of a wide
   table (the table would overflow horizontally). Below 880px, prefer cards. */
@media (max-width: 879.98px) {
  .atlas-list table { display: none; }       /* hide the wide table          */
  .atlas-list.cards .ticket { margin-bottom: 11px; }
  /* #6 Touch targets: the primary rail/topbar filter controls render 25-36px tall by default — bring
     them to the 44px mobile minimum (radii/horizontal padding unchanged; the more-specific
     .atlas-topbar .segmented button keeps its tightened padding). Desktop (>=880px) is untouched. */
  .segmented button { min-height: 44px; display: inline-flex; align-items: center; }
  .cabin-grid button { min-height: 44px; }
  .program-chips .chip { min-height: 44px; display: inline-flex; align-items: center; padding: 9px 13px; }
  .legend-row { min-height: 44px; }
}

/* ----------------------------------------------------------------------------
   7. Motion & accessibility
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .sheet,
  .segmented button,
  .cabin-grid button,
  .legend-row,
  .list-sort button,
  .tabbar .tab,
  .book-bar .bb-cta {
    transition: none;
  }
}

/* Visible keyboard focus for every interactive control — brass, flat. */
.atlas-topbar button:focus-visible,
.segmented button:focus-visible,
.atlas-search input:focus-visible,
.origin-select:focus-visible,
.daynight:focus-visible,
.legend-row:focus-visible,
.cabin-grid button:focus-visible,
.ticket:focus-visible,
.list-sort button:focus-visible,
.tabbar .tab:focus-visible,
.transfer-row:focus-visible,
.book-bar .bb-cta:focus-visible {
  outline: 2px solid var(--brass-deep);   /* brass-deep clears the 3:1 non-text focus-ring minimum on light (brass was 2.65:1) */
  outline-offset: 2px;
}

/* ----------------------------------------------------------------------------
   8. P4-CONCIERGE (variant B preview): the ONE Jake rail (#jkRail)
   Token-driven component look; shown only under body.jk-stage (the state glue
   lives in app.html's shell-glue block). The rail wears the sanctioned frosted
   -glass .tp treatment, docked to the right edge — the globe breathes beside
   it and its arcs pass under the glass.
   -------------------------------------------------------------------------- */
.jk-rail { display: none; }
body.jk-stage .jk-rail { display: flex; flex-direction: column; position: absolute;
  top: 10px; right: 10px; bottom: 10px; width: var(--jk-rail-w, 420px); z-index: 32;
  background: color-mix(in srgb, var(--surface-raised) 88%, transparent);
  backdrop-filter: blur(14px) saturate(1.1); -webkit-backdrop-filter: blur(14px) saturate(1.1);
  border: 1px solid var(--border); border-radius: 16px; box-shadow: var(--shadow-float);
  overflow: hidden; }
.jk-head { flex: 0 0 auto; padding: 12px 14px 10px; border-bottom: 1px solid var(--border);
  display: flex; flex-direction: column; gap: 9px; }
.jk-id { margin: 0; display: flex; align-items: baseline; gap: 7px; min-width: 0;
  font-family: "Newsreader", Georgia, serif; font-size: 16px; color: var(--ink); }
.jk-id b { font-weight: 600; }
.jk-id-ic { color: var(--flare-deep); font-size: 14px; flex: 0 0 auto; }
.jk-id-sub { font-size: 12px; font-style: italic; color: var(--muted-1);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.jk-nav { display: flex; gap: 5px; flex-wrap: wrap; }
.jk-tab { flex: 0 0 auto; min-height: 34px; padding: 7px 12px; border: 1px solid var(--border);
  border-radius: 999px; background: transparent; color: var(--muted-1);
  font: 600 11.5px/1 -apple-system, system-ui, sans-serif; cursor: pointer;
  transition: border-color .15s, background .15s, color .15s; }
.jk-tab:hover { border-color: var(--muted-3); color: var(--ink); }
.jk-tab.is-active { background: var(--ink); border-color: var(--ink); color: var(--bg); }
/* the honest one-line narration over a lens ("12 outliers today … — best value first") */
.jk-note { flex: 0 0 auto; margin: 0; padding: 8px 14px; border-bottom: 1px solid var(--border-soft);
  font: 500 11px/1.5 "DM Mono", ui-monospace, monospace; letter-spacing: .04em; color: var(--muted-2); }
.jk-note[hidden] { display: none; }
/* CONTEXTUAL HEADER (owner-flagged): ONE descriptor line for the CURRENT lens, swapped by jkShow. */
.jk-ctx { margin: 0; font: 500 12px/1.45 "Newsreader", Georgia, serif; font-style: italic; color: var(--muted-1); }
.jk-ctx:empty { display: none; }
/* the two list lenses share one scrolling column body */
.jk-board, .jk-search { flex: 1 1 auto; min-height: 0; overflow-y: auto; overflow-x: hidden;
  padding: 10px 12px 14px; display: flex; flex-direction: column; gap: 7px; }
/* children must OVERFLOW the scrolling column, never flex-shrink into 2px slivers */
.jk-board > *, .jk-search > *, .jk-sf-results > * { flex: 0 0 auto; }
.jk-board[hidden], .jk-search[hidden] { display: none; }
#jkRail:not(.jk-s-board) .jk-board { display: none; }
.jk-detail { flex: 1 1 auto; min-height: 0; overflow-y: auto; overflow-x: hidden; padding: 10px 14px 16px; }
.jk-detail[hidden] { display: none; }
/* POPUP PEEK (owner-flagged): an OVERLAY over the DIMMED board — a scrim + a centered card + ‹ › arrows.
   NEVER a rail state (the board stays mounted behind it). Absolute within the rail so the scrim dims only
   the board, and the globe (left of the rail) stays bright and glides behind the popup. */
.jk-peek { position: absolute; inset: 0; z-index: 60; display: flex; align-items: center; justify-content: center;
  padding: 16px; }
.jk-peek[hidden] { display: none; }
.jk-peek-scrim { position: absolute; inset: 0; background: color-mix(in srgb, var(--ink) 34%, transparent);
  -webkit-backdrop-filter: blur(2px); backdrop-filter: blur(2px); cursor: pointer; }
.jk-peek-card { position: relative; z-index: 1; width: 100%; max-width: 380px; max-height: 100%; overflow-y: auto;
  overflow-x: hidden; background: var(--surface-raised); border: 1px solid var(--border); border-radius: 16px;
  box-shadow: var(--shadow-float); padding: 16px 16px 14px; }
.jk-peek-x { position: absolute; top: 8px; right: 8px; z-index: 3; min-width: 30px; min-height: 30px; border: 0;
  border-radius: 8px; background: color-mix(in srgb, var(--surface) 70%, transparent); color: var(--muted-1);
  font-size: 18px; line-height: 1; cursor: pointer; }
.jk-peek-x:hover { color: var(--ink); background: var(--surface); }
/* ‹ › ride the outer overlay edges so they flip the list without crowding the card */
.jk-peek-arrow { position: absolute; top: 50%; transform: translateY(-50%); z-index: 3; min-width: 40px;
  min-height: 40px; border: 1px solid var(--border); border-radius: 50%; background: var(--surface-raised);
  color: var(--ink); font-size: 22px; line-height: 1; cursor: pointer; box-shadow: var(--shadow-float);
  display: flex; align-items: center; justify-content: center; }
.jk-peek-arrow.prev { left: 6px; }
.jk-peek-arrow.next { right: 6px; }
.jk-peek-arrow:hover { border-color: var(--brass); }
.jk-peek-arrow:disabled { opacity: .3; cursor: default; box-shadow: none; }
.jk-peek-head { display: flex; align-items: baseline; gap: 9px; margin: 0 0 9px; min-width: 0; padding-right: 26px; }
.jk-peek-head h2 { margin: 0; font-size: 22px; }
.jk-peek-head .atlas-eyebrow { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.jk-peek-head .jkr-save { flex: 0 0 auto; margin-left: auto; border-left: 0; font-size: 19px;
  align-self: center; min-width: 34px; min-height: 34px; border-radius: 8px; }
.jk-peek .ticket { max-width: none; }
.jk-peek-all { display: block; width: 100%; margin: 12px 0 4px; text-align: center; }
/* honest provenance / standout reason on the popup (mirrors the row markers) */
.jk-peek-carry { margin: 0 0 9px; font: 500 11.5px/1.5 "DM Mono", ui-monospace, monospace; color: var(--muted-1); }
.jk-peek-why { margin: 0 0 9px; font: 600 12px/1.45 -apple-system, system-ui, sans-serif; color: var(--cat-gold-deep, #8a6a12); }
/* ===================================================================================================
   GLOBE FARE BUBBLE (Variant B, v294) — a floating best-fare card that rises off the globe over the
   clicked destination node (pointer/tail down to it). Positioned by JS (left/top set inline, clamped to
   the #map viewport); this is only its look + the pointer tail. Desktop-only — the mobile proof-band
   keeps the rail dive, so no ≤760px rules are needed here. Token-driven; no hard-coded palette.
   =================================================================================================== */
.globe-bubble { position: absolute; z-index: 46; left: 0; top: 0; width: max-content; max-width: 340px;
  background: var(--surface); border: 1px solid var(--border); border-radius: 14px;
  box-shadow: var(--shadow-float); padding: 12px 12px 11px; }
.globe-bubble[hidden] { display: none; }
.globe-bubble .jkr-wrap { width: 100%; }
.globe-bubble .gb-close { position: absolute; top: 6px; right: 6px; z-index: 3; min-width: 26px; min-height: 26px;
  border: 0; border-radius: 8px; background: color-mix(in srgb, var(--surface) 60%, transparent);
  color: var(--muted-1); font-size: 17px; line-height: 1; cursor: pointer; }
.globe-bubble .gb-close:hover { color: var(--ink); background: var(--surface-raised); }
.globe-bubble .gb-body { min-width: 0; }
.globe-bubble .gb-value { margin: 8px 2px 0; font: 500 12px/1.4 -apple-system, system-ui, sans-serif;
  color: var(--muted-1); }
.globe-bubble .gb-book { margin: 8px 2px 0; display: flex; flex-wrap: wrap; align-items: center; gap: 6px 12px; }
.globe-bubble .gb-book .ticket-booklink, .globe-bubble .gb-book .ticket-deeplink { margin-top: 0; }
.globe-bubble .gb-all { display: block; width: 100%; margin: 10px 0 0; padding: 8px 10px; text-align: center;
  border: 1px solid var(--border); border-radius: 9px; background: var(--surface-raised); color: var(--brass-deep);
  font: 600 12.5px/1.3 -apple-system, system-ui, sans-serif; cursor: pointer;
  transition: border-color .15s ease, color .15s ease; }
.globe-bubble .gb-all:hover { border-color: var(--brass); color: var(--ink); }
/* the pointer tail: a bordered diamond straddling the card edge (JS sets .left; margin-left centres it) */
.globe-bubble .gb-tail { position: absolute; width: 12px; height: 12px; margin-left: -6px; left: 50%;
  background: var(--surface); transform: rotate(45deg); }
.globe-bubble:not(.gb-below) .gb-tail { bottom: -6px; border-right: 1px solid var(--border);
  border-bottom: 1px solid var(--border); }
.globe-bubble.gb-below .gb-tail { top: -6px; border-left: 1px solid var(--border); border-top: 1px solid var(--border); }
@media (prefers-reduced-motion: reduce) { .globe-bubble .gb-all { transition: none; } }

/* v291 #5 — the points spine in the rail head */
.jk-pts { flex: 0 0 auto; margin-left: auto; min-height: 26px; padding: 5px 10px; border-radius: 999px;
  border: 1px solid var(--border); background: transparent; color: var(--muted-1);
  font: 600 10.5px/1 "DM Mono", ui-monospace, monospace; letter-spacing: .03em; cursor: pointer;
  white-space: nowrap; transition: border-color .15s, color .15s, background .15s; }
.jk-pts:hover { border-color: var(--brass); color: var(--ink); }
.jk-pts.is-cta { border-color: var(--brass); color: var(--brass-deep);
  background: color-mix(in srgb, var(--brass) 12%, transparent); }
.jk-pts[hidden] { display: none; }
/* (v291 first-run clarity strip retired — the owner-flagged contextual header (.jk-ctx) replaces the
   three stacked descriptor lines with ONE per-lens line.) */
.jk-back { align-self: flex-start; margin: 0 0 8px; background: none; border: 0; padding: 6px 0; cursor: pointer;
  font: 600 12px/1 "DM Mono", ui-monospace, monospace; color: var(--brass-deep); }
.jk-back:hover { text-decoration: underline; }
/* the four example prompts — Thread-lens only, retired once a conversation is live */
.jk-seeds { flex: 0 0 auto; display: flex; flex-wrap: wrap; gap: 7px; padding: 12px 14px 4px; }
#jkRail.has-chat .jk-seeds, #jkRail:not(.jk-s-thread) .jk-seeds { display: none; }
.jk-seed { display: inline-flex; align-items: center; gap: 7px; min-height: 40px; padding: 9px 13px;
  border: 1px solid var(--border); border-radius: 999px;
  background: color-mix(in srgb, var(--surface-raised) 88%, transparent); color: var(--ink);
  font: 600 12.5px/1.2 -apple-system, system-ui, sans-serif; cursor: pointer; text-align: left;
  transition: border-color .15s, background .15s; }
.jk-seed .g { color: var(--flare-deep); flex: 0 0 auto; }
.jk-seed:hover { border-color: var(--flare-deep); background: color-mix(in srgb, var(--flare-deep) 7%, var(--surface-raised)); }
/* ---- CONSOLE-DENSITY rows (grafted from p4-console's cx-list treatment; blueprint row anatomy:
   tier band left · route mono + program/cabin small · rt chip (+ signal-only trust chip) · price +
   taxes/seats + mini sparkline right). One renderer (jkRowHTML) feeds Board + Search results.
   v290 review #1: the rail is the primary reading surface, so rows read as TICKETS, not table rows —
   route 14px mono, price 15.5px mono, roomier padding at the clamp(480px, 42vw, 640px) rail width. */
.jkr-wrap { display: flex; flex-direction: row; align-items: stretch; border: 1px solid var(--border);
  border-radius: 10px; background: var(--surface); overflow: hidden; transition: border-color .15s; }
.jkr-wrap:hover { border-color: var(--muted-3); }
/* v291 #4 — the save loop, visible: a ☆ column on every row, writing the EXISTING watch store (F9) */
.jkr-save { flex: 0 0 38px; display: flex; align-items: center; justify-content: center;
  border: 0; border-left: 1px solid var(--border-soft); background: transparent; padding: 0;
  color: var(--muted-3); font-size: 16px; line-height: 1; cursor: pointer;
  transition: color .15s, background .15s; }
.jkr-save:hover { color: var(--brass-deep); background: color-mix(in srgb, var(--brass) 8%, transparent); }
.jkr-save.on { color: var(--brass-deep); }
.jkr-save:focus-visible { outline: 2px solid var(--brass-deep); outline-offset: -2px; }
.jkr-wrap.is-bookable { border-color: var(--book-tint-bd, var(--border)); background: var(--book-tint-bg, var(--surface)); }
/* A-2: personal affordability is a plain row-level verdict, never a trust chip. It can wrap under the
   route metadata without widening the fixed ticket grid or competing with routing/freshness evidence. */
.jk-row .jkr-afford { display: block; min-width: 0; margin-top: 3px; overflow-wrap: anywhere;
  font: 600 11.5px/1.4 -apple-system, system-ui, sans-serif; }
.jk-row .jkr-afford b { font-weight: 750; }
.jk-row .jkr-afford.is-yours { color: var(--book-deep); }
.jk-row .jkr-afford.is-short { color: var(--brass-deep); }
/* v290 review #2 — TIER IDENTITY MUST BE UNMISTAKABLE: a 6px tier band + a soft tier-tinted wash +
   the PRICE in the tier's own color. Tokens are the EXISTING tier hues (outlier purple --flare-deep ·
   gold --cat-gold-line, with --cat-gold-deep for text on light · sweet crimson --cat-sweet-line),
   each themed light+dark at its definition, so the washes theme for free. Tier identity outranks the
   green bookable wash — personal affordability lives at detail altitude, never as a row's identity. */
.jkr-wrap.is-outlier, .jkr-wrap.is-bookable.is-outlier { border-left: 6px solid var(--flare-deep);
  background: color-mix(in srgb, var(--flare-deep) 7%, var(--surface)); }
.jkr-wrap.is-outlier .jkr-cost b { color: var(--flare-deep); }
.jkr-wrap.is-gold, .jkr-wrap.is-bookable.is-gold { border-left: 6px solid var(--cat-gold-line, #d4a017);
  background: color-mix(in srgb, var(--cat-gold-line, #d4a017) 9%, var(--surface)); }
.jkr-wrap.is-gold .jkr-cost b { color: var(--cat-gold-deep, #8a6a12); }
.jkr-wrap.is-sweet, .jkr-wrap.is-bookable.is-sweet { border-left: 6px solid var(--cat-sweet-line, #c2455f);
  background: color-mix(in srgb, var(--cat-sweet-line, #c2455f) 7%, var(--surface)); }
.jkr-wrap.is-sweet .jkr-cost b { color: var(--cat-sweet-line, #c2455f); }
.jkr-wrap > .jk-row { display: flex; align-items: flex-start; gap: 12px; flex: 1 1 auto; min-width: 0;
  text-align: left; border: 0; border-radius: 0; background: transparent; cursor: pointer; padding: 12px 14px; }
.jk-row .jkr-main { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.jk-row .jkr-city { font: 600 15.5px/1.25 "Newsreader", Georgia, serif; color: var(--ink); }
.jk-row .jkr-route { font: 500 14px/1.3 "DM Mono", ui-monospace, monospace; letter-spacing: .04em;
  color: var(--muted-1); }
.jk-row .jkr-meta { font: 500 12px/1.35 -apple-system, system-ui, sans-serif; color: var(--muted-1); }
/* HONEST-DISPLAY CONTRACT — a carried gold row's provenance ("First flagged May 13 · still live …");
   never "found today". The standout `why` on a fresh gold row rides the same slot in gold ink. */
.jk-row .jkr-carry { font: 500 11px/1.35 "DM Mono", ui-monospace, monospace; letter-spacing: .02em; color: var(--muted-2); }
.jk-row .jkr-why { font: 600 11.5px/1.35 -apple-system, system-ui, sans-serif; color: var(--cat-gold-deep, #8a6a12); }
.jkr-reference { display: block; margin-top: 2px; font: 600 11px/1.35 -apple-system, system-ui, sans-serif; }
.jk-row .jkr-chips { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 4px; }
/* the row's (max two) chips reuse the trust-strip chip family at row density */
.jk-row .jkr-chips .tc { display: inline-flex; align-items: center; gap: 3px; max-width: 100%;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-family: "DM Mono", ui-monospace, monospace; font-size: 10.5px; letter-spacing: .02em;
  line-height: 1.3; color: var(--muted-1); background: var(--surface-raised);
  border: 1px solid var(--border-soft); border-radius: var(--r-pill); padding: 3px 9px; }
.jk-row .jkr-chips .tc--ok { color: var(--trust-ok-deep); background: var(--trust-ok-bg); border-color: var(--trust-ok-bd); }
.jk-row .jkr-chips .tc--warn { color: var(--trust-warn-deep); background: var(--trust-warn-bg); border-color: var(--trust-warn-bd); }
/* the open-jaw disclosure rides beside the rt chip at row density too (same .rt-jaw voice as the
   ticket card) — visible on touch, never a hover-title-only disclosure */
.jk-row .jkr-chips .rt-jaw { align-self: center; }
.jk-row .jkr-right { flex: 0 0 auto; display: flex; flex-direction: column; align-items: flex-end; gap: 3px;
  max-width: 46%; }
.jk-row .jkr-cost { display: flex; align-items: baseline; gap: 5px; }
.jk-row .jkr-cost b { font: 600 15.5px/1.2 "DM Mono", ui-monospace, monospace;
  font-variant-numeric: tabular-nums; color: var(--ink); white-space: nowrap; }
.jk-row .jkr-cost i { font: 500 11.5px/1.2 "DM Mono", ui-monospace, monospace; font-style: normal;
  color: var(--muted-2); white-space: nowrap; }
.jk-row .jkr-sub { font: 500 11.5px/1.3 -apple-system, system-ui, sans-serif; color: var(--muted-1);
  text-align: right; }
.jk-row .ticket-spark { margin: 1px 0 0; }
.jk-row .jkr-main > *, .jk-row .jkr-right > * { min-width: 0; }
/* Board group headers (v290 #2) — colored tier dot + name + honest count, with the plain-English
   tier definition (the landing's al-tierdef voice) on its own line beneath. */
.jk-group { display: block; margin: 14px 2px 3px; }
.jk-group:first-of-type { margin-top: 4px; }
.jk-group .jk-gh { display: flex; align-items: baseline; gap: 8px; }
.jk-group b { font: 600 14px/1.2 -apple-system, system-ui, sans-serif; color: var(--ink); }
.jk-group .jk-gh > b::before { content: ""; display: inline-block; width: 10px; height: 10px;
  border-radius: 50%; margin-right: 8px; background: var(--muted-3); vertical-align: -1px; }
.jk-group.g-outliers .jk-gh > b::before { background: var(--flare-deep); }
.jk-group.g-gold .jk-gh > b::before { background: var(--cat-gold-line, #d4a017); }
.jk-group.g-sweet .jk-gh > b::before { background: var(--cat-sweet-line, #c2455f); }
/* 'Also tracked' — the destinations we watch daily that carry NO tier today. Deliberately the
   quietest dot on the board (muted, not a category colour): the group makes no claim about the
   fare, it only says the route is tracked and this is today's cheapest. */
.jk-group.g-all .jk-gh > b::before { background: var(--muted-2, #8a8578); }
.jk-group span { font: 500 11px/1.4 "DM Mono", ui-monospace, monospace; letter-spacing: .03em;
  color: var(--muted-2); }
.jk-group .jk-gdef { margin: 3px 0 0 18px; font: 500 11.5px/1.45 -apple-system, system-ui, sans-serif;
  color: var(--muted-1); max-width: 58ch; }
.jk-group .jk-gdef b { font-weight: 600; color: var(--ink); }
/* the per-tier "see all N →" expander (v290 #3) — the digest expands in place, and collapses back */
.jk-more { align-self: flex-start; margin: 1px 0 5px; min-height: 32px; padding: 7px 13px;
  border: 1px solid var(--border); border-radius: 999px; background: transparent;
  color: var(--brass-deep); font: 600 11.5px/1 "DM Mono", ui-monospace, monospace; cursor: pointer;
  transition: border-color .15s; }
.jk-more:hover { border-color: var(--brass); }
/* A-1: member-specific affordability sits between the Board controls and its first tier. This is a
   full-width status band, not another card: it summarizes the exact representative fares rendered below. */
.jk-afford { display: flex; align-items: flex-start; gap: 9px; min-width: 0; margin: 2px -12px 1px;
  padding: 10px 14px; border-top: 1px solid var(--book-tint-bd, var(--border-soft));
  border-bottom: 1px solid var(--book-tint-bd, var(--border-soft));
  background: color-mix(in srgb, var(--trust-ok-deep) 7%, transparent);
  color: var(--trust-ok-deep); font: 500 12.5px/1.45 -apple-system, system-ui, sans-serif; }
.jk-afford > span:last-child { min-width: 0; overflow-wrap: anywhere; }
.jk-afford b { font-weight: 700; color: inherit; }
.jk-afford-mark { flex: 0 0 auto; font-size: 15px; line-height: 1.25; }
.jk-afford.is-empty { background: color-mix(in srgb, var(--brass) 7%, transparent);
  border-color: var(--border-soft); color: var(--muted-1); }
.jk-afford.is-empty .jk-afford-mark { color: var(--brass-deep); }
.jk-afford button { border: 0; background: transparent; padding: 0; color: var(--brass-deep);
  font: 650 12.5px/1.45 -apple-system, system-ui, sans-serif; cursor: pointer; text-decoration: underline;
  text-underline-offset: 2px; }
.jk-afford button:hover { color: var(--ink); }
.jk-afford button:focus-visible { outline: 2px solid var(--brass-deep); outline-offset: 2px; }
/* Board filter row (Class / Trip length / Award-Cash / Watching) */
.jk-bchips { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin: 0 0 2px; }
.jk-bsel { display: inline-flex; align-items: center; gap: 5px; font: 600 10px/1 "DM Mono", ui-monospace, monospace;
  letter-spacing: .06em; text-transform: uppercase; color: var(--muted-2); }
.jk-bsel select { min-height: 30px; border: 1px solid var(--border); border-radius: 999px; background: transparent;
  color: var(--ink); font: 600 11.5px/1 -apple-system, system-ui, sans-serif; padding: 4px 8px; cursor: pointer;
  text-transform: none; letter-spacing: 0; }
.jk-bsel select:focus-visible { outline: 2px solid var(--brass-deep); outline-offset: 2px; }
.jk-bseg { display: inline-flex; gap: 0; border: 1px solid var(--border); border-radius: 999px; overflow: hidden; }
.jk-bseg button { min-height: 30px; padding: 5px 11px; border: 0; background: transparent; color: var(--muted-1);
  font: 600 11.5px/1 -apple-system, system-ui, sans-serif; cursor: pointer; }
.jk-bseg button[aria-pressed="true"] { background: var(--ink); color: var(--bg); }
.jk-bseg button:focus-visible { outline: 2px solid var(--brass-deep); outline-offset: -2px; }
/* EXPLORE catalog — the exhaustive list under the trip search form */
.jk-cat { margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--border-soft); }
.jk-cat-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.jk-cat-head b { font: 600 14px/1.2 -apple-system, system-ui, sans-serif; color: var(--ink); }
.jk-cat-head input { flex: 1 1 140px; min-width: 0; min-height: 34px; border: 1px solid var(--border);
  border-radius: 999px; padding: 6px 12px; background: var(--surface); color: var(--ink); font-size: 13px; }
.jk-cat-head input::placeholder { font-family: "Newsreader", Georgia, serif; font-style: italic; color: var(--muted-2); }
.jk-cat-head input:focus-visible { outline: none; border-color: var(--brass); }
.jk-cat-cov { margin: 7px 2px 10px; font: 500 11px/1.5 "DM Mono", ui-monospace, monospace; letter-spacing: .03em; color: var(--muted-2); }
.jk-catalog { display: flex; flex-direction: column; gap: 7px; }
.jk-chip { flex: 0 0 auto; min-height: 30px; padding: 5px 11px; border-radius: 999px;
  border: 1px solid var(--border); background: transparent; color: var(--muted-1);
  font: 600 11.5px/1 -apple-system, system-ui, sans-serif; cursor: pointer;
  transition: border-color .15s, background .15s, color .15s; }
.jk-chip[aria-pressed="true"] { background: var(--ink); border-color: var(--ink); color: var(--bg); }
.jk-chip:hover { border-color: var(--muted-3); }
/* (BEST-EVER ledger CSS removed — v290 #4: the lens is gone; leaderboard.html keeps its own page.) */
/* SEARCH lens form */
.jk-sf { display: flex; flex-direction: column; gap: 9px; }
.jk-sf-row { display: flex; align-items: center; gap: 8px; }
.jk-sf-row > label { flex: 0 0 52px; font: 500 10px/1.2 "DM Mono", ui-monospace, monospace;
  letter-spacing: .08em; text-transform: uppercase; color: var(--muted-2); }
/* the From ORIGIN select (v290 5b) — the same origin state the topbar switcher holds */
.jk-sf-from { flex: 1 1 auto; min-width: 0; min-height: 36px; border: 1px solid var(--border);
  border-radius: 8px; padding: 6px 8px; background: var(--surface); color: var(--ink);
  font: 500 13px/1.3 -apple-system, system-ui, sans-serif; }
.jk-sf-from:focus-visible { outline: none; border-color: var(--brass); }
.jk-origin-note { margin: -2px 0 2px 60px; color: var(--muted-2); font-size: 10.5px; line-height: 1.35; }
/* the HONEST computed return window under the trip-shape chips (v290 5a) */
.jk-sf-ret { margin: -4px 0 0 60px; font: 500 11px/1.5 "DM Mono", ui-monospace, monospace;
  letter-spacing: .03em; color: var(--muted-2); }
.jk-sf-ret[hidden] { display: none; }
.jk-sf-towrap { position: relative; flex: 1 1 auto; min-width: 0; }
.jk-sf-towrap input { width: 100%; box-sizing: border-box; min-height: 36px; border: 1px solid var(--border);
  border-radius: 8px; padding: 6px 10px; background: var(--surface); color: var(--ink); font-size: 13px; }
.jk-sf-towrap input::placeholder { font-family: "Newsreader", Georgia, serif; font-style: italic; color: var(--muted-2); }
.jk-sf-towrap input:focus-visible { outline: none; border-color: var(--brass); }
.jk-sf-menu { position: absolute; top: calc(100% + 2px); left: 0; right: 0; z-index: 60;
  max-height: 240px; overflow-y: auto; background: var(--surface-raised);
  border: 1px solid var(--border); border-radius: 10px; box-shadow: var(--shadow-float); }
.jk-sf-menu[hidden] { display: none; }
.jk-sf-row input[type="date"] { min-height: 36px; border: 1px solid var(--border); border-radius: 8px;
  padding: 5px 8px; background: var(--surface); color: var(--ink); font: 500 12.5px/1.2 "DM Mono", ui-monospace, monospace; }
.jk-sf-flex { display: inline-flex; align-items: center; gap: 2px; margin-left: auto; }
.jk-sf-flex b { font: 600 11px/1.2 "DM Mono", ui-monospace, monospace; color: var(--muted-1);
  min-width: 58px; text-align: center; }
.jk-sf-flex button { min-width: 28px; min-height: 28px; border: 1px solid var(--border); border-radius: 6px;
  background: var(--surface); color: var(--ink); font-size: 14px; line-height: 1; cursor: pointer; }
.jk-sf-flex button:hover { border-color: var(--muted-3); }
.jk-sf-seg { display: inline-flex; flex-wrap: wrap; gap: 4px; }
.jk-sf-seg button { min-height: 30px; padding: 5px 10px; border: 1px solid var(--border); border-radius: 999px;
  background: transparent; color: var(--muted-1); font: 600 11px/1 -apple-system, system-ui, sans-serif;
  cursor: pointer; transition: border-color .15s, background .15s, color .15s; }
.jk-sf-seg button[aria-pressed="true"] { background: var(--ink); border-color: var(--ink); color: var(--bg); }
/* v291 #3 — EXACT-DATE mode: a set return date owns the trip shape; the chips dim until cleared */
.jk-sf-seg.is-exact button { opacity: .45; }
.jk-sf-clear { min-width: 28px; min-height: 28px; border: 1px solid var(--border); border-radius: 6px;
  background: var(--surface); color: var(--muted-1); font-size: 13px; line-height: 1; cursor: pointer; }
.jk-sf-clear:hover { border-color: var(--muted-3); color: var(--ink); }
.jk-sf-clear[hidden] { display: none; }
.jk-sf-go { min-height: 38px; border: 0; border-radius: 999px; background: var(--brass); color: var(--ink);
  font: 600 13px/1 -apple-system, system-ui, sans-serif; cursor: pointer; }
[data-theme="dark"] .jk-sf-go { color: var(--bg); }
.jk-sf-go:hover { filter: brightness(1.05); }
.jk-sf-results { display: flex; flex-direction: column; gap: 7px; }
.jk-sf-results .jk-shead { margin: 6px 2px 0; font: 600 12px/1.3 -apple-system, system-ui, sans-serif; color: var(--ink); }
.jk-sf-results .jk-srelax { margin: 0 2px; font: 500 11px/1.5 -apple-system, system-ui, sans-serif; color: var(--muted-1); }
/* the MONTH GRID flex picker — greener = cheaper, from REAL heatmap prices only */
.jk-hm { border: 1px solid var(--border); border-radius: 10px; padding: 9px 10px 7px; background: var(--surface); }
.jk-hm[hidden] { display: none; }
.jk-hm-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 6px; }
.jk-hm-head b { font: 600 12px/1.2 -apple-system, system-ui, sans-serif; color: var(--ink); }
.jk-hm-head button { min-width: 28px; min-height: 28px; border: 1px solid var(--border); border-radius: 6px;
  background: var(--surface); color: var(--ink); font-size: 14px; line-height: 1; cursor: pointer; }
.jk-hm-head button:disabled { opacity: .35; cursor: default; }
.jk-hm-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 3px; }
.jk-hm-day { position: relative; min-height: 30px; border: 1px solid var(--border-soft); border-radius: 6px;
  background: color-mix(in srgb, var(--trust-ok-bg) calc(100% - var(--t, 0) * 100%), var(--trust-warn-bg) calc(var(--t, 0) * 100%));
  color: var(--ink); font: 500 10px/1.1 "DM Mono", ui-monospace, monospace; cursor: pointer;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 1px; padding: 2px 0; }
.jk-hm-day small { font-size: 8px; color: var(--muted-1); }
.jk-hm-day.is-empty { background: transparent; border-color: transparent; color: var(--muted-3); cursor: default; }
.jk-hm-day.is-picked { outline: 2px solid var(--brass-deep); outline-offset: -1px; }
.jk-hm-cap, .jk-hm-none { margin: 6px 2px 0; font: 500 10px/1.5 "DM Mono", ui-monospace, monospace;
  letter-spacing: .03em; color: var(--muted-2); }
.jk-hm-none[hidden] { display: none; }
/* the composer's GHOST typeahead — rises above the one composer in every lens */
.jk-ghost { position: absolute; bottom: calc(100% + 4px); left: 8px; right: 8px; z-index: 70;
  max-height: 300px; overflow-y: auto; background: var(--surface-raised);
  border: 1px solid var(--border); border-radius: 10px; box-shadow: var(--shadow-float); }
.jk-ghost[hidden] { display: none; }
.jk-ghost-opt, .jk-sf-menu .jk-ghost-opt { display: flex; align-items: baseline; gap: 8px; width: 100%;
  text-align: left; padding: 9px 12px; background: none; border: 0; border-bottom: 1px solid var(--border-soft);
  cursor: pointer; font: 500 13px/1.3 -apple-system, system-ui, sans-serif; color: var(--ink); }
.jk-ghost-opt:last-child { border-bottom: 0; }
.jk-ghost-opt:hover, .jk-ghost-opt.is-active { background: color-mix(in srgb, var(--brass) 10%, transparent); }
.jk-ghost-opt small { color: var(--muted-2); font-size: 11px; font-family: "DM Mono", ui-monospace, monospace;
  margin-left: auto; white-space: nowrap; }
.jk-ghost-opt .g { color: var(--flare-deep); flex: 0 0 auto; }
.jk-empty { padding: 22px 8px; text-align: center; color: var(--muted-1); font-size: 13.5px; line-height: 1.6; }
.jk-tab:focus-visible, .jk-seed:focus-visible, .jk-back:focus-visible, .jk-chip:focus-visible,
.jk-ghost-opt:focus-visible, .jk-sf-seg button:focus-visible, .jk-sf-go:focus-visible,
.jk-hm-day:focus-visible, .jk-more:focus-visible, .jk-pts:focus-visible,
.jk-sf-clear:focus-visible {
  outline: 2px solid var(--brass-deep); outline-offset: 2px; }
@media (prefers-reduced-motion: reduce) { .jk-tab, .jk-seed, .jk-chip, .jkr-wrap, .jk-sf-seg button { transition: none; } }
/* MOBILE: the rail goes full-screen beneath the proof-band — a plain opaque sheet (no glass: nothing
   sits behind it, and backdrop-filter costs composite time on scroll). 44px touch floor. */
@media (max-width: 760px) {
  /* `inset: auto` is LOAD-BEARING. The desktop rule docks the rail with position:absolute
     + top/right/bottom:10px. Switching to position:relative here without clearing those
     offsets does NOT undo them: on a relatively-positioned box `right:10px` shifts it 10px
     LEFT of normal flow (measured on origin/main at 390x844: #jkRail x = -10, i.e. the whole
     fare list hanging off the left edge of the phone) and `top:10px` pushes it 10px further
     down an already over-full first paint. Reset the inset; keep the flow layout. */
  body.jk-stage .jk-rail { position: relative; inset: auto; flex: 1 1 auto; min-height: 0; width: 100%;
    border: 0; border-radius: 0; box-shadow: none;
    background: var(--bg); backdrop-filter: none; -webkit-backdrop-filter: none; }
  /* the popup peek fills the phone rail; the card can use the full width */
  .jk-peek { padding: 12px; }
  .jk-peek-card { max-width: none; }
  .jk-peek-arrow { min-width: 44px; min-height: 44px; }
  .jk-tab { min-height: 44px; }
  .jk-seed { min-height: 44px; }
  .jk-chip, .jk-sf-seg button, .jk-sf-flex button, .jk-hm-head button, .jk-more, .jk-sf-clear,
  .jk-pts { min-height: 44px; }
  .jk-afford button { min-height: 44px; padding: 5px 1px; }
  .jkr-save { flex-basis: 44px; }
  .jk-hm-day { min-height: 40px; }
  .jk-sf-towrap input, .jk-sf-from, .jk-sf-row input[type="date"] { min-height: 44px; font-size: 16px; }   /* no iOS focus-zoom */
}
