/*
 * Desktop-only styling (architecture#ui-layout, goal G8). The visual channels are kept deliberately
 * distinct (spec#visual-encoding) so they never collide on one row:
 *   current turn  -> row background tint (.row-current)
 *   bloodied      -> HP-bar fill color   (.hp-bloodied)
 *   disabled      -> row opacity         (.row-disabled)
 *   player/monster-> icon + side accent  (.row-player / .row-monster)
 *   dead-pending  -> strike-through      (.row-dead)
 *   flash         -> transient highlight  (.row-flash, one render pass)
 */

:root {
  --bg: #1b1d23;
  --panel: #24272f;
  --panel-2: #2b2f39;
  --border: #3a3f4b;
  --text: #e6e8ec;
  --muted: #9aa0ac;
  --accent: #6ea8fe;
  --player: #5fb0ff;
  --monster: #ff8a6a;
  --danger: #e5534b;
  --hp-ok: #4caf7d;
  --hp-bloodied: #d9803f;
  --current: #34506b;
  --flash: #5a4b1f;
}

* { box-sizing: border-box; }

/*
 * The [hidden] attribute must always win. An author `display:` rule (e.g. .resume-banner{display:flex})
 * otherwise overrides the UA-stylesheet's `[hidden]{display:none}`, leaving elements toggled via the
 * `hidden` attribute permanently visible (this is why the resume banner showed on a fresh launch).
 */
[hidden] { display: none !important; }

body {
  font-family: system-ui, -apple-system, sans-serif;
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-size: 14px;
}

#app {
  max-width: 95vw;
  margin: 0 auto;
  padding: 0 1rem 2rem;
}

button {
  font: inherit;
  color: var(--text);
  background: var(--panel-2);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 0.35rem 0.7rem;
  cursor: pointer;
}
button:hover:not(:disabled) { border-color: var(--accent); }
button:disabled { opacity: 0.4; cursor: default; }

.btn-primary { background: var(--accent); color: #10141c; border-color: var(--accent); font-weight: 600; }
.btn-secondary { background: var(--panel-2); }
.btn-danger { background: var(--danger); border-color: var(--danger); color: #fff; }
.btn-lg { padding: 0.55rem 1.1rem; font-size: 1rem; }

input, select, textarea {
  font: inherit;
  color: var(--text);
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 5px;
  padding: 0.25rem 0.4rem;
}
input[type="number"] { width: 4rem; }

/* ---- Header ------------------------------------------------------------- */
/* Sticky lives on the #header-root WRAPPER, not .app-header: a sticky element can only travel within
 * its containing block, and .app-header's wrapper is exactly header-height (no room to stick). The
 * wrapper's containing block is the full-height #app, so the header stays pinned as the page scrolls. */
#header-root {
  position: sticky;
  top: 0;
  z-index: 10;
  background: var(--bg);
  border-bottom: 1px solid var(--border);
}
.app-header {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 0.75rem 0;
}
.header-status { display: flex; flex-direction: column; }
.round-label { font-size: 1.25rem; font-weight: 700; }
.turn-label { color: var(--muted); }
.header-buttons { display: flex; gap: 0.5rem; margin-left: auto; }

/* Undo/redo cluster: smaller than the large turn buttons, sitting just after them. */
.header-undo { display: flex; gap: 0.35rem; }

/* Round "?" that opens the standalone help page; sits between the turn buttons and the session menu. */
.help-link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.9rem;
  height: 1.9rem;
  border: 1px solid var(--border);
  border-radius: 50%;
  color: var(--muted);
  text-decoration: none;
  font-weight: 700;
  flex: none;
}
.help-link:hover { color: var(--accent); border-color: var(--accent); }

.session-menu { position: relative; }
.menu-button { font-size: 1.2rem; line-height: 1; padding: 0.4rem 0.6rem; }
.session-menu-items {
  display: none;
  position: absolute;
  right: 0;
  top: calc(100% + 4px);
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 0.35rem;
  min-width: 200px;
  box-shadow: 0 8px 24px rgba(0,0,0,0.4);
}
.session-menu.open .session-menu-items { display: flex; flex-direction: column; gap: 2px; }
.menu-item { text-align: left; background: transparent; border: none; padding: 0.5rem; border-radius: 5px; }
.menu-item:hover:not(:disabled) { background: var(--panel-2); }

/* ---- Layout ------------------------------------------------------------- */
/* The right column holds Targets stacked above the combat log. Its width tracks the widest expanded
 * panel (architecture#ui-layout): the log — when open — is wider than the Targets panel; with only
 * Targets open it uses the normal width; with both collapsed it shrinks to just their toggles so the
 * table reclaims the space. The panels stay anchored on the right (never wrapping to the bottom). */
