/* Mythraven — the campaign desk: everything around the table.
   Source file. Copied verbatim into wiki/dist/play/ by build_play() in wiki/build.py.
   Loaded after play.css, which owns the tokens, the brass, the gauges and the felt.

   The shape below — a standing character bar, a rail of destinations, one stage
   that changes — is the browser-RPG convention this client was asked to adopt.
   The surface is entirely this game's: the same leather, the same brass, the
   same two faces, the same one candle. A borrowed skeleton wearing its own skin
   is the whole brief. */

#view-game { min-height: 100dvh; }

/* ---------------------------------------------------------------------------
   The character bar. It never leaves, which is the point: the hunt table used
   to carry its own copy of these numbers, and a second copy is a copy that can
   be stale. There is one now, above everything.
--------------------------------------------------------------------------- */

.hud {
  position: sticky;
  top: 0;
  z-index: 12;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem 1.2rem;
  padding: 0.7rem 1.25rem;
  border-bottom: 2px solid var(--brass-dark);
  background: linear-gradient(180deg, rgba(23, 17, 31, 0.97), rgba(10, 8, 16, 0.92));
  backdrop-filter: blur(8px);
  box-shadow: 0 10px 26px rgba(0, 0, 0, 0.5);
}

.hud-portrait {
  width: 52px;
  height: 52px;
  flex-shrink: 0;
  display: grid;
  place-items: center;
  overflow: hidden;
  border: 2px solid var(--brass-dark);
  border-radius: 50%;
  background: var(--leather-lo);
  box-shadow: inset 0 1px 0 var(--brass-edge), 0 3px 8px rgba(0, 0, 0, 0.55);
}
.hud-portrait img { width: 100%; height: 100%; object-fit: cover; }
.hud-portrait svg { width: 22px; height: 22px; color: var(--border-lit); }

.hud-who { min-width: 8rem; }
.hud-who h1 {
  margin: 0;
  font-family: 'Cinzel', Georgia, serif;
  font-size: var(--fs-body);
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--gold-bright);
}
.hud-who p {
  margin: 0;
  font-size: var(--fs-nano);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--dim);
}
.hud-vip {
  margin-left: 0.4rem;
  padding: 0.05em 0.4em;
  border: 1px solid var(--brass-dark);
  border-radius: 3px;
  font-size: var(--fs-nano);
  letter-spacing: 0.1em;
  color: var(--gold);
}

