/* ============================================================
   MoCo — MotoController landing page
   ============================================================ */

:root{
  --bg-0: #0e1219;
  --bg-1: #1b2332;
  --bg-2: #28334a;
  --line: rgba(120, 170, 235, 0.14);
  --line-soft: rgba(120, 170, 235, 0.07);
  --blue: #3d84e8;
  --blue-bright: #5aa8ff;
  /* --blue is the accent for rules, borders and glows, where 3:1 is the bar and
     it passes. Filled with white text on top it only reached 3.71:1, so the
     solid controls get their own darker step: white on this is 4.70:1, and the
     button still clears 3:1 against the page behind it. */
  --blue-cta: #2d6bcb;
  --blue-glow: rgba(74, 163, 255, 0.35);
  --ink-0: #f3f6fb;
  --ink-1: #c7d3e6;
  /* The two muted tiers are set so the smallest text on the page still clears
     4.5:1 on the lightest surface it ever sits on (--bg-2). --ink-3 used to be
     2.38:1 there, which is why the roadmap sub-labels and the card descriptions
     vanished in daylight. The tiers sit closer together than before because the
     palette has no room for a third readable step below --ink-2. */
  --ink-2: #99a7c1;   /* 5.20:1 on --bg-2, 7.73:1 on --bg-0 */
  --ink-3: #909db3;   /* 4.61:1 on --bg-2, 6.84:1 on --bg-0 */
  --amber: #e0ac2b;
  --max-w: 1180px;
  --gloss-edge: rgba(255, 255, 255, 0.62);
  --gloss-sheen: rgba(255, 255, 255, 0.1);
  --ambient: rgba(61, 132, 232, 0.2);
  --font-sans: 'Switzer', system-ui, -apple-system, 'Segoe UI', sans-serif;
  /* display i tekst ciagly to teraz ta sama rodzina; alias zostaje,
     zeby dwanascie regul nie musialo sie zmieniac przy kolejnej podmianie */
  --font-display: var(--font-sans);
  --ease-motion: cubic-bezier(0.16, 1, 0.3, 1);
  /* Scroll entrances get their own curve. --ease-motion leaves the start line at
     6.25x its average speed: it covers 49% of the distance in the first 10% of
     the duration and 97% by halfway, so a 1650ms entrance was visually over in
     about 500ms and the rest was imperceptible creep. That is why lengthening
     the duration never made it calmer. This one starts from rest and actually
     spends the time it is given — 4% at a tenth, 43% at a third, 79% at the
     halfway point. State feedback (hover, the active roadmap card) keeps the
     snappy curve, because a control should answer immediately. */
  --ease-enter: cubic-bezier(0.34, 0, 0.2, 1);
  /* one multiplier scales every entrance duration, so phones stay a touch
     quicker than desktop without restating each rule */
  --mscale: 1;
  --radius: 14px;
}

*, *::before, *::after{ box-sizing: border-box; }

/* the reading scroll drives position frame by frame, so the page's own smooth
   scrolling has to be out of the way while it runs */
html.is-auto-scrolling{ scroll-behavior: auto; }

/* The page scrollbar was left at the system default, which paints a light grey
   bar down the right edge of a very dark page. Tinted to the page's own blue
   and held well back, with the track left clear so only the thumb reads. */
html{
  scrollbar-width: thin;                                  /* Firefox */
  scrollbar-color: rgba(120, 170, 235, 0.38) transparent;
}

::-webkit-scrollbar{ width: 10px; height: 10px; }
::-webkit-scrollbar-track{ background: transparent; }

::-webkit-scrollbar-thumb{
  background: rgba(120, 170, 235, 0.38);
  border-radius: 6px;
  /* a transparent border with padding-box clipping keeps the thumb off the very
     edge without needing a track colour */
  border: 2px solid transparent;
  background-clip: padding-box;
}

::-webkit-scrollbar-thumb:hover{
  background: rgba(120, 170, 235, 0.62);
  background-clip: padding-box;
}

html{
  scroll-behavior: smooth;
  overflow-x: clip;
  max-width: 100%;
  overscroll-behavior-x: none;
}

body{
  margin: 0;
  background: var(--bg-0);
  color: var(--ink-1);
  font-family: var(--font-sans);
  font-size: 17px;
  line-height: 1.7;
  -webkit-font-smoothing: antialiased;
  overflow-x: clip;
  max-width: 100%;
  position: relative;
  overscroll-behavior-x: none;
}

