/* The Perfect General II -- the console.

   The whole interface is a MAP TABLE seen from above: a lithographed staff
   sheet held down on dark waxed oak, with a brass-tracked order rack beside
   it. Two rules follow from that and are worth stating because they are the
   reason this does not look like every other browser wargame:

   1. The paper is the only light surface. Everything else is oak and brass.
      That inverts the usual cream-background layout -- here the cream IS the
      map, and it is surrounded rather than surrounding.
   2. Nothing glows. There is no lighting in a printed sheet, so no gradients
      pretending to be light, no glass, no blur. Depth comes from a shadow
      under a counter and from the fact that brass sits ON the wood.

   Type does two jobs and is set to say which: surveyor's lettering (wide,
   uppercase, letterspaced sans) for anything printed on the map or engraved
   on the console, and a typewriter face for anything a staff officer typed --
   the order slate, the odds strip, the log. Nothing uses both. */

:root {
  --oak: #241C15;
  --oak-lit: #33281E;
  --oak-deep: #17110C;
  --brass: #C2933F;
  --brass-dim: #8A6A2E;
  --paper: #D8CEB3;
  --ink: #2E261C;
  --red: #A0392A;
  --blue: #2F5372;
  --field: #BFC49A;

  --lettering: "Trebuchet MS", "Segoe UI", system-ui, -apple-system, sans-serif;
  --typed: ui-monospace, "DejaVu Sans Mono", Menlo, Consolas, monospace;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  height: 100%;
  background: var(--oak-deep);
  color: var(--paper);
  font-family: var(--lettering);
  overflow: hidden;
}

button {
  font-family: inherit;
  color: inherit;
  cursor: pointer;
}

/* --------------------------------------------------------------- console */

#table {
  display: grid;
  /* minmax(0, 1fr), NOT 1fr. A 1fr track's automatic minimum is the MIN-CONTENT
     of its items, so the order rack's peg row and button strip pushed the whole
     console to 642 px inside a 430 px phone and the right of the map was simply
     unreachable. This is the third build in this line to hit it. */
  grid-template-columns: minmax(0, 1fr) 330px;
  grid-template-rows: 46px minmax(0, 1fr);
  height: 100vh;
  background:
    repeating-linear-gradient(92deg, rgba(0,0,0,0.16) 0 2px, rgba(255,255,255,0.014) 2px 7px),
    linear-gradient(180deg, var(--oak-lit), var(--oak));
}

#rail {
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 0 12px;
  min-width: 0;
  overflow-x: auto;
  scrollbar-width: none;
  border-bottom: 2px solid var(--brass-dim);
  background: linear-gradient(180deg, rgba(255,255,255,0.05), rgba(0,0,0,0.28));
}

#rail .mark {
  font-size: 13px;
  letter-spacing: 0.30em;
  text-transform: uppercase;
  color: var(--brass);
  font-weight: 700;
}

#rail .sep { flex: 1; }

#rail .score {
  font-family: var(--typed);
  font-size: 14px;
  letter-spacing: 0.05em;
}
#rail .score b { color: var(--brass); }
#rail .score .r { color: #E08C79; }
#rail .score .b { color: #8FB4D2; }

.chip {
  border: 1px solid var(--brass-dim);
  background: rgba(194,147,63,0.10);
  color: var(--paper);
  padding: 5px 11px;
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  border-radius: 2px;
}
.chip:hover { background: rgba(194,147,63,0.24); }
.chip:disabled { opacity: 0.35; cursor: default; }
.chip.hot { background: var(--brass); color: #241C15; font-weight: 700; }
.chip:focus-visible { outline: 2px solid var(--brass); outline-offset: 2px; }

/* ------------------------------------------------------------- map sheet */

#sheet {
  position: relative;
  min-width: 0;
  min-height: 0;
  margin: 12px;
  border: 1px solid rgba(0,0,0,0.5);
  box-shadow: 0 10px 26px rgba(0,0,0,0.55), 0 0 0 7px var(--oak-lit), 0 0 0 9px var(--brass-dim);
  background: var(--paper);
  overflow: hidden;
}

#map {
  display: block;
  width: 100%;
  height: 100%;
  cursor: grab;
  /* The browser's own pan and pinch would fight the map's, and on a touch
     screen it would win. */
  touch-action: none;
}

#zoombar {
  position: absolute;
  right: 10px;
  top: 10px;
  display: flex;
  gap: 4px;
}

