/*
 * The Grim Recapper.
 *
 * Frosted glass over a void, lit by two sources: blood crimson from the left,
 * soul-fire violet from the right. Structure and typography come from the
 * Discord bot's tomestone card so the two feel like one product, but the gold
 * is gone -- gold reads like treasure, and this is a ledger of the dead.
 *
 * Playfair Display is self-hosted and portraits are proxied, so the page makes
 * no third-party requests at all.
 */

@font-face {
  font-family: 'Playfair Display';
  src: url('/fonts/PlayfairDisplay.ttf') format('truetype');
  font-weight: 400 900;
  font-display: swap;
}

:root {
  color-scheme: dark;

  /* true black, faint blue in the shadows */
  --void: #04060a;
  --onyx: #090d12;
  --onyx-2: #10161c;

  /* bone */
  --plat: #e6efe9;
  --mute: #8fa39a;
  --faint: #5c6b64;

  /* soul-fire: the primary accent, and the thing that makes it a reaper site */
  --soul: #00ffa3;
  --soul-mid: #00c47e;
  --soul-deep: #016b47;
  --soul-dim: rgba(0, 255, 163, 0.12);

  /* cold steel, the second voice */
  --steel: #86b4d6;
  --steel-dim: rgba(134, 180, 214, 0.12);

  /* blood is now reserved for one job only: blame */
  --blood: #ff3355;
  --blood-lit: #ff6f88;
  --blood-deep: #8e0f2a;
  --ember: #c4183c;

  --tank: #5c98ec;
  --healer: #60d28e;
  --dps: #ec5462;

  --neon-green: #00ffa3;
  --neon-blue: #86b4d6;
  --neon-purple: #86b4d6;

  --glass: rgba(255, 255, 255, 0.045);
  --glass-line: rgba(0, 255, 163, 0.22);
  --glass-line-soft: rgba(255, 255, 255, 0.08);

  --serif: 'Playfair Display', 'Iowan Old Style', Georgia, serif;
  --sans: 'Inter', system-ui, -apple-system, 'Segoe UI', sans-serif;

  --r-lg: 18px;
  --r-md: 12px;
  --r-pill: 999px;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  padding: 0 22px 90px;
  color: var(--plat);
  font: 15.5px/1.65 var(--sans);
  background-color: var(--void);
  /* two contained light sources rather than a flat field */
  background-image:
    radial-gradient(920px 540px at 10% -170px, rgba(255, 46, 79, 0.30), transparent 66%),
    radial-gradient(760px 460px at 90% -130px, rgba(177, 74, 255, 0.20), transparent 68%),
    radial-gradient(1200px 760px at 50% 118%, rgba(142, 15, 42, 0.22), transparent 66%);
  background-attachment: fixed;
  min-height: 100vh;
}

main, .masthead, footer { max-width: 960px; margin-inline: auto; }

/* ---- masthead ---- */

.masthead {
  display: flex;
  align-items: center;
  gap: 22px;
  padding: 46px 4px 26px;
  position: relative;
}
.masthead::after {
  content: '';
  position: absolute;
  left: 4px; right: 4px; bottom: 0;
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--ember), transparent);
  opacity: 0.55;
}
.mascot {
  flex: none;
  animation: bob 5s ease-in-out infinite;
  filter: drop-shadow(0 8px 26px rgba(142, 15, 42, 0.55));
}
@keyframes bob {
  0%, 100% { transform: translateY(0) rotate(-1.5deg); }
  50%      { transform: translateY(-7px) rotate(1.5deg); }
}

h1 {
  margin: 0;
  font-family: var(--serif);
  font-size: 44px;
  font-weight: 700;
  letter-spacing: 0.005em;
  line-height: 1.02;
  background: linear-gradient(178deg, #ffffff 0%, #cfffec 30%, var(--soul) 66%, var(--soul-deep) 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
.tagline { margin: 9px 0 0; color: var(--mute); font-size: 15px; }

/* ---- frosted glass ---- */

.panel {
  position: relative;
  background: var(--glass);
  backdrop-filter: blur(18px) saturate(130%);
  -webkit-backdrop-filter: blur(18px) saturate(130%);
  border: 1px solid var(--glass-line-soft);
  border-radius: var(--r-lg);
  padding: 26px 28px;
  margin-bottom: 18px;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.06),
    0 20px 50px -30px rgba(0, 0, 0, 0.9);
  animation: rise 0.45s cubic-bezier(0.2, 0.7, 0.3, 1) both;
}
/* a hairline of blood along the top edge, like the card */
.panel::before {
  content: '';
  position: absolute;
  inset: 0 0 auto 0;
  height: 1px;
  border-radius: var(--r-lg) var(--r-lg) 0 0;
  background: linear-gradient(90deg, transparent, var(--glass-line), transparent);
}
@keyframes rise {
  from { opacity: 0; transform: translateY(12px); }
  to   { opacity: 1; transform: none; }
}

h2 {
  margin: 0 0 4px;
  font-family: var(--serif);
  font-size: 30px;
  font-weight: 700;
  letter-spacing: 0.01em;
}
h3 {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0 0 14px;
  font: 700 11.5px/1 var(--sans);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--soul);
}
h3::before {
  content: '';
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--soul);
  box-shadow: 0 0 10px 2px var(--soul), 0 0 22px 6px rgba(0, 255, 163, 0.35);
}

