/*
 * design-v2/dashboard.css – 3-panel grid, loyalty rows, photo header,
 * hero-fig, activity feed, section heads + small button set used on the
 * Pure Stone Dashboard. All classes prefixed `v2-` to avoid collisions.
 * Source of truth: 07-atlas-brief-pure-stone.html.
 */

/* ─── 3-PANEL GRID ─────────────────────────────────────────── */
.v2-panels {
  display: grid;
  grid-template-columns: 1fr 1.08fr 1fr;
  gap: 18px;
}
.v2-panel {
  border-radius: 18px;
  padding: 22px 22px 20px;
  min-height: 380px;
  display: flex;
  flex-direction: column;
  box-shadow: var(--sh-card);
  transition: all 220ms var(--ease-out);
  position: relative;
  overflow: hidden;
  border: 1px solid var(--hairline);
}
.v2-panel::before {
  content: "";
  position: absolute;
  top: 0;
  left: 16px;
  right: 16px;
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.6), transparent);
  z-index: 2;
}
.v2-panel:hover {
  box-shadow: var(--sh-card-hover);
  transform: translateY(-2px);
}
.v2-panel--dark {
  background: linear-gradient(180deg, var(--navy-soft) 0%, var(--navy) 100%);
  color: var(--paper-soft);
  border-color: var(--navy);
  box-shadow: var(--sh-inverse);
}
.v2-panel--dark::before {
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.12), transparent);
}
.v2-panel--cream {
  background: var(--paper-soft);
  padding-top: 0;
}
.v2-panel--cream::before {
  /* head sits flush at the top — let it own the panel's top edge */
  display: none;
}
.v2-panel--cream .v2-panel__head {
  background: var(--paper);
  color: var(--ink-strong);
  margin: 0 -22px 0;
  padding: 14px 22px 12px;
  border-top-left-radius: 18px;
  border-top-right-radius: 18px;
  position: relative;
  z-index: 1;
}
.v2-panel--cream .v2-panel__head::before {
  content: "";
  position: absolute;
  top: 0;
  left: 16px;
  right: 16px;
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.7), transparent);
}
.v2-panel--photo {
  background: var(--paper-soft);
  padding-top: 0;
}
.v2-panel--photo::before {
  /* head fills the top edge with its own dark background – suppress the white hairline */
  display: none;
}
.v2-panel--photo .v2-panel__head {
  /* Solid navy – must match the .v2-photo background AND the empty-state
     SVG rect fill (#0E1F3B) so the head + hero read as one uniform band. */
  background: var(--navy);
  color: var(--paper-cream);
  margin: 0 -22px;
  padding: 14px 22px 12px;
  border-top-left-radius: 18px;
  border-top-right-radius: 18px;
  position: relative;
  z-index: 1;
}
.v2-panel--photo .v2-panel__head::before {
  content: "";
  position: absolute;
  top: 0;
  left: 16px;
  right: 16px;
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.16), transparent);
}
.v2-panel--photo .v2-panel__head .v2-panel__title {
  color: var(--paper-cream);
}
.v2-panel--photo .v2-panel__head .v2-panel__arrow {
  color: var(--paper-cream);
  opacity: 0.75;
}
.v2-panel--photo .v2-panel__head .v2-panel__arrow:hover {
  background: rgba(255, 255, 255, 0.10);
  opacity: 1;
}
.v2-panel__head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 16px;
  gap: 8px;
}
.v2-panel__head-actions {
  display: flex;
  align-items: center;
  gap: 8px;
}

/* ─── PANEL MODE TOGGLE (Status / Rewards on Loyalty progress) ─ */
.v2-mode-toggle {
  display: inline-flex;
  padding: 2px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.08);
  border: 1px solid rgba(255, 255, 255, 0.10);
}
.v2-panel--cream .v2-mode-toggle,
.v2-panel--photo .v2-mode-toggle {
  background: var(--paper-shade);
  border-color: var(--hairline);
}
.v2-mode-toggle__opt {
  font-family: 'Geist', sans-serif;
  font-weight: 500;
  font-size: 0.76667rem;
  letter-spacing: 0.01em;
  color: rgba(255, 255, 255, 0.65);
  background: transparent;
  border: 0;
  padding: 4px 10px;
  border-radius: 999px;
  cursor: pointer;
  transition: all 160ms var(--ease-out);
  white-space: nowrap;
}
.v2-mode-toggle__opt:hover {
  color: var(--color-text-inverse);
}
.v2-mode-toggle__opt.is-active {
  background: var(--orange);
  color: var(--color-text-inverse);
  font-weight: 600;
  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.18) inset, 0 1px 3px rgba(255, 104, 16, 0.32);
}
.v2-panel--cream .v2-mode-toggle__opt,
.v2-panel--photo .v2-mode-toggle__opt { color: var(--ink-muted); }
.v2-panel--cream .v2-mode-toggle__opt:hover,
.v2-panel--photo .v2-mode-toggle__opt:hover { color: var(--ink-strong); }

/* ─── REWARDS MODE: collapse tier bar, emphasise balance ─────── */
.v2-panel.is-reward-mode .v2-lr__bar { display: none; }
.v2-panel.is-reward-mode .v2-lr__body > .v2-lr__m { display: none; }
.v2-panel.is-reward-mode .v2-lr__head .v2-lr__m { opacity: 0.42; }
.v2-panel.is-reward-mode .v2-lr {
  align-items: center;
  padding: 14px 0;
}
.v2-panel.is-reward-mode .v2-lr__r {
  font-size: 1.13333rem;
  letter-spacing: -0.012em;
}
.v2-panel.is-reward-mode .v2-lr__r small {
  font-size: 0.66667rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  margin-top: 2px;
}
.v2-panel.is-reward-mode .v2-lr__u {
  font-size: 0.73333rem;
  margin-left: 4px;
  font-weight: 500;
  opacity: 0.75;
}

/* ─── STATUS MODE (default): hide reward balance, promote tier label
   to the right edge of the row. The .v2-lr__head uses justify-content:
   space-between, so when .v2-lr__r is removed from the grid the body
   column expands and the tier chip naturally sits at the panel edge —
   exactly where the balance used to live. Scope to the loyalty panel
   only; the Flights/Stays panels reuse .v2-lr but must keep their
   right column. */
.v2-panel[data-mm-loyalty-panel]:not(.is-reward-mode) .v2-lr__r {
  display: none;
}
.v2-panel[data-mm-loyalty-panel]:not(.is-reward-mode) .v2-lr__head .v2-lr__m {
  font-size: 0.86667rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  opacity: 0.92;
}
.v2-panel__title {
  font-family: 'Geist', sans-serif;
  font-weight: 600;
  font-size: 1.06667rem;
  letter-spacing: -0.005em;
}
.v2-panel__arrow {
  width: 26px;
  height: 26px;
  display: grid;
  place-items: center;
  border-radius: 7px;
  color: inherit;
  opacity: 0.55;
  text-decoration: none;
  transition: all 160ms var(--ease-out);
  cursor: pointer;
}
.v2-panel__arrow:hover {
  opacity: 1;
  transform: translate(1px, -1px);
}
.v2-panel--dark .v2-panel__arrow:hover {
  background: rgba(255, 255, 255, 0.08);
}
.v2-panel--cream .v2-panel__arrow:hover,
.v2-panel--photo .v2-panel__arrow:hover {
  background: var(--paper-shade);
}
.v2-panel__arrow svg {
  width: 13px;
  height: 13px;
  stroke-width: 2;
}

.v2-lede {
  font-family: 'Bricolage Grotesque', serif;
  font-weight: 400;
  font-size: 1.46667rem;
  line-height: 1.2;
  letter-spacing: -0.015em;
  margin-bottom: 16px;
}
.v2-lede b {
  font-weight: 600;
}
.v2-panel--dark .v2-lede .amber { color: var(--pace-amber-dark); font-weight: 500; }
.v2-panel--dark .v2-lede .ruby  { color: var(--pace-ruby-dark); font-weight: 500; }
.v2-panel--cream .v2-lede .amber,
.v2-panel--photo .v2-lede .amber { color: var(--pace-amber); font-weight: 500; }
.v2-panel--cream .v2-lede .ruby,
.v2-panel--photo .v2-lede .ruby  { color: var(--pace-ruby); font-weight: 500; }

/* ─── LOYALTY ROW (logo + bar + balance) ───────────────────── */
.v2-lr {
  display: grid;
  grid-template-columns: 28px 1fr auto;
  gap: 12px;
  padding: 12px 0;
  border-top: 1px solid var(--hairline-soft);
  align-items: center;
}
.v2-lr:first-of-type {
  border-top: 1px solid var(--hairline);
  margin-top: 4px;
}
.v2-panel--dark .v2-lr {
  border-top-color: rgba(255, 255, 255, 0.10);
}
.v2-panel--dark .v2-lr:first-of-type {
  border-top-color: rgba(255, 255, 255, 0.18);
}
.v2-lr--empty {
  grid-template-columns: 1fr;
  font-family: 'Bricolage Grotesque', serif;
  font-style: normal;
  font-size: 0.93333rem;
  color: var(--ink-muted);
}
/* The [hidden] attribute defaults to display:none, but .v2-lr { display: grid }
   wins on specificity — spare rows would render visibly without this override.
   Pair with .v2-lr--spare so we control hiding from either CSS or markup. */
.v2-lr[hidden],
.v2-lr--spare {
  display: none !important;
}
.v2-lr--empty a {
  color: inherit;
  text-decoration: underline;
}

.v2-lr__lg {
  width: 28px;
  height: 28px;
  border-radius: 7px;
  display: grid;
  place-items: center;
  font-family: 'Geist', sans-serif;
  font-weight: 700;
  font-size: 0.63333rem;
  letter-spacing: 0.04em;
  color: white;
  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.18) inset, 0 1px 2px rgba(0, 0, 0, 0.12);
  flex-shrink: 0;
  background: linear-gradient(135deg, var(--navy-soft) 0%, var(--navy) 100%);
}
/* Programme brand gradients. These are real third-party brand colors (British
   Airways navy, Air France, Lufthansa yellow, Marriott Bonvoy, etc.) and are
   not part of the Miles Mosaic palette. Documenting them inline rather than
   tokenising under our namespace is the honest choice; if a brand updates
   their palette, the gradient terminus changes here, not in our tokens. */
