/* ═══════════════════════════════════════════════════════════════════════════
   Dungeondle (bare) - neon / bloom / pastel on deep dark.

   Same system as the reference build, with every rule the bare UI does not
   render deleted rather than left to rot: no nav, no roster, no stash, market,
   stalls, workshop, nerve dial or pact panel. What is left is the login gate,
   the topbar, the forest banner, the Descend button, the
   descent log, the summary + share card, the board modal and the toast.

   The Forest drives TWO hues, --accent and --accent2, set from JS. Every glow
   is a duotone: the core in --accent, the soft outer halo picking up --accent2.
   That is what makes it read as bloom rather than as a coloured drop-shadow.

   Bloom recipe: a tight bright ring, a mid halo, a wide faint wash, and an
   inset sheen. Always box-shadow or drop-shadow - never filter: blur() on a
   live element, which would cost a repaint per frame.
   ═══════════════════════════════════════════════════════════════════════════ */

:root {
  /* deep dark, very slightly violet so neons sit warm on it */
  --bg:      #08071a;
  --panel:   #141232;
  --line:    #322a63;
  --line2:   #483c85;

  /* pastel-leaning text, never pure white */
  --text:    #f0edff;
  --muted:   #b0a7dd;
  --dim:     #8279b5;

  /* overridden from JS - the Forest's two hues */
  --accent:  #8fe37d;
  --accent2: #5eead4;

  /* neon pastel grade ramp - the descent log's four rails */
  --clean:    #7dffa8;
  --hurt:     #ffe27d;
  --bloodied: #ffab7d;
  --down:     #ff6b8a;

  --mono:    ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
  --sans:    system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --display: "Cinzel", Georgia, serif;

  --r:  12px;
  --r2: 9px;
}

* { box-sizing: border-box; }

html { color-scheme: dark; }

body {
  margin: 0;
  min-height: 100vh;
  background: var(--bg);
  color: var(--text);
  font-family: var(--sans);
  font-size: 15px;
  line-height: 1.55;
  overflow-x: hidden;
}

/* ─── backdrop: drifting aurora + grain ─────────────────────────────────── */

/* ⚠️ body is position: relative with NO z-index, so it creates no stacking
   context and these three paint under the content. Giving body a z-index
   would hide all of them. */
body::before {
  content: "";
  position: fixed; inset: -30%;
  z-index: -2; pointer-events: none;
  background:
    radial-gradient(40% 32% at 20% 10%, color-mix(in srgb, var(--accent) 62%, transparent), transparent 68%),
    radial-gradient(38% 30% at 84% 6%,  color-mix(in srgb, var(--accent2) 66%, transparent), transparent 68%),
    radial-gradient(52% 40% at 64% 98%, color-mix(in srgb, var(--accent2) 44%, transparent), transparent 70%),
    radial-gradient(44% 34% at 4% 74%,  color-mix(in srgb, var(--accent) 38%, transparent), transparent 70%),
    radial-gradient(60% 46% at 50% 44%, color-mix(in srgb, var(--accent2) 16%, transparent), transparent 74%);
  /* do NOT blur() this - the pools are already soft and a blur flattens five
     distinct ones into a single haze. Saturation does the work. */
  filter: saturate(165%);
  opacity: .78;
  will-change: transform;
  animation: drift 42s ease-in-out infinite alternate;
  transition: background .8s ease;
}

body::after {
  content: "";
  position: fixed; inset: 0;
  z-index: -1; pointer-events: none;
  background:
    radial-gradient(130% 100% at 50% 6%, transparent 50%, rgba(5,4,18,.46) 84%, rgba(5,4,18,.72) 100%);
}
body { position: relative; }

/* fine grain - kills the banding that big soft gradients always produce */
.grain {
  position: fixed; inset: 0; z-index: -1; pointer-events: none; opacity: .14;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

@keyframes drift {
  0%   { transform: translate3d(0,0,0) scale(1); }
  50%  { transform: translate3d(2.5%, -2%, 0) scale(1.06); }
  100% { transform: translate3d(-2%, 2.5%, 0) scale(1.02); }
}

/* ─── utilities ─────────────────────────────────────────────────────────── */

.hidden { display: none !important; }
.muted  { color: var(--muted); }
.small  { font-size: 13px; }
.empty  { color: var(--dim); font-size: 13px; font-style: italic; }
.err    { color: #ff8fa8; text-shadow: 0 0 14px rgba(255,107,138,.55); }
.label {
  color: var(--dim); font-size: 11px; font-weight: 600;
  text-transform: uppercase; letter-spacing: .14em;
}

/* glassy surface shared by every card */
.panel, .gate-card, .modal-card, .biome-banner {
  background:
    linear-gradient(158deg, rgba(255,255,255,.055), rgba(255,255,255,.012) 42%, rgba(0,0,0,.14));
  border: 1px solid var(--line);
  border-radius: var(--r);
  backdrop-filter: blur(14px) saturate(120%);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.10),
    inset 0 0 60px -26px color-mix(in srgb, var(--accent) 85%, transparent),
    inset 0 -40px 80px -60px color-mix(in srgb, var(--accent2) 90%, transparent),
    0 0 34px -22px color-mix(in srgb, var(--accent2) 60%, transparent),
    0 22px 48px -26px rgba(0,0,0,.9);
}
.panel { padding: 17px 19px; }

.panel-title {
  margin: 0 0 13px; font-size: 11px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .16em;
  color: color-mix(in srgb, var(--accent) 62%, var(--muted));
  text-shadow: 0 0 16px color-mix(in srgb, var(--accent) 45%, transparent);
}

/* ─── buttons ───────────────────────────────────────────────────────────── */

.btn {
  font: inherit; cursor: pointer; border-radius: var(--r2);
  border: 1px solid var(--line2);
  background: linear-gradient(180deg, rgba(255,255,255,.06), rgba(255,255,255,.015));
  color: var(--text); padding: 10px 17px;
  transition: border-color .18s, box-shadow .18s, transform .08s, color .18s;
}
.btn:hover {
  border-color: color-mix(in srgb, var(--accent) 60%, var(--line2));
  color: #fff;
  box-shadow:
    0 0 0 1px color-mix(in srgb, var(--accent) 28%, transparent),
    0 0 18px -2px color-mix(in srgb, var(--accent) 45%, transparent),
    0 0 40px -6px color-mix(in srgb, var(--accent2) 35%, transparent);
}
.btn:active { transform: translateY(1px); }
.btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.btn.primary {
  font-weight: 650; color: #fff;
  border-color: color-mix(in srgb, var(--accent) 65%, transparent);
  background:
    linear-gradient(180deg,
      color-mix(in srgb, var(--accent) 30%, transparent),
      color-mix(in srgb, var(--accent2) 20%, transparent));
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.28),
    0 0 20px -3px color-mix(in srgb, var(--accent) 55%, transparent),
    0 0 46px -8px color-mix(in srgb, var(--accent2) 45%, transparent);
  text-shadow: 0 0 16px color-mix(in srgb, var(--accent) 70%, transparent);
}
.btn.primary:hover {
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.34),
    0 0 28px -2px color-mix(in srgb, var(--accent) 75%, transparent),
    0 0 66px -6px color-mix(in srgb, var(--accent2) 60%, transparent);
}

.btn.ghost { background: transparent; border-color: var(--line); }
.btn.small { padding: 6px 12px; font-size: 12.5px; }
.btn.danger:hover {
  border-color: rgba(255,107,138,.6); color: #ffa8ba;
  box-shadow: 0 0 20px -3px rgba(255,107,138,.5), 0 0 44px -8px rgba(255,107,138,.3);
}
.btn:disabled { opacity: .4; cursor: not-allowed; transform: none; box-shadow: none; }

/* ─── login gate ────────────────────────────────────────────────────────── */

.gate { min-height: 100vh; display: grid; place-items: center; padding: 24px; }
.gate-card { width: 100%; max-width: 392px; padding: 38px 30px 32px; border-radius: 16px; }

.wordmark {
  font-family: var(--display); font-weight: 700; letter-spacing: .07em;
  margin: 0; font-size: 38px; text-align: center; line-height: 1.1;
  background: linear-gradient(170deg, #fff 8%, var(--accent) 52%, var(--accent2) 100%);
  -webkit-background-clip: text; background-clip: text; color: transparent;
  /* drop-shadow blooms the *glyphs*; text-shadow cannot reach clipped text */
  filter:
    drop-shadow(0 0 10px color-mix(in srgb, var(--accent) 60%, transparent))
    drop-shadow(0 0 34px color-mix(in srgb, var(--accent2) 45%, transparent));
  animation: breathe 5.5s ease-in-out infinite;
}
@keyframes breathe { 0%,100% { opacity: .93; } 50% { opacity: 1; } }

.wordmark.small { font-size: 20px; text-align: left; letter-spacing: .13em; animation: none; }

.tagline { text-align: center; color: var(--muted); margin: 9px 0 28px; font-size: 13.5px; }

.gate-form { display: grid; gap: 8px; }
.gate-form label {
  font-size: 11px; color: var(--dim); font-weight: 600;
  text-transform: uppercase; letter-spacing: .14em;
}
.gate-form input {
  font: inherit; padding: 12px 14px; border-radius: var(--r2);
  background: rgba(0,0,0,.42); border: 1px solid var(--line); color: var(--text);
  transition: border-color .18s, box-shadow .18s;
}
.gate-form input::placeholder { color: var(--dim); }
.gate-form input:focus {
  outline: none;
  border-color: color-mix(in srgb, var(--accent) 70%, transparent);
  box-shadow:
    0 0 0 3px color-mix(in srgb, var(--accent) 14%, transparent),
    0 0 26px -6px color-mix(in srgb, var(--accent) 60%, transparent);
}
#code {
  font-family: var(--mono); font-size: 23px; letter-spacing: .42em;
  text-align: center; text-indent: .42em;
  color: var(--accent); text-shadow: 0 0 18px color-mix(in srgb, var(--accent) 60%, transparent);
}
.gate-form .btn { margin-top: 7px; }

.dev-note {
  margin-top: 20px; padding: 12px 14px; border-radius: var(--r2); font-size: 13px;
  background: rgba(255,226,125,.07); border: 1px solid rgba(255,226,125,.32);
  color: #ffe9a8; box-shadow: inset 0 0 30px -14px rgba(255,226,125,.6);
}

/* ─── top bar ───────────────────────────────────────────────────────────── */

