/* Scarlet Citadel -- Finished HTML. Layout, palette and panel mechanics
   adapted from the Analects prototype (C:\Users\adam\Documents\AI\Project\_Shared\AL\_Prototype\Analects\analects.css).
   The publication has no right-side page rail: there is no Source PDF for
   this work, so no page geometry exists to mark (Captain's ruling). The
   prototype's --source-rail / --source-label reservation and its
   .source-page-origin markers are simply not part of this stylesheet -- the
   reading column takes the full measure instead of a rail being zeroed out. */

:root {
  --parchment: #f6f1e7;
  --parchment-mid: #eee7d6;
  --parchment-dark: #ddd3bd;
  --ink: #211c15;
  --ink-mid: #44392d;
  --ink-light: #665746;
  --rust: #842727;
  --rust-light: #a13a32;
  --gold: #7b6326;
  --rule: #c5b48f;
  --shadow: rgba(30, 25, 18, 0.16);
  /* Title-plate size lives here as one named number so it can be tried live
     without touching a rule:
       document.documentElement.style.setProperty('--plate-width','560px')
     This caps the FRAMED box.  box-sizing is border-box, so the 5px frame on
     each side is spent from it -- the picture itself lands 10px narrower. */
  --plate-width: 610px;
  --contents-panel-width: 16rem;
  --header-height: 3.55rem;
  --section-bar-height: 2.15rem;
  --body: "Iowan Old Style", "Palatino Linotype", "Book Antiqua", Georgia, serif;
  --display: "Palatino Linotype", "Book Antiqua", Georgia, serif;
  /* Formerly hard-coded outside the token set (16 values, Captain-ordered
     dark-mode audit, post-production edit 2026-09-03): each is used at
     least once below and now lives here so a theme switch can retarget it.
     Names describe role, not the light value, since dark mode gives each a
     different value. */
  --paper-highlight: rgba(255, 255, 255, 0.82);
  --paper-texture: rgba(83, 64, 32, 0.018);
  --on-accent: white;
  --header-text: #f8f1df;
  --header-bg: rgba(32, 27, 20, 0.97);
  --header-shadow: rgba(0, 0, 0, 0.2);
  --toggle-hover-color: #e3c46b;
  --toggle-hover-bg: rgba(255, 255, 255, 0.08);
  --nav-separator: #d7b85b;
  --nav-meta: rgba(248, 241, 223, 0.82);
  --link-hover-bg-strong: rgba(132, 39, 39, 0.07);
  --backdrop-bg: rgba(22, 18, 14, 0.42);
  --footer-text: #eee3ca;
  --footer-bg: #241f18;
  --title-ink: #1e1913;
  --panel-link-bg: rgba(255, 255, 255, 0.3);
  /* Palette-parity tokens (post-production edit, Captain's ruling
     2026-09-03): Sunzi-war's design tokens, copied verbatim so the two
     builds' contents-panel component is byte-for-byte the same palette.
     --note-bg/--note-border/--link-hover-bg/--panel-highlight did not
     previously exist in this stylesheet -- the carded Dark Mode control
     and the .display-toggle-* family adopted below need them. */
  --note-bg: #eee5cf;
  --note-border: #c0a070;
  --link-hover-bg: rgba(132, 39, 39, 0.06);
  --panel-highlight: rgba(255, 255, 255, 0.28);
  color-scheme: light;
}

