/* ==========================================================================
   EVERYTHING WRITTEN DOWN -- library.css

   An UNOFFICIAL fan archive. Tibia is a game and a registered trademark of
   CipSoft GmbH. No CipSoft logo or font file is used, and every mark drawn by
   this stylesheet is original CSS or original inline SVG authored for this
   project.

   ONE DELIBERATE EXCEPTION, added with the objects index: item sprites
   extracted from the official client are served under /icons/ and shown on
   objects.html. Those images are CipSoft's artwork, reproduced here for study
   alongside the object text. Nothing else on the site uses them, and this
   stylesheet still draws no CipSoft asset of its own.

   NETWORK CONTRACT
   ----------------
   This stylesheet makes ZERO network requests. No @import, no url() to any
   host, no webfont, no external image. Every family named below is a stack
   of locally-installed system fonts. The vhost serves
   default-src 'self' and the deploy check fails on any external reference,
   so this is enforced, not merely intended.

   CONTENT SECURITY POLICY NOTE
   ----------------------------
   style-src is 'self' with no 'unsafe-inline', so inline style="" attributes
   are blocked by the browser. Nothing here uses them. Anything the router
   must size at runtime is driven by a CSS custom property set through the
   CSSOM, which CSP permits:  el.style.setProperty('--n', '12');

   ASCII ONLY. No em dashes, no smart quotes, no ellipsis character, no
   emoji, no box drawing. Double hyphen "--" stands in for a dash.

   CONTENTS
     01 Tokens
     02 Base and backdrop
     03 Typography
     04 Chrome primitives (panel, ornament, rule, slab)
     05 Buttons, chips and badges
     06 Masthead and navigation
     07 Home: the tally, the thread grid, the shelf grid
     08 The catalogue list
     09 A volume: the object, the identity, the text
     10 Where this leads: edges and the constellation
     11 Threads: the reading path
     12 Names, shelves, series
     13 Search
     13b Marginalia (the comment box)
     14 Footer
     15 Utilities
     16 Responsive
     17 Reduced motion, forced colours, print
   ========================================================================== */


/* ==========================================================================
   01 TOKENS
   Palette is the verified tibia.com website palette plus the classic C++
   client bar colours, carried over unchanged from the previous build of this
   site so the two read as one place. Names are ours.
   ========================================================================== */

:root {
  /* --- The dark field ------------------------------------------------- */
  --night:          #061222;  /* page backdrop. never pure black. */
  --slate:          #16232F;  /* dark chrome band */
  --slate-hi:       #24333F;  /* raised dark chrome */
  --slate-lo:       #0C1A28;  /* recessed dark chrome */

  /* --- Parchment ------------------------------------------------------ */
  --parch-pale:     #FAF0D7;  /* palest paper. inner highlight line. */
  --parch-light:    #F1E0C6;  /* odd rows, primary surface */
  --parch:          #D4C0A1;  /* even rows, main container fill */
  --parch-dim:      #C3AE8D;  /* recessed paper */

  /* --- Ink and frame -------------------------------------------------- */
  --ink:            #5A2800;  /* body copy. dark red-brown, not black. */
  --ink-soft:       #6E4016;  /* secondary copy. 4.92:1 on --parch */
  --muted:          #505050;  /* tertiary on parchment */
  --frame:          #5F4D41;  /* caption bars, 1px content frame */
  --ornament:       #793D03;  /* tooled leather band between sections */
  --stone:          #55636C;  /* 2px cold outer border. the metal. */
  --stone-lit:      #7C8B95;  /* lit edge of the stone */
  --hairline:       #000000;  /* hard outer terminating line */
  --bevel-shadow:   #8B7355;  /* the dark inner bevel on paper */

  /* --- Torchlight ----------------------------------------------------- */
  --gold:           #FFBB05;  /* highlight, active */
  --gold-deep:      #CFA600;  /* secondary gold */
  --gold-ember:     #8A6402;  /* burnt gold, rules and dividers */

  /* --- Edge kinds ------------------------------------------------------
     Each way one book can lead to another gets its own colour, used on the
     badge and on the constellation line. The ramp runs warm for evidence
     that comes from the text itself and cold for evidence that comes only
     from where the volume happens to sit.                                */
  --k-sequence:     #FFBB05;  /* the next volume. the strongest claim. */
  --k-cites:        #FF8A3D;  /* it names the other outright */
  --k-related:      #E0B000;  /* editorially paired */
  --k-subject:      #59D97A;  /* shares rare proper nouns */
  --k-author:       #5FF7F7;  /* the same hand */
  --k-shelf:        #7C8B95;  /* arm's reach on a shelf */
  --k-place:        #6E7D87;  /* found in the same room */

  /* --- Type stacks. LOCAL FAMILIES ONLY. No webfonts, ever. ------------ */
  --face-display: "Palatino Linotype", "Book Antiqua", Palatino,
                  "URW Palladio L", "Liberation Serif", Georgia,
                  "Times New Roman", serif;
  --face-body:    Verdana, Geneva, "DejaVu Sans", Tahoma, Arial, sans-serif;
  --face-mono:    "DejaVu Sans Mono", "Liberation Mono", Consolas,
                  "Courier New", monospace;

  /* --- Metrics --------------------------------------------------------- */
  --tile:           32px;     /* the client renders 32x32 pixel tiles */
  --col-max:        1180px;   /* old-web centred column */
  --gap:            16px;
  --gap-s:          8px;
  --gap-l:          28px;
}