/* With no nav to hold, this is two groups on one row at every width. */
.topbar {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px 16px; flex-wrap: wrap; padding: 14px 24px;
  position: sticky; top: 0; z-index: 20;
  border-bottom: 1px solid var(--line);
  background: linear-gradient(180deg, rgba(6,6,14,.92), rgba(6,6,14,.66));
  backdrop-filter: blur(16px) saturate(130%);
  box-shadow: 0 1px 0 color-mix(in srgb, var(--accent) 14%, transparent),
              0 16px 40px -30px color-mix(in srgb, var(--accent) 60%, transparent);
}
.brand { display: flex; align-items: baseline; gap: 15px; min-width: 0; flex-wrap: wrap; row-gap: 2px; }
/* `.day-tag` lived here and is gone with the delve number it held. The board
   modal's title is the only place the day is named now. */
.topbar-right { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }

.streak-tag {
  font-size: 12px; padding: 5px 12px; border-radius: 999px; white-space: nowrap;
  color: var(--accent);
  border: 1px solid color-mix(in srgb, var(--accent) 45%, transparent);
  background: color-mix(in srgb, var(--accent) 9%, transparent);
  text-shadow: 0 0 14px color-mix(in srgb, var(--accent) 55%, transparent);
  box-shadow: 0 0 20px -6px color-mix(in srgb, var(--accent) 60%, transparent),
              inset 0 0 18px -10px color-mix(in srgb, var(--accent) 80%, transparent);
}

/* ─── layout ────────────────────────────────────────────────────────────── */

/* One column. There is one thing to do on this page. */
.solo {
  display: grid; gap: 17px; align-content: start;
  max-width: 760px; margin: 0 auto; padding: 22px 24px 72px;
}
@media (max-width: 640px) { .solo { padding-left: 16px; padding-right: 16px; } }

/* ─── the forest banner ─────────────────────────────────────────────────── */

.biome-banner {
  display: grid; grid-template-columns: auto 1fr auto; gap: 20px; align-items: center;
  padding: 20px 22px; position: relative; overflow: hidden;
  border-color: color-mix(in srgb, var(--accent) 34%, var(--line));
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.08),
    inset 0 0 70px -30px color-mix(in srgb, var(--accent) 90%, transparent),
    0 0 44px -22px color-mix(in srgb, var(--accent) 70%, transparent),
    0 22px 48px -26px rgba(0,0,0,.95);
}
/* a slow sheen crossing the banner */
.biome-banner::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(115deg, transparent 38%,
              color-mix(in srgb, var(--accent) 12%, transparent) 50%, transparent 62%);
  transform: translateX(-60%);
  animation: sheen 9s ease-in-out infinite;
}
@keyframes sheen { 0%,72% { transform: translateX(-60%); } 100% { transform: translateX(60%); } }

.biome-emoji {
  font-size: 44px; line-height: 1;
  filter:
    drop-shadow(0 0 14px color-mix(in srgb, var(--accent) 85%, transparent))
    drop-shadow(0 0 40px color-mix(in srgb, var(--accent2) 60%, transparent));
}
.biome-banner h2 {
  font-family: var(--display); margin: 0 0 4px; font-size: 24px; letter-spacing: .04em;
  color: #fff;
  text-shadow:
    0 0 16px color-mix(in srgb, var(--accent) 65%, transparent),
    0 0 44px color-mix(in srgb, var(--accent2) 45%, transparent);
}
.biome-banner p { margin: 0; font-size: 13px; }
.countdown { text-align: right; }
.countdown strong {
  display: block; font-family: var(--mono); font-size: 18px; margin-top: 3px;
  color: var(--accent);
  text-shadow: 0 0 18px color-mix(in srgb, var(--accent) 65%, transparent);
}
/* "- unlocks tomorrow 8:07 PM", in the viewer's own zone and locale. Quieter
   than the countdown on purpose: the countdown is the live thing, this is the
   fact you write down. Empty (and therefore invisible) whenever a delve is
   ready or the runtime could not format a time. */
.unlock-at {
  display: block; margin-top: 2px;
  font-size: 12px; letter-spacing: .01em; color: var(--muted);
}
.unlock-at:empty { display: none; }
@media (max-width: 640px) {
  .biome-banner { grid-template-columns: auto 1fr; }
  .countdown { grid-column: 1/-1; text-align: left; }
}

/* ─── the descend button ────────────────────────────────────────────────
   There was a `.delver` card above this button - emoji, rolled name, class and
   the four stats - and every rule for it is deleted rather than left to rot.
   There is no character to roll and the stats are not shown, so the pre-delve
   screen is deliberately just the banner, this button and the countdown. */

.delve-gate {
  text-align: center; padding: 34px 24px 46px; border-radius: var(--r);
  border: 1px solid var(--line);
  background:
    radial-gradient(75% 130% at 50% 50%, color-mix(in srgb, var(--accent) 11%, transparent), transparent 70%),
    linear-gradient(158deg, rgba(255,255,255,.045), rgba(255,255,255,.008) 45%, rgba(0,0,0,.16));
  backdrop-filter: blur(14px) saturate(120%);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.09),
    inset 0 0 90px -40px color-mix(in srgb, var(--accent) 95%, transparent),
    inset 0 -50px 90px -70px color-mix(in srgb, var(--accent2) 95%, transparent),
    0 22px 48px -26px rgba(0,0,0,.9);
}
.delve-gate p { margin-top: 15px; }

.btn.delve {
  position: relative; isolation: isolate;
  font-family: var(--display); font-size: 22px; font-weight: 700; letter-spacing: .18em;
  padding: 20px 60px; text-transform: uppercase; color: #fff; border-radius: 14px;
  border: 1px solid color-mix(in srgb, var(--accent) 70%, transparent);
  background:
    linear-gradient(180deg,
      color-mix(in srgb, var(--accent) 26%, transparent),
      color-mix(in srgb, var(--accent2) 18%, transparent)),
    rgba(10,10,22,.6);
  text-shadow:
    0 0 18px color-mix(in srgb, var(--accent) 80%, transparent),
    0 0 48px color-mix(in srgb, var(--accent2) 60%, transparent);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.3),
    inset 0 0 40px -18px color-mix(in srgb, var(--accent) 90%, transparent),
    0 0 26px -4px color-mix(in srgb, var(--accent) 60%, transparent),
    0 0 70px -10px color-mix(in srgb, var(--accent2) 55%, transparent);
}
/* ⚠️ THE PULSE ANIMATES OPACITY ONLY (2026-09-27, the "page lags after hours"
   report). It used to animate box-shadow on the button itself, which the
   browser cannot hand to the GPU: it re-styled and repainted the button on the
   main thread EVERY FRAME for as long as the page was open (measured: 120 style
   recalcs a second on an idle page). Now the brighter glow is drawn ONCE on this
   layer and only its opacity breathes - a compositor-only animation, no restyle,
   no repaint. Never animate box-shadow / filter / text-shadow on anything that
   loops forever. */
.btn.delve::after {
  content: ""; position: absolute; inset: 0; border-radius: inherit; pointer-events: none; z-index: -1;
  box-shadow:
    inset 0 0 40px -14px color-mix(in srgb, var(--accent) 100%, transparent),
    0 0 38px -2px color-mix(in srgb, var(--accent) 80%, transparent),
    0 0 104px -6px color-mix(in srgb, var(--accent2) 75%, transparent);
  opacity: 0;
  animation: pulse 3.4s ease-in-out infinite;
}
@keyframes pulse { 0%,100% { opacity: 0; } 50% { opacity: 1; } }
.btn.delve:hover::after { animation-play-state: paused; }
.btn.delve:hover { transform: translateY(-1px); }
.btn.delve:disabled::after { animation: none; opacity: 0; }
/* "Descending…" outgrows the 60px padding inside the gate on a phone */
@media (max-width: 640px) {
  .btn.delve { padding-left: 30px; padding-right: 30px; max-width: 100%; }
}

/* ─── descent log ───────────────────────────────────────────────────────── */

.descent-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 18px; margin-bottom: 15px; flex-wrap: wrap;
}
.descent-title { display: flex; align-items: center; gap: 12px; min-width: 0; }
.descent-head h3 {
  margin: 0; font-family: var(--display); font-size: 15px;
  letter-spacing: .2em; text-transform: uppercase; color: var(--accent);
  text-shadow: 0 0 18px color-mix(in srgb, var(--accent) 60%, transparent);
}
/* The way out of a 104-room run. Quiet - it is an exit, not an invitation. */
.btn.skip {
  letter-spacing: .1em; text-transform: uppercase; font-size: 11px;
  padding: 4px 11px; color: var(--muted);
  border-color: color-mix(in srgb, var(--accent) 34%, var(--line));
}
.btn.skip:hover {
  color: var(--text);
  border-color: color-mix(in srgb, var(--accent) 62%, transparent);
  box-shadow: 0 0 14px -4px var(--accent), 0 0 30px -12px var(--accent2);
}
.descent-hint { margin: -6px 0 11px; color: var(--dim); }
.hpwrap { display: flex; align-items: center; gap: 11px; min-width: 216px; }
.hp-label { font-family: var(--mono); font-size: 11.5px; color: var(--muted); white-space: nowrap; }
.hpbar {
  flex: 1; height: 8px; border-radius: 999px; overflow: hidden;
  background: rgba(0,0,0,.55); border: 1px solid var(--line);
  box-shadow: inset 0 1px 3px rgba(0,0,0,.8);
}
.hp-fill {
  height: 100%; width: 100%; border-radius: 999px;
  transition: width .38s cubic-bezier(.4,0,.2,1), background .38s, box-shadow .38s;
}

/* ─── summary + share card ──────────────────────────────────────────────── */

.summary-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; margin-bottom: 15px; }
.stat {
  background: linear-gradient(160deg, rgba(255,255,255,.05), rgba(255,255,255,.008));
  border: 1px solid var(--line); border-radius: var(--r2); padding: 12px 14px;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.06);
}
.stat strong {
  display: block; font-size: 26px; font-family: var(--display); margin-top: 4px;
  background: linear-gradient(155deg, #fff 10%, var(--accent) 62%, var(--accent2));
  -webkit-background-clip: text; background-clip: text; color: transparent;
  filter:
    drop-shadow(0 0 12px color-mix(in srgb, var(--accent) 70%, transparent))
    drop-shadow(0 0 32px color-mix(in srgb, var(--accent2) 55%, transparent));
}

.aftermath { display: grid; gap: 7px; margin-bottom: 15px; }
.after-line {
  padding: 9px 13px; border-radius: var(--r2); font-size: 13.5px; line-height: 1.5;
  background: linear-gradient(160deg, rgba(255,255,255,.05), rgba(255,255,255,.008));
  border: 1px solid var(--line);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.06);
  animation: popIn .45s cubic-bezier(.2,.9,.3,1.2) both;
}
@keyframes popIn { from { opacity: 0; transform: translateY(8px) scale(.96); } to { opacity: 1; transform: none; } }

