/* Per-game theming: app.js stamps <html data-theme="rs3|osrs"> at boot and in
   setGame(); the :root[data-theme=...] blocks at the bottom override ONLY the
   custom properties (plus a few colour/border/gradient flourishes). The bare
   :root below keeps the original palette, so a missing attribute regresses to
   exactly the pre-theming look. Layout is untouched in every theme. */
:root{
  --ink:#ece3cf; --dim:#b7a583; --faint:#96855f;
  --up:#5ccf7c; --up-bg:rgba(92,207,124,.13);
  --down:#f0685f; --down-bg:rgba(240,104,95,.13);
  --gold:#e3b23c; --gold-bg:rgba(227,178,60,.13); --line:#3a2c14;
  --page:#0d0a06; --panel:#15100a; --panel2:#1f1710;
  /* derived surfaces/accents — MarketWyrm gold-on-black base */
  --line-strong:#5a441f; --on-gold:#241800; --input-bg:#0c0803;
  --seg-on:#241a0d; --hover-bg:#1c1409;
  --row-line:#1c150c; --row-line2:#151009; --row-hover:#140e06;
  --ico-bg:#221a10; --inset-bg:#0f0b06; --tip-bg:#1a130b;
  --warn:#f0a35f; --warn-bg:rgba(240,163,95,.13); --backdrop:rgba(6,4,2,.74); --emph:#ffd873;
  /* --accent is the selection/action hue everywhere a component needs one
     (checkbox accent, admin chart line, progress fills). It was referenced in
     four places and declared nowhere — those components rendered invisible. */
  --accent:var(--gold);
  /* chart palette — chartColors() in app.js reads these once per draw; the
     .t-leg legend chips and the canvas must stay in lockstep through them */
  --ch-price:#e3b23c; --ch-grid:#241a0d; --ch-label:#96855f;
  --ch-res:#a98cd8; --ch-sup:#6fbf5a; --ch-exit:var(--down); --ch-proj:#b7a06a;
  /* bid / ask get their own hues — they used to borrow exit-red and support-green */
  --ch-bid:#4fd1c5; --ch-ask:#ff8fa3;
  --ch-up:var(--up); --ch-down:var(--down);
  --ch-fill:rgba(227,178,60,.08); --ch-tag-bg:rgba(13,10,6,.9);
  --ch-cross:rgba(210,192,150,.4); --ch-ring:#0d0a06;
  --mono:ui-monospace,"Cascadia Code","SF Mono","Roboto Mono",Menlo,monospace;
  --sans:system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;

  /* --- tokens added with the OKLCH palettes (both themes inherit these) --- */
  /* Neutral delta: 0.0% is NOT a gain. Themes override with their own --faint. */
  --flat:#96855f;
  /* Quiet gold: headings/decoration. --gold stays for ACTION only, so the CTA
     is the brightest gold on screen instead of being outshone by inert labels. */
  --gold-quiet:#b79345;
  /* Elevation. On dark UI depth reads as LIGHTNESS, so --edge (a top catchlight)
     does most of the work and the shadows only ground the surface. Negative
     spread is deliberate: it keeps the shadow under the card, not smeared. */
  --edge:inset 0 1px 0 rgba(255,255,255,.05);
  --sh-1:0 2px 8px -2px rgba(0,0,0,.45);
  --sh-2:0 8px 22px -6px rgba(0,0,0,.5);
  --sh-3:0 20px 44px -12px rgba(0,0,0,.6);
  /* Type scale. Replaces 25 ad-hoc sizes, 12 of which sat inside three sub-1px
     bands (9/9.5/10/10.5, 11/11.5, 12/12.5) — differences nobody can see but
     every one of which had to be maintained. Seven steps, one unit.
     1 micro-label · 2 meta · 3 secondary UI · 4 table body · 5 body
     6 heading · 7 display / hero numerals.
     The auth card deliberately opts out: it scales in em from a viewport-keyed
     root so the whole panel resizes as one unit. Do not tokenise it. */
  --fs-1:10.5px; --fs-2:11.5px; --fs-3:12.5px; --fs-4:13.5px;
  --fs-5:14.5px; --fs-5b:16.5px; --fs-6:19px;   --fs-7:23px;
  /* --fs-5b closes the 14.5 → 19 hole that kept inviting 16/17/18px inventions. */
  /* Radius scale. Was 12 values with no segmented tray concentric with its own
     buttons; OSRS squares them off for the stone look. */
  --r-1:4px; --r-2:7px; --r-3:9px; --r-4:12px;
  /* Pills: one token instead of eleven literal 999px radii — so OSRS can square
     them with the rest of its scale (below). */
  --r-pill:999px;
  /* Brand glow (mascot / gate art / sign-in card) — per theme, so the OSRS
     bronze skin doesn't carry RS3's yellow halo. */
  --glow:rgba(227,178,60,.14);
  /* Loading sheen — must be LIGHTER than --panel2 or the shimmer inverts. */
  --skel-sheen:#3a2e20;
  /* SMA overlays. One hue per window, identical in both themes — the same
     reasoning as --ch-res: an indicator must not change meaning per skin. */
  --ch-sma7:#62b6e0; --ch-sma30:#e08fcf; --ch-sma90:#cfcfcf;
  --ch-rsi:#bda0ff;
  /* (retoned 2026-08-19: MA90 used to be the resistance purple and MA30 sat on the
     price gold — an indicator must not look like a level or like the price. MA90 is
     a neutral grey; bid/ask are teal/pink AND dashed, so no two lines share a look) */
  /* Motion. Four durations by role, three easings. Never animate `all`, never
     width/height — a 250-row table cannot afford layout animation. */
  --dur-1:110ms; --dur-2:180ms; --dur-3:240ms; --dur-4:380ms;
  --ease-out:cubic-bezier(.22,.61,.36,1);
  --ease-emph:cubic-bezier(.16,.84,.28,1);
  --ease-in:cubic-bezier(.45,0,1,1);
}
/* Per-theme catchlight: neutral on obsidian, warm on stone. */
:root[data-theme="rs3"]{--edge:inset 0 1px 0 rgba(255,255,255,.055);--skel-sheen:#3a3a42;--glow:rgba(230,183,49,.12)}
:root[data-theme="osrs"]{--edge:inset 0 1px 0 rgba(255,236,190,.06);
  /* real bevels are square: rounded corners smear the four-colour border trick */
  --r-1:2px; --r-2:3px; --r-3:4px; --r-4:6px; --r-pill:3px;
  --skel-sheen:#5a4733;--glow:rgba(228,162,80,.12)}
*{box-sizing:border-box}
/* The hidden attribute must beat every display rule (v1 lesson: #loginview's
   flex kept the login form on screen after signing in). */
[hidden]{display:none!important}
html,body{margin:0;height:100%}
/* Use a real scrollbar only when needed. Reserving an empty lane on short
   pages left the header/footer rule and background short of the right edge. */
html{scrollbar-gutter:auto}
body{background:var(--page);color:var(--ink);font-family:var(--sans);
  font-size:var(--fs-5);line-height:1.5;-webkit-font-smoothing:antialiased}
button,select,input{font-family:inherit;font-size:var(--fs-5);color:var(--ink)}
button{cursor:pointer;border-radius:var(--r-3);border:1px solid var(--line);
  background:var(--panel2);padding:8px 14px}
button:hover{border-color:var(--line-strong)}
/* A real disabled treatment: opacity:.4 dropped labels under 3:1. Colour and
   surface carry the state instead, so it stays legible while clearly inert. */
button:disabled{cursor:default;color:var(--faint);background:var(--inset-bg);
  border-color:var(--line);box-shadow:none;filter:saturate(.35)}
button:focus-visible,select:focus-visible,input:focus-visible{outline:2px solid var(--gold);outline-offset:1px}
/* Links, link-cards and the brand get the same gold ring as controls (they
   showed the UA blue ring); text selection stops being UA blue on a gold UI. */
a:focus-visible,.pick:focus-visible,.cat-tile:focus-visible{outline:2px solid var(--gold);outline-offset:2px}
a:not([class]):focus-visible{border-radius:var(--r-1)}
.brand:focus-visible{outline-offset:4px}
::selection{background:var(--gold);color:var(--on-gold)}
input[type=checkbox],input[type=radio]{accent-color:var(--accent)}
button.ghost{background:transparent}
select,input{background:var(--input-bg);border:1px solid var(--line);border-radius:var(--r-3);padding:8px 10px}
/* :not(:focus-visible) is load-bearing — the bare `outline:none` that used to be
   here deleted the ONLY focus ring in the app, leaving keyboard users a 1px
   border tint. Mouse focus stays clean; keyboard focus keeps the ring above. */
input:focus:not(:focus-visible),select:focus:not(:focus-visible){outline:none}
input:focus,select:focus{border-color:var(--gold)}
::placeholder{color:var(--faint);opacity:1}
/* Links default to the action gold (they fell to UA blue wherever a component
   didn't set its own colour — e.g. inside prose in the gate cards). */
a{color:var(--gold)} a:hover{color:var(--emph)}
.num{font-family:var(--mono);font-variant-numeric:tabular-nums}
.up{color:var(--up)} .down{color:var(--down)}
/* Neutral delta. Zero movement is not a gain — app.js picks this class at 0. */
.flat{color:var(--flat)}

/* ---- interaction states -------------------------------------------------
   The generic `button:hover{border-color:var(--line-strong)}` above DOWNGRADES
   every gold control (gold -> dim olive) and is a no-op on the six borderless
   ones (tabs, game switch, modal close). These rules restore the intent: gold
   things brighten, quiet things gain a surface, everything presses. */
.tabs :is(button,a):not(.on):hover,.games :is(button,a):not(.on):hover,
.mchips :is(button,a):not(.on):hover,.menu button:hover,
.ch-tf:not(.on):hover,.ch-chip:not(.on):hover,.ch-mode:not(.on):hover,.wy-seg button:not(.on):hover,
.wy-rng:not(.on):hover,.t-back:hover{
  background:var(--hover-bg);color:var(--ink);border-color:var(--line-strong)}
.mclose:hover{color:var(--ink);background:var(--hover-bg)}
.btn-signin:hover,.msecondary:hover{
  border-color:var(--emph);color:var(--emph);background:var(--gold-bg)}
/* .t-follow (not .on) is now a solid CTA, so it brightens like .mprimary; the
   .on chip's own hover (unfollow → red) is defined with the .t-follow rules. */
.mprimary:hover,.t-follow:not(.on):hover{
  background:var(--emph);border-color:var(--emph)}
/* Press feedback existed only in OSRS, so the DEFAULT theme was the silent one
   — including on touch, where there is no hover to fall back on. */
button:active{transform:translateY(1px)}
.mprimary:active{filter:brightness(.94)}
button,tbody tr,.pick,.cat-tile,.t-item,.mchips :is(button,a){
  -webkit-tap-highlight-color:var(--gold-bg)}
/* Motion: explicit property lists only — never `all`, never width/height. */
button,.tabs :is(button,a),.games :is(button,a),.mchips :is(button,a),.menu button,
.btn-signin,.mprimary,.msecondary,.t-follow,.mclose,.acct-chip,
select,input,tbody tr,.t-item,.pick,.cat-tile,a{
  transition:background-color var(--dur-1) var(--ease-out),
             color var(--dur-1) var(--ease-out),
             border-color var(--dur-2) var(--ease-out),
             box-shadow var(--dur-2) var(--ease-out),
             transform var(--dur-1) var(--ease-out),
             filter var(--dur-1) var(--ease-out)}
@media(prefers-reduced-motion:reduce){
  *,*::before,*::after{transition-duration:1ms!important;animation-duration:1ms!important}
}

/* The header is viewport chrome, not part of any page or advertising grid.
   Its controls keep a small safe edge on every route while the page-specific
   content, tab and ad layouts begin below it. */
.hdr{display:flex;align-items:center;gap:14px;min-height:70px;
  /* viewport-fit=cover + a translucent status bar (index.html) means the bar
     draws UNDER the notch unless it pads the top inset itself. --apphdr-h is
     measured live, so the sticky tab bar follows the taller header. */
  padding:calc(9px + env(safe-area-inset-top)) max(20px,env(safe-area-inset-right)) 9px max(20px,env(safe-area-inset-left));
  background:var(--panel);border-bottom:1px solid var(--line);
  box-shadow:var(--sh-2);
  position:sticky;top:0;z-index:55;flex-wrap:wrap}
.logo{font-size:var(--fs-6);font-weight:500;letter-spacing:-.01em}
/* Shared header brand: the owner's complete v2 wordmark, dragon and market
   orb. It is never cropped; CSS scales the 512×256 web derivative as one unit
   across the shared shell. */
.brand{display:flex;align-items:center;gap:11px;flex:none}
/* The original 1774×887 PNG remains in design-assets/brand; the 512×256 WebP
   keeps the 48px header render sharp without shipping the 2.2 MB source. */
.brand-logo{height:65px;width:auto;display:block;filter:drop-shadow(0 2px 6px rgba(0,0,0,.5))}
@media(max-width:760px){.brand-logo{height:53px}}
.games{display:flex;background:var(--panel2);border-radius:var(--r-3);padding:3px}
.games :is(button,a){background:transparent;border:none;color:var(--dim);padding:6px 13px;
  border-radius:var(--r-2);font-size:var(--fs-4);box-shadow:none;text-decoration:none}
.games :is(button,a).on{background:var(--seg-on);color:var(--ink)}
.hdr-right{margin-left:auto;display:flex;align-items:center;gap:10px}
.search-wrap{position:relative;min-width:200px}
/* The static pages put the search input straight into .hdr-right (no wrap
   element): let it flex and shrink so the "Open the app" link beside it never
   has to fold. */
.hdr-right>.search{flex:1 1 200px;min-width:0;width:auto}
.search{width:100%;background:var(--input-bg)}
/* typeahead dropdown: anchored to the input's right edge so it can grow
   leftwards on desktop without leaving the viewport */
.search-dd{position:absolute;top:calc(100% + 6px);right:0;width:max(100%,320px);z-index:60;
  background:var(--panel);border:1px solid var(--line-strong);border-radius:var(--r-3);
  box-shadow:var(--edge),var(--sh-3);max-height:min(380px,60vh);overflow-y:auto;padding:4px}
.search-dd .dd-row{display:flex;align-items:center;gap:9px;width:100%;text-align:left;
  background:none;border:none;box-shadow:none;padding:7px 9px;border-radius:var(--r-2)}
.search-dd .dd-row:hover,.search-dd .dd-row.on{background:var(--hover-bg)}
.search-dd .dd-row .mi-ico{width:26px;height:26px;flex-shrink:0}
.search-dd .dd-row .mi-ico img{width:22px;height:22px}
.search-dd .dd-row span:last-child{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.search-dd .dd-empty{color:var(--faint);font-size:var(--fs-3);padding:9px}
/* search results page rows click through to the item */
.srch-t tbody tr{cursor:pointer}
.search-board{max-width:1180px;margin:0 auto}
.search-head{align-items:center}
.search-title{display:flex;align-items:center;gap:11px;min-width:0}
.search-title img{width:42px;height:42px;object-fit:contain;filter:drop-shadow(0 2px 8px var(--glow))}
.search-title span{display:flex;flex-direction:column;gap:1px;min-width:0}
.search-title b{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.search-tools{display:flex;align-items:center;justify-content:space-between;gap:12px;
  padding:9px 14px;border-top:1px solid var(--row-line);border-bottom:1px solid var(--line);
  background:var(--inset-bg)}
.search-pager{padding:0;align-items:center;justify-content:flex-end;flex-wrap:wrap}
.search-pager button{padding:6px 12px;font-size:var(--fs-3)}
.back{background:transparent;border:none;color:var(--dim);font-size:var(--fs-5);padding:6px 4px;box-shadow:none}
.back:hover{color:var(--ink)}

.acct-slot{display:flex}
.btn-signin{background:transparent;border:1px solid var(--gold);color:var(--gold);
  border-radius:var(--r-3);padding:8px 16px;font-size:var(--fs-4);font-weight:500;
  white-space:nowrap;flex:none}   /* "Open the app" on the static pages was folding onto two lines */
.acct{position:relative}
.acct-chip{display:flex;align-items:center;gap:8px;background:var(--panel2);
  border:1px solid var(--line);border-radius:var(--r-3);padding:5px 10px 5px 6px;font-size:var(--fs-4)}
.acct-chip .av{width:24px;height:24px;border-radius:var(--r-2);background:var(--gold-bg);
  color:var(--gold);display:flex;align-items:center;justify-content:center;font-weight:500;font-size:var(--fs-3)}
.acct-chip .cv{color:var(--faint);font-size:var(--fs-2)}
.menu{position:absolute;top:44px;right:0;width:190px;background:var(--panel2);
  border:1px solid var(--line);border-radius:var(--r-3);padding:6px;z-index:30;
  box-shadow:var(--edge),var(--sh-2)}
.menu[hidden]{display:none}
.menu button{display:flex;align-items:center;gap:9px;width:100%;text-align:left;background:transparent;
  border:none;padding:8px 10px;border-radius:var(--r-2);font-size:var(--fs-4);color:var(--dim);box-shadow:none}
.menu button .ico{color:var(--faint);width:16px;height:16px;margin-right:0}
.menu button:hover .ico{color:var(--gold)}
.acct-chip .cv.ico{width:12px;height:12px;margin-left:2px}
.menu button:hover{background:var(--hover-bg);color:var(--ink)}
.menu .sep{height:1px;background:var(--line);margin:5px 6px}


.subbar{display:flex;align-items:center;gap:16px;
  padding:10px max(20px,calc((100% - 1500px) / 2));
  border-bottom:1px solid var(--line);background:var(--panel);flex-wrap:wrap}
/* App chrome layering: top bar (55) > tab bar (50) > detail overlay (40), so
   the whole header stays visible and clickable on every view, item pages
   included. The account dropdown (.menu, z 30 INSIDE the bar's context) must
   outrank the tab bar, which is why the two bars can't share one z value.
   --apphdr-h / --chrome-h are measured live in app.js (the bars wrap and grow
   on narrow screens). Phones skip the sticky tab bar — their tabs are the
   fixed bottom nav (see the 640px block). */
@media(min-width:641px){
  .subbar{position:sticky;top:var(--apphdr-h,70px);z-index:50}
}
.tabs{display:flex;gap:2px;background:var(--panel2);border-radius:var(--r-3);padding:3px}
.tabs :is(button,a){background:transparent;border:none;color:var(--dim);padding:7px 15px;
  border-radius:var(--r-2);font-weight:500;box-shadow:none;text-decoration:none}
.tabs :is(button,a).on{background:var(--seg-on);color:var(--ink)}
/* ---- icon set: the inline sprite at the top of the page, used via <use>. 1em,
   currentColor stroke, so an icon takes the size and colour of its text — drop
   it in front of a label and it just fits. pointer-events off so click
   delegation sees the button, not the svg. ---- */
.sprite{position:absolute;width:0;height:0;overflow:hidden}
.ico{width:1em;height:1em;display:inline-block;vertical-align:-.15em;fill:none;stroke:currentColor;
  stroke-width:2;stroke-linecap:round;stroke-linejoin:round;flex:none;pointer-events:none}
.tabs a .ico,button .ico,.t-chip .ico,.t-back .ico{margin-right:.4em}
.tabs a .ico:only-child,button .ico:only-child,.mclose .ico,.t-burger .ico,.wl-actions .ico{margin-right:0}
.t-back .ico{margin-right:.2em}
.t-chip .ico{width:.85em;height:.85em;margin:0 0 0 .15em;order:2}
.t-follow .ico{width:1.05em;height:1.05em;vertical-align:-.2em}
.t-follow.on .ico{fill:currentColor}
.mclose .ico{width:18px;height:18px}
.t-burger .ico{width:17px;height:17px}
.wl-actions .ico{width:14px;height:14px;vertical-align:-.1em}
.ch-lk .ico{width:.85em;height:.85em;vertical-align:-.1em}
.tabs .ico{display:none}          /* desktop tabs stay text; the phone nav below turns them on */
.tabs .lk{display:inline-block;margin-left:.3em}
.tabs .lk .ico{display:inline-block;width:.8em;height:.8em;margin:0;vertical-align:-.05em}
.tabs .coming-soon{position:relative;overflow:hidden;color:var(--gold);
  box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--gold) 30%,transparent);
  background:linear-gradient(180deg,color-mix(in srgb,var(--gold) 10%,transparent),transparent)}
.tabs .coming-soon::before{content:"";position:absolute;inset:-20% auto -20% -42%;width:28%;
  pointer-events:none;transform:skewX(-18deg);opacity:0;
  background:linear-gradient(90deg,transparent,color-mix(in srgb,var(--gold) 28%,transparent),transparent);
  animation:soon-sheen 4.5s ease-in-out infinite}
.tabs .soon-tag{display:inline-flex;align-items:center;margin-left:.4em;padding:1px 4px;
  border:1px solid color-mix(in srgb,var(--gold) 55%,transparent);border-radius:var(--r-pill);
  color:var(--gold);background:color-mix(in srgb,var(--gold) 9%,transparent);
  font:700 7px/1.35 var(--mono);letter-spacing:.1em;vertical-align:.16em}
@keyframes soon-sheen{0%,70%{left:-42%;opacity:0}76%{opacity:.8}92%{left:120%;opacity:0}100%{left:120%;opacity:0}}
@media(prefers-reduced-motion:reduce){.tabs .coming-soon::before{animation:none}}
.tools{margin-left:auto;display:flex;align-items:center;gap:14px;flex-wrap:wrap}
.ctl{display:flex;align-items:center;gap:6px;color:var(--dim);font-size:var(--fs-3)}
.ctl select{padding:6px 8px}
/* Data-freshness chip: a always-visible pill with a state dot. Green pulse =
   feed current (OSRS: live prices <=3 min old; RS3: guide price <26 h).
   Amber = delayed. Neutral dot = transient messages (lookups, errors). */
.status{display:inline-flex;align-items:center;gap:7px;color:var(--dim);font-size:var(--fs-3);
  background:var(--panel2);border:1px solid var(--line);border-radius:var(--r-pill);padding:5px 12px;
  white-space:nowrap;max-width:min(360px,56vw);overflow:hidden}
/* Fixed 14px well: the dot grows to 14px in the busy state, which used to
   reflow the whole pill by 7px on every status change. */
.status::before{content:"";width:14px;height:14px;border-radius:50%;
  background:var(--faint);flex-shrink:0;box-shadow:inset 0 0 0 3.5px var(--panel2);
  transition:background-color var(--dur-2) var(--ease-out),box-shadow var(--dur-2) var(--ease-out)}
.status.live::before{background:var(--up);box-shadow:0 0 6px var(--up)}
.status.stale{color:var(--warn)}
.status.stale::before{background:var(--warn);box-shadow:0 0 6px var(--warn)}
/* busy: the dot becomes a softly pulsing wyrm mascot while a scan or lookup runs */
.status.busy::before{width:14px;height:14px;border-radius:50%;box-shadow:none;
  background:url("/assets/hero-alpha.webp") center/cover no-repeat;
  animation:coinpulse 1.2s ease-in-out infinite}
@keyframes coinpulse{50%{opacity:.4}}
@media(prefers-reduced-motion:reduce){.status.busy::before{animation:none}}

/* Scope to #main only — the detail panel is also a <main> (.t-mid); a bare
   `main` selector leaked margin:0 auto onto it and collapsed the grid column. */
#main{width:100%;max-width:1760px;margin:0 auto;padding:18px 22px 24px}
.page-head{width:100%;max-width:1500px;margin:0 auto 16px;min-width:0}
.page-head:empty{display:none}
.page-head h1{margin:0;color:var(--emph);font-family:var(--display);font-size:clamp(22px,3vw,34px);
  font-weight:600;line-height:1.15;letter-spacing:-.015em}
.page-head p{max-width:76ch;margin:7px 0 0;color:var(--dim);font-size:var(--fs-4);line-height:1.55}
.list-directory{display:grid;grid-template-columns:repeat(auto-fit,minmax(235px,1fr));gap:12px;max-width:1100px;margin:0 auto}
.list-group{grid-column:1/-1;margin:12px 0 0;color:var(--faint);font-size:var(--fs-2);font-weight:600;
  letter-spacing:.08em;text-transform:uppercase}
.list-card{display:flex;align-items:center;gap:12px;min-height:72px;padding:14px 16px;border:1px solid var(--line);
  border-radius:var(--r-3);background:var(--panel);text-decoration:none;color:var(--ink);box-shadow:var(--edge),var(--sh-1)}
.list-card:hover{border-color:var(--line-strong);background:var(--hover-bg);color:var(--emph)}
.list-card .list-icon{font-size:25px;font-weight:700;line-height:1}
.list-card.is-up .list-icon{color:var(--up)}
.list-card.is-down .list-icon{color:var(--down)}
.list-card strong{display:block}.list-card small{display:block;margin-top:3px;color:var(--faint)}
/* Featured GE-list directory only. Related-list links elsewhere retain their
   smaller existing cards; these six destinations form one balanced board. */
.list-directory-featured{width:100%;max-width:1500px;min-width:0;margin:0 auto;
  grid-template-columns:repeat(3,minmax(0,1fr));gap:14px;align-content:start;align-items:stretch}
.list-directory-featured .list-card{--list-accent:var(--gold);position:relative;isolation:isolate;
  display:grid;grid-template-columns:52px minmax(0,1fr);grid-template-rows:1fr auto;
  align-items:start;gap:20px 16px;min-width:0;min-height:225px;padding:22px 20px 18px;
  overflow:hidden;border:1px solid color-mix(in srgb,var(--list-accent) 24%,var(--line));
  border-top:3px solid var(--list-accent);border-radius:var(--r-4);color:var(--ink);
  background:linear-gradient(125deg,color-mix(in srgb,var(--list-accent) 7%,var(--panel)),var(--panel) 64%);
  box-shadow:var(--edge),0 3px 12px rgba(0,0,0,.18);
  transition:border-color var(--dur-2) var(--ease-out),box-shadow var(--dur-2) var(--ease-out)}
.list-directory-featured .list-card.is-up{--list-accent:var(--up)}
.list-directory-featured .list-card.is-down{--list-accent:var(--down)}
.list-directory-featured .list-card.is-gold{--list-accent:var(--gold)}
.list-directory-featured .list-card:hover{border-color:var(--list-accent);
  background:linear-gradient(125deg,color-mix(in srgb,var(--list-accent) 11%,var(--panel)),var(--panel) 72%);
  box-shadow:var(--edge),0 5px 20px rgba(0,0,0,.25)}
.list-directory-featured .list-card:focus-visible{outline:2px solid var(--list-accent);outline-offset:3px}
.list-directory-featured .list-card-art{position:absolute;z-index:-1;top:10px;right:0;
  width:48%;height:140px;color:var(--list-accent);opacity:.13;pointer-events:none;overflow:hidden}
.list-directory-featured .list-card-art svg{display:block;width:100%;height:100%}
.list-directory-featured .list-icon{display:flex;grid-column:1;grid-row:1;align-items:center;justify-content:center;
  width:52px;height:52px;border:1px solid color-mix(in srgb,var(--list-accent) 24%,transparent);
  border-radius:6px;color:var(--list-accent);font-size:34px;line-height:1;
  background:color-mix(in srgb,var(--list-accent) 7%,var(--panel))}
.list-directory-featured .list-card-copy{grid-column:2;grid-row:1;min-width:0}
.list-directory-featured .list-card-group{display:block;color:var(--faint);font-size:10px;
  font-weight:600;line-height:1.3;letter-spacing:.065em;text-transform:uppercase}
.list-directory-featured .list-card-copy h2{margin:7px 0 9px;color:var(--ink);font-family:var(--sans);
  font-size:18px;font-weight:700;line-height:1.25;letter-spacing:-.015em}
.list-directory-featured .list-card-copy p{max-width:34ch;margin:0;color:var(--dim);font-size:12.5px;line-height:1.6}
.list-directory-featured .list-card-bottom{display:flex;grid-column:1/-1;grid-row:2;min-width:0;
  align-items:center;justify-content:space-between;gap:10px;flex-wrap:wrap}
.list-directory-featured .list-card-tags{display:flex;min-width:0;align-items:center;gap:6px;flex-wrap:wrap}
.list-directory-featured .list-card-tags>span{padding:4px 8px;border:1px solid color-mix(in srgb,var(--list-accent) 20%,var(--line));
  border-radius:999px;color:var(--dim);background:color-mix(in srgb,var(--list-accent) 5%,var(--panel));
  font-size:10px;line-height:1.2;white-space:nowrap}
.list-directory-featured .list-card-cta{display:inline-flex;align-items:center;gap:8px;margin-left:auto;
  color:var(--gold);font-size:11px;font-weight:600;line-height:1.4;white-space:nowrap}
:root[data-ad-surface="list-directory"] #results{min-width:0}
/* This six-card directory has room for the standard horizontal footer unit.
   Audience/consent exclusions still use the shared .ad-hidden/.ad-empty rules;
   the runtime chooses 728×90 when it fits and 320×50 on smaller viewports. */
:root[data-ad-surface="list-directory"] body>:is(.ad-footer,.mw-brand-footer){max-width:728px}
@media(min-width:1280px){
  :root[data-ad-surface="list-directory"] .page-head.has-compact468{min-height:calc(63px + var(--fs-1)*1.4)}
}
@media(min-width:1560px){
  /* Out-of-flow rails reserve only their horizontal gutters, never their
     618px zone in the short directory's title/card grid rows. */
  :root[data-ad-surface="list-directory"][data-ad-rail-layout="1"] #main>:is(.ad-rail:is(.ad-live,.ad-pending,.ad-placeholder,.ad-template),.mw-brand-rail){
    position:fixed;top:var(--ad-rail-sticky-top);z-index:2;display:flex!important;
    min-height:var(--ad-rail-zone-h);margin:0;flex-direction:column;justify-content:center}
  :root[data-ad-surface="list-directory"][data-ad-rail-layout="1"] #main>:is(.ad-homeleft:is(.ad-live,.ad-pending,.ad-placeholder,.ad-template),.mw-brand-homeleft){
    right:auto;left:max(22px,calc((100% - 1860px)/2))}
  :root[data-ad-surface="list-directory"][data-ad-rail-layout="1"] #main>:is(.ad-railright:is(.ad-live,.ad-pending,.ad-placeholder,.ad-template),.mw-brand-railright){
    right:max(22px,calc((100% - 1860px)/2));left:auto}
}
@media(max-width:1099px){.list-directory-featured{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media(max-width:760px){
  .list-directory-featured{grid-template-columns:minmax(0,1fr);gap:12px}
  .list-directory-featured .list-card{min-height:205px;padding:18px 16px 16px;gap:18px 14px}
}
@media(prefers-reduced-motion:reduce){.list-directory-featured .list-card{transition:none}}
.list-more{max-width:1500px;margin:18px auto 0;padding-top:16px;border-top:1px solid var(--line)}
.list-more h2{margin:0 0 10px;color:var(--emph);font-size:var(--fs-4)}
.seo-list-links{display:grid;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));gap:8px}
.seo-list-links a{display:block;padding:9px 11px;border:1px solid var(--line);border-radius:var(--r-2);
  background:var(--panel);text-decoration:none}