::selection{ background: var(--blue-cta); color: #fff; }

h1, h2, h3, h4{
  font-family: var(--font-display);
  font-weight: 600;
  color: var(--ink-0);
  margin: 0;
  letter-spacing: 0.01em;
  text-transform: uppercase;
  text-wrap: balance;
}

p{ margin: 0; }
a{ color: inherit; text-decoration: none; }
img, svg{ display: block; max-width: 100%; }
button{ font-family: inherit; }

/* every anchor target clears the sticky header — without this a jump lands the
   section top at 0 and the header sits on top of it */
main, main section[id], footer, .hero, .video-slot{ scroll-margin-top: 94px; }

.container{
  width: 100%;
  max-width: var(--max-w);
  margin: 0 auto;
  padding: 0 28px;
  position: relative;
  z-index: 1;
}

/* -------------------- background texture -------------------- */

.blueprint-bg{
  position: absolute;
  inset: 0;
  z-index: -3;
  background: var(--bg-0);
}

/* default grid texture — scrolls naturally with the page instead of staying pinned to the viewport */
.blueprint-bg::before{
  content: "";
  position: absolute;
  inset: 0;
  background-image:
    linear-gradient(var(--line-soft) 1px, transparent 1px),
    linear-gradient(90deg, var(--line-soft) 1px, transparent 1px);
  background-size: 64px 64px;
  mask-image: radial-gradient(ellipse 90% 70% at 50% 0%, #000 40%, transparent 100%);
  opacity: 0.4;
}

.glow{
  position: absolute;
  border-radius: 50%;
  filter: blur(120px);
  pointer-events: none;
  z-index: -1;
}

/* faint racetrack line motif used as ambient background dressing */
.track-motif{
  position: absolute;
  z-index: -1;
  opacity: 0.16;
  pointer-events: none;
  color: var(--blue-bright);
}

/* faint full-bleed section photography, faded at the edges so it reads as texture, not an image */
.section-photo{
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
}

.section-photo img{
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0.55;
  filter: saturate(0.45) brightness(0.5) contrast(1.05);
  mask-image: radial-gradient(ellipse 75% 85% at 50% 50%, #000 40%, transparent 92%);
  -webkit-mask-image: radial-gradient(ellipse 75% 85% at 50% 50%, #000 40%, transparent 92%);
}

/* The hero render is a close product shot whose own MOTOCONTROLLER badge falls
   right behind the call to action at a plain cover crop, doubling the logo
   already in the header. Framing it a little tighter and higher lifts the badge
   out of the frame and keeps the mechanism itself as the subject. Nothing in
   script transforms this image, so the scale is free to sit here. */
.hero .section-photo img{
  transform: scale(1.45);
  transform-origin: 50% 20%;
}

/* extra darkening so a background photo never competes with a foreground product shot */
.section-photo.dim img{
  opacity: 0.39;
  filter: saturate(0.35) brightness(0.4) contrast(1.05);
}

/* the PCB render is a saturated green, so it gets pulled further toward the
   navy palette than the other backgrounds before it sits behind the cards */
#roadmap .section-photo img{
  opacity: 0.34;
  filter: saturate(0.2) brightness(0.55) contrast(1.02) hue-rotate(-12deg);
  /* this section is unusually tall, so the photo is pulled up behind the cards
     and faded out well before the teaser and the values copy */
  mask-image: radial-gradient(ellipse 78% 52% at 50% 28%, #000 26%, transparent 88%);
  -webkit-mask-image: radial-gradient(ellipse 78% 52% at 50% 28%, #000 26%, transparent 88%);
}

/* Stacked into one column these sections run many screens tall, and a full-height
   cover crop magnifies the photo until it reads as an abstract blur — #sensing was
   showing barely 7% of its image width. On narrow screens every section photo is
   bounded to a band behind the section opening, which holds the crop near 2.8x.
   The panorama card is deliberately excluded: there the photo IS the card. */
@media (max-width: 900px){
  section > .section-photo,
  .hero > .section-photo{ bottom: auto; height: 600px; }

  section > .section-photo img,
  .hero > .section-photo img{
    mask-image: radial-gradient(ellipse 125% 78% at 50% 34%, #000 22%, transparent 90%);
    -webkit-mask-image: radial-gradient(ellipse 125% 78% at 50% 34%, #000 22%, transparent 90%);
  }

  #roadmap .section-photo img{ opacity: 0.26; }
}

/* protective gradient so body text always sits on a readable, uncluttered zone,
   never directly over the product in the photo */
.section-photo::after{
  content: "";
  position: absolute;
  inset: 0;
}

.section-photo.protect-left::after{
  background: linear-gradient(90deg, rgba(6,10,19,0.95) 0%, rgba(6,10,19,0.8) 42%, rgba(6,10,19,0.35) 62%, rgba(6,10,19,0.05) 85%, transparent 100%);
}

.section-photo.protect-right::after{
  background: linear-gradient(270deg, rgba(6,10,19,0.95) 0%, rgba(6,10,19,0.8) 42%, rgba(6,10,19,0.35) 62%, rgba(6,10,19,0.05) 85%, transparent 100%);
}

/* -------------------- nav -------------------- */

.site-nav{
  position: sticky;
  top: 0;
  z-index: 100;
  background: rgba(7, 11, 21, 0.97);
  border-bottom: 1px solid var(--line);
}

.site-nav .container{
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 78px;
}

/* flex: none so the header never crushes the logo to make room for the rest;
   with the language switch added it was squeezed to 0px wide at 1024px */
.brand{ display: flex; align-items: center; justify-content: center; gap: 12px; flex: none; }
.brand-full{ height: 100%; }
.mark-full{ height: 46px; width: auto; display: block; }

.nav-links{
  display: flex;
  align-items: center;
  gap: 34px;
  list-style: none;
  margin: 0;
  padding: 0;
  /* The header is a flex row and the language switch made it a four-child one.
     Without this the list is a shrinkable sibling: it was given less than its
     content needs and wrapped to two lines even with 54px of room to spare. */
  flex: none;
}

.nav-links a{
  font-size: 13.5px;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--ink-2);
  transition: color 0.2s ease;
  position: relative;
}

.nav-links a:hover, .nav-links a.active{ color: var(--ink-0); }

/* -------------------- language switch -------------------- */

/* A segmented pair rather than two loose buttons, so the two languages read as
   one control with a current state. It sits beside Follow the project on the
   desktop and stays in the top bar on a phone, next to the hamburger, rather
   than being buried at the bottom of the open menu. */
.lang-switch{
  display: inline-flex;
  align-items: center;
  gap: 2px;
  padding: 3px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: rgba(10, 15, 26, 0.5);
  flex: none;
}

.lang-btn{
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 11px;
  border: 0;
  border-radius: 999px;
  background: transparent;
  cursor: pointer;
  font-family: var(--font-display);
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: 0.08em;
  /* quiet but unmistakably clickable while it is not the current language */
  color: var(--ink-2);
  transition: color 200ms ease, background 200ms ease, box-shadow 200ms ease;
}

.lang-btn:hover{ color: var(--ink-0); }

.lang-btn.is-active{
  color: #fff;
  background: var(--blue-cta);
  background-image: linear-gradient(180deg, rgba(255, 255, 255, 0.18), transparent 58%);
  box-shadow: 0 0 18px rgba(61, 132, 232, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.22);
}

.lang-btn:focus-visible{ outline: 2px solid var(--blue-bright); outline-offset: 2px; }

/* the flag is a label, not the control: dimmed until its language is current */
.lang-flag{
  width: 15px;
  height: 10px;
  border-radius: 1.5px;
  display: block;
  opacity: 0.75;
  box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.18);
  transition: opacity 200ms ease;
}

.lang-btn.is-active .lang-flag{ opacity: 1; }

.nav-links a.active::after{
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: -28px;
  height: 2px;
  background: var(--blue-bright);
}

.nav-cta{
  padding: 11px 22px;
  border: 1px solid var(--blue);
  border-radius: 999px;
  font-size: 12.5px;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--ink-0);
  white-space: nowrap;
  transition: background 0.2s ease, box-shadow 0.2s ease;
}

.nav-cta:hover{ background: var(--blue); box-shadow: 0 0 24px var(--blue-glow); }

/* The page had no keyframe animation at all before these three; each one is
   slow, small, and switched off under prefers-reduced-motion at the foot of
   this file, so the calm reading character survives them. */
@keyframes cta-breathe{
  0%, 100%{ box-shadow: 0 0 0 0 rgba(90, 168, 255, 0), 0 0 14px rgba(61, 132, 232, 0.28); }
  50%     { box-shadow: 0 0 0 5px rgba(90, 168, 255, 0), 0 0 26px rgba(90, 168, 255, 0.6); }
}

.nav-cta-pulse{
  animation: cta-breathe 3.4s var(--ease-motion) infinite;
  border-color: rgba(120, 170, 235, 0.5);
}

.nav-cta-pulse:hover{ animation-play-state: paused; }


.nav-toggle{
  display: none;
  width: 40px; height: 40px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: transparent;
  color: var(--ink-0);
  cursor: pointer;
  align-items: center;
  justify-content: center;
}

.nav-toggle:focus-visible, a:focus-visible, button:focus-visible, input:focus-visible{
  outline: 2px solid var(--blue-bright);
  outline-offset: 2px;
}

/* -------------------- hero -------------------- */

.hero{ position: relative; padding: 116px 0 96px; overflow: hidden; background: var(--bg-0); }

.hero .container{
  /* The art column is parked, so the grid holds one column and the copy is
     capped rather than running the full container width. */
  display: grid;
  grid-template-columns: minmax(0, 720px);
  gap: 60px;
  align-items: center;
}
/* A grid item defaults to min-width: auto, so its longest unbreakable word sets
   a floor for the whole column. On a 320px screen "MOTORCYCLES" is wider than
   the container, which pushed the entire block — eyebrow, lede and support line
   with it — 46px past the right edge, where .hero's overflow cut it off. */
.hero .container > *{ min-width: 0; }

.eyebrow{
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-size: 12.5px;
  font-weight: 700;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--blue-bright);
  margin-bottom: 22px;
}

.eyebrow::before{ content: ""; width: 26px; height: 1px; background: var(--blue-bright); }

/* Last resort for any word still too wide for its box — with a different font
   than the one measured, or at a browser zoom level. Breaking a word looks
   worse than not breaking it, but it never hides characters, and the sizing
   above means it should not trigger. */
h1, h2, h3, h4, h5{ overflow-wrap: break-word; }

/* The clamp floor used to be a fixed px value, so below ~400px the heading
   stopped shrinking while the screen kept getting narrower and the longest word
   ran off the edge. min(vw, px) keeps the old size everywhere it fits and only
   scales down in the band where it does not. */
.hero h1{ font-size: clamp(min(9.5vw, 40px), 5.4vw, 66px); line-height: 1.03; margin-bottom: 24px; }
.hero h1 span{ color: var(--blue-bright); }

.hero .lede{ font-size: 19.5px; color: var(--ink-1); max-width: 52ch; margin-bottom: 30px; line-height: 1.5; }
.hero .lede strong{ color: var(--ink-0); }
.hero .lede{ margin-bottom: 14px; }
.hero .lede-support{
  font-family: var(--font-display);
  font-size: clamp(15px, 1.5vw, 17.5px);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-2);
  max-width: 46ch;
  margin-bottom: 30px;
}

.hero-actions{ display: flex; gap: 16px; flex-wrap: wrap; margin-bottom: 26px; }

.status-badge{
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-2);
  padding: 9px 16px;
  border: 1px solid var(--line);
  border-radius: 999px;
}

.status-badge .rm-dot{ opacity: 1; box-shadow: 0 0 8px currentColor; color: var(--blue-bright); }

.btn{
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 15px 28px;
  border-radius: 999px;
  font-size: 13.5px;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  transition: all 0.2s ease;
  border: 1px solid transparent;
  cursor: pointer;
}

.btn-primary{ background: var(--blue-cta); color: #fff; }
.btn-primary:hover{ background: var(--blue-bright); box-shadow: 0 0 30px var(--blue-glow); transform: translateY(-1px); }

.btn-ghost{ border-color: var(--line); color: var(--ink-0); background: transparent; }
.btn-ghost:hover{ border-color: var(--blue); color: var(--blue-bright); }

/* Sits beside the primary button in the hero and points at someone else's
   video, so it is deliberately the quieter of the two: only the play glyph
   carries the accent. It takes the same glass the status badge below it has,
   because a plain ghost border is rgba(...,0.14) and the hero is a photograph:
   over a light patch of it the outline would have had nothing to hold. */
.btn-review{
  gap: 9px;
  background: rgba(10, 15, 26, 0.42);
  background-image: linear-gradient(180deg, rgba(255, 255, 255, 0.09), transparent 52%);
  border-color: rgba(255, 255, 255, 0.16);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.18), 0 0 18px rgba(255, 255, 255, 0.045);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}

.btn-review:hover{
  border-color: rgba(255, 255, 255, 0.42);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.3), 0 0 26px rgba(120, 170, 235, 0.35);
}

.btn-review svg{ color: var(--blue-bright); }

.hero-art{
  position: relative;
  display: block;
  aspect-ratio: 1 / 1;
  border-radius: 24px;
}

.hero-art-media{
  aspect-ratio: 16 / 9;
  border: 1px solid var(--line);
  overflow: hidden;
  background: var(--bg-2);
}

.hero-art-media img{
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.hero-art .hero-play{
  position: absolute;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  width: 64px; height: 64px;
  border-radius: 50%;
  background: rgba(61,132,232,0.92);
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  box-shadow: 0 0 34px var(--blue-glow);
  transition: transform 0.2s ease;
  z-index: 2;
}

.hero-art .hero-play svg{ width: 22px; height: 22px; margin-left: 3px; }
.hero-art:hover .hero-play{ transform: translate(-50%, -50%) scale(1.08); }



/* -------------------- generic section -------------------- */

section{ position: relative; padding: 92px 0; overflow-x: clip; }

.section-head{ max-width: 720px; margin-bottom: 56px; }
.section-head.center{ margin-left: auto; margin-right: auto; text-align: center; }

/* product sits on the left half of this section's photo, so keep text on the right, clear of it */
#countersteer .section-head,
#countersteer .prose{ margin-left: auto; }

.kicker{
  display: block;
  font-size: 12.5px;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--blue-bright);
  margin-bottom: 14px;
}

