/* Project Kite on the creativecue.co layout. Sizes are the reference's at 1440 (see tokens.css); colour, type and
   the selection-frame device are Kite's. Motion: transform, opacity and clip-path only; reduced motion and the
   "Pause motion" switch (html.is-still) show every finished state. */

/* ---------- Base ---------- */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; padding: 0; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; scroll-padding-top: 24px; }
/* Reduced motion and the footer's Pause motion: links jump, and the buttons' letters swap rows without rolling. */
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } :root .roll__row > span { transition: none; } }
:root.is-still { scroll-behavior: auto; }
:root.is-still .roll__row > span { transition: none; }
body {
  background: var(--bg); color: var(--ink);
  font: 400 var(--t-body) / 1.5 var(--font-sans);
  -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
  overflow-x: clip;
}
img, video, svg, canvas, picture { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }
ul, ol { list-style: none; }
h1, h2, h3 { font-weight: 500; }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
::selection { background: var(--accent); color: var(--accent-ink); }
[hidden] { display: none !important; }
.visually-hidden {
  position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.skip { position: fixed; left: 16px; top: 16px; z-index: 200; padding: 12px 16px; border-radius: 999px; background: var(--accent); color: var(--accent-ink); transform: translateY(-200%); }
.skip:focus { transform: none; }
.small { font-size: var(--t-small); line-height: var(--lh-small); letter-spacing: -0.01em; color: var(--muted); }
.link { text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 0.22em; }
.link:hover { text-decoration-thickness: 2px; }

:root {
  --signal: var(--accent); --stroke: 2px; --handle: 9px; --r-pill: 999px;
  --step-0: 15px; --step-2: clamp(24px, 2.2vw, 32px);
  --safe-l: max(var(--margin), env(safe-area-inset-left)); --safe-r: max(var(--margin), env(safe-area-inset-right));
  --safe-b: env(safe-area-inset-bottom);
}

/* ---------- Type ---------- */
.h { position: relative; z-index: 1; font: 500 var(--t-h) / var(--lh-h) var(--font-display); letter-spacing: var(--track-h); text-wrap: balance; }
.w { display: inline-block; }
.w__i { display: inline-block; }
.ghost {
  position: absolute; z-index: 0; left: calc(18px - var(--margin)); top: -78px;
  font: 500 var(--t-num) / 120px var(--font-display); letter-spacing: -0.01em;
  color: color-mix(in srgb, var(--ink) 7%, transparent);
  pointer-events: none; user-select: none; white-space: nowrap;
}
.sec__lead { max-width: 46ch; font-size: var(--t-body); line-height: 1.5; color: var(--muted); text-wrap: pretty; } /* no word left alone on the last line */

/* ---------- Buttons, tags, the selection frame ---------- */
.btn {
  position: relative; display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-height: 48px; padding: 0 22px; border-radius: var(--r-pill);
  background: var(--accent); color: var(--accent-ink);
  font: 500 15px / 1 var(--font-display); letter-spacing: -0.01em; white-space: nowrap;
  transition: transform var(--d-press) var(--ease-out);
}
.btn:active { transform: scale(0.97); }
/* The second button: a filled plum pill, one tone step up from the page (no outline). */
.btn--ghost { background: var(--surface-2); color: var(--ink); }
.icon-btn {
  position: relative; display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-width: 48px; min-height: 48px; padding: 0 16px; border-radius: var(--r-pill);
  background: var(--surface); color: var(--ink); font: 500 var(--step-0) / 1 var(--font-display);
  transition: transform var(--d-press) var(--ease-out);
}
.icon-btn:active { transform: scale(0.97); }
.ic { width: 18px; height: 18px; flex: none; transition: transform 280ms var(--ease-out); }
.icon-btn .ic { width: 16px; height: 16px; }

/* Letter roll: each letter rises out and its twin rises in (cue.js writes the rows). */
.roll { position: relative; display: inline-block; overflow: hidden; height: 1.25em; line-height: 1.25em; vertical-align: middle; }
.roll__row { display: block; white-space: pre; }
.roll__row + .roll__row { position: absolute; left: 0; top: 100%; }
.roll__row > span { display: inline-block; transition: transform 420ms var(--ease-out); transition-delay: calc(var(--i) * 16ms); }
@media (hover: hover) {
  a:hover .roll .roll__row > span, button:hover .roll .roll__row > span { transform: translateY(-100%); }
}

.tag {
  display: inline-flex; align-items: center; min-height: 26px; padding: 0 10px; border-radius: var(--r-pill);
  background: var(--surface-2); color: var(--ink); font: 500 13px / 1 var(--font-sans); letter-spacing: 0.01em; white-space: nowrap;
}
.tag--ai { background: var(--ai); color: var(--bg); }
.num.tag, .tag.num { font-variant-numeric: tabular-nums; }

.sel { position: absolute; inset: 0; border: var(--stroke) solid var(--signal); pointer-events: none; }
.sel > i { position: absolute; width: var(--handle); height: var(--handle); background: var(--bg); border: var(--stroke) solid var(--signal); }
.sel > i:nth-child(1) { top: calc(var(--handle) / -2 - 1px); left: calc(var(--handle) / -2 - 1px); }
.sel > i:nth-child(2) { top: calc(var(--handle) / -2 - 1px); left: calc(50% - var(--handle) / 2); }
.sel > i:nth-child(3) { top: calc(var(--handle) / -2 - 1px); right: calc(var(--handle) / -2 - 1px); }
.sel > i:nth-child(4) { top: calc(50% - var(--handle) / 2); right: calc(var(--handle) / -2 - 1px); }
.sel > i:nth-child(5) { bottom: calc(var(--handle) / -2 - 1px); right: calc(var(--handle) / -2 - 1px); }
.sel > i:nth-child(6) { bottom: calc(var(--handle) / -2 - 1px); left: calc(50% - var(--handle) / 2); }
.sel > i:nth-child(7) { bottom: calc(var(--handle) / -2 - 1px); left: calc(var(--handle) / -2 - 1px); }
.sel > i:nth-child(8) { top: calc(50% - var(--handle) / 2); left: calc(var(--handle) / -2 - 1px); }

.mark { width: 100%; height: auto; }
.mark__h { fill: var(--bg); }
.blogo {
  display: block; flex: none; background: var(--muted);
  -webkit-mask: var(--logo) center / contain no-repeat; mask: var(--logo) center / contain no-repeat;
}

/* ---------- Header, pill and menu ---------- */
.nav {
  position: relative; z-index: 20; height: var(--nav-h);
  display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: 24px; padding: 0 var(--safe-r) 0 var(--safe-l);
}
.nav__logo { justify-self: start; display: block; width: 74px; color: var(--ink); }
.logo { width: 100%; height: auto; }
.nav__links { display: flex; gap: 2px; }
.nav__links a { display: inline-flex; align-items: center; gap: 8px; min-height: 44px; padding: 0 12px; font: 500 15px / 1 var(--font-display); color: var(--muted); }
.nav__links a:hover, .nav__links a:focus-visible, .nav__links a[aria-current] { color: var(--ink); }

/* Link icons: line drawings in the text's colour. On hover or keyboard focus one part moves (transform, clip-path). */
.nic { width: 18px; height: 18px; flex: none; overflow: visible; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.nic .nic__fill { fill: currentColor; }
.nic__m, .nic__route { transform-box: fill-box; transform-origin: center; transition: transform 280ms var(--ease-out); }
.nic__tilt { transform-origin: 50% 75%; }
/* The route draws from its first node to its last: a box grows from the top-left corner. Both ends are inset()
   so the browser can blend them (inset to none would jump), and the -3 user units keep the stroke's caps whole. */
@keyframes nic-draw { from { clip-path: inset(-3px 100% 100% -3px); } to { clip-path: inset(-3px); } }
@media (prefers-reduced-motion: no-preference) {
  :is(a, button):is(:hover, :focus-visible) .nic--work .nic__m { transform: translateX(1.5px) scale(1.14); }
  :is(a, button):is(:hover, :focus-visible) .nic--services .nic__up { transform: translateY(-1.8px); }
  :is(a, button):is(:hover, :focus-visible) .nic--services .nic__down { transform: translateY(1.8px); }
  :is(a, button):is(:hover, :focus-visible) .nic--process .nic__route { animation: nic-draw 480ms var(--ease-in-out); }
  :is(a, button):is(:hover, :focus-visible) .nic--process .nic__end { transform: scale(1.28); transition-delay: 300ms; }
  :is(a, button):is(:hover, :focus-visible) .nic--faq .nic__tilt { transform: rotate(-16deg); }
  :is(a, button):is(:hover, :focus-visible) .nic--home .nic__lift { transform: translate(1px, -1.8px) rotate(9deg); }
  :is(a, button):is(:hover, :focus-visible) .nic--book .nic__up { transform: translateY(-1.4px); }
  :is(a, button):is(:hover, :focus-visible) .nic--book .nic__end { transform: scale(1.35); }
}
.nav__end { justify-self: end; display: flex; gap: 8px; }

/* The pill: one solid plum lozenge (no blur, no shadow, no outline), the same plum the menu panel grows into. */
.pill {
  position: fixed; z-index: 30; left: 50%; bottom: max(20px, env(safe-area-inset-bottom));
  display: flex; align-items: center; gap: 4px; padding: 6px;
  border-radius: var(--r-pill); background: var(--surface-2);
  transform: translate(-50%, calc(100% + 40px)); transition: transform 520ms var(--ease-out);
}
.pill.is-shown, .pill:focus-within { transform: translate(-50%, 0); }
/* At the close of the home page the kite scene's own Frame stands at the foot of the screen, so the pill steps aside
   at every width (one Frame on screen at a time); keyboard focus still brings it back. */
.pill.is-aside:not(:focus-within) { transform: translate(-50%, calc(100% + 40px)); }
.pill__mark { display: grid; place-items: center; width: 44px; height: 44px; border-radius: 50%; color: var(--accent); background: var(--bg); }
.pill__mark .mark { width: 26px; }
.pill__menu { display: inline-flex; align-items: center; gap: 10px; min-height: 44px; padding: 0 18px 0 14px; border-radius: var(--r-pill); font: 500 15px / 1 var(--font-display); }
.bars { display: grid; gap: 5px; width: 18px; }
.bars i { display: block; height: 2px; border-radius: 2px; background: currentColor; transition: transform 300ms var(--ease-out); }
.pill__menu:hover .bars i:first-child { transform: translateX(3px); }
.pill__menu:hover .bars i:last-child { transform: translateX(-3px); }

/* While a dialog is open the page behind it can't scroll. The scrollbar goes with it, so the body takes its width
   back as padding (cue.js measures it into --sbw) and nothing behind the dialog moves. */
html:has(dialog[open]) { overflow: hidden; }
html:has(dialog[open]) body { padding-right: var(--sbw, 0px); }

/* The menu: the pill grows into a full plum panel (clip-path from the pill's own shape, which cue.js measures into
   --wipe) and shrinks back into it. Links on the left, each with its icon; the selected one (pointer, keyboard, or
   the page you're on when it opens) wears the selection frame, and the frame on the right shows where it goes. */
.menu {
  position: fixed; inset: 0; width: 100vw; height: 100dvh; max-width: none; max-height: none; margin: 0; border: 0; padding: 0;
  overflow-y: auto; overscroll-behavior: contain;
  background: var(--surface-2); color: var(--ink);
  clip-path: inset(0 round 0);
}
.menu::backdrop { background: transparent; }
.menu .sel > i { background: var(--surface-2); }
.menu__panel {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); grid-template-rows: auto minmax(0, 1fr) auto;
  column-gap: clamp(40px, 5.6vw, 96px); row-gap: 24px; min-height: 100%;
  padding: 0 var(--safe-r) max(20px, env(safe-area-inset-bottom)) var(--safe-l);
  --mfs: clamp(36px, min(4.6vw, 7.2svh), 68px); --mgap: clamp(0px, 0.8svh, 10px); /* the links' size and gap */
}
/* The logo where the page header has it, so the menu reads as the same site. */
.menu__top { grid-column: 1 / -1; display: flex; align-items: center; height: var(--nav-h); }
.menu__top .logo { width: 74px; color: var(--ink); }
.menu__nav { align-self: center; }
.menu__links { display: grid; justify-items: start; gap: var(--mgap); }
.menu__links a {
  position: relative; display: inline-flex; align-items: center; gap: 0.3em;
  padding: 0.04em 0.24em 0.1em 0.18em;
  font: 500 var(--mfs) / 1.08 var(--font-display); letter-spacing: -0.03em;
  color: var(--muted);
}
.menu__links a.is-on, .menu__links a:focus-visible { color: var(--ink); }
.menu__links a:focus-visible { outline: none; }
.menu__links .nic { width: 0.56em; height: 0.56em; stroke-width: 1.6; }
.menu__here { flex: none; align-self: flex-start; width: 0.15em; height: 0.15em; margin: 0.2em 0 0 -0.12em; border-radius: 50%; background: var(--accent); }
/* Hidden, the frame is clipped to nothing at its left edge (handles included); selected, it wipes open to the right. */
.menu__links .sel { clip-path: inset(-12px calc(100% + 12px) -12px -12px); transition: clip-path 200ms var(--ease-exit); }
.menu__links a:is(.is-on, :focus-visible) .sel { clip-path: inset(-12px); transition: clip-path 420ms var(--ease-in-out); }

/* Kite's world, not our films (menu-map.js): the land as dots straight on the plum panel (no screen round it), home
   (Bangladesh) a wasabi point in every state, and the selected link's signals lit on the biggest cities. The preview is
   as tall as the six links (each 1.22em with its padding), so the map starts level with Home and its sentence ends
   near Book a call; the map runs on into the right margin and off the screen's edge. */
.menu__preview { align-self: center; display: grid; grid-template-rows: minmax(0, 1fr) auto; gap: 20px; height: calc(var(--mfs) * 7.32 + var(--mgap) * 5); }
.menu__frame { position: relative; min-height: 0; margin-right: calc(-1 * var(--safe-r)); }
.menu__map { position: absolute; inset: 0; width: 100%; height: 100%; }
.menu__pv { position: absolute; inset: 0; opacity: 0; transition: opacity 240ms var(--ease-out); }
.menu__pv.is-on { opacity: 1; }
.menu__home { position: absolute; width: 0; height: 0; }
.menu__home i { position: absolute; left: -4px; top: -4px; width: 8px; height: 8px; border-radius: 50%; background: var(--accent); }
.mm { position: absolute; color: var(--accent); }
.mm svg { display: block; width: 100%; height: 100%; overflow: visible; }
.menu__ring { position: absolute; width: 0; height: 0; }
.menu__ring::before { content: ""; position: absolute; left: -22px; top: -22px; width: 44px; height: 44px; border: 1.5px solid var(--accent); border-radius: 50%; opacity: 0; }
.menu__at { position: absolute; transform: translateX(-50%); font: 500 var(--t-small) / 20px var(--font-sans); color: var(--ink); white-space: nowrap; }
.menu__lines { display: grid; }
/* One sentence at a time: the old one goes in 120ms, the new one comes 100ms later, so two never read over each other. */
.menu__lines p { grid-area: 1 / 1; max-width: 42ch; font-size: 17px; line-height: 1.45; color: var(--muted); text-wrap: pretty; opacity: 0; transition: opacity 120ms var(--ease-exit); }
.menu__lines p.is-on { opacity: 1; transition: opacity 240ms var(--ease-out) 100ms; }

/* The foot: email left, Close exactly where the pill was (same height, same centre), the studio's status right. */
.menu__foot { grid-column: 1 / -1; display: grid; grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr); align-items: center; gap: 16px; }
.menu__mail { justify-self: start; display: inline-flex; align-items: center; gap: 10px; min-height: 44px; font-size: 15px; color: var(--muted); }
.menu__mail:hover, .menu__mail:focus-visible { color: var(--ink); }
.menu__mail .ic { width: 18px; height: 18px; }
.menu__close { display: inline-flex; align-items: center; gap: 10px; min-height: 56px; padding: 0 24px 0 20px; border-radius: var(--r-pill); background: var(--bg); font: 500 15px / 1 var(--font-display); transition: transform var(--d-press) var(--ease-out); }
.menu__close:active { transform: scale(0.97); }
.menu__close .ic { width: 14px; height: 14px; }
.menu__status { justify-self: end; display: inline-flex; align-items: center; gap: 10px; font-size: 15px; color: var(--muted); }