@media(max-width:640px){.page-head{margin-bottom:12px}.page-head h1{font-size:23px}}

/* ===== full-bleed from 1544px =====
   Where the 1500 cap would start leaving margins, the chrome spans the page
   with 22px gutters (the Overview and the lists follow — see .market). The
   rail block below re-sets these to its 202px inset from 1560px. */
@media(min-width:1544px){
  #main{max-width:none}
  .hdr,.subbar{padding-left:22px;padding-right:22px}
  /* .mchips / .site-foot are declared further down; their 1544 rules sit just
     ahead of the 1560 chips block so the cascade reads top-down. */
}

/* ===== side-rail gutters =====
   Above 1560px eligible public data routes reserve symmetric gutters around
   the content only while the rail is pending/live (or in admin template
   mode). Ads-off, excluded-audience, local non-template, and no-fill states
   remove the data-ad-rail-layout stamp and return the full width. One real
   160x600 unit sits in the right gutter. Symmetry keeps
   tables centred without shipping a blank second ad slot. The gutters + gaps
   + padding take 404px: at 1560 the column is 1156px
   and a two-up board 570px, exactly what three 118px wells + an ellipsised
   name need. Every column that is on at 1559 must still FIT at 1560, or it
   would flip off the moment the rails arrive — so the band waits until the
   rail column reaches 640px boards (1716px), and Trends' extra tiers wait for
   their widths too. Compact lists never substitute an in-feed row below 1560.
   The two gutters are equal, so the content column stays
   viewport-centred and anything centred (the chips, the overview boards) stays
   aligned with it — only the left edge moves, which is what the .subbar/.mchips
   rules below follow. Private tools and short directory pages never receive
   the data-ad-rail-layout stamp and keep the full-width layout. Keep
   1560/160/20 in step with RAIL_MIN and the rail unit in ads.js.
   NO CAP: the page fills the viewport — rails at the edges, the content column
   takes everything between (owner, 2026-08-19: the outer margins on a 2560
   monitor were the dead space, twice). What the column holds at each width is
   decided below: the Overview goes three-up from 2100px; the single-table
   views (All Items, Long-term Trends) keep their own caps because five
   columns across 2000px is a void, not a layout. */
@media(min-width:1560px){
  :root[data-ad-rail-layout="1"] #main{max-width:none;display:grid;column-gap:20px;
    grid-template-columns:160px minmax(0,1500px) 160px;
    grid-template-rows:auto auto auto auto;justify-content:center}
  /* Everything that isn't a rail lives in the middle track, stacked in source
     order. Explicit, because auto-placement would drop #results into the right
     rail's column. */
  :root[data-ad-rail-layout="1"] #main>#page-head,
  :root[data-ad-rail-layout="1"] #main>#results,
  :root[data-ad-rail-layout="1"] #main>#wyrm-root,
  :root[data-ad-rail-layout="1"] #main>#seo-item{grid-column:2}
  :root[data-ad-rail-layout="1"] #main>#page-head{grid-row:1}
  :root[data-ad-rail-layout="1"] #main>#results{grid-row:2}
  :root[data-ad-rail-layout="1"] #main>#seo-item{grid-row:3}
  :root[data-ad-rail-layout="1"] #main>#wyrm-root{grid-row:4}
  /* The tab bar tracks the content column's new left edge, so it stays flush
     with the table under it instead of seaming off to the left. Same figure the
     grid produces: gutter + 22px page padding + 160px rail + 20px gap. */
  :root[data-ad-rail-layout="1"] .subbar{padding-left:202px;padding-right:202px}
}

/* App-page footer: the same legal links + Jagex disclaimer the standalone
   pages carry. On phones the tab bar is fixed to the bottom edge, so the
   footer clears it with its own padding. */
/* Share the homepage's minimum-height shell: spare viewport height belongs
   to main, never to a blank strip after the footer. Grid content keeps its
   natural spacing instead of stretching the title and table tracks. */
body:has(>.site-foot){display:flex;height:auto;min-height:100dvh;flex-direction:column}
body:has(>.site-foot)>#main{flex:1 0 auto;align-content:start}
.site-foot{width:100%;max-width:none;flex-shrink:0;margin:0;padding:10px max(18px,calc((100% - 1500px)/2)) 14px;color:var(--faint);
  font-size:var(--fs-2);line-height:1.6;text-align:center;border-top:1px solid var(--line)}

.site-foot a{color:var(--faint)}
.site-foot a:hover{color:var(--ink)}
@media(max-width:640px){.site-foot{padding:14px max(12px,env(safe-area-inset-right)) calc(112px + env(safe-area-inset-bottom)) max(12px,env(safe-area-inset-left))}}

/* ===== Market (public browse) ===== */
/* Capped WITH .market.overview (1500 + 2x20 gutter) so the chips stay flush
   with the boards below them instead of seaming off to the left. */
