/* Build Planner surfaces: /builds list + read-only viewer. */
.builds-page { max-width: 72rem; margin: 0 auto; padding: 1.5rem 1rem 3rem; }
.builds-header { display: flex; justify-content: space-between; align-items: end; gap: 1rem; margin-bottom: 1.25rem; }
.builds-lead { color: var(--color-default); max-width: 46rem; }
.builds-noscript { border: 1px solid var(--border); padding: .75rem 1rem; border-radius: 6px; }

/* Picker overlay (z above build-menu 130/131, below header search 200). */
.picker-overlay .picker-scrim { position: fixed; inset: 0; z-index: 140; background: rgb(0 0 0 / .6); }
/* `zoom` scales absolute and viewport lengths on this element, so a plain
   `max-height: 80vh` rendered as 100vh at L and 120vh at XL — the panel ran off
   the bottom of a FIXED-position box, which page scrolling cannot reach.
   Dividing the viewport-relative values by the same factor cancels the scale.
   Percentages are NOT affected (they resolve in the element's own zoomed
   coordinate space), so `left: 50%` must stay untouched or the panel de-centers. */
.picker-panel { --picker-zoom: 1;
  position: fixed; z-index: 141; left: 50%; transform: translateX(-50%);
  top: calc(6vh / var(--picker-zoom)); max-height: calc(88vh / var(--picker-zoom));
  width: min(34rem, calc((100vw - 2rem) / var(--picker-zoom))); display: flex; flex-direction: column;
  background: var(--bg-surface); border: 1px solid var(--border); border-radius: 8px;
  box-shadow: 0 18px 48px rgb(0 0 0 / .38); }
.picker-input { flex: none; }
.picker-head { flex: none; }
.picker-results { flex: 1 1 auto; min-height: 0; }
.picker-head h2 { margin: 0; font-family: var(--font-display); font-size: 15px;
  font-weight: 500; color: var(--color-normal); }
.picker-close:hover { color: var(--color-normal); }
.picker-group h3 { color: var(--color-default); font-family: var(--font-smallcaps); }
.picker-row__name { color: var(--color-normal); }
.picker-input:focus-visible { outline: none;
  border-color: color-mix(in srgb, var(--accent-ui) 55%, var(--border));
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent-ui) 12%, transparent); }

/* Recommended supports: the graph already knows which supports a gem is meant to
   pair with (recommends_support edges -> planner.recommends). Surfacing that as
   its own section beats hiding it in the sort order. */
.picker-group--rec { border: 1px solid color-mix(in srgb, var(--accent-ui) 26%, var(--border));
  border-radius: 7px; background: color-mix(in srgb, var(--accent-ui) 6%, transparent);
  padding: 2px 4px 5px; margin: 0 .2rem .7rem; }
.picker-group--rec h3 { color: var(--accent-ui); }
.picker-group--rec .picker-row__name { color: var(--color-normal); }
.picker-rec-note { margin: 0 .6rem .5rem; padding: 0 .4rem; color: var(--color-default);
  font-size: 11px; line-height: 1.5; }
.picker-head { display: flex; justify-content: space-between; align-items: center; padding: .6rem 1rem; }
.picker-close { background: none; border: 0; color: inherit; font-size: 1.2rem; cursor: pointer; }
.picker-input { margin: 0 1rem .6rem; padding: .5rem .7rem; font: inherit; color: inherit;
  background: rgb(0 0 0 / .35); border: 1px solid var(--border); border-radius: 5px; }
.picker-results { overflow-y: auto; padding: 0 .6rem .8rem; }
.picker-group h3 { display: flex; justify-content: space-between; padding: .5rem .4rem .2rem;
  font-size: .8rem; text-transform: uppercase; letter-spacing: .06em; opacity: .7; }
.picker-row { display: flex; align-items: center; gap: .55rem; width: 100%; text-align: left;
  padding: .4rem .5rem; background: none; border: 0; color: inherit; font: inherit; cursor: pointer; border-radius: 4px; }
.picker-row:hover, .picker-row:focus-visible { background: rgb(255 255 255 / .08); }
.picker-row__icon { width: 1.6rem; height: 1.6rem; flex: none; object-fit: contain; }
.picker-row__name { flex: none; }
.picker-row__hint { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; opacity: .55; font-size: .85em; }
.picker-more { padding: .3rem .5rem; opacity: .6; font-size: .85em; }

/* ==== Dossier editor (2026-07-22 redesign) ==== */
.builds-page--editing .builds-header { display: none; }

/* UI scale (S/M/L/XL header control) — zoom the planner content, matching
   the card grids / detail panes (gem-card.css precedent). Zoom reflows the
   dossier narrower and scales it up, so the page never overflows sideways. */
html[data-card-size="s"] .dossier,
html[data-card-size="s"] .builds-import,
html[data-card-size="s"] .picker-panel { zoom: 0.85; --picker-zoom: 0.85; }
html[data-card-size="l"] .dossier,
html[data-card-size="l"] .builds-import,
html[data-card-size="l"] .picker-panel { zoom: 1.25; --picker-zoom: 1.25; }
html[data-card-size="xl"] .dossier,
html[data-card-size="xl"] .builds-import,
html[data-card-size="xl"] .picker-panel { zoom: 1.5; --picker-zoom: 1.5; }
html[data-card-size="xl"] .dossier-actions { flex-wrap: wrap; justify-content: flex-end; }
.dossier { display: grid; grid-template-columns: 132px minmax(0, 1fr); gap: 28px; }
/* z-index is load-bearing: `position: sticky` ALWAYS creates a stacking context,
   which traps the build-switcher popover's own z-index inside this element. The
   rail then competes as z-index:auto against .class-pick (also auto, positioned,
   and LATER in DOM), so the class picker and the chapter content painted over the
   open dropdown. Raising the popover cannot fix that — the rail itself has to sit
   above the main column. Stays below the modal picker (140/141). */
.dossier-rail { position: sticky; top: 24px; align-self: start; z-index: 130; }
.dossier-eyebrow { display: block; color: var(--accent-ui); font-size: 10px; font-weight: 650;
  letter-spacing: .16em; text-transform: uppercase; }
.dossier-rail__mark { margin: 0 0 16px; }

/* ---- rail build switcher ---- */
.build-switcher { position: relative; margin-top: 6px; }
.build-switcher__btn { display: flex; align-items: center; justify-content: space-between; gap: 8px;
  width: 100%; padding: 6px 9px;
  border: 1px solid var(--border); border-radius: 6px;
  background: color-mix(in srgb, var(--bg-surface) 88%, transparent);
  color: var(--color-normal); font: 12px/1.3 var(--font-smallcaps); text-align: left; cursor: pointer;
  transition: border-color 120ms ease; }
.build-switcher__btn:hover, .build-switcher__btn[aria-expanded="true"] {
  border-color: color-mix(in srgb, var(--accent-ui) 50%, var(--border)); }
.build-switcher__btn:focus-visible { outline: 2px solid var(--accent-ui); outline-offset: 2px; }
.build-switcher__name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.build-switcher__chev { color: var(--color-default); font-size: 10px; }
.build-switcher__pop { position: absolute; z-index: 120; top: calc(100% + 6px); left: 0;
  width: max(100%, 240px); padding: 6px;
  border: 1px solid var(--border); border-radius: 8px;
  background: var(--bg-surface);
  box-shadow: 0 18px 48px rgb(0 0 0 / .38); }
.build-switcher__list { list-style: none; margin: 0 0 6px; padding: 0;
  max-height: 300px; overflow-y: auto; display: flex; flex-direction: column; gap: 2px;
  scrollbar-color: var(--border) transparent; scrollbar-width: thin; }
