/* ── Archivo, self-hosted ───────────────────────────────────────────────────
   Was a stylesheet from fonts.googleapis.com, which is a render-blocking
   request to a third party that needs its own DNS lookup and TLS handshake
   before a single glyph can be asked for. Same files, served from this origin.

   VARIABLE, not the three static weights sitting in scripts/fonts for the card
   generator. The CSS here asks for 300, 400, 500, 600, 650 and 700, and 650 is
   the one that settles it: a static family can only synthesise it by smearing
   SemiBold, which is the kind of difference that shows up on a figure label and
   nowhere a reader could name. One axis only — nothing on this site sets
   font-stretch, so the wdth axis the old URL requested was never used.

   Subset by unicode-range exactly as Google served it, so a page of Latin text
   fetches the 34KB file and never asks for the other. The Vietnamese subset is
   not carried: this site has no Vietnamese in it, and a subset nothing matches
   is a file nobody fetches.

   OFL, same as upstream; the licence travels with the fonts in this directory.
   ───────────────────────────────────────────────────────────────────────── */
@font-face {
  font-family: 'Archivo';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('/assets/fonts/archivo-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Archivo';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('/assets/fonts/archivo-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* ═══════════════════════════════════════════════════════════════════════════
   Intrinsic Value Per Share — editorial design system
   Warm paper, serif prose, sans numerals. Charts are figures, not cards.
   ═══════════════════════════════════════════════════════════════════════════ */

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

/* ── Tokens: light (default) ──────────────────────────────────────────────── */
:root {
  color-scheme: light;

  /* Surfaces — warm paper */
  --paper:        #f6f4ef;  /* page plane, and the chart surface */
  --paper-raised: #fffefb;  /* pulled-out panels, tables */
  --paper-sunk:   #efece4;  /* wells, table stripes */

  /* Ink */
  --ink:      #15140f;
  --ink-2:    #504d44;
  --ink-3:    #857f72;
  --rule:     #ded9cd;      /* hairline rules, gridlines */
  --rule-firm: #c6c0b0;     /* axis / baseline */

  /* Accent — blue ramp step 550, dark enough for body text */
  --accent:      #1c5cab;
  --accent-soft: rgba(28, 92, 171, 0.09);

  /* Value buckets — ONE hue, three steps, ordered by liquidity.
     These three are not arbitrary categories: operating businesses are the
     least liquid thing Berkshire owns and cash the most, so the ramp encodes
     a real property rather than just telling the buckets apart.
     Validated as an ordinal ramp against --paper. */
  --bucket-operating:   #184f95;
  --bucket-investments: #3987e5;
  --bucket-cash:        #6da7ec;
  /* Ink for a label set ON each fill — picked by the fill's luminance, not by
     the theme, because the ramp's light end stays light in both themes. */
  --bucket-operating-ink:   #ffffff;
  --bucket-investments-ink: #ffffff;
  --bucket-cash-ink:        #0e2a4d;

  /* Categorical series — all cool. Slot order IS the stack order: the pairs
     that sit next to each other are the ones the validator checked.
     Validated categorical, light surface, adjacent pairlist. */
  --s1: #184f95;  /* deep blue  */
  --s2: #1baf7a;  /* teal       */
  --s3: #6da7ec;  /* light blue */
  --s4: #1d7a3a;  /* green      */

  /* Seven categorical colours, for the one chart form that must carry a line
     per company rather than a panel per company. The four --s slots above are
     deliberately close — two blues and two greens — because four series read
     better when they share a register. Seven do not: the auto-retail trends
     put seven retailers in one box, and four near-neighbours cannot separate
     them. So these are seven distinct hue families, still muted to the paper.
  
     No hue set can separate seven categories for a dichromat — red-green
     blindness collapses the wheel onto one blue-yellow axis, so beyond about
     four, lightness is the only hue-independent cue left. These were chosen
     against that: worst pair is dE 17.4 deuteranope / 16.5 protanope in light
     and 14.6 / 20.4 in dark, against 17.2 for the --s slots. Every line that
     uses them is endpoint-labelled with its ticker, so colour is the second
     cue and not the only one. Contrast against paper is >= 3:1 throughout.
     Check any change with scripts/palette-check.py before shipping it. */
  --c1: #184f95;  /* blue     */
  --c2: #199e70;  /* green    */
  --c3: #12808f;  /* teal     */
  --c4: #7a5a00;  /* ochre    */
  --c5: #b83232;  /* red      */
  --c6: #7a2a52;  /* mulberry */
  --c7: #3f3a33;  /* slate    */

  /* One brand colour, used once: the Wells Fargo line in the runoff chart,
     where the company's own red says "Wells Fargo" faster than a legend does.
     Not part of the categorical scale — never use it for an unrelated series. */
  --brand-wfc: #c9212b;

  /* Semantic value colors — diverging blue↔red, gray midpoint */
  --pos:  #1c5cab;
  --neg:  #c0392b;
  --mid:  #a9a394;
  /* Text sitting ON a --pos / --neg fill. Both fills are dark in this theme,
     so the label is paper; in dark mode both fills are light and it flips. */
  --pos-ink: #ffffff;
  --neg-ink: #ffffff;

  /* Scenario identity, used consistently on every chart */
  --sc-down: #c0392b;
  --sc-base: #1c5cab;
  --sc-up:   #157f5a;

  --shell: rgba(246, 244, 239, 0.86);

  /* Type */
  --serif: ui-serif, 'Iowan Old Style', 'Palatino Linotype', Palatino,
           Charter, Georgia, 'Times New Roman', serif;
  --sans:  Archivo, system-ui, -apple-system, 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;
  --mono:  ui-monospace, SFMono-Regular, 'SF Mono', Menlo, monospace;

  /* Measure */
  --prose: 40rem;    /* reading column */
  --wide:  66rem;    /* figures and tables break out to this */
  --t: 0.18s ease;
}

/* ── Tokens: dark ─────────────────────────────────────────────────────────── */
@media (prefers-color-scheme: dark) {
  :root:where(:not([data-theme='light'])) {
    color-scheme: dark;
    --paper:        #121210;
    --paper-raised: #1b1a17;
    --paper-sunk:   #090908;
    --ink:      #f4f2ec;
    --ink-2:    #b4b0a4;
    --ink-3:    #7d786c;
    --rule:     #2e2d28;
    --rule-firm: #45433c;
    --accent:      #6da7ec;
    --accent-soft: rgba(109, 167, 236, 0.13);
    --bucket-operating:   #256abf;
    --bucket-investments: #5598e7;
    --bucket-cash:        #9ec5f4;
    --bucket-operating-ink:   #ffffff;
    --bucket-investments-ink: #0e2a4d;
    --bucket-cash-ink:        #0e2a4d;
    --s1: #256abf;
    --s2: #199e70;
    --s3: #4a90e0;
    --s4: #3d9e37;

    /* Seven categorical colours, for the one chart form that must carry a line
       per company rather than a panel per company. The four --s slots above are
       deliberately close — two blues and two greens — because four series read
       better when they share a register. Seven do not: the auto-retail trends
       put seven retailers in one box, and four near-neighbours cannot separate
       them. So these are seven distinct hue families, still muted to the paper.
    
       No hue set can separate seven categories for a dichromat — red-green
       blindness collapses the wheel onto one blue-yellow axis, so beyond about
       four, lightness is the only hue-independent cue left. These were chosen
       against that: worst pair is dE 17.4 deuteranope / 16.5 protanope in light
       and 14.6 / 20.4 in dark, against 17.2 for the --s slots. Every line that
       uses them is endpoint-labelled with its ticker, so colour is the second
       cue and not the only one. Contrast against paper is >= 3:1 throughout.
       Check any change with scripts/palette-check.py before shipping it. */
    --c1: #256abf;  /* blue     */
    --c2: #1baf7a;  /* green    */
    --c3: #45b4c4;  /* teal     */
    --c4: #e5c070;  /* ochre    */
    --c5: #d06060;  /* red      */
    --c6: #bf6893;  /* mulberry */
    --c7: #c4c0b4;  /* slate    */
    --brand-wfc: #ef6f72;
    --pos:  #6da7ec;
    --neg:  #e06c5f;
    --mid:  #6b665c;
    --pos-ink: #0b2240;
    --neg-ink: #3a1009;
    --sc-down: #e06c5f;
    --sc-base: #6da7ec;
    --sc-up:   #3fb98a;
    --shell: rgba(18, 18, 16, 0.86);
  }
}
:root[data-theme='dark'] {
  color-scheme: dark;
  --paper:        #121210;
  --paper-raised: #1b1a17;
  --paper-sunk:   #090908;
  --ink:      #f4f2ec;
  --ink-2:    #b4b0a4;
  --ink-3:    #7d786c;
  --rule:     #2e2d28;
  --rule-firm: #45433c;
  --accent:      #6da7ec;
  --accent-soft: rgba(109, 167, 236, 0.13);
  --bucket-operating:   #256abf;
  --bucket-investments: #5598e7;
  --bucket-cash:        #9ec5f4;
  --bucket-operating-ink:   #ffffff;
  --bucket-investments-ink: #0e2a4d;
  --bucket-cash-ink:        #0e2a4d;
  --s1: #256abf;
  --s2: #199e70;
  --s3: #4a90e0;
  --s4: #3d9e37;

  /* Seven categorical colours, for the one chart form that must carry a line
     per company rather than a panel per company. The four --s slots above are
     deliberately close — two blues and two greens — because four series read
     better when they share a register. Seven do not: the auto-retail trends
     put seven retailers in one box, and four near-neighbours cannot separate
     them. So these are seven distinct hue families, still muted to the paper.
  
     No hue set can separate seven categories for a dichromat — red-green
     blindness collapses the wheel onto one blue-yellow axis, so beyond about
     four, lightness is the only hue-independent cue left. These were chosen
     against that: worst pair is dE 17.4 deuteranope / 16.5 protanope in light
     and 14.6 / 20.4 in dark, against 17.2 for the --s slots. Every line that
     uses them is endpoint-labelled with its ticker, so colour is the second
     cue and not the only one. Contrast against paper is >= 3:1 throughout.
     Check any change with scripts/palette-check.py before shipping it. */
  --c1: #256abf;  /* blue     */
  --c2: #1baf7a;  /* green    */
  --c3: #45b4c4;  /* teal     */
  --c4: #e5c070;  /* ochre    */
  --c5: #d06060;  /* red      */
  --c6: #bf6893;  /* mulberry */
  --c7: #c4c0b4;  /* slate    */
  --brand-wfc: #ef6f72;
  --pos:  #6da7ec;
  --neg:  #e06c5f;
  --mid:  #6b665c;
  --pos-ink: #0b2240;
  --neg-ink: #3a1009;
  --sc-down: #e06c5f;
  --sc-base: #6da7ec;
  --sc-up:   #3fb98a;
  --shell: rgba(18, 18, 16, 0.86);
}

/* ── Base ─────────────────────────────────────────────────────────────────── */
html { font-size: 17px; -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (max-width: 40rem) { html { font-size: 16px; } }

body {
  background: var(--paper);
  color: var(--ink);
  font-family: var(--serif);
  line-height: 1.62;
  min-height: 100vh;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; text-underline-offset: 0.18em; }

::selection { background: var(--accent-soft); }

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 2px;
}

.skip-link {
  position: absolute; left: -9999px;
  background: var(--paper-raised); color: var(--ink);
  padding: 0.6rem 1rem; z-index: 200; border: 1px solid var(--rule-firm);
}
.skip-link:focus { left: 1rem; top: 0.6rem; }

/* ── Shell: nav ───────────────────────────────────────────────────────────── */
.shell {
  position: sticky; top: 0; z-index: 60;
  background: var(--shell);
  backdrop-filter: saturate(170%) blur(14px);
  -webkit-backdrop-filter: saturate(170%) blur(14px);
  border-bottom: 1px solid var(--rule);
}
.shell-inner {
  max-width: var(--wide);
  margin: 0 auto;
  padding: 0 1.5rem;
  height: 3.4rem;
  display: flex; align-items: center; gap: 1.5rem;
}
.brand {
  font-family: var(--serif);
  font-size: 1.02rem;
  font-weight: 600;
  letter-spacing: -0.012em;
  color: var(--ink);
  white-space: nowrap;
  display: flex; align-items: center; gap: 0.55rem;
}
.brand:hover { text-decoration: none; color: var(--accent); }
/* The seal sits in the accent rather than the ink so it reads as a mark and
   not as the first letter of the name. It inherits nothing from .brand:hover —
   it is already accent, and flashing it on hover would be noise. */
.brand-seal {
  width: 1.9rem; height: 1.9rem;
  flex: none;
  color: var(--accent);
}
.brand-mark {
  font-family: var(--sans);
  font-size: 0.66rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  color: var(--ink-3);
  display: block;
  margin-top: -0.2rem;
}
.data-dl { display: flex; align-items: baseline; flex-wrap: wrap; gap: 0.5rem 0.9rem; }
.data-dl-note {
  font-family: var(--sans); font-size: 0.74rem; line-height: 1.45;
  color: var(--ink-3); max-width: 32rem;
}

/* The coverage sections. These sit LEFT, beside the brand, and carry a second
   line, because each one is a dozen pages and the utility links are one page
   each. Ranked beside "About" at the same weight they read as peers, which is
   the thing this is fixing. */
.shell-topics {
  list-style: none;
  display: flex; align-items: stretch; gap: 0.35rem;
  margin: 0 0 0 0.9rem; padding: 0;
  font-family: var(--sans);
}
/* The li stretches, so the card inside it has to as well, or the two cards
   end up different heights the moment one note wraps to a second line. */
.shell-topics li { display: flex; }
.shell-topics a {
  flex: 1;
  display: flex; flex-direction: column; justify-content: center;
  gap: 0.05rem;
  padding: 0.3rem 0.7rem;
  border-radius: 5px;
  border: 1px solid transparent;
  color: var(--ink);
  line-height: 1.15;
}
.shell-topics a:hover {
  text-decoration: none;
  background: var(--surface-2, rgba(0, 0, 0, 0.035));
  border-color: var(--rule);
}
.topic-label {
  font-size: 0.82rem; font-weight: 650; letter-spacing: -0.005em;
}
.topic-note {
  font-size: 0.63rem; font-weight: 500; letter-spacing: 0.02em;
  color: var(--ink-3);
  white-space: nowrap;
}
/* Current SECTION, not current page: the accent rule is the thing that says
   "you are inside this body of work" on all dozen of its pages. */
.shell-topics a[aria-current='true'] {
  background: var(--surface-2, rgba(0, 0, 0, 0.035));
  border-color: var(--rule);
  box-shadow: inset 2px 0 0 var(--accent);
}
.shell-topics a[aria-current='true'] .topic-label { color: var(--ink); }

.shell-nav {
  list-style: none;
  display: flex; align-items: center; gap: 1.35rem;
  margin-left: auto;
  font-family: var(--sans);
  font-size: 0.8rem;
}
.shell-nav a { color: var(--ink-2); letter-spacing: 0.005em; }
.shell-nav a:hover { color: var(--ink); text-decoration: none; }
.shell-nav a[aria-current='page'] { color: var(--ink); font-weight: 600; }
.shell-nav .soon { color: var(--ink-3); opacity: 0.55; pointer-events: none; }

.theme-btn {
  background: none; border: 1px solid var(--rule);
  color: var(--ink-2);
  width: 1.95rem; height: 1.95rem; border-radius: 50%;
  cursor: pointer; font-size: 0.85rem; line-height: 1;
  display: grid; place-items: center;
  transition: color var(--t), border-color var(--t);
  flex-shrink: 0;
}
.theme-btn:hover { color: var(--ink); border-color: var(--rule-firm); }

/* Segment sub-nav, used on deep dives */
.subnav {
  border-bottom: 1px solid var(--rule);
  overflow-x: auto;
  scrollbar-width: none;
  background: var(--paper);
  /* Without this an iOS swipe that starts in the bar is handed to the browser
     as a back-navigation once the bar reaches either end. */
  overscroll-behavior-x: contain;
  -webkit-overflow-scrolling: touch;
}
.subnav::-webkit-scrollbar { display: none; }
.subnav-inner {
  max-width: var(--wide); margin: 0 auto; padding: 0 1.5rem;
  display: flex; gap: 1.35rem; white-space: nowrap;
  font-family: var(--sans); font-size: 0.78rem;
}
.subnav a {
  color: var(--ink-2);
  padding: 0.7rem 0 calc(0.7rem - 2px);
  border-bottom: 2px solid transparent;
}
.subnav a:hover { color: var(--ink); text-decoration: none; }
.subnav a[aria-current='page'] {
  color: var(--ink); border-bottom-color: var(--accent); font-weight: 600;
}
.subnav .soon { color: var(--ink-3); opacity: 0.5; pointer-events: none; }

/* The collapsed sub-segment group. Written flat-first: by default the trigger
   is hidden and the group and its menu are `display: contents`, so the six
   links sit directly in the scrolling bar exactly as they used to. The
   dropdown is switched on only at the width where the bar has room for it,
   which also avoids every override an absolutely positioned menu would need
   inside `.subnav`'s overflow container. */
.subnav-group { display: contents; }
.subnav-trigger { display: none; }
.subnav-menu { display: contents; }

@media (min-width: 46rem) {
  .subnav { overflow: visible; }
  .subnav-group { position: relative; display: flex; }

  .subnav-trigger {
    display: inline-flex; align-items: center; gap: 0.32em;
    font: inherit; color: var(--ink-2);
    background: none; border: 0; cursor: pointer;
    padding: 0.7rem 0 calc(0.7rem - 2px);
    border-bottom: 2px solid transparent;
  }
  .subnav-trigger:hover { color: var(--ink); }
  /* The trigger stands in for whichever deep dive is open inside the menu. */
  .subnav-trigger[data-current='true'] {
    color: var(--ink); border-bottom-color: var(--accent); font-weight: 600;
  }
  .subnav-caret { font-size: 0.72em; transition: transform 0.15s ease; }
  .subnav-group:hover .subnav-caret,
  .subnav-group:focus-within .subnav-caret { transform: rotate(180deg); }

  .subnav-menu {
    position: absolute; top: 100%; left: -0.95rem; z-index: 40;
    min-width: 11.5rem;
    display: flex; flex-direction: column;
    padding: 0.3rem 0;
    background: var(--paper-raised);
    border: 1px solid var(--rule);
    border-radius: 3px;
    box-shadow: 0 8px 22px rgb(21 20 15 / 0.11);
    opacity: 0; visibility: hidden; transform: translateY(-3px);
    transition: opacity 0.14s ease, transform 0.14s ease, visibility 0.14s;
  }
  .subnav-group:hover .subnav-menu,
  .subnav-group:focus-within .subnav-menu {
    opacity: 1; visibility: visible; transform: none;
  }
  .subnav .subnav-menu a,
  .subnav .subnav-menu .soon {
    padding: 0.44rem 0.95rem;
    border-bottom: 0;
  }
  .subnav .subnav-menu a:hover { background: var(--paper-sunk); color: var(--ink); }
  .subnav .subnav-menu a[aria-current='page'] {
    color: var(--ink); font-weight: 600;
    border-bottom: 0;
    box-shadow: inset 2px 0 0 var(--accent);
  }
}

@media (prefers-reduced-motion: reduce) {
  .subnav-caret, .subnav-menu { transition: none; }
}

/* ── Layout ───────────────────────────────────────────────────────────────── */
.wrap { max-width: var(--wide); margin: 0 auto; padding: 0 1.5rem; }

/* The reading column. Children opt out with .breakout / .full. */
.column {
  max-width: var(--prose);
  margin-inline: auto;
}
.breakout {
  max-width: var(--wide);
  margin-inline: auto;
}
@media (min-width: 72rem) {
  .breakout { width: var(--wide); margin-left: calc(50% - var(--wide) / 2); }
}

/* ── Section dots ─────────────────────────────────────────────────────────
 *
 * A fixed column of open circles on the right, one per chapter, filling as the
 * reader passes each one. Built by base.njk from the sections actually on the
 * page, so it cannot drift out of step with them the way a hand-written list
 * would.
 *
 * The homepage has its own labelled rail (`#rail`) and is skipped — the script
 * checks for it rather than both appearing.
 *
 * The hit area is 22px even though the dot is 8px: a 8px tap target fails WCAG
 * and is miserable on a phone. The circle is drawn with ::before inside a
 * larger transparent anchor. */
.dots {
  position: fixed;
  top: 50%;
  right: 0.7rem;
  transform: translateY(-50%);
  z-index: 40;
}
.dots ol {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 0.15rem;
}
.dots a {
  display: grid;
  place-items: center;
  width: 22px;
  height: 22px;
}
.dots a::before {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: 50%;
  border: 1px solid var(--ink-3);
  background: transparent;
  opacity: 0.55;
  transition: background var(--t), border-color var(--t),
              transform var(--t), opacity var(--t);
}
/* Passed: filled, but still quiet. */
.dots a[data-state="past"]::before {
  background: var(--ink-3);
  opacity: 0.75;
}
/* Here: the one piece of colour, and the only dot that changes size. */
.dots a[data-state="here"]::before {
  background: var(--accent);
  border-color: var(--accent);
  opacity: 1;
  transform: scale(1.5);
}
.dots a:hover::before,
.dots a:focus-visible::before { opacity: 1; }

@media (max-width: 45.99rem) {
  /* Inside the 1.5rem page gutter, so it never sits over the text. */
  .dots { right: 0.1rem; }
  .dots a { width: 18px; height: 18px; }
  .dots a::before { width: 6px; height: 6px; }
}
@media (prefers-reduced-motion: reduce) {
  .dots a::before { transition: none; }
}
@media print { .dots { display: none; } }

/* ── Type scale ───────────────────────────────────────────────────────────── */
h1, h2, h3, h4 {
  font-family: var(--serif);
  font-weight: 600;
  letter-spacing: -0.021em;
  line-height: 1.16;
  text-wrap: balance;
}
h1 { font-size: clamp(2.1rem, 5.2vw, 3.1rem); }
h2 { font-size: clamp(1.5rem, 3.4vw, 2rem); }
h3 { font-size: 1.22rem; }
h4 { font-size: 1.02rem; }

p { margin-bottom: 1.05em; }
p:last-child { margin-bottom: 0; }

.lede {
  font-size: 1.2rem;
  line-height: 1.52;
  color: var(--ink-2);
  text-wrap: pretty;
}

.eyebrow {
  font-family: var(--sans);
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--ink-3);
}

.byline {
  font-family: var(--sans);
  font-size: 0.76rem;
  color: var(--ink-3);
  letter-spacing: 0.015em;
}

.prose-note {
  font-family: var(--sans);
  font-size: 0.82rem;
  line-height: 1.6;
  color: var(--ink-2);
}

/* Footnote marker in a table cell or a row header, linking to the note that
   qualifies the figure. Superscript rather than a bracketed number: the tables
   it appears in are already numeric, and "[1]" next to "9.7%" reads as part of
   the value. `text-decoration: none` because an underline under a 0.6rem
   asterisk is a smudge. */
a.fn {
  font-family: var(--sans);
  font-size: 0.68em;
  font-weight: 600;
  vertical-align: super;
  line-height: 0;
  margin-left: 0.15em;
  color: var(--ink-3);
  text-decoration: none;
}

a.fn:hover,
a.fn:focus-visible { color: var(--ink); }

/* Numbers inside prose */
.fig {
  font-family: var(--sans);
  font-weight: 600;
  font-variant-numeric: proportional-nums;
  letter-spacing: -0.01em;
}

/* ── Chapters ─────────────────────────────────────────────────────────────── */
/* Chapters are separated by air and a mark, not by a hairline.
 *
 * The old rule was `padding: 4.2rem 0 1rem` with a 1px top border, which put
 * 84px between one chapter's last line and the next chapter's heading — about
 * a tenth of a phone screen on a page that runs to twelve screens. The break
 * was also lopsided: 1rem below, 4.2rem above, so the rule hugged the text it
 * was meant to be releasing the reader from.
 *
 * Now the padding is symmetric and the separator is a dinkus — three dots,
 * centred. A full-width rule reads as joinery; a centred mark reads as a
 * pause, which is what this is. Readers told us the pages scrolled without
 * resting, and a rule they had stopped seeing was the reason. */
.chapter {
  padding: 3.8rem 0;
  scroll-margin-top: 5rem;
}
.chapter + .chapter { border-top: 0; }
.chapter + .chapter::before {
  content: "";
  display: block;
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: var(--rule);
  /* The outer two dots of the dinkus, so the whole mark is one element. */
  box-shadow: -15px 0 var(--rule), 15px 0 var(--rule);
  margin: 0 auto 3.8rem;
}
.chapter-head { margin-bottom: 1.6rem; }
.chapter-num {
  font-family: var(--sans);
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.15em;
  color: var(--accent);
  display: block;
  margin-bottom: 0.7rem;
}
.chapter-head h2 { margin-bottom: 0.7rem; }

/* The bolded answer each chapter exists to deliver */
.takeaway {
  margin: 1.9rem auto 0;
  padding: 1.1rem 0 1.1rem 1.3rem;
  border-left: 3px solid var(--accent);
  font-size: 1.1rem;
  line-height: 1.5;
  color: var(--ink);
  text-wrap: pretty;
}
.takeaway strong { font-weight: 600; }
.takeaway .label {
  display: block;
  font-family: var(--sans);
  font-size: 0.64rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-3);
  margin-bottom: 0.4rem;
}

/* ── Chapter rail (desktop only) ──────────────────────────────────────────── */
.rail {
  position: fixed;
  top: 50%;
  right: 1.5rem;
  transform: translateY(-50%);
  z-index: 40;
  font-family: var(--sans);
  display: none;
}
@media (min-width: 86rem) { .rail { display: block; } }
.rail ol { list-style: none; display: grid; gap: 0.1rem; }
.rail a {
  display: flex; align-items: baseline; gap: 0.6rem;
  font-size: 0.72rem;
  color: var(--ink-3);
  padding: 0.3rem 0;
  transition: color var(--t);
}
.rail a:hover { color: var(--ink); text-decoration: none; }
.rail a .n {
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  opacity: 0.6;
}
.rail a[aria-current='true'] { color: var(--ink); font-weight: 600; }
.rail a[aria-current='true'] .n { color: var(--accent); opacity: 1; }
.rail .t {
  max-width: 9.5rem;
  opacity: 0;
  transform: translateX(-0.3rem);
  transition: opacity var(--t), transform var(--t);
}
.rail:hover .t, .rail a[aria-current='true'] .t { opacity: 1; transform: none; }

/* ── Figures ──────────────────────────────────────────────────────────────── */
figure {
  margin: 2.1rem 0 1.6rem;
}
.figure-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 1rem; flex-wrap: wrap;
  border-bottom: 1px solid var(--rule-firm);
  padding-bottom: 0.5rem;
  margin-bottom: 1.1rem;
}
.figure-title {
  font-family: var(--sans);
  font-size: 0.84rem;
  font-weight: 700;
  letter-spacing: 0.005em;
  color: var(--ink);
}
.figure-unit {
  font-family: var(--sans);
  font-size: 0.72rem;
  color: var(--ink-3);
  font-weight: 400;
  letter-spacing: 0.01em;
}
figcaption {
  font-family: var(--sans);
  font-size: 0.775rem;
  line-height: 1.58;
  color: var(--ink-2);
  margin-top: 0.9rem;
  padding-top: 0.7rem;
  border-top: 1px solid var(--rule);
  text-wrap: pretty;
}
figcaption .src {
  color: var(--ink-3);
  display: block;
  margin-top: 0.35rem;
  font-size: 0.72rem;
}

