/* ─────────────────────────────────────────────────────────────────────────
   One typeface, on two axes.

   The brand guideline sets the identity in Proxima Nova, which is licensed and
   cannot be self-hosted. Moti asked instead for "the Economist's sans" — Econ
   Sans, a custom Dalton Maag cut, equally unavailable. **Archivo** is the face
   that can actually ship: a grotesque drawn for small sizes and dense columns,
   under the SIL Open Font License, and fetched by `npm run fonts`.

   It is one **variable** file carrying weight 100–900 and width 62–125, which
   is what lets a single family do three jobs. Headlines take a condensed width,
   the way a newspaper sets them and the way a bilingual paper must, because
   every headline here is set twice and narrow type is what buys the room.
   Running text takes the normal width. Labels take the same face, small and
   tracked — which is also how The Economist sets a label, and why the site no
   longer needs a monospace to sound instrumental.

   88 kB, replacing 394 kB across ten files.
   ───────────────────────────────────────────────────────────────────────── */

@font-face {
  font-family: 'Archivo';
  src: url('/assets/fonts/archivo-variable.woff2') format('woff2-variations');
  font-weight: 100 900;
  font-stretch: 62% 125%;
  font-style: normal;
  font-display: swap;
}

/* Ethiopic, for the Amharic edition. Archivo has no Ethiopic glyphs, so the
   browser takes these for Ethiopic characters only (unicode-range) and never
   downloads them for a page with none. Noto Sans Ethiopic, OFL. */
@font-face {
  font-family: 'Archivo';
  src: url('/assets/fonts/noto-sans-ethiopic-400.woff2') format('woff2');
  font-weight: 100 549;
  font-style: normal;
  font-display: swap;
  unicode-range: U+1200-139F, U+2D80-2DDF, U+AB00-AB2F;
}
@font-face {
  font-family: 'Archivo';
  src: url('/assets/fonts/noto-sans-ethiopic-700.woff2') format('woff2');
  font-weight: 550 900;
  font-style: normal;
  font-display: swap;
  unicode-range: U+1200-139F, U+2D80-2DDF, U+AB00-AB2F;
}

/* ═══════════════════════════════════════════════════════════════════════════
   E N S I G H T   ·   T H E   S C R E E N   S Y S T E M

   Built from the Brand Identity Manual rather than from a previous stylesheet.
   Two sentences in that manual decide almost everything here:

     "The number is the picture. Everything else supports it."
     "Air is a brand asset. A page is finished when something has been removed,
      not when the space is filled."

   So this is not a dense wire service. Every item Ensight publishes carries a
   figure — no other publication can say that — and the figure is therefore the
   compositional anchor at every scale, with the words hanging off it. The page
   holds few things, large, with room around them.

   What is taken from the Financial Times, Reuters and the Economist is their
   discipline — a real grid, named bands, rules instead of boxes, a strict
   hierarchy — and not their density, which would break the manual's own rule.

   Contents
     01  Tokens
     02  Reset and base type
     03  The grid
     04  The figure
     05  The flag, the masthead, the footer
     06  Bands
     07  The briefing: lead, second, third, list
     08  The numbers
     09  Diary, glossary panel, magazine, sponsors
     10  Charts, pictures, tables
     11  Forms and controls
     12  Utilities
   ═══════════════════════════════════════════════════════════════════════════ */

/* ───────────────────────────── 01 · TOKENS ───────────────────────────── */

:root {
  /* The four brand colours, exactly as the guidelines set them. */
  --red: #dd0033;          /* Ensight Red · the accent, under 5 % of a screen */
  /* Deep blue is now a **data** colour and nothing else: the one chart
     series, an indicator's value, a change figure. The brand guideline lists
     Red + Blue and Black + Blue as pairings to avoid, so blue has left every
     ground, rule and link on the site; what it kept is the job only it does,
     which is to mean "this is a measurement". */
  --blue: #081ea0;
  --ink: #0a0a0a;          /* Black 6 C */
  --paper: #ffffff;
  --paper-2: #f7f7f7;      /* Cool Gray 1 C */

  --ink-2: #3a3a3c;        /* running text that is not the main voice */
  --muted: #6e6e72;        /* ink 3 · labels, sources, folios */
  --line: #dcdcda;         /* the hairline */
  --line-2: #eaeae8;       /* chart gridlines, panel edges */
  /* A link is ink, and answers in red. Blue is reserved for figures now. */
  /* Links take the brand's deep blue. Blue + White is one of the four
     pairings the guideline approves, and a link that looks like body text is
     not a link. */
  --link: #081ea0;
  --teal: #0b7a6b;
  --gold: #a25c00;
  --red-2: #b00028;
  --red-wash: #fde8ee;
  --paper-3: #eaeae8;
  --grid: #eaeae8;
  /* The dot the whole guideline is printed on. Sampled from the document: a
     20-pixel pitch, and a value barely above the ground — measured at about
     eleven levels of difference, which is why it reads as texture and never as
     decoration. */
  --dot: #eef0f0;
  /* The wave field from page 16, defined once. The field, the rule and the
     footer edge are three windows onto the same tile. */
  --wave: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='70' viewBox='0 0 120 70'%3E%3Cg fill='none' stroke='%23dd0033' stroke-width='7'%3E%3Cpath d='M0 4 C20 4, 40 10, 60 10 S100 4, 120 4'/%3E%3Cpath d='M0 18 C20 18, 40 24, 60 24 S100 18, 120 18'/%3E%3Cpath d='M0 32 C20 32, 40 38, 60 38 S100 32, 120 32'/%3E%3Cpath d='M0 46 C20 46, 40 52, 60 52 S100 46, 120 46'/%3E%3Cpath d='M0 60 C20 60, 40 66, 60 66 S100 60, 120 60'/%3E%3C/g%3E%3C/svg%3E");

  /* Ensight Red for small text. The brand red exactly on paper; lifted on the
     black ground, where #DD0033 measures 3.89:1 and small text needs 4.5:1.
     Almost every piece of small red text on this site is Afaan Oromoo — the
     twin under each English headline — so not lifting it would fail the Oromo
     line on every item while the English beside it passed. The manual already
     lifts deep blue on black for the same reason. Figures keep the true red:
     above 24 px the threshold is 3:1, which #DD0033 clears. */
  --red-text: #dd0033;

  /* Grounds that never invert. `--ink` and `--paper` swap between themes so
     text stays readable; a band that *is* a dark field has to hold its value,
     or the video slab turns white in dark mode. The red inside them is the
     lifted one at all times, because they are always dark. */
  --ink-panel: #0a0a0a;
  --ink-panel-2: #232323;  /* the ink ground, one step up: a hover on a dark field */
  --on-panel: #f4f4f4;
  --on-panel-quiet: rgba(255, 255, 255, 0.72);
  --red-on-panel: #f4355e;

  /* Three faces, one job each. No fourth. */
  /* One family in three roles. `--mono` keeps its name because two hundred
     rules call it and the job it names — the label voice — has not changed;
     what changed is that the job no longer needs a second typeface. Figures
     still align, because every rule that needs it sets `tabular-nums`. */
  --display: 'Archivo', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --sans: 'Archivo', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --mono: 'Archivo', system-ui, -apple-system, 'Segoe UI', sans-serif;

  /* The width axis. A headline is set narrow, a figure narrower still — the
     two places a newspaper buys room — and everything else runs normal. */
  --wide-normal: 100%;
  --wide-head: 88%;
  --wide-fig: 84%;

  /* The web grid, from the manual: twelve columns at 1280 px with a 16 px
     minimum gutter. Text sets on 4, 6 or 12 columns and never on an odd span. */
  --wrap: 1280px;
  --cols: 12;
  --gutter: 24px;

  /* The figure, in four ranks. Rank one appears once on a page. */
  --fig-1: clamp(56px, 7.4vw, 104px);
  --fig-2: clamp(34px, 3.6vw, 46px);
  --fig-3: 28px;
  --fig-4: 20px;

  /* Headlines, tracked as the manual tracks them: −.022 em at text size,
     −.026 at section size, −.03 above 24 px. */
  --h-1: clamp(30px, 3.4vw, 44px);
  --h-2: clamp(22px, 2.2vw, 27px);
  --h-3: 19px;
  --h-4: 17px;
  --h-section: clamp(20px, 2vw, 25px);

  --track-display: -0.03em;
  --track-section: -0.026em;
  --track-text: -0.022em;
  --track-label: 0.11em;

  /* Air. The manual keeps 12 mm clear above a headline; these are its screen
     equivalents, and they are the only vertical values used between bands. */
  --air: 26px;
  --air-2: 44px;
  --band: 68px;

  --rule: 2px;             /* the ink rule above a band */
  --rule-heavy: 3px;       /* between the two language columns: neither is subordinate */
  --flag: 6px;

  --radius: 4px;
  color-scheme: light;
}

/* Dark is black, as the manual sets it, not navy. The guidelines name a dark
   theme in the brand's positioning, so it is a first-class mode and not an
   inversion: deep blue lifts for text, red lifts for small text, and the
   hairline gets enough weight to survive on black. */
:root[data-theme='dark'] {
  --paper: #0a0a0a;
  --paper-2: #151515;
  --ink: #f4f4f4;
  --ink-2: #cfcfcf;
  --muted: #9a9a9a;
  --line: #2e2e2e;
  --line-2: #242424;
  --paper-3: #1f1f1f;
  --grid: #242424;
  --dot: #1b1b1b;
  --blue: #a8b3e8;
  --link: #a8b3e8;
  --red-text: #f4355e;      /* 5.2:1 on black */
  --red-wash: rgba(221, 0, 51, 0.16);
  color-scheme: dark;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) {
    --paper: #0a0a0a;
    --paper-2: #151515;
    --ink: #f4f4f4;
    --ink-2: #cfcfcf;
    --muted: #9a9a9a;
    --line: #2e2e2e;
    --line-2: #242424;
    --paper-3: #1f1f1f;
    --grid: #242424;
    --dot: #1b1b1b;
    --blue: #a8b3e8;
    --link: #a8b3e8;
    --red-text: #f4355e;
    --red-wash: rgba(221, 0, 51, 0.16);
    color-scheme: dark;
  }
}

/* ──────────────────── 02 · RESET AND BASE TYPE ──────────────────── */

* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }

body {
  /* The dot grid the brand guideline lays every one of its pages on. It sits
     under the whole site and is covered wherever a band has a ground of its
     own — which is exactly how the document uses it: the paper has a texture,
     and anything printed on the paper hides it. */
  background-color: var(--paper);
  background-image: radial-gradient(var(--dot) 1.2px, transparent 1.2px);
  background-size: 20px 20px;
  color: var(--ink);
  font-family: var(--sans);
  font-size: 16px;               /* the manual: 16 px on 1.5 on screen */
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

a { color: inherit; }

/* Archivo (the one face, ADR-0007) at 700, tracked by size. Never below 9 px,
   never as body copy, never letter-spaced open. */
h1, h2, h3, h4, h5 {
  font-family: var(--display);
  font-weight: 700;
  letter-spacing: var(--track-text);
  line-height: 1.1;
  margin: 0 0 10px;
  text-wrap: balance;
}
h1 { font-size: var(--h-1); letter-spacing: var(--track-display); }
h2 { font-size: var(--h-2); letter-spacing: var(--track-section); }
h3 { font-size: var(--h-3); }

/* Running text is ragged right and measured at 62 to 72 characters. Never
   hyphenated: breaking a geminate across a line changes an Afaan Oromoo word. */
p, li { text-wrap: pretty; hyphens: none; }
p { margin: 0 0 12px; max-width: 68ch; }
.measure { max-width: 68ch; }
.measure-page { max-width: 760px; }

/* The label style — Archivo, uppercase, tracked: labels, eyebrows, folios,
   sources, dates, and anything a reader might need to copy exactly. */
.caps {
  font-family: var(--mono);
  font-size: 10.5px;
  font-weight: 500;
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--muted);
}

/* Afaan Oromoo. A headline and its twin are drawn by the same hand — display
   face, red, never slanted. Running text in Afaan Oromoo takes the same ink as
   the English, because red is never used over a large area. */
.om { color: var(--red-text); font-family: var(--display); font-weight: 700; letter-spacing: var(--track-text); font-style: normal; }
.caps .om, .mark .om { font-family: var(--mono); font-weight: 500; letter-spacing: var(--track-label); }
.om-text { color: var(--ink-2); font-style: normal; }
.standfirst-om { color: var(--red-text); }

.skip { position: absolute; left: -9999px; background: var(--ink); color: var(--paper); padding: 10px 14px; }
.skip:focus { left: 8px; top: 8px; z-index: 100; }

/* ───────────────────────────── 03 · THE GRID ─────────────────────────────
   Twelve columns at 1280 px, 24 px gutter. Editorial text sets on 4, 6 or 12
   columns — never on an odd span, because a narrow odd column sets a bad rag
   in Afaan Oromoo, whose words run longer than their English twins.

   `.wrap` centres the page; `.g` turns any container into the grid; `.c4`,
   `.c6`, `.c8` and `.c12` are the only spans an editorial block may take. */

.wrap { max-width: var(--wrap); margin: 0 auto; padding: 0 20px; }

.g {
  display: grid;
  grid-template-columns: repeat(var(--cols), minmax(0, 1fr));
  gap: var(--gutter);
}
.c4  { grid-column: span 4; min-width: 0; }
.c6  { grid-column: span 6; min-width: 0; }
.c8  { grid-column: span 8; min-width: 0; }
.c12 { grid-column: span 12; min-width: 0; }

/* The grid folds in two steps, never more: twelve columns become six, then
   one. A layout that reflows at five widths cannot be checked at any of them. */
@media (max-width: 1000px) {
  :root { --cols: 6; --gutter: 20px; }
  .c8, .c12 { grid-column: span 6; }
}
@media (max-width: 640px) {
  :root { --cols: 1; --gutter: 0px; }
  .c4, .c6, .c8, .c12 { grid-column: span 1; }
}

/* ──────────────────────────── 04 · THE FIGURE ────────────────────────────
   The number is the picture.

   Every Ensight item carries a figure, which is the thing no other publication
   can say, so the figure leads at every scale and the words support it. It is
   always the display face at 700, always red, always tabular and lining so a
   column of figures aligns, and always tracked tight, in a narrower width of
   the same variable face. */

.fig {
  display: block;
  font-family: var(--display);
  font-weight: 700;
  color: var(--red);
  line-height: 0.92;
  letter-spacing: var(--track-display);
  font-variant-numeric: tabular-nums lining-nums;
  /* A figure is never broken across lines: "US$10.7bn" is one word. */
  white-space: nowrap;
}
.fig-1 { font-size: var(--fig-1); }
.fig-2 { font-size: var(--fig-2); }
.fig-3 { font-size: var(--fig-3); letter-spacing: var(--track-section); }
.fig-4 { font-size: var(--fig-4); letter-spacing: var(--track-section); }

/* ─────────────── 05 · THE FLAG, THE MASTHEAD, THE FOOTER ─────────────── */

/* Six pixels of Ensight Red, full bleed, above everything, on every page of the
   public site (the desk has its own stylesheet, desk.css, and no flag). The one
   place red covers an area. The
   manual allows it to wipe in once; reduced motion skips that and the flag is
   simply there. */
.flag { height: var(--flag); background: var(--red); position: relative; z-index: 60; }
@media (prefers-reduced-motion: no-preference) {
  .flag { transform-origin: left center; animation: flag-wipe 520ms cubic-bezier(0.22, 0.61, 0.36, 1) both; }
  @keyframes flag-wipe { from { transform: scaleX(0); } to { transform: scaleX(1); } }
}

/* The masthead. The mark, the sections, the tools — on one line from 1100 px,
   two below it. It holds to the top while reading and loses its descriptor
   after 48 px of scroll; on a phone the tools step aside going down the page
   and return on any upward scroll. */
.sitehead { position: sticky; top: 0; z-index: 40; background: var(--paper); }
.sitehead[data-behaviour='moving'] .nav,
.sitehead[data-behaviour='moving'] .tools { transition: padding 160ms ease, max-height 200ms ease, opacity 160ms ease; }
.sitehead[data-shrunk='yes'] { box-shadow: 0 6px 18px -14px rgba(0, 0, 0, 0.45); }
.sitehead[data-shrunk='yes'] .nav { padding-top: 8px; padding-bottom: 8px; }
.sitehead[data-shrunk='yes'] .wm small { display: none; }

.nav {
  display: flex; align-items: center; gap: 12px 26px; flex-wrap: wrap;
  padding: 16px 0 14px;
  border-bottom: var(--rule) solid var(--ink);
}
/* The lockup: the mark, a hairline, then what it is. The label style at 500,
   tracked, ink 3 — never coloured, never bold, never italic. */
.wm { display: inline-flex; flex-direction: column; gap: 6px; text-decoration: none; color: var(--ink); }
/* The wordmark is painted, not placed: the artwork supplies the shape through a
   mask and the colour comes from this page's own `currentColor`. Placed in an
   `<img>`, the file is its own document and the browser resolves its
   `currentColor` against the reader's system preference rather than the site's
   theme — which made the mark white for anyone whose laptop is set to dark, and
   so invisible the moment they toggled the site to light. */
.wmimg {
  display: block;
  background-color: currentColor;
  -webkit-mask: url('/assets/brand/ensight-wordmark.svg') no-repeat center / contain;
  mask: url('/assets/brand/ensight-wordmark.svg') no-repeat center / contain;
}
/* Anything too old for masks gets the ink artwork, which is at least legible on
   the light theme rather than a blank space on both. */
@supports not ((-webkit-mask: url('/a.svg') no-repeat) or (mask: url('/a.svg') no-repeat)) {
  .wmimg { background: url('/assets/brand/wordmark-ink-300.png') no-repeat center / contain; }
}
.wm small {
  display: block; font-family: var(--mono); font-size: 9px; letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--muted); font-weight: 500; border-top: 1px solid var(--ink); padding-top: 6px;
}
.navlinks { display: flex; gap: 20px; margin-left: auto; flex-wrap: wrap; }
.navlinks a {
  font-family: var(--mono); font-size: 11px; letter-spacing: 0.1em; text-transform: uppercase;
  text-decoration: none; padding-bottom: 4px; border-bottom: 2px solid transparent; white-space: nowrap;
}
.navlinks a:hover { border-bottom-color: var(--line); }
.navlinks a[aria-current='page'] { color: var(--red-text); border-bottom-color: var(--red); }
.tools { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }

@media (max-width: 1100px) { .navlinks { margin-left: 0; order: 3; width: 100%; gap: 16px; overflow-x: auto; flex-wrap: nowrap; scrollbar-width: none; } .navlinks::-webkit-scrollbar { display: none; } .tools { margin-left: auto; } }
/* Below a phone's width the tools row wraps rather than pushing the page
   sideways; a business daily that scrolls horizontally on a phone is broken. */
@media (max-width: 560px) {
  .tools { gap: 8px; }
  .langtoggle button { padding: 7px 9px; font-size: 9px; }
  .btn.sm { padding: 8px 11px; }
  .iconbtn { width: 30px; height: 30px; }
}
@media (max-width: 700px) {
  /* Hidden from the keyboard too: invisible links in the tab order are a trap. */
  .sitehead[data-tools='out'] .tools { max-height: 0; opacity: 0; overflow: hidden; pointer-events: none; visibility: hidden; }
  .sitehead .tools { max-height: 80px; opacity: 1; }
}
@media (prefers-reduced-motion: reduce) { .sitehead .nav, .sitehead .tools { transition: none !important; } }

/* The date line: what day it is, where we are, what we promise, and what is on
   sale. A business daily says this and then gets on with the news. */
.dateline {
  display: flex; align-items: baseline; gap: 6px 24px; flex-wrap: wrap;
  font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--muted);
  padding: 13px 0;
  border-bottom: 1px solid var(--line);
  margin-bottom: var(--air-2);
}
.dateline .today { color: var(--ink); }
.dateline a { color: var(--link); text-decoration: none; }
.dateline a:hover { text-decoration: underline; }
.dateline .issueline { margin-left: auto; }
@media (max-width: 760px) { .dateline { gap: 4px 16px; } .dateline .issueline { margin-left: 0; } }

/* The foot of every page is the one full-bleed field of deep blue on the site.
   The manual gives red to the flag and to the figure that is the story, and
   names white on deep blue as a safe pairing; the footer is the right place for
   the second colour to hold an area, because nothing editorial is set in it.
   It is the same ground in both themes — `--ink-panel` never lifts — so the
   page ends on the brand rather than on whichever background the reader chose. */