/* ---- Dark mode (Captain-ordered, post-production edit 2026-09-03) --------
   Two paths reach the same palette: the System path follows the OS via
   prefers-color-scheme, suppressed when the reader has explicitly chosen
   Off (:root[data-theme="light"]); the explicit On path is
   :root[data-theme="dark"] and always wins regardless of the OS setting.
   This is a pulp-adventure text, not a generic inverted website, so hue is
   kept close to the light values -- warm ink on a dark citadel-stone paper --
   only lightness/direction flips. Rust and gold are brightened (not merely
   lightened) to clear 4.5:1 against the dark paper while still reading as
   the same two accent colours; --on-accent flips to a dark ink so button
   text stays legible against the now-bright rust. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    --parchment: #1b1712;
    --parchment-mid: #241f18;
    --parchment-dark: #2c251c;
    --ink: #e8dfc9;
    --ink-mid: #c9bc9c;
    --ink-light: #a89877;
    --rust: #e0785f;
    --rust-light: #ef9478;
    --gold: #d4af5a;
    --rule: #4a4030;
    --shadow: rgba(0, 0, 0, 0.5);
    --paper-highlight: rgba(255, 240, 210, 0.045);
    --paper-texture: rgba(0, 0, 0, 0.32);
    --on-accent: #1b1712;
    --header-text: #f3e8d0;
    --header-bg: rgba(20, 16, 12, 0.97);
    --header-shadow: rgba(0, 0, 0, 0.5);
    --toggle-hover-color: #f0c979;
    --toggle-hover-bg: rgba(255, 255, 255, 0.12);
    --nav-separator: #d8ae55;
    --nav-meta: rgba(243, 232, 208, 0.82);
    --link-hover-bg-strong: rgba(226, 118, 90, 0.16);
    --backdrop-bg: rgba(0, 0, 0, 0.6);
    --footer-text: #ece0c8;
    --footer-bg: #14100c;
    --title-ink: #f2e6cd;
    --panel-link-bg: rgba(255, 255, 255, 0.06);
    --note-bg: #2a2318;
    --note-border: #6b5636;
    --link-hover-bg: rgba(224, 120, 95, 0.14);
    --panel-highlight: rgba(255, 255, 255, 0.06);
  }
}

:root[data-theme="dark"] {
  color-scheme: dark;
  --parchment: #1b1712;
  --parchment-mid: #241f18;
  --parchment-dark: #2c251c;
  --ink: #e8dfc9;
  --ink-mid: #c9bc9c;
  --ink-light: #a89877;
  --rust: #e0785f;
  --rust-light: #ef9478;
  --gold: #d4af5a;
  --rule: #4a4030;
  --shadow: rgba(0, 0, 0, 0.5);
  --paper-highlight: rgba(255, 240, 210, 0.045);
  --paper-texture: rgba(0, 0, 0, 0.32);
  --on-accent: #1b1712;
  --header-text: #f3e8d0;
  --header-bg: rgba(20, 16, 12, 0.97);
  --header-shadow: rgba(0, 0, 0, 0.5);
  --toggle-hover-color: #f0c979;
  --toggle-hover-bg: rgba(255, 255, 255, 0.12);
  --nav-separator: #d8ae55;
  --nav-meta: rgba(243, 232, 208, 0.82);
  --link-hover-bg-strong: rgba(226, 118, 90, 0.16);
  --backdrop-bg: rgba(0, 0, 0, 0.6);
  --footer-text: #ece0c8;
  --footer-bg: #14100c;
  --title-ink: #f2e6cd;
  --panel-link-bg: rgba(255, 255, 255, 0.06);
  --note-bg: #2a2318;
  --note-border: #6b5636;
  --link-hover-bg: rgba(224, 120, 95, 0.14);
  --panel-highlight: rgba(255, 255, 255, 0.06);
}

:root[data-theme="light"] {
  color-scheme: light;
}

/* Preserved artefacts: image files themselves are never touched. Dark mode
   only dims them slightly so a bright scan does not glare on a dark page.
   Both of this edition's two <img> elements are .cover-figure img (the
   title-page plate and the mid-document Weird Tales plate); the bare `img`
   rule below never actually paints an element, since .cover-figure img
   (same (0,1,1) specificity, later in the cascade) always overrides it, so
   the dark override targets .cover-figure img directly and out-specifies
   it with the extra attribute/class selector rather than relying on
   source order. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .cover-figure img {
    filter: brightness(0.85);
  }
}

:root[data-theme="dark"] .cover-figure img {
  filter: brightness(0.85);
}

* { box-sizing: border-box; }

html {
  scroll-behavior: auto;
  scroll-padding-top: calc(var(--header-height) + var(--section-bar-height) + 0.75rem);
}

body {
  margin: 0;
  color: var(--ink);
  background:
    radial-gradient(circle at 18% 10%, var(--paper-highlight), transparent 34rem),
    repeating-linear-gradient(0deg, var(--paper-texture) 0, var(--paper-texture) 1px, transparent 1px, transparent 4px),
    var(--parchment);
  font-family: var(--body);
  font-size: clamp(1.06rem, 0.98rem + 0.24vw, 1.24rem);
  line-height: 1.58;
  text-rendering: optimizeLegibility;
}

a { color: var(--rust); text-decoration-thickness: 0.08em; text-underline-offset: 0.16em; }
a:hover { color: var(--rust-light); }

.skip-link {
  position: fixed;
  z-index: 100;
  top: 0.5rem;
  left: 0.5rem;
  padding: 0.65rem 1rem;
  color: var(--on-accent);
  background: var(--rust);
  transform: translateY(-150%);
}
.skip-link:focus { transform: none; }

.site-header {
  position: sticky;
  z-index: 30;
  top: 0;
  color: var(--header-text);
  background: var(--header-bg);
  border-bottom: 2px solid var(--gold);
  box-shadow: 0 0.25rem 1rem var(--header-shadow);
}

/* Floating section-title bar (post-production edit, 2026-09-03; ported from
   the Sunzi-war build's CAP-011): a second, slimmer sticky strip directly
   beneath .site-header, showing the current chapter's title as the reader
   scrolls. Reserves its height at all times so the reading column never
   jumps when it fills in; only its own opacity/visibility toggle when a
   section is known. No Part concept in this work, so no part span/
   separator -- just the title. */
.section-bar {
  position: sticky;
  z-index: 25;
  top: var(--header-height);
  display: flex;
  align-items: center;
  min-height: var(--section-bar-height);
  padding: 0;
  color: var(--ink-light);
  background: var(--parchment-mid);
  border-bottom: 1px solid var(--rule);
  box-shadow: 0 0.15rem 0.4rem var(--shadow);
  font-family: var(--display);
  font-size: 0.72rem;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  opacity: 0;
  visibility: hidden;
  transform: translateY(-0.35rem);
  transition: opacity 160ms ease, transform 160ms ease, visibility 0s linear 160ms;
}

.section-bar.is-visible {
  opacity: 1;
  visibility: visible;
  transform: none;
  transition: opacity 160ms ease, transform 160ms ease;
}

/* Inner wrapper mirrors main's own max-width/margin-inline/padding rule
   (below) so the title's left edge tracks the running text column's left
   edge at every viewport. No Contents-open override is needed here: per
   the 2026-08-24 centring-defect fix (see the comment above the
   .contents-open block near the end of this stylesheet), the panel inset
   is applied as `padding-left` on body itself, not as a margin on main --
   so .section-bar, an ordinary sticky flow child of body exactly like
   main, has its own content box narrowed by body's padding in lockstep
   with main's. This wrapper's "100%" is already main's own content-box
   width in both states; no escape/re-offset trick required, and none is
   applied, matching .section-bar's existing (pre-edit) inset behaviour. */
.section-bar-inner {
  max-width: 52rem;
  width: 100%;
  height: 100%;
  margin-inline: auto;
  padding: 0 1.5rem;
  box-sizing: border-box;
  display: flex;
  align-items: center;
}

.site-nav {
  width: min(100% - 2rem, 76rem);
  min-height: var(--header-height);
  margin-inline: auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  font-family: var(--display);
  font-size: 0.72rem;
  letter-spacing: 0.055em;
  text-transform: uppercase;
}