.share { display: flex; gap: 15px; align-items: flex-start; flex-wrap: wrap; }
.share-card {
  flex: 1; min-width: 268px; margin: 0; padding: 15px 17px; border-radius: var(--r2);
  background: rgba(0,0,0,.42);
  border: 1px solid color-mix(in srgb, var(--accent) 26%, var(--line));
  font-family: var(--mono); font-size: 13px; line-height: 1.7;
  white-space: pre-wrap; word-break: break-word;
  box-shadow: inset 0 0 44px -22px color-mix(in srgb, var(--accent) 90%, transparent);
}

/* ─── dev panel ─────────────────────────────────────────────────────────── */

.panel.dev {
  border-color: rgba(255,226,125,.3);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.06),
    inset 0 0 40px -24px rgba(255,226,125,.9),
    0 22px 48px -26px rgba(0,0,0,.95);
}
.panel.dev .panel-title { color: #ffe27d; text-shadow: 0 0 16px rgba(255,226,125,.5); }
.dev-btns { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 11px; }

/* ─── the board ─────────────────────────────────────────────────────────── */

.modal {
  position: fixed; inset: 0; z-index: 50; padding: 20px;
  display: grid; place-items: center;
  background: rgba(3,3,8,.78); backdrop-filter: blur(6px);
  animation: fadeIn .2s ease both;
}
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
.modal-card {
  width: 100%; max-width: 540px; max-height: 82vh;
  display: flex; flex-direction: column; overflow: hidden; border-radius: 15px;
  border-color: color-mix(in srgb, var(--accent) 30%, var(--line));
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.08),
    0 0 60px -20px color-mix(in srgb, var(--accent) 60%, transparent),
    0 40px 90px -40px #000;
  animation: popIn .28s cubic-bezier(.2,.9,.3,1.1) both;
}
.modal-head {
  display: flex; justify-content: space-between; align-items: center;
  padding: 17px 19px; border-bottom: 1px solid var(--line);
}
.modal-head h3 {
  margin: 0; font-family: var(--display); letter-spacing: .1em; font-size: 17px; color: #fff;
  text-shadow: 0 0 18px color-mix(in srgb, var(--accent) 60%, transparent);
}
.board-body { padding: 15px 19px 20px; overflow-y: auto; }
.board-note { margin: 0 0 6px; }
/* Where this window's edges fall in the READER's zone. The window itself is one
   shared server-side definition and does not move; this is the sentence that
   explains it to somebody who is not in the server's timezone. */
.board-window { margin: 0 0 12px; opacity: .78; }
.board-row {
  display: grid; grid-template-columns: 32px minmax(0,1fr) auto; gap: 11px; align-items: baseline;
  padding: 9px 8px; border-bottom: 1px solid var(--line); font-size: 14px; border-radius: 7px;
}
.board-row:last-child { border-bottom: none; }
.board-row .rank { font-family: var(--display); color: var(--dim); }
.board-row .bsub { color: var(--dim); font-size: 12px; }
.board-row .val {
  font-family: var(--mono); font-size: 12.5px; color: var(--accent); white-space: nowrap;
  text-shadow: 0 0 14px color-mix(in srgb, var(--accent) 55%, transparent);
}
.board-row.me {
  background: color-mix(in srgb, var(--accent) 11%, transparent);
  box-shadow: inset 0 0 34px -16px color-mix(in srgb, var(--accent) 100%, transparent),
              0 0 22px -12px color-mix(in srgb, var(--accent) 70%, transparent);
}
.board-row.me .rank { color: var(--accent); }

/* ─── toast ─────────────────────────────────────────────────────────────── */

.toast {
  position: fixed; bottom: 24px; left: 50%; transform: translateX(-50%); z-index: 60;
  width: max-content; max-width: calc(100vw - 32px); text-align: center;
  padding: 10px 18px; border-radius: 999px; font-size: 13.5px; color: #fff;
  background:
    linear-gradient(158deg, rgba(255,255,255,.07), rgba(255,255,255,.015) 45%, rgba(0,0,0,.2)),
    rgba(8,7,26,.86);
  border: 1px solid color-mix(in srgb, var(--accent) 55%, transparent);
  backdrop-filter: blur(14px) saturate(130%);
  text-shadow: 0 0 14px color-mix(in srgb, var(--accent) 60%, transparent);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.12),
    inset 0 0 30px -14px color-mix(in srgb, var(--accent) 90%, transparent),
    0 0 22px -4px color-mix(in srgb, var(--accent) 55%, transparent),
    0 0 50px -8px color-mix(in srgb, var(--accent2) 45%, transparent),
    0 14px 34px -18px #000;
  animation: toastIn .26s cubic-bezier(.2,.9,.3,1.1) both;
}
.toast.bad {
  border-color: rgba(255,107,138,.6);
  text-shadow: 0 0 14px rgba(255,107,138,.6);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.12),
    inset 0 0 30px -14px rgba(255,107,138,.9),
    0 0 22px -4px rgba(255,107,138,.55),
    0 0 50px -8px rgba(255,171,125,.45),
    0 14px 34px -18px #000;
}
@keyframes toastIn {
  from { opacity: 0; transform: translate(-50%, 10px); }
  to   { opacity: 1; transform: translate(-50%, 0); }
}

/* ─── scrollbars + selection ────────────────────────────────────────────── */

* { scrollbar-width: thin; scrollbar-color: var(--line2) transparent; }
::-webkit-scrollbar { width: 9px; height: 9px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
  background: var(--line2); border-radius: 999px; border: 2px solid transparent;
  background-clip: padding-box;
}
::-webkit-scrollbar-thumb:hover { background: color-mix(in srgb, var(--accent) 55%, var(--line2)); background-clip: padding-box; }

::selection { background: color-mix(in srgb, var(--accent) 35%, transparent); color: #fff; }

/* ─── motion off ────────────────────────────────────────────────────────── */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important; animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
}

/* ═══════════════════════════════════════════════════════════════════════════
   THE RUN - events, fight rounds, the award ledger, the multiplier readout,
   the drop chips and the verdict.

   Same duotone rule as everything above: a bright core in one hue and a soft
   halo in a second. The drop chips are the one place a THIRD hue enters, and it
   arrives from the server's tier legend as `--tc` on the element, never from a
   class list here - so adding a tier is a content change, not a CSS change.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ─── the meters row ────────────────────────────────────────────────────── */

.runmeters { display: flex; align-items: center; gap: 18px; flex-wrap: wrap; justify-content: flex-end; }
.multwrap, .expwrap { display: flex; align-items: baseline; gap: 7px; }
.mult-now, .exp-now {
  font-family: var(--mono); font-size: 16px; font-weight: 700; color: var(--text);
  font-variant-numeric: tabular-nums; transition: color .3s, text-shadow .3s;
}
/* Past x2 the multiplier is deciding the run, and it starts to say so. */
.multwrap.hot .mult-now {
  color: var(--accent);
  text-shadow: 0 0 10px var(--accent), 0 0 26px var(--accent2);
}
.exp-now { color: var(--accent); text-shadow: 0 0 9px var(--accent), 0 0 22px var(--accent2); }

@media (max-width: 640px) {
  .descent-head { flex-direction: column; align-items: stretch; gap: 10px; }
  .runmeters { justify-content: space-between; gap: 10px; }
  .hpwrap { min-width: 0; flex: 1 1 100%; order: 3; }
}

/* ─── one event ─────────────────────────────────────────────────────────── */

.events { display: grid; gap: 9px; }
.ev {
  border: 1px solid var(--line); border-radius: var(--r2);
  background: linear-gradient(160deg, rgba(255,255,255,.035), rgba(255,255,255,.006));
  padding: 10px 12px; border-left: 2px solid var(--line2);
  animation: evIn .34s cubic-bezier(.2,.8,.2,1) both;
}
@keyframes evIn {
  from { opacity: 0; transform: translateY(-7px) scaleY(.96); filter: blur(2px); }
  to   { opacity: 1; transform: none; filter: none; }
}
/* One rail per room KIND. The rail says what happened to you; the tier chip in
   the head says how rich the room was. Two different questions, two places. */
.ev.k-mob      { border-left-color: var(--clean); }
.ev.k-item     { border-left-color: var(--accent2); }
.ev.k-treasure { border-left-color: var(--hurt); background: linear-gradient(160deg, rgba(255,226,125,.07), rgba(255,255,255,.006)); }
.ev.k-trap     { border-left-color: var(--bloodied); background: rgba(255,171,125,.05); }
/* the one that ended it */
.ev.fatal {
  border-left-color: var(--down); background: rgba(255,107,138,.11);
  box-shadow: -1px 0 24px -3px rgba(255,107,138,.7), inset 0 0 40px -22px rgba(255,107,138,.9);
}

/* ─── the collapsed room line ───────────────────────────────────────────
   A real <button> spanning the whole room, so it is focusable and operable from
   the keyboard for free. Four columns: caret · RARITY · the line · the EXP.
   The line ellipsizes rather than wrapping - every room is exactly one row high
   at every width, and the detail is one click away, which is also how the long
   mob and drop names that used to be cut off on a phone are now readable. */

