@import url('fonts.css');

/* ==========================================================================
   walksos.co.uk — v2.0. See DESIGN.md.
   Three rules: no boxes; no two sections built the same way; the display face
   is a signage face, so it is set like signage.
   ========================================================================== */

:root{
  --red:      oklch(0.585 0.231 28);          /* #ED1C24, from the logo */
  --red-deep: oklch(0.478 0.190 28);
  --paper:    oklch(1 0 0);
  --paper-2:  oklch(0.985 0.003 45);   /* recessed panels — barely off white */
  --ink:      oklch(0.165 0.012 32);
  --ink-2:    oklch(0.430 0.012 38);
  --ink-3:    oklch(0.550 0.010 40);
  --rule:     oklch(0.885 0.006 40);
  --rule-2:   oklch(0.760 0.008 40);
  --on-red:   oklch(0.995 0.004 60);
  --moor:     oklch(0.560 0.022 140);         /* the scene's mid-tone, flat light */
  --moor-pale:oklch(0.930 0.008 140);

  --f-display:"Barlow",ui-sans-serif,system-ui,"Helvetica Neue",Arial,sans-serif;
  --f-text:"IBM Plex Sans",ui-sans-serif,system-ui,"Helvetica Neue",Arial,sans-serif;
  --f-data:"IBM Plex Mono",ui-monospace,SFMono-Regular,Menlo,monospace;
  --f-print:"Helvetica Neue",Helvetica,Arial,sans-serif;

  /* eight steps, hand-set, with a deliberate jump between d1 and d2 */
  --t-d1:clamp(3.1rem,12.4vw,10.5rem);
  --t-d2:clamp(2.3rem,6.4vw,5.2rem);
  --t-d3:clamp(1.35rem,2.5vw,2rem);
  --t-lead:clamp(1.2rem,1.85vw,1.6rem);
  --t-body:1.1rem;
  --t-small:0.95rem;
  --t-data:0.8125rem;
  --t-label:0.8125rem;  /* = --t-data: separated by case and tracking, not size */

  --gutter:22px;
  --measure:76rem;
  --col:min(100% - (var(--gutter) * 2),var(--measure));

  --e-out:cubic-bezier(0.16,1,0.30,1);
  --e-io:cubic-bezier(0.65,0,0.35,1);
  --e-soft:cubic-bezier(0.32,0.72,0,1);
  color-scheme:light;
}

*,*::before,*::after{box-sizing:border-box}
html{overflow-x:clip;-webkit-text-size-adjust:100%;scroll-padding-top:84px}
::selection{background:var(--red);color:#fff}
body{margin:0;background:var(--paper);color:var(--ink);
  font-family:var(--f-text);font-weight:300;font-size:var(--t-body);line-height:1.66;
  -webkit-font-smoothing:antialiased}
img,svg{max-width:100%}
/* an image never carries its height attribute as a used height: once
   max-width shrinks it, a fixed height is a stretch */
img{height:auto}
h1,h2,h3{margin:0;font-family:var(--f-display);text-wrap:balance}
p{margin:0}
a{color:inherit}
:focus-visible{outline:2px solid var(--red);outline-offset:4px}
.skip{position:absolute;left:-9999px;background:var(--red);color:#fff;padding:12px 18px;z-index:200;
  font-family:var(--f-display);font-weight:600;text-decoration:none}
.skip:focus{left:10px;top:10px}
.vh{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}

/* ---------------------------------------------------------------- shared */
.col{width:var(--col);margin-inline:auto}
.full{width:100%}
.art-h1,.crumb ~ .s .d1{font-size:var(--t-d2)}
.d1{font-size:var(--t-d1);font-weight:800;font-style:italic;line-height:.82;letter-spacing:-.042em;
  text-transform:uppercase}
.d2{font-size:var(--t-d2);font-weight:800;line-height:.90;letter-spacing:-.032em}
.d2.ital{font-style:italic;text-transform:uppercase}
h3{font-size:var(--t-d3);font-weight:600;line-height:1.14;letter-spacing:-.015em}
.lead{font-size:var(--t-lead);line-height:1.42;font-weight:300;color:var(--ink-2)}
.say{max-width:56ch}
/* an inline link in running text still has to be hittable */
.say a,.claims p a,.spec a{display:inline-block;padding-block:4px}
.say + .say{margin-top:.9em}
.narrow{max-width:34ch}
.data{font-family:var(--f-data);font-weight:500;font-size:var(--t-data);letter-spacing:.02em;
  font-variant-numeric:tabular-nums;color:var(--ink-2)}
.kicker{font-family:var(--f-data);font-weight:500;font-size:var(--t-data);letter-spacing:.1em;
  text-transform:uppercase;color:var(--red)}
.rule{border:0;border-top:1px solid var(--rule);margin:0}
.rule.heavy{border-top-width:2px;border-color:var(--ink)}

.cta{display:inline-flex;align-items:center;gap:.7em;font-family:var(--f-display);font-weight:800;
  font-size:var(--t-small);letter-spacing:.01em;text-transform:uppercase;text-decoration:none;
  background:var(--red);color:var(--on-red);padding:17px 26px;border:0;cursor:pointer;
  transition:background 160ms var(--e-io),transform 160ms var(--e-out)}
.cta:hover{background:var(--red-deep);transform:translateY(-2px)}
.cta .arw{transition:transform 220ms var(--e-out)}
.cta:hover .arw{transform:translateX(4px)}
.cta.line{background:none;color:var(--ink);padding:17px 0;position:relative}
.cta.line::after{content:"";position:absolute;left:0;right:0;bottom:10px;height:2px;background:var(--ink);
  transform-origin:left;transition:transform 260ms var(--e-out)}
.cta.line:hover{background:none;color:var(--red);transform:none}
.cta.line:hover::after{background:var(--red);transform:scaleX(1.06)}

/* ------------------------------------------------------------------ logo */
/* The lockup is supplied artwork, loaded as one cached file. Nothing here
   restyles it — the only job is to give it a size and reserve its space. */
.mark{display:inline-flex;text-decoration:none}
/* no aspect-ratio here: the img carries width and height attributes, so the
   browser reserves the box from those and then from the file's own viewBox */
.lockup{display:block;height:auto}
.lockup.wide{width:9.4em}
.lockup.stack{width:7.2em}

/* ---------------------------------------------------------------- splash */
/* Added by nobody: the markup ships in every page but stays display:none
   unless the inline head script sets data-splash, which it only does for a
   first visit, with motion allowed, arriving at the top of a page. A crawler
   never sees it. Belt and braces in site.js removes it on any input and
   after 3s, so it can never trap anyone behind it. */
.splash{display:none}
html[data-splash] .splash{display:grid;place-items:center;position:fixed;inset:0;z-index:200;
  background:var(--paper);animation:sp-lift 440ms cubic-bezier(.72,0,.18,1) 1180ms both}
html[data-splash] .splash::after{content:"";position:absolute;left:0;right:0;bottom:0;height:3px;
  background:var(--red);opacity:0;animation:sp-rule 440ms linear 1180ms forwards}

/* The reticle starts at five times size, centred on the viewport, and shrinks
   onto the spot it occupies in the finished lockup. It scales about its own
   fill-box centre, so it lands exactly, with no arithmetic — the only measured
   number is the 117.2 user units between that centre and the middle of the
   artwork, which is what puts it on screen centre to begin with.

   Read as: something sweeps the ground, finds the spot, and the sign is what
   it found. 1.6s, once per session, and any key or click ends it early. */
.sp-mark{width:min(72vw,520px);height:auto;overflow:visible}
html[data-splash] .sp-mark [data-part]{transform-box:fill-box;transform-origin:50% 50%}

/* the sign draws itself out from the left, the way a banner unrolls */
html[data-splash] .sp-mark [data-part="slab"],
html[data-splash] .sp-mark [data-part="panel"]{transform-origin:0 50%}
html[data-splash] .sp-mark [data-part="slab"]{animation:sp-wipe 520ms cubic-bezier(.72,0,.18,1) 260ms both}
html[data-splash] .sp-mark [data-part="panel"]{animation:sp-wipe 520ms cubic-bezier(.72,0,.18,1) 340ms both}
html[data-splash] .sp-mark [data-part="walk"]{animation:sp-rise 460ms var(--e-out) 520ms both}
html[data-splash] .sp-mark [data-part="sos"]{animation:sp-rise 460ms var(--e-out) 600ms both}
html[data-splash] .sp-mark [data-part="icon"]{animation:sp-lock 1000ms linear both}
html[data-splash] .sp-mark [data-p="ring"]{transform-box:fill-box;transform-origin:50% 50%;
  animation:sp-sweep 1000ms linear both}
/* the red the crosshair needs to be white against, until the slab arrives
   under it and takes over the job */
html[data-splash] .sp-mark .sp-halo{animation:sp-halo 1000ms linear both}

@keyframes sp-wipe{from{transform:scaleX(0)}to{transform:scaleX(1)}}
@keyframes sp-rise{from{opacity:0;transform:translateY(7px)}to{opacity:1;transform:none}}

/* held wide while it searches, then one firm move down onto the mark */
@keyframes sp-lock{
  0%  {opacity:0;transform:translateX(-117.2px) scale(5);
       animation-timing-function:cubic-bezier(.2,.7,.4,1)}
  9%  {opacity:1}
  26% {opacity:1;transform:translateX(-117.2px) scale(4.45);
       animation-timing-function:cubic-bezier(.66,0,.16,1)}
  100%{opacity:1;transform:translateX(0) scale(1)}
}
@keyframes sp-sweep{
  0%  {transform:rotate(0);animation-timing-function:linear}
  26% {transform:rotate(232deg);animation-timing-function:cubic-bezier(.66,0,.16,1)}
  100%{transform:rotate(360deg)}
}
@keyframes sp-halo{0%,56%{opacity:1}74%,100%{opacity:0}}
@keyframes sp-rule{from{opacity:1}to{opacity:1}}
@keyframes sp-lift{from{transform:translateY(0)}to{transform:translateY(-101%)}}

/* ---------------------------------------------------------------- header */
.top{position:sticky;top:0;z-index:60;background:var(--paper);transition:box-shadow 200ms var(--e-io)}
.top[data-stuck="true"]{box-shadow:0 1px 0 var(--rule)}
.top-in{display:flex;align-items:center;justify-content:space-between;gap:18px;padding-block:15px}
.top .mark{font-size:var(--t-data)}
.top .lockup.wide{width:10.6em}
@media (max-width:420px){.top .lockup.wide{width:9.2em}}
.top nav{display:none;gap:26px}
.top nav a{font-family:var(--f-data);font-weight:500;font-size:var(--t-label);letter-spacing:.09em;
  text-transform:uppercase;color:var(--ink-3);text-decoration:none;padding-block:9px;
  transition:color 140ms var(--e-io)}
.top nav a:hover,.top nav a[aria-current="true"]{color:var(--ink)}
.top-buy{display:flex;align-items:center;gap:14px}
.top-buy a{font-family:var(--f-display);font-weight:800;font-size:var(--t-data);letter-spacing:.04em;
  text-transform:uppercase;color:var(--red);text-decoration:none;padding-block:9px;
  border-bottom:2px solid var(--red)}
.burger{display:flex;flex-direction:column;gap:4px;padding:10px 6px;background:none;border:0;cursor:pointer}
.burger i{width:19px;height:2px;background:var(--ink);transition:transform 200ms var(--e-io),opacity 140ms}
.burger[aria-expanded="true"] i:nth-child(1){transform:translateY(6px) rotate(45deg)}
.burger[aria-expanded="true"] i:nth-child(2){opacity:0}
.burger[aria-expanded="true"] i:nth-child(3){transform:translateY(-6px) rotate(-45deg)}
#menu{display:none;padding-bottom:16px}
#menu[data-open="true"]{display:block}
#menu a{display:block;font-family:var(--f-display);font-weight:800;font-size:var(--t-d3);font-style:italic;
  text-transform:uppercase;letter-spacing:-.02em;text-decoration:none;padding-block:9px}

