/* ---------- Isaac Cheat Sheet — mobile-first rebuild ---------- */
:root{
  --bg:#141414; --bg2:#1c1c1c; --bg3:#242424; --line:#333;
  --fg:#e8e8e8; --dim:#9a9a9a; --accent:#9BCD35; --accent2:#7fae22;
  --warn:#e0a030; --bad:#d9534f; --good:#5cb85c;
  --hdr:56px; --rbarh:33px; --safe-b:env(safe-area-inset-bottom,0px);
  --tile:52px; --gap:6px; --tilebox:44;
  /* Side gutter for the full-bleed sticky bars, so their text sits in the same column as
     the page below them. It lives here as a variable rather than in a media query on the
     bars themselves, because that rule sat above .qkey in the file and .qkey's own
     shorthand padding quietly won — the quality key was the one bar still flush against
     the window edge on a wide screen. Percent, not vw: vw counts the scrollbar and would
     push every bar a few pixels right of the text it is supposed to line up with. */
  --gut:10px;
  --q0:#7d7d7d; --q1:#3f8fd0; --q2:#57b85c; --q3:#e0a63c; --q4:#c85fd0;
}
@media(min-width:1200px){:root{--gut:calc((100% - 1160px)/2)}}
*,*::before,*::after{box-sizing:border-box}
/* The UA rule for [hidden] is display:none, and ANY author rule that sets display beats
   it — so `hidden` silently did nothing on .chip and .frow, which is how the sync panel
   and its Undo button ended up permanently visible. */
[hidden]{display:none!important}
html{-webkit-text-size-adjust:100%}
body{
  margin:0;background:var(--bg);color:var(--fg);
  font:18px/1.55 -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
  overscroll-behavior-y:none;
}
a{color:var(--accent);text-decoration:none}
button{font:inherit;color:inherit;background:none;border:0;padding:0}
h1,h2,h3{line-height:1.25;margin:0 0 .5em}
h1{font-size:23px}h2{font-size:20px}h3{font-size:17px}
.wrap{max-width:1180px;margin:0 auto;padding:0 10px}
.muted{color:var(--dim)}
.sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}

