/* wii.css — client chrome (SPEC §6). Canvas fullscreen; WC2-authentic HUD +
   menus (HUD wave): the real WC2 UI art as CSS backgrounds (indexed PNGs
   decode fine for display; image-rendering: pixelated everywhere). The HUD
   left column + top bar render at native WC2 pixel sizes and scale via
   --wii-hud (1 or 2, set by ui_menus.js from screen height / options); the
   command panel alone stretches to the screen bottom so the column spans the
   full height (vendor buttonpanel filler — ui_pandora.lua:111). */

* { margin: 0; padding: 0; box-sizing: border-box; }

:root { --wii-hud: 2; }

html, body {
  width: 100%; height: 100%;
  overflow: hidden;
  background: #000;
  color: #d8c890;
  font-family: 'Palatino Linotype', Palatino, Georgia, serif;
  user-select: none;
  -webkit-user-select: none;
}

canvas#gl {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  image-rendering: pixelated;
  outline: none;
}
/* desktop (classic left-column layout): the world canvas sits RIGHT of the
   column and BELOW the resource strip so the camera clamp can actually reach
   the map's left/top edges (owner report 2026-07-09: units at the left map
   edge stayed hidden under the panel even at max scroll — same class as the
   W17 bottom-bar inset). main.js ResizeObserver re-runs cam.setViewport when
   the layout flips; explicit width/height calc, not insets (replaced element,
   see the html.touch note below). */
html:not(.touch) canvas#gl {
  left: calc(176px * var(--wii-hud));
  width: calc(100% - 176px * var(--wii-hud));
  top: calc(16px * var(--wii-hud));
  height: calc(100% - 16px * var(--wii-hud));
}

/* ---- HUD skeleton (ui_hud.js fills these once the world is up) ---- */
#hud { position: fixed; inset: 0; pointer-events: none; z-index: 10; }
#hud > * { pointer-events: auto; }
#hud > *:empty { display: none; }
#left > *:empty { display: none; }
#hud, #hud * { image-rendering: pixelated; }