/* SVG charts: all chart text is sans, per house rule */
.chart { width: 100%; display: block; overflow: visible; }
.chart text { font-family: var(--sans); fill: var(--ink-2); }
.chart .ax { font-size: 11px; fill: var(--ink-3); font-variant-numeric: tabular-nums; }
.chart .lbl { font-size: 11.5px; fill: var(--ink-2); }
.chart .val { font-size: 12px; font-weight: 600; fill: var(--ink); font-variant-numeric: tabular-nums; }
.chart .val-sm { font-size: 10.5px; font-weight: 600; fill: var(--ink-2); font-variant-numeric: tabular-nums; }
/* On-fill value labels. An ink token on an opaque mark is the "buried label"
   failure the card generator checks for, so these wear the fill's own ink. */
.chart .val-on { font-size: 10px; font-weight: 700; font-variant-numeric: tabular-nums; }
.chart .val-on-pos { fill: var(--pos-ink); }
.chart .val-on-neg { fill: var(--neg-ink); }
.chart .hed { font-size: 13px; font-weight: 700; fill: var(--ink); }
.chart .grid { stroke: var(--rule); stroke-width: 1; }
.chart .axis { stroke: var(--rule-firm); stroke-width: 1; }
.chart .connector { stroke: var(--rule-firm); stroke-width: 1; stroke-dasharray: none; opacity: 0.7; }

