/* NOTE ON TRANSITIONS
 * There are none on anything the flame drives, and that is deliberate.
 * Chromium does not reliably commit a transition whose value comes from a custom property:
 * with `transition: box-shadow` or `filter` or `border-color` in place, the property stayed
 * frozen at whatever it computed from --flame's initial 0.85 and never moved again. Only the
 * two background-driven light pools were actually animating; every piece of carving that was
 * supposed to react was silently dead. Candlelight should snap between frames anyway, so the
 * fix is simply not to transition it. */

/* Arreat Summit, not a launch page. Dark only on purpose: this is a room with two candles.
 *
 * Lighting: app.js sets --flame-l and --flame-r on :root every sprite frame, 0 to 1, taken
 * from how much fire is actually burning in that frame (measured by tools/build-candle.mjs).
 * Everything that should feel three dimensional reads those two numbers, so the carving
 * brightens and its shadows deepen in step with the flames rather than on a timer of its own.
 */
:root{
  --bg:#070605;--stone:#13100c;--stone-lo:#0b0907;--panel:#100d09;--panel-lo:#0a0806;
  --line:#2c2317;--line-2:#4a3a1e;--gold:#c9a227;--gold-lt:#e8d9a8;--gold-dim:#8a7748;
  --unique:#c7b377;--affix:#9aa2f2;--ink:#cfc6b4;--muted:#8a8275;
  --up:#7da364;--down:#b55b4e;
  --parch:#d9c9a3;--parch-lo:#bfa87c;--parch-ink:#2c2114;

  /* candle.css overrides these, written by tools/build-candle.mjs */
  --candle-w:95px;--candle-h:150px;--candle-frames:6;--candle-sheet-w:570px;
  /* live, set by app.js */
  --flame-l:.85;--flame-r:.85;--flame:.85;
}

/* grain used for stone and parchment, an SVG turbulence as a data URI */
:root{
  --grain:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  --fibre:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='f'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.028 .9' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23f)'/%3E%3C/svg%3E");
}

*{box-sizing:border-box}
/* set by app.js when the frame has been scaled to fit the window: there is nothing below
   the fold to reach, so the page should not offer to scroll to it */
html.fit,html.fit body{overflow:hidden}
html,body{margin:0;background:var(--bg);color:var(--ink);line-height:1.5;
  font-family:"EB Garamond",Georgia,"Times New Roman",serif}