.section-head h2{ font-size: clamp(min(7.3vw, 28px), 3.6vw, 42px); line-height: 1.12; margin-bottom: 18px; }
.section-head .desc{ font-size: 17.5px; color: var(--ink-2); }

.pull{
  font-family: var(--font-display);
  font-size: clamp(23px, 2.8vw, 32px);
  line-height: 1.32;
  color: var(--ink-0);
  text-transform: none;
  max-width: 880px;
  padding: 6px 0 6px 26px;
  border-left: 3px solid var(--blue);
  margin: 46px 0;
  font-weight: 500;
}

.pull-lg{
  font-size: clamp(26px, 3.4vw, 38px);
  line-height: 1.28;
  max-width: 780px;
}

.pull.center{
  margin-left: auto;
  margin-right: auto;
  text-align: center;
  border-left: none;
  border-top: 3px solid var(--blue);
  padding: 26px 0 0;
}

.prose{ max-width: 680px; }
.prose p{ margin-bottom: 18px; font-size: 17px; color: var(--ink-1); }
.prose p:last-child{ margin-bottom: 0; }
.prose strong{ color: var(--ink-0); font-weight: 700; }

/* Inline section photography: a framed image in the flow of a section, as
   opposed to .section-photo, which is the full-bleed texture behind one. Same
   hairline and radius as the cards, and a fixed aspect so the row is reserved
   before the file lands and the first render cannot shift. */
.section-shot{
  margin: 0 auto;
  max-width: 920px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--bg-1);
  box-shadow: 0 0 0 1px rgba(10, 15, 26, 0.35), inset 0 1px 0 rgba(255, 255, 255, 0.06);
}

.section-shot-wide{ max-width: 1000px; }

.section-shot img{
  width: 100%;
  height: auto;
  aspect-ratio: 1672 / 941;
  object-fit: cover;
  display: block;
}

/* Corner marks, the way a technical drawing or a viewfinder frames a subject.
   Drawn on the frame's own pseudo-elements, so no element is added to carry
   them, and built from borders rather than an image. */
.section-shot, .aside-shot, .ride-card{ position: relative; }

.section-shot::before, .section-shot::after,
.aside-shot::before, .aside-shot::after,
.ride-card::before, .ride-card::after,
.section-shot picture::before, .section-shot picture::after,
.aside-shot picture::before, .aside-shot picture::after,
.ride-card picture::before, .ride-card picture::after{
  content: "";
  position: absolute;
  width: 13px;
  height: 13px;
  border: 1px solid rgba(120, 170, 235, 0.55);
  pointer-events: none;
  z-index: 2;
}

/* A frame has four corners and an element has two pseudo-elements, so the other
   pair is drawn on the <picture> inside it, which is positioned against the same
   frame. */
.section-shot::before, .aside-shot::before, .ride-card::before{
  top: 9px; left: 9px; border-right: 0; border-bottom: 0;
}
.section-shot::after, .aside-shot::after, .ride-card::after{
  bottom: 9px; right: 9px; border-left: 0; border-top: 0;
}
.section-shot picture::before, .aside-shot picture::before, .ride-card picture::before{
  top: 9px; right: 9px; border-left: 0; border-bottom: 0;
}
.section-shot picture::after, .aside-shot picture::after, .ride-card picture::after{
  bottom: 9px; left: 9px; border-right: 0; border-top: 0;
}

/* "Follow the project" is 213px where "Follow" was 109, and the six labels plus
   the brand plus that button do not fit below about 1000px: at 768px the labels
   alone need 458px of the 712px the container has once the brand and the button
   are placed, so no amount of gap tightening rescues it. The full nav therefore
   gives way to the hamburger at 1023px rather than 760px, and the band just
   above it gets tighter gaps so the wider button still clears the labels. */
/* Four things now share this row: logo, seven labels, the language switch and
   the 213px button. At 1024px the labels need 510px of glyphs and have 601px
   once the other three are placed, so the gap has to come down from 20px to
   fit on one line without touching the logo or shrinking any type. */
@media (max-width: 1180px) and (min-width: 1024px){
  .nav-links{ gap: 14px; }
}

/* The last 56px before the hamburger takes over is tighter still: at exactly
   1024px, 14px gaps overran the row by 21px. 10px clears it with room to
   spare, and the band is narrow enough that the closer spacing is not read as
   a different header. Measured in the widest fallback face available; Switzer
   is narrower, so the real margin is larger. */
@media (max-width: 1079px) and (min-width: 1024px){
  .nav-links{ gap: 10px; }
}

@media (max-width: 1023px){
  .nav-links, .nav-cta{ display: none; }
  .nav-toggle{ display: flex; }
}

/* The CTA goes away with the links, but the language must not: it stays in the
   bar, so it is never hidden behind the hamburger. Slightly tighter so the
   logo, the pair and the burger all fit a narrow phone. */
@media (max-width: 1023px){
  .lang-switch{ margin-left: auto; margin-right: 10px; }
  .lang-btn{ padding: 6px 9px; gap: 5px; }
}

@media (max-width: 400px){
  .lang-btn{ padding: 5px 7px; letter-spacing: 0.04em; }
  .lang-flag{ width: 13px; height: 9px; }
}

@media (max-width: 760px){
  .section-shot::before, .aside-shot::before, .ride-card::before{ top: 7px; left: 7px; }
  .section-shot::after, .aside-shot::after, .ride-card::after{ bottom: 7px; right: 7px; }
  .section-shot picture::before, .aside-shot picture::before, .ride-card picture::before{ top: 7px; right: 7px; }
  .section-shot picture::after, .aside-shot picture::after, .ride-card picture::after{ bottom: 7px; left: 7px; }
  .section-shot::before, .section-shot::after,
  .aside-shot::before, .aside-shot::after,
  .ride-card::before, .ride-card::after,
  .section-shot picture::before, .section-shot picture::after,
  .aside-shot picture::before, .aside-shot picture::after,
  .ride-card picture::before, .ride-card picture::after{ width: 10px; height: 10px; }
}

/* -------------------- problem section -------------------- */

#problem{ background: var(--bg-1); border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }

/* The copy here sits centred beneath the photo rather than ranged left, and one
   step up in size from the standard prose so it carries the section on its own. */
.prose-center{ margin-left: auto; margin-right: auto; text-align: center; }

#problem .section-shot{ margin-top: 40px; margin-bottom: 40px; }
/* the second photo closes the section, so it needs no gap beneath it */
#problem .section-shot-after{ margin-bottom: 0; }
#problem .prose{ max-width: 720px; }
#problem .prose p{ font-size: 19.5px; line-height: 1.65; }

/* The Polish pain point ends on a three-beat statement, and it is set in the
   register the page already keeps for those: display face, uppercase, letter
   spaced, with the same soft halo the headings carry, over the short blue rule
   used above the countersteering caption. Scoped to html[lang="pl"], which the
   switch sets, so the English paragraph is untouched. */
html[lang="pl"] #problem [data-i18n="pain.p2"]{
  position: relative;
  margin-top: 30px;
  padding-top: 26px;
  font-family: var(--font-display);
  font-size: clamp(16px, 1.7vw, 19px);
  font-weight: 600;
  letter-spacing: 0.08em;
  line-height: 1.5;
  text-transform: uppercase;
  color: var(--ink-0);
  text-shadow: 0 0 18px rgba(255, 255, 255, 0.34), 0 0 55px rgba(255, 255, 255, 0.22);
}

html[lang="pl"] #problem [data-i18n="pain.p2"]::before{
  content: "";
  position: absolute;
  top: 0;
  left: 50%;
  transform: translateX(-50%);
  width: 42px;
  height: 3px;
  border-radius: 2px;
  background: var(--blue);
}

@media (max-width: 760px){
  #problem .prose p{ font-size: 18px; }
  #problem .section-shot{ margin-top: 32px; margin-bottom: 32px; }
  #problem .section-shot-after{ margin-bottom: 0; }
}

.input-tags{ display: flex; flex-wrap: wrap; gap: 12px; margin: 30px 0 6px; }

.input-tags span{
  font-family: var(--font-display);
  font-size: 13px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  padding: 10px 18px;
  border: 1px solid var(--line);
  border-radius: 999px;
  color: var(--ink-2);
}

/* -------------------- countersteering ride card -------------------- */

/* the rider, handlebar and push-arrow all sit in the right half of this image,
   so the statement lives over the empty road on the left */
.ride-card{
  position: relative;
  max-width: 880px;
  margin: 54px auto 0;
  aspect-ratio: 16 / 9;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
}

.ride-card img{
  /* The heavy lift here existed for the first render, which sat almost entirely
     in the blacks: mean luminance 17/255, 81% of pixels under 24, and it
     disappeared on a phone in daylight. The replacement is graded far brighter
     to begin with, mean 32 and a 90th percentile of 72 against the old 30, so
     it already clears daylight unaided; running the old brightness(1.9) over it
     washed the blues out and flattened the render's own grading. What is left
     is a nudge, which still lands above where the old image ended up after the
     full correction. */
  filter: brightness(1.08) saturate(1.06);
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 50%;
}

.ride-card::after{
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg,
    rgba(6,10,19,0.9) 0%,
    rgba(6,10,19,0.72) 32%,
    rgba(6,10,19,0.26) 54%,
    transparent 74%);
}

