/* Tiger & Bugs — the whole design system.
 *
 * WHY THIS IS NO LONGER INLINE. The old base.njk inlined 4KB of CSS and argued,
 * correctly at the time, that a separate request for 4KB buys nothing on a
 * three-page site. Both halves of that changed: this is ~16KB and the site is
 * eight pages. Inlining now means paying for the whole stylesheet again on every
 * navigation, where one cached file is paid for once. The request is preloaded
 * and served with an immutable cache header, so the round trip happens once per
 * visitor per deploy.
 *
 * THE IDEA. The account's running joke is that the cats are management and the
 * human works for them, delivered deadpan — "several complaints were filed"
 * rather than "they were SO mad". So the site is that company's website: rules,
 * hairlines, docket numbers, tabular figures, a stamp where a decoration would
 * go. The warmth has to come from the photographs, because the layout is not
 * going to supply any, and that split is the point rather than an accident.
 *
 * The exception is /partner, which drops the bit. A brand manager deciding
 * whether to spend money needs the numbers in plain language, and a joke there
 * costs more than it earns. See .plain further down.
 */

/* ------------------------------------------------------------------ fonts */
/* Self-hosted, subset to latin, both SIL OFL — licences sit beside the files.
 * Not Google-hosted: a font request to a third party on every page load is a
 * privacy footnote nobody wants to write and a DNS lookup nobody wants to pay
 * for. Archivo is the institutional grotesque doing the shouting; Plex Mono is
 * literally IBM's typeface and does every part that wants to look like a
 * document. */
@font-face {
  font-family: 'Archivo';
  src: url('/assets/fonts/archivo-var.woff2') format('woff2');
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Plex Mono';
  src: url('/assets/fonts/plex-mono-500.woff2') format('woff2');
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}

/* ----------------------------------------------------------------- tokens */
:root {
  --paper: #fdfaf6;
  --paper-2: #f7f1e8;
  --ink: #1b1714;
  --ink-2: #3d352e;
  --muted: #6b6157;
  --rule: #e2d6c6;
  --rule-strong: #cbbba4;

  /* TWO ORANGES, because one cannot do both jobs.
   * The brand orange (#e8730c) is 3.49:1 on paper — fine for large text, which
   * only needs 3:1, and a WCAG AA failure everywhere else. Nearly every use on
   * this site is small: docket numbers, section marks, 11px labels. So --orange
   * is a deepened version that clears 4.5:1 as text AND 4.5:1 for white on it as
   * a button, and --orange-hot stays vivid for display sizes only.
   * Never use --orange-hot below 24px. */
  --orange: #b85206;
  --orange-hot: #dd6908;
  --orange-on: #ffffff;      /* text that sits ON an orange fill */
  --orange-soft: #fff2e4;
  --manila: #f3e7d1;
  --stamp: #b3322a;
  --approve: #2f7350;

  --shell: 1180px;
  --gutter: clamp(20px, 5vw, 44px);
  --measure: 64ch;

  --sans: 'Archivo', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  --mono: 'Plex Mono', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

  --step: clamp(56px, 9vw, 104px);   /* vertical rhythm between sections */
  --ease: cubic-bezier(0.2, 0.7, 0.2, 1);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) {
    --paper: #14110f;
    --paper-2: #1b1714;
    --ink: #f4efe9;
    --ink-2: #d9cfc4;
    --muted: #a2968a;
    --rule: #322b25;
    --rule-strong: #4a4038;
    /* Inverted on dark: the orange is now the LIGHT colour, so text sitting on
     * an orange fill has to be the dark ink. White on #f5892c is about 2:1. */
    --orange: #f5892c;
    --orange-hot: #ff9d47;
    --orange-on: #1b1714;
    --orange-soft: #2a1d10;
    --manila: #241c12;
    --stamp: #e0685c;
    --approve: #5fb98a;
  }
}

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

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

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 17px;
  line-height: 1.6;
  font-synthesis-weight: none;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

/* The paper grain. A single repeating gradient rather than an image request —
 * it reads as texture at 3% and costs nothing. */
body::before {
  content: '';
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 0;
  opacity: 0.5;
  background-image:
    repeating-linear-gradient(0deg, rgba(120, 100, 80, 0.022) 0 1px, transparent 1px 3px);
}
body > * { position: relative; z-index: 1; }

img, svg, iframe { max-width: 100%; display: block; }
img { height: auto; }

a { color: inherit; }
:where(a, button, summary, input, textarea, select):focus-visible {
  outline: 2px solid var(--orange-hot);
  outline-offset: 3px;
  border-radius: 1px;
}

::selection { background: var(--orange); color: var(--orange-on); }

/* --------------------------------------------------------------- skeleton */
.shell { width: 100%; max-width: var(--shell); margin: 0 auto; padding-inline: var(--gutter); }
.measure { max-width: var(--measure); }

