/* KaunsaCard - The Thread, restyled as a modern product. 22 Sep 2026.
   Visual system: cool grey ground, white surfaces, soft elevation,
   Space Grotesk display + Inter UI + JetBrains Mono figures.
   Violet is the accent and the live step. Emerald is money gained and a
   step behind you. Red is money lost. The answer panel is the darkest
   thing on the screen - the one moment the product goes dark.
   Motion rule: things ARRIVE, they never pop. Money never moves faster
   than you can read it. */

:root {
  --ground: #F7F8FA;
  --surface: #FFFFFF;
  --raise: #F2F4F7;
  --line: #E4E7EC;
  /* The border a bordered thing takes on hover. It was the same raw hex in six
     places and had no name, so a new page copying the look also copied a rule
     violation. Named here so there is one to reach for. */
  --line-hover: #C8CDD6;
  --deep: #17181D;
  --body: #101828;
  --dim: #475467;
  --faint: #667085;
  --accent: #635BFF;
  --accent-deep: #5148E5;
  --accent-tint: rgba(99, 91, 255, .09);
  --mint: #059669;
  --mint-tint: rgba(5, 150, 105, .1);
  --air: #F1F2F6;
  --air-line: #DCDEE6;
  --air-ink: #475467;

  --ink: #0F1115;
  --ink-2: #171A21;
  --glow: rgba(99, 91, 255, .12);
  --clay: #D92D20;
  --spine: #D0D5DD;
  --night: #1E1B34;
  --trip-dim: #A9A3E8;   /* the muted label on the dark trip card */

  /* One display face, one UI face, one face for figures. */
  --display: 'Space Grotesk', 'Inter', system-ui, sans-serif;
  --sans: 'Inter', system-ui, sans-serif;
  --mono: 'JetBrains Mono', ui-monospace, monospace;

  /* warnings and exclusions carry meaning through a left rule, never a fill */
  --excl-bg: #FFFFFF; --excl-line: #F3C4BD;
  --warn-bg: #FFFFFF; --warn-line: #F3C4BD; --warn-ink: #B42318;
  --cash-bg: #FFFFFF; --cash-line: #A6E1C8;
  --hover: #F9FAFB;
  --shadow-soft: 0 1px 2px rgba(16, 24, 40, .05);
  --shadow-md: 0 4px 12px -4px rgba(16, 24, 40, .12);
  --shadow-lg: 0 12px 28px -10px rgba(16, 24, 40, .18);

  /* inside the ink panel */
  --ans-pos: #4ADE80; --ans-eyebrow: #A5A0F5; --ans-neg: #F87171;
  --ans-dim: #98A1B2; --ans-strong: #F2F4F7; --ans-faint: #858FA3;
  --ans-rule: rgba(255,255,255,.08); --ans-btn: rgba(255,255,255,.16);
  --ans-solid: #fff; --ans-solid-ink: #0F1115;
  --cap-ink: #F2C473; --cap-bg: rgba(242,196,115,.1); --cap-line: rgba(242,196,115,.32);
  --trip-from: #2B2560; --trip-to: #141226;

  /* Corners: modern, still architectural. Circles are reserved for step nodes
     and status dots, where roundness carries meaning. */
  --r-lg: 12px;  /* panels, the answer */
  /* ---- TYPE SCALE ----------------------------------------------------
     Eight rungs, each with a job. Before this the product rendered text at
     eighteen different sizes, including half-steps a pixel apart - `note` at
     12.5 and `gate-free` at 12 doing the same job, `sub` at 13.5 in one place
     and 14.5 in another. Invisible individually, and collectively why the
     pages read as slightly uneven. Pick a rung by ROLE, never by eye. */
  --t-micro: 10.5px;   /* mono eyebrows, unit labels, hints */
  --t-xs:    11.5px;   /* sub-values under a number, captions */
  --t-sm:    12.5px;   /* notes, row meta, chips, source lines */
  --t-base:    14px;   /* body copy, row names, value cells */
  --t-lead:    15px;   /* emphasised body, gate headline */
  --t-h3:      17px;   /* section heading inside a page */
  --t-h2:      21px;   /* block heading */
  --t-display: clamp(23px, 2.2vw, 29px);  /* a tool's page headline */
  --t-stat:    25px;   /* one large figure alone: a balance, a trip's worth */
  --r-md: 8px;   /* inputs, buttons */
  --r-sm: 6px;   /* chips, small marks */

  --ease-out: cubic-bezier(.16, 1, .3, 1);
  --ease-soft: cubic-bezier(.32, .72, 0, 1);
  --t: 560ms;

  --railh: 58px;
}
* { box-sizing: border-box; margin: 0; padding: 0 }
html { scroll-behavior: smooth }
body {
  background: var(--ground); color: var(--body); font-family: var(--sans);
  -webkit-font-smoothing: antialiased; overflow-x: hidden;
}
.num { font-family: var(--mono); font-variant-numeric: tabular-nums }
button { font-family: inherit; cursor: pointer }
::selection { background: var(--accent-tint) }
.rise {
  transition: opacity var(--t) var(--ease-out), transform var(--t) var(--ease-out), filter var(--t) var(--ease-out);
  transition-delay: calc(var(--i, 0) * 60ms);
}
.rise.pre { opacity: 0; transform: translateY(14px); filter: blur(6px); transition: none }
@media (prefers-reduced-motion: reduce) {
  :root { --t: 1ms }
  .rise { filter: none; transform: none }
  html { scroll-behavior: auto }
}
/* ================= RAIL ================= */
.rail {
  position: sticky; top: 0; z-index: 40; height: var(--railh);
  display: flex; align-items: center; gap: 16px; padding: 0 28px;
  background: color-mix(in srgb, var(--ground) 82%, transparent); backdrop-filter: saturate(170%) blur(16px);
  border-bottom: 1px solid transparent; transition: border-color 300ms linear;
}
.rail.stuck { border-bottom-color: var(--line) }
.logo { font-family: var(--display); font-size: var(--t-h3); font-weight: 700; letter-spacing: -.02em; color: var(--body); text-decoration: none }
.logo i { color: var(--accent); font-style: normal; display: inline-block }
.logo.ask i { animation: tilt 2.4s var(--ease-soft) }
@keyframes tilt {
  0%,100% { transform: rotate(0) } 12% { transform: rotate(-16deg) translateY(-1px) }
  26% { transform: rotate(10deg) } 38% { transform: rotate(0) }
}
.rail .grow { flex: 1 }
.railcards { display: flex }
.railcards .m {
  width: 18px; height: 18px; border-radius: 4px; margin-left: -7px;
  border: 2px solid var(--ground); box-shadow: var(--shadow-soft);
  animation: dealIn 520ms var(--ease-out) backwards;
}
.railcards .m:first-child { margin-left: 0 }
@keyframes dealIn { from { opacity: 0; transform: translateY(-7px) rotate(-8deg) scale(.8) } }
.railpts { font-family: var(--mono); font-size: var(--t-sm); color: var(--dim); text-decoration: none }
.railpts:hover { color: var(--body) }
.railpts span { color: var(--faint); font-size: var(--t-xs) }
.railbtn {
  border: 1px solid var(--line); background: var(--surface); color: var(--dim);
  border-radius: var(--r-md); padding: 7px 14px; font-size: var(--t-sm); font-weight: 600;
  box-shadow: var(--shadow-soft); transition: all 200ms var(--ease-out);
}
.railbtn:hover { border-color: var(--line-hover); color: var(--body) }
.railbtn.go { background: var(--accent); border-color: var(--accent); color: #fff; box-shadow: 0 1px 3px rgba(99,91,255,.35) }
/* ================= SHELL: stepper + stage ================= */
.shell {
  max-width: 1040px; margin: 0 auto; padding: 30px 28px 120px;
}
/* A page registered with `wide: true` (a console of tables, not prose) gets
   more measure. Everything inside still follows the same primitives. */
body.page-wide .shell, body.page-wide .foot { max-width: 1320px }
/* --- the thread, a top stepper --- */
.spine {
  position: relative; display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px;
  padding: 0 6px; margin-bottom: 32px;
}
.spine::before {
  content: ''; position: absolute; left: 15px; right: 15px; top: 15px; height: 2px;
  background: var(--spine); border-radius: 2px;
  transform-origin: left; animation: drawSpine 1000ms var(--ease-soft) 200ms backwards;
}
@keyframes drawSpine { from { transform: scaleX(0) } }
.spine .done-run {
  position: absolute; left: 15px; top: 15px; height: 2px; border-radius: 2px;
  width: var(--done, 0px);
  background: linear-gradient(90deg, var(--accent), var(--mint));
  transition: width 900ms var(--ease-soft);
}
.sstep { position: relative; display: flex; flex-direction: column; align-items: center; text-align: center; padding: 0 12px; cursor: default; min-width: 0 }
.sstep.can { cursor: pointer }
.snode {
  position: relative; z-index: 1; width: 30px; height: 30px; border-radius: 50%;
  display: grid; place-items: center; font-family: var(--mono); font-size: var(--t-sm);
  background: var(--ground); border: 2px solid var(--spine); color: var(--faint);
  transition: all 460ms var(--ease-out);
}
.sstep.live .snode {
  background: var(--surface); border-color: var(--accent); color: var(--accent);
  box-shadow: 0 0 0 4px var(--glow);
}
.sstep.live .snode::after {
  content: ''; position: absolute; inset: -2px; border-radius: 50%;
  border: 2px solid var(--accent); opacity: 0; animation: pulse 3.4s var(--ease-out) infinite;
}
@keyframes pulse { 0% { opacity: .5; transform: scale(1) } 40%,100% { opacity: 0; transform: scale(1.75) } }
.sstep.done .snode { background: var(--accent); border-color: var(--accent); color: #fff }
.sstep.done .snode .n, .sstep.live .snode svg, .sstep .snode svg { display: none }
.sstep.done .snode svg { display: block; width: 15px; height: 15px }
.snode svg path {
  fill: none; stroke: #fff; stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round;
  stroke-dasharray: 22; stroke-dashoffset: 22; animation: tick 460ms var(--ease-out) 120ms forwards;
}
@keyframes tick { to { stroke-dashoffset: 0 } }
.sstep h4 .sm { display: none }
.stxt { margin-top: 9px }
.sstep h4 {
  font-family: var(--sans); font-size: var(--t-sm); font-weight: 600; letter-spacing: -.005em;
  color: var(--faint); transition: color 400ms var(--ease-out); white-space: nowrap;
}
.sstep.live h4, .sstep.done h4 { color: var(--body) }
.sstep p { font-size: var(--t-xs); color: var(--faint); margin-top: 3px; line-height: 1.45; max-width: 210px }
.sstep .tag {
  font-family: var(--mono); font-size: var(--t-micro); color: var(--mint); margin-top: 4px; display: block;
}
.sstep.can:hover h4 { color: var(--accent) }
/* ================= STAGE: one view at a time ================= */
.stage { position: relative; min-height: 420px }
.view { transition: opacity 340ms var(--ease-out), transform 340ms var(--ease-out), filter 340ms var(--ease-out) }
.view.out { opacity: 0; transform: translateX(-18px); filter: blur(5px); pointer-events: none }
.view.pre { opacity: 0; transform: translateX(22px); filter: blur(5px) }
.vhead { margin-bottom: 22px }
/* A TOOL's header. The four-step thread earns a display headline; a calculator
   does not, and a 44px title over three lines of preamble pushed the control
   the reader came for most of the way down the first screen. */
.vhead.vhead-tool { margin-bottom: 14px }
.vhead.vhead-tool h2 { font-size: clamp(23px, 2.2vw, 29px) }
.vhead.vhead-tool .sub { margin-top: 6px; font-size: var(--t-base); max-width: 72ch }
.vhead .eyebrow {
  font-family: var(--mono); font-size: var(--t-micro); letter-spacing: .1em; text-transform: uppercase;
  color: var(--faint); font-weight: 500;
}
.vhead h2 {
  font-family: var(--display); font-size: clamp(28px, 3.5vw, 40px); font-weight: 700;
  letter-spacing: -.03em; line-height: 1.1; margin-top: 10px;
}
/* Space Grotesk has no italic - the accent word is colour only */
.vhead h2 em { font-style: normal; color: var(--accent) }
.vhead .sub { margin-top: 11px; color: var(--dim); font-size: var(--t-base); line-height: 1.55; max-width: 62ch }
/* ================= CARD SURFACE ================= */
.panel {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg);
  box-shadow: var(--shadow-soft);
}
.panel.lit { border-color: var(--accent); border-left: 3px solid var(--accent) }
.panel-b { padding: 22px 24px }
/* The compact surface. A control strip is not a content card, and two pages
   had each invented the same tighter padding privately. One name, so a third
   page does not invent a third value. */
.panel-b.tight { padding: 16px 18px }
/* ================= card chips ================= */
.chips { display: flex; flex-wrap: wrap; gap: 7px }
.chip {
  /* a <button> centres its text; a chip whose label wraps to two lines then
     goes ragged in the middle of a left-aligned list */
  display: inline-flex; align-items: center; gap: 7px; text-align: left;
  border: 1px solid var(--line); border-radius: var(--r-md); padding: 6px 11px 6px 7px;
  font-size: var(--t-sm); font-weight: 500; background: var(--surface); color: var(--body);
  box-shadow: var(--shadow-soft);
  transition: transform 200ms var(--ease-out), background 200ms var(--ease-out),
              border-color 200ms var(--ease-out), color 200ms var(--ease-out);
}
.chip:hover { transform: translateY(-1px); border-color: var(--line-hover) }
.chip:active { transform: translateY(0) scale(.97) }
.chip.on { border-color: var(--accent); background: var(--accent-tint); color: var(--accent-deep) }
.chip .m { width: 15px; height: 15px; border-radius: 3px; flex: none }
.chip .x { color: var(--faint); font-size: var(--t-sm); line-height: 1 }
.chip.on .x { color: var(--accent) }
.m-hdfc { background: linear-gradient(135deg,#1B3A6B,#0E2246) }
.m-axis { background: linear-gradient(135deg,#8C2242,#4A1024) }
.m-sbi  { background: linear-gradient(135deg,#1E5AA8,#123A6D) }
.m-amex { background: linear-gradient(135deg,#8E9AA8,#5C6875) }
.m-hsbc { background: linear-gradient(135deg,#C8102E,#7A0A1C) }
.m-icici{ background: linear-gradient(135deg,#B45309,#6B3208) }
.m-idfc { background: linear-gradient(135deg,#7A1F3D,#3D0F1E) }
.m-kotak{ background: linear-gradient(135deg,#C8102E,#8C0A20) }
.m-rbl  { background: linear-gradient(135deg,#2D2A6E,#14123A) }
.m-sc   { background: linear-gradient(135deg,#0F7B6C,#064239) }
.m-au   { background: linear-gradient(135deg,#5B2D8E,#2E1749) }
.m-yes  { background: linear-gradient(135deg,#1B4EA0,#0D2750) }
.m-indus{ background: linear-gradient(135deg,#8A1538,#4A0B1E) }
.m-fed  { background: linear-gradient(135deg,#1A7A5E,#0C3B2D) }
.m-bob  { background: linear-gradient(135deg,#E8632A,#8C3410) }
.m-one  { background: linear-gradient(135deg,#2B2B2B,#000) }
.m-none { background: var(--line) }

/* ================= BRAND MARKS ================= */
/* A programme or partner's own logo, bundled locally and served from our own
   origin - never a favicon service at render time. Anything with no bundled
   mark falls back to a monogram, tinted by kind so a long list stays
   scannable without reading every name. See KCUI.logo() in ui.js. */
.kcmark {
  display: inline-flex; align-items: center; justify-content: center;
  flex: none; overflow: hidden; border-radius: var(--r-sm);
  background: var(--surface);
}
.kcmark img { width: 100%; height: 100%; object-fit: contain }
.kcmark-sm { width: 18px; height: 18px }
.kcmark-md { width: 24px; height: 24px }
.kcmark-lg { width: 32px; height: 32px }
.kcmark-xl { width: 48px; height: 48px; border-radius: var(--r-md) }
.kcmono {
  border: 1px solid var(--line); background: var(--raise); color: var(--dim);
  font-family: var(--mono); font-weight: 700; letter-spacing: -.02em;
  text-transform: uppercase;
}
.kcmono.air { background: var(--accent-tint); border-color: var(--accent); color: var(--accent-deep) }
.kcmono.hot { background: var(--raise); border-color: var(--line); color: var(--body) }
/* A monogram is the fallback for a brand we have no logo for, so it has to be
   readable or it is worse than nothing. These were 7.5px and 9px - under this
   design's own 10px floor, and flagged by the layout audit the moment marks
   appeared in the transfer picker. Two characters still fit at these sizes. */
.kcmark-sm.kcmono { font-size: var(--t-micro); letter-spacing: -.04em }
.kcmark-md.kcmono { font-size: var(--t-micro) }
.kcmark-lg.kcmono { font-size: var(--t-sm) }
.kcmark-xl.kcmono { font-size: var(--t-lead) }
/* A mark inside a row lines up with the bank swatch it sits beside. */
.crow > .kcmark-md, .brow > .kcmark-md { margin-top: 1px }
/* ================= WALLET: cards as card faces ================= */
.wallet { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 8px }
.wcard {
  position: relative; display: grid; grid-template-columns: auto 1fr; grid-template-rows: auto auto;
  column-gap: 10px; align-items: center; text-align: left;
  border: 1px solid var(--line); border-radius: var(--r-sm); background: var(--surface);
  padding: 10px 12px; box-shadow: var(--shadow-soft);
  transition: transform 200ms var(--ease-out), border-color 200ms var(--ease-out), background 200ms var(--ease-out);
}
.wcard:hover { transform: translateY(-1.5px); border-color: var(--line-hover) }
.wcard.on { border-color: var(--accent); background: var(--accent-tint) }
.wcard .m { width: 30px; height: 20px; border-radius: 4px; grid-row: 1 / 3; box-shadow: 0 1px 3px rgba(16,24,40,.2) }
.wcard .wnm { font-size: var(--t-sm); font-weight: 600; color: var(--body); line-height: 1.3; padding-right: 16px }
.wcard .wbnk { font-size: var(--t-micro); color: var(--faint); font-family: var(--mono) }
.wcard .wx {
  position: absolute; top: 6px; right: 8px; width: 18px; height: 18px; border-radius: 50%;
  display: grid; place-items: center; font-size: var(--t-xs); line-height: 1;
  color: var(--faint); border: 1px solid var(--line); background: var(--surface);
}
.wcard.on .wx { color: #fff; background: var(--accent); border-color: var(--accent) }
/* ================= MONOGRAMS: programme badges ================= */
.mg {
  width: 28px; height: 28px; border-radius: 50%; flex: none;
  display: inline-grid; place-items: center;
  font-family: var(--mono); font-weight: 500; font-size: var(--t-micro); letter-spacing: .03em; text-transform: uppercase;
}
.mg.air { background: #EEF1FB; border: 1px solid #C9D3F4; color: #4457C4 }
.mg.hotel { background: #FBF2E4; border: 1px solid #EBD9B4; color: #8A6418 }
/* ================= TRANSFER ROUTES: click to open ================= */
.trow.tog { display: block; padding: 0 }
.trow.tog .tline {
  display: flex; align-items: center; gap: 12px; padding: 12px 20px; cursor: pointer;
}
.trow.tog .tline:hover { background: var(--hover) }
.trow.tog .g { font-family: var(--mono); font-size: var(--t-xs); font-weight: 600; color: var(--body);
  border: 1px solid var(--line); border-radius: 5px; padding: 3px 8px; background: var(--surface); white-space: nowrap; flex: none }
.trow.tog .get { font-family: var(--mono); font-weight: 500; font-size: var(--t-base); text-align: right; white-space: nowrap; flex: none }
.trow.tog .worth { font-family: var(--mono); font-size: var(--t-xs); color: var(--faint); text-align: right; white-space: nowrap; flex: none }
.trow.tog .caret { color: var(--faint); font-size: var(--t-xs); transition: transform 200ms var(--ease-out); flex: none }
.trow.tog.open .caret { transform: rotate(180deg); color: var(--accent) }
.trow.tog .bonus { color: var(--mint); font-size: var(--t-sm); font-weight: 600 }
.trow.tog .dwrap { display: none; padding: 0 20px 16px }
.trow.tog.open .dwrap { display: block }
.drawer {
  background: var(--raise); border: 1px solid var(--line); border-radius: 10px; padding: 16px 18px;
  animation: mountIn 420ms var(--ease-out);
}
.dgrid { display: grid; grid-template-columns: 1fr 1.4fr; gap: 20px }
@media (max-width: 640px) { .dgrid { grid-template-columns: 1fr } }
.dcol .dk { font-family: var(--mono); font-size: var(--t-micro); letter-spacing: .16em; text-transform: uppercase; color: var(--faint); margin-bottom: 8px }
.mathlines { font-family: var(--mono); font-size: var(--t-sm); color: var(--dim); line-height: 1.9 }
.mathlines .eq { color: var(--body); font-weight: 500 }
.mathlines .via { font-size: var(--t-micro); color: var(--faint) }
.dres { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; margin-top: 9px }
.dres .big { font-family: var(--mono); font-weight: 500; font-size: var(--t-h2); color: var(--accent-deep) }
.dres .w { font-family: var(--mono); font-size: var(--t-xs); color: var(--mint) }
.steps { list-style: none; counter-reset: st }
.steps li { counter-increment: st; position: relative; padding-left: 26px; font-size: var(--t-sm); color: var(--dim); line-height: 1.55; margin-bottom: 8px }
.steps li::before {
  content: counter(st); position: absolute; left: 0; top: 1px; width: 17px; height: 17px; border-radius: 50%;
  background: var(--surface); border: 1px solid var(--line); font-family: var(--mono); font-size: var(--t-micro); font-weight: 500;
  color: var(--dim); display: grid; place-items: center;
}
.steps li b { color: var(--body); font-weight: 600 }
.dwarn { margin-top: 12px; border-top: 1px dashed var(--line); padding-top: 10px; font-family: var(--mono); font-size: var(--t-micro); color: var(--faint); line-height: 1.7 }
.trow.tog .capnote { font-family: var(--mono); font-size: var(--t-micro); color: var(--dim); border: 1px solid var(--line); border-radius: 4px; padding: 2px 6px }
@media (max-width: 640px) {
  /* Seven items on one 358px line. Wrapping alone did not help: .grow has
     min-width 0, so it shrank to about 70px and clipped "Singapore Airlines
     KrisFlyer" mid-word rather than letting anything wrap. Give the name most
     of the first line and send the numbers to a second one. */
  .trow.tog .tline { flex-wrap: wrap; row-gap: 9px; column-gap: 9px }
  /* The ratio is already under the name as text; the pill repeats it. One of
     them goes on a narrow screen, and the pill is the redundant one. */
  .trow.tog .g { display: none }
  .trow.tog .worth { flex: 1 1 100%; order: 7; text-align: left; margin-top: 2px; white-space: normal }
  .trow.tog .tline > .kcmark { order: 1 }
  .trow.tog .kindpill { order: 2 }
  .trow.tog .grow { order: 3; flex: 1 1 55%; min-width: 0 }
  .trow.tog .g { order: 4 }
  .trow.tog .get { order: 5; margin-left: auto }
  .trow.tog .caret { order: 6 }
}
/* ================= FORM ================= */
.form { display: grid; gap: 14px }
.frow { display: grid; grid-template-columns: 1fr 1fr; gap: 12px }
.fld { display: grid; gap: 7px }
.fld > label {
  font-family: var(--mono); font-size: var(--t-micro); letter-spacing: .09em;
  text-transform: uppercase; color: var(--faint);
}
.inp, .sel {
  border: 1px solid var(--line); border-radius: var(--r-md); background: var(--surface);
  padding: 0 15px; height: 48px; font-family: var(--sans); font-size: var(--t-lead); color: var(--body);
  width: 100%; outline: 0; appearance: none; box-shadow: var(--shadow-soft);
  transition: border-color 200ms var(--ease-out), box-shadow 200ms var(--ease-out);
}
.inp:hover, .sel:hover { border-color: var(--line-hover) }
.inp:focus, .sel:focus { border-color: var(--accent); box-shadow: 0 0 0 4px var(--glow) }
.inp.money { font-family: var(--mono); font-size: var(--t-h3); font-variant-numeric: tabular-nums; letter-spacing: -.01em }
.moneywrap {
  display: flex; align-items: center; border: 1px solid var(--line); border-radius: var(--r-md);
  background: var(--surface); box-shadow: var(--shadow-soft); height: 48px;
  transition: border-color 200ms var(--ease-out), box-shadow 200ms var(--ease-out);
}
.moneywrap:focus-within { border-color: var(--accent); box-shadow: 0 0 0 4px var(--glow) }
.moneywrap .r { font-family: var(--mono); font-size: var(--t-h3); color: var(--dim); padding-left: 15px }
.moneywrap .inp { border: 0; box-shadow: none; background: transparent; height: auto; padding: 0 12px 0 5px }
.moneywrap .inp:focus { box-shadow: none }
.selwrap { position: relative }
.selwrap::after {
  content: ''; position: absolute; right: 16px; top: 50%; width: 7px; height: 7px;
  border-right: 1.8px solid var(--faint); border-bottom: 1.8px solid var(--faint);
  transform: translateY(-70%) rotate(45deg); pointer-events: none;
}
.sel { padding-right: 38px; cursor: pointer }
.segs { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 6px }
.seg {
  border: 1px solid var(--line); background: var(--surface); border-radius: var(--r-md);
  padding: 0 10px; height: 34px; font-size: var(--t-sm); font-weight: 500; color: var(--body);
  display: flex; align-items: center; justify-content: center; transition: all 200ms var(--ease-out);
  white-space: nowrap;
}
.seg.intl { border-style: dashed }
.seg:hover { border-color: var(--line-hover) }
.seg.on { background: var(--accent-tint); border-color: var(--accent); color: var(--accent-deep) }
.seg.intl.on { background: var(--raise); border-color: var(--air-ink); color: var(--air-ink) }
/* the payment selector sits beside its label on one row */
.fld.rails { display: flex; align-items: center; gap: 14px }
.fld.rails > label { flex: none }
.fld.rails .segs { flex: 1; min-width: 0 }
@media (max-width: 640px) {
  .fld.rails { flex-direction: column; align-items: stretch; gap: 7px }
}
.btn {
  /* .btn is worn by both <button> and <a>. An anchor is inline by default, so
     its vertical padding reserves no layout space and it overlaps whatever sits
     under it (the deals row did exactly that); it also arrives underlined.
     Stating the box here means one button, whichever element carries it. */
  display: inline-flex; align-items: center; justify-content: center;
  text-decoration: none; text-align: center; cursor: pointer;
  border: 0; border-radius: var(--r-md); background: var(--accent); color: #fff;
  padding: 15px 22px; font-size: var(--t-base); font-weight: 600; letter-spacing: -.01em;
  box-shadow: 0 1px 2px rgba(99, 91, 255, .4);
  transition: transform 200ms var(--ease-out), opacity 200ms var(--ease-out), background 200ms var(--ease-out), box-shadow 200ms var(--ease-out);
}
.btn:hover { background: var(--accent-deep); transform: translateY(-1px); box-shadow: 0 4px 10px -2px rgba(99,91,255,.5) }
.btn:active { transform: translateY(0) scale(.99) }
.btn[disabled] { opacity: .4; transform: none !important; cursor: default; box-shadow: none }
.btn.dark { background: var(--deep); box-shadow: var(--shadow-soft) }
.btn.dark:hover { background: #23252C }
.btn.quiet { background: var(--surface); color: var(--body); border: 1px solid var(--line); box-shadow: var(--shadow-soft) }
.btn.quiet:hover { border-color: var(--line-hover) }
.btn.wide { width: 100% }
/* ================= THE ANSWER ================= */
.ans {
  background: linear-gradient(160deg, #171A24 0%, #10121A 72%); border: 1px solid rgba(255,255,255,.07);
  border-radius: 14px; color: #fff; overflow: hidden;
  box-shadow: var(--shadow-lg);
}
.ans-top { padding: 24px 28px 20px; display: grid; grid-template-columns: 1fr auto; gap: 28px; align-items: start }
.ans-top .grow { min-width: 0 }
.ans .eyebrow {
  font-family: var(--mono); font-size: var(--t-micro); letter-spacing: .1em;
  text-transform: uppercase; color: var(--ans-eyebrow);
}
.ans h3 {
  font-family: var(--display); font-size: clamp(23px, 2.6vw, 30px); font-weight: 700;
  letter-spacing: -.02em; margin-top: 9px; display: flex; align-items: center; gap: 12px; line-height: 1.15;
}
.ans h3 .m { width: 28px; height: 28px; border-radius: 6px; flex: none; box-shadow: 0 0 0 1px rgba(255,255,255,.14) }
.ans .method { font-size: var(--t-sm); color: var(--ans-dim); margin-top: 9px; line-height: 1.7; max-width: 60ch }
.ans .method b { color: var(--ans-strong); font-weight: 600 }
.ans .method .arrow { color: var(--ans-pos); font-family: var(--mono); padding: 0 7px }
.ans .method .rulechip {
  display: inline-block; font-family: var(--mono); font-size: var(--t-micro); letter-spacing: .04em;
  color: var(--ans-eyebrow); background: rgba(165,160,245,.12); border: 1px solid rgba(165,160,245,.35);
  border-radius: 5px; padding: 2px 8px; margin-left: 8px; vertical-align: 1px; white-space: nowrap;
}
.ans-fig { text-align: right; flex: none; min-width: 190px }
.ans-fig .figlabel {
  font-family: var(--mono); font-size: var(--t-micro); letter-spacing: .16em; text-transform: uppercase;
  color: var(--ans-faint); margin-bottom: 6px;
}
.ans-fig .big {
  font-family: var(--mono); font-size: clamp(28px, 3.2vw, 36px); font-weight: 500; color: var(--ans-pos);
  letter-spacing: -.025em; display: block; line-height: 1.05;
}
.ans-fig .big.zero { color: var(--ans-dim) }
.ans-fig .big.bad { color: var(--ans-neg) }
.ans-fig .subline { display: flex; align-items: center; gap: 9px; justify-content: flex-end; margin-top: 8px; flex-wrap: wrap }
.ans-fig .pts { font-family: var(--mono); font-size: var(--t-sm); color: var(--ans-dim) }
.ans-fig .pct {
  display: inline-block; font-family: var(--mono); font-size: var(--t-xs);
  background: color-mix(in srgb, var(--ans-pos) 14%, transparent); color: var(--ans-pos); border-radius: var(--r-sm); padding: 3px 9px;
}
.ans-fig .pct.zero { background: rgba(152,161,178,.14); color: var(--ans-dim) }
/* --- the math, behind a click --- */
.mathbar {
  border-top: 1px solid var(--ans-rule); background: var(--ink-2);
  display: flex; align-items: center; gap: 10px; width: 100%;
  padding: 14px 28px; border-radius: 0; background-color: var(--ink-2);
  color: var(--ans-dim); font-size: var(--t-sm); text-align: left; border-left: 0; border-right: 0; border-bottom: 0;
  transition: color 240ms var(--ease-out), background 240ms var(--ease-out);
}
.mathbar:hover { color: var(--ans-strong) }
.mathbar .cv {
  width: 9px; height: 9px; border-right: 1.8px solid currentColor; border-bottom: 1.8px solid currentColor;
  transform: rotate(45deg) translateY(-2px); transition: transform 380ms var(--ease-out); flex: none;
}
.mathbar.open .cv { transform: rotate(-135deg) translateY(-2px) }
.mathbar .grow { flex: 1 }
.mathbar .hint { font-family: var(--mono); font-size: var(--t-micro); color: var(--ans-faint) }
.mathbox {
  background: var(--ink-2); overflow: hidden; height: 0;
  transition: height 460ms var(--ease-soft);
}
.mathbox .pad { padding: 2px 28px 20px }
.ml {
  font-family: var(--mono); font-size: var(--t-sm); color: var(--ans-faint); line-height: 2;
  display: flex; gap: 10px;
  opacity: 0; transform: translateX(-6px);
  transition: opacity 420ms var(--ease-out), transform 420ms var(--ease-out);
  transition-delay: calc(min(var(--i), 10) * 70ms);
}
.mathbox.open .ml { opacity: 1; transform: none }
.ml::before { content: '\00B7'; color: var(--ans-faint) }
.ml.neg { color: #F09B8B }
.ml.tot { color: var(--ans-strong) }
.capchip {
  display: inline-block; margin-top: 14px; font-family: var(--mono); font-size: var(--t-xs);
  color: var(--cap-ink); background: var(--cap-bg); border: 1px solid var(--cap-line);
  border-radius: var(--r-sm); padding: 7px 12px; line-height: 1.6;
}
.capchip.bite { animation: bite 900ms var(--ease-out) }
@keyframes bite {
  0% { border-color: rgba(242,196,115,.2); background: rgba(242,196,115,.06) }
  18% { border-color: rgba(242,196,115,.95); background: rgba(242,196,115,.22) }
  100% { border-color: rgba(242,196,115,.2); background: rgba(242,196,115,.06) }
}
.srcline { margin-top: 14px; font-size: var(--t-xs); color: var(--ans-faint); line-height: 1.6 }
.srcline b { color: var(--ans-dim); font-weight: 500 }
.ans-foot { display: flex; gap: 10px; padding: 17px 28px; border-top: 1px solid var(--ans-rule) }
.act {
  flex: 1; text-align: center; border-radius: var(--r-md); padding: 14px; font-size: var(--t-base);
  font-weight: 600; border: 0; transition: all 200ms var(--ease-out);
}
.act.solid { background: var(--ans-solid); color: var(--ans-solid-ink) }
.act.solid:hover { transform: translateY(-1px) }
.act.line { background: transparent; border: 1px solid var(--ans-btn); color: var(--ans-strong); font-weight: 500 }
.act.line:hover { background: rgba(255,255,255,.06); transform: translateY(-1px) }
.act[disabled] { opacity: .45; transform: none !important; cursor: default }
/* ================= THINKING ================= */
.ans-mount { margin-top: 18px }
.ans-mount:empty { display: none }
.ans-mount .ans, .ans-mount .thinking, .ans-mount .panel {
  animation: mountIn 560ms var(--ease-out);
}
@keyframes mountIn { from { opacity: 0; transform: translateY(16px); filter: blur(6px) } }
@media (prefers-reduced-motion: reduce) { .ans-mount .ans, .ans-mount .thinking, .ans-mount .panel { animation: none } }
.thinking {
  display: flex; align-items: center; gap: 13px;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg);
  box-shadow: var(--shadow-soft); padding: 26px 28px; font-size: var(--t-base); color: var(--dim);
}
.bars { display: flex; gap: 3px; align-items: flex-end; height: 16px }
.bars i { width: 3px; border-radius: 1px; background: var(--accent); height: 5px; animation: scan 900ms var(--ease-soft) infinite }
.bars i:nth-child(2) { animation-delay: 90ms }
.bars i:nth-child(3) { animation-delay: 180ms }
.bars i:nth-child(4) { animation-delay: 270ms }
@keyframes scan { 0%,100% { height: 4px; opacity: .45 } 45% { height: 16px; opacity: 1 } }
/* ================= COMPARE ================= */
.compare { margin-top: 12px; background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg); overflow: hidden; box-shadow: var(--shadow-soft) }
.compare-h {
  font-family: var(--mono); font-size: var(--t-micro); letter-spacing: .09em; text-transform: uppercase;
  color: var(--faint); padding: 15px 20px 11px; display: flex; justify-content: space-between;
  gap: 12px;
}
/* Two mono labels on a 358px line run into each other. The right-hand one is
   always the hint or the unit, so it is the one that gives way. */
@media (max-width: 640px) {
  .compare-h { padding-left: 16px; padding-right: 16px; flex-wrap: wrap; row-gap: 4px }
  .compare-h > span:last-child { flex: 1 1 100%; opacity: .75 }
}
.crow {
  display: flex; align-items: center; gap: 13px; padding: 13px 20px;
  border-top: 1px solid var(--line); font-size: var(--t-base);
  transition: opacity 460ms var(--ease-out), transform 460ms var(--ease-out), background 200ms linear;
  transition-delay: calc(min(var(--i), 10) * 60ms);
}
.crow.pre { opacity: 0; transform: translateY(8px); transition: none }
/* Entrance animations are OPT-OUT, not opt-in: a row is visible unless
   reveal() has marked it .pre for one frame. Built the other way round, any
   row painted after the initial mount - every search, filter or repaint - kept
   opacity 0 forever, which is how the MCC detail list became a 10,000px blank
   gap with 77 real rows invisible inside it. An animation must never be the
   thing that decides whether content can be seen.

   The stagger is capped at ten steps everywhere. Uncapped, a 26-row table took
   1.6s to finish appearing and a 60-row one 3.6s - rows near the bottom read as
   missing rather than arriving. Ten steps keeps the cascade and bounds the wait. */
.crow.in { opacity: 1; transform: none }
.crow:hover { background: var(--hover) }
.crow.has-note { align-items: flex-start }
/* Matches .kcmark-md. A row may carry either a gradient swatch or a real
   logo, and at different sizes the name column shifted between rows. */
.crow .m { width: 24px; height: 24px; border-radius: 5px; flex: none }
.crow .grow { flex: 1; min-width: 0 }
.crow .nm { font-weight: 600 }
.mt { font-size: var(--t-sm); color: var(--faint); margin-top: 3px; line-height: 1.45 }
.crow .mt { font-size: var(--t-sm); color: var(--faint); margin-top: 3px; line-height: 1.45 }
/* A value cell's colour is a claim, so it has to mean one thing.
     (default)  money or a rate you GAIN            mint
     .cost      money you PAY - a fee, a markup     ink, not red: a fee is not an error
     .zero      earns nothing here                  faint
     .bad       something actually wrong            clay
     .text      a fact that is not a number         ink, and not in the number face
   Green on an annual fee, which is what this page used to do, tells the reader
   a charge is a benefit. */
.crow > div:last-child:not(.grow) { text-align: right }
.v { font-family: var(--mono); font-size: var(--t-base); color: var(--mint); flex: none; text-align: right }
.v.cost { color: var(--body) }
.v.zero { color: var(--faint) }
.v.bad { color: var(--clay) }
.v.text {
  font-family: inherit; font-size: var(--t-base); font-weight: 500; color: var(--body);
  max-width: 320px; white-space: normal;
  /* .v is flex:none because a figure should never be squeezed. A .text value
     is a name or a sentence, so it must shrink and wrap instead of overflowing
     its column - which is what it did across /compare's rewards-currency row. */
  flex: 0 1 auto; min-width: 0;
}
.vp { font-family: var(--mono); font-size: var(--t-xs); color: var(--faint); display: block; margin-top: 3px }
/* "Use this card": picks an option that is not the best to see its math and log it. */
.picklink { display: block; margin: 5px 0 0 auto; padding: 0; border: 0; background: none; font-size: var(--t-xs);
  font-weight: 600; color: var(--accent-deep); text-align: right; cursor: pointer }
.picklink:hover { text-decoration: underline }
.pickgap { margin-top: 8px; font-size: var(--t-sm); color: var(--dim); display: flex; flex-wrap: wrap; gap: 4px 10px; align-items: baseline }
.pickgap .picklink { display: inline; margin: 0 }
/* Inside the dark answer panel the gap line uses the panel's own tokens. */
.ans .pickgap { color: var(--ans-dim) }
.ans .pickgap b { color: var(--ans-strong); font-weight: 600 }
.ans .pickgap .picklink { color: var(--ans-eyebrow) }
.crow.off { background: var(--raise) }
.crow.off .nm { color: var(--dim) }
.crow.off .m { opacity: .4 }
/* .has-note marks a row whose left column is prose, not a label. Side by side
   with a value column on a 390px screen that prose gets about 180px and every
   sentence wraps four times (sweet spots was unreadable). On a phone the value
   leads and the prose takes the full width. Plain rows are short enough to stay
   side by side, so they are left alone. */
@media (max-width: 640px) {
  /* A value cell holding a .vp sub-line has a wide min-content (the mono fee
     string), and because a flex item will not shrink past that, the card NAME
     was the only thing left to squeeze - three lines for "HDFC Regalia Gold".
     Letting the value cell shrink puts the wrap where it belongs. */
  .crow { padding-left: 16px; padding-right: 16px; gap: 10px }
  .crow > *:last-child { min-width: 0 }
  .crow.has-note { flex-wrap: wrap; align-items: baseline; row-gap: 9px }
  /* wrap, not column: the swatch or pill and the value keep the first line
     between them, and only the prose drops to a full-width second line. A
     column would strand a 21px swatch on a row of its own. */
  .crow.has-note > .grow { flex: 1 1 100%; order: 1 }
  .crow.has-note > *:last-child { margin-left: auto }
  /* A trailing NUMBER leads the row - "12,000 points, and here is what for".
     A trailing NOTE or BUTTON is not a headline, so it follows the prose
     instead of sitting above the name it qualifies. */
  .crow.has-note > .vp,
  .crow.has-note > span:last-child { order: 2; flex: 1 1 100%; margin-left: 0; text-align: left }
}
.excl {
  font-size: var(--t-sm); color: var(--clay); background: var(--excl-bg); border: 1px solid var(--line);
  border-left: 2px solid var(--clay);
  border-radius: var(--r-sm); padding: 9px 12px; margin-top: 8px; line-height: 1.55;
}
.excl b { font-weight: 600 }
/* ================= BEYOND ================= */
.beyond { margin-top: 12px; border: 1px solid var(--air-line); background: var(--air); border-radius: var(--r-lg); padding: 18px 20px }
.beyond-h {
  font-family: var(--mono); font-size: var(--t-micro); letter-spacing: .09em; text-transform: uppercase;
  color: var(--air-ink); display: flex; justify-content: space-between; align-items: baseline; gap: 14px;
}
.beyond-h .note { letter-spacing: 0; text-transform: none; font-family: var(--sans); font-size: var(--t-sm); opacity: .82 }
.brow {
  display: flex; align-items: center; gap: 13px; padding: 13px 0 0; font-size: var(--t-base);
  transition: opacity 460ms var(--ease-out), transform 460ms var(--ease-out);
  transition-delay: calc(min(var(--i), 10) * 60ms);
}
.brow.pre { opacity: 0; transform: translateY(8px); transition: none }
.brow .m { width: 24px; height: 24px; border-radius: 5px; flex: none }
.brow .grow { flex: 1; min-width: 0 }
.brow .nm { font-weight: 600 }
.brow .mt { font-size: var(--t-sm); color: var(--air-ink); opacity: .78; margin-top: 3px }
.brow .v { font-family: var(--mono); font-size: var(--t-base); color: var(--air-ink); flex: none; text-align: right }
.brow .v b { display: block; font-weight: 500 }
.brow .v span { font-size: var(--t-xs); opacity: .72 }
/* ================= POINTS / TRANSFER / TRIP ================= */
.tabs { display: flex; gap: 4px; margin-bottom: 20px; border-bottom: 1px solid var(--line); flex-wrap: wrap }
.tab {
  border: 0; background: none; border-radius: 0; padding: 11px 15px 12px; font-size: var(--t-base);
  font-weight: 500; color: var(--dim); transition: color 200ms var(--ease-out), box-shadow 200ms var(--ease-out);
  position: relative; margin-bottom: -1px; border-bottom: 2px solid transparent;
}
.tab:hover { color: var(--body) }
.tab.on { color: var(--accent-deep); border-bottom-color: var(--accent); font-weight: 600 }
.tab .c { font-family: var(--mono); font-size: var(--t-xs); opacity: .65; margin-left: 6px }
.balgrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 12px; margin-top: 14px }
/* Add a balance: programme, points, as-of, save - one row, stacking on a phone. */
.hf-h { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 10px; font-size: var(--t-sm); color: var(--dim); margin-bottom: 12px }
.hf-h b { color: var(--body); font-size: var(--t-base) }
.hf-row { display: grid; grid-template-columns: minmax(0, 2.2fr) minmax(0, 1fr) minmax(0, 1fr) auto; gap: 10px; align-items: start }
/* start, not end: a password manager injects its own element after a field,
   and with bottom alignment that pushed the whole Points column up. The
   button has no label, so it drops by one label row to sit on the inputs. */
.hf-row > .btn { margin-top: calc(var(--t-micro) * 1.5 + 3px) }
.hf-row .fld { gap: 5px }
.hf-row .btn { height: 48px; padding: 0 22px }  /* the inputs are 48px - a shorter button sat off their baseline */
.hf-note { margin-top: 10px; font-size: var(--t-xs); color: var(--faint) }
.hf-err { color: var(--clay); font-weight: 600 }
@media (max-width: 720px) {
  .hf-row { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) }
  .hf-row .fld:first-child { grid-column: 1 / -1 }
  .hf-row .btn { grid-column: 1 / -1 }
  .hf-row > .btn { margin-top: 0 }
}
/* A balance card: logo and name, what kind of points, the figure, where it came from. */
.bal-top { display: flex; align-items: center; gap: 10px; min-width: 0; min-height: 50px }  /* room for a two-line name, so numbers line up across a row */
.bal-top .kcmark { flex: none }
.bal-id { min-width: 0 }
.bal-id .pn { color: var(--body); font-weight: 600; line-height: 1.3 }
.bal-kind { display: inline-block; margin-top: 3px; font-family: var(--mono); font-size: var(--t-micro); letter-spacing: .05em;
  text-transform: uppercase; color: var(--faint) }
.bal-how { font-size: var(--t-xs); color: var(--faint); margin-top: 4px; line-height: 1.45 }
.bal-acts { display: flex; align-items: center; gap: 12px; margin-top: 12px; padding-top: 10px; border-top: 1px solid var(--line) }
.bal-act { border: 0; background: none; padding: 0; font-size: var(--t-xs); font-weight: 600; color: var(--accent-deep); cursor: pointer }
.bal-act:hover { text-decoration: underline }
.bal-act.arm { color: var(--clay) }
.bal-share { margin-left: auto; font-size: var(--t-xs); color: var(--faint) }
/* Trips: which balances the plan is priced against, and per trip which one pays. */
.tripfund { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 14px; margin-bottom: 16px; padding: 11px 14px;
  border: 1px solid var(--line); border-radius: var(--r-lg); background: var(--surface); text-decoration: none; color: inherit }
.tripfund:hover { border-color: var(--line-hover) }
.tripfund-k { font-family: var(--mono); font-size: var(--t-micro); letter-spacing: .08em; text-transform: uppercase; color: var(--faint); flex-basis: 100% }
.tripfund-b { display: inline-flex; align-items: center; gap: 6px; font-size: var(--t-sm); color: var(--dim) }
.tripfund-b b { color: var(--body); font-weight: 600 }
.tripfrom { display: flex; align-items: center; gap: 6px; margin: 4px 0 6px; font-size: var(--t-xs); color: var(--faint) }
.bal { border: 1px solid var(--line); background: var(--surface); border-radius: var(--r-lg); padding: 17px 19px; box-shadow: var(--shadow-soft);
  display: flex; flex-direction: column }
.bal .bal-acts { margin-top: auto; padding-top: 10px }  /* actions sit on the card's bottom edge whatever the name length */
.bal .bal-how { margin-bottom: 12px }
.hf + .panel { margin-top: 14px }  /* the empty state used to touch the form */
.bal .pn { font-size: var(--t-sm); color: var(--dim) }
.bal .pv { font-family: var(--mono); font-size: var(--t-stat); margin-top: 7px; letter-spacing: -.02em }
.bal .pw { font-family: var(--mono); font-size: var(--t-xs); color: var(--mint); margin-top: 5px }
.trow {
  display: flex; align-items: center; gap: 14px; padding: 14px 20px;
  border-top: 1px solid var(--line); font-size: var(--t-base);
  transition: opacity 460ms var(--ease-out), transform 460ms var(--ease-out);
  transition-delay: calc(min(var(--i), 10) * 55ms);
}
.trow.pre { opacity: 0; transform: translateY(8px); transition: none }
.trow .grow { flex: 1; min-width: 0 }
.trow .nm { font-weight: 600 }
.trow .mt { font-size: var(--t-sm); color: var(--faint); margin-top: 3px; font-family: var(--mono) }
.trow .v { font-family: var(--mono); font-size: var(--t-base); text-align: right; flex: none }
.trow .v b { display: block; font-weight: 500; color: var(--body) }
.trow .v span { font-size: var(--t-xs); color: var(--faint) }
.kindpill {
  font-family: var(--mono); font-size: var(--t-micro); letter-spacing: .06em; text-transform: uppercase;
  border-radius: 5px; padding: 3px 7px; flex: none;
}
.kindpill.air { background: var(--accent-tint); color: var(--accent-deep) }
.kindpill.hot { background: var(--raise); color: var(--dim) }
.prog { margin-bottom: 14px }
.prog .pl { display: flex; justify-content: space-between; font-size: var(--t-base); margin-bottom: 7px; gap: 14px }
.prog .pl .r { font-family: var(--mono); font-size: var(--t-sm); color: var(--faint) }
.prog .track { height: 7px; border-radius: 99px; background: var(--raise); overflow: hidden }
.prog .fill { height: 100%; border-radius: 99px; background: var(--mint); width: 0; transition: width 950ms var(--ease-soft); transition-delay: calc(min(var(--i), 10) * 110ms) }
.prog .fill.part { background: var(--air-ink) }
.trip {
  background: linear-gradient(118deg, var(--trip-from), var(--trip-to)); border-radius: var(--r-lg); color: #fff;
  padding: 24px 26px; display: flex; gap: 22px; align-items: flex-end;
  position: relative; overflow: hidden; box-shadow: var(--shadow-lg);
}
.trip::after {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(105deg, transparent 38%, rgba(255,255,255,.1) 50%, transparent 62%);
  transform: translateX(-120%);
}
.trip.in::after { animation: sweep 1500ms var(--ease-soft) 300ms }
@keyframes sweep { to { transform: translateX(120%) } }
.trip .grow { flex: 1 }
.trip .eyebrow { font-family: var(--mono); font-size: var(--t-micro); letter-spacing: .1em; text-transform: uppercase; color: #A9A3E8 }
.trip h4 { font-family: var(--display); font-size: 24px; font-weight: 700; letter-spacing: -.02em; margin-top: 11px }
.trip .sub { font-family: var(--mono); font-size: var(--t-sm); color: #A9A3E8; margin-top: 10px }
.trip .worth { font-family: var(--mono); font-size: var(--t-stat); text-align: right; flex: none }
.trip .worth span { display: block; font-size: var(--t-micro); color: var(--trip-dim); letter-spacing: .08em; margin-bottom: 6px }
/* ================= LEDGER ================= */
.lrow {
  display: flex; align-items: center; gap: 14px; padding: 13px 20px;
  border-top: 1px solid var(--line); font-size: var(--t-base);
}
.lrow .grow { flex: 1 }
.lrow .mt { font-size: var(--t-sm); color: var(--faint); margin-top: 3px }
.lrow .g { font-family: var(--mono); font-size: var(--t-sm); color: var(--mint) }
/* a cashback spend earns rupees, not points: its points cell is not a gain */
.lrow .g.zero { color: var(--faint) }
.empty { text-align: center; padding: 46px 24px; color: var(--faint); font-size: var(--t-base); line-height: 1.7 }
.empty b { color: var(--dim); display: block; font-size: var(--t-lead); margin-bottom: 7px; font-weight: 600 }
.note { font-size: var(--t-sm); color: var(--faint); line-height: 1.65; margin-top: 14px }
.note b { color: var(--dim); font-weight: 600 }
/* ================= FOOT ================= */
.foot {
  position: relative; z-index: 1;
  max-width: 1040px; margin: 0 auto; padding: 0 28px 70px;
  font-size: var(--t-sm); color: var(--faint); line-height: 1.75;
}
.foot b { color: var(--dim); font-weight: 600 }
/* ================= PHONE ================= */
@media (max-width: 900px) {
  .shell { padding: 20px 16px 100px }
  .foot { padding: 0 16px 60px }
  .rail { padding: 0 16px; gap: 10px }
  /* the stepper tightens */
  .spine { margin-bottom: 22px; gap: 2px; padding: 0 2px }
  .sstep { padding: 0 4px }
  .sstep p, .sstep .tag, .sstep h4 .lg { display: none }
  .sstep h4 .sm { display: inline }
  .sstep h4 { font-size: var(--t-xs) }
  /* the pulse ring smears across an inline stepper - drop it here */
  .sstep.live .snode::after { display: none }
  .frow { grid-template-columns: 1fr }
  .segs { grid-template-columns: 1fr 1fr }
  .ans-top { grid-template-columns: 1fr; gap: 18px; padding: 24px 22px }
  .ans-fig { text-align: left; min-width: 0 }
  .ans-fig .subline { justify-content: flex-start }
  .mathbar, .mathbox .pad, .ans-foot { padding-left: 22px; padding-right: 22px }
  .ans-foot { flex-wrap: wrap }
  .act { flex: 1 1 100% }
  .trip { flex-direction: column; align-items: flex-start; gap: 14px }
  .trip .worth { text-align: left }
}
/* ================= COMBOBOX: one field for merchant or category ================= */
.combo { position: relative }
.combo .inp { padding-right: 40px }
.combox {
  position: absolute; right: 10px; top: 50%; transform: translateY(-50%);
  width: 24px; height: 24px; border: 0; background: var(--raise); color: var(--dim);
  border-radius: 50%; font-size: var(--t-base); line-height: 1; display: grid; place-items: center;
  transition: background 200ms var(--ease-out), color 200ms var(--ease-out);
}
.combox:hover { background: var(--line); color: var(--body) }
.combox[hidden] { display: none }
.combolist {
  position: absolute; z-index: 30; left: 0; right: 0; top: calc(100% + 7px);
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-md);
  box-shadow: var(--shadow-lg); overflow: hidden auto; max-height: 306px;
  opacity: 0; transform: translateY(-6px); pointer-events: none;
  transition: opacity 220ms var(--ease-out), transform 220ms var(--ease-out);
}
.combolist.open { opacity: 1; transform: none; pointer-events: auto }
.comboitem {
  display: flex; align-items: center; gap: 12px; width: 100%; text-align: left;
  padding: 12px 16px; border: 0; background: none; font-size: var(--t-base); color: var(--body);
  border-bottom: 1px solid var(--line);
}
.comboitem:last-child { border-bottom: 0 }
.comboitem:hover, .comboitem.sel { background: var(--accent-tint) }
.comboitem .grow { flex: 1 }
.comboitem .hint { font-family: var(--mono); font-size: var(--t-micro); color: var(--faint) }
.comboitem.empty { color: var(--faint); font-size: var(--t-sm); cursor: default }
/* display:flex above beats the hidden attribute, so filtering hid nothing -
   every search box built on tfCombo showed its whole list. */
.comboitem[hidden] { display: none }
.warn {
  margin-top: 4px; font-size: var(--t-sm); line-height: 1.6; color: var(--warn-ink);
  background: var(--warn-bg); border: 0; border-left: 2px solid var(--warn-ink);
  border-radius: 0; padding: 10px 14px;
}
.warn b { font-weight: 600 }
/* ================= RETURN SIGNALS: one line until you want more ================= */
.signals {
  border: 1px solid var(--line); background: var(--surface);
  border-radius: var(--r-lg); overflow: hidden; margin-bottom: 16px; box-shadow: var(--shadow-soft);
}
.sigbar {
  display: flex; align-items: center; gap: 11px; width: 100%; text-align: left;
  padding: 12px 16px; border: 0; background: none; font-size: var(--t-base); color: var(--body);
}
.sigbar:hover { background: var(--hover) }
.sigbar .grow { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap }
.sigbar b { font-weight: 600 }
.sigbar .more {
  font-family: var(--mono); font-size: var(--t-micro); color: var(--faint);
  border: 1px solid var(--line); border-radius: var(--r-sm); padding: 3px 7px; flex: none;
}
.sigbar .cv, .discbar .cv, .morebar .cv {
  width: 8px; height: 8px; flex: none;
  border-right: 1.7px solid var(--faint); border-bottom: 1.7px solid var(--faint);
  transform: rotate(45deg) translateY(-2px); transition: transform 380ms var(--ease-out);
}
.signals.open .sigbar .cv { transform: rotate(-135deg) translateY(-2px) }
.sigbar .dot { width: 8px; height: 8px; border-radius: 50%; flex: none; background: var(--faint) }
.sigbar .dot.hot { background: var(--accent); box-shadow: 0 0 0 3px var(--glow) }
.sigbar .dot.warm { background: #D9A13A }
.sigbar .dot.good { background: var(--mint) }
.siglist { max-height: 0; overflow: hidden; transition: max-height 480ms var(--ease-soft) }
.signals.open .siglist { max-height: 620px }
.sig {
  display: flex; align-items: flex-start; gap: 12px; padding: 13px 16px;
  border-top: 1px solid var(--line);
  transition: opacity 460ms var(--ease-out), transform 460ms var(--ease-out);
  transition-delay: calc(min(var(--i), 10) * 60ms);
}
.sig.pre { opacity: 0; transform: translateY(8px); transition: none }
.sig .dot { width: 8px; height: 8px; border-radius: 50%; margin-top: 6px; flex: none; background: var(--faint) }
.sig.hot .dot { background: var(--accent); box-shadow: 0 0 0 3px var(--glow) }
.sig.warm .dot { background: #D9A13A }
.sig.good .dot { background: var(--mint) }
.sig .grow { flex: 1; min-width: 0 }
.sig .st { font-size: var(--t-base); font-weight: 600; letter-spacing: -.005em }
.sig .sd { font-size: var(--t-sm); color: var(--dim); margin-top: 4px; line-height: 1.55 }
.sigact { display: flex; gap: 6px; flex: none; flex-wrap: wrap; justify-content: flex-end }
.btn.tiny { padding: 6px 11px; font-size: var(--t-xs); font-weight: 600; border-radius: var(--r-sm) }
/* ================= DISCLOSURE: math, other cards, cards you lack ================= */
.disc {
  margin-top: 10px; border: 1px solid var(--line); background: var(--surface);
  border-radius: var(--r-lg); overflow: hidden; box-shadow: var(--shadow-soft);
}
.disc.air { border-style: solid; border-color: var(--air-line); background: var(--air) }
.discbar {
  display: flex; align-items: center; gap: 11px; width: 100%; text-align: left;
  padding: 14px 18px; border: 0; background: none; font-size: var(--t-base); color: var(--body);
}
.discbar:hover { background: var(--hover) }
.disc.air .discbar { color: var(--body) }
.disc.air .discbar:hover { background: rgba(255,255,255,.4) }
.disc.open > .discbar .cv { transform: rotate(-135deg) translateY(-2px) }
.discbar .grow { flex: 1; font-weight: 600 }
.discbar .hint { font-family: var(--mono); font-size: var(--t-micro); color: var(--faint) }
.disc.air .discbar .hint { color: var(--air-ink) }
.discbox { height: 0; overflow: hidden; transition: height 460ms var(--ease-soft) }
.discbox .pad { padding: 0 0 4px }
.disc.air .discbox .pad { padding: 0 18px 16px }
.compare.bare, .beyond.bare {
  margin: 0; border: 0; border-radius: 0; background: none; padding: 0;
}
.compare.bare .crow:first-child { border-top: 1px solid var(--line) }
/* ================= SEE ALL ================= */
.morebar {
  display: flex; align-items: center; justify-content: center; gap: 9px; width: 100%;
  padding: 13px; border: 0; border-top: 1px solid var(--line); background: var(--raise);
  font-size: var(--t-sm); color: var(--dim); font-weight: 600;
  transition: background 200ms var(--ease-out), color 200ms var(--ease-out);
}
.morebar:hover { background: var(--line); color: var(--body) }
.morebar.solo { border: 1px solid var(--line); border-radius: var(--r-md); margin-top: 14px; background: var(--surface) }
.morebar .cv.r { transform: rotate(-45deg) translateX(-1px) }
.bal.cash { border-color: var(--cash-line); background: var(--cash-bg); border-left: 3px solid var(--mint) }
.bal.cash .pv { color: var(--mint) }
@media (max-width: 900px) {
  .sig { flex-wrap: wrap }
  .sigact { width: 100%; justify-content: flex-start; margin-top: 4px }
  .signals.open .siglist { max-height: 1200px }
}
/* ================= TYPE SWITCHER (prototype only) ================= */
.typeswitch { display: flex; border: 1px solid var(--line); border-radius: var(--r-sm); overflow: hidden; background: var(--surface) }
.typeswitch button {
  border: 0; background: var(--surface); color: var(--faint);
  font-family: var(--mono); font-size: var(--t-micro); letter-spacing: .05em; padding: 6px 9px;
  border-right: 1px solid var(--line); transition: background 200ms var(--ease-out), color 200ms var(--ease-out);
}
.typeswitch button:last-child { border-right: 0 }
.typeswitch button:hover { color: var(--body) }
.typeswitch button.on { background: var(--accent-tint); color: var(--accent-deep) }
@media (max-width: 900px) { .typeswitch { display: none } }
/* the bar summarises when open, so it stops repeating the first row verbatim */
.sigbar .shown { display: none }
.signals.open .sigbar .shut { display: none }
.signals.open .sigbar .shown { display: inline; color: var(--dim); font-weight: 400 }
/* ================= DIRECT NAV ================= */
.railnav { display: flex; gap: 2px; margin-left: 8px }
.railnav a {
  font-size: var(--t-sm); font-weight: 500; color: var(--dim); text-decoration: none;
  padding: 6px 11px; border-radius: var(--r-md);
  transition: background 200ms var(--ease-out), color 200ms var(--ease-out);
}
.railnav a:hover { background: var(--raise); color: var(--body) }
.railnav a.on { color: var(--body) }
/* The current page is underlined, sitting on the rail's bottom edge like a
   tab - the tinted pill read as a button, not as "you are here". The same
   mark goes on a group (Cards / Travel / Earn) when one of its pages is open. */
.railnav > a, .navgroup-b { position: relative }
.railnav > a.on::after, .navgroup-b.on::after {
  content: ''; position: absolute; left: 11px; right: 11px; bottom: calc((var(--railh) - 30px) / -2);
  height: 2px; border-radius: 2px 2px 0 0; background: var(--accent);
}
/* Inside a dropdown, and in the phone sheet, the item itself is underlined. */
.navgroup-p a.on, .rail.navopen .railnav a.on {
  text-decoration: underline; text-decoration-color: var(--accent); text-decoration-thickness: 2px; text-underline-offset: 5px;
}
.rail.navopen .railnav > a.on::after, .rail.navopen .navgroup-b.on::after { content: none }
.crow .ok {
  font-family: var(--mono); font-size: var(--t-micro); letter-spacing: .05em; text-transform: uppercase;
  color: var(--mint); background: var(--mint-tint); border: 1px solid var(--cash-line);
  border-radius: 5px; padding: 2px 6px; margin-left: 7px; vertical-align: middle;
}
/* Below 900px the rail has no room for the nav, so it becomes a sheet behind
   a Menu button. It used to be display:none with nothing in its place - a
   phone could not reach any surface except by typing its address. */
.navtoggle { display: none }
.navcount { margin-left: 6px; padding: 1px 6px; border-radius: 999px; font-size: var(--t-micro);
  background: var(--raise); color: var(--dim) }
.railnav a.on .navcount { background: var(--surface); color: var(--accent-deep) }
/* My stack: one button on the right with the other things that are yours
   (points, account). Swatches say "cards", the count says how many. */
.railcards { text-decoration: none; align-items: center; gap: 8px; padding: 5px 11px 5px 8px;
  border-radius: var(--r-md); color: var(--dim); font-size: var(--t-sm); font-weight: 500;
  transition: background 200ms var(--ease-out), color 200ms var(--ease-out) }
.railcards:hover { background: var(--raise); color: var(--body) }
.railcards.on { background: var(--accent-tint); color: var(--accent-deep) }
.railsw { display: inline-flex }
.railsw:empty { display: none }
.railstack-t { white-space: nowrap }
.railnav a.navphone { display: none }
.rail.navopen .railnav a.navphone { display: block }
@media (max-width: 900px) {
  .navtoggle { display: inline-block }
  .railnav { display: none }
  .rail.navopen .railnav {
    display: flex; flex-direction: column; gap: 2px; margin: 0;
    position: absolute; top: var(--railh); left: 0; right: 0;
    max-height: calc(100vh - var(--railh)); overflow-y: auto;
    padding: 10px 16px 16px; background: var(--surface);
    border-bottom: 1px solid var(--line); box-shadow: 0 12px 24px -18px rgba(11,12,14,.45);
  }
  .rail.navopen .railnav a { padding: 10px 11px }
  .rail.navopen .navgroup-b { padding: 12px 11px 4px; font-family: var(--mono); font-size: var(--t-micro);
    letter-spacing: .09em; text-transform: uppercase; color: var(--faint); pointer-events: none }
  .rail.navopen .navgroup-b .navcv { display: none }
  .rail.navopen .navgroup-p a { padding-left: 11px }
}
.sheetreset { display: none }
/* Phone: logo, Menu, account and Start over did not fit once a balance
   appeared, and the page scrolled sideways. The balance and Start over move
   out of the rail; Start over lives at the foot of the Menu sheet. */
@media (max-width: 640px) {
  .railpts, #resetBtn { display: none !important }
  .rail.navopen .sheetreset { display: block; align-self: flex-start; margin-top: 10px }
}
/* Once a balance appears in the rail, the logo and the buttons have too little
   room left and both break mid-word ("kaunsacard / ?", "Start / over"). Tighten
   the gutter and forbid the wrap rather than let the header fold. */
@media (max-width: 640px) {
  .rail { padding: 0 16px; gap: 10px }
  .logo, .railbtn, .railpts { white-space: nowrap }
  .railpts { font-size: var(--t-sm) }
  /* The stacked card swatches are decoration; the balance beside them is not.
     On a phone the swatches are what gets dropped, so "Start over" still fits. */
  .railcards { display: none }
}
/* ================= TAB BODY =================
   A panel change gets a short opacity fade and nothing else. No translate, no
   blur, no scroll: the heading and the tabs must not move under the cursor. */
.tabbody { transition: opacity 150ms linear }
.tabbody.fading { opacity: 0 }
@media (prefers-reduced-motion: reduce) { .tabbody { transition: none } }

/* Start over, armed: the second click is the destructive one */
/* ================= ARMED: a destructive action's second click =================
   Promoted from .railbtn.arm on 22 Sep once a second surface (the admin panel)
   needed the same thing. One pattern, so "about to do something irreversible"
   looks identical wherever it appears, and a change here moves every surface.
   Native confirm() is deliberately not used anywhere: it blocks the page and
   reads as a browser warning rather than as part of the product. */
.arm, .railbtn.arm, .btn.arm {
  background: var(--clay); border-color: var(--clay); color: var(--surface);
}
.btn.quiet.arm { background: var(--clay); color: var(--surface) }

/* ================= CONFIRMED: something worked =================
   The stylesheet had .warn for bad news and nothing for good. Both the account
   page and the admin panel needed to say "that worked", so it lives here
   rather than twice. Mirrors .warn exactly, in mint. */
.ok {
  margin-top: 4px; font-size: var(--t-sm); line-height: 1.6; color: var(--mint);
  background: var(--mint-tint); border: 0; border-left: 2px solid var(--mint);
  border-radius: 0; padding: 10px 14px;
}
.ok b { font-weight: 600 }

/* ================= PAGE STRUCTURE =================
   Cool ground, white surfaces, hairline separation, soft elevation where it
   earns its keep. */

.rail { border-bottom: 1px solid var(--line) }
.rail.stuck { border-bottom-color: var(--line) }

/* the spine is a top stepper now; the stage is the page */
@media (min-width: 901px) {
  .vhead h2 { font-size: clamp(30px, 3.8vw, 44px) }
  .vhead.vhead-tool h2 { font-size: clamp(23px, 2.2vw, 29px) }
}

/* section heads read as printed heads: label, headline, rule to the margin */
.vhead { border-bottom: 1px solid var(--line); padding-bottom: 20px }

/* the answer panel is the darkest thing on the screen */
.ans { position: relative }

/* the live node keeps the only halo on the page, and it is tight */
.sstep.live .snode { box-shadow: 0 0 0 4px var(--glow) }

@media (max-width: 900px) {
  body { background-size: 26px 26px }
  .vhead { padding-bottom: 16px }
}

/* ================= ACCESS GATE =================
   Never replaces a page. Sits under real, working content so a visitor always
   sees what the thing does before being asked to pay for it. */
.gate {
  margin-top: 14px; border: 1px solid var(--line); border-radius: var(--r-lg);
  background: var(--surface); padding: 20px 22px;
  background-image: linear-gradient(180deg, color-mix(in srgb, var(--accent, #635BFF) 4%, transparent), transparent 70px);
}
.gate-h {
  display: flex; align-items: center; gap: 9px;
  font-family: var(--mono); font-size: var(--t-micro); letter-spacing: .1em;
  text-transform: uppercase; color: var(--accent, #635BFF);
}
.gate-lock {
  width: 11px; height: 11px; border-radius: 2px; flex: none;
  border: 1.6px solid currentColor; border-top-width: 5px; box-sizing: border-box;
}
.gate-count {
  margin-left: auto; color: var(--faint); letter-spacing: .06em; text-transform: none;
}
.gate-what { font-size: var(--t-lead); font-weight: 500; margin-top: 11px; letter-spacing: -.01em }
.gate-act { display: flex; gap: 9px; flex-wrap: wrap; margin-top: 15px }
.gate-free {
  font-size: var(--t-sm); color: var(--faint); line-height: 1.6; margin-top: 14px;
  padding-top: 13px; border-top: 1px solid var(--line);
}
@media (max-width: 720px) { .gate-act .btn { flex: 1 1 100% } }

/* a paid surface is shown in the rail with a padlock, never hidden - you
   cannot choose to want something you do not know exists */
.railnav a.locked { color: var(--faint) }
.railnav a .navlock {
  display: inline-block; width: 8px; height: 7px; margin-left: 5px;
  border: 1.4px solid currentColor; border-radius: 1px;
  border-top-width: 4px; box-sizing: border-box; opacity: .75;
  vertical-align: middle;
}

/* the account area sits apart from the content surfaces */
.railacct { display: flex; gap: 2px; margin-left: 6px }
.railacct a {
  font-size: var(--t-sm); color: var(--dim); text-decoration: none;
  padding: 6px 11px; border-radius: var(--r-sm); max-width: 190px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  transition: background 200ms var(--ease-out), color 200ms var(--ease-out);
}
.railacct a:hover { background: var(--raise); color: var(--body) }
.railacct a.on { background: var(--deep); color: var(--surface) }
@media (max-width: 900px) { .railacct a { max-width: 110px } }

/* ================= NAV GROUP =================
   Eleven flat entries in the rail was too many. Surfaces that answer the same
   question sit under one word, and the group reads as current when any child
   is - so you can see where you are without opening it. */
.navgroup { position: relative; display: inline-flex }
.navgroup-b {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: var(--t-sm); font-family: var(--sans); color: var(--dim);
  background: none; border: 0; padding: 6px 11px; border-radius: var(--r-sm);
  transition: background 200ms var(--ease-out), color 200ms var(--ease-out);
}
.navgroup-b:hover { background: var(--raise); color: var(--body) }
.navgroup-b.on { color: var(--body); font-weight: 500 }
.navcv {
  width: 6px; height: 6px; flex: none;
  border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor;
  transform: rotate(45deg) translate(-1px, -1px);
  transition: transform 260ms var(--ease-out); opacity: .7;
}
.navgroup.open .navcv { transform: rotate(-135deg) translate(-1px, -1px) }

.navgroup-p {
  position: absolute; top: calc(100% + 6px); left: 0; z-index: 50;
  display: flex; flex-direction: column; min-width: 160px;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-md); padding: 4px;
  box-shadow: 0 6px 18px -12px rgba(11,12,14,.45);
  opacity: 0; transform: translateY(-4px); pointer-events: none;
  transition: opacity 200ms var(--ease-out), transform 200ms var(--ease-out);
}
.navgroup.open .navgroup-p { opacity: 1; transform: none; pointer-events: auto }
.navgroup-p a { display: block; padding: 8px 11px; white-space: nowrap }

@media (max-width: 900px) {
  .navgroup-p { position: static; opacity: 1; transform: none; pointer-events: auto;
    box-shadow: none; border: 0; padding: 0; min-width: 0 }
  .navgroup { flex-direction: column; align-items: flex-start }
}

/* A reference surface has no stepper, so the page starts where the content
   does rather than after 75px of somebody else's progress bar. */
.spine[hidden] { display: none }
body.no-thread .shell { padding-top: 22px }

/* ================= AWARD ROWS =================
   One award as a disclosure row: partner + cabin, title, price on the right,
   and labelled fact blocks inside. Shared by Sweet spots and Plan a trip so
   an award reads the same wherever it appears (moved from sweet-spots.js). */
/* one sweet spot in full (index headline + partner page) */
/* One joined list, not a stack of separate cards: the rows are the same
   kind of thing and read as a table. Two classes to beat .disc. */
.ss-hlist { margin-top: 12px; border: 1px solid var(--line); border-radius: var(--r-lg);
  background: var(--surface); box-shadow: var(--shadow-soft); overflow: hidden }
.ss-hlist .ss-h { margin: 0; border: 0; border-top: 1px solid var(--line); border-radius: 0; box-shadow: none }
.ss-hlist .ss-h:first-child { border-top: 0 }
.ss-hbar { display: flex; align-items: center; gap: 12px; padding: 13px 18px }
.ss-htitle { margin-top: 3px; font-size: var(--t-base); font-weight: 700; color: var(--body); line-height: 1.4 }
.ss-hmeta { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; min-width: 0 }
.ss-hpartner { font-size: var(--t-micro); font-weight: 700; letter-spacing: .05em;
  text-transform: uppercase; color: var(--faint) }
.ss-hmore { display: inline-block; margin-top: 13px; font-size: var(--t-sm); font-weight: 600;
  color: var(--accent-deep); text-decoration: none }
.ss-hmore:hover { text-decoration: underline }
.ss-pill {
  display: inline-block; white-space: nowrap; padding: 2px 8px; font-size: var(--t-micro); font-weight: 700; text-transform: uppercase;
  letter-spacing: .03em; border-radius: 999px; background: var(--raise); color: var(--dim); vertical-align: middle;
}
.ss-pill.premium { background: var(--accent-tint); color: var(--accent-deep) }
.ss-hprice { font-family: var(--mono); font-size: var(--t-lead); color: var(--body); text-align: right; flex: none }
.ss-hprice .unit { font-size: var(--t-micro); color: var(--faint); font-weight: 500; font-family: var(--sans) }
.ss-hprice .sub { display: block; margin-top: 4px; font-size: var(--t-micro); color: var(--faint); font-weight: 400 }
/* .discbox .pad in app.css is a two-class selector and beats a bare
   .ss-hbody, so this override silently did nothing and the body ran
   edge to edge while the title stayed indented. Matched specificity. */
.discbox .pad.ss-hbody { padding: 0 18px 16px }
.ss-hbody { font-size: var(--t-sm); color: var(--dim); line-height: 1.6 }
/* Each kind of fact gets a label and its own block, separated by a rule.
   Five kinds of information as one run of paragraphs is what made this
   unreadable - the reader could not tell a condition from the evidence. */
.ss-blk { margin-top: 13px; padding-top: 12px; border-top: 1px solid var(--line) }
.ss-blk:first-child { margin-top: 4px; padding-top: 0; border-top: 0 }
.ss-k { font-family: var(--mono); font-size: var(--t-micro); letter-spacing: .09em;
  text-transform: uppercase; color: var(--faint); margin-bottom: 6px }
.ss-kn { color: var(--dim) }
.ss-p { color: var(--body); line-height: 1.6 }
.ss-blk .ss-src { margin-top: 9px }
/* A withheld price, shaped like a price. */
.ss-teaser { display: flex; align-items: center; gap: 14px; padding: 13px 18px;
  border-top: 1px solid var(--line) }
.ss-teaser:first-child { border-top: 0 }
/* .grow only stretches inside .discbar; a teaser is not one, so the
   withheld price sat against the title instead of in the price column. */
.ss-teaser .grow { flex: 1; min-width: 0 }
.ss-hprice.locked { flex: none }
.ss-hprice.locked .lockw { font-family: var(--mono); font-size: var(--t-micro);
  letter-spacing: .08em; text-transform: uppercase; color: var(--faint);
  border: 1px dashed var(--line); border-radius: var(--r-sm); padding: 3px 8px }
.ss-reach { margin-top: 9px; font-weight: 600; color: var(--mint) }
.ss-reach.pending, .ss-reach.miss { color: var(--dim); font-weight: 500 }
.ss-routes { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 9px }
.ss-routechip { background: var(--raise); border-radius: 6px; padding: 3px 9px; font-size: var(--t-micro); font-weight: 600; color: var(--body) }
.ss-src { margin-top: 11px; padding-top: 11px; border-top: 1px solid var(--line); font-size: var(--t-xs); color: var(--faint) }
@media (max-width: 640px) {
  /* Phone: the price column squeezed the spot into a 90px strip. The
     text takes the full width and the price sits under it. Two
     classes to beat .discbar's flex. */
  .discbar.ss-hbar { display: grid; grid-template-columns: auto auto minmax(0, 1fr);
    column-gap: 10px; row-gap: 6px; align-items: start; padding: 13px 14px }
  .ss-hbar .cv, .ss-hbar .kcmark { margin-top: 2px }
  .ss-hbar .ss-hprice { grid-column: 3; text-align: left }
}

/* ================= SECTIONS =================
   A labelled section inside a page: heading left, a count or aside right.
   (moved from sweet-spots.js; shared with Plan a trip) */
.vsec { margin-top: 26px }
.vsec-h {
  display: flex; align-items: baseline; justify-content: space-between; gap: 10px;
  font-family: var(--display); font-size: var(--t-h3); font-weight: 700; letter-spacing: -.01em;
}
.vsec-aside { font-family: var(--sans); font-size: var(--t-sm); font-weight: 500; color: var(--faint) }
.ss-pill.go { background: var(--mint-tint); color: var(--mint) }

/* ================= PLAN A TRIP =================
   The question (where, one way or back, how many), then award rows. Each row
   says in one line which balances pay for it; inside, one row per balance. */
.tripq { display: grid; grid-template-columns: minmax(0, 1fr) 190px 210px; gap: 14px; align-items: end;
  margin-bottom: 16px; padding: 16px; border: 1px solid var(--line); border-radius: var(--r-lg);
  background: var(--surface); box-shadow: var(--shadow-soft) }
.tq-route { display: grid; grid-template-columns: minmax(0, 1fr) 36px minmax(0, 1fr); gap: 8px; align-items: end; min-width: 0 }
.tripq .seg { height: 48px }
.tripq .segs { grid-template-columns: repeat(4, minmax(0, 1fr)) }
.tripq .segs.tq2 { grid-template-columns: repeat(2, minmax(0, 1fr)) }
.tq-swap { height: 48px; border: 1px solid var(--line); border-radius: var(--r-md); background: var(--surface);
  color: var(--dim); font-size: var(--t-lead); cursor: pointer; transition: border-color 160ms var(--ease-out), color 160ms var(--ease-out) }
.tq-swap:hover { border-color: var(--line-hover); color: var(--body) }
.tq-swap:active { transform: scale(.97) }
.tq-pay { margin-top: 5px; font-size: var(--t-xs); color: var(--dim); line-height: 1.5 }
.tq-pay b { color: var(--body); font-weight: 600 }
.tq-plus { color: var(--faint); padding: 0 2px }
.tq-fund { display: grid; gap: 0; border: 1px solid var(--line); border-radius: var(--r-md); overflow: hidden }
.tq-frow { display: flex; align-items: center; gap: 10px; padding: 9px 12px; border-top: 1px solid var(--line); background: var(--surface) }
.tq-frow:first-child { border-top: 0 }
.tq-frow .grow { flex: 1; min-width: 0; color: var(--body); font-weight: 600 }
.tq-fr { display: block; margin-top: 2px; font-size: var(--t-xs); font-weight: 400; color: var(--faint) }
.tq-fv { flex: none; text-align: right; color: var(--body) }
.tq-fu { display: block; font-size: var(--t-micro); color: var(--faint) }
.tq-warn { margin-top: 9px; font-size: var(--t-sm); color: var(--dim) }
.tq-spare { margin-top: 9px; font-size: var(--t-sm); color: var(--mint) }
.ss-p.tq-tip { margin-top: 4px; color: var(--dim) }
@media (max-width: 900px) {
  .tripq { grid-template-columns: 1fr 1fr }
  .tripq .tq-route { grid-column: 1 / -1 }
}
@media (max-width: 520px) {
  .tripq { grid-template-columns: 1fr; padding: 14px }
  .tripq .seg { height: 40px }
  .tq-route { grid-template-columns: minmax(0, 1fr) 36px }
  .tq-route > .fld:last-child { grid-column: 1 / 2 }
  .tq-swap { grid-row: 1 / 3; grid-column: 2; align-self: center; height: 36px }
}

/* a long programme name in a picker ends in an ellipsis instead of being cut mid-word */
.combo .tfc-input { text-overflow: ellipsis; white-space: nowrap; overflow: hidden }

/* the opened trip row: one saving line, pay-with, short notes, one action row,
   then a folded "other options and source" */
.tq-sum { font-size: var(--t-base); color: var(--dim); margin: 2px 0 12px; line-height: 1.5 }
.tq-sum b { color: var(--body); font-weight: 700 }
.tq-sum .tq-save { color: var(--mint) }
.tq-notes { margin: 10px 0 0; padding-left: 18px; font-size: var(--t-sm); color: var(--dim); line-height: 1.55 }
.tq-notes li + li { margin-top: 2px }
.tq-acts { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 10px; margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--line) }
.tq-savedlink { font-size: var(--t-sm); color: var(--accent-deep) }
.tq-tip2 { flex-basis: 100%; font-size: var(--t-sm); color: var(--faint) }
.ss-hbody .disc.tq-more { margin-top: 12px; box-shadow: none }
.ss-hbody .disc.tq-more .discbar { padding: 10px 14px; font-size: var(--t-sm) }
.ss-hbody .disc.tq-more .discbox .pad { padding: 0 14px 12px }

/* the three values of the points just earned, under the answer figure */
.ans-worth { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 8px; padding: 12px 28px 16px;
  border-top: 1px solid var(--ans-rule); font-size: var(--t-sm); color: var(--ans-dim); line-height: 1.5 }
.ans-worth-k { flex-basis: 100%; font-family: var(--mono); font-size: var(--t-micro); letter-spacing: .08em; text-transform: uppercase; color: var(--ans-faint) }
.ans-worth b { color: var(--ans-strong); font-weight: 600 }
.ans-worth i { font-style: normal; color: var(--ans-faint) }
@media (max-width: 720px) { .ans-worth { padding: 12px 22px 14px } }
