/*
 * Editorial Essay post template.
 *
 * Every rule is scoped under #primary.editorial-post. Tokens are declared on that
 * wrapper rather than :root so they cannot leak into the rest of the site.
 *
 * Fonts are NOT declared here — assets/css/main.css already serves
 * VC Garamond Condensed and Apercu sitewide.
 *
 * DO NOT simplify the prefix back down to plain `.editorial-post`.
 * <main id="primary" class="site-main editorial-post"> carries BOTH an id
 * and a class, and theme.css ships several `body.single-post #primary <x>`
 * rules (ids=1, classes=1, elements=1-2 → specificity ~121-122) that
 * silently beat any class-only selector we write here — e.g. it was
 * repainting every chapter heading 20px italic Noe and every rail link the
 * theme blue #2a70ea instead of --ed-blue. Prefixing every rule with the
 * SAME element's id, `#primary.editorial-post`, changes nothing about the
 * DOM (it's still one wrapper) but ties the specificity ID count with the
 * theme's rules and wins on the class count that follows. Losing the
 * `#primary` here silently reintroduces that bug.
 */

#primary.editorial-post {
  --ed-paper: #f8f9fb;
  --ed-ink: #142025;
  --ed-muted: #59666e;
  --ed-blue: #2353dc;
  --ed-blue-pale: #edf1fc;
  --ed-quote-blue: #6d8eb8;
  --ed-quote-paper: #dceafb;
  --ed-quote-ink: #345479;
  --ed-line: #d4dbe0;
  --ed-serif: "VC Garamond Condensed", Georgia, serif;
  --ed-sans: "Apercu", "Avenir Next", Avenir, "Segoe UI", sans-serif;
  --ed-max: 1344px;
  --ed-gutter: clamp(24px, 4.8vw, 80px);
}

/* ---------------------------------------------------------------- *
 * Collision mitigations. See CLAUDE.md "Lessons from the Batch 1-8
 * marathon" for how each of these was found.
 * ---------------------------------------------------------------- */

/* style.css hides EVERY <br> sitewide below 992px via
   "#notification-bar,br{display:none}". Template markup uses block-level
   spans instead, but pasted content may legitimately use <br>, so undo the
   rule inside our scope. Specificity 0,0,1,1 beats the theme's 0,0,0,1. */
#primary.editorial-post br {
  display: inline;
}

/* The wrapper must never inherit the theme's 9rem block padding. Belt and
   braces alongside the non-opal- prefixed class name. */
#primary.editorial-post {
  padding-top: 0;
  padding-bottom: 0;
}

/* The replacement for <br> in headlines. Spans are immune to the sitewide
   br rule, break at every viewport, and wrap gracefully inside themselves
   when a line is too long for a narrow phone. */
#primary.editorial-post .ed-line {
  display: block;
}

/* ---------------------------------------------------------------- *
 * Shell
 * ---------------------------------------------------------------- */

#primary.editorial-post .ed-shell,
#primary.editorial-post .ed-cover,
#primary.editorial-post .ed-layout {
  width: calc(100% - var(--ed-gutter) * 2);
  max-width: var(--ed-max);
  margin-inline: auto;
}

#primary.editorial-post {
  background: var(--ed-paper);
  color: var(--ed-ink);
  font-family: var(--ed-sans);
  -webkit-font-smoothing: antialiased;
}

/* The cover's paper tone runs to the top of the page, behind the
   transparent header, instead of stopping at the header's lower edge.
   Without this the white body shows through the nav and the page reads as
   three stacked bands: notification bar, white nav, paper article.
   Literal hex, not var(--ed-paper): the token is declared on
   #primary.editorial-post, which is not an ancestor of <body>. */
body.post-template-template-editorial-essay {
  background-color: #f8f9fb;
}

#primary.editorial-post * {
  box-sizing: border-box;
}

/* ---------------------------------------------------------------- *
 * Fixed reading progress. #masthead is position:relative, not sticky,
 * so the bar pins to the viewport instead of to the header.
 * ---------------------------------------------------------------- */

#primary.editorial-post .ed-progress {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: 3px;
  z-index: 30;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.3s;
}

#primary.editorial-post .ed-progress.is-active {
  opacity: 1;
}

#primary.editorial-post .ed-progress > span {
  display: block;
  height: 100%;
  background: var(--ed-blue);
  transform: scaleX(0);
  transform-origin: left;
}

/* ---------------------------------------------------------------- *
 * Chapter headings. The demo numbered these with a separate
 * .chapter-number element; here the number comes from the
 * data-chapter-number attribute PHP injects, so ordinary H2 blocks in
 * the editor get numbered with no special markup.
 * ---------------------------------------------------------------- */

#primary.editorial-post .ed-main h2[data-chapter] {
  position: relative;
  border-top: 1px solid var(--ed-line);
  padding-top: 34px;
  margin: 100px 0 34px;
  padding-left: 70px;
  font: 400 clamp(38px, 3.65vw, 55px) / 1.06 var(--ed-serif);
  letter-spacing: -0.024em;
  scroll-margin-top: 40px;
  /* Theme's `body.single-post #primary h2` (ids=1,classes=1,elements=2)
     otherwise wins the `color` property here: this selector's font
     shorthand covers family/size/style but not color. */
  color: var(--ed-ink);
}

#primary.editorial-post .ed-main h2[data-chapter]::before {
  content: attr(data-chapter-number);
  position: absolute;
  left: 0;
  top: 34px;
  font: 400 46px/1 var(--ed-serif);
  color: var(--ed-blue);
}

#primary.editorial-post .ed-main h2[data-chapter] em {
  color: var(--ed-blue);
  font-style: normal;
}

/* ---------------------------------------------------------------- *
 * Chapter kicker — the short label the demo showed above each chapter
 * heading (ported from `.chapter-heading .eyebrow`). Optional: a plain
 * <h2> with no preceding kicker is unaffected. When present, it is a
 * sibling immediately before h2[data-chapter], and takes over the
 * heading's top rule/spacing so the rule sits above the kicker, not
 * between the kicker and the headline.
 * ---------------------------------------------------------------- */

#primary.editorial-post .ed-chapter-kicker {
  display: block;
  color: var(--ed-muted);
  margin-bottom: 12px;
}

#primary.editorial-post .ed-main .ed-chapter-kicker {
  border-top: 1px solid var(--ed-line);
  padding-top: 34px;
  margin-top: 100px;
}

#primary.editorial-post .ed-chapter-kicker + h2[data-chapter] {
  border-top: 0;
  padding-top: 0;
  margin-top: 0;
}

/* ---------------------------------------------------------------- *
 * Mobile contents. The rail hides below 900px, so phones get an
 * inline <details> instead of losing chapter navigation entirely.
 * ---------------------------------------------------------------- */

#primary.editorial-post .ed-contents-mobile {
  display: none;
}