/* Vertical rhythm is BOTTOM-ONLY on purpose. Padding on both sides means every
 * boundary between two sections is worth two --steps, which is how the first
 * draft ended up with 200px of nothing between the hero and the first heading.
 * One owner per gap; the footer then adds none of its own. */
.section { padding-block: 0 var(--step); }

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}
.skip {
  position: absolute; left: var(--gutter); top: -60px; z-index: 100;
  background: var(--ink); color: var(--paper); padding: 10px 16px;
  font: 500 13px/1 var(--mono); text-decoration: none; transition: top 0.15s;
}
.skip:focus { top: 12px; }

/* ------------------------------------------------------------------- type */
h1, h2, h3, h4 { margin: 0; font-weight: 800; letter-spacing: -0.03em; line-height: 1.05; }

.display {
  font-size: clamp(35px, 5.6vw, 66px);
  font-weight: 800;
  letter-spacing: -0.038em;
  line-height: 1.01;
  text-wrap: balance;
}
.display em { font-style: normal; color: var(--orange-hot); }

.lede {
  font-size: clamp(17px, 1.9vw, 21px);
  line-height: 1.55;
  color: var(--muted);
  max-width: 46ch;
  margin: 20px 0 0;
  text-wrap: pretty;
}

p { text-wrap: pretty; }

/* The register that makes the whole thing read as a document: mono, uppercase,
 * widely tracked, small. Used for every label, eyebrow, stamp and figure
 * caption on the site. */
.meta {
  font-family: var(--mono);
  font-size: 11.5px;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted);
  line-height: 1.5;
}
.meta-strong { color: var(--ink); }
.meta-orange { color: var(--orange); }

/* Section headings: "§ 02 —— THE BOARD ————————————" */
.sec-head { display: flex; align-items: center; gap: 14px; margin-bottom: 30px; }
.sec-head h2 {
  font-family: var(--mono); font-weight: 500; font-size: 12px;
  letter-spacing: 0.18em; text-transform: uppercase; color: var(--ink);
}
.sec-head .no { font-family: var(--mono); font-size: 12px; letter-spacing: 0.1em; color: var(--orange); }
.sec-head::after { content: ''; flex: 1; height: 1px; background: var(--rule); }

.h-sub { font-size: clamp(26px, 3.6vw, 40px); letter-spacing: -0.032em; margin-bottom: 14px; text-wrap: balance; }

/* --------------------------------------------------------------- controls */
.btn {
  display: inline-flex; align-items: center; gap: 9px;
  background: var(--ink); color: var(--paper);
  font: 600 14.5px/1 var(--sans); letter-spacing: 0.01em;
  padding: 15px 22px; text-decoration: none; border: 1px solid var(--ink);
  transition: background 0.18s var(--ease), color 0.18s var(--ease), transform 0.18s var(--ease);
}
.btn:hover { background: var(--orange); border-color: var(--orange); color: var(--orange-on); }
.btn:active { transform: translateY(1px); }
.btn-ghost { background: transparent; color: var(--ink); border-color: var(--rule-strong); }
.btn-ghost:hover { background: var(--ink); border-color: var(--ink); color: var(--paper); }
.btn-orange { background: var(--orange); border-color: var(--orange); color: var(--orange-on); }
.btn-orange:hover { background: var(--ink); border-color: var(--ink); color: var(--paper); }
.btn .arw { transition: transform 0.18s var(--ease); }
.btn:hover .arw { transform: translateX(3px); }

.actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 30px; }

/* ------------------------------------------------------------- letterhead */
.letterhead {
  position: sticky; top: 0; z-index: 50;
  background: color-mix(in srgb, var(--paper) 88%, transparent);
  backdrop-filter: saturate(1.5) blur(10px);
  border-bottom: 1px solid var(--rule);
}
.letterhead .shell { display: flex; align-items: center; gap: 18px; min-height: 62px; }

.mark { display: flex; align-items: baseline; gap: 8px; text-decoration: none; margin-right: auto; }
.mark .orange { font-size: 15px; line-height: 1; }
.mark .name {
  font-weight: 800; font-size: 15.5px; letter-spacing: -0.02em; text-transform: uppercase;
}
.mark .inc { font-family: var(--mono); font-size: 10px; letter-spacing: 0.14em; color: var(--muted); }
.mark:hover .name { color: var(--orange); }

.nav { display: flex; align-items: center; gap: 4px; }
.nav a {
  font-family: var(--mono); font-size: 11.5px; font-weight: 500;
  letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--muted); text-decoration: none; padding: 8px 10px;
  transition: color 0.15s;
}
.nav a:hover { color: var(--ink); }
.nav a[aria-current='page'] { color: var(--orange); }
.nav .cta {
  color: var(--paper); background: var(--ink); margin-left: 8px; padding: 9px 14px;
}
.nav .cta:hover { background: var(--orange); color: var(--orange-on); }
/* The generic a[aria-current] rule paints the CURRENT page orange, which on the
 * CTA means orange text on the dark fill — 3.6:1, and unreadable at 11.5px. On
 * the CTA the current state is shown by filling it instead. */
