/* ════════════════════════════════════════════════════════════════════════
   css/reference.css — THE FIVE REFERENCE PAGES
   service.tnaado.ca · Tier 2, no storm
   /pricing · /faq · /stack · /consulting · /strategy-publicity

   ONE SHEET FOR FIVE PAGES, because they share a ground, a rail, a type
   scale, a chrome offset and one closing CTA, and five copies of those is
   how the old site's twenty pages drifted until no two eyebrows matched.
   /pricing additionally loads css/reference-pricing.css, which holds the
   figure tables nothing else on the site needs. Nothing in either file
   touches css/chrome.css — that sheet is linked, never overridden, with the
   one additive exception marked below.

   NO STORM. Storms are Tier 1. These five are reference surfaces: a stranger
   arriving from a search result or an ad needs the answer, not a wait.

   COLOUR, LOCKED AND MEASURED against the ink ground #0a0a0a:
       --bone     #f5f1e8   17.4:1   body copy
       --bone-2   #ebe5d8   15.9:1   italic display, emphasis
       --dim-ink  #b9b3a6    9.4:1   secondary copy, mono metadata
       --red-ink  #ef5c6e    6.06:1  the ONLY small red text on ink
       --red      #c8102e    3.37:1  BANNED as small text. Rules, fills and
                                     display type at 24px and over, only.
   On the bone ground #f5f1e8:
       --ink      #0a0a0a   17.4:1   body copy
       --ink-2    #3a3630    9.6:1   secondary copy
       --red-bone #a4132c    6.6:1   the ONLY small red text on bone
   There is no rgba(bone, .4x) anywhere in this file. That value is 3.77:1
   and it is the thing css/chrome.css was written to stop reproducing.

   FIGURES. Every column of numbers carries font-variant-numeric:
   tabular-nums. /pricing is almost entirely columns of numbers, so the
   property is set on the mono face itself and on every cell that holds one,
   rather than being remembered per table.

   DEGRADATION. Everything in this file paints with no JavaScript. None of
   the five pages loads page script of its own; the only script served is
   js/chrome.js, and css/chrome.css already guarantees that with it absent
   the chrome is a bar, a full open navigation tree and a footer in flow.
   No answer, figure, table row or list item on any of the five is hidden
   behind an interaction — /faq's whole design rests on that (see the
   FAQ section below).
   ════════════════════════════════════════════════════════════════════════ */

:root {
  --ink:       #0a0a0a;
  --plate:     #0d0d0d;
  --plate-2:   #131313;
  --bone:      #f5f1e8;
  --bone-2:    #ebe5d8;
  --ink-2:     #3a3630;   /* 9.6:1 on bone  */
  --red:       #c8102e;
  --red-ink:   #ef5c6e;   /* 6.06:1 on ink  — the only small red on ink  */
  --red-bone:  #a4132c;   /* 6.6:1  on bone — the only small red on bone */
  --dim-ink:   #b9b3a6;   /* 9.4:1  on ink  */
  --hair-ink:  rgba(245, 241, 232, .14);
  --hair-bone: rgba(10, 10, 10, .16);

  --serif: 'Fraunces', 'Times New Roman', Times, serif;
  --sans:  'IBM Plex Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
  --mono:  'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace;

  /* The site's shared rail, same 1136px as css/work.css, so a reader moving
     between a portfolio page and a price page does not see the column jump. */
  --rail: 1136px;
  --gut:  clamp(1.25rem, 4vw, 3rem);

  /* THE READING MEASURE, AND THE WIDTH EVERY RULE THAT BELONGS TO PROSE STOPS
     AT. Added 2026-08-21 after Ethan reported /pricing as "borken alignment and
     things arent matching", and the render confirmed it: at 1440 the answer
     copy wrapped at x=851 while the hairline under it ran to x=1240 — a rule
     extending 389px past the text it underlines, on every one of the eight
     answers. MEASURED, not guessed: the widest line box in the .qa blocks was
     708px and the median was 665px.

     The container was too wide for the measure, not the other way round: 68ch
     is a correct measure for prose and widening the copy to 1040px to meet the
     rule would have made the page harder to read to fix how it looked. So the
     RULES come in to the measure instead.

     44rem = 704px, which clears the widest measured line and sits inside the
     1040px rail. It is a rem rather than a ch because the blocks it governs mix
     1rem body copy, .9375rem notes and 1.75rem questions, and `ch` would
     resolve to a different width in each of them — which is how three
     "68ch" blocks end up three different widths. */
  --measure: 44rem;

  /* THE CHROME OFFSET. ONE OWNER, and it is this variable.

     It was two. css/chrome.css sets scroll-padding-top on the root AND this
     sheet set scroll-margin-top on every target, and the two ADD: measured at
     1440 an anchor landed 189px down the viewport (116 + 73) for a slab that is
     only 53px tall. 136px of nothing above every linked answer, a fifth of a
     phone screen. The root property is switched off below so this is the only
     offset in play.

     WHY IT IS NOT 53px ANY MORE. It was, as a hand-counted constant, and the
     count was right only by accident: these five pages omit the bypass row, so
     their fixed slab is the menu bar alone. css/chrome.css already publishes
     the real height as --chrome-bar-h (100px desktop, 92px at 860 and under,
     both MEASURED by the /work/camera build), so this reads that rather than
     restating it, and cannot go stale if a reference page ever gains a row.
     The fallbacks match chrome.css's own values for the no-JS case, where
     nothing is fixed and no offset is needed anyway.

     The extra 2.5rem is not padding for looks. A fresh load at #a-small-business
     measured 128px rather than the 189px the same jump gives once settled: the
     browser scrolls before the web fonts arrive and the reflow drags the target
     up by as much as 61px. The clearance has to survive that or the heading it
     was pointing at ends up under the bar, which is exactly what Ethan saw. */
  --chrome-h: 6.25rem;

  --ease: cubic-bezier(.22, 1, .36, 1);
}
@media (max-width: 860px) { :root { --chrome-h: 5.75rem; } }
html.chrome-live { --chrome-h: var(--chrome-bar-h, 6.25rem); }

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

