/* The Endless Online Wiki -- laid out like a wiki, because it is one: left sidebar of site
   navigation, article column with a contents box and edit-less section rules, infobox
   floated right, category footer, a navbox at the foot. Light, dense, and legible; the
   game's own art supplies all the colour the page needs. */

:root {
  --page:      #ffffff;
  --ground:    #f6f4ef;   /* parchment behind the page */
  --ink:       #1c1a17;
  --ink-2:     #3d3a34;
  --ink-3:     #6c675e;
  --rule:      #cfc9bb;
  --rule-2:    #e4dfd3;
  --link:      #2a5db0;
  --link-v:    #6b4ca8;
  --box:       #f3efe4;
  --box-head:  #e3dcc9;
  --accent:    #7a5c1e;
  --good:      #2d7a4f;
  --warn:      #9a3b2c;
  --rare-c:    #b0902c;
  --sans: "Source Sans 3", "Segoe UI", Tahoma, sans-serif;
  --serif: "Bitter", Georgia, "Times New Roman", serif;
  --mono: "IBM Plex Mono", ui-monospace, Consolas, monospace;
  --sidebar: 172px;
  --surface:   #ffffff;   /* cards, chips, table cells */
  --surface-2: #fbfaf6;   /* a panel one step off the card */
  --tint-good: #eaf4ec;
  --tint-blue: #eef3fb;
  --tint-warn: #fff8e8;
  --tint-bad:  #fbf3f1;
  --bar:       #2b2723;   /* the dark chrome bar across the top */
  --bar-edge:  #17140f;
  --bar-ink:   #f4edde;
  --field-edge:#55504a;
  --focus:     #8a7a4a;
  --r1: #2d7a4f; --r2: #4a6f2a; --r3: #8a6a12; --r4: #a8571c; --r5: #9a2f2f;
  --glass:     rgba(255,255,255,.92);  /* the controls floating over a map image */
  --glass-ink: #1c1a17;
}

/* Dark mode. Every colour the page uses is one of the tokens above, so the theme is those
   tokens restated -- nothing else in the sheet changes. The page follows the reader's system
   setting until they pick a side with the header toggle, which pins it (data-theme). */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --page:      #172136;
    --ground:    #071022;
    --ink:       #cbd9f4;
    --ink-2:     #b3c3e2;
    --ink-3:     #8b9bc0;
    --rule:      #596e96;
    --rule-2:    #2b3a57;
    --link:      #8cabe6;
    --link-v:    #b49ae0;
    --box:       #222e45;
    --box-head:  #313e59;
    --accent:    #e0b558;
    --good:      #7fcf9b;
    --warn:      #e88a7a;
    --rare-c:    #e0c869;
    --surface:   #1d2841;
    --surface-2: #192336;
    --tint-good: #1b3329;
    --tint-blue: #1c2a45;
    --tint-warn: #332c1b;
    --tint-bad:  #33222a;
    --bar:       #0d1729;
    --bar-edge:  #050c18;
    --bar-ink:   #dbe6fb;
    --field-edge:#3c4d70;
    --focus:     #8cabe6;
    --r1: #7fcf9b; --r2: #a6cf6a; --r3: #e0c869; --r4: #efa464; --r5: #e88a7a;
    --glass:     rgba(13,23,41,.94);
    --glass-ink: #dbe6fb;
  }
}
:root[data-theme="dark"] {
  --page:      #172136;
  --ground:    #071022;
  --ink:       #cbd9f4;
  --ink-2:     #b3c3e2;
  --ink-3:     #8b9bc0;
  --rule:      #596e96;
  --rule-2:    #2b3a57;
  --link:      #8cabe6;
  --link-v:    #b49ae0;
  --box:       #222e45;
  --box-head:  #313e59;
  --accent:    #e0b558;
  --good:      #7fcf9b;
  --warn:      #e88a7a;
  --rare-c:    #e0c869;
  --surface:   #1d2841;
  --surface-2: #192336;
  --tint-good: #1b3329;
  --tint-blue: #1c2a45;
  --tint-warn: #332c1b;
  --tint-bad:  #33222a;
  --bar:       #0d1729;
  --bar-edge:  #050c18;
  --bar-ink:   #dbe6fb;
  --field-edge:#3c4d70;
  --focus:     #8cabe6;
  --r1: #7fcf9b; --r2: #a6cf6a; --r3: #e0c869; --r4: #efa464; --r5: #e88a7a;
}