.ev-row {
  width: 100%; display: grid; align-items: baseline; gap: 10px;
  grid-template-columns: 9px auto minmax(0, 1fr) auto;
  font: inherit; color: inherit; text-align: left; cursor: pointer;
  background: none; border: 0; padding: 0; border-radius: 6px;
}
.ev-row:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; }
.ev-row:hover .rs-what { color: #fff; }

.rs-caret {
  color: var(--dim); font-size: 13px; line-height: 1;
  transition: transform .18s ease, color .18s;
  transform-origin: 40% 55%;
}
.ev-row[aria-expanded="true"] .rs-caret { transform: rotate(90deg); color: var(--tc, var(--accent)); }

/* THE RARITY WORD - first thing on the line, in the room's own tier colour,
   which arrives as `--tc` from the server's legend and never from a class list
   here. A word rather than a pill: a pill per row in a 100-row log is noise. */
.rs-tier {
  font-size: 9.5px; font-weight: 800; letter-spacing: .15em; text-transform: uppercase;
  color: var(--tc, var(--muted)); white-space: nowrap;
  text-shadow: 0 0 10px color-mix(in srgb, var(--tc, transparent) 70%, transparent);
}
/* Divine. `text-shadow` cannot reach `background-clip: text` glyphs, so the
   bloom is a drop-shadow filter - same rule as the wordmark. */
.rs-tier.prismatic {
  background: linear-gradient(115deg, #fff3b0, #ff6fae, #5eead4, #b79dff, #ffc46b, #fff3b0);
  background-size: 300% 100%;
  -webkit-background-clip: text; background-clip: text; color: transparent;
  text-shadow: none; animation: prism 7s linear infinite;
  filter: drop-shadow(0 0 8px rgba(255,243,176,.75));
}

.rs-line { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rs-what { font-weight: 650; color: var(--text); transition: color .18s; }
.rs-count { color: var(--hurt); }
.rs-rest { color: var(--muted); }
.rs-tint { color: var(--tc); font-weight: 650; text-shadow: 0 0 10px color-mix(in srgb, var(--tc) 55%, transparent); }
.rs-right { display: flex; gap: 10px; align-items: baseline; white-space: nowrap; }

.ev-gain {
  font-family: var(--mono); font-size: 13px; font-weight: 700; color: var(--accent);
  text-shadow: 0 0 10px var(--accent2); font-variant-numeric: tabular-nums;
}
/* The survival multiplier in force in this room. Deliberately quiet: it is
   context for the number next to it, not a number to read on its own. It sits
   between the HP change and the gain so the row reads left to right as
   "what it cost me / what it was worth / what I got". */
.rs-mult {
  font-family: var(--mono); font-size: 11px; color: var(--dim);
  font-variant-numeric: tabular-nums; letter-spacing: .02em;
}
/* Past a couple of doublings the multiplier IS the story of the run, so it
   stops being furniture and picks up the accent colour. */
.ev.deep .rs-mult { color: var(--accent); text-shadow: 0 0 8px var(--accent2); }

.ev-hp { font-family: var(--mono); font-size: 11.5px; }
.ev-hp.up   { color: var(--clean); text-shadow: 0 0 10px rgba(125,255,168,.6); }
.ev-hp.down { color: var(--down);  text-shadow: 0 0 10px rgba(255,107,138,.6); }

.ev-text { margin: 7px 0 0; font-size: 13px; color: var(--muted); }

/* ─── the detail, under the line ────────────────────────────────────────
   Hidden by the `hidden` attribute (so it is out of the accessibility tree,
   not merely invisible) and separated from its line by a hairline rather than
   a second card, because it belongs to the row above it. */
.ev-body {
  margin-top: 9px; padding-top: 8px;
  border-top: 1px dashed color-mix(in srgb, var(--tc, var(--line2)) 34%, transparent);
  animation: bodyIn .2s ease both;
}
@keyframes bodyIn { from { opacity: 0; transform: translateY(-3px); } to { opacity: 1; transform: none; } }
.ev-meta {
  font-family: var(--mono); font-size: 11px; color: var(--dim);
  letter-spacing: .04em; font-variant-numeric: tabular-nums;
}

/* ─── fight rounds ──────────────────────────────────────────────────────── */

.rounds { margin-top: 7px; display: grid; gap: 1px; font-family: var(--mono); font-size: 11.5px; }
.round {
  display: grid; grid-template-columns: 34px minmax(0,1fr) auto; gap: 9px;
  padding: 2px 6px; border-radius: 5px; align-items: baseline;
}
.round .r-who { color: var(--dim); }
.round .r-what b { color: var(--text); font-weight: 700; }
.round .r-hp { color: var(--dim); white-space: nowrap; font-variant-numeric: tabular-nums; }
.round.adv { background: rgba(125,255,168,.05); }
.round.mob { background: rgba(255,107,138,.06); }
.round.miss { opacity: .5; }
.round.miss .r-what { font-style: italic; }

/* ─── the award ledger - base x mult = total ────────────────────────────── */

.awards { margin-top: 8px; display: grid; gap: 2px; font-family: var(--mono); font-size: 12px; }
.award {
  display: grid; grid-template-columns: minmax(0,1fr) auto auto; gap: 12px;
  align-items: baseline; padding: 2px 6px; border-radius: 5px;
}
.award .a-label { color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.award .a-math  { color: var(--dim); white-space: nowrap; font-variant-numeric: tabular-nums; }
.award .a-x     { opacity: .6; }
.award .a-total {
  color: var(--text); font-weight: 700; min-width: 54px; text-align: right;
  font-variant-numeric: tabular-nums;
}
/* a drop line is the one worth looking at */
.award.is-drop { background: rgba(255,255,255,.05); }
.award.is-drop .a-label { color: var(--accent); }
.award.is-drop .a-total { color: var(--accent); text-shadow: 0 0 10px var(--accent2); }

/* ─── drop chips ────────────────────────────────────────────────────────── */

.ev-drop { margin-top: 8px; }
.drop-chip {
  display: inline-flex; align-items: baseline; gap: 9px; flex-wrap: wrap;
  padding: 5px 11px; border-radius: 999px;
  border: 1px solid color-mix(in srgb, var(--tc) 55%, transparent);
  background: linear-gradient(135deg, color-mix(in srgb, var(--tc) 13%, transparent), rgba(255,255,255,.02));
  box-shadow: 0 0 12px -2px color-mix(in srgb, var(--tc) 55%, transparent),
              inset 0 1px 0 rgba(255,255,255,.12);
  font-size: 12.5px; max-width: 100%;
}
.drop-chip .dc-tier {
  color: var(--tc); font-size: 10px; font-weight: 800;
  text-transform: uppercase; letter-spacing: .13em;
  text-shadow: 0 0 10px color-mix(in srgb, var(--tc) 75%, transparent);
}
.drop-chip .dc-name { color: var(--text); min-width: 0; }
.drop-chip .dc-exp {
  font-family: var(--mono); font-weight: 700; color: var(--tc);
  font-variant-numeric: tabular-nums;
}

/* DIVINE, and the Legend verdict. The only two things in the game that get a
   moving multi-stop treatment, so "above everything else" is legible without
   reading the label. */
.drop-chip.prismatic, .verdict.prismatic {
  border-color: transparent;
  background: linear-gradient(115deg, #fff3b0, #ff6fae, #5eead4, #b79dff, #ffc46b, #fff3b0);
  background-size: 300% 100%;
  animation: prism 7s linear infinite;
  box-shadow: 0 0 18px -2px rgba(255,243,176,.75), 0 0 44px -8px rgba(255,111,174,.55),
              inset 0 1px 0 rgba(255,255,255,.4);
}
.drop-chip.prismatic .dc-name,
.drop-chip.prismatic .dc-tier,
.drop-chip.prismatic .dc-exp { color: #16112e; text-shadow: none; }
@keyframes prism { to { background-position: 300% 0; } }

/* ─── the verdict ───────────────────────────────────────────────────────── */

.verdict-bar { margin-bottom: 15px; }
.verdict {
  display: inline-flex; align-items: baseline; gap: 12px;
  padding: 9px 18px; border-radius: 999px;
  border: 1px solid color-mix(in srgb, var(--vc) 60%, transparent);
  background: linear-gradient(135deg, color-mix(in srgb, var(--vc) 16%, transparent), rgba(255,255,255,.02));
  box-shadow: 0 0 20px -3px color-mix(in srgb, var(--vc) 60%, transparent),
              inset 0 1px 0 rgba(255,255,255,.14);
}
.verdict .verdict-name {
  font-family: var(--display); font-size: 19px; font-weight: 700; letter-spacing: .07em;
  text-transform: uppercase; color: var(--vc);
  text-shadow: 0 0 14px color-mix(in srgb, var(--vc) 80%, transparent);
}
.verdict .verdict-pct { font-family: var(--mono); font-size: 12.5px; color: var(--muted); }
.verdict.prismatic .verdict-name,
.verdict.prismatic .verdict-pct { color: #16112e; text-shadow: none; }
.verdict-note { margin: 8px 0 0; font-size: 13px; font-style: italic; }

/* ─── the haul ──────────────────────────────────────────────────────────── */

.haul { margin-bottom: 15px; }
.haul-head {
  font-size: 10.5px; text-transform: uppercase; letter-spacing: .15em;
  color: var(--dim); font-weight: 700; margin-bottom: 8px;
}
.haul-list { display: flex; flex-wrap: wrap; gap: 7px; }

/* ─── board tabs + rows ─────────────────────────────────────────────────── */

.board-tabs {
  display: flex; gap: 6px; flex-wrap: wrap;
  padding: 0 19px 12px; border-bottom: 1px solid var(--line);
}
.tab {
  font: inherit; font-size: 12.5px; cursor: pointer;
  padding: 5px 13px; border-radius: 999px;
  background: transparent; color: var(--muted);
  border: 1px solid var(--line);
  transition: color .18s, border-color .18s, box-shadow .18s, background .18s;
}
.tab:hover { color: var(--text); border-color: var(--line2); }
.tab.on {
  color: var(--text); border-color: color-mix(in srgb, var(--accent) 70%, transparent);
  background: linear-gradient(135deg, color-mix(in srgb, var(--accent) 16%, transparent), rgba(255,255,255,.02));
  box-shadow: 0 0 14px -3px var(--accent), 0 0 30px -10px var(--accent2), inset 0 1px 0 rgba(255,255,255,.12);
}
.tab:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.board-row .bmain { display: grid; gap: 2px; min-width: 0; }
.board-row .bname { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.board-row .bverdict {
  font-size: 9.5px; font-weight: 800; letter-spacing: .13em; text-transform: uppercase;
  color: var(--vc); text-shadow: 0 0 10px color-mix(in srgb, var(--vc) 70%, transparent);
}
.board-row .bdrop {
  font-size: 11.5px; color: var(--tc); justify-self: start;
  text-shadow: 0 0 10px color-mix(in srgb, var(--tc) 55%, transparent);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%;
}

@media (max-width: 640px) {
  .summary-grid { grid-template-columns: repeat(2, 1fr); }
  .round { grid-template-columns: 30px minmax(0,1fr) auto; gap: 7px; font-size: 11px; }
  .award { gap: 8px; font-size: 11.5px; }
  /* The room line stays ONE line at every width - that is the whole point of
     collapsing it - so the phone rules only tighten it. */
  .ev-row { gap: 7px; grid-template-columns: 8px auto minmax(0,1fr) auto; }
  .rs-right { gap: 7px; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   THE ROOM MODEL - the rarity chip, the announce beat, the treasure burst and
   the growing numbers.

   Same rules as everything above: the tier colour arrives as `--tc` from the
   server's legend and never from a class list here, and every glow is a duotone.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ─── the room's own rarity ─────────────────────────────────────────────
   The rarity CHIP that used to sit in the room head is now the rarity WORD at
   the head of the collapsed line - see `.rs-tier` above. */

/* A room whose rarity is the top of the ladder lights its own rail. */
.ev.r-prismatic {
  border-left-color: #fff3b0;
  box-shadow: -1px 0 26px -4px rgba(255,243,176,.55), inset 0 0 40px -24px rgba(255,111,174,.8);
}

/* The beat between "a room opens" and "what it did". The rarity and the subject
   are on screen, the outcome and the EXP are still `.pending`, and the reel runs
   under the line while you wait.

   ⚠️ It is ABSOLUTELY POSITIONED, inside the room's own bottom padding. It used
   to be a block element that added ~12 px for the length of the beat - which was
   invisible when a room was a multi-line card and is a visible jitter now that a
   room is one line and a new one arrives every second. */
.ev { position: relative; }
.ev.opening { border-left-color: var(--tc, var(--line2)); }
.ev.opening::after {
  content: ""; position: absolute; left: 12px; right: 12px; bottom: 3px;
  height: 2px; border-radius: 2px;
  background: linear-gradient(90deg, transparent, var(--accent), var(--accent2), transparent);
  background-size: 220% 100%;
  animation: reel .7s linear infinite;
}
@keyframes reel { to { background-position: 220% 0; } }

/* ─── the treasure burst ────────────────────────────────────────────────── */

.burst-count {
  margin: 6px 0 0; font-family: var(--mono); font-size: 11.5px;
  color: var(--hurt); letter-spacing: .06em;
  text-shadow: 0 0 10px rgba(255,226,125,.55);
}
.ev-drop.burst { display: flex; flex-wrap: wrap; gap: 6px; }

/* Not yet landed. `visibility` rather than display so the row keeps its space
   and the ledger does not jump as each treasure arrives. */
.award.pending, .drop-chip.pending { visibility: hidden; }
.awards .award:not(.pending).is-drop { animation: landIn .3s cubic-bezier(.2,.9,.25,1) both; }
.ev-drop.burst .drop-chip:not(.pending) { animation: landIn .34s cubic-bezier(.2,.9,.25,1) both; }
@keyframes landIn {
  from { opacity: 0; transform: translateY(-5px) scale(.94); }
  to   { opacity: 1; transform: none; }
}

/* The item's name on its own ledger line - in a six-treasure room the tier
   alone stops being enough to tell the lines apart. */
.award .a-item { color: var(--tc, var(--text)); }
.award.is-drop .a-label { color: var(--tc, var(--accent)); }
.award.is-drop .a-total { color: var(--tc, var(--accent)); text-shadow: 0 0 10px color-mix(in srgb, var(--tc, var(--accent2)) 60%, transparent); }

/* ─── numbers that grow with the descent ────────────────────────────────── */

.ev-gain.mid  { font-size: 14px; }
.ev-gain.big  { font-size: 15.5px; letter-spacing: -.01em; text-shadow: 0 0 12px var(--accent), 0 0 26px var(--accent2); }
.ev-gain.huge { font-size: 17px;   letter-spacing: -.02em; text-shadow: 0 0 14px var(--accent), 0 0 34px var(--accent2); }
.exp-now { transition: font-size .35s cubic-bezier(.2,.8,.2,1), text-shadow .35s; }
.exp-now.mid  { font-size: 18px; }
.exp-now.big  { font-size: 21px; text-shadow: 0 0 12px var(--accent), 0 0 30px var(--accent2); }
.exp-now.huge { font-size: 24px; text-shadow: 0 0 16px var(--accent), 0 0 42px var(--accent2); }

/* ─── the haul tally ────────────────────────────────────────────────────── */

.haul-tally { margin: 9px 0 0; font-family: var(--mono); letter-spacing: .03em; }

@media (max-width: 640px) {
  .rs-tier { font-size: 8.5px; letter-spacing: .1em; }
  .exp-now.big, .exp-now.huge { font-size: 19px; }
}

/* The reduced-motion block earlier in this file names the animations it knows
   about, so anything added here has to opt in explicitly or it keeps moving. */
@media (prefers-reduced-motion: reduce) {
  .ev { animation: none; }
  .drop-chip.prismatic, .verdict.prismatic, .rs-tier.prismatic { animation: none; background-position: 0 0; }
  .ev.opening::after { animation: none; }
  .ev-body { animation: none; }
  .rs-caret { transition: none; }
  .awards .award.is-drop, .ev-drop.burst .drop-chip { animation: none; }
  .exp-now { transition: none; }
}

/* ─── the leaderboard, rngdle-style (2026-09-25) ─────────────────────────
   Owner asked for rngdle's global board look: the leader as a HERO card with a
   huge glowing number, underline tabs, and rows that end in a glowing number box.
   Colours arrive per element as --hc (hero) / --rc (row) / --cc (chip) from the
   verdict band or the best drop's tier, never from a class list. */

.modal-card.lb-card { max-width: 680px; max-height: 90vh; }
.lb-card .modal-head h3 { text-transform: uppercase; letter-spacing: .18em; }

.lb-card .board-tabs {
  gap: 0; flex-wrap: nowrap; overflow-x: auto; padding: 0 12px;
  scrollbar-width: none;
}
.lb-card .board-tabs::-webkit-scrollbar { display: none; }
.lb-card .tab {
  flex: 1 0 auto; border: none; border-radius: 0; background: none; box-shadow: none;
  padding: 12px 12px 11px; font-size: 11.5px; font-weight: 700;
  letter-spacing: .14em; text-transform: uppercase; color: var(--dim);
  border-bottom: 2px solid transparent;
}
.lb-card .tab:hover { color: var(--text); }
.lb-card .tab.on {
  color: var(--accent); background: none; box-shadow: none;
  border-bottom-color: var(--accent);
  text-shadow: 0 0 12px color-mix(in srgb, var(--accent) 70%, transparent);
}

.lb-hero {
  --hc: var(--accent);
  text-align: center; padding: 20px 16px 16px; margin-bottom: 14px; border-radius: 14px;
  border: 1px solid color-mix(in srgb, var(--hc) 45%, var(--line));
  background:
    radial-gradient(120% 90% at 50% 0%, color-mix(in srgb, var(--hc) 16%, transparent), transparent 70%),
    rgba(255,255,255,.015);
  box-shadow: 0 0 40px -18px var(--hc), inset 0 1px 0 rgba(255,255,255,.06);
}
.lb-hero-label {
  font-family: var(--display); font-size: 12px; font-weight: 700;
  letter-spacing: .24em; text-transform: uppercase; color: var(--muted); margin-bottom: 12px;
}
.lb-bigbox {
  display: inline-block; max-width: 100%; padding: 12px 26px; border-radius: 14px;
  border: 2px solid transparent;
  background:
    linear-gradient(var(--bg), var(--bg)) padding-box,
    linear-gradient(135deg, var(--hc), var(--accent2), var(--hc)) border-box;
  box-shadow: 0 0 34px -6px color-mix(in srgb, var(--hc) 80%, transparent),
              inset 0 0 26px -12px var(--hc);
}
.lb-bignum {
  display: block; font-family: var(--mono); font-weight: 800; line-height: 1.05;
  font-size: clamp(34px, 9vw, 56px); color: #fff; letter-spacing: .02em;
  overflow-wrap: anywhere;
  text-shadow: 0 0 12px var(--hc), 0 0 30px color-mix(in srgb, var(--hc) 70%, transparent);
}
.lb-by { margin-top: 12px; color: var(--muted); font-size: 14px; }
.lb-by b { color: var(--text); font-size: 16px; }
.lb-you {
  display: inline-block; font-size: 9.5px; font-weight: 800; letter-spacing: .14em;
  text-transform: uppercase; padding: 2px 7px; border-radius: 999px; vertical-align: 2px;
  color: var(--bg); background: var(--accent);
}
.lb-chips { display: flex; flex-wrap: wrap; justify-content: center; gap: 6px; margin-top: 12px; }
.lb-chip {
  --cc: var(--accent);
  font-size: 11.5px; font-weight: 700; padding: 4px 10px; border-radius: 999px;
  color: var(--cc); border: 1px solid color-mix(in srgb, var(--cc) 55%, transparent);
  background: color-mix(in srgb, var(--cc) 12%, transparent);
  text-shadow: 0 0 10px color-mix(in srgb, var(--cc) 55%, transparent);
  max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.lb-chip.plain { color: var(--muted); border-color: var(--line); background: rgba(255,255,255,.03); text-shadow: none; }
.lb-foot { margin-top: 12px; color: var(--dim); font-size: 12px; }
.lb-hero .board-window { margin: 6px 0 0; font-size: 11.5px; }

.lb-list { display: grid; gap: 8px; }
.lb-row {
  --rc: var(--accent);
  display: grid; grid-template-columns: 38px minmax(0,1fr) auto; grid-template-rows: auto auto;
  column-gap: 12px; row-gap: 2px; align-items: center;
  padding: 11px 12px; border-radius: 12px;
  border: 1px solid var(--line); background: rgba(255,255,255,.02);
}
.lb-rank {
  grid-row: 1 / 3; text-align: center; font-family: var(--display); font-weight: 700;
  font-size: 15px; color: var(--dim);
}
.lb-row:nth-child(-n+2) .lb-rank { font-size: 24px; }
.lb-main { grid-row: 1 / 3; display: grid; gap: 3px; min-width: 0; }
.lb-name {
  display: flex; align-items: baseline; gap: 7px; flex-wrap: wrap;
  font-weight: 800; font-size: 15px; color: var(--rc);
  text-shadow: 0 0 12px color-mix(in srgb, var(--rc) 45%, transparent);
}
.lb-vtag {
  --cc: var(--accent);
  font-size: 9px; font-weight: 800; letter-spacing: .13em; text-transform: uppercase;
  color: var(--cc); text-shadow: 0 0 8px color-mix(in srgb, var(--cc) 60%, transparent);
}
.lb-sub {
  font-size: 12px; color: var(--muted); font-style: italic;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.lb-when { font-style: normal; color: var(--dim); }
.lb-box {
  justify-self: end; font-family: var(--mono); font-weight: 800; font-size: 16px; color: #fff;
  padding: 5px 12px; border-radius: 9px; white-space: nowrap;
  border: 1.5px solid color-mix(in srgb, var(--rc) 70%, transparent);
  background: color-mix(in srgb, var(--rc) 10%, var(--bg));
  box-shadow: 0 0 16px -6px var(--rc);
  text-shadow: 0 0 10px color-mix(in srgb, var(--rc) 80%, transparent);
}
.lb-side { justify-self: end; font-size: 11px; color: var(--dim); white-space: nowrap; }
.lb-row.me, .lb-hero.me {
  border-color: color-mix(in srgb, var(--accent) 70%, transparent);
  box-shadow: 0 0 22px -10px var(--accent), inset 0 0 30px -18px var(--accent);
}
.lb-alone { text-align: center; }

@media (max-width: 520px) {
  .lb-row { grid-template-columns: 30px minmax(0,1fr) auto; column-gap: 9px; padding: 10px 9px; }
  .lb-box { font-size: 14px; padding: 4px 9px; }
  .lb-bigbox { padding: 10px 16px; }
}

/* The tab strip scrolls sideways, and a flex child with overflow set may shrink
   to zero height. On a long board (Weekly and up) the list squeezed the tabs out
   of sight. Head and tabs keep their height; only the body shrinks and scrolls. */
.lb-card .modal-head, .lb-card .board-tabs { flex-shrink: 0; }
.lb-card .board-body { flex: 1 1 auto; min-height: 0; }

/* One fixed size for every window: a short Daily board and a long All Time
   board open the same panel, and switching tabs never resizes it. */
.modal-card.lb-card { height: min(90vh, 820px); max-height: none; }

/* ─── board recap (2026-09-25) ─── the run in one line, plus the best room,
   the toughest kill and the best find, each in its own tier's colour. */
.lb-story { margin-top: 12px; font-size: 12.5px; color: var(--muted); }
.lb-story b { color: var(--text); font-weight: 700; }
.lb-bests { display: grid; grid-template-columns: repeat(3, minmax(0,1fr)); gap: 8px; margin-top: 10px; text-align: left; }
.lb-best {
  --cc: var(--accent);
  display: grid; gap: 2px; min-width: 0; padding: 8px 10px; border-radius: 10px;
  border: 1px solid color-mix(in srgb, var(--cc) 45%, var(--line));
  background: color-mix(in srgb, var(--cc) 8%, transparent);
}
.lb-best.none { --cc: var(--line2); opacity: .6; }
.lb-best-l { font-size: 9.5px; font-weight: 800; letter-spacing: .14em; text-transform: uppercase; color: var(--dim); }
.lb-best-t {
  font-size: 12px; font-weight: 800; color: var(--cc);
  text-shadow: 0 0 10px color-mix(in srgb, var(--cc) 60%, transparent);
}
.lb-best-n { font-size: 12px; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lb-minis { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 3px; min-width: 0; }
.lb-mini {
  --cc: var(--accent);
  font-size: 10.5px; font-weight: 700; color: var(--cc); padding: 1px 7px; border-radius: 999px;
  border: 1px solid color-mix(in srgb, var(--cc) 45%, transparent);
  background: color-mix(in srgb, var(--cc) 9%, transparent);
  max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.lb-mini i { font-style: normal; color: var(--dim); font-weight: 600; }
.lb-row .lb-sub { font-style: normal; }
@media (max-width: 520px) {
  .lb-bests { grid-template-columns: 1fr; }
}

/* ─── three ways in (2026-09-25) ─── Discord and Google in their own brand
   colours, then "or use email", then the code form. */
.provider-logins { display: grid; gap: 9px; margin-bottom: 4px; }
.btn.oauth {
  display: block; text-align: center; text-decoration: none; font-weight: 700;
  padding: 11px 14px; border-radius: 10px; border: 1px solid transparent;
}
.btn.oauth-discord { background: #5865f2; color: #fff; box-shadow: 0 0 22px -8px #5865f2; }
.btn.oauth-discord:hover { background: #4752c4; }
.btn.oauth-google { background: #fff; color: #1f1f1f; border-color: #dadce0; }
.btn.oauth-google:hover { background: #f1f3f4; }
.login-or {
  display: flex; align-items: center; gap: 10px; margin: 16px 0 12px;
  color: var(--dim); font-size: 11.5px; letter-spacing: .12em; text-transform: uppercase;
}
.login-or::before, .login-or::after { content: ""; flex: 1; height: 1px; background: var(--line); }
.turnstile:empty { display: none; }
.turnstile { display: flex; justify-content: center; min-height: 0; }

/* Provider marks + wording (2026-09-25): "Connect with Discord" in blurple with
   the white mark and a soft duotone bloom, "Sign in with Google" on white with
   the four-colour G - brand colours kept, our radius, weight and glow. */
.btn.oauth {
  display: flex; align-items: center; justify-content: center; gap: 11px;
  font-size: 14.5px; padding: 12px 16px; border-radius: 12px;
  transition: transform .15s ease, box-shadow .2s ease, background .2s ease;
}
.btn.oauth:hover { transform: translateY(-1px); }
.btn.oauth:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.oauth-ico { width: 20px; height: 20px; flex: none; }
.btn.oauth-discord {
  background: linear-gradient(180deg, #6571f6, #5865f2);
  box-shadow: 0 0 0 1px rgba(255,255,255,.08) inset, 0 0 24px -8px #5865f2, 0 0 40px -18px var(--accent2);
}
.btn.oauth-discord:hover { background: linear-gradient(180deg, #5c68f3, #4752c4); box-shadow: 0 0 0 1px rgba(255,255,255,.1) inset, 0 0 30px -6px #5865f2; }
.btn.oauth-google { background: #fff; color: #1f1f1f; border-color: #dadce0; box-shadow: 0 0 22px -12px #fff; }
.btn.oauth-google:hover { background: #f5f6f7; box-shadow: 0 0 28px -10px #fff; }
@media (prefers-reduced-motion: reduce) { .btn.oauth, .btn.oauth:hover { transition: none; transform: none; } }

/* the EXP each best paid (same numbers as the share card's Best line) */
.lb-best-x { font-family: var(--mono); font-size: 11px; font-weight: 700; color: var(--muted); }
.lb-mini b { font-family: var(--mono); font-weight: 700; color: var(--text); opacity: .85; }

/* ─── the privacy page (2026-09-25) ─── a plain reading column on the same
   backdrop; no biome, so it uses the default accents from :root. */
.legal { max-width: 680px; margin: 0 auto; padding: 40px 16px 64px; line-height: 1.6; }
.legal .wordmark { margin: 14px 0 6px; }
.legal-back { color: var(--muted); text-decoration: none; font-size: 13px; }
.legal-back:hover { color: var(--text); }
.legal-lead { color: var(--text); font-size: 16px; margin: 10px 0 4px; }
.legal section {
  margin-top: 22px; padding: 18px 20px; border-radius: var(--r);
  background: var(--panel); border: 1px solid var(--line);
}
.legal h2 {
  margin: 0 0 8px; font-family: var(--display); font-size: 15px; letter-spacing: .08em;
  text-transform: uppercase; color: #fff;
  text-shadow: 0 0 16px color-mix(in srgb, var(--accent) 55%, transparent);
}
.legal ul { margin: 0; padding-left: 20px; }
.legal li { margin: 6px 0; color: var(--muted); }
.legal li b { color: var(--text); }
.legal p { margin: 6px 0; color: var(--muted); }
.legal a { color: var(--accent); }

/* the small link row under the login card and at the foot of the game */
.site-foot { text-align: center; margin: 22px 0 28px; font-size: 12px; }
.site-foot a { color: var(--dim); text-decoration: none; }
.site-foot a:hover { color: var(--text); text-decoration: underline; }

/* ─── the about page (2026-09-25) ─── same reading column as the privacy page,
   plus the two live tables: every row takes its tier / verdict colour as --tc. */
.about-steps { margin: 4px 0 0; padding-left: 20px; color: var(--muted); }
.about-steps li { margin: 8px 0; }
.about-steps b, .legal p b { color: var(--text); }
.about-table { display: grid; gap: 6px; margin: 10px 0 6px; }
.about-row {
  --tc: var(--accent);
  display: grid; grid-template-columns: 26px 118px minmax(0,1fr); gap: 10px; align-items: baseline;
  padding: 8px 12px; border-radius: 10px;
  border: 1px solid color-mix(in srgb, var(--tc) 35%, var(--line));
  background: color-mix(in srgb, var(--tc) 7%, transparent);
}
#verdictTable .about-row { grid-template-columns: 118px 92px minmax(0,1fr); }
.about-sq { font-size: 15px; }
.about-name {
  font-weight: 800; color: var(--tc);
  text-shadow: 0 0 10px color-mix(in srgb, var(--tc) 55%, transparent);
}
.about-band { font-family: var(--mono); font-size: 12px; color: var(--text); }
.about-note { font-size: 12.5px; color: var(--muted); }
@media (max-width: 520px) {
  .about-row, #verdictTable .about-row { grid-template-columns: 26px 1fr; }
  #verdictTable .about-row { grid-template-columns: 1fr auto; }
  .about-note { grid-column: 1 / -1; }
}

/* ─── the changelog (2026-09-25) ─── one card per date, newest first */
.log-day h2 { font-family: var(--mono); letter-spacing: .04em; text-transform: none; }

/* ─── settings (2026-09-25) ─── the cog, and the Account / Danger zone panel */
.icon-btn { display: inline-flex; align-items: center; justify-content: center; padding: 6px 9px; }
.ico { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; flex: none; }
.set-card { max-width: 520px; }
.set-body { padding: 18px 20px 22px; overflow-y: auto; }
.set-h { margin: 4px 0 12px; font-size: 17px; font-weight: 800; letter-spacing: .06em; text-transform: uppercase; color: var(--text); }
.set-h.danger { margin-top: 30px; color: #ff9b9b; }
.set-btn {
  display: inline-flex; align-items: center; gap: 10px; padding: 10px 16px; border-radius: 10px;
  font-weight: 800; letter-spacing: .05em; text-transform: uppercase; font-size: 13px;
  background: rgba(255,255,255,.04); color: var(--muted); border: 1px solid var(--line2);
}
.set-btn:hover { color: var(--text); border-color: var(--muted); }
.danger-row { display: grid; grid-template-columns: minmax(0,1fr) auto; gap: 16px; align-items: center; }
.danger-title { font-weight: 800; letter-spacing: .04em; text-transform: uppercase; font-size: 14px; color: var(--text); }
.danger-text { margin: 4px 0 0; color: var(--muted); font-size: 14px; }
.danger-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 9px; padding: 10px 16px; border-radius: 10px;
  font-weight: 800; letter-spacing: .05em; text-transform: uppercase; font-size: 13px; white-space: nowrap;
  background: #2a0b12; color: #ff5b6b; border: 1px solid #6b1d28;
}
.danger-btn:hover:not(:disabled) { background: #3a0e18; box-shadow: 0 0 20px -8px #ff5b6b; }
.danger-btn:disabled { opacity: .45; cursor: not-allowed; }
.delete-confirm { margin-top: 16px; padding: 14px; border-radius: 10px; border: 1px solid #6b1d28; background: rgba(255,91,107,.05); }
.delete-confirm p { margin: 0 0 10px; color: var(--muted); font-size: 13.5px; }
.delete-confirm p b { color: #ff5b6b; }
.delete-confirm input {
  width: 100%; box-sizing: border-box; padding: 10px 12px; border-radius: 8px; font: inherit; letter-spacing: .1em;
  background: var(--bg); color: var(--text); border: 1px solid var(--line2);
}
.delete-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 10px; }
@media (max-width: 520px) { .danger-row { grid-template-columns: 1fr; } }

/* ─── the top bar on every page (2026-09-25) ─── the name is a link home, and
   on the side pages the buttons are links, so they must not look like links. */
a.home-link { text-decoration: none; cursor: pointer; }
a.home-link:hover { filter: drop-shadow(0 0 14px color-mix(in srgb, var(--accent) 80%, transparent)); }
.topbar a.btn { text-decoration: none; display: inline-flex; align-items: center; }
.legal { padding-top: 24px; }

/* ─── the feed (2026-09-25) ─── your own past delves, one compact card each;
   the card takes its verdict's colour as --vc. */
.feed { margin-top: 28px; }

/* ─── THE BESTIARY (2026-09-29) ─── per-biome tabs, completion pills, a rarity
   table, then chips grouped by rarity. --tc is the tier colour (from the
   server's legend, as everywhere), --bc a biome's own hue on its tab. */
.bestiary { margin-top: 28px; }
.bz-tabs { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 14px; }
.bz-tab {
  font: inherit; font-size: 13px; letter-spacing: .04em; cursor: pointer;
  padding: 8px 14px; border-radius: 999px; color: var(--muted);
  background: rgba(255,255,255,.03); border: 1px solid var(--line);
}
.bz-tab.on { color: #fff; border-color: color-mix(in srgb, var(--bc) 70%, var(--line)); box-shadow: 0 0 18px -6px var(--bc); }
.bz-pills { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 12px; }
.bz-pill { font-size: 13px; padding: 7px 12px; border-radius: 10px; border: 1px solid var(--line); background: rgba(255,255,255,.03); color: var(--muted); }
.bz-pill b { color: #fff; font-family: var(--mono, monospace); } .bz-pill i { font-style: normal; color: var(--dim); }
.bz-pill.done { border-color: color-mix(in srgb, var(--accent) 60%, var(--line)); color: var(--accent); }
.bz-stats { display: flex; gap: 6px 16px; flex-wrap: wrap; font-size: 13px; color: var(--muted); margin-bottom: 14px; }
.bz-stats b { color: var(--text); font-family: var(--mono, monospace); }
.bz-table { width: 100%; border-collapse: collapse; font-size: 13px; margin-bottom: 18px; }
.bz-table th { text-align: right; font-weight: 500; color: var(--dim); font-size: 11px; letter-spacing: .08em; text-transform: uppercase; padding: 6px 8px; border-bottom: 1px solid var(--line); }
.bz-table th:first-child, .bz-table td:first-child { text-align: left; }
.bz-table td { text-align: right; padding: 6px 8px; border-bottom: 1px solid var(--line); font-family: var(--mono, monospace); color: var(--muted); }
.bz-table td.bz-t { font-family: inherit; color: var(--tc); font-weight: 600; }
.bz-section { margin: 6px 0 14px; border: 1px solid var(--line); border-radius: 12px; background: rgba(255,255,255,.02); }
.bz-section > summary { cursor: pointer; list-style: none; display: flex; align-items: baseline; gap: 10px; padding: 12px 14px; }
.bz-section > summary .bz-sec-count { margin-left: auto; }
.bz-section summary::-webkit-details-marker, .bz-group summary::-webkit-details-marker { display: none; }
/* the chevron that says "this folds": points right when closed, down when open */
.bz-chev { display: inline-block; width: 7px; height: 7px; border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor; transform: rotate(-45deg); transition: transform .15s; opacity: .6; margin-right: 2px; }
details[open] > summary > .bz-chev { transform: rotate(45deg); }
.bz-group > summary { cursor: pointer; list-style: none; }
.bz-sec-title { font-family: var(--display); font-size: 14px; letter-spacing: .12em; text-transform: uppercase; color: #fff; }
.bz-sec-count { font-family: var(--mono, monospace); font-size: 13px; color: var(--muted); }
.bz-group { padding: 0 14px 12px; }
.bz-group-h { font-size: 12px; letter-spacing: .06em; text-transform: uppercase; color: var(--tc); margin: 4px 0 8px; display: flex; align-items: center; gap: 8px; }
.bz-group-h i { font-style: normal; color: var(--dim); margin-left: 6px; }
.bz-grid { display: flex; flex-wrap: wrap; gap: 6px; }
.bz-chip {
  display: inline-flex; align-items: baseline; gap: 8px; max-width: 100%;
  padding: 5px 10px; border-radius: 8px; font-size: 13px;
  border: 1px solid color-mix(in srgb, var(--tc) 45%, var(--line));
  background: color-mix(in srgb, var(--tc) 10%, transparent);
}
.bz-chip .bz-name { color: var(--text); min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bz-chip .bz-n { color: var(--muted); font-size: 11.5px; white-space: nowrap; }
.bz-chip.locked { border-style: dashed; background: transparent; opacity: .6; min-width: 34px; justify-content: center; }
.bz-chip.locked .bz-name { color: var(--tc); }
.bz-chip.retired { opacity: .7; }
.bz-chip.prismatic { border-color: rgba(255,255,255,.4); }
.feed-title {
  margin: 0 0 12px; font-family: var(--display); font-size: 16px; letter-spacing: .12em;
  text-transform: uppercase; color: #fff;
  text-shadow: 0 0 16px color-mix(in srgb, var(--accent) 55%, transparent);
}
.feed-list { display: grid; gap: 12px; }
.feed-card {
  --vc: var(--accent);
  padding: 14px 16px; border-radius: 14px; background: var(--panel);
  border: 1px solid color-mix(in srgb, var(--vc) 38%, var(--line));
  box-shadow: 0 0 26px -18px var(--vc);
}
.fc-head { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.fc-verdict {
  font-size: 11px; font-weight: 800; letter-spacing: .14em; text-transform: uppercase; color: var(--vc);
  text-shadow: 0 0 10px color-mix(in srgb, var(--vc) 65%, transparent);
}
.fc-label { font-size: 12px; color: var(--muted); }
.fc-when { margin-left: auto; font-size: 12px; color: var(--dim); }
/* the biome a run was played in (rotation, 2026-09-29) */
.fc-biome, .lb-biome { font-size: 12px; color: var(--dim); white-space: nowrap; }
.fc-main { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; margin: 6px 0 8px; }
.fc-exp {
  font-family: var(--mono); font-weight: 800; font-size: 26px; color: #fff;
  text-shadow: 0 0 12px color-mix(in srgb, var(--vc) 70%, transparent);
}
.fc-exp small { font-size: 12px; color: var(--muted); font-weight: 700; }
.fc-stats { font-size: 12.5px; color: var(--muted); }
.fc-grid { font-size: 13px; line-height: 1.35; letter-spacing: 1px; margin-bottom: 6px; overflow-wrap: anywhere; }
.fc-story { margin: 4px 0 2px; font-size: 12.5px; color: var(--muted); }
.fc-toggle {
  margin-top: 10px; padding: 6px 12px; border-radius: 8px; cursor: pointer; font: inherit; font-size: 12px; font-weight: 700;
  background: transparent; color: var(--muted); border: 1px solid var(--line2);
}
.fc-toggle:hover { color: var(--text); border-color: var(--muted); }
.fc-toggle:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.fc-log { margin-top: 10px; display: grid; gap: 4px; }
.feed-status { text-align: center; margin: 14px 0 0; }
.feed-more { display: block; margin: 10px auto 0; }
.feed-sentinel { height: 1px; }

/* "Your Delves", to the left of the name in the top bar (2026-09-25) */
.brand { align-items: center; }
.nav-link {
  font-size: 12.5px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
  color: var(--muted); text-decoration: none; padding: 5px 10px; border-radius: 8px;
  border: 1px solid var(--line); white-space: nowrap;
}
.nav-link:hover { color: var(--text); border-color: var(--line2); }
.nav-link:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
#feed { scroll-margin-top: 80px; }

/* ⚠️ `display: grid` above beats the browser's own [hidden] rule, so without
   this the full log could never close (and its empty box showed before opening).
   Any element that is toggled with `hidden` and also given a display needs it. */
.fc-log[hidden], .feed[hidden] { display: none !important; }

/* Your Delves is its own page now (2026-09-25): the link sits after the name,
   and shows as current on /delves. */
.nav-link.on { color: var(--text); border-color: color-mix(in srgb, var(--accent) 60%, var(--line)); }
#delvesView .feed { margin-top: 8px; }
#delvesView .feed-title { font-size: 20px; }

/* About: odds instead of descriptions (2026-09-25) - two or three columns, no note */
.about-row { grid-template-columns: 26px 130px minmax(0,1fr); }
#verdictTable .about-row { grid-template-columns: 130px minmax(0,1fr); }
.about-band { font-family: var(--mono); font-size: 12.5px; color: var(--text); }
@media (max-width: 520px) {
  .about-row { grid-template-columns: 26px 1fr auto; }
  #verdictTable .about-row { grid-template-columns: 1fr auto; }
}

/* Settings: the Display Name, read-only (2026-09-25) */
.set-field { display: grid; gap: 3px; margin: 0 0 14px; }
.set-label { font-size: 11px; font-weight: 800; letter-spacing: .12em; text-transform: uppercase; color: var(--dim); }
.set-value { font-size: 17px; font-weight: 800; color: var(--text); overflow-wrap: anywhere; }

/* ─── the live result card (2026-09-25) ─── it rides above the log for the
   whole delve: a pulsing "Delving - room N" where the verdict will land, tiles
   that climb, haul chips that pop in, and a NEW BEST badge the moment the record
   falls. The real verdict arrives with a flourish when the reveal finishes. */
.verdict.verdict-live { --vc: var(--accent); animation: livePulse 1.6s ease-in-out infinite; }
@keyframes livePulse { 0%,100% { opacity: .75; } 50% { opacity: 1; } }
.summary:not(.live) .verdict { animation: verdictIn .7s cubic-bezier(.2,.9,.3,1.25) both; }
@keyframes verdictIn { 0% { transform: scale(.6); opacity: 0; filter: blur(4px); } 60% { transform: scale(1.08); opacity: 1; filter: none; } 100% { transform: scale(1); } }
.drop-chip.fresh { animation: chipIn .55s cubic-bezier(.2,.9,.3,1.3) both; }
@keyframes chipIn { 0% { transform: translateY(-8px) scale(.7); opacity: 0; } 100% { transform: none; opacity: 1; } }
.stat.beat { border-color: color-mix(in srgb, var(--accent) 70%, var(--line)); box-shadow: 0 0 24px -8px var(--accent); position: relative; }
.stat.beat::after {
  content: "NEW BEST"; position: absolute; top: 8px; right: 10px;
  font-size: 9.5px; font-weight: 800; letter-spacing: .14em; padding: 2px 6px; border-radius: 999px;
  color: var(--bg); background: var(--accent);
}
.summary.live .summary-grid strong { transition: color .2s; }
@media (prefers-reduced-motion: reduce) {
  .verdict.verdict-live, .summary:not(.live) .verdict, .drop-chip.fresh { animation: none; }
}

/* ─── the share card takes the full width (owner, 2026-09-25) ─── the Copy
   button sits INSIDE the card, bottom-right, beside the short site-link line
   that always ends the card, so it never covers the text. */
.share { display: block; position: relative; }
.share-card { width: 100%; min-width: 0; padding-bottom: 20px; }
.share #copyShare {
  position: absolute; right: 12px; bottom: 12px;
  background: color-mix(in srgb, var(--panel) 85%, transparent);
  backdrop-filter: blur(4px);
}
@media (max-width: 520px) {
  .share-card { padding-bottom: 54px; }        /* narrow screens: the button gets its own strip */
}

/* Copy button: TOP-right of the share card (owner, 2026-09-25). The card's
   first line is the short header, so on desktop the button sits clear of it;
   narrow screens give it its own strip at the top instead. */
.share-card { padding-bottom: 15px; }
.share #copyShare { top: 12px; bottom: auto; }
@media (max-width: 520px) {
  .share-card { padding-top: 54px; padding-bottom: 15px; }
}

/* ─── REST MODE (2026-09-27) ─── players leave the tab open for hours, and the
   decorative loops (the drifting aurora, the banner sheen, the Delve pulse, the
   breathing wordmark, prismatic shimmer) kept the GPU busy the whole time. After
   60 s with no mouse / key / touch / scroll, or the moment the tab is hidden,
   app.js and site.js put `dd-rest` on <html> and every animation pauses where it
   is; any input wakes them. A delve being revealed counts as activity, so the
   page never rests mid-run. */
html.dd-rest *, html.dd-rest *::before, html.dd-rest *::after { animation-play-state: paused !important; }

/* ═══════════════════════════════════════════════════════════════════════════
   RESPONSIVE (2026-09-29) - phones and small tablets. Owner: "certain stuff is
   too big and sometimes pushes out causing an x axis issue ... dont make any
   changes to desktop view".

   Every rule here is either behind a max-width media query or a min-width: 0
   that only takes effect when content would otherwise be forced wider than
   its column - so desktop renders byte-identical (proved by a pixel comparison
   of 24 desktop screenshots before and after).

   The two causes of sideways scrolling, both measured in a headless phone:
   1. The login card. "Dungeondle" at 38px cannot wrap, so the card's
      min-content is ~357px and it overflows any screen under 393px.
   2. Your Delves. A feed card is a grid item (min-width: auto), so a nowrap
      best-drop chip ("find Legendary The Sound Rope From ... +677") set the
      column width instead of being ellipsized.
   ═══════════════════════════════════════════════════════════════════════════ */

/* a grid item may shrink below its longest unbreakable child (the chip itself
   already has overflow: hidden, so it needed nothing; its ANCESTORS did) */
.feed, .feed-card { min-width: 0; }
.feed-list { grid-template-columns: minmax(0, 1fr); }

@media (max-width: 640px) {
  /* the login gate fits any phone: the card may shrink (min-width: 0 is the
     whole fix - it keeps its 392px cap), and the wordmark scales with the
     screen (38px at 432px and up, never under 21px) while every theme keeps
     its own letter-spacing. svh, not dvh: dvh grows when the browser toolbar
     collapses mid-scroll and the centred card would slide with it. */
  .gate { padding: 20px 14px; min-height: 100svh; }
  .gate-card { min-width: 0; padding: 30px 20px 26px; }
  .gate .gate-card .wordmark { font-size: clamp(21px, 8.8vw, 38px); }
  .gate .gate-card .tagline { margin-bottom: 22px; }

  /* the NEW BEST tag sat on top of the "BEST EVER" label once the summary
     grid dropped to two columns; it now rides the card's top edge */
  .stat.beat::after { top: -7px; right: 10px; }

  /* modals keep a little more room on a small screen */
  .modal { padding: 12px; }
}

@media (max-width: 520px) {
  /* drop chips: the name wraps INSIDE the pill instead of pushing the EXP onto
     a third line, so a long Legendary is two lines, not a fat blob */
  .drop-chip { flex-wrap: nowrap; gap: 7px; padding: 5px 10px; }
  .drop-chip .dc-tier, .drop-chip .dc-exp { flex: none; }
  .drop-chip .dc-name { flex: 1 1 auto; min-width: 0; overflow-wrap: anywhere; }

  /* the delve summary: a little tighter so four stats read as one block */
  .summary-grid { gap: 10px; }
  .stat { padding: 11px 12px; }
  .stat strong { font-size: 24px; }

  /* the share card's mono text: a few more characters per line */
  .share-card { font-size: 12px; padding-left: 14px; padding-right: 14px; }

  /* Your Delves: the timestamp takes its own line rather than squeezing the
     verdict, and the big EXP steps down a notch */
  .fc-when { flex-basis: 100%; margin-left: 0; }
  .fc-exp { font-size: 23px; }
}

@media (max-width: 360px) {
  .biome-banner { padding: 16px 16px; gap: 14px; }
  .biome-emoji { font-size: 38px; }
  .biome-banner h2 { font-size: 21px; }
  .btn.delve { font-size: 19px; letter-spacing: .14em; padding: 18px 26px; }
  .modal-head { padding: 14px 15px; }
  .modal-head h3 { font-size: 15px; }
}

/* ─── second pass (2026-09-29): what a screenshot review of all six themes at
   320 / 375 / landscape found. Same rule as above: phones and small tablets
   only, desktop stays byte-identical. ─── */

@media (max-width: 640px) {
  /* tap targets: every small button and pill is at least 36 CSS px tall */
  .btn.small, .nav-link { min-height: 36px; box-sizing: border-box; }
  .nav-link { display: inline-flex; align-items: center; }
  .streak-tag { padding: 7px 12px; }
  .site-foot a { display: inline-block; padding: 6px 4px; }
}

@media (max-width: 520px) {
  /* THE ROOM LINE. Its right-hand cluster (hp change + multiplier + gain) left
     a few characters for the room name. The multiplier is context, not a
     result, and the opened room repeats it ("room 17 - x2.18 - 17/100 hp"),
     so on a phone it leaves the collapsed line; the rarity word goes back to
     its desktop size, which the freed width pays for. */
  .ev-row .rs-mult { display: none; }
  .rs-tier { font-size: 9.5px; letter-spacing: .13em; }

  /* inside an opened room: award labels wrap instead of ending in "...", and
     "hits for 11" never breaks between the words and the number */
  .award .a-label { white-space: normal; overflow: visible; }
  .round .r-what { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }

  /* chips that carry a whole item name: multi-line ones are rounded boxes
     (a 999px radius on a three-line pill curved into its own text) */
  .drop-chip { border-radius: 16px; padding: 5px 12px; }

  /* the tiny recap pills (Your Delves cards, leaderboard rows, the hero card):
     the ellipsis used to eat the EXP value, the one number that matters */
  .lb-mini, .lb-chip, .lb-best-n { white-space: normal; overflow: visible; text-overflow: clip; }

  /* the leaderboard's five window tabs wrap into two rows instead of scrolling
     off the edge with no hint that ALL TIME exists */
  .lb-card .board-tabs { flex-wrap: wrap; overflow: visible; padding: 0 8px; }
  .lb-card .tab { flex: 1 1 auto; padding: 10px 8px 9px; font-size: 10.5px; letter-spacing: .1em; }

  /* the leaderboard's big number: shrinks to stay on ONE line ("1,946,398"
     used to break after the 9 at 320px); 12,200,000 still fits at 320 */
  .lb-bigbox { padding: 10px 14px; }
  .lb-bignum { font-size: clamp(24px, 8.4vw, 56px); overflow-wrap: normal; white-space: nowrap; }

  /* the verdict pill keeps "Top 5.4%" on one line beside the verdict */
  .verdict .verdict-pct { white-space: nowrap; }

  /* the summary stats: a seven-digit best ("1,946,398") was wider than its
     half of the grid at 320px and pushed the whole page column 4px past the
     screen. The columns can no longer grow, and the number steps down with the
     screen (24px at 375px and up, ~20px at 320px). */
  .summary-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .stat { min-width: 0; }
  .stat strong { font-size: clamp(18px, 6.4vw, 24px); overflow-wrap: anywhere; }

  /* the static pages' title (ABOUT / CHANGELOG / PRIVACY) scales like the login
     wordmark instead of running edge to edge */
  .legal .wordmark { font-size: clamp(24px, 8vw, 38px); }
}

@media (max-width: 360px) {
  /* the header was three rows at 320px with YOUR DELVES alone on one of them;
     a smaller wordmark and a tighter link put the brand back on one row */
  .topbar { padding: 10px 14px; gap: 8px 10px; }
  .brand { gap: 10px; }
  .wordmark.small { font-size: 16px; letter-spacing: .1em; }
  .nav-link { font-size: 10px; padding: 4px 8px; letter-spacing: .08em; }
  .topbar-right { gap: 8px; }
  .streak-tag { font-size: 11.5px; padding: 6px 10px; }
  .verdict { gap: 9px; padding: 8px 14px; }
  .verdict .verdict-name { font-size: 17px; }
}

/* LANDSCAPE PHONES (any width, under 500px tall): the header stops being
   sticky (it took 15% of the screen and scrolled content ghosted through it),
   the login card slims down so the email step is not below the fold, and the
   leaderboard's hero card leaves room for ranked rows underneath it. */
@media (max-height: 500px) and (max-width: 900px) {
  .topbar { position: static; }
  .gate { min-height: 0; padding: 12px 14px; }
  .gate-card { padding: 18px 20px 16px; }
  .gate .gate-card .wordmark { font-size: 26px; }
  .gate .gate-card .tagline { margin: 4px 0 12px; }
  .provider-logins { gap: 6px; }
  .btn.oauth { padding: 9px 14px; }
  .login-or { margin: 10px 0 8px; }
  .modal-card { max-height: 92vh; }
  .modal-card.lb-card { height: min(94vh, 820px); }
  .lb-hero { padding: 12px 12px 10px; margin-bottom: 10px; }
  .lb-hero-label { margin-bottom: 6px; }
  .lb-bigbox { padding: 8px 18px; }
  .lb-bignum { font-size: clamp(28px, 7vw, 40px); }
  .lb-by { margin-top: 6px; }
  .lb-chips { margin-top: 8px; }
}
