/* ==========================================================================
   Sections 1–7, in page order. Values read out of the boards in
   handoff/design/. Display sizes are fluid; the 1440px board value is the
   upper clamp, so the boards are reproduced exactly at 1440 and above.

   Optical left bearings are expressed in em, not px, so they keep scaling
   with the font size the way the measured numbers do (build-spec §2.1).
   ========================================================================== */

/* --- 1. Hero ------------------------------------------------------------ */

.topbar {
  position: sticky;
  top: 0;
  z-index: 60;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  padding: 5px var(--gutter-right) 5px var(--gutter-hero);
  border-bottom: 1px solid var(--rule-faint);
  /* It outlives its section, so it needs a ground of its own */
  background: var(--paper);
}

/* Centred on the bar itself, not between the two side items, so its
   position does not shift as the clock ticks. */
.topbar__now {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  font-family: var(--narrow);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: var(--ultramarine);
  white-space: nowrap;
  pointer-events: none;
}

.topbar__now[hidden] { display: none; }

/* The travelling player. It sits at the right of the bar, before the
   contact line, and only appears once the hero's own control is gone. */

.topbar__now i {
  display: inline-block;
  width: 6px;
  height: 6px;
  margin-right: 8px;
  border-radius: 50%;
  background: var(--ultramarine);
  vertical-align: 1px;
  animation: now-pulse 1.9s ease-in-out infinite;
}

@keyframes now-pulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50%      { opacity: 0.35; transform: scale(0.72); }
}

.topbar__item {
  font-family: var(--narrow);
  font-size: 10.5px;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--slate);
}

.topbar__item b { color: var(--onyx); font-weight: 500; }

.topbar__item a { color: var(--onyx); }
.topbar__item a:hover { color: var(--crowdflower); }

.navbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 40px;
  padding: 7px var(--gutter-right) 11px var(--gutter-hero);
}

.navbar__mark {
  margin-left: -1.3px;
  font-size: 18px;
}

.navbar__mark .kern-v { margin-left: -0.055em; }

.nav {
  display: flex;
  align-items: center;
  gap: 24px;
}

.nav__link {
  font-size: 13.5px;
  font-weight: 500;
  letter-spacing: -0.005em;
}

.nav__link:hover { color: var(--crowdflower); }

.hero {
  position: relative;
  /* The board's 900px, minus the bar and nav above it — see index.html.
     900/1440 is 62.5vw, so the hero keeps the board's aspect as the window
     widens, up to the shared cap. It also fills a taller
     window and never shrinks below what the board needs:
     capping it to the viewport compressed every gap on a short screen and
     the hero stopped matching the reference. The trade is §10's open item
     — on a 13-inch the bottom row sits below the fold, which is the
     board's own proportion. */
  min-height: calc(max(100svh, min(62.5vw, 1375px)) - var(--header-h, 79px));
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 32px;
  padding: 14px var(--gutter-right) 40px var(--gutter-hero);
  overflow: hidden;
}

.hero__eye {
  position: absolute;
  /* Both set by main.js: left from the midpoint between the headline's two
     periods, top from the bottom of the headline so the eye stays tucked
     under the text rather than drifting with the height of the section. */
  top: 0;
  left: 0;
  margin: 0;
  font-family: var(--mono);
  font-size: 9px;
  line-height: 1;
  letter-spacing: 0;
  font-variant-ligatures: none;
  color: var(--onyx);
  white-space: pre;
  user-select: none;
  cursor: crosshair;
  pointer-events: none;
}

.hero__headline-block { position: relative; }

.hero__headline {
  margin: 0 0 0 -0.081em; /* measured bearing: 11px at 136px */
  font-size: clamp(40px, 9.44vw, 208px);
  font-weight: 600;
  letter-spacing: -0.058em;
  line-height: 0.87;
  text-wrap: normal; /* NEVER balance: it rewraps and breaks the eye alignment */
}

.hero__cta { margin-top: clamp(28px, 3.9vw, 86px); }

/* Liquid headline. Letters are split by main.js; words stay unbreakable so
   the line wrap is unchanged. The transition is what makes it read as
   liquid rather than magnetic: it restarts on every pointer move, so the
   letters are always chasing a target they never quite reach. */
.hero__word {
  display: inline-block;
  white-space: nowrap;
}

.hero__ltr {
  display: inline-block;
  will-change: transform;
  transition: transform 520ms cubic-bezier(0.22, 1, 0.36, 1);
}

@media (prefers-reduced-motion: reduce) {
  .hero__ltr { transition: none; transform: none !important; }
}

/* The tagline the eye reveals on hover. Real text for screen readers, so it
   is present and merely transparent until revealed (build-spec §4). */
.hero__tagline {
  position: absolute;
  right: var(--gutter-right);
  top: 0;
  max-width: 420px;
  text-align: right;
  font-family: var(--narrow);
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.055em;
  line-height: 1.5;
  text-transform: uppercase;
  color: var(--slate);
  opacity: 0;
  transform: translateY(6px);
  transition: opacity 420ms var(--ease-zoom), transform 420ms var(--ease-zoom);
  pointer-events: none;
}

.hero__tagline.is-visible { opacity: 1; transform: translateY(0); }

.hero__knobs {
  position: relative;
  display: flex;
  align-items: flex-start;
  gap: 36px;
}

.hero__footrow {
  position: relative;
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 64px;
}

.hero__disciplines {
  font-family: var(--narrow);
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  flex-shrink: 0;
}