/* Touch screens and narrow windows: no hover to preview with, so the links take the whole panel. On a phone they sit
   low, in reach of the thumb, with the email and status under them and Close where the pill was. */
@media (max-width: 900px), (hover: none) {
  .menu__panel { grid-template-columns: minmax(0, 1fr); }
  .menu__preview { display: none; }
  .menu__links a { font-size: clamp(36px, min(9vw, 7.2svh), 76px); }
}
@media (max-width: 760px) {
  .menu__nav { align-self: end; }
  .menu__links a { font-size: clamp(34px, min(11.5vw, 6.4svh), 52px); }
  .menu__foot { grid-template-columns: minmax(0, 1fr); justify-items: start; gap: 4px; }
  .menu__status { justify-self: start; min-height: 32px; }
  .menu__close { order: 1; justify-self: center; margin-top: 20px; }
}

@media (prefers-reduced-motion: no-preference) {
  :root:not(.is-still) .menu[open] { animation: menu-grow 520ms var(--ease-in-out) both; }
  :root:not(.is-still) .menu[open] :is(.menu__links li, .menu__preview, .menu__mail, .menu__status) { animation: rise 560ms var(--ease-out) both; animation-delay: calc(180ms + var(--i, 0) * 50ms); }
  :root:not(.is-still) .menu[open] .menu__close { animation: fade-in 200ms var(--ease-out) 160ms both; }
  :root:not(.is-still) .menu[open] .menu__top { animation: fade-in 320ms var(--ease-out) 200ms both; }
  :root:not(.is-still) .menu.is-closing { animation: menu-shrink 340ms var(--ease-in-out) both; }
  :root:not(.is-still) .menu.is-closing .menu__panel { animation: fade-out 140ms var(--ease-exit) both; }
  /* The selected link's signals pop out from home, nearest first (--d, from menu-map.js); home's ring goes out once. */
  :root:not(.is-still) .menu__pv.is-on .mm { animation: mm-pop 420ms var(--ease-out) both; animation-delay: var(--d, 0ms); }
  :root:not(.is-still) .menu__pv.is-on .menu__ring::before { animation: mm-ring 1100ms var(--ease-out) 160ms both; }
}
@keyframes mm-pop { from { opacity: 0; transform: scale(0.5); } }
@keyframes mm-ring { from { opacity: 0.9; transform: scale(0.7); } to { opacity: 0; transform: scale(2.4); } }
/* Reduced motion and "Pause motion": the panel fades in and out; nothing travels, the frame and the lit signals just
   switch. */
@media (prefers-reduced-motion: reduce) {
  .menu[open] { animation: fade-in 160ms var(--ease-out) both; }
  .menu.is-closing { animation: fade-out 120ms var(--ease-exit) both; }
  .menu__links .sel { transition: none; }
}
.is-still .menu[open] { animation: fade-in 160ms var(--ease-out) both; }
.is-still .menu.is-closing { animation: fade-out 120ms var(--ease-exit) both; }
.is-still .menu__links .sel { transition: none; }
@keyframes menu-grow { from { clip-path: var(--wipe, inset(calc(100% - 76px) calc(50% - 80px) 20px round 28px)); } to { clip-path: inset(0 round 0); } }
@keyframes menu-shrink { from { clip-path: inset(0 round 0); } to { clip-path: var(--wipe, inset(calc(100% - 76px) calc(50% - 80px) 20px round 28px)); } }
@keyframes fade-in { from { opacity: 0; } }
@keyframes fade-out { to { opacity: 0; } }
@keyframes rise { from { opacity: 0; transform: translateY(24px); } }

