/* ============================================================
   CONFIG (config.html) — the spec sheet, forged
   Header: the crest portal onto the night canyon, the trike standing
   on a bank of jungle roots in front of it. A section index sticks under the
   nav; a line of light slides under the section being read. Rates are
   a chrome spec pack on a bus that leaves the spine lane (motion.js
   powers it on: pads light, values rise, one sheen). Levels + stat caps
   and settings are boards of facet rows on chrome-capped plates. Quality of
   life sits over the jungle ruins at night and taps the spine item by item; mods
   branch off it like the server rack; commands are panels in columns
   with search beside the heading. Closing band comes from main.js.
   Uses style.css tokens and components only.
   ============================================================ */

:root { --bar-h: 48px; }
@media (min-width: 961px) { :root { --bar-h: 54px; } }
/* in-page jumps land below the nav AND the section index */
html { scroll-padding-top: calc(var(--nav-h) + var(--bar-h) + var(--s-4)); }

/* ---------- header: portal + the trike standing on its ledge ---------- */

.cfg-band { padding-bottom: var(--s-7); }
.cfg-stage { --cast-x: -24%; --cast-y: 1%; --cast-w: 86%; }
/* phones: the stage is centred under the copy, so the trike steps out less and keeps its horns on screen */
@media (max-width: 959.98px) { .cfg-stage { --cast-x: -10%; --cast-w: 80%; } }
/* narrower desktops: the copy column is close to the frame, so the lede stops short and the horns stay nearer
   the flank (32px+ clear) */
@media (min-width: 960px) and (max-width: 1279.98px) {
  .cfg-band .lede { max-width: 30ch; }
  .cfg-stage { --cast-x: -12%; --cast-w: 84%; }
}
/* the lede waits for the load sequence with the rest of the header (open.js arms data-open, motion.js releases it) */
html[data-open] .cfg-band .lede { visibility: hidden; }

/* ---------- section index: sticky under the nav; light slides under the section being read ---------- */

