  :root{
    --night:#1a120c; --panel:#241a12; --panel2:#31241a; --line:#54402a;
    --parch:#efe3c2; --ink:#e6dbc9; --dim:#a8977f;
    --brass:#d9a441; --brass-deep:#a4761f;
    --hp:#4caf6d; --mp:#6d8fd0;
    --rare:#5b9bd5; --epic:#a66bd0; --fine:#6dbb6d;
    --display:'Iowan Old Style','Palatino Linotype',Palatino,Georgia,serif;
    --body:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;
    --sidew:420px;
  }
  *{margin:0;padding:0;box-sizing:border-box;-webkit-tap-highlight-color:transparent;touch-action:manipulation}
  html,body{height:100%;overscroll-behavior:none}
  /* iOS Safari: a long-press otherwise pops the blue selection/copy callout over the game */
  body{-webkit-user-select:none;user-select:none;-webkit-touch-callout:none}
  input,textarea{-webkit-user-select:text;user-select:text;-webkit-touch-callout:default}
  /* html carries it too: on iOS the html box is the LARGE viewport, so it is taller than the
     100dvh app whenever the toolbar is showing, and that difference is what peeks out. */
  html{background:url('assets/ui/ui_allt.png') center center/cover no-repeat var(--night)}
  body{background:transparent;color:var(--ink);font-family:var(--body);display:flex;justify-content:center;overflow:hidden}
  /* menu screens live inside the capped app column - paint the artwork across the whole
     window behind them so narrow windows don't show the green body on the sides */
  html:has(#login.open),html:has(#select.open),html:has(#create.open),
  body:has(#login.open),body:has(#select.open),body:has(#create.open){
    background:url('assets/ui/bakground_signin.png') center/cover no-repeat #0d0a07}
  /* ...and stretch the app column to the full page while a menu screen is up, so a phone
     never shows the flat backdrop in the strip 100dvh leaves when Safari's bar hides */
  body:has(#login.open) #app,body:has(#select.open) #app,body:has(#create.open) #app{
    height:100%;min-height:100dvh;
    background:url('assets/ui/bakground_signin.png') center/cover no-repeat #0d0a07}
  /* Wood underneath EVERYTHING. Any strip the layout leaves - the notch band, the
     home-indicator band, the gap 100dvh leaves against the taller html box, the overscroll
     rubber-band - lands on this and shows plank, never a flat colour. It costs one already
     cached image and removes a whole class of "it looks different on my phone". */
  #app{width:100%;max-width:480px;height:100dvh;display:flex;flex-direction:column;position:relative;
    background:url('assets/ui/ui_allt.png') center center/cover no-repeat var(--night)}
  /* the installed-app height fix lives at the very bottom of this file - see STANDALONE */
  /* viewport-fit=cover means the app paints under the notch and the home indicator, so every
     edge-touching bar keeps its own content clear of those bands.
     The plate art carries ~20% of dead dark border along its top edge; anchored to the bottom
     and overscaled, that border is pushed off screen so bare wood runs all the way up. The
     overscale is a plain percentage on purpose - env() inside a calc() multiplication is the
     kind of thing that silently invalidates the whole shorthand on an older iOS, and then the
     header loses its art entirely. 132% crops the border on every device and costs nothing
     where there is no notch, because the art is a texture, not a composition. */
  header{padding:calc(7px + env(safe-area-inset-top,0px)) 14px 6px;border-bottom:none;
    background:url('assets/ui/ui_allt.png') center bottom/100% 132% no-repeat #342011;
    flex:0 0 auto;z-index:5}
  .hrow{display:flex;align-items:center;justify-content:space-between;gap:8px}
  .zone-name{font-family:var(--display);font-size:15.5px;color:var(--parch)}
  .zone-sub{font-size:9px;color:var(--dim);text-transform:uppercase;letter-spacing:1.4px;margin-top:1px}
  .curr{text-align:right}
  .gold{font-size:13px;color:var(--brass);font-weight:600;white-space:nowrap}
  .gold::before{content:'◉ ';font-size:10px}
  .scrap{font-size:11px;color:#a8bcb0;font-weight:600;white-space:nowrap;margin-top:1px}
  .scrap::before{content:'⚙ ';font-size:10px}
  .vrow{margin-top:6px;display:flex;align-items:center;gap:8px}
  .lvl{font-family:var(--display);font-size:12px;color:var(--parch);white-space:nowrap;min-width:42px}
  .bar{flex:1;height:6px;border-radius:4px;background:#0d1512;overflow:hidden;border:1px solid #0a100d}
  .bar>i{display:block;height:100%;border-radius:4px;transition:width .25s}
  .bar.xp>i{background:linear-gradient(90deg,#8a6fb0,#b08ad0)}
  .bar.hp>i{background:linear-gradient(90deg,#3a8a55,var(--hp))}
  .bar.mp>i{background:linear-gradient(90deg,#4b6bb0,var(--mp))}
  .vlab{font-size:9px;color:var(--dim);width:20px;text-align:right}
 
  #stageWrap{flex:1 1 auto;position:relative;min-height:0}
  canvas#game{position:absolute;inset:0;width:100%;height:100%;display:block;touch-action:none}
  #ticker{position:absolute;left:8px;right:60px;bottom:4px;pointer-events:none;font-size:10.5px;line-height:1.45;color:#eef4ea;text-shadow:0 1px 3px rgba(0,0,0,.85)}
  #ticker .imp{color:var(--parch)} #ticker .loot{color:var(--brass)}
  #ticker .lrare{color:#8fc3ef} #ticker .lepic{color:#c9a0ea} #ticker .lfine{color:#9adf9a} #ticker .lscroll{color:#e8c9ef} #ticker .llegendary{color:#7fd7ff}
  #hint{position:absolute;top:6px;left:0;right:0;text-align:center;pointer-events:none;font-size:10px;color:#fff;opacity:.85;text-shadow:0 1px 3px rgba(0,0,0,.8);transition:opacity 1s}
  #stagemsg{position:absolute;top:24px;left:0;right:0;text-align:center;pointer-events:none;font-family:var(--display);font-size:14px;color:var(--parch);text-shadow:0 1px 4px rgba(0,0,0,.9);opacity:0;transition:opacity .4s;padding:0 20px}
  #stagemsg.bigblink{font-size:26px;letter-spacing:1.5px;animation:msgblink .55s ease-in-out infinite}
  @keyframes msgblink{50%{opacity:.5}}
  #stagemsg.show{opacity:1}
  .stgbtn{position:absolute;right:8px;width:32px;height:32px;border-radius:8px;border:1px solid rgba(255,255,255,.25);background:rgba(10,18,14,.55);color:#fff;font-size:15px;cursor:pointer;z-index:6}
  #sndBtn{top:6px} #cfgBtn{top:44px;font-size:15px}
  #musBtn{top:82px;font-size:13px}
  #sideToggle{top:120px;height:64px;width:22px;padding:0;font-size:11px;display:none;align-items:center;justify-content:center}
  .stgbtn.off{opacity:.45}
  /* ⚙ Settings is a panel in the middle of the screen now, on the same .casinobox the smith and the
     other venues use, rather than a popover tucked under its own button. It is where the player
     leaves the game from, so it should feel like somewhere you arrive, not a tooltip. */
  /* fixed, not absolute: opened from the character screen the panel used to centre itself inside
     #stageWrap, which is only part of the window there, so it sat off to one side. Against the
     viewport it lands in the middle wherever it is opened from. No dimming behind it. */
  #cfgBox{position:fixed;inset:0;z-index:72;display:none;align-items:center;justify-content:center;
          padding:16px;box-sizing:border-box}
  #cfgBox.open{display:flex}
  #cfgBox .casinobox{background:linear-gradient(180deg,rgba(30,22,14,.80),rgba(14,10,6,.92)),url('assets/ui/modal_settings.png') center/cover no-repeat}
  #cfgBox .cfgrow{width:100%}
  #cfgBox .cfgrow input[type=range]{flex:1}
  #cfgBox .cfgrow>span{min-width:78px;text-align:left}
  /* Audio / Video as two tabs. Only one pane is ever in the flow, so the panel is the height of what
     it is showing rather than the height of everything it could show. */
  .cfgtabs{display:flex;flex-direction:column;gap:7px;margin-bottom:12px} /* stacked, Audio first */
  .cfgtab{width:100%;padding:9px 10px;border-radius:9px;border:1px solid var(--line);background:rgba(0,0,0,.28);
          color:var(--dim);font-family:inherit;font-size:13px;letter-spacing:.4px;cursor:pointer;transition:all .15s}
  .cfgtab:hover{color:var(--parch)}
  .cfgtab.on{border-color:var(--brass);background:linear-gradient(180deg,#3a2a1c,#221610);color:var(--brass)}
  .cfgpane{display:none;flex-direction:column;gap:8px}
  .cfgpane.on{display:flex}
  #cfgBox select{flex:1;padding:6px 8px;border-radius:7px;border:1px solid var(--line);
                 background:#241a12;color:var(--parch);font-family:inherit;font-size:12px;cursor:pointer}
  /* Controls: the keyboard is illustration, the list below it is the truth. Generated art cannot be
     trusted to letter a dozen keycaps correctly, and a controls screen that lies is worse than none -
     so the caps are blank in the picture and every binding is written out in real text. */
  .kbdart{width:100%;border-radius:9px;border:1px solid var(--line);margin-bottom:10px;display:block}
  .kbdlist{display:grid;grid-template-columns:auto 1fr;gap:5px 10px;align-items:center;
           max-height:38vh;overflow-y:auto}
  .kbdlist kbd{justify-self:start;padding:3px 7px;border-radius:5px;border:1px solid var(--brass-deep);
               background:linear-gradient(180deg,#3a2a1c,#221610);color:var(--brass);
               font:600 11px/1.35 ui-monospace,Consolas,monospace;white-space:nowrap;
               box-shadow:0 1px 0 rgba(0,0,0,.6)}
  .kbdlist span{color:var(--parch);font-size:12px}
  .kbdlist .kbdhead{grid-column:1/-1;color:var(--dim);font-size:10.5px;letter-spacing:.6px;
                    text-transform:uppercase;margin-top:6px}
  .kbdlist .kbdhead:first-child{margin-top:0}
  .cfgrow{display:flex;align-items:center;gap:9px;color:#e9e0cf;font-size:12px;cursor:pointer;user-select:none}
  .cfgrow>span{min-width:52px}      /* the two labels line their sliders up with each other */
  .cfgrow input[type=range]{width:118px;accent-color:var(--brass)}
  .cfgrow b{min-width:24px;text-align:right;font-weight:600;color:var(--brass);font-variant-numeric:tabular-nums}
  .cfgchk input{width:15px;height:15px;accent-color:var(--brass);cursor:pointer}
  .cfgsep{height:1px;background:rgba(255,255,255,.16);margin:1px 0}
  .cfgnote{color:var(--dim);font-size:10.5px;margin:-4px 0 0 24px} /* sits under its checkbox, aligned past the box */
  .cfgexit{width:100%;padding:7px 10px;border-radius:8px;border:1px solid #8e3a30;background:linear-gradient(180deg,#7a2f26,#4d1c17);
           color:#ffd9d2;font-family:inherit;font-size:12px;font-weight:600;cursor:pointer}
  .cfgexit:hover{background:linear-gradient(180deg,#93392e,#5d221b)}
  /* Native scrollbars are a grey Windows slab bolted onto painted wood. Hidden, not disabled -
     wheel, touch, drag and the keyboard all still scroll; only the chrome goes. */
  #app *::-webkit-scrollbar{width:0;height:0}
  #app *{scrollbar-width:none}
  /* FPS readout - left side, and pointer-events:none so it can never swallow a click on the world */
  #fps{position:absolute;left:8px;top:6px;z-index:6;color:#fff;font:600 12px/1 ui-monospace,Consolas,monospace;
       text-shadow:0 1px 3px rgba(0,0,0,.85);pointer-events:none}
 

  #skillbar{position:absolute;bottom:22px;left:50%;transform:translateX(-50%);display:flex;gap:7px;align-items:flex-end;z-index:6}
  #farmCheckBtn{position:absolute;bottom:84px;left:50%;transform:translateX(-50%);width:52px;height:44px;border-radius:11px;border:1px solid var(--brass);background:linear-gradient(180deg,#3a2a1c,#221610);font-size:20px;cursor:pointer;display:none;align-items:center;justify-content:center;z-index:6;box-shadow:0 0 12px rgba(217,164,65,.4)}
  #farmCheckBtn .cnt{position:absolute;top:1px;right:5px;font-size:10px;color:#ffd76a;font-weight:700;text-shadow:0 1px 2px #000}
  #farmSnapBtn{position:absolute;bottom:84px;left:50%;transform:translateX(calc(-50% - 62px));width:52px;height:44px;border-radius:11px;border:1px solid #6a4a2a;background:linear-gradient(180deg,#3a2a1c,#221610);font-size:20px;cursor:pointer;display:none;align-items:center;justify-content:center;z-index:6;opacity:.55}
  #farmSnapBtn.on{border-color:var(--brass);opacity:1;box-shadow:0 0 12px rgba(217,164,65,.4)}
  #farmHarvBtn{position:absolute;bottom:84px;left:50%;transform:translateX(calc(-50% + 62px));width:52px;height:44px;border-radius:11px;border:1px solid #6a4a2a;background:linear-gradient(180deg,#3a2a1c,#221610);font-size:20px;cursor:pointer;display:none;align-items:center;justify-content:center;z-index:6;opacity:.55}
  #farmHarvBtn.on{border-color:var(--brass);opacity:1;box-shadow:0 0 12px rgba(217,164,65,.4)}
  .fsitem{position:relative}
  .fscnt{position:absolute;top:4px;right:6px;font-size:12px;font-weight:800;color:#ffd76a;text-shadow:0 1px 3px #000;pointer-events:none}
  #farmStore{transition:transform .25s ease}
  #farmStore.collapsed{transform:translateX(-100%)}
  #fsCollapse{position:absolute;right:-20px;top:50%;transform:translateY(-50%);width:20px;height:58px;border:1px solid #6a4a2a;border-left:none;border-radius:0 10px 10px 0;background:rgba(22,15,9,.94);color:#e8c9a0;font-size:11px;cursor:pointer;padding:0;z-index:66}
  #fishBtn{position:absolute;bottom:84px;left:50%;transform:translateX(-50%);width:44px;height:44px;border-radius:11px;border:1px solid var(--brass-deep);background:linear-gradient(180deg,#3a2a1c,#221610);font-size:20px;cursor:pointer;display:none;align-items:center;justify-content:center;z-index:6;box-shadow:0 2px 8px rgba(0,0,0,.5)}
  #fishBtn.on{border-color:var(--brass);box-shadow:0 0 12px rgba(217,164,65,.5);animation:pulseNext 1.6s infinite}
  #fishBtn .cnt{position:absolute;top:1px;right:4px;font-size:9px;color:#fff;font-weight:700;text-shadow:0 1px 2px #000}
  #torchBtn{position:absolute;bottom:84px;left:50%;transform:translateX(-50%);width:44px;height:44px;border-radius:11px;border:1px solid var(--brass-deep);background:linear-gradient(180deg,#3a2a1c,#221610);font-size:20px;cursor:pointer;display:none;align-items:center;justify-content:center;z-index:6;box-shadow:0 2px 8px rgba(0,0,0,.5)}
  #torchBtn:disabled{opacity:.4;cursor:default}
  #torchBtn .cnt{position:absolute;top:1px;right:4px;font-size:9px;color:#ffd76a;font-weight:700;text-shadow:0 1px 2px #000}
  #fishToast{position:absolute;bottom:136px;left:50%;transform:translateX(-50%);padding:8px 18px;border-radius:9px;border:1px solid rgba(210,175,130,.55);background:#221610;color:var(--parch);font-family:var(--display);font-size:13px;z-index:6;display:none;text-align:center;box-shadow:0 2px 10px rgba(0,0,0,.5);white-space:nowrap}
  .skill{position:relative;width:46px;height:46px;border-radius:11px;border:1px solid var(--brass-deep);background:linear-gradient(180deg,#3a2a1c,#221610);color:var(--parch);font-size:19px;cursor:pointer;overflow:hidden;box-shadow:0 2px 8px rgba(0,0,0,.5)}
  .skill .spicon{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;pointer-events:none}
  .btnico{width:78%;height:78%;object-fit:contain;pointer-events:none;filter:drop-shadow(0 1px 2px rgba(0,0,0,.6))}
  .lootico{width:1.05em;height:1.05em;object-fit:contain;vertical-align:middle;pointer-events:none}
  .shopico{width:22px;height:22px;object-fit:contain;vertical-align:-5px;margin-right:3px;pointer-events:none;border-radius:4px}
  .autocfg-btn .btnico{width:80%;height:80%;object-fit:contain;pointer-events:none}
  .spellg .spicon{width:100%;height:100%;object-fit:cover;border-radius:8px}
  .skill .cdm{position:absolute;left:0;right:0;bottom:0;background:rgba(10,7,4,.78);height:0%;pointer-events:none}
  .skill .cost{position:absolute;bottom:1px;right:3px;font-size:8.5px;color:#9fb4e8;font-weight:700;text-shadow:0 1px 2px #000}
  .skill.nomana{filter:saturate(.3) brightness(.7)}
  .skill.pot{border-color:var(--brass-deep);font-size:17px}
  /* ⛏ half the size of a spell button, as asked - it is a toggle you set and forget, not something
     you reach for mid-fight, so it should not compete with the potions for the thumb. */
  .skill.mine{width:32px;height:32px;border-radius:8px;align-self:flex-end;margin-bottom:2px}
  .skill.mine.on{border-color:#e8c06a;box-shadow:0 0 9px rgba(232,192,106,.65)}
  /* the mining hall and the smelter reuse the smith's panel and forge slots rather than inventing
     their own - one modal shape across every venue in the game */
  .fmico{width:34px;height:34px;object-fit:contain;border-radius:6px}
  .fmslot .fmn{position:absolute;bottom:2px;right:5px;font-size:11px;font-weight:600;color:var(--parch);text-shadow:0 1px 2px #000}
  .fmslot{position:relative}
  .skill .cnt{position:absolute;top:1px;right:3px;font-size:9px;color:#fff;font-weight:700;text-shadow:0 1px 2px #000}
  .sep{width:1px;height:36px;background:rgba(255,255,255,.18);margin:0 2px 5px}
  /* auto-cast config: the small Ⓐ between spells and potions */
  .autocfg-btn{position:relative;display:flex;align-items:center;justify-content:center;padding:0;overflow:hidden;width:30px;height:30px;border-radius:8px;border:1px solid var(--brass-deep);background:linear-gradient(180deg,#3a2a1c,#221610);color:var(--brass);font-size:14px;font-weight:800;cursor:pointer;align-self:center;margin:0 2px;box-shadow:0 2px 6px rgba(0,0,0,.5)}
  #skillbar.autocfg .autocfg-btn{border-color:var(--brass);color:#ffd76a;box-shadow:0 0 10px rgba(217,164,65,.5)}
  #skillbar.autocfg .skill:not(.autocfg-btn){filter:brightness(.5) saturate(.55)}
  .skill .au{position:absolute;inset:0;display:none;align-items:center;justify-content:center;font-size:22px;font-weight:900;pointer-events:none;text-shadow:0 1px 4px #000;z-index:3}
  #skillbar.autocfg .skill .au{display:flex}
  .skill .au.on{color:#39ff6a}
  .skill .au.offx{color:#ff5a5a}
 
  #questcard{margin:7px 10px;padding:8px 14px;background:url('assets/ui/ui_allt.png') center/100% 100% no-repeat;border:none;border-radius:10px;flex:0 0 auto}
  .qtop{display:flex;justify-content:space-between;align-items:center;gap:10px}
  .qname{font-family:var(--display);font-size:13px;color:var(--parch)}
  .qdesc{font-size:10.5px;color:var(--dim);margin-top:1px}
  .qprog{display:flex;align-items:center;gap:8px;margin-top:6px}
  .bar.q>i{background:linear-gradient(90deg,var(--brass-deep),var(--brass))}
  .qcount{font-size:11px;color:var(--brass);white-space:nowrap;font-weight:600}
  .qbtns{display:flex;flex-direction:column;gap:5px;flex:0 0 auto}
  #autoBtn,#nextBtn{font-family:var(--display);font-size:12px;letter-spacing:.5px;padding:7px 13px;border-radius:9px;border:1px solid var(--brass-deep);background:linear-gradient(180deg,#332519,#241a12);color:var(--brass);cursor:pointer;transition:all .2s;white-space:nowrap}
  #autoBtn.on{background:linear-gradient(180deg,var(--brass),var(--brass-deep));color:#20180a;border-color:var(--brass);box-shadow:0 0 14px rgba(217,164,65,.35)}
  #nextBtn{display:none;border-color:#6dbb6d;color:#9adf9a;animation:pulseNext 2s infinite}
  @keyframes pulseNext{0%,100%{box-shadow:0 0 4px rgba(109,187,109,.2)}50%{box-shadow:0 0 12px rgba(109,187,109,.5)}}
 
  /* the panel tucks 12px under the nav plate on purpose, but the plate now also spans the
     home-indicator band - so lift the panel by that inset too, and pad the scroll end past
     the tucked-under strip or the last item/leaderboard row can never be reached */
  /* inset:0 puts the panel's top edge at the very top of the app, which now reaches under
     the clock - so the hero name and every panel heading need the notch inset too */
  .panel{position:absolute;inset:0;bottom:calc(56px + env(safe-area-inset-bottom,0px));z-index:20;display:none;background:url('assets/ui/ui_allt.png') center/100% 100% no-repeat;overflow-y:auto;padding:calc(14px + env(safe-area-inset-top,0px)) 14px 30px}
  .panel.open{display:block}
  .ptitle{font-family:var(--display);font-size:19px;color:var(--parch);margin-bottom:12px}
  /* bag section headings - same weight as the Scrolls and Gear headings further down */
  .bagcat{font-size:14px;margin:16px 0 8px}
  .bagcat:first-child{margin-top:0}
  .card{background:var(--panel);border:1px solid var(--line);border-radius:10px;padding:12px;margin-bottom:10px}
  #p-hero .card{background:rgba(128,95,62,.38);border:1px solid rgba(165,128,90,.45)} /* light-brown cards on the panel art */
  #p-hero .sbtn{background:#221610;border-color:rgba(140,105,70,.5)} /* dark-brown action buttons */
  .statgrid{display:grid;grid-template-columns:1fr 1fr;gap:8px;margin-top:4px}
  .stat{background:#31221a;border:1px solid rgba(150,112,74,.35);border-radius:8px;padding:10px 14px}
  .stat b{display:block;font-size:15px;color:var(--parch)}
  .stat span{font-size:10px;color:var(--dim);text-transform:uppercase;letter-spacing:1px}
  .slotrow{display:flex;gap:8px;margin-top:10px}
  #scrollRow{margin-top:8px}
  .slot{flex:1;background:#31221a;border:1px dashed rgba(150,112,74,.45);border-radius:8px;padding:10px 14px;min-height:64px;font-size:11px;display:flex;flex-direction:column;min-width:0;overflow:hidden}
  .slot .sn,.slot .ss,.slot .en{overflow-wrap:anywhere} /* long names/stat lines wrap instead of spilling out */
  .slot .sn{font-weight:600}
  .slot .ss{color:var(--dim);font-size:10px;margin-top:2px}
  .slot .en{color:#d9a0ef;font-size:10px;margin-top:2px}
  .upbtn{margin-top:auto;padding:4px 6px;font-size:9.5px;border-radius:6px;border:1px solid rgba(140,105,70,.4);background:#221610;color:#cfc0a8;cursor:pointer}
  .upbtn.can{border-color:var(--brass-deep);color:var(--brass)}
  .r-common{color:var(--ink)} .r-fine{color:var(--fine)} .r-rare{color:var(--rare)} .r-epic{color:var(--epic)} .r-legendary{color:#7fd7ff;text-shadow:0 0 8px rgba(111,208,255,.55)}
  .zonecard{display:flex;align-items:center;gap:12px;cursor:pointer}
  .zonecard.locked{opacity:.45;cursor:default}
  .zonecard.active{border-color:var(--brass)}
  .zdot{width:44px;height:44px;border-radius:9px;flex:0 0 auto;border:1px solid rgba(0,0,0,.3);display:flex;align-items:center;justify-content:center;font-size:18px}
  .zinfo{flex:1}
  .zn{font-family:var(--display);font-size:14px;color:var(--parch)}
  .zl{font-size:10.5px;color:var(--dim);margin-top:2px}
  .ztag{font-size:10px;color:var(--brass);border:1px solid var(--brass-deep);border-radius:5px;padding:2px 7px;white-space:nowrap;background:#221610}
  #p-map .card,#p-shop .card,#p-bag .card{background:rgba(80,58,38,.55);border-color:rgba(165,128,90,.4)} /* brown zone/shop/bag cards */
  #p-map .sbtn,#p-shop .sbtn,#p-bag .sbtn{background:#221610;border-color:rgba(140,105,70,.5)} /* dark-brown action buttons */
  .ztag.boss{color:#e88a8a;border-color:#8a4a4a}
  .ztag.done{color:#9adf9a;border-color:#4a6a4a}
  .continent-tab{display:inline-block;font-family:var(--display);font-size:13px;padding:6px 14px;border-radius:8px;border:1px solid rgba(210,175,130,.55);background:#221610;color:#cfc0a8;margin:0 8px 12px 0;cursor:pointer;user-select:none}
  .continent-tab.cur{color:var(--parch);border-color:#e8c987;background:#31221a;box-shadow:0 0 8px rgba(217,164,65,.25)}
  .continent-tab:not(.cur):hover{color:var(--parch)}
  .item{display:flex;justify-content:space-between;align-items:center;gap:10px}

  /* even-sized gamble cards */
  .gcard-chest{min-height:126px}
  .gcard-slot{min-height:96px}
  .gcard-chest>div:first-child,.gcard-slot>div:first-child{flex:1}
  .item .btns{display:flex;gap:6px;flex-wrap:wrap;justify-content:flex-end}
  .sbtn{font-size:11px;padding:6px 11px;border-radius:7px;cursor:pointer;border:1px solid var(--line);background:var(--panel2);color:var(--ink)}
  .sbtn.gold{border-color:var(--brass-deep);color:var(--brass)}
  .sbtn.scrapb{border-color:#4a6a55;color:#a8bcb0}
  .sbtn:disabled{opacity:.4;cursor:default}
  .toggle-row{display:flex;justify-content:space-between;align-items:center;font-size:12.5px}
  .spellcard{display:flex;gap:10px;align-items:center}
  /* ⛏ the mining track, styled off the spell card it sits under. The count rides inside the bar
     rather than beside it so the row stays the same height as the spells above it. */
  .minebar{position:relative;height:15px;margin-top:5px;border-radius:8px;overflow:hidden;
           background:rgba(0,0,0,.34);border:1px solid rgba(120,170,220,.30)}
  .minebar i{display:block;height:100%;border-radius:8px;
             background:linear-gradient(180deg,#6fb3ef,#2f6fb5);transition:width .35s ease}
  .minebar b{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;
             font-size:10.5px;font-weight:600;color:#eaf3ff;text-shadow:0 1px 2px rgba(0,0,0,.8)}
  .spellg{width:36px;height:36px;border-radius:9px;background:#2a1d13;border:1px solid var(--brass-deep);display:flex;align-items:center;justify-content:center;font-size:17px;flex:0 0 auto}
  .glowdot{display:inline-block;width:8px;height:8px;border-radius:50%;margin-right:5px;vertical-align:middle}
  .wallet{font-size:12px;color:var(--dim);margin:-6px 0 12px}
  .wallet b{color:var(--brass)} .wallet i{color:#a8bcb0;font-style:normal}
 
  /* the bar grows downward into the home-indicator band, but the plate art and the buttons
     both stay pinned to the top 68px so Home/Bag never drift upward off the plate */
  nav{flex:0 0 auto;height:calc(68px + env(safe-area-inset-bottom,0px));display:flex;border-top:none;padding:0 30px env(safe-area-inset-bottom,0px);justify-content:center;background:url('assets/ui/ui_buttons.png') top center/100% 68px no-repeat,url('assets/ui/ui_allt.png') center/cover no-repeat;z-index:30}
  nav button{flex:0 1 auto;padding:0 16px;background:none;border:none;color:var(--dim);cursor:pointer;font-size:11px;letter-spacing:.5px;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:4px;font-family:var(--body)}
  nav button svg{width:24px;height:24px;stroke:currentColor;fill:none;stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round}
  nav button.cur{color:var(--brass)}
  /* Belt and braces with the blur() in the click handler: the tab already shows which one is
     current in brass, so the browser's ring adds nothing but a white box over the artwork. */
  nav button:focus{outline:none}
  nav button:focus-visible{outline:none}
 
  #create{position:absolute;inset:0;z-index:50;display:none;flex-direction:column;
    padding:calc(26px + env(safe-area-inset-top,0px)) 22px calc(26px + env(safe-area-inset-bottom,0px));overflow-y:auto;
    background:
      linear-gradient(rgba(8,14,11,.35),rgba(8,14,11,.5)),
      url('assets/ui/bakground_signin.png') center/cover no-repeat;
  }
  #create h1{font-family:var(--display);font-size:27px;color:var(--parch);text-shadow:0 2px 12px rgba(217,164,65,.25)}
  #create .tag{color:var(--dim);font-size:12px;margin:4px 0 16px;letter-spacing:1.5px;text-transform:uppercase}
  #create label{font-size:11px;color:var(--dim);text-transform:uppercase;letter-spacing:1.2px;display:block;margin:13px 0 7px}
  /* ✍️ The name field wears the same plate as the buttons, but cut as a 9-slice instead of
     stretched to fit. The plate is drawn 1484x344 and this bar is 760x60, so filling it squeezed the
     art 3x harder vertically than horizontally - which is what pulled the rounded ends and their
     arrows out of shape. Slicing 180px in from each end and 45/55 off the rails lets both end
     fittings keep their own size, and only the flat rail between them follows the width. The 48px
     side borders against 12px top and bottom is the ratio that scales the ends evenly - 180/45.
     The middle is a flat plate in the plate's own colour rather than the picture's centre, which
     at this width would read as a smeared texture. */
  #cname{width:100%;padding:8px 20px;background:transparent;border:12px solid transparent;border-left-width:48px;border-right-width:48px;border-image:url('assets/ui/ui_buttons.png') 45 180 55 180 fill stretch;color:var(--parch);font-size:15px;font-family:var(--display);text-shadow:0 1px 2px rgba(0,0,0,.7)}
  #cname:focus{outline:none;filter:brightness(1.15)}
  #cname.nameerr{border-color:#ff5a5a;box-shadow:0 0 10px rgba(255,90,90,.35);animation:nameshake .3s}
  #cname.nameerr::placeholder{color:#ff8a7a}
  @keyframes nameshake{25%{transform:translateX(-5px)}75%{transform:translateX(5px)}}
  /* AWOOOOGAAAAA: unmissable pulsing gold frame when prestige is ready */
  #prestigeBtn{border:2px solid #ffd76a;animation:awoogaGlow 1.4s ease-in-out infinite}
  @keyframes awoogaGlow{0%,100%{box-shadow:0 0 8px rgba(255,215,106,.4)}50%{box-shadow:0 0 24px rgba(255,215,106,.9),0 0 40px rgba(255,180,60,.35)}}
  /* the translucent rename pencil next to the hero title */
  #renameBtn,#nameEyeBtn{background:none;border:none;cursor:pointer;opacity:.4;font-size:13px;padding:0 2px;vertical-align:middle;transition:opacity .15s}
  #renameBtn:hover,#nameEyeBtn:hover{opacity:1}
  #nameEyeBtn{opacity:.72}     /* sits brighter than the pencil - it is a state you can leave switched on */
  #nameEyeBtn.off{opacity:.32} /* the eye dims rather than swapping glyph - one icon, so the button never jumps width */
  #nameEyeBtn.off:hover{opacity:1} /* .off and :hover tie on specificity, so without this the later one wins and a hidden eye never lights up */
  .pickgrid{display:grid;grid-template-columns:1fr 1fr;gap:8px}
  .pick{background:url('assets/ui/ui_buttons.png') center/100% 100% no-repeat;border:none;border-radius:10px;padding:17px 38px;cursor:pointer;transition:filter .15s}
  .pick:hover{filter:brightness(1.12)}
  .pick.sel{filter:brightness(1.3);box-shadow:0 0 14px rgba(217,164,65,.5)}
  #classPick .pick{background-image:url('assets/ui/ui_buttonsstone.png?v=2')} /* stone plate for the classes */
  .pick b{font-family:var(--display);font-size:14px;color:var(--parch);display:block}
  .rangetag{float:right;font-family:var(--body);font-size:9px;font-weight:700;letter-spacing:1px;padding:2px 7px;border-radius:20px;vertical-align:middle}
  .rangetag.rng{color:#8fc3ef;border:1px solid rgba(143,195,239,.45);background:rgba(91,155,213,.12)}
  .rangetag.mle{color:#e8b06a;border:1px solid rgba(232,176,106,.45);background:rgba(217,164,65,.12)}
  .pick span{font-size:10.5px;color:var(--dim);line-height:1.4;display:block;margin-top:3px}
  #startBtn,#startHcBtn{margin-top:20px;padding:16px;border-radius:11px;border:none;background:url('assets/ui/ui_buttons.png') center/100% 100% no-repeat;color:#ffd76a;font-family:var(--display);font-size:16px;letter-spacing:1px;cursor:pointer;text-shadow:0 1px 3px rgba(0,0,0,.8)}
  #startBtn:hover,#startHcBtn:hover{filter:brightness(1.18)}
  #startHcBtn{background-image:url('assets/ui/ui_buttonshardcore.png?v=2');color:#ffe0da}
  .fineprint{font-size:10px;color:#5c7263;margin-top:12px;line-height:1.5}
 
  #select,#login{position:absolute;inset:0;z-index:60;display:none;flex-direction:column;
    padding:calc(26px + env(safe-area-inset-top,0px)) 22px calc(18px + env(safe-area-inset-bottom,0px));overflow-y:auto;
    background:
      linear-gradient(rgba(8,14,11,.35),rgba(8,14,11,.5)),
      url('assets/ui/bakground_signin.png') center/cover no-repeat;
  }
  #login{z-index:62;justify-content:center}
  #select.open,#login.open{display:flex}
  #select h1,#login h1{font-family:var(--display);font-size:27px;color:var(--parch);text-shadow:0 2px 12px rgba(217,164,65,.25)}
  #select .tag,#login .tag{color:var(--dim);font-size:12px;margin:4px 0 16px;letter-spacing:1.5px;text-transform:uppercase}
  .charcard{display:flex;align-items:center;gap:12px;background:url('assets/ui/ui_buttonrak.png') center/100% 100% no-repeat;border:none;padding:18px 30px}
  .charcard .portrait{width:64px;height:76px;border-radius:9px;flex:0 0 auto}
  .cinfo{flex:1;min-width:0}
  .cn{font-family:var(--display);font-size:15px;color:var(--parch);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .pstar{color:var(--brass);font-size:11px;margin-left:4px}
  .cl{font-size:10.5px;color:var(--dim);margin-top:2px}
  .cbtns{display:flex;flex-direction:column;gap:6px;align-items:stretch}
  .playbtn{font-family:var(--display);font-size:12px;padding:10px 14px;border-radius:9px;border:none;background:url('assets/ui/ui_buttons.png') center/100% 100% no-repeat;color:#ffd76a;cursor:pointer;white-space:nowrap;text-shadow:0 1px 3px rgba(0,0,0,.8)}
  .playbtn:hover{filter:brightness(1.2)}
  .delbtn{font-size:10px;padding:6px 8px;border-radius:7px;border:none;background:url('assets/ui/ui_buttons.png') center/100% 100% no-repeat;color:#e09a8a;cursor:pointer;text-shadow:0 1px 2px rgba(0,0,0,.8)}
  .delbtn:hover{filter:brightness(1.2)}
  /* same 9-slice trick as the name field: the ends keep their size, only the rail runs the width.
     37px sides against 12px rails is 130/42, the plate's own ratio, so nothing is skewed. */
  #newCharBtn{margin-top:6px;padding:10px;background:transparent;border:12px solid transparent;border-left-width:37px;border-right-width:37px;border-image:url('assets/ui/ui_buttonrak.png') 42 130 45 130 fill stretch;color:var(--brass);font-family:var(--display);font-size:14px;cursor:pointer;text-shadow:0 1px 3px rgba(0,0,0,.8)}
  #newCharBtn:hover{filter:brightness(1.15)}
  /* leaving the game gets the hardcore plate - the one red thing on a brown screen, which is the
     right amount of warning for the button that closes everything. 43/14 is 180/58, its own ratio. */
  #selExitBtn{display:none;width:50%;align-self:center;margin-top:14px;padding:7px;background:transparent;border:14px solid transparent;border-left-width:43px;border-right-width:43px;border-image:url('assets/ui/ui_buttonshardcore.png?v=2') 58 180 58 180 fill stretch;color:#ffe0da;font-family:var(--display);font-size:12px;cursor:pointer;text-shadow:0 1px 3px rgba(0,0,0,.8)}
  #selExitBtn:hover{filter:brightness(1.2)}
  #createBack{align-self:flex-start;margin-bottom:6px;padding:9px 16px;border-radius:8px;border:none;background:url('assets/ui/ui_buttons.png') center/100% 100% no-repeat;color:var(--parch);font-size:11px;cursor:pointer;display:none;text-shadow:0 1px 3px rgba(0,0,0,.8)}
  #createBack:hover{filter:brightness(1.2)}
 
  #chestFx{position:absolute;inset:0;z-index:70;display:none;align-items:center;justify-content:center;flex-direction:column;background:rgba(10,7,4,.84);cursor:default;padding:env(safe-area-inset-top,0px) 0 env(safe-area-inset-bottom,0px);box-sizing:border-box}
  #chestFx.open{display:flex}
  /* --- CS:GO-style case reel --- */
  .casewrap{position:relative;width:min(92vw,560px);height:116px;border:1px solid var(--brass-deep);border-radius:12px;background:linear-gradient(180deg,#101a15,#0a120e);overflow:hidden;box-shadow:0 10px 40px rgba(0,0,0,.6),inset 0 0 30px rgba(0,0,0,.5)}
  .casereel{position:absolute;top:12px;left:0;height:92px;display:flex;gap:8px;will-change:transform}
  .casecard{flex:0 0 84px;height:92px;border-radius:9px;border:1px solid var(--cc,#54402a);background:linear-gradient(180deg,#241a12,#150e08);display:flex;flex-direction:column;align-items:center;justify-content:center;gap:4px}
  .casecard .ci{font-size:26px;filter:drop-shadow(0 0 6px var(--cc))}
  .casecard .cr{font-size:8px;letter-spacing:1.5px;text-transform:uppercase;color:var(--cc)}

  .casecard.gbar{background:linear-gradient(180deg,#3a2a10,#171006);border-color:#ffd76a;box-shadow:0 0 14px rgba(255,215,106,.22),inset 0 0 18px rgba(255,215,106,.12)}
  .casecard.gbar .ci{filter:drop-shadow(0 0 9px #ffd76a)}
  .casecard.gbar .cr{color:#ffd76a}

  .caseqty{display:flex;flex-direction:column;align-items:center;gap:4px;margin-top:5px;font-size:10px;color:var(--dim)}
  .qtyrow{display:flex;align-items:center;justify-content:center;gap:6px}
  .qtybtn{width:23px;height:23px;border-radius:6px;border:1px solid var(--line);background:var(--panel2);color:var(--parch);cursor:pointer;font-weight:700}
  .qtybtn:disabled{opacity:.35;cursor:default}
  .qtybtn.on{border-color:var(--brass);background:linear-gradient(180deg,var(--brass),var(--brass-deep));color:#20180a}
  .qtynum{min-width:18px;text-align:center;color:var(--parch);font-weight:700}
  .qtytotal{white-space:nowrap;color:var(--brass)}
  /* Multi-chest: flex-start + overflow is the only combination that lets you scroll to the top
     when the reels overflow - centring a scrolling flex column clips the first row unreachably.
     The auto margins hand the centring back when the content DOES fit, so a small open sits in
     the middle instead of hugging the notch. env() keeps it clear of the status bar / cutout. */
  #chestFx.multi{justify-content:flex-start;overflow-y:auto;
    padding:calc(14px + env(safe-area-inset-top,0px)) 0 calc(14px + env(safe-area-inset-bottom,0px))}
  #chestFx.multi>:first-child{margin-top:auto}
  #chestFx.multi>:last-child{margin-bottom:auto}
  #chestFx.multi .casewrap{margin-bottom:7px;flex:0 0 auto}
  .caseextra{position:relative;width:min(92vw,560px);height:116px;border:1px solid var(--brass-deep);border-radius:12px;background:linear-gradient(180deg,#101a15,#0a120e);overflow:hidden;box-shadow:0 10px 40px rgba(0,0,0,.6),inset 0 0 30px rgba(0,0,0,.5)}
  .crgrid{display:grid;grid-template-columns:repeat(auto-fit,minmax(120px,1fr));gap:8px;width:min(92vw,620px);margin-top:8px}
  .crmini{border:1px solid var(--cc);border-radius:10px;background:rgba(19,31,26,.86);padding:9px;text-align:center;box-shadow:0 0 10px color-mix(in srgb,var(--cc),transparent 72%)}
  .crmini .mi{font-size:28px;filter:drop-shadow(0 0 10px var(--cc))}
  .crmini .mt{font-size:9px;letter-spacing:1.3px;text-transform:uppercase;color:var(--cc);margin-top:2px}
  .crmini .mn{font-family:var(--display);font-size:12px;color:var(--cc);margin-top:3px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .casecard.win{box-shadow:0 0 18px var(--cc);border-width:2px;animation:winPulse 1.2s infinite}
  @keyframes winPulse{0%,100%{filter:brightness(1)}50%{filter:brightness(1.35)}}
  .casemark{position:absolute;top:-1px;bottom:-1px;left:50%;width:2px;margin-left:-1px;background:var(--brass);box-shadow:0 0 8px var(--brass);pointer-events:none}
  .casemark::before,.casemark::after{content:'';position:absolute;left:50%;transform:translateX(-50%);border:6px solid transparent}
  .casemark::before{top:0;border-top-color:var(--brass)}
  .casemark::after{bottom:0;border-bottom-color:var(--brass)}
  .chestrays{position:absolute;width:300px;height:300px;border-radius:50%;pointer-events:none;
   background:repeating-conic-gradient(var(--rayc,rgba(255,215,106,.33)) 0 8deg,transparent 8deg 26deg);
   -webkit-mask:radial-gradient(circle,#000 0%,transparent 68%);mask:radial-gradient(circle,#000 0%,transparent 68%);
   animation:raySpin 8s linear infinite;transition:opacity .35s;opacity:0}
  .chestrays.epic{width:380px;height:380px;animation-duration:4s}
  @keyframes raySpin{to{transform:rotate(360deg)}}
  .chestreveal{position:relative;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:6px;text-align:center;padding:0 30px;min-height:126px;margin-top:12px;opacity:0;transform:translateY(18px) scale(.82);transition:all .45s cubic-bezier(.2,1.4,.4,1);pointer-events:none}
  .chestreveal.show{opacity:1;transform:none}
  .cricon{font-size:46px;filter:drop-shadow(0 0 16px currentColor)}
  .crname{font-family:var(--display);font-size:19px;text-shadow:0 0 16px currentColor}
  .crsub{font-size:11px;color:var(--dim);line-height:1.45}
  .crtier{font-size:10px;letter-spacing:2px;text-transform:uppercase;opacity:.85}
  .casebtns{display:flex;gap:10px;margin-top:16px;align-items:center;opacity:0;pointer-events:none;transition:opacity .3s}
  .casebtns.show{opacity:1;pointer-events:auto}
  #respinBtn{font-family:var(--display);font-size:16px;letter-spacing:.5px;padding:14px 30px;border-radius:12px;border:1px solid var(--brass);background:linear-gradient(180deg,var(--brass),var(--brass-deep));color:#20180a;cursor:pointer;box-shadow:0 0 18px rgba(217,164,65,.35)}
  #respinBtn:disabled{opacity:.45;cursor:default;box-shadow:none}
  #caseClose{font-family:var(--display);font-size:13px;padding:12px 20px;border-radius:12px;border:1px solid var(--line);background:var(--panel2);color:var(--ink);cursor:pointer}


  @media (max-width:600px){
    /* reels: compact */
    .casewrap,.caseextra{height:78px}
    .casereel{top:8px;height:62px;gap:6px}
    .casecard{flex:0 0 56px;height:62px;border-radius:7px;gap:2px}
    .casecard .ci{font-size:17px}
    .casecard .cr{font-size:6.5px;letter-spacing:.8px}
    /* result mini-cards: much smaller */
    .crgrid{grid-template-columns:repeat(auto-fit,minmax(80px,1fr));gap:6px;width:94vw;margin-top:6px}
    .crmini{padding:6px;border-radius:8px}
    .crmini .mi{font-size:16px}
    .crmini .mt{font-size:6.5px;letter-spacing:.8px}
    .crmini .mn{font-size:9.5px}
    /* single-win reveal: tighter */
    .chestreveal{min-height:86px;margin-top:6px}
    .cricon{font-size:30px}
    .crname{font-size:15px}
    .crsub{font-size:10px}
    /* buttons: don't eat vertical space */
    .casebtns{margin-top:10px;gap:7px}
    #respinBtn{font-size:13px;padding:10px 18px}
    #caseClose{font-size:11px;padding:9px 14px}
    #chestFx.multi{padding-top:calc(10px + env(safe-area-inset-top,0px))}
    #chestFx.multi .casewrap,#chestFx.multi .caseextra{margin-bottom:5px}
  }


  /* --- Lucky 7 slot machine --- */
  #slotFx{position:absolute;inset:0;z-index:72;display:none;align-items:center;justify-content:center;flex-direction:column;background:rgba(10,7,4,.86)}
  #slotFx.open{display:flex}
  .slotmach{display:flex;flex-direction:column;align-items:center;padding:22px 26px 20px;border-radius:18px;border:2px solid var(--brass);background:linear-gradient(180deg,#332519,#150e08);box-shadow:0 14px 50px rgba(0,0,0,.6),0 0 24px rgba(217,164,65,.18)}
  .slottop{font-family:var(--display);font-size:21px;color:var(--brass);letter-spacing:2.5px;margin-bottom:14px;text-shadow:0 0 14px rgba(217,164,65,.45)}
  .slotreels{display:flex;gap:10px}
  .slotwin{width:92px;height:92px;border-radius:12px;border:1px solid var(--brass-deep);background:#0d1512;overflow:hidden;position:relative}
  .slotwin::before,.slotwin::after{content:'';position:absolute;left:0;right:0;height:18px;z-index:2;pointer-events:none}
  .slotwin::before{top:0;background:linear-gradient(180deg,rgba(0,0,0,.7),transparent)}
  .slotwin::after{bottom:0;background:linear-gradient(0deg,rgba(0,0,0,.7),transparent)}
  .slotreel{display:flex;flex-direction:column;will-change:transform}
  .slotcell{flex:0 0 92px;display:flex;align-items:center;justify-content:center;font-size:44px}
  .slotres{margin-top:14px;font-family:var(--display);font-size:18px;min-height:1.4em;text-align:center;width:0;min-width:100%} /* width:0+min-width:100%: long win texts wrap instead of widening the machine */
  .slotstats{margin-top:5px;font-size:11px;color:var(--dim);min-height:1.2em;text-align:center}
  .slotbet{display:flex;align-items:center;gap:8px;margin-top:12px}
  .slotbetcost{font-size:12px;color:var(--brass);margin-left:4px;white-space:nowrap}
  #slotSpinBtn{font-family:var(--display);font-size:16px;letter-spacing:.5px;padding:14px 28px;border-radius:12px;border:1px solid var(--brass);background:linear-gradient(180deg,var(--brass),var(--brass-deep));color:#20180a;cursor:pointer;box-shadow:0 0 16px rgba(217,164,65,.3)}
  #slotSpinBtn:disabled{opacity:.45;cursor:default;box-shadow:none}
  #slotAutoBtn{font-family:var(--display);font-size:14px;padding:14px 20px;border-radius:12px;border:1px solid #6dbb6d;background:var(--panel2);color:#9adf9a;cursor:pointer}
  #slotAutoBtn.on{background:linear-gradient(180deg,#c75146,#8a3a32);border-color:#e88a7a;color:#fff;box-shadow:0 0 14px rgba(199,81,70,.4)}
  .slotmach.bigwin{animation:slotGlow .8s ease-in-out infinite;border-color:#ffd100}
  .slotmach.bigwin .slotwin{border-color:#ffd100;box-shadow:0 0 18px rgba(255,209,0,.5),inset 0 0 14px rgba(255,209,0,.15)}
  @keyframes slotGlow{0%,100%{box-shadow:0 14px 50px rgba(0,0,0,.6),0 0 24px rgba(255,209,0,.35)}50%{box-shadow:0 14px 50px rgba(0,0,0,.6),0 0 60px rgba(255,209,0,.75)}}
  .slotres.bigres{font-size:26px;animation:resPop .5s cubic-bezier(.2,1.8,.4,1)}
  @keyframes resPop{from{transform:scale(.4);opacity:0}to{transform:scale(1);opacity:1}}
  #slotFx.flash{animation:epicFlash .6s ease-out}
  @media (min-width:900px){
    .slotmach{padding:34px 46px 30px;border-radius:22px}
    .slottop{font-size:30px;margin-bottom:22px}
    .slotreels{gap:16px}
    .slotwin{width:150px;height:150px;border-radius:16px}
    .slotcell{flex-basis:150px;font-size:76px}
    .slotres{font-size:24px;margin-top:20px}
    .slotres.bigres{font-size:36px}
    .slotstats{font-size:13px}
    #slotSpinBtn{font-size:19px;padding:17px 38px}
    #slotAutoBtn{font-size:16px;padding:17px 26px}
    .slotbet{margin-top:16px;gap:10px}
    .slotbet .qtybtn{width:30px;height:30px;font-size:15px}
    .slotbet .qtynum{font-size:15px}
    .slotbetcost{font-size:14px}
  }
  @media (max-width:600px){
    .slotwin{width:66px;height:66px}
    .slotcell{flex-basis:66px;font-size:30px}
    .slottop{font-size:17px}
  }

  /* --- Bag: scroll tier categories --- */
  .tierhead{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:9px 12px;margin-bottom:8px;background:rgba(80,58,38,.55);border:1px solid rgba(165,128,90,.4);border-radius:10px;cursor:pointer;font-family:var(--display);font-size:13px;color:var(--parch);user-select:none}
  .tierhead .tcount{font-size:10.5px;color:var(--dim);font-family:var(--body)}
  .tierbody{margin:0 0 6px}
  .chestp{position:absolute;left:50%;top:50%;width:7px;height:7px;border-radius:2px;pointer-events:none;animation:chestp 1.05s ease-out forwards}
  @keyframes chestp{from{transform:translate(-50%,-50%) rotate(0);opacity:1}to{transform:translate(calc(-50% + var(--dx)),calc(-50% + var(--dy))) rotate(320deg);opacity:0}}
  @keyframes epicFlash{0%{background:rgba(200,150,255,.35)}100%{background:rgba(10,7,4,.84)}}
  #chestFx.flash{animation:epicFlash .6s ease-out}
 
  /* the plate lives on the wrapper - Chrome's autofill can hide an input's own background image */
  .acctwrap{background:url('assets/ui/ui_buttons.png') center/100% 100% no-repeat;border-radius:8px;margin-top:6px;padding:6px 30px 6px 38px}
  .acctwrap:focus-within{filter:brightness(1.18)}
  .acctin{width:100%;padding:6px 0;border-radius:6px;border:none;background:transparent;color:var(--parch);font-size:13px;text-shadow:0 1px 2px rgba(0,0,0,.7)}
  .acctin::placeholder{color:#b8a888;opacity:.75}
  /* Chrome autofill forces a light background - clip it to the text glyphs so it never
     paints over the plate behind; the wrapper's artwork shows through untouched */
  .acctin:-webkit-autofill,.acctin:-webkit-autofill:hover,.acctin:-webkit-autofill:focus{
   -webkit-background-clip:text;
   -webkit-text-fill-color:var(--parch);caret-color:var(--parch);
  }
  .acctin:focus{outline:none;filter:brightness(1.18)}
  /* the title row carries the Close button - without the top inset it sits under the clock
     and cannot be tapped at all */
  #lbFx{position:absolute;inset:0;z-index:75;display:none;flex-direction:column;background:rgba(18,11,7,.94);padding:calc(20px + env(safe-area-inset-top,0px)) 20px calc(20px + env(safe-area-inset-bottom,0px))}
  #lbFx .sbtn{background:#221610;border-color:rgba(140,105,70,.5)} /* dark-brown Inspect/Close buttons */
  #lbFx.open{display:flex}
  .lbrow{display:flex;align-items:center;gap:10px;padding:8px 10px;border-bottom:1px solid var(--line);font-size:12.5px}
  .lbrow.me{background:rgba(217,164,65,.08);border-radius:8px}
  .lbrank{width:26px;color:var(--brass);font-family:var(--display);font-size:13px}
  .lbname{flex:1;color:var(--parch);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .lbmeta{color:var(--dim);font-size:11px;white-space:nowrap}
  .lbcard{background:rgba(80,58,38,.55);border-color:rgba(165,128,90,.4)}
  .lbcard.me{border-color:var(--brass);box-shadow:0 0 14px rgba(217,164,65,.22)}
  .lbrank.big{width:34px;flex:0 0 auto;text-align:center;font-size:17px}

  .lbinsp .slotrow{display:flex;gap:8px}
  .lbinsp .slot{flex:1}


  /* ---- Riptide sign-in gate ---- */
  .loginbox{width:min(100%,390px);margin:0 auto;padding:34px 30px;background:url('assets/ui/ui_background.png') center/100% 100% no-repeat;border:none;border-radius:14px;box-shadow:0 18px 50px rgba(0,0,0,.45)}
  .loginbox h1{margin:14px 0 0 10px} /* keep the title inside the panel's black inlay */
  .loginbox .tag{margin-left:10px}
  .loginbox #fbForgot{margin-left:10px}
  .loginbox .fineprint{margin:12px 10px 14px}
  .loginrow{display:grid;grid-template-columns:1fr 1fr;gap:8px;margin-top:10px}
  .loginbtn{padding:13px 10px;border-radius:9px;border:none;background:url('assets/ui/ui_buttons.png') center/100% 100% no-repeat;color:var(--parch);font-family:var(--display);font-size:13px;cursor:pointer;text-shadow:0 1px 3px rgba(0,0,0,.8)}
  .loginbtn:hover{filter:brightness(1.15)}
  .loginbtn.primary{color:#ffd76a;filter:brightness(1.2) drop-shadow(0 0 6px rgba(217,164,65,.35))}
  .loginbtn.primary:hover{filter:brightness(1.35) drop-shadow(0 0 8px rgba(217,164,65,.5))}
  #guestBtn{width:100%;margin-top:9px;color:var(--brass)}
  /* right-hand end of the content column, under the heading. Not pinned to the window corner:
     #select is fixed and full width on the desktop, with the column centred by its own padding, so
     a corner button lands out in the wallpaper instead of over the plates. align-self keeps it on
     the same right edge the plates use, whatever that width turns out to be. */
  #selCfgBtn{align-self:flex-end;margin:0 0 7px;padding:3px 6px;background:transparent;border:6px solid transparent;border-left-width:24px;border-right-width:24px;border-image:url('assets/ui/ui_buttons.png') 45 180 55 180 fill stretch;color:var(--parch);font-family:var(--display);font-size:12px;cursor:pointer;text-shadow:0 1px 3px rgba(0,0,0,.8)}
  #selCfgBtn:hover{filter:brightness(1.2)}
  .selectacct{display:flex;align-items:center;justify-content:space-between;gap:10px;margin:-4px 0 12px;padding:12px 30px;background:url('assets/ui/ui_buttonrak.png') center/100% 100% no-repeat;border:none;border-radius:9px}
  .selectacct .sbtn{background:transparent;border:6px solid transparent;border-left-width:24px;border-right-width:24px;border-image:url('assets/ui/ui_buttons.png') 45 180 55 180 fill stretch;color:var(--parch);padding:3px 6px;text-shadow:0 1px 3px rgba(0,0,0,.8)}
  .selectacct .sbtn:hover{filter:brightness(1.2)}
  .statusval{font-size:9px;color:var(--dim);white-space:nowrap;min-width:54px;text-align:right}
  .statusgrid{display:grid;grid-template-columns:1fr;gap:5px;margin-top:7px}
  .statusline{display:grid;grid-template-columns:56px 24px 1fr 58px;gap:7px;align-items:center}


  @media (max-width:899px){#sideToggle{display:none!important}}
  /* ---- desktop RuneScape-style split layout; mobile rules above stay untouched ---- */
  @media (min-width:900px){
    body{display:block;overflow:hidden}
    #app{max-width:none;width:100vw;height:100dvh;display:grid;grid-template-columns:minmax(0,7fr) minmax(320px,3fr);grid-template-rows:auto minmax(0,1fr) auto;background:var(--night);transition:grid-template-columns .25s ease}
    body.sidehidden #app{grid-template-columns:minmax(0,1fr) 0px}
    body.sidehidden nav,body.sidehidden .panel{opacity:0;pointer-events:none;overflow:hidden}
    body.sidehidden #stageWrap,body.sidehidden header,body.sidehidden #questcard{border-right:0}
    #sideToggle{display:flex}
    body.sidehidden #sideToggle{transform:none}
    header{grid-column:1;grid-row:1;padding:10px 16px 9px;border-right:none;background:url('assets/ui/ui_allt.png') center/100% 100% no-repeat}
    header .hrow{max-width:none}
    header .zone-name{font-size:17px}
    header .vrow{margin-top:7px;padding:6px 8px;border:none;border-radius:8px;background:none}
    header .bar{height:9px;box-shadow:inset 0 0 0 1px rgba(255,255,255,.025)}
    #stageWrap{grid-column:1;grid-row:2;min-width:0;min-height:0;border-right:none}
    #questcard{grid-column:1;grid-row:3;margin:0;padding:10px 18px 11px;border-radius:0;border-left:0;border-right:none;border-bottom:0;background:url('assets/ui/ui_allt.png') center/100% 100% no-repeat}
    #questcard .qtop{max-width:100%}
    #questcard .qname{font-size:14px}
    #questcard .qdesc{font-size:11px}
    nav{grid-column:2;grid-row:1;display:flex;min-width:0;height:auto;flex:0 0 auto;border-top:0;border-bottom:none;padding:0 26px;background:url('assets/ui/ui_buttons.png') center/100% 100% no-repeat,url('assets/ui/ui_allt.png') center/cover no-repeat}
    nav button{flex:1;min-width:0;padding:9px 4px;font-size:9px}
    nav button[data-tab="battle"]{display:none}
    .panel{position:relative;inset:auto;bottom:auto;grid-column:2;grid-row:2 / 4;z-index:20;width:100%;height:100%;min-height:0;padding:16px;background:url('assets/ui/ui_allt.png') center/100% 100% no-repeat;border-left:0;overflow-y:auto}
    .panel.open{display:block}
    .panel .ptitle{font-size:18px}
    .slotrow{display:grid;grid-template-columns:1fr 1fr;gap:8px}
    #scrollRow{grid-template-columns:1fr 1fr}
    .slot{min-width:0}
    .statgrid{grid-template-columns:1fr 1fr}
    #skillbar{bottom:28px;gap:9px}
    .skill{width:54px;height:54px;font-size:22px}
    #ticker{left:12px;right:76px;bottom:8px;font-size:11px}
    #hint{font-size:11px}
    #select,#create,#login{position:fixed;inset:0;padding-left:max(24px,calc(50vw - 380px));padding-right:max(24px,calc(50vw - 380px))}
    #lbFx,#chestFx{position:fixed;inset:0}
    .casewrap{width:min(78vw,760px)}
  }

/* --- Slots: 3/5/5/3 ways slot --- */
#seaFx{position:absolute;inset:0;z-index:72;display:none;align-items:center;justify-content:center;flex-direction:column;background:rgba(10,7,4,.86)}
#seaFx.open{display:flex}
.slotmach.sea{position:relative;border-color:#5b9bd5;background:linear-gradient(180deg,#1d3345,#0d1620);box-shadow:0 14px 50px rgba(0,0,0,.6),0 0 24px rgba(91,155,213,.2)}
.slotmach.sea .slottop{color:#8fc3ef;text-shadow:0 0 14px rgba(91,155,213,.55)}
.slotmach.sea.bigwin{border-color:#ffd100;animation:slotGlow .8s ease-in-out infinite}
/* Cell size scales with BOTH viewport width and height so the machine fits 4:3
   tablets (iPad) as well as phones and 4k screens - never below 62px, capped at 110px. */
#seaFx{--seavh:100vh}
@supports (height:100dvh){#seaFx{--seavh:100dvh}}
#seaFx{--seacell:clamp(62px,min(calc((100vw - 120px)/4),calc((var(--seavh) - 340px)/5)),110px)}
.seagrid{display:flex;gap:6px;align-items:center}
.seacolwin{width:var(--seacell);border-radius:10px;border:1px solid #3a6a8a;background:#0a141d;overflow:hidden;position:relative}
.seacolwin[data-rows="3"]{height:calc(var(--seacell)*3)}
.seacolwin[data-rows="5"]{height:calc(var(--seacell)*5)}
.seacolwin::before,.seacolwin::after{content:'';position:absolute;left:0;right:0;height:14px;z-index:2;pointer-events:none}
.seacolwin::before{top:0;background:linear-gradient(180deg,rgba(0,0,0,.7),transparent)}
.seacolwin::after{bottom:0;background:linear-gradient(0deg,rgba(0,0,0,.7),transparent)}
.seastrip{display:flex;flex-direction:column;will-change:transform}
.seacell{flex:0 0 var(--seacell);width:var(--seacell);height:var(--seacell);display:flex;align-items:center;justify-content:center;font-size:calc(var(--seacell)*.42);position:relative}
.seacell .m{position:absolute;bottom:2px;right:5px;font-size:max(12px,calc(var(--seacell)*.145));font-weight:800;color:#ffd76a;text-shadow:0 1px 3px #000,0 0 8px rgba(255,150,50,.8);z-index:3}
.seacell .ic{line-height:1}
/* respin mini-roll: a per-cell strip scrolling the same direction as the reels */
.seacell.rolling{overflow:hidden}
.seaminiroll{position:absolute;left:0;right:0;top:0;display:flex;flex-direction:column;will-change:transform}
.seaminicell{flex:0 0 var(--seacell);width:100%;height:var(--seacell);display:flex;align-items:center;justify-content:center;position:relative}
.seacell:not(.prize) .ic{opacity:.55;filter:grayscale(.4)}
.seacell.prize{border-radius:8px}
.seacell.prize::before{content:'';position:absolute;inset:4px;border:1.5px solid var(--cc);border-radius:8px;opacity:.75;box-shadow:0 0 8px color-mix(in srgb,var(--cc),transparent 55%),inset 0 0 10px color-mix(in srgb,var(--cc),transparent 82%);pointer-events:none}
.seacell.prize .ic{filter:drop-shadow(0 0 5px var(--cc))}
.seacell.hit::after{content:'';position:absolute;inset:3px;border:2px solid #ffd76a;border-radius:8px;box-shadow:0 0 10px rgba(255,180,80,.7),inset 0 0 8px rgba(255,180,80,.25);animation:winPulse 1s infinite}
.seacell.lockd{outline:3px solid #4da3ff;outline-offset:-3px;box-shadow:0 0 16px rgba(77,163,255,.55);animation:lockpulse 1.2s ease-in-out infinite}
@keyframes lockpulse{50%{box-shadow:0 0 22px rgba(77,163,255,.85)}}
.seapay{margin-top:9px;font-size:10px;color:var(--dim);display:grid;grid-template-columns:auto auto;gap:2px 16px;text-align:left}
.seapay b{color:#d8e4d6;font-weight:600}
#seaSpinBtn{font-family:var(--display);font-size:16px;letter-spacing:.5px;padding:14px 28px;border-radius:12px;border:1px solid #5b9bd5;background:linear-gradient(180deg,#5b9bd5,#2f5f8a);color:#0a1420;cursor:pointer;box-shadow:0 0 16px rgba(91,155,213,.3)}
#seaSpinBtn:disabled{opacity:.45;cursor:default;box-shadow:none}
#seaAutoBtn{font-family:var(--display);font-size:14px;padding:14px 20px;border-radius:12px;border:1px solid #6dbb6d;background:var(--panel2);color:#9adf9a;cursor:pointer}
#seaAutoBtn.on{background:linear-gradient(180deg,#c75146,#8a3a32);border-color:#e88a7a;color:#fff;box-shadow:0 0 14px rgba(199,81,70,.4)}
#seaFastBtn.on{border-color:#ffd76a;color:#ffd76a;box-shadow:0 0 12px rgba(255,215,106,.25)}
@media (min-width:900px){
 .seacolwin{border-radius:12px}
 .seapay{font-size:12px}
}

/* --- Moonshine Inn: daily Rested XP wheel --- */
#restFx{position:absolute;inset:0;z-index:72;display:none;align-items:center;justify-content:center;flex-direction:column;background:rgba(10,7,4,.86)}
#restFx.open{display:flex}
#restSpinBtn{font-family:var(--display);font-size:16px;letter-spacing:.5px;padding:14px 28px;border-radius:12px;border:1px solid var(--brass);background:linear-gradient(180deg,var(--brass),var(--brass-deep));color:#20180a;cursor:pointer;box-shadow:0 0 16px rgba(217,164,65,.3)}
#restSpinBtn:disabled{opacity:.45;cursor:default;box-shadow:none}

/* --- Blackjack --- */
#bjFx{position:absolute;inset:0;z-index:72;display:none;align-items:center;justify-content:center;flex-direction:column;background:rgba(10,7,4,.86)}
#bjFx.open{display:flex}
#rouFx{position:absolute;inset:0;z-index:72;display:none;align-items:center;justify-content:center;flex-direction:column;background:rgba(10,7,4,.86)}
#rouFx.open{display:flex}
#rtbFx{position:absolute;inset:0;z-index:72;display:none;align-items:center;justify-content:center;flex-direction:column;background:rgba(10,7,4,.86)}
#rtbFx.open{display:flex}
/* 🥤 Sebbe's cup game. The cups are laid out absolutely inside a fixed-height track so the shuffle
   can slide them past each other; three columns in a flex row would have to reflow instead. */
#sebbeFx{position:absolute;inset:0;z-index:72;display:none;align-items:center;justify-content:center;flex-direction:column;background:rgba(10,7,4,.86)}
#sebbeFx.open{display:flex}
/* his table, with a dark wash over it so the brass type still reads against the torchlight */
.slotmach.cups{position:relative;border-color:#c9a05a;
 background:linear-gradient(180deg,rgba(26,18,11,.80),rgba(10,7,4,.93)),
            url('assets/ui/cup_table.jpg') center 64%/cover no-repeat;
 box-shadow:0 14px 50px rgba(0,0,0,.65),0 0 26px rgba(201,160,90,.20)}
.slotmach.cups .slottop{color:#f0d9a4;text-shadow:0 0 16px rgba(217,164,65,.5)}
.cuprow{position:relative;height:120px;width:276px;margin:2px auto 10px}
.cup{position:absolute;bottom:16px;width:84px;height:73px;border:0;padding:0;background:none;
 cursor:pointer;transition:left .001s linear;transform-origin:50% 100%;
 filter:drop-shadow(0 5px 6px rgba(0,0,0,.55))}
.cup .cupbody{display:block;width:100%;height:100%;
 background:url('assets/ui/cup_stone.png') center/contain no-repeat}
.cup.lift{transform:translateY(-40px) rotate(-7deg)}
.cup.pick{filter:drop-shadow(0 5px 6px rgba(0,0,0,.55)) drop-shadow(0 0 9px rgba(255,215,106,.85))}
.cup:disabled{cursor:default}
.cupfloor{position:absolute;left:6px;right:6px;bottom:12px;height:8px;border-radius:4px;
 background:radial-gradient(ellipse at center,rgba(255,214,140,.30),rgba(0,0,0,0) 72%)}
.cupball{position:absolute;bottom:18px;width:22px;height:22px;border-radius:50%;
 background:radial-gradient(circle at 34% 30%,#fff6d0,#e8c45a 45%,#a2761f);
 box-shadow:0 0 12px rgba(255,215,106,.85);opacity:0;transition:opacity .12s linear}
.cupball.show{opacity:1}
.rtbladder{display:flex;gap:6px;justify-content:center;margin:2px 0 8px}
.rtbstep{padding:5px 10px;border-radius:8px;border:1px solid #4a4436;background:#241c12;color:var(--dim);font-size:11px;font-weight:700}
.rtbstep.won{border-color:#9adf9a;color:#9adf9a}
.rtbstep.cur{border-color:var(--brass);color:#ffd76a;box-shadow:0 0 8px rgba(217,164,65,.35)}
.gvbside{display:flex;flex-direction:column;align-items:center;gap:5px}
.gvbname{font-size:12px;font-weight:700;color:#e8dcc8}
.gvbreel{width:104px;height:104px;overflow:hidden;border-radius:12px;border:2px solid #6a4a2a;background:#161009;position:relative}
.gvbreel.rolling{border-color:#ffd76a;box-shadow:0 0 14px rgba(255,215,106,.35)}
.gvbstrip{transition:none}
.gvbcard{width:104px;height:104px;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:2px;font-size:38px}
.gvbcard .gl{font-size:10px;font-weight:800;letter-spacing:.5px}
.gvbscore{font-size:15px;font-weight:800;color:#ffd76a}
.gvbbigwin{position:relative;width:100%;height:96px;overflow:hidden;border-radius:12px;border:2px solid #ffd76a;background:#161009;margin-top:8px;box-shadow:0 0 14px rgba(255,215,106,.25) inset}
.gvbbigstrip{display:flex;position:absolute;left:0;top:0;height:100%;will-change:transform}
.gvbbigcard{width:78px;flex:0 0 78px;height:100%;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:2px;font-size:30px;border-right:1px solid rgba(255,255,255,.06)}
.gvbbigcard .gl{font-size:10px;font-weight:800}
.gvbbigmark{position:absolute;left:50%;top:0;bottom:0;width:2px;background:#ffd76a;box-shadow:0 0 10px #ffd76a}
/* ⏳ boot screen - holds the door shut until the art is in memory */
/* the framed parchment is the whole composition - contain it so the border is never cropped */
/* landscape screens get the wide art; portrait phones get the tall one (rule below).
   cover on the matching aspect fills edge to edge with almost nothing cropped. */
#boot{position:fixed;inset:0;z-index:9999;display:flex;align-items:center;justify-content:center;
  background:url('assets/ui/loading_desktop.jpg') center/cover no-repeat #0b0906;transition:opacity .5s ease}
#boot.gone{opacity:0;pointer-events:none}
.bootinner{position:relative;text-align:center;width:min(60%,430px);margin-top:42vh} /* well below the crest, low on the parchment */
.bootbar{height:13px;border-radius:8px;border:1px solid #6b4a22;background:rgba(60,42,22,.55);overflow:hidden;
  box-shadow:inset 0 1px 4px rgba(0,0,0,.5),0 1px 0 rgba(255,240,200,.25)}
.bootbar i{display:block;height:100%;width:0%;border-radius:7px;
  background:linear-gradient(90deg,#8a6a2a,#e0b45a 55%,#ffe9a8);
  box-shadow:0 0 10px rgba(180,130,50,.6);transition:width .25s ease}
.boottip{margin-top:11px;font-family:var(--display);font-size:14px;color:#fff;
  text-shadow:0 0 8px #000,0 0 3px #000,0 2px 4px rgba(0,0,0,.9);min-height:1.3em;letter-spacing:.4px}
/* 📱 portrait: the tall artwork, centred bar, and the art has to fill the whole
   screen even while iOS Safari's chrome slides in and out (dvh alone leaves a strip) */
@media (max-aspect-ratio:1/1){
  #boot{background-image:url('assets/ui/loading_phone.jpg');align-items:center;padding-bottom:0;
    height:100dvh;
    /* bottom-anchored and slightly overscaled: crops the black margin baked into the top
       of the artwork so the gilded frame starts right under the status bar */
    background-size:auto 103%;background-position:center bottom}
  .bootinner{margin-top:0;width:min(82%,420px)}
  /* same trick for the tavern art behind login / select / create */
  html:has(#login.open),html:has(#select.open),html:has(#create.open),
  body:has(#login.open),body:has(#select.open),body:has(#create.open),
  body:has(#login.open) #app,body:has(#select.open) #app,body:has(#create.open) #app,
  #select,#login,#create{background-size:auto 112%;background-position:center bottom}
}
/* ❄ Ice Armor talent tree */
.talentbox{background:linear-gradient(180deg,#101a2a,#080d16);border:2px solid #5b9bd5;border-radius:18px;padding:20px 24px 18px;max-width:560px;width:94%;max-height:94%;overflow-y:auto;text-align:center;box-shadow:0 14px 50px rgba(0,0,0,.7),0 0 30px rgba(91,155,213,.22)}
.ttop{font-family:var(--display);font-size:22px;color:#9fd4ff;letter-spacing:1px;text-shadow:0 0 14px rgba(120,200,255,.45)}
.tsub{font-size:12px;color:var(--dim);margin:4px 0 12px}
.tsub b{color:#9fd4ff}
.ttree{display:flex;flex-direction:column;align-items:center;gap:0}
.trow{display:flex;justify-content:center;align-items:center;gap:18px}
.tlink{width:2px;height:16px;background:#2f4a66}
.tlink.on{background:#5b9bd5;box-shadow:0 0 8px rgba(91,155,213,.7)}
.tbranch{display:flex;justify-content:center;gap:120px;width:100%;margin-top:2px}
.tcol{display:flex;flex-direction:column;align-items:center;gap:0}
.tnode{width:52px;height:52px;border-radius:11px;border:2px solid #2f4a66;background:#0c1420;display:flex;align-items:center;justify-content:center;font-size:24px;cursor:default;position:relative;color:#3a4a5e}
.tnode.avail{border-color:#d9a441;background:linear-gradient(180deg,#1a2436,#0e1622);color:#ffd76a;cursor:pointer;box-shadow:0 0 12px rgba(217,164,65,.45);animation:pulseNext 1.8s infinite}
.tnode.taken{border-color:#6dbb6d;background:linear-gradient(180deg,#16301f,#0c1a12);color:#bfe4ff;cursor:default;box-shadow:0 0 12px rgba(109,187,109,.4)}
.tnode.locked{opacity:.75}
.tnode .trank{position:absolute;bottom:-2px;right:-4px;font-size:9px;font-weight:800;color:#e8dcc8;background:#0c1420;border:1px solid #2f4a66;border-radius:6px;padding:0 3px}
.tnode.taken .trank{color:#9adf9a;border-color:#6dbb6d}
.tinfo{margin-top:12px;font-size:12px;color:#cfe0f0;min-height:3.2em;line-height:1.5;border-top:1px solid #23384f;padding-top:10px}
.tinfo b{color:#9fd4ff}
@media (min-width:900px){.talentbox{max-width:640px;padding:26px 30px 22px}.tnode{width:60px;height:60px;font-size:28px}.ttop{font-size:26px}}
/* 🏦 bank: deposits in one column, withdrawals in the other */
.bankcols{display:flex;gap:10px;margin-top:6px;align-items:flex-start}
.bankcol{flex:1;display:flex;flex-direction:column;gap:5px;min-width:0}
.bankcol .sbtn{width:100%;padding:9px 4px}
.bankcolhd{font-family:var(--display);font-size:12.5px;color:var(--brass);margin-bottom:1px}
#gvbFx .casinobox{max-height:94%;overflow-y:auto} /* 10 reel rows must scroll on small screens */
.gvbrow{display:flex;align-items:center;gap:8px;width:100%}
.gvbrowinfo{width:92px;flex:0 0 92px;text-align:left;display:flex;flex-direction:column;gap:2px}
.gvbbigwin.sm{height:62px;margin-top:0;flex:1;border-width:1.5px}
.gvbbigwin.sm.rolling{border-color:#fff;box-shadow:0 0 10px rgba(255,255,255,.3) inset}
.gvbbigcard.sm{width:58px;flex:0 0 58px;font-size:21px}
.gvbbigcard.sm .gl{font-size:8.5px}
.slotmach.rou{max-height:96%;overflow-y:auto}
#rouWheel{display:block;margin:4px auto 2px;width:300px;height:300px} /* canvas renders at 420 - crisp on desktop, downscaled on phones */
.roucolors{display:flex;gap:5px;margin:6px 0 5px}
.roubet{flex:1;position:relative;padding:9px 2px;border-radius:9px;border:1px solid #4a4436;background:#2a241a;color:#e8dcc8;font-weight:700;font-size:11px;cursor:pointer;font-family:inherit}
.roubet.red{background:#7a2020;border-color:#a03636}
.roubet.black{background:#191919;border-color:#3c3c3c}
.roubet.sel{outline:2px solid #ffd76a}
.rougrid{display:grid;grid-template-columns:repeat(13,1fr);gap:3px}
.roucell{position:relative;padding:7px 0;border-radius:6px;border:1px solid rgba(255,255,255,.14);color:#fff;font-weight:700;font-size:10.5px;text-align:center;cursor:pointer;font-family:inherit}
.roucell.r{background:#7a2020}
.roucell.b{background:#191919}
.roucell.g{background:#1c5a30;grid-row:span 3}
.roucell.sel{outline:2px solid #ffd76a}
.rchip{position:absolute;top:-6px;right:-4px;background:#ffd76a;color:#1a1206;font-size:8px;font-weight:800;border-radius:8px;padding:1px 4px;pointer-events:none;box-shadow:0 1px 3px rgba(0,0,0,.6)}
.roustat{font-size:11px;color:var(--dim);text-align:center;margin:6px 0 2px}
.slotmach.bj{border-color:#6dbb6d;background:linear-gradient(180deg,#1d3a2a,#0d1a12);box-shadow:0 14px 50px rgba(0,0,0,.6),0 0 24px rgba(109,187,109,.2)}
.slotmach.bj .slottop{color:#9adf9a;text-shadow:0 0 14px rgba(109,187,109,.5)}
.bjrow{display:flex;flex-direction:column;gap:4px;align-items:center;min-height:70px}
.bjlab{font-size:10px;color:var(--dim);text-transform:uppercase;letter-spacing:1.4px}
.bjcards{display:flex;gap:6px;min-height:54px}
.bjcard{width:38px;height:54px;border-radius:6px;background:#efe9da;color:#1a1a1a;display:flex;flex-direction:column;align-items:center;justify-content:center;font-weight:800;font-size:14px;line-height:1.1;box-shadow:0 2px 6px rgba(0,0,0,.45)}
.bjcard.red{color:#b03030}
.bjcard.back{background:linear-gradient(135deg,#2f5f8a,#1d3345);color:transparent}
.bjtot{font-size:12px;color:var(--parch);font-weight:700}
.bjbtns{display:flex;gap:8px;margin-top:12px;flex-wrap:wrap;justify-content:center}
.bjact{font-family:var(--display);font-size:14px;padding:12px 20px;border-radius:12px;border:1px solid #6dbb6d;background:linear-gradient(180deg,#6dbb6d,#3a7a4a);color:#0a1a10;cursor:pointer}
.bjact:disabled{opacity:.4;cursor:default}
.bjact.alt{background:var(--panel2);color:#9adf9a}
.bjact.rtbred{background:linear-gradient(180deg,#a03636,#6a1a1a);border-color:#c05050;color:#ffe0e0}
.bjact.rtbblack{background:linear-gradient(180deg,#3c3c3c,#141414);border-color:#5a5a5a;color:#e8e8e8}
@media (max-width:600px){.bjcard{width:32px;height:46px;font-size:12px}}
@media (min-width:900px){
 .slotmach.rou,.slotmach.rtb{padding:30px 44px 26px;border-radius:22px}
 .slotmach.rou .slottop,.slotmach.rtb .slottop{font-size:30px;margin-bottom:14px}
 #rouWheel{width:420px;height:420px}
 .roucell{padding:11px 0;font-size:14px}
 .roubet{padding:13px 2px;font-size:14px}
 .rchip{font-size:10px;padding:1px 5px}
 .roustat{font-size:13px}
 .slotmach.rou .slotres,.slotmach.rtb .slotres{font-size:22px}
 .rtbladder{gap:9px}
 .rtbstep{padding:8px 15px;font-size:14px}
 .slotmach.bj{padding:34px 46px 30px;border-radius:22px}
 .slotmach.bj .slottop{font-size:30px;margin-bottom:22px}
 .bjrow{min-height:110px;gap:6px}
 .bjlab{font-size:12px}
 .bjcards{gap:9px;min-height:84px}
 .bjcard{width:58px;height:84px;border-radius:9px;font-size:21px}
 .bjtot{font-size:15px}
 .slotmach.bj .slotres{font-size:24px;margin-top:18px}
 .slotmach.bj .slotstats{font-size:13px}
 .bjact{font-size:17px;padding:15px 26px}
 .bjbtns{gap:10px;margin-top:16px}
 .slotmach.bj .slotbet{margin-top:16px;gap:10px}
 .slotmach.bj .qtybtn{width:30px;height:30px;font-size:15px}
 .slotmach.bj .qtynum{font-size:15px}
}
/* card deal + flip animations */
.bjcard{transform-style:preserve-3d;backface-visibility:hidden}
.bjcard.deal{animation:bjDeal .38s cubic-bezier(.2,1.3,.4,1) backwards}
.bjcard.okc{box-shadow:0 0 14px rgba(109,187,109,.85),0 2px 6px rgba(0,0,0,.45)}
.bjcard.badc{box-shadow:0 0 14px rgba(255,90,70,.9),0 2px 6px rgba(0,0,0,.45)}
@keyframes bjDeal{from{transform:translate(60px,-70px) rotate(14deg) scale(.6);opacity:0}to{transform:none;opacity:1}}
.bjcard.flip{animation:bjFlip .5s ease}
@keyframes bjFlip{0%{transform:rotateY(90deg) scale(1.06)}100%{transform:rotateY(0)}}
/* --- Casino building menu --- */
#casinoMenu{position:absolute;inset:0;z-index:71;display:none;align-items:center;justify-content:center;background:rgba(10,7,4,.86)}
#casinoMenu.open{display:flex}
.casinobox{width:min(92%,360px);padding:22px;border-radius:18px;border:2px solid var(--brass);background:linear-gradient(180deg,#332519,#150e08);box-shadow:0 14px 50px rgba(0,0,0,.6),0 0 24px rgba(217,164,65,.18);text-align:center}
.casinopick{display:flex;align-items:center;gap:12px;width:100%;margin:8px 0;padding:12px 14px;border-radius:12px;border:1px solid var(--brass-deep);background:linear-gradient(180deg,#332519,#241a12);color:var(--parch);cursor:pointer;text-align:left;transition:border-color .15s,transform .1s}
.casinopick:hover{border-color:var(--brass);transform:translateY(-1px)}
.casinopick.disabled{opacity:.48;cursor:not-allowed;filter:grayscale(.45)}
.casinopick.disabled:hover{border-color:var(--brass-deep);transform:none}
.casinopick .cg{font-size:26px;flex:0 0 auto}
.casinopick .ct{display:flex;flex-direction:column}
.casinopick .ct b{font-family:var(--display);font-size:15px;color:var(--parch)}
.casinopick .ct i{font-style:normal;font-size:11px;color:var(--dim);margin-top:2px}

.fmslot{width:64px;height:64px;border-radius:10px;border:2px dashed #c88a5a;display:flex;align-items:center;justify-content:center;font-size:26px;background:rgba(0,0,0,.25);color:#7a6a58}
.fmslot.filled{border-style:solid;color:#8fd0ff;box-shadow:0 0 12px rgba(120,190,255,.25)}
.fmslot.out{border-color:#ffd76a}
.fmslot.out.filled{color:#ffd76a;box-shadow:0 0 14px rgba(255,215,106,.3)}


  /* 🚜 farm store */
  .fsitem{border:1.5px solid #5a4630;border-radius:10px;background:rgba(46,32,20,.8);padding:6px;cursor:pointer}
  .fsitem:hover{border-color:#8a6a44}
  .fsitem.sel{border-color:#ffd76a;box-shadow:0 0 10px rgba(255,215,106,.25)}
  .fsitem.lock{opacity:.45;cursor:default}
  .fsitem img{width:100%;height:62px;object-fit:contain;display:block;pointer-events:none}
  .fsitem .fsn{font-size:11.5px;color:#e8dcc8;text-align:center;margin-top:4px;font-weight:600}
  .fsitem .fsl{font-size:10px;color:var(--dim);text-align:center;margin-top:2px}

/* ==================== 📱 STANDALONE (added to the Home Screen) ====================
   Installed there is no browser chrome that can slide in or out, so dvh has nothing
   dynamic left to track - yet iOS still reports 100dvh short of the home-indicator band,
   which leaves a dead strip under whatever sits at the bottom. lvh is the whole screen by
   definition, and it is safe HERE precisely because nothing can ever slide over it. In a
   Safari tab the same value would push the nav underneath the toolbar, which is why this
   is locked behind display-mode and why the rules live last: #app, #boot and the menu
   screens are all set earlier in the file at equal or higher specificity. */
@media (display-mode:standalone),(display-mode:fullscreen){
  #app,#boot{height:100lvh}
  body:has(#login.open) #app,body:has(#select.open) #app,body:has(#create.open) #app{height:100lvh}
}

/* --- venue backdrops: each modal keeps the .casinobox frame but gets its own painted interior.
   The gradient stays ON TOP of the art so body text keeps its contrast no matter how busy the
   picture is; the art is already darkened on disk, this is the second safety net. --- */
#bankFx .casinobox{background:linear-gradient(180deg,rgba(30,22,14,.78),rgba(14,10,6,.90)),url('assets/ui/modal_bank.png') center/cover no-repeat}
#casinoMenu .casinobox{background:linear-gradient(180deg,rgba(30,22,14,.78),rgba(14,10,6,.90)),url('assets/ui/modal_casino.png') center/cover no-repeat}
#restFx .slotmach{background:linear-gradient(180deg,rgba(30,22,14,.78),rgba(14,10,6,.90)),url('assets/ui/modal_inn.png') center/cover no-repeat}
#smithFx .casinobox{background:linear-gradient(180deg,rgba(30,22,14,.78),rgba(14,10,6,.90)),url('assets/ui/modal_smith.png') center/cover no-repeat}
#fishhutMenu .casinobox{background:linear-gradient(180deg,rgba(30,22,14,.78),rgba(14,10,6,.90)),url('assets/ui/modal_fish.png') center/cover no-repeat}
#mineFx .casinobox{background:linear-gradient(180deg,rgba(30,22,14,.78),rgba(14,10,6,.90)),url('assets/ui/modal_mine.png') center/cover no-repeat}
#smeltFx .casinobox{background:linear-gradient(180deg,rgba(30,22,14,.78),rgba(14,10,6,.90)),url('assets/ui/modal_smelter.png') center/cover no-repeat}
#enchFx .casinobox{background:linear-gradient(180deg,rgba(22,18,34,.80),rgba(10,8,16,.92)),url('assets/ui/modal_ench.png') center/cover no-repeat}
/* ⛧ the last door. Same treatment as the other painted modals: the art carries the mood, a dark
   wash over it carries the text. */
/* 🎮 the controller badge. Shown only while the pad is steering: touch the keyboard and it goes.
   It replaces a corner of raw axis numbers that was only ever there to get the pad working. */
#padBadge{position:absolute;left:8px;top:30px;z-index:30;display:none;font-size:17px;line-height:1;
 filter:drop-shadow(0 1px 2px rgba(0,0,0,.8));pointer-events:none}
#padBadge.on{display:block}
/* what the d-pad is standing on inside a panel */
.padfocus{outline:2px solid #ffd76a !important;outline-offset:2px;
 box-shadow:0 0 14px rgba(255,215,106,.55) !important;border-radius:8px}
#finalGateFx{position:absolute;inset:0;z-index:75;display:none;align-items:center;justify-content:center;background:rgba(4,8,14,.90)}
#finalGateFx.open{display:flex}
/* a lighter wash than the other modals: this backdrop is already almost black, so the usual
   0.78/0.93 turned it into a flat panel and the doorway vanished */
#finalGateFx .casinobox{background:linear-gradient(180deg,rgba(10,18,28,.46),rgba(4,8,14,.80)),url('assets/ui/modal_final.png') center/cover no-repeat;
 box-shadow:0 14px 50px rgba(0,0,0,.7),0 0 26px rgba(127,180,224,.20)}
/* ✨ the hall's rune inventory. Each cell carries its rune's own colour through --eg, so the grid
   reads as a rack of different magics rather than a row of identical buttons. */
.enchgrid{display:grid;grid-template-columns:repeat(5,1fr);gap:7px;margin-bottom:10px}
.enchcell{position:relative;aspect-ratio:1;padding:0;border-radius:9px;cursor:pointer;
          border:1px solid color-mix(in srgb,var(--eg) 45%,#000);background:rgba(0,0,0,.30);
          box-shadow:0 0 0 rgba(0,0,0,0);transition:box-shadow .18s,border-color .18s,transform .12s}
.enchcell:hover{transform:translateY(-1px);border-color:var(--eg);box-shadow:0 0 10px -1px var(--eg)}
.enchcell.on{border-color:var(--eg);box-shadow:0 0 14px -1px var(--eg),inset 0 0 12px -4px var(--eg)}
.enchico{width:100%;height:100%;object-fit:cover;border-radius:8px;pointer-events:none}
/* how many of this rune are in the hall - only drawn past the first */
.enchnum{position:absolute;right:-3px;bottom:-3px;min-width:17px;height:17px;padding:0 3px;
 border-radius:9px;background:#120d08;border:1px solid var(--eg);color:#f2e6cf;
 font:700 11px/15px var(--ui,sans-serif);text-align:center;pointer-events:none;
 box-shadow:0 0 8px -2px var(--eg)}

/* ✨ THE CUTTING. A rune is the end of a long chain - six ore, two coal, a smelt, an emerald - so
   it gets a moment rather than a line in the log. The book opens, the stones fall into the page,
   and what you got is held up for three seconds. Click anywhere to cut it short. */
#enchCraftFx{position:absolute;inset:0;z-index:96;display:none;align-items:center;justify-content:center;
 background:radial-gradient(ellipse at center,rgba(10,6,16,.72),rgba(3,2,6,.93))}
#enchCraftFx.open{display:flex}
.ecstage{position:relative;width:330px;height:250px;perspective:900px}
.ecbook{position:absolute;left:50%;top:52%;width:260px;height:170px;margin:-85px 0 0 -130px;
 transform-style:preserve-3d;animation:ecIn .55s cubic-bezier(.2,1.5,.4,1) both}
@keyframes ecIn{from{opacity:0;transform:scale(.5) rotateX(38deg)}to{opacity:1;transform:scale(1) rotateX(14deg)}}
.ecleaf{position:absolute;top:0;width:130px;height:170px;background:
 linear-gradient(180deg,#f0e2c2,#d8c49a 62%,#c2ac82);
 box-shadow:inset 0 0 22px rgba(120,90,50,.45);border:1px solid #8a6f45}
.ecleaf.l{left:0;border-radius:9px 2px 2px 9px;transform-origin:right center;
 animation:ecOpenL .7s .42s cubic-bezier(.3,.9,.3,1) both}
.ecleaf.r{left:130px;border-radius:2px 9px 9px 2px;transform-origin:left center;
 animation:ecOpenR .7s .42s cubic-bezier(.3,.9,.3,1) both}
@keyframes ecOpenL{from{transform:rotateY(72deg)}to{transform:rotateY(0)}}
@keyframes ecOpenR{from{transform:rotateY(-72deg)}to{transform:rotateY(0)}}
.ecspine{position:absolute;left:128px;top:-4px;width:4px;height:178px;border-radius:2px;
 background:linear-gradient(180deg,#5a3f22,rgba(90,63,34,.10) 34%,rgba(90,63,34,.10) 66%,#2e1f10);
 box-shadow:0 0 8px rgba(0,0,0,.5)}
.ecaura{position:absolute;left:50%;top:52%;width:430px;height:430px;margin:-215px 0 0 -215px;
 border-radius:50%;pointer-events:none;
 background:radial-gradient(circle,color-mix(in srgb,var(--eg) 70%,transparent),transparent 58%);
 opacity:0;animation:ecAura 2.4s .5s ease-out both}
@keyframes ecAura{0%{opacity:0;transform:scale(.5)}55%{opacity:.85;transform:scale(1)}100%{opacity:.35;transform:scale(1.06)}}
/* the stones fall in from the ring and land on the page */
.ecstone{position:absolute;left:50%;top:52%;width:32px;height:32px;margin:-16px 0 0 -16px;
 border-radius:7px;background:linear-gradient(160deg,#c6bba4,#756957 60%,#463e32);
 border:1px solid #2b241b;color:var(--eg);font:700 18px/30px serif;text-align:center;
 text-shadow:0 0 9px var(--eg);opacity:0;box-shadow:0 0 12px -3px var(--eg);
 animation:ecStone 1.25s cubic-bezier(.35,.05,.2,1) both}
@keyframes ecStone{
 0%{opacity:0;transform:translate(var(--sx),var(--sy)) rotate(var(--sr)) scale(1.2)}
 14%{opacity:1}
 66%{opacity:1;transform:translate(calc(var(--sx)*.12),calc(var(--sy)*.12)) rotate(calc(var(--sr)*.3)) scale(.95)}
 88%{opacity:.9;transform:translate(0,0) rotate(0) scale(.7)}
 100%{opacity:0;transform:translate(0,0) rotate(0) scale(.3)}}
.ecflash{position:absolute;left:50%;top:52%;width:8px;height:8px;margin:-4px 0 0 -4px;border-radius:50%;
 background:#fff;opacity:0;animation:ecFlash .5s 1.75s ease-out both;pointer-events:none}
@keyframes ecFlash{0%{opacity:0;transform:scale(1)}25%{opacity:.95;transform:scale(26)}100%{opacity:0;transform:scale(46)}}
/* and the rune itself, held up ON THE PAGE. Anchored to the book rather than to the stage: laid
   out against the stage the name and the flavour ran off the bottom edge onto the dark, which read
   as a caption under a picture instead of an entry written in the book. */
.ecgot{position:absolute;left:50%;top:52%;width:236px;text-align:center;opacity:0;
 animation:ecGot 3.6s 1.95s ease-out both}
@keyframes ecGot{0%{opacity:0;transform:translate(-50%,-44%) scale(.82)}
 12%{opacity:1;transform:translate(-50%,-50%) scale(1)}
 88%{opacity:1;transform:translate(-50%,-50%) scale(1)}
 100%{opacity:0;transform:translate(-50%,-55%) scale(1.02)}}
.ecgot img{width:54px;height:54px;border-radius:10px;border:1px solid var(--eg);
 box-shadow:0 0 22px -4px var(--eg);background:rgba(0,0,0,.45)}
.ecname{margin-top:5px;font-family:var(--display);font-size:19px;color:var(--eg);
 text-shadow:0 0 14px var(--eg),0 1px 0 rgba(60,40,15,.5)}
.ecflav{margin-top:1px;font-size:11px;color:#6b563a;font-style:italic;line-height:1.3}
.ectag{margin-top:5px;font-size:9.5px;color:#8a7458;letter-spacing:.7px;text-transform:uppercase}
.enchsel{margin-top:4px;padding:10px 12px;border-radius:11px;border:1px solid var(--line);background:rgba(0,0,0,.32)}
/* the rune bound to a weapon, top-right of its slot card, breathing in its own colour */
.enchmark{position:absolute;top:6px;right:6px;width:26px;height:26px;border-radius:7px;cursor:help;
          border:1px solid var(--eg);background:rgba(0,0,0,.35);overflow:hidden;
          animation:enchPulse 2.6s ease-in-out infinite}
.enchmark img{width:100%;height:100%;object-fit:cover;pointer-events:none}
@keyframes enchPulse{0%,100%{box-shadow:0 0 5px -1px var(--eg)}50%{box-shadow:0 0 13px 0 var(--eg)}}
.slot{position:relative}

/* venue title icons - they replace the emoji that used to sit in these headings. Height is in em so
   the icon scales with the heading's own font-size, and it is nudged onto the cap-height baseline. */
.venico{height:1.15em;width:auto;vertical-align:-0.18em;margin-right:.12em;
        filter:drop-shadow(0 2px 4px rgba(0,0,0,.55))}

/* 🎮 the pad is driving - the pointer goes away until the real mouse moves. The * is needed
   because buttons and the canvas set cursors of their own, and any one of them would keep an arrow
   on screen. */
body.padcursor, body.padcursor *{cursor:none!important}
