/* The Magic of Oz.
 *
 * Three rules govern everything below.
 *
 * One: prose measure and reference measure are different problems. A chapter of
 * Baum wants ~34em and nothing else. An index of 426 names wants the whole
 * screen. The old stylesheet gave both of them 42rem, which made the reading
 * pages slightly too wide and the reference pages unusable. --measure and
 * --wide are that distinction, and .shell is what aligns the masthead to
 * whichever one the page is using.
 *
 * Two: script is allowed, but it is first-party, it never phones anywhere, and
 * the page must be complete without it. Search is the one thing that genuinely
 * needs it; everything else here is a link, an anchor, a <details> or a
 * checkbox, and still works with script off.
 *
 * Three: one mode, done properly. This is a paper-and-ink palette — a warm grey
 * ground, near-black ink, emerald and straw out of the books. It is not a
 * light theme awaiting a dark twin.
 */

/* --------------------------------------------------------------- tokens */

:root {
  color-scheme: light;

  /* Ink & Color. The world is painted in ink; magic enters as colour.
     The ground is aged paper, not a light theme's white, and it is the exact
     tone every plate is normalised to — so an illustration's paper and the
     page it sits on are the same sheet, with no visible edge between them.
     Ink is never black. */
  --ground:      #F1EADC;
  --surface:     #F7F2E6;
  --sunk:        #E6DECB;
  --ink:         #2B2721;
  --dim:         #625B4E;
  --rule:        #CBBB99;
  --hair:        #DBCDAD;

  /* Two values per hue. The -plate value is the pigment as it appears in the
     paintings; the plain one is darkened to carry text on paper at 4.5:1.
     Never set type in a -plate colour. */
  --emerald:       #3A6E58;
  --emerald-plate: #4E8F72;
  --emerald-dim:   #E4EDE5;
  --straw:         #A17C33;
  --straw-plate:   #BE9A4E;
  --straw-dim:     #F3EAD3;
  --poppy:         #A8412F;
  --poppy-plate:   #B85541;
  --dorothy:       #4A6E8A;
  --tin:           #9AA0A0;
  /* The two country hues. Gillikin was already being asked for by name on the
     homepage and falling back to a literal, because it had never been defined
     here; the map needs both, so they are tokens now like every other hue. */
  --gillikin:      #857B94;
  --munchkin:      #6E88A3;
  /* The world beyond the desert, for the one moment it is allowed a colour.
     Umber rather than any of the five hues inside Oz — green belongs to the
     Emerald City, and the sand already has the straw. */
  --earth:         #6F5540;
  /* Tints for the world tag on the places index. The index is one A–Z now, so
     the world has to be stated on the row rather than by a heading above it. */
  --earth-dim:     #EDE4D8;
  --dorothy-dim:   #E2E9EF;

  /* Self-hosted by core/fonts.js into /assets/fonts — same-origin woff2, so
     the privacy page's "no third-party requests" stays true for free. */
  --f-display: "Young Serif", "Iowan Old Style", Georgia, serif;
  --f-body:    "Literata", Georgia, "Iowan Old Style", serif;
  --f-ui:      "Outfit", -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;

  /* Matched to the brand guide. --measure is untouched and never should be:
     a chapter of Baum wants ~34em and widening it would make the one thing
     this site exists to do worse. What widens is everything around it — the
     reference rows, the frame and the gutters — which is where the guide got
     its air from. */
  --measure: 34em;   /* prose: a chapter, an essay */
  --wide:    58rem;  /* a single column of reference rows: index, shelf, chapters */
  --frame:   78rem;  /* the widest a page goes: --wide plus the contents rail */
  --gutter:  clamp(20px, 5vw, 48px);
  /* Every citation column on the site — the tables inside an expanded material,
     colour, office or law. Wide enough for the longest citation the corpus can
     produce, "Dorothy and the Wizard in Oz, ch. 20" at 217px, plus the 23px
     inset that lines the column up with the count in the row above it. Measured,
     not chosen: sized to the longest citation currently on a page it would fail
     the first time a longer book was cited. */
  --cite-col: 15rem;
  /* The specimen slot on an expanded index — a painted material, a colour blot,
     an office's emblem — and the air between it and the name. One token for
     both, because .matbody indents by exactly their sum to line the evidence up
     under the name: widening the gap alone would have quietly broken that. */
  --spec-w: 44px;
  --spec-gap: 22px;
  /* The summary's own side padding. It is in the sum too, or the evidence sits
     6px left of the name it belongs to. */
  --row-pad: 6px;
}

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

body {
  margin: 0;
  background: var(--ground);
  color: var(--ink);
  font: 17px/1.62 var(--f-body);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* One shell, three widths. The article takes whichever its page needs; the
   masthead and footer always take the full frame.

   Letting the header track the article width was tried and is wrong twice
   over: on a prose page the wordmark, five nav links and the search field no
   longer fit on one line and the header wraps, and walking from the library to
   a chapter makes the wordmark jump left. A header that moves as you navigate
   reads as a bug. Fixed at the frame it is the edge of the page — which is
   what a masthead is — and no article ever grows past it, so the wordmark is
   never indented inside the text it heads. */
.shell {
  max-width: var(--w);
  margin: 0 auto;
  padding-inline: var(--gutter);
}

.masthead .shell, footer .shell { --w: var(--frame); }

/* Prose measure: a chapter, the front door, a hand-written page. */
body { --w: calc(var(--measure) + 2 * var(--gutter) + 4em); }

/* Everything that is a list of things to find runs the full width of the frame
   — the same edges as the masthead above and the footer below, so the page
   reads as one block rather than a narrow strip inside a wide one. A book's
   chapter list belongs here with the indexes and the shelf: it is a table of
   contents, scanned the same way. Still a single column; it is the column that
   got wider, not the count. */
.tpl-index-list, .tpl-library, .tpl-book, .tpl-entity, .tpl-map,
.tpl-materials, .tpl-scenery, .tpl-colors, .tpl-professions, .tpl-laws, .tpl-leaderboards { --w: var(--frame); }

/* The timeline takes the frame. Collapsed, it is a list of sixty-eight rows
   to scan — which is an index, and indexes get the full width here. It was
   built at --wide with the prose held to a reading measure inside that, and the
   result was a narrow column of text with a third of the page empty beside it.
   Nothing inside caps its own width any more; --frame is the cap. */
.tpl-timeline { --w: var(--frame); }

/* The map template puts its text in .prose, which caps paragraphs at a reading
   measure — right for a chapter, wrong here: this text is a caption to the map,
   and a caption two-thirds the width of the thing it captions reads as a
   mistake. */
.page.mappage .prose p { max-width: none; }

a { color: var(--emerald); text-underline-offset: 3px; }
a:focus-visible, summary:focus-visible, [tabindex]:focus-visible {
  outline: 2px solid var(--emerald);
  outline-offset: 3px;
  border-radius: 2px;
}

.skip {
  position: absolute;
  left: -9999px;
  background: var(--ink);
  color: var(--ground);
  padding: 10px 16px;
}
.skip:focus { left: 12px; top: 12px; z-index: 20; }

/* ------------------------------------------------------------- masthead */

/* No rule under it. The masthead is two icons and a wordmark on the site's own
   paper, and a line beneath them drew a box around chrome that is trying not to
   be a box — the page below already starts where it starts. */
.masthead {
  background: var(--ground);
}

/* On the homepage the plate runs to the very top of the window with nothing
   above it — that edge-to-edge start is most of why the guide's hero worked.
   So the masthead floats on the painting instead of sitting in a bar above it.
   It only works because the top of that plate is bare paper: the nav is ink on
   cream either way, and the hero's own tone is the masthead's background. */
.tpl-home .masthead {
  position: absolute;
  inset: 0 0 auto;
  z-index: 5;
  background: none;
  border-bottom: 0;
}
.tpl-home { position: relative; }
/* The hero starts at the very top, so no padding above it. And less beneath it
   than main gives every other page: measured, the drop from the last line of
   the closing section to the footer's rule was 166px against a 204px gap
   between bands — already tighter than the page's own rhythm, but a page should
   close more decisively than it separates its parts, and it was not doing that. */
.tpl-home main > .home { padding-top: 0; padding-bottom: 34px; }
/* The search field is the one opaque thing up there, so it loses its fill and
   keeps only its rule until it is focused. */
.tpl-home .masthead .search input {
  background: rgba(241, 234, 220, 0.55);
  backdrop-filter: blur(2px);
}
.tpl-home .masthead .search input:focus { background: var(--surface); }

/* ------------------------------------------------- minimal masthead tools */

/* Two icons and a wordmark, on every page. The chrome of a reference site
   should be the quietest thing on screen, and on the homepage it also has to
   sit on a painting without arguing with it. Both buttons and both panels are
   inert until script reveals them, so no-JS keeps the full masthead. */
.mast-tools { display: flex; align-items: center; gap: 2px; margin-left: auto; }
.icon-btn {
  display: none;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  border: 0;
  border-radius: 3px;
  background: none;
  padding: 0;
  cursor: pointer;
  color: var(--ink);
}
.has-tools .icon-btn { display: inline-flex; }
.icon-btn:hover { background: var(--sunk); }
.icon-btn svg { width: 19px; height: 19px; display: block; }
.icon-btn[aria-expanded="true"] { background: var(--sunk); }

.menu-bars {
  width: 18px;
  height: 11px;
  border-top: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  position: relative;
}
.menu-bars::after {
  content: "";
  position: absolute;
  left: 0; right: 0; top: 50%;
  margin-top: -1px;
  border-top: 2px solid currentColor;
}
.menu[aria-expanded="true"] .menu-bars { border-bottom-color: transparent; }

/* Both panels hang off the masthead's shell and share one behaviour.
   Anchoring to the shell rather than the masthead matters: only the homepage
   masthead is positioned (it floats on the hero), so on every other page an
   absolutely-placed panel escaped to the viewport and landed in the wrong
   corner. The shell is positioned everywhere, so both now sit under the icons
   and align with the content edge on every page. */
.masthead .shell { position: relative; }

.has-tools .masthead nav,
.has-tools .masthead .search {
  position: absolute;
  top: calc(100% - 8px);
  right: var(--gutter);
  /* Above the indexes' sticky alphabet, which is z-index 10. Both panels are
     positioned, so they open their own stacking context and everything inside
     them — the results list at z-index 30 included — is trapped underneath
     whatever number is written here. At 6 the A-Z rail slid over the search
     results as the reader scrolled, cutting the list in half. */
  z-index: 20;
  /* the search overrides top/right below to open sideways instead */
  background: var(--ground);
  border: 1px solid var(--rule);
  box-shadow: 0 14px 38px rgba(43, 39, 33, 0.10);
  visibility: hidden;
  opacity: 0;
  transform: translateY(-6px);
  transition: opacity 160ms ease, transform 160ms ease, visibility 160ms;
}
.has-tools .masthead nav {
  flex-direction: column;
  align-items: stretch;
  gap: 0;
  padding: 6px;
  min-width: 12rem;
}
/* Full-width rows, left-aligned, with a real hover target — the right-aligned
   floating words it had before read as a scrap of text rather than a menu. */
.has-tools .masthead nav a {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 8px 12px;
  border-radius: 3px;
  border-bottom: 0;
  text-align: left;
}
/* Matched to .foot-ico rather than sized separately — they are the same five
   marks for the same five doors, and drifting apart would make them read as
   two different sets. */
.nav-ico { width: 19px; height: 19px; flex: none; color: var(--straw); opacity: 0.92; }
.has-tools .masthead nav a:hover .nav-ico,
.has-tools .masthead nav a[aria-current] .nav-ico { color: var(--emerald); opacity: 1; }
.has-tools .masthead nav a:hover { background: var(--sunk); border-bottom: 0; }
.has-tools .masthead nav a[aria-current] { border-bottom: 0; color: var(--emerald); }
/* The search opens sideways, out of its own icon, rather than dropping below
   the masthead: right: 100% against the tools group puts its right edge on the
   group's left edge, and it slides in from the right so the motion comes out of
   the button you pressed. */
.mast-tools { position: relative; }
.has-tools .masthead .search {
  padding: 8px 10px;
  width: min(24rem, calc(100vw - 2 * var(--gutter) - 6rem));
  top: 50%;
  right: calc(100% + 8px);
  transform: translateY(-50%) translateX(10px);
}
/* The open states are written separately, and the search's must stay separate.
   Sharing one rule with the menu meant sharing its transform: none, which at
   equal specificity landed after the centring translateY(-50%) and cancelled
   it — the panel then hung half its own height below the icon instead of
   level with it. The menu drops from the masthead and wants no transform; the
   search is centred on its button and needs to keep one. */
.has-tools.menu-open .masthead nav {
  visibility: visible;
  opacity: 1;
  transform: none;
}
.has-tools.search-open .masthead .search {
  visibility: visible;
  opacity: 1;
  transform: translateY(-50%);
}
@media (max-width: 640px) {
  /* No room beside the icons on a phone, so it goes back under the masthead
     and spans the width, which is the only shape that fits. */
  .has-tools .masthead .search {
    top: calc(100% + 8px);
    right: 0;
    width: min(22rem, calc(100vw - 2 * var(--gutter)));
    transform: translateY(-6px);
  }
  .has-tools.search-open .masthead .search { transform: none; }
}
.has-tools .masthead .search input { width: 100%; }
.masthead .shell {
  display: flex;
  flex-wrap: wrap;
  gap: 10px 32px;
  align-items: center;
  padding-block: 16px;
}

.wordmark {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-right: auto;
  font-size: 20px;
  font-weight: 700;
  letter-spacing: 0.005em;
  color: var(--ink);
  text-decoration: none;
}
/* The mark of the property, not a shout: raised, small, and a step down in
   weight and colour so it never competes with the name it qualifies. It is
   deliberately not in the <title>, headings or prose — only on the wordmark,
   which is the one place the name is being used as a mark rather than read as
   English. The glyph is in the self-hosted latin subset, so it costs nothing. */
.tm {
  font-size: 0.42em;
  font-weight: 500;
  vertical-align: super;
  line-height: 0;
  margin-left: 0.12em;
  color: var(--dim);
  letter-spacing: 0;
}
/* The stroke runs corner to corner of its box, so it needs a little more room
   than a centred glyph did, and object-fit keeps its bleed from being clipped. */
.wordmark .mark { width: 34px; height: 34px; flex: none; object-fit: contain; }
.wordmark span { line-height: 1; }

.masthead nav {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 22px;
  font-family: var(--f-ui);
  font-size: 14px;
}
.masthead nav a {
  color: var(--dim);
  text-decoration: none;
  padding-block: 2px;
  border-bottom: 1.5px solid transparent;
}
/* No wordmark on the homepage. The page prints its own name directly below
   this, ten times the size, and a link home is dead weight on the page you are
   already on — so the masthead there is two icons and nothing else.
   It hides rather than going away: the wordmark keeps its box, so the icons
   opposite stay where they are on every page of the site.
   This was briefly a reveal-on-scroll — hidden over the hero, back once you had
   passed it — which was pointless. The homepage masthead is absolutely
   positioned, not sticky: it scrolls away with the hero, so there is no later
   in which anyone could have seen it come back. */
.tpl-home .masthead .wordmark { opacity: 0; pointer-events: none; }

.masthead nav a:hover { color: var(--emerald); border-bottom-color: var(--emerald); }
.masthead nav a[aria-current] { color: var(--ink); border-bottom-color: var(--straw); }

/* ---------------------------------------------------------------- search */

/* 659 entries behind one field. It sits in the masthead on every page because
   the thing a reader wants next is almost always a name, and until now the only
   way to reach one was to open a 426-entry index and scroll.

   The field is [hidden] in the HTML and revealed by search.js, so it never
   appears as a dead box. The nav beside it is the fallback and a real one. */

.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.search {
  position: relative;
  flex: 1 1 13rem;
  max-width: 20rem;
  margin: 0;
  border: 0;
  padding: 0;
}
.search[hidden] { display: none; }

.search input {
  width: 100%;
  padding: 8px 32px 8px 12px;
  border: 1px solid var(--rule);
  border-radius: 3px;
  background: var(--surface);
  color: var(--ink);
  font-family: var(--f-ui);
  font-size: 14px;
  line-height: 1.3;
  appearance: none;
}
.search input::placeholder { color: var(--dim); opacity: 1; }
.search input:focus {
  outline: none;
  border-color: var(--emerald);
  box-shadow: 0 0 0 3px var(--emerald-dim);
}
.search input::-webkit-search-cancel-button { appearance: none; }

/* The shortcut, shown rather than documented. Hidden once the field is focused,
   where it would be telling the reader something they have already done. */
.search kbd {
  position: absolute;
  top: 50%;
  right: 9px;
  transform: translateY(-50%);
  padding: 1px 6px;
  border: 1px solid var(--rule);
  border-radius: 3px;
  background: var(--ground);
  color: var(--dim);
  font-family: var(--f-ui);
  font-size: 11px;
  line-height: 1.5;
  pointer-events: none;
}
.search input:focus ~ kbd, .search input:not(:placeholder-shown) ~ kbd { display: none; }

.results {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  right: 0;
  z-index: 30;
  max-height: min(70vh, 30rem);
  overflow-y: auto;
  background: var(--surface);
  border: 1px solid var(--rule);
  border-radius: 3px;
  box-shadow: 0 8px 28px rgba(20, 32, 27, 0.13);
}
.results[hidden] { display: none; }
.results ul { list-style: none; margin: 0; padding: 4px; }

.results a {
  display: block;
  padding: 8px 10px;
  border-radius: 2px;
  text-decoration: none;
  color: var(--ink);
}
.results li[aria-selected="true"] a, .results a:hover { background: var(--emerald-dim); }

.sr-name { font-size: 15.5px; }
.sr-name mark {
  background: none;
  color: var(--emerald);
  font-weight: 700;
}
.sr-kind {
  margin-left: 8px;
  font-family: var(--f-ui);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--straw);
}
.sr-sum {
  display: block;
  margin-top: 1px;
  font-family: var(--f-ui);
  font-size: 12.5px;
  line-height: 1.4;
  color: var(--dim);
}
.sr-empty { margin: 0; padding: 14px 14px; font-size: 14px; color: var(--dim); }