@media (max-width: 900px) {
  #primary.editorial-post .ed-rail {
    display: none;
  }

  #primary.editorial-post .ed-contents-mobile {
    display: block;
    width: calc(100% - var(--ed-gutter) * 2);
    max-width: var(--ed-max);
    margin: 30px auto 0;
    border-top: 1px solid var(--ed-line);
    border-bottom: 1px solid var(--ed-line);
  }

  #primary.editorial-post .ed-contents-mobile summary {
    list-style: none;
    cursor: pointer;
    padding: 18px 0;
    font-size: 0.8125rem;
    font-weight: 600;
    letter-spacing: 0.12em;
    text-transform: uppercase;
  }

  #primary.editorial-post .ed-contents-mobile summary::-webkit-details-marker {
    display: none;
  }

  #primary.editorial-post .ed-contents-mobile nav {
    display: grid;
    gap: 2px;
    padding-bottom: 16px;
  }

  #primary.editorial-post .ed-contents-mobile nav a {
    display: flex;
    gap: 12px;
    padding: 10px 0;
    font-size: 0.8125rem;
    color: var(--ed-muted);
    text-decoration: none;
  }
}

/* ---------------------------------------------------------------- *
 * Core-block typography — base element resets ported from the demo.
 * Scoped under #primary.editorial-post so nothing leaks sitewide.
 * ---------------------------------------------------------------- */

#primary.editorial-post button,
#primary.editorial-post a {
  -webkit-tap-highlight-color: transparent;
}

#primary.editorial-post a {
  color: inherit;
}

#primary.editorial-post button {
  font: inherit;
}

#primary.editorial-post button,
#primary.editorial-post a,
#primary.editorial-post summary {
  touch-action: manipulation;
}

#primary.editorial-post button:focus-visible,
#primary.editorial-post a:focus-visible,
#primary.editorial-post summary:focus-visible {
  outline: 2px solid var(--ed-blue);
  outline-offset: 6px;
}

#primary.editorial-post ::selection {
  background: #ccdbff;
  color: #142025;
}

#primary.editorial-post img {
  display: block;
  max-width: 100%;
}

#primary.editorial-post p {
  margin: 0 0 1.35em;
}

#primary.editorial-post strong {
  font-weight: 600;
}

#primary.editorial-post em {
  font-family: var(--ed-serif);
  font-weight: 700;
}

#primary.editorial-post .ed-main > p em,
#primary.editorial-post .ed-main > ul em,
#primary.editorial-post .ed-main > ol em {
  font-family: var(--ed-sans);
  font-weight: 400;
}

#primary.editorial-post h1,
#primary.editorial-post h2,
#primary.editorial-post h3,
#primary.editorial-post blockquote,
#primary.editorial-post figure {
  margin: 0;
}

/* ---------------------------------------------------------------- *
 * Eyebrow
 * ---------------------------------------------------------------- */

#primary.editorial-post .ed-eyebrow {
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  line-height: 1.6;
  text-transform: uppercase;
}

/* ---------------------------------------------------------------- *
 * Cover
 * ---------------------------------------------------------------- */

#primary.editorial-post .ed-cover {
  padding-top: 50px;
  padding-bottom: 42px;
  border-bottom: 1px solid var(--ed-ink);
}

#primary.editorial-post .ed-cover-eyebrow {
  display: flex;
  justify-content: space-between;
  color: var(--ed-muted);
  margin-bottom: 46px;
}

#primary.editorial-post .ed-cover-eyebrow > :first-child {
  color: var(--ed-blue);
}

#primary.editorial-post .ed-slash {
  margin: 0 15px;
  color: #9aa2aa;
}

#primary.editorial-post .ed-title {
  font-family: var(--ed-serif);
  font-size: clamp(44px, 5.4vw, 80px);
  font-weight: 400;
  letter-spacing: -0.035em;
  line-height: 0.98;
}

#primary.editorial-post .ed-title em {
  color: var(--ed-blue);
  font-style: normal;
  font-weight: 400;
  letter-spacing: inherit;
}

#primary.editorial-post .ed-title sup {
  display: inline-block;
  vertical-align: top;
  color: var(--ed-blue);
  font: 400 clamp(32px, 4vw, 58px) / 1 var(--ed-sans);
  margin: 25px 0 0 28px;
}

#primary.editorial-post .ed-cover-bottom {
  display: grid;
  grid-template-columns: 1fr auto 56px;
  align-items: end;
  gap: 42px;
  margin-top: 51px;
}

#primary.editorial-post .ed-cover-meta {
  display: grid;
  gap: 8px;
}

#primary.editorial-post .ed-read-time {
  font-size: 0.75rem;
  color: var(--ed-muted);
}

#primary.editorial-post .ed-cover-note {
  margin: 0;
  font-family: var(--ed-serif);
  font-weight: 100;
  font-size: 1.75rem;
  line-height: 1.25;
  max-width: 330px;
}

#primary.editorial-post .ed-cover-note em {
  color: var(--ed-quote-blue);
  font-style: normal;
  font-weight: 100;
}

#primary.editorial-post .ed-start {
  width: 53px;
  height: 53px;
  display: grid;
  place-items: center;
  border: 1px solid var(--ed-line);
  border-radius: 50%;
  font-size: 25px;
  text-decoration: none;
  /* Theme's `body.single-post #primary a` (ids=1,classes=1,elements=2)
     otherwise wins color/font-weight here. */
  color: var(--ed-ink);
  font-weight: 400;
  transition: color 0.25s, background 0.25s, transform 0.25s;
}

/* Theme's `body.single-post #primary a:hover` (ids=1,classes=2,elements=2)
   beats `#primary.editorial-post .ed-start` (ids=1,classes=2,elements=0) and
   forces text-decoration:underline back on. This selector (ids=1,classes=3)
   wins outright. */
#primary.editorial-post .ed-start:hover {
  background: var(--ed-blue);
  border-color: var(--ed-blue);
  color: white;
  text-decoration: none;
  transform: translateY(3px);
}

@media (prefers-reduced-motion: no-preference) {
  #primary.editorial-post .ed-cover-bottom {
    animation: ed-cover-in 1s 0.38s both;
  }

  @keyframes ed-cover-in {
    from {
      opacity: 0;
      transform: translateY(22px);
    }
    to {
      opacity: 1;
      transform: translateY(0);
    }
  }
}

/* ---------------------------------------------------------------- *
 * Two-column layout + chapter rail
 * ---------------------------------------------------------------- */

#primary.editorial-post .ed-layout {
  display: grid;
  grid-template-columns: 200px minmax(0, 1fr);
  gap: 6.3%;
  align-items: start;
  padding-top: 100px;
}

/* No chapters -> no <aside class="ed-rail"> is rendered, so .ed-main would
   otherwise auto-place into the 200px rail track. Collapse to one column. */
#primary.editorial-post .ed-layout.ed-layout--no-rail {
  grid-template-columns: minmax(0, 1fr);
}

/* The chapter rail is position:sticky, but style.css ships
   `#page { overflow: hidden }` on the theme's outer wrapper, and ANY
   ancestor with overflow:hidden turns it into a scroll container — which
   silently degrades sticky to relative. Measured on production before this
   rule: the rail scrolled to -1731px instead of holding at its 126px offset.

   `overflow: clip` is the fix rather than `visible`: clip still clips, but
   does NOT create a scroll container, so sticky keeps working. Setting
   `visible` here instead would expose the theme's solutions mega-menu
   (39px of horizontal scroll at 1024px) and the cookie plugin's off-canvas
   modal parked at left:-480px — both of which #page is legitimately hiding.

   Scoped to this template's body class, so no other page is affected. This
   selector cannot use the #primary.editorial-post prefix used everywhere
   else in this file, because #page is an ANCESTOR of #primary.

   Specificity: body + .post-template-… + #page = (1 id, 1 class, 1 element)
   beats the theme's bare `#page` (1 id) on class count.

   If overflow:clip is unsupported, this declaration is simply dropped and
   the theme's overflow:hidden still applies — the rail stops sticking but
   nothing breaks. */
