/* sunzi-war-3b.css -- Finished HTML stage (PIPE 3).
   House style (palette, panel chrome, toggle mechanism, page furniture)
   follows the Analects/Daodejing prototypes' shared design tokens.
   No PDF source for this build: no --source-rail gutter is reserved and
   no source-page-origin markers exist to style. The Part divisions and
   the Part 2 verse indentation ladder are this edition's own, re-themed
   into this palette and type scale rather than replaced. */

: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;
  --note-bg: #eee5cf;
  --note-border: #c0a070;
  --shadow: rgba(30, 25, 18, 0.16);
  /* Formerly hard-coded outside the token set (14 values, Captain-ordered
     dark-mode audit): 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;
  --footer-text: #eee3ca;
  --footer-bg: #241f18;
  --toggle-hover-bg: rgba(255, 255, 255, 0.08);
  --nav-separator: #d7b85b;
  --nav-meta: rgba(248, 241, 223, 0.82);
  --link-hover-bg: rgba(132, 39, 39, 0.06);
  --link-hover-bg-strong: rgba(132, 39, 39, 0.07);
  --backdrop-bg: rgba(22, 18, 14, 0.42);
  --panel-highlight: rgba(255, 255, 255, 0.28);
  --contents-panel-width: 16rem;
  --header-height: 3.55rem;
  --section-bar-height: 2.15rem;
  --body: "Iowan Old Style", "Palatino Linotype", "Book Antiqua", "Noto Serif CJK TC", Georgia, serif;
  --display: "Palatino Linotype", "Book Antiqua", "Noto Serif CJK TC", Georgia, serif;
  /* Our own verse-ladder unit (Basic HTML, PIPE 1/2), re-themed to rem
     so it still lands every layer at the same absolute offset
     regardless of a paragraph's local font-size -- see
     build_basic_html.py's own reasoning for this, unchanged here. */
  --indent-unit: 1.5rem;
  /* Prototype paddings below reference --source-rail (their PDF
     page-marker gutter). This build has no PDF source, so it is
     zero -- carried as a token, not hand-omitted, so the rule
     stays copy-identical to the prototype's; zero means no
     visible gutter. */
  --source-rail: 0rem;
  /* Frame around the title plate. Black in light, as Daodejing has it; a
     warm light tone in dark, so the frame stays visible instead of going
     black on black. */
  --cover-border: rgb(0, 0, 0);
  /* 2026-10-11 (Analects layout): colour of the title h1, Analects' --title-ink
     (analects.css:37 light, :88/:121 dark); not the same as --ink here. */
  --title-ink: #1e1913;
  color-scheme: light;
}

/* ---- Dark mode (Captain-ordered) -----------------------------------------
   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.
   A parchment-and-ink edition in the dark reads as ink-on-dark-paper --
   warm, not a generic inverted website -- so hue is kept close to the
   light values; 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. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    --cover-border: rgba(232, 223, 201, 0.4);
    --title-ink: #f2e9d6;
    --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;
    --note-bg: #2a2318;
    --note-border: #6b5636;
    --shadow: rgba(0, 0, 0, 0.5);
    --paper-highlight: rgba(255, 240, 210, 0.045);
    --paper-texture: rgba(0, 0, 0, 0.32);
    --header-shadow: rgba(0, 0, 0, 0.5);
    --toggle-hover-bg: rgba(255, 255, 255, 0.12);
    --link-hover-bg: rgba(224, 120, 95, 0.14);
    --link-hover-bg-strong: rgba(224, 120, 95, 0.18);
    --backdrop-bg: rgba(0, 0, 0, 0.6);
    --panel-highlight: rgba(255, 255, 255, 0.06);
    --on-accent: #1b1712;
  }
}

:root[data-theme="dark"] {
  color-scheme: dark;
  --cover-border: rgba(232, 223, 201, 0.4);
  --title-ink: #f2e9d6;
  --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;
  --note-bg: #2a2318;
  --note-border: #6b5636;
  --shadow: rgba(0, 0, 0, 0.5);
  --paper-highlight: rgba(255, 240, 210, 0.045);
  --paper-texture: rgba(0, 0, 0, 0.32);
  --header-shadow: rgba(0, 0, 0, 0.5);
  --toggle-hover-bg: rgba(255, 255, 255, 0.12);
  --link-hover-bg: rgba(224, 120, 95, 0.14);
  --link-hover-bg-strong: rgba(224, 120, 95, 0.18);
  --backdrop-bg: rgba(0, 0, 0, 0.6);
  --panel-highlight: rgba(255, 255, 255, 0.06);
  --on-accent: #1b1712;
}

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

/* Title plate on the front matter. Sized so it never upscales past the
   image's own 640px width, and never wider than 70% of the column.
   The frame sits on the figure; the figure carries no caption yet. */