/* ---------- Intro: the selection frame turns into a kite and flies off ---------- */
.intro { display: none; }
.is-intro .intro {
  position: fixed; inset: 0; z-index: 100; display: grid; place-items: center; background: var(--bg);
  animation: intro-out 640ms var(--ease-in-out) 1000ms both; pointer-events: none;
}
.intro__mark { width: 84px; color: var(--accent); animation: intro-kite 1300ms var(--ease-in-out) both; }
@keyframes intro-kite {
  0% { opacity: 0; transform: scale(0.7) rotate(0deg); }
  30% { opacity: 1; transform: scale(1) rotate(0deg); }
  62% { transform: scale(1) rotate(45deg); }
  100% { opacity: 0; transform: translate(26vw, -42vh) scale(0.6) rotate(45deg); }
}
@keyframes intro-out { to { clip-path: inset(0 0 100% 0); visibility: hidden; } }

/* ---------- Reveal on scroll (cue.js marks .is-in) ---------- */
.cue .reveal { opacity: 0; transform: translateY(32px); }
.cue .reveal.is-in { opacity: 1; transform: none; transition: opacity var(--d-reveal) var(--ease-out), transform var(--d-reveal) var(--ease-out); transition-delay: calc(var(--d, 0) * 70ms); }
.cue .h .w__i, .cue .hero__title .w__i { opacity: 0; transform: translateY(45%); }
.cue .is-in .w__i { opacity: 1; transform: none; transition: opacity 700ms var(--ease-out), transform 900ms var(--ease-out); transition-delay: calc(var(--wi, 0) * 55ms); }
.cue .hero__text > :not(h1) { opacity: 0; transform: translateY(16px); }
.cue .hero.is-in .hero__text > :not(h1) { opacity: 1; transform: none; transition: opacity 700ms var(--ease-out) 380ms, transform 900ms var(--ease-out) 380ms; }
.is-intro .hero.is-in .w__i { transition-delay: calc(1250ms + var(--wi, 0) * 55ms); }
.is-intro .hero.is-in .hero__text > :not(h1) { transition-delay: 1650ms; }
@media (prefers-reduced-motion: reduce) {
  .cue .reveal, .cue .w__i, .cue .hero__text > * { opacity: 1 !important; transform: none !important; transition: none !important; }
}
.is-still .reveal, .is-still .w__i, .is-still .hero__text > * { opacity: 1 !important; transform: none !important; transition: none !important; }

/* ---------- Hero ---------- */
.hero {
  position: relative; display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  height: clamp(560px, calc(100svh - var(--nav-h)), 816px); padding-left: var(--safe-l); overflow: hidden;
}
.hero__text { position: relative; z-index: 2; align-self: center; max-width: 540px; padding: 48px 0 72px; }
.status { display: inline-flex; align-items: center; gap: 10px; min-height: 34px; padding: 0 14px 0 12px; border-radius: var(--r-pill); background: var(--surface); font-size: 14px; color: var(--ink); }
.status__dot { position: relative; width: 8px; height: 8px; border-radius: 50%; background: var(--accent); }
.status__dot::after { content: ""; position: absolute; inset: 0; border-radius: 50%; background: var(--accent); animation: ping 2.2s var(--ease-out) infinite; }
@keyframes ping { 0% { transform: scale(1); opacity: 0.6; } 80%, 100% { transform: scale(3.2); opacity: 0; } }
.hero__title { margin-top: 28px; font: 500 var(--t-h) / 1.17 var(--font-display); letter-spacing: var(--track-h); text-wrap: balance; }
.hero__lead { margin-top: 20px; max-width: 44ch; color: var(--muted); text-wrap: pretty; }
.hero__actions { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 32px; }

.stream {
  position: relative; overflow: hidden;
  /* Masks, not fills: the drifting films fade out at the left and at the top and bottom edges. */
  -webkit-mask: linear-gradient(90deg, transparent 0, #000 16%), linear-gradient(transparent 0, #000 12%, #000 88%, transparent 100%); /* taste-skill-ignore: mask */
  -webkit-mask-composite: source-in; mask: linear-gradient(90deg, transparent 0, #000 16%) intersect, linear-gradient(transparent 0, #000 12%, #000 88%, transparent 100%); /* taste-skill-ignore: mask */
}
.stream__plane { position: absolute; inset: -30% -12% -30% 2%; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 16px; transform: rotate(-14deg); }
.stream__col { display: flex; flex-direction: column; animation: drift-up calc(var(--n, 6) * 9s) linear infinite; will-change: transform; }
.stream__col:nth-child(2) { animation-name: drift-down; animation-duration: calc(var(--n, 6) * 11s); }
.stream__run { display: flex; flex-direction: column; gap: 16px; padding-bottom: 16px; }
@keyframes drift-up { to { transform: translateY(-50%); } }
@keyframes drift-down { from { transform: translateY(-50%); } to { transform: translateY(0); } }
.stream:hover .stream__col { animation-play-state: paused; }
.stream .tile__frame { aspect-ratio: 16 / 10; }

/* A film tile: the still fills the frame; it scales a little under the cursor. */
.tile__frame { position: relative; display: block; width: 100%; overflow: hidden; border-radius: 10px; background: var(--surface); -webkit-tap-highlight-color: transparent; }
.tile__frame .tile__media, .tile__frame .tile__media img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.tile__frame .tile__media img { transition: transform 900ms var(--ease-out); }
@media (hover: hover) { .tile__frame:hover .tile__media img { transform: scale(1.04); } }

/* ---------- Brands: one line of every logo, running in a loop; it stops while the cursor is on it ---------- */
.brands { display: grid; grid-template-columns: 330px minmax(0, 1fr); align-items: center; gap: 24px; padding: 120px var(--safe-r) 40px var(--safe-l); }
.brands__title { font: 500 20px / 1.3 var(--font-display); letter-spacing: -0.01em; max-width: 16ch; }
.brands__text .small { margin-top: 10px; max-width: 26ch; }
.marquee { position: relative; min-width: 0; border-radius: var(--radius); background: var(--surface); }
/* The logos fade out over the last 72px at each end; the band itself keeps its hard edges. */
.marquee__track {
  --fade: 72px; display: flex; overflow: hidden;
  -webkit-mask: linear-gradient(90deg, transparent 0, #000 var(--fade), #000 calc(100% - var(--fade)), transparent 100%); /* taste-skill-ignore: mask */
  mask: linear-gradient(90deg, transparent 0, #000 var(--fade), #000 calc(100% - var(--fade)), transparent 100%); /* taste-skill-ignore: mask */
}
/* Both copies move by their own width, so the second takes the first one's place without a seam. Linear: a ticker. */
.marquee__run { display: flex; flex: none; align-items: center; min-width: 100%; animation: marquee var(--marquee-d, 64s) linear infinite; }
@keyframes marquee { to { transform: translate3d(-100%, 0, 0); } }
@media (hover: hover) { .marquee:hover .marquee__run { animation-play-state: paused; } }
.brand { display: grid; place-items: center; height: 120px; padding: 0 clamp(26px, 2.8vw, 44px); }
.brand .blogo { background: var(--ink); opacity: 0.6; transition: opacity var(--d-hover) var(--ease-out), transform 320ms var(--ease-out); }
.brand__name { display: inline-block; font: 500 18px / 1 var(--font-display); letter-spacing: -0.01em; white-space: nowrap; opacity: 0.6; transition: opacity var(--d-hover) var(--ease-out), transform 320ms var(--ease-out); }
@media (hover: hover) {
  .brand:hover .blogo, .brand:hover .brand__name { opacity: 1; transform: scale(1.08); }
}
/* Still: no loop; the one list wraps inside the band and every logo shows at once. */
.is-still .marquee__run { animation: none; flex-wrap: wrap; justify-content: center; min-width: 0; flex: 1 1 100%; padding: 12px 24px; }
.is-still .marquee__run[aria-hidden] { display: none; }
.is-still .marquee__track { -webkit-mask: none; mask: none; }
.is-still .brand { height: 84px; }
@media (prefers-reduced-motion: reduce) {
  .marquee__run { animation: none; flex-wrap: wrap; justify-content: center; min-width: 0; flex: 1 1 100%; padding: 12px 24px; }
  .marquee__run[aria-hidden] { display: none; }
  .marquee__track { -webkit-mask: none; mask: none; }
  .brand { height: 84px; }
}

/* ---------- Sections ---------- */
.sec { position: relative; padding: var(--section-gap) var(--safe-r) 0 var(--safe-l); }
.sec__head { position: relative; display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); align-items: end; gap: 20px 64px; margin-bottom: 64px; }
.sec__head .sec__lead { justify-self: end; }
.sec__head--center { grid-template-columns: minmax(0, 1fr); justify-items: center; text-align: center; }
.sec__head--center .sec__lead { justify-self: center; text-wrap: balance; } /* centred lines of even length, not a long line over a short one */
.sec__head--center .ghost { left: 50%; transform: translateX(-50%); }

/* (01) Benefits: eight short cards, four across (two rows, about 230px each), then one plum band to book a call.
   Was three across at 400px a card. The cards are not links, so nothing on them moves under the cursor: a hover move
   would promise a click that isn't there. The band is a link; its mark turns into a kite, as in the intro. */
.cards { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 16px; }
.card { display: flex; flex-direction: column; padding: 24px 24px 28px; border-radius: var(--radius); background: var(--surface); }
/* Each icon is cropped to its own ink and sized by the build to the area of a 46px square (--iw / --ih, px at --k 1),
   so a wide tag and a tall kite look the same size; --k also sets the line weight inside the sprite. On a desktop
   card every icon stands on the foot of a slot as tall as the tallest (--ih-max), so the titles in a row line up,
   20px under the ink, and the ink's left edge is the title's. overflow: the ink box is exact, so nothing is clipped
   by rounding. */
.card__icon { --k: 1; flex: none; width: calc(var(--iw) * var(--k) * 1px); height: calc(var(--ih) * var(--k) * 1px); margin-top: calc((var(--ih-max) - var(--ih)) * var(--k) * 1px); overflow: visible; }
.card__icon--empty { border-radius: 50%; background: var(--surface-2); width: 56px; height: 56px; }
.card__title { margin-top: 20px; font: 500 20px / 1.25 var(--font-display); letter-spacing: -0.01em; text-wrap: balance; }
.card__text { margin-top: 6px; max-width: 34ch; font-size: var(--t-small); line-height: var(--lh-small); letter-spacing: -0.01em; color: var(--muted); text-wrap: pretty; }

.cta-band {
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: 20px;
  margin-top: 16px; padding: 20px 20px 20px 24px; border-radius: var(--radius); background: var(--plum);
}
.cta-band__kite { width: 44px; color: var(--accent); }
.cta-band__kite .mark { transition: transform 340ms var(--ease-in-out); }
.cta-band__kite .mark__h { fill: var(--plum); }
.cta-band__title { font: 500 20px / 1.25 var(--font-display); letter-spacing: -0.01em; }
.cta-band__text { margin-top: 2px; font-size: var(--t-small); line-height: var(--lh-small); color: var(--muted); }
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  .cta-band:hover .cta-band__kite .mark { transform: rotate(45deg); transition-duration: 520ms; }
}

/* (02) Process: the six steps as one route (rafi, 2026-11-09: no artwork here, only the information and icons). Each
   step's drawing sits on the line in a disc, what we do is under it, and what you get closes the column, on one row
   across the six. No boxes: (01) just above is a grid of tiles, so here the line is the shape. cue.js lights the
   steps in order as they arrive (a step's drawing plays, then its stretch of line runs on to the next disc). Without
   script, under reduced motion and with motion paused, all six are lit and still. */
.process { overflow: hidden; padding-bottom: 40px; }
.route { --node: 80px; --gap: 24px; --run: scaleX(0); --track: color-mix(in srgb, var(--ink) 16%, transparent); position: relative; display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); column-gap: var(--gap); }
.route__step { position: relative; display: flex; flex-direction: column; align-items: flex-start; }
/* Each step's stretch of line, from its disc's edge to the next one's: the track, and the wasabi run over it. */
.route__step:not(:last-child)::before, .route__step:not(:last-child)::after { content: ''; position: absolute; left: var(--node); top: calc(var(--node) / 2 - 1px); width: calc(100% + var(--gap) - var(--node)); height: 2px; pointer-events: none; }
.route__step::before { background: var(--track); }
.route__step::after { background: var(--accent); transform-origin: 0 50%; }
.route__node { position: relative; z-index: 1; display: grid; place-items: center; flex: none; width: var(--node); height: var(--node); border-radius: 50%; background: var(--surface); }
.route__icon { width: 60%; height: 60%; overflow: visible; color: var(--ink); fill: none; stroke: currentColor; stroke-width: 2.9px; stroke-linecap: round; stroke-linejoin: round; }
.route__icon .ri__fill { fill: var(--accent); stroke: none; }
.route__icon .ri__mute { fill: var(--muted); stroke: none; }
.route__icon .ri__ink { stroke: var(--accent); stroke-width: 4px; }
.route__icon .ri__cut { fill: var(--surface); } /* the reply's bubble hides the one behind it */
.route__title { margin-top: 26px; font: 500 24px / 30px var(--font-display); letter-spacing: -0.01em; }
.route__text { margin: 8px 0 22px; max-width: 30ch; font-size: 16px; line-height: 24px; color: var(--muted); text-wrap: pretty; }
.route__get { width: 100%; margin-top: auto; font: 500 18px / 24px var(--font-display); letter-spacing: -0.01em; text-wrap: pretty; }
.route__get > span { display: block; margin-bottom: 2px; font: 400 var(--t-small) / var(--lh-small) var(--font-sans); letter-spacing: 0; color: var(--muted); }
/* Where subgrid works, the six columns share their rows, so every title, text and "You get" starts on one line. */
@supports (grid-template-rows: subgrid) {
  .route__step { display: grid; grid-row: span 4; grid-template-rows: subgrid; row-gap: 0; justify-items: start; align-items: start; }
  .route__get { align-self: stretch; margin-top: 0; }
}

/* (03) Services */
.services__body { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: 64px; align-items: start; }
.services__reel { position: sticky; top: 32px; }
.frame { margin: 0; }
/* The showreel is 16:9 like its frame, and is shown whole: contain, never cover. */
.frame__box { position: relative; aspect-ratio: 16 / 9; background: var(--bg); }
.frame__video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; }
.frame .sel { inset: -8px; }
.frame figcaption { margin-top: 20px; }
/* The sheets are set apart by space and their wasabi numbers, not by rules. The number column is two figures wide
   (2ch: Funnel's figures are tabular, so 2ch is exactly "10"), so 1 to 10 share one title edge one gap away. */
