/* astrite.app redesign - styles
   Near-black charcoal surfaces, warm off-white text, one antique-gold accent.
   Colour beyond gold only where the data has a real category (Tide types, timeline kinds)
   or a real negative state. Every category also carries a text label or shape. */

:root {
  /* surfaces */
  --bg: #030304;            /* page */
  --panel: #0a0a0a;         /* card */
  --panel-2: #0e0e0e;       /* inset surface */
  --section: hsl(240, 7%, 5%); /* drawer sections */
  --raised: #1a1917;
  --line: rgba(255, 255, 255, 0.07);   /* card hairline (v1.3.4: softer, was 0.10) */
  --line-soft: rgba(255, 255, 255, 0.045); /* main container outline (v1.2.7: softer; v1.3.4: 0.065 -> 0.045) */
  --line-2: rgba(255, 255, 255, 0.14); /* group / control border (v1.3.4: 0.20 -> 0.14) */
  --line-3: rgba(255, 255, 255, 0.035); /* inner divider (v1.3.4: 0.05 -> 0.035) */
  /* text */
  --text: #eeeae2;
  --text-2: #c9c4b8;
  --muted: #837f78;         /* v1.2.7: a little darker (still AA on cards) */
  /* brand */
  --gold: #ba975c;                         /* --main */
  --gold-hi: #cfae72;
  --gold-lo: rgba(186, 151, 92, 0.15);     /* selected fill  (main/15) */
  --gold-line: rgba(186, 151, 92, 0.30);   /* selected edge  */
  /* semantic */
  --danger: #ff6467;
  --danger-line: rgba(255, 100, 103, 0.45);
  --danger-bg: rgba(255, 100, 103, 0.09);
  --focus: #d0b16e;
  /* live-data cues: electric cyan for "this just changed", sage for gains */
  --cyan: #5cc8e0;
  --cyan-lo: rgba(92, 200, 224, 0.12);
  --cyan-line: rgba(92, 200, 224, 0.42);
  --up: #61ba5c;
  --up-bg: rgba(97, 186, 92, 0.12);
  --up-line: rgba(97, 186, 92, 0.45);
  --glass-edge: rgba(255, 255, 255, 0.05);
  /* category colours (names kept: the JS draws the composition bar with them) */
  --lustrous: #6fa8b8;   /* Standard */
  --radiant: #d6a04f;    /* Limited Character */
  --forging: #9c8bc9;    /* Limited Weapon */
  --flex: #8fb39a;       /* Afterglow / flexible */
  /* timeline kinds: always paired with a label and a shape */
  --c-event: #6fa8b8;
  --c-banner: #d6a04f;
  --c-patch: #9c8bc9;
  --c-custom: #8fb39a;
  --c-endgame: #e0866a;

  --serif: "Iowan Old Style", "Palatino Linotype", Palatino, "Book Antiqua", Georgia, serif;
  --sans: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --r: 0;                    /* tool surfaces are square (the tiles' border light needs square corners) */
  --r-ctl: 0.375rem;         /* v1.3.4: controls (buttons, fields, tabs, chips, bars) are rounded */
  /* motion vocabulary (audit §14) */
  --dur-fast: 100ms;
  --dur-base: 200ms;
  --dur-hover: 300ms;
  --dur-media: 500ms;
  --ease-ui: ease-in-out;
  --nav-h: 5.5rem;

  /* v1.2.11 type roles: every font size in this file is one of these (the hero's display clamps excepted) */
  --fs-xs: 0.8125rem;    /* overlines, badges, table heads, tile labels (v1.3.4: one step up from 0.75) */
  --fs-sm: 0.9375rem;    /* support: hints, intros, captions, meta, footer (0.875) */
  --fs-label: 1rem;      /* field labels, buttons, tabs, choices (0.9375) */
  --fs-body: 1.0625rem;  /* reading text (1) */
  --fs-lg: 1.1875rem;    /* card and sub-section titles (1.125) */
  --fs-xl: 1.5rem;       /* panel titles (1.375) */
  --fs-data: 2rem;       /* stat figures (1.75) */
  --lh-body: 1.55;
  --measure: 65ch;       /* longest comfortable line for prose */
  /* v1.2.11 spacing scale (4px base): tight inside a group, generous between groups */
  --s-1: 0.25rem; --s-2: 0.5rem; --s-3: 0.75rem; --s-4: 1rem; --s-5: 1.25rem; --s-6: 1.5rem; --s-7: 2rem; --s-8: 2.5rem; --s-9: 3rem;
  --gap-tight: var(--s-2);    /* label to field, chips in a row */
  --gap-group: var(--s-4);    /* between controls of one group */
  --gap-section: var(--s-7);  /* between sections of a panel */
  --gap-panel: var(--s-6);    /* between panels of a view */
  --pad-panel: var(--s-7) var(--s-7);
  --pad-panel-sm: var(--s-6) var(--s-4);
  --ease: cubic-bezier(0.2, 0.7, 0.2, 1);
  --dur-state: 280ms;        /* v1.3.4: every state change (colour, fill, saturation, stripes) eases over this */
  color-scheme: dark;
}

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
/* Atmosphere at the top of the page only, masked like the audit's hero poster (32% -> 68%).
   Layer 1 (v1.2.4): the catalog's current patch splash (html.site-art-patch, --site-art set by ui.js applySiteArt).
   Darkened and softened so text stays readable; it fades in once chosen, so the wrong image never flashes. When it
   can't load (html.site-art-fallback) there is no image: the bundled key art was removed, so only the glow shows.
   Layer 2: the gold glow. If no image loads the glow still renders. */
body::before, body::after { content: ""; position: absolute; left: 0; right: 0; top: 0; height: 56rem; z-index: -1; pointer-events: none; -webkit-mask-image: linear-gradient(#000 32%, transparent 68%); mask-image: linear-gradient(#000 32%, transparent 68%); }
body::before {
  opacity: 0; filter: blur(1.5px) saturate(0.85);        /* no scale(): it would widen the page by a few px */
  transition: opacity 0.6s var(--ease);
}
html.site-art-patch body::before {
  background:
    linear-gradient(90deg, rgba(3, 3, 4, 0.15) calc(50% - 640px), rgba(3, 3, 4, 0.62) calc(50% - 470px), rgba(3, 3, 4, 0.62) calc(50% + 470px), rgba(3, 3, 4, 0.15) calc(50% + 640px)),
    linear-gradient(180deg, rgba(3, 3, 4, 0.84) 0, rgba(3, 3, 4, 0.72) 7rem, rgba(3, 3, 4, 0.48) 17rem, rgba(3, 3, 4, 0.6) 45%, var(--bg) 100%),
    var(--site-art) center 30% / cover no-repeat;
  opacity: 0.55;
}
@media (prefers-reduced-motion: reduce) { body::before { transition: none; } }
@media (forced-colors: active) { body::before { display: none; } }
body::after {
  background:
    radial-gradient(52rem 24rem at 14% -4rem, rgba(186, 151, 92, 0.16), transparent 70%),
    radial-gradient(40rem 22rem at 96% 2rem, rgba(224, 175, 242, 0.05), transparent 70%);
}
@media (max-width: 800px) {
  html.site-art-patch body::before { background: linear-gradient(180deg, rgba(3, 3, 4, 0.86) 0, rgba(3, 3, 4, 0.76) 7rem, rgba(3, 3, 4, 0.56) 17rem, rgba(3, 3, 4, 0.68) 45%, var(--bg) 100%), var(--site-art) center 30% / cover no-repeat; }
}
body {
  margin: 0;
  min-height: 100vh;
  background: var(--bg);
  color: var(--text);
  font: var(--fs-body)/var(--lh-body) var(--sans);
}
.wrap { width: min(1180px, 100% - 2rem); margin-inline: auto; }
h1, h2, h3, h4, legend, summary { text-wrap: balance; }
p, li, dd { text-wrap: pretty; }
/* the browser's own surfaces, themed from the palette */
::selection { background: rgba(186, 151, 92, 0.35); color: var(--text); }
input, textarea, select { caret-color: var(--gold-hi); }
h1, h2, h3, h4 { margin: 0; font-weight: 600; line-height: 1.25; }
p { margin: 0; }
a { color: var(--gold-hi); }
[hidden] { display: none !important; }

.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; }
.skip { position: absolute; left: 0.5rem; top: -4rem; background: var(--gold); color: #0b0a08; padding: 0.5rem 0.75rem; border-radius: var(--r); z-index: 100; font-weight: 600; }
.skip:focus { top: 0.5rem; }
:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; box-shadow: 0 0 0 5px rgba(208, 177, 110, 0.16); }

/* ---------- shared type ---------- */
.overline, .subhead {
  font: 600 var(--fs-xs)/1.3 var(--sans); letter-spacing: 0.14em; text-transform: uppercase; color: var(--muted);
}
.subhead { margin: var(--s-7) 0 var(--s-3); display: flex; align-items: center; gap: var(--s-3); }
.subhead::before { content: ""; width: 5px; height: 5px; background: var(--gold); transform: rotate(45deg); flex: none; }
.confirm .subhead { margin-top: 0; }
.subsub { font: 600 var(--fs-sm) var(--sans); color: var(--text-2); margin: 1rem 0 0.5rem; }
.hint { font-size: var(--fs-sm); line-height: 1.5; color: var(--muted); margin-top: var(--s-2); max-width: var(--measure); }
.hint.warn { color: var(--gold-hi); }
.caption { font-size: var(--fs-sm); color: var(--muted); margin-top: 1rem; }
.card-intro { color: var(--muted); font-size: var(--fs-sm); line-height: 1.55; margin: var(--s-2) 0 var(--s-6); max-width: var(--measure); }   /* v1.2.11: under the title, before any control */
.card-intro strong { color: var(--text-2); font-weight: 600; }

/* ---------- header ---------- */
.site-header { padding: 1.25rem 0 1rem; }
.header-row { display: flex; align-items: center; justify-content: space-between; gap: 1rem; }
.brand { display: flex; align-items: center; gap: 0.75rem; flex-wrap: wrap; min-width: 0; }
.site-header h1 { font: 600 var(--fs-xl)/1 var(--serif); letter-spacing: 0.04em; }
.tagline { color: var(--muted); font-size: var(--fs-sm); padding-left: 1rem; border-left: 1px solid var(--line-2); }
.version { font-size: var(--fs-sm); color: var(--muted); border: 1px solid var(--line); border-radius: var(--r); padding: 0.25rem 0.75rem; white-space: nowrap; }
/* phones: the header keeps Guide and the cache pill on one row; the version is still in the footer */
@media (max-width: 480px) { .header-meta .version { display: none; } .header-meta { flex-wrap: nowrap; gap: var(--s-2); } .header-meta .cache-pill, .header-meta .guide-btn { padding-left: var(--s-2); padding-right: var(--s-2); } }
@media (max-width: 640px) { .tagline { display: none; } }

/* ---------- navigation: boxed tab group, actions on the right, section switcher beneath ---------- */
.sidenav { position: sticky; top: 0; z-index: 30; background: rgba(6, 6, 6, 0.8); -webkit-backdrop-filter: blur(18px) saturate(1.3); backdrop-filter: blur(18px) saturate(1.3); border-bottom: 1px solid var(--line); box-shadow: 0 10px 30px -22px #000; padding: 0.75rem 0; }
.nav-inner { display: flex; flex-wrap: wrap; align-items: center; gap: 0.75rem 0.75rem; }
.tabbar {
  display: flex; gap: 2px; padding: 3px; border: 1px solid var(--line); border-radius: var(--r); background: var(--panel);
  overflow-x: auto; overscroll-behavior-x: contain; scrollbar-width: none; min-width: 0; max-width: 100%;
}
.tabbar::-webkit-scrollbar { display: none; }
.tab {
  position: relative; flex: none; min-height: 2.4rem; padding: 0 1rem; font: inherit; font-size: var(--fs-label); color: var(--muted);
  background: transparent; border: 1px solid transparent; border-radius: 3px; cursor: pointer; white-space: nowrap;
  transition: color var(--dur-base), background-color var(--dur-base), border-color var(--dur-base);
}
.tab:hover, .tab:focus-visible { color: var(--text); }
.tab[aria-selected="true"] { color: var(--gold); background: var(--gold-lo); border-color: var(--gold-line); font-weight: 600; }
.tab::after { content: none; }
.tab[aria-selected="true"]::after { content: none; }
.nav-actions { margin-left: auto; display: flex; gap: 0.5rem; }
/* v1.2.5: the Income subtabs take their own row under the tab bar and actions (keyboard order stays tabs, subtabs, actions) */
.nav-inner > .nav-actions { order: 2; }
.nav-inner > .subnav { order: 3; }
.nav-actions .btn { text-decoration: none; display: inline-flex; align-items: center; }
@media (max-width: 760px) { .nav-actions .btn:not(.primary) { display: none; } }
@media (max-width: 560px) { .nav-actions { display: none; } .tabbar { width: 100%; } }

.subnav { flex-basis: 100%; list-style: none; margin: 0; padding: 0; display: flex; gap: 0.5rem; overflow-x: auto; scrollbar-width: none; }
.subnav::-webkit-scrollbar { display: none; }
.subnav li { flex: none; }
.subnav a {
  display: block; min-height: 2rem; padding: 0.5rem 1rem; border: 1px solid var(--line); border-radius: var(--r);
  color: var(--muted); font-size: var(--fs-sm); text-decoration: none; white-space: nowrap; line-height: 1.3;
  transition: color 0.15s, border-color 0.15s, background-color 0.15s;
}
.subnav a:hover, .subnav a:focus-visible { color: var(--text); border-color: var(--line-2); }
.subnav a[aria-current="true"] { color: var(--gold); border-color: var(--gold-line); background: var(--gold-lo); }
.subnav a:focus-visible { outline-offset: 1px; }
[data-attention]:not(.subnav a)::before, .subnav a[data-attention]::after {
  content: ""; display: inline-block; width: 6px; height: 6px; margin-left: 0.5rem; border-radius: 50%; background: var(--gold-hi); vertical-align: middle;
}
.tab[data-attention]::before { margin: 0 0.5rem 0 0; }
.attn { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

/* ---------- workspace ---------- */
.workspace { padding: 1.5rem 0 4rem; outline: none; }
.view { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--gap-panel); min-width: 0; }
.view-enter { animation: rise var(--dur-hover) var(--ease) backwards; }
@keyframes rise { from { opacity: 0; transform: translateY(8px); filter: blur(5px); } }
.view > section, .assumptions > section, .results, .panel { scroll-margin-top: calc(var(--nav-h) + 0.75rem); }
.assumptions { display: grid; gap: 1rem; grid-template-columns: repeat(2, minmax(0, 1fr)); align-items: start; }
@media (max-width: 820px) { .assumptions { grid-template-columns: minmax(0, 1fr); } }
.assumptions .group-label { grid-column: 1 / -1; margin-bottom: -0.35rem; }
.assumptions > #horizon { grid-column: 1 / -1; }
.horizon-controls { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.4fr); gap: 0 var(--gap-group); align-items: start; }
.horizon-controls > .field-row { max-width: none; }
@media (max-width: 820px) { .horizon-controls { grid-template-columns: minmax(0, 1fr); } }

.panel, .results {
  position: relative; background: var(--panel); border: 1px solid var(--line-soft); border-radius: var(--r); padding: var(--pad-panel); min-width: 0;
  transition: border-color var(--dur-base);
}
.panel:focus-within { border-color: var(--line-2); }
.panel > h2 { display: flex; align-items: center; gap: var(--s-3); font: 500 var(--fs-xl)/1.25 var(--serif); letter-spacing: 0.01em; color: var(--text); }
.panel > h2::before { content: ""; width: 6px; height: 6px; background: var(--gold); transform: rotate(45deg); flex: none; }
@media (max-width: 560px) { .panel, .results { padding: var(--pad-panel-sm); } }

/* ---------- overview: balance and projection ---------- */
.results { padding: 0; display: grid; grid-template-columns: minmax(0, 1fr); gap: 0; overflow: hidden; }
.hero, .hero-top, .hero-figures, .hero-figures > * { min-width: 0; }
.hero { position: relative; padding: 1.5rem 1.5rem 1.5rem; background: linear-gradient(to right, rgba(186, 151, 92, 0.06), rgba(10, 10, 10, 0.1)); box-shadow: inset 0 1px 0 var(--gold-line); overflow: hidden; }
.hero::before, .hero::after { content: ""; position: absolute; width: 14px; height: 14px; border: 0 solid var(--gold); pointer-events: none; opacity: 0.8; }
.hero::before { top: 8px; left: 8px; border-top-width: 1px; border-left-width: 1px; }
.hero::after { bottom: 8px; right: 8px; border-bottom-width: 1px; border-right-width: 1px; }
.hero-top { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 0.75rem 1.25rem; }
.hero-top .overline { display: flex; align-items: center; gap: 0.75rem; color: var(--gold); }
.hero-top .overline::before { content: ""; width: 5px; height: 5px; background: var(--gold); transform: rotate(45deg); }

.filters { min-width: 0; }
.filter-group { display: flex; gap: 2px; padding: 3px; border: 1px solid var(--line); border-radius: var(--r); background: rgba(6, 6, 6, 0.55); overflow-x: auto; scrollbar-width: none; max-width: 100%; }
.filter-group::-webkit-scrollbar { display: none; }
.filter { position: relative; flex: none; }
.filter input { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; opacity: 0; cursor: pointer; }
.filter span { display: block; padding: 0 1rem; min-height: 2.2rem; line-height: 2.2rem; font-size: var(--fs-sm); color: var(--muted); border-radius: 3px; border: 1px solid transparent; white-space: nowrap; transition: color 0.15s, background-color 0.15s, border-color 0.15s; }
.filter input:hover + span { color: var(--text); }
.filter input:checked + span { color: var(--gold); background: var(--gold-lo); border-color: var(--gold-line); font-weight: 600; }
.filter input:focus-visible + span { outline: 2px solid var(--focus); outline-offset: 1px; }

.hero-figures { display: grid; grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr); gap: 1.5rem; align-items: end; margin-top: 1.5rem; }
.headline-number { font: 500 clamp(3.4rem, 9vw, 5.4rem)/1 var(--serif); letter-spacing: -0.01em; color: var(--text); font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
.headline-unit { font: 400 var(--fs-body) var(--sans); color: var(--muted); letter-spacing: 0; }
.headline-label { margin-top: 0.5rem; color: var(--text-2); font-size: var(--fs-label); }
.hero-projected { padding-left: 1.5rem; border-left: 1px solid var(--line-2); min-width: 0; }
.projected-number { font: 500 clamp(1.8rem, 4.4vw, 2.7rem)/1.1 var(--serif); color: var(--gold-hi); margin-top: 0.5rem; font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
@media (max-width: 640px) {
  .hero-figures { grid-template-columns: 1fr; gap: 1.25rem; }
  .hero-projected { padding: 1rem 0 0; border-left: 0; border-top: 1px solid var(--line-2); }
}

.tidebar { margin-top: 1.25rem; }
.tidebar-track { display: flex; height: 8px; background: var(--raised); border-radius: 2px; overflow: hidden; gap: 1px; }
.seg { height: 100%; min-width: 0; transition: flex-grow 0.3s var(--ease); }
.seg-standard { background: var(--lustrous); }
.seg-character { background: var(--radiant); }
.seg-weapon { background: var(--forging); }
.seg-pool { background: repeating-linear-gradient(135deg, var(--radiant) 0 5px, var(--forging) 5px 10px); }
.seg-afterglow { background: var(--flex); }

.legend { list-style: none; margin: 1rem 0 0; padding: 0; display: flex; flex-wrap: wrap; gap: 0.5rem 1.25rem; font-size: var(--fs-sm); }
.legend li { display: inline-flex; align-items: center; gap: 0.5rem; color: var(--muted); }
#legend { display: grid; grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr)); gap: 0.5rem 1.5rem; }
#legend li { padding-bottom: 0.5rem; border-bottom: 1px solid var(--line); }
#legend .count { margin-left: auto; color: var(--text); font: 500 var(--fs-label) var(--serif); font-variant-numeric: tabular-nums; }
.swatch { width: 0.7rem; height: 0.7rem; flex: none; display: inline-block; border: 2px solid currentColor; background: currentColor; }
#legend .swatch { border: 0; border-radius: 1px; width: 0.55rem; height: 0.55rem; }
.empty { margin-top: 1rem; padding: 1rem 1rem; border: 1px dashed var(--line-2); border-radius: var(--r); color: var(--muted); font-size: var(--fs-sm); }
.item-list + .empty, .btn-row + .empty { margin-top: 1rem; }

.results-grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); border-top: 1px solid var(--line); }
.results-grid > * { padding: 0.25rem 1.5rem 1.5rem; min-width: 0; }
.results-grid > .projection { border-right: 1px solid var(--line); }
@media (max-width: 860px) {
  .results-grid { grid-template-columns: 1fr; }
  .results-grid > .projection { border-right: 0; border-bottom: 1px solid var(--line); }
}
@media (max-width: 560px) { .hero, .results-grid > * { padding-left: 1rem; padding-right: 1rem; } }

.proj-list { margin: 0; }
.proj-list > div { display: flex; justify-content: space-between; gap: 1rem; padding: 0.5rem 0; border-top: 1px solid var(--line); font-size: var(--fs-sm); }
.proj-list > div:first-child { border-top: 0; }
.proj-list dt { color: var(--text-2); }
.proj-list dd { margin: 0; text-align: right; font-variant-numeric: tabular-nums; color: var(--text); }
.proj-list .sub { padding-left: 1rem; font-size: var(--fs-sm); border-left: 1px solid var(--line-2); }
.proj-list .sub dt { color: var(--muted); }

.breakdown, .notes { list-style: none; margin: 0; padding: 0; }
.breakdown li { display: grid; grid-template-columns: 1fr auto; gap: 0.1rem 1rem; padding: 0.75rem 0; border-top: 1px solid var(--line); }
.breakdown li:first-child { border-top: 0; }
.breakdown .b-label { font-size: var(--fs-label); }
.breakdown .b-value { font: 500 var(--fs-xl)/1.1 var(--serif); font-variant-numeric: tabular-nums; text-align: right; grid-row: span 2; align-self: center; color: var(--gold-hi); }
.breakdown .b-meta { font-size: var(--fs-sm); color: var(--muted); }
.breakdown .b-kind { color: var(--text-2); font-weight: 600; }
.notes { margin-top: 1rem; display: grid; gap: 0.5rem; }
.notes li { font-size: var(--fs-sm); color: var(--text-2); background: linear-gradient(90deg, rgba(186, 151, 92, 0.07), transparent 70%), var(--panel-2); border-left: 1px solid var(--gold-line); padding: var(--s-2) var(--s-3); border-radius: 0 var(--r) var(--r) 0; }
.key { margin-top: 1rem; font-size: var(--fs-sm); color: var(--muted); }
.key strong { color: var(--text-2); font-weight: 600; }

.breakdown-details { border-top: 1px solid var(--line); padding: 0 1.5rem; }
.breakdown-details summary { cursor: pointer; min-height: 3rem; display: flex; align-items: center; gap: 0.75rem; font-size: var(--fs-sm); font-weight: 600; color: var(--text-2); list-style: none; }
.breakdown-details summary::-webkit-details-marker { display: none; }
details > summary::before { content: ""; width: 0.45rem; height: 0.45rem; border-right: 2px solid var(--gold); border-bottom: 2px solid var(--gold); transform: rotate(-45deg); transition: transform 0.2s var(--ease); flex: none; }
details[open] > summary::before { transform: rotate(45deg); }
details > summary:hover { color: var(--text); }
.breakdown-details .table-wrap { margin-bottom: 1.25rem; }
@supports (interpolate-size: allow-keywords) {
  details { interpolate-size: allow-keywords; }
  /* v1.3.4: overflow hidden (not clip) contains the children's margins, so the whole height eases; with clip a child's
     margin stayed outside the animated box and dropped in one frame at the end of a close (the owner's "snap") */
  details::details-content { height: 0; overflow: hidden; transition: height 0.24s var(--ease), content-visibility 0.24s allow-discrete; }
  details[open]::details-content { height: auto; }
}
.eg-details { margin-top: 0.75rem; }
.eg-details > summary { cursor: pointer; font-weight: 600; font-size: var(--fs-sm); min-height: 2.25rem; display: flex; align-items: center; gap: 0.75rem; list-style: none; color: var(--text-2); }
.eg-details > summary::-webkit-details-marker { display: none; }

/* ---------- forms ---------- */
fieldset { border: 0; margin: 0; padding: 0; min-width: 0; }
legend { padding: 0; font-size: var(--fs-sm); font-weight: 600; color: var(--text-2); margin-bottom: 0.5rem; }
.field-row { display: grid; gap: 1rem 1.25rem; grid-template-columns: repeat(auto-fit, minmax(9.5rem, 1fr)); }
.field-row.two { grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr)); }
.field { min-width: 0; margin-bottom: 0.5rem; }
.field label, .counter > label { display: block; font-size: var(--fs-label); font-weight: 600; color: var(--text-2); margin-bottom: var(--gap-tight); }

