/* ==========================================================================
   Indore — home.css
   The home page, index.html. (It was product.css / product.html until the
   product page became the front door; the old home page is home-2.html and
   keeps site.css.)

   Loads AFTER css/base.css, which carries the faces, the tokens, the reset,
   .wrap, the display type classes, .cap / .btn / .capsule / .capsule--nav /
   .opill, .mc, .snav and the footer. Nothing here belongs to any other page.

   The page opens on a white hero — logo, one line, a phone tilted away from
   the viewer — which is held for one screen while the phone turns to face
   you. Then it reads as a centre column: a lede, then seven sections.

     00  hero      white, pinned; the phone turns with the scroll (js/home.js)
     01  base      the photograph full-bleed, text over it, the phone on it
     02  sessions  white, the two films side by side
     03  group     white, the two-phone render and a note
     04  routes    the printed contour sheet, the route loop drawn across it,
                   one phone with two readings floating off it
     05  history   white, two phones as a staggered pair
     06  hud       white, the desktop screen
     07  running   surface, text beside the running photograph

   COMPONENTS
     .hero*        the pinned opening and the 3D panel
     .fcap         the floating CTA capsule
     .sec / .sec__head    the section frame and its opening
     .phone .screen       the device frames, drawn in CSS around a flat capture
     .trio         the repeating row of short feature lines
     .note         a speech-bubble glyph beside a small line
     .films .duo .pair .solo .rphoto   the picture arrangements
   ========================================================================== */


/* ---------- focus ----------
   base.css rings focus in white, which is invisible on this page: it is white
   end to end. base.css says to make this override in the page's own sheet. */
.snav :focus-visible,
.footer :focus-visible,
.sec :focus-visible{outline-color:var(--primary)}


/* ==========================================================================
   00 — HERO
   ========================================================================== */
.hero{
  --hp-w:clamp(280px,31.1vw,448px);   /* phone width: 448 at 1440, floor 280 */
  --tilt:30deg;                        /* start angle. TILT in js/home.js
                                          holds the same number — change both */
  background:var(--white);
  /* NO overflow here, and none on any ancestor: sticky would stop working */
}
.hero__stage{
  position:sticky;top:0;
  min-height:100vh;min-height:100lvh; /* safety net only; content is taller */
  display:flex;flex-direction:column;align-items:center;
  padding:64px var(--pad) 128px;
}
/* the scroll distance the hero is held for: one screen, floor 600, cap 1000.
   Two declarations on purpose: a browser without lvh drops the second at
   parse time and keeps the first. Do NOT move this into a custom property;
   an invalid custom property does not fall back to the earlier declaration,
   it makes the height `auto` and the pin silently disappears. */
.hero__runway{height:clamp(600px,100vh,1000px);height:clamp(600px,100lvh,1000px)}
/* The turn happens once. After it the runway has no job, and leaving it there
   means a screen of dead travel every time the page is scrolled back up — so
   the script adds .is-turned and it goes, hero back to an ordinary block.
   In the same frame the script moves the scroll position down by the height
   it just removed, so nothing appears to move. It waits for the scrolling to
   stop before doing either: see the note in js/home.js. */
.hero.is-turned .hero__runway{height:0}

.hero__logo{display:block;height:16px}
.hero__logo img{height:16px;width:auto}
.hero__tag{margin-top:128px;max-width:376px;text-align:center;
  font-family:var(--disp);font-weight:500;font-size:24px;line-height:1.15;
  color:var(--plum)}

/* the phone: wrapper carries the size, the intro fade and the perspective;
   the panel carries the tilt */
