/* 1934, after dark.
   ────────────────────────────────────────────────────────────────────────────
   ONE MOTIF, EVERYWHERE: THE PLACARD.

   The whole interface is handbills nailed up in the dark. Every surface that
   talks to you is the same object — cream poster stock, a heavy ink border, a
   gold rule printed just inside it, Playbill display type, and a letterspaced
   monospace kicker in tent-red. It is the curtain placard, repeated.

   The rule that keeps it from turning into a scrapbook:
     the WORLD is black — the night, the road, the ring, the map, the fog;
     the PAPER is what the show puts in front of you.
   Light only ever comes from a bulb: gold, warm, and slightly unreliable. */

:root{
  /* ---- the night ---- */
  --ink:#14110e;          /* the ink everything is printed in. never pure black */
  --ink2:#5c5140;         /* faded ink — small print */
  --ink3:#8a7d64;         /* the print that has weathered off */
  --canvas:#171a1c;       /* tent canvas by moonlight — cold, not brown */
  --canvas2:#0f1113;
  --night:#07080a;
  --line2:#2b2924;

  /* ---- the paper ---- */
  --paper:#e6dcc2;
  --paper2:#cdbc9a;
  --paper3:#bfab85;       /* the shadowed fold */

  /* ---- the ink that is not black ---- */
  --red:#8f3020;          /* the tent stripe. the kicker. */
  --red2:#a8301f;
  --gold:#c9a227;         /* the rule printed inside the border */
  --glow:#ffcf62;         /* what a bulb actually throws */
  --cream:#e7dcc6;        /* type ON the dark */
  --dim:#8a8072;
  --green:#5d7f52;
  --spook:#7fa88c;        /* cold green. a way out. used almost nowhere. */

  --radius:2px;           /* period signage is square. this is nearly a lie. */

  /* ---- THE PLACARD ---- the one recipe, reused by every panel on the site.
     The stock is NOT clean. It has been in a truck since '31: foxed, stained,
     and lit by a single bulb hung above it — bright across the top, going brown
     into the corners. That unevenness is what keeps a screen full of cream paper
     ominous instead of cheerful. */
  --plate:
    radial-gradient(100% 85% at 50% -12%, rgba(255,246,216,.60), transparent 62%),
    radial-gradient(55% 45% at 12% 88%, rgba(122,96,58,.20), transparent 70%),
    radial-gradient(45% 40% at 88% 22%, rgba(122,96,58,.15), transparent 70%),
    radial-gradient(30% 26% at 72% 92%, rgba(122,96,58,.13), transparent 70%),
    linear-gradient(var(--paper), var(--paper2));
  --plate-edge:3px solid var(--ink);
  /* the gold rule, and the grime that gathers at every edge */
  --plate-rule:inset 0 0 0 3px var(--gold), inset 0 0 70px rgba(74,56,30,.34);
  --plate-lift:0 14px 40px rgba(0,0,0,.6), 0 0 60px -20px rgba(255,207,98,.25);
}

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

