/* ═══════════════════════════════════════════════════════════════════
   Falconite Marketing

   Type:  Anton (display, uppercase) · Newsreader (body) · IBM Plex Mono
   Idea:  the page wears each client's skin. In the hero the headline
          rewrites itself; in the work each section repaints entirely.
   Rule:  no card grids, no eyebrows, no colour on the type.
   ═══════════════════════════════════════════════════════════════════ */

:root {
  --ink:       #0a0b0f;
  --ink-2:     #12141a;
  --ink-3:     #1b1e26;
  --bone:      #f2efe8;
  --bone-dim:  #b9bcc4;
  --paper:     #f4f1ea;
  --gold:      #ffc82c;
  --gold-deep: #8a6800;   /* gold that still passes AA on paper */
  --slate:     #868c98;

  --skin: var(--gold);

  --bg:     var(--ink);
  --fg:     var(--bone);
  --muted:  var(--slate);
  --accent: var(--gold);
  --hair:   rgba(242, 239, 232, .13);
  /* An input's boundary is a UI component under WCAG 1.4.11 and needs 3:1.
     The hairline used for dividers is 1.41:1 against the form panel — fine
     for a rule, invisible as a field edge. */
  --field-edge: rgba(242, 239, 232, .38);

  --display: "Anton", "Arial Narrow", "Helvetica Neue Condensed", Impact, sans-serif;
  --serif:   "Newsreader", Georgia, "Times New Roman", serif;
  --mono:    "IBM Plex Mono", ui-monospace, monospace;

  /* 8px base, 4px half-steps. Every gap, pad and margin below resolves to
     one of these so spacing is a decision made once rather than per rule. */
  --s-1: .25rem;   /*  4 */
  --s-2: .5rem;    /*  8 */
  --s-3: .75rem;   /* 12 */
  --s-4: 1rem;     /* 16 */
  --s-5: 1.5rem;   /* 24 */
  --s-6: 2rem;     /* 32 */
  --s-7: 3rem;     /* 48 */
  --s-8: 4rem;     /* 64 */

  /* How far a row's hover tint reaches past its text. Without this the
     highlight stops pixel-exact on the first glyph, which reads as a
     rendering seam rather than as a field. */
  /* Scales down on small screens: a fixed 16px bleed against a 21.6px
     page margin leaves the tint almost touching the viewport edge. */
  --bleed: clamp(var(--s-2), 2vw, var(--s-4));

  /* ── type scale ───────────────────────────────────────────
     Spacing was tokenised; type never was, so 44 separate font-size
     declarations had drifted apart — sixteen of them describing the one
     mono label, and eight different clamps landing between 1.1 and
     1.2rem. These are the steps; anything still written inline below is
     a genuine one-off display size used exactly once. */
  --fs-label: .72rem;   /* mono caps labels */
  --fs-xs:    .82rem;   /* fine print */
  --fs-ui:    .88rem;   /* nav and small controls */
  --fs-sm:    .97rem;   /* notes, list items, dense body */
  --fs-input: 1rem;     /* never smaller: iOS zooms the page under 16px */
  --fs-base:  clamp(1.02rem, .55rem + .62vw, 1.2rem);
  --fs-md:    clamp(1.06rem, .68rem + .7vw, 1.3rem);
  --fs-lead:  clamp(1.16rem, .72rem + .84vw, 1.46rem);
  --fs-name:  clamp(1.12rem, 1.8vw, 1.5rem);
  --fs-h3:    clamp(1.48rem, 2.9vw, 2.3rem);

  --px: clamp(1.35rem, 5vw, 6.5rem);
  --py: clamp(5rem, 10vw, 10rem);
  /* Two curves, two jobs. --ease is the long expo-out that carries section
     entrances; --ease-ui is the shorter ease-out for anything the pointer
     triggers. Hover feedback under 200ms, press under 130ms: a button that
     takes 300ms to acknowledge a cursor reads as lag, not as polish. */
  --ease:    cubic-bezier(.16, 1, .3, 1);
  --ease-ui: cubic-bezier(.23, 1, .32, 1);

  --t-press: .12s;
  --t-hover: .18s;
  --t-theme: .5s;
}

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

html {
  /* No scroll-behavior: smooth here on purpose. Chrome's native smooth
     scroll is near-constant-speed, so on a page this tall a nav click
     turns into a long blur. js/main.js animates it instead, with a capped
     duration and an instant jump for very long distances. */
  color-scheme: dark;
  -webkit-tap-highlight-color: rgba(255, 200, 44, .18);
}

:target,
#work, #services, #ads, #pricing, #speed, #process, #contact, #top,
[id^="case-"] { scroll-margin-top: 5.5rem; }

body {
  background: var(--ink);
  color: var(--bone);
  font-family: var(--serif);
  /* no opsz axis is loaded any more — see the font URL in the HTML */
  font-size: var(--fs-base);
  line-height: 1.58;
  font-kerning: normal;
  font-feature-settings: "kern" 1, "liga" 1;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
  touch-action: manipulation;
  caret-color: var(--gold);
}

/* height:auto is load-bearing — the width/height attributes that stop
   layout shift would otherwise apply as a literal pixel height. */
img { max-width: 100%; display: block; height: auto; }

/* Every image is wrapped in <picture> to offer WebP with a JPEG fallback.
   display:contents keeps the wrapper out of the box tree entirely, so every
   selector written against the img — and the hero's absolute positioning —
   behaves exactly as it did before the wrappers existed. */
picture { display: contents; }
a { color: inherit; }
::selection { background: var(--gold); color: var(--ink); }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 2px; }

