/* ============================================================
   style-base.css
   Split from static/css/style.css on 2026-08-01 for token-cost
   reasons (7057-line file forced multi-chunk reads on every touch).
   Sections 1-6: CSS variables/tokens, reset, navbar, buttons, character vault list page
   Load order matters - see templates/base.html <link> order.
   ============================================================ */

/*
 * ============================================================
 *  D&D CHARACTER CREATOR — style.css
 *  Table of Contents (search for the section name with Ctrl+F)
 * ============================================================
 *
 *  1.  CSS VARIABLES & DESIGN TOKENS     :root { ...
 *  2.  BASE / BODY / RESET               *, body { ...
 *  3.  NAVBAR                            .navbar { ...
 *  4.  BUTTONS                           .btn { ...
 *  5.  PAGE HEADER                       .page-header { ...
 *  6.  CHARACTER VAULT                   .char-vault-shell { ...
 *  7.  WIZARD SHELL (desktop)            .wizard-shell { ...
 *  8.  MOBILE WIZARD SHELL               .wiz-mobile-nav { ...
 *  9.  STEP CONTENT & FORMS              .step-content { ...
 *  10. ABILITY GRID                      .ability-grid { ...
 *  11. SPELLS (wizard step)              .spell-panel { ...
 *  12. MODE CARDS & SETUP SECTIONS       .setup-section { ...
 *  13. REVIEW DOSSIER                    .review-hero-card { ...
 *  14. IDENTITY STEP                     .identity-panels { ...
 *  15. EQUIPMENT & INVENTORY             .inv-add-browser { ...
 *  16. HOMEBREW STEP                     .homebrew-step { ...
 *  17. CLASS STEP & GALLERY              .class-gallery-card { ...
 *  18. FEATURE ACCORDION                 .feat-accordion { ...
 *  19. CLASS FEATURES ACCORDION          .cf-section-header { ...
 *  20. ELDRITCH INVOCATIONS              .inv-list { ...
 *  21. THEME PICKER                      .theme-overlay { ...
 *  22. SOURCE & EDITION BADGES           .source-badge { ...
 *  23. RICH SEARCHABLE SELECT            .rich-select-wrapper { ...
 *  24. LOGIN & ADMIN PAGES               .login-container { ...
 *  25. PLAY SHEET (desktop)              .locked-play-sheet { ...
 *  26. MOBILE CHARACTER VAULT            @media (max-width: 720px) body { ...
 *  27. MOBILE PLAY SHEET                 @media (max-width: 899px) { ...
 *  28. MOBILE RESPONSIVE BREAKPOINT      @media (max-width: 640px) { ...
 *  29. MOBILE IDENTITY STEP              .wiz-mobile-identity { ...
 *  30. MOBILE CLASS STEP                 .wiz-mobile-class { ...
 *  31. MOBILE ABILITIES STEP             .wiz-mobile-abilities { ...
 *  32. MOBILE HOMEBREW STEP              .wiz-mobile-homebrew { ...
 *  33. MOBILE EQUIPMENT STEP             .wiz-mobile-equipment { ...
 *  34. MOBILE SPELLS STEP                .wiz-mobile-spells { ...
 *  35. VAULT DIALOG                      .vault-dialog-overlay { ...
 *  36. MISC FIXES & FEATURES             (point buy, previews, etc.)
 *  37. ERROR PAGES                       .error-page { ...
 *  38. ACCESSIBILITY (WHCM)              @media (forced-colors) { ...
 *  39. UI COMPONENTS                     (toggle, attunement, badge)
 *
 * ============================================================
 */

/* ══════════════════════════════════════════════════════════
   1. CSS VARIABLES & DESIGN TOKENS
   ══════════════════════════════════════════════════════════ */
