/* ==========================================================
   Sprite's Studio
   Editorial layout · adapts to light and dark
   ========================================================== */

/* FONTS
   Self-hosted; the page makes zero third-party requests.

   Outfit carries the display type — the big, tightly-tracked headings. Inter
   carries body copy and UI. Both are variable fonts, one file per subset, so
   `font-weight: 100 900` on a single face rather than a file per weight. The
   unicode-range split means latin-ext only downloads if a visitor hits those
   glyphs. To update: re-run the download, keep font-display: swap. */
@font-face {
  font-family: 'Outfit';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url(fonts/Outfit-normal-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Outfit';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url(fonts/Outfit-normal-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url(fonts/Inter-normal-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url(fonts/Inter-normal-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* THEME
   Every colour holds both values via light-dark(LIGHT, DARK) — one place to edit,
   so the two themes can't drift apart. Which one resolves is decided purely by
   `color-scheme` below, which is also what the nav toggle flips.
   Both values of each pair are checked to at least 4.5:1 against their background;
   re-check if you change any of them. */
:root {
  color-scheme: light dark;            /* follow the device by default */

  /* Paper is near-white / near-black — no warm cast. The muted text tones are
     one ink at three strengths rather than three separate colours, so they
     stay in family automatically and can sit on any paper shade. */
  --paper:     light-dark(#ffffff, #0c0d0c);
  --paper-2:   light-dark(#f5f5f7, #141614);
  --paper-3:   light-dark(#ececef, #1c1e1c);

  --ink:       light-dark(#0e0e0c, #f4f5f3);
  --ink-2:     light-dark(#0e0e0cc7, #f4f5f3c2);  /* body copy      ~9.7:1 */
  --ink-3:     light-dark(#0e0e0c9e, #f4f5f39e);  /* small labels   ~5.2:1 */
  --rule:      light-dark(#0e0e0c1f, #f4f5f31c);  /* hairlines, barely there */
  --rule-2:    light-dark(#0e0e0c33, #f4f5f333);

  --accent:    light-dark(#ad3410, #ff5c2b);  /* text + buttons — needs 4.5:1 */
  --accent-hi: light-dark(#e0431a, #ff5c2b);  /* decoration only, never text */
  --accent-ink: light-dark(#ffffff, #14120f);
  --accent-soft: light-dark(#ad341014, #ff5c2b1f);
  --danger:    light-dark(#d64532, #ff8f7d);
  --g1: light-dark(#ff8a3d, #ff9a4d);   /* gradient stops — decoration only */
  --g2: light-dark(#ff2d78, #ff4d86);

  /* Outfit is a display face — big headings only. Long copy stays in Inter,
     which is built for text sizes. --mono is a system stack, no download. */
  --display: "Outfit", ui-sans-serif, system-ui, sans-serif;
  --sans:  "Inter", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  --mono:  ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;

  --shell: 1600px;                     /* wide canvas; text blocks self-limit in ch */
  --pad: clamp(1.25rem, 3.2vw, 3.25rem);
  --band-y: clamp(4rem, 9vw, 8.5rem);

  --r:    12px;                        /* cards */
  --r-sm: 8px;                         /* buttons, inputs */

  /* motion — expo-out, the curve that makes UI feel like it settles */
  --out: cubic-bezier(0.16, 1, 0.3, 1);
  --inout: cubic-bezier(0.77, 0, 0.175, 1);
  --fast: .2s;
  --med: .46s;
}

/* The toggle writes data-theme on <html>; these pin the scheme, which also fixes
   native controls (scrollbars, form widgets) to match. No data-theme = follow the OS. */
:root[data-theme="light"] { color-scheme: light; }
:root[data-theme="dark"]  { color-scheme: dark; }

/* ---------- base ---------- */
*, *::before, *::after { box-sizing: border-box; }

html {
  scroll-behavior: smooth;
  scroll-padding-top: 84px;
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 1.0625rem;
  line-height: 1.6;
  font-weight: 400;
  letter-spacing: 0;            /* body sits near zero tracking */
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

h1, h2, h3, h4 { margin: 0; font-weight: 600; }
p { margin: 0; text-wrap: pretty; }
ul, ol, dl, dd, figure { margin: 0; padding: 0; list-style: none; }
img { display: block; max-width: 100%; height: auto; }
a { color: inherit; text-decoration: none; }
button, input, select, textarea { font: inherit; color: inherit; }

::selection { background: var(--accent); color: var(--accent-ink); }

:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 3px; }

.skip-link {
  /* fixed, not absolute — an absolutely positioned skip link reappears at the
     top of the document, off-screen, if focus reaches it after any scrolling. */
  position: fixed; left: -9999px; z-index: 999;
  background: var(--accent); color: var(--accent-ink);
  padding: .8rem 1.2rem; font-weight: 600;
}
.skip-link:focus { left: 1rem; top: 1rem; }

/* ---------- shell ---------- */
.shell {
  width: 100%;
  max-width: var(--shell);
  margin-inline: auto;
  padding-inline: var(--pad);
}
.shell--tight { max-width: 860px; }

.band { padding-block: var(--band-y); }

/* ---------- type scale ----------
   Display type is set tight: the bigger it gets the more negative the tracking
   needs to be, or the letters drift apart and it reads as a wordmark rather
   than a sentence. Body copy stays at zero. */
.h2 {
  font-family: var(--display);
  font-weight: 500;
  font-size: clamp(2.15rem, 5vw, 4.1rem);
  line-height: 1.0;
  letter-spacing: -0.035em;
  text-wrap: balance;
}

/* Section labels are monospace — a small technical counterweight to all the
   soft geometry, and it reads as a studio rather than an agency. */
.kicker {
  font-family: var(--mono);
  font-size: .73rem;
  font-weight: 400;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ink-3);
  margin-bottom: 1.35rem;
  display: flex; align-items: center; gap: .7rem;
}
.kicker::after {
  content: "";
  flex: 1; height: 1px;
  background: var(--rule);
  max-width: 5rem;
}

.head { max-width: 52rem; margin-bottom: clamp(2.75rem, 5.5vw, 4.5rem); }
.head__sub { color: var(--ink-2); margin-top: 1.5rem; max-width: 58ch; font-size: 1.02rem; }

/* ---------- buttons ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--accent);
  color: var(--accent-ink);
  font-size: .96rem;
  font-weight: 500;
  letter-spacing: -0.005em;
  padding: .85rem 1.6rem;
  border: 1px solid transparent;
  border-radius: 100px;                            /* pill — the modern tell */
  cursor: pointer;
  /* Named properties only, never `all` — `all` would animate the pseudo-element
     and border-radius too and cost frames for nothing. */
  transition: transform 160ms var(--out), background-color var(--fast) ease,
              border-color var(--fast) ease, color var(--fast) ease,
              box-shadow var(--fast) var(--out);
  /* Below: the hover fill. isolation keeps the z-index:-1 layer from escaping
     behind an ancestor's background. */
  position: relative;
  overflow: hidden;
  isolation: isolate;
}

/* The fill wipes up from the bottom edge on hover and retreats on the way out.
   z-index:-1 is deliberate: a positioned pseudo-element paints *above* the
   parent's background but *below* its inline text, so the label stays legible
   without needing a wrapper span around every button's text. */
.btn::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: light-dark(rgba(0,0,0,.22), rgba(255,255,255,.22));
  transform: translateY(101%);        /* 101% hides the sub-pixel seam */
  transition: transform 320ms var(--out);
}
.btn:active { transform: scale(0.97); }          /* instant press feedback */
.btn--lg { padding: 1.05rem 2rem; font-size: 1.02rem; }
.btn--sm { padding: .55rem 1.1rem; font-size: .88rem; }
.btn--block { width: 100%; border-radius: var(--r-sm); }

.btn--quiet {
  background: transparent;
  color: var(--ink);
  border-color: var(--rule-2);
}

@media (hover: hover) and (pointer: fine) {
  /* Fill rises, button lifts a hair, shadow grounds the lift. Three cheap
     transforms reading as one gesture. */
  .btn:hover::before { transform: translateY(0); }
  .btn:hover {
    transform: translateY(-2px);
    box-shadow: 0 10px 22px -14px light-dark(rgba(0,0,0,.55), rgba(0,0,0,.9));
  }
  /* Press beats hover — the lift collapses into the press so the two states
     never fight when the pointer is down. */
  .btn:active { transform: scale(0.97); box-shadow: none; }

  .btn--quiet:hover { border-color: var(--ink-3); }
  .btn--quiet::before { background: var(--accent-soft); }
}

.link-arrow {
  display: inline-flex; align-items: center; gap: .45rem;
  font-size: .96rem; color: var(--ink-2);
  border-bottom: 1px solid var(--rule-2);
  padding-bottom: 2px;
  transition: color 180ms ease, border-color 180ms ease;
}
.link-arrow span { transition: transform 220ms var(--out); }
@media (hover: hover) and (pointer: fine) {
  .link-arrow:hover { color: var(--ink); border-color: var(--accent); }
  .link-arrow:hover span { transform: translateX(4px); }
}

/* ---------- nav ---------- */
.nav {
  position: sticky; top: 0; z-index: 100;
  background: color-mix(in srgb, var(--paper) 72%, transparent);
  backdrop-filter: blur(16px) saturate(180%);
  -webkit-backdrop-filter: blur(16px) saturate(180%);
}
/* soft scroll edge instead of a hard 1px divider */
.nav::after {
  content: "";
  position: absolute; left: 0; right: 0; bottom: -22px; height: 22px;
  background: linear-gradient(to bottom, color-mix(in srgb, var(--paper) 60%, transparent), transparent);
  opacity: 0;
  transition: opacity 260ms ease;
  pointer-events: none;
}
.nav.stuck::after { opacity: 1; }

.nav__in {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1.5rem; height: 68px;
}

.brand { display: inline-flex; align-items: center; gap: .55rem; }
.brand__mark {
  width: 40px; height: 40px; flex: none;
  overflow: visible;
  transition: transform 420ms var(--out);
}
@media (hover: hover) and (pointer: fine) {
  .brand:hover .brand__mark { transform: rotate(-28deg); }
}
.brand__name {
  font-family: var(--display);
  font-size: 1.16rem;
  font-weight: 500;
  letter-spacing: -0.03em;
}

/* The links sit in their own soft capsule, which separates navigation from the
   wordmark and the CTA without needing a divider rule. */
.nav__links {
  display: flex; gap: .35rem;
  padding: .25rem;
  border-radius: 100px;
  background: var(--paper-2);
  border: 1px solid var(--rule);
}
.nav__links a {
  font-size: .9rem; color: var(--ink-2);
  padding: .42rem .95rem;
  border-radius: 100px;
  position: relative;
  transition: color var(--fast) ease, background-color var(--fast) ease;
}
.nav__links a::after {
  content: "";
  position: absolute; bottom: 6px; left: 50%; right: 50%;
  height: 1.5px; background: var(--accent);
  border-radius: 1px;
  transition: left 240ms var(--out), right 240ms var(--out);
}
@media (hover: hover) and (pointer: fine) {
  .nav__links a:hover { color: var(--ink); background: var(--paper); }
  .nav__links a:hover::after { left: 28%; right: 28%; }
}

.nav__end { display: flex; align-items: center; gap: .6rem; }

/* ---------- theme toggle ---------- */
.theme {
  display: grid; place-items: center;
  width: 36px; height: 36px; flex: none;
  padding: 0; cursor: pointer;
  background: none;
  border: 1px solid var(--rule-2);
  border-radius: 100px;
  color: var(--ink-2);
  transition: color 180ms ease, border-color 180ms ease, transform 140ms var(--out);
}
.theme:active { transform: scale(0.94); }
@media (hover: hover) and (pointer: fine) {
  .theme:hover { color: var(--ink); border-color: var(--ink-3); }
}
.theme svg { width: 17px; height: 17px; grid-area: 1 / 1; }

/* Cross-fade the two icons. Nothing scales from 0 — they rotate through. */
.theme__sun, .theme__moon {
  transition: opacity 220ms var(--out), transform 260ms var(--out);
}
.theme__sun  { opacity: 0; transform: rotate(-70deg) scale(.7); }
.theme__moon { opacity: 1; transform: none; }

/* In dark mode offer the sun (what you'd switch TO) */
:root[data-theme="dark"] .theme__sun { opacity: 1; transform: none; }
:root[data-theme="dark"] .theme__moon { opacity: 0; transform: rotate(70deg) scale(.7); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme]) .theme__sun { opacity: 1; transform: none; }
  :root:not([data-theme]) .theme__moon { opacity: 0; transform: rotate(70deg) scale(.7); }
}

.burger {
  display: none;
  width: 40px; height: 36px;
  background: none; border: 1px solid var(--rule-2); border-radius: var(--r-sm);
  cursor: pointer; padding: 0;
  place-items: center; gap: 5px;
}
.burger span {
  width: 16px; height: 1.5px; background: var(--ink);
  transition: transform 200ms var(--out);
}
.burger[aria-expanded="true"] span:first-child { transform: translateY(3.25px) rotate(45deg); }
.burger[aria-expanded="true"] span:last-child { transform: translateY(-3.25px) rotate(-45deg); }

.drawer {
  display: flex; flex-direction: column;
  padding: .25rem var(--pad) 1.6rem;
  border-top: 1px solid var(--rule);
  background: var(--paper);
}
/* An author `display` beats the UA stylesheet's [hidden] { display: none },
   so the rule above would leave the menu permanently open on mobile. This
   hands `hidden` back its meaning — the JS toggles that attribute. */
.drawer[hidden] { display: none; }
.drawer a:not(.btn) {
  padding: .85rem 0;
  border-bottom: 1px solid var(--rule);
  font-family: var(--display);
  font-size: 1.25rem;
}
.drawer__cta { margin-top: 1.15rem; }

/* ---------- scroll progress ---------- */
.progress {
  position: fixed; inset: 0 0 auto 0; z-index: 200;
  height: 2px; pointer-events: none;
}
.progress i {
  display: block; height: 100%; width: 100%;
  transform: scaleX(0); transform-origin: 0 50%;
  background: linear-gradient(90deg, var(--g1), var(--g2));
  box-shadow: 0 0 8px 1px color-mix(in srgb, var(--g2) 50%, transparent);
}

/* ---------- hero ---------- */
.hero {
  position: relative;
  padding-block: clamp(3.5rem, 9vw, 7rem) clamp(3rem, 6vw, 5rem);
  isolation: isolate;
}

/* soft gradient wash behind the headline */
.aura {
  position: absolute; z-index: -1;
  top: -28%; left: 50%; translate: -50% 0;
  width: min(1250px, 135vw); aspect-ratio: 1.35;
  pointer-events: none;
  background:
    radial-gradient(42% 46% at 30% 34%, color-mix(in srgb, var(--g1) 26%, transparent), transparent 70%),
    radial-gradient(40% 44% at 70% 46%, color-mix(in srgb, var(--g2) 22%, transparent), transparent 72%);
  filter: blur(28px);
  opacity: .7;
  animation: drift 22s ease-in-out infinite alternate;
}
@keyframes drift {
  from { transform: translate3d(-2%, -1%, 0) scale(1); }
  to   { transform: translate3d(2%, 2%, 0) scale(1.07); }
}

.chip {
  display: inline-flex; align-items: center; gap: .55rem;
  font-size: .82rem; color: var(--ink-2);
  border: 1px solid var(--rule-2);
  border-radius: 100px;
  padding: .34rem .9rem .34rem .75rem;
  margin-bottom: clamp(1.75rem, 4vw, 2.75rem);
}
.chip__dot {
  width: 6px; height: 6px; border-radius: 50%;
  background: #34c759; flex: none;
  animation: pulse 2.4s ease-in-out infinite;
}
@keyframes pulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50% { opacity: .55; transform: scale(1.35); }
}

.hero__h1 {
  font-family: var(--display);
  font-weight: 500;
  font-size: clamp(2.9rem, 9vw, 7.25rem);
  line-height: .94;
  letter-spacing: -0.045em;          /* the bigger it gets, the tighter it goes */
  margin-bottom: clamp(2.5rem, 5vw, 3.75rem);
}
.hero__h1 em {
  font-style: italic;
  padding-right: .08em;
  background: linear-gradient(100deg, var(--g1), var(--g2) 70%);
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent; color: transparent;
}
/* Windows High Contrast strips background-clip, so restore a solid colour */
@media (forced-colors: active) {
  .hero__h1 em { -webkit-text-fill-color: currentColor; color: currentColor; }
}

.hero__grid {
  display: grid;
  grid-template-columns: minmax(0, 1.15fr) minmax(0, .85fr);
  gap: clamp(1.75rem, 4vw, 3.5rem);
  align-items: end;
  border-top: 1px solid var(--rule);
  padding-top: clamp(1.75rem, 3.5vw, 2.5rem);
}
.hero__lede { font-size: clamp(1.05rem, 1.6vw, 1.2rem); color: var(--ink-2); max-width: 46ch; }
.hero__lede strong { color: var(--ink); font-weight: 600; }

.hero__side { display: flex; flex-direction: column; align-items: flex-start; gap: 1.15rem; }

/* ---------- ticker ---------- */
.ticker {
  border-block: 1px solid var(--rule);
  padding-block: 1.1rem;
  overflow: hidden;
  user-select: none;
  /* Fade the ends so the loop slides out of view instead of clipping hard. */
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
          mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
}
.ticker__row {
  display: flex; align-items: center; gap: 2.25rem;
  width: max-content;
  /* The list is duplicated once and scrolled by exactly half its width. Without
     this trailing gap the row is one gap short of two identical halves, so the
     loop restarts 18px off and visibly jumps. Keep it equal to the gap. */
  padding-right: 2.25rem;
  animation: run 44s linear infinite;   /* constant motion → linear */
}
.ticker__row span {
  font-family: var(--mono);
  font-size: .82rem;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--ink-3);
  white-space: nowrap;
}
.ticker__row i { width: 5px; height: 5px; border-radius: 50%; background: var(--accent-hi); flex: none; }
@keyframes run { to { transform: translateX(-50%); } }

/* ---------- services rows ---------- */
.rows { border-top: 1px solid var(--rule); }

.row {
  display: grid;
  grid-template-columns: 4.5rem minmax(0, 1fr) 15rem;
  gap: clamp(1.25rem, 3vw, 2.5rem);
  padding-block: clamp(2rem, 3.5vw, 2.9rem);
  border-bottom: 1px solid var(--rule);
  align-items: start;
}
.row__n {
  font-size: .8rem; letter-spacing: .1em;
  color: var(--accent); padding-top: .45rem;
}
.row__body h3 {
  font-family: var(--display); font-weight: 500;
  font-size: clamp(1.5rem, 2.6vw, 2rem);
  letter-spacing: -0.018em;
  margin-bottom: .7rem;
}
.row__body p { color: var(--ink-2); max-width: 52ch; }

.row__tags { display: flex; flex-wrap: wrap; gap: .4rem; align-content: start; padding-top: .5rem; }
.row__tags li {
  font-size: .8rem; color: var(--ink-2);
  border: 1px solid var(--rule);
  border-radius: 100px;
  padding: .22rem .7rem;
}

/* ---------- work ---------- */
.band--work { background: var(--paper-2); border-block: 1px solid var(--rule); }

.shot { margin-bottom: clamp(2rem, 4vw, 3rem); }

.shot__link { display: block; border-radius: var(--r); }
.shot__frame {
  display: block;
  border: 1px solid var(--rule-2);
  border-radius: var(--r);
  overflow: hidden;
  background: var(--paper-3);
  box-shadow: 0 26px 60px -34px rgba(0,0,0,.55);
  transition: transform 320ms var(--out), box-shadow 320ms var(--out), border-color 320ms var(--out);
}
@media (hover: hover) and (pointer: fine) {
  .shot__link:hover .shot__frame {
    transform: translateY(-4px);
    box-shadow: 0 40px 80px -38px rgba(0,0,0,.7);
    border-color: var(--accent-hi);
  }
  .shot__link:hover .shot__go { opacity: 1; transform: none; }
}
.shot__link:active .shot__frame { transform: translateY(-1px) scale(.995); }

.shot__chrome {
  display: flex; align-items: center; gap: .38rem;
  padding: .6rem .8rem;
  border-bottom: 1px solid var(--rule);
  background: var(--paper-3);
}
.shot__chrome .dot {
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--rule-2); flex: none;
}
.shot__url {
  margin-left: .5rem; font-size: .74rem; color: var(--ink-3);
}
.shot__go {
  margin-left: auto; flex: none;
  font-size: .72rem; font-weight: 500;
  color: var(--accent);
  opacity: 0; transform: translateX(-4px);
  transition: opacity 220ms var(--out), transform 220ms var(--out);
}
@media (hover: none) { .shot__go { opacity: 1; transform: none; } }
.shot__view { display: block; position: relative; aspect-ratio: 16 / 9; background: #0d0f0c; }
.shot__view picture { display: block; height: 100%; }
.shot__view img { width: 100%; height: 100%; object-fit: cover; }

/* ---------- screenshot skeleton ----------
   Only ever active with JS, because only JS can clear it. Without JS the
   picture stays at full opacity and the placeholder is never painted, so a
   no-JS visitor sees the image rather than a permanent shimmer. */
.shot__skel { display: none; }
.js .shot__skel {
  display: block;
  position: absolute; inset: 0; z-index: 1;
  background-image: linear-gradient(
    100deg,
    transparent 25%,
    rgba(255, 255, 255, .07) 45%,
    rgba(255, 255, 255, .07) 55%,
    transparent 75%
  );
  background-size: 250% 100%;
  background-repeat: no-repeat;
  animation: sweep 1.7s linear infinite;
  transition: opacity 420ms var(--out);
}
@keyframes sweep {
  from { background-position: 150% 0; }
  to   { background-position: -150% 0; }
}

.js .shot__view picture,
.js .shot__over {
  opacity: 0;
  transition: opacity 520ms var(--out);
}
.js .shot__view.is-loaded picture,
.js .shot__view.is-loaded .shot__over { opacity: 1; }
.js .shot__view.is-loaded .shot__skel { opacity: 0; animation: none; }
.shot__over {
  position: absolute; inset: auto 0 0 0;
  padding: clamp(1rem, 3.5vw, 2.75rem);
  background: linear-gradient(to top, rgba(8,10,7,.9), rgba(8,10,7,.35) 55%, transparent);
  color: #fff;
}
.shot__eyebrow {
  display: block;
  font-size: clamp(.6rem, 1.1vw, .74rem);
  letter-spacing: .16em; text-transform: uppercase;
  color: rgba(255,255,255,.72);
  margin-bottom: .5rem;
}
.shot__h1 {
  display: block;
  font-family: var(--display);
  font-size: clamp(1.05rem, 3.4vw, 2.5rem);
  line-height: 1.03; letter-spacing: -0.02em;
  max-width: 18ch; margin-bottom: clamp(.6rem, 1.6vw, 1.2rem);
}
.shot__btn {
  display: inline-block;
  background: #fff; color: #14120f;
  font-size: clamp(.62rem, 1.15vw, .82rem);
  font-weight: 500;
  padding: .45em 1.05em;
  border-radius: var(--r-sm);
}
.shot figcaption {
  margin-top: .9rem; font-size: .86rem; color: var(--ink-3);
}

.facts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  border-top: 1px solid var(--rule);
  border-left: 1px solid var(--rule);
  margin-bottom: clamp(2.5rem, 5vw, 4rem);
}
.facts > div {
  border-right: 1px solid var(--rule);
  border-bottom: 1px solid var(--rule);
  padding: 1.15rem 1.25rem;
}
.facts dt {
  font-size: .74rem; letter-spacing: .13em; text-transform: uppercase;
  color: var(--ink-3); margin-bottom: .3rem;
}
.facts dd {
  font-family: var(--display); font-size: 1.85rem;
  line-height: 1; letter-spacing: -0.02em;
}

.case {
  display: grid;
  grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr);
  gap: clamp(2rem, 5vw, 4rem);
  align-items: start;
}
.case__h {
  font-family: var(--display); font-weight: 500;
  font-size: 1.45rem; letter-spacing: -0.018em;
  margin: 2.35rem 0 .85rem;
}
.case__col > .case__h:first-child { margin-top: 0; }
.case__col p { color: var(--ink-2); margin-bottom: 1rem; max-width: 62ch; }
.case__col p strong { color: var(--ink); font-weight: 600; }
.case__col em { font-style: italic; }

.ticks { display: grid; gap: .68rem; }
.ticks li {
  position: relative; padding-left: 1.45rem;
  color: var(--ink-2); font-size: .97rem;
}
.ticks li::before {
  content: ""; position: absolute; left: 0; top: .62em;
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--accent-hi);
}
.ticks li strong { color: var(--ink); font-weight: 600; }

.case__aside { display: grid; gap: 1rem; position: sticky; top: 92px; }

.side-card {
  border: 1px solid var(--rule);
  border-radius: var(--r);
  padding: 1.4rem 1.5rem;
  background: var(--paper);
}
.side-card h4 {
  font-size: .74rem; letter-spacing: .14em; text-transform: uppercase;
  color: var(--ink-3); font-weight: 500; margin-bottom: 1rem;
}

.mini { display: grid; gap: .7rem; }
.mini li {
  display: flex; justify-content: space-between; gap: 1rem;
  font-size: .92rem; align-items: baseline;
}
.mini span { color: var(--ink-3); font-size: .82rem; }

.timeline { display: grid; gap: .95rem; }
.timeline li {
  display: grid; grid-template-columns: 3.6rem 1fr; gap: .85rem;
  font-size: .92rem; color: var(--ink-2);
}
.timeline span {
  color: var(--accent); font-size: .78rem;
  letter-spacing: .06em; padding-top: .18em;
}

.handover {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(1.75rem, 4vw, 3.5rem);
  margin-top: clamp(2.75rem, 5vw, 4rem);
  padding-top: clamp(2.25rem, 4vw, 3rem);
  border-top: 1px solid var(--rule);
  align-items: start;
}
.handover h3 {
  font-family: var(--display); font-weight: 500;
  font-size: clamp(1.5rem, 2.6vw, 2rem);
  letter-spacing: -0.018em; margin-bottom: .85rem;
}
.handover p { color: var(--ink-2); max-width: 52ch; }

.quote {
  margin: 0; border-left: 2px solid var(--accent-hi);
  padding-left: clamp(1.15rem, 2.5vw, 1.75rem);
}
.quote p {
  font-family: var(--display);
  font-size: clamp(1.35rem, 2.9vw, 2rem);
  line-height: 1.2; letter-spacing: -0.02em;
  margin-bottom: 1rem;
}
.quote cite { font-style: normal; font-size: .87rem; color: var(--ink-3); }

/* ---------- pricing ---------- */
.tiers {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(265px, 1fr));
  gap: 1rem;
  align-items: start;
}

.tier {
  position: relative;
  border: 1px solid var(--rule);
  border-radius: var(--r);
  padding: 1.85rem 1.7rem 2rem;
  background: var(--paper-2);
  display: flex; flex-direction: column;
}
.tier--pick { border-color: var(--accent); }

.tier__flag {
  position: absolute; top: 0; left: 1.7rem;
  transform: translateY(-50%);
  background: var(--accent); color: var(--accent-ink);
  font-size: .7rem; font-weight: 500; letter-spacing: .04em;
  padding: .24rem .65rem; border-radius: 100px;
}
.js .r .tier__flag {
  animation: flag-pop 500ms var(--out) 400ms both;
}
@keyframes flag-pop {
  0% { opacity: 0; transform: translateY(-50%) scale(.6); }
  60% { transform: translateY(-50%) scale(1.08); }
  100% { opacity: 1; transform: translateY(-50%) scale(1); }
}
.tier__name {
  font-family: var(--display); font-weight: 500;
  font-size: 1.7rem; letter-spacing: -0.02em;
}
.tier__note { font-size: .88rem; color: var(--ink-3); margin: .35rem 0 1.4rem; }
.tier__price {
  font-family: var(--display);
  font-size: 3rem; line-height: 1; letter-spacing: -0.03em;
  margin-bottom: 1.4rem;
}
.tier__from {
  display: block;
  font-family: var(--sans); font-size: .76rem;
  letter-spacing: .12em; text-transform: uppercase;
  color: var(--ink-3); margin-bottom: .35rem;
}
.tier .btn { margin-bottom: 1.6rem; }
.tier .ticks { padding-top: 1.4rem; border-top: 1px solid var(--rule); }

.fineprint {
  margin-top: 2rem; font-size: .89rem; color: var(--ink-3);
  max-width: 62ch;
}

/* ---------- faq ---------- */
.band--faq { background: var(--paper-2); border-block: 1px solid var(--rule); }

.faq { border-top: 1px solid var(--rule); }

.qa { border-bottom: 1px solid var(--rule); }
.qa summary {
  list-style: none; cursor: pointer;
  padding: 1.3rem 2.5rem 1.3rem 0;
  position: relative;
  font-family: var(--display);
  font-size: clamp(1.15rem, 2.1vw, 1.4rem);
  letter-spacing: -0.015em;
  transition: color 160ms ease;
}
.qa summary::-webkit-details-marker { display: none; }
@media (hover: hover) and (pointer: fine) {
  .qa summary:hover { color: var(--accent); }
}
.qa summary::before,
.qa summary::after {
  content: ""; position: absolute; right: 4px; top: 50%;
  background: var(--accent);
  transition: transform 220ms var(--out), opacity 220ms var(--out);
}
.qa summary::before { width: 13px; height: 1.5px; margin-top: -.75px; }
.qa summary::after { width: 1.5px; height: 13px; right: 9.75px; margin-top: -6.5px; }
.qa[open] summary::after { transform: rotate(90deg); opacity: 0; }

.qa > div { padding-bottom: 1.4rem; }
.qa p { color: var(--ink-2); max-width: 66ch; font-size: .98rem; }

/* ---------- contact ---------- */
.contact {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, .85fr);
  gap: clamp(2rem, 5vw, 4.5rem);
  align-items: start;
}

.reach { margin-top: 2.5rem; border-top: 1px solid var(--rule); }
.reach li {
  display: flex; justify-content: space-between; gap: 1rem;
  align-items: baseline;
  padding: .95rem 0;
  border-bottom: 1px solid var(--rule);
}
.reach > li > span:first-child {
  font-size: .76rem; letter-spacing: .13em; text-transform: uppercase;
  color: var(--ink-3);
}
.reach a { color: var(--accent); }
.reach__plain { color: var(--ink-2); }
@media (hover: hover) and (pointer: fine) {
  .reach a:hover { text-decoration: underline; text-underline-offset: 3px; }
}

.form {
  border: 1px solid var(--rule);
  border-radius: var(--r);
  background: var(--paper-2);
  padding: clamp(1.35rem, 3vw, 2rem);
  display: grid; gap: 1rem;
}
.f { display: grid; gap: .42rem; }
.f label {
  font-size: .76rem; letter-spacing: .12em; text-transform: uppercase;
  color: var(--ink-3);
}
.f input, .f select, .f textarea {
  background: var(--paper);
  border: 1px solid var(--rule-2);
  border-radius: var(--r-sm);
  padding: .72rem .85rem;
  font-size: .96rem;
  width: 100%;
  transition: border-color 160ms ease;
}
.f textarea { resize: vertical; min-height: 118px; }
.f input:focus, .f select:focus, .f textarea:focus { border-color: var(--accent); }
.f input:user-invalid, .f textarea:user-invalid { border-color: var(--danger); }

/* ---------- footer ---------- */
.foot {
  border-top: 1px solid var(--rule);
  padding-block: 3rem 2.25rem;
}
.foot__in {
  display: grid;
  grid-template-columns: minmax(0, 1.6fr) repeat(2, minmax(0, 1fr));
  gap: 2rem;
  align-items: start;
}
.foot__brand p {
  margin-top: .85rem; font-size: .89rem; color: var(--ink-3); max-width: 34ch;
}
.foot__nav, .foot__reach { display: grid; gap: .6rem; align-content: start; }
.foot__nav a, .foot__reach a { font-size: .92rem; color: var(--ink-2); }
@media (hover: hover) and (pointer: fine) {
  .foot__nav a:hover, .foot__reach a:hover { color: var(--accent); }
}
.foot__legal {
  grid-column: 1 / -1;
  margin-top: 1.5rem; padding-top: 1.5rem;
  border-top: 1px solid var(--rule);
  font-size: .84rem; color: var(--ink-3);
  display: flex; flex-wrap: wrap; gap: .4rem 1.1rem;
  align-items: baseline;
}
.foot__privacy { color: var(--ink-2); }
@media (hover: hover) and (pointer: fine) {
  .foot__privacy:hover { color: var(--accent); }
}

/* ---------- legal pages ---------- */
.legal { padding-block: var(--band-y); }
.legal p { color: var(--ink-2); margin-bottom: 1rem; max-width: 66ch; }
.legal p strong { color: var(--ink); font-weight: 600; }
.legal a:not(.btn) {
  color: var(--accent);
  text-decoration: underline; text-underline-offset: 3px;
}
.legal .ticks { margin-bottom: 1rem; }
.legal .head__sub { margin-bottom: 0; }

/* ---------- work CTA row ---------- */
.head__cta {
  display: flex; align-items: center; flex-wrap: wrap;
  gap: .75rem 1rem; margin-top: 1.75rem;
}
.head__note { font-size: .84rem; color: var(--ink-3); }
.ext { transition: transform 220ms var(--out); }
@media (hover: hover) and (pointer: fine) {
  .btn:hover .ext { transform: translate(2px, -2px) rotate(15deg); }
}

/* ---------- tooltips ----------
   One bubble is reused for every trigger. It is inverted against the page so it
   reads as an overlay in both themes, and pointer-events stay off so it can
   never sit between the cursor and the thing it describes. */
.tip { cursor: help; }
/* Only the non-interactive hints get the dotted hint underline — buttons and
   labels already look interactive on their own. Gated behind hover, because on
   a touch screen there is nothing to hover: the underline would promise a
   tooltip that can never open. Touch users simply see plain text. */
@media (hover: hover) and (pointer: fine) {
  dt.tip, span.tip, p.tip {
    text-decoration: underline dotted var(--rule-2);
    text-underline-offset: 3px;
    text-decoration-thickness: 1px;
  }
  .tip:hover { text-decoration-color: var(--accent); }
}
/* Touch has no hover state to reveal a tooltip, so the cursor hint is
   meaningless there too. */
@media not all and (hover: hover) {
  .tip { cursor: auto; }
}

.tip-bubble {
  position: fixed; top: 0; left: 0; z-index: 300;
  max-width: min(21rem, calc(100vw - 2rem));
  padding: .55rem .72rem;
  border-radius: var(--r-sm);
  background: var(--ink);
  color: var(--paper);
  font-size: .81rem;
  line-height: 1.45;
  letter-spacing: 0;
  text-align: left;
  box-shadow: 0 12px 32px -14px rgba(0, 0, 0, .55);
  pointer-events: none;
  opacity: 0;
  transform: translateY(4px);
  transition: opacity 150ms var(--out), transform 150ms var(--out);
}
/* Same trap as the drawer: an author `display` would beat UA [hidden]. */
.tip-bubble[hidden] { display: none; }
.tip-bubble.in { opacity: 1; transform: none; }

.tip-bubble::after {
  content: "";
  position: absolute;
  left: var(--tip-x, 50%);
  translate: -50% 0;
  border: 5px solid transparent;
  border-top-color: var(--ink);
  bottom: -10px;
}
.tip-bubble.is-below::after {
  bottom: auto; top: -10px;
  border-top-color: transparent;
  border-bottom-color: var(--ink);
}

/* ---------- form extras ---------- */
.hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

/* restored-draft notice */
.form__draft {
  display: flex; align-items: center; justify-content: space-between;
  gap: .75rem;
  font-size: .82rem; color: var(--ink-3);
  border: 1px dashed var(--rule-2);
  border-radius: var(--r-sm);
  padding: .55rem .7rem;
}
.form__draft[hidden] { display: none; }
.form__draft button {
  background: none; border: 0; padding: 0;
  cursor: pointer; flex: none;
  color: var(--accent); font-size: inherit;
  text-decoration: underline; text-underline-offset: 2px;
}

.f__err { font-size: .82rem; color: var(--danger); min-height: 0; }
.f__err:empty { display: none; }

.form__msg { font-size: .89rem; color: var(--ink-2); min-height: 1.3em; }
.form__msg[data-state="ok"] { color: var(--accent); font-weight: 500; }
.form__msg[data-state="bad"] { color: var(--danger); }

.btn:disabled { pointer-events: none; opacity: .72; }

/* the whole form settles back after a successful send */
.form.sent { border-color: var(--accent-hi); }
.form__msg[data-state="ok"]::before {
  content: "\2713\0020";
  display: inline-block;
  animation: check-pop 400ms var(--out) both;
}
@keyframes check-pop {
  0% { opacity: 0; transform: scale(0) rotate(-45deg); }
  60% { transform: scale(1.25) rotate(4deg); }
  100% { opacity: 1; transform: scale(1) rotate(0); }
}

/* ---------- gradient accents ---------- */
.tier--pick {
  border-color: transparent;
  background:
    linear-gradient(var(--paper-2), var(--paper-2)) padding-box,
    linear-gradient(150deg, var(--g1), var(--g2)) border-box;
}

.ticker__row i {
  background: linear-gradient(135deg, var(--g1), var(--g2));
}

.quote { border-left-color: transparent; border-image: linear-gradient(var(--g1), var(--g2)) 1; }

.foot { position: relative; }
.foot::before {
  content: ""; position: absolute; inset: 0 0 auto 0; height: 1px;
  background:
    linear-gradient(90deg, transparent, color-mix(in srgb, var(--g1) 55%, transparent), color-mix(in srgb, var(--g2) 55%, transparent), transparent),
    linear-gradient(90deg, transparent 30%, color-mix(in srgb, var(--g1) 90%, transparent) 50%, transparent 70%);
  background-size: 100% 100%, 200% 100%;
  background-position: 0 0, -100% 0;
}
.js .foot.in::before {
  animation: foot-shimmer 1.2s var(--out) .2s both;
}
@keyframes foot-shimmer {
  to { background-position: 0 0, 200% 0; }
}

/* ---------- hover lift on cards ---------- */
.tier, .side-card {
  transition: transform var(--med) var(--out), box-shadow var(--med) var(--out),
              border-color var(--med) var(--out);
}
@media (hover: hover) and (pointer: fine) {
  .tier:hover {
    transform: translateY(-5px);
    border-color: var(--rule-2);
    box-shadow: 0 24px 50px -32px light-dark(rgba(0,0,0,.4), rgba(0,0,0,.8));
  }
}

/* ---------- section rhythm ----------
   Alternating bands were doing the work of separating sections. With paper this
   close to white the tint alone is too weak, so bands get a hairline as well. */
.band--work, .band--faq { border-block: 1px solid var(--rule); }
.band--contact { border-top: 1px solid var(--rule); }

/* Rows read as a list, not a table — the number leads and the rule follows. */
.row { transition: background-color var(--fast) ease; }
@media (hover: hover) and (pointer: fine) {
  .row:hover { background: var(--paper-2); }
}
.row__n {
  font-family: var(--mono);
  font-size: .78rem;
  letter-spacing: 0;
}

/* Tags become soft pills on the muted paper rather than outlined chips. */
.row__tags li {
  background: var(--paper-2);
  border-color: transparent;
  color: var(--ink-3);
  font-size: .78rem;
  padding: .3rem .8rem;
}

/* Numbers are the point of the facts strip, so they get the display face big. */
.facts dt { font-family: var(--mono); letter-spacing: .06em; }
.facts dd {
  font-family: var(--display);
  font-weight: 500;
  font-size: clamp(1.9rem, 3vw, 2.4rem);
  letter-spacing: -0.035em;
}

.tier__price {
  font-family: var(--display);
  font-weight: 500;
  letter-spacing: -0.04em;
}
.tier__from { font-family: var(--mono); letter-spacing: .08em; }
.tier__flag { border-radius: 100px; font-family: var(--mono); font-size: .68rem; }

.side-card h4, .mini span, .timeline span, .facts dt, .f label, .reach > li > span:first-child,
.shot__url, .shot__eyebrow {
  font-family: var(--mono);
}

.qa summary { font-family: var(--display); font-weight: 500; letter-spacing: -0.025em; }
.quote p { font-family: var(--display); font-weight: 500; letter-spacing: -0.03em; }
.shot__h1 { font-weight: 500; letter-spacing: -0.035em; }

/* ---------- reveal ----------
   Scoped to .js so the page is fully readable without JavaScript.
   Blur bridges the two states so the fade reads as one motion, not two
   overlapping copies. */
.js .r {
  opacity: 0;
  transform: translateY(16px);
  filter: blur(6px);
  transition:
    opacity 700ms var(--out),
    transform 700ms var(--out),
    filter 700ms var(--out);
  transition-delay: calc(var(--d, 0) * 70ms);   /* short stagger */
  will-change: transform, opacity;
}
.js .r.in { opacity: 1; transform: none; filter: none; }
.js .r.in { will-change: auto; }

.js .hero__h1.r {
  transform: translateY(24px) scale(.97);
  transition-duration: 900ms;
}
.js .hero__h1.r.in { transform: none; }

/* ==========================================================
   INTERACTIONS
   Everything here is transform/opacity only, so it runs on the compositor
   and never triggers layout. Durations stay under ~320ms: past that a hover
   stops reading as feedback and starts reading as lag. All of it is gated
   behind a real pointer — on touch there is no hover to reveal it, and a
   tap would otherwise fire the hover state and leave it stuck on.
   ========================================================== */
@media (hover: hover) and (pointer: fine) {

  /* Arrows lead the eye in the direction the link goes. */
  .link-arrow:hover span { transform: translateX(5px); }
  .btn:hover .ext { transform: translate(3px, -3px) rotate(15deg); }

  /* Theme toggle: the icon turns a little as you approach it, which hints
     that the control rotates between two states. */
  .theme { transition: color var(--fast) ease, border-color var(--fast) ease,
                       transform 160ms var(--out), background-color var(--fast) ease; }
  .theme:hover { background: var(--paper-2); transform: rotate(-12deg); }
  .theme:active { transform: rotate(-12deg) scale(0.92); }

  /* Service rows: the number steps aside and colours up, the row tints.
     Small enough to feel like the row is acknowledging the cursor. */
  .row__n { transition: transform 260ms var(--out), color var(--fast) ease; }
  .row:hover .row__n { transform: translateX(3px); color: var(--accent); }
  .row__tags li { transition: background-color var(--fast) ease, color var(--fast) ease; }
  .row:hover .row__tags li { background: var(--paper-3); color: var(--ink-2); }

  /* Pricing: the card lifts (declared earlier) and its CTA answers with it. */
  .tier { will-change: transform; }
  .tier:hover .btn--quiet { border-color: var(--ink-3); }

  /* Contact list: the value slides toward the pointer. */
  .reach li a { display: inline-block; transition: transform 220ms var(--out); }
  .reach li:hover a { transform: translateX(4px); }

  /* Footer + FAQ: colour only. These are scanned often, so movement here
     would be noise rather than feedback. */
  .qa summary { transition: color var(--fast) ease; }

  /* Brand mark already rotates on hover; give the wordmark a matching beat. */
  .brand__name { transition: opacity var(--fast) ease; }
  .brand:hover .brand__name { opacity: .72; }
}

/* Form fields: a focus ring that grows rather than snaps. Focus states are
   NOT gated behind hover — keyboard users need them most. */
.f input, .f select, .f textarea {
  transition: border-color var(--fast) ease, box-shadow var(--fast) var(--out),
              background-color var(--fast) ease;
}
.f input:focus, .f select:focus, .f textarea:focus {
  box-shadow: 0 0 0 3px var(--accent-soft);
}

/* FAQ answers fade down as they open instead of snapping into place.
   @starting-style gives the element an entry state to animate *from*; browsers
   without it simply show the answer instantly, which is a fine fallback. */
.qa > div {
  opacity: 1;
  transform: translateY(0);
  transition: opacity 260ms var(--out), transform 260ms var(--out);
}
@starting-style {
  .qa[open] > div { opacity: 0; transform: translateY(-8px); }
}

/* The mobile drawer slides down instead of appearing. An animation (not a
   transition) is required here because the element goes display:none →
   flex, and transitions do not run across a display change. */
.drawer:not([hidden]) { animation: drawer-in 300ms var(--out) both; }
@keyframes drawer-in {
  from { opacity: 0; transform: translateY(-10px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* Tick bullets pop very slightly as their block reveals — it draws the eye
   down the list in order. Purely decorative, so it is the first thing the
   reduced-motion block below removes. */
.js .r .ticks li::before { transition: transform 320ms var(--out); }
.js .r:not(.in) .ticks li::before { transform: scale(0); }

/* ---------- responsive ---------- */
@media (max-width: 1000px) {
  .case { grid-template-columns: 1fr; }
  .case__aside { position: static; }
  .handover { grid-template-columns: 1fr; }
  .row { grid-template-columns: 3.25rem minmax(0, 1fr); }
  .row__tags { grid-column: 2; padding-top: 0; }
  .contact { grid-template-columns: 1fr; }
}

@media (max-width: 860px) {
  .nav__links, .nav__cta { display: none; }
  .burger { display: grid; }
  .hero__grid { grid-template-columns: 1fr; align-items: start; }
  .foot__in { grid-template-columns: 1fr 1fr; }
  .foot__brand { grid-column: 1 / -1; }
}

@media (min-width: 861px) {
  .drawer { display: none !important; }
}

@media (max-width: 560px) {
  body { font-size: 1rem; }
  .hero__side { width: 100%; }
  .hero__side .btn { width: 100%; }
  .facts { grid-template-columns: 1fr 1fr; }
  .reach li { flex-direction: column; gap: .2rem; }
}

/* ---------- preferences ---------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .ticker__row { animation: none; }
  .aura { animation: none; }
  .js .shot__skel { animation: none; }   /* a still placeholder, not a pulse */
  .js .r { opacity: 1; transform: none; filter: none; transition: none; }
  .tip-bubble { transition: none; }

  /* Reduced motion means less movement, not less feedback. Colour and opacity
     changes stay — they carry meaning. Everything that TRAVELS is removed. */
  .btn::before { transform: none; opacity: 0; transition: opacity 1ms; }
  .btn:hover::before { opacity: 1; }
  .btn:hover { transform: none; box-shadow: none; }
  .btn:active { transform: none; }
  .theme:hover, .theme:active { transform: none; }
  .row:hover .row__n { transform: none; }
  .reach li:hover a { transform: none; }
  .link-arrow:hover span, .btn:hover .ext { transform: none; }
  .brand:hover .brand__mark { transform: none; }
  .tier:hover, .shot__link:hover .shot__frame { transform: none; }
  .drawer:not([hidden]) { animation: none; }
  .qa > div { transition: none; }
  .js .r:not(.in) .ticks li::before { transform: none; }
  .chip__dot { animation: none; }
  .js .r .tier__flag { animation: none; }
  .js .foot.in::before { animation: none; }
  .nav__links a::after { transition: none; }
  *, *::before, *::after {
    animation-duration: .01ms !important;
    transition-duration: .01ms !important;
  }
}

@media (prefers-reduced-transparency: reduce) {
  .nav { background: var(--paper); backdrop-filter: none; -webkit-backdrop-filter: none; }
}

@media (prefers-contrast: more) {
  :root { --rule: var(--ink-3); --rule-2: var(--ink-2); }
  .nav { background: var(--paper); backdrop-filter: none; }
}

@media print {
  .nav, .ticker, .drawer, .form, .progress, .skip-link, .aura { display: none; }
  body { background: #fff; color: #000; }
}