.v2-lr__lg.ba { background: linear-gradient(135deg, #2d6cb0 0%, #002f6c 100%); }
.v2-lr__lg.af { background: linear-gradient(135deg, #0e4d8e 0%, #001436 100%); }
.v2-lr__lg.lh { background: linear-gradient(135deg, #FFD200 0%, #FFA500 100%); color: #050505; }
.v2-lr__lg.mb { background: linear-gradient(135deg, #D6A24E 0%, #6B4715 100%); }
.v2-lr__lg.ih { background: linear-gradient(135deg, #2C2A29 0%, var(--mm-fg-strong) 100%); }
.v2-lr__lg.hh { background: linear-gradient(135deg, #1259a2 0%, #002a5c 100%); }
.v2-lr__lg.aa { background: linear-gradient(135deg, #C5C5C5 0%, #555 100%); color: var(--navy); }
.v2-lr__lg.ua { background: linear-gradient(135deg, #1259d6 0%, #050C1C 100%); }
.v2-lr__lg.hy { background: linear-gradient(135deg, #2C2A29 0%, #1A1A1A 100%); }
.v2-lr__lg.has-img {
  background: var(--mm-bg-surface);
  padding: 2px;
}
.v2-panel--dark .v2-lr__lg.has-img {
  background: rgba(255, 255, 255, 0.92);
}
.v2-lr__lg img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  border-radius: 5px;
  display: block;
}

/* Fallback SVG icon variant — used when no brand-coded logo class matches.
   Keeps the brand-tile gradient + sizing but swaps the two-letter monogram
   for a premium outline glyph (e.g. hotel building, takeoff). */
.v2-lr__lg--icon {
  color: rgba(255, 255, 255, 0.92);
}
.v2-lr__lg-svg {
  width: 16px;
  height: 16px;
  display: block;
  stroke-width: 1.6;
}

.v2-lr__body {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}
.v2-lr__head {
  display: flex;
  align-items: baseline;
  gap: 6px;
  justify-content: space-between;
}
.v2-lr__n {
  font-family: 'Geist', sans-serif;
  font-size: 0.9rem;
  font-weight: 500;
}
.v2-lr__m {
  font-family: 'Geist Mono', monospace;
  font-size: 0.7rem;
  letter-spacing: 0.08em;
  opacity: 0.6;
}
.v2-lr__bar {
  height: 4px;
  background: rgba(0, 0, 0, 0.10);
  border-radius: 999px;
  overflow: hidden;
}
.v2-panel--dark .v2-lr__bar { background: rgba(255, 255, 255, 0.10); }
.v2-lr__bar-fill {
  height: 100%;
  border-radius: 999px;
  transition: width 320ms var(--ease-out);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.32);
}
.v2-lr__bar-fill.ok  { background: linear-gradient(90deg, var(--pace-on-track) 0%, var(--pace-on-track-light) 100%); }
.v2-lr__bar-fill.at  { background: linear-gradient(90deg, var(--pace-amber) 0%, var(--pace-amber-light) 100%); }
.v2-lr__bar-fill.be  { background: linear-gradient(90deg, var(--pace-ruby) 0%, var(--pace-ruby-light) 100%); }
.v2-lr__bar-fill.ach { background: linear-gradient(90deg, var(--orange-deep) 0%, var(--orange) 100%); }

.v2-lr__r {
  font-family: 'Geist Mono', monospace;
  font-size: 0.86667rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  text-align: right;
  white-space: nowrap;
}
.v2-lr__r small {
  display: block;
  font-size: 0.66667rem;
  font-weight: 400;
  opacity: 0.55;
  margin-top: 1px;
}
.v2-lr__u {
  font-size: 0.66667rem;
  font-weight: 400;
  opacity: 0.55;
  margin-left: 4px;
}
.v2-lr__r.expiring { color: var(--orange); }
.v2-panel--dark .v2-lr__r.expiring { color: var(--orange-soft); }
.v2-lr__r.expired { color: var(--pace-risk); } /* UX-audit F-027 */
.v2-panel--dark .v2-lr__r.expired { color: var(--pace-risk-dark); }
.v2-lr__r.gain { color: var(--pace-on-track); }
.v2-panel--dark .v2-lr__r.gain { color: var(--pace-on-track-gain); }

/* Logo opt-out: hide brand logo + collapse the grid column to a single line.
   Useful for A/B testing whether the row reads cleaner without brand tiles. */
[data-design-v2="no-logos"] .v2-lr {
  grid-template-columns: 1fr auto;
}
[data-design-v2="no-logos"] .v2-lr__lg {
  display: none;
}

/* P2-D additions (2026-05-14 audit): expired-tier CTAs + adjust affordance.
   When .v2-lr--expired is set, the tier-pct chip is suppressed and the
   "EXPIRED" suffix renders in --pace-ruby. CTAs render below the meta line.
   The adjust link opens the corrector modal for the programme. */
.v2-lr__m--expired { color: var(--pace-ruby); opacity: 1; }
.v2-panel--dark .v2-lr__m--expired { color: var(--pace-ruby-dark); }
.v2-lr__ctas {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 2px;
}
.v2-lr__cta {
  font-family: 'Geist', sans-serif;
  font-size: 0.76667rem;
  font-weight: 500;
  color: var(--orange-deep);
  text-decoration: underline;
  text-underline-offset: 2px;
  text-decoration-thickness: 1px;
  transition: color 160ms var(--ease-out);
}
.v2-lr__cta:hover { color: var(--orange); }
.v2-panel--dark .v2-lr__cta { color: var(--orange-soft); }
.v2-panel--dark .v2-lr__cta:hover { color: var(--paper); }

/* ── Renewal outlook line (StatusForecastService) ────────────────────
   One additive line under the tier bar: renewal standing on the left,
   a prediction pill (reuses .v2-pace) on the right. Hidden in reward mode
   alongside the bar/meta so the rewards view stays calm. */
/* PI-04: requalification verdict promoted above the tier bar in each loyalty
   row. Reuses the shared .v2-pace pill for the badge colour. */
.v2-lr__verdict {
  margin: 2px 0 5px;
}
.v2-lr__verdict-row {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}
.v2-lr__verdict-days {
  font-family: 'Geist Mono', monospace;
  font-size: 0.66667rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--ink-muted);
  white-space: nowrap;
}
.v2-panel--dark .v2-lr__verdict-days { color: var(--paper-cream); }
.v2-lr__verdict-line {
  margin-top: 3px;
  font-size: 0.76667rem;
  line-height: 1.4;
  color: var(--ink-muted);
  display: -webkit-box;
  -webkit-line-clamp: 1;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.v2-panel--dark .v2-lr__verdict-line { color: var(--paper-cream); }
.v2-lr__fc {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-top: 1px;
}
.v2-lr__fc-renew {
  font-family: 'Geist Mono', monospace;
  font-size: 0.66667rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  opacity: 0.6;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* MM-07: the base .v2-lr__fc-renew carries opacity:0.6; compounding it with a
   0.62 colour alpha dropped contrast to ~2.7:1 on navy. Use a solid colour and
   reset the inherited opacity (9.6:1 vs navy-soft, 13.8:1 vs navy). */
.v2-panel--dark .v2-lr__fc-renew { color: #F3EAD8; opacity: 1; }
.v2-lr__pred {
  flex-shrink: 0;
  padding: 2px 7px;
  font-size: 0.6rem;
  letter-spacing: 0.1em;
  gap: 3px;
}
.v2-pred__caret { width: 9px; height: 9px; display: block; }
.v2-panel.is-reward-mode .v2-lr__fc { display: none; }

/* Forecast projection strip — earned-to-date + planned lift from upcoming
   trips, toward the qualification target (Delta-style "pending & upcoming").
   Mirrors .v2-lr__bar; only rendered when there is a planned contribution. */
.v2-lr__fcbar {
  display: flex;
  height: 4px;
  border-radius: 3px;
  overflow: hidden;
  background: var(--paper-shade);
  margin-top: 7px;
}
.v2-panel--dark .v2-lr__fcbar { background: rgba(255, 255, 255, 0.10); }
.v2-lr__fcbar-earned { height: 100%; }
.v2-lr__fcbar-earned.ok  { background: linear-gradient(90deg, var(--pace-on-track) 0%, var(--pace-on-track-light) 100%); }
.v2-lr__fcbar-earned.at  { background: linear-gradient(90deg, var(--pace-amber) 0%, var(--pace-amber-light) 100%); }
.v2-lr__fcbar-earned.be  { background: linear-gradient(90deg, var(--pace-ruby) 0%, var(--pace-ruby-light) 100%); }
.v2-lr__fcbar-earned.ach { background: linear-gradient(90deg, var(--orange-deep) 0%, var(--orange) 100%); }
/* Planned segment: projected lift from upcoming trips — orange, hatched so it
   reads as "planned, not yet earned". */
.v2-lr__fcbar-planned {
  height: 100%;
  background-color: var(--orange);
  background-image: repeating-linear-gradient(45deg, transparent, transparent 2px, rgba(255, 255, 255, 0.45) 2px, rgba(255, 255, 255, 0.45) 4px);
  opacity: 0.9;
}
.v2-lr__fccap {
  margin-top: 3px;
  font-family: 'Geist Mono', monospace;
  font-size: 0.66667rem;
  letter-spacing: 0.04em;
  color: var(--ink-faint);
}
.v2-panel--dark .v2-lr__fccap { color: rgba(243, 234, 216, 0.55); }
.v2-panel.is-reward-mode .v2-lr__fcbar,
.v2-panel.is-reward-mode .v2-lr__fccap { display: none; }

/* Verdict colour aliases — reuse the ach/ruby families with a directional caret. */
.v2-pace--up   { background: var(--orange-paper);    color: var(--orange-deep); }
.v2-pace--down { background: var(--pace-ruby-paper); color: var(--pace-ruby); }
/* A low-confidence projection reads fainter. */
.v2-pred--c-low { opacity: 0.62; }

/* Dark-panel readability: the paper tints are too pale on navy, so lift the
   prediction chip to the lighter token family with a translucent wash. */
.v2-panel--dark .v2-lr__pred.v2-pace--ok   { background: rgba(127, 217, 164, 0.16); color: var(--pace-on-track-gain); }
.v2-panel--dark .v2-lr__pred.v2-pace--at   { background: rgba(245, 194, 78, 0.16);  color: var(--pace-amber-dark); }
.v2-panel--dark .v2-lr__pred.v2-pace--be,
.v2-panel--dark .v2-lr__pred.v2-pace--down { background: rgba(255, 142, 128, 0.18);  color: var(--pace-ruby-dark); }
.v2-panel--dark .v2-lr__pred.v2-pace--ach,
.v2-panel--dark .v2-lr__pred.v2-pace--up   { background: rgba(255, 170, 102, 0.18);  color: var(--orange-soft); }

.v2-lr__adjust {
  display: inline-block;
  margin-top: 4px;
  font-family: 'Geist Mono', ui-monospace, monospace;
  font-size: 0.63333rem;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-faint);
  text-decoration: none;
  border: 1px solid var(--hairline);
  padding: 2px 7px;
  border-radius: 999px;
  transition: all 160ms var(--ease-out);
}
.v2-lr__adjust:hover {
  color: var(--ink-strong);
  border-color: var(--ink-strong);
}
.v2-panel--dark .v2-lr__adjust {
  color: rgba(255, 255, 255, 0.55);
  border-color: rgba(255, 255, 255, 0.16);
}
.v2-panel--dark .v2-lr__adjust:hover {
  color: var(--paper);
  border-color: var(--paper-soft);
}

/* ─── FLIGHTS HERO (Option 1 — all navy) ──────────────────────
   Filled navy block matching the Trips + Stays heroes and tying to the
   navy Loyalty anchor. The route arc is a light dashed curve with an
   orange apex dot; the "SIN, AMS" headline is white serif. */
.v2-fhero {
  display: block;
  background: linear-gradient(180deg, var(--navy-soft) 0%, var(--navy) 100%);
  border-radius: 13px;
  padding: 13px 15px 14px;
  margin-bottom: 11px;
}
.v2-fhero__lab {
  font-family: 'Geist Mono', monospace;
  font-size: 0.66667rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: #9fb0c4;
}
.v2-fhero__arc {
  position: relative;
  height: 44px;
  margin: 8px 0 2px;
}
.v2-fhero__arc svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}
.v2-fhero__arc svg path { stroke: rgba(255, 255, 255, 0.28); }
.v2-fhero__dot {
  position: absolute;
  left: 50%;
  top: 1px;
  width: 9px;
  height: 9px;
  border-radius: 999px;
  background: var(--orange);
  transform: translateX(-50%);
  box-shadow: 0 0 0 4px rgba(255, 104, 16, 0.18);
}
/* Endpoint row beneath the arc: [code / time] · airline·class · [code / time].
   Fonts match the Loyalty panel — Geist for the codes, Geist Mono for times. */
.v2-fhero__row {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 10px;
  margin-top: 4px;
}
.v2-fhero__pt {
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 0;
}
.v2-fhero__pt--r { align-items: flex-end; text-align: right; }
.v2-fhero__code {
  font-family: 'Geist', sans-serif;
  font-weight: 600;
  font-size: 1.46667rem;
  line-height: 1;
  letter-spacing: -0.01em;
  color: #d7dfea;
}
.v2-fhero__time {
  font-family: 'Geist Mono', monospace;
  font-size: 0.8rem;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.02em;
  color: #9fb0c4;
}
.v2-fhero__mid {
  flex: 1 1 auto;
  align-self: center;
  text-align: center;
  font-family: 'Geist', sans-serif;
  font-size: 0.8rem;
  color: #c4cdd8;
}
.v2-fhero__big {
  font-family: 'Geist', sans-serif;
  font-weight: 600;
  font-size: 1.33333rem;
  line-height: 1.1;
  letter-spacing: -0.01em;
  color: #ffffff;
}
.v2-fhero--empty .v2-fhero__big { color: #c4cdd8; }
.v2-fhero__sub {
  font-size: 0.8rem;
  color: #c4cdd8;
  margin-top: 6px;
}

/* ─── HERO FIG (stays panel) ───────────────────────────────── */
.v2-hero-fig {
  background: var(--paper);
  border: 1px solid var(--hairline);
  border-radius: 14px;
  padding: 14px 16px;
  margin-bottom: 14px;
  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.5) inset;
}
.v2-hero-fig .k {
  font-family: 'Geist Mono', monospace;
  font-size: 0.66667rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin-bottom: 4px;
}
.v2-hero-fig .fig {
  font-family: 'Geist Mono', monospace;
  font-size: 1.73333rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--ink-strong);
  letter-spacing: -0.01em;
}
.v2-hero-fig .fig small {
  font-family: 'Geist', sans-serif;
  font-size: 0.86667rem;
  font-weight: 400;
  color: var(--ink-muted);
  margin-left: 6px;
}
.v2-hero-fig .fig.v2-fig--expired { color: var(--pace-risk); } /* UX-audit F-027 */
.v2-hero-fig .note {
  font-family: 'Bricolage Grotesque', serif;
  font-style: normal;
  font-weight: 400;
  font-size: 0.93333rem;
  color: var(--ink-muted);
  margin-top: 4px;
  line-height: 1.4;
}
.v2-hero-fig .note b {
  font-style: normal;
  font-family: 'Geist', sans-serif;
  font-weight: 500;
  color: var(--pace-amber);
}

/* ─── UPCOMING STAY CARD (replaces nights-this-year hero) ─── */
/* Flows seamlessly out of .v2-panel--cream .v2-panel__head: same paper bg, no
   border, edge-to-edge so head + hero read as one consolidated zone — mirrors
   how .v2-panel--photo .v2-panel__head + .v2-photo merge on the Flights side.
   Locked to the same 152px box height as .v2-photo (Flights hero) so bottoms
   align exactly. Content uses line-clamp on the address and margin-top:auto
   on the dates row to flex into the fixed box gracefully. */
.v2-stay-up {
  background: linear-gradient(180deg, var(--navy-soft) 0%, var(--navy) 100%);
  border: 0;
  border-radius: 13px;
  padding: 13px 15px 14px;
  margin: 0 0 11px;
  box-shadow: none;
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-height: 152px;
  box-sizing: border-box;
}
.v2-stay-up__lab {
  font-family: 'Geist Mono', monospace;
  font-size: 0.66667rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: #9fb0c4;
}
.v2-stay-up__name {
  font-family: 'Geist', sans-serif;
  font-weight: 600;
  font-size: 1.2rem;
  line-height: 1.2;
  letter-spacing: -0.01em;
  color: #ffffff;
  margin-top: 2px;
}
.v2-stay-up__addr {
  font-family: 'Geist', sans-serif;
  font-size: 0.83333rem;
  color: #9fb0c4;
  line-height: 1.4;
  margin-top: 2px;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.v2-stay-up__dates {
  display: flex;
  align-items: flex-start;
  justify-content: center;
  gap: 22px;
  margin-top: auto;
  padding-top: 8px;
  border-top: 1px dashed rgba(255, 255, 255, 0.16);
}
.v2-stay-up__d {
  display: flex;
  flex-direction: column;
  gap: 1px;
  min-width: 0;
}
.v2-stay-up__d--sep {
  align-items: center;
  text-align: center;
}
.v2-stay-up__dk {
  font-family: 'Geist Mono', monospace;
  font-size: 0.63333rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: #9fb0c4;
}
.v2-stay-up__dv {
  font-family: 'Geist Mono', monospace;
  font-size: 0.86667rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: #ffffff;
  letter-spacing: -0.005em;
}
.v2-stay-up__arrow {
  font-family: 'Geist', sans-serif;
  font-size: 1.06667rem;
  color: var(--orange);
  opacity: 0.7;
  flex: 0 0 auto;
}
.v2-stay-up--empty .v2-stay-up__name {
  color: #c4cdd8;
}

/* ─── MARK COMPLETE PILL (inline action on past-due flight rows) ─── */
.v2-mark-pill {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin-left: 8px;
  padding: 2px 8px 2px 6px;
  border-radius: 999px;
  font-family: 'Geist', sans-serif;
  font-weight: 500;
  font-size: 0.7rem;
  letter-spacing: 0.02em;
  text-transform: none;
  color: var(--paper-cream);
  background: rgba(255, 104, 16, 0.85);
  border: 1px solid rgba(255, 104, 16, 0.95);
  cursor: pointer;
  vertical-align: middle;
  transition: all 160ms var(--ease-out);
  box-shadow: 0 1px 2px rgba(255, 104, 16, 0.28), 0 1px 0 rgba(255, 255, 255, 0.18) inset;
  white-space: nowrap;
}
.v2-mark-pill:hover {
  background: var(--orange);
  border-color: var(--orange);
  transform: translateY(-1px);
  box-shadow: 0 3px 8px rgba(255, 104, 16, 0.32);
}
.v2-mark-pill:active { transform: scale(0.97); }
.v2-mark-pill:disabled,
.v2-mark-pill.is-busy {
  opacity: 0.55;
  cursor: progress;
  transform: none;
}
.v2-mark-pill svg {
  width: 10px;
  height: 10px;
  stroke-width: 2.4;
}

/* ─── PANEL FOOTER STAT STRIP (small YTD/lifetime info) ─── */
.v2-panel__stats {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 8px;
  margin-top: auto;
  padding-top: 14px;
  border-top: 1px solid var(--hairline-soft);
}
.v2-panel--dark .v2-panel__stats {
  border-top-color: rgba(255, 255, 255, 0.12);
}
.v2-panel__stat {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 2px;
  min-width: 0;
}
.v2-panel__stat-k {
  font-family: 'Geist Mono', monospace;
  font-size: 0.6rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-faint);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 100%;
}
.v2-panel--photo .v2-panel__stat-k {
  color: var(--ink-faint);
}
.v2-panel__stat-v {
  font-family: 'Geist Mono', monospace;
  font-size: 1.06667rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--ink-strong);
  letter-spacing: -0.01em;
}
.v2-panel--dark .v2-panel__stat-k { color: rgba(243, 234, 216, 0.55); }
.v2-panel--dark .v2-panel__stat-v { color: var(--paper-cream); }

/* ─── PACE PILLS ───────────────────────────────────────────── */
.v2-pace {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 3px 9px;
  border-radius: 999px;
  font-family: 'Geist Mono', monospace;
  font-size: 0.63333rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  font-weight: 500;
}
.v2-pace--ok  { background: var(--pace-on-track-paper); color: var(--pace-on-track); }
.v2-pace--at  { background: var(--pace-amber-paper);   color: var(--pace-amber); }
.v2-pace--be  { background: var(--pace-ruby-paper);    color: var(--pace-ruby); }
.v2-pace--ach { background: var(--orange-paper);       color: var(--orange-deep); }
.v2-pace--in  { background: var(--atlas-paper);        color: var(--atlas-deep); }

/* ─── SECTION HEAD + BUTTONS ───────────────────────────────── */
.v2-s-head {
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  margin: 48px 0 14px;
  padding-bottom: 14px;
  border-bottom: 1px solid var(--hairline);
}
.v2-s-head h2 {
  font-family: 'Bricolage Grotesque', 'Public Sans', system-ui, sans-serif;
  font-weight: 700;
  font-size: 1.66667rem;
  letter-spacing: -0.02em;
  color: var(--ink-strong);
  font-style: normal;
}
.v2-s-head h2 b {
  font-style: normal;
  font-weight: 800;
}
.v2-s-head h2 em {
  font-style: normal;
  font-weight: 700;
  color: var(--ink-muted);
}
.v2-s-head .actions {
  display: flex;
  gap: 8px;
}

.v2-btn {
  font-family: 'Geist', sans-serif;
  font-weight: 500;
  font-size: 0.86667rem;
  border: 1px solid var(--hairline);
  background: var(--paper-soft);
  color: var(--ink);
  cursor: pointer;
  padding: 8px 14px;
  border-radius: 9px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  text-decoration: none;
  transition: all 160ms var(--ease-out);
}
.v2-btn:hover {
  border-color: var(--ink-strong);
  transform: translateY(-1px);
}
.v2-btn:active {
  transform: scale(0.97);
}
.v2-btn--p {
  background: var(--navy);
  color: var(--paper-soft);
  border-color: var(--navy);
}
.v2-btn--p:hover {
  background: var(--orange);
  border-color: var(--orange);
  color: white;
}
.v2-btn--orange {
  background: var(--orange);
  color: white;
  border-color: var(--orange);
  box-shadow: 0 4px 14px rgba(255, 104, 16, 0.30);
}
.v2-btn--orange:hover {
  background: var(--orange-deep);
  border-color: var(--orange-deep);
}

/* P2-E (2026-05-14 audit): discrete button variants beyond --p (navy primary)
   and --orange (CTA). Each variant has a single committed look. Use --primary
   as the canonical alias of --p; older call sites continue to work. */
.v2-btn--primary {
  background: var(--navy);
  color: var(--paper-soft);
  border-color: var(--navy);
}
.v2-btn--primary:hover {
  background: var(--orange);
  border-color: var(--orange);
  color: white;
}
.v2-btn--secondary {
  background: var(--paper-soft);
  color: var(--navy);
  border-color: var(--navy);
}
.v2-btn--secondary:hover {
  background: var(--navy);
  color: var(--paper-soft);
}
.v2-btn--ghost {
  background: transparent;
  color: var(--ink-muted);
  border-color: transparent;
}
.v2-btn--ghost:hover {
  color: var(--ink-strong);
  background: var(--paper-shade);
  border-color: transparent;
}
.v2-btn--outline {
  background: transparent;
  color: var(--ink-strong);
  border-color: var(--hairline-strong);
}
.v2-btn--outline:hover {
  border-color: var(--ink-strong);
  background: var(--paper-soft);
}
.v2-btn--danger {
  background: var(--pace-ruby);
  color: var(--paper-soft);
  border-color: var(--pace-ruby);
}
.v2-btn--danger:hover {
  background: #8E2A1F;
  border-color: #8E2A1F;
}

.v2-btn svg {
  width: 13px;
  height: 13px;
}

/* ─── ACTIVITY FEED ────────────────────────────────────────── */
.v2-act {
  background: var(--paper-soft);
  border: 1px solid var(--hairline);
  border-radius: 14px;
  padding: 16px 20px;
  display: grid;
  grid-template-columns: 36px 1fr auto 90px;
  align-items: center;
  gap: 18px;
  margin-bottom: 8px;
  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.4) inset;
  transition: all 180ms var(--ease-out);
}
.v2-act:hover {
  transform: translateY(-1px);
  border-color: var(--hairline-strong);
}
.v2-act--empty {
  grid-template-columns: 1fr;
  font-family: 'Bricolage Grotesque', serif;
  font-style: normal;
  color: var(--ink-muted);
}
.v2-act__i {
  width: 32px;
  height: 32px;
  border-radius: 9px;
  background: var(--paper);
  border: 1px solid var(--hairline);
  display: grid;
  place-items: center;
  color: var(--navy);
}
.v2-act__i.atlas {
  background: var(--atlas-paper);
  color: var(--atlas-deep);
  border-color: var(--pace-on-track-border);
}
.v2-act__i.alert {
  background: var(--orange-paper);
  color: var(--orange-deep);
  border-color: var(--pace-amber-border);
}
.v2-act__i.flight {
  background: var(--navy-50);
  color: var(--navy);
  border-color: var(--c-navy-border);
}
.v2-act__i.stay {
  background: var(--c-business-paper);
  color: var(--c-business);
  border-color: var(--c-business-border);
}
.v2-act__i svg {
  width: 14px;
  height: 14px;
  stroke-width: 1.8;
}
.v2-act__b {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.v2-act__t {
  font-family: 'Geist', sans-serif;
  font-size: 0.93333rem;
  color: var(--ink-strong);
}
.v2-act__t b { font-weight: 600; }
.v2-act__t em {
  font-style: normal;
  color: var(--orange-deep);
}
.v2-act__m {
  font-family: 'Geist Mono', monospace;
  font-size: 0.7rem;
  letter-spacing: 0.08em;
  color: var(--ink-faint);
}
.v2-act__d {
  font-family: 'Geist Mono', monospace;
  font-size: 0.86667rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--ink-strong);
}
.v2-act__d.gain { color: var(--pace-on-track); }
.v2-act__d.loss { color: var(--pace-ruby); }
.v2-act__w {
  font-family: 'Geist Mono', monospace;
  font-size: 0.73333rem;
  color: var(--ink-muted);
  text-align: right;
}

/* ─── AD SLOT (Explorer dashboard) ─────────────────────────── */
.v2-ad-slot {
  margin: 32px 0 16px;
}
.v2-ad-slot--dash-in-content {
  border-top: 1px solid var(--hairline-soft);
  border-bottom: 1px solid var(--hairline-soft);
  padding: 16px 0;
}

/* ─── ERROR STATE ──────────────────────────────────────────── */
.v2-error {
  padding: 24px;
  background: var(--pace-ruby-paper);
  color: var(--pace-ruby);
  border-radius: 14px;
  font-family: 'Geist', sans-serif;
}

/* ─── RESPONSIVE (Phase 9 will deepen) ─────────────────────── */
@media (max-width: 1120px) {
  .v2-panels { grid-template-columns: 1fr; }
}
@media (max-width: 720px) {
  .v2-act { grid-template-columns: 32px 1fr auto; }
  .v2-act__w { display: none; }
  .v2-s-head { flex-direction: column; align-items: flex-start; gap: 12px; }
}

/* ═══════════════════════════════════════════════════════════════
   LAYOUT A — Loyalty anchor + Trips strip + Flights/Stays 2-up
   ───────────────────────────────────────────────────────────────
   The dashboard grid carries `.v2-panels--quad` to switch from the
   legacy 3-up row to a 2-column composition: Loyalty is a full-height
   left anchor, and `.v2-panels__right` stacks Trips above Flights + Stays
   (`.v2-fs` 2-up) with no dead row gap between them.
   ═══════════════════════════════════════════════════════════════ */
.v2-panels--quad {
  grid-template-columns: minmax(360px, 410px) minmax(0, 1fr);
  grid-template-rows: auto;
  align-items: stretch;
}
.v2-panels--quad > .v2-panel--anchor { grid-column: 1; grid-row: 1; }
.v2-panels--quad > .v2-panels__right {
  grid-column: 2;
  grid-row: 1;
  display: flex;
  flex-direction: column;
  gap: 12px;
  min-width: 0;
  align-self: start;
}
.v2-panels__right > .v2-fs {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 18px;
  min-width: 0;
}
.v2-fs > .v2-panel { min-width: 0; }
/* Keep loyalty rows at their natural (dense) height — the anchor spans the
   full column height, but the programme rows stay top-stacked rather than
   stretching to fill it. */
.v2-panels--quad > .v2-panel--anchor .v2-lr { flex: 0 0 auto; }

/* ─── Calm restyle: light Loyalty panel (replaces the navy v2-panel--dark anchor) ───
   The loyalty rows + forecast sub-lines + Status/Rewards toggle were styled white
   for the dark panel; re-assert dark ink on light so nothing reads white-on-white. */
.v2-panel--loyalty { background: var(--paper-soft); }
.v2-panel--loyalty .v2-lede .amber { color: var(--pace-caution); font-weight: 600; }
.v2-panel--loyalty .v2-lede .ruby  { color: var(--pace-risk); font-weight: 600; }
.v2-panel--loyalty .v2-mode-toggle { background: var(--paper-shade); border-color: transparent; }
.v2-panel--loyalty .v2-mode-toggle__opt { color: var(--ink-muted); }
.v2-panel--loyalty .v2-mode-toggle__opt:hover { color: var(--ink-strong); }
.v2-panel--loyalty .v2-mode-toggle__opt.is-active {
  background: var(--paper-soft); color: var(--ink-strong);
  box-shadow: 0 1px 1px rgba(14, 31, 59, 0.06);
}
.v2-panel--loyalty .v2-lr__fc-after { color: var(--ink-muted); }
.v2-panel--loyalty .v2-lr__fc-conf  { color: var(--ink-faint); }
.v2-panel--loyalty .v2-lr__fc-renew { color: var(--ink-muted); opacity: 1; }
.v2-panel--loyalty .v2-lr__fccap    { color: var(--ink-faint); }
.v2-panel--loyalty .v2-lr__verdict-days,
.v2-panel--loyalty .v2-lr__verdict-line { color: var(--ink-strong); }
.v2-panel--loyalty .v2-lr__cta { color: var(--orange-deep); }
.v2-panel--loyalty .v2-lr__cta:hover { color: var(--orange); }
.v2-panel--loyalty .v2-lr__r.gain { color: var(--pace-secure); }
.v2-panel--loyalty .v2-lr__r.expiring { color: var(--pace-caution); }
.v2-panel--loyalty .v2-lr__r.expired { color: var(--pace-risk); } /* UX-audit F-027 */
.v2-panel--loyalty .v2-lr__m--expired { color: var(--pace-risk); }
.v2-panel--loyalty .v2-lr__bar,
.v2-panel--loyalty .v2-lr__fcbar { background: var(--paper-shade); }

/* ─── Calm: compact loyalty rows — minimal default, detail on hover/focus ───
   Logo, name + status level, tier bar and the status-points line stay visible;
   the forecast verdict / renewal outlook / reward balance collapse into
   .v2-lr__detail and reveal on hover or keyboard focus. A details-icon links to
   the full programme-detail page. Scoped to .v2-panel--loyalty so the shared
   .v2-lr work-queue rows elsewhere are untouched. */
.v2-panel--loyalty .v2-lr { align-items: start; }
.v2-panel--loyalty .v2-lr__lg { margin-top: 1px; }
.v2-lr__m--points {
  font-family: 'IBM Plex Mono', ui-monospace, monospace;
  font-variant-numeric: tabular-nums;
  margin-top: 5px;
}
.v2-lr__detail {
  max-height: 0;
  overflow: hidden;
  opacity: 0;
  transition: max-height 280ms var(--ease-out), opacity 200ms var(--ease-out), margin-top 280ms var(--ease-out);
}
.v2-lr__detail > * + * { margin-top: 7px; }
.v2-panel--loyalty .v2-lr:hover .v2-lr__detail,
.v2-panel--loyalty .v2-lr:focus-within .v2-lr__detail {
  max-height: 480px;
  opacity: 1;
  margin-top: 9px;
}
/* F-038: touch devices have no hover and the rows are plain divs, so the
   hover/focus-within reveal above never fires on phones/tablets. Under a
   coarse pointer the detail (requalification verdict, expiry, "What fixes
   this") is always visible. */
@media (pointer: coarse) {
  .v2-panel--loyalty .v2-lr .v2-lr__detail {
    max-height: none;
    overflow: visible;
    opacity: 1;
    margin-top: 9px;
  }
}
.v2-lr__detail-bal {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 4px 12px;
  font-family: 'IBM Plex Mono', ui-monospace, monospace;
  font-size: 0.8rem;
  color: var(--ink-muted);
}
.v2-lr__detail-bal-n { color: var(--ink-strong); font-weight: 600; font-variant-numeric: tabular-nums; }
.v2-lr__detail-bal-n.expiring { color: var(--pace-caution); }
.v2-lr__detail-bal-n.expired { color: var(--pace-risk); } /* UX-audit F-027 */
.v2-lr__detail-bal-n.gain { color: var(--pace-secure); }
.v2-lr__detail-bal .v2-lr__u { font-family: 'Public Sans', system-ui, sans-serif; font-weight: 400; color: var(--ink-muted); }
.v2-lr__detail-bal small { color: var(--ink-faint); }
.v2-lr__detail-link {
  align-self: start;
  width: 30px;
  height: 30px;
  display: grid;
  place-items: center;
  border-radius: 8px;
  color: var(--ink-faint);
  border: 1px solid transparent;
  text-decoration: none;
  transition: color 160ms var(--ease-out), background 160ms var(--ease-out), border-color 160ms var(--ease-out);
}
.v2-lr__detail-link svg { width: 16px; height: 16px; }
.v2-panel--loyalty .v2-lr:hover .v2-lr__detail-link { color: var(--ink-muted); }
.v2-lr__detail-link:hover,
.v2-lr__detail-link:focus-visible {
  color: var(--ink-strong);
  background: var(--paper-shade);
  border-color: var(--hairline);
  outline: none;
}
@media (prefers-reduced-motion: reduce) {
  .v2-lr__detail { transition: none; }
}

/* ─── Rewards mode: the Status/Rewards toggle (.is-reward-mode on the panel) swaps
   each row to reward-balance emphasis — the reward points replace the status tier
   label, and the tier bar / status-points line / forecast detail are hidden. ─── */
.v2-lr__rewards-val,
.v2-lr__rewards-meta { display: none; }
.v2-panel--loyalty.is-reward-mode .v2-lr__head .v2-lr__m,
.v2-panel--loyalty.is-reward-mode .v2-lr__bar,
.v2-panel--loyalty.is-reward-mode .v2-lr__m--points,
.v2-panel--loyalty.is-reward-mode .v2-lr__ctas,
.v2-panel--loyalty.is-reward-mode .v2-lr__detail { display: none; }
.v2-panel--loyalty.is-reward-mode .v2-lr__rewards-val {
  display: inline-flex;
  align-items: baseline;
  gap: 4px;
  font-family: 'IBM Plex Mono', ui-monospace, monospace;
  font-size: 1rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--ink-strong);
  white-space: nowrap;
}
.v2-panel--loyalty.is-reward-mode .v2-lr__rewards-val.expiring { color: var(--pace-caution); }
.v2-panel--loyalty.is-reward-mode .v2-lr__rewards-val.expired { color: var(--pace-risk); } /* UX-audit F-027 */
.v2-panel--loyalty.is-reward-mode .v2-lr__rewards-val.gain { color: var(--pace-secure); }
.v2-lr__rewards-val .v2-lr__u {
  font-family: 'Public Sans', system-ui, sans-serif;
  font-size: 0.73333rem;
  font-weight: 400;
  color: var(--ink-muted);
}
.v2-panel--loyalty.is-reward-mode .v2-lr__rewards-meta {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  margin-top: 5px;
  font-family: 'IBM Plex Mono', ui-monospace, monospace;
  font-size: 0.73333rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-faint);
}
.v2-panel--loyalty.is-reward-mode .v2-lr__rewards-meta .v2-lr__adjust {
  text-transform: none;
  letter-spacing: 0;
  color: var(--orange-deep);
}

/* ─── Calm restyle: light Trips active card (was navy gradient; mockup uses a
   light #FCFCFC card). Re-assert dark ink on the card contents. ─── */
.v2-panel--journey .v2-trips__active {
  background: var(--paper-soft);
  border: 1px solid var(--hairline);
}
.v2-panel--journey .v2-trips__lead { color: var(--ink-muted); }
.v2-panel--journey .v2-trips__title {
  color: var(--ink-strong);
  font-family: 'Bricolage Grotesque', 'Public Sans', system-ui, sans-serif;
}
.v2-panel--journey .v2-trips__meta { color: var(--ink-muted); }
.v2-panel--journey .v2-rail__node { border-color: var(--hairline-strong); }
.v2-panel--journey .v2-rail__code { color: var(--ink-strong); }
.v2-panel--journey .v2-rail__fl { color: var(--ink-faint); }
.v2-panel--journey .v2-rail__nights.is-ghost { color: var(--ink-faint); }
.v2-panel--journey .v2-rail__line {
  background: repeating-linear-gradient(90deg, var(--hairline-strong) 0 3px, transparent 3px 6px);
}
.v2-panel--journey .v2-tchip {
  color: var(--ink-muted);
  background: var(--paper-shade);
  border-color: var(--hairline);
}
.v2-panel--journey .v2-tchip b { color: var(--ink-strong); }
.v2-panel--journey .v2-trips__grouped-note { color: var(--ink-faint); }
.v2-panel--journey .v2-trips__active .v2-trips__earn { color: var(--ink-muted); }
.v2-panel--journey .v2-trips__active .v2-trips__earn b { color: var(--ink-strong); }
.v2-panel--journey .v2-trips__active .v2-trips__ready-chip {
  color: var(--ink-muted); border-color: var(--hairline);
}
.v2-panel--journey .v2-trips__active .v2-trips__ready-chip.is-ok {
  color: var(--pace-secure); border-color: var(--pace-secure-border); background: var(--pace-secure-paper);
}
.v2-panel--journey .v2-trips__active .v2-trips__ready-chip.is-warn {
  color: var(--pace-caution); border-color: var(--pace-caution-border); background: var(--pace-caution-paper);
}

/* ─── Calm restyle: "Needs attention" consolidated header + decluttered queues ─── */
.v2-na-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  margin: 4px 2px 2px;
}
.v2-na-head__title { font-size: 1.13333rem; font-weight: 700; color: var(--ink-strong); }
.v2-na-head__hint {
  font-size: 0.66667rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-faint);
}
/* Drop the redundant per-panel count chips + lifetime stats — they live on the
   Flights/Stays pages; the Needs-attention pair keeps the next-X cards + rows. */
.v2-panels__right .v2-fs .v2-wq-counts,
.v2-panels__right .v2-fs .v2-panel__stats { display: none; }
/* True single "Needs attention" panel — header + the two queues read as one card. */
.v2-na { background: var(--paper-soft); padding: 18px 22px 16px; }
.v2-na .v2-na-head { margin: 0 0 4px; }
.v2-na .v2-fs { display: grid; grid-template-columns: 1fr 1fr; gap: 0; min-width: 0; }
.v2-na .v2-fs > .v2-panel {
  border: 0; box-shadow: none; background: transparent;
  padding: 12px 0 0; min-height: 0; border-radius: 0;
}
.v2-na .v2-fs > .v2-panel::before { display: none; }
.v2-na .v2-fs > .v2-panel:hover { transform: none; box-shadow: none; }
.v2-na .v2-fs > [data-tour="dashboard-flights-panel"] {
  padding-right: 22px;
  border-right: 1px solid var(--hairline);
}
.v2-na .v2-fs > [data-tour="dashboard-stays-panel"] { padding-left: 22px; }
/* strip the photo/cream head bands inside the single panel */
.v2-na .v2-panel--photo .v2-panel__head,
.v2-na .v2-panel--cream .v2-panel__head {
  background: transparent; margin: 0; padding: 0 0 8px; border-radius: 0;
}
.v2-na .v2-panel--photo .v2-panel__head::before,
.v2-na .v2-panel--cream .v2-panel__head::before { display: none; }
/* When the two columns stack (≤720px, see :1899), the vertical divider becomes a
   horizontal one and padding goes symmetric. */
@media (max-width: 720px) {
  .v2-na .v2-fs { grid-template-columns: 1fr; }
  .v2-na .v2-fs > [data-tour="dashboard-flights-panel"] {
    border-right: 0; padding-right: 0;
    border-bottom: 1px solid var(--hairline); padding-bottom: 14px;
  }
  .v2-na .v2-fs > [data-tour="dashboard-stays-panel"] { padding-left: 0; padding-top: 14px; }
}
/* Demoted verdict strip: keep the Sandstone/Ember number emphasis on light paper. */
.v2-verdict .amber { color: var(--pace-caution); font-weight: 700; }
.v2-verdict .ruby  { color: var(--pace-risk); font-weight: 700; }

/* ─── UNIFIED PANELS (Trips · Flights · Stays) ─────────────────
   Handoff "Option 1 — all navy": the three cards stay quiet white with a
   plain head, but each LEAD/HERO block is a filled navy box (see the
   .v2-fhero, .v2-stay-up and .v2-trips__active rules) so all three match
   each other and tie to the navy Loyalty anchor. The card + head
   backgrounds are still neutralised here so the heads read uniform. */
.v2-panel--photo,
.v2-panel--cream {
  background: var(--paper-soft);
  padding-top: 22px;
}
.v2-panel--photo::before,
.v2-panel--cream::before { display: block; }
.v2-panel--photo .v2-panel__head,
.v2-panel--cream .v2-panel__head {
  background: transparent;
  color: var(--ink-strong);
  margin: 0 0 16px;
  padding: 0;
  border-radius: 0;
}
.v2-panel--photo .v2-panel__head::before,
.v2-panel--cream .v2-panel__head::before { display: none; }
.v2-panel--photo .v2-panel__head .v2-panel__title { color: var(--ink-strong); }
.v2-panel--photo .v2-panel__head .v2-panel__arrow { color: inherit; opacity: 0.55; }
.v2-panel--photo .v2-panel__head .v2-panel__arrow:hover { background: var(--paper-shade); opacity: 1; }
/* Stays hero: navy fill (Option 1) — see the .v2-stay-up base rule above. */

/* ─── TRIP HERO (active / ≤7d — full-width above panel grid) ─── */
.v2-trip-hero {
  margin: 0 0 18px;
  border-radius: 18px;
  background: linear-gradient(180deg, #1b2d46 0%, #0e1f3b 100%);
  border: 1px solid rgba(255, 255, 255, 0.08);
  box-shadow: var(--sh-inverse);
  overflow: hidden;
}
.v2-trip-hero__inner {
  padding: 22px 24px 20px;
}
.v2-trip-hero__top {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
}
.v2-trip-hero__lead {
  display: flex;
  align-items: center;
  gap: 7px;
  font-family: 'Geist Mono', monospace;
  font-size: 0.66667rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: #f3a672;
}
.v2-trip-hero--active .v2-trip-hero__lead { color: var(--orange); }
.v2-trip-hero__lead.is-soon { color: var(--orange); }
.v2-trip-hero__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin-left: auto;
}
.v2-trip-hero__cta.v2-btn--p {
  background: var(--orange);
  border-color: var(--orange);
  color: #fff;
}
.v2-trip-hero__cta.v2-btn--p:hover {
  background: var(--orange-deep);
  border-color: var(--orange-deep);
  color: #fff;
}
.v2-trip-hero__cta-secondary {
  background: transparent;
  border-color: rgba(255, 255, 255, 0.28);
  color: rgba(255, 255, 255, 0.9);
}
.v2-trip-hero__cta-secondary:hover {
  border-color: rgba(255, 255, 255, 0.5);
  color: #fff;
  background: rgba(255, 255, 255, 0.06);
}
.v2-trip-hero__title {
  font-family: 'Geist', sans-serif;
  font-weight: 600;
  font-size: clamp(1.46667rem, 2.4vw, 1.86667rem);
  line-height: 1.12;
  letter-spacing: -0.02em;
  color: #fff;
  margin: 8px 0 0;
}
.v2-trip-hero__meta {
  font-family: 'Geist Mono', monospace;
  font-size: 0.66667rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: #9fb0c4;
  margin: 5px 0 0;
}
.v2-trip-hero__progress {
  height: 4px;
  margin: 16px 0 4px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.12);
  overflow: hidden;
}
.v2-trip-hero__progress-fill {
  height: 100%;
  border-radius: inherit;
  background: linear-gradient(90deg, var(--orange), #ffb07a);
  transition: width 400ms var(--ease-out);
}
.v2-rail--hero {
  margin: 16px 0 14px;
  overflow-x: auto;
  padding-bottom: 4px;
}
.v2-trip-hero__footer {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 10px 16px;
  margin-top: 4px;
}
.v2-trip-hero .v2-trips__chips { margin-top: 0; }
.v2-trips__band--hero-mode {
  grid-template-columns: 1fr;
  gap: 12px;
}
.v2-trips__hero-note {
  font-family: 'Geist', sans-serif;
  font-size: 0.86667rem;
  line-height: 1.45;
  color: var(--ink-muted);
  padding: 2px 0 4px;
}
.v2-trips__aside {
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-width: 0;
}
.v2-trips__also {
  font-family: 'Geist Mono', monospace;
  font-size: 0.66667rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-muted);
}

/* ─── TRIPS PANEL (white card, warm border) ─────────────────── */
.v2-panel--journey {
  background: var(--paper-soft);
  border-color: var(--orange-paper);
  min-height: 0;
}
.v2-panel--journey-empty {
  min-height: 248px;
}
.v2-panel--journey .v2-trips__band {
  flex: 0 0 auto;
}
.v2-panel--journey .v2-panel__arrow:hover { background: var(--paper-shade); }
.v2-trips__count {
  margin-right: auto;
  font-family: 'Geist Mono', monospace;
  font-size: 0.66667rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-faint);
  white-space: nowrap;
}

/* ─── WORK-QUEUE PANELS (Flights · Stays "not in a trip") ───────
   The Flights/Stays panels are de-duplicated work queues: they list only
   records NOT attached to a trip (trip_id IS NULL). The hint keeps the title
   left + arrow right (mirrors .v2-trips__count); the links guarantee that
   trip-attached records are always one click away (never hidden). */
.v2-panel__hint {
  margin-right: auto;
  font-family: 'Geist Mono', monospace;
  font-size: 0.66667rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-faint);
  white-space: nowrap;
}
.v2-panel__links {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 16px;
  margin: 10px 0 2px;
}
.v2-panel__link {
  font-family: 'Geist Mono', monospace;
  font-size: 0.73333rem;
  letter-spacing: 0.06em;
  color: var(--ink-muted);
  text-decoration: none;
  transition: color 0.15s ease;
}
.v2-panel__link:hover,
.v2-panel__link:focus-visible {
  color: var(--orange);
}
.v2-trips__band {
  display: grid;
  grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr);
  gap: 18px;
  flex: 1;
  min-height: 0;
}
.v2-trips__active {
  display: flex;
  flex-direction: column;
  min-width: 0;
  background: linear-gradient(180deg, var(--navy-soft) 0%, var(--navy) 100%);
  border-radius: 13px;
  padding: 13px 15px 14px;
}
.v2-trips__list {
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-width: 0;
}
/* Trips panel layout: the active trip card (the "hero") + its CTA (wrapped in
   .v2-trips__primary) sit in the left column and the trip list sits in the right
   column, so the panel takes more horizontal and less vertical space and the
   Flight/Stay work-queue row beneath rises into view. The optional grouped-note
   keeps its full-width span (grid-column: 1 / -1) and so leads as its own row.
   Scoped to the non-hero band; the hero mode (card rendered above the grid) and
   the empty state already use the 2-column band. */
.v2-trips__band:not(.v2-trips__band--hero-mode) > .v2-trips__primary {
  grid-column: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-self: start;
}
.v2-trips__band:not(.v2-trips__band--hero-mode) > .v2-trips__list {
  grid-column: 2;
  justify-content: flex-start;
  align-self: start;
}

/* Active journey — eyebrow, title, meta */
.v2-trips__lead {
  display: flex;
  align-items: center;
  gap: 7px;
  font-family: 'Geist Mono', monospace;
  font-size: 0.66667rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: #f3a672;
}
.v2-trips__dot {
  width: 7px;
  height: 7px;
  border-radius: 999px;
  background: var(--orange);
  box-shadow: 0 0 0 3px rgba(255, 104, 16, 0.16);
  flex: 0 0 auto;
}
.v2-trips__dot--idle {
  background: rgba(255, 255, 255, 0.4);
  box-shadow: none;
}
.v2-panel--journey-empty .v2-trips__lead { color: #8597ac; }
.v2-trips__title {
  font-family: 'Geist', sans-serif;
  font-weight: 600;
  font-size: 1.33333rem;
  line-height: 1.15;
  letter-spacing: -0.01em;
  color: #ffffff;
  margin-top: 5px;
}
.v2-trips__title--empty { color: #c4cdd8; }
.v2-trips__meta {
  font-family: 'Geist Mono', monospace;
  font-size: 0.66667rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: #9fb0c4;
  margin-top: 3px;
}
.v2-panel--journey-empty .v2-trips__meta {
  font-family: 'Geist', sans-serif;
  font-style: normal;
  font-size: 0.86667rem;
  letter-spacing: 0;
  text-transform: none;
  color: #c4cdd8;
  line-height: 1.4;
  margin-top: 6px;
  max-width: 46ch;
}

/* Journey rail — horizontal stops + flight legs */
.v2-rail {
  display: flex;
  align-items: flex-start;
  margin: 14px 0 12px;
}
.v2-rail__stop {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 5px;
  flex: 0 0 auto;
  width: 40px;
}
.v2-rail__node {
  width: 10px;
  height: 10px;
  border-radius: 999px;
  background: transparent;
  border: 2px solid rgba(255, 255, 255, 0.55);
  margin-top: 9px;
}
.v2-rail__stop.is-sleep .v2-rail__node { border-color: var(--orange); }
.v2-rail__code {
  font-family: 'Geist Mono', monospace;
  font-size: 0.66667rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: #ffffff;
}
.v2-rail__nights {
  font-family: 'Geist Mono', monospace;
  font-size: 0.6rem;
  font-weight: 600;
  color: white;
  background: var(--orange);
  border-radius: 999px;
  padding: 1px 6px;
  letter-spacing: 0.02em;
}
.v2-rail__nights.is-ghost {
  background: transparent;
  color: rgba(255, 255, 255, 0.4);
  font-weight: 500;
}
.v2-rail__leg {
  flex: 1 1 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  min-width: 0;
}
.v2-rail__fl {
  display: flex;
  align-items: center;
  gap: 4px;
  height: 14px;
  color: #9fb0c4;
  font-family: 'Geist Mono', monospace;
  font-size: 0.56667rem;
  letter-spacing: 0.04em;
  white-space: nowrap;
}
.v2-rail__fl svg { width: 11px; height: 11px; color: var(--orange); flex: 0 0 auto; }
.v2-rail__line {
  height: 2px;
  width: 100%;
  margin-top: 8px;
  background: repeating-linear-gradient(90deg, rgba(255, 255, 255, 0.4) 0 3px, transparent 3px 6px);
}

/* Summary chips */
.v2-trips__chips {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: auto;
}
/* `.v2-tchip` (NOT `.v2-chip` — that belongs to the Atlas bar in shell.css;
   dashboard.css loads after shell.css so reusing the name would hijack it). */
.v2-tchip {
  font-family: 'Geist', sans-serif;
  font-size: 0.73333rem;
  color: #d8e0ea;
  background: rgba(255, 255, 255, 0.08);
  border: 1px solid rgba(255, 255, 255, 0.16);
  border-radius: 9px;
  padding: 5px 9px;
  white-space: nowrap;
}
.v2-tchip b {
  font-family: 'Geist Mono', monospace;
  font-weight: 600;
  font-size: 0.86667rem;
  font-variant-numeric: tabular-nums;
  color: #ffffff;
  margin-right: 3px;
}
.v2-tchip--cta {
  color: var(--orange-deep);
  background: var(--orange-paper);
  border-color: var(--orange-paper);
  font-weight: 600;
  text-decoration: none;
  transition: all 160ms var(--ease-out);
}
.v2-tchip--cta:hover {
  background: var(--orange);
  color: white;
  border-color: var(--orange);
}

/* Compact trip list (right column of the strip) */
.v2-trip-row {
  display: grid;
  grid-template-columns: 30px 1fr auto;
  /* A row can carry 4 children (cal, main, readiness dot, status tag). Flow the
     extra child into a new column on the same row instead of wrapping the tag
     into the 30px column, which clipped its pill to a "half pill". */
  grid-auto-flow: column;
  align-items: center;
  gap: 11px;
  padding: 9px 0;
  border-top: 1px solid var(--hairline-soft);
  text-decoration: none;
  color: inherit;
  transition: background 140ms var(--ease-out);
}
.v2-trip-row:first-child { border-top: 0; }
.v2-trip-row:hover {
  background: var(--paper-shade);
  border-radius: 8px;
}
.v2-trip-row--empty {
  display: block;
  font-family: 'Geist', sans-serif;
  font-size: 0.86667rem;
  color: var(--ink-muted);
}
.v2-trip-row--empty a { color: inherit; text-decoration: underline; }
.v2-trip-row__cal {
  width: 30px;
  height: 30px;
  border-radius: 8px;
  display: grid;
  place-items: center;
  background: var(--paper-shade);
  color: var(--ink-muted);
}
.v2-trip-row__cal svg { width: 16px; height: 16px; }
.v2-trip-row__main {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.v2-trip-row__name {
  font-family: 'Geist', sans-serif;
  font-size: 0.83333rem;
  font-weight: 600;
  color: var(--ink-strong);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.v2-trip-row__sub {
  font-family: 'Geist Mono', monospace;
  font-size: 0.6rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-faint);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.v2-trip-row__tag {
  font-family: 'Geist Mono', monospace;
  font-size: 0.6rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--orange-deep);
  white-space: nowrap;
  flex: 0 0 auto;
}
.v2-trip-row__tag.is-done {
  color: var(--pace-on-track);
  background: var(--pace-on-track-paper);
  border-radius: 999px;
  padding: 3px 9px;
}
.v2-trip-row__tag.is-warn {
  color: var(--orange-deep);
  background: var(--orange-paper);
  border-radius: 999px;
  padding: 3px 9px;
}

/* ─── CLICK-TO-EDIT AFFORDANCES ─────────────────────────────────
   Every hero block (Flights, Stays, Trips) and every flight/stay row links
   to its item's editor. Heroes are <a> elements; the navy fill stays, we just
   neutralise the anchor defaults and add a subtle lift on hover. Rows keep
   their <div> markup (they hold the "Mark complete" button) and navigate via
   JS, so they get a paper hover + focus ring here. */
.v2-fhero--link,
.v2-stay-up--link,
.v2-trips__active--link {
  cursor: pointer;
  text-decoration: none;
  color: inherit;
  transition: box-shadow 160ms var(--ease-out), transform 160ms var(--ease-out);
}
.v2-fhero--link:hover,
.v2-stay-up--link:hover,
.v2-trips__active--link:hover {
  transform: translateY(-1px);
  box-shadow: 0 8px 22px rgba(8, 15, 28, 0.30);
}
.v2-fhero--link:focus-visible,
.v2-stay-up--link:focus-visible,
.v2-trips__active--link:focus-visible {
  outline: 2px solid var(--orange);
  outline-offset: 2px;
}
.v2-lr--clickable {
  cursor: pointer;
  border-radius: 8px;
  transition: background 140ms var(--ease-out);
}
.v2-lr--clickable:hover { background: var(--paper-shade); }
.v2-lr--clickable:focus-visible {
  outline: 2px solid var(--orange);
  outline-offset: -2px;
}

/* ─── LAYOUT A RESPONSIVE ───────────────────────────────────── */
@media (max-width: 1120px) {
  /* Tablet: single main column, source order Loyalty → Trips →
     (Flights | Stays 2-up). Explicit placement overrides the generic
     `.v2-panels { grid-template-columns: 1fr }` collapse above. */
  .v2-panels--quad {
    grid-template-columns: 1fr;
    grid-template-rows: auto;
  }
  .v2-panels--quad > .v2-panel--anchor,
  .v2-panels--quad > .v2-panels__right {
    grid-column: 1;
    grid-row: auto;
  }
}
@media (max-width: 720px) {
  /* Mobile: full single-column stack; Flights + Stays drop to 1-up and
     the dense journey rail becomes horizontally scrollable. */
  .v2-panels__right > .v2-fs { grid-template-columns: 1fr; }
  .v2-rail {
    overflow-x: auto;
    padding-bottom: 4px;
  }
}
@media (min-width: 721px) and (max-width: 1120px) {
  /* MM-38: tablet (~768-1023) was collapsing the dashboard to one column,
     wasting ~half the width. Re-introduce a balanced 2-column composition for
     the 721-1120 band only. Phones (<=720) keep the single-column stack above;
     desktop (>=1121) keeps the anchor layout. The Loyalty anchor takes a fixed
     left rail; Trips + the Flights/Stays pair stack in the right column, and
     that pair stays 2-up. */
  .v2-panels--quad {
    grid-template-columns: minmax(300px, 360px) minmax(0, 1fr);
    grid-template-rows: auto;
  }
  .v2-panels--quad > .v2-panel--anchor { grid-column: 1; grid-row: 1; }
  .v2-panels--quad > .v2-panels__right { grid-column: 2; grid-row: 1; }
}
/* The active trip card carries a journey rail, so once the right column gets
   narrow (tablet as well as phone) stack the card above the list instead of
   cramping it into a sliver. Resets the desktop 2-column placement so the
   primary block and the list fall back to a single source-ordered column. */
@media (max-width: 960px) {
  .v2-trips__band:not(.v2-trips__band--hero-mode) { grid-template-columns: 1fr; }
  .v2-trips__band:not(.v2-trips__band--hero-mode) > .v2-trips__primary,
  .v2-trips__band:not(.v2-trips__band--hero-mode) > .v2-trips__list {
    grid-column: 1;
  }
  .v2-trips__list {
    border-left: 0;
    padding-left: 0;
    border-top: 1px solid var(--hairline);
    padding-top: 6px;
    margin-top: 10px;
  }
}
@media (max-width: 560px) {
  .v2-trip-hero__inner { padding: 18px 16px 16px; }
  .v2-trip-hero__top { flex-direction: column; align-items: stretch; }
  .v2-trip-hero__actions { margin-left: 0; }
  .v2-trip-hero__cta,
  .v2-trip-hero__cta-secondary { flex: 1 1 auto; justify-content: center; }
}

/* ── Pull-to-refresh (mobile dashboard) ──────────────────────────────────────
   Indicator for assets/js/design-v2/pull-refresh.js. Rendered only on the
   dashboard by _layout.php. A position:fixed pill that fades in during a
   top-of-page downward drag, then spins (reusing overlays.css @keyframes
   v2-spin) while the page reloads. Hidden + inert on desktop (the JS never
   adds .is-visible above 768px), so no media query is needed here. */
.mm-pull-refresh {
  position: fixed;
  top: calc(64px + env(safe-area-inset-top, 0px));
  left: 50%;
  transform: translate(-50%, -18px) scale(0.92);
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 10px 14px;
  border-radius: 999px;
  background: var(--paper-soft);
  border: 1px solid var(--hairline);
  box-shadow: 0 12px 24px rgba(14, 31, 59, 0.16);
  color: var(--ink-strong);
  font-size: 0.86667rem;
  font-weight: 600;
  opacity: 0;
  pointer-events: none;
  transition: opacity 200ms ease, transform 200ms ease;
  z-index: 1080;
}

.mm-pull-refresh.is-visible {
  opacity: 1;
  transform: translate(-50%, 0) scale(1);
}

.mm-pull-refresh__spinner {
  width: 18px;
  height: 18px;
  border: 2px solid var(--navy-100);
  border-top-color: var(--navy);
  border-radius: 50%;
}

.mm-pull-refresh.is-loading .mm-pull-refresh__spinner {
  animation: v2-spin 700ms linear infinite;
}

@media (prefers-reduced-motion: reduce) {
  .mm-pull-refresh {
    transition-duration: 0.01ms;
  }
  .mm-pull-refresh.is-loading .mm-pull-refresh__spinner {
    animation: none;
  }
}

/* ─── MOBILE TYPE FLOOR & ANTI-TRUNCATION (≤ 767px) ──────────
   MM-08: never clip status-critical days-to-renewal on the dashboard loyalty
   rows; raise metadata to the 12px mobile floor and allow a 2-line wrap.
   MM-07: lift sub-12px micro-labels and the sub-11px projection chip. */
@media (max-width: 767px) {
  .v2-lr__fc-renew {
    font-size: 0.8rem;
    white-space: normal;
    overflow: hidden;
    text-overflow: clip;
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    line-height: 1.35;
  }
  /* keep the projection pill aligned to the first line when renew wraps */
  .v2-lr__fc { align-items: flex-start; }

  /* MM-07: chip floor — lift the projection pill + caret off 9px */
  .v2-lr__pred { font-size: 0.73333rem; padding: 3px 8px; }
  .v2-pred__caret { width: 11px; height: 11px; }

  /* MM-07: row meta + forecast caption to the 12px floor */
  .v2-lr__m { font-size: 0.8rem; opacity: 0.72; }
  .v2-lr__fccap { font-size: 0.8rem; }
  .v2-panel--dark .v2-lr__fccap { color: rgba(243, 234, 216, 0.82); }
}

/* ── Trips panel: read-first Overview signals (Trips redesign) ─────────────
   Flag-gated in markup (only render when $tripOverviewEnabled). Tokens + rgba
   only, no new hex literals (css-hex-guard). Extends, does not rewrite, the
   existing .v2-trips__* / .v2-trip-row__* blocks above. */
.v2-trips__active-wrap { position: relative; }

/* 3-way status: vivid green "active" dot (mirrors the orange default dot) */
.v2-trips__dot--active {
  background: rgba(47, 191, 143, 0.95);
  box-shadow: 0 0 0 3px rgba(47, 191, 143, 0.18);
}
/* Imminent (<=3 days) lift; pulse only when motion is allowed */
.v2-trips__lead.is-soon { color: var(--orange); }
@media (prefers-reduced-motion: no-preference) {
  .v2-trips__lead.is-soon .v2-trips__dot { animation: v2-trips-pulse 2.4s ease-in-out infinite; }
}
@keyframes v2-trips-pulse {
  0%, 100% { box-shadow: 0 0 0 3px rgba(255, 104, 16, 0.16); }
  50%      { box-shadow: 0 0 0 5px rgba(255, 104, 16, 0.10); }
}

/* Signals row: readiness pill + loyalty stat (below rail, above chips) */
.v2-trips__signals { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; margin-top: 8px; }
.v2-trips__ready {
  display: inline-flex; align-items: center; gap: 5px;
  font-family: 'Geist', sans-serif; font-size: 0.73333rem; line-height: 1;
  border-radius: 9px; padding: 5px 9px; white-space: nowrap;
}
.v2-trips__ready-ic { width: 13px; height: 13px; flex: 0 0 auto; }
.v2-trips__ready--ok   { color: var(--atlas-deep); background: var(--atlas-paper); }
.v2-trips__ready--warn { color: var(--orange); background: var(--orange-paper); }
.v2-trips__earn { font-family: 'Geist Mono', monospace; font-size: 0.73333rem; color: rgba(255, 255, 255, 0.78); white-space: nowrap; }
.v2-trips__earn b { color: rgba(255, 255, 255, 0.96); font-variant-numeric: tabular-nums; }

/* Quiet hero Edit sibling, top-right (navy-on-navy; must not compete) */
.v2-trips__edit {
  position: absolute; top: 4px; right: 0;
  display: inline-flex; align-items: center; gap: 4px;
  font-family: 'Geist Mono', monospace; font-size: 0.66667rem; letter-spacing: 0.06em;
  color: rgba(255, 255, 255, 0.55); text-decoration: none; padding: 8px; border-radius: 8px;
}
.v2-trips__edit:hover { color: rgba(255, 255, 255, 0.92); }
.v2-trips__edit:focus-visible { outline: 2px solid var(--orange); outline-offset: 2px; }
.v2-trips__edit-ic { width: 12px; height: 12px; flex: 0 0 auto; }

/* Side-row readiness dot (text-backed via aria-label) */
.v2-trip-row__ready { width: 7px; height: 7px; border-radius: 999px; flex: 0 0 auto; margin-right: 6px; }
.v2-trip-row__ready.is-ok   { background: rgba(47, 191, 143, 0.75); }
.v2-trip-row__ready.is-warn { background: var(--orange); }

@media (pointer: coarse) {
  .v2-trips__edit { padding: 12px; }
}

/* Dashboard panel empty states + Atlas prompt chips */
.v2-empty-state {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 14px 0 6px;
}
.v2-empty-state__headline {
  font-family: 'Bricolage Grotesque', serif;
  font-size: 1.13333rem;
  line-height: 1.25;
  color: var(--ink-strong);
}
.v2-empty-state__body {
  margin: 0;
  font-size: 0.86667rem;
  line-height: 1.45;
  color: var(--ink-muted);
  max-width: 36ch;
}
.v2-empty-state__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
  margin-top: 4px;
}
.v2-empty-state__btn {
  min-height: 40px;
}
.v2-empty-state--dark .v2-empty-state__headline { color: rgba(255, 255, 255, 0.96); }
.v2-empty-state--dark .v2-empty-state__body { color: rgba(255, 255, 255, 0.62); }
.v2-empty-state--activity {
  padding: 18px 0 8px;
  border-top: 1px solid var(--hairline);
}
.v2-atlas-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 40px;
  padding: 0 12px;
  border-radius: 999px;
  border: 1px solid var(--hairline);
  background: var(--paper-shade);
  color: var(--ink-muted);
  font-size: 0.8rem;
  line-height: 1.2;
  cursor: pointer;
}
.v2-atlas-chip:hover { color: var(--ink-strong); border-color: rgba(14, 31, 59, 0.18); }
.v2-atlas-chip:focus-visible { outline: 2px solid var(--orange); outline-offset: 2px; }
.v2-atlas-chip__ic { width: 14px; height: 14px; color: var(--orange); }
.v2-empty-state--dark .v2-atlas-chip {
  background: rgba(255, 255, 255, 0.06);
  border-color: rgba(255, 255, 255, 0.14);
  color: rgba(255, 255, 255, 0.72);
}
.v2-empty-state--dark .v2-atlas-chip:hover { color: rgba(255, 255, 255, 0.95); }
.v2-lr__lg.has-img img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  border-radius: inherit;
}
.v2-subnav__right.is-refreshing .quick { opacity: 0.55; pointer-events: none; }

/* ─── Work queue counts + urgent preview (dashboard rec 4) ───────── */
.v2-wq-counts {
  display: flex;
  flex-wrap: nowrap;
  gap: 0 8px;
  margin: 0 0 12px;
  min-width: 0;
}
.v2-wq-count {
  flex: 0 0 auto;
  white-space: nowrap;
  font-family: 'Geist Mono', monospace;
  font-size: 0.6rem;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--ink-muted);
}
.v2-wq-count b { font-variant-numeric: tabular-nums; color: var(--ink-strong); }
.v2-wq-count.is-warn b { color: var(--ruby); }
.v2-wq-preview { display: grid; gap: 8px; margin-bottom: 10px; }
.v2-wq-row {
  display: grid;
  gap: 2px;
  padding: 10px 12px;
  border: 1px solid var(--hairline);
  border-radius: 12px;
  text-decoration: none;
  background: var(--paper-shade);
  transition: border-color 0.15s ease;
}
.v2-wq-row.is-urgent { border-color: rgba(255, 104, 16, 0.35); }
.v2-wq-row:hover { border-color: rgba(14, 31, 59, 0.18); }
.v2-wq-row__label { font-size: 0.86667rem; color: var(--ink-strong); line-height: 1.35; }
.v2-wq-row__meta {
  font-family: 'Geist Mono', monospace;
  font-size: 0.66667rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-faint);
}
.v2-lr--all-clear { font-size: 0.86667rem; color: var(--ink-muted); }

/* ─── Portfolio completeness strip (dashboard rec 5) ───────────── */
.v2-portfolio-strip {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px 18px;
  margin: 0 0 16px;
  padding: 12px 16px;
  border: 1px solid var(--hairline);
  border-radius: 14px;
  background: var(--paper);
}
.v2-portfolio-strip__title {
  display: block;
  font-family: 'Geist Mono', monospace;
  font-size: 0.66667rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-faint);
}
.v2-portfolio-strip__sync,
.v2-portfolio-strip__counts {
  display: block;
  margin-top: 4px;
  font-size: 0.86667rem;
  color: var(--ink-muted);
}
.v2-portfolio-strip__counts span + span::before { content: ' · '; }
.v2-portfolio-strip__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 14px;
  font-size: 0.86667rem;
}
.v2-portfolio-strip__actions a,
.v2-portfolio-strip__actions .v2-link-btn {
  color: var(--ink-strong);
  text-decoration: none;
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  font: inherit;
}
.v2-portfolio-strip__actions a:hover,
.v2-portfolio-strip__actions .v2-link-btn:hover { color: var(--orange); }

.v2-trips__state-badge {
  font-family: 'Geist Mono', monospace;
  font-size: 0.73333rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.72);
  margin-left: auto;
  margin-right: 8px;
}
.v2-trips__state-badge.is-warn { color: var(--orange); }
.v2-trips__state-badge.is-active { color: var(--orange); }
.v2-trips__head-cta {
  margin-left: auto;
  margin-right: 8px;
  white-space: nowrap;
}