@media (max-width: 640px) {
  .search { order: 3; flex-basis: 100%; max-width: none; }
}

main { display: block; }
main > * { padding-block: clamp(28px, 5vw, 52px) 80px; }

/* --------------------------------------------------------------- typography */

/* Young Serif carries every title. It is a single weight by design — the
   display face never bolds, it only changes size, which is the typographic
   equivalent of the restraint the plates are painted with. */
h1 {
  font-family: var(--f-display);
  font-weight: 400;
  font-size: clamp(34px, 5.4vw, 52px);
  line-height: 1.06;
  letter-spacing: -0.02em;
  text-wrap: balance;
  margin: 0 0 12px;
}

/* h2 was doing two jobs — a big section heading and a small caps label — and
   the label won, which is why every page read flat. They are separate now.
   Bare h2 is a display heading; h2.label is the caps rule for the structural
   labels inside an entity or a chapter. */
h2 {
  font-family: var(--f-display);
  font-weight: 400;
  font-size: clamp(25px, 3.4vw, 34px);
  line-height: 1.12;
  letter-spacing: -0.012em;
  text-wrap: balance;
  color: var(--ink);
  margin: 46px 0 14px;
}

h2.label {
  font-family: var(--f-ui);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: var(--dim);
  margin: 44px 0 14px;
  padding-bottom: 8px;
  border-bottom: 1px solid var(--rule);
  line-height: 1.3;
}

/* The eyebrow: a coloured rule, then the label. The dash is the only place on
   a page where a plate colour is allowed to appear as flat UI, because it is a
   mark rather than type — it reads as a stroke of pigment laid on the paper.
   Set --accent on the section to change it. */
.eyebrow {
  display: flex;
  align-items: center;
  gap: 10px;
  font-family: var(--f-ui);
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--dim);
  margin: 0 0 14px;
}
.eyebrow::before {
  content: "";
  width: 26px;
  height: 3px;
  border-radius: 2px;
  background: var(--accent, var(--emerald-plate));
  flex: none;
}

h3 { font-family: var(--f-display); font-weight: 400; font-size: 19px; margin: 0 0 6px; }
p { margin: 0 0 14px; }

.kind {
  font-family: var(--f-ui);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--straw);
  margin: 0 0 6px;
}

.note { color: var(--dim); font-size: 14.5px; max-width: var(--measure); }
.qualify { color: var(--dim); font-size: 13px; }
.credits { color: var(--dim); }

.breadcrumb {
  display: flex;
  align-items: center;
  gap: 10px;
  font-family: var(--f-ui);
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--dim);
  margin-bottom: 14px;
}
/* The breadcrumb is the eyebrow. It already sat exactly where one goes — above
   the title, naming the section — so it gets the coloured rule rather than a
   second competing device being invented next to it. The colour says which
   part of the site you are in. */
.breadcrumb::before {
  content: "";
  width: 26px;
  height: 3px;
  border-radius: 2px;
  background: var(--accent, var(--emerald-plate));
  flex: none;
}
.tpl-chapter .breadcrumb, .tpl-book .breadcrumb { --accent: var(--straw-plate); }
.tpl-entity .breadcrumb { --accent: var(--poppy-plate); }
.breadcrumb a { color: var(--dim); text-decoration: none; }
.breadcrumb a:hover { color: var(--emerald); text-decoration: underline; }

/* ------------------------------------------------------------ front door */

/* The hero is a plate, full width, with the title sitting in its empty sky.
   It works because the painting's paper is the same tone as the page: there is
   no frame, no card and no visible edge — the illustration simply stops being
   painted and the page carries on. That is the whole idea of the system, said
   once at the top before anything is explained. */
.hero {
  position: relative;
  margin-block: 0 clamp(30px, 5vw, 52px);
  background: var(--ground);
}
/* Cropped from the bottom, not the middle: the road and the traveller live in
   the lower third and the top of the plate is empty sky, so a tall viewport
   should gain sky and a short one should never lose the road. */
/* Taller than it needs to be, on purpose. The plate is nine tenths empty sky
   and the height is what lets that emptiness register as space rather than as
   a band of blank at the top of a web page. */
/* Transparent text, so the alt never paints. The plate is the largest image on
   the site and the browser reserves its full box before a byte of it arrives;
   in that gap a two-line description of the painting flashed across the sky
   under the title. The hero is preloaded ahead of the stylesheets so the gap is
   as short as it can be, but on a cold connection it is never zero. Nothing is
   lost by hiding it: the alt is still there for a screenreader, and the one
   thing it says that a reader needs — that this is Oz — is set over it in
   96px. */
.hero img {
  color: transparent;
  display: block;
  width: 100%;
  height: auto;
  max-height: 78vh;
  object-fit: cover;
  object-position: 50% 100%;
}
/* Fades the plate's lower edge into the page so the join is invisible. */
.hero::after {
  content: "";
  position: absolute;
  inset: auto 0 -1px 0;
  height: 34%;
  background: linear-gradient(to top, var(--ground) 2%, rgba(241,234,220,0.72) 34%, rgba(241,234,220,0) 100%);
  pointer-events: none;
}
.hero-words {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  padding-bottom: clamp(14px, 3vw, 34px);
  z-index: 1;
}
.hero-words .shell { width: 100%; --w: var(--frame); }

/* The homepage title is the wordmark, not a heading — it is the largest thing
   on the site by a wide margin, because it sits in an acre of empty sky and
   has to hold it. */
.home h1 {
  font-size: clamp(40px, 8.2vw, 96px);
  line-height: 0.94;
  letter-spacing: -0.032em;
  margin: 0;
}
/* Two lines, doing two different jobs. The first is Baum's promise and is set
   in ink at full strength; the second is the plain answer to "what is this",
   and is quieter. One without the other is either poetry with no substance or
   substance with no invitation. */
.standfirst {
  font-family: var(--f-ui);
  font-weight: 400;
  font-size: clamp(15px, 1.75vw, 19px);
  line-height: 1.5;
  color: var(--dim);
  margin: 16px 0 0;
  max-width: 38em;
}
.standfirst b {
  display: block;
  font-weight: 500;
  color: var(--ink);
  margin-bottom: 3px;
}
/* The kicker scales with the title rather than sitting at a fixed small size —
   at 96px of wordmark a 12px kicker disappears. It is the only vermilion on
   the page and the only thing that announces itself. */
.hero-kicker {
  display: block;
  font-family: var(--f-ui);
  font-size: clamp(11px, 1.5vw, 17px);
  font-weight: 600;
  letter-spacing: 0.38em;
  text-transform: uppercase;
  color: var(--poppy);
  margin: 0 0 clamp(12px, 1.6vw, 22px);
}
.home > .shell > p:first-of-type { margin-top: 4px; }

/* Every shell on the homepage is the full frame, and the prose is narrowed by
   max-width inside it rather than by being centred in a smaller shell. Two
   centred shells of different widths give a page two different left edges,
   which is what made the doors and the paragraphs above them look unrelated.
   One edge, several widths — the way the guide is built. */
.home > .shell { --w: var(--frame); }
/* The opening paragraphs run the full frame like everything else on this page.
   Constraining them to the reading measure made them a narrow column floating
   in the middle of a wide page — the measure is for chapters, not for a front
   door that is mostly pictures. */
.home > .shell > .note,
.home > .shell > h2 { max-width: 52em; }
.home > .shell > p { max-width: 46em; }
/* The library band. The plate is the larger half of the pair, because it is
   the thing worth looking at and the prose is only there to be read. It leads
   on the left so the reader meets the books before the sentence about them. */
.libband { margin-top: 0 !important; }
.libband::before { display: none; }
.libband-inner {
  display: grid;
  grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
  gap: clamp(26px, 4vw, 56px);
  align-items: center;
  padding-top: clamp(30px, 5vw, 56px);
}
.lib-art { display: block; width: 100%; height: auto; }
.lib-copy h2 { margin: 10px 0 14px; }
.lib-copy p { max-width: 40em; }
@media (max-width: 46rem) {
  .libband-inner { grid-template-columns: 1fr; }
}
/* The doors are a plain shell rather than a band, so they get no rule above
   them and need their own clearance from whatever ran before. */
.doors-shell { --w: var(--frame); margin-top: clamp(34px, 5vw, 60px); }

/* ------------------------------------------------------- homepage bands */

/* Bands are separated by space and a hairline, never by a fill. The page is
   one sheet of paper from the hero to the footer. */
/* The rule between bands stops where the content stops. A line running the
   full width of the window is a piece of furniture drawn across the page; one
   that matches the column is the page breathing. So the border lives on the
   shell, not on the section. */
.home .band {
  padding-block: 0;
  margin-top: clamp(36px, 5vw, 60px);
}
.home .band > .shell { --w: var(--frame); }
/* The rule hangs off the section, never off a shell. A shell may be a flex or
   grid container — the band head is, and so is the start block — and a
   pseudo-element inside one of those is not decoration, it is a layout item:
   it pushed the band head to the centre and knocked the start band's columns
   apart. On the block-level section it is just a line. */
.home .band::before {
  content: "";
  display: block;
  height: 1px;
  background: var(--hair);
  width: min(var(--frame) - 2 * var(--gutter), 100% - 2 * var(--gutter));
  margin: 0 auto clamp(34px, 5vw, 58px);
}
.home .band h2 { margin-top: 0; }
.home .band .note, .home .band > .shell > p { max-width: var(--measure); }

.band-head { display: flex; align-items: baseline; justify-content: space-between; gap: 20px; flex-wrap: wrap; }
.band-head .eyebrow { margin-bottom: 0; }
.band-all, .start-link {
  font-family: var(--f-ui);
  font-size: 14px;
  font-weight: 500;
  color: var(--emerald);
  text-decoration: none;
  white-space: nowrap;
}
.band-all:hover, .start-link:hover { text-decoration: underline; }

/* The cast uses .entity-list / .card straight from the indexes — same rows,
   same chevron, no homepage-only variant to keep in sync. */
.home .band .entity-list { margin-top: 20px; }

/* The homepage map is the atlas itself — same figure, same toolbar, same
   script — so it needs no styling of its own. The .mapband-view rules that
   used to live here dressed a still image that no template emits any more. */
.mapband .note { margin-top: 0; }

/* The last band on the page, and the seal closes it — set low and right so it
   sits in the corner of the page the way a seal sits in the corner of a sheet,
   which gives the bottom of the homepage an edge it did not have. Empty alt:
   the paragraph beside it already says everything the mark stands for. */
/* Two columns on the band above's own ratio, mirrored — plate left and copy
   right up there, copy left and seal right down here. Letting the copy run to
   the full width while the seal took only what it needed left the section
   without the halves the rest of the page is built on, and the mark reading as
   an afterthought parked in the margin rather than as the thing that closes the
   page. */
.prov-inner {
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
  gap: clamp(24px, 4vw, 52px);
  align-items: end;
}
.prov-seal {
  width: clamp(92px, 11vw, 144px);
  height: auto;
  justify-self: end;
  align-self: end;
  /* Sits into the foot of the band rather than on the baseline of the last
     line, so it reads as pressed into the corner of the sheet. */
  margin-bottom: clamp(-4px, -1vw, -16px);
  opacity: 0.94;
  /* It is a stamp on the page, not a picture in the flow — nothing should read
     it as something to click or look into. */
  pointer-events: none;
}
@media (max-width: 700px) {
  .prov-inner { grid-template-columns: 1fr; gap: 20px; }
  .prov-seal { justify-self: end; width: clamp(76px, 22vw, 104px); }
}

/* Start reading: the plate on one side, the way in on the other. */
.start-inner {
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
  gap: clamp(24px, 4vw, 52px);
  align-items: center;
}
.start-art { display: block; width: 100%; height: auto; }
.start-copy h2 { margin: 10px 0 8px; }
/* :not(.eyebrow) matters — a bare `.start-copy p` outranks `.eyebrow` on
   specificity and was quietly setting this one eyebrow to 14px while every
   other on the site sat at 11.5px. */
.start-copy p:not(.eyebrow) { font-family: var(--f-ui); font-size: 14px; color: var(--dim); margin: 0 0 10px; }
.start-lede { font-family: var(--f-body) !important; font-size: 16.5px !important; line-height: 1.6; color: var(--ink) !important; max-width: 32em; }
@media (max-width: 46rem) {
  .start-inner { grid-template-columns: 1fr; }
}

/* The five ways in. These are the whole navigation of the site for a first-time
   reader, so they are doors rather than list items: the name carries the weight
   and the count underneath tells you what is behind it. */
/* Each door gets a vignette, and the vignettes are the argument: five small
   paintings that are mostly empty paper, so the row reads as a sheet with five
   marks on it rather than as five cards. No borders and no panels — the
   pictures sit directly on the page, exactly as the plates do. */
/* The doors get the full frame rather than the prose measure, so five of them
   sit in one row and read as a single sheet of five marks. Below that width
   they wrap, which is fine — what must not happen is 3+2, which looks like a
   grid that ran out. */
.doors {
  list-style: none;
  padding: 0;
  margin: clamp(30px, 5vw, 46px) 0 40px;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(136px, 1fr));
  gap: clamp(16px, 2.4vw, 26px);
}
@media (min-width: 62rem) {
  .doors { grid-template-columns: repeat(5, 1fr); }
}
.doors li { background: none; }
.doors li a {
  display: block;
  padding: 0;
  text-decoration: none;
  font-size: 19px;
}
.doors .door-art {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 1;
  object-fit: cover;
  margin-bottom: 10px;
  /* The plate and the page share a paper tone, so the only thing that should
     change on hover is the ink getting a shade stronger. */
  filter: saturate(0.94) contrast(0.98);
  transition: filter 260ms ease;
}
.doors li a:hover .door-art,
.doors li a:focus-visible .door-art { filter: saturate(1.06) contrast(1.05); }
.doors li a:hover { background: none; }
.doors li a:hover .door-name { color: var(--emerald); text-decoration: underline; }
.doors .door-name {
  color: var(--ink);
  display: block;
  font-family: var(--f-display);
  line-height: 1.15;
}
.doors span:not(.door-name):not(.door-art) {
  display: block;
  margin-top: 4px;
  color: var(--dim);
  font-size: 13.5px;
  line-height: 1.45;
  font-family: var(--f-ui);
}

/* The five doors stay stacked. Two abreast made the reader choose between
   columns before choosing a door, and the front page is the one place worth
   spending a whole line on each way in. */

/* ---------------------------------------------------------------- indexes */

/* 426 names in one column was a scroll, not an index. Three things fix it and
   none of them need script: the alphabet is a row of anchors at the top, the
   entries flow into as many columns as the window allows, and each letter is a
   scroll target with its own heading. Ctrl-F still works over all of it,
   because all of it is in the page. */

.az {
  position: sticky;
  top: 0;
  z-index: 10;
  display: flex;
  flex-wrap: wrap;
  gap: 2px;
  margin: 22px 0 8px;
  padding: 10px 0;
  background: var(--ground);
  border-bottom: 1px solid var(--rule);
  font-family: var(--f-ui);
}
/* The alphabet spreads to fill the column rather than sitting at a fixed size.
   At a fixed 1.85em a 27-letter rail is wider than the single-column measure
   and wrapped, leaving Z alone on a second line. Letting each letter flex means
   the rail is always exactly one line and always the width of the list it
   points into. */
.az a, .az span {
  flex: 1 1 auto;
  min-width: 1.35em;
  padding: 3px 0;
  text-align: center;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.02em;
  border-radius: 3px;
  text-decoration: none;
}
.az a { color: var(--emerald); }
.az a:hover { background: var(--emerald); color: var(--ground); }
.az span { color: var(--rule); }          /* a letter nothing is filed under */
.az .all { flex: 0 0 auto; min-width: auto; padding-inline: 10px; color: var(--dim); }

/* One column, each letter section running the full width of it.

   Multi-column was denser and worse to read: the eye has to find the top of the
   next column, an entry's blurb wraps every four or five words, and a name and
   the chapter it comes from end up on different lines for no reason but the
   column being narrow. One column gives each entry a whole line, which is what
   a reference entry wants. The A–Z rail is what makes the length navigable.

   .entities is the plain block that wraps the letter headings and their lists;
   it carries no column properties, and should not grow any. */