.nav .cta[aria-current='page'] { background: var(--orange); color: var(--orange-on); }

/* The menu toggle. The checkbox itself is visually hidden but focusable, and the
 * label is the visible control; :focus-visible on the input paints the ring on
 * the label so keyboard users can see where they are. */
.nav-btn {
  display: none; cursor: pointer; padding: 9px 12px;
  font: 500 11.5px/1 var(--mono); letter-spacing: 0.1em; text-transform: uppercase;
  border: 1px solid var(--rule-strong); color: var(--ink);
  user-select: none;
}
.nav-toggle:focus-visible + .nav-btn { outline: 2px solid var(--orange-hot); outline-offset: 3px; }
.nav-toggle:checked + .nav-btn { background: var(--ink); color: var(--paper); border-color: var(--ink); }

@media (max-width: 900px) {
  .nav-btn { display: inline-flex; align-items: center; gap: 7px; }
  .nav {
    position: absolute; right: var(--gutter); top: calc(100% + 8px); z-index: 60;
    display: none; flex-direction: column; align-items: stretch; gap: 0;
    background: var(--paper); border: 1px solid var(--rule-strong);
    min-width: 216px; padding: 6px;
    box-shadow: 0 18px 40px -18px rgba(0, 0, 0, 0.35);
  }
  .nav-toggle:checked ~ .nav { display: flex; }
  .nav a { padding: 12px; }
  .nav .cta { margin: 6px 0 0; text-align: center; justify-content: center; }
}

/* ------------------------------------------------------------------- hero */
.hero { padding-block: clamp(34px, 5vw, 64px) var(--step); }
.hero-grid { display: grid; gap: clamp(30px, 5vw, 58px); align-items: center; }
/* The type column has to be wide enough that the headline is not setting two
 * words to a line. At 1.12fr the display size and the column fought each other
 * and "badly managed company" took three lines on its own. */
@media (min-width: 860px) { .hero-grid { grid-template-columns: 1.32fr 0.68fr; } }

.tagstrip {
  display: flex; flex-wrap: wrap; align-items: center; gap: 10px;
  padding-bottom: 16px; margin-bottom: 22px; border-bottom: 1px solid var(--rule);
}
.tagstrip .dot { width: 5px; height: 5px; background: var(--orange); border-radius: 50%; }

/* The framed photograph. It is doing two jobs: it is the only warmth on the
 * page, and its caption is where the site admits — in character — that we
 * cannot tell the two cats apart in a still. brandVoice.js is explicit that
 * guessing has already put Tiger's name on Bugs (aka Garfield), so the constraint became
 * a joke rather than a thing to quietly work around. */
/* CAPPED, because a portrait photo at full column width is a wall.
   His words: "Some pages have giant photos on them.. might be worth another
   look." The plate is a framed exhibit, not a hero — it should read as a
   plate on a page, and above about 620px it stops being one. */
.plate { margin: 0; max-width: 620px; border: 1px solid var(--rule-strong); background: var(--paper-2); padding: 10px; }
.plate img { width: 100%; filter: saturate(1.04) contrast(1.02); }
.plate figcaption {
  font-family: var(--mono); font-size: 10px; font-weight: 500;
  letter-spacing: 0.11em; text-transform: uppercase; color: var(--muted);
  padding-top: 10px; margin-top: 10px; border-top: 1px solid var(--rule);
  display: flex; justify-content: space-between; gap: 10px; flex-wrap: wrap;
}

/* ------------------------------------------------------- the hairline grid */
/* One-pixel gaps over a rule-coloured ground. It was already the trick the old
 * stat strip used and it is still the cheapest way to draw a real table edge
 * without fighting border-collapse. */
.grid-rule {
  display: grid; gap: 1px;
  background: var(--rule); border: 1px solid var(--rule);
}
.grid-rule > * { background: var(--paper); }

.dash { grid-template-columns: repeat(2, 1fr); }
@media (min-width: 760px) { .dash { grid-template-columns: repeat(4, 1fr); } }

.tile { padding: clamp(16px, 2.4vw, 26px); }
.tile b {
  display: block; font-size: clamp(30px, 4.6vw, 50px); font-weight: 800;
  letter-spacing: -0.04em; line-height: 1; font-variant-numeric: tabular-nums;
  margin-bottom: 8px;
}
.tile .lbl { font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--muted); }
.tile .note { font-size: 13px; color: var(--muted); margin: 10px 0 0; line-height: 1.45; }

.tile-wide { grid-column: 1 / -1; }
.tile-accent b { color: var(--orange-hot); }

/* The comparison bar. Engagement per view against the industry averages is the
 * single most sellable fact on the site, so it gets drawn rather than stated.
 * The widths come from stats.json via --w and are scaled against our own rate —
 * they were once literals computed for a 6.59% that has since moved, which left
 * a chart whose labels updated while its bars did not. */