.footground { background: var(--ink-panel); color: #fff; margin-top: var(--band); }
/* Every link on this ground is white, including the ones the generic link
   rule further down would otherwise paint in the brand blue — which on a blue
   field is a link you cannot see. The selector carries enough specificity to
   win that rule outright rather than relying on source order. */
.footground a,
.footground p a:not(.btn):not(.chip),
.footground .note a { color: #fff; }
footer {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: var(--gutter);
  padding: 40px 0 30px;
}
/* The footer's column headings. They are h2 rather than h4 — the footer is
   its own landmark and starts its own outline, and an h4 after an h2 skips a
   level a screen reader navigates by. The size is unchanged. */
footer .foothead { font-size: 15px; margin-bottom: 8px; color: #fff; font-family: var(--display); font-weight: 700; letter-spacing: var(--track-text); }
/* Secondary text on the blue ground: an opacity, not a grey, so it stays a
   tint of the same field. At 0.78 over #081EA0 it measures 8.4:1 on white. */
footer p { font-size: 14px; color: rgba(255, 255, 255, 0.78); max-width: 40ch; }
.footlinks { display: flex; flex-wrap: wrap; gap: 6px 16px; }
.footlinks a { font-size: 14px; text-decoration: none; border-bottom: 1px solid rgba(255, 255, 255, 0.35); padding-bottom: 1px; }
.footlinks a:hover { border-bottom-color: #fff; }
.foot-mark { color: #fff; margin-bottom: 12px; }
/* The endorsement, once per document, here only. */
.endorse { display: flex; flex-direction: column; gap: 2px; margin: 0 0 12px; }
.endorse .caps { color: rgba(255, 255, 255, 0.7); }
.endorse b { font-family: var(--display); font-weight: 700; font-size: 15px; letter-spacing: var(--track-text); color: #fff; }
.legal { display: flex; justify-content: space-between; gap: 12px; flex-wrap: wrap; padding: 14px 0 34px; border-top: 1px solid rgba(255, 255, 255, 0.24); }
.legal span { font-family: var(--mono); font-size: 10.5px; color: rgba(255, 255, 255, 0.78); }
.legal a { text-decoration: none; }
.legal a:hover { text-decoration: underline; }
/* Another company's mark keeps its own colour everywhere else on the site; on
   this ground the brand greens and reds fall below three to one, so here — and
   only here — the marks take the field's own white. It is the one change the
   brands' own dark-ground guidance allows: the shape is untouched. */
.footground .svc .icon { color: #fff; }

/* ───────────────────────────── 06 · BANDS ─────────────────────────────
   A page is a stack of named bands. A band is a 2 px ink rule, a title in the
   display face, an optional note and link, then its content — and nothing else
   is furniture. This is the shape a broadsheet front has, and it lets a reader
   find the numbers without reading the news. */

.band, .slice { margin: 0 0 var(--band); }
.sechead {
  display: flex; align-items: baseline; gap: 8px 20px; flex-wrap: wrap;
  border-top: var(--rule) solid var(--ink);
  padding-top: 10px; margin: 0 0 var(--air);
}
.sechead h2 { font-size: var(--h-section); letter-spacing: var(--track-section); margin: 0; }
.sechead h2 .om { font-size: inherit; }   /* the twin is never smaller */
.sechead .secnote { font-family: var(--mono); font-size: 10px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--muted); }
.sechead .seclink {
  margin-left: auto; white-space: nowrap;
  font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--link); text-decoration: none; border-bottom: 1px solid transparent; padding-bottom: 2px;
}
.sechead .seclink:hover { border-bottom-color: currentColor; }

/* ────────────────── 07 · THE BRIEFING ──────────────────
   A broadsheet cascade: one lead, then two, then three, then the rest as a
   list. The rank of an item is carried by the size of its figure before
   anything else, so the page can be read by its numbers alone. */

/* The spans live on the grid, not on the items: the same item styles are used
   on a section front, where the container is a plain auto-fit grid. */
.briefing { display: grid; gap: var(--air-2) var(--gutter); grid-template-columns: repeat(var(--cols), minmax(0, 1fr)); }
.briefing > .lead-story { grid-column: span 12; }
.briefing > .second { grid-column: span 6; }
.briefing > .third { grid-column: span 6; }
.briefing > .ranked { grid-column: span 12; }
@media (max-width: 1000px) {
  .briefing > .lead-story, .briefing > .ranked { grid-column: span 6; }
  .briefing > .second, .briefing > .third { grid-column: span 3; }
}
@media (max-width: 640px) {
  .briefing > .lead-story, .briefing > .second, .briefing > .third, .briefing > .ranked { grid-column: span 1; }
}

/* A section front: the same column items, three across, on their own grid. */
.news { display: grid; grid-template-columns: 1fr; gap: var(--air-2) var(--gutter); }
@media (min-width: 560px) { .news { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 720px) { .news { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (min-width: 940px) { .news { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
@media (min-width: 1320px) { .news { grid-template-columns: repeat(5, minmax(0, 1fr)); } }

/* ── The lead ──
   The one place the manual's bilingual spread comes to screen: the two
   languages in equal columns with the heavier rule between them, same size,
   same leading, same ink, because neither edition is subordinate. Afaan Oromoo
   runs longer, so its column is allowed to be deeper — the answer is never to
   shrink the type. */
.lead-story {
  min-width: 0;
  display: block; text-decoration: none;
  border-top: 3px solid var(--cat, var(--ink));
  padding-top: 14px;
}
.lead-story .wtop { display: flex; justify-content: space-between; align-items: baseline; gap: 6px 16px; flex-wrap: wrap; margin-bottom: 14px; }
.lead-story .fig { margin: 0 0 18px; }
.lead-story:hover .fig { color: var(--red-2); }

.spread {
  display: grid;
  grid-template-columns: 1fr var(--rule-heavy) 1fr;
  gap: 0 var(--gutter);
  border-top: 1px solid var(--line);
  padding-top: 18px;
}
.spread .edition { min-width: 0; }
.spread .divider { background: var(--ink); width: var(--rule-heavy); }
.spread h2 { font-size: var(--h-1); letter-spacing: var(--track-display); margin: 0 0 10px; }
.spread p { font-size: 15.5px; color: var(--ink-2); margin: 0; max-width: 62ch; }
.spread .edlabel { display: block; margin-bottom: 8px; }
.lead-story:hover .spread h2 { color: var(--red); }
.lead-story .lsrc {
  display: block; margin-top: 16px; padding-bottom: 2px;
  font-family: var(--mono); font-size: 10px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted);
}
@media (max-width: 760px) {
  /* Stacked, the heavier rule runs across instead of down. */
  .spread { grid-template-columns: 1fr; }
  .spread .divider { width: auto; height: var(--rule-heavy); margin: 18px 0; }
}

/* ── Second rank: two items on six columns ── */
.second { min-width: 0; text-decoration: none; border-top: var(--rule) solid var(--cat, var(--ink)); padding-top: 12px; }
.second .fig { margin: 8px 0 8px; }
.second h3 { font-size: var(--h-2); letter-spacing: var(--track-section); margin: 0 0 4px; }
.second:hover h3 { color: var(--red); }
.second .hom { display: block; color: var(--red-text); font-family: var(--display); font-weight: 700; font-size: 16px; line-height: 1.24; letter-spacing: var(--track-text); margin-bottom: 8px; }
.second p { font-size: 15px; color: var(--ink-2); margin: 0 0 10px; }
.second .src { font-family: var(--mono); font-size: 10px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted); }

/* ── Third rank: three items on four columns ── */
.third { min-width: 0; text-decoration: none; border-top: var(--rule) solid var(--cat, var(--ink)); padding-top: 12px; }
.third .fig { margin: 8px 0 7px; }
.third h3 { font-size: var(--h-3); margin: 0 0 3px; }
.third:hover h3 { color: var(--red); }
.third .hom { display: block; color: var(--red-text); font-family: var(--display); font-weight: 700; font-size: 14px; line-height: 1.25; letter-spacing: var(--track-text); margin-bottom: 7px; }
.third p { font-size: 14px; color: var(--ink-2); margin: 0 0 9px; }
.third .src { font-family: var(--mono); font-size: 9.5px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted); }

/* ── The rest: a ranked list, figures down the left edge ──
   The figure column keeps its width whether or not an item has a figure, so a
   reader scanning for a number runs their eye down one axis. */
.ranked { border-top: 1px solid var(--line); }
.ranked .row {
  display: grid; grid-template-columns: minmax(92px, 132px) 1fr minmax(0, 88px);
  gap: 0 var(--gutter); align-items: baseline;
  padding: 15px 0; border-bottom: 1px solid var(--line); text-decoration: none;
}
.ranked .row:hover h3 { color: var(--red); }
.ranked .wcat { display: block; font-family: var(--mono); font-size: 9px; letter-spacing: var(--track-label); text-transform: uppercase; color: var(--muted); margin-top: 6px; }
.ranked h3 { font-size: var(--h-4); margin: 0; line-height: 1.25; }
.ranked .hom { display: block; color: var(--red-text); font-family: var(--display); font-weight: 700; font-size: 14px; line-height: 1.28; margin-top: 2px; letter-spacing: var(--track-text); }
.ranked .src { display: block; font-family: var(--mono); font-size: 9.5px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted); margin-top: 6px; }
.ranked .when { font-family: var(--mono); font-size: 9.5px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted); text-align: right; white-space: nowrap; }
@media (max-width: 640px) {
  .ranked .row { grid-template-columns: 76px 1fr; }
  .ranked .when { display: none; }
}

/* ──────────────────────────── 08 · THE NUMBERS ────────────────────────────
   Ensight's signature band: the figures the desk tracks, each with the change
   and the period that make it worth anything. Four across on a full page —
   large enough that the figure is the picture, rather than eight squeezed into
   a terminal rail.

   Direction is an arrow, never a colour. Eight cells in green and red would
   spend the whole of the manual's red budget on decoration and collide with
   the category colours. */
.numbers { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 0; border-top: var(--rule) solid var(--blue); }
.numbers .cell {
  padding: 16px 20px 18px 0; margin-right: 20px;
  border-bottom: 1px solid var(--line); border-right: 1px solid var(--line);
  text-decoration: none; min-width: 0; overflow: hidden;
}
.numbers .cell:nth-child(4n) { border-right: 0; margin-right: 0; padding-right: 0; }
.numbers .rlabel {
  display: block; font-family: var(--mono); font-size: 9.5px; font-weight: 500;
  letter-spacing: var(--track-label); text-transform: uppercase; color: var(--muted);
  /* Wraps rather than being cut off — "Reserves, import cover" lost its last
     word on a phone — and holds two lines in every cell, so the values below
     stay level across the row whether a label takes one line or two. */
  white-space: normal; min-height: 2.5em; line-height: 1.25;
}
.numbers .rvalue {
  display: block; margin: 9px 0 6px;
  font-family: var(--display); font-weight: 700; font-size: clamp(26px, 2.6vw, 34px); line-height: 1;
  letter-spacing: var(--track-section); font-variant-numeric: tabular-nums lining-nums;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.numbers .cell:hover .rvalue { color: var(--red); }
.numbers .rfoot { display: block; font-family: var(--mono); font-size: 9.5px; letter-spacing: 0.05em; color: var(--muted); line-height: 1.55; }
.numbers .rfoot > span { display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.numbers .rchg { color: var(--ink-2); font-variant-numeric: tabular-nums; }
.numbers .arrow { font-size: 8px; }
@media (max-width: 1000px) { .numbers { grid-template-columns: repeat(2, minmax(0, 1fr)); } .numbers .cell:nth-child(4n) { border-right: 1px solid var(--line); margin-right: 20px; padding-right: 20px; } .numbers .cell:nth-child(2n) { border-right: 0; margin-right: 0; padding-right: 0; } }
/* Two across on a phone rather than one. Eight indicators in a single column
   is fifteen hundred pixels of scrolling before the reader reaches the news,
   and they came for the news. The figures stay legible because they are short. */
@media (max-width: 480px) {
  .numbers .cell { padding: 13px 14px 14px 0; margin-right: 14px; }
  .numbers .rvalue { font-size: 25px; }
}

/* ──────────── 09 · DIARY, GLOSSARY, MAGAZINE, SPONSORS ──────────── */

/* The diary: dates down the left in the data face, the event beside them. */
.diary { border-top: 1px solid var(--line); }
.drow { display: grid; grid-template-columns: minmax(84px, 116px) 1fr; gap: 0 var(--gutter); padding: 11px 0; border-bottom: 1px solid var(--line); align-items: baseline; }
.ddate { display: inline-flex; align-items: center; min-height: 34px; padding: 6px 10px; background: var(--paper-2); border-left: 3px solid var(--ink); font-family: var(--mono); font-size: 10px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink); font-variant-numeric: tabular-nums; }
.ddate .dest { color: var(--muted); }
.drow b { font-family: var(--sans); font-weight: 600; font-size: 14.5px; line-height: 1.35; display: block; }
.drow .dom { display: block; color: var(--red-text); font-size: 13px; line-height: 1.3; margin-top: 1px; }

/* The word of the week: the one filled panel on the front page. It is White on
   Black, which the guideline names as safe, and it uses `--ink-panel` rather
   than `--ink` because this ground is dark in *both* themes — `--ink` swaps
   with the theme and would turn the panel near-white under a reader who has
   chosen dark, taking the white type with it. */
.word { background: var(--ink-panel); color: #fff; padding: 26px 28px 28px; }
.word h3 { color: #fff; font-size: 25px; letter-spacing: var(--track-section); margin: 0 0 12px; }
.word .wordom { color: #fff; opacity: 0.7; font-weight: 700; }
.word p { color: #fff; font-size: 15px; margin: 0 0 10px; max-width: 54ch; }
.word .worddef-om { opacity: 0.76; font-size: 14.5px; margin-bottom: 0; }
/* On black, the guidelines call Black + Blue a pairing to avoid; the panel
   keeps a visible edge rather than melting into the page. */
:root[data-theme='dark'] .word,
:root:not([data-theme='light']) .word { outline: 1px solid rgba(255, 255, 255, 0.16); outline-offset: -1px; }

/* The magazine, on the front of a daily: the cover beside the cover line. */
.hero { display: grid; grid-template-columns: minmax(0, 300px) minmax(0, 1fr); gap: calc(var(--gutter) * 1.5); align-items: start; }
.hero h1 { font-size: clamp(32px, 3.8vw, 50px); letter-spacing: var(--track-display); margin-bottom: 12px; }
.mark { display: inline-block; font-family: var(--mono); font-size: 10.5px; letter-spacing: var(--track-label); text-transform: uppercase; color: var(--red-text); margin-bottom: 14px; }
.lead { font-size: 17px; color: var(--ink-2); max-width: 62ch; }
@media (max-width: 860px) { .hero { grid-template-columns: 1fr; } }

/* Sponsors: where a paid page sits, never what it costs. A company's name
   appears only against a position it has booked; a sample shows a kind of
   advertiser. The one place a box is right, because a sponsor's space should
   look like a space that was bought. */
.spgrid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 16px; margin: 4px 0 18px; }
.spcard { border: 1px solid var(--line); padding: 18px; display: flex; flex-direction: column; gap: 5px; background: var(--paper-2); }
.spcard.open { border-style: dashed; background: transparent; }
.spsample { display: block; margin: -18px -18px 12px; padding: 6px 12px; background: var(--ink-panel); color: #fff; font-family: var(--mono); font-size: 9px; letter-spacing: 0.12em; text-transform: uppercase; }
.hascreative .adby .spsample { display: inline-block; margin: 0 0 0 8px; padding: 3px 8px; vertical-align: middle; }
.spcard b { font-family: var(--display); font-size: 16px; letter-spacing: var(--track-text); }
.spcard p { font-size: 13.5px; color: var(--muted); margin: 0; }
.sprate { margin-top: auto; padding-top: 12px; font-family: var(--mono); font-size: 11px; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase; color: var(--red-text); text-decoration: none; align-self: flex-start; border-bottom: 1px solid transparent; }
.sprate:hover { border-bottom-color: var(--red); }
.spnote { border-left: 3px solid var(--red); padding-left: 14px; font-size: 13.5px; color: var(--muted); max-width: 72ch; }

/* The advertising spaces. They run inside the briefing and nowhere else, and
   every one obeys three visible rules so a reader can tell it from a story
   with the label covered: the label, in the same words every time; a red rule
   above it where a story carries its category colour; and a different measure
   — the mono face in a narrow column — so it cannot pass for editorial. Never
   more than three in sixteen; `withAdSpaces` in blocks.mjs counts. */
.adspace {
  border-top: var(--rule) solid var(--red); background: var(--paper-2); padding: 14px 16px 16px;
  display: flex; flex-direction: column; gap: 6px; font-family: var(--mono); min-width: 0;
}
.adspace.open { background: transparent; border: 1px dashed var(--line); border-top: var(--rule) solid var(--red); }
.adlabel { display: inline-flex; align-items: center; gap: 7px; font-size: 9.5px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--muted); }
.adlabel::before { content: ''; width: 7px; height: 7px; background: var(--red); transform: rotate(45deg); flex: none; }
/* In the briefing grid a space is as tall as the story cards beside it, so the
   free height is spent deliberately: label at the top, the name and line in the
   middle, the way to ask at the foot — a placard, not a short card floating in
   a tall dashed box. */
.adspace b { font-family: var(--display); font-size: 19px; font-weight: 700; letter-spacing: var(--track-text); line-height: 1.15; margin-top: auto; padding-top: 10px; }
.adspace p { margin: 0; font-size: 12px; line-height: 1.5; color: var(--muted); max-width: 30ch; }
.adgo {
  margin-top: auto; padding-top: 12px; font-size: 10.5px; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--red-text); text-decoration: none; display: inline-flex; align-items: center; gap: 6px; align-self: flex-start;
}
.adgo:hover { text-decoration: underline; }
.storyrail .adspace { min-height: 200px; }

/* Two bands side by side, where each is too short to hold a full width. */
.twoup { display: grid; grid-template-columns: repeat(var(--cols), minmax(0, 1fr)); gap: 0 var(--gutter); }
.twoup > *:first-child { grid-column: span 8; }
.twoup > *:last-child { grid-column: span 4; }
@media (max-width: 1000px) { .twoup > *:first-child, .twoup > *:last-child { grid-column: span 6; } }
@media (max-width: 640px) { .twoup > *:first-child, .twoup > *:last-child { grid-column: span 1; } }

/* ──────────────── 10 · CHARTS, PICTURES, TABLES ────────────────
   "The number is the picture." One series in deep blue, the latest reading in
   red, gridlines behind, an ink baseline, no legend, and the same numbers in a
   table beneath — so a chart is never the only way to read a figure. */

.chart { width: 100%; height: auto; display: block; margin: 4px 0 2px; }
svg.chart text { font-variant-numeric: tabular-nums lining-nums; }
/* The one label on a chart: the latest reading, in red, in the display face.
   A chart carries no legend and no axis labels — the unit is in the heading
   above it and every number is in the table beneath. */
svg.chart .chartlabel { font-family: var(--display); font-size: 13px; font-weight: 700; letter-spacing: -0.02em; }
.chart { max-width: 100%; height: auto; }

.datagrid { display: grid; grid-template-columns: repeat(auto-fit, minmax(330px, 1fr)); gap: var(--air-2) var(--gutter); }
.figblock { border-top: var(--rule) solid var(--ink); padding-top: 14px; }
.figblock .big {
  font-family: var(--display); font-weight: 700; font-size: 38px; line-height: 1;
  letter-spacing: var(--track-display); font-variant-numeric: tabular-nums lining-nums; color: var(--red);
}

/* Three picture ratios and no fourth: 16:9 for stories, 1:1 for covers, 3:4
   for people. Where there is no photograph the story's own figure is set in
   type on the category colour, rather than an empty grey box. */
.pic { position: relative; margin: 0; overflow: hidden; background: var(--paper-2); width: 100%; }
.pic img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* The phone's own, smaller set (blocks.mjs) wraps the img in <picture>; it takes no box of its own. */
.pic picture { display: contents; }
.pic figcaption { position: absolute; right: 6px; bottom: 6px; font-family: var(--mono); font-size: 9.5px; color: #fff; background: rgba(0, 0, 0, 0.6); padding: 2px 7px; }
.pic.typo { display: flex; flex-direction: column; justify-content: space-between; padding: 18px; color: #fff; background: var(--tone); container-type: inline-size; }
.pic.typo .typo-cat { font-family: var(--mono); font-size: 10px; letter-spacing: var(--track-label); text-transform: uppercase; opacity: 0.85; }
.pic.typo .typo-fig { font-family: var(--display); font-weight: 700; font-size: clamp(34px, 5vw, 64px); line-height: 0.95; letter-spacing: var(--track-display); }

table.plain { width: 100%; border-collapse: collapse; font-size: 14px; }
table.plain td, table.plain th { border-bottom: 1px solid var(--line); padding: 8px 10px 8px 0; text-align: left; }
table.plain th { font-family: var(--mono); font-size: 9.5px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--muted); font-weight: 500; background: none; }
table.plain td.num { text-align: right; font-family: var(--mono); font-variant-numeric: tabular-nums lining-nums; }

/* ──────────────────── 11 · FORMS AND CONTROLS ──────────────────── */

.btn {
  display: inline-block; font-family: var(--mono); font-size: 11px; letter-spacing: 0.1em; text-transform: uppercase;
  padding: 13px 22px; border: 1.5px solid var(--ink); text-decoration: none; background: transparent; color: inherit; cursor: pointer;
}
.btn:hover { background: var(--ink); color: var(--paper); }
.btn.red { background: var(--red); border-color: var(--red); color: #fff; }
.btn.red:hover { background: var(--red-2); border-color: var(--red-2); }
.btn.ink { background: var(--ink); border-color: var(--ink); color: var(--paper); }
/* `.btn.blue` is gone. It painted a deep-blue button, which the guideline's
   pairing rules retired, and leaving the class behind painting black would have
   been a name that lies — the worst kind of dead code, because it reads as an
   option. Nothing used it. `.btn.ink` is the black button. */
.btn.sm { padding: 8px 15px; font-size: 10px; }
.btnrow { display: flex; gap: 12px; flex-wrap: wrap; margin-top: 20px; }

.langtoggle { display: flex; border: 1px solid var(--ink); overflow: hidden; }
.langtoggle button {
  font-family: var(--mono); font-size: 10px; letter-spacing: 0.08em; text-transform: uppercase;
  padding: 7px 13px; border: 0; background: transparent; color: inherit; cursor: pointer;
}
.langtoggle button[aria-pressed='true'] { background: var(--ink); color: var(--paper); }

.form { display: grid; gap: 14px; max-width: 560px; }
.form.wide { max-width: none; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }
.field { display: grid; gap: 6px; }
.field label { font-family: var(--mono); font-size: 10px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--muted); }
input, select, textarea {
  font-family: var(--sans); font-size: 15px; padding: 11px 13px;
  /* The boundary of a field has to be seen: --line is 1.4:1 against the
     paper, --muted 5:1 (WCAG 1.4.11 asks for 3:1). */
  border: 1px solid var(--muted); background: var(--paper); color: var(--ink); width: 100%; border-radius: 0;
}
input:focus, select:focus, textarea:focus { outline: 2px solid var(--link); outline-offset: 1px; border-color: var(--ink); }
textarea { min-height: 130px; resize: vertical; }

.note { font-size: 13.5px; color: var(--muted); max-width: 72ch; }
.hint { font-size: 12.5px; }
.err { color: var(--red); font-size: 14px; border-left: 3px solid var(--red); padding-left: 12px; }
.ok { color: var(--teal); font-size: 14px; border-left: 3px solid var(--teal); padding-left: 12px; }
.hp { position: absolute; left: -9999px; }

.chip { font-family: var(--mono); font-size: 10px; letter-spacing: 0.08em; text-transform: uppercase; padding: 6px 12px; border: 1px solid var(--line); text-decoration: none; }
.chip[aria-current='true'] { background: var(--ink); color: var(--paper); border-color: var(--ink); }
.months { display: flex; flex-wrap: wrap; gap: 8px; margin: 10px 0 var(--air-2); }
.searchbar { display: grid; grid-template-columns: 1fr auto auto auto; gap: 10px; margin: 14px 0 20px; }
.searchrow { display: flex; align-items: flex-end; gap: 10px; flex-wrap: wrap; margin: 18px 0 8px; }
.searchrow label { display: block; width: 100%; margin-bottom: 4px; }
.searchrow input { flex: 1 1 240px; min-width: 200px; }
.pager { display: flex; justify-content: space-between; gap: 12px; margin: var(--air-2) 0; }
@media (max-width: 760px) { .searchbar { grid-template-columns: 1fr 1fr; } }

/* ──────────────────────────── 12 · UTILITIES ──────────────────────────── */

.cols2 { display: grid; grid-template-columns: 1fr 1fr; gap: 32px; }
@media (max-width: 860px) { .cols2 { grid-template-columns: 1fr; } }

.steps { counter-reset: s; display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 22px; }
.steps > div { border-top: var(--rule) solid var(--ink); padding-top: 12px; }
.steps > div::before { counter-increment: s; content: '0' counter(s); font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.1em; color: var(--red-text); display: block; margin-bottom: 6px; }

.plans { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 16px; }
.plan { border: 1px solid var(--line); padding: 18px; }
.plan .price { font-family: var(--display); font-size: 25px; font-weight: 700; letter-spacing: var(--track-section); font-variant-numeric: tabular-nums lining-nums; }

.receipt { border: 2px solid var(--teal); padding: 18px; }
.receipt code { font-family: var(--mono); font-size: 12px; word-break: break-all; }

.savedata { font-size: 13.5px; background: var(--paper-2); padding: 10px 14px; margin: 10px 0 0; border-left: 3px solid var(--link); }

/* Sharing an item: two named services and a copy button, no third-party script. */
.share { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin: 22px 0; }

.prose a, .note a, p a:not(.btn):not(.chip) { color: var(--link); }
.scroll { overflow-x: auto; }
.mt { margin-top: 12px; }
.mt2 { margin-top: 24px; }

/* ──────────────────── 13 · THE MAGAZINE, BY ISSUE ────────────────────
   An issue is the unit the magazine is actually made in, so it is the unit the
   site browses in: a cover line, a page plan you can see rather than read, the
   month's reporting beneath it, and the issue before and after at the foot. */

.issuehead { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: var(--air-2) var(--gutter); align-items: start; }
.issuehead h1 { font-size: clamp(30px, 3.6vw, 46px); letter-spacing: var(--track-display); margin-bottom: 8px; }
@media (max-width: 900px) { .issuehead { grid-template-columns: 1fr; } }

/* The page plan as a bar: one segment per page. Thirty-two segments, and a
   reader can count the commercial ones without reading a table. Publishing the
   plan is the promise; drawing it is what makes the promise checkable. */
.planwrap { border-top: var(--rule) solid var(--ink); padding-top: 14px; }
.planbar { display: flex; gap: 2px; align-items: flex-end; }
.planseg { flex: 1 1 0; height: 150px; min-width: 4px; padding: 0; border: 0; background: var(--paper-3); border-radius: 1px; cursor: pointer; transition: transform 0.12s ease; }
.planbar .planseg:focus-visible { outline: 2px solid var(--link); outline-offset: 2px; z-index: 1; }
@media (prefers-reduced-motion: reduce) { .planseg { transition: none; } }
.planseg.editorial { background: var(--ink); }
.planseg.commercial { background: var(--red); }
.planseg.front { background: var(--ink); }
.planseg.unplanned { background: var(--line); }
.planbar .planseg:hover { transform: scaleY(1.18); }
.plankey { display: flex; flex-wrap: wrap; gap: 6px 18px; margin: 12px 0 0; font-family: var(--mono); font-size: 10px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted); }
.plankey i.planseg { display: inline-block; width: 10px; height: 10px !important; flex: 0 0 auto; vertical-align: -1px; }
.plankey .note { text-transform: none; letter-spacing: 0; font-family: var(--sans); font-size: 12.5px; flex-basis: 100%; }

/* The plan as a list. A commercial row is marked, not hidden: the reader who
   scrolls the plan should meet the paid pages in the same list as the rest.
   The mark is a red rule down the edge of the row rather than a wash behind it
   — the manual's rule is that colour rides the rule and never touches the
   words, and the wash measured 4.36:1 under the words it was tinting. */
.planlist tr.commercialrow td:first-child { box-shadow: inset var(--flag) 0 0 0 var(--red); padding-left: 14px; }
.tag { display: inline-block; font-family: var(--mono); font-size: 9px; letter-spacing: 0.12em; text-transform: uppercase; padding: 3px 8px; border: 1px solid currentColor; }
.tag.commercial { color: var(--red-text); }

/* Between issues, at the foot of one. */
.issuenav { display: flex; justify-content: space-between; gap: 16px; margin: var(--band) 0 var(--air-2); border-top: 1px solid var(--line); padding-top: 18px; }
.issuenav a { text-decoration: none; display: grid; gap: 3px; }
.issuenav a.next { text-align: right; }
.issuenav a .caps { color: var(--muted); }
.issuenav a b { font-family: var(--display); font-size: 19px; letter-spacing: var(--track-text); }
.issuenav a:hover b { color: var(--red-text); }

/* Every issue, by year. A year is a heading and its issues are the row under
   it, so a reader hunting "that piece from March" has a shape to look in. */
.yearband { margin-top: var(--air-2); }
.yearhead {
  font-family: var(--display); font-size: clamp(38px, 5vw, 66px); font-weight: 700; line-height: 1;
  letter-spacing: var(--track-display); font-variant-numeric: tabular-nums lining-nums;
  /* A year is the label of the group, not a watermark: it was set in the
     panel tone, which on black measured 1.2:1 and simply vanished. Muted ink
     keeps it quiet in both themes and readable in both. */
  color: var(--muted); margin: 0 0 6px;
}
.issuegrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: var(--gutter); border-top: var(--rule) solid var(--ink); padding-top: 18px; }
.issuecard {
  display: grid; gap: 5px; align-content: start; text-decoration: none;
  border-left: var(--flag) solid var(--red); padding: 2px 0 14px 16px;
  transition: border-color 0.12s ease, transform 0.12s ease;
}
.issuecard:hover { transform: translateX(3px); border-left-color: var(--ink); }
.issuecard.empty { border-left-color: var(--line); }
.issueno {
  font-family: var(--display); font-weight: 700; font-size: 34px; line-height: 1;
  letter-spacing: var(--track-display); font-variant-numeric: tabular-nums lining-nums;
}
.issuecard b { font-family: var(--display); font-size: 17px; font-weight: 700; letter-spacing: var(--track-text); line-height: 1.22; margin-top: 4px; }
.issuecard .issuemeta { font-family: var(--mono); font-size: 10px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted); }

/* ──────────────── 14 · ICONS AND THE CONTROLS THAT USE THEM ────────────────
   Two kinds of mark, and they follow different rules. The house set is drawn in
   `currentColor` at one stroke weight, so an icon is simply the colour of the
   text it sits beside. Another company's logo keeps its own artwork and its own
   colour: a logo belongs to whoever owns it, and a reader scanning for the
   green speech bubble should find the green speech bubble. */

.icon { display: inline-block; vertical-align: -0.18em; flex: 0 0 auto; }
.btn, .chip, .seclink { display: inline-flex; align-items: center; gap: 7px; }
.btn .icon, .chip .icon { vertical-align: 0; }

/* A control that is only an icon. It always carries an aria-label. */
.iconbtn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 34px; height: 34px; padding: 0; border: 1px solid var(--line);
  background: transparent; color: inherit; cursor: pointer; text-decoration: none;
}
.iconbtn:hover { border-color: var(--ink); background: var(--paper-2); }
.iconbtn:focus-visible { outline: 2px solid var(--link); outline-offset: 2px; }

/* The theme button shows the mode you are not in, so it pictures what pressing
   it does. Default and explicit light show the moon; dark shows the sun. */
.themebtn .ifdark { display: none; }
.themebtn .iflight { display: inline-flex; }
:root[data-theme='dark'] .themebtn .ifdark { display: inline-flex; }
:root[data-theme='dark'] .themebtn .iflight { display: none; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) .themebtn .ifdark { display: inline-flex; }
  :root:not([data-theme='light']) .themebtn .iflight { display: none; }
}

/* A named third-party service: its own mark, its own colour, its own word.
   Brand values, used unmodified. On black they are lightened only as far as
   each brand's own dark-mode guidance allows, because an unreadable logo helps
   nobody — the hue is never changed. */
.svc { display: inline-flex; align-items: center; gap: 7px; text-decoration: none; }
.svc.whatsapp .icon { color: #25d366; }
.svc.telegram .icon { color: #229ed9; }
.svc.youtube .icon { color: #ff0000; }
.svc.rss .icon { color: #f26522; }
.legallinks { display: flex; flex-wrap: wrap; gap: 6px 18px; align-items: center; }
.legallinks a { text-decoration: none; }
.legallinks a:hover { text-decoration: underline; }

/* The copy button carries both states and a flag decides which shows, so the
   icon changes with the word and no script has to rebuild the label. */
[data-share-copy] .ifidle,
[data-share-copy] .ifdone { align-items: center; gap: 7px; }
[data-share-copy] .ifidle { display: inline-flex; }
[data-share-copy] .ifdone { display: none; }
[data-share-copy][data-state='done'] .ifidle { display: none; }
[data-share-copy][data-state='done'] .ifdone { display: inline-flex; }
[data-share-copy][data-state='done'] { border-color: var(--teal); color: var(--teal); }

/* Which printed issue a daily item belongs to. */
.inissue {
  display: inline-flex; align-items: center; gap: 12px; text-decoration: none;
  border: 1px solid var(--line); border-left: var(--flag) solid var(--ink);
  padding: 12px 16px; margin: 18px 0 4px;
}
.inissue:hover { border-color: var(--ink); border-left-color: var(--red); }
.inissue .caps { display: block; color: var(--muted); }
.inissue b { font-family: var(--display); font-size: 16px; letter-spacing: var(--track-text); }

/* ──────────────── 15 · MOTION, KEPT TO WHAT EARNS ITS PLACE ────────────────
   The manual allows two motions: the flag wiping in, and a figure counting up.
   These two are navigation rather than decoration — how far through a long
   piece you are, and the way back to the top — and both disappear entirely
   under reduced motion or with scripts off. */

/* The progress hairline is the flag doing a second job, not new furniture. */
.progress {
  position: fixed; top: 0; left: 0; height: var(--flag); width: 100%;
  background: var(--red); transform: scaleX(0); transform-origin: left center;
  z-index: 70; pointer-events: none;
}
@media (prefers-reduced-motion: reduce) { .progress { display: none; } }

.totop {
  position: fixed; right: 20px; bottom: 20px; z-index: 50;
  width: 42px; height: 42px; display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--ink); background: var(--paper); color: var(--ink); cursor: pointer;
  box-shadow: 0 6px 20px -12px rgba(0, 0, 0, 0.6);
}
.totop:hover { background: var(--ink); color: var(--paper); }
.totop[hidden] { display: none; }
@media print { .totop, .progress { display: none; } }

/* ──────────────── 16 · THE PARTNERS ────────────────
   A sponsor position is a page for sale; a partner is a company that has
   actually signed something. Only the second gets a name, a mark and a band of
   its own — and it gets a good one, because a company that backs a bilingual
   business publication in Ethiopia is doing something the readers should see.
   Their marks sit on a light ground at a common optical size, never stretched,
   never tinted, never turned grey: it is their artwork. */

.roll { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: var(--gutter); border-top: var(--rule) solid var(--ink); padding-top: 22px; }
.roll.compact { grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 14px; }
.rollcard {
  display: grid; gap: 6px; align-content: start; text-decoration: none;
  background: var(--paper-2); border: 1px solid var(--line); padding: 20px;
}
.rollcard:hover { border-color: var(--ink); }
.roll.compact .rollcard { padding: 16px; justify-items: center; text-align: center; }
/* A fixed box so marks of different proportions read at one weight together. */
.rollmark { display: flex; align-items: center; min-height: 46px; }
.rollmark img { max-height: 46px; max-width: 100%; width: auto; object-fit: contain; }
/* No logo file: the name in the display face beats a broken image every time. */
.rollname { font-family: var(--display); font-weight: 700; font-size: 21px; letter-spacing: var(--track-text); }
.rolltier {
  display: inline-flex; align-items: center; gap: 6px; align-self: start;
  font-family: var(--mono); font-size: 9px; letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--red-text); border: 1px solid currentColor; padding: 3px 8px;
}
.rollcard b { font-family: var(--sans); font-weight: 600; font-size: 14.5px; line-height: 1.35; }
.rollsince { font-family: var(--mono); font-size: 10px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted); }
.rollempty { border-top: var(--rule) solid var(--ink); padding-top: 20px; }

/* What a partnership actually attaches to: four surfaces, each named in both
   editions, so a company can see what it is buying before it asks the price. */
.surfaces { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: var(--gutter); }
.surface { border-top: var(--rule) solid var(--ink); padding-top: 14px; display: grid; gap: 4px; align-content: start; }
.surfaceicon { color: var(--red-text); }
.surface b { font-family: var(--display); font-size: 18px; font-weight: 700; letter-spacing: var(--track-text); }
.surface .om { font-size: 14px; }
.surface p { font-size: 13.5px; color: var(--muted); margin: 6px 0 0; }

/* ──────────────────────────── 17 · THE VIDEO ────────────────────────────
   Every video plays on YouTube, and the page says so before it is clicked.
   Two things are deliberately absent:

     · **No YouTube thumbnail.** That would be a request to i.ytimg.com on a
       page that promises no third-party request, the policy refuses it, and the
       reader on a prepaid bundle pays for it. The poster is set in type on the
       category colour instead — the same answer the site gives a story with no
       photograph, and the same rule: the number is the picture.
     · **No embedded player.** An iframe would put their scripts and cookies
       inside an Ensight page. The card is a link. */

.vposter {
  position: relative; display: flex; flex-direction: column; justify-content: space-between;
  /* 16:9, the shape of every YouTube thumbnail and player (1280×720): the
     poster is a promise of the frame the film plays in. */
  aspect-ratio: 16 / 9; width: 100%; padding: 14px; overflow: hidden;
  background: var(--tone, var(--ink-panel)); color: #fff;
}
/* 0.92, not 0.82: a 9.5px label is small text, and at 0.82 white over the
   lightest poster ground (agriculture green) measured 4.0:1. 0.92 clears
   4.5:1 on every fill in CATEGORY_FILL and still reads as a tint. */
.vposter .vseries { font-family: var(--mono); font-size: 9.5px; letter-spacing: var(--track-label); text-transform: uppercase; opacity: 0.92; }
/* The figure is the picture. It sits low-left the way a cover line does, and is
   allowed to run to the edge of the frame rather than being centred in it. */
.vposter .vfig {
  font-family: var(--display); font-weight: 700; font-size: clamp(38px, 6vw, 62px); line-height: 0.92;
  letter-spacing: var(--track-display); font-variant-numeric: tabular-nums lining-nums; margin-top: auto;
}
.vposter .vlabel { font-family: var(--mono); font-size: 10px; letter-spacing: 0.08em; text-transform: uppercase; opacity: 0.85; margin-top: 4px; }
.vposter.big .vfig { font-size: clamp(56px, 8vw, 104px); }
.vposter.big .vlabel { font-size: 11px; }

/* The play badge: a filled disc in Ensight Red over the poster's lower right.
   Red is the accent and this is the one thing on the card you are meant to do. */
.vposter .vplay {
  /* Centred, as a player draws it, so the corner is free for the length. */
  position: absolute; left: 50%; top: 50%; translate: -50% -50%;
  display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; border-radius: 50%;
  background: var(--red); color: #fff;
  transition: transform 0.14s ease, background-color 0.14s ease;
}
.vposter.big .vplay { width: 64px; height: 64px; }
/* The length, where YouTube puts it: bottom right, white on near-black, small
   rounded corners, tabular figures so 9:58 and 10:02 are the same width. */
.vposter .vdur {
  position: absolute; right: 8px; bottom: 8px;
  font-family: var(--sans); font-weight: 600; font-size: 12px; line-height: 1; letter-spacing: 0.01em;
  font-variant-numeric: tabular-nums; color: #fff;
  background: rgba(0, 0, 0, 0.8); padding: 3px 5px; border-radius: 4px;
}
.vposter.big .vdur { font-size: 13px; right: 10px; bottom: 10px; }
.vlink:hover .vplay, .vheroposter:hover .vplay { transform: scale(1.09); background: var(--red-2); }
@media (prefers-reduced-motion: reduce) { .vposter .vplay { transition: none; } }

/* The video at the top of the page. */
.vhero { display: grid; grid-template-columns: minmax(0, 1.45fr) minmax(0, 1fr); gap: var(--air-2) var(--gutter); align-items: start; }
.vhero h1 { font-size: clamp(26px, 3vw, 38px); letter-spacing: var(--track-display); margin: 0 0 6px; }
.vheroposter { display: block; text-decoration: none; }
.vheroside .lead { margin-top: 12px; }
@media (max-width: 900px) { .vhero { grid-template-columns: 1fr; } }

.vgrid { display: grid; grid-template-columns: 1fr; gap: var(--air-2) var(--gutter); }
@media (min-width: 560px) { .vgrid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 820px) { .vgrid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (min-width: 1240px) { .vgrid { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
.vcard { display: flex; flex-direction: column; gap: 10px; min-width: 0; }
.vlink { display: block; text-decoration: none; color: inherit; }
.vbody { display: block; margin-top: 12px; }
.vmeta { display: block; color: var(--muted); }
.vtitle { display: block; font-family: var(--display); font-weight: 700; font-size: 18px; line-height: 1.2; letter-spacing: var(--track-text); margin-top: 6px; }
/* Two lines of title and three of summary, as a video grid shows them. */
.vtitle, .filmcard .wtitle { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; overflow: hidden; }
.vsum { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; line-clamp: 3; overflow: hidden; }
.vcard .hom { display: block; color: var(--red-text); font-family: var(--display); font-weight: 700; font-size: 14.5px; letter-spacing: var(--track-text); margin-top: 2px; }
.vsum { font-size: 13.5px; color: var(--muted); margin-top: 8px; }
.vlink:hover .vtitle { color: var(--red-text); }
/* A video that is not out yet keeps its poster but loses the play badge: there
   is nothing to play, and a button that does nothing is worse than none. */
.vcard.soon .vplay { display: none; }
.vcard.soon .vposter { opacity: 0.82; }

.vactions { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 14px; margin-top: auto; padding-top: 4px; }
/* Rendered as a span inside the card's own anchor: a link inside a link is
   invalid HTML, and the whole card already goes to YouTube. */
.vactions .vwatch { pointer-events: none; }
.vsoon { display: inline-flex; align-items: center; gap: 7px; font-family: var(--mono); font-size: 10px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--ink); }
.vtrailer {
  display: inline-flex; align-items: center; gap: 7px; text-decoration: none;
  font-family: var(--mono); font-size: 10px; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--red-text); border-bottom: 1px solid transparent; padding-bottom: 2px;
}
.vtrailer:hover { border-bottom-color: currentColor; }

.vfoot { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 16px; border-top: 1px solid var(--line); padding-top: 18px; }
.vfoot .note { margin: 0; flex: 1 1 380px; }

.serieshead { display: flex; align-items: flex-start; gap: 12px; color: var(--muted); font-size: 14px; max-width: 74ch; margin: 0 0 var(--air); }
.seriesmark { color: var(--blue); flex: 0 0 auto; line-height: 1; }
.epmeta { display: flex; flex-wrap: wrap; gap: 4px 16px; margin-top: 12px; font-family: var(--mono); font-size: 10px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted); }
.epmeta span { display: inline-flex; align-items: center; gap: 6px; }

/* ──────────────────────────── 18 · SERVICES ────────────────────────────
   Seven categories and thirty-five offers: the longest piece of copy on the
   site, and the one page where the range itself is the argument. It opens with
   a menu rather than making a reader scroll to find out what is here. */

.svcmenu { display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); gap: 2px; margin-top: var(--air-2); border-top: var(--rule) solid var(--ink); padding-top: 16px; }
.svcmenu a {
  display: grid; grid-template-columns: auto 1fr auto; align-items: baseline; gap: 10px;
  text-decoration: none; padding: 11px 12px 11px 0; border-bottom: 1px solid var(--line);
}
.svcmenu a:hover { background: var(--paper-2); }
.svcmenu a .caps { color: var(--ink); }
.svcmenu a b { font-family: var(--display); font-size: 15px; font-weight: 700; letter-spacing: var(--track-text); line-height: 1.2; }
.svcmenu a:hover b { color: var(--red-text); }
.svccount { font-family: var(--mono); font-size: 10px; color: var(--muted); font-variant-numeric: tabular-nums; }

/* A category. The number is set in the display face beside the name, the way
   the magazine numbers its sections, and the hook sits on the same rule. */
.svcband { scroll-margin-top: 120px; }
.svcband .sechead h2 { display: flex; align-items: baseline; gap: 12px; }
.svcno { color: var(--ink); font-variant-numeric: tabular-nums lining-nums; }
.svcgrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: var(--air) var(--gutter); }
.svcitem { border-top: 1px solid var(--line); padding-top: 12px; }
.svcitem h3 { font-size: 17px; letter-spacing: var(--track-text); margin: 0 0 6px; }
.svcitem p { font-size: 13.5px; color: var(--muted); margin: 0; max-width: 46ch; }

/* ──────────────────────────── 19 · ABOUT ────────────────────────────
   The page where a publication is either believable or it is not. It is built
   as an argument: one sentence at display size that has to land, the evidence
   beside it, then the principles, the people and the disclosures that let a
   reader check the claim rather than take it. */

.aboutlede { display: grid; grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr); gap: var(--air-2) calc(var(--gutter) * 2); align-items: start; }
.aboutlede h1 { font-size: clamp(28px, 3.2vw, 42px); letter-spacing: var(--track-display); margin: 0 0 14px; }
/* The statement of the gap. Display face, tight, and measured short so it reads
   as a claim rather than as a paragraph. */
.abigsay {
  font-family: var(--display); font-weight: 700; font-size: clamp(19px, 1.9vw, 24px); line-height: 1.32;
  letter-spacing: var(--track-text); max-width: 34ch; margin: 0;
  border-left: var(--flag) solid var(--red); padding-left: 18px;
}
.aboutlede p { font-size: 15.5px; }
@media (max-width: 900px) { .aboutlede { grid-template-columns: 1fr; } }

/* The five principles, numbered. An ordered list because they are in an order:
   the first is the one the rest depend on. */
.principles { list-style: none; margin: 0; padding: 0; display: grid; gap: 0; }
.principles li {
  display: grid; grid-template-columns: 66px minmax(0, 1fr); gap: 0 var(--gutter);
  padding: 18px 0; border-bottom: 1px solid var(--line); align-items: start;
}
.principles li:first-child { border-top: 1px solid var(--line); }
.pno {
  font-family: var(--display); font-weight: 700; font-size: 30px; line-height: 1;
  letter-spacing: var(--track-display); font-variant-numeric: tabular-nums lining-nums; color: var(--blue);
}
.principles h3 { font-size: 18px; letter-spacing: var(--track-text); margin: 0 0 6px; }
.principles p { font-size: 14.5px; color: var(--ink-2); margin: 0; max-width: 72ch; }

/* The desk. Initials set in type, never a stock photograph of somebody who does
   not work here; an unfilled seat is drawn as an unfilled seat. */
.deskgrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: var(--air) var(--gutter); margin-top: var(--air); }
.seat { border-top: var(--rule) solid var(--ink); padding-top: 14px; }
.seat h3 { font-size: 17px; letter-spacing: var(--track-text); margin: 10px 0 2px; }
.seat .hom { display: block; color: var(--red-text); font-family: var(--display); font-weight: 700; font-size: 14px; letter-spacing: var(--track-text); }
.seat p { font-size: 13.5px; color: var(--muted); margin: 10px 0 0; }
.seatmark {
  display: inline-flex; align-items: center; justify-content: center;
  width: 46px; height: 46px; border-radius: 50%;
  background: var(--ink-panel); color: #fff;
  font-family: var(--display); font-weight: 700; font-size: 16px; letter-spacing: 0.02em;
}
/* An open seat: dashed, quiet, and obviously not a person. */
.seat.open { border-top-color: var(--line); }
.seat.open .seatmark { background: transparent; color: var(--muted); border: 1px dashed var(--line); }
.seat.open h3 { color: var(--muted); }

/* The standards table and the disclosures that the fifth one promises. */
table.standards td { padding-top: 12px; padding-bottom: 12px; }
table.standards td.caps { color: var(--ink); }
.svcitem.discl { border-top-color: var(--ink); }

/* ──────────────── 20 · THE COMMERCIAL SECTION ────────────────
   On the companies page, since the advertising itself runs in the briefing.
   It sells three different things — a signed partnership, a bought position,
   and labelled content — and the old design showed them as one undifferentiated
   list, which is why nobody could tell what they were buying. Three cards, in
   the three brand colours, and then a band each. */

.commlede { display: grid; grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr); gap: var(--air-2) calc(var(--gutter) * 2); align-items: start; }
.commlede h1, .commlede h2 { font-size: clamp(28px, 3.2vw, 42px); letter-spacing: var(--track-display); margin: 0 0 14px; max-width: 18ch; }
@media (max-width: 900px) { .commlede { grid-template-columns: 1fr; } }