.hud-gauges {
  flex: 1 1 22rem;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0.2rem 1.1rem;
}
.hud-gauges .gauge { margin-bottom: 0; }
.gauge-xp .gauge-fill { background: linear-gradient(180deg, #6f8bd0, #2f3f6b); }

.hud-purse { display: flex; gap: 0.9rem; flex-shrink: 0; }
.coin {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  font-variant-numeric: tabular-nums;
  font-size: var(--fs-small);
}
/* 16, not 14: these three are the only icons that must be told apart from each other rather
   than merely recognised, and two pixels is the difference between a shape and a smudge. */
.coin svg { width: 16px; height: 16px; }
.coin-gold { color: var(--gold-bright); }
.coin-gems { color: #a695dd; }
.coin-fragments { color: #cf8f6a; }
.coin i { color: var(--dim); font-style: normal; margin: 0 0.15rem; }

.hud-ailments { display: flex; flex-wrap: wrap; gap: 0.35rem; }

.hud-event {
  margin: 0;
  padding: 0.55rem 1.25rem;
  border-bottom: var(--rule);
  background: rgba(201, 162, 74, 0.09);
  color: var(--gold-bright);
  font-size: var(--fs-small);
  text-align: center;
}
.hud-event[hidden] { display: none; }

/* ---------------------------------------------------------------------------
   The rail. The bot's own hubs, in the bot's own order — a player who learned
   where the Forge lives in Telegram must not have to learn it twice. Arena is
   absent from both, and for the same reason: it stays dark until the population
   justifies it.
--------------------------------------------------------------------------- */

.rail {
  flex-basis: 100%;
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem 1.6rem;
  padding-top: 0.7rem;
  border-top: var(--rule);
}
/* On a wide screen a group is not a drawer at all: the marker is hidden, the summary is
   just the label, and the whole thing lies flat — the rail the desk always had. The <details>
   only becomes a drawer inside the phone block below. */
.rail-group { display: flex; align-items: baseline; gap: 0.55rem; flex-wrap: wrap; }
.rail-group > summary { list-style: none; cursor: default; }
.rail-group > summary::-webkit-details-marker { display: none; }
.rail-group > summary svg { display: none; }
.rail-items { display: flex; align-items: baseline; gap: 0.55rem; flex-wrap: wrap; }
/* Sign-out belongs to the header on a wide screen. The rail carries its own copy only on a
   phone, where the header has run out of width and hides the header one — showing both at
   once put the same control on the screen twice. */
.rail-group.is-session { display: none; }
.rail-group > summary > span {
  margin: 0;
  font-family: 'Cinzel', Georgia, serif;
  font-size: var(--fs-nano);
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--brass-text);
}
.rail-link {
  padding: 0.28rem 0.55rem;
  border: 1px solid transparent;
  border-radius: 4px;
  font-family: 'Cinzel', Georgia, serif;
  font-size: var(--fs-micro);
  letter-spacing: 0.06em;
  color: var(--dim);
  text-decoration: none;
  transition: color 0.18s var(--ease), border-color 0.18s var(--ease), background-color 0.18s var(--ease);
}
.rail-link:hover { color: var(--gold-bright); background: rgba(201, 162, 74, 0.08); }
.rail-link.is-on {
  color: var(--gold-bright);
  border-color: var(--brass-dark);
  background: rgba(201, 162, 74, 0.13);
  box-shadow: inset 0 1px 0 var(--brass-edge);
}

.rail-button { display: none; }
.rail-button svg { width: 20px; height: 20px; color: var(--gold); }

/* ---------------------------------------------------------------------------
   The stage
--------------------------------------------------------------------------- */

.stage {
  flex: 1;
  width: min(1440px, 100%);
  margin: 0 auto;
  padding: 1.5rem 1.5rem 3rem;
}
/* The hunt brings its own full-bleed composition and must not be padded twice. */
.stage[data-panel="hunt"] { padding: 0; }
.stage-wait {
  padding: 4rem 0;
  text-align: center;
  font-family: 'Cinzel', Georgia, serif;
  font-size: var(--fs-micro);
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--dim);
}

.panel-head { margin-bottom: 1.5rem; }
.panel-head h1 {
  margin: 0 0 0.35rem;
  font-family: 'Cinzel', Georgia, serif;
  font-size: var(--fs-title);
  font-weight: 700;
  letter-spacing: 0.03em;
  color: var(--gold-bright);
}
.panel-head p { margin: 0; max-width: 62ch; color: var(--dim); font-size: var(--fs-small); }
.panel-empty { padding: 3rem 1rem; text-align: center; color: var(--dim); font-style: italic; }
.fine { margin-top: 1.5rem; max-width: 68ch; color: var(--dim); font-size: var(--fs-micro); line-height: 1.7; }
.lines { display: grid; gap: 0.3rem; }
.lines p { margin: 0; font-size: var(--fs-small); color: var(--text); }

/* --- tabs, toolbars, chips ------------------------------------------------ */

.toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.6rem 1rem;
  margin-bottom: 1.25rem;
}
.tabs { display: flex; flex-wrap: wrap; gap: 0.3rem; }
.tab {
  padding: 0.42rem 0.85rem;
  border: 1px solid var(--border);
  border-radius: 4px;
  background: rgba(12, 9, 18, 0.6);
  color: var(--dim);
  font-family: 'Cinzel', Georgia, serif;
  font-size: var(--fs-micro);
  letter-spacing: 0.08em;
  cursor: pointer;
  transition: color 0.18s var(--ease), border-color 0.18s var(--ease), background-color 0.18s var(--ease);
}
.tab:hover { color: var(--gold-bright); border-color: var(--border-lit); }
.tab.is-on { color: var(--gold-bright); border-color: var(--brass-dark); background: rgba(201, 162, 74, 0.14); }
.tabs.is-sub { margin: -0.5rem 0 1.25rem; }
/* The auction board's ordering, under the Browse/Sell/My listings row rather than beside it:
   they answer different questions and reading them as one row of seven buttons does not. */
.sort-tabs { margin: -0.6rem 0 1rem; }

.search {
  flex: 1 1 12rem;
  max-width: 22rem;
  padding: 0.5rem 0.8rem;
  border: 1px solid var(--border);
  border-radius: 4px;
  background: rgba(0, 0, 0, 0.4);
  color: var(--text);
  font-family: 'Spectral', Georgia, serif;
  font-size: var(--fs-small);
}
.search::placeholder { color: var(--dim); opacity: 0.7; }

.chip-row { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-bottom: 1.25rem; }
.chip {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0.35rem 0.7rem 0.35rem 0.35rem;
  border: 1px solid var(--border);
  border-radius: 4px;
  background: rgba(12, 9, 18, 0.6);
  color: var(--dim);
  font-family: 'Cinzel', Georgia, serif;
  font-size: var(--fs-micro);
  cursor: pointer;
}
.chip.is-on { color: var(--gold-bright); border-color: var(--brass-dark); background: rgba(201, 162, 74, 0.14); }

/* --- cards ---------------------------------------------------------------- */

.card-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 1rem; }
.card {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  padding: 1rem;
  border: var(--rule);
  border-radius: 5px;
  background: linear-gradient(165deg, rgba(30, 23, 42, 0.95), rgba(16, 12, 24, 0.97));
  box-shadow: 0 10px 24px rgba(0, 0, 0, 0.45), inset 0 1px 0 rgba(255, 255, 255, 0.03);
}
.card h2 {
  margin: 0;
  font-family: 'Cinzel', Georgia, serif;
  font-size: var(--fs-body);
  font-weight: 600;
  color: var(--text);
}
.card h2 i { font-style: normal; color: var(--dim); font-size: var(--fs-micro); }
.card-desc { margin: 0; font-size: var(--fs-small); color: var(--dim); line-height: 1.55; }
.card.is-on { border-color: var(--brass-dark); box-shadow: 0 0 0 1px rgba(201, 162, 74, 0.2), 0 10px 24px rgba(0, 0, 0, 0.45); }
.card.is-locked { opacity: 0.55; }
.card.is-done { border-color: var(--brass-dark); }