.ride-card figcaption{
  position: absolute;
  inset: 0;
  z-index: 1;
  width: 56%;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 0 clamp(18px, 3.4vw, 40px);
}

.ride-rule{
  display: block;
  width: 42px;
  height: 3px;
  border-radius: 2px;
  background: var(--blue);
  margin-bottom: clamp(12px, 2vw, 20px);
}

.ride-card figcaption p{
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(15px, 2.3vw, 28px);
  line-height: 1.3;
  color: var(--ink-0);
  text-shadow: 0 2px 20px rgba(0,0,0,0.65);
  text-wrap: balance;
}

.ride-card figcaption p + p{ margin-top: 0.35em; }

/* on narrow screens a 16:9 crop leaves the statement no room, so give the card
   more height and re-anchor the crop on the handlebar instead */
@media (max-width: 640px){
  .ride-card{ aspect-ratio: 4 / 3; margin-top: 40px; }
  .ride-card img{ object-position: 64% 50%; }
  .ride-card::after{
    background: linear-gradient(90deg,
      rgba(6,10,19,0.88) 0%,
      rgba(6,10,19,0.7) 38%,
      rgba(6,10,19,0.26) 60%,
      transparent 80%);
  }
  .ride-card figcaption{ width: 62%; }
  .ride-card figcaption p{ font-size: 16px; }
}

/* -------------------- brake highlight (compact feature block) -------------------- */

.feature-block{
  display: grid;
  grid-template-columns: minmax(0, 1.55fr) minmax(0, 1fr);
  gap: 34px;
  align-items: center;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: linear-gradient(160deg, var(--bg-2), var(--bg-1));
  padding: 40px 38px;
}

.feature-main h3{ font-size: clamp(24px, 2.9vw, 34px); line-height: 1.14; margin-bottom: 20px; }
.feature-main p{ margin-bottom: 14px; font-size: 16.5px; color: var(--ink-1); max-width: 62ch; }
.feature-main p:last-child{ margin-bottom: 0; }

.feature-aside{
  border-left: 3px solid var(--blue);
  padding: 4px 0 4px 22px;
}

.feature-aside h4{ font-size: 14px; letter-spacing: 0.1em; margin-bottom: 12px; color: var(--ink-0); }
.feature-aside p{ font-size: 14.5px; line-height: 1.6; color: var(--ink-2); }

/* Product shot under the panel copy, held to the width of the text it sits
   beneath rather than bleeding to the column edge. Same hairline and radius as
   the cards elsewhere on the page, and a fixed aspect so the row it occupies is
   reserved before the file arrives and the first render cannot shift. */
.aside-shot{
  margin: 18px 0 0;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--bg-1);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.06);
}

.aside-shot img{
  width: 100%;
  height: auto;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  display: block;
}

/* -------------------- physical controls (icon-pack badge grid) -------------------- */

.badge-grid{
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 36px 24px;
  margin-top: 20px;
}

.badge-item{
  text-align: center;
  transition: transform 0.25s ease;
}

.badge-item:hover{ transform: translateY(-3px); }

.badge-item img{ width: 140px; height: 140px; margin: 0 auto 6px; }

.tech-note{ margin-top: 44px; font-size: 17px; color: var(--ink-1); }

.badge-item p{ font-size: 16.5px; line-height: 1.62; color: var(--ink-1); max-width: 30ch; margin: 0 auto; }

/* -------------------- supported titles -------------------- */

#platform{ background: var(--bg-1); border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }

.panorama-card{
  position: relative;
  min-height: 540px;
  display: flex;
  align-items: center;
  border-radius: 20px;
  overflow: hidden;
  border: 1px solid var(--line);
}

.panorama-card .section-photo img{
  mask-image: none;
  -webkit-mask-image: none;
}

.section-photo.vivid img{
  opacity: 0.85;
  filter: saturate(0.8) brightness(0.68) contrast(1.08);
}

.panorama-glass{
  position: relative;
  z-index: 1;
  max-width: 540px;
  margin: 48px;
  padding: 34px 38px;
  background: rgba(6, 10, 19, 0.76);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border-radius: 14px;
  border: 1px solid rgba(255, 255, 255, 0.07);
}

.panorama-glass .section-head{ max-width: none; }

.fine-print{ margin-top: 22px; font-size: 17.5px; color: var(--ink-3); }

/* Compatibility section: text bumped +3pt (4px) per feedback */
#platform .kicker{ font-size: 16.5px; }
#platform .desc{ font-size: 21.5px; }

.title-badges{ display: flex; flex-wrap: wrap; gap: 14px; margin-top: 30px; }

.title-badges span{
  font-family: var(--font-display);
  font-size: 18px;
  letter-spacing: 0.04em;
  padding: 14px 22px;
  border: 1px solid var(--line);
  border-radius: 10px;
  color: var(--ink-0);
  background: var(--bg-2);
}


/* -------------------- iteration / development -------------------- */



/* -------------------- roadmap -------------------- */

#roadmap{ background: var(--bg-1); border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }

.roadmap-track{
  position: relative;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 20px;
  margin-top: 60px;
}

.roadmap-track::before{
  content: "";
  position: absolute;
  top: -30px;
  left: 8%;
  right: 8%;
  height: 2px;
  background: var(--line);
}

/* Stops on the dot of the phase in progress, so the fill never overstates how
   far along the project is. The end point is arithmetic, not a guess: with four
   columns of width (W - 3*20)/4, the third card's centre sits at 0.625W + 2.5px,
   and the line starts at 8%, so it has to run 54.5% + 2.5px to land there. It
   was a flat 42% while there were five cards, where the third centre falls on
   exactly 0.5W whatever the width. */
.roadmap-track::after{
  content: "";
  position: absolute;
  top: -30px;
  left: 8%;
  width: calc(54.5% + 2.5px);
  height: 2px;
  background: linear-gradient(90deg, var(--blue-bright), var(--blue));
}

.rm-card{ border: 1px solid var(--line); border-radius: var(--radius); padding: 26px 20px; background: var(--bg-2); position: relative; }

.rm-card::before{
  content: "";
  position: absolute;
  top: -37px;
  left: 50%;
  transform: translateX(-50%);
  width: 14px; height: 14px;
  border-radius: 50%;
  background: var(--bg-0);
  border: 2px solid var(--line);
}

.rm-card.done::before, .rm-card.active::before{
  border-color: var(--blue-bright);
  background: var(--blue-bright);
  box-shadow: 0 0 12px var(--blue-glow);
}

.rm-card.active{ border-color: var(--blue); background: linear-gradient(160deg, rgba(61,132,232,0.12), var(--bg-2)); box-shadow: 0 0 34px rgba(61,132,232,0.14); }

.rm-card .ver{ display: block; font-family: var(--font-display); font-size: 20px; font-weight: 600; color: var(--ink-0); margin-bottom: 4px; }

.rm-card .ver-label{
  min-height: 2.4em;
  display: block;
  font-family: var(--font-display);
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-3);
  margin: 0 0 16px;
}

.rm-icon{
  width: 40px; height: 40px;
  border-radius: 50%;
  border: 1px solid var(--line);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--blue-bright);
  margin-bottom: 18px;
}

.rm-card ul{ margin: 0 0 18px; padding-left: 16px; font-size: 12.5px; color: var(--ink-2); }
.rm-card li{ margin-bottom: 5px; }

.rm-status{
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--ink-3);
}

.rm-card.done .rm-status, .rm-card.active .rm-status{ color: var(--blue-bright); }

.rm-dot{ width: 7px; height: 7px; border-radius: 50%; background: currentColor; display: inline-block; opacity: 0.55; }
.rm-dot.lock{ border-radius: 2px; opacity: 0.4; }
.rm-card.done .rm-dot, .rm-card.active .rm-dot{ opacity: 1; box-shadow: 0 0 8px currentColor; }

/* Only the phase in progress breathes; the finished ones stay lit and still.
   The breath is opacity, never box-shadow. Animating a shadow repaints the
   element on every frame for as long as the page is open, off screen included,
   and on a phone that one 7px dot was costing 54% of the main-thread time of a
   full scroll. The glow is now a static shadow on a pseudo-element and only
   its opacity moves, which the compositor handles without repainting. The
   shape and the rhythm are unchanged. */
@keyframes dot-breathe{
  0%, 100%{ opacity: 0.3; }
  50%     { opacity: 1; }
}

.rm-card.active .rm-dot{ position: relative; opacity: 1; }

.rm-card.active .rm-dot::after{
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  box-shadow: 0 0 16px currentColor, 0 0 26px currentColor;
  opacity: 0.3;
}

/* And it only breathes while the roadmap is actually on screen. The observer
   already puts in-view on this card for its own glow, so gating the animation
   on it costs nothing new and stops the work entirely for the rest of the
   page. will-change is scoped to the same state, so the layer exists while it
   is needed and is given back afterwards. */
.js .rm-card.active.in-view .rm-dot::after{
  will-change: opacity;
  animation: dot-breathe 2.8s var(--ease-motion) infinite;
}

.teaser{ text-align: center; margin-top: 64px; }

.teaser-line{
  font-family: var(--font-display);
  font-size: clamp(16px, 1.8vw, 20px);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-1);
  margin-bottom: 8px;
}

.teaser-sub{ font-size: 13.5px; color: var(--ink-3); }

.pillars{
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 26px 48px;
  max-width: 900px;
  margin: 64px auto 0;
  padding-top: 44px;
  border-top: 1px solid var(--line);
}