.build-switcher__row { display: block; padding: 6px 8px; border: 1px solid transparent; border-radius: 5px;
  text-decoration: none; }
.build-switcher__row b { display: block; color: var(--color-normal); font-size: 12.5px; font-weight: 500;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.build-switcher__row span { display: block; margin-top: 1px; color: var(--color-default); font-size: 10px; }
.build-switcher__row:hover { border-color: var(--border); background: rgb(255 255 255 / .04); }
.build-switcher__row.is-current { border-color: color-mix(in srgb, var(--accent-ui) 30%, transparent);
  background: color-mix(in srgb, var(--accent-ui) 9%, transparent); }
.build-switcher__new { width: 100%; padding: 6px; border: 1px dashed var(--border); border-radius: 5px;
  background: none; color: var(--color-default); font: 11.5px/1.3 var(--font-smallcaps); cursor: pointer; }
.build-switcher__new:hover { color: var(--accent-ui);
  border-color: color-mix(in srgb, var(--accent-ui) 45%, var(--border)); }
.dossier-rail__nav { list-style: none; margin: 0; padding: 0; border-left: 1px solid var(--border); }
.dossier-rail__nav a { display: block; padding: 7px 0 7px 14px; margin-left: -1px;
  border-left: 2px solid transparent; color: var(--color-default);
  font-size: 11.5px; letter-spacing: .12em; text-transform: uppercase; text-decoration: none;
  transition: color 120ms ease, border-color 120ms ease; }
.dossier-rail__nav a:hover { color: var(--color-normal); }
.dossier-rail__nav a.is-here { color: var(--accent-ui); border-left-color: var(--accent-ui); }
.dossier-rail__note { margin-top: 20px; color: var(--color-default); font-size: 10px; line-height: 1.5; }

/* ---- rail Summary panel (Phase 7 light math) ----------------------------
   Compact, collapsible character sheet beneath the nav. Adapts the passive
   tree's stats-panel idiom (display-font title + collapse toggle) to the
   narrow rail; content is the build rollup, not raw stat lines. */
.rail-summary { margin-top: 20px; border: 1px solid var(--border); border-radius: 7px;
  background: color-mix(in srgb, var(--bg-surface) 88%, transparent); overflow: hidden; }
.rail-summary__toggle { display: flex; flex-direction: column; align-items: stretch; gap: 3px; width: 100%;
  padding: 7px 9px; background: none; border: 0; cursor: pointer; color: var(--color-normal);
  text-align: left; }
.rail-summary__toggle:focus-visible { outline: 2px solid var(--accent-ui); outline-offset: -2px; }
.rail-summary__titlerow { display: flex; align-items: center; justify-content: space-between; gap: 6px; }
.rail-summary__title { font-family: var(--font-display); color: var(--accent-ui);
  font-size: 11px; letter-spacing: .06em; text-transform: uppercase; }
.rail-summary__meta { display: flex; align-items: center; gap: 6px; }
.rail-summary__lvl { color: var(--color-default); font-size: 10px; font-variant-numeric: tabular-nums; }
.rail-summary__badge { display: inline-flex; align-items: center; justify-content: center;
  min-width: 15px; height: 15px; padding: 0 3px; border-radius: 8px; font-size: 10px; font-weight: 600;
  background: color-mix(in srgb, var(--color-corrupted) 22%, transparent);
  color: var(--color-corrupted); }
.rail-summary__chev::before { content: '▾'; color: var(--color-default); font-size: 9px; }
.rail-summary.collapsed .rail-summary__chev::before { content: '▸'; }
.rail-summary.collapsed .rail-summary__body { display: none; }
.rail-summary__body { padding: 8px 9px 9px; border-top: 1px solid var(--border); }
.rail-summary__list { list-style: none; margin: 0; padding: 0; }
.rail-summary__list--agg { margin-top: 6px; padding-top: 6px; border-top: 1px dashed var(--border); }
.rail-summary__row { display: flex; justify-content: space-between; gap: 6px; padding: 2px 0; font-size: 11px; }
.rail-summary__k { color: var(--color-default); text-transform: uppercase; letter-spacing: .04em; font-size: 10px; }
.rail-summary__v { color: var(--color-normal); font-variant-numeric: tabular-nums; }
.rail-summary__v i { color: var(--color-default); font-style: normal; }
.rail-summary__row--deficit .rail-summary__v { color: var(--color-corrupted); font-weight: 600; }
.rail-summary__row--deficit .rail-summary__k { color: var(--color-corrupted); }
.rail-summary__warnings { list-style: none; margin: 8px 0 0; padding: 8px 0 0;
  border-top: 1px solid var(--border); display: flex; flex-direction: column; gap: 4px;
  color: var(--color-corrupted); font-size: 10px; line-height: 1.35; }

.dossier-head { display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: space-between;
  gap: 12px 24px; padding-bottom: 16px; margin-bottom: 4px; border-bottom: 1px solid var(--border); }
.dossier-head__copy { min-width: 0; flex: 1 1 24rem; }
.dossier-head h2 { margin: 0 0 2px; font-size: clamp(24px, 3vw, 36px); }
.dossier-name { padding: 0; border: 0; background: none; cursor: pointer; text-align: left;
  color: var(--color-normal); font-family: var(--font-display);
  font-size: inherit; font-weight: 500; letter-spacing: .015em; line-height: 1.15; }
/* Always visible: at opacity 0 nothing signalled the title was editable at all.
   Quiet by default, lit on hover — discoverable without shouting. */
.dossier-name__pen { display: inline-flex; align-items: center; justify-content: center;
  width: 1.9rem; height: 1.9rem; margin-left: 11px; border-radius: 50%;
  border: 1px solid color-mix(in srgb, var(--accent-ui) 26%, transparent);
  background: color-mix(in srgb, var(--accent-ui) 8%, transparent);
  color: var(--accent-ui); font-size: .34em; vertical-align: middle; opacity: .75;
  transition: opacity 120ms ease, background-color 120ms ease, border-color 120ms ease; }
.dossier-name:hover .dossier-name__pen, .dossier-name:focus-visible .dossier-name__pen {
  opacity: 1; background: color-mix(in srgb, var(--accent-ui) 20%, transparent);
  border-color: color-mix(in srgb, var(--accent-ui) 52%, transparent); }
.dossier-name:focus-visible { outline: 2px solid var(--accent-ui); outline-offset: 3px; }
/* Elevated pills (chosen 2026-07-26): the class is a primary lever, not a byline.
   Real bordered/filled buttons at 14px instead of 12.5px bare text. */
.dossier-class { margin: 4px 0 10px; display: flex; align-items: center; gap: 9px;
  flex-wrap: wrap; font-size: 15px; }
.dossier-class__sep { display: none; }
.class-pick { position: relative; display: inline-flex; }
.class-pick__btn { padding: 6px 14px; border-radius: 999px; cursor: pointer;
  border: 1px solid color-mix(in srgb, var(--color-notable) 40%, var(--border));
  background: color-mix(in srgb, var(--color-notable) 9%, transparent);
  color: var(--color-notable); font: 14px/1.3 var(--font-smallcaps);
  transition: border-color 120ms ease, background-color 120ms ease; }
.class-pick__btn:hover, .class-pick__btn[aria-expanded="true"] {
  border-color: color-mix(in srgb, var(--color-notable) 45%, var(--border));
  background: color-mix(in srgb, var(--color-notable) 7%, transparent); }
.class-pick__btn:disabled { color: var(--color-default); cursor: default; opacity: .5;
  border-color: var(--border); background: none; }
.class-pick__btn:disabled:hover { border-color: var(--border); background: none; }
.class-pick__btn:focus-visible { outline: 2px solid var(--accent-ui); outline-offset: 2px; }
.class-pick__pop { position: absolute; z-index: 120; top: calc(100% + 6px); left: 0;
  min-width: 170px; max-height: 300px; overflow-y: auto;
  margin: 0; padding: 6px; list-style: none;
  border: 1px solid var(--border); border-radius: 8px;
  background: var(--bg-surface);
  box-shadow: 0 18px 48px rgb(0 0 0 / .38);
  display: flex; flex-direction: column; gap: 2px;
  scrollbar-color: var(--border) transparent; scrollbar-width: thin; }
.class-pick__row { width: 100%; padding: 6px 9px; border: 1px solid transparent; border-radius: 5px;
  background: none; color: var(--color-normal); font: 12px/1.3 var(--font-smallcaps);
  text-align: left; cursor: pointer; }
.class-pick__row:hover { border-color: var(--border); background: rgb(255 255 255 / .04); }
.class-pick__row.is-current { border-color: color-mix(in srgb, var(--accent-ui) 30%, transparent);
  background: color-mix(in srgb, var(--accent-ui) 9%, transparent); }
.dossier-name-input { width: min(24ch, 100%); padding: 0; border: 0; border-bottom: 1px solid
  color-mix(in srgb, var(--accent-ui) 58%, var(--border));
  background: none; color: var(--color-normal); font-family: var(--font-display);
  font-size: inherit; font-weight: 500; letter-spacing: .015em; line-height: 1.15; }
.dossier-name-input:focus-visible { outline: none;
  box-shadow: 0 2px 0 0 color-mix(in srgb, var(--accent-ui) 25%, transparent); }
.dossier-desc { width: 100%; max-width: 44rem; resize: vertical; padding: 6px 9px;
  border: 1px solid color-mix(in srgb, var(--border) 70%, transparent); border-radius: 6px;
  background: rgb(0 0 0 / .25); color: var(--text); font: 13px/1.5 var(--font-regular); }
.dossier-share { display: inline-flex; align-items: center; gap: 7px; padding: 5px 12px;
  border: 1px solid color-mix(in srgb, var(--accent-ui) 40%, var(--border)); border-radius: 999px;
  background: color-mix(in srgb, var(--accent-ui) 8%, transparent); color: var(--color-normal);
  font: 12px/1.2 var(--font-smallcaps); cursor: pointer;
  transition: border-color 120ms ease, background-color 120ms ease, transform 120ms ease; }
.dossier-share:hover { background: color-mix(in srgb, var(--accent-ui) 14%, transparent); transform: translateY(-1px); }
.dossier-share:focus-visible { outline: 2px solid var(--accent-ui); outline-offset: 2px; }
.dossier-actions { display: flex; align-items: center; gap: 7px; flex-wrap: wrap;
  margin: 0 0 10px; }
.dossier-action { padding: 5px 11px; border: 1px solid var(--border); border-radius: 999px;
  background: none; color: var(--color-default); font: 11.5px/1.2 var(--font-smallcaps); cursor: pointer;
  transition: border-color 120ms ease, color 120ms ease; }
.dossier-action:hover { color: var(--color-normal);
  border-color: color-mix(in srgb, var(--accent-ui) 50%, var(--border)); }
.dossier-action--danger:hover { color: var(--color-corrupted);
  border-color: color-mix(in srgb, var(--color-corrupted) 55%, var(--border)); }

/* ---- read-only (shared preview / import) ---- */
.dossier-banner { margin: 0 0 12px; padding: 8px 12px;
  border: 1px solid color-mix(in srgb, var(--accent-ui) 30%, var(--border)); border-radius: 6px;
  background: color-mix(in srgb, var(--accent-ui) 6%, transparent);
  color: var(--color-normal); font-size: 12px; }
.dossier-name--static { color: var(--color-normal); font-family: var(--font-display);
  font-weight: 500; letter-spacing: .015em; line-height: 1.15; }
.dossier-desc--static { margin: 4px 0 0; max-width: 44rem; border: 0; padding: 0;
  background: none; color: var(--text); font: 13px/1.5 var(--font-regular); }
.editor-notes-static { padding: 13px 15px; border: 1px solid var(--border); border-radius: 8px;
  background: rgb(0 0 0 / .25); color: var(--text); font: 15px/1.6 var(--font-regular);
  white-space: pre-wrap; }
.editor-slot.is-readonly { cursor: default; }
.editor-slot.is-readonly:hover { transform: none; box-shadow: none; border-color: var(--border); }
.editor-slot.is-unique.is-readonly:hover { border-color: color-mix(in srgb, var(--color-unique) 50%, var(--border));
  box-shadow: inset 0 0 18px rgb(239 105 22 / .07); }
.editor-slot.is-magic.is-readonly:hover { border-color: color-mix(in srgb, var(--color-magic) 50%, var(--border)); }
.editor-slot.is-rare.is-readonly:hover { border-color: color-mix(in srgb, var(--color-rare) 50%, var(--border)); }
.dossier--readonly .editor-orb { cursor: default; }
.build-switcher__name--static { display: block; margin-top: 6px; color: var(--color-normal);
  font-size: 12px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ---- chapters ---- */
.editor-chapter { padding: 26px 0 6px; scroll-margin-top: 16px; }
.chapter-head { display: flex; align-items: baseline; gap: 14px; margin-bottom: 14px; }
.chapter-head h2 { margin: 0; color: var(--color-normal); font-family: var(--font-display);
  font-size: 23px; font-weight: 500; letter-spacing: .03em; }
.chapter-rule { flex: 1; height: 1px; background: linear-gradient(90deg, var(--border), transparent); }

/* ---- gear: abstract doll (in-game spatial arrangement, no game art) ----
   The doll owns the full section width; checks + tray sit in a card row
   beneath it, so the wells can run mobalytics-large. */
.editor-gear-layout { display: flex; flex-direction: column; gap: 14px; }
.editor-doll-board { position: relative; padding: 22px 18px; border: 1px solid var(--border);
  border-radius: 8px; box-shadow: 0 12px 32px rgb(0 0 0 / .14);
  background: radial-gradient(ellipse at 50% 28%, rgb(255 255 255 / .025), transparent 60%),
    color-mix(in srgb, var(--bg-surface) 88%, transparent); }
.editor-doll { display: grid; gap: 10px; max-width: 705px; margin: 0 auto;
  grid-template-columns: 1.25fr 1fr 1.25fr 1fr 1.25fr;
  grid-template-rows: 30px minmax(90px, auto) minmax(105px, auto) minmax(105px, auto) minmax(78px, auto) minmax(87px, auto);
  grid-template-areas:
    ".  .      helmet .      ."
    "w1 .      helmet amulet w2"
    "w1 ring1  body   ring2  w2"
    "w1 gloves body   boots  w2"
    ".  gloves belt   boots  ."
    ".  flask1 charm1 flask2 ."; }
.editor-slot--weapon1a, .editor-slot--weapon2a { grid-area: w1; }
.editor-slot--weapon1b, .editor-slot--weapon2b { grid-area: w2; }
.editor-slot--helmet { grid-area: helmet; }
.editor-slot--body   { grid-area: body; }
.editor-slot--amulet { grid-area: amulet; }
.editor-slot--ring1  { grid-area: ring1; align-self: end; min-height: 72px; }
.editor-slot--ring2  { grid-area: ring2; align-self: end; min-height: 72px; }
.editor-slot--gloves { grid-area: gloves; align-self: end; min-height: 158px; }
.editor-slot--boots  { grid-area: boots;  align-self: end; min-height: 158px; }
.editor-slot--belt   { grid-area: belt; }
.editor-slot--flask1 { grid-area: flask1; }
.editor-slot--flask2 { grid-area: flask2; }
.editor-slot--charm1 { grid-area: charm1; }
.editor-slot { position: relative; display: flex; flex-direction: column; align-items: center;
  justify-content: center; gap: 4px; padding: 8px 6px; text-align: center; cursor: pointer;
  border: 1px solid var(--border); border-radius: 7px;
  background: color-mix(in srgb, var(--bg-base) 55%, transparent);
  transition: border-color 120ms ease, box-shadow 120ms ease, transform 120ms ease; }
.editor-slot:hover { transform: translateY(-1px);
  border-color: color-mix(in srgb, var(--accent-ui) 45%, var(--border));
  box-shadow: 0 6px 18px rgb(0 0 0 / .35); }
.editor-slot:focus-visible { outline: 2px solid var(--accent-ui); outline-offset: 2px; }
.editor-slot.is-empty { border-style: dashed; }
.editor-slot.is-empty:hover .editor-slot__hint { color: var(--accent-ui); }
.editor-slot.is-unique { border-color: color-mix(in srgb, var(--color-unique) 50%, var(--border));
  box-shadow: inset 0 0 18px rgb(239 105 22 / .07); }
.editor-slot.is-unique:hover { border-color: color-mix(in srgb, var(--color-unique) 75%, var(--border)); }
/* Base-item rarity tint by chosen mod count — magic blue, rare yellow (mirrors
   the unique treatment above). */
.editor-slot.is-magic { border-color: color-mix(in srgb, var(--color-magic) 50%, var(--border));
  box-shadow: inset 0 0 18px color-mix(in srgb, var(--color-magic) 10%, transparent); }
.editor-slot.is-magic:hover { border-color: color-mix(in srgb, var(--color-magic) 78%, var(--border)); }
.editor-slot.is-rare { border-color: color-mix(in srgb, var(--color-rare) 50%, var(--border));
  box-shadow: inset 0 0 18px color-mix(in srgb, var(--color-rare) 10%, transparent); }
.editor-slot.is-rare:hover { border-color: color-mix(in srgb, var(--color-rare) 78%, var(--border)); }
.editor-slot.is-ghost { border-style: dashed; opacity: .6; cursor: default; }
.editor-slot--violation { outline: 1px solid color-mix(in srgb, var(--color-corrupted) 70%, transparent); }
.editor-slot__label { font-size: 8.5px; letter-spacing: .14em; text-transform: uppercase;
  color: var(--color-default); order: 2; }
.editor-slot__hint { font-size: 11px; letter-spacing: .1em; text-transform: uppercase;
  color: var(--color-default); }
.editor-slot__ghost { font-size: 10px; color: var(--color-default); font-style: italic; }
.editor-slot__clear { position: absolute; top: 4px; right: 4px; padding: 3px 5px; border: 0;
  border-radius: 4px; background: rgb(0 0 0 / .5); color: var(--color-default);
  font-size: 11px; line-height: 1; cursor: pointer; opacity: 0; transition: opacity 120ms ease; }
.editor-slot:hover .editor-slot__clear, .editor-slot__clear:focus-visible { opacity: 1; }
.editor-slot__clear:hover { color: var(--color-normal); }
.editor-item { display: flex; flex-direction: column; align-items: center; gap: 4px; min-width: 0; }
.editor-item__name { font-size: 12.5px; line-height: 1.25; overflow-wrap: anywhere; }
.editor-item__name--unique { color: var(--color-unique); }
.editor-item__name--base { color: var(--color-normal); }
.editor-item__name--gem { color: var(--color-gem); }
.well-tile { position: relative; width: 32px; height: 32px; display: flex; align-items: center;
  justify-content: center; border-radius: 6px; background: rgb(255 255 255 / .06);
  color: rgb(255 255 255 / .75); font: 11px/1 var(--font-display); }
.well-tile__img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; }
/* Full-bleed art in filled wells — identity from the icon, detail from the
   hover card (mobalytics pattern). */
.editor-item--art { position: absolute; inset: 8px; display: block; }
.well-art { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  color: rgb(255 255 255 / .7); font: 16px/1 var(--font-display); }
.well-art__img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain;
  filter: drop-shadow(0 4px 10px rgb(0 0 0 / .55)); }
