
:root{
  --ink:#0c0f14; --panel:#141920; --panel-2:#1b212b; --line:#28313d;
  --text:#dfe6ef; --dim:#93a1b3; --faint:#5f6f83;
  --hot:#ff8a3d; --cool:#5fd0e8; --ok:#7ddb9a; --bad:#ff5f6d;
  --mono:"IBM Plex Mono",ui-monospace,SFMono-Regular,Menlo,monospace;
  --disp:"Oswald","Arial Narrow",system-ui,sans-serif;
  --body:"Inter",system-ui,-apple-system,Segoe UI,sans-serif;
}
:root[data-theme="light"]{
  --ink:#eef1f5; --panel:#ffffff; --panel-2:#f4f6f9; --line:#d3dae3;
  --text:#131922; --dim:#4d5b6d; --faint:#7d8b9d;
}
*{box-sizing:border-box}
body{margin:0;background:var(--ink);color:var(--text);font-family:var(--body);
  font-size:15px;line-height:1.6;-webkit-font-smoothing:antialiased}
a{color:var(--cool);text-decoration:none}
a:hover{text-decoration:underline}
.wrap{max-width:1180px;margin:0 auto;padding:0 24px}
header.top{border-bottom:1px solid var(--line);background:
  linear-gradient(180deg,rgba(255,138,61,.07),transparent 60%),var(--panel)}
.top .wrap{padding-top:54px;padding-bottom:46px}
.eyebrow{font-family:var(--mono);font-size:11px;letter-spacing:.22em;text-transform:uppercase;
  color:var(--hot);margin:0 0 14px}
h1{font-family:var(--disp);font-weight:600;font-size:clamp(38px,6vw,68px);line-height:1.02;
  margin:0 0 16px;letter-spacing:-.01em;text-wrap:balance}
.lede{font-size:clamp(16px,2vw,19px);color:var(--dim);max-width:62ch;margin:0 0 26px}
.counts{display:flex;flex-wrap:wrap;gap:26px;font-family:var(--mono);font-size:12px;
  color:var(--faint);letter-spacing:.06em;text-transform:uppercase}
.counts b{display:block;font-size:26px;color:var(--text);letter-spacing:0;font-weight:500}
nav.sticky{position:sticky;top:0;z-index:20;background:rgba(12,15,20,.92);
  backdrop-filter:blur(8px);border-bottom:1px solid var(--line)}
:root[data-theme="light"] nav.sticky{background:rgba(238,241,245,.92)}
nav.sticky .wrap{display:flex;gap:22px;overflow-x:auto;padding-top:12px;padding-bottom:12px;
  font-family:var(--mono);font-size:12px;letter-spacing:.1em;text-transform:uppercase}
nav.sticky a{color:var(--dim);white-space:nowrap}
nav.sticky a:hover{color:var(--text);text-decoration:none}
section{padding:56px 0;border-bottom:1px solid var(--line)}
h2{font-family:var(--disp);font-weight:600;font-size:clamp(24px,3.4vw,36px);margin:0 0 8px;
  letter-spacing:.01em}
h2 .n{font-family:var(--mono);font-size:13px;color:var(--faint);letter-spacing:.08em;
  margin-left:10px;font-weight:400}
.sub{color:var(--dim);max-width:70ch;margin:0 0 30px}
h3{font-family:var(--mono);font-size:12px;letter-spacing:.18em;text-transform:uppercase;
  color:var(--hot);margin:38px 0 14px;font-weight:500}
h3 small{color:var(--faint);text-transform:none;letter-spacing:0;font-size:12px;margin-left:8px}
.grid{display:grid;gap:18px;grid-template-columns:repeat(auto-fill,minmax(260px,1fr))}
.card{background:var(--panel);border:1px solid var(--line);border-radius:3px;overflow:hidden;
  display:flex;flex-direction:column}
.card .shot{background:var(--panel-2);border-bottom:1px solid var(--line);aspect-ratio:4/3;
  display:block;width:100%;object-fit:contain}
