/* D&D 2024 Character Builder - ink on parchment, with a dark mode. */

:root {
  color-scheme: light dark;

  --bg: #f6f2e9;
  --bg-raised: #fffdf8;
  --bg-sunken: #ece5d6;
  --ink: #23201b;
  --ink-soft: #5c5548;
  --ink-faint: #6b6457;
  --line: #d9d0bd;
  --line-strong: #948767;

  --accent: #7b2d26;
  --accent-soft: #f0dcd8;
  --accent-ink: #5d1f1a;
  --gold: #96762c;
  --gold-soft: #f4ead0;
  --ok: #2f6b45;
  --ok-soft: #dcefe2;
  --todo: #9a5b12;
  --todo-soft: #fbead2;
  --danger: #a02b20;
  --on-accent: #fff;   /* text on an --accent fill */
  --on-todo: #fff;     /* text on a --todo fill */
  --tile: var(--bg);   /* stat and ability tiles on a card */

  /* Type scale: three small steps with a 12px floor. Descriptions are what
     people actually read, so they get the largest of the small sizes. */
  --fs-label: .75rem;    /* 12px: labels, badges, table heads */
  --fs-meta: .8125rem;   /* 13px: captions, sources, secondary lines */
  --fs-desc: .875rem;    /* 14px: descriptions and help text */
  --measure: 75ch;       /* longest comfortable line */

  --radius: 10px;
  --radius-sm: 6px;
  --shadow: 0 1px 2px rgba(35, 32, 27, .08), 0 4px 14px rgba(35, 32, 27, .06);
  --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
  --sans: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
  --serif: "Iowan Old Style", "Palatino Linotype", Palatino, Georgia, serif;
}

/* Dark palette: only when the viewer's system asks for it, or they chose it.
   Without the media guard this would override the light palette unconditionally. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #17161a;
    --bg-raised: #201f25;
    --bg-sunken: #121115;
    --ink: #ece7dd;
    --ink-soft: #b0a99c;
    --ink-faint: #9a9387;
    --line: #33313a;
    --line-strong: #757080;
    --accent: #d97c6f;
    --accent-soft: #3a2320;
    --accent-ink: #f0b7ad;
    --gold: #d7b569;
    --gold-soft: #332b18;
    --ok: #6ec295;
    --ok-soft: #1d2f25;
    --todo: #e0a95d;
    --todo-soft: #33280f;
    --danger: #e8796b;
    --on-accent: #1a0f0d;
    --on-todo: #1a1305;
    --tile: color-mix(in srgb, var(--ink) 5%, var(--bg-raised));
    --shadow: 0 1px 2px rgba(0, 0, 0, .3), 0 4px 16px rgba(0, 0, 0, .25);
  }
}

:root[data-theme="dark"] {
  --bg: #17161a;
  --bg-raised: #201f25;
  --bg-sunken: #121115;
  --ink: #ece7dd;
  --ink-soft: #b0a99c;
  --ink-faint: #9a9387;
  --line: #33313a;
  --line-strong: #757080;

  --accent: #d97c6f;
  --accent-soft: #3a2320;
  --accent-ink: #f0b7ad;
  --gold: #d7b569;
  --gold-soft: #332b18;
  --ok: #6ec295;
  --ok-soft: #1d2f25;
  --todo: #e0a95d;
  --todo-soft: #33280f;
  --danger: #e8796b;
  --on-accent: #1a0f0d;
  --on-todo: #1a1305;
  --tile: color-mix(in srgb, var(--ink) 5%, var(--bg-raised));
  --shadow: 0 1px 2px rgba(0, 0, 0, .3), 0 4px 16px rgba(0, 0, 0, .25);
  color-scheme: dark;
}

/* Light overrides win when the viewer explicitly picks light. color-scheme
   follows the chosen theme, not the OS, or native checkboxes, selects and
   scrollbars come out in the other theme's colours. */
:root[data-theme="light"] {
  color-scheme: light;
  --bg: #f6f2e9;
  --bg-raised: #fffdf8;
  --bg-sunken: #ece5d6;
  --ink: #23201b;
  --ink-soft: #5c5548;
  --ink-faint: #6b6457;
  --line: #d9d0bd;
  --line-strong: #948767;
  --accent: #7b2d26;
  --accent-soft: #f0dcd8;
  --accent-ink: #5d1f1a;
  --gold: #96762c;
  --gold-soft: #f4ead0;
  --ok: #2f6b45;
  --ok-soft: #dcefe2;
  --todo: #9a5b12;
  --todo-soft: #fbead2;
  --danger: #a02b20;
  --on-accent: #fff;   /* text on an --accent fill */
  --on-todo: #fff;     /* text on a --todo fill */
  --tile: var(--bg);
  --shadow: 0 1px 2px rgba(35, 32, 27, .08), 0 4px 14px rgba(35, 32, 27, .06);
}

/* ------------------------------------------------------------- icon tones
   One colour per element or effect, so a list of spells is scannable by hue
   before a single name is read. Tone names come from TONES in js/data/icons.js.
   Light values first; the dark block below re-states every one of them, because
   these are saturated enough that the light set goes muddy on a dark ground. */
:root {
  --icon-fire: #c1441e;
  --icon-frost: #1f86b0;
  --icon-lightning: #8d7a05;
  --icon-acid: #7f8a0c;
  --icon-poison: #2d5a35;
  --icon-necrotic: #7b3a86;
  --icon-radiant: #a67a12;
  --icon-force: #3b5fc0;
  --icon-psychic: #9c2fa0;
  --icon-thunder: #3c5f96;
  --icon-life: #12855e;
  --icon-nature: #4a7024;
  --icon-mind: #c04070;
  --icon-shadow: #4f5570;
  --icon-arcane: #7444b8;
  --icon-divine: #8a5a17;
  --icon-neutral: var(--ink-soft);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --icon-fire: #f08a5d;
    --icon-frost: #5cc2ea;
    --icon-lightning: #e8d23c;
    --icon-acid: #c3d64e;
    --icon-poison: #63b877;
    --icon-necrotic: #e08ac0;
    --icon-radiant: #efc258;
    --icon-force: #8aa2ff;
    --icon-psychic: #d77aff;
    --icon-thunder: #89b0e8;
    --icon-life: #4ed6a0;
    --icon-nature: #9ecb5e;
    --icon-mind: #ff9382;
    --icon-shadow: #a6aad0;
    --icon-arcane: #bb95f5;
    --icon-divine: #e0a95d;
  }
}

:root[data-theme="dark"] {
  --icon-fire: #f08a5d;
  --icon-frost: #5cc2ea;
  --icon-lightning: #e8d23c;
  --icon-acid: #c3d64e;
  --icon-poison: #63b877;
  --icon-necrotic: #e08ac0;
  --icon-radiant: #efc258;
  --icon-force: #8aa2ff;
  --icon-psychic: #d77aff;
  --icon-thunder: #89b0e8;
  --icon-life: #4ed6a0;
  --icon-nature: #9ecb5e;
  --icon-mind: #ff9382;
  --icon-shadow: #a6aad0;
  --icon-arcane: #bb95f5;
  --icon-divine: #e0a95d;
}

:root[data-theme="light"] {
  --icon-fire: #c1441e;
  --icon-frost: #1f86b0;
  --icon-lightning: #8d7a05;
  --icon-acid: #7f8a0c;
  --icon-poison: #2d5a35;
  --icon-necrotic: #7b3a86;
  --icon-radiant: #a67a12;
  --icon-force: #3b5fc0;
  --icon-psychic: #9c2fa0;
  --icon-thunder: #3c5f96;
  --icon-life: #12855e;
  --icon-nature: #4a7024;
  --icon-mind: #c04070;
  --icon-shadow: #4f5570;
  --icon-arcane: #7444b8;
  --icon-divine: #8a5a17;
}

