
/* The title splash (Title, 17-title.js; owner, 2026-10-11: "Make a title splash screen for loot forge"). It is the first thing
   on the page, before the three.js script and the other styles, so it shows while they load; its styles name their own
   colours and fonts for that reason. The LOOT FORGE letters in molten gold (a dark forged copy behind each word, data-text,
   for the outline and the depth, and a light that sweeps across now and then), the 2 on a gold coin whose ring fills with
   the loading (--p, 0 to 1, clockwise from 6 o'clock like the level ring), the chest below with light and gems in its open
   lid, and embers rising. Only small parts move (transform and opacity), and no shadow or filter covers the screen, so the
   splash costs the graphics card little (owner, 2026-10-11: a 100vmax shadow made a huge layer on an iPhone).
   Smooth while loading (owner, 2026-10-11: the embers and the light sweep stuttered while the game loaded): every moving part
   is a CSS animation or transition of transform or opacity only, so the browser's compositor runs it off the main thread
   that loading keeps busy. The light sweep is a window (ts-sh) sliding over the word with a bright copy of the letters
   inside it sliding back the other way, so the bright band stays on the letters; the rays are their own small svg whose
   opacity breathes; the ring's fill is two half windows turned by transform transitions (--a1, --a2, set in steps by
   Title.progress), each with the ring's gradient turned back inside it; the embers are few and tiny, each its own layer.
   Loading done: the status line gives way to "Tap to begin" (class ready). The tap (or Enter or Space) opens the chest, the
   splash fades and grows a little (class open) and is taken out of the page. class still (Reduce motion): no embers, light
   sweep or pulse, and a short fade. */