.v2-trips__ready-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  width: 100%;
}
.v2-trips__ready-chip {
  font-family: 'Geist Mono', monospace;
  font-size: 0.66667rem;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  padding: 3px 8px;
  border-radius: 999px;
  border: 1px solid rgba(255, 255, 255, 0.14);
  color: rgba(255, 255, 255, 0.78);
}
.v2-trips__ready-chip.is-ok {
  border-color: rgba(46, 196, 182, 0.35);
  color: #8fe8de;
  background: rgba(46, 196, 182, 0.08);
}
.v2-trips__ready-chip.is-warn {
  border-color: rgba(255, 104, 16, 0.35);
  color: #ffb48a;
  background: rgba(255, 104, 16, 0.1);
}
.v2-trip-hero .v2-trips__ready-chip {
  border-color: rgba(255, 255, 255, 0.18);
}
.v2-trips__grouped-note,
.v2-trips__panel-cta {
  grid-column: 1 / -1;
}
.v2-trips__grouped-note {
  margin: 0 0 8px;
  font-size: 0.8rem;
  color: rgba(255, 255, 255, 0.62);
}
.v2-trips__panel-cta {
  margin: 10px 0 0;
}
.v2-trips__panel-cta .v2-btn--s {
  font-size: 0.8rem;
  padding: 7px 12px;
}

