/* ============================================================================
   Condy — design system layer
   ----------------------------------------------------------------------------
   Ported 2026-09-14 from the Claude Design project
   "Cards restructured for cash stops" (b09a32c9-69bd-4d7a-8e9d-922adafe6291),
   files: handoff/tokens.css, handoff/motion.css, and the roadmap + hero
   background as built in `Condy Homepage.dc.html`.

   Loaded AFTER styles.css, so everything here wins on source order without
   needing specificity games.

   One deliberate difference from the source. In the Design canvas every card
   style is an inline attribute (a DC authoring rule), so the original had to
   fight its own markup with `!important` on each state rule — the file says so
   in its comments. Here the card styles are real CSS, so the state rules win
   on source order alone and every one of those `!important`s is gone.

   Structure:
     1. Token additions        4. Hero background
     2. Motion layer           5. The path (roadmap)
     3. Buttons                6. Reduced motion + responsive
   ========================================================================= */

/* --- 1. Token additions --------------------------------------------------- */
/* Additions only. Nothing here overrides a colour that styles.css already
   defines; the names that look new are the semantic money/points families. */
:root {
  /* Points. --sun (#e9a13b) on --sun-wash is ~1.9:1 and fails as text — these
     are the readable text colours for the warm/points family. */
  --warm-ink:    #8a5a14;   /* 6.0:1 on --sun-wash */
  --warm-line:   #f0d9ac;

  /* Money. Payout amounts and cash chips are GREEN, not brand orange: orange
     means "Condy" (hero, road, progress), green means "cash to you". */
  --money:       #2f7a52;   /* 4.9:1 on white */
  --money-deep:  #25603f;   /* 6.4:1 on --money-wash */
  --money-wash:  #eaf3ed;
  --money-line:  #c9e0d3;

  /* Warm-tinted elevation, never grey. */
  --shadow-1: 0 1px 2px rgba(36,26,18,.05), 0 8px 24px -12px rgba(156,63,19,.18);
  --shadow-2: 0 2px 4px rgba(36,26,18,.06), 0 18px 40px -18px rgba(156,63,19,.26);

  /* One easing, three durations. */
  --ease:   cubic-bezier(.22,.61,.36,1);
  --d-fast: 140ms;   /* hover, press, focus */
  --d-base: 320ms;   /* card weighting, state change */
  --d-slow: 520ms;   /* entrances, reveals */

  /* Roadmap geometry, so scroll length is tunable without touching JS.
     --stops MUST equal content.js flow.stops.length; main.js asserts it. */
  --stops:   6;
  --step-vh: 40;
}

/* --- 2. Motion layer ------------------------------------------------------ */
/* Transform and opacity only. Nothing pulses, and nothing waits for JS to
   become readable. */

@keyframes cd-rise { from { opacity:0; transform:translate3d(0,10px,0) } to { opacity:1; transform:none } }
.cd-enter { animation: cd-rise var(--d-slow) var(--ease) both }
.cd-d1 { animation-delay: 60ms }
.cd-d2 { animation-delay: 120ms }
.cd-d3 { animation-delay: 180ms }
.cd-d4 { animation-delay: 240ms }

/* Scroll reveals. The hidden state is gated on html.cd-anim, which the driver
   sets only after its first successful tick — so if the driver ever throws,
   nothing is hidden and the page reads as a plain document. Content can never
   be blanked by a JS error. */
.cd-reveal { transition: opacity var(--d-slow) var(--ease), transform var(--d-slow) var(--ease) }
html.cd-anim:not(.cd-rm) .cd-reveal { opacity:0; transform:translate3d(0,12px,0) }
html.cd-anim:not(.cd-rm) .cd-reveal.is-in { opacity:1; transform:none }

/* The scroll hint is the only continuous loop on the page, and it earns that
   because it carries DIRECTION rather than urgency: a 3px drift over 2.6s, no
   scale, no opacity flash, no colour change. It fades the moment the path
   completes. Anything faster or larger starts reading as a pitch device —
   which brand-voice.md rules out. */
@keyframes cd-nudge { 0%,100% { transform:translate3d(0,-3px,0) } 50% { transform:translate3d(0,3px,0) } }
/* The explicit size is load-bearing, not cosmetic: this is a viewBox="0 0 24 24"
   SVG, so without width/height it expands to the full container width at a 1:1
   ratio (~1128px tall) and starves every flex sibling in the pinned column —
   the summary card collapses to its borders and the path frame to zero.
   Same failure as .cd-road: both were inline styles in the Design source. */
.cd-arrow { display:block; width:56px; height:56px; margin-inline:auto; overflow:visible;
            animation: cd-nudge 2600ms var(--ease) infinite }
.cd-railwrap { padding-top:10px }
.cd-hint  { transition: opacity var(--d-base) var(--ease) }
html.cd-complete .cd-hint { opacity:0 }

