/* cu-rail — the position rail for a page built from N long, similar sections.
   Built 2026-08-05 for /carly/use-cases/ (19,217px, five blocks of 1,854–2,808px sharing one
   kicker→title→lead→split frame). The blocks weren't bad; they were indistinguishable, and with no
   position feedback the reader had no idea whether they were in the second or the fifth. The rail
   answers "where am I / how much is left" continuously, which is what actually shortens a long page.

   Pairs with /assets/js/w/shared/cu-rail.js. Opt in with sharedCSS/sharedJS: [cu-rail].

   TWO FORMS, one state model:
     ≥1400px  vertical rail (numbers), fixed to the left gutter
     ≥1500px  …with the verb labels
     <1400px  horizontal strip, sticky under the nav

   Both numbers are DERIVED from the widest container on the page, not chosen. #ai-outbound uses
   .w-container--wide (1320px), not the 1200px default, so its content starts at
   (100vw - 1320)/2 + 48 — earlier and tighter than every other section. Requiring 20px of
   clearance from the rail's right edge, clamp(14,1.5vw,30) + railW:
     railW 30 (numbers)  → W ≥ 1365   → 1400 chosen, giving 37px measured
     railW 92 (+labels)  → W ≥ 1493   → 1500 chosen, giving 24px measured
   Assuming the 1200px container here is how this went wrong twice: 1200 gave 0px clearance and
   1280 gave −1px. If a section is ever widened again, re-derive both.
   The breakpoint is set by GUTTER MATH, not taste: the rail is 132px + 24px of clearance, and the
   container is 1200px, so it needs (1200 + 2*156) = 1512px to sit fully outside the content… which
   we don't have at 1440. Instead it overlaps the gutter and is allowed to, because at ≥1200 the
   gutter is ≥120px and the rail's own width collapses to 92px there. Below 1200 there is no gutter
   left at all, so it becomes the strip. Do not "simplify" this to a single form — the vertical rail
   at 1024 lands on top of the copy. */

/* ═══════════════════════════════════════════ shared state ═══════════════════════════════════ */
/* SURFACE SKIN — the one thing a fixed overlay must get right and almost never does.
   The rail is position:fixed at body level, so it sits OUTSIDE every .cz-light section and
   therefore inherits the ROOT (dark) token set while floating over light bands. Shipped like that
   it rendered inactive items as rgba(255,255,255,.42) on near-white — invisible, and invisible in a
   way no geometry or state gate can see: the elements are present, sized, positioned and correctly
   classed. It was caught by looking at a screenshot.
   The fix reuses the convention the page already has: every section carries data-nav-surface, and
   cu-rail.js mirrors the active section's value onto the rail as data-surface. Colours below are
   literal, not token references, precisely because token inheritance is what broke this. */
.cu-rail{
  --cu-rail-ink: rgba(255,255,255,.46);
  --cu-rail-on: #c1b4ff;
  --cu-rail-track: rgba(255,255,255,.16);
  position:fixed;z-index:40;
  opacity:0;visibility:hidden;pointer-events:none;
  transition:opacity .45s var(--w-ease),visibility .45s var(--w-ease);
}
/* light band: --w-purple-ink (#6f5fe0) measures 4.78:1 on white; --w-brand-2 / --w-purple is
   2.95:1 and fails AA for these 10.5–11px labels. Do not "simplify" this to var(--w-brand). */
.cu-rail[data-surface="light"]{
  --cu-rail-ink: rgba(28,26,36,.52);
  --cu-rail-on: #6f5fe0;
  --cu-rail-track: rgba(28,26,36,.16);
}
/* .is-armed is added by the JS only while one of the tracked sections is on screen, so the rail
   never floats over the hero or the closing bands. */
.cu-rail.is-armed{opacity:1;visibility:visible;pointer-events:auto}
.cu-rail__list{list-style:none;margin:0;padding:0}
.cu-rail__link{display:flex;align-items:center;gap:10px;text-decoration:none;cursor:pointer;
  color:var(--cu-rail-ink);transition:color .3s var(--w-ease)}