.mchips{display:flex;gap:8px;padding:10px 20px 2px;max-width:1540px;margin:0 auto;
  overflow-x:auto;scrollbar-width:none;
  -webkit-mask-image:linear-gradient(90deg,#000 calc(100% - 26px),transparent);
          mask-image:linear-gradient(90deg,#000 calc(100% - 26px),transparent)}
.mchips :is(button,a){background:transparent;border:1px solid var(--line);border-radius:var(--r-pill);
  color:var(--dim);padding:5px 15px;font-size:var(--fs-3);white-space:nowrap;box-shadow:none;text-decoration:none}
.mchips :is(button,a).on{border-color:var(--line-strong);color:var(--emph);background:var(--seg-on)}
/* Full-bleed from 1544px: chips and footer span the page with 22px gutters,
   matching the header/tab bar rules near the top. */
@media(min-width:1544px){
  .mchips{max-width:none;padding-left:22px;padding-right:22px}
}
/* Rails on: the chips follow the narrowed content column. The footer is
   viewport chrome, so its background and top rule never stop at a page-grid
   edge or move when an ad/template state changes. */
@media(min-width:1560px){
  /* 364 = both rails + both gaps + the 4px that keeps the chips' own 20px
     padding inside the column, so chip content lines up with the boards. */
  :root[data-ad-rail-layout="1"] .mchips{max-width:calc(100% - 364px);padding-left:20px;padding-right:20px}
}
/* Dashboard grid: boards pack two-up on wide screens instead of stretching
   a three-column table across the whole viewport; pulse, picks, and the big
   paged tables span the full row. Numeric columns get a fixed width so the
   item name column absorbs the slack — no more empty chasm mid-table. */
/* Centred at the SAME 1500px cap as .market.overview and the chip row (1540 −
   2×20 chip padding): the paged tables used to sit left-aligned at 1400px under
   a centred chip row, seaming off by up to ~80px (1540-1700px) and ~108px past
   1904px. One cap, one centre — the chips, the boards and the tables share an
   edge at every width. */
.market{display:grid;grid-template-columns:repeat(auto-fit,minmax(430px,1fr));
  gap:16px;max-width:1500px;margin-inline:auto;align-items:start}
@media(max-width:900px){.market{grid-template-columns:1fr}}
/* Overview: balanced 2×2 board grid (traded|valuable / risers|fallers).
   From 1544px (where the 1500 cap would start leaving margins) it FILLS the
   page — 22px gutters, then the rails' 202px inset from 1560 — and the extra
   width goes into the sparkline column (see .spk rules), not into a void
   beside the item name. The shared chrome (header, tab bar, chips, footer)
   fills with it so everything keeps one left edge; the single-table lists
   (All Items, categories) keep their 1500 cap but sit on that same edge. */
.market.overview{grid-template-columns:1fr 1fr}
/* Two-up boards need ~520px each to hold a 3-well row beside a readable
   name; below 1100px they stack (the old 900 cut-over clipped the last column
   of "Most valuable" on small laptops). */
@media(max-width:1099px){.market.overview{grid-template-columns:1fr}}
@media(min-width:1544px){
  .market.overview{max-width:none}
  .market:not(.overview){margin-inline:0}
  /* chrome (header, tab bar, chips, footer) follows in the block ahead of the
     rail gutters, so the 1560px rail insets can still override it */
}

.market>.pulse,.market>.b-full,.market>.empty,.market>.cat-grid{grid-column:1/-1}
.board td:not(.l),.board th:not(.l){width:118px}
/* The 1px `gap` used to be drawn by painting the CONTAINER in --line, so any
   row the auto-fit grid left incomplete showed as a raw slab of border colour.
   Panel ground + per-cell hairline gives the same seam with no slab. */
.pulse{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:1px;
  background:var(--panel);border:1px solid var(--line);border-radius:var(--r-4);overflow:hidden;
  box-shadow:var(--edge),var(--sh-1)}
.pulse>*{background:var(--panel);padding:10px 14px;
  box-shadow:0 0 0 1px color-mix(in srgb,var(--gold) 14%,var(--row-line));
  text-decoration:none;color:inherit;min-width:0}
/* Item tiles (busiest / top riser) are links to the item: name shown, whole
   tile clickable. The item name rides in the label line in the ink colour,
   not the uppercase faint of the label itself. */
.pulse a.pt{display:flex;align-items:center;gap:11px}
.pulse a.pt:hover{background:var(--hover-bg)}
.pulse a.pt .mi-ico{flex:none}
.pulse .pt-t{display:block;min-width:0;font-size:inherit;color:inherit;text-transform:none;letter-spacing:0;margin:0}
/* riser / faller tiles: a breath of their direction behind the numbers */
.pulse>a.pt.t-up{background:color-mix(in srgb,var(--up) 6%,var(--panel))}
.pulse>a.pt.t-up:hover{background:color-mix(in srgb,var(--up) 11%,var(--panel))}
.pulse>a.pt.t-down{background:color-mix(in srgb,var(--down) 6%,var(--panel))}
.pulse>a.pt.t-down:hover{background:color-mix(in srgb,var(--down) 11%,var(--panel))}
.pulse a.pt span{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.pulse span i{font-style:normal;text-transform:none;letter-spacing:0;color:var(--dim)}
.pulse a.pt:hover span i{color:var(--ink)}
/* Inset ring: .pulse is overflow:hidden, so an outside ring was cut on every
   edge flush with the strip's border. */
.pulse a.pt:focus-visible{outline:2px solid var(--gold);outline-offset:-2px}
.pulse a.pt:focus:not(:focus-visible){outline:none}
.pulse b{display:block;font-family:var(--mono);font-variant-numeric:tabular-nums;
  font-size:var(--fs-7);color:var(--ink);line-height:1.2;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}   /* never clip mid-glyph */
/* `.pulse b` (0-1-1) used to out-rank `.up` (0-1-0): the top-riser figure was
   painted ink, never green. */
.pulse b.up{color:var(--up)}
.pulse b.down{color:var(--down)}
/* Mono is for NUMERALS. Prose in a metric slot ("28h ago") gets the sans
   back, and the tabular guarantee moves into CSS so alignment no longer
   depends on app.js remembering to emit class="num". */
.pulse b.txt{font-family:var(--sans);letter-spacing:-.01em}
tbody td,thead th,.perf-t td,.perf-t th{font-variant-numeric:tabular-nums}
.pulse span{font-size:var(--fs-1);color:var(--faint);text-transform:uppercase;letter-spacing:.07em;
  display:block;margin-bottom:3px}
/* freshness tile's live dot (reuses the header coin's pulse) */
.pt-dot{display:inline-block;width:7px;height:7px;border-radius:50%;background:var(--up);
  margin-right:8px;vertical-align:1px;animation:coinpulse 1.2s ease-in-out infinite}
/* breadth split bar: green share of movers over a dim red track */
.pulse .bd{display:block;height:3px;border-radius:2px;margin-top:7px;margin-bottom:0;overflow:hidden;
  background:color-mix(in srgb,var(--down) 40%,var(--panel2))}
.pulse .bd i{display:block;height:100%;background:var(--up);border-radius:2px}
/* Elevation: on dark UI depth reads as lightness, so --edge (top catchlight)
   carries it and the shadow only grounds the card. */
.board{background:var(--panel);border:1px solid var(--line);border-radius:var(--r-4);overflow:hidden;
  box-shadow:var(--edge),var(--sh-1)}
.board .b-head{display:flex;align-items:baseline;justify-content:space-between;
  padding:11px 16px 8px;gap:10px}
/* GOLD TIERS: headings are decoration, so they take the quiet gold. Full --gold
   is reserved for ACTION. Previously four inert board headings per screen were
   painted the same gold as the primary CTA — and since .btn-signin is only an
   outline, the headings were literally brighter than the button they compete
   with. This one substitution makes the CTA the brightest gold on the page. */
.board .b-head b{color:var(--gold-quiet);font-size:var(--fs-4);letter-spacing:.01em}
.board .b-head a{color:var(--faint);font-size:var(--fs-2);text-decoration:none}
.board .b-head a:hover{color:var(--emph)}
.board .b-sub{color:var(--faint);font-size:var(--fs-2)}
.board table{font-size:var(--fs-4)}
.board tbody td{padding:9px 14px}
.board thead th{padding:8px 14px}
.board td.market-data-none{color:var(--faint);font-family:var(--sans);font-size:var(--fs-2);
  font-variant-numeric:normal;white-space:nowrap}
.board .mi-ico{width:30px;height:30px}
.board .mi-ico img{width:26px;height:26px}
.board .mi b{font-size:var(--fs-4)}
/* Members-only marker: the OSRS gold star (wiki Member_icon.png), inlined as a
   data URI so it costs no request and needs no sw precache entry. It's a 16px
   sprite, so keep it pixelated rather than letting it blur when scaled down. */
.mbadge{display:inline-block;width:12px;height:12px;margin-left:6px;vertical-align:0;
  background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IB2cksfwAAACBjSFJNAAB6JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAABm0lEQVR42qWR20sCQRTG+zN6DbKiG90ou2ltUalhhUQRFb1UDz31z3lFSnIzNO9JF3rUNci77qq7xteMxSqYW9LAxwwz5/zON+d0tVvq3m40q12cIuDtaha1Gv4BcKplQMfJSfsgks45lILHMqSz6o4RpNwMyrFzZQB9+ElZVouizwDx6Qwfr5doF/ddbRRploEQ3oUYO0QluodycBuVsBHS4xEFUBd1CZEDutOcBiBu6UfCSiA3i+D9elQjRojRTYgRHaSYCbXnU0gvFxCiJ0i715Cwj9Ec+VtfEHMvkQoZ1zh43yLE0Aqk8Cqk6AaBbUEIGpFxaxC3DtK41p7Qi4S5B5y1D3l2CtWglgCWiRhyZpC/nSOTGQJnUSk3NGlTIeeeRCWwRFwwRMvkrEXhbh5p17ScrAAYQI5VoxzSk0bqwHs14H0L4O9XwQcMvwM4CvAs1SdR8huRcs3g/XoMWY8GQmhH2T5n7yMaRsG7jurDvjzrhIXc24aRYVeIM5MMabVv7SfVpiAE9HJQo8EqcI4JFL269oBm/fX9Eyx6ibFdmY1ZAAAAAElFTkSuQmCC") center/contain no-repeat;
  image-rendering:pixelated}
/* Sparkline cells: a 100px sprite in a 14px-padded cell = a 128px well, the
   same height as a number cell, reserved before the series arrive (no shift
   when they do). Colour follows the 30-day direction through the same
   --up/--down/--flat channel the percent cells use; the area fill is the
   line's own colour at 12%.
   The SVG is fluid (preserveAspectRatio none, non-scaling strokes) up to a
   320px cap; past that the row's spare width is shared by every column. */
.board td.spk,.board th.spk{width:128px;min-width:118px;text-align:right}
/* A column shows or it doesn't — never a header over clipped cells. The
   boards are two-up; the cut-overs are set by what FITS in the widest board
   (fixed layout from 1100px: wells 118px, band 22%, name = the rest, names
   ellipsise). board = (column − 16) / 2:
     band        ≥1716px (640px board beside the rails; the name keeps ~140px)
     + 7d / 30d  ≥2140px (board ≥860 with rails)
   Below those the columns are display:none, header and cells alike.
   THE BAND IS CAPPED AT 320px (owner: "the graph is too long"). Whatever
   width is left over is shared by every column as breathing room — the
   normal look of a wide table — never one giant cell. */
.w-only,.w-only2{display:none}
.spk-svg,.spk-ph{max-width:320px;margin-left:auto}
@media(min-width:1100px){
  /* Fixed layout from the two-up width so every column is a KNOWN share:
     wells 118px, the band (when on) 22% of the board with the SVG capped at
     320px, the item name gets what is left and ellipsises — a board can
     never clip its last column, and auto layout can't dump all the slack
     into one column (it did: first the band, then the name). */
  .market.overview .board table{table-layout:fixed;width:100%}
  .market.overview .board td.spk,.market.overview .board th.spk{width:22%}   /* clamp() is not honoured on table columns */
  .market.overview .board td:not(.l):not(.spk),.market.overview .board th:not(.l):not(.spk){width:118px}
  .market.overview .board .mi{min-width:0}
  .market.overview .board .mi span{display:block;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
}
/* 7d / 30d need name ≥150 + five wells + band min in a board: ≥860px, i.e. a
   2140px window with the rails on. */
@media(min-width:2140px){.market.overview .w-only{display:table-cell}}
/* Below 1716px the two-up boards beside the rails can't hold the band (phones
   drop it through .p-hide anyway). */
@media(max-width:1715px){
  .market.overview td.spk,.market.overview th.spk{display:none}}
.spk-ph{display:block;width:100%;min-width:100px;height:30px;border-radius:var(--r-1);
  background:linear-gradient(90deg,var(--panel2) 25%,var(--skel-sheen) 50%,var(--panel2) 75%);
  background-size:200% 100%;animation:skel 1.2s linear infinite;opacity:.6}
.spk-ph.none{background:none;animation:none;color:var(--faint);text-align:right;line-height:30px;opacity:1;font-family:var(--mono)}
@media(prefers-reduced-motion:reduce){.spk-ph{animation:none;background:var(--panel2)}}
.spk-svg{display:block;width:100%;height:30px;overflow:visible}
.spk-svg .spk-l{fill:none;stroke:var(--flat);stroke-width:1.5;stroke-linejoin:round;stroke-linecap:round}
.spk-svg .spk-a{fill:var(--flat);opacity:.12}
.spk-svg .spk-e{fill:none;stroke:var(--flat);stroke-width:4;stroke-linecap:round}
.spk-svg.up .spk-l,.spk-svg.up .spk-e{stroke:var(--up)} .spk-svg.up .spk-a{fill:var(--up)}
.spk-svg.down .spk-l,.spk-svg.down .spk-e{stroke:var(--down)} .spk-svg.down .spk-a{fill:var(--down)}
.duo-b{display:grid;grid-template-columns:1fr 1fr;gap:16px}
@media(max-width:860px){.duo-b{grid-template-columns:1fr}}
.picks{display:flex;gap:10px;padding:4px 14px 14px;overflow-x:auto}
.pick{flex:0 0 150px;background:var(--panel2);border:1px solid var(--line);border-radius:var(--r-3);
  padding:10px 12px;font-size:var(--fs-2);text-decoration:none;color:var(--dim);cursor:pointer;text-align:left}
.pick b{display:block;color:var(--ink);font-size:var(--fs-3);margin-bottom:3px;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.pick .v{font-family:var(--mono);color:var(--up);display:block}
.pick .lk{font-size:var(--fs-1);display:block;margin-top:4px;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.pick .lk:not(.up):not(.down):not(.flat){color:var(--faint)}   /* the P/L line keeps its sign colour */
.pick:hover{border-color:var(--line-strong)}
.pick.cta{background:var(--gold);border-color:var(--gold);color:var(--on-gold)}
.pick.cta b{color:var(--on-gold)}
.pick.cta span{font-size:var(--fs-1)}
.pager{display:flex;gap:10px;justify-content:center;padding:12px}
.pager a{color:var(--gold);text-decoration:none;padding:5px 10px;border:1px solid var(--line);border-radius:var(--r-2)}
.pager a[aria-disabled="true"]{color:var(--faint);pointer-events:none}
.pager span{align-self:center;color:var(--dim)}
.catalogue-pager{display:grid;grid-template-columns:minmax(0,1fr) auto minmax(0,1fr);align-items:center;gap:8px;padding:2px 14px;border-top:1px solid var(--line)}
.catalogue-page-links{display:flex;align-items:center;justify-content:center;gap:3px}
.catalogue-pager .catalogue-label,.catalogue-pager .catalogue-page-info{min-width:0;font-size:var(--fs-2);line-height:1.3;color:var(--faint)}
.catalogue-pager .catalogue-label{justify-self:start;color:var(--gold-quiet)}
.catalogue-pager .catalogue-disclosure{display:inline-flex;align-items:center;gap:6px;min-height:26px;
  padding:0 4px;margin-left:-4px;border:1px solid transparent;border-radius:3px;background:transparent;
  box-shadow:none;font-family:inherit;white-space:nowrap;cursor:pointer}
.catalogue-disclosure>span{color:var(--gold);transition:transform var(--dur-2)}
.catalogue-disclosure[aria-expanded="true"]>span{transform:rotate(90deg)}
.catalogue-pager .catalogue-disclosure:hover{border-color:var(--line);background:var(--hover-bg)}
.catalogue-pager .catalogue-disclosure:focus-visible{outline:2px solid var(--gold);outline-offset:1px}
.catalogue-pager .catalogue-page-info{justify-self:end;text-align:right}
.catalogue-label-group{display:flex;min-width:0;align-items:center;gap:10px}
.catalogue-pager .catalogue-page-info{display:flex;align-items:center;justify-content:flex-end;gap:7px}
.catalogue-label-group .list-toolbar{display:flex;min-width:0;align-items:center;gap:5px;margin:0}
.list-toolbar .ctl{max-width:160px;min-height:24px;padding:1px 5px;font-size:var(--fs-2)}
.list-toolbar .ctl select{min-width:0;max-width:124px;min-height:24px;padding:1px 4px;font-size:var(--fs-2)}
.catalogue-pager .list-expand{display:inline-flex;flex:none;align-items:center;justify-content:center;
  width:26px;min-height:26px;padding:0;border:1px solid transparent;border-radius:3px;
  background:transparent;box-shadow:none;color:var(--gold);font-size:15px;line-height:1;cursor:pointer}
.catalogue-pager .list-expand:hover{border-color:var(--line);background:var(--hover-bg)}
.catalogue-pager .list-expand:focus-visible{outline:2px solid var(--gold);outline-offset:1px}
.catalogue-table[aria-busy="true"] .catalogue-page-info{color:var(--gold-quiet)}
.catalogue-table[aria-busy="true"] .catalogue-page-info::before{content:"Loading… ";font-size:var(--fs-1)}
.catalogue-retry{padding:0 4px;font-size:inherit;line-height:inherit;background:transparent;color:var(--gold)}
.catalogue-page-links>:is(a,span,button){display:inline-flex;align-items:center;justify-content:center;min-width:32px;
  height:26px;padding:0 7px;white-space:nowrap;font-size:var(--fs-3);border:1px solid transparent;border-radius:3px}
.catalogue-pager a,.catalogue-page-links>button{color:var(--gold);background:transparent;text-decoration:none;box-shadow:none}
.catalogue-pager a:hover,.catalogue-page-links>button:hover{background:var(--hover-bg);border-color:var(--line-strong)}
.catalogue-pager .page-current{color:var(--bg);background:var(--gold);border-color:var(--gold);font-weight:700}
.catalogue-pager [aria-disabled="true"]{color:var(--faint);opacity:.65}
.catalogue-pager .page-ellipsis{min-width:16px;padding:0 2px;color:var(--faint)}
/* One compact shell for table-based collections. Overview dashboards and
   directory pages retain their own layouts. Expanded lists scroll normally. */
:root:is([data-ad-surface="items"],[data-ad-surface="ranked-list"],[data-ad-surface="trend-list"],[data-ad-surface="category-items"],[data-ad-surface="watchlist-ready"]){scrollbar-gutter:auto}
:root:is([data-ad-surface="items"],[data-ad-surface="ranked-list"],[data-ad-surface="trend-list"],[data-ad-surface="category-items"],[data-ad-surface="watchlist-ready"]) #main{padding-bottom:0}
:root:is([data-ad-surface="items"],[data-ad-surface="ranked-list"],[data-ad-surface="trend-list"],[data-ad-surface="category-items"],[data-ad-surface="watchlist-ready"]) .page-head{margin-bottom:10px}
:root:is([data-ad-surface="items"],[data-ad-surface="ranked-list"],[data-ad-surface="trend-list"],[data-ad-surface="category-items"],[data-ad-surface="watchlist-ready"]) .page-head h1{font-size:clamp(21px,2.2vw,28px);line-height:1.1}
:root:is([data-ad-surface="items"],[data-ad-surface="ranked-list"],[data-ad-surface="trend-list"],[data-ad-surface="category-items"],[data-ad-surface="watchlist-ready"]) .page-head p{margin-top:4px;font-size:var(--fs-3);line-height:1.4}
:root:is([data-ad-surface="items"],[data-ad-surface="ranked-list"],[data-ad-surface="trend-list"],[data-ad-surface="category-items"],[data-ad-surface="watchlist-ready"]) body>.ad-footer{display:none!important}
:root:is([data-ad-surface="items"],[data-ad-surface="ranked-list"],[data-ad-surface="trend-list"],[data-ad-surface="category-items"],[data-ad-surface="watchlist-ready"]) body>.mw-brand-footer{display:none!important}
@media(min-width:641px){
  /* Use spare desktop height for data rows, not a void below Explore. Only
     the results track grows; the title, pager and legal footer stay compact.
     Intrinsic table height remains the minimum on shorter windows. */
  :root:is([data-ad-surface="items"],[data-ad-surface="ranked-list"],[data-ad-surface="trend-list"],[data-ad-surface="category-items"],[data-ad-surface="watchlist-ready"]) #main{display:grid;grid-template-rows:auto minmax(min-content,1fr) auto auto}
  :root:is([data-ad-surface="items"],[data-ad-surface="ranked-list"],[data-ad-surface="trend-list"],[data-ad-surface="category-items"],[data-ad-surface="watchlist-ready"]):not([data-ad-rail-layout="1"]) #main{grid-template-columns:minmax(0,1500px);justify-content:center}
  :root:is([data-ad-surface="items"],[data-ad-surface="ranked-list"],[data-ad-surface="trend-list"],[data-ad-surface="category-items"],[data-ad-surface="watchlist-ready"]) #results{display:flex;min-width:0}
  .market.catalogue-table{display:flex;flex:1;align-items:stretch;margin-block:0}
  .catalogue-table>.board{display:flex;flex:1;min-width:0;flex-direction:column}
  .catalogue-table .board table{flex:1;height:100%}
  .catalogue-table .board thead{height:1px}
  .catalogue-table .catalogue-pager{flex-shrink:0}
  .catalogue-table .board tbody td{padding-block:8px}
  /* A short saved list should look intentional, not like two enormous rows.
     The longer-view control also keeps the established natural row pitch. */
  .catalogue-table:is(.list-short,.list-expanded){align-self:start}
  .catalogue-table:is(.list-short,.list-expanded) .board table{flex:none;height:auto}
}
@media(max-width:900px){
  .catalogue-pager{grid-template-columns:1fr 1fr;gap:1px 8px}
  .catalogue-page-links{grid-column:1/-1;grid-row:2}
  .catalogue-pager .catalogue-page-info{grid-column:2;grid-row:1}
}
@media(max-width:640px){
  .catalogue-pager{gap:2px;padding:3px 4px}
  .catalogue-pager .catalogue-disclosure{min-height:32px;margin-left:0}
  .catalogue-pager .list-expand{width:32px;min-height:32px}
  .catalogue-label-group{gap:4px}
  .list-toolbar .ctl{max-width:104px;min-height:30px}
  .list-toolbar .ctl select{max-width:76px;min-height:30px}
  .catalogue-page-links{gap:2px}
  .catalogue-page-links>:is(a,span,button){min-width:27px;height:32px;padding:0 5px;font-size:var(--fs-2)}
}
th.sortable{cursor:pointer}
th.sortable:hover{color:var(--ink)}
.cat-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(190px,1fr));gap:12px}
/* The directory keeps one centered content column when audience/policy turns
   the rails off. The wide-screen .market margin reset is for other market
   views, not a reason to pin category cards to the left of their heading. */
:root[data-ad-surface="categories"] #results>.market{width:100%;max-width:1500px;margin-inline:auto;min-width:0}
.cat-tile{background:var(--panel);border:1px solid var(--line);border-radius:var(--r-4);
  padding:12px 14px;text-decoration:none;color:var(--dim);box-shadow:var(--edge),var(--sh-1);
  display:flex;align-items:center;gap:12px}
.cat-tile .ct-i{width:40px;height:40px;flex:none;object-fit:contain;image-rendering:auto}
[data-theme="osrs"] .cat-tile .ct-i{image-rendering:pixelated}   /* keep the 2007 sprites crisp */
.cat-tile .ct-t{min-width:0}
.cat-tile b{display:block;color:var(--ink);font-size:var(--fs-4);margin-bottom:3px;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.cat-tile span span,.cat-tile .ct-t>span{font-size:var(--fs-2);color:var(--faint)}
.cat-tile:hover{border-color:var(--line-strong);background:var(--hover-bg)}
@media(min-width:901px){
  /* Forty-three RS3 categories plus the real footer creative and its label
     fit a normal desktop window without reducing type or icon sizes. */
  :root[data-ad-surface="categories"] .cat-grid{gap:10px}
  :root[data-ad-surface="categories"] .cat-tile{padding-block:10px}
}
/* Dedicated sheen token: the shimmer used --hover-bg, which is BELOW --panel2
   in OSRS, so the highlight ran darker than the track and read inverted. */
.skel{background:linear-gradient(90deg,var(--panel2) 25%,var(--skel-sheen) 50%,var(--panel2) 75%);
  background-size:200% 100%;animation:skel 1.2s linear infinite;border-radius:var(--r-2);color:transparent}
.skel-row{height:34px;margin:6px 14px}
@keyframes skel{to{background-position:-200% 0}}
/* Substitute a gentler cue rather than deleting feedback entirely. */
@media(prefers-reduced-motion:reduce){
  .skel{animation:none;background:var(--skel-sheen)}
}
/* Signals masthead: the algo tabs read as the branded premium product */
.sig-head{display:flex;align-items:center;gap:12px;background:var(--panel);box-shadow:var(--edge),var(--sh-1);
  border:1px solid var(--line);border-left:3px solid var(--gold);
  border-radius:0 var(--r-3) var(--r-3) 0;padding:10px 16px;margin-bottom:16px}
.sig-head img{height:40px;width:auto;display:block;filter:drop-shadow(0 2px 6px rgba(0,0,0,.55))}
.sig-head b{display:block;font-size:var(--fs-5);color:var(--emph)}
.sig-head span{font-size:var(--fs-3);color:var(--faint)}
.sig-score{margin-left:auto;font-size:var(--fs-3);color:var(--dim);text-align:right;line-height:1.5}
.sig-score b{color:var(--ink)}

/* ===== ad slots (see ads.js) =====
   Slots are inert until the server policy and audience resolve. Live,
   near-viewport pending, and admin-template states reserve the creative's true
   size; disabled/ineligible states collapse completely, while a failed or
   blocked live request keeps the geometry with first-party MarketWyrm art. */
.ad-slot{position:relative;width:100%;margin:14px auto}
.ad-slot.ad-hidden,tr.ad-row.ad-hidden,.ad-slot.ad-empty,tr.ad-row.ad-empty{display:none}
.ad-slot.ad-live{overflow:hidden}
.ad-slot .ad-native{display:block;width:100%}
.mw-brand-slot{position:relative;display:flex;width:100%;margin:14px auto;align-items:center;
  justify-content:center;overflow:hidden;background:#020608;border:1px solid rgba(255,190,55,.28);
  border-radius:var(--r-2);box-shadow:inset 0 1px 0 rgba(255,230,166,.055),0 0 18px -13px rgba(255,175,34,.7)}
.mw-brand-art{display:block;max-width:100%;object-fit:cover;object-position:center;user-select:none}
/* The honest label above a live unit keeps the creative distinct from content. */
.ad-tag{display:block;font-size:var(--fs-1);line-height:1.4;letter-spacing:.08em;
  text-transform:uppercase;color:var(--faint);margin-bottom:3px;text-align:center}
.ad-placeholder{display:flex;align-items:center;justify-content:center;
  background:var(--inset-bg);border:1px dashed var(--line-strong);
  border-radius:var(--r-3);box-shadow:var(--edge)}
.ad-placeholder::after{content:"Ad space";color:var(--faint);opacity:.5;
  font-size:var(--fs-3);letter-spacing:.06em}
.ad-footer,.mw-brand-footer{max-width:1544px;margin:12px auto;text-align:center}
.ad-footer:is(.ad-live,.ad-pending,.ad-placeholder,.ad-template),.mw-brand-footer{min-height:68px}
:root[data-ad-surface="overview"] body>.ad-footer,
:root[data-ad-surface="items"] body>.ad-footer,
:root[data-ad-surface="categories"] body>.ad-footer,
:root[data-ad-surface="overview"] body>.mw-brand-footer,
:root[data-ad-surface="items"] body>.mw-brand-footer,
:root[data-ad-surface="categories"] body>.mw-brand-footer{max-width:728px}
/* The 468×60 overview/directory/compact-list unit sits in the title row's
   already-empty right side. The two-column title geometry is stable even when
   premium/admin policy hides the slot, so an impression cannot move content. */
.page-head>.page-head-ad,.page-head>.mw-brand-head{display:none}
@media(min-width:1280px){
  .page-head.has-compact468{display:grid;grid-template-columns:minmax(0,1fr) 468px;
    align-items:center;gap:24px}
  /* The live creative adds an Advertisement label above its 60px iframe.
     Category cards must not move when a template or ad-free account removes
     that label/creative; reserve the same existing title-row footprint. */
  :root[data-ad-surface="categories"] .page-head.has-compact468{min-height:calc(63px + var(--fs-1)*1.4)}
  .page-head>:is(.page-head-ad:is(.ad-live,.ad-pending,.ad-placeholder,.ad-template),.mw-brand-head){
    display:block;width:468px;min-height:60px;margin:0;justify-self:end;text-align:center}
}
/* Desktop content normally carries 24px of its own bottom breathing room.
   When the shared footer slot is actually visible, let the slot's equal 12px
   margins own that separation so the space above and below the creative is
   visually identical. Hidden/ad-free slots never match and keep no ghost gap. */
@media(min-width:901px){
  body:has(>:is(.ad-footer:is(.ad-live,.ad-pending,.ad-placeholder,.ad-template),.mw-brand-footer)) #main{padding-bottom:0}
}
.about-wrap>:is(.ad-footer,.mw-brand-footer),.legal-wrap>:is(.ad-footer,.mw-brand-footer){padding:0;margin-top:36px}
.ad-infeed:is(.ad-live,.ad-pending,.ad-placeholder,.ad-template){min-height:138px}
/* Rails: a fixed 160x600 skyscraper, so the slot is sized, not fluid. The
   gutters it sits in only exist above the grid breakpoint, so it is hidden
   below. Hiding it HERE (not with a display:block up in the grid block) keeps
   .ad-hidden/.ad-empty winning on specificity, so a collapsed rail stays
   collapsed on a wide screen. */
.ad-rail,.mw-brand-rail{width:160px;margin:0}
@media(max-width:1559px){.ad-rail,.mw-brand-rail{display:none}}
@media(min-width:1560px){
  /* Center the fixed 618px rail zone in the VISIBLE viewport below the live-
     measured header. Page height is deliberately absent from this equation:
     tables below the fold must never drag a side ad down the document. The
     first max() arm keeps the rail safely below the header on short screens. */
  .ad-rail,.mw-brand-rail{--ad-rail-zone-h:618px;
    --ad-rail-sticky-top:max(calc(var(--chrome-h,70px) + 12px),calc((100dvh + var(--chrome-h,70px) - var(--ad-rail-zone-h))/2));
    grid-row:1/3;align-self:start;position:sticky;top:var(--ad-rail-sticky-top)}
  .ad-homeleft,.mw-brand-homeleft{grid-column:1}
  .ad-railright,.mw-brand-railright{grid-column:3}
  /* GE overview gets the same viewport-centred treatment as every other rail:
     the distinct 160x300 left creative is centred inside the same fixed zone
     as the unique 160x600 right creative. */
  :root:is([data-ad-surface="overview"],[data-ad-surface="items"])[data-ad-rail-layout="1"] #main>:is(.ad-homeleft:is(.ad-live,.ad-pending,.ad-placeholder,.ad-template),.ad-railright:is(.ad-live,.ad-pending,.ad-placeholder,.ad-template),.mw-brand-homeleft,.mw-brand-railright){
    display:flex!important;margin:0;min-height:var(--ad-rail-zone-h);
    flex-direction:column;justify-content:center}
  :root:is([data-ad-surface="overview"],[data-ad-surface="items"])[data-ad-rail-layout="1"] #main>:is(.ad-homeleft:is(.ad-live,.ad-pending,.ad-placeholder,.ad-template),.mw-brand-homeleft){justify-self:end}
  :root:is([data-ad-surface="overview"],[data-ad-surface="items"])[data-ad-rail-layout="1"] #main>:is(.ad-railright:is(.ad-live,.ad-pending,.ad-placeholder,.ad-template),.mw-brand-railright){justify-self:start}
  /* A short directory is shorter than the 618px rail zone. A sticky grid item
     spanning page-head + results made that zone enlarge both auto rows, which
     manufactured a blank band between the category subtitle and its cards.
     Category-directory rails are fixed into the same physical gutters and
     viewport-centred, so their height cannot participate in content sizing. */
  :root:is([data-ad-surface="categories"],[data-ad-surface="items"],[data-ad-surface="ranked-list"],[data-ad-surface="trend-list"],[data-ad-surface="category-items"],[data-ad-surface="watchlist-ready"])[data-ad-rail-layout="1"] #main>.ad-rail:is(.ad-live,.ad-pending,.ad-placeholder,.ad-template),
  :root:is([data-ad-surface="categories"],[data-ad-surface="items"],[data-ad-surface="ranked-list"],[data-ad-surface="trend-list"],[data-ad-surface="category-items"],[data-ad-surface="watchlist-ready"])[data-ad-rail-layout="1"] #main>.mw-brand-rail{
    position:fixed;top:var(--ad-rail-sticky-top);z-index:2;display:flex!important;
    min-height:var(--ad-rail-zone-h);margin:0;flex-direction:column;justify-content:center}
  :root:is([data-ad-surface="categories"],[data-ad-surface="items"],[data-ad-surface="ranked-list"],[data-ad-surface="trend-list"],[data-ad-surface="category-items"],[data-ad-surface="watchlist-ready"])[data-ad-rail-layout="1"] #main>:is(.ad-homeleft:is(.ad-live,.ad-pending,.ad-placeholder,.ad-template),.mw-brand-homeleft){
    right:auto;left:max(22px,calc((100% - 1860px)/2))}
  :root:is([data-ad-surface="categories"],[data-ad-surface="items"],[data-ad-surface="ranked-list"],[data-ad-surface="trend-list"],[data-ad-surface="category-items"],[data-ad-surface="watchlist-ready"])[data-ad-rail-layout="1"] #main>:is(.ad-railright:is(.ad-live,.ad-pending,.ad-placeholder,.ad-template),.mw-brand-railright){
    right:max(22px,calc((100% - 1860px)/2));left:auto}
}
.ad-rail:is(.ad-live,.ad-pending,.ad-placeholder,.ad-template),.mw-brand-rail{min-height:618px}
/* Item detail has two mutually exclusive mounts: a short desktop skyscraper docked
   below the independently scrolling watchlist, and a mobile rectangle after
   the complete stacked detail. Neither consumes chart space. */
.ad-detail,.mw-brand-detail{margin:12px auto 16px;flex-shrink:0}
.t-ad-desktop:is(.ad-live,.ad-pending,.ad-placeholder,.ad-template),.mw-brand-desktop{min-height:338px}
.t-ad-mobile:is(.ad-live,.ad-pending,.ad-placeholder,.ad-template),.mw-brand-mobile{min-height:268px}
.t-ad-mobile,.mw-brand-mobile{width:100%;flex:none}
/* Both responsive mounts stay in the detail DOM so ads.js can move the unit
   after a live resize. CSS mirrors the runtime arbitration as a no-flash
   guard; only one mount is ever eligible or executable at a time. */
@media(min-width:901px){.t-ad-mobile,.mw-brand-mobile{display:none}}
@media(max-width:900px){.t-ad-desktop,.mw-brand-desktop{display:none}}
/* in-feed row: strip table chrome so the unit sits flush in the list and is
   inert to row hover (it is not a clickable item row) */
tr.ad-row td{padding:8px 14px;background:transparent;cursor:default}
tr.ad-row:hover td{background:transparent}

/* screener table — #results is a horizontal scroll container so a wide table
   scrolls within itself on a phone instead of panning the whole page. */
#results{overflow-x:auto}
table{width:100%;border-collapse:collapse;font-size:var(--fs-4)}
/* `cursor:pointer` on every th LIED on five of six tables — only the screener
   has sortable headers. app.js adds .sortable where sorting is real. */
thead th{text-align:right;padding:10px 14px;font-size:var(--fs-2);text-transform:uppercase;
  letter-spacing:.06em;color:var(--faint);border-bottom:1px solid var(--line);
  cursor:default;user-select:none;white-space:nowrap;font-weight:500}
thead th:first-child,thead th.l{text-align:left}
thead th.sorted{color:var(--ink)}
/* Row pitch 67px -> ~48px. At the old density a 1366x768 laptop showed eight
   rows and no second board; a screener should show data, not whitespace. */
tbody td{text-align:right;padding:9px 14px;border-bottom:1px solid var(--row-line);
  font-variant-numeric:tabular-nums;white-space:nowrap}
tbody td:first-child,tbody td.l{text-align:left}
tbody tr{cursor:pointer} tbody tr:hover{background:var(--row-hover)}
/* watchlist: inline editable targets, gap-to-target, alert status, live meta */
.wl-tgt{text-align:right}
.wl-tin{width:84px;text-align:right;font:inherit;font-variant-numeric:tabular-nums;
  color:var(--emph);background:var(--input-bg);border:1px solid var(--line);
  border-radius:var(--r-2);padding:5px 8px}
.wl-tin:hover{border-color:var(--line-strong)}
/* Gold border on focus; the global :focus-visible ring stays (the bare
   outline:none here was the one input in the app with no keyboard ring). */
.wl-tin:focus{border-color:var(--gold)}
.wl-tin::placeholder{color:var(--faint)}
.wl-gap{display:block;font-size:var(--fs-1);color:var(--faint);margin-top:3px}
/* "hit" is the product's payoff — it reads as a gold badge, not 11.5px text in
   a routine-gain green. Green/red stay reserved for the SIGN of a number
   (dcls); a fired alert is an event, and a buy hit is often a price DROP, so
   green-for-hit collided with that channel. */
.wl-al{font-size:var(--fs-3);white-space:nowrap;font-weight:500}
.wl-al.hit{color:var(--emph);background:var(--gold-bg);border-radius:var(--r-pill);padding:2px 9px}
.wl-al.armed{color:var(--gold-quiet)} .wl-al.none{color:var(--faint);font-weight:400}
.wl-load{color:var(--faint)}
.wl-tval{display:inline-block} .wl-tval.muted{color:var(--faint)}
.wl-editing{background:var(--hover-bg)}
.wl-actions{white-space:nowrap}
.wl-actions .ghost{padding:4px 9px}
.wl-actions .ghost+.ghost{margin-left:6px}
/* Save-targets tick is the editing row's PRIMARY action → action gold, not the
   up/down channel. */
.wl-act.on{color:var(--gold);border-color:var(--gold)}
/* The two signed-in-only tables were the app's only unpanelled tables — bare
   rows on the page with no border, radius or elevation. Give them the same
   .board chrome every guest table already has. */
.wl-table,.perf-t{background:var(--panel);border:1px solid var(--line);
  border-radius:var(--r-4);overflow:hidden;box-shadow:var(--edge),var(--sh-1)}
/* The icon well — not the text — sets the row height, so density work has to
   start here: 40px well + 9px cell padding was a 67px pitch and eight rows on a
   1366x768 laptop. 32px brings the pitch to ~48 without shrinking the artwork
   much (the sprites are 32px native anyway, so they actually sharpen). */
.mi{display:flex;align-items:center;gap:11px}
.mi-ico{width:32px;height:32px;border-radius:var(--r-3);background:var(--ico-bg);display:flex;
  align-items:center;justify-content:center;font-size:var(--fs-4);color:var(--gold);
  flex-shrink:0;overflow:hidden;box-shadow:inset 0 0 0 1px var(--row-line)}
.mi-ico img{width:28px;height:28px;object-fit:contain;image-rendering:auto}
.mi b{font-weight:500;font-size:var(--fs-5)} .mi em{font-style:normal;color:var(--faint);font-size:var(--fs-2)}
.dir{font-weight:500;font-size:var(--fs-2)}
.grade{display:inline-block;min-width:20px;text-align:center;font-weight:500;
  padding:1px 7px;border-radius:var(--r-2);font-size:var(--fs-3)}
.gA{background:rgba(38,162,105,.15);color:#4bd090}
.gB{background:rgba(122,199,79,.15);color:#9fd868}
.gC{background:rgba(224,165,22,.15);color:#e6bd4f}
.gD{background:rgba(232,135,58,.15);color:#e8873a}
.gF{background:rgba(229,72,77,.15);color:#f0787c}
.sig{font-size:var(--fs-3);color:var(--dim)} .sig.warn{color:var(--warn)}
/* guest signal tease: visible lock, clickable straight into sign-in */
/* Gated cells repeat down every row of two columns. Rendered as full-colour OS
   emoji they were the brightest, most saturated objects on Long Plays and
   Performance — ~50 padlocks per page, outranking the actual P/L numbers.
   Desaturating the glyph hands the row's contrast back to the data; the lock
   still reads, and hover still promotes it to gold as the affordance. */
.sig-lock{color:var(--faint);font-size:var(--fs-2);cursor:pointer;white-space:nowrap}
/* Greyscale only — the old opacity:.72 on top dropped these to ~2:1. */
.sig-band .lk,.sig-lock .lk,.menu .lk,.ch-lk,.t-leg .lk{opacity:.85}
.lk.ico{vertical-align:-.1em}
.tabs .lk{margin-left:.3em}
tbody tr:hover .sig-lock{color:var(--gold)} tbody tr:hover .sig-lock .lk{filter:none}
.sig-band{white-space:nowrap} .sig-band .lk{font-size:var(--fs-1)}
.mini{vertical-align:middle}
.empty{text-align:center;color:var(--dim);padding:56px 20px;line-height:1.7}

/* signed-out preview — a slim sign-in strip sitting just above the sample table */
.preview-cta{display:flex;align-items:center;justify-content:space-between;gap:14px;flex-wrap:wrap;box-shadow:var(--edge),var(--sh-1);
  background:var(--panel);border:1px solid var(--line);border-left:3px solid var(--gold);
  border-radius:0 var(--r-3) var(--r-3) 0;padding:11px 16px;margin-bottom:16px}
.pv-txt{color:var(--dim);font-size:var(--fs-4);line-height:1.5;flex:1 1 320px;min-width:220px}
.pv-txt b{color:var(--ink)}
.preview-btns{display:flex;gap:10px;flex-shrink:0}
.preview-btns .mprimary{width:auto;padding:8px 18px;border-radius:var(--r-3)}

/* gated watchlist + empty states — the cartoon mascot owns the friendly
   moments; photo-real art never appears on data screens */
.gate{text-align:center;padding:60px 24px}
.gate-img{width:158px;max-width:58%;height:auto;display:block;margin:0 auto 18px;
  filter:drop-shadow(0 8px 22px rgba(0,0,0,.55)) drop-shadow(0 0 44px var(--glow))}
.empty-img{width:110px;height:auto;display:block;margin:0 auto 14px;opacity:.9;
  filter:drop-shadow(0 6px 16px rgba(0,0,0,.5))}
.gate h3{font-size:var(--fs-6);font-weight:500;margin:0 0 8px}
.gate p{color:var(--dim);font-size:var(--fs-4);margin:0 auto 22px;max-width:420px;line-height:1.6}
.gate-btns{display:flex;gap:10px;justify-content:center}
.gate-coming{position:relative;max-width:620px;margin:22px auto;padding-top:46px;
  border:1px solid color-mix(in srgb,var(--gold) 24%,var(--line));border-radius:var(--r-3);
  background:radial-gradient(circle at 50% 18%,color-mix(in srgb,var(--gold) 8%,transparent),transparent 48%)}
.gate-kicker{display:inline-flex;margin:0 auto 18px;padding:4px 9px;border:1px solid var(--line-strong);
  border-radius:var(--r-pill);color:var(--gold);background:var(--inset-bg);
  font:700 var(--fs-1)/1.3 var(--mono);letter-spacing:.1em}

/* detail overlay — starts BELOW the sticky chrome instead of covering it, so
   the logo / game switch / search / account and the tabs work from any item. */
.overlay{position:fixed;left:0;right:0;bottom:0;top:var(--chrome-h,70px);
  z-index:40;background:var(--page);
  display:flex;flex-direction:column;overflow:hidden}
.overlay[hidden]{display:none}
/* Seal the background while an item is open: lock the document scroll so the
   page behind the overlay can't move (it was dragging the sticky chrome
   off-screen). The overlay's own panes still scroll — .t-mid / .t-side on
   desktop, the whole .term-scroll on mobile. */
html:has(#detail:not([hidden])){overflow:hidden}
/* ☰ opens/closes the terminal's item list (#detail.nolist = closed). Absolute
   against the overlay; whatever sits leftmost (the list's filter row, or the
   ticker header once the list is closed) pads left to clear it. */
.t-burger{position:absolute;top:9px;left:10px;z-index:6;width:34px;height:34px;
  display:flex;align-items:center;justify-content:center;padding:0;
  background:var(--panel2);border:1px solid var(--line);border-radius:var(--r-2);
  color:var(--dim);font-size:15px;box-shadow:none}
.t-burger:hover{color:var(--ink);border-color:var(--line-strong);background:var(--seg-on)}
/* Desktop-only: the ≤900px stacked layout has no list (and its .term
   min-width:0 must not lose to these higher-specificity rules). */
@media(min-width:901px){
  #detail.nolist .t-list{display:none}
  #detail.nolist .term{grid-template-columns:minmax(320px,1fr) 270px;min-width:590px}
  #detail.nolist .t-tick{padding-left:54px}
}
.term-scroll{flex:1;min-height:0;overflow-x:auto;overflow-y:hidden}
.term{display:grid;grid-template-columns:230px minmax(320px,1fr) 270px;
  height:100%;min-width:820px;background:var(--page)}
.t-list{border-right:1px solid var(--line);min-height:0;display:flex;flex-direction:column;overflow:hidden}
.t-search{padding:9px 11px 9px 50px;border-bottom:1px solid var(--line);flex-shrink:0}
.t-search input{width:100%;padding:7px 10px;font-size:var(--fs-3);background:var(--input-bg)}
.t-items{flex:1;overflow-y:auto;min-height:0}
.t-lhead{padding:11px 14px;border-bottom:1px solid var(--line);font-size:var(--fs-2);
  color:var(--faint);text-transform:uppercase;letter-spacing:.05em;flex-shrink:0}
.t-item{display:flex;align-items:center;justify-content:space-between;padding:9px 14px;
  border-bottom:1px solid var(--row-line2);cursor:pointer}
.t-item:hover{background:var(--panel)}
.t-item.sel{background:var(--panel2);border-left:2px solid var(--gold)}
.t-item .nm{font-size:var(--fs-3)} .t-item .nm em{display:block;font-style:normal;color:var(--faint);font-size:var(--fs-1)}
.t-item .pc{text-align:right} .t-item .pc b{font-size:var(--fs-3);font-weight:500}
.t-item .pc span{display:block;font-size:var(--fs-1)}
.t-mid{display:flex;flex-direction:column;min-width:0;overflow:hidden}
.t-tick{display:flex;align-items:center;justify-content:space-between;padding:14px 18px;
  border-bottom:1px solid var(--line);gap:12px;flex-wrap:wrap;flex-shrink:0}
.t-tick b{font-weight:500}
/* The item name is the page's de-facto H1 — it sat at body size under a
   bigger price and level with the sidebar labels. Name → heading step,
   price → display step, the game tag → a quiet pill. */
#t-name{font-size:var(--fs-6);font-weight:600;letter-spacing:-.01em;line-height:1.2}
.t-tick .sub{color:var(--faint);font-size:var(--fs-1);margin-left:8px;letter-spacing:.06em;
  border:1px solid var(--line);border-radius:var(--r-pill);padding:1px 7px;vertical-align:2px}
.t-tick-l{display:flex;align-items:center;gap:10px;min-width:0;flex-wrap:wrap}
.t-tick-l .mi-ico{flex:none}
/* meta strip under the ticker: what the item is, where else it lives */
.t-meta{display:flex;flex-wrap:wrap;align-items:center;gap:6px;padding:8px 18px 6px;flex-shrink:0;
  border-bottom:1px solid var(--line)}
.t-meta-sp{flex:1 1 8px}
.t-chip{display:inline-flex;align-items:center;gap:5px;font-size:var(--fs-2);color:var(--dim);background:var(--panel2);
  border:1px solid var(--line);border-radius:var(--r-pill);padding:2px 9px;text-decoration:none;white-space:nowrap;
  font-family:var(--sans);line-height:1.5;box-shadow:none}
.t-chip b{color:var(--ink);font-weight:500}
.t-chip .mbadge{margin:0}
a.t-chip.cat:hover{color:var(--ink);border-color:var(--line-strong);background:var(--hover-bg)}
.t-chip.lnk{color:var(--gold);background:transparent;cursor:pointer}
.t-chip.lnk:hover{color:var(--emph);border-color:var(--line-strong);background:var(--gold-bg)}
button.t-chip{min-height:0;padding:2px 9px}
@media(pointer:coarse){.t-chip,button.t-chip{min-height:32px}}
/* similar items strip under the chart */
.t-sim{padding:4px 18px 14px;flex-shrink:0}
.t-sim .t-shead{margin-bottom:6px}
.t-sim-sub{color:var(--faint);font-weight:400;text-transform:none;letter-spacing:0;font-family:var(--sans);font-size:var(--fs-3)}
.picks.sim{padding:0;flex-wrap:wrap;overflow:visible}
.picks.sim .pick{flex:1 1 150px;max-width:220px;display:flex;align-items:center;gap:9px;padding:8px 10px}
.picks.sim .pick .mi-ico{width:28px;height:28px;flex:none}
.picks.sim .pick .mi-ico img{width:24px;height:24px}
.picks.sim .pk-t{min-width:0}
.picks.sim .pick b{font-size:var(--fs-3);margin-bottom:1px}
.picks.sim .pick .v{color:var(--dim);font-size:var(--fs-2)}
/* ← Back: the overlay's only visible exit (the tabs/logo above it are exits
   too, but nothing SAID "close"). Quiet ghost chip; Escape is the keyboard
   twin (app.js). The focused item name takes the gold ring like every other
   focus target, but only for keyboard focus — it is focused programmatically
   on open, and a ring on a heading after a mouse click reads as a glitch. */
.t-back{background:transparent;border:1px solid var(--line);border-radius:var(--r-pill);color:var(--dim);
  font-size:var(--fs-3);padding:4px 11px 4px 9px;box-shadow:none;white-space:nowrap;flex:none}
.t-back:hover{color:var(--ink);border-color:var(--line-strong);background:var(--hover-bg)}
#t-name:focus:not(:focus-visible){outline:none}
/* The overlay shell takes focus on open (app.js) purely to move the caret out
   of the header search; it is a region, not a control — no ring on it. */
.overlay:focus{outline:none}
#t-name:focus-visible{outline:2px solid var(--gold);outline-offset:3px;border-radius:2px}
.t-px{text-align:right} .t-px b{font-size:var(--fs-7)} .t-px span{margin-left:9px;font-size:var(--fs-3)}
.t-livepx{font-size:var(--fs-2);color:var(--faint);margin-top:2px;font-family:var(--mono);font-variant-numeric:tabular-nums}
.t-livepx b{font-size:var(--fs-2);font-weight:500;color:var(--dim)}
/* Canvas is taken OUT OF FLOW so its intrinsic width attribute can't collapse
   the middle grid column. .t-mid then stretches to the full 1fr track and the
   chart fills every pixel of it, scaling with the window. */
.t-chart{flex:1;min-height:0;position:relative}
.ch-empty{position:absolute;z-index:4;inset:20% 12%;display:grid;place-items:center;
  color:var(--faint);font:12px/1.55 var(--mono);text-align:center;pointer-events:none}
.t-chart.rsi-on{min-height:360px}
.t-chart canvas{position:absolute;top:10px;left:20px;
  width:calc(100% - 40px);height:calc(100% - 14px);display:block}
.t-leg{display:flex;flex-wrap:wrap;gap:4px 15px;padding:0 18px 14px;font-size:var(--fs-2);color:var(--dim)}
.t-leg i{display:inline-block;width:14px;height:2px;vertical-align:middle;margin-right:5px}
.t-cap{color:var(--faint);font-size:var(--fs-2);padding:0 18px 16px}
/* Interactive chart surface. Vertical touch gestures still scroll the detail;
   a deliberate horizontal drag pans the chart after zooming. Mouse-wheel zoom
   is armed by clicking/focusing the canvas first, so page scrolling is never
   hijacked just because the pointer crosses the graph. */
#dchart-ov{touch-action:pan-y;cursor:crosshair}
#dchart-ov.nav-active{cursor:grab}
#dchart-ov.dragging{cursor:grabbing}
#dchart-ov:focus-visible{outline:1px solid var(--line-strong);outline-offset:-1px}
.t-tip{position:absolute;z-index:5;pointer-events:none;background:var(--tip-bg);
  border:1px solid var(--line);border-radius:var(--r-2);padding:5px 9px;font-size:var(--fs-2);
  line-height:1.5;font-family:var(--mono);font-variant-numeric:tabular-nums;
  white-space:nowrap;box-shadow:var(--edge),var(--sh-2)}
.t-tip .tt-d{color:var(--dim)}
.t-side{border-left:1px solid var(--line);padding:14px 16px;overflow-y:auto;min-height:0}
.t-shead{font-size:var(--fs-4);font-weight:600;text-transform:uppercase;letter-spacing:.06em;color:var(--ink);margin-bottom:9px}
.t-row{display:flex;justify-content:space-between;padding:6px 0;font-size:var(--fs-4);color:var(--dim)}
.t-row b{color:var(--ink);font-weight:500}
/* The sign colour must win in the panel too: `.t-row b` (0-1-1) used to beat
   `.up/.down` (0-1-0), so Direction / Slope / 30d·90d read neutral here while
   the header slope span was green or red — same number, two vocabularies. */
.t-row b.up,.t-row .up{color:var(--up)} .t-row b.down,.t-row .down{color:var(--down)} .t-row b.flat,.t-row .flat{color:var(--flat)}
.t-row .dir{font-size:inherit}
.t-note{font-size:var(--fs-3);color:var(--dim);padding:3px 0;line-height:1.5} .t-note b{color:var(--ink)}
.t-flip{display:flex;justify-content:space-between;margin-top:13px;padding:9px 11px;
  background:var(--inset-bg);border-radius:var(--r-3);font-size:var(--fs-3);color:var(--faint)}
.t-flip b{color:var(--ink);font-weight:500;font-size:var(--fs-3)}
/* ===== chart v2 toolbar (timeframes + indicator toggles) ===== */
.ch-bar{display:flex;align-items:center;justify-content:space-between;gap:10px;
  padding:7px 18px 2px;flex-wrap:wrap;flex-shrink:0}
.ch-range,.ch-tools,.ch-mode-wrap,.ch-candle-tray{display:flex;align-items:center}
.ch-range{gap:6px}
.ch-tools{gap:4px;flex-wrap:wrap;justify-content:flex-end}
.ch-mode-wrap{gap:4px;margin-right:2px}
.ch-candle-tray{border:1px solid var(--line);border-radius:var(--r-2);overflow:hidden}
.ch-group-label{color:var(--faint);font-size:var(--fs-1);font-weight:600;letter-spacing:.08em;text-transform:uppercase}
/* Timeframes are ONE radio group, so they read as one segmented tray; the
   overlay toggles stay separate chips. Both use the app-wide "selected TEXT =
   --emph, selected EDGE = --line-strong" rule. */
.ch-tfs{display:flex;flex-wrap:wrap;border:1px solid var(--line);border-radius:var(--r-2);overflow:hidden}
.ch-tf,.ch-chip,.ch-mode,.ch-ci{background:transparent;border:1px solid var(--line);border-radius:var(--r-2);
  color:var(--dim);padding:3px 10px;font-size:var(--fs-2);box-shadow:none}
.ch-tf{border:0;border-radius:0;border-right:1px solid var(--line)}
.ch-mode.ch-line{border:1px solid var(--line);border-radius:var(--r-2)}
.ch-candle-tray .ch-mode,.ch-ci{border:0;border-radius:0;border-right:1px solid var(--line)}
.ch-candle-tray .ch-mode:last-child{border-right:0}
.ch-ci:last-child{border-right:0}
.ch-tf:last-child{border-right:0}
.ch-tf:focus-visible,.ch-mode:focus-visible,.ch-ci:focus-visible{outline-offset:-2px}   /* segmented trays clip overflow; keep the ring inside */
.ch-tf.on{color:var(--emph);background:var(--seg-on)}
.ch-mode.on,.ch-ci.on{color:var(--emph);background:var(--seg-on)}
.ch-chip.on{color:var(--emph);border-color:var(--line-strong);background:var(--seg-on)}
.ch-chip.on::before{content:"";display:inline-block;width:10px;height:2px;margin-right:6px;vertical-align:middle;
  border-radius:1px;background:var(--sw,var(--gold))}   /* swatch = the overlay's line colour (renderChartBar sets --sw) */
.ch-levels{display:inline-flex;align-items:center;gap:5px}
.ch-levels.on::before{content:none}
.ch-levels .ico{width:13px;height:13px;margin:0}
.ch-lk{font-style:normal;font-size:var(--fs-1);margin-left:4px;opacity:.8}
.ch-busy{color:var(--faint);filter:saturate(.4);cursor:progress} .ch-busy button{pointer-events:none}
/* posted-call progress bars */
.prog{display:inline-block;width:64px;height:7px;border-radius:var(--r-1);background:var(--inset-bg);
  border:1px solid var(--line);vertical-align:middle;overflow:hidden}
.prog i{display:block;height:100%;background:var(--up);border-radius:var(--r-1)}
.prog-n{font-size:var(--fs-2);margin-left:7px}
/* the wyrm's receipts: recently-closed calls strip */
.closed-strip{display:flex;align-items:center;gap:8px;overflow-x:auto;
  padding:9px 14px;margin-bottom:14px;background:var(--panel);
  border:1px solid var(--line);border-radius:var(--r-4);scrollbar-width:none}
.closed-strip .cs-t{color:var(--faint);font-size:var(--fs-2);text-transform:uppercase;
  letter-spacing:.08em;flex-shrink:0}
.cs{flex-shrink:0;font-size:var(--fs-3);font-weight:500;color:var(--dim);background:var(--panel2);
  border:1px solid var(--line);border-radius:var(--r-pill);padding:2px 9px;white-space:nowrap;letter-spacing:.04em}
/* the outcome colours the pill itself — the markup is <span class="cs cs-hit">HIT</span>, no nested <b> */
.cs-hit{color:var(--up);background:var(--up-bg);border-color:currentColor}
.cs-stop{color:var(--down);background:var(--down-bg);border-color:currentColor}
.cs-exp{color:var(--warn);background:var(--warn-bg);border-color:currentColor}
/* Outcome pills are coloured by the MONEY, not the mechanism: a trailing stop
   that banked a profit is a win and must not read in loss-red. cs-win/cs-loss
   supersede cs-hit/cs-stop, which stay for older markup. */
.cs-win{color:var(--up);background:var(--up-bg);border-color:currentColor}
.cs-loss{color:var(--down);background:var(--down-bg);border-color:currentColor}
/* Closed-trades results strip */
.wy-cl-sum{display:grid;grid-template-columns:repeat(auto-fit,minmax(120px,1fr));gap:10px;
  margin:10px 0 14px}
.wy-cl-sum>div{background:var(--inset-bg);border:1px solid var(--line);border-radius:var(--r-2);
  padding:9px 11px;display:flex;flex-direction:column;gap:2px}
.wy-cl-sum b{font-size:16px;color:var(--emph);font-variant-numeric:tabular-nums}
.wy-cl-sum span{color:var(--faint);font-size:10.5px;letter-spacing:.04em;text-transform:uppercase}

/* guest gate for the predictive block: one clean sign-in teaser card */
.t-lock{margin-top:14px;background:var(--inset-bg);border:1px solid var(--line);
  border-radius:var(--r-3);padding:12px 13px}
.t-lock .t-note{padding:2px 0 10px}
.t-lock-btn{width:100%;padding:9px;font-size:var(--fs-3);border-radius:var(--r-3)}
/* Gold law: solid --gold is the loudest thing and belongs to the ACTION. The
   states were inverted — the inert "Following" was a full gold slab while the
   real CTA (Follow) was a tint outline. Now Follow is the solid CTA and the
   followed state is a quiet chip that recedes. */
.t-follow{width:100%;margin-top:12px;background:var(--gold);color:var(--on-gold);
  border:1px solid var(--gold);border-radius:var(--r-3);padding:10px;font-weight:500;font-size:var(--fs-3)}
.t-follow.on{background:var(--seg-on);color:var(--gold-quiet);border-color:var(--line-strong)}
.t-follow.on:hover{border-color:var(--down);color:var(--down);background:var(--down-bg)}
.t-tgt{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-bottom:8px}
.t-tgt label{font-size:var(--fs-3);color:var(--dim);white-space:nowrap}
.t-tin{width:110px;text-align:right;padding:6px 9px;font-size:var(--fs-3)}
/* the saved-state line under the alert inputs: chip + the levels in mono, so the
   sidebar confirms exactly what the watchlist shows */
#tgt-hint .t-hint-lv{font-family:var(--mono);color:var(--dim);margin-left:6px}

/* modals */
.modal-bg{position:fixed;inset:0;z-index:60;background:var(--backdrop);
  display:flex;align-items:center;justify-content:center;padding:24px;overflow-y:auto}
/* Sign-in splash: full-bleed `cover`, edge-to-edge, and NOTHING ELSE.
   ABSOLUTE RULE (Diego, rejected ~8 times): never `contain`, never letterbox
   bars, never a blurred/darkened backdrop layer, never any side fill of any
   kind. If the wyrm is clipped at some aspect, the ONLY acceptable fix is
   different SOURCE ART composed with croppable dark margin — never a CSS
   arrangement. The dark base colour shows only if the image fails to load.

   GEOMETRY CONTRACT — one composition, two canvas widths, wyrm bbox 848x672px
   centred in both. `cover` shows a canvas_w/A-tall slice at viewport aspect A,
   so the wyrm stays whole while A <= canvas_w/672:
     hero-splash.webp       1600x1024  A <= 2.38   (default, every normal PC)
     hero-splash-wide.webp  2944x1024  A <= 4.38   (swapped in above A 2.35)
   Together they cover A 0.83 -> 4.38 with no gap, i.e. a narrow half-screen
   window through 32:9. The margin either side is croppable dark hall, and that
   is what `cover` eats instead of the wyrm.

   WHY 1600 AND NOT WIDER: the canvas width also sets how BIG the wyrm renders.
   At 2048 the arc dropped 7-12px BEHIND the auth card on a 1366x768 screen; at
   1600 it rides 38-56px above it. Widen this and the arc goes behind the panel
   again — that is the regression to watch for, not clipping.
   THE OTHER TRAP: padding vertically buys no wide-aspect headroom at all — the
   visible slice is canvas_width/A, so only a wider canvas moves that number.
   Verified against 22 PC sizes (1280x720 -> 5120x1440, maximised and
   fullscreen): worst edge clearance +27px, worst arc-above-card +18px.
   Margins are mirror-TILED from each edge's outer 304px, which is pillar only —
   a wider band drags the goblets in and they ghost in the margin. The unpadded
   original is kept at assets/source/hero-splash-1536x1024.webp. */
#login{background:#050403 url("/assets/hero-splash.webp") center/cover no-repeat}
/* float the card above both layers; width:min() keeps it inside narrow phones
   (min-width:0 defeats the flex-item auto min so it can actually shrink) */
#login .modal{position:relative;z-index:2;width:min(340px,100%);min-width:0;
  box-shadow:0 26px 64px -14px rgba(0,0,0,.78),0 8px 22px rgba(0,0,0,.5),
  0 0 0 1px var(--glow),0 0 42px var(--glow)}
.modal-bg[hidden]{display:none}
/* margin:auto + the overlay's overflow-y:auto = centered when it fits, fully
   scrollable (top reachable) when the card is taller than the viewport. */
/* width:min(340px,100%) + min-width:0 on EVERY modal (it used to be #login's
   alone): the settings card is a flex child of a 24px-padded backdrop, so on a
   320px phone a fixed 340px was wider than the space it sat in. */
.modal{width:min(340px,100%);min-width:0;background:var(--panel2);border:1px solid var(--line);
  border-radius:var(--r-4);padding:26px 24px;position:relative;margin:auto}
.mclose{position:absolute;top:14px;right:14px;background:transparent;border:none;color:var(--faint);font-size:var(--fs-5);box-shadow:none}
.mlogo{font-size:var(--fs-6);font-weight:500;text-align:center}
/* the FULL logo, transparent, above the sign-in form — never clipped */
.mbrand{display:block;width:250px;max-width:86%;height:auto;margin:4px auto 2px;
  filter:drop-shadow(0 6px 18px rgba(0,0,0,.5))}
.msub{text-align:center;color:var(--dim);font-size:var(--fs-4);margin:6px 0 20px}
.fl{display:block;font-size:var(--fs-2);color:var(--dim);margin:0 0 5px}
.fin{width:100%;margin-bottom:13px}
.mprimary{width:100%;background:var(--gold);color:var(--on-gold);border:none;border-radius:var(--r-3);
  padding:11px;font-weight:500;font-size:var(--fs-4)}
.mfoot{text-align:center;font-size:var(--fs-3);color:var(--faint);margin:15px 0 0}
.mfoot.err{color:var(--down)}
.mfoot.ok{color:var(--up)}
/* auth card: secondary (Register) button + inline links, and the switchable
   views. Hiding is the global [hidden] rule; only the shared logo/close persist. */
.mlink{color:var(--gold);text-decoration:none;font-weight:500}
.mlink:hover{text-decoration:underline}
.msecondary{width:100%;margin-top:11px;background:transparent;color:var(--gold);
  border:1px solid var(--gold);border-radius:var(--r-3);padding:11px;font-weight:500;font-size:var(--fs-4)}
.msecondary:hover{background:var(--gold-bg)}
/* Registration closed (Admin → Settings): a plain notice above the Register
   form, the form itself dimmed and inert, and the sign-in view's Register
   button relabelled — the state reads the same in every view. */
.auth-closed{margin:0 0 14px;padding:10px 12px;border:1px solid var(--warn);border-left-width:3px;
  border-radius:var(--r-2);background:var(--warn-bg);text-align:left}
.auth-closed b{display:block;color:var(--warn);font-size:var(--fs-4);margin-bottom:2px}
.auth-closed span{display:block;color:var(--dim);font-size:var(--fs-3);line-height:1.5}
.auth-closed[hidden]{display:none}
#register-form.is-closed{pointer-events:none}
#register-form.is-closed .fl{color:var(--faint)}
#register-form.is-closed .fin{color:var(--faint);background:var(--panel2);border-color:var(--row-line)}
#register-form.is-closed .mprimary{background:var(--panel2);color:var(--faint);border:1px solid var(--line);box-shadow:none}
.msecondary.is-closed{color:var(--dim);border-color:var(--line-strong);cursor:default}
.msecondary.is-closed:hover{background:transparent;color:var(--dim);border-color:var(--line-strong)}
/* Desktop auth card — PROPORTIONAL, not pixel-stepped. Two rules make it work
   at any screen size:
     1. the panel is a share of the VIEWPORT (~40% wide, ~80% tall), and
     2. every child is sized in `em`, so one font-size on .modal is the single
        knob that scales the logo, type, fields, buttons and gaps together.
   That knob is itself viewport-derived (vh), so the contents keep the same
   proportion of the panel on a 13" laptop and a 4K monitor alike. The clamps
   are only sanity rails (unreadable at the low end, comic at the high end).
   Mobile (<=640px) keeps the compact fixed-px card Diego signed off on. */
/* Height is part of the gate: a landscape phone is wider than 641px but far
   too short for the vh-scaled desktop card, which became a nested scroll box.
   Below 600px tall it keeps the compact fixed-px card. */
@media(min-width:641px) and (min-height:600px){
  #login .modal{
    /* ONE knob, keyed to viewport height; EVERYTHING else (width, padding,
       type, fields, gaps) is em-relative to it, so the card scales as a unit
       on any screen. 1.31vh lands on the signed-off 17px type at this desk's
       ~1300px viewport, and 33em then gives that card's ~560px width.
       Height is deliberately AUTO: a fixed height leaves dead space above and
       below the shorter sign-in view (2 fields) — letting the panel hug its
       content keeps every view tight, and max-height caps the tallest one. */
    font-size:clamp(12px,1.31vh,30px);
    width:min(33em,92vw);
    max-height:90vh;
    padding:2.4em 2.2em;overflow-y:auto}
  #login .mbrand{width:82%;max-width:100%;margin:0 auto .6em}
  #login .msub{font-size:1em;margin:.5em 0 1.5em}
  #login .fl{font-size:.92em;margin:0 0 .34em}
  #login .fin{font-size:.97em;padding:.62em .8em;margin-bottom:.9em;border-radius:.5em}
  #login .mprimary{font-size:1em;padding:.82em;border-radius:.55em}
  #login .msecondary{font-size:.97em;padding:.76em;margin-top:.72em;border-radius:.55em}
  #login .mfoot{font-size:.88em;margin-top:.9em}
  #login .mclose{font-size:1.15em;top:.7em;right:.8em}
  /* Register/update carry 4 fields; trim their gaps a touch so every view
     lives inside the same panel without the panel itself changing size. */
  #login .auth-view[data-view="register"] .fin,
  #login .auth-view[data-view="update"] .fin{margin-bottom:.62em}
  #login .auth-view[data-view="register"] .fl,
  #login .auth-view[data-view="update"] .fl{margin-bottom:.26em}
}
.field{margin-bottom:15px} .field label{display:block;font-size:var(--fs-3);color:var(--dim);margin-bottom:5px}
.field input,.field select{width:100%} .hint{font-size:var(--fs-2);color:var(--faint);margin:5px 0 0;line-height:1.5}
.row-btns{display:flex;gap:10px;justify-content:flex-end;margin-top:6px}

/* ---- entrances ----------------------------------------------------------
   Everything that appears used to be a hard cut: a 2600ms toast popped into
   existence and vanished mid-read, and the account menu — carrying a 30px-blur
   shadow — materialised with no origin. [hidden]{display:none} is the app's
   only show/hide mechanism, so animating :not([hidden]) is what makes these
   possible at all. Reduced motion is handled by the global guard near the top. */
@keyframes pop-in{from{opacity:0;transform:translateY(-6px) scale(.97)}to{opacity:1;transform:none}}
@keyframes toast-in{from{opacity:0;transform:translateX(-50%) translateY(10px)}
                    to{opacity:1;transform:translateX(-50%)}}
@keyframes card-in{from{opacity:0;transform:translateY(14px) scale(.985)}to{opacity:1;transform:none}}
@keyframes fade-in{from{opacity:0}to{opacity:1}}
.menu:not([hidden]){animation:pop-in var(--dur-3) var(--ease-emph);transform-origin:top right}
.search-dd:not([hidden]){animation:pop-in var(--dur-2) var(--ease-emph);transform-origin:top right}
.modal-bg:not([hidden]){animation:fade-in var(--dur-3) var(--ease-out)}
.modal-bg:not([hidden]) .modal{animation:card-in var(--dur-3) var(--ease-emph)}
.overlay:not([hidden]){animation:fade-in var(--dur-4) var(--ease-out)}
.toast:not([hidden]){animation:toast-in var(--dur-3) var(--ease-emph)}
/* A left:50% fixed box shrink-wraps to at most ~50vw, so a long message on a
   360px phone folded into a ~180px-wide multi-line pill. Give it real width. */
/* ---- tooltips ---- one bubble (#tip, app.js tipEngine); carriers wear a
   dotted underline so the explanation is discoverable, and cursor:help. */
[data-tip]{cursor:help}
th[data-tip],.t-row span[data-tip],.t-tgt label[data-tip],.b-head b[data-tip],.pulse>div[data-tip] span,.pulse a[data-tip] span{
  text-decoration:underline dotted;text-decoration-color:var(--line-strong);text-underline-offset:3px;text-decoration-thickness:1px}
.tip{position:fixed;z-index:90;max-width:300px;background:var(--tip-bg);border:1px solid var(--line-strong);
  border-radius:var(--r-2);padding:8px 11px;font-size:var(--fs-3);line-height:1.5;color:var(--ink);
  font-family:var(--sans);font-weight:400;text-transform:none;letter-spacing:0;text-align:left;
  box-shadow:var(--edge),var(--sh-2);pointer-events:none;opacity:0;transform:translateY(2px);
  transition:opacity var(--dur-1) var(--ease-out),transform var(--dur-1) var(--ease-out)}
.tip.on{opacity:1;transform:none}
.tip::after{content:"";position:absolute;left:50%;bottom:-5px;width:8px;height:8px;margin-left:-4px;
  background:var(--tip-bg);border-right:1px solid var(--line-strong);border-bottom:1px solid var(--line-strong);transform:rotate(45deg)}
.tip.below::after{bottom:auto;top:-5px;transform:rotate(225deg)}
.toast{position:fixed;bottom:24px;left:50%;transform:translateX(-50%);z-index:80;
  width:max-content;max-width:min(92vw,520px);text-align:center;
  background:var(--panel2);border:1px solid var(--line);border-radius:var(--r-3);
  padding:12px 18px;font-size:var(--fs-4);box-shadow:var(--edge),var(--sh-2)}
.toast[hidden]{display:none}

/* Phones: the four tabs become an app-style fixed bottom nav. z 45 keeps it
   above the detail overlay (40) so navigation works from item pages too. */
@media(max-width:640px){
  /* grid-auto-flow:column, not repeat(4,1fr): the nav holds however many tabs
     are VISIBLE (4 for guests/members, more for admins) in one equal-width
     row, instead of a fixed four tracks that wrapped a fifth tab onto a second
     row the 104px #main padding never cleared. */
  .tabs{position:fixed;bottom:0;left:0;right:0;z-index:45;
    display:grid;grid-auto-flow:column;grid-auto-columns:1fr;gap:2px;border-radius:0;
    background:var(--panel);
    background-image:linear-gradient(180deg,rgba(255,255,255,.03),transparent 60%);
    border-top:1px solid var(--line-strong);
    padding:5px calc(6px + env(safe-area-inset-right)) calc(5px + env(safe-area-inset-bottom)) calc(6px + env(safe-area-inset-left));
    box-shadow:0 -4px 16px rgba(0,0,0,.35)}
  /* icon + label per tab — the "this is an app" read on a phone. The label is a
     block so it can ellipsis; the icon sits above it at a fixed 22px. */
  .tabs :is(button,a){border-radius:var(--r-3);padding:6px 2px 5px;font-size:var(--fs-2);text-align:center;min-height:44px;
    white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0;
    display:flex;flex-direction:column;align-items:center;justify-content:center;gap:3px;line-height:1.2;font-weight:500}
  .tabs .ico{display:block;width:22px;height:22px;stroke-width:1.75;margin:0;opacity:.85}
  .tabs :is(button,a).on .ico{opacity:1}
  .tabs .tl{display:block;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .tabs .lk{margin-left:.2em}
  .tabs .lk .ico{display:inline-block;width:.8em;height:.8em;stroke-width:2.2}
  .tabs .coming-soon .soon-tag{position:absolute;top:2px;right:2px;margin:0;padding:0 2px;font-size:6px}
  .tabs .coming-soon .lk{position:absolute;top:3px;left:3px;margin:0}
  .tabs .coming-soon .lk .ico{width:8px;height:8px}
  /* "Long-term Trends" wrapped inside an ~81px cell; the qualifier is desktop-only. */
  .tabs .tl-long{display:none}
  #main{padding-bottom:calc(104px + env(safe-area-inset-bottom))}
  .subbar{padding-top:8px;padding-bottom:8px}
  /* Overview boards were being amputated: min-content ~497px against ~346px of
     available width, cut off by the card's own overflow:hidden with NO scrollbar
     and no affordance — the last column simply vanished. Tighten the gutters,
     shrink the icon well, drop one numeric column, and let the item name
     ellipsis instead of forcing the table wider than the screen. */
  #main{padding-left:max(12px,env(safe-area-inset-left));padding-right:max(12px,env(safe-area-inset-right))}
  .board table{table-layout:fixed;width:100%}
  .board thead th,.board tbody td{padding-left:9px;padding-right:9px}
  .board .mi{gap:9px;min-width:0}
  .board .mi-ico{width:26px;height:26px}
  .board .mi-ico img{width:22px;height:22px}
  .board .mi span{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:block}
  .board th:not(.l),.board td:not(.l){width:88px}
  .board thead th{font-size:var(--fs-1);letter-spacing:.04em}   /* 88px wells: the bigger desktop header would wrap */
  /* WHICH column drops is the table builder's call, not position's: app.js /
     wyrm.js mark it .p-hide (Buy limit on All Items, 24h on Most traded, volume
     on risers/fallers, rank + volume on Long-term Trends). The old
     `tr>:nth-child(3)` rule hid Price on Long-term Trends and the ranked-by
     volume on Most traded while the inert Buy limit column survived. */
  thead th.p-hide,tbody td.p-hide{display:none}
  /* Toast cleared the fixed bottom nav (it used to land on top of it). */
  .toast{bottom:calc(84px + env(safe-area-inset-bottom))}
  /* The bottom nav now floats over the detail terminal — give its stacked
     content room to scroll clear of it. */
  .overlay .term{padding-bottom:calc(76px + env(safe-area-inset-bottom))}
  /* Watchlist at phone width: volume + since-followed already drop via .m-hide,
     so Item · Alert · Price · 24h · Buy · Sell · actions fit. Tighten gutters and
     let the (sticky) item name ellipsis instead of forcing a wider table. */
  .wl-table th,.wl-table td{padding-left:9px;padding-right:9px}
  .wl-table td.l:first-child{max-width:130px}
  .wl-table .mi{gap:8px;min-width:0}
  .wl-table .mi span{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:block}
  /* Watchlist actions need more width than a market quote table. On phones,
     give each item a readable name/price row and a target/actions row instead
     of squeezing its name to zero between fixed-width numeric columns. */
  .catalogue-table .wl-table,.catalogue-table .wl-table tbody{display:block;width:100%}
  .catalogue-table .wl-table thead{display:none}
  .catalogue-table .wl-table tbody tr{display:grid;grid-template-columns:minmax(0,1fr) auto;
    gap:2px 8px;padding:7px 9px;border-bottom:1px solid var(--line)}
  #results .catalogue-table .wl-table tbody td{position:static;width:auto;max-width:none;
    padding:2px 0;border:0;background:transparent}
  .catalogue-table .wl-table tbody td:nth-child(1){grid-column:1;grid-row:1}
  .catalogue-table .wl-table tbody td:nth-child(3){grid-column:2;grid-row:1;align-self:center}
  .catalogue-table .wl-table tbody td:nth-child(7){grid-column:1;grid-row:2;align-self:center;text-align:left}
  .catalogue-table .wl-table tbody td:nth-child(8){grid-column:2;grid-row:2}
  .catalogue-table .wl-table tbody td:nth-child(2),.catalogue-table .wl-table tbody td:nth-child(5){display:none}
  .catalogue-table .wl-tgt::before{content:"Target ";color:var(--faint);font-size:var(--fs-2)}
  .catalogue-table .wl-table .mi span{white-space:normal;overflow-wrap:anywhere}
}

/* Phones: the search gets its own full-width row instead of vanishing; the
   table builders mark low-priority columns .m-hide so Item / Price / movement
   / Risk / Signal survive; the detail terminal stacks vertically (its item
   list is desktop-only — header search covers lookup on a phone). */
/* Touch devices: nothing in the app reached the 44px minimum — the tallest
   control measured 39px. Scoped to `pointer:coarse` so mouse users keep the
   tighter desktop rhythm, and applied via min-height + centring rather than
   padding so nothing reflows. */
@media(pointer:coarse){
  button,.btn-signin,.mprimary,.msecondary,.acct-chip,.mchips :is(button,a),
  .tabs :is(button,a),.games :is(button,a),select,input,.t-follow{min-height:44px}
  .mchips :is(button,a),.games :is(button,a),.tabs :is(button,a){display:inline-flex;align-items:center;
    justify-content:center}
  .mclose{min-width:44px;min-height:44px;display:flex;align-items:center;justify-content:center}
  /* keep the ☰ square when the coarse-pointer min-height bumps it to 44 */
  .t-burger{width:44px;height:44px}
  .menu button{min-height:44px;display:flex;align-items:center}
  /* the ✎/✕ row-actions set min-height above but never min-width, so they stayed
     ~32px wide — below the 44px target on touch. */
  .wl-actions .ghost{min-width:44px}
}
/* text-overflow only works on a BLOCK container: the coarse-pointer rule above
   turns the phone bottom-nav tabs into inline-flex, which clipped long labels
   from both ends ("yrm Pic") instead of ellipsising. Back to block here, after
   that rule; 22px line + 11px padding keeps the 44px target and centres it. */
@media(max-width:640px) and (pointer:coarse){.tabs :is(button,a){display:flex;line-height:1.2}}

/* THE TABLET DEAD BAND. .m-hide used to fire only below 760px, but the Long
   Plays screener needs ~1250px to lay out — so from 761px to ~1250px it hid
   nothing and simply overflowed, pushing the gated SIGNAL column (the entire
   sign-up mechanic) off the right edge on every tablet and small laptop. Drop
   the low-priority columns from 1180px down instead, which is the widest point
   the screener still fits without them. */
@media(max-width:1180px){
  thead th.m-hide,tbody td.m-hide{display:none}
}
@media(max-width:760px){
  .hdr{gap:10px;padding:calc(8px + env(safe-area-inset-top)) max(14px,env(safe-area-inset-right)) 8px max(14px,env(safe-area-inset-left))}
  .hdr-right{flex:1 1 100%;position:relative}
  .search-wrap{flex:1;min-width:0;position:static}
  /* The typeahead panel spans the whole search row instead of hanging off the
     input's right edge: the input shares that row with the account control,
     so a 320px right-anchored panel overhung the left edge of a 375px phone
     by 50-100px and the item icons were the part that got cut. Anchored to
     .hdr-right (position:relative above), so left:0 is the row's left. */
  .search-dd{left:0;right:0;width:auto;top:calc(100% + 4px)}
  /* Item name stays put while the numbers scroll, so a row never loses its
     subject — the screener is horizontally scrollable at this width. */
  #results{overflow-x:auto}
  /* :first-child, not every td.l — the watchlist has TWO left cells (Item + the
     Alert chip); only the item name should pin, or they'd stack at left:0. */
  #results thead th.l:first-child,#results tbody td.l:first-child{position:sticky;left:0;z-index:1;
    background:var(--panel)}
  #results tbody tr:hover td.l:first-child{background:var(--row-hover)}
  /* pin the watchlist action buttons to the right edge the same way — scoped
     to the watchlist table: a bare `thead th:last-child` grabbed whatever
     column came last in ANY table under #results. */
  #results tbody td.wl-actions,#results .wl-table thead th:last-child{position:sticky;right:0;z-index:1;
    background:var(--panel)}
}
@media(max-width:640px){
  .brand-logo{height:44px}
  .hdr{gap:8px;min-height:0;
    padding:calc(6px + env(safe-area-inset-top)) max(12px,env(safe-area-inset-right)) 6px max(12px,env(safe-area-inset-left))}
  .hdr-right{gap:8px}
  .games{padding:2px}
  .games :is(button,a){min-height:38px;padding:4px 10px}
  .btn-signin{min-height:38px;padding:6px 12px}
  .search{min-height:38px;padding:6px 9px}
  .subbar{gap:8px;padding:5px max(12px,env(safe-area-inset-right)) 5px max(12px,env(safe-area-inset-left))}
  .tools{gap:8px;justify-content:flex-end}
  .status{max-width:100%;padding:3px 8px;font-size:var(--fs-2)}
  .status::before{width:10px;height:10px;box-shadow:inset 0 0 0 2.5px var(--panel2)}
  .status.busy::before{width:10px;height:10px}
  .mchips{padding:6px 12px 0;gap:6px}
  .mchips :is(button,a){padding:4px 12px}
  #main{padding-top:12px}
  .search-board{margin-top:2px}
  .search-head{align-items:flex-start}
  .search-tools{align-items:flex-start;flex-direction:column}
  .search-pager{width:100%;justify-content:space-between}
}
/* Detail terminal stacks at 900, not 760: .term has min-width:820px (line 431),
   so between 761-819px it stayed a 3-column grid and overflowed horizontally —
   an iPad-portrait dead band. Stacking from 900 down closes it. Kept separate
   from the 760 block so the header/search/#results rules there are unaffected. */
@media(max-width:900px){
  .term-scroll{overflow-y:auto;overflow-x:hidden}
  .term{display:flex;flex-direction:column;min-width:0;height:auto;min-height:100%}
  .t-list{display:none}
  /* No list to toggle in the stacked layout — the ☰ goes too. */
  .t-burger{display:none}
  .t-mid{flex:none}
  .t-chart{height:46vh;flex:none}
  .t-side{border-left:none;border-top:1px solid var(--line)}
}

/* ============================================================ RS3 THEME ====
   RS3 NXT interface language: near-black charcoal-slate with a cool blue
   undertone, thin antique-gold (bronze) trim, small glowing gold accents.
   The cool ground is what makes the vibe switch real against OSRS's warm
   stone. Colours/shadows only — every box keeps its exact size. Text pairs
   verified >= 4.5:1 (ink/page 15.6:1, gold/panel2 7.8:1, dim/panel 8.3:1). */
/* RS3 — "Obsidian & White Gold". Every value generated in OKLCH from one
   perceptual ramp (see docs), so this theme and OSRS share identical lightness
   targets and contrast behaviour while reading as different worlds. Surfaces
   are near-achromatic graphite (chroma 0.006-0.012 — neutral, deliberately NOT
   the old navy); the accent is a rich gold on a deep obsidian ground.
   Do not hand-tune single values here: they are a system, not a list. */
:root[data-theme="rs3"]{
  --page:#030304; --panel:#0e0e11; --panel2:#1e1e22;
  --ink:#efe7d9; --dim:#b2aa9c; --faint:#908980; --flat:#908980;
  --up:#67c07d; --up-bg:rgba(103,192,125,.13);
  --down:#f58478; --down-bg:rgba(245,132,120,.13);
  --gold:#e6b731; --gold-quiet:#bea160; --gold-bg:rgba(230,183,49,.13);
  --emph:#f7d566; --on-gold:#08080a;
  --line:#2f3036; --line-strong:#4c4c54;
  --input-bg:#050608; --seg-on:#17171b; --hover-bg:#15161a;
  --row-line:#222226; --row-line2:#19191d; --row-hover:#161619;
  --ico-bg:#202024; --inset-bg:#050608; --tip-bg:#19191d;
  --warn:#ee9a52; --warn-bg:rgba(238,154,82,.13); --backdrop:rgba(3,3,4,.78);
  --ch-price:#e6b731; --ch-grid:#222226; --ch-label:#867f74;
  --ch-res:#af95df; --ch-sup:#6ebe80; --ch-exit:#e8796e; --ch-proj:#a99e7f;
  --ch-fill:rgba(230,183,49,.09); --ch-tag-bg:rgba(3,3,4,.9);
  --ch-cross:rgba(178,170,156,.42); --ch-ring:#030304;
  scrollbar-color:#3a3a41 #030304;
}
/* gilded double-hairline under the top chrome + a faint cool glow up top */
/* Header owns the gradient; the tab bar under it is flat (two restarted
   gradients + two identical trays made header and tabs carry equal weight).
   Neutral graphite now, not the retired navy: the content tokens were retuned
   to near-achromatic and the chrome had kept #1a1e28 (V6). */
[data-theme="rs3"] .hdr{
  background-image:linear-gradient(180deg,color-mix(in oklch,var(--panel2),white 5%),var(--panel));
  box-shadow:0 1px 0 rgba(215,171,63,.16),0 4px 16px rgba(0,0,0,.45)}
[data-theme="rs3"] .subbar{background:var(--panel);box-shadow:0 1px 0 rgba(215,171,63,.10)}
[data-theme="rs3"] body{background-image:radial-gradient(1200px 600px at 50% -10%,rgba(255,255,255,.035),transparent 60%)}
/* floating slate slabs with a metal catchlight along the top edge */
[data-theme="rs3"] .modal,[data-theme="rs3"] .menu,[data-theme="rs3"] .toast{
  background-image:linear-gradient(180deg,color-mix(in oklch,var(--panel2),white 5%),var(--panel2));border-color:var(--line-strong);
  box-shadow:inset 0 1px 0 rgba(255,222,140,.06),var(--sh-3)}
[data-theme="rs3"] #login{background:#050403 url("/assets/hero-splash.webp") center/cover no-repeat}
/* phones / portrait screens: swap to the tall portrait art so cover crops only
   the dark sides, never the wyrm. Selector beats the rs3 override above and is
   placed after it to win on source order; only the image swaps (cover stays). */
@media (max-aspect-ratio:1/1){
  #login,[data-theme] #login{background-image:url("/assets/hero-splash-mobile.webp")}}
/* ultrawide: past ~2.35 the 1600 canvas runs out of side margin and `cover`
   starts eating the crest, so swap to the 2944 canvas — same composition, more
   croppable colonnade either side. Same trick as the portrait swap: only the
   image changes, `cover` stays, so no bars can appear at any width. */
@media (min-aspect-ratio:47/20){
  #login,[data-theme] #login{background-image:url("/assets/hero-splash-wide.webp")}}
/* :where() keeps specificity at 0-0-1 so every classed button (.ghost,
   .primary, .games/.tabs/.menu buttons…) still wins for the properties it
   sets — the gloss lands only where the plain button background survives. */
:where([data-theme="rs3"]) button{
  background-image:linear-gradient(180deg,rgba(255,255,255,.055),rgba(0,0,0,.2));
  box-shadow:inset 0 1px 0 rgba(255,255,255,.04)}
/* selected tab glows along its lower edge, like NXT's active ribbon tab */
[data-theme="rs3"] .tabs :is(button,a).on{color:var(--emph);
  background:linear-gradient(180deg,color-mix(in oklch,var(--seg-on),white 6%),var(--seg-on));
  box-shadow:inset 0 0 0 1px var(--line-strong),inset 0 -9px 12px -10px rgba(255,216,115,.5)}
[data-theme="rs3"] input:focus,[data-theme="rs3"] select:focus{border-color:#d7ab3f;
  box-shadow:0 0 0 1px rgba(215,171,63,.25),0 0 10px rgba(215,171,63,.12)}
/* gold edge on the hovered row (on td, not tr — tr box-shadow is unreliable
   under border-collapse in Safari) */
[data-theme="rs3"] tbody tr:hover td:first-child{box-shadow:inset 2px 0 0 rgba(215,171,63,.55)}
/* filigree dividers: gold hairlines fading at both ends, structural headers
   only — never table rows, so row scanning stays uniform */
[data-theme="rs3"] .t-tick,[data-theme="rs3"] .t-lhead,[data-theme="rs3"] .t-search{
  border-image:linear-gradient(90deg,rgba(168,135,62,0),rgba(168,135,62,.55) 14%,rgba(168,135,62,.55) 86%,rgba(168,135,62,0)) 1}
[data-theme="rs3"] .menu .sep{background:linear-gradient(90deg,transparent,#8a7239,transparent)}
[data-theme="rs3"] .logo,[data-theme="rs3"] .mlogo{color:var(--gold)}
[data-theme="rs3"] thead th.sorted{color:var(--emph)}
[data-theme="rs3"] .t-px b{color:var(--emph)}

/* =========================================================== OSRS THEME ====
   Classic stone interface in pure CSS: warm brown page, stone panels with
   bevelled (outset) edges from light top/left + dark bottom/right border
   colours and inset shadows, orange-gold headings, bright-yellow emphasis,
   parchment body text, stone-slab buttons with a darker pressed state.
   No images, no game assets, no external fonts. Verified >= 4.5:1. */
/* OSRS — "Vault & Bronze". Same OKLCH ramp as RS3 (identical lightness targets),
   but warm-earth surfaces and an ANTIQUE BRONZE accent. The old --gold #ff981f
   was 100%-saturation orange, the highest-chroma value in the product and the
   main reason this theme read cheaper than RS3; chroma is now capped at 0.125.
   --ch-res is the same hue as RS3's so "resistance" means one thing app-wide. */
:root[data-theme="osrs"]{
  --page:#0b0502; --panel:#1c140e; --panel2:#2f2318;
  --ink:#f8e5c9; --dim:#bba88b; --faint:#9c8c74; --flat:#9c8c74;
  --up:#67c07d; --up-bg:rgba(103,192,125,.13);
  --down:#f58478; --down-bg:rgba(245,132,120,.13);
  --gold:#e4a250; --gold-quiet:#ae875c; --gold-bg:rgba(228,162,80,.13);
  --emph:#f7c77a; --on-gold:#0d0703;
  --line:#463423; --line-strong:#655140;
  --bev-l:#796453; --bev-d:#050200;
  --input-bg:#120a05; --seg-on:#281c12; --hover-bg:#271b11;
  --row-line:#362b22; --row-line2:#2b2017; --row-hover:#261c13;
  --ico-bg:#33261b; --inset-bg:#120a05; --tip-bg:#2b1f14;
  --warn:#f08f4a; --warn-bg:rgba(240,143,74,.13); --backdrop:rgba(11,5,2,.8);
  --ch-price:#e4a250; --ch-grid:#362b22; --ch-label:#8e7e66;
  --ch-res:#af95df; --ch-sup:#6ebe80; --ch-exit:#e8796e; --ch-proj:#a99e7f;
  --ch-fill:rgba(228,162,80,.09); --ch-tag-bg:rgba(11,5,2,.9);
  --ch-cross:rgba(187,168,139,.45); --ch-ring:#0b0502;
  scrollbar-color:#5b4636 #0b0502;
}
/* two-direction weave texture — but never under the price table: #results
   gets an opaque ground below */
[data-theme="osrs"] body{background-image:
  radial-gradient(1100px 520px at 50% -6%,rgba(255,214,140,.05),transparent 60%),
  repeating-linear-gradient(45deg,rgba(255,236,190,.012) 0 2px,transparent 2px 5px),
  repeating-linear-gradient(135deg,rgba(0,0,0,.03) 0 3px,transparent 3px 6px)}
[data-theme="osrs"] #results{background:var(--page)}
[data-theme="osrs"] .hdr{
  background-image:linear-gradient(180deg,#2a2010,#1d1509);
  box-shadow:inset 0 1px 0 rgba(255,236,190,.06),0 4px 14px rgba(0,0,0,.4)}
[data-theme="osrs"] .subbar{background:var(--panel);box-shadow:inset 0 1px 0 rgba(255,236,190,.04)}
[data-theme="osrs"] .logo,[data-theme="osrs"] .mlogo,[data-theme="osrs"] .gate h3{color:var(--gold)}
[data-theme="osrs"] thead th.sorted{color:var(--gold)}
[data-theme="osrs"] .tabs :is(button,a).on{color:var(--gold);
  box-shadow:inset 1px 1px 0 var(--bev-d),inset -1px -1px 0 rgba(255,236,190,.08)}
[data-theme="osrs"] #t-name,[data-theme="osrs"] .t-tick b{color:var(--emph)}
[data-theme="osrs"] .t-px b{color:var(--emph)}
[data-theme="osrs"] .t-row b:not(.up):not(.down):not(.flat){color:var(--emph)}
[data-theme="osrs"] .acct-chip .av{color:var(--emph)}
/* .t-item.sel is the one panel2 surface carrying up/down text — press it into
   the darker stone so the tuned red keeps >= 4.5:1 (5.7 on --seg-on). */
[data-theme="osrs"] .t-item.sel{background:var(--seg-on)}
/* stone-slab buttons: 1px bevel border (light TL / dark BR) + inner highlight;
   :where() keeps this at 0-0-1 so classed buttons override what they set */
:where([data-theme="osrs"]) button{
  background-image:linear-gradient(180deg,rgba(255,236,190,.07),rgba(0,0,0,.18));
  border-color:var(--bev-l) var(--bev-d) var(--bev-d) var(--bev-l);
  box-shadow:inset 0 1px 0 rgba(255,236,190,.06)}
:where([data-theme="osrs"]) button:active{
  background-color:#1a1207;background-image:none;
  border-color:var(--bev-d) var(--bev-l) var(--bev-l) var(--bev-d);
  box-shadow:inset 0 1px 2px rgba(0,0,0,.45)}
[data-theme="osrs"] .mprimary:active{
  background:var(--gold);filter:brightness(.92);
  box-shadow:inset 1px 1px 0 color-mix(in oklch,var(--gold),black 35%),inset -1px -1px 0 color-mix(in oklch,var(--gold),white 25%)}
[data-theme="osrs"] select,[data-theme="osrs"] input{
  border-color:var(--bev-d) var(--bev-l) var(--bev-l) var(--bev-d);
  box-shadow:inset 0 1px 2px rgba(0,0,0,.35)}
[data-theme="osrs"] input:focus,[data-theme="osrs"] select:focus{border-color:var(--gold)}
[data-theme="osrs"] .menu,[data-theme="osrs"] .toast{
  background-color:var(--panel);
  background-image:linear-gradient(180deg,rgba(255,236,190,.04),rgba(0,0,0,.12));
  border-color:var(--bev-l) var(--bev-d) var(--bev-d) var(--bev-l)}
/* dialogs are chiselled stone slabs with gold corner rivets (pure CSS) */
[data-theme="osrs"] .modal{
  background-color:var(--panel);
  background-image:
    radial-gradient(circle 3px at 9px 9px,#c79b46 30%,#7a5a22 65%,transparent 70%),
    radial-gradient(circle 3px at calc(100% - 9px) 9px,#c79b46 30%,#7a5a22 65%,transparent 70%),
    radial-gradient(circle 3px at 9px calc(100% - 9px),#c79b46 30%,#7a5a22 65%,transparent 70%),
    radial-gradient(circle 3px at calc(100% - 9px) calc(100% - 9px),#c79b46 30%,#7a5a22 65%,transparent 70%),
    linear-gradient(180deg,rgba(255,236,190,.05),rgba(0,0,0,.14));
  border-color:var(--bev-l) var(--bev-d) var(--bev-d) var(--bev-l);
  box-shadow:0 0 0 1px var(--bev-d),inset 0 1px 0 rgba(255,229,166,.10),
    inset -1px -1px 0 rgba(0,0,0,.38),0 16px 40px rgba(0,0,0,.5)}
[data-theme="osrs"] .t-tip{border-color:var(--bev-l) var(--bev-d) var(--bev-d) var(--bev-l)}
/* Content surfaces finally get the stone treatment: the four-colour bevel
   needs near-square corners, which --r-3:4px now provides. */
[data-theme="osrs"] .board,[data-theme="osrs"] .pulse,[data-theme="osrs"] .cat-tile,
[data-theme="osrs"] .sig-head,[data-theme="osrs"] .perf-card,[data-theme="osrs"] .preview-cta,
[data-theme="osrs"] .wy-edit,[data-theme="osrs"] .wy-admin,[data-theme="osrs"] .wy-item,
[data-theme="osrs"] #wy-bt-panel:not(:empty),[data-theme="osrs"] .about-feats li,
[data-theme="osrs"] .tldr,[data-theme="osrs"] .contact-card,[data-theme="osrs"] .wy-stat-tiles>div{
  border-color:var(--bev-l) var(--bev-d) var(--bev-d) var(--bev-l);
  background-image:linear-gradient(180deg,rgba(255,236,190,.045),rgba(0,0,0,.14))}
[data-theme="osrs"] .wy-admin{border-color:var(--gold)}   /* the admin card keeps its gold identity edge under the stone */
/* real bevels are square: rounded corners smear the four-colour border trick */
/* primary CTAs wear the stone too (box-shadow bevel — no size change) */
[data-theme="osrs"] .mprimary{border-radius:var(--r-1);
  box-shadow:inset 1px 1px 0 color-mix(in oklch,var(--gold),white 25%),inset -1px -1px 0 color-mix(in oklch,var(--gold),black 35%)}
[data-theme="osrs"] .btn-signin,[data-theme="osrs"] .msecondary{border-radius:var(--r-1);
  border-color:var(--bev-l) var(--bev-d) var(--bev-d) var(--bev-l);
  background-image:linear-gradient(180deg,rgba(255,236,190,.06),rgba(0,0,0,.14))}
/* carved stone lintel over the screener columns */
[data-theme="osrs"] thead th{
  background:linear-gradient(180deg,#2a2010,#1f170b);
  border-bottom:1px solid var(--bev-d);
  box-shadow:inset 0 1px 0 rgba(255,229,166,.05)}
/* the classic OSRS tell: clickable text flashes yellow on hover */
[data-theme="osrs"] tbody tr:hover .mi b,
[data-theme="osrs"] .t-item:hover .nm,
[data-theme="osrs"] .menu button:hover,
[data-theme="osrs"] .back:hover{color:var(--emph)}
/* risk grades re-tinted for the brown surfaces (>= 6.6:1 over the page) */
[data-theme="osrs"] .gA{background:rgba(87,201,87,.16);color:#8ce08c}
[data-theme="osrs"] .gB{background:rgba(154,205,68,.16);color:#c5dc82}
[data-theme="osrs"] .gC{background:rgba(240,207,90,.15);color:#f0cf5a}
[data-theme="osrs"] .gD{background:rgba(255,154,92,.15);color:#ff9a5c}
[data-theme="osrs"] .gF{background:rgba(245,122,103,.16);color:#ffa294}

/* ==================================================== DISPLAY TIER ====
   All self-hosted, latin-subset woff2 — no third-party request, nothing for
   the CSP to block, no render-blocking round trip. Licences in assets/fonts/.

   RS3   -> Cinzel (Natanael Gama, SIL OFL): roman inscriptional caps that echo
            the gold logotype.
   OSRS  -> a HYBRID, and the split is the whole point. Alagard is a PIXEL font:
            it is the authentic 2007 voice but it visibly crumbles below ~16px,
            so it takes only the large brand strings. IM Fell English (Igino
            Marini, SIL OFL) carries the small headings, where it stays crisp
            and reads as an aged ledger rather than a retro game.

   Scope is deliberately six selectors. NEVER extend this to: the detail-overlay
   item name (.logo — dynamic data), any numeral (they are monospace so columns
   stay aligned), or anything under ~12px. */
@font-face{font-family:"Alagard";src:url("/assets/fonts/alagard.woff2") format("woff2");font-display:swap}
@font-face{font-family:"Cinzel";src:url("/assets/fonts/cinzel.woff2") format("woff2");
  font-weight:600;font-display:swap}
@font-face{font-family:"IM Fell English";src:url("/assets/fonts/imfell.woff2") format("woff2");
  font-weight:400;font-display:swap}   /* single weight; font-synthesis:none on its users stops faux-bold */
:root{
  --display:"Cinzel",Georgia,serif;        /* headings           */
  --display-brand:"Cinzel",Georgia,serif;  /* brand / masthead   */
}
:root[data-theme="osrs"]{
  --display:"IM Fell English",Georgia,serif;
  --display-brand:"Alagard","IM Fell English",Georgia,serif;
}
/* .perf-h left this list: an 11.5px --faint label is under the 12px floor the
   comment above sets. :where() keeps the tracking at 0 specificity so
   component rules (.t-shead's .06em) keep their own letter-spacing. */
.board .b-head b,.sig-head b,.t-shead{font-family:var(--display);font-synthesis:none}
:where(.board .b-head b,.sig-head b){letter-spacing:.015em}
.mlogo,.gate h3{font-family:var(--display-brand);font-weight:600;
  font-synthesis:none;letter-spacing:.02em}
/* Alagard is unhinted pixel art: it must never be synthesised or tracked in. */
[data-theme="osrs"] .mlogo,[data-theme="osrs"] .gate h3{font-weight:400}
/* Alagard is pixel art: it only looks right at its native 16px and at 32px. */
[data-theme="osrs"] .gate h3{font-size:32px}

/* ================================================= GAME TOGGLE BUTTONS ====
   Each button wears its OWN game's skin regardless of the active theme, so
   the switch itself telegraphs both styles: RS3 dark + gold trim, OSRS stone
   + orange bevel. Idle text passes 4.5:1 on both themes' --panel2 tray. */
.games :is(button,a)[data-game="rs3"]{color:#b6b0a0}
.games :is(button,a)[data-game="rs3"].on{
  background:linear-gradient(180deg,#26262c,#17171b);color:#ffd873;
  box-shadow:inset 0 0 0 1px #8a7239,inset 0 -9px 12px -10px rgba(255,216,115,.45)}
.games :is(button,a)[data-game="osrs"]{color:#e8a457}
.games :is(button,a)[data-game="osrs"].on{
  background:linear-gradient(180deg,#332413,#1d1509);color:#ffb457;
  box-shadow:inset 1px 1px 0 #8a6f3a,inset -1px -1px 0 #0b0703}

/* ---- Performance page (#/performance) ----------------------------------
   Folded into the design system 2026-07-29. It was previously a parallel
   vocabulary: `--muted` and `--fg` are declared NOWHERE in this file, so every
   rule fell back to its hard-coded brown and the page stayed OSRS-coloured in
   both themes. It also sized in rem against an undeclared root while the app
   body is 14.5px, and `display:block` on the table defeated its own width:100%
   (the ledger rendered at ~44% of the page with the rest left empty).
   Substitutions: --muted -> --faint, --fg -> --ink, white-alphas -> --row-line
   / --row-hover, private radius -> the shared card radius. */
.perf-link{color:var(--gold);text-decoration:none;font-weight:600;
  margin-left:.5rem;white-space:nowrap}
.perf-link:hover{text-decoration:underline}
.perf-grid{display:grid;gap:10px;margin:13px 0 16px;
  grid-template-columns:repeat(auto-fit,minmax(150px,1fr))}
.perf-card{background:var(--panel);border:1px solid var(--line);
  border-radius:var(--r-4);padding:11px 13px;display:flex;flex-direction:column;gap:2px;
  box-shadow:var(--edge),var(--sh-1)}
.perf-card .pk{font-size:var(--fs-1);letter-spacing:.09em;text-transform:uppercase;
  color:var(--faint)}
.perf-card .pv{font-family:var(--mono);font-size:var(--fs-7);font-weight:600;
  color:var(--ink);font-variant-numeric:tabular-nums}
.perf-card .ps{font-size:var(--fs-2);color:var(--faint)}
.perf-h{font-weight:600;letter-spacing:.06em;text-transform:uppercase;
  font-size:var(--fs-2);color:var(--faint);margin:18px 0 7px}
.perf-note{background:var(--panel);border-left:3px solid var(--gold);
  border-radius:0 var(--r-3) var(--r-3) 0;padding:10px 13px;margin:10px 0 16px;
  font-size:var(--fs-3);line-height:1.5;color:var(--dim);box-shadow:var(--edge),var(--sh-1)}
.perf-note b{color:var(--ink)}
/* display:table so it actually fills the column; the scroll moves to a wrapper
   at phone width instead of crippling the desktop layout. */
.perf-t{width:100%;border-collapse:collapse;font-size:var(--fs-4);
  font-variant-numeric:tabular-nums;display:table;table-layout:auto}
.perf-t th{text-align:right;letter-spacing:.08em;text-transform:uppercase;
  color:var(--faint);border-bottom:1px solid var(--line);
  padding:9px 12px;white-space:nowrap;font-weight:500}
.perf-t td{padding:11px 12px;border-bottom:1px solid var(--row-line);
  white-space:nowrap;text-align:right;color:var(--ink)}
.perf-t th:first-child,.perf-t td:first-child{text-align:left;width:auto}
.perf-t th:not(:first-child),.perf-t td:not(:first-child){width:110px}
.perf-t tbody tr:hover td{background:var(--row-hover)}
.perf-t .muted{color:var(--faint)}
@media(max-width:760px){.perf-t{display:block;overflow-x:auto}}

/* ---------- D6/D13: screener, saved filters, live Long Plays ---------- */
.wy-grid{display:grid;grid-template-columns:minmax(220px,300px) 1fr;gap:16px}
@media(max-width:720px){.wy-grid{grid-template-columns:1fr}}
.wy-list-head{display:flex;justify-content:space-between;align-items:center;margin-bottom:8px}
.wy-item{display:flex;align-items:center;gap:10px;padding:8px 10px;border:1px solid var(--line);
  border-left-width:3px;border-radius:var(--r-3);margin-bottom:6px;cursor:pointer}
.wy-item:hover{background:var(--hover-bg)}
.wy-item.sel{border-color:var(--gold)}
/* enabled/disabled reads at a glance: colored left edge + the pill toggle */
.wy-item.en{border-left-color:var(--up)}
.wy-item.dis{border-left-color:var(--down)}
.wy-item-main{flex:1 1 auto;display:flex;flex-direction:column;gap:2px;min-width:0}
.wy-item-n{font-weight:600}
.wy-item-m{color:var(--dim);font-size:var(--fs-3)}
.wy-tog{flex-shrink:0;font-size:var(--fs-2);padding:4px 10px;border-radius:var(--r-pill);white-space:nowrap;
  display:inline-flex;align-items:center;border:1px solid var(--line)}
.wy-tog.on{color:var(--up);border-color:var(--up);background:var(--up-bg)}
.wy-tog.off{color:var(--down);border-color:var(--down);background:var(--down-bg)}
.wy-tog.static{cursor:default;opacity:.75}
/* a clause is a bare row of controls — no wrapper box around boxes */
.wy-clause{display:flex;gap:6px;margin-bottom:6px;align-items:center;flex-wrap:wrap}
.wy-clause select,.wy-clause input{min-width:0}
.wy-clause .wy-val{flex:0 1 220px}
.wy-clause .wy-del{flex-shrink:0;color:var(--faint);padding:4px 9px}
.wy-clause .wy-del:hover{color:var(--down);border-color:var(--down)}
.wy-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap;margin-bottom:8px}
.wy-row label{display:inline-flex;align-items:center;gap:6px;color:var(--dim);font-size:var(--fs-3)}
.wy-name{flex:1 1 180px}
.wy-desc{width:100%;margin-bottom:8px}
.wy-actions{display:flex;gap:8px;margin-top:10px;flex-wrap:wrap}
.wy-err{color:var(--down);margin-top:8px;font-size:var(--fs-4)}
.wy-note{color:var(--warn);font-size:var(--fs-3);margin:6px 0}
.wy-empty{color:var(--dim);padding:14px;border:1px dashed var(--line);border-radius:var(--r-3);line-height:1.6}
.wy-table{width:100%;border-collapse:collapse;font-size:var(--fs-4);display:block;overflow-x:auto}
.wy-table th,.wy-table td{padding:6px 8px;border-bottom:1px solid var(--line);text-align:left;
  white-space:nowrap}
.wy-cfg{padding:10px;border:1px solid var(--line);border-radius:var(--r-3);margin-bottom:12px}
.wy-tabs{display:flex;gap:6px;margin-bottom:12px;border-bottom:1px solid var(--line)}
.wy-tab{background:none;border:none;padding:8px 4px;color:var(--dim);cursor:pointer;
  border-bottom:2px solid transparent;font-size:var(--fs-5)}
.wy-tab.on{color:var(--ink);border-bottom-color:var(--gold)}
.wy-ok{color:var(--up)}
.wy-warn{color:var(--warn)}
.wy-bt-head{margin-top:14px;padding-top:10px;border-top:1px solid var(--line)}
.wy-bt-note td{color:var(--dim);font-size:var(--fs-3);white-space:normal;font-style:italic}
/* both editors read as one designed card, not bare inputs on the page */
.wy-edit{background:var(--panel);border:1px solid var(--line);border-radius:var(--r-4);
  padding:14px;box-shadow:var(--edge),var(--sh-1)}
.wy-shead{font-size:var(--fs-1);letter-spacing:.09em;text-transform:uppercase;
  color:var(--faint);font-weight:600;margin:14px 0 6px}
#wy-bt-panel:not(:empty){background:var(--panel);border:1px solid var(--line);
  border-radius:var(--r-4);padding:2px 14px 14px;margin-top:12px;box-shadow:var(--edge),var(--sh-1)}
#wy-bt-panel .wy-bt-head{margin-top:12px;padding-top:0;border-top:none}
/* labeled field grid: small-caps label above each control — a settings form
   that reads as tidy columns instead of a run of inline boxes */
.wy-fgrid{display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));gap:10px;margin-bottom:8px}
.wy-f{display:flex;flex-direction:column;gap:4px;min-width:0}
.wy-f>span{font-size:var(--fs-1);letter-spacing:.07em;text-transform:uppercase;
  color:var(--faint);font-weight:600}
.wy-f select,.wy-f input{width:100%;min-width:0}
.wy-f-static{color:var(--dim);font-size:var(--fs-4);padding:6px 0}
/* config/filter editors: view/edit mode */
.wy-edit input:disabled,.wy-edit select:disabled{color:var(--dim);background:var(--inset-bg);
  border-color:var(--line);opacity:1;cursor:default}
.wy-actions .mprimary{width:auto;padding:8px 18px}
.wy-actions .wy-right{margin-left:auto}
.wy-actions .wy-danger{color:var(--down);border-color:var(--down)}
.wy-actions .wy-danger:hover{background:var(--down-bg)}
/* Long-term Trends: two real SITE-filter categories, then the selected list. */
.wy-trend-cats{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px;
  margin:12px 0}
.wy-trend-cat{display:flex;align-items:center;gap:10px;text-align:left;padding:10px 14px;
  background:var(--panel);border:1px solid var(--line);box-shadow:var(--edge),var(--sh-1)}
.wy-trend-cat .ico{width:24px;height:24px;flex:none;margin:0;stroke-width:2}
.wy-trend-cat span{display:block;min-width:0}
.wy-trend-cat b{display:block;color:var(--ink);font-size:var(--fs-4)}
.wy-trend-cat small{display:block;color:var(--faint);font-size:var(--fs-2);margin-top:1px}
.wy-trend-cat.is-up .ico{color:var(--up)}
.wy-trend-cat.is-down .ico{color:var(--down);transform:scaleY(-1)}
.wy-trend-cat.is-up.on{border-color:var(--up);background:var(--up-bg)}
.wy-trend-cat.is-down.on{border-color:var(--down);background:var(--down-bg)}
.wy-trend-cat:not(.on):hover{background:var(--hover-bg)}
@media(max-width:640px){
  .wy-trend-cats{gap:6px;margin:8px 0}
  .wy-trend-cat{gap:7px;padding:8px}
  .wy-trend-cat .ico{width:20px;height:20px}
  .wy-trend-cat b{font-size:var(--fs-3);line-height:1.25}
}

.wy-lp-sum{display:flex;gap:8px;flex-wrap:wrap;margin:12px 0}
.wy-lp-note{color:var(--faint);font-size:var(--fs-2);margin:10px 0 4px}
.wy-lp-t th:nth-child(2),.wy-lp-t td:nth-child(2){text-align:left;width:auto}
.wy-lp-t th:first-child,.wy-lp-t td:first-child{width:44px}
.wy-lp-t th:not(:first-child):not(:nth-child(2)):not(.spk),.wy-lp-t td:not(:first-child):not(:nth-child(2)):not(.spk){width:96px}
/* the sparkline column: 128px well from .board td.spk, flexible past 1180px (below) */
/* Long-term Trends fills the column like everything above it; past 1180px the
   sparkline column takes the row's slack (name stays min-content), so the
   width reads as a 30-day band per row rather than an empty name cell. */
@media(min-width:1181px){
  /* Fixed layout, known shares (clamp() is not honoured on table columns, so
     plain percentages per tier): rank 44px, the band 14% (the SVG caps itself
     at 320px), wells 6.5% with eight of them (tier 1) and 5.5% with twelve
     (tier 2) — both sum well under 100% — and the item name takes the rest
     and ellipsises. */
  .wy-lp-t{table-layout:fixed;width:100%}
  .wy-lp-t th.l,.wy-lp-t td.l{white-space:nowrap}
  .wy-lp-t .mi{min-width:0}
  .wy-lp-t .mi span{display:block;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .wy-lp-t th:first-child,.wy-lp-t td:first-child{width:44px}
  .wy-lp-t th:not(:first-child):not(.l):not(.spk),.wy-lp-t td:not(:first-child):not(.l):not(.spk){width:6.5%}
  .wy-lp-t th.spk,.wy-lp-t td.spk{width:14%}
}
@media(min-width:1990px){
  .wy-lp-t th:not(:first-child):not(.l):not(.spk),.wy-lp-t td:not(:first-child):not(.l):not(.spk){width:5.5%}
}
/* Trends' wide-only extras come in two tiers as the table gets room (base
   table with the band ≈ 891px; each extra is a 96px well; column = window −
   44 below the rails):
     tier 1 — 7d, 30-day low, 30-day high        (≥1179px table; with the rails
              on from 1560 that is a ≥1590px window — and it must stay off
              below that too, or it would flip when the rails arrive)
     tier 2 — daily volume, buy limit, 24h turnover, 1y range (≥1563px table
              → ≥1990px window)
   The band itself is capped at 320px; the rest is shared spacing. */
@media(min-width:1590px){.wy-lp-t .w-only{display:table-cell}}
@media(min-width:1990px){.wy-lp-t .w-only2{display:table-cell}}
.wy-lp-t tbody tr{cursor:pointer}
/* click-to-sort headers: pointer + gold active column with a direction arrow */
.wy-lp-t thead th{cursor:pointer;user-select:none}
.wy-lp-t thead th:hover{color:var(--ink)}
.wy-lp-t thead th.s-on{color:var(--gold)}
.wy-lp-t thead th.s-asc::after{content:" ▲";font-size:var(--fs-1)}
.wy-lp-t thead th.s-desc::after{content:" ▼";font-size:var(--fs-1)}
.dim{color:var(--dim)}

/* ---------- Wyrm Picks board + admin panel + backtest reports ---------- */
.wy-admin{background:var(--panel);border:1px solid var(--gold);border-radius:var(--r-3);
  padding:12px 14px;margin:14px 0}
.wy-admin .wy-bt-head{margin-top:0;padding-top:0;border-top:none;margin-bottom:10px}
.wy-tr-t tbody tr,.wy-cl-t tbody tr{cursor:pointer}
.wy-tr-t thead th,.wy-cl-t thead th{cursor:pointer;user-select:none}
.wy-tr-t thead th.s-on,.wy-cl-t thead th.s-on{color:var(--gold)}
.wy-tr-t thead th.s-asc::after,.wy-cl-t thead th.s-asc::after{content:" ▲";font-size:var(--fs-1)}
.wy-tr-t thead th.s-desc::after,.wy-cl-t thead th.s-desc::after{content:" ▼";font-size:var(--fs-1)}
.wy-bt-date{margin:12px 0 4px;color:var(--dim);font-size:var(--fs-2)}
.wy-rep-list{display:flex;flex-direction:column;gap:6px;margin-bottom:10px}
.wy-rep-list .wy-item{border-left-width:1px}
.wy-rep-rm{flex-shrink:0;color:var(--faint)}
.wy-rep-rm:hover{color:var(--down);border-color:var(--down)}
.wy-rep-cfg{margin:10px 0}
.wy-rep-cfg pre{max-height:320px;overflow:auto;background:var(--inset-bg);
  border:1px solid var(--line);border-radius:var(--r-2);padding:10px;font-size:var(--fs-2)}

/* ---------- Admin page + backtest progress ---------- */
.wy-chip{display:inline-block;font-size:var(--fs-1);padding:1px 6px;border:1px solid var(--line);
  border-radius:var(--r-pill);color:var(--faint);vertical-align:middle;margin-left:6px}
.wy-help{display:block;font-size:var(--fs-2);color:var(--faint);font-style:normal;margin-top:2px}
.wy-sl-vis{font-size:var(--fs-3);background:var(--inset-bg);color:var(--ink);
  border:1px solid var(--line);border-radius:var(--r-2);padding:4px 6px;flex-shrink:0}
.wy-brain-ed .wy-fgrid{grid-template-columns:repeat(auto-fit,minmax(210px,1fr))}
.wy-adminpage .wy-admin{margin:14px 0}
/* ---------- Admin: Stats | Settings toggle + the Stats area ---------- */
.wy-seg{display:flex;gap:8px;margin:14px 0 4px}
.wy-seg button{background:transparent;border:1px solid var(--line);border-radius:var(--r-pill);
  padding:6px 22px;color:var(--dim);font-size:var(--fs-3)}
.wy-seg button.on{border-color:var(--line-strong);color:var(--emph);background:var(--seg-on)}
.wy-stat-tiles{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));
  gap:10px;margin:10px 0}
.wy-stat-tiles>div{background:var(--inset-bg);border:1px solid var(--line);
  border-radius:var(--r-2);padding:10px 12px;display:flex;flex-direction:column;gap:2px}
.wy-stat-tiles b{font-size:var(--fs-6);color:var(--emph)}
.wy-stat-tiles span{color:var(--faint);font-size:var(--fs-2)}
.wy-chart{width:100%;height:auto;margin-top:6px}
.wy-chart .ax{stroke:var(--line);stroke-width:1}
.wy-chart .s1{fill:none;stroke:var(--accent);stroke-width:2}
.wy-chart .s2{fill:none;stroke:var(--dim);stroke-width:1.5;stroke-dasharray:4 3}
.wy-chart .lb{fill:var(--faint);font-size:var(--fs-1)}
.wy-chart .lb.e{text-anchor:end}
.wy-chart .k1{fill:var(--accent)} .wy-chart .k2{fill:var(--dim)}
.wy-stat-cols{display:grid;grid-template-columns:1fr 1fr;gap:16px}
@media(max-width:700px){.wy-stat-cols{grid-template-columns:1fr}}
.wy-sub{display:block;margin:8px 0 4px;color:var(--emph);font-size:var(--fs-3)}
.wy-stat-tbl{width:100%;border-collapse:collapse}
.wy-stat-tbl td,.wy-stat-tbl th{padding:5px 8px;border-bottom:1px solid var(--line);
  font-size:var(--fs-3)}
.wy-stat-tbl th{color:var(--faint);text-align:right;font-weight:400}
.wy-stat-tbl th.l,.wy-stat-tbl td.l{text-align:left}
.wy-stat-tbl td.n{text-align:right;font-variant-numeric:tabular-nums;color:var(--emph)}
.wy-stat-tbl tr[data-h]{cursor:pointer}
.wy-rngs{float:right;display:flex;gap:6px}
.wy-rng{background:transparent;border:1px solid var(--line);border-radius:var(--r-pill);
  padding:2px 12px;color:var(--dim);font-size:var(--fs-2)}
.wy-rng.on{border-color:var(--line-strong);color:var(--emph);background:var(--seg-on)}
.wy-inp{background:var(--inset-bg);border:1px solid var(--line);border-radius:var(--r-2);
  color:var(--emph);padding:7px 10px;min-width:260px;margin:6px 8px 0 0}
.wy-ta{display:block;width:100%;max-width:720px;font-family:inherit;font-size:var(--fs-3)}
.wy-btn{border:1px solid var(--line-strong);border-radius:var(--r-2);
  background:var(--seg-on);color:var(--emph);padding:7px 14px}
.wy-bt-prog{margin:14px 0}
.wy-bar{height:6px;border-radius:var(--r-pill);background:var(--inset-bg);overflow:hidden;
  border:1px solid var(--line);margin-bottom:8px}
.wy-bar i{display:block;height:100%;width:38%;border-radius:var(--r-pill);background:var(--accent);
  animation:wybar 1.1s ease-in-out infinite alternate;will-change:transform}
@keyframes wybar{from{transform:translateX(-26%)}to{transform:translateX(190%)}}
/* the global 1ms clamp would turn this into a strobe; a still, half-lit bar says "busy" instead */
@media(prefers-reduced-motion:reduce){.wy-bar i{animation:none;width:100%;opacity:.45}}

/* ---------- Ads: template spacers + rail docking ---------- */
.ad-tpl{display:flex;align-items:center;justify-content:center;margin:0 auto;
  border:1px dashed var(--line);border-radius:var(--r-2);background:var(--inset-bg);
  color:var(--faint);font-size:var(--fs-2);letter-spacing:.08em;text-transform:uppercase}
.wy-ads-cb input[type=checkbox]{width:18px;height:18px;accent-color:var(--accent)}
.t-list>.t-ad-desktop{margin-top:auto;flex-shrink:0;padding:10px 6px;
  border-top:1px solid var(--line)}
.t-list>.t-ad-desktop iframe{max-width:100%}
@media(max-width:900px){.term>.t-ad-mobile{border-top:1px solid var(--line);padding-top:12px}}

/* ---------- Wyrm's read: single-line rows, ladder legibility ---------- */
#wyrm-read .wr-row span{white-space:nowrap}
#wyrm-read .wr-row b{white-space:nowrap;text-align:right;overflow:hidden;text-overflow:ellipsis}
#wyrm-read .wr-px b{color:var(--gold)}
#wyrm-read .wr-px{border-top:1px dashed var(--line);border-bottom:1px dashed var(--line);margin:2px 0}
.wr-sub{color:var(--faint);font-weight:400;font-size:var(--fs-2);margin-left:5px}
.wr-tf{float:right;color:var(--faint);font-weight:400;font-size:var(--fs-2);letter-spacing:.05em}

/* ---------- OSRS Paper Trading -----------------------------------------
   A compact three-column trading terminal. The account ledger remains
   server-authoritative; the chart reuses the item-page transport cache. */
:root[data-page="paper-trading"]{scrollbar-gutter:auto}
:root[data-page="paper-trading"] #main{max-width:none;padding:10px 20px 18px}
:root[data-page="paper-trading"] #page-head,
:root[data-page="paper-trading"] #main>.ad-slot,
:root[data-page="paper-trading"] #ad-footer-slot,
:root[data-page="paper-trading"] body>.mw-brand-footer{display:none!important}
:root[data-page="paper-trading"] #results{overflow:visible;background:transparent}
.pt-host{min-width:0;width:100%}
.pt-page{width:100%;max-width:none;margin:0;padding:0 0 28px}
.pt-head{display:flex;align-items:center;justify-content:space-between;gap:18px;
  margin-bottom:9px;padding:4px 2px 8px;border-bottom:0;background:none!important}
.pt-head-copy{min-width:0}.pt-titleline{display:flex;align-items:center;gap:10px;min-width:0}
.pt-head h2{margin:0;color:var(--emph);font-family:"Cinzel",serif;font-size:clamp(20px,1.7vw,27px);
  font-weight:650;letter-spacing:.01em;white-space:nowrap}
.pt-head p{margin:2px 0 0;color:var(--dim);font-size:var(--fs-2)}
.pt-sim,.pt-generation{display:inline-flex;align-items:center;min-height:25px;padding:3px 9px;
  border:1px solid color-mix(in srgb,var(--gold) 52%,var(--line));border-radius:var(--r-2);
  color:var(--gold);background:color-mix(in srgb,var(--gold) 10%,var(--inset-bg));
  font:700 var(--fs-1)/1 var(--mono);letter-spacing:.05em;text-transform:uppercase}
.pt-generation{border-width:0 0 0 1px;border-radius:0;color:var(--faint);background:none;font-weight:500}
.pt-live{display:inline-flex;align-items:center;gap:7px;color:var(--up);font-size:var(--fs-2);white-space:nowrap}
.pt-live i{width:8px;height:8px;border-radius:50%;background:var(--up);box-shadow:0 0 0 4px var(--up-bg)}
.pt-account-menu{flex:0 0 auto;padding:6px 10px;color:var(--dim);font-size:var(--fs-2)}
.pt-loading{min-height:260px;display:grid;place-items:center;color:var(--dim)}
.pt-panel,.pt-cards{min-width:0;border:1px solid var(--line);border-radius:var(--r-3);
  background:var(--panel);box-shadow:var(--edge),var(--sh-1);overflow:hidden}
.pt-cards{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));margin-bottom:9px}
.pt-metric{display:flex;align-items:center;gap:12px;min-width:0;min-height:74px;padding:9px 14px;
  border-right:1px solid var(--line);background:linear-gradient(180deg,var(--surface-top),var(--surface-bottom))}
.pt-metric:last-child{border-right:0}.pt-metric-icon{display:grid!important;place-items:center;flex:0 0 36px;
  width:36px;height:36px;border:1px solid color-mix(in srgb,var(--gold) 35%,var(--line));border-radius:10px;
  color:var(--gold)!important;background:color-mix(in srgb,var(--gold) 9%,var(--inset-bg));
  font:800 17px/1 var(--mono)!important}
.pt-metric-copy{min-width:0}.pt-cards .pt-metric-copy>span,.pt-cards small{display:block;color:var(--faint);font-size:var(--fs-1)}
.pt-cards b{display:block;overflow:hidden;text-overflow:ellipsis;margin:2px 0;color:var(--emph);
  font:650 clamp(16px,1.35vw,22px)/1.18 var(--mono);font-variant-numeric:tabular-nums;white-space:nowrap}
.pt-cards b .num{font:inherit}.pt-metric.is-up b{color:var(--up)}.pt-metric.is-down b{color:var(--down)}
.pt-workspace{display:grid;grid-template-columns:minmax(270px,.78fr) minmax(430px,2.1fr) minmax(290px,.92fr);
  gap:9px;align-items:stretch;margin-bottom:9px}
.pt-panel-head{display:flex;align-items:center;justify-content:space-between;gap:12px;min-height:45px;
  padding:8px 12px;border-bottom:1px solid var(--line);background:linear-gradient(180deg,var(--surface-top),var(--panel2))}
.pt-panel-head b{display:block;color:var(--emph);font-size:var(--fs-4)}
.pt-panel-head span{display:block;color:var(--faint);font-size:var(--fs-1)}
.pt-watch,.pt-market,.pt-ticket{height:530px}
.pt-watch{display:flex;flex-direction:column}.pt-watch-search{display:block;padding:9px 10px;border-bottom:1px solid var(--row-line)}
.pt-watch-search input{width:100%;height:34px;padding:6px 10px;background:var(--input-bg)}
.pt-watch-cols{display:grid;grid-template-columns:minmax(0,1fr) 72px 58px;gap:7px;padding:6px 9px;
  color:var(--faint);background:var(--inset-bg);font:500 var(--fs-1)/1 var(--mono);letter-spacing:.04em;text-transform:uppercase}
.pt-watch-cols span:not(:first-child){text-align:right}.pt-watch-list{min-height:0;flex:1;overflow:auto}
.pt-watch-row{display:grid;grid-template-columns:minmax(0,1fr) 72px 58px;align-items:center;gap:7px;width:100%;
  min-height:54px;padding:6px 9px;border:0;border-bottom:1px solid var(--row-line);border-radius:0;
  color:var(--ink);background:transparent;box-shadow:none;text-align:left}
.pt-watch-row:hover{background:var(--row-hover)}.pt-watch-row.on{background:color-mix(in srgb,var(--theme-accent) 11%,var(--panel2));box-shadow:inset 2px 0 0 var(--theme-accent)}
.pt-watch-row>.num{text-align:right;font-size:var(--fs-2);white-space:nowrap}
.pt-watch-row .mi,.pt-order-row .mi,.pt-table .mi{display:flex;align-items:center;gap:8px;min-width:0;text-align:left}
.pt-watch-row .mi>span,.pt-order-row .mi>span,.pt-table .mi>span{min-width:0}
.pt-watch-row .mi b,.pt-watch-row .mi small,.pt-order-row .mi b,.pt-order-row .mi small,.pt-table .mi b,.pt-table .mi small{display:block}
.pt-watch-row .mi b,.pt-order-row .mi b,.pt-table .mi b{overflow:hidden;text-overflow:ellipsis;color:var(--ink);white-space:nowrap;font-size:var(--fs-2)}
.pt-watch-row .mi small,.pt-order-row .mi small,.pt-table .mi small{color:var(--faint);font-size:10px}
.pt-watch-row img,.pt-ticket-instrument img,.pt-table .mi img,.pt-order-row .mi img{width:31px;height:31px;object-fit:contain;image-rendering:auto;flex:0 0 auto}
.pt-market{display:flex;min-width:0;flex-direction:column}.pt-market-head{display:flex;align-items:center;justify-content:space-between;
  gap:18px;min-height:87px;padding:10px 13px;border-bottom:1px solid var(--line);background:linear-gradient(180deg,var(--surface-top),var(--panel))}
.pt-instrument{display:flex;align-items:center;gap:10px;min-width:0}.pt-instrument-icon{display:grid;place-items:center;flex:0 0 52px;width:52px;height:52px;
  border:1px solid var(--line);border-radius:var(--r-3);background:var(--inset-bg)}
.pt-instrument img{width:44px;height:44px;object-fit:contain}.pt-instrument b,.pt-instrument small{display:block}.pt-instrument b{overflow:hidden;text-overflow:ellipsis;
  color:var(--emph);font-size:var(--fs-5);white-space:nowrap}.pt-instrument small{color:var(--faint);font-size:var(--fs-1)}
.pt-market-stats{display:grid;grid-template-columns:repeat(4,minmax(74px,1fr));gap:0;min-width:min(55%,520px)}
.pt-market-stats>div{min-width:0;padding:2px 10px;border-left:1px solid var(--row-line);text-align:right}
.pt-market-stats span,.pt-market-stats b{display:block}.pt-market-stats span{color:var(--faint);font-size:var(--fs-1)}
.pt-market-stats b{margin-top:3px;color:var(--emph);font:650 var(--fs-4)/1.1 var(--mono);white-space:nowrap}
.pt-market-stats .pt-spread b{display:flex;justify-content:flex-end;gap:7px}.pt-market-stats .pt-spread i{font-style:normal}
.pt-chart-tools{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:7px 9px;border-bottom:1px solid var(--row-line);background:var(--inset-bg)}
.pt-chart-ranges,.pt-chart-modes{display:flex;gap:4px}.pt-chart-tools button{min-width:39px;padding:5px 8px;color:var(--dim);background:transparent;border-color:var(--line);font-size:var(--fs-1)}
.pt-chart-tools button.on{color:var(--on-gold);border-color:var(--gold);background:var(--gold);box-shadow:0 0 12px -6px var(--gold)}
.pt-chart-modes button{min-width:auto}.pt-chart-stage{position:relative;min-height:0;flex:1;background:color-mix(in srgb,var(--inset-bg) 86%,transparent)}
.pt-chart-stage canvas{display:block;width:100%;height:100%;min-height:330px}.pt-chart-status{position:absolute;inset:0;display:none;place-items:center;color:var(--faint);font-size:var(--fs-2)}
.pt-chart-stage.is-loading .pt-chart-status,.pt-chart-status:not(:empty){display:grid}.pt-chart-stage.is-loading canvas{opacity:.35}
.pt-chart-foot{display:flex;align-items:center;gap:15px;min-height:27px;padding:5px 11px;border-top:1px solid var(--row-line);
  color:var(--faint);font-size:10px}.pt-chart-foot>span{display:inline-flex;align-items:center;gap:5px}.pt-chart-foot>span:last-child{margin-left:auto}
.pt-chart-foot i{display:inline-block;width:13px;height:2px;background:var(--gold)}.pt-chart-foot .pt-key-volume{height:7px;background:var(--theme-accent);opacity:.45}
.pt-market-empty{color:var(--faint)}
.pt-ticket{position:relative;overflow:auto}.pt-ticket form{padding:9px 11px 10px}.pt-side{display:grid;grid-template-columns:1fr 1fr;gap:4px;padding:3px;margin-bottom:8px;
  border:1px solid var(--line);border-radius:var(--r-2);background:var(--inset-bg)}
.pt-side button{padding:6px;background:transparent;border-color:transparent;color:var(--dim);box-shadow:none;text-transform:uppercase;font-weight:700}
.pt-side button.on{color:#03120a;border-color:var(--up);background:var(--up)}.pt-side button[data-side="sell"].on{color:#170304;border-color:var(--down);background:var(--down)}
.pt-ticket-instrument{display:flex;align-items:center;gap:9px;min-height:48px;margin-bottom:8px;padding:6px 8px;border:1px solid var(--line);
  border-radius:var(--r-2);background:var(--inset-bg)}.pt-ticket-instrument span{min-width:0}.pt-ticket-instrument b,.pt-ticket-instrument small{display:block}
.pt-ticket-instrument b{overflow:hidden;text-overflow:ellipsis;color:var(--emph);font-size:var(--fs-3);white-space:nowrap}.pt-ticket-instrument small,.pt-muted{color:var(--faint);font-size:var(--fs-1)}
.pt-field{position:relative;display:block;margin-bottom:7px}.pt-field>span{display:flex;justify-content:space-between;margin:0 0 3px;color:var(--dim);font-size:var(--fs-1)}
.pt-field em{color:var(--faint);font-style:normal}.pt-field input,.pt-field select{display:block;width:100%;min-width:0;height:34px;background:var(--input-bg)}
.pt-grid2{display:grid;grid-template-columns:1fr 1fr;gap:7px}.pt-estimate{margin:2px 0 8px;padding:7px 9px;border:1px solid var(--line);border-radius:var(--r-2);background:var(--inset-bg)}
.pt-estimate>div{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:2px 0;color:var(--dim);font-size:var(--fs-1)}
.pt-estimate b{color:var(--emph);font:600 var(--fs-3)/1.2 var(--mono)}.pt-estimate small{display:block;margin-top:4px;color:var(--faint);font-size:10px;line-height:1.3}
.pt-submit{width:100%;border-color:var(--up);background:linear-gradient(180deg,color-mix(in srgb,var(--up) 86%,#fff),var(--up));color:#03120a;font-weight:800;box-shadow:0 5px 16px -8px var(--up)}
.pt-submit.is-sell{border-color:var(--down);background:linear-gradient(180deg,color-mix(in srgb,var(--down) 84%,#fff),var(--down));color:#170304;box-shadow:0 5px 16px -8px var(--down)}
.pt-submit:hover{filter:brightness(1.08)}.pt-note{min-height:15px;margin-top:5px;color:var(--down);font-size:var(--fs-1)}
.pt-ledger{min-height:132px}.pt-ledger-tabs{display:flex;align-items:center;min-height:43px;padding:0 8px;border-bottom:1px solid var(--line);background:linear-gradient(180deg,var(--surface-top),var(--panel2))}
.pt-ledger-tabs button{align-self:stretch;min-width:142px;padding:7px 14px;border:0;border-bottom:2px solid transparent;border-radius:0;color:var(--dim);background:transparent;box-shadow:none;text-align:left}
.pt-ledger-tabs button.on{color:var(--emph);border-bottom-color:var(--gold);background:color-mix(in srgb,var(--gold) 7%,transparent)}
.pt-ledger-tabs button i{display:inline-grid;place-items:center;min-width:21px;height:21px;margin-left:6px;border:1px solid var(--line);border-radius:var(--r-2);color:var(--faint);font:normal var(--fs-1)/1 var(--mono)}
.pt-ledger-tabs>span{margin-left:auto;padding-right:8px;color:var(--faint);font-size:var(--fs-1)}
.pt-table-wrap{width:100%;overflow:auto}.pt-table{width:100%;border-collapse:collapse;white-space:nowrap;font-size:var(--fs-2)}
.pt-table th{padding:7px 10px;color:var(--faint);background:var(--inset-bg);font-size:10px;font-weight:500;letter-spacing:.05em;text-align:right;text-transform:uppercase}
.pt-table td{padding:7px 10px;border-top:1px solid var(--row-line);text-align:right;font-family:var(--mono);font-variant-numeric:tabular-nums}
.pt-table th.l,.pt-table td.l{text-align:left}.pt-table tbody tr:hover{background:var(--row-hover)}
.pt-badge{display:inline-block;min-width:40px;padding:2px 5px;border-radius:var(--r-1);text-align:center;font:600 var(--fs-1)/1.4 var(--mono)}
.pt-badge.buy{color:var(--up);background:var(--up-bg)}.pt-badge.sell{color:var(--down);background:var(--down-bg)}
.pt-order-list{max-height:300px;overflow:auto}.pt-order-row{display:grid;grid-template-columns:minmax(0,1fr) auto auto;align-items:center;gap:10px;padding:8px 12px;border-bottom:1px solid var(--row-line);font-size:var(--fs-2)}
.pt-order-row:last-child{border-bottom:0}.pt-order-row>span{color:var(--faint);white-space:nowrap}.pt-order-row button,.pt-table button{padding:5px 9px;font-size:var(--fs-1)}
.pt-empty{min-height:86px;display:grid;place-items:center;padding:18px;color:var(--faint);text-align:center;font-size:var(--fs-2)}
.pt-modal{position:fixed;z-index:90;inset:0;display:grid;place-items:center;padding:18px;background:var(--backdrop);backdrop-filter:blur(5px)}
.pt-modal>div{width:min(480px,100%);padding:19px;border:1px solid var(--line-strong);border-radius:var(--r-4);background:var(--panel);box-shadow:var(--sh-3)}
.pt-modal h3{margin:0 0 7px;color:var(--emph);font-size:var(--fs-6)}.pt-modal p{margin:0 0 15px;color:var(--dim);font-size:var(--fs-3)}
.pt-modal-actions{display:flex;justify-content:flex-end;gap:8px;margin-top:13px}.pt-reset-go{border-color:var(--down);background:var(--down);color:#fff;font-weight:700}

@media(max-width:1260px){
  .pt-page{padding-inline:8px}.pt-workspace{grid-template-columns:260px minmax(400px,1fr) 285px}
  .pt-market-stats{grid-template-columns:1fr 1fr;min-width:245px;row-gap:9px}.pt-market-stats>div:nth-child(odd){border-left:0}
  .pt-watch,.pt-market,.pt-ticket{height:520px}.pt-chart-stage canvas{min-height:315px}
}
@media(max-width:980px){
  .pt-cards{grid-template-columns:repeat(3,minmax(0,1fr))}.pt-metric:nth-child(3){border-right:0}.pt-metric:nth-child(n+4){border-top:1px solid var(--line)}
  .pt-workspace{grid-template-columns:minmax(210px,.75fr) minmax(430px,1.7fr)}.pt-ticket{grid-column:1/-1;height:auto;max-height:none}.pt-ticket form{display:grid;grid-template-columns:220px 1fr 1fr;gap:8px 10px}.pt-ticket .pt-side,.pt-ticket-instrument{grid-column:1}.pt-ticket .pt-grid2,.pt-ticket #pt-limit-row,.pt-ticket #pt-protect{grid-column:2}.pt-ticket .pt-estimate,.pt-ticket .pt-submit,.pt-ticket .pt-note{grid-column:3}.pt-ticket .pt-submit{align-self:end}
}
@media(max-width:720px){
  :root[data-page="paper-trading"] #main{padding:8px 6px 0}.pt-page{padding:0 0 90px}.pt-head{align-items:flex-start}.pt-titleline{flex-wrap:wrap}.pt-head h2{width:100%;white-space:normal}.pt-generation{border-left:0;padding-left:0}.pt-head p{max-width:520px}.pt-account-menu{margin-top:2px}
  .pt-cards{grid-template-columns:1fr 1fr}.pt-metric{border-right:1px solid var(--line)!important;border-top:1px solid var(--line)}.pt-metric:nth-child(-n+2){border-top:0}.pt-metric:nth-child(even){border-right:0!important}.pt-metric:last-child{grid-column:1/-1;border-right:0!important}
  .pt-workspace{display:flex;flex-direction:column}.pt-watch{height:330px}.pt-market{height:500px}.pt-ticket{height:auto}.pt-market-head{align-items:flex-start;flex-direction:column;gap:8px}.pt-market-stats{width:100%;min-width:0}.pt-ticket form{display:block}.pt-ledger-tabs{overflow-x:auto}.pt-ledger-tabs button{min-width:126px}.pt-ledger-tabs>span{display:none}
}
@media(max-width:450px){
  .pt-head p,.pt-generation{display:none}.pt-account-menu{font-size:0}.pt-account-menu::after{content:"Reset";font-size:var(--fs-1)}
  .pt-cards{grid-template-columns:1fr}.pt-metric,.pt-metric:nth-child(-n+2){min-height:64px;border-top:1px solid var(--line);border-right:0!important}.pt-metric:first-child{border-top:0}.pt-metric:last-child{grid-column:auto}.pt-metric-icon{width:31px;height:31px;flex-basis:31px}
  .pt-market{height:480px}.pt-market-stats{grid-template-columns:1fr 1fr}.pt-chart-modes{display:none}.pt-chart-stage canvas{min-height:270px}.pt-grid2{grid-template-columns:1fr}.pt-order-row{grid-template-columns:minmax(0,1fr) auto}.pt-order-row>span{display:none}
}

/* ===== MarketWyrm homepage =====
   A compact exchange terminal rather than a generic landing page. The hero,
   live strip, market panels, game doors and tools follow one dense vertical
   rhythm so a desktop visitor sees the whole product story immediately. */
:root[data-page="home"] body{background:#070704;background-image:
  radial-gradient(900px 480px at 73% 120px,rgba(179,116,22,.065),transparent 66%),
  linear-gradient(180deg,#090805,#050503 70%,#080704)}
:root[data-page="home"] .hdr{min-height:58px;padding-top:calc(4px + env(safe-area-inset-top));padding-bottom:4px;
  background:#0b0a07;box-shadow:0 5px 20px rgba(0,0,0,.45)}
:root[data-page="home"] .brand-logo{height:50px}
:root[data-page="home"] .subbar{padding:5px max(18px,calc((100% - 1460px)/2));background:#090806}
:root[data-page="home"] .subbar .tools{display:none}
:root[data-page="home"] .tabs{padding:2px;background:#100e09}
:root[data-page="home"] .tabs :is(button,a){padding:6px 12px;font-size:12px}
:root[data-page="home"] #main{display:block;max-width:none;padding:0 16px 10px}
:root[data-page="home"] #main>.ad-slot,:root[data-page="home"] #page-head{display:none!important}
:root[data-page="home"] #results{overflow:visible;background:transparent}

.home-landing{--home-gold:#dfa33b;--home-bright:#f5ca70;--home-line:rgba(186,132,49,.31);
  --home-panel:#0d0c08;--home-quiet:#9f8f70;max-width:1460px;margin:0 auto;color:#e8ddc7}
.home-hero{position:relative;isolation:isolate;min-height:310px;overflow:hidden;border-inline:1px solid var(--home-line);
  border-bottom:1px solid rgba(191,137,48,.28);background:#050503;box-shadow:0 20px 60px -42px #000}
.home-hero::after{content:"";position:absolute;z-index:2;inset:auto 0 0;height:1px;
  background:linear-gradient(90deg,transparent,rgba(235,184,84,.46),transparent)}
.home-hero-art{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:center}
.home-hero-shade{position:absolute;z-index:1;inset:0;background:
  linear-gradient(90deg,#050503 0%,rgba(5,5,3,.96) 22%,rgba(5,5,3,.7) 43%,rgba(5,5,3,.1) 69%),
  linear-gradient(180deg,rgba(3,3,2,.02) 55%,rgba(3,3,2,.55) 100%)}
.home-hero-copy{position:relative;z-index:3;display:flex;min-height:310px;width:54%;max-width:720px;
  flex-direction:column;justify-content:center;padding:28px clamp(26px,4.8vw,66px) 30px}
.home-kicker{color:#d4a24e;font-size:10px;font-weight:800;letter-spacing:.25em;text-transform:uppercase}
.home-hero h1{max-width:650px;margin:9px 0 8px;color:#f8e7bd;font-family:"Cinzel",Georgia,serif;
  font-size:clamp(34px,3.6vw,53px);font-weight:600;letter-spacing:-.035em;line-height:.98;
  text-shadow:0 2px 24px #000;text-wrap:balance}
.home-lede{max-width:560px;margin:0;color:#b7aa91;font-size:13px;line-height:1.5;text-shadow:0 1px 10px #000}
.home-search{display:flex;width:min(560px,100%);margin-top:13px;border:1px solid rgba(202,148,57,.34);
  border-radius:5px;background:rgba(5,5,3,.88);box-shadow:inset 0 1px 0 rgba(255,255,255,.025),0 9px 30px -18px #000}
.home-search input{min-width:0;flex:1;border:0;background:transparent;padding:9px 13px;font-size:12px;box-shadow:none}
.home-search input:focus{outline:0}
.home-search:focus-within{border-color:#d8a246;box-shadow:0 0 0 1px rgba(216,162,70,.18)}
.home-search button{flex:none;margin:3px;padding:6px 20px;border-color:#f0b95d;border-radius:3px;
  background:linear-gradient(180deg,#e5ad4d,#bd7923);color:#1b1105;font-size:11px;font-weight:800;box-shadow:inset 0 1px 0 rgba(255,255,255,.34)}
.home-search-note{margin-top:5px;color:#7f735e;font-size:9.5px;letter-spacing:.02em}.home-search-note b{color:#b99a61}

.home-livebar{display:grid;grid-template-columns:.55fr .95fr .95fr 1.1fr 1.1fr;min-height:40px;border:1px solid var(--home-line);
  border-top:0;background:#0c0b07;color:#93846a;font-size:10px;text-transform:uppercase;letter-spacing:.04em}
.home-livebar>span{display:flex;align-items:center;justify-content:center;gap:7px;padding:7px 13px;border-right:1px solid rgba(163,116,43,.2);white-space:nowrap}
.home-livebar>span:last-child{border-right:0}.home-livebar b{color:#d3aa62;font:700 12px var(--mono);letter-spacing:0}
.home-livebar .home-live{justify-content:flex-start;color:#e4b862;font-weight:800}.home-live i{width:7px;height:7px;border-radius:50%;background:#55c879;box-shadow:0 0 8px rgba(85,200,121,.65)}
.home-freshness b{color:#bda06c}

.home-market-grid{display:grid;grid-template-columns:1.05fr .95fr;gap:12px;margin-top:12px}
.home-panel{min-width:0;overflow:hidden;border:1px solid var(--home-line);border-radius:5px;background:var(--home-panel);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.025),0 14px 28px -24px #000}
.home-panel>header{display:flex;min-height:43px;align-items:center;justify-content:space-between;padding:7px 12px;border-bottom:1px solid rgba(164,114,39,.25);background:linear-gradient(180deg,#121008,#0d0c08)}
.home-panel h2{display:flex;align-items:center;gap:7px;margin:0;color:#d8bd84;font-family:"Cinzel",Georgia,serif;font-size:15px;font-weight:600}
.home-panel h2 img{width:24px;height:24px;object-fit:contain}.home-panel h2 .ico{color:#d7a243}
.home-panel header a{color:#9f8961;font-size:9.5px;text-decoration:none}.home-panel header a:hover{color:#e4bd71}
.home-panel header>span{display:flex;gap:4px}.home-panel header>span a{padding:3px 7px;border:1px solid rgba(177,124,42,.25);border-radius:3px}
.home-pulse-chart{height:135px;padding:9px 11px 0;background:
  radial-gradient(420px 120px at 60% 100%,rgba(202,142,46,.08),transparent 70%)}
.home-pulse-chart svg{display:block;width:100%;height:100%}.home-chart-grid{fill:none;stroke:rgba(159,125,68,.13);stroke-width:1}
.home-chart-area{fill:url(#home-area)}.home-chart-line{fill:none;stroke:#dca541;stroke-width:2;filter:drop-shadow(0 0 4px rgba(220,165,65,.28))}
.home-chart-candles{fill:rgba(225,170,67,.64);stroke:#e1aa43;stroke-width:1}
.home-pulse-stats{display:grid;grid-template-columns:repeat(4,1fr);border-top:1px solid rgba(164,114,39,.2)}
.home-pulse-stats>span{padding:8px 10px;border-right:1px solid rgba(164,114,39,.17)}.home-pulse-stats>span:last-child{border-right:0}
.home-pulse-stats small,.home-pulse-stats b{display:block}.home-pulse-stats small{color:#706550;font-size:8.5px;text-transform:uppercase}.home-pulse-stats b{margin-top:2px;color:#c9b180;font:600 10px var(--mono)}
.home-mover-head,.home-mover-list>a{display:grid;grid-template-columns:minmax(0,1.7fr) minmax(64px,.75fr) 58px 52px;align-items:center}
.home-mover-head{min-height:25px;padding:0 12px;border-bottom:1px solid rgba(164,114,39,.2);color:#776b55;font-size:8.5px;text-transform:uppercase}.home-mover-head span:not(:first-child){text-align:right}
.home-mover-list>a{min-height:40px;padding:4px 12px;border-bottom:1px solid rgba(164,114,39,.15);color:#d4c7ae;text-decoration:none;font-size:10.5px}
.home-mover-list>a:last-child{border-bottom:0}.home-mover-list>a:hover{background:rgba(205,148,54,.055)}
.home-mover-list b{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-weight:600}.home-mover-list b small{display:inline-block;margin-right:6px;padding:2px 4px;border:1px solid rgba(198,143,51,.22);border-radius:2px;color:#9f7b3f;font-size:7.5px}
.home-mover-list span,.home-mover-list em,.home-mover-list i{text-align:right}.home-mover-list span{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:#8d8068}.home-mover-list em{font-style:normal;font-family:var(--mono)}
.home-mover-list i{font:700 15px var(--mono);letter-spacing:-4px;color:#857758}.home-mover-list i.up{color:#55b875}.home-mover-list i.down{color:#d7665e}

.home-portals{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:16px;margin-top:16px}
.home-game{position:relative;display:flex;min-height:184px;align-items:flex-start;overflow:hidden;padding:22px 18px 78px 144px;border:1px solid var(--home-line);border-radius:8px;color:#e6d9c0;text-decoration:none;box-shadow:inset 0 1px 0 rgba(255,255,255,.04),0 18px 38px -28px #000;transition:transform var(--dur-2) var(--ease-out),border-color var(--dur-2) var(--ease-out),box-shadow var(--dur-2) var(--ease-out)}
.home-game::before{content:"";position:absolute;inset:0;pointer-events:none}.home-osrs{background:linear-gradient(105deg,#181006,#100d08 70%,#151006)}.home-rs3{background:linear-gradient(105deg,#101215,#0c0e11 70%,#0b1014)}
.home-osrs::before{background:radial-gradient(circle at 86% 40%,rgba(195,129,34,.14),transparent 34%)}.home-rs3::before{background:radial-gradient(circle at 86% 40%,rgba(68,126,162,.16),transparent 34%)}
.home-game:hover{transform:translateY(-2px);border-color:rgba(232,178,81,.58);box-shadow:inset 0 1px 0 rgba(255,255,255,.05),0 22px 42px -25px #000}.home-game-medallion{position:absolute;z-index:1;top:26px;left:12px;width:122px;height:122px;object-fit:contain;filter:drop-shadow(0 10px 16px #000);transition:transform var(--dur-3) var(--ease-emph)}
.home-game:hover .home-game-medallion{transform:scale(1.045)}.home-game-copy{position:relative;z-index:2;display:block;min-width:0}.home-game-copy strong,.home-game-copy small,.home-game-copy>span{display:block}
.home-game-copy strong{color:#e6c98c;font-family:"Cinzel",Georgia,serif;font-size:23px;line-height:1.18;white-space:nowrap}.home-rs3 .home-game-copy strong{color:#9fbfd0}.home-game-copy small{margin-top:5px;color:#a99a7c;font-size:11.5px;line-height:1.4}.home-game-copy>span{margin-top:11px;color:#7f745f;font-size:10px}.home-game-copy>span b{color:#c39d60;font-family:var(--mono)}

@media(max-width:1050px){
  .home-hero-copy{width:64%}.home-livebar{grid-template-columns:.55fr .9fr .9fr 1fr 1fr}
}
@media(max-width:780px){
  .home-hero{min-height:500px}.home-hero-art{height:280px;object-position:72% center}.home-hero-shade{background:linear-gradient(180deg,rgba(4,4,2,.06) 0,rgba(4,4,2,.14) 32%,#050503 57%,#050503)}
  .home-hero-copy{min-height:500px;width:100%;max-width:none;justify-content:flex-end;padding:230px 24px 24px}.home-market-grid,.home-portals{grid-template-columns:1fr}
  .home-livebar{grid-template-columns:repeat(2,1fr)}.home-livebar>span{justify-content:flex-start;border-bottom:1px solid rgba(163,116,43,.16)}.home-livebar .home-live{grid-column:1/-1}.home-livebar>span:nth-child(3),.home-livebar>span:last-child{border-right:0}
}
@media(max-width:640px){
  :root[data-page="home"] #main{padding:0 8px calc(105px + env(safe-area-inset-bottom))}:root[data-page="home"] .hdr{padding-top:6px;padding-bottom:6px}:root[data-page="home"] .brand-logo{height:44px}
  .home-hero{min-height:520px}.home-hero-copy{min-height:520px;padding:235px 17px 22px}.home-hero h1{font-size:clamp(31px,9.6vw,42px)}.home-lede{font-size:12px}
  .home-search{display:block;border:0;background:transparent;box-shadow:none}.home-search input{width:100%;min-height:42px;border:1px solid rgba(202,148,57,.34);border-radius:4px;background:rgba(5,5,3,.9)}.home-search button{width:100%;min-height:40px;margin:7px 0 0}
  .home-market-grid,.home-portals{gap:10px;margin-top:10px}.home-pulse-chart{height:118px}.home-pulse-stats{grid-template-columns:repeat(2,1fr)}.home-pulse-stats>span:nth-child(2){border-right:0}.home-pulse-stats>span:nth-child(-n+2){border-bottom:1px solid rgba(164,114,39,.17)}
  .home-mover-head,.home-mover-list>a{grid-template-columns:minmax(0,1.6fr) 64px 54px}.home-mover-head span:last-child,.home-mover-list i{display:none}
}
@media(max-width:390px){.home-livebar>span{padding-inline:9px}.home-hero-copy{padding-inline:14px}}
@media(prefers-reduced-motion:reduce){.home-game,.home-game-medallion,.home-game-actions a{transition:none}}

/* Screen-reader-only: real content for crawlers and assistive tech, zero pixels. */
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
  clip:rect(0,0,0,0);white-space:nowrap;border:0}

/* ===== print ===== a price table on paper: no chrome, no ads, dark ink on white */
@media print{
  .hdr,.subbar,.mchips,.ad-slot,.ad-rail,.site-foot,.toast,.modal-bg,.overlay{display:none!important}
  [data-theme] body,[data-theme] #results,.wl-table,.perf-t{background:#fff!important;background-image:none!important;box-shadow:none}
  body{background:#fff;color:#111}
  .board,.pulse,.wy-edit,.wy-admin,[data-theme] .board,[data-theme] .pulse,[data-theme] thead th{background:#fff;background-image:none;border-color:#bbb;box-shadow:none}
  tbody td,thead th,.board .b-head b,.pulse b,.pulse span,.up,.down,.flat,.mi em,.sig,.t-row,.board .b-head a,.board .b-sub,.wl-al,.wl-tval.muted,.perf-t .muted{color:#111}
  a{color:#111;text-decoration:underline}
}

/* ---------- #seo-item: the SEO worker's server-rendered content ----------
   This block used to be injected inside #results, where the app's first
   render() deleted it — which also meant nobody ever saw it, so it needed no
   styling. It now lives OUTSIDE #results so it survives into the DOM that
   crawlers index (see the seo-worker header), which means humans see it too.
   Hiding it would be both a lie to the reader and a hidden-text risk at
   19,650 pages, so it is styled as what it honestly is: a plain-text summary
   of the same facts the app shows above, sitting quietly at the foot of the
   page. On item pages the terminal overlay covers it entirely. */
#seo-item{box-sizing:border-box;width:100%;min-width:0;max-width:1540px;margin:26px auto 40px;padding:20px 20px 0;
  border-top:1px solid var(--line);color:var(--dim);font-size:var(--fs-3);line-height:1.65}
#seo-item h2{margin:22px 0 8px;color:var(--emph);font-size:15px;font-weight:500}
#seo-item h3{margin:16px 0 4px;color:var(--ink);font-size:13.5px;font-weight:500}
#seo-item p{margin:0 0 10px;max-width:74ch}
#seo-item img{float:left;margin:2px 10px 6px 0}
#seo-item table{border-collapse:collapse;margin:10px 0 14px;min-width:min(420px,100%)}
#seo-item th{text-align:left;font-weight:400;color:var(--faint);padding:3px 18px 3px 0;
  white-space:nowrap}
#seo-item td{padding:3px 0;color:var(--emph);font-variant-numeric:tabular-nums}
#seo-item a{color:var(--gold)}
#seo-item time{color:var(--faint)}
/* Hub pages are a long two-column list of item → price. */
#seo-item table td:first-child{padding-right:22px}

/* Core market/trend pages already explain themselves in the live board. Their
   server-rendered block exists to keep useful crawlable navigation in the
   rendered DOM, so present it as a compact related-pages footer instead of a
   duplicate article. Crucially it stays in #main's centre track above 1560px;
   without the explicit grid placement it auto-flowed into the right ad rail. */
#seo-item.seo-related{display:flex;align-items:center;gap:18px;margin-top:22px;
  padding:13px 16px;border:1px solid var(--line);border-radius:4px;
  background:color-mix(in srgb,var(--panel) 88%,transparent)}
#seo-item.seo-related h2{flex:0 0 auto;margin:0;color:var(--emph);font-size:var(--fs-3);
  font-weight:600;letter-spacing:.02em}
#seo-item.seo-related p{display:flex;flex-wrap:wrap;gap:4px 9px;margin:0;max-width:none}
#seo-item.seo-related a{white-space:nowrap}
/* Category cards already carry the explanation and counts. Their crawlable
   links stay in a native, keyboard-accessible drawer, sharing the heading and
   grid's exact width in public, template and ad-free account layouts. */
#seo-item.seo-related.seo-category-links{display:block;max-width:1500px;margin:6px auto 0;
  padding:0;font-size:var(--fs-2);line-height:1.4;background:transparent}
#seo-item.seo-category-links .category-directory-links{min-width:0}
#seo-item.seo-category-links summary{min-height:28px;padding:6px 12px;cursor:pointer;
  color:var(--gold-quiet);font-size:var(--fs-2);line-height:16px}
#seo-item.seo-category-links summary::marker{font-size:9px;color:var(--gold-quiet)}
#seo-item.seo-category-links summary:focus-visible{outline:2px solid var(--gold);outline-offset:-2px}
#seo-item.seo-category-links .category-directory-count{margin-left:8px;color:var(--faint);font-size:var(--fs-1)}
#seo-item.seo-category-links .category-directory-content{padding:0 12px 10px}
#seo-item.seo-category-links .category-directory-context{display:flex;flex-wrap:wrap;align-items:center;
  gap:5px 16px;padding:6px 0 8px;border-top:1px solid var(--line)}
#seo-item.seo-category-links .category-directory-index{display:grid;
  grid-template-columns:repeat(auto-fit,minmax(min(100%,210px),1fr));gap:4px 18px}
#seo-item.seo-category-links .category-directory-index a{display:flex;min-width:0;
  align-items:baseline;justify-content:space-between;gap:8px;font-size:var(--fs-2);text-decoration:none;white-space:normal}
#seo-item.seo-category-links .category-directory-index a:hover span:first-child{text-decoration:underline}
#seo-item.seo-category-links .category-link-count{flex:none;color:var(--faint);font-variant-numeric:tabular-nums}
/* All items in the pager owns this drawer. No extra strip, margin or border
   exists when closed. Context links are part of the expanded content only. */
#seo-item.seo-related.seo-all-items-links{display:block;min-height:0;margin:0 auto;
  max-width:1500px;padding:4px 10px;background:linear-gradient(180deg,color-mix(in srgb,var(--panel) 94%,transparent),color-mix(in srgb,var(--bg) 94%,transparent))}
#seo-item.seo-all-items-links[hidden]{display:none!important}
.market.catalogue-table{width:100%;max-width:1500px;margin-inline:auto}
#seo-item.seo-all-items-links .seo-index-drawer{padding:2px 2px 7px}
#seo-item.seo-all-items-links .seo-index-drawer>nav:last-child{display:grid;grid-template-columns:repeat(auto-fill,minmax(180px,1fr));
  gap:4px 14px;padding-top:9px;border-top:1px solid var(--line)}
#seo-item.seo-all-items-links .seo-index-drawer>nav:last-child a{min-width:0;overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap;font-size:var(--fs-2)}
#seo-item.seo-all-items-links .seo-index-drawer>nav:last-child span{color:var(--faint);font-family:var(--mono);font-size:var(--fs-1)}
#seo-item.seo-all-items-links .seo-context{display:flex;min-height:24px;align-items:center;justify-content:center;gap:0}
#seo-item.seo-all-items-links .seo-context strong{margin-right:12px;color:var(--dim);font-size:var(--fs-1);letter-spacing:.08em;text-transform:uppercase}
#seo-item.seo-all-items-links .seo-context a{padding:0 12px;border-left:1px solid var(--line);font-size:var(--fs-2)}
#seo-item.list-seo-drawer .list-related-links{display:flex;flex-wrap:wrap;justify-content:center;gap:4px 14px;
  padding:4px 0 8px;font-size:var(--fs-2)}
#seo-item.list-seo-drawer .list-item-links:empty{display:none}
#seo-item.list-seo-drawer [hidden],.catalogue-table tr[hidden]{display:none!important}
#seo-item.list-seo-drawer .list-methodology{max-width:none;margin:0;padding:2px 0 8px;
  color:var(--faint);font-size:var(--fs-2);line-height:1.45}
.list-empty-related{max-width:1500px;margin:8px auto 0;padding:5px 10px;border:1px solid var(--line);
  border-radius:4px;color:var(--faint);font-size:var(--fs-2)}
.list-empty-related>summary{cursor:pointer;color:var(--gold-quiet)}
.list-empty-related .list-related-links,.list-empty-related .seo-context{display:flex;flex-wrap:wrap;
  align-items:center;gap:4px 14px;padding:7px 0 2px;font-size:var(--fs-2)}
.list-empty-related .seo-context strong{font-size:var(--fs-1);text-transform:uppercase}
@media(max-width:640px){
  #seo-item.seo-related{display:block;margin-top:16px;padding:12px}
  #seo-item.seo-related h2{margin-bottom:5px}
  #seo-item.seo-related.seo-category-links{margin-bottom:0}
  #seo-item.seo-related.seo-all-items-links{min-height:0;margin-top:0;padding:4px 8px}
  #seo-item.seo-all-items-links .seo-context{min-height:32px;justify-content:flex-start;overflow-x:auto;white-space:nowrap}
  #seo-item.seo-all-items-links .seo-context strong{margin-right:8px}
  #seo-item.seo-all-items-links .seo-context a{padding:0 10px}
}

/* ===== GE-first homepage and clean-root header (v29) =====
   Overview, item browsing, categories, GE lists, tools, freshness, search and
   account controls share one physical header. On the neutral homepage the
   game switch is absent and game-dependent controls reveal the explicit GE
   portals without changing the URL; game pages keep their scoped switch and search. */
.hdr{min-height:58px;gap:8px;
  padding:calc(4px + env(safe-area-inset-top)) max(18px,env(safe-area-inset-right)) 4px max(18px,env(safe-area-inset-left));
  flex-wrap:nowrap}
.games[hidden]{display:none!important}
.brand-logo{height:48px}
.hdr>.tabs{min-width:0;flex:0 1 auto;background:transparent;padding:0}
.hdr>.tabs :is(button,a){padding:7px 9px;font-size:12px;white-space:nowrap}
:root[data-page="home"] #tabs [data-game-scoped]{display:none!important}
.hdr>.tools{flex:none;margin-left:auto;gap:8px}
.hdr>.hdr-right{flex:1 1 300px;margin-left:0;min-width:230px}
.hdr>.tabs+.hdr-right{margin-left:auto}
.hdr .search-wrap{min-width:0;flex:1}
.hdr .acct-slot{flex:none}
.hdr .status{max-width:190px;padding:5px 9px;font-size:10px}
.hdr .games :is(button,a){padding:6px 10px;font-size:12px}
.search-dd .dd-row>span:not(.mi-ico){min-width:0;flex:1}
.search-dd .dd-game{flex:none;margin-left:auto;padding:2px 5px;border:1px solid var(--line);border-radius:3px;
  color:var(--faint);font:700 9px var(--mono);letter-spacing:.04em}
.search-dd .dd-game.dd-osrs{color:#d9ad62;border-color:rgba(205,151,58,.34)}
.search-dd .dd-game.dd-rs3{color:#9ebccd;border-color:rgba(95,143,169,.38)}
@media(max-width:1180px) and (min-width:641px){
  .hdr{flex-wrap:wrap;padding-top:calc(6px + env(safe-area-inset-top));padding-bottom:6px}
  .hdr>.tabs{order:5;flex:1 1 100%;justify-content:center;border-top:1px solid var(--line);padding-top:4px}
  .hdr>.tools{margin-left:auto}
}
@media(max-width:760px){
  .hdr{flex-wrap:wrap}
  .hdr>.tools{margin-left:auto}
  .hdr>.hdr-right{flex:1 1 100%;min-width:0}
}
@media(max-width:640px){
  .hdr>.tabs{padding:5px calc(6px + env(safe-area-inset-right)) calc(5px + env(safe-area-inset-bottom)) calc(6px + env(safe-area-inset-left))}
  .hdr>.tabs :is(button,a){padding-inline:3px;font-size:9px}
  .hdr>.tabs .ico{width:19px;height:19px}
  .hdr .status{max-width:min(185px,52vw)}
  :root[data-page="home"] .hdr>.tools{display:none}
}

/* The generated source now matches the desktop banner's 4:1 geometry. A
   dedicated square crop serves phones, where the artwork occupies its own
   upper panel and the copy remains readable below it. */
:root[data-page="home"] .hdr{min-height:58px;padding-top:calc(4px + env(safe-area-inset-top));padding-bottom:4px;background:#0b0a07}
:root[data-page="home"] .brand-logo{height:48px}
.home-hero{aspect-ratio:4.6/1;min-height:0}
.home-hero-picture{position:absolute;inset:0;display:block}
.home-hero-art{display:block;position:static;width:100%;height:100%;object-fit:cover;object-position:center}
.home-hero-copy{min-height:100%;width:52%;padding-top:24px;padding-bottom:26px}
.home-portals{scroll-margin-top:calc(var(--apphdr-h,58px) + 14px)}
.wl-tools{display:flex;justify-content:flex-end;align-items:center;margin:0 0 10px}
.wl-tools .ctl{background:rgba(31,23,15,.86);border:1px solid var(--line);border-radius:4px;padding:5px 7px}
.home-game-actions{position:absolute;z-index:2;right:16px;bottom:16px;left:144px;display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:7px}
.home-game-actions a{display:flex;align-items:center;justify-content:space-between;min-height:50px;padding:9px 13px;
  border:1px solid rgba(201,148,60,.35);border-radius:5px;background:linear-gradient(180deg,rgba(30,22,11,.72),rgba(8,7,5,.72));color:#d7b878;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.035);font-size:11px;font-weight:750;letter-spacing:.015em;text-decoration:none;white-space:nowrap;
  transition:border-color var(--dur-2) var(--ease-out),background var(--dur-2) var(--ease-out),color var(--dur-2) var(--ease-out),transform var(--dur-2) var(--ease-out)}
.home-game-actions a::after{content:"›";margin-left:8px;color:#8d713f;font-size:18px;font-weight:400;line-height:1}
.home-game-actions a:hover{transform:translateY(-1px);border-color:rgba(232,178,81,.72);background:linear-gradient(180deg,rgba(67,45,17,.82),rgba(18,13,7,.8));color:#f1d294}
.home-game-actions a:focus-visible{outline:2px solid #e0aa4e;outline-offset:2px}
.home-rs3 .home-game-actions a{border-color:rgba(105,151,178,.36);background:linear-gradient(180deg,rgba(17,29,37,.78),rgba(7,10,13,.76));color:#aac7d7}
.home-rs3 .home-game-actions a::after{color:#638da4}.home-rs3 .home-game-actions a:hover{border-color:rgba(132,183,211,.72);background:linear-gradient(180deg,rgba(28,54,68,.84),rgba(10,18,23,.8));color:#d1e8f4}
@media(max-width:1050px){
  .home-portals{grid-template-columns:1fr}.home-game{min-height:174px;padding:20px 16px 76px 118px}.home-game-medallion{top:27px;left:9px;width:104px;height:104px}.home-game-copy strong{font-size:21px}
  .home-game-actions{right:14px;bottom:14px;left:118px;gap:7px}.home-game-actions a{min-height:46px;padding:8px 11px;font-size:10.5px}
}
@media(max-width:780px){
  .home-hero{aspect-ratio:auto;min-height:500px}
  .home-hero-picture{inset:0 0 auto;height:min(78vw,350px)}
  .home-hero-art{height:100%;object-position:center 43%}
  .home-hero-shade{background:linear-gradient(180deg,rgba(4,4,2,.03) 0,rgba(4,4,2,.12) 42%,#050503 68%,#050503)}
  .home-hero-copy{min-height:500px;width:100%;max-width:none;justify-content:flex-end;padding:300px 24px 25px}
  .home-game{min-height:174px;padding:20px 16px 76px 122px}.home-game-medallion{top:27px;width:108px;height:108px}.home-game-copy strong{font-size:21px}
  .home-game-actions{left:122px}
}
@media(max-width:640px){
  :root[data-page="home"] .hdr{padding-top:calc(5px + env(safe-area-inset-top));padding-bottom:5px}
  :root[data-page="home"] .brand-logo{height:44px}
  .home-hero{min-height:475px}.home-hero-picture{height:min(88vw,340px)}
  .home-hero-copy{min-height:475px;padding:275px 17px 22px}
  .home-game{display:block;min-height:228px;padding:17px 14px 14px 110px}.home-game-medallion{top:11px;left:9px;width:94px;height:94px}
  .home-game-copy strong{font-size:19px;white-space:normal}.home-game-copy small{font-size:10.5px}.home-game-copy>span{margin-top:8px}
  .home-game-actions{position:relative;inset:auto;width:auto;margin:17px 0 0 -96px;grid-template-columns:repeat(2,minmax(0,1fr));gap:7px;transform:none}
  .home-game-actions a{min-height:45px;padding:8px 11px;font-size:10.5px}
}
@media(max-width:390px){.home-game{min-height:232px;padding-right:12px}.home-game-actions{margin-left:-98px}.home-game-actions a{padding-inline:9px}}

/* ===== Homepage market dashboard (v34) =====
   The root page has no selected game. It introduces both GEs, then presents
   one real aggregate data surface. All density rules live here so the full
   desktop dashboard stays coherent as a single screen. */
:root[data-page="home"]{scrollbar-gutter:auto}
:root[data-page="home"] body{display:flex;height:auto;min-height:100dvh;flex-direction:column;background:#050503;background-image:
  radial-gradient(900px 420px at 68% 70px,rgba(185,116,21,.06),transparent 68%),
  linear-gradient(180deg,#080704,#040403 72%,#070604)}
:root[data-page="home"] .hdr{width:100%;max-width:none;margin:0}
:root[data-page="home"] #main{display:flex;width:100%;max-width:none;flex:1 0 auto;flex-direction:column;padding:0 8px 8px}
:root[data-page="home"] #main>.ad-slot,:root[data-page="home"] #page-head{display:none!important}
:root[data-page="home"] #results{display:flex;min-height:0;flex:1;overflow:visible;background:transparent}
:root[data-page="home"] .hdr>.tools{display:none}
:root[data-page="home"] .hdr>.hdr-right{flex:1 1 480px;min-width:300px;margin-left:auto}
:root[data-page="home"] #ad-footer-slot{display:none!important}
:root[data-page="home"] body>:is(.ad-footer,.mw-brand-footer){display:none!important}
.home-landing{--home-gold:#dca33b;--home-bright:#f0c568;--home-blue:#4aa9df;--home-purple:#b45be2;
  --home-line:rgba(181,126,42,.34);--home-panel:#0b0b08;display:flex;width:100%;max-width:1500px;min-height:100%;flex:1;flex-direction:column;margin:0 auto;color:#e7dcc5}

.home-hero{position:relative;isolation:isolate;height:clamp(145px,11.4vw,174px);min-height:0;aspect-ratio:auto;
  overflow:hidden;border:1px solid var(--home-line);border-top:0;background:#030302;box-shadow:0 20px 60px -45px #000}
.home-hero-picture{position:absolute;inset:0;display:block}.home-hero-art{position:static;display:block;width:100%;height:100%;object-fit:cover;object-position:center 49%}
.home-hero::after{content:"";position:absolute;z-index:2;right:0;bottom:0;left:0;height:1px;background:linear-gradient(90deg,transparent,rgba(235,184,84,.48),transparent)}
.home-hero-shade{position:absolute;z-index:1;inset:0;background:linear-gradient(90deg,#040403 0%,rgba(4,4,3,.97) 23%,rgba(4,4,3,.72) 43%,rgba(4,4,3,.06) 69%)}
.home-hero-copy{position:relative;z-index:3;display:flex;width:49%;max-width:690px;min-height:100%;flex-direction:column;justify-content:center;padding:18px clamp(24px,3.5vw,54px)}
.home-kicker{color:#d9a33f;font-size:9px;font-weight:850;letter-spacing:.23em;text-transform:uppercase}
.home-hero h1{max-width:640px;margin:6px 0 4px;color:#f8e8c0;font-family:"Cinzel",Georgia,serif;font-size:clamp(30px,3.1vw,44px);font-weight:650;letter-spacing:-.035em;line-height:1;text-shadow:0 2px 22px #000}
.home-lede{max-width:570px;margin:0;color:#c0b294;font-size:11px;line-height:1.4;text-shadow:0 1px 9px #000}

.home-portals{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px;margin-top:8px;scroll-margin-top:calc(var(--apphdr-h,58px) + 10px)}
.home-game-column{min-width:0}.home-updatebar{display:flex;min-height:25px;align-items:center;gap:7px;padding:4px 11px;border:1px solid var(--home-line);border-bottom:0;border-radius:5px 5px 0 0;background:#0a0906;color:#82765f;font:600 8px var(--mono);letter-spacing:.035em;text-transform:uppercase}
.home-updatebar strong{color:#ddb25b;font-size:9px}.home-rs3-column .home-updatebar strong{color:#8dc7eb}.home-updatebar b{color:#cbb481}.home-updatebar i{width:5px;height:5px;border-radius:50%;background:#6d675b;box-shadow:none}.home-updatebar.is-fresh i{background:#4fc978;box-shadow:0 0 7px rgba(79,201,120,.75)}.home-updatebar.is-stale i{background:#d39b38;box-shadow:0 0 7px rgba(211,155,56,.5)}.home-updatebar small{color:#7a715e;font:inherit}.home-updatebar.is-fresh small{color:#57966b}.home-updatebar.is-stale small{color:#b08343}
.home-game{position:relative;display:block;min-height:116px;overflow:hidden;padding:13px 12px 48px 112px;border:1px solid var(--home-line);border-radius:0 0 6px 6px;color:#e6d9c0;box-shadow:inset 0 1px 0 rgba(255,255,255,.035),0 15px 30px -28px #000}
.home-game::before{content:"";position:absolute;inset:0;pointer-events:none}.home-osrs{background:linear-gradient(105deg,#171006,#0e0c07 69%,#120e06)}.home-rs3{background:linear-gradient(105deg,#0d1216,#090d10 69%,#071015)}
.home-osrs::before{background:radial-gradient(circle at 82% 38%,rgba(197,130,32,.12),transparent 38%)}.home-rs3::before{background:radial-gradient(circle at 82% 38%,rgba(56,134,178,.14),transparent 38%)}
.home-game-medallion{position:absolute;z-index:1;top:9px;left:9px;width:92px;height:92px;object-fit:contain;filter:drop-shadow(0 8px 13px #000);transition:transform var(--dur-3) var(--ease-emph)}
.home-game:hover .home-game-medallion{transform:scale(1.035)}.home-game-copy{position:relative;z-index:2;display:block;min-width:0}.home-game-copy strong,.home-game-copy small,.home-game-copy>span{display:block}
.home-game-copy strong{color:#e5c889;font-family:"Cinzel",Georgia,serif;font-size:19px;line-height:1.1;white-space:nowrap}.home-rs3 .home-game-copy strong{color:#9fc8e2}.home-game-copy small{margin-top:3px;color:#a99a7c;font-size:9.5px}.home-game-copy>span{margin-top:6px;color:#766c59;font-size:8.5px}.home-game-copy>span b{color:#c39d60;font-family:var(--mono)}
.home-private-tools{position:absolute;z-index:2;top:10px;right:10px;display:flex;gap:5px}.home-private-tools a{display:block;padding:5px 7px;border:1px solid rgba(188,137,51,.27);border-radius:4px;background:rgba(5,5,3,.44);color:#b99e6c;font-size:8px;text-decoration:none}.home-private-tools a::before{content:"⌑";margin-right:4px;color:#c79b49}.home-private-tools a small{display:block;margin:1px 0 0 12px;color:#6f6552;font-size:6.5px;text-transform:uppercase}
.home-rs3 .home-private-tools a{border-color:rgba(75,137,173,.32);color:#8eb7cf}.home-rs3 .home-private-tools a::before{color:#5a9bc0}
.home-game-actions{position:absolute;z-index:2;right:10px;bottom:9px;left:112px;display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:5px}
.home-game-actions a{display:flex;min-height:31px;align-items:center;justify-content:space-between;padding:6px 8px;border:1px solid rgba(201,148,60,.34);border-radius:4px;background:linear-gradient(180deg,rgba(28,20,9,.7),rgba(7,6,4,.7));color:#dbb96f;box-shadow:inset 0 1px 0 rgba(255,255,255,.025);font-size:8.5px;font-weight:750;text-decoration:none;white-space:nowrap;transition:border-color var(--dur-2),background var(--dur-2),transform var(--dur-2)}
.home-game-actions a::after{content:"›";margin-left:5px;color:#8d713f;font-size:14px}.home-game-actions a:hover{transform:translateY(-1px);border-color:rgba(232,178,81,.7);background:rgba(56,38,14,.7);color:#f0d08c}.home-game-actions a:focus-visible{outline:2px solid #e0aa4e;outline-offset:1px}
.home-rs3 .home-game-actions a{border-color:rgba(94,151,184,.36);background:linear-gradient(180deg,rgba(14,28,37,.76),rgba(5,9,12,.75));color:#a7cde3}.home-rs3 .home-game-actions a::after{color:#638da4}.home-rs3 .home-game-actions a:hover{border-color:rgba(132,183,211,.72);background:rgba(26,53,68,.78);color:#d1e8f4}

.home-data-grid{display:grid;min-height:350px;flex:1 0 350px;grid-template-columns:minmax(0,2.6fr) minmax(350px,.95fr);gap:10px;margin-top:9px}.home-value-panel{display:flex;min-width:0;overflow:hidden;flex-direction:column;border:1px solid var(--home-line);border-radius:5px;background:rgba(10,10,7,.94);box-shadow:inset 0 1px 0 rgba(255,255,255,.022)}.home-market-rail{min-width:0}
.home-value-head{display:flex;min-height:54px;align-items:center;justify-content:space-between;gap:18px;padding:10px 13px 8px;border-bottom:1px solid rgba(177,124,40,.22)}.home-value-head>div:first-child{min-width:0}.home-value-head h2{margin:0;color:#dfc18a;font-family:"Cinzel",Georgia,serif;font-size:16px;font-weight:650}.home-value-head p{margin:2px 0 0;color:#80745e;font-size:10px;line-height:1.3}.home-value-head .home-coverage-note{max-width:min(62vw,820px);overflow:hidden;color:#aa9876;font:650 9px var(--mono);text-overflow:ellipsis;white-space:nowrap}.home-value-head .home-coverage-note.has-partial{color:#b48848}.home-chart-controls{display:flex;flex:none;align-items:center;justify-content:flex-end;gap:8px}.home-range-tabs,.home-view-tabs{display:flex;flex:none;gap:4px}.home-view-tabs[hidden]{display:none}.home-range-tabs button,.home-view-tabs button{min-width:34px;padding:5px 7px;border-color:rgba(174,124,42,.28);border-radius:3px;background:#0b0a07;color:#88785c;font:700 9px var(--mono)}.home-view-tabs button{min-width:52px}.home-range-tabs button:hover,.home-range-tabs button.on,.home-view-tabs button:hover,.home-view-tabs button.on{border-color:#bc8735;background:#1b1409;color:#efbd5c}
.home-chart-legend{display:flex;flex-wrap:wrap;align-items:center;gap:6px 16px;padding:7px 13px 3px}.home-chart-legend button{display:flex;align-items:center;gap:5px;padding:2px 0;border:0;background:transparent;color:#81745d;font:650 9px var(--mono);opacity:.42}.home-chart-legend button.on{opacity:1}.home-chart-legend button i{width:8px;height:8px;border:2px solid currentColor;border-radius:2px;background:currentColor}.home-chart-legend .osrs{color:#d7a22e}.home-chart-legend .rs3{color:#4ba9df}.home-chart-legend .osrs-tax{color:#f0c96e}.home-chart-legend .rs3-tax{color:#89d1f3}.home-chart-legend :is(.osrs-tax,.rs3-tax) i{height:0;border:0;border-top:2px dashed currentColor;border-radius:0;background:transparent}
.home-value-chart{position:relative;min-height:220px;height:auto;flex:1;padding:0 3px 2px;transition:opacity .15s}.home-value-chart.loading{opacity:.55}.home-value-chart>p{display:grid;height:100%;place-items:center;margin:0;color:#706651;font-size:10px}.home-value-chart svg{display:block;width:100%;height:100%;overflow:visible}.home-value-grid line{stroke:rgba(146,116,64,.16);stroke-width:1;vector-effect:non-scaling-stroke}.home-value-grid text,.home-axis-title{fill:#746a56;font:7.5px var(--mono)}.home-axis-title{fill:#91846a}.home-value-series path{fill:none;stroke-width:1.7;vector-effect:non-scaling-stroke}.home-value-series circle{stroke-width:1.5;vector-effect:non-scaling-stroke}.home-value-series circle.home-series-point{stroke:#080806;stroke-width:1.2}.home-value-series circle.home-series-point.is-current{stroke:#f5e2ae;stroke-width:2;filter:drop-shadow(0 0 3px rgba(239,189,92,.45))}.home-series-osrs{stroke:#d7a22e;fill:#d7a22e}.home-series-rs3{stroke:#4ba9df;fill:#4ba9df}.home-series-osrs-tax{stroke:#f0c96e;fill:#f0c96e;stroke-dasharray:4 3}.home-series-rs3-tax{stroke:#89d1f3;fill:#89d1f3;stroke-dasharray:4 3}.home-chart-note{position:absolute;right:12px;bottom:25px!important;left:64px;height:auto!important;color:#8a7b60!important;font-size:8px!important;text-align:center}

.home-value-cards{display:grid;height:100%;min-height:0;grid-template-rows:repeat(4,minmax(76px,1fr));gap:8px;margin:0}.home-value-cards article{display:grid;min-width:0;min-height:76px;grid-template-columns:52px minmax(0,1fr);align-items:center;gap:14px;padding:11px 16px;border:1px solid var(--home-line);border-radius:6px;background:#0b0a07;box-shadow:inset 0 1px 0 rgba(255,255,255,.025)}.home-value-cards article.osrs{background:radial-gradient(circle at 8% 50%,rgba(205,139,25,.11),transparent 34%),linear-gradient(105deg,#171006,#0d0b06)}.home-value-cards article.rs3{border-color:rgba(71,131,165,.42);background:radial-gradient(circle at 8% 50%,rgba(58,164,218,.11),transparent 34%),linear-gradient(105deg,#0c1419,#080d11)}.home-value-cards article.tax{background-image:radial-gradient(circle at 8% 50%,rgba(222,170,62,.1),transparent 34%),linear-gradient(105deg,rgba(20,16,8,.98),rgba(8,8,6,.98))}.home-value-cards article.rs3.tax{background-image:radial-gradient(circle at 8% 50%,rgba(79,178,226,.1),transparent 34%),linear-gradient(105deg,rgba(9,18,23,.98),rgba(6,10,13,.98))}.home-metric-icon{display:grid;width:52px;height:52px;place-items:center;border:1px solid rgba(211,154,55,.23);border-radius:12px;background:rgba(222,160,49,.07);color:#dca53b}.home-value-cards .rs3 .home-metric-icon{border-color:rgba(83,169,216,.27);background:rgba(62,151,202,.08);color:#62b8e8}.home-metric-glyph{width:27px;height:27px;stroke-width:1.65}.home-metric-copy{display:grid;min-width:0;grid-template-columns:minmax(96px,1fr) auto;grid-template-areas:"heading value" "meta value";align-items:center;column-gap:14px;row-gap:5px}.home-metric-heading{display:flex;min-width:0;grid-area:heading;align-items:center;gap:7px}.home-metric-title{display:block;overflow:hidden;color:#c7ad7c;font:750 11px var(--sans);letter-spacing:.035em;text-overflow:ellipsis;text-transform:uppercase;white-space:nowrap}.home-value-cards .rs3 .home-metric-title{color:#9fc7df}.home-metric-badge{padding:2px 5px;border:1px solid rgba(194,139,46,.26);border-radius:999px;color:#927b52;font:700 7.5px var(--mono);letter-spacing:.04em;text-transform:uppercase}.home-value-cards .rs3 .home-metric-badge{border-color:rgba(84,165,208,.25);color:#739db5}.home-metric-value{display:block;grid-area:value;margin:0;color:#f1c66e;font:780 clamp(21px,1.45vw,26px)/1.05 var(--mono);letter-spacing:-.035em;text-align:right;white-space:nowrap}.home-value-cards .rs3 .home-metric-value{color:#6ec4f1}.home-metric-meta{display:block;grid-area:meta;margin:0;color:#9a8c70;font:650 9.5px/1.25 var(--mono);white-space:normal}.home-value-cards .rs3 .home-metric-meta{color:#7896a7}.home-value-cards article.is-unavailable .home-metric-value{color:#8e826b;font-size:20px}.home-value-cards article.is-delayed .home-metric-meta{color:#c59a57}
@media(max-width:1120px){.home-private-tools{display:none}.home-game{padding-left:102px}.home-game-medallion{width:82px;height:82px}.home-game-actions{left:102px}.home-data-grid{grid-template-columns:minmax(0,2.15fr) minmax(330px,1fr)}}
@media(max-width:880px){.home-hero{height:170px}.home-hero-copy{width:62%}.home-portals,.home-data-grid{grid-template-columns:1fr}.home-data-grid{min-height:0;flex:none}.home-value-chart{height:210px;min-height:210px;flex:none}.home-value-cards{grid-template-rows:repeat(4,minmax(70px,auto))}}
@media(max-width:640px){
  :root[data-page="home"] #main{padding:0 6px calc(94px + env(safe-area-inset-bottom))}.home-hero{height:330px}.home-hero-picture{inset:0 0 auto;height:215px}.home-hero-art{height:100%;object-position:center 42%}.home-hero-shade{background:linear-gradient(180deg,rgba(3,3,2,.05),rgba(3,3,2,.22) 48%,#050503 68%,#050503)}.home-hero-copy{width:100%;min-height:330px;justify-content:flex-end;padding:210px 17px 18px}.home-hero h1{font-size:32px}.home-lede{font-size:10px}
  .home-game{min-height:190px;padding:13px 12px 83px 100px}.home-game-medallion{top:11px;left:7px;width:86px;height:86px}.home-game-copy strong{font-size:17px;white-space:normal}.home-game-actions{right:9px;bottom:9px;left:9px;margin:0;grid-template-columns:repeat(2,minmax(0,1fr))}.home-game-actions a{min-height:31px}.home-data-grid{margin-top:8px}.home-value-head{align-items:flex-start;flex-direction:column}.home-chart-controls{width:100%;flex-wrap:wrap;justify-content:flex-start}.home-range-tabs{width:100%}.home-range-tabs button{flex:1}.home-chart-legend{gap:5px 10px}.home-value-chart{height:175px;min-height:175px}.home-value-cards{grid-template-columns:1fr}
}
@media(max-width:430px){.home-metric-copy{display:block}.home-metric-value{margin-top:4px;text-align:left}.home-metric-meta{margin-top:5px}}
@media(max-width:390px){.home-updatebar small{display:none}.home-value-chart{height:160px}}
@media(prefers-reduced-motion:reduce){.home-game-medallion,.home-game-actions a,.home-value-chart{transition:none}}

/* v34 data-truth labels: keep coverage visible without expanding the compact
   dashboard, and let the card comparison state occupy its own line. */
.home-value-cards small{display:block}
.home-value-head .home-coverage-note{max-width:none;overflow:visible;text-overflow:clip;white-space:normal}
@media(max-width:640px){.home-value-head .home-coverage-note{max-width:none;white-space:normal}}

/* Wide homepages reserve two equal 160px ad gutters only while both ad policy
   and visitor consent permit those placements. Any resolved no-ad state uses
   the fluid dashboard instead of retaining a 1500px island on a wide monitor.
   Admin template mode intentionally restores the exact public ad geometry. */
:root[data-page="home"][data-ad-home-expanded="1"] .home-landing{max-width:none}
@media(min-width:1560px){
  :root[data-page="home"][data-ad-home-gutters="1"] #main{display:grid;grid-template-columns:160px minmax(0,1500px) 160px;justify-content:center;align-items:stretch;align-content:stretch;column-gap:20px}
  :root[data-page="home"][data-ad-home-gutters="1"] #main>#results,
  :root[data-page="home"][data-ad-home-gutters="1"] #main>#page-head,
  :root[data-page="home"][data-ad-home-gutters="1"] #main>#wyrm-root{grid-column:2;grid-row:1}
  :root[data-page="home"][data-ad-home-gutters="1"] #main>:is(.ad-homeleft:is(.ad-live,.ad-pending,.ad-template),.ad-railright:is(.ad-live,.ad-pending,.ad-template),.mw-brand-homeleft,.mw-brand-railright){
    display:flex!important;grid-row:1;align-self:start;margin:0;min-height:var(--ad-rail-zone-h);
    flex-direction:column;justify-content:center}
  /* One unique 160x300 creative occupies the left rail. Centering it inside
     the same 618px rail zone as the unique 160x600 creative balances the two
  sides without cloning an ad key or fabricating a second placement. */
  :root[data-page="home"][data-ad-home-gutters="1"] #main>:is(.ad-homeleft:is(.ad-live,.ad-pending,.ad-template),.mw-brand-homeleft){
    grid-column:1;justify-self:end}
  :root[data-page="home"][data-ad-home-gutters="1"] #main>:is(.ad-railright:is(.ad-live,.ad-pending,.ad-template),.mw-brand-railright){grid-column:3;justify-self:start}
}

/* ====================================================== V73 VISUAL SYSTEM ====
   Luminous obsidian unifies the product while the active Grand Exchange owns
   the accent channel: molten gold for OSRS, electric cyan for RS3. This pass
   changes paint only. Existing layout, density, advertising, and responsive
   contracts remain untouched. */
:root{
  --page:#03070a;--bg:var(--page);--panel:#081016;--panel2:#0d1820;
  --input-bg:#02070b;--inset-bg:#050b10;--tip-bg:#0c171e;
  --ink:#f3eee3;--dim:#bac3c7;--faint:#82939d;--flat:#82939d;
  --gold:#ffc348;--gold-quiet:#d1a54d;--gold-bg:rgba(255,195,72,.13);
  --emph:#ffe09a;--on-gold:#120d03;--accent:var(--gold);
  --up:#35e58a;--up-bg:rgba(53,229,138,.13);
  --down:#ff7077;--down-bg:rgba(255,112,119,.13);
  --warn:#ffb34f;--warn-bg:rgba(255,179,79,.13);
  --line:#223440;--line-strong:#3b596b;--row-line:#14242d;
  --row-line2:#0e1b23;--row-hover:#102630;--hover-bg:#10232d;
  --ico-bg:#10202a;--seg-on:#132732;--backdrop:rgba(1,5,8,.82);
  --theme-accent:#ffc348;--theme-soft:rgba(255,195,72,.10);
  --theme-line:rgba(255,195,72,.42);--theme-glow:rgba(255,180,42,.18);
  --surface-top:#101c24;--surface-bottom:#070d12;
  --chrome-top:#0d171e;--chrome-bottom:#050a0e;
  --edge:inset 0 1px 0 rgba(224,242,255,.075);
  --sh-1:0 4px 13px -6px rgba(0,0,0,.78);
  --sh-2:0 10px 28px -12px rgba(0,0,0,.82);
  --sh-3:0 24px 54px -18px rgba(0,0,0,.9);
  --r-1:2px;--r-2:4px;--r-3:5px;--r-4:7px;--r-pill:5px;
  --ch-price:#ffc23d;--ch-grid:#18303b;--ch-label:#8ca0aa;
  --ch-fill:rgba(255,194,61,.10);--ch-tag-bg:rgba(3,7,10,.94);
  --ch-cross:rgba(183,207,218,.42);--ch-ring:#03070a;
  scrollbar-color:#315064 #03070a;
}
:root[data-theme="osrs"]{
  --page:#050605;--bg:var(--page);--panel:#0b0e0e;--panel2:#141812;
  --input-bg:#030604;--inset-bg:#070a07;--tip-bg:#11150f;
  --ink:#fff3d8;--dim:#c9bfa8;--faint:#928873;--flat:#928873;
  --gold:#ffc23e;--gold-quiet:#d9a942;--gold-bg:rgba(255,194,62,.14);
  --emph:#ffe59d;--on-gold:#130d02;--accent:var(--gold);
  --line:#463713;--line-strong:#85641b;--row-line:#29240f;
  --row-line2:#19180c;--row-hover:#211d0d;--hover-bg:#211d0d;
  --ico-bg:#211c0d;--seg-on:#29220c;
  --theme-accent:#ffc23e;--theme-soft:rgba(255,194,62,.11);
  --theme-line:rgba(255,194,62,.48);--theme-glow:rgba(255,174,35,.22);
  --surface-top:#17180f;--surface-bottom:#090c09;
  --chrome-top:#11130d;--chrome-bottom:#070906;
  --bev-l:#8d6b22;--bev-d:#020301;
  --ch-price:#ffc23e;--ch-grid:#2d2a14;--ch-label:#9e9277;
  --ch-fill:rgba(255,194,62,.11);--ch-tag-bg:rgba(5,6,5,.94);
  --ch-cross:rgba(226,209,169,.44);--ch-ring:#050605;
  --glow:rgba(255,174,35,.20);--skel-sheen:#3a3218;
  scrollbar-color:#77591d #050605;
}
:root[data-theme="rs3"]{
  --page:#02080d;--bg:var(--page);--panel:#06121a;--panel2:#0b1d28;
  --input-bg:#02080d;--inset-bg:#040d13;--tip-bg:#0a1a24;
  --ink:#eaf8ff;--dim:#afc8d4;--faint:#7894a3;--flat:#7894a3;
  --gold:#27c9ff;--gold-quiet:#67bde0;--gold-bg:rgba(39,201,255,.14);
  --emph:#a4eaff;--on-gold:#001019;--accent:var(--gold);
  --line:#17435a;--line-strong:#2383ad;--row-line:#0d2a38;
  --row-line2:#091d28;--row-hover:#0b2a39;--hover-bg:#0b2937;
  --ico-bg:#0d2b3a;--seg-on:#0c3041;
  --theme-accent:#27c9ff;--theme-soft:rgba(39,201,255,.11);
  --theme-line:rgba(39,201,255,.48);--theme-glow:rgba(0,178,255,.22);
  --surface-top:#0c2230;--surface-bottom:#050d13;
  --chrome-top:#0b1c26;--chrome-bottom:#030a0f;
  --ch-price:#27c9ff;--ch-grid:#123544;--ch-label:#83a8b9;
  --ch-fill:rgba(39,201,255,.11);--ch-tag-bg:rgba(2,8,13,.94);
  --ch-cross:rgba(157,220,242,.44);--ch-ring:#02080d;
  --glow:rgba(0,178,255,.20);--skel-sheen:#153848;
  scrollbar-color:#1d718f #02080d;
}

body{background-color:var(--page);background-image:
  radial-gradient(1100px 460px at 50% -90px,var(--theme-soft),transparent 68%),
  linear-gradient(180deg,color-mix(in srgb,var(--page) 88%,#0b1820),var(--page) 34%,#010305)}
[data-theme="osrs"] body,[data-theme="rs3"] body{background-image:
  radial-gradient(1100px 460px at 50% -90px,var(--theme-soft),transparent 68%),
  linear-gradient(180deg,color-mix(in srgb,var(--page) 88%,var(--theme-accent) 12%),var(--page) 31%,#010304)}

.hdr{background:linear-gradient(180deg,var(--chrome-top),var(--chrome-bottom));
  border-bottom-color:color-mix(in srgb,var(--theme-accent) 46%,var(--line));
  box-shadow:inset 0 1px 0 rgba(220,241,252,.08),0 1px 0 rgba(0,0,0,.8),0 10px 28px -17px var(--theme-glow)}
.subbar{background:linear-gradient(180deg,color-mix(in srgb,var(--panel) 92%,var(--theme-accent) 8%),var(--panel));
  border-bottom-color:var(--line);box-shadow:inset 0 1px 0 rgba(220,241,252,.045),0 6px 18px -15px var(--theme-glow)}
.games,.tabs{border:1px solid var(--line);background:var(--inset-bg);
  box-shadow:inset 0 1px 3px rgba(0,0,0,.72),0 1px 0 rgba(255,255,255,.025)}
[data-theme] .tabs :is(button,a).on,[data-theme] .games :is(button,a).on{
  border-color:color-mix(in srgb,var(--theme-accent) 55%,var(--line));
  background:linear-gradient(180deg,color-mix(in srgb,var(--seg-on) 76%,var(--theme-accent) 24%),var(--seg-on));
  color:var(--emph);box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--theme-accent) 28%,transparent),0 0 12px -7px var(--theme-glow)}
:where([data-theme]) button{background-color:var(--panel2);
  background-image:linear-gradient(180deg,rgba(225,244,255,.06),rgba(0,0,0,.24));
  border-color:var(--line);box-shadow:inset 0 1px 0 rgba(225,244,255,.055),0 3px 10px -7px #000}
[data-theme="osrs"] select,[data-theme="osrs"] input,[data-theme="rs3"] select,[data-theme="rs3"] input{
  border-color:var(--line);box-shadow:inset 0 1px 4px rgba(0,0,0,.72)}
input:focus,select:focus{box-shadow:0 0 0 1px var(--theme-line),0 0 15px -5px var(--theme-glow)}
[data-theme="rs3"] input:focus,[data-theme="rs3"] select:focus{
  border-color:var(--theme-accent);box-shadow:0 0 0 1px var(--theme-line),0 0 15px -5px var(--theme-glow)}
[data-theme="rs3"] .hdr{box-shadow:inset 0 1px 0 rgba(211,242,255,.08),0 1px 0 rgba(0,0,0,.82),0 10px 28px -16px var(--theme-glow)}
[data-theme="rs3"] .subbar{box-shadow:inset 0 1px 0 rgba(211,242,255,.05),0 6px 18px -14px var(--theme-glow)}
[data-theme="rs3"] .t-tick,[data-theme="rs3"] .t-lhead,[data-theme="rs3"] .t-search{
  border-image:linear-gradient(90deg,transparent,var(--theme-line) 14%,var(--theme-line) 86%,transparent) 1}
[data-theme="rs3"] .menu .sep{background:linear-gradient(90deg,transparent,var(--theme-accent),transparent)}

:is(.board,.pulse,.cat-tile,.list-card,.sig-head,.wl-table,.perf-t,.perf-card,
  .wy-edit,.wy-admin,.wy-item,.pt-panel,.pt-cards,.list-empty-related,
  #wy-bt-panel:not(:empty)){
  border-color:var(--line);background-color:var(--panel);
  background-image:linear-gradient(180deg,var(--surface-top),var(--surface-bottom));
  box-shadow:var(--edge),0 0 0 1px rgba(0,0,0,.72),var(--sh-1)}
.board .b-head,.pt-head,.search-tools,.catalogue-pager{
  background:linear-gradient(180deg,color-mix(in srgb,var(--panel2) 82%,var(--theme-accent) 18%),var(--panel));
  border-color:var(--line)}
.board .b-head{border-bottom:1px solid var(--row-line)}
.board .b-head b,.page-head h1,.sig-head b{color:var(--emph)}
thead th,[data-theme="osrs"] thead th{
  background:linear-gradient(180deg,color-mix(in srgb,var(--panel2) 84%,var(--theme-accent) 16%),var(--panel));
  border-bottom:1px solid var(--line);box-shadow:inset 0 1px 0 rgba(221,242,252,.05)}
tbody td{border-bottom-color:var(--row-line)}
tbody tr:hover td{background-color:var(--row-hover)}
[data-theme] tbody tr:hover td:first-child{box-shadow:inset 2px 0 0 var(--theme-accent)}
:is(.cat-tile,.list-card,.pick,.seo-list-links a):hover{
  border-color:var(--theme-line);background:color-mix(in srgb,var(--hover-bg) 84%,var(--theme-accent) 16%);
  box-shadow:inset 0 1px 0 rgba(229,246,255,.07),0 0 18px -9px var(--theme-glow)}
.cat-tile .ct-i,.mi-ico,.list-directory-featured .list-icon{
  filter:drop-shadow(0 4px 7px rgba(0,0,0,.72)) drop-shadow(0 0 7px var(--theme-glow))}
.catalogue-pager .page-current{color:var(--on-gold);background:var(--theme-accent);
  border-color:var(--theme-accent);box-shadow:0 0 14px -6px var(--theme-glow)}
.site-foot{background:linear-gradient(180deg,rgba(3,8,11,.86),rgba(1,4,6,.98));
  border-top-color:color-mix(in srgb,var(--line) 76%,var(--theme-accent) 24%)}
.ad-placeholder{background:color-mix(in srgb,var(--inset-bg) 90%,var(--theme-accent) 10%);
  border-color:color-mix(in srgb,var(--line-strong) 72%,var(--theme-accent) 28%)}

/* Home deliberately shows both identities at once, independent of whichever
   game was last open. Its shell therefore owns a neutral blue-black chrome. */
:root[data-page="home"] body{background:#02070a;background-image:
  radial-gradient(900px 350px at 72% 90px,rgba(0,173,255,.09),transparent 66%),
  radial-gradient(760px 300px at 24% 250px,rgba(255,177,34,.075),transparent 72%),
  linear-gradient(180deg,#061016,#020609 72%,#010305)}
:root[data-page="home"] .hdr{background:linear-gradient(180deg,#0b1820,#040a0e);
  border-bottom-color:#244555;box-shadow:inset 0 1px 0 rgba(208,240,255,.08),0 8px 26px -16px rgba(0,186,255,.28)}
.home-landing{--home-gold:#ffc23e;--home-bright:#ffe49a;--home-blue:#28c9ff;
  --home-line:rgba(108,157,180,.42);--home-panel:#061016;color:#f1eee6}
.home-hero{border-color:#214353;box-shadow:inset 0 1px 0 rgba(215,242,255,.07),0 18px 46px -30px rgba(0,167,235,.32)}
.home-hero::after{background:linear-gradient(90deg,transparent,#ffbd35 36%,#36ccff 72%,transparent)}
.home-updatebar{background:linear-gradient(180deg,#0b171e,#050b0f);border-color:#2a4c5c;color:#93a6ae}
.home-osrs-column .home-updatebar{border-color:rgba(255,190,54,.58);background:linear-gradient(180deg,#171407,#080a07)}
.home-rs3-column .home-updatebar{border-color:rgba(39,201,255,.62);background:linear-gradient(180deg,#08202b,#050d13)}
.home-game{box-shadow:inset 0 1px 0 rgba(229,247,255,.075),0 0 0 1px rgba(0,0,0,.8),0 16px 32px -22px #000}
.home-osrs{border-color:rgba(255,190,54,.64);background:radial-gradient(circle at 82% 38%,rgba(255,174,28,.14),transparent 39%),linear-gradient(105deg,#161307,#080a08 72%,#101007)}
.home-rs3{border-color:rgba(39,201,255,.64);background:radial-gradient(circle at 82% 38%,rgba(39,201,255,.15),transparent 39%),linear-gradient(105deg,#071b25,#050b10 72%,#06131a)}
.home-game-copy strong{color:#ffe7a7}.home-rs3 .home-game-copy strong{color:#a8ebff}
.home-game-actions a{border-color:rgba(255,194,62,.57);color:#f6cc6d;background:linear-gradient(180deg,rgba(52,38,7,.82),rgba(8,8,5,.9));box-shadow:inset 0 1px 0 rgba(255,239,192,.08)}
.home-rs3 .home-game-actions a{border-color:rgba(39,201,255,.58);color:#a9e9ff;background:linear-gradient(180deg,rgba(5,45,62,.86),rgba(3,10,15,.92));box-shadow:inset 0 1px 0 rgba(194,238,255,.08)}
.home-value-panel{border-color:#285064;background:linear-gradient(180deg,#07141b,#03090d);box-shadow:inset 0 1px 0 rgba(215,242,255,.065),0 0 0 1px #010405,0 18px 34px -26px rgba(0,174,241,.28)}
.home-value-head{border-bottom-color:#1e4252;background:linear-gradient(180deg,#0b1a22,#061016)}
.home-value-head h2{color:#f3e4bf}.home-value-head p{color:#93a6af}.home-value-head .home-coverage-note{color:#b8c4c8}
.home-range-tabs button,.home-view-tabs button{border-color:#294757;background:#061017;color:#8fa5af}.home-range-tabs button:hover,.home-range-tabs button.on,.home-view-tabs button:hover,.home-view-tabs button.on{border-color:#f0b832;background:#271c04;color:#ffd66d;box-shadow:0 0 13px -7px rgba(255,190,54,.65)}
.home-chart-legend button{color:#99a8ae}.home-value-grid line{stroke:rgba(81,142,168,.22)}.home-value-grid text,.home-axis-title{fill:#839aa5}
.home-series-osrs{stroke:#ffc23e;fill:#ffc23e}.home-series-rs3{stroke:#28c9ff;fill:#28c9ff}.home-series-osrs-tax{stroke:#ffe29a;fill:#ffe29a}.home-series-rs3-tax{stroke:#a2eaff;fill:#a2eaff}
.home-value-cards article{border-color:#34515e;background:linear-gradient(105deg,#0d171c,#050b0f);box-shadow:inset 0 1px 0 rgba(222,244,255,.07),0 0 0 1px rgba(0,0,0,.76),0 10px 24px -19px #000}
.home-value-cards article.osrs{border-color:rgba(255,190,54,.65);background:radial-gradient(circle at 8% 50%,rgba(255,184,38,.14),transparent 36%),linear-gradient(105deg,#171407,#080a08)}
.home-value-cards article.rs3{border-color:rgba(39,201,255,.68);background:radial-gradient(circle at 8% 50%,rgba(39,201,255,.15),transparent 36%),linear-gradient(105deg,#07202b,#040b10)}
.home-metric-title{color:#ffd87d}.home-value-cards .rs3 .home-metric-title{color:#9fe8ff}.home-metric-value{color:#ffd36b}.home-value-cards .rs3 .home-metric-value{color:#48d3ff}.home-metric-meta{color:#afa183}.home-value-cards .rs3 .home-metric-meta{color:#84adbf}

@media(min-width:641px){
  :is(.board,.pulse,.cat-tile,.list-card,.sig-head,.wl-table,.perf-t,.perf-card,
    .wy-edit,.wy-admin,.pt-panel,.pt-cards>div){border-radius:4px}
  .cat-tile,.list-card{outline:1px solid rgba(0,0,0,.42);outline-offset:-2px}
}

/* Signed-out/private empty states are still product surfaces. Framing these
   prevents a large pure-black hole on otherwise structured pages, while the
   soft center glow keeps the mascot and single call to action dominant. */
.gate{
  border:1px solid var(--line);border-radius:var(--r-3);
  background:
    radial-gradient(520px 250px at 50% 46%,var(--theme-soft),transparent 72%),
    linear-gradient(180deg,var(--surface-top),var(--surface-bottom));
  box-shadow:var(--edge),0 0 0 1px rgba(0,0,0,.72),var(--sh-2)}
[data-theme="osrs"] .gate{border-color:color-mix(in srgb,var(--line) 78%,var(--theme-accent) 22%)}
[data-theme="rs3"] .gate{border-color:color-mix(in srgb,var(--line) 72%,var(--theme-accent) 28%)}