.entity-list { list-style: none; padding: 0; margin: 0; }

/* ------------------------------------------------------------------ cards */

/* One treatment for every row that is really a link: an index entry, a book on
   the shelf, a chapter in a book. The whole row is the target, it says so on
   hover, and a chevron at the right edge says so before you hover.

   The motion is deliberately small — a hairline ground, a hair of movement, a
   chevron that slides a couple of pixels. This is a paper-and-ink site and a
   card that lifts off the page with a shadow would be borrowed from a different
   one. What matters is that the row answers when you point at it. */
.card {
  display: flex;
  align-items: baseline;
  gap: 4px 16px;
  padding: 13px 14px 13px 12px;
  margin-left: -12px;
  border-radius: 3px;
  color: inherit;
  text-decoration: none;
  border-left: 2px solid transparent;
  transition: background-color 0.13s ease, border-color 0.13s ease, transform 0.13s ease;
}
.card-main { flex: 1 1 auto; min-width: 0; }

a.card:hover {
  background: var(--surface);
  border-left-color: var(--emerald);
  transform: translateX(2px);
}
a.card:focus-visible {
  outline: 2px solid var(--emerald);
  outline-offset: -2px;
  background: var(--surface);
}

/* The affordance, before the pointer arrives: present but quiet, and it moves
   with the row rather than appearing out of nothing on hover — an icon that
   only exists on hover cannot tell anyone the row is clickable. */
.go {
  flex: none;
  align-self: center;
  font-size: 19px;
  line-height: 1;
  color: var(--rule);
  transition: color 0.13s ease, transform 0.13s ease;
}
a.card:hover .go, a.card:focus-visible .go {
  color: var(--emerald);
  transform: translateX(3px);
}

a.card:hover .name, a.card:focus-visible .name,
a.card:hover .title, a.card:focus-visible .title,
a.card:hover .ct, a.card:focus-visible .ct { color: var(--emerald); }

/* A book with no chapters yet is not a link, so it gets none of this. */
span.card { cursor: default; }

/* The letter a group is filed under. Full width, with the rule running the
   whole measure so it reads as a section divider rather than a label. */
.letter {
  margin: 34px 0 4px;
  padding: 0 0 8px;
  font-family: var(--f-body);
  font-size: 22px;
  font-weight: 700;
  letter-spacing: 0;
  text-transform: none;
  color: var(--straw);
  border-bottom: 1px solid var(--straw-dim);
  scroll-margin-top: 72px;
}
/* The first letter keeps the same space above it as every other letter. Zeroing
   it pulled A up tight under the alphabet rail while B, C and D each sat in
   their own air, so the top of the list was a different shape from the rest of
   it for no reason a reader could see. */

/* The row's padding lives on the card now, so the <li> carries only the rule
   between entries. */
.entities li { padding: 0; margin: 0; border-bottom: 1px solid var(--hair); }
/* A separator goes between things. The last row of a letter group keeps its
   rule because it is separating the group from the heading below it — but the
   last row of the last group has nothing under it to be separated from, and the
   rule just dangles. On the homepage cast it dangled straight into the band
   divider a few pixels below, which read as two lines by mistake rather than
   one on purpose. */
.entities .entity-list:last-child li:last-child { border-bottom: 0; }
.entities .name { font-size: 17px; color: var(--emerald); transition: color 0.13s ease; }
.entities .blurb {
  display: block;
  margin-top: 2px;
  font-size: 15px;
  line-height: 1.45;
  color: var(--ink);
}
.entities .meta {
  display: block;
  margin-top: 4px;
  font-family: var(--f-ui);
  font-size: 12.5px;
  color: var(--dim);
}

/* A creature is not a person, and the combined index gave no way to tell them
   apart short of opening the page. One quiet word does it. */
.entities .tag {
  font-family: var(--f-ui);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--straw);
  margin-left: 7px;
  vertical-align: 1px;
}

/* The page's own contents, for an index that is really three indexes. Set as
   a row of targets rather than a bulleted list, because it is navigation. */
.worldnav {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin: 24px 0 8px;
  padding-bottom: 4px;
}
.worldnav a {
  display: flex;
  align-items: baseline;
  gap: 9px;
  padding: 8px 14px;
  border: 1px solid var(--rule);
  border-radius: 20px;
  background: var(--surface);
  font-family: var(--f-ui);
  font-size: 13.5px;
  color: var(--ink);
  text-decoration: none;
  transition: border-color 0.13s ease, color 0.13s ease;
}
.worldnav a:hover { border-color: var(--emerald); color: var(--emerald); }
.worldnav .wn-count {
  font-size: 11.5px;
  font-variant-numeric: tabular-nums;
  color: var(--straw);
}

.worldgroup { margin-top: 44px; scroll-margin-top: 20px; }
.worldgroup > h2 {
  font-family: var(--f-body);
  font-size: 24px;
  font-weight: 700;
  letter-spacing: -0.01em;
  text-transform: none;
  color: var(--ink);
  border-bottom-width: 2px;
  border-bottom-color: var(--ink);
}

.countline {
  font-family: var(--f-ui);
  font-size: 13px;
  color: var(--dim);
  margin: 0;
}

/* ----------------------------------------------------------- entity pages */

/* An entity page is eight sections and, for Dorothy, fifty-seven kilobytes.
   On a wide screen the section list becomes a rail beside the article: the
   reader can see the shape of the page and jump into it. Below that width it
   is a plain row of links above the article, which is the same information in
   the shape a phone can use. Anchors only. */

@media (min-width: 1000px) {
  /* The body column is capped near the reading measure and the rail is pushed
     to the far edge of the frame, so the article lines up under the wordmark
     and the rail lines up under the search field, instead of both drifting
     into the middle of a wide window. */
  .entity {
    display: grid;
    /* The rail was 13rem, which was sized for a contents list and not for a
       picture. The frame is 78rem and the grid spends 46rem + 13rem + 44px of
       it, so the surplus was going into the gap between the two columns —
       space-between was pushing them apart rather than giving the rail room.
       At 18rem the prose column is untouched and the plates get 38% more
       width, which lands where it is needed: a tall figure is capped by height
       and does not change, while a wide subject like a country or the Magic
       Belt was being squeezed by the column, not by its own proportions. */
    grid-template-columns: minmax(0, 46rem) 18rem;
    justify-content: space-between;
    gap: 0 44px;
    align-items: start;
  }
  .entity > * { grid-column: 1; min-width: 0; }
  .entity > .entity-rail {
    grid-column: 2;
    grid-row: 1 / span 99;
    /* Stretch, against the grid's align-items: start. A sticky child can only
       travel inside its own containing block, so a rail that shrank to the
       height of the portrait plus the nav gave the nav nowhere to stick — it
       simply scrolled away. When .contents was itself the grid item its
       containing block was the whole row span, which is why it used to work. */
    align-self: stretch;
  }
  /* The contents sticks; the portrait does not. Sticking the whole rail carried
     the figure down the page alongside the reader, which made a drawing that is
     meant to sit at the head of the page behave like a piece of chrome. The
     rail already spans every row, so the nav sticking inside it behaves exactly
     as it did before the portrait existed. */
  .entity-rail .contents { position: sticky; top: 24px; margin: 0; }
}

.contents {
  margin: 0 0 30px;
  padding: 14px 0;
  border-block: 1px solid var(--rule);
  font-family: var(--f-ui);
}
.contents h2 {
  margin: 0 0 8px;
  padding: 0;
  border: 0;
  font-size: 11px;
}
.contents ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 4px 18px;
}
.contents a {
  font-size: 13.5px;
  color: var(--dim);
  text-decoration: none;
  padding-block: 2px;
}
.contents a:hover { color: var(--emerald); text-decoration: underline; }

@media (min-width: 1000px) {
  .contents { border: 0; padding: 0; border-left: 1px solid var(--rule); padding-left: 18px; }
  .contents ul { flex-direction: column; gap: 7px; }
}

.entity section { scroll-margin-top: 24px; }

.aliases { color: var(--dim); font-style: italic; margin: 0 0 16px; }

/* The summary is the first thing a reader wants and the thing most of these
   pages lacked, so it carries the weight of the page rather than sitting in the
   same grey as the metadata around it. */
.entity .summary {
  font-size: 20px;
  line-height: 1.5;
  color: var(--ink);
  max-width: var(--measure);
  margin: 0 0 16px;
}
.first { color: var(--dim); margin: 0; }

.confidence { font-size: 13.5px; color: var(--dim); margin: 12px 0 0; max-width: var(--measure); }
.confidence.confirmed { color: var(--emerald); }

/* How sure we are, said plainly next to the claim itself. */
.ev {
  font-family: var(--f-ui);
  font-size: 10.5px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  cursor: help;
}
.ev.confirmed   { color: var(--emerald); }
.ev.plausible   { color: var(--straw); }
.ev.unconfirmed { color: var(--poppy); }
.ev.disputed    { color: var(--poppy); text-decoration: line-through; }

.cites { list-style: none; padding: 0; margin: 0; }
.cites li { padding-bottom: 10px; margin-bottom: 10px; border-bottom: 1px solid var(--hair); }
.cite { font-family: var(--f-ui); font-size: 13px; color: var(--dim); }
.cite:hover { color: var(--emerald); }

.rel {
  color: var(--straw);
  font-variant: small-caps;
  letter-spacing: 0.04em;
}

/* One claim per row — "friend of Ozma" — with its evidence folded away behind
   a toggle labelled with the number of chapters that state it. The claim reads
   as a sentence; the count sits at the right edge so the counts line up down
   the list and the better-attested connections are visible at a glance. */
.relations { list-style: none; padding: 0; margin: 0; }
.relations > li { border-bottom: 1px solid var(--hair); }

/* The whole row is the summary, so the count keeps its place in the right hand
   column whether the row is open or shut. Opening only adds the body beneath
   it — the control the reader just clicked does not move out from under the
   pointer they would use to close it again. */
.relev summary {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: baseline;
  gap: 4px 16px;
  padding: 11px 0;
  cursor: pointer;
  list-style: none;
}
.relev summary::-webkit-details-marker { display: none; }
.relev summary:hover .relcount { color: var(--emerald); }
.relev summary:focus-visible { outline: 2px solid var(--emerald); outline-offset: -2px; border-radius: 2px; }

.relations .relclaim { grid-column: 1; font-size: 16.5px; }

/* No reserved column for the relationship. Holding it to 7.5em was meant to
   line the names up, and it did the opposite: short labels got a gap wide
   enough to read as a missing word ("friend of      Dorothy Gale"), while
   "transformed into" overran the column and butted straight against its name.
   Set as a phrase, every row reads the same way — which is how the claim is
   spoken anyway. */
/* The relationship gets the same breathing room on both sides. It only had it
   on the right, so "Gargoyles enemy of  Dorothy Gale" sat tight against the
   name before it and loose against the name after — and because the label
   widths differ, the second name landed somewhere different on every row. Even
   margins also make an inbound row space exactly like an outbound one, where
   the label leads and the gap after it is all there is. */
.relations .rel { margin-right: 0.35em; }
.relations .relclaim > .rel:not(:first-child) { margin-left: 0.35em; }

.relcount {
  grid-column: 2;
  justify-self: end;
  font-family: var(--f-ui);
  font-size: 11.5px;
  letter-spacing: 0.05em;
  color: var(--dim);
  white-space: nowrap;
}
.relcount::after {
  content: "▸";
  display: inline-block;
  margin-left: 7px;
  color: var(--straw);
  font-size: 12px;
  vertical-align: -1px;
}
.relev[open] .relcount::after { content: "▾"; }

.relev-body {
  padding: 0 0 14px 14px;
  border-left: 2px solid var(--straw-dim);
  margin-left: 2px;
}
.relations .where { display: block; margin: 0; font-family: var(--f-ui); font-size: 12.5px; color: var(--dim); }
.relations .pull { margin-top: 7px; font-size: 15.5px; }

.pull {
  margin: 8px 0 0;
  padding-left: 14px;
  border-left: 2px solid var(--rule);
  color: var(--dim);
  font-style: italic;
  max-width: var(--measure);
}
.first-quote { margin-top: 8px; }

/* The books in their own words — the best content on the page, set like it. */
.described-quote {
  margin: 0 0 18px;
  padding: 2px 0 2px 18px;
  border-left: 3px solid var(--straw);
  font-size: 17.5px;
  line-height: 1.55;
  max-width: var(--measure);
}
.described-quote cite {
  display: block;
  margin-top: 7px;
  font-family: var(--f-ui);
  font-size: 12.5px;
  font-style: normal;
  color: var(--dim);
}

.names b { font-size: 15.5px; }
.names .meta { display: block; font-family: var(--f-ui); font-size: 12.5px; color: var(--dim); }

/* Where the books disagree.
 *
 * This is the site's editorial position made visible — every other Oz reference
 * has had to choose a side — and it was rendering as a pale warning box with
 * the passages in a bullet list, which made a deliberate stance look like a
 * validation error. The panel is gone. What is left is the explanation, and
 * then the passages themselves set side by side as evidence, each over the
 * author who wrote it and the year they wrote it, so a reader can see the
 * disagreement rather than be told about it. */

/* The explanation is ordinary prose — the same paragraph the rest of the page
   uses — because it is ordinary prose. Styling it as its own panel made the
   section read as two competing blocks before the evidence had even started.
   The section is one block: a sentence saying what the disagreement is, then
   the passages that constitute it. */
.entity #disagree > p { max-width: var(--measure); }

/* A quoted passage looks the same wherever it appears. These are the same kind
   of object as the ones under "As the books describe them" — the books' own
   words with a citation under them — so they get the same treatment: a straw
   rule down the left and nothing else. Boxing them in bordered white panels
   made three quotations look like an alert about a problem, which is the
   opposite of the point: the disagreement is the content, not a warning. */
.sides {
  list-style: none;
  margin: 20px 0 0;
  padding: 0;
}
.sides li {
  margin: 0 0 18px;
  padding: 2px 0 2px 18px;
  border-left: 3px solid var(--straw);
}
.sides li:last-child { margin-bottom: 0; }
.sides blockquote {
  margin: 0;
  padding: 0;
  border: 0;
  max-width: var(--measure);
  font-size: 17.5px;
  line-height: 1.55;
  color: var(--ink);
}
.sides .side-src {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 2px 8px;
  margin: 7px 0 0;
  font-family: var(--f-ui);
  font-size: 12.5px;
  color: var(--dim);
}
.sides .side-who { color: var(--dim); }
.sides .side-where::before,
.sides .side-year::before { content: "·"; margin-right: 8px; color: var(--straw); }

/* Worked out rather than quoted: present, useful, and visibly not the same kind
   of thing as a citation. */
.derived .cites li { border-bottom-style: dashed; }
.derived .how { display: block; margin-top: 3px; font-family: var(--f-ui); font-size: 12.5px; color: var(--dim); }

.inline {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 7px 18px;
}
.together .inline li { display: flex; align-items: baseline; gap: 5px; }
.together .n { color: var(--straw); font-family: var(--f-ui); font-size: 11px; font-variant-numeric: tabular-nums; }

/* ----------------------------------------------- appearances, by book */

/* A book, and how much of it a thing is in. The coverage line is the point:
   "all 24 chapters" tells a reader more than twenty-four links they will not
   follow. <details> keeps this working with no JavaScript on the page. */

/* Bottom rules only, like the relations list and the index rows. The first
   group used to add a top border of its own, which drew a second line 14px
   under the one h2.label already draws beneath the section heading — two rules
   with a gap between them, where every other section on the page has one. */
.bookgroup { border-bottom: 1px solid var(--hair); }
/* Laid out like every other row on the site that opens or leads somewhere: the
   thing you are reading on the left, its count in a right-hand column, and the
   chevron at the far right edge. It used to carry a small triangle tucked in
   front of the title, which is the one place the site does not put its
   affordances — the cards, the index rows and the relations all keep the mark
   at the end of the row. Same three columns as .relev, so Appears in and
   Connections read as the same kind of list. */
.bookgroup summary {
  display: grid;
  grid-template-columns: 1fr auto auto;
  align-items: baseline;
  gap: 4px 16px;
  padding: 12px 0;
  cursor: pointer;
  list-style: none;
}
.bookgroup summary::-webkit-details-marker { display: none; }
.bookgroup summary::after {
  content: "\203A";
  align-self: center;
  font-size: 19px;
  line-height: 1;
  color: var(--rule);
  transition: color 0.13s ease, transform 0.13s ease;
}
.bookgroup summary:hover::after { color: var(--emerald); }
/* Turned down rather than nudged along: this one opens in place, it does not
   take you anywhere. */
.bookgroup[open] summary::after { transform: rotate(90deg); color: var(--emerald); }
.bookgroup summary:hover .bt { color: var(--emerald); }
.bookgroup .bt { font-size: 16.5px; }
.bookgroup .cov { font-family: var(--f-ui); font-size: 12.5px; color: var(--dim); }