.pillar h4{ font-size: 15px; margin-bottom: 8px; color: var(--ink-0); }
.pillar p{ font-size: 14px; line-height: 1.6; color: var(--ink-3); }

/* -------------------- vision / community -------------------- */

/* video embed */
.video-slot{
  position: relative;
  aspect-ratio: 16 / 9;
  border-radius: var(--radius);
  border: 1px solid var(--line);
  background: linear-gradient(160deg, var(--bg-2), var(--bg-1));
  overflow: hidden;
  margin-top: 26px;
}

/* -------------------- closing / CTA -------------------- */

.closing{ text-align: center; padding: 128px 0; position: relative; overflow: hidden; }
.closing .logo-reveal{ width: 150px; height: auto; margin: 0 auto 28px; opacity: 0.92; }
.closing h2{ font-size: clamp(min(8vw, 30px), 5vw, 54px); max-width: 900px; margin: 0 auto 20px; line-height: 1.15; }
.closing .desc{ max-width: 620px; margin: 0 auto 40px; color: var(--ink-2); font-size: 17.5px; }

.closing .desc + .desc{ margin-top: -22px; }

.final-note{
  font-family: var(--font-display);
  font-size: 13px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--blue-bright);
}

/* the closing sections already end with a thin blue rule, so the statement inside them
   drops the pull's own top border instead of stacking two accents */
.closing .pull.center{ border-top: none; padding-top: 0; margin-top: 34px; }

.thin-line{ display: block; width: 64px; height: 3px; background: var(--blue); margin: 40px auto 0; border-radius: 2px; }

/* -------------------- follow / social -------------------- */

.social-grid{
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 18px;
  max-width: 980px;
  margin: 48px auto 0;
}

.contact-grid{
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 18px;
  max-width: 700px;
  margin: 48px auto 0;
}

.contact-grid .social-card span{ word-break: break-word; }

.social-card{
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 10px;
  padding: 30px 16px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--bg-1);
  transition: border-color 0.25s ease, transform 0.25s ease, background 0.25s ease;
}

.social-card:hover{ border-color: var(--blue); transform: translateY(-3px); }

.social-card svg{ width: 32px; height: 32px; color: var(--blue-bright); }

.social-card strong{
  font-family: var(--font-display);
  font-size: 15px;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--ink-0);
}

.social-card span{ font-size: 12.5px; color: var(--ink-3); }

/* -------------------- footer -------------------- */

footer{ border-top: 1px solid var(--line); padding: 56px 0 40px; }

.footer-grid{ display: flex; justify-content: space-between; align-items: flex-start; flex-wrap: wrap; gap: 30px; }

.footer-tag{ max-width: 320px; font-size: 14px; color: var(--ink-3); margin-top: 14px; }

.footer-links{ display: flex; gap: 40px; flex-wrap: wrap; }

.footer-links div h5{
  font-family: var(--font-display);
  font-size: 12px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-0);
  margin-bottom: 14px;
}

.footer-links ul{ list-style: none; margin: 0; padding: 0; }
.footer-links li{ margin-bottom: 10px; }
.footer-links a{ font-size: 13.5px; color: var(--ink-3); transition: color 0.2s; }
.footer-links a:hover{ color: var(--blue-bright); }

.social-row{ display: flex; gap: 10px; margin-top: 20px; }

.social-row a{
  width: 38px; height: 38px;
  border-radius: 50%;
  border: 1px solid var(--line);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--ink-2);
  transition: border-color 0.2s ease, color 0.2s ease, transform 0.2s ease;
}

.social-row a:hover{ border-color: var(--blue); color: var(--blue-bright); transform: translateY(-2px); }
.social-row svg{ width: 16px; height: 16px; }

.visit-counter{ font-size: 10px; opacity: 0.6; }

.footer-bottom{
  margin-top: 50px;
  padding-top: 24px;
  border-top: 1px solid var(--line);
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 10px;
  font-size: 12.5px;
  color: var(--ink-3);
}

/* -------------------- reveal animation -------------------- */

/* ============================================================
   MOTION SYSTEM
   Two mechanisms only:
     .reveal      - one element, observed and revealed on its own
     [data-group] - a container observed as a unit, children staggered
   Both are gated behind .js so nothing can stay hidden without script.
   Distances/scale come from custom properties so variants stay declarative.
   ============================================================ */

.js .reveal,
.js [data-group] > *{
  opacity: 0;
  transform: translate3d(var(--mx, 0px), var(--my, 30px), 0) scale(var(--ms, 1));
  --mdur: calc(950ms * var(--mscale));
  transition: opacity var(--mdur) var(--ease-enter),
              transform var(--mdur) var(--ease-enter);
  transition-delay: var(--mdelay, calc(270ms * var(--mscale)));
}

.js .reveal.in-view,
.js [data-group].in-view > *{ opacity: 1; transform: none; }

/* a container that only staggers its children never animates itself */
.js [data-group]{ opacity: 1; transform: none; }

/* --- variants --- */
.js [data-m="left"]{ --mx: -30px; --my: 0px; }
.js [data-m="right"]{ --mx: 30px; --my: 0px; }
.js [data-m="soft"]{ --my: 22px; --ms: 0.962; }
.js [data-m="card"]{ --my: 30px; }
.js [data-m="tag"]{ --my: 18px; --mdur: calc(690ms * var(--mscale)); }

/* section heads: eyebrow, then headline with a touch more travel, then body */
.js .section-head[data-group] > h1,
.js .section-head[data-group] > h2{ --my: 40px; --mdur: calc(1040ms * var(--mscale)); }
.js .section-head[data-group] > .desc{ --my: 26px; }

/* tag rows build up piece by piece */
.js .input-tags[data-group] > span,
.js .title-badges[data-group] > span{ --my: 18px; --mdur: calc(690ms * var(--mscale)); }

/* the two countersteering lines resolve outward from the centre */
.js .ride-card figcaption[data-group] > p:nth-of-type(1){ --mx: -34px; --my: 0px; --mdur: calc(1025ms * var(--mscale)); }
.js .ride-card figcaption[data-group] > p:nth-of-type(2){ --mx: 34px; --my: 0px; --mdur: calc(1025ms * var(--mscale)); }

/* control icons settle in with the card rather than popping */
.js .badge-item.reveal img{
  transform: scale(0.86);
  transition: transform var(--mdur) var(--ease-enter);
  transition-delay: var(--mdelay, calc(270ms * var(--mscale)));
}
.js .badge-item.reveal.in-view img{ transform: none; }

/* values drift in from their own side of the grid, vertical only on small screens */
@media (min-width: 901px){
  .js .pillars > .reveal:nth-child(odd){ --mx: -28px; --my: 0px; }
  .js .pillars > .reveal:nth-child(even){ --mx: 28px; --my: 0px; }
}

/* the closing logo scales up instead of travelling */
.js [data-group] > .logo-reveal{ --my: 0px; --ms: 0.9; --mdur: calc(1095ms * var(--mscale)); }

/* body copy trails its own heading */
.js .prose.reveal{ --mdelay: calc(330ms * var(--mscale)); }
.js .pull.reveal{ --mdelay: calc(410ms * var(--mscale)); }

/* the current roadmap card lifts once on entry - settles, never pulses */
.rm-card.active{ transition: box-shadow 700ms var(--ease-motion), border-color 700ms var(--ease-motion); }
.js .rm-card.active.in-view{ box-shadow: 0 0 46px rgba(61,132,232,0.26); }

/* ---- scroll-linked pieces (driven by one rAF loop in main.js) ---- */

.scroll-progress{
  position: fixed;
  top: 0; left: 0; right: 0;
  height: 2px;
  z-index: 200;
  pointer-events: none;
  background: transparent;
}

.scroll-progress > i{
  display: block;
  height: 100%;
  background: linear-gradient(90deg, var(--blue), var(--blue-bright));
  transform: scaleX(0);
  transform-origin: left center;
  position: relative;
}

/* A brighter head at the leading edge, so the bar reads as a needle sweeping a
   scale rather than a strip filling up. It rides the scaled element, so it is
   counter-scaled to stay a constant width; without that it would stretch into a
   smear as the bar grows. The counter-scale needs the live scale, which main.js
   already writes to the element as --sp. */
.scroll-progress > i::after{
  content: "";
  position: absolute;
  right: 0;
  top: -1px;
  bottom: -1px;
  width: 26px;
  transform: scaleX(calc(1 / max(var(--sp, 1), 0.02)));
  transform-origin: right center;
  background: linear-gradient(90deg, transparent, rgba(150, 200, 255, 0.95));
  box-shadow: 0 0 10px rgba(90, 168, 255, 0.85), 0 0 22px rgba(61, 132, 232, 0.5);
  pointer-events: none;
}

/* parallaxed photos get a little static headroom so a translate never
   uncovers an edge of the cropped image */
.js #countersteer .section-photo img,
.js #platform .panorama-card .section-photo img,
.js #community .section-photo img{
  transform: scale(1.1);
  will-change: transform;
}

.js .hero-art, .js .hero .container > div:first-child{ will-change: transform; }

/* roadmap progress line fills with scroll position through the section */
.roadmap-track::after{ transform-origin: left center; transform: scaleX(var(--rm-p, 1)); }