/* ─── Loyalty forecast fixes affordance (dashboard rec 3) ────────── */
.v2-lr__fc-after {
  margin-top: 4px;
  font-size: 0.8rem;
  color: rgba(255, 255, 255, 0.78);
  font-variant-numeric: tabular-nums;
}
.v2-lr__fc-conf {
  margin-top: 2px;
  font-size: 0.73333rem;
  color: rgba(255, 255, 255, 0.55);
}
.v2-lr__fc-fix {
  margin-top: 6px;
  padding: 0;
  border: 0;
  background: none;
  color: var(--orange);
  font-size: 0.8rem;
  font-weight: 600;
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 2px;
}
.v2-lr__fc-fix:hover { color: #ff8533; }

.v2-sf-summary__line { margin: 0 0 14px; font-size: 0.93333rem; line-height: 1.5; color: var(--ink-strong); }
.v2-sf-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; }
.v2-sf-row {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 4px 12px;
  padding: 12px;
  border: 1px solid var(--hairline);
  border-radius: 12px;
}
.v2-sf-row__label { font-size: 0.86667rem; color: var(--ink-strong); grid-column: 1; }
.v2-sf-row__meta { font-size: 0.73333rem; color: var(--ink-faint); grid-column: 1; }
.v2-sf-row__val { font-variant-numeric: tabular-nums; font-size: 0.86667rem; color: var(--ink-strong); align-self: center; }
.v2-sf-est { font-size: 0.66667rem; color: var(--ink-faint); text-transform: uppercase; }
.v2-sf-loading { display: flex; align-items: center; gap: 10px; color: var(--ink-muted); font-size: 0.86667rem; }
.v2-sf-loading[hidden] { display: none !important; }