input[type="text"], input[type="date"], input[type="time"], select, textarea {
  width: 100%; min-height: 2.5rem; padding: 0.5rem 0.75rem; font: inherit; color: var(--text); background: #080808;
  border: 1px solid var(--line-2); border-radius: var(--r); font-variant-numeric: tabular-nums;
  transition: border-color 0.15s, background-color 0.15s, box-shadow 0.15s;
}
input[type="date"], input[type="time"] { color-scheme: dark; }
input:hover, select:hover, textarea:hover { border-color: #4a463c; }
input:focus-visible, select:focus-visible, textarea:focus-visible { outline: none; border-color: var(--gold); box-shadow: 0 0 0 2px var(--gold-lo), 0 0 0 1px var(--gold); }
input[aria-invalid="true"] { border-color: var(--danger); background: var(--danger-bg); }
textarea { min-height: 6rem; font: var(--fs-sm)/1.45 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; resize: vertical; word-break: break-all; }
.field-error { font-size: var(--fs-sm); color: var(--danger); margin-top: 0.5rem; }
.tone-radiant label, .tone-forging label, .tone-lustrous label { padding-left: 0.75rem; border-left: 3px solid; }
.tone-radiant label { border-color: var(--radiant); }
.tone-forging label { border-color: var(--forging); }
.tone-lustrous label { border-color: var(--lustrous); }

.toggle { position: relative; display: flex; align-items: center; gap: 0.75rem; margin: 1rem 0 0.5rem; cursor: pointer; min-height: 2.5rem; max-width: 100%; }
.toggle input { position: absolute; opacity: 0; inset: 0; width: 100%; height: 100%; margin: 0; cursor: pointer; }
.toggle-track { width: 2.6rem; height: 1.45rem; border-radius: 999px; background: var(--raised); border: 1px solid var(--line-2); position: relative; flex: none; transition: background-color 0.18s, border-color 0.18s; }
.toggle-track::after { content: ""; position: absolute; top: 2px; left: 2px; width: 1.05rem; height: 1.05rem; border-radius: 50%; background: var(--muted); transition: transform 0.2s var(--ease), background-color 0.18s; }
.toggle input:checked ~ .toggle-track { background: var(--gold); border-color: var(--gold); }
.toggle input:checked ~ .toggle-track::after { transform: translateX(1.15rem); background: #0b0a08; }
.toggle input:focus-visible ~ .toggle-track { outline: 2px solid var(--focus); outline-offset: 2px; }
.toggle-text { font-size: var(--fs-label); font-weight: 600; color: var(--text-2); }
.toggle:hover .toggle-text { color: var(--text); }

.choice { margin-top: 1rem; }
.choice-group { display: flex; flex-wrap: wrap; gap: 0.5rem; }
.choice-item { position: relative; display: inline-block; }
.choice-item input { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; opacity: 0; cursor: pointer; }
.choice-item span { display: block; padding: 0.5rem 1rem; min-height: 2.3rem; line-height: 1.5rem; font-size: var(--fs-sm); border: 1px solid var(--line-2); border-radius: var(--r); background: var(--panel-2); color: var(--text-2); transition: color 0.15s, border-color 0.15s, background-color 0.15s; }
.choice-item input:hover:not(:disabled):not(:checked) + span { border-color: #5a554a; color: var(--text); }
.choice-item input:checked + span { color: var(--gold); background: var(--gold-lo); border-color: var(--gold-line); font-weight: 600; }
.choice-item input:focus-visible + span { outline: 2px solid var(--focus); outline-offset: 2px; }
.choice-item input:disabled + span { opacity: 0.45; cursor: not-allowed; }
.check { display: inline-flex; align-items: center; gap: 0.75rem; min-height: 2.3rem; cursor: pointer; font-size: var(--fs-label); margin: 0.1rem 1rem 0.1rem 0; color: var(--text-2); }
.check input { width: 1.1rem; height: 1.1rem; accent-color: var(--gold); flex: none; }

.summary { margin-top: var(--s-4); font-size: var(--fs-sm); line-height: 1.55; padding: var(--s-3) var(--s-4); background: linear-gradient(90deg, rgba(186, 151, 92, 0.07), transparent 70%), var(--panel-2); border: 1px solid var(--line); border-left-color: var(--gold-line); border-radius: var(--r); color: var(--text-2); }
.summary:empty { display: none; }
.summary + .field, .summary + .field-row, .summary + .choice, .summary + fieldset { margin-top: var(--s-6); }
.panel > .field, .panel > .field-row, .subpanel > .field, .subpanel > .field-row { max-width: 40rem; }
.panel > .field-row.two { max-width: 40rem; }

.counters { display: grid; gap: 1rem 1.25rem; grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr)); }
.stepper { display: grid; grid-template-columns: 2.5rem minmax(0, 1fr) 2.5rem; gap: 0.5rem; }
.stepper input { text-align: center; }
.stepper button { min-height: 2.5rem; border-radius: var(--r); border: 1px solid var(--line-2); background: var(--panel-2); color: var(--text); font: inherit; font-size: var(--fs-lg); cursor: pointer; transition: border-color 0.15s, color 0.15s, background-color 0.15s; }
.stepper button:hover, .stepper button:focus-visible { border-color: var(--gold); color: var(--gold-hi); }
.stepper button:active { background: var(--raised); }

/* ---------- stat tiles: label over figure, note close by ---------- */
.stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(10.5rem, 1fr)); gap: 0.75rem; margin: 1.25rem 0 0; }
.stats > div { position: relative; display: flex; flex-direction: column; background: var(--panel); border: 1px solid var(--line-soft); border-radius: var(--r); padding: 1rem 1rem 1rem; min-width: 0; }
.stats dt { font: 600 var(--fs-xs)/1.35 var(--sans); letter-spacing: 0.12em; text-transform: uppercase; color: var(--muted); min-height: 1.8em; flex: 1 0 auto; }   /* grows, so every number in a row sits on the same line however its label wraps */
.stats dd { margin: 0.5rem 0 0; font: 500 var(--fs-data)/1.1 var(--serif); color: var(--text); font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
.stats .strong { border-color: var(--gold-line); background: linear-gradient(to right, rgba(186, 151, 92, 0.05), var(--panel)); }
.stats .strong dd { color: var(--gold-hi); }
.stats dd.stat-text { font-size: var(--fs-xl); line-height: 1.3; }   /* a sentence-like value ("0 Astrite (0 days)") instead of one number */

/* ---------- buttons and messages ---------- */
.btn-row { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 1rem; }
.btn-row.tight { margin-top: 0.5rem; }
.btn {
  min-height: 2.5rem; padding: 0.5rem 1rem; border-radius: var(--r); border: 1px solid var(--line-2); background: var(--panel-2);
  color: var(--text); font: inherit; font-size: var(--fs-label); font-weight: 600; cursor: pointer;
  transition: background-color var(--dur-base), border-color var(--dur-base), color var(--dur-base), box-shadow var(--dur-base), transform var(--dur-fast);
}
.btn:hover:not(:disabled), .btn:focus-visible { border-color: var(--line-2); background: rgba(255, 255, 255, 0.08); color: var(--text); }
.btn:active:not(:disabled) { transform: translateY(1px); }
.btn.primary { background: var(--gold); border-color: transparent; color: #000; box-shadow: 0 0 16px rgba(186, 151, 92, 0.2); }
.btn.primary:hover:not(:disabled), .btn.primary:focus-visible { background: rgba(186, 151, 92, 0.9); border-color: transparent; color: #000; box-shadow: 0 0 24px rgba(186, 151, 92, 0.35); }
.btn.small { min-height: 2.1rem; padding: 0.25rem 0.75rem; font-size: var(--fs-sm); }
.btn.danger { border-color: var(--danger-line); color: var(--danger); background: transparent; }
.btn.danger:hover:not(:disabled), .btn.danger:focus-visible { background: var(--danger-bg); border-color: var(--danger); color: var(--danger); }
.btn:disabled { opacity: 0.45; cursor: not-allowed; }

.msg { margin-top: 1rem; padding: 0.75rem 1rem; border-radius: var(--r); font-size: var(--fs-sm); border: 1px solid var(--line); border-left: 1px solid var(--muted); background: linear-gradient(90deg, rgba(255, 255, 255, 0.03), transparent 70%), var(--panel-2); animation: fade 0.2s ease; }
@keyframes fade { from { opacity: 0; } }
.msg-ok { border-left-color: var(--gold); }
.msg-error { border-left-color: var(--danger); background: var(--danger-bg); }
.msg-info { border-left-color: var(--lustrous); }
/* v1.2.9: results of card actions (Events, Timeline, Endgame) float as a toast, outside the layout, so no card moves.
   Under the sticky bar on the right; full width minus the gutters on phones. Hidden again after a few seconds. */
.msg.toast {
  position: fixed; z-index: 60; top: calc(var(--nav-h) + 0.75rem); right: 1rem; margin: 0;
  width: min(26rem, calc(100% - 2rem)); background: var(--raised); box-shadow: 0 12px 32px -12px #000;
}
.msg-error.toast { background: #2a1416; }
/* v1.2.10: frosted, and it arrives / leaves with a soft blur instead of snapping */
.msg.toast { background: rgba(26, 25, 23, 0.84); -webkit-backdrop-filter: blur(14px) saturate(1.2); backdrop-filter: blur(14px) saturate(1.2); }
.msg-error.toast { background: rgba(42, 20, 22, 0.88); }
.msg.toast.toast-in { animation: toast-in 420ms var(--ease) both; }
.msg.toast.toast-out { animation: toast-out 340ms var(--ease) both; }
@keyframes toast-in { from { opacity: 0; transform: translateY(-10px) scale(0.98); filter: blur(6px); } to { opacity: 1; transform: none; filter: none; } }
@keyframes toast-out { to { opacity: 0; transform: translateY(-8px) scale(0.98); filter: blur(6px); } }
/* v1.2.9: a card's confirmation opens inside the card, under its actions */
.confirm.confirm-in-card { margin-top: 1rem; }
.review { margin-top: 0.75rem; padding: 0.75rem 1rem; border: 1px dashed var(--gold-line); border-radius: var(--r); background: var(--panel-2); font-size: var(--fs-sm); }

/* inline confirmation panels */
.confirm { margin-top: 1rem; padding: 1rem 1.25rem; border: 1px solid var(--gold-line); border-left: 1px solid var(--gold); border-radius: var(--r); background: linear-gradient(90deg, rgba(186, 151, 92, 0.07), transparent 70%), var(--panel-2); animation: fade 0.2s ease; }
.confirm p + p { margin-top: 0.5rem; }
.confirm textarea, .confirm input { max-width: 100%; }
.confirm .field { margin-bottom: 0.75rem; }
.kv { margin: 0.75rem 0 0; display: grid; gap: 0.5rem; }
.kv div { display: grid; grid-template-columns: minmax(7rem, 11rem) 1fr; gap: 0.5rem; font-size: var(--fs-sm); }
.kv dt { color: var(--muted); }
.kv dd { margin: 0; overflow-wrap: anywhere; }

/* ---------- tables ---------- */
.table-wrap { overflow-x: auto; margin-top: 0.75rem; -webkit-overflow-scrolling: touch; }
.preview-table { width: 100%; border-collapse: collapse; font-size: var(--fs-sm); }
.preview-table th, .preview-table td { padding: 0.75rem 0.75rem; border-top: 1px solid var(--line); text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.preview-table thead th { color: var(--muted); font: 600 var(--fs-xs)/1.3 var(--sans); letter-spacing: 0.1em; text-transform: uppercase; border-top: 0; border-bottom: 1px solid var(--line-2); white-space: normal; vertical-align: bottom; }
.preview-table th[scope="row"], .preview-table thead th:first-child { text-align: left; font-weight: 500; color: var(--text-2); }
.preview-table tbody tr:last-child { font-weight: 700; background: var(--gold-lo); }
.preview-table tbody tr:last-child th { color: var(--gold-hi); }
.pulls-row th, .pulls-row td { font-weight: 700; border-top: 1px solid var(--gold-line); }
.breakdown-table { font-size: var(--fs-sm); }
.breakdown-table th, .breakdown-table td { padding: 0.5rem 0.75rem; }
.event-table input, .editor-table input { min-height: 2.1rem; padding: 0.25rem 0.5rem; text-align: right; }
.editor-table td { padding: 0.25rem 0.5rem; }
.event-table th, .event-table td { padding: 0.5rem 0.5rem; }
/* equal columns, so every event card's Maximum / Collected / Credited / Outstanding line up down the list (phones use tiles) */
@media (min-width: 561px) { .event-table { table-layout: fixed; } }

/* ---------- lists: events, endgames, timeline ---------- */
.item-list { list-style: none; margin: 1rem 0 0; padding: 0; display: grid; gap: 0.75rem; }
.item { padding: 1rem 1.25rem; border: 1px solid var(--line-soft); border-left-width: 3px; border-radius: var(--r); background: var(--panel-2); min-width: 0; transition: border-color 0.18s, background-color 0.18s, transform 0.18s var(--ease-ui); }
.item:hover, .item:focus-within { background: #161614; border-top-color: var(--line-2); border-right-color: var(--line-2); border-bottom-color: var(--line-2); transform: translateY(-1px); }
.item-selected { border-color: var(--gold-line); background: rgba(186, 151, 92, 0.05); box-shadow: inset 3px 0 0 var(--gold); }
.item-head { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem 0.75rem; }
.item-head h3 { font: 500 var(--fs-lg) var(--serif); margin-right: 0.25rem; overflow-wrap: anywhere; }
.item > p { margin-top: 0.5rem; font-size: var(--fs-sm); color: var(--text-2); }
/* v1.2.6: the projection line is supporting text: muted and a step smaller, with its label kept legible */
.item > p.item-proj { font-size: var(--fs-sm); color: var(--muted); }
.item > p.item-proj strong { color: var(--text-2); font-weight: 600; }
.item.has-art > p.item-proj { color: var(--text-2); }   /* brighter over card art */
.eg-help { margin: 0 0 0.75rem; }
.eg-help > summary { min-height: 2.25rem; font-size: var(--fs-sm); }
.eg-help .notes { margin: 0.25rem 0 0.75rem; font-size: var(--fs-sm); color: var(--muted); }
.badge { display: inline-block; padding: 0.08rem 0.5rem; border-radius: 2px; font: 600 var(--fs-xs)/1.6 var(--sans); letter-spacing: 0.07em; text-transform: uppercase; border: 1px solid var(--line-2); color: var(--text-2); }
.badge-ongoing { border-color: var(--gold-line); color: var(--gold-hi); background: var(--gold-lo); }
.badge-upcoming { border-color: var(--lustrous); color: var(--lustrous); }
.badge-completed { border-color: var(--flex); color: var(--flex); }
.badge-expired, .badge-ended { border-style: dashed; color: var(--muted); }
.badge-warn { border-color: var(--danger-line); color: var(--danger); }
.badge-deadline { background: var(--gold); color: #0b0a08; border-color: var(--gold); }
.badge-kind { border-style: dashed; }

.item-event { border-left-color: var(--c-event); }
.item-banner { border-left-color: var(--c-banner); }
.item-patch { border-left-color: var(--c-patch); }
.item-custom { border-left-color: var(--c-custom); }
.item-endgame { border-left-color: var(--c-endgame); }
.item-event .badge-kind { border-style: solid; border-color: var(--c-event); color: var(--c-event); }
.item-banner .badge-kind { border-style: solid; border-color: var(--c-banner); color: var(--c-banner); }
.item-patch .badge-kind { border-style: solid; border-color: var(--c-patch); color: var(--c-patch); }
.item-custom .badge-kind { border-style: solid; border-color: var(--c-custom); color: var(--c-custom); }
.item-endgame .badge-kind { border-style: solid; border-color: var(--c-endgame); color: var(--c-endgame); }
.swatch-event { color: var(--c-event); border-radius: 50%; }
.swatch-banner { color: var(--c-banner); border-radius: 1px; }
.swatch-patch { color: var(--c-patch); transform: rotate(45deg); border-radius: 1px; }
.swatch-custom { color: var(--c-custom); border-radius: 1px; background: transparent; }
.swatch-endgame { color: var(--c-endgame); border-radius: 50% 50% 1px 1px; }

.eg-cycle { margin-top: 0.75rem; }
.eg-cycle-title { font: 500 var(--fs-body) var(--serif); margin: 0 0 0.5rem; }
.eg-assume { display: grid; gap: 0.5rem; margin-top: 0.75rem; }
.eg-prompt { margin-top: 1rem; border-color: var(--danger-line); border-left-color: var(--c-endgame); }
.subpanel { margin: 0.5rem 0; padding: 0.75rem; border: 1px solid var(--line-soft); border-radius: var(--r); }
.import-list { list-style: none; padding: 0; margin: 0.75rem 0 0; display: grid; gap: 0.75rem; }
.import-entry { padding: 0.75rem; border: 1px solid var(--line); border-radius: var(--r); background: var(--panel); }
.import-entry select { margin-top: 0.5rem; }
.import-entry label { display: block; font-size: var(--fs-sm); margin-top: 0.5rem; color: var(--muted); }

/* ---------- drawer: editors and import panels slide in from the right ---------- */
.drawer-backdrop { position: fixed; inset: 0; z-index: 50; background: rgba(0, 0, 0, 0.34); animation: fade var(--dur-fast) ease; }
.confirm.drawer {
  position: fixed; top: 0; right: 0; bottom: 0; z-index: 60; width: min(36rem, 100%); margin: 0; padding: 1.25rem 1.5rem 2rem;
  border: 0; border-left: 1px solid var(--gold-line); border-radius: 0; background: rgba(3, 3, 4, 0.92); -webkit-backdrop-filter: blur(40px); backdrop-filter: blur(40px); overflow-y: auto; overscroll-behavior: contain;
  animation: drawer-in var(--dur-base) var(--ease-ui);
}
@keyframes drawer-in { from { transform: translateX(2.5rem); opacity: 0; } }
.confirm.drawer.drawer-closing { animation: drawer-out var(--dur-base) var(--ease-ui) forwards; pointer-events: none; }
@keyframes drawer-out { to { transform: translateX(2.5rem); opacity: 0; } }
.drawer-close { display: block; margin: 0 0 1rem auto; min-height: 2.1rem; padding: 0.25rem 1rem; background: transparent; color: var(--text-2); border: 1px solid var(--line-2); border-radius: var(--r); font: inherit; font-size: var(--fs-sm); font-weight: 600; cursor: pointer; transition: border-color 0.15s, color 0.15s; }
.drawer-close:hover, .drawer-close:focus-visible { border-color: var(--gold-line); color: var(--text); }
body.drawer-open { overflow: hidden; }
.confirm.drawer > .subhead { margin: 0 0 1rem; font-size: var(--fs-sm); color: var(--gold); }

/* ---------- footer ---------- */
.site-footer { border-top: 1px solid var(--line); padding: var(--s-7) 0 var(--s-7); color: var(--muted); font-size: var(--fs-sm); line-height: 1.55; }
.site-footer p { max-width: 80ch; }
/* footer: disclaimer, copyright, links to Privacy / Terms / contact */
.footer-body { display: grid; gap: 0.5rem; }
.footer-meta .footer-version { margin-left: 0.5rem; padding-left: 0.75rem; border-left: 1px solid var(--line-2); white-space: nowrap; }
.footer-links { display: flex; flex-wrap: wrap; gap: 0.5rem 1.25rem; margin-top: 0.15rem; }
.footer-links a { color: var(--text-2); text-decoration: none; overflow-wrap: anywhere; }
.footer-links a:hover, .footer-links a:focus-visible { color: var(--gold-hi); text-decoration: underline; }

/* ---- standalone document pages (privacy.html, terms.html): no game art, readable measure ---- */
.doc-header { padding: 1.25rem 0 1rem; border-bottom: 1px solid var(--line); }
.doc-header .header-row { flex-wrap: wrap; }
.doc-home { display: inline-flex; align-items: center; gap: 0.5rem; color: var(--text-2); text-decoration: none; font-size: var(--fs-sm); }
.doc-home:hover, .doc-home:focus-visible { color: var(--gold-hi); }
.doc { max-width: 70ch; padding: var(--s-8) 0 var(--s-9); }
.doc h1 { font: 500 clamp(1.9rem, 4vw, 2.25rem)/1.15 var(--serif); letter-spacing: 0.01em; margin-bottom: var(--s-2); }
.doc .doc-updated { color: var(--muted); font-size: var(--fs-sm); margin-bottom: 1.5rem; }
.doc h2 { font: 500 var(--fs-xl)/1.3 var(--serif); margin: var(--s-8) 0 var(--s-3); color: var(--text); }
.doc p, .doc li { color: var(--text-2); line-height: 1.7; }
.doc p + p { margin-top: 0.75rem; }
.doc ul { margin: 0.5rem 0 0; padding-left: 1.25rem; }
.doc li + li { margin-top: 0.5rem; }
.doc ul + p { margin-top: 0.75rem; }
.doc code { font-size: 0.9em; color: var(--text); overflow-wrap: anywhere; }
.doc .doc-note { margin-top: var(--s-4); padding: var(--s-3) var(--s-4); border: 1px solid var(--line-soft); border-left-color: var(--gold-line); background: linear-gradient(90deg, rgba(186, 151, 92, 0.07), transparent 70%), var(--panel-2); }
.doc table { width: 100%; border-collapse: collapse; margin-top: 0.75rem; font-size: var(--fs-label); }
.doc th, .doc td { text-align: left; padding: 0.5rem 0.75rem 0.5rem 0; border-top: 1px solid var(--line); color: var(--text-2); vertical-align: top; }
.doc th { color: var(--text); font-weight: 600; white-space: nowrap; }
@media (max-width: 560px) { .doc th { white-space: normal; } .doc { padding-top: 1.5rem; } }

@media (max-width: 420px) { #legend { grid-template-columns: 1fr; } .kv div { grid-template-columns: 1fr; } }

/* ---------- v1.2.11 layout groups ---------- */
/* Timeline: sort and Show filters form one band; each filter carries its type's colour */
.tl-controls { display: flex; flex-wrap: wrap; align-items: flex-end; gap: var(--s-4) var(--s-7); }
.tl-controls > .sort-control { flex: 0 1 20rem; margin-bottom: 0; }
.tl-controls > .tl-filters { flex: 1 1 24rem; margin-top: 0; }
.tl-filters .check { margin-right: var(--s-4); }
@media (max-width: 560px) { .tl-filters .choice-group { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 var(--s-3); } .tl-filters .check { margin: 0; } .tl-filters .check:last-child:nth-child(odd) { grid-column: 1 / -1; } }
.tl-filters .check .swatch { width: 0.6rem; height: 0.6rem; border: 0; }
.tl-filters .check .swatch-custom { border: 1.5px solid currentColor; }
.tl-controls + .btn-row { margin-top: var(--s-6); }
/* a note right under a row of buttons sits a step away from them */
.btn-row + .hint { margin-top: var(--s-3); }
/* Save & Load: the savecode box uses the panel's width; Save and Patch content are separate groups */
#savecode > .field { max-width: none; }
#savecode > .btn-row:has(#btn-patch-load) { margin-top: var(--gap-section); padding-top: var(--gap-section); border-top: 1px solid var(--line); }


/* ---------- motion preferences ---------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; scroll-behavior: auto !important; }
}

/* ======================= summary strip ======================= */
.sum-strip { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 0.75rem; margin-top: 1.5rem; }
.sum-tile { position: relative; padding: 1rem 1rem 1rem; min-width: 0; border: 1px solid var(--line-soft); border-radius: var(--r); background: var(--panel); transition: border-color var(--dur-hover); }
.sum-tile::before { content: ""; position: absolute; left: 0; top: 0.8rem; bottom: 0.8rem; width: 2px; background: var(--line-2); }
.sum-tile.is-up::before { background: var(--up); box-shadow: 0 0 10px var(--up); }
.sum-val { font: 600 clamp(1.5rem, 3.6vw, 2.15rem)/1.1 var(--serif); margin-top: 0.5rem; font-variant-numeric: tabular-nums; color: var(--text); overflow-wrap: anywhere; }
.sum-tile.is-up .sum-val { color: var(--up); }
.sum-date { font-size: clamp(1.05rem, 2.3vw, 1.4rem); letter-spacing: 0.02em; padding-top: 0.5rem; }
.sum-tile .hint { margin-top: 0.5rem; }
@media (max-width: 560px) { .sum-strip { grid-template-columns: repeat(2, minmax(0, 1fr)); } .sum-tile:first-child { grid-column: 1 / -1; } }

/* ======================= live change chips ======================= */
.headline, .hero-projected { position: relative; }
.delta { position: absolute; top: 0.6rem; right: 0.6rem; z-index: 2; pointer-events: none; padding: 0.5rem 0.5rem; border: 1px solid; border-radius: 3px; font: 700 var(--fs-sm)/1 var(--sans); letter-spacing: 0.02em; font-variant-numeric: tabular-nums; white-space: nowrap; animation: delta-pop 2.4s var(--ease) both;}
.headline > .delta { top: -1.55rem; left: 0; right: auto; }
.hero-projected > .delta { top: -1.55rem; left: 1.5rem; right: auto; }
@media (max-width: 640px) { .hero-projected > .delta { left: 0; } }
.delta-up { color: var(--up); background: var(--up-bg); border-color: var(--up-line); }
.delta-down { color: var(--danger); background: var(--danger-bg); border-color: var(--danger-line); }
.delta-up::before { content: "\25B2"; font-size: 0.55rem; margin-right: 0.5rem; vertical-align: 0.1em; }
.delta-down::before { content: "\25BC"; font-size: 0.55rem; margin-right: 0.5rem; vertical-align: 0.1em; }
@keyframes delta-pop { 0% { opacity: 0; transform: translateY(8px) scale(0.96); } 10% { opacity: 1; transform: none; } 78% { opacity: 1; } 100% { opacity: 0; transform: translateY(-4px); } }
.tick { animation: tick 0.8s ease-out; }
@keyframes tick { from { color: var(--cyan); text-shadow: 0 0 18px rgba(92, 200, 224, 0.55); } }
.number-tick { animation: number-flash 0.8s ease-out; }
@keyframes number-flash { from { color: var(--gold-hi); text-shadow: 0 0 12px var(--gold-line); } }

/* ======================= adjust: live preview ======================= */
.delta-preview { display: grid; grid-template-columns: auto minmax(0, 1fr); column-gap: 0.75rem; row-gap: 0.5rem; align-items: center; max-width: 40rem; margin-top: 1rem; padding: 0.75rem 1rem; border: 1px solid var(--line); border-left-color: var(--cyan-line); border-radius: var(--r); background: linear-gradient(90deg, var(--cyan-lo), transparent 60%), var(--panel-2); animation: fade 0.2s ease; }
.delta-preview > .cur { grid-row: span 2; align-self: start; }
.dp-row { display: flex; align-items: center; gap: 0.75rem; font-size: var(--fs-sm); font-variant-numeric: tabular-nums; min-width: 0; }
.dp-op { min-width: 4.6rem; color: var(--muted); font-weight: 600; }
.dp-from { color: var(--muted); }
.dp-arrow { color: var(--cyan); }
.dp-to { font: 500 var(--fs-lg)/1 var(--serif); color: var(--text); }
.dp-blocked .dp-to { font: 600 var(--fs-sm) var(--sans); color: var(--danger); }
.dp-blocked .delta { opacity: 0.45; }
.delta-inline { position: static; margin-left: auto; animation: none; }

/* ======================= currency badges ======================= */
.cur { --c: var(--muted); --c-bg: rgba(143, 139, 131, 0.12); --c-bd: rgba(143, 139, 131, 0.4); position: relative; display: inline-grid; place-items: center; width: 1.6rem; height: 1.6rem; margin-right: 0.5rem; flex: none; vertical-align: middle; border: 1px solid var(--c-bd); border-radius: 4px; background: var(--c-bg); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.07), 0 0 14px -8px var(--c); }
.cur-ico { display: block; width: 0.78rem; height: 0.78rem; background: var(--c); }
.delta-preview > .cur { margin-right: 0; width: 1.8rem; height: 1.8rem; }
.cur-cell { display: inline-flex; align-items: center; }
.cur-astrite { --c: #8fd3ec; --c-bg: rgba(143, 211, 236, 0.12); --c-bd: rgba(143, 211, 236, 0.42); }
.cur-astrite .cur-ico { clip-path: polygon(50% 0, 61% 39%, 100% 50%, 61% 61%, 50% 100%, 39% 61%, 0 50%, 39% 39%); }
.cur-lunite { --c: #cfd6ea; --c-bg: rgba(207, 214, 234, 0.1); --c-bd: rgba(207, 214, 234, 0.4); }
.cur-lunite .cur-ico { clip-path: polygon(25% 0, 75% 0, 100% 38%, 50% 100%, 0 38%); }
.cur-radiant { --c: var(--radiant); --c-bg: rgba(214, 160, 79, 0.13); --c-bd: rgba(214, 160, 79, 0.45); }
.cur-radiant .cur-ico { border-radius: 50%; background: radial-gradient(circle, var(--c) 0 28%, transparent 30% 52%, var(--c) 54%); }
.cur-forging { --c: var(--forging); --c-bg: rgba(156, 139, 201, 0.13); --c-bd: rgba(156, 139, 201, 0.45); }
.cur-forging .cur-ico { clip-path: polygon(25% 4%, 75% 4%, 100% 50%, 75% 96%, 25% 96%, 0 50%); }
.cur-lustrous { --c: var(--lustrous); --c-bg: rgba(111, 168, 184, 0.13); --c-bd: rgba(111, 168, 184, 0.45); }
.cur-lustrous .cur-ico { clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%, 50% 22%, 78% 50%, 50% 78%, 22% 50%, 50% 22%); }
.cur-afterglow { --c: var(--flex); --c-bg: rgba(143, 179, 154, 0.12); --c-bd: rgba(143, 179, 154, 0.42); }
.cur-afterglow .cur-ico { background: radial-gradient(circle at 30% 32%, var(--c) 0 21%, transparent 23%), radial-gradient(circle at 70% 32%, var(--c) 0 21%, transparent 23%), radial-gradient(circle at 50% 72%, var(--c) 0 25%, transparent 27%); }
.cur-oscillated { --c: #7fb8b0; --c-bg: rgba(127, 184, 176, 0.12); --c-bd: rgba(127, 184, 176, 0.42); }
.cur-oscillated .cur-ico { border-radius: 60% 0 60% 0; transform: rotate(-8deg); }

/* ======================= timeline and event cards ======================= */
.item.has-date { display: grid; grid-template-columns: auto minmax(0, 1fr); column-gap: 1rem; align-items: start; }
.item.has-date > .item-date { grid-column: 1; grid-row: 1 / span 8; }
.item.has-date > :not(.item-date) { grid-column: 2; min-width: 0; }
.item-date { display: flex; flex-direction: column; align-items: center; justify-content: center; width: 3.7rem; padding: 0.5rem 0.25rem 0.5rem; border: 1px solid var(--line-2); border-top: 2px solid var(--gold); border-radius: var(--r); background: linear-gradient(180deg, #1c1b18, var(--panel)); box-shadow: inset 0 1px 0 var(--glass-edge); line-height: 1.1; }
.item-date-m { font: 600 var(--fs-xs) var(--sans); letter-spacing: 0.14em; text-transform: uppercase; color: var(--gold); }
.item-date-d { font: 500 var(--fs-data)/1.15 var(--serif); color: var(--text); font-variant-numeric: tabular-nums; }
.item-date-y { font: 500 var(--fs-xs) var(--sans); color: var(--muted); letter-spacing: 0.06em; }
.item-event > .item-date { border-top-color: var(--c-event); }
.item-banner > .item-date { border-top-color: var(--c-banner); }
.item-patch > .item-date { border-top-color: var(--c-patch); }
.item-custom > .item-date { border-top-color: var(--c-custom); }
.item-endgame > .item-date { border-top-color: var(--c-endgame); }
.badge-kind::before { content: ""; display: inline-block; width: 0.42rem; height: 0.42rem; margin-right: 0.5rem; background: currentColor; vertical-align: 0.05em; }
.item-event .badge-kind::before { border-radius: 50%; }
.item-patch .badge-kind::before { transform: rotate(45deg); }
.item-custom .badge-kind::before { background: transparent; border: 1.5px solid currentColor; }
.item-endgame .badge-kind::before { border-radius: 50% 50% 1px 1px; }
.item-patch .badge-kind { background: rgba(156, 139, 201, 0.1); box-shadow: 0 0 14px -6px var(--c-patch); }
.item-banner .badge-kind { background: rgba(214, 160, 79, 0.1); }
.badge-deadline { box-shadow: 0 0 14px -4px var(--gold); }
@media (max-width: 560px) {
  .item.has-date { grid-template-columns: auto minmax(0, 1fr); column-gap: 0.75rem; } .item-date { width: 3.1rem; } .item-date-d { font-size: var(--fs-xl); }
  .item.has-date > .item-date { grid-row: 1 / span 2; }
  .item.has-date > :not(.item-date):not(.item-head):not(.item-dates):not(.item-art) { grid-column: 1 / -1; }
}

/* ======================= small screens: tables become bento cards ======================= */
@media (max-width: 700px) {
  .table-wrap { overflow: visible; }
  .preview-table, .preview-table tbody { display: block; }
  .preview-table thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
  .preview-table tr { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.5rem; margin-top: 0.75rem; padding: 0.75rem; border: 1px solid var(--line); border-radius: var(--r); background: linear-gradient(180deg, rgba(255, 255, 255, 0.035), rgba(255, 255, 255, 0.008)); box-shadow: inset 0 1px 0 var(--glass-edge); }
  .preview-table th, .preview-table td { border-top: 0; }
  .preview-table tbody th { grid-column: 1 / -1; display: block; padding: 0 0 0.5rem; border-bottom: 1px solid var(--line); text-align: left; white-space: normal; }
  .preview-table td { display: flex; flex-direction: column; gap: 0.25rem; min-width: 0; padding: 0.5rem 0.75rem; border: 1px solid var(--line); border-radius: 3px; background: rgba(0, 0, 0, 0.25); text-align: left; white-space: normal; font-size: var(--fs-body); color: var(--text); }
  .preview-table td[data-label]::before { content: attr(data-label); font: 600 var(--fs-xs)/1.3 var(--sans); letter-spacing: 0.1em; text-transform: uppercase; color: var(--muted); }
  .preview-table td[data-empty] { display: none; }
  .preview-table td:last-child { grid-column: 1 / -1; border-color: var(--gold-line); background: linear-gradient(90deg, var(--gold-lo), rgba(0, 0, 0, 0.25)); }
  .preview-table td:last-child::before { color: var(--gold); }
  .preview-table td:last-child { font: 500 var(--fs-xl)/1.15 var(--serif); font-variant-numeric: tabular-nums; }
  .preview-table tbody tr:last-child { background: linear-gradient(180deg, var(--gold-lo), rgba(255, 255, 255, 0.01)); border-color: var(--gold-line); }
  /* v1.3.5: a row with only Before and After: both full width, so "2,280 (38 days)" stays on one line */
  .preview-table tr:has(> td:nth-of-type(2):last-child) > td { grid-column: 1 / -1; }
  .editor-table td input, .event-table td input { width: 100%; text-align: left; }
  .breakdown-table { font-size: var(--fs-label); }
}
@media (max-width: 560px) {
  .stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .stats > div:last-child:nth-child(odd) { grid-column: 1 / -1; }
  .stats dd { font-size: var(--fs-data); }
  .field-row, .field-row.two, .counters { grid-template-columns: minmax(0, 1fr); }
}

/* the change chip should stay visible (not animate) when motion is reduced */
@media (prefers-reduced-motion: reduce) { .delta { animation: none; } .tick, .number-tick { animation: none; } .item:hover, .item:focus-within { transform: none; } }

/* ======================= audit: serif tabular numerals for data ======================= */
.preview-table td, .proj-list dd, .kv dd, .dp-from, .badge-deadline, .breakdown .b-value { font-family: var(--serif); font-variant-numeric: tabular-nums; }
.preview-table td { font-size: var(--fs-label); }
input[data-kind="count"], input[data-kind="optcount"] { font-family: var(--serif); text-align: right; }
.stepper input[data-kind="count"] { text-align: center; }

/* =====================================================================================
   Motion and animated graphics
   Vocabulary from the audit: 100 / 200 / 300 / 500 ms, 2px lift, 1px press, small amplitudes,
   one looping graphic at most, everything gated by prefers-reduced-motion (see the end).
   ===================================================================================== */

/* ---- brand (v1.1.4; re-measured v1.1.5): assets/brand/astrite-logo.png, cropped to its artwork box ----
   The file is a 1920x1080 canvas whose artwork (icon + "astrite.app") is the 1361x319 box at (279, 386).
   The h1 is that box at a fixed height; the image is scaled and offset inside it, so its 16:9 ratio is kept. */
.brand-logo { position: relative; height: 1.75rem; aspect-ratio: 1361 / 319; overflow: hidden; flex: none; }
.brand-logo img { position: absolute; max-width: none; width: 141.073%; height: 338.558%; left: -20.500%; top: -121.003%; }
.doc-header .brand-logo { display: block; }   /* privacy.html / terms.html: the logo is a link home */
@keyframes pop { from { transform: scale(0); } }

/* ---- navigation: one indicator glides between tabs; a hairline tracks page scroll ---- */
.tabbar { position: relative; }
.tab-slider { position: absolute; left: 0; bottom: 3px; height: 2px; z-index: 1; pointer-events: none; background: var(--gold); box-shadow: 0 0 10px rgba(186, 151, 92, 0.7); clip-path: inset(0 0.7rem); transition: transform var(--dur-hover) var(--ease), width var(--dur-hover) var(--ease); }
.tab-slider.no-anim { transition: none; }
.scroll-progress { position: absolute; left: 0; right: 0; bottom: -1px; height: 2px; background: var(--gold); transform-origin: left; transform: scaleX(0); pointer-events: none; opacity: 0.85; }

/* ---- view entrance: cards rise in turn (children of the view, then tiles inside them) ---- */
.view.stagger > * { animation: rise var(--dur-media) var(--ease) backwards; animation-delay: calc(var(--n, 0) * 70ms); }
.view.stagger > :nth-child(2) { --n: 1; } .view.stagger > :nth-child(3) { --n: 2; } .view.stagger > :nth-child(4) { --n: 3; } .view.stagger > :nth-child(5) { --n: 4; }
.view.stagger .sum-tile, .view.stagger .stats > div, .view.stagger .item-list > .item, .view.stagger .legend li { animation: rise 420ms var(--ease) backwards; animation-delay: calc(160ms + var(--n, 0) * 55ms); }
.view.stagger .sum-tile:nth-child(2), .view.stagger .stats > div:nth-child(2), .view.stagger .item-list > .item:nth-child(2), .view.stagger .legend li:nth-child(2) { --n: 1; }
.view.stagger .sum-tile:nth-child(3), .view.stagger .stats > div:nth-child(3), .view.stagger .item-list > .item:nth-child(3), .view.stagger .legend li:nth-child(3) { --n: 2; }
.view.stagger .stats > div:nth-child(4), .view.stagger .item-list > .item:nth-child(4), .view.stagger .legend li:nth-child(4) { --n: 3; }
.view.stagger .stats > div:nth-child(5), .view.stagger .item-list > .item:nth-child(5) { --n: 4; }
.view.stagger .panel > h2::before, .view.stagger .hero-top .overline::before { animation: pop 420ms var(--ease) 200ms backwards; }

/* ---- hero graphic: slow orbital rings behind the figures (the one ambient loop) ---- */
.hero > *:not(.hero-orbit) { position: relative; z-index: 1; }
.hero-orbit { position: absolute; right: -5.5rem; top: -7rem; z-index: 0; width: 28rem; height: 28rem; pointer-events: none; opacity: 0.55; fill: none; stroke: var(--gold); stroke-width: 0.6; -webkit-mask-image: radial-gradient(closest-side, #000 50%, transparent 100%); mask-image: radial-gradient(closest-side, #000 50%, transparent 100%); animation: fade 900ms ease backwards; }
.orb { transform-box: fill-box; transform-origin: center; }
.orb-a { animation: spin 140s linear infinite; }
.orb-b { animation: spin 90s linear infinite reverse; }
.orb-c { animation: spin 200s linear infinite; }
.hero-orbit .ticks { stroke-dasharray: 1 7; stroke-width: 3; opacity: 0.7; }
.hero-orbit .ticks.fine { stroke-dasharray: 0.6 3.4; stroke-width: 2; }
.hero-orbit .arc { stroke-width: 1.4; opacity: 0.9; }
.hero-orbit .node { fill: var(--gold); stroke: none; }
.orb-cross { stroke-width: 0.4; opacity: 0.45; }
@keyframes spin { to { transform: rotate(360deg); } }
@media (max-width: 640px) { .hero-orbit { width: 19rem; height: 19rem; right: -6.5rem; top: -4.5rem; opacity: 0.4; } }

/* ---- live data: figures roll in, the tide bar eases and is swept by a single highlight ---- */
#result-value { display: inline-block; }
.tick { animation: roll var(--dur-hover) var(--ease) both; }
@keyframes roll { from { opacity: 0.2; transform: translateY(0.2em); color: var(--cyan); text-shadow: 0 0 18px rgba(92, 200, 224, 0.5); } }
.seg { transition: flex-grow var(--dur-media) var(--ease); }
.tidebar { position: relative; overflow: hidden; }
.tidebar::after { content: ""; position: absolute; inset: 0; pointer-events: none; opacity: 0; background: linear-gradient(100deg, transparent 30%, rgba(255, 255, 255, 0.5) 50%, transparent 70%); transform: translateX(-100%); }
.tidebar.sweep::after { animation: sweep 800ms var(--ease-ui); }
@keyframes sweep { 0% { transform: translateX(-100%); opacity: 1; } 100% { transform: translateX(100%); opacity: 1; } }
.sum-tile::before { transform: scaleY(0.35); transform-origin: bottom; transition: transform var(--dur-hover) var(--ease), background-color var(--dur-hover), box-shadow var(--dur-hover); }
.sum-tile.is-up::before { transform: scaleY(1); }
.sum-tile .overline { display: flex; align-items: center; gap: 0.5rem; }
.ico { width: 0.95rem; height: 0.95rem; flex: none; fill: none; stroke: var(--gold); stroke-width: 2; stroke-linecap: square; stroke-linejoin: miter; }

/* ---- feedback: messages and confirmations slide in; attention dots ping three times ---- */
.msg, .confirm:not(.drawer) { animation: msg-in var(--dur-base) var(--ease-ui); }
@keyframes msg-in { from { opacity: 0; transform: translateY(-4px); } }
.subnav a[data-attention]::after, .tab[data-attention]::before { animation: ping 1.4s ease-out 3; }
@keyframes ping { 0% { box-shadow: 0 0 0 0 rgba(207, 174, 114, 0.6); } 100% { box-shadow: 0 0 0 7px rgba(207, 174, 114, 0); } }

/* ---- hover: icons turn a little, rows brighten (kept small, as in the reference) ---- */
.cur-ico { transition: transform var(--dur-hover) var(--ease); }
.field:hover .cur-ico, .counter:hover .cur-ico, .cur-cell:hover .cur-ico { transform: rotate(14deg) scale(1.12); }
.proj-list > div, .breakdown li, .legend li { transition: background-color var(--dur-base); }
.proj-list > div:hover, .breakdown li:hover { background: rgba(255, 255, 255, 0.02); }
.preview-table tbody tr { transition: background-color var(--dur-base); }
.preview-table tbody tr:hover { background: rgba(255, 255, 255, 0.02); }
.item { transition: border-color var(--dur-hover), background-color var(--dur-hover); }

/* ---- reduced motion: no looping graphics, no travel; state changes still read ---- */
@media (prefers-reduced-motion: reduce) {
  .orb, .tidebar.sweep::after { animation: none !important; }
  .tab-slider, .seg, .sum-tile::before { transition: none; }
}

/* =====================================================================================
   v1.1: claim status, composition, icons, scroll cues, finer interaction feedback
   ===================================================================================== */

/* ---- no visible scrollbars (and so no sideways jump when one appears); scrolling is unchanged ---- */
html { scrollbar-width: none; -ms-overflow-style: none; }
html::-webkit-scrollbar { width: 0; height: 0; display: none; }
.table-wrap, .drawer, .tabbar, .subnav, .filter-group { scrollbar-width: none; -ms-overflow-style: none; }
.table-wrap::-webkit-scrollbar, .drawer::-webkit-scrollbar, .filter-group::-webkit-scrollbar { display: none; width: 0; height: 0; }

/* The nav is sticky: keep focused fields, confirmations and anchors from landing underneath it. */
html { scroll-padding-top: calc(var(--nav-h) + 0.75rem); }
.confirm { scroll-margin-top: calc(var(--nav-h) + 0.75rem); }

/* ---- scroll-edge fades: shown only on the side that still has more content (set by ui-polish.js) ---- */
[data-fade="x"].fade-start:not(.fade-end) { -webkit-mask-image: linear-gradient(90deg, transparent, #000 1.6rem); mask-image: linear-gradient(90deg, transparent, #000 1.6rem); }
[data-fade="x"].fade-end:not(.fade-start) { -webkit-mask-image: linear-gradient(270deg, transparent, #000 1.6rem); mask-image: linear-gradient(270deg, transparent, #000 1.6rem); }
[data-fade="x"].fade-start.fade-end { -webkit-mask-image: linear-gradient(90deg, transparent, #000 1.6rem, #000 calc(100% - 1.6rem), transparent); mask-image: linear-gradient(90deg, transparent, #000 1.6rem, #000 calc(100% - 1.6rem), transparent); }
[data-fade="y"].fade-start:not(.fade-end) { -webkit-mask-image: linear-gradient(180deg, transparent, #000 1.6rem); mask-image: linear-gradient(180deg, transparent, #000 1.6rem); }
[data-fade="y"].fade-end:not(.fade-start) { -webkit-mask-image: linear-gradient(0deg, transparent, #000 2rem); mask-image: linear-gradient(0deg, transparent, #000 2rem); }
[data-fade="y"].fade-start.fade-end { -webkit-mask-image: linear-gradient(180deg, transparent, #000 1.6rem, #000 calc(100% - 2rem), transparent); mask-image: linear-gradient(180deg, transparent, #000 1.6rem, #000 calc(100% - 2rem), transparent); }

/* ---- claim cards (today's daily, this week's cycle): the status is read from the real state ---- */
.claim-card { position: relative; overflow: hidden; display: grid; grid-template-columns: auto minmax(0, 1fr) auto; gap: 0.5rem 1rem; align-items: center; margin: 1rem 0 1.25rem; padding: 1rem 1rem; border: 1px solid var(--line-soft); background: var(--panel-2); transition: border-color var(--dur-hover), background-color var(--dur-hover); }
.claim-card[data-state="counted"] { border-color: var(--gold-line); background: linear-gradient(90deg, var(--gold-lo), var(--panel-2) 75%); }
.claim-card[data-state="sync-first"] { border-style: dashed; border-color: var(--gold-line); }
.claim-card[data-state="unavailable"], .claim-card[data-state="past-deadline"] { opacity: 0.85; }
.claim-body { min-width: 0; }
.claim-body .overline { display: flex; flex-wrap: wrap; gap: 0 0.5rem; }
.claim-date { color: var(--muted); letter-spacing: 0.06em; text-transform: none; font-weight: 500; }
.claim-state { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem 0.75rem; margin-top: 0.5rem; font-size: var(--fs-label); color: var(--text); }
.claim-card .hint { margin-top: 0.5rem; }
.claim-chip { display: inline-block; padding: 0.12rem 0.75rem; border: 1px solid var(--line-2); font: 600 var(--fs-xs)/1.6 var(--sans); letter-spacing: 0.1em; text-transform: uppercase; color: var(--text-2); transition: color var(--dur-hover), background-color var(--dur-hover), border-color var(--dur-hover); }
.claim-card[data-state="counted"] .claim-chip { color: var(--gold); background: var(--gold-lo); border-color: var(--gold-line); }
.claim-card[data-state="sync-first"] .claim-chip { border-style: dashed; border-color: var(--gold-line); color: var(--gold-hi); }
.claim-card[data-state="unavailable"] .claim-chip, .claim-card[data-state="past-deadline"] .claim-chip { color: var(--muted); }
.claim-badge { width: 2.5rem; height: 2.5rem; }
.claim-badge svg { width: 100%; height: 100%; fill: none; stroke: var(--muted); stroke-width: 1.5; stroke-linecap: square; }
.cb-ring { stroke-dasharray: 3 3.2; transition: stroke var(--dur-hover), stroke-dasharray var(--dur-hover); }
.cb-check { stroke: var(--gold); stroke-dasharray: 1; stroke-dashoffset: 1; transition: stroke-dashoffset 450ms var(--ease) 100ms; }
.cb-dash { stroke-dasharray: 1; stroke-dashoffset: 0; transition: opacity var(--dur-base); }
.claim-card[data-state="counted"] .cb-ring { stroke: var(--gold); stroke-dasharray: 63 0; }
.claim-card[data-state="counted"] .cb-check { stroke-dashoffset: 0; }
.claim-card[data-state="counted"] .cb-dash { opacity: 0; }
.claim-card[data-state="sync-first"] .cb-ring { stroke: var(--gold-hi); }
.claim-card[data-state="sync-first"] .cb-dash { stroke: var(--gold-hi); }
/* The shine exists only while .claim-flash is set (JS removes it on animationend). It runs once, ends fully transparent and
   keeps that end state (fill-mode both), so it can never snap back to the centre of the card. */
.claim-card.claim-flash::after { content: ""; position: absolute; inset: 0; pointer-events: none; opacity: 0; background: linear-gradient(100deg, transparent 30%, rgba(186, 151, 92, 0.3) 50%, transparent 70%); animation: claim-shine 900ms var(--ease-ui) both; }
@keyframes claim-shine { 0% { transform: translateX(-100%); opacity: 1; } 85% { opacity: 1; } 100% { transform: translateX(100%); opacity: 0; } }
.claim-action .btn { white-space: nowrap; }
@media (max-width: 560px) {
  .claim-card { grid-template-columns: auto minmax(0, 1fr); }
  .claim-action { grid-column: 1 / -1; }
  .claim-action .btn { width: 100%; }
}

/* ---- composition: scope label and percentages ---- */
.comp-head { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 0.25rem 1rem; margin-top: 1.25rem; }
.comp-scope { color: var(--gold); }
.tidebar { margin-top: 0.75rem; }
#legend li { gap: 0.5rem; }
#legend .pct { min-width: 3.5rem; text-align: right; color: var(--muted); font: 500 var(--fs-sm) var(--serif); font-variant-numeric: tabular-nums; }
#legend .cur { width: 1.35rem; height: 1.35rem; margin-right: 0; }
.seg { transition: flex-grow var(--dur-media) var(--ease), filter var(--dur-base); }
.seg:hover { filter: brightness(1.18); }

/* ---- supplied currency icons ---- */
.cur .cur-img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; filter: drop-shadow(0 1px 3px rgba(0, 0, 0, 0.55)); transition: transform var(--dur-hover) var(--ease); }
.cur.has-img { border-color: transparent; background: transparent; box-shadow: none; }
.cur.has-img .cur-ico { visibility: hidden; }   /* v1.2.9: keeps the same box, so a loading icon never changes the row height */
.field:hover .cur-img, .counter:hover .cur-img, .cur-cell:hover .cur-img { transform: scale(1.14) rotate(-4deg); }
.h-icons { display: inline-flex; align-items: center; gap: 0.1rem; margin-left: 0.5rem; }
.h-icons .cur { width: 1.75rem; height: 1.75rem; margin-right: 0; }
.empty-icons { display: flex; gap: 0.1rem; margin-bottom: 0.75rem; }
.empty-icons .cur { width: 2.4rem; height: 2.4rem; margin-right: 0; }
.field label .cur, .counter > label .cur { margin-right: 0.5rem; margin-top: -0.2rem; margin-bottom: -0.2rem; }
.delta-preview > .cur { width: 2.2rem; height: 2.2rem; }

/* ---- selection highlight that glides between the "Show pulls for" options ---- */
.filter-group { position: relative; }
.pill-slider { position: absolute; left: 0; top: 0; z-index: 0; pointer-events: none; background: var(--gold-lo); border: 1px solid var(--gold-line); transition: transform var(--dur-hover) var(--ease), width var(--dur-hover) var(--ease), height var(--dur-hover) var(--ease); }
.pill-slider.no-anim { transition: none; }
.filter-group.has-slider .filter { z-index: 1; }
.filter-group.has-slider .filter input:checked + span { background: transparent; border-color: transparent; }

/* ---- Endstate reset option ---- */
.reset-option { margin: 1rem 0 0.25rem; padding: 0.75rem 1rem; border: 1px dashed var(--gold-line); background: var(--panel); }

/* ---- pressed and focus feedback ---- */
.btn:active:not(:disabled) { transform: translateY(1px) scale(0.985); }
.tab:active, .subnav a:active, .drawer-close:active { transform: scale(0.97); }
.filter input:active + span, .choice-item input:active + span { transform: scale(0.97); }
.stepper button:active { transform: scale(0.94); }
/* v1.3.4: no press stretch on the switch thumb (owner: the circle turned oval) */
.filter span, .choice-item span { transition: color var(--dur-base), background-color var(--dur-base), border-color var(--dur-base), transform var(--dur-fast); }
.btn, .tab, .subnav a, .drawer-close, .stepper button {
  outline: 2px solid transparent; outline-offset: 6px;
  transition: background-color var(--dur-base), border-color var(--dur-base), color var(--dur-base), box-shadow var(--dur-base), transform var(--dur-fast), outline-color var(--dur-fast), outline-offset var(--dur-base) var(--ease);
}
.btn:focus-visible, .tab:focus-visible, .subnav a:focus-visible, .drawer-close:focus-visible, .stepper button:focus-visible { outline-color: var(--focus); outline-offset: 2px; }

@media (prefers-reduced-motion: reduce) {
  .pill-slider, .cb-check, .cb-ring { transition: none; }
  .claim-card.claim-flash::after { display: none; }
}

/* =====================================================================================================
   v1.1.2: three-stage projection, single-page Balances / Income, floating counter, card and button effects
   ===================================================================================================== */
.subpanel, .panel { scroll-margin-top: calc(var(--nav-h) + 0.75rem); }
.inline-link { color: var(--gold-hi); text-decoration: underline; text-underline-offset: 0.2em; margin-left: 0.5rem; }
.inline-link:hover, .inline-link:focus-visible { color: var(--text); }
.field-row.three { grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr)); }
.panel.group > .subpanel { margin: var(--gap-section) 0 0; padding: var(--gap-section) 0 0; border: 0; border-top: 1px solid var(--line); border-radius: 0; background: none; }
.panel.group > .subpanel > .subhead:first-child { margin-top: 0; }
.subpanel > .card-intro { margin-top: 0; }
.compact-details { margin: 1rem 0 0; border: 1px solid var(--line-soft); border-radius: var(--r); background: var(--panel); padding: 0 1rem; }
.compact-details summary { cursor: pointer; min-height: 2.5rem; display: flex; align-items: center; gap: 0.75rem; font-size: var(--fs-sm); font-weight: 600; color: var(--text-2); }
.compact-details[open] { padding-bottom: 1rem; }

/* ---- Overview: Initial / Current / Forecast ---- */
.results > .projection { padding: 0.25rem 1.5rem 0.5rem; border-top: 1px solid var(--line); }
@media (max-width: 560px) { .results > .projection { padding-left: 1rem; padding-right: 1rem; } }
.stage-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 1rem; margin-top: 0.75rem; }
@media (max-width: 1060px) { .stage-grid { grid-template-columns: minmax(0, 1fr); } }
.stage { position: relative; min-width: 0; padding: 1rem 1rem 1.25rem; border: 1px solid var(--line-soft); border-radius: var(--r); background: var(--panel); }
.stage-forecast { border-color: var(--gold-line); background: linear-gradient(180deg, rgba(186, 151, 92, 0.06), var(--panel) 55%); }
.stage-head { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: end; gap: 0.1rem 1rem; }
.stage-head .overline { grid-column: 1 / -1; }
.stage-head h4 { font: 500 var(--fs-xl)/1.2 var(--serif); color: var(--text); }
.stage-pulls { position: relative; text-align: right; color: var(--muted); font-size: var(--fs-sm); }
.stage-pulls strong { font: 500 var(--fs-data)/1 var(--serif); color: var(--gold-hi); font-variant-numeric: tabular-nums; }
.cur-grid { list-style: none; margin: var(--s-6) 0 0; padding: 0; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s-4) var(--s-2); }   /* row gap holds the change chips */
@media (max-width: 1060px) and (min-width: 561px) { .cur-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
@media (max-width: 460px) { .cur-grid { grid-template-columns: minmax(0, 1fr); } }
.cur-tile { position: relative; display: flex; align-items: center; gap: 0.5rem; min-width: 0; padding: 0.5rem 0.75rem; border: 1px solid var(--line); border-radius: var(--r); background: var(--panel-2); }
.cur-tile .cur { flex: none; width: 1.6rem; height: 1.6rem; margin: 0; }
.cur-tile .ct-text { display: flex; flex-direction: column; min-width: 0; flex: 1; }
.ct-name { font: 500 var(--fs-xs)/1.3 var(--sans); letter-spacing: 0.01em; color: var(--muted); overflow-wrap: anywhere; }
.ct-amt { font: 500 var(--fs-body)/1.2 var(--serif); color: var(--text); font-variant-numeric: tabular-nums; }
.cur-tile.is-zero .ct-amt { color: var(--muted); }
.ct-chg { flex: none; font: 700 var(--fs-xs)/1 var(--sans); font-variant-numeric: tabular-nums; color: var(--muted); }
.ct-chg.up { color: var(--up); } .ct-chg.down { color: var(--danger); }
.src-head { margin-top: 1rem; }
.src-list { list-style: none; margin: 0.5rem 0 0; padding: 0; display: grid; gap: 0.25rem; }
.src-list li { display: flex; justify-content: space-between; gap: 1rem; padding: 0.5rem 0; border-bottom: 1px solid var(--line); font-size: var(--fs-sm); }
.src-list li:last-child { border-bottom: 0; }
.src-name { color: var(--text-2); } .src-val { text-align: right; color: var(--text); font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
.src-manual .src-name, .src-assumed .src-name { color: var(--gold); }
.src-list .src-empty { color: var(--muted); display: block; }
.stage-key { margin-top: 1rem; }
/* delta chips sit on the tile they belong to */
/* v1.2.11: the chip sits in the gap above its tile (only touching the top edge), never over the tile's name or amount */
.cur-tile > .delta { top: auto; bottom: calc(100% - 0.375rem); right: var(--s-2); padding: 0.125rem 0.375rem; font-size: var(--fs-xs); }
.stage-pulls > .delta { top: -1.4rem; right: 0; left: auto; }

/* ---- first-time / revisit setup ---- */
.accounting-setup { margin: 0 0 0.25rem; }
.setup-head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 0.5rem; }
.accounting-setup.is-quiet { padding: 0.5rem 1rem; background: transparent; border-style: dashed; }
.accounting-setup.is-quiet .setup-head { align-items: center; }
.accounting-setup.is-quiet #accounting-setup-kicker { margin: 0; }
#accounting-setup-kicker { display: inline-block; margin-bottom: var(--s-2); padding: 0.125rem var(--s-2); border: 1px solid var(--gold-line); color: var(--gold-hi); background: var(--gold-lo); letter-spacing: 0.1em; }
#accounting-setup-kicker + .subhead { margin-top: 0; }
.claim-setup { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 0.75rem; }
.claim-setup .btn[aria-pressed="true"], .claim-setup .btn.is-on { border-color: var(--gold); background: var(--gold-lo); color: var(--gold-hi); }
.sync-source-fields { max-width: 44rem; }

/* ---- floating pull counter ---- */
.float-count {
  position: fixed; left: 50%; bottom: calc(0.9rem + env(safe-area-inset-bottom, 0px)); z-index: 18;
  display: inline-flex; align-items: baseline; gap: 0.5rem; padding: 0.5rem 1rem; max-width: calc(100vw - 1.5rem); white-space: nowrap;
  border: 1px solid var(--gold-line); border-radius: 999px; color: var(--muted); font: 600 var(--fs-xs) var(--sans); letter-spacing: 0.08em; text-transform: uppercase; cursor: pointer;
  background: rgba(10, 10, 9, 0.82); -webkit-backdrop-filter: blur(14px) saturate(1.3); backdrop-filter: blur(14px) saturate(1.3);
  box-shadow: 0 6px 24px rgba(0, 0, 0, 0.45), 0 0 18px rgba(186, 151, 92, 0.12);
  opacity: 0; visibility: hidden; pointer-events: none; transform: translate(-50%, 14px);
  transition: opacity var(--dur-hover) var(--ease), transform var(--dur-hover) var(--ease), visibility 0s linear var(--dur-hover);
}
.float-count.is-in { opacity: 1; visibility: visible; pointer-events: auto; transform: translate(-50%, 0); transition-delay: 0s; }
.float-count .fc-value { font: 500 var(--fs-xl)/1 var(--serif); color: var(--gold-hi); font-variant-numeric: tabular-nums; letter-spacing: 0; text-transform: none; }
.float-count .fc-unit { letter-spacing: 0.06em; }
.float-count:hover, .float-count:focus-visible { border-color: var(--gold); }
body.drawer-open .float-count { opacity: 0; visibility: hidden; pointer-events: none; }
.site-footer { padding-bottom: 4.5rem; }

/* ---- card hover: tilt + glow (js/ui-fx.js toggles .fx-hover and sets --rx --ry --gx --gy) ---- */
.sum-tile, .stage, .item-list > .item { transform-origin: 50% 50%; }
.sum-tile::after, .stage::after, .item-list > .item::after {
  content: ""; position: absolute; inset: 0; border-radius: inherit; pointer-events: none; opacity: 0; transition: opacity var(--dur-hover) var(--ease);
  background:
    linear-gradient(115deg, transparent calc(var(--gx, 50%) - 30%), rgba(236, 214, 160, 0.07) var(--gx, 50%), transparent calc(var(--gx, 50%) + 30%));
}
.item-list > .item { position: relative; }
/* v1.1.7: the tilt is written only by ui-fx.js's easing loop, so .fx-tilt has NO transform transition (a CSS transition
   would compete with the per-frame values and cause lag or a snap). .fx-hover only switches the light on. */
.fx-hover { transition: border-color var(--dur-hover), background-color var(--dur-hover); z-index: 1; }
.fx-hover::after { opacity: 1; }
.fx-tilt, .item-list > .item.fx-tilt { transform: perspective(900px) rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg)); z-index: 1; }   /* replaces the older 1px lift */
@media (hover: none), (pointer: coarse) { .fx-tilt, .item-list > .item.fx-tilt { transform: none; } .fx-hover::after { opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .fx-tilt, .item-list > .item.fx-tilt { transform: none !important; } }

/* ---- selective button shine (hover/focus only, one pass, primary actions) ---- */
.btn.shine { position: relative; overflow: hidden; }
.btn.shine::after { content: ""; position: absolute; inset: 0; pointer-events: none; opacity: 0; transform: translateX(-120%); background: linear-gradient(105deg, transparent 35%, rgba(255, 255, 255, 0.38) 50%, transparent 65%); }
.btn.shine:hover:not(:disabled)::after, .btn.shine:focus-visible::after { opacity: 1; transform: translateX(120%); transition: transform 650ms var(--ease), opacity 120ms; }
@media (prefers-reduced-motion: reduce) { .btn.shine::after { display: none; } }
.btn:hover:not(:disabled) { transform: translateY(-1px); }
.btn:active:not(:disabled) { transform: translateY(1px) scale(0.985); }

/* ---- text entrance: brief blur-to-sharp for headings and intros, small stagger ---- */
.view.stagger .panel > h2, .view.stagger .stage-head h4, .view.stagger .card-intro { animation: text-rise 480ms var(--ease) backwards; animation-delay: 90ms; }
.view.stagger .stage:nth-child(2) { --n: 1; } .view.stagger .stage:nth-child(3) { --n: 2; }
.view.stagger .stage { animation: rise 460ms var(--ease) backwards; animation-delay: calc(140ms + var(--n, 0) * 70ms); }
@keyframes text-rise { from { opacity: 0; filter: blur(4px); transform: translateY(4px); } }
@media (prefers-reduced-motion: reduce) { .view.stagger .stage, .view.stagger .panel > h2, .view.stagger .card-intro { animation: none; } }
.panel > h2 + .field-row { margin-top: 1rem; }

/* v1.1.8: projection assumptions as toggle buttons (the allocation picker's choice-item pills, as checkboxes) */
.assume-toggles { margin-top: 0.75rem; }
.eg-assume.assume-toggles { display: flex; }   /* row of pills like the event buttons (overrides the old checkbox grid) */
.assume-toggles .choice-item span { font-size: var(--fs-sm); }
.assume-toggles .choice-item[hidden] { display: none; }
.assume-hint { margin-top: 0.5rem; }

/* =====================================================================================
   v1.1.8 permanent events: limited and permanent rewards as two sections. After the event ends the limited
   section is greyed and hatched (no longer obtainable); the permanent section stays fully active.
   ===================================================================================== */
.event-cats { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.75rem; margin-top: 0.75rem; }
@media (max-width: 1100px) { .event-cats { grid-template-columns: minmax(0, 1fr); } }
/* compact cells so all five columns fit inside a half-width section */
.event-cat .event-table th, .event-cat .event-table td { padding: 0.5rem 0.5rem; }
.event-cat .preview-table thead th { letter-spacing: 0.05em; }
.event-cat { min-width: 0; padding: 0.75rem 0.75rem 0.75rem; border: 1px solid var(--line-soft); background: var(--panel); }
.event-cat-permanent { border-color: var(--gold-line); }
.event-cat-head { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 0.25rem 1rem; }
.event-cat-head h4 { font: 600 var(--fs-xs) var(--sans); letter-spacing: 0.12em; text-transform: uppercase; color: var(--text-2); }
.event-cat-state { font-size: var(--fs-sm); color: var(--muted); }
.event-cat .table-wrap { margin-top: 0.5rem; }
.event-cat.is-expired {   /* v1.2.3: red hatch, matching ended cards; the table stays readable on a solid surface */
  color: var(--muted); border-style: dashed; border-color: var(--danger-line);
  background: repeating-linear-gradient(135deg, rgba(255, 100, 103, 0.09) 0 6px, transparent 6px 12px), var(--panel);
}
.event-cat.is-expired .event-cat-state { color: var(--danger); font-weight: 600; }
.event-cat.is-expired .table-wrap { background: var(--panel); }
.event-cat.is-expired table, .event-cat.is-expired .event-cat-head h4 { opacity: 0.75; }
.event-cat.is-completed .event-cat-state { color: var(--gold); }
.badge-permanent { border-color: var(--gold-line); color: var(--gold-hi); }
@media (forced-colors: active) { .event-cat.is-expired { background: Canvas; } }

/* =====================================================================================
   v1.1.8 dropdowns: native <select> in the site's style (CSS only; the real element stays for keyboard, screen
   readers, phone pickers and data-bind). Closed control everywhere; the open list too where the browser supports
   customizable select (appearance: base-select); elsewhere the dark native list is used.
   ===================================================================================== */
select {
  -webkit-appearance: none; appearance: none; cursor: pointer; padding-right: 2.5rem; text-overflow: ellipsis;
  /* gold chevron from two small gradients (no image) */
  background-image: linear-gradient(45deg, transparent 50%, var(--gold) 50%), linear-gradient(135deg, var(--gold) 50%, transparent 50%);
  background-position: calc(100% - 1.15rem) 52%, calc(100% - 0.8rem) 52%;
  background-size: 0.36rem 0.36rem, 0.36rem 0.36rem;
  background-repeat: no-repeat;
}
select:disabled { opacity: 0.5; cursor: not-allowed; }
select option { background: var(--panel-2); color: var(--text); }   /* honoured by the native list in some browsers */

@supports (appearance: base-select) {
  select, ::picker(select) { appearance: base-select; }
  select { display: flex; align-items: center; }
  select::picker-icon { display: none; }                                /* the gold chevron above is the only arrow */
  select:open {
    border-color: var(--gold-line);
    background-image: linear-gradient(45deg, transparent 50%, var(--gold-hi) 50%), linear-gradient(135deg, var(--gold-hi) 50%, transparent 50%);
  }
  ::picker(select) {
    /* open below the field and flip above only when the list doesn't fit. The browser default
       (position-try-order: most-block-size, plus a height that stretches to the space) opened it on whichever side
       had more room, often above with plenty of space below. A fixed max height makes "fits" mean the real list. */
    position-area: bottom span-right; position-try-fallbacks: flip-block; position-try-order: normal;
    max-block-size: 20rem; overflow-y: auto;
    /* v1.2.11: exactly the field's width. It used to grow to its longest option (timeline names in Deadline source),
       sticking out past the field and, on phones, past the screen. */
    box-sizing: border-box; inline-size: anchor-size(inline); min-inline-size: 0; max-inline-size: calc(100vw - 1rem); overflow-x: hidden;
    margin-top: 4px; padding: 0.5rem; border: 1px solid var(--line-2); border-radius: var(--r);
    background: var(--panel-2); color: var(--text-2); box-shadow: 0 14px 34px rgba(0, 0, 0, 0.6);
    /* v1.2.4: an explicit closed state. Closing used to keep the list fully visible for the whole display/overlay
       window and then drop it; now it fades out at once (90 ms, ease-in) and ignores the pointer while it does, so it
       never blocks the control underneath. Opening eases in over 140 ms. The new state's duration applies, so the
       variables below pick the open or close timing; reduced motion turns both off. */
    --pk-dur: 90ms; --pk-ease: cubic-bezier(0.4, 0, 1, 1);
    opacity: 0; translate: 0 -4px; pointer-events: none;
    transition: opacity var(--pk-dur) var(--pk-ease), translate var(--pk-dur) var(--pk-ease), overlay var(--pk-dur) allow-discrete, display var(--pk-dur) allow-discrete;
  }
  ::picker(select):popover-open { --pk-dur: 140ms; --pk-ease: var(--ease-ui); opacity: 1; translate: 0 0; pointer-events: auto; }
  @starting-style { ::picker(select):popover-open { opacity: 0; translate: 0 -4px; } }
  select option {
    display: flex; align-items: center; gap: 0.75rem; min-height: 2.2rem; padding: 0.5rem 0.75rem; white-space: normal; overflow-wrap: anywhere;
    font-size: var(--fs-label); color: var(--text-2); background: transparent; border: 1px solid transparent; cursor: pointer;
  }
  select option:hover, select option:focus-visible { background: rgba(255, 255, 255, 0.06); color: var(--text); outline: none; }
  select option:checked { color: var(--gold); background: var(--gold-lo); border-color: var(--gold-line); font-weight: 600; }
  select option::checkmark { color: var(--gold); }
  select option:disabled { opacity: 0.45; cursor: not-allowed; }
  /* v1.3.2: the chosen text is one line (never a taller field); it ends with an ellipsis and glides while hovered or
     focused (ui.js kit.marquee). The face is the select's own: no box of its own. */
  select > button.select-face { all: unset; display: flex; align-items: center; flex: 1 1 auto; min-width: 0; overflow: hidden; }
  select > button.select-face > selectedcontent { display: block; flex: 1 1 auto; min-width: 0; }
}
/* one-line text that glides through what doesn't fit (any .mq, and dropdowns' chosen text) */
.mq, select selectedcontent { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
/* v1.3.5: while it glides, the text moves with a transform (smooth, no re-layout) inside a box that clips it; the box's
   edges fade softly. A dropdown's chosen text moves inside its button. */
.mq.mq-on, select selectedcontent.mq-on { text-overflow: clip; }
select selectedcontent.mq-run { overflow: visible; }
.mq-in { display: inline-block; white-space: nowrap; }
.mq-clip { overflow: hidden;
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 var(--s-3), #000 calc(100% - var(--s-3)), transparent 100%);
  mask-image: linear-gradient(90deg, transparent 0, #000 var(--s-3), #000 calc(100% - var(--s-3)), transparent 100%); }
.mq-run { animation: mq-glide var(--mq-dur, 4s) var(--ease-ui) 0.35s 2 alternate both; will-change: transform; }
@keyframes mq-glide { 0%, 14% { transform: translateX(0); } 86%, 100% { transform: translateX(var(--mq-shift, 0)); } }
select { white-space: nowrap; }
@media (prefers-reduced-motion: reduce) { .mq-run { animation: none; } }
@media (prefers-reduced-motion: reduce) { ::picker(select) { transition: none; } }
@media (forced-colors: active) {
  select { background-image: none; }
  select option:checked { forced-color-adjust: auto; }
}

/* =====================================================================================
   v1.2.0 Library: patch cards reuse .item-list > .item (card style, stagger, hover effects); banner slot is 16:9.
   ===================================================================================== */
.library-page { margin-top: 0; }
.library-head { display: flex; justify-content: space-between; align-items: center; gap: 0.75rem; margin-bottom: 0.75rem; }
.library-page > h2:focus { outline: none; }
.library-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr)); gap: 1rem; }
.library-card { padding: 0; border-left-width: 1px; }
.library-card.is-current { border-color: var(--gold-line); }
.library-card-btn { display: block; width: 100%; padding: 0; border: 0; background: none; color: inherit; font: inherit; text-align: left; cursor: pointer; }
.library-card-btn:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
.library-card-meta { padding: 0.75rem 1rem 1rem; }
.library-card-meta .hint { margin-top: 0.25rem; }
.library-banner { position: relative; aspect-ratio: 16 / 9; overflow: hidden; background: var(--panel-2); border-bottom: 1px solid var(--line); }
.library-banner img { display: block; width: 100%; height: 100%; object-fit: cover; }
.library-banner-wide { max-width: 44rem; margin: 0.5rem 0 1rem; border: 1px solid var(--line); }
.library-placeholder { position: absolute; inset: 0.6rem; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 0.25rem; border: 1px dashed var(--line-2); }
.library-placeholder-v { font: 500 var(--fs-data)/1 var(--serif); color: var(--text-2); font-variant-numeric: tabular-nums; }
.library-placeholder-t { font-size: var(--fs-xs); letter-spacing: 0.12em; text-transform: uppercase; color: var(--muted); }
.library-expired { margin-top: 0.75rem; }
/* v1.2.9 fix: long source links in import cards wrapped nowhere and widened phone screens (found at 320 px) */
.import-entry .hint, .import-entry li { overflow-wrap: anywhere; }
/* v1.2.9: ended limited events of a patch, kept in the catalog: a closed group, greyed with translucent stripes,
   still importable */
.library-ended { margin-top: 1rem; }
.library-ended > summary { cursor: pointer; font-weight: 600; font-size: var(--fs-sm); min-height: 2.5rem; display: flex; align-items: center; gap: 0.75rem; list-style: none; color: var(--text-2); }
.library-ended > summary::-webkit-details-marker { display: none; }
.library-ended > .hint { margin: 0.25rem 0 0.5rem; }
.library-ended-preview .import-entry {
  opacity: 0.72;
  background: repeating-linear-gradient(135deg, rgba(255, 255, 255, 0.075) 0 10px, transparent 10px 22px), var(--panel-2);
  filter: grayscale(0.55);
  transition: opacity var(--dur-hover), filter var(--dur-hover);
}
.library-ended-preview .import-entry:hover, .library-ended-preview .import-entry:focus-within { opacity: 1; filter: none; }
@media (forced-colors: active) { .library-ended-preview .import-entry { opacity: 1; filter: none; background: Canvas; } }
@media (max-width: 560px) { .library-grid { grid-template-columns: minmax(0, 1fr); } }

/* =====================================================================================
   v1.2.1 card artwork and per-entry import cards. Artwork is a darkened image layer (.item-art, inserted by
   ui.js applyArt only when the developer-supplied file loads) behind the card's content; the plain card is the
   fallback. Import entries are .item cards too, so they get the same 3D tilt, glow and border light.
   ===================================================================================== */
.item.has-art { isolation: isolate; }
.item > .item-art {
  position: absolute; inset: 0; z-index: -1; pointer-events: none; border-radius: inherit;
  background: linear-gradient(90deg, rgba(10, 10, 9, 0.93) 0%, rgba(10, 10, 9, 0.86) 55%, rgba(10, 10, 9, 0.78) 100%), var(--art) center / cover no-repeat;
}
.item.has-date > .item-art { grid-column: auto; grid-row: auto; }
.item.has-art .hint, .item.has-art > p { color: var(--text-2); }
.import-list.item-list { margin-top: 0.75rem; }
.item.import-entry { padding: 1rem 1.25rem; border-left-width: 3px; background: var(--panel-2); }
.item.import-new { border-left-color: var(--gold-line); }
.item.import-conflict, .item.import-resembles { border-left-color: var(--line-2); }
.item.import-identical, .item.import-owned, .item.import-batch, .item.import-error { border-left-color: var(--line); }
.import-entry .btn-row { margin-top: 0.75rem; }
.import-entry .msg { margin-top: 0.5rem; }
.library-placeholder-v.is-category { font-size: var(--fs-data); }

/* =====================================================================================
   v1.2.2 first-launch choices, patch-content results, live countdown tag
   ===================================================================================== */
/* the first-launch pop-up: darkened + blurred page, fading in and out together */
.start-overlay {
  position: fixed; inset: 0; z-index: 70; display: grid; place-items: center; padding: 1rem; overflow-y: auto;
  background: rgba(0, 0, 0, 0); -webkit-backdrop-filter: blur(0); backdrop-filter: blur(0); opacity: 0;
  transition: opacity 0.4s var(--ease), background-color 0.4s var(--ease), -webkit-backdrop-filter 0.4s var(--ease), backdrop-filter 0.4s var(--ease);
}
.start-overlay[hidden] { display: none; }
.start-overlay.is-open { opacity: 1; background: rgba(0, 0, 0, 0.58); -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px); }
.start-overlay .start-panel {
  width: min(42rem, 100%); max-height: calc(100vh - 2rem); overflow-y: auto; margin: 0;
  transform: translateY(10px) scale(0.985); transition: transform 0.4s var(--ease);
}
.start-overlay.is-open .start-panel { transform: none; }
body.modal-open { overflow: hidden; }
@media (prefers-reduced-motion: reduce) { .start-overlay, .start-overlay .start-panel { transition: none; } }
.start-panel { border-color: var(--gold-line); }
.start-panel .btn-row { margin-top: 1rem; }
.patch-load { margin-top: 1rem; }
.patch-load-summary { margin-top: 0.5rem; }
.patch-load .overline { margin-top: 1rem; }
.confirm-inline { margin-top: 0.75rem; padding-top: 0.75rem; border-top: 1px dashed var(--danger-line); }
.countdown-tag {
  /* v1.2.5: urgency colour. --cd-h is set per tag from the time left (events.urgency): 140 green ... 0 red. One
     lightness and saturation for every hue keeps the text above 4.5:1 on the darkest card and the artwork overlay. */
  --cd-h: 0;
  margin-left: auto; padding: 0.15rem 0.5rem; border: 1px solid hsl(var(--cd-h) 85% 66% / 0.45); border-radius: var(--r);
  background: hsl(var(--cd-h) 85% 66% / 0.11); color: hsl(var(--cd-h) 85% 66%); font: 600 var(--fs-xs)/1.4 var(--sans); letter-spacing: 0.03em;
  font-variant-numeric: tabular-nums; white-space: nowrap;
  transition: color 0.6s, border-color 0.6s, background-color 0.6s;
}
@media (forced-colors: active) { .countdown-tag { color: CanvasText; border-color: CanvasText; background: Canvas; } }
/* v1.2.8: the longer "Limited rewards unavailable in …" never widens a card: the tag can take the full row and, on a
   narrow card, wraps at a space */
.countdown-tag { max-width: 100%; white-space: normal; }
/* v1.2.5: the card "Open in Events" / "Open in Endgame Content" lands on (uiNav.reveal), clear of the sticky bar */
.item-list > .item { scroll-margin-top: calc(var(--nav-h) + 0.75rem); }
.item.nav-target { animation: nav-target 1.6s var(--ease) 1; }
@keyframes nav-target { 0%, 35% { box-shadow: 0 0 0 2px var(--gold), 0 0 28px rgba(186, 151, 92, 0.45); } 100% { box-shadow: 0 0 0 0 transparent; } }
@media (prefers-reduced-motion: reduce) { .item.nav-target { animation: none; outline: 2px solid var(--gold); outline-offset: 2px; } }
.eg-not-published { margin-top: 0.5rem; }

/* =====================================================================================
   v1.2.3 ended cards (Events and Timeline): marked on the card itself instead of a separate "has ended" note.
   Red diagonal stripes over the card's surface, or over its darkened artwork so the image stays recognisable; a red
   left edge and Ended badge; the Delete action leads the row as a solid red button. Reward tables keep an opaque
   surface so their numbers stay readable over the stripes.
   ===================================================================================== */
.item.is-ended {
  border-left-color: var(--danger);
  background: repeating-linear-gradient(135deg, rgba(255, 100, 103, 0.13) 0 10px, transparent 10px 22px), var(--panel-2);
}
.item.is-ended > .item-art {
  background: repeating-linear-gradient(135deg, rgba(255, 100, 103, 0.16) 0 10px, transparent 10px 22px),
    linear-gradient(90deg, rgba(10, 10, 9, 0.9) 0%, rgba(10, 10, 9, 0.8) 55%, rgba(10, 10, 9, 0.7) 100%), var(--art) center / cover no-repeat;
}
.item.is-ended .badge-expired, .item.is-ended .badge-ended { border-style: solid; border-color: var(--danger-line); color: var(--danger); background: var(--danger-bg); }
.item.is-ended .table-wrap { background: var(--panel); border-radius: var(--r); }
.btn.danger.solid { background: var(--danger); border-color: var(--danger); color: #000; font-weight: 600; }
.btn.danger.solid:hover:not(:disabled), .btn.danger.solid:focus-visible { background: #ff8587; border-color: #ff8587; color: #000; }
@media (forced-colors: active) {
  .item.is-ended { background: Canvas; border-left-color: Mark; border-left-style: double; border-left-width: 6px; }
  .btn.danger.solid { background: ButtonText; color: ButtonFace; forced-color-adjust: none; }
}

/* =====================================================================================
   v1.2.4 card actions: operational actions on the left, the management group (Edit, Export, Delete) on the right.
   On narrow cards the management group wraps to its own line, right-aligned, under a hairline.
   ===================================================================================== */
.card-actions { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 0.5rem 1rem; margin-top: 0.75rem; }
.card-actions .act-ops, .card-actions .act-manage { display: flex; flex-wrap: wrap; gap: 0.5rem; min-width: 0; }
.card-actions .act-manage { margin-left: auto; justify-content: flex-end; }
@media (max-width: 560px) {
  .card-actions .act-ops + .act-manage { flex-basis: 100%; padding-top: 0.5rem; border-top: 1px solid var(--line); }
}
.event-cats.single { grid-template-columns: minmax(0, 1fr); }

/* =====================================================================================
   v1.2.7 local cache: header pill, status line in Save & Load, the "restored" note
   ===================================================================================== */
.header-meta { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; justify-content: flex-end; }
.cache-pill {
  display: inline-flex; align-items: center; gap: 0.5rem; font-size: var(--fs-sm); color: var(--muted); text-decoration: none;
  border: 1px solid var(--line); border-radius: var(--r); padding: 0.25rem 0.75rem; white-space: nowrap;
}
.cache-pill:hover, .cache-pill:focus-visible { color: var(--text-2); border-color: var(--line-2); }
.cache-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--muted); flex: none; }
[data-cache="ok"] .cache-dot { background: var(--up); }
[data-cache="pending"] .cache-dot, [data-cache="off"] .cache-dot, [data-cache="conflict"] .cache-dot { background: var(--gold); }
[data-cache="error"] .cache-dot { background: var(--danger); }
.cache-pill[data-cache="error"], .cache-pill[data-cache="conflict"] { color: var(--text-2); border-color: var(--gold-line); }
.cache-pill[data-cache="error"] { border-color: var(--danger-line); }
.cache-box { margin-top: var(--gap-section); padding: var(--gap-section) 0 0; border: 0; border-top: 1px solid var(--line); border-radius: 0; background: none; }   /* an unboxed section, like the Income and Balances sub-sections */
.cache-box > .subhead:first-child { margin-top: 0; }
.cache-status { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; font-size: var(--fs-label); margin: 0.5rem 0; }
.cache-status #cache-status-time { color: var(--muted); font-size: var(--fs-sm); }
.cache-toggles { margin-top: 0.5rem; }
.cache-interval { margin-top: 0.5rem; }
.cache-restored { margin: 0.75rem 0; display: flex; flex-wrap: wrap; gap: 0.5rem 0.75rem; align-items: center; }
.cache-restored .cache-restored-actions { margin: 0 0 0 auto; }
.cache-restored-actions a.btn { text-decoration: none; display: inline-flex; align-items: center; }
@media (forced-colors: active) { .cache-dot { forced-color-adjust: none; border: 1px solid CanvasText; } }

/* =====================================================================================
   v1.2.10 guide (js/ui-guide.js): header button, panel (docked on desktop, bottom sheet on phones),
   the ring on the field a step is about, in-game paths and step pictures. Astrite palette only.
   ===================================================================================== */
.guide-btn {
  display: inline-flex; align-items: center; gap: 0.5rem; font: 600 var(--fs-sm)/1 var(--sans); letter-spacing: 0.03em;
  color: var(--text-2); background: transparent; border: 1px solid var(--gold-line); border-radius: var(--r);
  padding: 0.5rem 0.75rem; cursor: pointer; white-space: nowrap;
  transition: color var(--dur-hover) var(--ease-ui), border-color var(--dur-hover) var(--ease-ui), background-color var(--dur-hover) var(--ease-ui);
}
.guide-btn:hover, .guide-btn:focus-visible, .guide-btn[aria-expanded="true"] { color: var(--gold-hi); border-color: var(--gold); background: var(--gold-lo); }
.guide-btn-ico { width: 14px; height: 14px; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linejoin: round; }
.guide-btn.has-progress .guide-btn-ico path { fill: var(--gold); stroke: var(--gold); }

.guide {
  position: fixed; z-index: 40; right: 1rem; bottom: 1rem; width: min(24rem, calc(100vw - 2rem));
  max-height: calc(100vh - var(--nav-h) - 2rem); display: flex; flex-direction: column;
  background: linear-gradient(180deg, rgba(22, 20, 16, 0.84), rgba(10, 10, 10, 0.88)); border: 1px solid var(--gold-line);
  -webkit-backdrop-filter: blur(18px) saturate(1.3); backdrop-filter: blur(18px) saturate(1.3);
  box-shadow: 0 18px 50px -18px #000, 0 0 0 1px rgba(0, 0, 0, 0.4); color: var(--text);
  opacity: 0; transform: translateY(16px) scale(0.985); filter: blur(8px); transform-origin: 100% 100%;
  transition: opacity 420ms var(--ease), transform 420ms var(--ease), filter 420ms var(--ease), height 380ms var(--ease);
}
.guide[hidden] { display: none; }
.guide.is-open { opacity: 1; transform: none; filter: none; }
.guide.is-morphing { overflow: hidden; }
/* new step content (and the start pop-up's offer) fades in from a soft blur */
.soft-enter { animation: soft-enter 440ms var(--ease) both; }
.guide-actions.soft-enter { animation-delay: 70ms; }
@keyframes soft-enter { from { opacity: 0; transform: translateY(8px); filter: blur(6px); } to { opacity: 1; transform: none; filter: none; } }
body.modal-open .guide { visibility: hidden; }        /* the first-launch pop-up comes first */
.guide-head { display: flex; align-items: center; gap: 0.5rem; padding: 0.75rem 0.75rem 0 1rem; }
.guide-count { margin: 0; flex: 1 1 auto; min-width: 0; }
.guide-opt { flex: none; }
.guide-icon { flex: none; width: 2rem; height: 2rem; display: grid; place-items: center; background: none; border: 1px solid transparent; color: var(--muted); cursor: pointer; border-radius: var(--r); }
.guide-icon:hover, .guide-icon:focus-visible { color: var(--text); border-color: var(--line-2); }
.guide-icon svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; transition: transform var(--dur-hover) var(--ease); }
.guide.is-collapsed #guide-collapse svg { transform: rotate(180deg); }
.guide-main { flex: 1 1 auto; min-height: 0; padding: 0.25rem 1rem 0.25rem; overflow-y: auto; overflow-x: hidden; overscroll-behavior: contain; scrollbar-width: none; }
/* no scrollbar: it appeared while new content slid in and narrowed the text, so everything shifted. Long steps still
   scroll with the wheel, touch and keyboard. */
.guide-main::-webkit-scrollbar { display: none; }
/* ...so when there is more below, the lower edge fades out instead (ui-guide.js sets has-more) */
.guide-main.has-more { -webkit-mask-image: linear-gradient(to bottom, #000 calc(100% - 2rem), transparent); mask-image: linear-gradient(to bottom, #000 calc(100% - 2rem), transparent); }
.guide.is-collapsed .guide-main, .guide.is-collapsed .guide-actions { display: none; }
.guide-title { font: 600 var(--fs-lg)/1.3 var(--serif); margin: 0.25rem 0 0.5rem; outline: none; }
.guide-title:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
.guide-text { margin: 0 0 0.75rem; color: var(--text-2); font-size: var(--fs-label); line-height: 1.5; }
.guide-actions { flex: none; margin: 0; padding: 0.75rem 1rem 1rem; display: flex; flex-wrap: wrap; gap: 0.5rem; justify-content: flex-end; border-top: 1px solid var(--line-3); }
.guide-actions[hidden] { display: none; }

/* where it is in-game: a short breadcrumb, the spot itself stands out */
.guide-where { border-top: 1px solid var(--line-3); padding-top: 0.5rem; margin: 0.5rem 0 0.75rem; }
.guide-where-head { margin: 0 0 0.5rem; font: 600 var(--fs-xs)/1.4 var(--sans); letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted); }
.guide-path { margin: 0 0 0.5rem; display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.25rem 0.5rem; font-size: var(--fs-sm); color: var(--text-2); }
.guide-path-label { color: var(--text); font-weight: 600; margin-right: 0.15rem; }
.guide-sep { color: var(--muted); }
.guide-spot { background: var(--gold-lo); color: var(--gold-hi); font-weight: 700; border: 1px solid var(--gold-line); padding: 0 0.5rem; border-radius: 2px; }
.guide-note { margin: 0 0 0.5rem; font-size: var(--fs-sm); color: var(--muted); }

/* step picture: fixed 16:9 frame; the placeholder (with the caption) stays until the real file has loaded */
.guide-shot-wrap { margin: 0.25rem 0 0.5rem; }
.guide-shot-toggle { display: none; }
.guide-shot {
  position: relative; margin: 0; width: 100%; aspect-ratio: 16 / 9; overflow: hidden;
  border: 1px solid var(--gold-line); background: radial-gradient(120% 90% at 50% 0%, rgba(186, 151, 92, 0.12), transparent 60%), linear-gradient(160deg, #15130f, #0a0a0a);
}
.guide-ph { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 0.5rem; padding: 0.75rem; text-align: center; transition: opacity var(--dur-media) var(--ease-ui); }
.guide-ph svg { width: 28px; height: 28px; fill: none; stroke: var(--gold); stroke-width: 1.4; stroke-linejoin: round; opacity: 0.8; }
.guide-ph-cap { font-size: var(--fs-sm); line-height: 1.35; color: var(--text-2); max-width: 22rem; }
.guide-shot img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; opacity: 0; transition: opacity var(--dur-media) var(--ease-ui); }
.guide-shot.has-img img { opacity: 1; }
.guide-shot.has-img .guide-ph { opacity: 0; }

/* the check mark when a step completes */
.guide-check { display: none; align-items: center; gap: 0.5rem; margin: 0.25rem 0 0; color: var(--up); font-weight: 600; font-size: var(--fs-sm); }
.guide-check svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; stroke-dasharray: 24; stroke-dashoffset: 24; }
.guide.is-done .guide-check { display: flex; animation: soft-enter 320ms var(--ease) both; }
.guide.is-done .guide-check svg { animation: guide-tick 420ms var(--ease) forwards; }
@keyframes guide-tick { to { stroke-dashoffset: 0; } }

/* review and menus */
.guide-review { margin: 0 0 0.75rem; border-top: 1px solid var(--line-3); }
.guide-row { display: grid; grid-template-columns: minmax(0, 1fr); gap: 0.05rem; padding: 0.5rem 0; border-bottom: 1px solid var(--line-3); }
.guide-row dt { font-size: var(--fs-sm); color: var(--muted); grid-column: 1; }
.guide-row dd { margin: 0; grid-column: 1 / -1; display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; font-size: var(--fs-label); }
.guide-value { color: var(--text); font-variant-numeric: tabular-nums; min-width: 0; overflow-wrap: anywhere; }
.guide-missing { color: var(--gold-hi); font-weight: 600; }
.guide-row.is-missing { box-shadow: inset 2px 0 0 var(--gold); padding-left: 0.5rem; }
.guide-fix.btn.small { flex: none; padding: 0.15rem 0.75rem; font-size: var(--fs-sm); min-height: 0; }
.guide-forecast { margin: 0.25rem 0 0; font-size: var(--fs-label); }
.guide-forecast strong { color: var(--gold-hi); font-family: var(--serif); font-size: var(--fs-lg); }
.guide-forecast.is-missing strong { font-size: var(--fs-label); font-family: var(--sans); }
.guide-choices { list-style: none; margin: 0.25rem 0 0; padding: 0; display: grid; gap: 0.75rem; }
.guide-choices li { display: grid; gap: 0.25rem; justify-items: start; }
.guide-choices .hint { margin: 0; }
.msg .msg-action { margin-left: 0.5rem; vertical-align: middle; }

/* the field a step is about: a gold ring that fades in, then breathes slowly */
.guide-target { outline: 2px solid transparent; outline-offset: 4px; transition: outline-color 450ms var(--ease-ui), box-shadow 450ms var(--ease-ui); }
.guide-target.is-lit { outline-color: var(--gold); box-shadow: 0 0 0 6px rgba(186, 151, 92, 0.1), 0 0 26px -2px rgba(186, 151, 92, 0.35); animation: guide-breathe 2.8s 500ms ease-in-out infinite; }
@keyframes guide-breathe { 50% { box-shadow: 0 0 0 9px rgba(186, 151, 92, 0.05), 0 0 34px 0 rgba(186, 151, 92, 0.22); } }

/* phones: a bottom sheet up to 42% of the screen; the page gets room underneath so nothing hides behind it */
@media (max-width: 600px) {
  .guide { left: 0; right: 0; bottom: 0; width: auto; max-height: 42vh; border-left: 0; border-right: 0; border-bottom: 0; padding-bottom: env(safe-area-inset-bottom, 0px); }
  body.guide-open { padding-bottom: 42vh; }
  body.guide-open .float-count { display: none; }
  .guide-head { padding-left: 16px; }
  .guide-main { padding: 0.15rem 16px 0.25rem; }
  .guide-actions { padding: 0.5rem 16px 0.75rem; }
  .guide-title { font-size: var(--fs-body); }
}
/* very small or short screens: the picture waits behind "Show picture" so the field and the steps stay in view */
@media (max-width: 360px), (max-height: 640px) {
  .guide-shot-toggle { display: inline-flex; }
  .guide-shot-wrap .guide-shot { display: none; }
  .guide-shot-wrap.is-open .guide-shot { display: block; margin-top: 0.5rem; }
}
@media (prefers-reduced-motion: reduce) {
  .guide, .guide-ph, .guide-shot img, .guide-target, .guide-icon svg { transition: none; }
  .guide { filter: none; transform: none; }
  .soft-enter, .msg.toast.toast-in, .msg.toast.toast-out { animation: none; }
  .guide-target.is-lit { animation: none; }
  .guide.is-done .guide-check svg { animation: none; stroke-dashoffset: 0; }
}
@media (forced-colors: active) { .guide-target.is-lit { outline-color: Highlight; } }

/* the first-launch pop-up's guide offer (first visits only) */
.start-offer .btn-row { margin-top: 1rem; }

/* =====================================================================================
   v1.2.12 timeline chart (js/ui-chrono.js): a second view of the Timeline beside the cards. The chart has its own
   sideways scroll; the page never scrolls sideways. Bars carry the item kind's colour as a 3px edge (like the cards)
   over their card's artwork; lines mark now (gold-hi), the projection deadline (dashed gold) and milestones (thin).
   Rhythm: tight inside a lane, generous between lanes; every size from the tokens.
   ===================================================================================== */
.tl-view-row { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--s-3) var(--s-4); margin: 0 0 var(--s-7); }
.view-switch { width: auto; }
.view-switch .filter span { min-width: 7rem; text-align: center; }
#timeline[data-view="chart"] .tl-controls > .sort-control { display: none; }

.chrono { --bar-h: 2.5rem; --row-h: 3.5rem; margin-top: var(--s-7); }
.chrono.is-empty .chrono-frame { display: none; }
.chrono-head {
  position: sticky; top: var(--chrono-top, var(--nav-h)); z-index: 8; display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: var(--s-3) var(--s-5); margin: 0 0 var(--s-5); padding: var(--s-3) var(--s-4);
  border: 1px solid var(--line); background: rgba(10, 10, 9, 0.86); -webkit-backdrop-filter: blur(14px) saturate(1.2); backdrop-filter: blur(14px) saturate(1.2);
}   /* stays under the sticky nav while a tall chart scrolls by, so Jump to now is always in reach */
#btn-chart-now { display: inline-flex; align-items: center; gap: var(--s-2); }
.chrono-tools { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-2) var(--s-3); }
.chrono-hint { font-size: var(--fs-xs); color: var(--muted); }
.chrono-zoom { display: inline-flex; gap: 2px; }
.chrono-zoom .btn { min-width: 2.25rem; padding-left: var(--s-2); padding-right: var(--s-2); font-size: var(--fs-body); line-height: 1; }
@media (hover: none), (max-width: 560px) { .chrono-hint { display: none; } }   /* no wheel: the buttons zoom */
.chrono-status { margin: 0; font-size: var(--fs-sm); color: var(--text-2); }
.chrono-frame { position: relative; border: 1px solid var(--line); background: var(--panel-2); }
.chrono-scroll { overflow-x: auto; overflow-y: hidden; overscroll-behavior-x: contain; scrollbar-width: thin; scrollbar-color: var(--line-2) transparent; -webkit-overflow-scrolling: touch; }
.chrono-scroll:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
.chrono-canvas { position: relative; min-width: 100%; padding-bottom: var(--s-6);
  /* one faint line per server day, aligned with the axis (the range starts on a day boundary) */
  background-image: linear-gradient(to right, rgba(255, 255, 255, 0.04) 1px, transparent 1px);
  background-size: var(--day) 100%; }

/* axis: months (name sticky at the left edge) over days */
.chrono-axis { position: relative; height: 5.5rem; border-bottom: 1px solid var(--line-2); background: var(--panel); }
.chrono-months, .chrono-days { position: absolute; left: 0; right: 0; }
.chrono-months { top: 0; height: 2.5rem; }
.chrono-days { top: 2.5rem; height: 3rem; }
.chrono-month { position: absolute; top: 0; height: 100%; border-left: 1px solid var(--line-2); overflow: clip; }   /* the sticky name stops at its month's edge (clip, not hidden: hidden would stop it sticking) */
.chrono-month-name { position: sticky; left: 0; display: inline-block; padding: var(--s-2) var(--s-4); font: 500 var(--fs-lg)/1.3 var(--serif); color: var(--gold-hi); white-space: nowrap; }
.chrono-day { position: absolute; top: 0; height: 100%; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 0.125rem; line-height: 1.1; }
.chrono-dow { font-size: var(--fs-xs); letter-spacing: 0.04em; color: var(--muted); }
.chrono-dom { font: 500 var(--fs-body) var(--serif); color: var(--text-2); font-variant-numeric: tabular-nums; }
.chrono-day.is-weekend .chrono-dom { color: var(--muted); }
.chrono-day.is-today { background: var(--gold-lo); }
.chrono-canvas.is-compact .chrono-dow { display: none; }
.chrono-canvas.is-tiny .chrono-day:not(.is-mark):not(.is-today) .chrono-dom { visibility: hidden; }
.chrono-canvas.is-tiny .chrono-dom { font-size: var(--fs-xs); }
.chrono-day.is-today .chrono-dom, .chrono-day.is-today .chrono-dow { color: var(--gold-hi); }

/* patch band and lanes: a label row, then the rows; generous space between lanes */
.chrono-lane-head, .chrono-row { position: relative; }
.chrono-lane { padding: var(--s-3) 0 var(--s-5); border-bottom: 1px solid var(--line); }
.chrono-lane-head { height: 2rem; }
.chrono-lane-name { position: sticky; left: 0; z-index: 3; display: inline-block; padding: var(--s-1) var(--s-4); font: 600 var(--fs-xs)/1.6 var(--sans); letter-spacing: 0.12em; text-transform: uppercase; color: var(--muted); background: var(--panel-2); }
.chrono-row { height: var(--row-h); }
.chrono-band-row { height: 3rem; }
.chrono-band .chrono-bar { top: 0.375rem; height: 2.25rem; }

/* bars: the card's artwork darkened, the kind's colour as a 3px edge; the name sticks to the visible edge */
.chrono-bar {
  position: absolute; top: calc((var(--row-h) - var(--bar-h)) / 2); height: var(--bar-h); z-index: 2; isolation: isolate;
  display: flex; align-items: center; gap: var(--s-3); min-width: 0; padding: 0 var(--s-3) 0 0; margin: 0;
  border: 1px solid var(--line-2); border-left: 3px solid var(--kc, var(--gold)); border-radius: 0;
  background: linear-gradient(90deg, color-mix(in srgb, var(--kc, var(--gold)) 20%, var(--panel)), var(--panel) 80%);
  color: var(--text); font: 600 var(--fs-sm)/1.2 var(--sans); text-align: left; cursor: pointer; overflow: clip;   /* clip, not hidden: hidden would make the bar the sticky name's scroller */
  transition: border-color var(--dur-base), filter var(--dur-base), box-shadow var(--dur-base);
}
.chrono-bar > .item-art {
  /* the card's thumbnail as a small image at the bar's right end: the bar's height, at most 8rem wide (16:9 art is
     about 4.5rem at this height, so it widens a little but never zooms in much), fading out towards the left */
  position: absolute; top: 0; bottom: 0; right: 0; width: min(100%, 8rem); z-index: -1; pointer-events: none;
  background: linear-gradient(90deg, rgba(10, 10, 9, 0) 0%, rgba(10, 10, 9, 0.35) 100%), var(--art) center / cover no-repeat;
  -webkit-mask-image: linear-gradient(90deg, transparent 0%, #000 65%); mask-image: linear-gradient(90deg, transparent 0%, #000 65%);
}
.chrono-bar:hover, .chrono-bar:focus-visible { border-color: var(--line-2); border-left-color: var(--kc, var(--gold)); filter: brightness(1.2); z-index: 4; }
.chrono-bar:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
.chrono-bar-name { position: sticky; left: 0; min-width: 0; padding-left: var(--s-3); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; text-shadow: 0 1px 3px rgba(0, 0, 0, 0.8); }
/* the countdown, outside the bar: a compact chip ("15d") that opens to the live countdown on hover. Its width eases
   between the two and each text blurs in and out as it swaps. Colour from the countdown's urgency (--cd-h). */
.chrono-cd {
  --cd-h: 140; position: absolute; top: calc((var(--row-h) - 1.75rem) / 2); z-index: 3; height: 1.75rem;
  display: inline-flex; align-items: center; padding: 0 var(--s-2); white-space: nowrap;
  border: 1px solid hsl(var(--cd-h) 85% 66% / 0.45); background: color-mix(in srgb, hsl(var(--cd-h) 85% 66%) 12%, var(--panel));
  color: hsl(var(--cd-h) 85% 66%); font: 600 var(--fs-xs)/1 var(--sans); font-variant-numeric: tabular-nums; cursor: default;
  box-shadow: 0 6px 16px -10px #000; transition: box-shadow 300ms var(--ease), background-color 300ms var(--ease);
}
.chrono-cd > .chrono-cd-short, .chrono-cd > .chrono-cd-full {
  display: inline-block; overflow: hidden; vertical-align: middle;
  transition: max-width 320ms var(--ease), opacity 260ms var(--ease), filter 300ms var(--ease);
}
.chrono-cd-short { max-width: 4rem; opacity: 1; filter: none; }
.chrono-cd > .chrono-cd-full { max-width: 0; opacity: 0; filter: blur(5px); margin: 0; padding: 0; border: 0; background: none; color: inherit; font: inherit; }
.chrono-cd:hover, .chrono-bar:hover + .chrono-cd, .chrono-bar:focus-visible + .chrono-cd { z-index: 6; box-shadow: 0 10px 24px -10px #000, 0 0 0 1px hsl(var(--cd-h) 85% 66% / 0.25); }
.chrono-cd:hover > .chrono-cd-short, .chrono-bar:hover + .chrono-cd > .chrono-cd-short, .chrono-bar:focus-visible + .chrono-cd > .chrono-cd-short { max-width: 0; opacity: 0; filter: blur(5px); }
.chrono-cd:hover > .chrono-cd-full, .chrono-bar:hover + .chrono-cd > .chrono-cd-full, .chrono-bar:focus-visible + .chrono-cd > .chrono-cd-full { max-width: 16rem; opacity: 1; filter: none; }
@media (forced-colors: active) { .chrono-cd { color: CanvasText; border-color: CanvasText; background: Canvas; } }
.chrono-bar.kind-event { --kc: var(--c-event); }
.chrono-bar.kind-banner { --kc: var(--c-banner); }
.chrono-bar.kind-patch { --kc: var(--c-patch); }
.chrono-bar.kind-custom { --kc: var(--c-custom); }
.chrono-bar.kind-endgame { --kc: var(--c-endgame); }
.chrono-bar.is-upcoming { background: var(--panel); }
.chrono-bar.is-upcoming > .item-art { opacity: 0.6; }
.chrono-bar.is-estimated { border-style: dashed; border-left-style: solid; }
.chrono-bar.is-ended { color: var(--muted); border-left-color: var(--danger); }
.chrono-bar.is-ended::after { content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none; background: repeating-linear-gradient(135deg, rgba(255, 100, 103, 0.12) 0 8px, transparent 8px 16px); }
.chrono-bar.is-ended > .item-art { filter: grayscale(0.6); opacity: 0.7; }
.chrono-bar.is-deadline { border-color: var(--gold-line); box-shadow: 0 0 0 1px var(--gold-line), 0 0 14px -4px var(--gold); }
.chrono-bar.is-selected { border-color: var(--gold); box-shadow: 0 0 0 1px var(--gold); }
/* points (milestones, start-less items): a diamond on the date, the name beside it */
.chrono-bar.is-point { width: auto; padding: 0 var(--s-3) 0 0; border: 0; background: none; overflow: visible; transform: translateX(-0.625rem); }
.chrono-diamond { flex: none; width: 1.25rem; height: 1.25rem; margin-right: var(--s-1); transform: rotate(45deg); border: 2px solid var(--kc, var(--gold)); background: var(--panel); }
.chrono-bar.is-point .chrono-bar-name { position: static; padding-left: 0; }

/* full-height lines; their tags sit in the axis so they never cover a bar's text */
.chrono-lines { position: absolute; inset: 0; pointer-events: none; z-index: 5; }
.chrono-line { position: absolute; top: 0; bottom: 0; width: 0; border-left: 1px solid var(--c-custom); }
.chrono-line-tag { position: absolute; top: var(--s-2); left: var(--s-1); padding: 0.125rem var(--s-2); font: 600 var(--fs-xs)/1.5 var(--sans); white-space: nowrap; color: var(--c-custom); background: var(--panel); border: 1px solid currentColor; }
.chrono-line.is-milestone { opacity: 0.8; }
.chrono-line.is-deadline { border-left: 2px dashed var(--gold); }
.chrono-line.is-deadline .chrono-line-tag { top: 3.25rem; color: #0b0a08; background: var(--gold); border-color: var(--gold); }
.chrono-line.is-now { border-left: 2px solid var(--gold-hi); box-shadow: 0 0 12px rgba(207, 174, 114, 0.45); }
.chrono-line.is-now .chrono-line-tag { color: var(--gold-hi); border-color: var(--gold-line); }
.chrono-marker { position: absolute; top: 5.5rem; bottom: 0; width: 0; border-left: 1px dotted var(--cyan); }   /* future planner marks */

.badge.kind-event { border-color: var(--c-event); color: var(--c-event); }
.badge.kind-banner { border-color: var(--c-banner); color: var(--c-banner); }
.badge.kind-patch { border-color: var(--c-patch); color: var(--c-patch); }
.badge.kind-custom { border-color: var(--c-custom); color: var(--c-custom); }
.badge.kind-endgame { border-color: var(--c-endgame); color: var(--c-endgame); }

/* the pop-up: over a darkened, blurred page; the item's card art fills the panel behind its facts */
.chrono-pop-overlay {
  position: fixed; inset: 0; z-index: 72; display: grid; place-items: center; padding: var(--s-4);
  background: rgba(0, 0, 0, 0); -webkit-backdrop-filter: blur(0); backdrop-filter: blur(0); opacity: 0;
  transition: opacity 280ms var(--ease), background-color 280ms var(--ease), -webkit-backdrop-filter 280ms var(--ease), backdrop-filter 280ms var(--ease);
}
.chrono-pop-overlay[hidden] { display: none; }
.chrono-pop-overlay.is-open { opacity: 1; background: rgba(0, 0, 0, 0.55); -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px); }
.chrono-pop {
  position: relative; isolation: isolate; width: min(30rem, 100%); max-height: calc(100vh - 2rem); overflow-y: auto;
  border: 1px solid var(--gold-line); border-left: 3px solid var(--kc, var(--gold)); background: var(--panel);
  box-shadow: 0 30px 70px -20px #000, 0 0 0 1px rgba(0, 0, 0, 0.4);
  transform: translateY(14px) scale(0.97); filter: blur(6px);
  transition: transform 340ms var(--ease), filter 340ms var(--ease);
}
.chrono-pop-overlay.is-open .chrono-pop { transform: none; filter: none; }
.chrono-pop.kind-event { --kc: var(--c-event); }
.chrono-pop.kind-banner { --kc: var(--c-banner); }
.chrono-pop.kind-patch { --kc: var(--c-patch); }
.chrono-pop.kind-custom { --kc: var(--c-custom); }
.chrono-pop.kind-endgame { --kc: var(--c-endgame); }
.chrono-pop > .item-art {
  position: absolute; inset: 0; z-index: -1; pointer-events: none;
  /* the image centred; darker towards the facts so they always read */
  background: linear-gradient(180deg, rgba(10, 10, 9, 0.15) 0%, rgba(10, 10, 9, 0.55) 22%, rgba(10, 10, 9, 0.94) 42%, rgba(10, 10, 9, 0.97) 100%),
    var(--art) center / cover no-repeat;
}
.chrono-pop-body { padding: var(--s-9) var(--s-7) var(--s-7); }
.chrono-pop.has-art .chrono-pop-body { padding-top: 7rem; }   /* the art shows clear above the text */
.chrono-pop-tags { display: flex; flex-wrap: wrap; gap: var(--s-2); }
.chrono-pop-title { margin: var(--s-3) 0 0; font: 500 var(--fs-xl)/1.25 var(--serif); color: var(--text); text-shadow: 0 2px 10px rgba(0, 0, 0, 0.7); }
.chrono-pop-countdown { display: inline-block; margin: var(--s-3) 0 0; }
.chrono-pop-facts { display: grid; grid-template-columns: repeat(auto-fit, minmax(8rem, 1fr)); gap: var(--s-3) var(--s-5); margin: var(--s-6) 0 0; padding-top: var(--s-5); border-top: 1px solid var(--line); }
.chrono-pop-facts > div { min-width: 0; }
.chrono-pop-facts dt { font: 600 var(--fs-xs)/1.4 var(--sans); letter-spacing: 0.1em; text-transform: uppercase; color: var(--muted); }
.chrono-pop-facts dd { margin: var(--s-1) 0 0; font: 500 var(--fs-body)/1.3 var(--serif); color: var(--text); font-variant-numeric: tabular-nums; }
.chrono-pop-tz { margin-top: var(--s-4); font-size: var(--fs-sm); color: var(--text-2); }
.chrono-pop-summary { margin-top: var(--s-2); font-size: var(--fs-sm); color: var(--text-2); }
.chrono-pop-actions { margin-top: var(--s-6); }
.chrono-pop-close { position: absolute; top: var(--s-3); right: var(--s-3); z-index: 1; width: 2.5rem; height: 2.5rem; display: grid; place-items: center; border: 1px solid var(--line-2); background: rgba(10, 10, 9, 0.6); color: var(--text-2); cursor: pointer; transition: color var(--dur-base), border-color var(--dur-base); }
.chrono-pop-close:hover, .chrono-pop-close:focus-visible { color: var(--text); border-color: var(--gold-line); }
.chrono-pop-close svg { width: 1rem; height: 1rem; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; }

@media (max-width: 560px) {
  .chrono { --bar-h: 2.25rem; --row-h: 3rem; }
  .chrono-axis { height: 5rem; }
  .chrono-days { top: 2.25rem; height: 2.75rem; }
  .chrono-months { height: 2.25rem; }
  .chrono-month-name { font-size: var(--fs-body); padding: var(--s-2) var(--s-3); }
  .chrono-line.is-deadline .chrono-line-tag { top: 2.75rem; }
  .chrono-marker { top: 5rem; }
  .chrono-bar { font-size: var(--fs-xs); }
  .tl-view-row .view-switch { width: 100%; }
  .view-switch .filter { flex: 1 1 0; }
  .chrono-pop-body { padding: var(--s-7) var(--s-5) var(--s-5); }
  .chrono-pop.has-art .chrono-pop-body { padding-top: 5.5rem; }
}
@media (prefers-reduced-motion: reduce) {
  .chrono-bar, .chrono-pop-overlay, .chrono-pop, .chrono-cd, .chrono-cd > span { transition: none; }
  .chrono-pop { transform: none; filter: none; }
}
@media (forced-colors: active) { .chrono-line, .chrono-bar { forced-color-adjust: auto; } }

/* =====================================================================================
   v1.2.13 pity (js/ui-pity.js): one block per limited pool, side by side, stacked on phones. The pool's banner colour
   (--radiant / --forging) marks its top edge and meter. Tokens only. Not a card: no tilt, no holo.
   ===================================================================================== */
.pity-pools { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 19rem), 1fr)); align-items: start; gap: var(--s-5); margin-top: var(--s-5); }
.pity-pool { --pool: var(--gold); min-width: 0; padding: var(--s-5); border: 1px solid var(--line); border-top-color: var(--pool); border-radius: var(--r); background: var(--panel-2); }
.pity-limitedCharacter { --pool: var(--radiant); }
.pity-limitedWeapon { --pool: var(--forging); }
.pity-title { margin: 0; font: 600 var(--fs-lg)/1.3 var(--serif); color: var(--text); }
.pity-sub { margin: var(--s-1) 0 0; font-size: var(--fs-sm); color: var(--muted); }
.pity-count { margin: var(--s-4) 0 var(--s-2); font-family: var(--serif); font-variant-numeric: tabular-nums; color: var(--text); }
.pity-num { font-size: var(--fs-data); font-weight: 500; line-height: 1.1; }
.pity-of { font-size: var(--fs-lg); color: var(--muted); }
.pity-meter { height: var(--s-1); background: var(--line-3); overflow: hidden; }
.pity-meter-fill { display: block; height: 100%; width: 0; background: var(--pool); transition: width var(--dur-media) var(--ease); }
.pity-next { margin: var(--s-3) 0 0; font-size: var(--fs-label); font-weight: 600; color: var(--text-2); }
.pity-pool.is-guaranteed .pity-next { color: var(--gold-hi); }
.pity-updated { margin: var(--s-1) 0 0; font-size: var(--fs-sm); color: var(--muted); }
.pity-pool.is-unset .pity-num { color: var(--muted); }
.pity-form { margin-top: var(--s-4); padding-top: var(--s-4); border-top: 1px solid var(--line-3); }
.pity-form .toggle { margin-top: var(--s-3); }
.pity-form .toggle-text { font-weight: 500; }
.pity-count-row { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-2); }
.pity-count-row input { width: 6rem; }
.pity-fives-head { margin: var(--s-4) 0 var(--s-2); }
.pity-fives { list-style: none; margin: 0 0 var(--s-2); padding: 0; display: grid; gap: var(--s-2); }
.pity-five { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-2) var(--s-3); padding: var(--s-2) 0; border-bottom: 1px solid var(--line-3); }
.pity-five-pos { display: inline-flex; align-items: center; gap: var(--s-2); font-size: var(--fs-label); color: var(--text-2); }
.pity-five-pos input { width: 5rem; }
.pity-five-result { display: flex; flex-wrap: wrap; gap: var(--s-1); }
.pity-five-del { margin-left: auto; }
.pity-none { margin: 0 0 var(--s-2); }
.pity-preview { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--s-1) var(--s-3); margin-top: var(--s-4); padding: var(--s-3) var(--s-4); border: 1px solid var(--line); border-left-color: var(--cyan-line); border-radius: var(--r); background: var(--panel); font-size: var(--fs-sm); color: var(--text-2); }
.pity-preview.is-bad { border-left-color: var(--danger-line); background: var(--danger-bg); color: var(--text); }
.pity-preview-lead { font: 600 var(--fs-body)/1.3 var(--serif); color: var(--text); }
.pity-preview-note { flex-basis: 100%; color: var(--muted); }
.pity-rules { margin-top: var(--s-6); }
.pity-rules summary { gap: var(--s-3); }
.pity-rules-list { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--s-3); }
.pity-rule { font-size: var(--fs-sm); color: var(--text-2); line-height: var(--lh-body); }
.pity-rule .badge { margin-right: var(--s-1); }
.pity-rule-src { color: var(--gold); }
#pity-message { margin-top: var(--s-4); }
@media (prefers-reduced-motion: reduce) { .pity-meter-fill { transition: none; } }

/* =====================================================================================
   v1.3.0 pull planner (js/ui-planner.js): goal editors side by side, then the results: one headline figure, the tier
   table (also the chart's table view), the cumulative chance curve with budget markers. Tokens only; not a card.
   ===================================================================================== */
.plan-goals { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 19rem), 1fr)); align-items: start; gap: var(--s-5); margin-top: var(--s-5); }
.plan-goal { min-width: 0; padding: var(--s-5); border: 1px solid var(--line); border-radius: var(--r); background: var(--panel-2); }
.plan-goal-character { border-top-color: var(--radiant); }
.plan-goal-weapon { border-top-color: var(--forging); }
.plan-goal-title { margin: 0 0 var(--s-3); font: 600 var(--fs-lg)/1.3 var(--serif); color: var(--text); }
.plan-goal select, .plan-goal input { width: 100%; }
.plan-goal .field-row.two { grid-template-columns: repeat(auto-fit, minmax(min(100%, 9rem), 1fr)); }
.plan-coral-hint { margin-top: var(--s-2); }
.plan-results { margin-top: var(--s-6); }
.plan-empty { color: var(--muted); font-size: var(--fs-sm); }
.plan-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--s-2) var(--s-4); }
.plan-big { margin: 0; font: 500 var(--fs-data)/1.1 var(--serif); color: var(--gold-hi); font-variant-numeric: tabular-nums; }
.plan-head-text { margin: 0; flex: 1 1 18rem; font-size: var(--fs-sm); color: var(--text-2); max-width: var(--measure); }
.plan-tiers { width: 100%; max-width: 40rem; margin-top: var(--s-4); border-collapse: collapse; font-size: var(--fs-sm); }
.plan-tiers caption { text-align: left; font-size: var(--fs-xs); letter-spacing: 0.07em; text-transform: uppercase; color: var(--muted); padding-bottom: var(--s-2); }
.plan-tiers th, .plan-tiers td { padding: var(--s-2) var(--s-3) var(--s-2) 0; border-bottom: 1px solid var(--line-3); text-align: left; font-weight: 500; color: var(--text-2); }
.plan-tiers thead th { font-size: var(--fs-xs); color: var(--muted); font-weight: 600; }
.plan-tiers .num { text-align: right; font-variant-numeric: tabular-nums; color: var(--text); }
.plan-tiers .tier-estimated th, .plan-tiers .tier-estimated td { color: var(--text); font-weight: 600; }
.plan-need, .plan-short, .plan-sens { margin: var(--s-3) 0 0; font-size: var(--fs-sm); color: var(--text-2); max-width: var(--measure); }
.plan-short.is-short { padding-left: var(--s-3); border-left: 1px solid var(--danger-line); color: var(--text); }
.plan-chart { margin: var(--s-5) 0 0; max-width: 44rem; }
.plan-chart-title { font-size: var(--fs-sm); font-weight: 600; color: var(--text-2); margin-bottom: var(--s-2); }
.plan-chart-wrap { position: relative; }
.plan-chart svg { display: block; max-width: 100%; height: auto; overflow: visible; }   /* drawn at the width it gets */
.plan-grid { stroke: var(--line-3); stroke-width: 1; }
.plan-axis { fill: var(--muted); font-size: var(--fs-xs); font-family: var(--sans); }
.plan-curve { fill: none; stroke: var(--gold-hi); stroke-width: 2; stroke-linejoin: round; }
.plan-marker { stroke: var(--text-2); stroke-width: 1; stroke-dasharray: 4 3; }
.plan-marker-confirmed { stroke-dasharray: 1 3; }
.plan-marker-optional { stroke: var(--muted); }
.plan-marker-label { fill: var(--text-2); font-size: var(--fs-xs); font-family: var(--sans); }
.plan-cross { stroke: var(--muted); stroke-width: 1; }
.plan-dot { fill: var(--gold-hi); stroke: var(--panel); stroke-width: 2; }
.plan-hit { fill: transparent; cursor: crosshair; }
.plan-tip { position: absolute; top: 0; transform: translate(-50%, calc(-100% - var(--s-3))); padding: var(--s-1) var(--s-2); border: 1px solid var(--line-2); border-radius: var(--r); background: var(--raised); font-size: var(--fs-xs); color: var(--text); white-space: nowrap; pointer-events: none; }
.plan-chart-note { margin-top: var(--s-2); }
.plan-assumptions { margin-top: var(--s-6); }
.plan-assumptions summary { gap: var(--s-3); }
.plan-assumptions-list { margin: 0; padding-left: var(--s-5); display: grid; gap: var(--s-2); font-size: var(--fs-sm); color: var(--text-2); }
@media (forced-colors: active) { .plan-curve { stroke: CanvasText; } .plan-marker { stroke: GrayText; } }

/* =====================================================================================
   v1.3.1 planner board (js/ui-board.js): the Timeline chart's frame, axis and bars (shared classes) with a pulls lane
   and a points lane. v1.3.2: a creation toolbar above, the point list below, the hover / tap preview line, and the
   selected point in a drawer (the event editor's .confirm.drawer; full screen on phones). Only the board scrolls sideways.
   Tokens only; not a card (no tilt, no holo).
   ===================================================================================== */
.board { margin-top: var(--s-4); display: grid; grid-template-columns: minmax(0, 1fr); align-items: start; }
.board-main.chrono { margin-top: 0; min-width: 0; }
.board-canvas { cursor: crosshair; }
.board-lane-banners .chrono-bar { cursor: crosshair; }
.board-empty-lane { margin: var(--s-2) var(--s-4); font-size: var(--fs-sm); color: var(--muted); }
.board-lane-pulls .board-pulls { display: block; }
.board-line-nothing { fill: none; stroke: var(--gold); stroke-width: 1; stroke-dasharray: 4 3; opacity: 0.8; }
.board-line-plan { fill: none; stroke: var(--gold-hi); stroke-width: 2; stroke-linejoin: round; }
.board-band { fill: var(--gold-lo); stroke: none; }
.board-short { fill: var(--danger-bg); stroke: var(--danger-line); stroke-width: 1; }
.board-short-tag { fill: var(--danger); }
.board-points-row { position: relative; height: 4.5rem; }
.board-link { position: absolute; top: 1.5rem; height: 0; border-top: 1px dashed var(--line-2); }
.board-link.is-route { border-top: 2px solid var(--gold); }
.board-link-tag { position: absolute; left: 50%; top: var(--s-1); transform: translateX(-50%); padding: 0 var(--s-2); font-size: var(--fs-xs); color: var(--gold-hi); background: var(--panel-2); white-space: nowrap; }
.board-point { position: absolute; top: calc(var(--nudge, 0) * var(--s-2)); transform: translateX(-50%); margin-left: calc(var(--nudge, 0) * var(--s-7)); display: flex; flex-direction: column; align-items: center; gap: var(--s-1); padding: 0; border: 0; background: none; color: var(--text); cursor: grab; touch-action: none; z-index: 6; }
.board-point-num { display: grid; place-items: center; width: 2rem; height: 2rem; border-radius: 50%; border: 1px solid var(--gold-line); background: var(--panel); font: 600 var(--fs-label)/1 var(--serif); color: var(--gold-hi); }
.board-point-chip { padding: 0 var(--s-2); border: 1px solid var(--line-2); background: var(--panel); font-size: var(--fs-xs); font-weight: 600; color: var(--text); font-variant-numeric: tabular-nums; }
.board-point.is-blocked .board-point-num { border-style: dashed; border-color: var(--danger-line); color: var(--danger); }
.board-point.is-blocked .board-point-chip { color: var(--danger); border-color: var(--danger-line); }
.board-point.is-selected .board-point-num { background: var(--gold); color: #0b0a08; border-color: var(--gold); box-shadow: 0 0 0 3px var(--gold-lo); }
.board-point:focus-visible { outline: none; }
.board-point:focus-visible .board-point-num { outline: 2px solid var(--focus); outline-offset: 2px; }
.chrono-line.board-now { border-left: 2px solid var(--gold-hi); }
.chrono-line.board-now .chrono-line-tag { color: var(--gold-hi); }
.chrono-line.board-deadline { border-left: 1px dashed var(--gold); }
.chrono-line.board-deadline .chrono-line-tag { color: var(--gold); }
.chrono-line.board-sel-line { border-left: 1px dashed var(--gold); opacity: 0.7; }
.board-panel-body > .subhead.board-kicker { margin: 0 0 var(--s-3); font-size: var(--fs-sm); color: var(--gold); }
.board-panel-title { margin: 0; font: 600 var(--fs-lg)/1.3 var(--serif); color: var(--text); }
.board-panel-head { display: flex; align-items: center; gap: var(--s-3); margin-bottom: var(--s-2); }
.board-panel-head .board-panel-title { flex: 1 1 auto; min-width: 0; }
.board-panel-nav { display: flex; gap: var(--s-1); flex: none; }
.board-panel-summary { margin: var(--s-2) 0 var(--s-4); font-size: var(--fs-sm); color: var(--text-2); }
.board-panel-summary strong { font: 500 var(--fs-data)/1 var(--serif); color: var(--gold-hi); margin-right: var(--s-2); }
.board-panel-body .subhead.board-section-title { margin: var(--s-6) 0 var(--s-3); font-size: var(--fs-sm); color: var(--gold); }
.board-settings > .subhead.board-section-title { margin-top: var(--s-5); }
.board-results { margin-top: var(--s-6); padding-top: var(--s-2); border-top: 1px solid var(--line-3); }
.board-group { margin: var(--s-6) 0 0; padding: var(--s-5) 0 0; border: 0; border-top: 1px solid var(--line-3); min-width: 0; }
.board-settings > .board-group:first-of-type { margin-top: 0; padding-top: 0; border-top: 0; }
.board-group-title { float: left; width: 100%; margin: 0 0 var(--s-4); padding: 0; font: 500 var(--fs-lg)/1.3 var(--serif); color: var(--text); }
.board-group-title + * { clear: left; }
.board-group .field { margin-bottom: var(--s-3); }
.board-group .field-row { margin-bottom: 0; }
.board-group > .hint { margin: 0; }
.board-group select, .board-group input:not([type="checkbox"]), .board-settings input:not([type="checkbox"]) { width: 100%; }
/* (v1.3.5: the v1.3.3 uneven three-column override for the drawer's "You own" is gone: the drawer uses a two-column row since v1.3.4, and it squeezed "Subscription claims") */
.board-exact { max-width: 12rem; }
.board-goal .field-row.two { grid-template-columns: repeat(auto-fit, minmax(min(100%, 8rem), 1fr)); }
.board-carried { margin: 0 0 var(--s-3); }
.board-delete { margin-top: var(--s-6); padding-top: var(--s-5); border-top: 1px solid var(--line-3); }
.board-delete-confirm { margin: 0; }
.board-confirm { margin: 0 0 var(--s-2); font-size: var(--fs-sm); color: var(--text); }
.board-route { margin: var(--s-3) 0 0; padding-left: var(--s-3); border-left: 1px solid var(--gold-line); font-size: var(--fs-sm); color: var(--text-2); }
.board-stats { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.3fr); gap: var(--s-3) var(--s-5); margin: var(--s-4) 0 0; font-size: var(--fs-sm); line-height: 1.45; }
.board-stats dt { color: var(--muted); }
.board-stats dd { margin: 0; color: var(--text); font-variant-numeric: tabular-nums; }
.board-results .plan-chart svg, .board-hist svg { max-width: 100%; height: auto; }
.board-outcomes, .board-hist { margin: var(--s-5) 0 0; }
.board-obar { display: flex; height: var(--s-3); gap: 2px; background: var(--line-3); }
.board-oseg { display: block; height: 100%; min-width: 2px; }
.board-olegend { display: flex; flex-wrap: wrap; gap: var(--s-1) var(--s-4); margin: var(--s-2) 0 0; padding: 0; list-style: none; font-size: var(--fs-xs); color: var(--text-2); }
.board-oswatch { display: inline-block; width: var(--s-2); height: var(--s-2); margin-right: var(--s-1); background: currentColor; }
.seg-both { color: var(--gold); } .board-oseg.seg-both { background: var(--gold); }
.seg-char { color: var(--radiant); } .board-oseg.seg-char { background: var(--radiant); }
.seg-weap { color: var(--forging); } .board-oseg.seg-weap { background: var(--forging); }
.seg-mg { color: var(--cyan); } .board-oseg.seg-mg { background: var(--cyan); }
.seg-miss { color: var(--muted); } .board-oseg.seg-miss { background: var(--muted); }
.board-olegend li { color: var(--text-2); }
.board-olegend li .board-oswatch { color: inherit; }
.board-olegend .seg-both .board-oswatch { color: var(--gold); } .board-olegend .seg-char .board-oswatch { color: var(--radiant); }
.board-olegend .seg-weap .board-oswatch { color: var(--forging); } .board-olegend .seg-mg .board-oswatch { color: var(--cyan); }
.board-olegend .seg-miss .board-oswatch { color: var(--muted); }
.board-bar { fill: var(--gold); opacity: 0.75; }
.board-bar.is-clipped { opacity: 1; stroke: var(--gold-hi); stroke-dasharray: 2 2; }
.board-assume { margin-top: var(--s-6); }
.board-assume summary { gap: var(--s-3); }
.board-coral { margin-top: var(--s-5); }
.board-sub { margin: 0 0 var(--s-2); font-size: var(--fs-label); font-weight: 600; color: var(--text); }
.board-coral > .choice-group { margin-bottom: var(--s-4); }
.board-coral > .hint { margin: var(--s-2) 0 0; }
.board-callout { margin-top: var(--s-2); padding: var(--s-1) 0 var(--s-1) var(--s-4); border-left: 1px solid var(--gold-line); }
.board-callout .board-stats { margin-top: 0; }
.board-callout .hint { margin: var(--s-3) 0 0; }
/* v1.3.2 toolbar: add at a significant date or on a date; the snap toggles */
.board-toolbar { margin-top: var(--s-5); padding: var(--s-4) var(--s-5); border: 1px solid var(--line); background: var(--panel-2); }
.board-tool-label { margin: 0; font-size: var(--fs-xs); font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase; color: var(--gold); }
.board-toolbar > .board-tool-label { margin-bottom: var(--s-3); }
.board-add-row { display: grid; grid-template-columns: minmax(0, 1.8fr) auto minmax(0, 1fr) minmax(0, 0.8fr) auto; align-items: end; gap: var(--s-2) var(--s-4); min-width: 0; }
.board-add-row .field { margin: 0; }
.board-add-row select, .board-add-row input { width: 100%; }
.board-or { padding-bottom: var(--s-3); font-size: var(--fs-sm); color: var(--muted); }
.board-add-btn { min-width: 6rem; }
.board-add-hint { margin: var(--s-2) 0 0; }
.board-snap { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-2) var(--s-3); margin-top: var(--s-4); padding-top: var(--s-3); border-top: 1px solid var(--line-3); min-width: 0; }
.board-snap .choice-group { display: flex; flex-wrap: wrap; gap: var(--s-2); }
.board-points-jump { margin-left: auto; }
/* the preview line (exactly where a click adds the point) and its chip */
.board-preview { position: absolute; top: 0; bottom: 0; left: 0; width: 0; border-left: 2px solid var(--gold-hi); opacity: 0.85; pointer-events: none; z-index: 7; }
.board-preview.is-edge { box-shadow: 0 0 0 1px var(--gold-lo); }
.board-chip { position: absolute; left: 0; top: 0; will-change: transform; transition: transform 170ms var(--ease-ui); z-index: 8; display: grid; gap: var(--s-1); box-sizing: border-box; width: max-content; max-width: min(20rem, calc(100vw - 2rem)); padding: var(--s-2) var(--s-3); border: 1px solid var(--gold-line);
  background: rgba(10, 10, 9, 0.94); font-size: var(--fs-xs); line-height: 1.4; color: var(--text-2); pointer-events: none; white-space: normal; overflow-wrap: anywhere; }
.board-chip > * { min-width: 0; }
.board-chip-title { font-size: var(--fs-sm); color: var(--gold-hi); }
.board-chip-line { color: var(--text); }
.board-chip-note { color: var(--muted); }
.board-chip-actions { display: flex; gap: var(--s-2); margin-top: var(--s-1); pointer-events: auto; }
/* motion: the line and the chip glide (transforms only); they fade in where they appear; a changed line settles in from
   a soft blur. Reduced motion: none of it. */
.board-chip.is-in { animation: preview-in 140ms ease-out; }   /* the line itself never moves or fades: it is exactly where it adds */
.board-chip > .is-swap { animation: chip-swap 220ms var(--ease-ui); }
@keyframes preview-in { from { opacity: 0; } }
@keyframes chip-swap { from { opacity: 0.25; filter: blur(4px); transform: translateY(2px); } }
@media (prefers-reduced-motion: reduce) {
  .board-chip { transition: none; }
  .board-chip.is-in, .board-chip > .is-swap { animation: none; }
}
.board-undo { margin-left: var(--s-3); }
.board-added { margin: 0 0 var(--s-3); }
/* the point list: the site's item cards (date tile, serif heading, badges, card action row) */
.board-points { margin-top: var(--s-7); }
.board-points-title { margin: 0 0 var(--s-1); font: 500 var(--fs-lg)/1.3 var(--serif); color: var(--text); }
.board-item { border-left-color: var(--gold-line); }
.board-item.is-current { border-left-color: var(--gold); }
.board-item.is-blocked { border-left-color: var(--danger-line); }
.board-item > p.board-item-result { margin-top: var(--s-2); color: var(--text-2); }
.board-item-p { font: 500 var(--fs-xl)/1 var(--serif); color: var(--gold-hi); margin-right: var(--s-1); }
.board-item.is-blocked .board-item-result { color: var(--danger); }
.board-item .card-actions { margin-top: var(--s-3); }
.board-item[draggable="true"] { cursor: grab; }
#board-message .btn { vertical-align: middle; }
@media (max-width: 999.98px) {
  .board-points-row { height: 4rem; }
}
@media (max-width: 520px) {
  .field-row.three { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .field-row.three > .field:last-child:nth-child(odd) { grid-column: 1 / -1; }
  .board-stats { grid-template-columns: minmax(0, 1fr); gap: var(--s-1); }
  .board-stats dd { margin-bottom: var(--s-2); }
}
/* narrow toolbars: the key date on its own row, then date and time side by side, then Add */
@media (max-width: 719.98px) {
  .board-toolbar { padding: var(--s-4); }
  .board-add-row { grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr); }
  .board-add-at, .board-add-btn { grid-column: 1 / -1; }
  .board-or { grid-column: 1 / -1; padding: 0; }
}
@media (forced-colors: active) { .board-line-plan { stroke: CanvasText; } .board-point-num { forced-color-adjust: auto; } .board-preview { border-left-color: Highlight; } }

/* =====================================================================================
   v1.3.3 inventory and portraits (js/ui-inventory.js, kit.portrait): circular portraits that show the name's initial
   until the image (assets/portraits/...) is found; the inventory as item cards, two columns on wide screens; Rover's
   forms in a 2 x 2 grid. Busy places (the board's bars and markers, Timeline banner cards) show a portrait only once
   its image exists. Tokens only; not a card of its own (no tilt, no holo).
   ===================================================================================== */
.portrait { --pt: 2.5rem; display: inline-grid; place-items: center; flex: none; width: var(--pt); height: var(--pt); border-radius: 50%;
  border: 1px solid var(--gold-line); background: var(--panel) center / cover no-repeat; overflow: hidden; vertical-align: middle; }
.portrait-28 { --pt: 1.75rem; } .portrait-32 { --pt: 2rem; } .portrait-40 { --pt: 2.5rem; } .portrait-56 { --pt: 3.5rem; }
.portrait-initial { font: 600 var(--fs-sm)/1 var(--serif); color: var(--gold-hi); }
.portrait-56 .portrait-initial { font-size: var(--fs-lg); }
.portrait.has-img .portrait-initial { visibility: hidden; }
.portrait-only-image:not(.has-img) { display: none; }
/* The segmented bar (kit.segmented): one choice from a short list, in the tab bar's language. */
.segbar { display: flex; gap: 2px; padding: 2px; border: 1px solid var(--line); border-radius: var(--r); background: rgba(0, 0, 0, 0.35); min-width: 0; }
.seg-btn { flex: 1 1 0; min-width: 0; min-height: 1.75rem; padding: 0 var(--s-1); border: 0; border-radius: var(--r); background: transparent;
  color: var(--muted); font: 600 var(--fs-xs)/1 var(--sans); font-variant-numeric: tabular-nums; white-space: nowrap; cursor: pointer;
  transition: background-color var(--dur-base) var(--ease), color var(--dur-base) var(--ease); }
.seg-btn:hover { color: var(--text); background: rgba(255, 255, 255, 0.05); }
.seg-btn.is-on { color: #0b0a08; background: var(--gold); }
.seg-btn:focus-visible { outline: 2px solid var(--gold-hi); outline-offset: 1px; }

/* Element tints: card backgrounds only (the figure's glow), never text. */
:root { --el-spectro: #e8cf6a; --el-havoc: #c2477f; --el-aero: #4fd1a5; --el-electro: #a57cf0; --el-fusion: #ef6a45; --el-glacio: #6cc4f2; }
.inv-tools { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: var(--s-3) var(--s-5); margin-top: var(--s-4); }
.inv-tools .inv-filter { margin: 0; }
.inv-count { margin: 0; color: var(--muted); font-size: var(--fs-sm); font-variant-numeric: tabular-nums; }
.inv-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s-3); }
@media (min-width: 600px) { .inv-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (min-width: 800px) { .inv-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
@media (min-width: 1000px) { .inv-grid { grid-template-columns: repeat(5, minmax(0, 1fr)); } }
@media (min-width: 1200px) { .inv-grid { grid-template-columns: repeat(6, minmax(0, 1fr)); } }

/* The card: ONE fixed size (2:3) whatever it holds. The art fills it; the name and the bars sit over its bottom fade,
   so Add, the Sequence bar and the weapon bar never make a card taller. */
.inv-grid > .inv-card { --el-c: var(--gold); position: relative; aspect-ratio: 2 / 3; padding: 0; overflow: hidden; border: 1px solid var(--line-soft); border-left-width: 1px;
  background: var(--panel-2); }
.inv-card[data-el="spectro"] { --el-c: var(--el-spectro); } .inv-card[data-el="havoc"] { --el-c: var(--el-havoc); }
.inv-card[data-el="aero"] { --el-c: var(--el-aero); } .inv-card[data-el="electro"] { --el-c: var(--el-electro); }
.inv-card[data-el="fusion"] { --el-c: var(--el-fusion); } .inv-card[data-el="glacio"] { --el-c: var(--el-glacio); }
.inv-art { position: absolute; inset: 0; display: grid; place-items: start center; padding-top: 14%; overflow: hidden;
  background: radial-gradient(70% 50% at 50% 32%, color-mix(in srgb, var(--el-bg) 30%, transparent), transparent 75%), linear-gradient(180deg, color-mix(in srgb, var(--el-bg) 10%, var(--panel-2)), var(--panel-2)); }
.inv-art::before { content: ""; position: absolute; inset: auto 0 0; height: 62%; z-index: 3; pointer-events: none;
  background: linear-gradient(180deg, transparent, color-mix(in srgb, var(--panel-2) 78%, transparent) 45%, var(--panel-2) 78%); }
.inv-figure { position: absolute; inset: 0; z-index: 2; background: center top / cover no-repeat; }
.inv-art.has-figure > .portrait { display: none; }
.inv-art > .portrait { --pt: 5.5rem; position: relative; z-index: 2; }
.inv-art > .portrait .portrait-initial { font-size: var(--fs-xl); }
.inv-info { position: absolute; inset: auto 0 0; z-index: 4; display: flex; flex-direction: column; gap: var(--s-2); padding: 0 var(--s-2) var(--s-2); min-width: 0; }
.inv-name { display: flex; align-items: baseline; gap: var(--s-2); min-width: 0; }
/* v1.3.5: the name larger, in capitals, in a very light version of the element's colour (dimmer when not owned); a long
   name wraps at its words onto a second line (the controls sit at the card's foot, so it only covers more of the art) */
.inv-name { align-items: flex-end; }
.inv-name h3 { flex: 1 1 auto; min-width: 0; margin: 0; font: 600 var(--fs-lg)/1.15 var(--serif); text-transform: uppercase; letter-spacing: 0.025em;
  color: color-mix(in srgb, var(--el-c) 16%, #fff); text-shadow: 0 1px 6px rgba(0, 0, 0, 0.75);
  white-space: normal; overflow-wrap: normal; word-break: normal; text-wrap: balance;
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; overflow: hidden; }
@media (max-width: 599.98px) { .inv-name h3 { font-size: var(--fs-label); letter-spacing: 0.015em; } }
.inv-chip { flex: none; font-size: var(--fs-xs); font-weight: 600; color: var(--gold-hi); font-variant-numeric: tabular-nums; }
.inv-rarity { position: absolute; top: var(--s-2); left: var(--s-2); z-index: 5; padding: 0 var(--s-1); border-radius: var(--r); background: rgba(3, 3, 4, 0.55);
  font-size: var(--fs-xs); line-height: 1.6; color: var(--gold-hi); letter-spacing: 0.02em; }
.inv-card.is-four .inv-rarity { color: var(--text-2); }
.inv-info .seg-btn { min-height: 1.5rem; padding: 0; }   /* equal flex segments: no side padding, so labels fit at 320px */
.inv-add { display: inline-flex; align-items: center; justify-content: center; gap: var(--s-1); width: 100%; }
.inv-add-icon { font-weight: 700; }
.inv-weapon { display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: center; gap: var(--s-1); }
.inv-weapon > .portrait { --pt: 1.5rem; }
@media (max-width: 599.98px) { .inv-art { padding-top: 10%; } .inv-art > .portrait { --pt: 4rem; } .inv-art > .portrait .portrait-initial { font-size: var(--fs-lg); } }
.inv-forms .seg-btn.has-own { color: var(--text); }
.inv-forms .seg-btn { position: relative; }
.inv-forms .seg-btn.has-own::after { content: ""; position: absolute; top: 0.2rem; right: 0.2rem; width: 0.25rem; height: 0.25rem; border-radius: 50%; background: currentColor; }   /* a corner dot: never widens the label */
.inv-unown { position: absolute; top: var(--s-2); right: var(--s-2); z-index: 5; display: grid; place-items: center; width: 1.75rem; height: 1.75rem; padding: 0;
  border: 1px solid var(--line); border-radius: 50%; background: rgba(3, 3, 4, 0.6); color: var(--text-2); font-size: var(--fs-label); line-height: 1; cursor: pointer;
  opacity: 0.7; transition: opacity var(--dur-base) var(--ease), color var(--dur-base) var(--ease); }
.inv-unown:hover, .inv-unown:focus-visible { opacity: 1; color: var(--danger); }
.inv-unown:focus-visible { outline: 2px solid var(--gold-hi); outline-offset: 1px; }

/* Not owned: very faint red stripes, the art muted, and the card's own tint darker and greyer. --el-bg is a registered
   colour, so a card that changes state can fade its tint (the card itself is rebuilt, so this is a keyframe). */
@property --el-bg { syntax: '<color>'; inherits: true; initial-value: #ba975c; }
.inv-card { --el-bg: var(--el-c); }
.inv-card:not(.is-owned) { --el-bg: color-mix(in srgb, var(--el-c) 22%, #1c1c1c); }
@keyframes inv-tint-in { from { --el-bg: color-mix(in srgb, var(--el-c) 22%, #1c1c1c); } to { --el-bg: var(--el-c); } }
@keyframes inv-tint-out { from { --el-bg: var(--el-c); } to { --el-bg: color-mix(in srgb, var(--el-c) 22%, #1c1c1c); } }
#inv-list > .inv-card.just-owned { animation: inv-tint-in 520ms var(--ease) both; }      /* on the card: the art and the edge glow fade together */
#inv-list > .inv-card.just-unowned { animation: inv-tint-out 520ms var(--ease) both; }
/* Not owned: very faint red stripes, the art muted. */
.inv-card:not(.is-owned) .inv-art::after { content: ""; position: absolute; inset: 0; z-index: 3; pointer-events: none;
  background: repeating-linear-gradient(135deg, rgba(255, 100, 103, 0.065) 0 2px, transparent 2px 11px); }
.inv-card:not(.is-owned) .inv-figure, .inv-card:not(.is-owned) .inv-art > .portrait { filter: grayscale(0.75) brightness(0.7); }
.inv-card:not(.is-owned) .inv-name h3 { color: color-mix(in srgb, var(--el-c) 12%, var(--text-2)); }
#inv-empty, #inv-unknown { margin-top: var(--s-4); }
/* v1.3.4: the card's edges. An inward glow along the border in the element's colour (fainter when not owned), and the
   pointer's border light in a brightened element colour (the overview tiles' light, recoloured for these cards only). */
.inv-card { --el-hi: color-mix(in srgb, var(--el-c) 62%, #fff); }
.inv-grid > .inv-card::before { content: ""; position: absolute; inset: 0; z-index: 6; pointer-events: none;
  box-shadow: inset 0 0 0 1px var(--inv-ring), inset 0 0 28px -8px color-mix(in srgb, var(--el-bg) 55%, transparent); }
/* the outline keeps its own colour; the inward glow is the background's colour (--el-bg), so it darkens and greys with it */
.inv-card { --inv-ring: color-mix(in srgb, var(--el-c) 26%, transparent); }
.inv-card:not(.is-owned) { --inv-ring: color-mix(in srgb, var(--el-c) 12%, transparent); }
/* the light sits on the card's own edge (inside it: the card clips what lies outside), over the card's tinted
   background but under the character, the name and the controls (owner), so the edge and the space around the figure
   near the pointer brighten to --el-hi, a brighter version of the outline's element colour */
#inv-list > .inv-card::after {
  inset: 0; z-index: 1; border-left-width: 1.5px;
  border-width: 1.5px;
  border-image: radial-gradient(190px circle at var(--gx, 50%) var(--gy, 50%), var(--el-hi), var(--el-hi) 18%, color-mix(in srgb, var(--el-hi) 65%, transparent) 38%, color-mix(in srgb, var(--el-c) 30%, transparent) 58%, transparent 76%) 1;
  background:
    radial-gradient(130px circle at var(--gx, 50%) var(--gy, 50%), color-mix(in srgb, var(--el-hi) 14%, transparent), transparent 70%),
    linear-gradient(115deg, transparent calc(var(--gx, 50%) - 24%), color-mix(in srgb, var(--el-hi) 9%, transparent) var(--gx, 50%), transparent calc(var(--gx, 50%) + 24%));
}
/* switched on while the pointer is over the card: the shared ".fx-hover::after" is weaker than the list cards' own
   hidden state, so the inventory turns it on itself (touch screens keep it off, like the tiles) */
#inv-list > .inv-card.fx-hover::after { opacity: 1; }
@media (hover: none), (pointer: coarse) { #inv-list > .inv-card.fx-hover::after { opacity: 0; } }
/* v1.3.5: the same for the other list cards (events, Timeline cards, endgames, pull points): their light never showed */
#event-list > li.fx-hover::after, #tl-list > li.fx-hover::after, #eg-list > li.fx-hover::after, #board-list > li.fx-hover::after { opacity: 1; }
@media (hover: none), (pointer: coarse) { #event-list > li.fx-hover::after, #tl-list > li.fx-hover::after, #eg-list > li.fx-hover::after, #board-list > li.fx-hover::after { opacity: 0; } }
/* v1.3.4 motion: a card that just changed state eases into it; nothing snaps */
@keyframes inv-color-in { from { filter: grayscale(0.75) brightness(0.7); } to { filter: none; } }
@keyframes inv-color-out { from { filter: none; } to { filter: grayscale(0.75) brightness(0.7); } }
@keyframes inv-fade-out { from { opacity: 1; } to { opacity: 0; } }
@keyframes inv-fade-in { from { opacity: 0; } to { opacity: 1; } }
.inv-card.just-owned .inv-figure, .inv-card.just-owned .inv-art > .portrait { animation: inv-color-in 520ms var(--ease) both; }
.inv-card.just-owned .inv-art::after { content: ""; position: absolute; inset: 0; z-index: 3; pointer-events: none;
  background: repeating-linear-gradient(135deg, rgba(255, 100, 103, 0.065) 0 2px, transparent 2px 11px); animation: inv-fade-out 520ms var(--ease) both; }
.inv-card.just-unowned .inv-figure, .inv-card.just-unowned .inv-art > .portrait { animation: inv-color-out 520ms var(--ease) both; }
.inv-card.just-unowned .inv-art::after { animation: inv-fade-in 520ms var(--ease) both; }
.inv-card.just-owned .inv-info > *, .inv-card.just-unowned .inv-info > *, .inv-card.just-changed .inv-info > *, .inv-card.just-owned .inv-unown { animation: state-in var(--dur-state) var(--ease) both; }
.inv-card.just-owned .inv-info > :nth-child(3), .inv-card.just-changed .inv-info > :nth-child(3) { animation-delay: 60ms; }
@media (prefers-reduced-motion: reduce) {
  .inv-card[class*="just-"] .inv-figure, .inv-card[class*="just-"] .inv-art > .portrait, .inv-card[class*="just-"] .inv-art::after,
  .inv-card[class*="just-"] .inv-info > *, .inv-card[class*="just-"] .inv-unown, #inv-list > .inv-card[class*="just-"] { animation: none; }
  .inv-card.just-owned .inv-art::after { display: none; }
}
@media (forced-colors: active) { .inv-grid > .inv-card::before { display: none; } }
#inv-message .btn { vertical-align: middle; margin-left: var(--s-2); }
@media (forced-colors: active) { .seg-btn.is-on { forced-color-adjust: none; background: Highlight; color: HighlightText; } .inv-card:not(.is-owned) .inv-art::after { display: none; } }
@media (prefers-reduced-motion: reduce) { .seg-btn, .inv-unown { transition: none; } }
/* portraits elsewhere: a marker's portrait takes its badge's place and the number becomes a corner chip; a bar's sits at
   its left; card and drawer headings get one before the title */
.board-point .portrait { order: -1; }
.board-point:has(.portrait.has-img) .board-point-num { position: absolute; top: calc(-1 * var(--s-1)); left: calc(50% + var(--s-2)); width: 1.15rem; height: 1.15rem;
  font-size: var(--fs-xs); z-index: 1; }
.board-point.is-selected .portrait.has-img { box-shadow: 0 0 0 3px var(--gold-lo); border-color: var(--gold); }
.board-lane-banners .chrono-bar .portrait { position: absolute; left: var(--s-1); top: 50%; transform: translateY(-50%); z-index: 1; }
.board-lane-banners .chrono-bar:has(.portrait.has-img) .chrono-bar-name { padding-left: var(--s-8); }
.board-panel-head .portrait, .board-item .portrait, #tl-list .portrait { margin-right: var(--s-1); }

/* =====================================================================================
   v1.3.4 visual pass (the owner's notes and the wudamage.com reference): the page art stays behind the whole page,
   darker and blurred; sections have no box of their own (space and a faint rule separate them); controls are rounded;
   lines are softer; and every state change eases instead of snapping. Cards keep square corners (their border light
   needs them). Tokens only; the card light and its layer at the end of the file are unchanged.
   ===================================================================================== */
/* the page art: fixed behind everything, darker and softly blurred (it no longer stops at the top of the page) */
body::before { position: fixed; inset: -2rem; height: auto; -webkit-mask-image: none; mask-image: none; filter: blur(14px) saturate(0.8); }
html.site-art-patch body::before {
  background:
    linear-gradient(90deg, rgba(3, 3, 4, 0.1) calc(50% - 640px), rgba(3, 3, 4, 0.45) calc(50% - 470px), rgba(3, 3, 4, 0.45) calc(50% + 470px), rgba(3, 3, 4, 0.1) calc(50% + 640px)),
    linear-gradient(180deg, rgba(3, 3, 4, 0.7), rgba(3, 3, 4, 0.8) 35%, rgba(3, 3, 4, 0.9)),
    var(--site-art) center 30% / cover no-repeat;
  opacity: 0.55;
}

/* sections: no box. The content keeps its own surfaces (cards, tiles, fields); a faint rule and space separate them */
/* page sections only: the start pop-up is a .panel too and keeps its surface and padding */
.panel:not(.start-panel) { background: transparent; border-color: transparent; border-top-color: var(--line-3); padding-inline: 0; }
.panel:not(.start-panel):focus-within { border-color: transparent; border-top-color: var(--line-3); }
.results { background: rgba(10, 10, 10, 0.55); -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px); }

/* rounded controls (cards stay square) */
.btn, .tab, .tabbar, .subnav a, .drawer-close, .version, .choice-item span, .filter span, .segbar, .badge, .msg, .confirm,
input[type="text"], input[type="date"], input[type="time"], input[type="number"], select, textarea { border-radius: var(--r-ctl); }
::picker(select) { border-radius: var(--r-ctl); }   /* its own rule: a browser without ::picker drops only this one */
/* the same rounding for the controls the first pass missed (found by an audit of every tab): the header's Guide and
   cache pills, the steppers, the skip link, collapsible boxes; the chart bars take a smaller radius (data, not buttons) */
.guide-btn, .cache-pill, .stepper button, .skip, .compact-details { border-radius: var(--r-ctl); }
.guide-icon { border-radius: var(--r-ctl); }
/* the guide minimised is just its header: equal space above and below, so the count and the icons sit centred */
.guide.is-collapsed .guide-head { padding-bottom: 0.75rem; }
.guide.is-collapsed .guide-count { line-height: 2rem; }
/* pop-ups that scroll clip what lies past their edges, so their content keeps at least 1.75rem on each side at every
   width: a button's glow or focus ring (and the guide's highlight around it) is never cut off (owner) */
.start-overlay .start-panel { padding-inline: 1.75rem; }
/* the start pop-up has no box of its own (owner): it floats on the blurred page; only its padding stays */
.start-overlay .start-panel { background: transparent; border-color: transparent; }
.confirm.drawer { padding-left: 1.75rem; padding-right: 1.75rem; }
.chrono-pop-body { padding-inline: max(var(--s-7), 1.75rem); }
/* the guide's menu has no action bar under it (the bar normally gives the bottom space): the body keeps it instead */
.guide-main:has(+ .guide-actions[hidden]), .guide-main:has(+ .guide-actions:empty) { padding-bottom: 1rem; }
.chrono-bar:not(.is-point) { border-radius: 4px; }
/* nested rounding is concentric (owner): outer radius = inner radius + the gap + the border. Bars of choices (the tab
   bar, "Show pulls for", Timeline | Cards, the segmented bars) have 4px items: 3px padding + 1px border -> 8px outside;
   the segmented bars' 2px padding + 1px border -> 7px */
:root { --r-in: 4px; }
.tabbar, .filter-group { border-radius: calc(var(--r-in) + 4px); }
.tabbar .tab, .filter-group .filter span, .filter-group .pill-slider { border-radius: var(--r-in); }
.segbar { border-radius: calc(var(--r-in) + 3px); }
.seg-btn, .seg-ind { border-radius: var(--r-in); }
.tab-slider { border-radius: 2px; }

/* motion: hover and state changes ease with a little more time; pressed controls keep their quick press */
.choice-item span, .filter span { transition: color var(--dur-state) var(--ease), background-color var(--dur-state) var(--ease), border-color var(--dur-state) var(--ease), box-shadow var(--dur-state) var(--ease), transform var(--dur-fast); }
.btn { transition: background-color var(--dur-state) var(--ease), border-color var(--dur-state) var(--ease), color var(--dur-state) var(--ease), box-shadow var(--dur-state) var(--ease), opacity var(--dur-state) var(--ease), transform var(--dur-fast); }
input, select, textarea { transition: border-color var(--dur-state) var(--ease), box-shadow var(--dur-state) var(--ease), background-color var(--dur-state) var(--ease); }
/* things that appear (confirmations, hints that change, a card's new controls) settle in from a soft blur */
.confirm:not([hidden]) { animation: soft-enter var(--dur-state) var(--ease) both; }
@keyframes state-in { from { opacity: 0; filter: blur(4px); transform: translateY(3px); } }
.state-in { animation: state-in var(--dur-state) var(--ease) both; }

/* the segmented bar's fill is one sliding piece: it glides from the old choice to the new one (kit.segmented) */
.segbar { position: relative; isolation: isolate; }
.seg-ind { position: absolute; top: 2px; bottom: 2px; left: 2px; z-index: -1; border-radius: var(--r-in); background: var(--gold); pointer-events: none;
  width: calc((100% - 4px - (var(--n) - 1) * 2px) / var(--n)); transform: translateX(calc(var(--i) * (100% + 2px)));
  transition: transform var(--dur-state) var(--ease), opacity var(--dur-state) var(--ease); }
.segbar.has-ind .seg-btn.is-on { background: transparent; }
.board-seg { margin-top: var(--s-1); align-self: start; height: auto; } .board-seg .seg-btn { min-height: 2.25rem; } .board-seg-short { max-width: 12rem; }
/* a select shown as a bar (kit.enhanceSelect) stays in the page as the value's source, out of sight */
select.seg-source { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; opacity: 0; pointer-events: none; }
.seg-btn { transition: color var(--dur-state) var(--ease), background-color var(--dur-state) var(--ease); }

/* icons in buttons (kit.icon, class .ic; .ico is the tiles' own icon): inline SVG, current colour */
.ic { width: 1em; height: 1em; flex: none; vertical-align: -0.125em; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.btn .ic { margin-right: 0.4em; }
.btn.has-ico { display: inline-flex; align-items: center; justify-content: center; }

/* good / bad values (owner): a value that is bad is red, otherwise green (chances from 50%, pulls needed against the
   pulls a point can use, a shortfall). Costs and remainders stay neutral. */
.val-good, .plan-big.val-good, .board-item-p.val-good, .board-point-chip.val-good, .board-stats dd.val-good, .board-stats dd .val-good { color: var(--up); }
.val-bad, .plan-big.val-bad, .board-item-p.val-bad, .board-point-chip.val-bad, .board-stats dd.val-bad, .board-stats dd .val-bad { color: var(--danger); }
.board-point-chip.val-good { border-color: var(--up-line); } .board-point-chip.val-bad { border-color: var(--danger-line); }
/* the pulls lane: the worst case (the least left over) as a dotted red line under the band, and a key for the lines */
.board-line-worst { fill: none; stroke: var(--danger); stroke-width: 1.25; stroke-dasharray: 1.5 3; opacity: 0.85; }
.board-key { display: inline-flex; flex-wrap: wrap; gap: var(--s-1) var(--s-3); margin-left: var(--s-3); font-size: var(--fs-xs); color: var(--muted); font-weight: 400; letter-spacing: 0; text-transform: none; }
.board-key-item { display: inline-flex; align-items: center; gap: var(--s-1); white-space: nowrap; }
.board-key-sw { display: inline-block; width: 1.25rem; height: 0; border-top: 2px solid var(--gold-hi); }
.board-key-nothing { border-top: 1px dashed var(--gold); } .board-key-worst { border-top: 2px dotted var(--danger); }
@media (forced-colors: active) { .board-line-worst { stroke: CanvasText; } .val-good, .val-bad { forced-color-adjust: auto; } }

/* the date picker (js/ui-datepicker.js): a calendar button inside every date field, and a calendar in the site's style */
.dp-wrap { position: relative; display: block; min-width: 0; }
.dp-wrap > input[type="date"] { width: 100%; padding-right: 2.6rem; }
input[type="date"]::-webkit-calendar-picker-indicator, input[type="time"]::-webkit-calendar-picker-indicator { display: none; }
.dp-wrap > input[type="time"] { width: 100%; padding-right: 2.6rem; }
.dp-btn { position: absolute; top: 50%; right: 0.3rem; transform: translateY(-50%); display: grid; place-items: center; width: 2rem; height: 2rem; padding: 0;
  border: 0; border-radius: var(--r-ctl); background: transparent; color: var(--gold-hi); cursor: pointer; font-size: var(--fs-label);
  transition: background-color var(--dur-state) var(--ease), color var(--dur-state) var(--ease); }
.dp-btn:hover:not(:disabled), .dp-btn[aria-expanded="true"] { background: var(--gold-lo); }
.dp-btn:focus-visible { outline: 2px solid var(--focus); outline-offset: 1px; }
.dp-btn:disabled { color: var(--muted); cursor: not-allowed; }
.dp-pop { position: fixed; z-index: 90; width: 18.5rem; max-width: calc(100vw - 1rem); padding: var(--s-3); border: 1px solid var(--line-2); border-radius: calc(var(--r-ctl) + 2px);
  background: rgba(12, 12, 11, 0.94); -webkit-backdrop-filter: blur(16px) saturate(1.2); backdrop-filter: blur(16px) saturate(1.2);
  box-shadow: 0 18px 40px -12px rgba(0, 0, 0, 0.8); animation: soft-enter var(--dur-state) var(--ease) both; }
.dp-pop.dp-closing { animation: dp-out 180ms var(--ease) both; pointer-events: none; }
@keyframes dp-out { to { opacity: 0; transform: translateY(4px); filter: blur(4px); } }
.dp-head { display: flex; align-items: center; justify-content: space-between; gap: var(--s-2); margin-bottom: var(--s-2); }
.dp-title { margin: 0; font: 600 var(--fs-label)/1.3 var(--serif); color: var(--text); }
.dp-nav { width: 2rem; height: 2rem; padding: 0; border: 1px solid var(--line); border-radius: var(--r-ctl); background: transparent; color: var(--text-2); font-size: var(--fs-lg); line-height: 1; cursor: pointer;
  transition: background-color var(--dur-state) var(--ease), color var(--dur-state) var(--ease); }
.dp-nav:hover, .dp-nav:focus-visible { background: rgba(255, 255, 255, 0.06); color: var(--text); }
.dp-grid { display: grid; gap: 2px; }
.dp-row { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 2px; }
.dp-wd { padding: var(--s-1) 0; text-align: center; font-size: var(--fs-xs); color: var(--muted); }
.dp-day { aspect-ratio: 1; padding: 0; border: 1px solid transparent; border-radius: var(--r-ctl); background: transparent; color: var(--text-2); font: 500 var(--fs-sm)/1 var(--sans);
  font-variant-numeric: tabular-nums; cursor: pointer; transition: background-color var(--dur-state) var(--ease), color var(--dur-state) var(--ease), border-color var(--dur-state) var(--ease); }
.dp-day:hover:not(:disabled) { background: rgba(255, 255, 255, 0.06); color: var(--text); }
.dp-day:focus-visible { outline: 2px solid var(--focus); outline-offset: 0; }
.dp-day.is-today { border-color: var(--gold-line); color: var(--gold-hi); }
.dp-day.is-on { background: var(--gold); border-color: var(--gold); color: #0b0a08; font-weight: 700; }
.dp-day:disabled { opacity: 0.3; cursor: not-allowed; }
.dp-foot { display: flex; justify-content: space-between; gap: var(--s-2); margin-top: var(--s-2); }
/* the time picker: the same pop-up; an hour grid (6 x 4) and a minute grid (5-minute steps), the chosen time on top */
.tp-pop { width: 17.5rem; }
.tp-head { margin-bottom: var(--s-1); }
.tp-value { margin: 0; font: 600 var(--fs-lg)/1 var(--serif); color: var(--gold-hi); font-variant-numeric: tabular-nums; }
.tp-sec + .tp-sec { margin-top: var(--s-3); }
.tp-label { margin: 0 0 var(--s-1); font-size: var(--fs-xs); color: var(--muted); letter-spacing: 0.04em; text-transform: uppercase; }
.tp-grid { display: grid; gap: 2px; }
.tp-hours { grid-template-columns: repeat(6, minmax(0, 1fr)); }
.tp-minutes { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.tp-cell { min-height: 2rem; padding: 0; border: 1px solid transparent; border-radius: var(--r-ctl); background: transparent; color: var(--text-2); font: 500 var(--fs-sm)/1 var(--sans);
  font-variant-numeric: tabular-nums; cursor: pointer; transition: background-color var(--dur-state) var(--ease), color var(--dur-state) var(--ease); }
.tp-cell:hover { background: rgba(255, 255, 255, 0.06); color: var(--text); }
.tp-cell:focus-visible { outline: 2px solid var(--focus); outline-offset: 0; }
.tp-cell.is-on { background: var(--gold); border-color: var(--gold); color: #0b0a08; font-weight: 700; }
@media (max-width: 599.98px) { .tp-cell { min-height: 1.75rem; } .tp-sec + .tp-sec { margin-top: var(--s-2); } }
@media (prefers-reduced-motion: reduce) { .dp-pop, .dp-pop.dp-closing { animation: none; } .dp-btn, .dp-nav, .dp-day, .tp-cell { transition: none; } }
@media (forced-colors: active) { .dp-day.is-on, .tp-cell.is-on { forced-color-adjust: none; background: Highlight; color: HighlightText; } }

/* graphs (v1.3.4): every graph moves in. The pity meter is a real meter (marks every 10 pulls, 0 / half / hard pity);
   the planner's chance curve draws itself in and its outcome bar grows when the numbers change */
.pity-meter { position: relative; height: 0.625rem; border-radius: 999px; background: rgba(255, 255, 255, 0.06); }
.pity-meter-fill { border-radius: 999px; box-shadow: 0 0 12px -2px var(--pool); }
.pity-tick { position: absolute; top: 2px; bottom: 2px; width: 1px; background: rgba(0, 0, 0, 0.45); }
.pity-scale { display: flex; justify-content: space-between; margin-top: var(--s-1); font-size: var(--fs-xs); color: var(--muted); font-variant-numeric: tabular-nums; }
@keyframes meter-grow { from { transform: scaleX(0); } }
.pity-meter-fill { transform-origin: left center; }
/* entrances play when the graph comes on screen (K.reveal: reveal-wait until then, reveal-go while it plays) */
.pity-meter.reveal-wait .pity-meter-fill { transform: scaleX(0); }
.pity-meter.reveal-go .pity-meter-fill { animation: meter-grow 700ms var(--ease) backwards; animation-delay: 80ms; }
@keyframes curve-draw { from { stroke-dashoffset: 1; } to { stroke-dashoffset: 0; } }
.plan-curve-in { stroke-dasharray: 1; }
.plan-chart.reveal-wait .plan-curve-in { stroke-dashoffset: 1; }
.plan-chart.reveal-go .plan-curve-in { animation: curve-draw 800ms var(--ease) both; }
.plan-chart.reveal-wait .plan-marker, .plan-chart.reveal-wait .plan-marker-label { opacity: 0; }
.plan-chart.reveal-go .plan-marker, .plan-chart.reveal-go .plan-marker-label { animation: state-in var(--dur-state) var(--ease) 450ms both; }
.board-obar .board-oseg { transform-origin: left center; }
.board-obar.reveal-wait .board-oseg { transform: scaleX(0); }
.board-obar.reveal-go .board-oseg { animation: meter-grow 600ms var(--ease) both; }
@media (prefers-reduced-motion: reduce) {
  .pity-meter.reveal-go .pity-meter-fill, .plan-chart.reveal-go .plan-curve-in, .plan-chart.reveal-go .plan-marker, .plan-chart.reveal-go .plan-marker-label, .board-obar.reveal-go .board-oseg { animation: none; }
  .plan-curve-in { stroke-dasharray: none; }
}

/* the Timeline's "Timeline | Cards" switch: the chosen view settles in; the chart's bars grow, the cards rise in turn */
#tl-chart.view-swap, #tl-list.view-swap { animation: state-in var(--dur-state) var(--ease) both; }
#tl-chart.view-swap .chrono-bar { animation: bar-grow 520ms var(--ease) backwards; animation-delay: 80ms; }
#tl-list.view-swap > li { animation: rise 420ms var(--ease) backwards; }
#tl-list.view-swap > li:nth-child(2) { animation-delay: 50ms; } #tl-list.view-swap > li:nth-child(3) { animation-delay: 100ms; }
#tl-list.view-swap > li:nth-child(4) { animation-delay: 150ms; } #tl-list.view-swap > li:nth-child(n+5) { animation-delay: 200ms; }
.pill-slider { transition: transform var(--dur-state) var(--ease), width var(--dur-state) var(--ease), height var(--dur-state) var(--ease); }

/* view entrance: the Timeline's and the board's bars grow in from their start, with the cards */
@keyframes bar-grow { from { clip-path: inset(0 100% 0 0); opacity: 0.4; } }
.reveal-wait .chrono-bar { opacity: 0; }   /* not a clip: a clipped bar can't be hovered or clicked */
.reveal-go .chrono-bar { animation: bar-grow 620ms var(--ease) backwards; animation-delay: 60ms; }

@media (prefers-reduced-motion: reduce) {
  .confirm:not([hidden]), .state-in, .reveal-go .chrono-bar, #tl-chart.view-swap, #tl-list.view-swap, #tl-chart.view-swap .chrono-bar, #tl-list.view-swap > li { animation: none; }
  .pill-slider { transition: none; }
  .seg-ind, .seg-btn, .btn, .choice-item span, .filter span, input, select, textarea { transition: none; }
}
@media (forced-colors: active) { .seg-ind { background: Highlight; } body::before { display: none; } }

/* =====================================================================================
   v1.3.5: events "assumed completed by" a date. Under an assumed category's pill, a "When" row: a bar (By the deadline |
   By a date) and, by a date, its date and optional time. Tokens only.
   ===================================================================================== */
.assume-when { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-2) var(--s-3); margin-top: var(--s-2); }
.assume-when-label { font-size: var(--fs-sm); color: var(--muted); white-space: nowrap; }
.assume-when-bar { flex: 0 1 18rem; min-width: 14rem; }
.assume-when-bar .seg-btn { min-height: 2rem; padding: 0 var(--s-2); font-size: var(--fs-xs); }
.assume-when-field { flex: 0 1 11rem; min-width: 9.5rem; }
.assume-when-hint { flex: 1 1 100%; margin: 0; font-size: var(--fs-xs); }
@media (max-width: 420px) { .assume-when-bar, .assume-when-field { flex: 1 1 100%; min-width: 0; } }
/* the planner's hover: a dot where the pointer's moment meets each line of the Pulls lane */
.board-hover-dot { stroke: var(--bg); stroke-width: 1.5; pointer-events: none; }
.board-hover-dot.dot-nothing { fill: var(--gold); }
.board-hover-dot.dot-plan { fill: var(--gold-hi); }
.board-hover-dot.dot-worst { fill: var(--danger); }
@media (forced-colors: active) { .board-hover-dot { fill: CanvasText; } }
/* the Events and Timeline sort orders as segmented bars */
.sort-seg { max-width: 20rem; margin-top: var(--s-1); }
.sort-seg .seg-btn { min-height: 2.25rem; }
/* the planner's points list: its title and Delete all on one line */
.board-points-head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--s-2) var(--s-4); }
.board-points-head .board-points-title { margin: 0; }
/* the Timeline: where an event is assumed done, a thin green tick inside its bar */
.chrono-done { position: absolute; top: 2px; bottom: 2px; width: 2px; margin-left: -1px; z-index: 2; border-radius: 1px; background: var(--up); box-shadow: 0 0 6px var(--up); pointer-events: none; }

/* =====================================================================================
   v1.1.6 holographic layer (visual only)
   The logo's crystal spectrum (aqua, lilac, periwinkle) is a second, quiet accent that means "projected / live";
   gold still means selected / owned / action. Rules: never on text, never a new animation or loop, no outline on
   every card; light only on projection surfaces (static hairlines) and on interaction (hover sheen, button shine,
   focus halo). Hidden in forced-colors mode; nothing here moves under prefers-reduced-motion.
   ===================================================================================== */
:root {
  --holo-aqua: #bdeff4;
  --holo-lilac: #d9b8f0;
  --holo-blue: #9aa8ea;
  --holo-line: linear-gradient(90deg, transparent, rgba(189, 239, 244, 0.55) 22%, rgba(217, 184, 240, 0.55) 52%, rgba(154, 168, 234, 0.45) 78%, transparent);
  --holo-line-v: linear-gradient(180deg, transparent, rgba(189, 239, 244, 0.45) 22%, rgba(217, 184, 240, 0.45) 52%, rgba(154, 168, 234, 0.35) 78%, transparent);
}

/* ---- projection emphasis: static 1px light on the surfaces that show projected values ---- */
.stage-forecast::before { content: ""; position: absolute; left: 0.9rem; right: 0.9rem; top: -1px; height: 1px; pointer-events: none; background: var(--holo-line); }
.hero-projected { border-left-color: transparent; }
.hero-projected::before { content: ""; position: absolute; left: -1px; top: 0; bottom: 0; width: 1px; pointer-events: none; background: var(--holo-line-v); }
@media (max-width: 640px) {
  .hero-projected { border-top-color: transparent; }
  .hero-projected::before { left: 0; right: 0; top: -1px; bottom: auto; width: auto; height: 1px; background: var(--holo-line); }
}

/* ---- reflected light on interaction (existing hooks only) ---- */
/* card hover (ui-fx.js): a narrow spectral band that follows the pointer (the round gold cursor glow was removed after v1.1.7 review).
   v1.1.7 border light: the same layer is moved onto the card's border (inset -1px + a 1px transparent border) and its
   border-image is a radial light centred on the SAME --gx/--gy as the band, so only the edge near the shine brightens
   and it moves with it. Visible only while .fx-hover is on (this layer's opacity); border-image needs the square
   corners the design uses (--r: 0). */
.sum-tile::after, .stage::after, .item-list > .item::after {
  inset: -1px; border: 1px solid transparent;
  border-image: radial-gradient(150px circle at var(--gx, 50%) var(--gy, 50%), rgba(240, 224, 186, 0.85), rgba(189, 239, 244, 0.5) 28%, rgba(217, 184, 240, 0.28) 48%, transparent 70%) 1;
  background:
    linear-gradient(115deg, transparent calc(var(--gx, 50%) - 24%), rgba(189, 239, 244, 0.06) calc(var(--gx, 50%) - 7%), rgba(217, 184, 240, 0.075) var(--gx, 50%), rgba(154, 168, 234, 0.05) calc(var(--gx, 50%) + 7%), transparent calc(var(--gx, 50%) + 24%));
}
/* items have a 3px coloured left edge: the light ring covers it at the same width */
.item-list > .item::after { inset: -1px -1px -1px -3px; border-left-width: 3px; }
/* primary-button shine: the same single pass, with a thin chromatic fringe */
.btn.shine::after { background: linear-gradient(105deg, transparent 33%, rgba(189, 239, 244, 0.26) 44%, rgba(255, 255, 255, 0.4) 50%, rgba(217, 184, 240, 0.26) 56%, transparent 67%); }
/* tide-bar sweep: the same single pass, with the same fringe */
.tidebar::after { background: linear-gradient(100deg, transparent 30%, rgba(189, 239, 244, 0.32) 44%, rgba(255, 255, 255, 0.5) 50%, rgba(217, 184, 240, 0.32) 56%, transparent 70%); }
/* floating counter: a faint spectral rim on hover only (the gold value and border stay) */
.float-count:hover { box-shadow: 0 6px 24px rgba(0, 0, 0, 0.45), 0 0 18px rgba(186, 151, 92, 0.12), 0 0 0 1px rgba(189, 239, 244, 0.14), 0 0 22px rgba(154, 168, 234, 0.12); }

/* ---- focus: the gold 2px outline is unchanged and stays the strongest cue; a soft aqua halo is added beside it ---- */
.btn.primary:focus-visible { box-shadow: 0 0 24px rgba(186, 151, 92, 0.35), 0 0 16px rgba(189, 239, 244, 0.12); }
.tab:focus-visible { box-shadow: 0 0 0 5px rgba(208, 177, 110, 0.16), 0 0 16px rgba(189, 239, 244, 0.12); }

/* ---- safety nets ---- */
@media (prefers-reduced-motion: reduce) {
  .sum-tile::after, .stage::after, .item-list > .item::after { transition: none; }
}
@media (forced-colors: active) {
  .stage-forecast::before, .hero-projected::before,
  .sum-tile::after, .stage::after, .item-list > .item::after, .btn.shine::after, .tidebar::after { display: none; }
  .hero-projected { border-left-color: CanvasText; }
}
@media (forced-colors: active) and (max-width: 640px) { .hero-projected { border-top-color: CanvasText; } }