/* the brake accent grows as you scroll the section, reading as force building */
.feature-aside{ position: relative; border-left-color: rgba(61,132,232,0.2); }
.feature-aside::before{
  content: "";
  position: absolute;
  left: -3px; top: 0;
  width: 3px; height: 100%;
  background: var(--blue);
  transform-origin: top center;
  transform: scaleY(var(--brake-p, 1));
}

/* -------------------- ambient light / hi-gloss -------------------- */

/* A soft off-frame light per section, alternating side to side so the page
   reads as lit rather than flat. Painted as ::before, which sits above the
   section background but below every child, so nothing lands over copy.
   Plain gradients only — no blur filters, nothing animated. */
section::before,
.hero::before{
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background:
    radial-gradient(85% 40% at 22% -4%, rgba(255, 255, 255, 0.1), transparent 68%),
    radial-gradient(120% 70% at 12% -10%, var(--ambient), transparent 62%),
    radial-gradient(90% 55% at 100% 108%, rgba(61, 132, 232, 0.1), transparent 66%);
}

section:nth-of-type(even)::before{
  background:
    radial-gradient(85% 40% at 78% -4%, rgba(255, 255, 255, 0.1), transparent 68%),
    radial-gradient(120% 70% at 88% -10%, var(--ambient), transparent 62%),
    radial-gradient(90% 55% at 0% 108%, rgba(61, 132, 232, 0.1), transparent 66%);
}

/* The ambient alternates on nth-of-type, so inserting the FAQ section shifted
   the parity of everything after it and would have mirrored the light on the
   two sections that follow. Pin both to the side they already had. */
#faq ~ #contact::before{
  background:
    radial-gradient(85% 40% at 78% -4%, rgba(255, 255, 255, 0.1), transparent 68%),
    radial-gradient(120% 70% at 88% -10%, var(--ambient), transparent 62%),
    radial-gradient(90% 55% at 0% 108%, rgba(61, 132, 232, 0.1), transparent 66%);
}
#faq ~ #signup::before{
  background:
    radial-gradient(85% 40% at 22% -4%, rgba(255, 255, 255, 0.1), transparent 68%),
    radial-gradient(120% 70% at 12% -10%, var(--ambient), transparent 62%),
    radial-gradient(90% 55% at 100% 108%, rgba(61, 132, 232, 0.1), transparent 66%);
}

/* the panorama and the ride card carry their own photography — keep the
   ambient off them so it never muddies the image */
#platform::before{ opacity: 0.55; }

/* Gloss: a lit top edge plus a shallow sheen down the face of each surface.
   The edge is what sells it — a hairline that catches light in the middle
   and fades out at both corners. */
.rm-card::after,
.feature-block::after,
.social-card::after,
.panorama-glass::after,
.ride-card::before{
  content: "";
  position: absolute;
  top: 0;
  left: 12%;
  right: 12%;
  height: 1px;
  border-radius: inherit;
  background: linear-gradient(90deg, transparent, var(--gloss-edge), transparent);
  /* the bloom under the hairline is what makes it read as a light streak
     rather than a drawn line — this is the part that survives daylight */
  box-shadow: 0 0 16px 1px rgba(255, 255, 255, 0.45);
  pointer-events: none;
  z-index: 2;
}

.rm-card,
.feature-block,
.social-card,
.panorama-glass{
  background-image:
    radial-gradient(78% 46% at 50% -8%, rgba(255, 255, 255, 0.17), transparent 70%),
    linear-gradient(180deg, var(--gloss-sheen), transparent 40%);
}

/* the active roadmap card already carries a blue wash — layer the sheen on top
   of it rather than replacing it */
.rm-card.active{
  background-image:
    linear-gradient(180deg, rgba(255, 255, 255, 0.06), transparent 38%),
    linear-gradient(160deg, rgba(61, 132, 232, 0.12), var(--bg-2));
}

.social-card{ position: relative; }

/* primary buttons get the same treatment: lit top edge, sheen, ambient halo */
.btn-primary{
  position: relative;
  background-image: linear-gradient(180deg, rgba(255, 255, 255, 0.18), transparent 58%);
  box-shadow: 0 0 22px rgba(61, 132, 232, 0.24), inset 0 1px 0 rgba(255, 255, 255, 0.22);
}

.btn-primary:hover{ box-shadow: 0 0 34px var(--blue-glow), inset 0 1px 0 rgba(255, 255, 255, 0.3); }

/* Headings catch a soft white halo. Zero offset and a wide radius, so it
   reads as light coming off the letterforms rather than a blurred copy. */
h1, h2,
.feature-main h3,
.pull,
.teaser-line{
  text-shadow:
    0 0 18px rgba(255, 255, 255, 0.4),
    0 0 55px rgba(255, 255, 255, 0.3),
    0 0 110px rgba(255, 255, 255, 0.18);
}

.hero h1{
  text-shadow:
    0 0 20px rgba(255, 255, 255, 0.45),
    0 0 65px rgba(255, 255, 255, 0.35),
    0 0 130px rgba(255, 255, 255, 0.22);
}

.kicker, .eyebrow{ text-shadow: 0 0 22px rgba(120, 180, 255, 0.5); }

/* Boxed text — tag pills and the game chips — get the same lit top edge as
   the larger surfaces, scaled down: an inset hairline plus a faint halo. */
.input-tags span,
.title-badges span,
.status-badge{
  background-image: linear-gradient(180deg, rgba(255, 255, 255, 0.09), transparent 52%);
  border-color: rgba(255, 255, 255, 0.16);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.18), 0 0 18px rgba(255, 255, 255, 0.045);
}

/* the badge links through to how it works, so it has to look pressable */
a.status-badge{
  cursor: pointer;
  transition: color 240ms ease, border-color 240ms ease, box-shadow 240ms ease;
}

a.status-badge:hover,
a.status-badge:focus-visible{
  color: var(--ink-0);
  border-color: rgba(255, 255, 255, 0.42);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.3), 0 0 26px rgba(120, 170, 235, 0.35);
}

a.status-badge:focus-visible{ outline: 2px solid var(--blue-bright); outline-offset: 3px; }

.title-badges span{ box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.22), 0 0 24px rgba(255, 255, 255, 0.06); }

/* Roadmap: the current stage is the lit one, and everything still ahead of it
   sits back. Completed stages keep their normal weight — they are history, not
   something being de-emphasised. */
.rm-card.active{
  border-color: var(--blue-bright);
  box-shadow:
    0 0 60px rgba(61, 132, 232, 0.3),
    inset 0 1px 0 rgba(255, 255, 255, 0.28);
}

.js .rm-card.active.in-view{ box-shadow: 0 0 60px rgba(61, 132, 232, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.28); }

.rm-card.active::after{ left: 4%; right: 4%; background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.55), transparent); }

.rm-card.active .ver{ text-shadow: 0 0 26px rgba(120, 180, 255, 0.55); }

/* NEXT and FUTURE — the stages still ahead. Dimmed by taking the light off
   the surface, not by fading the card: at full strength these list items only
   reach 4.5:1 against their own background, so any opacity on the card drops
   the copy under the readable threshold. A darker, unlit face reads as held
   back and actually raises text contrast rather than lowering it. */
.rm-card:not(.done):not(.active){
  border-color: var(--line-soft);
  background-color: #1e2637;
  background-image: none;
  box-shadow: none;
}

.rm-card:not(.done):not(.active)::after{ opacity: 0.3; }

.rm-card:not(.done):not(.active) .rm-icon,
.rm-card:not(.done):not(.active) .rm-status{ opacity: 0.55; }

/* -------------------- section stepper -------------------- */

.section-nav{
  position: fixed;
  right: 22px;
  /* Percentages on a fixed element resolve against the viewport, which on a
     phone grows and shrinks as the address bar slides away — the panel used to
     slide with it. svh is the height with the bar showing and, unlike dvh, it
     is a fixed number that does not follow the bar, so the panel stays put.
     The percentage stays first as the fallback for engines without svh. */
  top: 65%;
  top: 65svh;
  transform: translateY(-50%);
  z-index: 95;
  display: flex;
  flex-direction: column;
  gap: 13px;
  opacity: 0;
  pointer-events: none;
  transition: opacity 420ms var(--ease-motion);
}

.section-nav.is-visible{ opacity: 1; pointer-events: auto; }

/* stays out of the way while the mobile menu is open */
body.nav-open .section-nav{ opacity: 0; pointer-events: none; }

.section-nav-btn{
  width: 42px;
  height: 42px;
  padding: 0;
  display: grid;
  place-items: center;
  border-radius: 50%;
  /* These float over whatever the page is showing — photographs included — so
     they carry their own light: a lit rim, a tight halo to separate them from
     the content behind, and a wider one so they still register in daylight. */
  border: 1px solid rgba(255, 255, 255, 0.24);
  background: rgba(10, 15, 26, 0.72);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  color: var(--ink-1);
  box-shadow:
    0 0 0 1px rgba(10, 15, 26, 0.5),
    0 0 18px rgba(120, 170, 235, 0.35),
    0 0 44px rgba(120, 170, 235, 0.18),
    inset 0 1px 0 rgba(255, 255, 255, 0.28);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: color 240ms ease, border-color 240ms ease,
              background-color 240ms ease, box-shadow 240ms ease, opacity 240ms ease;
}

.section-nav-btn svg{ width: 19px; height: 19px; }

/* -------------------- reading throttle -------------------- */

/* The bar carries its name down its left edge, reading bottom to top the way
   the travel does. It has to live outside .section-nav-throttle, which clips to
   its capsule so the fill stays inside the rounded ends; a label positioned out
   there would be cut off. */
