/* ---------------------------------------------------------------- theme -- */
:root{
  --bg:#0b0e14; --bg2:#121722; --line:#232b3b; --ink:#e6ebf5; --dim:#8d99b0;

  --have:#38bdf8;   /* you own it            */
  --now:#4ade80;    /* fusable right now     */
  --soon:#2f855a;   /* reachable in steps    */
  --need:#fbbf24;   /* go roll this          */
  --path:#fb923c;   /* intermediate step     */
  --want:#c084fc;   /* your goal             */
  --fuse:#f472b6;   /* a fused ball          */
}
*{box-sizing:border-box}
html,body{height:100%}
body{
  margin:0; background:var(--bg); color:var(--ink);
  font:14px/1.5 ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;
  display:flex; flex-direction:column;
}
a{color:var(--have)}
kbd{
  background:#1c2331; border:1px solid var(--line); border-bottom-width:2px;
  border-radius:4px; padding:1px 5px; font:11px/1.4 ui-monospace,monospace;
}

/* --------------------------------------------------------------- topbar -- */
.topbar{
  display:flex; align-items:center; gap:16px; flex-wrap:wrap;
  padding:10px 18px; background:var(--bg2); border-bottom:1px solid var(--line);
}
.brand{display:flex; align-items:center; gap:10px}
.brand img{width:34px; height:34px; image-rendering:pixelated}
.brand h1{margin:0; font-size:17px; letter-spacing:.2px}
.sub{margin:0; font-size:10px; letter-spacing:.22em; color:var(--dim); text-transform:uppercase}
.sub span{color:var(--want)}