/* Charts are drawn at the container's width rather than scaled to it, so they
   do not need to scroll. The exception is a waterfall with enough steps that
   76px a step outgrows the box; that one scrolls, and says so. */
.chart-scroll { overflow-x: auto; scrollbar-width: thin; }
.chart-scroll > svg { display: block; width: 100%; height: auto; }
.chart-scroll[data-wide='true'] > svg { width: auto; max-width: none; }

/* Legend */
.legend {
  display: flex; flex-wrap: wrap; gap: 0.35rem 1.1rem;
  font-family: var(--sans); font-size: 0.75rem; color: var(--ink-2);
  margin-bottom: 0.9rem;
}
.legend span { display: inline-flex; align-items: center; gap: 0.42rem; }
.legend i {
  width: 0.72rem; height: 0.72rem; border-radius: 2px;
  background: currentColor; flex-shrink: 0;
}
.legend .k1 { color: var(--s1); } .legend .k2 { color: var(--s2); }
.legend .k3 { color: var(--s3); } .legend .k4 { color: var(--s4); }
.legend .kop   { color: var(--bucket-operating); }
.legend .kinv  { color: var(--bucket-investments); }
.legend .kcash { color: var(--bucket-cash); }
.legend .kp { color: var(--pos); } .legend .kn { color: var(--neg); }
.legend .kwfc  { color: var(--brand-wfc); }
.legend span b { color: var(--ink-2); font-weight: 400; }

/* ── Stat row ─────────────────────────────────────────────────────────────── */
.stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(8.5rem, 1fr));
  gap: 0;
  border-top: 1px solid var(--rule-firm);
  border-bottom: 1px solid var(--rule-firm);
  margin: 1.8rem 0;
}
.stat { padding: 1rem 1.1rem 1.05rem; border-left: 1px solid var(--rule); }
.stat:first-child { border-left: none; padding-left: 0; }
.stat-label {
  font-family: var(--sans); font-size: 0.66rem; font-weight: 700;
  letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--ink-3); margin-bottom: 0.4rem;
}
.stat-value {
  font-family: var(--sans); font-size: 1.72rem; font-weight: 600;
  letter-spacing: -0.028em; line-height: 1.05;
  font-variant-numeric: proportional-nums;
}
.stat-note {
  font-family: var(--sans); font-size: 0.715rem; color: var(--ink-3);
  margin-top: 0.3rem; line-height: 1.4;
}
.stat-value.down { color: var(--sc-down); }
.stat-value.base { color: var(--sc-base); }
.stat-value.up   { color: var(--sc-up); }

/* The one hero number */
.hero-figure {
  font-family: var(--sans);
  font-size: clamp(3rem, 9vw, 4.6rem);
  font-weight: 600;
  letter-spacing: -0.04em;
  line-height: 1;
  font-variant-numeric: proportional-nums;
}

/* ── Controls: scenario toggle + levers ───────────────────────────────────── */
.controls {
  background: var(--paper-raised);
  border: 1px solid var(--rule);
  border-radius: 4px;
  padding: 1.15rem 1.25rem 1.25rem;
  margin: 1.8rem 0;
  font-family: var(--sans);
}
.controls-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 1rem; flex-wrap: wrap; margin-bottom: 0.9rem;
}
.controls-title {
  font-size: 0.8rem; font-weight: 700; letter-spacing: 0.01em; color: var(--ink);
}
.scenario {
  display: inline-flex; border: 1px solid var(--rule-firm);
  border-radius: 3px; overflow: hidden;
}
.scenario button {
  font-family: var(--sans); font-size: 0.755rem; font-weight: 600;
  padding: 0.38rem 0.8rem;
  background: none; border: none; cursor: pointer;
  color: var(--ink-2);
  border-left: 1px solid var(--rule-firm);
  transition: background var(--t), color var(--t);
}
.scenario button:first-child { border-left: none; }
.scenario button:hover { background: var(--paper-sunk); color: var(--ink); }
.scenario button[aria-pressed='true'] { color: #fff; }
.scenario button[data-sc='downside'][aria-pressed='true'] { background: var(--sc-down); }
.scenario button[data-sc='base'][aria-pressed='true']     { background: var(--sc-base); }
.scenario button[data-sc='upside'][aria-pressed='true']   { background: var(--sc-up); }
:root[data-theme='dark'] .scenario button[aria-pressed='true'],
.scenario button[aria-pressed='true'] { color: var(--paper); }

.levers { display: grid; gap: 1.05rem; }
@media (min-width: 46rem) { .levers { grid-template-columns: 1fr 1fr; gap: 1.05rem 2rem; } }

.lever-top {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 0.6rem; margin-bottom: 0.3rem;
}
.lever-label { font-size: 0.775rem; color: var(--ink); font-weight: 500; }
.lever-out {
  font-size: 0.8rem; font-weight: 700; color: var(--accent);
  font-variant-numeric: tabular-nums;
  background: var(--accent-soft);
  padding: 0.05rem 0.4rem; border-radius: 3px;
}
.lever-out[data-changed='true']::after { content: ' ·'; color: var(--ink-3); }
.lever-why { font-size: 0.71rem; color: var(--ink-3); line-height: 1.45; margin-top: 0.3rem; }

input[type='range'] {
  -webkit-appearance: none; appearance: none;
  width: 100%; height: 1.1rem; background: none; cursor: pointer; display: block;
}
input[type='range']::-webkit-slider-runnable-track {
  height: 3px; background: var(--rule-firm); border-radius: 2px;
}
input[type='range']::-moz-range-track {
  height: 3px; background: var(--rule-firm); border-radius: 2px;
}
input[type='range']::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: 0.95rem; height: 0.95rem; border-radius: 50%;
  background: var(--accent); border: 2px solid var(--paper-raised);
  margin-top: calc((3px - 0.95rem) / 2);
  box-shadow: 0 0 0 1px var(--rule-firm);
}
input[type='range']::-moz-range-thumb {
  width: 0.95rem; height: 0.95rem; border-radius: 50%;
  background: var(--accent); border: 2px solid var(--paper-raised);
  box-shadow: 0 0 0 1px var(--rule-firm);
}