.v2-pt-mode {
  display: flex;
  gap: 8px;
  margin-bottom: 16px;
}
.v2-pt-mode__btn {
  flex: 1;
  padding: 10px 12px;
  border: 1px solid var(--hairline);
  border-radius: 12px;
  background: var(--paper-shade);
  color: var(--ink-muted);
  font-size: 0.86667rem;
  cursor: pointer;
}
.v2-pt-mode__btn.is-active {
  border-color: rgba(255, 104, 16, 0.45);
  color: var(--ink-strong);
  background: rgba(255, 104, 16, 0.08);
}
.v2-pt-assemble__lede { margin: 0 0 12px; font-size: 0.86667rem; color: var(--ink-muted); line-height: 1.45; }
.v2-pt-assemble__section { margin-bottom: 14px; }
.v2-pt-assemble__section h5 { margin: 0 0 8px; font-size: 0.8rem; letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink-faint); }
.v2-pt-assemble__pick {
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: 8px 10px;
  align-items: center;
  padding: 10px 0;
  border-bottom: 1px solid var(--hairline);
  font-size: 0.86667rem;
}
.v2-pt-assemble__pick small { color: var(--ink-faint); font-family: 'Geist Mono', monospace; font-size: 0.66667rem; }

@media (max-width: 767px) {
  .v2-empty-state__actions { flex-direction: column; align-items: stretch; }
  .v2-empty-state__btn,
  .v2-atlas-chip { width: 100%; justify-content: center; }
}