.cfg-index {
  position: sticky;
  top: var(--nav-h);
  z-index: 39;
  background: rgba(10, 18, 48, 0.97);
  box-shadow: inset 0 1px var(--rule), inset 0 -1px var(--rule);
}
.cfg-index ul {
  position: relative;
  display: flex;
  align-items: stretch;
  gap: 2px;
  height: var(--bar-h);
  margin: 0 auto;
  list-style: none;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-padding-inline: 48px; /* a focused link lands clear of the edge fade, ring included */
  scrollbar-width: none;
}
.cfg-index ul::-webkit-scrollbar { display: none; }
/* more sections off to the right (main.js sets .more): the last visible label fades into the bar */
.cfg-index ul.more { -webkit-mask-image: linear-gradient(90deg, #000 calc(100% - 44px), transparent); mask-image: linear-gradient(90deg, #000 calc(100% - 44px), transparent); }
/* the line of light: main.js sets --lx (px) and --lw (the link's width) for the section being read */
.cfg-index ul::after {
  content: "";
  position: absolute;
  left: 0; bottom: 0;
  width: 1px; height: 2px;
  background: var(--trace);
  transform-origin: 0 0;
  transform: translateX(calc(var(--lx, 0px) + 14px)) scaleX(max(0, var(--lw, 0) - 28));
  transition: transform 0.6s var(--ease);
}
.cfg-index li { flex: none; display: flex; }
.cfg-index li:first-child { margin-left: -14px; } /* the first label's text lines up with the column edge */
.cfg-index a {
  display: flex;
  align-items: center;
  padding: 0 14px;
  color: var(--steel);
  font: 500 var(--fs-ui)/1 var(--font-text);
  text-decoration: none;
  white-space: nowrap;
  transition: color var(--dur-ui) var(--ease);
}
.cfg-index a:hover, .cfg-index a[aria-current] { color: var(--chrome); }
/* the bar clips overflow, so the ring sits inside the link */
.cfg-index a:focus-visible { outline-offset: -7px; }

/* short viewports (landscape phones, 200-400% zoom): the index stops sticking so it never eats the screen */
@media (max-height: 520px) {
  html { scroll-padding-top: calc(var(--nav-h) + var(--s-4)); }
  .cfg-index { position: static; }
}

.cfg-nojs { padding-block: var(--s-6); }
.cfg-nojs .notice { max-width: 46rem; margin: 0; }

/* ---------- rates: one forged plate, then a ledger on the trace ----------
   tbody#rates-table keeps tr > th[scope=row] + td (roles restated by the renderer); the value (td) reads
   first, its label (th) after it. The two headline rates (rows 1-2) share ONE wide chrome-capped plate
   (painted by the tbody's ::before, a grid item behind them), split by a facet. Every other rate is a
   ledger row that branches off the spine like a rack row: its pad sits on the trace in the lane, a stub
   carries the light to the row, and its multiplier is a chrome numeral. motion.js powers it on: the bus
   and drops light, each pad in reading order, each value rises through its mask, one sheen on the
   headline pair. .pack: main.js fitPack shrinks --pack-fs until the widest headline value fits. */

/* a long spec page: chapters sit ~40% closer than the site default; the quality-of-life scene keeps its room */
.cfg > .sec:not(.cfg-qol) { padding-block: calc(var(--chapter-pad) * 0.6); }
.cfg > .cfg-rates.sec { padding-top: var(--s-9); }
.spec { position: relative; max-width: 1120px; }
/* the bus: leaves the spine lane above the plate and ends at the second headline pad; a drop feeds each
   headline pad. Lit by motion.js (.spec.lit), lit when static; phones have no lane, so no bus */
.spec::before, .spec::after {
  content: "";
  position: absolute;
  z-index: 3;
  top: -22px;
  left: calc(var(--lane) * -0.5);
  width: calc(var(--lane) * 0.5 + 50% + 35.5px); /* the second headline half starts at 50%; its pad centre is 35px in */
  height: 1px;
  background: var(--facet);
}
.spec::after {
  background: var(--trace);
  transform: scaleX(0);
  transform-origin: 0 50%;
  transition: transform 0.6s var(--ease);
}
#rates-table tr:nth-child(-n + 2) td::before, #rates-table tr:nth-child(-n + 2) td::after {
  content: "";
  position: absolute;
  z-index: 3;
  left: 34.5px;
  top: -22px;
  width: 1px;
  height: 44px; /* from the bus to the top of the pad */
  background: var(--facet);
}
#rates-table tr:nth-child(-n + 2) td::after {
  background: var(--trace);
  transform: scaleY(0);
  transform-origin: 50% 0;
  transition: transform 0.2s var(--ease) 0.06s;
}
#rates-table tr:nth-child(2) td::after { transition-delay: 0.22s; }
.spec.lit::after, html:not(.motion) .spec::after,
.spec.lit #rates-table td::after, html:not(.motion) #rates-table td::after { transform: none; }
@media (max-width: 719.98px) {
  .spec::before, .spec::after, #rates-table td::before, #rates-table td::after { display: none; }
}

table.rates { display: block; border-spacing: 0; }
#rates-table.pack {
  --pack-fs: clamp(3.25rem, 8.6vw, 8.5rem);
  --led-fs: clamp(2.25rem, 1.5rem + 1.9vw, 3.25rem);
  position: relative;
  isolation: isolate;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
#rates-table th, #rates-table td { display: block; min-width: 0; padding: 0; background: none; clip-path: none; }
#rates-table td { order: -1; }
#rates-table .num { display: inline-block; font: inherit; }