.cover-figure {
  width: min(40rem, 76vw);
  max-width: 70%;
  margin: clamp(1.75rem, 4vw, 2.75rem) auto 0;
  padding: 0;
  background: transparent;
  border: 5px solid var(--cover-border);
  box-shadow: none;
}

.cover-figure img {
  display: block;
  width: 100%;
  height: auto;
}

/* 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. This edition currently has no in-page <img>, so the rule
   presently matches nothing -- it is here for anything added later. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) img {
    filter: brightness(0.85);
  }
}

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

* {
  box-sizing: border-box;
}

html {
  scroll-behavior: auto;
  scroll-padding-top: calc(var(--header-h-actual, 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;
}

/* ---- Header / nav ------------------------------------------------------ */
.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 (CAP-011): a second, slimmer sticky strip
   directly beneath .site-header, showing the current section'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. */
.section-bar {
  position: sticky;
  z-index: 25;
  /* the measured header height, set by script; the token is the fallback */
  top: var(--header-h-actual, 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, padding-left 180ms ease;
}

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

/* Inner wrapper mirrors .reading-shell's own width/centring rule (below)
   so the title's left edge tracks the running text column's left edge at
   every viewport and Contents-panel state. The bar's background stays
   full-bleed; only this wrapper -- and the text inside it -- is inset. */
.section-bar-inner {
  max-width: 52rem;
  width: 100%;
  height: 100%;
  margin: 0 auto;
  padding-left: 1rem;
  padding-right: 1rem;
  box-sizing: border-box;
  display: flex;
  align-items: center;
}

.section-bar-part:not(:empty) {
  color: var(--rust);
}

.section-bar-part:not(:empty)::after {
  content: "\00B7";
  margin: 0 0.5em;
  color: var(--gold);
}

.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;
}

/* ---- Contents panel ------------------------------------------------------ */
.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;
}

.eyebrow {
  margin: 1rem 0 0.25rem;
  color: var(--rust);
  font-family: var(--display);
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

.contents-panel-head .eyebrow {
  margin-top: 0;
}

.contents-panel-head h2 {
  margin: 0;
  font-size: 1.65rem;
}

.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);
}

/* The Part entries used to appear twice: once as a boxed quick-link in
   a now-removed .major-links block, once as each toc-group's plain-text
   heading. The Captain's ruling: keep the box, drop the duplicate --
   each group's own <h3><a> IS that boxed Part link now, doing double
   duty as a real heading (kept for aria-labelledby/screen-reader
   structure) and as the link. .major-links itself, and the CSS that
   styled only it, are gone -- nothing else used that class. */
.toc-columns {
  display: grid;
  gap: 1.75rem;
}

.toc-group h3 {
  margin: 0 0 0.75rem;
}

.toc-group h3 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-decoration: none;
  text-transform: uppercase;
}

.toc-group h3 a:hover {
  border-color: var(--gold);
  color: var(--rust);
}

/* Captain-ordered 2026-09-13: End of Document / Title, Analects-style --
   rust small-caps display text, uppercase, letter-spaced, no box. Raised
   selector specificity (two classes) over the boxed .toc-group h3 a /
   :hover rules above so this wins regardless of source order; Part 1/Part
   2 groups match neither selector and keep the boxed style untouched. */
.toc-group.toc-end h3,
.toc-group.toc-title h3 {
  margin: 0;
  text-align: left;
}

.toc-group.toc-end h3 a,
.toc-group.toc-title h3 a {
  display: inline;
  padding: 0;
  color: var(--rust);
  background: none;
  border: none;
  border-radius: 0;
  font-family: var(--display);
  font-size: 0.86rem;
  font-weight: 700;
  letter-spacing: 0.09em;
  text-decoration: none;
  text-transform: uppercase;
}

.toc-group.toc-end h3 a:hover,
.toc-group.toc-title h3 a:hover {
  border-color: transparent;
  color: var(--rust);
}

/* Captain order 2026-10-12 (as Sunzi-war's 2026-10-12 rule): as in Analects,
   only "Title" is the plain rust heading; "Table of Contents" (the toc-title
   group's second link) is a boxed entry like the Part entries, centred, a
   1.25rem gap under Title. */
.toc-group.toc-title h3 + h3 {
  margin: 1.25rem 0 0;
}

.toc-group.toc-title h3 + h3 a {
  display: block;
  padding: 0.65rem 0.75rem;
  color: var(--ink);
  background: var(--parchment-mid);
  border: 1px solid var(--rule);
  border-radius: 4px;
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-align: center;
}

.toc-group.toc-title h3 + h3 a:hover {
  border-color: var(--gold);
  color: var(--rust);
}

.chapter-links {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 0.05rem;
}

.chapter-links a {
  display: block;
  padding: 0.28rem 0.3rem;
  color: var(--ink-mid);
  border-radius: 3px;
  font-size: 0.82rem;
  text-decoration: none;
  line-height: 1.35;
}

