/* ==========================================================================
   SpaceFed Forum — modern redesign
   Roots: i_style.css (2005). Hairline frames, hatch texture, cream table
   headers, two-tone rows with a full-row navy hover, #0a649a system blue.
   ========================================================================== */

/* ---------- 1. TOKENS ------------------------------------------------ */

:root {
  /* ---- DARK (default) ---- */
  --bg:            #080b10;
  --bg-deep:       #05070a;
  --panel:         #111820;
  --panel-2:       #161f29;
  --panel-3:       #1b2531;
  --sunken:        #0c1117;

  --line:          #26313d;   /* was #4d4d4d */
  --line-soft:     #1a222c;
  --line-strong:   #35434f;

  --ink:           #c0cad4;   /* was #606060 */
  --ink-dim:       #7e8b98;
  --ink-faint:     #5c6773;
  --ink-strong:    #e9eff5;

  --blue:          #0f6fa8;   /* was #0a649a */
  --blue-hi:       #2c8fd0;
  --blue-deep:     #0b4f78;
  --link:          #52aee4;
  --link-hover:    #8ccdf3;

  --row-head-bg:   #1d2029;
  --row-head-ink:  #e8cf92;   /* the cream #faf2d3, as a label on dark */
  --row-a:         #121a23;   /* was #ddeeff */
  --row-b:         #15202b;   /* was #e6f2ff */
  --row-hover:     #0d3f6e;   /* was #013d72 */
  --row-hover-ink: #ffffff;
  --row-active:    #041018;

  --gold:          #e8cf92;
  --green:         #45b97c;
  --amber:         #d99a3a;
  --red:           #d4574f;
  --violet:        #9a7cd4;

  --hatch:         rgba(255, 255, 255, .022);
  --hatch-size:    7px;
  --glow:          0 0 0 1px rgba(44,143,208,.25), 0 6px 22px -10px rgba(0,0,0,.9);
  --shadow:        0 10px 30px -18px rgba(0,0,0,.95);

  /* nebula wash — the dark answer to pic2.jpg */
  --sky-1: rgba(24, 58, 92, .40);
  --sky-2: rgba(58, 30, 84, .28);
  --sky-3: rgba(10, 60, 70, .22);
  --star:  rgba(255,255,255,.55);
  --star-2: rgba(160,205,255,.40);

  /* ---- geometry ---- */
  --radius:      3px;
  --radius-lg:   5px;
  --shell:       1440px;
  --rail-l:      232px;
  --rail-r:      278px;
  --tab-w:       26px;
  --topbar-h:    54px;
  --row-h:       34px;

  --font: Arial, "Helvetica Neue", Helvetica, "Segoe UI", system-ui, sans-serif;
  --mono: "Cascadia Mono", Consolas, "SF Mono", "Roboto Mono", ui-monospace, monospace;
  /* Text size. EVERY text font-size multiplies by --fs-scale -- write new
     ones as calc(12px * var(--fs-scale)) -- so the reader's size setting
     (A-/A+ in the top bar, forum.js) grows the text without zooming the
     layout. The exceptions are glyphs inside FIXED-size boxes (.av initials,
     .iconbtn, .f-icon, .brand-mark), which would overflow their box. */
  --fs-scale: 1;
  --fs:   calc(13px * var(--fs-scale));
}
:root[data-fs="90"]  { --fs-scale: .9; }
:root[data-fs="115"] { --fs-scale: 1.15; }
:root[data-fs="130"] { --fs-scale: 1.3; }
:root[data-fs="150"] { --fs-scale: 1.5; }

/* ---- LIGHT (a faithful, cleaned-up original) ---- */
:root[data-theme="light"] {
  --bg:            #e8e8e8;
  --bg-deep:       #dcdcdc;
  --panel:         #ffffff;
  --panel-2:       #f6f8fb;
  --panel-3:       #eef3f9;
  --sunken:        #f2f2f2;

  --line:          #4d4d4d;
  --line-soft:     #c8ccd2;
  --line-strong:   #4d4d4d;

  --ink:           #606060;
  --ink-dim:       #7b7b7b;
  --ink-faint:     #999999;
  --ink-strong:    #2f2f2f;

  --blue:          #0a649a;
  --blue-hi:       #0d7cbd;
  --blue-deep:     #013d72;
  --link:          #0645ad;
  --link-hover:    #013d72;

  --row-head-bg:   #faf2d3;
  --row-head-ink:  #6b5c2e;
  --row-a:         #ddeeff;
  --row-b:         #e6f2ff;
  --row-hover:     #013d72;
  --row-hover-ink: #ffffff;
  --row-active:    #000000;

  --gold:          #8a6d1f;
  --green:         #1f7a4a;
  --amber:         #a86b12;
  --red:           #b3312a;
  --violet:        #6a4fae;

  --hatch:         rgba(0, 0, 0, .035);
  --glow:          0 0 0 1px rgba(10,100,154,.22), 0 4px 14px -8px rgba(0,0,0,.35);
  --shadow:        0 6px 18px -14px rgba(0,0,0,.45);

  --sky-1: rgba(150, 150, 150, .30);
  --sky-2: rgba(170, 170, 170, .26);
  --sky-3: rgba(140, 145, 150, .22);
  --star:  rgba(255,255,255,0);
  --star-2: rgba(255,255,255,0);
}

/* ---------- 2. BASE -------------------------------------------------- */

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  min-height: 100vh;
  font: var(--fs)/1.55 var(--font);
  color: var(--ink);
  background-color: var(--bg);
  background-image:
    radial-gradient(1100px 620px at 12% -8%,  var(--sky-1), transparent 62%),
    radial-gradient(900px  560px at 88% 6%,   var(--sky-2), transparent 60%),
    radial-gradient(1300px 700px at 50% 108%, var(--sky-3), transparent 66%);
  background-attachment: fixed;
}

/* starfield — dark only, sits under everything */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 0;
  background-image:
    radial-gradient(1px 1px at 12% 18%,  var(--star),   transparent),
    radial-gradient(1px 1px at 34% 62%,  var(--star-2), transparent),
    radial-gradient(1px 1px at 58% 24%,  var(--star),   transparent),
    radial-gradient(1px 1px at 77% 71%,  var(--star-2), transparent),
    radial-gradient(1px 1px at 91% 36%,  var(--star),   transparent),
    radial-gradient(1px 1px at 22% 84%,  var(--star-2), transparent),
    radial-gradient(1px 1px at 46% 92%,  var(--star),   transparent),
    radial-gradient(1px 1px at 66% 48%,  var(--star-2), transparent),
    radial-gradient(1px 1px at 8%  52%,  var(--star-2), transparent),
    radial-gradient(1px 1px at 84% 12%,  var(--star),   transparent);
  opacity: .9;
}

a { color: var(--link); text-decoration: none; }
a:hover { color: var(--link-hover); text-decoration: underline; }
/* Visited links keep the normal link colour on purpose: a board where every
   read thread turns a different shade reads as damage rather than progress. */
a:visited { color: var(--link); }
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid var(--blue-hi);
  outline-offset: 1px;
  border-radius: 2px;
}

h1, h2, h3, h4 { margin: 0; font-weight: bold; color: var(--ink-strong); line-height: 1.3; }
h1 { font-size: calc(20px * var(--fs-scale)); letter-spacing: .2px; }
h2 { font-size: calc(16px * var(--fs-scale)); }
h3 { font-size: calc(14px * var(--fs-scale)); }
h4 { font-size: calc(13px * var(--fs-scale)); }
p  { margin: 0 0 10px; }
p:last-child { margin-bottom: 0; }
hr { border: 0; border-top: 1px solid var(--line-soft); margin: 14px 0; }
img { max-width: 100%; }

/* the line.gif hatch, rebuilt */
.hatch {
  background-image: repeating-linear-gradient(
    45deg,
    var(--hatch) 0, var(--hatch) 1px,
    transparent 1px, transparent var(--hatch-size)
  );
}