.nav-leading { min-width: 0; flex: 1; display: flex; align-items: center; gap: 0.75rem; }
.site-nav a { color: inherit; text-decoration: none; }

.contents-toggle, .contents-close, .contents-backdrop { border: 0; font: inherit; cursor: pointer; }

.contents-toggle {
  width: 2.25rem; height: 2.25rem; padding: 0;
  display: grid; place-items: center;
  color: var(--header-text); background: transparent; border-radius: 0.25rem;
  font-family: var(--body); font-size: 1.2rem; line-height: 1;
}
.contents-toggle:hover, .contents-toggle[aria-expanded="true"] {
  color: var(--toggle-hover-color); background: var(--toggle-hover-bg);
}

.nav-brand { min-width: 0; display: flex; flex-wrap: wrap; align-items: baseline; column-gap: 0.55rem; row-gap: 0.08rem; font-size: 0.86rem; line-height: 1.3; }
.nav-title { white-space: nowrap; }
.nav-meta-group { display: inline-flex; align-items: baseline; gap: 0.55rem; white-space: nowrap; }
.nav-separator { color: var(--nav-separator); font-size: 0.68rem; }
.nav-meta { color: var(--nav-meta); font-size: 0.54rem; letter-spacing: 0.045em; }
.top-link { white-space: nowrap; }

main {
  min-height: 100vh;
  transition: margin-left 180ms ease;
  overflow-x: clip;
  max-width: 52rem;
  margin-inline: auto;
  /* Captain order, 2026-09-28 (About box): bottom padding clamp(4rem, 8vw, 6rem)
     -> 0. The About box is now main's last element and carries Analects' own
     5rem margin-bottom (see .source-note below), so box -> footer reads 80px
     as in Analects instead of 80px stacked on this padding. */
  padding: clamp(2rem, 6vw, 4rem) 1.5rem 0;
}

/* --- publication content: carried over unchanged from BasicHTML, styled
   in place. No wrapper divs were introduced around it. --- */

h1, h2, h3, h4 {
  font-family: var(--display);
  font-weight: 400;
  text-align: center;
  color: var(--ink);
  margin: 1.4em 0 0.6em;
}
h1 { font-size: clamp(2.4rem, 5vw, 3.6rem); letter-spacing: 0.01em; }
h2 { font-size: clamp(1.6rem, 3.4vw, 2.2rem); margin-top: 2.2em; }
h3 { font-size: 1.05rem; letter-spacing: 0.04em; }
h4 { font-size: 1rem; font-style: italic; color: var(--ink-light); }
h2 a { color: inherit; text-decoration: none; }

/* Section-divider rhythm (Captain's ruling, post-production edit
   2026-09-24: a spacing-line-spacing divider marks a work's main sections
   and its large chapters; the gap above the line must equal the gap below,
   as the reader sees it). This build has no .document-section wrapper to
   hang matching top/bottom padding on the way Analects does (recon
   2026-09-21) -- every boundary here is a bare <hr> sitting in the flow, so
   its own margin is the only thing both sides can collapse against.
   clamp(3.5rem, 8vw, 7rem) is lifted verbatim from the Analects prototype's
   own section-gap rhythm (analects.css .document-section, Order 3): 102.4px
   at 1280px, 56px at 420px. That is bigger than every margin it neighbours
   here -- including h2's own 2.2em top margin below, see line 784, which
   only wins by a sub-pixel margin at the narrowest width -- so this <hr>'s
   margin wins the collapse on both sides at (almost) every boundary and the
   two sides come out equal. */
hr { border: none; border-top: 1px solid var(--rule); margin: clamp(3.5rem, 8vw, 7rem) auto; width: 50%; }
/* The captured markup puts a bare <br> after every <hr> (recon 2026-09-21:
   7 of the 8 boundaries; the 8th, Chapter 5 -> THE END, never had one, and
   is symmetric enough on its own once the rule above is in place). Same
   defect p.verse + br fixes below (line 1023): a bare <br> is non-empty
   content, so it blocks the <hr>'s margin from collapsing with the
   following heading's margin, stacking a full line-box on top instead.
   Suppressed the same way, in CSS only, per the Captain's order -- the
   <br> itself stays untouched in the markup at all 7 boundaries. */
hr + br { display: none; }

img { max-width: 100%; height: auto; display: block; margin: 1.25em auto; filter: sepia(0.08) contrast(1.02); }

/* --- title-page hero: h1/byline/cover-plate/first-publication-line, taken
   out of the plain reading column and given the prototype's distinct
   treatment (analects.css .title-page / .cover-figure / .title-rule),
   scaled down from the prototype's 20-book front matter to this
   five-chapter novelette's much shorter title matter. --- */
/* Captain order, 2026-09-28 (stamp gap follows Analects, see
   .library-edition below): min-height loses 10.08px -- exactly the
   margin-bottom the h3 above the stamp loses -- so that in a window taller
   than this title page (where it is stretched to min-height) the gap from
   the stamp to the divider line does not grow by that amount. At 900px
   tall and below the page is sized by its content and this has no effect. */
