/* ==========================================================================
   Indore — product.css
   Loads AFTER css/base.css, which carries the faces, the tokens, the reset,
   .wrap, the display type classes, .cap / .btn / .capsule / .opill, .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/product.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    white, one phone with the route loop behind 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/product.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/product.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}


/* ==========================================================================
   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}
.base__phone{justify-self:end}
@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 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
   One phone with the route loop drawn across the section behind it. The loop
   SVG carries preserveAspectRatio="none", so it is given height:auto and
   keeps its 1359:803 shape. The section clips it, so it cannot open a
   horizontal scrollbar.
   ========================================================================== */
.sec--routes{position:relative;overflow:hidden}
.routes__pic{position:relative;display:flex;justify-content:center}
.routes__pic .phone{position:relative;z-index:1}
/* 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 the homepage stands it on the printed
   topo sheet; this section is white, so here it is inverted to the pale grey
   the design shows. The file is shared — recolour it here, never in place. */
.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;
  filter:invert(1) opacity(.12)}
@media (max-width:899px){.routes__loop{filter:invert(1) opacity(.06)}}


/* ==========================================================================
   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)}
}
