/* --- Typeface -----------------------------------------------------------------
   IBM Plex Sans Condensed, served from this origin. Four weights, latin subset,
   woff2. No italic face: `em` is set to `font-style: normal` below and every
   `<i>` on the site is an empty decorative bar in `.ref-strip` / `.fit-dots`.
   If real italic text ever appears, add the face with it.

   SIL Open Font License 1.1 — the licence text ships with the files in
   fonts/OFL.txt, which the OFL requires to travel with them. */
@font-face {
  font-family: "IBM Plex Sans Condensed";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("fonts/ibm-plex-sans-condensed-latin-400-normal.woff2") format("woff2");
}
@font-face {
  font-family: "IBM Plex Sans Condensed";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("fonts/ibm-plex-sans-condensed-latin-500-normal.woff2") format("woff2");
}
@font-face {
  font-family: "IBM Plex Sans Condensed";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("fonts/ibm-plex-sans-condensed-latin-600-normal.woff2") format("woff2");
}
@font-face {
  font-family: "IBM Plex Sans Condensed";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("fonts/ibm-plex-sans-condensed-latin-700-normal.woff2") format("woff2");
}
/* ============================================================
   NotchFrame — monochrome product site
   Structural tokens (spacing grid, elevations, focus rings,
   control sizing) from the Blueprint design system.
   Palette is deliberately black + white only.
   ============================================================ */

:root {
  --black: #111418;
  --text: #1c2127;
  --text-muted: #5e5a53;
  --gray3: #8f99a8;
  --gray4: #abb3bf;
  --gray5: #c5cbd3;
  --lg1: #d3d8de;
  --lg3: #e4e2dc;
  --lg4: #eceae6;
  --lg5: #f5f4f1;
  --surface: #ffffff;

  --ink: #111418;
  --ink-hover: #2f343c;
  --ink-active: #000000;

  /* sampled from the logo mark — used only for the nav CTA hover */
  --brand: #d0021a;
  --brand-active: #a90215;

  --divider: rgba(17, 20, 24, 0.15);
  --divider-muted: rgba(17, 20, 24, 0.1);

  --radius-pill: 999px;
  --radius-block: 16px;
  --radius-card: 12px;

  --focus-ring: rgba(17, 20, 24, 0.75);
  /* The dark sections paint the ring in near-black on near-black — a keyboard
     user tabbing the hero CTAs, the footer or the sticky bar saw nothing at all. */
  --focus-ring-light: rgba(255, 255, 255, 0.92);
  --ease: cubic-bezier(0.4, 1, 0.75, 0.9);
  /* Entrances use this instead: nearly all the distance is covered in the first
     third, then it settles hard. That's the snap — the soft --ease above drifts
     into place, which reads as a web transition rather than motion design.
     --ease is still right for hovers and other small state changes. */
  --ease-snap: cubic-bezier(0.16, 1, 0.3, 1);
  --dur: 120ms;

  --font: "IBM Plex Sans Condensed", -apple-system, "Segoe UI Condensed", "Roboto Condensed", "Helvetica Neue", sans-serif;

  /* Grade for the .hero-film panel, applied on the page rather than baked into
     the file so it stays tunable. Set light; the heavier camcorder numbers were
     0.55 / 0.72 / 1.15 / 0.5px / 0.3 / 0.55 if that look is wanted back.
     No page uses .hero-film at the moment — these are parked with it. */
  --film-saturate: 0.92;
  --film-brightness: 0.94;
  --film-contrast: 1.04;
  --film-blur: 0px;
  --film-grain: 0.07;
  --film-vignette: 0.4;
}

* { margin: 0; padding: 0; box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
  background: var(--lg5);
  color: var(--text);
  font-family: var(--font);
  font-size: 17px;                    /* the face is narrow; a point up keeps it legible */
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

::selection { background: var(--lg1); }

.container { max-width: 1140px; margin: 0 auto; padding: 0 24px; }

h1, h2, h3 { color: var(--black); font-weight: 500; letter-spacing: -0.008em; }
h1 { font-size: clamp(2.8rem, 6.4vw, 5rem); line-height: 1.0; letter-spacing: -0.015em; }
h2 { font-size: clamp(2rem, 4vw, 3.1rem); line-height: 1.08; letter-spacing: -0.012em; }
h3 { font-size: 1.1rem; font-weight: 600; letter-spacing: -0.004em; }

p { color: var(--text-muted); }
strong { color: var(--text); font-weight: 600; }
em { font-style: normal; font-weight: 600; color: var(--text); }
a { color: var(--black); text-decoration: none; }

:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 3px; border-radius: 2px; }
.hero :focus-visible,
.stage :focus-visible,
.sticky-bar :focus-visible,
.site-footer :focus-visible,
.notice-footer :focus-visible { outline-color: var(--focus-ring-light); }

/* First thing in the tab order, out of the way until it is focused. */
.skip-link {
  position: absolute;
  left: 16px;
  top: -60px;
  z-index: 100;
  background: var(--black);
  color: #fff;
  padding: 10px 18px;
  border-radius: var(--radius-pill);
  font-size: 0.88rem;
  font-weight: 600;
  transition: top 150ms var(--ease);
}
.skip-link:focus { top: 16px; }

.microlabel {
  display: block;
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--black);
}

/* ============ Buttons (soft, pill) ============ */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  height: 46px;
  padding: 0 26px;
  background: var(--ink);
  color: #fff;
  font-family: var(--font);
  font-size: 0.95rem;
  font-weight: 600;
  border: 1px solid var(--ink);
  border-radius: var(--radius-pill);
  cursor: pointer;
  white-space: nowrap;
  transition: background var(--dur) var(--ease), border-color var(--dur) var(--ease), transform var(--dur) var(--ease);
}
.btn:hover { background: var(--ink-hover); border-color: var(--ink-hover); }
.btn:active { background: var(--ink-active); border-color: var(--ink-active); transform: translateY(1px); }

.btn-outline {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  height: 46px;
  padding: 0 26px;
  background: #fff;
  color: var(--black);
  font-family: var(--font);
  font-size: 0.95rem;
  font-weight: 600;
  border: 1px solid var(--divider);
  border-radius: var(--radius-pill);
  cursor: pointer;
  white-space: nowrap;
  transition: background var(--dur) var(--ease), border-color var(--dur) var(--ease), transform var(--dur) var(--ease);
}
.btn-outline:hover { background: var(--lg5); border-color: var(--black); }
.btn-outline:active { transform: translateY(1px); }

.btn-lg { height: 56px; padding: 0 32px; font-size: 1rem; }
.btn-sm, .btn-sm-outline { height: 40px; padding: 0 20px; font-size: 0.88rem; }
.btn-icon {
  width: 18px;
  height: 18px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* Download CTAs are the one thing on the page in the brand red at rest: a
   gradient lit from the top, a hairline highlight along the upper edge, and a
   red glow beneath, so they sit proud of the page — then a lift and a
   brighter glow under the cursor. Keyed on the href rather than a class, so
   every one of them behaves the same and a new one anywhere inherits it.
   The outline variant stays quiet at rest and takes the red on its border and
   label on hover, which keeps the primary and secondary readable as different
   buttons. To fill it too, give it the solid rule's lines. */
a[href^="/download/"] {
  transition: background 170ms var(--ease), border-color 170ms var(--ease),
              color 170ms var(--ease), transform 170ms var(--ease),
              box-shadow 170ms var(--ease), filter 170ms var(--ease);
}
a.btn[href^="/download/"] {
  background: linear-gradient(180deg, #ee2b42 0%, var(--brand) 58%, #b8021a 100%);
  border-color: #b8021a;
  color: #fff;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.32),
              0 8px 22px -6px rgba(208, 2, 26, 0.6),
              0 2px 6px rgba(208, 2, 26, 0.24);
}
a.btn[href^="/download/"]:hover {
  background: linear-gradient(180deg, #f5404f 0%, #dd0a24 58%, #b8021a 100%);
  border-color: #b8021a;
  transform: translateY(-2px);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.36),
              0 14px 30px -8px rgba(208, 2, 26, 0.7),
              0 3px 8px rgba(208, 2, 26, 0.28);
}
a.btn[href^="/download/"]:active {
  background: linear-gradient(180deg, var(--brand) 0%, var(--brand-active) 100%);
  border-color: var(--brand-active);
  transform: translateY(0);
  box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.18),
              0 2px 6px rgba(208, 2, 26, 0.28);
}
a.btn-outline[href^="/download/"]:hover {
  background: #fff;
  color: var(--brand);
  border-color: var(--brand);
  transform: translateY(-2px);
  box-shadow: 0 6px 16px rgba(208, 2, 26, 0.16);
}
a.btn-outline[href^="/download/"]:active {
  color: var(--brand-active);
  border-color: var(--brand-active);
  transform: translateY(0);
  box-shadow: 0 2px 6px rgba(208, 2, 26, 0.14);
}

/* On the dark hero (and the nav sitting in it) the reel already uses the brand
   red, so a red fill would not stand apart. White primary, ghost outline.
   Same on the getting-started stage: btn-light / btn-ghost must actually stay
   light, rather than being repainted by the href rule above. */
.hero a.btn[href^="/download/"],
.nav-space a.btn[href^="/download/"],
.stage a.btn.btn-light[href^="/download/"] {
  background: #fff;
  color: var(--black);
  border-color: #fff;
  box-shadow: none;
}
.hero a.btn[href^="/download/"]:hover,
.nav-space a.btn[href^="/download/"]:hover,
.stage a.btn.btn-light[href^="/download/"]:hover {
  background: #e6e9ee;
  color: var(--black);
  border-color: #e6e9ee;
  transform: translateY(-2px);
  box-shadow: none;
}
.hero a.btn[href^="/download/"]:active,
.nav-space a.btn[href^="/download/"]:active,
.stage a.btn.btn-light[href^="/download/"]:active {
  background: #d3d8de;
  color: var(--black);
  border-color: #d3d8de;
  transform: translateY(0);
  box-shadow: none;
}
.hero a.btn-outline[href^="/download/"],
.stage a.btn-outline.btn-ghost[href^="/download/"] {
  background: transparent;
  color: #fff;
  border-color: rgba(255, 255, 255, 0.55);
  box-shadow: none;
}
.hero a.btn-outline[href^="/download/"]:hover,
.stage a.btn-outline.btn-ghost[href^="/download/"]:hover {
  background: #fff;
  color: var(--black);
  border-color: #fff;
  transform: translateY(-2px);
  box-shadow: none;
}
.hero a.btn-outline[href^="/download/"]:active,
.stage a.btn-outline.btn-ghost[href^="/download/"]:active {
  background: #fff;
  color: var(--black);
  border-color: #fff;
  transform: translateY(0);
  box-shadow: none;
}

/* ============ Nav ============ */
.nav {
  background: var(--lg5);
  border-bottom: 1px solid var(--divider-muted);
}
/* on the front page the nav sits over the hero, in it rather than above it:
   no ground of its own, white type, and the hero makes room for it */
.nav-space {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  z-index: 5;
  background: transparent;
  border-bottom: 0;
}
.nav-space .brand,
.nav-space .brand-name,
.nav-space .nav-links a { color: #fff; }
.nav-space .nav-links a:hover { opacity: 0.7; }
/* Three columns rather than space-between: the brand is much wider than the
   Download button, so pushing the links to the middle of what's left put them
   right of the page centre. Equal 1fr gutters centre them on the container
   instead, whatever the brand and button happen to measure. */
.nav-inner {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 24px;
  height: 70px;
}
/* Placed explicitly rather than by source order, because the inner pages carry
   only a brand and a Back button — without this the button would land in the
   centre column meant for the links. */
.nav-inner > .brand { grid-column: 1; justify-self: start; }
.nav-inner > .nav-links { grid-column: 2; }
.nav-inner > :last-child { grid-column: 3; justify-self: end; }
.brand { display: flex; align-items: center; gap: 12px; color: var(--black); }
.brand-logo { display: block; height: 32px; width: auto; }
.brand-name { font-size: 0.82rem; font-weight: 700; letter-spacing: 0.14em; text-transform: uppercase; }
.nav-links { display: flex; gap: 28px; }
.nav-links a {
  font-size: 0.9rem;
  font-weight: 500;
  color: var(--black);
  transition: opacity var(--dur) var(--ease);
}
.nav-links a:hover { opacity: 0.6; }


/* ============ Left section rail ============ */
.rail {
  display: none;
  position: fixed;
  top: 132px;
  left: 34px;
  width: 172px;
  flex-direction: column;
  z-index: 20;
  opacity: 0;
  pointer-events: none;
  /* not just invisible — out of the tab order too, or the first Tab on the page
     walks eight section links no one can see */
  visibility: hidden;
  transition: opacity 250ms var(--ease), visibility 250ms var(--ease);
}
.rail.show { opacity: 1; pointer-events: auto; visibility: visible; }
.rail a {
  font-size: 0.73rem;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-muted);
  padding: 11px 0 9px;
  border-bottom: 1px solid var(--divider-muted);
  transition: color var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
.rail a:hover { color: var(--text-muted); }
.rail a.active {
  color: var(--black);
  font-weight: 700;
  border-bottom-color: var(--black);
}

/* ============ Hero ============ */
/* ============ Hero ground: space ============
   The reel's opening frame — a blue field on the left, ink on the right — run
   out to the whole hero: the same left-to-right blue to black, two layers of
   stars, a soft nebula, and a planet limb rising behind the reel with a lit
   rim. All CSS and inline SVG; no image assets. Text goes to paper on it. */
.hero {
  position: relative;
  padding: 162px 0 220px;              /* 70px of that is under the nav; the tail is the fade to the page */
  text-align: center;
  color: #fff;
  background:
    radial-gradient(46% 42% at 50% 24%, rgba(4, 6, 14, 0.5) 0%, transparent 70%),   /* dark pool behind the copy */
    radial-gradient(60% 50% at 22% 40%, rgba(27, 67, 232, 0.55) 0%, transparent 70%),
    radial-gradient(40% 40% at 70% 20%, rgba(118, 38, 254, 0.28) 0%, transparent 70%),
    linear-gradient(100deg, #1b43e8 0%, #1636b6 26%, #0e1a5c 47%, #090c1e 70%, #050609 100%);
  overflow: hidden;
  isolation: isolate;
}
/* stars: three tiles — a sparse layer of bright ones with a halo and a
   four-point glint, then two fields at different densities, the near ones
   larger. Different tile sizes so the repeat never lines up. */
.hero::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background-image: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20width='1500'%20height='1000'%20viewBox='0%200%201500%201000'%3E%3Ccircle%20cx='693'%20cy='184'%20r='9.7'%20fill='white'%20fill-opacity='0.10'/%3E%3Ccircle%20cx='693'%20cy='184'%20r='2.3'%20fill='white'%20fill-opacity='0.99'/%3E%3Cpath%20d='M693%20175.7V192.3M684.7%20184H701.3'%20stroke='white'%20stroke-opacity='0.45'%20stroke-width='0.7'/%3E%3Ccircle%20cx='838'%20cy='696'%20r='9.7'%20fill='white'%20fill-opacity='0.10'/%3E%3Ccircle%20cx='838'%20cy='696'%20r='2.3'%20fill='white'%20fill-opacity='0.91'/%3E%3Cpath%20d='M838%20687.7V704.3M829.7%20696H846.3'%20stroke='white'%20stroke-opacity='0.45'%20stroke-width='0.7'/%3E%3Ccircle%20cx='128'%20cy='104'%20r='10.9'%20fill='white'%20fill-opacity='0.10'/%3E%3Ccircle%20cx='128'%20cy='104'%20r='2.6'%20fill='white'%20fill-opacity='0.86'/%3E%3Cpath%20d='M128%2094.6V113.4M118.6%20104H137.4'%20stroke='white'%20stroke-opacity='0.45'%20stroke-width='0.7'/%3E%3Ccircle%20cx='1127'%20cy='126'%20r='10.5'%20fill='white'%20fill-opacity='0.10'/%3E%3Ccircle%20cx='1127'%20cy='126'%20r='2.5'%20fill='white'%20fill-opacity='0.89'/%3E%3Cpath%20d='M1127%20117.0V135.0M1118.0%20126H1136.0'%20stroke='white'%20stroke-opacity='0.45'%20stroke-width='0.7'/%3E%3Ccircle%20cx='148'%20cy='961'%20r='8.4'%20fill='white'%20fill-opacity='0.10'/%3E%3Ccircle%20cx='148'%20cy='961'%20r='2.0'%20fill='white'%20fill-opacity='0.87'/%3E%3Cpath%20d='M148%20953.8V968.2M140.8%20961H155.2'%20stroke='white'%20stroke-opacity='0.45'%20stroke-width='0.7'/%3E%3Ccircle%20cx='215'%20cy='594'%20r='8.8'%20fill='white'%20fill-opacity='0.10'/%3E%3Ccircle%20cx='215'%20cy='594'%20r='2.1'%20fill='white'%20fill-opacity='0.97'/%3E%3Cpath%20d='M215%20586.4V601.6M207.4%20594H222.6'%20stroke='white'%20stroke-opacity='0.45'%20stroke-width='0.7'/%3E%3Ccircle%20cx='487'%20cy='675'%20r='8.4'%20fill='white'%20fill-opacity='0.10'/%3E%3Ccircle%20cx='487'%20cy='675'%20r='2.0'%20fill='white'%20fill-opacity='0.94'/%3E%3Cpath%20d='M487%20667.8V682.2M479.8%20675H494.2'%20stroke='white'%20stroke-opacity='0.45'%20stroke-width='0.7'/%3E%3C/svg%3E"), url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20width='1100'%20height='800'%20viewBox='0%200%201100%20800'%3E%3Ccircle%20cx='760'%20cy='53'%20r='1.5'%20fill='white'%20fill-opacity='0.62'/%3E%3Ccircle%20cx='1053'%20cy='739'%20r='1.2'%20fill='white'%20fill-opacity='0.66'/%3E%3Ccircle%20cx='140'%20cy='347'%20r='1.7'%20fill='white'%20fill-opacity='0.94'/%3E%3Ccircle%20cx='524'%20cy='254'%20r='1.2'%20fill='white'%20fill-opacity='0.75'/%3E%3Ccircle%20cx='1018'%20cy='104'%20r='1.7'%20fill='white'%20fill-opacity='0.36'/%3E%3Ccircle%20cx='214'%20cy='182'%20r='1.6'%20fill='white'%20fill-opacity='0.56'/%3E%3Ccircle%20cx='391'%20cy='496'%20r='1.1'%20fill='white'%20fill-opacity='0.83'/%3E%3Ccircle%20cx='135'%20cy='408'%20r='1.2'%20fill='white'%20fill-opacity='0.48'/%3E%3Ccircle%20cx='583'%20cy='349'%20r='1.3'%20fill='white'%20fill-opacity='0.62'/%3E%3Ccircle%20cx='582'%20cy='128'%20r='1.2'%20fill='white'%20fill-opacity='0.76'/%3E%3Ccircle%20cx='702'%20cy='424'%20r='1.8'%20fill='white'%20fill-opacity='0.75'/%3E%3Ccircle%20cx='942'%20cy='186'%20r='1.7'%20fill='white'%20fill-opacity='0.88'/%3E%3Ccircle%20cx='993'%20cy='253'%20r='1.3'%20fill='white'%20fill-opacity='0.95'/%3E%3Ccircle%20cx='240'%20cy='799'%20r='1.8'%20fill='white'%20fill-opacity='0.44'/%3E%3Ccircle%20cx='263'%20cy='581'%20r='1.2'%20fill='white'%20fill-opacity='0.41'/%3E%3Ccircle%20cx='915'%20cy='337'%20r='1.7'%20fill='white'%20fill-opacity='0.43'/%3E%3Ccircle%20cx='443'%20cy='548'%20r='1.0'%20fill='white'%20fill-opacity='0.48'/%3E%3Ccircle%20cx='751'%20cy='729'%20r='1.9'%20fill='white'%20fill-opacity='0.43'/%3E%3Ccircle%20cx='556'%20cy='607'%20r='1.5'%20fill='white'%20fill-opacity='0.80'/%3E%3Ccircle%20cx='208'%20cy='56'%20r='1.1'%20fill='white'%20fill-opacity='0.37'/%3E%3Ccircle%20cx='607'%20cy='412'%20r='1.5'%20fill='white'%20fill-opacity='0.45'/%3E%3Ccircle%20cx='203'%20cy='163'%20r='1.8'%20fill='white'%20fill-opacity='0.99'/%3E%3Ccircle%20cx='1020'%20cy='76'%20r='1.1'%20fill='white'%20fill-opacity='0.97'/%3E%3Ccircle%20cx='508'%20cy='612'%20r='1.3'%20fill='white'%20fill-opacity='0.65'/%3E%3Ccircle%20cx='567'%20cy='344'%20r='1.5'%20fill='white'%20fill-opacity='0.36'/%3E%3Ccircle%20cx='771'%20cy='675'%20r='1.2'%20fill='white'%20fill-opacity='0.65'/%3E%3Ccircle%20cx='813'%20cy='324'%20r='1.2'%20fill='white'%20fill-opacity='0.46'/%3E%3Ccircle%20cx='564'%20cy='12'%20r='1.8'%20fill='white'%20fill-opacity='0.87'/%3E%3C/svg%3E"), url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20width='900'%20height='700'%20viewBox='0%200%20900%20700'%3E%3Ccircle%20cx='407'%20cy='392'%20r='1.1'%20fill='white'%20fill-opacity='0.65'/%3E%3Ccircle%20cx='457'%20cy='411'%20r='0.6'%20fill='white'%20fill-opacity='0.68'/%3E%3Ccircle%20cx='567'%20cy='555'%20r='0.6'%20fill='white'%20fill-opacity='0.55'/%3E%3Ccircle%20cx='82'%20cy='567'%20r='0.9'%20fill='white'%20fill-opacity='0.38'/%3E%3Ccircle%20cx='884'%20cy='675'%20r='0.9'%20fill='white'%20fill-opacity='0.75'/%3E%3Ccircle%20cx='142'%20cy='11'%20r='0.8'%20fill='white'%20fill-opacity='0.39'/%3E%3Ccircle%20cx='171'%20cy='169'%20r='0.5'%20fill='white'%20fill-opacity='0.65'/%3E%3Ccircle%20cx='396'%20cy='590'%20r='0.8'%20fill='white'%20fill-opacity='0.77'/%3E%3Ccircle%20cx='450'%20cy='464'%20r='0.8'%20fill='white'%20fill-opacity='0.53'/%3E%3Ccircle%20cx='898'%20cy='697'%20r='1.0'%20fill='white'%20fill-opacity='0.81'/%3E%3Ccircle%20cx='284'%20cy='161'%20r='0.7'%20fill='white'%20fill-opacity='0.40'/%3E%3Ccircle%20cx='690'%20cy='280'%20r='1.0'%20fill='white'%20fill-opacity='0.60'/%3E%3Ccircle%20cx='862'%20cy='593'%20r='0.5'%20fill='white'%20fill-opacity='0.49'/%3E%3Ccircle%20cx='819'%20cy='329'%20r='1.1'%20fill='white'%20fill-opacity='0.61'/%3E%3Ccircle%20cx='66'%20cy='441'%20r='1.0'%20fill='white'%20fill-opacity='0.53'/%3E%3Ccircle%20cx='78'%20cy='233'%20r='1.1'%20fill='white'%20fill-opacity='0.84'/%3E%3Ccircle%20cx='106'%20cy='172'%20r='0.6'%20fill='white'%20fill-opacity='0.39'/%3E%3Ccircle%20cx='717'%20cy='124'%20r='0.8'%20fill='white'%20fill-opacity='0.64'/%3E%3Ccircle%20cx='172'%20cy='512'%20r='0.6'%20fill='white'%20fill-opacity='0.77'/%3E%3Ccircle%20cx='105'%20cy='295'%20r='0.6'%20fill='white'%20fill-opacity='0.53'/%3E%3Ccircle%20cx='874'%20cy='562'%20r='0.7'%20fill='white'%20fill-opacity='0.93'/%3E%3Ccircle%20cx='190'%20cy='276'%20r='1.0'%20fill='white'%20fill-opacity='0.77'/%3E%3Ccircle%20cx='90'%20cy='693'%20r='0.6'%20fill='white'%20fill-opacity='0.52'/%3E%3Ccircle%20cx='695'%20cy='230'%20r='0.7'%20fill='white'%20fill-opacity='0.40'/%3E%3Ccircle%20cx='81'%20cy='408'%20r='0.6'%20fill='white'%20fill-opacity='0.74'/%3E%3Ccircle%20cx='335'%20cy='317'%20r='1.1'%20fill='white'%20fill-opacity='0.66'/%3E%3Ccircle%20cx='517'%20cy='607'%20r='0.6'%20fill='white'%20fill-opacity='0.45'/%3E%3Ccircle%20cx='818'%20cy='572'%20r='0.6'%20fill='white'%20fill-opacity='0.47'/%3E%3Ccircle%20cx='665'%20cy='658'%20r='0.6'%20fill='white'%20fill-opacity='0.97'/%3E%3Ccircle%20cx='794'%20cy='422'%20r='0.8'%20fill='white'%20fill-opacity='0.42'/%3E%3Ccircle%20cx='35'%20cy='674'%20r='0.6'%20fill='white'%20fill-opacity='0.81'/%3E%3Ccircle%20cx='231'%20cy='577'%20r='0.9'%20fill='white'%20fill-opacity='0.54'/%3E%3Ccircle%20cx='158'%20cy='504'%20r='0.5'%20fill='white'%20fill-opacity='0.50'/%3E%3Ccircle%20cx='503'%20cy='597'%20r='0.9'%20fill='white'%20fill-opacity='0.53'/%3E%3Ccircle%20cx='826'%20cy='143'%20r='0.5'%20fill='white'%20fill-opacity='0.52'/%3E%3Ccircle%20cx='401'%20cy='42'%20r='0.6'%20fill='white'%20fill-opacity='0.59'/%3E%3Ccircle%20cx='515'%20cy='92'%20r='0.7'%20fill='white'%20fill-opacity='0.93'/%3E%3Ccircle%20cx='882'%20cy='460'%20r='0.9'%20fill='white'%20fill-opacity='0.73'/%3E%3Ccircle%20cx='126'%20cy='25'%20r='0.5'%20fill='white'%20fill-opacity='0.94'/%3E%3Ccircle%20cx='631'%20cy='674'%20r='0.5'%20fill='white'%20fill-opacity='0.76'/%3E%3Ccircle%20cx='434'%20cy='511'%20r='0.7'%20fill='white'%20fill-opacity='1.00'/%3E%3Ccircle%20cx='68'%20cy='382'%20r='0.9'%20fill='white'%20fill-opacity='0.94'/%3E%3Ccircle%20cx='663'%20cy='493'%20r='1.0'%20fill='white'%20fill-opacity='0.94'/%3E%3Ccircle%20cx='317'%20cy='480'%20r='1.0'%20fill='white'%20fill-opacity='0.92'/%3E%3Ccircle%20cx='375'%20cy='553'%20r='1.0'%20fill='white'%20fill-opacity='0.72'/%3E%3Ccircle%20cx='562'%20cy='268'%20r='0.8'%20fill='white'%20fill-opacity='0.75'/%3E%3Ccircle%20cx='72'%20cy='448'%20r='1.1'%20fill='white'%20fill-opacity='0.92'/%3E%3Ccircle%20cx='655'%20cy='272'%20r='0.9'%20fill='white'%20fill-opacity='0.73'/%3E%3Ccircle%20cx='396'%20cy='587'%20r='0.6'%20fill='white'%20fill-opacity='0.84'/%3E%3Ccircle%20cx='27'%20cy='421'%20r='0.8'%20fill='white'%20fill-opacity='0.50'/%3E%3Ccircle%20cx='629'%20cy='348'%20r='0.9'%20fill='white'%20fill-opacity='0.95'/%3E%3Ccircle%20cx='230'%20cy='8'%20r='0.7'%20fill='white'%20fill-opacity='0.79'/%3E%3Ccircle%20cx='182'%20cy='119'%20r='1.0'%20fill='white'%20fill-opacity='0.78'/%3E%3Ccircle%20cx='398'%20cy='624'%20r='0.7'%20fill='white'%20fill-opacity='0.78'/%3E%3Ccircle%20cx='179'%20cy='302'%20r='1.0'%20fill='white'%20fill-opacity='0.94'/%3E%3Ccircle%20cx='792'%20cy='269'%20r='0.8'%20fill='white'%20fill-opacity='0.56'/%3E%3Ccircle%20cx='123'%20cy='348'%20r='1.0'%20fill='white'%20fill-opacity='0.90'/%3E%3Ccircle%20cx='640'%20cy='665'%20r='0.7'%20fill='white'%20fill-opacity='0.46'/%3E%3Ccircle%20cx='406'%20cy='193'%20r='0.6'%20fill='white'%20fill-opacity='0.62'/%3E%3Ccircle%20cx='563'%20cy='346'%20r='0.7'%20fill='white'%20fill-opacity='0.90'/%3E%3Ccircle%20cx='884'%20cy='317'%20r='0.5'%20fill='white'%20fill-opacity='0.37'/%3E%3Ccircle%20cx='786'%20cy='29'%20r='0.9'%20fill='white'%20fill-opacity='0.72'/%3E%3Ccircle%20cx='278'%20cy='554'%20r='0.5'%20fill='white'%20fill-opacity='0.44'/%3E%3Ccircle%20cx='409'%20cy='17'%20r='1.0'%20fill='white'%20fill-opacity='0.50'/%3E%3Ccircle%20cx='127'%20cy='33'%20r='0.9'%20fill='white'%20fill-opacity='0.64'/%3E%3Ccircle%20cx='567'%20cy='459'%20r='1.0'%20fill='white'%20fill-opacity='0.97'/%3E%3Ccircle%20cx='616'%20cy='140'%20r='0.8'%20fill='white'%20fill-opacity='0.47'/%3E%3Ccircle%20cx='10'%20cy='331'%20r='0.9'%20fill='white'%20fill-opacity='0.47'/%3E%3Ccircle%20cx='245'%20cy='242'%20r='0.9'%20fill='white'%20fill-opacity='0.69'/%3E%3Ccircle%20cx='553'%20cy='529'%20r='0.7'%20fill='white'%20fill-opacity='0.86'/%3E%3Ccircle%20cx='816'%20cy='61'%20r='1.1'%20fill='white'%20fill-opacity='0.82'/%3E%3Ccircle%20cx='117'%20cy='317'%20r='0.9'%20fill='white'%20fill-opacity='0.94'/%3E%3Ccircle%20cx='339'%20cy='398'%20r='1.0'%20fill='white'%20fill-opacity='0.87'/%3E%3Ccircle%20cx='850'%20cy='325'%20r='0.9'%20fill='white'%20fill-opacity='0.48'/%3E%3Ccircle%20cx='650'%20cy='573'%20r='0.9'%20fill='white'%20fill-opacity='0.82'/%3E%3Ccircle%20cx='192'%20cy='630'%20r='1.1'%20fill='white'%20fill-opacity='0.99'/%3E%3Ccircle%20cx='483'%20cy='554'%20r='0.7'%20fill='white'%20fill-opacity='0.94'/%3E%3Ccircle%20cx='770'%20cy='244'%20r='0.5'%20fill='white'%20fill-opacity='0.64'/%3E%3Ccircle%20cx='495'%20cy='538'%20r='0.8'%20fill='white'%20fill-opacity='0.37'/%3E%3Ccircle%20cx='728'%20cy='45'%20r='1.0'%20fill='white'%20fill-opacity='0.46'/%3E%3Ccircle%20cx='302'%20cy='552'%20r='0.6'%20fill='white'%20fill-opacity='0.45'/%3E%3Ccircle%20cx='465'%20cy='506'%20r='1.0'%20fill='white'%20fill-opacity='0.80'/%3E%3Ccircle%20cx='851'%20cy='345'%20r='1.1'%20fill='white'%20fill-opacity='0.41'/%3E%3Ccircle%20cx='199'%20cy='369'%20r='0.7'%20fill='white'%20fill-opacity='0.82'/%3E%3Ccircle%20cx='575'%20cy='366'%20r='1.0'%20fill='white'%20fill-opacity='0.71'/%3E%3Ccircle%20cx='281'%20cy='267'%20r='1.0'%20fill='white'%20fill-opacity='0.94'/%3E%3Ccircle%20cx='187'%20cy='596'%20r='1.1'%20fill='white'%20fill-opacity='0.69'/%3E%3Ccircle%20cx='516'%20cy='141'%20r='0.8'%20fill='white'%20fill-opacity='0.68'/%3E%3Ccircle%20cx='545'%20cy='19'%20r='1.1'%20fill='white'%20fill-opacity='0.69'/%3E%3Ccircle%20cx='361'%20cy='561'%20r='0.8'%20fill='white'%20fill-opacity='0.67'/%3E%3C/svg%3E");
  background-size: 1500px 1000px, 1100px 800px, 900px 700px;
  background-position: 380px 60px, 0 0, 0 0;
  opacity: 0.85;
}
/* a small ringed planet far off in the dark, upper right, to break the field
   up: a shaded disc, the ring's far half behind it and its near half in front */
.hero-far {
  position: absolute;
  z-index: 0;
  top: 118px;
  right: 7%;
  width: 54px;
  height: 54px;
  border-radius: 50%;
  background: radial-gradient(circle at 32% 30%, #8d9ad0 0%, #3d4a8a 34%, #171d3f 62%, #080a16 100%);
  box-shadow: 0 0 22px 2px rgba(120, 140, 255, 0.18);
  pointer-events: none;
}
.hero-far::before,
.hero-far::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  width: 118px;
  height: 22px;
  margin: -11px 0 0 -59px;
  border-radius: 50%;
  border: 2px solid rgba(190, 200, 235, 0.55);
  border-top-color: rgba(190, 200, 235, 0.3);
  transform: rotate(-18deg);
}
.hero-far::before { z-index: -1; }
.hero-far::after  { clip-path: inset(50% 0 0 0); }
/* the seam with the page: the nav sits inside the space at the top (see
   .nav-space), and at the bottom the last stretch fades to the page ground,
   so the way out of the dark isn't a hard step */
.hero-fade {
  position: absolute;
  z-index: 2;
  left: 0;
  right: 0;
  bottom: 0;
  height: 260px;
  background: linear-gradient(to bottom, rgba(246, 247, 249, 0) 0%, rgba(246, 247, 249, 0.35) 45%, rgba(246, 247, 249, 0.8) 75%, var(--lg5) 100%);
  pointer-events: none;
}
/* the same grain the mesh panel and the reel frame carry */
.hero::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  opacity: 0.16;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}
/* the planet: a huge dark disc whose top edge sits just above the reel, with a
   thin lit rim and a blue glow — the reel and the proof row sit on its face.
   Drawn as the reel figure's own ::after so it tracks the reel wherever the
   copy above it puts it. */