.hint { color: var(--mute); font-size: 14px; margin: 12px 0 0; max-width: 68ch; }
.hint b { color: var(--plat); font-weight: 600; }
.hidden { display: none; }

/* ---- inputs ---- */

label {
  display: block;
  font: 600 10.5px/1 var(--sans);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--faint);
  margin-bottom: 12px;
}
.row { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.row.end { justify-content: flex-end; margin-top: 20px; }

input[type='text'], select {
  padding: 13px 18px;
  border: 1px solid var(--glass-line-soft);
  border-radius: var(--r-pill);
  background: rgba(0, 0, 0, 0.32);
  color: var(--plat);
  font: 15px/1.3 var(--sans);
  transition: border-color 0.16s ease, box-shadow 0.16s ease;
}
input[type='text'] { flex: 1 1 200px; min-width: 0; }
select { flex: 0 1 auto; cursor: pointer; }
select.narrow { max-width: 190px; }
option, optgroup { background: var(--onyx); color: var(--plat); }
input[type='text']::placeholder { color: var(--faint); }
input[type='text']:focus, select:focus {
  outline: none;
  border-color: var(--soul-mid);
  box-shadow: 0 0 0 3px rgba(0, 255, 163, 0.16), 0 0 18px -6px var(--soul);
}

button {
  padding: 13px 24px;
  border: 1px solid var(--glass-line);
  border-radius: var(--r-pill);
  background: rgba(255, 255, 255, 0.04);
  color: var(--plat);
  font: 600 13px/1 var(--sans);
  letter-spacing: 0.02em;
  cursor: pointer;
  transition: transform 0.14s cubic-bezier(0.2, 0.7, 0.3, 1), box-shadow 0.14s ease, background 0.14s ease;
}
button:hover { transform: translateY(-2px); background: rgba(255, 255, 255, 0.08); }
button:active { transform: translateY(0); }
button.primary {
  background: linear-gradient(180deg, var(--soul) 0%, var(--soul-mid) 100%);
  border-color: transparent;
  color: #032018;
  font-weight: 700;
  box-shadow: 0 8px 26px -10px var(--soul), inset 0 1px 0 rgba(255, 255, 255, 0.35);
}
button.primary:hover { filter: brightness(1.07); }
button.ghost { background: transparent; border-color: transparent; color: var(--mute); }
button[disabled] { opacity: 0.4; cursor: default; transform: none; }

/* ---- tabs ---- */

.tabs { display: flex; gap: 6px; margin-bottom: 22px; }
.tab {
  padding: 9px 18px;
  border: 1px solid transparent;
  border-radius: var(--r-pill);
  background: transparent;
  color: var(--faint);
  font: 600 12.5px/1 var(--sans);
  letter-spacing: 0.04em;
}
.tab:hover { background: rgba(255, 255, 255, 0.05); transform: none; color: var(--plat); }
.tab.active {
  color: var(--soul);
  border-color: rgba(0, 255, 163, 0.35);
  background: var(--soul-dim);
  box-shadow: inset 0 0 20px -8px var(--soul), 0 0 18px -10px var(--soul);
}

.inline-range { display: inline-flex; align-items: center; vertical-align: middle; margin-left: 8px; }
.inline-range input[type='range'] { width: 130px; accent-color: var(--blood); }

/* ---- portrait ---- */

.profile { display: flex; align-items: center; gap: 22px; }
.portrait-ring {
  flex: none;
  width: 104px; height: 104px;
  border-radius: 50%;
  padding: 3px;
  background: conic-gradient(from 210deg, var(--soul), var(--steel), var(--soul-deep), var(--soul));
  box-shadow: 0 0 26px -6px rgba(255, 46, 79, 0.55);
}
.portrait-ring img,
.portrait-ring .placeholder {
  width: 100%; height: 100%;
  border-radius: 50%;
  object-fit: cover;
  background: var(--onyx-2);
  display: grid;
  place-items: center;
  font-family: var(--serif);
  font-size: 34px;
  color: var(--ember);
}

/* ---- stat blocks ---- */

.plan-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: 10px; }
.plan-cell, .stats > div, .funnel-step {
  background: rgba(0, 0, 0, 0.3);
  border: 1px solid var(--glass-line-soft);
  border-radius: var(--r-md);
  padding: 15px 17px;
  color: var(--mute);
  font: 500 11px/1.4 var(--sans);
  letter-spacing: 0.03em;
}
.plan-cell:last-child { border-color: var(--glass-line); }
.plan-cell b, .stats b, .funnel-step b {
  display: block;
  font-family: var(--serif);
  font-size: 30px;
  font-weight: 700;
  line-height: 1.1;
  color: var(--plat);
  font-variant-numeric: tabular-nums;
  margin-bottom: 3px;
}
.plan-cell:last-child b { color: var(--blood); }
.plan-cell span { display: block; }

.stats { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 18px; }
.stats > div { flex: 1 1 150px; }

.funnel { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }
.funnel-step { flex: 1 1 140px; }
.funnel-step.dropped { background: transparent; border-style: dashed; }
.funnel-step.dropped b { color: var(--faint); }

/* ---- progress ---- */