.tabs{display:flex; gap:4px; background:#0d121c; padding:3px; border-radius:9px; border:1px solid var(--line)}
.tab{
  background:none; border:0; color:var(--dim); font:inherit; font-weight:600;
  padding:5px 14px; border-radius:6px; cursor:pointer;
}
.tab.is-on{background:#20293a; color:var(--ink)}

.slots{
  margin-left:auto; display:flex; align-items:center; gap:7px;
  font-size:12px; color:var(--dim); white-space:nowrap;
}
.slots input{
  width:52px; padding:6px 7px; border-radius:7px; border:1px solid var(--line);
  background:#0d121c; color:var(--ink); font:inherit; text-align:center;
}
.slots input:focus{outline:none; border-color:var(--have)}

#search{
  width:170px; padding:7px 11px; border-radius:8px;
  border:1px solid var(--line); background:#0d121c; color:var(--ink); font:inherit;
}
#search:focus{outline:none; border-color:var(--have)}
.ghost{
  background:none; border:1px solid var(--line); color:var(--dim);
  padding:7px 12px; border-radius:8px; cursor:pointer; font:inherit;
}
.ghost:hover{color:var(--ink); border-color:var(--dim)}

/* ------------------------------------------------------- howto + legend -- */
.howto{
  display:flex; gap:20px; flex-wrap:wrap; align-items:center;
  padding:9px 18px; font-size:12.5px; color:var(--dim);
  background:#0e131d; border-bottom:1px solid var(--line);
}
.howto .hint{opacity:.75; font-style:italic}

.modes{display:flex; gap:4px; background:#0b0f18; padding:3px; border-radius:9px; border:1px solid var(--line)}
.mode{
  display:flex; align-items:center; gap:6px;
  background:none; border:0; color:var(--dim); font:inherit; font-weight:600;
  padding:5px 12px; border-radius:6px; cursor:pointer;
}
.mode:hover{color:var(--ink)}
.mode kbd{font-size:9.5px; padding:0 4px; opacity:.75}
.mode.is-on{background:#20293a; color:var(--ink)}
.mode.is-on[data-mode="slot"]{box-shadow:inset 0 -2px 0 var(--have)}
.mode.is-on[data-mode="goal"]{box-shadow:inset 0 -2px 0 var(--want)}
.mode.is-on[data-mode="fuse"]{box-shadow:inset 0 -2px 0 var(--fuse)}

.dimtoggle{
  margin-left:auto; display:flex; align-items:center; gap:6px;
  font-size:11.5px; color:var(--dim); cursor:pointer; white-space:nowrap;
}
.dimtoggle input{accent-color:#5b6b8a; margin:0; cursor:pointer}

/* the board picks up a tint so the active mode is never in doubt */
body[data-mode="goal"] .tile:hover{border-color:var(--want)}
body[data-mode="fuse"] .tile:hover{border-color:var(--fuse)}

.legend{display:flex; gap:16px; flex-wrap:wrap; padding:8px 18px; font-size:12px; color:var(--dim)}
.lg{display:flex; align-items:center; gap:6px}
.lg::before{content:""; width:11px; height:11px; border-radius:3px; background:currentColor}
.lg-have{color:var(--have)} .lg-now{color:var(--now)} .lg-soon{color:var(--soon)}
.lg-need{color:var(--need)} .lg-path{color:var(--path)} .lg-want{color:var(--want)}

/* --------------------------------------------------------------- layout -- */
main{flex:1; display:flex; min-height:0}
.board{position:relative; flex:1; overflow:auto; padding:6px 18px 40px}
.panel{
  width:330px; flex:none; overflow:auto; padding:18px;
  background:var(--bg2); border-left:1px solid var(--line);
}
.wires{position:absolute; inset:0; width:100%; height:100%; pointer-events:none; z-index:1}

.cols{
  position:relative; z-index:2; display:grid; gap:22px; align-items:start;
  /* --cols is set per data set in app.js, weighted by how many tiles each tier holds */
  grid-template-columns:var(--cols, 1fr 3fr 1fr);
}
/* ---------------------------------------------------------------- tiles -- */
.tile{
  position:relative; width:52px; height:52px; padding:0; cursor:pointer;
  background:#151b27; border:2px solid #222b3c; border-radius:10px;
  display:grid; place-items:center; transition:transform .08s, opacity .12s;
}
.tile img{width:38px; height:38px; image-rendering:pixelated; pointer-events:none}
.tile:hover{transform:translateY(-2px)}
.tile:focus-visible{outline:2px solid var(--have); outline-offset:2px}

/* fill = what you HAVE / CAN BUILD ------------------------------------- */
.tile.have{border-color:var(--have); background:#0d2d40; box-shadow:0 0 0 1px var(--have) inset}
.tile.now {border-color:var(--now);  background:#0f2e1d; box-shadow:0 0 12px -2px var(--now)}
.tile.soon{border-color:var(--soon); background:#132a1f}
.tile.need{border-color:var(--need); background:#2e2410; box-shadow:0 0 12px -3px var(--need)}
.tile.path{border-color:var(--path); background:#2e1d0f}

/* ring = what you WANT ------------------------------------------------- */
.tile.want::after{
  content:""; position:absolute; inset:-5px; border-radius:13px;
  border:2px dashed var(--want); animation:spin 14s linear infinite;
}
@keyframes spin{to{transform:rotate(360deg)}}

.tile.mute{opacity:.45}
.tile.mute:hover{opacity:.9}
.tile.hit{outline:2px solid #fff; outline-offset:2px}   /* search match */

/* corner pip: how many goals this feeds */
.tile .pip{
  position:absolute; top:-6px; right:-6px; min-width:16px; height:16px; padding:0 3px;
  border-radius:8px; background:var(--want); color:#1a0b26;
  font:700 10px/16px ui-monospace,monospace; text-align:center;
}

/* --------------------------------------------------------------- panel --- */
.panel .empty{color:var(--dim); font-size:13px}
.p-head{display:flex; gap:12px; align-items:center; margin-bottom:4px}
.p-head img{width:46px; height:46px; image-rendering:pixelated}
.p-head h3{margin:0; font-size:17px}
.p-tier{font-size:11px; letter-spacing:.1em; text-transform:uppercase; color:var(--dim)}
.p-desc{color:#c3ccdd; font-size:13px; margin:12px 0}

.p-acts{display:flex; gap:8px; margin:14px 0}
.p-acts button{flex:1; padding:8px; border-radius:8px; cursor:pointer; font:inherit; font-weight:600;
  background:#0d121c; border:1px solid var(--line); color:var(--dim)}
.p-acts .on-have{border-color:var(--have); color:var(--have); background:#0d2d40}
.p-acts .on-want{border-color:var(--want); color:var(--want); background:#241436}

.p-sec{margin-top:18px}
.p-sec h4{margin:0 0 7px; font-size:11px; letter-spacing:.14em; text-transform:uppercase; color:var(--dim)}
.p-sec p{margin:0; font-size:13px; color:#c3ccdd}

.chips{display:flex; flex-wrap:wrap; gap:5px}
.chip{
  display:inline-flex; align-items:center; gap:5px; cursor:pointer;
  background:#0d121c; border:1px solid var(--line); border-radius:20px;
  padding:3px 9px 3px 4px; font-size:12px; color:var(--ink);
}
.chip img{width:19px; height:19px; image-rendering:pixelated}
.chip:hover{border-color:var(--dim)}
.chip.have{border-color:var(--have)} .chip.need{border-color:var(--need)}

.steps{list-style:none; margin:0; padding:0; counter-reset:s}
.steps li{
  display:grid; grid-template-columns:17px 1fr; gap:3px 7px; align-items:center;
  padding:8px 0; border-top:1px solid var(--line); font-size:12px;
}
.step-in,.step-out{grid-column:2; display:flex; align-items:center; gap:5px; flex-wrap:wrap}
.step-in{color:var(--dim)}
.step-out b{color:var(--ink)}
.steps li::before{
  counter-increment:s; content:counter(s); grid-row:1; grid-column:1;
  width:17px; height:17px; border-radius:50%; background:#20293a;
  color:var(--dim); font:700 10px/17px ui-monospace,monospace; text-align:center;
}
.steps img{width:21px; height:21px; image-rendering:pixelated}
.steps .arrow{color:var(--dim)}

.tags{display:flex; flex-wrap:wrap; gap:5px}
.tag{background:#1a2230; border:1px solid var(--line); border-radius:5px; padding:2px 7px; font-size:11px; color:var(--dim)}

footer{
  padding:11px 18px; font-size:11.5px; color:var(--dim);
  background:var(--bg2); border-top:1px solid var(--line);
}

.noicon{
  width:38px; height:38px; display:grid; place-items:center;
  background:#20293a; border-radius:6px; color:var(--dim); font-weight:700;
}

/* Ball sprites are ~50px and want crisp nearest-neighbour scaling.
   Passive sprites are 324px; pixelated downscaling drops most of their
   pixels and leaves the tile looking empty, so let those resample smoothly. */
body[data-set="passives"] img{image-rendering:auto}

/* ------------------------------------------------------------- summary -- */
.summary{
  display:flex; gap:18px; flex-wrap:wrap; align-items:center;
  padding:9px 18px; font-size:12.5px;
  background:#101725; border-bottom:1px solid var(--line);
}
.summary.off{color:var(--dim); font-style:italic}
.summary.tight{background:#231a12; border-bottom-color:#4a3419}
.stat b{font-size:15px; margin-right:3px}
.s-need b{color:var(--need)}
.s-path b{color:var(--path)}
.s-ok   b{color:var(--now)}
.s-bad  b{color:#f87171}
.summary .warn{color:#fbbf24}
.summary .muted{color:var(--dim)}

.tile .pip.extra{background:var(--need); color:#2a1e05}
.tile.have.owes{border-color:var(--need)}

/* pickup counts */
.chip i.x{font-style:normal; font-weight:700; color:var(--need); margin-left:2px}
.p-sec .note{
  margin-top:8px; font-size:11.5px; line-height:1.5; color:var(--dim);
  border-left:2px solid var(--need); padding-left:9px;
}
.p-sec .cost b{font-size:15px; color:var(--ink)}

/* ------------------------------------------------------------------ rack -- */
.rack{
  display:flex; align-items:flex-start; gap:14px; flex-wrap:wrap;
  padding:10px 18px; background:#0e131d; border-bottom:1px solid var(--line);
}
.rack.armed{background:#1d1220; border-bottom-color:#4a2540}

.rack-label{display:flex; flex-direction:column; line-height:1.15; padding-top:4px}
.rack-label b{font-size:16px}
.rack-label span{font-size:10px; letter-spacing:.14em; text-transform:uppercase; color:var(--dim)}

.rack-boxes{display:flex; gap:7px; flex-wrap:wrap}
.slot{
  width:74px; min-height:70px; border-radius:10px;
  display:flex; flex-direction:column; align-items:center; gap:3px;
  padding:6px 4px 5px; text-align:center;
}
.slot.empty{border:1px dashed #2b3446; background:#0b0f18}
.slot.filled{
  position:relative; cursor:grab; background:#151b27; touch-action:none;
  border:2px solid var(--have); box-shadow:0 0 0 1px rgba(56,189,248,.18) inset;
}
.slot.filled:active{cursor:grabbing}
.slot.is-fused{border-color:var(--fuse)}
.slot.over{border-color:#f87171; background:#2a1414}
.slot.fusing{border-color:var(--fuse); box-shadow:0 0 12px -2px var(--fuse)}
.slot.dragging{opacity:.35}
.rack.dragging-any .rack-boxes{outline:1px dashed #3a4459; outline-offset:5px}
.rack.drop-armed .rack-boxes{outline-color:#f87171}
.rack.drop-armed::after{
  content:"release to drop it"; position:absolute; right:18px; bottom:4px;
  font-size:11px; color:#f87171;
}
.rack{position:relative}

/* outranks .slot.filled, which would otherwise pin it back to position:relative */
.slot.filled.drag-ghost{
  position:fixed; z-index:99; margin:-35px 0 0 -37px; pointer-events:none;
  opacity:.92; transform:scale(1.06); box-shadow:0 8px 22px rgba(0,0,0,.55);
}
.slot.filled.drag-ghost .slot-x{display:none}
.slot.filled.drag-ghost.will-drop{border-color:#f87171; opacity:.6}

.slot img{width:34px; height:34px; image-rendering:pixelated}
body[data-set="passives"] .slot img{image-rendering:auto}
.slot-name{
  font-size:9.5px; line-height:1.25; color:var(--dim);
  display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden;
}
.slot-x{
  position:absolute; top:-7px; right:-7px; width:18px; height:18px; padding:0;
  border-radius:50%; border:1px solid var(--line); background:#1c2331;
  color:var(--dim); font-size:10px; line-height:1; cursor:pointer; opacity:0;
}
.slot.filled:hover .slot-x{opacity:1}
.slot-x:hover{color:#f87171; border-color:#f87171}

/* both halves of a fusion, overlapping */
.fused-icon{position:relative; width:34px; height:34px; display:block}
.fused-icon img{
  position:absolute; width:25px; height:25px;
  image-rendering:pixelated; border-radius:3px;
}
.fused-icon img:first-child{top:0; left:0}
.fused-icon img:last-child{bottom:0; right:0; box-shadow:-2px -2px 0 0 #151b27}
.p-head .fused-icon{width:46px; height:46px}
.p-head .fused-icon img{width:33px; height:33px}

.rack-hint{margin-left:auto; align-self:center; font-size:11.5px; color:var(--dim); max-width:340px}
.rack-hint.live{color:var(--fuse)}
.rack-hint.warn{color:var(--need)}
.linkish{
  background:none; border:0; color:var(--dim); text-decoration:underline;
  cursor:pointer; font:inherit; padding:0 0 0 8px;
}
.linkish:hover{color:var(--ink)}

.tile.fusing{border-color:var(--fuse); box-shadow:0 0 14px -2px var(--fuse)}
.lg-fuse{color:var(--fuse)}

body[data-set="passives"] .only-balls{display:none}

/* ----------------------------------------------------------------- intro -- */
/* flex, not `grid; place-items:center` - centring a grid item makes the track
   size to the item's intrinsic width, which collapses the text column. */
.intro{
  position:fixed; inset:0; z-index:50; display:flex;
  align-items:center; justify-content:center;
  background:rgba(5,8,13,.78); backdrop-filter:blur(3px); padding:20px;
}
.intro[hidden]{display:none}
.intro-card{
  width:100%; max-width:560px; max-height:92vh; overflow:auto;
  background:var(--bg2); border:1px solid var(--line); border-radius:16px;
  padding:26px 28px 22px; box-shadow:0 24px 60px rgba(0,0,0,.6);
}
.intro-kicker{margin:0 0 10px; font-size:10.5px; letter-spacing:.24em; text-transform:uppercase; color:var(--dim)}
.intro-kicker span{color:var(--fuse)}
.intro-card h2{margin:0 0 12px; font-size:23px; line-height:1.22; letter-spacing:-.2px}
.intro-lede{margin:0 0 20px; font-size:14px; line-height:1.6; color:#c3ccdd}
.intro-lede em{color:var(--ink); font-style:normal; font-weight:600}

.intro-steps{list-style:none; margin:0 0 22px; padding:0; display:flex; flex-direction:column; gap:14px}
/* exactly two grid children per row - a bare text node would become a third
   anonymous item and get placed back in the 11px dot column */
.intro-steps li{
  display:grid; grid-template-columns:11px minmax(0,1fr); gap:11px; align-items:start;
  font-size:13.5px; line-height:1.55; color:#aab4c6;
}
.intro-steps li p{margin:0}
.intro-steps b{color:var(--ink); font-weight:600}
.intro-steps code{
  background:#1a2230; border:1px solid var(--line); border-radius:4px;
  padding:0 4px; font:600 11.5px ui-monospace,monospace; color:var(--need);
}
.s-dot{width:11px; height:11px; border-radius:3px; margin-top:5px}
.d-have{background:var(--have)} .d-want{background:var(--want)} .d-fuse{background:var(--fuse)}

.intro-go{
  width:100%; padding:11px; border-radius:9px; cursor:pointer;
  background:#20293a; border:1px solid #33405a; color:var(--ink);
  font:inherit; font-weight:600; font-size:14px;
}
.intro-go:hover{background:#273246; border-color:var(--have)}
.intro-fine{margin:14px 0 0; font-size:11px; line-height:1.5; color:var(--dim); text-align:center}

#help{width:32px; padding:7px 0; text-align:center; font-weight:700}

/* =========================================================================
   RESPONSIVE - kept last on purpose. Media queries add no specificity, so
   any of these that lived higher up would lose to the plain rules below them.
   ========================================================================= */

/* Below the desktop width the page scrolls as one document instead of the
   board being its own scroller beside a fixed panel - squeezing a full-height
   flex row into a short viewport left the board a few pixels tall. */
@media (max-width:1250px){
  html,body{height:auto}
  main{display:block}
  .board{overflow:visible}
  .panel{
    display:block; width:auto; flex:none; overflow:visible;
    border-left:0; border-top:1px solid var(--line);
  }
  .panel .empty{max-width:60ch}
  /* the run totals are the thing you keep glancing at, so pin them */
  .summary{position:sticky; top:0; z-index:20}
}

/* three tiers still fit down to about here; below it they stack */
@media (max-width:900px){
  .cols{grid-template-columns:1fr}
  .col h2{top:38px}
  /* with the tiers stacked the connectors just trail down the page without
     showing a left-to-right progression, so they are noise here */
  .wires{display:none}
}

/* phones: strip the chrome back so the board is above the fold */
@media (max-width:640px){
  .topbar{padding:8px 12px; gap:8px 10px}
  .brand img{width:28px; height:28px}
  .brand h1{font-size:15px}
  .sub{font-size:9px}
  .tab{padding:5px 11px}
  .slots{margin-left:0; font-size:11px}
  .slots input{width:46px}
  #search{width:auto; flex:1 1 110px; min-width:0}
  .ghost{padding:6px 10px}

  .howto{padding:7px 12px; gap:10px}
  .howto .hint{display:none}
  .mode{padding:5px 10px; font-size:13px}
  .dimtoggle{margin-left:0}

  .legend{padding:7px 12px; gap:9px 12px; font-size:11px}
  .summary{padding:8px 12px; gap:10px 14px; font-size:12px}
  .stat b{font-size:14px}

  .rack{padding:8px 12px; gap:10px}
  .rack-label b{font-size:14px}
  .slot{width:54px; min-height:52px; padding:5px 3px}
  .slot img,.fused-icon{width:28px !important; height:28px !important}
  .fused-icon img{width:20px !important; height:20px !important}
  .slot-name{display:none}
  .rack-hint{display:none}
  .slot-x{opacity:1}                 /* no hover on touch, so always show it */

  .board{padding:6px 12px 28px}
  .panel{padding:15px 12px}
  footer{padding:10px 12px; font-size:11px}
  .intro-card{padding:20px 18px 18px}
  .intro-card h2{font-size:20px}
}

.col h2{
  position:sticky; top:0; z-index:3; margin:0 0 10px;
  padding:8px 2px; font-size:11px; letter-spacing:.16em; text-transform:uppercase;
  color:var(--dim); background:var(--bg); border-bottom:1px solid var(--line);
}
.col h2 b{color:#5c6a85}
.grid{display:flex; flex-wrap:wrap; gap:7px; align-content:start}