body.post-template-template-editorial-essay #page {
  overflow: clip;
}

#primary.editorial-post .ed-rail {
  position: sticky;
  top: 126px;
  align-self: start;
}

#primary.editorial-post .ed-rail-title {
  color: var(--ed-muted);
  display: block;
  margin-bottom: 25px;
}

#primary.editorial-post .ed-rail-inner nav {
  display: grid;
  gap: 7px;
}

#primary.editorial-post .ed-rail-inner nav a {
  display: flex;
  align-items: baseline;
  gap: 12px;
  font-size: 0.75rem;
  line-height: 1.4;
  text-decoration: none;
  color: var(--ed-muted);
  padding: 9px 0;
  transition: color 0.3s;
}

#primary.editorial-post .ed-rail-inner nav a span {
  font-size: 0.75rem;
  font-variant-numeric: tabular-nums;
  color: #7a8790;
}

#primary.editorial-post .ed-rail-inner nav a.is-current,
#primary.editorial-post .ed-rail-inner nav a.is-current span,
#primary.editorial-post .ed-rail-inner nav a:hover {
  color: var(--ed-blue);
}

#primary.editorial-post .ed-rail-inner nav a.is-current {
  font-weight: 600;
}

#primary.editorial-post .ed-rail-progress {
  border-top: 1px solid var(--ed-line);
  margin-top: 30px;
  padding-top: 18px;
  display: flex;
  justify-content: space-between;
  font-size: 0.75rem;
  color: var(--ed-muted);
}

#primary.editorial-post .ed-read-percent {
  color: var(--ed-blue);
  font-variant-numeric: tabular-nums;
}

#primary.editorial-post .ed-main {
  min-width: 0;
}

/* ---------------------------------------------------------------- *
 * Body copy measure. The demo wrapped running text in a .text-column
 * container; here .ed-main is that container and its direct-child
 * paragraphs/lists get the measure directly.
 * ---------------------------------------------------------------- */

#primary.editorial-post .ed-main > p,
#primary.editorial-post .ed-main > ul,
#primary.editorial-post .ed-main > ol {
  max-width: 620px;
  font-size: 1.0625rem;
  line-height: 1.85;
}

#primary.editorial-post .ed-main > p:last-child {
  margin-bottom: 0;
}

/* ---------------------------------------------------------------- *
 * Responsive
 * ---------------------------------------------------------------- */

@media (min-width: 1500px) {
  #primary.editorial-post .ed-title {
    font-size: 80px;
  }

  #primary.editorial-post .ed-layout {
    grid-template-columns: 210px minmax(0, 1fr);
  }

  #primary.editorial-post .ed-layout.ed-layout--no-rail {
    grid-template-columns: minmax(0, 1fr);
  }
}

@media (max-width: 1200px) {
  #primary.editorial-post .ed-layout {
    grid-template-columns: 165px minmax(0, 1fr);
    gap: 45px;
  }

  #primary.editorial-post .ed-layout.ed-layout--no-rail {
    grid-template-columns: minmax(0, 1fr);
  }

  #primary.editorial-post .ed-title {
    font-size: 5.4vw;
  }

  #primary.editorial-post .ed-rail-inner nav a {
    font-size: 0.75rem;
  }

  #primary.editorial-post .ed-cover-note {
    font-size: 1.375rem;
  }
}

@media (max-width: 900px) {
  #primary.editorial-post .ed-layout {
    grid-template-columns: 1fr;
    max-width: 740px;
    padding-top: 65px;
  }

  #primary.editorial-post .ed-cover {
    padding-top: 32px;
  }

  #primary.editorial-post .ed-title {
    font-size: 6.6vw;
  }

  #primary.editorial-post .ed-cover-eyebrow {
    margin-bottom: 38px;
  }

  #primary.editorial-post .ed-cover-bottom {
    gap: 25px;
  }

  #primary.editorial-post .ed-cover-meta > .ed-eyebrow {
    max-width: 190px;
  }

  #primary.editorial-post .ed-cover-note {
    font-size: 1.1875rem;
  }

  #primary.editorial-post .ed-title sup {
    margin-left: 15px;
    margin-top: 15px;
  }

  #primary.editorial-post .ed-main > p,
  #primary.editorial-post .ed-main > ul,
  #primary.editorial-post .ed-main > ol {
    max-width: 100%;
    font-size: 1.0625rem;
  }

  #primary.editorial-post .ed-main h2[data-chapter] {
    font-size: 46px;
  }
}

@media (max-width: 600px) {
  #primary.editorial-post {
    --ed-gutter: 23px;
  }

  #primary.editorial-post .ed-cover {
    padding-top: 27px;
    padding-bottom: 28px;
  }

  #primary.editorial-post .ed-cover-eyebrow {
    margin-bottom: 34px;
    gap: 15px;
  }

  #primary.editorial-post .ed-cover-eyebrow .ed-eyebrow {
    font-size: 0.75rem;
    letter-spacing: 0.08em;
  }

  #primary.editorial-post .ed-cover-eyebrow > :last-child {
    max-width: 130px;
    text-align: right;
  }

  #primary.editorial-post .ed-cover-eyebrow .ed-slash {
    margin-inline: 5px;
  }

  #primary.editorial-post .ed-title {
    font-size: 9.8vw;
    line-height: 1.07;
    letter-spacing: -0.04em;
  }

  #primary.editorial-post .ed-title sup {
    font-size: 21px;
    margin-top: 7px;
    margin-left: 8px;
  }

  #primary.editorial-post .ed-cover-bottom {
    grid-template-columns: 1fr 42px;
    gap: 20px;
    margin-top: 32px;
  }

  #primary.editorial-post .ed-cover-note {
    grid-column: 1;
    grid-row: 2;
    font-size: 1.1875rem;
  }

  #primary.editorial-post .ed-start {
    width: 42px;
    height: 42px;
    grid-column: 2;
    grid-row: 1 / 3;
    align-self: end;
  }

  #primary.editorial-post .ed-cover-meta {
    gap: 6px;
  }

  #primary.editorial-post .ed-cover-meta > .ed-eyebrow {
    max-width: 100%;
    font-size: 0.75rem;
  }

  #primary.editorial-post .ed-read-time {
    font-size: 0.75rem;
  }

  #primary.editorial-post .ed-layout {
    padding-top: 46px;
  }

  #primary.editorial-post .ed-main > p,
  #primary.editorial-post .ed-main > ul,
  #primary.editorial-post .ed-main > ol {
    font-size: 1rem;
    line-height: 1.85;
  }

  #primary.editorial-post .ed-main h2[data-chapter] {
    font-size: 35px;
  }

  #primary.editorial-post .ed-main h2[data-chapter]::before {
    font-size: 34px;
  }
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  #primary.editorial-post *,
  #primary.editorial-post *::before,
  #primary.editorial-post *::after {
    animation: none !important;
    transition: none !important;
  }
}