.progress-label { color: var(--mute); font-size: 14px; }
.bar { height: 6px; background: rgba(0, 0, 0, 0.45); border-radius: var(--r-pill); overflow: hidden; margin-top: 14px; }
.bar-fill {
  height: 100%; width: 0;
  border-radius: var(--r-pill);
  background: linear-gradient(90deg, var(--soul-deep), var(--soul));
  box-shadow: 0 0 14px rgba(255, 46, 79, 0.5);
  transition: width 0.35s cubic-bezier(0.2, 0.7, 0.3, 1);
}

.error { border-color: var(--blood-deep); background: rgba(142, 15, 42, 0.16); }

.notice {
  background: var(--steel-dim);
  border-color: rgba(134, 180, 214, 0.26);
  font-size: 14px;
  padding: 16px 22px;
}
.notice b { color: var(--plat); }
.notice span { color: var(--mute); }

/* ---- tables ---- */

table { width: 100%; border-collapse: separate; border-spacing: 0; margin-top: 6px; }
th {
  text-align: left;
  padding: 0 12px 11px;
  color: var(--faint);
  font: 700 10px/1 var(--sans);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  white-space: nowrap;
}
td { padding: 13px 12px; border-top: 1px solid rgba(255, 255, 255, 0.06); vertical-align: middle; }
tbody tr { transition: background 0.14s ease; }
tbody tr:hover { background: rgba(255, 255, 255, 0.035); }
td.num { text-align: center; }

.name { font-family: var(--serif); font-size: 18px; font-weight: 600; line-height: 1.25; color: var(--plat); }
.job {
  display: inline-block;
  padding: 3px 11px;
  border-radius: var(--r-pill);
  background: var(--steel-dim);
  border: 1px solid rgba(134, 180, 214, 0.32);
  color: var(--steel);
  font: 700 10.5px/1.6 var(--sans);
  letter-spacing: 0.06em;
}

.badge {
  display: inline-block;
  min-width: 32px;
  padding: 5px 10px;
  border-radius: var(--r-pill);
  font: 700 14px/1.35 var(--sans);
  font-variant-numeric: tabular-nums;
}
.badge-root {
  background: rgba(142, 15, 42, 0.32);
  border: 1px solid var(--blood-lit);
  color: #ffb3bd;
  box-shadow: 0 0 16px -6px var(--blood-lit);
}
.badge-cascade { background: rgba(255, 255, 255, 0.05); border: 1px solid var(--glass-line-soft); color: var(--mute); }
.badge-amb { background: var(--steel-dim); border: 1px solid rgba(134, 180, 214, 0.35); color: var(--steel); }
.badge-none { color: var(--faint); font-weight: 500; }