/* ---------- header ---------- */
header{
  position:sticky;top:0;z-index:40;background:var(--bg2);
  border-bottom:1px solid var(--line);
}
.hbar{display:flex;align-items:center;gap:8px;height:var(--hdr);padding:0 8px;max-width:1180px;margin:0 auto}
.brand{display:flex;align-items:center;gap:7px;font-weight:700;color:var(--accent);flex:0 0 auto;font-size:16px}
.brand img{width:26px;height:26px;border-radius:5px}
.brand span{display:none}
@media(min-width:560px){.brand span{display:inline}}
.searchbox{position:relative;flex:1 1 auto;min-width:0}
.searchbox input{
  width:100%;height:38px;padding:0 34px 0 32px;border-radius:9px;
  background:var(--bg3);border:1px solid var(--line);color:var(--fg);font-size:16px;
}
.searchbox input:focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 2px rgba(155,205,53,.18)}
.searchbox .mag{position:absolute;left:10px;top:50%;transform:translateY(-50%);color:var(--dim);pointer-events:none;font-size:14px}
.searchbox .clr{position:absolute;right:2px;top:50%;transform:translateY(-50%);width:32px;height:32px;color:var(--dim);font-size:18px;display:none}
.searchbox.has .clr{display:block}
.iconbtn{
  flex:0 0 auto;width:38px;height:38px;border-radius:9px;background:var(--bg3);
  border:1px solid var(--line);display:grid;place-items:center;font-size:16px;position:relative;
}
.iconbtn[aria-expanded="true"]{background:var(--accent);color:#111;border-color:var(--accent)}
.iconbtn .dot{position:absolute;top:-3px;right:-3px;width:9px;height:9px;border-radius:50%;background:var(--warn);display:none}
.iconbtn.on .dot{display:block}

/* ---------- nav drawer ---------- */
.nav{
  position:fixed;inset:var(--hdr) 0 0 0;z-index:39;background:var(--bg);
  transform:translateY(-100%);transition:transform .2s ease-out;
  overflow-y:auto;-webkit-overflow-scrolling:touch;padding:10px 10px calc(20px + var(--safe-b));
  visibility:hidden;
}
.nav.open{transform:translateY(0);visibility:visible}

.nav a{display:block;padding:11px 12px;border-radius:8px;background:var(--bg2);margin-bottom:6px;color:var(--fg);min-height:44px}
.nav a[aria-current]{background:var(--accent);color:#111;font-weight:600}
.navgrid{display:grid;gap:6px;grid-template-columns:1fr}
@media(min-width:560px){.navgrid{grid-template-columns:1fr 1fr}}
@media(min-width:900px){.navgrid{grid-template-columns:repeat(3,1fr)}}

/* ---------- filter panel ---------- */
.filters{
  background:var(--bg2);border-bottom:1px solid var(--line);
  display:none;padding:10px;
}
.filters.open{display:block}
.frow{display:flex;flex-wrap:wrap;gap:6px;align-items:center;margin-bottom:9px}
.frow:last-child{margin-bottom:0}
.flabel{font-size:11px;letter-spacing:.06em;text-transform:uppercase;color:var(--dim);width:100%;margin-bottom:2px}
.chip{
  padding:7px 11px;border-radius:999px;background:var(--bg3);border:1px solid var(--line);
  font-size:14px;color:var(--fg);min-height:34px;display:inline-flex;align-items:center;gap:5px;
}
.chip[aria-pressed="true"]{background:var(--accent);border-color:var(--accent);color:#111;font-weight:600}
.chip.q[aria-pressed="true"]{color:#111}
.chip.qq0[aria-pressed="true"]{background:#9a9a9a;border-color:#9a9a9a;color:#111}
.chip.qq1[aria-pressed="true"]{background:#7fc0f0;border-color:#7fc0f0;color:#111}
.chip.qq2[aria-pressed="true"]{background:#8ee095;border-color:#8ee095;color:#111}
.chip.qq3[aria-pressed="true"]{background:var(--q3);border-color:var(--q3);color:#111}
.chip.qq4[aria-pressed="true"]{background:#e3a4ec;border-color:#e3a4ec;color:#111}
.fclear{margin-left:auto;font-size:13px;color:var(--accent);padding:7px 4px;min-height:34px}
select.sel{background:var(--bg3);border:1px solid var(--line);color:var(--fg);border-radius:8px;padding:7px 9px;font-size:14px;min-height:34px}

/* ---------- results bar ---------- */
.rbar{
  position:sticky;top:var(--hdr);z-index:30;background:rgba(20,20,20,.94);
  backdrop-filter:blur(6px);border-bottom:1px solid var(--line);
  padding:6px var(--gut);font-size:13px;color:var(--dim);display:flex;gap:10px;align-items:center;
}
.rbar>*,.qkey>*{max-width:1180px}
.rbar,.qkey{justify-content:flex-start}
/* The combos page puts a results bar inside the centred content column instead of
   full-bleed under the header, so it must not add the gutter a second time. It keeps a
   10px inset for its text and bleeds the same amount back out, so the tinted strip still
   reaches the column edges while the words line up with everything above them. */
.rbar.inline{--gut:10px;margin-left:-10px;margin-right:-10px}

.rbar b{color:var(--fg);font-weight:600}

/* ---------- hover label on the item grid ----------
   position:fixed and outside the grid, because .it clips to a 52px box. Never
   interactive, so it cannot swallow the click it is sitting on top of. */
.tip{
  position:fixed;left:0;top:0;z-index:45;pointer-events:none;
  max-width:min(280px,88vw);padding:5px 9px;border-radius:8px;
  background:#0d0d0d;border:1px solid var(--line);color:var(--fg);
  font-size:14px;line-height:1.3;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
  box-shadow:0 6px 18px rgba(0,0,0,.55);
}
.tip .tq{margin-left:7px;font-size:11px;font-weight:700;padding:1px 5px;border-radius:999px;color:#111}
.tip .tq.q0{background:var(--q0)}.tip .tq.q1{background:var(--q1)}.tip .tq.q2{background:var(--q2)}
.tip .tq.q3{background:var(--q3)}.tip .tq.q4{background:var(--q4)}

/* ---------- collection ticking ---------- */
.rbar .cstat{margin-left:auto;color:var(--accent);font-weight:600;white-space:nowrap}
.rbar .minibtn{
  margin-left:8px;padding:4px 10px;border-radius:999px;background:var(--bg3);
  border:1px solid var(--line);color:var(--fg);font-size:13px;min-height:30px;white-space:nowrap;
}
.rbar .minibtn[aria-pressed="true"]{background:var(--accent);border-color:var(--accent);color:#111;font-weight:600}
/* No .cstat before anything is ticked, so the hint keeps the right-hand slot. */
.rbar .cstat[hidden]+.minibtn{margin-left:auto}
.sect > h2 .cown{margin-left:auto;font-size:11px;color:var(--accent);font-weight:600}
/* The tick is only drawn once something has been recorded — before that it would be
   1021 empty corners on a page whose main job is looking one item up. */
body.hascoll .it.own::after{
  content:"";position:absolute;left:3px;bottom:3px;width:9px;height:9px;
  border-left:2px solid var(--accent);border-bottom:2px solid var(--accent);
  transform:rotate(-45deg) translateY(-1px);
}
body.ticking .it{cursor:pointer}
body.ticking .it:not(.own){opacity:.5}
body.ticking .it.own{outline:2px solid var(--accent);outline-offset:-2px;opacity:1}
.collsync{flex-direction:column;align-items:stretch;gap:7px}
.collsync .syncrow{display:flex;gap:7px;align-items:center;flex-wrap:wrap}
.collsync input{
  flex:1 1 180px;min-width:0;padding:8px 10px;border-radius:9px;background:var(--bg);
  border:1px solid var(--line);color:var(--fg);font:12px/1.3 ui-monospace,SFMono-Regular,Menlo,monospace;
  min-height:38px;
}
.collsync .syncmsg{font-size:13px;color:var(--dim);margin:0}
.collsync .syncmsg.bad{color:#f0a3a3}
.downed{margin-top:10px}
.downed button{
  width:100%;padding:11px;border-radius:9px;background:var(--bg3);border:1px solid var(--line);
  color:var(--fg);font-size:15px;min-height:44px;
}
.downed button[aria-pressed="true"]{background:var(--accent);border-color:var(--accent);color:#111;font-weight:600}

/* ---------- item grid ---------- */
main{padding-bottom:calc(40px + var(--safe-b))}
.sect{margin:14px 0 4px;content-visibility:auto;contain-intrinsic-size:auto 420px}
.sect > h2{
  font-size:14px;letter-spacing:.05em;text-transform:uppercase;color:var(--dim);
  margin:0 0 8px;display:flex;align-items:baseline;gap:7px;
}
.sect > h2 .c{font-size:11px;color:#8a8a8a}
.sect[hidden]{display:none}
.grid{
  display:grid;gap:var(--gap);
  grid-template-columns:repeat(auto-fill,minmax(var(--tile),1fr));
}
.it{
  position:relative;aspect-ratio:1;border-radius:8px;background-color:var(--bg2);
  /* flex, not grid, and contained. 1021 nested grid formatting contexts made every
     filter keystroke cost ~50ms of style+layout on a throttled phone regardless of how
     many items actually changed; flex + contain drops the same work to ~32ms and the
     show-everything case from 140ms to 34ms. Measured, not guessed. */
  display:flex;align-items:center;justify-content:center;contain:layout paint style;
  touch-action:manipulation;-webkit-tap-highlight-color:transparent;
  border:1px solid transparent;overflow:hidden;
}
.it > .sp{--box:var(--tilebox)}
.it:active{border-color:var(--accent)}
.sp{
  display:block;
  width:calc(var(--w) * 1px);height:calc(var(--h) * 1px);
  background-position:calc(var(--x) * -1px) calc(var(--y) * -1px);
  background-repeat:no-repeat;
  image-rendering:pixelated;
  transform-origin:center;
  /* Auto-fit: a transform never changes the layout box, so a 67px-wide sprite used to
     spill out of a 52px tile and collide with whatever sat next to it. --box is the
     target edge length; the sprite scales down only as far as it needs to. */
  --box:44;
  transform:scale(min(1, calc(var(--box) / var(--w)), calc(var(--box) / var(--h))));
}
.sp.inv{transform:scale(min(1, calc(var(--box) / var(--w)), calc(var(--box) / var(--h)))) rotate(180deg)}
/* Fixed-size, clipping container for any sprite. */
.spbox{display:grid;place-items:center;overflow:hidden;flex:0 0 auto}
.it[hidden]{display:none}
.it .qd{position:absolute;top:3px;right:3px;width:6px;height:6px;border-radius:50%}
body.noq .it .qd{display:none}
.qd0{background:var(--q0)}.qd1{background:var(--q1)}.qd2{background:var(--q2)}.qd3{background:var(--q3)}.qd4{background:var(--q4)}
.empty{padding:40px 10px;text-align:center;color:var(--dim)}

/* sprite sheets */
.sh{background-repeat:no-repeat}

/* ---------- detail sheet ---------- */
.scrim{
  position:fixed;inset:0;z-index:50;background:rgba(0,0,0,.65);
  opacity:0;pointer-events:none;transition:opacity .16s ease-out;
}
.scrim.open{opacity:1;pointer-events:auto}
.sheet{
  position:fixed;left:0;right:0;bottom:0;z-index:51;
  background:var(--bg2);border-top:1px solid var(--line);
  border-radius:16px 16px 0 0;max-height:86vh;overflow-y:auto;-webkit-overflow-scrolling:touch;
  transform:translateY(100%);transition:transform .2s cubic-bezier(.2,.8,.2,1);
  padding:0 14px calc(22px + var(--safe-b));will-change:transform;visibility:hidden;
}
.sheet.open{transform:translateY(0);visibility:visible}
@media(min-width:760px){
  .sheet{
    left:50%;right:auto;bottom:auto;top:50%;width:520px;max-height:80vh;
    border-radius:14px;border:1px solid var(--line);
    transform:translate(-50%,-45%) scale(.97);opacity:0;transition:transform .16s,opacity .16s;
  }
  .sheet.open{transform:translate(-50%,-50%) scale(1);opacity:1}
}
.grab{width:38px;height:4px;border-radius:2px;background:#4a4a4a;margin:9px auto 4px}
@media(min-width:760px){.grab{display:none}}
.dhead{display:flex;gap:12px;align-items:flex-start;padding:6px 0 10px;position:sticky;top:0;background:var(--bg2);z-index:2}
.dicon{flex:0 0 auto;width:66px;height:66px;border-radius:10px;background:var(--bg3);display:grid;place-items:center;overflow:hidden}
.dicon .sp{--box:58}
.dhead .t{flex:1 1 auto;min-width:0;overflow-wrap:anywhere}
.dhead h3{margin:0 0 3px;font-size:18px}
.dq{color:var(--accent);font-style:italic;font-size:15px}
.dclose{flex:0 0 auto;width:34px;height:34px;border-radius:8px;background:var(--bg3);font-size:17px;color:var(--dim)}
.badges{display:flex;flex-wrap:wrap;gap:5px;margin:2px 0 10px}
.badge{font-size:11px;padding:3px 8px;border-radius:999px;background:var(--bg3);border:1px solid var(--line);color:var(--dim)}
.badge.q{color:#111;font-weight:700;border:0}
.badge.q0{background:var(--q0);color:#fff}.badge.q1{background:var(--q1);color:#fff}
.badge.q2{background:var(--q2);color:#fff}.badge.q3{background:var(--q3)}.badge.q4{background:var(--q4);color:#fff}
.dsec{margin:0 0 12px}
.dsec h4{font-size:11px;letter-spacing:.07em;text-transform:uppercase;color:var(--dim);margin:0 0 5px}
.dsec ul{margin:0;padding-left:17px}
.dsec li{margin-bottom:5px}
.dsec p{margin:0 0 6px}
.unlock{background:rgba(224,166,60,.1);border-left:3px solid var(--warn);padding:8px 10px;border-radius:0 7px 7px 0;font-size:15px}
.kv{display:flex;flex-wrap:wrap;gap:5px}
.kv .badge{background:var(--bg3)}
.dnav{display:flex;gap:8px;margin-top:6px}
.dnav button{flex:1;padding:10px;border-radius:9px;background:var(--bg3);border:1px solid var(--line);font-size:15px;min-height:44px}

/* ---------- combos page ---------- */
.pgsearch{margin:0 0 12px}
.cmbgrid{display:grid;gap:12px;grid-template-columns:1fr}
@media(min-width:820px){.cmbgrid{grid-template-columns:1fr 1fr}}
.cmb{background:var(--bg2);border:1px solid var(--line);border-radius:12px;padding:13px}
.cmb h3{display:flex;align-items:center;gap:8px;font-size:16px;margin-bottom:8px}
.cmb p{margin:0 0 8px}
.cmb ul{margin:0 0 8px;padding-left:18px}
.cmb li{margin-bottom:4px}
.cmb .src{font-size:13px;margin:0}
.cmb .why{color:var(--fg)}
.cmb .trap{color:#e7c07a}
.tier{
  flex:0 0 auto;width:22px;height:22px;border-radius:6px;display:grid;place-items:center;
  font-size:13px;font-weight:800;color:#111;
}
.tier.tS{background:var(--accent)}.tier.tA{background:#7fc0f0}.tier.tT{background:var(--warn)}
.cmb.tS{border-left:3px solid var(--accent)}
.cmb.tA{border-left:3px solid #7fc0f0}
.cmb.tT{border-left:3px solid var(--warn)}
.cmb.ch{border-left:3px solid #b98cd0}
.cmb .badges{margin-bottom:8px}
.badge.aG{background:#20301c;border-color:#3d6b3f;color:#a6d98a}
.badge.aB{background:#301c1c;border-color:#6b3d3d;color:#e09a9a}
.badge.rH{background:#301c1c;border-color:#6b3d3d;color:#e09a9a}
.badge.rM{background:#302a1c;border-color:#6b5a3d;color:#e0c99a}
.badge.bconf{background:#22222a;border-color:#44445a;color:#a9a9c4}
td.num{text-align:right;font-variant-numeric:tabular-nums;white-space:nowrap}

/* ---------- character unlocks ---------- */
.chgrid{display:grid;gap:10px;grid-template-columns:1fr}
@media(min-width:820px){.chgrid{grid-template-columns:1fr 1fr}}
.chu{background:var(--bg2);border:1px solid var(--line);border-radius:12px;padding:12px;
     border-left:3px solid var(--accent)}
.chu.tnt{border-left-color:#b98cd0}
.chu.have{opacity:.45;border-left-color:var(--line)}
.chu h3{display:flex;align-items:center;gap:8px;font-size:16px;margin-bottom:6px}
.chu p{margin:0 0 6px}
.chu .cond{color:var(--dim)}
.chu .src{font-size:13px;margin:0}
.chstate{flex:0 0 auto;width:9px;height:9px;border-radius:50%;background:var(--accent)}
.chu.have .chstate{background:var(--line)}
.proc .steps{padding-left:20px;margin:0}
.proc .steps > li{margin-bottom:12px}
.proc .steps > li > div{margin-top:4px;color:var(--dim)}
.proc .steps b{color:var(--fg)}
.proc h3{margin-top:14px;font-size:14px;letter-spacing:.05em;text-transform:uppercase;color:var(--dim)}

/* ---------- generic content pages ---------- */
.page{padding-block:16px 40px}
.page h1{font-size:21px;margin-bottom:4px}
.page .lede{color:var(--dim);margin-bottom:18px}
.card{background:var(--bg2);border:1px solid var(--line);border-radius:12px;padding:13px;margin-bottom:12px}
.card h3{margin:0 0 7px}
table{width:100%;border-collapse:collapse;font-size:15px;display:block;overflow-x:auto;-webkit-overflow-scrolling:touch}
table thead th{
  text-align:left;font-size:11px;letter-spacing:.05em;text-transform:uppercase;color:var(--dim);
  padding:8px 10px;border-bottom:1px solid var(--line);white-space:nowrap;
}
table td{padding:9px 10px;border-bottom:1px solid #262626;vertical-align:top}
table tr:last-child td{border-bottom:0}
.tblwrap{background:var(--bg2);border:1px solid var(--line);border-radius:12px;
         overflow-x:auto;-webkit-overflow-scrolling:touch;margin-bottom:14px;position:relative}
code,.mono{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:.92em}
.seedcode{font-family:ui-monospace,Menlo,monospace;font-weight:700;color:var(--accent);letter-spacing:.06em;white-space:nowrap}
img.lazy{background:var(--bg3);max-width:100%;height:auto;display:block}
details{background:var(--bg2);border:1px solid var(--line);border-radius:10px;margin-bottom:8px}
details>summary{padding:12px 13px;cursor:pointer;font-weight:600;min-height:44px;display:flex;align-items:center}
details>div{padding:0 13px 13px}
footer{border-top:1px solid var(--line);padding:20px 10px calc(30px + var(--safe-b));color:var(--dim);font-size:13.5px;text-align:center}
footer a{color:var(--accent)}
.muted a,footer a{text-decoration:underline;text-underline-offset:2px}

/* icon density */
body.dense{--tile:42px;--tilebox:34}
body.roomy{--tile:64px;--tilebox:56}

/* ---------- transformations ---------- */
.tfhead{display:flex;gap:14px;align-items:flex-start;margin-bottom:8px}
.tfhero{width:76px;height:76px;border-radius:10px;background:var(--bg3)}
.tfhero .sp{--box:68}
.tfgrid{display:grid;gap:6px;grid-template-columns:repeat(auto-fill,minmax(58px,1fr));margin-top:6px}
.tfitem{margin:0;background:var(--bg3);border-radius:8px;padding:6px 3px;text-align:center;display:flex;flex-direction:column;align-items:center;gap:3px}
.tfitem .spbox{width:44px;height:44px}
.tfitem .spbox .sp{--box:40}
.tfitem figcaption{font-size:10.5px;line-height:1.25;color:var(--dim);word-break:break-word}

/* ---------- babies ---------- */
.babylist{display:grid;gap:8px;grid-template-columns:1fr}
@media(min-width:640px){.babylist{grid-template-columns:1fr 1fr}}
@media(min-width:980px){.babylist{grid-template-columns:repeat(3,1fr)}}
.baby{display:flex;gap:10px;align-items:flex-start;background:var(--bg2);border:1px solid var(--line);border-radius:10px;padding:9px}
.baby[hidden]{display:none}
.bico{width:52px;height:52px;background:var(--bg3);border-radius:8px}
.bico .sp{--box:46}
.baby p{margin:3px 0 0;font-size:14px;color:var(--dim)}
.baby p.unlock{font-size:13.5px;margin-top:5px}

/* ---------- synergies ---------- */
.syn[hidden]{display:none}
.synh{display:flex;align-items:center;gap:6px;flex-wrap:wrap;font-size:16px}
.badge.r-green{background:rgba(92,184,92,.18);border-color:#3d6b3f;color:#9fdca2}
.badge.r-orange{background:rgba(224,166,60,.16);border-color:#7a5c22;color:#e8c37e}
.badge.r-red{background:rgba(217,83,79,.16);border-color:#7a3634;color:#e79a97}
.icrow{display:grid;grid-template-columns:repeat(auto-fill,minmax(52px,1fr));gap:5px}
.chip.ic{padding:0;min-height:56px;height:56px;min-width:0;width:100%;border-radius:9px;
         display:grid;place-items:center;overflow:hidden}
.chip.ic .sp{--box:46}
.synh .spbox{width:34px;height:34px}
.synh .spbox .sp{--box:32}
img.syn,.vid{width:100%;max-width:420px;border-radius:9px;margin-top:9px;display:block;background:var(--bg3)}
img.hero{max-width:180px;display:block;margin:0 auto 14px;image-rendering:pixelated}

/* ---------- calculator ---------- */
.calcout{display:grid;gap:8px;grid-template-columns:repeat(auto-fit,minmax(130px,1fr));margin-bottom:12px}
.stat{background:var(--bg2);border:1px solid var(--line);border-radius:10px;padding:10px 12px}
.stat[hidden]{display:none}
.stat span{display:block;font-size:11px;letter-spacing:.06em;text-transform:uppercase;color:var(--dim)}
.stat b{font-size:22px;color:var(--accent)}
.infotext{background:var(--bg2);border-left:3px solid var(--accent);padding:10px 12px;border-radius:0 8px 8px 0;font-size:15px}
.infotext.fade{opacity:.55;border-left-color:var(--line)}
.ctogs{display:grid;gap:6px;grid-template-columns:repeat(auto-fill,minmax(48px,1fr))}
.ctog{aspect-ratio:1;border-radius:9px;background:var(--bg3);border:2px solid transparent;display:grid;place-items:center;-webkit-tap-highlight-color:transparent}
.ctog img{image-rendering:pixelated;width:32px;height:32px}
.ctog[aria-pressed="true"]{background:rgba(155,205,53,.22);border-color:var(--accent)}
.crow{margin-bottom:10px;transition:opacity .15s}
.crow label{display:block;font-size:14px;margin-bottom:4px}
.crow input{width:100%;height:40px;border-radius:8px;background:var(--bg3);border:1px solid var(--line);color:var(--fg);padding:0 10px;font-size:16px}
.mark[hidden],.chr[hidden],.tf[hidden],.seed[hidden]{display:none}

/* relevance ordering — driven by one container class, not per-node inline styles */
#browser.ranked .it{order:5 !important}
#browser.ranked .it[data-r="0"]{order:0 !important}
#browser.ranked .it[data-r="1"]{order:1 !important}
#browser.ranked .it[data-r="2"]{order:2 !important}
#browser.ranked .it[data-r="3"]{order:3 !important}
#browser.ranked .it[data-r="4"]{order:4 !important}


/* ---------- completion mark icons (16px sprites, one 208x32 atlas) ---------- */
.mk{display:inline-block;width:16px;height:16px;background-image:var(--marksheet);
    background-repeat:no-repeat;image-rendering:pixelated;vertical-align:-3px;flex:0 0 auto;
    /* The game draws marks on the beige completion page. On a dark UI the Normal
       (solid black) marks vanish without a light plate behind them. */
    background-color:#ded7c6;border-radius:3px}
.mk.hard{background-position-y:-16px}
.mk.big{width:32px;height:32px;background-size:416px 64px;vertical-align:-8px;border-radius:5px}
.mk.big.hard{background-position-y:-32px}

/* ---------- quality key ---------- */
.qkey{display:flex;flex-wrap:wrap;gap:4px 12px;align-items:center;font-size:11.5px;color:var(--dim);
      padding:7px var(--gut);border-bottom:1px solid var(--line);background:var(--bg2)}
.qkey b{color:var(--fg);font-weight:600;letter-spacing:.05em;text-transform:uppercase;font-size:10.5px}
.qkey span{display:inline-flex;align-items:center;gap:4px;white-space:nowrap}
.qkey i{width:8px;height:8px;border-radius:50%;display:inline-block}
body.noq .qkey{display:none}

/* ---------- completion marks page ---------- */
.mkstrip{background:#191919}
.mkgrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(64px,1fr));gap:6px}
.mkcell{display:flex;flex-direction:column;align-items:center;gap:4px;padding:8px 3px;
        background:var(--bg3);border-radius:9px;color:var(--fg);min-height:44px}
.mkcell span{font-size:9.5px;line-height:1.15;text-align:center;color:var(--dim);margin-top:2px;word-break:break-word}
.mkcell .mk.big{vertical-align:0}
h3.mkh{display:flex;align-items:center;gap:9px}
h3.mkh .mk.big{flex:0 0 auto}
.badge.mkb{display:inline-flex;align-items:center;gap:5px}
.mkrow{display:inline-flex;align-items:center;gap:6px}
details>summary .mk{margin-right:6px}
.umarks{display:flex;gap:4px;margin-bottom:6px}
.tcico{width:44px;height:44px;display:inline-grid}
.tcico .sp{--box:40}

/* Selected item chip: outline + tint, never a solid fill — a solid accent fill
   washes out the pixel sprite sitting on top of it. */
.chip.ic[aria-pressed="true"]{background:rgba(155,205,53,.18);border-color:var(--accent);
    box-shadow:inset 0 0 0 1px var(--accent)}

/* == ATLAS-CLASSES:BEGIN (generated by build_items.py — do not edit by hand) == */
:root{--marksheet:url(/img/marks.993971e88a.webp)}.s0{background-image:url(/img/ab-items7.a47a872bfa.webp)}.s1{background-image:url(/img/ab-synergies-items.3cff8f5c9c.webp)}.s2{background-image:url(/img/ap-items10.0ef135ffbc.webp)}.s3{background-image:url(/img/coop-babies.a9481b3b3f.webp)}.s4{background-image:url(/img/rebirth-items-final.4865c87394.webp)}.s5{background-image:url(/img/rep-cards.7535660365.webp)}.s6{background-image:url(/img/rep-items.f9531011d1.webp)}.s7{background-image:url(/img/rep-trinkets.eb52501af8.webp)}.s8{background-image:url(/img/transformations2.ba2ba414fc.webp)}
/* == ATLAS-CLASSES:END == */

/* ---------- data-accuracy banners ---------- */
.acc{border-radius:10px;margin:0 0 14px;border:1px solid var(--line);background:var(--bg2);overflow:hidden}
.acc>summary{padding:11px 13px;cursor:pointer;font-size:14.5px;line-height:1.45;display:flex;
             gap:8px;align-items:flex-start;min-height:44px}
.acc>summary::-webkit-details-marker{display:none}
.acc>div{padding:0 13px 13px;font-size:14.5px}
.acc>div ul{margin:0 0 8px;padding-left:18px}
.acc>div li{margin-bottom:6px}
.accdot{width:9px;height:9px;border-radius:50%;flex:0 0 auto;margin-top:6px;display:inline-block;
        vertical-align:middle;margin-right:6px}
.acc-ok{border-color:#3d6b3f}      .acc-ok .accdot,.accdot.acc-ok{background:var(--good)}
.acc-partial{border-color:#7a5c22} .acc-partial .accdot,.accdot.acc-partial{background:var(--warn)}
.acc-stale{border-color:#7a3634}   .acc-stale .accdot,.accdot.acc-stale{background:var(--bad)}
.acc-ok>summary{background:rgba(92,184,92,.08)}
.acc-partial>summary{background:rgba(224,166,60,.08)}
.acc-stale>summary{background:rgba(217,83,79,.08)}
.badge.fixnote{background:rgba(224,166,60,.14);border-color:#7a5c22;color:#e8c37e;
               white-space:normal;text-align:left;line-height:1.35;margin:2px 0 6px;display:inline-block}
.seed .seedcode{font-size:17px}

/* ---------- Dead God tracker ---------- */
/* The grid is as tall as it needs to be and the page scrolls; a panel with its own
   scrollbar inside a scrolling page is two scrollers fighting over one flick.
   Horizontal scroll stays on phones — 13 mark columns are wider than the screen — which
   also keeps the character-name column stuck to the left edge. Wide enough for the whole
   table and the wrapper stops being a scroll container at all, which is what lets the
   column headers stick to the page instead of to a box that never scrolls. */
.gridwrap{overflow-x:auto;overflow-y:visible;-webkit-overflow-scrolling:touch;background:var(--bg2);
          border:1px solid var(--line);border-radius:12px;margin-bottom:14px;
          overscroll-behavior-x:contain}
table.dgrid{width:auto;min-width:100%;border-collapse:separate;border-spacing:0;display:table}
table.dgrid th,table.dgrid td{padding:0;border:0}
table.dgrid thead th{position:sticky;top:0;z-index:2;background:var(--bg3);padding:6px 2px;text-align:center}
table.dgrid thead th.cname{left:0;z-index:3;text-align:left;padding-left:10px;font-size:10px}
table.dgrid th.cname{position:sticky;left:0;background:var(--bg2);z-index:1;min-width:132px;
                     border-right:1px solid var(--line)}
table.dgrid tbody tr:nth-child(even) th.cname{background:#1f1f1f}
table.dgrid tbody tr:nth-child(even){background:#1f1f1f}
table.dgrid tr.tainted th.cname .rowtog{color:#c9a8e0}
/* From here the whole table fits, so the wrapper can stop being a scroll container —
   which is the only thing that lets the header row stick to the PAGE. Below this width it
   is still a horizontal scroller and the header simply rides at the top of the table,
   where it belongs when the run of rows is short enough to reach by thumb anyway.
   The offset clears the site header and the results bar, both sticky above it. */
@media(min-width:820px){
  .gridwrap{overflow:visible}
  table.dgrid thead th{top:calc(var(--hdr) + var(--rbarh))}
}
.rowtog{display:block;width:100%;text-align:left;padding:8px 10px;font-size:14px;min-height:40px}
.cell{width:44px;height:46px;display:grid;place-items:center;opacity:.4;
      -webkit-tap-highlight-color:transparent}
.cell[aria-pressed="true"]{opacity:1}
/* Normal and Hard read differently at a glance: a Normal clear gets a plain ring, a Hard
   clear gets the game's red-outlined artwork and a warmer ring. */
.cell[data-l="1"] .mk{box-shadow:0 0 0 2px var(--dim)}
.cell[data-l="2"] .mk{box-shadow:0 0 0 2px var(--bad)}
/* ---------- the save panel ---------- */
.savepanel{display:grid;gap:7px;margin:2px 0 4px}
.savepanel p{margin:0}
.savehead{font-size:15px}
.savehead b{color:var(--accent)}
.micro{font-size:12.5px;line-height:1.4;color:var(--dim)}
.savepanel .syncrow{display:flex;gap:6px;align-items:center;flex-wrap:wrap}
.savepanel input{flex:1 1 180px;min-width:0;background:var(--bg3);border:1px solid var(--line);
                 color:var(--fg);border-radius:8px;padding:9px 10px;font-size:15px;min-height:40px}
/* The code is read character by character off one screen and typed into another, so it is
   set in a monospace face with room between the glyphs — 0 and O do not both occur in the
   alphabet, but B and 8 still have to be told apart at arm's length. */
.savepanel input.savecode{font:15px/1.3 ui-monospace,SFMono-Regular,Menlo,monospace;
                          letter-spacing:.06em;color:var(--accent);text-align:center;
                          background:#161616}
.adoptrow{display:grid;gap:5px;margin-top:2px;padding-top:9px;border-top:1px solid var(--line)}
.adoptrow label{color:var(--dim)}
.savemsg{font-size:13px;color:var(--dim);min-height:1px}
.savemsg.bad{color:var(--bad)}
.chip.primary{background:var(--accent);border-color:var(--accent);color:#111;font-weight:600}
.synccode{width:100%;background:var(--bg3);border:1px solid var(--line);color:var(--fg);
          border-radius:8px;padding:8px;font:12px/1.4 ui-monospace,Menlo,monospace;resize:vertical}
.sug .sugh{display:flex;align-items:center;gap:7px;flex-wrap:wrap;font-size:16px}
.sug .rank{background:var(--accent);color:#111;border-radius:6px;padding:1px 7px;font-size:13px;font-weight:700}
.opens{background:rgba(155,205,53,.1);border-left:3px solid var(--accent);padding:8px 10px;
       border-radius:0 7px 7px 0;font-size:14.5px;margin:8px 0}
.checklist{display:grid;gap:5px;margin-bottom:18px}
.ckrow{display:flex;gap:10px;align-items:flex-start;background:var(--bg2);border:1px solid var(--line);
       border-radius:9px;padding:10px 11px;min-height:44px;cursor:pointer}
.ckrow[hidden]{display:none}
/* 637 rows now. Off-screen ones skip layout entirely; the intrinsic size keeps the
   scrollbar honest so the list does not jump while you scroll it. */
.ckrow{content-visibility:auto;contain-intrinsic-size:auto 62px}
.ckrow input{width:20px;height:20px;flex:0 0 auto;margin:1px 0 0;accent-color:var(--accent)}
.ckrow span{display:flex;flex-direction:column;gap:2px;min-width:0}
.ckrow small{font-size:13px;line-height:1.35}
.ckrow:has(input:checked){opacity:.5}
.ckrow:has(input:checked) b{text-decoration:line-through}
/* Read-only rows for achievements recorded on the Marks tab or in the challenge list.
   A second tickable copy of the same fact would just be a way to disagree with yourself. */
.ckrow.covered{background:transparent;border-style:dashed}
/* Round, not square: a read-only indicator that looks like a checkbox invites taps that
   do nothing. */
.ckrow .cbox{
  width:18px;height:18px;flex:0 0 auto;margin:2px 1px 0;border-radius:50%;
  border:1px dashed var(--line);background:transparent;display:block;position:relative;
}
.ckrow.covered.on .cbox{border-style:solid;border-color:var(--accent)}
.ckrow.covered.on .cbox::after{
  content:"";position:absolute;left:5px;top:1px;width:4px;height:9px;
  border-right:2px solid var(--accent);border-bottom:2px solid var(--accent);transform:rotate(42deg);
}
.ckrow.covered.on{opacity:.5}
.ckrow.covered.on b{text-decoration:line-through}
/* Body rows only. The header's own name cell is left a real table-cell: as a flex box
   Chrome quietly drops its vertical stickiness, so the mark columns would stick to the
   top of the page while the word Character slid away underneath them. */
table.dgrid tbody th.cname{display:flex;align-items:center;gap:4px;padding-right:6px}
.lock{width:44px;height:44px;flex:0 0 auto;border-radius:9px;font-size:15px;
      filter:grayscale(1) opacity(.55);border:1px solid var(--line);display:grid;place-items:center}
.lock[aria-pressed="true"]{filter:none;border-color:var(--bad);background:rgba(217,83,79,.16)}
tr.islocked .cell{opacity:.18}
tr.islocked .rowtog{text-decoration:line-through;color:var(--dim)}
.sug .sugh .rank{margin-right:2px}

/* column headers double as fill-the-column buttons */
.colfill{display:flex;flex-direction:column;align-items:center;gap:2px;padding:5px 2px;width:100%;
         min-height:44px;color:var(--dim);-webkit-tap-highlight-color:transparent}
.colfill span{font-size:8px;line-height:1.05;max-width:46px;word-break:break-word;text-align:center}
.colfill:active{background:var(--bg2)}
.warnbar{background:rgba(224,166,60,.14);border-bottom:1px solid #7a5c22;color:#e8c37e;
         margin:0;padding:9px 12px;font-size:14px}
.warnbar[hidden]{display:none}
.syncstatus{margin:9px 0 0;font-size:14px;color:var(--good)}
.syncstatus.bad{color:var(--bad)}
.syncstatus[hidden]{display:none}
/* Handoff QR. Capped at 260px because a phone camera locks on to a symbol about that
   size from a comfortable arm's length; bigger just means more scrolling on the sending
   phone. The white plate is not decoration — scanners need the light quiet zone, and this
   page is dark. */
.qrbox{margin:10px 0 0}
.qrbox[hidden]{display:none}
.qrbox .qrimg{width:100%;max-width:260px;background:#fff;border-radius:8px;padding:6px;
              box-sizing:border-box}
.qrbox .qrimg svg{display:block;width:100%;height:auto}
.qrbox p{margin:9px 0 0;font-size:13.5px;max-width:46em}
a.chip{text-decoration:none;display:inline-flex;align-items:center}
a.chip[hidden]{display:none}
/* Cloud sync. The card gets a live edge when it is on, so "is this actually running?" is
   answerable from across the room without reading anything. */
.card.cloud.on{border-color:#2f6f4f}
.cloudstate{font-size:13.5px}
#collCloudState{color:var(--good)}
#collCloudState.bad{color:#f0a3a3}
.sug .sugchar{font-weight:700}
.sug .sugarch{font-weight:400}
.sugmeta{margin:2px 0 8px;font-size:13.5px}
.didit{margin-top:10px;width:100%;justify-content:center;min-height:44px;
       background:rgba(155,205,53,.14);border-color:var(--accent);color:var(--accent);font-weight:600}
.didit:active{background:var(--accent);color:#111}

/* Bigger touch targets on the controls used most. */
.dclose{width:44px;height:44px}
.searchbox .clr{width:44px;height:44px}
.iconbtn{width:44px;height:44px}
.searchbox input{height:44px}
.chip{min-height:40px}
select.sel{min-height:40px}
input[type=search]::-webkit-search-cancel-button{-webkit-appearance:none;appearance:none}

/* The site animates the sheet, the drawer and the scrim. */
@media (prefers-reduced-motion: reduce){
  *,*::before,*::after{transition-duration:.01ms !important;animation-duration:.01ms !important;
                       animation-iteration-count:1 !important;scroll-behavior:auto !important}
}
.nav .navgrp{margin:14px 0 6px;font-size:13px;letter-spacing:.08em;text-transform:uppercase;color:var(--dim)}

/* ---------- thumb-zone search (touch only) ----------
   56px because Apple's minimum touch target is 44 and a corner control that overlaps a
   grid wants to read as deliberate, not as a stray tile. Hidden entirely on pointer
   devices — the top field is already there and a mouse has no thumb-reach problem. */
.fabsearch{position:fixed;right:14px;bottom:calc(14px + env(safe-area-inset-bottom));
           z-index:60;display:flex;justify-content:flex-end;pointer-events:none}
.fabsearch>*{pointer-events:auto}
@media (hover:hover){.fabsearch{display:none}}
.fabbtn{width:56px;height:56px;border-radius:50%;border:1px solid var(--line);
        background:var(--bg3);color:var(--fg);font-size:26px;line-height:1;
        display:flex;align-items:center;justify-content:center;
        box-shadow:0 6px 20px rgba(0,0,0,.55)}
.fabbtn:active{background:var(--bg2)}
.fabsearch.open .fabbtn{display:none}
/* Open state spans the width so the field is a real field, not a slot. The wrapper keeps
   its right-hand anchor so the expansion reads as coming out of the button. */
.fabsearch.open{left:10px;right:10px}
.fabfield{display:flex;align-items:center;gap:6px;width:100%;
          background:var(--bg3);border:1px solid var(--line);border-radius:26px;
          padding:6px 6px 6px 14px;box-shadow:0 6px 24px rgba(0,0,0,.6)}
.fabfield[hidden]{display:none}
.fabfield .mag{font-size:19px;color:var(--dim);flex:0 0 auto}
.fabfield input{flex:1 1 auto;min-width:0;background:none;border:0;outline:none;
                color:var(--fg);font-size:16px;padding:10px 0}
/* 16px is not a style choice: anything smaller makes iOS zoom the page on focus. */
.fabclose{flex:0 0 auto;width:40px;height:40px;border-radius:50%;border:0;
          background:var(--bg2);color:var(--fg);font-size:22px;line-height:1}

/* ---------- desktop hover card ----------
   Same content as the tap-through sheet, built by the same code. Fixed-position and
   pointer-events:none so it can never swallow the click it is inviting. */
.hovcard{position:fixed;top:0;left:0;z-index:70;width:330px;max-height:78vh;overflow:hidden;
         background:var(--bg2);border:1px solid var(--line);border-radius:12px;padding:12px;
         box-shadow:0 14px 44px rgba(0,0,0,.66);pointer-events:none}
.hovcard[hidden]{display:none}
.hovcard .hcHead{display:flex;gap:10px;align-items:flex-start;margin-bottom:8px}
.hovcard h3{margin:0;font-size:16px}
.hovcard .quote{margin:3px 0 0;font-size:13px;color:var(--dim);font-style:italic}
.hovcard .quote[hidden]{display:none}
.hovcard .badges{margin-top:6px}
.hovcard .dsec{margin:8px 0 0}
.hovcard .dsec h4{margin:0 0 4px;font-size:11px;letter-spacing:.05em;text-transform:uppercase;color:var(--dim)}
.hovcard ul{margin:0;padding-left:17px}
.hovcard li{font-size:13.5px;line-height:1.42;margin-bottom:3px}
.hovcard .more{margin:5px 0 0;font-size:11.5px;font-style:italic}
.hovcard .unlock{font-size:13px}

/* Cross-links inside description text. Underlined rather than colour-only: the
   descriptions are dense and a colour shift alone reads as emphasis, not as "you can go
   there". Dotted so it does not compete with the bullet text it sits in. */
.xlink{color:var(--accent);text-decoration:underline;text-decoration-style:dotted;
       text-underline-offset:2px}
.xlink:hover{text-decoration-style:solid}
/* The hover card is pointer-events:none by design, so its links cannot be clicked. Do not
   dangle the affordance there. */
.hovcard .xlink{color:inherit;text-decoration:none}

/* ---------- the in-game completion note ----------
   A pale, slightly-rotated post-it with a pin, matching what the game pins to the
   character-select screen. Drawn in CSS rather than shipped as a sprite: this is a
   likeness of the layout, and the mark icons themselves are the real artwork.
   aspect-ratio locks it to the sprite's 88:82 so the measured icon percentages land
   where they should at any width. */
.notecard .notewrap{
  position:relative;width:min(340px,86vw);margin:0 auto;aspect-ratio:88/82;
  transform:rotate(-2.5deg);
}
.notepaper{
  position:absolute;inset:0;display:block;border-radius:3px;
  background:linear-gradient(#efe2e6,#e4d3d9);
  box-shadow:0 10px 26px rgba(0,0,0,.55), inset 0 0 0 1px rgba(114,108,105,.5);
}
.notepaper:focus-visible{outline:3px solid var(--accent);outline-offset:3px}
/* The pin sits at ~58% across and ~10% down on the real sprite. */
.notepin{
  position:absolute;left:58%;top:10%;width:13%;aspect-ratio:1;transform:translate(-50%,-50%);
  border-radius:50%;background:radial-gradient(circle at 35% 32%,#cfcfcf,#7e7e7e 60%,#4a4a4a);
  box-shadow:0 0 0 1.5px #1b1b1b, 0 2px 4px rgba(0,0,0,.5);
}
.notemk{
  position:absolute;transform:translate(-50%,-50%);display:grid;place-items:center;
  /* 44px minimum tap target even though the icon is drawn smaller — these sit close
     together on the note and a 16px hit box would be unusable on a phone. */
  width:44px;height:44px;border-radius:8px;
}
/* On the real 88x82 sprite an icon is 16px, about 18% of the note's width. Scaling the
   16px sprite by 2.6 lands close to that at the note's natural size without dividing
   lengths in calc(), which CSS will not do. */
.notemk .mk{transform:scale(2.6);transform-origin:center;background-color:transparent;border-radius:0}
.notepin{width:10%}
.notemk:hover,.notemk:focus-visible{background:rgba(155,205,53,.22);outline:none}
.notecard .notewrap+p{margin-top:12px}

/* Still actually locked: gated behind an achievement the tracker says is not done, and not
   hand-ticked either. Dimmed rather than hidden — you still want to look them up, that is
   most of why you are here. Grayscale as well as opacity so it survives on a bright phone
   screen outdoors, where a 45% opacity drop alone is nearly invisible. */
.it.locked .sp{opacity:.34;filter:grayscale(.85)}
.it.locked .qd{opacity:.35}
body.ticking .it.locked{opacity:1}
/* Dimming the locked two-fifths of the grid is genuinely useful when you are tracking and
   genuinely in the way when you are looking something up — a greyed, desaturated sprite is
   the hardest kind to pick out of 1021 of them. So it is a preference, not a fact about
   the page, and the control sits in the results bar next to the count it explains.

   The middle setting keeps the artwork and states the same fact with a padlock instead: a
   6px mark in a corner nothing else uses, drawn rather than set in an emoji font so it
   renders identically everywhere and costs no glyph load. Bottom-left, because the quality
   dot already owns the top-right. */
body.lk-mark .it.locked .sp,body.lk-off .it.locked .sp{opacity:1;filter:none}
body.lk-mark .it.locked .qd,body.lk-off .it.locked .qd{opacity:.85}
body.lk-mark .it.locked::before{
  /* Shackle: narrower and taller than the body, or the two together read as a handbag. */
  content:"";position:absolute;left:4px;bottom:7.5px;width:4px;height:5px;
  border:1.5px solid rgba(232,232,232,.62);border-bottom:0;border-radius:2.5px 2.5px 0 0;
}
body.lk-mark .it.locked::after{
  content:"";position:absolute;left:2px;bottom:3px;width:8px;height:5.5px;border-radius:1.5px;
  background:rgba(232,232,232,.62);
  /* Half the sprites are pale, so the mark carries its own separation from them. */
  box-shadow:0 0 0 1px rgba(0,0,0,.6);
}
/* Ticking already forces every tile to full strength, so the padlock would be the only
   thing still claiming an item is locked while you are busy telling it otherwise. */
body.ticking .it.locked::before,body.ticking .it.locked::after{display:none}
.rbar .minibtn[data-lk]{background:var(--bg3);border-color:var(--line);color:var(--fg);font-weight:400}
.rbar .minibtn[data-lk="dim"]{color:var(--dim)}
.rbar .minibtn[data-lk="mark"]{border-color:var(--accent2);color:var(--fg)}

/* The ordered run queue on the Path tab. Numbered because it is a sequence, not a set. */
.runq{margin:6px 0 0;padding-left:26px}
.runq li{margin-bottom:11px;line-height:1.4}
.runq .qsub{font-size:14px;margin-top:1px}
.runq .qwin{font-size:14px;color:var(--accent);margin-top:2px}
.runq .qfin{font-size:14px;color:var(--good);margin-top:2px}

/* Run playbooks. Collapsed by default and built on open — twelve queue entries' worth of
   bullets is a lot of DOM to create for panels nobody has looked at. */
.tipbox{margin:8px 0 0;border:1px solid var(--line);border-radius:9px;background:var(--bg3)}
.tipbox>summary{padding:9px 12px;cursor:pointer;font-size:14px;color:var(--accent);
                list-style:none;min-height:40px;display:flex;align-items:center}
.tipbox>summary::-webkit-details-marker{display:none}
.tipbox>summary::before{content:"\25B8";margin-right:8px;transition:transform .15s}
.tipbox[open]>summary::before{transform:rotate(90deg)}
.tipbody{padding:0 12px 10px}
.tipbody h4{margin:8px 0 4px;font-size:13px;letter-spacing:.05em;text-transform:uppercase;color:var(--dim)}
.tipbody .tiplist{margin:0;padding-left:18px}
.tipbody .tiplist li{font-size:15px;line-height:1.45;margin-bottom:7px}
.tipbody .src{margin:6px 0 0;font-size:12.5px}

/* ---------- character guides ---------- */
.ggrid{display:grid;gap:8px;grid-template-columns:1fr}
@media(min-width:640px){.ggrid{grid-template-columns:1fr 1fr}}
@media(min-width:1000px){.ggrid{grid-template-columns:repeat(3,1fr)}}
.gcard{display:block;padding:12px 14px;border:1px solid var(--line);border-radius:10px;
       background:var(--bg2);color:var(--fg);position:relative}
.gcard[hidden]{display:none}
.gcard.tnt{border-color:#4a3a52}
.gcard .gname{display:block;font-weight:700;font-size:17px;color:var(--accent)}
.gcard .gpeek{display:block;margin-top:4px;font-size:14px;color:var(--dim);line-height:1.4}
.gcard .gleft{position:absolute;top:12px;right:12px;font-size:12px;color:var(--warn);
              font-weight:600;white-space:nowrap}
.gcard .gleft.done{color:var(--good)}
.gcard .gleft[hidden]{display:none}
.cguide .crumb{margin:0 0 6px;font-size:14px}
.cguide .gsec{margin-bottom:10px}
.cguide .gsub{margin:-2px 0 8px;font-size:13.5px}
.cguide .gl{margin:0;padding-left:19px}
.cguide .gl li{margin-bottom:8px;line-height:1.5}
.cguide .gstate h3{margin:0 0 4px}
.tipbody .guidelink{margin:10px 0 0;font-size:14px}

/* The one-time offer to keep a save. Its own strip under the results bar, not inside it:
   the bar already holds the count, the hint and two toggles, and on a 390px phone adding a
   question and two buttons to that row turned every item in it into a vertical sliver. */
.nudgebar{display:flex;align-items:center;gap:10px;flex-wrap:wrap;justify-content:space-between;
          padding:8px var(--gut);font-size:13.5px;line-height:1.4;color:var(--fg);
          background:rgba(155,205,53,.09);border-bottom:1px solid var(--line)}
.nudgebar[hidden]{display:none}
.nudgebar>span:first-child{flex:1 1 210px;min-width:0}
.nudgebtns{display:flex;gap:6px;flex:0 0 auto}
.chip.tiny{padding:5px 10px;font-size:12.5px;min-height:30px;background:var(--accent);
           border-color:var(--accent);color:#111;font-weight:600}
.chip.tiny.ghost{background:transparent;border-color:var(--line);color:var(--dim);font-weight:400}

/* Dimming is already forced off while you are ticking, so the toggle would be a button
   that does nothing — and the bar has no room for a dead control on a phone. */
body.ticking #dimBtn{display:none}
/* Narrow: the standing hint is advisory and the first thing that should give up its space.
   The ticking hint is live feedback, so it stays — and #dimBtn is gone by then anyway. */
@media(max-width:620px){
  .rbar #rhint{display:none}
  body.ticking .rbar #rhint{display:block}
}
/* Only the two code fields are monospace. The name is a name. */
.savepanel input{font:15px/1.3 -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif}
.savepanel input.savecode,.savepanel #saveAdopt{
  font:15px/1.3 ui-monospace,SFMono-Regular,Menlo,monospace;letter-spacing:.05em}