.svc { display: grid; grid-template-columns: auto minmax(0, 1fr); column-gap: 24px; padding: 44px 0 44px; }
.svc:first-child { padding-top: 0; }
.svc__n { min-width: 2ch; font: 500 var(--t-h) / 1 var(--font-display); color: var(--accent); font-variant-numeric: tabular-nums; }
.svc__title { font: 500 28px / 1.15 var(--font-display); letter-spacing: -0.01em; }
.svc__lead { margin-top: 10px; max-width: 52ch; color: var(--muted); text-wrap: pretty; }
.svc__items { columns: 2; column-gap: 32px; margin-top: 24px; }
.svc__items li { display: flex; gap: 14px; padding: 9px 0; font-size: var(--t-small); line-height: var(--lh-small); break-inside: avoid; }
.svc__i { min-width: 28px; color: var(--muted); font-variant-numeric: tabular-nums; }
.svc__t { display: inline-block; transition: transform 320ms var(--ease-out); }

/* (04) Films */
.fcards { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 72px 16px; }
.fcard:nth-child(even) { margin-top: clamp(64px, 12.5vw, 180px); }
.fcard__frame { aspect-ratio: 16 / 10; border-radius: var(--radius); }
.fcard__loop { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; opacity: 0; transition: opacity 500ms var(--ease-out); }
.fcard__loop.is-playing { opacity: 1; }
.fcard__gray { position: absolute; inset: 0; transition: opacity 700ms var(--ease-out); }
.fcard__grayimg, .fcard__grayimg img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.fcard__grayimg img { filter: grayscale(1) contrast(1.06) brightness(0.9); }
.fcard__frame:hover .fcard__gray, .fcard__frame:focus-visible .fcard__gray, .fcard__frame.is-hot .fcard__gray { opacity: 0; }
.fcard__play { position: absolute; left: 20px; bottom: 20px; display: grid; place-items: center; width: 48px; height: 48px; border-radius: 50%; background: var(--accent); color: var(--accent-ink); transition: transform 400ms var(--ease-out); }
.fcard__play .ic { width: 16px; height: 16px; margin-left: 2px; }
.fcard__frame:hover .fcard__play { transform: scale(1.08); }
/* Every card's words start at one edge: the logo has a column of its own, left empty where a film has no logo. */
.fcard__meta { display: grid; grid-template-columns: 72px minmax(0, 1fr) auto; align-items: center; gap: 16px; margin-top: 18px; }
.fcard__logo { grid-column: 1; justify-self: start; max-width: 72px; }
.fcard__words { grid-column: 2; }
.fcard__tags { grid-column: 3; }
.fcard__client { font-size: var(--t-small); line-height: var(--lh-small); color: var(--muted); }
.fcard__title { font: 500 24px / 1.2 var(--font-display); letter-spacing: -0.01em; text-wrap: balance; }
.fcard__tags, .wcard__tags, .watch__tags { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 6px; }
@media (hover: none) { .fcard__gray { opacity: 0; } }

/* Let's talk */
.book-sec { overflow: hidden; padding-bottom: 40px; }
.book-sec__field { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0.55; pointer-events: none; }
.book-sec__head { position: relative; display: grid; justify-items: center; gap: 16px; max-width: 760px; margin: 0 auto 56px; text-align: center; }
.book { position: relative; max-width: 1040px; margin: 0 auto; }
.book__fallback { text-align: center; color: var(--muted); }
.book-sec__or { position: relative; margin-top: 28px; text-align: center; color: var(--muted); }

/* (05) FAQ */
.faq { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 656px); gap: 64px; align-items: start; }
.faq__side { position: sticky; top: 32px; display: grid; justify-items: start; gap: 18px; }
.faq__side .ghost { top: -78px; }
.faq__stills { display: flex; margin: 20px 0 14px 10px; }
/* Three stills held like a hand of cards; a border in the page's colour keeps each one's edge where they overlap. */
.faq__still { position: relative; width: 132px; aspect-ratio: 4 / 5; margin-left: -18px; overflow: hidden; border: 4px solid var(--bg); border-radius: 14px; transition: transform 600ms var(--ease-out); }
.faq__still img { width: 100%; height: 100%; object-fit: cover; }
.faq__still:nth-child(1) { transform: translate(0, 0) rotate(-7deg); }
.faq__still:nth-child(2) { transform: translate(0, -10px) rotate(2deg); z-index: 1; }
.faq__still:nth-child(3) { transform: translate(0, 0) rotate(8deg); }
.faq__list { display: grid; gap: 8px; }
.qa { border-radius: var(--radius); background: var(--surface); }
.qa__q { display: flex; align-items: center; justify-content: space-between; gap: 24px; padding: 28px; font: 500 18px / 32px var(--font-display); letter-spacing: -0.01em; cursor: pointer; list-style: none; }
.qa__q::-webkit-details-marker { display: none; }
/* A question that wraps splits into even lines, so no word is left alone on the last one. */
.qa__q > span { text-wrap: balance; }
.qa__icon { display: grid; place-items: center; flex: none; width: 32px; height: 32px; border-radius: 50%; background: var(--surface-2); transition: transform 360ms var(--ease-out); }
.qa__icon .ic { width: 14px; height: 14px; }
.qa[open] .qa__icon { transform: rotate(45deg); background: var(--accent); color: var(--accent-ink); }
.qa__a { padding: 0 28px 28px; max-width: 60ch; color: var(--muted); }
@media (prefers-reduced-motion: no-preference) { .qa[open] .qa__a { animation: rise 420ms var(--ease-out) both; } }