.icon {
  flex: none;
  display: inline-block;
  vertical-align: -.18em;
  color: var(--icon-neutral);
  overflow: visible;
}
.icon-fire { color: var(--icon-fire); }
.icon-frost { color: var(--icon-frost); }
.icon-lightning { color: var(--icon-lightning); }
.icon-acid { color: var(--icon-acid); }
.icon-poison { color: var(--icon-poison); }
.icon-necrotic { color: var(--icon-necrotic); }
.icon-radiant { color: var(--icon-radiant); }
.icon-force { color: var(--icon-force); }
.icon-psychic { color: var(--icon-psychic); }
.icon-thunder { color: var(--icon-thunder); }
.icon-life { color: var(--icon-life); }
.icon-nature { color: var(--icon-nature); }
.icon-mind { color: var(--icon-mind); }
.icon-shadow { color: var(--icon-shadow); }
.icon-arcane { color: var(--icon-arcane); }
.icon-divine { color: var(--icon-divine); }
.icon-neutral { color: var(--icon-neutral); }

/* Supplied artwork replacing a glyph. It carries its own colour, so it takes
   no tone - and the badge behind it stays untinted for the same reason. */
.icon-art { color: var(--ink-soft); object-fit: contain; }
.icon-badge:has(.icon-art) { background: var(--bg-sunken); border-color: var(--line); }

/* A tinted disc behind the glyph, for the places an icon leads a row or a
   card rather than sitting inside a line of text. color-mix keeps one rule
   working for all seventeen tones and both themes. */
.icon-badge {
  flex: none;
  display: grid;
  place-items: center;
  width: 32px; height: 32px;
  border-radius: 9px;
  background: color-mix(in srgb, currentColor 13%, transparent);
  border: 1px solid color-mix(in srgb, currentColor 26%, transparent);
}
.icon-badge.sm { width: 26px; height: 26px; border-radius: 7px; }
.icon-badge.lg { width: 40px; height: 40px; border-radius: 11px; }

@supports not (background: color-mix(in srgb, red 50%, transparent)) {
  .icon-badge { background: var(--bg-sunken); border-color: var(--line); }
}

* { box-sizing: border-box; }
:root { accent-color: var(--accent); }
::placeholder { color: var(--ink-faint); opacity: 1; }
/* Components below set display (the drawer is flex), which would otherwise
   beat the hidden attribute and leave them on screen. */
[hidden] { display: none !important; }

body {
  margin: 0;
  font: 15px/1.55 var(--sans);
  color: var(--ink);
  background: var(--bg);
  -webkit-text-size-adjust: 100%;
}

h1, h2, h3, h4 { font-family: var(--serif); font-weight: 600; line-height: 1.25; margin: 0; }
h1 { font-size: 1.6rem; }
h2 { font-size: 1.25rem; }
h3 { font-size: 1.05rem; }
h4 { font-size: .95rem; }
p { margin: 0 0 .6em; }
a { color: var(--accent); }

/* ------------------------------------------------------------- top bar */
/* The app's name and the things that are not about one character. It scrolls
   away; the character bar below it stays. */