.bars { display: grid; gap: 10px; margin-top: 16px; }
.bar-row { display: grid; grid-template-columns: minmax(96px, auto) 1fr auto; gap: 12px; align-items: center; }
.bar-row .who { font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.09em; text-transform: uppercase; color: var(--muted); }
/* THE BARS NEVER RENDERED. Two independent faults in three lines.
 *
 * .bar-fill was a <span> with no display set, so it stayed `display: inline`
 * and a width and height on it mean nothing — the element had no box at all.
 * .bar-track looked fine only because it is a grid item, which blockifies it.
 * So the chart drew three identical empty tracks, reading as "this account,
 * pet accounts and all creators are the same", the precise opposite of the
 * claim it exists to make. It survived an axe pass, a contrast pass and two
 * commits about whether its widths were computed correctly.
 *
 * The width also arrived as `style="--w:82%"`, an inline attribute, which
 * `style-src 'self'` refuses on the deploy — so even with display fixed the
 * bars would have fallen back to 0% in production and nowhere else.
 *
 * Both are solved by drawing it as SVG: `width` on a <rect> is a presentation
 * attribute, not a style attribute, so the CSP does not touch it, and a rect
 * has a box by definition. Colour still comes from CSS. */
.bar-track { height: 9px; background: var(--rule); overflow: hidden; }
.bar-svg { display: block; width: 100%; height: 9px; }
.bar-fill { fill: var(--rule-strong); }
.bar-row.is-us .bar-fill { fill: var(--orange); }
.bar-row.is-us .who { color: var(--ink); }
.bar-row .val { font-family: var(--mono); font-size: 12px; font-variant-numeric: tabular-nums; }

/* --------------------------------------------------------------- channels */
.channels { display: grid; gap: 1px; background: var(--rule); border: 1px solid var(--rule); }
@media (min-width: 700px) { .channels { grid-template-columns: repeat(3, 1fr); } }
.channel {
  background: var(--paper); padding: 20px; text-decoration: none;
  display: flex; flex-direction: column; gap: 4px;
  transition: background 0.16s var(--ease);
}
.channel:hover { background: var(--orange-soft); }
.channel .p { font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--muted); }
.channel .c { font-size: 28px; font-weight: 800; letter-spacing: -0.03em; font-variant-numeric: tabular-nums; }
.channel .h { font-size: 13px; color: var(--muted); overflow-wrap: anywhere; }
.channel:hover .c { color: var(--orange); }

/* ---------------------------------------------------------------- filings */
.filings { display: grid; gap: 1px; background: var(--rule); border: 1px solid var(--rule); }
@media (min-width: 720px) { .filings { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1040px) { .filings { grid-template-columns: repeat(3, 1fr); } }

.filing {
  background: var(--paper); padding: 22px;
  display: flex; flex-direction: column; gap: 14px;
  transition: background 0.16s var(--ease);
}
.filing:hover { background: var(--paper-2); }
.filing .top { display: flex; justify-content: space-between; gap: 10px; align-items: baseline; }
.filing .dkt { font-family: var(--mono); font-size: 11px; letter-spacing: 0.1em; color: var(--orange); }
.filing .chan { font-family: var(--mono); font-size: 10px; letter-spacing: 0.13em; text-transform: uppercase; color: var(--muted); }
.filing .quote {
  margin: 0; font-size: 16px; line-height: 1.45; color: var(--ink-2);
  flex: 1; text-wrap: pretty;
}
.filing .imp { border-top: 1px solid var(--rule); padding-top: 13px; }
.filing .imp b { display: block; font-size: 27px; font-weight: 800; letter-spacing: -0.035em; font-variant-numeric: tabular-nums; line-height: 1.1; }
.filing .imp span { font-family: var(--mono); font-size: 10px; letter-spacing: 0.13em; text-transform: uppercase; color: var(--muted); }
.filing .open {
  font-family: var(--mono); font-size: 11px; letter-spacing: 0.1em; text-transform: uppercase;
  text-decoration: none; color: var(--ink); display: inline-flex; gap: 7px; align-items: center;
}
.filing .open:hover { color: var(--orange); }
.filing .open::after { content: '→'; transition: transform 0.16s var(--ease); }
.filing .open:hover::after { transform: translateX(3px); }

/* Embed facade. The real Facebook/Instagram/TikTok iframe is not written into
 * the page until someone asks for it — three platform SDKs loading on a page
 * nobody has interacted with is how a fast site stops being one. With scripting
 * off the same element is a plain link to the post, which is the behaviour the
 * site had before and is not a downgrade. */
/* The closed facade is SHORT. It was 9/16 to match the reel it eventually
 * shows, which meant every unopened card carried 435px of empty beige — a
 * placeholder pretending to be a video. It is honest as a control and dishonest
 * as a poster, so it is sized as a control and only takes reel proportions once
 * there is an actual reel inside it. */
.facade {
  position: relative; aspect-ratio: 4 / 3;
  background: var(--paper-2); border: 1px solid var(--rule);
  display: grid; place-items: center;
  background-image: repeating-linear-gradient(135deg, transparent 0 9px, color-mix(in srgb, var(--rule) 55%, transparent) 9px 10px);
}
.facade.is-live { aspect-ratio: 9 / 16; background-image: none; }
/* WITH A POSTER, the card is the video's real shape from the start. The hatched
   4:3 placeholder was a guess at a size, and clicking play resized the card from
   4:3 to 9:16 — every other card on the page jumping down as it did. Portrait
   from the outset is both honest about the content and stable. */
.facade.has-poster { aspect-ratio: 9 / 16; background-image: none; }
.facade .poster {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; display: block;
}
/* The play control sits over the poster, and needs its own contrast now that it
   is on photography rather than on flat paper. The gradient is gone with the
   label it existed to make readable — the disc carries its own contrast, and a
   scrim over every card was dimming the thing the poster was added to show. */
.facade.has-poster .play {
  position: relative; z-index: 1; color: #fff;
}
.facade.has-poster .disc {
  background: rgba(0, 0, 0, 0.55); color: #fff; border-color: rgba(255, 255, 255, 0.6);
}
/* Once the iframe is in, the poster is behind it and only costs a repaint. */
.facade.is-live .poster { display: none; }
.facade iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }
.facade .play {
  display: grid; place-items: center; gap: 10px; width: 100%; height: 100%;
  background: none; border: 0; cursor: pointer; color: var(--ink); font-family: var(--mono);
  font-size: 11px; letter-spacing: 0.12em; text-transform: uppercase;
  text-decoration: none;
}
.facade .play .disc {
  width: 54px; height: 54px; border: 1px solid var(--rule-strong); border-radius: 50%;
  display: grid; place-items: center; transition: all 0.18s var(--ease);
}
.facade .play:hover .disc { background: var(--orange); border-color: var(--orange); color: var(--orange-on); transform: scale(1.06); }