.throttle-wrap{ position: relative; display: flex; }

.throttle-label{
  position: absolute;
  right: calc(100% + 9px);
  top: 50%;
  writing-mode: vertical-rl;
  transform: translateY(-50%) rotate(180deg);
  font-family: var(--font-display);
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: 0.34em;
  text-transform: uppercase;
  color: rgba(120, 170, 235, 0.72);
  text-shadow: 0 0 14px rgba(10, 15, 26, 0.9), 0 0 20px rgba(61, 132, 232, 0.35);
  white-space: nowrap;
  pointer-events: none;
  user-select: none;
  /* follows the bar it names, so the pair fades and returns as one */
  opacity: 0.3;
  transition: color 260ms ease, text-shadow 260ms ease, opacity 260ms ease;
}

.section-nav-throttle:hover ~ .throttle-label,
.section-nav-throttle:focus-visible ~ .throttle-label,
.section-nav-throttle.is-dragging ~ .throttle-label,
.section-nav-throttle.is-live ~ .throttle-label,
.throttle-wrap:hover .throttle-label{ opacity: 1; }

/* lights up with the bar it names; a plain sibling selector rather than :has(),
   which is why the label sits after the bar in the markup */
.section-nav-throttle.is-live ~ .throttle-label{
  color: var(--blue-bright);
  text-shadow: 0 0 14px rgba(10, 15, 26, 0.9), 0 0 22px rgba(90, 168, 255, 0.7);
}

.section-nav-throttle{
  --throttle-set: 0;
  --throttle-now: 0;
  width: 42px;
  height: 116px;
  position: relative;
  overflow: hidden;
  border-radius: 21px;
  /* same glass and same self-carried light as the arrows, so the three read as
     one control and not as a widget parked between two buttons */
  border: 1px solid rgba(255, 255, 255, 0.24);
  background: rgba(10, 15, 26, 0.72);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  box-shadow:
    0 0 0 1px rgba(10, 15, 26, 0.5),
    0 0 18px rgba(120, 170, 235, 0.35),
    0 0 44px rgba(120, 170, 235, 0.18),
    inset 0 1px 0 rgba(255, 255, 255, 0.28);
  cursor: ns-resize;
  /* the drag belongs to the control; without this a touch on it scrolls the
     page underneath and the throttle never sees the move */
  touch-action: none;
  -webkit-tap-highlight-color: transparent;
  /* Held well back while it is not being used, so it stops competing with the
     page it floats over, and brought fully forward the moment it is reached
     for or actually driving the scroll. Touch has no hover, so the live state
     carries it there: one tap sets a speed and the bar comes up with it. */
  opacity: 0.3;
  transition: border-color 240ms ease, box-shadow 240ms ease, opacity 260ms ease;
}

.section-nav-throttle:hover,
.section-nav-throttle:focus-visible,
.section-nav-throttle.is-dragging,
.section-nav-throttle.is-live{ opacity: 1; }

/* what the page is actually doing */
.throttle-fill{
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: calc(var(--throttle-now) * 100%);
  background: linear-gradient(180deg, var(--blue-bright), var(--blue-cta));
  box-shadow: 0 0 20px rgba(90, 168, 255, 0.55);
  pointer-events: none;
}

/* what the reader asked for — the gap between this and the fill is the
   throttle taking up, which is the whole point of the control */
.throttle-thumb{
  position: absolute;
  left: 7px; right: 7px;
  bottom: calc(var(--throttle-set) * 100%);
  height: 2px;
  margin-bottom: -1px;
  border-radius: 2px;
  background: #fff;
  box-shadow: 0 0 10px rgba(255, 255, 255, 0.85);
  opacity: 0;
  transition: opacity 220ms ease;
  pointer-events: none;
}

.section-nav-throttle.is-live .throttle-thumb,
.section-nav-throttle.is-dragging .throttle-thumb,
.section-nav-throttle:hover .throttle-thumb,
.section-nav-throttle:focus-visible .throttle-thumb{ opacity: 1; }

/* ladder, drawn over the fill so the travel stays readable once it is lit */
.section-nav-throttle::after{
  content: "";
  position: absolute;
  left: 15px; right: 15px; top: 12px; bottom: 12px;
  background: repeating-linear-gradient(
    180deg,
    rgba(255, 255, 255, 0.34) 0 1px,
    transparent 1px 13px);
  pointer-events: none;
}

.section-nav-throttle.is-live{
  border-color: var(--blue-bright);
  box-shadow:
    0 0 0 1px rgba(10, 15, 26, 0.5),
    0 0 26px rgba(61, 132, 232, 0.7),
    0 0 66px rgba(61, 132, 232, 0.36),
    inset 0 1px 0 rgba(255, 255, 255, 0.5);
}

.section-nav-throttle:hover{ border-color: rgba(255, 255, 255, 0.45); }

.section-nav-throttle:focus-visible{
  outline: 2px solid var(--blue-bright);
  outline-offset: 3px;
}

.section-nav-btn:hover{
  color: var(--blue-bright);
  border-color: rgba(255, 255, 255, 0.45);
  background: rgba(10, 15, 26, 0.86);
  box-shadow:
    0 0 0 1px rgba(10, 15, 26, 0.5),
    0 0 26px rgba(120, 170, 235, 0.6),
    0 0 62px rgba(120, 170, 235, 0.3),
    inset 0 1px 0 rgba(255, 255, 255, 0.42);
}

.section-nav-btn:focus-visible{
  outline: 2px solid var(--blue-bright);
  outline-offset: 3px;
  color: var(--blue-bright);
}

/* a disabled arrow keeps a faint presence so the control still reads as a
   group of three, but drops the halo entirely — nothing to invite a press */
.section-nav-btn:disabled{
  opacity: 0.32;
  cursor: default;
  box-shadow: 0 0 0 1px rgba(10, 15, 26, 0.5);
}

.section-nav-btn:disabled:hover{
  color: var(--ink-1);
  border-color: rgba(255, 255, 255, 0.24);
  background: rgba(10, 15, 26, 0.72);
  box-shadow: 0 0 0 1px rgba(10, 15, 26, 0.5);
}

@media (max-width: 760px){
  .section-nav{ right: 12px; top: 67%; top: 67svh; gap: 11px; }
  .section-nav-btn{ width: 38px; height: 38px; }
  .section-nav-btn svg{ width: 17px; height: 17px; }
}

@media (prefers-reduced-motion: reduce){
  html{ scroll-behavior: auto; }
  .js .reveal,
  .js [data-group] > *,
  .js .badge-item.reveal img{ opacity: 1; transform: none; transition: none; transition-delay: 0s; }
  /* no parallax, no scroll-linked transforms, no progress bar animation */
  .js #countersteer .section-photo img,
  .js #platform .panorama-card .section-photo img,
  .js #community .section-photo img{ transform: none; will-change: auto; }
  .js .hero-art, .js .hero .container > div:first-child{ transform: none !important; opacity: 1 !important; will-change: auto; }
  .roadmap-track::after{ transform: scaleX(1); }
  .feature-aside::before{ transform: scaleY(1); }
  .scroll-progress{ display: none; }
  .nav-cta-pulse, .js .rm-card.active.in-view .rm-dot::after{ animation: none; }
  .btn, .badge-item, .nav-links a, .social-row a, .social-card, .video-slot .play-btn{ transition: none; }
}

/* -------------------- responsive -------------------- */

@media (max-width: 900px){
  :root{ --mscale: 0.88; }
  /* 761-900px is the tightest the full nav ever gets; tightening the gaps
     keeps it on one line whatever the loaded face's widths turn out to be.
     With the FAQ entry added the six labels measure 458px at 768px against
     538px of room, so the old 22px gaps overran by 30px and "How it works"
     folded onto a second line. 16px clears it from 801px up. */
  .nav-links{ gap: 16px; }
  .hero .container{ grid-template-columns: 1fr; }
  .hero-art{ max-width: 420px; margin: 0 auto; }
  .badge-grid{ grid-template-columns: repeat(2, 1fr); }
  .roadmap-track{ grid-template-columns: repeat(2, 1fr); }
  .roadmap-track::before, .roadmap-track::after{ display: none; }
  .social-grid{ grid-template-columns: repeat(3, 1fr); }
  .pillars{ grid-template-columns: repeat(2, 1fr); }
  .feature-block{ grid-template-columns: 1fr; gap: 28px; padding: 34px 30px; }
}

/* The last 40px before the hamburger takes over is tighter still: at 768px
   16px gaps land exactly on the limit with nothing to spare. 11px keeps about
   25px in hand there, and the band is narrow enough that the closer spacing
   reads as deliberate rather than cramped. */
@media (max-width: 800px){
  .nav-links{ gap: 11px; }
}

@media (max-width: 760px){
  :root{ --mscale: 0.78; }
  .nav-links, .nav-cta{ display: none; }
  .nav-toggle{ display: flex; }
  section{ padding: 68px 0; }
  .hero{ padding: 90px 0 60px; }
  .roadmap-track{ grid-template-columns: 1fr; }
  .badge-grid{ grid-template-columns: 1fr; }
  .pillars{ grid-template-columns: 1fr; gap: 24px; }
  .feature-block{ padding: 28px 22px; }
  .feature-aside{ padding-left: 18px; }
  .social-grid{ grid-template-columns: repeat(2, 1fr); }
  .contact-grid{ grid-template-columns: 1fr; }
  .panorama-card{ min-height: 460px; }
  .panorama-glass{ max-width: none; margin: 22px; padding: 24px 22px; }
}