.controls-foot {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem; flex-wrap: wrap;
  margin-top: 1.1rem; padding-top: 0.9rem; border-top: 1px solid var(--rule);
  font-size: 0.75rem; color: var(--ink-2);
}
.btn-text {
  font-family: var(--sans); font-size: 0.75rem; font-weight: 600;
  background: none; border: none; color: var(--accent); cursor: pointer;
  padding: 0; text-decoration: underline; text-underline-offset: 0.18em;
}
.btn-text:disabled { color: var(--ink-3); cursor: default; text-decoration: none; }

.controls-acts { display: flex; align-items: baseline; gap: 0.85rem; flex-wrap: wrap; }
/* The copy confirmation gets its space reserved, so appearing doesn't shove
   the two buttons sideways. */
.share-status {
  font-family: var(--sans); font-size: 0.7rem; color: var(--ink-3);
  min-width: 5.5rem; text-align: right;
}
@media (max-width: 30rem) { .share-status { min-width: 0; } }

/* ── Tables ───────────────────────────────────────────────────────────────── */
.table-scroll { overflow-x: auto; scrollbar-width: thin; }
table.data {
  width: 100%; border-collapse: collapse;
  font-family: var(--sans); font-size: 0.775rem;
  font-variant-numeric: tabular-nums;
}
table.data caption {
  text-align: left; font-size: 0.8rem; font-weight: 700;
  color: var(--ink); padding-bottom: 0.55rem;
}
table.data th, table.data td {
  padding: 0.44rem 0.7rem; text-align: right;
  border-bottom: 1px solid var(--rule);
  white-space: nowrap;
}
table.data th:first-child, table.data td:first-child {
  text-align: left; padding-left: 0;
}
table.data th:last-child, table.data td:last-child { padding-right: 0; }
table.data thead th {
  font-size: 0.68rem; font-weight: 700; letter-spacing: 0.055em;
  text-transform: uppercase; color: var(--ink-3);
  border-bottom: 1px solid var(--rule-firm);
  vertical-align: bottom;
}
table.data tbody tr:hover { background: var(--paper-sunk); }

/* A table printed in blocks, one per measure, each carrying its own column
   headers. A single header row at the top is invisible by the third block:
   the reader scrolls past it and is left with four unlabelled columns of
   percentages. Repeating the labels on the block head costs one row and
   removes the need to scroll back.

   Rows are tighter than the default here because these blocks are read DOWN
   a column — eight retailers compared on one measure — and at the standard
   spacing a block is most of a screen, which puts the thing being compared
   and the thing it is compared with in different glances. */
table.data.compact th, table.data.compact td { padding: 0.26rem 0.7rem; }
table.data.compact .group th {
  padding-top: 0.95rem; padding-bottom: 0.3rem;
  color: var(--ink-3); border-bottom: 1px solid var(--rule-firm);
}
/* The measure's name is the one cell on that row that is not a column
   label, so it carries the ink the labels do not. */
table.data.compact .group th:first-child { color: var(--ink); letter-spacing: 0.1em; }

/* A vertical rule where one measure's columns end and the next begins. Two
   three-column groups side by side read as six columns without it, and the
   reader has to count to work out which three belong together. */
table.data .rule-left { border-left: 1px solid var(--rule-firm); padding-left: 0.8rem; }
/* The upper tier of a two-tier head names the group, centred over its three. */
table.data thead tr.span th { text-align: center; border-bottom: none; padding-bottom: 0.1rem; }
table.data thead tr.span td { border-bottom: none; }
table.data .group th {
  font-size: 0.67rem; font-weight: 700; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--ink-2);
  padding-top: 1.1rem; background: none; border-bottom: 1px solid var(--rule);
}
table.data tr.sub td:first-child { padding-left: 1.1rem; color: var(--ink-2); }
table.data tr.total td {
  font-weight: 700; border-top: 1px solid var(--rule-firm);
  border-bottom: 1px solid var(--rule-firm);
}
table.data tr.accent td {
  font-weight: 700; color: var(--accent);
  background: var(--accent-soft);
  border-bottom: 1px solid var(--rule-firm);
}
table.data td.neg, table.data .neg { color: var(--neg); }

/* Progressive-disclosure appendix */
details.appendix {
  border-top: 1px solid var(--rule-firm);
  margin-top: 2rem;
}
details.appendix > summary {
  font-family: var(--sans); font-size: 0.8rem; font-weight: 600;
  color: var(--accent);
  padding: 0.95rem 0; cursor: pointer; list-style: none;
  display: flex; align-items: center; gap: 0.5rem;
}
details.appendix > summary::-webkit-details-marker { display: none; }
details.appendix > summary::before {
  content: '+'; font-weight: 700; font-size: 0.95rem;
  width: 0.8rem; display: inline-block;
}
details.appendix[open] > summary::before { content: '−'; }
details.appendix > summary:hover { text-decoration: underline; }
details.appendix .appendix-body { padding-bottom: 1.6rem; }

/* ── Pull quote ───────────────────────────────────────────────────────────── */
blockquote.pull {
  margin: 2.4rem auto;
  text-align: center;
  max-width: 34rem;
}
blockquote.pull p {
  font-size: 1.32rem; font-style: italic; line-height: 1.45;
  color: var(--ink); letter-spacing: -0.012em; text-wrap: pretty;
}
blockquote.pull cite {
  font-family: var(--sans); font-size: 0.73rem; font-style: normal;
  color: var(--ink-3); letter-spacing: 0.04em;
  display: block; margin-top: 0.75rem;
}

/* A long passage quoted at length reads badly at pull-quote size: 1.32rem
   italic over ten lines is a wall. This keeps the pull-quote voice and steps
   the type back down to something readable, and left-aligns it, because
   centred text only works for a line or two. */
blockquote.pull.quote-long { text-align: left; max-width: var(--prose); }
blockquote.pull.quote-long p {
  font-size: 1.04rem; line-height: 1.6; letter-spacing: 0;
}
blockquote.pull.quote-long p + p { margin-top: 0.8rem; }
blockquote.pull.quote-long cite { text-align: left; }

/* ── Cards (hub, blog index) ──────────────────────────────────────────────── */
.cards { display: grid; gap: 1px; background: var(--rule); border-block: 1px solid var(--rule); }
@media (min-width: 46rem) { .cards { grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr)); } }
/* Five cards into an auto-fit grid lands 4 across and 1 stranded on its own
   row, which reads as a card that failed to load rather than as the fifth of
   five. Three and two is a deliberate shape. Scoped to a modifier because the
   Berkshire grid has nine cards and auto-fit suits it. */
@media (min-width: 46rem) { .cards-3 { grid-template-columns: repeat(3, 1fr); } }
.card {
  background: var(--paper);
  padding: 1.3rem 1.3rem 1.4rem;
  display: flex; flex-direction: column; gap: 0.45rem;
  color: var(--ink); transition: background var(--t);
}
.card:hover { background: var(--paper-raised); text-decoration: none; }
.card h3 { font-size: 1.05rem; }
.card p { font-family: var(--sans); font-size: 0.79rem; color: var(--ink-2); line-height: 1.55; flex-grow: 1; margin: 0; }
.card .more { font-family: var(--sans); font-size: 0.74rem; font-weight: 600; color: var(--accent); }
.card.soon { opacity: 0.5; pointer-events: none; }
/* A card whose page exists but is being rebuilt. Unlike .card.soon it stays
   clickable — the current write-up is still there to read — so it is dimmed
   only slightly and lifts to full strength on hover. */
.card-soon { opacity: 0.72; }
.card-soon:hover, .card-soon:focus-visible { opacity: 1; }
.card.soon .tag,
.card-soon .tag {
  font-family: var(--sans); font-size: 0.65rem; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--ink-3);
  border: 1px solid var(--rule); border-radius: 2px;
  padding: 0.08rem 0.35rem; align-self: flex-start;
}

/* A slide reproduced from a company's own investor material. It is someone
   else's artwork sitting among hand-drawn charts, so it gets a border and the
   page's own surface behind it to read as a quotation rather than as one of
   this site's figures. White-backed slides need the surface in dark mode too,
   which is why the background is set rather than left transparent. */
/* ── A company's own mark ──────────────────────────────────────────────────
   Reproduced, so it sits on its own light plaque rather than on the page
   background: these are dark-ink marks and the site has a dark mode. Height is
   fixed and width follows, because the five marks have wildly different aspect
   ratios and matching their HEIGHTS is what makes a row of them look level. */
.house-mark {
  display: inline-block;
  background: #fff;
  border: 1px solid var(--rule-firm);
  border-radius: 2px;
  padding: 0.5rem 0.7rem;
  line-height: 0;
  margin-bottom: 1rem;
}
/* The plaque is an inline-block and the eyebrow that follows it is a span, so
   the two share a line box: side by side on a wide screen, and on a phone the
   eyebrow wrapped around the plaque and broke mid-phrase. Scoped to the pair
   so .eyebrow keeps its inline behaviour everywhere else on the site. */
.house-mark + .eyebrow { display: block; }

.house-mark img {
  display: block;
  height: 26px;
  width: auto;
  max-width: 200px;
}

.slide-figure {
  display: block;
  width: 100%;
  height: auto;
  background: #fff;
  border: 1px solid var(--rule-firm);
  border-radius: 2px;
}

/* ── Post list ────────────────────────────────────────────────────────────── */
.post-list { list-style: none; }
.post-list li { border-bottom: 1px solid var(--rule); padding: 1.3rem 0; }
.post-list h3 { margin-bottom: 0.3rem; }
.post-list .meta { font-family: var(--sans); font-size: 0.73rem; color: var(--ink-3); margin-bottom: 0.4rem; }
.post-list p { font-family: var(--sans); font-size: 0.82rem; color: var(--ink-2); margin: 0; }
.tags { display: flex; gap: 0.4rem; flex-wrap: wrap; margin-top: 0.5rem; }
.tag-chip {
  font-family: var(--sans); font-size: 0.66rem; letter-spacing: 0.05em;
  text-transform: uppercase; color: var(--ink-2);
  border: 1px solid var(--rule); border-radius: 2px; padding: 0.1rem 0.4rem;
}

/* ── Group marks ──────────────────────────────────────────────────────────
   An identity tile per listed retailer: the ticker set in the house sans on
   the colour its business model already wears on every chart in the page.
   Deliberately typographic rather than the companies' own logos, which are
   their trademarks and not ours to redistribute.

   Built to be replaced. Drop an <img> inside .gmark-tile — a licensed logo,
   an SVG the company supplies — and it fills the tile at the same size with
   no other change; the ticker text is the fallback, not the structure. The
   tile colour arrives as --tile from the company's own model, so it always
   matches that company's bars; two colours only, because --s1 to --s4 are the
   validated set and eight would not survive the colour-blind check. */
.gmark { display: inline-flex; align-items: center; gap: 0.5rem; vertical-align: baseline; }
.gmark-tile {
  display: inline-flex; align-items: center; justify-content: center;
  width: 2.6rem; height: 1.45rem; flex: 0 0 auto; overflow: hidden;
  background: var(--tile, var(--s1)); color: var(--paper);
  border-radius: 2px;
  font-family: var(--sans); font-size: 0.62rem; font-weight: 700;
  letter-spacing: 0.08em;
}
.gmark-tile img { width: 100%; height: 100%; object-fit: contain; display: block; }
/* In a heading the tile should not inherit the serif's larger line box. */
h3 .gmark-tile { position: relative; top: -0.08em; }
/* In a table's row header the name is already in the row, so the tile stands
   alone and the cell stays narrow. */