/* Showcase: films scattered down the page, each drifting at its own speed */
.showcase { position: relative; padding: var(--section-gap) var(--safe-r) 0 var(--safe-l); }
.showcase__head { display: flex; align-items: end; justify-content: space-between; gap: 24px; margin-bottom: 96px; }
.scatter { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: 16px; row-gap: 96px; }
.scatter__inner { will-change: transform; }
.scatter .tile__frame { aspect-ratio: 16 / 10; border-radius: var(--radius); }
.scatter__cap { margin-top: 12px; font-size: var(--t-small); line-height: var(--lh-small); }
.scatter__cap span { color: var(--muted); }
.s1 { grid-column: 1 / span 5; }
.s2 { grid-column: 8 / span 4; margin-top: 220px; }
.s3 { grid-column: 3 / span 4; }
.s4 { grid-column: 9 / span 4; margin-top: 80px; }
.s5 { grid-column: 1 / span 4; margin-top: 40px; }
.s6 { grid-column: 6 / span 6; margin-top: 200px; }
.s7 { grid-column: 2 / span 5; }
.s8 { grid-column: 9 / span 4; margin-top: 140px; }
.s9 { grid-column: 4 / span 5; }
.s10 { grid-column: 10 / span 3; margin-top: 260px; }
.s11 { grid-column: 1 / span 4; margin-top: 100px; }
.s12 { grid-column: 7 / span 5; }
/* The 13th film closes the scatter alone in its row, centred and the widest tile (8 of 12 columns, 869px at 1440),
   before the closing scene. Its poster is an arrival: a couple walking into este's reception. */
.s13 { grid-column: 3 / span 8; margin-top: 40px; }

/* ---------- The closing scene (fly.js): the visitor's brand on a wing over a dotted map of the world, Frame holding
   the line from the bottom left. The words and the field share one row; the stage runs edge to edge under them, so
   the map can fill the width and the line can cross it on the diagonal. Without script only the heading and the
   button show. */
.fly { position: relative; display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: 16px; align-items: end; margin-top: var(--section-gap); padding: 0 var(--safe-r) 0 var(--safe-l); }
.fly__words { position: relative; z-index: 1; grid-column: 1 / span 6; }
.fly__lead { margin-top: 16px; max-width: 40ch; text-wrap: pretty; }
.fly__form { position: relative; z-index: 1; grid-column: 8 / -1; display: grid; justify-items: start; }
.fly__field { display: grid; gap: 8px; width: 100%; max-width: 400px; }
.fly__label { font-size: var(--t-small); line-height: var(--lh-small); color: var(--muted); }
.fly__input { width: 100%; min-height: 52px; padding: 0 16px; border: 1px solid var(--edge); border-radius: 12px; background: var(--surface); color: var(--ink); font: 500 20px / 1 var(--font-display); letter-spacing: -0.01em; } /* taste-skill-ignore: a text field's edge */
.fly__input::placeholder { color: var(--muted); }
.fly__input:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.fly__btn { margin-top: 16px; max-width: 100%; }
/* A long name never pushes the button past its column: the letters end in an ellipsis instead. */
.fly__btn .roll { min-width: 0; max-width: 100%; }
.fly__btn .roll__row { overflow: hidden; text-overflow: ellipsis; }
.fly__btn .roll__row + .roll__row { right: 0; }
/* The scene and the footer under it fit the last screen, so the words, the field, the wing and the button are seen
   together where the scroll ends (the stage gives up to 400px of the screen to them). */
.fly__stage { position: relative; grid-column: 1 / -1; height: clamp(380px, min(43.5vw, 100svh - 400px), 760px); margin: 24px calc(var(--safe-r) * -1) 0 calc(var(--safe-l) * -1); pointer-events: none; }
.fly__map, .fly__svg { position: absolute; inset: 0; width: 100%; height: 100%; }
/* A vertical swipe over the drawing still scrolls the page on a phone (set on the svg itself: browsers differ on
   touch-action for the shapes inside it). */
.fly__svg { overflow: visible; touch-action: pan-y; }
.fly__name { font-family: var(--font-display); font-weight: 500; letter-spacing: -0.02em; }
/* The wing takes the pointer: a drag moves it, a tap or a click goes to the field. With motion off it can't be
   dragged, so the pointer only says it can be clicked. */
.fly__wing { pointer-events: auto; cursor: grab; }
.fly.is-dragging .fly__wing { cursor: grabbing; }
:root.is-still .fly__wing { cursor: pointer; }
@media (prefers-reduced-motion: reduce) { .fly__wing { cursor: pointer; } }
/* Home: an ink point in Bangladesh and its name under it, or in another spot round it where the wing or the line
   would cover it (fly.js picks the spot and sets it inline). */
.fly__home { position: absolute; width: 0; height: 0; }
.fly__home i { position: absolute; left: -5px; top: -5px; width: 10px; height: 10px; border-radius: 50%; background: var(--ink); } /* a place, not the brand: the wasabi stays with the wing, Frame and the button */
.fly__home span { position: absolute; left: 0; top: 12px; transform: translateX(-50%); font: 500 var(--t-small) / 20px var(--font-sans); color: var(--muted); white-space: nowrap; }
/* Kite's five signals on the world's biggest cities (fly.js): dim ink at rest, a little brighter while a name is on
   the wing (never brighter than home's name), and a wasabi flare in a soft glow, the brand's colour, as attention
   reaches one (the wave from home, the wing passing over it, a mouse resting on it, a tap). A flare comes up over
   160ms and goes out over 110ms, about 65% of the way in; only opacity and scale move. Reduced motion and Pause
   motion: lit or dim, never flaring. */
.fly__sigs { position: absolute; inset: 0; }
.fly__sig { position: absolute; width: var(--m); height: var(--m); margin: calc(var(--m) / -2) 0 0 calc(var(--m) / -2); }
.fly__sig > * { position: absolute; inset: 0; display: block; width: 100%; height: 100%; overflow: visible; }
.fly__sig-base { color: var(--ink); opacity: 0.32; }
.fly__sig.is-lit .fly__sig-base { opacity: 0.5; }
.fly__sig-hot { color: var(--accent); opacity: 0; }
.fly__sig > i { inset: -110%; width: auto; height: auto; border-radius: 50%; background: radial-gradient(closest-side, color-mix(in srgb, var(--accent) 40%, transparent), color-mix(in srgb, var(--accent) 12%, transparent) 55%, transparent); opacity: 0; transform: scale(0.4); }
.fly__sig.is-hot > :is(.fly__sig-hot, i) { opacity: 1; }
.fly__sig.is-hot > i { transform: none; }
@media (prefers-reduced-motion: no-preference) {
  :root:not(.is-still) .fly__sig { transition: transform 110ms var(--ease-exit); }
  :root:not(.is-still) .fly__sig.is-hot { transform: scale(1.18); transition: transform 160ms var(--ease-out); }
  :root:not(.is-still) .fly__sig > :is(.fly__sig-hot, i) { transition: opacity 110ms var(--ease-exit), transform 110ms var(--ease-exit); }
  :root:not(.is-still) .fly__sig.is-hot > :is(.fly__sig-hot, i) { transition: opacity 160ms var(--ease-out), transform 160ms var(--ease-out); }
  :root:not(.is-still) .fly__sig-base { transition: opacity 260ms var(--ease-exit); }
  :root:not(.is-still) .fly__sig.is-lit .fly__sig-base { transition: opacity 400ms var(--ease-out); }
}

/* The photo ring (orb.js): sixteen photos on a tilted ring, edge to edge across the screen. With no script, or if
   orb.js fails (.is-static), the same links sit in a grid. The ring's height is kept from the start, so nothing
   below it moves when the script arrives. */
.orb { margin-bottom: 144px; }
.orb__ring { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 16px; }
.orb__link { position: relative; display: block; -webkit-tap-highlight-color: transparent; }
.orb__link:focus-visible { outline: none; }
.orb__pic { position: relative; display: block; aspect-ratio: 4 / 5; overflow: hidden; border-radius: 6px; background: var(--surface); }
.orb__pic img { width: 100%; height: 100%; object-fit: cover; -webkit-user-drag: none; user-select: none; transition: transform 700ms var(--ease-out); }
/* Distance: orb.js sets --fog (0 at the front, 0.72 at the back). The photo under the cursor clears. */
.orb__fog { position: absolute; inset: 0; background: var(--bg); opacity: var(--fog, 0); pointer-events: none; transition: opacity var(--d-hover) var(--ease-out); }
.orb__link:focus-visible .orb__fog { opacity: 0; }
/* The selection frame draws on from the top-left corner over the photo under the cursor or the keyboard. When Frame is
   the cursor it is already the photo's frame, so the photo's own stays off: one frame at a time. */
.orb__link .sel { inset: -6px; opacity: 0; clip-path: inset(0 100% 100% 0); transition: opacity 120ms var(--ease-out), clip-path 380ms var(--ease-out); }
.orb__link:focus-visible .sel { opacity: 1; clip-path: inset(-12px); }
@media (hover: hover) {
  html:not(.has-buddy) .orb__link:hover .sel { opacity: 1; clip-path: inset(-12px); }
  .orb__link:hover .orb__pic img { transform: scale(1.05); }
  .orb__link:hover .orb__fog { opacity: 0; }
}
.cue .orb__ring {
  display: block; position: relative; height: clamp(360px, 52vw, 760px);
  margin: 0 calc(var(--safe-r) * -1) 0 calc(var(--safe-l) * -1);
  touch-action: pan-y; cursor: grab; user-select: none; -webkit-user-select: none;
  isolation: isolate; /* orb.js sorts the photos with z-index 1000 ± depth; this keeps that sort inside the ring, under the pill and the cursor */
  overflow-x: clip; /* the ring runs edge to edge already; its side photos must not widen the page (a phone zoomed out to fit them) */
}
.cue .orb__card { position: absolute; left: 50%; top: var(--orb-cy, 46%); width: var(--orb-w, 200px); margin: calc(var(--orb-w, 200px) * -0.625) 0 0 calc(var(--orb-w, 200px) / -2); opacity: 0; will-change: transform, opacity; }
.cue .orb.is-dragging .orb__ring, .cue .orb.is-dragging .orb__link { cursor: grabbing; }
.cue .orb.is-static .orb__ring { display: grid; height: auto; margin: 0; cursor: auto; }
.cue .orb.is-static .orb__card { position: static; width: auto; margin: 0; opacity: 1; will-change: auto; }
.orb__info { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: end; gap: 20px 64px; margin-top: 40px; }
.orb__client { margin-bottom: 6px; font-size: var(--t-small); line-height: var(--lh-small); color: var(--muted); }
.orb__title { font: 500 28px / 1.15 var(--font-display); letter-spacing: -0.01em; text-wrap: balance; }
.orb__text { margin-top: 10px; max-width: 56ch; color: var(--muted); text-wrap: pretty; }
.orb__side { display: grid; justify-items: end; gap: 12px; }
.orb__hint { display: none; }
.cue .orb.is-live .orb__hint { display: block; }
.orb__turn { display: flex; gap: 8px; }