/* PI-03: requalification forecast hero atop the demo dashboard (demo_renderer.php).
   Token-only so the css-hex-guard stays green. */
.mm-demo-fc {
  border: 1px solid var(--hairline);
  border-left: 4px solid var(--pace-on-track);
  border-radius: 14px;
  padding: 18px 20px;
  background: var(--paper-soft);
  margin: 4px 0 20px;
}
.mm-demo-fc--short { border-left-color: var(--pace-ruby); }
.mm-demo-fc--pace { border-left-color: var(--pace-amber); }
.mm-demo-fc__eyebrow { font-size: 0.73333rem; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--orange); }
.mm-demo-fc__q { margin: 6px 0 10px; font-family: 'Bricolage Grotesque', serif; font-size: clamp(1.26667rem, 3vw, 1.6rem); line-height: 1.2; color: var(--ink-strong); }
.mm-demo-fc__verdict { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.mm-demo-fc__verdict strong { font-size: 1rem; color: var(--ink-strong); }
.mm-demo-fc__chip { font-size: 0.8rem; font-weight: 700; padding: 3px 10px; border-radius: 999px; color: var(--paper); background: var(--pace-on-track); }
.mm-demo-fc--short .mm-demo-fc__chip { background: var(--pace-ruby); }
.mm-demo-fc--pace .mm-demo-fc__chip { background: var(--pace-amber); }
.mm-demo-fc__detail { margin: 8px 0 12px; font-size: 0.86667rem; line-height: 1.5; color: var(--ink-muted); max-width: 64ch; }
.mm-demo-fc__bar { display: flex; width: 100%; height: 8px; border-radius: 999px; overflow: hidden; background: var(--paper-shade); }
.mm-demo-fc__bar-earned { height: 100%; background: var(--pace-on-track); }
.mm-demo-fc__bar-planned { height: 100%; background: var(--pace-on-track); opacity: 0.5; }
.mm-demo-fc--short .mm-demo-fc__bar-earned { background: var(--pace-ruby); }
.mm-demo-fc__caption { margin: 8px 0 0; font-size: 0.8rem; color: var(--ink-muted); }

/* Live Flight Experience (Phase E) — dashboard glance line on the .v2-fhero
   "next departure" hero. Lives here (dashboard.css is always loaded; the
   dashboard skips flight_live.css). Status colour is paired with a text label. */
.v2-fhero__live { display: flex; align-items: center; gap: 10px; margin-top: 10px; flex-wrap: wrap; }
.v2-fhero__live-chip { font-size: 0.8rem; }
.v2-fhero__live-meta { font-size: 0.86667rem; color: var(--ink-muted); }

/* Live Flight Experience — compact "what's happening now" banner inside the
   Trips panel. Navy treatment matches the Loyalty panel + the work-queue heroes.
   One tap-target into the trip's live card. Status colour is paired with a text
   label + a distinct icon (no colour-only signalling). Line 1 = flight + status
   pill (right); line 2 = the stage-relevant fields (gate/terminal/belt/time). */
.v2-flive-mini {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 10px 13px;
  margin-bottom: 11px;
  border: 0;
  border-left: 3px solid var(--pace-on-track);
  border-radius: 13px;
  background: linear-gradient(180deg, var(--navy-soft) 0%, var(--navy) 100%);
  color: var(--paper-soft);
  text-decoration: none;
}
.v2-flive-mini--at { border-left-color: var(--pace-amber); }
.v2-flive-mini--be { border-left-color: var(--pace-ruby); }
.v2-flive-mini:hover { filter: brightness(1.07); }
.v2-flive-mini:focus-visible { outline: 2px solid var(--orange); outline-offset: 2px; }
.v2-flive-mini__ic {
  flex: 0 0 auto;
  width: 18px;
  height: 18px;
  margin-top: 1px;
  color: rgba(255, 255, 255, 0.58);
}
.v2-flive-mini__ic svg { width: 100%; height: 100%; display: block; }
.v2-flive-mini__main { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.v2-flive-mini__l1 { display: flex; align-items: center; gap: 8px; }
.v2-flive-mini__title {
  flex: 1 1 auto;
  min-width: 0;
  font-family: 'Geist', sans-serif;
  font-weight: 600;
  font-size: 0.86667rem;
  color: var(--paper-soft);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.v2-flive-mini__chip { flex: 0 0 auto; font-size: 0.73333rem; }
.v2-flive-mini__l2 {
  display: flex;
  align-items: baseline;
  gap: 8px;
  flex-wrap: wrap;
  font-size: 0.8rem;
}
.v2-flive-mini__meta {
  min-width: 0;
  color: rgba(255, 255, 255, 0.70);
  font-variant-numeric: tabular-nums;
  overflow-wrap: anywhere;
}
.v2-flive-mini__action { color: var(--orange-soft); font-weight: 600; }
.v2-flive-mini__more { margin-left: auto; color: rgba(255, 255, 255, 0.55); white-space: nowrap; }
.v2-flive-mini__go { flex: 0 0 auto; width: 16px; height: 16px; align-self: center; color: rgba(255, 255, 255, 0.45); }
.v2-flive-mini__go svg { width: 100%; height: 100%; display: block; }
/* Lead as its own full-width row at the top of the 2-column Trips panel grid
   (grid gap handles the spacing, so drop the standalone margin). */
.v2-trips__band > .v2-flive-mini { grid-column: 1 / -1; margin-bottom: 0; }

/* ─── Calm restyle: light next-flight / next-stay / live-flight heroes (were navy) ───
   The Needs-attention "Next departure" + "Next stay" cards and the Trips live-flight
   banner all dropped their navy fill for a light card; spectrum left-accent + the
   orange position dot stay as the only colour. */
.v2-fhero,
.v2-stay-up {
  background: var(--paper-soft);
  border: 1px solid var(--hairline);
}
.v2-fhero__lab,
.v2-stay-up__lab,
.v2-stay-up__dk { color: var(--ink-faint); }
.v2-fhero__code,
.v2-fhero__big,
.v2-stay-up__name,
.v2-stay-up__dv { color: var(--ink-strong); }
.v2-fhero__time,
.v2-fhero__mid,
.v2-fhero__sub,
.v2-stay-up__addr { color: var(--ink-muted); }
.v2-fhero--empty .v2-fhero__big,
.v2-stay-up--empty .v2-stay-up__name { color: var(--ink-muted); }
.v2-fhero__arc svg path { stroke: var(--hairline-strong); }
.v2-stay-up__dates { border-top-color: var(--hairline); }
.v2-flive-mini {
  background: var(--paper-soft);
  border: 1px solid var(--hairline);
  border-left: 3px solid var(--pace-secure);
  color: var(--ink);
}
.v2-flive-mini--at { border-left-color: var(--pace-caution); }
.v2-flive-mini--be { border-left-color: var(--pace-risk); }
.v2-flive-mini:hover { filter: none; border-color: var(--hairline-strong); }
.v2-flive-mini__ic { color: var(--ink-muted); }
.v2-flive-mini__title { color: var(--ink-strong); }
.v2-flive-mini__meta { color: var(--ink-muted); }
.v2-flive-mini__action { color: var(--orange-deep); }
.v2-flive-mini__more { color: var(--ink-faint); }
.v2-flive-mini__go { color: var(--ink-faint); }

/* ── Unified Trips (Direction B) ───────────────────────────────────────── */
.v2-trips__band--unified { display: block; padding: 0; }
.v2-trips-b {
  display: grid;
  grid-template-columns: minmax(0, 1.55fr) minmax(180px, 1fr);
  gap: 18px;
  align-items: start;
}
.v2-trips-b__detail { min-width: 0; }
.v2-trips-b__panel[hidden] { display: none; }
.v2-trips-b__ttl {
  font-family: var(--font-disp, 'Bricolage Grotesque', sans-serif);
  font-weight: 700; font-size: 1.46667rem; color: var(--navy); margin: 0; line-height: 1.12;
}
.v2-trips-b__ttl-wrap { margin: 0; }
.v2-trips-b__ttl--link {
  display: inline;
  color: inherit;
  text-decoration: none;
  cursor: pointer;
  border-radius: 4px;
  transition: color .15s ease;
}
.v2-trips-b__ttl--link:hover,
.v2-trips-b__ttl--link:focus-visible {
  color: var(--orange-deep);
  outline: none;
  box-shadow: 0 0 0 2px var(--amber);
}
.v2-trips-b__lead {
  font-family: var(--font-mono, 'Geist Mono', monospace);
  font-size: 0.66667rem; letter-spacing: .09em; text-transform: uppercase;
  color: var(--ink-muted); margin: 6px 0 0;
}
.v2-trips-b__signals { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin: 13px 0 2px; }
.v2-trips-b__ready, .v2-trips-b__chip {
  font-family: var(--font-mono, monospace); font-size: 0.66667rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: .05em; padding: 4px 10px; border-radius: 999px;
}
.v2-trips-b__ready.is-ok { color: var(--atlas-deep); background: var(--atlas-paper); }
.v2-trips-b__chip.is-warn { color: var(--orange-deep); background: var(--amber); }
.v2-trips-b__chip.is-caution { color: var(--orange-deep); background: var(--amber); }
.v2-trips-b__earn { font-size: 0.83333rem; color: var(--ink-strong); }
.v2-trips-b__fold {
  font-family: var(--font-mono, monospace); font-size: 0.66667rem; color: var(--ink-faint);
  text-transform: uppercase; letter-spacing: .06em; margin: 16px 0 2px;
  display: flex; align-items: center; gap: 7px;
}
.v2-trips-b__fold::before { content: ""; width: 12px; height: 12px; border-radius: 999px; background: var(--ink-faint); opacity: .5; }
.v2-trips-b__tl { margin: 12px 0 4px; }
/* Long itineraries: "Next up" stays pinned while the remaining stops scroll
   inside the panel, so a 10+ stop trip never blows out the dashboard height. */
.v2-trips-b__tl-rest {
  max-height: 320px;
  overflow-y: auto;
  /* Timeline dots sit at left:-7px; pad in then pull back so the scroll box
     never clips them while the spine stays aligned with the rest of the panel. */
  padding-left: 8px;
  margin-left: -8px;
  scrollbar-width: thin;
  scrollbar-color: var(--hairline-strong) transparent;
}
.v2-trips-b__tl-rest::-webkit-scrollbar { width: 6px; }
.v2-trips-b__tl-rest::-webkit-scrollbar-thumb { background: var(--hairline-strong); border-radius: 999px; }
.v2-trips-b__tl-rest::-webkit-scrollbar-track { background: transparent; }
.v2-trips-b__item {
  position: relative; padding: 10px 0 10px 26px; border-left: 2px solid var(--hairline);
}
.v2-trips-b__item:last-child { border-left-color: transparent; }
.v2-trips-b__item::before {
  content: ""; position: absolute; left: -7px; top: 14px; width: 12px; height: 12px;
  border-radius: 999px; background: var(--card); border: 2px solid var(--hairline-strong);
}
.v2-trips-b__item--next {
  background: var(--paper-soft); border: 1px solid var(--hairline);
  border-left: 3px solid var(--orange); border-radius: 0 13px 13px 0;
  margin-left: -2px; padding: 14px 16px 15px 26px;
}
.v2-trips-b__badge { display: flex; align-items: center; gap: 8px; margin-bottom: 7px; }
.v2-trips-b__nb {
  font-family: var(--font-mono, monospace); font-size: 0.56667rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: .1em; color: var(--orange-deep);
}
.v2-trips-b__live {
  display: inline-flex; align-items: center; gap: 5px; font-family: var(--font-mono, monospace);
  font-size: 0.56667rem; font-weight: 600; text-transform: uppercase; letter-spacing: .08em;
  color: var(--pace-ruby); background: var(--pace-risk-paper, var(--amber)); padding: 3px 8px; border-radius: 999px;
}
.v2-trips-b__pulse { width: 6px; height: 6px; border-radius: 999px; background: var(--pace-ruby); animation: v2bpulse 1.4s infinite; }
@keyframes v2bpulse { 0%, 100% { opacity: 1; } 50% { opacity: .3; } }
.v2-trips-b__item-t { font-weight: 600; font-size: 0.86667rem; color: var(--ink-strong); }
.v2-trips-b__item--next .v2-trips-b__item-t { font-weight: 700; font-size: 1rem; color: var(--navy); }
.v2-trips-b__item-t--link {
  display: block;
  width: 100%;
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  text-align: left;
  cursor: pointer;
  border-radius: 4px;
  transition: color .15s ease;
}
.v2-trips-b__item-t--link:hover,
.v2-trips-b__item-t--link:focus-visible {
  color: var(--orange-deep);
  outline: none;
  box-shadow: 0 0 0 2px var(--amber);
}
.v2-trips-b__item-w {
  font-family: var(--font-mono, monospace); font-size: 0.66667rem; color: var(--ink-faint);
  margin-top: 2px; text-transform: uppercase; letter-spacing: .04em;
}
.v2-trips-b__item--next .v2-trips-b__item-w { font-size: 0.86667rem; color: var(--ink-strong); text-transform: none; letter-spacing: 0; }
.v2-trips-b__item-sub { font-size: 0.76667rem; color: var(--ink-muted); margin-top: 3px; }
.v2-trips-b__liveline {
  display: flex; align-items: center; gap: 8px; margin: 9px 0 2px; font-size: 0.83333rem;
  color: var(--ink-strong); background: var(--card); border: 1px solid var(--hairline);
  border-radius: 9px; padding: 7px 11px;
}
.v2-trips-b__liveic { width: 15px; height: 15px; color: var(--pace-ruby); }
.v2-trips-b__notmon { font-size: 0.73333rem; color: var(--ink-faint); margin-top: 9px; }
/* Baseline ops line (canonical data, pre-live): neutral icon, reuses liveline box. */
.v2-trips-b__opsline .v2-trips-b__liveic { color: var(--ink-faint); }
/* Proactive "what changed" pill, rendered under the ops/live line. */
.v2-trips-b__change {
  display: inline-flex; align-items: center; margin-top: 7px;
  padding: 2px 10px; border-radius: 999px;
  font-family: 'Geist', sans-serif; font-size: 0.73333rem; font-weight: 600; line-height: 1.7;
}
.v2-trips-b__change.is-amber {
  color: var(--pace-amber);
  background: color-mix(in srgb, var(--pace-amber) 14%, transparent);
  border: 1px solid color-mix(in srgb, var(--pace-amber) 34%, transparent);
}
.v2-trips-b__change.is-ruby {
  color: var(--pace-ruby);
  background: color-mix(in srgb, var(--pace-ruby) 14%, transparent);
  border: 1px solid color-mix(in srgb, var(--pace-ruby) 34%, transparent);
}
.v2-trips-b__ess { display: flex; flex-wrap: wrap; gap: 7px; margin-top: 10px; }
.v2-trips-b__ess-pill {
  font-family: var(--font-mono, monospace); font-size: 0.7rem; font-weight: 500; color: var(--ink-strong);
  background: var(--card); border: 1px solid var(--hairline); border-radius: 8px; padding: 5px 9px;
  display: inline-flex; gap: 5px; align-items: center;
}
.v2-trips-b__ess-pill.is-add { color: var(--orange-deep); border-color: var(--amber); background: var(--amber); }
.v2-trips-b__ess-k { color: var(--ink-faint); font-size: 0.6rem; text-transform: uppercase; letter-spacing: .05em; }
.v2-trips-b__acts { display: flex; gap: 8px; margin-top: 12px; }
.v2-trips-b__list { display: flex; flex-direction: column; gap: 6px; }
.v2-trips-b__row { width: 100%; text-align: left; cursor: pointer; background: transparent; border: 1px solid transparent; }
.v2-trips-b__row.is-shown { background: var(--paper-soft); border-color: var(--hairline-soft); }
.v2-trips-b__row .v2-trip-row__name.is-dim { color: var(--ink-faint); }
.v2-trip-row__calic { width: 18px; height: 18px; color: var(--ink-muted); }
.v2-trips-b__overflow {
  display: flex; align-items: center; gap: 10px; margin-top: 10px; padding: 10px 12px;
  border: 1px solid var(--pace-caution-border); border-radius: 10px;
  background: var(--pace-caution-paper); text-decoration: none;
  transition: border-color .15s ease;
}
.v2-trips-b__overflow:hover { border-color: var(--pace-caution); }
.v2-trips-b__overflow-ic { display: inline-flex; flex: 0 0 auto; color: var(--pace-caution); }
.v2-trips-b__overflow-svg { width: 16px; height: 16px; }
.v2-trips-b__overflow-t { flex: 1 1 auto; font-size: 0.86667rem; font-weight: 600; color: var(--ink); }
.v2-trips-b__overflow-go {
  flex: 0 0 auto; font-family: var(--font-mono, monospace); font-size: 0.66667rem;
  text-transform: uppercase; letter-spacing: .06em; color: var(--pace-caution);
}
@media (max-width: 720px) {
  .v2-trips-b { grid-template-columns: 1fr; }
}
@media (prefers-reduced-motion: reduce) {
  .v2-trips-b__pulse { animation: none; }
}

/* Multi-flight live stack (Task 3) */
.v2-flive-stack{display:flex;flex-direction:column;}
.v2-flive-stack__body{display:flex;flex-direction:column;}
.v2-flive-stack__h{display:flex;align-items:center;justify-content:space-between;gap:10px;font-size: 0.86667rem;color:var(--v2-ink-3,#5A6B85);font-weight:500;margin-bottom:12px;}
.v2-flive-stack__live{display:inline-flex;align-items:center;gap:6px;font-size: 0.8rem;font-weight:500;color:#0F6E56;background:#E1F5EE;padding:4px 10px;border-radius:999px;}
.v2-flive-stack__dot{width:7px;height:7px;border-radius:50%;background:#1D9E75;animation:v2FlivePulse 1.6s ease-in-out infinite;}
@keyframes v2FlivePulse{0%,100%{opacity:1}50%{opacity:.3}}
.v2-flive-stack__exp{display:flex;background:#fff;border:.5px solid #DDE3EE;border-radius:12px;margin-bottom:10px;overflow:hidden;}
.v2-flive-stack__rail{width:4px;flex:none;background:#9AA6BC;}
.v2-flive-stack__exp--boarding .v2-flive-stack__rail{background:#FF6810;}
.v2-flive-stack__exp--landed .v2-flive-stack__rail{background:#1D9E75;}
.v2-flive-stack__exp--inair .v2-flive-stack__rail{background:#378ADD;}
.v2-flive-stack__exp--delayed .v2-flive-stack__rail,.v2-flive-stack__exp--disrupted .v2-flive-stack__rail{background:#E24B4A;}
.v2-flive-stack__exp-b{flex:1;min-width:0;padding:14px 16px;}
.v2-flive-stack__row1{display:flex;align-items:center;justify-content:space-between;gap:10px;flex-wrap:wrap;}
.v2-flive-stack__code{font-size: 1rem;font-weight:500;color:#0E1F3B;}
.v2-flive-stack__route{font-size: 0.86667rem;color:#6B7A93;margin-left:8px;}
.v2-flive-stack__pill{font-size: 0.8rem;font-weight:500;padding:4px 11px;border-radius:999px;white-space:nowrap;}
.v2-flive-stack__pill--boarding{background:#FF6810;color:#fff;}
.v2-flive-stack__pill--landed{background:#CFEDE2;color:#0F6E56;}
.v2-flive-stack__pill--inair{background:#E6F1FB;color:#185FA5;}
.v2-flive-stack__pill--delayed,.v2-flive-stack__pill--disrupted{background:#FCEBEB;color:#A32D2D;}
.v2-flive-stack__pill--scheduled{background:#F0F3F8;color:#33507F;}
.v2-flive-stack__meta{font-size: 0.86667rem;color:#46566F;margin-top:9px;display:flex;flex-wrap:wrap;gap:4px 16px;}
.v2-flive-stack__badge{display:inline-flex;align-items:center;gap:6px;font-size: 0.8rem;font-weight:500;color:#B5480F;background:#FFE8D6;padding:5px 10px;border-radius:8px;margin-top:10px;}
.v2-flive-stack__count{font-size: 0.83333rem;color:#C24A0F;font-weight:500;margin-top:9px;}
.v2-flive-stack__sep{font-size: 0.76667rem;color:#8593AC;font-weight:500;margin:6px 2px 9px;}
.v2-flive-stack__cmp{display:flex;align-items:center;gap:12px;background:#fff;border:.5px solid #E7EBF2;border-radius:12px;padding:11px 14px;margin-bottom:8px;}
.v2-flive-stack__cmp-b{flex:1;min-width:0;}
.v2-flive-stack__cmp-t{font-size: 0.9rem;font-weight:500;color:#0E1F3B;}
.v2-flive-stack__cmp-when{font-size: 0.8rem;color:#8593AC;font-weight:500;white-space:nowrap;flex:none;}
@media (prefers-reduced-motion: reduce) {
  .v2-flive-stack__dot { animation: none; }
}
