:root{color-scheme:dark;--bg:#0b0605;--panel:#17100d;--panel2:#1f1510;--line:#3a241c;--txt:#efe6dd;--muted:#b9a08f;--red:#c41e1e;--red2:#ff4d2e;--gold:#d8a24a;--gold-dim:#7d5f27;--radius:4px;--font-d:"Cinzel",Georgia,"Times New Roman","Noto Serif TC","Songti TC","PMingLiU",serif}
*{box-sizing:border-box}
body{margin:0;background:radial-gradient(1200px 520px at 50% -140px,#47150c 0%,var(--bg) 58%);color:var(--txt);font-family:"Segoe UI",system-ui,-apple-system,"Noto Sans TC","PingFang TC",sans-serif;line-height:1.55}
a{color:var(--gold)}
:focus-visible{outline:2px solid var(--gold);outline-offset:2px;border-radius:2px}
button{transition:background-color .15s ease,border-color .15s ease,color .15s ease;font:inherit}
input,select{font:inherit;color:var(--txt);background:var(--panel2);border:1px solid var(--line);border-radius:var(--radius);padding:.45rem .55rem;min-height:40px}
input[type=range]{min-height:0;padding:0}
.skip{position:absolute;left:-999px;top:0;background:var(--red);color:#fff;padding:.6rem 1rem;z-index:60;border-radius:0 0 4px 0}
.skip:focus{left:0}
.topbar{max-width:1240px;margin:0 auto;padding:1rem 1.1rem .4rem;display:flex;flex-wrap:wrap;gap:.8rem 1.2rem;align-items:flex-end;justify-content:space-between}
.brand{display:flex;align-items:baseline;gap:.55rem;flex-wrap:wrap}
.brand-mark{color:var(--red2);font-size:1.2rem}
.brand-name{font-family:var(--font-d);font-size:1.45rem;letter-spacing:.04em;color:var(--gold)}
.brand-sub{color:var(--muted);font-size:.82rem}
.top-controls{display:flex;flex-wrap:wrap;gap:.6rem;align-items:flex-end}
.ctl{display:flex;flex-direction:column;gap:.2rem;font-size:.82rem;color:var(--muted)}
.ctl input,.ctl select{min-width:9.5rem}
#titleInput{min-width:13rem}
.lang-btn{background:var(--panel);border:1px solid var(--gold-dim);color:var(--gold);border-radius:var(--radius);padding:.5rem .9rem;min-height:40px;cursor:pointer}
.lang-btn:hover{border-color:var(--gold)}
/* PTR-SWITCH: dataset toggle (segmented) + PTR banner */
.ds-toggle{display:flex;border:1px solid var(--gold-dim);border-radius:var(--radius);overflow:hidden}
.ds-toggle button{background:var(--panel);border:0;color:var(--ink-dim,#b8a88f);padding:.5rem .8rem;min-height:40px;cursor:pointer;font:inherit}
.ds-toggle button + button{border-left:1px solid var(--gold-dim)}
.ds-toggle button.on{background:var(--gold-dim);color:#14100b;font-weight:600}
.ds-toggle button#dsPtr.on{background:#7a4fd0;color:#fff}
.ptr-banner{max-width:1240px;margin:.45rem auto 0;padding:.55rem 1.1rem;border:1px solid #7a4fd0;border-left:4px solid #7a4fd0;border-radius:var(--radius);background:rgba(122,79,208,.12);color:var(--ink);font-size:.85rem}
/* P1-5: library bar */
.libbar{max-width:1240px;margin:.2rem auto 0;padding:.4rem 1.1rem 0}
.lib-row{display:flex;flex-wrap:wrap;gap:.5rem .7rem;align-items:flex-end;margin-bottom:.45rem}
.lib-row .ctl select,.lib-row .ctl input{min-width:9rem}
.lib-row #shareUrl{flex:1 1 18rem;min-width:14rem}
.lib-row .grow{flex:1 1 14rem}
.lib-row .grow input{width:100%}
.lib-row .file-ctl input{min-width:0;max-width:15rem}
.seeds-row{align-items:center;border-top:1px solid #3a2a1a;padding-top:.45rem}
.mx-row{align-items:flex-start}
.mx-row textarea{width:100%;background:var(--panel2,#17100b);border:1px solid var(--line);border-radius:var(--radius);color:inherit;padding:.35rem .5rem;font:inherit;font-size:.8rem}
.mx-result{border-top:1px solid #3a2a1a;padding-top:.45rem;margin-top:.45rem}
.mx-result .note{margin:.15rem 0}
.mx-lost{margin:.25rem 0 .25rem 1.1rem;padding:0;font-size:.8rem;color:var(--muted)}
.mx-lost li{margin:.15rem 0}
.seeds-heading{font-weight:600;color:#d8a24a}
.seed-list{display:flex;flex-wrap:wrap;gap:.35rem}
.seed-btn{white-space:nowrap}
.libbar .mini-btn{min-height:40px}
.tabs{max-width:1240px;margin:.4rem auto 0;padding:0 1.1rem;display:flex;gap:.4rem;border-bottom:1px solid var(--line)}
.tabs button{background:none;border:1px solid transparent;border-bottom:none;color:var(--muted);padding:.55rem 1.1rem;min-height:44px;cursor:pointer;border-radius:4px 4px 0 0;font-size:1rem}
.tabs button[aria-selected=true]{color:var(--gold);background:var(--panel);border-color:var(--line)}
main{max-width:1240px;margin:0 auto;padding:1rem 1.1rem 2rem}
.load-error{background:#3d0f0f;border:1px solid var(--red);padding:.7rem 1rem;border-radius:var(--radius)}
.view-h{font-family:var(--font-d);font-size:1.05rem;color:var(--gold);margin:.2rem 0 .7rem;letter-spacing:.03em}

/* P2-1: paragon view */
.paragon-head{display:flex;align-items:center;gap:1rem;flex-wrap:wrap}
.paragon-stage{position:relative;margin:0 auto}
.pg-board{position:absolute;border:1px solid var(--line);background:rgba(255,255,255,.045)}
.pg-board.selected{border-color:var(--gold-dim)}
.pg-board-name{position:absolute;left:4px;top:2px;font-size:.72rem;color:#e3d3bd;z-index:3;pointer-events:none;text-shadow:0 1px 2px #000}
.pg-cell{position:absolute;width:15px;height:15px;padding:0;border:1.5px solid rgba(0,0,0,.8);border-radius:2px;background:#503722;cursor:pointer;opacity:.88}
.pg-cell.pg-magic{background:#2f5cb8}
.pg-cell.pg-rare{background:#bfa01c}
.pg-cell.pg-legendary{background:#d96a00}
.pg-cell.pg-gate{background:#5a431c;border-color:var(--gold);border-radius:50%}
.pg-cell.pg-socket{background:#5c2266;border-color:#e0aaff;border-radius:50%}
.pg-cell.pg-socket.has-glyph{background:#c586ff}
.pg-cell.allocated{opacity:1;border-color:#ffe1a1;box-shadow:0 0 0 1.5px var(--gold),0 0 7px rgba(216,162,74,.6)}
.pg-cell.selected{box-shadow:0 0 0 2px var(--red2);z-index:4}
.pg-start{position:absolute;width:15px;height:15px;border-radius:50%;background:#f4efe2;border:2px solid #ffd97a;z-index:2;pointer-events:none}
.paragon-boards{display:flex;flex-direction:column;gap:.4rem}
.pg-board-row{display:flex;justify-content:space-between;gap:.6rem;text-align:left;background:var(--panel);border:1px solid var(--line);border-radius:var(--radius);padding:.5rem .6rem;cursor:pointer;color:var(--txt);min-height:44px;align-items:center;width:100%}
.pg-board-row.selected{border-color:var(--gold)}
.pg-board-row-name{font-weight:600}
.gear-layout{display:grid;grid-template-columns:1fr;gap:1.4rem}
@media (min-width:900px){.gear-layout{grid-template-columns:minmax(400px,6fr) 6fr}}
/* .doll layout lives in the P6-2 block at the end of this file. */
.slot{display:flex;gap:.7rem;align-items:center;text-align:left;width:100%;background:var(--panel);border:1px solid var(--line);border-radius:var(--radius);padding:.6rem .7rem;cursor:pointer;color:var(--txt);min-height:64px}
.slot:hover{border-color:var(--gold-dim)}
.slot.selected{border-color:var(--gold);box-shadow:0 0 0 1px var(--gold)}
.slot-tile{flex:0 0 42px;height:42px;border:1px solid var(--gold-dim);border-radius:var(--radius);display:flex;align-items:center;justify-content:center;font-family:var(--font-d);color:var(--gold);background:var(--panel2);font-size:.8rem;text-align:center;line-height:1.1}
.slot-main{min-width:0}
.slot-name{display:block;font-size:.78rem;color:var(--muted)}
/* VIS-RICH-2: equipped names wrap to a 2-line clamp (was one-line
   nowrap truncation); overflow-wrap keeps a single over-long word
   inside the card, where the clamp ellipsises it. */
.slot-item{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;font-weight:600;font-size:.93rem;line-height:1.3;overflow:hidden;overflow-wrap:anywhere}
.slot-item.empty{color:var(--muted);font-weight:400}
.slot-meta{display:block;font-size:.78rem;color:var(--muted)}
.rarity-unique{color:#ff8000}.rarity-mythic{color:#c586ff}.rarity-legendary{color:#ff8000}.rarity-rare{color:#ffe98a}
.panel{background:var(--panel);border:1px solid var(--line);border-radius:var(--radius);padding:1rem}
.placeholder{color:var(--muted);text-align:center;padding:2.2rem 1rem}
.editor h3{font-family:var(--font-d);color:var(--gold);margin:.1rem 0 .6rem;font-size:1.05rem}
.editor h4{margin:1rem 0 .45rem;font-size:.95rem;color:var(--txt)}
.mode-row{display:flex;gap:.5rem;margin-bottom:.7rem}
.mode-row button{flex:1;background:var(--panel2);border:1px solid var(--line);color:var(--muted);border-radius:var(--radius);padding:.55rem;min-height:44px;cursor:pointer}
.mode-row button[aria-pressed=true]{color:var(--gold);border-color:var(--gold)}
.pick-list{display:flex;flex-direction:column;gap:.35rem;max-height:330px;overflow:auto;margin-top:.5rem}
.pick-item{display:flex;justify-content:space-between;gap:.6rem;text-align:left;background:var(--panel2);border:1px solid var(--line);border-radius:var(--radius);padding:.5rem .6rem;cursor:pointer;color:var(--txt);min-height:44px;align-items:center}
.pick-item:hover{border-color:var(--gold-dim)}
.pick-item .pi-meta{font-size:.78rem;color:var(--muted);white-space:nowrap}
/* P6-1: icon layer — one fixed-size box per icon; the img and the
   monogram fallback occupy the same box, so loading/failure never
   shifts layout. .db-row is the database list row (icon + name left,
   meta pinned right); .ic-tile matches the gear .slot-tile footprint. */
.icon-box{display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;background:var(--panel2);border:1px solid var(--line);border-radius:var(--radius);overflow:hidden}
.icon-box.ic-sm{width:30px;height:30px}
.icon-box.ic-tile{width:42px;height:42px;border-color:var(--gold-dim)}
.icon-img{width:100%;height:100%;object-fit:contain;display:block}
.icon-mono{font-family:var(--font-d);color:var(--gold);font-size:.8rem;line-height:1.1;text-align:center}
.pick-item.db-row{justify-content:flex-start}
.pick-item.db-row .pi-meta{margin-left:auto}
.pick-count{font-size:.8rem;color:var(--muted);margin-top:.4rem}
.search-input{width:100%}
.field-row{display:flex;flex-wrap:wrap;gap:.6rem;align-items:flex-end;margin:.5rem 0}
.field-row label{display:flex;flex-direction:column;gap:.2rem;font-size:.82rem;color:var(--muted)}
.field-row input[type=number]{width:7.5rem}
.affix-row{border:1px solid var(--line);border-radius:var(--radius);padding:.55rem .6rem;margin:.45rem 0;background:var(--panel2)}
.affix-row .af-name{font-weight:600}
.af-crit{display:inline-block;margin-left:.5rem;padding:.05rem .45rem;border:1px solid var(--gold);border-radius:999px;color:var(--gold);font-size:.75rem;font-weight:600;vertical-align:middle}
.affix-row .af-desc{display:block;font-size:.85rem;color:var(--muted)}
.affix-vals{display:flex;flex-wrap:wrap;gap:.5rem;align-items:flex-end;margin-top:.4rem}
.affix-vals label{display:flex;flex-direction:column;gap:.15rem;font-size:.78rem;color:var(--muted)}
.affix-vals input{width:6.5rem;min-height:38px}
.chk{display:flex;flex-direction:row;align-items:center;gap:.35rem;font-size:.85rem;color:var(--txt)}
.chk input{min-height:0;width:18px;height:18px}
.mini-btn{background:none;border:1px solid var(--line);color:var(--muted);border-radius:var(--radius);padding:.3rem .6rem;min-height:36px;cursor:pointer}
.mini-btn:hover{color:var(--red2);border-color:var(--red)}
.mini-btn.neutral:hover{color:var(--gold);border-color:var(--gold)}
.err{color:var(--red2);font-size:.85rem;min-height:1.2em;margin:.3rem 0 0}
.note{font-size:.8rem;color:var(--muted)}
.item-head{display:flex;justify-content:space-between;gap:.8rem;align-items:flex-start}
.item-head .ih-name{font-size:1.05rem;font-weight:700}
select.wide{width:100%}
.foot{max-width:1240px;margin:0 auto;padding:0 1.1rem 1.6rem;color:var(--muted);font-size:.8rem}
/* P1-3: skills view */
.skills-head{display:flex;flex-wrap:wrap;gap:.8rem 1.4rem;align-items:flex-end;margin-bottom:.6rem}
.points-box{font-size:.95rem;color:var(--muted)}
.points-box strong{color:var(--gold);font-size:1.1rem}
.tree-scroll{overflow:auto;border:1px solid var(--line);border-radius:var(--radius);background:var(--panel);max-height:80vh;margin-bottom:.8rem}
.tree-stage{position:relative;margin:0 auto}
.tree-links{position:absolute;left:0;top:0;pointer-events:none}
.tree-links line{stroke:#5d4634;stroke-width:1.8}
.tree-links line.link-on{stroke:var(--gold);stroke-width:2.4}
.tree-node{position:absolute;transform:translate(-50%,-50%);width:27px;height:27px;border-radius:50%;border:2px solid #7d5f43;background:#2b1a10;color:var(--txt);font-size:.66rem;font-weight:700;line-height:1;padding:0;cursor:pointer;z-index:2}
.tree-node.avail{border-color:var(--gold);background:#43300f;box-shadow:0 0 0 1px #000}
.tree-node.locked{opacity:.7;border-color:#54402c;background:#1a0f09}
.tree-node.allocated{border-color:#ffd97a;background:#7a5410;color:#ffedbe;box-shadow:0 0 0 1px #000,0 0 7px rgba(216,162,74,.5)}
.tree-node.selected{box-shadow:0 0 0 2px var(--red2);z-index:3}
.tree-conn{position:absolute;transform:translate(-50%,-50%);width:7px;height:7px;border-radius:50%;background:#8a6a4e;z-index:1}
.tree-root{position:absolute;transform:translate(-50%,-50%) rotate(45deg);width:15px;height:15px;background:var(--gold-dim);border:1px solid var(--gold);z-index:1}
.skill-detail{margin-bottom:1rem;min-height:3.2rem}
.skill-desc{font-size:.9rem;color:var(--txt);margin:.4rem 0}
.stepper{display:flex;align-items:center;gap:.6rem}
.stepper .mini-btn{width:40px;min-height:40px;font-size:1.05rem}
.stepper-val{font-weight:700;color:var(--gold);min-width:4.2rem;text-align:center}
/* P4-1: mercenary view (tree reuses the P1-3 .tree-* classes) */
.merc-legacy{margin-bottom:1rem}
.merc-legacy .mx-lost{font-size:.85rem}
/* P4-2: war plans + season views (trees reuse the P1-3 .tree-* classes) */
.wp-list{display:flex;flex-direction:column;gap:.4rem;margin-bottom:.8rem}
.wp-row{display:flex;justify-content:space-between;gap:.6rem;background:var(--panel);border:1px solid var(--line);border-radius:var(--radius);padding:.5rem .6rem;align-items:center}
.wp-row.selected{border-color:var(--gold)}
.wp-row-name{font-weight:600}
.wp-row-meta{font-size:.78rem;color:var(--muted)}
.wp-row-btns{display:flex;gap:.4rem;flex-wrap:wrap}
.sp-picked{display:flex;flex-direction:column;gap:.35rem;margin:.5rem 0}
.set-tier-met{color:var(--gold)}
#spPruneNote{color:var(--gold);border:1px solid var(--gold-dim);border-radius:var(--radius);padding:.5rem .6rem}
/* P1-3: skill bar */
.skill-bar{display:grid;grid-template-columns:1fr;gap:.5rem;margin-bottom:1rem}
@media (min-width:560px){.skill-bar{grid-template-columns:1fr 1fr}}
@media (min-width:900px){.skill-bar{grid-template-columns:repeat(3,1fr)}}
.bar-slot{display:flex;flex-direction:column;gap:.25rem}
.bar-slot-name{font-size:.78rem;color:var(--muted)}
/* P1-3b: specialization panel */
.spec-list{display:flex;flex-direction:column;gap:.35rem;margin:.5rem 0}
.spec-row{border:1px solid var(--line);border-radius:var(--radius);padding:.45rem .6rem;background:var(--panel2)}
.spec-row-name{display:block;font-weight:600}
.spec-row-desc{display:block;font-size:.85rem;color:var(--muted)}
.spec-unit{margin-top:.9rem}
.spec-unit .ih-name{font-size:1rem;font-weight:700;display:block;margin-bottom:.3rem}
.spec-flavor{font-style:italic}
.spec-boons .ih-name{font-size:1rem;font-weight:700;display:block;margin-top:.7rem}
/* P3-2: database view */
.db-badge{display:inline-block;margin-left:.4rem;padding:.02rem .4rem;border:1px solid var(--gold-dim);border-radius:999px;color:var(--gold);font-size:.68rem;font-weight:700;vertical-align:middle;white-space:nowrap}
.db-name{min-width:0}
.db-name-sec{display:block;font-size:.8rem;color:var(--muted);font-weight:400}
.db-name-main .db-name-pri{font-size:1.05rem;font-weight:700}
.pick-item.selected{border-color:var(--gold);box-shadow:0 0 0 1px var(--gold)}
.db-list{max-height:430px}
.db-detail{margin-top:.8rem}
.db-detail h4{margin:1rem 0 .45rem;font-size:.95rem;color:var(--txt)}
.db-more-row{margin-top:.5rem}
.db-search{flex:1 1 14rem}
.db-search input{width:100%}
.stats-sec{margin-bottom:1rem}
.stats-sec h3{margin:.2rem 0 .6rem;font-size:1rem;color:var(--gold)}
.stat-line{display:flex;flex-wrap:wrap;align-items:baseline;gap:.35rem .8rem;padding:.3rem 0;border-bottom:1px solid var(--line)}
.stat-name{font-weight:600;min-width:9rem}
.stat-val{color:var(--gold);font-weight:700}
.stat-break{flex-basis:100%}
.stat-break summary{cursor:pointer;color:var(--muted);font-size:.8rem}
.contrib-list{margin:.3rem 0 .3rem 1.1rem;padding:0;font-size:.85rem;color:var(--muted)}
.contrib-list li{margin:.15rem 0}
/* P4-3: loot filter (§1.10) */
.lf-rules{display:flex;flex-direction:column;gap:.35rem;margin:.5rem 0}
.lf-types{display:flex;flex-wrap:wrap;gap:.35rem;margin-top:.5rem;max-height:300px;overflow:auto}
.lf-type{border:1px solid var(--line);background:var(--panel2);color:var(--txt);border-radius:var(--radius);padding:.35rem .55rem;cursor:pointer;font-size:.85rem;min-height:36px}
.lf-type:hover{border-color:var(--gold-dim)}
.lf-type.selected{border-color:var(--gold);color:var(--gold);box-shadow:0 0 0 1px var(--gold)}
.lf-verdict{font-weight:700;white-space:nowrap}
.lf-verdict.match{color:var(--gold)}
.lf-verdict.nomatch{color:var(--muted)}
.lf-verdict.partial{color:var(--red2)}
.lf-verdict.disabled,.lf-verdict.invalid{color:var(--muted)}
#lfRuleMeta .chk{display:inline-flex;align-items:center;gap:.3rem}
/* P5-1: UI/UX pass — mobile-first navigation, tap targets, sticky controls,
   stats readability. Presentation only; no behaviour or data changes.
   --p5-sticky-top is the offset sticky in-page controls sit below: 0 on
   desktop (no sticky page header there), the compact sticky header's
   height on small screens. */
:root{--p5-sticky-top:0px}
.stat-val,.points-box strong,.stepper-val,.contrib-list,.pick-count{font-variant-numeric:tabular-nums}
/* Item 4: picker search bars stay pinned while their panel scrolls. */
.search-input,.ctl.db-search{position:sticky;top:var(--p5-sticky-top);z-index:20;background:var(--panel);padding-top:.3rem;padding-bottom:.3rem}
.db-controls{position:sticky;top:var(--p5-sticky-top);z-index:20;background:var(--panel);padding-top:.3rem;padding-bottom:.3rem}
@media (max-width:768px){
  :root{--p5-head-h:112px;--p5-sticky-top:var(--p5-head-h)}
  /* Item 5: build header (title/class/season/language) sticks, compacted
     to brand row + one horizontally scrollable controls row. */
  .topbar{position:sticky;top:0;z-index:30;background:var(--bg);padding:.55rem .7rem .45rem;gap:.35rem .8rem;box-shadow:0 1px 0 var(--line)}
  .brand-name{font-size:1.12rem}
  .brand-sub{font-size:.75rem}
  .top-controls{flex-wrap:nowrap;overflow-x:auto;max-width:100%;gap:.5rem;padding-bottom:.15rem}
  .top-controls .ctl input,.top-controls .ctl select{min-width:7rem}
  .top-controls #titleInput{min-width:9.5rem}
  /* Item 1: tab bar becomes a sticky bottom nav with safe-area padding. */
  .tabs{position:fixed;left:0;right:0;bottom:0;z-index:40;margin:0;max-width:none;padding:.25rem .4rem calc(.25rem + env(safe-area-inset-bottom));background:var(--panel);border-top:1px solid var(--line);border-bottom:none;overflow-x:auto;flex-wrap:nowrap;scrollbar-width:none}
  .tabs::-webkit-scrollbar{display:none}
  .tabs button{flex:0 0 auto;min-height:48px;padding:.55rem .85rem;border-radius:var(--radius);border-bottom:1px solid transparent}
  .tabs button[aria-selected=true]{border-color:var(--gold-dim)}
  main{padding-bottom:calc(4.6rem + env(safe-area-inset-bottom))}
  .foot{padding-bottom:calc(4.6rem + env(safe-area-inset-bottom))}
  /* Item 2: touch targets ≥40px on small screens. */
  input,select{min-height:44px}
  .mini-btn{min-height:40px;padding:.45rem .7rem}
  .stepper .mini-btn{width:44px;min-height:44px}
  .pick-item{min-height:48px}
  .lf-type{min-height:40px;padding:.5rem .65rem}
  .affix-vals input{min-height:40px}
  /* Item 2/3: larger, higher-contrast tree nodes on phones (positions are
     centre-anchored, so a CSS size bump keeps the geometry coherent). */
  .tree-node{width:34px;height:34px;font-size:.74rem}
  .tree-root{width:18px;height:18px}
  .pg-cell{border-width:2px}
  /* Item 6: stat group headers stick within the page scroll on mobile. */
  .stats-sec h3{position:sticky;top:var(--p5-sticky-top);z-index:10;background:var(--panel);padding:.3rem 0;margin-top:0}
}
/* P6-2: game-style item cards + paper-doll gear layout. Presentation
   only; textures are pure CSS gradients (no external assets). */
/* --- item card --- */
.item-card{display:block;text-align:left;background:radial-gradient(130% 90% at 50% 0%,rgba(216,162,74,.08),rgba(0,0,0,0) 55%),repeating-linear-gradient(115deg,rgba(255,255,255,.016) 0 2px,rgba(0,0,0,0) 2px 5px),linear-gradient(165deg,#26180f,#150d07 58%,#0f0805);border:1px solid var(--line);border-radius:6px;padding:.6rem .7rem;box-shadow:inset 0 0 0 1px rgba(0,0,0,.55),inset 0 1px 0 rgba(216,162,74,.14)}
.item-card.card-unique,.item-card.card-legendary{border-color:#9c5a10}
.item-card.card-mythic{border-color:#8a5fc0}
.item-card.card-rare{border-color:#8f7414}
.ic-head{display:flex;gap:.65rem;align-items:flex-start}
.ic-title{display:block;min-width:0}
.ic-name{display:block;font-family:var(--font-d);font-size:1.02rem;font-weight:700;line-height:1.3}
.ic-sub{display:block;font-size:.8rem;color:var(--muted);margin-top:.1rem}
.ic-lines{display:block;margin-top:.5rem;border-top:1px solid rgba(216,162,74,.18);padding-top:.45rem}
.ic-line{display:block;font-size:.88rem;line-height:1.45;margin:.16rem 0;color:var(--txt)}
.ic-effect{color:var(--gold)}
.ic-flavor{display:block;font-style:italic;color:var(--muted);font-size:.85rem;margin-top:.4rem}
/* picker rows host the card inside the existing .pick-item button */
.pick-item.item-card{width:100%;cursor:pointer;color:var(--txt)}
.pick-item.item-card:hover{border-color:var(--gold)}
/* editor header: card grows, remove button stays at its right */
.item-head .item-card{flex:1 1 auto;min-width:0}
/* --- paper doll --- */
.doll{display:grid;grid-template-columns:1fr 216px 1fr;gap:.7rem;align-items:stretch}
.doll-col{display:flex;flex-direction:column;gap:.5rem;min-width:0}
.doll-center{display:flex;flex-direction:column;align-items:center;gap:.45rem;padding-top:.5rem;text-align:center;min-width:0}
.doll-medallion{width:84px;height:84px;border-radius:50%;border:2px solid var(--gold-dim);background:radial-gradient(circle at 50% 32%,#3d2712,#170e08 72%);display:flex;align-items:center;justify-content:center;box-shadow:0 0 0 4px #0d0805,0 0 0 5px var(--line),inset 0 0 18px rgba(0,0,0,.7)}
.doll-emblem{font-family:var(--font-d);font-size:1.7rem;color:var(--gold);line-height:1}
.doll-class{font-family:var(--font-d);color:var(--gold);font-size:.98rem;letter-spacing:.03em}
.doll-build{font-size:.78rem;color:var(--muted);overflow-wrap:anywhere}
.slot.filled.r-unique,.slot.filled.r-legendary{border-color:#9c5a10}
.slot.filled.r-mythic{border-color:#8a5fc0}
.slot.filled.r-rare{border-color:#8f7414}
@media (max-width:899px){
  /* stacked flow: medallion on top, slot columns become grids */
  .doll{display:flex;flex-direction:column;align-items:stretch}
  .doll-center{order:-1}
  .doll-col{display:grid;grid-template-columns:1fr 1fr;align-items:stretch}
}
@media (max-width:559px){
  .doll-col{grid-template-columns:1fr}
}
/* P6-3: texture/typography layer + node icons. Presentation only.
   Every texture is self-made: layered CSS gradients plus an inline
   SVG fractal-noise data URI authored in this file — no external
   assets beyond the Cinzel stylesheet linked in index.html. */
/* --font-d already leads with Cinzel; index.html loads the face from
   Google Fonts with Georgia/"Times New Roman"/serif fallbacks, and
   CJK headings fall through the stack to the serif faces (Cinzel
   carries no CJK glyphs). font-synthesis is off for display text so
   fallback faces are never artificially bolded. */
:root{
  --tex-noise:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)' opacity='0.5'/%3E%3C/svg%3E");
  --tex-noise-soft:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)' opacity='0.14'/%3E%3C/svg%3E")
}
/* Page backdrop: vignette + faint grain over the base ember
   gradient. Text-bearing surfaces keep their own solid/near-solid
   backgrounds (.panel, controls), so grain never sits under body
   text at reading strength. */
body{background-color:var(--bg);background-image:radial-gradient(125% 100% at 50% 38%,rgba(0,0,0,0) 54%,rgba(0,0,0,.5) 100%),var(--tex-noise-soft),radial-gradient(1200px 520px at 50% -140px,#47150c 0%,var(--bg) 58%);background-repeat:no-repeat,repeat,repeat;background-attachment:fixed,scroll,scroll}
/* Major panels: a subtle gold hairline frame; the fill stays the
   solid panel colour. */
.panel{box-shadow:inset 0 0 0 1px rgba(216,162,74,.07),inset 0 1px 0 rgba(216,162,74,.1),inset 0 0 26px rgba(0,0,0,.32)}
/* Stage panels (skill tree / paragon / mercenary / war-plan scroll
   stages): stone grain under a dark wash, so the texture reads as
   material behind the nodes while node art and labels stay crisp. */
.tree-scroll{background-color:#150e09;background-image:linear-gradient(rgba(19,12,8,.87),rgba(19,12,8,.93)),var(--tex-noise),radial-gradient(85% 65% at 50% 28%,rgba(216,162,74,.06),rgba(0,0,0,0) 62%);background-repeat:no-repeat,repeat,no-repeat}
.pg-board{background-image:var(--tex-noise-soft)}
/* Typography: display face for tab labels + the build title input
   (headings, brand and item-card names already use --font-d). */
.tabs button{font-family:var(--font-d);letter-spacing:.04em}
#titleInput{font-family:var(--font-d);letter-spacing:.02em}
.brand-name,.view-h,.tabs button,.editor h3,.doll-class,.ic-name{font-synthesis:none}
/* Skill tree node icons (P6-3 scope 3): the icon fills the node
   frame; state treatments ride over the art — allocated full
   colour under the gold ring, available slightly dimmed, locked
   desaturated + dark. Positions are centre-anchored, so the modest
   desktop size bump keeps the kit geometry untouched. */
@media (min-width:769px){#skillTree .tree-node{width:32px;height:32px}}
.tree-node .icon-box.ic-node{position:absolute;inset:0;width:100%;height:100%;border:none;border-radius:50%;background:#170d07}
.tree-node .icon-box.ic-node .icon-img{border-radius:50%;filter:brightness(.92) saturate(.95)}
.tree-node.allocated .icon-box.ic-node .icon-img{filter:none}
.tree-node.locked .icon-box.ic-node .icon-img{filter:grayscale(.85) brightness(.48)}
.node-pts{position:absolute;right:-4px;bottom:-4px;z-index:3;background:#0d0805;border:1px solid var(--gold);color:#ffedbe;border-radius:999px;font-size:.62rem;font-weight:700;line-height:1.25;padding:.05rem .32rem;pointer-events:none}
/* P7-1: skill tree Canvas 2D stage. The canvas fills the stage and
   the view controls float at its top-right; pan/zoom replaces the
   scroll the DOM stage needed. The DOM renderer above remains the
   no-canvas fallback. */
.tree-stage.tree-canvas-mode{width:100%;height:min(76vh,680px);min-height:360px;overflow:hidden}
.tree-canvas{position:absolute;inset:0;width:100%;height:100%;display:block;touch-action:none;user-select:none;-webkit-user-select:none;-webkit-touch-callout:none;cursor:grab}
.tree-canvas:active{cursor:grabbing}
.tree-view-ctl{position:absolute;right:.5rem;top:.5rem;display:flex;flex-direction:column;gap:.3rem;z-index:5}
.tree-view-btn{width:40px;height:40px;padding:0;background:rgba(23,16,13,.92);border:1px solid var(--gold-dim);border-radius:var(--radius);color:var(--gold);font-size:1.05rem;font-weight:700;line-height:1;cursor:pointer}
.tree-view-btn:hover{border-color:var(--gold)}
@media (max-width:768px){.tree-stage.tree-canvas-mode{height:64vh;min-height:320px}}
/* P7-2: paragon Canvas 2D stage — mirrors the P7-1 tree stage: the
   canvas fills the stage, the shared view controls float at its
   top-right, pan/zoom replaces the scroll the DOM stage needed. The
   DOM renderer above remains the no-canvas fallback. */
.paragon-stage.pg-canvas-mode{width:100%;height:min(76vh,680px);min-height:360px;overflow:hidden}
.pg-canvas{position:absolute;inset:0;width:100%;height:100%;display:block;touch-action:none;user-select:none;-webkit-user-select:none;-webkit-touch-callout:none;cursor:grab}
.pg-canvas:active{cursor:grabbing}
@media (max-width:768px){.paragon-stage.pg-canvas-mode{height:64vh;min-height:320px}}
/* Paragon glyph socket icon (P6-3 scope 4): fills the round cell. */
.pg-cell .icon-box.ic-cell{position:absolute;inset:0;width:100%;height:100%;border:none;border-radius:50%;background:transparent}
.pg-cell .icon-box.ic-cell .icon-img{border-radius:50%}
/* Skill bar (P6-3 scope 5): equipped slots lead with the icon. */
.bar-row{display:flex;gap:.5rem;align-items:center}
.bar-row select{flex:1 1 auto;min-width:0}

/* VIS-RICH — visual richness pass (display only). Class artwork is
   mirrored same-origin under assets/classes/ (INV-3); nothing here
   hotlinks. */
/* atmosphere: fixed wash of the active class art under everything,
   heavily blurred + darkened so body-text contrast is untouched;
   the self-made noise texture on body stays layered above it. */
#bgWash{position:fixed;inset:0;z-index:-1;pointer-events:none;background-size:cover;background-position:50% 18%;filter:blur(26px) brightness(.30) saturate(.35);transform:scale(1.18)}
/* paper-doll centrepiece: centre-cropped class art, name overlaid
   on a legibility gradient at the bottom. */
.doll-center{height:100%}
.doll-art{position:relative;flex:1 1 auto;width:100%;min-height:340px;border:1px solid var(--gold-dim);border-radius:var(--radius);overflow:hidden;background:#0d0805;box-shadow:inset 0 0 34px rgba(0,0,0,.55)}
/* VIS-RICH-2: brightness lift on the centre art only (the #bgWash
   backdrop keeps its own dark filter); the shade gradient is
   deepened a step so the name overlay stays legible over the
   lifted image. */
.doll-art-img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:50% 16%;filter:brightness(1.18) contrast(1.05)}
.doll-art-shade{position:absolute;left:0;right:0;bottom:0;padding:2rem .6rem .55rem;background:linear-gradient(180deg,rgba(5,3,2,0) 0%,rgba(5,3,2,.86) 50%,rgba(5,3,2,.97) 100%);display:flex;flex-direction:column;align-items:center;gap:.15rem;text-align:center}
.doll-art-shade .doll-class{text-shadow:0 1px 6px rgba(0,0,0,.9)}
.doll-art-shade .doll-build{text-shadow:0 1px 5px rgba(0,0,0,.9)}
@media (max-width:899px){
  /* stacked flow: the art centre becomes a banner above the slots */
  .doll-center{width:100%;height:auto}
  .doll-art{flex:none;width:100%;height:158px;min-height:0}
  .doll-art-img{object-position:50% 22%}
}
/* library + seed cards */
.lib-cards{display:flex;flex-wrap:wrap;gap:.55rem;margin-top:.55rem}
.seed-list{gap:.55rem}
.lib-card,.seed-card{display:flex;flex-direction:column;width:172px;padding:0;overflow:hidden;text-align:left;background:var(--panel);border:1px solid var(--line);border-radius:var(--radius);color:var(--txt);cursor:pointer;min-height:40px;white-space:normal}
.lib-card.active{border-color:var(--gold);box-shadow:0 0 0 1px var(--gold)}
.card-cover{display:block;height:62px;overflow:hidden;background:radial-gradient(circle at 50% 30%,#3d2712,#170e08 75%);border-bottom:1px solid var(--line)}
.card-cover-img{width:100%;height:100%;object-fit:cover;object-position:50% 20%;display:block}
.card-body{display:flex;flex-direction:column;gap:.22rem;padding:.5rem .6rem .6rem}
.card-title{font-weight:600;line-height:1.3;overflow-wrap:anywhere}
.card-meta{font-size:.78rem;color:var(--muted)}
.badge{align-self:flex-start;font-size:.72rem;line-height:1.5;border:1px solid var(--gold-dim);color:var(--gold);border-radius:99px;padding:.02rem .5rem;white-space:nowrap}
.badge-curated,.badge-src{color:var(--muted);border-color:var(--line)}
/* rarity glow on game-style item cards */
.item-card.card-unique,.item-card.card-legendary{box-shadow:0 0 13px rgba(216,122,26,.38)}
.item-card.card-mythic{box-shadow:0 0 15px rgba(169,112,255,.45)}
/* gold hairline on major panels (strengthens the P6-3 inset line) */
.panel{box-shadow:inset 0 0 0 1px rgba(216,162,74,.07),inset 0 1px 0 rgba(216,162,74,.26),inset 0 0 26px rgba(0,0,0,.32)}
/* hover lift on clickable cards (motion-safe only) */
@media (prefers-reduced-motion: no-preference){
  .seed-card,.lib-card,.pick-item{transition:transform .15s ease,box-shadow .15s ease,border-color .15s ease}
  .seed-card:hover,.lib-card:hover{transform:translateY(-2px);box-shadow:0 7px 18px rgba(0,0,0,.5)}
  .lib-card.active:hover{box-shadow:0 0 0 1px var(--gold),0 7px 18px rgba(0,0,0,.5)}
}
/* WB-4: community tab — the seed grid's new home (no libbar divider),
   gallery filter chips, and the submission dialog. */
#view-community .seeds-row{border-top:none;padding-top:0}
.gal-controls{display:flex;flex-wrap:wrap;gap:.6rem 1rem;align-items:flex-end;margin-bottom:.6rem}
.gal-chips{display:flex;flex-wrap:wrap;gap:.35rem}
.gal-chip{min-height:40px;padding:.35rem .8rem;background:var(--panel);border:1px solid var(--line);border-radius:99px;color:var(--muted);cursor:pointer;font-size:.9rem}
.gal-chip.active{border-color:var(--gold);color:var(--gold)}
.gal-list{margin-top:.2rem}
.badge-community{color:var(--gold);border-color:var(--gold-dim)}
.dialog-overlay{position:fixed;inset:0;z-index:60;background:rgba(4,2,1,.72);display:flex;align-items:flex-start;justify-content:center;padding:8vh 1rem 1rem;overflow:auto}
.dialog-overlay[hidden]{display:none}
.dialog{width:100%;max-width:30rem;background:var(--panel);border:1px solid var(--line);border-radius:var(--radius);padding:1rem 1.1rem 1.1rem}
.dialog .ctl{display:flex;flex-direction:column;gap:.3rem;margin-bottom:.7rem}
.dialog .ctl input{min-height:40px}
.ts-widget{margin:.4rem 0 .6rem;min-height:65px}