:root {
  /* ── DARK · "Twilight indigo" (default) ── */
  --bg: #0f1322;
  --bg-glow: #1b2142;
  --surface: #161c33;
  --surface2: #1c2344;
  --input-bg: #141934;
  --border: #2c355e;
  --border-strong: #3a4576;
  --text: #eef1f8;
  --text-muted: #c2cbe6;
  --text-faint: #a3aed2;

  --accent: #e8c66a;          /* gold */
  --accent-strong: #f0d488;
  --accent-glow: rgba(232,198,106,.5);
  /* Soft accent wash for large tinted fills (selected type circles, section
     backgrounds). --accent-glow is a 50% focus-ring alpha — far too loud behind
     accent-colored text, so tinted surfaces use this instead. */
  --accent-soft: rgba(232,198,106,.14);
  --num: #e8c66a;             /* numeric values (ability mod, derived): gold in dark */
  --accent2: #3a4576;         /* level badge etc. (muted indigo in dark)
                               * A11Y-9 NOTE: --accent2 (#3a4576) on --bg (#0f1322) ≈ 2.1:1 — FAILS 3:1.
                               * Accent2 is not used as standalone text or focus indicator after A11Y-3 fix.
                               * Needs manual verification if ever used as text. */
  --accent-gold: #e8c66a;     /* keep existing token name, new value */
  --gold: #e8c66a;            /* fixes previously-undefined --gold */
  --on-accent: #141934;       /* text on gold buttons */
  --danger: #d9694e;          /* fixes previously-undefined --danger */
  --warn: #e8a64a;            /* allowed-but-noteworthy choices (custom recharge). Errors stay --danger. */
  --warn-soft: rgba(232,166,74,.14);

  /* status badges (mode-aware) — see .badge-* classes */
  --badge-grant-bg: #1a2a1a;  --badge-grant-fg: #80e080;  /* granted / free uses */
  --badge-prof-bg:  #1a1a2e;  --badge-prof-fg:  #99aaff;  /* proficiency source */
  --badge-info-bg:  #1a2a3a;  --badge-info-fg:  #80b0e0;  /* prerequisite info */
  --badge-warn-bg:  #2a1a1a;  --badge-warn-fg:  #e08080;  /* level gate / resistance */
  --badge-arcane-bg:#2a1a4a;  --badge-arcane-fg:#c8a8f8;  /* arcane cost */
  --badge-edition2024-bg:#2a4a7f; --badge-edition2024-fg:#c8d8f8;
  --badge-edition2014-bg:#4a3a1a; --badge-edition2014-fg:#f0d890;
  --badge-editionunknown-bg:#333; --badge-editionunknown-fg:#aaa;
  --badge-border: transparent;

  /* magic-item rarity (mode-aware) — consumed by .rarity-* classes, see style-components.css */
  --rarity-common-bg: #2b2f38;    --rarity-common-fg: #c3cad6;
  --rarity-uncommon-bg: #1a2a1a;  --rarity-uncommon-fg: #7fe08a;
  --rarity-rare-bg: #1a2a4a;      --rarity-rare-fg: #7ab8ff;
  --rarity-very_rare-bg: #2a1a4a; --rarity-very_rare-fg: #c8a8f8;
  --rarity-legendary-bg: #4a3a1a; --rarity-legendary-fg: #f0c860;
  --rarity-artifact-bg: #4a1a1a;  --rarity-artifact-fg: #ff8a6a;

  /* live-play sheet: semantic tag/marker colors with no existing equivalent */
  --success: #4ade80;
  --tag-resistance: #5b8a68;
  --tag-immunity: #7f74b7;
  --tag-vulnerability: #a45656;
  --tag-advantage: #c8a84b;
  --marker-expertise: #aab7ff;
  --marker-half: #9bd3c0;

  /* Carried-weight bands. One ramp, shared by the wizard's carry summary and the
     live-play carry bar, so both surfaces say the same thing in the same colour.
     Weight is advisory here — nothing is ever blocked — so the top of the ramp is a
     warm caution, not the alarm red of --danger. Deliberately graded in LIGHTNESS as
     well as hue so the ramp still reads as a ramp in greyscale; the band name is also
     spelled out in the copy, and over-capacity adds a hatch, so colour is never the
     only carrier of the message. */
  --carry-clear: #6b76a6;             /* unremarkable: muted indigo, near the border hue */
  --carry-encumbered: #d4b054;        /* light amber */
  --carry-heavily_encumbered: #cf7c3a;/* deeper orange — a clear step DOWN in lightness */
  --carry-over_capacity: #e2735a;     /* warm terracotta — loudest, still not an error red */

  /* Encounter difficulty tiers. One token per tier, Trivial to Overwhelming: slate, green,
     yellow-olive, orange, red, violet. Each step changes lightness as well as hue, and every
     chip spells its tier name, so colour is never the only signal. Overwhelming is the one
     filled chip; its text uses --on-tier-overwhelming. */
  --tier-trivial: #a3aed2;
  --tier-easy: #6fd08a;
  --tier-moderate: #e2d35c;
  --tier-hard: #ef9a4e;
  --tier-deadly: #f2796a;
  --tier-overwhelming: #b98af0;
  --on-tier-overwhelming: #141934;

  --radius: 6px;
  --radius-lg: 10px;
  --font: 'Source Sans 3', 'Segoe UI', system-ui, sans-serif;
  --font-display: 'Cormorant Garamond', Georgia, 'Times New Roman', serif;
  /* color-emoji stack: forces glyphs like ⚔️/🛡️ to render in the OS color font
     instead of inheriting a text font that draws them as dark monochrome. */
  --font-emoji: 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji', sans-serif;
}

/* ── LIGHT · "Tavern Parchment" ── */
[data-theme="light"] {
  --bg: #e9e2d1;
  --bg-glow: #ece5d6;
  --surface: #ded4c0;
  --surface2: #f3ece0;
  --input-bg: #f3ece0;
  --border: #bcaa86;
  --border-strong: #a89878;
  --text: #241c10;
  --text-muted: #2e2616;
  --text-faint: #4a3f29;

  --accent: #7a1f1f;          /* oxblood — active tab, CTA, links */
  --accent-strong: #5e1717;
  --accent-glow: rgba(122,31,31,.18);
  --accent-soft: rgba(122,31,31,.10);
  --accent2: #8a6a3a;
  --accent-gold: #8a6a3a;
  --gold: #8a6a3a;            /* A11Y-9: #8a6a3a on --surface #ded4c0 ≈ 3.5:1 — passes 3:1 (UI/large text)
                               * but fails 4.5:1 for normal body text; verify usage context */
  --num: #241c10;             /* numeric values (ability mod, derived): near-black ink in light */
  --on-accent: #f5ecd6;       /* text on oxblood buttons */
  --danger: #a33;
  --warn: #8a5a1f;            /* darker amber for parchment contrast */
  --warn-soft: rgba(138,90,31,.12);

  /* status badges — parchment-friendly tints + dark readable text */
  --badge-grant-bg: #d8e6cf;  --badge-grant-fg: #2f5024;
  --badge-prof-bg:  #dbe2f0;  --badge-prof-fg:  #2a3c6e;
  --badge-info-bg:  #d6e6ec;  --badge-info-fg:  #27505e;
  --badge-warn-bg:  #f0dcd6;  --badge-warn-fg:  #7a2a1a;
  --badge-arcane-bg:#e4dcf0;  --badge-arcane-fg:#4a2d6e;
  --badge-edition2024-bg:#dbe2f0; --badge-edition2024-fg:#2a3c6e;
  --badge-edition2014-bg:#ece0c4; --badge-edition2014-fg:#6e561f;
  --badge-editionunknown-bg:#e0d8c8; --badge-editionunknown-fg:#6b5a3e;
  --badge-border: rgba(0,0,0,.10);

  /* magic-item rarity — parchment-friendly tints + dark readable text */
  --rarity-common-bg: #e2e2dc;    --rarity-common-fg: #55524a;
  --rarity-uncommon-bg: #d8e6cf;  --rarity-uncommon-fg: #2f5024;
  --rarity-rare-bg: #d6e6ec;      --rarity-rare-fg: #27505e;
  --rarity-very_rare-bg: #e4dcf0; --rarity-very_rare-fg: #4a2d6e;
  --rarity-legendary-bg: #ece0c4; --rarity-legendary-fg: #6e561f;
  --rarity-artifact-bg: #f0dcd6;  --rarity-artifact-fg: #7a2a1a;

  /* live-play sheet: semantic tag/marker colors — parchment-friendly, readable ink shades */
  --success: #2f5024;
  --tag-resistance: #3d6b46;
  --tag-immunity: #5c4f96;
  --tag-vulnerability: #7a2a1a;
  --tag-advantage: #6e561f;
  --marker-expertise: #3a4d9e;
  --marker-half: #1f6e5a;

  /* Carried-weight bands — same ramp, inked for parchment. Each step is darker than the
     last against the light ground, so the greyscale ordering matches the dark theme's. */
  --carry-clear: #7d7767;
  --carry-encumbered: #8a6a1f;
  --carry-heavily_encumbered: #a04d10;
  --carry-over_capacity: #8f2f1c;

  /* Difficulty tiers, inked for parchment: the same order, each darker than the ground. */
  --tier-trivial: #3f4a6e;
  --tier-easy: #1f6b34;
  --tier-moderate: #6b5a0c;
  --tier-hard: #94450e;
  --tier-deadly: #8f1d1d;
  --tier-overwhelming: #4e2580;
  --on-tier-overwhelming: #f5ecd6;
}

/* Library-era navbar: light-theme overrides for tabs + avatar user menu */
[data-theme="light"] .nav-tab:hover { background: rgba(0,0,0,0.05); }
[data-theme="light"] .nav-tab.active { background: rgba(60,90,160,0.12); color: #3a5bd0; }
[data-theme="light"] .user-menu-dropdown { box-shadow: 0 8px 24px rgba(0,0,0,0.12); }

/* ══════════════════════════════════════════════════════════
   2. BASE / BODY / RESET
   ══════════════════════════════════════════════════════════ */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

body {
  background:
    radial-gradient(120% 80% at 50% -10%, var(--bg-glow) 0%, var(--bg) 60%) no-repeat,
    var(--bg);
  color: var(--text);
  font-family: var(--font);
  font-size: 14px;
  min-height: 100vh;
  min-height: 100dvh;
  transition: background-color .2s ease, color .2s ease;
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition: none !important; animation: none !important; }
}

/* Item #13: themed scrollbars everywhere (inventory panels, character vault list, etc.) --
   was the plain unstyled browser scrollbar. Firefox via scrollbar-color, WebKit/Blink via
   the ::-webkit-scrollbar pseudo-elements. */
* {
  scrollbar-width: thin;
  scrollbar-color: var(--border-strong) var(--surface);
}
*::-webkit-scrollbar { width: 10px; height: 10px; }
*::-webkit-scrollbar-track { background: var(--surface); }
*::-webkit-scrollbar-thumb {
  background: var(--border-strong);
  border-radius: 999px;
  border: 2px solid var(--surface);
}
*::-webkit-scrollbar-thumb:hover { background: var(--accent); }
*::-webkit-scrollbar-corner { background: var(--surface); }

a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }

/* [hidden] always wins until JS removes the attribute (dropdowns, panels) */
[hidden] { display: none !important; }

/* ══════════════════════════════════════════════════════════
   3. NAVBAR
   ══════════════════════════════════════════════════════════ */
.navbar {
  display: flex;
  align-items: center;
  gap: 24px;
  padding: 0 24px;
  height: 52px;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
}
.brand {
  font-family: var(--font-display);
  font-size: 22px;
  font-weight: 700;
  letter-spacing: .01em;
  color: var(--accent);
}
.nav-link { color: var(--text-muted); font-size: 13px; transition: color .15s ease; }
.nav-link:hover { color: var(--text); text-decoration: none; }

.theme-toggle {
  display: inline-flex; align-items: center; justify-content: center;
  width: 40px; height: 40px; border-radius: 99px;
  background: transparent; border: 1px solid var(--border-strong);
  color: var(--accent); cursor: pointer; font-size: 18px; line-height: 1;
  transition: border-color .15s ease, color .15s ease, background-color .15s ease;
}
.theme-toggle:hover { border-color: var(--accent); background: var(--surface2); }
.theme-toggle:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--accent-glow); }

/* ── Library-era navbar: tabs + avatar user menu ────────────────────── */
.nav-tabs { display: flex; align-items: center; gap: 6px; margin-left: 18px; }
.nav-tab {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 6px 14px; border-radius: 8px;
  color: var(--text, #d8dee9); text-decoration: none;
  font-size: 14px; font-weight: 600; white-space: nowrap;
}
.nav-tab:hover { background: var(--hover, rgba(255,255,255,0.06)); }
.nav-tab.active { background: var(--accent-soft, rgba(120,140,200,0.18)); color: var(--accent, #8fb0ff); }
.nav-tab .avatar { font-size: 13px; }

/* Tablet widths (above the mobile icon-only bar, below full desktop): tighten the top bar
   so the five tabs plus the account buttons fit without a horizontal scroll. */
@media (min-width: 721px) and (max-width: 960px) {
  .navbar { gap: 12px; padding: 0 12px; }
  .nav-tabs { margin-left: 6px; gap: 2px; }
  .nav-tab { padding: 6px 9px; min-height: 36px; box-sizing: border-box; }   /* 33px before: below the 36px touch target */
  .brand { font-size: 18px; white-space: nowrap; }
  .navbar .user-menu-toggle { width: 36px; height: 36px; }   /* 34px before */
  .navbar .nav-link { display: inline-flex; align-items: center; min-height: 36px; padding: 0 8px; }   /* the logged-out Login link was 19px */
}
/* Narrow tablets: same icon-only tabs the phone bar uses (labels stay for screen readers). */
@media (min-width: 721px) and (max-width: 820px) {
  .nav-tab { position: relative; padding: 7px 10px; }
  .nav-tab > span:last-child {
    position: absolute; width: 1px; height: 1px; margin: -1px;
    overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
  }
  .nav-tab > span:first-child { font-size: 17px; }
}

.user-menu { position: relative; }
.user-menu-toggle {
  display: inline-flex; align-items: center; justify-content: center;
  width: 34px; height: 34px; border-radius: 50%;
  border: 1px solid var(--border, #3a4150); background: transparent;
  cursor: pointer; color: var(--text, #d8dee9);
}
.user-menu-toggle:hover { background: var(--hover, rgba(255,255,255,0.06)); }
.user-menu-toggle[aria-expanded="true"] { background: var(--accent-soft, rgba(120,140,200,0.18)); }
.user-menu-dropdown {
  position: absolute; right: 0; top: calc(100% + 8px); min-width: 170px;
  background: var(--surface); border: 1px solid var(--border, #3a4150);
  border-radius: 10px; padding: 6px; box-shadow: 0 8px 24px rgba(0,0,0,0.35);
  z-index: 50;
}
.user-menu-header { padding: 8px 10px; font-weight: 700; font-size: 14px; border-bottom: 1px solid var(--border, #3a4150); margin-bottom: 4px; }
.user-menu-item { display: block; padding: 8px 10px; border-radius: 6px; color: var(--text, #d8dee9); text-decoration: none; font-size: 14px; }
.user-menu-item:hover { background: var(--hover, rgba(255,255,255,0.06)); }

/* Items #2/#3 (round 2): was a fixed 1100px cap, which barely mattered on typical
   1280-1440px laptop widths (main just filled ~100%, same as before) but left roughly half
   the screen empty on wide/ultra-wide monitors. Only scale the width down on genuinely wide
   viewports (>=1400px) so laptop-class screens keep their existing full-bleed layout; above
   that, ~76% width gives ~12% empty on each side instead of the previous ~50%, capped so it
   doesn't get absurd on ultra-wide monitors. */
main { padding: 24px; max-width: 1700px; margin: 0 auto; }
@media (min-width: 1400px) {
  main { width: 76%; }
}

/* ══════════════════════════════════════════════════════════
   4. BUTTONS
   ══════════════════════════════════════════════════════════ */
.btn {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 8px 18px; border-radius: var(--radius);
  font-family: var(--font);
  font-size: 13px; font-weight: 600; cursor: pointer;
  border: 1px solid transparent; transition: filter .15s ease, border-color .15s ease, color .15s ease, background-color .15s ease;
}
.btn:hover { filter: brightness(1.06); text-decoration: none; }
.btn-primary {
  background: linear-gradient(180deg, var(--accent-strong), var(--accent));
  color: var(--on-accent);
  border-color: var(--accent);
  font-weight: 700;
}
.btn-outline { background: transparent; color: var(--text); border: 1px solid var(--border-strong); }
.btn-outline:hover { border-color: var(--accent); color: var(--accent); filter: none; }
.btn-danger { background: var(--danger); color: #fff; border-color: var(--danger); }
.btn-sm { padding: 5px 12px; font-size: 12px; }
.btn-lg { padding: 11px 26px; font-size: 15px; }
.btn.disabled,
.btn[aria-disabled="true"],
.btn:disabled {
  opacity: 0.4;
  cursor: not-allowed;
  pointer-events: none;
}

/* ══════════════════════════════════════════════════════════
   6. CHARACTER VAULT
   ══════════════════════════════════════════════════════════ */
.char-vault-shell {
  display: flex;
  flex-direction: column;
  gap: 18px;
}

.char-vault-header {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 20px;
  padding: 22px 24px;
  background:
    linear-gradient(135deg, rgba(232,198,106,.12), transparent 38%),
    var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-lg);
  box-shadow: 0 18px 45px rgba(0,0,0,.18);
}

.char-vault-kicker {
  color: var(--accent);
  font-size: 11px;
  font-weight: 800;
  letter-spacing: .14em;
  text-transform: uppercase;
  margin-bottom: 4px;
}

.char-vault-header h1 {
  font-family: var(--font-display);
  font-size: clamp(32px, 5vw, 54px);
  line-height: .95;
  color: var(--text);
}

.char-vault-count {
  color: var(--text-muted);
  margin-top: 8px;
}

.char-vault-header-actions,
.char-vault-actions,
.char-vault-box-actions,
.char-vault-active-filters,
.char-vault-tag-stack {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px;
}
/* Card view: limit tag row to single line, shrink action buttons */
.char-vault-card .char-vault-tag-stack {
  max-height: 24px;
  overflow: hidden;
  flex-wrap: nowrap;
}
.char-vault-card .btn-sm {
  padding: 3px 8px;
  font-size: 11px;
}
.char-vault-layout {
  display: grid;
  grid-template-columns: minmax(230px, 280px) minmax(0, 1fr);
  gap: 18px;
  align-items: start;
}

.char-vault-sidebar {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.char-vault-box,
.char-vault-main,
.char-vault-empty,
.char-vault-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
}

.char-vault-box {
  padding: 14px;
}

.char-vault-box-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 10px;
}

.char-vault-box-head h2 {
  font-size: 13px;
  font-weight: 800;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--text-muted);
}

.char-vault-chip,
.char-vault-filter-count,
.char-vault-tag,
.char-vault-active-chip {
  border-radius: 999px;
  font-size: 11px;
  font-weight: 700;
}

.char-vault-chip,
.char-vault-filter-count {
  padding: 2px 8px;
  background: var(--surface2);
  color: var(--text-muted);
  border: 1px solid var(--border);
}

.char-vault-filter-list {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-bottom: 12px;
}

.char-vault-filter-btn {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 8px 10px;
  color: var(--text-muted);
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--radius);
  font-family: var(--font);
  font-size: 13px;
  cursor: pointer;
  text-align: left;
}

.char-vault-filter-btn:hover,
.char-vault-filter-btn.active {
  color: var(--text);
  background: var(--surface2);
  border-color: var(--border-strong);
}

.char-vault-filter-btn.active .char-vault-filter-count {
  color: var(--on-accent);
  background: var(--accent);
  border-color: var(--accent);
}

.char-vault-main {
  min-width: 0;
  padding: 16px;
}

.char-vault-toolbar {
  display: grid;
  grid-template-columns: minmax(220px, 1fr) minmax(180px, 220px) auto auto;
  gap: 10px;
  align-items: end;
  margin-bottom: 12px;
}

.char-vault-search,
.char-vault-sort {
  display: flex;
  flex-direction: column;
  gap: 5px;
  color: var(--text-muted);
  font-size: 11px;
  font-weight: 800;
  letter-spacing: .08em;
  text-transform: uppercase;
}

.char-vault-search input,
.char-vault-sort select {
  width: 100%;
  min-height: 38px;
  padding: 8px 10px;
  color: var(--text);
  background: var(--input-bg);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  font-family: var(--font);
  font-size: 13px;
}

.char-vault-filter-menu-wrap,
.char-vault-row-menu {
  position: relative;
}

.char-vault-filter-menu {
  position: absolute;
  right: 0;
  top: calc(100% + 8px);
  z-index: 30;
  width: min(760px, calc(100vw - 48px));
  display: grid;
  grid-template-columns: 160px minmax(220px, 1fr);
  gap: 12px;
  padding: 14px;
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-lg);
  box-shadow: 0 18px 55px rgba(0,0,0,.35);
}
.char-vault-filter-menu[hidden] { display: none !important; }

.char-vault-filter-cats,
.char-vault-filter-values {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.char-vault-filter-values h3 {
  color: var(--accent);
  font-size: 11px;
  letter-spacing: .1em;
  text-transform: uppercase;
}

.char-vault-filter-cats button,
.char-vault-filter-values button,
.char-vault-row-menu-panel button,
.char-vault-clear-filters,
.char-vault-active-chip,
.char-vault-view-btn {
  font-family: var(--font);
  cursor: pointer;
}

.char-vault-filter-cats button,
.char-vault-filter-values button {
  padding: 6px 8px;
  color: var(--text-muted);
  background: transparent;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  text-align: left;
}

.char-vault-filter-cats button:hover,
.char-vault-filter-cats button.active,
.char-vault-filter-values button:hover,
.char-vault-filter-values button.active {
  color: var(--text);
  border-color: var(--accent);
}

.char-vault-view-toggle {
  display: inline-flex;
  padding: 3px;
  background: var(--input-bg);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
}

.char-vault-view-btn {
  padding: 7px 10px;
  color: var(--text-muted);
  background: transparent;
  border: 0;
  border-radius: calc(var(--radius) - 2px);
  font-size: 12px;
  font-weight: 800;
}

.char-vault-view-btn.active {
  color: var(--on-accent);
  background: var(--accent);
}

.char-vault-active-filters {
  min-height: 34px;
  margin-bottom: 12px;
}

.char-vault-active-chip {
  padding: 5px 10px;
  color: var(--text);
  background: var(--surface2);
  border: 1px solid var(--border-strong);
}

.char-vault-clear-filters {
  color: var(--accent);
  background: transparent;
  border: 0;
  font-size: 12px;
  font-weight: 800;
}

.char-vault-results {
  min-height: 220px;
}

.char-vault-ledger {
  overflow-x: auto;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
}

.char-vault-ledger table {
  width: 100%;
  min-width: 860px;
  border-collapse: collapse;
}

.char-vault-ledger th,
.char-vault-ledger td {
  padding: 11px 12px;
  border-bottom: 1px solid var(--border);
  vertical-align: middle;
  text-align: left;
}

.char-vault-ledger th {
  color: var(--text-faint);
  background: var(--surface2);
  font-size: 11px;
  font-weight: 800;
  letter-spacing: .08em;
  text-transform: uppercase;
}

.char-vault-ledger tr:last-child td {
  border-bottom: 0;
}

/* Sticky Actions column — always visible even when table scrolls horizontally */
.char-vault-actions-th,
.char-vault-actions-cell {
  position: sticky;
  right: 0;
  background: var(--surface2);
  z-index: 2;
}
.char-vault-ledger th.char-vault-actions-th {
  background: var(--surface2);
}
tr:hover .char-vault-actions-cell {
  background: var(--surface2);
}
[data-theme="light"] .char-vault-actions-th,
[data-theme="light"] .char-vault-actions-cell,
[data-theme="light"] tr:hover .char-vault-actions-cell {
  background: var(--surface2);
}

/* Truncate long background names in ledger */
.char-vault-ledger tbody td:nth-child(4) {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 150px;
}

.char-vault-title-cell {
  display: flex;
  flex-direction: column;
  gap: 3px;
}

.char-vault-title-cell strong {
  color: var(--text);
  font-size: 14px;
}

.char-vault-title-cell span,
.char-vault-card-meta,
.char-vault-muted,
.loading,
.empty {
  color: var(--text-muted);
  font-size: 12px;
}

.char-vault-tag {
  display: inline-flex;
  padding: 3px 8px;
  border: 1px solid var(--border);
}

.char-vault-tag.manual {
  color: var(--text);
  background: var(--surface2);
}

.char-vault-tag.auto {
  color: var(--badge-info-fg);
  background: var(--badge-info-bg);
  border-color: var(--badge-border);
}

.char-vault-tag.draft {
  color: var(--badge-warn-fg, var(--text));
  background: var(--badge-warn-bg, var(--surface2));
  border-color: var(--badge-border);
}

.char-vault-row-menu-panel {
  position: absolute;
  right: 0;
  top: calc(100% + 6px);
  z-index: 20;
  min-width: 210px;
  padding: 6px;
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  box-shadow: 0 14px 35px rgba(0,0,0,.3);
}

.char-vault-row-menu-panel button {
  width: 100%;
  display: block;
  padding: 8px 10px;
  color: var(--text-muted);
  background: transparent;
  border: 0;
  border-radius: calc(var(--radius) - 2px);
  text-align: left;
  font-size: 13px;
}

.char-vault-row-menu-panel button:hover {
  color: var(--text);
  background: var(--surface2);
}

.char-vault-row-menu-panel button.danger {
  color: var(--danger);
}

.char-vault-card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 14px;
}

.char-vault-card,
.char-vault-empty {
  padding: 8px;
}

.char-vault-card {
  display: flex;
  flex-direction: column;
  gap: 5px;
}

/* Language / skill picker: highlight selected items */
#species-lang-choices label:has(input:checked) {
  background: rgba(212,168,67,0.12);
  border-radius: 4px;
  color: var(--gold, #d4a843);
  font-weight: 600;
}
#species-skill-choice-list .mastery-label:has(input:checked) {
  background: rgba(212,168,67,0.12);
  border-radius: 4px;
  color: var(--gold, #d4a843);
  font-weight: 600;
}

.char-vault-empty {
  display: grid;
  justify-items: start;
  gap: 10px;
}

.char-vault-empty h2 {
  font-family: var(--font-display);
  font-size: 28px;
}

@media (max-width: 980px) {
  .char-vault-layout,
  .char-vault-toolbar {
    grid-template-columns: 1fr;
  }

  .char-vault-filter-menu {
    left: 0;
    right: auto;
    grid-template-columns: repeat(2, minmax(130px, 1fr));
  }
}

@media (max-width: 640px) {
  .char-vault-header {
    align-items: stretch;
    flex-direction: column;
  }

  .char-vault-header-actions,
  .char-vault-actions {
    align-items: stretch;
    flex-direction: column;
  }

  .char-vault-header-actions .btn,
  .char-vault-actions .btn,
  .char-vault-row-menu,
  .char-vault-row-menu > .btn {
    width: 100%;
    justify-content: center;
  }

  .char-vault-filter-menu {
    width: calc(100vw - 48px);
    grid-template-columns: 1fr;
  }
}

.loading, .empty { color: var(--text-muted); padding: 24px 0; }

/* Bullet lists inside formatDescriptionHTML() output (static/js/text-format.js) --
   feature/spell/item/feat/background/class description text authored with
   markdown-style "- " lines. Lives here (loaded on every page) rather than a
   page-specific stylesheet since the formatter itself is shared app-wide.
   Inherits color/size/line-height from its container instead of hardcoding
   either, since it's reused across many differently-styled detail panels. */
.desc-list {
  margin: 4px 0;
  padding-left: 18px;
  list-style: disc;
  color: inherit;
  font-size: inherit;
  line-height: inherit;
  cursor: auto;
}
.desc-list li {
  margin: 2px 0;
}

/* Markdown tables inside formatDescriptionHTML() output (tryRenderTable() in
   static/js/text-format.js) -- random-effect tables baked into a few sourcebooks'
   description prose (e.g. Arrow of Slaying). Same "inherit from container, reused
   everywhere" approach as .desc-list above. */
.desc-table {
  margin: 6px 0;
  border-collapse: collapse;
  font-size: inherit;
  line-height: inherit;
  color: inherit;
}
.desc-table th,
.desc-table td {
  padding: 3px 10px 3px 0;
  text-align: left;
  border-bottom: 1px solid var(--border);
}
.desc-table th {
  font-weight: 700;
  color: var(--text-muted);
}

/* Tablets (721-980px): the vault drops to one column, which put every folder and tag box above the first
   character (it started about 1,600px down). The three boxes sit side by side and scroll inside themselves. */
@media (min-width: 721px) and (max-width: 980px) {
  .char-vault-sidebar { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; align-items: start; }
  .char-vault-sidebar > .char-vault-box { max-height: 240px; overflow-y: auto; }
}

/* ══════════════════════════════════════════════════════════
   VIEW TRANSITIONS  (cross-page, Chromium and Safari; Firefox ignores it)
   Ground rules: subtle motion only, nothing over 500ms, off for reduced motion.
   The navbar is named so it is not part of the page fade and does not flicker.
   Everything else (the root) carries the motion: the old page fades out fast,
   the new page fades in with a small rise. Pages marked body.vt-fade fade only.
   <main> is deliberately NOT named: a named element becomes the containing block
   for position:fixed descendants (theme overlay, wizard backdrops, play panels),
   which would then cover only <main> instead of the viewport.
   ══════════════════════════════════════════════════════════ */
@media (prefers-reduced-motion: no-preference) {
  @view-transition { navigation: auto; }

  .navbar { view-transition-name: navbar; }

  /* Navbar: the same bar before and after, so no animation at all. */
  ::view-transition-group(navbar),
  ::view-transition-old(navbar),
  ::view-transition-new(navbar) { animation: none; }
  ::view-transition-old(navbar) { display: none; }

  ::view-transition-old(root) {
    animation: vt-page-out 100ms ease-out both;
  }
  ::view-transition-new(root) {
    animation: vt-page-in 200ms ease-out both;
  }
  :root:has(body.vt-fade)::view-transition-new(root) {
    animation-name: vt-fade-in;
  }

  @keyframes vt-page-out { to { opacity: 0; } }
  @keyframes vt-page-in {
    from { opacity: 0; transform: translateY(8px); }
  }
  @keyframes vt-fade-in { from { opacity: 0; } }

  /* Fetched lists: fade in once, only during the entry window (see base.html). */
  html.vt-entering #char-list > *,
  html.vt-entering .lib-body > *,
  html.vt-entering #homebrew-root > *,
  html.vt-entering #campaigns-root > *,
  html.vt-entering .step-pane > * {
    animation: vt-list-in 150ms ease-out both;
  }
  @keyframes vt-list-in { from { opacity: 0; } }

  /* Wizard steps swap by display:none/block inside one page, so there is no page
     navigation to animate. @starting-style fades the pane in each time it is shown. */
  .step-pane.active {
    transition: opacity 150ms ease-out, transform 150ms ease-out;
  }
  @starting-style {
    .step-pane.active { opacity: 0; transform: translateY(6px); }
  }
}