/* ------------------------------------------------------------------ memos */
.memo {
  background: var(--manila); border: 1px solid var(--rule-strong);
  padding: clamp(20px, 3vw, 34px); position: relative; overflow: hidden;
}
/* The punched filing holes down the left edge. Two radial gradients, no image. */
.memo::before {
  content: ''; position: absolute; left: 13px; top: 0; bottom: 0; width: 10px;
  background-image: radial-gradient(circle, var(--rule-strong) 3.5px, transparent 4px);
  background-size: 10px 74px; background-repeat: repeat-y; opacity: 0.7;
}
.memo-inner { padding-left: 30px; }
.memo-head { display: flex; flex-wrap: wrap; gap: 8px 20px; padding-bottom: 14px; margin-bottom: 16px; border-bottom: 1px solid var(--rule-strong); }
.memo-re { font-size: clamp(19px, 2.6vw, 26px); font-weight: 800; letter-spacing: -0.03em; margin: 0 0 12px; }
.memo-body { margin: 0; font-size: 16.5px; line-height: 1.6; color: var(--ink-2); max-width: 62ch; }

/* The status stamp. Rotated, hollow, slightly transparent — a rubber stamp
 * rather than a badge. It is the one purely decorative object on the site and
 * it earns its place by naming the state of a complaint. */
.stamp {
  display: inline-block; font-family: var(--mono); font-size: 11px; font-weight: 500;
  letter-spacing: 0.16em; text-transform: uppercase;
  border: 2px solid var(--stamp); color: var(--stamp);
  padding: 5px 11px; transform: rotate(-3.5deg);
}
.stamp-ok { border-color: var(--approve); color: var(--approve); }

.memo-list { display: grid; gap: 1px; background: var(--rule); border: 1px solid var(--rule); }
.memo-row {
  background: var(--paper); padding: 20px 22px;
  display: grid; gap: 6px 20px; align-items: baseline;
}
@media (min-width: 780px) { .memo-row { grid-template-columns: 110px 1fr 130px; } }
.memo-row .re { font-weight: 700; letter-spacing: -0.02em; }
.memo-row .bd { grid-column: 1 / -1; color: var(--muted); font-size: 15px; margin: 0; max-width: 70ch; }
@media (min-width: 780px) { .memo-row .bd { grid-column: 2 / 3; } }