/* ==========================================================================
   02 BASE AND BACKDROP
   ========================================================================== */

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

html {
  /* The whole design is committed to night. There is no light variant:
     the shelves are underground. color-scheme keeps form controls and
     scrollbars from being rendered pale by the browser. */
  color-scheme: dark;
  background: var(--night);
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  scroll-behavior: smooth;
}

body {
  margin: 0;
  padding: 0;
  min-height: 100%;
  font-family: var(--face-body);
  font-size: 15px;
  line-height: 1.55;
  color: var(--parch-light);
  background-color: var(--night);

  /* 1. vignette  2. lamp bloom from above  3. 32px tile lattice  4. night */
  background-image:
    radial-gradient(ellipse 150% 120% at 50% 38%,
                    rgba(6, 18, 34, 0) 0%,
                    rgba(6, 18, 34, 0.55) 62%,
                    rgba(3, 9, 18, 0.92) 100%),
    radial-gradient(ellipse 90% 55% at 50% -8%,
                    rgba(255, 187, 5, 0.075) 0%,
                    rgba(255, 187, 5, 0) 70%),
    repeating-linear-gradient(0deg,
                    rgba(85, 99, 108, 0.075) 0 1px,
                    rgba(85, 99, 108, 0) 1px var(--tile)),
    repeating-linear-gradient(90deg,
                    rgba(85, 99, 108, 0.075) 0 1px,
                    rgba(85, 99, 108, 0) 1px var(--tile));
  background-attachment: fixed;
  background-repeat: no-repeat, no-repeat, repeat, repeat;

  /* The page must never scroll sideways. Wide content scrolls inside its
     own .scroll-x container instead. clip is used rather than hidden so
     that position: sticky keeps working. */
  overflow-x: clip;
}

.wrap {
  width: 100%;
  max-width: var(--col-max);
  margin: 0 auto;
  padding: 0 var(--gap);
}

.band { padding: var(--gap-l) 0; }
.band + .band { padding-top: var(--gap); }

.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 50;
  background: var(--gold);
  color: #000;
  padding: 8px 14px;
  font-weight: 700;
}
.skip:focus { left: 8px; top: 8px; }

:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 2px;
}


/* ==========================================================================
   03 TYPOGRAPHY
   Square, dense, 2002. Verdana at small sizes for copy; a heavy local serif
   in small caps for anything with authority.
   ========================================================================== */

h1, h2, h3, h4, h5 {
  font-family: var(--face-display);
  font-weight: 700;
  margin: 0;
  line-height: 1.15;
  text-wrap: balance;
}

.wordmark {
  font-family: var(--face-display);
  font-size: clamp(1.9rem, 6.4vw, 3.5rem);
  font-weight: 700;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--gold);
  text-shadow:
     1px  1px 0 var(--hairline),
    -1px -1px 0 var(--hairline),
     1px -1px 0 var(--hairline),
    -1px  1px 0 var(--hairline),
     0 0 24px rgba(255, 187, 5, 0.28);
  margin: 0;
}

.kicker {
  font-family: var(--face-body);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--stone-lit);
  margin: 0 0 6px;
}

.band__title {
  font-size: clamp(1.25rem, 4vw, 1.85rem);
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: var(--gold-deep);
  text-shadow: 1px 1px 0 var(--hairline);
  margin: 0;
}

.band__lead {
  max-width: 72ch;
  margin: 10px 0 0;
  color: #C7B9A2;
  font-size: 14px;
}

.band__head { margin-bottom: var(--gap); }

p { margin: 0 0 0.9em; }
p:last-child { margin-bottom: 0; }

a {
  color: var(--gold-deep);
  text-underline-offset: 2px;
}
a:hover { color: var(--gold); }

code, .mono, kbd, samp {
  font-family: var(--face-mono);
  font-size: 0.92em;
  font-variant-ligatures: none;
}

small { font-size: 12px; }

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


/* ==========================================================================
   04 CHROME PRIMITIVES

   THE PANEL RECIPE, from canon:
     outer 1px solid #000 hairline
     then 2px solid #55636C stone border
     then 1px solid #FAF0D7 pale inner highlight
     then the #D4C0A1 parchment fill
     with a full width caption bar in #5F4D41 above the fill.

   All four layers come from one border plus two zero-blur box-shadow rings.
   In this idiom the third dimension comes from stacked hard 1px edges,
   never from a soft shadow. Corners are square everywhere; one rounded
   corner breaks the illusion.
   ========================================================================== */

.panel {
  position: relative;
  border: 2px solid var(--stone);
  border-radius: 0;
  background: var(--parch);
  color: var(--ink);
  box-shadow:
    0 0 0 1px var(--hairline),
    inset 0 0 0 1px var(--parch-pale);
  /* Grid children must be allowed to shrink or long values force the page
     sideways. This is the fix for that, and it must not be removed. */
  min-width: 0;
}

.panel--stone {
  background-color: var(--slate);
  background-image:
    repeating-linear-gradient(45deg,
      rgba(255, 255, 255, 0.022) 0 2px,
      rgba(0, 0, 0, 0.075) 2px 4px);
  color: var(--parch-light);
  box-shadow:
    0 0 0 1px var(--hairline),
    inset 0 0 0 1px rgba(124, 139, 149, 0.55);
}