/* Page-local visually-hidden. css/chrome.css scopes its .u-vh to .chrome and
   .chrome-foot, so the class used anywhere else gets no rule and the text
   renders on screen. */
.u-vh {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap;
}

html {
  overflow-x: clip;
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  background: var(--ink);
  color: var(--bone);
  font-family: var(--sans);
  font-size: 1rem;
  font-weight: 400;
  line-height: 1.62;
  -webkit-font-smoothing: antialiased;
}
/* Body padding for the fixed slab is owned by css/chrome.css
   (html.chrome-live:not(.sc-live) body { padding-top: var(--chrome-bar-h) }).
   This sheet used to restate it as `html.chrome-live body { padding-top:
   var(--bar) }`, which never applied — chrome.css's selector is one class more
   specific and loads second — so it was a dead rule that read like a decision.
   Removed rather than made to win: one owner for one measurement. */

img { max-width: 100%; display: block; }

/* The one chrome rule these pages add, and it is purely additive: with no
   bypass row beneath it the fixed bar has no lower edge, because css/chrome.css
   draws that edge on .bypass. There is no storm on a reference page — a
   five-beat row pointing at #who and #examples would be five broken anchors —
   so the edge is drawn here instead. Nothing is overridden. */
html.chrome-live .menubar { border-bottom: 1px solid var(--hair-ink); }

/* ══ ANCHORS ═════════════════════════════════════════════════════════════
   Every in-page target on these pages — and /faq is nothing but in-page
   targets — must come to rest below the fixed bar, or a linked answer lands
   with its own question hidden underneath the chrome. scroll-margin-top on
   the target itself, not scroll-padding on the root, because the root
   property is ignored by an anchor navigation that happens before layout
   settles in Safari, and because a per-target margin also fixes a
   :target landing from a pasted URL. Only applied while the bar is fixed.

   The root property is switched OFF for these pages so the two mechanisms stop
   adding — see --chrome-h above for the 189px measurement that found it. The
   doubled class is how this sheet wins a specificity fight it would otherwise
   lose on source order: css/chrome.css is linked after it and its selector is
   html.chrome-live:not(.sc-live), so one repeated class is the smallest thing
   that outranks it without inventing an attribute to hang the rule on. */
html.chrome-live.chrome-live:not(.sc-live) { scroll-padding-top: 0; }
html.chrome-live :target,
html.chrome-live [id] { scroll-margin-top: calc(var(--chrome-h) + 2.5rem); }

/* ── RAIL, BANDS ───────────────────────────────────────────────────────── */
.rail { width: 100%; max-width: var(--rail); margin: 0 auto; padding: 0 var(--gut); }
.rail--narrow { max-width: 62rem; }
.measure { max-width: var(--measure); }

/* ══ ONE MEASURE ═════════════════════════════════════════════════════════
   Everything that is a block of prose, or a hairline belonging to one, stops
   at --measure. Before this there were six measures on these pages — 62ch,
   64ch, 66ch, 68ch, 72ch and 76ch — each resolving against its own font size,
   so no two blocks on /pricing lined up and the rules lined up with none of
   them. That is the "things arent matching" fault, and it is a fault of having
   six answers to one question rather than of any one of the six being wrong.

   NOT included, deliberately: .qa__q at 40ch and .close h2 at 32ch. Those are
   display type, where a shorter line is the point, and they sit inside a block
   that is already at the measure. The tables, the ledgers, the tier grids and
   the card grids are NOT prose and keep the full rail: a price column is meant
   to run the width of the page.

   The token is applied at each declaration below rather than as one group rule
   here, because css/reference-pricing.css loads second and a group rule at the
   top of this file loses to any later `max-width` on the same selector — which
   is how a page ends up with a measure that is set in two places and obeys
   neither. Search this file and that one for --measure to see the full set. */