.chapter-links a:hover {
  color: var(--rust);
  background: var(--link-hover-bg);
}

/* Captain order 2026-10-12: Contents panel spacing as Analects' .major-links
   (analects.css, read-only): boxes 0.55rem apart, each chapter list 0.55rem
   under its box and 1.1rem + 0.55rem above the next box, End of Document
   1.75rem under the last box; Title / End of Document headings at their own
   0.86rem size (line box 22px, as Analects). Captain ruling kept: no repeated
   heading above the chapter lists. */
.toc-columns {
  gap: 0.55rem;
}

.toc-group h3 {
  margin-bottom: 0.55rem;
}

.toc-group h3:last-child {
  margin-bottom: 0;
}

.toc-group.toc-end h3,
.toc-group.toc-title h3 {
  font-size: 0.86rem;
}

.toc-group.toc-end {
  margin-top: 1.2rem;
}

.toc-group .chapter-links {
  margin-bottom: 1.1rem;
}

/* ---- Display (note-box) controls ---------------------------------------- */
.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-child {
  margin-top: 0.15rem;
  padding: 0.28rem 0 0.28rem 0.85rem;
  border-top: 1px solid var(--note-border);
}

.display-toggle-child .display-toggle-label {
  color: var(--ink-light);
  font-weight: 500;
  text-transform: none;
  letter-spacing: 0.03em;
  font-size: 0.63rem;
}

.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;
}

.display-toggle-switch {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  flex: none;
  padding: 0.15rem;
  border: 0;
  background: none;
  color: var(--ink-light);
  cursor: pointer;
  font-family: var(--display);
  font-size: 0.58rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.display-toggle-switch:disabled {
  cursor: not-allowed;
  opacity: 0.42;
}

.display-toggle-track {
  display: inline-block;
  position: relative;
  width: 1.85rem;
  height: 0.85rem;
  border: 1px solid var(--note-border);
  border-radius: 0.85rem;
  background: transparent;
  transition: background-color 0.15s ease;
}

.display-toggle-track::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 0.13rem;
  width: 0.55rem;
  height: 0.55rem;
  border-radius: 50%;
  background: var(--note-border);
  transform: translateY(-50%);
  transition: left 0.15s ease, background-color 0.15s ease;
}

.display-toggle-switch[aria-checked="true"] .display-toggle-track {
  background: var(--parchment);
}

.display-toggle-switch[aria-checked="true"] .display-toggle-track::after {
  left: calc(100% - 0.68rem);
  background: var(--rust);
}

.display-toggle-switch:focus-visible {
  outline: 2px solid var(--rust);
  outline-offset: 2px;
}

.display-toggle-state {
  min-width: 1.6rem;
  text-align: left;
}

/* Dark Mode: a three-way segmented control, not a track-and-thumb switch
   (that shape only ever honestly shows two states). Kept in the same
   .display-toggle row/label rhythm as the note-box switches above so it
   reads as one family of controls, not a bolted-on extra. */
.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;
}

body.notes-hidden .note-box {
  display: none;
}

.note-box.is-hidden {
  display: none;
}

@media (min-width: 901px) {
  .contents-open main,
  .contents-open .site-footer {
    margin-left: var(--contents-panel-width);
  }

  .contents-open .section-bar {
    padding-left: var(--contents-panel-width);
  }

  .site-footer {
    transition: margin-left 180ms ease;
  }

  /* 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 864px of main remains, only flattening at
     780px beyond that. The base rule (52rem cap, 1rem/side padding =
     32px) is the <901px value; this raises it to match the Prototype's
     own knee exactly at every measured viewport. .reading-shell's own
     override sits with its base rule below (source order matters here:
     this block precedes that rule, so it cannot win against it). */
  .section-bar-inner {
    max-width: 54rem;
    padding-left: 2.625rem;
    padding-right: 2.625rem;
  }
}

@media (max-width: 900px) {
  body.contents-open {
    overflow: hidden;
  }

  .contents-open .contents-backdrop {
    display: block;
  }
}

@media (max-width: 600px) {
  .section-bar-part {
    display: none;
  }
}

/* ---- Reading shell ------------------------------------------------------- */
.reading-shell {
  max-width: 52rem;
  margin: 0 auto;
  padding: 2.5rem 1rem 6rem;
}

/* Captain order 2026-09-28 (body text width uniform with Daodejing): the
   >=901px half of the same fix as .section-bar-inner's own override
   above (see that block's comment) -- must come after this base rule in
   source order to win against it, unlike .section-bar-inner's, whose
   base rule sits earlier in the file. */
@media (min-width: 901px) {
  .reading-shell {
    max-width: 54rem;
    padding-left: 2.625rem;
    padding-right: 2.625rem;
  }
}