body{
  /* a lit tent somewhere ahead of you; everything nearer is dark */
  background:
    radial-gradient(120% 70% at 50% 118%, rgba(216,167,44,.16), transparent 60%),
    radial-gradient(90% 55% at 50% -20%, #23262a, transparent 70%),
    linear-gradient(#0f1113, #0a0b0c) fixed;
  background-attachment:fixed;
  color:var(--cream);
  font:15px/1.55 "Iowan Old Style","Palatino Linotype",Palatino,Georgia,serif;
  min-height:100vh;
}

/* ---------- the air ----------
   Dust that hangs, a vignette that closes the corners, grain. Never clickable. */
body::before{
  content:""; position:fixed; inset:0; pointer-events:none; z-index:60;
  opacity:.06;
  background-image:repeating-linear-gradient(0deg,#000 0 1px,transparent 1px 3px);
}
body::after{
  content:""; position:fixed; inset:-20%; pointer-events:none; z-index:59;
  background:
    radial-gradient(50% 40% at 20% 30%, rgba(200,184,150,.055), transparent 70%),
    radial-gradient(45% 38% at 78% 62%, rgba(200,184,150,.045), transparent 70%),
    radial-gradient(60% 45% at 55% 88%, rgba(190,170,135,.05), transparent 70%);
  animation:drift 42s ease-in-out infinite alternate;
}
/* the dust does not blow — it hangs, and shifts when you are not looking */
@keyframes drift{
  from{transform:translate3d(-2%,0,0) scale(1);}
  to  {transform:translate3d(3%,-2%,0) scale(1.08);}
}
#app::after{
  content:""; position:fixed; inset:0; pointer-events:none; z-index:58;
  box-shadow:inset 0 0 220px 40px rgba(0,0,0,.72);
}
@media(prefers-reduced-motion:reduce){body::after{animation:none;}}

#app{max-width:1120px; margin:0 auto; padding:22px 16px 40px; position:relative; z-index:1;}
.hidden{display:none !important;}

/* ═══════════ THE PLACARD ═══════════
   .panel, .result-panel, .enemy, .hero, .log, .road-hud, .town-plate and the
   map folio are all THIS object. If a new surface appears, it is this too. */
.panel, .enemy, .hero, .log, .road-hud, .minimap{
  position:relative;
  background:var(--plate);
  border:var(--plate-edge);
  border-radius:var(--radius);
  box-shadow:var(--plate-rule), var(--plate-lift);
  color:var(--ink);
}
/* every bill is nailed up: two tacks, top corners */
.panel::before, .enemy::before, .hero::before, .road-hud::before{
  content:""; position:absolute; inset:0; pointer-events:none; z-index:2;
  background-image:
    radial-gradient(circle at 15px 14px, #2a2119 0 3px, rgba(0,0,0,.25) 3.4px, transparent 4.6px),
    radial-gradient(circle at calc(100% - 15px) 14px, #2a2119 0 3px, rgba(0,0,0,.25) 3.4px, transparent 4.6px);
}
.panel{padding:20px 22px;}

/* the printing on paper */
h1{
  font-family:"Playbill",Rockwell,Impact,Haettenschweiler,sans-serif;
  font-size:48px; letter-spacing:.06em; color:var(--ink); line-height:1.05;
}
h2{
  font:700 11px/1 ui-monospace,monospace; letter-spacing:.3em; text-transform:uppercase;
  color:var(--red); margin-bottom:12px;
  border-bottom:1px solid rgba(20,17,14,.25); padding-bottom:9px;
}
.hint{color:var(--ink2); font-size:12.5px; margin-bottom:12px; font-style:italic;}
.kicker{font:700 11px/1 ui-monospace,monospace; letter-spacing:.3em;
  text-transform:uppercase; color:var(--red);}

/* ---------- the title bill ----------
   The one placard that hangs in the night rather than on a wall: it gets the
   bulbs. Nailed to nothing, lit from in front, and the current is bad. */
.title{
  text-align:center; margin-bottom:26px; position:relative;
  background:var(--plate);
  border:var(--plate-edge); border-radius:var(--radius);
  box-shadow:var(--plate-rule), 0 18px 55px rgba(0,0,0,.7),
             0 0 90px -20px rgba(255,207,98,.4);
  padding:30px 26px 32px;
  transform:rotate(-.35deg); /* nobody hangs a bill straight */
}
.title h1{
  font-size:clamp(38px,7vw,62px); letter-spacing:.08em;
  color:#2a2119;
  text-shadow:0 1px 0 rgba(255,255,255,.45), 0 3px 0 rgba(20,17,14,.12);
  animation:marquee 7s linear infinite;
}
/* the bulbs behind the bill, flickering */
.title::after{
  content:""; position:absolute; inset:-30px; pointer-events:none; z-index:-1;
  background:radial-gradient(closest-side, rgba(255,207,98,.30), transparent 75%);
  animation:marquee 7s linear infinite;
}
@keyframes marquee{
  0%,46%{opacity:1;} 47%{opacity:.72;} 48%{opacity:1;}
  70%{opacity:1;} 71%{opacity:.6;} 72.5%{opacity:.95;} 73%,100%{opacity:1;}
}
@media(prefers-reduced-motion:reduce){
  .title h1, .title::after{animation:none;}
}
.title .kicker{margin-bottom:12px;}
.sub{color:var(--ink); margin-top:12px; font-size:16px;}
.rule{color:var(--ink2); margin-top:8px; font-size:13.5px;}
.rule b{color:var(--red); font-weight:700;}
/* The rules live in the book, not in the header. Both buttons are the SAME
   object at the same size — one is simply printed louder than the other. Before,
   .big and .ghost carried different padding and the pair came out mismatched. */
.title-actions{
  display:flex; gap:10px; justify-content:center; align-items:stretch;
  flex-wrap:wrap; margin-top:20px;
}
.title-actions .btn{
  margin:0; text-decoration:none;
  display:inline-flex; align-items:center; justify-content:center;
  min-height:50px; padding:0 26px;
  font-size:12px; letter-spacing:.2em;
}
@media(max-width:620px){
  .title-actions{flex-direction:column;}
  .title-actions .btn{width:100%;}
}

.columns{display:grid; grid-template-columns:1.2fr 1fr; gap:16px;}
@media(max-width:860px){.columns{grid-template-columns:1fr;}}

/* ═══════════ TICKETS ═══════════
   The small repeated rows — a foe, an act, a shop door. A ticket is the placard
   at one-quarter scale: same stock, same ink edge, but the gold rule collapses
   to a single stub down the left, because that is where you tear it. */
.foe, .deck-card, .shop, .dbg, .drop{
  background:
    radial-gradient(80% 100% at 50% -20%, rgba(255,246,216,.5), transparent 70%),
    radial-gradient(40% 80% at 92% 60%, rgba(122,96,58,.18), transparent 70%),
    linear-gradient(var(--paper), var(--paper3));
  border:1px solid var(--ink);
  border-left:5px solid var(--ink3);
  border-radius:var(--radius);
  color:var(--ink);
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.35),
             inset 0 0 26px rgba(74,56,30,.28),
             0 3px 0 rgba(0,0,0,.45);
}

.foe{
  display:flex; gap:14px; align-items:center; width:100%; text-align:left;
  padding:12px; margin-bottom:10px; cursor:pointer; font:inherit;
  transition:transform .12s, box-shadow .12s, filter .12s;
}
.foe:hover{transform:translateX(3px);
  filter:brightness(1.05);
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.4), 0 3px 0 rgba(0,0,0,.45),
             -4px 0 20px -6px rgba(255,207,98,.65);}
.foe.trouble{border-left-color:var(--red);}
.foe.show{border-left-color:var(--gold);}
.foe-icon{font-size:30px; filter:drop-shadow(0 1px 1px rgba(0,0,0,.35));}
.foe-meta{display:flex; flex-direction:column; gap:1px;}
.foe-meta b{font-size:16px; font-family:"Playbill",Rockwell,Impact,sans-serif;
  letter-spacing:.03em;}
.foe-where{font-size:12px; color:var(--ink2); font-style:italic;}
.foe-stats{font:700 10px/1 ui-monospace,monospace; letter-spacing:.16em;
  text-transform:uppercase; color:var(--red); margin-top:5px;}
.foe-meta small{color:var(--ink2); font-size:12.5px; margin-top:3px;}

/* ---------- THE TROUPE ----------
   These are PAINTINGS, not list rows. The banner fills the tile and the words go
   over the bottom of it on a scrim, the way a real sideshow banner carries its
   own billing. The art is the point; the text is the caption. */
#deck{
  display:grid; grid-template-columns:repeat(auto-fill, minmax(128px, 1fr));
  gap:9px;
}
.deck-card{
  position:relative; display:block; padding:0; margin:0;
  aspect-ratio:3/4; overflow:hidden;
  border:2px solid var(--ink); border-left:2px solid var(--ink);
  border-radius:var(--radius);
  background:linear-gradient(var(--paper), var(--paper3));
  box-shadow:inset 0 0 0 2px color-mix(in srgb, var(--tint) 70%, var(--ink)),
             0 4px 0 rgba(0,0,0,.5);
  transition:transform .12s, box-shadow .12s;
}
.deck-card:hover{
  transform:translateY(-3px);
  box-shadow:inset 0 0 0 2px var(--gold),
             0 6px 0 rgba(0,0,0,.5), 0 0 26px -4px rgba(255,207,98,.7);
}
.deck-art{
  position:absolute; inset:0; width:100%; height:100%;
  background-size:cover; background-position:center top;
  border:0; border-radius:0;
}
/* the glyph fallback, before a painting lands */
.deck-card .glyph{
  position:absolute; inset:0; display:grid; place-items:center;
  font-size:38px; opacity:.5;
}
/* the billing, printed over the bottom of the banner */
.deck-card > div{
  position:absolute; left:0; right:0; bottom:0; z-index:2;
  padding:20px 8px 7px;
  background:linear-gradient(transparent, rgba(12,10,8,.72) 42%, rgba(8,7,6,.93));
}
.deck-card b{
  display:block; color:#f1e6cf; font-size:12px;
  font-family:"Playbill",Rockwell,Impact,sans-serif; letter-spacing:.04em;
  text-shadow:0 1px 3px #000;
}
.deck-card small{
  display:block; color:#c4b79f; font-size:10px; line-height:1.3; margin-top:2px;
  text-shadow:0 1px 3px #000;
}

/* WHAT IS OUT THERE — art first, the way the troupe is. */
#debug{
  display:grid; grid-template-columns:repeat(auto-fill, minmax(128px, 1fr));
  gap:9px;
}
.dbg{
  position:relative; display:block; padding:0; margin:0;
  aspect-ratio:3/4; overflow:hidden; cursor:pointer; font:inherit;
  border:2px solid var(--ink); border-left:2px solid var(--ink);
  border-radius:var(--radius);
  background:linear-gradient(var(--paper), var(--paper3));
  box-shadow:inset 0 0 0 2px var(--ink3), 0 4px 0 rgba(0,0,0,.5);
  transition:transform .12s, box-shadow .12s;
}
.dbg:hover{
  transform:translateY(-3px);
  box-shadow:inset 0 0 0 2px var(--red),
             0 6px 0 rgba(0,0,0,.5), 0 0 26px -4px rgba(168,48,31,.9);
}
.dbg-art{
  position:absolute; inset:0;
  background-size:cover; background-position:center top;
}
.dbg-glyph{
  position:absolute; inset:0; display:grid; place-items:center;
  font-size:38px; opacity:.55;
}
.dbg-cap{
  position:absolute; left:0; right:0; bottom:0; z-index:2;
  padding:20px 8px 7px;
  background:linear-gradient(transparent, rgba(12,10,8,.72) 42%, rgba(8,7,6,.94));
}
.dbg-cap b{
  display:block; color:#f1e6cf; font-size:11.5px;
  font-family:"Playbill",Rockwell,Impact,sans-serif; letter-spacing:.03em;
  text-shadow:0 1px 3px #000;
}
.dbg-cap small{
  display:block; margin-top:2px; color:#bfae94;
  font:700 7.5px/1.3 ui-monospace,monospace; letter-spacing:.08em;
  text-transform:uppercase; text-shadow:0 1px 3px #000;
}