.row-acts { display: flex; flex-wrap: wrap; gap: 0.6rem; margin-top: 1.5rem; }

/* The roster's portraits. A fixed ratio rather than a fixed height: the class
   plates are 3:2 busts, and letting them set their own height makes the three
   cards in a row disagree about where their names sit. */
.roster-art {
  aspect-ratio: 3 / 2;
  overflow: hidden;
  border: var(--rule);
  border-radius: 4px;
  background: rgba(0, 0, 0, 0.35);
  display: flex;
  align-items: center;
  justify-content: center;
}
.roster-art img { width: 100%; height: 100%; object-fit: cover; object-position: 50% 18%; }
.roster-art svg { width: 34px; height: 34px; color: var(--border-lit); }
.roster-confirm h2 { margin: 0 0 0.4rem; font-family: 'Cinzel', Georgia, serif; font-size: var(--fs-body); color: var(--text); }
.item-acts { display: flex; flex-wrap: wrap; gap: 0.4rem; margin-top: auto; padding-top: 0.5rem; }

.counter.is-small { min-width: 0; padding: 0.45rem 0.75rem; font-size: var(--fs-nano); letter-spacing: 0.08em; }
a.counter { text-decoration: none; display: inline-flex; flex-direction: column; align-items: center; justify-content: center; }

/* --- tags and badges ------------------------------------------------------ */