/* the browser's own surfaces, themed */
::-webkit-scrollbar { width: 11px; height: 11px; }
::-webkit-scrollbar-track { background: var(--ink); }
::-webkit-scrollbar-thumb { background: #2a2e38; border: 3px solid var(--ink); border-radius: 99px; }
::-webkit-scrollbar-thumb:hover { background: #3a404c; }
html { scrollbar-color: #2a2e38 var(--ink); scrollbar-width: thin; }

/* A field only a bot will ever fill. Clipped to a pixel rather than
   parked at -9999px, so it can never widen the page if overflow-x is
   ever changed. Out of the tab order and out of the accessibility tree
   as well, not merely out of sight. */
.gotcha {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.skip {
  letter-spacing: .07em;
  position: absolute; left: -9999px; top: 0; z-index: 200;
  background: var(--gold); color: var(--ink);
  padding: .8rem 1.4rem; font-family: var(--display); font-weight: 400; text-decoration: none;
}
.skip:focus { left: 0; }


/* ── Anton: one weight, set in caps ───────────────────────────
   Anton has a single 400 that is already the "bold". Any heavier
   request makes the browser synthesise a smeared fake bold, and its
   side bearings are so tight that the negative tracking a variable
   grotesque wants will crash the glyphs together. Both are fixed here,
   once, rather than at every call site. */

h1, h2, h3, h4,
.skip, .btn, .btn-ghost, .topnav a:not(.btn),
.meter-name, .band-name, .case-cta, .idx-name,
.step-verb, .quote cite, .foot-brand p, .problem-turn,
.tier-name, .tier-price, .tier-cap, .lane-name, .lane-days {
  font-family: var(--display);
  font-variation-settings: normal;
  font-synthesis-weight: none;
  font-synthesis-style: none;
  text-transform: uppercase;
}

/* Caps have no descenders, so the leading can close up; and tracking
   goes positive, not negative, which is the opposite of the old face. */
h1, h2, h3, h4 { letter-spacing: .004em; line-height: .95; }

/* ── headings ─────────────────────────────────────────────── */

h1, h2, h3 {
  font-family: var(--display);
  text-wrap: balance;
  hyphens: none;
}

/* "Nobody remembers" breaks to two lines at any size that still reads as a
   hero, so the stack is the design rather than a fault — a four-line slab of
   Anton is the idiom. Sized to fill the wider copy column, not to dodge the
   wrap. */
h1 { font-size: clamp(2.4rem, 7vw, 6.2rem); letter-spacing: 0; line-height: .94; }
h1 .line { display: block; }

.swap { transition: opacity .3s ease; }
.swap.is-out { opacity: 0; }

h2 { font-size: clamp(2.05rem, 4.9vw, 4.3rem); max-width: 20ch; line-height: .95; }
h3 { font-size: var(--fs-name); letter-spacing: .02em; line-height: 1.1; }

/* ── body copy ────────────────────────────────────────────── */

p { max-width: 66ch; text-wrap: pretty; }

.lead {
  font-size: var(--fs-lead);
  line-height: 1.42;
  color: var(--fg);
  letter-spacing: -.008em;
}

/* Child combinators, deliberately: the contact section nests its .mast
   inside .contact-copy, and a descendant selector here outranks the
   and repaints the chapter numeral muted. */
.case-copy > p + p, .contact-copy > p + p { margin-top: 1.15em; }
.case-copy > p:not(.lead), .contact-copy > p:not(.lead) { color: var(--muted); }

em { font-style: italic; }
.case-copy em, .contact-copy em { color: var(--fg); }

/* ── the mast: a heading and a rule, never an eyebrow ─────── */

.mast {
  padding-bottom: clamp(var(--s-5), 2.4vw, var(--s-6));
  margin-bottom: clamp(var(--s-6), 4.5vw, var(--s-8));
  border-bottom: 1px solid var(--hair);
}


.case-tag {
  font-family: var(--mono);
  font-size: var(--fs-label);
  letter-spacing: .15em;
  text-transform: uppercase;
  color: var(--accent);
  margin-top: var(--s-3);
  max-width: none;
}



/* ── buttons ──────────────────────────────────────────────── */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .5rem;
  background: var(--gold);
  color: #0a0b0f;
  font-family: var(--display);
  font-size: var(--fs-sm);
  letter-spacing: .07em;
  text-decoration: none;
  border: 0;
  border-radius: 3px;
  padding: .82rem 1.55rem;
  cursor: pointer;
  transition: background var(--t-hover) ease, transform var(--t-hover) var(--ease-ui);
}
.btn:hover { background: #ffd75e; }
.btn:active { transform: translateY(1px); transition-duration: var(--t-press); }
.btn-lg { padding: 1.05rem 2.15rem; font-size: 1.02rem; }
.btn-sm { padding: .5rem 1.05rem; font-size: var(--fs-xs); min-height: 44px; }

.btn-ghost {
  display: inline-flex;
  align-items: center;
  gap: .5rem;
  font-family: var(--display);
  font-size: var(--fs-sm);
  text-decoration: none;
  padding: .9rem 0;
  border-bottom: 1px solid var(--hair);
  /* `gap` was animated here: a layout property, so every frame re-ran
     layout for a 6px nudge. The arrow carries the same read on transform. */
  transition: border-color var(--t-hover) ease;
}
.btn-ghost { letter-spacing: .06em; }
.btn-ghost:hover { border-color: var(--skin); }

.arr { display: inline-block; transition: transform var(--t-hover) var(--ease-ui); }

/* ── top bar ──────────────────────────────────────────────── */

.topbar {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 100;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: calc(1.05rem - .42rem * var(--brand-shrink, 0)) var(--px);
  /* Opaque, and no backdrop-filter. Two findings, one line of CSS.
     A blur on a full-width fixed bar makes the compositor copy and re-blur
     the strip behind it on EVERY scroll frame; an A/B on real wheel events
     measured 33.3ms per frame (30fps) with it against 16.7ms (60fps)
     without, and across every later run the blurred build was the only one
     that ever fell to 30fps. Removing it then exposed what it had been
     hiding: the translucency's only job was obscuring the page behind the
     bar, and the blur was doing that by smearing. Unsmeared, the letterforms
     underneath resolve into a readable ghost across the nav - visible in
     screenshots at .95, .97 and .98 alike. So the fill goes solid. It costs
     nothing, because there was never anything worth seeing through. */
  /* --bar-bg and --bar-fg are written by main.js from the ACTUAL computed
     background of the section currently under the bar, so the bar dissolves
     into whatever it is sitting on. Reading the real colour rather than
     keeping a hand-written list beside it means the two cannot drift apart:
     restyle a section and the bar follows on its own.

     The old two-state flip could only ever be ink or paper, so it sat
     near-black on Mischief's warm brown (30,19,15) and on Davis's navy
     (13,29,45), and cream on Kempker's near-white (251,251,249).

     The rule stays transitioned, so moving between sections is a half-second
     dissolve rather than a switch. */
  background: var(--bar-bg, var(--ink));
  color: var(--bar-fg, var(--bone));
  border-bottom: 1px solid color-mix(in srgb, var(--bar-fg, var(--bone)) 13%, transparent);
  transition: background var(--t-theme) ease, color var(--t-theme) ease, border-color var(--t-theme) ease;
}
/* Fallback only, for the first frame before the script has measured
   anything — or if it never runs. Without it the bar would sit dark over a
   pale section in that gap. Inline custom properties from the script
   outrank these. */
.topbar.on-light { --bar-bg: var(--paper); --bar-fg: #14161c; }

/* How far through a 21-screen page you are. Two pixels, no numerals. */
.scroll-rail {
  position: absolute;
  inset: auto 0 0 0;
  height: 2px;
  background: transparent;
  overflow: hidden;
}
.scroll-rail i {
  display: block;
  height: 100%;
  width: 100%;
  background: var(--gold);
  transform: scaleX(0);
  transform-origin: left center;
}

.meter-pause {
  appearance: none;
  background: none;
  border: 0;
  width: 44px;
  height: 44px;
  margin-inline-end: var(--s-2);
  padding: 0;
  cursor: pointer;
  position: relative;
  color: var(--slate);
  transition: color var(--t-hover) ease;
}
.meter-pause:hover { color: var(--bone); }
/* two bars for pause; one triangle once it is paused */
.meter-pause::before, .meter-pause::after {
  content: "";
  position: absolute;
  top: 50%;
  width: 3px;
  height: 12px;
  background: currentColor;
  transform: translateY(-50%);
}
.meter-pause::before { inset-inline-start: 15px; }
.meter-pause::after  { inset-inline-start: 22px; }
.meter-pause[aria-pressed="true"]::before {
  inset-inline-start: 16px;
  width: 0;
  height: 0;
  background: none;
  border-block: 7px solid transparent;
  border-inline-start: 11px solid currentColor;
}
.meter-pause[aria-pressed="true"]::after { display: none; }

/* ── brand ────────────────────────────────────────────────────
   The wordmark is the logo's own artwork rather than type chosen to
   resemble it: the FALCONITE and MARKETING glyphs lifted straight out of
   logo-full.svg as paths. It therefore cannot drift out of step with the
   logo, needs no webfont to load before it is correct, and stays sharp at
   any size. The tagline it replaced was three bulleted words set in the
   mono face — a different voice from the logo, sitting right beside it.

   --brand-shrink runs 0 at the top of the page to 1 once you are past the
   hero's shoulder, written by main.js on each scroll frame. Every size
   below interpolates against it, so the bar contracts continuously with
   the scroll instead of snapping between two states on a class. Nothing
   here is transitioned — the scroll position IS the timeline, and a
   transition on top of it would only add lag. */
.topbar { --brand-shrink: 0; }

.brand {
  display: flex;
  align-items: center;
  gap: calc(.88rem - .28rem * var(--brand-shrink, 0));
  text-decoration: none;
}
.mark {
  width: calc(83px - 27px * var(--brand-shrink, 0));
  height: auto;
  color: var(--gold);
  flex-shrink: 0;
}
.wordmark {
  height: calc(30px - 10px * var(--brand-shrink, 0));
  width: auto;
  flex-shrink: 0;
}

.topnav { display: flex; align-items: center; gap: clamp(.9rem, 2.1vw, 1.9rem); }
.topnav a:not(.btn) {
  /* 22px of text is under the 24px minimum target, and these are not
     inline-in-a-sentence, so the exception doesn't apply. */
  padding-block: .62rem;
  font-family: var(--display);
  font-size: var(--fs-ui);
  letter-spacing: .06em;
  text-decoration: none;
  opacity: .74;
  transition: opacity var(--t-hover) ease;
}
.topnav a:not(.btn):hover { opacity: 1; }
.topnav a:not(.btn) { position: relative; }

@media (max-width: 800px) { .topnav a:not(.btn) { display: none; } }
/* Below 800px the nav links go, leaving the brand and the button. The
   brand has to give ground too or the two collide. */
@media (max-width: 560px) {
  .mark     { width:  calc(58px - 16px * var(--brand-shrink, 0)); }
  .wordmark { height: calc(22px -  6px * var(--brand-shrink, 0)); }
}
/* At 360px the button was breaking "Start a project" across three lines
   and standing the bar up to 92px. Holding it on one line costs ~165px,
   which is what is left for the brand here. */
.topnav .btn { white-space: nowrap; }
@media (max-width: 400px) {
  .brand    { gap: calc(.62rem - .16rem * var(--brand-shrink, 0)); }
  .mark     { width:  calc(44px - 10px * var(--brand-shrink, 0)); }
  .wordmark { height: calc(17px -  4px * var(--brand-shrink, 0)); }
}

/* ══════════ HERO ══════════ */

.hero {
  position: relative;
  background: var(--ink);
  padding: clamp(7rem, 14vh, 10rem) var(--px) 0;
  overflow: hidden;
  min-height: min(100svh, 900px);
  display: flex;
  flex-direction: column;
  justify-content: center;
}

.hero-wash {
  position: absolute;
  inset: 0;
  background:
    radial-gradient(80% 60% at 78% 32%, color-mix(in srgb, var(--skin) 22%, transparent), transparent 68%),
    radial-gradient(50% 50% at 8% 88%, color-mix(in srgb, var(--skin) 9%, transparent), transparent 70%);
  transition: background 1s ease;
  pointer-events: none;
}

.hero-grid {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1.12fr) minmax(0, .88fr);
  gap: clamp(var(--s-6), 5vw, var(--s-8));
  align-items: center;
  width: 100%;
}

.hero-sub {
  font-size: var(--fs-md);
  line-height: 1.5;
  color: var(--bone-dim);
  max-width: 46ch;
  margin: var(--s-5) 0 var(--s-6);
  min-height: 3em;
}

/* The headline names a problem and the line under it names a client, so a
   first-time visitor could read both without learning what this company
   actually is. This says it once, quietly, above the buttons. */
.hero-what {
  margin: 0 0 clamp(var(--s-5), 3vw, var(--s-6));
  font-family: var(--mono);
  font-size: var(--fs-label);
  letter-spacing: .15em;
  text-transform: uppercase;
  color: var(--slate);
  max-width: none;
}

.cta-row { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-4) var(--s-6); }

.hero-stage { position: relative; }

.stage-frame {
  border: 1px solid var(--hair);
  border-radius: 9px;
  overflow: hidden;
  background: var(--ink-2);
  box-shadow:
    0 40px 90px -50px rgba(0, 0, 0, .9),
    0 0 0 1px color-mix(in srgb, var(--skin) 22%, transparent),
    0 26px 70px -40px color-mix(in srgb, var(--skin) 60%, transparent);
  transition: box-shadow 1s ease;
}

.stage-link { display: block; text-decoration: none; position: relative; }
.stage-link::after {
  content: "See the case study \2192";
  position: absolute;
  inset-inline-end: var(--s-4);
  bottom: var(--s-4);
  padding: .42rem .8rem;
  background: var(--ink);
  color: var(--bone);
  font-family: var(--mono);
  font-size: var(--fs-label);
  letter-spacing: .12em;
  text-transform: uppercase;
  border-radius: 3px;
  opacity: 0;
  transform: translateY(6px);
  transition: opacity var(--t-hover) ease, transform var(--t-hover) var(--ease-ui);
  pointer-events: none;
}
@media (hover: hover) and (pointer: fine) {
  .stage-link:hover::after { opacity: 1; transform: none; }
}
.stage-link:focus-visible::after { opacity: 1; transform: none; }

.stage-shots { position: relative; aspect-ratio: 16 / 10; }
.stage-shot {
  position: absolute;
  inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  object-position: top center;
  opacity: 0;
  transform: scale(1.02);
  transition: opacity .9s ease, transform 1.6s var(--ease);
}
.stage-shot.is-on { opacity: 1; transform: none; }

.hero-meter {
  position: relative;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1rem 2rem;
  margin-top: clamp(2.2rem, 5vw, 3.6rem);
  padding: 1.1rem 0 clamp(1.6rem, 4vw, 2.6rem);
  border-top: 1px solid var(--hair);
}

.meter-now { display: flex; align-items: baseline; gap: .85rem; flex-wrap: wrap; max-width: none; }
.meter-name {
  font-family: var(--display);
  font-size: var(--fs-name);
  letter-spacing: .035em;
  color: var(--bone);
}
.meter-sector {
  font-family: var(--mono);
  font-size: var(--fs-label);
  letter-spacing: .17em;
  text-transform: uppercase;
  color: var(--muted);
}

.hero-meter > .meter-pause { margin-inline-start: auto; }
.meter-ticks { list-style: none; display: flex; gap: .5rem; }
.meter-ticks button {
  appearance: none; background: none; border: 0;
  padding: .5rem .2rem; cursor: pointer; display: block; position: relative;
}
.meter-ticks button::after { content: ""; position: absolute; inset: -12px -5px; }
.meter-ticks span {
  display: block; width: 42px; height: 2px;
  background: rgba(242, 239, 232, .2);
  transition: background var(--t-theme) ease;
}
.meter-ticks .is-on span { background: var(--skin); }
/* These are buttons. They had no hover state, so nothing said so. */
.meter-ticks button:hover span { background: rgba(242, 239, 232, .55); transition-duration: var(--t-hover); }
.meter-ticks .is-on button:hover span { background: var(--skin); }

@media (max-width: 940px) {
  .hero { min-height: 0; padding-top: 7rem; }
  .hero-grid { grid-template-columns: 1fr; }
  .hero-stage { max-width: 620px; }
}
@media (max-width: 620px) {
  .hero { padding-top: 5.6rem; }
  .hero-sub { margin: 1.3rem 0 1.75rem; }
  .hero-meter { margin-top: 1.4rem; padding: .85rem 0 1.15rem; }
  .meter-ticks button { padding: .42rem .2rem; }
  .meter-ticks span { width: 34px; }
}

/* ══════════ 01 · THE SLOP ══════════ */

.problem {
  --fg: #14161c; --muted: #5b6373; --accent: var(--gold-deep);
  --hair: rgba(20, 22, 28, .13);
  background: var(--paper);
  color: #14161c;
  padding: var(--py) var(--px);
}

.tells { list-style: none; }

.tell {
  display: grid;
  grid-template-columns: 190px minmax(0, 21ch) minmax(0, 1fr);
  /* 43px within against 64px between read as one undifferentiated block;
     this puts it near 1:3 so each mockup groups with its own words. */
  gap: clamp(var(--s-4), 2.2vw, var(--s-6));
  align-items: start;
  padding: clamp(var(--s-6), 3.4vw, var(--s-7)) 0;
  border-bottom: 1px solid rgba(20, 22, 28, .14);
}
.tell h3 { color: #14161c; padding-top: .1rem; }
.tell p { color: #5b6373; }

/* miniature portraits of the thing we're criticising, drawn in CSS */
.slop {
  aspect-ratio: 4 / 3;
  background: #e9e5dc;
  border: 1px solid rgba(20, 22, 28, .13);
  border-radius: 3px;
  padding: 7px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  overflow: hidden;
  filter: saturate(.6);
}
.slop i, .slop u, .slop b, .slop em, .slop span { display: block; }
.slop u { text-decoration: none; }

.slop-a .s-top { display: flex; gap: 4px; justify-content: flex-end; }
.slop-a .s-top i { width: 14px; height: 3px; background: rgba(20, 22, 28, .2); border-radius: 1px; }
.slop-a .s-grad {
  flex: 1; border-radius: 2px;
  background: linear-gradient(135deg, #6366f1, #a855f7);
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 7px;
}
.slop-a .s-grad b { width: 58%; height: 7px; background: rgba(255, 255, 255, .86); border-radius: 2px; }
.slop-a .s-grad u { width: 26%; height: 11px; background: rgba(255, 255, 255, .34); border-radius: 99px; }

.slop-b .s-head { width: 44%; height: 6px; background: rgba(20, 22, 28, .26); border-radius: 2px; margin: 3px 0 1px; }
.slop-b .s-cards { flex: 1; display: grid; grid-template-columns: repeat(3, 1fr); gap: 5px; }
.slop-b .s-cards em {
  background: #fff; border: 1px solid rgba(20, 22, 28, .1); border-radius: 3px;
  padding: 6px; display: flex; flex-direction: column; gap: 4px;
}
.slop-b .s-cards i { width: 10px; height: 10px; border-radius: 50%; background: rgba(99, 102, 241, .5); }
.slop-b .s-cards u { height: 3px; background: rgba(20, 22, 28, .15); border-radius: 1px; }
.slop-b .s-cards u:last-child { width: 68%; }

.slop-c { background: #fff; }
.slop-c .s-wall { flex: 1; display: flex; flex-direction: column; gap: 5px; padding-top: 3px; }
.slop-c .s-wall u { height: 3px; background: rgba(20, 22, 28, .26); border-radius: 1px; }
.slop-c .s-wall u:nth-child(3n) { width: 76%; }
.slop-c .s-wall u:nth-child(4n) { width: 88%; }
.slop-c .s-buried {
  width: 34px; height: 3px; border-radius: 1px; margin-top: auto;
  background: rgba(99, 102, 241, .55);   /* the one link, lost at the bottom */
}

.problem .problem-turn {
  margin-top: clamp(var(--s-6), 5vw, var(--s-8));
  font-family: var(--display);
  font-size: clamp(1.65rem, 3.7vw, 2.9rem);
  line-height: 1.02;
  letter-spacing: .006em;
  max-width: 22ch;
  color: #14161c;
}

@media (max-width: 900px) {
  .tell { grid-template-columns: 140px minmax(0, 1fr); }
  .tell p { grid-column: 2; }
}
@media (max-width: 560px) {
  .tell { grid-template-columns: 1fr; }
  .tell p { grid-column: 1; }
  .slop { max-width: 220px; }
}

/* ══════════ THE WORK INDEX ══════════
   Five case studies is a long scroll if the one that looks like your
   business is fourth. This is the table of contents for them. */

.work-index {
  background: var(--ink);
  padding: clamp(var(--s-7), 6vw, var(--s-8)) var(--px);
}
.wi-label {
  font-family: var(--mono);
  font-size: var(--fs-label);
  letter-spacing: .15em;
  text-transform: uppercase;
  color: var(--gold);
  margin-bottom: var(--s-5);
  max-width: none;
}
.work-index ul {
  list-style: none;
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  border-top: 1px solid var(--hair);
}
.work-index li { border-bottom: 1px solid var(--hair); }
.work-index a {
  display: block;
  padding: var(--s-5) var(--s-4) var(--s-5) 0;
  text-decoration: none;
  border-top: 2px solid transparent;
  margin-top: -1px;
  transition: border-color var(--t-hover) ease;
}
.work-index b {
  display: block;
  font-family: var(--display);
  font-weight: 400;
  font-synthesis-weight: none;
  text-transform: uppercase;
  font-size: var(--fs-name);
  letter-spacing: .02em;
  line-height: 1.05;
  color: var(--bone);
}
.work-index span {
  display: block;
  margin-top: var(--s-2);
  font-family: var(--mono);
  font-size: var(--fs-label);
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--slate);
  transition: color var(--t-hover) ease;
}
.work-index a:hover { border-top-color: var(--gold); }
.work-index a:hover span { color: var(--bone-dim); }

@media (max-width: 900px) {
  .work-index ul { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 480px) {
  .work-index ul { grid-template-columns: 1fr; }
}

/* ══════════ 02–05 · CASE STUDIES ══════════ */

.case { background: var(--bg); color: var(--fg); padding: var(--py) var(--px); }

/* Seam rule. Most boundaries here are a tone change and need nothing, but
   `.problem` (#f4f1ea) sits directly above Harken (#f5f1ea) — one point
   apart in red, an invisible join — and `.range` and `.services` are the
   same ink. A hairline in each section's own palette makes every seam
   deliberate, and is invisible where the tones already separate. */
.problem, .case, .services, .rates, .speed, .process, .contact {
  border-top: 1px solid var(--hair);
}
/* .range is excluded on purpose: its bands run flush to the top edge, so a
   hairline would stack against each band's own 5px accent and read muddy —
   and it always follows a light section, which already separates it. */

.case[data-case="harken"]   { --bg: #f5f1ea; --fg: #1a1714; --muted: #6a6055; --accent: #9e4a11; --skin: #c9611a; --hair: rgba(26, 23, 20, .15); }
.case[data-case="mischief"] { --bg: #1e130f; --fg: #f4ead9; --muted: #a08a73; --accent: #e0a55a; --skin: #e0a55a; --hair: rgba(244, 234, 217, .15); }
.case[data-case="davis"]    { --bg: #0d1d2d; --fg: #f6f8fa; --muted: #8497aa; --accent: #ffc61a; --skin: #ffc61a; --hair: rgba(246, 248, 250, .15); }
.case[data-case="alphatots"] { --bg: #faf6ec; --fg: #26311f; --muted: #55604b; --accent: #b00f28; --skin: #d71433; --hair: rgba(38, 49, 31, .15); }
.case[data-case="kempker"]  { --bg: #fbfbf9; --fg: #17210f; --muted: #52603f; --accent: #3f6618; --skin: #55871f; --hair: rgba(23, 33, 15, .15); }

.case-body {
  display: grid;
  grid-template-columns: minmax(0, .86fr) minmax(0, 1.14fr);
  gap: clamp(var(--s-6), 4.5vw, var(--s-8));
  align-items: start;
}

/* alternate which side the writing sits on */
.case-flip .case-body { grid-template-columns: minmax(0, 1.14fr) minmax(0, .86fr); }
.case-flip .case-copy { order: 2; }
.case-flip .case-shots { order: 1; }

.case-cta {
  display: inline-block;
  margin-top: var(--s-6);
  font-family: var(--display);
  font-size: 1.04rem;
  letter-spacing: .045em;
  text-decoration: none;
  color: var(--fg);
  border-bottom: 2px solid var(--accent);
  padding-bottom: .22rem;
  transition: color var(--t-hover) ease;
}
.case-cta:hover { color: var(--accent); }

@media (hover: hover) and (pointer: fine) {
  .btn:hover { transform: translateY(-2px); }
  .case-cta:hover .arr,
  .foot-link:hover .arr { transform: translateX(4px); }
  /* the hero's ghost link points down, so it should move down */
  .btn-ghost:hover .arr { transform: translateY(3px); }
}

.case-shots { display: flex; flex-direction: column; gap: clamp(var(--s-4), 2vw, var(--s-5)); }

@media (min-width: 1021px) {
  .case-copy { position: sticky; top: 6.5rem; align-self: start; }
}
@media (max-width: 1020px) {
  .case-body, .case-flip .case-body { grid-template-columns: 1fr; }
  .case-flip .case-copy { order: 1; }
  .case-flip .case-shots { order: 2; }
}

/* ── ledger ───────────────────────────────────────────────── */

.ledger { margin-top: var(--s-6); border-top: 1px solid var(--hair); }
.ledger div {
  display: grid;
  grid-template-columns: 8.5rem minmax(0, 1fr);
  gap: var(--s-4);
  padding: var(--s-3) 0;
  border-bottom: 1px solid var(--hair);
}
.ledger dt {
  font-family: var(--mono);
  font-size: var(--fs-label);
  letter-spacing: .15em;
  text-transform: uppercase;
  color: var(--accent);
  padding-top: .3rem;
}
.ledger dd { font-size: var(--fs-sm); color: var(--fg); }

@media (max-width: 520px) { .ledger div { grid-template-columns: 1fr; gap: .2rem; } }

/* ── browser frame ────────────────────────────────────────── */

.frame {
  background: color-mix(in srgb, var(--fg) 4%, transparent);
  border: 1px solid var(--hair);
  border-radius: 8px;
  overflow: hidden;
  box-shadow: 0 30px 64px -40px rgba(0, 0, 0, .6);
}

.chrome { display: flex; align-items: center; gap: .4rem; padding: .58rem .9rem; border-bottom: 1px solid var(--hair); }
.chrome span { width: 8px; height: 8px; border-radius: 50%; background: currentColor; opacity: .2; }
.chrome-pill {
  margin-inline-start: .65rem; min-width: 0;
  font-family: var(--mono); font-size: var(--fs-label); letter-spacing: .05em;
  color: var(--muted);
  overflow: hidden; white-space: nowrap; text-overflow: ellipsis; max-width: none;
}

.shot { overflow: hidden; }
.shot img { width: 100%; display: block; }
.shot-sm { aspect-ratio: 16 / 10; }
.shot-sm img { height: 100%; object-fit: cover; object-position: top center; }

.shot-scroll { position: relative; aspect-ratio: 16 / 10.5; }
/* Slow on the way down, quick on the way back. The 7s is the deliberate
   read-the-page pace; applying it to the return meant the image kept
   drifting for seven seconds after the pointer had gone. */
.shot-scroll img {
  position: absolute; inset: 0 0 auto 0;
  transition: transform .45s var(--ease-ui);
}
.frame:hover .shot-scroll img,
.frame:focus-within .shot-scroll img { transition: transform 7s linear; }

/* Explanatory motion, so 7s linear is right — but a tap fires :hover on
   touch, which would strand a phone user mid-scroll with no way out.
   Keyboard focus still triggers it on every device. */
@media (hover: hover) and (pointer: fine) {
  /* promoted only while the pointer is actually on it, not for the life
     of the page.
     `:not(.is-scrolling)` matters more than it looks: without it, wheeling
     down the page with the cursor anywhere over a frame counts as a hover,
     so a 3,000px screenshot starts sliding inside its box while the page
     is also moving. Two things sliding at once reads as broken. */
  html:not(.is-scrolling) .frame:hover .shot-scroll img {
    transform: translateY(calc(-100% + 62%));
    will-change: transform;
  }
}
.frame:focus-within .shot-scroll img { transform: translateY(calc(-100% + 62%)); }

.shot-hint {
  font-family: var(--mono); font-size: var(--fs-label); letter-spacing: .15em; text-transform: uppercase;
  color: var(--muted); padding: .55rem .9rem; border-top: 1px solid var(--hair); max-width: none;
}

.frame-pair { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(var(--s-4), 2vw, var(--s-5)); }
@media (max-width: 640px) { .frame-pair { grid-template-columns: 1fr; } }

/* ══════════ THE RANGE — four palettes, full bleed ══════════ */

.range { background: var(--ink); padding: 0 0 var(--py); }

.bands { list-style: none; display: grid; grid-template-columns: repeat(5, 1fr); }

.band {
  background: var(--field);
  color: var(--on);
  min-height: clamp(230px, 36vh, 400px);
  padding: clamp(var(--s-4), 2.2vw, var(--s-6));
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  gap: var(--s-1);
  box-shadow: inset 0 5px 0 0 var(--edge);
}
.band-name {
  font-family: var(--display);
  font-size: var(--fs-name);
  letter-spacing: .04em;
  line-height: 1.05;
}
.band-sector {
  font-family: var(--mono);
  font-size: var(--fs-label);
  letter-spacing: .14em;
  text-transform: uppercase;
  opacity: .62;
}

.range-say {
  margin: clamp(var(--s-7), 5vw, var(--s-8)) var(--px) 0;
}
.range-line {
  font-size: clamp(1.75rem, 3.9vw, 3.3rem);
  color: var(--bone);
  max-width: 20ch;
}
.range-sub {
  margin-top: var(--s-5);
  font-size: var(--fs-md);
  line-height: 1.58;
  color: var(--bone-dim);
  max-width: 56ch;
}
.range-sub em { font-style: italic; color: var(--bone); }

@media (max-width: 1000px) {
  .bands { grid-template-columns: repeat(3, 1fr); }
}
@media (max-width: 620px) {
  .bands { grid-template-columns: repeat(2, 1fr); }
  .band { min-height: 180px; }
}

/* ══════════ 06 · SERVICES ══════════ */

.services {
  --fg: #14161c; --muted: #5b6373; --accent: var(--gold-deep);
  --hair: rgba(20, 22, 28, .14);
  background: var(--paper);
  color: #14161c;
  padding: var(--py) var(--px);
}

.index { list-style: none; }

.idx {
  display: grid;
  /* Proximity: a name sat 43px from its own note and 64px from the next
     row — a 1.5x ratio reads as ambiguous grouping. Pulling the columns
     together and pushing the rows apart makes it roughly 1:3.5. */
  grid-template-columns: minmax(0, 16rem) minmax(0, 1fr);
  gap: clamp(var(--s-3), 1.6vw, var(--s-5));
  align-items: baseline;
  padding: clamp(var(--s-6), 3.4vw, var(--s-7)) var(--bleed);
  margin-inline: calc(var(--bleed) * -1);
  border-bottom: 1px solid var(--hair);
}
.idx:last-child { border-bottom: 0; }

.idx-name {
  font-family: var(--display);
  font-size: var(--fs-h3);
  letter-spacing: .012em;
  line-height: 1.08;
  color: #14161c;
}
.idx-note { color: #5b6373; font-size: var(--fs-sm); line-height: 1.55; }



@media (max-width: 880px) {
  .idx { grid-template-columns: 1fr; gap: .5rem; }
}

/* ══════════ PROCESS — three verbs, at scale ══════════
   The sequence is carried by the words themselves (learn, then plan, then
   build), which is why this section needs no numerals. Each verb is set at
   headline size so the three of them read as the section's structure. */

.process {
  --fg: #14161c; --muted: #5b6373; --accent: var(--gold-deep);
  --hair: rgba(20, 22, 28, .14);
  background: var(--paper);
  color: #14161c;
  padding: var(--py) var(--px);
}

.steps { list-style: none; }

.step {
  display: grid;
  grid-template-columns: minmax(0, 15rem) minmax(0, 58ch);
  justify-content: start;
  gap: 0 clamp(var(--s-5), 2.6vw, var(--s-6));
  align-items: start;
  padding: clamp(var(--s-6), 4vw, var(--s-7)) var(--bleed);
  margin-inline: calc(var(--bleed) * -1);
  border-top: 1px solid rgba(20, 22, 28, .14);
}
.step:first-child { border-top: 0; }

.step-verb {
  font-size: clamp(2.6rem, 6.4vw, 5.4rem);
  line-height: .84;
  letter-spacing: .004em;
  color: #14161c;
  max-width: none;
}

.step-lead {
  font-size: var(--fs-lead);
  line-height: 1.42;
  color: #14161c;
  letter-spacing: -.008em;
}
.step-note {
  margin-top: var(--s-3);
  color: #5b6373;
  font-size: var(--fs-sm);
  line-height: 1.6;
}

@media (max-width: 820px) {
  .step { grid-template-columns: 1fr; gap: var(--s-4) 0; }
}

/* ══════════ TESTIMONIAL ══════════ */

.quote {
  background: var(--ink-2);
  padding: clamp(5.5rem, 11vw, 9rem) var(--px);
  border-block: 1px solid var(--hair);
  /* The quote left half the viewport empty and double-ruled its own
     attribution. The call to action moves into that empty half and
     bottom-aligns, which anchors the composition and removes a rule. */
  display: grid;
  grid-template-columns: minmax(0, 1.25fr) minmax(0, .75fr);
  gap: clamp(var(--s-6), 5vw, var(--s-8));
  align-items: end;
}

.quote blockquote p {
  font-family: var(--serif);
  font-weight: 300;
  font-style: italic;
  font-size: clamp(1.7rem, 4.6vw, 3.8rem);
  line-height: 1.12;
  letter-spacing: -.024em;
  max-width: 20ch;
  color: var(--bone);
  text-wrap: balance;
}
.quote blockquote p::before { content: "\201C"; }
.quote blockquote p::after  { content: "\201D"; }

.quote figcaption {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: .3rem 1rem;
  margin-top: var(--s-6); padding-top: var(--s-4); border-top: 1px solid var(--hair);
}
.quote .section-cta {
  margin-top: 0;
  padding-top: 0;
  border-top: 0;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--s-4);
}
@media (max-width: 900px) {
  .quote { grid-template-columns: 1fr; align-items: start; }
  .quote .section-cta {
    flex-direction: row;
    align-items: center;
    padding-top: var(--s-5);
    border-top: 1px solid var(--hair);
  }
}
.quote cite {
  font-family: var(--display); font-style: normal; font-weight: 400;
  font-size: 1rem; letter-spacing: .05em;
}
.quote figcaption span {
  font-family: var(--mono); font-size: var(--fs-label); letter-spacing: .16em;
  text-transform: uppercase; color: var(--gold);
}

/* ══════════ 08 · CONTACT ══════════ */

.contact {
  background: var(--ink);
  padding: var(--py) var(--px);
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, .9fr);
  gap: clamp(2.5rem, 5vw, 5rem);
  align-items: start;
}

.contact .mast { margin-bottom: var(--s-5); }

.contact-form {
  display: flex; flex-direction: column; gap: var(--s-4);
  background: var(--ink-2);
  border: 1px solid var(--hair);
  border-radius: 8px;
  padding: clamp(var(--s-5), 3vw, var(--s-6));
}

.contact-form .row { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s-4); }

.contact-form label {
  display: flex; flex-direction: column; gap: .42rem;
  font-family: var(--mono); font-size: var(--fs-label); letter-spacing: .15em;
  text-transform: uppercase; color: var(--slate);
}

.contact-form input,
.contact-form select,
.contact-form textarea {
  font-family: var(--serif); font-size: 1rem;
  letter-spacing: normal; text-transform: none;
  color: var(--bone); background: var(--ink);
  border: 1px solid var(--field-edge); border-radius: 4px;
  padding: .8rem .92rem;
  min-height: 44px;
  transition: border-color var(--t-hover) ease;
}
/* appearance:none strips the native arrow, so the control looked exactly
   like a text input. Put one back. */
.contact-form select {
  appearance: none;
  padding-inline-end: 2.6rem;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%23bcbfc6' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 1rem center;
  background-size: 10px 6px;
}
.contact-form textarea { resize: vertical; }
.contact-form input:focus, .contact-form select:focus, .contact-form textarea:focus { border-color: var(--gold); }
.contact-form input:focus-visible,
.contact-form select:focus-visible,
.contact-form textarea:focus-visible { outline: 2px solid var(--gold); outline-offset: 1px; }

.contact-form .btn { align-self: flex-start; margin-top: .25rem; }
.form-note { font-family: var(--serif); font-size: var(--fs-xs); color: var(--slate); letter-spacing: normal; text-transform: none; }
.form-note a { color: var(--bone); border-bottom: 1px solid var(--gold); text-decoration: none; }

@media (max-width: 980px) {
  .contact { grid-template-columns: 1fr; }
  .contact-form .row { grid-template-columns: 1fr; }
}

/* ══════════ FOOTER ══════════ */

.foot {
  background: var(--ink);
  border-top: 1px solid var(--hair);
  padding: clamp(2.6rem, 5vw, 4rem) var(--px) 3rem;
  color: var(--slate);
  font-size: var(--fs-sm);
}
.foot-top {
  display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between;
  gap: 1.5rem 3rem; padding-bottom: 1.6rem; border-bottom: 1px solid var(--hair);
}
.foot-brand { display: flex; align-items: center; gap: .65rem; }
.foot-brand .mark { width: 38px; }
.foot-brand p {
  font-family: var(--display); font-weight: 400;
  font-size: 1.34rem; letter-spacing: .035em; color: var(--bone);
}
.foot-brand span { color: var(--gold); }
.foot-line { max-width: 52ch; }
.foot-link {
  font-family: var(--display);
  text-transform: uppercase;
  letter-spacing: .06em;
  font-size: var(--fs-ui);
  color: var(--bone);
  text-decoration: none;
  border-bottom: 2px solid var(--gold);
  padding-bottom: .1rem;
  white-space: nowrap;
}
.foot-link:hover { color: var(--gold); }
.foot-fine { font-size: var(--fs-xs); opacity: .7; margin-top: 1.4rem; font-variant-numeric: tabular-nums; }

/* ══════════ SECTION CTA — every section gets one ══════════ */

.section-cta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-4) var(--s-6);
  margin-top: clamp(var(--s-6), 4.5vw, var(--s-7));
  padding-top: clamp(var(--s-5), 3vw, var(--s-6));
  border-top: 1px solid var(--hair);
}
/* Twelve filled gold buttons meant none of them read as the primary
   action. Filled is now reserved for the five real decision points —
   the hero, the three prices, and the form — and every mid-section
   nudge is outlined in the section's own accent. */
.section-cta .btn {
  background: transparent;
  color: var(--fg);
  box-shadow: inset 0 0 0 1px var(--accent);
}
.section-cta .btn:hover {
  background: color-mix(in srgb, var(--accent) 15%, transparent);
  box-shadow: inset 0 0 0 1px var(--accent);
}

.section-cta p {
  font-family: var(--serif);
  font-size: var(--fs-sm);
  color: var(--muted);
  max-width: 36ch;
}
.section-cta p a {
  color: var(--fg);
  text-decoration: none;
  border-bottom: 1px solid var(--accent);
}
.section-cta p a:hover { color: var(--accent); }


/* ══════════ ADVERTISING — three moments, each with its own format ══════════
   The formats are drawn in CSS rather than screenshotted, so the section
   explains what it is selling instead of describing it. Deliberately a
   rhyme with the slop mockups in the opening section — same technique,
   showing something worth buying rather than something to avoid. */

.ads { background: var(--ink); padding: var(--py) var(--px); }

.ads-lead {
  font-size: var(--fs-lead);
  line-height: 1.44;
  color: var(--bone);
  max-width: 58ch;
  margin-bottom: clamp(var(--s-7), 5vw, var(--s-8));
}

.moments { list-style: none; }

.moment {
  display: grid;
  grid-template-columns: 200px minmax(0, 60ch);
  justify-content: start;
  gap: 0 clamp(var(--s-5), 2.6vw, var(--s-6));
  align-items: start;
  padding: clamp(var(--s-6), 4vw, var(--s-7)) var(--bleed);
  margin-inline: calc(var(--bleed) * -1);
  border-top: 1px solid var(--hair);
}
.moment:first-child { border-top: 0; }

.moment-name {
  font-size: var(--fs-h3);
  letter-spacing: .012em;
  line-height: 1.02;
  color: var(--bone);
  max-width: none;
}
.moment-lead {
  margin-top: var(--s-2);
  font-family: var(--mono);
  font-size: var(--fs-label);
  letter-spacing: .15em;
  text-transform: uppercase;
  color: var(--gold);
  max-width: none;
}
.moment-note {
  margin-top: var(--s-4);
  color: var(--slate);
  font-size: var(--fs-sm);
  line-height: 1.6;
}

.ads-ledger { margin-top: clamp(var(--s-7), 5vw, var(--s-8)); }
.ads-ledger dd { color: var(--bone-dim); }

/* ── the three formats, drawn ──────────────────────────────────── */

.admock {
  aspect-ratio: 4 / 3;
  background: #15171d;
  border: 1px solid rgba(242, 239, 232, .12);
  border-radius: 4px;
  padding: 9px;
  display: flex;
  flex-direction: column;
  gap: 7px;
  overflow: hidden;
}
.admock i, .admock u, .admock b, .admock span { display: block; }
.admock u { text-decoration: none; }

/* a search page: the query, a paid result, then the map pack */
.ad-search .m-search { height: 13px; border-radius: 99px; background: rgba(242, 239, 232, .1); padding: 4px 6px; }
.ad-search .m-search i { width: 46%; height: 4px; border-radius: 1px; background: rgba(242, 239, 232, .3); }
.ad-search .m-result { display: flex; flex-direction: column; gap: 4px; }
.ad-search .m-result b {
  width: 20px; height: 8px; border-radius: 2px;
  /* the text is transparent — this is a shape, not a word. Left at 700 it
     was the only thing on the page requesting a Newsreader bold. */
  background: var(--gold); color: transparent; font-size: 6px; font-weight: 400;
}
.ad-search .m-result u { height: 4px; border-radius: 1px; background: rgba(242, 239, 232, .42); }
.ad-search .m-result u:last-child { width: 72%; background: rgba(242, 239, 232, .2); }
.ad-search .m-map {
  flex: 1; border-radius: 3px; margin-top: 2px;
  background:
    linear-gradient(90deg, transparent 49%, rgba(242, 239, 232, .07) 50%, transparent 51%),
    linear-gradient(0deg, transparent 49%, rgba(242, 239, 232, .07) 50%, transparent 51%),
    rgba(242, 239, 232, .05);
  position: relative;
}
.ad-search .m-map i {
  position: absolute; width: 7px; height: 7px; border-radius: 50% 50% 50% 0;
  background: var(--gold); transform: rotate(-45deg);
}
.ad-search .m-map i:nth-child(1) { left: 22%; top: 30%; }
.ad-search .m-map i:nth-child(2) { left: 52%; top: 55%; opacity: .55; }
.ad-search .m-map i:nth-child(3) { left: 74%; top: 24%; opacity: .55; }

/* a feed post: avatar, photo, sponsored row with a button */
.ad-social .m-head { display: flex; align-items: center; gap: 6px; }
.ad-social .m-head i { width: 15px; height: 15px; border-radius: 50%; background: rgba(242, 239, 232, .28); }
.ad-social .m-head u { flex: 1; height: 4px; border-radius: 1px; background: rgba(242, 239, 232, .18); max-width: 55%; }
.ad-social .m-photo {
  flex: 1; border-radius: 3px;
  background: linear-gradient(150deg, rgba(255, 200, 44, .28), rgba(242, 239, 232, .07));
}
.ad-social .m-cta { display: flex; align-items: center; gap: 6px; }
.ad-social .m-cta u { flex: 1; height: 4px; border-radius: 1px; background: rgba(242, 239, 232, .16); }
.ad-social .m-cta b { width: 34px; height: 11px; border-radius: 2px; background: var(--gold); }

/* a page they are reading, with your banner following them */
.ad-return { background: #12141a; }
.ad-return .m-page { flex: 1; display: flex; flex-direction: column; gap: 6px; padding-top: 2px; }
.ad-return .m-page u { height: 4px; border-radius: 1px; background: rgba(242, 239, 232, .14); }
.ad-return .m-page u:nth-child(3) { width: 78%; }
.ad-return .m-page u:nth-child(5) { width: 64%; }
.ad-return .m-banner {
  align-self: flex-end;
  width: 62%; height: 30px;
  border-radius: 3px;
  background: linear-gradient(120deg, var(--gold), #e0a836);
  box-shadow: 0 6px 14px -8px rgba(0, 0, 0, .9);
}

@media (max-width: 860px) {
  .moment { grid-template-columns: 1fr; gap: var(--s-5) 0; }
  .admock { max-width: 220px; }
}

/* ══════════ PRICING — a rate card, not three cards ══════════
   Chapter 01 spends its whole argument attacking "the same three cards",
   so the prices are set as ledger rows instead, and the number itself is
   the display type. One row per tier, full width, hairline-separated. */

.rates {
  --fg: #14161c; --muted: #5b6373; --accent: var(--gold-deep);
  --hair: rgba(20, 22, 28, .14);
  background: var(--paper);
  color: #14161c;
  padding: var(--py) var(--px);
}

.tiers { list-style: none; }
.tier:last-child { border-bottom: 0; }

.tier {
  display: grid;
  grid-template-columns: minmax(0, 19rem) minmax(0, 1fr) minmax(0, 13rem);
  gap: clamp(var(--s-5), 3vw, var(--s-7));
  align-items: start;
  padding: clamp(var(--s-6), 4vw, var(--s-7)) var(--bleed);
  margin-inline: calc(var(--bleed) * -1);
  border-bottom: 1px solid rgba(20, 22, 28, .14);
  transition: background var(--t-hover) ease;
}
.tier:hover { background: rgba(20, 22, 28, .022); }

.tier-price {
  display: block;
  font-size: clamp(3.2rem, 7.4vw, 5.8rem);
  line-height: .86;
  letter-spacing: -.005em;
  color: #14161c;
  font-variant-numeric: tabular-nums;
  max-width: none;
}
.tier-price sup {
  position: relative;
  top: .42em;
  font-size: .36em;
  vertical-align: top;
  margin-inline-end: .06em;
  color: var(--gold-deep);
}
.tier-name {
  display: block;
  margin-top: .85rem;
  font-size: var(--fs-name);
  letter-spacing: .02em;
  line-height: 1;
  color: #14161c;
  max-width: none;
}
.tier-cap {
  display: block;
  margin-top: .5rem;
  font-family: var(--mono);
  font-size: var(--fs-label);
  letter-spacing: .15em;
  color: var(--gold-deep);
  max-width: none;
}

.tier-gets { list-style: none; display: flex; flex-direction: column; gap: var(--s-3); }
.tier-gets li {
  position: relative;
  padding-inline-start: 1.75rem;
  font-size: var(--fs-sm);
  line-height: 1.46;
  color: #5b6373;
  max-width: 46ch;
}
.tier-gets li::before {
  content: "";
  position: absolute;
  inset-inline-start: 0;
  top: .52rem;
  width: 9px;
  height: 9px;
  background: var(--gold-deep);
  clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%);
}
.tier-gets b { font-weight: inherit; color: #14161c; }

.tier-act { display: flex; flex-direction: column; align-items: flex-start; gap: var(--s-3); }
.tier-act .btn { width: 100%; text-align: center; }
.tier-when {
  font-family: var(--mono);
  font-size: var(--fs-label);
  letter-spacing: .13em;
  text-transform: uppercase;
  color: #5b6373;
  max-width: none;
}

.rate-foot {
  margin-top: clamp(var(--s-5), 3.5vw, var(--s-6));
  font-size: var(--fs-sm);
  line-height: 1.6;
  color: #5b6373;
  max-width: 64ch;
}

@media (max-width: 1040px) {
  .tier { grid-template-columns: minmax(0, 15rem) minmax(0, 1fr); }
  .tier-act { grid-column: 2; flex-direction: row; align-items: center; flex-wrap: wrap; gap: 1rem; }
  .tier-act .btn { width: auto; }
}
@media (max-width: 680px) {
  .tier { grid-template-columns: 1fr; gap: 1.3rem; }
  .tier-act { grid-column: 1; }
}

/* ══════════ 09 · TURNAROUND — the wait, drawn to scale ══════════
   Three bars at true proportion: three days really is a seventh of
   three weeks, and it reads as a seventh. */

.speed { background: var(--ink); padding: var(--py) var(--px); }

.lanes { list-style: none; }

.lane {
  display: grid;
  grid-template-columns: minmax(0, 13rem) minmax(0, 1fr) minmax(0, 7rem);
  gap: clamp(var(--s-3), 2.5vw, var(--s-6));
  align-items: center;
  padding: clamp(var(--s-5), 3vw, var(--s-6)) var(--bleed);
  margin-inline: calc(var(--bleed) * -1);
  border-bottom: 1px solid var(--hair);
}
.lane:last-child { border-bottom: 0; }

.lane-name {
  font-size: var(--fs-name);
  letter-spacing: .025em;
  line-height: 1.05;
  color: var(--bone);
  max-width: none;
}
.lane-sub {
  display: block;
  margin-top: .42rem;
  font-family: var(--mono);
  font-size: var(--fs-label);
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--slate);
}

.lane-track {
  position: relative;
  height: 12px;
  background: rgba(242, 239, 232, .07);
  border-radius: 99px;
  overflow: hidden;
}
.lane-bar {
  position: absolute;
  inset: 0 auto 0 0;
  width: var(--w);
  background: linear-gradient(90deg, color-mix(in srgb, var(--gold) 55%, transparent), var(--gold));
  border-radius: 99px;
  transform-origin: left center;
}

.lane-days {
  font-size: clamp(1.5rem, 3.2vw, 2.4rem);
  line-height: .9;
  letter-spacing: 0;
  color: var(--gold);
  font-variant-numeric: tabular-nums;
  text-align: right;
  max-width: none;
}
.lane-days small {
  display: block;
  margin-top: .38rem;
  font-family: var(--mono);
  font-size: var(--fs-label);
  letter-spacing: .16em;
  color: var(--slate);
}

.speed-note {
  margin-top: clamp(var(--s-6), 4vw, var(--s-7));
  font-size: clamp(1.15rem, 2.2vw, 1.6rem);
  line-height: 1.36;
  font-weight: 300;
  color: var(--bone-dim);
  max-width: 44ch;
}
.speed-note em { color: var(--bone); font-style: italic; }

@media (max-width: 760px) {
  .lane { grid-template-columns: minmax(0, 1fr) minmax(0, 5rem); gap: .7rem 1.2rem; }
  .lane-track { grid-column: 1 / -1; order: 3; }
  .lane-days { font-size: 1.5rem; }
}

/* ══════════ MOTION — one authored entrance per section ══════════ */

.rise { opacity: 0; transform: translateY(24px); animation: rise .95s var(--ease) forwards; }
.d1 { animation-delay: .07s; } .d2 { animation-delay: .15s; }
.d3 { animation-delay: .34s; } .d4 { animation-delay: .48s; } .d5 { animation-delay: .6s; }
@keyframes rise { to { opacity: 1; transform: none; } }

.js [data-motion] .mast {
  opacity: 0; transform: translateY(16px);
  transition: opacity .7s var(--ease), transform .7s var(--ease);
}
.js [data-motion].seen .mast { opacity: 1; transform: none; }

/* 01 — the mockups develop like contact prints */
.js .problem .tell { opacity: 0; transition: opacity .8s var(--ease); }
.js .problem .slop { transform: scale(.93); filter: saturate(0) blur(3px); transition: transform .9s var(--ease), filter .9s var(--ease); }
.js .problem .problem-turn { opacity: 0; transform: translateY(14px); transition: opacity .7s var(--ease), transform .7s var(--ease); }
.js .problem.seen .tell { opacity: 1; }
.js .problem.seen .slop { transform: none; filter: saturate(.6) blur(0); }
.js .problem.seen .tell:nth-child(1), .js .problem.seen .tell:nth-child(1) .slop { transition-delay: .1s; }
.js .problem.seen .tell:nth-child(2), .js .problem.seen .tell:nth-child(2) .slop { transition-delay: .22s; }
.js .problem.seen .tell:nth-child(3), .js .problem.seen .tell:nth-child(3) .slop { transition-delay: .34s; }
.js .problem.seen .problem-turn { opacity: 1; transform: none; transition-delay: .5s; }

/* 02–05 — writing and evidence arrive from their own sides */
.js .case .case-copy { opacity: 0; transform: translateX(-22px); transition: opacity .8s var(--ease), transform .8s var(--ease); }
.js .case .case-shots { opacity: 0; transform: translateY(26px); transition: opacity .9s var(--ease) .12s, transform .9s var(--ease) .12s; }
.js .case-flip .case-copy { transform: translateX(22px); }
.js .case.seen .case-copy, .js .case.seen .case-shots { opacity: 1; transform: none; }

/* the range — four palettes wipe up like swatches */
.js .range .band { clip-path: inset(100% 0 0 0); transition: clip-path 1s var(--ease); }
.js .range.seen .band { clip-path: inset(0 0 0 0); }
.js .range.seen .band:nth-child(2) { transition-delay: .12s; }
.js .range.seen .band:nth-child(3) { transition-delay: .24s; }
.js .range.seen .band:nth-child(4) { transition-delay: .36s; }
.js .range.seen .band:nth-child(5) { transition-delay: .48s; }
.js .range .range-say { opacity: 0; transform: translateY(16px); transition: opacity .8s var(--ease) .45s, transform .8s var(--ease) .45s; }
.js .range.seen .range-say { opacity: 1; transform: none; }

/* 06 — the index lists itself */
.js .services .idx { opacity: 0; transform: translateX(-18px); transition: opacity .6s var(--ease), transform .6s var(--ease); }
.js .services.seen .idx { opacity: 1; transform: none; }
.js .services.seen .idx:nth-child(1) { transition-delay: .04s; }
.js .services.seen .idx:nth-child(2) { transition-delay: .1s; }
.js .services.seen .idx:nth-child(3) { transition-delay: .16s; }
.js .services.seen .idx:nth-child(4) { transition-delay: .22s; }
.js .services.seen .idx:nth-child(5) { transition-delay: .28s; }
.js .services.seen .idx:nth-child(6) { transition-delay: .34s; }

/* 07 — the staircase climbs */
.js .process .step { opacity: 0; transform: translate(-26px, 10px); transition: opacity .7s var(--ease), transform .7s var(--ease); }
.js .process.seen .step { opacity: 1; transform: none; }
.js .process.seen .step:nth-child(2) { transition-delay: .14s; }
.js .process.seen .step:nth-child(3) { transition-delay: .28s; }

/* the quote arrives slowly, on its own */
.js .quote figure { opacity: 0; filter: blur(6px); transition: opacity 1.1s ease, filter 1.1s var(--ease); }
.js .quote.seen figure { opacity: 1; filter: blur(0); }

/* 08 — contact */
.js .contact .contact-copy > *:not(.mast),
.js .contact .contact-form { opacity: 0; transform: translateY(18px); transition: opacity .7s var(--ease), transform .7s var(--ease); }
.js .contact.seen .contact-copy > *:not(.mast) { opacity: 1; transform: none; }
.js .contact.seen .contact-form { opacity: 1; transform: none; transition-delay: .14s; }

/* advertising — each format develops, then its copy arrives */
.js .ads .ads-lead { opacity: 0; transition: opacity .7s ease; }
.js .ads.seen .ads-lead { opacity: 1; }
.js .ads .moment { opacity: 0; transform: translateY(18px); transition: opacity .7s var(--ease), transform .7s var(--ease); }
.js .ads.seen .moment { opacity: 1; transform: none; }
.js .ads.seen .moment:nth-child(2) { transition-delay: .12s; }
.js .ads.seen .moment:nth-child(3) { transition-delay: .24s; }
.js .ads .admock { filter: saturate(0); transition: filter .9s var(--ease) .15s; }
.js .ads.seen .admock { filter: saturate(1); }
.js .ads .ads-ledger { opacity: 0; transition: opacity .7s ease .38s; }
.js .ads.seen .ads-ledger { opacity: 1; }

/* the rate card rules itself off, row by row */
.js .rates .tier { opacity: 0; transform: translateY(20px); transition: opacity .7s var(--ease), transform .7s var(--ease); }
.js .rates.seen .tier { opacity: 1; transform: none; }
.js .rates.seen .tier:nth-child(2) { transition-delay: .13s; }
.js .rates.seen .tier:nth-child(3) { transition-delay: .26s; }
.js .rates .rate-foot { opacity: 0; transition: opacity .7s ease .42s; }
.js .rates.seen .rate-foot { opacity: 1; }

/* 09 — the bars run out to their true length */
.js .speed .lane-bar { transform: scaleX(0); transition: transform 1.1s var(--ease); }
.js .speed.seen .lane-bar { transform: scaleX(1); }
.js .speed.seen .lane:nth-child(2) .lane-bar { transition-delay: .16s; }
.js .speed.seen .lane:nth-child(3) .lane-bar { transition-delay: .32s; }
.js .speed .lane-name, .js .speed .lane-days { opacity: 0; transition: opacity .6s ease; }
.js .speed.seen .lane-name, .js .speed.seen .lane-days { opacity: 1; }
.js .speed .speed-note { opacity: 0; transform: translateY(14px); transition: opacity .8s var(--ease) .5s, transform .8s var(--ease) .5s; }
.js .speed.seen .speed-note { opacity: 1; transform: none; }

/* every section's closing call to action */
.js [data-motion] .section-cta { opacity: 0; transform: translateY(14px); transition: opacity .7s var(--ease) .3s, transform .7s var(--ease) .3s; }
.js [data-motion].seen .section-cta { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  .scroll-rail i { transition: none; }
  .rise { animation: none; opacity: 1; transform: none; }
  .stage-shot, .hero-wash, .meter-ticks span, .swap { transition: none; }
  .shot-scroll img { transition: none; }
  .frame:hover .shot-scroll img,
  .frame:focus-within .shot-scroll img { transform: none; }
  .btn, .btn-ghost, .arr, .case-cta { transition: none; }

  /* Suppress the hover *movement*, not the hover. Killing only the
     transition would leave the element jumping to its hovered position
     with no travel, which is worse than either option. Colour, border and
     background feedback all stay. */
  .btn:hover,
  .case-cta:hover .arr, .foot-link:hover .arr, .btn-ghost:hover .arr,
  .idx:hover .idx-name { transform: none; }
  .js [data-motion] .mast,
  .js .problem .tell, .js .problem .slop, .js .problem .problem-turn,
  .js .case .case-copy, .js .case .case-shots,
  .js .range .band, .js .range .range-say,
  .js .ads .ads-lead, .js .ads .moment, .js .ads .admock, .js .ads .ads-ledger,
  .js .services .idx,
  .js .process .step,
  .js .quote figure,
  .js .rates .tier, .js .rates .rate-foot,
  .js .speed .lane-bar, .js .speed .lane-name, .js .speed .lane-days, .js .speed .speed-note,
  .js [data-motion] .section-cta,
  .js .contact .contact-copy > *, .js .contact .contact-form {
    opacity: 1 !important;
    transform: none !important;
    filter: none !important;
    clip-path: none !important;
    transition: none !important;
  }
}

/* ── Lenis ────────────────────────────────────────────────────
   The library's own stylesheet, inlined. Only the rules that apply to how
   this site uses it; the autoToggle transition is left out because that
   feature is off. `height: auto` is the load-bearing one - Lenis measures
   the document, and a percentage height on html/body would fight it. */
html.lenis, html.lenis body { height: auto; }
.lenis:not(.lenis-autoToggle).lenis-stopped { overflow: clip; }
.lenis [data-lenis-prevent] { overscroll-behavior: contain; }
.lenis.lenis-smooth iframe { pointer-events: none; }

/* ── the package popup ──────────────────────────────────────
   A <dialog>, not a div. showModal() gives the focus trap, the Escape
   key, inert background content and top-layer stacking for free — four
   things that are easy to get subtly wrong by hand, and that decide
   whether this is usable with a keyboard or a screen reader.

   Sized for a phone first. The panel is capped by viewport height and
   scrolls internally, because a keyboard opening on a small screen can
   leave under 300px of usable height and the send button must stay
   reachable. */

html.pkg-open { overflow: hidden; }

.pkg {
  border: 0;
  padding: 0;
  background: none;
  max-width: none;
  max-height: none;
  width: 100%;
  height: 100%;
  margin: 0;
  display: none;
  overflow: hidden;
}
.pkg[open] {
  display: grid;
  place-items: center;
  padding: clamp(.75rem, 4vw, 2rem);
}
.pkg::backdrop {
  background: rgba(6, 7, 10, .76);
}

.pkg-panel {
  position: relative;
  width: min(30rem, 100%);
  max-height: calc(100dvh - clamp(1.5rem, 8vw, 4rem));
  overflow-y: auto;
  overscroll-behavior: contain;
  background: var(--ink-2);
  border: 1px solid var(--hair);
  color: var(--bone);
  padding: clamp(1.5rem, 5vw, 2.4rem);
  text-align: left;
}

/* 44px of target, sitting in the corner without crowding the heading. */
.pkg-x {
  position: absolute;
  top: .35rem;
  right: .35rem;
  width: 2.75rem;
  height: 2.75rem;
  display: grid;
  place-items: center;
  appearance: none;
  background: none;
  border: 0;
  color: var(--slate);
  font-size: 1.6rem;
  line-height: 1;
  cursor: pointer;
  transition: color var(--t-hover) ease;
}
.pkg-x:hover { color: var(--bone); }

.pkg-kind {
  font-family: var(--mono);
  font-size: var(--fs-label);
  letter-spacing: .15em;
  text-transform: uppercase;
  color: var(--slate);
}
.pkg-title {
  margin-top: .3rem;
  font-size: clamp(1.5rem, 1rem + 2vw, 2.1rem);
  line-height: 1.05;
  padding-right: 2.5rem;   /* clear of the close button */
}
.pkg-price {
  margin-top: .45rem;
  font-family: var(--mono);
  font-size: var(--fs-label);
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--gold);
}

.pkg-form {
  margin-top: clamp(1.2rem, 4vw, 1.7rem);
  padding-top: clamp(1.2rem, 4vw, 1.7rem);
  border-top: 1px solid var(--hair);
  display: grid;
  gap: .85rem;
}
.pkg-form label {
  display: grid;
  gap: .34rem;
  font-family: var(--mono);
  font-size: var(--fs-label);
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--slate);
}
.pkg-form input {
  width: 100%;
  font: inherit;
  font-family: var(--serif);
  font-size: 1rem;           /* 16px — anything smaller makes iOS zoom in */
  letter-spacing: normal;
  text-transform: none;
  color: var(--bone);
  background: var(--ink);
  /* WCAG 1.4.11: an input's boundary is a UI component and needs 3:1.
     The divider hairline is nowhere near that. */
  border: 1px solid var(--field-edge, rgba(242, 239, 232, .34));
  border-radius: 0;
  padding: .72rem .8rem;
  transition: border-color var(--t-hover) ease;
}
.pkg-form input:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-color: transparent;
}
.pkg-form button[type="submit"] { margin-top: .5rem; width: 100%; }
.pkg-form button[disabled] { opacity: .6; cursor: default; }

.pkg-note,
.pkg-alt {
  margin-top: .85rem;
  font-size: clamp(.86rem, .7rem + .2vw, .95rem);
  line-height: 1.5;
  color: var(--slate);
}
.pkg-alt { margin-top: 1.1rem; padding-top: 1.1rem; border-top: 1px solid var(--hair); }
.pkg-alt a { color: var(--bone); text-decoration: underline; text-underline-offset: 3px; }
.pkg-alt a:hover { color: var(--gold); }

.pkg-done { margin-top: clamp(1.2rem, 4vw, 1.7rem); padding-top: clamp(1.2rem, 4vw, 1.7rem); border-top: 1px solid var(--hair); }
.pkg-done h3 { font-size: clamp(1.3rem, 1rem + 1.2vw, 1.7rem); }
.pkg-done h3:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; }
.pkg-done p { margin-top: .7rem; font-size: clamp(.95rem, .8rem + .3vw, 1.05rem); line-height: 1.55; color: var(--bone-dim); }
.pkg-done-next { color: var(--slate); }
.pkg-done-next a { color: var(--bone); text-decoration: underline; text-underline-offset: 3px; }

/* The panel arrives rather than appearing. Suppressed where the reader
   has asked for less movement — the popup still opens, just without the
   travel. */
@media (prefers-reduced-motion: no-preference) {
  .pkg[open] .pkg-panel { animation: pkg-in .26s var(--ease-ui) both; }
  @keyframes pkg-in {
    from { opacity: 0; transform: translateY(12px) scale(.985); }
    to   { opacity: 1; transform: none; }
  }
}