.zbtn {
  font-family: var(--typed);
  font-size: 13px;
  min-width: 30px;
  height: 28px;
  padding: 0 8px;
  color: var(--paper);
  background: rgba(36,28,21,0.88);
  border: 1px solid var(--brass-dim);
  border-radius: 2px;
}
.zbtn:hover { background: rgba(194,147,63,0.30); }
.zbtn:focus-visible { outline: 2px solid var(--brass); outline-offset: 2px; }

#legend {
  position: absolute;
  left: 10px;
  bottom: 10px;
  font-family: var(--typed);
  font-size: 11px;
  color: var(--ink);
  background: rgba(216,206,179,0.88);
  border: 1px solid rgba(46,38,28,0.4);
  padding: 5px 8px;
  pointer-events: none;
  max-width: 62%;
}

/* ------------------------------------------------------- the order rack */

#rack {
  margin: 12px 12px 12px 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
  min-width: 0;
  overflow-y: auto;
}

/* The peg rack is the one row that will not shrink on its own. */
#slate .pegs { min-width: 0; }
.panel { min-width: 0; }

.panel {
  border: 1px solid rgba(0,0,0,0.45);
  border-top: 1px solid rgba(255,255,255,0.07);
  background: linear-gradient(180deg, rgba(255,255,255,0.035), rgba(0,0,0,0.20));
  padding: 10px 11px;
}

.panel h2 {
  margin: 0 0 8px;
  font-size: 10px;
  letter-spacing: 0.26em;
  text-transform: uppercase;
  color: var(--brass);
  font-weight: 700;
}

/* THE SIGNATURE. The order allowance is a rack of brass pegs that visibly
   empties as it is spent. It is the one place in the interface allowed to be
   emphatic, because the whole game is about this number being smaller than
   the army it commands. */
#slate .pegs {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: 8px;
}

.peg {
  width: 17px;
  height: 26px;
  border-radius: 2px 2px 5px 5px;
  background: linear-gradient(180deg, #E8C579, var(--brass) 45%, var(--brass-dim));
  box-shadow: inset 0 -3px 4px rgba(0,0,0,0.35), 0 1px 2px rgba(0,0,0,0.5);
  transition: transform 180ms ease, opacity 180ms ease;
}
.peg.spent {
  background: none;
  border: 1px dashed rgba(194,147,63,0.42);
  box-shadow: none;
  transform: translateY(4px);
  opacity: 0.5;
}
.peg.arty {
  border-radius: 50% 50% 3px 3px;
  background: linear-gradient(180deg, #D2A8C0, #8E5F79 45%, #63404F);
}
.peg.arty.spent { background: none; border: 1px dashed rgba(142,95,121,0.5); }

#slate .count {
  font-family: var(--typed);
  font-size: 13px;
  color: var(--paper);
}
#slate .count b { color: var(--brass); font-size: 17px; }
#slate .warn { color: #E0A07A; }

/* --------------------------------------------------------- the odds strip */

/* The shot the player reads BEFORE committing, resolved by exactly the same
   arithmetic the engine will use. A wargame that shows you different odds
   from the ones it rolls has told you a lie. */
#strip .head {
  font-family: var(--typed);
  font-size: 12px;
  color: var(--paper);
  margin-bottom: 7px;
  line-height: 1.5;
}
#strip .odds {
  color: var(--brass);
  font-size: 18px;
  font-weight: 700;
}
#strip table {
  width: 100%;
  border-collapse: collapse;
  font-family: var(--typed);
  font-size: 11px;
}
#strip th {
  text-align: left;
  color: var(--brass-dim);
  font-weight: 400;
  letter-spacing: 0.10em;
  padding-bottom: 3px;
  border-bottom: 1px solid rgba(194,147,63,0.30);
}
#strip td { padding: 2px 0; color: #CFC5AA; }
#strip td:first-child { color: var(--brass-dim); }
#strip tr.rolled td { color: #F0DCA8; background: rgba(194,147,63,0.16); }
#strip .none { font-family: var(--typed); font-size: 12px; color: #9A8E76; }

/* ------------------------------------------------------------- unit card */

#card .name {
  font-size: 14px;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  margin-bottom: 5px;
}
#card .note {
  font-size: 12px;
  line-height: 1.45;
  color: #B8AC92;
  margin-bottom: 7px;
}
#card .stats {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 5px;
  font-family: var(--typed);
  font-size: 11px;
}
#card .stats div { border: 1px solid rgba(194,147,63,0.22); padding: 3px 5px; }
#card .stats span { display: block; color: var(--brass-dim); font-size: 9px; letter-spacing: 0.10em; }