/* Chapters read as chapters, not as a row of numbers: the number keeps its
   column so the titles line up, and the title is what you actually scan.
   Unlike the name lists, which became bare numbers, the title stays here — this
   is somebody browsing which chapters a character is IN, and the title is the
   answer, not decoration.
   So the condensing is done with the width instead: two columns, which is what
   `break-inside: avoid` on the item below was written for and never got. All
   24 chapters of The Wonderful Wizard ran 819px down a column half the width of
   the page; paired they are 410 and the empty half is used. */
.chapterlinks {
  list-style: none;
  margin: 0 0 12px;
  padding: 0 0 0 1.6em;
  columns: 2;
  column-gap: 30px;
}
@media (max-width: 46rem) { .chapterlinks { columns: 1; } }
.chapterlinks li { break-inside: avoid; margin: 0; }
.chapterlinks a {
  display: flex;
  gap: 10px;
  align-items: baseline;
  padding: 4px 6px 4px 0;
  border-radius: 3px;
  text-decoration: none;
  font-size: 14.5px;
}
.chapterlinks a:hover { background: var(--surface); }
.chapterlinks .n {
  flex: none;
  width: 2em;
  text-align: right;
  color: var(--straw);
  font-family: var(--f-ui);
  font-size: 12.5px;
  font-variant-numeric: tabular-nums;
}
.chapterlinks .ct { color: var(--ink); }
.chapterlinks a:hover .ct { color: var(--emerald); }

/* ---------------------------------------------------------- the library */

/* Twenty-five books set as a bulleted list read as a bibliography. A library is
   a thing you look along. Each book gets a card with its number in the sequence
   and its year, grouped by who was writing — the handover from Baum to Thompson
   in 1921 is the single most useful fact about the shape of this shelf, and the
   old list stated it nowhere. */

/* One book per row, full width. A grid of cards packed four across turned the
   shelf into a contact sheet — you read it by scanning a block, not by running
   your eye down a spine. In a single column the title, its credits and its
   length line up in three fixed places down the page, which is how a
   bibliography is read and how a shelf is looked along. */
.shelf {
  list-style: none;
  padding: 0;
  margin: 16px 0 0;
}
.shelf li { border-bottom: 1px solid var(--hair); }

/* No permanent left rule on a shelf row. It was left over from the design
   before these became cards, and against the card's own inset it rendered as a
   column of broken green dashes down the page rather than a continuous shelf
   edge. The hover edge every other card gets does the job, and does it only
   when it means something. */
.shelf .card { align-items: center; }
.shelf .title {
  display: block;
  font-size: 18.5px;
  line-height: 1.3;
  color: var(--emerald);
  transition: color 0.13s ease;
}
.shelf li.quiet .title { color: var(--dim); }
.shelf .credits {
  display: block;
  margin-top: 2px;
  font-family: var(--f-ui);
  font-size: 13px;
  color: var(--dim);
}
/* The length is pushed to the right edge and given a fixed column, so "6
   chapters" and "30 chapters" end at the same place and the numbers can be
   compared by running an eye down them. Without the min-width they were merely
   right-of-centre and each row ended somewhere different. */
.shelf .count {
  flex: none;
  min-width: 7.5em;
  text-align: right;
  font-family: var(--f-ui);
  font-size: 11px;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  white-space: nowrap;
  color: var(--straw);
}
.shelf li.quiet .count { color: var(--dim); }

.shelf-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 14px;
  margin: 44px 0 0;
}
.shelf-head h2 {
  font-family: var(--f-body);
  font-size: 23px;
  font-weight: 700;
  letter-spacing: -0.01em;
  text-transform: none;
  color: var(--ink);
  margin: 0;
  padding: 0;
  border: 0;
}
.shelf-head .span {
  font-family: var(--f-ui);
  font-size: 13px;
  color: var(--dim);
}

/* ------------------------------------------------------------- one book */

/* A book's chapters in one column, in order. Two or three columns made the
   reader jump back to the top of the page to continue at chapter 13, which is
   exactly wrong for a list whose whole meaning is its order. */
.chapters { list-style: none; padding: 0; margin: 18px 0 0; }
.chapters li { border-bottom: 1px solid var(--hair); }
.chapters .card { padding-block: 10px; gap: 14px; }
.chapters .n {
  flex: none;
  width: 2em;
  text-align: right;
  color: var(--straw);
  font-family: var(--f-ui);
  font-size: 12.5px;
  font-variant-numeric: tabular-nums;
}
/* The title, not "the last span" — the chevron is the last span now. */
.chapters .ct { flex: 1 1 auto; color: var(--ink); font-size: 16px; transition: color 0.13s ease; }

/* ------------------------------------------------------------ the plates */

.plates { margin-top: 44px; }

/* The line about the plates is a caption to the grid under it, so it shares the
   grid's edges. `.note` holds text to a reading measure, which is right for a
   note in a column of prose and wrong for one heading a full-width gallery. */
.plates .note { max-width: none; }

/* The plates are scans of whatever was on the page — a full-page colour plate,
   a decorated initial, a strip of caption two inches tall. Shown at their own
   proportions they made a grid with holes in it: rows an inch high next to rows
   a foot high, and a caption stranded beside a picture six times its size.
   Normalising them to one tile shape is what makes it a gallery rather than a
   pile. object-fit: contain keeps every plate whole — a scan cropped to fill
   would cut the head off a drawing — and the tile's ground shows the shape of
   what is in it. The lightbox is where the plate is seen properly. */
.plate-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
  gap: 18px;
  margin: 20px 0 0;
}
.plate { margin: 0; }
.plate a {
  display: block;
  border: 1px solid var(--rule);
  background: var(--surface);
  border-radius: 2px;
  overflow: hidden;
  transition: border-color 0.13s ease, transform 0.13s ease, box-shadow 0.13s ease;
}
.plate a:hover {
  border-color: var(--emerald);
  transform: translateY(-2px);
  box-shadow: 0 4px 14px rgba(20, 32, 27, 0.10);
}
.plate a:focus-visible { outline: 2px solid var(--emerald); outline-offset: 2px; }
/* height:auto is load-bearing, not tidiness. Every plate carries width/height
   attributes for layout stability, and the height attribute maps to the CSS
   height property — which outranks aspect-ratio. Without this the tiles took
   the scan's raw pixel height and the grid became five columns 4,322px tall. */
.plate img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 3 / 4;
  object-fit: contain;
  background: #F3EFE2;
  padding: 6px;
}
.plate figcaption {
  margin-top: 7px;
  font-family: var(--f-ui);
  font-size: 12px;
  color: var(--dim);
}

/* The lightbox, opened by :target. Hidden with display:none rather than
   opacity, which is what keeps the full-size scan from being downloaded until
   someone actually opens it. */
.lightbox {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 50;
  padding: 3vh 4vw;
  overflow: auto;
}
.lightbox:target { display: grid; align-content: center; justify-items: center; gap: 14px; }

/* The scrim is a link, so clicking anywhere outside the plate closes it. */
.lb-scrim {
  position: fixed;
  inset: 0;
  background: rgba(16, 22, 19, 0.86);
  cursor: zoom-out;
}

.lightbox figure {
  position: relative;
  margin: 0;
  max-width: min(64rem, 92vw);
}
.lightbox img {
  display: block;
  width: auto;
  max-width: 100%;
  max-height: 78vh;
  margin: 0 auto;
  background: var(--surface);
}
.lightbox figcaption {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 4px 20px;
  margin-top: 10px;
  font-family: var(--f-ui);
  font-size: 12.5px;
  color: #C3CCC6;
}
.lightbox figcaption a { color: #8FD3B6; }

.lb-nav {
  position: relative;
  display: flex;
  align-items: center;
  gap: 26px;
  font-family: var(--f-ui);
  font-size: 13.5px;
}
.lb-nav a { color: #C3CCC6; text-decoration: none; padding: 6px 4px; }
.lb-nav a:hover { color: #fff; text-decoration: underline; }
.lb-nav a:focus-visible { outline: 2px solid #8FD3B6; outline-offset: 2px; }
.lb-close { font-weight: 600; }

/* ------------------------------------------------------------- a chapter */

/* The reading page is the site's whole promise, so it is the one place that
   gets typographic treatment rather than layout: a wider leading, an opening
   line that announces itself the way a printed chapter does, and nothing in
   the margins to look at. */

.prose { margin-top: 26px; font-size: 18px; line-height: 1.72; }
.prose p { margin: 0 0 1.05em; max-width: var(--measure); }

.chapter h1 { font-size: clamp(27px, 3.6vw, 34px); margin-bottom: 4px; }

/* The rule under the chapter number, as the books set it. */
.chapter .kind { margin-bottom: 10px; }
.chapter .kind::after {
  content: "";
  display: block;
  width: 44px;
  height: 2px;
  margin-top: 8px;
  background: var(--straw);
  opacity: 0.55;
}

/* A drop cap on the first paragraph only. ::first-letter is safe here — if a
   chapter opens on a quotation mark the browser takes both characters, which is
   the correct typographic answer anyway. */
.prose > p:first-of-type::first-letter {
  float: left;
  font-size: 3.1em;
  line-height: 0.84;
  padding: 0.06em 0.1em 0 0;
  color: var(--emerald);
}
.prose > p:first-of-type::after { content: ""; display: table; clear: both; }

.appears { max-width: var(--measure); }
.appears h2 { margin-top: 40px; }

/* Previous and next chapter, named. "← Previous" tells a reader nothing they
   could not guess; the title of the chapter they are about to open tells them
   whether to open it. */
.pager {
  display: grid;
  gap: 12px;
  margin-top: 48px;
  padding-top: 20px;
  border-top: 1px solid var(--rule);
  font-family: var(--f-ui);
  font-size: 14.5px;
}
@media (min-width: 620px) { .pager { grid-template-columns: 1fr 1fr; } }
/* No box. Two filled, bordered panels at the foot of a chapter competed with
   the chapter — the last thing on a reading page should be quiet, and the
   titles alone are enough to say what they are. They behave like every other
   row on the site instead: nothing until you point at them. */
.pager a {
  display: block;
  padding: 12px 14px;
  border-radius: 3px;
  text-decoration: none;
  line-height: 1.35;
  color: var(--ink);
  transition: background-color 0.13s ease, color 0.13s ease;
}
.pager a:hover { background: var(--surface); color: var(--emerald); }
.pager a:hover .dir { color: var(--emerald); }
.pager a:focus-visible { outline: 2px solid var(--emerald); outline-offset: -2px; }
.pager .prev { margin-left: -14px; }
.pager .next { margin-right: -14px; }
.pager .dir {
  display: block;
  margin-bottom: 3px;
  font-size: 11px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--dim);
}
.pager .next { text-align: right; }
.pager .next:only-child { grid-column: 2; }

/* ---------------------------------------------------------------- the map */

.compass-switch { border: none; margin: 30px 0 0; padding: 0; }
.compass-switch legend {
  font-family: var(--f-ui);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: var(--dim);
  padding: 0;
}
.compass-switch input { position: absolute; opacity: 0; pointer-events: none; }
.compass-switch label {
  display: inline-block;
  margin: 10px 8px 0 0;
  padding: 7px 14px;
  border: 1px solid var(--rule);
  border-radius: 20px;
  font-family: var(--f-ui);
  font-size: 13px;
  color: var(--dim);
  cursor: pointer;
  background: var(--surface);
}
.compass-switch label:hover { border-color: var(--emerald); color: var(--emerald); }
#compass-baum:checked ~ label[for="compass-baum"],
#compass-thompson:checked ~ label[for="compass-thompson"] {
  background: var(--emerald);
  border-color: var(--emerald);
  color: var(--ground);
}
#compass-baum:focus-visible ~ label[for="compass-baum"],
#compass-thompson:focus-visible ~ label[for="compass-thompson"] {
  outline: 2px solid var(--emerald);
  outline-offset: 2px;
}

.mapwrap { margin-top: 22px; }
/* The map fills the page. It is the one illustration on the site and the reason
   the page exists, so it gets the width rather than sitting at 640px in the
   corner of a 992px frame.

   The viewBox is square, so full width means full height too — capped at 78vh
   so the whole of Oz is on screen at once, which is the point of a map. Below
   that cap the width is what governs.

   Type inside an SVG scales with the SVG, so the label sizes have to come down
   as the map goes up or the countries end up shouting: at 400 user units across
   a 912px box the old 12px became a rendered 27px. These values are set so the
   labels land near where they were at 640px. */
.ozmap {
  width: 100%;
  max-width: min(100%, 78vh);
  height: auto;
  display: block;
  margin: 0 auto;
}
.ozmap text { font-family: var(--f-body); font-size: 8.5px; }
.ozmap .rose { font-size: 7.5px; fill: var(--dim); letter-spacing: 0.08em; }
.ozmap a text { text-decoration: none; }
.ozmap a:hover .quadfill { filter: brightness(0.94); }
.ozmap a:hover text { text-decoration: underline; }
.ozmap a:focus-visible { outline: 2px solid var(--emerald); outline-offset: 2px; }

/* Munchkin and Winkie country each exist twice; which copy shows depends on
   whose account you asked for. */
.quad-munchkin.at-west, .quad-winkie.at-east { display: none; }
#compass-thompson:checked ~ .mapwrap .quad-munchkin.at-east,
#compass-thompson:checked ~ .mapwrap .quad-winkie.at-west { display: none; }
#compass-thompson:checked ~ .mapwrap .quad-munchkin.at-west,
#compass-thompson:checked ~ .mapwrap .quad-winkie.at-east { display: block; }

.mapnote { margin-top: 16px; }
.regionlist {
  list-style: none;
  padding: 0;
  margin: 18px 0 0;
}
.regionlist li {
  padding: 14px 0;
  border-bottom: 1px solid var(--hair);
}
.regionlist b { display: block; font-size: 16.5px; margin-bottom: 4px; }
.regionlist b a { text-decoration: none; }
.regionlist b a:hover { text-decoration: underline; }

/* ------------------------------------------------------- written pages */

/* The method page's tally and table: counts of what the site contains, so they
   take the full measure rather than the prose one. */
.page .tally { list-style: none; padding: 0; margin: 16px 0 0; max-width: none; }
.tally li {
  padding: 11px 0;
  border-bottom: 1px solid var(--hair);
  font-size: 16px;
}
.tally b { font-family: var(--f-ui); font-size: 17px; color: var(--straw); }

.table-scroll { overflow-x: auto; margin: 18px 0; border: 1px solid var(--rule); }
.method table { border-collapse: collapse; width: 100%; font-size: 14.5px; min-width: 34rem; }
.method th, .method td {
  text-align: left;
  padding: 11px 16px;
  border-bottom: 1px solid var(--hair);
  vertical-align: top;
}
.method thead th {
  font-family: var(--f-ui);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--dim);
  background: var(--surface);
}
.method tbody th { font-weight: 600; white-space: nowrap; }
.method td.num, .method th.num {
  font-family: var(--f-ui);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.method tbody tr:last-child th, .method tbody tr:last-child td { border-bottom: 0; }

.page h2 {
  font-family: var(--f-body);
  font-size: 20px;
  font-weight: 700;
  letter-spacing: -0.005em;
  text-transform: none;
  color: var(--ink);
  margin: 38px 0 10px;
  padding: 0;
  border: 0;
}
/* No reading measure on .page paragraphs. There was one — 34em on every p, ul
   and ol — and it spent its life being switched off: the map caption, the
   index intros, the shelf, the alphabet, the region grid, the colour note that
   broke onto a second line at two-thirds of its row. A rule that every page
   has to opt out of is the wrong default. The written pages that wanted a
   short line get it from the shell: body's --w is the measure plus its
   gutters, so /about and /method are still a reading column without any
   paragraph inside them having to say so. Chapter prose keeps its own cap on
   .prose p. */
.page li { margin-bottom: 5px; }
.page em { color: var(--dim); }

.page .shelf li, .page .entities li, .page .regionlist li,
.page .matlist > li { margin-bottom: 0; }

/* ----------------------------------------------------------------- footer */

/* A footer that ends the site rather than trailing off it. What was here was a
   sentence about the public domain and four small links, which left every page
   stopping mid-air. This gives the reader the way back in — every section, and
   the pages about the site — with the rights note kept but demoted to where a
   colophon belongs. */

/* The footer is the same sheet of paper, not a tinted tray at the bottom of
   it. A surface panel here would be the one filled box on the whole site and
   would contradict everything above it — so the only thing separating it is a
   hairline and a lot of space. */
footer {
  background: var(--ground);
  padding-block: clamp(44px, 6vw, 68px) 56px;
  color: var(--dim);
  font-family: var(--f-ui);
  font-size: 13.5px;
}

/* A rule above the footer, and none above the copyright. The one inside was
   drawing a box the space had already drawn; this one is doing the same job as
   the dividers between the homepage bands — ending the page — so it ends where
   the column ends rather than running off into the window, and matches their
   width exactly. It sits on the footer element rather than its shell, for the
   reason noted on .home .band::before. */
footer::before {
  content: "";
  display: block;
  height: 1px;
  background: var(--hair);
  width: min(var(--frame) - 2 * var(--gutter), 100% - 2 * var(--gutter));
  margin: 0 auto clamp(38px, 5vw, 58px);
}
/* What the site is, with its seal. */
.foot-top { display: grid; gap: 26px 48px; grid-template-columns: 1fr; }
@media (min-width: 700px) {
  .foot-top { grid-template-columns: minmax(0, 1fr) auto; align-items: start; }
  .foot-about p { max-width: 34em; }
}
/* The full width of the footer, under everything it is a way out of. Wrapping
   rather than a fixed five, so a narrow footer folds them onto a second line
   instead of squeezing. */
.foot-doors { margin-top: clamp(30px, 4vw, 46px); }
.foot-doors ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 12px 26px;
}
.foot-doors a {
  display: flex;
  align-items: center;
  gap: 11px;
  font-size: 15px;
  color: var(--ink);
  text-decoration: none;
}
.foot-doors a:hover { color: var(--emerald); }
.foot-doors a:hover span { text-decoration: underline; }
.foot-ico { width: 19px; height: 19px; flex: none; color: var(--straw); opacity: 0.92; }
.foot-doors a:hover .foot-ico { color: var(--emerald); opacity: 1; }