.band { position: relative; padding: clamp(2.25rem, 4.6vw, 4rem) 0; }
.band + .band { border-top: 1px solid var(--hair-ink); }
.band--tight { padding-block: clamp(1.75rem, 3.2vw, 2.75rem); }
.band--plate { background: var(--plate); }

/* ── EYEBROW ───────────────────────────────────────────────────────────── */
/* The live site's idiom: a short red rule, a mono numeral, a label. Kept so a
   reader who learns one section header can read every section header. */
.eyebrow {
  display: flex; align-items: center; gap: .75rem; flex-wrap: wrap;
  margin: 0 0 1.1rem;
  font-family: var(--mono); font-size: .75rem; font-weight: 500;
  letter-spacing: .16em; text-transform: uppercase; color: var(--dim-ink);
}
.eyebrow__rule { display: block; width: 2.25rem; height: 2px; background: var(--red); flex: 0 0 auto; }
.eyebrow__num  { color: var(--red-ink); }

/* ── TYPE ──────────────────────────────────────────────────────────────── */
/* Fraunces is requested with the ital, opsz and wght axes only (the same
   Google Fonts URL committed index.html uses), so opsz is left to
   font-optical-sizing: auto and no font-variation-settings are declared —
   naming an axis the served font does not carry is a silent no-op that reads
   like an intention. */
h1, h2, h3, h4 {
  font-family: var(--serif); font-weight: 400; margin: 0; line-height: 1.04;
}
/* SCALE CORRECTION. These were clamp(2.375,6.6vw,4.25) / (1.75,4vw,2.625) /
   (1.25,2.3vw,1.625) — a 68px headline ceiling against 15px body copy. Measured
   on /contact it rendered h1 56px, and everything else on the site had been
   sized to sit beside it. Ethan: "its like youre treating the reader as a
   todler". The ceiling comes down about 16%, the floor barely moves (a small
   screen was never the problem), so the type gets tighter as the viewport grows
   rather than louder. */
h1 { font-size: clamp(2.25rem, 5.2vw, 3.5rem); letter-spacing: -.018em; }
h2 { font-size: clamp(1.625rem, 3.1vw, 2.125rem); letter-spacing: -.012em; }
h3 { font-size: clamp(1.1875rem, 1.9vw, 1.4375rem); letter-spacing: -.008em; }
h4 { font-size: clamp(1.0625rem, 1.6vw, 1.1875rem); line-height: 1.28; }
h1 em, h2 em, h3 em { font-style: italic; color: var(--bone-2); }

.lede {
  margin: 1.15rem 0 0; max-width: var(--measure);
  font-size: clamp(1.0625rem, 1.5vw, 1.1875rem); line-height: 1.6;
  color: var(--bone);
}
.copy { margin: 1.1rem 0 0; max-width: var(--measure); }
.copy--dim { color: var(--dim-ink); }
.note {
  margin: 1rem 0 0; max-width: var(--measure);
  color: var(--dim-ink); font-size: .9375rem; line-height: 1.66;
}
p:last-child { margin-bottom: 0; }

/* Inline links in running copy: underlined, because colour alone is not a
   signal and --red at small size is not available to us. */
.copy a, .lede a, .note a, .qa__a a, .sep__body a {
  color: var(--bone); text-decoration: underline;
  text-decoration-color: var(--red); text-decoration-thickness: 1px;
  text-underline-offset: .18em;
}
.copy a:hover, .lede a:hover, .note a:hover, .qa__a a:hover, .sep__body a:hover {
  text-decoration-color: var(--red-ink);
}

strong, b { font-weight: 600; color: var(--bone); }

/* ── FOCUS ─────────────────────────────────────────────────────────────── */
/* One visible ring for the whole page, matching css/chrome.css's, so the ring
   does not change appearance as focus crosses out of the bar and into the
   document. */
:focus-visible { outline: 2px solid var(--red-ink); outline-offset: 3px; }
.on-bone :focus-visible { outline-color: var(--red-bone); }

/* ── BREADCRUMB ────────────────────────────────────────────────────────── */
.crumb {
  display: flex; flex-wrap: wrap; align-items: center; gap: .5rem;
  list-style: none; margin: 0 0 1.5rem; padding: 0;
  font-family: var(--mono); font-size: .75rem; letter-spacing: .1em;
  text-transform: uppercase; color: var(--dim-ink);
}
.crumb li + li::before { content: '/'; margin-right: .5rem; color: var(--red-ink); }
.crumb a { color: var(--dim-ink); text-decoration: none; }
.crumb a:hover { color: var(--bone); }
.crumb [aria-current] { color: var(--bone); }