.panel__caption {
  display: flex;
  align-items: baseline;
  gap: var(--gap-s);
  flex-wrap: wrap;
  margin: 0;
  padding: 6px 10px;
  background: var(--frame);
  color: var(--parch-pale);
  border-bottom: 1px solid var(--hairline);
  font-family: var(--face-body);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  text-shadow: 1px 1px 0 rgba(0, 0, 0, 0.65);
}

.panel--stone > .panel__caption {
  background: var(--slate-hi);
  box-shadow: inset 0 -1px 0 rgba(124, 139, 149, 0.35);
}

.panel__caption-text { min-width: 0; overflow-wrap: anywhere; }

.panel__caption-note {
  margin-left: auto;
  font-size: 11px;
  font-weight: 400;
  letter-spacing: 0.08em;
  color: #D8CCB6;   /* 5.04:1 on --frame */
  text-transform: none;
}

.panel__body { padding: 0; }
.panel__body--pad { padding: 14px; }

.ornament {
  height: 6px;
  background-color: var(--ornament);
  background-image:
    repeating-linear-gradient(45deg,
      rgba(0, 0, 0, 0.42) 0 3px,
      rgba(255, 187, 5, 0.16) 3px 6px);
  box-shadow: 0 1px 0 var(--hairline), 0 -1px 0 var(--hairline);
  margin: var(--gap-l) 0;
}
.ornament--tight { margin: var(--gap) 0; }

.rule {
  height: 1px;
  background: var(--gold-ember);
  opacity: 0.5;
  margin: var(--gap) 0;
  border: 0;
}

.slab {
  background: var(--parch);
  border: 1px solid var(--frame);
  box-shadow:
    0 0 0 1px var(--hairline),
    inset 1px 1px 0 var(--parch-pale),
    inset -1px -1px 0 var(--bevel-shadow);
  color: var(--ink);
  padding: 14px 12px;
  text-align: center;
  min-width: 0;
}

.slab__title {
  font-family: var(--face-display);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink);
  margin: 0 0 6px;
}

.slab__body {
  font-size: 13px;
  line-height: 1.5;
  color: var(--ink-soft);
  margin: 0;
}


/* ==========================================================================
   05 BUTTONS, CHIPS AND BADGES
   ========================================================================== */

.btn {
  display: inline-block;
  font-family: var(--face-body);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--ink);
  background: var(--parch-light);
  border: 1px solid var(--frame);
  box-shadow:
    0 0 0 1px var(--hairline),
    inset 1px 1px 0 var(--parch-pale),
    inset -1px -1px 0 var(--bevel-shadow);
  padding: 7px 13px;
  cursor: pointer;
}
.btn:hover { background: var(--parch-pale); color: var(--ink); }
.btn:active,
.btn[aria-pressed="true"] {
  background: var(--parch-dim);
  box-shadow:
    0 0 0 1px var(--hairline),
    inset 1px 1px 0 var(--bevel-shadow),
    inset -1px -1px 0 var(--parch-pale);
}

.btn--dark {
  color: var(--parch-light);
  background: var(--slate-hi);
  border-color: var(--stone);
  box-shadow:
    0 0 0 1px var(--hairline),
    inset 1px 1px 0 rgba(124, 139, 149, 0.5),
    inset -1px -1px 0 rgba(0, 0, 0, 0.6);
}
.btn--dark:hover { background: #2C3D4A; color: var(--gold); }

/* A chip: a small tappable classification token. */
.chip {
  display: inline-block;
  font-family: var(--face-body);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--parch-light);
  background: var(--slate-lo);
  border: 1px solid var(--stone);
  box-shadow: 0 0 0 1px var(--hairline);
  padding: 2px 7px;
  white-space: nowrap;
}
.chip:hover { color: var(--gold); border-color: var(--gold-ember); }

.chip--ink {
  color: var(--ink);
  background: var(--parch-dim);
  border-color: var(--frame);
}
.chip--ink:hover { color: var(--ink); background: var(--parch-pale); }

/* The edge badge: names the kind of connection, coloured by kind. */
.badge {
  display: inline-block;
  font-family: var(--face-mono);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: #000;
  background: var(--stone-lit);
  border: 1px solid var(--hairline);
  padding: 1px 6px;
  white-space: nowrap;
}
.badge[data-kind="sequence"] { background: var(--k-sequence); }
.badge[data-kind="cites"]    { background: var(--k-cites); }
.badge[data-kind="related"]  { background: var(--k-related); }
.badge[data-kind="subject"]  { background: var(--k-subject); }
.badge[data-kind="author"]   { background: var(--k-author); }
.badge[data-kind="shelf"]    { background: var(--k-shelf); }
.badge[data-kind="place"]    { background: var(--k-place); }

.count {
  font-family: var(--face-mono);
  font-size: 11px;
  font-weight: 700;
  color: var(--gold);
  background: rgba(0, 0, 0, 0.42);
  border: 1px solid rgba(0, 0, 0, 0.8);
  box-shadow: inset 0 0 0 1px rgba(255, 187, 5, 0.22);
  padding: 1px 6px;
  white-space: nowrap;
}


/* ==========================================================================
   06 MASTHEAD AND NAVIGATION
   ========================================================================== */

.masthead {
  position: relative;
  border-bottom: 1px solid var(--hairline);
  box-shadow: 0 1px 0 rgba(124, 139, 149, 0.28);
  padding: var(--gap-l) 0 var(--gap);
  overflow: hidden;
}