.topbar {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 10px 16px;
  background: var(--bg-sunken);
}
.topbar-right { display: flex; align-items: center; gap: 8px; min-width: 0; }
.brand { display: flex; flex-direction: column; flex: 1 1 0; min-width: 0; }
.brand strong { font-family: var(--serif); font-size: 1.02rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.brand-sub { font-size: var(--fs-label); color: var(--ink-soft); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

.icon-btn {
  border: 1px solid var(--line); background: var(--bg); color: var(--ink);
  width: 34px; height: 34px; border-radius: var(--radius-sm);
  font-size: 1rem; cursor: pointer; flex: none;
}
.icon-btn:hover { border-color: var(--line-strong); }

/* ------------------------------------------------------- character bar */
.app-bar {
  position: sticky; top: 0; z-index: 30;
  background: var(--bg-raised);
  box-shadow: 0 1px 0 var(--line), 0 6px 14px -10px rgba(0, 0, 0, .25);
  transition: transform .2s ease;
}
/* Phones only (app.js): slide the character row up out of view while
   scrolling down, leaving the mode switch pinned. */
.app-bar.tuck { transform: translateY(calc(-1 * var(--strip-h, 0px))); }
@media (prefers-reduced-motion: reduce) { .app-bar { transition: none; } }

/* One folder tab per character. The active one takes the colour of the bar
   beneath it and overlaps the strip's bottom edge, so it reads as joined to
   the page it opens - the same cue as a browser tab. */
.char-strip {
  display: flex; align-items: flex-end; gap: 8px;
  padding: 8px 12px 0;
  background: var(--bg-sunken);
  border-bottom: 1px solid var(--line);
}
.char-tabs {
  display: flex; gap: 4px; align-items: flex-end;
  flex: 0 1 auto; min-width: 0;
  overflow-x: auto; scrollbar-width: none;
  margin-bottom: -1px; /* lets the active tab cover the strip's border */
}
.char-tabs::-webkit-scrollbar { display: none; }
/* More tabs than fit: fade the edge they are hiding behind (app.js sets these). */
.char-tabs.more-right { mask-image: linear-gradient(to left, transparent, #000 32px); }
.char-tabs.more-left { mask-image: linear-gradient(to right, transparent, #000 32px); }
.char-tabs.more-left.more-right { mask-image: linear-gradient(to right, transparent, #000 32px, #000 calc(100% - 32px), transparent); }

.char-tab {
  flex: none; position: relative;
  display: flex; align-items: center; gap: 9px;
  max-width: 280px; padding: 8px 12px 9px;
  border: 1px solid transparent; border-bottom: none;
  border-radius: 10px 10px 0 0;
  background: transparent; color: var(--ink-soft);
  font: inherit; text-align: left; cursor: pointer;
}
.char-tab:hover { background: color-mix(in srgb, var(--bg-raised) 60%, transparent); color: var(--ink); }
.char-tab.active {
  background: var(--bg-raised); color: var(--ink);
  border-color: var(--line);
  box-shadow: inset 0 3px 0 var(--accent);
  z-index: 1;
}
.char-tab:focus-visible { outline-offset: -2px; }
.char-tab-text { display: flex; flex-direction: column; min-width: 0; line-height: 1.25; }
.char-tab-name, .char-tab-line { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 190px; }
.char-tab-name { font-weight: 600; font-size: .9375rem; }
.char-tab-line { font-size: var(--fs-meta); color: var(--ink-soft); }
.char-tab-todo {
  flex: none; display: grid; place-items: center;
  min-width: 21px; height: 21px; padding: 0 6px; border-radius: 999px;
  font-size: var(--fs-label); font-weight: 700;
  background: var(--todo-soft); color: var(--todo);
  border: 1px solid color-mix(in srgb, var(--todo) 40%, transparent);
}

.char-new {
  flex: none; align-self: center; margin-bottom: 7px;
  border: 1px dashed var(--line-strong); border-radius: var(--radius-sm);
  background: transparent; color: var(--ink-soft);
  padding: 7px 12px; font: inherit; font-size: var(--fs-desc); white-space: nowrap; cursor: pointer;
}
.char-new:hover { border-style: solid; border-color: var(--accent); color: var(--accent-ink); background: var(--bg-raised); }
.char-manage { margin-left: auto; align-self: center; margin-bottom: 7px; white-space: nowrap; }
.char-manage-short { display: none; }

/* ------------------------------------------------------------ mode bar */
/* Reading the sheet and editing the character are two separate places.
   The switch says which one you are in; the edit sections appear only while
   editing, on a tinted bar so the change of mode is visible at a glance. */
.modebar {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  padding: 8px 16px;
}
.modebar.editing { background: color-mix(in srgb, var(--gold-soft) 55%, var(--bg-raised)); }

.mode-switch {
  display: inline-flex; gap: 2px; padding: 3px;
  background: var(--bg-sunken); border: 1px solid var(--line); border-radius: 10px;
}
.mode {
  display: inline-flex; align-items: center; gap: 7px;
  border: none; background: transparent; color: var(--ink-soft);
  padding: 7px 14px; border-radius: 7px;
  font: inherit; font-size: .9375rem; font-weight: 600; cursor: pointer; white-space: nowrap;
}
.mode:hover { color: var(--ink); }
.mode.active {
  background: var(--bg-raised); color: var(--accent-ink);
  box-shadow: 0 0 0 1px var(--line-strong), 0 1px 3px rgba(0, 0, 0, .12);
}
.mode .icon { color: currentColor; }

.edit-steps { display: flex; align-items: center; gap: 2px; min-width: 0; overflow-x: auto; scrollbar-width: thin; }
.edit-steps::before {
  content: ""; flex: none; width: 1px; height: 26px; margin-right: 10px;
  background: var(--line-strong);
}
.tab {
  border: none; background: none; color: var(--ink-soft);
  padding: 7px 12px; border-radius: 7px;
  font: inherit; font-size: .9375rem; cursor: pointer; white-space: nowrap;
}
.tab:hover { color: var(--ink); background: color-mix(in srgb, var(--bg-raised) 70%, transparent); }
.tab.active { color: var(--accent-ink); background: var(--bg-raised); font-weight: 600; box-shadow: inset 0 -2px 0 var(--accent); }

.save-state { margin-left: auto; font-size: var(--fs-meta); color: var(--ink-soft); min-width: 3.5em; text-align: right; }

.todo-badge {
  display: inline-block; margin-left: 6px; min-width: 18px; padding: 1px 6px;
  font-size: var(--fs-label); font-weight: 700; border-radius: 999px; text-align: center;
  background: var(--todo); color: var(--on-todo); vertical-align: 1px;
}

/* --------------------------------------------------------------- main */
main { padding: 18px 16px 80px; max-width: 1180px; margin: 0 auto; }

.view-head { margin-bottom: 16px; }
.view-head h1 { margin-bottom: 4px; }
.view-head .muted { margin: 0; }

.muted { color: var(--ink-soft); }
.small { font-size: var(--fs-desc); }
.tiny { font-size: var(--fs-meta); }
/* Prose inside cards stops at a readable line length. */
p.small, p.tiny, ul.small, .choice-help, .opt-desc, .spell-desc, .feature-desc, .view-head p { max-width: var(--measure); }
.center { text-align: center; }
.nowrap { white-space: nowrap; }

.card {
  background: var(--bg-raised); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 16px; margin-bottom: 14px;
  box-shadow: var(--shadow);
}
.card > h2, .card > h3 { margin-bottom: 4px; }
.card-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; flex-wrap: wrap; margin-bottom: 10px; }

/* An icon badge leading a title, with the subtitle tucked under the title. */
.entry-head { display: flex; align-items: center; gap: 11px; min-width: 0; }
.entry-head h2, .entry-head h3 { margin: 0; }
.entry-sub { margin: 2px 0 0; }

/* A section heading with its own small glyph. */
.group-head { display: flex; align-items: center; gap: 7px; }

.grid { display: grid; gap: 12px; }
.grid-2 { grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); }
.grid-3 { grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); }
/* Fixed column counts where auto-fit would strand the last item on its own row. */
.grid-fixed-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.grid-fixed-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.row { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; }
.spread { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; justify-content: space-between; }

/* ------------------------------------------------------------ buttons */
.btn {
  border: 1px solid var(--line-strong); background: var(--bg-raised); color: var(--ink);
  padding: 7px 13px; border-radius: var(--radius-sm); font: inherit; font-size: .88rem;
  cursor: pointer;
}
.btn:hover:not(:disabled) { background: var(--bg-sunken); }
.btn:disabled { opacity: .5; cursor: not-allowed; }
.btn-primary { background: var(--accent); border-color: var(--accent); color: var(--on-accent); font-weight: 600; }
.btn-primary:hover:not(:disabled) { background: color-mix(in srgb, var(--accent) 88%, var(--ink)); }
.btn-danger { color: var(--danger); border-color: var(--danger); background: transparent; }
#btn-delete { margin-top: 18px; }
/* For actions that should be findable but not compete with the page. */
.btn-quiet { background: transparent; border-color: transparent; color: var(--ink-soft); }
.btn-quiet:hover:not(:disabled) { background: var(--bg-sunken); color: var(--ink); }
.btn-quiet.active { background: var(--accent-soft); color: var(--accent-ink); font-weight: 600; }
.btn-sm { padding: 4px 9px; font-size: .8rem; }

/* Segmented control: a setting, visibly one of several, never the primary fill. */
.seg { display: inline-flex; flex-wrap: wrap; border: 1px solid var(--line-strong); border-radius: var(--radius-sm); overflow: hidden; }
.seg-btn {
  border: none; border-right: 1px solid var(--line-strong); background: var(--bg-raised); color: var(--ink-soft);
  padding: 6px 12px; font: inherit; font-size: .86rem; cursor: pointer; white-space: nowrap;
}
.seg-btn:last-child { border-right: none; }
.seg-btn:hover { background: var(--bg-sunken); color: var(--ink); }
.seg-btn[aria-pressed="true"] { background: var(--accent-soft); color: var(--accent-ink); font-weight: 600; box-shadow: inset 0 -2px 0 var(--accent); }
.seg-wrap { margin-bottom: 12px; }
.btn.block { display: block; width: 100%; margin-bottom: 8px; text-align: center; }
.file-btn { cursor: pointer; }

/* ------------------------------------------------------- form controls */
label.field { display: block; margin-bottom: 10px; }
label.field > span { display: block; font-size: var(--fs-meta); color: var(--ink-soft); margin-bottom: 3px; }
input[type="text"], input[type="number"], input[type="search"], select, textarea {
  width: 100%; padding: 7px 9px; font: inherit; font-size: .9rem;
  background: var(--bg); color: var(--ink);
  border: 1px solid var(--line-strong); border-radius: var(--radius-sm);
}
textarea { min-height: 80px; resize: vertical; }
input:focus-visible, select:focus-visible, textarea:focus-visible, button:focus-visible, .opt:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 1px;
}

.filters { display: flex; gap: 8px; flex-wrap: wrap; align-items: end; margin-bottom: 12px; }
.filters label.field { margin: 0; min-width: 130px; flex: 1 1 130px; }
.filters label.field.wide { flex: 2 1 220px; }

/* ------------------------------------------------------------- badges */
.badge {
  display: inline-block; font-size: var(--fs-label); font-weight: 700; letter-spacing: .03em;
  padding: 1px 6px; border-radius: 4px; text-transform: uppercase;
  background: color-mix(in srgb, var(--ink) 9%, transparent); color: var(--ink-soft); white-space: nowrap;
}
.badge-tcm { background: var(--gold-soft); color: #7a5f1f; }
:root[data-theme="dark"] .badge-tcm { color: var(--gold); }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .badge-tcm { color: var(--gold); } }
.badge-phb { background: var(--bg-sunken); color: var(--ink-faint); }
.badge-verify { background: var(--todo-soft); color: var(--todo); }
.badge-ok { background: var(--ok-soft); color: var(--ok); }
.badge-todo { background: var(--todo-soft); color: var(--todo); }
.badge-conc { background: var(--accent-soft); color: var(--accent-ink); }

/* -------------------------------------------------------- choice cards */
.choice {
  border: 1px solid var(--line); border-radius: var(--radius);
  margin-bottom: 12px; background: var(--bg-raised); overflow: hidden;
}
.choice.pending { border-color: var(--todo); box-shadow: 0 0 0 1px var(--todo-soft); }
.choice-head {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 11px 14px; cursor: pointer; background: none; border: none;
  width: 100%; text-align: left; font: inherit; color: inherit;
}
.choice-head:hover { background: var(--bg-sunken); }
.choice-title { font-weight: 600; flex: 1 1 0; min-width: 0; }
.choice-sub { display: block; font-weight: 400; font-size: var(--fs-meta); color: var(--ink-faint); }
.choice-count { flex: none; font-family: var(--mono); font-size: var(--fs-meta); color: var(--ink-soft); }
.choice-caret { flex: none; color: var(--ink-faint); font-size: .8rem; }
.choice-head > .badge { flex: none; }
.choice-body { padding: 0 14px 14px; border-top: 1px solid var(--line); }
.choice-help { font-size: var(--fs-desc); color: var(--ink-soft); margin: 10px 0; }
.choice-search { margin: 10px 0; }
/* Always present, so the first pick never changes the card's height. */
.choice-foot { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-top: 10px; }
.choice-foot-count { font-size: var(--fs-meta); color: var(--ink-soft); }

/* minmax(0, 1fr), so a long word can never push a card past its column. */
.opts { display: grid; gap: 8px; grid-template-columns: repeat(auto-fill, minmax(min(250px, 100%), 1fr)); }
.opts.list { grid-template-columns: minmax(0, 1fr); }
.opt {
  display: flex; gap: 9px; align-items: flex-start;
  border: 1px solid var(--line); border-radius: var(--radius-sm);
  padding: 9px 11px; background: var(--bg); cursor: pointer; text-align: left;
  font: inherit; color: inherit; width: 100%;
}
.opt:hover:not(.disabled) { border-color: var(--line-strong); background: var(--bg-sunken); }
.opt.selected { border-color: var(--accent); background: var(--accent-soft); }
.opt.disabled { cursor: not-allowed; background: var(--bg-sunken); }
.opt.disabled .opt-name, .opt.disabled .opt-desc, .opt.disabled .opt-mark { opacity: .6; }
.opt-reason { display: block; font-size: var(--fs-meta); font-weight: 600; color: var(--todo); margin-top: 2px; }
.opt-mark {
  flex: none; width: 17px; height: 17px; margin-top: 2px; border-radius: 4px;
  border: 1.5px solid var(--line-strong); display: grid; place-items: center;
  font-size: .7rem; color: #fff; background: var(--bg-raised);
}
.opt.selected .opt-mark { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
/* Pick one: a round radio mark with a dot. Pick several: the square with a tick. */
.opt.single .opt-mark { border-radius: 50%; font-size: 0; }
.opt.single.selected .opt-mark { background: var(--bg-raised); box-shadow: inset 0 0 0 4px var(--accent); }
.opt-body { min-width: 0; }
.opt-name { font-weight: 600; font-size: .92rem; display: flex; gap: 6px; align-items: center; flex-wrap: wrap; }
/* The glyph sits on the text baseline in prose, but these rows centre it. */
.opt-name .icon { vertical-align: 0; }
.opt-desc { display: block; font-size: var(--fs-desc); color: var(--ink-soft); margin-top: 2px; }
.opt-desc.clamp { display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }

/* ------------------------------------------------------- ability block */
.abilities { display: grid; gap: 10px; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); }
.ability {
  border: 1px solid var(--line); border-radius: var(--radius);
  padding: 10px; text-align: center; background: var(--tile);
}
.ability-icon { display: grid; place-items: center; margin-bottom: 2px; }
.ability-name { font-size: var(--fs-label); letter-spacing: .06em; text-transform: uppercase; color: var(--ink-faint); }
.ability-score { font-family: var(--serif); font-size: 1.9rem; line-height: 1.1; }
.ability-mod { font-family: var(--mono); font-size: .9rem; color: var(--accent); font-weight: 700; }
.ability-detail { font-size: var(--fs-meta); color: var(--ink-faint); margin-top: 3px; }
.stepper { display: flex; gap: 4px; justify-content: center; margin-top: 7px; align-items: center; }
.stepper button { width: 26px; height: 26px; padding: 0; font-size: .95rem; line-height: 1; }
.stepper input { width: 46px; text-align: center; padding: 3px; }

/* ------------------------------------------------------------- sheet */
.sheet-top { display: grid; gap: 12px; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }
.stat-tile {
  border: 1px solid var(--line); border-radius: var(--radius);
  padding: 12px; text-align: center; background: var(--tile);
}
.stat-tile .label { font-size: var(--fs-label); text-transform: uppercase; letter-spacing: .06em; color: var(--ink-faint); }
.stat-tile .value { font-family: var(--serif); font-size: 1.8rem; line-height: 1.15; }
.stat-tile .sub { font-size: var(--fs-meta); color: var(--ink-faint); }
/* A value that is words rather than a number. */
.stat-tile .value.text { font: 600 1.05rem/1.3 var(--sans); padding: 6px 0 2px; overflow-wrap: anywhere; }

table.data { width: 100%; border-collapse: collapse; font-size: .88rem; }
table.data th, table.data td { text-align: left; padding: 6px 8px; border-bottom: 1px solid var(--line); vertical-align: top; }
table.data th { font-size: var(--fs-label); text-transform: uppercase; letter-spacing: .05em; color: var(--ink-faint); font-weight: 600; }
table.data tr:last-child td { border-bottom: none; }
table.data td.num, table.data th.num { text-align: right; font-family: var(--mono); white-space: nowrap; }
table.data tr.is-current { background: var(--accent-soft); }
table.data tr.is-current .skill-abbr { color: var(--ink-soft); }
.table-scroll { overflow-x: auto; }

.skill-list { display: grid; gap: 2px; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }
.skill-row { display: flex; gap: 8px; align-items: center; padding: 4px 6px; border-radius: var(--radius-sm); }
.skill-row.prof { background: color-mix(in srgb, var(--accent) 11%, transparent); }
.skill-dot { flex: none; width: 9px; height: 9px; border-radius: 50%; border: 1.5px solid var(--line-strong); }
.skill-row.prof .skill-dot { background: var(--accent); border-color: var(--accent); }
.skill-row.expert .skill-dot { background: var(--gold); border-color: var(--gold); box-shadow: 0 0 0 2px var(--gold-soft); }
.skill-name { flex: 1 1 auto; }
.skill-bonus { font-family: var(--mono); font-weight: 700; }
.skill-abbr { font-size: var(--fs-label); color: var(--ink-faint); }

.feature { border-left: 3px solid var(--line-strong); padding: 2px 0 2px 11px; margin-bottom: 12px; }
.feature.from-subclass { border-left-color: var(--accent); }
.feature.from-species { border-left-color: var(--gold); }
.feature.from-feat { border-left-color: var(--ok); }
.feature-name { font-weight: 600; display: flex; gap: 7px; align-items: baseline; flex-wrap: wrap; }
.feature-src { font-size: var(--fs-meta); color: var(--ink-faint); }
.feature-desc { font-size: .9rem; color: var(--ink-soft); margin-top: 2px; }

.slots { display: flex; gap: 7px; flex-wrap: wrap; }
.slot-pill {
  border: 1px solid var(--line-strong); border-radius: var(--radius-sm);
  padding: 5px 10px; font-size: .82rem; background: var(--bg);
}
.slot-pill b { font-family: var(--mono); }

/* The icon has a column of its own; level, name, details and description all
   share one left edge beside it, however they wrap. */
.spell-line {
  display: grid; grid-template-columns: 26px minmax(0, 1fr); column-gap: 10px; align-items: start;
  padding: 7px 0; border-bottom: 1px dashed var(--line);
}
.spell-line > .icon-badge { grid-row: 1 / span 2; margin-top: 1px; }
.spell-line:last-child { border-bottom: none; }
.spell-head { display: flex; gap: 4px 9px; align-items: baseline; flex-wrap: wrap; min-width: 0; }
.spell-lvl { flex: none; font-family: var(--mono); font-size: var(--fs-meta); color: var(--ink-faint); }
.spell-name { font-weight: 600; }
.spell-meta { font-size: var(--fs-meta); color: var(--ink-faint); }
.spell-desc { grid-column: 2; font-size: var(--fs-desc); color: var(--ink-soft); margin-top: 2px; }

details.acc { border: 1px solid var(--line); border-radius: var(--radius); margin-bottom: 10px; background: var(--bg-raised); }
details.acc > summary { padding: 10px 13px; cursor: pointer; font-weight: 600; font-size: .92rem; }
details.acc > summary::marker { color: var(--ink-faint); }
details.acc > div { padding: 0 13px 13px; }

.notice {
  border-left: 3px solid var(--gold); background: var(--gold-soft);
  padding: 10px 13px; border-radius: var(--radius-sm); font-size: .85rem;
  margin-bottom: 14px;
}
.notice.warn { border-left-color: var(--todo); background: var(--todo-soft); }
.notice.ok { border-left-color: var(--ok); background: var(--ok-soft); }

.empty { padding: 30px 16px; text-align: center; color: var(--ink-faint); }

/* -------------------------------------------------------------- drawer */
.drawer {
  position: fixed; inset: 0 auto 0 0; width: min(340px, 86vw); z-index: 50;
  background: var(--bg-raised); border-right: 1px solid var(--line);
  display: flex; flex-direction: column; box-shadow: var(--shadow);
}
.drawer-head { display: flex; align-items: center; justify-content: space-between; padding: 12px 14px; border-bottom: 1px solid var(--line); }
.drawer-body { padding: 14px; overflow-y: auto; }
.drawer-actions { margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--line); }
.scrim { position: fixed; inset: 0; background: rgba(0, 0, 0, .4); z-index: 45; }

.roster-list { list-style: none; margin: 0 0 12px; padding: 0; }
.roster-list li { margin-bottom: 6px; }
.roster-item {
  display: flex; align-items: center; gap: 10px;
  width: 100%; text-align: left; border: 1px solid var(--line);
  background: var(--bg); border-radius: var(--radius-sm); padding: 9px 11px;
  cursor: pointer; font: inherit; color: inherit;
}
.roster-item:hover { border-color: var(--line-strong); }
.roster-item.active { border-color: var(--accent); background: var(--accent-soft); }
.roster-item strong { display: block; }
.roster-item span { font-size: .78rem; color: var(--ink-soft); }

/* --------------------------------------------------------------- toast */
.toast {
  position: fixed; left: 50%; bottom: 22px; transform: translateX(-50%);
  background: var(--ink); color: var(--bg); padding: 9px 16px;
  border-radius: 999px; font-size: .86rem; z-index: 60; box-shadow: var(--shadow);
  max-width: 90vw; text-align: center;
}

/* ----------------------------------------------------------- level up */
.levelup-hero {
  display: flex; gap: 16px; align-items: center; flex-wrap: wrap;
  border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--bg-raised); padding: 16px; margin-bottom: 14px;
}
.level-dial {
  flex: none; width: 76px; height: 76px; border-radius: 50%;
  display: grid; place-items: center; background: var(--accent-soft);
  border: 2px solid var(--accent);
}
.level-dial b { font-family: var(--serif); font-size: 1.9rem; color: var(--accent-ink); line-height: 1; }
.level-dial span { display: block; margin-top: 3px; font-size: .7rem; text-transform: uppercase; letter-spacing: .08em; color: var(--accent-ink); }

.xp-bar { height: 7px; border-radius: 999px; background: var(--bg-sunken); overflow: hidden; margin-top: 6px; }
.xp-bar > i { display: block; height: 100%; background: var(--gold); }

/* ------------------------------------------------------ editing links */
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.card-actions { gap: 6px; }

/* Anything that takes you somewhere to change something: a pencil and the
   accent colour, the same on every card. */
.edit-link {
  display: inline-flex; align-items: center; gap: 6px;
  color: var(--accent-ink); font-weight: 600;
  border-color: color-mix(in srgb, var(--accent) 45%, var(--line-strong));
}
.edit-link:hover:not(:disabled) { background: var(--accent-soft); }
.edit-link.btn-primary { color: #fff; border-color: var(--accent); }
.edit-link.btn-primary:hover:not(:disabled) { background: var(--accent); }
.edit-link .icon { color: currentColor; vertical-align: 0; }

/* In play: fields line up by their labels, whether or not they have help text. */
.in-play { align-items: flex-start; }
.in-play > div { flex: 1 1 160px; }

/* ------------------------------------------------------------ tracking */
/* One row per thing that gets spent: its name on the left, circles on the right. */
.track-row {
  display: flex; align-items: center; justify-content: space-between; gap: 6px 14px; flex-wrap: wrap;
  padding: 8px 0; border-top: 1px solid var(--line);
}
.card > .track-row:first-of-type, .in-play + .track-row { margin-top: 6px; }
.track-name { display: flex; flex-direction: column; min-width: 0; font-weight: 600; }
.track-meta { font-size: var(--fs-meta); font-weight: 400; color: var(--ink-soft); }

/* Filled = still available, hollow = spent. The button is bigger than the
   circle so it is easy to hit. */
.pips { display: flex; align-items: center; flex-wrap: wrap; gap: 2px; }
.pip {
  width: 28px; height: 28px; padding: 0; border: none; background: none; cursor: pointer;
  display: grid; place-items: center; border-radius: 50%;
}
.pip::before {
  content: ""; width: 16px; height: 16px; border-radius: 50%;
  border: 2px solid var(--line-strong); background: transparent; box-sizing: border-box;
  transition: background .12s, border-color .12s;
}
.pip.on::before { background: var(--accent); border-color: var(--accent); }
.pip:hover::before { border-color: var(--accent); }
.pip:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.pip-count { margin-left: 8px; min-width: 3.2em; font-family: var(--mono); font-size: var(--fs-meta); color: var(--ink-soft); }

.use-stepper { display: flex; align-items: center; gap: 6px; }
.use-stepper input { width: 64px; text-align: center; }
.use-of { font-size: var(--fs-meta); color: var(--ink-soft); }

.rest-row { display: flex; gap: 8px; flex-wrap: wrap; padding-top: 12px; border-top: 1px solid var(--line); margin-top: 4px; }

/* ------------------------------------------------------------- dialogs */
.rest-dialog {
  width: min(560px, calc(100vw - 24px)); max-height: calc(100vh - 32px);
  padding: 0; border: 1px solid var(--line-strong); border-radius: var(--radius);
  background: var(--bg-raised); color: var(--ink); box-shadow: 0 18px 50px rgba(0, 0, 0, .35);
}
.rest-dialog[open] { display: flex; flex-direction: column; }
.rest-dialog::backdrop { background: rgba(0, 0, 0, .45); }
.dialog-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; padding: 16px 18px 10px; border-bottom: 1px solid var(--line); }
.dialog-head h2 { margin-bottom: 2px; }
.dialog-head p { margin: 0; }
.dialog-body { padding: 4px 18px; overflow-y: auto; }
.dialog-section { padding: 12px 0; border-bottom: 1px solid var(--line); }
.dialog-section:last-child { border-bottom: none; }
.dialog-section h3 { margin-bottom: 6px; }
.dialog-section ul { margin: 4px 0 0; padding-left: 20px; }
.dialog-foot { display: flex; justify-content: flex-end; gap: 8px; padding: 12px 18px; border-top: 1px solid var(--line); background: var(--bg); border-radius: 0 0 var(--radius) var(--radius); }
.hp-preview { font-size: var(--fs-desc); color: var(--ink-soft); }
.hp-preview b { color: var(--ink); font-size: 1rem; }
.die-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin: 8px 0; }
.die-row input { width: 76px; }
.die-name { min-width: 8.5em; font-size: var(--fs-desc); color: var(--ink-soft); }
.die-name b { color: var(--ink); font-size: 1rem; margin-right: 4px; }
.die-or { font-size: var(--fs-meta); color: var(--ink-soft); }
.ar-count { min-width: 1.5em; text-align: center; font-family: var(--mono); }
.spent-list { list-style: none; padding: 0 !important; margin: 6px 0 0; font-size: var(--fs-desc); }
.spent-list li { padding: 3px 0; }
.link-btn { border: none; background: none; padding: 0 4px; margin-left: 6px; color: var(--accent-ink); text-decoration: underline; font: inherit; font-size: var(--fs-meta); cursor: pointer; }
.check-row { display: flex; gap: 8px; align-items: flex-start; font-size: var(--fs-desc); cursor: pointer; }
.check-row input { margin-top: 3px; flex: none; }

/* Cards whose boxes are filled in right on the sheet. */
.inplace-hint { display: inline-flex; align-items: center; gap: 5px; font-size: var(--fs-meta); color: var(--ink-soft); }

.sheet-top { margin-bottom: 8px; }
.sheet-senses { margin: 0 0 14px; font-size: var(--fs-desc); color: var(--ink-soft); }
.sheet-senses strong { color: var(--ink); font-weight: 600; margin-right: 4px; }
.save-notes { margin: 12px 0 4px; padding-left: 20px; color: var(--ink-soft); }
.inplace-hint .icon { color: currentColor; }

/* ------------------------------------------------------------ sheet head */
.sheet-head { margin-bottom: 18px; }
/* The sheet's name reads as a heading but is a text field you can click into.
   A dashed underline and a pencil say so before you hover. */
.sheet-name { display: flex; align-items: center; gap: 6px; max-width: 100%; margin-bottom: 2px; cursor: text; }
.sheet-name input[type="text"] {
  font-family: var(--serif); font-size: 1.75rem; font-weight: 600; line-height: 1.25;
  padding: 2px 6px; margin-left: -7px; max-width: 100%;
  background: transparent; color: var(--ink);
  border: 1px solid transparent; border-bottom: 1px dashed var(--line-strong); border-radius: var(--radius-sm) var(--radius-sm) 0 0;
}
.sheet-name input[type="text"]:hover { border-color: var(--line-strong); border-style: dashed; }
.sheet-name input[type="text"]:focus { border-style: solid; border-color: var(--accent); background: var(--bg-raised); outline: none; }
.sheet-name input::placeholder { color: var(--ink-faint); font-style: italic; }
.sheet-name input[type="text"]:disabled { border-color: transparent; background: transparent; cursor: default; }
.sheet-name-hint { display: none; color: var(--ink-soft); }
@supports (field-sizing: content) {
  /* Sized to the name, so the pencil sits beside it; a long name shrinks the
     box and scrolls inside it rather than pushing the pencil off screen. */
  .sheet-name input[type="text"] { field-sizing: content; width: auto; min-width: 0; flex: 0 1 auto; }
  .sheet-name input[type="text"]:placeholder-shown { min-width: min(100%, 17ch); }
  .sheet-name-hint { display: inline-flex; flex: none; }
}
.sheet-sub { color: var(--ink-soft); font-size: 1rem; margin: 0 0 12px; }
.sheet-actions { display: flex; align-items: center; justify-content: space-between; gap: 8px 12px; flex-wrap: wrap; }
.sheet-actions > .row { gap: 8px; }

.notice-more { margin-top: 6px; }
.notice-more > summary { cursor: pointer; font-size: .84rem; color: var(--ink-soft); width: max-content; }
.notice-more > ul { margin: 6px 0 0; padding-left: 20px; }

/* Sections other tabs jump to: clear the sticky bar and flash once on arrival.
   --appbar-h is measured by app.js, because the bar wraps on narrow screens. */
[data-anchor] { scroll-margin-top: calc(var(--appbar-h, 110px) + 12px); }
.card.flash { animation: flash 1.6s ease-out; }
@keyframes flash {
  0%, 35% { box-shadow: 0 0 0 3px var(--accent); }
  100% { box-shadow: var(--shadow); }
}

/* -------------------------------------------------------------- party */
.profile-chip strong { color: var(--ink); }

/* Signing in, and other full-page messages. */
.gate { display: grid; place-items: center; min-height: 60vh; }
.gate-card {
  width: min(440px, 100%); padding: 28px 24px;
  background: var(--bg-raised); border: 1px solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow);
}
.gate-card h1 { margin-bottom: 6px; }
.login-card { width: min(520px, 100%); }
.login-form { margin-top: 16px; }
.login-label { display: block; font-weight: 600; margin-bottom: 6px; }
.login-row { display: flex; gap: 8px; }
.login-row input { flex: 1 1 auto; min-width: 0; }
.login-error { color: var(--danger); font-size: var(--fs-desc); margin: 10px 0 0; min-height: 1.3em; }