/* ── PAGE HEAD ─────────────────────────────────────────────────────────── */
.refhead { padding: clamp(1.9rem, 4vw, 3.25rem) 0 clamp(1.6rem, 3.2vw, 2.5rem); }
.refhead h1 { margin-top: .25rem; }

/* A short mono strip under an h1 that states what the page is, in facts. */
.stamp {
  display: flex; flex-wrap: wrap; gap: .5rem 1.5rem;
  margin: 1.75rem 0 0; padding: .9rem 0 0; max-width: var(--measure);
  border-top: 1px solid var(--hair-ink);
  font-family: var(--mono); font-variant-numeric: tabular-nums;
  font-size: .8125rem; color: var(--dim-ink);
}
.stamp b { color: var(--bone); font-weight: 500; }

/* ── DERIVATION ────────────────────────────────────────────────────────── */
/* A number with its arithmetic attached. Mono, so a derivation reads as a
   calculation rather than as a claim. Every count printed on these pages
   arrives with one of these: Ethan has thrown out "RANDOM STATS NO ONE CARES
   ABOUT", and a count you can check is not a statistic. */
.deriv {
  margin: 1.5rem 0 0; padding: .9rem 0 0;
  border-top: 1px solid var(--hair-ink);
  font-family: var(--mono); font-variant-numeric: tabular-nums;
  font-size: .8125rem; line-height: 1.85; color: var(--dim-ink); max-width: var(--measure);
}
.deriv b { color: var(--bone); font-weight: 500; }
.deriv .op { color: var(--red-ink); }

/* ── CONTENTS / JUMP LIST ──────────────────────────────────────────────── */
/* A plain list of in-page links. Not sticky, not a scrollspy: no page script
   runs on these five, and a contents list that needs JavaScript to say where
   you are is a contents list that says nothing on a slow phone. */
.jump { margin: 0; padding: 0; list-style: none; }
.jump {
  display: grid; gap: 1px;
  grid-template-columns: repeat(auto-fit, minmax(min(15rem, 100%), 1fr));
  background: var(--hair-ink); border: 1px solid var(--hair-ink);
}
.jump a {
  display: block; height: 100%; padding: .95rem 1.1rem;
  background: var(--plate); text-decoration: none; color: var(--bone);
}
.jump a:hover { background: var(--plate-2); }
.jump i {
  display: block; font-style: normal;
  font-family: var(--mono); font-size: .6875rem; letter-spacing: .16em;
  text-transform: uppercase; color: var(--red-ink); margin-bottom: .3rem;
}
.jump span { display: block; font-size: .9375rem; color: var(--dim-ink); }
.jump b { font-weight: 500; }

/* ── CARDS ─────────────────────────────────────────────────────────────── */
.grid {
  display: grid; gap: 1px; margin: 2rem 0 0;
  grid-template-columns: repeat(auto-fit, minmax(min(17rem, 100%), 1fr));
  background: var(--hair-ink); border: 1px solid var(--hair-ink);
}
.grid--2 { grid-template-columns: repeat(auto-fit, minmax(min(21rem, 100%), 1fr)); }
.card {
  background: var(--plate); padding: clamp(1.25rem, 2.4vw, 1.75rem);
  display: flex; flex-direction: column; gap: .6rem;
}
.card__kicker {
  margin: 0; font-family: var(--mono); font-size: .6875rem; font-weight: 500;
  letter-spacing: .16em; text-transform: uppercase; color: var(--red-ink);
}
.card h3, .card h4 { margin: 0; }
.card p { margin: 0; color: var(--dim-ink); font-size: .9375rem; }
.card p.card__lead { color: var(--bone); font-size: 1rem; }

/* ── LINE LIST ─────────────────────────────────────────────────────────── */
/* What a capability actually delivers, one line each. A list, because it is a
   list — never a set of cards, which would give five deliverables the visual
   weight of five products. */
.lines { list-style: none; margin: 1rem 0 0; padding: 0; }
.lines li {
  position: relative; padding: .6rem 0 .6rem 1.5rem;
  border-top: 1px solid var(--hair-ink);
  font-size: .9375rem; color: var(--bone);
}
.lines li::before {
  content: ''; position: absolute; left: 0; top: 1.15rem;
  width: .5rem; height: 2px; background: var(--red);
}

/* ── CAPABILITY BLOCK ──────────────────────────────────────────────────── */
/* Used by /consulting and /strategy-publicity: a numbered heading, one line
   of what it is, one line of how it runs, then the deliverables. Everything
   visible. The old pages put the deliverables behind a <details> toggle; on a
   page whose whole job is to say what you get, hiding what you get is the one
   thing it must not do. */