.well-art__img + .well-art__initials { display: none; }
.editor-slot.is-filled:hover .well-art__img, .editor-slot.is-unique:hover .well-art__img,
.editor-slot.is-magic:hover .well-art__img, .editor-slot.is-rare:hover .well-art__img {
  transform: scale(1.04); transition: transform 120ms ease; }
/* Initials are the fallback only — hidden while real art is present. */
.well-tile__img + .well-tile__initials, .orb-tile__img + .orb-tile__initials { display: none; }

.editor-gear-side { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; align-items: start; }
.editor-side-card { padding: 15px 17px; border: 1px solid var(--border); border-radius: 8px;
  background: color-mix(in srgb, var(--bg-surface) 88%, transparent);
  box-shadow: 0 12px 32px rgb(0 0 0 / .14); }
.editor-side-card > h3 { margin: 0 0 10px; color: var(--color-default); font-size: 11px;
  font-weight: 650; letter-spacing: .16em; text-transform: uppercase; }
.editor-checks { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 5px; }
.editor-checks li { padding: 7px 11px; border-radius: 6px; font-size: 13px;
  border: 1px solid color-mix(in srgb, var(--border) 80%, transparent); color: var(--color-default); }
.editor-checks li.is-warn { border-color: color-mix(in srgb, var(--color-notable) 40%, var(--border));
  background: color-mix(in srgb, var(--color-notable) 7%, transparent); color: var(--color-notable); }