.chip {
  display: inline-block;
  padding: 3px 10px;
  border-radius: var(--r-pill);
  font: 700 10px/1.6 var(--sans);
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
.chip-root { background: rgba(142, 15, 42, 0.28); border: 1px solid var(--blood-lit); color: #ffb3bd; }
.chip-unattributed { background: var(--steel-dim); border: 1px solid rgba(134, 180, 214, 0.3); color: var(--steel); }
.chip-cascade { background: rgba(255, 255, 255, 0.05); border: 1px solid var(--glass-line-soft); color: var(--mute); }

.c-certain { color: #ffb3bd; }
.c-likely { color: var(--soul); }
.c-ambiguous { color: var(--steel); }
.faded { opacity: 0.5; }

.rules { color: var(--mute); font: 400 12.5px/1.8 var(--sans); }
.rules span { margin-right: 12px; white-space: nowrap; }
.roles { color: var(--faint); font: 400 12px/1.5 var(--sans); margin-top: 3px; }

.meter {
  display: inline-block;
  width: 90px; height: 6px;
  border-radius: var(--r-pill);
  background: rgba(0, 0, 0, 0.45);
  overflow: hidden;
  vertical-align: middle;
  margin-right: 9px;
}
.meter i {
  display: block; height: 100%;
  border-radius: var(--r-pill);
  background: linear-gradient(90deg, var(--blood-deep), var(--blood), var(--soul));
}
.rate { font: 600 12.5px/1 var(--sans); color: var(--mute); font-variant-numeric: tabular-nums; }

tbody tr.subject { background: var(--soul-dim); }
tbody tr.subject:hover { background: rgba(0, 255, 163, 0.16); }
tbody tr.subject td { border-top-color: var(--glass-line); }

/* ---- pull entries ---- */

.pulls { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
.pull {
  padding: 8px 13px;
  border-radius: var(--r-pill);
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid var(--glass-line-soft);
  font: 500 12.5px/1.3 var(--sans);
  font-variant-numeric: tabular-nums;
  color: var(--mute);
  cursor: default;
  transition: transform 0.12s ease;
}
.pull:hover { transform: translateY(-2px); }
.pull.kill { background: var(--soul-dim); border-color: rgba(0, 255, 163, 0.45); color: var(--soul); font-weight: 700; }
.pull.fatal { background: rgba(142, 15, 42, 0.22); border-color: var(--blood-lit); color: #ffb3bd; }
.pull.clean { opacity: 0.5; }

footer { margin-top: 40px; color: var(--faint); font-size: 13px; text-align: center; }
footer a { color: var(--soul-mid); }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
}

@media (max-width: 640px) {
  body { padding-inline: 15px; }
  .masthead { padding: 28px 0 20px; gap: 14px; }
  .mascot { width: 64px; height: 64px; }
  h1 { font-size: 31px; }
  .panel { padding: 20px 18px; }
  .profile { gap: 15px; }
  .portrait-ring { width: 76px; height: 76px; }
  select.narrow { max-width: none; flex: 1 1 45%; }
  th, td { padding-inline: 8px; }
}


/* A slow bleed across the masthead rule -- the only motion above the fold. */
.masthead::after {
  background: linear-gradient(90deg, transparent, var(--soul), var(--steel), transparent);
  opacity: 0.7;
  animation: bleed 9s ease-in-out infinite;
}
@keyframes bleed {
  0%, 100% { opacity: 0.45; }
  50%      { opacity: 0.85; }
}

/* Findings that pin someone get a faint pulse, so the eye lands on blame. */
.badge-root {
  animation: pulse 3.2s ease-in-out infinite;
}
@keyframes pulse {
  0%, 100% { box-shadow: 0 0 16px -6px var(--blood-lit); }
  50%      { box-shadow: 0 0 22px -3px var(--blood); }
}

/* ---- texture ----------------------------------------------------------
   A flat gradient reads as a slide deck. Three cheap layers fix that:
   fine grain over everything, a vignette to pull the eye inward, and slow
   drifting embers so the page feels alive without asking for attention.
   All CSS/SVG -- no image requests, nothing to load.
------------------------------------------------------------------------ */

body::before {
  content: '';
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 0;
  /* fractal noise, tiled small so it reads as grain rather than pattern */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='0.42'/%3E%3C/svg%3E");
  opacity: 0.16;
  mix-blend-mode: overlay;
}

body::after {
  content: '';
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 0;
  background: radial-gradient(125% 95% at 50% 42%, transparent 46%, rgba(0, 0, 0, 0.72) 100%);
}

main, .masthead, footer { position: relative; z-index: 1; }

/* drifting embers */
.embers {
  position: fixed;
  inset: 0;
  pointer-events: none;
  overflow: hidden;
  z-index: 0;
}
.ember {
  position: absolute;
  bottom: -20px;
  width: 3px; height: 3px;
  border-radius: 50%;
  background: var(--soul);
  box-shadow: 0 0 8px 2px rgba(0, 255, 163, 0.7);
  opacity: 0;
  will-change: transform;
  animation: drift linear infinite;
}
.ember.soul {
  background: var(--steel);
  box-shadow: 0 0 8px 2px rgba(134, 180, 214, 0.6);
}
@keyframes drift {
  0%   { transform: translateY(0) translateX(0) scale(0.6); opacity: 0; }
  12%  { opacity: 0.85; }
  70%  { opacity: 0.5; }
  100% { transform: translateY(-104vh) translateX(var(--sway, 24px)) scale(1.1); opacity: 0; }
}

/* Panels sit above the grain and catch a little of the glow behind them. */
.panel { z-index: 1; }
.panel:hover { border-color: rgba(255, 255, 255, 0.13); }

/* The mascot gets its own bleed of light. */
.mascot { filter: drop-shadow(0 10px 30px rgba(0, 255, 163, 0.42)); }

@media (prefers-reduced-motion: reduce) {
  .embers { display: none; }
}

/* ---- wordmark ---------------------------------------------------------
   Playfair is a fine reading serif and a boring logo. Cinzel Decorative has
   the flourished, engraved-fantasy feel the name is asking for.
------------------------------------------------------------------------ */

@font-face {
  font-family: 'Cinzel Decorative';
  src: url('/fonts/CinzelDecorative-Bold.ttf') format('truetype');
  font-weight: 700;
  font-display: swap;
}

h1 {
  font-family: 'Cinzel Decorative', 'Playfair Display', Georgia, serif;
  font-size: 46px;
  letter-spacing: 0.02em;
  line-height: 1.12;
  filter: drop-shadow(0 2px 20px rgba(0, 255, 163, 0.4));
}

/* ---- aura -------------------------------------------------------------
   Two slow counter-rotating blooms behind everything. Big, blurred and
   barely moving, so it reads as energy in the room rather than animation
   demanding attention.
------------------------------------------------------------------------ */

.aura {
  position: fixed;
  inset: -30vmax;
  z-index: 0;
  pointer-events: none;
  opacity: 0.9;
  contain: strict;
}
.aura i {
  position: absolute;
  display: block;
  border-radius: 50%;
  will-change: transform;
  transform: translateZ(0);
}
.aura i:nth-child(1) {
  width: 76vmax; height: 76vmax;
  left: -10vmax; top: -14vmax;
  background: radial-gradient(circle at 50% 50%, rgba(0, 255, 163, 0.20), rgba(0, 255, 163, 0.06) 42%, transparent 68%);
  animation: swirl 48s linear infinite;
}
.aura i:nth-child(2) {
  width: 64vmax; height: 64vmax;
  right: -12vmax; top: -6vmax;
  background: radial-gradient(circle at 50% 50%, rgba(134, 180, 214, 0.16), transparent 66%);
  animation: swirl 72s linear infinite reverse;
}
.aura i:nth-child(3) {
  width: 88vmax; height: 88vmax;
  left: 8vmax; bottom: -34vmax;
  background: radial-gradient(circle at 50% 50%, rgba(1, 107, 71, 0.34), transparent 70%);
  animation: swirl 96s linear infinite;
}
@keyframes swirl {
  from { transform: translate3d(0, 0, 0) rotate(0deg); }
  to   { transform: translate3d(0, 0, 0) rotate(360deg); }
}
  50%  { transform: rotate(180deg) scale(1.12); }
  100% { transform: rotate(360deg) scale(1); }
}

/* the body glow is now the aura's job, so the static one steps back */
body { background-image: none; }

@media (prefers-reduced-motion: reduce) {
  .aura i { animation: none; }
}


/* ---- the pull-count slider ----
   It sets how deep the search goes, so it deserves to look like a dial rather
   than a browser default. Neon track, glowing thumb.
------------------------------------------------------------------------ */

.inline-range input[type='range'] {
  -webkit-appearance: none;
  appearance: none;
  width: 150px;
  height: 6px;
  border-radius: var(--r-pill);
  background: linear-gradient(90deg, var(--soul-deep), var(--soul));
  box-shadow: 0 0 12px -2px var(--soul), inset 0 0 4px rgba(0, 0, 0, 0.6);
  outline: none;
  cursor: pointer;
}
.inline-range input[type='range']::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 18px; height: 18px;
  border-radius: 50%;
  background: #eafff6;
  border: 2px solid var(--soul);
  box-shadow: 0 0 10px 2px var(--soul), 0 0 22px 6px rgba(0, 255, 163, 0.45);
  transition: transform 0.12s ease, box-shadow 0.12s ease;
}
.inline-range input[type='range']::-webkit-slider-thumb:hover {
  transform: scale(1.15);
  box-shadow: 0 0 14px 3px var(--soul), 0 0 30px 10px rgba(0, 255, 163, 0.55);
}
.inline-range input[type='range']::-moz-range-thumb {
  width: 16px; height: 16px;
  border-radius: 50%;
  background: #eafff6;
  border: 2px solid var(--soul);
  box-shadow: 0 0 10px 2px var(--soul);
}
.inline-range input[type='range']::-moz-range-track {
  height: 6px;
  border-radius: var(--r-pill);
  background: linear-gradient(90deg, var(--soul-deep), var(--soul));
}
#limit-label {
  color: var(--soul);
  font-weight: 700;
  text-shadow: 0 0 10px rgba(0, 255, 163, 0.6);
}

/* the pull-count control reads as one unit */
.limit-row {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
  margin-top: 16px;
  padding: 12px 16px;
  border: 1px solid var(--glass-line-soft);
  border-radius: var(--r-pill);
  background: rgba(0, 0, 0, 0.28);
  width: fit-content;
}
.limit-label {
  font: 600 10.5px/1 var(--sans);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--faint);
}
.limit-hint { font: 500 11.5px/1 var(--sans); color: var(--faint); }
.inline-range { margin-left: 0; }
input[type='number'] {
  width: 84px;
  padding: 9px 12px;
  border: 1px solid rgba(0, 255, 163, 0.3);
  border-radius: var(--r-pill);
  background: rgba(0, 0, 0, 0.4);
  color: var(--soul);
  font: 700 15px/1 var(--sans);
  font-variant-numeric: tabular-nums;
  text-align: center;
  text-shadow: 0 0 10px rgba(0, 255, 163, 0.5);
}
input[type='number']:focus {
  outline: none;
  border-color: var(--soul);
  box-shadow: 0 0 0 3px rgba(0, 255, 163, 0.16), 0 0 18px -6px var(--soul);
}