/* the crest overhangs the frame top and bottom by 34 art px, so the page has to make room */
body{overflow-x:hidden;min-height:100vh;
  padding:calc(10px + var(--fs) * 26px) 16px calc(10px + var(--fs) * 26px);
  background-image:var(--grain),radial-gradient(90% 60% at 50% 0,#16110c 0,#070605 70%);
  background-size:180px 180px,100% 100%;background-blend-mode:overlay,normal}
a{color:var(--gold);text-decoration:none}
a:hover{color:var(--gold-lt)}
.hidden{display:none !important}
h1,h2,h3,.logo,.tabs,.tip-name,.tip-type,.creed,.drop,.plate-h{
  font-family:Cinzel,Georgia,"Times New Roman",serif}

/* ---------------------------------------------------------------- light */
/* Two pools, one per candle. Opacity and reach follow that candle's own flame. */
/* The broad wash on the room beyond the frame. Kept wide, weak and very soft: this is the
   ambient the candles raise, not a beam, so it should never have a discernible edge. */
.light{position:fixed;inset:0;pointer-events:none;z-index:3;mix-blend-mode:screen;
  background:
    radial-gradient(calc(520px + var(--flame-l) * 150px) calc(460px + var(--flame-l) * 130px)
      at 9% 14%, rgba(255,172,76,calc(.03 + .055 * var(--flame-l))) 0,
      rgba(255,156,58,calc(.012 + .024 * var(--flame-l))) 44%, rgba(255,140,40,0) 78%),
    radial-gradient(calc(520px + var(--flame-r) * 150px) calc(460px + var(--flame-r) * 130px)
      at 91% 14%, rgba(255,172,76,calc(.03 + .055 * var(--flame-r))) 0,
      rgba(255,156,58,calc(.012 + .024 * var(--flame-r))) 44%, rgba(255,140,40,0) 78%)}

/* ---------------------------------------------------------------- frame */
/* The frame is the real art, cut into nine parts by tools/build-frame.mjs. Corners are drawn
   at a fixed size so the skulls and shelves never distort; the edges tile along their run at
   their measured repeat. --fs scales the whole assembly, and every offset below is in art
   pixels multiplied by it, so the pieces stay locked together at any size. */
:root{--fs:1}
.frame{--c:calc(var(--fr-corner) * var(--fs) * 1px);
  position:relative;max-width:1800px;margin:0 auto;
  padding:calc(var(--fr-inset-top) * var(--fs) * 1px)
          calc(var(--fr-inset-right) * var(--fs) * 1px)
          calc(var(--fr-inset-bottom) * var(--fs) * 1px)
          calc(var(--fr-inset-left) * var(--fs) * 1px)}
/* the room behind the frame, sitting inside the stone */
/* the per-side factors put this just inside the OUTER face of each bar, which in the art
   sits at 108 / 62 / 80 / 61 px against insets of 194 / 153 / 167 / 152 */
.frame::before{content:"";position:absolute;
  inset:calc(var(--fr-inset-top) * var(--fs) * .56px) calc(var(--fr-inset-right) * var(--fs) * .4px)
        calc(var(--fr-inset-bottom) * var(--fs) * .48px) calc(var(--fr-inset-left) * var(--fs) * .4px);
  z-index:0;pointer-events:none;
  background-image:var(--grain),
    linear-gradient(180deg,#14100b 0,#0a0806 45%,#100d09 100%);
  background-size:180px 180px,100% 100%;background-blend-mode:overlay,normal;
  box-shadow:0 0 90px rgba(0,0,0,.9) inset,
    0 0 calc(30px + 40px * var(--flame)) rgba(255,150,50,calc(.04 + .06 * var(--flame))) inset}

.fr{position:absolute;pointer-events:none;z-index:1;background-repeat:no-repeat}
/* edges first, so the corners overlap their ends and hide the joins */
/* One piece corner to corner, never tiled. app.js keeps --fs exactly proportional to the
   frame's width, so this draws at 1:1 and the arcade cannot break mid-pattern. The corners
   paint over its two ends (z-index 2 against 1), which hides the joins entirely. */
.fr-top,.fr-bottom{height:var(--c);
  left:calc(var(--c) - var(--fr-bleed) * var(--fs) * 1px);
  right:calc(var(--c) - var(--fr-bleed) * var(--fs) * 1px);
  background-size:100% 100%;background-repeat:no-repeat}
.fr-left,.fr-right{top:var(--c);bottom:var(--c);width:var(--c);
  background-size:100% calc(var(--fr-side-tile) * var(--fs) * 1px);background-repeat:repeat-y}
.fr-top{top:0;background-image:url(frame/edge-top.png)}
.fr-bottom{bottom:0;background-image:url(frame/edge-bottom.png)}
.fr-left{left:0;background-image:url(frame/edge-left.png)}
.fr-right{right:0;background-image:url(frame/edge-right.png)}

.fr-c{width:var(--c);height:var(--c);background-size:100% 100%;z-index:2}
.fr-tl{top:0;left:0;background-image:url(frame/corner-tl.png)}
.fr-tr{top:0;right:0;background-image:url(frame/corner-tr.png)}
.fr-bl{bottom:0;left:0;background-image:url(frame/corner-bl.png)}
.fr-br{bottom:0;right:0;background-image:url(frame/corner-br.png)}

/* the crest cannot live in a tiled edge, so it rides on top at the middle of the run */
.fr-crest{left:50%;width:calc(var(--fr-crest-w) * var(--fs) * .42px);
  height:calc(var(--fr-crest-h) * var(--fs) * .42px);
  background-size:100% 100%;background-image:url(frame/crest.png);z-index:3}
.fr-crest-t{top:calc(var(--fs) * -34px);transform:translateX(-50%)}
.fr-crest-b{bottom:calc(var(--fs) * -34px);transform:translateX(-50%) scaleY(-1)}

/* Warm light thrown onto the stone by the candles. Screened over the carving, strongest at
   the two top corners where the flames stand, so the relief lifts as they flare. */
/* z-index 6 puts this ABOVE the candles, which sit at 5. Underneath them the glow looked
   like a spotlight aimed at the wall behind the sconce rather than light coming off the
   wick. The pools are anchored to the flame, not the shelf: --fr-shelf-y is the base of the
   candle, so lift by most of the drawn height to reach the fire.
   The falloff is deliberately long and low: a two-stop gradient has a visible edge and reads
   as a lamp being switched, where fire has no edge at all. */
.frame::after{content:"";position:absolute;inset:0;pointer-events:none;z-index:6;
  mix-blend-mode:screen;
  background:
    radial-gradient(calc(var(--c) * (.42 + .34 * var(--flame-l))) calc(var(--c) * (.38 + .3 * var(--flame-l)))
      at calc(var(--fr-shelf-cx) * var(--fs) * 1px)
         calc(var(--fr-shelf-y) * var(--fs) * 1px - var(--candle-h) * var(--fs) * .72),
      rgba(255,186,104,calc(.07 + .15 * var(--flame-l))) 0,
      rgba(255,172,82,calc(.04 + .09 * var(--flame-l))) 26%,
      rgba(255,158,62,calc(.015 + .035 * var(--flame-l))) 52%,
      rgba(255,146,48,0) 82%),
    radial-gradient(calc(var(--c) * (.42 + .34 * var(--flame-r))) calc(var(--c) * (.38 + .3 * var(--flame-r)))
      at calc(100% - var(--fr-shelf-cx) * var(--fs) * 1px)
         calc(var(--fr-shelf-y) * var(--fs) * 1px - var(--candle-h) * var(--fs) * .72),
      rgba(255,186,104,calc(.07 + .15 * var(--flame-r))) 0,
      rgba(255,172,82,calc(.04 + .09 * var(--flame-r))) 26%,
      rgba(255,158,62,calc(.015 + .035 * var(--flame-r))) 52%,
      rgba(255,146,48,0) 82%)}

/* ---------------------------------------------------------------- candles */
/* Standing on the carved shelves. The anchor is the shelf's top surface, in art pixels from
   the frame's corner, so the candles stay planted on the stone at every scale. The sprite is
   95px wide against a 104px shelf, which is why it scales with the frame rather than apart
   from it. */
/* No image-rendering:pixelated: the sheet is built nearly 3x denser than it draws, so the
   browser resolves it as painted art. Pixelating it next to the smooth stone was the loudest
   reason it read as pasted on. The drop shadow is what seats it against the carving. */
/* --f is this candle's own flame, so each side reacts to the frame it is actually showing.
   The brightness and warmth ride on it: the room was being lit while the candle itself stayed
   flat, which read as the sprite sitting outside the scene rather than in it. The light pass
   in .frame::after paints UNDER the sprite, so the candle has to light itself. */
.sconce{--f:var(--flame-l);
  position:absolute;width:var(--candle-w);height:var(--candle-h);z-index:5;
  pointer-events:none;background-image:url(candle-sheet.png);background-repeat:no-repeat;
  background-size:var(--candle-sheet-w) var(--candle-h);
  background-position:var(--sx,0) 0;transform-origin:bottom center;
  top:calc(var(--fr-shelf-y) * var(--fs) * 1px);
  filter:drop-shadow(1px 3px 3px rgba(0,0,0,.55))
         drop-shadow(0 1px 1px rgba(0,0,0,.7))
         drop-shadow(0 calc(-2px - 4px * var(--f)) calc(6px + 14px * var(--f))
           rgba(255,172,74,calc(.3 + .5 * var(--f))))
         brightness(calc(.86 + .18 * var(--f)))
         saturate(calc(.9 + .18 * var(--f)))}

/**
 * Fill light on the wax.
 *
 * brightness() multiplies, so it barely touches the dark parts: a crevice at 0.2 scaled by
 * 1.1 is still 0.22, while a highlight at 0.8 gains four times as much in absolute terms.
 * The shadowed channels between the drips and under the base therefore stayed black no
 * matter how hard the flame burned, which is not how a candle lights its own wax.
 *
 * A screen blend does the opposite: it adds roughly (1 - base), so it lifts shadows hard and
 * leaves highlights and the flame itself alone. This layer is a flat warm wash masked to the
 * sprite's own silhouette, sharing --sx with the background so the mask can never drift onto
 * a different frame.
 */
.sconce .fill{position:absolute;inset:0;z-index:3;pointer-events:none;
  background:rgba(255,178,102,calc(.03 + .21 * var(--f)));
  mix-blend-mode:screen;
  -webkit-mask-image:url(candle-sheet.png);mask-image:url(candle-sheet.png);
  -webkit-mask-size:var(--candle-sheet-w) var(--candle-h);
  mask-size:var(--candle-sheet-w) var(--candle-h);
  -webkit-mask-position:var(--sx,0) 0;mask-position:var(--sx,0) 0;
  -webkit-mask-repeat:no-repeat;mask-repeat:no-repeat}
/* No transition on that filter, deliberately. Chromium does not reliably commit a
   transition whose value comes from a custom property, and with one here the whole filter
   stayed frozen at the brightness computed from --flame-l's initial 0.85: the candle never
   lit at all. A flame should snap between frames anyway. */
/* contact shadow: the dark the wax presses into the slab it stands on. It tightens and
   darkens as the flame comes up, like a real occlusion would. */
.sconce::before{content:"";position:absolute;left:50%;bottom:-1px;z-index:-1;
  width:calc(132% - 22% * var(--f));height:13%;transform:translateX(-50%);
  border-radius:50%;
  background:radial-gradient(ellipse at center,
    rgba(0,0,0,calc(.5 + .3 * var(--f))) 0,rgba(0,0,0,.28) 48%,rgba(0,0,0,0) 72%)}
.sconce.left{left:calc(var(--fr-shelf-cx) * var(--fs) * 1px);
  transform:translate(-50%,-100%) scale(var(--fs))}
.sconce.right{--f:var(--flame-r);right:calc(var(--fr-shelf-cx) * var(--fs) * 1px);
  transform:translate(50%,-100%) scale(var(--fs)) scaleX(-1)}
/* the halo immediately around each wick */
/* The close halo on the wick. Sized off the candle so it scales with --fs, swelling with the
   flame rather than only brightening, and sitting above the sprite so the wax nearest the
   fire is the brightest part of it. Feathered over four stops for the same reason as the
   pools: an edge on a flame's glow reads as a light being switched on. */
.sconce::after{content:"";position:absolute;left:50%;top:0;z-index:2;
  width:calc(var(--candle-w) * (1.5 + 1.5 * var(--f)));
  height:calc(var(--candle-w) * (1.5 + 1.5 * var(--f)));
  transform:translate(-50%,-30%);border-radius:50%;pointer-events:none;
  background:radial-gradient(circle,
    rgba(255,196,118,calc(.08 + .16 * var(--f))) 0,
    rgba(255,178,88,calc(.045 + .1 * var(--f))) 30%,
    rgba(255,160,62,calc(.015 + .04 * var(--f))) 56%,
    rgba(255,145,45,0) 84%)}

.inner{position:relative;z-index:1;padding:10px 30px 16px;border-radius:2px;
  border:1px solid #241c12;
  background:linear-gradient(180deg,rgba(9,7,6,.94) 0,rgba(6,5,4,.97) 100%);
  box-shadow:0 0 70px rgba(0,0,0,.8) inset}

/* ---------------------------------------------------------------- chrome */
/* Centred, like the examples: the candles own the top corners, so nothing else may sit
   there. The gutter tracks --fs, because the candle's inner edge lands 116 art px into the
   content area whatever the frame is scaled to. */
.chrome{text-align:center;padding:0 calc(var(--fs) * 125px) 10px;margin-bottom:14px;
  border-bottom:1px solid rgba(201,162,39,.2);position:relative}
/* Four stops on the chrome's bottom rail, one per room: the page you are in is lit and
   takes the candles' glow, the rest are cold. They are real links, a second way through the
   same four views. The hit target is the anchor, deliberately bigger than the diamond. */
.pips{position:absolute;left:50%;bottom:-9px;transform:translateX(-50%);
  display:flex;gap:15px;z-index:3}
.pips a{display:flex;align-items:center;justify-content:center;width:19px;height:19px}
.pips span{width:9px;height:9px;transform:rotate(45deg);background:#413829;
  box-shadow:0 1px 0 rgba(0,0,0,.6)}
.pips a:hover span{background:var(--gold-dim)}
.pips a.on span{background:var(--gold);
  box-shadow:0 0 calc(4px + 8px * var(--flame)) rgba(255,170,70,calc(.5 * var(--flame)))}
.logo{display:inline-block;font-size:27px;color:var(--gold-lt);letter-spacing:.07em;
  line-height:1.15;margin-bottom:8px;
  text-shadow:0 0 calc(9px + 14px * var(--flame)) rgba(255,170,70,calc(.3 * var(--flame)))}
.tabs{display:flex;gap:4px;justify-content:center;flex-wrap:wrap}
.tabs a{position:relative;padding:7px 20px;font-size:15px;letter-spacing:.1em;
  text-transform:uppercase;color:#8d816c;border:1px solid transparent;border-radius:3px}
.tabs a:hover{color:var(--gold-lt);background:rgba(201,162,39,.05)}
.tabs a.on{color:var(--gold-lt);border-color:rgba(201,162,39,.4);
  background:linear-gradient(180deg,rgba(201,162,39,.12),rgba(201,162,39,.02));
  box-shadow:0 0 calc(7px + 9px * var(--flame)) rgba(255,170,70,calc(.16 * var(--flame))) inset}
/* The active tab had a gold underline here. It collided with the diamond rail below, and it
   was saying nothing the tab's own border, fill and inner glow do not already say. */

.ca{display:inline-flex;align-items:center;gap:8px;min-width:0;max-width:100%;margin-top:14px;
  border:1px solid var(--line-2);border-radius:4px;padding:5px 6px 5px 10px}
.ca-l{font-size:10px;letter-spacing:.18em;color:var(--gold-dim);cursor:help;
  font-family:"Segoe UI",sans-serif}
.ca-v{font-family:Consolas,"SFMono-Regular",Menlo,monospace;font-size:13px;color:var(--gold-lt);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}
.ca-copy{border:1px solid var(--line-2);background:#1b1409;color:var(--gold);font-size:11px;
  padding:4px 9px;border-radius:3px;cursor:pointer;font-family:"Segoe UI",sans-serif}
.ca-copy:hover{background:#271c0d}

/* ---------------------------------------------------------------- plates */
/* A plate is a carved stone panel. The top edge catches the candles, the bottom falls away. */
.plate{position:relative;padding:14px 18px;border-radius:3px;border:1px solid #30261a;
  background-image:var(--grain),linear-gradient(180deg,var(--panel) 0,var(--panel-lo) 100%);
  background-size:180px 180px,100% 100%;background-blend-mode:overlay,normal;
  box-shadow:
    0 1px 0 rgba(255,214,150,calc(.04 + .07 * var(--flame))) inset,
    0 -1px 0 rgba(0,0,0,.7) inset,
    0 0 0 1px rgba(201,162,39,.1) inset,
    0 10px 26px rgba(0,0,0,.55)}
.plate::before,.plate::after{content:"";position:absolute;width:11px;height:11px;
  border:1px solid rgba(201,162,39,calc(.3 + .35 * var(--flame)));pointer-events:none}
.plate::before{top:5px;left:5px;border-right:0;border-bottom:0}
.plate::after{bottom:5px;right:5px;border-left:0;border-top:0}
.plate-h{margin:0 0 10px;text-align:center;font-size:15px;letter-spacing:.2em;
  text-transform:uppercase;color:var(--gold-lt);font-weight:400}
.plate-h::after{content:"";display:block;width:62%;height:1px;margin:7px auto 0;
  background:linear-gradient(90deg,transparent,rgba(201,162,39,.55),transparent)}

/* Every room is padded out to the tallest so the frame never changes size between pages;
   centring keeps the shorter ones from sitting in a pool of empty space at the top. */
main{position:relative;display:flex;flex-direction:column;justify-content:center}
.drop{text-align:center;color:var(--gold-dim);font-size:14px;font-style:italic;
  margin:0 0 12px;letter-spacing:.03em}
/* the address rides on the same centred line, upright and monospaced so it reads as data
   rather than prose, and breaks anywhere so a 44 character mint cannot force a scrollbar */
.drop-ca{font-style:normal;font-family:Consolas,"SFMono-Regular",Menlo,monospace;
  font-size:12.5px;letter-spacing:0;overflow-wrap:anywhere}
.drop-ca a{color:var(--gold-lt)}
.drop-ca a:hover{color:#f0e2b4}
.bench{display:grid;grid-template-columns:1fr 1.08fr 1fr;gap:14px;align-items:start}
/* the stash is two panels, not three: the grid and the readout for whatever is selected */
.bench-2{grid-template-columns:370px 1fr;width:100%;max-width:900px;margin:0 auto}

/* inventory */
.inv{display:grid;gap:6px}
.inv-sm{grid-template-columns:repeat(4,1fr)}
.inv-lg{grid-template-columns:repeat(4,1fr)}
.pad,.slot{aspect-ratio:1;border-radius:2px;border:1px solid #2a2117;
  background:linear-gradient(180deg,#0c0a07 0,#070605 100%);
  box-shadow:0 1px 0 rgba(201,162,39,.05) inset,0 -1px 2px rgba(0,0,0,.6) inset}
.slot{display:flex;align-items:center;justify-content:center;position:relative;
  border-color:rgba(201,162,39,calc(.3 + .3 * var(--flame)));
  background:radial-gradient(circle at 50% 50%,
    rgba(201,162,39,calc(.1 + .1 * var(--flame))) 0,rgba(10,8,6,0) 70%),#0a0806}
/* no image-rendering:pixelated here on purpose: the sprite is downscaled into the socket,
   and nearest neighbour on a downscale just aliases the gold band. The candle is drawn 1:1,
   so it keeps it. */
.slot img{max-width:80%;max-height:80%;
  filter:drop-shadow(0 0 calc(5px + 8px * var(--flame)) rgba(201,162,39,calc(.35 + .3 * var(--flame))))}
.slot.empty img{display:none}
.slot.empty::after{content:"ring.png";position:absolute;font-size:10px;color:#4d4435;
  font-family:"Segoe UI",sans-serif;letter-spacing:.08em}
/* a slot you can choose: it lifts on hover and holds a brighter socket once chosen */
#stashGrid .slot{cursor:pointer}
#stashGrid .slot:hover{border-color:rgba(201,162,39,.75)}
#stashGrid .slot:focus-visible{outline:1px solid var(--gold);outline-offset:2px}
#stashGrid .slot.on{border-color:var(--gold);
  background:radial-gradient(circle at 50% 50%,rgba(201,162,39,.26) 0,rgba(10,8,6,0) 70%),#0d0a07;
  box-shadow:0 0 calc(5px + 9px * var(--flame)) rgba(255,170,70,calc(.3 * var(--flame))) inset}
/* the chosen token's name, above its figures */
.id-chart{margin:12px 0 0;text-align:right}
.id-chart a{font-size:12px;letter-spacing:.12em;text-transform:uppercase}
.id-name{margin:0 0 10px;text-align:center;font-size:14px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--gold-lt);font-family:Cinzel,Georgia,serif}

/* the examine */
.tip{text-align:center}
.tip-name{font-size:26px;color:var(--unique);margin:0;letter-spacing:.03em;font-weight:600;
  text-shadow:0 0 calc(9px + 13px * var(--flame)) rgba(199,179,119,calc(.3 * var(--flame)))}
.tip-type{font-size:15px;color:var(--unique);margin:3px 0 0;letter-spacing:.18em;
  text-transform:uppercase}
.tip hr{border:0;height:1px;margin:10px 0;
  background:linear-gradient(90deg,transparent,rgba(201,162,39,.32),transparent)}
.tip-stats{list-style:none;margin:0;padding:0}
.tip-stats li{color:var(--affix);font-size:15px;line-height:1.5}
.tip-stats li.tax{color:var(--gold)}
.tip-req{color:var(--ink);font-size:14.5px;margin:0}

/* identify */
.identify .idrow:first-of-type{margin-top:2px}
.identify hr{border:0;height:1px;margin:14px 0 10px;
  background:linear-gradient(90deg,transparent,rgba(201,162,39,.28),transparent)}
.idrow{display:flex;justify-content:space-between;align-items:baseline;gap:12px;
  font-size:14.5px;padding:6px 0;color:var(--ink);
  border-bottom:1px solid rgba(201,162,39,.08)}
.idrow b{color:var(--gold-lt);font-weight:500;text-align:right;word-break:break-word}
.idrow b.blank{color:#5a5040;letter-spacing:.2em;font-weight:400}
.idsub{display:flex;justify-content:space-between;gap:10px;font-size:12.5px;
  color:var(--muted);padding:3px 0;font-family:"Segoe UI",sans-serif}
.idsub b{color:var(--ink);font-weight:600}
/* the whole freshness signal, inline in the Identify heading so it costs no height */
.dot{display:inline-block;width:6px;height:6px;border-radius:50%;background:#4a443a;
  margin-left:9px;vertical-align:middle;cursor:help}
.dot.live{background:var(--up);box-shadow:0 0 6px rgba(125,163,100,.85)}
.up{color:var(--up)}
.down{color:var(--down)}
.help{border-bottom:1px dotted var(--gold-dim);cursor:help}

/* creed */
.creed{width:100%;max-width:360px;margin:14px auto 2px;text-align:center;padding:8px 20px;
  border-radius:3px;border:1px solid rgba(201,162,39,.3);
  background:linear-gradient(180deg,rgba(26,20,13,.9) 0,rgba(10,8,6,.9) 100%);
  box-shadow:0 0 calc(14px + 18px * var(--flame)) rgba(255,160,50,calc(.07 * var(--flame))) inset,
    0 8px 22px rgba(0,0,0,.5)}
.creed .flourish{display:block;font-size:16px;color:var(--gold-lt);letter-spacing:.04em}
.creed .flourish::before,.creed .flourish::after{content:"\2756";color:var(--gold-dim);
  font-size:15px;margin:0 16px;vertical-align:middle}
.creed em{display:block;font-size:12.5px;color:var(--gold);margin-top:2px}

/* ---------------------------------------------------------------- tome */
/* A real spread: two leaves tilted toward a spine with perspective, so the text lies on the
   page instead of floating over a picture of one. */
.book{position:relative;perspective:1800px;perspective-origin:50% 45%;padding:6px 0 10px;
  display:grid;grid-template-columns:1fr 1fr;max-width:1000px;margin:0 auto;
  filter:drop-shadow(0 26px 34px rgba(0,0,0,.72))}
/* the binding, sitting between the two leaves */
.book::after{content:"";position:absolute;top:6px;bottom:10px;left:50%;width:22px;
  transform:translateX(-50%);pointer-events:none;z-index:2;border-radius:2px;
  background:linear-gradient(90deg,rgba(40,27,12,.55) 0,rgba(22,14,6,.82) 48%,
    rgba(40,27,12,.55) 100%)}
/* Both leaves are one sheet of the same book, so they must end at the same height. The grid
   row already stretches them to the taller one; the page has to fill its leaf rather than
   stop at its own text, or the shorter side ends early and you see through to the room. */
.leaf{transform-style:preserve-3d;position:relative;display:flex}
/* the thickness of the sheets still to turn, on the outer edge of each leaf */
.leaf::before{content:"";position:absolute;top:10px;bottom:10px;width:9px;z-index:-1;
  background:repeating-linear-gradient(180deg,#cdbb93 0 2px,#a8906a 2px 3px);
  box-shadow:0 0 8px rgba(0,0,0,.5)}
.leaf-l::before{left:-7px;border-radius:3px 0 0 3px}
.leaf-r::before{right:-7px;border-radius:0 3px 3px 0}
.leaf-l{transform:rotateY(7deg);transform-origin:right center}
.leaf-r{transform:rotateY(-7deg);transform-origin:left center}
.page{position:relative;flex:1 1 auto;min-height:360px;padding:28px 34px 32px;overflow:hidden;
  color:var(--parch-ink);
  background-image:var(--fibre),
    radial-gradient(130% 90% at 50% 0,rgba(255,250,235,.5) 0,rgba(255,250,235,0) 60%),
    linear-gradient(180deg,#e2d4b2 0,#d7c69f 55%,#c9b68c 100%);
  background-size:220px 220px,100% 100%,100% 100%;
  background-blend-mode:soft-light,normal,normal}
.leaf-l .page{border-radius:5px 2px 2px 5px}
.leaf-r .page{border-radius:2px 5px 5px 2px}
/* the gutter: paper curving down into the spine, plus the shadow it throws */
.leaf-l .page::after,.leaf-r .page::after{content:"";position:absolute;top:0;bottom:0;
  width:78px;pointer-events:none}
.leaf-l .page::after{right:0;
  background:linear-gradient(90deg,rgba(90,66,32,0) 0,rgba(90,66,32,.1) 55%,rgba(60,42,20,.42) 100%)}
.leaf-r .page::after{left:0;
  background:linear-gradient(270deg,rgba(90,66,32,0) 0,rgba(90,66,32,.1) 55%,rgba(60,42,20,.42) 100%)}
/* foxing and the darker outer edge, so the sheet reads as a physical thing */
.page::before{content:"";position:absolute;inset:0;pointer-events:none;
  background:
    radial-gradient(60% 50% at 8% 94%,rgba(120,88,42,.2) 0,rgba(120,88,42,0) 70%),
    radial-gradient(45% 40% at 92% 6%,rgba(120,88,42,.16) 0,rgba(120,88,42,0) 70%),
    radial-gradient(120% 100% at 50% 50%,rgba(255,255,255,0) 55%,rgba(74,52,24,.3) 100%);
  mix-blend-mode:multiply}
.page h1{font-family:Cinzel,Georgia,serif;font-size:23px;color:#4a3317;margin:0 0 3px;
  text-align:center;letter-spacing:.02em;font-weight:600}
.page h2{font-family:Cinzel,Georgia,serif;font-size:14px;color:#5c4120;margin:15px 0 5px;
  letter-spacing:.07em;text-transform:none;font-weight:600}
.page p{font-size:15px;line-height:1.6;margin:0 0 9px;text-align:justify;
  hyphens:auto;text-shadow:0 1px 0 rgba(255,250,235,.35)}
.page .rule{height:1px;margin:10px auto 16px;width:58%;background:
  linear-gradient(90deg,transparent,rgba(90,64,28,.6),transparent)}
.page .closing{font-style:italic;color:#4e381b;margin-top:18px}
.folio{position:absolute;bottom:16px;left:0;right:0;text-align:center;font-size:13px;
  color:#7a5c30;font-family:Cinzel,Georgia,serif;letter-spacing:.2em}

/* ---------------------------------------------------------------- stash + vendor */
.inv-lg{max-width:none}
/* the readout and its caption share the right column, so the caption sits under what it
   describes rather than under the whole bench */
.stash-right{display:flex;flex-direction:column;gap:12px;min-width:0}
.stash-note{text-align:center;color:var(--muted);font-size:13.5px;margin:0;font-style:italic;
  line-height:1.5;text-wrap:pretty}
.vendor-plate{width:100%;max-width:820px;margin:0 auto;text-align:center}
.vlede{font-size:19.5px;color:var(--gold-lt);margin:0 0 14px;line-height:1.6}
.vlede.strong{color:var(--gold);font-style:italic}
.vendor-plate hr{border:0;height:1px;margin:22px 0;
  background:linear-gradient(90deg,transparent,rgba(201,162,39,.3),transparent)}
.vendor-plate h3{font-size:14.5px;letter-spacing:.2em;text-transform:uppercase;
  color:var(--gold-dim);margin:0 0 10px;font-weight:400}
.vbody{font-size:17.5px;color:var(--ink);margin:0;text-align:left;max-width:700px;
  margin-inline:auto}
.mono{font-family:Consolas,"SFMono-Regular",Menlo,monospace;font-size:15px;color:var(--gold-lt);
  word-break:break-all;background:#0a0907;border:1px solid var(--line);border-radius:3px;
  padding:11px;display:inline-block;max-width:100%}
.hint{font-size:12px;color:var(--muted);margin:10px 0 0;font-family:"Segoe UI",sans-serif}
.vlinks{margin:18px 0 0;display:flex;gap:20px;justify-content:center;align-items:center}
/* the X mark, lit like everything else the candles reach */
.iconlink{display:inline-flex;align-items:center;justify-content:center;
  width:34px;height:34px;border:1px solid rgba(201,162,39,.32);border-radius:4px;
  background:linear-gradient(180deg,rgba(26,20,13,.9),rgba(10,8,6,.9))}
.iconlink img{width:17px;height:17px;display:block;
  filter:drop-shadow(0 0 calc(2px + 5px * var(--flame)) rgba(255,170,70,calc(.3 * var(--flame))))}
.iconlink:hover{border-color:var(--gold);
  box-shadow:0 0 calc(5px + 9px * var(--flame)) rgba(255,170,70,calc(.25 * var(--flame))) inset}
.vlinks a{font-size:13px;letter-spacing:.14em;text-transform:uppercase}
.disclaim{font-size:11.5px;color:#6f6859;margin:22px 0 0;font-family:"Segoe UI",sans-serif}

/* ---------------------------------------------------------------- responsive */
/* One number scales the whole frame: corners, edges, insets, crest and candles all read it,
   so the assembly can never come apart. app.js sets it continuously from the frame's width,
   which is what lets the top and bottom runs be a single 1:1 piece. These steps are only a
   fallback for when scripting is off. */
@media (max-width:1300px){:root{--fs:.8}}
@media (max-width:1040px){:root{--fs:.62}}
@media (max-width:820px){:root{--fs:.46}}
@media (max-width:560px){:root{--fs:.34}}
@media (max-width:980px){
  body{padding:8px}
  .inner{padding:18px 16px 24px}
  .bench{grid-template-columns:1fr;max-width:470px;margin:0 auto}
  /* On a phone the examine and the figures carry the page and the inventory is scenery, so
     they are reordered. Scoped to the sanctuary deliberately: unscoped, `.identify{order:2}`
     also matched the stash's panel, which shares a flex column with its caption, and the
     caption at the default order 0 jumped above the panel it describes. */
  #sanctuary .tip{order:1}
  #sanctuary .identify{order:2}
  #sanctuary .bench>[aria-label="Inventory"]{order:3;max-width:330px;margin:0 auto;width:100%}
  .logo{font-size:20px}
  .tabs a{padding:6px 12px;font-size:13px}
  /* a phone cannot hold a spread, so the book becomes one page: no binding, no tilt */
  .book{grid-template-columns:1fr;perspective:none;max-width:520px}
  .book::after,.leaf::before{display:none}
  .leaf-l,.leaf-r{transform:none}
  .leaf-l .page{border-radius:5px 5px 0 0}
  .leaf-r .page{border-radius:0 0 5px 5px;min-height:0;padding-top:8px}
  .leaf-l .page::after,.leaf-r .page::after{display:none}
  .page{min-height:0;padding:26px 24px 34px}
  .inv-lg{max-width:300px}
  .bench-2{grid-template-columns:1fr;max-width:460px}
}
@media (max-width:760px){
  .logo{font-size:17px}
  .tabs a{padding:5px 9px;font-size:11.5px;letter-spacing:.08em}
}
/* app.js already pins the sprite to one frame under reduced motion, which also pins every
   flame-driven value, so there is nothing left here to switch off. */