.title-page {
  min-height: calc(100vh - var(--header-height) - 10.08px);
  padding: clamp(2.5rem, 6vw, 4.5rem) 1.5rem clamp(2.5rem, 5vw, 3.5rem);
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  justify-items: center;
  align-content: start;
  text-align: center;
}
/* Divider-rhythm fix, one boundary only (Captain's ruling, post-production
   edit 2026-09-24): title page -> Table of Contents is the sole boundary
   where the preceding box ends in padding (.title-page's own
   padding-bottom, clamp(2.5rem, 5vw, 3.5rem) above) rather than a plain
   margin. Padding blocks collapse, so that padding stacks underneath the
   following <hr>'s own margin-top instead of collapsing with it, the way
   every other boundary in this document does. Left at the shared hr
   margin-top above, the two would stack to ~158px/~96px (1280/420) against
   a ~102px/56px target -- roughly 1.5x too much. Subtracting the section's
   own padding-bottom back out of this one <hr>'s margin-top brings the
   combined gap back to the same clamp(3.5rem, 8vw, 7rem) target as every
   other boundary, at any width -- not just the two measured here. A further
   flat 1.19px is added on top, measured live (Playwright, both test widths
   agreed to 0.01px): the closing chrome link that used to end this section
   is gone (Captain's order, 2026-09-25), so the title page's own last
   visible line is now the ".library-edition" imprint line, and it sits
   that much below its own line box's nominal bottom edge -- the opposite
   of where the removed link's own text-glyph/line-height leading placed
   it, which is why this constant is now added rather than subtracted; the
   padding-box math above cannot see either effect. Confirmed live afterwards: gap
   above/below now agree exactly (0.00px) at both widths, both themes
   (recon's own Range-rect method, not element boxes, is what surfaces
   this). */
/* 2026-10-11 (Captain order, dividers to the Analects layout): every divider
   reads G = clamp(3.5rem, 8vw, 7rem) above and below the line, measured to ink
   from the line's own edges (the 1px line itself excluded), within 1px of
   Analects' 56 / 58.9 / 102.4 / 112 at 420 / 736 / 1280 / 1920. The earlier
   tunings above measured the lower gap from the line's top edge, so each sat
   1px high; they are re-based here. Per-neighbour leading is taken back off the
   shared margin: title-page stamp +0.19px (was +1.19px); the colophon needs no
   offset; prose line above -2.6px; h2 headings below -0.085 x their size (their
   own 2.2em margin-top zeroed so it cannot win the collapse); contents list
   above -2.2px (rule further down); the Table of Contents h3 below -1px. */
.title-page + hr { margin-top: calc(clamp(3.5rem, 8vw, 7rem) - clamp(2.5rem, 5vw, 3.5rem) + 0.19px); }
.colophon + hr {
  margin-top: clamp(3.5rem, 8vw, 7rem);
  margin-bottom: calc(clamp(3.5rem, 8vw, 7rem) - 1px);
}
p.prose + hr { margin-top: calc(clamp(3.5rem, 8vw, 7rem) - 2.6px); }
hr + h2,
hr + br + h2 { margin-top: 0; }
hr:has(+ h2),
hr:has(+ br + h2) { margin-bottom: calc(clamp(3.5rem, 8vw, 7rem) - 0.085 * clamp(1.6rem, 3.4vw, 2.2rem)); }
/* Display face for the title, distinct from --display, matching
   analects.css:236-245 exactly except for font-size, which stays at our
   scaled-down clamp() (sanctioned; a five-chapter novelette does not need
   the prototype's 6.75rem ceiling). Nothing else in section.title-page
   gets a distinct face: the prototype only special-cases h1 and .kicker
   (analects.css:247-252), and this build has no .kicker element -- the
   byline (h4/h2) and the first-publication line (h3) are not given the
   Bodoni treatment by the prototype, so they keep the generic heading
   rule here too. */
.title-page h1 {
  margin: 0;
  color: var(--title-ink);
  font-family: "Bodoni MT", Didot, "Times New Roman", serif;
  font-size: clamp(2.4rem, 5vw, 3.6rem);
  font-weight: 400;
  letter-spacing: 0.015em;
  line-height: 0.82;
  text-transform: uppercase;
}
.title-page .kicker {
  margin: clamp(1.1rem, 2.2vw, 1.6rem) 0 0;
  color: var(--rust);
  font-family: "Bodoni MT", Didot, "Times New Roman", serif;
  font-size: clamp(0.74rem, 1.2vw, 1rem);
  font-weight: 400;
  letter-spacing: 0.34em;
  line-height: 1.3;
  text-transform: uppercase;
}
.title-rule { width: 6rem; margin: 1.5rem 0; border-top: 1px solid var(--rule); }
.title-credits { margin: 0 0 1.75rem; }
.title-credits h4, .title-credits h2 { margin: 0.15em 0; }
/* The frame hugs the plate.  Both cover images are smaller than the old fixed
   figure width (400x560 and 424x620 against a 28rem/448px box), so a fixed width
   left the border enclosing a blank strip to the right of the picture -- and
   `img { margin: 0 }` had overridden the generic `margin: auto`, so the image sat
   flush left and the whole gap fell on one side.  fit-content sizes the figure to
   the rendered image; max-width still caps it on narrow screens, where the image
   scales down inside it.  The plates are never upscaled past their natural size --
   enlarging an archival scan to fill a box only softens it. */
/* The border sits on the IMAGE, not on the figure.  A border on the figure
   enclosed the caption as well, so the plate's title read as part of the framed
   picture; and because the figure is a block, the frame could also be wider than
   the plate inside it.  Bordering the image makes the box the picture's own edge
   by definition -- it cannot be wider or narrower than what it frames -- and
   leaves the caption below it, outside the box.  The figure shrink-wraps with
   fit-content so the caption still centres under the plate.  The plates are never
   upscaled to fill a box; enlarging an archival scan only softens it. */
.cover-figure {
  width: fit-content;
  /* Presentation size set by the Captain: 125% of the original plate's
     presented width.  The source cover presented at 400px, so the target is
     500px -- 31.25rem -- which is 60% of main's 52rem/832px reading measure.
     The height cap below is deliberately loose (85vh) so it does not undercut
     that width on an ordinary desktop; it still catches a short viewport,
     where a 1024x1536 plate would otherwise fill the screen. */
  max-width: min(var(--plate-width), 80vw);
  margin: 0 auto 1.5rem;
  padding: 0;
  background: transparent;
  border: 0;
}
.cover-figure img {
  display: block;
  margin: 0;
  filter: none;
  width: auto;
  max-width: 100%;
  height: auto;
  /* Loose enough not to undercut --plate-width on an ordinary desktop: a
     610px framed box on this 2:3 artwork stands 910px tall, so an 85vh cap
     would have held it to ~513px on a 900px-tall viewport and quietly
     delivered something narrower than the width that was asked for.  It
     still catches a genuinely short window. */
  max-height: 110vh;
  border: 5px solid var(--ink);
}
.title-page h3 { margin-top: 0.5rem; }
/* Imprint line and closing block, from the prototype (analects.css:214-223
   .library-edition, :1160-1175 .site-footer).  The footer sits outside <main>,
   so it is outside the invariant span and adds no chrome to it. */
