
:root {
  --bg:      #14161a;
  --panel:   #1b1e24;
  --panel-2: #22262e;
  --line:    #2e333d;
  --text:    #d8dae0;
  --dim:     #8b93a1;
  --faint:   #666d7a;
  --link:    #79b8ff;
  --gold:    #d9a441;
  --green:   #7bbf6a;
  --red:     #d1666a;

  /* The content column. 1100px was set when a page was a paragraph and a
     short table; the servers table is seven columns and the zone lists run
     to sixty names, and both were being squeezed for no reason. One value,
     used by the body, the notice and the footer, so they cannot drift apart.

     Not wider than this: prose above about 90 characters a line is harder to
     read, not easier, and the notes on these pages are prose. 1280 keeps a
     14px line around 85 at its widest while giving the tables their room. */
  --page: 1280px;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font: 15px/1.55 system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
}

/* A spell icon is a 40x40 window onto a sheet, not an image of its own. The
   sheets are served whole so a list of fifty spells pulls three or four
   files; sliding the sheet behind the hole is what picks one icon out. */
.icon { display: inline-block; width: 40px; height: 40px; flex: 0 0 40px;
        border: 1px solid var(--line); border-radius: 4px;
        background-repeat: no-repeat; background-color: var(--panel-2); }

.unknown { color: var(--faint); font-style: italic; }

/* The item tooltip, in the site's colours rather than the client's.
   Deliberately recognisable as the in-game window — a title bar, the name in
   its rarity colour, two columns of numbers — without pretending to be a
   screenshot of it. */
.tt {
  width: min(460px, 100%);
  background: #0f1115;
  border: 1px solid var(--line);
  border-radius: 5px;
  font-size: 13.5px;
  line-height: 1.5;
  overflow: hidden;
}
.tt-title {
  background: var(--panel-2);
  border-bottom: 1px solid var(--line);
  padding: 5px 10px;
  text-align: center;
  color: var(--dim);
  font-size: 12px;
}
.tt-body { padding: 12px 14px; }
.tt-name { color: var(--gold); font-weight: 600; font-size: 15px; }
.tt-sub { color: var(--dim); }
.tt-rule { border: 0; border-top: 1px solid var(--line); margin: 10px 0; }