/* Who is signing in: the players, then the Dungeon Master on a row of their own. */
.account-grid { display: grid; gap: 8px; grid-template-columns: repeat(2, minmax(0, 1fr)); margin-top: 16px; }
.account-btn {
  display: flex; align-items: center; gap: 10px; padding: 10px 12px; text-align: left; cursor: pointer;
  font: inherit; color: inherit;
  background: var(--bg-raised); border: 1px solid var(--line); border-radius: var(--radius-sm);
}
.account-btn:hover { border-color: var(--accent); }
.account-btn.selected {
  border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent);
  background: color-mix(in srgb, var(--accent) 8%, var(--bg-raised));
}
.account-btn.dm { grid-column: 1 / -1; }
.account-text { display: flex; flex-direction: column; min-width: 0; }
.account-name { font-family: var(--serif); font-size: 1.1rem; font-weight: 600; line-height: 1.2; }
.account-role { font-size: var(--fs-meta); color: var(--ink-soft); }
.profile-avatar {
  display: grid; place-items: center; flex: none;
  width: 36px; height: 36px; border-radius: 50%;
  font-family: var(--serif); font-size: 1.1rem; font-weight: 600;
  background: color-mix(in srgb, currentColor 14%, transparent);
  border: 1px solid color-mix(in srgb, currentColor 35%, transparent);
}
.profile-avatar.sm { width: 24px; height: 24px; font-size: .8rem; }