.editor-checks--clear { margin: 0; color: var(--color-default); font-size: 11.5px; }
.editor-tray__list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 4px; }
.editor-tray__row { display: flex; align-items: center; justify-content: space-between; gap: 8px;
  padding: 5px 6px; border-radius: 6px; }
.editor-tray__row:hover { background: rgb(255 255 255 / .04); }
.editor-tray__row .editor-item { flex-direction: row; }
.editor-tray__row .well-tile { width: 32px; height: 32px; font-size: 11px; }
.editor-tray__actions { display: flex; gap: 5px; }
.editor-tray__actions button { padding: 2px 9px; border: 1px solid var(--border); border-radius: 999px;
  background: none; color: var(--color-default); font: 10.5px/1.3 var(--font-smallcaps); cursor: pointer; }
.editor-tray__actions button:hover { color: var(--color-normal);
  border-color: color-mix(in srgb, var(--accent-ui) 50%, var(--border)); }
.editor-none { margin: 0; opacity: .55; font-size: 13px; }
.editor-set-toggle { display: inline-flex; border: 1px solid var(--border); border-radius: 999px; overflow: hidden; }
.editor-set-btn { padding: 3px 12px; border: 0; background: transparent; color: var(--color-default);
  font: 11px/1.4 var(--font-smallcaps); letter-spacing: .08em; cursor: pointer; }
.editor-set-btn.is-active { background: color-mix(in srgb, var(--accent-ui) 14%, transparent);
  color: var(--color-normal); }
.editor-set-btn:not(.is-active):hover { color: var(--color-normal); }

/* ---- skills: constellation chains ---- */
.editor-chains { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 12px; }
.editor-chain { position: relative; display: flex; flex-wrap: wrap; align-items: flex-start; padding: 22px 18px 16px;
  border: 1px solid var(--border); border-radius: 8px; overflow-x: auto; min-width: 0;
  background: color-mix(in srgb, var(--bg-surface) 88%, transparent);
  box-shadow: 0 12px 32px rgb(0 0 0 / .14);
  transition: border-color 120ms ease, transform 120ms ease; }