* { box-sizing: border-box; }

html { background: var(--ground); }
body {
  margin: 0; color: var(--ink);
  font-family: var(--sans); font-size: 15px; line-height: 1.6;
}
img { image-rendering: pixelated; image-rendering: crisp-edges; }
a { color: var(--link); text-decoration: none; }
a:hover { text-decoration: underline; }
a:visited { color: var(--link-v); }
a.new, a.new:visited { color: var(--warn); }

/* ------------------------------------------------------------------- chrome */
.topbar {
  display: flex; align-items: center; gap: 16px;
  background: var(--bar); color: var(--box-head);
  padding: 0 14px; height: 46px; position: sticky; top: 0; z-index: 60;
  border-bottom: 2px solid var(--bar-edge);
}
.topbar .wordmark {
  font-family: var(--serif); font-weight: 700; font-size: 17px; letter-spacing: .2px;
  color: var(--bar-ink); white-space: nowrap;
}
.topbar .wordmark:hover { text-decoration: none; color: var(--surface); }
.topbar .wordmark b { color: var(--rare-c); }
.search { position: relative; margin-left: auto; width: min(420px, 46vw); }
.search input {
  width: 100%; height: 28px; padding: 0 28px 0 9px; font-size: 14px; font-family: var(--sans);
  border: 1px solid var(--field-edge); border-radius: 2px; background: var(--surface); color: var(--ink);
}
.search input:focus { outline: 2px solid var(--focus); outline-offset: -1px; }
.search kbd {
  position: absolute; right: 7px; top: 6px; font-family: var(--mono); font-size: 10px;
  color: var(--ink-3); border: 1px solid var(--rule); border-radius: 2px; padding: 0 4px; background: var(--surface);
}
.results {
  position: absolute; top: 32px; left: 0; right: 0; max-height: 64vh; overflow: auto;
  background: var(--surface); border: 1px solid var(--rule); box-shadow: 0 12px 28px -12px rgba(0,0,0,.4); z-index: 70;
}
.results a { display: flex; gap: 8px; align-items: center; padding: 5px 9px; color: var(--ink); border-bottom: 1px solid var(--rule-2); }
.results a:last-child { border: 0; }
.results a:hover, .results a.on { background: var(--tint-blue); text-decoration: none; }
.results img { width: 20px; height: 20px; object-fit: contain; flex: none; }
.results .kind { font-family: var(--mono); font-size: 11px; text-transform: uppercase; color: var(--ink-3); min-width: 44px; margin-right: 6px; white-space: nowrap; flex: none; }
.results .sub { margin-left: auto; color: var(--ink-3); font-size: 12px; }

.shell { display: flex; align-items: flex-start; gap: 0; }

.navtoggle { display: none; background: none; border: 0; color: var(--box-head); font-size: 22px;
  line-height: 1; padding: 0 4px; cursor: pointer; }
.navtoggle:hover { color: var(--surface); }
.navdim { display: none; }

.sidebar {
  width: var(--sidebar); flex: none; padding: 14px 10px 40px 14px;
  position: sticky; top: 46px; max-height: calc(100vh - 46px); overflow: auto;
}
.sidebar h5 {
  margin: 14px 0 3px; font-size: 11px; letter-spacing: .6px; text-transform: uppercase;
  color: var(--ink-3); font-weight: 600;
}
.sidebar a { display: block; padding: 1px 0; font-size: 13.5px; }
.sidebar .logo {
  display: block; text-align: center; font-family: var(--serif); font-size: 15px;
  line-height: 1.15; color: var(--accent); border: 2px solid var(--rule); background: var(--surface);
  padding: 10px 6px; margin-bottom: 6px;
}
.sidebar .logo:hover { text-decoration: none; }
.sidebar .logo b { display: block; font-size: 20px; color: var(--ink); }
/* The crescent is the game's own, out of gfx001 (re/wikiart.py site_marks). It is not
   pixel art at this size, so it is the one image on the page that should be smoothed
   rather than take the global `image-rendering: pixelated`. */