/* ═══════════ THE TICKET BUTTON ═══════════ */
.btn{
  position:relative;
  background:linear-gradient(var(--paper), var(--paper2));
  color:var(--red);
  border:var(--plate-edge); border-radius:var(--radius);
  box-shadow:inset 0 0 0 2px var(--gold), 0 4px 0 #2a2119,
             0 0 34px -8px rgba(255,207,98,.6);
  padding:13px 26px;
  font:700 12px/1 ui-monospace,monospace;
  letter-spacing:.24em; text-transform:uppercase;
  cursor:pointer;
  transition:box-shadow .15s, transform .08s, filter .15s;
}
.btn:hover{
  filter:brightness(1.04);
  box-shadow:inset 0 0 0 2px var(--gold), 0 4px 0 #2a2119,
             0 0 44px -4px rgba(255,207,98,.95);
}
.btn:active{transform:translateY(3px);
  box-shadow:inset 0 0 0 2px var(--gold), 0 1px 0 #2a2119;}
.btn.big{margin-top:20px; padding:16px 38px; font-size:13px; letter-spacing:.28em;}

/* ═══════════ THE RING ═══════════
   The one place the paper gives way: the ring floor is dark, because the ring
   IS dark. The bills hang above and below it.

   The whole screen is columnar and CENTRED on the ring. The foe's bill and your
   own used to run the full width of the page while the board sat small in the
   middle of them, which made the ring look like an afterthought between two
   billboards. Now everything is the same width as the thing it is about. */
/* A single auto column, centred. The column takes the width of its widest child
   — which is the arena — so the foe's bill and your own come out EXACTLY as wide
   as the ring and the log beneath them. No magic number: shrink the ring and the
   bills shrink with it. */
/* THE RING GETS THE ROOM.
   Nothing is stacked on top of the board any more. Everything that is only
   information — the foe, the clock, the log, your own state — is one narrow
   column beside it. So every pixel the page can spare goes to cards, which is
   what you actually have to see and remember. */
.dossier{
  display:flex; flex-direction:column; gap:10px;
  min-width:0; align-self:stretch;
}
.dossier .enemy, .dossier .hero{flex-wrap:wrap; padding:12px 13px; gap:10px;}
.dossier .log{flex:1; min-height:120px; max-height:none;}
.dossier .e-top{flex-direction:column; align-items:flex-start; gap:3px;}
/* portrait and name on one line, everything else beneath: a narrow column needs
   its widest element to be the thing you actually read */
.e-head{display:flex; gap:11px; align-items:center; flex:1 1 100%; min-width:0;}
.dossier .e-icon{font-size:30px;}
.dossier .e-icon.has-art{width:46px; height:46px; flex:0 0 46px;}
.dossier .e-info{flex:1 1 100%;}
.dossier .e-id b{font-size:16px;}
.dossier .badge{font-size:9.5px; letter-spacing:.06em; padding:3px 6px;}
.dossier .badges{gap:4px;}
.dossier .intent{white-space:normal;}
.dossier .h-left{min-width:0; flex:1 1 100%;}
.dossier .hero .bar{flex:1 1 100%;}
.dossier .combo{min-width:0; text-align:left; flex:1 1 100%;}
#battle.hurt{animation:shake .3s;}
@keyframes shake{25%{transform:translateX(-7px);}50%{transform:translateX(6px);}75%{transform:translateX(-3px);}}

/* The foe is a WANTED bill — the same placard, with a red stripe across its top
   edge. A show gets a gold stripe instead: they are billed, not hunted. */
.enemy{display:flex; gap:14px; align-items:center; padding:14px 16px;
  border-top:6px solid var(--red);}
#battle.is-show .enemy{border-top-color:var(--gold);}
.e-icon{font-size:40px; filter:drop-shadow(0 1px 2px rgba(0,0,0,.4));}
.e-info{flex:1;}
.e-top{display:flex; justify-content:space-between; align-items:flex-start; gap:12px; margin-bottom:7px;}
/* name over place, so a long "where" never breaks across the middle of a phrase */
.e-id{display:flex; flex-direction:column; gap:1px; min-width:0;}
.e-id b{font-size:19px; font-family:"Playbill",Rockwell,Impact,sans-serif;
  letter-spacing:.04em; color:var(--ink); line-height:1.1;}
.e-id .where{margin-left:0;}
.where{font-size:12px; color:var(--ink2); font-style:italic; margin-left:8px;}
.intent{font:700 10.5px/1 ui-monospace,monospace; letter-spacing:.18em;
  text-transform:uppercase; color:var(--red); white-space:nowrap;}
#battle.is-show .intent{color:#8a6a1c;}

/* bars: an ink trough stamped into the paper */
.bar{position:relative; height:19px; background:#2a2119;
  border:1px solid var(--ink); border-radius:1px; overflow:hidden;
  box-shadow:inset 0 2px 5px rgba(0,0,0,.6);}
.bar i{position:absolute; inset:0 auto 0 0; display:block; transition:width .35s ease;}
.enemy-bar i{background:repeating-linear-gradient(45deg,#8f3020 0 8px,#a8301f 8px 16px);}
#battle.is-show .enemy-bar i{background:repeating-linear-gradient(45deg,#8a6a1c 0 8px,#a5821f 8px 16px);}
.hero-bar i{background:repeating-linear-gradient(45deg,#4a6b42 0 8px,#5d7f52 8px 16px);}
.bar span{position:absolute; inset:0; display:grid; place-items:center;
  font:700 10px/1 ui-monospace,monospace; letter-spacing:.16em;
  text-shadow:0 1px 2px #000; color:var(--paper);}

/* a badge is a torn corner of the same stock */
.badge{
  font:700 10px/1 ui-monospace,monospace; letter-spacing:.1em;
  background:var(--paper3); color:var(--ink);
  border:1px solid var(--ink); border-radius:1px; padding:4px 8px;
  box-shadow:0 1px 0 rgba(0,0,0,.4);
}
.badges{display:flex; gap:6px; flex-wrap:wrap; margin-top:8px;}

/* the clock: a fuse burning down, set into the paper */
.timer-wrap{height:7px; background:#2a2119; border:1px solid var(--ink);
  margin:8px 0 0; overflow:hidden; box-shadow:inset 0 1px 4px rgba(0,0,0,.7);}
.timer-wrap i{display:block; height:100%;
  background:linear-gradient(90deg,var(--red),var(--gold) 70%,var(--glow));
  box-shadow:0 0 12px rgba(255,207,98,.7);}

/* The ring is only as wide as the ring. It used to take a 1fr column and sit in
   the middle of it, so a 4x4 board floated in a great empty hall of nothing —
   which is what made the board read as "strangely wide". Now the board is
   max-content and the whole arena centres on it. */
.arena{
  display:grid; grid-template-columns:1fr 292px;
  gap:16px; margin:10px 0; align-items:stretch;
}
/* On a narrow screen the side column is wrong: you want the two of you facing
   each other ACROSS the board, the way you actually are. So the dossier stops
   being a box (display:contents) and its children take their places in one
   column — THEM above the ring, YOU below it, and the running record of what is
   happening at the bottom where it can be read but never gets in the way. */
@media(max-width:860px){
  .arena{display:flex; flex-direction:column; gap:9px;}
  .dossier{display:contents;}
  .dossier .enemy{order:1;}
  .dossier .timer-wrap{order:2;}
  #grid{order:3;}
  .dossier .hero{order:4;}
  .dossier .log{order:5; max-height:104px; min-height:0; flex:none;}
  /* facing each other: their stripe on top, yours on the bottom */
  .dossier .enemy{border-top-width:6px;}
  .dossier .hero{border-bottom-width:6px;}
}

/* Cells auto-size so a 6x6 ring always fits the viewport — whichever runs out
   first, the column width or the remaining height, decides the cell. */
/* The ring must ALWAYS fit on screen without scrolling — a memory game you have
   to scroll is not a memory game, because you cannot see the board you are being
   asked to remember. So the cell is whichever is smaller: what the width allows,
   or what the height allows. On a phone that is the width; on a desktop, height. */
/* Nothing sits above or below the board now, so the ring may use the WHOLE
   height of the page and the whole width left over by the dossier. The cell is
   whichever runs out first — height or width — and never bigger than it needs. */
.grid{
  --gap:8px;
  --avail-h:calc(100dvh - 90px);
  --by-height:calc((var(--avail-h) - var(--rows) * var(--gap)) * 0.75 / var(--rows));
  --by-width:calc((min(100vw, 1120px) - 300px - var(--cols) * var(--gap)) / var(--cols));
  --cell:min(122px, var(--by-height), var(--by-width));
  display:grid;
  grid-template-columns:repeat(var(--cols,4), var(--cell));
  justify-content:center; align-content:center;
  gap:var(--gap);
  padding:10px;
  /* the ring: a pool of bulb-light on a dark floor */
  background:radial-gradient(60% 60% at 50% 45%, rgba(216,167,44,.09), transparent 72%);
}
.card{
  position:relative; width:var(--cell); aspect-ratio:3/4;
  border:0; background:transparent; padding:0; cursor:pointer; perspective:600px;
}
.card:disabled{cursor:default;}
.face{
  position:absolute; inset:0; display:grid; place-items:center; gap:3px;
  border-radius:var(--radius); backface-visibility:hidden;
  transition:transform .38s cubic-bezier(.4,.1,.2,1);
  border:2px solid var(--ink);
}
/* the back of a handbill: tent ticking inside the same ink edge and gold rule */
.back{
  background:repeating-linear-gradient(45deg,#6f2114 0 7px,#83291a 7px 14px);
  box-shadow:
    inset 0 0 0 3px var(--paper), inset 0 0 0 5px var(--gold),
    inset 0 -22px 30px -18px rgba(0,0,0,.8),
    0 4px 10px rgba(0,0,0,.5);
}
/* the front is the placard, tinted by the act printed on it */
.front{
  background:linear-gradient(
    color-mix(in srgb, var(--tint) 18%, var(--paper)),
    color-mix(in srgb, var(--tint) 32%, var(--paper2)));
  color:var(--ink);
  box-shadow:inset 0 0 0 3px rgba(255,255,255,.4),
             inset 0 0 0 4px color-mix(in srgb, var(--tint) 60%, var(--ink)),
             0 0 22px -4px rgba(255,207,98,.5);
  transform:rotateY(180deg);
  align-content:center;
}
.card.up .back{transform:rotateY(-180deg);}
.card.up .front{transform:rotateY(0);}
.glyph{font-size:clamp(17px,3.2vw,28px); line-height:1;}
/* the painted banner, when one has landed */
.art{
  width:100%; flex:1; min-height:0; align-self:stretch;
  background-size:cover; background-position:center top;
  border-bottom:1px solid rgba(20,17,14,.35);
}
.front{grid-template-rows:1fr auto; padding-bottom:3px;}
.cname{
  font:700 8.5px/1.15 ui-monospace,monospace; letter-spacing:.1em;
  text-transform:uppercase; color:#4a3a29; text-align:center; padding:0 3px;
}
/* ═══════════ THE HECKLER ═══════════
   The ONE card in the ring that is not yours. It must be impossible to mistake
   for one of your acts — so it is not printed on your poster stock at all. It is
   ink-black, it is stamped in red, and it tells you exactly what it will cost
   you BEFORE you turn its mate over. */
.card.is-curse .front{
  background:linear-gradient(#2a2119, #16120e);
  box-shadow:inset 0 0 0 3px var(--red), 0 0 26px -4px rgba(168,48,31,.8);
  border-color:var(--red);
}
.card.is-curse .cname{color:#e8c9a8;}
.card.is-curse .glyph{filter:grayscale(.4) brightness(1.1);}
.card.is-curse .art{border-bottom-color:var(--red); filter:saturate(.6) contrast(1.1);}
.cost{
  display:block; text-align:center;
  font:800 8px/1.4 ui-monospace,monospace; letter-spacing:.08em;
  background:var(--red); color:#f7ead2;
  margin:2px -3px -3px; padding:2px 0;
}
/* a bulb comes up under the card you are about to turn */
.card:not(:disabled):hover .back{
  filter:brightness(1.22);
  box-shadow:inset 0 0 0 3px var(--paper), inset 0 0 0 5px var(--gold),
             0 0 22px -2px rgba(255,207,98,.6);
}
/* a landed act does not vanish — it goes out, like a lamp */
.card.matched{opacity:.22; transform:scale(.94); filter:grayscale(.7) brightness(.6);
  transition:all .35s;}
/* Mentalist peek — face shown, still clickable. Dashed says "temporary". */
.card.peek .front{
  box-shadow:inset 0 0 0 3px var(--gold), 0 0 28px -2px rgba(255,207,98,.75);
  border-style:dashed;
}

/* the log is the ledger: ruled paper, kept in pencil */
.log{
  padding:12px 14px; overflow-y:auto; max-height:390px;
  font-size:12.5px; display:flex; flex-direction:column;
  background:
    repeating-linear-gradient(180deg, transparent 0 25px, rgba(20,17,14,.09) 25px 26px),
    var(--plate);
}
.log .line{padding:4px 0; border-bottom:1px solid rgba(20,17,14,.14); color:var(--ink2);}
.log .line:first-child{color:var(--ink); font-weight:700;}

/* your own bill, with a green stripe along its bottom edge */
.hero{display:flex; gap:14px; align-items:center; padding:14px 16px;
  border-bottom:6px solid var(--green);}
.h-left{display:flex; gap:10px; align-items:center; min-width:200px;}
.h-name{font-weight:700; font-family:"Playbill",Rockwell,Impact,sans-serif;
  letter-spacing:.04em; font-size:17px;}
.block{font:700 10px/1 ui-monospace,monospace; letter-spacing:.1em; color:var(--ink2);}
.block.on{background:#2b3350; color:var(--paper); border:1px solid var(--ink);
  border-radius:1px; padding:4px 8px;}
.fatigue{font:700 10px/1 ui-monospace,monospace; letter-spacing:.1em; color:var(--ink2);}
.hero .bar{flex:1;}
.combo{
  min-width:120px; text-align:right;
  font:800 12px/1 ui-monospace,monospace; letter-spacing:.14em; text-transform:uppercase;
  color:var(--red); opacity:0; transition:opacity .2s;
}
.combo.on{opacity:1; animation:pop .3s;}
@keyframes pop{from{transform:scale(1.3);}}

/* ═══════════ THE BILL (after) ═══════════ */
.result-panel{max-width:520px; margin:11vh auto 0; text-align:center;}
.result-panel h1{margin-bottom:6px; font-size:40px;}
.result-panel .win{color:var(--ink);}
.result-panel .lose{color:var(--red);}
#result-sub{color:var(--ink2); margin-bottom:20px; font-style:italic;}
.drops{text-align:left; margin-bottom:16px;}
/* each line drops in on a stagger, so the payoff lands beat by beat */
.drop{
  display:flex; gap:12px; align-items:center;
  border-left-color:var(--tint, var(--ink3));
  padding:10px 12px; margin-bottom:8px;
  opacity:0; transform:translateY(10px);
  animation:dropin .38s cubic-bezier(.2,1.3,.4,1) forwards;
  animation-delay:calc(var(--i) * 160ms + 120ms);
}
@keyframes dropin{to{opacity:1; transform:none;}}
.drop-icon{font-size:22px; width:26px; text-align:center;}
/* the painted banner of the act you just won */
.drop-art{
  width:40px; height:52px; flex:0 0 40px; border-radius:1px;
  background-size:cover; background-position:center top;
  border:2px solid var(--ink);
  box-shadow:inset 0 0 0 1px var(--gold);
}
.drop-main{flex:1;}
.drop-main b{font-size:14px;}
.drop-main small{display:block; color:var(--ink2); font-size:11.5px; margin-top:1px;}
.drop-val{
  font:700 10px/1 ui-monospace,monospace; letter-spacing:.14em;
  color:var(--ink2); white-space:nowrap;
}
.drop.take{border-left-color:var(--green);}
.drop.take .drop-val{color:#3f6b3a; font-size:15px; letter-spacing:0;}
.drop.caught{border-left-color:var(--gold);}
.drop.caught .drop-val{color:#8a6a1c;}
/* a rare catch is worth a lamp of its own */
.drop.rare{border-left-color:var(--gold);
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.4), 0 3px 0 rgba(0,0,0,.45),
             0 0 30px -4px rgba(255,207,98,.8);}
.drop.rare .drop-val{color:#8a6a1c;}
.drop.loss{border-left-color:var(--red);}
.drop.loss .drop-val{color:var(--red); font-size:15px; letter-spacing:0;}
.drop.none{opacity:.72;}
.result-total{
  font:700 10.5px/1 ui-monospace,monospace; letter-spacing:.16em;
  text-transform:uppercase; color:var(--ink2); margin-bottom:20px;
  border-top:1px solid rgba(20,17,14,.25); padding-top:14px;
}
.result-total b{color:var(--ink);}

/* ═══════════ THE ROAD ═══════════ */
/* THE ROAD: the country gets the screen. The instruments go in a column beside
   it, so the only thing above the driving view is a thin name-plate and the one
   reading you actually steer by. */
.road{display:grid; grid-template-columns:1fr 262px; gap:14px; align-items:start;}
.road-main{min-width:0;}
.road-side{min-width:0;}
@media(max-width:860px){
  .road{grid-template-columns:1fr;}
}

.gauges{padding:14px 15px;}
.gauge{margin-bottom:9px;}
.g-label{
  display:block; margin-bottom:3px;
  font:700 9px/1 ui-monospace,monospace; letter-spacing:.16em;
  text-transform:uppercase; color:var(--ink2);
}
.gauge-note{
  font-size:11px; font-style:italic; color:var(--ink2);
  border-top:1px solid rgba(20,17,14,.2); padding-top:9px; margin-top:11px;
}
.tallies{display:flex; gap:5px; flex-wrap:wrap; margin:10px 0 12px;}
.btn.wide{
  display:block; width:100%; margin-bottom:7px;
  padding:11px 12px; font-size:10px; letter-spacing:.14em;
}

.road-hud{
  display:flex; gap:16px; align-items:center;
  padding:10px 14px; margin-bottom:10px;
}
.rh-left{min-width:180px; display:flex; flex-direction:column;}
.rh-left b{font-size:18px; font-family:"Playbill",Rockwell,Impact,sans-serif;
  letter-spacing:.04em; color:var(--ink);}
.rh-left .where{margin-left:0; color:var(--ink2);}
.rh-mid{flex:1; display:flex; flex-direction:column; gap:7px;}
.road-hud .radar{flex:1;}

/* ---------- THE RADAR ----------
   Hot and cold. It never says where — only how near. The colour does the work,
   because you are reading it out of the corner of your eye while driving. */
.radar{display:flex; align-items:center; gap:10px;}
.radar-label{
  font:700 9px/1 ui-monospace,monospace; letter-spacing:.16em;
  text-transform:uppercase; color:var(--ink2); white-space:nowrap;
}
.radar-bar{flex:1; height:11px;}
.radar-bar i{
  background:linear-gradient(90deg,#5d7f52,#c9a227 55%,#a8301f);
  transition:width .18s linear;
}
.radar-read{
  font:700 9.5px/1 ui-monospace,monospace; letter-spacing:.12em;
  text-transform:uppercase; color:var(--ink2);
  min-width:132px; text-align:right; white-space:nowrap;
}
.radar.warm .radar-read{color:#8a6a1c;}
.radar.hot .radar-read{color:var(--red);}
/* when it has you, the whole meter should be shouting */
.radar.seen .radar-read{color:var(--red);}
.radar.seen .radar-bar{
  border-color:var(--red);
  box-shadow:0 0 22px -3px rgba(168,48,31,.9);
  animation:radarpulse .5s ease-in-out infinite alternate;
}
@keyframes radarpulse{from{opacity:.62;} to{opacity:1;}}
@media(prefers-reduced-motion:reduce){.radar.seen .radar-bar{animation:none;}}
.rh-right{display:flex; gap:8px; align-items:center; flex-wrap:wrap;}
.badge.take{color:#3f6b3a; font-weight:700;}

/* ---------- THE TWO CLOCKS ----------
   Neither ever goes up on its own. They are drawn small and side by side so you
   watch them the way you watch a fuel gauge: never, until suddenly always. */
.supply{display:flex; flex-direction:column; gap:3px; min-width:74px;}
.sup-label{
  font:700 8.5px/1 ui-monospace,monospace; letter-spacing:.16em;
  text-transform:uppercase; color:var(--ink2);
}
.sup-bar{height:9px;}
.sup-bar i{background:repeating-linear-gradient(45deg,#5a7a4e 0 6px,#6d8f5c 6px 12px);}
.sup-bar.fuel i{background:repeating-linear-gradient(45deg,#8a6a1c 0 6px,#a5821f 6px 12px);}
.sup-bar.low{border-color:var(--red);}
.sup-bar.low i{background:repeating-linear-gradient(45deg,#a8301f 0 6px,#c04a34 6px 12px);}
.sup-bar.out{
  border-color:var(--red);
  box-shadow:0 0 16px -2px rgba(168,48,31,.9);
  animation:radarpulse .6s ease-in-out infinite alternate;
}

/* The map is a painting in daylight. It is graded to dusk in CSS rather than in
   the draw loop — the canvas keeps its own colours, and we simply put the
   evening over it, so nothing in the game's rendering has to know it is dark. */
.map-wrap{
  position:relative;
  border:var(--plate-edge); border-radius:var(--radius);
  overflow:hidden; background:#2a2620;
  /* the inset shadow used to eat 60px of the picture on every side */
  box-shadow:var(--plate-rule), inset 0 0 26px rgba(0,0,0,.35), 0 12px 34px rgba(0,0,0,.55);
}
/* The road was being darkened THREE times over — a brightness filter on the
   canvas, a multiply scrim on top of it, AND the cloud shadows now drawn into
   the world. Together they took a painted county down to mud you could not read.
   The canvas keeps a light evening grade; the scrim only shapes the edges. */
#map{display:block; width:100%; height:min(62vh, 560px);
  filter:saturate(.86) brightness(.92) contrast(1.04) hue-rotate(-4deg);}
.map-wrap::after{
  content:""; position:absolute; inset:0; pointer-events:none;
  background:
    /* the lamp you are carrying — now actually visible */
    radial-gradient(38% 46% at 50% 50%, rgba(255,207,98,.14), transparent 72%),
    /* a whisper of evening, not a blackout */
    linear-gradient(rgba(24,28,36,.12), rgba(14,16,22,.22)),
    /* the corners go down, the middle stays readable */
    radial-gradient(130% 100% at 50% 50%, transparent 58%, rgba(8,9,12,.62));
  mix-blend-mode:multiply;
}
/* a lighter pass, so the dust reads as hanging IN the air, not on glass */
.map-wrap::before{
  content:""; position:absolute; inset:-10%; z-index:1; pointer-events:none;
  background:
    radial-gradient(40% 35% at 25% 35%, rgba(198,180,146,.10), transparent 70%),
    radial-gradient(45% 40% at 75% 68%, rgba(198,180,146,.08), transparent 70%);
  animation:drift 38s ease-in-out infinite alternate;
}
@media(prefers-reduced-motion:reduce){.map-wrap::before{animation:none;}}
.keys{margin-top:10px; text-align:center; color:var(--dim); font-size:12px; font-style:italic;}

/* ---------- the road so far ----------
   A folio: the same paper, unfolded over the road, with the night charted on it.
   The MAP itself stays black — it is the world, not the bill. */
.mm-btn{
  background:var(--paper); color:var(--red); border:1px solid var(--ink);
  cursor:pointer; font:700 10px/1 ui-monospace,monospace; letter-spacing:.14em;
  padding:5px 9px; border-radius:1px;
  box-shadow:0 2px 0 rgba(0,0,0,.5);
  transition:box-shadow .15s, transform .08s, filter .15s;
}
.mm-btn:hover{filter:brightness(1.05);
  box-shadow:0 2px 0 rgba(0,0,0,.5), 0 0 22px -3px rgba(255,207,98,.9);}
.mm-btn:active{transform:translateY(2px); box-shadow:0 0 0 rgba(0,0,0,.5);}

.minimap{
  position:absolute; inset:12px; z-index:3;
  display:flex; flex-direction:column; gap:9px;
  padding:14px 16px 12px;
  animation:unfold .22s ease-out;
}
@keyframes unfold{from{opacity:0; transform:scale(.985) rotate(-.4deg);} to{opacity:1; transform:none;}}
.mm-head{
  display:flex; justify-content:space-between; align-items:baseline;
  border-bottom:1px solid rgba(20,17,14,.25); padding-bottom:8px;
}
.mm-head b{
  font:700 12px/1 ui-monospace,monospace; letter-spacing:.3em;
  text-transform:uppercase; color:var(--red);
}
.mm-close{font:700 10px/1 ui-monospace,monospace; letter-spacing:.12em;
  color:var(--ink2); text-transform:uppercase;}
/* the chart itself: the night, set into the paper */
#mm-canvas{
  flex:1; width:100%; min-height:0; display:block;
  background:var(--night);
  border:2px solid var(--ink);
  box-shadow:inset 0 0 30px rgba(0,0,0,.9);
}
.mm-foot{
  text-align:center; font-size:11.5px; font-style:italic; color:var(--ink2);
}

/* ═══════════ TOWN ═══════════ */
.town-art{
  position:relative; height:min(46vh,380px);
  border:var(--plate-edge); border-radius:var(--radius);
  background-size:cover; background-position:center;
  display:flex; align-items:flex-end; overflow:hidden;
  box-shadow:var(--plate-rule), 0 14px 44px rgba(0,0,0,.6);
}
/* you are arriving at dusk, and nobody has come out to meet you */
.town-art::after{
  content:""; position:absolute; inset:0; z-index:1; pointer-events:none;
  background:
    linear-gradient(rgba(16,20,26,.32), rgba(8,10,13,.5)),
    radial-gradient(115% 85% at 50% 45%, transparent 40%, rgba(5,6,8,.8));
  mix-blend-mode:multiply;
}
/* no painting yet — a canvas-and-dust stand-in, still legible */
.town-art.no-art{
  background:
    linear-gradient(transparent 40%, rgba(8,9,11,.92)),
    repeating-linear-gradient(90deg,#33302a 0 40px,#2a2823 40px 80px);
}
/* the town's name is a placard nailed to the picture */
.town-plate{
  position:relative; z-index:2; margin:0 0 18px 20px;
  background:var(--plate);
  border:var(--plate-edge); border-radius:var(--radius);
  box-shadow:var(--plate-rule), 0 12px 34px rgba(0,0,0,.7);
  padding:14px 26px 16px; width:auto;
  transform:rotate(-.6deg);
}
.town-plate h1{font-size:34px; color:var(--ink);}
.town-plate .kicker{margin-top:5px;}
.town-blurb{margin:16px 2px; color:var(--dim); font-style:italic;}
.shops{display:grid; grid-template-columns:repeat(auto-fit,minmax(230px,1fr)); gap:10px; margin-bottom:16px;}
.shop{
  display:flex; gap:11px; align-items:center; text-align:left; font:inherit;
  border-left-color:var(--gold);
  padding:12px; cursor:pointer;
  transition:transform .12s, filter .12s, box-shadow .12s;
}
.shop:hover{transform:translateY(-2px); filter:brightness(1.05);
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.4), 0 5px 0 rgba(0,0,0,.45),
             0 0 24px -6px rgba(255,207,98,.7);}
.shop b{font-family:"Playbill",Rockwell,Impact,sans-serif; letter-spacing:.03em;
  font-size:15px;}
.shop-icon{font-size:24px;}
.shop small{display:block; color:var(--ink2); font-size:12px;}
.toast{
  opacity:0; transition:opacity .2s; color:var(--glow);
  margin-bottom:12px; min-height:20px;
  font:700 11px/1 ui-monospace,monospace; letter-spacing:.16em; text-transform:uppercase;
  text-shadow:0 0 16px rgba(255,207,98,.6);
}
.toast.on{opacity:1;}

/* ---------- THE BILL — the descent ----------
   The nights you have played are named and stamped. The night ahead is a blank
   line, and so is the one after it. The whole point of the layout is that the
   list does not end: you cannot see the bottom of the staircase. */
.bill-wrap{margin-top:14px;}
.bill{list-style:none; margin:0 0 16px;}
.night{
  display:flex; gap:14px; align-items:center;
  padding:10px 12px; margin-bottom:7px;
  border:1px solid var(--ink); border-left:5px solid var(--ink3);
  border-radius:var(--radius);
  background:linear-gradient(var(--paper), var(--paper3));
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.3);
}
.night .n{
  font:700 10px/1 ui-monospace,monospace; letter-spacing:.16em;
  text-transform:uppercase; color:var(--ink2); min-width:66px;
}
.night b{flex:1; font-family:"Playbill",Rockwell,Impact,sans-serif;
  letter-spacing:.03em; font-size:15px;}
.night .v{font:700 10px/1 ui-monospace,monospace; letter-spacing:.16em; color:var(--ink2);}

.night.done{border-left-color:var(--green); opacity:.75;}
.night.done .v{color:#3f6b3a;}
/* tonight is the only lit line on the bill */
.night.next{
  border-left-color:var(--red);
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.4), 0 0 26px -6px rgba(255,207,98,.8);
}
.night.next b{color:var(--red);}
.night.next .v{color:var(--red);}
/* and below tonight, the staircase just keeps going */
.night.unknown{
  opacity:.5; border-left-color:var(--ink3); border-style:dashed;
  background:none;
}
.night.unknown b{font-family:inherit; font-style:italic; font-size:13px;}

.town-actions{
  display:flex; gap:12px; align-items:center; flex-wrap:wrap;
  border-top:1px solid rgba(20,17,14,.25); padding-top:14px;
}
.pot{flex:1; display:flex; flex-direction:column; gap:2px;}
.pot-label{font:700 9.5px/1 ui-monospace,monospace; letter-spacing:.16em;
  text-transform:uppercase; color:var(--ink2);}
.pot b{font-size:22px; font-family:"Playbill",Rockwell,Impact,sans-serif;
  color:var(--ink);}
/* pulling out is the quiet option, so it is printed quietly */
.btn.ghost{
  background:none; color:var(--ink2);
  border:1px solid var(--ink3); box-shadow:none;
  padding:12px 20px;
}
.btn.ghost:hover{color:var(--ink); border-color:var(--ink);
  box-shadow:0 0 20px -6px rgba(255,207,98,.5); filter:none;}
.btn.ghost:active{transform:translateY(2px); box-shadow:none;}

/* ═══════════ THE BOOK ═══════════
   Six clowns. An empty cage is a to-do list, so a man you have MET but not
   caught is drawn at full strength with his rule showing — and no painting is
   given away until you have actually stood in front of him. */
.book-head{text-align:center; margin-bottom:14px;}
.book-head h1{font-size:38px; margin-bottom:8px;}
.book-head .hint{max-width:640px; margin:10px auto 0;}
.book-count{
  margin-top:12px; font:700 11px/1 ui-monospace,monospace;
  letter-spacing:.18em; text-transform:uppercase; color:var(--ink2);
}
.book-count b{color:var(--red); font-size:15px;}
.book-grid{
  display:grid; grid-template-columns:repeat(auto-fill, minmax(280px, 1fr));
  gap:12px; margin-bottom:18px;
}
.pm{
  display:flex; gap:12px; align-items:stretch;
  background:
    radial-gradient(80% 100% at 50% -20%, rgba(255,246,216,.5), transparent 70%),
    linear-gradient(var(--paper), var(--paper3));
  border:1px solid var(--ink); border-left:5px solid var(--ink3);
  border-radius:var(--radius); padding:10px;
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.35), 0 3px 0 rgba(0,0,0,.45);
}
.pm-art{
  width:84px; flex:0 0 84px; border:2px solid var(--ink); border-radius:1px;
  background-size:cover; background-position:center top; background-color:#15120f;
  display:grid; place-items:center; min-height:112px;
}
.pm-q{font:800 34px/1 ui-monospace,monospace; color:#4a4335;}
.pm-body{display:flex; flex-direction:column; gap:3px; min-width:0;}
.pm-body b{font-family:"Playbill",Rockwell,Impact,sans-serif; font-size:16px; letter-spacing:.03em;}
.pm-where{font-size:11.5px; font-style:italic; color:var(--ink2);}
.pm-body small{color:var(--ink2); font-size:11.5px; line-height:1.35;}
.pm-state{
  margin-top:auto; font:700 9.5px/1 ui-monospace,monospace;
  letter-spacing:.14em; text-transform:uppercase; color:var(--ink2);
}
/* caged: he is yours, and the cage is gold */
.pm.caged{border-left-color:var(--gold);
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.4), 0 3px 0 rgba(0,0,0,.45),
             0 0 26px -6px rgba(255,207,98,.6);}
.pm.caged .pm-state{color:#8a6a1c;}
/* loose: you have seen him. he is still out there. */
.pm.loose{border-left-color:var(--red);}
.pm.loose .pm-state{color:var(--red);}
.pm.loose .pm-art{filter:grayscale(.55) brightness(.75);}
.pm.unknown{opacity:.62; border-left-color:var(--ink3); border-style:dashed;}
.pm.unknown .pm-body b{font-family:inherit; font-style:italic; font-size:14px;}

/* ---------- CAMP — the only friendly fire in the game ---------- */
/* the camp's name plate sits ON the painting, like a town's, but lit by fire
   rather than by a bulb */
.camp-plate{
  display:flex; gap:16px; align-items:center;
  border-left:6px solid #d07a24;
}
.camp-plate h1{font-size:30px;}
.camp-icon{font-size:38px; filter:drop-shadow(0 0 18px rgba(255,140,40,.85));}
#camp-art::after{
  /* warmer than a town: somebody here is pleased to see you */
  background:
    linear-gradient(rgba(20,14,8,.28), rgba(10,7,4,.48)),
    radial-gradient(115% 85% at 50% 60%, transparent 38%, rgba(8,5,3,.82));
}

/* a painted foe portrait in place of the glyph — underlit, like a sideshow
   banner with a lamp on the floor in front of it */
.e-icon.has-art{
  width:78px; height:78px; flex:0 0 78px;
  background-size:cover; background-position:center 20%;
  border:2px solid var(--ink); border-radius:1px;
  filter:saturate(.85) brightness(.9) contrast(1.08);
  box-shadow:inset 0 0 26px rgba(5,6,8,.8),
             inset 0 -14px 22px -12px rgba(168,48,31,.6),
             0 0 0 3px var(--paper3);
}

/* the town loop sits over its own still, and fades in once it can actually
   play — so a missing or autoplay-blocked video never shows a black box */
.town-video{
  position:absolute; inset:0; width:100%; height:100%;
  object-fit:cover; opacity:0; transition:opacity .6s ease;
  pointer-events:none;
  filter:saturate(.8) brightness(.82) contrast(1.05);
}
.town-video.on{opacity:1;}

/* ═══════════ THE PHONE ═══════════
   A mud show plays where the crowd is, and the crowd is on a phone. The rules:
   the ring never scrolls, nothing sits under the thumb by accident, and every
   tap target is a real one. */
@media(max-width:700px){
  #app{padding:12px 10px 28px;}
  .title{padding:20px 14px 22px;}
  .title h1{font-size:clamp(28px,10vw,44px);}
  .sub{font-size:14px;}
  .heckler-rule{font-size:12px; padding:9px 11px;}

  /* the ring gets the whole width AND the top of the screen; the dossier follows */
  .arena{gap:8px;}
  .grid{
    --gap:5px;
    --avail-h:calc(100dvh - 300px);
    --by-width:calc((100vw - 24px - var(--cols) * var(--gap)) / var(--cols));
    padding:4px;
  }
  .cname{font-size:7px; letter-spacing:.04em;}
  .cost{font-size:7px;}

  /* the HUD stacks instead of squeezing */
  .road-hud{flex-wrap:wrap; gap:10px; padding:10px 12px;}
  .rh-left{min-width:0; flex:1 1 100%;}
  .rh-mid{flex:1 1 100%;}
  .rh-right{flex:1 1 100%; flex-wrap:wrap;}
  .radar{flex-wrap:wrap; gap:6px;}
  .radar-label{flex:1 1 100%;}
  .radar-read{min-width:0; flex:0 0 auto;}

  .enemy, .hero{flex-wrap:wrap; padding:11px 12px;}
  .h-left{min-width:0; flex:1 1 100%;}
  .hero .bar{flex:1 1 100%;}
  .combo{min-width:0; text-align:left;}
  .e-icon.has-art{width:54px; height:54px; flex:0 0 54px;}

  #map{height:min(48dvh, 380px);}
  .town-art{height:min(34dvh, 260px);}
  .town-plate{margin:0 0 12px 12px; padding:10px 16px 12px;}
  .town-plate h1{font-size:24px;}
  .shops{grid-template-columns:1fr;}

  .town-actions{gap:8px;}
  .town-actions .btn{flex:1 1 100%;}
  /* a real thumb needs a real target */
  .btn{padding:14px 20px; min-height:46px;}
  .foe, .shop, .dbg, .night{padding:12px;}

  .minimap{inset:6px; padding:10px 10px 8px;}
  .mm-foot{display:none;} /* the map needs the height more than it needs the joke */
  .columns{gap:12px;}
}

/* ═══════════ THE CURTAIN ═══════════ the motif's source. unchanged. */
#curtain{position:fixed; inset:0; z-index:100; pointer-events:none; display:none;}
#curtain.on{display:block;}
#curtain .stripes{position:absolute; inset:0; display:flex;}
#curtain .stripes i{
  flex:1; display:block; transform:scaleY(0); transform-origin:top;
  background:repeating-linear-gradient(180deg,#7d2415 0 26px,#c2b294 26px 52px);
  border-right:1px solid rgba(0,0,0,.4);
  box-shadow:inset 0 0 30px rgba(0,0,0,.6), inset 0 0 60px rgba(60,10,4,.5);
}
/* stagger the fall so it reads as cloth dropping, not a shutter closing */
#curtain.closing .stripes i{
  animation:drop .34s cubic-bezier(.3,.9,.35,1) forwards;
  animation-delay:calc(var(--i) * 12ms);
}
#curtain.opening .stripes i{
  transform:scaleY(1); transform-origin:bottom;
  animation:lift .38s cubic-bezier(.5,0,.6,.2) forwards;
  animation-delay:calc((14 - var(--i)) * 10ms);
}
@keyframes drop{from{transform:scaleY(0);} to{transform:scaleY(1);}}
@keyframes lift{from{transform:scaleY(1);} to{transform:scaleY(0);}}

#curtain .placard{
  position:absolute; left:50%; top:50%;
  transform:translate(-50%,-50%) scale(2.2) rotate(-8deg);
  opacity:0;
  background:var(--plate);
  border:var(--plate-edge);
  box-shadow:0 18px 50px rgba(0,0,0,.8), var(--plate-rule),
             0 0 70px -10px rgba(255,207,98,.5);
  padding:20px 44px; text-align:center; min-width:340px;
}
#curtain.slam .placard{animation:slam .42s cubic-bezier(.2,1.5,.4,1) forwards;}
@keyframes slam{
  0%{opacity:0; transform:translate(-50%,-50%) scale(2.2) rotate(-8deg);}
  70%{opacity:1; transform:translate(-50%,-50%) scale(.94) rotate(1.5deg);}
  100%{opacity:1; transform:translate(-50%,-50%) scale(1) rotate(-1deg);}
}
#curtain .placard-kind{
  font:700 11px/1 ui-monospace,monospace; letter-spacing:.3em;
  color:var(--red); margin-bottom:9px;
}
#curtain .placard-kind.show{color:#8a6a1c;}
#curtain .placard-name{
  font-family:"Playbill",Rockwell,Impact,sans-serif; font-size:34px;
  letter-spacing:.06em; color:var(--ink); line-height:1.05;
}
#curtain .placard-where{
  margin-top:7px; font-size:13px; font-style:italic; color:var(--ink2);
}