/* ---- high-shine glass -------------------------------------------------
   The coverage notice is the first thing read, so it gets the real glass
   treatment: heavier blur, a lit rim, and a specular sweep across the top.
------------------------------------------------------------------------ */

.notice {
  position: relative;
  overflow: hidden;
  background:
    linear-gradient(135deg, rgba(255, 255, 255, 0.14) 0%, rgba(255, 255, 255, 0.05) 34%, rgba(255, 255, 255, 0.02) 60%),
    var(--steel-dim);
  backdrop-filter: blur(26px) saturate(180%) brightness(1.1);
  -webkit-backdrop-filter: blur(26px) saturate(180%) brightness(1.1);
  border: 1px solid rgba(255, 255, 255, 0.22);
  border-radius: var(--r-lg);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.5),
    inset 0 -1px 0 rgba(255, 255, 255, 0.08),
    inset 0 0 40px rgba(0, 255, 163, 0.07),
    0 22px 54px -30px rgba(0, 0, 0, 1);
}
/* the specular highlight: a hard sheen across the upper edge */
.notice::after {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(112deg,
    transparent 0%,
    rgba(255, 255, 255, 0.16) 38%,
    rgba(255, 255, 255, 0.38) 46%,
    rgba(255, 255, 255, 0.10) 54%,
    transparent 78%);
  transform: translateX(-120%);
  animation: sheen 7.5s ease-in-out infinite;
}
@keyframes sheen {
  0%, 62% { transform: translateX(-120%); }
  84%     { transform: translateX(120%); }
  100%    { transform: translateX(120%); }
}
/* a curved glare in the top-left corner, the way real glass catches light */
.notice::before {
  content: '';
  position: absolute;
  left: -10%;
  top: -140%;
  width: 60%;
  height: 220%;
  pointer-events: none;
  background: radial-gradient(50% 50% at 50% 50%, rgba(255, 255, 255, 0.20), transparent 70%);
  transform: rotate(-18deg);
}

@media (prefers-reduced-motion: reduce) {
  .notice::after { animation: none; }
}