.empty-profile { padding: 36px 0; }
.empty-profile h1 { margin-bottom: 6px; }

/* A character the Dungeon Master is reading. */
.readonly-bar {
  display: flex; align-items: center; justify-content: space-between; gap: 8px 14px; flex-wrap: wrap;
  padding: 10px 14px; margin-bottom: 14px; border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--icon-frost) 12%, var(--bg-raised));
  border-left: 3px solid var(--icon-frost); font-size: var(--fs-desc);
}
input:disabled, textarea:disabled, select:disabled { background: var(--bg-sunken); color: var(--ink); opacity: 1; cursor: default; }
.pips.readonly .pip { cursor: default; }
.pips.readonly .pip:hover::before { border-color: var(--line-strong); }
.pips.readonly .pip.on:hover::before { border-color: var(--accent); }

/* Saved on two devices at once: ask which to keep. */
.conflict-bar {
  position: fixed; left: 50%; bottom: 16px; transform: translateX(-50%); z-index: 55;
  display: flex; align-items: center; gap: 8px 14px; flex-wrap: wrap;
  width: min(720px, calc(100vw - 24px)); padding: 12px 16px;
  background: var(--bg-raised); color: var(--ink); font-size: var(--fs-desc);
  border: 1px solid var(--todo); border-left-width: 4px; border-radius: var(--radius-sm); box-shadow: var(--shadow);
}