/* Pressed into the corner of the page rather than set on its baseline. */
/* Bottom right of the block it signs, not top right beside the wordmark. Level
   with the wordmark it read as a second logo on the same line, and it left the
   whole right half beneath it empty; down here it closes the corner and answers
   the road strip across the diagonal. A seal signs off — at the top of a footer
   it is a logo, at the foot of one it is a stamp on a finished page. */
.foot-seal {
  width: clamp(46px, 5vw, 62px);
  height: auto;
  align-self: end;
  justify-self: end;
  opacity: 0.92;
  pointer-events: none;
}
.tpl-home .foot-seal { display: none; }
@media (max-width: 759px) {
  .foot-seal { justify-self: start; width: 44px; }
}


.foot-about .wordmark { font-size: 17px; margin-bottom: 12px; }
.foot-about .wordmark .mark { width: 22px; height: 22px; }
.foot-about p {
  margin: 0;
  max-width: 34em;
  font-size: 13.5px;
  line-height: 1.6;
}

/* Footer headings are eyebrows: same coloured rule as the rest of the site,
   so the bottom of the page uses the same vocabulary as the top. */
.foot-doors h2 {
  display: flex;
  align-items: center;
  gap: 9px;
  margin: 0 0 12px;
  padding: 0;
  border: 0;
  font-family: var(--f-ui);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--dim);
  line-height: 1.3;
}
.foot-doors h2::before {
  content: "";
  width: 20px;
  height: 3px;
  border-radius: 2px;
  background: var(--accent, var(--emerald-plate));
  flex: none;
}


/* Copyright left, small print right, on one line. */
.foot-base {
  margin-top: 46px;
  padding-top: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px 28px;
}
.foot-base p { margin: 0; max-width: 52em; font-size: 12.5px; line-height: 1.6; }
.foot-meta { display: flex; flex-wrap: wrap; gap: 6px 20px; font-size: 12.5px; }
.foot-meta a { color: var(--dim); text-decoration: none; white-space: nowrap; }
.foot-meta a:hover { color: var(--emerald); text-decoration: underline; }
.foot-note { opacity: 0.8; }

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

/* What a thing is, said in a block rather than buried in prose. Only the keys
   the books actually supply get a row — and the rows are the Connections rows,
   so the definition-list styling that used to live here styles nothing now. */
.factstrip dd { margin: 0; font-size: 16px; }
.factstrip .src { font-size: 12.5px; color: var(--dim); }


/* --------------------------------------------------------------- the atlas */

/* A map of Oz and the countries near to it, after the two 1914 endpapers.
   The compass sits above the map rather than on it, because here it is a
   control: Baum and Thompson disagree about which way round east and west are,
   and the switch relabels the rose rather than moving the land. */

.atlas { margin: 30px 0 0; }

.atlas-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 14px 22px;
  padding: 0 0 10px;
}

/* The rose lives on the map, in its corner, the way a map keeps its compass —
   not in a row of controls above it. Overlaid on the view rather than drawn into
   the SVG, so panning the land does not carry the compass off the frame. */
/* At the left of the toolbar, level with the controls. It spent a while in the
   corner of the drawing, which is where a map keeps its compass — but the
   drawing is 800px tall and a rose in its bottom corner was below the fold at
   the moment you pressed the button that turns it, which made the flip look
   broken. Up here the rose and the button are always on screen together. */
.map-rose {
  position: relative;
  width: 74px;
  height: 74px;
  flex: none;
  pointer-events: none;
}
/* And it turns over when it flips. Two letters trading places is the whole of
   the argument but it is not enough of a movement to catch an eye that was
   looking at the button. */
.map-rose .rose {
  position: absolute; inset: 8px; width: 58px; height: 58px; opacity: 0.82;
  transition: transform 0.5s cubic-bezier(0.2, 0.7, 0.3, 1);
}
[data-compass="thompson"] .map-rose .rose { transform: rotateY(180deg); }
@media (prefers-reduced-motion: reduce) {
  .map-rose .rose { transition: none; }
}
.map-rose .r {
  position: absolute;
  font-family: var(--f-ui);
  font-size: 11px;
  font-weight: 700;
  color: var(--ink);
  opacity: 0.62;
  letter-spacing: 0.06em;
  transition: color 0.3s ease, opacity 0.3s ease;
}
.map-rose .r-n { top: -1px; left: 50%; transform: translateX(-50%); }
.map-rose .r-s { bottom: -1px; left: 50%; transform: translateX(-50%); }
.map-rose .r-e { right: -1px; top: 50%; transform: translateY(-50%); }
.map-rose .r-w { left: -1px; top: 50%; transform: translateY(-50%); }
/* The two letters the argument is actually about. Turned, they are the only
   thing on the screen that changes, so they say so. */
[data-compass="thompson"] .map-rose .r-e,
[data-compass="thompson"] .map-rose .r-w { color: var(--poppy); opacity: 1; }

.atlas-bar button:focus-visible { outline: 2px solid var(--emerald); outline-offset: 2px; }

.zoom-tool { display: flex; gap: 2px; }
/* The same bare icon button the masthead uses for search and menu. The map is
   drawn straight onto the paper now, so a row of bordered chips above it was
   the last piece of ordinary chrome left on the page. Not .icon-btn itself:
   that one is display:none until the masthead script claims it, and these have
   no business disappearing on a page whose script has already run. */
.atlas-bar .map-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  padding: 0;
  border: 0;
  border-radius: 3px;
  background: none;
  color: var(--ink);
  cursor: pointer;
}
.atlas-bar .map-btn:hover { background: var(--sunk); border-color: transparent; color: var(--ink); }
.atlas-bar .map-btn[aria-pressed="true"] { background: var(--sunk); color: var(--poppy); }
.atlas-bar .map-btn svg { width: 18px; height: 18px; display: block; }

/* The window onto the map. Overflow hidden is what makes panning mean
   anything; without it the page itself would scroll instead. */
/* A window, not a band. Capping the height alone letterboxed it — the drawing
   fitted itself to the height and left the width empty on both sides. An aspect
   ratio matching the map's own is what makes it fill its box. */
/* No width of its own. A hard 1180px here was wider than --frame, so the map
   hung past the masthead and the footer and broke the one edge every other page
   keeps — and the article was missing the `shell` class that gives every other
   template its width, so it had no edge to keep. Both fixed; this only fills. */
.atlas { width: 100%; }
.atlas-view {
  position: relative;
  overflow: hidden;
  /* The map's own 10:7, so the drawing fills the column edge to edge instead of
     sitting letterboxed in the middle of it. This was a fixed height once,
     because at the page's full width the aspect ratio ran the box past a
     thousand pixels tall — but the shell is capped at --frame now, which caps
     this at about 800px, near enough what the fixed height was giving anyway.
     The floor is for phones, where 10:7 of a narrow column is too short a
     window to read a map through; a box taller than its ratio letterboxes top
     and bottom, which costs nothing, rather than at the sides, which was the
     thing worth fixing. */
  aspect-ratio: 2000 / 1400;
  /* Both of these, and in this order. aspect-ratio on an auto-width block does
     not only set the height: when min-height asks for more than the ratio
     allows, the browser widens the box to keep the ratio rather than
     letterboxing it. On a 400px phone that made this element 571px wide — 400
     times 1.4286 — and pushed the whole homepage sideways. Pinning the width
     leaves the ratio only the height to work with, which is what the floor was
     always meant to do. */
  width: 100%;
  max-width: 100%;
  min-height: min(58vh, 400px);
  /* No frame and no ground. The map is drawn onto the page rather than shown
     inside a panel sitting on it, which is also what finally makes the sea
     right: the water is paper nobody has painted. */
  background: transparent;
  cursor: grab;
  touch-action: none;
}
.atlas-view.dragging { cursor: grabbing; }
.atlas-view:focus-visible { outline: 2px solid var(--emerald); outline-offset: 2px; }
/* Zoom moves the viewBox, so the element itself never scales and nothing here
   should encourage the browser to rasterise it. */
.atlas-view .ozmap {
  display: block;
  width: 100%;
  height: 100%;
  /* The base .ozmap rule caps the drawing at 78vh, from when the map was a
     plain inline SVG that sized itself by height. Inside the atlas the box is
     the thing with a size and the SVG fills it, so that cap only ever held the
     map narrower than the space it had been given — 1023px inside a 1634px
     view, which is why it kept looking letterboxed however wide the container
     got. */
  max-width: none;
  background: transparent;
}

/* ---------------------------------------------------------------- the paper */

/* Every label on the sheet is the UI face. A map is an instrument, and one
   family told apart by case, weight and tracking reads as a legend; three
   families reads as three different maps. */
.ozmap text {
  font-family: var(--f-ui);
  fill: var(--ink);
  paint-order: stroke;
  stroke: var(--ground);
  stroke-width: 2.6px;
  stroke-linejoin: round;
}

/* ------------------------------------------------------------ sea and shore */

/* There is no sea to paint, and no ground rect to paint it on. The water is the
   page, left bare, and what marks the coast is the ink that stops there: the
   shore stroke, the bleed behind it, and the washes that only ever fall on the
   land side of it. */
.ozmap .sea-label {
  font-size: 20px; letter-spacing: 0.34em; text-anchor: middle;
  fill: var(--ink); fill-opacity: 0.4; text-transform: uppercase;
  font-weight: 500; stroke: none;
}
/* Ink bleeding outward into damp paper, which is the one thing a vector edge
   cannot do on its own. */
.ozmap .coast-bleed { fill: var(--ink); fill-opacity: 0.3; stroke: none; }
/* The land is the site's own paper, not a scan of somebody's parchment. The
   scan is still laid over it, but at a tenth strength and only as tooth — at
   full it was an old-treasure-map cliche loud enough to bury the washes. */
.ozmap .landmass { fill: var(--ground); stroke: none; }
.ozmap .grain { stroke: none; opacity: 0.12; pointer-events: none; }
/* No crisp outline round the continent. A uniform 2.4px line is the one mark a
   brush cannot make, and having drawn everything else wet it was the single
   thing on the sheet still announcing itself as vector. What reads as the coast
   now is the bleed above — ink soaking outward into damp paper — and the fact
   that every wash on the map stops at the shore. A hairline stays under it at a
   fifth of the weight, because with the sea and the land both bare paper the
   soft edge alone loses the shore wherever no country's wash reaches it. */
/* Lighter and less definite than the borders inside it. The shore of the whole
   landmass is the least certain line on the sheet — it is where the ink stops,
   not a border anyone drew — so it should be the faintest, and it was reading
   as the firmest thing on the map. */
.ozmap .coast { fill: none; stroke: var(--ink); stroke-opacity: 0.07; stroke-width: 0.9; }
/* Deeper than the mainland washes, not paler. The mask multiplies whatever is
   under it, so at 0.14 the blot's whole range landed between alpha 0.04 and
   0.14 — a variation too small to see on a shape forty pixels wide, which is
   why these two kept reading as flat chips however they were masked. */
.ozmap .isle-land {
  fill: var(--ink); fill-opacity: 0.24;
  stroke: var(--ink); stroke-opacity: 0.26; stroke-width: 1.3;
}

/* ------------------------------------------------------- the outer countries */

/* Outside the desert the world is painted in ink and nothing else — the rule
   the plates are made under, and on a map also plain information design: the
   four countries and the green city are the subject, and they are the only
   things allowed a hue. The outer lands are told apart by the weight of their
   wash and by the border between them, the way an engraved map does it.
   Base fill-opacity is a presentation attribute set per country in map.js, so
   it must not be declared here or every one of them would come out the same. */
.ozmap .outer-land {
  fill: var(--ink);
  stroke: var(--ink); stroke-opacity: 0.26; stroke-width: 1.3;
  transition: fill 0.15s ease, fill-opacity 0.15s ease;
}
/* Hovering tints rather than darkens — the same green that means "this is a
   link" everywhere else on the site. */
/* Earth, not emerald. Hovering a country outside the desert used to turn it the
   green that on this map means the Emerald City and nothing else — so half the
   world could be made to look like Oz by running a pointer across it. Umber
   instead: still one clear step out of the ink, still nothing like the sand
   under the pointer next door. */
.ozmap .outer:hover .outer-land { fill: var(--earth); fill-opacity: 0.26; }
.ozmap .isle:hover .isle-land { fill: var(--earth); fill-opacity: 0.3; }
.ozmap .outer-label {
  font-size: 18px; text-anchor: middle; letter-spacing: 0.13em;
  text-transform: uppercase; font-weight: 500; fill: var(--ink); fill-opacity: 0.78;
}
.ozmap .isle-label { font-size: 15px; letter-spacing: 0.1em; }
.ozmap .march-label {
  font-size: 13px; text-anchor: middle; letter-spacing: 0.08em;
  fill: var(--dim); font-weight: 300;
}

/* The sand is the boundary of the coloured world, so it is barely a colour
   itself — warm paper rather than a hue. */
/* Ink at rest like the countries, sand-coloured under the pointer. Hovering the
   band is what colours it — the path runs under the whole of Oz, but a country
   drawn on top of it is the element actually hit there, so only the visible ring
   of sand answers. */
.ozmap .sands {
  fill: var(--ink); fill-opacity: 0.08;
  stroke: var(--ink); stroke-opacity: 0.16; stroke-width: 1.2;
  transition: fill 0.2s ease, fill-opacity 0.2s ease;
}
.ozmap .desert-ring:hover .sands { fill: var(--straw-plate); fill-opacity: 0.36; }
.ozmap .desert-label {
  font-size: 20px; letter-spacing: 0.3em; text-anchor: middle;
  fill: var(--ink); fill-opacity: 0.5; text-transform: uppercase; font-weight: 500;
  stroke: none; transition: fill 0.2s ease, fill-opacity 0.2s ease;
}
.ozmap .desert-ring:hover .desert-label { fill: var(--straw); fill-opacity: 1; }

/* -------------------------------------------------------------------- Oz */

/* The map opens in ink. Every country is a grey wash at rest and only takes its
   own hue when you touch it — --wash is set per country in map.js from the
   palette tokens, and goes down through a painted blot mask either way, so the
   colour pools and thins the way ink does instead of sitting flat.
   The Emerald City is the exception and keeps its green always: it is the thing
   the whole map is arranged around, and leaving one note of colour in the middle
   of a grey sheet says that better than four competing ones. */
.ozmap .land {
  fill: var(--ink); fill-opacity: 0.16; stroke: none;
  transition: fill 0.2s ease, fill-opacity 0.2s ease;
}
.ozmap .region:hover .land { fill: var(--wash); fill-opacity: 0.88; }
.ozmap .region.city .land { fill: var(--wash); fill-opacity: 0.85; }
.ozmap .region.city:hover .land { fill-opacity: 1; }
/* The border and the whole hit area. Transparent rather than unfilled, because
   a path with fill:none is only clickable on its stroke — and the mask above
   makes its own thin patches untargetable, which is why this is a second copy
   rather than the same element. */
.ozmap .land-edge {
  fill: transparent;
  stroke: var(--ink); stroke-opacity: 0.3; stroke-width: 1.2;
  transition: stroke-opacity 0.15s ease;
}
.ozmap .region:hover .land-edge { stroke-opacity: 0.72; }
/* Oz's own shore, drawn over the four countries the way the continent's coast
   is drawn over the sixteen. Heavier than the mainland coast: this is the one
   border in the world that cannot be walked across. */
.ozmap .oz-shore {
  fill: none; stroke: var(--ink); stroke-opacity: 0.24; stroke-width: 1.2;
  pointer-events: none;
}
.ozmap .country-label {
  font-size: 20px; letter-spacing: 0.16em; text-anchor: middle;
  text-transform: uppercase; font-weight: 600;
  fill: var(--ink); fill-opacity: 0.76; pointer-events: none;
}
.ozmap .region:hover .country-label { fill-opacity: 1; }

/* The rivers and the road were the last coloured things inside Oz, and they are
   ink now like everything else the pointer is not on. The road loses the most by
   this — it is the Road of Yellow Brick and the yellow was carrying its name —
   but a single straw line running across a grey country reads as the one thing
   that failed to lose its colour rather than as a deliberate exception. */