.hero__tools {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-shrink: 0;
}

/* --- 2. Logo carousel --------------------------------------------------- */

.proof {
  --grain-alpha: 0.13;
  --proof-fade: 160px;
  position: relative;
  min-height: 340px;
  overflow: hidden;
  padding: 48px 0 0;
}

/* The band colour and the blooms, dissolved into the page at top and
   bottom. Clipped square by the band's own rectangle they read as a hard
   edge across the page; the mask is what removes it. The card row sits
   well inside the uniform middle, so the left/right fades still match. */
.proof__ground {
  position: absolute;
  inset: 0;
  overflow: hidden;
  /* No band fill — the blooms glow straight onto the page, so there is no
     colour plateau to end and therefore no edge. The mask is only here to
     stop the blooms being clipped square by the band's box. */
  -webkit-mask-image: linear-gradient(180deg, transparent 0, #000 100px, #000 calc(100% - 100px), transparent 100%);
  mask-image: linear-gradient(180deg, transparent 0, #000 100px, #000 calc(100% - 100px), transparent 100%);
}

.proof__bloom {
  position: absolute;
  pointer-events: none;
  will-change: transform;
}

/* Filled edge to edge and blurred, so the falloff follows the silhouette
   rather than a circle. Centred on the card row, and carrying a little
   more weight than the board's values because there is no band fill
   underneath — glass only reads as glass over something varied (§3). */
.proof__bloom:nth-of-type(1) {
  left: -170px; top: -60px; width: 820px; height: 360px;
  background: linear-gradient(128deg, rgba(11,31,214,0.52) 0%, rgba(38,78,248,0.30) 58%, rgba(11,31,214,0.10) 100%);
  animation: bloom-a 52s ease-in-out infinite;
}
.proof__bloom:nth-of-type(2) {
  left: 140px; top: 46px; width: 600px; height: 230px;
  background: linear-gradient(72deg, rgba(6,14,112,0.40) 0%, rgba(11,31,214,0.22) 70%, rgba(6,14,112,0.06) 100%);
  animation: bloom-b 67s ease-in-out infinite;
}
.proof__bloom:nth-of-type(3) {
  left: 370px; top: 10px; width: 980px; height: 330px;
  background: linear-gradient(158deg, rgba(38,78,248,0.46) 0%, rgba(110,140,255,0.26) 62%, rgba(38,78,248,0.08) 100%);
  animation: bloom-c 41s ease-in-out infinite;
}
.proof__bloom:nth-of-type(4) {
  right: -180px; top: -30px; width: 760px; height: 320px;
  background: linear-gradient(104deg, rgba(110,140,255,0.56) 0%, rgba(38,78,248,0.30) 60%, rgba(110,140,255,0.08) 100%);
  animation: bloom-d 58s ease-in-out infinite;
}
.proof__bloom:nth-of-type(5) {
  left: -80px; top: -10px; width: 1160px; height: 340px;
  background: linear-gradient(90deg, rgba(38,78,248,0.22) 0%, rgba(195,208,255,0.18) 55%, rgba(38,78,248,0.04) 100%);
  animation: bloom-e 70s ease-in-out infinite;
}

@keyframes bloom-a {
  0%, 100% { transform: rotate(-9deg) translate3d(0, 0, 0) scale(1); }
  50%      { transform: rotate(-4deg) translate3d(70px, 26px, 0) scale(1.06); }
}
@keyframes bloom-b {
  0%, 100% { transform: rotate(15deg) translate3d(0, 0, 0) scale(1); }
  50%      { transform: rotate(9deg) translate3d(-90px, -18px, 0) scale(0.94); }
}
@keyframes bloom-c {
  0%, 100% { transform: rotate(6deg) translate3d(0, 0, 0) scale(1); }
  50%      { transform: rotate(11deg) translate3d(-110px, 20px, 0) scale(1.05); }
}
@keyframes bloom-d {
  0%, 100% { transform: rotate(-13deg) translate3d(0, 0, 0) scale(1); }
  50%      { transform: rotate(-7deg) translate3d(60px, 34px, 0) scale(0.95); }
}
@keyframes bloom-e {
  0%, 100% { transform: rotate(3deg) translate3d(0, 0, 0) scale(1); }
  50%      { transform: rotate(0deg) translate3d(80px, -24px, 0) scale(1.04); }
}

.proof__label {
  position: relative;
  text-align: center;
  display: block;
  padding: 0 var(--gutter);
}

.proof__viewport {
  position: relative;
  margin-top: 18px;
  overflow: hidden;
  /* headroom so a lifted card is never clipped */
  padding: 16px 0 40px;
  /* The row dissolves at both ends by masking itself. Painting
     page-coloured strips over the top instead put two rectangles over the
     blooms, and their horizontal edges cut a straight line across the
     glow — which is the division that kept showing up. */
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 var(--proof-fade), #000 calc(100% - var(--proof-fade)), transparent 100%);
  mask-image: linear-gradient(90deg, transparent 0, #000 var(--proof-fade), #000 calc(100% - var(--proof-fade)), transparent 100%);
}

/* No scrollbar chrome, ever — including the reduced-motion fallback below,
   where the row stays reachable by swipe and keyboard but draws no bar. */
.proof__viewport { scrollbar-width: none; -ms-overflow-style: none; }
.proof__viewport::-webkit-scrollbar { display: none; }

.proof__track {
  display: flex;
  align-items: stretch;
  gap: 18px;
  width: max-content;
  will-change: transform; /* track only — never the cards (§5) */
  animation: proof-scroll 45s linear infinite;
}

/* The row does NOT stop on hover. Hovering a card lifts that card instead,
   and it keeps travelling under the cursor — see the centre-zoom block in
   main.js. (This overrides "pause on hover" in build-spec §5, on request.) */

/* Rightward: the duplicated half starts shifted left and resolves to 0 */
@keyframes proof-scroll {
  from { transform: translate3d(-50%, 0, 0); }
  to   { transform: translate3d(0, 0, 0); }
}

/* The outer card is the hit box and never moves. Only the inner visual
   scales and shifts.

   This split is load-bearing. When the transform was on the card itself,
   lifting one card pushed its neighbours' hit areas sideways under a
   stationary cursor, so the browser handed :hover to a different card than
   the one being pointed at — and clearing that card's push snapped the
   first one back, which could oscillate. Keeping the hit geometry fixed
   makes the hovered card always the card under the cursor. */
.proof__card {
  flex-shrink: 0;
  position: relative;
}

.proof__card-inner {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 7px;
  height: 100%;
  border-radius: 20px;
  padding: 20px 30px;
  transform-origin: 50% 50%;
  transform: scale(1);
  transition: transform 380ms var(--ease-zoom);
}

.proof__card:hover { z-index: 3; }
.proof__card:hover .proof__card-inner { transform: scale(1.14); }

.proof__name {
  font-size: 25px;
  font-weight: 600;
  letter-spacing: -0.032em;
  line-height: 1;
  color: var(--onyx);
  white-space: nowrap;
}

.proof__role {
  font-family: var(--narrow);
  font-size: 11.5px;
  font-weight: 500;
  letter-spacing: 0.095em;
  text-transform: uppercase;
  color: #525A64;
  white-space: nowrap;
}

/* Accent numbers inside glass are Ultramarine, not Signal (§3) */
.proof__role b { color: var(--ultramarine); font-weight: 500; }

/* --- 3. Case studies — one slot, swiped --------------------------------- */

.cases {
  padding: 42px var(--gutter) 44px;
  overflow: hidden;
}

.cases__viewport { overflow: hidden; }

.cases__track {
  display: flex;
  transition: transform 520ms var(--ease-zoom);
  will-change: transform;
}

.case {
  flex: 0 0 100%;
  min-width: 0;
  display: flex;
  flex-direction: column;
  min-height: 720px;
}

.case__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 40px;
  padding-bottom: 22px;
}

.case__client {
  font-family: var(--narrow);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  margin-left: -0.6px;
}

.case__meta {
  display: flex;
  align-items: baseline;
  gap: 20px;
  margin-right: -1px;
  font-family: var(--narrow);
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.13em;
  text-transform: uppercase;
}

.case__live { color: var(--crowdflower); }
.case__year { color: var(--slate); }

/* The field is the page's blue bloom, never a blur of the screenshot (§6) */
.case__field {
  /* The ground behind each card is one photograph — a sky, shot close
     enough that it reads as weather rather than as a picture of clouds —
     turned to the case's own colour. The file is greyscale, and
     `background-blend-mode: luminosity` keeps its light while taking hue
     and saturation from `--case-accent`, so a single 73KB texture serves
     every case and nothing has to be re-exported to add one.

     Each accent comes out of a hue histogram of the case's own
     screenshot, weighted by saturation, rather than being picked by
     eye. */
  --grain-alpha: 0.11;
  --case-accent: #2A3A6B;
  position: relative;
  flex-grow: 1;
  min-height: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 20px;
  overflow: hidden;
  background-color: var(--case-accent);
  background-image: url('../assets/case-clouds.jpg');
  background-size: cover;
  background-position: 50% 42%;
  background-blend-mode: luminosity;
  cursor: zoom-in;
  padding: 36px;
}

/* A vignette, so the pale screenshot still lifts off the sky at the
   corners where the cloud happens to be bright. */
.case__field::before {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: radial-gradient(120% 90% at 50% 46%,
    rgba(0, 0, 0, 0) 38%,
    rgba(0, 0, 0, 0.22) 78%,
    rgba(0, 0, 0, 0.38) 100%);
}

/* David's screenshot is 93% one teal, so that one chose itself.
   Prevención's splits almost evenly — 37% warm rust, 34% the deep navy
   of its own chrome — and the navy is taken, because Balerco already has
   the warm end of the wheel and three cards want three colours.
   Balerco's capture reads mostly as the sky in its own hero photograph,
   which would have been a second blue and told you nothing; its orange
   is the next cluster down and the colour the brand is actually built
   on. */
#slide-prevencion .case__field { --case-accent: #2A3A6B; }
#slide-david      .case__field { --case-accent: #0C4F5E; }
#slide-balerco    .case__field { --case-accent: #A85516; }

/* Glass-rimmed card. No fake browser chrome (§6). */
.case__shot {
  position: relative;
  width: 720px;
  max-width: 100%;
  border-radius: 18px;
  overflow: hidden;
  border: 1px solid rgba(255,255,255,0.78);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,0.9),
    0 2px 8px -2px rgba(12,18,40,0.18),
    0 34px 70px -28px rgba(12,18,40,0.52);
  transition: transform 480ms var(--ease-zoom);
}

.case__shot--wide { width: 780px; }

.case__field:hover .case__shot { transform: translateY(-6px) scale(1.012); }

.case__shot img { display: block; width: 100%; height: auto; }

.case__body {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 64px;
  padding: 26px 0 22px;
}

.case__desc {
  max-width: 560px;
  font-size: 17px;
  font-weight: 450;
  letter-spacing: -0.014em;
  line-height: 1.45;
}

.case__tags {
  display: flex;
  gap: 8px;
  flex-shrink: 0;
  padding-top: 2px;
  flex-wrap: wrap;
}

.case__foot {
  border-top: 1px solid var(--hairline);
  padding-top: 20px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 40px;
}

.case__read {
  display: inline-flex;
  align-items: center;
  gap: 11px;
  font-family: var(--narrow);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  margin-left: -0.6px;
}

.case__read svg { display: block; transition: transform 240ms var(--ease-zoom); }
.case__read:hover svg { transform: translateX(4px); }

.cases__dots {
  display: flex;
  align-items: center;
  gap: 9px;

  /* The row sits at the slide's right edge, which is also the carousel
     viewport's `overflow: hidden` boundary — and that boundary lands on a
     fractional pixel, so the browser was shaving the last column off the
     selected dot and leaving it flat on one side. Two pixels of clearance
     keeps the circle whole, and leaves room for the hover scale, which
     grows it past the edge by just over a pixel. */
  margin-right: 2px;
}

.cases__dot {
  width: 9px;
  height: 9px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: var(--dot-off);
  cursor: pointer;
  transition: background 220ms ease, transform 220ms var(--ease-zoom);
}

.cases__dot[aria-selected='true'] { background: var(--onyx); }
.cases__dot:hover { transform: scale(1.25); }

/* --- Case reader ------------------------------------------------------ */

.reader {
  position: fixed;
  inset: 0;
  z-index: 90;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: clamp(12px, 3vw, 44px);
  background: rgba(4, 5, 7, 0.86);
  -webkit-backdrop-filter: blur(10px) saturate(0.6);
  backdrop-filter: blur(10px) saturate(0.6);
  opacity: 0;
  transition: opacity 360ms var(--ease-zoom);
}

.reader[hidden] { display: none; }
.reader.is-open { opacity: 1; }

.reader__panel {
  position: relative;
  width: min(1240px, 100%);
  height: min(92vh, 1000px);
  display: flex;
  flex-direction: column;
  border-radius: 14px;
  overflow: hidden;
  background: #16181C;
  border: 1px solid rgba(255,255,255,0.16);
  box-shadow: 0 2px 8px rgba(0,0,0,0.5), 0 50px 110px -30px rgba(0,0,0,0.9);
  transform: scale(0.96) translateY(10px);
  transition: transform 420ms var(--ease-zoom);
}

.reader.is-open .reader__panel { transform: none; }

/* Same chrome as the reel windows — it is the same motif */
.reader__bar { height: 38px; gap: 12px; flex-shrink: 0; }

.reader__close {
  width: 11px;
  height: 11px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: #FF5F57;
  cursor: pointer;
  transition: filter 160ms ease;
}

.reader__close:hover { filter: brightness(1.25); }

.reader__bar .win__title { padding-right: 0; }

.reader__actions {
  display: flex;
  align-items: center;
  gap: 18px;
  flex-shrink: 0;
  font-family: var(--narrow);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.11em;
  text-transform: uppercase;
}

.reader__actions a { color: var(--signal); }
.reader__actions a:hover { color: var(--paper); }
.reader__actions a[hidden] { display: none; }

/* The scrollable space: an embedded site scrolls itself, a set of pages
   scrolls here. */
.reader__body {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  background: #0B0C0F;

  /* The platform scrollbar — grey thumb in a grey trough — is the one
     piece of chrome in here the site did not draw. It gets the same
     treatment as everything else: no trough, and a floating glass pill
     for the thumb. The transparent border plus `background-clip:
     content-box` is what lifts the pill off both edges; there is no way
     to inset a scrollbar thumb directly. */
}

/* Setting `scrollbar-width` at all makes Chrome ignore the
   ::-webkit-scrollbar rules below, so the standard properties are kept
   for the browsers that have nothing else — Firefox gets thin and
   troughless, which is as close as the standard gets. */
@supports not selector(::-webkit-scrollbar) {
  .reader__body {
    scrollbar-width: thin;
    scrollbar-color: rgba(255, 255, 255, 0.26) transparent;
  }
}

.reader__body::-webkit-scrollbar { width: 14px; }

.reader__body::-webkit-scrollbar-track,
.reader__body::-webkit-scrollbar-corner { background: transparent; }

.reader__body::-webkit-scrollbar-thumb {
  border: 3px solid transparent;
  background-clip: content-box;
  border-radius: 999px;
  background-color: rgba(255, 255, 255, 0.30);
  background-image: linear-gradient(180deg,
    rgba(255, 255, 255, 0.34) 0%,
    rgba(255, 255, 255, 0.10) 100%);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.16);
}