/* the headline plate */
#rates-table::before {
  content: "";
  grid-row: 1;
  grid-column: 1 / -1;
  z-index: -1;
  background:
    linear-gradient(90deg, transparent var(--cut-xl), rgba(245, 248, 248, 0.75) var(--cut-xl), rgba(203, 215, 220, 0.25) 58%, transparent 92%) top / 100% 2px no-repeat,
    var(--plate-2);
  clip-path: polygon(var(--cut-xl) 0, 100% 0, 100% calc(100% - var(--cut-xl)), calc(100% - var(--cut-xl)) 100%, 0 100%, 0 var(--cut-xl));
}
#rates-table tr:nth-child(-n + 2) {
  position: relative;
  grid-row: 1;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  gap: 10px;
  min-width: 0;
  min-height: 276px;
  padding: 58px 32px 30px;
}
#rates-table tr:nth-child(1) { grid-column: 1; } /* placed explicitly: the plate (::before) already holds row 1 */
#rates-table tr:nth-child(2) { grid-column: 2; box-shadow: inset 1px 0 var(--rule-strong); }
#rates-table tr:nth-child(-n + 2) .ln-mask { font: 800 var(--pack-fs)/0.92 var(--font-display); font-stretch: 84%; white-space: nowrap; }
#rates-table tr:nth-child(-n + 2) th { font: 600 var(--fs-lede)/1.3 var(--font-text); color: var(--chrome); }
#rates-table tr:nth-child(-n + 2) .pad { --pad: 14px; left: 28px; top: 22px; }

/* the ledger: each rate a row off the spine */
#rates-table tr:nth-child(n + 3) {
  position: relative;
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: calc(var(--led-fs) * 2.9) minmax(0, 1fr); /* 2.9: wide enough for a 4-digit rate (2000×) */
  align-items: center;
  column-gap: var(--s-5);
  min-height: 80px;
  padding: 12px 0;
  box-shadow: inset 0 -1px var(--rule);
}
#rates-table tr:nth-child(3) { margin-top: var(--s-5); }
#rates-table tr:nth-child(n + 3) td { text-align: right; }
#rates-table tr:nth-child(n + 3) .ln-mask { font: 800 var(--led-fs)/0.92 var(--font-display); font-stretch: 84%; white-space: nowrap; }
#rates-table tr:nth-child(n + 3) th { font: 500 var(--fs-body)/1.35 var(--font-text); color: var(--silver); }
#rates-table tr:nth-child(n + 3):hover th { color: var(--chrome); }
#rates-table tr:nth-child(n + 3) .pad { --pad: 12px; left: calc(var(--lane) * -0.5 - var(--pad) / 2); top: calc(50% - var(--pad) / 2); }
/* the stub from the trace to the row (lit with its pad) */
#rates-table tr:nth-child(n + 3)::after {
  content: "";
  position: absolute;
  left: calc(var(--lane) * -0.5);
  top: 50%;
  width: calc(var(--lane) * 0.5 - 8px);
  height: 1px;
  background: var(--trace);
  transform: scaleX(0);
  transform-origin: 0 50%;
  transition: transform var(--dur-ui) var(--ease);
}
#rates-table tr:nth-child(n + 3):has(.pad.lit)::after, html:not(.motion):not([data-open]) #rates-table tr:nth-child(n + 3)::after { transform: scaleX(1); }

/* wide: the ledger fills the plate's width in two columns, read down (main.js sets --led-rows and marks the right
   column .led-2); only the left column's rows branch off the spine, the right column's sit beside them */
@media (min-width: 960px) {
  #rates-table.pack { grid-template-rows: auto repeat(var(--led-rows, 3), auto); grid-auto-flow: column; column-gap: var(--s-7); }
  #rates-table tr:nth-child(n + 3) { grid-column: auto; }
  #rates-table tr.led-2 { grid-column: 2; }
  #rates-table tr:not(.led-2) + tr.led-2 { margin-top: var(--s-5); } /* the right column starts level with the left */
  #rates-table tr.led-2 > td > .pad, #rates-table tr.led-2::after { display: none; }
}
@media (min-width: 640px) and (max-width: 1023.98px) {
  #rates-table tr:nth-child(-n + 2) { min-height: 220px; padding: 50px 22px 24px; }
  #rates-table tr:nth-child(-n + 2) .pad { left: 20px; top: 18px; }
  #rates-table tr:nth-child(-n + 2) th { font-size: var(--fs-body); }
}
/* phones: the headline pair stacks inside its plate; the ledger keeps numeral | label */
@media (max-width: 639.98px) {
  #rates-table.pack { --pack-fs: clamp(3rem, 19vw, 5.5rem); --led-fs: 2.25rem; grid-template-columns: minmax(0, 1fr); }
  #rates-table::before { grid-row: 1 / span 2; }
  #rates-table tr:nth-child(-n + 2) { grid-column: 1; min-height: 0; padding: 40px 20px 22px; }
  #rates-table tr:nth-child(2) { grid-row: 2; box-shadow: inset 0 1px var(--rule-strong); }
  #rates-table tr:nth-child(-n + 2) .pad { left: 18px; top: 18px; }
  #rates-table tr:nth-child(-n + 2) th { font-size: var(--fs-body); }
  #rates-table tr:nth-child(n + 3) { min-height: 68px; column-gap: var(--s-4); }
  #rates-table tr:nth-child(n + 3) th { font-size: var(--fs-ui); }
}