/* A lamp above the shelves. Pure CSS: no image is fetched for this. */
.masthead::before {
  content: "";
  position: absolute;
  inset: -40% 0 auto 0;
  height: 260px;
  background: radial-gradient(ellipse 60% 100% at 50% 0%,
              rgba(255, 187, 5, 0.14) 0%, rgba(255, 187, 5, 0) 72%);
  pointer-events: none;
}

.masthead__inner {
  position: relative;
  display: grid;
  grid-template-columns: 132px minmax(0, 1fr);
  gap: var(--gap-l);
  align-items: center;
}

.masthead__mark { width: 132px; height: 148px; display: block; }

.shelf-wood   { fill: #3A2A1C; }
.shelf-wood-lit { fill: #55402C; }
.shelf-shadow { fill: #1A1109; }
.book-spine-a { fill: #7A2318; }
.book-spine-b { fill: #2E4A2A; }
.book-spine-c { fill: #1F3350; }
.book-spine-d { fill: #6A5A22; }
.book-spine-e { fill: #4A2A50; }
.book-spine-f { fill: #5A3218; }
.book-gilt    { fill: var(--gold-ember); }
.lamp-glass   { fill: rgba(255, 187, 5, 0.24); }
.lamp-flame   { fill: var(--gold); }

.masthead__place {
  font-family: var(--face-mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--stone-lit);
  margin: 0 0 4px;
}

.masthead__sub {
  max-width: 74ch;
  margin: 12px 0 0;
  color: #C7B9A2;
  font-size: 14px;
}

.creed {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: 6px 10px;
  margin: 14px 0 0;
  padding: 0;
}

.creed__item {
  font-family: var(--face-mono);
  font-size: 10.5px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--stone-lit);
  border: 1px solid rgba(124, 139, 149, 0.4);
  padding: 1px 7px;
}

/* The navigation bar. Sticky, because a 1226-volume catalogue is a place you
   get lost in and the way out should never scroll away. */
.nav {
  position: sticky;
  top: 0;
  z-index: 20;
  background: var(--slate);
  border-bottom: 1px solid var(--hairline);
  box-shadow: 0 1px 0 rgba(124, 139, 149, 0.3), 0 4px 12px rgba(0, 0, 0, 0.55);
}

.nav__inner {
  display: flex;
  align-items: center;
  gap: 4px;
  flex-wrap: wrap;
  padding: 6px var(--gap);
  max-width: var(--col-max);
  margin: 0 auto;
}

.nav__link {
  font-family: var(--face-body);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--parch-light);
  padding: 6px 10px;
  border: 1px solid transparent;
}
.nav__link:hover { color: var(--gold); border-color: var(--gold-ember); }
.nav__link[aria-current="page"] {
  color: var(--gold);
  background: var(--slate-lo);
  border-color: var(--gold-ember);
}

.nav__brand {
  font-family: var(--face-display);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--gold-deep);
  text-decoration: none;
  padding: 6px 10px 6px 0;
  margin-right: 4px;
  border-right: 1px solid rgba(124, 139, 149, 0.3);
}
.nav__brand:hover { color: var(--gold); }

.nav__spacer { flex: 1 1 auto; }

/* The mark beside a trusted reader's name in the bar. A character rather than
   an icon, because there is no icon font here and there never will be. */
.nav__trust {
  color: var(--gold);
  font-weight: 700;
}

.nav__search {
  font-family: var(--face-body);
  font-size: 12px;
  color: var(--ink);
  background: var(--parch-light);
  border: 1px solid var(--frame);
  box-shadow: inset 1px 1px 0 var(--bevel-shadow);
  padding: 5px 8px;
  width: 190px;
  max-width: 42vw;
}
.nav__search::placeholder { color: var(--muted); }

/* The crumb trail under the nav on inner views. */
.crumbs {
  font-family: var(--face-mono);
  font-size: 11px;
  letter-spacing: 0.06em;
  color: var(--stone-lit);
  padding: 10px 0 0;
}
.crumbs a { color: var(--stone-lit); text-decoration: none; }
.crumbs a:hover { color: var(--gold); }
.crumbs__sep { opacity: 0.5; padding: 0 6px; }


/* ==========================================================================
   07 HOME: THE TALLY, THE THREAD GRID, THE SHELF GRID
   ========================================================================== */

.tally {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(148px, 1fr));
  gap: var(--gap-s);
  margin-top: var(--gap);
}

.tally__cell {
  background: var(--slate-lo);
  border: 1px solid var(--stone);
  box-shadow: 0 0 0 1px var(--hairline);
  padding: 12px 10px;
  text-align: center;
  min-width: 0;
}

.tally__n {
  display: block;
  font-family: var(--face-display);
  font-size: clamp(1.5rem, 5vw, 2.2rem);
  font-weight: 700;
  color: var(--gold);
  text-shadow: 1px 1px 0 var(--hairline);
  line-height: 1.05;
}

.tally__what {
  display: block;
  font-family: var(--face-body);
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--stone-lit);
  margin-top: 4px;
}

.cardgrid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(272px, 1fr));
  gap: var(--gap-s);
}

.card {
  display: block;
  text-decoration: none;
  background: var(--parch);
  border: 2px solid var(--stone);
  box-shadow:
    0 0 0 1px var(--hairline),
    inset 0 0 0 1px var(--parch-pale);
  color: var(--ink);
  min-width: 0;
}
.card:hover {
  border-color: var(--gold-ember);
  color: var(--ink);
}
.card:hover .card__title { color: #3E1B00; }

.card__bar {
  display: flex;
  align-items: baseline;
  gap: var(--gap-s);
  background: var(--frame);
  color: var(--parch-pale);
  border-bottom: 1px solid var(--hairline);
  padding: 5px 9px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}
.card__bar-n { margin-left: auto; color: var(--gold); font-family: var(--face-mono); }

.card__body { padding: 11px 12px 13px; }

.card__title {
  font-family: var(--face-display);
  font-size: 16px;
  font-weight: 700;
  color: var(--ink);
  margin: 0 0 5px;
  line-height: 1.2;
}

.card__note {
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--ink-soft);
  margin: 0;
}


/* ==========================================================================
   08 THE CATALOGUE LIST
   One row per volume. This is the view that has to survive 1226 rows, so it
   is a plain list of hard 1px rules and nothing else.
   ========================================================================== */

.filters {
  display: flex;
  flex-wrap: wrap;
  gap: var(--gap-s);
  align-items: center;
  margin-bottom: var(--gap);
}

.filters__field {
  font-family: var(--face-body);
  font-size: 12px;
  color: var(--ink);
  background: var(--parch-light);
  border: 1px solid var(--frame);
  box-shadow: inset 1px 1px 0 var(--bevel-shadow);
  padding: 5px 7px;
  max-width: 100%;
}

.filters__label {
  font-family: var(--face-body);
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--stone-lit);
}

.listing {
  list-style: none;
  margin: 0;
  padding: 0;
  border-top: 1px solid rgba(124, 139, 149, 0.32);
}

.entry {
  border-bottom: 1px solid rgba(124, 139, 149, 0.32);
}

.entry__link {
  display: grid;
  grid-template-columns: 34px minmax(0, 1fr) auto;
  gap: 12px;
  align-items: baseline;
  padding: 9px 6px;
  text-decoration: none;
  color: var(--parch-light);
}
.entry__link:hover { background: rgba(255, 187, 5, 0.07); color: var(--parch-pale); }
.entry__link:hover .entry__title { color: var(--gold); }

.entry__obj { width: 30px; height: 30px; align-self: center; }

.entry__title {
  font-family: var(--face-display);
  font-size: 15.5px;
  font-weight: 700;
  color: var(--parch-light);
  margin: 0;
  line-height: 1.25;
}

.entry__sub {
  display: block;
  font-size: 12.5px;
  color: #A79880;
  margin-top: 2px;
}

.entry__meta {
  font-family: var(--face-mono);
  font-size: 10.5px;
  letter-spacing: 0.06em;
  color: var(--stone-lit);
  text-align: right;
  white-space: nowrap;
}

.emptynote {
  color: #A79880;
  font-size: 13px;
  padding: var(--gap) 0;
}


/* ==========================================================================
   09 A VOLUME: THE OBJECT, THE IDENTITY, THE TEXT
   ========================================================================== */

.tome-head {
  display: grid;
  grid-template-columns: 168px minmax(0, 1fr);
  gap: var(--gap-l);
  align-items: start;
}

/* The object itself, drawn at a size where the reader can see what it is.
   Every one of these is original inline SVG built by a parametric function
   in library.js from the volume's recorded type; no sprite is used. */
.tome-object {
  width: 168px;
  height: 168px;
  display: block;
  background: var(--slate-lo);
  border: 1px solid var(--hairline);
  box-shadow:
    inset 1px 1px 0 rgba(0, 0, 0, 0.85),
    inset -1px -1px 0 rgba(124, 139, 149, 0.4);
  image-rendering: auto;
}

.tome-object__caption {
  font-family: var(--face-mono);
  font-size: 10.5px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--stone-lit);
  text-align: center;
  margin: 6px 0 0;
  line-height: 1.35;
}