/* Captain order, 2026-09-28 ("All builds should match": the title-page
   `Arsinoe Library Edition, 2026` stamp follows Analects in gap above and
   colour). The stamp already carried Analects' 0.35rem margin and
   var(--ink-light), but this title page is a grid (no margin collapsing),
   so the h3 above it ("First published in ...") added its own 10.08px
   margin-bottom: 17.2px of ink gap (Range-rect) against Analects' 7.38 /
   7.27 / 7.22 / 6.94 at 420 / 768 / 1280 / 1920. That margin is zeroed
   for the line directly above the stamp (`:has()`, which analects.css:857
   already uses): ink gap 7.13px at every width (0.09-0.25px from
   Analects). The title-page -> table-of-contents divider is unchanged
   (57 / 62.44 / 103.39 / 113 above the line, measured before and after). */
.title-page h3:has(+ .library-edition) {
  margin-bottom: 0;
}

.library-edition {
  margin: 0.35rem 0 0;
  color: var(--ink-light);
  font-family: var(--display);
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.14em;
  line-height: 1.2;
  text-transform: uppercase;
}
/* Colophon (Captain order 2026-10-11): made uniform with On War's
   (clausewitz-war.css .colophon rules): two-column label/value grid, body-font
   labels in --ink-light, 0.9rem. This build keeps its own <hr> dividers above and
   below, so the top rule and top padding of On War's .colophon are not carried. */
.colophon { padding: 0 1.25rem; font-size: 0.9rem; }
.colophon dl {
  margin: 0;
  display: grid;
  grid-template-columns: minmax(0, max-content) minmax(0, 1fr);
  column-gap: 1.25rem;
  row-gap: 0.5rem;
}
.colophon dt { color: var(--ink-light); font-weight: 600; }
.colophon dd {
  margin: 0;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
@media (max-width: 560px) {
  .colophon dl { display: block; }
  .colophon dt { margin-top: 0.7rem; }
  .colophon dt:first-child { margin-top: 0; }
}
.site-footer {
  padding: 2.5rem 1rem;
  color: var(--footer-text);
  background: var(--footer-bg);
  border-top: 3px solid var(--gold, #c9a227);
  font-size: 0.86rem;
  text-align: center;
}
.site-footer p { margin: 0.2rem; }
.site-footer a { color: var(--toggle-hover-color); }

/* Weird Tales plate, mid-document -- same framed idiom, in the normal
   reading column rather than the hero. */
main > figure.cover-figure { width: fit-content; max-width: min(30rem, 80vw); margin: 1.5em auto; }
main > figure.cover-figure p.caption { margin: 0.6em 0 0; border: none; }

/* analects.css:1755-1758: loosen the tight display line-height at narrow
   widths so the uppercased, tracked title does not collide with itself. */
@media (max-width: 700px) {
  .title-page h1 { line-height: 0.94; }
}

/* The in-document table of contents runs in two columns, matching the chapter
   grid in the left panel (.chapter-links above).  Five entries fill it 1-2 /
   3-4 / 5.  It is centred under its own centred heading rather than carrying
   the source's left indent: that indent came from the capture's
   `margin-left:40%`, which belongs to the plain BasicHTML edition and is
   preserved there.  Width is fit-content so the pair of columns centres as a
   block instead of stretching across the reading measure. */
ul.toc {
  margin: 1em auto;
  padding: 0;
  list-style: none;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, auto));
  gap: 0.35em 3em;
  justify-content: center;
  width: fit-content;
  font-family: var(--display);
  font-size: 0.95em;
}
/* Divider-rhythm fix, one boundary only (Captain's ruling, post-production
   edit 2026-09-24: ToC -> Frontispiece). Symmetric to the .title-page + hr
   note above, but for the same reason on the OTHER side: the ToC's last
   entry (Chapter 5, alone in the grid's third row) sits noticeably above
   its own line box's true bottom edge -- text-glyph/line-height leading
   again, this time large enough to matter (0.95em font-size inside a
   1.58 line-height inherited from body) because nothing here has padding
   to hide it behind, unlike the title page. Measured live, ~4.8px at both
   widths; 4.82px split the difference. */
/* 2026-10-11: -4.82px -> -2.2px, re-based to the line's own edge (see the
   dividers note near .title-page + hr). */
ul.toc + hr { margin-top: calc(clamp(3.5rem, 8vw, 7rem) - 2.2px); }
ul.toc li { margin: 0.15em 0; }
ul.toc a { color: var(--ink); }

/* Prose narrative paragraphs -- the two-space sentence rule depends on
   pre-wrap actually being applied here; unchanged from BasicHTML. */
p.prose { white-space: pre-wrap; margin: 1.1em 0; text-align: left; }
p.first { text-indent: 0; }

/* Chapter 1's opening words, set in capitals to match chapters 2-5.  Only the
   rendering changes: the underlying text is untouched, so selecting or
   copying the line still yields "THE roar of battle". */
.opening-words { text-transform: uppercase; }

p.verse, p.quote { margin: 1.3em 0; font-style: italic; color: var(--ink-mid); text-align: left; }
p.verse, p.quote { margin-left: 3em; }