/* The Party drawer. */
.party-group { margin-bottom: 10px; }
.party-head { display: flex; align-items: center; gap: 8px; font-size: .95rem; margin: 8px 0 6px; }
.roster-sub { list-style: none; padding: 0; margin: 0; }
.roster-sub li { margin-bottom: 6px; }
.party-none { margin: 0 0 6px 32px; }
.deleted-wrap h3 { font-size: .95rem; margin: 16px 0 6px; }
.deleted-list { list-style: none; padding: 0; margin: 0; }
.deleted-list li { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 6px 0; border-bottom: 1px solid var(--line); font-size: var(--fs-desc); }
#btn-logout { margin-top: 8px; }

/* A character's history. */
.history-list { list-style: none; padding: 0; margin: 0; }
.history-list li { display: grid; grid-template-columns: 8.5em minmax(0, 1fr) auto; gap: 4px 12px; align-items: center; padding: 8px 0; border-bottom: 1px solid var(--line); }
.history-when { font-size: var(--fs-meta); color: var(--ink-soft); }
.history-what { font-size: var(--fs-desc); min-width: 0; }

/* ------------------------------------------------------------ sheet tabs */
/* The sheet has its own tabs, in the place the edit sections take while editing. */
.sheet-tabs { display: flex; align-items: center; gap: 2px; min-width: 0; overflow-x: auto; scrollbar-width: thin; }
.sheet-tabs::before {
  content: ""; flex: none; width: 1px; height: 26px; margin-right: 10px;
  background: var(--line-strong);
}
.tab-short { display: none; }
.sheet-head.compact { margin-bottom: 14px; }