.gmark-cell { display: inline-flex; align-items: center; gap: 0.45rem; }

/* ── Brand chips ──────────────────────────────────────────────────────────
   A marque and, where the filing gives one, its weight.

   An earlier version drew the weight as a fill behind each chip, scaled to
   the company's largest brand. It read as a progress bar and meant nothing:
   the top brand came out full whether it was 30% of the book or 18%, and
   because each company was scaled to its own maximum the fills did not
   compare between them — all this beside a number that was already exact.
   A chip is a label. The figure does the work.

   No manufacturer logos: they are third-party trademarks, and a wordmark set
   in the page's own type is both legible at this size and honest about being
   our typography rather than theirs. */
.brandset { display: flex; flex-wrap: wrap; gap: 0.3rem; margin: 0.5rem 0 0; }
.brandchip {
  display: inline-flex; align-items: baseline; gap: 0.35rem;
  font-family: var(--sans); font-size: 0.72rem; line-height: 1.35;
  color: var(--ink); background: var(--paper-sunk);
  border: 1px solid var(--rule); border-radius: 3px;
  padding: 0.18rem 0.45rem;
}
.brandchip b { font-weight: 600; }
.brandchip i {
  font-style: normal; font-variant-numeric: tabular-nums;
  font-size: 0.66rem; color: var(--ink-2);
}
.brandset-note {
  font-family: var(--sans); font-size: 0.74rem; color: var(--ink-3);
  margin: 0.45rem 0 0;
}

/* ── Subscribe ────────────────────────────────────────────────────────────── */
.subscribe {
  background: var(--paper-raised);
  border: 1px solid var(--rule);
  border-radius: 4px;
  padding: 1.5rem 1.5rem 1.6rem;
  margin: 2.6rem 0 1rem;
}
.subscribe h3 { font-size: 1.15rem; margin-bottom: 0.4rem; }
.subscribe p { font-family: var(--sans); font-size: 0.8rem; color: var(--ink-2); line-height: 1.55; }
.subscribe form { display: flex; gap: 0.5rem; flex-wrap: wrap; margin-top: 1rem; }
.subscribe input[type='email'] {
  flex: 1 1 14rem; min-width: 0;
  font-family: var(--sans); font-size: 0.85rem;
  padding: 0.55rem 0.7rem;
  background: var(--paper); color: var(--ink);
  border: 1px solid var(--rule-firm); border-radius: 3px;
}
.btn {
  font-family: var(--sans); font-size: 0.82rem; font-weight: 600;
  padding: 0.55rem 1.1rem; border-radius: 3px; cursor: pointer;
  background: var(--accent); color: var(--paper); border: 1px solid var(--accent);
  transition: filter var(--t);
}
.btn:hover { filter: brightness(1.1); text-decoration: none; }
.btn-ghost {
  background: none; color: var(--ink); border-color: var(--rule-firm);
}
.btn-ghost:hover { background: var(--paper-sunk); }

/* `.btn` is written for <button>, which is inline-block and undecorated by
   default. An <a> is neither, so a link wearing .btn renders as underlined
   body text with the padding collapsing into the line above it. Both pages
   that offer a download use an anchor, because it is a navigation, not an
   action. */
a.btn { display: inline-block; text-decoration: none; }
a.btn:hover { text-decoration: none; }

/* The dataset download under a deep dive. */
.data-dl { margin-top: 0.9rem; }
.subscribe .fineprint { font-size: 0.7rem; color: var(--ink-3); margin-top: 0.7rem; }

/* ── Footer ───────────────────────────────────────────────────────────────── */
.foot {
  border-top: 1px solid var(--rule);
  margin-top: 4rem;
  padding: 2.2rem 0 3rem;
  font-family: var(--sans);
  font-size: 0.75rem;
  color: var(--ink-3);
  line-height: 1.6;
}
.foot-inner { max-width: var(--wide); margin: 0 auto; padding: 0 1.5rem; }
.foot-grid { display: grid; gap: 1.4rem; }
@media (min-width: 46rem) { .foot-grid { grid-template-columns: 2fr 1fr 1fr; gap: 2.5rem; } }
.foot h4 {
  font-family: var(--sans); font-size: 0.66rem; font-weight: 700;
  letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--ink-2); margin-bottom: 0.6rem;
}
.foot ul { list-style: none; display: grid; gap: 0.32rem; }
.foot a { color: var(--ink-2); }
.foot .disclaim {
  margin-top: 1.9rem; padding-top: 1.1rem;
  border-top: 1px solid var(--rule);
  font-size: 0.72rem;
}

/* ── Deep-dive page header ────────────────────────────────────────────────── */
.page-head {
  padding: 2.6rem 0 0.6rem;
  border-bottom: 1px solid var(--rule-firm);
  margin-bottom: 1.4rem;
}
.page-head h1 { font-size: clamp(1.7rem, 4.2vw, 2.5rem); margin-bottom: 0.45rem; }
.page-head .meta { font-family: var(--sans); font-size: 0.78rem; color: var(--ink-3); }

/* ── Utilities ────────────────────────────────────────────────────────────── */
.visually-hidden {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}
.mt-0 { margin-top: 0; }
.center { text-align: center; }
.sans { font-family: var(--sans); }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { transition-duration: 0.01ms !important; animation-duration: 0.01ms !important; }
}

@media print {
  .shell, .rail, .controls, .theme-btn, .subnav { display: none; }
  body { background: #fff; color: #000; }
  .chapter { page-break-inside: avoid; }
}

/* ── Chart hover layer ────────────────────────────────────────────────────── */
.chart-tip {
  /* Positioned with a transform from the viewport origin, never with left/top:
     a transform is a compositor-only change, so moving the tooltip cannot
     invalidate layout. left/top are pinned to 0 so the translate is absolute.
     See the hover-layer note in charts.js. */
  position: fixed; left: 0; top: 0; z-index: 120;
  will-change: transform;
  pointer-events: none;
  max-width: 17rem;
  background: var(--paper-raised);
  color: var(--ink);
  border: 1px solid var(--rule-firm);
  border-radius: 3px;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.14);
  padding: 0.5rem 0.65rem;
  font-family: var(--sans);
  font-size: 0.755rem;
  line-height: 1.5;
}
.chart-tip b { font-weight: 700; }
.chart-tip em { color: var(--ink-2); font-style: italic; }
.chart-tip i {
  display: inline-block; width: 0.55rem; height: 0.55rem;
  border-radius: 2px; margin-right: 0.35rem;
}
.chart-hit { cursor: default; }
.chart-hit:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }

/* The table twin under a figure reads as apparatus, not a second chart */
details.table-twin { border-top: none; margin-top: 0.6rem; }
details.table-twin > summary {
  font-size: 0.73rem; font-weight: 600; color: var(--ink-3); padding: 0.4rem 0;
}
details.table-twin > summary:hover { color: var(--accent); }
details.table-twin .appendix-body { padding-bottom: 0.8rem; }

/* ═══════════════════════════════════════════════════════════════════════════
   Segment deep dives

   The pages used to be tables. They are now the same editorial object as the
   essay's chapters, plus three devices of their own: a strip that places the
   segment inside the valuation, a numbered takeaway list, and a scrubber for
   pages where the story runs year by year.
   ═══════════════════════════════════════════════════════════════════════════ */

.seg-head { padding-top: 3.2rem; }
.seg-head h1 { margin: 0.85rem 0 1rem; }

/* ── Where this sits in the valuation ─────────────────────────────────────── */
.seg-place {
  max-width: var(--wide);
  margin: 0 auto 2.6rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--rule);
}
.seg-place-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.5rem 1rem;
  margin-bottom: 0.85rem;
}
.seg-place-head .figure-unit { margin-left: auto; }

/* One bar, every row of the base case in it, this segment at full strength
   and the rest dimmed. The 2px surface gap is the border-right. */
.place-bar {
  display: flex;
  height: 30px;
  border-radius: 4px;
  overflow: hidden;
  background: var(--paper-sunk);
}
.place-seg {
  min-width: 2px;
  border-right: 2px solid var(--paper);
  opacity: 0.26;
  transition: opacity var(--t);
}
.place-seg:last-child { border-right: 0; }
.place-seg.g-operating   { background: var(--bucket-operating); }
.place-seg.g-investments { background: var(--bucket-investments); }
.place-seg.g-cash        { background: var(--bucket-cash); }
/* The sogo shosha strip ranks five peer companies rather than three buckets of
   one valuation, so there is nothing for the bucket inks to mean. One series
   colour, and `is-this` does the work of saying which house you are reading. */
.place-seg.g-house       { background: var(--s1); }
.place-seg.is-this { opacity: 1; }

.place-facts {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem 1.6rem;
  margin-top: 0.9rem;
  font-family: var(--sans);
  font-size: 0.82rem;
  color: var(--ink-3);
}
.place-fact b {
  font-weight: 600;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}

/* ── Takeaways: the argument, before the evidence ─────────────────────────── */
/* A bulleted list in the reading column. The site had no such pattern until
   the Buffett page needed to set out Munger's elements of the Berkshire
   system, so this matches the prose: serif body, a quiet rule-coloured marker
   that is not a bullet glyph, and paragraph-sized spacing between items. The
   `display: block` guard is the same one `.seg-takeaways` carries, because a
   grid list turns every bare word into a grid item. */
.bullets {
  list-style: none;
  margin: 1.1rem 0 1.4rem;
  padding: 0;
  display: grid;
  gap: 0.85rem;
}
.bullets > li {
  display: block;
  position: relative;
  padding-left: 1.15rem;
  line-height: 1.62;
}
.bullets > li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.62em;
  width: 0.5rem;
  height: 1px;
  background: var(--rule-firm);
}
.bullets > li > strong { font-weight: 650; }

.seg-takeaways {
  max-width: var(--prose);
  margin: 0 auto 1rem;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 1.05rem;
}
/* The two-column grid applies only where the .t-num / .t-body pair is actually
   present. An <li> of bare text used to make every word a grid item and render
   one word per line — a silent, total failure from a missing span. It now
   degrades to ordinary prose instead. */
.seg-takeaways li {
  display: block;
}
.seg-takeaways li:has(> .t-num) {
  display: grid;
  grid-template-columns: 1.7rem 1fr;
  gap: 0.85rem;
  align-items: start;
}
.t-num {
  font-family: var(--sans);
  font-size: 0.72rem;
  font-weight: 650;
  letter-spacing: 0.04em;
  color: var(--accent);
  background: var(--accent-soft);
  border-radius: 3px;
  text-align: center;
  padding: 0.3rem 0;
  font-variant-numeric: tabular-nums;
}
.t-body {
  font-size: 1.02rem;
  line-height: 1.58;
  color: var(--ink-2);
}
.t-body strong { color: var(--ink); font-weight: 600; }

/* ── A compact figure note, for "how to read this" ───────────────────────── */
.readnote {
  max-width: var(--prose);
  margin: 0 auto 1.4rem;
  padding: 0.85rem 1.05rem;
  background: var(--paper-sunk);
  border-left: 2px solid var(--rule-firm);
  font-family: var(--sans);
  font-size: 0.86rem;
  line-height: 1.55;
  color: var(--ink-2);
}
.readnote b { color: var(--ink); font-weight: 600; }