.app-main {
  display: grid;
  grid-template-columns: 1fr 440px;
  gap: 1rem;
  margin-top: 1rem;
  align-items: start;
}
.app-main.side-normal { grid-template-columns: 1fr 440px; }
.app-main.side-selection { grid-template-columns: 1fr 560px; }
.app-main.side-wide { grid-template-columns: 1fr 640px; }
.app-main.side-min { grid-template-columns: 1fr auto; }

/* ---- Initiative table --------------------------------------------------- */
.table-head, .row {
  display: grid;
  grid-template-columns: 2.25rem 4rem 1fr 8rem 5rem 9rem auto;
  align-items: center;
  gap: 0.5rem;
}
.table-head {
  padding: 0.4rem 0.6rem;
  color: var(--muted);
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.row-wrapper {
  border: 1px solid var(--border);
  border-radius: 8px;
  margin-bottom: 0.4rem;
  background: var(--panel);
  overflow: hidden;
}
/* Auto-follow (render.js) top-aligns the current row via scrollIntoView on the `.row-current` element
 * — which is this inner `.row`, not `.row-wrapper` — so the scroll-margin must live here to keep the
 * followed row clear of the sticky header (else scrolling back to the top row tucks it underneath). */
.row { padding: 0.5rem 0.6rem; border-left: 4px solid transparent; scroll-margin-top: 4rem; }
.row-player { border-left-color: var(--player); }
.row-monster { border-left-color: var(--monster); }
.row-current { background: var(--current); }
.row-disabled { opacity: 0.5; background: #15161a; }
.row-dead .creature-name { text-decoration: line-through; }
.row-dead { opacity: 0.7; }
.row-flash { animation: flash 1.2s ease-out; }
@keyframes flash {
  from { background: var(--flash); }
  to { background: transparent; }
}
.row-current.row-flash { animation: none; background: var(--current); }

.cell { min-width: 0; }
.cell-select { display: flex; align-items: center; justify-content: center; }
.cell-select input { cursor: pointer; }
.cell-name { display: flex; align-items: center; gap: 0.4rem; overflow: hidden; }
.creature-name { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.creature-icon { flex: none; }
.expand-toggle { background: transparent; border: none; padding: 0.2rem 0.4rem; color: var(--muted); font-size: 1.25rem; line-height: 1; cursor: pointer; }
.cell-hp-empty { color: var(--muted); text-align: center; }

.hp-bar {
  height: 8px;
  background: var(--panel-2);
  border: 1px solid var(--border);
  border-radius: 4px;
  overflow: hidden;
  margin-bottom: 3px;
}
/* Target-panel bar: thin, fills its fixed-width HP block (below). */
.hp-bar-sm { height: 4px; margin: 0; }
.hp-fill { height: 100%; background: var(--hp-ok); }
.hp-fill.hp-bloodied { background: var(--hp-bloodied); }
.input-hp { width: 100%; }

.cell-ac { display: flex; align-items: center; gap: 0.3rem; }
.ac-label { color: var(--muted); font-size: 0.75rem; }
.input-ac { width: 4rem; }
.select-target { width: 100%; }

.cell-rolltype { display: flex; gap: 0.25rem; flex-wrap: wrap; align-items: center; }
.rolltype-badge { font-size: 0.7rem; font-weight: 700; padding: 0.1rem 0.3rem; border-radius: 4px; }
.rolltype-advantage { background: #2f5d3a; color: #b7f0c4; }
.rolltype-disadvantage { background: #5d2f2f; color: #f0b7b7; }

/* At-a-glance condition chips at the right of the name cell, hugging the HP box (margin-left: auto);
 * the creature name shrinks/ellipsizes to make room. Display-only — the expand row edits conditions. */
.row-conditions { margin-left: auto; display: flex; gap: 0.25rem; flex: none; align-items: center; overflow: hidden; }
.row-condition-chip {
  background: var(--accent);
  color: #10141c;
  border-radius: 10px;
  padding: 0.05rem 0.4rem;
  font-size: 0.7rem;
  font-weight: 600;
  white-space: nowrap;
  cursor: default;
}
/* The "+N more" marker: outlined rather than filled, so it reads as a count, not a condition. */
.row-condition-more { background: transparent; border: 1px solid var(--accent); color: var(--accent); }

/* ---- Row expand section ------------------------------------------------- */
.row-expand {
  border-top: 1px solid var(--border);
  background: var(--panel-2);
  padding: 0.6rem;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}
.expand-field { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; }
.expand-label { color: var(--muted); width: 5rem; flex: none; font-size: 0.8rem; }
.dm-mods { gap: 0.75rem; }
.dm-mod { display: flex; align-items: center; gap: 0.25rem; }
.dm-mod input { width: 3.5rem; }
/* HP-max shares the "Mod" row but holds larger values (e.g. "120"), so give it a touch more width. */
.dm-mod .input-maxhp { width: 4.5rem; }

/* The six save badges + adv/disadv dropdown, pushed to the right edge of the Attack line. */
.saving-throws { margin-left: auto; display: flex; gap: 0.3rem; align-items: center; }
.save-roll {
  font-size: 0.75rem;
  padding: 0.15rem 0.4rem;
  border-radius: 12px;
  background: transparent;
  border: 1px solid var(--border);
  color: var(--muted);
}
.save-roll:hover:not(:disabled) { color: var(--text); border-color: var(--accent); }
.save-rolltype { width: 3rem; }

.condition-chips { display: flex; gap: 0.3rem; flex-wrap: wrap; }
/* Applied condition: solid, high-contrast fill so active conditions read at a glance. */
.condition-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  background: var(--accent);
  border: 1px solid var(--accent);
  border-radius: 12px;
  padding: 0.1rem 0.5rem;
  font-size: 0.8rem;
  font-weight: 600;
  color: #10141c;
}
.chip-remove { background: transparent; border: none; padding: 0; color: #10141c; font-size: 0.75rem; opacity: 0.7; }
.chip-remove:hover { opacity: 1; }
.condition-presets { display: flex; gap: 0.3rem; flex-wrap: wrap; align-items: center; }
/* Addable preset: muted, dashed outline, no fill — clearly "not yet applied". */
.condition-preset {
  font-size: 0.75rem;
  padding: 0.15rem 0.5rem;
  border-radius: 12px;
  background: transparent;
  border: 1px dashed var(--border);
  color: var(--muted);
}
.condition-preset:hover:not(:disabled) { color: var(--text); border-color: var(--accent); }
.input-condition { width: 10rem; }

/* ---- Dead-confirm bar --------------------------------------------------- */
.dead-confirm {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.5rem 0.6rem;
  background: #3a2323;
  border-top: 1px solid var(--danger);
}

/* ---- Panels (targets + log) --------------------------------------------- */
.panel-header { display: flex; align-items: center; }
.panel-toggle {
  background: transparent;
  border: none;
  font-weight: 600;
  padding: 0.3rem 0;
  color: var(--text);
}
/* The whole panel is a click target that toggles collapse (targetPanel.js / logPanel.js). */
.target-panel, .log-panel { cursor: pointer; }
.panel-body { display: flex; flex-direction: column; gap: 0.6rem; }
.panel-empty { color: var(--muted); font-style: italic; padding: 0.4rem 0; }

/* Pin the whole right column (Targets + combat log) just below the sticky header so both panels —
 * collapsed or expanded — stay on screen while the DM scrolls a large encounter. Sticky lives on the
 * grid item (#side-column), whose containing block .app-main is as tall as the table, so it has room
 * to travel. align-self: start keeps the cell content-height (it doesn't stretch to the table's
 * height). The two panels are stacked with a gap. */
#side-column {
  position: sticky;
  top: 5rem;
  align-self: start;
  display: flex;
  flex-direction: column;
  gap: 1rem;
}
.target-panel {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 0.6rem 0.8rem;
  /* Keep Targets at its own width even when the column widens for an expanded log, so the log reads
   * as the wider panel; left-aligned within the column. */
  max-width: 440px;
  align-self: start;
}
/* Cap the Targets list so a long panel scrolls within itself instead of pushing the log off-screen. */
.target-panel .panel-body { max-height: 70vh; overflow-y: auto; }
.target-group-title { font-weight: 600; color: var(--accent); margin-bottom: 0.3rem; }
.attacker { display: flex; align-items: center; gap: 0.5rem; padding: 0.15rem 0; }
.attacker-disabled { opacity: 0.5; }
.attacker-name { flex: 1 1 auto; min-width: 3rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Fixed-width HP block: bar above, cur/max number below. */
.attacker-hp-block { flex: none; width: 4rem; display: flex; flex-direction: column; gap: 1px; }
.attacker-hp { color: var(--muted); font-size: 0.8rem; }

.log-panel {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 0.6rem 0.8rem;
}
/* The log body scrolls within the panel; capped so a long log never pushes the panel off-screen. */
.log-body { max-height: 70vh; overflow-y: auto; gap: 0.15rem; font-family: ui-monospace, monospace; font-size: 0.85rem; }
.log-line { padding: 0.15rem 0.4rem; border-radius: 3px; }
/* Zebra striping: alternate log lines get a faint background band so each line is easy to separate. */
.log-body > .log-line:nth-child(even) { background: rgba(255, 255, 255, 0.07); }
.log-round { color: var(--accent); font-weight: 700; margin-top: 0.4rem; }
.log-info { color: var(--muted); }
.log-initiative { color: var(--muted); }
.log-hit { color: var(--text); }
.log-crit { color: #fff4c2; font-weight: 600; }
.log-crit-miss { color: #ffb3b3; font-weight: 600; }
.save-badge {
  margin-left: 0.4rem;
  font-size: 0.65rem;
  font-weight: 700;
  background: #3a4a5d;
  color: #bcd6f0;
  padding: 0.05rem 0.3rem;
  border-radius: 4px;
}

/* ---- Selection panel (bulk actions) ------------------------------------- */
/* Interactive panel: only the header toggle is a click target, so the body's inputs/buttons keep
 * their own clicks (unlike the read-only Targets/log panels, where the whole panel toggles). Reuses
 * the row-expand field/condition/save classes so the controls read like the per-row expand. */
.selection-panel {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 0.6rem 0.8rem;
  max-width: 560px;
  align-self: start;
}
/* The empty panel area toggles collapse (selectionPanel.js), so it reads as clickable; the text
 * inputs keep their own caret cursor so they don't look like collapse triggers. */
.selection-panel { cursor: pointer; }
.selection-panel input, .selection-panel select, .selection-panel textarea, .selection-panel label { cursor: auto; }
.selection-panel .panel-body { max-height: 70vh; overflow-y: auto; }
.selection-panel .select-attack, .selection-panel .select-rolltype { min-width: 8rem; }
/* Left-align the save buttons after the label, like the rows above — not pushed right as on the
 * row-expand Attack line (where .saving-throws uses margin-left: auto). */
.selection-panel .saving-throws { margin-left: 0; }

/* ---- Empty state -------------------------------------------------------- */
.empty-state { text-align: center; padding: 4rem 1rem; color: var(--muted); }
.empty-title { font-size: 1.4rem; margin-bottom: 0.5rem; color: var(--text); }

/* ---- Overlays: toast + modal + prompts ---------------------------------- */
.toast {
  position: fixed;
  right: 1.5rem;
  bottom: 1.5rem;
  min-width: 462px;
  max-width: 682px;
  max-height: 70vh;
  overflow-y: auto;
  background: var(--panel);
  border: 1px solid var(--accent);
  border-radius: 8px;
  padding: 0.9rem 1.1rem;
  box-shadow: 0 8px 24px rgba(0,0,0,0.5);
  z-index: 50;
  cursor: pointer;
}
/* Collapsed toast: a thin tab flush against the right edge, revealing the table it covered. */
.toast.toast-collapsed {
  min-width: 0;
  max-width: none;
  width: auto;
  right: 0;
  padding: 0.5rem 0.4rem;
  border-top-right-radius: 0;
  border-bottom-right-radius: 0;
}
.toast-tab {
  writing-mode: vertical-rl;
  transform: rotate(180deg);
  font-size: 0.8rem;
  color: var(--muted);
  letter-spacing: 0.05em;
}
.toast-title { font-weight: 600; margin-bottom: 0.5rem; font-size: 1rem; }
/* Per-attack detail: monospace like the log, so hits line up as they did on the Java console. */
.toast-detail {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  font-family: ui-monospace, monospace;
  font-size: 0.85rem;
  margin-bottom: 0.5rem;
}
.toast-line { color: var(--text); line-height: 1.4; padding: 0.15rem 0.4rem; border-radius: 3px; }
/* Zebra striping: alternate attack lines get a faint background band to separate them. */
.toast-detail > .toast-line:nth-child(even) { background: rgba(255, 255, 255, 0.07); }
.toast-crit { color: #fff4c2; font-weight: 600; }
/* Per-player summary sits below the detail, set off by a divider. */
.toast-summary {
  border-top: 1px solid var(--border);
  padding-top: 0.4rem;
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
}
.toast-row { color: var(--muted); font-size: 0.9rem; }

.modal-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.55);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 100;
}
.modal {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 1.25rem;
  min-width: 360px;
  max-width: 80vw;
  max-height: 80vh;
  overflow: auto;
  box-shadow: 0 12px 40px rgba(0,0,0,0.6);
}
.modal-title, .prompt-title { font-size: 1.1rem; font-weight: 600; margin-bottom: 0.75rem; }
.modal-message { white-space: pre-wrap; font-family: ui-monospace, monospace; margin: 0 0 1rem; }
.modal-actions { display: flex; justify-content: flex-end; gap: 0.5rem; margin-top: 0.5rem; }
.prompt-modal { min-width: 480px; }
.prompt-status { color: var(--muted); margin: 0.5rem 0; }

/* ---- Startup notices ---------------------------------------------------- */
.fatal { color: var(--danger); padding: 1rem; }
.resume-banner {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  background: var(--panel-2);
  border: 1px solid var(--accent);
  border-radius: 8px;
  padding: 0.6rem 1rem;
  margin: 1rem 0;
}