/* What a buyer can check before they call. Structural facts, never an audience
   figure nobody has audited — this publication does not publish those. */
.commfacts { list-style: none; margin: 0; padding: 0; border-top: var(--rule) solid var(--ink); }
.commfacts li { display: grid; grid-template-columns: auto 1fr; gap: 12px; align-items: start; padding: 12px 0; border-bottom: 1px solid var(--line); font-size: 14px; }
.commfacts .icon { color: var(--ink); margin-top: 2px; }

.kinds { display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: var(--gutter); }
.kind {
  display: grid; align-content: start; gap: 8px; text-decoration: none;
  border-top: var(--rule) solid var(--ink); padding: 16px 0 0;
  transition: border-top-color 0.12s ease;
}
.kind:nth-child(2) { border-top-color: var(--ink); }
.kind:nth-child(3) { border-top-color: var(--red); }
.kind:hover { border-top-color: var(--red); }
.kindmark { color: var(--ink); }
.kind b { font-family: var(--display); font-size: 21px; font-weight: 700; letter-spacing: var(--track-text); }
.kind:hover b { color: var(--red-text); }
.kindnote { font-size: 13.5px; color: var(--muted); max-width: 34ch; }
.kindlist { display: flex; flex-direction: column; gap: 3px; margin-top: 6px; font-family: var(--mono); font-size: 10px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-2); }

/* The founding places, inside the partnership band: the one offer that is a
   relationship rather than a purchase, so it gets the panel. */
.foundingbox { border-left: var(--flag) solid var(--red); background: var(--paper-2); padding: 18px 20px; margin-top: var(--air); display: grid; gap: 8px; justify-items: start; }
.foundingbox .caps { color: var(--muted); }
.foundingbox p { font-size: 14.5px; margin: 0; max-width: 68ch; }

/* What the money does not buy. The rules are the product: a labelled page in a
   publication a reader trusts is worth more than an unlabelled one in a
   publication they do not. */
.rules { list-style: none; margin: 0; padding: 0; }
.rules li { display: grid; grid-template-columns: 66px minmax(0, 1fr); gap: 0 var(--gutter); padding: 16px 0; border-bottom: 1px solid var(--line); align-items: start; }
.rules li:first-child { border-top: 1px solid var(--line); }
.rules p { margin: 0; font-size: 15.5px; max-width: 72ch; }

/* ──────────────── 21 · THE PAGE AS PICTURE ────────────────
   "The number is the picture." Taken literally: every story makes its own
   poster out of the one thing it is certain of, set in type on its category's
   ground. There is no photo desk and there will be no stock photography of a
   bank branch in another country.

   It is also why the site can be three-quarters picture and still weigh almost
   nothing. A poster is a coloured box, two words and a number in a face the
   page has already loaded — no image request, no bytes on a prepaid bundle, no
   layout shift while something downloads, and sharp on any screen. */