/* ── Inline metric rail — a stat row that is not a grid of big numbers ───── */
.rail-metrics {
  display: flex;
  flex-wrap: wrap;
  max-width: var(--wide);
  margin: 0 auto 2rem;
  border-top: 1px solid var(--rule);
  border-bottom: 1px solid var(--rule);
}
.rail-metric {
  flex: 1 1 8.5rem;
  padding: 0.9rem 1.1rem 0.95rem 0;
  font-family: var(--sans);
}
.rail-metric .m-label {
  display: block;
  font-size: 0.7rem;
  letter-spacing: 0.055em;
  text-transform: uppercase;
  color: var(--ink-3);
  margin-bottom: 0.3rem;
}
.rail-metric .m-value {
  display: block;
  font-size: 1.22rem;
  font-weight: 600;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
  line-height: 1.15;
}
.rail-metric .m-note {
  display: block;
  font-size: 0.74rem;
  color: var(--ink-3);
  margin-top: 0.22rem;
}
.rail-metric .m-value.pos { color: var(--sc-up); }
.rail-metric .m-value.neg { color: var(--neg); }

/* ── Year scrubber: the capital-allocation record, one year at a time ───── */
.scrub { max-width: var(--wide); margin: 0 auto 2.2rem; }
.scrub-track {
  display: flex;
  gap: 2px;
  margin-bottom: 1.2rem;
}
.scrub-year {
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.35rem;
  padding: 0.45rem 0 0.4rem;
  border: 0;
  background: none;
  cursor: pointer;
  font-family: var(--sans);
  font-size: 0.66rem;
  color: var(--ink-3);
  border-radius: 3px;
  transition: color var(--t), background var(--t);
}
.scrub-year i {
  display: block;
  width: 100%;
  background: var(--bucket-cash);
  border-radius: 2px 2px 0 0;
  opacity: 0.42;
  transition: opacity var(--t), background var(--t);
}
.scrub-year:hover { background: var(--accent-soft); color: var(--ink-2); }
.scrub-year:hover i { opacity: 0.7; }
.scrub-year[aria-pressed='true'] { color: var(--ink); font-weight: 650; }
.scrub-year[aria-pressed='true'] i { opacity: 1; background: var(--bucket-operating); }
.scrub-year:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

.scrub-panel {
  display: grid;
  grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
  gap: 1.6rem 2.4rem;
  padding: 1.5rem 0 0;
  border-top: 1px solid var(--rule);
}
.scrub-panel h3 {
  font-family: var(--sans);
  font-size: 0.78rem;
  font-weight: 650;
  letter-spacing: 0.055em;
  text-transform: uppercase;
  color: var(--ink-3);
  margin-bottom: 0.7rem;
}
.scrub-year-label {
  font-family: var(--sans);
  font-size: 2.1rem;
  font-weight: 300;
  line-height: 1;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
  margin-bottom: 0.6rem;
}
.scrub-ctx { font-size: 1rem; line-height: 1.6; color: var(--ink-2); }
.scrub-list { list-style: none; display: grid; gap: 0.6rem; }
.scrub-list li {
  font-family: var(--sans);
  font-size: 0.86rem;
  line-height: 1.5;
  color: var(--ink-2);
  padding-left: 0.85rem;
  border-left: 2px solid var(--rule-firm);
}
.scrub-list li b { color: var(--ink); font-weight: 600; }
.scrub-list.bought li { border-left-color: var(--bucket-operating); }
.scrub-list.sold   li { border-left-color: var(--bucket-cash); }
.scrub-flows {
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem 1.4rem;
  margin-top: 0.4rem;
  font-family: var(--sans);
  font-size: 0.8rem;
  color: var(--ink-3);
}
.scrub-flows b {
  color: var(--ink);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

/* ── What would change the answer ────────────────────────────────────────── */
.lever-list { display: grid; gap: 1.15rem; margin-bottom: 1.4rem; }
.lever-item { border-top: 1px solid var(--rule); padding-top: 0.8rem; }
.lever-item dt {
  font-family: var(--sans);
  font-size: 0.93rem;
  font-weight: 600;
  color: var(--ink);
  margin-bottom: 0.25rem;
}
.lever-base {
  display: block;
  font-weight: 400;
  font-size: 0.76rem;
  color: var(--ink-3);
  font-variant-numeric: tabular-nums;
  margin-top: 0.12rem;
}
.lever-item dd { font-size: 0.97rem; line-height: 1.58; color: var(--ink-2); }

/* ── Page foot ───────────────────────────────────────────────────────────── */
.seg-foot {
  max-width: var(--wide);
  margin: 3rem auto 0;
  padding-top: 1.4rem;
  border-top: 1px solid var(--rule);
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr);
  gap: 1.4rem 2.4rem;
  align-items: start;
}
.seg-foot-main p { font-size: 0.97rem; color: var(--ink-2); margin-top: 0.4rem; }
.seg-foot-links {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}
.seg-foot-links a {
  display: inline-block;
  font-family: var(--sans);
  font-size: 0.8rem;
  color: var(--ink-2);
  text-decoration: none;
  padding: 0.34rem 0.65rem;
  border: 1px solid var(--rule);
  border-radius: 3px;
  transition: border-color var(--t), color var(--t);
}
.seg-foot-links a:hover { border-color: var(--accent); color: var(--accent); }

/* ── Comparison table, for the few places a table is still the right form ── */
.compare {
  width: 100%;
  border-collapse: collapse;
  font-family: var(--sans);
  font-size: 0.86rem;
}
.compare caption {
  text-align: left;
  font-size: 0.8rem;
  color: var(--ink-3);
  padding-bottom: 0.6rem;
}
.compare th, .compare td {
  padding: 0.5rem 0.7rem;
  text-align: right;
  border-bottom: 1px solid var(--rule);
  font-variant-numeric: tabular-nums;
}
.compare thead th {
  font-size: 0.72rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-3);
  font-weight: 600;
  border-bottom-color: var(--rule-firm);
}
.compare th:first-child, .compare td:first-child {
  text-align: left;
  font-weight: 500;
  color: var(--ink);
}
.compare tbody tr:hover { background: var(--paper-sunk); }
.compare .num { color: var(--ink-2); white-space: nowrap; }
.compare .nowrap { white-space: nowrap; }
/* A wide numeric table on a phone: tighten the cells rather than drop columns.
   Hiding data to fit is not a layout fix on a site whose point is the data. */
@media (max-width: 34rem) {
  .compare, table.data { font-size: 0.72rem; }
  .compare th, .compare td,
  table.data th, table.data td { padding: 0.34rem 0.22rem; }
  .compare thead th,
  table.data thead th { font-size: 0.6rem; letter-spacing: 0.02em; }
  .compare caption, table.data caption { font-size: 0.72rem; }
}

/* ── Fitting a wide table ──────────────────────────────────────────────────
 *
 * Both classes below are set by tables.js, which measures each table against
 * the room it actually has. See that file for why a desktop and a phone need
 * different answers; neither state is reached unless the table overflows.
 *
 * `is-wide` — the table needs more than the reading column but less than the
 * page. It breaks out of the measure the same way a figure does, so it stays a
 * centred table and simply stops being pinched by the prose width.
 */
.table-scroll.is-wide {
  max-width: none;
  width: var(--fit-width);
  /* `.column` is centred in the page, so its own centre is the page's: pulling
     half the surplus off the left edge centres the wider table too. */
  margin-left: calc(50% - var(--fit-width) / 2);
}

/* `is-wrapped` — the table needs more than the whole page, because some cell
 * holds a sentence that `white-space: nowrap` is keeping on one line. Letting
 * the words break costs far less than giving up the table shape. Only cells
 * containing spaces can wrap at all, so no figure is split across lines; the
 * two classes that exist to keep a composite value together are restated
 * afterwards, since this rule would otherwise outrank them.
 */
.table-scroll.is-wrapped th,
.table-scroll.is-wrapped td { white-space: normal; }
.table-scroll.is-wrapped .num,
.table-scroll.is-wrapped .nowrap { white-space: nowrap; }

/* `is-stacked` — the whole page is still too narrow: eleven numeric columns
 * want 526px against 327px of phone, with the type already at 11.5px. One
 * block per row, each figure carrying the heading of the column it came from.
 * Nothing is dropped and nothing has to be swiped for.
 *
 * Not inside a phone-width media query, because the class is set by fit rather
 * than by viewport — an eleven-column table does not fit a 700px tablet
 * either. Every selector carries two classes, so these win over the
 * phone-width padding and type rules above whatever their source order.
 */
.table-scroll.is-stacked { overflow-x: visible; }
.table-scroll.is-stacked table { display: block; width: 100%; font-size: 0.8rem; }
.table-scroll.is-stacked thead { display: none; }
.table-scroll.is-stacked tbody { display: block; }
/* Two label/value pairs to a line, not one. A ten-column row stacked one
   figure per line is ten lines, and the longest table on the site is
   twenty-nine of those — eight thousand pixels, ten phone screens, for one
   table. Paired, it is half that, and 160px still holds a 0.7rem label beside
   its figure. */
.table-scroll.is-stacked tr {
  display: grid; grid-template-columns: 1fr 1fr;
  column-gap: 1.1rem;
  padding: 0.5rem 0 0.6rem;
  border-bottom: 1px solid var(--rule-firm);
}
.table-scroll.is-stacked tr:last-child { border-bottom: 0; }
/* The row's own <th scope="row"> is its title, so it is the one cell that
   needs no label of its own. */
.table-scroll.is-stacked tbody th {
  display: block; grid-column: 1 / -1;
  padding: 0 0 0.3rem; border-bottom: 0;
  text-align: left; font-weight: 700; font-size: 0.82rem; color: var(--ink);
}
.table-scroll.is-stacked td {
  display: flex; justify-content: space-between; align-items: baseline;
  gap: 1rem; padding: 0.16rem 0; border-bottom: 0;
  text-align: right; white-space: normal;
}
.table-scroll.is-stacked td::before {
  content: attr(data-label);
  flex: 1 1 auto; text-align: left; font-weight: 400;
  font-size: 0.7rem; letter-spacing: 0.02em; color: var(--ink-3);
}
/* A cell with no heading to print — a spacer, or a note spanning the row —
   reads as a plain paragraph across the full width rather than hanging off an
   empty label in one of the two tracks. */
.table-scroll.is-stacked td:not([data-label]),
.table-scroll.is-stacked td[colspan] {
  display: block; grid-column: 1 / -1; text-align: left;
}
.table-scroll.is-stacked td:first-child,
.table-scroll.is-stacked td:last-child { padding-left: 0; padding-right: 0; }
/* The rule between two column groups is a horizontal device. Stacked, the
   groups no longer sit side by side and it lands in the middle of a pair. */
.table-scroll.is-stacked .rule-left { border-left: 0; padding-left: 0; }
.table-scroll.is-stacked caption { padding-bottom: 0.4rem; }
/* Set by tables.js only where the table had no gutter of its own. */
.table-scroll.is-stacked.is-inset { padding-left: 1rem; padding-right: 1rem; }

/* Years outside the window the normalised average is struck over. Dimmed and
   struck through the tick column rather than hidden: the point is that the
   reader can see exactly what was left out and judge the choice. */
.compare tr.is-excluded { background: var(--paper-sunk); }
.compare tr.is-excluded th, .compare tr.is-excluded td { color: var(--ink-3); }

/* A loss year in a long run of profitable ones. The minus sign already says
   so — this makes it findable when scanning twenty-eight rows. */
.compare tr.is-negative td:last-child { color: var(--neg); font-weight: 600; }
.compare tr.is-negative th:first-child { box-shadow: inset 2px 0 0 var(--neg); }
.compare tr.is-total th, .compare tr.is-total td {
  border-top: 1px solid var(--rule-firm);
  border-bottom: 0;
  font-weight: 650;
  color: var(--ink);
}

/* ── Cross-link to another section of the site ───────────────────────────── */
/* Distinct from .gap-note (which admits a hole in the data) and from
   .takeaway (which is the argument). This one points somewhere. The accent
   rule on the left is the same device as .takeaway because both interrupt the
   prose, but the raised paper and the smaller type keep it subordinate — it is
   an offer, not a conclusion. */