/* ---- two-column result -------------------------------------------------
   The findings were stacking down a centred column with dead space either
   side. The profile becomes a sticky card in that space instead, so the
   portrait stays visible while you read the mechanics beside it.
   Tomestone-card furniture -- framed portrait, engraved rules, stat rows --
   lit with the reaper green rather than gold.
------------------------------------------------------------------------ */

.result-grid {
  display: grid;
  grid-template-columns: 300px minmax(0, 1fr);
  gap: 18px;
  align-items: start;
}
.result-main { min-width: 0; }
.result-main > .panel:first-child { margin-top: 0; }

.profile-card {
  position: sticky;
  top: 22px;
  padding: 24px 22px 34px;
  text-align: center;
  overflow: hidden;
  border-color: rgba(255, 255, 255, 0.2);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.45),
    inset 0 -1px 0 rgba(255, 255, 255, 0.07),
    inset 0 0 40px rgba(0, 255, 163, 0.06),
    0 22px 54px -30px rgba(0, 0, 0, 1);
  /* the frost itself lives in the memory-diet section at the end of this
     file, which is where blur is granted or revoked per panel */
}
/* a soul-fire wash behind the card, contained by the panel's own rounding */
.profile-card::after {
  content: '';
  position: absolute;
  left: 50%;
  top: -40%;
  width: 150%;
  height: 90%;
  transform: translateX(-50%);
  pointer-events: none;
  background: radial-gradient(50% 50% at 50% 50%, rgba(0, 255, 163, 0.16), transparent 70%);
}

.portrait-frame {
  position: relative;
  width: 172px;
  height: 172px;
  margin: 4px auto 16px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  isolation: isolate;
  background: radial-gradient(circle at 50% 30%, var(--onyx-2), var(--void));
  border: 2px solid rgba(0, 255, 163, 0.4);
  box-shadow:
    0 0 0 1px rgba(0, 0, 0, 0.8),
    0 0 34px -6px rgba(0, 255, 163, 0.55),
    inset 0 0 30px rgba(0, 0, 0, 0.9);
  overflow: hidden;
}
.portrait-frame img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 18%;
  filter: saturate(1.05) contrast(1.05);
}
/* rotating halo, so the frame reads as lit rather than printed */
.portrait-glow {
  position: absolute;
  inset: -30%;
  z-index: -1;
  background: conic-gradient(from 0deg, transparent 0deg, rgba(0, 255, 163, 0.5) 70deg, transparent 150deg, transparent 210deg, rgba(134, 180, 214, 0.35) 280deg, transparent 350deg);
  animation: halo 14s linear infinite;
  will-change: transform;
}
@keyframes halo { to { transform: rotate(360deg); } }
.portrait-frame .placeholder {
  font-family: var(--serif);
  font-size: 62px;
  color: var(--soul-deep);
  text-shadow: 0 0 22px rgba(0, 255, 163, 0.4);
}

.profile-card h2 {
  font-size: 23px;
  line-height: 1.2;
  margin: 0 0 3px;
  text-shadow: 0 0 20px rgba(0, 255, 163, 0.25);
}
.char-world {
  font: 600 10.5px/1 var(--sans);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--soul-mid);
}

/* engraved divider, the way the card separates its blocks */
.profile-rule {
  height: 1px;
  margin: 16px 0;
  background: linear-gradient(90deg, transparent, rgba(0, 255, 163, 0.42), transparent);
  box-shadow: 0 1px 0 rgba(0, 0, 0, 0.7);
}

/* their profiles elsewhere, right under the nameplate */
.char-links {
  display: flex;
  justify-content: center;
  gap: 8px;
  margin-top: 10px;
}
.char-links:empty { display: none; }
.ext-link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 11px;
  border: 1px solid rgba(134, 180, 214, 0.3);
  border-radius: var(--r-pill);
  font: 600 10.5px/1 var(--sans);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--steel);
  text-decoration: none;
  transition: color 0.12s ease, border-color 0.12s ease, transform 0.12s ease;
}
.ext-link:hover {
  color: var(--soul);
  border-color: rgba(0, 255, 163, 0.5);
  transform: translateY(-1px);
}
.ext-link svg { flex: none; }

/* the tall Tomestone art, when they have set one -- more character on the page */
.tall-art {
  margin-top: 16px;
  border-radius: var(--r-md);
  overflow: hidden;
  border: 1px solid rgba(255, 255, 255, 0.14);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 14px 34px -22px rgba(0, 0, 0, 1);
}
.tall-art:empty { display: none; }
.tall-art img {
  display: block;
  width: 100%;
  max-height: 44vh;
  object-fit: cover;
  object-position: top center;
}