.pic.typo {
  aspect-ratio: 1 / 1; gap: 6px; padding: 14px;
  background: var(--tone, var(--ink));
}
.pic.typo .typo-cat { position: static; background: none; padding: 0; color: #fff; opacity: 0.92; }
.pic.typo .typo-cat .om { color: #fff; font-family: var(--mono); font-weight: 500; }
/* The figure fills the frame. It is allowed to be enormous: it is the picture,
   and a picture that has to be squinted at is a caption.

   `break-word`, never `anywhere`: `anywhere` counts toward min-content width,
   so the browser *prefers* breaking and splits US$8.2bn into "US$8.2b / n" —
   a number broken in half, which is the one thing a figure must never be. The
   safety net against a genuinely unfittable token is kept either way. */
.pic.typo .typo-fig {
  margin-top: auto; font-size: clamp(24px, 17cqw, 52px); line-height: 0.92;
  font-variant-numeric: tabular-nums lining-nums; overflow-wrap: break-word;
}
/* The source line is the smallest type on the poster; 0.92 for the same reason as .vseries. */
.pic.typo .typo-src { font-family: var(--mono); font-size: 9.5px; letter-spacing: 0.08em; text-transform: uppercase; color: #fff; opacity: 0.92; }
/* The lead's picture is the biggest thing on the front page, and taller than
   the rest, so the eye lands on it before any headline. */
.pic.typo.lead { aspect-ratio: 16 / 10; padding: 20px; }
.pic.typo.lead .typo-fig { font-size: clamp(40px, 19cqw, 116px); }
.pic.typo.lead .typo-cat { font-size: 11px; }
@media (max-width: 700px) { .pic.typo.lead { aspect-ratio: 16 / 9; } }

/* Every card leads with its picture, so the grid reads as a wall of figures
   before it reads as a list of headlines. */
.lead-story .pic, .second .pic, .third .pic { margin-bottom: 14px; }

/* The magazine's cover, drawn the way the printed one is made: the flag across
   the head, the issue number at cover size, the cover line beneath. */
.cover {
  position: relative; display: grid; grid-template-rows: auto 1fr auto; gap: 10px;
  aspect-ratio: 3 / 4; padding: 26px 22px 22px;
  background: var(--red); color: #fff; text-decoration: none;
  transition: transform 0.14s ease;
}
.cover:hover { transform: translateY(-3px); }
@media (prefers-reduced-motion: reduce) { .cover { transition: none; } }
.coverflag { position: absolute; inset: 0 0 auto 0; height: var(--flag); background: var(--ink); }
.covertop { display: flex; justify-content: space-between; gap: 10px; }
.covertop .caps, .coverfoot .caps { color: #fff; opacity: 0.85; }
.coverno {
  font-family: var(--display); font-weight: 700; font-size: clamp(64px, 9vw, 128px); line-height: 0.86;
  letter-spacing: var(--track-display); font-variant-numeric: tabular-nums lining-nums; margin-top: 6px;
}
.coverline { font-family: var(--display); font-weight: 700; font-size: clamp(17px, 1.7vw, 22px); line-height: 1.2; letter-spacing: var(--track-text); }
.covermid { display: grid; align-content: start; gap: 8px; min-height: 0; }
.coverfoot { display: flex; justify-content: space-between; gap: 10px; align-self: end; border-top: 1px solid rgba(255, 255, 255, 0.35); padding-top: 10px; }

/* The shape of an indicator, under its figure. Two readings make a straight
   line and say nothing, so a series that short draws none at all. */
.spark { display: block; width: 100%; height: 26px; color: var(--blue); margin: 2px 0 8px; }
.numbers .cell:hover .spark { color: var(--red); }

/* The issue page: its cover above its plan. */
.issueside { display: grid; gap: var(--air); }

/* The page plan, written out. The bar is the picture; this is the same plan in
   words, folded so it does not print the picture twice at full length, and
   still in the document for any reader who cannot see the bar. */
.planfold > summary {
  cursor: pointer; list-style: none; display: inline-flex; align-items: center; gap: 10px;
  font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--ink); border-bottom: 1px solid currentColor; padding-bottom: 3px; margin-bottom: var(--air);
}
.planfold > summary::-webkit-details-marker { display: none; }
.planfold > summary::after { content: "+"; font-size: 13px; }
.planfold[open] > summary::after { content: "\2013"; }
.planfold > summary:focus-visible { outline: 2px solid var(--link); outline-offset: 3px; }

/* ──────────────── 22 · WHAT A PARTNER GETS, AND THE KIT ────────────────
   The benefits come before the ask and both are short: a company that wants
   the detail asks for the kit, and one that does not is not helped by more. */

.gets { display: grid; grid-template-columns: 1fr; gap: var(--air) var(--gutter); }
@media (min-width: 720px) { .gets { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1100px) { .gets { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
.get { border-top: var(--rule) solid var(--ink); padding-top: 14px; display: grid; gap: 6px; align-content: start; }
.getmark { color: var(--ink); line-height: 1; }
.get b { font-family: var(--display); font-size: 17px; font-weight: 700; letter-spacing: var(--track-text); line-height: 1.2; }
.get p { font-size: 13.5px; color: var(--muted); margin: 0; max-width: 42ch; }

/* The ask. Deep blue, because it is the one panel on a commercial page that is
   the publication speaking rather than the rate card. */
.kitbox {
  background: var(--ink-panel); color: #fff;
  display: grid; grid-template-columns: 1fr; gap: var(--air) calc(var(--gutter) * 1.5);
  padding: 30px 28px;
}
@media (min-width: 900px) { .kitbox { grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr); align-items: start; } }
.kitbox .caps { color: rgba(255, 255, 255, 0.78); }
.kitbox h2 { color: #fff; font-size: clamp(22px, 2.4vw, 30px); letter-spacing: var(--track-section); margin: 6px 0 10px; }
.kitbox p { color: rgba(255, 255, 255, 0.86); font-size: 14.5px; margin: 0; max-width: 46ch; }
.kitbox .ok { color: #fff; border-left-color: #fff; align-self: center; }
.kitform { max-width: none; display: grid; gap: 12px; }
@media (min-width: 560px) { .kitform { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.kitform .field label { color: rgba(255, 255, 255, 0.78); }
.kitform input { background: rgba(255, 255, 255, 0.08); border-color: rgba(255, 255, 255, 0.4); color: #fff; }
.kitform input:focus { outline-color: #fff; border-color: #fff; }
.kitform .kitgo { align-self: end; }
@media (min-width: 560px) { .kitform .kitgo { grid-column: 1 / -1; } }
.kitform .btn.red { border-color: #fff; }

/* ──────────────── 23 · THE FRONT PAGE AS AN INTRODUCTION ────────────────
   The front page is not the briefing. It says what Ensight is, then takes each
   thing it makes in turn and shows one of each at full size with the door to
   the rest beside it. Long to scroll, and nothing on it small. */

/* The statement of the gap, at the top of the site. */
.intro {
  display: grid; grid-template-columns: 1fr; gap: var(--air) calc(var(--gutter) * 2);
  border-top: var(--rule) solid var(--ink); padding-top: var(--air);
  margin: 0 0 var(--band);
}
@media (min-width: 950px) { .intro { grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr); align-items: start; } }
.intro h1 {
  font-size: clamp(27px, 3.6vw, 48px); line-height: 1.12; letter-spacing: var(--track-display);
  margin: 0; max-width: 20ch;
}
.introside .lead { margin-bottom: 0; }

/* Each band ends in its own door. */
.bandgo { margin: var(--air) 0 0; }
.bandnote { font-size: 13.5px; color: var(--muted); max-width: 72ch; margin: var(--air) 0 0; }
.bigline { font-size: clamp(22px, 2.6vw, 34px); letter-spacing: var(--track-section); margin: 8px 0 6px; }

/* The video band: one film, its poster at hero size. */
.filmrow { display: grid; grid-template-columns: 1fr; gap: var(--air) calc(var(--gutter) * 1.5); align-items: start; }
@media (min-width: 900px) { .filmrow { grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr); } }
.filmposter { display: block; text-decoration: none; }
.filmrow .hom { display: block; color: var(--red-text); font-family: var(--display); font-weight: 700; font-size: 17px; letter-spacing: var(--track-text); margin-bottom: 10px; }

/* The seven doors into what Ensight does. */
.doors { display: grid; grid-template-columns: 1fr; gap: 2px; border-top: var(--rule) solid var(--ink); }
@media (min-width: 620px) { .doors { grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: var(--gutter); } }
@media (min-width: 1000px) { .doors { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.door {
  display: grid; align-content: start; gap: 4px; text-decoration: none;
  padding: 16px 14px 16px 0; border-bottom: 1px solid var(--line);
}
.door:hover { background: var(--paper-2); }
.door .caps { color: var(--ink); }
.door b { font-family: var(--display); font-size: 18px; font-weight: 700; letter-spacing: var(--track-text); line-height: 1.2; }
.door:hover b { color: var(--red-text); }
.doorhook { font-size: 13px; color: var(--muted); }

/* Three of the five principles, with the door to all of them. */
.stands { display: grid; grid-template-columns: 1fr; gap: var(--air) var(--gutter); }
@media (min-width: 820px) { .stands { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.stand { border-top: var(--rule) solid var(--ink); padding-top: 14px; display: grid; gap: 6px; align-content: start; }
.standno { font-family: var(--display); font-weight: 700; font-size: 26px; line-height: 1; letter-spacing: var(--track-display); color: var(--ink); font-variant-numeric: tabular-nums; }
.stand b { font-family: var(--display); font-size: 17px; font-weight: 700; letter-spacing: var(--track-text); line-height: 1.2; }
.stand p { font-size: 13.5px; color: var(--muted); margin: 0; max-width: 46ch; }

/* The last thing on a long page is the one thing to do about it. */
.joinbox {
  background: var(--ink-panel); color: var(--on-panel);
  display: grid; grid-template-columns: 1fr; gap: var(--air) var(--gutter);
  padding: 30px 28px; align-items: center;
}
@media (min-width: 860px) { .joinbox { grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr); } }
.joinbox .caps { color: var(--on-panel-quiet); }
.joinbox h2 { color: var(--on-panel); font-size: clamp(21px, 2.4vw, 30px); letter-spacing: var(--track-section); margin: 6px 0 8px; }
.joinbox p { color: var(--on-panel-quiet); font-size: 14.5px; margin: 0; max-width: 52ch; }
.joinbox .btn { border-color: var(--on-panel); color: var(--on-panel); }
.joinbox .btn:hover { background: var(--on-panel); color: var(--ink-panel); }
.joinbox .btn.red { background: var(--red); border-color: var(--red); color: #fff; }
.joinbox .btn.red:hover { background: var(--red-2); border-color: var(--red-2); color: #fff; }

/* ──────────────── 24 · THE FRONT PAGE, WITH ITS RHYTHM ────────────────
   Three things give a long page its shape: a rhythm (bands alternate between
   the measured column and the full width, and between paper and ink), a place
   in it (the index marks the band you are in), and something to do (the ticker
   runs, the services switch, the bands arrive). All of the motion is off under
   `prefers-reduced-motion`, and all of it works with no script at all. */

/* The hero, on ink, full bleed. */
.hero-ink { position: relative; background: var(--ink-panel); color: var(--on-panel); padding: clamp(40px, 6vw, 86px) 0 clamp(52px, 7vw, 96px); }
.herogrid { display: grid; grid-template-columns: 1fr; gap: var(--air-2) calc(var(--gutter) * 2); align-items: center; }
@media (min-width: 900px) { .herogrid { grid-template-columns: minmax(0, 1.35fr) minmax(0, 0.65fr); } }
.herokicker { margin: 0 0 18px; }
.herokicker .caps { color: var(--paper); opacity: 0.6; }
.hero-ink h1 {
  color: var(--paper); margin: 0 0 20px;
  font-size: clamp(30px, 4.6vw, 62px); line-height: 1.06; letter-spacing: var(--track-display);
  max-width: 17ch;
}
.herolead { color: var(--paper); opacity: 0.8; font-size: 16px; max-width: 56ch; margin: 0; }
.hero-ink .btnrow { margin-top: 26px; }
/* The ghost button is a **panel** button: it is white-on-dark by design. Put it
   on paper and it is white on white — 1.1:1, invisible, and nothing about the
   page looks broken. That happened. So the plain form is now the safe one and
   the white treatment is claimed only by the dark grounds that can carry it: a
   ghost button used in the wrong place now degrades to a readable button
   instead of disappearing. This is the same rule as `--ink-panel` and
   `--ink-panel`, applied to a component rather than a colour. */
.btn.ghost { border-color: var(--line); color: inherit; }
.btn.ghost:hover { background: var(--ink); color: var(--paper); border-color: var(--ink); }
.slab.dark .btn.ghost, .strip .btn.ghost, .joinbox .btn.ghost, .footground .btn.ghost {
  border-color: rgba(255, 255, 255, 0.45); color: var(--on-panel);
}
.slab.dark .btn.ghost:hover, .strip .btn.ghost:hover, .joinbox .btn.ghost:hover, .footground .btn.ghost:hover {
  background: var(--on-panel); color: var(--ink-panel); border-color: var(--on-panel);
}
.herocover { max-width: 300px; justify-self: end; width: 100%; }
@media (max-width: 899px) { .herocover { justify-self: start; } }
/* The way down, for anyone who has read enough. */
.heroscroll {
  position: absolute; left: 50%; bottom: 14px; transform: translateX(-50%);
  display: inline-flex; align-items: center; justify-content: center;
  width: 38px; height: 38px; border: 1px solid rgba(255, 255, 255, 0.4); color: var(--paper);
}
.heroscroll:hover { background: var(--paper); color: var(--ink); }
@media (prefers-reduced-motion: no-preference) {
  .heroscroll { animation: nudge 2.4s ease-in-out infinite; }
  @keyframes nudge { 0%, 100% { transform: translate(-50%, 0); } 50% { transform: translate(-50%, 5px); } }
}

/* The ticker: the publication's signature, running. */
.tickerwrap { overflow: hidden; border-bottom: 1px solid var(--line); background: var(--paper-2); }
.tickrail { display: flex; width: max-content; }
.tickrow { display: flex; }
@media (prefers-reduced-motion: no-preference) {
  .tickrail { animation: tickrun var(--run, 40s) linear infinite; }
  .tickerwrap[data-running='no'] .tickrail { animation-play-state: paused; }
  @keyframes tickrun { from { transform: translateX(0); } to { transform: translateX(-50%); } }
}
/* No script, or reduced motion: an ordinary row you can push along yourself. */
@media (prefers-reduced-motion: reduce) { .tickerwrap { overflow-x: auto; } }
.tick {
  display: flex; align-items: baseline; gap: 10px; white-space: nowrap;
  padding: 11px 22px; border-right: 1px solid var(--line); text-decoration: none;
}
.tick:hover { background: var(--paper); }
.tlabel { font-family: var(--mono); font-size: 9.5px; letter-spacing: var(--track-label); text-transform: uppercase; color: var(--muted); }
.tvalue { font-family: var(--display); font-weight: 700; font-size: 16px; letter-spacing: var(--track-text); font-variant-numeric: tabular-nums lining-nums; }
.tchg { font-family: var(--mono); font-size: 10px; color: var(--ink-2); font-variant-numeric: tabular-nums; }
.tchg i { font-style: normal; font-size: 8px; }

/* Where you are. It arrives once the hero is behind you, and marks the band
   the reader is actually looking at. */
.sectionindex {
  position: sticky; top: 0; z-index: 30;
  background: var(--paper); border-bottom: 1px solid var(--line);
  overflow: hidden; max-height: 0; opacity: 0;
  transition: max-height 220ms ease, opacity 180ms ease;
}
.sectionindex[data-shown='yes'] { max-height: 60px; opacity: 1; }
/* With no script the attribute is never set, so the index is simply always
   there rather than never. */
.sectionindex:not([data-shown]) { max-height: 60px; opacity: 1; }
@media (prefers-reduced-motion: reduce) { .sectionindex { transition: none; } }
.sectionindex ul { display: flex; gap: 22px; list-style: none; margin: 0; padding: 0; overflow-x: auto; scrollbar-width: none; }
.sectionindex ul::-webkit-scrollbar { display: none; }
.sectionindex a {
  display: block; white-space: nowrap; padding: 13px 0 11px; text-decoration: none;
  font-family: var(--mono); font-size: 10px; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--muted); border-bottom: 2px solid transparent;
}
.sectionindex a:hover { color: var(--ink); }
.sectionindex a[aria-current='true'] { color: var(--red-text); border-bottom-color: var(--red); }

/* A slab: a band that takes the whole width and its own ground, so the page has
   a rhythm rather than twelve identical sections. */
.slab { background: var(--paper-2); padding: var(--band) 0; margin: var(--band) 0; }
.slab.dark { background: var(--ink-panel); color: var(--on-panel); }
.slab.dark .sechead { border-top-color: var(--on-panel); }
.slab.dark .sechead h2, .slab.dark .bigline { color: var(--on-panel); }
.slab.dark .secnote { color: var(--on-panel-quiet); }
.slab.dark .seclink { color: var(--on-panel); }
.slab.dark .lead { color: var(--on-panel-quiet); }
.slab.dark .btn { border-color: rgba(255, 255, 255, 0.45); color: var(--on-panel); }
.slab.dark .btn:hover { background: var(--on-panel); color: var(--ink-panel); }
.slab .band, .slab .hero { margin-bottom: 0; }

/* The services, switched in place. */
.tablist { display: flex; gap: 2px; overflow-x: auto; scrollbar-width: none; border-bottom: 1px solid var(--line); margin-bottom: var(--air); }
.tablist::-webkit-scrollbar { display: none; }
.tab {
  display: grid; gap: 3px; justify-items: start; white-space: nowrap; cursor: pointer;
  background: none; border: 0; border-bottom: 2px solid transparent; padding: 10px 18px 12px 0; color: inherit;
}
.tab .caps { color: var(--muted); }
.tab b { font-family: var(--display); font-size: 15px; font-weight: 700; letter-spacing: var(--track-text); }
.tab:hover b { color: var(--red-text); }
.tab[aria-selected='true'] { border-bottom-color: var(--red); }
.tab[aria-selected='true'] .caps { color: var(--red-text); }
.tab:focus-visible { outline: 2px solid var(--link); outline-offset: 2px; }
.panelhead { font-size: 20px; letter-spacing: var(--track-section); margin: 0 0 4px; }
.panelhook { font-size: 14px; color: var(--muted); margin: 0 0 var(--air); max-width: 70ch; }
.panelgrid { display: grid; grid-template-columns: 1fr; gap: var(--air) var(--gutter); }
@media (min-width: 640px) { .panelgrid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1000px) { .panelgrid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.panelgrid .svcitem h4 { font-family: var(--display); font-size: 16px; font-weight: 700; letter-spacing: var(--track-text); margin: 0 0 6px; }
/* Every panel is open before the script runs, and each is headed, so the page
   reads the same with no JavaScript at all. */
.tabpanel { padding-top: 2px; }
.tabpanel + .tabpanel { margin-top: var(--air-2); }

/* Bands arriving. Marked elements are visible until the script says otherwise,
   so nothing can be left invisible by a script that never ran. */
@media (prefers-reduced-motion: no-preference) {
  [data-reveal='wait'] { opacity: 0; transform: translateY(14px); }
  [data-reveal='in'] { opacity: 1; transform: none; transition: opacity 520ms ease, transform 520ms cubic-bezier(0.22, 0.61, 0.36, 1); }
}

/* ──────────────── 25 · THE DATA PAGE, MADE WORTH LOOKING AT ────────────────
   The numbers are the product, so the page that holds all of them is the one
   that most needs to reward a look. The chart carries a faint fill so its shape
   reads as a quantity, the scale is labelled at the edge, every reading is a
   point (a smooth line through three readings claims a precision the desk does
   not have), and the change is a chip rather than a sentence. */

.datagrid { gap: var(--band) var(--gutter); }
/* The full-width blue rule that used to head a card is gone: the frame's own
   tag rule (section 29) marks where a figure begins, and two rules stacked on
   one card is one rule too many. */
.figblock {
  border-top: 0;
  background: var(--paper-2);
  padding: 18px 18px 20px;
  margin: 0;
}
.figblock > .caps { color: var(--muted); }

/* The figure and its direction, on one line. */
.figrow { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; margin: 6px 0 0; }
.figblock .big { font-size: clamp(34px, 3.6vw, 48px); margin: 0; }
.chip {
  display: inline-flex; align-items: center; gap: 5px;
  font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.06em;
  padding: 4px 9px; border: 1px solid currentColor; color: var(--ink-2);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.chip i { font-style: normal; font-size: 8px; }
/* Direction is the arrow, and the chip only borrows the brand's two colours —
   never green and red, which would spend the whole red budget on decoration
   and collide with the category colours. */
.chip.up { color: var(--blue); }
.chip.down { color: var(--red-text); }

.chart { background: var(--paper); border: 1px solid var(--line); }
svg.chart .chartaxis {
  font-family: var(--mono); font-size: 10px; letter-spacing: 0.06em;
  fill: var(--muted); font-variant-numeric: tabular-nums lining-nums;
}
.figblock table.plain { background: var(--paper); }
.figblock table.plain td, .figblock table.plain th { padding-left: 10px; }

/* ──────────────── 26 · THE BOARD ────────────────
   The front page. Every tile is a field of colour with a number on it — a
   story's own figure, an indicator's latest reading, an issue number, a running
   time. Nothing is a thumbnail of something else; the number is the thing.

   Rank is size: the lead takes four squares, the two behind it take two each,
   the rest take one, so the day can be read by the size of its figures alone.
   `grid-auto-flow: dense` lets the small tiles fill in behind the large ones,
   which is what keeps a mosaic from leaving holes. */

.boardwrap { background: var(--ink-panel); color: var(--on-panel); padding: var(--air-2) 0 var(--band); margin-bottom: var(--band); }
.boardhead { display: grid; gap: 6px; margin-bottom: var(--air); }
.boardhead h1 {
  color: var(--paper); margin: 0;
  font-size: clamp(30px, 4vw, 54px); line-height: 1; letter-spacing: var(--track-display);
}
.boardnote { color: var(--paper); opacity: 0.66; font-size: 14px; margin: 0; max-width: 62ch; }

/* The filter. Hidden until the script arrives, because a filter that cannot
   filter is a row of dead buttons; the board below is the whole day either way. */
.boardbar { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 var(--air); }
.fchip {
  display: inline-flex; align-items: center; gap: 8px; cursor: pointer;
  font-family: var(--mono); font-size: 10px; letter-spacing: 0.1em; text-transform: uppercase;
  padding: 8px 13px; border: 1px solid rgba(255, 255, 255, 0.28);
  background: transparent; color: var(--paper);
}
.fchip:hover { border-color: var(--paper); }
.fchip[aria-pressed='true'] { background: var(--paper); color: var(--ink); border-color: var(--paper); }
/* The subject's own colour rides the edge of its chip, never the words. */
.fchip[data-filter]:not([data-filter='ALL']) { border-left: 3px solid var(--cat, var(--paper)); }
.fcount { font-variant-numeric: tabular-nums; opacity: 0.6; }
.fchip[aria-pressed='true'] .fcount { opacity: 0.55; }
.fchip:focus-visible { outline: 2px solid var(--paper); outline-offset: 2px; }

.board {
  display: grid; gap: 2px;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  grid-auto-rows: minmax(128px, auto);
  grid-auto-flow: dense;
}
@media (min-width: 620px) { .board { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (min-width: 900px) { .board { grid-template-columns: repeat(4, minmax(0, 1fr)); grid-auto-rows: minmax(150px, auto); } }
@media (min-width: 1240px) { .board { grid-template-columns: repeat(6, minmax(0, 1fr)); } }

.tile {
  position: relative; display: flex; flex-direction: column; gap: 6px;
  padding: 14px; text-decoration: none; overflow: hidden;
  background: var(--tone, #0a0a0a); color: #fff;
  transition: transform 0.14s ease, filter 0.14s ease;
}
.tile:hover { filter: brightness(1.12); z-index: 2; }
@media (prefers-reduced-motion: reduce) { .tile { transition: none; } }
.tile:focus-visible { outline: 2px solid #fff; outline-offset: -4px; z-index: 3; }

/* Rank by span. Two squares wide on a phone is the whole width, so the lead
   folds to a tall tile rather than an unreadably wide one. */
.t2 { grid-column: span 2; }
.t4 { grid-column: span 2; grid-row: span 2; }
@media (min-width: 900px) { .t4 { grid-column: span 2; grid-row: span 2; } }

.tiletop { display: flex; justify-content: space-between; gap: 10px; align-items: baseline; }
.tilekind, .tilewhen, .tilefoot, .tilecat {
  font-family: var(--mono); font-size: 9px; letter-spacing: 0.1em; text-transform: uppercase;
}
.tilekind { opacity: 0.8; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tilewhen { opacity: 0.66; white-space: nowrap; }
/* The figure fills what is left. It is the picture, so it is allowed to be as
   large as the tile can carry. */
.tilefig {
  font-family: var(--display); font-weight: 700; line-height: 0.9; letter-spacing: var(--track-display);
  font-variant-numeric: tabular-nums lining-nums; margin-top: auto; overflow-wrap: break-word;
  font-size: clamp(22px, 2.4vw, 32px);
}
.t2 .tilefig { font-size: clamp(28px, 3.2vw, 44px); }
.t4 .tilefig { font-size: clamp(40px, 5.2vw, 76px); }
.tilefoot { opacity: 0.7; }
.tiletitle {
  font-family: var(--display); font-weight: 700; font-size: 13px; line-height: 1.22;
  letter-spacing: var(--track-text); display: none;
}
/* Only the tiles with room carry a headline; the small ones are the figure and
   its source, which is what a board is. */
.t2 .tiletitle, .t4 .tiletitle { display: block; }
.t4 .tiletitle { font-size: clamp(15px, 1.5vw, 19px); }
.tilecat { opacity: 0.62; display: none; }
.t4 .tilecat { display: block; }
.tilecat .om { color: inherit; font-family: var(--mono); font-weight: 500; }

/* A tile filtered out leaves the grid entirely, so the mosaic closes up. */
.tile[hidden] { display: none !important; }
.boardempty { color: var(--paper); opacity: 0.7; margin: var(--air) 0 0; }
.boardgo { display: flex; flex-wrap: wrap; gap: 10px; margin-top: var(--air-2); }
.boardwrap .btn { border-color: rgba(255, 255, 255, 0.4); color: var(--on-panel); }
.boardwrap .btn:hover { background: var(--on-panel); color: var(--ink-panel); }

/* What Ensight is, said once, under the board. */
.saying { display: grid; grid-template-columns: 1fr; gap: var(--air) calc(var(--gutter) * 2); margin-bottom: var(--band); }
@media (min-width: 900px) { .saying { grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr); align-items: start; } }
.sayingbig {
  font-family: var(--display); font-weight: 700; font-size: clamp(20px, 2.2vw, 28px); line-height: 1.24;
  letter-spacing: var(--track-text); margin: 0; max-width: 26ch;
  border-left: var(--flag) solid var(--red); padding-left: 20px;
}
.saying p { font-size: 15.5px; }

/* ──────────────── 27 · THE WIRE FRONT ────────────────
   The shape a markets wire uses: a ticker across the top, a lead well with a
   rail beside it, a strip, then a block per subject. The densest arrangement in
   news design, because a reader of a business front page is scanning for the
   one thing they came for rather than reading down the page.

   The structure is borrowed; everything set inside it is the manual's. The
   category colour rides the rule above a block and never touches the words, the
   figure is the picture, and every headline carries its twin. */

/* The lead well and the rail. */
.front { display: grid; grid-template-columns: 1fr; gap: var(--air-2) calc(var(--gutter) * 1.5); margin-bottom: var(--band); }
@media (min-width: 920px) { .front { grid-template-columns: minmax(0, 1fr) minmax(0, 300px); } }
@media (min-width: 1200px) { .front { grid-template-columns: minmax(0, 1fr) minmax(0, 330px); } }
.well { display: grid; grid-template-columns: 1fr; gap: var(--air) var(--gutter); }
@media (min-width: 760px) { .well { grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr); } }
.wellnext { display: grid; align-content: start; border-top: var(--rule) solid var(--ink); }

/* A headline row: the figure, the two editions, the source and the hour. This
   is the unit a wire front is made of. */
.wrow {
  display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 0 14px;
  padding: 13px 0; border-bottom: 1px solid var(--line); text-decoration: none;
  border-left: 3px solid transparent; padding-left: 0;
}
.wrow:hover { border-left-color: var(--cat, var(--red)); padding-left: 11px; }
@media (prefers-reduced-motion: no-preference) { .wrow { transition: padding-left 0.12s ease, border-left-color 0.12s ease; } }
.wfig {
  font-family: var(--display); font-weight: 700; font-size: 17px; line-height: 1.2;
  letter-spacing: var(--track-text); font-variant-numeric: tabular-nums lining-nums;
  color: var(--red-text); white-space: nowrap;
}
.wbody { display: grid; gap: 2px; min-width: 0; }
.wtitle { font-family: var(--display); font-weight: 700; font-size: 15.5px; line-height: 1.24; letter-spacing: var(--track-text); }
.wrow:hover .wtitle { color: var(--red-text); }
.wtwin { font-family: var(--display); font-weight: 700; font-size: 13.5px; line-height: 1.24; letter-spacing: var(--track-text); color: var(--red-text); }
.wmeta { font-family: var(--mono); font-size: 9.5px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted); margin-top: 3px; }
.wsum { font-size: 13.5px; color: var(--muted); margin-top: 6px; }

/* The rail. Boxes a reader glances at without reading. */
.frontrail { display: grid; gap: var(--air-2); align-content: start; }
.railbox { border-top: var(--rule) solid var(--ink); }
.railhead { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; padding: 9px 0 10px; }
.railhead .caps { color: var(--ink); }
.railhead a.caps { color: var(--ink); text-decoration: none; }
.railhead a.caps:hover { text-decoration: underline; }
.raillist { display: grid; }
.railrow {
  display: grid; grid-template-columns: minmax(0, 1fr) auto auto; gap: 0 10px; align-items: baseline;
  padding: 8px 0; border-top: 1px solid var(--line); text-decoration: none;
}
.railrow:hover { background: var(--paper-2); }
.rrlabel { font-family: var(--mono); font-size: 9.5px; letter-spacing: var(--track-label); text-transform: uppercase; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rrvalue { font-family: var(--display); font-weight: 700; font-size: 14px; letter-spacing: var(--track-text); font-variant-numeric: tabular-nums lining-nums; }
.rrchg { font-family: var(--mono); font-size: 9.5px; color: var(--ink-2); font-variant-numeric: tabular-nums; white-space: nowrap; }
.rrchg i { font-style: normal; font-size: 7px; }
.rrchg.up { color: var(--blue); }
.rrchg.down { color: var(--red-text); }

.railranked { list-style: none; margin: 0; padding: 0; }
.railranked li { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 0 12px; padding: 10px 0; border-top: 1px solid var(--line); }
.railranked a { text-decoration: none; display: grid; gap: 2px; min-width: 0; }
.railranked a:hover .wtitle { color: var(--red-text); }
.rrno {
  font-family: var(--display); font-weight: 700; font-size: 15px; line-height: 1.25;
  letter-spacing: var(--track-display); color: var(--blue); font-variant-numeric: tabular-nums;
}
.railranked .wtitle { font-size: 14px; }
.railranked .wtwin { font-size: 12.5px; }
.railbox .cover { margin-top: 4px; }
.railbtn { margin-top: 12px; }

/* The strip, where a wire puts its newsletter: after the lead, before the
   subjects, when the reader has decided the publication is worth something. */
.strip { background: var(--ink-panel); color: var(--on-panel); padding: var(--air-2) 0; margin: 0 0 var(--band); }
.stripgrid { display: grid; grid-template-columns: 1fr; gap: var(--air) var(--gutter); align-items: center; }
@media (min-width: 860px) { .stripgrid { grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr); } }
.strip .caps { color: var(--on-panel-quiet); }
.strip h2 { color: var(--on-panel); font-size: clamp(21px, 2.4vw, 31px); letter-spacing: var(--track-section); margin: 6px 0 8px; }
.strip p { color: var(--on-panel-quiet); font-size: 14.5px; margin: 0; max-width: 54ch; }

/* A block per subject. The label sits on its own rule in the subject's colour;
   the words stay ink, as the manual requires. */
.subjects { display: grid; gap: var(--band); margin-bottom: var(--band); }
.subject { border-top: var(--rule) solid var(--cat, var(--ink)); padding-top: 12px; }
.subjhead { display: flex; justify-content: space-between; align-items: baseline; gap: 14px; flex-wrap: wrap; margin-bottom: var(--air); }
.subjhead h2 { font-size: var(--h-section); letter-spacing: var(--track-section); margin: 0; }
.subjhead .om { font-size: inherit; }
.subjhead a.caps { color: var(--ink); text-decoration: none; white-space: nowrap; }
.subjhead a.caps:hover { text-decoration: underline; }
.subjbody { display: grid; grid-template-columns: 1fr; gap: var(--air) calc(var(--gutter) * 1.4); }
@media (min-width: 820px) { .subjbody { grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr); } }
.subjlead { display: grid; gap: 4px; text-decoration: none; align-content: start; }
.subjlead .pic { margin-bottom: 10px; }
.subjlead .wtitle { font-size: 19px; }
.subjlead:hover .wtitle { color: var(--red-text); }
.subjrows { display: grid; align-content: start; border-top: 1px solid var(--line); }

/* The films at the foot, three across. */
.filmstrip { display: grid; grid-template-columns: 1fr; gap: var(--air) var(--gutter); }
@media (min-width: 620px) { .filmstrip { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 900px) { .filmstrip { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.filmcard { display: grid; gap: 4px; text-decoration: none; }
.filmcard .vposter { margin-bottom: 10px; }
.slab.dark .wtitle { color: var(--on-panel); }
/* The twin sits on a permanently dark ground, so it takes the lifted red at
   all times: the page-level one is 3.89:1 here. */
.slab.dark .wtwin { color: var(--red-on-panel); }
.slab.dark .filmcard:hover .wtitle { color: var(--red-text); }

/* ──────────────── 28 · PHOTOGRAPHS, WHERE THERE ARE ANY ────────────────
   Three ratios and no fourth, which is both the manual's rule and what the
   field actually runs: the FT sets most of its front at 16:9, Reuters at 3:2,
   the Guardian at 5:4 and 1:1, and everyone uses a square for a small card and
   a portrait for a face. Ensight takes 16:9 for a story, 1:1 for a card or a
   cover, 3:4 for a person.

   Width and height are declared on every image so the page does not move as
   one loads — the single worst thing a picture can do to a reader on a slow
   connection. Below the fold they load lazily; the lead does not, because it is
   the thing the reader came to see. */

.pic.shot { background: var(--paper-3); }
.pic.shot img { width: 100%; height: 100%; object-fit: cover; display: block; }
.pic.r16x9 { aspect-ratio: 16 / 9; }
.pic.r1x1 { aspect-ratio: 1 / 1; }
.pic.r3x4 { aspect-ratio: 3 / 4; }
/* The credit sits in the corner of the frame, the way a picture desk sets it —
   legible, and never larger than the caption it belongs to. */
.pic.shot figcaption {
  position: absolute; right: 0; bottom: 0;
  font-family: var(--mono); font-size: 9px; letter-spacing: 0.06em; text-transform: uppercase;
  color: #fff; background: rgba(0, 0, 0, 0.66); padding: 3px 8px;
}
/* A picture and a poster occupy the same slot, so a card does not change shape
   the day a photograph arrives for it. */
.lead-story .pic.shot, .second .pic.shot, .third .pic.shot, .subjlead .pic.shot { margin-bottom: 14px; }
.pic.shot.lead { aspect-ratio: 16 / 10; }
@media (max-width: 700px) { .pic.shot.lead { aspect-ratio: 16 / 9; } }

/* ──────────────── 29 · THE CHART FRAME, AND THE WEEK IN NUMBERS ────────────────
   Two conventions borrowed from *The Economist*, because both are conventions
   rather than anyone's property, and both happen to be the thing this
   publication already promises.

   The first is the furniture around a figure: a short heavy rule to mark where
   a chart begins, a title saying what is measured, a lighter line carrying the
   unit and the period, the plot, and the source underneath. It answers a
   reader's four questions in the order they ask them. Ensight draws the rule in
   its own red, sets the title at the display weight and the subtitle in the
   label style, and
   keeps the one series in the manual's deep blue — what is borrowed is the
   order of the information, not the look of it.

   The second is the digest: the week reduced to the figures that moved, one
   line each, so a reader who has been away catches up standing at a lift. Every
   line carries its twin in the other language, which no one else's digest
   does. */

.figtag { display: block; width: 28px; height: 5px; background: var(--red); margin: 0 0 12px; }
.fighead { display: block; margin: 0 0 12px; }
.fighead strong {
  display: block;
  font-family: var(--display); font-weight: 700; font-size: 19px; line-height: 1.16;
  letter-spacing: var(--track-display);
}
.figsub {
  display: block; margin-top: 6px;
  font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--muted); font-variant-numeric: tabular-nums lining-nums;
}
.fignote { font-size: 13.5px; line-height: 1.5; color: var(--ink-2); margin: 12px 0 0; max-width: 58ch; }
/* The source is the line this publication is least willing to leave off, so it
   is set apart by its own hairline rather than left to trail the note. */
.figsource {
  margin: 12px 0 0; padding-top: 9px; border-top: 1px solid var(--line);
  font-family: var(--mono); font-size: 10px; letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--muted);
}

/* The week in numbers. The figure is the picture here too — it holds the left
   column at a fixed width so the column of figures reads down the page as a
   column, and the category colour rides the rule at the edge of the row and
   never touches the words. */
.week { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--line); }
.week li { border-bottom: 1px solid var(--line); }
.week li > a {
  display: grid; grid-template-columns: 132px 1fr; gap: 0 var(--gutter); align-items: start;
  padding: 15px 0 15px 15px; text-decoration: none; color: inherit;
  border-left: 3px solid var(--cat, var(--ink));
}
.week li > a:hover { background: var(--paper-2); }
.weekfig {
  font-family: var(--display); font-weight: 700; font-size: 26px; line-height: 1.02;
  letter-spacing: var(--track-display); color: var(--red-text);
  font-variant-numeric: tabular-nums lining-nums; overflow-wrap: break-word;
}
.weekbody { display: block; }
.weektitle {
  display: block;
  font-family: var(--display); font-weight: 700; font-size: 15.5px; line-height: 1.26;
  letter-spacing: var(--track-text);
}
.week li > a:hover .weektitle { color: var(--red-text); }
.weektwin {
  display: block; margin-top: 3px;
  font-family: var(--display); font-weight: 700; font-size: 13.5px; line-height: 1.26;
  letter-spacing: var(--track-text); color: var(--red-text);
}
.weeksrc {
  display: block; margin-top: 6px;
  font-family: var(--mono); font-size: 10px; letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--muted);
}

@media (max-width: 720px) {
  .week li > a { grid-template-columns: 1fr; gap: 6px; }
  .weekfig { font-size: 22px; }
}

/* ──────────────── 30 · THE ARTICLE PAGE ────────────────
   The page a stranger lands on. Everything here answers one of three questions
   a reader has in the first four seconds: what happened, who says so, and what
   it connects to. The body keeps a reading measure; the rail carries the
   connections; nothing is decoration. */

.storygrid { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--air-2) var(--gutter); padding-top: var(--air-2); }
@media (min-width: 900px) {
  .storygrid { grid-template-columns: minmax(0, 1fr) 300px; gap: var(--band) calc(var(--gutter) * 1.6); align-items: start; }
}
/* A reading measure, and no wider — a line of 90 characters is a line nobody
   finishes. The rail takes the space that would otherwise be spent making the
   body harder to read. */
.storybody { max-width: 46rem; min-width: 0; }
.storybody > .wtop { display: flex; justify-content: space-between; align-items: baseline; gap: 6px 16px; flex-wrap: wrap; margin-bottom: 4px; }
.storytwin { font-size: 20px; line-height: 1.25; margin-bottom: 18px; }

.storyshot { margin: 18px 0 4px; }
.storyshot .pic { width: 100%; }

/* The byline. Two halves: who, and when. It sits under the picture rather than
   over it, because a reader looks at the photograph first whatever anyone
   intends, and the name means more once they have. */
.byline {
  display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 6px var(--gutter);
  border-top: 1px solid var(--line); border-bottom: 1px solid var(--line);
  padding: 12px 0; margin: 18px 0 22px;
}
.byline .bywho { display: flex; align-items: baseline; flex-wrap: wrap; gap: 8px; }
.byline .bywho b { font-family: var(--display); font-weight: 700; font-size: 15px; letter-spacing: var(--track-text); }
.byline .byrole, .byline .bywhen {
  font-family: var(--mono); font-size: 10px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--muted);
}
/* An update is the one part of a dateline a reader should notice. */
.byline .byupdated { color: var(--red-text); }

.corrections { border-left: 3px solid var(--red); padding-left: 14px; margin-top: 26px; }
.corrections h3 { margin: 0 0 6px; font-size: 15px; }

/* ── the rail ── */
.storyrail { min-width: 0; display: grid; gap: var(--air-2); }
@media (min-width: 900px) { .storyrail { position: sticky; top: 92px; } }

.railfigs, .railmore { list-style: none; margin: 0; padding: 0; }
.railfigs li { border-top: 1px solid var(--line); }
.railfigs li:first-child { border-top: 0; }
.railfigs a { display: grid; grid-template-columns: 1fr auto; gap: 2px 10px; padding: 11px 0; text-decoration: none; color: inherit; }
.railfigs a:hover .rfvalue { color: var(--red-text); }
.rflabel { font-family: var(--mono); font-size: 10px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted); }
.rfvalue {
  grid-row: 2; font-family: var(--display); font-weight: 700; font-size: 22px; line-height: 1.05;
  letter-spacing: var(--track-display); font-variant-numeric: tabular-nums lining-nums;
}
.railfigs .chip { grid-column: 2; grid-row: 2; align-self: center; }
.rfperiod { grid-column: 1 / -1; grid-row: 3; font-family: var(--mono); font-size: 9.5px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--muted); }

.railterms { margin: 0; }
.railterms > div { border-top: 1px solid var(--line); padding: 11px 0; }
.railterms > div:first-child { border-top: 0; }
.railterms dt { font-family: var(--display); font-weight: 700; font-size: 14px; letter-spacing: var(--track-text); }
.railterms dt a { text-decoration: none; color: inherit; }
.railterms dt a:hover { color: var(--red-text); }
.railterms dt .om { display: block; color: var(--red-text); font-size: 12.5px; }
.railterms dd { margin: 4px 0 0; font-size: 13px; line-height: 1.45; color: var(--ink-2); }

.railmore li { border-top: 1px solid var(--line); }
.railmore li:first-child { border-top: 0; }
.railmore a { display: grid; grid-template-columns: 1fr auto; gap: 10px; align-items: baseline; padding: 10px 0; text-decoration: none; color: inherit; }
.railmore a:hover .wtitle { color: var(--red-text); }
.railmore .wtitle { font-size: 14px; }
.railmore .when { font-family: var(--mono); font-size: 9.5px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--muted); white-space: nowrap; }

/* ──────────────── 31 · THE MASTHEAD ON A PHONE ────────────────
   Three changes, each answering something measured rather than guessed:

    · **The tagline and the language toggle leave the bar.** They are the two
      widest things in it and neither is why anyone opened the page. The toggle
      moves to the foot of the header where it has a whole row to itself, which
      is also where a thumb reaches most easily.
    · **The section nav says that it continues.** A row that scrolls with no
      edge to it reads as a row that ends. A fade at the right edge, and the
      row's own scrollbar hidden, is the whole fix.
    · **The wordmark shrinks to what a phone can still read.** 34px of mark on a
      375px screen is a poster, not a masthead. */

@media (max-width: 719px) {
  .sitehead .nav { display: grid; grid-template-columns: auto 1fr; gap: 8px 10px; align-items: center; }
  /* The tagline is the publication's promise, and it is on the About page, the
     footer and the front page dateline. It does not also need to cost a
     quarter of a phone's first screen. */
  .sitehead .wm small { display: none; }
  .sitehead .wm .wmimg { width: 108px !important; height: 26px !important; }

  .sitehead .tools { justify-self: end; gap: 6px; flex-wrap: nowrap; }
  /* Two controls in the bar: search, and the one action the publication wants.
     The theme toggle moves down beside the language switch. */
  .sitehead .tools .langtoggle, .sitehead .tools .themebtn { display: none; }
  .sitehead .tools .btn.sm { padding: 9px 13px; font-size: 10px; }

  .sitehead .navlinks {
    grid-column: 1 / -1;
    display: flex; gap: 18px; overflow-x: auto; scrollbar-width: none;
    padding-bottom: 2px;
    /* The row is cut with a fade rather than a hard edge, so a reader can see
       that it goes on. */
    -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 34px), transparent);
    mask-image: linear-gradient(to right, #000 calc(100% - 34px), transparent);
  }
  .sitehead .navlinks::-webkit-scrollbar { display: none; }
  .sitehead .navlinks a { white-space: nowrap; }

  /* The row that used to crowd the bar, given its own line under the nav. */
  .headfoot {
    grid-column: 1 / -1;
    display: flex; align-items: center; justify-content: space-between; gap: 10px;
    border-top: 1px solid var(--line); padding-top: 8px; margin-top: 2px;
  }
  .headfoot .langtoggle { display: inline-flex; }
  .headfoot .themebtn { display: inline-flex; }
}
/* Above the fold on a phone belongs to the journalism; on a wide screen the
   second row is redundant, because everything in it is already in the bar. */
@media (min-width: 720px) { .headfoot { display: none; } }

/* ──────────────── 32 · SECTION FRONTS, AND SEARCH ────────────────
   A list filtered by category is not a section front. A front has a lead, and
   a lead is an editorial judgement — which is the thing a publication has and
   an archive does not. */

.sectionhead .wavemark { margin-bottom: 18px; }
.sectionhead { border-bottom: var(--rule) solid var(--cat, var(--ink)); padding: var(--air-2) 0 12px; margin-bottom: var(--air-2); }
.sectionhead h1 { margin: 0; }
.sectionhead h1 .om { color: var(--red-text); }
.sectionhead .lead { margin: 8px 0 0; font-family: var(--mono); font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted); }

.sectionlead { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--air-2) var(--gutter); }
@media (min-width: 900px) { .sectionlead { grid-template-columns: minmax(0, 1.55fr) minmax(0, 1fr); align-items: start; } }
.sectionrail { display: grid; gap: 0; align-content: start; }
.sectionrail .railbox { margin-top: var(--air-2); }
.subjlead .wsum { display: block; margin-top: 8px; font-size: 15px; line-height: 1.5; color: var(--ink-2); }

/* ── search ── */
.visually-hidden {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.searchform { display: flex; gap: 10px; flex-wrap: wrap; align-items: stretch; margin: 4px 0 14px; }
.searchwrap { display: flex; align-items: center; gap: 10px; flex: 1 1 260px; border: 1.5px solid var(--ink); padding: 0 14px; background: var(--paper); }
.searchwrap svg { flex: 0 0 auto; color: var(--muted); }
.searchwrap input {
  flex: 1; border: 0; background: none; color: inherit; padding: 13px 0;
  font-family: var(--display); font-weight: 700; font-size: 17px; letter-spacing: var(--track-text);
}
.searchwrap input:focus { outline: none; }
.searchwrap:focus-within { border-color: var(--red); }

/* One shape for every kind of answer: the figure on the left, the thing on the
   right. A result list that changes shape per kind is four lists. */
.results { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--line); }
.results li { border-bottom: 1px solid var(--line); }
.results li > a { display: grid; grid-template-columns: 132px minmax(0, 1fr); gap: 0 var(--gutter); padding: 14px 0; text-decoration: none; color: inherit; align-items: start; }
.results.tight li > a { padding: 11px 0; }
.results li > a:hover { background: var(--paper-2); }
.results li > a:hover .wtitle { color: var(--red-text); }
.rfig {
  font-family: var(--display); font-weight: 700; font-size: 22px; line-height: 1.05;
  letter-spacing: var(--track-display); color: var(--red-text);
  font-variant-numeric: tabular-nums lining-nums; overflow-wrap: break-word;
}
.rbody { display: block; min-width: 0; }
.rcat, .rsrc { display: block; font-family: var(--mono); font-size: 9.5px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted); }
.rcat { margin-bottom: 3px; }
.rsrc { margin-top: 5px; }
.results .wtitle, .results .wtwin { display: block; }
.results.terms { border-top: 1px solid var(--line); margin: 0; }
.results.terms > div { border-bottom: 1px solid var(--line); padding: 13px 0; }
.results.terms dt { font-family: var(--display); font-weight: 700; font-size: 16px; letter-spacing: var(--track-text); }
.results.terms dt a { text-decoration: none; color: inherit; }
.results.terms dt .om { color: var(--red-text); font-size: 14px; }
.results.terms dd { margin: 5px 0 0; font-size: 14.5px; line-height: 1.5; color: var(--ink-2); max-width: 70ch; }

/* The row of sections, wherever a reader is offered them. */
.sectionrow { display: flex; flex-wrap: wrap; gap: 8px 10px; margin: 10px 0 0; }
.sectionrow a {
  display: inline-flex; align-items: baseline; gap: 7px;
  font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.08em; text-transform: uppercase;
  text-decoration: none; color: inherit; border: 1px solid var(--line); padding: 7px 11px;
  border-left: 3px solid var(--cat, var(--ink));
}
.sectionrow a:hover { border-color: var(--ink); border-left-color: var(--cat, var(--ink)); }
.sectionrow a b { font-family: var(--mono); font-weight: 500; color: var(--muted); }

@media (max-width: 720px) {
  .results li > a { grid-template-columns: 1fr; gap: 6px; }
  .rfig { font-size: 19px; }
}

/* ──────────────── 33 · A LIVE FIGURE IN RUNNING TEXT ────────────────
   The figure keeps its place in the sentence. It is marked by an underline in
   the category's own colour and a small red dot, not by turning blue and
   jumping out — a paragraph of reporting is not a set of links, and a reader
   should be able to read straight past these without being interrupted by
   them. The dot is the signal that there is more behind the number. */

.livefig {
  color: inherit; text-decoration: none;
  border-bottom: 1.5px solid var(--cat, var(--blue));
  padding-bottom: 1px;
  font-variant-numeric: tabular-nums lining-nums;
  white-space: nowrap;
}
.livefig .livedot {
  display: inline-block; width: 4px; height: 4px; border-radius: 50%;
  background: var(--red); margin-left: 3px; vertical-align: 0.42em;
}
.livefig:hover { border-bottom-color: var(--red); color: var(--red-text); }
.livefig:focus-visible { outline: 2px solid var(--red); outline-offset: 2px; }

/* In print and in the light version there is nothing to follow, so the mark
   goes and the number is just a number again. */
@media print { .livefig { border-bottom: 0; } .livefig .livedot { display: none; } }

/* ──────────────── 34 · THE BRAND GUIDELINE'S OWN HAND ────────────────
   Three things the guideline draws that this site had never used.

   **The width axis.** Archivo carries widths 62–125, and a headline set narrow
   is how a newspaper buys room. It matters more here than at any English-only
   paper: every headline on this site is set twice, once in each language, so
   the column has to hold two of everything. Condensing the display face by 12%
   is worth roughly a word and a half a line, and it reads as intent rather than
   as compression because the face was drawn for it.

   **The radius.** The one interface the guideline draws — the sign-in card on
   page 36 — is soft: a large radius on the card, a smaller one on the fields
   and the action. That language belongs on things a reader *touches*. It does
   not belong on the editorial grid, and putting it there would round off the
   rules and cards that make a business page read as a business page. So the
   radius lands on controls and forms, and the grid stays square.

   **The pattern.** A field of red waves, taken from the striped globe in the
   mark. It is the one piece of pure brand the site can carry, so it carries it
   only as a mark at the head of a page — a section front, the magazine before
   its first issue, the missing page — and nowhere a figure or a headline has to
   sit on top of it. */

h1, h2, h3, .wtitle, .fig, .typo-fig, .big, .lead-story h2, .sechead h2 {
  font-stretch: var(--wide-head);
}
/* A figure is the picture, and a picture is allowed to be narrower still. */
.fig, .typo-fig, .big, .weekfig, .rfig, .rfvalue { font-stretch: var(--wide-fig); }

/* Controls, per the card on page 36 of the guideline. */
:root { --radius: 6px; --radius-card: 14px; }
.btn, .chip, input, select, textarea, .searchwrap { border-radius: var(--radius); }
.joinbox, .kitbox, .figblock, .railbox.soft { border-radius: var(--radius-card); }
/* A form is the one place this site is an application rather than a paper, so
   it is the one place the guideline's soft card is right whole. */
.kitform input, .kitform select, .kitform textarea, .searchwrap {
  background: var(--paper-2); border-color: transparent;
  /* The field is paper now, so what is typed is ink — not the white that
     section 22 set for a field on the dark panel. White on paper was invisible. */
  color: var(--ink);
}
.kitform input:focus, .kitform select:focus, .kitform textarea:focus, .searchwrap:focus-within {
  background: var(--paper); border-color: var(--red);
}


/* The same pattern at rule height. A field of waves is a statement and belongs
   at the head of a section front; a band of them is punctuation, and that is
   what a long front page needs between one movement and the next. Same tile,
   same crest-aligned seam — only the window onto it is shorter. */
.waverule {
  display: block; height: 30px;
  background-repeat: repeat-x;
  background-size: 120px 70px;
  background-position: center;
  background-image: var(--wave);
  /* Cropped top and bottom on purpose: the guideline prints the pattern as a
     crop of an endless field, not as a motif with edges. */
  margin: var(--air-2) 0 var(--band);
}
/* The footer wears it along its top edge, where the publication signs off. */
.footground { position: relative; }
.footground::before {
  content: ""; display: block; height: 26px;
  background-image: var(--wave);
  background-repeat: repeat-x; background-size: 120px 70px; background-position: center top;
}

/* The wordmark in the red lozenge the guideline draws it in — page 10, and on
   the letterhead. The site had never used it. It goes where there is room for
   it to be a signature rather than a second masthead: the foot of the page. */
.marklozenge {
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--red); padding: 13px 20px; border-radius: 12px;
}
.marklozenge .wmimg { background-color: #fff; }

/* The brand pattern, from page 16 of the guideline: a field of red waves taken
   from the striped globe in the mark. Drawn in CSS — five curves, costing
   neither a request nor a download.

   Two things it took to get right, and the second is the interesting one.

   The bands are **thick with a thin gap**. Thin strokes on wide gaps read as a
   texture; the document draws the opposite, and the opposite is what says
   Ensight.

   And the tile boundary sits on a **crest**, not on a zero crossing. An SVG
   background clips at its own viewBox, so wherever the tile ends the stroke is
   cut by a vertical line. Cut it where the wave is steepest and that vertical
   slices across an angled stroke, leaving a notch every 120 pixels — which is
   exactly the seam the first two attempts had. Cut it where the wave is flat
   and the cut runs square across the stroke, so the tiles meet invisibly. Each
   curve therefore starts and ends with a horizontal tangent: that is what the
   cubics below are for, and why they are not the quadratics you would reach
   for first. */
.wavemark {
  /* A span, so it needs telling: an inline box ignores height and collapses. */
  display: block;
  height: 70px;
  background-repeat: repeat-x;
  background-size: 120px 70px;
  background-image: var(--wave);
}
/* On a dark ground the pattern would be the brightest thing on the page, which
   is not what a 5%-of-a-screen accent is for. */
:root[data-theme='dark'] .wavemark { opacity: 0.6; }
@media (prefers-color-scheme: dark) { :root:not([data-theme='light']) .wavemark { opacity: 0.6; } }

/* The tagline, which the guideline pairs with the primary logo and nothing
   else. It is set in the label voice so it reads as a signature rather than as
   a headline competing with the wordmark. */
.tagline {
  font-family: var(--mono); font-size: 10px; font-weight: 500;
  letter-spacing: var(--track-label); text-transform: uppercase; color: var(--muted);
}

/* ──────────────── 35 · THE FRONT PAGE, REBUILT ────────────────
   Four movements, four shapes, alternating grounds — replacing nine bands that
   all had the same shape and all sat on paper.

   The measurement that drove it: the old lead set a 44-pixel headline in a
   250-pixel measure, because the two editions ran in parallel columns inside an
   already-narrow main column. Six lines of two words, at the top of the page,
   where the day is supposed to be announced. Everything else on the page was
   downstream of that failure. */

/* ── 1 · the front ── */
.hero {
  display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--air) var(--gutter);
  padding: var(--air) 0 var(--band);
  border-bottom: var(--rule) solid var(--ink);
  margin-bottom: var(--band);
}
@media (min-width: 900px) {
  /* Seven columns of picture to five of words: the headline gets a measure it
     can actually be set in, which is the whole point of the rebuild. */
  .hero { grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); gap: var(--air-2) calc(var(--gutter) * 1.6); align-items: start; }
}
.heroshot { display: block; text-decoration: none; }
.heroshot .pic { border-top: var(--rule) solid var(--cat, var(--ink)); }
.herotext { min-width: 0; display: flex; flex-direction: column; }
.herotext .wtop { display: flex; justify-content: space-between; align-items: baseline; gap: 6px 16px; flex-wrap: wrap; margin-bottom: 14px; }
.herolink { text-decoration: none; color: inherit; display: block; }

.herohead {
  font-family: var(--display); font-weight: 700;
  font-size: clamp(34px, 4.4vw, 62px); line-height: 0.98;
  letter-spacing: var(--track-display); font-stretch: var(--wide-head);
  margin: 0;
}
.herolink:hover .herohead { color: var(--red-text); }
/* The other edition, directly beneath and a little over half the size. The
   manual asks for two equals, not two columns: both headlines are here, both
   are in the tab order, neither is behind a toggle — and neither has to be set
   in half a measure to prove it. */
.herotwin {
  font-family: var(--display); font-weight: 700;
  font-size: clamp(20px, 2.3vw, 33px); line-height: 1.06;
  letter-spacing: var(--track-display); font-stretch: var(--wide-head);
  color: var(--red-text); margin: 14px 0 0;
}
.herosum { font-size: 17px; line-height: 1.5; color: var(--ink-2); max-width: 54ch; margin: 20px 0 0; }
.herofoot {
  display: flex; align-items: center; justify-content: space-between; gap: 14px; flex-wrap: wrap;
  border-top: 1px solid var(--line); margin-top: auto; padding-top: 14px;
}
.herofoot > .caps { color: var(--muted); }
/* The number behind the story, where the desk tracks one. */
.herofig {
  display: inline-flex; align-items: baseline; gap: 9px; text-decoration: none; color: inherit;
  border-left: 3px solid var(--red); padding-left: 11px;
}
.herofig b {
  font-family: var(--display); font-weight: 700; font-size: 21px; letter-spacing: var(--track-display);
  font-variant-numeric: tabular-nums lining-nums; font-stretch: var(--wide-fig); color: var(--blue);
}
.herofig .caps { color: var(--muted); }
.herofig:hover b { color: var(--red-text); }

/* ── 2 · the position ── */
.slab.dark.position { padding: var(--band) 0; }
.board2 { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: 1px; background: rgba(255, 255, 255, 0.14); }
.b2cell {
  display: grid; align-content: start; gap: 4px;
  background: var(--ink-panel); padding: 20px 18px 18px; text-decoration: none; color: var(--on-panel);
}
.b2cell:hover { background: var(--ink-panel-2); }
.b2label { font-family: var(--mono); font-size: 10px; font-weight: 500; letter-spacing: var(--track-label); text-transform: uppercase; color: var(--on-panel-quiet); }
/* White, not blue. Blue is the data colour, but the guideline lists Black+Blue
   among the pairings to avoid and a board of blue figures on black is that
   pairing at full size. Blue keeps the charts, which sit on paper. */
.b2value {
  font-family: var(--display); font-weight: 700; font-size: clamp(27px, 2.6vw, 38px); line-height: 1;
  letter-spacing: var(--track-display); font-stretch: var(--wide-fig);
  font-variant-numeric: tabular-nums lining-nums; color: var(--on-panel);
}
.b2chg { font-family: var(--mono); font-size: 11px; letter-spacing: 0.05em; color: var(--on-panel-quiet); font-variant-numeric: tabular-nums; }
.b2chg i { font-style: normal; font-size: 8px; }
.b2chg.up { color: var(--on-panel); }
.b2chg.down { color: var(--red-on-panel); }
.b2meta { font-family: var(--mono); font-size: 9.5px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--on-panel-quiet); margin-top: 4px; }

/* ── 3 · what moved ── */
@media (min-width: 900px) {
  .movedcols .week { columns: 2; column-gap: calc(var(--gutter) * 1.6); }
  .movedcols .week li { break-inside: avoid; }
  /* A column rule would be a fourth vertical line in a page that already has
     enough; the gutter does the separating. */
  .movedcols .week { border-top: 0; }
  .movedcols .week li:first-child { border-top: 1px solid var(--line); }
}

/* ── 4 · the desk ── */
.subjgrid { display: grid; grid-template-columns: repeat(auto-fit, minmax(270px, 1fr)); gap: var(--air-2) var(--gutter); }
.subjcard { min-width: 0; border-top: var(--rule) solid var(--cat, var(--ink)); padding-top: 12px; }
.subjcaphead { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; margin-bottom: 12px; }
.subjcaphead a { text-decoration: none; color: inherit; }
.subjcaphead a:hover { color: var(--red-text); }
.subjcaphead .count { color: var(--muted); }
.subjcardlead { display: block; text-decoration: none; color: inherit; }
.subjcardlead .pic { margin-bottom: 10px; }
.subjcardlead .wtitle { display: block; font-size: 17px; }
.subjcardlead:hover .wtitle { color: var(--red-text); }
.subjcardlead .wtwin { display: block; font-size: 13.5px; margin-top: 2px; }
.subjcardrest { list-style: none; margin: 12px 0 0; padding: 0; }
.subjcardrest li { border-top: 1px solid var(--line); }
.subjcardrest a { display: grid; grid-template-columns: auto 1fr; gap: 9px; align-items: baseline; padding: 9px 0; text-decoration: none; color: inherit; }
.subjcardrest b {
  font-family: var(--display); font-weight: 700; font-size: 13px; color: var(--red-text);
  font-variant-numeric: tabular-nums lining-nums; font-stretch: var(--wide-fig); white-space: nowrap;
}
.subjcardrest span { font-family: var(--display); font-weight: 700; font-size: 13.5px; line-height: 1.24; letter-spacing: var(--track-text); }
.subjcardrest a:hover span { color: var(--red-text); }

.threeup { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--band) var(--gutter); }
@media (min-width: 860px) { .threeup { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--air-2) calc(var(--gutter) * 1.4); } }
.threeup .railbtn { margin-top: 14px; }

@media (max-width: 899px) {
  .hero { padding-bottom: var(--air-2); margin-bottom: var(--air-2); }
  .herosum { margin-top: 14px; }
  .herofoot { margin-top: 18px; }
}

/* ──────────────── 36 · THE FRONT PAGE ON A PHONE ────────────────
   The rebuilt front is 6.1 screens on a desktop and was 15.4 on a phone, which
   is the same page failing a different reader. Two changes close most of the
   gap, and both are about figures: a figure is short, so it does not need a
   whole row, and a figure is the picture, so it does not need one beside it. */

@media (max-width: 719px) {
  /* Two figures to a row. Eight indicators stacked one-per-row is a screen and
     a half of scrolling to read sixteen words. */
  .board2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .b2cell { padding: 14px 12px 13px; }
  .b2value { font-size: 25px; }
  .b2meta { display: none; }
  /* The period and source leave the cell on a phone and stay one tap away on
     the data page — dropping the *source* from a figure would break this
     publication's one promise, so the figure stays a link and the promise is
     kept where there is room to keep it. */

  .subjcard .pic { aspect-ratio: 2 / 1; }
  .subjcardlead .wtitle { font-size: 16px; }
}

/* ──────────────── 37 · THE DESK ────────────────
   The editing side. It shares this stylesheet on purpose — an editor who works
   here all day should not be looking at a worse-made page than the readers get,
   and a second design system is a second thing to keep true.

   What it does not share is the publication's furniture: no flag, no ticker, no
   bilingual pairing in the chrome. This is a tool, and a tool dressed as the
   thing it edits makes it easy to forget which one you are looking at — where
   the consequence of that confusion is publishing something. */

.adminbody { display: grid; grid-template-columns: minmax(0, 1fr); min-height: 100vh; background: var(--paper-2); }
@media (min-width: 900px) { .adminbody { grid-template-columns: 250px minmax(0, 1fr); } }

.adminnav {
  background: var(--ink-panel); color: var(--on-panel);
  padding: 20px 0 26px; display: flex; flex-direction: column; gap: 22px;
}
@media (min-width: 900px) { .adminnav { position: sticky; top: 0; height: 100vh; overflow-y: auto; } }
.adminmark { display: flex; align-items: center; gap: 10px; padding: 0 18px; text-decoration: none; color: inherit; }
.adminmark .wmimg { background-color: var(--on-panel); }
.adminmark .caps { color: var(--on-panel-quiet); }
.adminnav nav { display: flex; flex-direction: column; }
.navlabel { padding: 0 18px 7px; color: var(--on-panel-quiet); }
.adminnav nav a {
  display: grid; grid-template-columns: 26px 1fr auto; gap: 10px; align-items: baseline;
  padding: 9px 18px; text-decoration: none; color: var(--on-panel);
  font-family: var(--display); font-weight: 600; font-size: 14px; letter-spacing: var(--track-text);
  border-left: 3px solid transparent;
}
.adminnav nav a:hover { background: var(--ink-panel-2); }
.adminnav nav a[aria-current] { border-left-color: var(--red); background: var(--ink-panel-2); }
.navno, .navcount { font-family: var(--mono); font-size: 10px; letter-spacing: 0.06em; color: var(--on-panel-quiet); }
.adminwho { margin-top: auto; padding: 16px 18px 0; border-top: 1px solid rgba(255, 255, 255, 0.16); display: grid; gap: 4px; }
.adminwho b { font-size: 14px; }
.adminwho .caps { color: var(--on-panel-quiet); }
.adminwho .btnrow { margin-top: 10px; gap: 8px; }
.adminwho .btn { border-color: rgba(255, 255, 255, 0.4); color: var(--on-panel); }
.adminwho .btn:hover { background: var(--on-panel); color: var(--ink-panel); }

.adminmain { padding: var(--air-2) 22px var(--band); max-width: 1100px; }
.adminhead { display: flex; align-items: flex-end; justify-content: space-between; gap: 16px var(--gutter); flex-wrap: wrap; margin-bottom: var(--air); }
.adminhead h1 { margin: 0; font-size: clamp(26px, 3vw, 36px); }
.adminacts { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.adminsearch { display: flex; gap: 8px; }
.adminsearch input { padding: 8px 12px; border: 1.5px solid var(--line); background: var(--paper); color: inherit; font-family: var(--sans); border-radius: var(--radius); }

.flash { padding: 11px 15px; margin: 0 0 18px; font-size: 14.5px; border-left: 3px solid var(--blue); background: var(--paper); border-radius: var(--radius); }
.flash.bad { border-left-color: var(--red); }

.tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 1px; background: var(--line); margin-bottom: var(--band); }
.tile { display: grid; gap: 4px; padding: 16px 16px 18px; background: var(--paper); text-decoration: none; color: inherit; }
.tile:hover { background: var(--paper-3); }
.tile .caps { color: var(--muted); }
.tile b {
  font-family: var(--display); font-weight: 700; font-size: 34px; line-height: 1;
  letter-spacing: var(--track-display); font-stretch: var(--wide-fig); font-variant-numeric: tabular-nums;
}

/* The checks on the dashboard are the publication's own promises, not a generic
   score: a published item with no Afaan Oromoo headline breaks the front page,
   and an indicator with no period breaks the one line this masthead runs. */
.checks { list-style: none; margin: 0; padding: 0; }
/* Named chk-* rather than ok/warn/bad: `.ok` already means the forms'
   confirmation line, and inheriting it turned these teal at 3.49:1. */
.checks > li { border-top: 1px solid var(--line); padding: 12px 0 12px 16px; font-size: 14.5px; position: relative; }
.checks > li::before { content: ""; position: absolute; left: 0; top: 16px; width: 7px; height: 7px; border-radius: 50%; }
.checks > li.chk-ok::before { background: var(--blue); }
.checks > li.chk-warn::before { background: var(--muted); }
.checks > li.chk-bad::before { background: var(--red); }
.checks ul { margin: 6px 0 0; padding-left: 18px; font-size: 13.5px; }

.adminlist { background: var(--paper); }
.adminlist td, .adminlist th { padding: 10px 12px 10px 0; }
.adminlist td:first-child, .adminlist th:first-child { padding-left: 12px; }
.adminlist tbody tr:hover { background: var(--paper-2); }
.nowrap { white-space: nowrap; }
td.quiet { color: var(--muted); font-size: 13px; }
.pill { font-family: var(--mono); font-size: 9.5px; letter-spacing: 0.08em; text-transform: uppercase; padding: 3px 7px; border: 1px solid var(--line); border-radius: var(--radius); }
.pill.create { border-color: var(--blue); color: var(--blue); }
.pill.delete { border-color: var(--red); color: var(--red-text); }

/* The form. Two columns on a wide screen, and an Afaan Oromoo field sits
   against the English one it twins rather than in a block of its own — an
   editor writing both should see both, or the second one gets forgotten. */
.adminform { background: var(--paper); padding: 22px; border-radius: var(--radius-card); }
.fldgrid { display: grid; grid-template-columns: minmax(0, 1fr); gap: 16px var(--gutter); }
@media (min-width: 760px) { .fldgrid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.fld { display: grid; gap: 5px; align-content: start; }
.fld label { font-family: var(--mono); font-size: 10px; font-weight: 500; letter-spacing: var(--track-label); text-transform: uppercase; color: var(--muted); }
.fld input, .fld select, .fld textarea {
  font-family: var(--sans); font-size: 15px; padding: 10px 12px; border: 1.5px solid var(--line);
  background: var(--paper-2); color: inherit; border-radius: var(--radius); width: 100%;
}
.fld textarea { font-size: 14.5px; line-height: 1.5; resize: vertical; }
.fld input:focus, .fld select:focus, .fld textarea:focus { outline: none; border-color: var(--red); background: var(--paper); }
.fldcheck { grid-template-columns: auto 1fr; align-items: center; gap: 9px; }
.fldcheck input { width: 18px; height: 18px; padding: 0; }
.fldcheck label { order: 2; }
.fldom label { color: var(--red-text); }
.fldom input, .fldom textarea { border-left: 3px solid var(--red-wash); }
.fldint label { color: var(--ink-2); }
.fld .int { background: var(--ink); color: var(--paper); padding: 2px 6px; border-radius: 3px; }
.fldhelp { font-size: 12.5px; color: var(--muted); line-height: 1.4; }
.flderr { font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.05em; text-transform: uppercase; color: var(--red-text); }
.fld.bad input, .fld.bad select, .fld.bad textarea { border-color: var(--red); }
.formfoot { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; border-top: 1px solid var(--line); margin-top: 24px; padding-top: 18px; }
.dangerfold { margin-left: auto; }
.dangerfold > summary { cursor: pointer; color: var(--red-text); }
.dangerfold p { max-width: 42ch; margin: 8px 0; }

.signin { max-width: 380px; margin: 8vh auto; background: var(--paper); padding: 30px 28px 32px; border-radius: var(--radius-card); }
.signinmark { margin-bottom: 20px; }
.signin h1 { font-size: 27px; margin: 0 0 6px; }
.signinform { display: grid; gap: 14px; margin-top: 20px; }
.signinform label { display: grid; gap: 5px; font-family: var(--mono); font-size: 10px; letter-spacing: var(--track-label); text-transform: uppercase; color: var(--muted); }
.signinform input { font-family: var(--sans); font-size: 16px; padding: 11px 13px; border: 1.5px solid var(--line); background: var(--paper-2); color: inherit; border-radius: var(--radius); }
.signinform input:focus { outline: none; border-color: var(--red); background: var(--paper); }
.signinform button { margin-top: 4px; }

/* The door is open. Red, at the top of every page, because the worst version
   of a sign-in bypass is the one somebody forgot was on. */
.openwarn { background: var(--red); color: #fff; padding: 11px 15px; margin: 0 0 18px; font-size: 14px; border-radius: var(--radius); }
.openwarn b { font-weight: 700; }

/* The subject mark sits on the baseline of the label it belongs to, at the
   label's own colour — it is the same currentColor, so a mark on a red rule is
   red and a mark in a nav is whatever the nav is. */
.eyebrow { display: inline-flex; align-items: center; gap: 6px; }
.eyebrow .icon { flex: 0 0 auto; opacity: 0.85; }
.subjcaphead a { display: inline-flex; align-items: center; gap: 6px; }
.sectionmark { display: inline-flex; vertical-align: -3px; margin-right: 10px; color: var(--cat, var(--ink)); }
.adminnav .navno { display: inline-flex; align-items: center; justify-content: center; }
.adminnav .navno .icon { opacity: 0.75; }
.adminnav a[aria-current] .navno .icon { opacity: 1; }

/* A link to another story, inside a sentence. Deliberately quieter than a
   figure: a figure is a fact the desk stands behind and carries a red dot, a
   cross-link is only a suggestion that there is more to read. It is the link
   blue, underlined, and it does not interrupt. */
.crosslink { color: var(--link); text-decoration: none; border-bottom: 1px solid var(--link); padding-bottom: 1px; }
.crosslink:hover { color: var(--red-text); border-bottom-color: var(--red); }
.crosslink:focus-visible { outline: 2px solid var(--red); outline-offset: 2px; }

/* A state, at a glance. The dot carries the colour and the word carries the
   meaning: an editor who cannot tell the dots apart reads exactly the same
   thing, which is the only version of colour-coding worth shipping. */
.state { display: inline-flex; align-items: center; gap: 6px; font-family: var(--mono); font-size: 10px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-2); }
.state::before { content: ""; width: 7px; height: 7px; border-radius: 50%; flex: 0 0 auto; }
.state.live::before { background: var(--blue); }
.state.draft::before { background: var(--muted); }
.state.gone::before { background: var(--red); }
.rowacts { display: flex; gap: 12px; align-items: baseline; }
.rowacts a { text-decoration: none; color: var(--link); display: inline-flex; align-items: center; gap: 4px; }
.rowacts a:hover { color: var(--red-text); }
.crumb { display: block; color: var(--muted); margin-bottom: 4px; }
.crumb a { color: inherit; }
.adminhead .state { margin-top: 8px; }

/* ──────────────── 38 · THE DESK: CONTROLS ────────────────
   The pieces the readiness pass added: the save line, drafts, conflicts,
   history, the second step, deliveries. Same tokens, same restraint. */

.savestatus { font-family: var(--mono); font-size: 11px; letter-spacing: 0.04em; color: var(--muted); }
.savestatus[data-kind='dirty'] { color: var(--ink); }
.savestatus[data-kind='kept'] { color: var(--blue); }
.savestatus[data-kind='bad'] { color: var(--red-text); }
.draftnote .btnrow { margin-top: 8px; }
.draftnote form { display: inline; }
.plainset { border: 0; margin: 0; padding: 0; min-width: 0; }
.plainset:disabled input, .plainset:disabled select, .plainset:disabled textarea { opacity: 0.75; }
.fld input:disabled { background: transparent; border-style: dashed; }
.templates { display: flex; flex-wrap: wrap; gap: 8px 14px; align-items: baseline; margin: 0 0 12px; }
.templates a { font-family: var(--mono); font-size: 11px; letter-spacing: 0.04em; }
.prepub { background: var(--paper); border-left: 3px solid var(--muted); padding: 10px 15px; margin: 0 0 18px; border-radius: var(--radius); }
.prepub > summary { cursor: pointer; }
.prepub .checks { margin-top: 8px; }
.corrband { margin-top: var(--band); }
.corrlist { list-style: none; margin: 0 0 16px; padding: 0; }
.corrlist li { border-top: 1px solid var(--line); padding: 10px 0; font-size: 14.5px; }
.revision { background: var(--paper); border-radius: var(--radius-card); padding: 14px 18px; margin-bottom: 14px; }
.revhead { display: flex; flex-wrap: wrap; gap: 8px 14px; align-items: center; margin-bottom: 8px; }
.revhead form { margin-left: auto; }
.revdiff td { vertical-align: top; font-size: 13.5px; }
.revdiff del { color: var(--red-text); text-decoration: line-through; }
.revdiff ins { color: var(--blue); text-decoration: none; }
.qrbox { background: #fff; display: inline-block; padding: 6px; margin: 12px 0; border-radius: var(--radius); }
.qrbox svg { display: block; width: 220px; height: 220px; }
.secretkey { font-family: var(--mono); font-size: 13px; word-break: break-all; }
.recovery { columns: 2; font-family: var(--mono); font-size: 14px; margin: 14px 0 20px; }
.inlineform { display: flex; flex-wrap: wrap; gap: 10px; align-items: flex-end; margin: 10px 0; padding: 14px 18px; }
.inlineform .fld { min-width: 220px; }
.jobpreview { white-space: pre-wrap; font-family: var(--mono); font-size: 13px; background: var(--paper); border-left: 3px solid var(--blue); padding: 14px 16px; border-radius: var(--radius); max-width: 72ch; }
.jobpanel form { display: inline-flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.adminbare .adminmain { grid-column: 1 / -1; }
.adminsearch select { font: inherit; font-size: 13px; padding: 6px 8px; }

/* Partner content: the label in the same words and the same place on every
   card and page. Red rule, mono face — the same devices the advertising spaces
   use, because it is the same fact: someone paid. */
.partnertag {
  display: inline-flex; align-items: center; gap: 6px; align-self: flex-start;
  font-family: var(--mono); font-size: 9.5px; letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--ink); border: 1px solid var(--red); padding: 3px 7px; margin: 8px 0 4px;
}
.partnertag::before { content: ''; width: 6px; height: 6px; background: var(--red); transform: rotate(45deg); flex: none; }
.storyshot .caption { font-size: 13.5px; color: var(--muted); margin: 8px 0 0; max-width: 68ch; }
.reporterr { font-size: 13.5px; margin: 18px 0 0; }
.persongrid { display: grid; gap: var(--air-2) var(--gutter); }

/* ──────────────── 39 · PICTURES THE DESK UPLOADS ────────────────
   Portraits are square and all the same size — five by five — so the desk
   reads as a row of equals. Graphics are shown whole, never cropped. */

.portrait { display: block; width: 160px; height: 160px; aspect-ratio: 1 / 1; object-fit: cover; background: var(--paper-2); filter: grayscale(1) contrast(1.05); }
.seat .portrait { margin-bottom: 14px; }
.personhead { display: flex; gap: var(--gutter); align-items: center; flex-wrap: wrap; margin-bottom: var(--air); }
.personhead .portrait { width: 200px; height: 200px; }
.personhead .seatmark { width: 200px; height: 200px; font-size: 56px; }
.seat h3 a { color: inherit; text-decoration: none; }
.seat h3 a:hover { text-decoration: underline; }

.graphic { margin: 26px 0; padding: 14px 0 0; border-top: var(--rule) solid var(--ink); }
.graphic img { display: block; width: 100%; height: auto; background: #fff; }
.graphic figcaption { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 6px 18px; font-size: 13.5px; color: var(--muted); margin-top: 8px; }
.graphic .gsrc { font-family: var(--mono); font-size: 11px; letter-spacing: 0.04em; }

.fldimage { grid-column: 1 / -1; }
.imgpreview { background: var(--paper-2); border: 1.5px dashed var(--line); display: grid; place-items: center; overflow: hidden; border-radius: var(--radius); }
.imgpreview.wide { aspect-ratio: 16 / 9; max-width: 480px; }
.imgpreview.square { aspect-ratio: 1 / 1; width: 200px; }
.imgpreview img { width: 100%; height: 100%; object-fit: contain; }
.imgpreview.square img { object-fit: cover; }
.imgempty { font-family: var(--mono); font-size: 11px; color: var(--muted); letter-spacing: 0.06em; text-transform: uppercase; }
.imgacts { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; margin-top: 8px; }
.imgacts input[type=file] { font-size: 13px; max-width: 100%; }
.imgstatus { font-family: var(--mono); font-size: 11px; color: var(--muted); }
.imgstatus[data-kind='bad'] { color: var(--red-text); }
.imgstatus[data-kind='ok'] { color: var(--blue); }
.unusedmedia { list-style: none; margin: 0; padding: 0; }
.unusedmedia li { display: flex; gap: 14px; align-items: center; border-top: 1px solid var(--line); padding: 10px 0; font-size: 13.5px; }
.unusedmedia img { width: 96px; height: auto; background: var(--paper-2); }
.unusedmedia form { margin-left: auto; }
/* Where there is no portrait, the initials take the same square, so every seat
   on the desk is the same size whether or not it has a photograph yet. */
.seat .seatmark { width: 160px; height: 160px; border-radius: 0; font-size: 44px; margin-bottom: 14px; }

/* ──────────────── 40 · TEXT TO ITS SPACE ────────────────
   Each card's text is cut to its slot on the server (lib/fit.mjs), at a
   sentence where it can be. These clamps are the safety net under that — a
   text that somehow arrives longer is held to the slot rather than allowed to
   stretch its row — and they never apply on the article itself. */

.third p, .second p { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 9; overflow: hidden; }
.herosum { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 10; overflow: hidden; }
.wsum { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 9; overflow: hidden; }
.third h3, .second h3 { overflow-wrap: break-word; hyphens: auto; }

/* An indicator's label wraps rather than being cut off on a phone. */
.rlabel { white-space: normal; overflow: visible; text-overflow: clip; }

.fldcount { font-family: var(--mono); font-size: 10.5px; color: var(--muted); justify-self: end; }
.fldcount[data-kind='near'] { color: var(--ink); }
.fldcount[data-kind='full'] { color: var(--red-text); font-weight: 600; }

/* The word of the week's column: three more defined words beneath it. */
.morewords { list-style: none; margin: 14px 0 0; padding: 0; }
.morewords li { border-top: 1px solid var(--line); }
.morewords a { display: block; padding: 10px 0; text-decoration: none; color: inherit; }
.morewords b { font-family: var(--display); font-size: 15px; }
.morewords span { display: block; font-size: 13.5px; color: var(--muted); margin-top: 2px; }
.morewords a:hover b { color: var(--red-text); }
/* The cover is a picture of a cover, not a poster: held to a size that sits
   beside a diary rather than towering over it. */
.threeup .cover { max-width: 300px; }
/* A figure waiting for its history. */
.sparse { margin-top: var(--air-2); border-top: var(--rule) solid var(--ink); padding-top: 12px; display: grid; gap: 4px; }
.sparse > .caps { color: var(--muted); }
.sparserow { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 18px; padding: 10px 0; border-bottom: 1px solid var(--line); }
.sparserow b { font-family: var(--display); font-size: 17px; }
.sparsevalue { font-family: var(--display); font-weight: 700; font-size: 22px; color: var(--red); font-variant-numeric: tabular-nums lining-nums; }
.subjcardlead .wsum { display: block; font-size: 14px; color: var(--muted); margin-top: 6px; }
/* The Afaan Oromoo edition carries half as much text again for the same
   sense (lib/fit.mjs), so its safety clamps give it half as many lines again
   rather than cutting off what it was allowed to say. */
html[lang='om'] .third p, html[lang='om'] .second p { -webkit-line-clamp: 14; }
html[lang='om'] .herosum { -webkit-line-clamp: 15; }
html[lang='om'] .wsum { -webkit-line-clamp: 14; }
.seat .seatcall { font-size: 13.5px; color: var(--muted); }
.seat .seatcall a { color: inherit; }
.fldcount[data-kind='near'] { color: #9a6200; }

/* The fly title, as The Economist sets it: two or three words of subject
   above the headline, in the accent, smaller than the headline and quieter
   than a label. */
.flytitle { font-family: var(--display); font-weight: 700; font-size: 15px; letter-spacing: var(--track-text); color: var(--red-text); margin: 14px 0 -4px; }

/* ──────────────── 41 · THE LEAD IN TURN, AND ADVERTISERS' ARTWORK ──────────────── */

/* The slides share one grid cell: the lead keeps the height of its tallest
   story, and the page below never moves when the story changes. */
.rotslides { display: grid; }
.rotslide { grid-area: 1 / 1; min-width: 0; }
.rotator.rotating .rotslide[hidden] { display: block; visibility: hidden; }
@media (prefers-reduced-motion: no-preference) {
  .rotator.rotating .rotslide:not([hidden]) { animation: rotin 0.35s ease; }
  @keyframes rotin { from { opacity: 0; } to { opacity: 1; } }
}
.rotbar { display: flex; align-items: center; justify-content: flex-end; gap: 6px; margin: 0 0 8px; }
.rotbtn {
  display: inline-flex; align-items: center; justify-content: center; width: 32px; height: 32px;
  border: 1px solid var(--line); background: transparent; color: inherit; cursor: pointer; border-radius: var(--radius);
}
.rotbtn:hover { border-color: var(--ink); }
.rotprev svg { transform: scaleX(-1); }
.rotplay .ifpaused { display: none; }
.rotplay[data-state='paused'] .ifplaying { display: none; }
.rotplay[data-state='paused'] .ifpaused { display: inline-flex; }
.rotdots { display: flex; gap: 2px; }
.rotdot {
  position: relative; border: 0; background: transparent; cursor: pointer; padding: 8px 6px 10px;
  font-family: var(--mono); font-size: 11px; letter-spacing: 0.06em; color: var(--muted);
}
.rotdot[aria-current] { color: var(--ink); font-weight: 700; }
.rotdot::after { content: ''; position: absolute; left: 6px; right: 6px; bottom: 4px; height: 2px; background: var(--line); }
.rotdot[aria-current]::after { background: var(--red); transform-origin: left; }
@media (prefers-reduced-motion: no-preference) {
  .rotator[data-playing='yes'] .rotdot[aria-current].fill::after { animation: rotfill 7s linear; }
  @keyframes rotfill { from { transform: scaleX(0); } to { transform: scaleX(1); } }
}

/* An advertiser's artwork: their image at its booked size, centred in the
   space, with the label above and their name beneath — never mistakable for a
   story card. */
.adspace.hascreative { align-items: center; text-align: center; gap: 10px; }
.adspace.hascreative .adlabel { align-self: flex-start; }
.adcreative { display: block; line-height: 0; margin: auto 0; }
.adcreative img { max-width: 100%; height: auto; display: block; }
.adby { font-size: 11px; color: var(--muted); }
.adpause {
  font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.06em; text-transform: uppercase;
  border: 1px solid var(--line); background: transparent; color: inherit; padding: 5px 10px; cursor: pointer;
}

/* ──────────────── 42 · STRUCTURE INSIDE A STORY ────────────────
   What lib/body.mjs lets a writer make: a crosshead, a pull quote, a list, a
   link. Sized from the running text, never louder than the headline. */
.storybody .crosshead {
  font-family: var(--display); font-weight: 700; font-size: clamp(19px, 2vw, 22px); line-height: 1.25;
  letter-spacing: var(--track-text); margin: 1.6em 0 0.4em;
}
.storybody .pullquote {
  margin: 1.4em 0; padding: 4px 0 4px 18px; border-left: 3px solid var(--red);
  font-family: var(--display); font-weight: 700; font-size: clamp(19px, 2.2vw, 24px); line-height: 1.3;
}
.storybody .pullquote p { margin: 0; }
.storybody .storylist { margin: 0.8em 0 1em; padding-left: 1.2em; }
.storybody .storylist li { margin: 0.35em 0; }
.storybody p a, .storybody li a, .storybody .crosshead a { color: inherit; text-decoration: underline; text-decoration-color: var(--red); text-underline-offset: 3px; }
.storylegal { margin: 6px 0 14px; font-size: 12.5px; color: var(--muted); line-height: 1.5; }
.storyreply { border-left: 3px solid var(--ink); padding-left: 10px; }
.replyreq { border-top: 1px solid var(--line); padding: 14px 0; }
.replyreq.overdue { border-left: 4px solid var(--red); padding-left: 12px; }
.replyreq blockquote { margin: 8px 0; padding: 8px 12px; background: var(--paper-2); white-space: pre-wrap; }
.inlineform { display: inline-flex; gap: 6px; align-items: center; }
.inlineform input { min-width: 260px; }
.choice { display: block; margin: 4px 0; font-weight: 400; text-transform: none; letter-spacing: 0; }
.storydoc { margin: 10px 0 0; font-size: 14.5px; }
.storydoc a { font-weight: 700; color: inherit; text-decoration: underline; text-decoration-color: var(--red); text-underline-offset: 3px; }
.storydoc .caps { margin-left: 6px; color: var(--muted); }
.previewbar {
  margin: 0; padding: 10px 16px; text-align: center; background: var(--ink); color: var(--paper);
  font-family: var(--mono); font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase;
}

/* ──────────────── 43 · SUGGESTIONS AS YOU TYPE ────────────────
   Under the search box, the full width of its form. Every row is a touch
   target of 44 px or more; the kind sits left in small capitals, the other
   edition's title under it. */
.hassuggest { position: relative; }
.suggest {
  position: absolute; left: 0; right: 0; top: 100%; z-index: 60; margin: 4px 0 0; padding: 4px 0; list-style: none;
  background: var(--paper); color: var(--ink); border: 1px solid var(--line); box-shadow: 0 10px 28px rgba(0, 0, 0, 0.14);
  max-height: min(60vh, 440px); overflow-y: auto; overscroll-behavior: contain;
}
.sug { display: grid; grid-template-columns: minmax(64px, auto) minmax(0, 1fr); gap: 2px 12px; align-items: baseline; padding: 10px 14px; min-height: 44px; cursor: pointer; }
.sug[aria-selected="true"], .sug:hover { background: var(--paper-2); }
.sugkind { font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted); }
.suglabel { font-weight: 600; line-height: 1.3; overflow-wrap: anywhere; }
.sugother { grid-column: 2; font-size: 12.5px; color: var(--muted); }
.sugfix .sugkind { color: var(--red-text); }
.sugfix .suglabel { font-style: italic; }
.didyoumean { margin: 6px 0 0; font-size: 15px; }
.didyoumean a b { color: var(--red-text); }

/* ──────────────── 44 · EVERY SCREEN, EVERY FINGER ────────────────
   From the 20-device run (scripts/layout.mjs): a folded Galaxy Fold at 280 px
   to a QHD monitor, touch emulated below 1280. WCAG 2.2, 2.5.8: a control is
   at least 24 × 24 px, or its label is the target. */
.navlinks a { display: inline-block; padding-top: 5px; padding-bottom: 5px; }
input[type="checkbox"], input[type="radio"] { width: 20px; height: 20px; flex: 0 0 auto; margin: 2px 8px 0 0; accent-color: var(--red); }
.choice { display: flex; align-items: flex-start; gap: 0; min-height: 28px; }
/* The page plan scrolls inside itself rather than squeezing 32 pages into a
   narrow screen, where each page was a 9–16 px sliver nobody could tap. Every
   page is at least 24 px; where they fit, they share the width as before. */
.planwrap, .planbar { min-width: 0; max-width: 100%; }
.issuehead > * { min-width: 0; }
.planbar { overflow-x: auto; overscroll-behavior-x: contain; padding-bottom: 6px; }
.planbar .planseg { flex: 1 0 24px; min-width: 24px; }
@media (max-width: 340px) {
  /* A folded Fold: the figures step down a size so "US$10.7bn" fits its cell. */
  .numbers .rvalue { font-size: 18px; }
  .rvalue { font-size: 18px; }
}
/* A label in a rail wraps rather than losing its last word. */
.rrlabel { white-space: normal; overflow: visible; text-overflow: clip; overflow-wrap: anywhere; }
.selectfind { display: block; width: 100%; margin: 0 0 6px; font-size: 14px; padding: 8px 10px; min-height: 36px; }
.selectfindstatus { display: block; font-size: 12px; color: var(--muted); min-height: 1em; }
/* An open seat holds less than a filled one; its invitation sits at the foot
   of the card so the row reads level with its neighbours. */
.seat.open { display: flex; flex-direction: column; }
.seat.open .seatcall { margin-top: auto; padding-top: 12px; }

/* ──────────────── 45 · THE NUMBERS, TO WORK WITH ──────────────── */
.converter { max-width: 46rem; margin: var(--air-2) 0 0; padding: 14px 16px; background: var(--paper-2); border-radius: var(--radius-card); display: grid; gap: 8px; }
.convrow { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.convrow input { flex: 1 1 110px; min-width: 0; font: inherit; font-size: 16px; padding: 9px 12px; min-height: 44px; border: 1.5px solid var(--line); border-radius: var(--radius); background: var(--paper); color: inherit; font-variant-numeric: tabular-nums; }
.convrow select { flex: 1 1 170px; min-width: 0; font: inherit; font-size: 16px; padding: 9px 10px; min-height: 44px; border: 1.5px solid var(--line); border-radius: var(--radius); background: var(--paper); color: inherit; }
.convrow .btn { min-height: 44px; }
.convanswer { margin: 2px 0 0; font-size: 19px; line-height: 1.3; }
.convanswer b { font-variant-numeric: tabular-nums; }
.convanswer span { display: block; font-family: var(--mono); font-size: 11px; color: var(--muted); margin-top: 3px; }
.converter .fignote { margin: 0; }
.figdl { margin: 10px 0 0; font-family: var(--mono); font-size: 11.5px; letter-spacing: 0.02em; }
.figdl a { display: inline-block; padding: 6px 0; }

/* ──────────────── 46 · THE READER'S SIDE, AFTER THE OCTOBER REVIEW ──────────────── */

/* Anything a script reveals is hidden until it does, whatever else the
   element's class says about how it is displayed. */
[hidden] { display: none !important; }
.rotator.rotating .rotslide[hidden] { display: block !important; visibility: hidden; }

/* A link to a part of a page lands just below the masthead, which stays at
   the top of the window; it used to land underneath it. The script measures
   the masthead; without it, a height that fits the tallest (three rows, on a
   phone) is assumed. */
html { scroll-padding-top: calc(var(--head-h, 132px) + 12px); }
.svcband { scroll-margin-top: 0; }
:target { scroll-margin-top: 4px; }
.figblock:target, .sparserow:target, .third:target { outline: 2px solid var(--red); outline-offset: 6px; }

/* A band's title, whatever heading it is: the page's own (h1), a band's (h2),
   or a label above the page's headline (p). */
.sechead .sectitle {
  font-family: var(--display); font-weight: 700; line-height: 1.1; text-wrap: balance;
  font-size: var(--h-section); letter-spacing: var(--track-section); margin: 0; font-stretch: var(--wide-head);
}
.sechead .sectitle .om { font-size: inherit; }
.svcband .sechead .sectitle { display: flex; align-items: baseline; gap: 12px; }
.slab.dark .sechead .sectitle { color: var(--on-panel); }
.corrections .corrhead { margin: 0 0 6px; font-size: 15px; letter-spacing: var(--track-text); }

/* Sixteen pixels in every field a reader types into: an iPhone zooms the
   whole page when a smaller one takes focus, and does not zoom back. */
input, select, textarea { font-size: 16px; }

/* What a form says back. In the dark theme the two colours used to fall
   under 4.5:1 on black; each now has a text shade for it. */
:root { --teal-text: #0b7a6b; }
:root[data-theme='dark'] { --teal-text: #4cc9b4; }
@media (prefers-color-scheme: dark) { :root:not([data-theme='light']) { --teal-text: #4cc9b4; } }
.err { color: var(--red-text); border-left-color: var(--red); font-size: 15px; }
.ok { color: var(--teal-text); font-size: 15px; }
.receipt { scroll-margin-top: 8px; }

/* The ticker moves only once the script has switched it on, and has a button
   that stops it — on a phone there is nothing to hover with. With no script,
   or for a reader who asked for less motion, it is one row that scrolls by
   hand, and its copy is not there. */
.tickerwrap { position: relative; }
.tickerwrap:not([data-ticker='on']) { overflow-x: auto; }
.tickerwrap:not([data-ticker='on']) .tickrail { animation: none; }
.tickrow[data-tick-copy] { display: none; }
.tickerwrap[data-ticker='on'] .tickrow[data-tick-copy] { display: flex; }
.tickerwrap[data-ticker='on'] { padding-right: 46px; }
.tickpause {
  position: absolute; top: 0; right: 0; bottom: 0; z-index: 2; width: 46px; min-height: 24px;
  border: 0; border-left: 1px solid var(--line); background: var(--paper-2); color: var(--ink);
  font-size: 11px; line-height: 1; cursor: pointer; display: grid; place-items: center;
}
.tickpause:focus-visible { outline: 2px solid var(--link); outline-offset: -3px; }
.tickpause .ifheld, .tickpause[aria-pressed='true'] .ifrun { display: none; }
.tickpause[aria-pressed='true'] .ifheld { display: inline; }

/* The reader's own tools: save for later, the size of the text, the parts of
   a long piece, and the stories either side of this one. */
.savebtn .ifidle, .savebtn .ifdone { align-items: center; gap: 7px; }
.savebtn .ifidle { display: inline-flex; }
.savebtn .ifdone { display: none; }
.savebtn[data-state='done'] .ifidle { display: none; }
.savebtn[data-state='done'] .ifdone { display: inline-flex; }
.savebtn[aria-pressed='true'] { border-color: var(--ink); }
.savedlist { list-style: none; margin: var(--air) 0; padding: 0; max-width: 46rem; }
.savedlist li { display: grid; grid-template-columns: minmax(0, 1fr) auto auto; gap: 6px 14px; align-items: center; padding: 14px 0; border-top: 1px solid var(--line); }
.savedlist li.note { display: block; border-top: 0; padding: 0; }
.savedlist a { font-family: var(--display); font-weight: 700; font-size: 18px; line-height: 1.25; text-decoration: none; overflow-wrap: anywhere; }
.savedlist a:hover { text-decoration: underline; text-underline-offset: 3px; }
@media (max-width: 520px) { .savedlist li { grid-template-columns: minmax(0, 1fr) auto; } .savedlist li a { grid-column: 1 / -1; } }

.textsize { margin-left: auto; min-width: 44px; justify-content: center; font-family: var(--display); font-weight: 700; }
.textsize sup { font-size: 0.7em; }
html[data-text='large'] .storybody > p:not([class]), html[data-text='large'] .storybody .storylist li, html[data-text='large'] .storybody .keypoints li { font-size: 19px; line-height: 1.6; }
html[data-text='large'] .storybody > p.lead { font-size: 20.5px; }
html[data-text='larger'] .storybody > p:not([class]), html[data-text='larger'] .storybody .storylist li, html[data-text='larger'] .storybody .keypoints li { font-size: 22px; line-height: 1.6; }
html[data-text='larger'] .storybody > p.lead { font-size: 23.5px; }

.keypoints { margin: 0 0 22px; padding: 16px 18px 14px; background: var(--paper-2); border-left: 3px solid var(--cat, var(--red)); border-radius: 0 var(--radius-card) var(--radius-card) 0; }
.keypoints h2 { margin: 0 0 8px; font-family: var(--mono); font-size: 10.5px; font-weight: 500; letter-spacing: var(--track-label); color: var(--muted); }
.keypoints ul { margin: 0; padding-left: 18px; display: grid; gap: 6px; }
.keypoints li { font-size: 16px; line-height: 1.45; }
.storytoc { margin: 6px 0 22px; padding: 12px 0; border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }
.storytoc h2 { margin: 0 0 6px; font-family: var(--mono); font-size: 10.5px; font-weight: 500; letter-spacing: var(--track-label); color: var(--muted); }
.storytoc ol { margin: 0; padding-left: 22px; display: grid; gap: 2px; }
.storytoc a { display: inline-block; padding: 4px 0; text-underline-offset: 3px; }
.storynext { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--gutter); margin: 26px 0 0; padding-top: 16px; border-top: 2px solid var(--ink); }
.storynext a { display: grid; gap: 4px; text-decoration: none; min-width: 0; }
.storynext a.right { text-align: right; }
.storynext a b { font-family: var(--display); font-size: 16px; line-height: 1.25; overflow-wrap: anywhere; }
.storynext a:hover b { text-decoration: underline; text-underline-offset: 3px; }
@media (max-width: 520px) { .storynext { grid-template-columns: minmax(0, 1fr); } .storynext a.right { text-align: left; } }
.filternote b { color: var(--ink); }

/* One word of the glossary, and the archive by the Ethiopian calendar. */
.termpage h1 { margin-top: 10px; }
.termdefs { max-width: 46rem; }
.termdefs .om-text { font-size: 17px; }
.termexample { display: block; margin-top: 10px; }
.archivemonths { list-style: none; margin: 10px 0 var(--air-2); padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 250px), 1fr)); gap: 12px; }
.archivemonths li { background: var(--paper); padding: 14px 16px; display: grid; gap: 6px; align-content: start; border: 1px solid var(--line); border-radius: var(--radius-card); }
.archivemonths a { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 2px 10px; text-decoration: none; }
.archivemonths a b { font-family: var(--display); font-size: 18px; }
.archivemonths a .caps { grid-column: 1; color: var(--muted); }
.archivecount { grid-row: 1 / span 2; grid-column: 2; align-self: center; font-family: var(--display); font-weight: 700; font-size: 26px; font-variant-numeric: tabular-nums; color: var(--red-text); }
.archivemonths a:hover b { text-decoration: underline; text-underline-offset: 3px; }
.archivecats { font-size: 12.5px; color: var(--muted); }
.yearhead .caps { margin-left: 8px; color: var(--muted); font-weight: 500; }

/* On paper: the story, its figures, its sources — and nothing that is only
   furniture on a screen. People print a story for a credit committee or a
   board pack; it should arrive as a document. */
@media print {
  .flag, .sitehead, .footground, .tickerwrap, .storyrail, .share, .storynext, .totop, .progress, .skip, .reporterr, .textsize, .adspace, [data-ad], .pager, .rotbar, .searchbar, .sectionrow, .btnrow { display: none !important; }
  html, body { background: #fff !important; color: #000 !important; }
  body { font-size: 11.5pt; }
  .wrap, .storygrid, .storybody { display: block !important; max-width: none !important; width: auto !important; margin: 0 !important; padding: 0 !important; }
  .storybody h1 { font-size: 22pt; }
  .storybody > p, .storybody li { font-size: 11.5pt !important; line-height: 1.45 !important; orphans: 3; widows: 3; }
  .crosshead, .keypoints, .storytoc, figure, .corrections { break-inside: avoid; }
  .crosshead { break-after: avoid; }
  .storyshot img, .pic img { max-height: 90mm; object-fit: contain; }
  a { color: inherit !important; text-decoration: none !important; }
  /* Where a link in the story goes, printed after it: paper cannot be clicked. */
  .storybody > p a[href^='http']::after, .storybody li a[href^='http']::after { content: ' (' attr(href) ')'; font-size: 9pt; word-break: break-all; }
  .storygrid ~ .band { display: none; }
  @page { margin: 16mm 15mm; }
}

/* ──────────────── 47 · THE NUMBERS, AS A DESK TO WORK AT ────────────────
   A dashboard's arrangement in the publication's own hand: one face, cards on
   paper with a hairline, blue for the data and only the data (the bars, the
   chart, the gauge's arc), red for the latest reading and the one button
   that is Ensight's. A pale wash of the red sits behind the head; red itself
   stays under a twentieth of the screen, as the manual sets it. */
.dash .band { margin-bottom: var(--air-2); }
.dashtop { margin-top: 14px; }
.dashhero {
  border: 1px solid var(--line); border-radius: 22px; padding: clamp(16px, 3vw, 34px);
  background:
    radial-gradient(44% 72% at 60% 26%, var(--red-wash), transparent 72%),
    radial-gradient(30% 50% at 84% 78%, var(--red-wash), transparent 70%),
    var(--paper-2);
}
.dashhead { display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: space-between; gap: 18px 28px; }
.dashhead > div { min-width: 0; flex: 1 1 320px; }
.dashtitle { font-size: clamp(34px, 5vw, 58px); margin: 0 0 8px; }
.dashlead { font-size: 16.5px; line-height: 1.45; color: var(--ink-2); max-width: 48ch; margin: 0; }
.dashasof { display: inline-flex; align-items: center; gap: 7px; flex-wrap: wrap; margin: 12px 0 0; color: var(--muted); }
.dashacts { display: flex; flex-wrap: wrap; gap: 8px; justify-content: flex-end; flex: 1 1 380px; max-width: 640px; }
.dpill {
  display: inline-flex; align-items: center; gap: 7px; min-height: 40px; padding: 8px 15px;
  border-radius: 999px; border: 1px solid var(--line); background: var(--paper); color: var(--ink);
  font-size: 13.5px; font-weight: 600; text-decoration: none; white-space: nowrap;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
}
.dpill:hover { border-color: var(--ink); }
.dpill:focus-visible, .dmore:focus-visible, .dchoose a:focus-visible, .dtag.link:focus-visible { outline: 2px solid var(--link); outline-offset: 2px; }
.dpill.red { background: var(--red); border-color: var(--red); color: #fff; }
.dpill.red:hover { background: var(--red-2); border-color: var(--red-2); }
@media (max-width: 700px) { .dashacts { justify-content: flex-start; } }

.dcard {
  background: var(--paper); border: 1px solid var(--line); border-radius: 18px; padding: 18px 20px 20px; min-width: 0;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04), 0 10px 28px rgba(0, 0, 0, 0.05);
}
.dcardhead { font-size: 18px; margin: 0; }
.dcardtop { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin-bottom: 10px; }
.dcardnote { font-family: var(--mono); font-size: 11px; letter-spacing: 0.03em; color: var(--muted); margin: 0; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.dashrow2 { display: grid; grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr); gap: 16px; margin-top: 22px; align-items: stretch; }
@media (max-width: 860px) { .dashrow2 { grid-template-columns: minmax(0, 1fr); } }
.dash .converter { max-width: none; margin: 0; padding: 18px 20px 20px; background: var(--paper); border-radius: 18px; display: grid; gap: 10px; align-content: start; }
.dash .converter .convanswer { font-size: clamp(19px, 2.4vw, 26px); font-family: var(--display); margin: 2px 0 0; overflow-wrap: anywhere; }

.convquick { list-style: none; margin: 2px 0 0; padding: 0; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 18px; }
.convquick a { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; min-height: 34px; padding: 7px 0; border-top: 1px solid var(--line); text-decoration: none; font-size: 13.5px; font-variant-numeric: tabular-nums; }
.convquick a span { color: var(--ink-2); }
.convquick a b { font-weight: 600; text-align: right; overflow-wrap: anywhere; }
.convquick a:hover b { text-decoration: underline; text-underline-offset: 3px; }
@media (max-width: 520px) { .convquick { grid-template-columns: minmax(0, 1fr); } }

/* The gauge: a half circle that fills, with what it measures in its middle. */
.dgauge { display: grid; gap: 8px; align-content: start; }
.dgaugearc { position: relative; width: min(100%, 250px); margin: 2px auto 0; }
.dgaugearc svg { display: block; width: 100%; height: auto; }
.dgaugearc path { fill: none; stroke-width: 14; stroke-linecap: round; }
.dgaugearc .track { stroke: var(--paper-3); }
.dgaugearc .fill { stroke: var(--blue); }
.dgaugesay { position: absolute; left: 0; right: 0; bottom: 0; display: grid; justify-items: center; gap: 2px; text-align: center; }
.dgaugesay b { font-family: var(--display); font-stretch: var(--wide-fig); font-size: 36px; line-height: 1; font-variant-numeric: tabular-nums; }
.dgaugesay span { font-size: 11.5px; line-height: 1.25; color: var(--muted); max-width: 150px; }
.dgaugenote { justify-content: center; text-align: center; }
.dsources { list-style: none; margin: 4px 0 0; padding: 10px 12px; background: var(--paper-2); border-radius: 12px; display: grid; gap: 7px; }
.dsources li { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; font-size: 13px; }
.dsources li > span:first-child { min-width: 0; overflow-wrap: anywhere; }
.dtag {
  display: inline-flex; align-items: center; min-height: 22px; padding: 2px 8px; border: 1px solid var(--line); border-radius: 6px;
  background: var(--paper); color: var(--ink-2); font-family: var(--mono); font-size: 10px; letter-spacing: 0.06em; text-transform: uppercase; white-space: nowrap;
}
.dtag.now { color: var(--blue); border-color: currentColor; }
.dtag.then { color: var(--muted); }
.dtag.link { min-height: 28px; text-decoration: none; color: var(--ink); }
.dtag.link:hover { border-color: var(--ink); }

/* The tiles: every figure, each with its whole statement. */
.dtiles { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 14px; }
@media (max-width: 1000px) { .dtiles { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 420px) { .dtiles { grid-template-columns: minmax(0, 1fr); } }
.dtile {
  background: var(--paper); border: 1px solid var(--line); border-radius: 16px; padding: 15px 16px 13px; min-width: 0;
  display: grid; gap: 6px; align-content: start; box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04);
}
.dtile.on { border-color: var(--ink); }
.dtile:target { outline: 2px solid var(--red); outline-offset: 4px; }
.dtilehead { display: flex; align-items: flex-start; justify-content: space-between; gap: 8px; }
.dlabel { font-family: var(--sans); font-stretch: normal; font-weight: 500; font-size: 13.5px; line-height: 1.3; letter-spacing: 0; color: var(--ink-2); margin: 0; min-width: 0; overflow-wrap: anywhere; }
.dmore { flex: 0 0 auto; display: inline-grid; place-items: center; width: 30px; height: 30px; margin: -5px -6px 0 0; border: 1px solid transparent; border-radius: 8px; color: var(--muted); }
.dmore:hover { border-color: var(--line); color: var(--ink); }
.dvalrow { display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 10px; }
.dvalue { font-family: var(--display); font-stretch: var(--wide-fig); font-weight: 700; font-size: clamp(26px, 2.5vw, 34px); line-height: 1.05; font-variant-numeric: tabular-nums lining-nums; overflow-wrap: anywhere; }
.dperiod { font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.05em; text-transform: uppercase; color: var(--muted); margin: 0; }
.dbars { display: block; width: 100%; height: 38px; margin-top: 6px; }
.dbars rect { fill: var(--blue); }
.dbars rect.last { fill: var(--red); }
.dbars rect.ghost { fill: var(--paper-3); }
.dbars.none { border-bottom: 3px solid var(--paper-3); }
.dsource { font-size: 11.5px; line-height: 1.35; color: var(--muted); margin: 4px 0 0; padding-top: 8px; border-top: 1px solid var(--line); }

/* One figure opened up, and what changed last. */
.dashrow3 { display: grid; grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr); gap: 16px; align-items: start; }
@media (max-width: 1000px) { .dashrow3 { grid-template-columns: minmax(0, 1fr); } }
.dchoose { display: flex; flex-wrap: wrap; gap: 6px; margin: 0 0 14px; }
.dchoose a { display: inline-flex; align-items: center; min-height: 30px; padding: 4px 11px; border: 1px solid var(--line); border-radius: 999px; font-size: 12.5px; text-decoration: none; color: var(--ink); background: var(--paper); }
.dchoose a:hover { border-color: var(--ink); }
.dchoose a[aria-current] { background: var(--ink); border-color: var(--ink); color: var(--paper); }
.ddetail .figblock { background: transparent; padding: 0; margin: 0; }
.ddetail .figblock table.plain { background: transparent; }
.dscroll { overflow-x: auto; overscroll-behavior-x: contain; }
.dtable td { vertical-align: top; }
.dtable a { font-weight: 600; text-decoration: none; }
.dtable a:hover { text-decoration: underline; text-underline-offset: 3px; }
.dfrom { display: block; font-size: 11.5px; color: var(--muted); margin-top: 1px; }
@media (prefers-color-scheme: dark) { :root:not([data-theme='light']) .dcard, :root:not([data-theme='light']) .dtile, :root:not([data-theme='light']) .dpill { box-shadow: none; } }
:root[data-theme='dark'] .dcard, :root[data-theme='dark'] .dtile, :root[data-theme='dark'] .dpill { box-shadow: none; }

/* ─── 48 · Coming soon ──────────────────────────────────────────────────
   Before the first issue and the first film, the pages keep their shape and
   leave the content blank: a cover with no number, contents with no lines
   written, frames with no film. Blank is drawn in the paper tones, never in a
   brand colour, so nothing reads as a thing that exists. */
.cover.soon { background: var(--paper-2); color: var(--ink); border: 1px solid var(--line); }
.cover.soon .covertop .caps, .cover.soon .coverfoot .caps { color: var(--muted); opacity: 1; }
.cover.soon .coverfoot { border-top-color: var(--line); }
.coverblank { display: block; height: 14px; width: 82%; background: var(--paper-3); border-radius: 2px; }
.coverblank.no { height: clamp(64px, 9vw, 112px); width: 46%; margin: 6px 0 6px; }
.coverblank.short { width: 54%; }
.planbar.soon { pointer-events: none; }
.planbar.soon .planseg { height: 64px; cursor: default; }
.blankline { display: block; height: 12px; max-width: 100%; background: var(--paper-3); border-radius: 2px; margin: 6px 0; }
.blankplan td { height: 46px; }
.vcard.blank .vposter { background: var(--paper-2); color: var(--muted); border: 1px solid var(--line); opacity: 1; }
.vcard.blank .vlabel { opacity: 1; }
.diaryempty { border-top: 1px solid var(--line); padding-top: 12px; }
/* A blank cover at full column width is a large grey box; at book size it
   reads as a magazine waiting to be printed. */
.issuehead.soon .issueside { width: 100%; max-width: 340px; justify-self: center; }
@media (max-width: 720px) { .issuehead.soon .issueside { max-width: 260px; } }

/* ─── 49 · A term, in Ethiopia ──────────────────────────────────────────
   The context note under a glossary definition: a rule above, a label, then
   the note in the edition's language and its twin. */
.termcontext { margin-top: var(--air); padding-top: 14px; border-top: 1px solid var(--line); max-width: 46rem; }
.termcontext h2 { margin: 0 0 8px; color: var(--red-text); font-size: 11px; }
.termcontext p { margin: 0 0 10px; }

/* ─── 50 · Glossary cards end level ──────────────────────────────────────
   Definitions differ in length; the examples sit at the foot of each card so
   a row of terms finishes on one line. */
.news .termcard { display: flex; flex-direction: column; }
.termcard .termfoot { margin-top: auto; padding-top: 10px; }

/* The Amharic edition is built but not published: every page says so. */
.draftbar { margin: 0; padding: 8px var(--gutter, 16px); background: var(--ink, #0a0a0a); color: #fff; font-size: 13px; line-height: 1.5; text-align: center; }
.draftbar span { opacity: .75; }

/* Forms: a field the server turned down, and a button while the form is on its way. */
.form [aria-invalid="true"] { border-color: var(--red); box-shadow: 0 0 0 2px var(--red-wash); }
.form button.busy, .form .btn.busy { cursor: progress; opacity: .75; }
.form button.busy::after, .form .btn.busy::after { content: ' …'; }

/* ═══════════════════════════════════════════════════════════════════════
   Motion — "ink on the page"
   One idea, applied everywhere: things arrive the way ink does. A button
   fills like a highlighter stroke; a headline is underlined as if by an
   editor's pen; a chart draws its line from the first reading to the last,
   and the latest figure lands with the red mark; turning to a story slides
   the page like a broadsheet, and the headline you chose travels with you.

   Rules it keeps: nothing moves for a reader who asked for less motion (all of
   it is inside the media query below); only transform, opacity and SVG stroke
   are animated, so no layout is shifted and nothing is repainted wholesale;
   nothing is hidden unless the script is there to show it again (the hidden
   starting states need `html.motion`, which chrome.js sets); and nothing above
   the fold is hidden once the page has painted. No live light: the figures are
   published, not live (data.mjs).
   ═══════════════════════════════════════════════════════════════════════ */
:root { --ease-ink: cubic-bezier(0.2, 0.8, 0.2, 1); --ease-in: cubic-bezier(0.4, 0, 1, 1); }

@media (prefers-reduced-motion: no-preference) {
  /* ── buttons: a highlighter stroke, then a press ─────────────────────── */
  .btn:not(.red):not(.ink) {
    background-image: linear-gradient(var(--ink), var(--ink)); background-repeat: no-repeat;
    background-position: 0 0; background-size: 0% 100%;
    transition: background-size 0.34s var(--ease-ink), color 0.2s ease, transform 0.12s ease;
  }
  .btn:not(.red):not(.ink):hover, .btn:not(.red):not(.ink):focus-visible {
    background-color: transparent; background-image: linear-gradient(var(--ink), var(--ink));
    background-repeat: no-repeat; background-size: 100% 100%; color: var(--paper);
  }
  .btn.red, .btn.ink {
    background-repeat: no-repeat; background-position: 0 0; background-size: 0% 100%;
    transition: background-size 0.34s var(--ease-ink), border-color 0.2s ease, transform 0.12s ease;
  }
  .btn.red { background-image: linear-gradient(var(--red-2), var(--red-2)); }
  .btn.ink { background-image: linear-gradient(var(--red), var(--red)); }
  .btn.red:hover, .btn.red:focus-visible { background-color: var(--red); background-image: linear-gradient(var(--red-2), var(--red-2)); background-size: 100% 100%; }
  .btn.ink:hover, .btn.ink:focus-visible { background-color: var(--ink); background-image: linear-gradient(var(--red), var(--red)); background-size: 100% 100%; border-color: var(--red); }
  .btn:active, .rotbtn:active, .fchip:active, .langtoggle button:active, .tickpause:active, .dpill:active { transform: translateY(1px) scale(0.97); }
  .rotbtn, .fchip, .dpill, .langtoggle button { transition: background-color 0.2s ease, color 0.2s ease, border-color 0.2s ease, transform 0.12s ease; }
  /* An arrow leans towards where it goes. */
  .btn .icon, .dpill .icon, a.more .icon { transition: transform 0.24s var(--ease-ink); }
  .btn:hover .icon, .dpill:hover .icon, a.more:hover .icon { transform: translateX(3px); }

  /* ── story cards: the editor's pen, and a closer look ────────────────── */
  .second h3, .third h3 {
    text-decoration: underline; text-decoration-thickness: 2px; text-underline-offset: 4px;
    text-decoration-color: transparent; transition: color 0.2s ease, text-decoration-color 0.3s var(--ease-ink);
  }
  .second:hover h3, .third:hover h3, .second:focus-visible h3, .third:focus-visible h3 { text-decoration-color: currentColor; }
  .subjcardlead .wtitle { text-decoration: underline; text-decoration-thickness: 2px; text-underline-offset: 4px; text-decoration-color: transparent; transition: color 0.2s ease, text-decoration-color 0.3s var(--ease-ink); }
  .subjcardlead:hover .wtitle, .subjcardlead:focus-visible .wtitle { text-decoration-color: currentColor; }
  .subjcardlead .pic img, .heroshot img { transition: transform 0.7s var(--ease-ink); }
  .subjcardlead:hover .pic img, .heroshot:hover img { transform: scale(1.035); }
  .second .pic img, .third .pic img { transition: transform 0.7s var(--ease-ink); }
  .second:hover .pic img, .third:hover .pic img { transform: scale(1.035); }

  /* ── arriving as you scroll: ink settling on the page ────────────────── */
  .motion .second:not(.in), .motion .third:not(.in), .motion .dtile:not(.in), .motion .subjcard:not(.in), .motion .slab:not(.in) { opacity: 0; transform: translateY(12px); }
  /* The transition is on the arrived state only: hiding is instant (below the
     fold, unseen), arriving is animated. */
  .motion .second.in, .motion .third.in, .motion .dtile.in, .motion .subjcard.in, .motion .slab.in {
    transition: opacity 0.55s var(--ease-ink), transform 0.55s var(--ease-ink);
    transition-delay: calc(var(--k, 0) * 70ms);
  }

  /* ── charts: the line is drawn, the latest figure lands ──────────────── */
  .motion .chart:not(.in) .chartline { stroke-dasharray: 1; stroke-dashoffset: 1; }
  .motion .chart .chartline { stroke-dasharray: 1; }
  .motion .chart.in .chartline { transition: stroke-dashoffset 1.3s var(--ease-ink); }
  .motion .chart:not(.in) .chartarea { opacity: 0; }
  .motion .chart.in .chartarea { transition: opacity 0.9s ease 0.6s; }
  .motion .chart:not(.in) .chartdot { opacity: 0; transform: scale(0.2); }
  .motion .chart .chartdot { transform-box: fill-box; transform-origin: center; }
  .motion .chart.in .chartdot { transition: opacity 0.3s ease, transform 0.4s var(--ease-ink); transition-delay: calc(0.25s + var(--i, 0) * 45ms); }
  .motion .chart:not(.in) .chartend, .motion .chart:not(.in) .chartlabel { opacity: 0; transform: scale(0.3); }
  .motion .chart .chartend { transform-box: fill-box; transform-origin: center; }
  .motion .chart.in .chartend { transition: opacity 0.2s ease 1.2s, transform 0.5s cubic-bezier(0.3, 1.6, 0.5, 1) 1.2s; }
  .motion .chart .chartlabel { transform-box: fill-box; transform-origin: left center; }
  .motion .chart.in .chartlabel { transition: opacity 0.4s ease 1.35s, transform 0.4s var(--ease-ink) 1.35s; }
  .motion .chart.in .chartend { animation: ink-ring 1.1s var(--ease-ink) 1.5s 1 both; }
  @keyframes ink-ring { 0% { stroke: var(--red); stroke-width: 0; stroke-opacity: 0.6; } 100% { stroke: var(--red); stroke-width: 14; stroke-opacity: 0; } }

  /* Bars grow from the baseline, in order, the newest in red last. */
  .motion .dbars:not(.in) rect:not(.ghost) { transform: scaleY(0); }
  .motion .dbars rect { transform-box: fill-box; transform-origin: bottom; }
  .motion .dbars.in rect { transition: transform 0.55s var(--ease-ink); transition-delay: calc(var(--i, 0) * 40ms); }

  /* The gauge fills to its share. */
  .motion .dgaugearc:not(.in) .fill { stroke-dashoffset: var(--len, 0); }
  .motion .dgaugearc.in .fill { transition: stroke-dashoffset 1.1s var(--ease-ink) 0.15s; }

  /* ── search suggestions drop in like a wire item ─────────────────────── */
  .suggest:not([hidden]) { animation: wire-in 0.2s var(--ease-ink) both; }
  @keyframes wire-in { from { opacity: 0; transform: translateY(-4px); } }

  /* ── a form on its way: the dots of a story being filed ──────────────── */
  .form button.busy::after, .form .btn.busy::after { content: ''; display: inline-block; width: 1.2em; text-align: left; animation: filing 1.1s steps(4, end) infinite; }
  @keyframes filing { 0% { content: ''; } 25% { content: '.'; } 50% { content: '..'; } 75% { content: '...'; } }

  /* ── turning to a story: the broadsheet slides, the headline travels ─── */
  @view-transition { navigation: auto; }
  .sitehead { view-transition-name: masthead; }
  .vt-head { view-transition-name: headline; }
  ::view-transition-old(root) { animation: page-out 0.16s var(--ease-in) both; }
  ::view-transition-new(root) { animation: page-in 0.3s var(--ease-ink) both; }
  ::view-transition-group(headline) { animation-duration: 0.36s; animation-timing-function: var(--ease-ink); }
  ::view-transition-group(masthead) { animation-duration: 0s; }
  @keyframes page-out { to { opacity: 0; transform: translateX(-14px); } }
  @keyframes page-in { from { opacity: 0; transform: translateX(18px); } }
}

/* ═══════════════════════════════════════════════════════════════════════
   ANALYSIS · the kind label, the story's own chart, the section front
   ═══════════════════════════════════════════════════════════════════════ */
/* "Analysis" ahead of the subject: a solid ink chip, so an argument is never
   read as a report of fact. Reports and interviews take the outline. */
.kindtag { display: inline-block; font-family: var(--mono); font-size: 9.5px; font-weight: 700; letter-spacing: 0.12em; text-transform: uppercase; line-height: 1; padding: 4px 6px 3px; margin-right: 2px; background: var(--ink); color: var(--paper); border: 1px solid var(--ink); }
.kindtag.kind-report, .kindtag.kind-interview { background: transparent; color: var(--ink); }
.wbody .kindtag { margin: 0 0 4px; align-self: flex-start; width: max-content; }
.slab.dark .kindtag, .lead-story .kindtag { background: var(--paper); color: var(--ink); border-color: var(--paper); }

/* The story's chart: labels, a track, the value — text first, bars second. */
.abars { margin: 26px 0; padding: 14px 0 0; border-top: var(--rule) solid var(--ink); }
.abhead { display: grid; gap: 4px; margin-bottom: 14px; }
.abhead .caps { color: var(--muted); }
.abhead b { font-family: var(--display); font-size: 18px; line-height: 1.25; font-stretch: var(--wide-head); }
.abrows { list-style: none; margin: 0; padding: 0; display: grid; gap: 9px; }
.abrow { display: grid; grid-template-columns: minmax(96px, 34%) minmax(0, 1fr) auto; align-items: center; gap: 12px; font-size: 14px; }
.ablabel { color: var(--ink-2); line-height: 1.25; }
.abtrack { display: block; height: 14px; background: var(--line-2); position: relative; overflow: hidden; }
.abtrack i { position: absolute; inset: 0 auto 0 0; width: calc(var(--share, 0) * 100%); background: var(--ink); }
.abrow.hot .abtrack i { background: var(--red); }
.abrow.hot .ablabel, .abrow.hot .abval { color: var(--ink); font-weight: 700; }
.abval { font-family: var(--display); font-weight: 700; font-variant-numeric: tabular-nums; min-width: 3.2em; text-align: right; }
.abars .gsrc { font-family: var(--mono); font-size: 11px; letter-spacing: 0.04em; color: var(--muted); margin: 12px 0 0; }
@media (max-width: 559px) { .abrow { grid-template-columns: minmax(0, 1fr) auto; gap: 4px 10px; } .abtrack { grid-column: 1 / -1; grid-row: 2; } }

/* The section front: the method as a masthead, the lens beside it. */
.ahead { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--air-2) var(--gutter); align-items: end; padding: var(--air-2) 0 18px; border-bottom: var(--rule) solid var(--ink); }
.ahead h1 { margin: 6px 0 0; }
.ahead h1 .om { color: var(--red-text); }
.ahead .lead { max-width: 62ch; margin: 10px 0 8px; }
.ahead .caps { color: var(--muted); }
.lensmark { width: min(260px, 70%); height: auto; justify-self: end; }
.lensmark .lbars rect { fill: var(--ink); }
.lensmark .lbars rect.hot { fill: var(--red); }
.lensmark .lbase { stroke: var(--ink); stroke-width: 3; }
.lensmark .lring circle { fill: none; stroke: var(--ink); stroke-width: 7; }
.lensmark .lring circle.thin { stroke-width: 1.5; stroke-dasharray: 3 5; }
.lensmark .lring line { stroke: var(--ink); stroke-width: 12; stroke-linecap: round; }
@media (min-width: 760px) { .ahead { grid-template-columns: minmax(0, 1fr) 260px; } }
.asteps { list-style: none; margin: 0 0 var(--air-2); padding: 0; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); border-bottom: 1px solid var(--line); }
.asteps li { padding: 12px 12px 14px 0; border-right: 1px solid var(--line); display: grid; gap: 4px; }
.asteps li:nth-child(2n) { border-right: 0; padding-left: 12px; }
.asteps .caps { color: var(--red-text); }
.asteps b { font-size: 14.5px; line-height: 1.3; }
@media (min-width: 760px) { .asteps { grid-template-columns: repeat(4, minmax(0, 1fr)); } .asteps li { padding: 14px 16px 16px; } .asteps li:first-child { padding-left: 0; } .asteps li:nth-child(2n) { border-right: 1px solid var(--line); padding-left: 16px; } .asteps li:last-child { border-right: 0; } }

/* The lead piece: its argument and its chart, side by side on a wide screen. */
.alead { display: grid; grid-template-columns: minmax(0, 1fr); gap: 8px var(--gutter); padding-top: 14px; border-top: var(--rule) solid var(--cat, var(--ink)); }
.aleadtext { display: grid; gap: 6px; align-content: start; text-decoration: none; color: inherit; }
.aleadtext .wtitle { font-family: var(--display); font-size: var(--h-1); line-height: 1.06; letter-spacing: var(--track-display); font-stretch: var(--wide-head); margin: 4px 0 0; }
.aleadtext:hover .wtitle { color: var(--red-text); }
.aleadtext .wtwin { color: var(--muted); font-size: 15px; }
.aleadtext .wsum { font-size: 16px; line-height: 1.55; color: var(--ink-2); margin-top: 6px; }
.aleadtext .ameta { font-family: var(--mono); font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted); }
.aleadtext .btn { justify-self: start; margin-top: 8px; }
.aleadart .abars { margin-top: 0; }
@media (min-width: 900px) { .alead { grid-template-columns: minmax(0, 6fr) minmax(0, 5fr); } .aleadart .abars { margin: 0; border-top: 0; padding-top: 0; } }
.aband .atwo { margin-top: var(--air-2); }

/* A poster for a piece with a chart: its bars, small, under the figure. */
.pic.typo .typo-bars { display: flex; align-items: flex-end; gap: 4px; height: 26%; min-height: 26px; margin: 6px 0 4px; }
.pic.typo .typo-bars i { flex: 1 1 0; max-width: 18%; height: calc(var(--share, 0) * 100%); background: rgba(255, 255, 255, 0.55); }
.pic.typo .typo-bars i.hot { background: #fff; }

@media (prefers-reduced-motion: no-preference) {
  /* The bars grow to their share in order as the chart arrives. */
  .motion .abars:not(.in) .abtrack i { transform: scaleX(0); }
  .motion .abars .abtrack i { transform-origin: left center; }
  .motion .abars.in .abtrack i { transition: transform 0.8s var(--ease-ink); transition-delay: calc(0.1s + var(--i, 0) * 90ms); }
  /* The lens: bars rise, then the glass comes to rest over the tallest. */
  .motion .lensmark:not(.in) .lbars rect { transform: scaleY(0); }
  .motion .lensmark .lbars rect { transform-box: fill-box; transform-origin: bottom; }
  .motion .lensmark.in .lbars rect { transition: transform 0.6s var(--ease-ink); transition-delay: calc(var(--i, 0) * 90ms); }
  .motion .lensmark:not(.in) .lring { opacity: 0; transform: translate(-24px, 18px) scale(0.92); }
  .motion .lensmark .lring { transform-box: view-box; transform-origin: 128px 62px; }
  .motion .lensmark.in .lring { transition: opacity 0.4s ease 0.45s, transform 0.8s var(--ease-ink) 0.45s; }
}

/* ── Accessibility sweep, 23 October 2026 ────────────────────────────────
   What platform/scripts/a11y.mjs found in a real browser — axe-core's WCAG
   2.2 A/AA rules, typed text measured against its ground, and every Tab
   stop checked for a ring — on both sites, in both themes. One block, so the
   reason for each rule stays beside it. */

/* A placeholder is text a reader must read: the browser's own grey measured
   4.30:1 on the dark field and 3.96:1 on the desk's dark finder. The muted
   ink is 4.7:1 on the light field and 6.5:1 on the dark one. */
::placeholder { color: var(--muted); opacity: 1; }

/* The search box shows its focus on the box, not the field inside it, and a
   change of border colour alone is not a ring (2.4.7). */
.searchwrap:focus-within { outline: 2px solid var(--link); outline-offset: 2px; }

/* An empty video slot is drawn in muted ink on paper; the series label's
   0.92 opacity is for white on a category fill and took it to 4.04:1 here. */
.vcard.blank .vposter .vseries { opacity: 1; }

/* The quality page's lists of links ran 15 px apart: under the 24 px a
   finger needs (2.5.8). */
.checks ul > li { padding: 4.5px 0; }

/* A dashboard tile under the pointer turns paper-3, where the muted label
   measured 4.21:1. The label darkens with it (9.4:1 light, 10.6:1 dark). */
.tile:hover .caps { color: var(--ink-2); }

/* Inline styles, as classes (ASVS 5.0 V3.4: the policy allows no style
   attribute — style-src-attr 'none'). A declaration that used to sit in a
   style="" attribute of the platform's pages sits here, and keeps the inline
   declaration's place in the cascade: :not(#_) three times is the specificity
   of three ids, which no other rule here has, and there is no !important, so
   it beats every ordinary rule and loses to an !important one, as inline did.
   The original turns its attributes into the same kind of rule at the
   server's boundary (app/src/lib/inline-styles.mjs). */
.u-mt-air:not(#_):not(#_):not(#_) { margin-top: var(--air); }
.u-mt-band:not(#_):not(#_):not(#_) { margin-top: var(--band); }
.u-mt0:not(#_):not(#_):not(#_) { margin-top: 0; }
.u-mt14:not(#_):not(#_):not(#_) { margin-top: 14px; }
.u-mt18:not(#_):not(#_):not(#_) { margin-top: 18px; }
.u-mb-air:not(#_):not(#_):not(#_) { margin-bottom: var(--air); }
.u-mb10:not(#_):not(#_):not(#_) { margin-bottom: 10px; }
.u-m6:not(#_):not(#_):not(#_) { margin: 6px 0; }
.u-fig:not(#_):not(#_):not(#_) { margin: 16px 0 14px; }
.u-pt-band:not(#_):not(#_):not(#_) { padding-top: var(--band); }
.u-pt-band48:not(#_):not(#_):not(#_) { padding-top: var(--band, 48px); }
.u-pad24:not(#_):not(#_):not(#_) { padding: 24px 0; }
.u-span:not(#_):not(#_):not(#_) { grid-column: 1/-1; }
.u-checkrow:not(#_):not(#_):not(#_) { display: flex; gap: 10px; align-items: flex-start; }
.u-check:not(#_):not(#_):not(#_) { width: auto; margin-top: 4px; }
.u-block:not(#_):not(#_):not(#_) { display: block; }
.u-mw68:not(#_):not(#_):not(#_) { max-width: 68ch; }
.u-mw520:not(#_):not(#_):not(#_) { max-width: 520px; }
.u-ruled:not(#_):not(#_):not(#_) { border-top: 1px solid var(--line); padding-top: 12px; margin-top: 22px; }
.u-twin18:not(#_):not(#_):not(#_) { font-size: 18px; font-weight: 700; letter-spacing: -0.022em; }
.u-twin19:not(#_):not(#_):not(#_) { font-size: 19px; font-weight: 700; letter-spacing: -0.022em; }
.u-fs14:not(#_):not(#_):not(#_) { font-size: 14px; }
.u-right:not(#_):not(#_):not(#_) { text-align: right; }
.u-inherit:not(#_):not(#_):not(#_) { color: inherit; }
.u-w92:not(#_):not(#_):not(#_) { white-space: nowrap; width: 92px; }
.u-w180:not(#_):not(#_):not(#_) { width: 180px; vertical-align: top; }
.u-w220:not(#_):not(#_):not(#_) { width: 220px; }
.u-w40:not(#_):not(#_):not(#_) { width: 40%; }
.u-w44:not(#_):not(#_):not(#_) { width: 44%; }
.u-w45:not(#_):not(#_):not(#_) { width: 45%; }
.u-w48:not(#_):not(#_):not(#_) { width: 48%; }
.u-w52:not(#_):not(#_):not(#_) { width: 52%; }
.u-w56:not(#_):not(#_):not(#_) { width: 56%; }
.u-w62:not(#_):not(#_):not(#_) { width: 62%; }
.u-w66:not(#_):not(#_):not(#_) { width: 66%; }
.u-w70:not(#_):not(#_):not(#_) { width: 70%; }
.u-wm24:not(#_):not(#_):not(#_) { width: 89px; height: 24px; }
.u-wm30:not(#_):not(#_):not(#_) { width: 111px; height: 30px; }
.u-wm34:not(#_):not(#_):not(#_) { width: 126px; height: 34px; }
.u-i0:not(#_):not(#_):not(#_) { --i: 0; }
.u-i1:not(#_):not(#_):not(#_) { --i: 1; }
.u-i2:not(#_):not(#_):not(#_) { --i: 2; }
.u-i3:not(#_):not(#_):not(#_) { --i: 3; }

/* ── A new version (public/sw.js, chrome.js), 23 October 2026 ────────────
   One line at the foot of the screen when a new release has taken over while
   the page was open: ink on paper with the brand rule, 44 px tall, ringed on
   focus like every other control. */
.swnotice { position: fixed; left: 16px; right: 16px; bottom: 16px; z-index: 60; display: flex; justify-content: center; pointer-events: none; }
.swnotice .swreload {
  pointer-events: auto; min-height: 44px; padding: 10px 18px; font: 600 15px/1.3 var(--sans);
  color: var(--ink); background: var(--paper); border: 1.5px solid var(--ink); border-left: 6px solid var(--red);
  border-radius: var(--radius); box-shadow: 0 6px 24px rgba(0, 0, 0, 0.18); cursor: pointer;
}
.swnotice .swreload:hover { text-decoration: underline; }
.swnotice .swreload:focus-visible { outline: 2px solid var(--link); outline-offset: 2px; }