.sidebar .logo img { display: block; margin: 0 auto 4px; image-rendering: auto; }
.sidebar .stat { margin-top: 16px; font-size: 11.5px; color: var(--ink-3); font-family: var(--mono); line-height: 1.7; border-top: 1px solid var(--rule-2); padding-top: 8px; }

.article {
  flex: 1; min-width: 0; background: var(--page);
  border-left: 1px solid var(--rule); border-right: 1px solid var(--rule);
  min-height: calc(100vh - 46px); padding: 0 0 60px;
}
.tabs {
  display: flex; gap: 2px; padding: 6px 18px 0; border-bottom: 1px solid var(--rule);
  background: linear-gradient(180deg, var(--surface-2), var(--box));
}
.tabs span, .tabs a {
  font-size: 12.5px; padding: 3px 11px; border: 1px solid var(--rule); border-bottom: 0;
  background: var(--box-head); color: var(--ink-3); border-radius: 2px 2px 0 0;
}
.tabs .on { background: var(--surface); color: var(--ink); position: relative; top: 1px; }
.tabs .right { margin-left: auto; display: flex; gap: 2px; }
/* NO WIDTH CAP: the article fills whatever the window gives it, which is how the OSRS wiki
   scales -- measured at 1900px, its sidebar is a fixed 168 and its content runs the whole
   remaining 1660 with no max-width and no centring. The cap used to be 1180 pinned left,
   which left 533px of empty panel at that width; centring it instead only moved the gap to
   both sides. What keeps a line of prose readable is the infobox floating into it, the same
   as there. */
.body { padding: 14px 24px 0; }

/* ------------------------------------------------------------------ article */
h1 {
  font-family: var(--serif); font-weight: 400; font-size: 30px; margin: 4px 0 2px;
  padding-bottom: 5px; border-bottom: 1px solid var(--rule); letter-spacing: -.2px;
}
h2 {
  font-family: var(--serif); font-weight: 400; font-size: 21px; margin: 26px 0 8px;
  padding-bottom: 4px; border-bottom: 1px solid var(--rule);
}
h3 { font-family: var(--serif); font-weight: 600; font-size: 15.5px; margin: 18px 0 4px; }
p { margin: 8px 0; }
.lead { font-size: 15.5px; }
ul.plain { margin: 6px 0; padding-left: 20px; }

.hatnote {
  font-size: 13.5px; color: var(--ink-2); background: var(--box); border: 1px solid var(--rule-2);
  border-left: 3px solid var(--accent); padding: 7px 12px; margin: 10px 0;
}
.hatnote.warn { border-left-color: var(--warn); background: var(--tint-bad); }
.hatnote b { color: var(--ink); }

/* contents box, floated like a wiki's */
/* The contents box is a block above the first section, not a float: floated, a numbered
   walkthrough wrapped around it and every table beside it was squeezed to half width. */
.toc {
  display: table; min-width: 230px; max-width: 420px; background: var(--box);
  border: 1px solid var(--rule); padding: 8px 14px 10px; margin: 10px 0 12px;
  font-size: 13.5px;
}
.toc h4 { margin: 0 0 4px; font-family: var(--serif); font-size: 14px; font-weight: 600; text-align: center; }
.toc ol { margin: 0; padding-left: 20px; }
.toc li { margin: 1px 0; }
.clearfix::after { content: ""; display: block; clear: both; }

/* infobox */
.infobox {
  float: right; width: 272px; margin: 6px 0 14px 22px; background: var(--box);
  border: 1px solid var(--rule); font-size: 13px;
}
.infobox .ib-title {
  background: var(--box-head); font-family: var(--serif); font-size: 16px; text-align: center;
  padding: 5px 8px; border-bottom: 1px solid var(--rule); font-weight: 600;
}
.infobox .ib-img { text-align: center; padding: 12px 8px; background: var(--surface-2); border-bottom: 1px solid var(--rule-2); }
.infobox .ib-img img { max-width: 132px; max-height: 132px; }
.infobox .ib-sec {
  background: var(--box-head); text-align: center; font-size: 11.5px; letter-spacing: .5px;
  text-transform: uppercase; color: var(--ink-2); padding: 3px; border-top: 1px solid var(--rule);
  border-bottom: 1px solid var(--rule);
}
.infobox table { width: 100%; border-collapse: collapse; }
.infobox th, .infobox td { padding: 3px 9px; border-bottom: 1px solid var(--rule-2); vertical-align: top; }
.infobox th { text-align: left; font-weight: 600; width: 45%; color: var(--ink-2); }
.infobox td { text-align: right; }