.ozmap .river { fill: none; stroke: var(--ink); stroke-width: 1.6; opacity: 0.42; }
/* The one road on the map, drawn as a road. It was dashed, and a dashed line
   across a map is the universal sign for a route somebody took — so the Road of
   Yellow Brick was reading as Dorothy's journey rather than as a thing that is
   there whether or not anyone is walking on it. Solid, soft and unbroken now.
   Still ink, like everything else outside the green city; it is the one mark on
   the sheet with a colour in its own name, so if any second exception to that
   rule is ever worth making, it is this one. */
.ozmap .road {
  fill: none; stroke: var(--ink); stroke-width: 2.2;
  stroke-linecap: round; opacity: 0.32;
}
.ozmap .range { fill: none; stroke: var(--ink); stroke-width: 1.6; opacity: 0.5; }
.ozmap .lake { fill: var(--ink); fill-opacity: 0.22; stroke: none; }
/* The painted pond, in place of the flat blue ellipse that sat on top of the
   picture instead of in it. */
.ozmap .lake-art { pointer-events: none; opacity: 0.8; }
.ozmap .feature-label {
  font-size: 12px; text-anchor: middle; fill: var(--ink); fill-opacity: 0.62; font-weight: 500;
}

/* The Emerald City is a country on this map, not a dot on it — the endpaper
   gives it a territory of its own that all four of the others border — so its
   name is set exactly like theirs, and .ec-label no longer overrides anything.
   It was 15px against their 20px, which made the one place the whole map is
   arranged around read as a footnote to it. */

/* Painted hills where the sources put a range. */
.ozmap .range-art { pointer-events: none; opacity: 0.82; }

/* Names arrive as you go in.
   The opening zoom names Oz and nothing else: the four countries and the green
   city at their centre. That is the whole subject of the map, and the deserts,
   the sands and the ocean — which are what Oz is NOT — were competing with it
   in the same breath. One step in draws the boundary and the world past it: the
   four deserts, the ocean, the sixteen outer countries, the two isles, the Nome
   King's marches. Two steps in names the forty places inside Oz, which at the
   opening zoom were forty pieces of six-point type laid over each other.
   Written as three states that HIDE rather than one that reveals, so that with
   no script — and therefore no data-zoom — every name is simply present, which
   is the right fallback for a map whose labels are half its content. */
.ozmap .outer-label, .ozmap .march-label, .ozmap .desert-label,
.ozmap .sea-label, .ozmap .place-label, .ozmap .feature-label {
  transition: opacity 0.28s ease;
}
.atlas-view[data-zoom="0"] .ozmap .outer-label,
.atlas-view[data-zoom="0"] .ozmap .march-label,
.atlas-view[data-zoom="0"] .ozmap .desert-label,
.atlas-view[data-zoom="0"] .ozmap .sea-label,
.atlas-view[data-zoom="0"] .ozmap .place-label,
.atlas-view[data-zoom="0"] .ozmap .feature-label,
.atlas-view[data-zoom="1"] .ozmap .place-label,
.atlas-view[data-zoom="1"] .ozmap .feature-label {
  opacity: 0;
  /* A name you cannot see must not be the thing your pointer lands on. The
     region and the vignette under it stay clickable either way. */
  pointer-events: none;
}

.ozmap .vig { pointer-events: none; }
.ozmap .place-label { font-size: 12.5px; font-weight: 500; }
.ozmap .spot, .ozmap .outer, .ozmap .isle, .ozmap .region,
.ozmap .march, .ozmap .desert, .ozmap .feature, .ozmap .route { cursor: pointer; }
.ozmap .flat { cursor: default; }
/* The marches and the deserts are names outside Oz, so they answer in earth and
   straw like the outer countries, never in the green. The desert label was
   already lit by hovering the ring of sand; now the name itself lights too, and
   the keyboard gets the same. */
.ozmap .march:hover .march-label { fill: var(--earth); font-weight: 500; }
.ozmap .desert:hover .desert-label { fill: var(--straw); fill-opacity: 1; }
.ozmap .feature:hover .feature-label { fill: var(--emerald); fill-opacity: 1; font-weight: 700; }
/* The invisible wide stroke that makes a river or the road something a pointer
   can actually land on. Stroke-only, so the loop of a bend is not a hit. */
.ozmap .route .hit { fill: none; stroke: transparent; stroke-width: 14; pointer-events: stroke; }
.ozmap .route:hover .river, .ozmap .route:hover .road { opacity: 0.85; stroke: var(--emerald); }
.ozmap .spot .vig { transition: transform 0.12s ease; transform-origin: center bottom; transform-box: fill-box; }
.ozmap .spot:hover .vig { transform: scale(1.25); }
.ozmap .spot:hover .place-label { fill: var(--emerald); font-weight: 700; }
.ozmap a:focus-visible { outline: none; }
.ozmap a:focus-visible .place-label,
.ozmap a:focus-visible .country-label { fill: var(--emerald); text-decoration: underline; }
/* Keyboard equivalent of the hover above, and it follows the same rule: a name
   outside Oz does not go green either. */
.ozmap a:focus-visible .outer-label,
.ozmap a:focus-visible .march-label { fill: var(--earth); text-decoration: underline; }
.ozmap a:focus-visible .desert-label { fill: var(--straw); fill-opacity: 1; text-decoration: underline; }
.ozmap a:focus-visible .feature-label { fill: var(--emerald); text-decoration: underline; }
.ozmap a:focus-visible .river, .ozmap a:focus-visible .road { opacity: 0.85; stroke: var(--emerald); }

@media (prefers-reduced-motion: reduce) {
  .ozmap .land, .ozmap .land-edge, .ozmap .outer-land, .ozmap .spot .vig,
  .atlas-view .ozmap { transition: none; }
}

.ozmap .m-dot { fill: var(--ink); fill-opacity: 0.8; }
.rose-blank { position:absolute; inset:8px; border:1px dashed var(--rule); border-radius:50%; }

/* Full-column prose, and a painting to close a page.
   `wide` drops the reading measure so the text fills the column. It is a choice
   made per page in frontmatter rather than a default, because 34em exists for a
   reason and most pages should keep it. */
.page-wide > p, .page-wide > ul, .page-wide > ol,
.page-wide > h2, .page-wide > h3, .page-wide > blockquote { max-width: none; }

/* auto, not 0, on the sides. The shorthand was setting the side margins to
   zero, which overrode the `margin: 0 auto` that .shell centres itself with —
   so on the homepage, where this figure is a shell in its own right, it pinned
   itself to the left edge of the page instead of lining up with the column. */
/* The source line under a quoted heading. Small, quiet, and directly beneath
   the words it accounts for — the same shape the entity pages use to hang a
   chapter off a claim. */
.epigraph-cite {
  font-family: var(--f-ui);
  font-size: 13px;
  color: var(--dim);
  margin: -6px 0 18px;
  max-width: var(--measure);
}
.epigraph-cite cite { font-style: italic; }
.epigraph-cite a { color: var(--dim); text-decoration: none; border-bottom: 1px solid var(--rule); }
.epigraph-cite a:hover { color: var(--emerald); border-bottom-color: var(--emerald); }

.tailplate { margin: clamp(44px, 6vw, 80px) auto 0; }
/* The top of both plates is empty paper, and its edge showed as a faint
   rectangle against the page's own. Fading it out means the sky simply becomes
   the page — the painting arrives rather than being pasted on. Only the top:
   the sides and foot carry the drawing. */
.tailplate img {
  display: block;
  width: 100%;
  height: auto;
  -webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 16%);
  mask-image: linear-gradient(to bottom, transparent 0, #000 16%);
}

/* The road, small, under the footer's own paragraph. Kept narrow — it is a
   closing note here, not the picture it is on /about. */
.foot-plate {
  display: block;
  width: 100%;
  max-width: 430px;
  height: auto;
  margin-top: 22px;
  opacity: 0.95;
  -webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 14%);
  mask-image: linear-gradient(to bottom, transparent 0, #000 14%);
}

/* Drawn on the page, not framed on it: no border, no ground, no shadow, and a
   transparent plate so the paper shows through the washes. */
/* Capped in BOTH directions, and the height cap is the one that matters. Sized
   by width alone a tall figure came out 515px deep and pushed the contents nav
   halfway down the page, while a wide flat object like the belt was a 60px
   sliver — the rail looked like a different component on every entry. Bounding
   the height too keeps every plate to the same modest band at the head of the
   rail, whatever the shape of the thing it shows. */
/* The world line reads as a statement, not a citation — it is the one derived
   claim that sits this high on a place page, so it is set plainly rather than
   dressed as a quotation. */
/* Prose, not a blockquote. The reasoning often contains a quotation but is not
   itself one, and setting it like the pull-quotes would claim an authority it
   does not have. */
.worldwhy { margin: 8px 0 0; color: var(--ink); }

/* Every sentence behind a claim, each under its own chapter. */
/* The evidence behind a claim, as a table: the passage on the left, the chapter
   it comes from on the right. The same treatment /laws gets, and it feeds three
   sections here at once — what the books say it is, connections, and
   connections from others.

   It stacked before: quote, then its citation on a line of its own underneath,
   then the next quote. That reads fine for one, and Dorothy has claims carrying
   a dozen, where it becomes a column of alternating voices with no edge to run
   an eye down. Right-aligned in a column of its own, the citations answer "which
   chapters is this from" without reading a word of the quotations.

   Narrower citation column than the reference pages use: this content sits
   inside the entity page's text column, not the full frame, and 15rem there
   would leave the passage almost nothing. It wraps if it must — the guarantee
   belongs where there is room to keep it. */
.evlist { list-style: none; margin: 10px 0 0; padding: 0; }
.evlist > li {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(6.5rem, auto);
  align-items: baseline;
  gap: 4px 18px;
  padding: 11px 0;
  border-top: 1px solid var(--hair);
}
.evlist > li:first-child { border-top: 0; padding-top: 2px; }
.evlist blockquote { margin: 0; }
.evlist cite {
  font-style: normal;
  text-align: right;
  color: var(--dim);
  font-size: 0.76rem;
  line-height: 1.45;
}
/* Below the point where two columns fit, the citation returns beneath its
   quotation rather than being squeezed into a stripe. */
@media (max-width: 46rem) {
  .evlist > li { grid-template-columns: 1fr; gap: 3px; }
  .evlist cite { text-align: left; }
}

/* The quotations now sit under the attribute rows in one section, so the first
   one needs air between it and the last row rather than butting against it. */
.relations + .described-quote { margin-top: 22px; }

/* The width is written per plate by the template, computed so every plate
   covers about the same area — see the note on portrait() in entity.js. These
   are the safety rails, not the sizing.

   Two things the area calculation cannot do on its own. A plate narrower than
   the rail is centred in it rather than left-aligned, because a narrow figure
   pushed against the left edge reads as misaligned with the nav beneath it
   rather than as a deliberately small drawing. And min-height gives the very
   flat subjects a floor: the Magic Belt is 3.5:1 and clamps to the rail width
   at 60px tall, which is a stripe rather than a plate. object-fit keeps that
   floor honest — the extra height is empty paper above and below the belt, not
   a stretched belt. */
.entity-portrait {
  display: block;
  max-width: 18rem;
  height: auto;
  min-height: 9rem;
  object-fit: contain;
  margin: 0 auto 22px;
}
@media (max-width: 999px) {
  /* There is no rail below 1000px — the contents becomes a plain row of links
     across the page. display:contents dissolves the wrapper so both children
     behave exactly as they did before it existed, and the portrait simply sits
     in the flow beside the text.
     Note this leaves the rail with no box of its own at these widths, which is
     the point: nothing here should be styled on .entity-rail itself. */
  .entity-rail { display: contents; }
  /* Centred rather than floated. Floating it right put the picture in the
     margin of the opening paragraphs, which packs the screen and reads as a
     thumbnail beside the text; on a phone the plate is the only image on the
     page and it can have the width. Bigger, too, now that nothing has to flow
     past it — 240px against the 190 it had squeezed into. */
  .entity-portrait {
    float: none;
    display: block;
    max-width: min(64%, 240px);
    min-height: 0;
    margin: 0 auto 22px;
  }
  /* And the contents is a single column of links. Across the page it wrapped
     into two ragged columns of different lengths, which is a list you have to
     read twice to find anything in. */
  .entity-rail .contents { clear: both; }
  .entity-rail .contents ul { flex-direction: column; gap: 8px; }
}


/* The world a place belongs to, said on its own row.
   The places index used to be four stacked indexes with four alphabets, which
   answered "what is in Oz" and failed "where is Foxville" — you had to know
   the world before you could look the place up. One alphabet, and the world
   moves onto the row, which is also more precise: the claim is about Australia,
   not about a region of the page.
   Oz keeps the site's own green. Beyond the desert takes the umber already
   defined for exactly that. Our world takes Dorothy's blue. Unplaced stays
   grey, because it is an absence rather than a fourth country. */
.wtag {
  flex: 0 0 auto;
  align-self: center;
  font: 500 0.66rem/1 "IBM Plex Sans", system-ui, sans-serif;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  white-space: nowrap;
  padding: 4px 7px;
  border-radius: 2px;
  background: var(--sunk);
  color: var(--dim);
}
/* One colour for all of them. Three hues made the index look like a chart, and
   the tag already says which world it is in words — the colour was decoration
   doing a job the word had done. */

.worldcount {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 14px;
  margin: 0 0 18px;
  color: var(--dim);
  font-size: 0.86rem;
}
.worldcount .wtag { margin-right: 2px; }

@media (max-width: 640px) {
  .card { flex-wrap: wrap; }
  .wtag { order: 3; }
}


/* The world filter. The counts row named the four worlds and did nothing with
   them; since the index became one A–Z those numbers are the only place the set
   is stated, which makes them the natural control. Built by script over the
   plain counts, so a reader without script keeps a true sentence rather than a
   dead button. */
.filterbar { position: relative; display: inline-block; margin: 0; }
/* The masthead's control, reused. .icon-btn is hidden until script adds
   .has-tools to the root, which is exactly right here too: the button only
   exists because script built it. */
.filterbar .icon-btn { display: inline-flex; }
.filterbtn { color: var(--dim); }
/* .icon-btn already sizes the svg at 19px, the masthead's size — do not
   override it, that was the thing making this look like a different set. */
.filterbtn:hover { color: var(--emerald); }
/* One signal, for a reader who has scrolled past the top: the index is not
   showing everything. */
.filterbtn.on { color: var(--emerald); }
.filterbtn.on::after {
  content: "";
  position: absolute;
  top: 7px;
  right: 7px;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--emerald);
}
.filterbtn { position: relative; }
.countline-filtered {
  display: flex;
  align-items: center;
  gap: 4px;
}
.countline-filtered .filterbar { margin-left: -9px; }