.cap { border-top: 1px solid var(--hair-ink); padding: clamp(1.25rem, 2.6vw, 1.75rem) 0; }
.cap:last-of-type { border-bottom: 1px solid var(--hair-ink); }
.cap__grid {
  display: grid; gap: clamp(1.25rem, 3vw, 2.5rem);
  grid-template-columns: 1fr;
}
@media (min-width: 62rem) { .cap__grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); } }
.cap__n {
  display: block; margin: 0 0 .55rem;
  font-family: var(--mono); font-variant-numeric: tabular-nums;
  font-size: .75rem; font-weight: 500; letter-spacing: .16em;
  text-transform: uppercase; color: var(--red-ink);
}
.cap h3 { margin: 0; }
.cap__what { margin: .85rem 0 0; max-width: 46ch; color: var(--bone); }
.cap__how  { margin: .85rem 0 0; max-width: 46ch; color: var(--dim-ink); font-size: .9375rem; }
.cap__count {
  margin: 0 0 .35rem;
  font-family: var(--mono); font-variant-numeric: tabular-nums;
  font-size: .75rem; letter-spacing: .14em; text-transform: uppercase;
  color: var(--dim-ink);
}
.cap__count b { color: var(--bone); font-weight: 500; }

/* ── FAQ LEDGER ────────────────────────────────────────────────────────── */
/* NO ACCORDION, AND THERE NEVER WILL BE ONE, and this is not a style choice.
   The FAQPage structured data on /faq states answer text that Google requires
   to be visible without an interaction, so a disclosure widget would make the
   rich result a misrepresentation of the page. Second reason, just as binding:
   a prospect two hours from a meeting has to be able to Cmd-F this page and
   land on the sentence. Every answer is open, always, and each question owns a
   real id so it can be linked to directly.

   A ledger, not cards: eight questions in eight boxes reads as eight products.
   A hairline between rows and one measure down the page reads as a document,
   which is what a reader with a question wants. */
.qagroup { border-top: 1px solid var(--hair-ink); padding-top: clamp(1.25rem, 2.6vw, 1.75rem); margin-top: clamp(1.25rem, 2.6vw, 1.75rem); max-width: var(--measure); }
.qagroup:first-of-type { border-top: 0; margin-top: 0; }
.qagroup__head { max-width: var(--measure); }
.qagroup__head h2 { margin: 0; }
.qagroup__head p { margin: .7rem 0 0; color: var(--dim-ink); font-size: .9375rem; }

/* THE RULE STOPS AT THE MEASURE. This border-top used to run the full 1040px
   rail while the answer under it wrapped at ~665px, so every answer block ended
   in 389px of hairline pointing at nothing. */
.qa { padding: clamp(1rem, 2.1vw, 1.375rem) 0; border-top: 1px solid var(--hair-ink); max-width: var(--measure); }
.qa:first-of-type { margin-top: clamp(1rem, 2.5vw, 1.75rem); }
.qa__n {
  display: block; margin: 0 0 .5rem;
  font-family: var(--mono); font-variant-numeric: tabular-nums;
  font-size: .75rem; font-weight: 500; letter-spacing: .16em;
  text-transform: uppercase; color: var(--red-ink);
}
.qa__q {
  font-family: var(--serif); font-weight: 400;
  font-size: clamp(1.1875rem, 1.9vw, 1.4375rem); line-height: 1.16;
  letter-spacing: -.01em; margin: 0; max-width: 40ch;
}
.qa__a { margin: 1rem 0 0; max-width: var(--measure); }
.qa__a > p { margin: 0 0 .85rem; }
.qa__a > p:last-child { margin-bottom: 0; }
/* The FIRST paragraph of every answer is the schema answer, character for
   character. It is set slightly larger so the direct answer is the thing the
   eye lands on, and so an editor can see at a glance which sentence is under
   contract. */
.qa__a > p:first-child { color: var(--bone); font-size: 1.0625rem; }
.qa__a > p + p { color: var(--dim-ink); font-size: .9375rem; }
.qa__a .lines li { color: var(--dim-ink); }
/* A permalink to one question. Visible on hover and on keyboard focus — never
   hover-only, which would make it unreachable by keyboard. */
.qa__link {
  display: inline-block; margin-left: .5rem;
  font-family: var(--mono); font-size: .75rem; color: var(--red-ink);
  text-decoration: none; opacity: 0; transition: opacity .18s var(--ease);
}
.qa:hover .qa__link, .qa__link:focus-visible { opacity: 1; }
@media (prefers-reduced-motion: reduce) { .qa__link { transition: none; } }