/* ------------------------------------------------- the cover's corner device
   Two corners cut and an offset red bracket at the other two, lifted off the
   printed card so the page and the product carry the same mark. Not a border:
   the brackets stand away from the image and never close around it. */
.cut{--cut:clamp(30px,8.2%,84px);--bk:clamp(28px,7.4%,78px);--bo:clamp(9px,1.9%,19px);--bt:4px;
  position:relative;display:block;
  /* the marks sit outside the frame, so reserve what they overhang */
  margin-block:calc(var(--bo) + var(--bt) + 10px)}
.cut img{clip-path:polygon(var(--cut) 0,100% 0,100% calc(100% - var(--cut)),
  calc(100% - var(--cut)) 100%,0 100%,0 var(--cut))}
.cut::after{content:"";position:absolute;pointer-events:none;
  inset:calc((var(--bo) + var(--bt)) * -1);
  background:
    linear-gradient(var(--red),var(--red)) no-repeat right calc(var(--bo) + var(--bt)) top 0 / var(--bk) var(--bt),
    linear-gradient(var(--red),var(--red)) no-repeat right 0 top calc(var(--bo) + var(--bt)) / var(--bt) var(--bk),
    linear-gradient(var(--red),var(--red)) no-repeat left calc(var(--bo) + var(--bt)) bottom 0 / var(--bk) var(--bt),
    linear-gradient(var(--red),var(--red)) no-repeat left 0 bottom calc(var(--bo) + var(--bt)) / var(--bt) var(--bk)}

/* a quiet full-bleed ground. Not a third loud bleed: no saturation, just the
   recessed paper, so "what turns up" reads as its own shelf. */
.s-tint{background:var(--paper-2)}

/* ------------------------------------------------------------------ shop */
.shop{display:flex;flex-direction:column;gap:clamp(30px,4vw,56px)}
.shop-art{display:flex;flex-direction:column;gap:clamp(16px,2.4vw,30px)}
/* ---------------------------------------------- the object on its own ground
   The product is white and the page is white, so on paper the pack shot had no
   edge at all: photograph 254,254,254 against a ground of 255,255,255, the
   product dissolving off the bottom of the screen with nothing to stop it.
   The spec already answers this — wherever the banner is shown as an object it
   sits on the moor in flat light, because that is the condition it is made for.
   Painted from the scene's own fixed palette so it agrees with every diagram. */