h1 {
  font-family: "Bodoni MT", Didot, "Times New Roman", serif;
  text-align: center;
  line-height: 1.1;
}

h2 {
  font-family: var(--display);
  text-align: center;
}

h4, h5 {
  text-align: center;
  font-family: var(--display);
  color: var(--ink-light);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  font-size: 0.8rem;
}

h3 {
  font-family: var(--display);
  text-align: center;
}

p.center {
  text-align: center;
}

hr {
  border: none;
  border-top: 1px solid var(--rule);
  width: 60%;
  margin: 2rem auto;
}

table {
  margin: 1.5rem auto;
  border-collapse: collapse;
}

td {
  padding: 0.2em 0.6em;
}

/* ---- In-page Contents list (Captain-ordered) -----------------------------
   The publication's own contents list, restyled from a bare table into a
   list -- the panel's own .toc-group/.chapter-links treatment (boxed Part
   heading, plain-link entries below it) is the reference, adapted to sit
   full-width in the reading measure instead of a narrow sidebar column.
   Deliberately quieter than h1.part further down the page -- a small
   uppercase label, not a rule-framed heading -- so it never competes with
   the real Part dividers it is merely a table of contents for. */
.contents-page {
  display: grid;
  gap: 2rem;
  margin-top: 1.75rem;
}

.contents-page-part {
  margin: 0 0 0.75rem;
  text-align: left;
}

.contents-page-part a {
  display: block;
  padding: 0.6rem 0.85rem;
  color: var(--ink);
  background: var(--parchment-mid);
  border: 1px solid var(--rule);
  border-radius: 4px;
  font-family: var(--display);
  font-size: 0.76rem;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-decoration: none;
  text-transform: uppercase;
}

.contents-page-part a:hover {
  border-color: var(--gold);
  color: var(--rust);
}

.contents-page-list {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 0.15rem;
}

.contents-page-list a {
  display: block;
  padding: 0.32rem 0.4rem;
  color: var(--ink-mid);
  border-radius: 3px;
  font-size: 0.94rem;
  text-decoration: none;
  line-height: 1.4;
}

.contents-page-list a:hover {
  color: var(--rust);
  background: var(--link-hover-bg);
}

/* Captain order 2026-10-12 (all builds, as Lovecraft): each counted map,
   illustration, figure and table is listed under the section that holds it,
   with a dot in front. */
.contents-page-illustration > a::before {
  content: "\2022";
  margin-right: 0.5em;
}

/* ---- Source tables (Analects house treatment, carried faithfully) -------- */
/* A source table is always wrapped: <div class="table-scroll"> around the
   <table class="source-table">. The scroll container is what keeps a wide
   table from forcing the whole page to scroll sideways on a narrow screen. */

.source-table {
  margin: 1.6rem 0;
}