@property --p{syntax:"<number>";inherits:true;initial-value:0}
.title-splash{position:fixed;inset:0;z-index:900;display:flex;flex-direction:column;align-items:center;overflow:hidden;color:#e8c98a;
  --u:min(1vw,.7vh,9px);--a1:0deg;--a2:180deg;--gold:#ffd866;font-family:"Metamorphous","Cinzel",Georgia,"Times New Roman",serif;cursor:default;
  padding:env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left);
  background:radial-gradient(ellipse 70% 45% at 50% 66%,#5a2a0e 0,#2a140a 45%,transparent 75%),
    radial-gradient(ellipse 120% 70% at 50% 0,#1c1410 0,transparent 70%),linear-gradient(#0d0a08,#070504);
  -webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent}
.title-splash.ready{cursor:pointer}
.ts-stage{position:relative;flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;width:100%;padding-top:calc(4 * var(--u))}
.ts-mark{position:relative;margin:0;display:flex;flex-direction:column;align-items:center;font-weight:400;line-height:.86;text-align:center;
  animation:ts-stamp .9s cubic-bezier(.2,1.4,.4,1) .1s both}
.ts-word{position:relative;display:block;font-size:calc(22 * var(--u));letter-spacing:.03em;padding:0 .06em;color:#2a1306;-webkit-text-stroke:calc(2 * var(--u)) #1e0d04;
  text-shadow:0 calc(.5 * var(--u)) 0 #6a3410,0 var(--u) 0 #50260b,0 calc(1.6 * var(--u)) 0 #321606,0 calc(2.8 * var(--u)) calc(2 * var(--u)) rgba(0,0,0,.75)}
.ts-word.small{font-size:calc(13.5 * var(--u));letter-spacing:.26em;padding-left:.32em}
.ts-word::before{content:attr(data-text);position:absolute;inset:0;padding:inherit;color:transparent;-webkit-text-stroke:0;text-shadow:none}
.ts-word::before{background:linear-gradient(180deg,#fff8d6 8%,#ffe07a 30%,#f5b23e 50%,#a85a16 51%,#d98a2c 64%,#ffcf6e 86%,#fff0b8 100%);-webkit-background-clip:text;background-clip:text}
.ts-sh{position:absolute;inset:0;overflow:hidden;pointer-events:none;will-change:transform;transform:translateX(-110%) skewX(-15deg);
  -webkit-mask:linear-gradient(90deg,transparent 38%,#000 50%,transparent 62%);mask:linear-gradient(90deg,transparent 38%,#000 50%,transparent 62%);
  animation:ts-shine 6s ease-in-out 1.4s infinite}
.ts-sh>span{position:absolute;inset:0;padding:inherit;color:rgba(255,255,240,.9);-webkit-text-stroke:0;text-shadow:none;will-change:transform;
  transform:skewX(15deg) translateX(110%);animation:ts-shine-in 6s ease-in-out 1.4s infinite}
.ts-word>.ts-sh{padding:0}.ts-sh>span{padding:0 .06em}.ts-word.small .ts-sh>span{padding:0 0 0 .32em}
.ts-word.small .ts-sh,.ts-word.small .ts-sh>span{animation-delay:1.25s}
.ts-glow{position:absolute;left:50%;top:50%;width:150%;height:130%;transform:translate(-50%,-50%);z-index:-1;pointer-events:none;
  background:radial-gradient(closest-side,rgba(255,150,40,.32),rgba(255,110,20,.1) 60%,transparent)}
.ts-seal{position:relative;display:flex;align-items:center;gap:calc(2 * var(--u));margin:calc(3.2 * var(--u)) 0 calc(1 * var(--u));animation:ts-rise .7s ease-out .55s both}
.ts-rule{width:calc(17 * var(--u));height:2px;background:linear-gradient(90deg,transparent,#b4803a 60%,#ffdf8a)}
.ts-rule.r{transform:scaleX(-1)}
.ts-rule::after{content:"";position:absolute;width:6px;height:6px;margin:-2px 0 0 calc(17 * var(--u) - 3px);transform:rotate(45deg);background:#ffdf8a}
.ts-coin{position:relative;width:calc(13 * var(--u));height:calc(13 * var(--u));border-radius:50%;display:grid;place-items:center;
  background:radial-gradient(circle at 35% 28%,#fff4c0,#f2bf4e 38%,#b26b1a 72%,#6e3a0c);box-shadow:inset 0 0 0 2px #7a440c,inset 0 0 0 4px #ffe39a,0 3px 8px rgba(0,0,0,.6)}
.ts-coin b{font-weight:400;font-size:calc(9 * var(--u));line-height:1;color:#5a2c08;text-shadow:0 1px 0 #ffe9a8,0 -1px 0 #6e3a0c;margin-top:calc(.6 * var(--u))}
.ts-ring{position:absolute;inset:calc(-2.2 * var(--u));border-radius:50%;background:rgba(20,12,6,.85);
  -webkit-mask:radial-gradient(farthest-side,transparent calc(100% - 5px),#000 calc(100% - 4.5px));mask:radial-gradient(farthest-side,transparent calc(100% - 5px),#000 calc(100% - 4.5px))}
.ts-rh{position:absolute;top:0;bottom:0;width:50%;overflow:hidden}.ts-rh.a{left:0}.ts-rh.b{right:0}
.ts-rw{position:absolute;top:0;width:200%;height:100%;will-change:transform;transition:transform .45s ease-out}
.ts-rh.a .ts-rw{left:0;transform:rotate(var(--a1))}.ts-rh.b .ts-rw{left:-100%;transform:rotate(var(--a2))}
.ts-rw>span{position:absolute;top:0;left:50%;width:50%;height:100%;overflow:hidden}
.ts-rw>span>i{position:absolute;top:0;left:-100%;width:200%;height:100%;will-change:transform;transition:transform .45s ease-out;
  background:conic-gradient(from 180deg,#fff2a8 0deg,#ffd84a 180deg,#e8a224 360deg)}
.ts-rh.a .ts-rw>span>i{transform:rotate(calc(-1 * var(--a1)))}.ts-rh.b .ts-rw>span>i{transform:rotate(calc(-1 * var(--a2)))}
.ts-tip{position:absolute;inset:calc(-2.2 * var(--u));border-radius:50%;transform:rotate(calc(var(--a1) + var(--a2)));will-change:transform;transition:transform .45s ease-out}
.ts-tip::before{content:"";position:absolute;left:50%;top:-1px;width:7px;height:7px;margin-left:-3.5px;border-radius:50%;background:#fffbe6;box-shadow:0 0 8px 3px #ffc850}
.title-splash.ready .ts-tip{opacity:0;transition:opacity .4s}
.ts-chest{position:relative;width:calc(66 * var(--u));margin-top:calc(1 * var(--u));animation:ts-rise .8s ease-out .35s both}
.ts-chest svg{position:relative;display:block;width:100%;height:auto;overflow:visible}
.ts-halo{position:absolute;left:50%;top:44%;width:150%;aspect-ratio:1;transform:translate(-50%,-50%);border-radius:50%;pointer-events:none;will-change:transform,opacity;
  background:radial-gradient(closest-side,rgba(255,196,90,.55),rgba(255,130,30,.22) 45%,transparent);animation:ts-breathe 3.2s ease-in-out infinite}
.ts-lid{transform-box:view-box;transform-origin:120px 88px;transform:translateY(-13px) scaleY(.9);transition:transform .5s cubic-bezier(.3,1.6,.5,1)}
.ts-rays{position:absolute;inset:0;width:100%;height:auto;overflow:visible;will-change:opacity;animation:ts-rays 3.2s ease-in-out infinite}
.ts-chest svg.ts-rays{position:absolute}
.ts-embers{position:absolute;inset:0;pointer-events:none}
.ts-embers i{position:absolute;left:var(--x);bottom:18%;width:var(--s);height:var(--s);border-radius:50%;opacity:0;
  background:radial-gradient(circle,#fffbe0 0,#ffc24a 35%,rgba(255,120,20,.0) 70%);will-change:transform,opacity;animation:ts-ember var(--t) linear var(--d) infinite}
.ts-foot{position:relative;height:calc(16 * var(--u));min-height:64px;display:grid;place-items:center;width:100%}
.ts-foot>*{grid-area:1/1}
.ts-status{font-family:"Alegreya Sans","Segoe UI",system-ui,sans-serif;font-size:12px;letter-spacing:.24em;text-transform:uppercase;color:#a08458;transition:opacity .3s}
.ts-tap{display:flex;white-space:nowrap;align-items:center;gap:12px;font-size:calc(max(18px,3.4 * var(--u)));letter-spacing:.14em;text-transform:uppercase;color:#ffe3a0;opacity:0;
  text-shadow:0 2px 0 #3a1a06,0 0 12px rgba(255,170,60,.55);pointer-events:none}
.ts-tap::before,.ts-tap::after{content:"";width:7px;height:7px;transform:rotate(45deg);background:#ffcf6a}
.title-splash.ready .ts-status{opacity:0}
.title-splash.ready .ts-tap{animation:ts-pulse 1.8s ease-in-out .2s infinite both}
.title-splash.ready .ts-ring{background:conic-gradient(#fff2a8,#ffd84a,#e8a224,#ffd84a,#fff2a8)}.title-splash.ready .ts-rh{display:none}
.title-splash.ready .ts-coin{animation:ts-ding .6s ease-out}
.title-splash.open{opacity:0;transition:opacity .55s ease-in .25s;pointer-events:none}
.title-splash.open .ts-stage{transform:scale(1.08);transition:transform .8s cubic-bezier(.3,0,.2,1)}
.title-splash.open .ts-lid{transform:translateY(-34px) scaleY(.42)}
.title-splash.open .ts-halo{animation:none;opacity:1;transform:translate(-50%,-50%) scale(1.5);transition:transform .6s ease-out}
.title-splash.open .ts-tap{animation:none;opacity:0;transition:opacity .2s}
.title-splash.still .ts-embers,.title-splash.still .ts-sh{display:none}
.title-splash.still .ts-mark,.title-splash.still .ts-seal,.title-splash.still .ts-chest,.title-splash.still .ts-halo,.title-splash.still .ts-rays,.title-splash.still.ready .ts-tap,.title-splash.still .ts-coin{animation:none}
.title-splash.still.ready .ts-tap{opacity:1}
.title-splash.still.open{transition:opacity .25s}.title-splash.still.open .ts-stage,.title-splash.still.open .ts-lid,.title-splash.still.open .ts-halo{transition:none}
@keyframes ts-stamp{from{opacity:0;transform:scale(1.35)}60%{opacity:1}to{opacity:1;transform:none}}
@keyframes ts-rise{from{opacity:0;transform:translateY(14px)}to{opacity:1;transform:none}}
@keyframes ts-shine{0%,72%{transform:translateX(-110%) skewX(-15deg)}92%,100%{transform:translateX(110%) skewX(-15deg)}}
@keyframes ts-shine-in{0%,72%{transform:skewX(15deg) translateX(110%)}92%,100%{transform:skewX(15deg) translateX(-110%)}}
@keyframes ts-breathe{0%,100%{opacity:.8;transform:translate(-50%,-50%) scale(.96)}50%{opacity:1;transform:translate(-50%,-50%) scale(1.04)}}
@keyframes ts-rays{0%,100%{opacity:.75}50%{opacity:1}}
@keyframes ts-ember{0%{opacity:0;transform:translate(0,0)}12%{opacity:1}75%{opacity:.8}100%{opacity:0;transform:translate(var(--dx),calc(-62 * var(--u)))}}
@keyframes ts-pulse{0%,100%{opacity:.55;transform:scale(.97)}50%{opacity:1;transform:scale(1.03)}}
@keyframes ts-ding{40%{transform:scale(1.12)}}


/* Layout: the 3D view fills the window. The top bar (profile, location, Journal, Options, the quest tracker), the item card (right) and the dock (bottom: coin pouch and inventory) are drawn over it. Nothing scrolls except inside a panel. */
:root{
  --ground:#0b0908; --panel:#15110d; --panel-2:#1c1712; --well:#0f0c0a;
  --edge:#3a2f23; --edge-hi:#6b5436; --bronze:#b48c50; --bronze-hi:#e0bb7a;
  --text:#d2c8b6; --dim:#8c8170; --faint:#5f5548;
  --r-normal:#e4dfd5; --r-magic:#8299ff; --r-rare:#f4d850; --r-set:#4cd66c; --r-legendary:#f28b2e; --r-mythic:#b04cff; --r-unique:#f4f8ff; --r-unique-edge:#9ec3e6;
  --affix:#93a8ff; --good:#4cd66c; --bad:#e0584a; --flavor:#c98f52;
  --display:"Metamorphous","Cinzel",Georgia,"Times New Roman",serif;
  --body:"Alegreya Sans","Segoe UI",system-ui,-apple-system,sans-serif;
  --serif:"Alegreya",Georgia,"Times New Roman",serif;
  --mono:ui-monospace,"Cascadia Mono",Consolas,monospace;
  color-scheme:dark;
}
*{box-sizing:border-box}
html,body{height:100%;background:var(--ground);color:var(--text);overflow:hidden}
/* Nothing on the page is selectable text, so fast clicking never paints a blue selection; the item code box keeps it. */
body{-webkit-user-select:none;user-select:none;-webkit-touch-callout:none;-webkit-tap-highlight-color:transparent}
input,textarea{-webkit-user-select:text;user-select:text}
body{font-family:var(--body);font-size:11.5px;line-height:1.25}
button,input,select{font:inherit;color:inherit}
:focus-visible{outline:2px solid var(--bronze-hi);outline-offset:1px}
p{margin:0}
#gl{position:fixed;inset:0;width:100%;height:100%;display:block;background:#070605}
#labels{position:fixed;inset:0;pointer-events:none;overflow:hidden}
.lbl{position:absolute;left:0;top:0;transform:translate(-50%,-100%);padding:3px 9px;font-size:16px;font-weight:600;color:var(--rc);
  background:rgba(6,5,4,.88);border:1px solid color-mix(in srgb,var(--rc) 45%,transparent);border-radius:2px;white-space:nowrap;pointer-events:auto;cursor:pointer;will-change:transform}
.lbl.on,.lbl:hover{background:rgba(40,30,20,.97);border-color:var(--rc)}
.lbl[hidden]{display:none}
#flash{position:fixed;inset:0;pointer-events:none;opacity:0;background:radial-gradient(circle at 50% 60%,rgba(255,150,50,.35),transparent 60%)}
.hud{position:fixed;inset:0;display:grid;grid-template-columns:200px minmax(0,1fr) 300px;grid-template-rows:auto minmax(0,1fr) auto;gap:6px;padding:8px;pointer-events:none}
.hud>*{pointer-events:auto;min-width:0;min-height:0}
.panel{position:relative;background:linear-gradient(180deg,rgba(28,23,18,.88),rgba(21,17,13,.92));backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px);
  border:1px solid var(--edge);box-shadow:inset 0 0 0 1px #000,0 4px 14px rgba(0,0,0,.5);border-radius:2px}
.panel::before,.panel::after{content:"";position:absolute;width:6px;height:6px;border:1px solid var(--bronze);opacity:.5;pointer-events:none}
.panel::before{top:-1px;left:-1px;border-right:0;border-bottom:0}
.panel::after{bottom:-1px;right:-1px;border-left:0;border-top:0}
/* No blur behind the panels while the loading screen covers the room (it cannot be seen there), and with Battery saver on (17-speed.js). */
body.is-loading .panel,body.saver .panel{backdrop-filter:none;-webkit-backdrop-filter:none}
.h{margin:0;font-family:var(--display);font-weight:400;font-size:9.5px;letter-spacing:.14em;text-transform:uppercase;color:var(--bronze-hi)}
/* The top bar: the profile chip at the left, the location box in the centre, the Journal and Options buttons at the right
   and the quest tracker under them. The bar has no background; each part is its own box. */
.top{grid-column:1/-1;position:relative;display:grid;grid-template-columns:minmax(0,1fr) auto minmax(0,1fr);align-items:start;gap:8px;pointer-events:none}
.hud>.top{pointer-events:none}.top>*{pointer-events:auto}
.place-box{grid-column:2;padding:6px 26px 7px;font-family:var(--display);font-size:24px;line-height:1.1;letter-spacing:.12em;text-transform:uppercase;white-space:nowrap;
  color:#ffe2ad;text-align:center;border:1px solid var(--edge-hi);border-radius:3px;background:linear-gradient(180deg,rgba(44,34,22,.94),rgba(18,14,10,.95));
  box-shadow:inset 0 0 0 1px #000,inset 0 1px 0 rgba(255,220,160,.12),0 4px 14px rgba(0,0,0,.55);text-shadow:0 2px 3px #000}
.place-box b{font-weight:400}
.place-box span{color:var(--bronze-hi)}
.top .right{grid-column:3;justify-self:end;display:flex;align-items:center;gap:8px}
/* The Developer panel: the item level, Magic Find, type, rarity table, item code, the Developer box and the drop log, for
   testing. It opens over the room above the Developer button at the bottom left (placeDev in 17-ui.js sets --dev-top and --dev-bottom). */
.controls{position:fixed;left:8px;top:var(--dev-top,64px);bottom:var(--dev-bottom,220px);z-index:3;width:232px;display:flex;flex-direction:column;overflow-x:hidden;overflow-y:auto}
.controls[hidden]{display:none}
/* The item card opens under the quest tracker (--trk-h is the tracker's height; 25-quests.js writes it). */
.inspect{grid-row:2/4;grid-column:3;overflow-x:hidden;overflow-y:auto;align-self:start;max-height:calc(100% - var(--trk-h,0px));margin-top:var(--trk-h,0px)}
.inspect[hidden]{display:none}
/* The dock at the bottom: the coin pouch at the left with the Developer button over it, the inventory in the centre, raised
   from the bottom, and the items-per-touch buttons at its right. Only its parts take taps; the room between them stays open. */
.hud>.dock{pointer-events:none}.dock>*{pointer-events:auto}
.dock{grid-row:3;grid-column:1/-1;display:grid;grid-template-columns:minmax(0,1fr) auto minmax(0,1fr);align-items:end;gap:12px}
.per-touch{grid-column:3;justify-self:start;margin-bottom:18px;display:flex;align-items:center;gap:3px;padding:4px;font-size:14px}
.per-touch .label{margin-right:4px;white-space:nowrap}
.per-touch label{cursor:pointer}
.per-touch input{position:absolute;opacity:0;pointer-events:none}
.per-touch span:not(.label){display:inline-block;min-width:32px;padding:4px 7px;text-align:center;border:1px solid var(--edge);border-radius:2px;
  font-variant-numeric:tabular-nums;color:var(--dim);background:var(--well)}
.per-touch input:checked+span{border-color:#a7753a;color:#ffe2ad;background:linear-gradient(180deg,#6a3d17,#3b200c)}
.per-touch input:focus-visible+span{outline:2px solid var(--bronze-hi)}
.field{padding:3px 6px;border-bottom:1px solid rgba(58,47,35,.65);display:flex;flex-direction:column;gap:1px}
.label-row{display:flex;justify-content:space-between;align-items:baseline;gap:6px}
.label{font-size:9px;letter-spacing:.09em;text-transform:uppercase;color:var(--dim)}
.val{font-variant-numeric:tabular-nums;color:var(--bronze-hi);font-weight:700;font-size:10.5px}
input[type=range]{-webkit-appearance:none;appearance:none;width:100%;height:11px;background:transparent;margin:0;display:block}
input[type=range]::-webkit-slider-runnable-track{height:3px;border-radius:2px;background:linear-gradient(90deg,#8a5e2c var(--p,50%),#231c15 var(--p,50%));box-shadow:0 0 0 1px #000}
input[type=range]::-moz-range-track{height:3px;border-radius:2px;background:linear-gradient(90deg,#8a5e2c var(--p,50%),#231c15 var(--p,50%))}
input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;width:10px;height:10px;margin-top:-3.5px;border-radius:50%;background:radial-gradient(circle at 35% 30%,#ffe7b3,#b3833f 55%,#5a3a16);border:1px solid #000;box-shadow:0 0 5px rgba(240,170,80,.5)}
input[type=range]::-moz-range-thumb{width:9px;height:9px;border-radius:50%;background:radial-gradient(circle at 35% 30%,#ffe7b3,#b3833f 55%,#5a3a16);border:1px solid #000}
.inline{display:grid;grid-template-columns:auto minmax(0,1fr);align-items:center;gap:5px}
select,.code-input{width:100%;min-width:0;background:var(--well);border:1px solid var(--edge);border-radius:2px;padding:0 3px;color:var(--text);font-size:11px;height:19px}
select option,select optgroup{background:#15110d}
.code-row{display:flex;gap:3px}
.code-input{font-family:var(--mono);font-size:10px}
.err{color:var(--bad);font-size:10px}
.checks{flex-direction:row;flex-wrap:wrap;gap:2px 10px}
.check{display:flex;align-items:center;gap:4px;font-size:10.5px;cursor:pointer}
.check input{accent-color:#b48c50;width:10px;height:10px;margin:0}
.rar-head,.rar-row{display:grid;grid-template-columns:50px minmax(0,1fr) 31px 24px;align-items:center;gap:4px}
.rar-head{font-size:9px;letter-spacing:0;text-transform:uppercase;color:var(--faint);padding:0 3px}
.rar-head span:nth-child(n+3){text-align:right}
.rar-row{position:relative;padding:0 3px;border:1px solid transparent;border-radius:2px;cursor:pointer;font-size:11px;line-height:1.3}
.rar-row input{position:absolute;opacity:0;pointer-events:none}
.rar-row:hover{background:rgba(255,255,255,.03)}
.rar-row:has(input:checked){border-color:var(--rc);background:linear-gradient(90deg,color-mix(in srgb,var(--rc) 14%,transparent),transparent)}
.rar-row:has(input:focus-visible){outline:2px solid var(--bronze-hi)}
.rar-row .n{color:var(--rc)}
.rar-row .bar{height:4px;background:#0a0807;border:1px solid #2a221a;border-radius:3px;overflow:hidden}
.rar-row .bar i{display:block;height:100%;background:var(--rc);box-shadow:0 0 6px var(--rc);border-radius:3px;transition:width .25s}
.rar-row .pct,.rar-row .cnt{text-align:right;font-variant-numeric:tabular-nums;color:var(--dim);font-size:10.5px}
.rar-row .cnt{color:var(--text)}
.rar-row.any .n{color:var(--text)}
.rar-row.any .bar{visibility:hidden}
.log{flex:1;min-height:0;display:flex;flex-direction:column;gap:2px;padding:3px 6px 5px}
.log-line{display:flex;align-items:center;gap:8px;font-size:10.5px;color:var(--dim)}
.log-line b{color:var(--text);font-weight:700;font-variant-numeric:tabular-nums}
.log-line .btn{margin-left:auto}
.recent{flex:1;min-height:30px;overflow:auto;display:flex;flex-direction:column;font-size:10.5px;border-top:1px solid rgba(58,47,35,.65);padding-top:3px}
.recent button{all:unset;flex:none;cursor:pointer;color:var(--rc);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;line-height:1.35}
.recent button:hover{text-decoration:underline}
.recent button:focus-visible{outline:2px solid var(--bronze-hi)}
.btn{appearance:none;border:1px solid var(--edge-hi);background:linear-gradient(180deg,#2a2119,#17120d);color:var(--text);padding:1px 8px;border-radius:2px;cursor:pointer;
  font-family:var(--display);letter-spacing:.04em;font-size:11px;line-height:1.35;box-shadow:inset 0 1px 0 rgba(255,220,160,.08),0 1px 0 #000;white-space:nowrap}
.btn:hover{filter:brightness(1.25)}
.btn:active{transform:translateY(1px)}
.btn.primary{border-color:#a7753a;color:#ffe2ad;background:linear-gradient(180deg,#6a3d17,#3b200c);box-shadow:inset 0 1px 0 rgba(255,210,150,.25),0 0 12px -5px #f28b2e}
.btn.small{font-family:var(--body);letter-spacing:0;font-size:10px;padding:0 5px}
.btn.ghost{background:transparent;box-shadow:none;border-color:var(--edge)}
/* Inventory: a grid of big square slots (layoutInv in 17-ui.js), one item per slot. A tap throws the item out; a drag lifts
   it and the copy (.lift) follows the pointer; holding a slot still for 0.5 s fills a ring (.hold-ring, shown from 0.2 s) and opens the card. */
.inv{grid-column:2;position:relative;margin-bottom:18px;padding:6px}
/* --cols and --slot come from the backpack's size and the screen (layoutInv in 17-ui.js). */
.inv-grid{display:grid;grid-template-columns:repeat(var(--cols,4),var(--slot,78px));grid-auto-rows:var(--slot,78px);gap:4px}
.inv-slot{position:relative;width:var(--slot,78px);height:var(--slot,78px);border:1px solid #2a221a;border-radius:3px;padding:0;background:#0a0807;box-shadow:inset 0 0 8px #000;display:grid;place-items:center;overflow:hidden}
/* A filled slot: a 3 px border in the full rarity colour and a faint inner glow of the same colour. */
.inv-slot.full{border-width:3px;border-color:var(--rc);cursor:grab;touch-action:none;user-select:none;-webkit-user-select:none;-webkit-touch-callout:none;
  box-shadow:inset 0 0 5px 1px color-mix(in srgb,var(--rc) 45%,transparent);background:radial-gradient(circle at 50% 55%,color-mix(in srgb,var(--rc) 18%,#0c0a08),#0a0807 75%)}
.inv-slot img{width:100%;height:100%;display:block;pointer-events:none;-webkit-user-drag:none}
.inv-slot.full:hover,.inv-slot.sel{border-color:color-mix(in srgb,var(--rc) 70%,#fff);box-shadow:inset 0 0 6px 1px color-mix(in srgb,var(--rc) 60%,transparent),0 0 8px -1px var(--rc)}
/* A quest item's slot: a gold star in the top-left corner. */
.inv-slot.quest::after{content:'\2605';position:absolute;left:1px;top:-2px;font-size:12px;line-height:1;color:#ffcf5a;text-shadow:0 0 3px #000,0 0 2px #000;pointer-events:none}
/* A Unique's slot (28-uniques.js): a white frame with a cold pearl edge, and a band of light that crosses it every 3 s. */
.inv-slot.uq{box-shadow:inset 0 0 0 1px var(--r-unique-edge),inset 0 0 12px 2px color-mix(in srgb,var(--r-unique-edge) 70%,transparent),0 0 10px -1px #fff}
.inv-slot.uq::after{content:'';position:absolute;inset:0;pointer-events:none;background:linear-gradient(115deg,transparent 35%,rgba(255,255,255,.5) 50%,transparent 65%);
  transform:translateX(-120%);animation:uq-shine 3s ease-in-out infinite}
@keyframes uq-shine{60%,100%{transform:translateX(120%)}}body:has(#reduceMotion:checked) .inv-slot.uq::after{animation:none}
.inv-slot.arriving img{opacity:0}
.inv-slot.lifted img{opacity:.25}
.hold-ring{position:absolute;left:50%;top:50%;width:40px;height:40px;margin:-20px 0 0 -20px;pointer-events:none;transform:rotate(-90deg);overflow:visible;
  opacity:0;animation:hold-show .06s linear .2s forwards;filter:drop-shadow(0 0 2px #000)}
.hold-ring .back{fill:rgba(6,5,4,.55);stroke:rgba(255,226,173,.3);stroke-width:4}
.hold-ring .fill{fill:none;stroke:#ffd75e;stroke-width:4;stroke-linecap:round;stroke-dasharray:100;stroke-dashoffset:100;animation:hold-fill .3s linear .2s forwards}
@keyframes hold-show{to{opacity:1}}
@keyframes hold-fill{to{stroke-dashoffset:0}}
/* The thumbnail of an item thrown out with a tap: it flies up out of its slot to the floor spot where the item lands. */
.toss-thumb{position:fixed;left:0;top:0;width:48px;height:48px;margin:-24px 0 0 -24px;pointer-events:none;border:2px solid var(--rc);border-radius:3px;
  background:radial-gradient(circle at 50% 55%,color-mix(in srgb,var(--rc) 22%,#0c0a08),#0a0807 75%);box-shadow:0 0 12px -2px var(--rc),0 6px 10px rgba(0,0,0,.8)}
.toss-thumb img{width:100%;height:100%;display:block}
/* The hidden switch for haptic feedback on iPhone (Haptics in 17-ui.js): never shown, never focused, never read out. */
.haptic{display:none}
.slot-tip{position:fixed;z-index:6;pointer-events:none;padding:1px 6px;font-size:10.5px;color:var(--rc);background:rgba(6,5,4,.94);
  border:1px solid color-mix(in srgb,var(--rc) 55%,transparent);border-radius:2px;white-space:nowrap}
.slot-tip[hidden]{display:none}
.lift{position:fixed;left:0;top:0;width:44px;height:44px;margin:-22px 0 0 -22px;pointer-events:none;z-index:6;box-sizing:border-box;border:1px solid var(--rc);border-radius:2px;
  background:radial-gradient(circle at 50% 55%,color-mix(in srgb,var(--rc) 22%,#0c0a08),#0a0807 75%);box-shadow:0 0 10px -2px var(--rc),0 6px 10px rgba(0,0,0,.8)}
.lift[hidden]{display:none}
.msg{position:fixed;left:50%;bottom:226px;transform:translateX(-50%);max-width:calc(100vw - 16px);padding:4px 11px;font-size:15px;color:#ffe2ad;text-align:center;
  background:rgba(6,5,4,.92);border:1px solid var(--edge-hi);border-radius:2px;pointer-events:none;opacity:0;transition:opacity .2s;z-index:4}
.msg.on{opacity:1}
/* The coin pouch at the bottom left, the one gold number on screen (Hud.pouch() in 17-ui.js gives its element and the point
   where coins land): a round frame with the pouch picture and the gold under it, which grows to the right when it is wider than the frame. During the sell-off it glows. */
.pouch-col{grid-column:1;justify-self:start;display:flex;flex-direction:column;align-items:flex-start;gap:10px}
.pouch{display:flex;flex-direction:column;align-items:flex-start;gap:3px;min-width:124px;pointer-events:none}
.pouch-ring{display:grid;place-items:center;width:112px;height:112px;margin-left:10px;border-radius:50%;border:2px solid #c99a4a;
  background:radial-gradient(circle at 50% 40%,#3c2b18,#120d08 72%);
  box-shadow:inset 0 0 0 3px #1a120a,inset 0 0 0 4px #6b5436,inset 0 0 22px #000,0 0 0 1px #000,0 6px 18px rgba(0,0,0,.6),0 0 26px -6px rgba(255,190,80,.55)}
.pouch-icon{width:82px;height:82px;flex:none;transform-origin:50% 90%;filter:drop-shadow(0 3px 3px rgba(0,0,0,.8))}
.pouch .gold{min-width:112px;margin-left:10px;text-align:center;font-size:28px;font-weight:800;line-height:1.05;color:var(--r-rare);font-variant-numeric:tabular-nums;
  white-space:nowrap;text-shadow:0 2px 3px #000,0 0 10px #000,0 0 16px rgba(244,216,80,.3)}
.hud.selling .pouch-icon{filter:drop-shadow(0 0 8px rgba(255,200,60,.9))}
.hud.selling .dev-toggle{visibility:hidden}
/* The Developer button over the pouch: a small triangle that turns when the panel is open. */
.dev-toggle{appearance:none;display:flex;align-items:center;gap:7px;padding:4px 10px 4px 8px;font:600 12px var(--body);color:var(--dim);cursor:pointer;
  border:1px solid var(--edge);border-radius:2px;background:rgba(15,12,10,.82)}
.dev-toggle::before{content:"";border:5px solid transparent;border-left:7px solid currentColor;border-right:0;transition:transform .15s}
.dev-toggle[aria-expanded="true"]{color:var(--text);border-color:var(--edge-hi)}.dev-toggle[aria-expanded="true"]::before{transform:rotate(-90deg)}
.dev-toggle:hover{color:var(--text)}
/* After time is up the items-per-touch buttons are dimmed: touches do nothing until the next round. */
.hud.round-over .per-touch{opacity:.35;pointer-events:none}
/* The time left, large, under the location box. It turns orange in the last 10 seconds, then red and pulsing in the last 5. */
.big-time{position:fixed;left:50%;top:var(--bt-top,36px);transform:translateX(-50%);transform-origin:50% 0;pointer-events:none;font-family:var(--display);
  font-size:clamp(34px,5.2vw,44px);line-height:1;color:#ffe2ad;font-variant-numeric:tabular-nums;letter-spacing:.04em;
  text-shadow:0 2px 4px #000,0 0 16px rgba(0,0,0,.9)}
.big-time.low{color:#ffb050}
.big-time.urgent{color:#ff5a40;text-shadow:0 2px 4px #000,0 0 18px rgba(255,60,30,.6)}
/* While the shop is open the top bar and the coin pouch stay over it: the shop is at z-index 6, the HUD comes to 7 and shows
   only those (on a phone only the pouch, as the shop fills the top there). The shop's sign hangs where the location and the time are. */
body:has(#shop:not([hidden])) .hud{z-index:7}
body:has(#shop:not([hidden])) :is(.big-time,.round-sub,.place-box,.q-track,.controls,.inspect,.spells,.inv,.per-touch,.dev-toggle){visibility:hidden}
/* Under the large time: the potions working this round. */
.round-sub{position:fixed;left:50%;top:var(--rs-top,120px);transform:translateX(-50%);display:flex;flex-direction:column;align-items:center;gap:5px;pointer-events:none}
/* While a spell runs, the large time turns pale blue (Time Stop) or blue (Slow Time). */
.big-time.frozen{color:#e6f0ff;text-shadow:0 2px 4px #000,0 0 18px rgba(150,190,255,.95)}
.big-time.slowed{color:#8fb4ff;text-shadow:0 2px 4px #000,0 0 16px rgba(60,110,255,.8)}
/* Spell buttons (22-shop.js): round buttons, each with its picture, its name under it, the charges left in a gold badge,
   and while it runs a ring that empties as its time runs out (--left). On a desktop they sit at the bottom of the right
   column, outside the floor where drops land; the item card there leaves room for them. On a phone they sit over the
   bottom right of the room, and the floor where drops land ends above them (floorScreen in 12-scene.js). */
.spells{grid-row:2/4;grid-column:3;align-self:end;justify-self:center;display:flex;gap:14px;margin:0 0 30px}
.hud:has(.spells:not([hidden])) .inspect{max-height:calc(100% - 86px - var(--trk-h,0px))}
.spells[hidden]{display:none}
.spell{position:relative;width:54px;height:54px;padding:0;border-radius:50%;border:2px solid #8fb4ff;cursor:pointer;display:grid;place-items:center;touch-action:manipulation;
  background:radial-gradient(circle at 50% 38%,#2c3e72,#0c1022 75%);box-shadow:0 0 14px -2px #5a8cff,inset 0 0 10px #000}
.spell .shop-icon{width:30px;height:30px}
.spell .n{position:absolute;top:100%;left:50%;transform:translateX(-50%);margin-top:2px;font-size:9.5px;white-space:nowrap;color:#d6e4ff;text-shadow:0 1px 2px #000,0 0 6px #000}
.spell .cnt{position:absolute;right:-4px;top:-4px;min-width:18px;height:18px;border-radius:9px;background:#ffd75e;color:#2a1a04;font-style:normal;font-weight:700;font-size:11px;
  line-height:18px;text-align:center;box-shadow:0 1px 3px #000}
.spell:disabled{opacity:.45;cursor:default;filter:grayscale(.6)}
.spell:not(:disabled):hover{filter:brightness(1.25)}
.spell.on{border-color:#eaf2ff;box-shadow:0 0 22px 2px #7aa8ff,inset 0 0 10px #000}
.spell.on::before{content:"";position:absolute;inset:-7px;border-radius:50%;background:conic-gradient(#cfe0ff var(--left,100%),rgba(255,255,255,.08) 0);
  -webkit-mask:radial-gradient(closest-side,transparent 84%,#000 86%);mask:radial-gradient(closest-side,transparent 84%,#000 86%)}
/* The room while a spell runs: grey and still for Time Stop, blue for Slow Time, with a tint layer over the room. */
#gl{transition:filter .35s}
.spell-tint{position:fixed;inset:0;pointer-events:none;opacity:0;transition:opacity .35s}
body.spell-stop .spell-tint{opacity:1;background:radial-gradient(ellipse at 50% 50%,rgba(230,240,255,0) 40%,rgba(200,220,255,.26))}
body.spell-slow .spell-tint{opacity:1;background:radial-gradient(ellipse at 50% 50%,rgba(70,120,255,.1),rgba(40,80,230,.34))}
.spell-ring{border-width:4px}
/* The shop between rounds: Shop (22-shop.js) keeps the goods and the rules, ShopShelf (22-shop-shelf.js) draws them. A wooden SHOP
   sign, the gold in the bank and the X at the top; the hooded goblin trader with her speech bubble at the left (above the shelves on a
   phone); the goods as big icons on two shelves with a price tag under each; the counter with the selected good and the BUY button;
   ShopShelf.fit scales the shop to the window (--sh-k) and sets its top; the sheet before it (.shop-dim) dims the room behind it
   (owner, 2026-10-11: not a 100vmax shadow, a huge layer on an iPhone). Hidden under the Journal or the player panel (class under). */
.shop.under{visibility:hidden}.shop-dim{position:fixed;inset:0;z-index:6;display:none;background:rgba(4,3,2,.5);pointer-events:none}
.shop{position:fixed;left:50%;top:60px;z-index:6;width:1080px;transform:translateX(-50%) scale(var(--sh-k,1));transform-origin:50% 0;display:grid;
  grid-template-columns:236px minmax(0,1fr);grid-template-rows:56px auto auto;grid-template-areas:"head head" "keeper wall" "counter counter";
  padding:14px 18px 16px;font-size:16px;line-height:1.2;color:var(--text);background:linear-gradient(180deg,#1f1913,#130f0b);border:1px solid var(--edge-hi);border-radius:4px;
  box-shadow:inset 0 0 0 1px #000,inset 0 0 0 4px #1a140f,inset 0 0 0 5px #3a2f23,0 30px 80px rgba(0,0,0,.85)}
.shop[hidden]{display:none}.shop-dim:has(+ .shop:not([hidden]):not(.under)){display:block;animation:sh-dim-in .26s ease-out}@keyframes sh-dim-in{from{opacity:0}}.sh-corner{position:absolute;width:16px;height:16px;border:2px solid var(--bronze);opacity:.8;pointer-events:none}
.sh-corner.tl{left:-2px;top:-2px;border-right:0;border-bottom:0}.sh-corner.tr{right:-2px;top:-2px;border-left:0;border-bottom:0}
.sh-corner.bl{left:-2px;bottom:-2px;border-right:0;border-top:0}.sh-corner.br{right:-2px;bottom:-2px;border-left:0;border-top:0}
.sh-head{grid-area:head;position:relative;display:flex;align-items:center;justify-content:flex-end;gap:14px}
.sh-sign{position:absolute;left:50%;top:-34px;transform:translateX(-50%);display:flex;flex-direction:column;align-items:center;pointer-events:none}
.sh-ropes{position:relative;width:120px;height:14px}
.sh-ropes::before,.sh-ropes::after{content:"";position:absolute;top:0;width:2px;height:14px;background:linear-gradient(#5a4530,#8a6a44)}
.sh-ropes::before{left:22px}.sh-ropes::after{right:22px}
.sh-board{padding:6px 30px 8px;border:1px solid #9a7444;border-radius:3px;box-shadow:inset 0 1px 0 rgba(255,220,160,.3),inset 0 0 0 3px rgba(0,0,0,.25),0 6px 14px rgba(0,0,0,.6);
  background:repeating-linear-gradient(0deg,transparent 0 5px,rgba(0,0,0,.12) 5px 6px),linear-gradient(180deg,#6e4a2a,#4a301a 60%,#3a2514)}
.sh-board h2{margin:0;font:400 26px var(--display);letter-spacing:.24em;text-transform:uppercase;color:transparent;-webkit-background-clip:text;background-clip:text;
  background-image:linear-gradient(180deg,#fff0c8,#e3b45e 55%,#a8701f);filter:drop-shadow(0 1px 0 rgba(0,0,0,.8))}
.sh-x{display:grid;place-items:center;width:40px;height:40px;padding:0;cursor:pointer;color:var(--bronze-hi);border:1px solid var(--edge-hi);border-radius:3px;
  background:linear-gradient(180deg,#2a2119,#120e0a)}
.sh-x:hover{color:#fff0c8;border-color:var(--bronze)}.sh-x svg{width:18px;height:18px}
/* The shop's X when nothing on the shelf can be bought (22-shop-shelf.js): every 3.2 s a light sweeps across it and its edge
   warms, as the Unique slots' shine does. */
#shopClose.glint{position:relative;overflow:hidden;animation:x-warm 3.2s ease-in-out infinite}
#shopClose.glint::after{content:'';position:absolute;inset:0;pointer-events:none;transform:translateX(-120%);
  background:linear-gradient(105deg,transparent 30%,rgba(255,236,190,.75) 50%,transparent 70%);animation:uq-shine 3.2s ease-in-out infinite}
@keyframes x-warm{0%,40%,100%{color:var(--bronze-hi);border-color:var(--edge-hi);box-shadow:none}
  55%{color:#fff0c8;border-color:#e0bb7a;box-shadow:0 0 14px rgba(240,190,90,.55)}}
body:has(#reduceMotion:checked) #shopClose.glint,body:has(#reduceMotion:checked) #shopClose.glint::after{animation:none}
.gold-pop.sh-spent{padding:2px 8px;border-radius:10px;background:rgba(0,0,0,.7);font-size:20px;font-weight:800;color:#ff6a50;text-shadow:0 1px 2px #000}
/* The trader and her bubble. She is quiet while Elowen's speech box is open. */
.sh-keeper{grid-area:keeper;position:relative;min-height:330px}.sh-kp{position:absolute;left:0;bottom:-2px;width:236px;height:266px}
.sh-bubble{position:absolute;left:10px;right:4px;bottom:250px;margin:0;padding:12px 16px 13px;border-radius:14px;font:italic 500 21px/1.2 var(--serif);
  text-align:center;text-wrap:balance;color:#2a1a0c;background:linear-gradient(180deg,#f6e9c9,#e4cf9f);box-shadow:0 6px 16px rgba(0,0,0,.55),inset 0 0 0 1px rgba(120,80,30,.35)}
.sh-bubble::after{content:"";position:absolute;left:96px;bottom:-12px;border:12px solid transparent;border-top-color:#e4cf9f;border-bottom:0}
.sh-bubble:empty,body:has(#story:not([hidden])) .sh-bubble{visibility:hidden}.sh-bubble.pop{animation:sh-pop .32s cubic-bezier(.3,1.6,.5,1)}
.sh-lid{opacity:0;animation:sh-blink 5.2s infinite}.sh-bob{animation:sh-bob 4s ease-in-out infinite;transform-origin:50% 100%}.sh-kp.nod .sh-bob{animation:sh-nod .5s ease-out}
/* The wall with two shelves 16 px apart, each good a button: glow, corner marks (ending under its own price tag), icon, count mark and the price tag on a string. */
.sh-wall{grid-area:wall;position:relative;overflow:hidden;padding:18px 26px 30px;border-radius:3px;box-shadow:inset 0 0 0 1px #000,inset 0 0 40px rgba(0,0,0,.7);
  background:radial-gradient(ellipse 50% 70% at 8% 0%,rgba(255,176,86,.22),transparent 70%),radial-gradient(ellipse 60% 50% at 70% 100%,rgba(0,0,0,.45),transparent 70%),
  linear-gradient(180deg,rgba(0,0,0,.35),transparent 26%,rgba(0,0,0,.25)),
  repeating-linear-gradient(90deg,#1a110b 0 2px,#2c1e13 2px 4px,#271a11 4px 92px,#21160e 92px 120px,#2a1c12 120px 182px)}
.sh-lantern{position:absolute;left:12px;top:-2px;width:30px;height:62px;filter:drop-shadow(0 0 10px rgba(255,170,70,.7))}
.sh-row{position:relative;display:grid;grid-template-columns:repeat(var(--sh-cols,4),minmax(0,1fr));height:172px}.sh-row+.sh-row{margin-top:16px}
.sh-plank{position:absolute;left:-30px;right:-30px;top:108px;height:24px;border-radius:2px;pointer-events:none;box-shadow:0 1px 0 #000,0 12px 18px rgba(0,0,0,.65);
  background:repeating-linear-gradient(90deg,transparent 0 37px,rgba(0,0,0,.18) 37px 38px,transparent 38px 91px,rgba(255,220,160,.06) 91px 92px),
  linear-gradient(180deg,#a87a48 0,#80592f 4px,#5a3c20 5px,#46301a 60%,#2e1e10 100%)}
.sh-good{position:relative;padding:0;border:0;background:none;cursor:pointer;outline:none;color:inherit}.sh-good:focus-visible .sh-tag{outline:2px solid var(--bronze-hi)}
.sh-glow{position:absolute;left:50%;top:-6px;width:170px;height:130px;transform:translateX(-50%);border-radius:50%;opacity:0;transition:opacity .25s;
  background:radial-gradient(ellipse at 50% 70%,rgba(255,206,120,.42),rgba(255,180,80,.12) 45%,transparent 70%)}
.sh-ico{position:absolute;left:50%;top:18px;width:88px;height:88px;transform:translateX(-50%);filter:drop-shadow(0 7px 4px rgba(0,0,0,.65));
  transition:transform .25s cubic-bezier(.3,1.5,.5,1),filter .25s}
.sh-ico svg,.sh-pic svg{display:block;width:100%;height:100%}
.sh-ico.caged>svg:first-child{position:absolute;left:19%;top:27%;width:62%;height:62%}.sh-ico .sh-cage{position:absolute;inset:0}.sh-good:hover .sh-ico{transform:translateX(-50%) translateY(-3px)}.sh-good.sel .sh-glow{opacity:1}
.sh-good.sel .sh-ico{transform:translateX(-50%) translateY(-7px) scale(1.06);animation:sh-float 2.4s ease-in-out infinite}
.sh-good.cant .sh-ico{filter:saturate(.45) brightness(.62) drop-shadow(0 7px 4px rgba(0,0,0,.65))}
.sh-good.maxed .sh-ico{filter:saturate(.3) brightness(.6) drop-shadow(0 7px 4px rgba(0,0,0,.65))}.sh-good.pop .sh-ico{animation:sh-gpop .55s cubic-bezier(.3,1.6,.5,1)}
.sh-brk{--c:#ffd75e;--l:16px;position:absolute;left:50%;top:2px;width:132px;height:160px;transform:translateX(-50%);opacity:0;pointer-events:none;transition:opacity .2s;
  filter:drop-shadow(0 0 5px rgba(255,215,94,.7));
  background:linear-gradient(var(--c),var(--c)) 0 0/var(--l) 3px no-repeat,linear-gradient(var(--c),var(--c)) 0 0/3px var(--l) no-repeat,
  linear-gradient(var(--c),var(--c)) 100% 0/var(--l) 3px no-repeat,linear-gradient(var(--c),var(--c)) 100% 0/3px var(--l) no-repeat,
  linear-gradient(var(--c),var(--c)) 0 100%/var(--l) 3px no-repeat,linear-gradient(var(--c),var(--c)) 0 100%/3px var(--l) no-repeat,
  linear-gradient(var(--c),var(--c)) 100% 100%/var(--l) 3px no-repeat,linear-gradient(var(--c),var(--c)) 100% 100%/3px var(--l) no-repeat}
.sh-good.sel .sh-brk{opacity:1;animation:sh-brk 1.6s ease-in-out infinite}
/* Each price tag hangs from the shelf's front edge on a brass nail: its top is on the plank and it swings round the nail. */
.sh-tag{position:absolute;left:50%;top:114px;display:flex;align-items:center;gap:7px;padding:10px 12px 6px;white-space:nowrap;transform:translateX(-50%) rotate(var(--tilt,0deg));
  transform-origin:50% 5px;border:1px solid #7a5c38;border-radius:4px;background:linear-gradient(180deg,#2e2216,#191109);
  box-shadow:0 4px 8px rgba(0,0,0,.6),inset 0 1px 0 rgba(255,220,160,.12)}
.sh-tag::after{content:"";position:absolute;left:50%;top:2px;width:6px;height:6px;margin-left:-3px;border-radius:50%;background:radial-gradient(circle at 35% 35%,#ffe7a8,#a8701f 70%);
  box-shadow:0 1px 1px #000}
.sh-tag svg{flex:none;width:22px;height:22px}.sh-tag b{font-size:22px;font-weight:800;line-height:1;color:var(--r-rare);font-variant-numeric:tabular-nums}
.sh-good.cant .sh-tag b{color:#c4665a}.sh-good.cant .sh-tag svg{opacity:.55;filter:grayscale(.6)}.sh-good.maxed .sh-tag svg{display:none}
.sh-good.maxed .sh-tag b{font:400 20px var(--display);letter-spacing:.12em;color:#ffe2ad}
.sh-good.sel .sh-tag{border-color:#e0bb7a;box-shadow:0 4px 10px rgba(0,0,0,.6),0 0 12px -2px rgba(255,215,94,.6)}.sh-good.deny .sh-tag{animation:sh-shake .4s}
.sh-mark{position:absolute;left:calc(50% + 14px);top:28px;z-index:2;display:none;align-items:center;justify-content:center;min-width:46px;height:36px;padding:0 10px;
  font-size:23px;font-weight:800;line-height:1;color:#ffe2ad;font-variant-numeric:tabular-nums;border:2px solid #e0bb7a;border-radius:20px;
  background:linear-gradient(180deg,#3a2614,#1a110a);box-shadow:0 2px 6px rgba(0,0,0,.7),0 0 10px rgba(255,200,100,.35)}
.sh-mark.on{display:flex}.sh-mark.max{border-color:#ffd75e;color:#2a1606;background:linear-gradient(180deg,#ffe39a,#d9a03e)}
.sh-mark.bump{animation:sh-bump .5s cubic-bezier(.3,1.8,.5,1)}
/* A shelf with five places (sh-five, 22-shop-shelf.js): narrower price tags, so the five fit side by side. */
.sh-five .sh-tag{gap:5px;padding:10px 9px 6px}.sh-five .sh-tag b{font-size:20px}.sh-five .sh-brk{width:124px}
/* The bottom shelf's tags: "New" in green, "Last chance" in red, a small card above the good, clear of its price tag and of the top shelf's tags. A Sold
   sign is a price tag that reads Sold, in a place that cannot be selected. */
.sh-new{position:absolute;left:50%;top:-10px;z-index:3;display:none;padding:4px 10px 5px;white-space:nowrap;transform:translateX(-50%) rotate(-2deg);
  font-size:17px;font-weight:800;line-height:1;color:#16300a;border:1px solid #2a4a14;border-radius:4px;background:linear-gradient(180deg,#d6f2a0,#86c050);
  box-shadow:0 2px 6px rgba(0,0,0,.65)}
.sh-new.on{display:block}.sh-new.last{color:#fff2e4;border-color:#4a1408;background:linear-gradient(180deg,#e8683e,#a8301a)}
.sh-good.sh-sold{cursor:default}.sh-sold .sh-tag{opacity:.85}.sh-sold .sh-tag b{font:400 20px var(--display);letter-spacing:.12em;color:#d8c49a}
/* The counter: the selected good's picture, name and short line, and the BUY button with its price, one group in the middle. */
.sh-counter{grid-area:counter;position:relative;z-index:2;display:flex;justify-content:center;align-items:center;gap:22px;min-height:140px;margin:0 -6px;
  padding:18px 22px 10px 20px;border-radius:3px;box-shadow:0 -8px 18px rgba(0,0,0,.55),inset 0 0 0 1px rgba(0,0,0,.6);
  background:repeating-linear-gradient(180deg,transparent 0 9px,rgba(0,0,0,.12) 9px 10px),linear-gradient(180deg,#b0824c 0,#8a6038 5px,#5d3e22 7px,#2a1c11 9px,#1d140c 100%)}
.sh-pic{display:grid;place-items:center;flex:none;width:104px;height:104px;padding:12px;border:1px solid var(--edge-hi);border-radius:6px;
  background:radial-gradient(circle at 50% 40%,#2c2117,#0d0a07 75%);box-shadow:inset 0 0 18px rgba(0,0,0,.8),0 0 0 1px #000}
.sh-pic svg{filter:drop-shadow(0 4px 4px rgba(0,0,0,.7))}.sh-info{min-width:0;max-width:430px}.sh-name{font:400 30px/1.08 var(--display);color:#ffe2ad;text-shadow:0 2px 0 rgba(0,0,0,.6)}
.sh-line{margin-top:4px;font-size:22px;font-weight:500;line-height:1.15;color:#efe3c8}
.sh-buy{position:relative;display:flex;flex:none;align-items:center;justify-content:center;gap:16px;width:252px;height:74px;padding:0;overflow:hidden;cursor:pointer;color:#2a1606;
  border:1px solid #ffe39a;border-radius:6px;background:linear-gradient(180deg,#ffe08a 0%,#e9b54c 48%,#c48a2c 52%,#a8701f 100%);transition:transform .08s,filter .2s;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.6),inset 0 -2px 0 rgba(90,50,10,.5),0 0 0 1px #3a2208,0 6px 16px rgba(0,0,0,.6),0 0 24px -6px rgba(255,200,90,.7)}
.sh-buy:hover{filter:brightness(1.08)}.sh-buy:active{transform:translateY(2px)}.sh-buy .w{font:400 24px var(--display);letter-spacing:.12em;text-transform:uppercase}
.sh-buy .sep{width:1px;align-self:stretch;background:rgba(60,30,5,.35);box-shadow:1px 0 0 rgba(255,240,200,.4)}
.sh-buy .p{display:flex;align-items:center;gap:7px;font-size:25px;font-weight:800;font-variant-numeric:tabular-nums}.sh-buy .p svg{width:24px;height:24px}
.sh-buy.cant{color:#8c8170;border-color:#5a4632;background:linear-gradient(180deg,#3a2c1e,#241a11);box-shadow:inset 0 1px 0 rgba(255,220,160,.08),0 0 0 1px #000}
.sh-buy.cant .p{color:#c4665a}.sh-buy.cant .sep{background:rgba(0,0,0,.4);box-shadow:1px 0 0 rgba(255,220,160,.06)}.sh-buy.cant .p svg{opacity:.5;filter:grayscale(.6)}
.sh-buy.maxed{cursor:default;color:#ffe2ad;border-color:#6b5436;background:linear-gradient(180deg,#2a2119,#17120d);box-shadow:inset 0 0 0 1px #000}
.sh-buy.maxed .sep,.sh-buy.maxed .p{display:none}.sh-buy.deny{animation:sh-shake .4s}
.sh-shine{position:absolute;inset:0;transform:translateX(-120%);pointer-events:none;background:linear-gradient(105deg,transparent 35%,rgba(255,255,255,.55) 50%,transparent 65%)}
.sh-buy.flash .sh-shine{animation:sh-shine .6s ease-out}
/* With Reduce motion on, the trader, the selection marks and the selected good keep still. */
.shop.sh-still .sh-lid,.shop.sh-still .sh-bob,.shop.sh-still .sh-good.sel .sh-ico,.shop.sh-still .sh-good.sel .sh-brk{animation:none}
@keyframes sh-pop{0%{transform:scale(.86)}100%{transform:scale(1)}}@keyframes sh-blink{0%,94%,97.5%,100%{opacity:0}95%,96.5%{opacity:1}}
@keyframes sh-bob{0%,100%{transform:translateY(0)}50%{transform:translateY(-2.5px)}}
@keyframes sh-nod{0%{transform:translateY(0)}35%{transform:translateY(5px) rotate(1.5deg)}100%{transform:translateY(0)}}
@keyframes sh-float{0%,100%{translate:0 0}50%{translate:0 -3px}}
@keyframes sh-gpop{0%{transform:translateX(-50%) scale(1)}
  30%{transform:translateX(-50%) translateY(-12px) scale(1.22)}100%{transform:translateX(-50%) translateY(-7px) scale(1.06)}}
@keyframes sh-brk{0%,100%{scale:1}50%{scale:1.035}}@keyframes sh-bump{0%{scale:.4}100%{scale:1}}
@keyframes sh-shake{0%,100%{translate:0}20%{translate:-7px}40%{translate:6px}60%{translate:-4px}80%{translate:3px}}@keyframes sh-shine{to{transform:translateX(120%)}}
/* The tabs of the player panel and the Journal, and the chest looks in the player panel (backpack-style cards). */
.shop-tabs{display:flex;gap:3px;padding:5px 10px 0;flex-wrap:wrap}
.shop-tab{appearance:none;cursor:pointer;padding:1px 9px;font-size:11px;border:1px solid var(--edge);border-radius:2px;color:var(--dim);background:var(--well)}
.shop-tab.on{color:#ffe2ad;border-color:#a7753a;background:linear-gradient(180deg,#6a3d17,#3b200c)}.shop-icon{display:block;flex:none}
.packs{display:grid;grid-template-columns:repeat(auto-fill,minmax(82px,1fr));gap:4px}
.pack{display:flex;flex-direction:column;align-items:center;gap:1px;padding:4px 2px 5px;border:1px solid var(--edge);border-radius:2px;background:var(--well);text-align:center;min-width:0}
.pack .shop-icon{width:30px;height:30px}.pack b{font-size:10.5px;font-weight:500;line-height:1.1;min-height:2.2em;display:flex;align-items:center}
.pack .slots{font-size:10px;color:var(--dim)}.tag{font-size:10px;color:#ffe2ad}.tag.dim{color:var(--faint)}.buy{min-width:76px}
.buy.can{border-color:#a7753a;color:#ffe2ad;background:linear-gradient(180deg,#6a3d17,#3b200c)}.buy:not(.can):not(:disabled){color:var(--faint)}
.big-time[hidden]{display:none}
.tt{--rc:var(--r-normal)}
.tt-head{position:relative;padding:4px 30px 3px;text-align:center;border-bottom:1px solid color-mix(in srgb,var(--rc) 45%,transparent);
  background:radial-gradient(120% 150% at 50% 0%,color-mix(in srgb,var(--rc) 24%,transparent),transparent 70%)}
.tt-name{margin:0;font-family:var(--display);font-weight:400;font-size:14px;line-height:1.1;color:var(--rc);letter-spacing:.02em;text-wrap:balance;text-shadow:0 0 14px color-mix(in srgb,var(--rc) 45%,transparent)}
.tt-base{color:var(--dim);font-size:10px}
.tt-portrait{position:relative;height:150px;margin:0 7px;border:1px solid color-mix(in srgb,var(--rc) 40%,#000);border-radius:2px;overflow:hidden;
  background:radial-gradient(circle at 50% 60%,color-mix(in srgb,var(--rc) 20%,#0c0a08),#070605 75%);box-shadow:inset 0 0 18px #000}
.tt-portrait canvas{position:absolute;inset:0;width:100%;height:100%;display:block}
.tt-main{display:flex;justify-content:space-between;align-items:baseline;gap:8px;padding:4px 7px 3px}
.tt-type{font-size:10.5px;color:var(--rc)}
.tt-type span{color:var(--dim)}
.tt-big{font-family:var(--display);font-size:15px;line-height:1.05;color:#fff4e0;font-variant-numeric:tabular-nums;display:flex;align-items:baseline;gap:5px;white-space:nowrap}
.tt-big small{font-family:var(--body);font-size:8.5px;letter-spacing:.1em;text-transform:uppercase;color:var(--dim)}
.tt-sec{padding:0 7px 3px}
.tt-sec+.tt-sec{border-top:1px solid rgba(58,47,35,.7);padding-top:3px}
.tt-lines{list-style:none;margin:0;padding:0}
.tt-lines li{position:relative;padding-left:9px;font-size:11px;line-height:1.3}
.tt-lines li::before{content:"";position:absolute;left:0;top:.5em;width:3px;height:3px;transform:rotate(45deg);background:currentColor;opacity:.7}
.tt-lines.plain li{padding-left:0}
.tt-lines.plain li::before{display:none}
.tt-lines.cols{display:grid;grid-template-columns:repeat(auto-fit,minmax(96px,1fr));column-gap:8px}
.tt-lines .affix{color:var(--affix)}
.tt-lines .power{color:var(--r-legendary);font-style:italic}
.tt.r-mythic .tt-lines .power{color:var(--r-mythic)}
.tt.r-unique .tt-name,.tt.r-unique .tt-type,.tt.r-unique .tt-lines .power{color:var(--r-unique);text-shadow:0 0 1px var(--r-unique-edge),0 1px 2px #12223a,0 0 10px var(--r-unique-edge)}
.tt.r-unique .flavor{color:var(--r-unique-edge)}
.tt-lines .num{color:#fff;font-variant-numeric:tabular-nums}
/* A gem's size on its card: five small diamonds in the rarity colours, smallest size first; the gem's own size is lit. */
.gem-steps{display:inline-flex;gap:3px;margin-left:6px;vertical-align:middle}
.gem-steps i{width:6px;height:6px;transform:rotate(45deg);background:color-mix(in srgb,var(--sc) 30%,#000);border:1px solid color-mix(in srgb,var(--sc) 60%,#000)}
.gem-steps i.on{background:var(--sc);box-shadow:0 0 6px var(--sc)}
.tt-lines .rng{color:var(--faint);font-size:9.5px;margin-left:4px;font-variant-numeric:tabular-nums}
.tt-lines .enh{color:var(--affix)}
.sockets{display:flex;align-items:center;gap:3px;font-size:10px;color:var(--dim)}
.sock{width:10px;height:10px;border-radius:50%;background:radial-gradient(circle at 45% 40%,#1b1714,#050404 70%);border:1px solid #4a3d2e;box-shadow:inset 0 1px 3px #000}
.set-name{color:var(--r-set);font-size:10.5px}
.set-pieces{display:flex;flex-wrap:wrap;gap:0 6px;font-size:9.5px;color:var(--faint)}
.set-pieces .have{color:var(--r-set)}
.set-bonus{font-size:10px;color:var(--faint)}
.set-bonus.on{color:var(--r-set)}
.note{color:var(--dim);font-size:9.5px}
.flavor{font-family:var(--serif);font-style:italic;color:var(--flavor);font-size:10.5px;line-height:1.25;text-align:center;padding:0 8px 3px;text-wrap:balance}
.tt-foot{padding:3px 7px 2px;border-top:1px solid var(--edge);display:grid;grid-template-columns:1fr 1fr;gap:0 8px;font-size:9.5px;color:var(--dim);font-variant-numeric:tabular-nums;line-height:1.35}
.tt-foot b{color:var(--text);font-weight:500}
.quality{grid-column:1/-1;display:grid;grid-template-columns:auto minmax(0,1fr) auto;align-items:center;gap:5px}
.quality .bar{height:4px;border-radius:3px;background:#0a0807;border:1px solid #2a221a;overflow:hidden}
.quality .bar i{display:block;height:100%;background:linear-gradient(90deg,#7a3e18,var(--rc));border-radius:3px}
.tt-actions{display:flex;align-items:center;gap:5px;padding:2px 7px 5px}
.tt-code{font-family:var(--mono);font-size:8.5px;color:var(--faint);user-select:all;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0;flex:1;text-align:right}
.loading{position:fixed;inset:0;display:grid;place-items:center;background:var(--ground);color:var(--dim);font-family:var(--display);letter-spacing:.1em;font-size:13px;z-index:5;transition:opacity .4s}
.loading[hidden]{display:none}
.load-box{width:min(320px,80vw);text-align:center}
.load-bar{height:4px;margin-top:8px;background:#0a0807;border:1px solid #2a221a;border-radius:3px;overflow:hidden}
.load-bar i{display:block;height:100%;width:0;background:linear-gradient(90deg,#7a3e18,#f28b2e)}
/* The profile chip at the top left (24-achievements.js): the name and title, and the level under them. It opens the profile
   pop-up with the achievements; its badge counts the achievements earned after the pop-up was last opened. */
.player-chip{grid-column:1;justify-self:start;position:relative;appearance:none;display:flex;flex-direction:column;align-items:flex-start;gap:2px;max-width:100%;min-width:0;
  padding:5px 16px 6px 12px;cursor:pointer;text-align:left;color:var(--text);font:inherit;border:1px solid var(--edge-hi);border-radius:3px;
  background:linear-gradient(180deg,rgba(44,34,22,.94),rgba(18,14,10,.95));box-shadow:inset 0 0 0 1px #000,inset 0 1px 0 rgba(255,220,160,.12),0 4px 14px rgba(0,0,0,.55)}
.player-chip:hover{border-color:var(--bronze-hi)}
.pc-name{max-width:100%;font-size:17px;line-height:1.15;color:var(--bronze-hi);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.pc-name b{font-weight:700;color:#ffe2ad}
.player-chip small{font-size:14px;font-weight:600;line-height:1.1;color:var(--text)}
/* The potions working this round: one tag each in the potion's colour. */
.round-sub .potions{display:flex;justify-content:center;gap:4px}
.round-sub .potions[hidden]{display:none}
.round-sub .potions i{font-style:normal;font-size:13px;font-weight:600;padding:1px 6px;border:1px solid var(--pc);border-radius:2px;color:var(--pc);background:rgba(10,8,6,.85)}
/* The Developer box in the Developer panel: for testing; it overrides what the shop sells. */
.field.dev{border:1px dashed #6a4a8a;border-radius:2px;padding:3px 4px;background:rgba(90,50,130,.12)}
.dev-h{color:#c8a8f0;margin-bottom:2px}
.reset-account{display:block;width:100%;margin-top:4px}
.reset-account[data-armed]{color:#ff9a88;border-color:#b04838}
.per-touch[hidden]{display:none}
/* "+1 s" under the large time (Bonus Time) and "Lucky! +1 item" over the chest (Lucky Touch). */
.time-bonus{position:fixed;left:0;top:0;z-index:3;pointer-events:none;font-family:var(--display);font-size:20px;color:#ffb050;text-shadow:0 2px 4px #000,0 0 10px rgba(255,140,40,.7)}
.lucky-pop{font-size:14px;color:#ffe98a}
/* The chest looks in the player panel use the backpack cards; a look the level has not reached is at 55% opacity. */
.pack.look .slots{font-size:9.5px;line-height:1.15;min-height:2.3em}
.pack.look.cur{border-color:#a7753a;box-shadow:inset 0 0 12px rgba(240,170,80,.28)}
.pack.look.shut{opacity:.55}
/* The Uniques tab: one card for each Unique, its picture, name and lore line; one not found is a dark silhouette with "?". */
.pack.uniq{position:relative;border-color:#8a90a8;background:radial-gradient(circle at 50% 32%,rgba(235,240,255,.16),var(--well) 70%)}
.pack.uniq img{width:min(84px,100%);height:auto;aspect-ratio:1;object-fit:contain;filter:drop-shadow(0 0 5px rgba(240,246,255,.85))}
.pack.uniq b{color:#f4f7ff;text-shadow:0 0 6px rgba(200,215,255,.6)}
.pack.uniq .slots{font-size:11px;line-height:1.2;min-height:2.4em}
.pack.uniq.shut{border-color:var(--edge);background:var(--well)}
.pack.uniq.shut img{filter:brightness(0) drop-shadow(0 0 1px rgba(255,255,255,.6)) drop-shadow(0 0 1px rgba(255,255,255,.6))}
.pack.uniq.shut b{color:var(--faint);text-shadow:none}
.pack.uniq i{position:absolute;left:0;right:0;top:34px;font:400 26px var(--display);font-style:normal;color:#c8d0e8;text-shadow:0 0 6px #000}
/* The player panel: name, title, Stats, the level over the achievements, the titles or the
   chest looks. Over the shop. */
.player-panel{position:fixed;left:50%;top:50%;transform:translate(-50%,-50%);z-index:8;width:min(560px,calc(100vw - 16px));max-height:calc(100vh - 24px);display:flex;flex-direction:column}
.player-panel[hidden]{display:none}
.pp-head{display:flex;align-items:flex-end;gap:12px;padding:6px 10px;border-bottom:1px solid var(--edge)}
.pp-who{display:flex;flex-direction:column;gap:1px;min-width:0;flex:1}
.pp-title{font-family:var(--display);font-size:12px;letter-spacing:.06em;color:var(--bronze-hi)}
.pp-name{display:flex;align-items:center;gap:6px}
.pp-name input{background:var(--well);border:1px solid var(--edge);border-radius:2px;color:var(--text);font:600 13px var(--body);padding:1px 5px;width:100%;max-width:200px;min-width:0}
/* Stats (32-stats.js) at the top right of the header, where the lifetime gold was (owner, 2026-10-09; the gold is in Stats, Records). */
.pp-stats{display:flex;align-items:center;gap:6px;height:40px;padding:0 12px 0 8px;cursor:pointer;color:#ffe2ad;font:400 16px var(--display);letter-spacing:.06em;
  border:1px solid #c99a4a;border-radius:3px;background:radial-gradient(circle at 50% 38%,#3c2b18,#120d08 80%);box-shadow:inset 0 0 0 1px #000,0 0 14px -4px rgba(255,190,80,.6)}
.pp-stats:hover{border-color:#ffe39a}.pp-stats svg{width:26px;height:26px;display:block}
.pp-next{padding:4px 10px 0;font-size:10.5px;color:var(--dim);display:flex;align-items:center;gap:6px;flex-wrap:wrap}
.pp-next b{color:var(--text)}
.pp-next .ach-bar{flex:1;min-width:80px}
.pp-tabs span{color:var(--text);font-size:11.5px;font-weight:600}
.pp-body{overflow:auto;padding:5px 10px 8px;min-height:0;flex:1;display:flex;flex-direction:column;gap:3px}
.ach-row{display:grid;grid-template-columns:26px minmax(0,1fr) auto;align-items:center;gap:7px;padding:3px 6px;border:1px solid var(--edge);border-radius:2px;background:var(--well)}
.ach-row .shop-icon{width:24px;height:24px;filter:grayscale(1) brightness(.5)}
.ach-row.got{border-color:#7a5a2a;background:linear-gradient(90deg,rgba(240,170,80,.12),var(--well) 60%)}
.ach-row.got .shop-icon{filter:none}
.ach-text{display:flex;flex-direction:column;min-width:0}
.ach-text b{font-family:var(--display);font-weight:400;font-size:12px;color:var(--bronze-hi)}
.ach-text span{font-size:10.5px;color:var(--text);line-height:1.2}
.ach-text small{font-size:9.5px;color:var(--dim);display:flex;align-items:center;gap:6px;font-variant-numeric:tabular-nums}
.ach-row.got .ach-text small{color:var(--good)}
.ach-row>i{font-style:normal;font-weight:700;font-size:11px;color:#ffd75e;font-variant-numeric:tabular-nums}
.ach-bar{display:inline-block;height:5px;width:110px;border-radius:3px;background:#0a0807;border:1px solid #2a221a;overflow:hidden;vertical-align:middle}
.ach-bar i{display:block;height:100%;background:linear-gradient(90deg,#7a3e18,#ffd75e)}
.title-row{display:flex;align-items:center;gap:8px;padding:3px 7px;border:1px solid var(--edge);border-radius:2px;background:var(--well);font-size:11px;color:var(--dim)}
.title-row b{font-family:var(--display);font-weight:400;font-size:12.5px;color:var(--faint);min-width:120px}
.title-row.got b{color:var(--text)}
.title-row.cur{border-color:#a7753a;box-shadow:inset 0 0 12px rgba(240,170,80,.28)}
.title-row.cur b{color:var(--bronze-hi)}
.title-row i{margin-left:auto;font-style:normal;color:#ffd75e}.tr-prog{flex:1;display:flex;align-items:center;gap:8px;min-width:0}.tr-prog .ach-bar{flex:1;min-width:60px}
/* The pop-up for an achievement, a new title or a new level: top centre, moved under the large time during a round
   and to the bottom of the shop or the player panel while one is open (Achievements in 24-achievements.js). */
.ach-toast{position:fixed;left:50%;top:84px;transform:translate(-50%,0);z-index:9;display:flex;align-items:center;gap:8px;padding:5px 12px 5px 7px;pointer-events:none;
  background:linear-gradient(180deg,rgba(60,40,16,.97),rgba(24,17,10,.97));border:1px solid #c98f2e;border-radius:3px;box-shadow:0 0 18px rgba(255,190,80,.45),0 4px 12px #000}
.ach-toast[hidden]{display:none}
.ach-toast .shop-icon{width:28px;height:28px}
.ach-toast span{display:flex;flex-direction:column;line-height:1.1}
.ach-toast small{font-size:11px;letter-spacing:.12em;text-transform:uppercase;color:#ffb050}
.ach-toast b{font-family:var(--display);font-weight:400;font-size:14px;color:#ffe2ad;max-width:calc(100vw - 70px)}
.ach-toast i{font-style:normal;font-weight:700;font-size:13px;color:#ffd75e;margin-left:4px}
/* The book on the Journal button, the quest tracker and the quest pop-up. */
.q-book{width:22px;height:22px;display:block}
/* The Journal and Options buttons in the top bar: big boxes with an icon and a label,
   with a red badge that counts what is new. */
.top-btn{position:relative;appearance:none;display:flex;align-items:center;gap:7px;height:46px;padding:0 16px 0 9px;border:1px solid var(--edge-hi);border-radius:3px;
  background:linear-gradient(180deg,rgba(51,40,28,.95),rgba(23,18,13,.96));color:#ffe2ad;font:400 18px var(--display);letter-spacing:.06em;cursor:pointer;white-space:nowrap;
  box-shadow:inset 0 0 0 1px #000,inset 0 1px 0 rgba(255,220,160,.12),0 4px 14px rgba(0,0,0,.55)}
.top-btn:hover{border-color:var(--bronze-hi)}
.top-btn[hidden]{display:none}
.top-btn .q-book{width:30px;height:30px;display:block}
.top-btn.gear{width:46px;padding:0;justify-content:center}
.badge{position:absolute;top:-6px;right:-6px;min-width:16px;height:16px;padding:0 4px;border-radius:8px;background:#d8402a;color:#fff;font:700 10px/16px var(--body);
  font-style:normal;text-align:center;box-shadow:0 0 0 1.5px #120d09,0 0 8px rgba(255,90,50,.7);pointer-events:none}
.badge[hidden]{display:none}
.btn .badge{position:static;display:inline-block;margin-left:4px;min-width:14px;height:14px;font-size:9px;line-height:14px;vertical-align:1px}
.btn .badge[hidden]{display:none}
.top-btn.gear svg{width:28px;height:28px;display:block}
/* The X that closes a window, in its top right corner: 24 px, and 32 px on a phone. */
.x-btn{position:absolute;top:4px;right:4px;z-index:2;width:24px;height:24px;display:grid;place-items:center;padding:0;border:1px solid var(--edge-hi);border-radius:2px;
  background:linear-gradient(180deg,#2a2119,#120e0a);color:var(--bronze-hi);cursor:pointer}
.x-btn:hover{border-color:var(--bronze-hi);color:#ffe2ad}
.x-btn svg{width:12px;height:12px;display:block}
.player-panel .pp-head{padding-right:38px;flex:none}
.player-panel .pp-next,.player-panel .pp-tabs{flex:none}
/* The quest tracker (25-quests.js): under the Journal button at the right, over the item card's column, in big type; each row
   is a face, the goal and the count. A tap opens the Journal. */
.q-track{position:absolute;right:0;top:calc(100% + 6px);width:300px;display:flex;flex-direction:column;gap:6px;padding:7px 10px 9px;text-align:left;cursor:default;pointer-events:none;
  color:var(--text);font:inherit;appearance:none}
.q-track[hidden]{display:none}
/* The quest tracker shows the quests and does not answer a tap (owner, 2026-10-06): taps reach the game under it. */
.qt-head{display:flex;align-items:center;gap:7px;font-family:var(--display);font-size:14px;letter-spacing:.12em;text-transform:uppercase;color:var(--bronze-hi)}
.qt-head .q-book{width:22px;height:22px}
.qt-row{display:grid;grid-template-columns:28px minmax(0,1fr) auto;align-items:center;gap:9px;font-size:17px;line-height:1.2}
.qt-row b{font-weight:500;color:var(--text);display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.qt-row i{font-style:normal;font-weight:800;font-size:17px;color:#ffd75e;font-variant-numeric:tabular-nums}
.qt-row.empty{grid-template-columns:minmax(0,1fr)}
.qt-row.empty b{color:var(--dim)}
.qt-face{width:28px;height:28px;border:1px solid var(--edge-hi);border-radius:2px;display:block}
/* The speech box (26-story.js) that Elowen and the people of Thornbury talk in: a portrait, the name and title (story-title), the words,
   one line at a time in big type, and for a quest a block: the quest, its count at the left and reward at the far right of one row,
   Accept and Not now. It sits low over a dimmed view, 900 px wide; a tap shows the next line. Elowen's lines in play are a pop-up. */
.story{position:fixed;inset:0;z-index:11;display:flex;align-items:flex-end;justify-content:center;padding:0 10px calc(22px + env(safe-area-inset-bottom,0px));
  background:linear-gradient(180deg,rgba(0,0,0,.05),rgba(0,0,0,.55));cursor:pointer}
.story[hidden]{display:none}
.story-box{position:relative;display:flex;gap:20px;width:min(900px,100%);padding:16px 60px 16px 16px;border:1px solid #a7753a;border-radius:3px;
  background:linear-gradient(180deg,rgba(44,33,20,.98),rgba(18,14,10,.98));box-shadow:inset 0 0 0 1px #000,0 0 30px rgba(240,180,90,.28),0 10px 30px #000}
.story-box::before,.story-box::after{content:"";position:absolute;width:12px;height:12px;border:2px solid var(--bronze);opacity:.85;pointer-events:none}
.story-box::before{left:-2px;top:-2px;border-right:0;border-bottom:0}.story-box::after{right:-2px;bottom:-2px;border-left:0;border-top:0}
.story-face{flex:none;width:150px;height:180px;overflow:hidden;border:2px solid #c98f2e;border-radius:4px;box-shadow:0 0 16px rgba(120,220,140,.3)}
.story-face.sq{height:150px;box-shadow:0 0 16px rgba(255,200,100,.3)}
.story-face svg{display:block;width:100%;height:100%}
.story-text{display:flex;flex-direction:column;gap:4px;min-width:0;flex:1}
.story-text b{font:400 32px/1.05 var(--display);letter-spacing:.04em;color:#ffe2ad}.story-title{display:inline-block;font-size:.72em;letter-spacing:.03em;color:#d9bc8c}
.story-text small{font-size:14px;font-weight:700;letter-spacing:.14em;text-transform:uppercase;color:#8fd0a0}
.story-text p{flex:1;margin:4px 0 0;min-height:2.6em;font:italic 500 28px/1.3 var(--serif);color:#f3e8d2}
.story-offer{display:flex;align-items:center;gap:18px;margin-top:8px;padding:12px 14px;border:1px solid #7a5c38;border-radius:4px;background:rgba(0,0,0,.35);cursor:default}
.story-offer[hidden]{display:none}
.so-q{flex:1;min-width:0;display:flex;flex-direction:column}
.so-q small{font-size:14px;font-weight:800;letter-spacing:.16em;text-transform:uppercase;color:var(--bronze-hi)}
.so-q b{margin-top:2px;font:800 27px/1.12 var(--body);letter-spacing:0;color:#fff4e0}
.so-row{display:flex;flex-wrap:wrap;align-items:center;gap:4px 18px;margin-top:5px;font-size:22px;font-weight:800;color:#f4d850}.so-row[hidden]{display:none}
.so-have,.so-pay{display:flex;align-items:center;gap:7px}.so-pay{margin-left:auto}.so-row svg{flex:none;width:24px;height:24px}.so-have:empty,.so-pay:empty{display:none}
.so-acts{display:flex;flex-direction:column;gap:8px;flex:none}.so-acts[hidden]{display:none}
.so-accept{appearance:none;width:200px;height:64px;cursor:pointer;font:400 26px var(--display);letter-spacing:.12em;text-transform:uppercase;color:#2a1606;
  border:1px solid #ffe39a;border-radius:6px;background:linear-gradient(180deg,#ffe08a 0%,#e9b54c 48%,#c48a2c 52%,#a8701f 100%);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.6),0 0 0 1px #3a2208,0 6px 16px rgba(0,0,0,.6),0 0 24px -6px rgba(255,200,90,.7)}
.so-accept:hover{filter:brightness(1.08)}
.so-accept:disabled{cursor:default;filter:none;font-size:18px;letter-spacing:.06em;color:#8c8170;border-color:#5a4632;
  background:linear-gradient(180deg,#3a2c1e,#241a11);box-shadow:none}
.so-later{appearance:none;height:40px;cursor:pointer;font:700 17px var(--body);color:var(--dim);border:1px solid var(--edge-hi);border-radius:4px;
 background:linear-gradient(180deg,#2a2119,#120e0a)}
.story-foot{display:flex;justify-content:space-between;align-items:center;font-size:18px;color:var(--dim)}
#storyNext{color:var(--bronze-hi);font-weight:700}
#storyClose{top:10px;right:10px;width:40px;height:40px}#storyClose svg{width:18px;height:18px}
.story-say{position:fixed;left:0;right:0;margin:auto;width:fit-content;z-index:9;display:flex;align-items:center;gap:8px;padding:5px 12px 5px 5px;pointer-events:none;
  max-width:min(580px,calc(100vw - 16px));
  background:linear-gradient(180deg,rgba(44,33,20,.97),rgba(18,14,10,.97));border:1px solid #a7753a;border-radius:3px;box-shadow:0 3px 12px #000}
.story-say[hidden]{display:none}
.story-mini{flex:none;width:44px;height:53px;border:1px solid #c98f2e;border-radius:2px}
.story-say span{display:flex;flex-direction:column;line-height:1.2;min-width:0}
.story-say small{font-size:12px;letter-spacing:.12em;text-transform:uppercase;color:#8fd0a0}
.story-say b{font-family:var(--serif);font-style:italic;font-weight:500;font-size:18px;color:#ffe2ad}
/* The Journal (25-quests.js), as big as the shop: a leather frame with the hanging JOURNAL sign and the X, the tabs Active and Done,
   and a parchment page with a row for each quest (a portrait, the giver, the quest in big bold type, a thick bar with the count and
   the reward), a red COMPLETE stamp on a quest whose goal is met, dashed rows for free quest slots, and the slots in use at the
   bottom. The quest pop-up shows under the top bar at the right. */
.journal{position:fixed;left:50%;top:96px;z-index:8;width:min(1060px,calc(100vw - 24px));height:min(640px,calc(100vh - 110px));transform:translateX(-50%);display:flex;
  flex-direction:column;padding:34px 22px 18px;color:var(--text);border:1px solid var(--edge-hi);border-radius:5px;background:linear-gradient(180deg,#2a1d12,#160f09);
  box-shadow:inset 0 0 0 1px #000,inset 0 0 0 5px #1a140f,inset 0 0 0 6px #3a2f23,0 30px 80px rgba(0,0,0,.85),0 0 0 100vmax rgba(4,3,2,.55)}
.journal[hidden]{display:none}
.jr-sign{top:-38px}.jr-sign .sh-board h2{font-size:30px;letter-spacing:.26em}
.jr-x{position:absolute;right:14px;top:14px;width:46px;height:46px}
.jr-tabs{display:flex;gap:10px;align-items:flex-end;padding:0 18px}
.jr-tab{appearance:none;cursor:pointer;display:flex;align-items:center;gap:10px;height:52px;padding:0 24px;font:400 23px var(--display);letter-spacing:.06em;color:#bfae8c;
  border:1px solid #5a4632;border-bottom:0;border-radius:6px 6px 0 0;background:linear-gradient(180deg,#3a2a1a,#241a10)}
.jr-tab.on{height:58px;color:#3a2410;border-color:#c8a868;background:linear-gradient(180deg,#f2e4c2,#e6d3a6)}
.jr-tab em{font:800 19px var(--body);font-style:normal;padding:1px 9px;border-radius:12px;background:rgba(0,0,0,.25)}
.jr-tab.on em{background:#3a2410;color:#f2e4c2}
.jr-page{flex:1;min-height:0;overflow-y:auto;display:flex;flex-direction:column;gap:10px;padding:14px 20px;border-radius:4px;color:#2a1a0c;
  background:radial-gradient(ellipse at 20% 10%,rgba(255,255,255,.35),transparent 50%),radial-gradient(ellipse at 90% 100%,rgba(120,80,30,.25),transparent 60%),
  linear-gradient(180deg,#efe1bd,#e2cf9f);box-shadow:inset 0 0 0 1px #c8a868,inset 0 0 40px rgba(120,80,30,.35)}
.jrow{position:relative;flex:none;display:flex;align-items:center;gap:20px;padding:10px 18px;border:1px solid rgba(90,60,25,.35);border-radius:5px;background:rgba(255,248,226,.45)}
.jrow .pf{flex:none;display:block;width:104px;height:104px;border:2px solid #8a6a3a;border-radius:4px;box-shadow:0 2px 6px rgba(60,30,5,.4)}
.jrow .tx{flex:1;min-width:0}
.jrow .gv{font:400 19px var(--display);letter-spacing:.04em;color:#7a4a1a}
.jrow .gl{margin-top:2px;font-size:29px;font-weight:800;line-height:1.1;color:#24160a}
.jrow .prog{display:flex;align-items:center;gap:14px;margin-top:9px}
.jrow .bar{flex:1;max-width:420px;height:16px;border-radius:9px;background:rgba(60,35,10,.22);box-shadow:inset 0 1px 2px rgba(0,0,0,.35);overflow:hidden}
.jrow .bar i{display:block;height:100%;border-radius:9px;background:linear-gradient(180deg,#e8c868,#b8862a)}
.jrow .bar.full i{background:linear-gradient(180deg,#7ad08a,#3a8a4a)}
.jrow .prog b{font-size:22px;font-weight:800;color:#3a2410;font-variant-numeric:tabular-nums}
.jrow .rw{display:flex;align-items:flex-start;gap:7px;margin-top:6px;font-size:20px;font-weight:700;color:#6a4a1a}
.jrow .rw svg{flex:none;width:22px;height:22px;margin-top:2px}.jrow .rw ul{margin:1px 0 0;padding:0;list-style:none}.jrow .rw li::before{content:'\2022\00a0'}
.jrow.complete{background:linear-gradient(90deg,rgba(122,208,138,.28),rgba(255,248,226,.45) 60%);border-color:rgba(58,138,74,.5)}
.jrow.complete .tx{padding-right:300px}.jrow.complete .gl{color:#2a3a1e}.jrow.complete .bar{max-width:300px}
.jrow.done{opacity:.85}
.stamp{position:absolute;right:26px;top:50%;margin-top:-38px;display:grid;place-items:center;height:76px;padding:0 22px;font:400 38px var(--display);letter-spacing:.12em;
  text-transform:uppercase;color:#a8321e;border:4px double #a8321e;border-radius:8px;transform:rotate(-9deg);opacity:.9;mix-blend-mode:multiply;pointer-events:none;
  background:radial-gradient(circle at 30% 40%,transparent 60%,rgba(168,50,30,.12))}
.stamp.new{animation:j-stamp .5s cubic-bezier(.3,1.6,.5,1) .3s both}
@keyframes j-stamp{from{opacity:0;transform:rotate(-9deg) scale(2.2)}to{opacity:.9;transform:rotate(-9deg) scale(1)}}
@keyframes j-stamp-phone{from{opacity:0;transform:rotate(-4deg) scale(2)}to{opacity:.9;transform:rotate(-4deg) scale(1)}}
.jrow.empty{justify-content:center;min-height:96px;border:2px dashed rgba(90,60,25,.35);background:none;font-size:22px;font-weight:700;color:#7a5a30}
.j-abandon{appearance:none;flex:none;cursor:pointer;height:44px;padding:0 18px;font:700 18px var(--body);color:#6a4a1a;border:1px solid rgba(90,60,25,.45);border-radius:4px;
  background:rgba(255,248,226,.5)}
.j-abandon:hover{background:rgba(255,248,226,.85)}
.jr-foot{display:flex;align-items:center;gap:12px;padding:12px 18px 0;font-size:19px;color:#bfae8c}
.jr-foot b{color:#ffe2ad}
.j-dots{display:flex;gap:6px}
.j-dots i{width:12px;height:12px;border-radius:50%;border:1px solid #8a6a3a;background:rgba(0,0,0,.4)}.j-dots i.on{border-color:#ffe39a;background:#f2c040}
.qt-row.done i{color:#7dff9a;letter-spacing:.06em}
/* Thornbury (29-village.js): the round's clock, the inventory, the spells and the quest tracker hide; one hint shows low in the
   middle in big letters (beside the coin pouch on a phone), and keeps still with Reduce motion on. */
body.in-village :is(.big-time,.round-sub,.inv,.per-touch,.spells,.q-track,#labels,.inspect,.story-say){visibility:hidden}
.v-hint{position:fixed;left:50%;bottom:30px;z-index:5;transform:translateX(-50%);display:flex;align-items:center;gap:12px;padding:10px 26px 11px;white-space:nowrap;
  pointer-events:none;font:400 30px var(--display);letter-spacing:.06em;color:#ffe2ad;border:1px solid #a7753a;border-radius:4px;
  background:linear-gradient(180deg,rgba(44,33,20,.95),rgba(18,14,10,.95));box-shadow:0 0 26px rgba(240,180,90,.25),0 8px 24px #000;animation:v-hint 2.2s ease-in-out infinite}
.v-hint[hidden]{display:none}
.v-hint svg{flex:none;width:30px;height:30px}
body:has(#reduceMotion:checked) .v-hint{animation:none}
@keyframes v-hint{0%,100%{box-shadow:0 0 18px rgba(240,180,90,.2),0 8px 24px #000}50%{box-shadow:0 0 34px rgba(240,180,90,.5),0 8px 24px #000}}
.q-toast{position:fixed;right:8px;z-index:9;display:flex;align-items:center;gap:10px;padding:6px 12px 6px 8px;pointer-events:none;max-width:min(480px,calc(100vw - 16px));
  background:linear-gradient(180deg,rgba(40,28,14,.96),rgba(20,14,8,.96));border:1px solid #a7753a;border-radius:3px;box-shadow:0 3px 10px #000}
.q-toast[hidden]{display:none}
.q-toast .q-book{flex:none;width:30px;height:30px}
.q-toast span{display:flex;flex-direction:column;line-height:1.15;min-width:0}
.q-toast small{font-size:12px;letter-spacing:.12em;text-transform:uppercase;color:#ffb050}
.q-toast b{font-size:16px;font-weight:600;color:#ffe2ad}
.q-toast i{font-style:normal;font-weight:700;font-size:15px;color:#ffd75e;white-space:nowrap}
/* The Options pop-up (gear button): the player's settings in big type. */
.options{width:min(460px,calc(100vw - 16px))}
.options .pp-head{padding:9px 46px 9px 14px}.options .pp-head .h{font-size:15px}
.opt-body{overflow:auto;padding:10px 16px 14px;display:flex;flex-direction:column;gap:10px;font-size:16px}
.opt-row{display:flex;align-items:center;justify-content:space-between;gap:12px;font-size:16px}
.opt-row select{width:auto;height:34px;padding:0 10px;font-size:16px}
.opt-checks{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px 14px}
.options .check{font-size:16px;gap:9px}.options .check input{width:18px;height:18px}
.options .field{padding:2px 0;border-bottom:0;gap:3px}.options .label{font-size:13px}.options .val{font-size:15px}
.options input[type=range]{height:24px}
.options input[type=range]::-webkit-slider-thumb{width:18px;height:18px;margin-top:-7.5px}
/* Phones: the room stays visible in the middle. The top bar is the profile chip and the buttons, the location box under them
   and the quest tracker; the item card is a short panel above the dock that scrolls inside itself. The dock sits 48 px above
   the bottom of the screen plus the safe area, clear of the band where a swipe up leaves the app; nothing to touch is in that
   band. The coin pouch sits at the left of the dock with the inventory beside it. */
@media (max-width:700px){
  .hud{grid-template-columns:minmax(0,1fr);grid-template-rows:auto minmax(0,1fr) auto auto;gap:5px;padding:6px 8px calc(48px + env(safe-area-inset-bottom,0px))}
  .controls{left:8px;width:auto;right:8px}
  .inspect{grid-row:3;grid-column:1;max-height:36vh;align-self:end}
  .tt-portrait{height:84px}
  .dock{grid-row:4;grid-column:1;grid-template-columns:auto minmax(0,1fr);gap:4px 8px}
  .top{grid-template-columns:minmax(0,1fr) auto;gap:6px}
  .top .right{grid-column:2;grid-row:1;gap:6px}
  .place-box{grid-row:2;grid-column:1/-1;justify-self:center;max-width:100%;overflow:hidden;text-overflow:ellipsis;padding:4px 16px 5px;font-size:18px}
  .pouch-col{grid-row:2;position:relative}
  .dev-toggle{position:absolute;left:0;bottom:calc(100% + 6px);white-space:nowrap}
  .inv{grid-row:2;grid-column:2;justify-self:center;margin-bottom:0;padding:4px}
  .per-touch{grid-row:1;grid-column:1/-1;justify-self:center;margin:0}
  .pouch{min-width:0}
  .pouch-ring{width:84px;height:84px;margin-left:0}
  .pouch-icon{width:62px;height:62px}
  .pouch .gold{min-width:84px;margin-left:0;font-size:20px}
  body:has(#shop:not([hidden])) .pouch-col{margin-left:8px}
  .inv-slot img{width:94%;height:94%}
  .hold-ring{width:34px;height:34px;margin:-17px 0 0 -17px}
  .spells{grid-row:2;grid-column:1;justify-self:end;margin:0 4px 14px 0}
  .hud:has(.spells:not([hidden])) .inspect{max-height:36vh}
  .shop{left:8px;right:8px;width:auto;transform:scale(var(--sh-k,1));grid-template-columns:minmax(0,1fr);grid-template-rows:50px auto auto auto;
    grid-template-areas:"head" "keeper" "wall" "counter";row-gap:8px;padding:10px 10px 12px}
  .sh-sign{left:12px;top:-22px;transform:none;align-items:flex-start}
  .sh-ropes{width:96px}
  .sh-board{padding:4px 18px 6px}
  .sh-board h2{font-size:19px}
  .gold-pop.sh-spent{font-size:18px}
  .sh-keeper{display:flex;align-items:flex-end;gap:6px;min-height:106px}
  .sh-kp{position:static;flex:none;width:106px;height:116px;margin-bottom:-8px}
  .sh-bubble{position:relative;left:auto;right:auto;bottom:auto;flex:1;align-self:center;margin-bottom:6px;padding:10px 14px 11px;font-size:18px;text-align:left}
  .sh-bubble::after{left:-10px;top:50%;bottom:auto;margin-top:-8px;border:8px solid transparent;border-right-color:#ecdbb2;border-left:0}
  .sh-wall{padding:12px 8px 4px}
  .sh-lantern{display:none}
  .sh-row{height:126px}.sh-row+.sh-row{margin-top:14px}
  .sh-plank{top:72px;height:17px}
  .sh-glow{width:96px;height:86px}
  .sh-ico{top:12px;width:58px;height:58px}
  .sh-brk{--l:12px;width:84px;height:116px}
  .sh-tag{top:79px;gap:4px;padding:9px 7px 3px}
  .sh-tag svg{width:16px;height:16px}
  .sh-tag b{font-size:18px}
  .sh-good.maxed .sh-tag b{font-size:16px}
  .sh-mark{left:calc(50% + 6px);top:18px;min-width:34px;height:27px;padding:0 7px;font-size:18px}
  .sh-new{top:-13px;padding:3px 7px 4px;font-size:15px}
  .sh-sold .sh-tag b{font-size:16px}
  .sh-five .sh-glow{width:72px}.sh-five .sh-brk{--l:10px;width:66px}.sh-five .sh-tag{gap:2px;padding:8px 4px 3px}.sh-five .sh-tag svg{width:13px;height:13px}
  .sh-five .sh-tag b{font-size:15px}.sh-five .sh-mark{left:auto;right:-2px;top:6px;min-width:26px;height:22px;padding:0 5px;font-size:14px}
  .sh-counter{flex-wrap:wrap;gap:10px 12px;min-height:0;margin:0;padding:16px 12px 12px}
  .sh-pic{width:76px;height:76px;padding:9px}
  .sh-info{max-width:calc(100% - 88px)}
  .sh-name{font-size:22px}
  .sh-line{margin-top:3px;font-size:18px}
  .sh-buy{flex:1 0 100%;width:auto;height:56px;gap:14px}
  .sh-buy .w{font-size:20px}
  .sh-buy .p{font-size:21px;gap:6px}
  .sh-buy .p svg{width:20px;height:20px}
  .player-chip{padding:4px 10px 5px 8px}
  .pc-name{font-size:14px}
  .player-chip small{font-size:13px}
  .top-btn{height:42px;padding:0 10px 0 6px;font-size:15px;gap:5px}
  .top-btn.gear{width:42px;padding:0}
  .top-btn .q-book{width:26px;height:26px}
  .x-btn{width:32px;height:32px;top:3px;right:3px}
  .x-btn svg{width:14px;height:14px}
  .player-panel .pp-head{padding-right:42px;min-height:40px}
  .tt-head{padding:4px 38px 3px;min-height:38px}
  .q-track{position:static;grid-row:3;grid-column:1/-1;width:auto;gap:3px;padding:5px 8px 6px}
  .qt-head{display:none}
  .qt-row{grid-template-columns:22px minmax(0,1fr) auto;gap:7px;font-size:15px}
  .qt-row i{font-size:15px}
  .qt-row b{-webkit-line-clamp:1}
  .qt-row.empty{grid-column:1/-1}
  .qt-face{width:22px;height:22px}
  .inspect{margin-top:0}
  .story{padding:0 8px calc(50px + env(safe-area-inset-bottom,0px))}
  .story-box{flex-wrap:wrap;gap:12px;padding:12px 12px 14px}
  .story-face{width:84px;height:101px}
  .story-face.sq{width:72px;height:72px}
  .story-text{flex:1 1 200px}
  .story-text b{font-size:25px;padding-right:40px}.story-title{text-wrap:balance}
  .story-text small{font-size:12px}
  .story-text p{font-size:21px}
  .story-foot{font-size:16px}
  .story-offer{flex-direction:column;align-items:stretch;gap:9px;margin:4px 0 0 -96px;width:calc(100% + 96px);padding:9px 10px}
  .story-face.sq + .story-text .story-offer{margin-left:-84px;width:calc(100% + 84px)}
  .so-q b{font-size:22px}
  .so-row{font-size:20px}
  .so-acts{flex-direction:row}
  .so-accept{flex:1;width:auto;height:54px;font-size:23px}
  .so-later{height:54px;padding:0 16px}
  #storyClose{top:8px;right:8px}
  .journal{left:6px;right:6px;top:calc(64px + env(safe-area-inset-top,0px));bottom:calc(52px + env(safe-area-inset-bottom,0px));width:auto;height:auto;transform:none;padding:30px 10px 10px}
  .jr-sign{left:50%;top:-24px;transform:translateX(-50%);align-items:center}
  .jr-sign .sh-board h2{font-size:23px;white-space:nowrap}
  .jr-x{right:8px;top:8px;width:42px;height:42px}
  .jr-tabs{padding:0 52px 0 6px;gap:6px}
  .jr-tab{flex:1;justify-content:center;height:48px;padding:0 10px;font-size:19px}
  .jr-tab.on{height:52px}
  .jr-page{flex:1;padding:10px 8px;gap:9px}
  .jrow{flex-wrap:wrap;gap:10px 12px;padding:10px}
  .jrow .pf{width:62px;height:62px}
  .jrow .tx{flex:1 1 200px}
  .jrow .gv{font-size:17px}
  .jrow .gl{font-size:22px}
  .jrow .prog b{font-size:18px}
  .jrow .bar{height:13px}
  .jrow .rw{font-size:18px}
  .jrow.complete .tx{padding-right:0}
  .jrow.complete .prog{display:none}
  .stamp{position:static;display:inline-grid;margin:8px 0 2px 4px;height:44px;padding:0 14px;font-size:23px;border-width:3px;transform:rotate(-4deg)}
  .stamp.new{animation-name:j-stamp-phone}
  .jrow.empty{min-height:66px;font-size:18px;text-align:center}
  .jr-foot{padding:10px 6px 0;font-size:18px}
  .j-abandon{height:40px;padding:0 14px;font-size:16px}
  .v-hint{left:106px;right:8px;bottom:calc(62px + env(safe-area-inset-bottom,0px));transform:none;justify-content:center;font-size:clamp(16px,5vw,21px);padding:9px 10px}
  .v-hint svg{width:24px;height:24px}
  /* The chest hint of a round (14-idle-hint.js) is the same bar across the room, its bottom measured over the dock. */
  .v-hint.chest-hint{left:16px;right:16px}
  /* With the item card closed, the quest and lore pop-up sits above the spell buttons (86 px tall with the gaps). */
  body:has(#spells:not([hidden])):has(#inspect[hidden]) .q-toast{margin-bottom:86px}
  .player-panel{top:auto;bottom:calc(52px + env(safe-area-inset-bottom,0px));transform:translateX(-50%);max-height:calc(100vh - 64px - env(safe-area-inset-bottom,0px))}
  .pp-head{flex-wrap:wrap;gap:6px}
  .ach-bar{width:70px}
  .ach-toast{top:96px}
  .ach-toast small{font-size:13px}
  .ach-toast.in-top span{flex-direction:row;align-items:baseline;gap:6px;min-width:0}
  .ach-toast.in-top small{flex:none}
  .ach-toast.in-top b{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
}
/* Narrow phones: the chip's line is a little smaller so the chip, Journal and Options share the first row. */
@media (max-width:400px){ .pc-name{font-size:13px} .top-btn{font-size:14px} }
.perf{position:fixed;top:34px;left:50%;transform:translateX(-50%);width:min(520px,calc(100vw - 12px));max-height:60vh;overflow:auto;padding:4px 7px;z-index:4;font-size:10px}
.perf.panel{backdrop-filter:none;-webkit-backdrop-filter:none}
.btn:disabled{opacity:.5;cursor:default}
.perf-head{display:flex;align-items:center;gap:6px;margin-bottom:3px;cursor:move;touch-action:none;user-select:none}
.perf.min .perf-body{display:none}
.perf.min{width:auto}
.perf-head .h{margin-right:auto}
.perf-line{color:var(--dim);margin:3px 0 2px}
.perf table{width:100%;border-collapse:collapse;font-variant-numeric:tabular-nums}
.perf th{text-align:left;color:var(--faint);font-weight:500}
.perf td,.perf th{padding:0 4px 0 0;vertical-align:top}
.perf td:not(:first-child):not(:last-child){text-align:right}


/* The sell-off at the end of a round: a dim layer over the whole page that takes every tap (taps do nothing until it ends).
   The panels stay above it, faded, except the dock with the coin pouch. Each item flies from its slot to the centre of the
   screen with its price, bursts, and its coins pour into the coin pouch. The moving parts are drawn in .sell-fx, above all.
   --sell-y: the height of that centre point (from sellCentre); the banner and the total show there, with a dark glow round the letters. */
.sell{position:fixed;inset:0;z-index:7;overflow:hidden;background:radial-gradient(circle at 50% var(--sell-y,56%),rgba(0,0,0,.42),rgba(0,0,0,.7))}
.sell[hidden]{display:none}
.hud.selling{z-index:8}
.hud.selling>:not(.dock){opacity:.35}
/* The panels draw no background blur during the sell-off, so the moving effects over them cost no blur work on the GPU. */
.hud.selling .panel{backdrop-filter:none;-webkit-backdrop-filter:none}
/* A legendary item dims the room further (.deep) while it is in the centre; a mythic one adds its veil (.myth-veil) just before its impact. */
.sell::before{content:"";position:absolute;inset:0;background:rgba(0,0,0,.66);opacity:0;transition:opacity .5s}
.sell.deep::before{opacity:1}
/* The effects layer does not clip: while it shakes (shake in 21-sell-off.js), what reaches past the screen fills the edges. */
.sell-fx{position:fixed;inset:0;z-index:9;pointer-events:none}
.sell-banner,.sell-total{position:absolute;left:50%;top:var(--sell-y,56%);transform:translate(-50%,-50%);font-family:var(--display);white-space:nowrap;text-align:center;pointer-events:none;
  padding:28px 44px;color:transparent;
  background:linear-gradient(180deg,#fff1cf 0%,#f0b860 55%,#a8641f 100%),radial-gradient(closest-side,rgba(0,0,0,.86),rgba(0,0,0,.62) 55%,rgba(0,0,0,0));
  -webkit-background-clip:text,padding-box;background-clip:text,padding-box}
/* The gold letters are the first background, cut to the text; the dark glow behind them is the second, a soft gradient over
   the padding. A blur filter is not used: three drop-shadow filters on the "Time is up" banner made its first frame take 48
   to 67 ms to draw. */
.sell-banner{font-size:clamp(26px,7vw,40px);letter-spacing:.06em}
.sell-total{font-size:clamp(30px,9vw,52px);line-height:1;width:max-content;max-width:92vw}
.sell-total small{display:block;font-family:var(--body);font-size:12px;letter-spacing:.12em;text-transform:uppercase;color:#ffe2ad;-webkit-text-fill-color:#ffe2ad;margin-top:4px}
.sell-banner[hidden],.sell-total[hidden]{display:none}
.spark{position:fixed;left:0;top:0;width:8px;height:8px;margin:-4px 0 0 -4px;border-radius:50%;pointer-events:none;background:radial-gradient(circle,#fffbe0,#ffd040 45%,transparent 75%)}
.poof{position:fixed;left:0;top:0;width:120px;height:120px;margin:-60px 0 0 -60px;border-radius:50%;pointer-events:none;
  background:radial-gradient(circle,rgba(255,240,200,.95) 0%,color-mix(in srgb,var(--rc) 70%,transparent) 35%,transparent 70%)}
/* The "+123g" that floats up from a gold pile when it is picked up, drawn above the flying coins. */
.gold-pop{position:fixed;left:0;top:0;z-index:1;pointer-events:none;font-weight:700;font-size:17px;color:#ffd75e;white-space:nowrap;font-variant-numeric:tabular-nums;
  text-shadow:0 1px 2px #000,0 0 8px rgba(0,0,0,.9),0 0 14px rgba(255,190,60,.6)}
.coin{position:fixed;left:0;top:0;width:14px;height:14px;margin:-7px 0 0 -7px;border-radius:50%;pointer-events:none;
  background:radial-gradient(circle at 35% 30%,#fff6c8,#f2c040 45%,#9a6410 100%);box-shadow:0 0 4px rgba(255,200,60,.8)}
.pouch .gold.counting{color:#ffe98a;text-shadow:0 0 8px rgba(255,200,60,.9),0 2px 3px #000}
/* The rarity tiers of the sell-off (17-ui.js). --rc is the item's light colour: its rarity colour, or a gem's own colour.
   #sellHero holds the 3D view of a rare, set or legendary item over the effects layer; everything else is in .sell-fx. */
.sell-hero{position:fixed;left:0;top:0;z-index:10;pointer-events:none;will-change:transform,opacity}
.sell-hero[hidden]{display:none}
.sell-hero canvas{display:block}
.coin.big{width:18px;height:18px;margin:-9px 0 0 -9px}
.trail{position:fixed;left:0;top:0;width:34px;height:34px;margin:-17px 0 0 -17px;border-radius:50%;pointer-events:none;
  background:radial-gradient(circle,#fff 0,var(--rc) 35%,transparent 70%)}
.ring{position:fixed;left:0;top:0;width:200px;height:200px;margin:-100px 0 0 -100px;border-radius:50%;pointer-events:none;border:3px solid var(--rc);
  box-shadow:0 0 16px var(--rc),inset 0 0 16px var(--rc)}
.dot{position:fixed;left:0;top:0;width:11px;height:11px;margin:-5.5px 0 0 -5.5px;border-radius:50%;pointer-events:none;
  background:radial-gradient(circle,#f6fff2,var(--rc) 45%,transparent 75%)}
/* The glow behind sold items: the sell-off's 512 px picture of an even disc of light (glowPic in 21-sell-off.js), shown larger. */
.back-glow{--rs:min(940px,150vmax);position:fixed;left:0;top:0;width:var(--rs);height:var(--rs);margin:calc(var(--rs) / -2) 0 0 calc(var(--rs) / -2);
  pointer-events:none;will-change:transform,opacity}
.hero-label{position:fixed;left:0;top:0;text-align:center;white-space:nowrap;pointer-events:none;color:var(--rc);font-family:var(--display);font-size:clamp(17px,4.8vw,26px);
  line-height:1.1;text-shadow:0 2px 4px #000,0 0 14px rgba(0,0,0,.95),0 0 24px color-mix(in srgb,var(--rc) 60%,transparent)}
.hero-label small{display:block;margin-top:2px;font-family:var(--body);font-size:11px;letter-spacing:.2em;text-transform:uppercase;color:#f3ead8}
.hero-price{position:fixed;left:0;top:0;transform:translateX(-50%);padding:1px 12px;font-size:clamp(22px,6vw,32px);font-weight:700;color:#ffd75e;white-space:nowrap;
  pointer-events:none;font-variant-numeric:tabular-nums;background:rgba(6,5,4,.9);border:1px solid #8a6a2a;border-radius:3px;text-shadow:0 0 10px rgba(255,190,60,.6)}
/* The price of a legendary item: larger, with a gold glow, so it reads as the cash-in under the large title. */
.hero-price.big{font-size:clamp(30px,9vw,52px);padding:2px 18px;border-color:#d9a640;box-shadow:0 0 26px -2px rgba(255,190,60,.75);
  text-shadow:0 0 14px rgba(255,200,70,.95),0 0 30px rgba(255,150,40,.6)}
/* "LEGENDARY" in large letters with the item's name under it. */
.legend-title{position:fixed;left:0;top:0;text-align:center;white-space:nowrap;pointer-events:none;line-height:1}
.legend-title b{display:block;font-family:var(--display);font-weight:400;font-size:clamp(42px,12vw,86px);letter-spacing:.12em;text-transform:uppercase;
  background:linear-gradient(180deg,#fffbe8 0%,color-mix(in srgb,var(--rc) 60%,#fff2c0) 45%,var(--rc) 70%,color-mix(in srgb,var(--rc) 50%,#3a1404) 100%);
  -webkit-background-clip:text;background-clip:text;color:transparent;filter:drop-shadow(0 3px 4px #000) drop-shadow(0 0 18px color-mix(in srgb,var(--rc) 70%,transparent))}
.legend-title span{display:block;margin-top:4px;font-family:var(--serif);font-style:italic;font-size:clamp(16px,4.6vw,24px);color:#ffe9c4;text-shadow:0 2px 4px #000,0 0 14px #000}
/* A mythic title ("MYTHIC", legendTitle): larger than a legendary one, lighter at the top, with a purple glow. */
.legend-title.mythic b{font-size:clamp(48px,13.5vw,100px);
  background-image:linear-gradient(180deg,#fbf0ff 0%,#e6b8ff 38%,var(--rc) 70%,color-mix(in srgb,var(--rc) 70%,#12001f) 100%);
  filter:drop-shadow(0 3px 4px #000) drop-shadow(0 0 20px rgba(190,90,255,.95)) drop-shadow(0 0 44px rgba(150,40,240,.7))}
/* A flash reaches 40 px past each screen edge, more than the largest shake, so it covers the whole screen while it shakes. */
.white-flash{position:fixed;inset:-40px;background:#fff;opacity:0;pointer-events:none}
.white-flash.purple{background:radial-gradient(circle at 50% 45%,#f6e6ff,#b04cff 55%,#3a0a5a)}
/* The mythic show's veil (mythicBuild): purple-black, it darkens the room a moment before the impact; it sits just under
   .sell-fx and outside it, like the Unique veil, so it stays still in the shake. Its purple rays share the rays' rule below. */
.myth-veil{position:fixed;inset:0;z-index:9;background:#0a0214;opacity:0;pointer-events:none}
/* The stars that burst out at a mythic or Unique impact (starBurst): four-pointed, white in the middle. */
.star{position:fixed;left:0;top:0;width:26px;height:26px;margin:-13px 0 0 -13px;pointer-events:none;
  clip-path:polygon(50% 0,60% 40%,100% 50%,60% 60%,50% 100%,40% 60%,0 50%,40% 40%);background:radial-gradient(circle,#fff 0,#f2dcff 30%,#b04cff 75%)}
.star.unique{background:radial-gradient(circle,#fff 0,#fff 35%,#bcd6f2 80%)}
/* The glow round the screen edges (edgeSparks) sits outside the effects layer, just under it like the veils, so it stays still. */
.edge-glow{position:fixed;inset:0;z-index:9;pointer-events:none;opacity:0;background:radial-gradient(ellipse 75% 75% at 50% 50%,transparent 62%,rgba(255,150,40,.32) 84%,rgba(255,200,80,.7) 100%)}
.edge-glow.mythic{background:radial-gradient(ellipse 75% 75% at 50% 50%,transparent 58%,rgba(150,50,240,.38) 82%,rgba(210,140,255,.8) 100%)}
.spark.mythic{background:radial-gradient(circle,#fbf0ff,#c070ff 45%,transparent 75%)}
/* The Unique show (21-unique-show.js): the dark veil (just under .sell-fx and outside it, so it stays still in the shake), the
   pillar of white light, the turning white rays and the wider second layer of them (.wide), the flashes over the 3D view (white,
   then pearl), the burst of white light at the impact (.uq-burst, the glow picture grown large), "UNIQUE" in large white
   letters with a band of light that runs along them, the item's name, lore line and price (over the coins), the white edge
   glow and sparks, and the 3D view's edge fading out so its glow never ends at a hard line. The mythic rays share the rays' rule. */
.uq-veil{position:fixed;inset:0;z-index:9;background:#000;opacity:0;pointer-events:none}
/* The soft dark disc behind the Unique item (uniqueShade, its picture drawn once): over every other part of the effects
   layer but the words, and under the 3D view, so even a white crystal stands out from the white light; --d: its width. */
.uq-shade{position:fixed;left:0;top:0;z-index:1;width:var(--d);height:var(--d);margin:calc(var(--d) / -2) 0 0 calc(var(--d) / -2);pointer-events:none;
  will-change:transform,opacity}
.uq-pillar{--pw:min(300px,46vw);position:fixed;left:50%;top:0;bottom:0;width:var(--pw);margin-left:calc(var(--pw) / -2);pointer-events:none;transform-origin:50% 100%;opacity:0;
  background:linear-gradient(90deg,transparent,rgba(158,195,230,.3) 22%,rgba(244,248,255,.75) 42%,#fff 50%,rgba(244,248,255,.75) 58%,rgba(158,195,230,.3) 78%,transparent)}
.uq-rays,.myth-rays{--rs:min(1300px,180vmax);position:fixed;left:0;top:0;width:var(--rs);height:var(--rs);margin:calc(var(--rs) / -2) 0 0 calc(var(--rs) / -2);pointer-events:none;
  will-change:transform,opacity}
.uq-rays.wide{--rs:min(1800px,240vmax)}
.myth-rays{--rs:min(1100px,160vmax)}
.uq-flash{z-index:11}
.uq-flash.pearl{background:radial-gradient(circle at 50% 45%,#fff,#e6f0ff 40%,#9ec3e6)}
.back-glow.uq-burst{--rs:min(1500px,210vmax)}
.uq-price{z-index:1}
.uq-title{position:fixed;left:0;top:0;z-index:1;text-align:center;white-space:nowrap;pointer-events:none;line-height:1}
.uq-title b{display:block;font-family:var(--display);font-weight:400;font-size:clamp(52px,15vw,96px);letter-spacing:.16em;text-transform:uppercase;
  background:linear-gradient(100deg,#9ec3e6 0%,#fff 22%,#fff 42%,#9ec3e6 50%,#fff 58%,#fff 78%,#9ec3e6 100%);background-size:300% 100%;
  -webkit-background-clip:text;background-clip:text;color:transparent;filter:drop-shadow(0 0 1px #4f7fb8) drop-shadow(0 3px 4px #000) drop-shadow(0 0 20px rgba(200,222,255,.9))}
.uq-name{position:fixed;left:0;top:0;z-index:1;transform:translateX(-50%);text-align:center;pointer-events:none;width:max-content;max-width:92vw}
.uq-name b{display:block;font-family:var(--display);font-weight:400;font-size:clamp(24px,6.4vw,36px);line-height:1.1;color:#fff;
  text-shadow:0 0 2px #4f7fb8,0 2px 4px #000,0 0 18px rgba(158,195,230,.95)}
.uq-name span{display:block;margin-top:4px;font-family:var(--serif);font-style:italic;font-size:clamp(17px,4.6vw,22px);color:#e6efff;text-shadow:0 2px 4px #000,0 0 12px #000}
.edge-glow.unique{background:radial-gradient(ellipse 75% 75% at 50% 50%,transparent 56%,rgba(158,195,230,.38) 80%,rgba(255,255,255,.85) 100%)}
.spark.unique{background:radial-gradient(circle,#fff,#dce9ff 45%,transparent 75%)}
.sell-hero.unique canvas{-webkit-mask-image:radial-gradient(closest-side,#000 85%,transparent);mask-image:radial-gradient(closest-side,#000 85%,transparent)}
/* A row of the sell-off: one card per item (its picture --w px wide, its name in its colour on at most two lines, its price
   counting up), and over the row its rarity, its count and its total. A legendary or mythic row has a large title. */
.row-card{position:fixed;left:0;top:0;width:var(--w);margin:calc(var(--w) / -2) 0 0 calc(var(--w) / -2);display:flex;flex-direction:column;align-items:center;
  pointer-events:none;will-change:transform,opacity}
.row-card img{width:var(--w);height:var(--w);flex:none;border:2px solid var(--rc);border-radius:3px;background:radial-gradient(circle at 50% 55%,color-mix(in srgb,var(--rc) 26%,#0c0a08),#0a0807 75%);
  box-shadow:0 0 16px -3px var(--rc),0 6px 12px rgba(0,0,0,.8)}
.row-card span{width:calc(var(--w) + 8px);margin-top:4px;font-size:18.5px;line-height:1.08;text-align:center;color:var(--rc);text-shadow:0 1px 2px #000,0 0 6px #000;
  display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}
.row-card b{margin-top:2px;padding:0 5px;font-size:15px;color:#ffd75e;white-space:nowrap;background:rgba(6,5,4,.88);border:1px solid #8a6a2a;border-radius:2px;font-variant-numeric:tabular-nums}
.row-card.small span{font-size:15px}
.row-card.small b{font-size:12px;padding:0 3px}
.row-head{position:fixed;left:0;top:0;transform:translate(-50%,-100%);display:flex;align-items:baseline;gap:8px;white-space:nowrap;pointer-events:none;text-shadow:0 2px 4px #000,0 0 12px #000}
.row-head .t{font-family:var(--display);font-size:20px;color:var(--rc);letter-spacing:.06em;text-transform:uppercase}
.row-head small{font-size:11px;color:#f3ead8;letter-spacing:.1em;text-transform:uppercase}
.row-head b{font-size:19px;color:#ffd75e;font-variant-numeric:tabular-nums;display:inline-block}
.row-head.top{flex-direction:column;align-items:center;gap:0}
/* The large title has no text shadow: Chrome draws a text shadow over clipped gradient text and darkens it. Its shadow is the filter. */
.row-head.top .t{font-size:clamp(42px,12vw,86px);line-height:1;letter-spacing:.12em;color:transparent;-webkit-background-clip:text;background-clip:text;text-shadow:none;
  background-image:linear-gradient(180deg,#fffbe8 0%,color-mix(in srgb,var(--rc) 55%,#fff) 42%,var(--rc) 72%,color-mix(in srgb,var(--rc) 75%,#000) 100%);
  filter:drop-shadow(0 3px 4px #000) drop-shadow(0 0 16px color-mix(in srgb,var(--rc) 70%,transparent))}
.row-head.top b{font-size:clamp(22px,6vw,32px);text-shadow:0 0 12px rgba(255,200,70,.9)}
/* A mythic row's title: lighter at the top, with a purple glow, larger than any legendary title. */
.row-head.top.mythic .t{font-size:clamp(48px,13.5vw,100px);
  background-image:linear-gradient(180deg,#fbf0ff 0%,#e6b8ff 38%,var(--rc) 70%,color-mix(in srgb,var(--rc) 70%,#12001f) 100%);
  filter:drop-shadow(0 3px 4px #000) drop-shadow(0 0 20px rgba(190,90,255,.95)) drop-shadow(0 0 44px rgba(150,40,240,.7))}
/* The round's results (showSellTotal): high on the screen under the top bar (its top is set by the script), "LOOT HAUL" in
   large gold letters, the total under it larger still, the count of items and gold, the count of each rarity sold,
   each in its rarity colour, and the best find in the middle as a stack: a small "Best find", its picture, its name in its
   colour and its price. Each gold line has its own gold letters, so the tall panel does not stretch one gradient over all.
   The letters have no filter: a drop shadow on letters this large made their first frame take hundreds of milliseconds to
   draw; the dark glow of the panel behind them keeps them clear. */
.sell-total{transform:translateX(-50%);padding:10px 44px 20px;white-space:normal;
  background:radial-gradient(closest-side,rgba(0,0,0,.88),rgba(0,0,0,.66) 60%,rgba(0,0,0,0));-webkit-background-clip:padding-box;background-clip:padding-box}
.sell-total .haul,.sell-total .haul-gold{display:block;font-weight:400;white-space:nowrap;color:transparent;-webkit-text-fill-color:transparent;
  background:linear-gradient(180deg,#fffbe8 0%,#f6c86a 50%,#b06a20 100%);-webkit-background-clip:text;background-clip:text}
.sell-total .haul{font-size:clamp(30px,8.5vw,60px);letter-spacing:.16em;text-transform:uppercase}
/* The total's box reaches below its letters (bottom padding), so the gold of the clipped letters also covers the tail of
   the g and the comma. */
.sell-total .haul-gold{font-size:124px;line-height:1.08;margin-top:2px;padding:0 .06em .17em}
.sell-total small{font-size:clamp(18px,4.6vw,28px);margin-top:12px}
.sell-total .sell-tiers,.sell-total .sell-best{display:block;font-family:var(--body);white-space:normal;color:#f3ead8;-webkit-text-fill-color:#f3ead8}
.sell-total .sell-tiers{font-size:clamp(16px,4vw,24px);letter-spacing:.06em;margin-top:10px}
.sell-tiers span{color:var(--rc);-webkit-text-fill-color:var(--rc)}
.sell-total .sell-best{display:flex;flex-direction:column;align-items:center;gap:3px;margin-top:20px;text-align:center}
.sell-best img{width:clamp(80px,20vw,120px);height:clamp(80px,20vw,120px);border:2px solid var(--rc);border-radius:4px;background:rgba(6,5,4,.8);box-shadow:0 0 18px -3px var(--rc)}
/* A short window keeps the Continue button clear of the results: a smaller best find picture. */
@media (max-height:820px){.sell-best img{width:clamp(72px,18vw,96px);height:clamp(72px,18vw,96px)}}
.sell-total .sell-best small{margin:0 0 2px;font-size:clamp(14px,3.6vw,16px)}
.sell-best b{display:block;max-width:86vw;font-family:var(--display);font-weight:400;font-size:clamp(20px,5vw,28px);line-height:1.1;letter-spacing:.02em;
  color:var(--rc);-webkit-text-fill-color:var(--rc)}
.sell-best i{font-style:normal;font-size:clamp(18px,4.4vw,24px);font-weight:700;color:#ffd75e;-webkit-text-fill-color:#ffd75e;font-variant-numeric:tabular-nums}
/* While the results show, the empty inventory hides, so the Continue button never sits on it, and an achievement pop-up
   shows low on the screen, where the inventory was, not over LOOT HAUL. The results stay unhidden inside the hidden sell-off
   layer until the next sell-off, so both rules ask for the layer too. */
body:has(#sell:not([hidden]) #sellTotal:not([hidden])) .inv{visibility:hidden}
body:has(#sell:not([hidden]) #sellTotal:not([hidden])) .ach-toast{top:auto;bottom:max(70px,15vh)}
/* The Continue button under the results (its top is set by the script); the sell-off waits for it. */
.sell-continue{position:fixed;left:50%;top:0;transform:translateX(-50%);pointer-events:auto;cursor:pointer;min-width:220px;padding:12px 48px;
  font-family:var(--display);font-size:clamp(24px,6vw,34px);letter-spacing:.08em;color:#1a1004;border:2px solid #ffe7a6;border-radius:6px;
  background:linear-gradient(180deg,#ffe48e,#e0a63a 55%,#a8641f);box-shadow:0 0 22px rgba(255,190,60,.55),0 6px 14px rgba(0,0,0,.7)}
.sell-continue:hover,.sell-continue:focus-visible{filter:brightness(1.12);outline:none}
/* "Tap to skip" (21-sell-skip.js): faint gold letters at the foot of the sell-off, just over the dock (its bottom is set by
   the script), while a stage can be skipped. */
.sell-skip{position:absolute;left:50%;bottom:200px;transform:translateX(-50%);pointer-events:none;white-space:nowrap;font-family:var(--display);
  font-size:15px;letter-spacing:.1em;color:#ffe2ad;text-shadow:0 1px 3px #000,0 0 10px rgba(0,0,0,.9);opacity:0;transition:opacity .4s}
.sell-skip.on{opacity:.5}
/* The name under each item of a group of legendary or mythic items (sellGroup), in its colour, on at most four lines (two in
   a group of more than four); the script sets its width and size from groupLayout (at most this clamp). .plain: the narrower
   italic of the single show's name line, for names too long for the display font in narrow places. */
.group-label{position:fixed;left:0;top:0;transform:translateX(-50%);text-align:center;pointer-events:none;color:var(--rc);font-family:var(--display);
  font-size:clamp(17px,2vw,26px);line-height:1.1;text-shadow:0 2px 4px #000,0 0 14px rgba(0,0,0,.95),0 0 24px color-mix(in srgb,var(--rc) 60%,transparent)}
.group-label.plain{font-family:var(--serif);font-style:italic}
/* The dark veil over the top bar while a group takes its band (bandVeil): just under .sell-fx and outside it, like the mythic
   veil, so it stays still in the shake; its height is set by the script, and its foot fades out. */
.band-veil{position:fixed;left:0;right:0;top:0;z-index:9;pointer-events:none;opacity:0;
  background:linear-gradient(180deg,rgba(5,4,3,.94),rgba(5,4,3,.94) calc(100% - 28px),rgba(5,4,3,0))}
/* What the helpers brought (helpersShow, 21-sell-helpers.js): the panel in the middle, YOUR HELPERS in gold letters, one row
   per helper (its shop picture, its name with a small line under it, and a large gold number), and the total line. */
.helpers-show{position:fixed;left:50%;top:45%;transform:translate(-50%,-50%);width:min(720px,94vw);padding:16px 26px 20px;pointer-events:none;text-align:center;
  background:radial-gradient(closest-side,rgba(0,0,0,.86),rgba(0,0,0,.66) 65%,rgba(0,0,0,0))}
.hs-title{display:block;font-family:var(--display);font-weight:400;font-size:clamp(34px,8vw,60px);letter-spacing:.12em;text-transform:uppercase;color:transparent;
  background:linear-gradient(180deg,#fffbe8,#f6c86a 50%,#b06a20);-webkit-background-clip:text;background-clip:text}
.hs-row{display:grid;grid-template-columns:56px minmax(0,1fr) auto;align-items:center;gap:14px;min-height:64px;margin-top:6px;text-align:left}
.hs-row .shop-icon{width:56px;height:56px;filter:drop-shadow(0 0 8px rgba(255,200,80,.45))}
.hs-name{font-family:var(--display);font-size:clamp(18px,4vw,26px);line-height:1.1;color:#f3ead8;text-shadow:0 2px 4px #000}
.hs-name small{display:block;margin-top:2px;font-family:var(--body);font-size:14px;letter-spacing:.12em;text-transform:uppercase;color:#cdbb98}
.hs-num{font-size:clamp(24px,7vw,40px);font-weight:700;color:#ffd75e;white-space:nowrap;font-variant-numeric:tabular-nums;text-shadow:0 0 12px rgba(255,190,60,.7),0 2px 3px #000}
.hs-total{margin-top:12px;font-family:var(--display);font-size:clamp(20px,5vw,30px);color:#ffe9b0;text-shadow:0 2px 4px #000,0 0 14px #000}
.hs-total b{font-weight:400;color:#ffd75e}
/* On a phone the icon sits beside the name and the number, and a long number line ("2 items, worth 2,756 gold") wraps, so it
   never runs off the screen. */
@media (max-width:700px){.sell-total{padding:8px 12px 16px}.hs-title{font-size:30px;letter-spacing:.06em}
  .hs-row{grid-template-columns:44px minmax(0,1fr);gap:4px 10px}.hs-row .shop-icon{width:44px;height:44px;grid-row:span 2}
  .hs-num{font-size:28px;line-height:1.1;white-space:normal}}


/* The top bar folded away (owner, 2026-10-09): the profile chip is only the player's picture (Avatar.portraitURL, 30-avatar.js)
   in a round frame, and the Journal button only its book; a tap opens the profile or the Journal as before, and each badge
   stays at the corner. The name, title and level, the word Journal and an
   achievement's "Earned" (24-achievements.js) stay in the page for screen readers only. The place's
   name stands between them in the same row (on a phone too), and the quest tracker comes right under that row. */
.player-chip{display:grid;place-items:center;width:46px;height:46px;padding:0;border-radius:50%}
.pc-pic{display:block;width:38px;height:38px;border:1px solid #c98f2e;border-radius:50%;background:#2a1f15;box-shadow:0 0 0 1px #000}
.player-chip>.pc-name,.player-chip>small,#journalBtn .tb-label,.ach-earned{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}
#journalBtn{width:46px;padding:0;justify-content:center}
.top{align-items:center}
/* The picture in the profile pop-up, beside the name field: a tap opens the look pop-up; the gold pencil shows it can be changed. */
.pp-pic{position:relative;flex:none;align-self:center;width:84px;height:84px;padding:0;cursor:pointer;border:2px solid #c98f2e;border-radius:50%;
  background:#2a1f15;box-shadow:0 0 0 1px #000,0 0 14px rgba(240,180,90,.25)}
.pp-pic:hover{border-color:#ffe08a}
.pp-pic img{display:block;width:100%;height:100%;border-radius:50%}
.pp-pen{position:absolute;right:-5px;bottom:-3px;width:30px;height:30px;display:grid;place-items:center;border:1px solid #3a2208;border-radius:50%;color:#2a1606;
  background:linear-gradient(180deg,#ffe08a,#c48a2c);box-shadow:0 2px 6px rgba(0,0,0,.6)}
.pp-pen svg{width:16px;height:16px;display:block}
/* The name row under the first line of Elowen's greeting (26-story.js): the player's picture, Customize and the name field.
   A tap in the row never moves to the next line. */
.story-name{display:flex;align-items:center;gap:12px;margin-top:8px;cursor:default}
.story-name[hidden]{display:none}
.sn-pic{flex:none;width:52px;height:52px;padding:0;cursor:pointer;overflow:hidden;border:2px solid #c98f2e;border-radius:50%;background:#2a1f15}
.sn-pic img{display:block;width:100%;height:100%}
.sn-custom{flex:none;height:50px;padding:0 20px;cursor:pointer;font:400 19px var(--display);letter-spacing:.08em;color:#ffe2ad;border:1px solid #a7753a;border-radius:4px;
  background:linear-gradient(180deg,#6a3d17,#3b200c);box-shadow:inset 0 1px 0 rgba(255,210,150,.25),0 4px 10px rgba(0,0,0,.5)}
.sn-custom:hover{filter:brightness(1.15)}
.sn-input{flex:1;min-width:0;max-width:360px;height:50px;padding:0 14px;cursor:text;font:600 22px var(--body);color:#fff4e0;background:rgba(0,0,0,.45);
  border:1px solid #7a5c38;border-radius:4px}
.sn-input::placeholder{color:#8c8170;font-weight:500}
.sn-input:focus{outline:none;border-color:var(--bronze-hi);box-shadow:0 0 0 2px rgba(224,187,122,.35)}
.dev-btn{display:block;width:100%;margin-top:4px}
/* The look pop-up (30-avatar-panel.js), over everything, the speech box and the profile pop-up included: the title and the X,
   the preview (the portrait and the running flipbook) at the left, a row for each part at the right, Random and Done. */
.av-wrap{position:fixed;inset:0;z-index:12;display:grid;place-items:center;padding:12px;background:rgba(0,0,0,.55);cursor:default}
.av-wrap[hidden]{display:none}
.av-panel{width:min(820px,100%);max-height:100%;display:flex;flex-direction:column;overflow:hidden}
.av-head{position:relative;display:flex;align-items:center;min-height:52px;padding:10px 56px 8px 18px;border-bottom:1px solid var(--edge)}
.av-head .h{font-size:22px;letter-spacing:.16em}
#avatarClose{top:9px;right:9px;width:36px;height:36px}#avatarClose svg{width:16px;height:16px}
.av-body{display:flex;gap:22px;min-height:0;overflow:auto;padding:16px 18px}
.av-preview{flex:none;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:12px;width:176px;padding:14px 8px;border:1px solid #5a4632;
  border-radius:4px;background:radial-gradient(circle at 50% 35%,rgba(240,190,110,.18),rgba(0,0,0,.35))}
.av-big{display:block;width:140px;height:140px;border:2px solid #c98f2e;border-radius:50%;box-shadow:0 0 18px rgba(240,180,90,.3)}
.av-run{display:block}
.av-rows{flex:1;min-width:0;display:flex;flex-direction:column;gap:10px}
.av-label{margin-bottom:4px;font-size:16px;font-weight:700;letter-spacing:.04em;color:var(--bronze-hi)}
.av-label b{margin-left:6px;font-weight:600;color:#f3e8d2}
.av-opts{display:flex;flex-wrap:wrap;gap:7px;padding:3px}
.av-opt{flex:none;appearance:none;padding:0;cursor:pointer;overflow:hidden;border:2px solid #5a4632;border-radius:50%;background:#1a140e}
.av-opt:hover{border-color:var(--bronze-hi)}
.av-opt[aria-pressed="true"]{border-color:#f2c040;box-shadow:0 0 0 2px #f2c040,0 0 12px rgba(242,192,64,.6)}
.pics .av-opt{width:56px;height:56px}
/* A friendship look still locked (30-avatar-panel.js): dimmed, with a lock and the friend's name across its foot. */
.av-opt{position:relative}.av-opt.locked>img,.av-opt.locked>i{opacity:.4;filter:grayscale(.6)}
.av-by{position:absolute;left:0;right:0;bottom:0;display:flex;align-items:center;justify-content:center;gap:2px;padding-bottom:3px;font:800 9px/12px var(--body);color:#ffd75e;background:rgba(10,6,2,.78)}.av-by svg{width:8px;height:8px}
.pics .av-opt img{display:block;width:100%;height:100%}
.dots .av-opt{width:40px;height:40px}
.dots .av-opt i{display:block;width:100%;height:100%}
.av-foot{display:flex;justify-content:flex-end;gap:10px;padding:10px 18px 14px;border-top:1px solid var(--edge)}
.av-foot .btn{height:46px;padding:0 24px;font:400 18px var(--display);letter-spacing:.08em}
@media (max-width:700px){
  .player-chip{width:42px;height:42px;padding:0}
  .pc-pic{width:34px;height:34px}
  #journalBtn{width:42px;padding:0}
  .top{grid-template-columns:auto minmax(0,1fr) auto}
  .top .right{grid-column:3}
  /* A long name ("Old Forest Shrine VIII") takes two lines rather than run out of the row. */
  .place-box{grid-row:1;grid-column:2;padding:3px 8px 4px;font-size:clamp(13px,4.2vw,18px);letter-spacing:.06em;line-height:1.05;white-space:normal;text-wrap:balance}
  .q-track{grid-row:2}
  .pp-pic{width:72px;height:72px}
  .pp-pen{width:26px;height:26px}
  /* On a phone the row spans the speech box under the portrait, as the quest block does. */
  .story-name{gap:8px;margin:4px 0 0 -96px;width:calc(100% + 96px)}
  .sn-pic{width:44px;height:44px}
  .sn-custom{height:44px;padding:0 12px;font:700 17px var(--body);letter-spacing:0}
  .sn-input{height:44px;padding:0 10px;font-size:18px}
  .av-wrap{padding:8px}
  .av-head{min-height:46px;padding:8px 50px 6px 14px}
  .av-head .h{font-size:19px}
  #avatarClose{top:6px;right:6px;width:34px;height:34px}
  .av-body{flex-direction:column;gap:12px;padding:12px}
  .av-preview{flex-direction:row;width:auto;gap:20px;padding:8px}
  .av-big{width:104px;height:104px}
  .av-rows{gap:8px}
  .av-label{font-size:15px;margin-bottom:2px}
  /* Each row scrolls sideways inside the panel. */
  .av-opts{flex-wrap:nowrap;overflow-x:auto;scrollbar-width:none}
  .av-foot{padding:8px 12px 10px}
  .av-foot .btn{flex:1;height:44px;font-size:17px}
}
/* The profile pop-up (#playerPanel, 24-achievements.js) has tabs, so its top stays put under the top bar and its height is
   fixed: switching tabs never moves it, and a long tab scrolls inside (owner, 2026-10-09). The Journal and Stats are placed
   the same way. On a phone it reaches down to the dock, as the Journal does. */
#playerPanel{top:calc(64px + env(safe-area-inset-top,0px));transform:translateX(-50%);height:min(720px,calc(100vh - 76px - env(safe-area-inset-top,0px)))}
@media (max-width:700px){ #playerPanel{height:auto;max-height:none} }


/* The level ring (24-level-ring.js; owner, 2026-10-10, "Gold ring" of the level bar ideas) round the picture in the profile
   chip and in the profile pop-up: a dark track filled in gold from the bottom (from 180deg), clockwise, as far as --p (0 to 1),
   with a bright dot at the end of the fill and the level on a gold tag at the bottom, where the fill starts and ends. In the
   chip a new level pops the tag with a flash and sparks, and gold earned shows "+1,250g" and the numbers for a moment, right
   under the chip's corner, below the place's name. */
.lv-wrap{--p:0}
.lv-ring{position:absolute;inset:0;border-radius:50%;pointer-events:none;
  background:conic-gradient(from 180deg,#fff2a8 0deg,#ffd84a calc(var(--p)*180deg),#e8a224 calc(var(--p)*360deg),#1a1008 0);
  -webkit-mask:radial-gradient(farthest-side,transparent calc(100% - 4px),#000 calc(100% - 3.5px));mask:radial-gradient(farthest-side,transparent calc(100% - 4px),#000 calc(100% - 3.5px))}
.lv-tip{position:absolute;inset:0;border-radius:50%;pointer-events:none;transform:rotate(calc(180deg + var(--p)*360deg))}
.lv-tip::before{content:"";position:absolute;left:50%;top:-1px;width:6px;height:6px;margin-left:-3px;border-radius:50%;background:#fff;box-shadow:0 0 7px 2px #ffd060}
.lv-tag{position:absolute;left:50%;bottom:-5px;z-index:2;min-width:20px;height:16px;padding:0 5px;display:grid;place-items:center;transform:translateX(-50%);
  border-radius:8px;border:2px solid #2a1406;background:linear-gradient(180deg,#ffe08a,#c48a2c);box-shadow:0 2px 3px rgba(0,0,0,.6);pointer-events:none;
  font:800 11px/1 var(--body);color:#fff;font-variant-numeric:tabular-nums;text-shadow:-1px -1px 0 #2a1406,1px -1px 0 #2a1406,-1px 1px 0 #2a1406,1px 1px 0 #2a1406}
.lv-tag.pop{animation:lv-pop .8s cubic-bezier(.3,1.6,.5,1)}
@keyframes lv-pop{0%{transform:translateX(-50%) scale(1)}25%{transform:translateX(-50%) scale(1.7) rotate(-8deg)}55%{transform:translateX(-50%) scale(.9)}100%{transform:translateX(-50%) scale(1)}}
.player-chip.lv-wrap{border:0;background:#120a04;box-shadow:0 0 0 1px #000,0 0 0 2px #4a3218,0 3px 8px rgba(0,0,0,.6)}
.lv-flash{position:absolute;left:50%;top:100%;z-index:3;width:120px;height:120px;margin:-60px 0 0 -60px;border-radius:50%;pointer-events:none;opacity:0;
  background:radial-gradient(circle,rgba(255,240,180,.95),rgba(255,190,80,.35) 30%,transparent 65%)}
.lv-flash.go{animation:lv-flash .7s ease-out}
@keyframes lv-flash{0%{opacity:0}12%{opacity:1}100%{opacity:0}}
.lv-spark{position:absolute;left:50%;top:100%;z-index:4;width:6px;height:6px;margin:-3px;border-radius:50%;pointer-events:none;background:#fff1a0;
  box-shadow:0 0 8px #ffb030,0 0 2px #fff;animation:lv-spark .8s ease-out forwards}
@keyframes lv-spark{0%{transform:translate(0,0) scale(1.2);opacity:1}100%{transform:translate(var(--dx),var(--dy)) scale(.2);opacity:0}}
.lv-peek{position:absolute;left:calc(100% + 2px);top:calc(100% - 4px);z-index:5;padding:3px 8px;border-radius:10px;opacity:0;transform:translateX(-8px);
  transition:opacity .3s,transform .3s;background:rgba(10,7,4,.88);border:1px solid #6b5436;pointer-events:none;
  font:800 12px var(--body);color:#fff;font-variant-numeric:tabular-nums;white-space:nowrap}
.lv-peek.on{opacity:1;transform:none}
.lv-gain{position:absolute;left:calc(100% + 10px);top:calc(100% + 18px);z-index:5;pointer-events:none;font:800 14px var(--body);color:#ffd75e;white-space:nowrap;
  text-shadow:0 1px 0 #000,0 0 6px #000;animation:lv-gain 1.2s ease-out forwards}
@keyframes lv-gain{0%{opacity:0;transform:translateY(6px)}20%{opacity:1}100%{opacity:0;transform:translateY(-12px)}}
/* In the profile pop-up the ring stands round the big picture's frame, with a larger tag, and the numbers are in the line under. */
.pp-pic.lv-wrap{margin:9px}
.pp-pic .lv-ring,.pp-pic .lv-tip{inset:-9px}
.pp-pic .lv-ring{-webkit-mask:radial-gradient(farthest-side,transparent calc(100% - 6px),#000 calc(100% - 5.5px));mask:radial-gradient(farthest-side,transparent calc(100% - 6px),#000 calc(100% - 5.5px))}
.pp-pic .lv-tip::before{top:-1px;width:8px;height:8px;margin-left:-4px}
.pp-pic .lv-tag{bottom:-17px;min-width:28px;height:20px;border-radius:10px;font-size:13px}
.pp-pic .pp-pen{z-index:3}
.pp-next .lv-nums{font-weight:800;color:#ffd75e;font-variant-numeric:tabular-nums}
@media (prefers-reduced-motion:reduce){ .lv-tag.pop,.lv-flash.go,.lv-gain,.lv-spark{animation:none}.lv-peek{transition:none} }
/* A secret achievement not earned yet (24-achievements.js): a dashed, dim row with "???" (owner, 2026-10-10). */
.ach-row.secret{border-style:dashed;opacity:.75}.ach-row.secret .ach-text b{letter-spacing:.3em;color:var(--dim)}


/* The travel screen (31-travel.js): over everything but the loading screen's first showing, which ends before any travel.
   It fades in over --tr-ms; the tip and the strip (.tr-body) show once it is fully in. The painted night (.tr-scene, a canvas
   31-travel.js puts first in #travel) lies under the grain; the background here is the same night sky in plain gradients. */
.travel{position:fixed;inset:0;z-index:12;opacity:0;transition:opacity var(--tr-ms,350ms) ease;pointer-events:auto;user-select:none;-webkit-user-select:none;
  background:linear-gradient(#0e1631 0%,#1c2a4d 45%,#34466c 62%,#1a2c2a 82%,#10201a 100%);touch-action:none}
.travel[hidden]{display:none}
.travel.on{opacity:1}
.travel .tr-scene{position:absolute;inset:0;width:100%;height:100%;display:block;pointer-events:none}
.travel .tr-grain{position:absolute;inset:0;background-image:var(--tr-grain,none);background-size:128px 128px;opacity:.32;pointer-events:none}
.travel .tr-body{position:absolute;inset:0;opacity:0;transition:opacity .25s ease}
.travel.shown .tr-body{opacity:1}
.travel .tr-tip{position:absolute;left:16px;right:16px;bottom:calc(var(--tr-strip,136px) + 11vh + env(safe-area-inset-bottom,0px));margin:0 auto;max-width:32em;
  text-align:center;font-family:var(--body);font-size:28px;line-height:1.4;color:#f6ead0;
  text-shadow:0 1px 3px rgba(4,6,16,.85),0 0 16px rgba(8,12,30,.8)}
.travel .tr-tip small{display:block;margin-bottom:6px;font-family:var(--display);font-size:18px;letter-spacing:.22em;text-transform:uppercase;color:#f0c97e}
.travel .tr-tip p{margin:0}
/* The gold marker in front of a tip about "!" or "?" (31-travel.js MARK_SVG), with the soft glow of the markers in Thornbury. */
.travel .tr-tip .tr-mark{display:inline-block;width:1.2em;height:1.2em;vertical-align:-.25em;filter:drop-shadow(0 0 5px rgba(255,190,70,.85))}
.travel .tr-run{position:absolute;left:0;bottom:calc(14px + env(safe-area-inset-bottom,0px));width:100%;height:var(--tr-strip,136px);display:block}
/* On a phone (a tall screen) the strip sits 22% of the height up, so the night above it is not one tall empty sky: the moon
   and stars, the tip, the hills, the path with the party, and dark ground under it share the height. 31-travel.js layout()
   uses the same 22% when the strip is not laid out. */
@media (max-width:700px){
  .travel .tr-run{bottom:calc(22vh + env(safe-area-inset-bottom,0px))}
  .travel .tr-tip{font-size:21px;bottom:calc(var(--tr-strip,136px) + 30vh + env(safe-area-inset-bottom,0px))}
  .travel .tr-tip small{font-size:15px;margin-bottom:4px}
}


/* Stats (32-stats.js), opened from the Stats button in the profile pop-up (owner, 2026-10-09: no button over the room). */
/* The panel, as big as the Journal: a dark frame with gold edges, the hanging STATS sign and the X, the tabs, the caption with
   the range switch, three big gold numbers, and the charts on a black ground. A tap on the dimmed room closes it. */
.stats-wrap{position:fixed;inset:0;z-index:8;background:rgba(4,3,2,.58)}
.stats-wrap[hidden]{display:none}
.stats-panel{position:absolute;left:50%;top:96px;width:min(1060px,calc(100vw - 24px));height:min(640px,calc(100vh - 110px));transform:translateX(-50%);display:flex;
  flex-direction:column;gap:10px;padding:34px 22px 18px;color:var(--text);border:1px solid #8a6a3a;border-radius:5px;
  background:radial-gradient(ellipse 70% 40% at 50% 0%,rgba(242,192,64,.11),transparent 70%),linear-gradient(180deg,#18110a,#090705);
  box-shadow:inset 0 0 0 1px #000,inset 0 0 0 5px #120d08,inset 0 0 0 6px #5a4426,0 30px 80px rgba(0,0,0,.85),0 0 46px -6px rgba(242,192,64,.3)}
.st-tabs{flex:none;display:flex;gap:8px;padding:0 70px 0 2px}
.st-tab{appearance:none;cursor:pointer;height:48px;padding:0 22px;font:400 21px var(--display);letter-spacing:.06em;color:#c9b080;border:1px solid #4a3a26;border-radius:6px;
  background:linear-gradient(180deg,#24190f,#110c07)}
.st-tab:hover{border-color:#8a6a3a;color:#ffe2ad}
.st-tab.on{color:#2a1606;border-color:#ffe39a;background:linear-gradient(180deg,#ffe08a 0%,#e9b54c 48%,#c48a2c 52%,#a8701f 100%);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.5),0 0 18px -4px rgba(255,200,90,.75)}
.st-head{flex:none;display:flex;align-items:center;gap:14px;min-height:38px}
.st-cap{flex:1;min-width:0;font:400 22px var(--display);letter-spacing:.05em;color:#ffe2ad;text-shadow:0 0 14px rgba(242,192,64,.35)}
.st-range{display:flex;padding:3px;gap:3px;border:1px solid #4a3a26;border-radius:20px;background:#0b0805}
.st-range[hidden]{display:none}
.st-range button{appearance:none;cursor:pointer;height:32px;padding:0 14px;border:0;border-radius:16px;font:700 16px var(--body);color:#bfa77a;background:none}
.st-range button.on{color:#2a1606;background:linear-gradient(180deg,#ffe08a,#c48a2c)}
.st-tiles{flex:none;display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:10px}
.st-tiles[hidden]{display:none}
.st-tiles:has(> :nth-child(2):last-child){grid-template-columns:repeat(2,minmax(0,1fr))}.st-lines{justify-content:center;gap:4px}
.st-tile,.st-rec{position:relative;min-width:0;display:flex;flex-direction:column;gap:2px;padding:8px 14px 9px;border:1px solid #3a2c1a;border-radius:4px;
  background:linear-gradient(180deg,rgba(242,192,64,.08),rgba(0,0,0,.35))}
.st-tile small,.st-rec small{display:flex;flex-wrap:wrap;align-items:center;gap:2px 8px;font:700 16px var(--body);letter-spacing:.1em;text-transform:uppercase;color:#bfa77a}
.st-tile b,.st-rec b{font:800 34px/1.05 var(--body);font-variant-numeric:tabular-nums;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:#f2c040;
  background:linear-gradient(180deg,#fff2b0,#f2c040 55%,#c48a2c);-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;
  filter:drop-shadow(0 2px 0 rgba(0,0,0,.7)) drop-shadow(0 0 10px rgba(242,192,64,.25))}
.st-tile i,.st-rec i{font-style:normal;font-size:16px;color:var(--dim);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.st-new{font-style:normal;padding:1px 8px;border-radius:10px;font:800 15px var(--body);letter-spacing:.04em;text-transform:none;color:#2a1606;background:#ffd75e;
  box-shadow:0 0 12px rgba(255,210,90,.8)}
.st-body{flex:1;min-height:0;display:flex;flex-direction:column;gap:6px}
.st-legend{flex:none;display:flex;flex-wrap:wrap;align-items:center;gap:4px 18px;font-size:16px;color:var(--text)}
.st-sub{font:400 18px var(--display);letter-spacing:.04em;color:#ffe2ad;margin-right:4px}
.st-key{display:inline-flex;align-items:center;gap:7px;white-space:nowrap}
.st-key i{width:14px;height:14px;border-radius:3px;box-shadow:0 0 0 1px rgba(0,0,0,.8)}
.st-key i.st-ring{background:rgba(242,192,64,.24);box-shadow:inset 0 0 0 2px #e8b84a,0 0 0 1px rgba(0,0,0,.8)}
.st-key i.line{width:22px;height:3px;border-radius:2px;background:#ffe9a0;box-shadow:0 0 6px rgba(255,200,90,.9)}
.st-chart{position:relative;flex:1;min-height:0;border:1px solid #2a2014;border-radius:4px;
  background:radial-gradient(ellipse 80% 60% at 50% 100%,rgba(242,192,64,.07),transparent 70%),#0b0805;box-shadow:inset 0 0 24px rgba(0,0,0,.8)}
/* A tab's second chart (Hit rate, Helper gold) shares the room with the first, half each, never under 110 px. */
.st-chart.second{min-height:110px}
.st-chart canvas{position:absolute;inset:0;width:100%;height:100%;display:block;touch-action:pan-y}
.st-tip{position:absolute;top:8px;z-index:2;min-width:190px;max-width:calc(100% - 8px);display:flex;flex-direction:column;gap:2px;padding:8px 12px 9px;pointer-events:none;
  font-size:16px;line-height:1.25;color:#f3e8d2;border:1px solid #c99a4a;border-radius:4px;background:linear-gradient(180deg,rgba(40,28,14,.97),rgba(12,9,6,.97));
  box-shadow:0 6px 18px #000,0 0 18px -4px rgba(242,192,64,.55)}
.st-tip[hidden]{display:none}
.st-tip b{font:400 19px var(--display);letter-spacing:.04em;color:#ffe2ad}
.st-tip small{font-size:16px;color:#bfa77a;margin-bottom:3px}
.st-tip span{display:flex;justify-content:space-between;gap:16px}
.st-tip em{font-style:normal;color:var(--text)}
.st-tip i{font-style:normal;font-weight:800;color:#ffd75e;font-variant-numeric:tabular-nums;white-space:nowrap}
.st-tip .st-find{margin-top:3px;font-weight:700}.st-tip .st-sq{display:inline-block;width:12px;height:12px;border-radius:2px;box-shadow:0 0 0 1px #000;vertical-align:-1px}
/* The sparkle at the crown of a new best round: a four-pointed gold star that turns and pulses. */
.st-spark{position:absolute;width:30px;height:30px;margin:-15px 0 0 -15px;pointer-events:none;
  background:radial-gradient(circle,#fffbe6 0 10%,rgba(255,224,130,.7) 18%,transparent 60%);
  clip-path:polygon(50% 0,60% 40%,100% 50%,60% 60%,50% 100%,40% 60%,0 50%,40% 40%);animation:st-spark 1.4s ease-in-out infinite}
@keyframes st-spark{0%,100%{transform:scale(.6) rotate(0);opacity:.6}50%{transform:scale(1.25) rotate(45deg);opacity:1}}
body:has(#reduceMotion:checked) .st-spark,body.saver .st-spark{display:none}
/* Before any round is sold: three faint gold bars and one line. */
.st-empty{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:18px;text-align:center}
.st-empty b{font:400 26px var(--display);letter-spacing:.04em;color:#ffe2ad}
.st-ghost{display:flex;align-items:flex-end;gap:10px;height:90px;opacity:.45}
.st-ghost i{width:30px;border-radius:4px 4px 0 0;background:linear-gradient(180deg,#fff2b0,#f2c040 55%,#a86c12);box-shadow:0 0 0 1px #3a2208}
.st-ghost i:nth-child(1){height:40%}.st-ghost i:nth-child(2){height:70%}.st-ghost i:nth-child(3){height:100%}
/* Records: lifetime totals and bests in a grid of big gold numbers; Total gold and Items found are twice as wide. */
.st-recs{flex:1;min-height:0;overflow-y:auto;display:grid;grid-template-columns:repeat(4,minmax(0,1fr));grid-auto-rows:min-content;gap:10px;align-content:start}
.st-rec.wide{grid-column:span 2}.st-inline{gap:2px 12px}.st-inline b{letter-spacing:0;text-transform:none}
.st-rec.gold{border-color:#8a6a3a;background:radial-gradient(ellipse at 30% 0%,rgba(242,192,64,.2),transparent 70%),linear-gradient(180deg,rgba(242,192,64,.1),rgba(0,0,0,.35))}
.st-rec.gold b{font-size:44px}
.st-feel{grid-column:1/-1;display:flex;align-items:center;gap:10px;padding:10px 4px 4px;font:700 16px var(--body);color:#bfa77a;cursor:pointer}.st-feel input{width:20px;height:20px;accent-color:#f2c040}
.st-rec b.txt{font-size:24px;line-height:1.15;white-space:normal;-webkit-text-fill-color:currentColor;background:none;filter:drop-shadow(0 1px 0 #000)}
.st-chips{display:flex;flex-wrap:wrap;gap:4px 12px;font-size:16px;color:var(--text)}
.st-chip{display:inline-flex;align-items:center;gap:5px;white-space:nowrap}
.st-chip::before{content:"";width:11px;height:11px;border-radius:2px;background:var(--c);box-shadow:0 0 0 1px #000}
.st-chip b{font:800 16px var(--body);color:var(--text);background:none;-webkit-text-fill-color:currentColor;filter:none}
/* The rarity's name in a chip is for screen readers only (owner, 2026-10-10); the head row hides on Records, which has no caption. */
.st-sr{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}.st-head[hidden]{display:none}
/* The rarest find's name as a button: its rarity colour, underlined, with a small eye; the hint under a best item in a tooltip. */
.st-see{appearance:none;display:inline-flex;align-items:center;gap:8px;align-self:flex-start;max-width:100%;margin:0;padding:2px 0;border:0;background:none;
  cursor:pointer;text-align:left;font:800 24px/1.15 var(--body);text-decoration:underline;text-decoration-thickness:2px;text-underline-offset:4px;
  text-shadow:0 1px 0 #000,0 0 12px rgba(0,0,0,.6)}
.st-see:hover,.st-see:focus-visible{filter:brightness(1.25) drop-shadow(0 0 8px currentColor);outline:none}
.st-eye{flex:none;width:24px;height:24px}
.st-tip .st-see-hint{margin:0;font-size:15px;color:#ffd75e}
/* The item view (32-stats-find.js) over the Stats panel: the item turning large on the left, its card in large type on the
   right; the box as tall as the card needs, at least 520 px so the item has a large square, at most the window's height, the
   card scrolling inside itself beyond that; on a phone the item on top and the card under it. The turning item is hidden
   while the view opens (wait) and fades in once drawn. A short card's text grows to fill its room (fitCard sets its zoom). */
.sf-wrap{position:absolute;inset:0;z-index:3;background:rgba(4,3,2,.7)}
.sf-wrap[hidden]{display:none}
.sf-box{--rc:var(--r-normal);position:absolute;left:50%;top:50%;width:min(1040px,calc(100vw - 32px));max-height:calc(100vh - 32px);transform:translate(-50%,-50%);
  display:flex;gap:16px;padding:16px;border:1px solid color-mix(in srgb,var(--rc) 60%,#000);border-radius:5px;
  background:linear-gradient(180deg,#18110a,#090705);box-shadow:inset 0 0 0 1px #000,0 30px 80px rgba(0,0,0,.9),0 0 50px -6px color-mix(in srgb,var(--rc) 55%,transparent)}
.sf-box .sf-stage{flex:1 1 auto;min-width:0;height:auto;min-height:min(520px,calc(100vh - 64px));margin:0}
.sf-stage canvas{transition:opacity .28s ease-out}
.sf-stage.wait canvas{opacity:0;transition:none}
body:has(#reduceMotion:checked) .sf-stage canvas{transition:none}
.sf-side{flex:0 0 480px;min-width:0;min-height:0;display:flex;flex-direction:column;gap:10px;padding-top:44px}
.sf-where{margin:0;font-size:19px;line-height:1.3;color:#ffe2ad}
/* A record with no code (owner, 2026-10-07): the line about the picture item under the room, the line while it is found (in
   the middle of the picture) and the line under the name that the item's own rolls were not saved. */
.sf-pic{margin:0;font-size:16px;line-height:1.3;color:#cdb68a}
.sf-pic[hidden],.sf-wait[hidden]{display:none}
.sf-wait{position:absolute;inset:0;display:grid;place-items:center;margin:0;padding:16px;text-align:center;font-size:20px;color:#cdb68a}
.sf-card .sf-note{margin:0;padding:0 16px 8px;font-size:17px;line-height:1.3;color:#cdb68a}
.sf-card{flex:0 1 auto;min-height:0;overflow-y:auto;border:1px solid #3a2c1a;border-radius:4px;background:rgba(0,0,0,.35)}
.sf-x{position:absolute;top:10px;right:10px;z-index:2;width:44px;height:44px;display:grid;place-items:center;padding:0;cursor:pointer;color:#e8d6b0;
  border:1px solid #8a6a3a;border-radius:50%;background:radial-gradient(circle at 50% 38%,#3c2b18,#120d08 74%)}
.sf-x:hover{border-color:#ffe39a;color:#fff}
.sf-x svg{width:20px;height:20px;display:block}
.sf-card .tt-head{padding:12px 16px 8px}
.sf-card .tt-name{font-size:38px}
.sf-card .tt-base{font-size:19px}
/* The type line keeps at least 260 px beside the value; when both do not fit, the value moves under it. */
.sf-card .tt-main{padding:10px 16px 8px;flex-wrap:wrap}
.sf-card .tt-type{font-size:21px;flex:1 1 260px}
.sf-card .tt-big{font-size:34px}
.sf-card .tt-big small{font-size:15px}
.sf-card .tt-sec{padding:6px 16px 9px}
.sf-card .tt-lines li{padding-left:16px;font-size:21px;line-height:1.35}
.sf-card .tt-lines li::before{width:6px;height:6px}
.sf-card .tt-lines.plain li{padding-left:0}
.sf-card .tt-lines.cols{grid-template-columns:repeat(auto-fit,minmax(200px,1fr))}
.sf-card .tt-lines .rng{font-size:16px}
.sf-card .sockets,.sf-card .set-pieces,.sf-card .set-bonus,.sf-card .note{font-size:18px}
.sf-card .sock{width:18px;height:18px}
.sf-card .set-name{font-size:20px}
.sf-card .flavor{font-size:21px;padding:6px 18px 9px}
.sf-card .tt-foot{padding:8px 16px 6px;font-size:18px;gap:3px 14px}
.sf-card .quality .bar{height:8px}
.sf-card .tt-code{font-size:15px}
/* Phones: the panel fills the room between the top bar and the dock, like the Journal. */
@media (max-width:700px){
  .stats-panel{left:6px;right:6px;top:calc(64px + env(safe-area-inset-top,0px));bottom:calc(52px + env(safe-area-inset-bottom,0px));width:auto;height:auto;transform:none;padding:30px 10px 10px;gap:8px}
  .st-tabs{gap:4px;padding:0 50px 0 0}
  .st-tab{flex:1;min-width:0;height:44px;padding:0;font:700 15px var(--body);letter-spacing:0}
  .st-head{flex-wrap:wrap;gap:6px 10px;min-height:0}
  .st-cap{font-size:18px}
  .st-range button{height:32px;padding:0 10px;font-size:15px}
  .st-tiles{gap:6px}
  .st-tile{padding:6px 8px 7px}
  .st-tile small{font-size:15px;letter-spacing:0;text-transform:none}
  .st-tile b{font-size:22px}
  .st-tile i{font-size:15px}
  .st-new{font-size:15px;padding:0 5px}
  .st-legend{font-size:15px;gap:3px 12px}
  .st-sub{font-size:16px}
  .st-chart.second{min-height:96px}
  .st-tip{min-width:160px;font-size:15px;padding:6px 9px 7px}
  .st-tip b{font-size:17px}
  .st-recs{grid-template-columns:repeat(2,minmax(0,1fr));gap:6px}
  .st-rec{padding:6px 9px 8px}
  .st-rec small{font-size:15px;letter-spacing:.04em}
  .st-rec b{font-size:26px}
  .st-rec.gold b{font-size:32px}
  .st-rec b.txt{font-size:19px}
  .st-rec i,.st-chips,.st-chip b{font-size:15px}
  .st-empty b{font-size:21px}
  .st-see{font-size:19px;gap:6px}
  .st-eye{width:20px;height:20px}
  .sf-box{left:6px;right:6px;top:64px;bottom:calc(52px + env(safe-area-inset-bottom,0px));width:auto;height:auto;max-height:none;transform:none;display:grid;
    grid-template-columns:minmax(0,1fr);grid-template-rows:minmax(150px,38%) minmax(0,1fr);gap:8px;padding:10px}
  .sf-box .sf-stage{min-height:0}
  .sf-side{padding-top:0}
  .sf-where{font-size:16px}
  .sf-pic,.sf-card .sf-note{font-size:15px}
  .sf-x{top:14px;right:14px}
  .sf-card .tt-head{padding:8px 12px 6px}.sf-card .tt-main,.sf-card .tt-sec{padding-left:12px;padding-right:12px}
  .sf-card .tt-name{font-size:27px}.sf-card .tt-base{font-size:17px}.sf-card .tt-type{font-size:18px}.sf-card .tt-big{font-size:28px}
  .sf-card .tt-lines li{font-size:18px}.sf-card .tt-lines.cols{grid-template-columns:repeat(auto-fit,minmax(150px,1fr))}
  .sf-card .flavor{font-size:18px}.sf-card .tt-foot{font-size:16px;padding:6px 12px 4px}
}


/* The Lore tab of the Journal (33-lore.js): a row for each page, its picture at the left, the group line, the heading in the
   display face with a small New mark, and the text in large type. A locked page is a dark row with "???" and its hint. */
.jrow.lore{align-items:flex-start;padding:14px 18px}
.jrow.lore .gl{font:400 28px var(--display);letter-spacing:.03em;color:#3a2410}
.jrow.lore .lt{margin:6px 0 0;font-size:21px;line-height:1.38;color:#2a1a0c;max-width:46em}
.lore-pic text{font-family:var(--display)}
.jr-tab.has-new em{color:#fff6d8;background:linear-gradient(180deg,#d8502e,#a8321e)}
.lore-gob{background:#24160c}
.lore-new{display:inline-block;margin-left:12px;padding:2px 10px;vertical-align:4px;font:800 15px var(--body);letter-spacing:.08em;text-transform:uppercase;
  color:#fff6d8;border-radius:10px;background:linear-gradient(180deg,#d8502e,#a8321e);box-shadow:0 1px 3px rgba(60,20,5,.5)}
.jrow.lore.locked{align-items:center;border-color:rgba(20,12,4,.6);background:linear-gradient(180deg,#3a2c1c,#2a2014)}
.jrow.lore.locked .gv{color:#9a8a6a}
.jrow.lore.locked .gl{color:#6a5a44;letter-spacing:.2em}
.jrow.lore.locked .lt{color:#bfae8c;font-style:italic}
@media (max-width:700px){
  .jrow.lore{flex-wrap:nowrap;align-items:flex-start;padding:10px}
  .jrow.lore .gl{font-size:21px}
  .jrow.lore .lt{font-size:17px;line-height:1.34}
  .lore-new{font-size:13px;margin-left:8px;padding:1px 8px;vertical-align:2px}
  /* Three tabs share the phone's width. */
  .jr-tabs .jr-tab{padding:0 5px;gap:4px;font-size:17px;letter-spacing:.02em}
  .jr-tabs .jr-tab em{font-size:16px;padding:1px 7px}
}


/* The gift counter on the coin pouch and the list of the gifts carried (34-gifts.js). The counter is a round badge at the top
   right of the pouch's frame, a wrapped gift and the count; a tap on it opens the list above the pouch: the icon, the name and
   the count of each kind, in large type. */
.pouch{position:relative}
.gift-badge{position:absolute;top:-4px;right:-10px;display:flex;align-items:center;gap:3px;padding:3px 10px 3px 5px;pointer-events:auto;cursor:pointer;
  font:800 20px var(--body);color:#ffe6a0;background:radial-gradient(circle at 50% 35%,#3c2b18,#120d08 80%);border:2px solid #c99a4a;border-radius:20px;
  box-shadow:0 0 0 1px #000,0 4px 10px rgba(0,0,0,.6),0 0 14px -4px rgba(255,120,170,.75);text-shadow:0 2px 3px #000}
.gift-badge[hidden]{display:none}
.gift-badge .gift-icon{width:28px;height:28px;flex:none}
.gift-badge:hover,.gift-badge:focus-visible{border-color:#ffd27a}
.gift-pop{position:fixed;z-index:12;width:min(340px,calc(100vw - 16px));padding:12px 16px 12px;box-sizing:border-box}
.gift-pop[hidden]{display:none}
.gp-title{margin:0 34px 8px 0;font:400 24px var(--display);color:#ffe6a0}
.gp-title span{margin-left:8px;font:600 17px var(--body);color:var(--dim)}
/* The rows, each 53 px (GP_ROW in 34-gifts.js), scroll in whole rows when the room above the pouch holds fewer than all. */
.gp-rows{overflow-y:auto;overscroll-behavior:contain;scroll-snap-type:y mandatory;scrollbar-width:thin;scrollbar-color:#7a5c38 transparent}
.gp-row{display:flex;align-items:center;gap:12px;height:53px;padding:6px 0;border-top:1px solid var(--edge);scroll-snap-align:start}
.gp-row .gift-icon{width:40px;height:40px;flex:none}
.gp-row b{flex:1;min-width:0;font-size:19px;font-weight:600;color:#f0e6d0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.gp-row.rare b{color:var(--r-rare)}
.gp-row i{font-style:normal;font-size:19px;font-weight:800;color:#ffe6a0;white-space:nowrap}
.gp-note{margin:8px 0 0;font-size:16px;color:var(--dim)}
@media (max-width:700px){
  .gift-badge{top:-2px;right:-8px;padding:2px 8px 2px 4px;font-size:18px}
  .gift-badge .gift-icon{width:24px;height:24px}
}


/* Friends (34-friends.js): the heart of each person beside the name in the speech box with "Level 2", the Give a gift button and
   the row of gifts under the line; Grubb's button in the shop; the Journal's Friends tab. The heart is an empty heart with a red
   one over it, cut off from the top (--cut) so the red rises from the bottom; the cut moves over 0.8 s; small marks on both
   sides part its five bands, one for each level. */
.fr-head{display:flex;align-items:center;flex-wrap:wrap;gap:6px 16px;min-width:0}
.fr-tag{display:flex;align-items:center;gap:14px}
.fr-tag[hidden],.fr-gifts[hidden],.fr-give[hidden],.fr-shop[hidden]{display:none}
.fr-badge{position:relative;display:inline-flex;align-items:center;gap:7px}
/* With the hearts hidden (FRIEND_HEARTS false, 34-friends.js) the badge is empty and takes no room. */
.fr-badge:empty{display:none}
.fr-heart{position:relative;flex:none;display:inline-block;width:36px;height:36px}
.fr-heart svg{position:absolute;inset:0;width:100%;height:100%;overflow:visible}
.fr-heart .e{fill:#3a0e16;stroke:#ffb4bc;stroke-width:1.8}
.fr-heart .full{clip-path:inset(var(--cut,100%) 0 0 0);transition:clip-path .8s ease-out}
.fr-heart .full path{fill:#e8304a;stroke:#ffc8cf;stroke-width:1.8}
.fr-heart .full .hi{fill:none;stroke:#fff;stroke-width:2;stroke-linecap:round;opacity:.65}
.fr-heart .mk path{fill:none;stroke:#ffe2e8;stroke-opacity:.85;stroke-width:1;stroke-linecap:round}
.fr-lv{display:inline-flex;align-items:baseline;gap:5px;white-space:nowrap;color:#ffd0d6;text-shadow:0 2px 3px #000}
.fr-lw{font:800 14px var(--body);letter-spacing:.12em;text-transform:uppercase;color:#f2aab4}
.fr-ln{font:800 26px/1 var(--body)}
.fr-badge.up .fr-heart{animation:fr-pop .55s cubic-bezier(.3,1.6,.5,1)}
@keyframes fr-pop{0%{transform:scale(1)}40%{transform:scale(1.5)}100%{transform:scale(1)}}
.fr-plus{position:absolute;left:2px;top:-12px;font:800 22px var(--body);color:#ff9aa8;pointer-events:none;text-shadow:0 2px 3px #000}
.fr-plus.minus{color:#b8a8a0}
.fr-give{display:flex;align-items:center;gap:8px;height:44px;padding:0 16px 0 8px;cursor:pointer;font:700 19px var(--body);color:#ffe6a0;
  border:1px solid #c99a4a;border-radius:22px;background:linear-gradient(180deg,#4a2a1a,#24140c);box-shadow:0 2px 6px rgba(0,0,0,.5)}
.fr-give:hover,.fr-give:focus-visible,.fr-give[aria-expanded="true"]{border-color:#ffd27a;color:#fff0c8}
.fr-give .gift-icon{width:30px;height:30px;flex:none}
/* The row of gifts: rows of one height, the box exactly three of them tall (four on a phone, three there beside a quest on
   offer), and the scroll stops at a row's top, so a row is never cut in half. A kind given away in this talk stays greyed.
   Closed while the person shows (room), it keeps its place, faded, so the speech box is the same height open or closed and the
   place shows the gifts carried rather than an empty band; a tap on the faded row opens it (34-friends.js). */
.fr-gifts{display:flex;flex-wrap:wrap;align-content:flex-start;gap:8px;margin-top:4px;padding:10px;max-height:200px;overflow-y:auto;overscroll-behavior:contain;
  scroll-snap-type:y mandatory;scroll-padding:10px 0;scrollbar-width:thin;scrollbar-color:#7a5c38 transparent;cursor:default;border:1px solid #7a5c38;border-radius:4px;
  background:rgba(0,0,0,.35)}
#story .fr-on .fr-gifts.room[hidden]{display:flex;opacity:.4;cursor:pointer}
#story .fr-on .fr-gifts.room[hidden] .fr-gift{pointer-events:none}
.fr-gift{flex:none;display:flex;align-items:center;gap:8px;height:54px;padding:4px 12px 4px 6px;white-space:nowrap;scroll-snap-align:start;cursor:pointer;
  font:600 19px var(--body);color:#f0e6d0;border:1px solid #6a5030;border-radius:6px;background:linear-gradient(180deg,#2e2014,#1a120a)}
.fr-gift:hover,.fr-gift:focus-visible{border-color:#ffd27a}
.fr-gift:disabled{cursor:default;opacity:.42;filter:grayscale(.8);border-color:#6a5030}
.fr-gift .gift-icon{width:42px;height:42px;flex:none}
.fr-gift.rare .fr-gn{color:var(--r-rare)}
.fr-gc{font-weight:800;color:#ffe6a0;white-space:nowrap}
.fr-t{padding:2px 8px;border-radius:10px;font-size:15px;font-weight:800;letter-spacing:.04em;white-space:nowrap}
.fr-t.loved{background:#b02a40;color:#fff}.fr-t.liked{background:#3a6a3a;color:#fff}.fr-t.neutral{background:#4a4030;color:#e8dcc0}
.fr-t.disliked{background:#2a2a2a;color:#c0b0a0}
/* The speech box of a person with a heart (fr-on, 34-friends.js): the portrait beside the heading (the name and title) with the heart,
   and the line under it, with no second line (owner, 2026-10-07); the quest block, the row of gifts and the foot run across the whole
   box under them, so no space is left under the portrait. */
#story .story-box.fr-on{display:grid;grid-template-columns:auto minmax(0,1fr);grid-template-rows:auto 1fr;column-gap:20px;row-gap:4px;padding:16px}
#story .fr-on .story-text{display:contents}
#story .fr-on .story-face{grid-column:1;grid-row:1/3}
#story .fr-on .fr-head{grid-column:2;grid-row:1;padding-right:44px}
#story .fr-on #storyLine{grid-column:2;grid-row:2}
#story .fr-on :is(.story-name,.story-offer,.fr-gifts,.story-foot){grid-column:1/-1}
#story .fr-on :is(.story-name,.story-offer){order:1}#story .fr-on .fr-gifts{order:2}#story .fr-on .story-foot{order:3}
/* Grubb's button in the shop: over the bottom of her cloak on a wide screen, and beside her bubble on a phone. */
.fr-shop{position:absolute;left:4px;right:4px;bottom:6px;z-index:2;display:flex;align-items:center;justify-content:center;gap:6px}
.fr-stalk,.fr-sgive{cursor:pointer;color:#ffe6a0;border:1px solid #c99a4a;background:linear-gradient(180deg,rgba(74,42,26,.96),rgba(36,20,12,.96));
  box-shadow:0 2px 8px rgba(0,0,0,.6)}
.fr-stalk{display:flex;align-items:center;gap:7px;height:52px;padding:0 14px 0 7px;font:700 16px var(--body);border-radius:26px}
.fr-stalk:hover,.fr-sgive:hover,.fr-stalk:focus-visible,.fr-sgive:focus-visible{border-color:#ffd27a}
.fr-stalk .fr-heart{width:34px;height:34px}
.fr-sx{display:flex;flex-direction:column;align-items:flex-start;gap:2px;line-height:1.05;white-space:nowrap}
.fr-stalk .fr-lw{font-size:12px}.fr-stalk .fr-ln{font-size:18px}
.fr-stalk.ask{border-color:#ff8a9a;animation:fr-ask 1.4s ease-in-out infinite}
@keyframes fr-ask{50%{box-shadow:0 0 0 3px rgba(255,90,120,.55),0 0 18px rgba(255,90,120,.75)}}
.fr-sgive{display:grid;place-items:center;flex:none;width:48px;height:48px;padding:0;border-radius:50%}
.fr-sgive .gift-icon{width:32px;height:32px}
.fr-short{display:none}
.sh-kp{cursor:pointer}
.fr-gob{background:#24160c}
body:has(#reduceMotion:checked) .fr-stalk.ask{animation:none}
body:has(#reduceMotion:checked) .fr-heart .full{transition:none}
/* The Journal's Friends tab. */
.jrow.fr-row{align-items:flex-start;padding:12px 18px}
.jrow.fr-row .gl{font:400 28px var(--display);letter-spacing:.03em;color:#3a2410}
.fr-line{display:flex;align-items:center;flex-wrap:wrap;gap:6px 14px;margin-top:6px}
.jrow .fr-heart .e{fill:#f6dcd8;stroke:#8a1a2a}
.jrow .fr-heart .mk path{stroke:#8a1a2a;stroke-opacity:.6}
.fr-lvl{font-size:22px;font-weight:800;color:#3a2410}
.fr-perk{font-size:20px;font-weight:700;color:#7a2a1a}
/* The three friendship steps on a Friends card (34-friend-steps.js): a numbered row each, lit once reached, "???" until
   then, and under the next step a thin bar of the way to it. */
.fs-steps{list-style:none;margin:8px 0 4px;padding:0;display:flex;flex-direction:column;gap:4px}
.fs-step{display:grid;grid-template-columns:24px 1fr;align-items:center;gap:2px 8px;font-size:17px;line-height:1.25;color:#6a5434}
.fs-step>b{display:grid;place-items:center;width:22px;height:22px;border-radius:50%;border:1.5px solid #8a6a3a;font:800 13px var(--body);color:#8a6a3a}
.fs-step em{font-style:normal;font-weight:800;color:#5a3a18}.fs-step.got{color:#3a2410}.fs-step.got>b{background:#a8263a;border-color:#6a1020;color:#fff3e0}
.fs-bar{grid-column:2;display:block;height:6px;border-radius:3px;background:rgba(90,60,24,.2);overflow:hidden}.fs-bar>i{display:block;height:100%;background:#a8263a}
.fr-tastes{display:flex;flex-wrap:wrap;gap:4px 18px;margin-top:6px;font-size:19px;color:#4a3418}
.fr-k em{font-style:normal;font-weight:800}
.fr-k.loved em{color:#a8263a}.fr-k.liked em{color:#2e6a30}.fr-k.disliked em{color:#5a4a3a}
@media (max-width:700px){
  .story-text .fr-head #storyName{padding-right:0}
  .fr-head{padding-right:40px;gap:4px 10px}
  .fr-heart{width:30px;height:30px}.fr-ln{font-size:22px}.fr-lw{font-size:12px}
  .fr-give{height:40px;padding:0 12px 0 6px;font-size:17px}
  .fr-give .gift-icon{width:26px;height:26px}
  .fr-gifts{gap:6px;padding:8px;max-height:228px;scroll-padding:8px 0}
  #story .fr-on:has(.story-offer:not([hidden])) .fr-gifts{max-height:174px}
  .fr-gift{height:48px;font-size:17px;padding:3px 10px 3px 4px}
  .fr-gift .gift-icon{width:36px;height:36px}
  .fr-t{font-size:13px}
  /* A phone: the portrait beside the heading and the heart with the gift button; the line and all under it across the box. */
  #story .story-box.fr-on{grid-template-rows:auto auto 1fr;column-gap:12px;padding:12px 12px 14px}
  #story .fr-on .story-face{grid-row:1/3;align-self:center}
  #story .fr-on .fr-head{display:contents}
  #story .fr-on #storyName{grid-column:2;grid-row:1;padding-right:40px}
  #story .fr-on .fr-tag{grid-column:2;grid-row:2;flex-wrap:wrap;gap:4px 10px;margin-top:2px}
  #story .fr-on #storyLine{grid-column:1/-1;grid-row:3}
  #story .fr-on :is(.story-offer,.story-name){margin:4px 0 0;width:auto}
  .fr-shop{position:static;flex:none;flex-direction:column;align-self:center;gap:5px}
  .fr-stalk{flex-direction:column;justify-content:center;width:66px;height:auto;padding:5px 2px 6px;gap:2px;border-radius:12px}
  .fr-stalk .fr-heart{width:28px;height:28px}
  .fr-sx{align-items:center;gap:1px}
  .fr-stalk .fr-lv{gap:3px}.fr-stalk .fr-lw{font-size:10px;letter-spacing:.06em}.fr-stalk .fr-ln{font-size:15px}
  .fr-off{display:none}.fr-short{display:block;width:100%;text-align:center;font-size:16px}
  .fr-sgive{width:42px;height:42px}.fr-sgive .gift-icon{width:28px;height:28px}
  .jrow.fr-row{flex-wrap:nowrap;padding:10px}
  .jrow.fr-row .gl{font-size:22px}
  .fr-lvl{font-size:18px}.fr-perk{font-size:16px}.fr-tastes{font-size:16px}.fs-step{font-size:15px}
  /* Four tabs share the phone's width. */
  .jr-tabs:has([data-qtab="friends"]) .jr-tab{padding:0 3px;font-size:15px}
  .jr-tabs:has([data-qtab="friends"]) .jr-tab em{font-size:14px;padding:1px 6px}
}


/* The friendship rewards (34-friend-steps.js, FRIENDSHIP.md).
   Grubb's good stuff (22-shop-cabinet.js): the shop's tabs, Shelves and Good stuff, centred at the top of the wall, and the
   cabinet: a dark wooden case with a glass front, a cobweb in each top corner, a shelf of gems above and below (each gem's
   glint twinkles in turn, still with Reduce motion) and the two goods on the middle shelf. */
.sh-tabs{position:relative;z-index:3;display:flex;justify-content:center;gap:0;margin:-6px auto 10px;width:max-content;padding:3px;border:1px solid #5a4632;border-radius:999px;background:#140e09}
.sh-tab{appearance:none;min-width:120px;padding:6px 16px;border:0;border-radius:999px;background:none;color:#bfa77a;font:700 15px var(--body);cursor:pointer}
.sh-tab[aria-selected="true"]{background:linear-gradient(180deg,#f6d77a,#c9952e);color:#2a1806;box-shadow:0 1px 4px rgba(0,0,0,.6)}
.sh-tab:not([aria-selected="true"]):hover{color:#ffe9b0}.sh-tab:focus-visible{outline:2px solid var(--bronze-hi)}
.cab{position:relative;margin:0 40px;padding:6px 18px 8px;border:6px solid #3a2414;border-radius:6px 6px 2px 2px;
  background:radial-gradient(ellipse at 50% 40%,#2e2014,#140c06);box-shadow:inset 0 0 0 2px #6a4424,inset 0 0 30px rgba(0,0,0,.8),0 8px 18px rgba(0,0,0,.6)}
.cab-glass{position:absolute;inset:0;pointer-events:none;background:linear-gradient(115deg,rgba(255,255,255,.07) 0 18%,transparent 18% 30%,rgba(255,255,255,.05) 30% 34%,transparent 34%)}
.cab-web{position:absolute;top:0;width:70px;height:70px;pointer-events:none}.cab-web.l{left:0}.cab-web.r{right:0;transform:scaleX(-1)}
.cab-deco{position:relative;height:84px}.cab-deco .sh-plank{top:58px;left:-18px;right:-18px}
.cab-gem{position:absolute;top:30px;width:34px;height:28px;transform:translateX(-50%) rotate(-6deg);filter:drop-shadow(0 4px 3px rgba(0,0,0,.6))}
.cab-glint{transform-box:fill-box;transform-origin:center;animation:cab-tw 3.2s ease-in-out infinite;animation-delay:var(--d)}
@keyframes cab-tw{0%,70%,100%{opacity:0;transform:scale(.4)}80%{opacity:1;transform:scale(1.2)}}
.sh-still .cab-glint{animation:none;opacity:.6}
.cab-row{margin:0}
@media (prefers-reduced-motion: reduce){.cab-glint{animation:none;opacity:.6}}
@media (max-width:700px){
  .sh-tabs{margin:-4px auto 8px}.sh-tab{min-width:100px;padding:5px 12px;font-size:14px}
  .cab{margin:0 6px;padding:4px 8px 6px;border-width:4px}.cab-web{width:46px;height:46px}
  .cab-deco{height:58px}.cab-deco .sh-plank{top:40px;left:-8px;right:-8px}.cab-gem{top:18px;width:26px;height:22px}
}
/* Wren's hunter's ring (35-hunter-ring.js): over the chest, letting every tap through. The thin gold ring (hr-aim) is where
   to strike; the faint white ring (hr-close) closes on it. A hit flashes the gold ring with a shock ring and "Bullseye!";
   a miss shows its word in grey, under the chest. The words drift up unless Reduce motion is on (still). */
.hr{position:fixed;left:0;top:0;z-index:3;width:0;height:0;pointer-events:none;opacity:0;transition:opacity .2s}
.hr svg{position:absolute;left:calc(var(--r,40px) * -3.4);top:calc(var(--r,40px) * -3.4);width:calc(var(--r,40px) * 6.8);height:calc(var(--r,40px) * 6.8);overflow:visible}
.hr circle{fill:none;vector-effect:non-scaling-stroke}
.hr-aim{stroke:#ffd75e;stroke-width:2.5;stroke-opacity:.85;filter:drop-shadow(0 0 4px rgba(255,215,94,.8))}
.hr-close{stroke:#fff6e0;stroke-width:2;stroke-opacity:.6}
.hr.hit .hr-aim{stroke:#fff;stroke-width:4;animation:hr-shock .6s ease-out forwards}.hr.still.hit .hr-aim{animation:none}
.hr.said .hr-close{stroke-opacity:0}
.hr-word{position:absolute;left:0;top:calc(var(--r,40px) * 1.35);transform:translate(-50%,0);white-space:nowrap;font:400 30px var(--display);letter-spacing:.04em;color:#cfc4b0;text-shadow:0 2px 6px #000}
.hr.hit .hr-word{color:#ffd75e;font-size:38px;text-shadow:0 0 14px rgba(255,190,60,.9),0 2px 6px #000}
.hr.said:not(.still) .hr-word{animation:hr-rise .9s ease-out both}
@keyframes hr-shock{from{transform:scale(1);opacity:1}to{transform:scale(3);opacity:0}}
@keyframes hr-rise{from{transform:translate(-50%,20%) scale(.8)}to{transform:translate(-50%,-20%) scale(1)}}
.hr-aim{transform-box:fill-box;transform-origin:center}
@media (max-width:700px){.hr-word{font-size:24px}.hr.hit .hr-word{font-size:30px}}
/* The window of a friendship reward (36-friend-window.js): centred over a dimmed village, at most the screen's size, its
   content scrolling inside. */
.fw-back{position:fixed;inset:0;z-index:30;display:grid;place-items:center;padding:calc(env(safe-area-inset-top) + 12px) 10px 12px;background:rgba(4,3,2,.6)}
.fw-back[hidden]{display:none}
.fw{position:relative;width:min(720px,100%);max-height:100%;overflow:auto;padding:18px 22px 22px;border:1px solid var(--edge-hi);border-radius:4px;
  background:linear-gradient(180deg,#1f1913,#130f0b);box-shadow:inset 0 0 0 4px #1a140f,inset 0 0 0 5px #3a2f23,0 30px 80px rgba(0,0,0,.85);color:var(--text)}
.fw-title{margin:0 40px 12px 0;font:400 30px var(--display);letter-spacing:.04em;color:#ffe9b0}
.fw-x{top:10px;right:10px;width:34px;height:34px}
/* Ambrose's spell book (36-spell-book.js): an open book, a page of his note at the left and the spells at the right. A spell
   written in shows in ink; one just written has its ink flow in from the left (at once with Reduce motion). */
.fw.book{background:linear-gradient(180deg,#3a2414,#22140a);border-color:#8a5a2a}
.sb-pages{display:grid;grid-template-columns:1fr 1.3fr;gap:0;border-radius:3px;background:linear-gradient(90deg,#efe0bc 0 48%,#c9b48a 49.5%,#a8946a 50%,#c9b48a 50.5%,#efe0bc 52%);
  box-shadow:0 6px 16px rgba(0,0,0,.6),inset 0 0 30px rgba(120,80,30,.35);color:#3a2410}
.sb-page{margin:0;padding:18px 20px;list-style:none}
.sb-note{margin:0 0 10px;font:italic 400 19px/1.45 var(--body);color:#4a3018}.sb-sign{margin:0;text-align:right;font:400 24px var(--display);color:#5a2a6a}
.sb-spell{display:grid;grid-template-columns:44px 1fr;gap:4px 12px;align-items:center;padding:10px 0;border-bottom:1px dashed rgba(90,60,24,.35)}
.sb-spell:last-child{border-bottom:0}.sb-spell .shop-icon{width:40px;height:40px}
.sb-spell b{display:block;font:400 24px var(--display);color:#2a1a4a}.sb-spell em{display:block;font:italic 400 16px/1.35 var(--body);color:#5a4024}
.sb-spell small{display:block;margin-top:2px;font:700 14px var(--body);color:#8a3a1a}
.sb-spell.blank{opacity:.6}.sb-q{display:grid;place-items:center;width:40px;height:40px;border:2px dashed #8a6a3a;border-radius:50%;font:700 22px var(--display);font-style:normal;color:#8a6a3a}
.sb-write{grid-column:2;justify-self:start;margin-top:4px;padding:6px 14px;font-size:15px}
.sb-spell.fresh span{animation:sb-ink 1s ease-out both}
@keyframes sb-ink{from{clip-path:inset(0 100% 0 0);opacity:.4}to{clip-path:inset(0 0 0 0);opacity:1}}
.spell.book{border-color:#e8c870;background:radial-gradient(circle at 40% 35%,#5a4a9a,#2a1f4a)}.spell.book .sb-free{background:#e8dcc0;font-size:9px;padding:0 3px}
.fr-reward{margin-left:6px}
@media (prefers-reduced-motion: reduce){.sb-spell.fresh span{animation:none}}
body:has(#reduceMotion:checked) .sb-spell.fresh span,body:has(#reduceMotion:checked) .cab-glint{animation:none}
@media (max-width:700px){
  .fw{padding:14px 12px 16px}.fw-title{font-size:24px}
  .sb-pages{grid-template-columns:1fr;background:#efe0bc}.sb-page.left{border-bottom:1px solid #c9b48a;padding-bottom:10px}
  .sb-note{font-size:17px}.sb-spell b{font-size:21px}.sb-spell em{font-size:15px}
}
/* Tobin's ventures (36-ventures.js): his news line, the gold, and a row for each venture: name and its way, its little
   price line (green when up), the price and the change since the last round, the shares held, and the buy and sell buttons. */
.vn-news{margin:0 0 8px;padding:10px 14px;border-left:3px solid #f2c040;background:rgba(242,192,64,.08);font:italic 400 18px/1.35 var(--body);color:#ffe9b0}
.vn-bank{margin:0 0 8px;font-size:16px;color:#bfa77a}.vn-bank b{color:#ffd75e}
.vn-list{margin:0;padding:0;list-style:none;display:flex;flex-direction:column;gap:8px}
.vn-row{display:grid;grid-template-columns:minmax(0,1.6fr) 74px 90px 100px;grid-template-areas:"name spark price own" "acts acts acts acts";gap:6px 12px;align-items:center;
  padding:10px 12px;border:1px solid #3a2f23;border-radius:3px;background:rgba(0,0,0,.25)}
.vn-name{grid-area:name;min-width:0}.vn-name b{display:block;font:700 17px var(--body);color:#ffe9b0}.vn-name em{display:block;font-size:14px;color:#a8946a}
.vn-spark{grid-area:spark;width:70px;height:24px}.vn-spark polyline{fill:none;stroke:#e05a4a;stroke-width:1.8;stroke-linejoin:round}.vn-spark.up polyline{stroke:#5ad070}
.vn-price{grid-area:price;text-align:right}.vn-price b{display:block;font-size:17px;color:#ffd75e}.vn-price small{font-size:13px;color:#a8946a}
.vn-price .up{color:#5ad070}.vn-price .down{color:#e86a5a}
.vn-own{grid-area:own;text-align:right;font-size:14px;color:#bfa77a}.vn-own b{font-size:16px;color:#ffe9b0}.vn-own small{display:block;color:#a8946a}
.vn-acts{grid-area:acts;display:flex;gap:6px;justify-content:flex-end}.vn-b{padding:5px 10px;font-size:14px}
.vn-foot{margin:10px 0 0;font-size:13px;color:#8a7a5a}
@media (max-width:700px){
  .vn-row{grid-template-columns:minmax(0,1fr) 70px 84px;grid-template-areas:"name name name" "spark price own" "acts acts acts";padding:8px}
  .vn-acts{justify-content:space-between}.vn-b{flex:1;padding:6px 4px;font-size:13px}.vn-news{font-size:16px}
}
/* Elowen's Page (36-scroll.js): parchment between two wooden rollers, the items in her hand (Dancing Script, with Georgia
   italic when it cannot load), dark brown ink for contrast. The top bar's scroll button has a soft gold dot while a page is
   unread. */
.fw.scroll{width:min(560px,100%);background:linear-gradient(180deg,#3a2414,#22140a);border-color:#8a5a2a}
.sc-paper{position:relative;padding:22px 28px 18px;border-radius:2px;background:radial-gradient(ellipse at 50% 40%,#f6ead0,#e6d2a4 80%,#d4bc88);
  box-shadow:inset 0 0 40px rgba(120,80,30,.35),0 6px 16px rgba(0,0,0,.6);color:#3a2410}
.sc-paper::before,.sc-paper::after{content:"";position:absolute;left:-10px;right:-10px;height:14px;border-radius:7px;background:linear-gradient(180deg,#8a5a2a,#4a2a10);box-shadow:0 2px 4px rgba(0,0,0,.5)}
.sc-paper::before{top:-8px}.sc-paper::after{bottom:-8px}
.sc-no{margin:0 0 6px;text-align:center;font:400 15px var(--display);letter-spacing:.12em;color:#7a5a3a}
.sc-items{margin:0;padding:0;list-style:none;font:500 24px/1.38 "Dancing Script","Segoe Script","Apple Chancery",Georgia,serif;color:#33200c}
.sc-items li{padding:8px 0 8px 22px;position:relative}.sc-items li+li{border-top:1px solid rgba(120,80,30,.22)}
.sc-items li::before{content:"\2766";position:absolute;left:0;top:10px;font:400 15px Georgia,serif;color:#9a3a2a}
.sc-sign{margin:8px 0 0;text-align:right;font:600 24px "Dancing Script",Georgia,serif;color:#5a2a1a}
.sc-btn{padding:0 8px}.sc-dot{position:absolute;top:5px;right:5px;width:10px;height:10px;border-radius:50%;background:#ffd75e;box-shadow:0 0 6px #ffb020}.sc-dot[hidden]{display:none}
@media (max-width:700px){.sc-paper{padding:18px 16px 14px}.sc-items{font-size:21px}}


/* The Rat House (37-rat-house.js): its name and the taps left under the top bar, the items out of the chest, the haul. */
.rh{position:fixed;inset:0;z-index:7;touch-action:none}
.rh-head{position:absolute;left:50%;top:calc(env(safe-area-inset-top) + 72px);transform:translateX(-50%);text-align:center;pointer-events:none;white-space:nowrap}
.rh-head b{display:block;font:400 clamp(26px,6vw,40px)/1.1 Metamorphous,serif;letter-spacing:.06em;color:#ffd890;text-shadow:0 2px 10px #000,0 0 18px rgba(255,170,60,.5)}
.rh-head small{display:block;margin-top:4px;font:700 13px/1.2 'Alegreya Sans',sans-serif;letter-spacing:.12em;text-transform:uppercase;color:#f0dcc0;text-shadow:0 1px 4px #000}
.rh-pops{position:absolute;inset:0;pointer-events:none}
.rh-pop{position:absolute;transform:translate(-50%,-100%);display:grid;justify-items:center;gap:2px;text-align:center;animation:rhPop 1.9s ease-out forwards}
.rh-pop img{width:64px;height:64px;border-radius:8px;border:2px solid var(--rc);background:rgba(10,6,3,.85);box-shadow:0 0 16px var(--rc)}
.rh-pop b{font:400 18px/1.1 Metamorphous,serif;color:var(--rc);text-shadow:0 1px 4px #000;white-space:nowrap}
.rh-pop i{font:700 12px/1.2 'Alegreya Sans',sans-serif;font-style:normal;color:#ffe2a0;text-shadow:0 1px 3px #000}
@keyframes rhPop{0%{opacity:0;margin-top:20px}12%{opacity:1;margin-top:0}75%{opacity:1}100%{opacity:0;margin-top:-90px}}
.rh-done[hidden]{display:none}
.rh-done{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);display:grid;justify-items:center;gap:6px;padding:18px 26px;border-radius:14px;
  background:rgba(14,8,4,.82);border:1px solid rgba(255,200,120,.35);text-align:center;color:#f0dcc0;pointer-events:none}
.rh-total{font:400 clamp(40px,11vw,64px)/1 Metamorphous,serif;color:#ffd060;text-shadow:0 2px 12px rgba(255,160,40,.5)}
.rh-done small{font:700 13px/1.2 'Alegreya Sans',sans-serif;letter-spacing:.12em;text-transform:uppercase}
.rh-best{display:grid;justify-items:center;gap:4px}.rh-best img{width:56px;height:56px;border-radius:8px;border:2px solid var(--rc)}
.rh-best b{font:400 17px/1.1 Metamorphous,serif;color:var(--rc)}
.rh-done p{margin:4px 0 0;font:italic 500 16px/1.2 Alegreya,serif;color:#ffcf9a}
.rh-x{position:absolute;left:50%;bottom:calc(env(safe-area-inset-bottom) + 24px);transform:translateX(-50%);min-width:150px;padding:10px 22px;border-radius:10px;
  font:400 22px/1 Metamorphous,serif;color:#2a1606;background:linear-gradient(#ffd98a,#e0a040);border:1px solid #fff2c8;box-shadow:0 4px 14px rgba(0,0,0,.5);cursor:pointer}
@media (prefers-reduced-motion:reduce){.rh-pop{animation:none}}


/* The owner's painted pictures (36-art.js). A portrait or a lore picture is an img with the drawing's class and art-pic: the
   same frame and size as the drawing (the speech box, the Journal rows, the Lore pages), the picture covering it. In the quest
   tracker and Elowen's pop-up during play the img is inside a span with the drawing's class and art-zoom, the frame. */
img.art-pic{display:block;object-fit:cover;object-position:50% 50%;user-select:none;-webkit-user-select:none;-webkit-user-drag:none;-webkit-touch-callout:none}
/* The portraits are cut-outs on a transparent background. Behind each one a painted backdrop: a dark wash of the person's
   colour, a soft glow of it round the figure, a warm light behind the head and a darker corner, the colours of the person's
   drawn portrait (Elowen's ELF_SVG in 26-story.js, the givers' faces in 25-quests.js, Grubb's fr-gob in 1-friends.html), dark
   enough to read as a framed picture on the Journal's parchment. --art-hi is the glow, --art-mid the wash, --art-lo the dark. */
[data-art^="elowen-"],[data-who="elowen"]{--art-hi:#b8d68a;--art-mid:#4a6a3c;--art-lo:#121a10}
[data-art^="merchant-"],[data-who="merchant"]{--art-hi:#e8a85a;--art-mid:#7a3424;--art-lo:#2a1e12}
[data-art^="collector-"],[data-who="collector"]{--art-hi:#9ab4e6;--art-mid:#2a3a6a;--art-lo:#141a26}
[data-art^="huntress-"],[data-who="huntress"]{--art-hi:#8cbc78;--art-mid:#2e5a2a;--art-lo:#14200f}
[data-art^="smith-"],[data-who="smith"]{--art-hi:#f29a52;--art-mid:#5a3a24;--art-lo:#24140c}
[data-art^="grubb-"],[data-who="grubb"]{--art-hi:#d8a058;--art-mid:#5a3418;--art-lo:#24160c}
img.art-pic[data-art^="elowen-"],img.art-pic[data-art^="merchant-"],img.art-pic[data-art^="collector-"],img.art-pic[data-art^="huntress-"],
img.art-pic[data-art^="smith-"],img.art-pic[data-art^="grubb-"],.art-zoom{
  background:radial-gradient(circle at 50% 30%,rgba(255,232,186,.55),rgba(255,232,186,0) 34%),
    radial-gradient(ellipse 70% 60% at 50% 42%,var(--art-hi),transparent 72%),
    radial-gradient(ellipse 45% 35% at 14% 88%,var(--art-lo),transparent 80%),radial-gradient(ellipse 50% 40% at 90% 8%,var(--art-lo),transparent 75%),
    linear-gradient(165deg,var(--art-mid),var(--art-lo))}
/* The speech box (150 x 150, Elowen 150 x 180, which crops overflow): head and shoulders, the picture 12% larger with its
   top in place, so the face sits in the upper middle. */
.story-face img.art-pic{width:100%;height:100%;object-position:50% 0;transform:scale(1.12);transform-origin:50% 12%}
/* Brom's picture has little space above his head, so it keeps its own size there and the top of his head stays in the frame. */
.story-face img.art-pic[data-art^="smith-"]{transform:none}
/* The Journal rows and the Lore pages (104 x 104): the whole square picture, head and shoulders, its top in place. */
.jrow img.art-pic,img.pf.art-pic{object-position:50% 0}
/* The small frames (the quest tracker, 28 x 28; Elowen's pop-up, 44 x 53): the frame crops the picture, scaled up round the
   head. The border and size come from the drawing's class (qt-face, story-mini). */
.art-zoom{display:block;overflow:hidden}
.art-zoom img.art-pic{width:100%;height:100%;background:none;object-position:50% 0;transform:scale(1.8);transform-origin:50% 18%}
/* Grubb's painted figure in the drawn goblin's box: the picture stands on the bottom of the box, its top where the drawing's
   hood reaches (90% of the box, under the bubble), whole; the blink picture lies over it as the eyelids. The figure is a
   square cut-out with no backdrop: the shop's wall shows round it. */
.sh-kp.sh-art{display:flex;align-items:flex-end}
.sh-art .sh-bob{position:relative;flex:1;min-width:0;height:90%}
.sh-art img.art-pic{width:100%;height:100%;object-fit:contain;object-position:50% 100%;background:none;filter:drop-shadow(0 4px 8px rgba(0,0,0,.55))}
.sh-art .sh-art-blink{position:absolute;left:0;top:0}
@media (max-width:700px){
  /* On a phone the bubble stands beside the figure: the figure takes the whole box. */
  .sh-art .sh-bob{height:100%}
}




/* The log (0-log.js, owner 2026-10-07). The LOG button: faint small text in the bottom right corner of the screen, under the
   Stats button and right of the items-per-touch buttons on a desktop (24 px high, below their 26 px), in the empty band under
   the dock on a phone (40 px high in a 48 px band). It is page markup over every screen of the game (z-index 50), so it
   shows also over a white or black 3D view after a lost WebGL context. It shows from the first warning or error, with their
   count, and turns a faint red once an error is in the log. */
.glog-btn{position:fixed;right:env(safe-area-inset-right,0px);bottom:env(safe-area-inset-bottom,0px);z-index:50;min-width:44px;height:24px;margin:0;padding:0 6px;
  border:0;background:none;color:rgba(255,255,255,.2);font:10px/24px var(--mono);letter-spacing:1px;text-align:center;cursor:pointer;
  -webkit-tap-highlight-color:transparent;touch-action:manipulation}
.glog-btn:hover,.glog-btn:focus-visible{color:rgba(255,255,255,.6)}
.glog-btn.bad{color:rgba(248,113,113,.5)}
.glog-btn.bad:hover,.glog-btn.bad:focus-visible{color:rgba(248,113,113,.9)}
.glog-btn[hidden],.glog[hidden]{display:none}
/* The log window (owner, 2026-10-10): StarCode 3's overlay (workspace/starcode-3/js/boot-diagnostics.js, OVL_STYLE and
   _mkButton) as it is there: a dark red band over the top of the screen, at most 40% of its height and scrolling, monospace
   11 px, the buttons Close (red), Copy log (light grey) and Save log (light blue), 44 px high, at its top right, staying
   there while it scrolls. Lines: error red, warning amber, the rest grey. The note under Copy log says whether the copy
   worked (StarCode 3's copy toast). */
.glog{position:fixed;top:0;left:0;right:0;z-index:99999;max-height:40vh;overflow:auto;background:rgba(20,0,0,0.95);color:#f87171;font:11px/1.5 monospace;
  padding:8px 12px;padding-top:max(8px, env(safe-area-inset-top, 0px));white-space:pre-wrap;pointer-events:auto;-webkit-overflow-scrolling:touch}
.glog-bar{position:sticky;top:0;float:right;display:flex;gap:8px;margin:0 0 4px 8px}
.glog-b{min-height:44px;padding:2px 14px;color:#200;border:0;border-radius:4px;font:11px/1.4 monospace;cursor:pointer}
.glog-b.close{background:#f87171}.glog-b.copy{background:#e2e8f0}.glog-b.save{background:#93c5fd}
.glog-list{white-space:pre-wrap;overflow-wrap:anywhere;-webkit-user-select:text;user-select:text}
.glog-e.error{color:#f87171}.glog-e.warn{color:#fbbf24}.glog-e.info,.glog-e.debug{color:#cbd5e1}
.glog-note{position:fixed;z-index:100000;padding:6px 12px;border-radius:6px;font:12px/1.3 system-ui,sans-serif;pointer-events:none;
  box-shadow:0 4px 14px rgba(0,0,0,.45);background:rgba(30,60,40,.95);color:#bff5cf}
.glog-note.bad{background:rgba(60,20,20,.95);color:#fecaca}
.glog-note[hidden]{display:none}
@media (max-width:700px){
  .glog-btn{height:40px;line-height:40px}
}


/* Uniques in all the colours (owner, 2026-10-10). The spectrum (--uq-rainbow; twice over in --uq-rainbow2, so half of it, the
   part a name shows as it slides, is still the whole spectrum) fills a Unique's colour square, its name and
   the words "UNIQUE" of its sell-off show, and frames the item card, the floor label and the slot's pop-up; everything else drawn in the Unique colour (--r-unique and its edge: the item card's
   frame and words, the inventory slot, the floor label, the item pop-ups) runs slowly through the colours of the spectrum
   while a Unique shows on the page. The floor show in the room is in 14-unique-floor.js. With Reduce motion or the system's
   reduced motion the colours stand still: the spectrum stays, and the one colour is a pale blue. A screen without background-
   clip text shows the names in the one colour. */
@property --uq-h{syntax:'<number>';inherits:true;initial-value:200}
:root{--uq-h:200;--r-unique:hsl(calc(var(--uq-h) * 1deg) 95% 76%);--r-unique-edge:hsl(calc((var(--uq-h) + 50) * 1deg) 85% 64%);
  --uq-rainbow:linear-gradient(90deg,#ff6b6b,#ffb45c,#fff07a,#6ef59a,#5cd6ff,#8f8bff,#e77bff,#ff6b6b);
  --uq-rainbow2:linear-gradient(90deg,#ff6b6b,#ffb45c,#fff07a,#6ef59a,#5cd6ff,#8f8bff,#e77bff,#ff6b6b,#ffb45c,#fff07a,#6ef59a,#5cd6ff,#8f8bff,#e77bff,#ff6b6b)}
html:has([style*="--r-unique"],.r-unique,.inv-slot.uq,.uq-name,.uq-title){animation:uq-hue 8s linear infinite}
@keyframes uq-hue{from{--uq-h:0}to{--uq-h:360}}
@keyframes uq-slide{from{background-position:0% 50%}to{background-position:200% 50%}}
@supports ((-webkit-background-clip:text) or (background-clip:text)){
  .tt.r-unique .tt-name,.recent button[style*="--r-unique"],.uq-text,.uq-name b,.uq-title b{
    background:var(--uq-rainbow2);background-size:200% 100%;-webkit-background-clip:text;background-clip:text;color:transparent;-webkit-text-fill-color:transparent;
    text-shadow:none;filter:drop-shadow(0 1px 1px #000) drop-shadow(0 0 6px rgba(0,0,0,.6));animation:uq-slide 6s linear infinite}
}
/* The floor label and the slot's name pop-up keep their dark plate: a frame in the spectrum, the words in the moving colour. */
.lbl[style*="--r-unique"],.slot-tip[style*="--r-unique"],.inspect:has(.tt.r-unique),.sf-box.r-unique{border-image:var(--uq-rainbow) 1}
.st-chip.uq::before,.st-key i.uq,.st-tip .st-sq.uq{background:var(--uq-rainbow)}
@media (prefers-reduced-motion:reduce){ html:has(*){animation:none} .tt.r-unique .tt-name,.uq-text,.uq-name b,.uq-title b{animation:none} }
body:has(#reduceMotion:checked) :is(.tt.r-unique .tt-name,.uq-text,.uq-name b,.uq-title b){animation:none}
html:has(#reduceMotion:checked){animation:none}