/* --- 3. Buttons ----------------------------------------------------------- */
.cd-btn {
  display:inline-flex; align-items:center; gap:10px;
  padding:15px 26px; border-radius:var(--radius);
  font:600 15px/1 var(--font); cursor:pointer;
  transition: transform var(--d-fast) var(--ease), background var(--d-fast) linear,
              border-color var(--d-fast) linear, box-shadow var(--d-fast) linear;
}
.cd-btn--primary { background:var(--brand); color:#fff; box-shadow:var(--shadow-2) }
.cd-btn--primary:hover { background:var(--brand-deep); color:#fff }
.cd-btn--ghost { border:1px solid var(--line); background:#fff; color:var(--ink) }
.cd-btn--ghost:hover { background:var(--bg-tint); border-color:#e0cdb8; color:var(--ink) }
.cd-btn:hover { transform:translate3d(0,-1px,0) }
.cd-btn:active { transform:translate3d(0,0,0) }
.cd-btn:focus-visible { outline:2px solid var(--brand); outline-offset:3px }
.cd-btn .cd-ar { display:inline-block; transition:transform var(--d-fast) var(--ease) }
.cd-btn:hover .cd-ar { transform:translate3d(2px,0,0) }

/* --- 4. Hero background --------------------------------------------------- */
/* Two layers drifting in opposite directions on long, unequal periods so they
   never resolve into a visible beat. Transform only — no opacity, no scale
   pulse, no colour change. At this speed it reads as depth rather than as
   something trying to get your attention. Both layers are scaled slightly past
   the frame so the drift never exposes an edge. */
@keyframes cd-drift-a {
  0%,100% { transform:scale(1.14) translate3d(-3.4%,1.4%,0) }
  50%     { transform:scale(1.14) translate3d(3.4%,-1.8%,0) }
}
@keyframes cd-drift-b {
  0%,100% { transform:scale(1.16) translate3d(4.2%,-2%,0) }
  50%     { transform:scale(1.16) translate3d(-3.6%,2.2%,0) }
}

.cd-hero { position:relative; overflow:hidden; padding:96px 24px 104px }
.cd-hero-inner { position:relative; max-width:var(--max); margin:0 auto; text-align:center }

.cd-wash {
  position:absolute; inset:0; pointer-events:none; will-change:transform;
  animation: cd-drift-b 34s ease-in-out infinite;
  background:
    radial-gradient(120% 78% at 50% -12%, var(--bg-tint) 0%, rgba(253,248,243,0) 62%),
    radial-gradient(70% 52% at 12% 108%, var(--brand-wash) 0%, rgba(253,239,227,0) 70%),
    radial-gradient(60% 46% at 92% 96%, var(--sun-wash) 0%, rgba(253,243,226,0) 72%);
}
.cd-route {
  position:absolute; inset:0; width:100%; height:100%; pointer-events:none;
  opacity:.85; will-change:transform;
  animation: cd-drift-a 26s ease-in-out infinite;
  /* Masked out through the middle so the headline never sits on top of line
     work — the contrast has to hold without the type needing a scrim. */
  -webkit-mask-image: radial-gradient(58% 52% at 50% 46%, rgba(0,0,0,0) 38%, rgba(0,0,0,.55) 62%, #000 88%);
          mask-image: radial-gradient(58% 52% at 50% 46%, rgba(0,0,0,0) 38%, rgba(0,0,0,.55) 62%, #000 88%);
}
.cd-hero-rule {
  position:absolute; left:0; right:0; bottom:0; height:1px;
  background:linear-gradient(90deg, rgba(237,222,206,0) 0%, var(--line) 28%, var(--line) 72%, rgba(237,222,206,0) 100%);
}

/* Each span is one line by intent. The size cap is set so the LONGEST line
   ("Earn up to $400 for completing", ~30ch) still fits the 1120px container
   at desktop — a larger cap wraps it and strands "$400" on a line of its own,
   which breaks the sentence in the wrong place. Narrow screens wrap normally. */
.cd-h1 {
  margin:0 auto; max-width:min(100%, 1060px);
  font:600 clamp(40px,7.4vw,92px)/1.04 var(--font);
  letter-spacing:-.035em; text-wrap:balance;
}
/* DIRECT children only. A bare `.cd-h1 span` also catches the nested .cd-amt
   that wraps "$400", turning it into a block and forcing a line break either
   side of it — which splits the sentence as "Earn up to / $400 / for
   completing" even though the whole line fits. */
.cd-h1 > span { display:block }
.cd-h1 .cd-amt { color:var(--brand) }
.cd-h1 .cd-free { color:var(--brand) }
.cd-hero-actions { display:flex; gap:12px; justify-content:center; flex-wrap:wrap; margin-top:34px }
.cd-hero-note { margin:20px 0 0; font:400 14px/1.6 var(--font); color:var(--ink-soft) }

/* --- 5. The path ---------------------------------------------------------- */
/* Base (phone / no-JS / reduced motion) is a plain vertical list. Everything
   below that is a progressive enhancement gated on html.cd-js. */

.cd-flow { position:relative; background:var(--bg-tint); border-top:1px solid var(--line); border-bottom:1px solid var(--line) }
.cd-pin  { padding:0 24px; background-image:radial-gradient(#f0e2d2 1px, transparent 1px); background-size:26px 26px; background-position:center }
.cd-col  { max-width:var(--max); margin:0 auto; width:100% }

.cd-flow-head { display:flex; align-items:flex-end; justify-content:space-between; gap:20px; flex-wrap:wrap; padding:clamp(28px,5vw,48px) 0 14px }
.cd-flow-head h2 { margin:0; font:600 clamp(24px,3vw,34px)/1.1 var(--font); letter-spacing:-.03em }
.cd-counter { font:500 13px/1 var(--font); color:var(--ink-faint); letter-spacing:.04em }

/* The payoff carries its own title once the path completes, so the section
   heading steps aside instead of stacking a second one above it. Opacity only:
   the box keeps its space, so the pinned column never jumps, and the text stays
   in the accessibility tree for anyone reading the page with one. */
.cd-flow-head { transition:opacity 1.1s cubic-bezier(.16,1,.3,1), transform 1.1s cubic-bezier(.16,1,.3,1) }
html.cd-complete .cd-flow-head { opacity:0 }

/* The summary card. Pinned above the path; the payoff overlay grows INTO it
   rather than replacing it, so the end reads as the path merging into one
   result rather than as a different card appearing. */
.cd-sum {
  position:relative; z-index:3; display:flex; align-items:stretch;
  border:1px solid var(--line); border-radius:var(--radius-lg);
  background:#fff; box-shadow:var(--shadow-2); overflow:hidden;
}
.cd-sum-main { flex:1.4; min-width:0; padding:clamp(16px,2.4svh,26px) clamp(20px,2.4vw,30px) }
.cd-sum-side { flex:1; min-width:0; display:flex; flex-direction:column; justify-content:center; gap:10px;
  padding:clamp(16px,2.4svh,26px) clamp(20px,2.4vw,30px); border-left:1px solid var(--line); background:var(--bg-tint) }
.cd-label { font:500 12px/1 var(--font); letter-spacing:.1em; text-transform:uppercase; color:var(--ink-faint) }

/* The running total and the "+$X" sit on a shared baseline, so the badge reads
   as part of the number rather than as a floating notification. */
.cd-total-row { display:flex; align-items:baseline; gap:14px; flex-wrap:wrap; margin-top:8px }
.cd-total { font:600 clamp(30px,3.2vw,40px)/.92 var(--font); letter-spacing:-.045em; color:var(--money);
            transition:font-size var(--d-base) var(--ease) }

/* Transient growth marker. The driver writes the amount and restarts this
   animation on each absorb. Informational, not an urgency device: no scale
   bounce, no colour flash, no repeat — it states what was just added and
   leaves. 6px of drift is the whole movement. */
.cd-bump { font:600 clamp(17px,1.8vw,25px)/1 var(--font); letter-spacing:-.02em;
           color:var(--money); opacity:0; pointer-events:none }
@keyframes cd-bump-in {
  0%   { opacity:0; transform:translate3d(0,6px,0) }
  16%  { opacity:1; transform:none }
  70%  { opacity:1; transform:none }
  100% { opacity:0; transform:translate3d(0,-6px,0) }
}
.cd-bump.is-on { animation: cd-bump-in 1500ms var(--ease) both }
.cd-sum-row { display:flex; align-items:baseline; justify-content:space-between; gap:12px }
.cd-sum-val { font:600 22px/1 var(--font); letter-spacing:-.02em; color:var(--ink) }
.cd-sum-val--pts { color:var(--warm-ink) }
.cd-bar { height:6px; border-radius:var(--radius); background:var(--bg-sunken); overflow:hidden }
.cd-bar i { display:block; height:100%; border-radius:var(--radius); background:var(--brand); transform-origin:0 50%; transform:scaleX(0); transition:transform var(--d-base) var(--ease) }

/* Resting opacity lives HERE, not inline: an inline opacity:0 would outrank
   any state rule and the payoff would never paint. */
/* Rebuilt 2026-09-15. Two faults in v1, both only visible in the completed
   state. The card's eyebrow and the section h2 above it read as two competing
   titles; and the six stops sat in a strip at the very foot of the card,
   leaving roughly 400px of empty gradient between the total and the footer.
   v2 gives the card ONE title of its own (the section h2 fades on completion,
   see html.cd-complete .cd-flow-head) and moves the stops into a ledger COLUMN
   beside the figures, which fills that space with the thing a reader actually
   wants there: what each stop paid.

   Rows are auto / minmax(0,1fr) / auto, so the middle row absorbs whatever
   height the pinned box has on the day. Nothing centres in dead space and
   nothing overflows a short viewport. */
.cd-payoff {
  position:absolute; inset:0; display:grid; grid-template-rows:auto minmax(0,1fr) auto;
  gap:clamp(14px,2vw,22px); padding:clamp(18px,2.6vw,34px); overflow:hidden;
  border-radius:calc(var(--radius-lg) - 1px);
  background:linear-gradient(115deg,#286b4e 0%,#2e7857 65%,#33815e 100%);
  color:#fff; pointer-events:none; opacity:0;
  transform:translate3d(0,16px,0);
  transition:opacity 1.4s cubic-bezier(.16,1,.3,1), transform 1.4s cubic-bezier(.16,1,.3,1);
  font-variant-numeric:tabular-nums;
}
.cd-payoff::before { content:""; position:absolute; inset:14px; border:1px solid #ffffff20; border-radius:16px; pointer-events:none }
html.cd-complete .cd-payoff { opacity:1; transform:none }

/* 1. One title, with the stop counter beside it as STATUS — a pill, so it
      cannot be misread as a second heading. */
.cd-payoff-top { display:flex; align-items:center; justify-content:space-between; gap:14px; flex-wrap:wrap }
.cd-payoff-title { margin:0; font:600 clamp(21px,2.5vw,32px)/1.05 var(--font); letter-spacing:-.03em; text-wrap:balance }
.cd-payoff-status { display:flex; align-items:center; gap:9px; padding:6px 13px 6px 7px; border:1px solid #ffffff33; border-radius:999px; font:500 11px/1 var(--font); letter-spacing:.1em; text-transform:uppercase; color:#dcece1 }
.cd-payoff-seal { width:22px; height:22px; display:grid; place-items:center; border-radius:50%; background:#f0e6cc; color:#25603f; font:400 12px/1 var(--font) }

/* 2. Figures left, every stop right. */
.cd-payoff-body { display:grid; grid-template-columns:minmax(0,1.05fr) minmax(0,1fr); gap:clamp(18px,2.6vw,36px); min-height:0 }
.cd-payoff-reward { display:flex; flex-direction:column; justify-content:space-between; gap:clamp(14px,2vw,24px); min-height:0 }
.cd-payoff-label { font:500 11px/1.3 var(--font); letter-spacing:.14em; text-transform:uppercase; color:#dcece1 }
.cd-payoff-total { display:flex; align-items:baseline; margin-top:8px; font:500 clamp(54px,7.4vw,108px)/.84 var(--font); letter-spacing:-.055em; color:#fff }
.cd-payoff-total > span { font-size:.51em; letter-spacing:-.04em; align-self:flex-start; padding-top:.08em; margin-right:.08em }
.cd-payoff-meta { margin-top:12px; font:400 clamp(12.5px,1.1vw,15px)/1.45 var(--font); color:#dcece1 }
.cd-payoff-cost { display:flex; align-items:baseline; gap:14px; flex-wrap:wrap; padding-top:14px; border-top:1px solid #ffffff33 }
.cd-payoff-cost .cd-payoff-label { flex:1 1 100% }
.cd-payoff-zero { font:500 clamp(36px,4.2vw,56px)/.9 var(--font); letter-spacing:-.05em; color:#f0e6cc }
.cd-payoff-note { font:400 14px/1.4 var(--font); color:#f0e6cc }

/* The ledger. One row per stop, each naming what the stop WAS — the strip it
   replaces showed six amounts and no reason for any of them. */
.cd-payoff-ledger { display:flex; flex-direction:column; min-height:0; padding:clamp(12px,1.4vw,18px); border:1px solid #ffffff33; border-radius:18px; background:#ffffff0f }
.cd-payoff-ledger > .cd-payoff-label { padding:0 6px clamp(6px,1vw,10px) }
.cd-payoff-list { display:flex; flex-direction:column; justify-content:space-between; flex:1; min-height:0; margin:0; padding:0; list-style:none }
.cd-payoff-row { display:grid; grid-template-columns:auto 1fr auto auto; align-items:center; gap:12px; padding:clamp(5px,.9vw,9px) 6px; border-top:1px solid #ffffff1f }
.cd-payoff-row:first-child { border-top:0 }
.cd-payoff-day { min-width:50px; font:500 12.5px/1 var(--font); letter-spacing:.04em; color:#dcece1 }
.cd-payoff-what { font:400 13px/1 var(--font); color:#ffffffd9 }
.cd-payoff-amt { font:600 clamp(15px,1.6vw,19px)/1 var(--font); letter-spacing:-.02em }
.cd-payoff-tick { width:14px; text-align:right; font:400 12px/1 var(--font); font-style:normal; color:#f0e6cc }

/* 3. The three "no"s, and the framing line compliance-rules.md asks for. */
.cd-payoff-bottom { display:flex; align-items:center; justify-content:space-between; gap:12px 26px; flex-wrap:wrap; padding-top:clamp(12px,1.6vw,18px); border-top:1px solid #ffffff33 }
.cd-payoff-checks { display:flex; flex-wrap:wrap; gap:10px 24px; font:400 14px/1.4 var(--font) }
.cd-payoff-checks span { display:flex; gap:8px; align-items:center }
.cd-payoff-checks i { font-style:normal; color:#e1d6b8 }
.cd-payoff-legal { margin:0; font:400 12.5px/1.5 var(--font); color:#dcece1; max-width:46ch }

/* The overlay only ever paints on the pinned desktop path (main.js `pinned()`),
   so these two are safety nets for odd boxes rather than the phone layout. */
@media (max-width:600px) {
  .cd-payoff-body { grid-template-columns:1fr; gap:18px }
  .cd-payoff-title { font-size:22px }
  .cd-payoff-zero { font-size:40px }
  .cd-payoff-checks { gap:10px 16px; font-size:12.5px }
  .cd-payoff-legal { font-size:11.5px; max-width:none }
  .cd-payoff-what { font-size:12px }
}
@media (min-width:601px) and (max-height:650px) {
  .cd-payoff { padding:20px 28px; gap:14px }
  .cd-payoff-zero { font-size:40px }
  .cd-payoff-row { padding-block:4px }
}

.cd-frame { position:relative; overflow:hidden; transition:opacity var(--d-base) var(--ease) }
.cd-track { display:flex; flex-direction:column; gap:20px; position:relative; padding:20px 0 }
.cd-node, .cd-railwrap { display:none }

/* The road MUST be taken out of flow. Its two SVGs are viewBox="0 0 100 600"
   with preserveAspectRatio="none"; in normal flow they resolve to their
   intrinsic aspect ratio and render ~7000px tall each, which pushes the track
   thousands of pixels down and collapses the summary card to its borders.
   These three rules were inline attributes in the Design source — dropping
   them during the port is what broke the layout. */
.cd-road { display:none; position:absolute; inset:0; pointer-events:none }
.cd-road svg { position:absolute; inset:0; width:100%; height:100%; overflow:visible }
.cd-fill { position:absolute; inset:0 }

.cd-card {
  width:100%; position:relative; display:flex; flex-direction:column;
  padding:22px 24px; border:1px solid var(--line); border-radius:var(--radius-lg);
  background:#fff; box-shadow:var(--shadow-1);
}
.cd-card-head { display:flex; align-items:flex-start; justify-content:space-between; gap:12px }
.cd-day { font:600 15px/1 var(--font); letter-spacing:.08em; text-transform:uppercase; color:var(--ink) }
.cd-chips { display:flex; gap:6px }
.cd-chip { padding:6px 11px; border-radius:var(--radius); font:600 12.5px/1 var(--font) }
.cd-chip--cash { background:var(--money-wash); color:var(--money-deep) }
.cd-chip--pts  { background:var(--sun-wash);   color:var(--warm-ink) }
.cd-amts { margin-top:18px; display:flex; align-items:baseline; gap:14px; flex-wrap:wrap }
.cd-cash { font:600 clamp(46px,5.8vw,68px)/.92 var(--font); letter-spacing:-.045em; color:var(--money) }
.cd-pts  { font:600 26px/1 var(--font); letter-spacing:-.03em; color:var(--warm-ink) }

/* Desktop: the pinned, scroll-driven path. */
@media (min-width:860px) {
  html.cd-js:not(.cd-rm) .cd-flow { height:calc(100svh - 72px + (var(--stops) - 1) * var(--step-vh) * 1vh) }
  html.cd-js:not(.cd-rm) .cd-pin {
    position:sticky; top:0; height:100svh; display:flex; flex-direction:column;
    justify-content:center; overflow:hidden; padding-block:clamp(16px,4svh,48px);
  }
  html.cd-js:not(.cd-rm) .cd-col { display:flex; flex-direction:column; min-height:0; max-height:100% }
  html.cd-js:not(.cd-rm) .cd-flow-head { padding-top:clamp(6px,2svh,22px) }
  html.cd-js:not(.cd-rm) .cd-track { gap:clamp(30px,6svh,72px); padding:0 }
  html.cd-js:not(.cd-rm) .cd-mover { transform:translate3d(0,var(--flow-y,0px),0) }
  html.cd-js:not(.cd-rm) .cd-fill { clip-path:inset(0 0 var(--flow-rest,100%) 0) }
  html.cd-js:not(.cd-rm) .cd-row { display:grid; grid-template-columns:34% 32% 34%; align-items:center }
  html.cd-js:not(.cd-rm) .cd-left  .cd-card { grid-column:1; justify-self:start }
  html.cd-js:not(.cd-rm) .cd-right .cd-card { grid-column:3; justify-self:end }
  html.cd-js:not(.cd-rm) .cd-road { display:block }
  html.cd-js:not(.cd-rm) .cd-railwrap { display:block }

  /* Frame sizing lives HERE, never inline: an inline flex shorthand would
     outrank the complete-state collapse below, leaving the faded road holding
     space under the payoff card and starving the card's own flex-grow. */
  html.cd-js:not(.cd-rm) .cd-frame { flex:1 1 0%; min-height:0 }
  html.cd-js:not(.cd-rm) .cd-sum { margin-bottom:clamp(14px,2.5svh,26px) }
  html.cd-js:not(.cd-rm) .cd-card { min-height:0;
    transition:background var(--d-base) var(--ease), border-color var(--d-base) var(--ease),
               box-shadow var(--d-base) var(--ease), opacity var(--d-base) var(--ease) }

  html.cd-js:not(.cd-rm) .cd-node {
    display:block; position:absolute; top:50%; width:20px; height:20px;
    border-radius:50%; background:var(--brand); border:4px solid var(--bg-tint);
    transform:translateY(-50%);
  }
  html.cd-js:not(.cd-rm) .cd-left  .cd-node { right:-11px }
  html.cd-js:not(.cd-rm) .cd-right .cd-node { left:-11px }
  html.cd-js:not(.cd-rm) .cd-row:last-child .cd-node { background:var(--brand-deep) }

  /* REACHED. The card inverts the moment the road's node crosses the hit line,
     so "the path got here" and "this money is yours" are the same event.
     Colour and border only — no transform, nothing that moves. */
  .cd-row[data-hit="true"] .cd-card {
    background:var(--money); border-color:var(--money-deep);
    box-shadow:0 2px 4px rgba(36,26,18,.06), 0 18px 40px -18px rgba(37,96,63,.42);
  }
  /* EVERY descendant, not a fixed depth: the payout amount is a direct child
     of the card while the label sits a level deeper, so a `> div > div` rule
     left the amount green-on-green and invisible. */
  .cd-row[data-hit="true"] .cd-card,
  .cd-row[data-hit="true"] .cd-card * { color:#fff }
  /* The chip INVERTS to a solid white ground with deep-green text (6.4:1). A
     translucent white ground cannot be fixed by tuning alpha — more white
     moves the ground toward the text colour, so contrast FALLS as alpha rises. */
  .cd-row[data-hit="true"] .cd-chip { background:#fff; color:var(--money-deep) }
  .cd-row[data-hit="true"] .cd-node { background:var(--money); border-color:var(--bg-tint) }

  /* The payoff ABSORBS the path: once the total lands, the road and remaining
     cards fade out entirely — leaving them on screen would read as "more steps
     ahead" when there are none. The frame keeps its layout box so the pin
     geometry never jumps; only opacity animates, and it is inert by then. */
  html.cd-complete .cd-sum,
  html.cd-settling .cd-sum { flex:1 1 auto; min-height:clamp(300px,52svh,520px) }
  html.cd-js.cd-complete:not(.cd-rm) .cd-col   { flex:1 1 0%; height:100% }
  html.cd-js.cd-complete:not(.cd-rm) .cd-frame { opacity:0; flex-grow:0; flex-basis:0; margin:0 }
  html.cd-js.cd-complete:not(.cd-rm) .cd-sum   { margin-bottom:0 }
  html.cd-js.cd-complete:not(.cd-rm) .cd-hint  { display:none }
  html.cd-complete .cd-railwrap { opacity:0 }

  /* Short viewports: drop the road gaps before dropping legibility. */
  @media (max-height:700px) {
    html.cd-js:not(.cd-rm) .cd-track { gap:24px }
  }
}

/* --- 5b. The ticker ------------------------------------------------------- */
/* A news-style strip between the hero and the path. This is the second
   continuous loop on a page whose design notes said there should only be one;
   it is here because the client asked for it directly. Kept as honest as a
   marquee can be: it states one fact and repeats it, with no countdown, no
   scarcity and no colour flashing. */
.cd-ticker {
  position:relative; overflow:hidden;
  background:var(--brand); color:#fff;
  border-top:1px solid var(--brand-deep); border-bottom:1px solid var(--brand-deep);
  padding:24px 0;
  /* One spacing value for the whole strip. Every gap in the loop — phrase to
     arrow, arrow to phrase — is exactly this, which is what a news ticker
     looks like: an even beat with the separator centred between phrases. */
  --tick-gap: clamp(30px,3.2vw,46px);
}
/* width:max-content lets the track be as wide as its content instead of being
   constrained to the parent, which is what makes the -50% loop exact. */
.cd-tick-track {
  display:flex; width:max-content;
  animation: cd-marquee 26s linear infinite;
  will-change:transform;
}
.cd-tick-group { display:flex; flex:0 0 auto }
/* The rhythm: half a gap of padding on each side of the item means two
   neighbouring items contribute one full gap between them, matching the gap
   inside the item. Keep `gap` and `padding-inline` in that 1:½ ratio or the
   arrow drifts back towards one of its two phrases. */
.cd-tick-item {
  display:inline-flex; align-items:center; gap:var(--tick-gap);
  padding-inline:calc(var(--tick-gap) / 2); white-space:nowrap;
  font:700 clamp(19px,1.9vw,24px)/1 var(--font); letter-spacing:.14em;
}
/* letter-spacing also applies after the LAST glyph of each span, so the arrow
   and the phrase each carry ~.14em of invisible trailing space that the
   padding maths cannot see. Cancelling it is what makes the beat measure even
   rather than merely close. */
.cd-tick-mark, .cd-tick-text { margin-inline-end:-.14em }
.cd-tick-mark { opacity:.72; font-size:1.1em; line-height:1 }
/* Exactly one group-width of travel: the duplicate group arrives where the
   first started, so there is no visible seam or reset. */
@keyframes cd-marquee {
  from { transform:translate3d(0,0,0) }
  to   { transform:translate3d(-50%,0,0) }
}
/* One readable copy for screen readers; the visible track is aria-hidden so the
   phrase is announced once, not sixteen times. */
.cd-tick-sr {
  position:absolute; width:1px; height:1px; margin:-1px; padding:0;
  overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; border:0;
}

/* --- 6. What's coming next ----------------------------------------------- */
/* Two cards on a sunken ground. Read as a preview, not as disabled controls:
   full-strength type and a real icon, with the dashed badge carrying the
   "not yet". Muting the whole block would make the most interesting thing on
   the page look broken. */
.cd-up-wrap { padding:clamp(56px,8vw,92px) 24px; background:var(--bg-tint);
              border-top:1px solid var(--line); border-bottom:1px solid var(--line) }
.cd-up-inner { max-width:var(--max); margin:0 auto }

.cd-up-head { text-align:center; max-width:58ch; margin:0 auto clamp(28px,4vw,42px) }
.cd-up-eyebrow {
  display:inline-block; margin-bottom:14px; padding:6px 13px;
  border-radius:var(--radius); background:var(--brand-wash);
  font:600 12px/1 var(--font); letter-spacing:.1em; text-transform:uppercase;
  color:var(--brand-deep);
}
.cd-up-head h2 { margin:0; font:600 clamp(26px,3.4vw,40px)/1.12 var(--font); letter-spacing:-.03em }
.cd-up-head p  { margin:14px auto 0; font:400 16px/1.6 var(--font); color:var(--ink-soft) }

.cd-up-grid { display:grid; grid-template-columns:repeat(2,1fr); gap:clamp(16px,2vw,24px) }
.cd-up-card {
  display:flex; flex-direction:column;
  padding:clamp(24px,2.8vw,34px);
  border:1px solid var(--line); border-radius:var(--radius-lg);
  background:#fff; box-shadow:var(--shadow-1);
  transition:transform var(--d-base) var(--ease), box-shadow var(--d-base) var(--ease),
             border-color var(--d-base) var(--ease);
}
.cd-up-card:hover { transform:translate3d(0,-2px,0); box-shadow:var(--shadow-2); border-color:#e0cdb8 }
.cd-up-top { display:flex; align-items:center; justify-content:space-between; gap:14px; margin-bottom:20px }
.cd-up-icon {
  display:grid; place-items:center; width:46px; height:46px; flex:0 0 auto;
  border-radius:14px; background:var(--brand-wash); color:var(--brand-deep);
}
/* Explicit size, same lesson as .cd-arrow and .cd-road: an unsized viewBox SVG
   expands to its container and wrecks the layout around it. */
.cd-up-icon svg { display:block; width:23px; height:23px }
.cd-up-card h3 { margin:0; font:600 clamp(19px,2vw,23px)/1.25 var(--font); letter-spacing:-.02em; color:var(--ink) }
.cd-up-card p  { margin:10px 0 0; font:400 15px/1.62 var(--font); color:var(--ink-soft) }

/* The "not yet" signal. Dashed, quiet, and never a countdown or a scarcity
   device: brand-voice.md rules those out and this audience reads them as a tell. */
.cd-soon {
  flex:0 0 auto; padding:8px 13px; border-radius:var(--radius);
  border:1px dashed var(--line); background:var(--bg-tint);
  font:600 11.5px/1 var(--font); letter-spacing:.07em; text-transform:uppercase;
  color:var(--ink-faint); white-space:nowrap;
}

@media (max-width:720px) {
  .cd-up-grid { grid-template-columns:1fr }
}

/* --- 7. Reduced motion ---------------------------------------------------- */
/* Total stop. The driver reads the same query and drops the pin, so the page
   becomes a plain scrolling document rather than a broken pinned one. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior:auto }
  .cd-wash, .cd-route, .cd-arrow { animation:none }
  .cd-enter { animation:none; opacity:1; transform:none }
  .cd-reveal { opacity:1; transform:none; transition:none }
  /* The growth marker is motion by definition, so it simply does not appear.
     The total's size step still carries the same information. */
  .cd-bump, .cd-bump.is-on { animation:none; opacity:0 }
  /* The ticker stops completely and centres one copy, rather than freezing
     mid-scroll with a half-cut phrase at each edge. */
  .cd-tick-track { animation:none; width:100%; justify-content:center }
  .cd-tick-track .cd-tick-group:nth-child(2) { display:none }
  .cd-tick-group { flex-wrap:wrap; justify-content:center }
}

/* September roadmap refresh: warm paper, engraved contours, gold reward light. */
.cd-hero { background:#fffdf8; isolation:isolate; padding-block:104px 84px }
.cd-wash { animation:none; background:radial-gradient(ellipse at 50% 32%,#fff 15%,#fffdf8aa 55%,transparent 75%),linear-gradient(135deg,#f1e4c8 0%,#fffdf9 36%,#fffdf9 65%,#eddcb9 100%) }
.cd-hero::before,.cd-hero::after { content:""; position:absolute; width:760px; height:760px; border-radius:45%; border:1px solid #b08b4433; box-shadow:0 0 0 24px #fff8,0 0 0 25px #b08b4426,0 0 0 58px #fff6,0 0 0 59px #b08b4422,0 0 0 104px #fff5,0 0 0 105px #b08b441a; pointer-events:none; transform:rotate(-28deg) }
.cd-hero::before { left:-590px; top:-410px }
.cd-hero::after { right:-590px; bottom:-490px }
.cd-route { opacity:.4; animation:none }
.cd-hero-inner { z-index:1 }
.cd-flow { background:#f8f5ed }
.cd-pin { position:relative; isolation:isolate; background:radial-gradient(ellipse at 50% 0%,#fffaf0 0%,transparent 65%),linear-gradient(100deg,#eee7d655,transparent 35%,transparent 65%,#ede6d455) }
.cd-pin::before { content:""; position:absolute; inset:0; z-index:-1; pointer-events:none; opacity:.48; background:repeating-radial-gradient(ellipse at -25% 55%,transparent 0 68px,#beaa7d30 69px 70px,transparent 71px 130px); mask-image:linear-gradient(90deg,#000,transparent 38%,transparent 62%,#000) }
.cd-flow-head h2 { font-weight:500; letter-spacing:-.045em }
.cd-counter { color:#786a52 }
.cd-sum { isolation:isolate; border-color:#dacfb9; background:#fffefb; box-shadow:0 3px 6px #57441d06,0 18px 45px -28px #57441d55 }
.cd-sum-main,.cd-sum-side { position:relative; z-index:2; padding-bottom:32px }
.cd-sum-side { background:transparent; border-left-color:#e8e1d2 }
.cd-label { font-size:10px; color:#76664b; letter-spacing:.13em }
.cd-total { font-weight:500 }
.cd-bar { height:3px; background:#e9e1d0 }
.cd-bar i { background:linear-gradient(90deg,#947037,#d6b360) }
.cd-sum-val--pts { font:500 10px/1 var(--font); padding:6px 9px; color:#7b6c50; border:1px solid #ded5c3; border-radius:30px; text-transform:uppercase; letter-spacing:.06em }
.cd-card { padding:22px 24px 16px; border-radius:18px; border-color:#e0d7c6; background:linear-gradient(125deg,#fff 45%,#faf7ef); box-shadow:0 2px 3px #46361a04,0 14px 30px -22px #70592d55 }
.cd-day { font-size:12px; font-weight:500; letter-spacing:.08em }
.cd-step-index { font:500 9px/1 var(--font); text-transform:uppercase; letter-spacing:.1em; color:#8b7d64 }
.cd-amts { margin-top:22px; margin-bottom:20px }
.cd-cash { font-size:clamp(42px,4.7vw,62px); font-weight:500; letter-spacing:-.06em }
.cd-card-foot { display:flex; justify-content:space-between; align-items:center; border-top:1px solid #e7decd; padding-top:12px; font:400 11px/1.3 var(--font); color:#75684e }
.cd-card-mark { display:grid; place-items:center; width:23px; height:23px; border-radius:50%; border:1px solid #d9ceb6; font-size:15px }
@media(min-width:860px) {
  .cd-row[data-hit="true"] .cd-card { background:linear-gradient(120deg,#2d7252,#245d45); border-color:#326d50; box-shadow:0 15px 30px -20px #174b3990 }
  .cd-row[data-hit="true"] .cd-card-foot { border-color:#ffffff30 }
  .cd-row[data-hit="true"] .cd-step-index,.cd-row[data-hit="true"] .cd-card-foot { color:#e0e9dc }
  .cd-row[data-hit="true"] .cd-card-mark { border-color:#e4d0a277; color:#f1dfb9 }
}
/* Soft overlapping plumes form a gold flame bed. Both opacity and height follow
   scroll, with brightness also tied to the credited reward. No perpetual loop. */
.cd-gold-smoke { --reward-level:inherit; position:absolute; z-index:1; pointer-events:none; left:-3%; right:-3%; bottom:-23px; height:120px; opacity:calc(.12 + var(--reward-scroll,0)*.5 + var(--reward-level,0)*.22); transform:scaleY(calc(.35 + var(--reward-scroll,0)*.65)); transform-origin:50% 100%; filter:blur(12px) }
.cd-gold-smoke::after { content:""; position:absolute; left:0; right:0; bottom:8px; height:36px; background:linear-gradient(90deg,#ad752700,#dba83b 25%,#ffe4a0 50%,#dca43d 75%,#ad752700); border-radius:50% }
.cd-gold-smoke i { position:absolute; bottom:0; width:31%; height:95px; border-radius:55% 45% 20% 20%; background:radial-gradient(ellipse at 50% 100%,#ffe4a8 0%,#dca342 33%,#d9a34355 52%,transparent 73%); transform:rotate(-17deg); }
.cd-gold-smoke i:nth-child(1) { left:0; height:72px }
.cd-gold-smoke i:nth-child(2) { left:18%; height:110px; transform:rotate(20deg) }
.cd-gold-smoke i:nth-child(3) { left:38%; height:82px; transform:rotate(-25deg) }
.cd-gold-smoke i:nth-child(4) { left:57%; height:105px; transform:rotate(12deg) }
.cd-gold-smoke i:nth-child(5) { left:77%; height:75px }
.cd-payoff { z-index:3 }
html.cd-complete .cd-gold-smoke { z-index:4; height:130px; opacity:.65 }
@media(max-width:859px) {
  .cd-hero { padding:70px 22px 80px }
  .cd-hero::before { left:-690px }
  .cd-hero::after { right:-680px }
  .cd-pin { padding-inline:20px }
  .cd-card { padding:22px }
  .cd-sum-main,.cd-sum-side { padding:20px 16px 28px }
  .cd-gold-smoke { opacity:.3; transform:scaleY(.55) }
  .cd-sum-val { font-size:18px }
  .cd-sum-val--pts { font-size:8px }
}
@media(prefers-reduced-motion:reduce) {
  .cd-gold-smoke { opacity:.25; transform:none }
  .cd-card,.cd-total { transition:none }
}
/* Remove the legacy hero's outer padding and dot layer. */
#hero { padding:0; background:none }
#hero::before { display:none }
@media(min-width:860px) {
  html.cd-js:not(.cd-rm) .cd-pin { top:72px; height:calc(100svh - 72px); padding-block:16px; justify-content:flex-start }
  html.cd-js:not(.cd-rm) .cd-col { flex:1; height:100% }
  html.cd-js:not(.cd-rm) .cd-flow-head { padding-top:0 }
}
html.cd-complete .cd-gold-smoke { opacity:.84 }

/* Earned-value states: animated emerald light, bold $100+, particles > $200. */
@keyframes cd-emerald-flow {
  0%,100% { transform:translate3d(-12px,9px,0) rotate(-8deg) scaleX(.92) }
  50% { transform:translate3d(24px,-14px,0) rotate(9deg) scaleX(1.15) }
}
@keyframes cd-amount-sheen {
  0%,100% { background-position:0% 50% }
  50% { background-position:100% 50% }
}
@keyframes cd-particle-rise {
  0% { transform:translate3d(0,12px,0) scale(.4); opacity:0 }
  18% { opacity:.7 }
  75% { opacity:.45 }
  100% { transform:translate3d(var(--drift),-110px,0) scale(.2); opacity:0 }
}
.cd-gold-smoke { bottom:-34px; filter:blur(13px); height:115px; opacity:calc(.3 + var(--reward-scroll,0)*.48) }
.cd-gold-smoke::after { background:linear-gradient(90deg,transparent,#46ad7877 25%,#a7e8bc 50%,#4db98777 75%,transparent); height:24px }
.cd-gold-smoke i { background:radial-gradient(ellipse at 50% 100%,#bceece 0%,#49b583 32%,#369c7155 53%,transparent 74%); animation:cd-emerald-flow 4.6s ease-in-out infinite }
.cd-gold-smoke i:nth-child(2) { animation-delay:-1.8s; animation-duration:5.2s }
.cd-gold-smoke i:nth-child(3) { animation-delay:-3.2s; animation-duration:4s }
.cd-gold-smoke i:nth-child(4) { animation-delay:-.7s; animation-duration:5.6s }
.cd-gold-smoke i:nth-child(5) { animation-delay:-2.4s }
.cd-reward-bold .cd-total { font-weight:700; color:#237449; background:linear-gradient(110deg,#164d38 5%,#32854d 32%,#668738 48%,#237d52 65%,#123f30 95%); background-size:220% 100%; background-clip:text; -webkit-background-clip:text; -webkit-text-fill-color:transparent; animation:cd-amount-sheen 5s ease-in-out infinite }
.cd-reward-particles { position:absolute; inset:0; z-index:5; pointer-events:none; overflow:hidden; opacity:0; transition:opacity .3s }
.cd-reward-rich .cd-reward-particles { opacity:1 }
.cd-reward-particles i { position:absolute; left:var(--x); bottom:8px; width:3px; height:3px; border-radius:50%; background:#59b583; box-shadow:0 0 5px #a5e8b788; animation:cd-particle-rise var(--duration) linear var(--delay) infinite; animation-play-state:paused }
.cd-reward-rich .cd-reward-particles i { animation-play-state:running }
.cd-reward-particles i:nth-child(3n) { width:2px; height:5px; background:#c4b479 }
/* A compact reward statement replaces the viewport-sized empty panel. */
@media(min-width:860px) {
  /* Shrink both boxes together at completion so scroll travel stays constant
     and the next section follows the compact payoff without an empty tail. */
  html.cd-js.cd-complete:not(.cd-rm) .cd-flow { height:calc(min(740px, 100svh - 72px) + (var(--stops) - 1) * var(--step-vh) * 1vh) }
  html.cd-js.cd-complete:not(.cd-rm) .cd-pin { height:min(740px, 100svh - 72px) }
  html.cd-js.cd-complete:not(.cd-rm) .cd-col { justify-content:flex-start }
  html.cd-js.cd-complete:not(.cd-rm) .cd-sum,
  html.cd-js.cd-settling:not(.cd-rm) .cd-sum { flex:1 1 auto; min-height:0 }
}
/* Deep-green treatment for the completed state. Colour and light only —
   every measurement lives in the v2 block above, so there is one place to
   change the geometry and one place to change the look. */
.cd-payoff { padding:clamp(20px,2.4vw,32px) clamp(22px,3vw,42px); background:linear-gradient(115deg,#1c5942,#287553 65%,#246b4d) }
.cd-payoff::before { inset:12px; border-color:#b8d2bd2e }
.cd-payoff::after { content:""; position:absolute; z-index:-1; pointer-events:none; width:750px; height:750px; right:-460px; top:-340px; border:1px solid #c8e5c522; border-radius:50%; box-shadow:0 0 0 36px #bdddc307,0 0 0 37px #c8e5c51a,0 0 0 90px #bdddc305,0 0 0 91px #c8e5c512 }
.cd-payoff-total { font-weight:700; letter-spacing:-.07em; background:linear-gradient(120deg,#fff 20%,#d6edd3 52%,#f6e9bb 80%); background-clip:text; -webkit-background-clip:text; -webkit-text-fill-color:transparent }
.cd-payoff-total > span { -webkit-text-fill-color:#eff5e8 }
/* Out of pocket becomes a panel rather than a ruled-off block: the shorthand
   `border` here deliberately replaces the border-top set above. */
.cd-payoff-cost { padding:16px 20px; border:1px solid #d4e8cd33; border-radius:16px; background:#ffffff07 }
.cd-payoff-zero { font-weight:600 }
.cd-payoff-ledger { border-color:#e2ecda33; background:#133e2a22 }
.cd-payoff-row { border-top-color:#e2ecda26 }
.cd-payoff-day { color:#c8ddcd }
.cd-payoff-amt { color:#f6f4e9 }
.cd-payoff-tick { color:#c5dab1 }
html.cd-complete .cd-gold-smoke { display:none }
html.cd-complete .cd-reward-particles i { background:#dcf0cc; box-shadow:0 0 5px #d9f2b533 }
@media(max-width:600px) {
  .cd-payoff { padding:20px 18px }
  .cd-payoff-cost { padding:14px 16px }
}
@media(min-width:860px) and (max-height:760px) {
  .cd-payoff { padding:18px 26px; gap:12px }
  .cd-payoff-cost { padding:12px 18px }
  .cd-payoff-row { padding-block:4px }
}
@media(prefers-reduced-motion:reduce) {
  .cd-gold-smoke i,.cd-reward-bold .cd-total { animation:none }
  .cd-reward-particles { display:none }
}

/* Motion revision: visible movement while resting at each earned stop. */
@keyframes cd-emerald-flow {
  0%,100% { transform:translate3d(-30px,14px,0) rotate(-12deg) scale(.85, .8) }
  50% { transform:translate3d(35px,-24px,0) rotate(14deg) scale(1.2, 1.18) }
}
.cd-gold-smoke { filter:blur(9px) }
.cd-gold-smoke i { animation-duration:2.8s }
.cd-gold-smoke i:nth-child(2) { animation-duration:3.4s }
.cd-gold-smoke i:nth-child(3) { animation-duration:2.6s }
.cd-gold-smoke i:nth-child(4) { animation-duration:3.8s }
.cd-reward-bold .cd-total { background-image:linear-gradient(110deg,#153f2e 10%,#248455 30%,#8c9f43 47%,#329e69 58%,#164532 80%); background-size:250% 100%; animation:cd-amount-sheen 2.6s ease-in-out infinite }
@keyframes cd-particle-rise {
  0% { transform:translate3d(0,14px,0) scale(.6); opacity:0 }
  15% { opacity:.95 }
  65% { opacity:.8 }
  100% { transform:translate3d(var(--drift),-155px,0) scale(.6); opacity:0 }
}
.cd-reward-particles i { width:4px; height:4px; background:#3d9b68; box-shadow:0 0 7px #80d8a680 }
.cd-reward-particles i:nth-child(3n) { width:3px; height:6px }
.cd-payoff-total { background-size:240% 100%; background-image:linear-gradient(110deg,#fff 5%,#e9f2df 25%,#b3d7a3 45%,#f3e3b4 60%,#fff 85%); animation:cd-amount-sheen 3.2s ease-in-out infinite }
@keyframes cd-final-contour {
  0%,100% { transform:translate3d(0,0,0) scale(1) }
  50% { transform:translate3d(-45px,38px,0) scale(1.09) }
}
.cd-payoff::after { animation:cd-final-contour 7s ease-in-out infinite; transform-origin:70% 30% }
html.cd-complete .cd-reward-particles { bottom:12%; }
html.cd-complete .cd-reward-particles i { width:4px; height:4px; background:#e4efba; box-shadow:0 0 8px #d4efba88 }
html.cd-complete .cd-reward-particles i:nth-child(3n) { width:3px; height:6px }
@media(prefers-reduced-motion:reduce) {
  .cd-gold-smoke i,.cd-reward-bold .cd-total,.cd-payoff-total,.cd-payoff::after { animation:none }
  .cd-reward-particles { display:none }
}

/* One uninterrupted amount, one footer, layered moving emerald light.
   The amount is sized to leave the ledger beside it room to breathe — at the
   old 162px it was the only thing on the card with any weight. */
.cd-payoff-total { display:block; white-space:nowrap; font-size:clamp(64px,8.4vw,128px); letter-spacing:-.075em; line-height:1.05 }
.cd-payoff-top,.cd-payoff-body,.cd-payoff-ledger,.cd-payoff-bottom { position:relative; z-index:1 }
.cd-payoff::after { opacity:.45 }
.cd-payoff-aura { position:absolute; inset:0; pointer-events:none; overflow:hidden; border-radius:inherit; z-index:0 }
@keyframes cd-payoff-current {
  0%,100% { transform:translate3d(-9%,12%,0) rotate(-12deg) scale(.9); opacity:.65 }
  50% { transform:translate3d(12%,-10%,0) rotate(10deg) scale(1.15); opacity:1 }
}
.cd-payoff-aura i { position:absolute; width:75%; height:90%; bottom:-48%; left:-15%; border-radius:50%; background:radial-gradient(ellipse,#7ce5aa55 0%,#42c79135 30%,transparent 68%); filter:blur(20px); animation:cd-payoff-current 5s ease-in-out infinite }
.cd-payoff-aura i:nth-child(2) { width:90%; left:45%; bottom:-35%; background:radial-gradient(ellipse,#b7dda331 0%,#51ce9838 35%,transparent 68%); animation-delay:-2.5s; animation-duration:6s }
.cd-payoff-total { animation-duration:2.6s; background-image:linear-gradient(110deg,#fff 8%,#e4f2d8 26%,#a7d3a6 43%,#f1e2af 60%,#fff 82%) }
html.cd-complete .cd-reward-particles { bottom:16%; mask-image:linear-gradient(0deg,transparent,#000 12%,#000 80%,transparent) }
@media(min-width:860px) and (max-height:760px) {
  .cd-payoff-total { font-size:clamp(60px,7vw,104px) }
  .cd-payoff-bottom { padding-top:12px }
}
@media(max-width:600px) {
  .cd-payoff-total { font-size:clamp(52px,15vw,78px) }
  .cd-payoff-bottom { flex-direction:column; align-items:flex-start; gap:10px; padding-top:14px }
}
@media(prefers-reduced-motion:reduce) {
  .cd-payoff-aura i,.cd-payoff-total { animation:none }
}

/* Homepage polish: equal breathing room around the invitation strip. */
.cd-hero { padding-bottom:64px }
.cd-ticker { padding-block:34px }
.cd-flow { padding-top:64px }
/* Clip the road to its own canvas so its negative lead-in cannot leak out. */
.cd-road { overflow:hidden; border-radius:18px 18px 0 0 }
.cd-road svg { overflow:hidden }
.cd-card--today { border:2px solid #c5a451; box-shadow:0 0 0 4px #d9b65924,0 12px 32px -16px #70541f70 }
.cd-today-badge { align-self:flex-start; margin:-8px 0 16px; padding:9px 15px; border-radius:7px; background:linear-gradient(115deg,#f7e3a0,#d9b454); color:#3b2b0c; box-shadow:0 4px 12px #0002; font:800 13px/1 var(--font); letter-spacing:.08em }
.cd-up-wrap { background:radial-gradient(ellipse at 12% 30%,#d6e5d866,transparent 50%),radial-gradient(ellipse at 90% 80%,#ecd5a566,transparent 50%),#f8f5ed }
.cd-up-head h2 { font-weight:500; letter-spacing:-.045em }
.cd-up-card { position:relative; isolation:isolate; overflow:hidden; min-height:390px; padding:32px; border-radius:26px; box-shadow:0 22px 48px -26px #283d3e66 }
.cd-up-card--invite { background:radial-gradient(ellipse at 95% 0%,#52896888,transparent 65%),linear-gradient(140deg,#163e30,#28694c); border-color:#42765a }
.cd-up-card--points { background:radial-gradient(ellipse at 100% 0%,#f8e9b1,transparent 65%),linear-gradient(140deg,#e7d1a0,#f5ebd6); border-color:#cfb778 }
.cd-up-top { position:relative; z-index:1; margin-bottom:115px }
.cd-up-card h3,.cd-up-card p { position:relative; z-index:1; max-width:48ch }
.cd-up-card h3 { font-size:28px }
.cd-up-card--invite h3 { color:#fff9e8 }
.cd-up-card--invite p { color:#d7e6da }
.cd-up-card--points h3 { color:#4e3a18 }
.cd-up-card--points p { color:#6d5935 }
.cd-up-icon { background:#ffffff1c; color:#f3de9d; border:1px solid #ffffff30 }
.cd-up-card--points .cd-up-icon { background:#fff9; color:#856625; border-color:#bfa36166 }
.cd-soon { border:1px solid #e6d49666; background:#ffffff13; color:#f8e8ba; padding:10px 14px; letter-spacing:.1em }
.cd-up-card--points .cd-soon { border-color:#ac8a4366; background:#fff8; color:#705421 }
.cd-up-art { position:absolute; z-index:0; width:240px; height:240px; right:-18px; top:18px; display:grid; place-items:center; color:#f5e2a5 }
.cd-up-art i { position:absolute; width:75%; height:75%; border:1px solid currentColor; border-radius:50%; opacity:.18; transform:rotate(-25deg) scaleY(.7) }
.cd-up-art i:nth-child(2) { width:100%; height:100% }
.cd-up-art i:nth-child(3) { width:125%; height:125% }
.cd-up-art span { display:grid; place-items:center; width:90px; height:90px; font-size:52px; border-radius:24px; border:1px solid #fffa; background:linear-gradient(145deg,#ffffff30,#ffffff08); box-shadow:12px 18px 35px #102e302b; transform:rotate(-12deg) }
.cd-up-card--points .cd-up-art { color:#9c7934 }
@media(max-width:720px) {
 .cd-hero { padding-bottom:44px }
 .cd-flow { padding-top:44px }
 .cd-ticker { padding-block:30px }
 .cd-up-card { padding:24px; min-height:370px }
 .cd-up-top { margin-bottom:110px }
 .cd-up-art { right:-35px; top:30px }
}

.cd-flow-head { padding-top:0 }
@media(min-width:860px) { .cd-flow { padding-top:48px } }

/* Day 0 handwritten callout and compact feature previews. */
.cd-card--today .cd-amts { flex-wrap:nowrap; gap:8px; align-items:center }
.cd-today-doodle { flex:1; min-width:0; display:flex; align-items:center; color:#f1d174; transform:rotate(-7deg) }
.cd-today-doodle svg { width:55px; height:48px; flex-shrink:0; overflow:visible }
.cd-today-doodle path { fill:none; stroke:currentColor; stroke-width:2.6; stroke-linecap:round; stroke-linejoin:round }
.cd-today-doodle > span { font:700 italic clamp(15px,1.5vw,20px)/1.12 Georgia,serif; letter-spacing:.02em; white-space:nowrap; text-align:center }
.cd-up-wrap { padding-block:44px }
.cd-up-head { margin-bottom:28px }
.cd-up-card { min-height:320px; padding-bottom:28px }
.cd-up-top { margin-bottom:80px }
.cd-up-art { top:0 }
.cd-up-art span svg { width:64px; height:64px }
@media(max-width:720px) {
 .cd-up-wrap { padding-block:32px }
 .cd-up-card { min-height:0 }
 .cd-up-top { margin-bottom:90px }
 .cd-today-doodle > span { font-size:18px }
 .cd-today-doodle svg { width:50px }
}

.cd-row[data-hit="true"] .cd-card .cd-today-doodle,
.cd-row[data-hit="true"] .cd-card .cd-today-doodle * { color:#f1d174 }
@media(min-width:860px) {
 html.cd-js:not(.cd-rm) .cd-card--today .cd-node { top:100%; left:calc(88.2353% - 10px); right:auto }
}

@media(max-width:859px) {
 .cd-card--today { background:linear-gradient(120deg,#2d7252,#245d45); border-color:#bd9a43 }
 .cd-card--today .cd-day,.cd-card--today .cd-cash { color:#fff9e8 }
 .cd-card--today .cd-step-index,.cd-card--today .cd-card-foot { color:#e0e9dc }
 .cd-card--today .cd-card-foot { border-color:#ffffff30 }
 .cd-card--today .cd-card-mark { color:#f1d174; border-color:#f1d17466 }
}

/* --- 5c. The gutters: day rail + ladder ledger ---------------------------- */
/* The 1120px column leaves 200-400px of empty ground either side on a desktop
   screen, and that space was the flattest part of the page. It is filled with
   ORIENTATION rather than texture: where you are on a 21-day calendar, and what
   the six stops pay.

   The rail is spaced by DAYS, not by stops. main.js writes each tick's `top`
   from `s.day / journeyDays`, so the four days to stop 2 and the seven to stop 6
   are drawn as different distances — the one thing the road cannot say, since
   its curves are evenly spaced whatever the calendar does.

   Three custom properties come from the driver, all measured, never assumed:
     --rail-top / --rail-h  the pinned FRAME's box, so the scale spans exactly
                            the road and nothing else
     --rail-prog            the current day as a percentage of the journey,
                            interpolated between stops so it descends smoothly
   Hidden by default and switched on only inside the pinned desktop block: below
   that breakpoint there are no gutters to sit in and no pinned frame to measure.
   Both elements are aria-hidden in the markup — every figure in them is already
   announced by the cards and the summary. */
.cd-rail, .cd-ledger { display:none }

@media (min-width:1360px) {
  html.cd-js:not(.cd-rm) .cd-rail {
    display:block; position:absolute; z-index:0; pointer-events:none;
    top:var(--rail-top,0px); height:var(--rail-h,0px);
    /* 98px left of the column's edge: the line, then ~64px of label, then the
       gap. The binding constraint is not the day label but the "you're here"
       chip below it, which is the widest thing the rail ever prints. */
    left:calc(50% - (var(--max) / 2) - 98px); width:200px;
  }
  .cd-rail-line { position:absolute; left:0; top:0; bottom:0; width:1px; background:#e4d9c3 }
  .cd-rail-line i { position:absolute; left:0; top:0; width:1px; height:var(--rail-prog,0%);
    background:var(--brand); transition:height var(--d-base) var(--ease) }

  .cd-rail-tick { position:absolute; left:0; display:flex; align-items:center; gap:12px;
    transform:translateY(-50%); white-space:nowrap;
    font:500 10px/1 var(--font); letter-spacing:.14em; text-transform:uppercase }
  /* The chip stacks UNDER the day label rather than beside it. Inline, the pair
     ran to ~110px and the gutter only offers 92px before the first card's edge,
     so "you're here" was printing underneath the day 0 card. */
  .cd-rail-txt { display:flex; flex-direction:column; align-items:flex-start; gap:6px }
  .cd-rail-dot { width:7px; height:7px; margin-left:-3px; border-radius:50%;
    border:1px solid #ddd0b4; background:var(--bg-tint); font-style:normal }
  .cd-rail-day { color:#a8967a }
  /* The "you're here" chip belongs to one tick at a time; it is in the markup on
     every tick and revealed by state, so nothing has to be moved or rebuilt as
     the path advances. */
  .cd-rail-here { display:none; font:500 8px/1 var(--font); font-style:normal; letter-spacing:.08em;
    padding:4px 6px; border:1px solid #e8c7ac; border-radius:20px;
    background:var(--brand-wash); color:var(--brand) }

  .cd-rail-tick.is-past .cd-rail-dot { background:var(--brand); border-color:var(--brand) }
  .cd-rail-tick.is-past .cd-rail-day { color:#b3a68c }
  .cd-rail-tick.is-now .cd-rail-dot { width:13px; height:13px; margin-left:-6px;
    background:var(--brand); border:3px solid var(--bg-tint); box-shadow:0 0 0 1px var(--brand) }
  .cd-rail-tick.is-now .cd-rail-day { color:var(--brand-deep); font-weight:600 }
  .cd-rail-tick.is-now .cd-rail-here { display:inline-block }

}

/* The chip is the one part of the rail that needs real width, and at 1360px the
   gutter is 120px — it printed under the first card. It appears only where the
   ledger does; below that the rail is a scale and nothing else. */
@media (min-width:1360px) and (max-width:1519px) {
  .cd-rail-tick.is-now .cd-rail-here { display:none }
}

/* The ledger needs its own, wider breakpoint: at 1360px the right gutter is
   120px and the amounts would sit under the cards' shadow. */
@media (min-width:1520px) {
  /* Mirrored on the rail: the box starts at the column's edge and runs 98px
     outward, so its spine sits exactly as far from the column as the rail's does
     on the other side. Six amounts with nothing running between them were hard
     to track as the section resized — the eye had no line to follow. */
  html.cd-js:not(.cd-rm) .cd-ledger {
    display:block; position:absolute; z-index:0; pointer-events:none;
    top:var(--rail-top,0px); height:var(--rail-h,0px);
    left:calc(50% + (var(--max) / 2)); width:98px;
  }
  /* The spine. Same hairline, same fill height (--rail-prog drives both), so the
     two gutters advance together — but GREEN, not brand orange: this side counts
     money, and the token comment for --money is explicit that orange means
     Condy (hero, road, progress) and green means cash to you. */
  .cd-led-line { position:absolute; right:0; top:0; bottom:0; width:1px; background:#e4d9c3 }
  .cd-led-line i { position:absolute; right:0; top:0; width:1px; height:var(--rail-prog,0%);
    background:var(--money); transition:height var(--d-base) var(--ease) }

  .cd-ledger ol { position:relative; height:100%; margin:0; padding:0; list-style:none }
  /* Each amount is parked at its own day's height — the same percentage the
     matching tick uses — so the two gutters read as one scale. */
  .cd-led-row { position:absolute; left:0; right:0; transform:translateY(-50%);
    display:flex; align-items:center; justify-content:flex-end; gap:12px }
  /* Bone until collected, then green — the same green the card inverts to and
     the same green the running total is written in. */
  .cd-led-row b { font:500 19px/1 var(--font); letter-spacing:-.03em; color:#ddd0b4;
    transition:color var(--d-base) var(--ease) }
  .cd-led-row.is-done b { color:var(--money) }

  /* The dots mirror the rail's, hanging on the spine rather than beside it. */
  .cd-led-dot { width:7px; height:7px; margin-right:-3px; border-radius:50%;
    border:1px solid #ddd0b4; background:var(--bg-tint); font-style:normal; flex:0 0 auto }
  .cd-led-row.is-done .cd-led-dot { background:var(--money); border-color:var(--money) }
  .cd-led-row.is-now .cd-led-dot { width:13px; height:13px; margin-right:-6px;
    background:var(--money); border:3px solid var(--bg-tint); box-shadow:0 0 0 1px var(--money) }
}

/* Once the payoff absorbs the path there is no path left to measure: the rail
   and the ledger leave with the road, not after it. */
html.cd-complete .cd-rail, html.cd-complete .cd-ledger { opacity:0 }
.cd-rail, .cd-ledger { transition:opacity var(--d-base) var(--ease) }
@media (prefers-reduced-motion:reduce) {
  .cd-rail, .cd-ledger, .cd-led-row b { transition:none }
}