/* ---------- 3. TOP BAR ----------------------------------------------- */

.topbar {
  position: sticky;
  top: 0;
  z-index: 60;
  height: var(--topbar-h);
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 0 16px;
  border-bottom: 1px solid var(--line);
  background: linear-gradient(180deg, var(--panel-2), var(--panel));
  box-shadow: var(--shadow);
}
.topbar::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: -1px;
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--blue-hi), transparent);
  opacity: .55;
}

.brand { display: flex; align-items: center; gap: 10px; text-decoration: none; flex: none; }
.brand:hover { text-decoration: none; }
.brand-mark {
  width: 30px; height: 30px;
  display: grid; place-items: center;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  background: linear-gradient(160deg, var(--blue), var(--blue-deep));
  color: #fff;
  font-size: 15px; font-weight: bold;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.18);
}
.brand-text { display: flex; flex-direction: column; line-height: 1.15; }
.brand-name { color: var(--ink-strong); font-size: calc(14px * var(--fs-scale)); font-weight: bold; letter-spacing: .6px; }
.brand-sub  { color: var(--ink-faint); font-size: calc(10px * var(--fs-scale)); letter-spacing: 1.1px; text-transform: uppercase; }

.topnav { display: flex; gap: 2px; margin-left: 6px; min-width: 0; overflow: hidden; }
.topnav a {
  padding: 6px 11px;
  border: 1px solid transparent;
  border-radius: var(--radius);
  color: var(--ink-dim);
  font-size: calc(12px * var(--fs-scale));
  white-space: nowrap;
}
.topnav a:hover { color: var(--ink-strong); background: var(--panel-3); text-decoration: none; }
.topnav a[aria-current="page"] {
  color: #fff;
  background: var(--blue);
  border-color: var(--line-strong);
}

.topsearch { margin-left: auto; display: flex; align-items: center; gap: 6px; min-width: 0; }
.topsearch .field { width: clamp(130px, 16vw, 210px); min-width: 0; }

.topuser { display: flex; align-items: center; gap: 8px; flex: none; }
.userchip .stack { min-width: 0; }
.userchip b, .userchip .rank { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.userchip {
  display: flex; align-items: center; gap: 8px;
  padding: 4px 9px 4px 4px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--sunken);
  color: var(--ink);
  font-size: calc(12px * var(--fs-scale));
}
.userchip:hover { text-decoration: none; border-color: var(--line-strong); color: var(--ink-strong); }
.userchip b { color: var(--ink-strong); }
.userchip .rank { color: var(--gold); font-size: calc(10px * var(--fs-scale)); letter-spacing: .5px; text-transform: uppercase; }

.iconbtn {
  position: relative;
  width: 30px; height: 30px;
  display: grid; place-items: center;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--sunken);
  color: var(--ink-dim);
  font-size: 13px;
  cursor: pointer;
}
.iconbtn:hover { color: var(--ink-strong); border-color: var(--line-strong); background: var(--panel-3); text-decoration: none; }
.iconbtn .dot {
  position: absolute; top: -5px; right: -5px;
  min-width: 15px; height: 15px; padding: 0 3px;
  display: grid; place-items: center;
  border-radius: 8px;
  background: var(--red);
  color: #fff;
  font-size: 9px; font-weight: bold;
}
button.iconbtn { padding: 0; font-family: var(--font); }
.iconbtn:disabled { opacity: .4; cursor: default; }
.iconbtn:disabled:hover { color: var(--ink-dim); border-color: var(--line); background: var(--sunken); }

/* Text size control: A- / A+ as one joined pair. [hidden] is restated
   because display:inline-flex would otherwise beat the attribute, and the
   control is hidden until forum.js has wired it. */
.fsctl { display: inline-flex; }
.fsctl[hidden] { display: none; }
.fsctl .iconbtn { font-weight: bold; }
.fsctl .iconbtn:first-child { border-top-right-radius: 0; border-bottom-right-radius: 0; }
.fsctl .iconbtn:last-child  { border-top-left-radius: 0; border-bottom-left-radius: 0; margin-left: -1px; }
.fsctl .iconbtn small { font-size: 10px; margin-left: 1px; }

/* ---------- 4. SHELL & SIDE TABS ------------------------------------- */

.shell {
  position: relative;
  z-index: 1;
  max-width: var(--shell);
  margin: 0 auto;
  padding: 16px calc(var(--tab-w) + 14px) 60px;
  display: grid;
  grid-template-columns: var(--rail-l) minmax(0, 1fr) var(--rail-r);
  gap: 14px;
  align-items: start;
}
.shell.no-right { grid-template-columns: var(--rail-l) minmax(0, 1fr); }
.shell.wide     { grid-template-columns: minmax(0, 1fr); }

/* the Menu side tab collapses the left rail */
body.nav-collapsed .shell          { grid-template-columns: minmax(0, 1fr) var(--rail-r); }
body.nav-collapsed .shell.no-right { grid-template-columns: minmax(0, 1fr); }
body.nav-collapsed .sidebar        { display: none; }