@media print {
  #primary.editorial-post .ed-rail,
  #primary.editorial-post .ed-start,
  #primary.editorial-post .ed-progress {
    display: none;
  }

  #primary.editorial-post .ed-shell,
  #primary.editorial-post .ed-cover,
  #primary.editorial-post .ed-layout {
    width: 100%;
    max-width: none;
  }

  #primary.editorial-post .ed-cover {
    padding-top: 0;
  }

  #primary.editorial-post .ed-title {
    font-size: 65px;
  }

  #primary.editorial-post .ed-title sup {
    display: none;
  }

  #primary.editorial-post .ed-layout {
    display: block;
    padding-top: 35px;
  }

  #primary.editorial-post .ed-main > p,
  #primary.editorial-post .ed-main > ul,
  #primary.editorial-post .ed-main > ol {
    max-width: 100%;
  }

  #primary.editorial-post {
    background: white;
  }

  /* The artwork is decorative and its overlap margin is derived for screen
     type sizes, so printing it both wastes the page and mis-pulls the
     headline. */
  #primary.editorial-post .ed-masthead {
    display: none;
  }
}

/* ================================================================== *
 * Layer 2 — opt-in components
 *
 * These are reached for on a showpiece article, not every post: drop-cap
 * lead, dialogue quote, margin notes, pullquote, dark panel, numbered
 * cards, stacked layers, figure chrome, and the closing CTA. Same scope
 * rule as layer 1 — every selector is #primary.editorial-post, never
 * plain .editorial-post, or it silently loses to the theme's
 * body.single-post #primary <x> rules.
 *
 * Renamed to an ed- prefix throughout: .example, .content, .closing and
 * .layer already exist in style.css. See docs/editorial-component-reference.md
 * for the full class map and copy-paste fixture markup.
 * ================================================================== */

/* ---------------------------------------------------------------- *
 * Lead paragraph + drop cap
 * ---------------------------------------------------------------- */

#primary.editorial-post .ed-lead {
  font-size: 1.25rem;
  line-height: 1.75;
}

#primary.editorial-post .ed-lead::first-letter {
  float: left;
  font: 400 100px/0.8 var(--ed-serif);
  margin: 9px 12px 0 0;
  color: var(--ed-blue);
}

/* ---------------------------------------------------------------- *
 * Dialogue — oversized quote with a rule beneath
 * ---------------------------------------------------------------- */

#primary.editorial-post .ed-dialogue {
  position: relative;
  margin: 70px 0 60px;
  padding: 0 0 25px 35px;
}

#primary.editorial-post .ed-dialogue > .ed-eyebrow {
  display: block;
  margin-bottom: 20px;
  color: var(--ed-muted);
}

#primary.editorial-post .ed-dialogue blockquote {
  font: 100 clamp(64px, 6.8vw, 108px)/1.05 var(--ed-serif);
  letter-spacing: -0.018em;
  color: var(--ed-quote-blue);
  text-wrap: balance;
}

#primary.editorial-post .ed-dialogue em {
  color: inherit;
  font-style: normal;
  font-weight: 100;
}

/* wpautop wraps bare blockquote text in an injected <p> (WordPress does
   not touch this markup as a Gutenberg block — it runs through the
   classic auto-formatter). Without this, main.css's global `p{font-size:
   var(--font-size-body)}` (a bare element selector, but the ONLY rule
   matching that <p>) wins by default and the quote renders at 16px
   despite the blockquote itself correctly computing ~98px. Inherit
   instead of restating every value. */
#primary.editorial-post .ed-dialogue blockquote p {
  font: inherit;
  margin: 0;
}

#primary.editorial-post .ed-dialogue-rule {
  display: block;
  height: 1px;
  width: 80px;
  background: var(--ed-quote-blue);
  margin-top: 35px;
}

/* ---------------------------------------------------------------- *
 * Underline accent
 * ---------------------------------------------------------------- */

#primary.editorial-post .ed-underline {
  text-decoration: underline;
  text-decoration-color: #8eabff;
  text-underline-offset: 5px;
  text-decoration-thickness: 2px;
}

/* ---------------------------------------------------------------- *
 * Example — blue-ruled inset
 * ---------------------------------------------------------------- */

#primary.editorial-post .ed-example {
  font-size: 0.9375rem;
  line-height: 1.85;
  padding: 5px 0 5px 21px;
  border-left: 2px solid #a5bdf4;
  color: #53606a;
}

#primary.editorial-post .ed-example .ed-eyebrow {
  display: block;
  color: var(--ed-blue);
  font-size: 0.75rem;
  margin-bottom: 7px;
}

/* ---------------------------------------------------------------- *
 * Annotated row — body column + margin note
 * ---------------------------------------------------------------- */

#primary.editorial-post .ed-annotated {
  display: grid;
  grid-template-columns: minmax(0, 620px) minmax(130px, 1fr);
  gap: 40px;
}

#primary.editorial-post .ed-margin-note {
  margin-top: 10px;
  padding-top: 16px;
  border-top: 1px solid var(--ed-quote-blue);
  color: var(--ed-quote-ink);
}

#primary.editorial-post .ed-margin-note .ed-eyebrow {
  font-size: 0.75rem;
  letter-spacing: 0.09em;
}

#primary.editorial-post .ed-margin-note p {
  font: 100 36px/1.13 var(--ed-serif);
  margin-top: 18px;
}

#primary.editorial-post .ed-margin-note em {
  display: block;
  font-style: normal;
  font-weight: 100;
}

/* ---------------------------------------------------------------- *
 * Pullquote — pale blue full-width
 * ---------------------------------------------------------------- */

#primary.editorial-post .ed-pullquote {
  margin-top: 65px;
  padding: 50px 46px 34px;
  background: var(--ed-quote-paper);
  color: var(--ed-quote-ink);
}

#primary.editorial-post .ed-pullquote > .ed-eyebrow {
  display: block;
  color: var(--ed-quote-ink);
  margin-bottom: 30px;
}

#primary.editorial-post .ed-pullquote blockquote {
  font: 100 clamp(64px, 6.6vw, 104px)/1.04 var(--ed-serif);
  letter-spacing: -0.018em;
  text-wrap: balance;
}

#primary.editorial-post .ed-pullquote blockquote em {
  color: inherit;
  font-style: normal;
  font-weight: 100;
}

/* Same wpautop <p>-injection trap as .ed-dialogue above. */
#primary.editorial-post .ed-pullquote blockquote p {
  font: inherit;
  margin: 0;
}

#primary.editorial-post .ed-quote-bottom {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 25px;
  margin-top: 40px;
}

#primary.editorial-post .ed-quote-bottom > span:first-child {
  font-size: 35px;
  line-height: 1;
}

#primary.editorial-post .ed-quote-bottom > .ed-eyebrow {
  color: var(--ed-quote-ink);
  font-size: 0.75rem;
  letter-spacing: 0.08em;
  text-align: right;
}

/* ---------------------------------------------------------------- *
 * Dark panel — inverted "what if" ground
 * ---------------------------------------------------------------- */