.reader__body::-webkit-scrollbar-thumb:hover {
  background-color: rgba(255, 255, 255, 0.44);
}

.reader__body::-webkit-scrollbar-thumb:active {
  background-color: rgba(255, 255, 255, 0.58);
}

.reader__body iframe {
  display: block;
  width: 100%;
  height: 100%;
  border: 0;
}

.reader__pages {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 18px;
  padding: 18px;
}

.reader__pages img {
  display: block;
  width: 100%;
  max-width: 1000px;
  height: auto;
  border-radius: 6px;
}

.reader__slot {
  width: 100%;
  max-width: 1000px;
  aspect-ratio: 16 / 10;
  border-radius: 6px;
  display: flex;
  align-items: flex-end;
  padding: 18px;
  background: linear-gradient(152deg, #27304A 0%, #151B2B 50%, #0D1018 100%);
  border: 1px solid rgba(255,255,255,0.09);
}

.reader__slot span {
  font-family: var(--narrow);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: rgba(255,255,255,0.6);
}

.reader__loading {
  padding: 40px;
  text-align: center;
  font-family: var(--narrow);
  font-size: 11.5px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--grey-dark);
}

@media (prefers-reduced-motion: reduce) {
  .reader, .reader__panel { transition: none; }
  .reader__panel { transform: none; }
}

