/* ─────────────────────────────────────────────────────────────────────
   theme-pixel.css — a blocky, limited-palette retro skin that grows GRIMMER
   with depth. Selected by <html data-theme="pixel">. Most of the look is just
   the token VALUES below; only the genuinely STRUCTURAL differences (hard
   shadows, the press, uppercase, image-rendering, the scanline/grime veil)
   need rules.

   The grimness ramp keys off `--dread` (= the controller's --depth, 0 at the
   surface → 1 in the deep): the warm parchment palette darkens toward a candle-
   black and the candlelit gold accent gutters out — but stays warm throughout.
   This is the manuscript identity rendered in pixel chrome. Backdrops the player
   supplies render pixelated.
   ───────────────────────────────────────────────────────────────────────── */
:root[data-theme="pixel"] {
  --dread: var(--depth, 0); /* no-JS fallback; applyAtmosphere overrides this inline
                               with tier + in-run descent blended (0 surface → 1 deep) */

  /* ── palette: candlelit parchment + gold, darkening into the dark with depth ── */
  --bg:         color-mix(in srgb, #0c0a09, #050403 calc(var(--dread) * 60%));
  --panel:      color-mix(in srgb, #141009, #0a0705 calc(var(--dread) * 70%));
  --panel-2:    color-mix(in srgb, #0f0b07, #070504 calc(var(--dread) * 70%));
  --edge:       color-mix(in srgb, #3a2c1a, #201810 calc(var(--dread) * 58%));
  --rule:       color-mix(in srgb, #4a3a22, #281f12 calc(var(--dread) * 58%));
  --ink:        color-mix(in srgb, #ddccab, #9d8f74 calc(var(--dread) * 52%));
  --ink-bright: color-mix(in srgb, #efdcb4, #b2a384 calc(var(--dread) * 52%));
  --dim:        color-mix(in srgb, #9b8a6b, #6a5e48 calc(var(--dread) * 52%));
  --gold:       color-mix(in srgb, #c8923a, #7c5824 calc(var(--dread) * 60%)); /* candlelit gold — guttering with depth */
  --accent-lit: color-mix(in srgb, #e9c074, #997740 calc(var(--dread) * 60%));
  --accent-rgb: 200, 146, 58; /* candlelit gold glow */
  --blood:      #a8312e;
  --vital:      color-mix(in srgb, #5f7d5a, #41553e calc(var(--dread) * 52%)); /* verdigris vitality */
  --steel:      color-mix(in srgb, #8694a0, #5c666f calc(var(--dread) * 52%));

  /* ── typography: a mono face reads as pixel/terminal ── */
  --font-body: "DejaVu Sans Mono", "Liberation Mono", "Courier New", ui-monospace, monospace;

  /* ── shape: hard pixel corners everywhere ── */
  --radius: 0; --radius-sm: 0; --radius-lg: 0; --radius-round: 0;

  /* ── surfaces: aged binding + manuscript leaf ── */
  --surface-sunk:  color-mix(in srgb, #241a13, #140e09 calc(var(--dread) * 58%));
  --surface-inset: #120d0a;
  --btn-bg: #1d1611;
  --btn-primary-bg: #2a1d0e;
  --loot-bg: #1c1607;
  --loot-ink: #f0d9ad;
  --item-border: var(--edge);

  --node-bg: var(--panel);
  --node-border: var(--rule);
  --node-ink: var(--dim);
  --node-ghost-bg: var(--panel-2);
  --boss-node-bg: #2a1610;
  --boss-node-border: #9a4438;
  --rdot-bg: #3a2c1a;
  --rdot-border: #5a4733;
  --rlink: #2a2114;
  --rail-bg: linear-gradient(var(--panel), var(--panel-2));
  --ribbon-bg: linear-gradient(var(--panel), var(--panel-2));
  --ribbon-lvl-bg: var(--panel-2);
  --routemap-bg: linear-gradient(var(--panel), var(--panel-2));

  --hoard-edge: #5a4a2a;
  --card-hoard-bg: #15120a;
  --card-parley-bg: #0d1115;
}

/* ════════ structural deltas (not expressible as token values) ════════ */

/* The whole frame: a faint pixel grid + crisp upscaling. */
[data-theme="pixel"] body {
  background:
    radial-gradient(120% 80% at 50% -10%, #1c1712 0%, var(--bg) 62%),
    repeating-linear-gradient(0deg, rgba(0,0,0,0.10) 0, rgba(0,0,0,0.10) 2px, transparent 2px, transparent 4px);
  image-rendering: pixelated;
}

/* The keep's masonry BUILDS UP in the four screen corners — never a full wall.
   The drawing is procedural on a <canvas> (startMasonry in main.ts): each corner
   gets its own seed/extent so no two match, per-brick tonal jitter + a ragged
   pile edge replace the old symmetric radial mask (which read as a repeating
   "heart"), and decay — cracks, darkening, dropped bricks — rises with --dread.
   Here we only switch the layer on for the pixel skin (the one that wears stone). */
[data-theme="pixel"] .ambient.masonry { display: block; }

/* The grime/scanline veil rises with depth (hidden in the manuscript theme). */
[data-theme="pixel"] .ambient.grime {
  display: block;
  z-index: 4; /* over room/torch/deep, under blood + sparks */
  opacity: var(--dread, 0);
  mix-blend-mode: multiply;
  background:
    radial-gradient(125% 120% at 50% 32%, transparent 38%, rgba(12,9,6,0.62) 100%),
    repeating-linear-gradient(0deg, rgba(0,0,0,0.28) 0, rgba(0,0,0,0.28) 1px, transparent 1px, transparent 3px);
  transition: opacity 900ms ease;
}

/* The keep stair backdrop gets the same chunky/cooled pixel treatment as the
   foe room scenes — it's the same authored-art layer, just the place between
   fights rather than a foe. */
[data-theme="pixel"] .ambient.keep {
  image-rendering: pixelated;
  filter:
    saturate(calc(0.88 - var(--dread) * 0.55))
    brightness(calc(0.82 - var(--dread) * 0.18))
    contrast(1.28);
}

/* Backdrops go chunky + posterized, cooling harder with depth. */
[data-theme="pixel"] .ambient.room {
  image-rendering: pixelated;
  filter:
    saturate(calc(0.88 - var(--dread) * 0.55))
    brightness(calc(0.82 - var(--dread) * 0.18))
    contrast(1.28);
}

/* The dark presses in: the room vignette tightens with depth — its lit centre
   shrinks and the scrim deepens — so the playable light shrinks toward the
   panel the further you sink. */
[data-theme="pixel"] .ambient.room::after {
  background:
    radial-gradient(125% 108% at 50% 30%,
      rgba(8,8,11,0) calc(24% - var(--dread) * 15%),
      rgba(7,8,12,0.5) calc(70% - var(--dread) * 20%),
      rgba(4,5,8,0.92) 100%),
    linear-gradient(rgba(8,9,12,calc(0.34 + var(--dread) * 0.20)),
                    rgba(8,9,12,calc(0.50 + var(--dread) * 0.20)));
}

/* The torch fails: its warm glow dims and pulls in, and the flicker quickens
   into a guttering as the keep runs out of fire. (Dim via the gradient's alpha,
   not opacity — the flicker keyframes drive opacity, so they'd fight it.) */
[data-theme="pixel"] .ambient.torch {
  background: radial-gradient(120% 85% at 50% -12%,
    rgba(86, 60, 30, calc(0.5 - var(--dread) * 0.34)) 0%,
    rgba(20, 15, 11, 0) calc(55% - var(--dread) * 16%));
  animation-duration: calc(6s - var(--dread) * 3.2s);
}

/* Blocky chrome: hard 2px edges + offset solid shadows. */
[data-theme="pixel"] .panel {
  border-width: 2px;
  box-shadow: 0 0 0 2px #07090b, 7px 7px 0 rgba(0,0,0,0.55);
}
/* All buttons get the hard 2px pixel edge; the RAISED drop-shadow is OPT-IN via
   .btn (the solid "chrome" buttons), so text/icon buttons — ghost actions, the
   borderless Chronicle line, the reroll die, the subtle map/close/back buttons —
   carry no shadow without per-class opt-outs. */
[data-theme="pixel"] button { border-width: 2px; }
[data-theme="pixel"] .btn { box-shadow: 3px 3px 0 rgba(0,0,0,0.55); }
[data-theme="pixel"] button:hover:not(:disabled) { background: #2b231a; }
/* The pixel "press": a raised button slams down into its own drop-shadow. */
[data-theme="pixel"] .btn:active:not(:disabled) { transform: translate(3px, 3px); box-shadow: none; }
[data-theme="pixel"] .status { border-width: 2px; box-shadow: 4px 4px 0 rgba(0,0,0,0.5); }

/* The card/tool/item hover-lift becomes a hard pixel nudge, not a soft float. */
[data-theme="pixel"] .card:hover:not(:disabled),
[data-theme="pixel"] .tool:hover:not(:disabled),
[data-theme="pixel"] .item:hover:not(:disabled),
[data-theme="pixel"] .preset:hover:not(:disabled),
[data-theme="pixel"] .primary:hover:not(:disabled) {
  transform: translate(-2px, -2px);
  box-shadow: 5px 5px 0 rgba(0,0,0,0.5);
}
[data-theme="pixel"] .card:active:not(:disabled),
[data-theme="pixel"] .tool:active:not(:disabled),
[data-theme="pixel"] .item:active:not(:disabled),
[data-theme="pixel"] .preset:active:not(:disabled),
[data-theme="pixel"] .primary:active:not(:disabled) { transform: translate(0,0); box-shadow: 2px 2px 0 rgba(0,0,0,0.5); }

/* Headings: uppercase mono with a chunky pixel drop-bevel (small-caps reads
   poorly in a mono face). */
[data-theme="pixel"] h1 {
  font-variant: normal; text-transform: uppercase; letter-spacing: 0.16em; font-size: 30px;
  text-shadow: 2px 2px 0 #07090b, 4px 4px 0 rgba(0,0,0,0.45);
}
[data-theme="pixel"] h2 {
  font-variant: normal; text-transform: uppercase; letter-spacing: 0.1em; font-size: 17px;
  border-bottom: 2px solid var(--rule);
}

/* small-caps synthesizes poorly in a mono face — read HUD/labels as uppercase. */
[data-theme="pixel"] .descent-label,
[data-theme="pixel"] .ribbon-lvl,
[data-theme="pixel"] .foe-shape,
[data-theme="pixel"] .card-shape,
[data-theme="pixel"] .status-cue,
[data-theme="pixel"] .cs-vcap,
[data-theme="pixel"] .cs-label,
[data-theme="pixel"] .lb-cap,
[data-theme="pixel"] .lb-tab,
[data-theme="pixel"] .label,
[data-theme="pixel"] .alloc-name,
[data-theme="pixel"] .namerow label,
[data-theme="pixel"] .meta-chronicle .chronicle-link,
[data-theme="pixel"] .tool-name { font-variant: normal; text-transform: uppercase; }

/* The intro rule keeps its chunky pixel border; menace-fill and tool-odds now
   inherit the warm base defaults (candlelit gold), so no override is needed. */
[data-theme="pixel"] .intro { border-left-width: 3px; }
[data-theme="pixel"] .end.win h2 { color: var(--accent-lit); }