/* ---------- boards: levels in two columns, then stat caps beside settings ----------
   Rows are facet plates (style.css table rows): label left, value right; a numeral reads in Tektur
   with its unit smaller, an on/off word as a switch chip, a note qualifies the value under it. */

.cfg-pair { display: grid; gap: var(--chapter-pad) clamp(40px, 5vw, 88px); }
@media (min-width: 1100px) {
  .cfg-pair { grid-template-columns: repeat(2, minmax(0, 1fr)); align-items: start; }
  /* side by side, the right board has no via on the spine */
  .pad-stacked { display: none; }
}
.cfg-pair .sec-head { margin-bottom: var(--s-6); }

/* each board stands on its own chrome-capped plate (the rates plate's material), its rows inset into it */
.board { position: relative; isolation: isolate; display: block; border-spacing: 0; padding: 18px; }
.board::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background:
    linear-gradient(90deg, transparent var(--cut-l), rgba(245, 248, 248, 0.7) var(--cut-l), rgba(203, 215, 220, 0.22) 60%, transparent 94%) top / 100% 2px no-repeat,
    linear-gradient(180deg, rgba(16, 28, 62, 0.92), rgba(9, 16, 41, 0.92));
  clip-path: polygon(var(--cut-l) 0, 100% 0, 100% calc(100% - var(--cut-l)), calc(100% - var(--cut-l)) 100%, 0 100%, 0 var(--cut-l));
}
.board tbody { display: grid; gap: 6px; }
.board tbody td, .board tbody th { --cell: rgba(3, 6, 26, 0.55); }
.board tbody tr:hover > td, .board tbody tr:hover > th { --cell: var(--hull-2); }
@media (max-width: 719.98px) { .board { padding: 10px; } }
.board tr { display: grid; grid-template-columns: minmax(0, 1fr) auto; min-height: 60px; }
.board th, .board td { display: flex; flex-direction: column; justify-content: center; padding: 13px 20px; }
.board th { font: 500 var(--fs-ui)/1.4 var(--font-text); color: var(--silver); }
.board td { align-items: flex-end; text-align: right; }
.board .v { font: 600 var(--fs-ui)/1.3 var(--font-text); color: var(--chrome); }
.board .v b { font: 800 1.625rem/1 var(--font-display); font-stretch: 86%; font-variant-numeric: tabular-nums lining-nums; color: var(--chrome); }
.board .v .u { font-size: var(--fs-small); font-weight: 500; color: var(--steel); }
.board .note { display: block; max-width: 30ch; margin-top: 5px; font: 400 var(--fs-fine)/1.4 var(--font-text); color: var(--steel); text-wrap: balance; }
.board tr:hover th { color: var(--chrome); }

/* switch chips: a lit diamond for on, a hollow one for off; the word carries the state */
.chip.sw { --chip-edge: transparent; gap: 10px; padding: 0; font-size: var(--fs-ui); }
.chip.sw::before { display: none; }
.sw::after { content: ""; order: -1; flex: none; width: 8px; height: 8px; transform: rotate(45deg); }
.sw-on { --chip-fg: var(--chrome); }
.sw-on::after { background: var(--trace); }
.sw-off { --chip-fg: var(--steel); }
.sw-off::after { box-shadow: inset 0 0 0 1.5px var(--steel); }

/* a flowing board pours its rows down two columns, read down (main.js sets --rows); settings only while it has
   the full width (side by side with stat caps it is one column) */