.tome-title {
  font-family: var(--face-display);
  font-size: clamp(1.5rem, 5vw, 2.4rem);
  font-weight: 700;
  color: var(--gold);
  text-shadow: 1px 1px 0 var(--hairline);
  margin: 0;
  line-height: 1.1;
}

.tome-byline {
  font-family: var(--face-display);
  font-size: 15px;
  font-style: italic;
  color: #C7B9A2;
  margin: 6px 0 0;
}

.tome-subject {
  font-family: var(--face-body);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: var(--k-subject);
  margin: 12px 0 0;
}

.tome-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 5px;
  margin: 12px 0 0;
}

/* The card of hard facts: who, where, what it looks like, when it appeared. */
.facts {
  display: grid;
  grid-template-columns: max-content minmax(0, 1fr);
  gap: 0;
  margin: var(--gap) 0 0;
  font-size: 13px;
}

.facts__k {
  font-family: var(--face-body);
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: var(--stone-lit);
  padding: 5px 14px 5px 0;
  border-top: 1px solid rgba(124, 139, 149, 0.25);
  white-space: nowrap;
}

.facts__v {
  color: var(--parch-light);
  padding: 5px 0;
  border-top: 1px solid rgba(124, 139, 149, 0.25);
  min-width: 0;
  overflow-wrap: anywhere;
}
.facts__v a { color: var(--gold-deep); }

/* Our summary. Marked as ours, deliberately and visibly, because everything
   below it is not ours. */
.gloss {
  margin-top: var(--gap-l);
}

