/* Light mode is the default UI theme (see #btn-theme-toggle in app.js,
   which flips :root[data-theme] and remembers the choice in localStorage).
   Dark mode, below, is the app's original palette, preserved exactly as it
   was for anyone who switches back to it. */
:root {
  --bg: #f4f5f7;
  --panel: #ffffff;
  --panel-2: #eef1f4;
  --border: #d7dbe1;
  --text: #1a1f27;
  --text-dim: #5c6472;
  --accent: #0d9488;
  --danger: #dc2626;
  --topbar-bg: #ffffff;
  --tag-warn: #b91c1c;
  --tag-info: #0369a1;
  --banner-warn-bg: #fef3c7;
  --banner-warn-border: #fde68a;
  --banner-warn-text: #92400e;
  --radius: 12px;
  font-family: 'Inter', system-ui, sans-serif;
}

:root[data-theme="dark"] {
  --bg: #0b0e13;
  --panel: #141922;
  --panel-2: #1a2029;
  --border: #262e3a;
  --text: #e8ebef;
  --text-dim: #9aa4b2;
  --accent: #2dd4bf;
  --danger: #ef4444;
  --topbar-bg: #0d1117;
  --tag-warn: #ffb4b4;
  --tag-info: #7dd3fc;
  --banner-warn-bg: #2a2010;
  --banner-warn-border: #4a3a18;
  --banner-warn-text: #f0c96b;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  min-height: 100vh;
}

.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 28px;
  border-bottom: 1px solid var(--border);
  background: var(--topbar-bg);
  position: sticky;
  top: 0;
  z-index: 10;
  flex-wrap: wrap;
  gap: 12px;
}

.brand {
  display: flex;
  align-items: center;
  gap: 8px;
  font-family: 'Rajdhani', sans-serif;
  font-weight: 700;
  font-size: 20px;
  letter-spacing: 0.02em;
}
.brand-mark { width: 34px; height: 34px; display: block; }
.brand strong { color: var(--accent); font-weight: 800; }

.backup-actions { display: flex; align-items: center; gap: 8px; }
.backup-actions .btn-secondary { padding: 7px 12px; font-size: 12.5px; }

/* Icon-only button (currently just the theme toggle): square instead of
   text-width, with the glyph centered and sized up since it's the only
   content — the padding above is sized for icon+label text and would
   otherwise leave a single glyph looking lost in a too-wide button. */
.btn-icon {
  width: 34px;
  height: 34px;
  padding: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 16px;
  line-height: 1;
}
.backup-theme-filter { width: 130px; }
#trash-count-badge:not(:empty) {
  display: inline-block; margin-left: 6px; padding: 1px 6px; border-radius: 999px;
  background: var(--accent); color: #06231f; font-size: 11px; font-weight: 700;
}

.backup-reminder-banner {
  display: flex; align-items: center; gap: 12px;
  padding: 9px 24px;
  background: var(--banner-warn-bg); border-bottom: 1px solid var(--banner-warn-border);
  color: var(--banner-warn-text); font-size: 13px;
}
.backup-reminder-banner.hidden { display: none; }
.backup-reminder-banner span { flex: 1; }
.backup-reminder-banner .btn-primary { padding: 6px 12px; font-size: 12.5px; }
.backup-reminder-banner .btn-ghost { padding: 4px 8px; font-size: 14px; }