.source-table figcaption {
  margin-bottom: 0.45rem;
  color: var(--ink-light);
  font-family: var(--display);
  font-size: 0.72rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.table-scroll {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

table.source-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.86rem;
  line-height: 1.45;
  text-align: left;
}

.source-table caption {
  padding-bottom: 0.4rem;
  font-size: 1.1rem;
  font-weight: bold;
  text-align: left;
}

.source-table th,
.source-table td {
  padding: 0.42rem 0.7rem;
  border-bottom: 1px solid var(--rule);
  vertical-align: top;
  text-indent: 0;
}

.source-table thead th {
  border-bottom: 2px solid var(--note-border);
  color: var(--rust);
  font-family: var(--display);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  white-space: nowrap;
}

.source-table tbody tr:last-child th,
.source-table tbody tr:last-child td {
  border-bottom: 0;
}

.source-table tbody tr:nth-child(even) {
  background: var(--parchment-mid);
}

/* Row-header tables -- first cell of each row identifies the row. Our
   chronology table's date column is exactly this: the year identifies
   the row, so it is marked up as <th scope="row"> rather than <td>. The
   nowrap keeps a two-part date ("509 or 508", "478 to 476") on one
   line instead of wrapping merely because the column is narrow. */
.source-table tbody th[scope="row"] {
  color: var(--ink);
  font-weight: 600;
  white-space: nowrap;
}

/* The chronology event cells carry the Basic HTML two-space sentence
   rule. Like every prose context in this sheet they need
   white-space: pre-wrap for the literal double spaces to render -- a
   <td> defaults to `normal`, which collapses them silently.
   overflow-wrap: break-word is paired with it as elsewhere, so a long
   token cannot overflow a narrow cell. */
.source-table td {
  white-space: pre-wrap;
  overflow-wrap: break-word;
}

@media (max-width: 720px) {
  .source-table table {
    font-size: 0.8rem;
  }

  .source-table th,
  .source-table td {
    padding: 0.34rem 0.5rem;
  }
}

/* ---- Note boxes (house treatment) ---------------------------------------- */
.note-box {
  margin: 1.5rem 0 1.5rem 1.6rem;
  padding: 0.7rem 0.9rem;
  background: var(--note-bg);
  border-left: 3px solid var(--note-border);
  color: var(--ink-mid);
  font-size: 0.85rem;
  line-height: 1.58;
  text-align: left;
}

/* The two-space sentence rule (Basic HTML) depends on white-space:
   pre-wrap to render its literal double spaces; the house .note-box
   rule would otherwise reset text to white-space: normal and silently
   collapse them back to one. */
.note-box p.content-note {
  margin: 0;
  text-align: left;
  text-indent: 0;
  white-space: pre-wrap;
  overflow-wrap: break-word;
}

/* Quotation passages (Captain-ordered): visually kin to note boxes --
   same background, border, padding, font -- but a structurally separate
   class, so the notes toggle (which only ever queries .note-box) can
   never hide one. */
.quotation {
  margin: 1.5rem 0 1.5rem 1.6rem;
  padding: 0.7rem 0.9rem;
  background: var(--note-bg);
  border-left: 3px solid var(--note-border);
  color: var(--ink-mid);
  font-size: 0.85rem;
  line-height: 1.58;
  text-align: left;
}

.quotation p.quotation-text {
  margin: 0 0 0.45rem;
  text-align: left;
  text-indent: 0;
  white-space: pre-wrap;
  overflow-wrap: break-word;
}

.quotation p.quotation-text:last-child {
  margin-bottom: 0;
}

/* ---- Colophon / source note ------------------------------------------------ */
.source-note {
  margin: 3rem auto 0;
  max-width: 42rem;
  padding: 1.5rem 1.25rem;
  border-top: 1px solid var(--rule);
  font-size: 0.9rem;
}

.source-note h2 {
  text-align: left;
  font-size: 1.1rem;
}

.source-note dl {
  display: grid;
  grid-template-columns: minmax(0, max-content) minmax(0, 1fr);
  column-gap: 1em;
  row-gap: 0.4em;
}

.source-note dt {
  font-weight: bold;
}

/* Captain order 2026-10-11 (Ref 41): the front colophon (aside.colophon)
   takes On War's .colophon dl/dt layout -- column-gap 1.25rem, row-gap
   0.5rem, dt in --ink-light at weight 600. Scoped to .colophon so the
   About box (#end-note, also .source-note) is untouched. */
.colophon dl {
  column-gap: 1.25rem;
  row-gap: 0.5rem;
}

.colophon dt {
  color: var(--ink-light);
  font-weight: 600;
}

.source-note dd {
  margin: 0;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

/* ---- Footer ---------------------------------------------------------------- */
/* Footer: the Analects presentation (Captain order 2026-09-28) -- the dark
   "furniture" bar in both themes, gold top rule, 0.86rem, body typeface. */
.site-footer {
  padding: 2.5rem 1rem;
  color: var(--footer-text);
  background: var(--footer-bg);
  border-top: 3px solid var(--gold);
  font-size: 0.86rem;
  text-align: center;
}

.site-footer p {
  margin: 0.2rem;
}

.site-footer a {
  color: var(--toggle-hover-color);
}

/* =====================================================================
   Part 2 verse indentation ladder -- this edition's own mechanism
   (Basic HTML, PIPE 1/2), re-themed into this palette/type scale only.
   Rules kept mutually exclusive (not "baseline plus override") because
   a :not()-heavy baseline selector can outrank the plain .verse-label /
   .sub-line rules meant to override it -- see build_basic_html.py.
   ===================================================================== */

.verse-chapter p:not(.verse-label):not(.sub-line):not(.poem):not(.center):not(.noindent):not(.signature),
.verse-chapter .content-note {
  text-indent: 0;
  padding-left: var(--indent-unit);
}

.verse-chapter p.verse-label {
  text-indent: calc(-1 * var(--indent-unit));
  padding-left: var(--indent-unit);
}

.verse-chapter p.sub-line {
  text-indent: 0;
  padding-left: calc(2 * var(--indent-unit));
}

p {
  margin-top: 0.5em;
  margin-bottom: 0.5em;
  text-indent: 1.5em;
}

p:not(.center):not(.poem):not(.noindent):not(.signature):not(.content-note) {
  white-space: pre-wrap;
  overflow-wrap: break-word;
  word-wrap: break-word;
}

p.center, p.poem, p.noindent, p.signature {
  text-indent: 0;
  white-space: normal;
}

p.poem {
  margin-left: 10%;
}

p.signature {
  text-align: right;
  font-style: italic;
}

div.chapter.editorial h3 {
  font-size: 1.1em;
  font-weight: bold;
  text-align: left;
}

h1.part {
  font-size: 1.8rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  margin-block: 2rem 3rem;
  padding: 3.5rem 1rem;
  border-top: 1px solid var(--gold);
  border-bottom: 1px solid var(--gold);
  color: var(--rust);
}

/* Every .chapter div in this build -- Part 1's front-matter sections,
   the six Introduction sections, the section holding the Bibliography
   and Footnotes, the two editorial sections, and Part 2's thirteen
   chapters alike -- gets this rhythm: 3.5rem of breathing room above
   and below (matching consecutive .chapter/.document-section in the
   prototypes) plus a dividing rule after it. Deliberately uniform
   rather than scoped to Part 2 only: every one of these IS a document
   section, and a reader should feel the same separation between all of
   them. The two editorial sections (div.chapter.editorial) get this
   too -- checked after the change: they read exactly like the other
   sections, just with more air, which is the point. --source-rail is
   0 for this build (see :root), so the right-hand padding component
   is inert -- no gutter. */
div.chapter {
  padding: 3.5rem var(--source-rail) 3.5rem 0;
  border-bottom: 1px solid var(--rule);
}

/* A Part divider (h1.part, inside div.part-division) already draws its
   own top and bottom rule. Where a .chapter's border-bottom would sit
   immediately above one, it doubles the divider's own top rule --
   two parallel hairlines framing an empty band, not a design. Suppress
   it declaratively (by relationship, not by naming the two sections
   that happen to precede a divider today) so a future third Part never
   reintroduces the defect. */
div.chapter:has(+ .part-division) {
  border-bottom: none;
}

/* Maps the prototypes' .chapter-header (a wrapper we do not have)
   2rem margin-bottom onto the heading itself. */
div.chapter > h2 {
  margin-bottom: 2rem;
}

.part-title {
  display: block;
  font-size: 0.6em;
  letter-spacing: 0.02em;
  text-transform: none;
  margin-top: 0.4rem;
  color: var(--ink-light);
}

a.part-link {
  font-weight: bold;
  letter-spacing: 0.03em;
  text-transform: uppercase;
}

/* ---- Print -------------------------------------------------------------- */
@media print {
  @page {
    size: letter;
    margin: 0.65in 0.7in;
  }

  body {
    color: #000;
    background: #fff;
    font-size: 11pt;
  }

  .site-header,
  .section-bar,
  .skip-link,
  .contents-backdrop,
  .contents-toggle,
  .contents-close,
  .display-controls,
  .top-link {
    display: none !important;
  }

  main {
    margin-left: 0 !important;
  }

  .contents-panel {
    position: static;
    width: 100%;
    padding: 0.35in 0;
    overflow: visible;
    border-right: 0;
    box-shadow: none;
    transform: none;
    visibility: visible;
    inset: auto;
  }

  .contents-panel {
    break-after: page;
  }

  .source-note {
    background: none;
    border: 0;
    box-shadow: none;
  }

  .site-footer {
    margin-top: 0.3in;
    padding-top: 0.15in;
    border-top: 1px solid #999;
    background: none;
    text-align: center;
  }

  .site-footer a[href="#top"] {
    display: none !important;
  }

  h2, h3, h4 {
    break-after: avoid;
  }

  .note-box, table, tr {
    break-inside: avoid;
  }

  a {
    color: #000;
    text-decoration: none;
  }
}

@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;
  }
}