.card.tall .shot{aspect-ratio:13/17}
.card .body{padding:13px 14px 15px;display:flex;flex-direction:column;gap:7px;flex:1}
.card .nm{font-family:var(--disp);font-size:17px;letter-spacing:.02em;line-height:1.15}
.card .key{font-family:var(--mono);font-size:10.5px;color:var(--faint);letter-spacing:.06em}
.card .ds{color:var(--dim);font-size:13px;line-height:1.5;flex:1}
.bars{display:flex;flex-direction:column;gap:4px;margin-top:2px}
.bar{display:grid;grid-template-columns:52px 1fr 42px;align-items:center;gap:8px;
  font-family:var(--mono);font-size:9.5px;letter-spacing:.08em;color:var(--faint)}
.bar .t{height:4px;background:var(--panel-2);border-radius:2px;overflow:hidden}
.bar .t i{display:block;height:100%;background:var(--accent,var(--cool))}
.bar .v{text-align:right;color:var(--dim)}
.tags{display:flex;flex-wrap:wrap;gap:5px;margin-top:3px}
.tag{font-family:var(--mono);font-size:9.5px;letter-spacing:.06em;text-transform:uppercase;
  padding:2.5px 6px;border:1px solid var(--line);border-radius:2px;color:var(--dim)}
.tag.hot{border-color:rgba(255,138,61,.45);color:var(--hot)}
table{width:100%;border-collapse:collapse;font-family:var(--mono);font-size:12px}
.scroll{overflow-x:auto;border:1px solid var(--line);border-radius:3px;background:var(--panel)}
th,td{padding:8px 12px;text-align:left;border-bottom:1px solid var(--line);white-space:nowrap}
th{color:var(--faint);font-weight:500;letter-spacing:.1em;text-transform:uppercase;font-size:10px}
td{color:var(--dim)}
td.k{color:var(--text)}
td.num{text-align:right;font-variant-numeric:tabular-nums}
tr:last-child td{border-bottom:none}
/* THE CLIPS GET A WIDER COLUMN THAN THE REST OF THE PAGE. Everything else reads best at
   1180px (prose, cards, tables); gameplay does not -- asked for as "bigger so I can see
   more than just 1 demo gameplay, but a bunch of them". At 1380 the hero plays at close to
   the 1280 it was filmed at and the cards below it sit two and three across instead of
   two, so several battles are on screen at once and each is still worth looking at. */
#action .wrap{max-width:1380px}
.clip.hero video{max-height:min(72vh,760px);object-fit:contain}
.clips{display:grid;gap:22px;grid-template-columns:repeat(auto-fit,minmax(460px,1fr))}
.clip{background:var(--panel);border:1px solid var(--line);border-radius:3px;overflow:hidden}
.clip img,.clip video{width:100%;display:block;background:#000;aspect-ratio:16/9;object-fit:cover;cursor:zoom-in}
[data-full]{cursor:zoom-in}
#lb video{max-width:min(1280px,96vw);max-height:92vh;border-radius:8px;box-shadow:0 30px 90px rgba(0,0,0,.6);background:#000;cursor:auto}
.clip .cap{padding:12px 14px}
.clip .cap b{font-family:var(--disp);font-weight:500;font-size:16px;display:block;margin-bottom:3px}
.clip .cap span{color:var(--dim);font-size:13px}
.note{border-left:2px solid var(--hot);padding:2px 0 2px 16px;color:var(--dim);
  max-width:70ch;margin:24px 0}
footer{padding:44px 0 70px;color:var(--faint);font-size:13px}
footer .wrap{display:flex;flex-wrap:wrap;gap:18px;justify-content:space-between}
.stamp{font-family:var(--mono);font-size:11px;letter-spacing:.06em}
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}
@media (max-width:640px){.grid{grid-template-columns:repeat(auto-fill,minmax(200px,1fr))}}

/* ---- the hero clip: full width, above the card grid ----------------------------------- */
.clip.hero{margin:22px 0 26px;background:var(--panel);border:1px solid var(--line);
  border-radius:12px;overflow:hidden}