#primary.editorial-post .ed-dark-panel {
  margin-top: 45px;
  padding: 46px;
  background: #142025;
  color: #f8f9fb;
  position: relative;
}

#primary.editorial-post .ed-dark-panel > .ed-eyebrow {
  display: block;
  color: #b5c7de;
  margin-bottom: 32px;
}

#primary.editorial-post .ed-dark-question {
  font: 100 clamp(48px, 5.2vw, 80px)/1.08 var(--ed-serif);
  letter-spacing: -0.016em;
  margin: 0 0 35px;
  color: #b9d4f5;
  text-wrap: balance;
}

#primary.editorial-post .ed-dark-question em {
  color: inherit;
  font-style: normal;
  font-weight: 100;
}

#primary.editorial-post .ed-dark-body {
  font-size: 1rem;
  line-height: 1.85;
  color: #c9d1d7;
  max-width: 470px;
  margin-left: auto;
  padding-left: 25px;
  border-left: 1px solid #627483;
}

/* .ed-dark-body sets font-size/line-height on itself, not on its <p>.
   Without this, main.css's global `p{font-size,line-height}` element
   rule is the only thing matching the <p> directly and wins over the
   inherited value from the ancestor — same trap as the blockquotes
   above, just less visually obvious since 1rem happened to coincide
   with the theme token's font-size (the line-height did not: 1.6 vs
   the intended 1.85). */
#primary.editorial-post .ed-dark-body p {
  font: inherit;
}

#primary.editorial-post .ed-dark-body p:last-child {
  margin-bottom: 0;
}

/* ---------------------------------------------------------------- *
 * Cards — two-up numbered
 * ---------------------------------------------------------------- */

#primary.editorial-post .ed-cards {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 54px 48px;
  margin-top: 44px;
}

#primary.editorial-post .ed-card {
  border-top: 1px solid var(--ed-ink);
  padding-top: 22px;
  /* Theme's `body.single-post #primary section{margin-bottom:5rem}` applies
     unopposed — this rule never declared the property. Demo had none. */
  margin-bottom: 0;
}

#primary.editorial-post .ed-card-number {
  display: block;
  color: var(--ed-muted);
  font-size: 0.75rem;
  font-variant-numeric: tabular-nums;
  margin-bottom: 19px;
}

#primary.editorial-post .ed-card h3 {
  font: 400 clamp(43px, 4.5vw, 65px)/1.04 var(--ed-serif);
  letter-spacing: -0.025em;
  margin-bottom: 24px;
}

#primary.editorial-post .ed-card h3 em {
  color: var(--ed-blue);
}

#primary.editorial-post .ed-card p {
  font-size: 1rem;
  line-height: 1.85;
  margin: 0;
}

#primary.editorial-post .ed-card:nth-child(even) {
  margin-top: 60px;
}

/* ---------------------------------------------------------------- *
 * Layers — numbered stacked rows
 * ---------------------------------------------------------------- */

#primary.editorial-post .ed-layers {
  margin: 40px 0;
}

#primary.editorial-post .ed-layer {
  display: grid;
  grid-template-columns: 55px 1fr;
  gap: 24px;
  /* Theme's `body.single-post #primary section{margin-bottom:5rem}` applies
     unopposed — this rule never declared the property. Demo had none. */
  margin-bottom: 0;
  padding: 29px 0;
  border-top: 1px solid var(--ed-line);
}

#primary.editorial-post .ed-layer:last-child {
  border-bottom: 1px solid var(--ed-line);
}

#primary.editorial-post .ed-layer-index {
  font: 400 32px/1 var(--ed-serif);
  color: var(--ed-blue);
  padding-top: 4px;
}

#primary.editorial-post .ed-layer h3 {
  font: 400 38px/1.15 var(--ed-serif);
  letter-spacing: -0.015em;
  margin-bottom: 13px;
}

#primary.editorial-post .ed-layer p {
  font-size: 1rem;
  line-height: 1.85;
  margin: 0;
  max-width: 605px;
}

/* ---------------------------------------------------------------- *
 * Risk — numbered sub-section. Not shown in the fixture, but carried
 * from the demo source per the brief's source-range list; the
 * risk-number name is not in the contractual class map, so it follows
 * the same ed- convention as .ed-card-number / .ed-layer-index.
 * ---------------------------------------------------------------- */

#primary.editorial-post .ed-risk {
  margin-top: 45px;
}

#primary.editorial-post .ed-risk h3 {
  font: 400 clamp(31px, 2.65vw, 40px)/1.15 var(--ed-serif);
  letter-spacing: -0.012em;
  display: flex;
  align-items: baseline;
  gap: 15px;
  margin-bottom: 20px;
  max-width: 740px;
}

#primary.editorial-post .ed-risk-number {
  font: 500 0.75rem/1.4 var(--ed-sans);
  color: var(--ed-blue);
  letter-spacing: 0.04em;
  white-space: nowrap;
}

#primary.editorial-post .ed-risk > p {
  padding-left: 39px;
}

/* ---------------------------------------------------------------- *
 * Figure chrome — the reusable shell every future figure gets.
 * The diagram's OWN layout (.context-diagram, .context-connections,
 * .diagram-row, .shared-context, etc.) is one-off content and travels
 * with the article body in Task 8. Do not add it here.
 * ---------------------------------------------------------------- */

#primary.editorial-post .ed-figure {
  border: 1px solid var(--ed-line);
  background: #fff;
  margin: 44px 0;
  overflow: hidden;
}

#primary.editorial-post .ed-figure-top {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  padding: 23px 25px 0;
}

#primary.editorial-post .ed-figure-top > .ed-eyebrow {
  color: var(--ed-muted);
}

#primary.editorial-post .ed-mode-control {
  display: flex;
  border: 1px solid var(--ed-line);
  padding: 3px;
  border-radius: 5px;
  background: var(--ed-paper);
}

#primary.editorial-post .ed-mode-control button {
  border: 0;
  background: transparent;
  color: var(--ed-muted);
  padding: 9px 14px;
  min-height: 38px;
  font-size: 0.75rem;
  cursor: pointer;
  border-radius: 3px;
  transition: background 0.3s, color 0.3s, box-shadow 0.3s;
}

/* Mode-switcher state hook. The demo drove this off [data-mode=multi];
   the template drives it off data-ed-mode + aria-pressed instead. */
#primary.editorial-post .ed-mode-control button[aria-pressed='true'] {
  background: var(--ed-ink);
  color: #fff;
  box-shadow: 0 1px 4px #14202510;
}

#primary.editorial-post .ed-figure[data-ed-mode='multi'] .ed-mode-control button[aria-pressed='true'] {
  background: var(--ed-blue);
}

#primary.editorial-post .ed-figcaption {
  padding: 16px 25px;
  border-top: 1px solid var(--ed-line);
  display: flex;
  gap: 20px;
  align-items: center;
  line-height: 1.6;
  font-size: 0.75rem;
  color: var(--ed-muted);
}

#primary.editorial-post .ed-fig-index {
  color: var(--ed-blue);
  font-size: 0.75rem;
  letter-spacing: 0.08em;
  flex-shrink: 0;
}