.gloss__body {
  padding: 13px 14px;
  font-size: 14px;
  line-height: 1.6;
  color: var(--ink);
}

/* The verbatim text. Set on paper, in a serif, at a comfortable measure --
   this is the thing the reader came for and it gets the best typography on
   the page. */
.leaf {
  margin-top: var(--gap-l);
}

.leaf__body {
  padding: 22px clamp(16px, 4vw, 40px) 26px;
  background: var(--parch-light);
  background-image:
    repeating-linear-gradient(0deg,
      rgba(139, 115, 85, 0.045) 0 1px,
      rgba(139, 115, 85, 0) 1px 3px);
}

.leaf__p {
  font-family: var(--face-display);
  font-size: 16.5px;
  line-height: 1.68;
  color: var(--ink);
  max-width: 68ch;
  margin: 0 auto 1.05em;
}
.leaf__p:last-child { margin-bottom: 0; }

/* An opening line that is plainly a heading in the original gets its weight
   back: the game's books often start with their own title and byline. */
.leaf__p--opening {
  font-weight: 700;
  text-align: center;
  letter-spacing: 0.02em;
  margin-bottom: 1.4em;
}

.leaf__none {
  font-family: var(--face-body);
  font-size: 13px;
  color: var(--muted);
  text-align: center;
  padding: 8px 0;
}

/* The digit volumes at Hellgate. Monospace, because the shape of the run of
   numbers is the entire content. */
.leaf__cipher {
  font-family: var(--face-mono);
  font-size: 13px;
  line-height: 1.75;
  color: var(--ink-soft);
  word-break: break-all;
  max-width: 62ch;
  margin: 0 auto;
}


/* ==========================================================================
   10 WHERE THIS LEADS: EDGES AND THE CONSTELLATION
   The point of the whole archive. Every row states its own reason.
   ========================================================================== */

.leads { margin-top: var(--gap-l); }

.leads__list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.lead {
  border-bottom: 1px solid rgba(0, 0, 0, 0.16);
}
.lead:last-child { border-bottom: 0; }