.hero__phone{
  width:var(--hp-w);aspect-ratio:498.5/1024;margin-top:64px;flex:0 0 auto;
  perspective:calc(var(--hp-w) * 7.85);
}
.hero__panel{
  position:relative;width:100%;height:100%;
  transform:rotateX(var(--tilt));      /* rest state before JS runs */
  transform-origin:50% 50%;
  backface-visibility:hidden;
  will-change:transform;               /* its own compositing layer, from the start */
}
.hero__body{position:absolute;inset:0;width:100%;height:100%;max-width:none;display:block}
/* the screen box, as fractions of the 498.5 x 1024 body render */
.hero__scr{position:absolute;left:4.2126%;top:1.7578%;width:91.4744%;height:96.4355%;
  overflow:hidden;border-radius:calc(var(--hp-w) * .142);background:#000}
.hero__scr img{width:100%;height:100%;max-width:none;object-fit:cover;display:block}
/* Dynamic Island: 106 x 40.5 at 34 px from the body top, on a 498.5 body */
.hero__island{position:absolute;left:50%;top:calc(var(--hp-w) * .0682);
  width:calc(var(--hp-w) * .213);height:calc(var(--hp-w) * .0812);
  transform:translateX(-50%);border-radius:999px;background:#000}

.hero__lede{margin-top:128px;max-width:600px;text-align:center;
  font-size:20px;line-height:1.3;color:var(--plum70)}
.hero__lede p+p{margin-top:1.3em}

@media (max-width:899px){
  .hero__stage{padding:40px var(--pad) 80px}
  .hero__tag{margin-top:72px}
  .hero__phone{margin-top:48px}
  .hero__lede{margin-top:80px;font-size:18px}
}

/* ---------- the intro ----------
   Logo fades down at 0 ms, the line 50 ms later, the phone 50 ms after that.
   700 ms for the two small things, 900 ms for the phone; one ease-out curve
   (fast start, long settle) so nothing arrives with speed. */
@keyframes hero-down{from{opacity:0;transform:translateY(-12px)}to{opacity:1;transform:none}}
@keyframes hero-up{from{opacity:0;transform:translateY(24px)}to{opacity:1;transform:none}}
.hero__logo{animation:hero-down .7s cubic-bezier(.22,1,.36,1) 0ms both}
.hero__tag{animation:hero-down .7s cubic-bezier(.22,1,.36,1) 50ms both}
.hero__phone{animation:hero-up .9s cubic-bezier(.22,1,.36,1) 100ms both}

/* Do NOT put a transition on .hero__panel or on its transform. The script
   writes the angle every frame; a transition would make the phone lag one
   step behind the scroll and feel rubbery. */

/* ---------- reduced motion ----------
   No turn, no pin. base.css already collapses the three fades to .01 ms, so
   the logo, the line and the phone simply appear. */
@media (prefers-reduced-motion:reduce){
  .hero__runway{display:none}
  .hero__panel{transform:none;will-change:auto}
}


/* ---------- the floating capsule ----------
   The site's .capsule, fixed 32 px above the bottom edge, centred. Hidden
   until the hero lede reaches mid-screen, hidden again when the footer
   arrives. visibility is transitioned too, so the hidden link is not in the
   tab order. z-index 30 keeps it under the sticky nav (40 in base.css). */
.fcap{position:fixed;left:0;right:0;bottom:calc(32px + env(safe-area-inset-bottom,0px));
  z-index:30;display:flex;justify-content:center;pointer-events:none;
  opacity:0;visibility:hidden;transform:translateY(24px);
  transition:opacity .35s ease,transform .35s ease,visibility 0s linear .35s}
.fcap.is-visible{opacity:1;visibility:visible;transform:none;transition-delay:0s}
.fcap .capsule{pointer-events:auto}
/* on a short viewport it would cover a fifth of the screen: do not show it */
@media (max-height:519px){.fcap{display:none}}


/* ==========================================================================
   THE SECTION FRAME
   Same skeleton for 02–07: a pill, the display line, a sentence or two, then
   the picture and the feature row. The parts are spaced by the section, not
   by themselves, so a picture block can be dropped in or taken out without
   carrying a margin around with it.
   ========================================================================== */
/* No clipping here: a section with no bottom padding would cut the soft shadow
   off the bottom of whatever picture it ends on (it did, on the Sessions
   films). Only the two sections that deliberately run something past the
   window clip, and they say so themselves. */
.sec{padding:128px 0 0}                          /* the NEXT section's top pad is the gap */
.sec--pad-bottom{padding-bottom:128px}           /* 06 and 07, which close the page */
.sec--surface{background:var(--surface)}         /* 07 only */
.sec[id]{scroll-margin-top:72px}
@media (min-width:900px){.sec[id]{scroll-margin-top:88px}}
.sec>.wrap>*+*{margin-top:80px}                  /* head → picture → feature row */
@media (max-width:899px){
  .sec{padding-top:80px}
  .sec--pad-bottom{padding-bottom:80px}
  .sec>.wrap>*+*{margin-top:56px}
}

.sec__head{max-width:600px;margin-inline:auto;text-align:center;
  display:flex;flex-direction:column;align-items:center;gap:28px}
.sec__eyebrow{border-color:rgba(37,68,113,.1)}   /* the design's pill: plum 10 % */
.sec__title{font-size:40px}                      /* .d3 carries face/weight/leading 1.15 */
.sec__intro{font-size:18px;line-height:1.35;color:var(--plum70)}
@media (max-width:599px){.sec__title{font-size:32px}}


/* ==========================================================================
   THE PHONE FRAME
   Drawn in CSS around a flat screenshot — rounded corners, a hairline bezel,
   the soft shadow from the --lift stack. Nothing is baked into the picture,
   so every regenerated capture drops straight in.
   ========================================================================== */
.phone{--phone-w:340px;
  position:relative;width:100%;max-width:var(--phone-w);aspect-ratio:402/874;
  margin:0;padding:5px;border-radius:44px;background:var(--white);
  border:1px solid var(--border);box-shadow:var(--lift);flex:0 0 auto}
.phone__scr{width:100%;height:100%;border-radius:39px;overflow:hidden;
  background:#2A2C33;box-shadow:inset 0 0 0 1px rgba(14,15,18,.14)}
.phone img,
.phone video{width:100%;height:100%;max-width:none;object-fit:cover;display:block;
  background:#2A2C33}
.phone--lg{--phone-w:402px}
.phone--sm{--phone-w:284px}
@media (max-width:399px){
  .phone{border-radius:36px;padding:4px}
  .phone__scr{border-radius:32px}
}

/* ---------- the screen frame ----------
   The desktop display is a Mac and Windows app, so its picture is a screen,
   not a phone. Same hairline, same white bezel, same --lift shadow, so the
   two frames read as siblings; only the proportion and the radius differ.
   1512 x 945 is a 14in MacBook Pro's logical screen, exactly 16:10, so a
   plain desktop screenshot drops straight in. */
.screen{--screen-w:1120px;
  position:relative;width:100%;max-width:var(--screen-w);aspect-ratio:1512/945;
  margin:0;padding:6px;border-radius:18px;background:var(--white);
  border:1px solid var(--border);box-shadow:var(--lift)}
.screen__scr{width:100%;height:100%;border-radius:12px;overflow:hidden;
  background:#2A2C33;box-shadow:inset 0 0 0 1px rgba(14,15,18,.14)}
.screen img{width:100%;height:100%;max-width:none;object-fit:cover;display:block;
  background:#2A2C33}
@media (max-width:599px){
  .screen{padding:4px;border-radius:12px}
  .screen__scr{border-radius:9px}
}

/* a single frame standing on the ground, with air around it */
.solo{display:flex;justify-content:center}


/* ==========================================================================
   THE FEATURE ROW
   The page's one repeating component: two or three short lines, each a mono
   label over a single sentence, divided by the hairline.
   ========================================================================== */
.trio{display:grid;gap:28px}
.trio li{border-top:1px solid rgba(37,68,113,.1);padding-top:20px}
.trio__l{font-family:var(--mono);font-weight:400;font-size:14px;line-height:1.1;
  letter-spacing:.08em;text-transform:uppercase;color:var(--plum)}
.trio__d{margin-top:12px;font-size:18px;line-height:1.35;color:var(--plum70)}
@media (min-width:760px){
  .trio{grid-template-columns:repeat(3,minmax(0,1fr));gap:49px}
}
/* 07 stacks its two lines in the text column. This must stay AFTER the
   min-width:760 rule above: same specificity, later wins. */
.trio--stack{grid-template-columns:1fr;gap:32px;width:100%}


/* ==========================================================================
   THE NOTE
   A speech-bubble glyph beside a small line. Used in 03 and 07.
   ========================================================================== */
.note{display:flex;gap:12px;align-items:flex-start;max-width:430px;
  font-size:14px;line-height:1.3;color:var(--plum70)}
.note__ic{flex:0 0 18px;margin-top:1px;fill:currentColor;display:block}
.note--center{margin-inline:auto}
/* The .zwo note, in Zwift's own orange as a nod to using their file format.
   The only place on the site that uses a colour belonging to somebody else,
   so it is kept to this one block and never enters base.css.
   Contrast of white on this orange is about 3:1, under the 4.5:1 that body
   copy wants — flagged to Dragan; it is his call and this is one short line,
   not running prose. If it needs to pass, the fixes are a darker orange or
   plum text instead of white. */
.note--zwo{margin-top:64px;padding:18px 22px;border-radius:12px;
  background:#FC6719;color:var(--white);max-width:472px;box-shadow:var(--lift-sm)}
/* ---------- the desktop downloads ----------
   Under the HUD picture: the two people actually want, side by side, with the
   Intel Mac and the fine print in the small register below. Three primary
   pills in a row would read as three equal choices, which they are not. */
.dl{margin-top:56px;display:grid;gap:16px;justify-items:center}
/* Three columns: the button sits in the middle one, so it is centred on the
   PAGE, and the note beside the Mac hangs off to the right without dragging
   the button off centre. Both buttons are the same fixed width whatever the
   label says. */
.dl__row{display:grid;grid-template-columns:1fr auto 1fr;align-items:center;
  gap:20px;width:100%}
.dl__btn{grid-column:2;width:260px;justify-content:center;text-align:center}
.dl__aside{grid-column:3;margin:0;max-width:280px;text-align:left}
@media (max-width:899px){
  /* No room for a column beside the button: the note goes under it. */
  .dl__row{grid-template-columns:1fr;gap:10px;justify-items:center}
  .dl__btn,.dl__aside{grid-column:1}
  .dl__aside{max-width:320px;text-align:center}
}
@media (max-width:399px){.dl__btn{width:100%}}

/* ---------- links in this page's prose ----------
   base.css sets `a{color:inherit;text-decoration:none}` site-wide and only
   dresses links inside .doc__body, so on a page like this one a link is
   indistinguishable from the sentence around it. These are the page's prose
   contexts; the nav, the footer and .btn are deliberately not in the list. */
.sec__intro a,.film__note a,.note a,.hero__lede a,.trio__d a,
.dl__aside a,.bfeat__d a{
  color:var(--primary);text-decoration:underline;text-underline-offset:3px}
.note--zwo a{color:var(--white)}   /* on the orange, inherit reads better */

/* A file, drawn as an outline rather than a solid. .note__ic fills with
   currentColor, and a CSS fill beats the element's own fill attribute, so the
   override has to live here or the document comes out as a filled blob. */
.note--zwo .note__ic{fill:none;stroke:currentColor;stroke-width:1.3;
  stroke-linejoin:round;stroke-linecap:round}


/* ==========================================================================
   01 — BASE RIDES
   The one section that is not a centre column: a full-bleed photograph with
   a scrim graded from the left, the text over it in white, the phone
   standing on the right.
   ========================================================================== */
.base{position:relative;overflow:hidden;background:var(--ink);color:var(--white);
  padding:128px 0}
.base__photo{position:absolute;inset:0;width:100%;height:100%;max-width:none;
  object-fit:cover;object-position:50% 40%}
.base__scrim{position:absolute;inset:0;
  background:linear-gradient(to left,rgba(0,0,0,0) .35%,rgba(0,0,0,.45) 100%)}
.base__in{position:relative;display:grid;grid-template-columns:minmax(0,878px) 402px;
  justify-content:space-between;align-items:start;gap:40px}
.base__text{padding-top:80px;display:flex;flex-direction:column;align-items:flex-start;gap:28px}
.base__eyebrow{border-color:rgba(255,255,255,.1)}
.base__title{font-size:clamp(56px,8.9vw,128px);color:var(--white)}
/* the design sets this in Archivo Medium, a face the site does not have and
   may not fetch; Clash 500 is the site's standfirst face */
.base__intro{font-family:var(--disp);font-weight:500;font-size:clamp(22px,2.1vw,30px);
  line-height:1.22;color:var(--white)}
.bfeat{display:flex;flex-direction:column;gap:32px;margin-top:4px}
.bfeat__l{font-family:var(--disp);font-weight:500;font-size:24px;line-height:1.15}
.bfeat__d{margin-top:12px;font-size:19px;line-height:1.35}
/* The phone stands proud of the photograph rather than lying flat on a page,
   so it takes the deeper shadow from the --lift stack; .phone's own
   var(--lift) is sized for a frame on white and disappears on a dark ground. */
.base__phone{justify-self:end;box-shadow:var(--lift-card)}
@media (max-width:999px){
  .base{padding:80px 0}
  .base__scrim{background:rgba(0,0,0,.5)}     /* uniform: the text now sits over the rider */
  .base__in{grid-template-columns:minmax(0,1fr);justify-items:center;gap:56px}
  .base__text{padding-top:0;max-width:640px}
  .base__phone{justify-self:center}
}


/* ==========================================================================
   02 — SESSIONS
   The two films are the reason the section exists, so they run side by side
   at the screenshot's own size, each with its caption above it.
   ========================================================================== */
.films{display:grid;gap:64px;justify-items:center}
@media (min-width:1200px){
  .films{grid-template-columns:repeat(2,524px);justify-content:center;gap:72px;align-items:start}
}
.film{margin:0;width:100%;display:flex;flex-direction:column;align-items:center;gap:32px}
.film__cap{font-family:var(--disp);font-weight:500;font-size:34px;line-height:1.15;
  color:var(--plum);text-align:center;max-width:364px}
@media (max-width:599px){.film__cap{font-size:28px}}
/* The sentence under a film's heading. Held to the heading's measure so the
   two read as one block, and sitting tight under it rather than in the gap
   the .film flex row would otherwise give it. */
.film__note{margin:-20px 0 0;max-width:364px;text-align:center;
  font-size:17px;line-height:1.5;color:var(--plum70)}

/* ---------- the play button ----------
   The site's white capsule made round: the same white ground, the same --lift
   shadow stack, a plum triangle. It is the ONLY control on a film — no pause,
   no scrubber, no native chrome — because these are silent loops rather than
   a video player, and it leaves for good once the film is running.
   Centred with inset:0 + margin:auto, which keeps `transform` free for the
   hover, pressed and leaving states. */
.play{position:absolute;inset:0;margin:auto;
  width:88px;height:88px;padding:0;
  display:flex;align-items:center;justify-content:center;
  background:var(--white);border:0;border-radius:999px;box-shadow:var(--lift);
  color:var(--plum);cursor:pointer;
  transition:transform 150ms ease,color 150ms linear,opacity 200ms ease}
.play svg{width:26px;height:30px;fill:currentColor;
  transform:translateX(7%)}      /* a triangle's optical centre sits left of its box */
.play:hover{transform:scale(1.04);color:var(--primary)}
.play:active{transform:scale(.96)}
.play.is-gone{opacity:0;transform:scale(.9);pointer-events:none}
/* `hidden` has to be spelled out here: an author display:flex beats the
   browser's own [hidden]{display:none} whatever the specificity says */
.play[hidden]{display:none}
@media (max-width:599px){
  .play{width:64px;height:64px}
  .play svg{width:19px;height:22px}
}


/* ==========================================================================
   03 — GROUP RIDES
   Desktop is the mockup (Figma 210:865): the render at its own 737 x 844,
   contained in the column, centred.
   Below 900 — the site's main breakpoint, phone and tablet on one side,
   desktop on the other — it runs 120 % of the window instead, so the phones
   are cut by the edges of the screen. At phone width a contained render is
   barely two thumbnails; cropped, it fills the screen and the faces are the
   size of faces.
   The section does the clipping there: it is the nearest box that spans the
   whole window, so the render can never widen the document. (Leaning on
   body{overflow-x:hidden} instead would be wrong — it stops position:sticky
   working in some browsers, and the hero depends on it.)
   `margin-left:calc(50% - 60vw)` is measured from the centre of the column,
   which is the centre of the window, so the overhang is equal on both sides
   whatever the column is doing.
   ========================================================================== */
.duo{display:flex;justify-content:center}
.duoimg{width:min(100%,737px);max-width:none;height:auto;display:block}
@media (max-width:899px){
  .sec--group{overflow:hidden}
  .duo{display:block}
  .duoimg{width:120vw;margin-left:calc(50% - 60vw)}
}


/* ==========================================================================
   04 — ROUTES
   The band the old home page gave this subject, brought across: the printed
   contour sheet as the ground, the route loop drawn across it, two readings
   floating off the phone. Both picture files are the ones site.css already
   uses — img/routes-topo.* and img/routes-path.svg — and neither is touched.
   The section clips, so nothing here can open a horizontal scrollbar.
   ========================================================================== */
.sec--routes{position:relative;overflow:hidden;background:var(--surface)}
/* The section frame's rule is that the NEXT section's top padding is the gap
   between two blocks. That breaks the moment a section is painted: the gap
   would be inside the band, so the block above would touch its top edge and
   the block below would start 128 px inside it. The 128 is split instead —
   half as white air outside the band, half as the band's own padding — so
   the rhythm reads the same and the band has room to be a band. */
.sec--group{padding-bottom:80px}
.sec--routes{padding-top:80px;padding-bottom:80px}
.sec--routes+.sec{padding-top:80px}
@media (max-width:899px){
  .sec--group{padding-bottom:48px}
  .sec--routes{padding-top:48px;padding-bottom:48px}
  .sec--routes+.sec{padding-top:48px}
}
/* the light-ground pill, as the old home page used on this sheet */
.sec--routes .sec__eyebrow{border-color:var(--white)}
/* The contour export is flat RGB with the band's own ground colour already
   baked into it, so it is painted at full strength — an extra opacity would
   wash the contours out twice over. It is the section's ground, so it sits
   under everything; .wrap is lifted above it below. */
.routes__paper{position:absolute;inset:0;background:center/cover no-repeat;
  pointer-events:none;z-index:0;
  background-image:url("../assets/img/routes-topo.png");
  background-image:image-set(url("../assets/img/routes-topo.webp") type("image/webp"),
                             url("../assets/img/routes-topo.png") type("image/png"))}
.sec--routes>.wrap{position:relative;z-index:1}
.routes__pic{position:relative;display:flex;justify-content:center}
/* the phone stands proud of the band rather than lying flat on a page, so it
   takes the deeper shadow from the --lift stack, as the one on the
   photograph in 01 does */
.routes__pic .phone{position:relative;z-index:1;box-shadow:var(--lift-card)}
/* the loop spans 95.6 % of the window, centred on the phone
   (Figma: inset 22.04 % 2.21 % 22.03 % 2.21 % of a 1440 x 1443 frame).
   The asset is drawn in white because it was made to stand on the printed
   topo sheet — which is now what it stands on here, so it is painted as
   drawn. It used to be inverted to pale grey for a white section. */
.routes__loop{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);
  width:calc(100vw - 4.4vw);max-width:none;height:auto;pointer-events:none;z-index:0}

/* ---------- the readings that float off the phone ----------
   The old home page's cluster, whole: its 450 x 112 box, its four children
   and every one of their offsets, copied from site.css unchanged — the wide
   distance card highest and centred, the plain distance low left, the
   gradient low right, the segment tag under the middle.
   What differs is only where the box is hung. On home-2.html it is centred
   in the column with nothing behind it; here it is placed against
   .routes__pic, the phone's own row, so it holds the same relation to the
   phone at every width and can never be thrown off the edge of the window.
   The cards are the size they are drawn, as on home-2.html — no scale above
   the narrow step. `transform-origin` is the box's bottom CENTRE, so the one
   scale there is does not move it: whatever the scale, the group stays
   centred on the phone and keeps its bottom edge where it is put. (Anchoring
   a corner instead means every scale needs a matching offset correction, and
   an offset left behind for a scale that changed throws the group off
   centre.)
   ========================================================================== */
.routes__cluster{position:absolute;z-index:2;left:50%;bottom:-64px;
  width:450px;height:112px;margin-left:-225px;transform-origin:50% 100%}
.routes__cluster .mc,
.routes__cluster .rtag{position:absolute}
.mc-a{left:144.5px;top:0;width:180px}
.mc-b{left:0;top:32px;width:112px}
.mc-c{left:357px;top:32px;width:93px}
.rtag{left:167px;top:81px}

/* The orange segment tag — the one coloured thing in the cluster, and the
   only part of it that is not the shared .mc. The dimmed block behind the
   category is drawn rather than filled, so the two words keep one pill.
   Copied from site.css; the white card itself (.mc) is shared in base.css.
   The `position:relative` here is what the two-class rule above overrides. */
.rtag{position:relative;display:inline-flex;gap:12px;padding:11px 18px;border-radius:var(--r);
  background:var(--orange);color:var(--white);box-shadow:var(--lift-sm);overflow:hidden;white-space:nowrap}
.rtag::before{content:"";position:absolute;left:0;top:0;width:39px;height:100%;background:rgba(0,0,0,.2)}
.rtag span{position:relative;font-family:var(--mono);font-weight:300;font-size:12px;line-height:9px;
  letter-spacing:.05em;text-transform:uppercase}
.rtag .dim{opacity:.66}

/* The cluster hangs 64px below the phone, into the gap the section frame
   leaves under a picture — and that gap is the NEXT block's top margin, 80
   above 900 and 56 below it. So the tag would sit 16px off the feature row
   on a desktop and 8px INTO it on a tablet. The row is pushed down enough to
   clear the whole cluster with air left over; this is the only section whose
   picture hangs something past its own bottom. */
.sec--routes>.wrap>.trio{margin-top:112px}
@media (max-width:899px){.sec--routes>.wrap>.trio{margin-top:104px}}

@media (max-width:560px){
  /* The cluster is drawn 450px wide. Below 560 that is wider than the window,
     so it has to come down — there is no arrangement of a 450px group inside
     a 390px screen. home-2.html steps down at the same width and by the same
     amount; this is its rule, not a fit of convenience. */
  .routes__cluster{transform:scale(.66)}
}


/* ==========================================================================
   05 — HISTORY
   Two phones as a pair rather than a row: the second one dropped so the
   block reads as one object with a diagonal through it.
   ========================================================================== */
.pair{display:grid;gap:40px;justify-items:center;max-width:960px;margin-inline:auto}
@media (min-width:800px){
  .pair{grid-template-columns:repeat(2,minmax(0,1fr));gap:clamp(24px,4vw,72px);
    align-items:start}
  .pair>*:nth-child(2){margin-top:clamp(48px,7vw,128px)}
}


/* ==========================================================================
   07 — RUNNING
   The text column on the left, the running photograph on the right, centred
   on each other. The photograph is a contained panel by design — it has no
   scrim and never had one — so it is never stretched into a band.
   ========================================================================== */
/* .wrap's own padding-inline is replaced here, not added to, so these are the
   design's offsets measured from the frame edge: 130 left, 155 right at 1440.
   They scale below that, because a flat 130 + 500 + 450 + 155 needs 1235px and
   this layout starts at 1200 — the 35px it used to overflow were only invisible
   because the section clipped them. */
.run__in{display:grid;grid-template-columns:500px 450px;justify-content:space-between;
  align-items:center;
  padding-left:clamp(40px,9.0278vw,130px);padding-right:clamp(40px,10.7639vw,155px)}
.run__in>*+*{margin-top:0}   /* cancel the section frame's stack rule: these are grid columns */
.run__text{display:flex;flex-direction:column;align-items:flex-start;gap:32px;text-align:left}
.run__text .sec__intro{text-align:left}
.rphoto{margin:0;width:100%;aspect-ratio:450/800;border-radius:12px;overflow:hidden;
  box-shadow:var(--lift-photo)}
.rphoto img{width:100%;height:100%;max-width:none;object-fit:cover;display:block}
@media (max-width:1199px){
  /* back to the page gutter — leaving this at 0 would run both columns off
     the edges of the window */
  .run__in{padding-left:var(--pad);padding-right:var(--pad);
    grid-template-columns:minmax(0,500px) minmax(280px,450px);gap:48px}
}
@media (max-width:999px){
  .run__in{grid-template-columns:minmax(0,1fr);justify-items:center;gap:56px}
  .run__text{max-width:600px}
  .rphoto{width:min(100%,450px)}
}