.editor-chain:hover { transform: translateY(-1px);
  border-color: color-mix(in srgb, var(--accent-ui) 30%, var(--border)); }
.chain-meta { position: absolute; top: 7px; right: 10px; display: flex; align-items: center; gap: 10px; }
.chain-spirit { color: var(--color-crafted); font-size: 10.5px; letter-spacing: .15em; text-transform: uppercase; }
.editor-setup__controls { display: flex; gap: 2px; }
.editor-setup__controls button { width: 26px; height: 26px; padding: 0; border: 0; border-radius: 4px;
  background: none; color: var(--color-default); font-size: 14px; cursor: pointer; }
.editor-setup__controls button:hover { color: var(--color-normal); background: rgb(255 255 255 / .07); }
.editor-node { display: flex; flex-direction: column; align-items: center; gap: 7px;
  min-width: 116px; text-align: center; }
.editor-node__name { font-size: 13px; line-height: 1.25; color: var(--color-normal); max-width: 120px; }
.editor-node__name--gem { color: var(--color-gem); font-size: 14.5px; }
.editor-node__sub { font-size: 10px; letter-spacing: .1em; text-transform: uppercase; color: var(--color-default); }
.editor-orb { position: relative; display: flex; align-items: center; justify-content: center;
  border-radius: 50%; cursor: pointer; transition: box-shadow 120ms ease, transform 120ms ease; }
.editor-orb--gem { width: 64px; height: 64px; border: 2px solid var(--color-gem);
  background: radial-gradient(circle at 35% 30%, color-mix(in srgb, var(--color-gem) 30%, var(--bg-base)), var(--bg-base));
  box-shadow: 0 0 14px color-mix(in srgb, var(--color-gem) 30%, transparent); }
.editor-orb--gem:hover { transform: scale(1.06);
  box-shadow: 0 0 20px color-mix(in srgb, var(--color-gem) 55%, transparent); }
.editor-node--support .editor-orb { width: 44px; height: 44px; margin-top: 10px;
  border: 2px solid var(--color-gem-w); background: var(--bg-surface); }
.editor-orb--r { border-color: var(--color-gem-r) !important; }
.editor-orb--g { border-color: var(--color-gem-g) !important; }
.editor-orb--b { border-color: var(--color-gem-b) !important; }
.editor-orb--w { border-color: var(--color-gem-w) !important; }
.editor-orb--empty { border: 2px dashed var(--border) !important; background: transparent;
  color: var(--color-default); font-size: 16px; }
.editor-orb--empty:hover { border-color: var(--color-gem) !important; color: var(--color-gem); }
.orb-tile { position: relative; width: 100%; height: 100%; display: flex; align-items: center;
  justify-content: center; border-radius: 50%; overflow: hidden;
  color: rgb(255 255 255 / .8); font: 12px/1 var(--font-display); }
.editor-orb--gem .orb-tile { font-size: 17px; }
.orb-tile__img { position: absolute; inset: 2px; width: calc(100% - 4px); height: calc(100% - 4px);
  object-fit: contain; }
.chain-link { flex: none; align-self: flex-start; margin-top: 31px; width: 42px; height: 2px;
  background: linear-gradient(90deg, color-mix(in srgb, var(--color-gem) 55%, transparent),
    color-mix(in srgb, var(--color-gem) 20%, transparent)); }
.chain-link--dim { background: repeating-linear-gradient(90deg, var(--border) 0 5px, transparent 5px 9px); }
.editor-chain--spirit { border-left: 3px solid var(--color-crafted); }
.editor-chain--spirit .editor-orb--gem { border-color: var(--color-crafted);
  box-shadow: 0 0 14px color-mix(in srgb, var(--color-crafted) 30%, transparent); }
.editor-chain--spirit .editor-node__name--gem { color: var(--color-crafted); }
.editor-chain--granted { border-left: 3px solid var(--color-unique); }
.editor-chain--granted .editor-orb--gem { border-color: var(--color-unique);
  box-shadow: 0 0 14px color-mix(in srgb, var(--color-unique) 25%, transparent); }
.editor-setup__source { display: inline-flex; align-items: center; gap: 6px;
  font-size: 11px; color: var(--color-default); }
.editor-source-chip { display: inline-flex; width: 26px; height: 26px; padding: 2px;
  border: 1px solid color-mix(in srgb, var(--color-unique) 45%, var(--border)); border-radius: 5px;
  background: rgb(0 0 0 / .3); cursor: help; }
.source-tile { position: relative; width: 100%; height: 100%; display: flex; align-items: center;
  justify-content: center; color: rgb(255 255 255 / .7); font: 9px/1 var(--font-display); }
.source-tile__img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; }
.source-tile__img + .source-tile__initials { display: none; }
.editor-socket__clear { position: absolute; top: -7px; right: -7px; display: none; width: 18px; height: 18px;
  padding: 0; border: 0; border-radius: 50%; background: rgb(0 0 0 / .7); color: var(--color-normal);
  font-size: 11px; line-height: 1; cursor: pointer; z-index: 1; }
.editor-orb:hover .editor-socket__clear, .editor-orb:focus-within .editor-socket__clear { display: block; }
.editor-chain__warning { flex-basis: 100%; margin: 10px 0 0; color: var(--color-notable); font-size: 12.5px; }
.editor-setup-add { display: block; width: 100%; margin-top: 12px; padding: 13px;
  border: 1px dashed var(--border); border-radius: 8px;
  background: none; color: var(--color-default); font: 13.5px/1.4 var(--font-smallcaps);
  letter-spacing: .06em; cursor: pointer; }
.editor-setup-add:hover { color: var(--accent-ui);
  border-color: color-mix(in srgb, var(--accent-ui) 45%, var(--border)); }

/* ---- tree + notes ---- */
.editor-tree-band { display: flex; flex-direction: column; gap: 12px; padding: 20px;
  border: 1px solid var(--border); border-radius: 8px;
  background: color-mix(in srgb, var(--bg-surface) 88%, transparent);
  box-shadow: 0 12px 32px rgb(0 0 0 / .14); }
.editor-tree-code { display: flex; flex-direction: column; gap: 5px; max-width: 38rem;
  color: var(--color-default); font-size: 11px; letter-spacing: .12em; text-transform: uppercase; }
.editor-tree-code input { padding: 8px 11px; border: 1px solid var(--border); border-radius: 6px;
  background: rgb(0 0 0 / .25); color: var(--text); font: 13.5px/1.4 var(--font-regular);
  letter-spacing: normal; text-transform: none; }
.editor-tree-code input.is-invalid { border-color: var(--color-corrupted); }
.editor-tree-hint { margin: 0; color: var(--color-default); font-size: 12px; }
.editor-notes textarea { width: 100%; min-height: 10rem; padding: 13px 15px; resize: vertical;
  border: 1px solid var(--border); border-radius: 8px; background: rgb(0 0 0 / .25);
  color: var(--text); font: 15px/1.6 var(--font-regular); }
.editor-notes textarea:focus-visible, .dossier-desc:focus-visible, .editor-tree-code input:focus-visible {
  outline: none; border-color: color-mix(in srgb, var(--accent-ui) 58%, var(--border));
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent-ui) 10%, transparent); }