/* The large photo: lifted out of its card (orb.js), on the plain night ground. */
.lightbox { width: 100vw; height: 100dvh; max-width: none; max-height: none; margin: 0; padding: 0; border: 0; overflow: hidden; background: transparent; color: var(--ink); }
.lightbox::backdrop { background: var(--bg); }
.lightbox[open] { display: grid; grid-template-rows: auto minmax(0, 1fr) auto; }
.lightbox:focus { outline: none; }
.lightbox__top { display: flex; align-items: center; gap: 6px; padding: 16px var(--safe-r) 12px var(--safe-l); }
.lightbox__top [data-lb-close] { margin-left: auto; }
.lightbox__top .tag.num { background: var(--surface); }
.lightbox__stage { container-type: size; display: grid; place-items: center; min-height: 0; padding: 4px var(--safe-r) 4px var(--safe-l); touch-action: pan-y; }
.lightbox__img { width: min(100cqw, 100cqh * 0.8); height: auto; aspect-ratio: 4 / 5; max-width: none; border-radius: 10px; background: #fff; user-select: none; -webkit-user-drag: none; will-change: transform; }
.lightbox__foot { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: 12px 32px; padding: 14px var(--safe-r) max(20px, var(--safe-b)) var(--safe-l); }
.lightbox__cap { max-width: 70ch; font-size: var(--t-small); line-height: var(--lh-small); color: var(--muted); }
.lightbox__steps { display: flex; gap: 8px; }
@media (prefers-reduced-motion: no-preference) {
  .lightbox[open]::backdrop { animation: fade-in 280ms var(--ease-out) both; }
  .lightbox.is-closing::backdrop { animation: fade-out 300ms var(--ease-exit) both; }
}
/* ---------- Footer ---------- */
.foot { padding: 56px var(--safe-r) calc(108px + var(--safe-b)) var(--safe-l); }
/* The home page's pill steps aside over the closing scene, so its footer needs no room for it. */
:root:has([data-fly-stage]) .foot { padding-bottom: calc(40px + var(--safe-b)); }
.foot__top { display: flex; align-items: center; gap: 20px; }
.foot__mark { width: 44px; color: var(--accent); flex: none; }
.foot__mark .mark { transition: transform 340ms var(--ease-in-out); }
.foot__line { font: 500 20px / 1.3 var(--font-display); letter-spacing: -0.01em; max-width: 40ch; }
.foot__row { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 12px 32px; margin-top: 40px; }
.foot__links { display: flex; flex-wrap: wrap; gap: 4px 24px; font-size: var(--t-small); }
.foot__links a { position: relative; display: inline-flex; align-items: center; min-height: 44px; color: var(--muted); }
.foot__links a:hover, .foot__links a:focus-visible { color: var(--ink); }
/* The underline draws in from the left under the link you point at. */
.foot__links a::after { content: ""; position: absolute; left: 0; right: 0; bottom: 9px; height: 2px; background: currentColor; clip-path: inset(0 100% 0 0); transition: clip-path 300ms var(--ease-out); }
.foot__links a:hover::after, .foot__links a:focus-visible::after { clip-path: inset(0); }
.foot__motion { min-height: 44px; font-size: var(--t-small); color: var(--muted); text-decoration: underline; text-underline-offset: 0.22em; }

/* ---------- Work page ---------- */
.workpage { padding: calc(var(--section-gap) * 0.55) var(--safe-r) 0 var(--safe-l); }
.workpage__head { position: relative; display: grid; gap: 16px; }
.workpage__head .ghost { top: -88px; }
.filters { display: flex; flex-wrap: wrap; gap: 8px; margin: 48px 0 40px; }
.filter { display: inline-flex; align-items: center; gap: 8px; min-height: 44px; padding: 0 18px; border-radius: var(--r-pill); background: var(--surface); font: 500 14px / 1 var(--font-display); transition: transform var(--d-press) var(--ease-out); }
.filter:active { transform: scale(0.97); }
.filter[aria-pressed="true"] { background: var(--ink); color: var(--bg); }
.filter__n { font-variant-numeric: tabular-nums; opacity: 0.6; }
.wgrid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 56px 16px; }
.wgrid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.wcard__frame { aspect-ratio: 16 / 10; border-radius: var(--radius); }
.wcard__link { position: relative; display: block; overflow: hidden; background: var(--surface); }
.wcard__link .tile__media, .wcard__link img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.wcard__meta { display: flex; align-items: start; justify-content: space-between; gap: 16px; margin-top: 16px; }
.wcard__client { font-size: var(--t-small); line-height: var(--lh-small); color: var(--muted); }
.wcard__title { font: 500 20px / 1.25 var(--font-display); letter-spacing: -0.01em; }
.wcard__title a:hover { text-decoration: underline; text-underline-offset: 0.2em; }