.fhead {
  margin: 2px 7px 8px;
  color: var(--dim);
  font: 500 0.76rem/1 var(--f-ui);
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.filterpanel {
  position: absolute;
  z-index: 20;
  top: calc(100% + 6px);
  left: 0;
  min-width: 15rem;
  padding: 8px;
  border: 1px solid var(--rule);
  border-radius: 3px;
  background: var(--surface);
  box-shadow: 0 6px 20px rgba(43, 39, 33, 0.12);
}
.filterpanel label {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 6px 7px;
  border-radius: 2px;
  cursor: pointer;
  font-size: 0.86rem;
}
.filterpanel label:hover { background: var(--sunk); }
.filterpanel input { margin: 0; accent-color: var(--emerald); }
.filterpanel .fn { margin-left: auto; color: var(--dim); font-variant-numeric: tabular-nums; }

/* A letter the filter has emptied still belongs in the rail — the gap is
   information — but it must stop being a link to nothing. */
.az .az-empty { color: var(--hair); pointer-events: none; }

/* Book headings inside a Names row. Appears in puts the book in a <summary>,
   which styles itself; here the list is already inside one toggle, so the book
   is a plain line above its chapters rather than a second thing to open. */
/* One row per book: the title in a column of its own, its chapter numbers
   flowing beside it. The two-column layout went with the chapter titles — it
   existed to stop long title lists running off the bottom of the screen, and
   with numbers there is nothing long left to break. Single column also means
   the books stay in publication order down the page instead of jumping from the
   foot of one column back to the head of the next. */
.namebooks { columns: auto; column-gap: normal; }
.nbrow {
  display: grid;
  grid-template-columns: var(--cite-col) minmax(0, 1fr);
  gap: 2px 20px;
  align-items: baseline;
  margin: 0;
  padding: 5px 0;
  border-top: 1px solid var(--hair);
}
.nbrow:first-child { border-top: 0; }
.nbrow .bt-plain { margin: 0; }
.nbnums {
  display: flex;
  flex-wrap: wrap;
  gap: 2px 4px;
}
.nbnums a {
  min-width: 1.9em;
  padding: 1px 4px;
  border-radius: 2px;
  text-align: center;
  color: var(--dim);
  text-decoration: none;
  font: 500 0.74rem/1.5 var(--f-ui);
  font-variant-numeric: tabular-nums;
}
.nbnums a:hover { background: var(--emerald-dim); color: var(--emerald); }
@media (max-width: 62rem) {
  .nbrow { grid-template-columns: 1fr; }
}
.namebooks .bt-plain {
  break-after: avoid;
  margin: 0 0 4px;
  font-family: var(--f-ui);
  font-size: 13px;
  font-weight: 600;
  color: var(--dim);
}
.namebooks .chapterlinks { margin-bottom: 16px; }



/* ------------------------------------------------------------- materials */

/* A catalogue of substances, ordered by how much of Oz is made of each. The
   long tail is the point: fourteen materials have one occupant, and those are
   the entries worth arriving at — one thing in all of Oz is made of wax. So the
   single-entry groups are set exactly like the big ones rather than being swept
   into an "other" bin. */
.matnav {
  display: flex;
  flex-wrap: wrap;
  gap: 5px 4px;
  margin: 0 0 34px;
  padding: 12px 0;
  border-top: 1px solid var(--hair);
  border-bottom: 1px solid var(--hair);
}
.matnav a {
  padding: 4px 9px;
  border-radius: 2px;
  background: var(--surface);
  color: var(--dim);
  font: 500 0.76rem/1 var(--f-ui);
  text-decoration: none;
  white-space: nowrap;
}
.matnav a:hover { background: var(--emerald-dim); color: var(--emerald); }

.matgroup { margin: 0 0 30px; scroll-margin-top: 18px; }
.matgroup h2 {
  display: flex;
  align-items: baseline;
  gap: 10px;
  margin: 0 0 6px;
  padding-bottom: 6px;
  border-bottom: 1px solid var(--hair);
  font-size: 1.15rem;
  font-weight: 600;
}
.matcount {
  font: 500 0.72rem/1 var(--f-ui);
  color: var(--dim);
  font-variant-numeric: tabular-nums;
}
/* An expanded group is a table: the thing on the left, the chapter that says so
   on the right. Same shape as /laws, and for the same reasons — the row header
   above spans the full frame, so evidence that used the left third and stacked
   its citation underneath left two thirds blank and gave the eye no column to
   run down. Finding which books a material comes from meant reading every row.

   The citation was deliberately outside the card, "because the card is the link
   and a citation is not part of what you are clicking". That objection is now
   answered rather than overridden: it is still outside the card, and it is a
   link of its own to the chapter it names. Clicking the name goes to the thing,
   clicking the chapter goes to the chapter, and neither is a surprise. */
.matbody .entity-list > li {
  display: grid;
  /* thing · kind · chapter. `auto` on the middle column sizes it to the widest
     tag in the group, so the tags line up as a column instead of tracking the
     ragged right edge of the names. */
  grid-template-columns: minmax(0, 1fr) auto var(--cite-col);
  align-items: baseline;
  gap: 4px 20px;
  padding: 9px 0;
  border-top: 1px solid var(--hair);
}
.matbody .entity-list > li:first-child { border-top: 0; }
/* .card pairs margin-left:-12px with padding-left:12px so the text sits on the
   row's edge and only the hover tint bleeds past it. Zeroing the padding broke
   that pair and pulled every name 12px left of the heading above it — a
   misalignment that predates the tables and was invisible until the two columns
   gave it something to be out of line with. The vertical padding does go: the
   grid row owns the spacing now. */
.matbody .entity-list > li > .card {
  display: block;
  padding: 0 14px 0 12px;
  margin-left: -12px;
}
/* Block, or the newline between the anchor and this span renders as a leading
   space and every name sits 2px right of the heading it belongs under. */
.matbody .entity-list .card-main { display: block; }
/* Right edge, so the pills form a column of their own rather than three ragged
   widths — character, treasure and place are different lengths and left-aligned
   they wander. */
.matbody .entity-list > li > .wtag { align-self: center; justify-self: end; }
.matsrc {
  margin: 0;
  padding-right: 23px;
  text-align: right;
  color: var(--dim);
  font-size: 0.76rem;
  line-height: 1.4;
}
.matsrc .cite, .matsrc a { color: var(--dim); white-space: nowrap; }

/* Under the point where a reading measure and a citation column both fit, the
   citation goes back beneath its row. */
@media (max-width: 62rem) {
  .matbody .entity-list > li { grid-template-columns: minmax(0, 1fr) auto; gap: 2px 12px; }
  .matsrc { grid-column: 1 / -1; text-align: left; padding-right: 0; }
}
.matgroup .wtag { text-transform: lowercase; letter-spacing: 0.03em; }

/* No .matgroup .blurb rule: the expanded rows carry the name and nothing else
   now. The value they used to print is on the entity's own page, beside the
   sentence that proves it. */


/* The materials list, condensed. Printed flat it was 130 rows deep and you had
   to scroll past gold to learn that wax exists. The list of substances IS the
   page; the things made of each are the evidence for it, so it takes the shape
   every other section here takes — claim on the row, evidence behind a toggle.

   The painted specimen is what makes the list worth looking at rather than
   reading. Materials without one keep their row and their space, because the
   icon is an ornament on a fact and not the fact. */
.matlist {
  list-style: none;
  margin: 26px 0 0;
  padding: 0;
}

.matgroup {
  /* <details> carries a 30px bottom margin site-wide, for the disclosure blocks
     on an entity page where each is a separate thought. Here they are rows in a
     list and must meet. This was the space above every label. */
  margin: 0;
  border-bottom: 1px solid var(--hair);
  scroll-margin-top: 18px;
}
.matgroup > summary {
  display: flex;
  align-items: center;
  gap: var(--spec-gap);
  padding: 16px var(--row-pad);
  cursor: pointer;
  list-style: none;
}
.matgroup > summary::-webkit-details-marker { display: none; }
.matgroup > summary:hover { background: var(--surface); }
.matspec {
  flex: 0 0 var(--spec-w);
  height: var(--spec-w);
  display: flex;
  align-items: center;
  justify-content: center;
}
.matspec img { max-width: 44px; max-height: 44px; width: auto; height: auto; display: block; }
.matname {
  flex: 1 1 auto;
  font-size: 1.05rem;
  font-weight: 600;
}
.matgroup .matcount {
  flex: 0 0 auto;
  font: 500 0.76rem/1 var(--f-ui);
  color: var(--dim);
  font-variant-numeric: tabular-nums;
}
/* The chevron the other toggles use, so an openable row looks openable. */
.matgroup > summary::after {
  content: "›";
  flex: 0 0 auto;
  color: var(--rule);
  transition: transform 0.14s ease;
}
.matgroup[open] > summary::after { transform: rotate(90deg); }
.matbody { padding-left: calc(var(--row-pad) + var(--spec-w) + var(--spec-gap)); }
.matbody .entity-list { margin: 0 0 10px; padding: 0; list-style: none; }
/* The mentions row: a disclosure inside a disclosure.
   Quieter than its parent — smaller name, no specimen slot, a hairline above to
   part it from the table of things — because it is the lesser evidence and
   should not compete with the row that opened onto it. */
.usesgroup { border-top: 1px solid var(--hair); margin-top: 4px; }
.usesgroup > summary {
  display: flex;
  align-items: baseline;
  gap: 14px;
  padding: 11px 0;
  cursor: pointer;
  list-style: none;
}
.usesgroup > summary::-webkit-details-marker { display: none; }
.usesgroup > summary:hover .usesname { color: var(--emerald); }
.usesname {
  flex: 1 1 auto;
  font: 500 0.82rem/1.4 var(--f-ui);
  letter-spacing: 0.02em;
  color: var(--dim);
}
.usesgroup > summary .matcount { flex: 0 0 auto; padding-right: 23px; }
.usesgroup > summary::after {
  content: "›";
  flex: 0 0 auto;
  color: var(--rule);
  transition: transform 0.14s ease;
}
.usesgroup[open] > summary::after { transform: rotate(90deg); }
.usesgroup .namebooks { padding-bottom: 6px; }

/* Kept for the old inline form; nothing renders it now. */
.matuses {
  margin: 0 0 16px;
  color: var(--dim);
  font-size: 0.86rem;
  line-height: 1.6;
}
.matuses .cite { color: var(--dim); }
.matuses .cite:hover { color: var(--emerald); }
/* The last row closes the list; a rule under it draws a line across the page
   and then leaves the footer's standing space below it, which reads as a gap
   rather than as an ending. The space is the same on every index — only this
   one was underlining it. */
.matlist > li:last-child .matgroup { border-bottom: 0; }

/* ------------------------------------------------------------ the timeline */

/* Two eras, and every event behind a disclosure.
 *
 * Written out in full, sixty-eight events with a summary, a quotation and a
 * citation each ran to a page whose shape nobody could see — which defeats the
 * one thing a chronology is for. Closed, the run of titles IS the timeline and
 * the evidence is one click away.
 *
 * The rows are the same rows as the rest of the site: a hairline under each, the
 * thing you are reading on the left, its note in the middle, the chevron at the
 * far right edge, turned down when it is open. Connections, Appears in and the
 * materials list are all built this way, so a reader who has opened one of those
 * already knows how this works. An earlier draft drew a straw spine with a mark
 * per event down the left of every run, which said "timeline" and said it in a
 * vocabulary this site does not otherwise speak; the era and station headings
 * carry the chronology on their own, and the page is quieter without it.
 */

/* Two definitions side by side, ruled rather than boxed. A filled panel here
   read as a callout — a warning, or an aside to skip — and this is neither: it
   is the key to the page, and the reader has to take it in before the first
   event or the dates on the events look like mistakes. */
.timeline .axes {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 0 48px;
  margin: 30px 0 44px;
  padding: 18px 0;
  border-top: 1px solid var(--rule);
  border-bottom: 1px solid var(--rule);
}
.timeline .axis h2 {
  margin: 0 0 6px;
  font-family: var(--f-ui);
  font-size: 12px;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--straw);
}
.timeline .axis p {
  margin: 0;
  max-width: none;
  font-family: var(--f-ui);
  font-size: 14px;
  line-height: 1.6;
  color: var(--dim);
}
@media (max-width: 620px) {
  .timeline .axis + .axis { margin-top: 16px; }
}

.timeline .era { margin: 0 0 52px; }
/* The first era follows the intro paragraphs directly, so it had only a
   paragraph's bottom margin above it and the heading sat on the prose. The
   gap between one era and the next is already the 52px below. */
.timeline .era:first-of-type { margin-top: 44px; }
.timeline .era-head { margin: 0 0 22px; }
.timeline .era-head h2 {
  margin: 0 0 8px;
  font-family: var(--f-display);
  font-size: 30px;
  line-height: 1.15;
}
.timeline .blurb {
  margin: 0;
  max-width: none;
  font-size: 16px;
  line-height: 1.6;
  color: var(--dim);
}

.timeline .phase, .timeline .station { margin: 0 0 34px; }
.timeline .phase h3 {
  margin: 0 0 4px;
  font-family: var(--f-display);
  font-size: 20px;
}

/* A station is a book. The year sits in the margin as the one number on this
   page that is actually known, and the title links to the book itself. */
.timeline .station-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 12px;
  padding-bottom: 6px;
}
.timeline .station-year {
  font-family: var(--f-ui);
  font-size: 13px;
  font-weight: 600;
  color: var(--straw);
  font-variant-numeric: tabular-nums;
}
.timeline .station-head h3 { margin: 0; font-family: var(--f-display); font-size: 20px; }
.timeline .station-head h3 a { color: inherit; text-decoration: none; }
.timeline .station-head h3 a:hover { color: var(--emerald); }
.timeline .station-by { font-family: var(--f-ui); font-size: 12.5px; color: var(--dim); }

/* A book still in copyright. It has not been read, so it has no events and no
   page — it is a name and a date on the shelf, and the January it becomes free
   sits where an event row's chevron would be. Dim rather than absent: the line
   of books carries on past 1930, and only the evidence stops. Tighter margin
   too, so sixteen of them read as a continuing list rather than as sixteen
   empty sections. */
.timeline .station.quiet { margin-bottom: 0; }
.timeline .station.quiet .station-head {
  padding: 11px 0;
  border-bottom: 1px solid var(--hair);
}
.timeline .station.quiet .station-year { color: var(--rule); }
.timeline .station.quiet .station-head h3 { font-size: 17px; color: var(--dim); font-weight: 400; }
.timeline .station-free {
  margin-left: auto;
  font-family: var(--f-ui);
  font-size: 12.5px;
  color: var(--dim);
  font-variant-numeric: tabular-nums;
}
/* The first unread book closes the run of read ones. */
.timeline .station.quiet + .station.quiet { margin-top: 0; }
.timeline .station:not(.quiet) + .station.quiet { margin-top: 6px; }

/* max-width matters: `.page ol` caps every list on the site at the reading
   measure, which is right inside a chapter and wrong for a full-width index. */
.timeline .tl-track {
  list-style: none;
  margin: 6px 0 0;
  padding: 0;
  max-width: none;
  border-top: 1px solid var(--hair);
}
.timeline .tl-row { border-bottom: 1px solid var(--hair); }
.timeline .tl-ev { scroll-margin-top: 90px; }

/* The whole row is the summary, so the note keeps its place in the middle column
   whether the row is open or shut: opening only adds the body beneath it, and
   the control the reader just clicked does not move out from under the pointer
   they would use to close it again. */
.timeline .tl-ev > summary {
  display: grid;
  grid-template-columns: 1fr auto auto;
  align-items: baseline;
  gap: 4px 18px;
  padding: 11px 0;
  cursor: pointer;
  list-style: none;
}
.timeline .tl-ev > summary::-webkit-details-marker { display: none; }
/* Pinned to the third column. A station's rows carry no "Told in" — the heading
   above them already said it — so with auto placement the chevron fell back
   into the middle column and every row inside the shelf sat a few pixels left
   of every row in the prehistory. The edge has to be an edge. */
.timeline .tl-ev > summary::after {
  content: "\203A";
  grid-column: 3;
  align-self: center;
  font-size: 19px;
  line-height: 1;
  color: var(--rule);
  transition: color 0.13s ease, transform 0.13s ease;
}
.timeline .tl-ev > summary:hover::after { color: var(--emerald); }
/* Turned down rather than nudged along: this opens in place, it does not take
   you anywhere. */
.timeline .tl-ev[open] > summary::after { transform: rotate(90deg); color: var(--emerald); }
.timeline .tl-ev > summary:focus-visible { outline: 2px solid var(--emerald); outline-offset: -2px; border-radius: 2px; }

.timeline .tl-title { grid-column: 1; font-size: 16.5px; }
.timeline .tl-ev > summary:hover .tl-title { color: var(--emerald); }

/* The published axis, on the closed row. This is the piece that keeps the page
   honest: an event in the prehistory says "Told in The Tin Woodman of Oz, 1918"
   on the same line as its title, so a reader scanning the closed list can see
   that the founding of the world is a 1918 statement about a time before 1900.
   Inside a station it is not printed at all — the heading above already said it. */
.timeline .tl-told {
  font-family: var(--f-ui);
  font-size: 12.5px;
  color: var(--dim);
}
.timeline .tl-told b { font-weight: 600; }

.timeline .tl-body { padding: 0 0 18px; }
.timeline .tl-sum {
  margin: 0 0 12px;
  max-width: none;
  font-size: 16px;
  line-height: 1.6;
}
/* Quotations get the straw rule they get everywhere else on the site. */
.timeline .tl-ev blockquote,
.timeline .tl-also blockquote {
  margin: 0;
  padding: 2px 0 2px 16px;
  border: 0;
  border-left: 3px solid var(--straw);
  max-width: none;
  font-size: 16.5px;
  line-height: 1.55;
  color: var(--ink);
}
.timeline .tl-body > .cite,
.timeline .tl-also .cite {
  display: inline-block;
  margin: 7px 0 0 19px;
  font-family: var(--f-ui);
  font-size: 12.5px;
}
.timeline .cite .yr { color: var(--rule); }

/* A second book saying the same thing, set back from the first so it cannot be
   mistaken for it. Corroboration is the strongest thing on this page and also
   the rarest, so it is worth the indent. */
.timeline .tl-also { margin: 14px 0 0 19px; }
.timeline .tl-also-label {
  margin: 0 0 5px;
  font-family: var(--f-ui);
  font-size: 12px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--emerald);
}

.timeline .tl-who {
  margin: 11px 0 0;
  font-family: var(--f-ui);
  font-size: 12.5px;
  color: var(--dim);
}
.timeline .tl-who .sep,
.timeline .tl-told .sep { margin: 0 5px; color: var(--rule); }

/* The three disagreements stay open. They are the argument the page is making
   about its own sources, not entries to look something up in, and there are
   three of them — folding those away would be tidiness for its own sake. */
.timeline .disputes { list-style: none; padding: 0; margin: 0; max-width: none; }
/* .sides is shared with the entity pages' canon conflicts, where it sits in a
   prose column. Here the note above it runs the frame, so a quotation
   two-thirds as wide read as a different column rather than as the evidence for
   the sentence it follows. The cap to lift is on the list, not the quotation:
   `.page ul` holds every list on the site to the reading measure, and the
   blockquote inside was only ever as wide as the <ul> it sits in. */