/* ---------------------------------------------------------------- archive */
.archive { display: grid; gap: 1px; background: var(--rule); border: 1px solid var(--rule); }
@media (min-width: 640px) { .archive { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 980px) { .archive { grid-template-columns: repeat(3, 1fr); } }
.clip {
  background: var(--paper); border: 0; padding: 16px 18px; cursor: pointer;
  display: flex; align-items: center; gap: 14px; text-align: left; width: 100%;
  font-family: inherit; color: inherit;
  transition: background 0.16s var(--ease);
}
.clip:hover { background: var(--orange-soft); }
.clip .disc {
  width: 34px; height: 34px; flex: none; border: 1px solid var(--rule-strong); border-radius: 50%;
  display: grid; place-items: center; font-size: 11px; transition: all 0.16s var(--ease);
}
.clip:hover .disc, .clip[aria-pressed='true'] .disc { background: var(--orange); border-color: var(--orange); color: var(--orange-on); }
.clip .dkt { font-family: var(--mono); font-size: 11px; letter-spacing: 0.09em; color: var(--orange); display: block; }
.clip .desc { font-size: 14px; color: var(--muted); }

/* --------------------------------------------------------------- the board */
.execs { display: grid; gap: clamp(24px, 4vw, 44px); }
@media (min-width: 780px) { .execs { grid-template-columns: repeat(2, 1fr); } }
/* align-content: start is load-bearing. The two cards are equal-height grid
 * items, but their rows are `auto`, so grid hands the leftover height to the
 * rows — and the card with the shorter bio has more left over, which inflated
 * its PHOTOGRAPH by 14px and knocked the two headings out of alignment. Pinning
 * the rows to their content puts the slack at the bottom of the card, where it
 * is invisible, instead of inside the frame. */
.exec { display: grid; gap: 20px; align-content: start; }
.exec-photo { border: 1px solid var(--rule-strong); background: var(--paper-2); padding: 9px; }
.exec-photo img { width: 100%; aspect-ratio: 1; object-fit: cover; }
.exec-photo .cap {
  font-family: var(--mono); font-size: 9.5px; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--muted); padding-top: 9px; margin-top: 9px; border-top: 1px solid var(--rule);
}
.exec h3 { font-size: clamp(24px, 3vw, 32px); letter-spacing: -0.035em; }
.exec .title { margin: 6px 0 14px; }
.exec .bio { margin: 0 0 16px; color: var(--ink-2); }
.exec .greivance { border-left: 2px solid var(--orange); padding-left: 14px; margin: 0; }

/* Org chart. Boxes and CSS-drawn connectors — an SVG would be one more thing to
 * keep in sync with the labels, and the labels are the joke.
 *
 * The bracket has to END where the two boxes BEGIN, or the chart reads as a
 * line that stops short of the thing it connects to. So the pair is a fixed
 * two-column grid and the bracket's width is derived from it — one column plus
 * one gap is exactly the centre-to-centre distance. */
.org {
  --org-w: min(440px, 88vw);
  --org-gap: 22px;
  --org-col: calc((var(--org-w) - var(--org-gap)) / 2);
  display: grid; justify-items: center; gap: 0; text-align: center; margin-top: 10px;
}
.org-box {
  border: 1px solid var(--rule-strong); background: var(--paper); padding: 13px 18px;
  min-width: 172px;
}
.org-box .who { font-weight: 700; letter-spacing: -0.02em; }
.org-box.top { border-color: var(--orange); background: var(--orange-soft); }
.org-box.bottom { border-style: dashed; }

.org-pair {
  display: grid; grid-template-columns: repeat(2, 1fr);
  gap: var(--org-gap); width: var(--org-w);
}
.org-pair .org-box { min-width: 0; }

.org-drop { width: 1px; height: 24px; background: var(--rule-strong); }
.org-bracket {
  width: calc(var(--org-col) + var(--org-gap));
  height: 24px;
  border-left: 1px solid var(--rule-strong);
  border-right: 1px solid var(--rule-strong);
  border-top: 1px solid var(--rule-strong);
}

/* ------------------------------------------------------------------ plain */
/* /partner drops the bit. Same typography, same grid, no docket numbers, no
 * stamps, no jokes in the headings — a brand manager works out in about four
 * seconds whether a page is going to tell them the price, and being funny at
 * them during those four seconds is expensive. */