/* The captured markup puts a bare <br> between each ballad and the paragraph
   that follows it.  That <br> contributes a full line box AND blocks margin
   collapse, so the ballad sat 70px above the prose but only 22px below the
   chapter title.  Suppressing just that <br> lets the margins collapse
   normally and leaves the ballad the same 1.3em from the title above and the
   prose below.  The <br> itself is untouched in the markup. */
p.verse + br { display: none; }

/* The closing attribution sits one indent level in from its ballad. */
.verse-attribution { display: block; margin-left: 3em; }
p.caption { text-align: center; font-style: italic; color: var(--ink-light); margin: 0.25em 0 1em; }

/* --- collapsible left contents panel: structure and behaviour from the
   Analects prototype. --- */

.contents { font-size: 1rem; }

.contents-panel {
  position: fixed;
  z-index: 40;
  top: var(--header-height);
  bottom: 0;
  left: 0;
  width: min(var(--contents-panel-width), calc(100vw - 3rem));
  padding: 1.25rem 1rem 2rem;
  overflow-y: auto;
  overscroll-behavior: contain;
  color: var(--ink);
  background:
    repeating-linear-gradient(0deg, var(--paper-texture) 0, var(--paper-texture) 1px, transparent 1px, transparent 4px),
    var(--parchment);
  border-right: 1px solid var(--rule);
  box-shadow: 0.5rem 0 1.4rem var(--shadow);
  transform: translateX(-105%);
  visibility: hidden;
  transition: transform 180ms ease, visibility 0s linear 180ms;
}

.contents-open .contents-panel { transform: translateX(0); visibility: visible; transition-delay: 0s; }

.contents-panel-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem; }
.contents-panel-head .eyebrow { margin: 0 0 0.25rem; color: var(--rust); font-family: var(--display); font-size: 0.68rem; font-weight: 700; letter-spacing: 0.16em; text-transform: uppercase; }
/* The panel headings take their face and weight from the prototype, which
   has no base h1-h4 rule at all: its .contents-panel-head h2 and .toc-group
   h3 fall through to the UA default of bold, and the h2 inherits the body
   face from <body>.  This build does have a base heading rule
   (font-family: var(--display); font-weight: 400), which would otherwise
   capture both and render them light and in the display face.  These two
   rules restore the prototype's rendering; do not fold them back into the
   base rule. */
.contents-panel-head h2 { margin: 0; font-family: var(--body); font-size: 1.65rem; font-weight: 700; text-align: left; }

.contents-close { flex: 0 0 auto; width: 2rem; height: 2rem; padding: 0; color: var(--ink-light); background: transparent; border-radius: 0.25rem; font-size: 1.6rem; line-height: 1; }
.contents-close:hover { color: var(--rust); background: var(--link-hover-bg-strong); }

.contents-backdrop { position: fixed; z-index: 35; inset: var(--header-height) 0 0; display: none; padding: 0; background: var(--backdrop-bg); }

/* Dark Mode control (post-production edit, Captain's order 2026-09-03;
   re-carded to match Sunzi-war's component exactly, further
   post-production edit, Captain's order, 2026-09-03) -- ported from the
   Sunzi-war build (_Build\Sunzi-war\Build-Scripts\build_finished_html.py,
   CSS_CONTENT: .display-controls / .display-toggle / .display-toggle-master
   / .display-toggle-label, and .theme-switch / .theme-switch-option),
   verbatim. This build has no note-box toggles of its own (no
   .display-toggle-child/-switch/-track/-state), so only the master-row
   shape and the bordered card are adopted -- a three-way segmented group
   (role="radiogroup"), not a track-and-thumb switch: that shape only ever
   honestly shows two states. */
.display-controls {
  margin: 1rem 0 1.25rem;
  padding: 0.55rem 0.7rem 0.6rem;
  border: 1px solid var(--rule);
  border-radius: 4px;
  background: var(--parchment-dark);
  box-shadow: 0 2px 6px var(--shadow), inset 0 1px 0 var(--panel-highlight);
}
.display-toggle {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  padding: 0.28rem 0;
}
.display-toggle-master { padding-top: 0.15rem; }
.display-toggle-label {
  color: var(--ink-mid);
  font-family: var(--display);
  font-size: 0.6rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  line-height: 1.25;
  text-transform: uppercase;
}
.theme-switch {
  display: inline-flex;
  flex: none;
  border: 1px solid var(--note-border);
  border-radius: 0.85rem;
  overflow: hidden;
}
.theme-switch-option {
  border: 0;
  border-left: 1px solid var(--note-border);
  padding: 0.2rem 0.5rem;
  background: transparent;
  color: var(--ink-light);
  cursor: pointer;
  font: inherit;
  font-family: var(--display);
  font-size: 0.58rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  line-height: 1.4;
}
.theme-switch-option:first-child { border-left: 0; }
.theme-switch-option[aria-checked="true"] { color: var(--parchment); background: var(--rust); }
.theme-switch-option:focus-visible { outline: 2px solid var(--rust); outline-offset: 2px; }

/* Group-header treatment (Captain's order, 2026-09-13: "Update the TOC panel
   and boxes to the same style as the Analects build"), superseding the
   2026-09-03 boxed `.toc-group h3` above -- vendored instead from Analects'
   CURRENT `.toc-group h3` (analects.css, the rule immediately above its own
   `.toc-end h3, .toc-title h3 { margin: 0; }`), which is unboxed: rust
   small-caps text, no background, no border, no padding. Analects has no
   base h1-h4 rule at all, so its plain `.toc-group h3` (Front Matter /
   Chapters-equivalent headings) falls through to the UA defaults of
   font-weight 700 and a symmetric "1em 0" margin block; this build's own
   base `h1, h2, h3, h4` rule (above) sets font-weight 400 and an asymmetric
   "1.4em 0 0.6em", so both are restored explicitly here -- the same
   precedent already used for `.contents-panel-head h2` -- rather than left
   to fall through to the wrong values. Measured equal to Analects live in
   both themes: color var(--rust), font-size 0.86rem (13.76px), font-weight
   700, letter-spacing 0.09em (1.2384px), margin 13.76px top and bottom. */