.cu-rail__no{font-family:var(--w-font-mono);font-size:11px;font-weight:700;letter-spacing:.06em;
  font-variant-numeric:tabular-nums;line-height:1}
.cu-rail__verb{font-family:var(--w-font-kicker,var(--w-font));font-size:10.5px;font-weight:700;
  letter-spacing:.14em;text-transform:uppercase;line-height:1;white-space:nowrap}
.cu-rail__item.is-on .cu-rail__link{color:var(--cu-rail-on)}
.cu-rail__link:hover,.cu-rail__link:focus-visible{color:var(--cu-rail-on)}
.cu-rail__link:focus-visible{outline:2px solid var(--w-brand-line);outline-offset:4px;border-radius:6px}

/* ═══════════════════════════════════ ≥1200 · vertical, fixed left ═══════════════════════════ */
@media(min-width:1400px){
  /* Pinned to the VIEWPORT edge at a constant offset, deliberately NOT tracking the container.
     An earlier version used max(14px, (100vw - 1200px)/2 - 108px), which pushed the rail to x=252
     at 1920 — that put it under #proof-delivery's full-bleed copy column and forced a 366px left
     inset on that copy to compensate, squeezing an h2 into 205px. A constant offset keeps the
     rail's footprint identical at every width, so exactly one clearance number has to be true.
     --cu-rail-edge is that number; the page sheet reads it (see use-cases.css §rail clearance). */
  .cu-rail{--cu-rail-w:30px;
    --cu-rail-x:clamp(14px,1.5vw,30px);
    --cu-rail-edge:calc(var(--cu-rail-x) + var(--cu-rail-w));
    left:var(--cu-rail-x);top:50%;translate:0 -50%}
  .cu-rail__list{display:flex;flex-direction:column;gap:2px;position:relative;padding-left:15px}
  /* the track + the travelled hairline. --cu-p (0–1) is written by the JS from real scroll
     position across the whole tracked run, not from which item is active — a 5-step stepped bar
     tells you the section, a continuous one tells you the distance, and distance is the thing
     that makes a long page feel finite. */
  .cu-rail__list::before,.cu-rail__list::after{content:"";position:absolute;left:0;top:6px;bottom:6px;
    width:2px;border-radius:2px}
  .cu-rail__list::before{background:var(--cu-rail-track)}
  .cu-rail__list::after{background:linear-gradient(180deg,var(--w-purple-ink),var(--w-purple));
    transform-origin:top center;transform:scaleY(var(--cu-p,0));
    transition:transform .18s linear}
  .cu-rail__item{position:relative}
  .cu-rail__link{padding:9px 0;flex-direction:column;align-items:flex-start;gap:3px}
  /* the label is present for everyone but only the ACTIVE one is legible — five stacked labels at
     full strength is just a second navigation, and this is a position indicator, not a menu. */
  /* 1200–1439: numbers + track only. The gutter there is ~0–120px and a 92px label block would
     sit on the copy of any full-bleed section. Numbers alone still answer "which of five am I in",
     which is the rail's actual job; the verbs are an enrichment, not the function. */
  .cu-rail__verb{display:none}
  /* Verbs need 93px of rail plus ~22px of clearance = 115px, and the gutter is (100vw-1200)/2.
     1440 gives only 120px — measured clearance there was -7px against #ai-outbound's payoff title,
     which sits slightly outside the container. 1500 is the first width where the gutter (150px)
     clears the labelled rail with room to spare. Do NOT lower this back to 1440. */
  @media(min-width:1500px){
    .cu-rail{--cu-rail-w:92px}
    .cu-rail__verb{display:block;opacity:.42;
      transition:opacity .3s var(--w-ease),transform .3s var(--w-ease)}
    .cu-rail__item.is-on .cu-rail__verb{opacity:1}
    .cu-rail__link:hover .cu-rail__verb{opacity:1}
  }
  /* the active marker on the track */
  .cu-rail__item::before{content:"";position:absolute;left:-15px;top:50%;translate:0 -50%;
    width:2px;height:0;border-radius:2px;background:var(--cu-rail-on);
    transition:height .35s var(--w-ease)}
  .cu-rail__item.is-on::before{height:26px}
  .cu-rail__strip-lbl{display:none}
}