/* --- 4. Reel: thrown windows ------------------------------------------- */

.reel {
  position: relative;
  /* Its own stacking context, so the dust can sit at z-index 0 — behind
     the content but still in front of the band's own colour. Without it
     the canvas would have to go negative and disappear behind the
     section background. */
  isolation: isolate;
  min-height: 720px;
  background: var(--onyx);
  color: var(--paper);
  padding: 40px var(--gutter) 22px;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.reel__dust {
  position: absolute;
  inset: 0;
  z-index: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

.reel__head,
.reel__body,
.reel__foot {
  position: relative;
  z-index: 1;
}

.reel__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 32px;
}

.reel__head .label { color: var(--grey-dark); }

.reel__time {
  font-family: var(--narrow);
  font-size: 12.5px;
  font-weight: 500;
  letter-spacing: 0.06em;
  color: var(--grey-dark);
}

.reel__body {
  flex-grow: 1;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto;
  align-items: center;
  gap: 24px 40px;
  padding: 28px 0;
}

.reel__headline {
  grid-column: 1;
  align-self: center;
  font-size: clamp(36px, 5.69vw, 125px);
  font-weight: 600;
  letter-spacing: -0.05em;
  line-height: 0.94;
  max-width: 14ch;
}

/* The stage the windows are thrown onto */
.reel__stage {
  grid-column: 2;
  position: relative;
  width: clamp(300px, 36vw, 620px);
  height: clamp(340px, 42vw, 600px);
  perspective: 1400px;
}

/* Beside the windows, not under the headline — it belongs to the thing
   it moves. */
.reel__nav {
  grid-column: 3;
  align-self: center;
  display: flex;
}

/* --- the window ------------------------------------------------------- */

.win {
  position: absolute;
  top: 50%;
  left: 50%;
  border-radius: 12px;
  overflow: hidden;
  background: #16181C;
  border: 1px solid rgba(255,255,255,0.14);
  box-shadow:
    0 2px 6px rgba(0,0,0,0.5),
    0 40px 80px -24px rgba(0,0,0,0.85);
  /* Thrown, not slid: an overshoot at the end of the travel, and the card
     arrives already turned. --angle is random per window but fixed once,
     so a window does not jitter each time it comes round. */
  /* No transition in the parked state: when the stack re-orders on a wrap
     the other windows must jump back to the right, not slide across. Both
     travelling states declare their own transition below. */
  transition: none;
  transform:
    translate(-50%, -50%)
    translateX(calc(var(--stage-w, 620px) * 1.25))
    rotate(calc(var(--angle, 0deg) * 2.4))
    scale(0.82);
  opacity: 0;
  pointer-events: none;
  will-change: transform, opacity;
}

.win.is-active,
.win.is-past {
  transition:
    transform 760ms cubic-bezier(0.18, 0.89, 0.32, 1.22),
    opacity 420ms ease;
}

.win.is-active {
  transform: translate(-50%, -50%) rotate(var(--angle, 0deg)) scale(1);
  opacity: 1;
  pointer-events: auto;
  z-index: 3;
}

/* Popped off to the left, spinning a little further as it goes */
.win.is-past {
  transform:
    translate(-50%, -50%)
    translateX(calc(var(--stage-w, 620px) * -1.3))
    rotate(calc(var(--angle, 0deg) * -2.8))
    scale(0.84);
  opacity: 0;
  z-index: 1;
}

.win--wide  { width: min(560px, 92%); }
.win--tall  { width: min(290px, 60%); }

.win__bar {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 0 12px;
  height: 30px;
  background: linear-gradient(180deg, #32363C 0%, #25282D 100%);
  border-bottom: 1px solid rgba(0,0,0,0.6);
}

.win__dots { display: flex; gap: 6px; flex-shrink: 0; }

.win__dots i {
  width: 11px;
  height: 11px;
  border-radius: 50%;
  display: block;
}

.win__dots i:nth-child(1) { background: #FF5F57; }
.win__dots i:nth-child(2) { background: #FEBC2E; }
.win__dots i:nth-child(3) { background: #28C840; }

.win__title {
  flex: 1;
  text-align: center;
  font-family: var(--narrow);
  font-size: 10.5px;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: rgba(255,255,255,0.56);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  /* balance the dots so the title sits optically centred */
  padding-right: 45px;
}

.win__body { position: relative; background: #000; }

.win__body video {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.win--wide .win__body { aspect-ratio: 16 / 9; }
.win--tall .win__body { aspect-ratio: 9 / 16; }

.reel__foot {
  border-top: 1px solid var(--rule-dark);
  padding: 18px 0 20px;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 40px;
  font-family: var(--narrow);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--grey-dark);
}

.reel__slot { color: var(--signal); }

.reel__progress {
  position: absolute;
  left: 0;
  bottom: 0;
  width: 100%;
  height: 2px;
  background: var(--rule-dark);
}

.reel__progress span {
  display: block;
  width: 14%;
  height: 2px;
  background: var(--crowdflower);
  transition: width 520ms var(--ease-zoom);
}

/* --- 5. Photography ----------------------------------------------------- */

.photo {
  --grain-alpha: 0.30;
  position: relative;
  min-height: 760px;
  background: var(--void);
  color: var(--paper);
  overflow: hidden;
  padding: 30px var(--gutter-right) 44px var(--gutter-hero);
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 48px;
}

.photo__bloom {
  position: absolute;
  pointer-events: none;
}

.photo__bloom:nth-of-type(1) {
  left: 90px; top: 10px; width: 760px; height: 560px;
  --blob-blur: 86px;
  background: linear-gradient(142deg, rgba(38,78,248,0.78) 0%, rgba(20,44,190,0.34) 56%, rgba(9,18,96,0.04) 100%);
}
.photo__bloom:nth-of-type(2) {
  right: -240px; top: -180px; width: 700px; height: 520px;
  --blob-blur: 92px;
  background: linear-gradient(68deg, rgba(110,140,255,0.34) 0%, rgba(38,78,248,0.10) 66%, rgba(110,140,255,0) 100%);
}
.photo__bloom:nth-of-type(3) {
  left: -200px; bottom: -300px; width: 820px; height: 520px;
  --blob-blur: 96px;
  background: linear-gradient(196deg, rgba(11,31,214,0.40) 0%, rgba(20,44,190,0.12) 62%, rgba(11,31,214,0) 100%);
}

.photo__head {
  position: relative;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 40px;
}

.photo__head .label { color: var(--haze); }
.photo__hint { color: #7E8AA8; }

.photo__foot {
  position: relative;
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 40px;
}

.photo__headline {
  margin: 0 0 0 -0.066em; /* measured bearing: 5px at 76px */
  font-size: clamp(34px, 5.28vw, 116px);
  font-weight: 600;
  letter-spacing: -0.052em;
  line-height: 0.95;
  max-width: 900px;
}

.photo__where {
  font-family: var(--narrow);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: #7E8AA8;
  margin-right: -1px;
  text-align: right;
  flex-shrink: 0;
}

/* Trail layer — nodes are spawned by JS at the pointer */
.photo__trail {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 1;
}

.photo__frame {
  position: absolute;
  border-radius: 10px;
  overflow: hidden;
  border: 1px solid rgba(255,255,255,0.14);
  box-shadow: 0 20px 50px -20px rgba(0,0,0,0.85);
  background: linear-gradient(152deg, #2B3550 0%, #151C2E 46%, #0C1018 100%);
  opacity: 0;
  transform: translate(-50%, -50%) scale(0.82) rotate(var(--rot, 0deg));
  transition: opacity 240ms ease-out, transform 380ms var(--ease-zoom);
  will-change: transform, opacity;
}

.photo__frame.is-in {
  opacity: 1;
  transform: translate(-50%, -50%) scale(1) rotate(var(--rot, 0deg));
}

.photo__frame.is-out {
  opacity: 0;
  transform: translate(-50%, -40%) scale(0.96) rotate(var(--rot, 0deg));
  transition: opacity 420ms ease-in, transform 480ms ease-in;
}

.photo__frame img { display: block; width: 100%; height: 100%; object-fit: cover; }

.photo__frame::after {
  content: '';
  position: absolute;
  inset: 0;
  background: radial-gradient(90% 70% at 24% 18%, rgba(176,196,255,0.22) 0%, rgba(176,196,255,0) 68%);
}

.photo__frame-no {
  position: absolute;
  left: 10px;
  bottom: 9px;
  z-index: 1;
  font-family: var(--narrow);
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(255,255,255,0.46);
}

/* Touch / reduced motion: a scroll strip instead of a trail (§7) */
.photo__strip {
  position: relative;
  display: none;
  gap: 16px;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  padding: 4px 0 18px;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  -ms-overflow-style: none;
}

.photo__strip::-webkit-scrollbar { display: none; }

.photo__strip > * {
  flex: 0 0 auto;
  width: 220px;
  height: 160px;
  scroll-snap-align: start;
  position: relative;
  border-radius: 10px;
  overflow: hidden;
  border: 1px solid rgba(255,255,255,0.14);
  background: linear-gradient(152deg, #2B3550 0%, #151C2E 46%, #0C1018 100%);
}

.photo.is-static .photo__trail { display: none; }
.photo.is-static .photo__strip { display: flex; }
.photo.is-static .photo__hint { visibility: hidden; }

/* --- 6. FAQ and rates --------------------------------------------------- */

.faq {
  padding: 64px var(--gutter);
  display: flex;
  gap: 96px;
}

.faq__intro {
  width: 400px;
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
}

.faq__headline {
  margin: 22px 0 0 -0.081em; /* measured bearing: 5px at 62px */
  font-size: clamp(34px, 4.31vw, 95px);
  font-weight: 600;
  letter-spacing: -0.05em;
  line-height: 0.95;
  text-wrap: balance;
}

.faq__copy {
  margin: 22px 0 0;
  font-size: 15.5px;
  line-height: 1.6;
  color: var(--ink-soft);
  max-width: 340px;
}

.faq__cta { margin-top: auto; align-self: flex-start; }

.faq__list {
  flex-grow: 1;
  min-width: 0;
  border-top: 1px solid var(--hairline);
}

.faq__item { border-bottom: 1px solid var(--hairline); }

.faq__q {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 32px;
  padding: 22px 0;
  border: 0;
  background: none;
  text-align: left;
  cursor: pointer;
  font-size: 19px;
  font-weight: 550;
  letter-spacing: -0.022em;
}

.faq__q:hover { color: var(--crowdflower); }

.faq__sign {
  flex-shrink: 0;
  font-size: 20px;
  font-weight: 400;
  line-height: 1;
  color: var(--grey-mid);
}

.faq__q[aria-expanded='true'] { color: var(--onyx); }
.faq__q[aria-expanded='true'] .faq__sign { color: var(--ultramarine); }

.faq__a {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows 420ms var(--ease-zoom);
}

.faq__a[data-open='true'] { grid-template-rows: 1fr; }

.faq__a > div { overflow: hidden; }

.faq__a-inner { padding: 0 0 26px; max-width: 640px; }

.faq__a p {
  font-size: 15.5px;
  line-height: 1.6;
  color: var(--ink-soft);
}

.faq__a p + p { margin-top: 14px; }

.rates {
  margin-top: 18px;
  border-top: 1px solid var(--rule-faint);
}

.rates__row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 24px;
  padding: 11px 0;
  border-bottom: 1px solid var(--rule-faint);
  font-size: 15px;
}

.rates__row:last-child { border-bottom: 0; }

.rates__price {
  font-family: var(--narrow);
  font-size: 14px;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--ultramarine);
  white-space: nowrap;
}

.rates__note {
  margin-top: 16px;
  font-family: var(--narrow);
  font-size: 11.5px;
  font-weight: 500;
  letter-spacing: 0.085em;
  text-transform: uppercase;
  color: var(--grey-mid);
}

/* --- 7. CTA ------------------------------------------------------------- */

.cta {
  position: relative;
  min-height: 800px;
  padding: 40px var(--gutter) 36px;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 40px;
  overflow: hidden;
}

.cta__head,
.cta__foot {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 40px;
}

.cta__foot {
  border-top: 1px solid var(--hairline);
  padding-top: 18px;
  font-family: var(--narrow);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--slate);
}

.cta__social {
  display: flex;
  gap: 26px;
  flex-wrap: wrap;
}

.cta__social a { color: var(--crowdflower); }
.cta__social a:hover { color: var(--ultramarine); }
.cta__copyright { color: var(--grey-mid); margin-right: -1px; }

/* Scales up as the section enters view — transform only, never font-size */
.cta__wordmark {
  font-size: clamp(56px, 24.1vw, 530px);
  font-weight: 600;
  letter-spacing: -0.055em;
  line-height: 0.80;
  white-space: nowrap;
  user-select: none;
  transform-origin: left center;
  transform: scale(0.86) translateY(14px);
  transition: transform 900ms var(--ease-zoom);
}

.cta__wordmark.is-in { transform: scale(1) translateY(0); }

/* Each letter slides in, the top line travelling right-to-left and the
   bottom line left-to-right. Split into spans by main.js. */
.cta__ltr {
  display: inline-block;
  transform: translateX(var(--from, 0));
  opacity: 0;
  transition:
    transform 760ms var(--ease-zoom) var(--delay, 0ms),
    opacity 420ms ease-out var(--delay, 0ms);
  will-change: transform, opacity;
}

.cta__wordmark-line:first-child .cta__ltr { --from: 0.42em; }
.cta__wordmark-line:last-child  .cta__ltr { --from: -0.42em; }

.cta__wordmark.is-in .cta__ltr {
  transform: translateX(0);
  opacity: 1;
}

/* A letter mid-flight would otherwise widen the page */
.cta { overflow-x: clip; }

.cta__wordmark-line:first-child { margin-left: -0.0805em; } /* K: 28px at 348px */
.cta__wordmark-line:last-child { margin-left: -0.023em; }   /* V: 8px at 348px */

.cta__wordmark .kern-v { margin-left: -0.012em; }

.cta__wordmark-reg {
  font-size: 0.30em;
  vertical-align: 0.90em;
  letter-spacing: 0;
  margin-left: 0.055em;
  color: var(--ultramarine);
}

.cta__card {
  position: absolute;
  right: 96px;
  top: 236px;
  width: 556px;
  max-width: calc(100% - var(--gutter) * 2);
  border-radius: 24px;
  padding: 26px;
  display: flex;
  gap: 24px;
  z-index: 2;
  will-change: transform;
  /* The follow is eased here rather than in a frame loop */
  transition: transform 520ms var(--ease-zoom);
}

.cta__portrait {
  flex-shrink: 0;
  width: 132px;
  height: 158px;
  border-radius: 14px;
  overflow: hidden;
  position: relative;
  border: 1px solid rgba(255,255,255,0.7);
  background: linear-gradient(152deg, #27304A 0%, #151B2B 50%, #0D1018 100%);
}

.cta__portrait img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* A light across the top, as the board has it, but gentler now that there
   is a photograph under it rather than a flat gradient. */
.cta__portrait::after {
  content: '';
  position: absolute;
  inset: 0;
  background:
    radial-gradient(86% 66% at 28% 20%, rgba(176,196,255,0.16) 0%, rgba(176,196,255,0) 70%),
    linear-gradient(0deg, rgba(5,7,12,0.72) 0%, rgba(5,7,12,0.18) 22%, rgba(5,7,12,0) 42%);
}

.cta__portrait span {
  position: absolute;
  left: 10px;
  bottom: 9px;
  z-index: 1;
  font-family: var(--narrow);
  font-size: 10.5px;
  font-weight: 500;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: rgba(255,255,255,0.72);
}

.cta__card-body {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.cta__status {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--narrow);
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

.cta__status i {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--ultramarine);
  box-shadow: 0 0 0 4px rgba(11,31,214,0.16);
}

.cta__pitch {
  font-size: 18px;
  line-height: 1.38;
  letter-spacing: -0.018em;
}

.cta__pitch b { font-weight: 650; }

/* ==========================================================================
   Responsive. The boards are 1440px; below that the display type is fluid
   and the two-column rows stack.
   ========================================================================== */

@media (max-width: 1200px) {
  .cta__card {
    position: static;
    width: 100%;
    max-width: 556px;
    margin-top: 32px;
  }
  .faq { gap: 56px; }
  .faq__intro { width: 320px; }
}

@media (max-width: 900px) {
  :root {
    --gutter: 24px;
    --gutter-hero: 20px;
    --gutter-right: 20px;
  }

  .hero {
    min-height: auto;
    padding-top: 28px;
    padding-bottom: 32px;
    gap: 44px;
  }

  .hero__eye {
    position: relative;
    bottom: auto;
    left: auto !important;
    align-self: center;
    order: -1;
  }

  .hero__tagline {
    position: static;
    opacity: 1;
    transform: none;
    max-width: none;
    margin-top: 24px;
    text-align: left;
  }

  .hero__knobs { gap: 20px; flex-wrap: wrap; }
  .hero__footrow { gap: 24px; }

  .case { min-height: 0; }
  .case__head,
  .case__body,
  .case__foot { flex-direction: column; align-items: flex-start; gap: 16px; }
  .case__field { padding: 20px; min-height: 280px; }
  .case__foot { align-items: stretch; }
  .cases__dots { align-self: flex-end; }

  .reel { min-height: 0; }
  .reel__body { grid-template-columns: minmax(0, 1fr) auto; grid-template-rows: auto auto; gap: 24px 16px; }
  .reel__headline { grid-column: 1 / -1; grid-row: 1; max-width: none; }
  .reel__stage { grid-column: 1; grid-row: 2; width: 100%; height: 62vw; min-height: 300px; }
  .reel__nav { grid-column: 2; grid-row: 2; align-self: center; }
  .reel__foot { flex-direction: column; align-items: flex-start; gap: 10px; }

  .photo { min-height: 0; padding-top: 28px; }
  .photo__foot { flex-direction: column; align-items: flex-start; gap: 20px; }
  .photo__where { text-align: left; }

  .faq { flex-direction: column; gap: 48px; padding-top: 48px; padding-bottom: 48px; }
  .faq__intro { width: 100%; }
  .faq__cta { margin-top: 32px; }

  .cta { min-height: 0; padding-top: 32px; }
  .cta__head,
  .cta__foot { flex-direction: column; align-items: flex-start; gap: 12px; }
  .cta__card { flex-direction: column; }
}

@media (max-width: 760px) {
  /* The bar stacks, so the readout cannot stay centred on top of it —
     it joins the column instead of overlapping the clock. */
  .topbar__now {
    position: static;
    transform: none;
    order: -1;
  }
}

@media (max-width: 560px) {
  .topbar { flex-direction: column; align-items: flex-start; gap: 4px; padding-top: 8px; padding-bottom: 8px; }
  .topbar__item--right { margin-right: 0; }
  .nav { gap: 14px; }
  .navbar { flex-wrap: wrap; gap: 16px; }
  .pill--hero { padding: 20px 32px; font-size: 18px; }
  .proof__card { padding: 16px 22px; }
  .proof__name { font-size: 20px; }
  .cta__portrait { width: 108px; height: 130px; }
}

/* --- Reduced motion ----------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  .cta__ltr { transform: none; opacity: 1; transition: none; }
  .cta__card { transition: none; }

  .proof__track,
  .proof__bloom { animation: none; }

  /* Static row, still reachable by swipe and keyboard, no scrollbar drawn */
  .proof__viewport { overflow-x: auto; }
  .proof__track { transform: none; }
  /* The hover lift is user-initiated, so it stays — only shorter */
  .proof__card-inner { transition: transform 200ms ease; }

  .cases__track { transition: none; }
  .case__shot { transition: none; }

  .case-zoom,
  .case-zoom__inner { transition: opacity 200ms linear; }
  .case-zoom__inner { transform: none; }

  .cta__wordmark { transition: none; transform: none; }

  .photo__frame { transition: none; }

  .faq__a { transition: none; }

  .pill, .circle-btn, .case__read svg { transition: none; }
}


/* ==========================================================================
   Travelling scrim
   A band of blur fixed to the bottom of the viewport. It rides along while
   you scroll and recedes once you settle, so it reads as motion rather
   than as a permanent bar across the page.
   ========================================================================== */

.scrim {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  height: 120px;
  z-index: 55;
  pointer-events: none;
  opacity: 0;
  transition: opacity 520ms var(--ease-zoom);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
  /* The mask is what keeps it from reading as a bar: the blur is full
     strength at the very bottom and gone by the top of the band. */
  -webkit-mask-image: linear-gradient(0deg, #000 0%, rgba(0,0,0,0.65) 38%, transparent 100%);
  mask-image: linear-gradient(0deg, #000 0%, rgba(0,0,0,0.65) 38%, transparent 100%);
}

.scrim.is-moving { opacity: 1; }

@media (prefers-reduced-motion: reduce) {
  .scrim { display: none; }
}