#acts { display: flex; flex-wrap: wrap; gap: 5px; align-items: flex-start; }
#acts h2 { flex-basis: 100%; margin-bottom: 4px; }
#acts .note { flex-basis: 100%; font-size: 12px; color: #B8AC92; }

/* ------------------------------------------------------------------ log */

#log {
  flex: 1;
  overflow-y: auto;
  font-family: var(--typed);
  font-size: 11px;
  line-height: 1.6;
  color: #B8AC92;
  min-height: 60px;
}
#log div { border-bottom: 1px dotted rgba(194,147,63,0.16); padding: 2px 0; }
#log .r { color: #E08C79; }
#log .b { color: #8FB4D2; }

/* ------------------------------------------------------------ requisition */

#shop { display: none; }
#shop.open { display: block; }

.buylist { max-height: 34vh; overflow-y: auto; }
.buyrow {
  display: grid;
  grid-template-columns: 1fr 42px 30px;
  gap: 6px;
  align-items: center;
  font-family: var(--typed);
  font-size: 11px;
  padding: 3px 0;
  border-bottom: 1px dotted rgba(194,147,63,0.14);
}
.buyrow .cost { color: var(--brass); text-align: right; }
.buyrow button { width: 100%; padding: 2px 0; }
.bought { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 7px; }
.tag {
  font-family: var(--typed);
  font-size: 10px;
  border: 1px solid var(--brass-dim);
  padding: 2px 5px;
  background: rgba(194,147,63,0.10);
}
.tag.next { background: var(--brass); color: #241C15; font-weight: 700; }

/* --------------------------------------------------------------- curtain */

#curtain {
  position: fixed;
  inset: 0;
  background: linear-gradient(180deg, var(--oak-lit), var(--oak-deep));
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  z-index: 20;
  overflow-y: auto;
}
#curtain.gone { display: none; }

.card {
  max-width: 760px;
  width: 100%;
  border: 1px solid var(--brass-dim);
  background: rgba(0,0,0,0.26);
  padding: 26px 28px;
  box-shadow: 0 18px 50px rgba(0,0,0,0.6);
}

.card .eyebrow {
  font-size: 10px;
  letter-spacing: 0.42em;
  text-transform: uppercase;
  color: var(--brass-dim);
}
.card h1 {
  margin: 6px 0 2px;
  font-size: 36px;
  line-height: 1.02;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  font-weight: 700;
}
.card .sub {
  font-family: var(--typed);
  font-size: 13px;
  color: var(--brass);
  margin-bottom: 16px;
}
.card p {
  font-size: 13.5px;
  line-height: 1.62;
  color: #C3B79C;
  margin: 0 0 12px;
}
.card .fine { font-size: 11.5px; color: #8E8370; }

.choices { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: 8px; margin: 14px 0; }
.choice {
  text-align: left;
  border: 1px solid rgba(194,147,63,0.34);
  background: rgba(194,147,63,0.06);
  padding: 9px 11px;
}
.choice:hover, .choice.on { background: rgba(194,147,63,0.20); border-color: var(--brass); }
.choice b { display: block; font-size: 13px; letter-spacing: 0.10em; text-transform: uppercase; margin-bottom: 3px; }
.choice span { font-family: var(--typed); font-size: 11px; color: #A99C82; line-height: 1.45; }

.go {
  display: inline-block;
  margin-top: 6px;
  border: 1px solid var(--brass);
  background: var(--brass);
  color: #241C15;
  font-weight: 700;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  font-size: 12px;
  padding: 10px 26px;
}
.go:hover { background: #E0B25A; }

@media (max-width: 900px) {
  #table {
    grid-template-columns: minmax(0, 1fr);
    /* The sheet gets the lion's share and the rack is scrollable underneath;
       giving the rack `auto` let its own content decide the split, which on a
       small glass left the map a letterbox. */
    grid-template-rows: 46px minmax(0, 1fr) minmax(0, 0.85fr);
  }
  #rack { margin: 0 10px 10px; }
  #sheet { margin: 10px 10px 0; }
  #rail .mark { font-size: 11px; letter-spacing: 0.18em; }
  .chip { padding: 5px 8px; font-size: 10px; }
}

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; }
}