/* tables */
table.wt { border-collapse: collapse; width: 100%; margin: 8px 0 6px; font-size: 13.5px; background: var(--surface); }
table.wt th, table.wt td { border: 1px solid var(--rule); padding: 4px 8px; }
table.wt th {
  background: var(--box-head); font-weight: 600; text-align: left; font-size: 12.5px;
  position: sticky; top: 46px; z-index: 2;
}
table.wt tbody tr:nth-child(even) { background: var(--surface-2); }
table.wt tbody tr:hover { background: var(--tint-blue); }
table.wt td.num, table.wt th.num { text-align: right; font-variant-numeric: tabular-nums; }
table.wt img.mini { width: 22px; height: 22px; object-fit: contain; vertical-align: middle; margin-right: 6px; }
td.rare { font-family: var(--mono); font-size: 12.5px; }
.r1 { color: var(--r1); } .r2 { color: var(--r2); } .r3 { color: var(--r3); }
.r4 { color: var(--r4); } .r5 { color: var(--r5); font-weight: 600; }

.grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(178px, 1fr)); gap: 6px; margin: 10px 0; }
.card { display: flex; gap: 8px; align-items: center; padding: 5px 8px; border: 1px solid var(--rule-2); background: var(--surface-2); color: var(--ink); }
.card:hover { border-color: var(--rule); background: var(--tint-blue); text-decoration: none; }
.card img { width: 26px; height: 26px; object-fit: contain; flex: none; }
.card b { font-weight: 400; font-size: 13.5px; display: block; line-height: 1.25; }
.card span { font-size: 12px; color: var(--ink-3); }

.cats {
  margin: 34px 24px 0; padding: 7px 12px; border-top: 1px solid var(--rule);
  background: var(--surface-2); font-size: 13px; color: var(--ink-2);
}
.cats b { font-weight: 600; margin-right: 6px; }
.cats a { margin-right: 10px; }

/* the navbox at the foot of an article */
.navbox {
  margin: 28px 0 0; border: 1px solid var(--rule); background: var(--box); font-size: 12.5px;
  clear: both;
}
.navbox .nb-title { background: var(--box-head); text-align: center; font-weight: 600; padding: 3px; border-bottom: 1px solid var(--rule); font-family: var(--serif); }
.navbox .nb-row { display: flex; border-bottom: 1px solid var(--rule-2); }
.navbox .nb-row:last-child { border-bottom: 0; }
.navbox .nb-group { flex: none; width: 140px; background: var(--box-head); font-weight: 600; padding: 3px 8px; text-align: center; }
.navbox .nb-list { flex: 1; padding: 3px 8px; }
.navbox .nb-list a + a::before { content: " · "; color: var(--ink-3); }

.filters { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; margin: 10px 0 2px; }
.filters input, .filters select {
  height: 27px; border: 1px solid var(--rule); background: var(--surface); color: var(--ink);
  padding: 0 7px; font-family: var(--sans); font-size: 13.5px; border-radius: 2px;
}
.count { margin-left: auto; font-size: 12px; color: var(--ink-3); font-family: var(--mono); }
.more { display: block; width: 100%; margin: 8px 0; padding: 6px; background: var(--box);
        color: var(--ink); border: 1px solid var(--rule); font-size: 13px; cursor: pointer; }
.more:hover { background: var(--box-head); }
/* `display: block` here is an AUTHOR rule and the `hidden` attribute is only the browser's
   own `display: none`, so this rule won every time and the button stayed on screen after the
   last row was drawn -- reading "show more (0 left)". Anything hidden by the attribute has to
   say so again once the class sets a display, which is why .card and .mechcard repeat it:
   the category page filters its grid with `hidden` and nothing was being filtered out. */
.more[hidden], .card[hidden], .mechcard[hidden] { display: none; }

/* -------------------------------------------------------------- map viewer */
/* `overflow: hidden` makes this a block formatting context, and a BFC SHRINKS to avoid a
   float -- so beside the floated infobox the map box was 460px wide inside a 1004px column
   and every map drew at a third of the size it should. Clearing the float is what gives it
   the full width back. */