/* ---------------------------------------------------------------- *
 * Product figure — screenshot figure. Not shown in the fixture, but
 * carried from the demo source per the brief's source-range list.
 * .ed-product-image is not in the contractual class map; it names the
 * inner screenshot mount following the same ed- convention.
 * ---------------------------------------------------------------- */

#primary.editorial-post .ed-product-figure {
  margin: 45px 0 40px;
}

#primary.editorial-post .ed-product-figure .ed-product-image {
  padding: 24px 24px 0;
  background: #e2eafb;
  border: 1px solid #cbd9ef;
  overflow: hidden;
  max-height: 530px;
}

#primary.editorial-post .ed-product-figure .ed-product-image img {
  width: 100%;
  height: auto;
  border-radius: 6px 6px 0 0;
  box-shadow: 0 8px 24px #14202515;
}

#primary.editorial-post .ed-product-figure figcaption {
  display: flex;
  align-items: baseline;
  gap: 16px;
  margin-top: 15px;
  font-size: 0.75rem;
  line-height: 1.6;
  color: var(--ed-muted);
}

#primary.editorial-post .ed-product-figure figcaption a {
  margin-left: auto;
  flex-shrink: 0;
  color: var(--ed-ink);
  text-decoration: none;
}

#primary.editorial-post .ed-product-figure figcaption a:hover {
  color: var(--ed-blue);
}

#primary.editorial-post .ed-product-figure figcaption a span {
  margin-left: 7px;
}

/* ---------------------------------------------------------------- *
 * Closing — CTA section
 * ---------------------------------------------------------------- */

#primary.editorial-post .ed-closing {
  display: grid;
  grid-template-columns: 1.3fr 1fr;
  gap: 8%;
  padding-block: 60px 70px;
  border-top: 1px solid var(--ed-ink);
  /* Theme's `body.single-post #primary section{margin-bottom:5rem}` applies
     unopposed — this rule never declared the property. Demo had none. */
  margin-bottom: 0;
}

#primary.editorial-post .ed-closing > div:first-child > .ed-eyebrow {
  display: block;
  color: var(--ed-blue);
  margin-bottom: 30px;
}

#primary.editorial-post .ed-closing h2 {
  font: 400 clamp(48px, 4.8vw, 73px)/1.04 var(--ed-serif);
  letter-spacing: -0.025em;
  color: var(--ed-ink);
}

#primary.editorial-post .ed-closing h2 em {
  color: var(--ed-blue);
}

#primary.editorial-post .ed-closing > div:last-child {
  padding-top: 48px;
  font-size: 1rem;
  line-height: 1.85;
}

/* Same wpautop/global-p trap: the "Closing copy" text lives in a <p>
   that never got directly targeted, so it drew the theme's global
   line-height instead of inheriting 1.85 from the div above. */
#primary.editorial-post .ed-closing > div:last-child p {
  font: inherit;
}

/* ---------------------------------------------------------------- *
 * Customer logo row. This block never had a rule, so the four <img>
 * fell back to the theme's global `img { display: block }` and stacked
 * one per line. Flex puts them back on a single baseline-aligned row;
 * the height normalises four different intrinsic sizes (55x35, 40x40,
 * 39x39, 37x37) to one optical scale. Width stays `auto` so the
 * width/height attributes supply the aspect ratio while Smush's
 * lazyload placeholder is still standing in for the real SVG.
 * ---------------------------------------------------------------- */

#primary.editorial-post .ed-brand-line {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 26px;
  margin: 26px 0 34px;
}

#primary.editorial-post .ed-brand-line img {
  display: block;
  width: auto;
  height: 30px;
  max-width: none;
  flex: 0 0 auto;
}

#primary.editorial-post .ed-cta {
  width: 100%;
  background: none;
  border-left: 0;
  border-right: 0;
  text-align: left;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 22px;
  padding: 19px 0;
  border-top: 1px solid var(--ed-line);
  border-bottom: 1px solid var(--ed-ink);
  color: var(--ed-blue);
  text-decoration: none;
  font-size: 0.875rem;
  font-weight: 600;
  line-height: 1.65;
  margin-top: 31px;
}

#primary.editorial-post .ed-cta > span:last-child {
  font-size: 26px;
  margin-left: auto;
  transition: transform 0.2s;
}

#primary.editorial-post .ed-cta:hover > span:last-child {
  transform: translate(3px, -3px);
}

/* ---------------------------------------------------------------- *
 * Reveal contract. Task 6's IntersectionObserver adds will-reveal only
 * to elements below 92% of viewport height, then is-visible when they
 * scroll in. A bare .reveal with neither modifier must stay visible —
 * this is progressive enhancement, not a hide-by-default animation.
 * ---------------------------------------------------------------- */

#primary.editorial-post .reveal.will-reveal {
  opacity: 0;
  transform: translateY(22px);
  transition: opacity 0.85s ease, transform 0.85s cubic-bezier(0.2, 0.65, 0.3, 1);
}

#primary.editorial-post .reveal.will-reveal.is-visible {
  opacity: 1;
  transform: translateY(0);
}

@media (prefers-reduced-motion: reduce) {
  #primary.editorial-post *,
  #primary.editorial-post *::before,
  #primary.editorial-post *::after {
    animation: none !important;
    transition: none !important;
  }

  #primary.editorial-post .reveal.will-reveal {
    opacity: 1;
    transform: none;
  }
}

/* ---------------------------------------------------------------- *
 * Responsive — layer 2
 * ---------------------------------------------------------------- */

@media (max-width: 1200px) {
  #primary.editorial-post .ed-annotated {
    grid-template-columns: minmax(0, 1fr);
  }

  #primary.editorial-post .ed-margin-note {
    margin-top: 8px;
    max-width: 360px;
    margin-left: 60px;
    padding-top: 15px;
  }

  #primary.editorial-post .ed-margin-note p {
    font-size: 36px;
  }

  #primary.editorial-post .ed-margin-note em {
    display: inline;
  }
}

@media (max-width: 1100px) {
  #primary.editorial-post .ed-cards {
    gap: 42px 30px;
  }

  #primary.editorial-post .ed-card h3 {
    font-size: 49px;
  }

  #primary.editorial-post .ed-dark-question br {
    display: none;
  }

  #primary.editorial-post .ed-pullquote {
    padding: 34px;
  }

  #primary.editorial-post .ed-dark-panel {
    padding: 34px;
  }

  #primary.editorial-post .ed-closing {
    gap: 6%;
    grid-template-columns: 1.2fr 1fr;
  }

  #primary.editorial-post .ed-closing h2 {
    font-size: 58px;
  }
}

@media (max-width: 900px) {
  #primary.editorial-post .ed-annotated {
    grid-template-columns: minmax(0, 1fr) 155px;
    gap: 28px;
  }

  #primary.editorial-post .ed-annotated .ed-margin-note {
    margin-left: 0;
    margin-top: 8px;
  }

  #primary.editorial-post .ed-margin-note p {
    font-size: 33px;
  }

  #primary.editorial-post .ed-margin-note em {
    display: block;
  }

  #primary.editorial-post .ed-dialogue blockquote {
    font-size: clamp(62px, 9.5vw, 82px);
  }

  #primary.editorial-post .ed-card h3 {
    font-size: 55px;
  }

  #primary.editorial-post .ed-pullquote blockquote {
    font-size: 76px;
  }

  #primary.editorial-post .ed-dark-question {
    font-size: 64px;
  }

  #primary.editorial-post .ed-closing {
    max-width: 740px;
    grid-template-columns: 1fr;
    padding-block: 45px 55px;
    gap: 30px;
  }

  #primary.editorial-post .ed-closing h2 {
    font-size: 64px;
  }

  #primary.editorial-post .ed-closing > div:last-child {
    padding-top: 0;
    max-width: 620px;
  }
}