/* the menu.gif / game.gif vertical tabs, rebuilt in CSS */
.sidetab {
  position: fixed;
  top: 120px;
  z-index: 50;
  width: var(--tab-w);
  padding: 16px 0;
  display: grid;
  place-items: center;
  border: 1px solid var(--line);
  background: linear-gradient(180deg, var(--panel-2), var(--panel));
  color: var(--ink-dim);
  font-size: calc(10px * var(--fs-scale));
  letter-spacing: 2px;
  text-transform: uppercase;
  writing-mode: vertical-rl;
  cursor: pointer;
}
.sidetab:hover { color: var(--ink-strong); border-color: var(--line-strong); text-decoration: none; }
.sidetab-menu { left: 0;  border-left: 0;  border-radius: 0 var(--radius) var(--radius) 0; }
.sidetab-game {
  right: 0; border-right: 0; border-radius: var(--radius) 0 0 var(--radius);
  background: linear-gradient(180deg, var(--blue-deep), #071a2b);
  border-color: var(--blue);
  color: #7fdcff;
}
:root[data-theme="light"] .sidetab-game { background: var(--blue-deep); color: #8fe3ff; }
.sidetab-game:hover { color: #cdf3ff; }

/* ---------- 5. PANELS ------------------------------------------------ */

.panel {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background-color: var(--panel);
  background-image: repeating-linear-gradient(
    45deg, var(--hatch) 0, var(--hatch) 1px, transparent 1px, transparent var(--hatch-size)
  );
  box-shadow: var(--shadow);
  margin-bottom: 14px;
}
.panel:last-child { margin-bottom: 0; }

.panel-head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 12px;
  border-bottom: 1px solid var(--line);
  background: var(--row-head-bg);
  color: var(--row-head-ink);
  border-radius: var(--radius) var(--radius) 0 0;
}
.panel-head h2, .panel-head h3 {
  font-size: calc(12px * var(--fs-scale));
  letter-spacing: 1px;
  text-transform: uppercase;
  color: inherit;
}
.panel-head .spacer { margin-left: auto; }
.panel-head .count { color: inherit; opacity: .7; font-size: calc(11px * var(--fs-scale)); }

.panel-body { padding: 12px; }
.panel-body.tight { padding: 0; }
.panel-foot {
  display: flex; align-items: center; gap: 8px;
  padding: 7px 12px;
  border-top: 1px solid var(--line);
  background: var(--sunken);
  color: var(--ink-faint);
  font-size: calc(11px * var(--fs-scale));
  border-radius: 0 0 var(--radius) var(--radius);
}

/* ---------- 6. SIDEBAR ----------------------------------------------- */

.sidebar { position: sticky; top: calc(var(--topbar-h) + 16px); }
.sidebar .panel { margin-bottom: 12px; }

.navlist { list-style: none; margin: 0; padding: 4px; }
.navlist li { margin: 0; }
.navlist a {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 8px;
  border-radius: 2px;
  border-left: 2px solid transparent;
  color: var(--ink);
  font-size: calc(12px * var(--fs-scale));
}
.navlist a:hover { background: var(--panel-3); color: var(--ink-strong); text-decoration: none; }
.navlist a[aria-current="page"] {
  background: var(--panel-3);
  border-left-color: var(--blue-hi);
  color: var(--ink-strong);
  font-weight: bold;
}
.navlist .glyph { width: 15px; text-align: center; color: var(--ink-faint); font-size: calc(12px * var(--fs-scale)); }
.navlist a:hover .glyph, .navlist a[aria-current="page"] .glyph { color: var(--blue-hi); }
.navlist .tail { margin-left: auto; color: var(--ink-faint); font-size: calc(10px * var(--fs-scale)); font-family: var(--mono); }
.navlist .tail.new { color: var(--gold); }

.navgroup {
  padding: 9px 10px 4px;
  color: var(--ink-faint);
  font-size: calc(10px * var(--fs-scale));
  letter-spacing: 1.2px;
  text-transform: uppercase;
}

/* ---------- 7. TABLES (the heart of the old board) -------------------- */

.tbl-wrap { overflow-x: auto; }

table.tbl {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0 1px;   /* the #818181 "gutter" of .table_back, modernised */
  font-size: calc(12.5px * var(--fs-scale));
}
table.tbl th {
  padding: 7px 10px;
  background: var(--row-head-bg);
  color: var(--row-head-ink);
  font-size: calc(11px * var(--fs-scale));
  font-weight: bold;
  letter-spacing: .7px;
  text-transform: uppercase;
  text-align: left;
  white-space: nowrap;
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}
table.tbl td {
  padding: 8px 10px;
  height: var(--row-h);
  vertical-align: middle;
  border-top: 1px solid var(--line-soft);
  border-bottom: 1px solid var(--line-soft);
}
table.tbl tbody tr             { background: var(--row-a); }
table.tbl tbody tr:nth-child(even) { background: var(--row-b); }

/* full-row hover — .table_rowon1 lives on */
table.tbl tbody tr.rowlink { cursor: pointer; }
table.tbl tbody tr.rowlink:hover,
table.tbl tbody tr.rowlink:focus-within {
  background: var(--row-hover);
  color: var(--row-hover-ink);
}
table.tbl tbody tr.rowlink:hover a,
table.tbl tbody tr.rowlink:hover .muted,
table.tbl tbody tr.rowlink:hover .num,
table.tbl tbody tr.rowlink:focus-within a { color: var(--row-hover-ink); }
table.tbl tbody tr.rowlink:active { background: var(--row-active); color: #fff; }

/* Qualified with table.tbl so they beat `table.tbl th`, which sets
   text-align:left. Unqualified, a `th.mid` lost to it and the header sat left
   over centred cells -- visible as a crooked column on the ticket queue. */
table.tbl td.num, table.tbl th.num,
td.num, th.num { text-align: right; font-family: var(--mono); font-size: calc(11.5px * var(--fs-scale)); color: var(--ink-dim); white-space: nowrap; }
table.tbl td.mid, table.tbl th.mid,
td.mid, th.mid { text-align: center; }
td.nowrap, th.nowrap { white-space: nowrap; }
.w-1  { width: 1%; }
.w-30 { width: 30%; }
.w-45 { width: 45%; }

.muted    { color: var(--ink-dim); }
.faint    { color: var(--ink-faint); }
.strong   { color: var(--ink-strong); }
.small    { font-size: calc(11px * var(--fs-scale)); }
.tiny     { font-size: calc(10px * var(--fs-scale)); letter-spacing: .4px; }
.mono     { font-family: var(--mono); }
.right    { text-align: right; }
.center   { text-align: center; }
.stack    { display: flex; flex-direction: column; gap: 1px; }
.row      { display: flex; align-items: center; gap: 8px; }
.row.wrap { flex-wrap: wrap; }
.spacer   { margin-left: auto; }

/* ---------- 8. FORUM / THREAD ROW ------------------------------------ */

.f-title { display: flex; align-items: baseline; gap: 7px; flex-wrap: wrap; }
.f-title a { font-size: calc(13px * var(--fs-scale)); font-weight: bold; }
.f-desc { color: var(--ink-dim); font-size: calc(11.5px * var(--fs-scale)); margin-top: 2px; }
.f-subs { margin-top: 4px; font-size: calc(11px * var(--fs-scale)); color: var(--ink-faint); }
.f-subs a { color: var(--ink-dim); }
.f-subs a:hover { color: var(--link-hover); }

.f-icon {
  width: 34px; height: 34px;
  display: grid; place-items: center;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--sunken);
  color: var(--ink-faint);
  font-size: 15px;   /* fixed box: not scaled */
  flex: none;
}
.f-icon.unread { border-color: var(--blue-hi); color: var(--blue-hi); box-shadow: inset 0 0 12px -4px var(--blue-hi); }
.f-icon.locked { color: var(--ink-faint); opacity: .6; }

.lastpost { font-size: calc(11px * var(--fs-scale)); line-height: 1.45; }
.lastpost .t { color: var(--ink); display: block; max-width: 190px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lastpost .m { color: var(--ink-faint); }

/* ---------- 9. BADGES / TAGS / PILLS --------------------------------- */

.tag {
  display: inline-block;
  padding: 1px 6px;
  border: 1px solid var(--line);
  border-radius: 2px;
  background: var(--sunken);
  color: var(--ink-dim);
  font-size: calc(10px * var(--fs-scale));
  font-weight: bold;
  letter-spacing: .6px;
  text-transform: uppercase;
  white-space: nowrap;
  vertical-align: middle;
}
.tag.blue   { color: var(--blue-hi); border-color: var(--blue); }
.tag.gold   { color: var(--gold);    border-color: var(--gold); }
.tag.green  { color: var(--green);   border-color: var(--green); }
.tag.red    { color: var(--red);     border-color: var(--red); }
.tag.amber  { color: var(--amber);   border-color: var(--amber); }
.tag.violet { color: var(--violet);  border-color: var(--violet); }
.tag.solid  { background: var(--blue); color: #fff; border-color: var(--blue-deep); }

.dotstat { display: inline-block; width: 7px; height: 7px; border-radius: 50%; background: var(--ink-faint); flex: none; }
.dotstat.on  { background: var(--green); box-shadow: 0 0 6px var(--green); }
.dotstat.off { background: var(--ink-faint); }

/* ---------- 10. AVATARS ---------------------------------------------- */

.av {
  display: grid; place-items: center;
  width: 34px; height: 34px;
  flex: none;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: linear-gradient(155deg, var(--panel-3), var(--sunken));
  color: var(--ink-strong);
  font-weight: bold;
  font-size: 13px;
  letter-spacing: .5px;
  text-transform: uppercase;
  overflow: hidden;
}
.av.xs { width: 22px; height: 22px; font-size: 10px; }
.av.sm { width: 28px; height: 28px; font-size: 11px; }
.av.lg { width: 56px; height: 56px; font-size: 20px; border-radius: var(--radius-lg); }
.av.xl { width: 92px; height: 92px; font-size: 32px; border-radius: var(--radius-lg); }
.av.a1 { background: linear-gradient(155deg, #1b4f7a, #0b2439); color: #a8d8f5; }
.av.a2 { background: linear-gradient(155deg, #57371f, #26170c); color: #f0c79a; }
.av.a3 { background: linear-gradient(155deg, #1f5340, #0c241b); color: #9de6c4; }
.av.a4 { background: linear-gradient(155deg, #472060, #1e0d2b); color: #d5b3f2; }
.av.a5 { background: linear-gradient(155deg, #5c2331, #260d13); color: #f3aab8; }
.av.a6 { background: linear-gradient(155deg, #4a4520, #1f1c0b); color: #ecdf9c; }

/* ---------- 11. BUTTONS & FORMS (from .navtop) ----------------------- */

.btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 13px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: linear-gradient(180deg, var(--panel-3), var(--sunken));
  color: var(--ink);
  font: bold calc(12px * var(--fs-scale))/1 var(--font);
  cursor: pointer;
  white-space: nowrap;
  text-decoration: none;
}
.btn:hover { color: var(--ink-strong); border-color: var(--line-strong); text-decoration: none; background: var(--panel-3); }
.btn:active { transform: translateY(1px); }
.btn.primary {
  background: linear-gradient(180deg, var(--blue-hi), var(--blue));
  border-color: var(--blue-deep);
  color: #fff;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.2);
}
.btn.primary:hover { background: var(--blue-hi); color: #fff; }
.btn.danger { color: var(--red); border-color: var(--red); }
.btn.danger:hover { background: var(--red); color: #fff; border-color: var(--red); }
.btn.ghost { background: transparent; }
.btn.sm { padding: 4px 9px; font-size: calc(11px * var(--fs-scale)); }
.btn.lg { padding: 9px 18px; font-size: calc(13px * var(--fs-scale)); }
.btn.block { width: 100%; justify-content: center; }
.btn[disabled], .btn.disabled { opacity: .45; pointer-events: none; }

.btnbar { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }

.field {
  padding: 6px 9px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--sunken);
  color: var(--ink-strong);
  font: calc(12px * var(--fs-scale))/1.4 var(--font);
}
.field::placeholder { color: var(--ink-faint); }
.field:focus { border-color: var(--blue-hi); background: var(--panel); }
select.field { cursor: pointer; }
textarea.field { width: 100%; resize: vertical; min-height: 150px; line-height: 1.6; font-size: calc(13px * var(--fs-scale)); }
.field.block { width: 100%; }
/* A list's filter box. Width lives here rather than in an inline style on each
   page so the phone rules below can widen it -- an inline width cannot be
   overridden by a media query without !important. */
.field.filter { max-width: 200px; }

.formrow { display: grid; grid-template-columns: 130px minmax(0,1fr); gap: 10px; align-items: start; padding: 10px 0; border-bottom: 1px solid var(--line-soft); }
.formrow:last-of-type { border-bottom: 0; }
.formrow > label { padding-top: 6px; color: var(--ink-dim); font-size: calc(12px * var(--fs-scale)); font-weight: bold; text-align: right; }
.formhint { color: var(--ink-faint); font-size: calc(11px * var(--fs-scale)); margin-top: 4px; }
.check { display: inline-flex; align-items: center; gap: 6px; font-size: calc(12px * var(--fs-scale)); color: var(--ink); cursor: pointer; }

/* editor toolbar */
.toolbar {
  display: flex; gap: 2px; flex-wrap: wrap;
  padding: 5px;
  border: 1px solid var(--line);
  border-bottom: 0;
  border-radius: var(--radius) var(--radius) 0 0;
  background: var(--panel-2);
}
.toolbar .tb {
  min-width: 26px; height: 24px; padding: 0 7px;
  display: grid; place-items: center;
  border: 1px solid transparent;
  border-radius: 2px;
  background: transparent;
  color: var(--ink-dim);
  font-size: calc(12px * var(--fs-scale));
  cursor: pointer;
}
.toolbar .tb:hover { background: var(--panel-3); color: var(--ink-strong); border-color: var(--line); }
.toolbar .sep { width: 1px; margin: 3px 4px; background: var(--line); }
.toolbar + textarea.field { border-radius: 0 0 var(--radius) var(--radius); }

/* ---------- 12. BREADCRUMB / TOOLROW --------------------------------- */

.crumbs {
  display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
  margin-bottom: 12px;
  padding: 7px 11px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--panel);
  font-size: calc(11.5px * var(--fs-scale));
  color: var(--ink-faint);
}
.crumbs a { color: var(--ink-dim); }
.crumbs a:hover { color: var(--link-hover); }
.crumbs .sep { color: var(--ink-faint); opacity: .6; }
.crumbs .here { color: var(--ink-strong); font-weight: bold; }

.pagehead { display: flex; align-items: flex-end; gap: 12px; flex-wrap: wrap; margin-bottom: 12px; }
.pagehead .sub { color: var(--ink-dim); font-size: calc(12px * var(--fs-scale)); margin-top: 3px; }

.toolrow {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin-bottom: 12px;
}

/* ---------- 13. POSTS ------------------------------------------------ */

.post {
  display: grid;
  grid-template-columns: 190px minmax(0, 1fr);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background-color: var(--panel);
  background-image: repeating-linear-gradient(45deg, var(--hatch) 0, var(--hatch) 1px, transparent 1px, transparent var(--hatch-size));
  margin-bottom: 10px;
  overflow: hidden;
}
.post.op { border-color: var(--blue); box-shadow: var(--glow); }
.post.staff { border-left: 3px solid var(--gold); }

/* The original poster, wherever they post in their own thread. The same
   signal most boards use -- an "OP" pill beside the name (Reddit, Discourse),
   a "thread starter" label (XenForo) -- plus a blue accent down the author
   column. Drawn with an inset shadow, not a border, so it never fights the
   gold staff border when the thread starter is also staff. */
.optag {
  display: inline-block; margin-left: 5px; padding: 0 5px;
  border: 1px solid var(--blue); border-radius: 3px;
  background: rgba(59, 158, 206, .14); color: var(--blue-hi);
  font-size: calc(9.5px * var(--fs-scale)); font-weight: bold; letter-spacing: .6px; line-height: 15px;
  vertical-align: 1px;
}
.post.is-op .post-aside { box-shadow: inset 3px 0 0 var(--blue); }
.post.is-op .post-aside .name a { color: var(--blue-hi); }

.post-aside {
  padding: 12px;
  border-right: 1px solid var(--line);
  background: var(--sunken);
  text-align: center;
}
.post-aside .name { display: block; margin-top: 7px; font-weight: bold; font-size: calc(13px * var(--fs-scale)); }
.post-aside .rank { margin-top: 2px; font-size: calc(10px * var(--fs-scale)); letter-spacing: .8px; text-transform: uppercase; color: var(--gold); }
.post-aside .av { margin: 0 auto; }
.post-aside dl { margin: 10px 0 0; padding-top: 9px; border-top: 1px solid var(--line-soft); display: grid; grid-template-columns: auto auto; gap: 2px 8px; font-size: calc(10.5px * var(--fs-scale)); text-align: left; }
.post-aside dt { color: var(--ink-faint); }
.post-aside dd { margin: 0; text-align: right; color: var(--ink-dim); font-family: var(--mono); }

.post-main { display: flex; flex-direction: column; min-width: 0; }
.post-meta {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 7px 12px;
  border-bottom: 1px solid var(--line-soft);
  background: var(--panel-2);
  font-size: calc(11px * var(--fs-scale));
  color: var(--ink-faint);
}
.post-meta .permalink { font-family: var(--mono); }
.post-body { padding: 14px 14px 16px; font-size: calc(13px * var(--fs-scale)); line-height: 1.68; flex: 1; }
.post-body p { margin: 0 0 11px; }
.post-body ul, .post-body ol { margin: 0 0 11px; padding-left: 22px; }
.post-body li { margin-bottom: 3px; }

.quote {
  margin: 0 0 12px;
  border: 1px solid var(--line);
  border-left: 3px solid var(--blue-hi);
  border-radius: 2px;
  background: var(--sunken);
}
.quote .qh { padding: 5px 10px; border-bottom: 1px solid var(--line-soft); color: var(--ink-faint); font-size: calc(11px * var(--fs-scale)); }
.quote .qh b { color: var(--ink-dim); }
.quote .qb { padding: 9px 11px; color: var(--ink-dim); font-size: calc(12.5px * var(--fs-scale)); }

.codeblock {
  margin: 0 0 12px;
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-radius: 2px;
  background: var(--bg-deep);
  color: var(--ink);
  font: calc(12px * var(--fs-scale))/1.6 var(--mono);
  white-space: pre;
  overflow-x: auto;
}
:root[data-theme="light"] .codeblock { background: #f4f4f4; }

.sig {
  margin: 14px 0 0;
  padding-top: 9px;
  border-top: 1px solid var(--line-soft);
  color: var(--ink-faint);
  font-size: calc(11px * var(--fs-scale));
  font-style: italic;
}

.post-foot {
  display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
  padding: 6px 12px;
  border-top: 1px solid var(--line-soft);
  background: var(--panel-2);
}
.react {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px 8px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--sunken);
  color: var(--ink-dim);
  font-size: calc(11px * var(--fs-scale));
  cursor: pointer;
}
.react:hover { border-color: var(--blue-hi); color: var(--ink-strong); text-decoration: none; }
.react.on { border-color: var(--blue-hi); color: var(--blue-hi); background: rgba(44,143,208,.10); }
.post-foot .lnk { color: var(--ink-faint); font-size: calc(11px * var(--fs-scale)); }
.post-foot .lnk:hover { color: var(--link-hover); }

/* ---------- 14. PAGINATION ------------------------------------------- */

.pager { display: flex; align-items: center; gap: 4px; flex-wrap: wrap; }
.pager a, .pager span {
  min-width: 28px; height: 26px;
  display: inline-flex; align-items: center; justify-content: center;
  padding: 0 8px;
  border: 1px solid var(--line);
  border-radius: 2px;
  background: var(--sunken);
  color: var(--ink-dim);
  font-size: calc(11.5px * var(--fs-scale));
  font-family: var(--mono);
}
.pager a:hover { border-color: var(--blue-hi); color: var(--ink-strong); background: var(--panel-3); text-decoration: none; }
.pager .cur { background: var(--blue); border-color: var(--blue-deep); color: #fff; font-weight: bold; }
.pager .gap { border: 0; background: none; color: var(--ink-faint); min-width: 16px; padding: 0 2px; }

/* ---------- 15. STAT RAIL -------------------------------------------- */

.rail { position: sticky; top: calc(var(--topbar-h) + 16px); }
.rail .panel { margin-bottom: 12px; }

.statgrid { display: grid; grid-template-columns: 1fr 1fr; gap: 1px; background: var(--line-soft); }
.statgrid div { padding: 9px 10px; background: var(--panel); }
.statgrid .k { display: block; color: var(--ink-faint); font-size: calc(10px * var(--fs-scale)); letter-spacing: .8px; text-transform: uppercase; }
.statgrid .v { display: block; margin-top: 2px; color: var(--ink-strong); font-size: calc(16px * var(--fs-scale)); font-family: var(--mono); }
.statgrid .v.up { color: var(--green); }

.userlist { display: flex; flex-wrap: wrap; gap: 5px; }
.userlist a { font-size: calc(11.5px * var(--fs-scale)); }
.userlist .staff { color: var(--gold); font-weight: bold; }
.userlist .mod   { color: var(--green); font-weight: bold; }

.minilist { list-style: none; margin: 0; padding: 0; }
.minilist li { display: flex; gap: 8px; padding: 8px 12px; border-bottom: 1px solid var(--line-soft); }
.minilist li:last-child { border-bottom: 0; }
.minilist li:hover { background: var(--panel-2); }
.minilist .t { display: block; font-size: calc(12px * var(--fs-scale)); margin-bottom: 1px; }
.minilist .m { color: var(--ink-faint); font-size: calc(10.5px * var(--fs-scale)); }

.bar { height: 5px; border-radius: 3px; background: var(--sunken); border: 1px solid var(--line-soft); overflow: hidden; }
.bar > i { display: block; height: 100%; background: linear-gradient(90deg, var(--blue), var(--blue-hi)); }

/* ---------- 16. NOTICES ---------------------------------------------- */

.notice {
  display: flex; gap: 10px; align-items: flex-start;
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-left: 3px solid var(--blue-hi);
  border-radius: var(--radius);
  background: var(--panel-2);
  font-size: calc(12px * var(--fs-scale));
  margin-bottom: 12px;
}
.notice .ico { font-size: calc(14px * var(--fs-scale)); line-height: 1.3; }
.notice.warn   { border-left-color: var(--amber); }
.notice.danger { border-left-color: var(--red); }
.notice.good   { border-left-color: var(--green); }
.notice b { color: var(--ink-strong); }

.empty { padding: 44px 20px; text-align: center; color: var(--ink-faint); }
.empty .big { font-size: calc(26px * var(--fs-scale)); margin-bottom: 8px; opacity: .5; }

/* ---------- 17. FOOTER ----------------------------------------------- */

.foot {
  position: relative;
  z-index: 1;
  max-width: var(--shell);
  margin: 0 auto;
  padding: 18px calc(var(--tab-w) + 14px) 40px;
  border-top: 1px solid var(--line-soft);
  display: flex;
  align-items: flex-start;
  gap: 18px;
  flex-wrap: wrap;
  color: var(--ink-faint);
  font-size: calc(11px * var(--fs-scale));
}
.foot a { color: var(--ink-dim); }
.foot .cols { display: flex; gap: 34px; flex-wrap: wrap; }
.foot .col { display: flex; flex-direction: column; gap: 4px; }
.foot .col b { color: var(--ink-dim); font-size: calc(10px * var(--fs-scale)); letter-spacing: 1px; text-transform: uppercase; margin-bottom: 3px; }
.foot .ver { margin-left: auto; text-align: right; font-family: var(--mono); line-height: 1.7; }

/* ---------- 18. PAGE-SPECIFIC ---------------------------------------- */

/* profile */
.profile-hero {
  display: flex; gap: 16px; align-items: center; flex-wrap: wrap;
  padding: 16px;
  border-bottom: 1px solid var(--line);
  background: linear-gradient(120deg, var(--panel-3), var(--panel));
}
.profile-hero .who h1 { font-size: calc(22px * var(--fs-scale)); }
.profile-hero .meta { color: var(--ink-dim); font-size: calc(12px * var(--fs-scale)); margin-top: 4px; }

.tabs { display: flex; gap: 2px; border-bottom: 1px solid var(--line); padding: 0 8px; background: var(--panel-2); }
.tabs a {
  padding: 8px 13px;
  border: 1px solid transparent;
  border-bottom: 0;
  border-radius: var(--radius) var(--radius) 0 0;
  color: var(--ink-dim);
  font-size: calc(12px * var(--fs-scale));
  margin-bottom: -1px;
}
.tabs a:hover { color: var(--ink-strong); text-decoration: none; }
.tabs a.on { background: var(--panel); border-color: var(--line); color: var(--ink-strong); font-weight: bold; }

.kv { display: grid; grid-template-columns: 128px minmax(0,1fr); gap: 7px 12px; font-size: calc(12px * var(--fs-scale)); }
.kv dt { color: var(--ink-faint); }
.kv dd { margin: 0; color: var(--ink); }

/* member cards */
.cardgrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); gap: 10px; }
.mcard {
  display: flex; gap: 10px; align-items: flex-start;
  padding: 11px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--panel-2);
}
.mcard:hover { border-color: var(--blue-hi); }
/* Avatar on the left, everything else stacked in ONE column beside it. Without
   the wrapper each line becomes its own flex item and gets squeezed into a
   narrow column of its own. min-width:0 lets long names wrap, not overflow. */
.mcard-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.mcard .n { display: block; font-weight: bold; font-size: calc(13px * var(--fs-scale)); overflow-wrap: anywhere; }
.mcard .s.seen { display: flex; align-items: center; gap: 6px; }
.mcard .r { color: var(--gold); font-size: calc(10px * var(--fs-scale)); letter-spacing: .6px; text-transform: uppercase; }
.mcard .s { color: var(--ink-faint); font-size: calc(11px * var(--fs-scale)); margin-top: 4px; font-family: var(--mono); }

/* messages / notifications */
.msglist { list-style: none; margin: 0; padding: 0; }
.msglist li {
  display: flex; gap: 11px; align-items: flex-start;
  padding: 11px 13px;
  border-bottom: 1px solid var(--line-soft);
  cursor: pointer;
}
.msglist li:hover { background: var(--panel-2); }
.msglist li.unread { background: var(--row-b); border-left: 3px solid var(--blue-hi); padding-left: 10px; }
.msglist li.unread .subj { color: var(--ink-strong); font-weight: bold; }
.msglist .subj { font-size: calc(12.5px * var(--fs-scale)); }
.msglist .prev { color: var(--ink-faint); font-size: calc(11.5px * var(--fs-scale)); margin-top: 2px; display: -webkit-box; -webkit-line-clamp: 1; -webkit-box-orient: vertical; overflow: hidden; }
.msglist .when { margin-left: auto; color: var(--ink-faint); font-size: calc(10.5px * var(--fs-scale)); white-space: nowrap; font-family: var(--mono); }

/* rules */
.prose { font-size: calc(13px * var(--fs-scale)); line-height: 1.75; max-width: 78ch; }
.prose h2 { margin: 22px 0 8px; padding-bottom: 5px; border-bottom: 1px solid var(--line-soft); font-size: calc(15px * var(--fs-scale)); }
.prose h2:first-child { margin-top: 0; }
.prose h3 { margin: 16px 0 6px; font-size: calc(13px * var(--fs-scale)); color: var(--gold); }
.prose ol, .prose ul { padding-left: 22px; margin: 0 0 12px; }
.prose li { margin-bottom: 6px; }
.prose .lead { color: var(--ink-strong); font-size: calc(14px * var(--fs-scale)); }

/* login */
.authwrap { max-width: 400px; margin: 46px auto; }
.authwrap .panel-body { padding: 18px; }
.authwrap .brandbig { text-align: center; margin-bottom: 16px; }
.authwrap .brandbig .m {
  width: 52px; height: 52px; margin: 0 auto 9px;
  display: grid; place-items: center;
  border: 1px solid var(--line-strong); border-radius: var(--radius-lg);
  background: linear-gradient(160deg, var(--blue), var(--blue-deep));
  color: #fff; font-size: 24px; font-weight: bold;   /* fixed box: not scaled */
}

/* styleguide */
.swatches { display: grid; grid-template-columns: repeat(auto-fill, minmax(148px, 1fr)); gap: 8px; }
.sw { border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; }
.sw .chip { height: 46px; }
.sw .lbl { padding: 5px 7px; background: var(--panel-2); font-size: 10.5px; }
.sw .lbl b { display: block; color: var(--ink-strong); }
.sw .lbl code { color: var(--ink-faint); font-family: var(--mono); font-size: 10px; }
.demo-row { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; padding: 10px 0; border-bottom: 1px dashed var(--line-soft); }
.demo-row:last-child { border-bottom: 0; }
.demo-row .lab { width: 118px; flex: none; color: var(--ink-faint); font-size: calc(11px * var(--fs-scale)); }

/* delete confirm */
.confirmbox { max-width: 520px; margin: 34px auto; text-align: center; }
.confirmbox .big { font-size: calc(34px * var(--fs-scale)); color: var(--red); margin-bottom: 10px; }
.confirmbox h1 { margin-bottom: 8px; }
.confirmbox .btnbar { justify-content: center; margin-top: 18px; }

/* search */
.hit { padding: 12px 13px; border-bottom: 1px solid var(--line-soft); }
.hit:hover { background: var(--panel-2); }
.hit:last-child { border-bottom: 0; }
.hit .h { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.hit .h a { font-size: calc(13.5px * var(--fs-scale)); font-weight: bold; }
.hit .where { color: var(--ink-faint); font-size: calc(11px * var(--fs-scale)); margin-top: 3px; }
.hit .snip { margin-top: 6px; font-size: calc(12px * var(--fs-scale)); color: var(--ink-dim); line-height: 1.6; }
.hit mark { background: rgba(232,207,146,.20); color: var(--gold); padding: 0 2px; border-radius: 2px; }
:root[data-theme="light"] .hit mark { background: #faf2d3; color: #6b5c2e; }

/* ---------- 19. RESPONSIVE ------------------------------------------- */

@media (max-width: 1280px) {
  .shell, body.nav-collapsed .shell { grid-template-columns: var(--rail-l) minmax(0, 1fr); }
  body.nav-collapsed .shell { grid-template-columns: minmax(0, 1fr); }
  .rail { display: none; }
}
@media (max-width: 1180px) {
  .topnav { display: none; }   /* the sidebar carries every link */
}
@media (max-width: 980px) {
  .shell, .shell.no-right,
  body.nav-collapsed .shell, body.nav-collapsed .shell.no-right {
    grid-template-columns: minmax(0, 1fr);
    padding-left: 14px; padding-right: 14px;
  }
  .foot { padding-left: 14px; padding-right: 14px; }
  .sidebar, body.nav-collapsed .sidebar { display: block; position: static; }
  .sidetab { display: none; }
}
@media (max-width: 720px) {
  .post { grid-template-columns: minmax(0, 1fr); }
  .post-aside { display: flex; align-items: center; gap: 10px; text-align: left; border-right: 0; border-bottom: 1px solid var(--line); padding: 9px 12px; }
  .post-aside .name { margin-top: 0; }
  .post-aside dl { display: none; }
  .post-aside .av { margin: 0; }
  .formrow { grid-template-columns: minmax(0,1fr); }
  .formrow > label { text-align: left; padding-top: 0; }
  .topsearch { display: none; }
  .hide-sm { display: none !important; }
  .foot .ver { margin-left: 0; text-align: left; }
}
/* Phone top bar. At a large text size the brand words plus the right-hand
   controls (text size, theme, sign-in or user chip) are wider than the screen.
   The mark alone still reads as the logo and still links home; the user chip
   is allowed to shrink so a long name ellipsises instead of widening the page. */
@media (max-width: 520px) {
  .brand-text { display: none; }
  .topuser { flex: 0 1 auto; min-width: 0; gap: 6px; margin-left: auto; }
  .userchip { min-width: 0; }
}

@media (prefers-reduced-motion: reduce) {
  * { animation: none !important; transition: none !important; }
}

@media print {
  .topbar, .sidebar, .rail, .sidetab, .foot, .toolrow { display: none !important; }
  .shell { grid-template-columns: 1fr; }
}

/* ==========================================================================
   20. LIVE-BOARD ADDITIONS
   Everything below exists because the board is now driven by real data. The
   mockup above is unchanged; these are the states a static page had no reason
   to describe.
   ========================================================================== */

/* ---- flash messages -------------------------------------------------- */
/* Posting, moderating and reporting all redirect and report back through one
   banner, so a player never loses a typed message to a blank error page the
   way the legacy board's abort screens did. */
.flash {
  display: flex; gap: 9px; align-items: flex-start;
  margin: 0 0 14px; padding: 10px 12px;
  border: 1px solid var(--line); border-left-width: 3px;
  border-radius: var(--radius);
  background: var(--panel-2); font-size: calc(12.5px * var(--fs-scale));
}
.flash .ico { line-height: 1.35; }
.flash.ok   { border-left-color: var(--green); }
.flash.bad  { border-left-color: var(--red); }
.flash.warn { border-left-color: var(--amber); }
.flash b { color: var(--ink-strong); }

/* ---- archived / rescued threads -------------------------------------- */
/* An archived thread is listed inline with live ones rather than hidden behind
   a mode switch, so it needs to read as archived at a glance without becoming
   unreadable. */
.tag.arch { border-color: var(--line-strong); color: var(--ink-faint); }
tr.is-arch td { opacity: .82; }
tr.is-arch:hover td { opacity: 1; }

.vault-note {
  margin-bottom: 14px; padding: 11px 13px;
  border: 1px dashed var(--line-strong); border-radius: var(--radius);
  background: var(--sunken); color: var(--ink-dim); font-size: calc(12px * var(--fs-scale));
}
.vault-note b { color: var(--gold); }

/* ---- unread ---------------------------------------------------------- */
/* The mockup showed unread as an icon state only. On a real board the whole
   row needs to carry it, or a page of 25 is unreadable at a glance. */
tr.is-unread td:first-child { box-shadow: inset 3px 0 0 var(--blue-hi); }
tr.is-unread .f-title a { color: var(--link-hover); font-weight: bold; }

/* ---- author with no surviving account -------------------------------- */
/* 85% of this board's authors have no `user` row. Their names still render and
   still link to a profile; they just are not live accounts, and pretending
   otherwise would be a lie the hover state has to tell. */
.gone { color: var(--ink-faint); border-bottom: 1px dotted var(--line-strong); cursor: help; }
a.gone:hover { color: var(--ink-dim); text-decoration: none; }

/* ---- post body ------------------------------------------------------- */
/* Bodies are twenty years of hand-written HTML. These rules stop a stray
   legacy table or an oversized image from breaking the column. */
.post-body img { max-width: 100%; height: auto; }
.post-body table { max-width: 100%; border-collapse: collapse; }
.post-body td, .post-body th { padding: 2px 6px; }
.post-body a { word-break: break-word; }
.post-body font[color] { /* legacy colour tags survive; they are whitelisted */ }
.post-body blockquote.quote {
  margin: 0 0 11px; border: 1px solid var(--line-soft);
  border-left: 3px solid var(--blue-deep); border-radius: var(--radius);
  background: var(--sunken);
}
.post-body blockquote.quote .qh { padding: 5px 10px; border-bottom: 1px solid var(--line-soft); color: var(--ink-faint); font-size: calc(11px * var(--fs-scale)); }
.post-body blockquote.quote .qb { padding: 9px 11px; color: var(--ink-dim); font-size: calc(12.5px * var(--fs-scale)); }

/* The accepted answer. The legacy board printed a lime sentence into the post
   body; this is the same signal as a property of the post instead. */
.post.answer { border-color: var(--green); }
.post.answer .post-meta { background: rgba(69,185,124,.09); }

/* ---- composer -------------------------------------------------------- */
.composer textarea.field { min-height: 190px; resize: vertical; font: calc(13px * var(--fs-scale))/1.6 var(--font); }
.charcount { color: var(--ink-faint); font-size: calc(11px * var(--fs-scale)); }
.charcount.over { color: var(--red); font-weight: bold; }

/* ---- section glyph --------------------------------------------------- */
.f-icon.arch { color: var(--ink-faint); }

/* ---- mobile ---------------------------------------------------------- */
@media (max-width: 720px) {
  /* The thread list drops to a single stacked column on a phone: five columns
     of 34px rows is unusable at 375px wide. */
  table.tbl.stack-sm thead { display: none; }
  table.tbl.stack-sm, table.tbl.stack-sm tbody, table.tbl.stack-sm tr, table.tbl.stack-sm td { display: block; width: 100%; }
  table.tbl.stack-sm tr { padding: 10px 12px; border-bottom: 1px solid var(--line-soft); }

  /* The section/thread icon is the first thing in the first cell, so with the
     cells stacked the title sits beside it and every line under it starts back
     at the left edge -- a ragged two-step down the row. Lift the icon into a
     gutter of its own and the title, the blurb, the counts and the last post
     all line up in one column beside it.

     :has() so a stacked table with no icon (the mod log, the access screen)
     does not get an empty 54px gutter. Where it is not supported the row keeps
     the plain stacked layout, which is the same thing minus the alignment. */
  table.tbl.stack-sm tr:has(.f-icon) { position: relative; padding-left: 54px; }
  table.tbl.stack-sm tr:has(.f-icon) .f-icon { position: absolute; left: 12px; top: 11px; }
  table.tbl.stack-sm tr:has(.f-icon) td > .row { display: block; }
  /* height:auto is load-bearing. `table.tbl td` sets height:var(--row-h) for
     the 34px desktop row; on a cell that has become a block that is a FIXED
     height, so a section with a title, a blurb and an archived-thread note
     overflows its 34px box and prints on top of the line below it. */
  table.tbl.stack-sm td { border: 0; padding: 0; height: auto; }
  table.tbl.stack-sm tr > td:first-child { font-size: calc(12.5px * var(--fs-scale)); }

  /* Every secondary cell carries a data-lbl and joins ONE meta line under the
     title, because a stacked row without labels is a column of bare values:
     "22  12  Jammer  07 May 2013" says nothing about what any of them are.
     Keyed on the attribute rather than on .num / .mid so a cell keeps whatever
     alignment it needs in the desktop table and still labels itself here. */
  table.tbl.stack-sm td[data-lbl] {
    display: inline-block;
    width: auto;
    margin: 5px 12px 0 0;
    text-align: left;
    color: var(--ink-faint);
    font-size: calc(11px * var(--fs-scale));
  }
  table.tbl.stack-sm td[data-lbl]::before { content: attr(data-lbl) " "; opacity: .75; }

  /* The last-post cell is two stacked lines inside a 30%-wide column on the
     desktop table. On the meta line it has to read as one phrase. */
  table.tbl.stack-sm td[data-lbl] .lastpost,
  table.tbl.stack-sm td[data-lbl] .lastpost .t,
  table.tbl.stack-sm td[data-lbl] .lastpost .m { display: inline; font-size: inherit; max-width: none; }
  /* The two spans are on separate source lines, so they already have a space
     between them -- the separator adds the mark, not the spacing. */
  table.tbl.stack-sm td[data-lbl] .lastpost .m::before { content: "\00b7\00a0"; }

  /* An unlabelled cell keeps a line of its own -- the board index's last-post
     cell is a thread title plus a by-line, which will not share the meta line
     with the counts. The 190px desktop clamp goes with it: the phone column is
     narrower than that already, so the ellipsis only loses words. */
  table.tbl.stack-sm td .lastpost { margin-top: 4px; }
  table.tbl.stack-sm td .lastpost .t { max-width: none; }
  /* ...and says so, or a thread title on a line of its own under a section
     name reads as a second section. */
  table.tbl.stack-sm td:not([data-lbl]) .lastpost::before {
    content: "Last post ";
    color: var(--ink-faint);
    font-size: calc(11px * var(--fs-scale));
  }
}

/* ---------- 21. AVATARS (uploaded images) ----------------------------- */
/* .av is the lettered colour block; .av--img is the same box holding a real
   picture. Sharing the class keeps every size, radius and border identical
   whichever a member has, so a thread with a mix of both still lines up. */
.av--img { padding: 0; background: var(--sunken); }
.av--img img {
  width: 100%; height: 100%;
  object-fit: cover;      /* the stored PNG is already square; this guards a
                             non-square file arriving by some other route */
  display: block;
  border-radius: inherit;
}

/* The moderation grid. Bigger preview than a member card, because the point of
   the page is to actually look at the picture. */
/* A moderation card is a centred COLUMN (picture, name, stats, form), not the
   avatar-beside-text row every other .mcard is -- without this the name, the
   stats and the form each become a squeezed column of their own. */
.mcard.avmod { flex-direction: column; align-items: stretch; text-align: center; }
.mcard.avmod .av { margin: 0 auto 8px; }
.mcard.avmod form { display: block; }
.mcard.avmod .field { font-size: calc(11px * var(--fs-scale)); padding: 4px 6px; }
.mcard.avmod .check { font-size: calc(11px * var(--fs-scale)); justify-content: center; }

/* ==========================================================================
   22. PHONE LAYOUT
   Everything above treats a narrow screen as a wide one with columns removed.
   That is right for the rails and wrong for the navigation: below 980px the
   sidebar is the ONLY navigation left (.topnav goes at 1180px, the Menu side
   tab at 980px), and left in the flow it pushed the first thread 679px down a
   375px screen -- a full phone screen of links before any content, on every
   page. So on a phone it becomes an off-canvas drawer, and the controls around
   it grow to thumb size.

   GATED ON :root.js. The class is set by the inline script in the head of
   index.cfm, before first paint. With scripting off it is never added, none of
   the drawer rules below match, and the sidebar renders in the flow exactly as
   it did before -- the board still navigates with the script file deleted,
   which is the rule this module is built on.
   ========================================================================== */

/* ---- the drawer ------------------------------------------------------ */

/* The hamburger. Hidden entirely on desktop and without script, so nobody is
   shown a button that opens nothing. */
.navbtn { display: none; flex: none; font-size: 15px; }   /* fixed box: not scaled */

/* The scrim. Rendered always, shown only while the drawer is open, so there is
   no markup to toggle and no state to get wrong. */
.navscrim { display: none; }

/* The drawer's own title bar, with the close button. Replaces the sidebar
   panel's "Navigation" head while the sidebar is a drawer, rather than sitting
   above it and saying the same word twice. */
.navdrawer-bar { display: none; }

@media (max-width: 980px) {
  :root.js .navbtn { display: grid; }

  :root.js .sidebar,
  :root.js body.nav-collapsed .sidebar {
    display: block;
    position: fixed;
    top: 0; left: 0; bottom: 0;
    z-index: 90;
    width: min(86vw, 330px);
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    padding-bottom: 40px;
    border-right: 1px solid var(--line);
    background: var(--panel);
    box-shadow: 14px 0 40px -22px rgba(0,0,0,.95);
    /* visibility, not display: it takes the links out of the tab order while
       the drawer is shut, and still allows the slide to animate. */
    visibility: hidden;
    transform: translateX(-100%);
    transition: transform .2s ease, visibility .2s;
  }
  :root.js body.nav-open .sidebar {
    visibility: visible;
    transform: none;
  }

  /* Inside the drawer the panel chrome is the drawer's own, so the border,
     radius and shadow come off rather than drawing a box inside a box. */
  :root.js .sidebar .panel {
    margin: 0;
    border: 0;
    border-radius: 0;
    box-shadow: none;
    background-image: none;
  }
  :root.js .sidebar .panel > .panel-head { display: none; }

  :root.js .navdrawer-bar {
    position: sticky;
    top: 0;
    z-index: 1;
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 9px 10px 9px 12px;
    border-bottom: 1px solid var(--line);
    background: var(--row-head-bg);
    color: var(--row-head-ink);
  }
  :root.js .navdrawer-bar .t {
    font-size: calc(12px * var(--fs-scale));
    font-weight: bold;
    letter-spacing: 1px;
    text-transform: uppercase;
  }
  :root.js .navdrawer-bar .iconbtn { margin-left: auto; }

  /* The drawer and its scrim are both children of .shell, which is a stacking
     context of its own (position:relative; z-index:1). Inside it the two order
     correctly against each other and against the page; the whole context is
     then lifted over the top bar for as long as the drawer is open, so the
     scrim dims the bar too and a tap up there shuts the drawer rather than
     hitting a control behind the dimming. */
  :root.js body.nav-open .shell { z-index: 95; }
  :root.js body.nav-open .navscrim {
    display: block;
    position: fixed;
    inset: 0;
    z-index: 85;
    background: rgba(2, 5, 9, .62);
  }

  /* The page behind the drawer must not scroll under it -- a drawer that moves
     the article it is covering reads as the page having jumped when it shuts. */
  :root.js body.nav-open { overflow: hidden; }

  /* Roomier rows: the drawer is the whole navigation and it is driven by a
     thumb. */
  :root.js .sidebar .navlist { padding: 4px 4px 12px; }
  :root.js .sidebar .navlist a { padding: 10px 10px; border-radius: var(--radius); }
  :root.js .sidebar .navgroup { padding-top: 12px; }
}

/* ---- the rail, on the one page that wants it ------------------------- */

/* The rail is the board's ambient information: who is online, what moved in
   the last hour. Hidden outright from 1280px down it does not exist at all on
   a phone. Bring it back under the index -- where a reader has arrived
   precisely to see what is happening -- and leave it off thread, form and
   listing pages, where it would be four panels of stats after the reply box. */
@media (max-width: 980px) {
  body[data-page="index"] .rail {
    display: block;
    position: static;
    margin-top: 14px;
  }
}

/* ---- thumb-sized controls -------------------------------------------- */

/* A 26px control is comfortable with a mouse and missed with a thumb. Scoped
   to a coarse pointer as well as a narrow screen so a touch-screen laptop at
   full width keeps the desktop board's density -- the problem being solved is
   fingers on a small screen, not fingers as such. */
@media (max-width: 980px) and (pointer: coarse) {
  .iconbtn { width: 38px; height: 38px; }
  .btn { padding: 9px 15px; }
  .btn.sm { padding: 7px 12px; }
  .pager a, .pager span { min-width: 38px; height: 38px; }
  .tabs a { padding: 11px 14px; }
  .toolbar .tb { min-width: 34px; height: 32px; }
  .react { padding: 6px 11px; }
  /* Inline text actions under a post sit shoulder to shoulder; the padding is
     what separates "Quote" from "Edit" under a thumb. */
  .post-foot .lnk { padding: 5px 2px; }
}

/* ---- the top bar, signed in ------------------------------------------ */

/* Signed out the bar carries a menu button, the mark, A-/A+, the theme toggle
   and Sign in, and that fits. Signed in it also carries messages,
   notifications and the user chip -- seven controls on a 375px line, which
   ends with every one of them squeezed a few pixels narrower than it was
   drawn. The name is the one thing up there that is also on the page it links
   to, so the chip keeps its avatar and drops the name, and the buttons keep
   the size a thumb was promised. */
@media (max-width: 520px) {
  .topuser .iconbtn { flex: none; }
  .userchip { padding: 3px; }
  .userchip .stack { display: none; }
}

/* ---- forms ------------------------------------------------------------ */

@media (max-width: 980px) {
  /* iOS Safari zooms the page in whenever a focused field's text is under
     16px, and does not zoom back out afterwards -- so tapping the reply box
     leaves the whole board magnified. max() holds the floor without breaking
     the reader's text-size setting: A+ still grows these, A- cannot shrink
     them past the threshold. */
  .field,
  select.field,
  textarea.field,
  .composer textarea.field { font-size: max(16px, calc(13px * var(--fs-scale))); }
}

@media (max-width: 720px) {
  /* Filter bars: four selects and a search box laid out as a wrapping row of
     content-width controls come out as a ragged staircase. Two up, search on
     its own line, and the result count below them all. */
  .toolrow { gap: 6px; }
  .toolrow select.field { flex: 1 1 calc(50% - 3px); min-width: 0; }
  .toolrow .field.filter { flex: 1 1 100%; max-width: none; }
  .toolrow .spacer { flex-basis: 100%; margin-left: 0; }
  .toolrow > .small { flex-basis: 100%; }

  /* Tabs scroll sideways rather than wrapping into a second row that looks
     like two sets of tabs. */
  .tabs { overflow-x: auto; scrollbar-width: none; }
  .tabs::-webkit-scrollbar { display: none; }
  .tabs a { white-space: nowrap; flex: none; }
}

/* ---- text that has to fit -------------------------------------------- */

@media (max-width: 720px) {
  /* A 30-character title, a long player name or a bare URL in a crumb trail
     are all wider than a phone column. */
  .crumbs { overflow-wrap: anywhere; }
  .pagehead h1 { overflow-wrap: anywhere; }

  /* The head's spacer pushes the buttons to the right of the heading on a wide
     screen. Once everything has wrapped into one column it is pushing them to
     the right of nothing, which reads as a stray right-aligned sentence. */
  .pagehead { align-items: flex-start; }
  .pagehead .spacer { display: none; }

  /* Twenty years of hand-written bodies include fixed-width layout tables and
     unbroken URLs. Let a table scroll inside its post instead of widening the
     whole page; everything else wraps. */
  .post-body { overflow-wrap: anywhere; }
  .post-body table { display: block; width: max-content; max-width: 100%; overflow-x: auto; }
  .post-body pre { overflow-x: auto; }
}