/* ── STACK GRID ────────────────────────────────────────────────────────── */
/* One cell per platform: the name, and one honest line on what it is for.
   auto-fit rather than a fixed column count, because the old page had 17 cells
   over 4 columns and left the last row with one filled cell and three empty
   ones. */
.stack {
  display: grid; gap: 1px; margin: 2rem 0 0;
  grid-template-columns: repeat(auto-fit, minmax(min(16rem, 100%), 1fr));
  background: var(--hair-ink); border: 1px solid var(--hair-ink);
}
.stack__cell { background: var(--plate); padding: 1.1rem 1.25rem 1.25rem; }
.stack__name {
  margin: 0; font-family: var(--sans); font-weight: 600; font-size: 1rem;
  letter-spacing: -.005em; color: var(--bone);
}
.stack__use { margin: .4rem 0 0; color: var(--dim-ink); font-size: .875rem; line-height: 1.55; }

/* THE FIELD. 175 marks, one per published tool, as a still CSS figure with no
   script behind it: the number gets a countable shape without the page loading
   a byte of JavaScript. Ethan, on the earlier version: "no scroll anaimtions
   not what i asked for." So it is complete on the first frame. */
.field {
  margin: 1.75rem 0 0; padding: 1.5rem;
  border: 1px solid var(--hair-ink); background: var(--plate);
}
.field__marks {
  --m: 6px; --g: 5px;
  display: grid; gap: var(--g);
  grid-template-columns: repeat(25, var(--m));
  justify-content: start;
}
.field__mark { width: var(--m); height: var(--m); background: var(--red); }
.field__mark--pale { background: rgba(200, 16, 46, .38); }
.field__legend {
  margin: 1.1rem 0 0; font-family: var(--mono); font-variant-numeric: tabular-nums;
  font-size: .75rem; letter-spacing: .06em; color: var(--dim-ink);
}
.field__legend b { color: var(--bone); font-weight: 500; }
@media (max-width: 34rem) {
  .field__marks { --m: 5px; --g: 4px; grid-template-columns: repeat(25, var(--m)); }
}