@media (max-width: 980px) {
  .dossier { grid-template-columns: minmax(0, 1fr); gap: 12px; }
  .dossier-rail { position: static; }
  .dossier-rail__nav { display: flex; border-left: 0; border-bottom: 1px solid var(--border); }
  .dossier-rail__nav a { border-left: 0; border-bottom: 2px solid transparent; padding: 6px 10px; }
  .dossier-rail__nav a.is-here { border-bottom-color: var(--accent-ui); }
  .dossier-rail__note { display: none; }
  .dossier-head { flex-direction: column; }
  .editor-gear-side { grid-template-columns: 1fr; }
}
@media (max-width: 640px) {
  .editor-doll { gap: 6px;
    grid-template-rows: 26px minmax(64px, auto) minmax(76px, auto) minmax(76px, auto) minmax(56px, auto) minmax(60px, auto); }
  .editor-slot--ring1, .editor-slot--ring2 { min-height: 56px; }
  .editor-slot--gloves, .editor-slot--boots { min-height: 120px; }
  .editor-item__name { font-size: 9px; }
  .editor-node { min-width: 76px; }
  .chain-link { width: 20px; }
}
@media (prefers-reduced-motion: reduce) {
  .editor-slot, .editor-chain, .editor-orb, .dossier-share { transition: none; }
}

/* ---- well mods indicator + affordance ---- */
.editor-slot__mods-edit { position: absolute; bottom: 4px; right: 4px; padding: 2px 6px; border: 0;
  border-radius: 4px; background: rgb(0 0 0 / .5); color: var(--color-default); font: 9px/1 var(--font-smallcaps);
  cursor: pointer; opacity: 0; transition: opacity 120ms ease; }
.editor-slot:hover .editor-slot__mods-edit, .editor-slot__mods-edit:focus-visible { opacity: 1; }
.editor-slot__mods-edit:hover { color: var(--color-crafted); }

/* ---- anchored mod picker popover ---- */
/* Two panes: the chooser and a live card of the item being crafted. --mirror
   puts the card on the left, for slots sitting in the right half of the screen. */
.mod-picker-pop { position: absolute; z-index: 60; display: flex; align-items: flex-start; gap: 10px; }
.mod-picker-pop--mirror { flex-direction: row-reverse; }
.mod-picker-host { width: 340px; flex: none; }
.mod-picker-preview { flex: none; max-width: 390px; max-height: min(80vh, 620px); overflow-y: auto;
  overscroll-behavior: contain; filter: drop-shadow(0 18px 44px rgb(0 0 0 / .45)); }
.mod-picker-preview[hidden] { display: none; }
.mod-picker-preview .newItemPopup { margin: 0; }
/* ONE scroller. The card is a flex column: a fixed header block (search +
   current selection) and a single scrolling body holding the pools. Nesting a
   scrolling selection inside a scrolling card gave three overlapping scrollbars
   with the page's, and which one caught the wheel depended on the cursor.
   overscroll-behavior stops a wheel that reaches the end from scrolling the
   page out from under the popover. */
.mod-picker { max-height: min(80vh, 620px); display: flex; flex-direction: column; overflow: hidden;
  border: 1px solid color-mix(in srgb, var(--color-crafted) 40%, var(--border)); border-radius: 8px;
  background: var(--bg-surface); box-shadow: 0 18px 44px rgb(0 0 0 / .45); }
.mod-picker__body { flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain; }
/* Header + current selection ride together above the scroller: the selection is
   what you scroll the pools to change, so it has to stay put. Bounded at 6 mods
   + 1 implicit; the max-height is a safety valve for a very short viewport. */
.mod-picker__sticky { flex: 0 0 auto; max-height: 62%; overflow-y: auto; overscroll-behavior: contain;
  background: var(--bg-surface); border-bottom: 1px solid var(--border); }
.mod-picker__head { display: flex; align-items: center; gap: 8px;
  padding: 8px 10px; background: var(--bg-surface); }
.mod-picker__head h3 { margin: 0; font-size: 12px; color: var(--color-normal); }
.mod-picker__search { flex: 1; padding: 4px 8px; border: 1px solid var(--border); border-radius: 6px;
  background: rgb(0 0 0 / .25); color: var(--text); font: 12px/1.4 var(--font-regular); }
.mod-picker__close { border: 0; background: none; color: var(--color-default); font-size: 15px; cursor: pointer; }
.mod-picker__cols { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; padding: 8px 10px; }
/* Corrupted implicit chooser — full-width below the columns, rendered red. */
.mod-picker__col--corrupt { padding: 8px 10px; border-top: 1px solid var(--border); }
.mod-picker__row--corrupt .mod-picker__generic--corrupt,
.mod-picker__chosen-row--corrupt .mod-picker__generic--corrupt {
  color: var(--color-corrupted); }
.mod-picker__row--corrupt:hover { border-color: color-mix(in srgb, var(--color-corrupted) 55%, var(--border)); }
.mod-picker__col--corrupt > h4 { color: var(--color-corrupted); }
.mod-picker__col h4 { margin: 0 0 6px; padding: 2px 0;
  font-size: 9px; letter-spacing: .12em; text-transform: uppercase;
  color: var(--color-default); display: flex; justify-content: space-between; }
.mod-picker__row { display: flex; align-items: center; justify-content: space-between; gap: 8px;
  width: 100%; text-align: left; padding: 4px 6px; margin-bottom: 2px;
  border: 1px solid transparent; border-radius: 5px; background: none; color: var(--color-normal);
  font: 11px/1.3 var(--font-regular); cursor: pointer; }
.mod-picker__row:hover { border-color: color-mix(in srgb, var(--color-crafted) 45%, var(--border)); }
.mod-picker__row.is-chosen { color: var(--color-crafted); }
.mod-picker__origin { flex: none; padding: 1px 6px; border-radius: 999px; font-size: 8.5px;
  letter-spacing: .08em; text-transform: uppercase; white-space: nowrap; }