/* ---- Captain-ordered 2026-09-24: divider spacing, main sections / large
   chapters only (see the block comment above add_divider_spacing_css() in
   build_restored_html.py for the full boundary set and rationale). ---- */

/* Captain order 2026-10-11: "review all the divider spacings in each build
   and update them to the Analects layout." Every divider is
   spacing-line-spacing with ONE gap G = clamp(3.5rem, 8vw, 7rem) above and
   below the 1px line, measured to visible ink (text Range rects, drawn
   borders, images): 56 / 58.9 / 102.4 / 112px at 420 / 736 / 1280 / 1920.
   This block replaces the 2026-09-24 per-boundary patches (the nine
   `h2:has(> #id)` margin resets, the padding-top 45.5 / 63.38 / 78.5px
   tweaks and the Part-banner -1 / -10px margins) with shared rules: every
   chapter, the Part banners, the front-matter rules and the colophon take
   --divider-gap on both sides; the neighbouring margins that used to add
   to it are zeroed. The title page itself is not changed. */
main {
  --divider-gap: clamp(3.5rem, 8vw, 7rem);
}

/* G less the ink's own offset inside the box (measured, every width): the
   h2's leading above its text ~2.6px; a chapter ending in a paragraph has the
   last line's leading ~2.5px below its text; one ending in a note-box
   (its left border runs to the box edge) has none. Reference (#citations)
   keeps the 0 bottom padding set at its own rule below. */
div.chapter:not(.front-matter) {
  padding-top: calc(var(--divider-gap) - 2.6px);
  padding-bottom: var(--divider-gap);
}

