/* ============================================================================
   OPTION C — "SIGNAL"
   The site as a confident consultancy brand. Warm ground, large type, real
   whitespace, copper used as a deliberate accent rather than a rule color.
   Revised: the marketing-pill eyebrows are gone, replaced by a monospace
   section marker with a copper rule; card shadows are gone in favor of a
   crisp warm hairline (printed report, not floating SaaS card); the 0–4 scale
   is a real ramp; vertical rhythm tightened to cut roughly a page-and-a-half
   off the phone scroll. Mobile-first. Navigation is a fixed bottom tab bar in
   the thumb zone on phones, promoted to a top nav from 48rem. No JavaScript.
   ========================================================================== */

/* ---------- fonts ----------
   Self-hosted, so the page contacts nobody. These are the Google Fonts builds
   of three OFL families, unmodified; the license they are served under is at
   /assets/fonts-LICENSE.txt, which is a condition of serving them, not a
   courtesy. Each is a variable font covering the weights the site uses, so one
   file per subset replaces five static weights.
   unicode-range means a browser fetches latin-ext only if the page needs it,
   which for English copy it never does. */
@font-face {
  font-family: 'Archivo';
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url(archivo-latin.7150c0ec5a.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Archivo';
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url(archivo-latin-ext.a999e009fd.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Syne';
  font-style: normal;
  font-weight: 700 800;
  font-display: swap;
  src: url(syne-latin.cfff412005.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Syne';
  font-style: normal;
  font-weight: 700 800;
  font-display: swap;
  src: url(syne-latin-ext.79bc839264.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url(jetbrains-mono-latin.2c32b9b3ee.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url(jetbrains-mono-latin-ext.9c38cb2d0d.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

:root {
  --paper:   #FBFAF7;
  --wash:    #F2EFE8;
  /* The hairline is the design: cards, ledger rows, datasheet rows and section
     breaks are all it. At #D8CFBE it measured 1.48:1 on paper and 1.55:1 on a
     white card — below the threshold where a 1px line survives a 1x screen in
     daylight, so the "printed report" reading collapsed into floating text.
     1.80:1 / 1.88:1 is a line you can see without turning the page into a grid. */
  --line:    #C8BCA5;
  --hair:    #948871;
  --ink:     #14181D;
  --ink-2:   #333C46;
  --slate:   #55606B;
  --copper:  #A85C36;   /* fills, bars, the logo mark */
  --copper-d:#8F4A28;   /* copper as TEXT — 6.3:1 on paper */

  --ground:  var(--paper);
  --surface: #FFFFFF;
  --raised:  var(--wash);
  --text:    var(--ink);
  --text-2:  var(--ink-2);
  --muted:   var(--slate);
  --rule:    var(--line);
  --rule-hi: var(--hair);
  --edge:    var(--hair);
  --accent:  var(--copper);
  --accent-ink: var(--copper-d);
  --accent-wash: rgba(168, 92, 54, 0.08);
  --mark-bar: var(--ink);
  --on-accent: #FFFFFF;
  --focus:   var(--ink);
  --shadow: 0 1px 2px rgba(20,24,29,0.04), 0 8px 24px -16px rgba(20,24,29,0.28);

  --f-display: "Syne", "Trebuchet MS", sans-serif;
  --f-body: "Archivo", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --f-mono: "JetBrains Mono", ui-monospace, "SF Mono", Menlo, Consolas, monospace;

  --measure: 35rem;
  --page: 70rem;
  --gutter: 1.35rem;
  --tap: 48px;
  --r: 7px;
  --tabbar: 60px;
  /* The desktop masthead band. .head-bar and the nav that overlays it read the
     same token so the two can never drift out of alignment. */
  --headbar: 72px;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --ground: #14181D; --surface: #1C2128; --raised: #20262E;
    --text: #F0ECE5; --text-2: #D6D1C9; --muted: #A3ADB8;
    /* was #333B45 — 1.43:1 on a surface card, fainter than the light theme's
       already-too-faint line. #414C59 is 2.04:1 on ground, 1.85:1 on surface. */
    --rule: #414C59; --rule-hi: #6B7887; --edge: #6B7887;
    --accent: #DE8858; --accent-ink: #E9A075; --accent-wash: rgba(222, 136, 88, 0.13);
    --mark-bar: #F0ECE5; --on-accent: #14181D; --focus: #F0ECE5;
    --shadow: 0 1px 2px rgba(0,0,0,0.3), 0 10px 28px -18px rgba(0,0,0,0.75);
  }
}
:root[data-theme="dark"] {
  --ground: #14181D; --surface: #1C2128; --raised: #20262E;
  --text: #F0ECE5; --text-2: #D6D1C9; --muted: #A3ADB8;
  --rule: #414C59; --rule-hi: #6B7887; --edge: #6B7887;
  --accent: #DE8858; --accent-ink: #E9A075; --accent-wash: rgba(222, 136, 88, 0.13);
  --mark-bar: #F0ECE5; --on-accent: #14181D; --focus: #F0ECE5;
  --shadow: 0 1px 2px rgba(0,0,0,0.3), 0 10px 28px -18px rgba(0,0,0,0.75);
}

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

body {
  margin: 0; background: var(--ground); color: var(--text);
  font-family: var(--f-body); font-size: 1.075rem; line-height: 1.56;
  -webkit-font-smoothing: antialiased;
  /* + 0.6rem so the last line of the footer clears the bar rather than
     touching it, and so a bar that grows by a pixel never covers content. */
  padding-bottom: calc(var(--tabbar) + 0.6rem + env(safe-area-inset-bottom));
}
@media (min-width: 48rem) { body { padding-bottom: 0; } }

a { color: var(--accent-ink); text-decoration-thickness: 1px; text-underline-offset: 3px; }
a:hover { color: var(--text); }
:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; border-radius: 3px; }

.skip { position: absolute; left: -9999px; top: 0; z-index: 100;
  background: var(--accent); color: var(--on-accent);
  padding: 0.9rem 1.2rem; font-weight: 700; text-decoration: none;
  border-radius: 0 0 var(--r) 0; }
.skip:focus { left: 0; }

h1, h2, h3 { font-family: var(--f-display); font-weight: 800; margin: 0;
  text-wrap: balance; letter-spacing: -0.022em; }
h1 { font-size: clamp(2.05rem, 8.6vw, 3.3rem); line-height: 1.04; }
h2 { font-size: clamp(1.5rem, 5.6vw, 2.1rem); line-height: 1.12; }
h3 { font-family: var(--f-body); font-weight: 700; font-size: 1.06rem;
  line-height: 1.32; letter-spacing: 0; }
p { margin: 0; }

.wrap { width: 100%; max-width: var(--page); margin-inline: auto; padding-inline: var(--gutter); }
@media (min-width: 40rem) { :root { --gutter: 2.25rem; } }
@media (min-width: 64rem) { :root { --gutter: 3rem; } }
.measure { max-width: var(--measure); }

/* ---------- logo ---------- */
/* .lockup-svg carries no width/height attributes: this height rule is the only
   thing sizing the mark. Never remove or zero it. */
.lockup { display: inline-flex; align-items: center; text-decoration: none;
  line-height: 0; min-height: 44px; }
.lockup-svg { height: 3em; width: auto; display: block; }
.lockup--sm { font-size: 14px; }
.lockup--xs { font-size: 13px; }
@media (min-width: 40rem) { .lockup--sm { font-size: 15px; } }

/* ---------- header ---------- */
/* On phones the header carries the lockup and nothing else — navigation lives
   in the tab bar at the other end of the screen. A sticky bar that holds no
   control is 58px of a 844px viewport spent on a logo: with the tab bar that
   is 14% of every screen of a 8,600px page. So it scrolls away on phones and
   only becomes sticky from 48rem, where it is actually carrying the nav.
   position: relative is kept so the absolutely-positioned desktop nav always
   has a containing block. */
.site-head { background: var(--ground); position: relative; z-index: 20;
  border-bottom: 1px solid var(--rule); }
@media (min-width: 48rem) { .site-head { position: sticky; top: 0; } }
.head-bar { display: flex; align-items: center; justify-content: space-between;
  gap: 1rem; min-height: 58px; }

/* mobile: fixed bottom tab bar in the thumb zone */
.nav {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 30;
  background: var(--surface); border-top: 1px solid var(--edge);
  padding-bottom: env(safe-area-inset-bottom);
  box-shadow: 0 -6px 20px -14px rgba(20,24,29,0.35);
}
/* Six tabs since the blog joined the nav. "Engagements" is the widest label and
   the bar must not grow a second line: at six columns a 390px phone gives each
   tab about 65px, so the label steps down twice on the way to 320px. Measured
   in a browser at 320, 360 and 390 — not estimated. */
.nav-rail { display: grid; grid-template-columns: repeat(6, 1fr); gap: 0;
  padding-inline: 0; }
.nav a {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  min-height: var(--tabbar); padding: 0.3rem 0.12rem;
  font-size: 0.71rem; font-weight: 600; letter-spacing: -0.008em;
  color: var(--text); text-decoration: none; text-align: center;
  border-top: 3px solid transparent;
}
/* Below 22rem "Engagements" is the widest label and would wrap, growing the
   bar past --tabbar and eating the bottom of the footer. Shrink the label
   rather than let the bar grow past the space the body reserved for it. */
@media (max-width: 26rem) { .nav a { font-size: 0.63rem; letter-spacing: -0.02em; } }
@media (max-width: 22rem) { .nav a { font-size: 0.56rem; } }
.nav a .tab-l { display: block; line-height: 1.2; }
.nav a[aria-current] { color: var(--accent-ink); border-top-color: var(--accent);
  background: var(--accent-wash); font-weight: 700; }

/* From 48rem the tab bar becomes a top nav laid over the sticky masthead. The
   nav box is click-through (pointer-events) so it can never swallow the logo
   link, and it right-aligns inside the same --page grid as the header, so it
   sits beside the wordmark at every width instead of only one.

   It is anchored with position: fixed, NOT position: absolute. <nav class="nav">
   is a SIBLING that follows </header> — it is not inside .site-head — so
   `position: absolute; inset: 0` had no positioned ancestor to resolve against
   and fell back to the initial containing block: a full-viewport box. With
   align-items: center that parked the five links halfway down the first screen
   (y=376 at 1024x800, y=426 at 1280x900, y=488 at 768x1024), floating over the
   hero copy, and — because an absolutely positioned box scrolls with the
   document — sent them off the top of the window the moment the page moved,
   leaving the sticky header carrying nothing but the logo. Every width from
   48rem up had no navigation at all below the first screen.

   fixed + top:0 is what the "laid over the sticky header" intent needed: it is
   out of flow (so it cannot displace <main>, which is why a negative margin was
   rejected) and it is viewport-anchored (so it tracks the sticky header instead
   of scrolling away). Height is --headbar, the same token .head-bar uses, so
   the links center on the wordmark. z-index must clear .site-head's 20 — the
   header paints an opaque --ground background and would otherwise cover it. */
@media (min-width: 48rem) {
  .site-head .head-bar { min-height: var(--headbar); }
  .nav { position: fixed; top: 0; left: 0; right: 0; bottom: auto;
    height: var(--headbar); z-index: 25; pointer-events: none;
    display: flex; align-items: center;
    background: none; border-top: 0; box-shadow: none; padding-bottom: 0; }
  .nav-rail { display: flex; justify-content: flex-end; gap: 0.2rem; width: 100%;
    padding-inline: var(--gutter); max-width: var(--page); margin-inline: auto; }
  .nav a { pointer-events: auto;
    flex-direction: row; min-height: var(--tap); padding: 0 0.8rem;
    font-size: 0.88rem; font-weight: 600; letter-spacing: 0;
    color: var(--text); border-top: 0; border-radius: var(--r); background: none; }
  .nav a:hover { color: var(--accent-ink); background: var(--raised); }
  .nav a[aria-current] { background: var(--accent-wash); color: var(--accent-ink);
    box-shadow: inset 0 -2px 0 var(--accent); }
}

/* ---------- sections ---------- */
main { display: block; }
section { padding-block: clamp(2.5rem, 8vw, 4.75rem); }
section + section { border-top: 1px solid var(--rule); }
.hero { padding-block: clamp(2.25rem, 7.5vw, 4.25rem); }

.stack { display: flex; flex-direction: column; gap: 1.1rem; align-items: flex-start; }
.stack.tight { gap: 0.65rem; }
.stack.loose { gap: 1.75rem; }
.cta-stack { gap: 1.1rem; }

/* The lede is the sentence that answers "is this for me". It was the palest
   text on the first screen; --muted is a caption color, not a promise
   color. Promoted to --text-2 (about 10:1 on paper). */
.lede { font-size: clamp(1.1rem, 4.25vw, 1.3rem); line-height: 1.47; color: var(--text-2);
  max-width: 41rem; }
.body-copy { color: var(--text-2); }
.body-copy strong { color: var(--text); font-weight: 600; }

/* ---------- a heading inside running prose ----------
   Every other h3 on this site lives inside a card or a numbered ledger row,
   where the container's edge supplies the hierarchy and 1.06rem body-bold is
   plenty. The study's "What we found" is the one h3 standing bare in prose,
   and there it was 1.06rem against 1.075rem body text with 1.75rem above it —
   the same size as the paragraph it introduces, separated by barely more than
   one line of leading. It read as a bolded run-in, so the h2/h3 pair on that
   page read as an accident rather than as two levels. A rule above and a real
   size step make the sub-part deliberate. The rule is the pattern already used
   for stacked disclosures in .panel, not a new device.
   Scoped to a direct child of .stack, which no card or ledger h3 ever is. */
.stack > h3 {
  width: 100%; max-width: var(--measure);
  font-size: 1.2rem; line-height: 1.3; letter-spacing: -0.006em;
  padding-top: 1.5rem; border-top: 1px solid var(--rule);
}

/* ---------- section marker ----------
   Was a soft wash pill. Thirty-seven of them across five pages made the site
   read as template marketing; a mono label on a copper rule reads as a label
   on a document, which is the brand. */
.eyebrow {
  display: inline-flex; align-items: center; gap: 0.65rem;
  font-family: var(--f-mono);
  font-size: 0.7rem; font-weight: 600; letter-spacing: 0.13em;
  text-transform: uppercase; color: var(--accent-ink); margin: 0;
  background: none; padding: 0; border-radius: 0;
}
.eyebrow::before { content: ""; flex: none; width: 1.35rem; height: 2px;
  background: var(--accent); }
.eyebrow.plain { color: var(--muted); background: none; }
.eyebrow.plain::before { background: var(--edge); }

/* ---------- buttons ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 0.6rem;
  min-height: 52px; padding: 0.85rem 1.6rem;
  background: var(--accent); color: var(--on-accent);
  border: 1px solid var(--accent); border-radius: var(--r); text-decoration: none;
  font-weight: 700; font-size: 1rem; box-shadow: none;
}
.btn:hover { background: var(--accent-ink); border-color: var(--accent-ink);
  color: var(--on-accent); }
/* Every ghost button on this site is the route from a claim to the evidence
   behind it ("See what is in the engagement", "Read the method", "All eight,
   in full"). A gray hairline made them read as afterthoughts; copper marks
   them as the proof path without competing with the one solid CTA. */
.btn.ghost { background: transparent; color: var(--accent-ink);
  border-color: var(--accent); }
.btn.ghost:hover { border-color: var(--accent-ink); color: var(--text);
  background: var(--accent-wash); }
.btn-row { display: flex; flex-wrap: wrap; gap: 0.75rem; }
@media (max-width: 26rem) { .btn { width: 100%; } }

/* ---------- grids: flat, ruled cards ---------- */
/* Eight audience cards stacked on a phone is a wall. Tighter gap and padding
   below 44rem takes roughly a screen and a half off the home page without
   giving up the ruled-card reading. */
.grid { display: grid; gap: 0.65rem; }
.grid > * { background: var(--surface); border: 1px solid var(--rule);
  border-radius: var(--r); padding: clamp(1rem, 4vw, 1.55rem); box-shadow: none; }
@media (min-width: 44rem) { .grid { gap: 0.85rem; } }
@media (min-width: 44rem) {
  .g2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .g3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
.card .eyebrow { margin-bottom: 0.6rem; }
.card h3 { margin-bottom: 0.4rem; }
.card p { color: var(--text-2); font-size: 0.97rem; }

.cols { display: grid; gap: 1.5rem; grid-template-columns: minmax(0, 1fr); }
@media (min-width: 60rem) {
  .cols { gap: 3.5rem; }
  .cols.side { grid-template-columns: 10.5rem minmax(0, 1fr); gap: 0 2.5rem; }
  /* the empty rail becomes a deliberate margin note, not dead space */
  .cols.side > * + * { border-left: 1px solid var(--rule); padding-left: 2.5rem; }
}

/* ---------- numbered list as ledger rows ---------- */
.deliverables { list-style: none; padding: 0; margin: 0; display: grid; gap: 0.7rem; }
.deliverables li {
  display: grid; grid-template-columns: 2.5rem minmax(0, 1fr); gap: 0 1rem;
  padding: 1rem 1.15rem; background: var(--surface);
  border: 1px solid var(--rule); border-radius: var(--r);
}
/* The tag column gets a full-height hairline, so D1–D5 and the eight values
   read as the numbered schedule of a document rather than as five cards that
   happen to start with a number. */
.deliverables .tag {
  font-family: var(--f-mono); font-weight: 600; color: var(--accent-ink);
  font-size: 0.92rem; line-height: 1.32; padding: 0.06rem 0.9rem 0 0;
  border-right: 1px solid var(--rule);
  font-variant-numeric: tabular-nums; letter-spacing: 0.02em;
}
.deliverables h3 { margin-bottom: 0.25rem; }
.deliverables p { color: var(--text-2); font-size: 0.96rem; }

/* ---------- bulleted list ---------- */
.plain-list { list-style: none; padding: 0; margin: 0;
  display: flex; flex-direction: column; gap: 0.9rem; }
.plain-list li { padding-left: 1.5rem; position: relative; color: var(--text-2); }
.plain-list li::before { content: ""; position: absolute; left: 0; top: 0.6em;
  width: 0.5rem; height: 0.5rem; border-radius: 50%;
  background: var(--accent); }
.plain-list strong { color: var(--text); font-weight: 700; }
/* Every item in these lists opens with a bolded term and then explains it.
   Inline, the seven commitments and the five confidentiality promises are a
   wall of gray a phone reader skips; as term-over-definition they can be
   scanned in the order a buyer actually reads them, which is terms first. */
.plain-list li > strong:first-child { display: block; margin-bottom: 0.15rem;
  line-height: 1.34; }

/* ---------- 0–4 scale ----------
   A real ramp. Every rung is now visible (the track was 1.29:1 against the
   ground) and the fourth step reads as the top of a climb rather than a
   detached copper lozenge. */
.scale { display: flex; gap: 0.4rem; align-items: stretch; width: 100%; max-width: 30rem; }
.scale .step { flex: 1; display: grid; grid-template-rows: auto 3.1rem auto; gap: 0.45rem; }
.scale .bar { align-self: end; width: 100%; background: var(--edge);
  border-radius: 2px; height: 0.45rem; }
.scale .step:nth-child(2) .bar { height: 1.05rem; }
.scale .step:nth-child(3) .bar { height: 1.7rem; }
.scale .step:nth-child(4) .bar { height: 2.35rem; }
.scale .step:nth-child(5) .bar { height: 3.1rem; }
.scale .step.on .bar { background: var(--accent); }
.scale .n { font-family: var(--f-mono); font-weight: 600; font-size: 0.92rem;
  color: var(--muted); font-variant-numeric: tabular-nums; }
.scale .step.on .n { color: var(--accent-ink); }
.scale .lbl { font-family: var(--f-mono); font-size: 0.62rem; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--muted); font-weight: 600; white-space: nowrap; }
.scale .step:first-child .lbl { text-align: left; }
.scale .step.on .lbl { color: var(--text); }
.scale .step:last-child .lbl { text-align: right; }

/* ---------- chips ---------- */
.chips { display: flex; flex-wrap: wrap; gap: 0.45rem; padding: 0; margin: 0; list-style: none; }
/* The seven frameworks are the single most-checked proof on the services page
   — a reviewer looks for their own framework by name. They were the palest
   thing on it. Mono, full ink, a firmer edge. */
.chips li { font-family: var(--f-mono); font-size: 0.72rem; font-weight: 600;
  letter-spacing: 0.01em; color: var(--text);
  border: 1px solid var(--edge); background: var(--surface);
  padding: 0.5rem 0.7rem; border-radius: var(--r); }

/* ---------- panel ---------- */
.panel { background: var(--raised); border: 1px solid var(--rule);
  border-radius: var(--r); padding: clamp(1.3rem, 5vw, 2.1rem); }
/* .panel.accent is the "what happens first" block, and on the engagements
   page it is the last thing on a 6,200px scroll. It has to look like the
   end of the road, not another aside. */
.panel.accent { background: var(--surface); border-color: var(--edge);
  border-left: 5px solid var(--accent); }
.panel.accent .panel-h { color: var(--text); }
.panel .panel-h { font-size: clamp(1.25rem, 4.6vw, 1.45rem); margin-bottom: 0.7rem; }
.panel .panel-eyebrow { margin-bottom: 0.85rem; }
.panel .btn-row { margin-top: 1.3rem; }
.panel p { color: var(--text-2); }
.panel p + p { margin-top: 0.85rem; }
/* The disclosure panels are three separate named disclosures run together as
   one gray block, which is exactly how boilerplate is written and exactly how
   it is skipped. Voluntarily declaring a conflict is a credibility asset for
   this firm, so the three names get to be visible. */
.panel .fineprint > strong:first-child { display: block; color: var(--text);
  font-size: 0.92rem; margin-bottom: 0.1rem; }
.panel .fineprint + .fineprint { margin-top: 1.05rem; padding-top: 1.05rem;
  border-top: 1px solid var(--rule); }

.fineprint { font-size: 0.87rem; line-height: 1.58; color: var(--muted); }
.fineprint strong { color: var(--text); }
/* The boxed, copper-edged .hero .fineprint was built for the home page's
   "Fixed fee. Three to four weeks." — a concrete commitment that earned terms-
   of-business styling. That line has since been cut, and the only .hero
   .fineprint left on the site is "Last reviewed 30 August 2026." on the
   security page. Shrink-wrapping was not enough: it still made a maintenance
   date the loudest, most structured object in that hero, louder than the
   p=reject / security.txt sentence directly above it, which is the actual
   checkable evidence and the entire point of the page. A review date is
   metadata. It gets metadata styling. If a hero ever carries a real commitment
   again, .status-strip is the class for it — it already renders exactly the
   box this rule used to. */
.hero .fineprint { font-size: 0.9rem; }

/* A body paragraph closing a hero — the home page's practitioner byline. Set
   in the same face, size and color as the lede three items above it and hung
   off the same 1.1rem stack gap as everything else, it read as a fourth
   paragraph of hero copy that had fallen out of the lede, and it ran five
   lines on a phone: the hero ended on gray prose instead of on the action.
   A rule and a step down make it a credential line under the CTAs, which is
   what it is. :last-child keeps it off the security hero, where the equivalent
   paragraph is evidence, not a signature, and is followed by the review date. */
.hero .body-copy:last-child {
  width: 100%; max-width: var(--measure);
  margin-top: 0.55rem; padding-top: 1.25rem;
  border-top: 1px solid var(--rule);
  font-size: 0.97rem; line-height: 1.54;
}

/* ---------- definition rows ---------- */
/* ---------- definition rows ----------
   These carry the densest evidence on the site — the study's population and
   method, the control list on the security page. Bold-label-over-body-text
   made them read as prose in a box. A mono uppercase label against a full-ink
   value reads as a datasheet row, which is what a reviewer is scanning for. */
.kv { display: grid; grid-template-columns: minmax(0,1fr); gap: 0.5rem; margin: 0; }
.kv div { display: grid; grid-template-columns: minmax(0,1fr); gap: 0.3rem;
  padding: 0.85rem 1.1rem; background: var(--surface); border: 1px solid var(--rule);
  border-radius: var(--r); font-size: 0.96rem; }
.kv dt { font-family: var(--f-mono); font-size: 0.68rem; font-weight: 600;
  letter-spacing: 0.11em; text-transform: uppercase; color: var(--muted); margin: 0; }
.kv dd { margin: 0; color: var(--text); line-height: 1.5; }
@media (min-width: 46rem) {
  .kv div { grid-template-columns: 11rem minmax(0,1fr); gap: 1.5rem; align-items: baseline; }
}

/* Publication status is the study's credibility in one line: it says the
   author notified the companies before publishing. It was a soft wash pill
   among other soft wash pills; given a copper edge it reads as a stamp on a
   record. */
.status-strip { display: flex; align-items: flex-start; gap: 0.65rem;
  border: 1px solid var(--rule); border-left: 3px solid var(--accent);
  background: var(--raised);
  padding: 0.7rem 1rem; border-radius: 0 var(--r) var(--r) 0; font-size: 0.88rem;
  line-height: 1.44; color: var(--text); font-weight: 600; max-width: 34rem; }
.status-strip .dot { width: 0.5rem; height: 0.5rem; background: var(--accent);
  border-radius: 50%; flex: none; margin-top: 0.42em; }

pre.txt { background: var(--surface); border: 1px solid var(--rule);
  border-radius: var(--r); padding: 1rem; overflow-x: auto; font-size: 0.8rem;
  line-height: 1.6; margin: 0; font-family: var(--f-mono); color: var(--text); }

/* ---------- footer ---------- */
.site-foot { border-top: 1px solid var(--rule); background: var(--raised);
  padding-block: 2.5rem; }
.foot-grid { display: grid; gap: 1.9rem; }
@media (min-width: 52rem) { .foot-grid { grid-template-columns: 1.4fr 1fr 1fr; gap: 3rem; } }
.foot-blurb { margin-top: 1rem; max-width: 25rem; }
.foot-h { font-family: var(--f-mono); font-size: 0.68rem; letter-spacing: 0.13em;
  text-transform: uppercase; color: var(--muted); margin: 0 0 0.5rem; font-weight: 600; }
.site-foot ul { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; }
.site-foot ul a { display: flex; align-items: center; min-height: 44px;
  color: var(--text); text-decoration: none; font-size: 0.95rem; }
.site-foot ul a:hover { color: var(--accent-ink); }
/* Home, about and security all end in the footer with no closing action in
   the copy. The contact addresses are the only thing there a reader can act
   on, so they are given the weight of an action instead of sitting at the
   same value as a sitemap link. */
.site-foot ul a[href^="mailto:"] { font-weight: 700; color: var(--accent-ink); }
.colophon { margin-top: 2rem; padding-top: 1.2rem; border-top: 1px solid var(--rule);
  font-size: 0.8rem; color: var(--muted); display: flex; flex-wrap: wrap;
  align-items: center; gap: 0.4rem 1.5rem; }

/* ---------- the LinkedIn mark in the colophon ----------
   LinkedIn's own [in] asset, downloaded from brand.linkedin.com/downloads and
   shipped unmodified. Their guidelines prohibit changing the color or the shape
   of the mark, so unlike the lockup it cannot take var(--accent): the approved
   black and white variants swap with the color scheme instead. Do not recolor
   these, do not redraw them, and do not replace them with a lookalike glyph.
   The mark is 24px; the link is padded to 44px for the touch target (rule 8). */
.colophon-social { margin-left: auto; }
.colophon-social a { display: inline-flex; align-items: center; justify-content: center;
  min-width: 44px; min-height: 44px; }
.li-mark { display: block; height: 24px; width: auto; }
.li-mark--dark { display: none; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .li-mark--light { display: none; }
  :root:not([data-theme="light"]) .li-mark--dark { display: block; }
}
:root[data-theme="dark"] .li-mark--light { display: none; }
:root[data-theme="dark"] .li-mark--dark { display: block; }

/* ---------- blog ----------
   The films are square, 1080x1080, cut for LinkedIn. The poster is the same
   still the post carried, so the card and the entry show the same frame.
   No autoplay and preload="none": the film is the point of the page but it is
   8MB, and nobody asked for it on arrival. */
.entry-list { list-style: none; padding: 0; margin: 0; display: grid; gap: 0.85rem;
  width: 100%; }
@media (min-width: 44rem) { .entry-list { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
/* The whole card is the tap target: the title's link is stretched over it.
   WARNING FOR WHOEVER ADDS TO A CARD NEXT: this forecloses a second link
   inside it. The series label is plain text for exactly this reason — a link
   there would sit under the overlay and be reachable by keyboard only. If a
   card ever needs two destinations, this rule comes out and the card gets a
   different pattern. */
.entry-card { background: var(--surface); border: 1px solid var(--rule);
  border-radius: var(--r); overflow: hidden; position: relative;
  display: flex; flex-direction: column; }
.entry-card h2 a::after { content: ""; position: absolute; inset: 0; }
/* The ring goes on the card, not on 140px of title, because the card is what
   you are activating. outline-offset is negative on purpose: .entry-card has
   overflow: hidden, which clips an outset ring. :has() is Baseline; where it is
   missing the title's own ring still shows, so it degrades rather than breaks.
   Not :focus-within — that cannot tell a keyboard from a tap, and would flash
   the ring on every touch. */
.entry-card:has(a:focus-visible) { outline: 3px solid var(--focus);
  outline-offset: -3px; }
/* The still leads the card, full width, 16:9. Three specifications in one day
   got here: a full-width 1080px square of the shared end card (the least
   informative thing on the card, and the largest), then no image, then an 88px
   square of the same end card. The rule that came out of it, worth keeping:
   a thumbnail that is the same on every card carries nothing, and a thumbnail
   too small to read carries nothing. It has to be distinct and large enough, or
   it should not be there.
   These are real frames, one per film, each carrying that film's own line. The
   timecode is recorded in the entry's front matter and the still is regenerated
   with tools/film-still.swift, so it is reproducible rather than a one-off.
   1080x608 is the widest true 16:9 crop of a 1080x608 source — see CLAUDE.md. */
.entry-still { display: block; width: 100%; height: auto; aspect-ratio: 16 / 9;
  object-fit: cover; border-bottom: 1px solid var(--rule); }
.entry-card-body { display: flex; flex-direction: column; gap: 0.3rem;
  align-items: flex-start; min-width: 0; padding: clamp(1rem, 4vw, 1.4rem); }
/* Label, then title, then date, then excerpt. The top line of a card is the
   most-scanned pixel on it, and with a title like "The question" the series
   label carries more than the date does. */
.entry-label { font-family: var(--f-mono); font-size: 0.68rem; font-weight: 600;
  letter-spacing: 0.11em; text-transform: uppercase; color: var(--accent-ink); }
.entry-card h2 { font-size: 1.3rem; line-height: 1.16; }
/* The title looks like a link, which is the only "this is clickable" cue a
   phone gets — there is no hover there. It also carries the 44px target. */
.entry-card h2 a { display: flex; align-items: center; min-height: 44px;
  color: var(--accent-ink); text-decoration: underline;
  text-decoration-thickness: 1px; text-underline-offset: 3px; }
.entry-card h2 a:hover { color: var(--text); text-decoration-thickness: 2px; }
.entry-excerpt { color: var(--text-2); font-size: 0.97rem; }
.entry-date, .entry-meta { font-family: var(--f-mono); font-size: 0.68rem;
  font-weight: 600; letter-spacing: 0.11em; text-transform: uppercase;
  color: var(--muted); }

.entry-film { display: block; width: 100%; max-width: 32rem; height: auto;
  aspect-ratio: 1 / 1; background: var(--ink);
  border: 1px solid var(--rule); border-radius: var(--r); }
.entry-body { display: flex; flex-direction: column; gap: 1.1rem;
  max-width: var(--measure); }
.entry-body p { color: var(--text-2); }
/* The closing line of every entry is the same standing sentence about the
   study. It is a footnote to the piece, not part of the argument. */
.entry-body .entry-note { padding-top: 1.25rem; border-top: 1px solid var(--rule);
  font-size: 0.97rem; }

/* Notes — Chicago style, first used by "The rule you can delete" (23 September
   2026). Anchors and CSS only: the CSP forbids script, and none is needed.
   The reference is a superscript numeral inside a sentence, so SC 2.5.8's
   inline exception covers its size; the back-links at the foot are not in a
   sentence, so they carry the full 44px. Copper as text is --accent-ink, never
   --accent: a small superscript in the wrong copper is the shape that failed an
   audit here before. */
.fn-ref { font-size: 0.7em; line-height: 0; vertical-align: super; }
.fn-ref a { color: var(--accent-ink); text-decoration: underline;
  text-decoration-thickness: 1px; text-underline-offset: 2px; padding-inline: 0.15em; }
.fn-ref a:hover { color: var(--text); text-decoration-thickness: 2px; }
.notes-head { font-family: var(--f-display); font-size: 1.05rem; color: var(--text);
  margin: 0.75rem 0 0.4rem; padding-top: 1.25rem; border-top: 1px solid var(--rule);
  max-width: var(--measure); }
.notes { max-width: var(--measure); margin: 0; padding-left: 1.5rem;
  display: grid; gap: 0.7rem; color: var(--text-2); font-size: 0.92rem; }
.notes li { line-height: 1.5; }
/* A URL with no spaces will not wrap on a 320px phone without this. */
.notes a { overflow-wrap: anywhere; }
.note-back { display: inline-flex; align-items: center; justify-content: center;
  min-width: 44px; min-height: 44px; margin-left: 0.15rem;
  color: var(--accent-ink); text-decoration: none; }
.note-back:hover { color: var(--text); }
.note-back-letter { font-size: 0.8em; margin-left: 0.1em; }

/* The foot of an entry — third pass, 22 September 2026, and the shape it
   landed on is the index's own card. The first pass was a pair of bordered
   cards that read as a callout; the second took the border off and read as more
   paragraphs, because the eye segments a page by background changes and this
   page is one cream field. The border was the only affordance the component
   had, and it was never the height — the excerpts and padding were about 70% of
   it — so the card came back and the excerpt went.
   `.entry-card` is reused exactly as the index uses it, including its focus
   ring: one rendering of "a blog entry", not two. What is here is only the
   container, the heading and the stack.
   The nav shares the article's measure and edges. A block 2.3x the width of the
   text it follows cannot look subordinate to it — and the first two passes were
   emitted outside any .wrap, so they ran to the viewport edge. */
.entry-nav-section { padding-top: 0; }
.entry-nav { margin-top: 0.5rem; }
/* Not .foot-h. "MORE ENTRIES" in mono uppercase --muted is the footer's own
   heading treatment, one scroll-second above "SITE" and "CONTACT", so a reader
   scanning down met what looked like the first footer column and skipped it. */
.entry-nav-head { font-family: var(--f-display); font-size: 1.05rem;
  color: var(--text); margin-bottom: 0.55rem; }
/* Stacked, always: at the article's measure two columns are about 265px each
   and the headlines wrap to three lines. The dropped excerpts pay for it. */
.entry-nav-list { list-style: none; margin: 0 0 0.6rem; padding: 0;
  display: grid; gap: 0.6rem; }
.entry-nav-item .entry-card-body { padding: 0.7rem clamp(1rem, 4vw, 1.2rem); gap: 0.15rem; }
.entry-nav-item h2 { font-size: 1.15rem; }
.entry-nav-all { display: inline-flex; align-items: center; min-height: 44px;
  font-size: 0.92rem; color: var(--accent-ink); text-decoration: underline;
  text-decoration-thickness: 1px; text-underline-offset: 3px; }
.entry-nav-all:hover { color: var(--text); text-decoration-thickness: 2px; }

@media (prefers-reduced-motion: reduce) {
  * { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
}