.clip.hero video{width:100%;display:block;aspect-ratio:16/9;background:#05070a}
.clip.hero .cap{padding:16px 20px 18px;display:grid;gap:6px}
.clip.hero .cap b{font-family:var(--disp);font-weight:500;font-size:22px;letter-spacing:.01em}
.clip.hero .cap span{font-size:14px;max-width:88ch}

/* ---- the trailer: the first thing on the page, above the nav ---------------------------
   THE PRODUCED CUT, built by `trailer.py` from real GPU gameplay. It plays with SOUND (it has a
   score), so it does not autoplay: a muted autoplay of a scored trailer is the worst of both. */
.trailer{background:#05070a;border-bottom:1px solid var(--line)}
.trailer .wrap{max-width:1380px;padding-top:26px;padding-bottom:26px}
.trailer .frame{position:relative;width:100%;aspect-ratio:16/9;border-radius:12px;overflow:hidden;
  background:#000;box-shadow:0 30px 90px rgba(0,0,0,.55)}
.trailer video,.trailer iframe,.trailer .yt{position:absolute;inset:0;width:100%;height:100%;border:0;display:block;
  background:#000}
.trailer .yt{padding:0;cursor:pointer}
.trailer .yt img{width:100%;height:100%;object-fit:cover;display:block}
.trailer .yt .play{position:absolute;left:50%;top:78%;width:92px;height:64px;margin:-32px 0 0 -46px;border-radius:16px;
  background:rgba(12,14,18,.78);box-shadow:0 8px 30px rgba(0,0,0,.5);transition:background .15s}
.trailer .yt .play::after{content:"";position:absolute;left:38px;top:20px;border-style:solid;border-width:12px 0 12px 20px;
  border-color:transparent transparent transparent #fff}
.trailer .yt:hover .play,.trailer .yt:focus-visible .play{background:#e0401b}
.trailer .meta{display:flex;flex-wrap:wrap;gap:6px 18px;align-items:baseline;margin-top:12px;
  color:var(--dim);font-size:13px}
.trailer .meta b{font-family:var(--disp);font-weight:500;color:var(--text);font-size:16px}
.trailer .meta a{color:var(--hot)}

/* ---- the filter box, in the sticky nav ------------------------------------------------ */
nav.sticky .wrap{display:flex;align-items:center;gap:4px;flex-wrap:wrap}
#q{margin-left:auto;min-width:260px;flex:0 1 320px;background:var(--panel-2);color:var(--text);
  border:1px solid var(--line);border-radius:7px;padding:7px 11px;font-family:var(--mono);
  font-size:12px}
#q:focus{outline:none;border-color:var(--cool)}
.qn{font-family:var(--mono);font-size:11px;color:var(--faint);min-width:5ch}
.card[hidden],.strip[hidden],.world[hidden],.sil figure[hidden],tr[hidden]{display:none!important}

/* ---- dense grids for the 106 objects -------------------------------------------------- */
.grid.tight{grid-template-columns:repeat(auto-fill,minmax(186px,1fr));gap:14px}
/* A SQUARE BOX, CONTAIN, because this grid mixes two frame shapes on purpose: a tall model
   is rendered portrait and a wide one landscape, and the cards still have to line up. Cover
   would crop a church tower's spire off; a 4:3 box would letterbox the portraits back to the
   width they were rendered portrait to escape. A square splits the difference and crops
   nothing. */
.grid.tight .shot{aspect-ratio:1;object-fit:contain}
.grid.tight .body{padding:10px 12px 12px}
.grid.tight .nm{font-size:14px}
.grid.tight .ds{font-size:12px;line-height:1.45;-webkit-line-clamp:4}

/* ---- the battlemech silhouette strip -------------------------------------------------- */
.sil{display:grid;grid-template-columns:repeat(auto-fill,minmax(118px,1fr));gap:10px;
  margin:18px 0 4px}
.sil figure{margin:0;background:var(--panel);border:1px solid var(--line);border-radius:8px;
  overflow:hidden;text-align:center}
.sil img{width:100%;display:block}
.sil figcaption{font-family:var(--mono);font-size:10px;letter-spacing:.05em;color:var(--dim);
  padding:5px 4px 7px}

/* ---- worlds from above ---------------------------------------------------------------- */
.worlds{display:grid;grid-template-columns:repeat(auto-fill,minmax(232px,1fr));gap:16px;
  margin-top:18px}
.world{margin:0;background:var(--panel);border:1px solid var(--line);border-radius:10px;
  overflow:hidden}
.world img{width:100%;display:block;aspect-ratio:1;object-fit:cover;cursor:zoom-in}
.world figcaption{padding:10px 12px 12px;display:flex;flex-direction:column;gap:3px}
.world b{font-family:var(--disp);font-weight:500;font-size:15px;letter-spacing:.02em}
.world .wt{font-family:var(--mono);font-size:10px;color:var(--hot);letter-spacing:.07em}
.world .wf{font-size:11px;color:var(--dim)}

/* ---- biome palette swatches ----------------------------------------------------------- */
table.biomes .sw{white-space:nowrap}
table.biomes .sw i{display:inline-block;width:19px;height:19px;border-radius:4px;
  margin-right:4px;border:1px solid rgba(255,255,255,.14);vertical-align:middle}
table.biomes .gr{color:var(--dim);font-size:12px}

/* ---- flora variant strips ------------------------------------------------------------- */
.strips{display:grid;grid-template-columns:repeat(auto-fill,minmax(330px,1fr));gap:16px;
  margin-top:18px}
.strip{margin:0;background:var(--panel);border:1px solid var(--line);border-radius:10px;
  overflow:hidden}
.strip img{width:100%;display:block;background:var(--panel-2)}
.strip figcaption{padding:10px 12px 12px;display:flex;flex-wrap:wrap;gap:4px 10px;
  align-items:baseline}
.strip b{font-family:var(--disp);font-weight:500;font-size:15px}
.strip .key,.strip .vn{font-family:var(--mono);font-size:10px;color:var(--faint)}
.strip .vn{color:var(--cool)}
.strip .wh{font-size:11px;color:var(--dim);flex-basis:100%}

/* ---- the numbers ---------------------------------------------------------------------- */
.figs{display:grid;grid-template-columns:repeat(auto-fill,minmax(178px,1fr));gap:12px;
  margin:20px 0}
.fig{background:var(--panel);border:1px solid var(--line);border-radius:10px;padding:14px 15px}
.fig b{display:block;font-family:var(--disp);font-weight:600;font-size:27px;line-height:1;
  color:var(--text)}
.fig span{display:block;font-size:12px;margin-top:5px}
.fig i{display:block;font-style:normal;font-family:var(--mono);font-size:10px;
  color:var(--faint);margin-top:4px;line-height:1.4}
ul.checks{list-style:none;padding:0;margin:10px 0 0;display:grid;
  grid-template-columns:repeat(auto-fill,minmax(272px,1fr));gap:6px}
ul.checks li{font-family:var(--mono);font-size:11px;color:var(--dim);
  border-left:2px solid var(--ok);padding:3px 0 3px 10px}
ol.log{list-style:none;padding:0;margin:14px 0 0}
ol.log li{display:flex;gap:12px;align-items:baseline;padding:7px 0;
  border-bottom:1px solid var(--line);font-size:13px}
ol.log code{font-family:var(--mono);font-size:11px;color:var(--hot)}
ol.log time{font-family:var(--mono);font-size:11px;color:var(--faint);min-width:9ch}

/* ---- lightbox for the world previews --------------------------------------------------- */
#lb{position:fixed;inset:0;background:rgba(4,6,9,.93);display:none;align-items:center;
  justify-content:center;z-index:50;cursor:zoom-out;padding:22px}
#lb.on{display:flex}
#lb img{max-width:min(1100px,96vw);max-height:92vh;border-radius:8px;
  box-shadow:0 30px 90px rgba(0,0,0,.6)}

/* the link to the engine write-up (voxelstrike-notes.pages.dev) */
.notes-link{margin:.9rem 0 0}
.notes-link a{display:inline-block;padding:.45rem .8rem;border:1px solid var(--hot);color:var(--hot);border-radius:4px;font-weight:600}
nav.sticky a.ext{color:var(--hot)}