.tabs { display: flex; gap: 6px; }
.tab-btn {
  background: transparent;
  border: 1px solid transparent;
  color: var(--text-dim);
  padding: 9px 16px;
  border-radius: 999px;
  cursor: pointer;
  font-family: 'Inter', sans-serif;
  font-weight: 600;
  font-size: 14px;
  transition: all .15s;
}
.tab-btn:hover { color: var(--text); border-color: var(--border); }
.tab-btn.active { background: var(--accent); color: #06231f; }

main { padding: 24px 28px 60px; max-width: 1400px; margin: 0 auto; }

.site-footer {
  max-width: 1400px;
  margin: 0 auto;
  padding: 0 28px 32px;
  text-align: center;
  font-size: 12px;
  line-height: 1.6;
  color: var(--text-dim);
}
.site-footer p { margin: 0; }
.site-footer a { color: var(--accent); text-decoration: none; }
.site-footer a:hover { text-decoration: underline; }

.tab-panel { display: none; }
.tab-panel.active { display: block; }

.panel {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 20px;
}

/* Three columns: Card Type–Character Name (left), the live card preview
   (middle, unchanged position), and Stats/Health/Abilities/Flavor (right)
   — split out of what used to be one long scrolling left column so each
   half is shorter and there's less scrolling to find a given field. #card-
   form wraps both form columns (so form.reset() and the form's delegated
   input/change listeners in app.js still cover every field) but itself
   generates no box, via `display:contents` below, so its two children can
   sit in grid columns 1 and 3 with the preview panel's own column in
   between them. */
.designer-grid {
  display: grid;
  /* Every column's lower bound is its own true minimum content width,
     found empirically (measuring scrollWidth vs clientWidth in a headless
     browser) rather than picked by eye — in particular the right column's
     520px, sized to the Stats grid's content (two fixed-width die selects
     per row plus its label, times 2 side-by-side columns). Below its own
     floor a column ran out of room and grew a horizontal scrollbar
     (overflow-y:auto on .form-panel implicitly makes overflow-x auto too,
     per the CSS spec's mixed-overflow rule) — raising the right column's
     floor to fix that pushed the left column below ITS floor at narrower
     widths instead (CSS Grid shrinks non-flex minmax tracks to fit before
     it'll shrink a flex (1fr) track below its own minimum), so the left
     column's floor also moved up to its measured true minimum (344px),
     and the single-column breakpoint below moved up to match — the three
     floors plus gaps plus main's own padding is right at that breakpoint,
     so no combination of column widths between the two layouts can force
     a column below what its content actually needs. */
  grid-template-columns: minmax(344px, 380px) minmax(400px, 460px) minmax(520px, 1fr);
  gap: 20px;
  align-items: start;
}
#card-form { display: contents; }
/* grid-row: 1 on all three is required, not cosmetic — designer-col-right
   (column 3) comes before #preview-panel (column 2) in DOM/auto-placement
   order (the form's two children are necessarily contiguous, so the
   preview panel can't sit between them in source order), and CSS Grid's
   sparse auto-placement cursor doesn't backtrack to fill column 2 once
   column 3 has been placed in row 1 — without this it silently drops
   the preview panel to row 2, off to the side of the two form columns. */
.designer-col-left { grid-column: 1; grid-row: 1; }
#preview-panel { grid-column: 2; grid-row: 1; }
.designer-col-right { grid-column: 3; grid-row: 1; }

@media (max-width: 1370px) {
  .designer-grid { grid-template-columns: 1fr; }
  .designer-col-left, #preview-panel, .designer-col-right { grid-column: auto; grid-row: auto; }
}

.form-panel { display: flex; flex-direction: column; gap: 16px; max-height: calc(100vh - 120px); overflow-y: auto; }

fieldset {
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 14px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
legend {
  padding: 0 6px;
  font-weight: 700;
  font-family: 'Rajdhani', sans-serif;
  font-size: 15px;
  letter-spacing: 0.04em;
  color: var(--accent);
  text-transform: uppercase;
}

label {
  display: flex;
  flex-direction: column;
  gap: 6px;
  font-size: 13px;
  color: var(--text-dim);
  font-weight: 500;
}
label.grow { flex: 1; }
label.narrow { width: 90px; }

input[type="text"], input[type="number"], select, input[type="range"] {
  background: var(--panel-2);
  border: 1px solid var(--border);
  color: var(--text);
  padding: 9px 10px;
  border-radius: 8px;
  font-family: 'Inter', sans-serif;
  font-size: 14px;
}
input[type="color"] {
  height: 38px;
  padding: 2px;
  background: var(--panel-2);
  border: 1px solid var(--border);
  border-radius: 8px;
  cursor: pointer;
}
input:focus, select:focus { outline: 2px solid var(--accent); outline-offset: 1px; }

#f-assetDescription {
  background: var(--panel-2);
  border: 1px solid var(--border);
  color: var(--text);
  padding: 9px 10px;
  border-radius: 8px;
  font-family: 'Inter', sans-serif;
  font-size: 14px;
  resize: vertical;
  min-height: 120px;
}

.card-type-field { flex: 1 1 120px; min-width: 100px; display: flex; flex-direction: column; gap: 6px; }
.card-type-caption { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.card-type-caption .checkbox-label { color: var(--text-dim); }
.checkbox-label { flex-direction: row; align-items: center; gap: 8px; font-size: 13px; }
.checkbox-label input { width: auto; }

.field-row { display: flex; gap: 12px; flex-wrap: wrap; }
.field-row > label:not(.grow):not(.narrow) { flex: 1 1 120px; min-width: 100px; }

.stat-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px 14px;
}
.stat-grid .hint { grid-column: 1 / -1; margin: -2px 0 2px; }
.stat-grid .hint:empty { display: none; }
.stat-grid-actions { grid-column: 1 / -1; display: flex; justify-content: flex-end; margin: -8px 0 -2px; }
.stat-reset-btn { padding: 5px 10px; font-size: 11.5px; }
.stat-row {
  grid-column: span 1;
  display: flex;
  align-items: center;
  gap: 6px;
  background: var(--panel-2);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 6px 8px;
}
.stat-row span:first-child { flex: 1; font-size: 13px; font-weight: 600; }
.stat-row .d { color: var(--text-dim); font-size: 12px; }
.stat-row select { width: 56px; padding: 5px 4px; }

.ability-item {
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 10px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  background: var(--panel-2);
  position: relative;
}

.ability-name-wrap { position: relative; }

.ability-suggestions {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  right: 0;
  background: var(--panel);
  border: 1px solid var(--accent);
  border-radius: 8px;
  box-shadow: 0 8px 24px rgba(0,0,0,0.5);
  z-index: 30;
  max-height: 240px;
  overflow-y: auto;
}
.ability-suggestions .sugg-item {
  padding: 8px 10px;
  cursor: pointer;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
  border-bottom: 1px solid var(--border);
}
.ability-suggestions .sugg-item:last-child { border-bottom: none; }
.ability-suggestions .sugg-item:hover,
.ability-suggestions .sugg-item.active {
  background: rgba(45,212,191,0.14);
}
.ability-suggestions .sugg-name { font-weight: 600; font-size: 13px; color: var(--text); }
.ability-suggestions .sugg-level {
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-dim);
  flex-shrink: 0;
}
.ability-suggestions .sugg-text {
  display: block;
  font-size: 11px;
  color: var(--text-dim);
  font-weight: 400;
  margin-top: 2px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.ability-suggestions .sugg-empty {
  padding: 10px;
  font-size: 12px;
  color: var(--text-dim);
}
.ability-item input, .ability-item textarea {
  background: var(--panel);
  border: 1px solid var(--border);
  color: var(--text);
  border-radius: 6px;
  padding: 7px 9px;
  font-family: 'Inter', sans-serif;
  font-size: 13px;
  width: 100%;
}
.ability-item textarea { resize: vertical; min-height: 44px; }
.ability-rename-note {
  font-size: 11px;
  color: var(--text-dim);
  margin-top: 2px;
}
.ability-rename-note strong { color: var(--text); font-weight: 600; }
.ability-reset-name { color: var(--accent); text-decoration: none; }
.ability-reset-name:hover { text-decoration: underline; }
.ability-remove {
  align-self: flex-end;
  background: transparent;
  border: none;
  color: var(--danger);
  cursor: pointer;
  font-size: 12px;
  font-weight: 600;
}

.btn-primary, .btn-secondary, .btn-ghost {
  border-radius: 8px;
  padding: 10px 16px;
  font-weight: 600;
  font-size: 14px;
  cursor: pointer;
  font-family: 'Inter', sans-serif;
  border: 1px solid transparent;
}
.btn-primary { background: var(--accent); color: #06231f; }
.btn-primary:hover { filter: brightness(1.08); }
.btn-secondary { background: var(--panel-2); border-color: var(--border); color: var(--text); }
.btn-secondary:hover { border-color: var(--accent); color: var(--accent); }
.btn-ghost { background: transparent; border-color: var(--border); color: var(--text-dim); }
.btn-ghost:hover { color: var(--text); }
.btn-danger { background: transparent; border-color: var(--border); color: var(--danger); }
.btn-danger:hover { background: var(--danger); border-color: var(--danger); color: #fff; }

.hint { color: var(--text-dim); font-size: 12px; margin: 2px 0 0; }

.preview-panel { display: flex; flex-direction: column; align-items: center; gap: 16px; position: sticky; top: 84px; }
.card-stage {
  /* Transparent, not var(--bg) — .preview-panel is already a .panel (so
     already var(--panel)), and var(--bg) is a visibly different shade from
     var(--panel) in both themes, which was showing as a grey box behind
     the card instead of blending into the panel around it. */
  background: transparent;
  border-radius: 16px;
  padding: 20px;
  display: flex;
  justify-content: center;
  transition: box-shadow 0.15s, background-color 0.15s;
}
/* Highlighted while a file is dragged over the preview panel (see
   dragenter/dragover/drop handling in app.js) — the whole panel is one
   drop target, so the highlight goes on the card stage since that's the
   visual "drop it here" surface. */
.preview-panel.drag-over .card-stage {
  box-shadow: 0 0 0 3px var(--accent) inset;
  background-color: rgba(45, 212, 191, 0.08);
}
.portrait-upload {
  width: 100%;
  max-width: 420px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
#card-canvas {
  width: min(360px, 78vw);
  height: auto;
  /* No border-radius — the card art itself now has square corners (see
     CARD_RADIUS in cardRenderer.js), so rounding this display element
     would clip the preview into a shape the exported file doesn't have. */
  box-shadow: 0 12px 40px rgba(0,0,0,0.5);
  cursor: grab;
  touch-action: none;
}
#card-canvas:active { cursor: grabbing; }

.preview-actions { display: flex; gap: 10px; flex-wrap: wrap; justify-content: center; }

/* Gallery */
.gallery-toolbar { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 12px; margin-bottom: 16px; }
.gallery-toolbar h2 { font-family: 'Rajdhani', sans-serif; margin: 0; font-size: 22px; }
.gallery-meta { display: flex; align-items: center; gap: 14px; }
#selected-count { color: var(--text-dim); font-size: 13px; }
.gallery-search { width: 180px; }
.theme-filter-select { width: 150px; }

.gallery-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: 16px;
}
.gallery-card {
  background: var(--panel-2);
  border: 2px solid var(--border);
  border-radius: 12px;
  overflow: hidden;
  cursor: pointer;
  transition: border-color .15s;
  position: relative;
}
.gallery-card.selected { border-color: var(--accent); }
.gallery-card img { width: 100%; display: block; }
.gallery-card .gc-name {
  padding: 8px 10px;
  font-size: 13px;
  font-weight: 600;
}
.gallery-card .gc-actions {
  position: absolute; top: 8px; right: 8px;
  display: flex; gap: 6px;
}
.gallery-card .gc-actions button {
  background: rgba(11,14,19,0.85);
  border: 1px solid var(--border);
  color: var(--text);
  border-radius: 6px;
  width: 28px; height: 28px;
  cursor: pointer;
  font-size: 13px;
}
.gallery-card .gc-check {
  position: absolute; top: 8px; left: 8px;
  width: 22px; height: 22px;
  border-radius: 6px;
  background: rgba(11,14,19,0.85);
  border: 1px solid var(--border);
  display: flex; align-items: center; justify-content: center;
  font-size: 13px;
  color: var(--accent);
}

/* Print sheet */
.sheet-stage {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 22px;
  background: var(--panel-2);
  border-radius: 12px;
  padding: 20px;
  overflow: auto;
}
.sheet-page-canvas {
  width: min(700px, 100%);
  height: auto;
  background: white;
  box-shadow: 0 8px 30px rgba(0,0,0,0.4);
  flex-shrink: 0;
}
.sheet-page-label {
  color: var(--text-dim);
  font-size: 12px;
  margin-top: -14px;
}

/* League Roster */
.slot-meter { margin: 4px 0 20px; }
.slot-meter-bar {
  height: 10px;
  border-radius: 999px;
  background: var(--panel-2);
  border: 1px solid var(--border);
  overflow: hidden;
}
.slot-meter-fill {
  height: 100%;
  width: 0%;
  background: var(--accent);
  transition: width .2s;
}
.slot-meter-fill.over { background: var(--danger); }
.slot-meter-label { margin-top: 6px; font-size: 12px; color: var(--text-dim); font-weight: 600; }

.roster-warnings { display: flex; flex-direction: column; gap: 6px; margin-bottom: 4px; }
.roster-warning {
  background: rgba(239,68,68,0.12);
  border: 1px solid rgba(239,68,68,0.4);
  color: #ffb4b4;
  border-radius: 8px;
  padding: 8px 12px;
  font-size: 12.5px;
}

.roster-columns {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: 20px;
  margin-top: 8px;
}
@media (max-width: 1100px) {
  .roster-columns { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 700px) {
  .roster-columns { grid-template-columns: 1fr; }
}
.roster-column-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 10px;
  flex-wrap: wrap;
}
.roster-column-header h3 {
  margin: 0;
  font-family: 'Rajdhani', sans-serif;
  font-size: 16px;
  color: var(--accent);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.roster-list { display: flex; flex-direction: column; gap: 8px; }
.roster-row {
  display: flex;
  align-items: center;
  gap: 10px;
  background: var(--panel-2);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 8px 10px;
}
.roster-row-thumb {
  width: 34px;
  height: 48px;
  object-fit: cover;
  border-radius: 4px;
  flex-shrink: 0;
  background: var(--panel);
}
.roster-row-body { flex: 1; min-width: 0; }
.roster-row-name { font-weight: 600; font-size: 13.5px; }
.roster-row-meta { font-size: 11px; color: var(--text-dim); margin-top: 1px; }
.roster-row-slots {
  font-family: 'Rajdhani', sans-serif;
  font-weight: 700;
  font-size: 13px;
  color: var(--accent);
  flex-shrink: 0;
  white-space: nowrap;
}
.roster-row-remove {
  background: transparent;
  border: none;
  color: var(--danger);
  cursor: pointer;
  font-size: 15px;
  flex-shrink: 0;
  padding: 4px;
}

.associates-list { display: flex; flex-direction: column; gap: 10px; }
.associate-item {
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 10px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  background: var(--panel-2);
}
.associate-item-top { display: flex; align-items: center; gap: 8px; }
.associate-ability-row { display: flex; flex-direction: column; gap: 4px; }
.associate-ability-text { font-size: 11.5px; color: var(--text-dim); line-height: 1.4; margin: 0; }
.associate-ability-name { font-weight: 600; font-size: 12.5px; }

/* Associate cards render landscape — a wide/short thumbnail box (with
   object-fit: contain, not cover) instead of the portrait-shaped boxes
   used for every other Card Type, so the image isn't harshly cropped. */
.associate-item-thumb {
  width: 64px;
  height: 46px;
  object-fit: contain;
  border-radius: 4px;
  flex-shrink: 0;
  background: var(--panel);
}
.associate-picker-thumb { width: 64px; height: 46px; object-fit: contain; }

/* Ability Library modal */
.modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(4,6,9,0.72);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 100;
  padding: 24px;
}
.modal-overlay.hidden { display: none; }

.modal-panel {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 14px;
  width: min(720px, 100%);
  max-height: min(760px, 90vh);
  display: flex;
  flex-direction: column;
  box-shadow: 0 24px 64px rgba(0,0,0,0.55);
}

.modal-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 18px 22px;
  border-bottom: 1px solid var(--border);
}
.modal-header h2 {
  margin: 0;
  font-family: 'Rajdhani', sans-serif;
  font-size: 21px;
}
.modal-close {
  background: transparent;
  border: 1px solid var(--border);
  color: var(--text-dim);
  border-radius: 8px;
  width: 32px;
  height: 32px;
  cursor: pointer;
  font-size: 14px;
}
.modal-close:hover { color: var(--text); border-color: var(--accent); }

.modal-toolbar {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 14px 22px;
  border-bottom: 1px solid var(--border);
}
.level-filter { display: flex; gap: 6px; flex-wrap: wrap; }
.level-btn {
  background: var(--panel-2);
  border: 1px solid var(--border);
  color: var(--text-dim);
  padding: 6px 13px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  font-family: 'Inter', sans-serif;
}
.level-btn:hover { color: var(--text); border-color: var(--accent); }
.level-btn.active { background: var(--accent); color: #06231f; border-color: var(--accent); }

#library-search {
  width: 100%;
}

#colleague-theme-filter { width: 160px; flex: 0 0 auto; }
#colleague-search { flex: 1 1 auto; }

.library-list {
  overflow-y: auto;
  padding: 8px 22px 20px;
  flex: 1;
}
.library-level-heading {
  position: sticky;
  top: 0;
  background: var(--panel);
  padding: 10px 0 6px;
  font-family: 'Rajdhani', sans-serif;
  font-weight: 700;
  font-size: 13px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--accent);
  border-bottom: 1px solid var(--border);
  margin-bottom: 4px;
}
.library-item {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 10px 4px;
  border-bottom: 1px solid var(--border);
}
.library-item:last-child { border-bottom: none; }
.library-item-body { flex: 1; min-width: 0; }
.library-item-name { font-weight: 700; font-size: 14px; color: var(--text); }
.library-item-level {
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-dim);
  margin-left: 8px;
  font-weight: 600;
}
.library-item-text { font-size: 12.5px; color: var(--text-dim); margin-top: 3px; line-height: 1.4; }
.library-item-overcap { opacity: 0.55; }
.library-item-overcap-tag {
  font-size: 9.5px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--tag-warn);
  margin-left: 8px;
  font-weight: 700;
}
.library-item-npc-tag {
  font-size: 9.5px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--tag-info);
  margin-left: 8px;
  font-weight: 700;
}
.library-item-thumb {
  width: 40px;
  height: 56px;
  object-fit: cover;
  border-radius: 5px;
  flex-shrink: 0;
  background: var(--panel-2);
}
.trash-roster-icon {
  display: flex; align-items: center; justify-content: center; font-size: 20px;
}
.library-add-btn {
  flex-shrink: 0;
  width: 34px;
  height: 34px;
  border-radius: 8px;
  background: var(--panel-2);
  border: 1px solid var(--border);
  color: var(--accent);
  font-size: 18px;
  font-weight: 700;
  cursor: pointer;
  line-height: 1;
}
.library-add-btn:hover { background: var(--accent); color: #06231f; border-color: var(--accent); }
.library-add-btn.added { background: var(--accent); color: #06231f; border-color: var(--accent); }
.library-empty { padding: 30px 4px; text-align: center; color: var(--text-dim); font-size: 13px; }
.library-item-actions { display: flex; flex-direction: column; gap: 6px; flex-shrink: 0; }
.library-item-actions .btn-secondary, .library-item-actions .btn-danger {
  padding: 6px 10px; font-size: 12px; white-space: nowrap;
}

@media print {
  header.topbar, .site-footer, #backup-reminder-banner, .panel > .gallery-toolbar, main > .panel > p.hint, #tab-designer, #tab-gallery, #tab-rules-index { display: none !important; }
  body { background: white; }
  main { padding: 0; max-width: none; }
  .panel { border: none; padding: 0; background: white; }
  .sheet-stage { padding: 0; background: white; gap: 0; }
  .sheet-page-canvas {
    width: 210mm; height: 297mm; box-shadow: none;
    page-break-after: always;
  }
  .sheet-page-canvas:last-of-type { page-break-after: auto; }
  .sheet-page-label { display: none; }
}

/* ---- League Roster print sheet (Print Roster / Download PDF) ----
   A plain, ink-friendly reference document, separate from the on-screen
   roster columns and the Print Sheet's card canvas. Hidden on screen at
   all times; shown full-page only while body.printing-roster-sheet is set
   (see roster-print-btn's click handler in app.js), so it never interferes
   with the rest of the app's own print rules above. */
/* background/color are set here (not just under @media print) because
   Copy Roster also renders this sheet on-screen (off-screen-positioned,
   see .copying-roster-sheet below) to run the browser's copy command —
   without an explicit light background+dark text here, the copied HTML
   inherits this app's dark theme (Chrome bakes computed styles into the
   clipboard's HTML), producing dark boxes with unreadable text when
   pasted into Notes/Docs/etc. */
#roster-print-sheet { display: none; background: #fff; color: #000; }

.rps-header { margin-bottom: 20px; border-bottom: 2px solid #000; padding-bottom: 10px; }
.rps-header h1 { margin: 0 0 4px; font-size: 22px; color: #000; }
.rps-summary { font-size: 12px; color: #333; }
.rps-section { margin-bottom: 22px; }
.rps-section h2 {
  font-size: 15px; margin: 0 0 8px; padding-bottom: 4px;
  border-bottom: 1px solid #999; color: #000;
}
.rps-colleague-row {
  display: flex; justify-content: space-between; gap: 10px;
  padding: 4px 0; border-bottom: 1px dotted #ccc; font-size: 12px; color: #000;
}
.rps-block { margin-bottom: 10px; page-break-inside: avoid; }
.rps-block-name { font-weight: 700; font-size: 13px; color: #000; }
.rps-block-meta { font-weight: 400; font-size: 11px; color: #555; }
.rps-block-text { font-size: 12px; line-height: 1.4; margin: 2px 0 0; color: #111; }
.rps-associate-block { margin-bottom: 14px; page-break-inside: avoid; }
.rps-associate-name { font-weight: 700; font-size: 13px; margin-bottom: 4px; color: #000; }
.rps-empty { font-size: 12px; color: #777; font-style: italic; }

@media print {
  body.printing-roster-sheet > *:not(#roster-print-sheet) { display: none !important; }
  body.printing-roster-sheet #roster-print-sheet {
    display: block !important;
    background: #fff;
    color: #000;
    padding: 0;
  }
}

/* Copy Roster: the sheet needs to be actually rendered (not display:none)
   for document.execCommand('copy') to pick up a DOM Selection over it —
   display:none content is excluded from copy. Positioned off-screen so it
   never flashes on screen while the copy runs. See roster-copy-btn's click
   handler in app.js. */
body.copying-roster-sheet #roster-print-sheet {
  display: block !important;
  position: fixed;
  top: 0;
  left: -99999px;
  width: 700px;
}

/* ---- Quick Reference tab ----
   Modeled directly on a printed-card-style reference sheet the user
   supplied (two letter-size pages, a cream "REMEMBER" callout, a
   Turn&Activation/Fighting/Moving&Evading/Dice,Modifiers&Saves/
   Actions,Perils&Scenario category legend). Every qr-box-* section header
   is colored by which of those five categories it belongs to — navy,
   maroon, teal, green or purple — matching the swatches in that legend
   row (.qr-categories). Gold is reserved for the "Where do I look?" lookup
   table, and qr-box-brown is currently unused (kept defined in case a
   future revision of the source sheet brings a box back to it).
   This is a fixed, print-style palette of its own, independent of the
   app's own Light/Dark UI toggle (same reasoning as card art already not
   following the UI theme — see .card-stage) so it always matches the
   reference sheet's look on screen.
   "Save as PDF" (see downloadQuickReferencePDF in app.js) still draws its
   own plain black-on-white two-page PDF independently of this DOM, so it
   no longer visually matches this on-screen tab — a known follow-up, not
   addressed here. */
.qr-sheet {
  --qr-navy: #14213d;
  --qr-teal: #1f5f6b;
  --qr-maroon: #9b1c1c;
  --qr-purple: #5b2a86;
  --qr-gold: #c49a1a;
  --qr-brown: #7a4a12;
  --qr-green: #2f6b2f;
  --qr-cream: #fbf6e4;
  --qr-box-border: #cfc9b8;
  --qr-ink: #1a1a1a;
  --qr-ink-dim: #444444;
  background: #ffffff;
  color: var(--qr-ink);
  border-radius: var(--radius);
  padding: 0 0 22px;
  margin-top: 18px;
  overflow: hidden;
  box-shadow: 0 1px 3px rgba(0,0,0,0.15);
}

.qr-banner {
  background: var(--qr-navy);
  color: #ffffff;
  padding: 16px 22px 14px;
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
}
.qr-banner-title {
  font-family: 'Rajdhani', sans-serif;
  font-weight: 700;
  font-size: 24px;
  letter-spacing: 0.01em;
  margin: 0;
  text-transform: uppercase;
}
.qr-banner-sub { font-size: 12.5px; color: rgba(255,255,255,0.75); margin-top: 2px; }
.qr-banner-right { text-align: right; flex-shrink: 0; }
.qr-page-label { font-size: 11px; font-weight: 700; letter-spacing: 0.04em; color: var(--qr-gold); }
.qr-success { font-family: 'Rajdhani', sans-serif; font-weight: 700; font-size: 22px; letter-spacing: 0.01em; }
.qr-success-sub { font-size: 11px; color: rgba(255,255,255,0.7); }
.qr-banner-accent { height: 4px; background: var(--qr-gold); }

/* A row of five colored swatches naming the sheet's five topic categories
   (Turn & Activation, Fighting, Moving & Evading, Dice/Modifiers & Saves,
   Actions/Perils & Scenario) — those same five colors are what every
   qr-box-* header below is now drawn from, so this row doubles as a legend
   for the section colors on the rest of the sheet. */
.qr-categories {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 22px;
  background: #f2f0e8;
  border: 1px solid var(--qr-box-border);
  border-top: none;
  margin: 0 22px;
  padding: 9px 16px;
}
.qr-cat {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 11.5px;
  font-weight: 700;
  color: var(--qr-ink);
}
.qr-cat-swatch { display: inline-block; width: 8px; height: 18px; border-radius: 1px; }
.qr-cat-navy { background: var(--qr-navy); }
.qr-cat-maroon { background: var(--qr-maroon); }
.qr-cat-teal { background: var(--qr-teal); }
.qr-cat-green { background: var(--qr-green); }
.qr-cat-purple { background: var(--qr-purple); }

.qr-remember {
  display: flex;
  align-items: stretch;
  gap: 16px;
  background: var(--qr-cream);
  border: 2px solid var(--qr-gold);
  margin: 14px 22px 0;
  padding: 10px 16px;
  font-size: 12.5px;
  color: var(--qr-ink);
}
.qr-remember-label {
  color: var(--qr-gold);
  font-weight: 700;
  font-size: 12px;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  flex-shrink: 0;
  display: flex;
  align-items: center;
}
.qr-remember-tip {
  flex: 1;
  min-width: 120px;
  padding-left: 16px;
  border-left: 1px solid var(--qr-gold);
  display: flex;
  align-items: center;
}

.qr-columns { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; padding: 18px 22px 0; }
.qr-col { min-width: 0; display: flex; flex-direction: column; gap: 14px; }

.qr-box {
  border: 1px solid var(--qr-box-border);
  border-radius: 3px;
  overflow: hidden;
}
.qr-box h4 {
  margin: 0;
  padding: 7px 14px;
  font-size: 13px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  color: #ffffff;
}
.qr-box-navy h4 { background: var(--qr-navy); }
.qr-box-teal h4 { background: var(--qr-teal); }
.qr-box-maroon h4 { background: var(--qr-maroon); }
.qr-box-purple h4 { background: var(--qr-purple); }
/* Gold is light enough that white header text (every other qr-box-* color
   uses white) loses contrast, so the one box still using it — the "Where
   Do I Look?" lookup table below — gets dark brown text instead. */
.qr-box-gold h4 { background: var(--qr-gold); color: var(--qr-brown); }
.qr-box-brown h4 { background: var(--qr-brown); }
.qr-box-green h4 { background: var(--qr-green); }

.qr-box ul, .qr-box ol {
  margin: 0;
  padding: 10px 14px 10px 30px;
  font-size: 12px;
  line-height: 1.4;
}
.qr-box > p.qr-plain { margin: 10px 14px; font-size: 12px; line-height: 1.4; }
.qr-box li { margin-bottom: 6px; }
.qr-box li:last-child { margin-bottom: 0; }
.qr-intro, .qr-note {
  margin: 10px 14px 0;
  font-size: 11.5px;
  font-style: italic;
  color: var(--qr-ink-dim);
}
.qr-box ul + .qr-note, .qr-box ol + .qr-note { margin-top: -2px; padding-bottom: 10px; }
.qr-intro + ul, .qr-intro + ol { padding-top: 6px; }
.qr-lead { margin: 10px 14px 0; font-size: 12.5px; font-weight: 700; }
.qr-lead + ul { padding-top: 6px; }

/* "Where do I look?" — a quick symptom-to-section lookup table, the one
   qr-box that isn't a ul/ol/p. Reuses qr-box-gold's header, cream fill and
   a thicker gold border like qr-remember's, since it's meant to read as a
   second at-a-table quick-reference, not just one more rule box. */
.qr-box-lookup { border: 2px solid var(--qr-gold); }
.qr-lookup { background: var(--qr-cream); }
.qr-lookup-row {
  display: grid;
  grid-template-columns: 1.3fr 1fr;
  gap: 14px;
  padding: 8px 14px;
  font-size: 12px;
  color: var(--qr-ink);
  border-bottom: 1px solid rgba(196, 154, 26, 0.35);
}
.qr-lookup-row:last-child { border-bottom: none; }
.qr-lookup-a { font-weight: 700; color: var(--qr-navy); }

@media (max-width: 760px) {
  .qr-columns { grid-template-columns: 1fr; }
  .qr-categories { gap: 14px 18px; }
  .qr-remember { flex-direction: column; gap: 8px; }
  .qr-remember-tip { border-left: none; padding-left: 0; border-top: 1px solid var(--qr-gold); padding-top: 8px; }
  .qr-remember-label { padding-bottom: 4px; }
  .qr-banner { flex-direction: column; align-items: flex-start; }
  .qr-banner-right { text-align: left; }
  .qr-lookup-row { grid-template-columns: 1fr; gap: 2px; }
}

/* ===================== ABOUT ===================== */
.about-panel { max-width: 760px; margin: 0 auto; display: grid; gap: 0; padding: 8px 28px 24px; }
.about-block { display: grid; gap: 10px; padding: 22px 0; border-bottom: 1px solid var(--border); }
.about-block h2 { font-family: 'Rajdhani', sans-serif; font-size: 24px; margin: 0; line-height: 1.15; }
.about-block p { margin: 0; max-width: 68ch; line-height: 1.6; font-size: 15px; }
.about-block .hint { font-size: 12px; }
.about-actions { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 2px; }
.about-link { display: inline-block; text-decoration: none; }
.about-link:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.about-list { margin: 0; padding-left: 20px; display: grid; gap: 8px; max-width: 68ch; line-height: 1.6; font-size: 15px; }
.about-legal { margin: 0; padding-top: 18px; color: var(--text-dim); font-size: 12px; line-height: 1.5; }
@media (max-width: 700px) { .about-panel { padding: 4px 16px 18px; } }

/* ===================== Rules Index ===================== */
.ri-controls { flex-wrap: wrap; justify-content: flex-end; }
.ri-search { width: 280px; max-width: 100%; }
.ri-count { margin: 10px 0 8px; font-size: 13px; color: var(--text-dim); }
.ri-table-wrap { overflow-x: auto; border: 1px solid var(--border); border-radius: var(--radius); }
.ri-table { width: 100%; border-collapse: collapse; font-size: 14px; }
.ri-table th {
  position: sticky; top: 0; text-align: left; padding: 9px 12px; background: var(--panel-2);
  border-bottom: 1px solid var(--border); font-size: 12px; letter-spacing: .04em; text-transform: uppercase; color: var(--text-dim);
}
.ri-table td { padding: 8px 12px; border-bottom: 1px solid var(--border); vertical-align: top; }
.ri-table tbody tr:last-child td { border-bottom: none; }
.ri-table tbody tr:hover { background: var(--panel-2); }
.ri-term { font-weight: 600; }
.ri-type-tag { display: inline-block; margin-left: 8px; padding: 1px 7px; border-radius: 999px; border: 1px solid var(--border); font-size: 11px; font-weight: 500; color: var(--text-dim); white-space: nowrap; }
.ri-page-col, .ri-page { white-space: nowrap; }
.ri-page strong { font-variant-numeric: tabular-nums; }
.ri-also { color: var(--text-dim); font-size: 12px; margin-left: 6px; }
.ri-section { color: var(--text-dim); }
.ri-table mark { background: color-mix(in srgb, var(--accent) 35%, transparent); color: inherit; border-radius: 2px; padding: 0 1px; }
@media (max-width: 700px) {
  .ri-search { width: 100%; }
  .ri-table td, .ri-table th { padding: 7px 8px; }
  .ri-table .ri-section-col, .ri-table td.ri-section { display: none; }
}