.mod-picker__origin--desecrated { color: var(--color-desecrated, #c9a0ff);
  border: 1px solid color-mix(in srgb, var(--color-desecrated, #c9a0ff) 45%, var(--border));
  background: color-mix(in srgb, var(--color-desecrated, #c9a0ff) 12%, transparent); }
.mod-picker__chosen { list-style: none; margin: 0; padding: 8px 10px; border-top: 1px solid var(--border);
  display: flex; flex-direction: column; gap: 5px; flex: none;
  background: color-mix(in srgb, var(--color-crafted) 7%, var(--bg-surface)); }
/* One line per family name (hover for the full text) — wrapped names made each
   pick three lines tall and pushed the pools off the popover. */
.mod-picker__chosen-row .mod-picker__generic { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Two lines per pick: flag + family + remove, then the tier select full width.
   One line squeezed the select to a few characters, which is the one control
   here you actually need to read. */
.mod-picker__chosen-row { display: grid; grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center; column-gap: 6px; row-gap: 3px;
  padding-bottom: 5px; border-bottom: 1px solid color-mix(in srgb, var(--border) 60%, transparent); }
.mod-picker__chosen-row:last-child { padding-bottom: 0; border-bottom: 0; }
.mod-picker__chosen-row > .mod-picker__kind { grid-area: 1 / 1; }
.mod-picker__chosen-row > .mod-picker__generic { grid-area: 1 / 2; }
.mod-picker__chosen-row > .mod-picker__remove { grid-area: 1 / 3; }
.mod-picker__chosen-row > .mod-picker__tier { grid-area: 2 / 1 / auto / -1; max-width: none; width: 100%; }
/* P / S / I flag, matching the card's planner-mod__kind badge. */
.mod-picker__kind { flex: none; width: 13px; text-align: center; border-radius: 3px;
  border: 1px solid var(--border); font: 8.5px/1.5 var(--font-smallcaps); color: var(--color-default); }
.mod-picker__kind--corrupt { color: var(--color-corrupted);
  border-color: color-mix(in srgb, var(--color-corrupted) 45%, var(--border)); }
.mod-picker__generic { flex: 1; font-size: 11px; color: var(--color-magic, var(--color-normal)); }
.mod-picker__tier { max-width: 60%; padding: 2px 4px; border: 1px solid var(--border); border-radius: 4px;
  background: rgb(0 0 0 / .25); color: var(--text); font: 10px/1.3 var(--font-regular); }
.mod-picker__remove { border: 0; background: none; color: var(--color-default); cursor: pointer; font-size: 13px; }
.mod-picker__none { margin: 0; font-size: 11px; color: var(--color-default); }
@media (prefers-reduced-motion: reduce) { .editor-slot__mods-edit { transition: none; } }

/* ---- Passive tree embed (Phase 5) ---- */
.editor-tree-embed { position: relative; margin: 4px 0 14px; }
/* The read-only preview mounts into .editor-tree-mount inside the same wrapper;
   the wrapper already owns the spacing. */
.editor-tree-embed > .editor-tree-mount { margin-top: 0; }
/* A fixed (read-only) list has no drag handles, but the tiles still click
   through to their node in the tree — so pointer, not grab. */
.prio-list:not([data-prio-dnd]) .prio-tile { cursor: pointer; }
.passive-tree-wrap--embed { position: relative; width: 100%; height: min(72vh, 720px);
  border: 1px solid var(--border); border-radius: 8px; overflow: hidden;
  background: color-mix(in srgb, var(--bg-base) 60%, transparent); }
.passive-tree-wrap--embed canvas { display: block; width: 100%; height: 100%; touch-action: none; }
/* The build's own class/ascendancy picker (Dossier header) is authoritative and
   drives the embed, so hide the embed's redundant selectors in the editor. */
.passive-tree-wrap--embed .tree-field--class,
.passive-tree-wrap--embed .tree-field--asc { display: none; }
.editor-tree-points { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 10px; }
.tree-chip { display: inline-flex; align-items: baseline; gap: 5px; padding: 4px 10px;
  border: 1px solid var(--border); border-radius: 999px;
  background: color-mix(in srgb, var(--bg-surface) 88%, transparent);
  color: var(--color-default); font: 11px/1.3 var(--font-smallcaps); letter-spacing: .04em; }
.tree-chip b { color: var(--color-normal); font-size: 13px; }

/* ---- Notable Priority list ---- */
.editor-notable-priority { margin-top: 8px; }
.editor-subhead { margin: 0 0 10px; color: var(--color-default); font-size: 10px; font-weight: 650;
  letter-spacing: .16em; text-transform: uppercase; }
/* Square icon tiles flowing left-to-right, wrapping — a compact constellation
   read (order = reading order) instead of full-width stacked rows. */
/* position: relative anchors the drop caret; the trailing padding gives the
   "drop after the last tile" gesture somewhere to land even when the last row
   is full. */
.prio-list { position: relative; list-style: none; margin: 0; padding: 0 0 0 6px;
  display: flex; flex-wrap: wrap; gap: 8px; min-height: 46px; }
.prio-tile.is-dragging { opacity: .35; cursor: grabbing; }
.prio-tile.is-dragging:hover { transform: none; }
/* Drop caret — where the dragged tile lands on release. */
.prio-dropbar { position: absolute; width: 2px; border-radius: 2px; pointer-events: none;
  background: var(--accent-ui);
  box-shadow: 0 0 9px 1px color-mix(in srgb, var(--accent-ui) 65%, transparent); }
.prio-tile { position: relative; flex: none; height: 46px;
  display: flex; align-items: center; gap: 3px; cursor: grab; border-radius: 8px;
  box-shadow: 0 0 11px 1px rgb(0 0 0 / .42);
  transition: transform 120ms ease, box-shadow 120ms ease; }
.prio-tile:hover { transform: translateY(-2px); z-index: 1; box-shadow: 0 0 18px 2px rgb(0 0 0 / .5); }
/* The frame/border lives on the icon itself; the grip sits outside it. */
.prio-icon { width: 40px; height: 40px; display: block; flex: none; pointer-events: none;
  border: 1px solid var(--border); border-radius: 8px;
  background: color-mix(in srgb, var(--bg-surface) 88%, transparent);
  transition: border-color 120ms ease; }
.prio-tile:hover .prio-icon { border-color: color-mix(in srgb, var(--accent-ui) 60%, var(--border)); }
.prio-tile.is-keystone .prio-icon { border-color: color-mix(in srgb, var(--color-keystone, var(--color-unique)) 55%, var(--border)); }
.prio-tile.is-notable .prio-icon, .prio-tile.is-blighted .prio-icon { border-color: color-mix(in srgb, var(--color-notable) 45%, var(--border)); }
.prio-tile.is-ascNotable .prio-icon { border-color: color-mix(in srgb, var(--color-crafted) 55%, var(--border)); }
/* Dedicated grip gutter to the left of the icon (not overlaid) — always visible. */
.prio-handle { flex: none; width: 11px; text-align: center; color: var(--color-default);
  font-size: 13px; line-height: 1; letter-spacing: -2px; opacity: .7; transition: opacity 120ms ease; }
.prio-tile:hover .prio-handle { opacity: 1; color: var(--color-normal); }
.prio-remove { position: absolute; top: -6px; right: -6px; width: 16px; height: 16px; padding: 0; border: 0;
  border-radius: 50%; background: rgb(0 0 0 / .8); color: var(--color-normal);
  font-size: 10px; line-height: 1; cursor: pointer; opacity: 0; transition: opacity 120ms ease; }
.prio-tile:hover .prio-remove, .prio-remove:focus-visible { opacity: 1; }
.prio-remove:hover { color: var(--color-corrupted); }

@media (max-width: 640px) {
  .passive-tree-wrap--embed { height: min(64vh, 520px); }
}
@media (prefers-reduced-motion: reduce) {
  .prio-tile { transition: none; }
}

/* ---- Phase 8: variant strip ------------------------------------------- */
.variant-strip {
  display: flex; align-items: center; gap: .75rem;
  margin: 0 0 1.25rem; padding-bottom: .5rem;
  border-bottom: 1px solid var(--border);
  flex-wrap: wrap;
}
.variant-strip__label {
  font-size: .7rem; letter-spacing: .12em; text-transform: uppercase;
  opacity: .55; flex: 0 0 auto;
}
.variant-strip__tabs {
  display: flex; align-items: center; gap: .35rem;
  list-style: none; margin: 0; padding: 0; flex-wrap: wrap;
}
.variant-strip__tabs > li { display: flex; align-items: center; }
.variant-tab {
  appearance: none; background: transparent; cursor: pointer;
  border: 1px solid var(--border); border-radius: 999px;
  padding: .3rem .7rem; font: inherit; font-size: .82rem;
  color: inherit; opacity: .72;
}
.variant-tab:hover { opacity: 1; }
.variant-tab.is-current {
  opacity: 1; font-weight: 600;
  border-color: var(--accent-ui); color: var(--accent-ui);
}
.variant-tab--add { opacity: .55; border-style: dashed; }
.variant-tab--add:hover { opacity: .95; }
/* Rename/detach for the active variant. Framed as real buttons: as bare glyphs
   at .8rem/.4 opacity they read as specks floating between pills. */
.variant-tab__tools { display: inline-flex; align-items: center; gap: 2px; margin-left: 5px; }
.variant-tab__edit, .variant-tab__drop {
  appearance: none; cursor: pointer; display: inline-flex;
  align-items: center; justify-content: center;
  width: 24px; height: 24px; padding: 0; border-radius: 50%;
  border: 1px solid color-mix(in srgb, var(--accent-ui) 30%, transparent);
  background: color-mix(in srgb, var(--accent-ui) 10%, transparent);
  color: var(--accent-ui); opacity: .8;
  font-size: 14px; line-height: 1;
  transition: opacity 120ms ease, background-color 120ms ease, border-color 120ms ease;
}
.variant-tab__edit:hover, .variant-tab__drop:hover {
  opacity: 1;
  background: color-mix(in srgb, var(--accent-ui) 22%, transparent);
  border-color: color-mix(in srgb, var(--accent-ui) 55%, transparent);
}
.variant-tab__drop:hover {
  color: var(--color-corrupted);
  background: color-mix(in srgb, var(--color-corrupted) 18%, transparent);
  border-color: color-mix(in srgb, var(--color-corrupted) 50%, transparent);
}
.variant-tab__edit:focus-visible, .variant-tab__drop:focus-visible {
  outline: 2px solid var(--accent-ui); outline-offset: 2px;
}
.icon-pencil { width: 1em; height: 1em; display: block; }
.variant-tab__input {
  font: inherit; font-size: .82rem; padding: .3rem .7rem;
  border-radius: 999px; border: 1px solid var(--accent-ui);
  background: rgba(0,0,0,.25); color: inherit; max-width: 12rem;
}

.dossier-export-note {
  flex-basis: 100%; margin: .5rem 0 0;
  font-size: .78rem; opacity: .7; line-height: 1.45;
}

.build-switcher__limit { margin: 5px 2px 0; color: var(--color-default); font-size: 10px; line-height: 1.4; }
.variant-tab--add[disabled], .build-switcher__new[disabled], .dossier-action[disabled] {
  opacity: .38; cursor: not-allowed;
}

.dossier-banner--warn { border-color: color-mix(in srgb, var(--color-notable) 45%, var(--border));
  background: color-mix(in srgb, var(--color-notable) 8%, transparent); color: var(--color-notable); }

/* ---- overflow containment for untrusted / pathological content -----------
   A shared build's strings are clamped by length, but length is not width: one
   60-character unbroken word still has to be allowed to break, and the grid
   column has to be allowed to shrink. Without these, an imported build could
   push the whole page sideways. */
.dossier-name, .dossier-name--static, .dossier-name-input {
  max-width: 100%; overflow-wrap: anywhere;
}
.dossier-head, .dossier-head__copy, .dossier-main, .editor-chains, .editor-chains > li { min-width: 0; }
.dossier-desc, .dossier-desc--static, .editor-notes-static { overflow-wrap: anywhere; }
.variant-tab { max-width: 16rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.build-switcher__row b { overflow-wrap: anywhere; }
.editor-item__name, .editor-node__name { overflow-wrap: anywhere; }

/* ---- ascendancy hero banner ---------------------------------------------
   Art occupies the right of the header — the region the copy column does not
   use — and fades out leftward so it never sits under the title or the class
   pills. The background-image itself comes from the GENERATED
   class-banners.css (one rule per ascendancy that has art), so an ascendancy
   with no illustration simply matches nothing and renders no banner.
   Built by scripts/build-class-banners.js; see it for the crop rationale. */
.dossier-head { position: relative; }
/* NO overflow:hidden here. The header is the containing block for the class and
   ascendancy popovers, so clipping it hid all but the top two rows of the
   dropdown. The hero is absolutely positioned with background-size:cover, so it
   cannot escape its own box anyway — it clips itself. */
.dossier-hero {
  position: absolute; inset: 0 0 0 63%; z-index: 0; pointer-events: none;
  border-radius: 0 10px 0 0; overflow: hidden;
  background-repeat: no-repeat; background-size: cover; background-position: center 30%;
  /* Fade leftward into the copy, and downward off the bottom rule. The vertical
     stop also keeps the art faint behind .dossier-actions, whose grey pill
     buttons would otherwise lose contrast against busy artwork. */
  mask-image:
    linear-gradient(90deg, transparent 0%, rgb(0 0 0 / .45) 38%, #000 78%),
    linear-gradient(180deg, rgb(0 0 0 / .5) 0%, #000 46%, rgb(0 0 0 / .25) 100%);
  mask-composite: intersect;
  -webkit-mask-composite: source-in;
  opacity: .78;
}
/* The copy rides above the art. The actions now sit INSIDE the copy column
   (between the title and the class row) rather than opposite it, so nothing
   overlaps the artwork and the pills need no backdrop plate to stay readable. */
.dossier-head__copy, .dossier-export-note { position: relative; z-index: 1; }
.has-hero .dossier-head__copy { max-width: 61%; }
@media (max-width: 900px) {
  /* Too narrow to share the row: art becomes a faint backdrop behind full-width copy. */
  .has-hero .dossier-head__copy { max-width: 100%; }
  .dossier-hero { inset: 0; opacity: .22; }
}
/* Light theme needs MORE of the art, not less. The illustrations are uniformly
   dark, so fading them over a pale ground turns them to grey mush rather than
   reading as a deliberate image; keep them close to full strength and let the
   horizontal mask do the blending. */
:root[data-theme="light"] .dossier-hero { opacity: .92; }
/* Pre-existing light-theme contrast bug, surfaced by putting art behind these:
   .dossier-share paints --color-normal (#c8c8c8), and tokens.css overrides only
   the bg / border / text tokens for light, so the label sat light-grey on
   near-white. */
:root[data-theme="light"] .dossier-share,
:root[data-theme="light"] .dossier-action:hover { color: var(--text); }
:root[data-theme="light"] .has-hero .dossier-action,
:root[data-theme="light"] .has-hero .dossier-share {
  background-color: color-mix(in srgb, var(--bg-base) 90%, transparent);
}
@media (prefers-reduced-motion: reduce) { .dossier-hero { transition: none; } }

/* ---- read-only tree preview (shared view / import) ----------------------
   Mounted automatically — the tree is pivotal to a build. The embed is ~3 MB but
   loads dynamically, so it fills in after the rest of the preview has painted. */
.editor-tree-mount:empty { display: none; }
.editor-tree-mount { margin-top: 12px; }
.editor-tree-mount.is-loading { padding: 18px 0; color: var(--color-default); font-size: 12.5px; }
/* A preview embed is shorter than the editor's — it is a look, not a workspace. */
.passive-tree-wrap--readonly { height: min(56vh, 520px); }

/* Recommended supports, grouped by the uncut-support level that crafts them —
   the same tiering the gem detail page uses, so the two read consistently. */
.picker-tier { margin: 0 0 6px; }
.picker-tier__head { display: flex; align-items: center; gap: 8px; margin: 8px .5rem 3px;
  font: 11px/1.4 var(--font-smallcaps); letter-spacing: .1em; text-transform: uppercase;
  color: var(--color-default); }
.picker-tier__num { display: inline-flex; align-items: center; justify-content: center;
  min-width: 20px; height: 20px; padding: 0 5px; border-radius: 4px;
  border: 1px solid color-mix(in srgb, var(--accent-ui) 34%, var(--border));
  background: color-mix(in srgb, var(--accent-ui) 12%, transparent);
  color: var(--accent-ui); font-size: 11px; letter-spacing: .04em; }
.picker-tier__label { flex: 1 1 auto; }
.picker-tier__count { color: var(--color-default); opacity: .8; }

/* "from a passive" — a skill you get by allocating a passive rather than by
   crafting a gem. Worth marking, because it is the one pickable kind you cannot
   simply buy. */
.picker-row__tag { flex: none; padding: 1px 6px; border-radius: 999px;
  border: 1px solid color-mix(in srgb, var(--color-notable) 32%, var(--border));
  color: var(--color-notable); font: 10px/1.5 var(--font-smallcaps);
  letter-spacing: .06em; white-space: nowrap; }

.editor-setup__source--passive b { color: var(--color-notable); font-weight: 500; }