.lead__link {
  display: grid;
  grid-template-columns: 84px minmax(0, 1fr);
  gap: 12px;
  align-items: start;
  padding: 10px 12px;
  text-decoration: none;
  color: var(--ink);
}
.lead__link:hover { background: rgba(255, 187, 5, 0.14); color: var(--ink); }
.lead__link:hover .lead__title { color: #3E1B00; text-decoration: underline; }

.lead__kind { padding-top: 2px; }

.lead__title {
  font-family: var(--face-display);
  font-size: 15px;
  font-weight: 700;
  color: var(--ink);
  margin: 0;
  line-height: 1.25;
}

/* The reason. This is the sentence that makes the archive worth having, so
   it is not small print: it is the same size as the title's supporting copy
   and it always sits directly beneath the title it explains. */
.lead__why {
  font-size: 13px;
  line-height: 1.5;
  color: var(--ink-soft);
  margin: 3px 0 0;
}

.lead__why b { color: var(--ink); font-weight: 700; }

/* The local map: this volume at the centre, its strongest links radiating.
   Drawn as inline SVG with presentation attributes, never inline style. */
.constellation {
  display: block;
  width: 100%;
  height: auto;
  background: var(--slate-lo);
  border: 1px solid var(--hairline);
  box-shadow: inset 0 0 0 1px rgba(124, 139, 149, 0.28);
}

.cons-line { stroke-width: 1.5; opacity: 0.75; fill: none; }
.cons-line[data-kind="sequence"] { stroke: var(--k-sequence); stroke-width: 2.5; opacity: 1; }
.cons-line[data-kind="cites"]    { stroke: var(--k-cites); stroke-width: 2; }
.cons-line[data-kind="related"]  { stroke: var(--k-related); }
.cons-line[data-kind="subject"]  { stroke: var(--k-subject); }
.cons-line[data-kind="author"]   { stroke: var(--k-author); }
.cons-line[data-kind="shelf"]    { stroke: var(--k-shelf); opacity: 0.45; }
.cons-line[data-kind="place"]    { stroke: var(--k-place); opacity: 0.45; }

.cons-node { fill: var(--slate-hi); stroke: var(--stone-lit); stroke-width: 1; }
.cons-node--self { fill: var(--gold); stroke: var(--hairline); stroke-width: 1.5; }
.cons-hit { fill: transparent; cursor: pointer; }
.cons-hit:hover + .cons-label,
.cons-hit:focus + .cons-label { fill: var(--gold); }

.cons-label {
  font-family: var(--face-body);
  font-size: 10px;
  fill: #C7B9A2;
  pointer-events: none;
}
.cons-label--self { fill: var(--gold); font-weight: 700; }

.legend {
  display: flex;
  flex-wrap: wrap;
  gap: 5px;
  margin-top: var(--gap-s);
}


/* ==========================================================================
   11 THREADS: THE READING PATH
   A path is a sequence of volumes joined by explicit reasons. The reason
   line is drawn as a physical connector between two steps, because that is
   literally what it is.
   ========================================================================== */

.path {
  list-style: none;
  margin: var(--gap) 0 0;
  padding: 0;
  counter-reset: step;
}

.path__step { position: relative; }

.path__because {
  display: grid;
  grid-template-columns: 34px minmax(0, 1fr);
  gap: 12px;
  align-items: center;
  padding: 2px 0;
}

/* The rail: a burnt-gold line running down through the numbers, so the path
   reads as one continuous route and not as a stack of cards. */
.path__rail {
  justify-self: center;
  width: 2px;
  min-height: 34px;
  height: 100%;
  background: var(--gold-ember);
  opacity: 0.65;
}

.path__reason {
  font-size: 13px;
  line-height: 1.5;
  color: #C7B9A2;
  font-style: italic;
  padding: 6px 0;
  margin: 0;
}

.path__card {
  display: grid;
  grid-template-columns: 34px minmax(0, 1fr) 46px;
  gap: 12px;
  align-items: center;
  text-decoration: none;
  color: var(--parch-light);
  background: var(--slate-lo);
  border: 1px solid var(--stone);
  box-shadow: 0 0 0 1px var(--hairline);
  padding: 10px 12px 10px 0;
}
.path__card:hover { border-color: var(--gold-ember); background: #101F2E; }
.path__card:hover .path__title { color: var(--gold); }

.path__n {
  counter-increment: step;
  justify-self: center;
  font-family: var(--face-mono);
  font-size: 12px;
  font-weight: 700;
  color: var(--gold);
  background: rgba(0, 0, 0, 0.45);
  border: 1px solid var(--gold-ember);
  width: 26px;
  height: 26px;
  display: grid;
  place-items: center;
}
.path__n::before { content: counter(step); }

.path__title {
  font-family: var(--face-display);
  font-size: 16px;
  font-weight: 700;
  margin: 0;
  line-height: 1.2;
}

.path__sub {
  display: block;
  font-family: var(--face-body);
  font-size: 12.5px;
  color: #A79880;
  margin-top: 2px;
}

.path__obj { width: 40px; height: 40px; }

.thread-intro {
  font-family: var(--face-display);
  font-size: 16px;
  line-height: 1.6;
  color: var(--parch-light);
  max-width: 74ch;
  margin: var(--gap) 0 0;
}


/* ==========================================================================
   12 NAMES, SHELVES, SERIES
   ========================================================================== */

.namecloud {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: var(--gap);
}

/* A name's weight in the cloud is how many volumes speak it. Set through
   the CSSOM as --w (1 to 5), never as an inline style. */
.namecloud .chip { font-size: calc(10px + (var(--w, 1) * 1.4px)); }

.serieslist {
  list-style: none;
  margin: var(--gap) 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: var(--gap-s);
}

.series {
  background: var(--slate-lo);
  border: 1px solid var(--stone);
  box-shadow: 0 0 0 1px var(--hairline);
  padding: 11px 12px;
  min-width: 0;
}

.series__name {
  font-family: var(--face-display);
  font-size: 15px;
  font-weight: 700;
  color: var(--parch-light);
  margin: 0 0 6px;
}

.series__vols {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}

.series__vol {
  font-family: var(--face-mono);
  font-size: 11px;
  color: var(--parch-light);
  text-decoration: none;
  background: var(--slate-hi);
  border: 1px solid var(--stone);
  padding: 1px 7px;
}
.series__vol:hover { color: var(--gold); border-color: var(--gold-ember); }

/* The prev / next strip on a volume that belongs to a series. */
.seriesbar {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: var(--gap-s);
  margin-top: var(--gap);
}

.seriesbar__step {
  display: block;
  text-decoration: none;
  background: var(--slate-lo);
  border: 1px solid var(--stone);
  box-shadow: 0 0 0 1px var(--hairline);
  padding: 9px 12px;
  color: var(--parch-light);
  min-width: 0;
}
.seriesbar__step:hover { border-color: var(--gold-ember); color: var(--gold); }
.seriesbar__step--next { text-align: right; }
.seriesbar__step--empty { opacity: 0.35; pointer-events: none; }

.seriesbar__dir {
  display: block;
  font-family: var(--face-body);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--stone-lit);
  margin-bottom: 3px;
}

.seriesbar__title {
  font-family: var(--face-display);
  font-size: 14.5px;
  font-weight: 700;
  overflow-wrap: anywhere;
}


/* ==========================================================================
   13 SEARCH
   ========================================================================== */

.searchbox {
  display: flex;
  gap: var(--gap-s);
  flex-wrap: wrap;
  align-items: center;
  margin-bottom: var(--gap);
}

.searchbox__input {
  flex: 1 1 280px;
  font-family: var(--face-body);
  font-size: 15px;
  color: var(--ink);
  background: var(--parch-light);
  border: 1px solid var(--frame);
  box-shadow:
    0 0 0 1px var(--hairline),
    inset 1px 1px 0 var(--bevel-shadow);
  padding: 9px 11px;
  min-width: 0;
}

.searchbox__note {
  font-family: var(--face-mono);
  font-size: 11px;
  color: var(--stone-lit);
  flex-basis: 100%;
}

.hit { background: rgba(255, 187, 5, 0.3); color: inherit; }

.searchopt {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: var(--face-body);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--stone-lit);
  cursor: pointer;
}


/* ==========================================================================
   13b MARGINALIA
   The comment box. Set as an annotation in the margin of a manuscript rather
   than as a web comment thread: same parchment, same hard 1px edges, and the
   form is plainly part of the book's page instead of a widget bolted under it.
   ========================================================================== */

.talk { margin-top: var(--gap-l); }

.talklist {
  list-style: none;
  margin: 0;
  padding: 0;
}