div.chapter:not(.front-matter):not(#citations):has(> p:last-child) {
  padding-bottom: calc(var(--divider-gap) - 2.5px);
}

div.chapter:not(.front-matter) > :first-child {
  margin-top: 0;
}

div.chapter > :last-child {
  margin-bottom: 0;
}

/* the wrapper's last visible content is a boxed Contents-page link ~23.8px
   above its content edge; this is the line above the Part 1 banner */
div.chapter.front-matter {
  padding-bottom: calc(var(--divider-gap) - 23.8px);
}

/* 2026-10-11 (Analects layout) -- Captain order: "Update both Sunzi titles in the
   Title section to same layout as Analects." The title h1 (the source title,
   words and <br>s untouched) takes the computed values of Analects' title h1
   (analects.css `.title-page h1`, lines 436-445, 2152-2155, 2527-2530):
   Bodoni stack, 400 weight, uppercase, 0.015em tracking, no margins,
   clamp(3.25rem, 6vw, 6.75rem) / line-height 0.82, and below 700px
   clamp(2.65rem, 14vw, 4.2rem) / 0.86. Scoped to this one h1 so h1.part is
   unchanged. Font-family and text-align already match the base h1 rule. */
.chapter.front-matter > h1:first-child {
  margin: 0;
  color: var(--title-ink);
  font-size: clamp(3.25rem, 6vw, 6.75rem);
  font-weight: 400;
  letter-spacing: 0.015em;
  line-height: 0.82;
  text-transform: uppercase;
}

@media (max-width: 700px) {
  .chapter.front-matter > h1:first-child {
    font-size: clamp(2.65rem, 14vw, 4.2rem);
    line-height: 0.86;
  }
}

/* 2026-10-11 (Analects layout) -- Captain order: match the gap between the Sunzi
   title and the line below it to Analects. Analects' `.title-page .kicker` sits
   clamp(1.45rem, 2.8vw, 2.2rem) below its h1; this h4 (the first subtitle line)
   takes that same margin less 1px, which makes the h1-last-line -> next-line gap
   (DOM Range rects) equal Analects' within 0.01px at 420-1920 (the 1px is the
   difference in the two next-lines' own box offsets). Scoped to this one
   boundary; the h4's own font, size and colour are unchanged. */
.chapter.front-matter > h1:first-child + h4 {
  margin-top: calc(clamp(1.45rem, 2.8vw, 2.2rem) - 1px);
}

.part-division {
  margin: 0;
}

/* the h1's own ink sits 2px above / 1px below its content box */
h1.part {
  margin: 0;
  padding-block: calc(var(--divider-gap) + 2px) calc(var(--divider-gap) + 1px);
}

/* the two front-matter rules: dedication text sits ~2.5px inside its box,
   the h2 below ~2.7px; after the colophon the last row ~2.8px above and the
   dedication ~1.5px below */
hr {
  margin-block: calc(var(--divider-gap) - 2.5px) calc(var(--divider-gap) - 2.7px);
}

#source-note + hr {
  margin-block: calc(var(--divider-gap) - 2.8px) calc(var(--divider-gap) - 1.5px);
}

.colophon {
  margin-top: calc(var(--divider-gap) + 0.2px);
  padding-top: calc(var(--divider-gap) - 2px);
  padding-bottom: 0;
  /* Captain order 2026-10-12: content and divider width as Analects' #colophon
     (full reading column, no side padding, no 42rem cap), as Sunzi-war. */
  max-width: none;
  padding-right: 0;
  padding-left: 0;
}

/* Captain order 2026-10-12 ("Match the Prototype"): above 900px Analects'
   #colophon divider runs its 3.25rem source rail past the text on the right
   (832 px line over 780 px text); the text width stays the column's. */
@media (min-width: 901px) {
  #source-note {
    margin-right: -3.25rem;
    padding-right: 3.25rem;
  }
}

/* Captain order 2026-10-12: stacked at 560px and narrower, as Analects'
   .colophon (the long "Arsinoe Library Edition, published by..." label had
   squeezed the value column to one letter per line). */
@media (max-width: 560px) {
  .colophon dl {
    display: block;
  }
  .colophon dt {
    margin-top: 0.7rem;
  }
  .colophon dt:first-child {
    margin-top: 0;
  }
}

.colophon > .front-edition-notice > h2:first-child {
  margin-top: 0;
}