/* ---- the Recapper on patrol -------------------------------------------
   The reaper moogle walks the bottom edge of the profile card, endlessly,
   like he is guarding the ledger. The wrapper owns the patrol (position and
   the flip at each end); the image owns the waddle, so the two transforms
   never fight over one element.
------------------------------------------------------------------------- */
.moogle-walker {
  position: absolute;
  left: 16px;
  right: 16px;
  bottom: 4px;
  height: 30px;
  pointer-events: none;
}
.moogle-step {
  position: absolute;
  bottom: 0;
  width: 26px;
  height: 26px;
  animation: moogle-patrol 34s linear infinite;
}
.moogle-step img {
  width: 26px;
  height: 26px;
  filter: drop-shadow(0 3px 8px rgba(0, 255, 163, 0.35));
  animation: moogle-waddle 0.55s ease-in-out infinite;
}
@keyframes moogle-patrol {
  0%    { left: 0%; transform: scaleX(1); }
  47%   { left: calc(100% - 26px); transform: scaleX(1); }
  50%   { left: calc(100% - 26px); transform: scaleX(-1); }
  97%   { left: 0%; transform: scaleX(-1); }
  100%  { left: 0%; transform: scaleX(1); }
}
@keyframes moogle-waddle {
  0%, 100% { transform: translateY(0) rotate(-3deg); }
  50%      { transform: translateY(-2.5px) rotate(3deg); }
}
@media (prefers-reduced-motion: reduce) {
  .moogle-step, .moogle-step img { animation: none; }
}

.profile-stats { margin: 0; display: grid; gap: 2px; }
.pstat {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  padding: 7px 10px;
  border-radius: 8px;
}
.pstat:nth-child(odd) { background: rgba(255, 255, 255, 0.03); }
.pstat dt {
  font: 500 11.5px/1.3 var(--sans);
  letter-spacing: 0.04em;
  color: var(--mute);
  text-align: left;
}
.pstat dd {
  margin: 0;
  font-family: var(--serif);
  font-size: 22px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--plat);
}
.pstat.blame dd { color: var(--blood); text-shadow: 0 0 16px rgba(255, 51, 85, 0.5); }
.pstat.blame dt { color: var(--blood-lit); }

.profile-funnel { display: grid; gap: 6px; }
.profile-funnel .funnel-step {
  display: flex;
  align-items: baseline;
  gap: 9px;
  text-align: left;
  padding: 8px 11px;
}
.profile-funnel .funnel-step b {
  font-size: 17px;
  margin-bottom: 0;
  min-width: 34px;
}
.profile-funnel .funnel-step span { font-size: 10.5px; line-height: 1.35; }

@media (max-width: 900px) {
  .result-grid { grid-template-columns: 1fr; }
  .profile-card { position: static; }
  .portrait-frame { width: 132px; height: 132px; }
}

/* ---- when it went wrong ----------------------------------------------
   A total cannot separate "two rough nights" from "every week". The bars
   can, so they lead and the prose explains what the shape means.
------------------------------------------------------------------------ */

.verdict {
  padding: 16px 18px;
  border-radius: var(--r-md);
  background: rgba(0, 0, 0, 0.32);
  border-left: 3px solid var(--soul);
}
.verdict b {
  display: block;
  font-family: var(--serif);
  font-size: 19px;
  color: var(--soul);
  margin-bottom: 6px;
  text-shadow: 0 0 16px rgba(0, 255, 163, 0.35);
}
.verdict p { margin: 0; color: var(--mute); font-size: 14px; line-height: 1.6; }

.sessions {
  display: flex;
  align-items: flex-end;
  gap: 5px;
  margin-top: 18px;
  padding: 14px 12px 10px;
  border-radius: var(--r-md);
  background: rgba(0, 0, 0, 0.28);
  overflow-x: auto;
}
.session {
  flex: 1 0 30px;
  min-width: 30px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 5px;
  cursor: default;
}
.session-bar {
  width: 100%;
  height: 88px;
  display: flex;
  align-items: flex-end;
  border-radius: 5px;
  background: rgba(255, 255, 255, 0.04);
  overflow: hidden;
}
.session-bar i {
  display: block;
  width: 100%;
  border-radius: 5px 5px 0 0;
  background: linear-gradient(180deg, var(--soul), var(--soul-deep));
  transition: filter 0.14s ease;
}
/* the nights that carry the story */
.session.worst .session-bar i {
  background: linear-gradient(180deg, var(--blood), var(--blood-deep));
  box-shadow: 0 0 16px -2px var(--blood);
}
.session.clean .session-bar i { background: rgba(255, 255, 255, 0.1); }
.session:hover .session-bar i { filter: brightness(1.25); }
.session-n {
  font: 700 12px/1 var(--sans);
  font-variant-numeric: tabular-nums;
  color: var(--plat);
  min-height: 12px;
}
.session.worst .session-n { color: var(--blood-lit); }
.session-date {
  font: 500 9.5px/1 var(--sans);
  color: var(--faint);
  white-space: nowrap;
}

/* pull-history bars read as volume, so they run steel rather than blame-red */
.pulls-chart .session-bar i { background: linear-gradient(180deg, var(--steel), rgba(134, 180, 214, 0.35)); }
.pulls-chart .session.killed .session-bar i {
  background: linear-gradient(180deg, var(--soul), var(--soul-deep));
  box-shadow: 0 0 16px -2px var(--soul);
}
.pulls-chart .session.killed .session-n { color: var(--soul); }

/* Sessions the pull limit never reached. Not clean -- unknown, and they must
   not be mistaken for a night that went well. */
.session.unseen .session-bar {
  background: repeating-linear-gradient(45deg,
    rgba(255,255,255,0.05) 0 4px, transparent 4px 8px);
  border: 1px dashed rgba(255,255,255,0.14);
}
.session.unseen .session-bar i { background: transparent; }
.session.unseen .session-n { color: var(--faint); }
.session.unseen .session-date { opacity: 0.55; }