.plain .h-sub { letter-spacing: -0.03em; }
.pack { display: grid; gap: 1px; background: var(--rule); border: 1px solid var(--rule); }
@media (min-width: 700px) { .pack { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1060px) { .pack { grid-template-columns: repeat(4, 1fr); } }
.pack-card { background: var(--paper); padding: 24px 22px; display: flex; flex-direction: column; gap: 12px; }
.pack-card.featured { background: var(--orange-soft); }
.pack-card h3 { font-size: 20px; letter-spacing: -0.025em; }
.pack-card .price { font-size: 30px; font-weight: 800; letter-spacing: -0.035em; font-variant-numeric: tabular-nums; margin: 0; }
.pack-card .price small {
  display: block; margin-top: 5px;
  font-family: var(--mono); font-size: 10.5px; font-weight: 500;
  letter-spacing: 0.1em; text-transform: uppercase; color: var(--muted);
}
.pack-card .sum { margin: 0; font-size: 15px; color: var(--ink-2); }
.pack-card ul { margin: 0; padding: 0; list-style: none; display: grid; gap: 8px; font-size: 14px; color: var(--muted); }
.pack-card li { padding-left: 18px; position: relative; }
.pack-card li::before { content: '—'; position: absolute; left: 0; color: var(--orange); }
.pack-card .tat { margin-top: auto; padding-top: 12px; border-top: 1px solid var(--rule); }

/* ------------------------------------------------------------------ forms */
.form { display: grid; gap: 16px; max-width: 620px; }
.field { display: grid; gap: 7px; }
.field label { font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.13em; text-transform: uppercase; color: var(--muted); }
.field input, .field textarea, .field select {
  font: 400 16px/1.5 var(--sans); color: var(--ink);
  background: var(--paper); border: 1px solid var(--rule-strong);
  padding: 12px 14px; width: 100%; border-radius: 0;
  transition: border-color 0.15s;
}
.field input:hover, .field textarea:hover, .field select:hover { border-color: var(--muted); }
.field input:focus, .field textarea:focus, .field select:focus { border-color: var(--orange); }
.field textarea { resize: vertical; min-height: 118px; }
.field-row { display: grid; gap: 16px; }
@media (min-width: 640px) { .field-row { grid-template-columns: 1fr 1fr; } }
.hp { position: absolute; left: -9999px; opacity: 0; }

.signup { display: flex; gap: 10px; flex-wrap: wrap; max-width: 480px; }
.signup input { flex: 1 1 220px; }
.form-note { font-size: 13px; color: var(--muted); margin: 0; }

/* ----------------------------------------------------------------- tables */
.scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }
table { width: 100%; border-collapse: collapse; font-size: 15px; }
th, td { text-align: left; padding: 12px 14px; border-bottom: 1px solid var(--rule); }
thead th {
  font-family: var(--mono); font-size: 10px; font-weight: 500; letter-spacing: 0.13em;
  text-transform: uppercase; color: var(--muted); border-bottom-color: var(--rule-strong);
}
td.num, th.num { text-align: right; font-variant-numeric: tabular-nums; }
tbody tr:hover { background: var(--paper-2); }

/* ------------------------------------------------------------------ misc */
.callout { border: 1px solid var(--rule-strong); border-left: 3px solid var(--orange); padding: 20px 22px; background: var(--paper-2); }
.strip { display: flex; flex-wrap: wrap; gap: 10px 26px; align-items: center; }
.asof { font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--muted); margin-top: 22px; }
/* Explicit column counts, not auto-fit. There are eight photographs; auto-fit
 * chose seven columns at desktop width and left the eighth alone on a second
 * row beside a large empty rectangle. Counts that divide eight are the fix. */
.gallery { display: grid; grid-template-columns: repeat(2, 1fr); gap: 1px; background: var(--rule); border: 1px solid var(--rule); }
@media (min-width: 620px) { .gallery { grid-template-columns: repeat(4, 1fr); } }
.gallery img { width: 100%; aspect-ratio: 4/5; object-fit: cover; }

.cta-band { border: 1px solid var(--rule-strong); background: var(--paper-2); padding: clamp(28px, 4.5vw, 52px); }

footer.site { border-top: 1px solid var(--rule); padding-block: 40px 48px; }
footer.site .cols { display: grid; gap: 30px; }
@media (min-width: 760px) { footer.site .cols { grid-template-columns: 1.4fr 1fr 1fr; } }
footer.site h4 { font-family: var(--mono); font-size: 10.5px; font-weight: 500; letter-spacing: 0.14em; text-transform: uppercase; color: var(--muted); margin-bottom: 12px; }
footer.site ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }
footer.site a { color: var(--muted); text-decoration: none; font-size: 14.5px; }
footer.site a:hover { color: var(--orange); }
footer.site .base { margin-top: 34px; padding-top: 20px; border-top: 1px solid var(--rule); display: flex; flex-wrap: wrap; gap: 10px 20px; }

/* ----------------------------------------------------------------- motion */
/* Everything here is an enhancement of a page that is already complete.
 *
 * THE HIDDEN STATE IS SCOPED TO .js, which a one-line script in <head> sets
 * before first paint. The usual way round — put opacity:0 in the stylesheet and
 * animate it up from script — has a failure mode of a permanently blank page
 * when the script does not run, and "blank page" is an expensive bug to trade
 * for a fade. This way, no JavaScript means no hiding, and there is no flash of
 * visible content either, because .js lands before anything is painted. */
.js .reveal { opacity: 0; transform: translateY(14px); }
.js .reveal.in { opacity: 1; transform: none; transition: opacity 0.6s var(--ease), transform 0.6s var(--ease); }
.js .reveal-d1.in { transition-delay: 0.07s; }
.js .reveal-d2.in { transition-delay: 0.14s; }
.js .reveal-d3.in { transition-delay: 0.21s; }

@media (prefers-reduced-motion: reduce) {
  .js .reveal, .js .reveal.in { opacity: 1; transform: none; transition: none; }
  *, *::before, *::after { animation-duration: 0.001ms !important; transition-duration: 0.001ms !important; }
}