.shop-stage{margin:0;padding:clamp(20px,3.2vw,54px);
  background:linear-gradient(168deg,#77826f 0%,#4e5749 64%,#3c4433 100%)}
.shop-stage img{display:block;width:100%;height:auto}
/* the specification is a table, so it gets the whole width and its heading
   sits on one line above it — not the heading-left/content-right shape the
   section after it already uses */
.spec-head{display:flex;flex-wrap:wrap;align-items:baseline;justify-content:space-between;
  gap:16px clamp(30px,4vw,64px)}
.shop-cap{margin-top:14px;font-family:var(--f-data);font-weight:500;font-size:var(--t-data);
  letter-spacing:.02em;line-height:1.5;color:var(--ink-3);max-width:54ch}
.shop-stage figcaption{margin-top:12px;font-family:var(--f-data);font-weight:500;
  font-size:var(--t-data);letter-spacing:.02em;color:var(--ink-3);max-width:52ch}
.shop-shot img{display:block;width:100%;height:auto}

/* the order reads as a document: the name leads, then what it is, then the
   numbers under a rule. Hairlines, because a border here describes the break
   between description and transaction and nothing else. */
.shop-buy .price{font-size:var(--t-d3);line-height:1;letter-spacing:-.03em}
.shop-rule{height:1px;background:var(--rule);margin-block:clamp(22px,2.6vw,34px)}
.shop-money{display:flex;flex-wrap:wrap;align-items:baseline;gap:8px 20px}
.shop-buy .price{margin:0}

/* in stock, low, none, or not known — the dot carries it and the words say it */
.avail{display:flex;align-items:flex-start;gap:10px;margin-top:clamp(22px,3vw,34px);
  font-family:var(--f-data);font-weight:500;font-size:var(--t-data);letter-spacing:.04em;
  color:var(--ink-2)}
.avail .dot{width:9px;height:9px;flex:none;border-radius:50%;background:var(--ink-3);
  margin-top:5px}  /* on the first line, not the middle one, when the message wraps */
.avail[data-state="in"]  .dot{background:oklch(0.520 0.120 150)}
.avail[data-state="low"] .dot{background:oklch(0.640 0.150 70)}
.avail[data-state="out"] .dot{background:var(--red)}

.order{display:flex;flex-direction:column;gap:20px;margin-top:clamp(24px,3vw,36px);
  padding-top:clamp(24px,3vw,36px);border-top:1px solid var(--rule)}
.order-row{display:flex;flex-wrap:wrap;align-items:flex-end;gap:28px}
.order .fld span{display:block;font-family:var(--f-data);font-weight:500;font-size:var(--t-label);
  letter-spacing:.1em;text-transform:uppercase;color:var(--ink-3);margin-bottom:6px}
.order select{font:inherit;font-size:var(--t-lead);font-weight:300;padding:8px 26px 10px 0;
  border:0;border-bottom:2px solid var(--rule-2);border-radius:0;background:none;color:var(--ink);
  min-width:5ch;cursor:pointer}
.order select:focus{border-bottom-color:var(--red);outline:none}
.order select:focus-visible{outline:2px solid var(--red);outline-offset:6px}
.order-total{display:flex;flex-direction:column;gap:6px}
.order-total .l{font-family:var(--f-data);font-weight:500;font-size:var(--t-label);letter-spacing:.1em;
  text-transform:uppercase;color:var(--ink-3)}
.order-total .v{font-family:var(--f-display);font-weight:800;font-size:var(--t-d3);
  font-variant-numeric:tabular-nums;letter-spacing:-.02em}
.order .cta{align-self:flex-start}
.order .cta[aria-disabled="true"]{background:var(--ink-3);cursor:not-allowed}
.order .cta[aria-disabled="true"]:hover{background:var(--ink-3);transform:none}
.order-note{font-family:var(--f-data);font-weight:500;font-size:var(--t-data);color:var(--ink-3);
  max-width:46ch}

/* ------------------------------------------------------------------ hero */
.hero{padding-top:clamp(18px,3vw,40px);padding-bottom:clamp(26px,3.5vw,52px);position:relative}
.hero h1{position:relative;z-index:2}
.hero h1 em{font-style:italic;color:var(--red)}
.hero-top{display:flex;flex-direction:column;gap:clamp(18px,2.6vw,30px)}
.hero-body{display:flex;flex-direction:column;gap:22px;margin-top:clamp(22px,3vw,40px)}
.hero-body .lead{max-width:62ch}
.hero-go{display:flex;flex-wrap:wrap;align-items:center;gap:10px 28px}
.hero-facts{display:flex;flex-wrap:wrap;gap:6px 22px;font-family:var(--f-data);font-weight:500;
  font-size:var(--t-data);letter-spacing:.08em;text-transform:uppercase;color:var(--ink-3)}
.hero-facts b{color:var(--red);font-weight:500}

/* the product as an object, not a rectangle on a panel */
.banner{--w:min(92%,560px);width:var(--w);aspect-ratio:1850/600;position:relative;background:#fff;
  display:grid;place-items:center;container-type:inline-size;
  box-shadow:0 1px 0 rgb(0 0 0/.16),0 2px 0 rgb(0 0 0/.05);
  outline:1px solid rgb(0 0 0/.13);outline-offset:-1px}
.banner .sos-print{font-family:var(--f-print);font-weight:700;font-size:25cqw;line-height:.76;
  color:#ED1C24;letter-spacing:.015em}
.banner i{position:absolute;width:2.3cqw;height:2.3cqw;max-width:10px;max-height:10px;border-radius:50%;
  background:#efeae6;box-shadow:inset 0 0 0 1px rgb(0 0 0/.3)}
.banner i:nth-of-type(1){left:2.2cqw;top:6.6cqw}
.banner i:nth-of-type(2){right:2.2cqw;top:6.6cqw}
.banner i:nth-of-type(3){left:2.2cqw;bottom:6.6cqw}
.banner i:nth-of-type(4){right:2.2cqw;bottom:6.6cqw}
.banner.laid{transform:perspective(1500px) rotateX(46deg) rotateZ(-9deg);
  filter:drop-shadow(0 34px 26px rgb(28 32 26/.30))}
/* Deliberately much larger than the header's horizontal lockup directly above
   it. At a similar size the two read as the same mark printed twice. */
.hero-mark{width:clamp(116px,15vw,204px);height:auto;display:block;flex:none;
  margin-bottom:clamp(22px,3vw,38px)}
/* The photograph is the argument, so it is the object in the hero rather than
   a drawing of the product. Its own caption says what to look at. */
.hero-obj{margin:0;padding-block:clamp(30px,4.2vw,56px) 0}
.hero-obj picture{display:block}
.hero-obj img{display:block;width:100%;height:auto;aspect-ratio:990/560;object-fit:cover;
  box-shadow:0 18px 30px -22px rgb(28 32 26/.55)}
.hero-obj figcaption{margin-top:6px;max-width:60ch;font-family:var(--f-data);font-weight:500;
  font-size:var(--t-label);letter-spacing:.06em;color:var(--ink-3);max-width:46ch}

/* ---------------------------------------------------- the horizon strip */
.horizon{position:relative;background:#dfe5e6;overflow:hidden;
  margin-inline:calc(50% - 50vw);width:100vw}
.horizon svg{display:block;width:100%;height:auto;aspect-ratio:1000/420}
.hud{position:absolute;left:0;bottom:0;display:flex;flex-wrap:wrap;align-items:baseline;gap:4px 22px;
  padding:10px 14px;font-family:var(--f-data);font-weight:500;font-size:var(--t-label);letter-spacing:.06em;
  text-transform:uppercase;color:#2c3430;background:rgb(255 255 255/.72);backdrop-filter:blur(3px)}
.hud b{font-weight:500;color:#111}
.replay{position:absolute;right:12px;bottom:12px;background:rgb(255 255 255/.8);border:0;
  font-family:var(--f-data);font-weight:500;font-size:var(--t-label);letter-spacing:.1em;text-transform:uppercase;
  padding:8px 12px;cursor:pointer;color:#2c3430}
.replay:hover{background:#fff}
.strip-note{display:flex;flex-wrap:wrap;justify-content:space-between;gap:6px 22px;padding-top:9px;
  font-family:var(--f-data);font-weight:500;font-size:var(--t-label);color:var(--ink-3)}

/* the control line: one row, a rule above it, nothing boxed */
.dial{border-top:1px solid var(--rule);margin-top:26px;padding-top:18px;
  display:flex;flex-direction:column;gap:18px}
.dial-row{display:flex;align-items:center;gap:16px}
.dial-row label{font-family:var(--f-data);font-weight:500;font-size:var(--t-label);letter-spacing:.1em;
  text-transform:uppercase;color:var(--ink-3);white-space:nowrap}
input[type=range]{flex:1;appearance:none;height:30px;background:transparent;cursor:ew-resize}
input[type=range]::-webkit-slider-runnable-track{height:1px;background:var(--rule-2)}
input[type=range]::-moz-range-track{height:1px;background:var(--rule-2)}
input[type=range]::-webkit-slider-thumb{appearance:none;width:16px;height:16px;margin-top:-8px;
  border-radius:50%;background:var(--red)}
input[type=range]::-moz-range-thumb{width:16px;height:16px;border:0;border-radius:50%;background:var(--red)}
.figs{display:flex;flex-wrap:wrap;gap:18px 40px}
.fig{display:flex;flex-direction:column;gap:2px}
.fig .n{font-family:var(--f-data);font-weight:500;font-size:var(--t-d3);
  font-variant-numeric:tabular-nums;line-height:1;letter-spacing:-.02em}
.fig .n u{text-decoration:none;font-size:var(--t-data);color:var(--ink-3);margin-left:.3em}
.fig .l{font-family:var(--f-data);font-weight:500;font-size:var(--t-label);letter-spacing:.1em;
  text-transform:uppercase;color:var(--ink-3)}
.fig.hot .n{color:var(--red)}
.verdict{font-family:var(--f-display);font-weight:800;font-style:italic;text-transform:uppercase;
  font-size:var(--t-d3);line-height:1.02;letter-spacing:-.025em;max-width:26ch}
.find{align-self:flex-start;background:none;border:0;padding:4px 0;cursor:pointer;color:var(--red);
  font-family:var(--f-data);font-weight:500;font-size:var(--t-label);letter-spacing:.1em;text-transform:uppercase;
  border-bottom:1px solid currentColor;padding-bottom:5px}

/* -------------------------------------------------------- display figures */
.figures{display:flex;flex-wrap:wrap;gap:clamp(26px,5vw,72px);align-items:flex-end}
.figure{display:flex;flex-direction:column;gap:10px}
.figure .v{font-family:var(--f-display);font-weight:800;font-size:var(--t-d2);
  line-height:.86;letter-spacing:-.04em;font-variant-numeric:tabular-nums}
.figure .l{font-family:var(--f-data);font-weight:500;font-size:var(--t-label);letter-spacing:.1em;
  text-transform:uppercase;color:var(--ink-3);line-height:1.5}

/* ------------------------------------------------------------ the pack-down */
.pack{display:flex;flex-direction:column;gap:clamp(26px,3.4vw,48px)}
.pack-head .lead{max-width:40ch}
/* The spec names this one: wherever the banner is shown as an object it sits
   on the moor in flat light. It was on --moor-pale at 0.93 lightness, which is
   a white product on a near-white ground — the property being sold, hidden.
   Same gradient as the shop stage, so the two agree. */
.pack-stage{position:relative;max-width:900px;
  background:linear-gradient(168deg,#77826f 0%,#4e5749 64%,#3c4433 100%)}
.pack-meta{display:flex;flex-wrap:wrap;align-items:baseline;justify-content:space-between;gap:14px 30px}

/* ------------------------------------------------------- fold, and bag it
   Four scenes, cross-faded, each drawn at its own true geometry at one
   shared scale of 0.38919 px per mm: 1850x600 flat, 925x300 folded once
   each way, 115x150 after four more folds, and the 130x190 mm portrait bag
   with the zip across its short top edge. Because 115 mm at banner scale is
   a 45px speck, the stage zooms in as the object shrinks — so the ruler at
   the bottom stays outside the zoom and carries the real size reduction.
   An earlier version clipped one sheet instead. It could not work: the
   element transform that zooms the stage also transforms the clip, so the
   window and the artwork moved against each other. */
.pk{display:block;width:100%;height:auto;aspect-ratio:1000/420}
.pk text{line-height:1}
.pk-ground{fill:none}   /* the stage paints the ground now */

.pk-stage{transition:transform 900ms var(--e-soft)}

/* ---- the fold itself -------------------------------------------------
   Folding in half, seen from above, is a reflection about the crease. The
   half being folded scales to zero width about the crease while the back
   of it sweeps out of that same line across the half that stays. Nothing
   is squashed: the face keeps its proportions right up to the moment it
   goes edge-on, which is what folding actually looks like.
   Only the long-way fold is played. The short-way fold and the four after
   it are carried by the frame tightening onto the result — a fold that
   works beats two that fight each other's clip paths. */
.pk-turn,.pk-backf{transform-box:view-box;transform-origin:500px 200px;
  transition:transform 520ms var(--e-io)}
.pk-backf{transform:scaleX(0);fill:#fbfbfa}
.pk-crease-x{stroke:rgb(28 32 26/.42);stroke-width:1.4;fill:none;opacity:0;
  vector-effect:non-scaling-stroke;transition:opacity 200ms var(--e-io)}
.pk-turn-y,.pk-backy{transform-box:view-box;transform-origin:500px 200px;
  transition:transform 520ms var(--e-io)}
.pk-backy{transform:scaleY(0);fill:#fbfbfa}
.pk-crease-y{stroke:rgb(28 32 26/.42);stroke-width:1.4;fill:none;opacity:0;
  vector-effect:non-scaling-stroke;transition:opacity 200ms var(--e-io)}
/* the scene slides as it folds so the result lands exactly where the next
   scene already is, and the handover has nothing to give away */
.pk-flat{transform-box:view-box;transform-origin:500px 200px;
  transition:transform 520ms var(--e-io)}
.pack.folding .pk-turn{transform:scaleX(0)}
.pack.folding .pk-backf{transform:scaleX(1)}
.pack.folding .pk-crease-x{opacity:1}
.pack.folding .pk-flat{transform:translateX(180px)}
.pack.half .pk-flat{opacity:0}
.pack.half .pk-half{opacity:1}
.pack.half.folding-y .pk-turn-y{transform:scaleY(0)}
.pack.half.folding-y .pk-backy{transform:scaleY(1)}
.pack.half.folding-y .pk-crease-y{opacity:1}
.pack.half.folding-y .pk-half{transform:translateY(58.4px);transform-box:view-box;
  transform-origin:500px 200px;transition:transform 520ms var(--e-io)}
.pack.f1 .pk-half,.pack.f2 .pk-half,.pack.bagged .pk-half{opacity:0}
/* the camera must already be back at the wide frame before the fold starts */
.pack.pk-instant .pk-stage,.pack.pk-instant .pk-sc,
.pack.pk-instant .pk-rule-bar,.pack.pk-instant .pk-rule-end{transition:none}

.pk-sc{opacity:0;transition:opacity 420ms var(--e-io)}
.pk-flat,.pk-half,.pk-f1{transition:opacity 140ms linear,transform 520ms var(--e-io)}
.pk-sc rect[fill="#fff"],.pk-pad{filter:drop-shadow(0 5px 6px rgb(28 32 26/.22))}
.pk-edge{fill:none;stroke:rgb(28 32 26/.32);stroke-width:1.2;vector-effect:non-scaling-stroke}
.pk-eye{fill:#efeae6;stroke:rgb(28 32 26/.38);stroke-width:1;vector-effect:non-scaling-stroke}
/* the cut edges of the folded layers, and the closed edges that are folds */
.pk-lay{fill:none;stroke:rgb(28 32 26/.30);stroke-width:.7;vector-effect:non-scaling-stroke}
.pk-crease{fill:none;stroke:rgb(28 32 26/.45);stroke-width:1.4;stroke-linecap:round;
  vector-effect:non-scaling-stroke}

/* deployed -> one fold each way -> four more -> bagged. The zoom is about the
   centre of the stage, which is where every scene is centred. */
.pack .pk-flat{opacity:1}
.pack.f1 .pk-flat,.pack.f2 .pk-flat,.pack.bagged .pk-flat{opacity:0}
.pack.folding .pk-flat{opacity:1}
.pack.folding .pk-f1{opacity:0}
.pack.f1 .pk-f1{opacity:1}
.pack.f2 .pk-f2,.pack.bagged .pk-f2{opacity:1}
.pack.f2 .pk-f1,.pack.bagged .pk-f1{opacity:0}
.pack.bagged .pk-f2{opacity:.5;transition-delay:260ms}
.pack.f1 .pk-stage{transform:translate(500px,200px) scale(1.9) translate(-500px,-200px)}
.pack.f2 .pk-stage{transform:translate(500px,200px) scale(4.2) translate(-500px,-200px)}
.pack.bagged .pk-stage{transform:translate(500px,200px) scale(5) translate(-500px,-200px)}

.pack.bagged .pk-bag{opacity:1;transition-delay:380ms}
.pk-bag-body{fill:#f3f6f7}
.pk-pad{fill:#fff}
.pk-bag-film{fill:url(#pk-poly);stroke:rgb(28 32 26/.28);stroke-width:.35}
.pk-zip{fill:#e4ebee;stroke:rgb(28 32 26/.22);stroke-width:.2}
.pk-zip-l{fill:rgb(28 32 26/.18)}
.pk-tab{fill:#dbe3e7;stroke:rgb(28 32 26/.2);stroke-width:.2}
.pk-card{opacity:.95}

/* the ruler: one length, at true scale, never zoomed */
.pk-rule-bar{fill:rgb(255 255 255/.74);transition:width 760ms var(--e-soft)}
.pk-rule-tick{stroke:rgb(255 255 255/.74);stroke-width:1.2}
.pk-rule-end{transform:translateX(720px);transition:transform 760ms var(--e-soft)}
.pk-rule text{font-family:var(--f-data);font-weight:500;font-size:13px;letter-spacing:.1em;
  fill:rgb(255 255 255/.78);text-transform:uppercase;dominant-baseline:hanging}
.pack.f1 .pk-rule-bar{width:360px}
.pack.f1 .pk-rule-end{transform:translateX(360px)}
.pack.f2 .pk-rule-bar,.pack.bagged .pk-rule-bar{width:44.8px}
.pack.f2 .pk-rule-end,.pack.bagged .pk-rule-end{transform:translateX(44.8px)}

/* both faces of the bag card, shown as the printed artwork they are.
   Not .cards: that name is taken further down by the article pages. */
.bagcard{margin:clamp(40px,6vw,80px) 0 0;padding:0;display:grid;gap:clamp(20px,3vw,44px);
  grid-template-columns:minmax(0,1fr)}
.bagcard-art{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:clamp(14px,2.4vw,30px)}
.bagcard-art img{display:block;width:100%;height:auto;border:1px solid var(--rule);
  box-shadow:0 10px 24px rgb(28 32 26/.14)}
.bagcard figcaption{font-size:var(--t-small);color:var(--ink-3);max-width:40ch;align-self:end;margin:0}

/* ask before you order — the only thing the public site writes anywhere */
.ask{display:flex;flex-direction:column;gap:14px}
.ask-row{display:flex;flex-direction:column;gap:20px;align-items:stretch}
.ask .fld{display:block}
.ask .fld.grow{flex:none}
.ask .fld span{display:block;font-family:var(--f-data);font-weight:500;font-size:var(--t-label);
  letter-spacing:.1em;text-transform:uppercase;color:var(--ink-3);margin-bottom:6px}
.ask .fld i{font-style:normal;opacity:.6}
.ask input{width:100%;font:inherit;font-size:var(--t-lead);font-weight:300;padding:8px 0 10px;
  border:0;border-bottom:2px solid var(--rule-2);border-radius:0;background:none;color:var(--ink);
  transition:border-color 160ms var(--e-io)}
.ask input::placeholder{color:var(--ink-3);opacity:1}
.ask input:hover{border-bottom-color:var(--ink-3)}
.ask input:focus{border-bottom-color:var(--red);outline:none}
.ask input:focus-visible{outline:2px solid var(--red);outline-offset:6px}
.ask .cta{padding:14px 22px;align-self:flex-start}
.ask-say{font-family:var(--f-data);font-weight:500;font-size:var(--t-data);color:var(--ink-3)}
.ask-say[data-state="bad"]{color:var(--red)}

.pack-sw{display:inline-flex;gap:20px;align-self:flex-start}
.pack-sw button{background:none;border:0;padding:5px 0;cursor:pointer;color:var(--ink-3);
  font-family:var(--f-data);font-weight:500;font-size:var(--t-label);letter-spacing:.1em;text-transform:uppercase;
  border-bottom:2px solid transparent}
.pack-sw button[aria-pressed="true"]{color:var(--ink);border-color:var(--red)}
.pack-cap{font-family:var(--f-data);font-weight:500;font-size:var(--t-label);letter-spacing:.08em;
  text-transform:uppercase;color:var(--ink-3);min-height:1.4em;margin:0}

/* --------------------------------------------------------- the claim list */
.claims{display:flex;flex-direction:column}
.claims li{list-style:none;display:grid;gap:6px;padding-block:26px;border-top:1px solid var(--rule)}
.claims li:last-child{border-bottom:1px solid var(--rule)}
.claims .l{font-family:var(--f-data);font-weight:500;font-size:var(--t-label);letter-spacing:.12em;
  text-transform:uppercase;color:var(--red)}
.claims p{color:var(--ink-2);max-width:44ch}

/* ---------------------------------------------------- the procedure, in red */
.crumb ~ .band > .col{width:min(100% - (var(--gutter) * 2),62rem)}
.band{background:var(--red);color:var(--on-red);padding-block:clamp(52px,7vw,104px);
  margin-block:clamp(56px,8vw,120px)}
.band h2{color:#fff}
.band .kicker{color:#fff;opacity:.72}
.band .lead{color:#fff;opacity:.9}
.steps{list-style:none;margin:0;padding:0;display:grid;gap:0}
.steps li{counter-increment:st;display:grid;grid-template-columns:auto 1fr;gap:0 18px;
  padding-block:22px;border-top:1px solid rgb(255 255 255/.3)}
.steps li::before{content:counter(st,decimal-leading-zero);font-family:var(--f-data);font-weight:500;
  font-size:var(--t-data);letter-spacing:.06em;color:#fff;opacity:.7;padding-top:.5em}
.steps b{display:block;font-family:var(--f-display);font-weight:800;font-size:var(--t-d3);
  font-style:italic;text-transform:uppercase;letter-spacing:-.02em;line-height:1.02;margin-bottom:7px}
.steps p{color:#fff;opacity:.92;max-width:52ch}
.notes{display:grid;gap:22px;margin-top:clamp(34px,4vw,56px);padding-top:26px;
  border-top:2px solid rgb(255 255 255/.5)}
.note .l{font-family:var(--f-data);font-weight:500;font-size:var(--t-label);letter-spacing:.12em;
  text-transform:uppercase;opacity:.72;margin-bottom:6px}
.note p{color:#fff;max-width:46ch;font-size:var(--t-small)}

/* ------------------------------------------------------------------- spec */
.spec{display:grid;gap:0;margin:0}
.spec div{display:grid;grid-template-columns:1fr auto;gap:12px 24px;padding-block:15px;
  border-top:1px solid var(--rule);align-items:baseline}
.spec div:last-child{border-bottom:1px solid var(--rule)}
/* eleven facts read as a datasheet in two columns, not as one long list with
   three quarters of a metre of nothing between each label and its value */
@media (min-width:880px){
  .spec-wide{grid-auto-flow:column;grid-template-rows:repeat(6,auto);
    column-gap:clamp(36px,4.4vw,78px)}
  .spec-wide div:nth-child(6){border-bottom:1px solid var(--rule)}
}
.spec dt{font-family:var(--f-data);font-weight:500;font-size:var(--t-label);letter-spacing:.1em;
  text-transform:uppercase;color:var(--ink-3)}
.spec dd{margin:0;text-align:right}

/* -------------------------------------------------------------------- buy */
.price{font-family:var(--f-display);font-weight:800;font-style:italic;
  font-size:var(--t-d1);line-height:.78;letter-spacing:-.05em}
.incl{display:flex;flex-wrap:wrap;gap:6px 22px;font-family:var(--f-data);font-weight:500;
  font-size:var(--t-data);letter-spacing:.08em;text-transform:uppercase;color:var(--ink-3)}

/* -------------------------------------------------------------------- faq */
.faq details{border-top:1px solid var(--rule)}
.faq details:last-of-type{border-bottom:1px solid var(--rule)}
.faq summary{list-style:none;cursor:pointer;display:flex;gap:20px;align-items:baseline;
  justify-content:space-between;padding-block:22px;font-family:var(--f-display);font-weight:600;
  font-size:var(--t-d3);letter-spacing:-.015em}
.faq summary::-webkit-details-marker{display:none}
.faq summary::after{content:"";width:13px;height:13px;flex:0 0 auto;align-self:center;
  background:linear-gradient(var(--red),var(--red)) center/100% 2px no-repeat,
             linear-gradient(var(--red),var(--red)) center/2px 100% no-repeat;
  transition:transform 240ms var(--e-out)}
.faq details[open] summary::after{
  background:linear-gradient(var(--red),var(--red)) center/100% 2px no-repeat}
.faq p{padding-bottom:24px;color:var(--ink-2);max-width:62ch}

/* ----------------------------------------------------------------- footer */
.foot{padding-block:clamp(46px,6vw,88px) 34px;border-top:2px solid var(--ink);
  margin-top:clamp(56px,8vw,120px)}
.foot a{text-decoration:none;border-bottom:1px solid transparent}
.foot a:hover{border-color:var(--red)}
.foot-nav{display:flex;flex-wrap:wrap;gap:2px 26px;font-family:var(--f-data);font-weight:500;
  font-size:var(--t-label);letter-spacing:.09em;text-transform:uppercase}
.foot-nav a{display:inline-block;padding-block:8px}
.alert{border-left:3px solid var(--red);padding-left:18px;max-width:44ch}
.alert p.l{font-family:var(--f-display);font-weight:800;font-style:italic;text-transform:uppercase;
  font-size:var(--t-d3);letter-spacing:-.02em;color:var(--red);margin-bottom:5px}
.alert p{font-size:var(--t-small);color:var(--ink-2)}
.fine{display:flex;flex-wrap:wrap;gap:6px 24px;justify-content:space-between;padding-top:26px;
  margin-top:36px;border-top:1px solid var(--rule);font-family:var(--f-data);font-weight:500;
  font-size:var(--t-label);color:var(--ink-3)}

/* ------------------------------------------------------------- sticky buy */
.bar{position:fixed;inset:auto 0 0 0;z-index:55;display:flex;align-items:center;justify-content:space-between;
  gap:14px;padding:11px var(--gutter);background:var(--paper);border-top:1px solid var(--rule);
  transform:translateY(110%);transition:transform 300ms var(--e-soft)}
.bar[data-show="true"]{transform:none}
.bar .p{font-family:var(--f-display);font-weight:800;font-style:italic;font-size:var(--t-d3);letter-spacing:-.02em}
.bar .cta{padding:13px 18px;font-size:var(--t-data)}

/* ============================== section rhythm ============================ */
.s{padding-block:clamp(52px,7vw,104px)}
.s-open{padding-top:clamp(76px,11vw,152px)}
.s-tight{padding-top:18px}
.s-flush{padding-bottom:22px}
.s-close{padding-bottom:clamp(88px,12vw,176px)}
/* full width, ruled rather than filled: a third container width without a box */
.s-band{width:100%;border-top:1px solid var(--rule);padding-block:clamp(44px,6vw,84px)}
.s-band > .col{width:min(100% - (var(--gutter) * 2),62rem);margin-inline:auto}
.s-narrow,.col-art{width:min(100% - (var(--gutter) * 2),62rem);margin-inline:auto}
.s-narrow > .col{width:100%}

/* ================================ desktop ================================ */
@media (min-width:880px){
  :root{--gutter:38px}
  .top nav{display:flex}
  .burger,#menu{display:none !important}
  .bar{display:none}

  /* hero: the mark is a block on the left at real size, the headline stacks
     beside it, and the body runs the full measure under both */
  .hero{padding-bottom:clamp(40px,5vw,80px)}
  .hero-stage{position:relative}
  /* The mark and the headline are one block, and the block has one height.
     Two lines of display at 0.82 leading is 1.64em, so the type size falls
     out of the height rather than being picked separately — which is what
     keeps them level at every width. The headline is two short words for the
     same reason: at signage scale nothing longer sits beside a mark this big
     and still fits the measure. */
  /* two lines of display at 0.82 leading is 1.64em, so the mark is exactly as
     tall as the headline beside it and neither was picked separately. */
  .hero-top{--hero-block:calc(var(--t-d1) * 1.64);
    flex-direction:row;align-items:flex-start;gap:clamp(30px,3.6vw,60px)}
  .hero-mark{width:auto;height:var(--hero-block);margin:0}
  .hero h1{flex:1 1 auto;margin:0;text-wrap:initial;font-size:var(--t-d1)}
  .hero-body{margin-top:clamp(30px,4vw,58px)}
  .hero-obj img{aspect-ratio:1000/420}

  /* the shop: what it is on the left, what it costs on the right, and the
     order panel stays with you while the pictures scroll */
  .shop{display:grid;grid-template-columns:minmax(0,7fr) minmax(0,5fr);
    gap:clamp(36px,4.5vw,80px);align-items:start}
  .shop-buy{position:sticky;top:104px}

  .two{display:grid;grid-template-columns:minmax(0,7fr) minmax(0,5fr);gap:clamp(30px,4vw,72px)}
  .two.flip{grid-template-columns:minmax(0,5fr) minmax(0,7fr)}
  .two.even{grid-template-columns:repeat(2,minmax(0,1fr))}
  .two > .end{align-self:end}
  .dial{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:26px 60px;align-items:start}
  .dial-row{grid-column:1 / -1}
  .band-intro{display:grid;grid-template-columns:minmax(0,7fr) minmax(0,5fr);gap:clamp(30px,4vw,72px);
    align-items:end}
  .steps{grid-template-columns:repeat(2,minmax(0,1fr));column-gap:56px}
  .steps li{border-top:1px solid rgb(255 255 255/.3)}
  .notes{grid-template-columns:repeat(3,minmax(0,1fr));gap:34px}
  .pack{display:flex;flex-direction:column}
  /* two cards and the caption beside them, rather than a block of white
     with the right half of the page empty */
  .bagcard{grid-template-columns:minmax(0,7fr) minmax(0,5fr);align-items:end}
  .bagcard-art{max-width:560px}
  /* three claims read as three, not as a stack with a blank right-hand column */
  .claims{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:0 clamp(24px,3vw,54px)}
  .claims li:last-child{border-bottom:0}
  .foot-grid{display:grid;grid-template-columns:minmax(0,4fr) minmax(0,3fr) minmax(0,5fr);
    gap:40px;align-items:start}
}

@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.001ms !important;animation-iteration-count:1 !important;
    transition-duration:.001ms !important;scroll-behavior:auto !important}
}
@media print{.top,.bar,.replay,.pack-sw,.hud{display:none}body{font-size:11pt}}

/* ==========================================================================
   v2.2 — the ziplock, the route profiles, and the article pages
   ========================================================================== */

/* ---- the pack-down: the banner folds and goes into a clear ziplock ------- */
.pack-stage{perspective:1400px}

/* ---- route profiles ----------------------------------------------------- */
.routes{display:flex;flex-direction:column;gap:0}
.route{border-top:1px solid var(--rule);padding-block:clamp(30px,4vw,52px)}
.route:last-child{border-bottom:1px solid var(--rule)}
.route-head{display:flex;flex-wrap:wrap;align-items:baseline;gap:6px 18px}
.route-head h3{font-family:var(--f-display);font-weight:800;font-style:italic;text-transform:uppercase;
  font-size:var(--t-d3);line-height:.96;letter-spacing:-.03em}
.route-where{font-family:var(--f-data);font-weight:500;font-size:var(--t-label);letter-spacing:.1em;
  text-transform:uppercase;color:var(--red)}
.route-body{display:flex;flex-direction:column;gap:22px;margin-top:22px}
.profile{width:100%}
.profile svg{display:block;width:100%;height:auto;aspect-ratio:1000/440;overflow:visible}

/* The line is the subject, so it carries the weight; everything measuring it
   stays underneath. One series, so no legend — the markers name their own
   values, which is the only labelling a single line needs. */
/* the geometry everything is measured against; never painted */
.rp-path{fill:none;stroke:none}
/* the climb, carried by the line: one hue, light at the bottom, dark at the top */
.rp-seg{stroke-width:3.5;stroke-linecap:butt;opacity:0;
  transition:opacity 260ms var(--e-io)}
.profile.drawn .rp-seg{opacity:1}
.rp-tick{stroke:var(--rule-2);stroke-width:2.5;stroke-linecap:round}
.rp-cross{stroke:var(--paper);stroke-width:2.5;stroke-linecap:butt}
.rp-lv{font-family:var(--f-data);font-weight:500;font-size:21px;fill:var(--ink-2);
  letter-spacing:.03em;paint-order:stroke fill;stroke:var(--paper);stroke-width:5px;
  stroke-linejoin:round}
.rp-cont{opacity:0}
.profile.drawn .rp-cont{transition:opacity 500ms var(--e-io) 1500ms;opacity:1}
.rp-key{flex:0 0 44px!important;height:9px!important;border:0!important;border-radius:5px;
  top:1px!important}
.rp-arrow{fill:var(--ink)}
.rp-arrows{opacity:0}
.profile.drawn .rp-arrows{transition:opacity 600ms var(--e-io) 1100ms;opacity:1}
.rp-ticks,.rp-marks{opacity:0}
.profile.drawn .rp-ticks{transition:opacity 600ms var(--e-io) 900ms;opacity:1}
.profile.drawn .rp-marks{transition:opacity 600ms var(--e-io) 1400ms;opacity:1}
.rp-pin{fill:var(--red)}
.rp-pin-eye{fill:var(--paper)}
.rp-node{fill:var(--paper);stroke:var(--ink);stroke-width:3}
/* a paper halo, so a label stays legible wherever it lands — the map
   convention, and cheaper than chasing every last collision by hand */
.rp-txt{font-family:var(--f-data);font-weight:500;font-size:21px;fill:var(--ink);letter-spacing:.04em;
  paint-order:stroke fill;stroke:var(--paper);stroke-width:6px;stroke-linejoin:round}
.rp-txt.hi{font-family:var(--f-display);font-weight:800;font-style:italic;font-size:29px;
  text-transform:uppercase;letter-spacing:-.01em}
/* dropped by its own em, so the line gap tracks the size the breakpoint gives it */
.rp-sub{fill:var(--ink-3);transform:translateY(1.5em)}
/* the drawing is a fixed viewBox, so on a narrow screen its text shrinks with
   the box. These are the sizes that keep it readable at 390px. */
@media (max-width:899px){
  .rp-txt{font-size:30px}.rp-txt.hi{font-size:38px}
  .rp-tick{stroke-width:4}.rp-node{stroke-width:5;r:11}
  .rp-seg{stroke-width:5.5}.rp-cross{stroke-width:4}.rp-lv{font-size:30px}
}
.rp-hair{fill:var(--red);opacity:0}
.rp-tip{font-family:var(--f-data);font-weight:500;font-size:20px;fill:var(--ink);opacity:0}
.profile:hover .rp-hair,.profile:focus-within .rp-hair{opacity:1}
.profile:hover .rp-tip,.profile:focus-within .rp-tip{opacity:1}

/* what the ticks are worth, said once per drawing */
.art p.rp-scale,
.rp-scale{display:flex;align-items:baseline;gap:10px;margin-top:2px;
  font-family:var(--f-data);font-weight:500;font-size:var(--t-label);line-height:1.4;
  letter-spacing:.09em;text-transform:uppercase;color:var(--ink-3);max-width:none}
.rp-scale i{flex:0 0 34px;height:0;border-top:2px solid var(--rule-2);
  position:relative;top:-4px}

.route-facts{display:flex;flex-wrap:wrap;gap:14px 34px}
.rf{display:flex;flex-direction:column;gap:3px}
.rf .v{font-family:var(--f-data);font-weight:500;font-size:var(--t-body);font-variant-numeric:tabular-nums;
  line-height:1}
.rf .l{font-family:var(--f-data);font-weight:500;font-size:var(--t-label);letter-spacing:.1em;
  text-transform:uppercase;color:var(--ink-3)}
.route-note{border-left:3px solid var(--red);padding-left:16px;max-width:52ch}
.route-note b{display:block;font-family:var(--f-display);font-weight:800;font-style:italic;
  text-transform:uppercase;font-size:var(--t-small);letter-spacing:-.01em;color:var(--red);margin-bottom:4px}
.route-src{font-family:var(--f-data);font-weight:500;font-size:var(--t-label);color:var(--ink-3);max-width:46ch}
.route-src a{display:inline-block;padding-block:4px;color:var(--ink-3)}
.notnav{border-left:4px solid var(--red);padding:2px 0 2px clamp(16px,2vw,26px);
  max-width:60ch;font-size:var(--t-small);color:var(--ink-2)}
.notnav b{font-family:var(--f-display);font-weight:800;font-style:italic;text-transform:uppercase;
  color:var(--red);display:block;margin-bottom:4px;letter-spacing:-.01em}

/* ---- article pages ------------------------------------------------------ */
.crumb{font-family:var(--f-data);font-weight:500;font-size:var(--t-label);letter-spacing:.08em;
  text-transform:uppercase;color:var(--ink-3);padding-top:clamp(22px,3vw,38px)}
.crumb a{display:inline-block;color:var(--ink-3);text-decoration:none;
  border-bottom:1px solid var(--rule-2);padding-block:6px}
.crumb a:hover{color:var(--red);border-color:var(--red)}
/* The article ran as one left-aligned ribbon: every paragraph 54ch inside a
   62rem container, so four hundred pixels of the page trailed off unused down
   the whole right-hand side and every line ended somewhere different. The
   measure stays where it is; the space it leaves becomes a side column and
   carries the sources and the pull quotes. Dense flow backfills a side cell
   into the row above, so a source sits beside the paragraph it belongs to
   rather than starting a row of its own. */
/* one column on a phone: there is no margin to hang a side note in, and a
   54ch text track forced 150px of horizontal scroll at 390. */
.art{display:grid;grid-template-columns:minmax(0,1fr);
  row-gap:clamp(22px,2.8vw,38px);align-items:start}
.art > .cite,.art > .pull{margin:0}
.art h2{margin-top:clamp(18px,2.5vw,32px)}
.art .say,.art p{max-width:54ch}
.art .pull{max-width:none}
.art .lead{max-width:46ch}


/* The measure, and the space it leaves put to work: the sources and the pull
   quotes hang in the margin beside the prose rather than interrupting it.

   This block has to live AFTER the single-column base rule above, not up in
   the main desktop media query: same specificity, so source order decides, and
   for three releases the base rule won at every width and this layout never
   rendered at all.

   `grid-column: text` is shorthand for `text / text` — start AND end on the
   same named line. With one line called text the grid invents an implicit
   track to end on and strands the prose in it. Always name the span. */
@media (min-width:880px){
  /* not `dense`: dense lets a later margin note jump backwards into an earlier
     hole, which put the emergencySMS source above the heading it belongs to.
     Plain row flow places a note in the row of the item it follows. */
  .art{grid-auto-flow:row;
    grid-template-columns:[text] minmax(0,54ch) [side] minmax(0,1fr);
    column-gap:clamp(28px,3.6vw,60px)}
  .art > *{grid-column:text / span 1}
  .art > .cite,.art > .pull{grid-column:side / span 1}
  /* the route plans are the page, not a note in the margin: full width */
  .art > .stat-row,.art > .breakdown,.art > .rp,.art > figure,
  .art > .routes,.art > .notnav,.art > .cards{grid-column:text / -1}
}
.stat-row{display:flex;flex-wrap:wrap;gap:clamp(26px,5vw,68px);align-items:flex-end}
.stat .v{font-family:var(--f-display);font-weight:800;font-size:var(--t-d2);
  line-height:.86;letter-spacing:-.04em;font-variant-numeric:tabular-nums}
.stat .v.red{color:var(--red)}
.stat .l{font-family:var(--f-data);font-weight:500;font-size:var(--t-label);letter-spacing:.1em;
  text-transform:uppercase;color:var(--ink-3);line-height:1.5;margin-top:10px;max-width:22ch;display:block}
.cite{font-family:var(--f-data);font-weight:500;font-size:var(--t-label);color:var(--ink-3);
  line-height:1.7;max-width:56ch}
.cite a{display:inline-block;padding-block:4px;color:var(--ink-3)}
.cite a:hover{color:var(--red)}
/* Every row was its own grid with an `auto` label column, so the track was
   whatever that row's label left over: a 78% bar could be drawn shorter than a
   23% one, and on a phone the long labels squeezed the track to nothing. The
   parent owns the columns now and the rows borrow them, so one length means
   one number on every row. Phone stacks the label under its bar instead. */
.breakdown{display:grid;grid-template-columns:3.4rem minmax(0,1fr)}
.breakdown > div{grid-column:1 / -1;display:grid;grid-template-columns:subgrid;
  gap:7px 14px;align-items:center;padding-block:11px;border-top:1px solid var(--rule)}
.breakdown .t{grid-column:2}
.breakdown div:last-child{border-bottom:1px solid var(--rule)}
.breakdown .p{font-family:var(--f-data);font-weight:500;font-size:var(--t-body);font-variant-numeric:tabular-nums}
.breakdown .trk{height:8px;background:var(--rule);position:relative}
.breakdown .trk i{position:absolute;inset:0 auto 0 0;width:var(--w);background:var(--ink)}
.breakdown div[data-hot] .trk i{background:var(--red)}
.breakdown div[data-hot] .p{color:var(--red)}
.breakdown .t{font-family:var(--f-text);font-size:var(--t-small);color:var(--ink-2)}

/* three shared columns on a wide screen, so the bars line up and compare.
   After the base rules, not up in the main desktop block: same specificity,
   so source order decides — the trap that hid the article layout for three
   releases. */
@media (min-width:880px){
  .breakdown{grid-template-columns:4.5rem minmax(140px,1fr) minmax(0,auto)}
  .breakdown > div{gap:0 18px}
  .breakdown .t{grid-column:auto;text-align:right}
}
.pull{font-family:var(--f-display);font-weight:800;font-style:italic;text-transform:uppercase;
  font-size:var(--t-d3);line-height:1.05;letter-spacing:-.03em;max-width:20ch;
  border-left:4px solid var(--red);padding-left:clamp(16px,2vw,26px)}
.cards{display:flex;flex-direction:column;gap:0}
.cardrow{display:grid;gap:6px;padding-block:24px;border-top:1px solid var(--rule)}
.cardrow:last-child{border-bottom:1px solid var(--rule)}
.cardrow a{font-family:var(--f-display);font-weight:800;font-style:italic;text-transform:uppercase;
  font-size:var(--t-d3);letter-spacing:-.025em;text-decoration:none;line-height:1.05}
.cardrow a:hover{color:var(--red)}
.cardrow p{color:var(--ink-2);max-width:58ch}

@media (min-width:880px){
  .route-body{display:grid;align-items:center;grid-template-columns:minmax(0,7fr) minmax(0,5fr);
    gap:clamp(26px,3.5vw,54px);align-items:start}
  .route-side{display:flex;flex-direction:column;gap:20px}
  .breakdown div{grid-template-columns:5rem 1fr 15rem}
  .cardrow{grid-template-columns:minmax(0,5fr) minmax(0,7fr);gap:0 clamp(26px,4vw,64px);align-items:baseline}
}