.hero-reel::after {
  content: "";
  position: absolute;
  z-index: -1;
  left: 50%;
  top: -34px;
  width: 260vw;
  height: 260vw;
  transform: translateX(-50%);
  border-radius: 50%;
  background: radial-gradient(closest-side at 50% 0%, #0f1a3a 0%, #0b0d10 45%, #0b0d10 100%);
  box-shadow:
    0 -1px 0 1px rgba(150, 175, 255, 0.55),
    0 -18px 60px 8px rgba(27, 67, 232, 0.45),
    0 -60px 160px 30px rgba(27, 67, 232, 0.25);
  pointer-events: none;
}
.hero > .container { position: relative; z-index: 1; }
.hero h1 { color: #fff; text-shadow: 0 2px 6px rgba(0, 0, 0, 0.35), 0 12px 40px rgba(0, 0, 0, 0.45); }
.hero-sub { color: rgba(255, 255, 255, 0.92); text-shadow: 0 1px 3px rgba(0, 0, 0, 0.4), 0 6px 24px rgba(0, 0, 0, 0.4); }
.hero .cta-micro { color: rgba(255, 255, 255, 0.72); text-shadow: 0 1px 3px rgba(0, 0, 0, 0.4); }
.hero .btn { background: #fff; color: var(--black); border-color: #fff; }
.hero .btn:hover, .hero .btn:active { background: #e6e9ee; color: var(--black); border-color: #e6e9ee; }
.hero .btn-outline { color: #fff; border-color: rgba(255, 255, 255, 0.55); background: transparent; }
.hero .btn-outline:hover { background: #fff; color: var(--black); border-color: #fff; }
/* the two-class selectors so these beat the reading-width rules below */
/* The hero runs wider than the rest of the page: the reel wants the room, and
   it's the one place the page is a picture rather than columns of copy. The
   headline and the stats stay at reading width inside it. */
.hero-inner { max-width: 1360px; }
.hero h1 { max-width: 1080px; margin-left: auto; margin-right: auto; }
.hero h1 { margin-bottom: 24px; }
/* The rating line over the headline: five stars and a short label. The markup is
   OUT of index.html — it read "5.0 from beta editors", a score nobody had given
   us. These rules stay so a real, citable number can be dropped straight back in;
   the .js .hero-rating entrance below is part of the same parked set. */
.hero-sub { font-size: 1.12rem; max-width: 720px; margin: 0 auto 36px; }
.hero-ctas { display: flex; justify-content: center; flex-wrap: wrap; gap: 12px; }
.cta-micro { font-size: 0.84rem; margin-top: 16px; }
/* on the waitlist page this sits on the light ground, not the dark hero */
.cta-micro-light { color: var(--text-muted); }

/* ============ Hero reel ============
   A flat-vector piece in two parts: someone at a desk scrubbing through a
   take, and then — flying into their monitor — the cut being made. It's the
   product, so it stays literal: one timeline strip, filler dim, keeps red.

   Deliberately NOT .hero-film — that panel grades and grains its contents for
   photographic stills, and every one of those filters fights flat vector.
   This one only borrows the panel chrome.

   Timing is a beat grid, not round numbers: 0.4234s a beat (143bpm), and
   every cut lands on one. The reel is 16 beats, played once — the reference
   loops it twice with a recolour, but with a first and third act around it
   a second pass just read as a rerun. The recolour happens at the third act
   instead: blue for the cut, violet for the loop.

     beat  0.00  ( 0.00%)  the raw take, scrubbed
     beat  2.80  (17.42%)  hard cut -> tighter, and the filler is cut out on
                           beats 3, 3.75, 4.5, 5.25 — the strip snaps shut each time
     beat  6.30  (39.11%)  hard cut -> black
     beat  8.10  (50.48%)  punch in -> the finished cut, captions on 12/14/15
     beat 16.00  (100.0%)  loop

   Before that, once, 12 beats at the desk: seven shots a beat and a half each — the
   wide, the hand on the mouse, the screen, the hand again, the eye (held
   a beat longer: he's focused), the screen again, the wide — cut against each other so the mouse going right
   and the playhead going right read as one action. Then a one-beat camera
   push into the monitor, which is showing shot one at quarter scale, so the
   push lands on shot one at 1:1. Every reel animation is delayed by
   --reel-pro to make room.

   After the pass, once, 22 beats: the shoot — where the footage came from.
   Him in the jungle with the camera up (2 beats), down a slope with a GoPro
   on his head (1.5), at a ring light where the lid comes off a box and his
   hands go up (3); then a list, rapid fire, a pairing a line — who, and how
   it's cut — the camera in close, swooping down to each line as it lands;
   the first three sit a beat each so they can be read, then it quickens
   geometrically to a flicker, and eases back at the end onto a card: or
   whatever you're into (14); then the three
   shots snap down into three clips on a strip (1.5) and it cuts to the drag,
   where the cursor takes the first one to the phone. Over the whole piece,
   a little geometric flare on the cuts — a ring, a triangle, a plus — at
   the edges.

   After the drag, once, 27 beats: the loop. Your cut on top, its
   cut below, the disagreements marked between them; each session they snap
   into agreement and it cuts to the next — fewer each time, each session
   shorter than the last (4, 3, 2, 1 beats, then twelve as lit/agreed pairs
   at half a beat a frame and then a quarter), then a beat of black, then the
   punch onto one strip, held two beats, then a hard cut to the one sentence
   the reel says, a word every half beat — and the last word comes in
   sideways, tries to right itself, fails, and lands — and as it does the
   frame goes gold, blasting out from the point a spark would have been, the
   black rippling off ahead of it, and the mark pops in under the line, last
   of all. Then it holds. Whole piece: 12 + 16 + 22 + 12 + 27.25 beats, 37.8s.

   Everything with a percentage in it that isn't in this comment is generated
   by tools/reel/gen.py — regenerate rather than edit between the @@ marks.

   Entrances are a 2-frame (83ms = 1.23%) scale-and-blur slam, never a fade.
   That is the whole grammar: snap in, drift slowly, cut hard. */
@property --reel-accent {
  syntax: "<color>";
  inherits: true;
  initial-value: #1b43e8;
}
/* the frame's two colours, animated in step with the reel (below) */
@property --frame-a { syntax: "<color>"; inherits: false; initial-value: #1b43e8; }
@property --frame-b { syntax: "<color>"; inherits: false; initial-value: #2a1c8e; }

.hero-reel {
  --frame: 8px;
  position: relative;
  max-width: 1312px;                 /* the wide hero container, less its padding */
  margin: 56px auto 0;
  padding: var(--frame);
  border-radius: calc(var(--radius-block) + var(--frame));
  /* the frame: ink to the reel's accent and back, drifting the way the mesh
     panel's ground does, with the same grain over it. The accent follows the
     reel like light spilling off a screen — blue through the desk and the
     first pass, violet once the reel swaps, gold when the end blasts out —
     on the reel's own clock (reelAmbient runs the reel's full length and is
     gated on .playing like everything inside it). */
  --frame-a: #1b43e8;
  --frame-b: #2a1c8e;
  background: linear-gradient(120deg, #0b0d10 0%, var(--frame-a) 42%, var(--frame-b) 62%, #0b0d10 100%);
  background-size: 220% 220%;
  animation: reelFrame 18s ease-in-out infinite alternate,
             reelAmbient 37.7884s linear 1 forwards;
  isolation: isolate;
}
.js .hero-reel:not(.playing) { animation-play-state: running, paused, running; }
.hero-reel::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  opacity: 0.22;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}
.hero-reel .reel {
  position: relative;
  z-index: 1;
  display: block;
  width: 100%;
  aspect-ratio: 8 / 3;
  border-radius: var(--radius-block);
  overflow: hidden;
  background: var(--black);
}
@keyframes reelFrame {
  from { background-position: 0% 50%; }
  to   { background-position: 100% 50%; }
}
/* percentages of the whole reel: 12 beats of desk, 16 of the pass, 22 of the
   shoot, 12 of the drag, 27.25 of the loop — 37.7884s (gen.py prints these).
   The accent swap lands at 69.47%; the gold blast at 97.59%. */
@keyframes reelAmbient {
  0%, 68.9%     { --frame-a: #1b43e8; --frame-b: #2a1c8e; }
  70.1%, 97.2%  { --frame-a: #7626fe; --frame-b: #3a1a9a; }
  97.7%, 100%   { --frame-a: #ffc53d; --frame-b: #e08a1a; }
}

.reel {
  --reel-loop: 6.775s;
  --reel-beat: 0.4234s;
  --reel-pro: calc(var(--reel-beat) * 12);   /* the desk, before the reel */
  --reel-shoot: calc(var(--reel-beat) * 22); /* the shoot, after the pass */
  --reel-drag: calc(var(--reel-beat) * 12);  /* the clip to the reel, after the shoot */
  /* the desk, the pass and the drag are the cool blue; the loop swaps it for
     violet. Ink, paper and the logo red hold across both, so the recolour
     reads as a change of mood rather than a change of subject. */
  --reel-accent: #1b43e8;
  animation: reel-accent-swap calc(var(--reel-loop) + var(--reel-shoot) + var(--reel-drag)) steps(1, end) var(--reel-pro) 1 forwards;
}

.reel .c-ground  { fill: var(--black); }
.reel .c-dark    { fill: var(--black); }
.reel .c-paper   { fill: #fff; }
.reel .c-red     { fill: var(--brand); }
.reel .c-accent  { fill: var(--reel-accent); }
.reel .c-paper85 { fill: #fff; fill-opacity: 0.85; }
.reel .c-paper45 { fill: #fff; fill-opacity: 0.45; }
.reel .c-paper22 { fill: #fff; fill-opacity: 0.22; }
.reel .c-paper05 { fill: #fff; fill-opacity: 0.05; }
.reel text {
  font-family: var(--font);
  letter-spacing: 0.02em;
}

/* --- scene visibility: hard cuts, so steps(1) and never a fade --- */
.reel .s { opacity: 0; }
.reel .s-a1 { opacity: 1; }
.reel .s-a1,
.reel .s-a2,
.reel .s-b { animation-duration: var(--reel-loop); animation-timing-function: steps(1, end);
             animation-delay: var(--reel-pro);
             animation-iteration-count: 1; animation-fill-mode: both; }
.reel .s-a1 { animation-name: reel-vis-a1; }
.reel .s-a2 { animation-name: reel-vis-a2; }
.reel .s-b  { animation-name: reel-vis-b; }

/* the pass's ground: big spiked shards behind the strip, faint, each turning
   a few degrees over the sixteen beats — so the timeline isn't on flat black.
   Under the shots; the drag's own ground covers them after. */
.reel .s-bg { animation-name: reel-vis-bg; }
.reel .s-bg,
.reel .bg-shard { animation-duration: var(--reel-loop); animation-delay: var(--reel-pro);
                  animation-iteration-count: 1; animation-fill-mode: both; }
.reel .bg-shard { transform-box: fill-box; transform-origin: center; animation-timing-function: linear; }
.reel .bg-shard-0, .reel .bg-shard-3, .reel .bg-shard-6 { animation-name: reel-shard-cw; }
.reel .bg-shard-1, .reel .bg-shard-4 { animation-name: reel-shard-ccw; }
.reel .bg-shard-2, .reel .bg-shard-5 { animation-name: reel-shard-cw-slow; }
@keyframes reel-vis-bg { 0% { opacity: 1; } 100% { opacity: 1; } }
@keyframes reel-shard-cw      { from { transform: rotate(-4deg) scale(1); }    to { transform: rotate(5deg) scale(1.06); } }
@keyframes reel-shard-ccw     { from { transform: rotate(4deg) scale(1.04); }  to { transform: rotate(-5deg) scale(1); } }
@keyframes reel-shard-cw-slow { from { transform: rotate(-2deg) scale(1.03); } to { transform: rotate(2deg) scale(1); } }

@keyframes reel-vis-a1 { 0% { opacity: 1; } 17.42% { opacity: 0; } 100% { opacity: 0; } }
@keyframes reel-vis-a2 { 0% { opacity: 0; } 17.42% { opacity: 1; } 39.11% { opacity: 0; } 100% { opacity: 0; } }
@keyframes reel-vis-b  { 0% { opacity: 0; } 50.48% { opacity: 1; } 100% { opacity: 1; } }

/* --- entrances: scale + blur, settled inside two frames --- */
.reel .p {
  transform-box: view-box;
  transform-origin: 50% 50%;
  animation-duration: var(--reel-loop);
  animation-timing-function: linear;
  animation-delay: var(--reel-pro);
  animation-iteration-count: 1;
  animation-fill-mode: both;
}
.reel .p-a1 { animation-name: reel-punch-a1; }
.reel .p-a2 { animation-name: reel-punch-a2; }
.reel .p-b  { animation-name: reel-punch-b; }

@keyframes reel-punch-a1 {
  0%     { transform: scale(3.2); filter: blur(40px); animation-timing-function: var(--ease-snap); }
  1.23%  { transform: scale(1); filter: blur(0); }
  100%   { transform: scale(1); filter: blur(0); }
}
/* the tighter shot is a straight cut — it only needs the blur to settle */
@keyframes reel-punch-a2 {
  0%      { transform: scale(1.1); filter: blur(26px); }
  17.42%  { transform: scale(1.1); filter: blur(26px); animation-timing-function: var(--ease-snap); }
  18.65%  { transform: scale(1); filter: blur(0); }
  100%    { transform: scale(1); filter: blur(0); }
}
/* the big one: out of black, from way oversized, then a slow settle to rest */
@keyframes reel-punch-b {
  0%      { transform: scale(3.6); filter: blur(56px); }
  50.48%  { transform: scale(3.6); filter: blur(56px); animation-timing-function: var(--ease-snap); }
  51.71%  { transform: scale(1.06); filter: blur(0); animation-timing-function: linear; }
  100%    { transform: scale(1); filter: blur(0); }
}

/* --- drift and per-element timing inside the shots --- */
.reel [class^="d-"],
.reel [class^="cut-"] {
  animation-duration: var(--reel-loop);
  animation-timing-function: steps(1, end);
  animation-delay: var(--reel-pro);
  animation-iteration-count: 1;
  animation-fill-mode: both;
}
/* shot one: the strip and ruler creep under a fixed playhead — scrubbing */
.reel .d-strip,
.reel .d-ruler { animation-name: reel-drift-strip; animation-timing-function: linear; }
@keyframes reel-drift-strip { 0% { transform: translateX(0); } 17.42%, 100% { transform: translateX(-90px); } }

/* shot two: the filler is cut and the strip closes up, on the beat */
/* @@generated:cuts */
@keyframes reel-cut-s1 { 0% { transform: translateX(0); opacity: 1; } 18.75% { transform: translateX(-0px); opacity: 0; } 100% { transform: translateX(-0px); opacity: 0; } }
.reel .cut-s1 { animation-name: reel-cut-s1; }
@keyframes reel-cut-s2 { 0% { transform: translateX(0); opacity: 1; } 18.75% { transform: translateX(-260px); opacity: 1; } 100% { transform: translateX(-260px); opacity: 1; } }
.reel .cut-s2 { animation-name: reel-cut-s2; }
@keyframes reel-cut-s3 { 0% { transform: translateX(0); opacity: 1; } 18.75% { transform: translateX(-260px); opacity: 1; } 23.44% { transform: translateX(-260px); opacity: 0; } 100% { transform: translateX(-260px); opacity: 0; } }
.reel .cut-s3 { animation-name: reel-cut-s3; }
@keyframes reel-cut-s4 { 0% { transform: translateX(0); opacity: 1; } 18.75% { transform: translateX(-260px); opacity: 1; } 23.44% { transform: translateX(-440px); opacity: 1; } 100% { transform: translateX(-440px); opacity: 1; } }
.reel .cut-s4 { animation-name: reel-cut-s4; }
@keyframes reel-cut-s5 { 0% { transform: translateX(0); opacity: 1; } 18.75% { transform: translateX(-260px); opacity: 1; } 23.44% { transform: translateX(-440px); opacity: 1; } 28.12% { transform: translateX(-440px); opacity: 0; } 100% { transform: translateX(-440px); opacity: 0; } }
.reel .cut-s5 { animation-name: reel-cut-s5; }
@keyframes reel-cut-s6 { 0% { transform: translateX(0); opacity: 1; } 18.75% { transform: translateX(-260px); opacity: 1; } 23.44% { transform: translateX(-440px); opacity: 1; } 28.12% { transform: translateX(-740px); opacity: 1; } 100% { transform: translateX(-740px); opacity: 1; } }
.reel .cut-s6 { animation-name: reel-cut-s6; }
@keyframes reel-cut-s7 { 0% { transform: translateX(0); opacity: 1; } 18.75% { transform: translateX(-260px); opacity: 1; } 23.44% { transform: translateX(-440px); opacity: 1; } 28.12% { transform: translateX(-740px); opacity: 1; } 32.81% { transform: translateX(-740px); opacity: 0; } 100% { transform: translateX(-740px); opacity: 0; } }
.reel .cut-s7 { animation-name: reel-cut-s7; }
@keyframes reel-cut-s8 { 0% { transform: translateX(0); opacity: 1; } 18.75% { transform: translateX(-260px); opacity: 1; } 23.44% { transform: translateX(-440px); opacity: 1; } 28.12% { transform: translateX(-740px); opacity: 1; } 32.81% { transform: translateX(-960px); opacity: 1; } 100% { transform: translateX(-960px); opacity: 1; } }
.reel .cut-s8 { animation-name: reel-cut-s8; }
/* @@end */

/* shot three: captions arrive on beats 12, 14 and 15 */
.reel .d-late1,
.reel .d-late2,
.reel .d-late3 { transform-box: view-box; transform-origin: 50% 50%; }
.reel .d-late1 { animation-name: reel-late-1; }
.reel .d-late2 { animation-name: reel-late-2; }
.reel .d-late3 { animation-name: reel-late-3; }
@keyframes reel-late-1 { 0%, 75%    { opacity: 0; } 75.01%  { opacity: 1; } 100% { opacity: 1; } }
@keyframes reel-late-2 { 0%, 87.5%  { opacity: 0; } 87.51%  { opacity: 1; } 100% { opacity: 1; } }
@keyframes reel-late-3 { 0%, 93.75% { opacity: 0; } 93.76%  { opacity: 1; } 100% { opacity: 1; } }

/* --- the spark: gold, lit from behind, with a glint turning on top --- */
.reel .c-gold    { fill: #ffc53d; }
.reel .spk-bloom { opacity: 0.6; }
.reel .spk-star  { transform-box: fill-box; transform-origin: center;
                   animation: reel-twinkle 1.7s ease-in-out infinite; }
.reel .spk-glint { transform-box: fill-box; transform-origin: center;
                   animation: reel-glint 4s linear infinite; }
@keyframes reel-twinkle { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.14); } }
@keyframes reel-glint   { from { transform: rotate(0deg); } to { transform: rotate(180deg); } }
/* in shot three the spark arrives on beat 9, with a pop */
.reel .d-spark { transform-box: view-box; transform-origin: 3300px 380px;
                 animation-name: reel-spark-in; animation-timing-function: linear; }
@keyframes reel-spark-in {
  0%, 56.25% { opacity: 0; transform: scale(0.2); }
  56.26%     { opacity: 1; transform: scale(1.5); animation-timing-function: var(--ease-snap); }
  58.5%      { opacity: 1; transform: scale(1); }
  100%       { opacity: 1; transform: scale(1); }
}

@keyframes reel-accent-swap {
  0%   { --reel-accent: #1b43e8; }
  100% { --reel-accent: #7626fe; }
}

/* @@generated:shoot */
/* --- the shoot: where the footage came from. Once, after the pass. ---
   Percentages are of 9.3148s (22 beats): the jungle at 0, the slope at 2,
   the ring light at 3.5 (the lid at 4.2), the list at 6.5 (three lines a beat apart, then
   quickening from 0.6 to 0.12 of a beat), the card at 18.44,
   the strip at 20.1388. Generated — see the note above .hero-reel. */
.reel .s-f,
.reel .sh-shot,
.reel .sh-thumb,
.reel .sh-rec,
.reel .sh-rider,
.reel .sh-spray,
.reel .sh-lines,
.reel .sh-hands,
.reel .sh-lid,
.reel .sh-glow,
.reel .sh-inner,
.reel .sh-bird,
.reel .sh-sp1,
.reel .sh-sp2,
.reel .sh-sp3,
.reel .sh-fig,
.reel .sh-near,
.reel .sh-cam,
.reel .sh-card,
.reel .sh-ln {
  animation-duration: 9.3148s;
  animation-timing-function: steps(1, end);
  animation-delay: calc(var(--reel-pro) + var(--reel-loop));
  animation-iteration-count: 1;
  animation-fill-mode: forwards;
}
.reel .s-f { animation-name: reel-f-vis; }
@keyframes reel-f-vis { 0% { opacity: 1; } 100% { opacity: 1; } }
.reel .sh-shot { opacity: 0; }
.reel .sh-shot-j { animation-name: reel-f-shot-j; }
@keyframes reel-f-shot-j { 0% { opacity: 1; } 0.00% { opacity: 1; } 9.09% { opacity: 0; } 100% { opacity: 0; } }
.reel .sh-shot-s { animation-name: reel-f-shot-s; }
@keyframes reel-f-shot-s { 0% { opacity: 0; } 9.09% { opacity: 1; } 15.91% { opacity: 0; } 100% { opacity: 0; } }
.reel .sh-shot-r { animation-name: reel-f-shot-r; }
@keyframes reel-f-shot-r { 0% { opacity: 0; } 15.91% { opacity: 1; } 29.55% { opacity: 0; } 100% { opacity: 0; } }
.reel .sh-shot-l { animation-name: reel-f-shot-l; }
@keyframes reel-f-shot-l { 0% { opacity: 0; } 29.55% { opacity: 1; } 91.54% { opacity: 0; } 100% { opacity: 0; } }
.reel .sh-strip { animation-name: reel-f-strip; }
@keyframes reel-f-strip { 0% { opacity: 0; } 91.54% { opacity: 1; } 100% { opacity: 1; } }
.reel .sh-rec { animation-name: reel-f-rec; }
@keyframes reel-f-rec { 0.00% { opacity: 1; } 2.27% { opacity: 0; } 4.55% { opacity: 1; } 6.82% { opacity: 0; } 9.09% { opacity: 1; } 11.36% { opacity: 0; } 13.64% { opacity: 1; } 15.91% { opacity: 0; } 18.18% { opacity: 1; } 20.45% { opacity: 0; } 22.73% { opacity: 1; } 25.00% { opacity: 0; } 27.27% { opacity: 1; } 100% { opacity: 1; } }
.reel .sh-shot-j .sh-fig { animation-name: reel-f-creep; animation-timing-function: linear; }
@keyframes reel-f-creep { 0% { transform: translate(-40px, 0); } 4.55% { transform: translate(0, -6px); } 9.09% { transform: translate(40px, 0); } 100% { transform: translate(40px, 0); } }
.reel .sh-near { animation-name: reel-f-sway; animation-timing-function: ease-in-out; transform-box: view-box; transform-origin: 50%% 100%%; }
@keyframes reel-f-sway { 0% { transform: rotate(0deg); } 4.55% { transform: rotate(1.5deg); } 9.09% { transform: rotate(-1deg); } 100% { transform: rotate(-1deg); } }
.reel .sh-bird { opacity: 0; transform-box: fill-box; transform-origin: center; animation-name: reel-f-bird; animation-timing-function: linear; }
@keyframes reel-f-bird { 0%, 3.18% { opacity: 0; transform: scale(0.2); } 3.27% { opacity: 1; transform: scale(1.4); animation-timing-function: var(--ease-snap); } 5.00% { opacity: 1; transform: scale(1); } 9.09%, 100% { opacity: 1; transform: scale(1); } }
.reel .sh-rider { animation-name: reel-f-ride; animation-timing-function: linear; transform-box: view-box; transform-origin: 1400px 690px; }
@keyframes reel-f-ride { 0%, 9.09% { transform: translate(-500px, -117px) rotate(13deg); animation-timing-function: linear; } 15.91% { transform: translate(700px, 164px) rotate(13deg); } 100% { transform: translate(700px, 164px) rotate(13deg); } }
.reel .sh-spray { animation-name: reel-f-spray; animation-timing-function: linear; }
@keyframes reel-f-spray { 0%, 9.09% { transform: translate(-500px, -117px); animation-timing-function: linear; } 15.91% { transform: translate(700px, 164px); } 100% { transform: translate(700px, 164px); } }
.reel .sh-lines { animation-name: reel-f-lines; animation-timing-function: linear; }
@keyframes reel-f-lines { 0%, 9.09% { transform: translateX(0); animation-timing-function: linear; } 15.91% { transform: translateX(-1600px); } 100% { transform: translateX(-1600px); } }
.reel .sh-lid { animation-name: reel-f-lid; animation-timing-function: linear; transform-box: view-box; transform-origin: 1890px 760px; }
@keyframes reel-f-lid { 0%, 19.09% { transform: rotate(0deg); animation-timing-function: cubic-bezier(0.3, 0, 0.2, 1); } 20.45% { transform: rotate(-112deg); animation-timing-function: ease-in-out; } 21.14% { transform: rotate(-104deg); } 100% { transform: rotate(-104deg); } }
.reel .sh-glow { opacity: 0; animation-name: reel-f-glow; animation-timing-function: linear; }
@keyframes reel-f-glow { 0%, 19.64% { opacity: 0; } 20.45% { opacity: 1; } 100% { opacity: 1; } }
.reel .sh-inner { opacity: 0; animation-name: reel-f-inner; animation-timing-function: linear; }
@keyframes reel-f-inner { 0%, 19.64% { opacity: 0; } 20.45% { opacity: 1; } 100% { opacity: 1; } }
.reel .sh-hands { animation-name: reel-f-hands; animation-timing-function: linear; transform-box: view-box; transform-origin: 1300px 760px; }
@keyframes reel-f-hands { 0%, 20.00% { transform: translateY(160px) rotate(0deg); animation-timing-function: var(--ease-snap); } 21.14% { transform: translateY(0) rotate(0deg); animation-timing-function: ease-in-out; } 23.18% { transform: translateY(-40px) rotate(-3deg); animation-timing-function: ease-in-out; } 24.77% { transform: translateY(0) rotate(2deg); animation-timing-function: ease-in-out; } 26.36% { transform: translateY(-24px) rotate(-2deg); animation-timing-function: ease-in-out; } 27.95% { transform: translateY(0) rotate(0deg); } 100% { transform: translateY(0) rotate(0deg); } }
.reel .sh-sp1 { opacity: 0; transform-box: fill-box; transform-origin: center; animation-name: reel-f-sp1; animation-timing-function: linear; }
@keyframes reel-f-sp1 { 0%, 21.14% { opacity: 0; transform: scale(0.2); } 21.23% { opacity: 1; transform: scale(1.5); animation-timing-function: var(--ease-snap); } 22.50% { opacity: 1; transform: scale(1); } 100% { opacity: 1; transform: scale(1); } }
.reel .sh-sp2 { opacity: 0; transform-box: fill-box; transform-origin: center; animation-name: reel-f-sp2; animation-timing-function: linear; }
@keyframes reel-f-sp2 { 0%, 22.73% { opacity: 0; transform: scale(0.2); } 22.82% { opacity: 1; transform: scale(1.5); animation-timing-function: var(--ease-snap); } 24.09% { opacity: 1; transform: scale(1); } 100% { opacity: 1; transform: scale(1); } }
.reel .sh-sp3 { opacity: 0; transform-box: fill-box; transform-origin: center; animation-name: reel-f-sp3; animation-timing-function: linear; }
@keyframes reel-f-sp3 { 0%, 24.09% { opacity: 0; transform: scale(0.2); } 24.18% { opacity: 1; transform: scale(1.5); animation-timing-function: var(--ease-snap); } 25.45% { opacity: 1; transform: scale(1); } 100% { opacity: 1; transform: scale(1); } }
/* the list: each pairing snaps in and the camera swoops down to it; then the card */
.reel .sh-cam { animation-name: reel-f-cam; animation-timing-function: linear; transform-box: view-box; transform-origin: 0 0; }
/* the camera carries a vertical blur for the length of each swoop: motion, not a fade.
   The first three lines are held right in close, a pause and a snap each; the camera
   then pulls back out and the gaps shrink geometrically, the swoops, slams and
   hand-offs shrinking with them. */
@keyframes reel-f-cam { 0%, 29.55% { transform: translate(-440.0px, -40.0px) scale(2.000); filter: none; } 41.20% { transform: translate(-440.0px, -40.0px) scale(2.000); filter: none; } 41.23% { transform: translate(-440.0px, -40.0px) scale(2.000); filter: url(#reel-vblur); animation-timing-function: cubic-bezier(0.3, 0, 0.2, 1); } 41.74% { transform: translate(-440.0px, -276.0px) scale(2.000); filter: url(#reel-vblur); } 41.86% { transform: translate(-440.0px, -276.0px) scale(2.000); filter: none; } 53.02% { transform: translate(-440.0px, -276.0px) scale(2.000); filter: none; } 53.05% { transform: translate(-440.0px, -276.0px) scale(2.000); filter: url(#reel-vblur); animation-timing-function: cubic-bezier(0.3, 0, 0.2, 1); } 53.55% { transform: translate(-440.0px, -512.0px) scale(2.000); filter: url(#reel-vblur); } 53.68% { transform: translate(-440.0px, -512.0px) scale(2.000); filter: none; } 55.75% { transform: translate(-440.0px, -512.0px) scale(2.000); filter: none; } 55.77% { transform: translate(-440.0px, -512.0px) scale(2.000); filter: url(#reel-vblur); animation-timing-function: cubic-bezier(0.3, 0, 0.2, 1); } 56.94% { transform: translate(-280.0px, -446.4px) scale(1.600); filter: url(#reel-vblur); } 57.23% { transform: translate(-280.0px, -446.4px) scale(1.600); filter: none; } 58.27% { transform: translate(-280.0px, -446.4px) scale(1.600); filter: none; } 58.29% { transform: translate(-280.0px, -446.4px) scale(1.600); filter: url(#reel-vblur); animation-timing-function: cubic-bezier(0.3, 0, 0.2, 1); } 59.20% { transform: translate(-280.0px, -635.2px) scale(1.600); filter: url(#reel-vblur); } 59.43% { transform: translate(-280.0px, -635.2px) scale(1.600); filter: none; } 60.59% { transform: translate(-280.0px, -635.2px) scale(1.600); filter: none; } 60.61% { transform: translate(-280.0px, -635.2px) scale(1.600); filter: url(#reel-vblur); animation-timing-function: cubic-bezier(0.3, 0, 0.2, 1); } 61.52% { transform: translate(-280.0px, -824.0px) scale(1.600); filter: url(#reel-vblur); } 61.75% { transform: translate(-280.0px, -824.0px) scale(1.600); filter: none; } 62.73% { transform: translate(-280.0px, -824.0px) scale(1.600); filter: none; } 62.75% { transform: translate(-280.0px, -824.0px) scale(1.600); filter: url(#reel-vblur); animation-timing-function: cubic-bezier(0.3, 0, 0.2, 1); } 63.66% { transform: translate(-280.0px, -1012.8px) scale(1.600); filter: url(#reel-vblur); } 63.89% { transform: translate(-280.0px, -1012.8px) scale(1.600); filter: none; } 64.71% { transform: translate(-280.0px, -1012.8px) scale(1.600); filter: none; } 64.73% { transform: translate(-280.0px, -1012.8px) scale(1.600); filter: url(#reel-vblur); animation-timing-function: cubic-bezier(0.3, 0, 0.2, 1); } 65.64% { transform: translate(-280.0px, -1201.6px) scale(1.600); filter: url(#reel-vblur); } 65.87% { transform: translate(-280.0px, -1201.6px) scale(1.600); filter: none; } 66.53% { transform: translate(-280.0px, -1201.6px) scale(1.600); filter: none; } 66.55% { transform: translate(-280.0px, -1201.6px) scale(1.600); filter: url(#reel-vblur); animation-timing-function: cubic-bezier(0.3, 0, 0.2, 1); } 67.46% { transform: translate(-280.0px, -1390.4px) scale(1.600); filter: url(#reel-vblur); } 67.69% { transform: translate(-280.0px, -1390.4px) scale(1.600); filter: none; } 68.21% { transform: translate(-280.0px, -1390.4px) scale(1.600); filter: none; } 68.24% { transform: translate(-280.0px, -1390.4px) scale(1.600); filter: url(#reel-vblur); animation-timing-function: cubic-bezier(0.3, 0, 0.2, 1); } 69.15% { transform: translate(-280.0px, -1579.2px) scale(1.600); filter: url(#reel-vblur); } 69.37% { transform: translate(-280.0px, -1579.2px) scale(1.600); filter: none; } 69.77% { transform: translate(-280.0px, -1579.2px) scale(1.600); filter: none; } 69.79% { transform: translate(-280.0px, -1579.2px) scale(1.600); filter: url(#reel-vblur); animation-timing-function: cubic-bezier(0.3, 0, 0.2, 1); } 70.66% { transform: translate(-280.0px, -1768.0px) scale(1.600); filter: url(#reel-vblur); } 70.88% { transform: translate(-280.0px, -1768.0px) scale(1.600); filter: none; } 71.20% { transform: translate(-280.0px, -1768.0px) scale(1.600); filter: none; } 71.22% { transform: translate(-280.0px, -1768.0px) scale(1.600); filter: url(#reel-vblur); animation-timing-function: cubic-bezier(0.3, 0, 0.2, 1); } 72.02% { transform: translate(-280.0px, -1956.8px) scale(1.600); filter: url(#reel-vblur); } 72.22% { transform: translate(-280.0px, -1956.8px) scale(1.600); filter: none; } 72.52% { transform: translate(-280.0px, -1956.8px) scale(1.600); filter: none; } 72.54% { transform: translate(-280.0px, -1956.8px) scale(1.600); filter: url(#reel-vblur); animation-timing-function: cubic-bezier(0.3, 0, 0.2, 1); } 73.28% { transform: translate(-280.0px, -2145.6px) scale(1.600); filter: url(#reel-vblur); } 73.47% { transform: translate(-280.0px, -2145.6px) scale(1.600); filter: none; } 73.74% { transform: translate(-280.0px, -2145.6px) scale(1.600); filter: none; } 73.76% { transform: translate(-280.0px, -2145.6px) scale(1.600); filter: url(#reel-vblur); animation-timing-function: cubic-bezier(0.3, 0, 0.2, 1); } 74.45% { transform: translate(-280.0px, -2334.4px) scale(1.600); filter: url(#reel-vblur); } 74.62% { transform: translate(-280.0px, -2334.4px) scale(1.600); filter: none; } 74.87% { transform: translate(-280.0px, -2334.4px) scale(1.600); filter: none; } 74.89% { transform: translate(-280.0px, -2334.4px) scale(1.600); filter: url(#reel-vblur); animation-timing-function: cubic-bezier(0.3, 0, 0.2, 1); } 75.52% { transform: translate(-280.0px, -2523.2px) scale(1.600); filter: url(#reel-vblur); } 75.68% { transform: translate(-280.0px, -2523.2px) scale(1.600); filter: none; } 75.90% { transform: translate(-280.0px, -2523.2px) scale(1.600); filter: none; } 75.93% { transform: translate(-280.0px, -2523.2px) scale(1.600); filter: url(#reel-vblur); animation-timing-function: cubic-bezier(0.3, 0, 0.2, 1); } 76.51% { transform: translate(-280.0px, -2712.0px) scale(1.600); filter: url(#reel-vblur); } 76.65% { transform: translate(-280.0px, -2712.0px) scale(1.600); filter: none; } 76.86% { transform: translate(-280.0px, -2712.0px) scale(1.600); filter: none; } 76.89% { transform: translate(-280.0px, -2712.0px) scale(1.600); filter: url(#reel-vblur); animation-timing-function: cubic-bezier(0.3, 0, 0.2, 1); } 77.42% { transform: translate(-280.0px, -2900.8px) scale(1.600); filter: url(#reel-vblur); } 77.56% { transform: translate(-280.0px, -2900.8px) scale(1.600); filter: none; } 77.75% { transform: translate(-280.0px, -2900.8px) scale(1.600); filter: none; } 77.77% { transform: translate(-280.0px, -2900.8px) scale(1.600); filter: url(#reel-vblur); animation-timing-function: cubic-bezier(0.3, 0, 0.2, 1); } 78.26% { transform: translate(-280.0px, -3089.6px) scale(1.600); filter: url(#reel-vblur); } 78.39% { transform: translate(-280.0px, -3089.6px) scale(1.600); filter: none; } 78.56% { transform: translate(-280.0px, -3089.6px) scale(1.600); filter: none; } 78.58% { transform: translate(-280.0px, -3089.6px) scale(1.600); filter: url(#reel-vblur); animation-timing-function: cubic-bezier(0.3, 0, 0.2, 1); } 79.04% { transform: translate(-280.0px, -3278.4px) scale(1.600); filter: url(#reel-vblur); } 79.16% { transform: translate(-280.0px, -3278.4px) scale(1.600); filter: none; } 79.31% { transform: translate(-280.0px, -3278.4px) scale(1.600); filter: none; } 79.34% { transform: translate(-280.0px, -3278.4px) scale(1.600); filter: url(#reel-vblur); animation-timing-function: cubic-bezier(0.3, 0, 0.2, 1); } 79.76% { transform: translate(-280.0px, -3467.2px) scale(1.600); filter: url(#reel-vblur); } 79.86% { transform: translate(-280.0px, -3467.2px) scale(1.600); filter: none; } 80.01% { transform: translate(-280.0px, -3467.2px) scale(1.600); filter: none; } 80.03% { transform: translate(-280.0px, -3467.2px) scale(1.600); filter: url(#reel-vblur); animation-timing-function: cubic-bezier(0.3, 0, 0.2, 1); } 80.42% { transform: translate(-280.0px, -3656.0px) scale(1.600); filter: url(#reel-vblur); } 80.52% { transform: translate(-280.0px, -3656.0px) scale(1.600); filter: none; } 80.65% { transform: translate(-280.0px, -3656.0px) scale(1.600); filter: none; } 80.67% { transform: translate(-280.0px, -3656.0px) scale(1.600); filter: url(#reel-vblur); animation-timing-function: cubic-bezier(0.3, 0, 0.2, 1); } 81.03% { transform: translate(-280.0px, -3844.8px) scale(1.600); filter: url(#reel-vblur); } 81.12% { transform: translate(-280.0px, -3844.8px) scale(1.600); filter: none; } 81.24% { transform: translate(-280.0px, -3844.8px) scale(1.600); filter: none; } 81.26% { transform: translate(-280.0px, -3844.8px) scale(1.600); filter: url(#reel-vblur); animation-timing-function: cubic-bezier(0.3, 0, 0.2, 1); } 81.59% { transform: translate(-280.0px, -4033.6px) scale(1.600); filter: url(#reel-vblur); } 81.68% { transform: translate(-280.0px, -4033.6px) scale(1.600); filter: none; } 81.79% { transform: translate(-280.0px, -4033.6px) scale(1.600); filter: none; } 81.81% { transform: translate(-280.0px, -4033.6px) scale(1.600); filter: url(#reel-vblur); animation-timing-function: cubic-bezier(0.3, 0, 0.2, 1); } 82.11% { transform: translate(-280.0px, -4222.4px) scale(1.600); filter: url(#reel-vblur); } 82.19% { transform: translate(-280.0px, -4222.4px) scale(1.600); filter: none; } 82.29% { transform: translate(-280.0px, -4222.4px) scale(1.600); filter: none; } 82.31% { transform: translate(-280.0px, -4222.4px) scale(1.600); filter: url(#reel-vblur); animation-timing-function: cubic-bezier(0.3, 0, 0.2, 1); } 82.59% { transform: translate(-280.0px, -4411.2px) scale(1.600); filter: url(#reel-vblur); } 82.66% { transform: translate(-280.0px, -4411.2px) scale(1.600); filter: none; } 83.31% { transform: translate(-280.0px, -4411.2px) scale(1.600); filter: none; } 83.36% { transform: translate(-280.0px, -4411.2px) scale(1.600); filter: url(#reel-vblur); animation-timing-function: cubic-bezier(0.4, 0, 0.15, 1); } 85.63% { transform: translate(-576.0px, -4259.0px) scale(1.300); filter: url(#reel-vblur); } 86.09% { transform: translate(-576.0px, -4259.0px) scale(1.300); filter: none; } 100% { transform: translate(-576.0px, -4259.0px) scale(1.300); filter: none; } }
/* focus: the line that just landed is the sharp white one; the moment the next
   lands, it softens and dims to the pack above, so the eye has one thing to read */
.reel .sh-ln { opacity: 0; transform-box: fill-box; transform-origin: left center; }
.reel .sh-ln-0 { animation-name: reel-f-ln-0; animation-timing-function: linear; }
@keyframes reel-f-ln-0 { 0%, 29.50% { opacity: 0; transform: scale(1.12); filter: blur(5px); } 29.55% { opacity: 1; transform: scale(1.12); filter: blur(5px); animation-timing-function: var(--ease-snap); } 30.44% { opacity: 1; transform: scale(1); filter: blur(0); } 41.34% { opacity: 1; transform: scale(1); filter: blur(0); animation-timing-function: ease-out; } 42.05% { opacity: 0.32; transform: scale(1); filter: blur(3px); } 100% { opacity: 0.32; transform: scale(1); filter: blur(3px); } }
.reel .sh-ln-1 { animation-name: reel-f-ln-1; animation-timing-function: linear; }
@keyframes reel-f-ln-1 { 0%, 41.32% { opacity: 0; transform: scale(1.12); filter: blur(5px); } 41.36% { opacity: 1; transform: scale(1.12); filter: blur(5px); animation-timing-function: var(--ease-snap); } 42.26% { opacity: 1; transform: scale(1); filter: blur(0); } 53.16% { opacity: 1; transform: scale(1); filter: blur(0); animation-timing-function: ease-out; } 53.86% { opacity: 0.32; transform: scale(1); filter: blur(3px); } 100% { opacity: 0.32; transform: scale(1); filter: blur(3px); } }
.reel .sh-ln-2 { animation-name: reel-f-ln-2; animation-timing-function: linear; }
@keyframes reel-f-ln-2 { 0%, 53.14% { opacity: 0; transform: scale(1.12); filter: blur(5px); } 53.18% { opacity: 1; transform: scale(1.12); filter: blur(5px); animation-timing-function: var(--ease-snap); } 54.08% { opacity: 1; transform: scale(1); filter: blur(0); } 55.89% { opacity: 1; transform: scale(1); filter: blur(0); animation-timing-function: ease-out; } 56.59% { opacity: 0.32; transform: scale(1); filter: blur(3px); } 100% { opacity: 0.32; transform: scale(1); filter: blur(3px); } }
.reel .sh-ln-3 { animation-name: reel-f-ln-3; animation-timing-function: linear; }
@keyframes reel-f-ln-3 { 0%, 55.86% { opacity: 0; transform: scale(1.12); filter: blur(5px); } 55.91% { opacity: 1; transform: scale(1.12); filter: blur(5px); animation-timing-function: var(--ease-snap); } 56.80% { opacity: 1; transform: scale(1); filter: blur(0); } 58.40% { opacity: 1; transform: scale(1); filter: blur(0); animation-timing-function: ease-out; } 59.11% { opacity: 0.32; transform: scale(1); filter: blur(3px); } 100% { opacity: 0.32; transform: scale(1); filter: blur(3px); } }
.reel .sh-ln-4 { animation-name: reel-f-ln-4; animation-timing-function: linear; }
@keyframes reel-f-ln-4 { 0%, 58.38% { opacity: 0; transform: scale(1.12); filter: blur(5px); } 58.43% { opacity: 1; transform: scale(1.12); filter: blur(5px); animation-timing-function: var(--ease-snap); } 59.32% { opacity: 1; transform: scale(1); filter: blur(0); } 60.72% { opacity: 1; transform: scale(1); filter: blur(0); animation-timing-function: ease-out; } 61.43% { opacity: 0.32; transform: scale(1); filter: blur(3px); } 100% { opacity: 0.32; transform: scale(1); filter: blur(3px); } }
.reel .sh-ln-5 { animation-name: reel-f-ln-5; animation-timing-function: linear; }
@keyframes reel-f-ln-5 { 0%, 60.70% { opacity: 0; transform: scale(1.12); filter: blur(5px); } 60.75% { opacity: 1; transform: scale(1.12); filter: blur(5px); animation-timing-function: var(--ease-snap); } 61.64% { opacity: 1; transform: scale(1); filter: blur(0); } 62.87% { opacity: 1; transform: scale(1); filter: blur(0); animation-timing-function: ease-out; } 63.57% { opacity: 0.32; transform: scale(1); filter: blur(3px); } 100% { opacity: 0.32; transform: scale(1); filter: blur(3px); } }
.reel .sh-ln-6 { animation-name: reel-f-ln-6; animation-timing-function: linear; }
@keyframes reel-f-ln-6 { 0%, 62.84% { opacity: 0; transform: scale(1.12); filter: blur(5px); } 62.89% { opacity: 1; transform: scale(1.12); filter: blur(5px); animation-timing-function: var(--ease-snap); } 63.78% { opacity: 1; transform: scale(1); filter: blur(0); } 64.84% { opacity: 1; transform: scale(1); filter: blur(0); animation-timing-function: ease-out; } 65.55% { opacity: 0.32; transform: scale(1); filter: blur(3px); } 100% { opacity: 0.32; transform: scale(1); filter: blur(3px); } }
.reel .sh-ln-7 { animation-name: reel-f-ln-7; animation-timing-function: linear; }
@keyframes reel-f-ln-7 { 0%, 64.82% { opacity: 0; transform: scale(1.12); filter: blur(5px); } 64.87% { opacity: 1; transform: scale(1.12); filter: blur(5px); animation-timing-function: var(--ease-snap); } 65.69% { opacity: 1; transform: scale(1); filter: blur(0); } 66.67% { opacity: 1; transform: scale(1); filter: blur(0); animation-timing-function: ease-out; } 67.37% { opacity: 0.32; transform: scale(1); filter: blur(3px); } 100% { opacity: 0.32; transform: scale(1); filter: blur(3px); } }
.reel .sh-ln-8 { animation-name: reel-f-ln-8; animation-timing-function: linear; }
@keyframes reel-f-ln-8 { 0%, 66.64% { opacity: 0; transform: scale(1.12); filter: blur(5px); } 66.69% { opacity: 1; transform: scale(1.12); filter: blur(5px); animation-timing-function: var(--ease-snap); } 67.45% { opacity: 1; transform: scale(1); filter: blur(0); } 68.35% { opacity: 1; transform: scale(1); filter: blur(0); animation-timing-function: ease-out; } 69.05% { opacity: 0.32; transform: scale(1); filter: blur(3px); } 100% { opacity: 0.32; transform: scale(1); filter: blur(3px); } }
.reel .sh-ln-9 { animation-name: reel-f-ln-9; animation-timing-function: linear; }
@keyframes reel-f-ln-9 { 0%, 68.33% { opacity: 0; transform: scale(1.12); filter: blur(5px); } 68.37% { opacity: 1; transform: scale(1.12); filter: blur(5px); animation-timing-function: var(--ease-snap); } 69.07% { opacity: 1; transform: scale(1); filter: blur(0); } 69.90% { opacity: 1; transform: scale(1); filter: blur(0); animation-timing-function: ease-out; } 70.55% { opacity: 0.32; transform: scale(1); filter: blur(3px); } 100% { opacity: 0.32; transform: scale(1); filter: blur(3px); } }
.reel .sh-ln-10 { animation-name: reel-f-ln-10; animation-timing-function: linear; }
@keyframes reel-f-ln-10 { 0%, 69.88% { opacity: 0; transform: scale(1.12); filter: blur(5px); } 69.93% { opacity: 1; transform: scale(1.12); filter: blur(5px); animation-timing-function: var(--ease-snap); } 70.57% { opacity: 1; transform: scale(1); filter: blur(0); } 71.34% { opacity: 1; transform: scale(1); filter: blur(0); animation-timing-function: ease-out; } 71.93% { opacity: 0.32; transform: scale(1); filter: blur(3px); } 100% { opacity: 0.32; transform: scale(1); filter: blur(3px); } }
.reel .sh-ln-11 { animation-name: reel-f-ln-11; animation-timing-function: linear; }
@keyframes reel-f-ln-11 { 0%, 71.31% { opacity: 0; transform: scale(1.12); filter: blur(5px); } 71.36% { opacity: 1; transform: scale(1.12); filter: blur(5px); animation-timing-function: var(--ease-snap); } 71.95% { opacity: 1; transform: scale(1); filter: blur(0); } 72.66% { opacity: 1; transform: scale(1); filter: blur(0); animation-timing-function: ease-out; } 73.21% { opacity: 0.32; transform: scale(1); filter: blur(3px); } 100% { opacity: 0.32; transform: scale(1); filter: blur(3px); } }
.reel .sh-ln-12 { animation-name: reel-f-ln-12; animation-timing-function: linear; }
@keyframes reel-f-ln-12 { 0%, 72.63% { opacity: 0; transform: scale(1.12); filter: blur(5px); } 72.68% { opacity: 1; transform: scale(1.12); filter: blur(5px); animation-timing-function: var(--ease-snap); } 73.23% { opacity: 1; transform: scale(1); filter: blur(0); } 73.88% { opacity: 1; transform: scale(1); filter: blur(0); animation-timing-function: ease-out; } 74.39% { opacity: 0.32; transform: scale(1); filter: blur(3px); } 100% { opacity: 0.32; transform: scale(1); filter: blur(3px); } }
.reel .sh-ln-13 { animation-name: reel-f-ln-13; animation-timing-function: linear; }
@keyframes reel-f-ln-13 { 0%, 73.85% { opacity: 0; transform: scale(1.12); filter: blur(5px); } 73.90% { opacity: 1; transform: scale(1.12); filter: blur(5px); animation-timing-function: var(--ease-snap); } 74.41% { opacity: 1; transform: scale(1); filter: blur(0); } 75.00% { opacity: 1; transform: scale(1); filter: blur(0); animation-timing-function: ease-out; } 75.48% { opacity: 0.32; transform: scale(1); filter: blur(3px); } 100% { opacity: 0.32; transform: scale(1); filter: blur(3px); } }
.reel .sh-ln-14 { animation-name: reel-f-ln-14; animation-timing-function: linear; }
@keyframes reel-f-ln-14 { 0%, 74.98% { opacity: 0; transform: scale(1.12); filter: blur(5px); } 75.03% { opacity: 1; transform: scale(1.12); filter: blur(5px); animation-timing-function: var(--ease-snap); } 75.49% { opacity: 1; transform: scale(1); filter: blur(0); } 76.04% { opacity: 1; transform: scale(1); filter: blur(0); animation-timing-function: ease-out; } 76.48% { opacity: 0.32; transform: scale(1); filter: blur(3px); } 100% { opacity: 0.32; transform: scale(1); filter: blur(3px); } }
.reel .sh-ln-15 { animation-name: reel-f-ln-15; animation-timing-function: linear; }
@keyframes reel-f-ln-15 { 0%, 76.02% { opacity: 0; transform: scale(1.12); filter: blur(5px); } 76.06% { opacity: 1; transform: scale(1.12); filter: blur(5px); animation-timing-function: var(--ease-snap); } 76.49% { opacity: 1; transform: scale(1); filter: blur(0); } 77.00% { opacity: 1; transform: scale(1); filter: blur(0); animation-timing-function: ease-out; } 77.40% { opacity: 0.32; transform: scale(1); filter: blur(3px); } 100% { opacity: 0.32; transform: scale(1); filter: blur(3px); } }
.reel .sh-ln-16 { animation-name: reel-f-ln-16; animation-timing-function: linear; }
@keyframes reel-f-ln-16 { 0%, 76.98% { opacity: 0; transform: scale(1.12); filter: blur(5px); } 77.02% { opacity: 1; transform: scale(1.12); filter: blur(5px); animation-timing-function: var(--ease-snap); } 77.42% { opacity: 1; transform: scale(1); filter: blur(0); } 77.88% { opacity: 1; transform: scale(1); filter: blur(0); animation-timing-function: ease-out; } 78.26% { opacity: 0.32; transform: scale(1); filter: blur(3px); } 100% { opacity: 0.32; transform: scale(1); filter: blur(3px); } }
.reel .sh-ln-17 { animation-name: reel-f-ln-17; animation-timing-function: linear; }
@keyframes reel-f-ln-17 { 0%, 77.86% { opacity: 0; transform: scale(1.12); filter: blur(5px); } 77.91% { opacity: 1; transform: scale(1.12); filter: blur(5px); animation-timing-function: var(--ease-snap); } 78.27% { opacity: 1; transform: scale(1); filter: blur(0); } 78.70% { opacity: 1; transform: scale(1); filter: blur(0); animation-timing-function: ease-out; } 79.05% { opacity: 0.32; transform: scale(1); filter: blur(3px); } 100% { opacity: 0.32; transform: scale(1); filter: blur(3px); } }
.reel .sh-ln-18 { animation-name: reel-f-ln-18; animation-timing-function: linear; }
@keyframes reel-f-ln-18 { 0%, 78.68% { opacity: 0; transform: scale(1.12); filter: blur(5px); } 78.72% { opacity: 1; transform: scale(1.12); filter: blur(5px); animation-timing-function: var(--ease-snap); } 79.06% { opacity: 1; transform: scale(1); filter: blur(0); } 79.45% { opacity: 1; transform: scale(1); filter: blur(0); animation-timing-function: ease-out; } 79.77% { opacity: 0.32; transform: scale(1); filter: blur(3px); } 100% { opacity: 0.32; transform: scale(1); filter: blur(3px); } }
.reel .sh-ln-19 { animation-name: reel-f-ln-19; animation-timing-function: linear; }
@keyframes reel-f-ln-19 { 0%, 79.43% { opacity: 0; transform: scale(1.12); filter: blur(5px); } 79.47% { opacity: 1; transform: scale(1.12); filter: blur(5px); animation-timing-function: var(--ease-snap); } 79.79% { opacity: 1; transform: scale(1); filter: blur(0); } 80.15% { opacity: 1; transform: scale(1); filter: blur(0); animation-timing-function: ease-out; } 80.45% { opacity: 0.32; transform: scale(1); filter: blur(3px); } 100% { opacity: 0.32; transform: scale(1); filter: blur(3px); } }
.reel .sh-ln-20 { animation-name: reel-f-ln-20; animation-timing-function: linear; }
@keyframes reel-f-ln-20 { 0%, 80.12% { opacity: 0; transform: scale(1.12); filter: blur(5px); } 80.17% { opacity: 1; transform: scale(1.12); filter: blur(5px); animation-timing-function: var(--ease-snap); } 80.46% { opacity: 1; transform: scale(1); filter: blur(0); } 80.79% { opacity: 1; transform: scale(1); filter: blur(0); animation-timing-function: ease-out; } 81.07% { opacity: 0.32; transform: scale(1); filter: blur(3px); } 100% { opacity: 0.32; transform: scale(1); filter: blur(3px); } }
.reel .sh-ln-21 { animation-name: reel-f-ln-21; animation-timing-function: linear; }
@keyframes reel-f-ln-21 { 0%, 80.76% { opacity: 0; transform: scale(1.12); filter: blur(5px); } 80.81% { opacity: 1; transform: scale(1.12); filter: blur(5px); animation-timing-function: var(--ease-snap); } 81.08% { opacity: 1; transform: scale(1); filter: blur(0); } 81.38% { opacity: 1; transform: scale(1); filter: blur(0); animation-timing-function: ease-out; } 81.64% { opacity: 0.32; transform: scale(1); filter: blur(3px); } 100% { opacity: 0.32; transform: scale(1); filter: blur(3px); } }
.reel .sh-ln-22 { animation-name: reel-f-ln-22; animation-timing-function: linear; }
@keyframes reel-f-ln-22 { 0%, 81.35% { opacity: 0; transform: scale(1.12); filter: blur(5px); } 81.40% { opacity: 1; transform: scale(1.12); filter: blur(5px); animation-timing-function: var(--ease-snap); } 81.65% { opacity: 1; transform: scale(1); filter: blur(0); } 81.92% { opacity: 1; transform: scale(1); filter: blur(0); animation-timing-function: ease-out; } 82.16% { opacity: 0.32; transform: scale(1); filter: blur(3px); } 100% { opacity: 0.32; transform: scale(1); filter: blur(3px); } }
.reel .sh-ln-23 { animation-name: reel-f-ln-23; animation-timing-function: linear; }
@keyframes reel-f-ln-23 { 0%, 81.90% { opacity: 0; transform: scale(1.12); filter: blur(5px); } 81.95% { opacity: 1; transform: scale(1.12); filter: blur(5px); animation-timing-function: var(--ease-snap); } 82.17% { opacity: 1; transform: scale(1); filter: blur(0); } 82.43% { opacity: 1; transform: scale(1); filter: blur(0); animation-timing-function: ease-out; } 82.65% { opacity: 0.32; transform: scale(1); filter: blur(3px); } 100% { opacity: 0.32; transform: scale(1); filter: blur(3px); } }
.reel .sh-ln-24 { animation-name: reel-f-ln-24; animation-timing-function: linear; }
@keyframes reel-f-ln-24 { 0%, 82.40% { opacity: 0; transform: scale(1.12); filter: blur(5px); } 82.45% { opacity: 1; transform: scale(1.12); filter: blur(5px); animation-timing-function: var(--ease-snap); } 83.06% { opacity: 1; transform: scale(1); filter: blur(0); } 83.79% { opacity: 1; transform: scale(1); filter: blur(0); animation-timing-function: ease-out; } 84.36% { opacity: 0.32; transform: scale(1); filter: blur(3px); } 100% { opacity: 0.32; transform: scale(1); filter: blur(3px); } }
.reel .sh-card { opacity: 0; transform-box: fill-box; transform-origin: center; animation-name: reel-f-card; animation-timing-function: linear; }
@keyframes reel-f-card { 0%, 83.77% { opacity: 0; transform: scale(1.1); filter: blur(8px); } 83.81% { opacity: 1; transform: scale(1.1); filter: blur(8px); animation-timing-function: var(--ease-snap); } 84.71% { opacity: 1; transform: scale(1); filter: blur(0); } 100% { opacity: 1; transform: scale(1); filter: blur(0); } }
.reel .sh-thumb-0 { opacity: 0; transform-box: fill-box; transform-origin: center; animation-name: reel-f-thumb-0; animation-timing-function: linear; }
@keyframes reel-f-thumb-0 { 0%, 91.72% { opacity: 0; transform: scale(2.4); filter: blur(30px); } 91.77% { opacity: 1; transform: scale(2.4); filter: blur(30px); animation-timing-function: var(--ease-snap); } 92.66% { opacity: 1; transform: scale(1); filter: blur(0); } 100% { opacity: 1; transform: scale(1); filter: blur(0); } }
.reel .sh-thumb-1 { opacity: 0; transform-box: fill-box; transform-origin: center; animation-name: reel-f-thumb-1; animation-timing-function: linear; }
@keyframes reel-f-thumb-1 { 0%, 92.72% { opacity: 0; transform: scale(2.4); filter: blur(30px); } 92.77% { opacity: 1; transform: scale(2.4); filter: blur(30px); animation-timing-function: var(--ease-snap); } 93.66% { opacity: 1; transform: scale(1); filter: blur(0); } 100% { opacity: 1; transform: scale(1); filter: blur(0); } }
.reel .sh-thumb-2 { opacity: 0; transform-box: fill-box; transform-origin: center; animation-name: reel-f-thumb-2; animation-timing-function: linear; }
@keyframes reel-f-thumb-2 { 0%, 93.72% { opacity: 0; transform: scale(2.4); filter: blur(30px); } 93.77% { opacity: 1; transform: scale(2.4); filter: blur(30px); animation-timing-function: var(--ease-snap); } 94.66% { opacity: 1; transform: scale(1); filter: blur(0); } 100% { opacity: 1; transform: scale(1); filter: blur(0); } }
/* @@end */

/* @@generated:drag */
/* --- the drag: the clip goes to the reel, and he works it. Once. ---
   Percentages are of 5.0808s (12 beats). Grab at 0.5, the move 0.7 to 2.0,
   the reflection 3.2 to 5.9, edits from 6, the last clip at 8.8, whole at 9.
   Generated — see the note above .hero-reel. */
.reel .s-d,
.reel .g-fx,
.reel .g-cam,
.reel .g-phone,
.reel .g-lines,
.reel .g-clip,
.reel .g-drop,
.reel .g-cursor,
.reel .g-reflect,
.reel .g-reflect-in,
.reel .g-eye-open,
.reel .g-eye-shut,
.reel .g-v,
.reel .g-wrong,
.reel .g-ph,
.reel .spk-whole {
  animation-duration: 5.0808s;
  animation-timing-function: steps(1, end);
  animation-delay: calc(var(--reel-pro) + var(--reel-loop) + var(--reel-shoot));
  animation-iteration-count: 1;
  animation-fill-mode: forwards;
}
.reel .s-d { animation-name: reel-d-vis; }
@keyframes reel-d-vis { 0% { opacity: 1; } 100% { opacity: 1; } }
/* the tracking move: the world goes 3400 px left under a horizontal blur;
   the clip crosses only part of the frame, so the camera reads as chasing it */
.reel .g-cam { animation-name: reel-d-cam; animation-timing-function: linear; }
@keyframes reel-d-cam {
  0%, 5.83% { transform: translateX(0); animation-timing-function: cubic-bezier(0.7, 0, 0.12, 1); }
  16.67%      { transform: translateX(-3440px); animation-timing-function: ease-out; }
  18.75%      { transform: translateX(-3400px); }
  100%    { transform: translateX(-3400px); }
}
/* the phone takes the hit like a cartoon: squashes, wobbles, settles; and
   gives a little jump when the reel is whole */
.reel .g-phone { animation-name: reel-d-phone; animation-timing-function: linear;
                 transform-box: view-box; transform-origin: 5320px 720px; }
@keyframes reel-d-phone {
  0%, 16.50% { transform: rotate(0deg) scale(1, 1); animation-timing-function: ease-out; }
  17.50%      { transform: rotate(-5deg) scale(1.06, 0.92); animation-timing-function: ease-in-out; }
  19.17%      { transform: rotate(4deg) scale(0.96, 1.05); animation-timing-function: ease-in-out; }
  20.83%      { transform: rotate(-2.5deg) scale(1.02, 0.98); animation-timing-function: ease-in-out; }
  22.50%      { transform: rotate(1deg) scale(1, 1); animation-timing-function: ease-in-out; }
  24.17%      { transform: rotate(0deg) scale(1, 1); }
  77.50%      { transform: rotate(0deg) scale(1, 1); animation-timing-function: ease-out; }
  78.75%      { transform: rotate(0deg) scale(1.08, 1.08); animation-timing-function: ease-in-out; }
  80.42%      { transform: rotate(0deg) scale(0.97, 0.97); animation-timing-function: ease-in-out; }
  81.67%      { transform: rotate(0deg) scale(1, 1); }
  100%    { transform: rotate(0deg) scale(1, 1); }
}
.reel .g-fx { animation-name: reel-d-fx; }
@keyframes reel-d-fx { 0%, 5.75% { filter: none; } 5.83% { filter: url(#reel-mblur); } 15.83%, 100% { filter: none; } }
.reel .g-lines { opacity: 0; animation-name: reel-d-lines; animation-timing-function: linear; }
@keyframes reel-d-lines {
  0%, 5.75% { opacity: 0; transform: translateX(0); }
  5.83%      { opacity: 1; transform: translateX(0); animation-timing-function: cubic-bezier(0.7, 0, 0.12, 1); }
  16.25%      { opacity: 1; transform: translateX(-9000px); }
  16.33%, 100% { opacity: 0; transform: translateX(-9000px); }
}
.reel .g-clip { animation-name: reel-d-clip; animation-timing-function: linear; }
@keyframes reel-d-clip {
  0%, 4.17% { transform: translate(740px, 560px) scale(1, 1) skewX(0deg); animation-timing-function: var(--ease-snap); }
  5.17%      { transform: translate(728px, 550px) scale(1.06, 1.06) skewX(0deg); }
  5.83%      { transform: translate(728px, 550px) scale(1.06, 1.06) skewX(0deg); animation-timing-function: cubic-bezier(0.7, 0, 0.12, 1); }
  16.67%      { transform: translate(1804px, 344px) scale(0.780, 0.369) skewX(-16deg); animation-timing-function: ease-out; }
  17.67%      { transform: translate(1774px, 344px) scale(0.819, 0.332) skewX(0deg); animation-timing-function: var(--ease-snap); }
  19.17%      { transform: translate(1774px, 344px) scale(0.780, 0.369) skewX(0deg); }
  49.92%      { transform: translate(1774px, 344px) scale(0.780, 0.369) skewX(0deg); opacity: 1; }
  50.00%, 100% { transform: translate(1774px, 344px) scale(0.780, 0.369) skewX(0deg); opacity: 0; }
}
.reel .g-cursor { opacity: 0; animation-name: reel-d-cursor; animation-timing-function: linear; }
@keyframes reel-d-cursor {
  0%%      { opacity: 1; transform: translate(1700px, 1400px); animation-timing-function: cubic-bezier(0.2, 0.7, 0.3, 1); }
  3.75%      { opacity: 1; transform: translate(940px, 720px); }
  5.83%      { opacity: 1; transform: translate(928px, 710px); animation-timing-function: cubic-bezier(0.7, 0, 0.12, 1); }
  16.67%      { opacity: 1; transform: translate(1960px, 403px); animation-timing-function: steps(1, end); }
  50.00%      { opacity: 1; transform: translate(1930px, 543px); }
  55.00%      { opacity: 1; transform: translate(1898px, 683px); }
  59.17%      { opacity: 1; transform: translate(1962px, 963px); }
  62.50%      { opacity: 1; transform: translate(1866px, 543px); }
  65.00%      { opacity: 1; transform: translate(1930px, 823px); }
  67.08%      { opacity: 1; transform: translate(1898px, 1103px); }
  68.75%      { opacity: 1; transform: translate(1962px, 683px); }
  70.00%      { opacity: 1; transform: translate(1930px, 963px); }
  72.92%      { opacity: 1; transform: translate(1930px, 1103px); }
  77.50%, 100% { opacity: 0; transform: translate(1930px, 1103px); }
}
.reel .g-reflect { opacity: 0; animation-name: reel-d-reflect; animation-timing-function: linear; }
@keyframes reel-d-reflect { 0%, 26.67% { opacity: 0; animation-timing-function: ease-in; } 33.33% { opacity: 0.5; } 45.83% { opacity: 0.5; animation-timing-function: ease-out; } 49.17%, 100% { opacity: 0; } }
.reel .g-reflect-in { animation-name: reel-d-reflect-in; animation-timing-function: linear;
                      transform-box: view-box; transform-origin: 2900px 640px; }
@keyframes reel-d-reflect-in { 0%, 26.67% { transform: scale(0.94); animation-timing-function: linear; } 49.17%, 100% { transform: scale(1.06); } }
.reel .g-eye-shut { opacity: 0; animation-name: reel-d-blink-shut; }
.reel .g-eye-open { animation-name: reel-d-blink-open; }
@keyframes reel-d-blink-shut { 0%, 41.58% { opacity: 0; } 41.67% { opacity: 1; } 44.17%, 100% { opacity: 0; } }
@keyframes reel-d-blink-open { 0%, 41.58% { opacity: 1; } 41.67% { opacity: 0; } 44.17%, 100% { opacity: 1; } }
.reel .g-v { opacity: 0; }
/* each edit swipes up in like the next thing in a feed, and goes as the next comes */
.reel .g-v0 { animation-name: reel-d-v0; animation-timing-function: linear; }
@keyframes reel-d-v0 { 0%, 49.92% { opacity: 0; transform: translateY(110px); } 50.00% { opacity: 1; transform: translateY(110px); animation-timing-function: cubic-bezier(0.2, 0.8, 0.2, 1); } 51.67% { opacity: 1; transform: translateY(0); } 54.92% { opacity: 1; transform: translateY(0); } 55.00%, 100% { opacity: 0; transform: translateY(0); } }
.reel .g-w0 { animation-name: reel-d-w0; }
@keyframes reel-d-w0 { 0% { opacity: 1; } 52.50% { opacity: 0; } 100% { opacity: 0; } }
.reel .g-v1 { animation-name: reel-d-v1; animation-timing-function: linear; }
@keyframes reel-d-v1 { 0%, 54.92% { opacity: 0; transform: translateY(110px); } 55.00% { opacity: 1; transform: translateY(110px); animation-timing-function: cubic-bezier(0.2, 0.8, 0.2, 1); } 56.67% { opacity: 1; transform: translateY(0); } 59.08% { opacity: 1; transform: translateY(0); } 59.17%, 100% { opacity: 0; transform: translateY(0); } }
.reel .g-w1 { animation-name: reel-d-w1; }
@keyframes reel-d-w1 { 0% { opacity: 1; } 57.08% { opacity: 0; } 100% { opacity: 0; } }
.reel .g-v2 { animation-name: reel-d-v2; animation-timing-function: linear; }
@keyframes reel-d-v2 { 0%, 59.08% { opacity: 0; transform: translateY(110px); } 59.17% { opacity: 1; transform: translateY(110px); animation-timing-function: cubic-bezier(0.2, 0.8, 0.2, 1); } 60.83% { opacity: 1; transform: translateY(0); } 62.42% { opacity: 1; transform: translateY(0); } 62.50%, 100% { opacity: 0; transform: translateY(0); } }
.reel .g-v3 { animation-name: reel-d-v3; animation-timing-function: linear; }
@keyframes reel-d-v3 { 0%, 62.42% { opacity: 0; transform: translateY(110px); } 62.50% { opacity: 1; transform: translateY(110px); animation-timing-function: cubic-bezier(0.2, 0.8, 0.2, 1); } 64.00% { opacity: 1; transform: translateY(0); } 64.92% { opacity: 1; transform: translateY(0); } 65.00%, 100% { opacity: 0; transform: translateY(0); } }
.reel .g-w3 { animation-name: reel-d-w3; }
@keyframes reel-d-w3 { 0% { opacity: 1; } 63.75% { opacity: 0; } 100% { opacity: 0; } }
.reel .g-v4 { animation-name: reel-d-v4; animation-timing-function: linear; }
@keyframes reel-d-v4 { 0%, 64.92% { opacity: 0; transform: translateY(110px); } 65.00% { opacity: 1; transform: translateY(110px); animation-timing-function: cubic-bezier(0.2, 0.8, 0.2, 1); } 66.25% { opacity: 1; transform: translateY(0); } 67.00% { opacity: 1; transform: translateY(0); } 67.08%, 100% { opacity: 0; transform: translateY(0); } }
.reel .g-v5 { animation-name: reel-d-v5; animation-timing-function: linear; }
@keyframes reel-d-v5 { 0%, 67.00% { opacity: 0; transform: translateY(110px); } 67.08% { opacity: 1; transform: translateY(110px); animation-timing-function: cubic-bezier(0.2, 0.8, 0.2, 1); } 68.08% { opacity: 1; transform: translateY(0); } 68.67% { opacity: 1; transform: translateY(0); } 68.75%, 100% { opacity: 0; transform: translateY(0); } }
.reel .g-w5 { animation-name: reel-d-w5; }
@keyframes reel-d-w5 { 0% { opacity: 1; } 67.92% { opacity: 0; } 100% { opacity: 0; } }
.reel .g-v6 { animation-name: reel-d-v6; animation-timing-function: linear; }
@keyframes reel-d-v6 { 0%, 68.67% { opacity: 0; transform: translateY(110px); } 68.75% { opacity: 1; transform: translateY(110px); animation-timing-function: cubic-bezier(0.2, 0.8, 0.2, 1); } 69.50% { opacity: 1; transform: translateY(0); } 69.92% { opacity: 1; transform: translateY(0); } 70.00%, 100% { opacity: 0; transform: translateY(0); } }
.reel .g-v7 { animation-name: reel-d-v7; animation-timing-function: linear; }
@keyframes reel-d-v7 { 0%, 69.92% { opacity: 0; transform: translateY(110px); } 70.00% { opacity: 1; transform: translateY(110px); animation-timing-function: cubic-bezier(0.2, 0.8, 0.2, 1); } 71.67% { opacity: 1; transform: translateY(0); } 77.42% { opacity: 1; transform: translateY(0); } 77.50%, 100% { opacity: 0; transform: translateY(0); } }
.reel .g-drop { opacity: 0; transform-box: fill-box; transform-origin: center;
                animation-name: reel-d-drop; animation-timing-function: linear; }
@keyframes reel-d-drop {
  0%, 72.83% { opacity: 0; transform: scale(3.4); filter: blur(40px); }
  72.92%      { opacity: 1; transform: scale(3.4); filter: blur(40px); animation-timing-function: var(--ease-snap); }
  74.56%   { opacity: 1; transform: scale(1); filter: blur(0); animation-timing-function: ease-in-out; }
  75.22%      { opacity: 1; transform: scale(0.9, 0.86); filter: blur(0); animation-timing-function: ease-in-out; }
  76.22%      { opacity: 1; transform: scale(1.04, 1.06); filter: blur(0); animation-timing-function: ease-in-out; }
  77.06%      { opacity: 1; transform: scale(1); filter: blur(0); }
  77.42%      { opacity: 1; transform: scale(1); filter: blur(0); }
  77.50%, 100% { opacity: 0; transform: scale(1); filter: blur(0); }
}
.reel .g-whole { animation-name: reel-d-whole; }
@keyframes reel-d-whole { 0%, 77.42% { opacity: 0; } 77.50%, 100% { opacity: 1; } }
.reel .g-ph { opacity: 0; animation-name: reel-d-ph; animation-timing-function: linear; }
@keyframes reel-d-ph { 0%, 77.42% { opacity: 0; transform: translateY(0); } 77.50% { opacity: 1; transform: translateY(0); } 96.67%, 100% { opacity: 1; transform: translateY(826px); } }
/* and the spark, with a pop, once it is whole */
.reel .spk-whole { opacity: 0; transform-box: fill-box; transform-origin: center;
                   animation-name: reel-d-spark; animation-timing-function: linear; }
@keyframes reel-d-spark {
  0%, 78.67% { opacity: 0; transform: scale(0.2); }
  78.75%      { opacity: 1; transform: scale(1.5); animation-timing-function: var(--ease-snap); }
  81.67%      { opacity: 1; transform: scale(1); }
  100%    { opacity: 1; transform: scale(1); }
}
/* @@end */

/* @@generated:epilogue */
/* --- the epilogue: the loop. Once, after the pass and the drag, then hold. ---
   Percentages are of 11.5376s (27.25 beats). Sessions run 3, 2, 1.5, 1 beats,
   then twelve as pairs of frames — lit, then agreed — six at 3/8 of a beat
   a frame and six at 3/16, then a beat of black, then the punch.
   Generated — see the note above .hero-reel. */
.reel .s-e,
.reel .e-base,
.reel .e-shot,
.reel .e-wrong,
.reel .e-punch,
.reel .e-w,
.reel .e-to,
.reel .e-card-line,
.reel .e-card-ruler rect,
.reel .e-blast,
.reel .e-ring,
.reel .e-mark {
  animation-duration: 11.5376s;
  animation-timing-function: steps(1, end);
  animation-delay: calc(var(--reel-pro) + var(--reel-loop) + var(--reel-shoot) + var(--reel-drag));
  animation-iteration-count: 1;
  animation-fill-mode: forwards;      /* not both: nothing shows before its turn */
}
.reel .s-e     { animation-name: reel-e-vis; }
.reel .e-shot  { opacity: 0; }
.reel .e-base  { animation-name: reel-e-base; }
.reel .e-punch { animation-name: reel-e-punch; animation-timing-function: linear;
                 transform-box: view-box; transform-origin: 50%% 50%%; }
@keyframes reel-e-vis  { 0% { opacity: 1; } 100% { opacity: 1; } }
/* the labels you / notchframe go with the sessions, not the final */
@keyframes reel-e-base { 0% { opacity: 1; } 52.29% { opacity: 0; } 100% { opacity: 0; } }
.reel .e-shot-c0 { animation-name: reel-e-c0; }
@keyframes reel-e-c0 { 0% { opacity: 0; } 0.00% { opacity: 1; } 11.01% { opacity: 0; } 100% { opacity: 0; } }
.reel .e-wrong-c0 { animation-name: reel-e-wrong-c0; }
@keyframes reel-e-wrong-c0 { 0% { opacity: 1; } 5.50% { opacity: 0; } 100% { opacity: 0; } }
.reel .e-shot-c1 { animation-name: reel-e-c1; }
@keyframes reel-e-c1 { 0% { opacity: 0; } 11.01% { opacity: 1; } 18.35% { opacity: 0; } 100% { opacity: 0; } }
.reel .e-wrong-c1 { animation-name: reel-e-wrong-c1; }
@keyframes reel-e-wrong-c1 { 0% { opacity: 1; } 14.68% { opacity: 0; } 100% { opacity: 0; } }
.reel .e-shot-c2 { animation-name: reel-e-c2; }
@keyframes reel-e-c2 { 0% { opacity: 0; } 18.35% { opacity: 1; } 23.85% { opacity: 0; } 100% { opacity: 0; } }
.reel .e-wrong-c2 { animation-name: reel-e-wrong-c2; }
@keyframes reel-e-wrong-c2 { 0% { opacity: 1; } 21.10% { opacity: 0; } 100% { opacity: 0; } }
.reel .e-shot-c3 { animation-name: reel-e-c3; }
@keyframes reel-e-c3 { 0% { opacity: 0; } 23.85% { opacity: 1; } 27.52% { opacity: 0; } 100% { opacity: 0; } }
.reel .e-shot-f0 { animation-name: reel-e-f0; }
@keyframes reel-e-f0 { 0% { opacity: 0; } 27.52% { opacity: 1; } 30.28% { opacity: 0; } 100% { opacity: 0; } }
.reel .e-wrong-f0 { animation-name: reel-e-wrong-f0; }
@keyframes reel-e-wrong-f0 { 0% { opacity: 1; } 28.90% { opacity: 0; } 100% { opacity: 0; } }
.reel .e-shot-f1 { animation-name: reel-e-f1; }
@keyframes reel-e-f1 { 0% { opacity: 0; } 30.28% { opacity: 1; } 33.03% { opacity: 0; } 100% { opacity: 0; } }
.reel .e-wrong-f1 { animation-name: reel-e-wrong-f1; }
@keyframes reel-e-wrong-f1 { 0% { opacity: 1; } 31.65% { opacity: 0; } 100% { opacity: 0; } }
.reel .e-shot-f2 { animation-name: reel-e-f2; }
@keyframes reel-e-f2 { 0% { opacity: 0; } 33.03% { opacity: 1; } 35.78% { opacity: 0; } 100% { opacity: 0; } }
.reel .e-wrong-f2 { animation-name: reel-e-wrong-f2; }
@keyframes reel-e-wrong-f2 { 0% { opacity: 1; } 34.40% { opacity: 0; } 100% { opacity: 0; } }
.reel .e-shot-f3 { animation-name: reel-e-f3; }
@keyframes reel-e-f3 { 0% { opacity: 0; } 35.78% { opacity: 1; } 38.53% { opacity: 0; } 100% { opacity: 0; } }
.reel .e-wrong-f3 { animation-name: reel-e-wrong-f3; }
@keyframes reel-e-wrong-f3 { 0% { opacity: 1; } 37.16% { opacity: 0; } 100% { opacity: 0; } }
.reel .e-shot-f4 { animation-name: reel-e-f4; }
@keyframes reel-e-f4 { 0% { opacity: 0; } 38.53% { opacity: 1; } 41.28% { opacity: 0; } 100% { opacity: 0; } }
.reel .e-wrong-f4 { animation-name: reel-e-wrong-f4; }
@keyframes reel-e-wrong-f4 { 0% { opacity: 1; } 39.91% { opacity: 0; } 100% { opacity: 0; } }
.reel .e-shot-f5 { animation-name: reel-e-f5; }
@keyframes reel-e-f5 { 0% { opacity: 0; } 41.28% { opacity: 1; } 44.04% { opacity: 0; } 100% { opacity: 0; } }
.reel .e-wrong-f5 { animation-name: reel-e-wrong-f5; }
@keyframes reel-e-wrong-f5 { 0% { opacity: 1; } 42.66% { opacity: 0; } 100% { opacity: 0; } }
.reel .e-shot-f6 { animation-name: reel-e-f6; }
@keyframes reel-e-f6 { 0% { opacity: 0; } 44.04% { opacity: 1; } 45.41% { opacity: 0; } 100% { opacity: 0; } }
.reel .e-wrong-f6 { animation-name: reel-e-wrong-f6; }
@keyframes reel-e-wrong-f6 { 0% { opacity: 1; } 44.72% { opacity: 0; } 100% { opacity: 0; } }
.reel .e-shot-f7 { animation-name: reel-e-f7; }
@keyframes reel-e-f7 { 0% { opacity: 0; } 45.41% { opacity: 1; } 46.79% { opacity: 0; } 100% { opacity: 0; } }
.reel .e-wrong-f7 { animation-name: reel-e-wrong-f7; }
@keyframes reel-e-wrong-f7 { 0% { opacity: 1; } 46.10% { opacity: 0; } 100% { opacity: 0; } }
.reel .e-shot-f8 { animation-name: reel-e-f8; }
@keyframes reel-e-f8 { 0% { opacity: 0; } 46.79% { opacity: 1; } 48.17% { opacity: 0; } 100% { opacity: 0; } }
.reel .e-wrong-f8 { animation-name: reel-e-wrong-f8; }
@keyframes reel-e-wrong-f8 { 0% { opacity: 1; } 47.48% { opacity: 0; } 100% { opacity: 0; } }
.reel .e-shot-f9 { animation-name: reel-e-f9; }
@keyframes reel-e-f9 { 0% { opacity: 0; } 48.17% { opacity: 1; } 49.54% { opacity: 0; } 100% { opacity: 0; } }
.reel .e-wrong-f9 { animation-name: reel-e-wrong-f9; }
@keyframes reel-e-wrong-f9 { 0% { opacity: 1; } 48.85% { opacity: 0; } 100% { opacity: 0; } }
.reel .e-shot-f10 { animation-name: reel-e-f10; }
@keyframes reel-e-f10 { 0% { opacity: 0; } 49.54% { opacity: 1; } 50.92% { opacity: 0; } 100% { opacity: 0; } }
.reel .e-wrong-f10 { animation-name: reel-e-wrong-f10; }
@keyframes reel-e-wrong-f10 { 0% { opacity: 1; } 50.23% { opacity: 0; } 100% { opacity: 0; } }
.reel .e-shot-f11 { animation-name: reel-e-f11; }
@keyframes reel-e-f11 { 0% { opacity: 0; } 50.92% { opacity: 1; } 52.29% { opacity: 0; } 100% { opacity: 0; } }
.reel .e-wrong-f11 { animation-name: reel-e-wrong-f11; }
@keyframes reel-e-wrong-f11 { 0% { opacity: 1; } 51.61% { opacity: 0; } 100% { opacity: 0; } }
.reel .e-shot-final { animation-name: reel-e-final; }
@keyframes reel-e-final { 0% { opacity: 0; } 55.96% { opacity: 1; } 63.30% { opacity: 0; } 100% { opacity: 0; } }
/* the end card: hard cut to black, then a word every half beat. The last
   word comes in sideways in the disagreement colour, tries to right itself,
   fails, and then lands — white — with the spark. */
.reel .e-shot-card { animation-name: reel-e-card; }
@keyframes reel-e-card { 0% { opacity: 0; } 63.30% { opacity: 1; } 100% { opacity: 1; } }
.reel .e-w { fill-opacity: 0; }
.reel .e-w0 { animation-name: reel-e-w0; }
@keyframes reel-e-w0 { 0% { fill-opacity: 0; } 63.30% { fill-opacity: 1; } 100% { fill-opacity: 1; } }
.reel .e-w1 { animation-name: reel-e-w1; }
@keyframes reel-e-w1 { 0% { fill-opacity: 0; } 65.14% { fill-opacity: 1; } 100% { fill-opacity: 1; } }
.reel .e-w2 { animation-name: reel-e-w2; }
@keyframes reel-e-w2 { 0% { fill-opacity: 0; } 66.97% { fill-opacity: 1; } 100% { fill-opacity: 1; } }
.reel .e-w3 { animation-name: reel-e-w3; }
@keyframes reel-e-w3 { 0% { fill-opacity: 0; } 68.81% { fill-opacity: 1; } 100% { fill-opacity: 1; } }
.reel .e-w4 { animation-name: reel-e-w4; }
@keyframes reel-e-w4 { 0% { fill-opacity: 0; } 70.64% { fill-opacity: 1; } 100% { fill-opacity: 1; } }
.reel .e-w5 { animation-name: reel-e-w5; }
@keyframes reel-e-w5 { 0% { fill-opacity: 0; } 72.48% { fill-opacity: 1; } 100% { fill-opacity: 1; } }
.reel .e-w6 { animation-name: reel-e-w6; }
@keyframes reel-e-w6 { 0% { fill-opacity: 0; } 74.31% { fill-opacity: 1; } 100% { fill-opacity: 1; } }
.reel .e-w7 { animation-name: reel-e-w7; }
@keyframes reel-e-w7 { 0% { fill-opacity: 0; } 76.15% { fill-opacity: 1; } 100% { fill-opacity: 1; } }
.reel .e-w8 { animation-name: reel-e-w8; }
@keyframes reel-e-w8 { 0% { fill-opacity: 0; } 77.98% { fill-opacity: 1; } 100% { fill-opacity: 1; } }
.reel .e-to { opacity: 0; transform-box: fill-box; transform-origin: 50%% 50%%;
              animation-name: reel-e-to; animation-timing-function: linear; }
@keyframes reel-e-to {
  0%, 79.78%  { opacity: 0; transform: rotate(90deg); fill: var(--reel-accent); }
  79.82%       { opacity: 1; transform: rotate(90deg); fill: var(--reel-accent); }
  83.49%       { opacity: 1; transform: rotate(90deg); fill: var(--reel-accent); animation-timing-function: var(--ease-snap); }
  84.40%       { opacity: 1; transform: rotate(16deg); fill: var(--reel-accent); }
  85.69%       { opacity: 1; transform: rotate(16deg); fill: var(--reel-accent); animation-timing-function: cubic-bezier(0.5, 0, 0.9, 0.6); }
  86.79%       { opacity: 1; transform: rotate(52deg); fill: var(--reel-accent); }
  90.83%       { opacity: 1; transform: rotate(52deg); fill: var(--reel-accent); animation-timing-function: var(--ease-snap); }
  91.38%       { opacity: 1; transform: rotate(-5deg); fill: #fff; animation-timing-function: var(--ease-snap); }
  92.11%       { opacity: 1; transform: rotate(0deg); fill: #fff; }
  92.40%       { opacity: 1; transform: rotate(0deg); fill: var(--black); }
  100%     { opacity: 1; transform: rotate(0deg); fill: var(--black); }
}
/* the blast: black ripples out, gold ripples in, from where a spark would
   have been. The disc is the gold; the rings are the black leaving. The
   words go to ink as it passes them. */
.reel .e-blast { r: 0; animation-name: reel-e-blast; animation-timing-function: linear; }
.reel .e-ring  { r: 0; fill: none; stroke: var(--black); opacity: 0; animation-timing-function: linear; }
.reel .e-ring1 { stroke-width: 44; animation-name: reel-e-ring1; }
.reel .e-ring2 { stroke-width: 22; animation-name: reel-e-ring2; }
@keyframes reel-e-blast {
  0%, 92.11% { r: 0; animation-timing-function: cubic-bezier(0.1, 0.9, 0.2, 1); }
  93.58%      { r: 3300px; }
  100%    { r: 3300px; }
}
@keyframes reel-e-ring1 {
  0%, 92.11% { r: 0; opacity: 1; animation-timing-function: cubic-bezier(0.1, 0.9, 0.2, 1); }
  93.76%      { r: 3400px; opacity: 1; animation-timing-function: linear; }
  94.31%      { r: 3600px; opacity: 0; }
  100%    { r: 3600px; opacity: 0; }
}
@keyframes reel-e-ring2 {
  0%, 92.55% { r: 0; opacity: 0; }
  92.59%      { r: 0; opacity: 0.7; animation-timing-function: cubic-bezier(0.2, 0.8, 0.3, 1); }
  94.86%      { r: 3400px; opacity: 0.7; animation-timing-function: linear; }
  95.60%      { r: 3600px; opacity: 0; }
  100%    { r: 3600px; opacity: 0; }
}
.reel .e-card-line       { animation-name: reel-e-ink; }
.reel .e-card-ruler rect { animation-name: reel-e-ink; }
@keyframes reel-e-ink { 0% { } 92.40% { fill: var(--black); } 100% { fill: var(--black); } }
/* and last of all, the mark, with a pop */
.reel .e-mark { opacity: 0; transform-box: fill-box; transform-origin: 50%% 50%%;
                animation-name: reel-e-mark; animation-timing-function: linear; }
@keyframes reel-e-mark {
  0%, 94.46% { opacity: 0; transform: scale(0.6); }
  94.50%      { opacity: 1; transform: scale(1.35); animation-timing-function: var(--ease-snap); }
  95.60%      { opacity: 1; transform: scale(1); }
  100%    { opacity: 1; transform: scale(1); }
}
@keyframes reel-e-punch {
  0%, 55.96% { transform: scale(3.6); filter: blur(56px); animation-timing-function: var(--ease-snap); }
  56.69% { transform: scale(1.06); filter: blur(0); animation-timing-function: linear; }
  100% { transform: scale(1); filter: blur(0); }
}
/* @@end */

/* @@generated:prologue */
/* --- the prologue: a montage at the desk, then into the screen ---
   Seven shots, a beat and a half each, hard cuts between them; a camera
   push into the monitor at the end. Runs once. Percentages are of
   5.1641s (12 beats plus shot one's slam, which this holds over),
   and are generated — see the note above .hero-reel. */
.reel .s-pro { opacity: 1; }
.reel .s-pro,
.reel .p-pro,
.reel .pro-shot,
.reel .pro-hand,
.reel .pro-scrub,
.reel .pro-eye-open,
.reel .pro-eye-shut,
.reel .pro-jit,
.reel .pro-figure,
.reel .pro-head,
.reel .pro-hair {
  animation-duration: 5.1641s;
  animation-timing-function: steps(1, end);
  animation-iteration-count: 1;
  animation-fill-mode: forwards;
}
.reel .pro-shot        { opacity: 0; }
.reel .s-pro           { animation-name: reel-pro-vis; }
.reel .pro-shot-wide   { animation-name: reel-pro-shot-wide; }
.reel .pro-shot-hand   { animation-name: reel-pro-shot-hand; }
.reel .pro-shot-screen { animation-name: reel-pro-shot-screen; }
.reel .pro-shot-eye    { animation-name: reel-pro-shot-eye; }
.reel .pro-hand        { animation-name: reel-pro-mouse; }
.reel .pro-scrub       { animation-name: reel-pro-scrub; }
.reel .pro-eye-open    { animation-name: reel-pro-blink-open; }
.reel .pro-eye-shut    { animation-name: reel-pro-blink-shut; opacity: 0; }
.reel .pro-jit         { animation-name: reel-pro-jitter; }
.reel .pro-figure      { animation-name: reel-pro-lean; animation-timing-function: linear; }
.reel .pro-head        { animation-name: reel-pro-head; animation-timing-function: linear; }
.reel .pro-hair        { animation-name: reel-pro-hair; animation-timing-function: linear;
                          transform-box: view-box; transform-origin: 1300px 330px; }
.reel .p-pro {
  animation-name: reel-pro-push;
  animation-timing-function: linear;
  transform-box: view-box;
  transform-origin: 2680px 560px;
}

/* which shot is up: wide / hand / screen / hand / eye (held) / screen / wide */
@keyframes reel-pro-shot-wide   { 0% { opacity: 1; } 12.30% { opacity: 0; } 73.79% { opacity: 1; } 100% { opacity: 1; } }
@keyframes reel-pro-shot-hand   { 0% { opacity: 0; } 12.30% { opacity: 1; } 24.60% { opacity: 0; } 36.90% { opacity: 1; } 49.19% { opacity: 0; } 100% { opacity: 0; } }
@keyframes reel-pro-shot-screen { 0% { opacity: 0; } 24.60% { opacity: 1; } 36.90% { opacity: 0; } 67.64% { opacity: 1; } 73.79% { opacity: 0; } 100% { opacity: 0; } }
@keyframes reel-pro-shot-eye    { 0% { opacity: 0; } 49.19% { opacity: 1; } 67.64% { opacity: 0; } 100% { opacity: 0; } }

/* the mouse goes right on beat 3 and back left on beat 7. The hand and the
   screen close-ups are cut against each other, so the playhead follows it:
   right on beat 5, back on beat 11 */
@keyframes reel-pro-mouse { 0% { transform: translateX(0); } 18.45% { transform: translateX(520px); } 43.04% { transform: translateX(-360px); } 100% { transform: translateX(-360px); } }
@keyframes reel-pro-scrub { 0% { transform: translateX(0); } 30.75% { transform: translateX(900px); } 67.64% { transform: translateX(-400px); } 100% { transform: translateX(-400px); } }

/* the eye holds three beats, not two — he's focused; one blink, late in it */
@keyframes reel-pro-blink-open { 0% { opacity: 1; } 61.49% { opacity: 0; } 63.34% { opacity: 1; } 100% { opacity: 1; } }
@keyframes reel-pro-blink-shut { 0% { opacity: 0; } 61.49% { opacity: 1; } 63.34% { opacity: 0; } 100% { opacity: 0; } }

/* stop-motion registration wobble, every half beat, in the wide */
@keyframes reel-pro-jitter {
  0% { transform: translate(0, 0); } 3.07% { transform: translate(5px, -3px); }
  6.15% { transform: translate(0, 0); } 9.22% { transform: translate(-4px, 2px); }
  12.30% { transform: translate(0, 0); }
  73.79% { transform: translate(0, 0); } 76.86% { transform: translate(5px, -2px); }
  79.94% { transform: translate(0, 0); } 83.01% { transform: translate(-3px, 3px); }
  86.09% { transform: translate(0, 0); } 89.16% { transform: translate(4px, -3px); }
  100% { transform: translate(0, 0); }
}
/* beats 13 to 14.6: he leans in to the screen — a real move, not a step:
   the body goes, the head goes further and dips, and the hair trails behind
   the head then settles. The camera creeps in with him (see the push). */
@keyframes reel-pro-lean {
  0%, 79.94% { transform: translate(0, 0); animation-timing-function: cubic-bezier(0.45, 0, 0.15, 1); }
  89.78%   { transform: translate(150px, 34px); }
  100%        { transform: translate(150px, 34px); }
}
@keyframes reel-pro-head {
  0%, 79.94% { transform: translate(0, 0) rotate(0deg); animation-timing-function: cubic-bezier(0.45, 0, 0.15, 1); }
  89.78%   { transform: translate(120px, 46px) rotate(4deg); }
  100%        { transform: translate(120px, 46px) rotate(4deg); }
}
@keyframes reel-pro-hair {
  0%          { transform: rotate(0deg); animation-timing-function: ease-in-out; }
  6.15%      { transform: rotate(1.4deg); animation-timing-function: ease-in-out; }
  12.30%      { transform: rotate(0deg); }
  73.79%     { transform: rotate(0deg); animation-timing-function: ease-in-out; }
  77.48%   { transform: rotate(-1.2deg); animation-timing-function: ease-in-out; }
  79.94%     { transform: rotate(0deg); animation-timing-function: cubic-bezier(0.3, 0, 0.7, 1); }
  83.01%   { transform: rotate(-7deg); animation-timing-function: cubic-bezier(0.3, 0, 0.5, 1); }
  89.78%   { transform: rotate(-3deg); animation-timing-function: ease-in-out; }
  92.24%     { transform: rotate(0deg); }
  100%        { transform: rotate(0deg); }
}

/* beat 15 -> 16: the camera pushes into the monitor. Scale 4 is exactly the
   screen filling the frame, and the screen is showing shot one at quarter
   scale, so the frame this lands on IS shot one. It then holds over shot
   one's own two-frame slam and drops out. */
@keyframes reel-pro-push {
  0%, 76.86% { transform: scale(1); filter: blur(0); animation-timing-function: cubic-bezier(0.4, 0, 0.6, 1); }
  92.24%     { transform: scale(1.12); filter: blur(0); animation-timing-function: cubic-bezier(0.55, 0, 1, 0.45); }
  95.31%   { transform: scale(2); filter: blur(14px); animation-timing-function: cubic-bezier(0, 0.55, 0.45, 1); }
  98.39%     { transform: scale(4); filter: blur(0); }
  100%        { transform: scale(4); filter: blur(0); }
}
@keyframes reel-pro-vis { 0% { opacity: 1; } 100% { opacity: 0; } }
/* @@end */

/* @@generated:flare */
/* --- geometric flare: pops of shape on the cuts, over the whole reel. ---
   Percentages are of the whole piece, 37.7884s (89.25 beats). Each pop is half a
   beat. Generated — see the note above .hero-reel. */
.reel .s-x { opacity: 1; pointer-events: none; }
.reel .x { opacity: 0; transform-box: fill-box; transform-origin: center;
           animation-duration: 37.7884s; animation-timing-function: linear;
           animation-iteration-count: 1; animation-fill-mode: forwards; }
.reel .x-ring { fill: none; stroke-width: 16px; }
.reel .x-ring.c-paper { stroke: #fff; } .reel .x-ring.c-accent { stroke: var(--reel-accent); } .reel .x-ring.c-gold { stroke: #ffc53d; }
.reel .x-0 { animation-name: reel-x-0; }
@keyframes reel-x-0 { 0%, 1.669% { opacity: 0; transform: scale(0.2); } 1.681% { opacity: 1; transform: scale(0.2); animation-timing-function: cubic-bezier(0.2, 0.8, 0.2, 1); } 2.241% { opacity: 0; transform: scale(1.8); } 100% { opacity: 0; transform: scale(1.8); } }
.reel .x-1 { animation-name: reel-x-1; }
@keyframes reel-x-1 { 0%, 6.711% { opacity: 0; transform: scale(0.2) rotate(-60deg); } 6.723% { opacity: 1; transform: scale(0.2) rotate(-60deg); animation-timing-function: var(--ease-snap); } 6.924% { opacity: 1; transform: scale(1) rotate(0deg); animation-timing-function: ease-in; } 7.283% { opacity: 0; transform: scale(0.6) rotate(40deg); } 100% { opacity: 0; transform: scale(0.6) rotate(40deg); } }
.reel .x-2 { animation-name: reel-x-2; }
@keyframes reel-x-2 { 0%, 13.434% { opacity: 0; transform: scale(0.2); } 13.445% { opacity: 1; transform: scale(0.2); animation-timing-function: cubic-bezier(0.2, 0.8, 0.2, 1); } 14.006% { opacity: 0; transform: scale(1.8); } 100% { opacity: 0; transform: scale(1.8); } }
.reel .x-3 { animation-name: reel-x-3; }
@keyframes reel-x-3 { 0%, 22.398% { opacity: 0; transform: scale(0.3) rotate(0deg); } 22.409% { opacity: 1; transform: scale(0.3) rotate(0deg); animation-timing-function: var(--ease-snap); } 22.611% { opacity: 1; transform: scale(1) rotate(45deg); animation-timing-function: ease-in; } 22.969% { opacity: 0; transform: scale(1.3) rotate(90deg); } 100% { opacity: 0; transform: scale(1.3) rotate(90deg); } }
.reel .x-4 { animation-name: reel-x-4; }
@keyframes reel-x-4 { 0%, 31.361% { opacity: 0; transform: scale(0.2) rotate(-60deg); } 31.373% { opacity: 1; transform: scale(0.2) rotate(-60deg); animation-timing-function: var(--ease-snap); } 31.574% { opacity: 1; transform: scale(1) rotate(0deg); animation-timing-function: ease-in; } 31.933% { opacity: 0; transform: scale(0.6) rotate(40deg); } 100% { opacity: 0; transform: scale(0.6) rotate(40deg); } }
.reel .x-5 { animation-name: reel-x-5; }
@keyframes reel-x-5 { 0%, 33.602% { opacity: 0; transform: scale(0.2); } 33.613% { opacity: 1; transform: scale(0.2); animation-timing-function: cubic-bezier(0.2, 0.8, 0.2, 1); } 34.174% { opacity: 0; transform: scale(1.8); } 100% { opacity: 0; transform: scale(1.8); } }
.reel .x-6 { animation-name: reel-x-6; }
@keyframes reel-x-6 { 0%, 35.283% { opacity: 0; transform: scale(0.3) rotate(0deg); } 35.294% { opacity: 1; transform: scale(0.3) rotate(0deg); animation-timing-function: var(--ease-snap); } 35.496% { opacity: 1; transform: scale(1) rotate(45deg); animation-timing-function: ease-in; } 35.854% { opacity: 0; transform: scale(1.3) rotate(90deg); } 100% { opacity: 0; transform: scale(1.3) rotate(90deg); } }
.reel .x-7 { animation-name: reel-x-7; }
@keyframes reel-x-7 { 0%, 38.644% { opacity: 0; transform: scale(0.2) rotate(-60deg); } 38.655% { opacity: 1; transform: scale(0.2) rotate(-60deg); animation-timing-function: var(--ease-snap); } 38.857% { opacity: 1; transform: scale(1) rotate(0deg); animation-timing-function: ease-in; } 39.216% { opacity: 0; transform: scale(0.6) rotate(40deg); } 100% { opacity: 0; transform: scale(0.6) rotate(40deg); } }
.reel .x-8 { animation-name: reel-x-8; }
@keyframes reel-x-8 { 0%, 53.926% { opacity: 0; transform: scale(0.2); } 53.937% { opacity: 1; transform: scale(0.2); animation-timing-function: cubic-bezier(0.2, 0.8, 0.2, 1); } 54.497% { opacity: 0; transform: scale(1.8); } 100% { opacity: 0; transform: scale(1.8); } }
.reel .x-9 { animation-name: reel-x-9; }
@keyframes reel-x-9 { 0%, 58.252% { opacity: 0; transform: scale(0.2); } 58.263% { opacity: 1; transform: scale(0.2); animation-timing-function: cubic-bezier(0.2, 0.8, 0.2, 1); } 58.824% { opacity: 0; transform: scale(1.8); } 100% { opacity: 0; transform: scale(1.8); } }
.reel .x-10 { animation-name: reel-x-10; }
@keyframes reel-x-10 { 0%, 69.457% { opacity: 0; transform: scale(0.2) rotate(-60deg); } 69.468% { opacity: 1; transform: scale(0.2) rotate(-60deg); animation-timing-function: var(--ease-snap); } 69.669% { opacity: 1; transform: scale(1) rotate(0deg); animation-timing-function: ease-in; } 70.028% { opacity: 0; transform: scale(0.6) rotate(40deg); } 100% { opacity: 0; transform: scale(0.6) rotate(40deg); } }
.reel .x-11 { animation-name: reel-x-11; }
@keyframes reel-x-11 { 0%, 79.541% { opacity: 0; transform: scale(0.3) rotate(0deg); } 79.552% { opacity: 1; transform: scale(0.3) rotate(0deg); animation-timing-function: var(--ease-snap); } 79.754% { opacity: 1; transform: scale(1) rotate(45deg); animation-timing-function: ease-in; } 80.112% { opacity: 0; transform: scale(1.3) rotate(90deg); } 100% { opacity: 0; transform: scale(1.3) rotate(90deg); } }
/* @@end */

/* ============ Bands & blocks ============ */
.band { padding: 24px 0; }
.band:last-of-type { padding-bottom: 72px; }

.block {
  background: #fff;
  border: 1px solid var(--divider-muted);
  border-radius: var(--radius-block);
  overflow: hidden;
}
.block-label {
  padding: 18px 40px;
  border-bottom: 1px solid var(--divider-muted);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.block-intro { padding: 72px 40px 64px; max-width: 780px; }
.block-intro h2 { margin-bottom: 20px; }
.block-lede { font-size: 1.08rem; margin-bottom: 28px; }
.block-intro .btn-outline { margin-top: 4px; }
.block-body { padding: 48px 40px; border-top: 1px solid var(--divider-muted); }
/* Whatever you're into: copy beside a phone-shaped panel of rapid footage */
/* the people it's for — set like the business card: a line of intent, then
   the list in three straight columns of plain text, and one word on its own
   line beneath, the only one in a pill: you */
/* one line on how it learns, under the grid */

/* hairline cell grids — one continuous surface, not floating cards */
.cell-grid {
  display: grid;
  gap: 1px;
  background: var(--divider-muted);
  border-top: 1px solid var(--divider-muted);
}
.cell-grid-2 { grid-template-columns: repeat(2, 1fr); }
.cell { background: #fff; padding: 34px 32px; }
.cell h3 { margin-bottom: 8px; }
.cell p { font-size: 0.89rem; }
.cell-head {
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--black);
  padding-bottom: 14px;
  border-bottom: 1px solid var(--divider-muted);
  margin-bottom: 6px;
}
.cell-head-muted { color: var(--text-muted); }

/* fit grid: three columns, a three-dot strength in each head, and a plain
   list beneath — the third column deliberately not sugar-coated */

/* how to use it: four moves in a row, the number outlined behind each */

/* the profile in three beats above the chart: keyword, one line, an arrow
   between them on wide screens */

/* from a reference: three cards in a row, a tag on each; the first holds a
   little strip, the second the card of what was read, the third the
   correction */
/* the reference itself, as the reel draws a cut: keeps in red, filler dim */

/* big result figures inside a cell */

/* ============ Compare lists ============ */
.compare-list { list-style: none; }
.compare-list li {
  position: relative;
  padding: 11px 0 11px 26px;
  font-size: 0.93rem;
  color: var(--text-muted);
  border-bottom: 1px solid var(--divider-muted);
}
.compare-list li:last-child { border-bottom: none; }
.compare-list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 18px;
  width: 11px;
  height: 1.5px;
  background: var(--gray4);
}
.compare-list-after li { color: var(--text); }
.compare-list-after li::before {
  top: 15px;
  width: 13px;
  height: 13px;
  background: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23111418' stroke-width='3.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 13l5 5L20 6'/%3E%3C/svg%3E");
  background-size: contain;
  background-repeat: no-repeat;
}

/* one quiet row under the first-pass compare, not a second hero */
.pass-cta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 16px 24px;
  padding: 28px 40px;
  background: #fff;
  border-top: 1px solid var(--divider-muted);
}
.pass-cta p {
  margin: 0;
  color: var(--text);
  font-weight: 500;
}
.pass-cta-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

.fic {
  width: 22px;
  height: 22px;
  fill: none;
  stroke: var(--black);
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
  margin-bottom: 14px;
}

/* ============ Ask an AI (in the footer) ============ */
.ask-btn {
  display: grid;
  place-items: center;
  width: 42px;
  height: 42px;
  border: 1px solid var(--divider-muted);
  border-radius: var(--radius-pill);
  background: #fff;
  transition: border-color var(--dur) var(--ease), transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.ask-btn:hover {
  border-color: #fff;
  transform: translateY(-2px);
  box-shadow: 0 6px 14px rgba(0, 0, 0, 0.35);
}
/* the real marks are filled logotypes, not line drawings */
.ask-ic {
  display: block;
  width: 20px;
  height: 20px;
  stroke: none;
}
/* each mark in its own brand colour */
.ic-chatgpt { fill: #0d0d0d; }
.ic-claude { fill: #d97757; }
.ic-perplexity { fill: #20808d; }
.ic-grok { fill: #000000; }
.ic-gemini { width: 21px; height: 21px; }  /* gradient fill is on the path */
.ic-google { width: 19px; height: 19px; }  /* the G reads heavier — trim it back */

/* clipboard confirmation */
.ask-toast {
  position: fixed;
  left: 50%;
  bottom: 26px;
  transform: translate(-50%, 14px);
  z-index: 60;
  background: var(--black);
  color: #fff;
  font-size: 0.86rem;
  font-weight: 500;
  padding: 11px 20px;
  border-radius: var(--radius-pill);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.22);
  opacity: 0;
  pointer-events: none;
  transition: opacity 180ms var(--ease), transform 180ms var(--ease);
}
.ask-toast.show { opacity: 1; transform: translate(-50%, 0); }

/* ============ Colour ============ */
/* The one place on the site that carries colour, and the stage is what spends
   it. Pitched around the red already sampled from the logo mark (--brand,
   #d0021a) so the colour reads as ours rather than borrowed. The plum is
   deliberate: an all-red field goes flat, and it holds the depth. */
:root {
  --mesh-1: #ff6f4e;   /* warm scarlet, the lift */
  --mesh-2: #e01b32;   /* close to --brand, the anchor */
  --mesh-3: #8d2246;   /* deep plum, the shadow side */
}
/* ============ Getting started — the stage ============ */
/* Three beats on a dark panel instead of three paragraphs beside a spec table.
   The information is the same; what changed is that you watch it arrive rather
   than read it. Colour comes from the mesh tokens, dropped onto black. */
.stage {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  border-top: 1px solid var(--divider-muted);
  background: #0b0d11;
}
.stage-bg {
  position: absolute;
  inset: -30%;
  z-index: 0;
  opacity: 0.5;
  filter: blur(26px);
  background:
    radial-gradient(30% 40% at 20% 24%, var(--mesh-1) 0%, transparent 60%),
    radial-gradient(34% 46% at 74% 18%, var(--mesh-2) 0%, transparent 62%),
    radial-gradient(42% 52% at 66% 92%, var(--mesh-3) 0%, transparent 64%),
    radial-gradient(28% 36% at 8% 86%, var(--mesh-2) 0%, transparent 58%);
  animation: stageDrift 30s var(--ease) infinite alternate;
}
@keyframes stageDrift {
  from { transform: scale(1.05) translate3d(2%, 1%, 0); }
  to   { transform: scale(1.25) translate3d(-4%, -3%, 0); }
}
/* the same grain as the mesh panel — it's what keeps a big gradient from
   reading as a stock background */
.stage::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  opacity: 0.16;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}
.stage-inner { position: relative; z-index: 1; padding: 72px 40px 60px; }

/* Move 2 from the reference: the headline doesn't fade up, a bright bar travels
   across it and leaves it lit. The gradient under background-clip does the
   reveal — white on its left half, near-dark on its right — and sliding it
   right-to-left walks the boundary across the words. ::after is the bar itself,
   blurred and brighter than the type it's uncovering.
   color: transparent would hide the text outright where background-clip isn't
   supported, so the whole treatment sits behind @supports and the plain rule
   below is a lit headline. */
.stage-head {
  position: relative;
  color: #fff;
  max-width: 16ch;
  margin-bottom: 18px;
}
.stage-lede {
  color: rgba(255, 255, 255, 0.62);
  font-size: 1.08rem;
  max-width: 46ch;
  margin-bottom: 56px;
}

@supports ((-webkit-background-clip: text) or (background-clip: text)) {
  .stage.in .stage-head {
    background-image: linear-gradient(
      100deg,
      #fff 0%,
      #fff 44%,
      rgba(255, 255, 255, 0.15) 57%,
      rgba(255, 255, 255, 0.15) 100%
    );
    background-size: 260% 100%;
    background-repeat: no-repeat;
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
    -webkit-text-fill-color: transparent;
    animation: wipeIn 900ms var(--ease-snap) both;
  }
  .stage.in .stage-head::after {
    content: "";
    position: absolute;
    top: -0.12em;
    bottom: -0.12em;
    width: 86px;
    background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.9), transparent);
    filter: blur(10px);
    pointer-events: none;
    animation: wipeBar 900ms var(--ease-snap) both;
  }
}
@keyframes wipeIn {
  from { background-position: 100% 0; }
  to   { background-position: 0 0; }
}
@keyframes wipeBar {
  0%   { left: -30%; opacity: 0; }
  10%  { opacity: 1; }
  84%  { opacity: 1; }
  100% { left: 130%; opacity: 0; }
}

.stage-steps { list-style: none; display: grid; grid-template-columns: repeat(3, 1fr); }
.stage-steps li { position: relative; padding: 0 34px; }
.stage-steps li:first-child { padding-left: 0; }
.stage-steps li:last-child { padding-right: 0; }
.stage-steps li:not(:first-child)::before {
  content: "";
  position: absolute;
  left: 0;
  top: 4px;
  bottom: 4px;
  width: 1px;
  background: rgba(255, 255, 255, 0.14);
}
/* the number is the graphic, not a bullet — outlined so it sits behind the
   words rather than competing with them */
.step-num {
  display: block;
  margin-bottom: 20px;
  font-size: clamp(3.2rem, 6vw, 5rem);
  font-weight: 700;
  line-height: 0.85;
  letter-spacing: -0.05em;
  color: rgba(255, 255, 255, 0.1);
  -webkit-text-stroke: 1.5px rgba(255, 255, 255, 0.42);
}
.stage-steps h3 { color: #fff; font-size: 1.2rem; font-weight: 600; margin-bottom: 8px; }
.stage-steps p { color: rgba(255, 255, 255, 0.6); font-size: 0.95rem; }

/* what the spec table said, demoted to something you scan in one pass */
.stage-specs {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 54px;
  padding-top: 34px;
  border-top: 1px solid rgba(255, 255, 255, 0.12);
}
.stage-specs li {
  padding: 7px 16px;
  border: 1px solid rgba(255, 255, 255, 0.2);
  border-radius: var(--radius-pill);
  font-size: 0.82rem;
  font-weight: 500;
  color: rgba(255, 255, 255, 0.76);
  white-space: nowrap;
}
.stage-ctas { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 34px; }

/* Button skins for a dark ground. The /download/ href rule would paint these
   red; the hero / stage exceptions above keep them light on this panel. */
.btn-light { background: #fff; color: var(--black); border-color: #fff; }
.btn-light:hover { background: var(--lg3); border-color: var(--lg3); }
.btn-ghost { background: transparent; color: #fff; border-color: rgba(255, 255, 255, 0.32); }

/* The panel holds still and its contents perform — a whole-panel fade on top of
   the stagger just muddies both. Gated on .reveal, which the script adds, so
   nothing is stuck invisible without JavaScript. */
.stage.reveal { opacity: 1; transform: none; transition: none; }
.stage.reveal .stage-head,
.stage.reveal .stage-lede,
.stage.reveal .stage-steps li,
.stage.reveal .stage-specs li,
.stage.reveal .stage-ctas { opacity: 0; }
.stage.reveal .stage-steps li:not(:first-child)::before { transform: scaleY(0); transform-origin: top; }
.stage.in .stage-head { opacity: 1; }

/* The bar leads and everything else runs under it. Each beat starts before the
   one ahead of it has landed — the overlap is what makes it read as one move
   through the panel rather than five things taking turns. Whole sequence is
   1.48s; stretching it further just makes you wait. */
.stage.in .stage-lede { animation: stageIn 520ms var(--ease-snap) both; animation-delay: 240ms; }
.stage.in .stage-steps li { animation: stageIn 640ms var(--ease-snap) both; animation-delay: 360ms; }
.stage.in .stage-steps li:nth-child(2) { animation-delay: 470ms; }
.stage.in .stage-steps li:nth-child(3) { animation-delay: 580ms; }
.stage.in .stage-steps li:not(:first-child)::before { animation: ruleGrow 520ms var(--ease-snap) both; animation-delay: 400ms; }
.stage.in .stage-steps li:nth-child(3)::before { animation-delay: 510ms; }
.stage.in .step-num { animation: numIn 720ms var(--ease-snap) both; animation-delay: 360ms; }
.stage.in .stage-steps li:nth-child(2) .step-num { animation-delay: 470ms; }
.stage.in .stage-steps li:nth-child(3) .step-num { animation-delay: 580ms; }
.stage.in .stage-specs li { animation: chipIn 400ms var(--ease-snap) both; animation-delay: 700ms; }
.stage.in .stage-specs li:nth-child(2) { animation-delay: 745ms; }
.stage.in .stage-specs li:nth-child(3) { animation-delay: 790ms; }
.stage.in .stage-specs li:nth-child(4) { animation-delay: 835ms; }
.stage.in .stage-specs li:nth-child(5) { animation-delay: 880ms; }
.stage.in .stage-ctas { animation: stageIn 540ms var(--ease-snap) both; animation-delay: 940ms; }

/* Move 3 from the reference: a pending beat is receded, not absent. It holds at
   14% and slightly small until its turn, so freezing the animation mid-cascade
   shows one lit, one arriving and one still back in the dark — which is the
   effect. Starting from 0 would just be three things fading in. */
@keyframes stageIn {
  from { opacity: 0.14; transform: translateY(26px) scale(0.93); filter: blur(7px); }
  to   { opacity: 1; transform: none; filter: blur(0); }
}
@keyframes numIn {
  from { opacity: 0.2; transform: translateY(16px) scale(1.14); }
  to   { opacity: 1; transform: none; }
}
@keyframes ruleGrow {
  from { transform: scaleY(0); }
  to   { transform: scaleY(1); }
}
/* the same draw, for when the steps stack and the rules turn horizontal */
@keyframes ruleGrowX {
  from { transform: scaleX(0); }
  to   { transform: scaleX(1); }
}
@keyframes chipIn {
  from { opacity: 0; transform: translateY(10px) scale(0.94); }
  to   { opacity: 1; transform: none; }
}

.privacy-note { display: flex; gap: 18px; align-items: flex-start; background: var(--lg5); }
.privacy-note .fic { flex: none; margin-bottom: 0; }
.privacy-note h3 { margin-bottom: 6px; }
.privacy-note p { font-size: 0.91rem; max-width: 70ch; }

/* ============ FAQ ============ */
details { border-bottom: 1px solid var(--divider-muted); padding: 20px 2px; }
details:first-of-type { padding-top: 0; }
details:last-of-type { border-bottom: none; padding-bottom: 0; }
details summary {
  cursor: pointer;
  font-weight: 600;
  font-size: 1.02rem;
  color: var(--black);
  list-style: none;
  position: relative;
  padding-right: 34px;
}
details summary::-webkit-details-marker { display: none; }
details summary::after {
  content: "+";
  position: absolute;
  right: 2px;
  top: 50%;
  transform: translateY(-50%);
  color: var(--black);
  font-size: 1.4rem;
  font-weight: 400;
  transition: transform var(--dur) var(--ease);
}
details[open] summary::after { transform: translateY(-50%) rotate(45deg); }
details p { margin-top: 10px; font-size: 0.93rem; max-width: 78ch; }

/* ============ Support & feedback (support.html, feedback.html) ============ */
.help-list { list-style: none; margin-top: 22px; display: grid; gap: 8px; font-size: 0.9rem; color: var(--text-muted); }
.help-list li { position: relative; padding-left: 18px; }
.help-list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.62em;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--brand);
}
.help-note { margin-top: 22px; font-size: 0.86rem; color: var(--text-muted); }
.help-note a { color: var(--black); text-decoration: underline; text-underline-offset: 2px; }

.feedback-form { margin-top: 18px; display: grid; gap: 16px; }
/* script.js sets form.hidden once Netlify redirects back with ?sent=1 / ?joined=1.
   The `display: grid` above is an author rule and so beats the UA sheet's
   [hidden] { display: none } — without these two selectors the form stayed on
   screen with the thank-you stacked under it, reading as a failed submission. */
.feedback-form[hidden], .waitlist-form[hidden] { display: none; }
.field[hidden], .waitlist-for[hidden] { display: none; }
.feedback-form .hp, .waitlist-form .hp { position: absolute; left: -9999px; }
.field { display: grid; gap: 6px; }
.field label { font-size: 0.82rem; font-weight: 600; color: var(--black); }
.field-opt { font-weight: 400; color: var(--text-muted); }
.field input,
.field select,
.field textarea {
  width: 100%;
  font: inherit;
  font-size: 0.95rem;
  color: var(--text);
  background: #fff;
  border: 1px solid var(--divider);
  border-radius: 10px;
  padding: 11px 13px;
  transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.field textarea { resize: vertical; min-height: 120px; }
.field input:focus,
.field select:focus,
.field textarea:focus { outline: none; border-color: var(--black); box-shadow: 0 0 0 3px rgba(17, 20, 24, 0.12); }
/* ...but put the real ring back when the focus came from the keyboard: the
   border shift alone is about 1.1:1 against the resting state. */
.field input:focus-visible,
.field select:focus-visible,
.field textarea:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 3px; }
.field input::placeholder, .field textarea::placeholder { color: var(--gray4); }
.feedback-sent { margin-top: 18px; padding: 16px 18px; border-radius: 12px; background: var(--lg5); font-size: 0.95rem; }
.feedback-sent strong { color: var(--black); }

.cta-block {
  background: var(--lg4);
  border: 1px solid var(--divider-muted);
  border-radius: var(--radius-block);
  padding: 88px 40px;
  text-align: center;
}
.cta-block h2 { color: var(--black); }
.cta-lede { color: var(--text-muted); margin: 16px 0 34px; }

/* ============ Footer ============ */
/* the footer is the one black band at the foot of every page — the same ink
   as the buttons, the reel's ground and the getting-started stage */
.site-footer {
  background: var(--black);
  color: rgba(255, 255, 255, 0.72);
  border-top: 1px solid var(--black);
  margin-top: 48px;
  padding: 64px 0 40px;
}
.footer-top {
  display: flex;
  justify-content: space-between;
  gap: 64px;
  flex-wrap: wrap;
  padding-bottom: 44px;
}
.footer-brand { max-width: 260px; }
.footer-brand .brand-logo { margin-bottom: 16px; }
.footer-brand p { font-size: 0.88rem; color: rgba(255, 255, 255, 0.6); }
.footer-cols { display: flex; gap: 72px; flex-wrap: wrap; }
.footer-col { display: flex; flex-direction: column; gap: 10px; }
.footer-col h2 {
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.45);
  margin-bottom: 4px;
}
.footer-col a {
  font-size: 0.9rem;
  color: rgba(255, 255, 255, 0.86);
  transition: opacity var(--dur) var(--ease);
}
.footer-col a:hover { opacity: 0.6; }

.footer-ask {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  flex-wrap: wrap;
  padding: 26px 0;
  border-top: 1px solid rgba(255, 255, 255, 0.12);
  border-bottom: 1px solid rgba(255, 255, 255, 0.12);
}
.footer-ask-label {
  font-size: 0.86rem;
  font-weight: 500;
  color: rgba(255, 255, 255, 0.6);
}
.footer-ask-row { display: flex; gap: 10px; flex-wrap: wrap; }

.footer-bottom {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 16px;
  padding-top: 26px;
  font-size: 0.82rem;
  color: rgba(255, 255, 255, 0.55);
}
.footer-tag { color: rgba(255, 255, 255, 0.55); }
.footer-links { display: flex; align-items: center; gap: 22px; }
.footer-links a {
  color: rgba(255, 255, 255, 0.6);
  transition: color var(--dur) var(--ease);
}
.footer-links a:hover { color: #fff; }
.footer-inner {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: 0.82rem;
  color: var(--text-muted);
}

/* ============ Legal pages ============ */
.legal-page { padding: 64px 0 88px; }
.legal-wrap { max-width: 720px; }
.legal-wrap .microlabel { margin-bottom: 18px; }
.legal-wrap h1 { font-size: clamp(2rem, 4vw, 2.8rem); margin-bottom: 12px; }
.legal-updated { font-size: 0.85rem; color: var(--text-muted); margin-bottom: 40px; }
.legal-wrap h2 {
  font-size: 1.15rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  margin: 40px 0 12px;
}
.legal-wrap p { margin-bottom: 14px; line-height: 1.65; }
.legal-wrap ul { list-style: none; margin: 0 0 14px; }
.legal-wrap li {
  position: relative;
  padding-left: 22px;
  margin-bottom: 10px;
  color: var(--text-muted);
  line-height: 1.6;
}
.legal-wrap li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 11px;
  width: 9px;
  height: 1.5px;
  background: var(--gray4);
}
.legal-wrap a { text-decoration: underline; text-underline-offset: 2px; }
.legal-summary {
  background: #fff;
  border: 1px solid var(--divider-muted);
  border-radius: var(--radius-card);
  padding: 26px 28px;
  margin-bottom: 8px;
}
.legal-summary h2 { margin: 0 0 14px; font-size: 0.78rem; letter-spacing: 0.12em; text-transform: uppercase; color: var(--text-muted); }
.legal-summary ul { margin-bottom: 0; }
.legal-summary li:last-child { margin-bottom: 0; }
.legal-cross {
  margin-top: 48px;
  padding-top: 24px;
  border-top: 1px solid var(--divider-muted);
  font-size: 0.9rem;
}

/* ============ Notice pages ============ */
.notice-page { display: flex; align-items: center; min-height: calc(100vh - 70px - 90px); padding: 64px 0; }
.notice-wrap { max-width: 640px; }
.notice-wrap .microlabel { margin-bottom: 20px; }
.notice-wrap h1 { font-size: clamp(2rem, 4vw, 2.9rem); margin-bottom: 18px; }
.notice-lede { font-size: 1.08rem; margin-bottom: 32px; }
.notice-actions { display: flex; flex-wrap: wrap; gap: 12px; }
/* the waitlist: one email field, two boxes, the buttons; the thank-you takes
   the form's place once Netlify sends the visitor back */
.waitlist-form { display: grid; gap: 20px; margin-bottom: 20px; }
.waitlist-aimed {
  font-size: 0.95rem;
  font-weight: 500;
  color: var(--text);
  margin: 0;
}
.waitlist-aimed[hidden] { display: none; }
.waitlist-form.is-aimed .waitlist-for { display: none; }
.waitlist-for { border: 0; padding: 0; margin: 0; min-width: 0; }
.waitlist-for legend { font-size: 0.82rem; font-weight: 600; color: var(--black); margin-bottom: 8px; padding: 0; }
.check { display: flex; align-items: center; gap: 10px; font-size: 0.95rem; color: var(--text); font-weight: 400; }
.check + .check { margin-top: 8px; }
.check input { width: 18px; height: 18px; accent-color: var(--brand); margin: 0; }
.waitlist-joined { font-size: 1.08rem; margin-bottom: 20px; }
.waitlist-joined a { text-decoration: underline; }
.notice-wrap .cta-micro { margin-top: 4px; }
/* support.html / feedback.html: the notice shell with the help styles from
   the block they used to share on the front page */
.help-page .help-list { margin-top: 28px; }
.help-page .help-note { margin-top: 28px; }
.help-page .feedback-form { margin-top: 0; margin-bottom: 20px; }
.help-page .feedback-sent { margin-top: 0; }
.notice-footer { padding: 28px 0; background: var(--black); }
.notice-footer .footer-inner { color: rgba(255, 255, 255, 0.55); }
.notice-footer .footer-links a { color: rgba(255, 255, 255, 0.6); }
.notice-footer .footer-links a:hover { color: #fff; }
.notice-footer .footer-tag { color: rgba(255, 255, 255, 0.55); }

/* ============ Sticky download bar ============ */
.sticky-bar {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 35;
  background: rgba(17, 20, 24, 0.96);
  color: #fff;
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  border-top: 1px solid rgba(255, 255, 255, 0.12);
  box-shadow: 0 -4px 20px rgba(0, 0, 0, 0.25);
  transform: translateY(100%);
  transition: transform 220ms var(--ease), visibility 220ms var(--ease);
}
.sticky-bar.show { transform: translateY(0); visibility: visible; }
/* script.js unhides the bar once and leaves it; without this its two links stay
   tabbable while the bar sits off the bottom of the screen. */
.sticky-bar:not(.show) { visibility: hidden; }
.sticky-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding-top: 12px;
  padding-bottom: 12px;
}
.sticky-text { display: flex; align-items: center; }
.sticky-text strong { font-size: 0.95rem; }
.sticky-note {
  margin-left: 12px;
  padding-left: 12px;
  border-left: 1px solid rgba(255, 255, 255, 0.2);
  font-size: 0.82rem;
  color: rgba(255, 255, 255, 0.6);
  white-space: nowrap;
}
.sticky-actions { display: flex; gap: 8px; }
/* the outline button on the dark bar: a ghost, until the red takes it on hover */
.sticky-bar .btn-outline { background: transparent; color: #fff; border-color: rgba(255, 255, 255, 0.35); }

/* ============ Reveal ============ */
/* Further to travel and a harder settle than the old 12px/0.45s ease, which was
   gentle enough to read as a page loading rather than a thing arriving. */
.reveal { opacity: 0; transform: translateY(20px); transition: opacity 0.5s var(--ease-snap), transform 0.6s var(--ease-snap); }
.reveal.in { opacity: 1; transform: none; }

/* Loops hold at frame zero until their figure is on screen — see script.js.
   Gated on .js so a scriptless page keeps the unconditional animation rather
   than a permanently frozen diagram. Two classes beat the one-class-one-element
   selectors the animations are declared with, so no !important is needed. */
.js [data-loop]:not(.playing) * { animation-play-state: paused; }

/* On arrival the hero fades in top to bottom rather than appearing whole:
   the star field first, then the rating, headline, line, buttons, note, the
   reel, and last the proof row — each a slow fade with a little lift, so the
   page settles while you sit on it. Gated on .js like the loops, so a
   scriptless page is simply there. The reel figure keeps its frame drift
   alongside its entrance; its playback waits for it (data-loop-delay). */
.js .hero::before,
.js .hero-far     { animation: heroFade 1600ms ease-out both; }
.js .hero h1,
.js .hero-sub,
.js .hero-ctas,
.js .hero > .container > .cta-micro { animation: heroIn 1200ms cubic-bezier(0.22, 0.61, 0.36, 1) both; }
.js .hero h1      { animation-delay: 380ms; }
.js .hero-sub     { animation-delay: 620ms; }
.js .hero-ctas    { animation-delay: 840ms; }
.js .hero > .container > .cta-micro { animation-delay: 980ms; }
/* the reel doesn't wait its turn: it's playing from the first frame, so it comes
   up fast and early and the copy settles in around it */
.js .hero-reel    { animation: reelFrame 18s ease-in-out infinite alternate, reelAmbient 37.7884s linear 1 forwards, heroIn 500ms ease-out both; }
@keyframes heroIn {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: none; }
}
@keyframes heroFade { from { opacity: 0; } }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .reveal { opacity: 1; transform: none; transition: none; }
  .sticky-bar, .rail { transition: none; }
  .stage-bg,
  .hero-reel { animation: none; }
  .js .hero h1,
  .js .hero-sub,
  .js .hero-ctas,
  .js .hero > .container > .cta-micro,
  .js .hero-reel,
  .js .hero::before,
  .js .hero-far { animation: none; }
  /* the reel skips straight to where it was going to end up anyway */
  .reel, .reel .s, .reel .p, .reel [class^="d-"], .reel [class^="cut-"],
  .reel [class^="pro-"], .reel [class^="e-"], .reel [class^="g-"], .reel .spk-star, .reel .spk-glint { animation: none; }
  .reel .p { transform: none; filter: none; }
  .reel .s-a1, .reel .s-a2, .reel .s-b, .reel .s-pro { opacity: 0; }
  .reel .s-e, .reel .e-shot-card, .reel .e-to, .reel .e-mark { opacity: 1; }
  .reel .e-mark { transform: none; }
  .reel .e-w { fill-opacity: 1; }
  .reel .e-blast { r: 3300px; }
  .reel .e-to, .reel .e-card-line, .reel .e-card-ruler rect { fill: var(--black); transform: none; }
  .reel .d-late1, .reel .d-late2, .reel .d-late3, .reel .d-spark { opacity: 1; transform: none; }
  .stage.reveal .stage-head,
  .stage.reveal .stage-lede,
  .stage.reveal .stage-steps li,
  .stage.reveal .stage-specs li,
  .stage.reveal .stage-ctas { opacity: 1; }
  .stage.reveal .stage-steps li:not(:first-child)::before { transform: none; }
  .stage.in .stage-lede,
  .stage.in .stage-steps li,
  .stage.in .stage-steps li::before,
  .stage.in .step-num,
  .stage.in .stage-specs li,
  .stage.in .stage-ctas { animation: none; }
  /* the bar never travels, so the headline is simply lit and the bar is gone */
  .stage.in .stage-head {
    animation: none;
    background-image: none;
    color: #fff;
    -webkit-text-fill-color: #fff;
  }
  .stage.in .stage-head::after { display: none; }
  a[href^="/download/"] {
    transition: background 170ms var(--ease), border-color 170ms var(--ease),
                color 170ms var(--ease);
  }
  a[href^="/download/"]:hover, a[href^="/download/"]:active { transform: none; }
}

/* ============ Responsive ============ */
/* The rail lives in the left gutter. Only the things on screen at the same time
   as the rail shift right to clear it — the blocks, footer and sticky bar. The
   nav and hero stay centred, because the rail hasn't faded in that far up. */
@media (min-width: 1340px) {
  .rail { display: flex; }
  body:not(.notice) .band,
  body:not(.notice) .site-footer,
  body:not(.notice) .sticky-bar { padding-left: 210px; }
}
@media (max-width: 1100px) {
  .block-intro { padding: 56px 32px 48px; }
  .block-label,
  .pass-cta { padding-left: 32px; padding-right: 32px; }
  .block-body { padding: 40px 32px; }
  .stage-inner { padding: 52px 32px 48px; }
  .stage-steps li { padding: 0 24px; }
  .cell { padding: 30px 28px; }
}
/* the figures need real width to stay legible — bullets go above before then */
@media (max-width: 900px) {

  .hero { padding: 134px 0 160px; }
  .hero-fade { height: 190px; }
  .hero-far { display: none; }        /* the headline fills the width here */
  .cell-grid-2 { grid-template-columns: 1fr; }
  /* stacked, the column rules become the rules between the beats */
  .stage-steps { grid-template-columns: 1fr; gap: 32px; }
  .stage-steps li { padding: 0; }
  .stage-steps li:not(:first-child) { padding-top: 32px; }
  .stage-steps li:not(:first-child)::before {
    left: 0;
    right: 0;
    top: 0;
    bottom: auto;
    width: auto;
    height: 1px;
  }
  .stage.reveal .stage-steps li:not(:first-child)::before { transform: scaleX(0); transform-origin: left; }
  .stage.in .stage-steps li:not(:first-child)::before { animation-name: ruleGrowX; }
  .step-num { margin-bottom: 12px; }
  .nav-links { display: none; }
  .cta-block { padding: 64px 28px; }
}
@media (max-width: 600px) {
  .hero-ctas { flex-direction: column; }
  .hero-ctas .btn, .hero-ctas .btn-outline { width: 100%; }
  .brand-name { display: none; }
  .footer-top { gap: 36px; padding-bottom: 32px; }
  .footer-cols { gap: 36px; }
  .footer-ask { flex-direction: column; align-items: flex-start; gap: 14px; }
  .footer-bottom { flex-direction: column; align-items: flex-start; gap: 8px; }
  .sticky-text { display: none; }
  .sticky-actions { width: 100%; }
  .sticky-actions .btn { flex: 1; }
  .footer-inner { flex-direction: column; gap: 8px; }
  .privacy-note { flex-direction: column; gap: 12px; }
  .notice-actions .btn, .notice-actions .btn-outline { width: 100%; }
  .pass-cta-actions { width: 100%; }
  .pass-cta-actions .btn, .pass-cta-actions .btn-outline { flex: 1; }
  .block-intro { padding: 44px 22px 36px; }
  .block-label,
  .pass-cta { padding-left: 22px; padding-right: 22px; }
  .block-body { padding: 32px 22px; }
  .cell { padding: 26px 22px; }
  .container { padding: 0 16px; }
  .stage-inner { padding: 40px 22px 40px; }
  .stage-ctas { flex-direction: column; }
  .stage-ctas .btn, .stage-ctas .btn-outline { width: 100%; }
}

/* The stacked rules draw sideways, so the held-still state has to match. */
@media (max-width: 900px) and (prefers-reduced-motion: reduce) {
  .stage.reveal .stage-steps li:not(:first-child)::before { transform: none; }
}

/* --- Consent banner ---------------------------------------------------------
   Sits at the bottom until the visitor answers. There is no close button on
   purpose: an X that dismisses without an answer teaches people that ignoring
   the thing means yes.

   `[hidden]` needs the explicit rule below, exactly as .feedback-form does — the
   author `display: flex` here would otherwise beat the UA sheet and the banner
   would stay on screen after a choice was made. */
.consent {
  position: fixed;
  inset-inline: 0;
  bottom: 0;
  z-index: 90;
  display: flex;
  justify-content: center;
  padding: 16px;
  background: #11151a;
  border-top: 1px solid rgba(255, 255, 255, 0.14);
  color: #f2f5f8;
  box-shadow: 0 -8px 32px rgba(0, 0, 0, 0.28);
}
.consent[hidden] { display: none; }
.consent:focus { outline: none; }
.consent:focus-visible { outline: 2px solid var(--focus-ring-light); outline-offset: -4px; }

.consent-inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px 24px;
  width: min(1080px, 100%);
}
.consent-copy { flex: 1 1 380px; min-width: 0; }
.consent-title { margin: 0 0 4px; font-size: 1rem; line-height: 1.3; color: #ffffff; }
.consent-text { margin: 0; font-size: 0.875rem; line-height: 1.5; color: rgba(242, 245, 248, 0.82); }
.consent-link { color: #ffffff; text-underline-offset: 2px; }

.consent-actions { display: flex; flex-wrap: wrap; gap: 8px; flex: 0 0 auto; }
.consent-btn {
  font: inherit;
  font-size: 0.875rem;
  font-weight: 600;
  padding: 10px 18px;
  border-radius: var(--radius-pill);
  border: 1px solid transparent;
  cursor: pointer;
  white-space: nowrap;
}
/* Equal weight, deliberately. A solid Allow beside an outlined Decline is the
   pattern the CNIL fined Google and Meta over: refusal must not be the quieter
   choice. Same fill, same contrast, same size — the only difference is the word. */
.consent-btn-yes,
.consent-btn-no { background: #ffffff; color: #11151a; }
.consent-btn-yes:hover,
.consent-btn-no:hover { background: rgba(255, 255, 255, 0.86); }
.consent-btn[aria-pressed="true"] { box-shadow: 0 0 0 2px #11151a, 0 0 0 4px rgba(255, 255, 255, 0.85); }

/* The banner is dark, so the near-black default ring disappears into it. */
.consent :focus-visible { outline: 2px solid var(--focus-ring-light); outline-offset: 2px; }

/* The banner shares the bottom of the viewport with the sticky download bar and,
   on a narrow screen, the footer's last rows. Two different failures:

   The sticky bar is `position: fixed` too, so no amount of page padding moves it
   — it has to be hidden, and with `visibility` rather than opacity, because the
   comment at .sticky-bar already established that its two links stay tabbable
   otherwise. That is the same trap, reached by a different route.

   The footer is in normal flow, so reserving the banner's height at the foot of
   the page is enough. Without it, a visitor who has not answered cannot scroll to
   the last rows — and the banner has no dismiss control, by design. */
body.consent-open { padding-bottom: var(--consent-height, 0px); }
body.consent-open .sticky-bar { visibility: hidden; }
body.consent-open .ask-toast { display: none; }

@media (max-width: 560px) {
  .consent-actions { width: 100%; }
  .consent-btn { flex: 1 1 auto; }
}

/* The "change your analytics choice" control on the Privacy Policy. Hidden in
   the markup and revealed by script.js only when analytics is actually running,
   so it is never a button that does nothing. */
#consent-settings[hidden] { display: none; }
.linklike {
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
  padding: 0;
  text-decoration: underline;
  text-underline-offset: 2px;
  cursor: pointer;
}