/* top resource bar — WC2 resource strip art, full width, left column padded */
#resources {
  position: absolute; top: 0; left: 0;
  height: 16px;
  width: calc(100% / var(--wii-hud));
  transform: scale(var(--wii-hud));
  transform-origin: 0 0;
  background: url('/assets/graphics/ui/human/resource.png?v=1') repeat-x #000;
  display: flex; align-items: center; gap: 22px;
  padding-left: 184px;
  font: bold 10px/1 'Palatino Linotype', Georgia, serif;
  color: #fce088;
}
.hud-orc #resources { background-image: url('/assets/graphics/ui/orc/resource.png?v=1'); }
.res-item { display: flex; align-items: center; gap: 4px; white-space: nowrap; }
.res-v.res-over { color: #ff5040; }
.res-v.res-flash { animation: wii-redflash .28s 3; }
@keyframes wii-redflash { 50% { color: #ff2020; } }

.res-ico {
  display: inline-block; width: 14px; height: 14px;
  background: url('/assets/graphics/ui/gold,wood,oil,mana.png?v=1') no-repeat;
  vertical-align: middle;
}
.ri-gold  { background-position: 0 0; }
.ri-wood  { background-position: 0 -14px; }
.ri-oil   { background-position: 0 -28px; }
.ri-mana  { background-position: 0 -42px; }
.ri-food  { background: url('/assets/graphics/ui/food.png?v=1') no-repeat; }
.ri-score { background: url('/assets/graphics/ui/score.png?v=1') no-repeat; }

/* left column: menu button / minimap frame / info panel / command card */
#left {
  position: absolute; left: 0;
  top: calc(16px * var(--wii-hud));
  width: 176px;
  transform: scale(var(--wii-hud));
  transform-origin: 0 0;
}
#minimap { width: 176px; }
.mm-menubtn {
  display: block; width: 176px; height: 24px;
  background: url('/assets/graphics/ui/human/menubutton.png?v=1');
  border: 0; cursor: pointer;
  font: bold 11px 'Palatino Linotype', Georgia, serif;
  color: #ffd75e; text-shadow: 1px 1px #000;
  image-rendering: pixelated;
}
.hud-orc .mm-menubtn { background-image: url('/assets/graphics/ui/orc/menubutton.png?v=1'); }
.mm-menubtn:hover { color: #fff; }
.mm-f10 { font-weight: normal; color: #b09a60; font-size: 9px; }
.mm-frame {
  position: relative; width: 176px; height: 136px;
  background: url('/assets/graphics/ui/human/minimap.png?v=1');
}
.hud-orc .mm-frame { background-image: url('/assets/graphics/ui/orc/minimap.png?v=1'); }
.mm-frame canvas {
  position: absolute; left: 24px; top: 2px;
  width: 128px; height: 128px;
  image-rendering: pixelated;
  cursor: crosshair;
}

/* selection info panel (top 176px slice of infopanel.png) */
.sel-panel {
  position: relative; width: 176px; height: 176px;
  background: url('/assets/graphics/ui/human/infopanel.png?v=1') 0 0;
}
.hud-orc .sel-panel { background-image: url('/assets/graphics/ui/orc/infopanel.png?v=1'); }
.sel-body { position: absolute; inset: 6px 8px 6px 8px; overflow: hidden; }
.sel-one { display: flex; gap: 6px; }
.sel-porta { width: 50px; flex: none; }
.sel-porta.sel-flash .sel-portrait { animation: wii-flashgold .3s 4; }
@keyframes wii-flashgold { 50% { filter: brightness(1.9) sepia(.6); } }
.sel-portrait { width: 46px; height: 38px; border: 2px solid #3a2e18; box-shadow: 0 0 0 1px #000; background-repeat: no-repeat; }
.sel-hpbar { width: 50px; height: 5px; background: #000; margin-top: 3px; border: 1px solid #201808; }
.sel-hpbar > div { height: 100%; }
/* golden-tier mod: SelfRepair regen pulse (wounded + finished tower — ui_hud.js) */
.sel-hpbar.sel-regen > div { animation: wii-regen 1s ease-in-out infinite; }
@keyframes wii-regen { 50% { filter: brightness(2); } }
.sel-hptext { font: 9px monospace; color: #cfc090; text-align: center; }
.sel-name { font: bold 12px 'Palatino Linotype', Georgia, serif; color: #fce088; text-shadow: 1px 1px #000; padding-top: 4px; }
.sel-stats { margin-top: 6px; font: 10px/1.5 'Palatino Linotype', Georgia, serif; color: #d8c890; }
.sel-stat { display: flex; justify-content: space-between; padding: 0 4px; }
.sel-stat span:first-child { color: #a89464; }
/* mana: 'Mana:' label + numeric value centered ON the light-blue bar (vendor
   wargus/scripts/ui.lua:274-281 — text at x=100, 60x14 CompleteBar, Value
   drawn on the bar; current value only, max 255) */
.sel-manarow { display: flex; align-items: center; gap: 4px; margin-top: 3px; }
.sel-manalabel { font: 10px 'Palatino Linotype', Georgia, serif; color: #a89464; }
.sel-manabar { position: relative; flex: 1; height: 13px; background: #000; border: 1px solid #201808; }
.sel-manabar > div { height: 100%; background: #3050e0; }
.sel-mananum {
  position: absolute; inset: 0; text-align: center;
  font: bold 9px/11px monospace; color: #fff; text-shadow: 1px 1px #000;
}
/* spell-buff indicators under the portrait (16x16 slices of the buff sheet) */
.sel-buffs { display: flex; gap: 1px; margin-top: 2px; }
.sel-buff {
  width: 16px; height: 16px; flex: none;
  background-repeat: no-repeat; image-rendering: pixelated;
  border: 1px solid #201808; background-color: #000;
}
/* transport cargo panel: click a chip to unload that unit, ⏏ = unload all */
.sel-cargou { cursor: pointer; }
.sel-cargou:hover { filter: brightness(1.3); }
.sel-unloadall {
  width: 20px; height: 21px; padding: 0; cursor: pointer;
  background: #2a2416; color: #ffd75e; border: 1px solid #665c33; font: 11px monospace;
}
.sel-unloadall:hover { filter: brightness(1.3); }
.sel-progress {
  position: absolute; left: 2px; right: 2px; bottom: 2px; height: 14px;
  background: #14100a; border: 1px solid #46381c; text-align: center;
  /* the bar sets its OWN font/line strut (12px = height minus borders): the
     label used to baseline-align against the panel's inherited 16px serif
     strut and hung clipped BELOW the bar (owner playtest B6) */
  font: 9px/12px monospace; color: #e8d8a0;
}
.sel-progress span { position: relative; }
.sel-progfill { position: absolute; inset: 0 auto 0 0; background: rgb(48, 100, 4); }
/* no queue data yet (sub-beat gap after a click/join before the {t:'prod'}
   row lands): calm full-width pulse — the old 30%-block left→right sweep
   read as a BROKEN bar ("renders garbage", owner playtest B6) */
.sel-indet .sel-progfill { width: 100%; animation: wii-indet 1.2s ease-in-out infinite alternate; }
@keyframes wii-indet { from { opacity: .15; } to { opacity: .45; } }
.sel-cargo { display: flex; gap: 2px; margin-top: 4px; flex-wrap: wrap; }
.sel-multi { display: flex; flex-wrap: wrap; gap: 3px; }
.sel-chip { cursor: pointer; }
.sel-chip:hover .sel-chipicon { filter: brightness(1.3); }
.sel-chipicon { border: 1px solid #3a2e18; background-repeat: no-repeat; background-color: #1a140c; }
.sel-chiphp { height: 3px; background: #000; margin-top: 1px; }
.sel-chiphp > div { height: 100%; }
.sel-dense .sel-chip { width: 30px; }

/* command card 3x3 on the buttonpanel art */
.cmd-panel {
  position: relative; width: 176px; height: 144px;
  background: url('/assets/graphics/ui/human/buttonpanel.png?v=1');
}
.hud-orc .cmd-panel { background-image: url('/assets/graphics/ui/orc/buttonpanel.png?v=1'); }
/* B1 (owner playtest 2026-07-08): the classic left column spans the FULL
   screen height. Vendor parity — ui_pandora.lua:111 AddResizedFiller
   STRETCHES the buttonpanel art from below the info panel to the screen
   bottom (176 x 144 + Video.Height - 480); the 3x3 buttons keep their fixed
   top anchors on it. 352px = 16 resource bar + 24 menu button + 136 minimap
   + 176 info panel above the card; #left is scaled by --wii-hud, so heights
   here are pre-scale px (100vh / scale = logical viewport height). Touch
   keeps its own bottom-bar layout (later html.touch rules override). */
html:not(.touch) .cmd-panel {
  height: calc(100vh / var(--wii-hud) - 352px);
  min-height: 144px;
  /* repeat-y quilted filler built from the buttonpanel's own pixels
     (build/gen_ui_fillers.mjs) — replaces the stretched buttonpanel entirely:
     layering the original above the filler would abut non-adjacent source
     rows at y=144 and show a hard seam (W17 texture-left). */
  background: url('/assets/graphics/ui/human/panel_filler.png?v=1') top left repeat-y;
}
html:not(.touch) .hud-orc .cmd-panel { background-image: url('/assets/graphics/ui/orc/panel_filler.png?v=1'); }
.cmd-btn { position: absolute; width: 50px; height: 42px; cursor: pointer; }
.cmd-btn.p1 { left: 7px;  top: 2px; }  .cmd-btn.p2 { left: 63px;  top: 2px; }  .cmd-btn.p3 { left: 119px; top: 2px; }
.cmd-btn.p4 { left: 7px;  top: 49px; } .cmd-btn.p5 { left: 63px;  top: 49px; } .cmd-btn.p6 { left: 119px; top: 49px; }
.cmd-btn.p7 { left: 7px;  top: 96px; } .cmd-btn.p8 { left: 63px;  top: 96px; } .cmd-btn.p9 { left: 119px; top: 96px; }
.cmd-icon { width: 46px; height: 38px; margin: 2px; border: 1px solid #000; box-shadow: 0 0 0 1px #4a3a1c; background-repeat: no-repeat; background-color: #1a140c; }
.cmd-btn:hover .cmd-icon { filter: brightness(1.25); }
.cmd-btn:active .cmd-icon { transform: translate(1px, 1px); }
.cmd-btn.cmd-lack .cmd-icon { filter: grayscale(.65) brightness(.75); }
.cmd-btn.cmd-lack::after {
  content: ''; position: absolute; inset: 2px 2px 2px 2px;
  background: rgba(150, 10, 10, .35); pointer-events: none;
}
.cmd-btn.cmd-armed .cmd-icon { box-shadow: 0 0 0 2px #ffd75e; }
/* autocast active (right-click toggle on autocast-capable spell buttons) */
.cmd-btn.cmd-auto .cmd-icon { box-shadow: 0 0 0 2px #58c8ff; }
.cmd-btn.cmd-auto::before {
  content: 'auto'; position: absolute; left: 4px; top: 3px; z-index: 1;
  font: bold 8px monospace; color: #9fe0ff; text-shadow: 1px 1px #000;
  pointer-events: none;
}
.cmd-key {
  position: absolute; right: 4px; bottom: 3px;
  font: bold 9px monospace; color: #ffe37a; text-shadow: 1px 1px #000;
  pointer-events: none;
}
/* production-queue count badge on train buttons (LMB enqueues, RMB removes) */
.cmd-q {
  position: absolute; left: 3px; top: 2px; z-index: 1;
  min-width: 14px; height: 14px; padding: 0 3px;
  background: rgba(10, 8, 4, .92); border: 1px solid #8a7433; border-radius: 7px;
  font: bold 10px/12px monospace; color: #7fff7f; text-align: center;
  pointer-events: none;
}

/* bottom status line: tooltips + alerts on the WC2 statusline art */
#wii-status {
  position: fixed; bottom: 0; right: 0;
  left: calc(176px * var(--wii-hud));
  height: calc(16px * var(--wii-hud));
  background: url('/assets/graphics/ui/human/statusline.png?v=1') repeat-x #000;
  background-size: auto 100%;
  color: #e8d8a0;
  font: bold calc(7px * var(--wii-hud))/calc(16px * var(--wii-hud)) 'Palatino Linotype', Georgia, serif;
  padding: 0 12px;
  white-space: nowrap; overflow: hidden;
  pointer-events: none;
  z-index: 11;
}
.hud-orc #wii-status { background-image: url('/assets/graphics/ui/orc/statusline.png?v=1'); }
#wii-status.st-alert, .st-alert { color: #ff4838; }
#wii-status u { color: #fff; }
.st-costs { margin-left: 14px; }
/* transform: scale() grows the icon VISUALLY but not its layout box — at HUD
   scale 2 the following number overlapped the icon (owner report 2026-07-09).
   Reserve the visual overhang in the margins: the icon spills 7px*(hud-1) on
   each side of its 14px box (transform-origin center). */
.st-costs .res-ico {
  margin: 0 calc(3px + 7px * (var(--wii-hud) - 1)) 0 calc(8px + 7px * (var(--wii-hud) - 1));
  transform: scale(var(--wii-hud));
  transform-origin: center;
}

/* chat overlay (log + Enter input) */
#chat {
  position: absolute;
  left: calc(176px * var(--wii-hud) + 10px);
  bottom: calc(16px * var(--wii-hud) + 8px);
  width: 42%;
  pointer-events: none;
  font: calc(6px * var(--wii-hud))/1.5 'Palatino Linotype', Georgia, serif;
}
.chat-log div { text-shadow: 1px 1px 2px #000; color: #e8e0c0; }
.chat-in {
  display: none; width: 100%; margin-top: 4px; pointer-events: auto;
  background: rgba(10, 8, 4, .85); border: 1px solid #665c33; color: #ffe9a8;
  font: inherit; padding: 3px 6px; outline: none;
}
.chat-in.open { display: block; }

/* ---- menus (ui_menus.js) ---- */
#menus { position: fixed; inset: 0; z-index: 26; pointer-events: none; }
#menus > * { pointer-events: auto; }
#menus:empty { display: none; }
#menus, #menus * { image-rendering: pixelated; }

.mn-screen {
  position: fixed; inset: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 10px;
}
.mn-title { background: url('/assets/graphics/ui/title.png?v=1') center / cover no-repeat #000; justify-content: flex-end; padding-bottom: 7vh; }
.mn-bg { background: url('/assets/graphics/ui/Menu_background_without_title.png?v=1') center / cover no-repeat #000; }
.mn-overlay { background: rgba(0, 0, 0, .55); }
.mn-over { background-color: #000; background-position: center; background-repeat: no-repeat; background-size: contain; justify-content: flex-end; padding-bottom: 4vh; }

.mn-panel {
  background: url('/assets/graphics/ui/human/panel_2.png?v=1');
  background-size: 100% 100%;
  padding: 26px 30px;
  min-width: 430px; max-width: 92vw; max-height: 92vh;
  overflow: auto;
  box-shadow: 0 8px 40px #000;
}
.mn-narrow { min-width: 300px; }
.mn-wide { min-width: 640px; }
.mn-room { min-width: min(960px, 94vw); }
.mn-h {
  font: bold 20px 'Palatino Linotype', Georgia, serif; letter-spacing: 3px;
  color: #ffd75e; text-shadow: 1px 2px 3px #000; text-align: center; margin-bottom: 12px;
}
.mn-sub { font: bold 13px Georgia, serif; color: #c8a850; margin: 10px 0 4px; letter-spacing: 1px; }
.mn-stack { display: flex; flex-direction: column; gap: 10px; align-items: center; }
.mn-row { display: flex; gap: 10px; align-items: center; justify-content: center; margin-top: 14px; flex-wrap: wrap; }
.mn-cols { display: flex; gap: 22px; flex-wrap: wrap; }
.mn-col { flex: 1 1 380px; min-width: 320px; }
.mn-col-map { flex: 0 0 200px; }
.mn-dim { color: #9a8a60; font-size: 12px; }
.mn-credits {
  position: absolute; bottom: 6px; left: 0; right: 0; text-align: center;
  font: 11px Georgia, serif; color: #8a7a50; text-shadow: 1px 1px #000;
}

.mn-btn {
  width: 224px; height: 28px; border: 0; cursor: pointer;
  background: url('/assets/graphics/ui/human/widgets/button-medium-normal.png?v=1') center / 100% 100% no-repeat;
  font: bold 12px 'Palatino Linotype', Georgia, serif;
  color: #ffd75e; text-shadow: 1px 1px #000;
  image-rendering: pixelated;
  width: 164px;
}
.mn-btn.mn-large { width: 224px; background-image: url('/assets/graphics/ui/human/widgets/button-large-normal.png?v=1'); }
.mn-btn.mn-small { width: 106px; background-image: url('/assets/graphics/ui/human/widgets/button-small-normal.png?v=1'); }
.mn-btn:hover:not(:disabled) { color: #fff; }
.mn-btn:active:not(:disabled) { background-image: url('/assets/graphics/ui/human/widgets/button-medium-pressed.png?v=1'); }
.mn-btn.mn-large:active:not(:disabled) { background-image: url('/assets/graphics/ui/human/widgets/button-large-pressed.png?v=1'); }
.mn-btn.mn-small:active:not(:disabled) { background-image: url('/assets/graphics/ui/human/widgets/button-small-pressed.png?v=1'); }
.mn-btn:disabled, .mn-btn.mn-grayed {
  background-image: url('/assets/graphics/ui/human/widgets/button-medium-grayed.png?v=1');
  color: #786848; cursor: default;
}
.mn-btn.mn-large:disabled { background-image: url('/assets/graphics/ui/human/widgets/button-large-grayed.png?v=1'); }

.mn-input {
  background: #14100a; border: 1px solid #665c33; color: #ffe9a8;
  font: 13px 'Palatino Linotype', Georgia, serif; padding: 5px 8px; outline: none;
  min-width: 120px;
}
.mn-name { margin-top: 8px; font: 12px Georgia, serif; color: #c8b070; display: flex; gap: 8px; align-items: center; }

select, #menus select {
  background: #14100a; color: #e8d8a0; border: 1px solid #665c33;
  font: 12px Georgia, serif; padding: 2px 4px; max-width: 130px;
}
select:disabled { color: #786848; }
input[type=range] { accent-color: #c8a850; }
input[type=checkbox] { accent-color: #c8a850; width: 15px; height: 15px; }

.mn-roomlist { min-height: 120px; max-height: 40vh; overflow: auto; border: 1px solid #46381c; background: rgba(8, 6, 2, .5); padding: 6px; }
.mn-roomrow { display: grid; grid-template-columns: 1fr 2fr 50px 110px; gap: 8px; align-items: center; padding: 4px 6px; border-bottom: 1px solid #2a2210; font-size: 13px; }
.mn-code { font: bold 13px monospace; color: #ffd75e; letter-spacing: 2px; }

.rm-slot { display: grid; grid-template-columns: 20px 1fr 106px 84px 80px 106px; gap: 5px; align-items: center; padding: 3px 0; font-size: 12px; }
.rm-num { color: #8a7a50; }
.rm-name { color: #e8d8a0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rm-name.rm-you { color: #ffd75e; font-weight: bold; }
.rm-opt { display: flex; justify-content: space-between; align-items: center; gap: 10px; padding: 3px 0; font-size: 12px; color: #c8b070; }
.mn-chat { height: 110px; overflow: auto; border: 1px solid #46381c; background: rgba(8, 6, 2, .5); padding: 4px 8px; font-size: 12px; }
.mn-chatin { width: 100%; margin-top: 4px; }
.mn-preview { width: 176px; height: 176px; image-rendering: pixelated; border: 2px solid #46381c; background: #101008; }

.mn-picker { position: fixed; inset: 0; background: rgba(0, 0, 0, .6); display: flex; align-items: center; justify-content: center; }
.mn-pickerbox { min-width: min(860px, 92vw); }
.pk-list { flex: 1; max-height: 52vh; overflow: auto; border: 1px solid #46381c; background: rgba(8, 6, 2, .5); }
.pk-row { padding: 4px 8px; cursor: pointer; font-size: 13px; border-bottom: 1px solid #201808; }
.pk-row:hover { background: #2a2210; }
.pk-row.sel { background: #3a3018; color: #ffd75e; }

.mn-toast {
  position: fixed; top: 12%; left: 50%; transform: translateX(-50%);
  background: rgba(60, 8, 4, .92); border: 1px solid #a03020; color: #ffb0a0;
  padding: 8px 22px; font: 14px Georgia, serif; opacity: 0; transition: opacity .25s;
  pointer-events: none; z-index: 40;
}
.mn-toast.on { opacity: 1; }

.mn-overpanel { min-width: min(680px, 92vw); }
.ov-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.ov-table th { color: #c8a850; text-align: left; border-bottom: 1px solid #665c33; padding: 3px 8px; }
.ov-table td { padding: 3px 8px; border-bottom: 1px solid #2a2210; }
/* player-colored name cells: shadow keeps the darker legit hues (red/blue)
   readable on the dark panel (chat-log gets the same treatment) */
.ov-table td:first-child { text-shadow: 1px 1px 2px #000; }
.ov-table tr.ov-me td { background: rgba(200, 168, 80, .12); }
.ov-win { color: #ffe37a; }
.ov-loss { color: #ff5040; }

/* ---- replay viewer (SPEC §10): playback bar + replays browser list ---- */
#replaybar {
  position: fixed; left: 50%; bottom: calc(16px * var(--wii-hud) + 10px);
  transform: translateX(-50%);
  display: flex; align-items: center; gap: 10px;
  background: rgba(12, 10, 6, .92); border: 2px solid #8a7433; border-radius: 6px;
  padding: 6px 14px; z-index: 24;
  font: 12px monospace; color: #e8d8a0;
  max-width: 96vw;
}
#replaybar button {
  background: #2a2416; color: #ffd75e; border: 1px solid #665c33;
  cursor: pointer; font: 12px monospace; padding: 3px 8px; white-space: nowrap;
}
#replaybar button:hover { color: #fff; }
#rb-play { min-width: 34px; }
#rb-speeds { display: flex; gap: 3px; }
#rb-speeds button.on { background: #5a4a20; color: #fff; }
#rb-slider { width: min(34vw, 420px); accent-color: #c8a850; }
/* cycle/time are quoted in bug reports — keep them selectable */
#rb-time, #rb-cycle { user-select: text; -webkit-user-select: text; white-space: nowrap; }
#rb-cycle { color: #9fd8ff; cursor: pointer; }
#rb-cycle:hover { color: #d8f0ff; }
#rb-warn { color: #ffb040; cursor: help; }

.rp-row {
  display: grid; grid-template-columns: 1.4fr 1fr 1.6fr 44px 1fr 226px;
  gap: 8px; align-items: center; padding: 4px 6px;
  border-bottom: 1px solid #2a2210; font-size: 13px;
}
.rp-map { color: #ffd75e; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rp-when { font-size: 11px; }
.rp-players { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rp-live { color: #7fff7f; font-size: 11px; border: 1px solid #3a6a3a; border-radius: 3px; padding: 0 4px; }
.rp-btns { display: flex; gap: 5px; justify-content: flex-end; }

/* ---- touch / mobile layout (html.touch — set by index.html) --------------
   Phones & tablets. The game view lives BETWEEN two strips (owner directive):
   a top resource strip (with the MENU button) and ONE full-width bottom bar
   (minimap | selection | commands) on a shared dark background with a thin
   gold top border. The 512px-wide panel group scales via --wii-mob (set by
   ui_hud.js on resize; #wii-barbg is the full-width strip behind it). The
   status line is PLAIN TEXT (no art) just above the bar. WC2 panel art is
   dropped on touch in favor of clean dark strips. Desktop is untouched. */

html.touch canvas#gl,
html.coarse canvas#gl { touch-action: none; }
/* bottom-bar layout: the canvas SHRINKS between the two opaque strips instead
   of hiding under them — cam.setViewport/clamp then measure the truly visible
   area, so the map's FIRST and LAST rows are reachable (W17: 3.63 tile rows
   were permanently hidden under the bar) and minimap jumps land visible.
   main.js re-runs resize() via a ResizeObserver on the canvas. NOTE: an
   explicit height calc, NOT top+bottom insets with height:auto — canvas is a
   replaced element, so height:auto resolves to its intrinsic (attribute) size
   and `bottom` is ignored (CSS2 §10.6.5). */
html.touch canvas#gl {
  top: calc(44px + env(safe-area-inset-top, 0px));
  height: calc(100% - 44px - env(safe-area-inset-top, 0px)
    - 166px * var(--wii-mob, 1) - env(safe-area-inset-bottom, 0px));
}
html.touch button, html.touch .cmd-btn, html.touch .sel-chip { touch-action: manipulation; }

/* full-width strip behind the scaled panel group (created by ui_hud.js) */
html.touch #wii-barbg {
  display: block;
  position: fixed; left: 0; right: 0; bottom: 0;
  height: calc(166px * var(--wii-mob, 1) + env(safe-area-inset-bottom, 0px));
  /* real WC2 art: statusline ledge + quilted buttonpanel body, horizontally
     seamless per-race tiles (build/gen_ui_barbg.mjs). The texture's own black
     outline row sits under the gold border and its bottom rows fade into
     #0b0905, so the safe-area extension blends invisibly. */
  background: #0b0905 url('/assets/graphics/ui/human/barbg.png?v=1') left top repeat-x;
  background-size: auto 100%;
  border-top: 1px solid #8a7433;
  box-shadow: 0 -3px 10px rgba(0, 0, 0, .55);
}
html.touch #hud.hud-orc #wii-barbg { background-image: url('/assets/graphics/ui/orc/barbg.png?v=1'); }

html.touch #left {
  top: auto; left: 50%; bottom: env(safe-area-inset-bottom, 0);
  width: 512px;
  transform: translateX(-50%) scale(var(--wii-mob, 1));
  transform-origin: bottom center;
  display: flex; align-items: stretch; justify-content: center; gap: 4px;
}
/* three sections, ONE shared height — no ragged top edge */
html.touch #minimap, html.touch #selection, html.touch #commands { flex: none; height: 166px; }
html.touch #minimap { width: 136px; }
html.touch #selection { width: 192px; border-left: 1px solid rgba(138, 116, 51, .35); border-right: 1px solid rgba(138, 116, 51, .35); }
html.touch #commands { width: 176px; }
html.touch .mm-menubtn { display: none; }        /* MENU lives in the top bar */
html.coarse .mm-f10 { display: none; }           /* no keyboard on coarse-pointer devices (input, not layout) */
html.touch .mm-frame { width: 136px; height: 166px; background: none; }
html.touch .mm-frame canvas { left: 4px; top: 19px; }
html.touch .sel-panel { width: 100%; height: 166px; background: none; }
html.touch .sel-body { inset: 6px 7px; }        /* 176px inner: 5 dense 35px chips per row (#selection's 1px side borders eat 2px) */
html.touch .cmd-panel { width: 176px; height: 166px; background: none; }
html.touch .cmd-btn.p1, html.touch .cmd-btn.p2, html.touch .cmd-btn.p3 { top: 14px; }
html.touch .cmd-btn.p4, html.touch .cmd-btn.p5, html.touch .cmd-btn.p6 { top: 61px; }
html.touch .cmd-btn.p7, html.touch .cmd-btn.p8, html.touch .cmd-btn.p9 { top: 108px; }
/* invisible hit slop: grow each button's border box to the full 56x48 grid
   pitch (transparent border, margin pulls the box back so icons don't move;
   whole px — Chrome floors fractional border widths) → >=32px effective tap
   height even at --wii-mob 0.695 (360px portrait) */
html.touch .cmd-btn {
  box-sizing: content-box;
  border: 3px solid transparent;
  margin: -3px;
}
html.touch .cmd-btn.cmd-lack::after { inset: 2px; }

/* bar internals: bigger type so the 0.6-1.0 scale stays legible */
html.touch .sel-name { font-size: 16px; padding-top: 2px; }
html.touch .sel-hptext { font: 11px monospace; }
html.touch .sel-manalabel { font-size: 12px; }
html.touch .sel-manabar { height: 16px; }
html.touch .sel-mananum { font: bold 11px/14px monospace; }
html.touch .sel-stats {
  margin-top: 3px;
  display: grid; grid-template-columns: 1fr 1fr; gap: 0 10px;
  font: 13px/1.5 'Palatino Linotype', Georgia, serif;
}
html.touch .sel-stat { padding: 0; }
/* 18px line = 20px height minus the 2px borders — label stays ON the bar */
html.touch .sel-progress { left: 0; right: 0; bottom: 0; height: 20px; font: 11px/18px monospace; }
/* multi-select chips: zero dead gaps — every chip's hit box tiles the grid
   (transparent padding, icons keep their size); 5 dense chips per row, 18 fit */
html.touch .sel-multi { gap: 0; align-content: flex-start; }
html.touch .sel-multi .sel-chip { padding: 3px 2px; }
html.touch .sel-dense .sel-chip { width: 35px; padding: 3px 1px; }
html.touch .cmd-key { font: bold 12px monospace; right: 3px; bottom: 2px; }

/* top strip: the only other UI band — taller (comfortable thumb reach for
   MENU, the sole in-game route to options/resign/chat), plain, MENU pinned
   right and nearly filling the bar (>=36px tap target, judge R1 finding) */
html.touch #resources {
  width: 100%; transform: none;
  height: calc(44px + env(safe-area-inset-top, 0px));
  /* right padding reserves the absolutely-pinned MENU button's lane — growing
     resource numbers can NEVER push MENU off-screen (judge2 360px finding) */
  padding: env(safe-area-inset-top, 0px) calc(98px + env(safe-area-inset-right, 0px)) 0 10px;
  gap: min(2.6vw, 20px);
  overflow: hidden;
  font: bold clamp(11px, 3.6vw, 14px)/1 'Palatino Linotype', Georgia, serif;
  font-variant-numeric: tabular-nums;
  background: linear-gradient(#17120a, #0b0905 80%);
  border-bottom: 1px solid #8a7433;
}
html.touch .res-item { flex: 0 1 auto; min-width: 0; }
/* narrow phones: drop the least important item (score) so gold/wood/oil/food
   always fit next to MENU even with late-game numbers */
@media (max-width: 430px) {
  html.touch .res-item:has(.ri-score) { display: none; }
}
#wii-mobmenu { display: none; }
html.touch #wii-mobmenu {
  display: block; flex: none;
  position: absolute;
  right: calc(6px + env(safe-area-inset-right, 0px));
  top: calc(4px + env(safe-area-inset-top, 0px));
  height: 36px; min-width: 76px; padding: 0 16px;
  background: #241c0e; color: #ffd75e;
  border: 1px solid #8a7433; border-radius: 5px;
  font: bold 13px 'Palatino Linotype', Georgia, serif;
  letter-spacing: 1px; cursor: pointer;
}
html.touch #wii-mobmenu:active { background: #3a3018; }

/* status line: PLAIN text over the game, no art, above the bottom bar */
html.touch #wii-status {
  left: 0; right: 0;
  bottom: calc(166px * var(--wii-mob, 1) + env(safe-area-inset-bottom, 0px) + 2px);
  height: 20px;
  background: none;
  font: bold 13px/20px 'Palatino Linotype', Georgia, serif;
  color: #f5e6b0;
  text-shadow: 0 1px 2px #000, 0 0 4px #000, 1px 1px 2px #000;
  text-align: center;
  padding: 0 8px;
}
html.touch #wii-status.st-alert { color: #ff5545; }   /* alerts stay red (beats the touch color) */
html.touch .st-costs .res-ico { transform: none; }

/* chat: top-left under the resource bar (bottom is HUD now) */
html.touch #chat {
  left: 8px; bottom: auto;
  top: calc(50px + env(safe-area-inset-top, 0px));
  width: 62%;
  font: 11px/1.5 'Palatino Linotype', Georgia, serif;
}

html.touch #replaybar {
  bottom: calc(166px * var(--wii-mob, 1) + env(safe-area-inset-bottom, 0px) + 26px);
  padding: 8px 14px;
}
html.touch #replaybar button { padding: 6px 10px; }

/* Preferences → Show command keys off */
body.hud-nokeys .cmd-key { display: none; }

/* ---- menus on touch: everything fits 360px portrait, no horizontal page
   scroll. WC2 art panels stay but columns stack and slot rows wrap. */
html.touch .mn-panel { min-width: 0; width: min(430px, 96vw); max-width: 96vw; padding: 16px 12px; max-height: 94vh; }
html.touch .mn-wide { width: min(640px, 96vw); }
html.touch .mn-room { width: min(960px, 96vw); }
html.touch .mn-pickerbox { width: min(860px, 96vw); }
html.touch .mn-roomlist { max-height: 34vh; }
html.touch .mn-roomrow { grid-template-columns: 60px 1fr 40px 92px; }
html.touch .mn-roomrow span:nth-child(3) { display: none; }   /* map name — no room at 360 */
html.touch select, html.touch #menus select { padding: 6px 4px; font-size: 13px; }
html.touch .mn-btn { height: 34px; }
html.touch .mn-btn.mn-small { height: 34px; }

/* options rows are <label>s (ui_menus.js) — the WHOLE row toggles its
   checkbox; controls themselves grow to thumb size (judge R3 finding) */
html.touch .rm-opt { min-height: 36px; padding: 4px 0; }
html.touch .rm-opt > span:last-child { display: inline-flex; align-items: center; gap: 8px; }
html.touch input[type=checkbox] { width: 24px; height: 24px; flex: none; }
html.touch input[type=range] { height: 36px; }

/* main menu: don't crop the title art; scrim the button stack + credits so
   they never mix with the art's baked-in text */
html.touch .mn-title { background-size: contain; background-position: center top; padding-bottom: 3vh; }
html.touch .mn-title .mn-stack { background: rgba(0, 0, 0, .74); border: 1px solid rgba(138, 116, 51, .4); border-radius: 8px; padding: 14px 18px; }
html.touch .mn-credits { font-size: 9px; background: rgba(0, 0, 0, .74); padding: 2px 0; }

/* room screen: columns stack, Start Game row right under the title (never
   below the fold), slot rows fit the width — one line when it fits, a clean
   name-row + selects-row break on narrow phones */
html.touch .mn-cols { flex-direction: column; gap: 12px; }
html.touch .mn-col, html.touch .mn-col-map { flex: none; min-width: 0; width: 100%; }
html.touch .mn-room { display: flex; flex-direction: column; }
html.touch .mn-room > .mn-h { order: 0; }
html.touch .mn-room > .mn-row { order: 1; margin-top: 6px; margin-bottom: 8px; flex-wrap: nowrap; }
html.touch .mn-room > .mn-row .mn-btn { flex: 0 1 auto; min-width: 90px; }
html.touch .mn-room > .mn-cols { order: 2; }
html.touch .rm-slot {
  display: flex; flex-wrap: wrap; gap: 3px 5px; align-items: center;
  padding: 6px 0; border-bottom: 1px solid #241c0e; font-size: 13px;
}
html.touch .rm-slot .rm-num { flex: none; }
html.touch .rm-slot .rm-typecell { flex: 1 1 auto; min-width: 100px; }
html.touch .rm-slot select, html.touch .rm-slot .rm-ai-x { flex: 0 1 108px; min-width: 62px; max-width: none; }
@media (max-width: 700px) {
  /* narrow: force the break after the name — line 1 = number + name/type,
     line 2 = the four selects sharing the row evenly */
  html.touch .rm-slot .rm-typecell { flex: 1 1 calc(100% - 40px); }
  html.touch .rm-slot select, html.touch .rm-slot .rm-ai-x { flex: 1 1 calc(25% - 8px); }
}
html.touch .mn-chat { height: 90px; }

/* map picker: ONE scroller (the list) — the panel is a flex column with
   overflow hidden, so Select/Cancel are ALWAYS on screen (no double-scroll,
   no confirm below the fold — judge R4 finding). Portrait stacks list over
   preview; landscape keeps list | preview side by side. */
html.touch .mn-pickerbox { display: flex; flex-direction: column; overflow: hidden; }
html.touch .mn-pickerbox .mn-cols { flex: 1 1 auto; min-height: 0; overflow: hidden; flex-wrap: nowrap; }
html.touch .mn-pickerbox .pk-list { flex: 1 1 auto; width: 100%; min-height: 72px; max-height: none; }
html.touch .mn-pickerbox .mn-col-map { flex: none; }
html.touch .mn-pickerbox > .mn-row { flex: none; margin-top: 8px; }
html.touch .pk-row { padding: 10px 8px; }
@media (orientation: landscape) {
  html.touch .mn-pickerbox .mn-cols { flex-direction: row; }
  html.touch .mn-pickerbox .pk-list { width: auto; }
  html.touch .mn-pickerbox .mn-col-map { width: 176px; }
  html.touch .mn-pickerbox .mn-preview { width: 132px; height: 132px; }
}

/* game over: the stats table scrolls INSIDE the panel, never the page */
html.touch .mn-overpanel { width: 96vw; min-width: 0; }
html.touch .ov-wrap { overflow-x: auto; max-width: 100%; -webkit-overflow-scrolling: touch; }
html.touch .ov-table { font-size: 12px; }
html.touch .ov-table th, html.touch .ov-table td { padding: 3px 5px; white-space: nowrap; }

/* ---- FPS / debug overlay (?dev=1 / ?fps=1) ---- */
#fps {
  display: none;
  position: fixed; top: 4px; right: 8px; z-index: 40;
  font: 12px/1.4 monospace;
  color: #7fff7f;
  text-shadow: 0 1px 2px #000;
  pointer-events: none;
}
#fps.on { display: block; }

/* ---- loading screen ---- */
#loading {
  position: fixed; inset: 0; z-index: 30;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 14px;
  background: #000;
  transition: opacity .35s ease;
}
#loading.done { opacity: 0; pointer-events: none; }
#loading-title {
  font-size: 34px; letter-spacing: 8px; font-weight: bold;
  color: #c8a850;
  text-shadow: 0 2px 6px #402800, 0 0 24px #604010;
}
#loading-label { font-size: 14px; color: #907850; min-height: 18px; }
#loading-label.error { color: #ff6a5a; max-width: 70%; text-align: center; }
#loading-bar {
  width: 320px; height: 14px;
  border: 1px solid #705828;
  background: #181008;
  box-shadow: inset 0 1px 3px #000;
}
#loading-fill {
  width: 0%; height: 100%;
  background: linear-gradient(#b89040, #806020);
  transition: width .15s linear;
}