.timeline .sides,
.timeline .sides blockquote { max-width: none; }

/* Once a disagreement became a .tl-ev row, its quotations started matching two
   rules at once: .sides li draws the straw rule for the pair, and the timeline's
   own blockquote rule drew a second one inside it — two nested bars, with the
   quote indented 16px past the citation beneath it. The li owns the rule here,
   so the blockquote gives both back. */
.timeline .sides blockquote { border-left: 0; padding-left: 0; }
.timeline .dispute { margin: 0 0 32px; }
.timeline .dispute h3 { margin: 0 0 6px; font-family: var(--f-display); font-size: 20px; }
.timeline .dispute > p { max-width: none; }
/* The closing paragraph sits under a full-width tally, so a paragraph held to a
   reading measure below it read as a stray column rather than as an ending. */
.timeline .gaps > p { max-width: none; }
.timeline .one-sided {
  margin: 10px 0 0;
  font-family: var(--f-ui);
  font-size: 12.5px;
  color: var(--dim);
}

/* On a narrow screen the note drops under the title rather than competing with
   it for a row that is not there. */
@media (max-width: 700px) {
  .timeline .tl-ev > summary { grid-template-columns: 1fr auto; }
  .timeline .tl-title { grid-column: 1; }
  .timeline .tl-told { grid-row: 2; grid-column: 1; }
  .timeline .tl-ev > summary::after { grid-row: 1; grid-column: 2; }
}


/* -------------------------------------------- colors, professions, laws */

/* Three indexes built on the materials row — same list, same summary, same
   disclosure — so almost nothing is needed here. What follows is only the
   places where a colour, an office or a statute is genuinely not a material.

   The specimen slot is one of them. /materials paints a lump of the substance
   and /colours puts a chip of the pigment there, but an office has no picture
   of itself and neither does a law. Rather than reserve 44px of nothing in
   front of sixty-nine rows, those two drop the column and start at the name. */
.matgroup.nospec > summary { gap: 12px; }
.matgroup.nospec > .matbody { padding-left: var(--row-pad); }

/* The pigment, not a web colour: every value comes from the tokens at the top
   of this file, and two of the five country hues were already there before the
   page existed.

   The blot itself is built in the template, because its shape is turbulence and
   turbulence belongs to SVG. All that is needed here is room for it to bleed —
   the filter region runs well outside the circle, so the element must not be
   clipped or the stain gets a straight edge, which is the one thing an ink blot
   must never have. */
.blot { display: block; overflow: visible; }

/* ---- laws ---- */

/* The summary is longer here than on the other three — a law is a sentence, not
   a word — so the name is allowed to wrap and the count is pinned to the top of
   the row rather than centred against two lines of it. */
/* BASELINE, not centre, and the difference is the whole of why this row looked
   wrong twice.

   Centring makes the two BOXES agree — measured, their midpoints were 0.1px
   apart, which is why it read as correct and was not. What a reader compares is
   the TEXT. The code is all caps and figures with no descenders, so its ink
   sits high inside a line box sized for a font's full ascender-to-descender
   range, while the title beside it is mixed case and fills its box. Two boxes
   perfectly centred, two lines of type visibly out by about 3.7px.

   Aligning the baselines is what "line it up with the text" actually means, and
   it drops the error to about 1px — the rest is the two typefaces disagreeing
   about where their baselines sit, which nothing in CSS can settle.

   The count and the chevron stay centred: neither is text a reader lines up
   against the title, and the chevron rotates about its own centre when the row
   opens. */
/* The code column width lives here because two rules need to agree on it: the
   code itself, and the indent that pulls the body of the law clear of it. */
.lawgroup { --lawcode-w: 8.2rem; }
.lawgroup > summary { align-items: baseline; }

/* The evidence hangs under the TITLE, not under the row.
   It inherited 58px from /materials, where that number clears the painted
   specimen so the body lines up with the material's name. There is no specimen
   here, so 58px lined the quotations up with nothing — they started between the
   code and the title, agreeing with neither.

   Under the title is the right answer rather than flush left, because it leaves
   the code alone in a margin with everything about the law in one column beside
   it, which is how an annotated statute is set and what makes the code column
   mean something. 6px of summary padding, the code, and the summary's gap. */
.lawgroup .matbody { padding-left: calc(var(--lawcode-w) + 18px); }
.lawgroup .matcount { align-self: center; }
.lawgroup > summary::after { align-self: center; }
.lawgroup .matname { font-size: 1rem; line-height: 1.4; font-weight: 600; }

.lawwhere {
  margin: 0 0 14px;
  font: 500 0.78rem/1.4 var(--f-ui);
  color: var(--dim);
}

/* The statute itself, as a table of authorities: the passage on the left, the
   book and chapter it comes from on the right.

   It was a stack first — quote, then its citation underneath, then the next —
   and that failed for a reason the header made obvious. The row above spans the
   full frame, with the code at one edge and the passage count at the other, and
   then the evidence for it used the left third and left the rest blank. Worse,
   with the citation tucked under each quote there was no column to run an eye
   down; finding which books a law comes from meant reading all twelve.

   Two things make it a table rather than two stacked columns. The citations sit
   in a right-hand column that ends where the passage count above it ends, so the
   row and its evidence share an edge. And the rows are separated by the same
   hairline every list on this site uses, which is what carries the eye across
   the gap between a short quote and its citation.

   The left rule on the blockquote is gone with the stack. A rule and a row
   hairline are two devices saying "this is one quotation", and the serif at
   reading size already says the rest — this is the book talking, on a page whose
   whole argument is that you should not have to take our word for it. */
.lawquotes { list-style: none; margin: 6px 0 0; padding: 0; }
.lawquotes > li {
  display: grid;
  /* The quote keeps a reading measure — the full column is ~100 characters at
     this size, which is nobody's idea of readable — and the space left over is
     what puts the citation out at the edge.

     The citation column is sized so a citation NEVER breaks across two lines.
     15rem is not a guess: it is the widest one the corpus can produce, measured
     — "Dorothy and the Wizard in Oz, ch. 20" at 216.7px, plus the 23px inset —
     rather than the widest one currently on the page, which is a smaller number
     that would fail the first time a law cited a longer book. The quote column
     mins at 0, so when the window is tight the passage gives up the width and
     the citation keeps its line. */
  grid-template-columns: minmax(0, 46em) minmax(var(--cite-col), 1fr);
  gap: 8px 28px;
  align-items: baseline;
  padding: 13px 0;
  border-top: 1px solid var(--hair);
}
.lawquotes > li:first-child { border-top: 0; padding-top: 4px; }
.lawquotes blockquote {
  margin: 0;
  font-size: 1rem;
  line-height: 1.6;
}
/* Right-aligned, and inset by the chevron plus the summary's own padding, so a
   citation ends exactly where the passage count above it ends and the two form
   one column down the page.

   The number is measured, and measuring it needs care: getBoundingClientRect on
   a right-aligned box returns the BOX edge, which padding does not move, so the
   obvious check reports no change however far the text actually shifts. Measure
   a Range over the text instead. */
.lawsrc {
  margin: 0;
  padding-right: 23px;
  text-align: right;
  color: var(--dim);
  font-size: 0.78rem;
  line-height: 1.5;
}
/* Belt as well as braces: the column is wide enough, and this makes it certain.
   Safe in the stacked layout below 62rem too, where the citation has the whole
   row — 217px is comfortable on the narrowest phone. */
.lawsrc .cite { color: var(--dim); white-space: nowrap; }

/* Below the point where 46em and a citation column both fit, the citation goes
   back under its quote — a two-column table whose columns are 60% and 40% of a
   phone is not a table, it is two ransom notes. */
@media (max-width: 62rem) {
  .lawquotes > li { grid-template-columns: 1fr; gap: 4px; }
  .lawsrc { text-align: left; padding-right: 0; }
}

/* The statute number.
   Set in the UI face, not a monospace one. The Mecha house system gives mono to
   data and a code is data, but this site loads exactly three faces and
   self-hosts all of them, so a fourth for fourteen labels would be a font
   request to make a label look technical. Tabular figures and wide tracking do
   the same job with what is already here.
   Fixed width so every title starts on the same line down the page, and dim,
   because the code is a handle and the law is the thing. */
.lawcode {
  flex: 0 0 auto;
  width: var(--lawcode-w);
  font: 500 0.7rem/1.4 var(--f-ui);
  letter-spacing: 0.08em;
  /* Straw, the same gold the entity pages give `made of` and `trait`. Those
     labels and this code are the same kind of thing — the key to a fact rather
     than the fact — and the site already had a colour for that. In --dim it
     read as body text that had been turned down; in straw it reads as a label,
     which is what it is. */
  color: var(--straw);
  font-variant-numeric: tabular-nums;
}
/* On a narrow screen the code goes above the title rather than beside it: at
   8rem it was taking a third of the row and breaking every law across four
   lines. */
@media (max-width: 640px) {
  .lawgroup > summary { flex-wrap: wrap; }
  .lawcode { width: 100%; padding: 0 0 3px; }
  /* The code is above the title now, not beside it, so there is no margin left
     to clear and the body goes back to the shared indent. */
  .lawgroup .matbody { padding-left: 0; }
}


/* ---------------------------------------------------------- leaderboards */

/* Twenty-odd boards of ten rows, one column, like everything else here. Two
   boards side by side was tried on paper and rejected for the reason the
   indexes are one column: the eye finishes a board and has to find the top of
   the next one, and a detail line ("Ozma, the Scarecrow, the Cowardly Lion
   and 20 more") wraps every few words at half the frame. The chip nav at the
   top is what makes the length navigable.

   A row is: rank, face, name over a detail line, count. The count is set in
   the UI face in straw, the same as the chapter counts under "Seen alongside"
   on an entity page, because it is the same kind of number. The face is the
   portrait cropped to the head — object-position at the top, since every
   figure stands with its head at the top of the sheet. */
.boardgroup { margin: 44px 0 0; }
.boardgroup > h2.eyebrow { margin-bottom: 26px; }
/* One column of reference rows beside the contents rail, on the entity page's
   grid: the body column is capped and the rail is pushed to the frame's edge.
   Below 1000px the rail is the same row of links above the boards that an
   entity page shows, and the boards take the width. */
@media (min-width: 1000px) {
  .tpl-leaderboards .index-page {
    display: grid;
    grid-template-columns: minmax(0, 54rem) 18rem;
    justify-content: space-between;
    gap: 0 44px;
    align-items: start;
  }
  .tpl-leaderboards .index-page > * { grid-column: 1; min-width: 0; }
  .tpl-leaderboards .index-page > .entity-rail {
    grid-column: 2;
    grid-row: 1 / span 99;
    align-self: stretch;
  }
  .tpl-leaderboards .entity-rail .contents {
    position: sticky;
    top: 24px;
    margin: 0;
    /* Twenty-two boards and five group labels is taller than a short window;
       the rail scrolls inside itself rather than losing its foot. */
    max-height: calc(100vh - 48px);
    overflow-y: auto;
  }
}
/* The rail's label, over the .page heading rule that would size it as a
   section heading here. Same values as .contents h2 above. */
.page .contents h2 {
  margin: 0 0 8px;
  padding: 0;
  border: 0;
  font: 600 11px/1.3 var(--f-ui);
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: var(--dim);
}
/* Sections inside the rail: a closed disclosure per group, its boards inside.
   The summary is set like the site's small caps labels, with the chevron every
   other disclosure carries, so it reads as something that opens. <details>
   carries a 30px bottom margin site-wide; here they are rows in a list. */
.contents .contents-section { margin: 0; }
.contents .contents-section > summary {
  display: flex;
  align-items: center;
  gap: 6px;
  list-style: none;
  cursor: pointer;
  padding: 5px 0;
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--straw);
}
.contents .contents-section > summary::-webkit-details-marker { display: none; }
.contents .contents-section > summary .matcount { font-size: 10px; letter-spacing: 0; color: var(--dim); }
.contents .contents-section > summary::after {
  content: "›";
  margin-left: auto;
  font-size: 14px;
  color: var(--rule);
  transition: transform 0.14s ease;
}
.contents .contents-section[open] > summary::after { transform: rotate(90deg); }
.contents .contents-section > summary:hover { color: var(--emerald); }
.contents .contents-section > ul { padding: 2px 0 8px 10px; }
.contents ul ul { display: flex; flex-wrap: wrap; gap: 4px 18px; }
@media (min-width: 1000px) {
  .contents > ul { flex-direction: column; gap: 0; }
  .contents ul ul { flex-direction: column; gap: 5px; }
  .contents .contents-section > summary::after { margin-left: 4px; }
}
.board { margin: 0 0 40px; scroll-margin-top: 18px; }
.board h3 {
  display: flex;
  align-items: baseline;
  gap: 12px;
  font-family: var(--f-display);
  font-weight: 400;
  font-size: 1.45rem;
  margin: 0 0 4px;
}
/* What a board counts, behind a small mark beside its title. Shown on hover
   and on focus (tabindex on the mark, so a tap or the Tab key reaches it),
   drawn by CSS from data-tip so it needs no script. The mark is deliberately quiet: a reader who wants the
   rule can find it, and one who does not is not read a sentence per board. */
/* Flex, so the mark sits on the title's vertical middle rather than on its
   baseline, where it hung low against the cap height of a serif. */
.board h3 { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; }
.tip {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 16px;
  height: 16px;
  flex: none;
  border: 1px solid var(--rule);
  border-radius: 50%;
  font: 600 10.5px/1 var(--f-ui);
  color: var(--dim);
  cursor: help;
}
.tip:hover, .tip:focus { border-color: var(--emerald); color: var(--emerald); outline: none; }
.tip::after {
  content: attr(data-tip);
  position: absolute;
  left: 50%;
  top: calc(100% + 8px);
  transform: translateX(-50%);
  z-index: 3;
  width: max-content;
  max-width: min(24em, 80vw);
  padding: 9px 12px;
  border: 1px solid var(--rule);
  border-radius: 3px;
  background: var(--surface);
  color: var(--ink);
  font: 400 13.5px/1.45 var(--f-body);
  text-align: left;
  white-space: normal;
  box-shadow: 0 2px 8px rgba(43, 39, 33, 0.08);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity 0.12s ease;
}
.tip:hover::after, .tip:focus::after { opacity: 1; visibility: visible; }
/* Near the left edge the bubble would run off the page; keep it inside. */
@media (max-width: 40rem) {
  .tip::after { left: 0; transform: none; }
}
/* .page caps every list at the prose measure; these are rows, not prose. */
.page .board-rows { list-style: none; margin: 0; padding: 0; max-width: none; }
.board-rows > li:last-child { border-bottom: 1px solid var(--hair); }
.board-rows > li {
  display: grid;
  grid-template-columns: 2.2rem 40px minmax(0, 1fr) auto;
  align-items: center;
  gap: 0 14px;
  padding: 6px 0;
  border-top: 1px solid var(--hair);
}
.board-rank {
  font: 500 0.82rem/1 var(--f-ui);
  color: var(--dim);
  text-align: right;
  font-variant-numeric: tabular-nums;
}
/* A dead heat is marked the way results tables mark it. */
.tied .board-rank::before { content: "="; opacity: 0.55; margin-right: 1px; }
.board-rows > li:first-child .board-rank { color: var(--straw); font-weight: 600; }
/* The link is the face, the name and the detail together, and it takes the
   two middle columns as its own grid so the face stays in its column whether
   or not there is a detail line. */
.board-who {
  grid-column: 2 / 4;
  display: grid;
  grid-template-columns: 40px minmax(0, 1fr);
  align-items: center;
  gap: 0 14px;
  color: inherit;
  text-decoration: none;
  min-width: 0;
}
.board-face {
  display: block;
  width: 40px;
  height: 50px;
  object-fit: cover;
  object-position: 50% 0;
}
.board-face-wide { object-position: 50% 50%; }
.board-face-none { background: transparent; }
.board-text { display: block; min-width: 0; }
.board-name { display: block; font-weight: 600; font-size: 1.02rem; line-height: 1.3; }
.board-who:hover .board-name { color: var(--emerald); text-decoration: underline; text-underline-offset: 2px; }
.board-who:focus-visible { outline: 2px solid var(--emerald); outline-offset: 2px; border-radius: 2px; }
.board-detail {
  display: block;
  color: var(--dim);
  font-size: 0.82rem;
  line-height: 1.35;
  margin-top: 1px;
  overflow-wrap: anywhere;
}
.board-n {
  text-align: right;
  font-family: var(--f-ui);
  font-variant-numeric: tabular-nums;
  line-height: 1.1;
  padding-left: 8px;
}
.board-n b { display: block; font-size: 1.2rem; font-weight: 600; color: var(--straw); }
.board-n small {
  display: block;
  font-size: 0.64rem;
  font-weight: 500;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--dim);
  margin-top: 2px;
  white-space: nowrap;
}
@media (max-width: 40rem) {
  .board-rows > li { grid-template-columns: 1.6rem 34px minmax(0, 1fr) auto; gap: 0 10px; }
  .board-who { grid-template-columns: 34px minmax(0, 1fr); gap: 0 10px; }
  .board-face { width: 34px; height: 42px; }
}