/* ------------------------------------------------ CSP-SAFE LAYOUT HELPERS
 *
 * Every rule below replaces an inline style="..." attribute, and every one of
 * those attributes was being DISCARDED on the deploy.
 *
 * netlify.toml sets `style-src 'self'` with no 'unsafe-inline'. That directive
 * governs style ATTRIBUTES exactly as it governs <style> elements — 59 of them
 * across the built site, refused silently. The partnerships hero asked for a
 * 16ch measure and rendered across the full 1092px column. The callouts lost
 * their offsets. The engagement chart lost the custom property carrying its bar
 * widths. Every page returned 200 with correct markup.
 *
 * The CSP comment in netlify.toml said "There is no inline <style>". That was
 * true, and it was not the same claim.
 *
 * Measures are named in ch because that is the unit the copy was written to. */
.mw-16 { max-width: 16ch; }
.mw-34 { max-width: 34ch; }
.mw-38 { max-width: 38ch; }
.mw-40 { max-width: 40ch; }
.mw-44 { max-width: 44ch; }
.mw-46 { max-width: 46ch; }
.mw-50 { max-width: 50ch; }
.mw-52 { max-width: 52ch; }
.mw-56 { max-width: 56ch; }

.mt-18 { margin-top: 18px; }
.mt-24 { margin-top: 24px; }
.mt-26 { margin-top: 26px; }
.mt-30 { margin-top: 30px; }
.mt-34 { margin-top: 34px; }
.mb-14 { margin: 0 0 14px; }
.mb-26 { margin-bottom: 26px; }
.flush { margin: 0; }
.push { margin-left: auto; }
/* The stamp hangs below its paragraph; 22px is the rotation's clearance. */
.stamp-line { margin: 22px 0 0; }

/* Callout internals were the same three inline attributes repeated on every h3
 * and p inside one. That is structure, so it is a rule. The two hand-typed gaps
 * between stacked paragraphs (12px and 16px) are unified at 14px. */
.callout h3 { font-size: 19px; margin-bottom: 10px; }
.callout p { margin: 0; color: var(--muted); font-size: 15px; }
.callout p + p { margin-top: 14px; }
.callout .actions { margin-top: 16px; }
.callout-quiet { border-left-color: var(--rule-strong); }

/* Terms under the rate cards. The em dash was a positioned <span> carrying its
 * own inline colour; it is decoration, so it is a ::before. */
.terms { list-style: none; padding: 0; margin: 0; display: grid; gap: 10px; color: var(--muted); font-size: 15px; }
.terms li { padding-left: 18px; position: relative; }
.terms li::before { content: "\2014"; position: absolute; left: 0; color: var(--orange); }

/* Newsletter block in the CTA band, and the footer tagline. */
.signup-head { font-size: 20px; margin-bottom: 8px; }
.signup-note { color: var(--muted); font-size: 15px; margin: 0 0 16px; max-width: 38ch; }
.foot-tag { font-size: 15px; margin-top: 14px; max-width: 34ch; }

/* ------------------------------------------------------------------ print */
/* A brand manager's first move with a media kit is to print it to PDF and put it
 * in a deck. It may as well survive the trip. */
@media print {
  :root { --paper: #fff; --ink: #000; --muted: #444; --rule: #ccc; --rule-strong: #999; --orange: #c05600; }
  .letterhead, footer.site, .actions, .skip, .facade, .archive, .signup, .cta-band { display: none !important; }
  body::before { display: none; }
  .section { padding-block: 18px; break-inside: avoid; }
  .tile, .filing, .pack-card { break-inside: avoid; }
  a[href^='http']::after { content: ' (' attr(href) ')'; font-size: 9px; color: #666; }
}

/* The thank-you clip on /tipped.html. Capped rather than full-width: the source
   is a phone-shot vertical of two cats, and letting it run the full column on a
   desktop would make a 5-second aside the largest thing on the page. */
.tip-clip { margin: 30px 0 0; max-width: 300px; }
.tip-clip video {
  display: block; width: 100%; height: auto; border-radius: 3px;
  border: 1px solid var(--rule-strong); background: var(--ink);
}

/* THE STORE'S "COMING SOON", and the question underneath it.
   His note: "Its not currently set up as a waitlist in my opinion.. make it a
   'Coming Soon' and instead of just asking for email maybe also ask what they
   want". The heading carries the status so the page states its own condition
   before anyone reads a word of copy. */
.soon { color: var(--orange); white-space: nowrap; }
.signup-block { display: block; }
.signup-row { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
.want { border: 1px solid var(--rule); padding: 12px 14px; margin: 0 0 14px; }
.want legend {
  font-family: var(--mono); font-size: 10px; font-weight: 600;
  letter-spacing: .08em; text-transform: uppercase; padding: 0 6px;
}
/* Stacked, not inline: four options wrapping mid-label read as one run-on
   sentence, and the whole point is that each one is a separate answer. */
.want-opt { display: block; margin: 6px 0; font-size: 14px; cursor: pointer; }
.want-opt input { margin-right: 8px; }