/* ── BUTTONS ───────────────────────────────────────────────────────────── */
.btns { display: flex; flex-wrap: wrap; gap: .75rem; margin: 1.75rem 0 0; align-items: center; }
.btn {
  display: inline-flex; align-items: center; gap: .55rem;
  padding: .85rem 1.35rem; text-decoration: none;
  font-family: var(--sans); font-size: .9375rem; font-weight: 600;
  letter-spacing: .01em; border: 1px solid transparent;
  transition: background .18s var(--ease), color .18s var(--ease);
}
.btn i { font-style: normal; }
.btn--go   { background: var(--bone); color: var(--ink); }
.btn--go:hover { background: #fff; }
.btn--ghost { border-color: var(--hair-ink); color: var(--bone); }
.btn--ghost:hover { background: var(--plate-2); border-color: rgba(245, 241, 232, .34); }
@media (prefers-reduced-motion: reduce) { .btn { transition: none; } }

/* The mailto beneath every CTA. /contact is the destination, but a reference
   page reached from an ad must never dead-end, so the address is in the served
   HTML under every button on every one of the five pages. */
.mailto {
  margin: .9rem 0 0;
  font-family: var(--mono); font-size: .8125rem; color: var(--dim-ink);
}
.mailto a {
  color: var(--bone); text-decoration: underline;
  text-decoration-color: var(--red); text-underline-offset: .18em;
}
.mailto a:hover { text-decoration-color: var(--red-ink); }

/* ── THE CLOSE ─────────────────────────────────────────────────────────── */
/* Every one of the five ends here. Same block, same order, on all five: what
   to send, the button, the address. A Tier 2 page ends in a booking. */
.close { border-top: 2px solid var(--red); background: var(--plate); }
.close__inner { padding: clamp(2rem, 4.2vw, 3.5rem) 0; }
.close h2 { max-width: 32ch; }
.close .lede { max-width: 58ch; }
.close__facts {
  display: grid; gap: 1px; margin: 2.25rem 0 0;
  grid-template-columns: repeat(auto-fit, minmax(min(16rem, 100%), 1fr));
  background: var(--hair-ink); border: 1px solid var(--hair-ink);
}
.close__fact { background: var(--ink); padding: 1.15rem 1.25rem; }
.close__fact h3 {
  margin: 0 0 .4rem; font-family: var(--mono); font-weight: 500;
  font-size: .6875rem; letter-spacing: .16em; text-transform: uppercase;
  color: var(--red-ink);
}
.close__fact p { margin: 0; color: var(--dim-ink); font-size: .875rem; }

/* ── BONE PANEL ────────────────────────────────────────────────────────── */
/* Inverted ground, used once per page at most. On /pricing it carries the
   editorial-separation section, which is required to be prominent — it is a
   selling point, not a disclaimer, and the strongest thing a plain reference
   page can do to make a section prominent is to stop being dark for it.
   Small red text inside here is --red-bone #a4132c (6.6:1); --red is used for
   the rules and for display type at 24px and over. */
.on-bone { background: var(--bone); color: var(--ink); }
.on-bone h1, .on-bone h2, .on-bone h3, .on-bone h4 { color: var(--ink); }
.on-bone h1 em, .on-bone h2 em, .on-bone h3 em { color: var(--ink-2); }
.on-bone .eyebrow { color: var(--ink-2); }
.on-bone .eyebrow__num { color: var(--red-bone); }
.on-bone .lede { color: var(--ink); }
.on-bone .copy, .on-bone p { color: var(--ink); }
.on-bone .note, .on-bone .copy--dim { color: var(--ink-2); }
.on-bone .card { background: rgba(10, 10, 10, .04); }
.on-bone .card p { color: var(--ink-2); }
.on-bone .card__kicker { color: var(--red-bone); }
.on-bone .grid { background: var(--hair-bone); border-color: var(--hair-bone); }
.on-bone .lines li { border-color: var(--hair-bone); color: var(--ink); }
.on-bone .btn--go { background: var(--ink); color: var(--bone); }
.on-bone .btn--go:hover { background: #1a1a1a; }
.on-bone .btn--ghost { border-color: var(--hair-bone); color: var(--ink); }
.on-bone .btn--ghost:hover { background: rgba(10, 10, 10, .05); }
.on-bone .mailto { color: var(--ink-2); }
.on-bone .mailto a { color: var(--ink); text-decoration-color: var(--red-bone); }
.on-bone .deriv, .on-bone .stamp { border-color: var(--hair-bone); color: var(--ink-2); }
.on-bone .deriv b, .on-bone .stamp b { color: var(--ink); }
.on-bone .deriv .op { color: var(--red-bone); }

/* ── EDITORIAL SEPARATION ──────────────────────────────────────────────── */
/* The three clauses stay verbatim. Numbered, on the bone ground, at the widest
   measure the rail allows. */
.sep__body { max-width: var(--measure); }
.sep__list { list-style: none; margin: 2rem 0 0; padding: 0; counter-reset: sep; max-width: var(--measure); }
.sep__item {
  display: grid; gap: .35rem 1.25rem; grid-template-columns: 2.5rem 1fr;
  padding: 1.25rem 0; border-top: 1px solid var(--hair-bone);
}
.sep__item:last-child { border-bottom: 1px solid var(--hair-bone); }
.sep__num {
  grid-row: span 2;
  font-family: var(--mono); font-variant-numeric: tabular-nums;
  font-size: .8125rem; font-weight: 500; color: var(--red-bone); padding-top: .25rem;
}
.sep__item h3 { font-size: clamp(1.125rem, 2vw, 1.375rem); }
.sep__item p { margin: 0; color: var(--ink-2); font-size: .9375rem; }
@media (max-width: 34rem) {
  .sep__item { grid-template-columns: 1fr; }
  .sep__num { grid-row: auto; }
}

/* ── LONG TABLE, SHARED ────────────────────────────────────────────────── */
/* /pricing owns the price tables in css/reference-pricing.css. This is the
   generic version /stack and /strategy-publicity use for a two-column list of
   facts. Wide content scrolls inside its own box; the page body never scrolls
   sideways. */
.scroller { overflow-x: auto; margin: 1.75rem 0 0; -webkit-overflow-scrolling: touch; }
table.t {
  width: 100%; border-collapse: collapse;
  font-variant-numeric: tabular-nums; font-size: .9375rem;
}
table.t caption {
  caption-side: top; text-align: left; padding: 0 0 .85rem;
  font-family: var(--mono); font-size: .75rem; letter-spacing: .14em;
  text-transform: uppercase; color: var(--dim-ink);
}
table.t th, table.t td { padding: .7rem .9rem; border-top: 1px solid var(--hair-ink); text-align: left; }
table.t th { font-weight: 600; color: var(--bone); }
table.t thead th {
  border-top: 0; border-bottom: 1px solid var(--hair-ink);
  font-family: var(--mono); font-size: .6875rem; font-weight: 500;
  letter-spacing: .14em; text-transform: uppercase; color: var(--dim-ink);
}
table.t td:last-child, table.t th:last-child { text-align: right; }
table.t tbody tr:hover td, table.t tbody tr:hover th { background: var(--plate); }

/* ADDED for /strategy-publicity, the first consumer table.t has. Two additive
   rules, no override of anything above:

   1. A second line inside a row header, saying what the figure actually covers
      — "Two-person crew, lighting and audio package. The edit is included."
      --dim-ink (9.4:1 on ink, 9.2:1 on the .plate hover) at 13px, never a
      translucent bone.
   2. The figure column in the mono face with tabular-nums, so $3,800, $4,000
      and $6,900 line up digit for digit down the column. table.t already sets
      tabular-nums on the table; the mono face is what makes three prices read
      as one column rather than three sentences. */
table.t th small {
  display: block; margin-top: .25rem;
  font-family: var(--sans); font-size: .8125rem; font-weight: 400;
  line-height: 1.55; color: var(--dim-ink);
}
table.t tbody td:last-child {
  font-family: var(--mono); font-variant-numeric: tabular-nums;
  white-space: nowrap; color: var(--bone); vertical-align: top;
}

/* ══ THE GUTTER, RESTORED ═══════════════════════════════════════════════════
   FOUND BY RENDERING, 2026-08-21. Measured at 390px on all five pages: TWELVE
   of pricing's thirteen .rail elements, and every .rail on the other four
   except the one inside .on-bone, computed padding-left: 0px. The h1, the
   lede, the tables and the card grids all touched both screen edges, and the
   lede's last word was clipped at the right.

   THE CAUSE IS THE CASCADE, not a missing value. `.rail` sets
   `padding: 0 var(--gut)`, and then three later rules of EQUAL specificity set
   a padding SHORTHAND with no inline component:

       .refhead      { padding: clamp(1.9rem,4vw,3.25rem) 0 clamp(1.6rem,3.2vw,2.5rem) }
       .band         { padding: clamp(2.25rem,4.6vw,4rem) 0 }
       .close__inner { padding: clamp(2rem,4.2vw,3.5rem) 0 }

   A shorthand writes all four sides, so each of those resets the inline
   padding to 0. One class each, later in the file, so they win. Every section
   on these pages carries `class="rail band"` or `class="rail refhead"` or
   `class="rail close__inner"`, which is why the only survivor is the bare
   <div class="rail"> inside the bone panels.

   It is invisible at 1440 — the 1136px rail is centred with 152px either side,
   so nothing appears to touch anything — and severe at 390 and 320, which is
   why it survived a desktop read.

   THE FIX IS ADDITIVE AND NOTHING ABOVE IS RESTRUCTURED. One longhand, at the
   end of the file, so it wins on order against every shorthand above it and
   against any future `.rail <modifier>` combination, while leaving each of
   those rules' BLOCK padding exactly as written. padding-inline rather than
   padding, precisely so the vertical rhythm is untouched.
   ═══════════════════════════════════════════════════════════════════════════ */
.rail { padding-inline: var(--gut); }

/* ══ THE TWO LINK RUNS THE ORIGINAL LIST MISSED ═════════════════════════════
   FOUND BY COMPUTING COMPOSITED CONTRAST, 2026-08-21. Both are additive.

   1. INSIDE A BONE PANEL, EVERY INLINE LINK WAS INVISIBLE. Measured 1:1.
      `.copy a, .lede a, .note a, .qa__a a, .sep__body a` sets
      `color: var(--bone)`, and the .on-bone block below overrides the colour of
      .copy, .note and every <p> but never of the <a> inside them. So the links
      in the editorial section's closing note were bone-on-bone: three blank
      underlines where "how the desk works" and "strategy and publicity" should
      be. It hit /pricing, /consulting and /strategy-publicity — every page
      that has a bone panel. Restored to --ink (17.4:1) with a --red-bone
      underline (6.6:1), matching what `.on-bone .mailto a` already did.

   2. A LINK INSIDE A CARD WAS UNSTYLED BROWSER BLUE. Measured 2.07:1 —
      rgb(0,0,238) on the #0d0d0d plate, on /pricing's "see the stack" in the
      last card of the no-hourly-billing section. The inline-link list covers
      .copy, .lede, .note, .qa__a and .sep__body, and a card's paragraph is
      none of those, so the anchor fell through to the UA default. Same
      treatment as every other inline link on these pages.
   ═══════════════════════════════════════════════════════════════════════════ */
.card p a, .cap__what a, .cap__how a {
  color: var(--bone); text-decoration: underline;
  text-decoration-color: var(--red); text-decoration-thickness: 1px;
  text-underline-offset: .18em;
}
.card p a:hover, .cap__what a:hover, .cap__how a:hover { text-decoration-color: var(--red-ink); }

.on-bone .copy a, .on-bone .lede a, .on-bone .note a,
.on-bone .qa__a a, .on-bone .sep__body a, .on-bone .card p a {
  color: var(--ink); text-decoration-color: var(--red-bone);
}
.on-bone .copy a:hover, .on-bone .lede a:hover, .on-bone .note a:hover,
.on-bone .qa__a a:hover, .on-bone .sep__body a:hover, .on-bone .card p a:hover {
  text-decoration-color: var(--red);
}