.toc-columns { display: grid; grid-template-columns: 1fr; gap: 1.75rem; }
.toc-group h3 {
  margin: 1em 0;
  color: var(--rust);
  font-family: var(--display);
  font-size: 0.86rem;
  font-weight: 700;
  letter-spacing: 0.09em;
  text-align: left;
  text-transform: uppercase;
}
/* End of Document (Captain's order, 2026-09-13: renamed from "The End") and
   Title (Captain's order, 2026-09-13: moved out of the boxed
   `.major-links-simple` list into this same heading-style entry, placed
   first in the panel) -- vendored from Analects' `.toc-end h3, .toc-title
   h3 { margin: 0; }` and `.toc-end a, .toc-title a { color: inherit;
   text-decoration: none; }`. Both share the base `.toc-group h3` rust/caps
   look above; this is only the zero-margin, plain-link addition each single-
   line entry needs on top of it, exactly as in Analects. */
.toc-end h3,
.toc-title h3 {
  margin: 0;
}
.toc-end a,
.toc-title a {
  color: inherit;
  text-decoration: none;
}
.major-links-simple { margin: 0; padding: 0; list-style: none; display: grid; gap: 0.5rem; }
.major-links-simple a {
  display: block;
  padding: 0.65rem 0.75rem;
  color: var(--ink);
  background: var(--parchment-mid);
  border: 1px solid var(--rule);
  border-radius: 4px;
  font-family: var(--display);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  text-decoration: none;
  text-align: center;
}
.major-links-simple a:hover { border-color: var(--gold); color: var(--rust); }

.chapter-links { margin: 0; padding: 0; display: grid; grid-template-columns: repeat(2, 1fr); gap: 0.4rem; list-style: none; }
.chapter-links a { display: block; padding: 0.4rem 0.3rem; color: var(--ink-mid); border-bottom: 1px dotted var(--rule); text-align: center; text-decoration: none; }
.chapter-links a:hover { color: var(--rust); }
.chapter-links span { display: inline; }

/* Intentional divergence from the prototype (analects.css:820-824), which
   uses this same margin-left-on-main rule and inherits the same bug: it
   replaces main's auto left margin while leaving the right margin auto, so
   at wide viewports the reading column sits pinned beside the panel and
   every remaining pixel piles up on the right -- reported by the Captain at
   ~1920px. Fixed here by moving the offset onto body's padding instead of
   main's margin: body keeps box-sizing: border-box, so padding-left simply
   shrinks its content box, and main's own margin-inline: auto (untouched)
   re-centres inside that shrunk box -- equal gaps on both sides of the
   remaining space, not one auto margin absorbing everything. .site-header
   is position: sticky, not fixed, so it is itself a padded child of body
   and would shrink and reveal a gap on the right of the coloured bar; it is
   pulled back out to full viewport width with a matching negative margin.
   .contents-panel and .contents-backdrop are position: fixed and .skip-link
   likewise, so body padding does not move any of them -- verified in a real
   render, not assumed. This build has no .site-footer to carry the same
   treatment. Do not revert this toward the prototype's version; the
   prototype's behaviour is the defect being fixed. */
@media (min-width: 901px) {
  .contents-open { padding-left: var(--contents-panel-width); }
  .contents-open .site-header {
    margin-left: calc(-1 * var(--contents-panel-width));
    width: calc(100% + var(--contents-panel-width));
  }
  /* Captain order 2026-09-28 (body text width uniform with Daodejing):
     the Prototype's own >=901px reading column is not simply its base
     52rem cap -- its rail-toggle mechanism makes it fluid (mainWidth -
     84px total inset) until 828px of main remains, only flattening at
     780px beyond that. main's base rule below (52rem cap, 1.5rem/side
     padding = 48px) supplies 48px of that inset already, so this adds
     the other 36px as width, not padding -- still an equal left/right
     margin via margin-inline: auto, just a narrower box, matching the
     Prototype's own knee exactly at every measured viewport. */
  main,
  .section-bar-inner {
    width: min(100% - 2.25rem, 51.75rem);
  }
}
@media (max-width: 900px) {
  body.contents-open { overflow: hidden; }
  .contents-open .contents-backdrop { display: block; }
  /* Captain order 2026-09-28: below 901px main has no panel offset, so
     matching the Prototype's own (rail-off) column here needs only its
     narrower <=600px padding widened to cover the whole <=900px band --
     see the max-width: 600px block below, now superseded by this pair
     for main/.section-bar-inner (left in place there, unchanged, since
     the values agree and removing it is not required). */
  main { padding-left: 1rem; padding-right: 1rem; }
  .section-bar-inner { padding-left: 1rem; padding-right: 1rem; }
}

@media (max-width: 600px) {
  main { padding-left: 1rem; padding-right: 1rem; }
  /* .section-bar-inner mirrors main's own padding above -- must be kept
     in step at this breakpoint too, or the title drifts 0.5rem off the
     text column's now-narrower left inset. */
  .section-bar-inner { padding-left: 1rem; padding-right: 1rem; }
  ul.toc { gap: 0.35em 1.5em; }
  p.verse, p.quote { margin-left: 1.5em; }
  .verse-attribution { margin-left: 1.5em; }
}