@media (max-width: 600px) {
  #primary.editorial-post .ed-lead {
    font-size: 1.125rem;
  }

  #primary.editorial-post .ed-lead::first-letter {
    font-size: 83px;
  }

  #primary.editorial-post .ed-dialogue {
    padding-left: 0;
    margin: 46px 0;
  }

  #primary.editorial-post .ed-dialogue blockquote {
    font-size: clamp(46px, 12vw, 68px);
    line-height: 1.05;
  }

  #primary.editorial-post .ed-annotated {
    grid-template-columns: minmax(0, 1fr);
    gap: 25px;
  }

  #primary.editorial-post .ed-annotated .ed-margin-note {
    margin: 0 0 0 40px;
    max-width: 260px;
  }

  #primary.editorial-post .ed-margin-note p {
    font-size: 35px;
    margin-bottom: 8px;
  }

  #primary.editorial-post .ed-margin-note em {
    display: inline;
  }

  #primary.editorial-post .ed-figure-top {
    padding: 20px 16px 0;
    flex-wrap: wrap;
    gap: 14px;
  }

  #primary.editorial-post .ed-mode-control {
    width: 100%;
  }

  #primary.editorial-post .ed-mode-control button {
    flex: 1;
    min-height: 42px;
    font-size: 0.75rem;
  }

  #primary.editorial-post .ed-figcaption {
    padding: 14px 16px;
    gap: 13px;
    font-size: 0.75rem;
    min-height: 66px;
  }

  #primary.editorial-post .ed-risk {
    margin-top: 35px;
  }

  #primary.editorial-post .ed-risk h3 {
    font-size: 31px;
    gap: 12px;
  }

  #primary.editorial-post .ed-risk > p {
    padding-left: 0;
  }

  #primary.editorial-post .ed-pullquote {
    padding: 27px 24px 24px;
    margin-top: 38px;
  }

  #primary.editorial-post .ed-pullquote blockquote {
    font-size: clamp(44px, 11.5vw, 62px);
    line-height: 1.06;
  }

  #primary.editorial-post .ed-pullquote blockquote br {
    display: none;
  }

  #primary.editorial-post .ed-pullquote > .ed-eyebrow {
    margin-bottom: 25px;
  }

  #primary.editorial-post .ed-quote-bottom {
    margin-top: 30px;
    gap: 20px;
  }

  #primary.editorial-post .ed-quote-bottom > .ed-eyebrow {
    font-size: 0.75rem;
    letter-spacing: 0.05em;
  }

  #primary.editorial-post .ed-quote-bottom > span:first-child {
    font-size: 27px;
  }

  #primary.editorial-post .ed-dark-panel {
    padding: 28px 24px;
    margin-top: 33px;
  }

  #primary.editorial-post .ed-dark-question {
    font-size: clamp(42px, 10.5vw, 58px);
    line-height: 1.08;
    margin-bottom: 28px;
  }

  #primary.editorial-post .ed-dark-body {
    font-size: 1rem;
    padding-left: 18px;
  }

  #primary.editorial-post .ed-dark-panel > .ed-eyebrow {
    margin-bottom: 26px;
  }

  #primary.editorial-post .ed-cards {
    grid-template-columns: 1fr;
    gap: 32px;
    margin-top: 33px;
  }

  #primary.editorial-post .ed-card:nth-child(even) {
    margin-top: 0;
  }

  #primary.editorial-post .ed-card h3 {
    font-size: 51px;
    margin-bottom: 20px;
  }

  #primary.editorial-post .ed-card-number {
    margin-bottom: 13px;
  }

  #primary.editorial-post .ed-card h3 br {
    display: none;
  }

  #primary.editorial-post .ed-layer {
    grid-template-columns: 30px 1fr;
    gap: 16px;
    padding: 24px 0;
  }

  #primary.editorial-post .ed-layer-index {
    font-size: 26px;
  }

  #primary.editorial-post .ed-layer h3 {
    font-size: 32px;
  }

  #primary.editorial-post .ed-product-figure .ed-product-image {
    max-height: 330px;
    padding: 13px 13px 0;
  }

  #primary.editorial-post .ed-product-figure figcaption {
    gap: 10px;
    flex-wrap: wrap;
  }

  #primary.editorial-post .ed-product-figure figcaption a {
    margin-left: 0;
    flex-basis: 100%;
    padding-left: 68px;
  }

  #primary.editorial-post .ed-closing {
    padding-block: 35px 42px;
  }

  #primary.editorial-post .ed-closing h2 {
    font-size: 47px;
  }

  #primary.editorial-post .ed-closing > div:first-child > .ed-eyebrow {
    margin-bottom: 23px;
  }
}

/* ---------------------------------------------------------------- *
 * Multiplayer cursor masthead
 *
 * The artwork bleeds past the cover's content column and the headline
 * overlaps its lower edge, so the two read as one composition rather
 * than [animation card] + [headline]. No card treatment: no border, no
 * radius, no shadow — the page itself is the canvas.
 * ---------------------------------------------------------------- */

#primary.editorial-post .ed-masthead {
  position: relative;
  /* Break out of the cover's gutter on both sides. Peripheral cursors
     crop at the edges on purpose — one slice of a larger system. */
  width: calc(100% + var(--ed-gutter) * 2);
  margin-inline: calc(var(--ed-gutter) * -1);
  /* Pulls the artwork's top edge up behind the transparent header (2026-09-17)
     so the ~96px band of bare paper between the notification bar and the
     artwork — logo + nav links sitting on empty ground above dense artwork —
     stops reading as a stripe. #masthead is position:relative with z-index:1
     and this element carries none, so the header already paints above the
     artwork; the nav is unaffected in stacking order. Derived per breakpoint
     from the header's own measured height (see tools/ed-check.mjs against
     #masthead), not scaled from this value — the header is a different
     height at each tier. -100px lands the artwork's top just under the
     notification bar at 1440/1024 (header 49-145). */
  margin-top: -52px;
  /* Pulls the headline up into the artwork's lower band. Derived, not
     eyeballed: the H1's line-height of 0.98 puts ~40px of leading above
     the capitals at 134px type, and pulling the title up moves that ink
     threshold with it, so the overlap only becomes visible past ~16px of
     extra pull. The swarm's lowest cursor also swings ~11px as the sphere
     turns (644-655 measured), so the margin has to clear the WORST frame,
     not the average one. -95px leaves ~13px of headroom. */
  margin-bottom: -95px;
  pointer-events: none;
}