.talkitem {
  border-top: 1px solid rgba(0, 0, 0, 0.16);
  padding: 11px 0;
}
.talkitem:first-child { border-top: 0; padding-top: 0; }
.talkitem:last-child  { padding-bottom: 0; }

.talkitem__who {
  font-family: var(--face-body);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin: 0 0 4px;
  display: flex;
  gap: var(--gap-s);
  flex-wrap: wrap;
  align-items: baseline;
}

.talkitem__when {
  margin-left: auto;
  font-family: var(--face-mono);
  font-weight: 400;
  letter-spacing: 0.04em;
  color: var(--muted);
  text-transform: none;
}

.talkitem__body {
  font-family: var(--face-display);
  font-size: 15.5px;
  line-height: 1.6;
  color: var(--ink);
  margin: 0;
  overflow-wrap: anywhere;
}

.talkform {
  margin-top: var(--gap);
  background: var(--slate-lo);
  border: 1px solid var(--stone);
  box-shadow: 0 0 0 1px var(--hairline);
  padding: 14px;
}

.talkform__note {
  font-size: 12.5px;
  line-height: 1.5;
  color: #A79880;
  max-width: 70ch;
  margin: 0 0 11px;
}

.talkform__name,
.talkform__body {
  display: block;
  width: 100%;
  font-family: var(--face-body);
  font-size: 14px;
  color: var(--ink);
  background: var(--parch-light);
  border: 1px solid var(--frame);
  box-shadow: inset 1px 1px 0 var(--bevel-shadow);
  padding: 8px 10px;
  margin-bottom: var(--gap-s);
}

.talkform__body {
  font-family: var(--face-display);
  font-size: 15px;
  line-height: 1.55;
  resize: vertical;
  min-height: 96px;
}

.talkform__name::placeholder,
.talkform__body::placeholder { color: var(--muted); }

/* The honeypot. Hidden from people without display:none, which some bots
   check for, and taken out of the tab order and the accessibility tree. */
.talkform__trap {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.talkform__row {
  display: flex;
  align-items: center;
  gap: var(--gap);
  flex-wrap: wrap;
}

.talkform__status {
  font-size: 12.5px;
  color: var(--gold-deep);
  min-height: 1.2em;
}

.btn[disabled] { opacity: 0.55; cursor: default; }


/* ==========================================================================
   14 FOOTER
   ========================================================================== */

.footer {
  margin-top: var(--gap-l);
  border-top: 1px solid var(--hairline);
  box-shadow: 0 -1px 0 rgba(124, 139, 149, 0.25);
  padding: var(--gap-l) 0;
  color: #9C8F7C;
  font-size: 12px;
}

.footer__cols {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: var(--gap-l);
}

.footer h3 {
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--stone-lit);
  margin: 0 0 7px;
  font-family: var(--face-body);
}

.footer p { margin: 0 0 0.7em; max-width: 60ch; }


/* ==========================================================================
   15 UTILITIES
   ========================================================================== */

.scroll-x { overflow-x: auto; max-width: 100%; }
.stack > * + * { margin-top: var(--gap); }
.hidden { display: none !important; }
.muted { color: #9C8F7C; }
.nowrap { white-space: nowrap; }


/* ==========================================================================
   16 RESPONSIVE
   ========================================================================== */

@media (max-width: 860px) {
  .masthead__inner { grid-template-columns: 92px minmax(0, 1fr); gap: var(--gap); }
  .masthead__mark  { width: 92px; height: 104px; }
  .tome-head       { grid-template-columns: 120px minmax(0, 1fr); gap: var(--gap); }
  .tome-object     { width: 120px; height: 120px; }
}

@media (max-width: 620px) {
  body { font-size: 14.5px; }
  .tome-head   { grid-template-columns: minmax(0, 1fr); }
  .tome-object { width: 108px; height: 108px; margin: 0 auto; }
  .facts       { grid-template-columns: minmax(0, 1fr); }
  .facts__k    { padding-bottom: 0; border-top: 1px solid rgba(124, 139, 149, 0.25); }
  .facts__v    { border-top: 0; padding-top: 1px; }
  .lead__link  { grid-template-columns: minmax(0, 1fr); gap: 5px; }
  .entry__link { grid-template-columns: 26px minmax(0, 1fr); }
  .entry__meta { grid-column: 2; text-align: left; }
  .seriesbar   { grid-template-columns: minmax(0, 1fr); }
  .seriesbar__step--next { text-align: left; }
  .leaf__body  { padding: 16px 14px 20px; }
  .leaf__p     { font-size: 16px; }
  .nav__search { width: 100%; max-width: none; }
}


/* ==========================================================================
   17 REDUCED MOTION, FORCED COLOURS, PRINT
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
}

@media (forced-colors: active) {
  .panel, .card, .slab, .series, .path__card, .tally__cell {
    border: 1px solid CanvasText;
    box-shadow: none;
  }
  .badge, .chip, .count { border: 1px solid CanvasText; }
  .cons-line { stroke: CanvasText; }
}

@media print {
  html, body {
    background: #FFF;
    color: #000;
  }
  body { background-image: none; }
  .nav, .masthead::before, .constellation, .legend, .searchbox { display: none; }
  .leaf__body { background: #FFF; }
  .leaf__p, .gloss__body, .lead__why { color: #000; }
  .panel { border: 1px solid #000; box-shadow: none; background: #FFF; }
  a { color: #000; text-decoration: underline; }
}