/* ---------- A film's own page ---------- */
.watch { padding: 16px var(--safe-r) 0 var(--safe-l); }
.watch__back { font-size: var(--t-small); color: var(--muted); }
.watch__head { display: flex; flex-wrap: wrap; align-items: end; justify-content: space-between; gap: 16px 32px; margin: 40px 0 32px; }
.watch__client { display: flex; align-items: center; gap: 12px; margin-bottom: 12px; font-size: var(--t-small); color: var(--muted); }
.watch__client .blogo { max-height: 28px; }
.watch__stage { position: relative; max-width: min(100%, calc((100svh - 140px) * var(--ar))); margin: 0 auto; }
.watch__video { width: 100%; height: auto; aspect-ratio: var(--ar); border-radius: var(--radius); background: #000; }
.watch__error { position: absolute; inset: 0; display: grid; place-items: center; padding: 24px; text-align: center; background: var(--bg); }
.watch__desc { max-width: 60ch; margin-top: 32px; font-size: var(--t-lead); line-height: 1.6; }
.watch__cta { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 32px; }
.watch__more { padding-top: var(--section-gap); }
.watch__more-title { margin-bottom: 32px; font: 500 28px / 1.2 var(--font-display); }

.nf { display: grid; align-content: center; justify-items: start; gap: 20px; min-height: 70svh; padding: 48px var(--safe-r) 64px var(--safe-l); }
.nf__links { display: flex; flex-wrap: wrap; gap: 10px; }

/* ---------- Player dialog ---------- */
.player { width: 100vw; height: 100dvh; max-width: none; max-height: none; margin: 0; padding: 0; border: 0; overflow: hidden; background: transparent; color: var(--ink); }
.player::backdrop { background: #160d12; }
.player[open] { display: grid; grid-template-rows: auto minmax(0, 1fr) auto; }
.player:focus { outline: none; }
@media (prefers-reduced-motion: no-preference) {
  .player[open]::backdrop { animation: fade-in 280ms var(--ease-out) both; }
  .player.is-closing::backdrop { animation: fade-out 220ms var(--ease-exit) both; }
}
.player__top { display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 16px var(--safe-r) 12px var(--safe-l); }
.player__top .tag:not(.tag--ai) { background: var(--surface); }
.player__tags { display: flex; flex-wrap: wrap; gap: 6px; }
.player__stage { container-type: size; display: grid; place-items: center; min-height: 0; padding: 12px var(--safe-r) 12px var(--safe-l); }
.player__frame { position: relative; will-change: transform; }
.player__frame .sel { inset: -10px; opacity: 0; }
.player.is-landed .player__frame .sel { opacity: 1; transition: opacity 160ms var(--ease-out); }
.player video { display: block; width: min(100cqw, 100cqh * var(--ar, 1.7778)); height: auto; aspect-ratio: var(--ar, 1.7778); max-width: none; max-height: none; background: var(--bg); }
.player__info { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 12px 32px; align-items: end; padding: 12px var(--safe-r) max(24px, var(--safe-b)) var(--safe-l); }
.player__info h2 { font: 500 var(--step-2) / 1.1 var(--font-display); letter-spacing: -0.015em; }
.player__info p { max-width: 70ch; color: var(--muted); margin-top: 6px; }
.player__nav, .player__steps { display: flex; align-items: center; gap: 8px; }
.player__end { position: absolute; inset: 0; z-index: 2; display: grid; place-content: center; justify-items: center; gap: 12px; padding: 24px; background: color-mix(in srgb, var(--bg) 86%, transparent); }
.player__end[hidden], .player__error[hidden] { display: none; }
.player__error { position: absolute; inset: 0; z-index: 3; display: grid; place-items: center; padding: 24px; text-align: center; background: var(--bg); }

/* ---------- The cursor: the soft arrow from the Pickaxe film (scripts/make-cursor.mjs) ----------
   A CSS cursor, so it never lags: bone with a 1.5px night edge everywhere; over anything that can be pressed, night
   with a 2px wasabi edge (there is no hand cursor, so the arrow says it, and it stays visible on wasabi buttons). Text
   fields keep the text cursor. The hotspot is the tip, 5 4 (scripts/make-cursor.mjs draws both).
   Mouse and trackpad only; Frame rides beside it (.fbuddy below). */
@media (hover: hover) and (pointer: fine) {
  html {
    cursor: url("/assets/img/cursor.png") 5 4, auto;
    cursor: -webkit-image-set(url("/assets/img/cursor.png") 1x, url("/assets/img/cursor@2x.png") 2x) 5 4, auto;
    cursor: image-set(url("/assets/img/cursor.png") 1x, url("/assets/img/cursor@2x.png") 2x) 5 4, auto;
  }
  :is(a[href], button:not(:disabled), summary, label[for], select, [role="button"], [data-cursor], .qa__q) {
    cursor: url("/assets/img/cursor-on.png") 5 4, pointer !important;
    cursor: -webkit-image-set(url("/assets/img/cursor-on.png") 1x, url("/assets/img/cursor-on@2x.png") 2x) 5 4, pointer !important;
    cursor: image-set(url("/assets/img/cursor-on.png") 1x, url("/assets/img/cursor-on@2x.png") 2x) 5 4, pointer !important;
  }
  :is(input:not([type="checkbox"], [type="radio"], [type="range"], [type="button"], [type="submit"], [type="reset"]), textarea, [contenteditable="true"]) { cursor: text !important; }
}

/* ---------- Frame, the mascot (frame.js) ----------
   The pill's mark is Frame at 40px: its eyes trail the pointer by about 150ms, it blinks every 3 to 6 seconds and
   breathes in on a 3.2s cycle (narrower and taller at the top of the breath), never while asleep or off screen. Beside
   the cursor it rides at 44px (.fbuddy), and the 404 page has it at 200px. */
.frame-svg { display: block; overflow: visible; }
.pill__mark.has-frame .frame-svg { width: 40px; height: 40px; }
/* One Frame on screen at a time: while Frame rides beside the cursor (frame.js), the pill shows the logo. */
.pill__mark.has-frame .mark, html.has-buddy .pill__mark.has-frame .frame-svg { display: none; }
html.has-buddy .pill__mark.has-frame .mark { display: block; }
@media (prefers-reduced-motion: no-preference) {
  .frame-breathe { transform-origin: 50% 81%; animation: frame-breathe 3.2s cubic-bezier(0.45, 0, 0.55, 1) infinite; }
  .is-still .frame-breathe, .frame-breathe.is-asleep { animation: none; }
  .pill:not(.is-shown):not(:focus-within) .frame-breathe, .pill.is-aside:not(:focus-within) .frame-breathe { animation-play-state: paused; }
}
@keyframes frame-breathe { 50% { transform: scale(0.992, 1.014); } }

/* Frame beside the cursor (frame.js): its box's top-left corner sits 14px right of and 20px below the arrow's tip, so it
   clears the arrow, and it swings from that corner when it leans into a fast move. It trails the pointer by about 70ms
   (frame.js moves .fbuddy by transform). Over a film a tag says what a press does. */
.fbuddy { position: fixed; left: 0; top: 0; z-index: 90; width: 0; height: 0; pointer-events: none; transition: opacity 160ms var(--ease-out); }
.fbuddy__body { position: absolute; left: 14px; top: 20px; width: 44px; height: 44px; transform-origin: 0 0; }
.fbuddy__body .frame-svg { width: 44px; height: 44px; }
/* A 1px night keyline: wasabi on a light photo is about 1:1, so without it the frame and eyes vanish over white shirts. */
.fbuddy__body .frame-svg { filter: drop-shadow(0 0 0.6px var(--bg)) drop-shadow(0 0 0.6px var(--bg)); }
.fbuddy__tag { position: absolute; left: 64px; top: 30px; padding: 6px 10px 7px; border-radius: 999px; background: var(--accent); color: var(--accent-ink); font: 600 13px / 1 var(--font-sans); white-space: nowrap; opacity: 0; transform: translateX(-6px); transition: opacity 140ms var(--ease-out), transform 200ms var(--ease-out); }
.fbuddy.is-ai .fbuddy__tag { background: var(--ai); color: var(--bg); }
.fbuddy.has-tag .fbuddy__tag { opacity: 1; transform: none; transition-delay: 60ms; }
.fbuddy.is-gone, .fbuddy.is-parked { opacity: 0; }

/* The holder keeps the drawing's 220:210 shape before frame.js fills it, so the 404 page doesn't jump. */
.nf__frame { width: 200px; aspect-ratio: 220 / 210; margin-bottom: 32px; }
.nf__frame .frame-svg { width: 200px; height: auto; aspect-ratio: 220 / 210; }

/* ---------- Micro motion: each part arrives or answers in its own way ----------
   Transform, opacity and clip-path only. Every hidden starting state lives inside no-preference and :not(.is-still),
   so reduced motion and "Pause motion" show the finished page. cue.js numbers the parts (--k). */
@media (prefers-reduced-motion: no-preference) {
  /* Process: until a step lights (cue.js marks it .is-lit, in order, 150ms apart, so all six are lit 750ms after the
     row arrives), its drawing waits at 40% with its wasabi part out, its moving part parked where its move starts, and
     its stretch of line not yet run. Lighting fades the drawing up and runs the line from its disc's edge to the next
     one's in 150ms, arriving as the next one lights. */
  .cue:not(.is-still) .route.is-waiting .route__icon { transition: opacity 300ms var(--ease-out); }
  .cue:not(.is-still) .route.is-waiting .route__step::after { transition: transform 150ms var(--ease-in-out); }
  .cue:not(.is-still) .route.is-waiting .route__step:not(.is-lit) .route__icon { opacity: 0.4; }
  .cue:not(.is-still) .route.is-waiting .route__step:not(.is-lit) .ri__sig { opacity: 0; }
  .cue:not(.is-still) .route.is-waiting .route__step:not(.is-lit) .ri__pen { transform: translate(-22px, 3.5px); }
  .cue:not(.is-still) .route.is-waiting .route__step:not(.is-lit) .ri__lens { transform: translate(-5px, 2px); }
  .cue:not(.is-still) .route.is-waiting .route__step:not(.is-lit)::after { transform: var(--run); }
  /* Each drawing's one move, played once as it lights (.is-play): the call's light blinks on; the magnifier sweeps and
     finds the person; the reply types; the pencil draws its line, its tip on the stroke; the files drop into the tray;
     this round's bar rises. Each is short, so the step that has just lit leads. */
  .route__icon :is(.ri__lens, .ri__who, .ri__dots circle, .ri__line, .ri__pen, .ri__drop, .ri__now) { transform-box: fill-box; }
  .route__icon :is(.ri__who, .ri__now) { transform-origin: 50% 100%; }
  .cue:not(.is-still) .is-play .ri__on { animation: ri-on 360ms linear both; }
  .cue:not(.is-still) .is-play .ri__lens { animation: ri-scan 420ms var(--ease-in-out) both; }
  .cue:not(.is-still) .is-play .ri__who { animation: ri-pop 280ms var(--ease-out) 140ms both; }
  .cue:not(.is-still) .is-play .ri__dots circle { animation: ri-type 420ms var(--ease-in-out) both; }
  .cue:not(.is-still) .is-play .ri__dots circle:nth-child(2) { animation-delay: 60ms; }
  .cue:not(.is-still) .is-play .ri__dots circle:nth-child(3) { animation-delay: 120ms; }
  .cue:not(.is-still) .is-play .ri__line { animation: ri-draw 560ms linear both; }
  .cue:not(.is-still) .is-play .ri__pen { animation: ri-pen 560ms linear both; }
  .cue:not(.is-still) .is-play .ri__drop { animation: ri-drop 380ms var(--ease-out) both; }
  .cue:not(.is-still) .is-play .ri__now { animation: ri-rise 680ms var(--ease-out) both; }

  /* Services: each sheet's number rises out of its line, then the list under it fills in, row by row. */
  .cue:not(.is-still) .svc__n { clip-path: inset(100% 0 0 0); transform: translateY(40%); }
  .cue:not(.is-still) .svc.is-in .svc__n { clip-path: inset(0 0 -10% 0); transform: none; transition: clip-path 700ms var(--ease-out) 120ms, transform 700ms var(--ease-out) 120ms; }
  .cue:not(.is-still) .svc__items li { opacity: 0; transform: translateY(10px); }
  .cue:not(.is-still) .svc.is-in .svc__items li { opacity: 1; transform: none; transition: opacity 480ms var(--ease-out), transform 640ms var(--ease-out); transition-delay: calc(260ms + var(--k, 0) * 35ms); }

  /* FAQ: the three stills wait as one pile (in view, never hidden), then are dealt into a fan as they arrive.
     The deal's backwards fill holds the pile through its delay, so nothing jumps; once dealt, hover takes over. */
  .cue:not(.is-still) .faq__stills:not(.is-in) .faq__still:nth-child(1) { transform: translate(114px, 0) rotate(0deg); }
  .cue:not(.is-still) .faq__stills:not(.is-in) .faq__still:nth-child(3) { transform: translate(-114px, 0) rotate(0deg); }
  .cue:not(.is-still) .faq__stills.is-in .faq__still:nth-child(1) { --deal: translate(114px, 0) rotate(0deg); animation: deal 760ms var(--ease-out) 240ms backwards; }
  .cue:not(.is-still) .faq__stills.is-in .faq__still:nth-child(3) { --deal: translate(-114px, 0) rotate(0deg); animation: deal 760ms var(--ease-out) 320ms backwards; }

  /* Booking: a day's times arrive top to bottom when the day is picked. */
  .cue:not(.is-still) .book__slots > li { animation: pui-in 360ms var(--ease-out) both; animation-delay: calc(min(var(--k, 0), 12) * 22ms); }
}
/* Services: the row you read is marked: its number turns wasabi (a colour, so it stays with reduced motion)… */
@media (hover: hover) { .svc__items li:hover .svc__i { color: var(--accent); } }
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  /* …and its words step 4px in. */
  .svc__items li:hover .svc__t { transform: translateX(4px); }
  /* FAQ: pointing at the stills fans them out; pointing at a closed question turns its plus a quarter. */
  .faq__stills:hover .faq__still:nth-child(1) { transform: translate(-18px, 0) rotate(-12deg); }
  .faq__stills:hover .faq__still:nth-child(2) { transform: translate(0, -20px) rotate(1deg); }
  .faq__stills:hover .faq__still:nth-child(3) { transform: translate(18px, 0) rotate(13deg); }
  .qa:not([open]) > .qa__q:hover .qa__icon { transform: rotate(90deg); }
  /* Footer: the mark turns into a kite, as in the intro. */
  .foot__mark:hover .mark { transform: rotate(45deg); transition-duration: 520ms; }
  /* Arrows lean the way they go; Close turns a quarter. */
  :is(a, button):hover > .ic--i-next { transform: translateX(3px); }
  :is(a, button):hover > .ic--i-prev { transform: translateX(-3px); }
  :is(a, button):hover > .ic--i-arrow { transform: translate(2px, -2px); }
  :is(a, button):hover > .ic--i-close { transform: rotate(90deg); }
}
@keyframes deal { from { transform: var(--deal); } }
/* Each names its end state: the parts rest at opacity 0 until they land, so an implied end would stay hidden. */
@keyframes pui-in { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
/* The process drawings' moves (units are the drawings' own 48 grid). */
@keyframes ri-on { 0% { opacity: 0; } 30%, 70%, 100% { opacity: 1; } 50% { opacity: 0.3; } }
@keyframes ri-scan { 0% { transform: translate(-5px, 2px); } 55% { transform: translate(2px, -1px); } 100% { transform: none; } }
@keyframes ri-pop { from { opacity: 0; transform: scale(0.4); } to { opacity: 1; transform: none; } }
@keyframes ri-type { 0% { opacity: 0; transform: translateY(3px); } 30% { opacity: 1; transform: translateY(-3px); } 60%, 100% { opacity: 1; transform: none; } }
@keyframes ri-draw { from { clip-path: inset(-40% 100% -40% -20%); } to { clip-path: inset(-40% 0 -40% -20%); } }
/* The pencil's tip rides the line it draws: the squiggle's ends and the middles of its three curves. */
@keyframes ri-pen { 0% { transform: translate(-22px, 3.5px); } 17% { transform: translate(-18px, -0.8px); } 33% { transform: translate(-14.5px, 2.5px); } 50% { transform: translate(-11px, 6px); } 67% { transform: translate(-7px, 3px); } 83% { transform: translate(-3.5px, -0.8px); } 100% { transform: none; } }
@keyframes ri-drop { from { opacity: 0; transform: translateY(-10px); } to { opacity: 1; transform: none; } }
@keyframes ri-rise { from { opacity: 0; transform: scaleY(0.3); } to { opacity: 1; transform: none; } }

/* ---------- Still: no drifting, no looping ---------- */
.is-still .stream__col, .is-still .status__dot::after { animation-play-state: paused; }
.is-still .scatter__inner { transform: none !important; }
@media (prefers-reduced-motion: reduce) {
  .stream__col, .status__dot::after { animation: none; }
  .tile__frame .tile__media img { transition: none; }
}

/* ---------- Narrower screens ---------- */
@media (max-width: 1180px) {
  .brands { grid-template-columns: minmax(0, 1fr); gap: 28px; }
  .services__body { grid-template-columns: minmax(0, 1fr); }
  .services__reel { position: relative; top: 0; }
  .faq { grid-template-columns: minmax(0, 1fr); }
  .faq__side { position: relative; top: 0; }
  /* Two across, each card turned on its side: the drawing at the left, the words beside it. */
  .cards { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
  /* The drawing's column is as wide as the widest icon at this size, and each icon is centred in it, so every title
     starts at the same x and the drawings share one centre line. */
  .card { display: grid; grid-template-columns: calc(var(--iw-max, 64) * 0.875px) minmax(0, 1fr); column-gap: 18px; align-content: start; padding: 20px 22px 22px 20px; }
  .card__icon { --k: 0.875; grid-row: 1 / span 2; justify-self: center; margin-top: 0; }
  .card__title { grid-column: 2; margin-top: 2px; }
  .card__text { grid-column: 2; }
  /* Film cards are half the width here: the title takes the row beside the logo, the tags go under it, on the
     title's edge. The zig-zag steps less, and the rows close up. */
  .fcards { row-gap: 48px; }
  .fcard__meta { grid-template-columns: 60px minmax(0, 1fr); gap: 10px 14px; }
  .fcard__tags { grid-column: 2; justify-content: flex-start; }
  .fcard__logo { max-width: 60px; }
}
/* At 1,320 px and under, six columns would be 175 px or narrower, so the route turns down the page: a step to a row,
   its disc on the line at the left, what we do beside it (the title centred on the disc) and what you get at the
   right, level with the title. It keeps the page's margins. */
@media (max-width: 1320px) {
  .route { --node: 64px; --gap: 44px; --run: scaleY(0); grid-template-columns: minmax(0, 1fr); row-gap: var(--gap); }
  .route__step { display: grid; grid-row: auto; grid-template-rows: none; grid-template-columns: var(--node) minmax(0, 1fr) minmax(0, 0.8fr); column-gap: 28px; align-items: start; }
  .route__node { grid-row: 1 / span 2; }
  .route__title { grid-column: 2; margin-top: 17px; }
  .route__text { grid-column: 2; max-width: 54ch; margin-bottom: 0; }
  .route__get { grid-column: 3; grid-row: 1 / span 2; align-self: start; margin-top: 15px; }
  .route__step:not(:last-child)::before, .route__step:not(:last-child)::after { left: calc(var(--node) / 2 - 1px); top: var(--node); width: 2px; height: calc(100% + var(--gap) - var(--node)); }
  .route__step::after { transform-origin: 50% 0; }
}
@media (max-width: 900px) {
  .nav { grid-template-columns: 1fr auto; }
  .nav__links { display: none; }
  .wgrid--3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  /* The hero stacks: the films stream across the top, the words centred under them. */
  .hero { display: flex; flex-direction: column; height: auto; padding: 0; }
  .stream { order: -1; height: clamp(300px, 46vw, 420px); flex: none; -webkit-mask: linear-gradient(transparent 0, #000 14%, #000 80%, transparent 100%); mask: linear-gradient(transparent 0, #000 14%, #000 80%, transparent 100%); } /* taste-skill-ignore: mask, the film stream fades at its ends */
  .stream__plane { inset: -40% -20%; gap: 10px; }
  .stream__run { gap: 10px; padding-bottom: 10px; }
  .hero__text { align-self: center; max-width: 620px; padding: 8px var(--safe-r) 24px var(--safe-l); text-align: center; display: grid; justify-items: center; }
  .hero__actions { justify-content: center; }
  .brands { text-align: center; justify-items: center; }
  .brands__title { max-width: none; }
  .marquee { width: 100%; }
}
@media (max-width: 760px) {
  .nav__view { display: none; }
  .nav__logo { width: 62px; }
  .pill { transform: translate(-50%, 0); }
  .stream__plane { inset: -40% -30%; }
  .brands { padding-top: 96px; padding-bottom: 24px; text-align: center; justify-items: center; }
  .brands__title { max-width: none; }
  .brand { height: 96px; padding: 0 22px; }
  .marquee__track { --fade: 40px; }
  .sec__head { grid-template-columns: minmax(0, 1fr); justify-items: center; text-align: center; margin-bottom: 40px; }
  .sec__head .sec__lead { justify-self: center; }
  .ghost { left: 50%; transform: translateX(-50%); top: -58px; }
  .cards { grid-template-columns: minmax(0, 1fr); gap: 10px; }
  .card { grid-template-columns: calc(var(--iw-max, 64) * 0.8125px) minmax(0, 1fr); column-gap: 16px; padding: 18px 18px 20px; }
  .card__icon { --k: 0.8125; }
  .card__title { font-size: 18px; }
  .cta-band { grid-template-columns: 40px minmax(0, 1fr); gap: 14px 16px; padding: 20px 18px; }
  .cta-band__kite { width: 40px; }
  .cta-band .btn { grid-column: 1 / -1; }
  /* On a phone what you get goes under what we do. */
  .route { --node: 56px; --gap: 36px; }
  .route__step { grid-template-columns: var(--node) minmax(0, 1fr); column-gap: 18px; }
  .route__title { margin-top: 13px; font-size: 20px; }
  .route__get { grid-column: 2; grid-row: auto; margin-top: 14px; font-size: 16px; line-height: 22px; }
  .svc { column-gap: 16px; }
  .svc__title { font-size: 24px; }
  .svc__items { columns: 1; }
  .fcards { grid-template-columns: minmax(0, 1fr); gap: 48px; }
  .fcard:nth-child(even) { margin-top: 0; }
  .fcard__meta { grid-template-columns: 60px minmax(0, 1fr); gap: 10px 14px; }
  .fcard__tags { grid-column: 2; justify-content: flex-start; }
  .fcard__logo { max-width: 60px; }
  .faq__side { justify-items: center; text-align: center; }
  .faq__side .ghost { left: 50%; }
  .qa__q { padding: 20px; font-size: 17px; line-height: 26px; }
  .qa__a { padding: 0 20px 22px; }
  .showcase__head { flex-direction: column; align-items: center; text-align: center; margin-bottom: 56px; }
  .scatter { grid-template-columns: repeat(6, minmax(0, 1fr)); row-gap: 40px; }
  .scatter__item { grid-column: 1 / span 5 !important; margin-top: 0 !important; }
  .scatter__item:nth-child(even) { grid-column: 2 / span 5 !important; }
  .scatter__item.s13 { grid-column: 1 / -1 !important; } /* the closer goes full width, not a 13th zig-zag tile */
  .fly { display: block; margin-top: 120px; text-align: center; }
  .fly__lead { margin-left: auto; margin-right: auto; }
  .fly__form { justify-items: center; margin-top: 32px; }
  .fly__field { max-width: 360px; text-align: left; }
  .fly__stage { height: clamp(320px, 100svh - 480px, 460px); margin: 16px calc(var(--safe-r) * -1) 0 calc(var(--safe-l) * -1); }
  :root:has([data-fly-stage]) .foot__mark { display: none; } /* the kite above is the mark */
  .orb { margin-bottom: 96px; }
  .orb__ring { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
  .orb__info { grid-template-columns: minmax(0, 1fr); justify-items: center; text-align: center; margin-top: 24px; }
  .orb__title { font-size: 24px; }
  .orb__side { justify-items: center; }
  .foot__top { flex-direction: column; text-align: center; }
  .foot__row { flex-direction: column; text-align: center; }
  .foot__links { justify-content: center; }
  .wgrid, .wgrid--3 { grid-template-columns: minmax(0, 1fr); gap: 40px; }
  .workpage__head { justify-items: center; text-align: center; }
  .filters { justify-content: center; }
  .player__info { grid-template-columns: minmax(0, 1fr); }
}