.tag, .badge {
  display: inline-block;
  padding: 0.1em 0.5em;
  border: 1px solid var(--border);
  border-radius: 3px;
  font-family: 'Cinzel', Georgia, serif;
  font-size: var(--fs-nano);
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--dim);
}
.tag-row, .item-tags, .badges { display: flex; flex-wrap: wrap; gap: 0.3rem; margin: 0; }
.tag.is-on, .badge.is-vip { color: var(--gold-bright); border-color: var(--brass-dark); }
.tag.is-plus { color: #a695dd; border-color: #4a3a66; }
.badge.is-founder { color: var(--gold-bright); border-color: var(--brass-dark); background: rgba(201, 162, 74, 0.1); }

/* Rarity is the one colour code this game already teaches everywhere else, so
   it keeps the same five steps here rather than inventing a sixth vocabulary. */
[data-rarity="common"]    { color: #b9b2c8; }
[data-rarity="uncommon"]  { color: #7fb08a; border-color: #33513a; }
[data-rarity="rare"]      { color: #7f9ed0; border-color: #2f4468; }
[data-rarity="epic"]      { color: #b285d8; border-color: #4b3369; }
[data-rarity="legendary"] { color: var(--gold-bright); border-color: var(--brass-dark); }

/* --- item art ------------------------------------------------------------- */

.item-art {
  position: relative;
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  flex-shrink: 0;
  border: 1px solid var(--border);
  border-radius: 4px;
  background: rgba(0, 0, 0, 0.45);
  overflow: hidden;
}
.item-art.is-big { width: 68px; height: 68px; }
.item-art img { width: 100%; height: 100%; object-fit: contain; image-rendering: pixelated; }
.item-art.is-blank svg { width: 18px; height: 18px; color: var(--border-lit); }
.item-art[data-rarity="uncommon"]  { border-color: #33513a; }
.item-art[data-rarity="rare"]      { border-color: #2f4468; }
.item-art[data-rarity="epic"]      { border-color: #4b3369; }
.item-art[data-rarity="legendary"] { border-color: var(--brass-dark); }
/* The cosmetic aura the bot composites into the icon file itself. That composite
   lives in a disk cache inside the bot container the wiki build has never seen,
   so here it is a ring of light over the plain icon — same purchase, same tiers,
   drawn instead of baked. */
.item-art.has-aura::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  box-shadow: inset 0 0 12px var(--aura-glow, rgba(201, 162, 74, 0.6));
}
.item-art[data-aura="ember"] { --aura-glow: rgba(214, 118, 60, 0.7); }
.item-art[data-aura="frost"] { --aura-glow: rgba(120, 178, 216, 0.7); }
.item-art[data-aura="void"]  { --aura-glow: rgba(150, 110, 210, 0.7); }
.item-art[data-aura="gold"]  { --aura-glow: rgba(232, 200, 118, 0.75); }

/* --- the pack ------------------------------------------------------------- */

.pack-group { margin-bottom: 2rem; }
.pack-group h2 {
  margin: 0 0 0.75rem;
  font-family: 'Cinzel', Georgia, serif;
  font-size: var(--fs-large);
  font-weight: 600;
  letter-spacing: 0.05em;
  color: var(--gold);
}
.pack-group h2 i { font-style: normal; font-size: var(--fs-micro); color: var(--dim); }
.pack-group.is-worn h2 { color: var(--gold-bright); }

.item-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); gap: 0.7rem; align-items: start; }
.item {
  border: var(--rule);
  border-radius: 5px;
  background: linear-gradient(165deg, rgba(28, 21, 40, 0.93), rgba(15, 11, 23, 0.96));
  overflow: hidden;
}
.item.is-equipped { border-color: var(--brass-dark); }
.item.is-open { box-shadow: 0 12px 28px rgba(0, 0, 0, 0.5); }
.item-face {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  grid-template-rows: auto auto;
  gap: 0.15rem 0.7rem;
  width: 100%;
  padding: 0.65rem 0.75rem;
  border: 0;
  background: none;
  color: inherit;
  text-align: left;
  cursor: pointer;
  font: inherit;
}
.item-face .item-art { grid-row: span 2; }
.item-name { font-size: var(--fs-small); color: var(--text); align-self: end; }
.item-name i { font-style: normal; color: var(--dim); }
.item-face:hover .item-name { color: var(--gold-bright); }

.item-detail { padding: 0.2rem 0.75rem 0.85rem; border-top: 1px solid rgba(46, 37, 64, 0.7); }
.item-detail > p { margin: 0.45rem 0 0; font-size: var(--fs-small); }
.item-slot {
  font-family: 'Cinzel', Georgia, serif;
  font-size: var(--fs-nano);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--brass-text);
}
.item-desc { color: var(--dim); line-height: 1.5; }
.item-stats { font-variant-numeric: tabular-nums; color: var(--text); }
.item-affix { color: #a695dd; }
.item-warn { color: #e9a8a8; }
.item-delta.is-up { color: #8fc79a; }
.item-delta.is-down { color: #c78c8c; }
.item-delta.is-same { color: var(--dim); }

/* --- the full character sheet -------------------------------------------- */

.sheet-full {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 1.5rem;
  padding: 1.25rem;
  border: var(--rule);
  border-radius: 5px;
  background: linear-gradient(165deg, rgba(30, 23, 42, 0.95), rgba(16, 12, 24, 0.97));
  box-shadow: 0 14px 34px rgba(0, 0, 0, 0.5);
}
.hero-portrait {
  width: 148px;
  height: 148px;
  display: grid;
  place-items: center;
  overflow: hidden;
  border: 2px solid var(--brass-dark);
  border-radius: 4px;
  background: var(--leather-lo);
}
.hero-portrait img { width: 100%; height: 100%; object-fit: cover; }
.hero-portrait svg { width: 40px; height: 40px; color: var(--border-lit); }
.hero-body h2 {
  margin: 0;
  font-family: 'Cinzel', Georgia, serif;
  font-size: var(--fs-section);
  font-weight: 700;
  color: var(--gold-bright);
}
.hero-order { margin: 0.15rem 0 0.8rem; font-size: var(--fs-small); color: var(--dim); }
.hero-gauges { display: grid; gap: 0.55rem; margin: 1rem 0; }
.gauge-row {
  display: grid;
  grid-template-columns: 6.5rem minmax(0, 1fr) auto;
  align-items: center;
  gap: 0.75rem;
  font-size: var(--fs-micro);
  color: var(--dim);
}
.gauge-row.is-wide { max-width: 34rem; margin-bottom: 1rem; }
.gauge-row b { color: var(--text); font-variant-numeric: tabular-nums; font-weight: 600; }
.gauge-row .gauge { margin: 0; }

.stat-row { display: flex; flex-wrap: wrap; gap: 1.5rem; margin-top: 0.85rem; }
.stat { text-align: center; }
.stat b {
  display: block;
  font-family: 'Cinzel', Georgia, serif;
  font-size: var(--fs-large);
  color: var(--gold-bright);
  font-variant-numeric: tabular-nums;
}
.stat span { font-size: var(--fs-nano); letter-spacing: 0.14em; text-transform: uppercase; color: var(--dim); }
.stat-row.is-quiet .stat b { font-size: var(--fs-body); color: var(--text); }
.note-line { margin: 0.9rem 0 0; font-size: var(--fs-small); color: var(--dim); }

/* --- skills, training, quests, forge, markets ---------------------------- */

.skill.is-on { border-color: var(--brass-dark); background: linear-gradient(165deg, rgba(48, 37, 22, 0.6), rgba(16, 12, 24, 0.97)); }
.skill-scale, .train-cost, .quest-count, .forge-odds, .recipe-cost,
.recipe-have, .pack-price, .listing-price, .listing-seller, .map-range, .map-boss {
  margin: 0;
  font-size: var(--fs-small);
  color: var(--dim);
  font-variant-numeric: tabular-nums;
}
.skill-state, .map-here {
  margin: 0;
  font-family: 'Cinzel', Georgia, serif;
  font-size: var(--fs-nano);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--brass-text);
}
.map-here { color: var(--gold-bright); }
.train h2 i { float: right; font-style: normal; color: var(--gold-bright); font-variant-numeric: tabular-nums; }
.recipe-have.is-short { color: #c78c8c; }
.forge-odds b { color: var(--gold-bright); }
.pack-price { color: var(--gold-bright); font-size: var(--fs-body); }
.pack-price i { color: var(--dim); font-size: var(--fs-small); font-style: normal; }
.quest .gauge { margin: 0.3rem 0 0.15rem; }
.recipe h2 { text-transform: capitalize; }

/* --- maps ----------------------------------------------------------------- */

.map-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 1rem; }
.map-card {
  display: flex;
  flex-direction: column;
  border: var(--rule);
  border-radius: 5px;
  overflow: hidden;
  background: linear-gradient(165deg, rgba(30, 23, 42, 0.95), rgba(16, 12, 24, 0.97));
}
.map-card.is-current { border-color: var(--brass-dark); box-shadow: 0 0 0 1px rgba(201, 162, 74, 0.18); }
.map-card.is-steep .map-art { filter: grayscale(0.4) brightness(0.75); }
.map-art { aspect-ratio: 16 / 9; background: var(--leather-lo) center / cover no-repeat; border-bottom: var(--rule); }
.map-body { display: flex; flex-direction: column; gap: 0.3rem; padding: 0.9rem 1rem 1rem; }
.map-body h2 { margin: 0; font-family: 'Cinzel', Georgia, serif; font-size: var(--fs-large); color: var(--gold-bright); }
.map-body .counter { margin-top: 0.6rem; align-self: flex-start; }

/* --- raid and idle -------------------------------------------------------- */

.raid { display: grid; grid-template-columns: minmax(0, 320px) minmax(0, 1fr); gap: 1.5rem; align-items: start; }
.raid-art {
  aspect-ratio: 4 / 5;
  border: 2px solid var(--brass-dark);
  border-radius: 5px;
  background: var(--leather-lo) center / cover no-repeat;
  box-shadow: 0 14px 34px rgba(0, 0, 0, 0.55);
}
.raid-body h2 { margin: 0 0 0.9rem; font-family: 'Cinzel', Georgia, serif; font-size: var(--fs-title); color: var(--gold-bright); }
.board-lines { margin-top: 1.5rem; padding-top: 1rem; border-top: var(--rule); }

.idle {
  display: grid;
  place-items: center;
  gap: 0.35rem;
  padding: 3rem 1.5rem;
  text-align: center;
  border: 1px dashed var(--border-lit);
  border-radius: 6px;
  background: rgba(12, 9, 18, 0.5);
}
.idle svg { width: 42px; height: 42px; color: var(--border-lit); }
.idle h2 { margin: 0.5rem 0 0; font-family: 'Cinzel', Georgia, serif; font-size: var(--fs-large); color: var(--gold-bright); }
.idle p { margin: 0; color: var(--dim); }

/* --- guild roster --------------------------------------------------------- */

.roster { width: 100%; border-collapse: collapse; font-size: var(--fs-small); }
.roster th {
  padding: 0.5rem 0.6rem;
  border-bottom: 1px solid var(--brass-dark);
  text-align: left;
  font-family: 'Cinzel', Georgia, serif;
  font-size: var(--fs-nano);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--brass-text);
  font-weight: 600;
}
.roster td { padding: 0.55rem 0.6rem; border-bottom: 1px solid rgba(46, 37, 64, 0.6); text-transform: capitalize; }
.roster tr:hover td { background: rgba(201, 162, 74, 0.05); }
.roster-acts { display: flex; flex-wrap: wrap; gap: 0.3rem; }

/* --- forms ---------------------------------------------------------------- */

.sell-form, .found-form, .report-form, .link-box {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.6rem;
  margin: 1.5rem 0;
  padding: 1.1rem 1.2rem;
  border: var(--rule);
  border-radius: 5px;
  background: rgba(12, 9, 18, 0.55);
}
.report-form { flex-direction: column; align-items: stretch; max-width: 62ch; }
.sell-form label, .found-form label {
  font-family: 'Cinzel', Georgia, serif;
  font-size: var(--fs-micro);
  letter-spacing: 0.1em;
  color: var(--dim);
}
.sell-form input, .found-form input, .report-form textarea, .link-box input {
  flex: 1 1 12rem;
  padding: 0.55rem 0.8rem;
  border: 1px solid var(--border);
  border-radius: 4px;
  background: rgba(0, 0, 0, 0.45);
  color: var(--text);
  font-family: 'Spectral', Georgia, serif;
  font-size: var(--fs-small);
}
.report-form textarea { resize: vertical; line-height: 1.6; }
.report-form button { align-self: flex-start; }
.sell-form .fine { flex-basis: 100%; margin: 0; }
.link-box input { font-family: ui-monospace, SFMono-Regular, Consolas, monospace; font-size: var(--fs-micro); }

.notice-inline {
  display: flex;
  align-items: flex-start;
  gap: 0.6rem;
  max-width: 68ch;
  margin: 0 0 1.5rem;
  padding: 0.8rem 1rem;
  border: 1px solid var(--brass-dark);
  border-radius: 4px;
  background: rgba(201, 162, 74, 0.08);
  color: var(--text);
  font-size: var(--fs-small);
}
.notice-inline svg { width: 16px; height: 16px; flex-shrink: 0; margin-top: 0.25em; color: var(--gold); }

/* ---------------------------------------------------------------------------
   Notices, restated. The base .notice in play.css is a refusal, in blood. Two
   other things happen on these screens — something worked, and something is
   merely worth knowing — and showing all three in the colour of failure is how
   a player learns to stop reading the box.
--------------------------------------------------------------------------- */

.notice { margin: 0.9rem 1.5rem 0; }
.notice[data-kind="good"] {
  border-color: var(--brass-dark);
  background: rgba(201, 162, 74, 0.12);
  color: var(--gold-bright);
}
.notice[data-kind="info"] {
  border-color: var(--border-lit);
  background: rgba(138, 118, 201, 0.1);
  color: var(--text);
}
.notice[data-fresh] { animation: ink 0.4s var(--ease) both; }

.counter-empty { align-self: center; color: var(--dim); font-size: var(--fs-small); font-style: italic; }
.verdict-acts { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 0.9rem; }

/* --- the foot ------------------------------------------------------------- */

.foot {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 1.5rem;
  padding: 1.5rem 1.25rem calc(1.5rem + env(safe-area-inset-bottom));
  border-top: var(--rule);
  font-family: 'Cinzel', Georgia, serif;
  font-size: var(--fs-micro);
  letter-spacing: 0.1em;
}
.foot a { color: var(--dim); text-decoration: none; }
.foot a:hover { color: var(--gold-bright); }

/* ---------------------------------------------------------------------------
   Phone
--------------------------------------------------------------------------- */

@media (max-width: 959px) {
  .hud { padding: 0.6rem 0.85rem; gap: 0.55rem 0.8rem; }
  .hud-portrait { width: 40px; height: 40px; }
  .hud-who { min-width: 0; flex: 1 1 auto; }
  .hud-gauges { flex-basis: 100%; gap: 0.15rem 0.6rem; }
  .hud-gauges .gauge-head span { display: none; }
  .hud-purse { flex-basis: 100%; justify-content: space-between; }
  #btn-signout { display: none; }
  .rail-group.is-session { display: block; }

  /* The rail goes behind a control here, because nineteen destinations across
     the top of a 390px screen is not a rail, it is the whole screen. It is a
     checkbox and not a script so the very first tap works, before any module
     has finished parsing. Sign-out moves into it, since the header row has run
     out of width and a hidden control with no other door is a trapped player. */
  .rail-button { display: grid; place-items: center; width: 44px; height: 44px; flex-shrink: 0; cursor: pointer; }
  /* The drawer is capped by what is ACTUALLY on screen, not by `dvh`. Inside Telegram's
     in-app browser `dvh` resolves against the whole screen, chrome included, so `55dvh`
     could be taller than the space left under the character bar — the bottom of the
     Character drawer (Forge, Achievements) fell off the screen with nothing able to
     scroll, because the bar is `position: sticky` and a sticky box does not scroll.
     `--app-vh` is measured in app.js from the visual viewport; `10rem` is the character
     bar above the drawer. Reported by a player: "Where is the craft option in browser
     found? If its below the 'Train' option under Character tab.... its unreachable." */
  .rail {
    display: none;
    /* `--rail-max` is measured from the rail's own top edge in app.js and is the one that is
       right on a bar of any height; the two behind it are fallbacks for the frames before
       the script has run. */
    max-height: var(--rail-max, min(55dvh, calc(var(--app-vh, 100dvh) - 10rem)));
    overflow-y: auto;
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
  }
  /* nowrap matters: the base rail wraps, and a *column* flex that wraps splits into
     columns once it hits the max-height — which turned five full-width drawers into two
     ragged 167px stacks. */
  #rail-toggle:checked ~ .rail {
    display: flex;
    flex-direction: column;
    flex-wrap: nowrap;
    gap: 0.4rem;
  }

  /* Here the groups become real drawers. Nineteen destinations wrapped across a 390px
     screen was six ragged rows with the group name stranded on the same line as its first
     entry — it read as a word cloud, not a menu. Closed, the whole rail is five headings a
     thumb can take in at once; open, one group at a time, each entry on its own full-width
     row. Only the group you are currently inside starts open. */
  .rail-group {
    display: block;
    border: 1px solid var(--border);
    border-radius: 5px;
    background: rgba(255, 255, 255, 0.022);
    overflow: hidden;
  }
  .rail-group > summary {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.6rem;
    /* 44px of thumb, and the whole bar is the target — not just the words. */
    min-height: 44px;
    padding: 0.55rem 0.85rem;
    cursor: pointer;
    /* Stops the long-press "select text" fight on a control that is tapped constantly. */
    user-select: none;
    -webkit-tap-highlight-color: transparent;
  }
  .rail-group[open] > summary { border-bottom: 1px solid var(--border); }
  .rail-group > summary svg {
    display: block;
    width: 16px;
    height: 16px;
    flex-shrink: 0;
    color: var(--brass-text);
    transform: rotate(180deg);
    transition: transform 0.18s var(--ease);
  }
  .rail-group[open] > summary svg { transform: rotate(0deg); }
  /* A closed <details> hides its content only while nothing has imposed a `display` on it.
     The desktop rule above sets `.rail-items { display: flex }` precisely so a group always
     reads open on a desk — which meant every drawer here was open too, closed or not, and
     all twenty destinations were on screen at once. So the state is driven explicitly. */
  .rail-group:not([open]) > .rail-items { display: none; }
  .rail-group[open] > .rail-items { display: block; padding: 0.2rem 0.35rem 0.4rem; }
  .rail-items .rail-link { display: block; }

  /* Everything a thumb has to land on clears 44px here. On a desktop these are
     mouse targets and 31px is generous; on a phone a menu of twenty entries at
     31px is a menu you hit the wrong row of. */
  .rail-link { padding: 0.82rem 0.6rem; }
  .tab, .chip { padding: 0.8rem 0.9rem; }
  .counter.is-small { padding: 0.82rem 0.9rem; }

  .stage { padding: 1.1rem 0.9rem 2.5rem; }
  .panel-head h1 { font-size: var(--fs-section); }
  .card-grid, .item-grid, .map-grid { grid-template-columns: 1fr; }
  .sheet-full { grid-template-columns: 1fr; gap: 1rem; }
  .hero-portrait { width: 100%; height: auto; aspect-ratio: 3 / 2; }

  /* One column of full-width cards, so a 3:2 portrait is nearly a whole screen
     each and a roster of three becomes a scroll. Wider and shorter here: the
     roster is a list to pick from, not a gallery. */
  .roster-art { aspect-ratio: 16 / 7; }
  .gauge-row { grid-template-columns: 5rem minmax(0, 1fr) auto; gap: 0.5rem; }
  .raid { grid-template-columns: 1fr; }
  .roster th:nth-child(3), .roster td:nth-child(3) { display: none; }
  .notice { margin: 0.7rem 0.9rem 0; }
}

/* --- the worn rack, on the character sheet -------------------------------- */
/* A sheet that lists STR and DEX but not the sword in the character's hand is a spreadsheet.
   Two columns on a desk, one on a phone; the icons carry it, the labels only confirm. */
.worn-rack { margin-top: 1rem; }
.worn-rack h3 {
  margin: 0 0 0.5rem;
  font-family: 'Cinzel', Georgia, serif;
  font-size: var(--fs-nano);
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--dim);
}
.worn-list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 0.45rem;
  margin: 0;
  padding: 0;
  list-style: none;
}
.worn-item {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  min-width: 0;
  padding: 0.4rem 0.55rem;
  border: 1px solid var(--border);
  border-radius: 4px;
  background: rgba(255, 255, 255, 0.022);
}
.worn-item img, .worn-blank {
  width: 34px;
  height: 34px;
  flex-shrink: 0;
  border-radius: 3px;
  background: rgba(0, 0, 0, 0.35);
  object-fit: contain;
}
.worn-text { display: flex; flex-direction: column; min-width: 0; }
.worn-text b {
  font-size: var(--fs-small);
  color: var(--ink);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.worn-text small {
  font-size: var(--fs-nano);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--dim);
}