#primary.editorial-post .ed-orbit {
  display: block;
  width: 100%;
  height: auto;
  /* 375, not the artboard's own 400: the SVG carries
     preserveAspectRatio="xMidYMid slice", so a shorter box crops the
     artboard vertically rather than scaling the sphere down. That buys
     30px at 1440 toward getting the whole H1 above a MacBook fold, at the
     cost of a little more crop on the sphere's top cap — which the spec
     explicitly welcomes ("some peripheral cursors may intentionally crop").
     The viewBox itself is unchanged at 0 0 1200 400. */
  aspect-ratio: 1200 / 375;
  overflow: hidden;
}

#primary.editorial-post .ed-orbit text {
  font-family: var(--ed-sans);
  letter-spacing: 0.01em;
}

/* The headline sits above the artwork in the stacking order so the
   overlap never costs readability. */
#primary.editorial-post .ed-cover .ed-title {
  position: relative;
  z-index: 1;
}

/* Breathing, not pulsing: a 5s ease-in-out cycle over a 20% scale range.
   transform-box: fill-box lets transform-origin: center resolve against the
   circle's own bounding box instead of the SVG user-space origin. */
#primary.editorial-post .ed-orbit-ring {
  transform-box: fill-box;
  transform-origin: center;
  animation: ed-orbit-breathe 5s ease-in-out infinite;
}

@keyframes ed-orbit-breathe {
  0%,
  100% {
    transform: scale(0.9);
  }
  50% {
    transform: scale(1.1);
  }
}

/* The eyebrow is gone (2026-09-17), and the paper background now runs
   behind the transparent header, so the artwork sits almost directly
   under the nav — the cover's top padding shrinks to a hairline instead
   of the negative space the eyebrow used to need above it. */
/* Desktop only. Unscoped, this would silently kill the existing mobile
   and print rhythm: the .ed-cover rule ties the max-width:900px and
   :600px rules at (1,2,0) but is later in source order, so it would win
   there and in @media print too — a landscape Letter page is ~1056px
   wide, well past this min-width. The `screen` keyword below is what
   actually excludes print; Task 6 owns the breakpoints and this task
   must not reach into them. */
@media screen and (min-width: 901px) {
  #primary.editorial-post .ed-cover {
    padding-top: 6px;
  }
}

/* Atmosphere, drifting slowly enough that you never catch it moving.
   Two different periods and two different paths so the pair never
   visibly resynchronises. */
#primary.editorial-post .ed-orbit-wash-blob {
  transform-box: fill-box;
  transform-origin: center;
}

#primary.editorial-post .ed-orbit-wash-blob:first-child {
  animation: ed-orbit-drift-a 29s ease-in-out infinite;
}

#primary.editorial-post .ed-orbit-wash-blob:last-child {
  animation: ed-orbit-drift-b 41s ease-in-out infinite;
}

@keyframes ed-orbit-drift-a {
  0%,
  100% {
    transform: translate(0, 0) scale(1);
  }
  50% {
    transform: translate(46px, 20px) scale(1.09);
  }
}

@keyframes ed-orbit-drift-b {
  0%,
  100% {
    transform: translate(0, 0) scale(1.06);
  }
  50% {
    transform: translate(-38px, -24px) scale(1);
  }
}

/* ---------------------------------------------------------------- *
 * Masthead responsive tuning (Task 6).
 *
 * The artboard is re-proportioned per breakpoint, not shrunk. Only
 * `height` is ever overridden here — `aspect-ratio` stays declared as
 * `1200 / 400` from the base rule above at every width, so
 * getComputedStyle(...).aspectRatio is never `auto` (masthead-layout.mjs's
 * reservesItsBox depends on that). Because host width tracks the viewport
 * 1:1 (the masthead's bleed formula cancels the gutter exactly below the
 * ~1344px shell cap) and preserveAspectRatio="xMidYMid slice" scales the
 * fixed 1200x400 viewBox to COVER the box, forcing a shorter `height`
 * while leaving width alone raises the cover scale factor and crops the
 * artboard horizontally — the sphere gets bigger and its edges run off
 * screen, rather than the whole composition shrinking into a motif.
 *
 * margin-bottom is re-derived at each tier (not scaled from the desktop
 * value) because the headline's ink threshold moves with its own
 * font-size, which itself steps at 1200/900/600 via clamp() and the
 * .ed-title rules above — see masthead-layout.mjs's __worstSwarmBottom /
 * __inkThreshold / __titleTop for the numbers behind each value below.
 * ---------------------------------------------------------------- */

@media (max-width: 1200px) {
  #primary.editorial-post .ed-orbit {
    height: 460px;
  }

  #primary.editorial-post .ed-masthead {
    /* Header height unchanged from the >1200 tier at 1024 (49-145), so
       this matches the base rule's -100px — set explicitly per the
       per-tier convention rather than left to inherit. */
    margin-top: -52px;
    margin-bottom: -89px;
  }
}

@media (max-width: 900px) {
  #primary.editorial-post .ed-orbit {
    height: 460px;
  }

  #primary.editorial-post .ed-masthead {
    /* The mobile nav collapse shortens the header (49-141 at 768) versus
       the desktop tiers (49-145), so this needs its own, larger pull. */
    margin-top: -74px;
    margin-bottom: -88px;
  }
}

/* R22: the phone/tablet line is 500px, not 760px. With slice cover-scaling
   pinning the sphere at 0.925 * height regardless of viewport width, and
   the phone rule (masthead-responsive.mjs) demanding it scale with vw, the
   two constraints are mutually unsatisfiable across 540-760px at a single
   fixed height. 500px is where the artwork switches from the phone
   treatment (large sphere floor, 300-370px band) to the taller tablet one
   shared with the 900px tier. */
@media (max-width: 500px) {
  #primary.editorial-post .ed-orbit {
    height: 352px;
  }

  #primary.editorial-post .ed-masthead {
    /* Notification bar wraps taller at this width (bar bottom 62 vs 49),
       and the header itself is 92px (62-154) — re-derived, not scaled
       from the desktop value. Also covers the 430px tier below, which
       measures identically and does not need its own override. */
    margin-top: -69px;
    margin-bottom: -63px;
  }
}

@media (max-width: 430px) {
  #primary.editorial-post .ed-orbit {
    height: 336px;
  }

  #primary.editorial-post .ed-masthead {
    margin-bottom: -68px;
  }
}

/* Reduced motion: hold the composition still. The artwork stays fully
   visible — a carefully chosen static frame is the deliverable, not a
   hidden illustration. */
/* Redundant with the blanket `#primary.editorial-post * { animation: none
   !important }` in the reduced-motion blocks above, and deliberately kept:
   masthead-a11y.mjs asserts that a reduced-motion rule naming `ed-orbit`
   exists, so this block is the explicit, greppable statement of intent for
   the masthead specifically. Do not delete it as redundant. */
@media (prefers-reduced-motion: reduce) {
  #primary.editorial-post .ed-orbit-ring,
  #primary.editorial-post .ed-orbit-wash-blob {
    animation: none;
  }

  #primary.editorial-post .ed-orbit-ring {
    transform: scale(1);
  }
}

/* Restates the scrim gradient's stop-color as a CSS declaration, which
   beats the presentation attribute in every engine and keeps --ed-paper
   the source of truth. The attribute itself carries a literal hex because
   WebKit does not reliably resolve var() in SVG presentation attributes,
   and the fallback there is black. */
#primary.editorial-post #ed-orbit-scrim-grad stop {
  stop-color: var(--ed-paper);
}