/* ------------------------------------ bonuses, and where each number comes from */
/* Anything a magic item or other bonus changes is tinted, in both themes. */
:root { --magic: #6a3d9a; --magic-soft: #efe7f7; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) { --magic: #c3a6ec; --magic-soft: #2e2540; }
}
:root[data-theme="dark"] { --magic: #c3a6ec; --magic-soft: #2e2540; }
:root[data-theme="light"] { --magic: #6a3d9a; --magic-soft: #efe7f7; }
.boosted, .value.boosted, .ability-score.boosted { color: var(--magic); }
.skill-row.boosted .skill-bonus { color: var(--magic); }

/* The small round "i": a small circle with a full-size tap target around it. */
.info-btn {
  position: relative; display: inline-grid; place-items: center; flex: none;
  width: 18px; height: 18px; margin-left: 5px; padding: 0; vertical-align: 1px;
  border: 1px solid var(--line-strong); border-radius: 50%; background: var(--bg-raised);
  color: var(--ink-soft); font: italic 700 11px/1 var(--serif);
  text-transform: none; letter-spacing: 0; cursor: pointer;
}
.info-btn::after { content: ""; position: absolute; inset: -10px; }
.info-btn:hover { color: var(--accent-ink); border-color: var(--accent); }
.info-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.stat-tile .label { display: flex; align-items: center; justify-content: center; }
.ability-name { display: flex; align-items: center; justify-content: center; }
.ability-detail { display: flex; align-items: center; justify-content: center; flex-wrap: wrap; }

.info-dialog { width: min(480px, calc(100vw - 24px)); }
table.breakdown { width: 100%; border-collapse: collapse; font-size: var(--fs-desc); margin: 10px 0; }
table.breakdown td { padding: 6px 6px; border-bottom: 1px solid var(--line); vertical-align: top; }
table.breakdown td.num { text-align: right; font-family: var(--mono); white-space: nowrap; }
table.breakdown tr.from-effect td { background: var(--magic-soft); }
table.breakdown tr.from-effect td:first-child { box-shadow: inset 3px 0 0 var(--magic); }
table.breakdown tr.is-note td { color: var(--ink-soft); }
table.breakdown tr.total td { font-weight: 700; border-bottom: none; border-top: 2px solid var(--line-strong); }
.breakdown-note { font-size: var(--fs-meta); color: var(--ink-soft); }
.breakdown-lines { padding-left: 18px; font-size: var(--fs-desc); }

.effect-list { list-style: none; margin: 4px 0 12px; padding: 0; }
.effect-row { display: flex; align-items: center; gap: 8px 10px; flex-wrap: wrap; padding: 7px 0; border-top: 1px solid var(--line); }
.effect-row:first-child { border-top: none; }
.effect-row input[type="checkbox"] { width: auto; margin: 0; }
.effect-row.off .effect-text { color: var(--ink-faint); text-decoration: line-through; }
.effect-text { flex: 1 1 220px; font-size: var(--fs-desc); }
.effect-actions { margin-left: auto; gap: 4px; }
.effect-form .field { margin-bottom: 10px; }
.effect-preview { margin: 10px 0 0; padding: 8px 10px; border-radius: var(--radius-sm); background: var(--magic-soft); color: var(--ink); font-weight: 600; }

/* --------------------------------------------------------------- inventory */
.coins { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 8px; }
.coin { display: flex; flex-direction: column; align-items: center; gap: 5px; }
.coin input { width: 100%; text-align: center; font-family: var(--mono); }
.coin-abbr {
  display: grid; place-items: center; width: 32px; height: 32px; border-radius: 50%;
  font: 700 .75rem/1 var(--sans); color: #2b2210; border: 1px solid rgba(0, 0, 0, .3);
}
.coin-cp { background: #d08a55; }
.coin-sp { background: #cfd3d8; }
.coin-ep { background: #dccb7e; }
.coin-gp { background: #e8b940; }
.coin-pp { background: #eef0f2; }
.custom-coins { list-style: none; padding: 0; margin: 12px 0 0; }
.custom-coins li { display: flex; align-items: center; gap: 8px; padding: 5px 0; border-top: 1px solid var(--line); }
.custom-coin-name { flex: 1 1 auto; font-weight: 600; }
.custom-coins input { width: 110px; text-align: center; font-family: var(--mono); }
.add-currency { margin-top: 10px; font-size: var(--fs-desc); }
.add-currency summary { cursor: pointer; color: var(--accent-ink); width: max-content; }
.add-currency .row { margin-top: 8px; flex-wrap: nowrap; }
.add-currency input { flex: 1 1 auto; min-width: 0; }

.item-filters { margin: 10px 0 4px; }
.item-filters .seg { flex-wrap: wrap; }
.item-list { list-style: none; margin: 6px 0 0; padding: 0; }
.item-result { display: flex; align-items: center; gap: 8px; padding: 8px 0; border-top: 1px solid var(--line); }
.item-main { flex: 1 1 auto; min-width: 0; }
.item-name { font-weight: 600; }
.item-meta { font-size: var(--fs-meta); color: var(--ink-soft); }
.item-result .info-btn, .inv-actions .info-btn { width: 26px; height: 26px; margin: 0 4px; font-size: 13px; }

.inv-status { display: flex; flex-wrap: wrap; gap: 4px 18px; margin: 0 0 6px; font-size: var(--fs-desc); color: var(--ink-soft); }
.warn-text { color: var(--danger); font-weight: 600; }
.inv-group-head { margin: 16px 0 2px; font-size: var(--fs-label); text-transform: uppercase; letter-spacing: .06em; color: var(--ink-faint); }
.inv-list { list-style: none; margin: 0; padding: 0; }
.inv-line {
  display: grid; grid-template-columns: minmax(0, 1fr) auto auto; gap: 4px 10px; align-items: start;
  padding: 8px 6px; border-top: 1px solid var(--line);
}
.inv-line.active { background: color-mix(in srgb, var(--magic) 7%, transparent); }
.inv-name { font-weight: 600; overflow-wrap: anywhere; }
.inv-meta { font-size: var(--fs-meta); color: var(--ink-soft); }
.inv-notes {
  margin-top: 2px; font-size: var(--fs-meta); color: var(--ink-soft); font-style: italic;
  white-space: pre-line; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.inv-toggles { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; margin-top: 6px; }
.pill-toggle {
  display: inline-flex; align-items: center; gap: 6px; padding: 3px 11px 3px 7px;
  border: 1px solid var(--line-strong); border-radius: 999px; background: var(--bg-raised);
  font-size: var(--fs-meta); cursor: pointer;
}
.pill-toggle input { width: auto; margin: 0; }
.pill-toggle.on { border-color: var(--magic); background: var(--magic-soft); font-weight: 600; }
.badge-on { background: var(--magic-soft); color: var(--magic); }
.inv-qty { display: flex; align-items: center; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--bg-raised); }
.qty-btn { width: 30px; height: 30px; padding: 0; border: none; background: none; color: var(--ink-soft); font-size: 1.05rem; cursor: pointer; }
.qty-btn:hover { color: var(--accent-ink); background: var(--bg-sunken); }
.qty-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.qty-num { min-width: 2.2ch; text-align: center; font-family: var(--mono); }
.inv-qty-ro { font-family: var(--mono); color: var(--ink-soft); }
.inv-actions { display: flex; align-items: center; }
.edit-line { width: 34px; height: 34px; }
.charge-count { display: inline-flex; align-items: center; gap: 6px; font-family: var(--mono); font-size: var(--fs-meta); }

.facts { display: grid; grid-template-columns: max-content minmax(0, 1fr); gap: 5px 14px; margin: 10px 0; font-size: var(--fs-desc); }
.facts dt { color: var(--ink-soft); font-weight: 600; }
.facts dd { margin: 0; }
.item-desc { font-size: var(--fs-desc); }
.item-fx { padding: 8px 10px; border-radius: var(--radius-sm); background: var(--magic-soft); font-size: var(--fs-desc); }
.item-badges { gap: 6px; margin-top: 10px; }
.item-notes h4 { margin: 12px 0 2px; }
.dialog-foot-left { margin-right: auto; }
.check-field { align-self: end; min-height: 44px; }
table.data.attacks tr.magic td:first-child { color: var(--magic); font-weight: 600; }
.print-title { display: none; }

@media print {
  .topbar, .app-bar, .drawer, .scrim, .toast, .btn, .icon-btn, .readonly-bar, .conflict-bar,
  .inplace-hint, .sheet-name-hint, .notice { display: none !important; }
  .info-btn, .qty-btn, .edit-line, .add-currency, .pill-toggle input, [data-anchor="add-items"] { display: none !important; }
  .print-section { break-before: page; }
  .print-title { display: block; margin: 0 0 10px; }
  body { background: #fff; color: #000; }
  main { max-width: none; padding: 0; }
  .card { break-inside: avoid; box-shadow: none; border-color: #999; }
  .sheet-name input[type="text"] { border: none; color: #000; }
  /* Print the glyph, not the tinted disc it sits on: browsers drop background
     graphics by default, which would otherwise leave an empty box per icon. */
  .icon-badge { background: none; border: none; width: auto; height: auto; }

  /* The theme is remembered, so someone reading in dark mode prints with the
     dark tones still set - and those sit at 1.6:1 on white. Restate the light
     values here; this block wins whatever data-theme says. */
  :root, :root[data-theme="dark"], :root[data-theme="light"] {
    --icon-fire: #c1441e;
    --icon-frost: #1d7ea5;
    --icon-lightning: #857305;
    --icon-acid: #707a0b;
    --icon-poison: #2d5a35;
    --icon-necrotic: #7b3a86;
    --icon-radiant: #936c10;
    --icon-force: #3b5fc0;
    --icon-psychic: #9c2fa0;
    --icon-thunder: #3c5f96;
    --icon-life: #12855e;
    --icon-nature: #4a7024;
    --icon-mind: #c04070;
    --icon-shadow: #4f5570;
    --icon-arcane: #7444b8;
    --icon-divine: #8a5a17;
    --icon-neutral: #333;
  }
}

/* Touch: controls big enough to hit with a thumb. */
@media (pointer: coarse), (max-width: 560px) {
  .stepper button { width: 40px; height: 40px; }
  .stepper input { height: 40px; }
  .btn, .seg-btn { min-height: 40px; }
  .icon-btn { width: 44px; height: 44px; }
  input[type="text"], input[type="number"], input[type="search"], select { min-height: 44px; }
  input[type="checkbox"] { width: 20px; height: 20px; }
  .choice-head { padding: 12px 14px; }
  .char-tab, .char-new, .char-manage, .mode, .edit-steps .tab { min-height: 44px; }
  .pip { width: 36px; height: 36px; }
  .pip::before { width: 20px; height: 20px; }
}

@media (max-width: 560px) {
  main { padding: 14px 12px 70px; }
  /* Three tiles to a row, so the numbers that matter fit on one screen. */
  .sheet-top { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
  .stat-tile { padding: 8px 6px; }
  .stat-tile .value { font-size: 1.4rem; }
  .stat-tile .value.text { font-size: .9rem; }
  .sheet-abilities { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
  .grid-fixed-3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .grid-fixed-2 { grid-template-columns: minmax(0, 1fr); }
  .choice-head { flex-wrap: nowrap; align-items: flex-start; gap: 8px; }
  .opts { grid-template-columns: minmax(0, 1fr); }
  /* A long segmented row scrolls rather than stranding its last button. */
  .seg { flex-wrap: nowrap; overflow-x: auto; max-width: 100%; scrollbar-width: none; }
  .brand-sub { display: none; }
  .profile-chip-label { display: none; }
  .history-list li { grid-template-columns: minmax(0, 1fr) auto; }
  .history-when { grid-column: 1 / -1; }
  .topbar { padding: 8px 10px; gap: 6px; }
  #btn-compendium { padding-inline: 8px; }

  .sheet-name input[type="text"] { font-size: 1.45rem; }

  /* Tabs shrink to a name and a count; the class line is on the sheet. */
  .char-strip { padding: 6px 8px 0; gap: 6px; }
  .char-tab { padding: 8px 10px; gap: 7px; }
  .char-new, .char-manage { margin-bottom: 5px; }
  .char-tab .icon-badge { display: none; }
  .char-tab-line { display: none; }
  .char-tab-name { max-width: 96px; }
  .char-tabs { scroll-snap-type: x proximity; }
  .char-tab { scroll-snap-align: start; }
  .char-new-label, .char-manage-label { display: none; }
  .char-manage-short { display: inline; }
  .char-new, .char-manage { padding: 7px 11px; }

  /* The mode switch takes the first line, the edit sections the second. */
  .modebar { padding: 6px 8px; gap: 4px; }
  .mode-switch { flex: 1 1 auto; }
  .mode { flex: 1 1 0; justify-content: center; padding: 7px 10px; }
  .edit-steps { flex: 1 1 100%; order: 3; justify-content: space-between; }
  .edit-steps .tab { padding: 7px 10px; }
  .edit-steps::before { display: none; }
  .save-state { display: none; }
}

/* Sheet tabs and the inventory on a phone. */
@media (pointer: coarse), (max-width: 560px) {
  .sheet-tabs .tab { min-height: 44px; }
  .qty-btn { width: 40px; height: 40px; }
  .pill-toggle { min-height: 36px; }
}
@media (max-width: 560px) {
  .sheet-tabs { flex: 1 1 100%; order: 3; justify-content: space-between; }
  .sheet-tabs::before { display: none; }
  .sheet-tabs .tab { padding: 7px 8px; }
  .tab-long { display: none; }
  .tab-short { display: inline; }
  .coins { gap: 4px; }
  .coin-abbr { width: 28px; height: 28px; }
  .inv-line { grid-template-columns: minmax(0, 1fr) auto; }
  .inv-main { grid-row: 1 / span 2; }
  .inv-qty { grid-column: 2; grid-row: 1; }
  .inv-actions { grid-column: 2; grid-row: 2; justify-content: flex-end; }
  .custom-coins input { width: 90px; }
}