/* ---- evidence -----------------------------------------------------------
   A count nobody can check is an assertion. Clicking one opens the pulls
   behind it, each linking into the reference analyzer at that exact fight,
   so anyone disputing a number can go and look at the arena themselves.
-------------------------------------------------------------------------- */

button.evidence-toggle {
  cursor: pointer;
  transition: transform 0.12s ease, filter 0.12s ease;
  font: 700 14px/1.35 var(--sans);
  padding: 5px 11px;
}
button.evidence-toggle:hover { transform: translateY(-1px); filter: brightness(1.15); box-shadow: none; }
button.evidence-toggle.open { outline: 2px solid var(--soul); outline-offset: 2px; }

.evidence-row-holder td { padding: 0; border-top: 0; }
.evidence {
  margin: 0 0 14px;
  border: 1px solid var(--glass-line);
  border-radius: var(--r-md);
  background: rgba(0, 0, 0, 0.34);
  overflow: hidden;
}
.evidence-head {
  padding: 10px 14px;
  font: 600 11px/1.4 var(--sans);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--soul);
  border-bottom: 1px solid var(--glass-line-soft);
}
.evidence-row {
  display: grid;
  grid-template-columns: 122px 132px 1fr 62px;
  gap: 10px;
  align-items: baseline;
  padding: 9px 14px;
  border-top: 1px solid rgba(255, 255, 255, 0.05);
  color: var(--mute);
  font: 400 12.5px/1.5 var(--sans);
  text-decoration: none;
  transition: background 0.12s ease;
}
.evidence-row:first-of-type { border-top: 0; }
.evidence-row:hover { background: rgba(0, 255, 163, 0.07); }
.ev-when { color: var(--plat); font-variant-numeric: tabular-nums; }
.ev-rule { color: var(--blood-lit); font-weight: 600; }
.ev-detail { color: var(--faint); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ev-open { color: var(--soul); font-weight: 700; text-align: right; white-space: nowrap; }

@media (max-width: 760px) {
  .evidence-row { grid-template-columns: 1fr auto; }
  .ev-detail { display: none; }
}

/* a stat's qualifier -- the mechanic wall under the prog percent */
.stats .stat-sub {
  display: block;
  margin-top: 3px;
  font: 600 11px/1.35 var(--sans);
  letter-spacing: 0.02em;
  text-transform: none;
  color: var(--soul-mid);
}

/* ---- the prog point wears the reaper's light ---- */
.stats b.prog-glow {
  background: linear-gradient(180deg, #eafff6 0%, var(--soul) 55%, var(--soul-deep) 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  filter: drop-shadow(0 0 8px rgba(0, 255, 163, 0.55));
  animation: soulflicker 3.4s ease-in-out infinite;
}
@keyframes soulflicker {
  0%, 100% { filter: drop-shadow(0 0 7px rgba(0, 255, 163, 0.45)); }
  46%      { filter: drop-shadow(0 0 13px rgba(0, 255, 163, 0.8)); }
  52%      { filter: drop-shadow(0 0 9px rgba(0, 255, 163, 0.55)); }
  58%      { filter: drop-shadow(0 0 15px rgba(0, 255, 163, 0.9)); }
}

/* ---- the working scythe ----
   Spins slowly while a job runs; click it for a proper swing. */
.status-row { display: flex; align-items: center; gap: 14px; }
.scythe { flex: none; cursor: pointer; overflow: visible; outline: none; }
.scythe .scythe-g {
  transform-origin: 50px 50px;
  animation: reap 4.5s linear infinite;
  filter: drop-shadow(0 0 6px rgba(0, 255, 163, 0.35));
}
.scythe:hover .scythe-g { filter: drop-shadow(0 0 12px rgba(0, 255, 163, 0.7)); }
.scythe.frenzy .scythe-g { animation: reap 0.45s linear infinite; filter: drop-shadow(0 0 16px rgba(0, 255, 163, 0.9)); }
@keyframes reap { to { transform: rotate(360deg); } }

@media (prefers-reduced-motion: reduce) {
  .stats b.prog-glow, .scythe .scythe-g, .scythe.frenzy .scythe-g { animation: none; }
}

/* ---- memory diet --------------------------------------------------------
   The heavy costs were compositor layers, not content: a backdrop blur on
   every panel (each one forces a live-blurred copy of everything behind it),
   a full-screen blend-mode grain, and three viewport-sized animated blobs.
   The glass look survives on the coverage notice; everything else goes solid.
-------------------------------------------------------------------------- */

.panel {
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  background: rgba(13, 18, 23, 0.86);
}
.notice {
  backdrop-filter: blur(20px) saturate(160%);
  -webkit-backdrop-filter: blur(20px) saturate(160%);
}
/* The profile card is the page's centerpiece, so it gets the one extra live
   blur layer, deliberately. */
.profile-card {
  background:
    linear-gradient(135deg, rgba(255, 255, 255, 0.13) 0%, rgba(255, 255, 255, 0.05) 34%, rgba(255, 255, 255, 0.02) 60%),
    rgba(13, 18, 23, 0.68);
  backdrop-filter: blur(26px) saturate(170%) brightness(1.08);
  -webkit-backdrop-filter: blur(26px) saturate(170%) brightness(1.08);
}
body::before { mix-blend-mode: normal; opacity: 0.05; }
.aura i:nth-child(3) { display: none; }
.aura { opacity: 0.7; }