.callout {
  max-width: var(--prose);
  margin: 2rem auto 0;
  padding: 1.05rem 1.25rem;
  border: 1px solid var(--rule);
  border-left: 3px solid var(--accent);
  border-radius: 4px;
  background: var(--paper-raised);
}
.callout p { font-family: var(--sans); font-size: 0.86rem; line-height: 1.6; color: var(--ink-2); }
.callout p:last-child { margin-bottom: 0; }
.callout-kicker {
  display: block;
  font-family: var(--sans);
  font-size: 0.66rem;
  font-weight: 700;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--ink-3);
  margin-bottom: 0.45rem;
}
.callout-link { margin-top: 0.7rem; }
.callout-link a { font-weight: 600; color: var(--accent); text-decoration: none; }
.callout-link a:hover, .callout-link a:focus-visible { text-decoration: underline; }

@media (max-width: 42rem) {
  .scrub-panel, .seg-foot { grid-template-columns: 1fr; }
  .scrub-year { font-size: 0; gap: 0; }
  .rail-metric { flex-basis: 45%; }
  .seg-place-head .figure-unit { margin-left: 0; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   Phones

   Most readers arrive on a phone. Charts handle this themselves — they are
   drawn at the container's width rather than scaled to it, so they need no
   rules here. What follows is the page furniture around them.
   ═══════════════════════════════════════════════════════════════════════════ */

.basis-note {
  border-left: 2px solid var(--rule-firm);
  padding-left: 0.9rem;
  margin: 1.6rem 0;
}

/* ── The quotable line ───────────────────────────────────────────────────────
   Set larger than body copy and in the serif, with a rule above and below
   rather than quote marks — it is the page's thesis, not a quotation from
   someone else. No italic: it is the plainest sentence on the page and should
   look like it. */
.quotable {
  margin: 1.8rem 0 2.2rem;
  padding: 1.1rem 0;
  border-top: 1px solid var(--rule-firm);
  border-bottom: 1px solid var(--rule-firm);
}
.quotable blockquote {
  margin: 0;
  padding: 0;
  border: 0;
  font-family: var(--serif);
  font-size: 1.22rem;
  line-height: 1.42;
  font-weight: 500;
  color: var(--ink);
  text-wrap: pretty;
}
@media (max-width: 34rem) {
  .quotable blockquote { font-size: 1.08rem; }
}

/* ── The revision log ────────────────────────────────────────────────────────
   A correction is visually distinct from a routine update, because the whole
   value of the page is that corrections are not buried among them. */
.rev-list { list-style: none; margin: 0; padding: 0; }
.rev {
  padding: 1.6rem 0 1.7rem;
  border-bottom: 1px solid var(--rule);
}
.rev:first-child { padding-top: 0; }
.rev-meta {
  display: flex;
  align-items: baseline;
  gap: 0.75rem;
  font-family: var(--sans);
  font-size: 0.74rem;
  color: var(--ink-3);
  margin-bottom: 0.5rem;
}
.rev-kind {
  font-size: 0.66rem;
  font-weight: 700;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  padding: 0.12rem 0.42rem;
  border-radius: 2px;
  border: 1px solid var(--rule-firm);
  color: var(--ink-2);
}
/* The one label that carries weight gets the accent; the rest stay quiet so
   it reads at a glance down the column. */
.rev-kind-correction {
  border-color: var(--accent);
  color: var(--accent);
  font-weight: 700;
}
.rev h3 {
  font-family: var(--serif);
  font-size: 1.15rem;
  font-weight: 600;
  margin: 0 0 0.6rem;
  text-wrap: balance;
}
.rev p { margin-bottom: 0.6rem; }
.rev p:last-child { margin-bottom: 0; }
.rev-was {
  font-family: var(--sans);
  font-size: 0.82rem;
  line-height: 1.6;
  color: var(--ink-2);
  background: var(--paper-sunk);
  border-left: 2px solid var(--rule-firm);
  padding: 0.6rem 0.8rem;
}
.rev-was .label {
  display: block;
  font-size: 0.65rem;
  font-weight: 700;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--ink-3);
  margin-bottom: 0.2rem;
}
.rev-detail {
  font-family: var(--sans);
  font-size: 0.8rem;
  line-height: 1.6;
  color: var(--ink-3);
}

/* ── The glossary page ───────────────────────────────────────────────────────
   Entries are separated by a rule rather than boxed. Twelve cards in a column
   would read as twelve unrelated things; a rule reads as one list. */
.gloss-index {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1rem;
  font-family: var(--sans);
  font-size: 0.8rem;
  padding: 1rem 0 0.2rem;
  margin-bottom: 2rem;
  border-top: 1px solid var(--rule);
  border-bottom: 1px solid var(--rule);
  padding-bottom: 1rem;
}
.gloss { margin: 0; }
.gloss-entry {
  padding: 1.7rem 0;
  border-bottom: 1px solid var(--rule);
  /* The anchor target must clear the sticky header, or a jump from the index
     lands with the term's own name hidden behind it. */
  scroll-margin-top: 5rem;
}
.gloss-entry:first-child { padding-top: 0; }
.gloss dt {
  font-family: var(--serif);
  font-size: 1.25rem;
  font-weight: 600;
  color: var(--ink);
  margin-bottom: 0.6rem;
}
.gloss-aka {
  font-family: var(--sans);
  font-size: 0.72rem;
  font-weight: 400;
  color: var(--ink-3);
  margin-left: 0.5rem;
}
.gloss dd { margin: 0; }
.gloss dd p { margin-bottom: 0.7rem; }
.gloss-short {
  font-family: var(--serif);
  font-size: 1.02rem;
  color: var(--ink);
}
.gloss-why {
  font-family: var(--sans);
  font-size: 0.84rem;
  line-height: 1.6;
  color: var(--ink-2);
  border-left: 2px solid var(--rule-firm);
  padding-left: 0.9rem;
}
.gloss-why .label {
  display: block;
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--ink-3);
  margin-bottom: 0.25rem;
}
.gloss-link {
  font-family: var(--sans);
  font-size: 0.78rem;
  margin-bottom: 0 !important;
}

/* ── Glossary terms in prose ─────────────────────────────────────────────────
   A dotted underline, not a solid one: it has to read as "there is a
   definition here" rather than as a navigation link, because the sentence
   still works if the reader ignores it. Inherits the ink colour for the same
   reason — a coloured term would pull the eye out of the sentence. */
.term {
  color: inherit;
  text-decoration: none;
  border-bottom: 1px dotted var(--rule-firm);
  cursor: help;
}
.term:hover,
.term:focus-visible {
  border-bottom-style: solid;
  border-bottom-color: var(--accent);
  text-decoration: none;
}

/* ── The compounding argument ────────────────────────────────────────────────
   Deliberately not a card. It is the thesis of the whole site, so it gets a
   left rule in the accent and a slightly larger measure rather than a border
   box that would file it alongside the asides. */
.compound-note {
  border-left: 3px solid var(--accent);
  padding: 0.2rem 0 0.2rem 1.3rem;
  margin: 2.4rem 0;
}
.compound-note h4 {
  font-family: var(--sans);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--ink-2);
  margin-bottom: 0.7rem;
}
.compound-note p { margin-bottom: 0.8rem; }
.compound-note p:last-child { margin-bottom: 0; }
.compound-note .fineprint {
  font-family: var(--sans);
  font-size: 0.74rem;
  line-height: 1.55;
  color: var(--ink-3);
  margin-top: 1rem;
}

/* The claim itself, set as a pull-quote because it is the one sentence a
   reader should leave with — and the one an answer engine should extract. */
.compound-claim {
  font-family: var(--serif);
  font-size: 1.12rem;
  line-height: 1.45;
  font-style: italic;
  color: var(--ink);
  padding: 0.6rem 0;
}

@media (max-width: 34rem) {
  .compound-note { padding-left: 1rem; }
  .compound-claim { font-size: 1.02rem; }
}

/* ── The masthead needs two rows long before a phone ──────────────────────
 *
 * It is a single flex row — brand, the coverage topics, the utility links,
 * the theme button — and it wants 866px. Below that the topic cards were
 * being compressed, and from about 840px down the row pushed the whole
 * document sideways: 72px of horizontal scroll at 768, 191px at 600, on every
 * page, with or without a table on it.
 *
 * The two-row layout below is not new; it was written for phones and simply
 * started 336px too late. Switching at 55rem puts it in before any
 * compression begins rather than after the overflow has started.
 *
 * The 866px is measured, not guessed: clone `.shell-inner` into an
 * unconstrained box and read the width it takes. Re-measure that way if the
 * brand, a topic or a nav link ever changes length — the number moves with
 * the content, and nothing here will warn you.
 */
@media (max-width: 55rem) {
  .shell-inner {
    height: auto;
    padding: 0.5rem 1.5rem 0;
    flex-wrap: wrap;
    gap: 0.4rem 0.75rem;
  }
  .theme-btn { margin-left: auto; }
  /* Topics take the full second row; the utility links sit up on the brand
     row, where two short words fit beside the theme button. */
  .shell-topics {
    order: 3;
    width: 100%;
    margin: 0;
    gap: 0.4rem;
    padding-bottom: 0.4rem;
  }
  .shell-topics li { flex: 1 1 0; min-width: 0; }
  .shell-topics a {
    border-color: var(--rule);
    padding: 0.32rem 0.6rem;
  }
  .topic-label { font-size: 0.78rem; }
  .topic-note {
    font-size: 0.6rem;
    white-space: normal;
  }
  .shell-nav {
    order: 2;
    margin-left: auto;
    gap: 1rem;
    font-size: 0.78rem;
  }
  .shell-nav::-webkit-scrollbar { display: none; }
}

@media (max-width: 34rem) {

  /* On a phone the page gutter narrows to 1rem, so the masthead follows it
     in; the two-row layout itself came in at 55rem above. */
  .shell-inner { padding: 0.5rem 1rem 0; }
  .brand { font-size: 0.95rem; }

  /* Figures and reading column share the page's own gutter. */
  .wrap { padding-left: 1rem; padding-right: 1rem; }
  .breakout { margin-left: 0; margin-right: 0; }

  /* ...except that a .chapter sits OUTSIDE .wrap, so none of this reached it.
     Every heading, paragraph and table inside a chapter ran to both edges of
     a phone screen while the nav and the takeaways above them did not.
     The text gets the page's own 1rem. Charts and reproduced slides keep the
     full width on purpose: a figure that bleeds to the edge reads as
     deliberate, and 2rem off a 375px chart is a worse trade than a flush
     edge. The labels around a figure are prose, so they are inset with it —
     and with `>` rather than a descendant selector, so a figure nested inside
     a .column does not take the padding twice.

     A table inside a breakout figure is on the prose side of that line too —
     it is words and figures, not a picture — so it is listed here as well.
     Without it a stacked table set its numbers hard against both edges of the
     screen while the paragraph above it kept its margin. */
  .chapter .column { padding-left: 1rem; padding-right: 1rem; }
  .chapter > .breakout > .figure-head,
  .chapter > .breakout > figcaption,
  .chapter > .breakout > .table-scroll,
  .chapter > .table-scroll { padding-left: 1rem; padding-right: 1rem; }

  /* A chart's own labels are sized for the chart, not the prose. */
  .figure-head { flex-direction: column; align-items: flex-start; gap: 0.15rem; }
  .figure-unit { margin-left: 0 !important; }

  /* Stat rails read as two columns rather than four squeezed ones. */
  .rail-metric { flex-basis: 48%; padding-right: 0.6rem; }
  .stats { grid-template-columns: 1fr 1fr; }

  /* The place strip's facts wrap instead of overflowing. */
  .place-facts { gap: 0.3rem 1rem; font-size: 0.78rem; }

  /* The subscribe field already wraps the button onto its own row at this
     width; left at its intrinsic 101px it reads as an afterthought under a
     full-width input. Stacked, both rows are the same object. */
  .subscribe form { flex-direction: column; align-items: stretch; }
  .subscribe .btn { text-align: center; }

  /* Twenty year buttons at 393px is 18px each — enough to tap, too narrow for
     a label, so the bars alone carry the year and the panel names it. */
  .scrub-track { gap: 1px; }
  .scrub-year { font-size: 0; padding: 0.3rem 0 0.25rem; }
  .scrub-year-label { font-size: 1.8rem; }

  .seg-takeaways li { grid-template-columns: 1.4rem 1fr; gap: 0.6rem; }
  .t-body { font-size: 0.97rem; }
}