/* Captain order 2026-09-28: "update all the 'About this archival edition'
   sections to look like Analects (color, text box, spacing, etc.)"; then
   "...no section line / space divider as requested for all sections.
   Again, reference Analects for correct example." #end-note (the "About
   the Arsinoe Library Edition" box; heading and text ruled unchanged --
   style only) takes Analects' aside#source-note card (analects.css
   ~1717-1755): note-bg fill, 1px --rule border, 0 0.8rem 2rem shadow,
   2.5rem padding (1.5rem at <=720px), body-size text with no indent, the
   heading 1.35rem / 1.2 / 3px top padding / 1.5rem below, the last
   paragraph's bottom margin 0 so the inner bottom gap equals the padding.
   Width is Analects' min(100% - 2rem, 52rem) of <main>: wider than this
   build's reading column by (its padding - 1rem) a side, hence the
   negative side margins (main clips overflow-x). The divider is the
   box's own `::before`, outside the box, drawn in its margin-top gap the
   full width of the box (left/right -1px = the border's outer edge), with
   equal space above and below: the gap is this build's own main-section
   divider gap, 3.5rem + 1.38em (79.4 / 80.2 / 81.9 / 83.4px at 420 / 768
   / 1280 / 1920; the Part 2 dividers measure 79.1 / 79.8 / 82.3 / 83.7
   below the line, 80.0 above it where a note-box ends the chapter);
   +2px = the box border and the line's own 1px, which the pseudo's
   containing block (the padding box) leaves out. margin-bottom -1rem
   brings the box-to-footer distance to Analects' 5rem (this shell's
   padding-bottom is 6rem). Scoped to #end-note on purpose: the front
   colophon (aside#source-note) shares .source-note and is unchanged.
   Supersedes the earlier chap21 -> #end-note fix (chap21's own
   border-bottom kept, #end-note's border-top/margin dropped,
   padding-top 63.93px inside the box): the line is now this ::before,
   outside the box, and the gap no longer sits inside it. */
#end-note {
  position: relative;
  max-width: none;
  margin: 1.5rem calc(-1 * max(0px, min(1rem, (100vw - 52rem) / 2))) -1rem;
  padding: 2.5rem;
  background: var(--note-bg);
  border: 1px solid var(--rule);
  box-shadow: 0 0.8rem 2rem var(--shadow);
  font-size: inherit;
}

/* Captain order 2026-10-10: the box is the closing box of the Reference
   section (#citations), as in Analects -- no divider line between them
   (the `::before` rule and the box's divider gap are gone) and the box sits
   1.5rem under Reference's last line (Analects' .source-note margin-top). */
#end-note > h2 {
  margin: 0 0 1.5rem;
  padding-top: 3px;
  font-size: 1.35rem;
  line-height: 1.2;
}

#end-note > p {
  margin: 1em 0;
  text-indent: 0;
}

#end-note > p:last-child {
  margin-bottom: 0;
}

@media (min-width: 901px) {
  /* the reading shell's own side padding is 2.625rem here (1rem below) */
  #end-note {
    margin-inline: -1.625rem;
  }
}

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

/* Print: the screen card is dropped, as `.source-note` already does for
   every box of this class (above); the id-level rules just above outrank
   that class rule, so it is repeated here, after them. */
@media print {
  #end-note {
    margin-inline: 0;
    background: none;
    border: 0;
    box-shadow: none;
  }
}

/* The chapter directly above #end-note is now Reference (#citations): it
   drops its own border-bottom and bottom padding, so no line sits between
   Reference and the About box. (Supersedes the 2026-10-02 rule that
   re-fitted chap21's padding to the box's ::before line.) */
div.chapter:has(+ #end-note) {
  padding-bottom: 0;
  border-bottom: none;
}

/* The divider above Reference is chap21's own border-bottom; its padding now
   comes from the shared div.chapter rules above (2026-10-11), which replace the
   2026-10-02 hand-fit (3.5rem + 0.88em - 3.6px) that used to sit here. */

/* Reference section (Captain order 2026-10-10; Analects' .citations): a
   normal .chapter divider above it (chap21's own border-bottom); no line
   and no bottom padding below it, so the About box closes it. A hanging
   indent, left-aligned (justification would stretch URLs). Scoped to
   #citations; the front colophon shares .source-note and is untouched. */
#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 .permalink {
  overflow-wrap: anywhere;
}

/* 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's 1rem margin-top collapsed with the 0.5em
   margin-bottom of the "1910" p.center above it (both are block siblings)
   and left 17.78 / 17.67 / 17.63 / 17.34px 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()`, as
   div.chapter:has(#chap..) above already does) and margin-top set to
   Analects' 0.35rem (analects.css:415): 7.38 / 7.27 / 7.22 / 6.94px, equal
   to Analects at every width. Colour was already var(--ink-light). Nothing
   below the stamp changes spacing, so the stamp -> source-note line gap
   stays 47.81px above / 40.59px below at every width (measured before and
   after). */
p.center: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-align: center;
  text-indent: 0;
  text-transform: uppercase;
}

/* Footer lines are centred; cancel the body paragraph indent so the text sits on the centre line. */
.site-footer p {
  text-indent: 0;
}