@media (min-width: 960px) {
  .board-flow tbody { grid-template-columns: repeat(2, minmax(0, 1fr)); grid-template-rows: repeat(var(--rows, 7), auto); grid-auto-flow: column; column-gap: 24px; }
}
@media (min-width: 1100px) {
  .cfg-pair .board-flow tbody { grid-template-columns: minmax(0, 1fr); grid-template-rows: none; grid-auto-flow: row; }
}
@media (max-width: 719.98px) {
  .board th, .board td { padding: 12px 14px; }
  .board .v b { font-size: 1.375rem; }
  .board .note { max-width: 22ch; }
}

/* ---------- quality of life: over the jungle ruins at night; each item taps the spine ---------- */

.cfg-qol { isolation: isolate; overflow: clip; padding-block: var(--s-10); }
.qol-env { z-index: -1; }
/* the ruins stand beside the middle of the list; the plate fades out into the fog below */
.qol-stones { bottom: 14%; }
.qol-stones > img { object-position: 85% 50%; -webkit-mask-image: linear-gradient(180deg, #000 72%, transparent); mask-image: linear-gradient(180deg, #000 72%, transparent); }
.qol-fog { top: auto; height: 56%; }
.qol-fog > img { object-position: 50% 100%; opacity: 0.32; }
.qol-scrim {
  background:
    linear-gradient(180deg, var(--void) 0%, rgba(3, 6, 26, 0.15) 18%, rgba(3, 6, 26, 0.2) 76%, var(--void) 100%),
    linear-gradient(90deg, rgba(3, 6, 26, 0.92) 0%, rgba(3, 6, 26, 0.66) 40%, rgba(3, 6, 26, 0) 72%);
}
.qol { position: relative; display: grid; gap: var(--s-6); max-width: 620px; margin: 0; padding: 0; list-style: none; }
.qol-item { position: relative; padding-left: var(--s-4); }
.qol-item > .pad { --pad: 12px; left: calc(var(--lane) * -0.5 - var(--pad) / 2); top: 8px; }
.qol-item > .stub { top: 14px; width: calc(var(--lane) * 0.5 + 8px); } /* stops just short of the title */
@media (max-width: 719.98px) { .qol-item { padding-left: 0; } }
.qol-item h3 { margin-bottom: 4px; font: 600 1.1875rem/1.35 var(--font-text); color: var(--chrome); }
.qol-item p { margin: 0; max-width: 56ch; color: var(--silver); }
@media (max-width: 959.98px) {
  .qol-scrim { background: linear-gradient(180deg, var(--void) 0%, rgba(3, 6, 26, 0.72) 14%, rgba(3, 6, 26, 0.72) 84%, var(--void) 100%); }
}

/* ---------- mods: a lineup of plates branching off the spine ---------- */

.mod-list { display: grid; gap: 8px; margin: 0; padding: 0; list-style: none; }
.mod {
  --cut: var(--cut-m);
  position: relative;
  isolation: isolate;
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 6fr) auto;
  align-items: center;
  gap: 4px var(--s-6);
  min-height: 76px;
  padding: 12px 24px;
}
.mod::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--plate);
  clip-path: polygon(var(--cut) 0, 100% 0, 100% calc(100% - var(--cut)), calc(100% - var(--cut)) 100%, 0 100%, 0 var(--cut));
  transition: background 0.3s var(--ease);
}
.mod:hover::before { background: var(--plate-2); }
.mod > .pad { --pad: 12px; left: calc(var(--lane) * -0.5 - var(--pad) / 2); top: calc(50% - var(--pad) / 2); }
.mod-name {
  justify-self: start;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
  color: var(--chrome);
  font: 700 1.375rem/1.15 var(--font-display);
  font-stretch: 92%;
  text-decoration: none; /* not running text: the plate and the icon carry the link */
}
.mod-name .icon { width: 16px; height: 16px; color: var(--trace); transition: transform 0.38s var(--ease-press); }
.mod-name:hover { color: #FFFFFF; }
.mod-name:hover .icon { transform: translate(2px, -2px); }
.mod-desc { margin: 0; font-size: var(--fs-ui); color: var(--silver); }
.mod-id { justify-self: end; }
.mod-list > li.notice { max-width: 46rem; }
@media (max-width: 959.98px) {
  .mod { grid-template-columns: minmax(0, 1fr) auto; padding: 10px 18px 14px; }
  .mod-desc { grid-column: 1 / -1; grid-row: 2; }
}
@media (max-width: 479.98px) {
  .mod { grid-template-columns: minmax(0, 1fr); }
  .mod-id { justify-self: start; grid-row: 3; }
}

/* ---------- commands: search + tally beside the heading, every group a panel in columns ----------
   tbody#commands-table keeps tr.cmd-group > th[colspan=2][scope=colgroup] + tr > th[scope=row] + td
   (roles restated by the renderer). Rows are blocks poured into columns; a group header opens its
   panel (top-left chamfer) and its last row (.cmd-end) closes it (bottom-right chamfer). */

.cmd-tools > p { margin-bottom: var(--s-4); }
.cmd-tools label { display: block; margin-bottom: var(--s-2); font-size: var(--fs-small); font-weight: 600; color: var(--chrome); }
.cmd-find { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-3); }
.cmd-find .search { flex: 1 1 15rem; }
.cmd-count { font-variant-numeric: tabular-nums; }
.cmd-empty { max-width: 46rem; margin: 0 0 var(--s-5); }