/* Two label/value pairs per row, which is how the client lays it out. */
.tt-grid {
  display: grid;
  grid-template-columns: auto 1fr auto 1fr;
  gap: 2px 10px;
  font-variant-numeric: tabular-nums;
}
.tt-grid .l { color: var(--dim); white-space: nowrap; }
.tt-grid .v { text-align: right; }
.tt-eff { color: #c98bd9; }
.tt-num.up { color: var(--green); }

/* EverQuest's heroic half of a stat line, dimmer than the base so the pair
   reads as one figure and its modifier rather than as two equal numbers. */
.tt-grid .heroic { color: var(--gold); font-size: .9em; }

/* The spell card. Same frame as an item's, with room for the icon beside the
   name — a spell is recognised by its icon in a way an item is not. */
.tt-spell { max-width: 460px; }
.tt-head { display: flex; gap: 11px; align-items: flex-start; }
.tt-head .icon { flex: 0 0 40px; }
/* The game's own sentence, with its numbers filled in. Left at the body's
   text colour rather than dimmed: it is the spell's actual description, not
   an aside about it. */
.tt-desc { font-size: 13px; line-height: 1.5; }


a { color: var(--link); text-decoration: none; }
a:hover { text-decoration: underline; }

header.top {
  background: var(--panel);
  border-bottom: 1px solid var(--line);
  padding: 10px 20px;
  display: flex;
  gap: 18px;
  align-items: center;
  flex-wrap: wrap;
  position: sticky;
  top: 0;
  z-index: 10;
}
header.top .brand { font-weight: 700; letter-spacing: .5px; color: var(--gold); font-size: 17px; }
/* The version switcher. Which game you are in is the page's context, so it
   reads as a control rather than as another link in the menu. */
header.top .versions { display: flex; border: 1px solid var(--line); border-radius: 5px; overflow: hidden; }
header.top .version {
  padding: 5px 12px;
  color: var(--dim);
  font-size: 13px;
  font-weight: 600;
  background: var(--bg);
  white-space: nowrap;
}
header.top .version + .version { border-left: 1px solid var(--line); }
header.top .version:hover { background: var(--panel-2); color: var(--text); text-decoration: none; }
header.top .version.on { background: var(--gold); color: #14161a; }

header.top nav { display: flex; gap: 14px; flex-wrap: wrap; }
header.top nav a { color: var(--dim); }
header.top nav a:hover { color: var(--text); }
/* The search box, and only it. This said `form` back when search was the
   only form in the header; the server picker is a form too, and inherited a
   margin-left:auto that shoved it to the far right and took the section
   links with it — which reads as everything being centred. */
header.top form:not(.servers) { margin-left: auto; display: flex; gap: 6px; }
header.top input[type=search] {
  background: var(--bg);
  border: 1px solid var(--line);
  color: var(--text);
  border-radius: 4px;
  padding: 6px 10px;
  min-width: 260px;
}
header.top button {
  background: var(--panel-2);
  border: 1px solid var(--line);
  color: var(--text);
  border-radius: 4px;
  padding: 6px 12px;
  cursor: pointer;
}
header.top button:hover { background: var(--line); }

main { max-width: var(--page); margin: 0 auto; padding: 22px 20px 60px; }

h1 { font-size: 25px; margin: 0 0 4px; }
h2 { font-size: 17px; margin: 28px 0 10px; padding-bottom: 6px; border-bottom: 1px solid var(--line); }
.sub { color: var(--dim); font-size: 13px; margin: 0 0 18px; }

ul.spells { list-style: none; padding: 0; margin: 14px 0; }
ul.spells li { display: flex; gap: 12px; padding: 10px 0;
               border-top: 1px solid var(--line); }
ul.spells li:last-child { border-bottom: 1px solid var(--line); }
ul.spells .body { min-width: 0; }
ul.spells .name { font-weight: 600; }
ul.spells .desc { margin: 3px 0; font-size: 13px; }
ul.spells .meta { margin: 3px 0 0; }
.spellhead { display: flex; gap: 14px; align-items: center; margin-bottom: 6px; }
/* The game's own sentence about the spell, with its numbers filled in. */
.lead { font-size: 15px; margin: 10px 0 18px; color: var(--text); }
/* The series a quest belongs to, above its own title. Sits tight against the
   h1 so the two read as one heading rather than as a stray line. */
.sub.series { margin: 0 0 2px; text-transform: uppercase; letter-spacing: .08em;
              font-size: 11px; }

table { width: 100%; border-collapse: collapse; font-size: 14px; }
th {
  text-align: left;
  color: var(--dim);
  font-weight: 600;
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: .4px;
  padding: 6px 10px;
  border-bottom: 1px solid var(--line);
}
td { padding: 7px 10px; border-bottom: 1px solid #23262c; vertical-align: top; }
tr:hover td { background: var(--panel); }
td.num, th.num { text-align: right; font-variant-numeric: tabular-nums; }

.wrap { overflow-x: auto; }

/* The front page's version chooser. Each game states what it holds, so the
   choice is informed rather than a coin toss between two names. */
.game-picks { display: flex; gap: 14px; flex-wrap: wrap; margin: 20px 0; }
.game-pick {
  flex: 1 1 300px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 18px 20px;
  color: var(--text);
  display: block;
}
.game-pick:hover { border-color: var(--gold); text-decoration: none; background: var(--panel-2); }
.game-pick .name { font-size: 19px; font-weight: 700; color: var(--gold); margin-bottom: 10px; }
.game-pick .holds { display: flex; gap: 6px 16px; flex-wrap: wrap; color: var(--dim); font-size: 13px; }
.game-pick .holds strong { color: var(--text); font-variant-numeric: tabular-nums; }
.game-pick p { margin: 0 0 10px; font-size: 13px; }

.cards { display: flex; gap: 12px; flex-wrap: wrap; margin: 16px 0 4px; }
.card {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 6px;
  padding: 12px 16px;
  min-width: 130px;
}
.card .n { font-size: 22px; font-weight: 600; font-variant-numeric: tabular-nums; }
.card .l { color: var(--dim); font-size: 12px; text-transform: uppercase; letter-spacing: .4px; }

.floor { color: var(--green); font-variant-numeric: tabular-nums; }

.tag {
  display: inline-block;
  background: var(--panel-2);
  border: 1px solid var(--line);
  border-radius: 3px;
  padding: 1px 6px;
  font-size: 11px;
  color: var(--dim);
  margin-right: 4px;
}
.coin { color: var(--gold); font-variant-numeric: tabular-nums; }

a.tag { text-decoration: none; }
a.tag:hover { background: var(--line); color: var(--text); }
.tag.active { background: var(--link); border-color: var(--link); color: #10131a; font-weight: 600; }

/* Zone loot: grouped by item, expanding to the creatures behind it.
   The header, the flat rows and the summaries share one grid template so the
   columns line up whether or not a row happens to be expandable. */
.loot-head, .loot-row, details.loot > summary, .loot-source {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 110px 90px minmax(0, 1fr);
  gap: 10px;
  align-items: baseline;
  padding: 7px 10px;
}

.loot-head {
  color: var(--dim);
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: .4px;
  font-weight: 600;
  border-bottom: 1px solid var(--line);
}

.loot-row, details.loot { border-bottom: 1px solid #23262c; font-size: 14px; }
.loot-row:hover, details.loot > summary:hover { background: var(--panel); }

details.loot > summary {
  cursor: pointer;
  font-size: 14px;
  list-style: none;
}
/* The default marker sits outside the grid and knocks the columns askew, so
   it is replaced by one drawn on the first cell. */
details.loot > summary::-webkit-details-marker { display: none; }
details.loot > summary > span:first-child::before {
  content: "▸";
  color: var(--faint);
  display: inline-block;
  width: 1em;
  margin-left: -1em;
}
details.loot[open] > summary > span:first-child::before { content: "▾"; }
details.loot[open] > summary { background: var(--panel); }

details.loot > summary .from { color: var(--dim); }
.loot-sources { background: var(--panel); padding: 2px 0 6px; }
.loot-source { font-size: 13px; padding-left: 26px; }
.loot-source + .loot-source { border-top: 1px solid #23262c; }

.num { text-align: right; font-variant-numeric: tabular-nums; }

.grade {
  width: min(460px, 100%);
  margin-top: 12px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 5px;
  padding: 10px 14px;
}
.grade-head { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; }
.grade-head .n { font-weight: 700; color: var(--gold); font-variant-numeric: tabular-nums; }
.grade input[type=range] { width: 100%; margin: 8px 0 2px; accent-color: var(--gold); }
.grade .why { color: var(--faint); font-size: 12px; }

.note {
  background: var(--panel);
  border-left: 3px solid var(--line);
  padding: 10px 14px;
  color: var(--dim);
  font-size: 13px;
  margin: 14px 0;
  border-radius: 0 4px 4px 0;
}
.note strong { color: var(--text); }

.empty { color: var(--faint); padding: 14px 0; font-style: italic; }

/* The footer carries the same things eqrng.com's does — what the site is,
   where else to find it, and whose trademark the whole thing rests on —
   written in this site's own CSS rather than lifted as markup, because that
   one is Tailwind and none of its classes exist here. */
footer {
  max-width: var(--page);
  margin: 0 auto;
  padding: 28px 20px 34px;
  /* --dim, not --faint. The footer used to be one throwaway line and now
     carries a trademark notice; --faint is 3.48:1 on this background, under
     the 4.5 a body text needs, and an unreadable disclaimer is worse than
     no disclaimer. --dim measures 5.85:1. Hierarchy here is size, not
     fading text out until it cannot be read. */
  color: var(--dim);
  font-size: 12px;
  border-top: 1px solid var(--line);
}
.foot-top {
  display: flex; flex-wrap: wrap; gap: 12px 20px;
  align-items: center; justify-content: space-between;
  margin-bottom: 14px;
}
.foot-links { display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 0; }
.foot-links strong { color: var(--text); }
/* Separators drawn by CSS rather than typed between the links, so a link
   that is only sometimes there — the current game — cannot leave a stray
   dot behind it. */
.foot-links > * + *::before { content: "·"; margin: 0 9px; color: var(--line); }
.foot-social { display: flex; flex-wrap: wrap; gap: 13px; }
.foot-social a { color: var(--dim); display: inline-flex; }
.foot-social a:hover, .foot-social a:focus { color: var(--link); }
.foot-bar { border-top: 1px solid var(--line); padding-top: 12px; }
.foot-legal {
  margin: 8px 0 0; max-width: 80ch; font-size: 11px; line-height: 1.5;
}

/* --- Zone maps ------------------------------------------------------------
   The SVG carries no colour of its own: eqmaps classes each contour path l0
   to l5 by elevation and leaves the palette to whoever draws it, which keeps
   the file small and lets the site theme match. Higher ground reads brighter,
   the same depth cue the client's own maps use. */
figure.zonemap {
  margin: 0 0 6px;
  padding: 10px;
  background: #0c0d10;
  border: 1px solid var(--line);
  border-radius: 6px;
  overflow: hidden;
}
figure.zonemap svg { display: block; width: 100%; height: auto; max-height: 70vh; }
figure.zonemap path { fill: none; stroke-width: 1; vector-effect: non-scaling-stroke; }
/* Six stops spread evenly by CONTRAST on the map's black, 4.51 to 11.01,
   measured with eqmaps' own contrast module against its 4.5 line floor.
   Picked by eye first, and four of the six came out below the floor — the
   darkest at 1.68, which is a stroke you cannot see rather than a subtle one.
   Raising them by blending toward white fixed the floor and turned the ramp
   grey, so hue and saturation are held constant (215°, 26%) and only
   lightness moves. That keeps the depth cue, which is the whole reason for a
   ramp: on a 30-layer zone like the Plane of Sky it is what tells one island
   from the one below it. */
.zonemap .l0 { stroke: #5b769b; }
.zonemap .l1 { stroke: #7089ab; }
.zonemap .l2 { stroke: #8298b6; }
.zonemap .l3 { stroke: #93a6c0; }
.zonemap .l4 { stroke: #a1b2c8; }
.zonemap .l5 { stroke: #afbdd0; }

/* Markers. Filled means the site has somewhere to send you; hollow means the
   thing was seen standing there and nothing more is known about it. */
.zonemap .mk circle {
  fill: none;
  stroke-width: 2;
  vector-effect: non-scaling-stroke;
  cursor: default;
}
.zonemap a.mk circle { fill-opacity: .85; cursor: pointer; }
.zonemap .mk-npc   circle { stroke: var(--gold); }
.zonemap a.mk-npc  circle { fill: var(--gold); }
.zonemap .mk-craft circle { stroke: #f2f2f2; }
.zonemap a.mk-craft circle { fill: #f2f2f2; }
.zonemap .mk-zone  circle { stroke: #00d2ff; }
.zonemap a.mk-zone circle { fill: #00d2ff; }
.zonemap a.mk:hover circle,
.zonemap a.mk:focus circle { stroke: #fff; stroke-width: 4; }

/* The under-construction notice. Amber rather than red: this is a caveat
   about coverage, not an error, and a page that shouts on every visit stops
   being read. */
.banner {
  display: flex;
  align-items: baseline;
  gap: 14px;
  max-width: var(--page);
  margin: 0 auto;
  padding: 10px 20px;
  font-size: 13px;
  line-height: 1.5;
  color: var(--text);
  background: #241f13;
  border-bottom: 1px solid #4a3c1d;
}
.banner strong { color: var(--gold); }
.banner button {
  margin-left: auto;
  flex: none;
  font: inherit;
  font-size: 18px;
  line-height: 1;
  padding: 2px 8px;
  color: var(--dim);
  background: none;
  border: 1px solid transparent;
  border-radius: 4px;
  cursor: pointer;
}
.banner button:hover { color: var(--text); border-color: var(--line); }
.banner[hidden] { display: none; }

/* The server picker. A second row under the version switcher, because it is
   the same kind of control one level down: the version says which game, the
   server says which rules that game is being read under. */
/* Inline in the header row, immediately after the version switcher: the
   game, then which of its servers, then where in it you are. It stays on
   that one line and only wraps when the header itself has to. */
.servers {
  display: flex; align-items: center; gap: 8px; flex-wrap: nowrap;
  margin: 0; font-size: 13px;
}
.servers .label {
  color: var(--faint); font-size: 11px; text-transform: uppercase;
  letter-spacing: .5px; font-weight: 600;
}
.servers select {
  font: inherit;
  font-size: 13px;
  padding: 4px 8px;
  max-width: 210px;
  color: var(--text);
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 4px;
}
.servers select:hover { border-color: var(--link); }
.servers select:focus-visible { outline: 2px solid var(--link); }
/* Inside a <noscript>: the only case where a button is needed, because
   changing the dropdown submits on its own everywhere else. */
.servers button.go {
  font: inherit;
  font-size: 13px;
  padding: 4px 10px;
  color: var(--text);
  background: var(--panel-2);
  border: 1px solid var(--line);
  border-radius: 4px;
  cursor: pointer;
}

/* A ⁂ in an option marks a ruleset whose loot tables are shuffled: a drop
   recorded there is evidence about those rules and about nowhere else. An
   option cannot carry its own colour in most browsers, so the mark is the
   character rather than styling. */

figure.zonemap svg { cursor: grab; touch-action: none; }
figure.zonemap.grabbing svg { cursor: grabbing; }

/* Controls. Present in the markup but inert without the script, so the
   zoom bar is written by the page and the elevation list is written by the
   script — a browser running neither still gets the whole static figure. */
.mapctl { display: flex; flex-wrap: wrap; gap: 10px 18px; margin: 8px 0 2px; }
.zoombar { display: flex; align-items: center; gap: 6px; }
.mapctl button {
  font: inherit;
  font-size: 13px;
  min-width: 30px;
  padding: 3px 9px;
  color: var(--text);
  background: var(--panel-2);
  border: 1px solid var(--line);
  border-radius: 4px;
  cursor: pointer;
}
.mapctl button:hover { background: var(--panel); border-color: var(--link); }
.mapctl .hint { color: var(--faint); font-size: 12px; }
.maplayers { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; }
.maplayers[hidden] { display: none; }
.maplayers label {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  font-size: 12px;
  color: var(--dim);
  font-variant-numeric: tabular-nums;
  cursor: pointer;
}
.maplayers input { accent-color: var(--link); margin: 0; }

p.sub.mapkey { display: flex; align-items: center; gap: 5px; flex-wrap: wrap; }
.mapkey .k {
  width: 9px; height: 9px; border-radius: 50%; display: inline-block;
}
.mapkey .k.mk-npc   { background: var(--gold); }
.mapkey .k.mk-craft { background: #f2f2f2; }
.mapkey .k.mk-zone  { background: #00d2ff; }

/* The ruleset glossary on the servers page. A definition list because that
   is what it is: a term and what it means. */
/* A zone list is names, not rows: three or four columns of them reads far
   faster than a table with one cell per line. */
ul.zonelist {
  list-style: none; padding: 0; margin: 14px 0;
  columns: 4 190px; column-gap: 24px; font-size: 14px;
}
ul.zonelist li { padding: 2px 0; break-inside: avoid; }

dl.rulesets { margin: 14px 0; font-size: 14px; }
dl.rulesets dt {
  color: var(--gold); font-weight: 600; margin-top: 12px;
}
dl.rulesets dd { margin: 3px 0 0; color: var(--dim); }

p.sub.spots { margin: -12px 0 18px; }
.spots .loc { font-variant-numeric: tabular-nums; color: var(--faint); }

/* The zone creature table dropped its two count columns: a kill tally is a
   fact about how much somebody ground, not about the zone, and it pushed the
   thing you actually came to read into a narrow third column. */
.loot-head.zone-creatures, .loot-row.zone-creatures,
details.loot > summary.zone-creatures, .loot-source.zone-creatures {
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
}

/* --- Tabs -----------------------------------------------------------------
   Radio driven, so the panels switch with no script. The inputs keep their
   focusability (opacity, not display:none) — that is what gives arrow-key
   movement between tabs for free. */
.tabs > input { position: absolute; opacity: 0; width: 0; height: 0; }
.tabbar {
  display: flex;
  gap: 2px;
  border-bottom: 1px solid var(--line);
  margin: 22px 0 0;
}
.tabbar label {
  padding: 9px 16px;
  cursor: pointer;
  color: var(--dim);
  font-size: 13px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .4px;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  user-select: none;
}
.tabbar label:hover { color: var(--text); }
.tabbar .count {
  margin-left: 7px;
  color: var(--faint);
  font-weight: 400;
  font-variant-numeric: tabular-nums;
}
.tabs > .panel { display: none; padding-top: 14px; }
#zt-creatures:checked ~ .tabbar label[for="zt-creatures"],
#zt-loot:checked ~ .tabbar label[for="zt-loot"] {
  color: var(--text);
  border-bottom-color: var(--link);
}
#zt-creatures:focus-visible ~ .tabbar label[for="zt-creatures"],
#zt-loot:focus-visible ~ .tabbar label[for="zt-loot"] { outline: 2px solid var(--link); }
#zt-creatures:checked ~ .panel-creatures,
#zt-loot:checked ~ .panel-loot { display: block; }