/* A horizontally scrollable region is invisible until you try it. Fade the
   right edge so there is something to see — the sub-nav and wide tables both
   rely on this. */
.table-scroll[data-overflow='true'] {
  -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 1.6rem), transparent);
  mask-image: linear-gradient(to right, #000 calc(100% - 1.6rem), transparent);
}

/* The sub-nav's fade goes on `.subnav`, which is the element that scrolls —
   NOT on `.subnav-inner`. A mask paints only inside its own element's box, and
   the inner is one viewport wide while its content runs to twice that, so
   masking the inner erased every link past the first screenful instead of
   fading the last one. The bar scrolled; the links were invisible.
   Scoped below the breakpoint because above it the group collapses behind the
   trigger, the bar no longer overflows, and a mask here would clip the
   absolutely positioned dropdown to the bar's own height. */
@media (max-width: 45.99rem) {
  .subnav[data-overflow='true'] {
    -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 1.6rem), transparent);
    mask-image: linear-gradient(to right, #000 calc(100% - 1.6rem), transparent);
  }
}

/* Stepping one year at a time, without having to hit a 19px target. */
.scrub-nav {
  display: none;
  align-items: center;
  justify-content: center;
  gap: 1rem;
  margin: 0.2rem 0 1rem;
  font-family: var(--sans);
}
.scrub-nav button {
  width: 2.6rem; height: 2.6rem;
  border: 1px solid var(--rule);
  border-radius: 50%;
  background: none;
  color: var(--ink-2);
  font-size: 1.1rem;
  line-height: 1;
  cursor: pointer;
  transition: border-color var(--t), color var(--t), opacity var(--t);
}
.scrub-nav button:hover:not(:disabled) { border-color: var(--accent); color: var(--accent); }
.scrub-nav button:disabled { opacity: 0.3; cursor: default; }
.scrub-nav button:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.scrub-nav [data-scrub-year] {
  min-width: 3.4rem;
  text-align: center;
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}
@media (max-width: 34rem) { .scrub-nav { display: flex; } }

/* ── Reading rhythm on a phone ────────────────────────────────────────────
 *
 * A phone screen is roughly a third the height of a laptop's, so a break that
 * reads as generous on desktop reads as nothing here. These are smaller in
 * absolute terms than the desktop values and larger as a share of the screen,
 * which is the ratio that decides whether a section feels separate. */
@media (max-width: 45.99rem) {
  .chapter { padding: 2.9rem 0; }
  .chapter + .chapter::before { margin-bottom: 2.9rem; }
  .chapter-head { margin-bottom: 1.3rem; }
  /* Figures and tables are the blocks that run longest on a phone; give them
     room to read as objects rather than as more of the same column. */
  figure, .compare, .table-scroll { margin-block: 2.2rem; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   Research section — the study pages that are not about one company

   Everything here is additive: no existing selector changes. The one override
   is `.ep-pick`, which opts out of a phone rule written for the twenty-year
   capital scrubber and wrong for an eleven-item picker. See below.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── The section index's study cards ───────────────────────────────────────
   A link that is a block, not a card with a link in it: the whole thing is the
   target, which is what makes it work on a phone. */
.study-list {
  max-width: var(--prose);
  margin: 1.4rem auto 0;
  display: grid;
  gap: 1rem;
}
.study {
  display: block;
  padding: 1.3rem 1.4rem;
  border: 1px solid var(--rule);
  border-left: 3px solid var(--accent);
  border-radius: 4px;
  background: var(--paper-raised);
  text-decoration: none;
  transition: border-color var(--t), background var(--t);
}
.study:hover, .study:focus-visible { border-color: var(--accent); }
.study h3 {
  margin: 0 0 0.4rem;
  font-family: var(--sans);
  font-size: 1.04rem;
  color: var(--ink);
}
.study p {
  margin: 0;
  font-family: var(--sans);
  font-size: 0.87rem;
  line-height: 1.6;
  color: var(--ink-2);
}
.study-cta {
  display: inline-block;
  margin-top: 0.7rem;
  font-family: var(--sans);
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--accent);
}

/* ── The four kinds of shock ───────────────────────────────────────────────
   Four short definitions that have to be readable side by side, because the
   point is the contrast between them. Two columns rather than four even on a
   wide screen: at four the text column is narrower than the words. */
.kind-grid {
  max-width: var(--prose);
  margin: 1.5rem auto 1.8rem;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1.1rem 1.4rem;
}
.kind { position: relative; padding-left: 0.9rem; }
.kind-swatch {
  position: absolute;
  left: 0; top: 0.28rem;
  width: 4px; height: calc(100% - 0.5rem);
  border-radius: 2px;
}
.kind h3 {
  margin: 0 0 0.3rem;
  font-family: var(--sans);
  font-size: 0.95rem;
  color: var(--ink);
}
.kind p {
  margin: 0;
  font-family: var(--sans);
  font-size: 0.83rem;
  line-height: 1.58;
  color: var(--ink-2);
}
.kind-eps {
  margin-top: 0.4rem !important;
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  color: var(--ink-3) !important;
}

/* ── The episode explorer ──────────────────────────────────────────────────
   Progressive: the panels are in the HTML and all eleven show until segment.js
   marks the wrapper enhanced. So the track and the stepper are hidden until
   there is something for them to drive — a visible control that does nothing
   is worse than no control. */
/* The side gutter is carried by `.column`, and this block is a sibling of one
   rather than a child, so it has to bring its own — without it the panel prose
   runs flush to both edges of a phone. `.breakout` gets away with no padding
   because a chart draws its own margins; a paragraph does not. */
.episodes {
  max-width: var(--wide);
  margin: 1.6rem auto 2.2rem;
  padding-inline: 1rem;
}
.episodes .scrub-track,
.episodes .scrub-nav { display: none; }
.episodes.is-enhanced .scrub-track { display: flex; }

/* The picker bars are the ranking chart from section two, so they have to sit
   on a shared baseline to be read as one. `.scrub-year` is a top-aligned
   column, which puts a short bar's label high and a tall bar's label low and
   turns eleven labels into a staircase. Pinning the content to the bottom of a
   fixed-height button gives both the bars and the labels one baseline each.
   Done on `.ep-pick` rather than on `.scrub-year`, because the capital page's
   twenty-year scrubber hides its labels at this size and is not affected. */
.ep-pick {
  justify-content: flex-end;
  height: 4.6rem;
  gap: 0.3rem;
}
.ep-pick i { border-radius: 2px; }

.ep-panel {
  display: grid;
  grid-template-columns: 1.5fr 1fr;
  gap: 2rem;
  padding: 1.6rem 0 0;
  border-top: 1px solid var(--rule);
  margin-top: 1.6rem;
}
/* Unenhanced, the panels are a sequence and each needs its own separator.
   Enhanced, only one is ever visible, so the top rule becomes the figure's
   own frame rather than a divider between things. */
.episodes.is-enhanced .ep-panel { display: none; margin-top: 0.4rem; }
.episodes.is-enhanced .ep-panel.is-current { display: grid; }

.ep-kind {
  display: inline-block;
  font-family: var(--sans);
  font-size: 0.66rem;
  font-weight: 700;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--kind, var(--ink-3));
  margin-bottom: 0.5rem;
}
.ep-main h3 { margin: 0 0 0.3rem; font-size: 1.35rem; }
.ep-when {
  font-family: var(--sans);
  font-size: 0.8rem;
  color: var(--ink-3);
  margin-bottom: 0.9rem;
}
.ep-main p { max-width: none; }
.ep-insight {
  margin-top: 1.1rem;
  padding-left: 0.9rem;
  border-left: 3px solid var(--accent);
  font-family: var(--sans);
  font-size: 0.9rem;
  line-height: 1.6;
  font-weight: 600;
  color: var(--ink);
}

.ep-side { font-family: var(--sans); }
.ep-figs {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.9rem 1rem;
  margin: 0 0 1.1rem;
  padding-bottom: 1.1rem;
  border-bottom: 1px solid var(--rule);
}
.ep-figs dt {
  font-size: 0.7rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--ink-3);
  margin-bottom: 0.2rem;
}
.ep-figs dd {
  margin: 0;
  font-size: 1.22rem;
  font-weight: 650;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
  line-height: 1.15;
}
.ep-side h4 {
  margin: 1.1rem 0 0.35rem;
  font-size: 0.7rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.ep-meta {
  font-size: 0.82rem;
  line-height: 1.55;
  color: var(--ink-2);
  margin: 0 0 0.5rem;
  max-width: none;
}
.ep-response, .ep-src {
  list-style: none;
  padding: 0;
  margin: 0;
  font-size: 0.82rem;
  line-height: 1.5;
  color: var(--ink-2);
}
.ep-response li, .ep-src li { margin-bottom: 0.45rem; }
.ep-response b { color: var(--ink); font-variant-numeric: tabular-nums; }
.ep-src a { color: var(--ink-2); }

/* The stepper's readout. Same job as [data-scrub-year] but it carries a name
   as well as a year, so it cannot have that element's fixed narrow width. */
.scrub-nav [data-ep-label] {
  min-width: 10rem;
  text-align: center;
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--ink);
}

/* ── Sources, and the table's unit sub-headings ────────────────────────────*/
.src-list {
  max-width: var(--prose);
  margin: 1.2rem auto 0;
  padding: 0;
  list-style: none;
  font-family: var(--sans);
  font-size: 0.85rem;
  line-height: 1.55;
}
.src-list li {
  margin-bottom: 0.7rem;
  padding-left: 0.9rem;
  border-left: 2px solid var(--rule);
}
.src-list a { color: var(--ink-2); }
.th-sub {
  display: block;
  font-weight: 400;
  font-size: 0.72rem;
  color: var(--ink-3);
  letter-spacing: 0.02em;
}

/* ── Narrow ────────────────────────────────────────────────────────────────*/
@media (max-width: 52rem) {
  .ep-panel, .episodes.is-enhanced .ep-panel.is-current {
    grid-template-columns: 1fr;
    gap: 1.4rem;
  }
}

@media (max-width: 42rem) {
  .kind-grid { grid-template-columns: 1fr; gap: 1rem; }
  .ep-main h3 { font-size: 1.15rem; }
  .ep-figs dd { font-size: 1.1rem; }

  /* Eleven buttons at 393px is about 34px each, which fits a four-digit year.
     The rule above this one blanks `.scrub-year` labels because the capital
     page puts TWENTY of them in the same space and they do not fit there.
     Opting out by class rather than loosening that rule keeps the two pickers
     independent — the year is the only thing identifying an episode here, and
     without it the track is eleven anonymous bars. */
  .ep-pick { font-size: 0.68rem; padding: 0.3rem 0 0.25rem; }
  .ep-pick span { font-variant-numeric: tabular-nums; }
}