.cmd-table { display: block; border-spacing: 0; }
.cmd-table thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.cmd-table tbody, .cmd-table tr, .cmd-table th, .cmd-table td { display: block; }
#commands-table { column-gap: 14px; }
@media (min-width: 720px) { #commands-table { columns: 2; } }
@media (min-width: 1280px) { #commands-table { columns: 3; } }
#commands-table tr { position: relative; break-inside: avoid; background: var(--hull); }
#commands-table tr:not(.cmd-end) { break-after: avoid; } /* columns break between groups, not inside one (main.js balanceCommands picks which) */
#commands-table tr > * { padding: 0; background: none; clip-path: none; }
#commands-table tr:not(.cmd-group) { padding: 11px 20px; box-shadow: inset 0 1px var(--rule); transition: background 0.25s var(--ease); }
#commands-table tr:not(.cmd-group):hover { background: var(--hull-2); }
#commands-table tr.cmd-group {
  margin-top: 16px; /* a margin, so it is dropped at the top of a column */
  padding: 16px 20px 12px;
  background: linear-gradient(180deg, rgba(203, 215, 220, 0.18) 0 1px, transparent 1px), var(--hull);
  clip-path: polygon(12px 0, 100% 0, 100% 100%, 0 100%, 0 12px);
}
#commands-table tr:first-child { margin-top: 0; }
#commands-table tr.cmd-end { padding-bottom: 15px; clip-path: polygon(0 0, 100% 0, 100% calc(100% - 12px), calc(100% - 12px) 100%, 0 100%); }
#commands-table tr.cmd-group th {
  display: flex;
  align-items: center;
  gap: 10px;
  font: 700 1.25rem/1.2 var(--font-display);
  font-stretch: 92%;
  color: var(--chrome);
}
#commands-table tr.cmd-group th::before { content: ""; flex: none; width: 7px; height: 7px; transform: rotate(45deg); background: var(--trace); }
#commands-table code { font-size: 0.875rem; font-weight: 500; line-height: 1.5; color: var(--chrome); overflow-wrap: anywhere; }
#commands-table td { margin-top: 2px; font-size: var(--fs-small); line-height: 1.45; color: var(--silver); }
@media (max-width: 719.98px) {
  #commands-table tr:not(.cmd-group) { padding: 10px 16px; }
  #commands-table tr.cmd-group { padding: 14px 16px 10px; }
}

/* ---------- motion-only overscan: layers that drift by depth get room so no edge ever shows ---------- */

html.motion .cfg-band .portal-win > .env-layer { top: -8%; bottom: -8%; }
html.motion .qol-stones { top: -10%; bottom: 4%; }
html.motion .qol-fog { bottom: -6%; }

/* Ascended mods sub-list under the Evolved one */
#asa-mods-title { margin: 48px 0 6px; }
#asa-mods-title + .sec-note { margin: 0 0 18px; }