/* ═══════════════════════════════ <1200 · horizontal, sticky strip ═══════════════════════════ */
@media(max-width:1399px){
  .cu-rail{left:0;right:0;top:0;
    /* --w-nav-h is defined in ds7.css :root (68px). It was NEVER set by base.js despite
       the comment that used to sit here, so this padding was 4px short until 2026-08-07. */
    padding-top:var(--w-nav-h,64px);
    background:rgba(18,16,26,.86);
    -webkit-backdrop-filter:blur(14px) saturate(140%);backdrop-filter:blur(14px) saturate(140%);
    border-bottom:1px solid rgba(255,255,255,.10)}
  .cu-rail[data-surface="light"]{background:rgba(255,255,255,.88);border-bottom-color:rgba(28,26,36,.10)}
  .cu-rail__inner{display:flex;align-items:center;gap:12px;
    max-width:1200px;margin-inline:auto;padding:9px clamp(14px,4vw,28px)}
  /* the active section's name, spelled out — on a phone the numbers alone are meaningless */
  .cu-rail__strip-lbl{font-family:var(--w-font-kicker,var(--w-font));font-size:10.5px;font-weight:700;
    letter-spacing:.12em;text-transform:uppercase;color:var(--cu-rail-on);white-space:nowrap;
    overflow:hidden;text-overflow:ellipsis;flex:1 1 auto;min-width:0}
  .cu-rail__list{display:flex;align-items:center;gap:7px;flex:none}
  .cu-rail__verb{display:none}
  .cu-rail__link{padding:6px 2px}
  .cu-rail__no{opacity:.4;transition:opacity .3s var(--w-ease)}
  .cu-rail__item.is-on .cu-rail__no{opacity:1}
  /* a continuous progress hairline along the very bottom edge of the strip */
  .cu-rail::after{content:"";position:absolute;left:0;bottom:-1px;height:2px;width:100%;
    transform-origin:left center;transform:scaleX(var(--cu-p,0));
    background:linear-gradient(90deg,#6f5fe0,#9887f4);
    transition:transform .18s linear}
}
/* On the narrowest phones the five numbers plus a label do not fit on one line. Numbers become
   dots — the label already says which move you are in, so the digits are redundant, and a wrapped
   strip is worse than no strip. 360 and 320 both land here. */
@media(max-width:420px){
  .cu-rail__no{font-size:0;line-height:0;display:block;width:7px;height:7px;border-radius:50%;
    background:currentColor;opacity:.3}
  .cu-rail__item.is-on .cu-rail__no{opacity:1;box-shadow:0 0 0 3px var(--w-brand-soft)}
  .cu-rail__list{gap:9px}
  .cu-rail__inner{padding-inline:14px;gap:10px}
  .cu-rail__strip-lbl{font-size:9.5px;letter-spacing:.1em}
}

@media(prefers-reduced-motion:reduce){
  .cu-rail,.cu-rail__link,.cu-rail__verb,.cu-rail__item::before,
  .cu-rail__list::after,.cu-rail::after,.cu-rail__no{transition:none}
}

/* ═══════════════════════════════ anchor landing clearance ═══════════════════════════════════
   The strip form is sticky under the nav, so an anchor jump (from the §2 overview cards, the rail
   itself, or a shared link) would land the section's title UNDERNEATH it. scroll-margin-top pushes
   the landing point down by nav + strip + a breath. The vertical form doesn't overlay content at
   all, so it only needs the nav's own clearance. */
/* scroll-margin-top removed 2026-08-07 — ds7.css now sets html{scroll-padding-top}
   sitewide. Keeping this ADDED to it: measured 168px at 1440 and 206px at 390
   instead of the intended 88px. */
@media(max-width:1399px){
  /* (paired mobile rule removed with the one above) */
}