.viewer {
  position: relative; height: 560px; margin: 10px 0 4px; overflow: hidden; clear: both;
  background: #11131a; border: 1px solid var(--rule); cursor: grab;
}
.viewer.drag { cursor: grabbing; }
.viewer.small { height: 300px; }
.stage { position: absolute; top: 0; left: 0; transform-origin: 0 0; will-change: transform; }
.stage img { display: block; }
/* Map markers are PINS, not dots: a teardrop whose point sits on the tile, so it is obvious
   which tile is meant and several kinds can overlap without turning into confetti. The shape
   is one rotated square with a round top -- no images, and it scales with the zoom. */
.mk {
  position: absolute; width: 16px; height: 16px; margin: -19px 0 0 -8px; cursor: pointer;
  border: 1.5px solid var(--bar-edge); border-radius: 50% 50% 50% 0; transform: rotate(-45deg);
  box-shadow: 1px -1px 3px rgba(0,0,0,.45); transform-origin: 50% 50%;
}
.mk::after {                                   /* the pin's eye */
  content: ""; position: absolute; left: 4px; top: 4px; width: 6px; height: 6px;
  border-radius: 50%; background: rgba(255,255,255,.85);
}
.mk.aggro { background: #e2402c; }
.mk.passive { background: #f0a72c; }
.mk.service { background: #3f8fe0; }
.mk.node { background: #3fbf72; }
.mk.trap { background: #d64bbd; border-radius: 2px; transform: rotate(0deg); margin: -8px 0 0 -8px; }
.mk.trap::after { left: 3px; top: 3px; width: 8px; height: 8px; border-radius: 1px; background: rgba(255,255,255,.6); }
.mk.warp { background: #45cbe0; border-radius: 3px 3px 50% 50%; transform: rotate(0deg); margin: -18px 0 0 -8px; }
.mk.warp::after { left: 5px; top: 6px; width: 6px; height: 7px; border-radius: 1px; }
.mk.you { background: var(--surface); width: 20px; height: 20px; margin: -24px 0 0 -10px;
          border-color: var(--warn); box-shadow: 0 0 0 2px rgba(179,38,30,.5), 1px -1px 4px rgba(0,0,0,.5); }
.mk.you::after { left: 5px; top: 5px; width: 8px; height: 8px; background: var(--warn); }
.mk:hover { z-index: 6; filter: brightness(1.25); box-shadow: 0 0 0 3px rgba(255,255,255,.8); }
.chip i.pin { width: 9px; height: 9px; border-radius: 50% 50% 50% 0; transform: rotate(-45deg); }
.vtools { position: absolute; left: 8px; top: 8px; z-index: 12; display: flex; flex-wrap: wrap; gap: 5px; max-width: calc(100% - 120px); }
.chip { display: inline-flex; align-items: center; gap: 5px; padding: 2px 8px; font-size: 11.5px;
        background: var(--glass); color: var(--glass-ink);
        border: 1px solid var(--rule); border-radius: 10px; cursor: pointer; user-select: none; }
.chip.off { opacity: .45; }
.chip i { width: 8px; height: 8px; border-radius: 50%; }
.vzoom { position: absolute; right: 8px; top: 8px; z-index: 12; display: flex; gap: 4px; }
.vzoom button { width: 26px; height: 26px; font-size: 13px; background: var(--glass);
                color: var(--glass-ink);
                border: 1px solid var(--rule); cursor: pointer; border-radius: 2px; }
.vread { position: absolute; right: 8px; bottom: 8px; z-index: 12; font-family: var(--mono);
         font-size: 11px; background: var(--glass); color: var(--glass-ink);
         border: 1px solid var(--rule); padding: 2px 7px; }
.tip { position: absolute; z-index: 20; pointer-events: none; transform: translate(-50%, -140%);
       background: var(--surface-2); border: 1px solid var(--ink-3); padding: 3px 7px; font-size: 12px;
       white-space: nowrap; box-shadow: 0 8px 18px -8px rgba(0,0,0,.6); }
.tip span { display: block; font-size: 11.5px; color: var(--ink-3); }

/* -------------------------------------------------------------- craft widget */
/* One card: the product and its station in the head; one column per direct ingredient with
   what that ingredient takes stacked under it; the from-scratch totals along the foot. */
.craft { margin: 8px 0 18px; }
.ecard { background: var(--surface); border: 1px solid var(--rule); }
.ehead { display: flex; align-items: center; gap: 8px; padding: 7px 12px; background: var(--box-head); border-bottom: 1px solid var(--rule); font-size: 14px; }
.ehead img { width: 24px; height: 24px; object-fit: contain; }
.ehead .pname { font-weight: 700; font-family: var(--serif); font-size: 15px; }
.ehead .opt { background: var(--surface); border: 1px solid var(--rule); font-size: 11.5px; font-weight: 600; padding: 0 6px; margin-right: 4px; }
.ehead .st { color: var(--ink-3); font-size: 12.5px; margin-left: auto; text-align: right; }
.ecols { display: flex; flex-wrap: wrap; gap: 8px; padding: 10px 12px; }
.ecol { flex: 1 1 200px; min-width: 200px; max-width: 100%; border: 1px solid var(--rule-2); border-radius: 4px; background: var(--surface-2); }
.ecol > .ep { padding: 6px 8px; background: var(--box); border-bottom: 1px solid var(--rule-2); font-weight: 600; }
.ecol > .ep.base { background: var(--tint-good); }
.ecol > .ep:only-child { border-bottom: 0; }
.esub { padding: 4px 6px 6px; }
.ep { display: flex; align-items: center; gap: 6px; font-size: 13px; padding: 2px 4px; white-space: nowrap; color: var(--ink); }
.ep img { width: 22px; height: 22px; object-fit: contain; flex: none; }
.ep b { color: var(--accent); }
.ep span { color: var(--link); }
.ep:hover span { text-decoration: underline; }
.esub .ep.made { font-weight: 600; }
.esub .ep.base span { color: var(--good); }
.esub .esub { margin-left: 14px; border-left: 2px solid var(--rule-2); padding-left: 8px; }
.efoot { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; padding: 8px 12px; border-top: 1px solid var(--rule); background: var(--box); font-size: 13px; }
.efoot .lbl { font-weight: 700; margin-right: 4px; }
.echip { display: inline-flex; align-items: center; gap: 4px; background: var(--surface); border: 1px solid var(--rule); border-radius: 12px; padding: 1px 9px 1px 4px; color: var(--ink); }
.echip img { width: 20px; height: 20px; object-fit: contain; }
.echip b { color: var(--accent); }
.echip.fee { background: var(--tint-warn); padding-left: 9px; }
/* the gathering aid: a collapse toggle on any part with its own recipe, and a tick box on
   every line of the required list. Both are the viewer's own state (localStorage). */
.ep .epl { display: inline-flex; align-items: center; gap: 6px; color: inherit; text-decoration: none; min-width: 0; }
.etog { flex: none; width: 16px; height: 16px; padding: 0; border: 0; background: none; cursor: pointer; font-size: 11px; line-height: 16px; color: var(--muted); }
.etog:hover { color: var(--ink); }
.etog.spacer { cursor: default; }
.ep.have { opacity: 0.55; }
.ep.have span { text-decoration: line-through; }
.ecol > .ep.have { background: var(--box); }
.echip a { display: inline-flex; align-items: center; gap: 4px; color: inherit; text-decoration: none; }
.echip a:hover span, .echip a:hover { text-decoration: underline; }
.echip input { margin: 0 2px 0 0; cursor: pointer; }
.echip.done { opacity: 0.5; }
.echip.done a { text-decoration: line-through; }
.echip.done a:hover { text-decoration: line-through underline; }
.ehint { flex-basis: 100%; font-size: 12px; margin-top: 2px; }
.ep .eck { margin: 0 2px 0 0; flex: none; cursor: pointer; }
.ep.done { opacity: 0.45; }
.ep.done .epl span, .ep.done .epl b { text-decoration: line-through; }
.ecol > .ep.done { background: var(--rule-2); }
.etools { display: inline-flex; gap: 6px; margin-left: auto; }
.ebtn { font: inherit; font-size: 12px; padding: 2px 8px; border: 1px solid var(--rule); border-radius: 4px; background: var(--surface); color: var(--ink); cursor: pointer; }
.ebtn:hover { background: var(--box); }

.cols2 { column-count: 2; column-gap: 26px; }
@media (max-width: 1050px) { .cols2 { column-count: 1; } }
@media (max-width: 860px) {
  .navtoggle { display: block; }
  .sidebar { display: none; position: fixed; top: 46px; left: 0; bottom: 0; z-index: 80;
    width: 270px; max-width: 82vw; max-height: none; background: var(--page);
    border-right: 1px solid var(--rule); box-shadow: 0 10px 30px -8px rgba(0,0,0,.45);
    padding: 12px 14px 40px; overflow: auto; }
  body.navopen .sidebar { display: block; }
  body.navopen .navdim { display: block; position: fixed; inset: 46px 0 0 0; z-index: 75;
    background: rgba(0,0,0,.35); }
  .sidebar .logo { display: none; }
  .infobox { float: none; width: auto; margin: 10px 0; }
  .toc { float: none; max-width: none; display: block; }
  .body { padding: 12px 14px 0; }
}

/* one map viewer per map an NPC appears on, picked with a row of buttons */
.mapsel { display: flex; flex-wrap: wrap; gap: 5px; margin: 8px 0 0; }
.mapsel button { font-size: 12.5px; padding: 3px 9px; border: 1px solid var(--rule);
                 background: var(--surface); color: var(--ink); cursor: pointer; border-radius: 2px; }
.mapsel button.on { background: var(--box-head); color: var(--ink); font-weight: 600;
                    border-color: var(--accent); }
.mapsel button:hover { border-color: var(--accent); }

/* one boxed block per recipe an item has */
.opt { border: 1px solid var(--rule); background: var(--surface-2); margin: 10px 0; }
.opt > h4 { margin: 0; padding: 4px 10px; background: var(--box-head); font-family: var(--serif);
            font-size: 14px; font-weight: 600; border-bottom: 1px solid var(--rule); }
.opt > div { padding: 8px 10px; }

/* the equipment stat block */
.statgrid { display: grid; grid-template-columns: repeat(auto-fit, minmax(88px, 1fr)); gap: 1px;
            background: var(--rule); border: 1px solid var(--rule); margin: 10px 0; }
.statgrid > div { background: var(--surface); padding: 6px 9px; text-align: center; }
.statgrid dt { font-size: 11px; letter-spacing: .6px; text-transform: uppercase; color: var(--ink-3); }
.statgrid dd { margin: 1px 0 0; font-size: 17px; font-variant-numeric: tabular-nums; }
.rolltbl td:first-child { font-weight: 600; }
.rolltbl tbody tr.best { background: var(--tint-good); }

/* sortable list headers */
table.wt th.sortcol { cursor: pointer; user-select: none; }
table.wt th.sortcol:hover { background: var(--rule); }
table.wt th.sortcol::after { content: " ⇅"; color: var(--ink-3); font-size: 11px; }
table.wt th.sorted::after { content: " ▲"; color: var(--accent); }
table.wt th.sorted[data-dir="desc"]::after { content: " ▼"; color: var(--accent); }

/* the mechanics index: one card per article */
.mechgrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 10px; margin: 10px 0 18px; }
.mechcard { display: block; padding: 10px 12px; border: 1px solid var(--rule); border-radius: 3px;
  background: var(--surface-2); text-decoration: none; }
.mechcard:hover { background: var(--box); border-color: var(--accent); }
.mechcard b { display: block; color: var(--accent); margin-bottom: 3px; }
.mechcard span { display: block; color: var(--ink); font-size: 13px; line-height: 1.35; }

/* a quest walkthrough */
ol.steps { margin: 8px 0 14px; padding-left: 26px; }
ol.steps li { margin: 5px 0; line-height: 1.5; }

/* a dev post reads as an article: the developer's prose under its own section heads */
.devpost p { max-width: 78ch; }
.updates td.ver { font-family: var(--mono); white-space: nowrap; }

/* secondary text inside a cell */
.muted { color: var(--ink-2); font-size: 12.5px; }

/* recorded NPC dialogue */
.dialog { border-left: 3px solid var(--rule); padding: 2px 12px; margin: 8px 0 12px; }
.dialog p { margin: 4px 0; }
.dialog ul.plain li { color: var(--ink-3); }

/* keyboard users: a visible focus ring everywhere, and a skip link that appears on focus */
a:focus-visible, button:focus-visible, input:focus-visible, [tabindex]:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.skip { position: absolute; left: -999px; top: 8px; background: var(--surface); color: var(--ink); padding: 6px 10px; border: 1px solid var(--rule); z-index: 100; }
.skip:focus { left: 8px; }

/* quest walkthrough checklist */
.checklist { border: 1px solid var(--rule); background: var(--surface); margin: 8px 0 14px; }
.checklist .step { display: flex; gap: 10px; align-items: flex-start; padding: 8px 12px; border-bottom: 1px solid var(--rule-2); cursor: pointer; line-height: 1.5; }
.checklist .step:last-of-type { border-bottom: 0; }
.checklist .step input { margin: 4px 0 0; flex: none; width: 16px; height: 16px; accent-color: var(--accent); }
.checklist .step .num { flex: none; min-width: 22px; font-family: var(--mono); font-size: 12px; color: var(--ink-3); padding-top: 2px; }
.checklist .step .txt { flex: 1; }
.checklist .step.done .txt { color: var(--ink-3); text-decoration: line-through; }
.checklist .step:hover { background: var(--surface-2); }
.checkfoot { display: flex; justify-content: space-between; padding: 6px 12px; background: var(--box-head); font-size: 12.5px; color: var(--ink-3); border-top: 1px solid var(--rule); }

/* narrow screens: a wide table scrolls inside the page instead of widening it */
@media (max-width: 640px) {
  #main table.wt { display: block; overflow-x: auto; max-width: 100%; }
  #main .infobox { float: none; width: auto; margin: 0 0 12px; }
}

/* a dialogue choice inside a walkthrough step, drawn as the button the game shows */
.say { display: inline-block; font-size: 12.5px; line-height: 1.3; padding: 0 6px; margin: 0 1px; background: var(--surface);
       border: 1px solid var(--rule); border-radius: 3px; box-shadow: 0 1px 0 var(--rule); white-space: nowrap; }

/* the licence line under every page */
.foot { margin: 26px 14px 18px; padding-top: 8px; border-top: 1px solid var(--rule-2); font-size: 12px; color: var(--ink-3); }

/* The light/dark switch in the header. It sits on the topbar, which is dark in both themes. */
.themetoggle {
  flex: none; width: 30px; height: 28px; padding: 0; cursor: pointer;
  background: none; border: 1px solid var(--field-edge); border-radius: 2px;
  color: var(--bar-ink); font-size: 15px; line-height: 1;
}
.themetoggle:hover { background: rgba(255,255,255,.08); }

/* The maze guide's key strings: one letter a step, big enough to follow with a finger while
   the other hand is on the arrow keys, and wrapping rather than running off a phone. */
.mzrow { line-height: 2; word-spacing: 2px; }
.mzk { display: inline-block; min-width: 18px; text-align: center; font-family: var(--mono);
       background: var(--box); border: 1px solid var(--rule); border-radius: 3px; font-size: 13px; }
.mzw { font-size: 12px; color: var(--accent); padding: 0 4px; }

/* The maze stepper: one view at a time, the moves under it, and a key to what is drawn on it.
   The key's swatches are the same colours re/mazeguide.py paints onto the frames. */
.mzview { max-width: 660px; margin: 12px 0; }
.mzview img { display: block; width: 100%; image-rendering: auto; border: 1px solid var(--rule); }
.mzbar { display: flex; align-items: center; justify-content: space-between; margin: 0 0 6px; font-family: var(--mono); font-size: 13px; }
.mzmoves { margin: 10px 0 4px; padding-left: 22px; font-size: 15px; }
.mzmoves li { margin: 2px 0; }
.mzkey { display: flex; flex-wrap: wrap; gap: 6px 16px; font-size: 13px; margin: 8px 0; }
.mzkey i { display: inline-block; width: 14px; height: 10px; margin-right: 5px; vertical-align: -1px; border-radius: 2px; }
.mzkey .k-you { background: #fff; border: 2px solid #222; border-radius: 50%; width: 10px; }
.mzkey .k-path { background: #ffd728; }
.mzkey .k-inv { background: rgba(220,40,40,.55); border: 1px solid #ff3c3c; }
.mzkey .k-fake { border: 2px dashed #50e678; }
.mzkey .k-go { border: 3px solid #46e66e; border-radius: 50%; }
.mzkey .k-no { border: 3px solid #f03c3c; border-radius: 50%; }