/* ---- About this archival edition (Captain order, 2026-09-28) -------------
   "Every build gets an About this archival edition box that looks exactly
   like Analects'", as the document's last element with a section divider in
   front of it, outside the box. Vendored from analects.css .source-note
   (:1717-1755, and its <=720px padding at :1864-1871): same background,
   1px border, shadow, 40px padding (24px at <=720px), heading 21.6px / 700 /
   line-height 1.2 / 3px padding-top / 24px below, paragraph at reading size,
   no indent. Differences forced by this build, each explained where it
   happens: the divider gap (this build's own, not Analects'), the box
   width (Analects' box is a 52rem .document-section; here it sits inside
   main's narrower text column), and main's clipping.
   G below = clamp(3.5rem, 8vw, 7rem), the section-gap rhythm this file's
   <hr> rule already uses. */

/* Divider: a 1px line drawn by ::before in the box's own margin-top gap, so
   the spacing stays outside the box (Analects' technique). This build's
   main-section dividers read G+1px of ink gap above and below the line
   (title page -> Table of Contents, measured 57 / 62.44 / 103.39 / 113px at
   420 / 768 / 1280 / 1920, above == below); this one is set to the same, so
   ink -> line = line -> box edge = G+1px, i.e. ink -> box edge = 2G+3px (the
   line is 1px). The ink above is "THE END": its line box ends ~0.13em of
   that heading's font-size clamp(1.6rem, 3.4vw, 2.2rem) below its text, and
   the heading's own 0.6em margin-bottom collapses into this margin-top, so
   that much is taken back off. The ::before's `top` is relative to the
   PADDING box (1px inside the border): -(G+1px) to the line's top edge, -1px
   more for the border. Its width is this build's own <hr> (50% of the text
   column, centred), not Analects' box-wide line, so the last divider matches
   the eight above it; the column is narrower than the box from 901px, so the
   width there and in the 833-900px band is set in the blocks below. */
.source-note {
  position: relative;
  /* Captain order, 2026-10-10: the box now closes the Reference section, so its
     divider line and clamp() gap are gone (the ::before below is removed); it sits
     1.5rem under Reference's last line, as in Analects. */
  margin-top: 1.5rem;
  margin-bottom: 5rem;
  padding: 2.5rem;
  background: var(--note-bg);
  border: 1px solid var(--rule);
  box-shadow: 0 0.8rem 2rem var(--shadow);
}

/* Divider above Reference (Captain order, 2026-10-10): the hr between "THE END"
   and Reference. Both neighbours are h2s whose line boxes carry leading below/above
   their ink, so the shared G is trimmed by that much on each side
   (0.098 / 0.05 x the h2 size) to read the same ink gap as the other dividers
   (57 / 59.88 / 103.39 / 113 above, 58 / 60.88 / 104.39 / 114 below at
   420 / 736 / 1280 / 1920). Reference's own h2 margin-top is zeroed so it does
   not outgrow the hr's margin-bottom in the collapse. */
/* 2026-10-11 re-based: above is taken back by 0.13 x the h2 size ("THE END"'s
   leading below its ink); below is the plain G (Reference's h2 sits flush). */
#the-end + hr {
  margin-top: calc(clamp(3.5rem, 8vw, 7rem) - 0.13 * clamp(1.6rem, 3.4vw, 2.2rem));
  margin-bottom: clamp(3.5rem, 8vw, 7rem);
}
#citations > h2 { margin-top: 0; }

/* Reference section (Captain order, 2026-10-10), vendored from analects.css
   `.citations > p` / `#citations`: hanging-indent entries, left-aligned (so URLs
   are not stretched), no bottom padding so the About box sits 1.5rem below. */
.citations > p {
  margin: 1.1rem 0;
  padding-left: 2em;
  text-indent: -2em;
  text-align: left;
  text-wrap: pretty;
}
.citations > p:last-child { margin-bottom: 0; }
#citations { padding-bottom: 0; }
.permalink { overflow-wrap: anywhere; }

.source-note h2 {
  margin: 0 0 1.5rem;
  padding-top: 3px;
  font-size: 1.35rem;
  font-weight: 700;
  line-height: 1.2;
  text-align: left;
}

.source-note p:last-child {
  margin-bottom: 0;
}

/* Width = Analects' box: min(container - 2rem, 52rem). At <=832px main's text
   column already is that (main padding 1rem/side). From 901px main's column is
   min(container - 84px, 780px) -- 2.25rem width gutter + 2 x 1.5rem padding --
   so the box is 52px short of Analects' at every width there; a symmetric
   negative margin widens it back out. From 833 to 900px main is capped at 52rem
   with 1rem padding (a fixed 800px column) while Analects' box keeps growing to
   832px, so the width is set from the viewport in that band only (100vw counts a
   classic scrollbar: measured 15px wider than Analects' box at viewports of
   833-878px with one, exact with overlay scrollbars). */
@media (min-width: 901px) {
  .source-note {
    margin-inline: calc((2rem - 2.25rem - 3rem) / 2);
  }
  /* main clips horizontal overflow (overflow-x: clip, above). From here the box
     is 2px wider than main's own box (its 1px side borders would be cut off) and
     its box-shadow (0.8rem 2rem) spreads ~2rem to each side, so main's clip is
     lifted at these widths. (overflow-clip-margin was tried first and does not
     take effect with overflow-x: clip alone.) Nothing else in main reaches past
     its own box at these widths (measured), and the page still does not scroll
     sideways. */
  main {
    overflow-x: visible;
  }
}

@media (min-width: 833px) and (max-width: 900px) {
  .source-note {
    width: min(100vw - 2rem, 52rem);
    margin-inline: calc((100% - min(100vw - 2rem, 52rem)) / 2);
  }
}

@media (max-width: 720px) {
  .source-note {
    padding: 1.5rem;
  }
}

/* ---- Reduced motion ------------------------------------------------------
   Added alongside the section-bar (post-production edit, 2026-09-03). Must
   be the universal *, *::before, *::after form -- a guard naming individual
   selectors gets out-specified by their own more specific transition rules
   (e.g. .contents-panel, .section-bar.is-visible) and silently does
   nothing, a lesson carried over from the Sunzi-war build. */
@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}