body.nav-open .nav-links{
  display: flex;
  position: fixed;
  top: 78px; left: 0; right: 0;
  flex-direction: column;
  background: var(--bg-1);
  padding: 26px 28px;
  border-bottom: 1px solid var(--line);
  gap: 20px;
  z-index: 99;
}

body.nav-open .nav-cta{
  display: inline-flex;
  position: fixed;
  bottom: 24px; left: 28px; right: 28px;
  justify-content: center;
  z-index: 99;
}


/* -------------------- FAQ -------------------- */

/* The open/close curve the brief asks for. Kept apart from --ease-enter: that
   one is for scroll entrances and deliberately starts from rest, which is
   wrong for a control that has to answer a press straight away. */
:root{ --ease-faq: cubic-bezier(0.22, 1, 0.36, 1); }

/* One column, wide enough to read and narrow enough not to sprawl. */
.faq-list{ max-width: 960px; margin: 0 auto; }

.faq-group + .faq-group{ margin-top: 56px; }

/* same treatment as the eyebrow labels elsewhere on the page, one step quieter */
.faq-group-label{
  display: block;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--blue-bright);
  margin-bottom: 18px;
  text-shadow: 0 0 22px rgba(120, 180, 255, 0.5);
}

.faq-item{
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: rgba(10, 15, 26, 0.55);
  transition: border-color 260ms ease, box-shadow 260ms ease, background-color 260ms ease;
}

.faq-item + .faq-item{ margin-top: 12px; }

.faq-q{ margin: 0; font-size: inherit; font-weight: inherit; }

/* The whole header is the control, not just the icon. */
.faq-trigger{
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 22px;
  padding: 21px 24px;
  border: 0;
  border-radius: var(--radius);
  background: none;
  color: var(--ink-0);
  font-family: var(--font-display);
  font-size: 17.5px;
  font-weight: 600;
  line-height: 1.45;
  letter-spacing: 0.01em;
  text-align: left;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.faq-q-text{ flex: 1 1 auto; }

/* drawn rather than shipped as an icon file: two rules that turn into a cross */
.faq-icon{
  position: relative;
  flex: 0 0 16px;
  width: 16px;
  height: 16px;
  color: var(--blue-bright);
  transition: transform 360ms var(--ease-faq);
}

.faq-icon::before,
.faq-icon::after{
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  background: currentColor;
  border-radius: 1px;
}

.faq-icon::before{ width: 15px; height: 1.6px; transform: translate(-50%, -50%); }
.faq-icon::after{ width: 1.6px; height: 15px; transform: translate(-50%, -50%); }

.faq-item.is-open .faq-icon{ transform: rotate(45deg); }

@media (hover: hover){
  .faq-item:hover{
    border-color: rgba(120, 170, 235, 0.3);
    box-shadow: 0 0 22px rgba(61, 132, 232, 0.14);
  }
}

.faq-item.is-open{
  border-color: rgba(90, 168, 255, 0.36);
  background: rgba(10, 15, 26, 0.72);
  box-shadow: 0 0 26px rgba(61, 132, 232, 0.15);
}

.faq-trigger:focus-visible{
  outline: 2px solid var(--blue-bright);
  outline-offset: -3px;
}

/* The panel animates on grid-template-rows, so the height comes from the
   content itself. No measuring in script, nothing to recompute on resize, and
   the closed height is genuinely zero, so the first render cannot shift. */
.faq-a{
  display: grid;
  grid-template-rows: 0fr;
  visibility: hidden;
  transition:
    grid-template-rows 320ms var(--ease-faq),
    visibility 0s linear 320ms;
}

.faq-item.is-open .faq-a{
  grid-template-rows: 1fr;
  visibility: visible;
  transition:
    grid-template-rows 430ms var(--ease-faq),
    visibility 0s;
}

.faq-a-clip{ overflow: hidden; }

.faq-a-body{
  padding: 0 24px 23px;
  max-width: 72ch;
  opacity: 0;
  transform: translateY(-4px);
  transition: opacity 190ms ease, transform 320ms var(--ease-faq);
}

.faq-item.is-open .faq-a-body{
  opacity: 1;
  transform: none;
  transition: opacity 260ms ease 90ms, transform 430ms var(--ease-faq);
}

.faq-a-body p{
  color: var(--ink-2);
  font-size: 16.5px;
  line-height: 1.7;
}

.faq-a-body p + p,
.faq-a-body ul + p{ margin-top: 14px; }

.faq-levels{
  list-style: none;
  margin: 14px 0 0;
  padding: 0;
}

.faq-levels li{
  font-family: var(--font-display);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.16em;
  color: var(--ink-1);
  line-height: 1.9;
}

@media (max-width: 900px){
  .faq-group + .faq-group{ margin-top: 46px; }
}

@media (max-width: 760px){
  .faq-trigger{
    padding: 17px 17px;
    gap: 16px;
    font-size: 16px;
    min-height: 62px;   /* comfortable target for a thumb */
  }
  .faq-a-body{ padding: 0 17px 19px; font-size: 16px; }
  .faq-a-body p{ font-size: 16px; }
  .faq-group + .faq-group{ margin-top: 40px; }
  .faq-item + .faq-item{ margin-top: 10px; }
}

/* The section stepper floats over the right edge of the viewport, and below
   about 1100px it lands on top of the plus icon and the last few characters of
   each answer: measured at 7 to 11px of overlap from 360px all the way up. The
   rest of the page only ever has body text under there, but here it is a
   control, so the row is given enough room on the right for the icon to clear
   it. Placed after the width blocks above so it wins on phones too. */
@media (max-width: 1100px){
  .faq-trigger{ padding-right: 54px; }
  .faq-a-body{ padding-right: 54px; }
}

@media (prefers-reduced-motion: reduce){
  /* no height travel and no sliding; the answer just appears */
  .faq-a,
  .faq-item.is-open .faq-a{ transition: grid-template-rows 0s, visibility 0s; }
  .faq-a-body,
  .faq-item.is-open .faq-a-body{ transform: none; transition: opacity 120ms linear; }
  .faq-icon{ transition: none; }
  .faq-item{ transition: none; }
}

/* ============================================================
   SHORTER COPY
   The main scroll path carries the idea and one argument; the
   detail lives in the FAQ, which opens on eight questions and
   reveals the rest in place. The spacing rules below are only
   where a section lost paragraphs and the picture should take
   the room instead; no token, type scale or global rhythm value
   is touched. Countersteering and the pain point carry their
   own padding on the section tag.
   ============================================================ */

/* -------------------- FAQ: eight first -------------------- */


.faq-list.is-trimmed .faq-item:not([data-faq-featured]),
.faq-list.is-trimmed .faq-group[data-faq-extra]{ display: none; }

.faq-more-wrap{ text-align: center; margin-top: 38px; }

/* focused only programmatically after a keyboard press, so it takes no ring */
.faq-list:focus{ outline: none; }

/* The browser does its own scroll anchoring when content appears above the
   viewport, and it was landing on top of the correction the script makes,
   overshooting by 45-80px. The script measures and restores the reader's
   position itself, so the automatic one is turned off for this list only. */
.faq-list{ overflow-anchor: none; }

.faq-more{
  /* btn-ghost over a sectioned background, same glass as the hero's
     secondary button so it reads as an affordance rather than an outline */
  background: rgba(10, 15, 26, 0.42);
  background-image: linear-gradient(180deg, rgba(255, 255, 255, 0.09), transparent 52%);
  border-color: rgba(255, 255, 255, 0.16);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.18);
}

.faq-more:hover{
  border-color: rgba(255, 255, 255, 0.42);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.3), 0 0 26px rgba(120, 170, 235, 0.35);
}

.faq-more-count{
  font-size: 10.5px;
  letter-spacing: 0.1em;
  color: var(--ink-3);
  padding-left: 10px;
  margin-left: 2px;
  border-left: 1px solid var(--line);
}

/* The newly shown questions arrive with the page's own entrance, not a new
   one: same distance, same easing, same scale variable as .reveal. The delay
   is set per item from the script. */
.faq-item.faq-arriving{
  opacity: 0;
  transform: translateY(18px);
}

.js .faq-item.faq-arrived{
  opacity: 1;
  transform: none;
  transition: opacity calc(620ms * var(--mscale)) var(--ease-enter) var(--faq-delay, 0ms),
              transform calc(620ms * var(--mscale)) var(--ease-enter) var(--faq-delay, 0ms);
}

@media (prefers-reduced-motion: reduce){
  .faq-item.faq-arriving{ opacity: 1; transform: none; }
  .js .faq-item.faq-arrived{ transition: none; }
}

/* -------------------- spacing after copy reduction -------------------- */

#countersteer .prose{ margin-bottom: 46px; }

/* The values row went from three-line paragraphs to three-word ones, which is
   the biggest single drop on the page. Tightened so the cards do not read as
   mostly air, and the row above it gets the space back. */
.pillars{ margin-top: 54px; }
.pillar p{ margin-bottom: 0; }

/* The closing lost a line; keep the logo and the headline from drifting apart */
#signup .desc{ margin-bottom: 14px; }

/* the compatibility footnote, in the panorama's own quiet tone */
.compat-note{
  margin: 18px 0 0;
  font-size: 13px;
  color: var(--ink-3);
}
