  .m-chcard{position:fixed;inset:0;z-index:520;background:rgba(0,0,0,0.78);
    display:none;align-items:center;justify-content:center;padding:16px}
  .m-chcard.open{display:flex}
  .m-chcard-inner{width:100%;max-width:400px;max-height:92vh;overflow-y:auto;
    -webkit-overflow-scrolling:touch;position:relative;padding:16px 16px 18px;
    background:linear-gradient(180deg,#28204a,#1a1535);
    border:1px solid #3a2860;border-radius:18px;box-shadow:0 10px 44px rgba(0,0,0,0.7)}
  .m-chcard-close{position:absolute;top:10px;right:12px;z-index:2;
    background:linear-gradient(180deg,#e04040,#b02020);border:2px solid #ff6060;color:#fff;
    width:30px;height:30px;border-radius:50%;font-size:18px;font-weight:700;line-height:1;
    cursor:pointer;display:flex;align-items:center;justify-content:center}
  .m-chcard-head{display:flex;align-items:center;gap:14px;padding:4px 0 12px}
  .m-chcard-portrait{width:84px;height:84px;object-fit:contain;flex-shrink:0;
    background:#140f28;border:1px solid #3a2860;border-radius:14px}
  .m-chcard-head-info{flex:1;min-width:0}
  .m-chcard-name-row{display:flex;align-items:center;gap:8px;min-width:0}
  .m-chcard-name{font-family:'Cinzel',serif;font-size:22px;font-weight:900;color:#fff;
    letter-spacing:1px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .m-chcard-edit{cursor:pointer;color:#c0a0f0;font-size:15px;line-height:1;opacity:.85;flex-shrink:0}
  .m-chcard-edit:active{transform:scale(.9)}
  .m-chcard-level{font-family:'Cinzel',serif;font-size:13px;font-weight:900;color:#f0d060;
    letter-spacing:2px;margin-top:2px}
  .m-chcard-active{display:none;margin-top:6px;font-size:10px;font-weight:800;letter-spacing:2px;
    color:#7de08a;background:#1a3524;border:1px solid #2e5e3e;border-radius:6px;
    padding:2px 8px;width:max-content}
  .m-chcard-active.show{display:block}
  .m-chcard-tabs{display:flex;gap:6px;margin:8px 0 10px}
  .m-chcard-tab{flex:1;padding:9px 4px;border-radius:9px;border:1px solid #3a2860;background:#1a1535;
    color:#8a7aaa;font-family:'Cinzel',serif;font-size:13px;font-weight:800;letter-spacing:1px;cursor:pointer}
  .m-chcard-tab.active{background:#241c40;color:#f0d060;border-color:#f0c060}
  .m-chcard-section-title{font-family:'Cinzel',serif;font-size:12px;font-weight:900;letter-spacing:3px;
    color:#c0a0f0;text-transform:uppercase;padding:10px 2px 8px;border-top:1px solid #3a286066;
    display:flex;align-items:center;justify-content:space-between}
  .m-chcard-pending{font-family:'Cinzel',serif;font-size:11px;font-weight:900;letter-spacing:1px;
    color:#0e0918;background:#f0c030;border-radius:20px;padding:2px 10px}
  /* Gear: 4 slots */
  .m-chcard-gear{display:grid;grid-template-columns:repeat(4,1fr);gap:8px}
  .m-chcard-slot{position:relative;aspect-ratio:1;background:#140f28;border:1px solid #3a2860;
    border-radius:12px;display:flex;align-items:center;justify-content:center;overflow:hidden}
  .m-chcard-slot img{width:78%;height:78%;object-fit:contain}
  .m-chcard-slot .m-chcard-slot-empty{font-size:9px;font-weight:800;letter-spacing:1px;color:#5a4a7a;text-transform:uppercase}
  .m-chcard-slot-label{position:absolute;bottom:2px;left:0;right:0;text-align:center;
    font-size:8px;font-weight:800;letter-spacing:1px;color:#8a7aaa;text-transform:uppercase}
  /* Derived character-sheet readout (top of Stats tab) */
  .m-csheet{background:#140f28;border:1px solid #2e2450;border-radius:10px;padding:8px 10px;margin-bottom:10px}
  .m-csheet-row{display:flex;justify-content:space-between;padding:4px 0;font-size:13px;color:#d8d0ea;border-bottom:1px solid #241c40}
  .m-csheet-row:last-child{border-bottom:none}
  .m-csheet-row span:first-child{color:#8a7aaa;font-size:12px}
  .m-cs-sub{color:#6a5a8a;font-size:11px}
  /* Stats: rows */
  /* Compact allocatable stats — same tight sheet style as the derived stats above (was big cards). */
  .m-chcard-stats{background:#140f28;border:1px solid #2e2450;border-radius:10px;padding:0 10px;display:flex;flex-direction:column}
  .m-chcard-stat{display:flex;align-items:center;gap:10px;padding:5px 0;border-bottom:1px solid #241c40}
  .m-chcard-stat:last-child{border-bottom:none}
  .m-chcard-stat-abbr{font-family:'Cinzel',serif;font-size:12px;font-weight:900;color:#f0d060;
    width:44px;flex-shrink:0;letter-spacing:1px}
  .m-chcard-stat-name{font-size:11px;color:#8a7aaa;flex:1;min-width:0}
  .m-chcard-stat-val{font-family:'Cinzel',serif;font-size:15px;font-weight:900;color:#fff;
    min-width:26px;text-align:right}
  .m-chcard-stat-plus{width:24px;height:24px;flex-shrink:0;border-radius:7px;border:none;
    background:linear-gradient(180deg,#7a3ff0,#5a28c0);color:#fff;font-size:17px;font-weight:700;
    line-height:1;cursor:pointer;display:flex;align-items:center;justify-content:center}
  .m-chcard-stat-plus:active{transform:translateY(1px)}
  .m-chcard-stat-plus.hidden{visibility:hidden}
  /* Set-bonus block (shown right under the derived sheet / Max HP). */
  .m-setbonus{background:#140f28;border:1px solid #2e2450;border-radius:10px;padding:8px 10px;margin-bottom:10px}
  .m-setbonus.active{border-color:#7a6320;background:linear-gradient(180deg,#241d0e,#160f24)}
  .m-setbonus-hd{font-family:'Cinzel',serif;font-size:12px;font-weight:900;letter-spacing:1px;color:#c0a0f0;display:flex;justify-content:space-between;align-items:center}
  .m-setbonus.active .m-setbonus-hd{color:#f0d060}
  .m-setbonus-hd b{color:#fff;font-size:13px}
  .m-setbonus.active .m-setbonus-hd b{color:#f0d060}
  .m-setbonus-eff{font-size:11px;color:#8a7aaa;margin-top:3px}
  .m-setbonus.active .m-setbonus-eff{color:#ffe6a0}
  .m-chcard-reset{text-align:center;margin:12px 0 4px;padding:8px;cursor:pointer;
    font-family:'Cinzel',serif;font-size:12px;font-weight:800;letter-spacing:1px;color:#c0a0f0;
    background:#140f28;border:1px solid #3a2860;border-radius:10px}
  .m-chcard-reset:active{opacity:0.8}
  /* Talent tree (Brawl-Stars style): tall + scrollable, hexagon gold nodes, thick curved gold lines. */
  .m-tal-wrap{position:relative;margin:6px 0 4px}
  .m-tal-scroll{max-height:64vh;overflow-y:auto;-webkit-overflow-scrolling:touch;
    background:linear-gradient(180deg,#2b3ea8,#3a6adf);border:1px solid #24306a;border-radius:12px;
    padding-bottom:140px}   /* room so the last row clears the floating footer */
  /* Description footer: pinned to the bottom of the tree area, slides up when a node is tapped. */
  .m-tal-foot{position:absolute;left:0;right:0;bottom:0;z-index:5;
    background:linear-gradient(180deg,rgba(20,15,40,.86),rgba(20,15,40,.98));
    border-top:1px solid #3a2860;border-radius:0 0 12px 12px;padding:8px 10px 10px;
    backdrop-filter:blur(3px);animation:talslideup .18s ease}
  @keyframes talslideup{from{transform:translateY(14px);opacity:.4}to{transform:translateY(0);opacity:1}}
  .m-tal-vrow{display:flex;align-items:center;justify-content:center;gap:8px;margin:4px 0 8px}
  .m-tal-tree{position:relative;width:100%}
  .m-tal-lines{position:absolute;inset:0;width:100%;height:100%;pointer-events:none;z-index:1}
  .m-tal-node{position:absolute;transform:translate(-50%,-50%);z-index:2;width:76px;height:76px;
    border:none;background:transparent;cursor:pointer;padding:0}
  .m-tal-node .m-tal-hex{position:absolute;inset:0;
    clip-path:polygon(25% 3%,75% 3%,100% 50%,75% 97%,25% 97%,0 50%);
    background:linear-gradient(180deg,#b9791a,#6d4506);display:flex;align-items:center;justify-content:center}
  .m-tal-node .m-tal-hex::before{content:'';position:absolute;inset:4px;
    clip-path:polygon(25% 3%,75% 3%,100% 50%,75% 97%,25% 97%,0 50%);
    background:linear-gradient(180deg,#ffe259,#f0a81e)}
  .m-tal-node .m-tal-ico{position:relative;z-index:1;font-size:30px;line-height:1;filter:drop-shadow(0 1px 1px rgba(0,0,0,.35))}
  .m-tal-node .m-tal-rank{position:absolute;left:50%;bottom:-9px;transform:translateX(-50%);z-index:3;
    background:linear-gradient(#ffd93b,#e8a81a);color:#5a3a00;border:2px solid #7a4e08;border-radius:8px;
    font:900 11px/1 'Cinzel',serif;padding:3px 8px;white-space:nowrap;box-shadow:0 2px 3px rgba(0,0,0,.3)}
  .m-tal-node.available{filter:drop-shadow(0 0 7px #fff3a0)}
  .m-tal-node.available .m-tal-hex{animation:talpulse 1.4s ease-in-out infinite}
  @keyframes talpulse{0%,100%{filter:brightness(1)}50%{filter:brightness(1.18)}}
  .m-tal-node.locked .m-tal-hex{background:linear-gradient(180deg,#4a4568,#2c2842)}
  .m-tal-node.locked .m-tal-hex::before{background:linear-gradient(180deg,#5c5680,#3a3556)}
  .m-tal-node.locked .m-tal-ico{opacity:.45;filter:grayscale(1)}
  .m-tal-node.locked .m-tal-rank{background:#5c5680;color:#c8c4e0;border-color:#3a3556}
  .m-tal-node.need{opacity:.9}
  .m-tal-node.sel{transform:translate(-50%,-50%) scale(1.12);filter:drop-shadow(0 0 8px #fff)}
  .m-tal-desc{background:#140f28;border:1px solid #2e2450;border-radius:10px;padding:8px 10px;margin-bottom:10px}
  .m-tal-desc-name{font-family:'Cinzel',serif;font-weight:900;color:#fff;font-size:14px;margin-bottom:6px}
  .m-tal-desc-txt{font-size:12px;color:#8a7aaa}
  .m-tal-val{font-family:'Cinzel',serif;font-weight:800;font-size:13px;white-space:nowrap;
    padding:6px 10px;border-radius:8px;border:1px solid #2e2450;background:#0e0a1e;color:#c8bce8}
  .m-tal-val.next{color:#7de08a;border-color:#2e5e3e;background:#12241a}
  .m-tal-arrow{color:#f0c060;font-size:13px;line-height:1}
  .m-chcard-actions{display:flex;gap:8px;margin-top:14px}
  .m-chcard-btn{flex:1;padding:11px 4px;border-radius:10px;border:1px solid #3a2860;
    background:#241c40;color:#c0a0f0;font-family:'Cinzel',serif;font-size:13px;font-weight:800;
    letter-spacing:1px;cursor:pointer}
  .m-chcard-btn:active{transform:translateY(1px)}
  .m-chcard-btn.primary{background:linear-gradient(180deg,#f0a838,#d0791e);color:#1a1005;border-color:#f0c060}
  .m-chcard-btn.primary.hidden{display:none}
  .m-chcard-btn.danger{color:#e88;border-color:#5a2830;background:#2a1620;flex:0 0 auto;padding:11px 14px}
  .m-econ-inner{width:100%;max-width:420px;height:88vh;
    background:linear-gradient(180deg,#28204a,#1a1535);
    border:2px solid #3a2860;border-radius:18px 18px 0 0;
    display:flex;flex-direction:column;overflow:hidden;
    box-shadow:0 -4px 32px rgba(0,0,0,0.7);animation:econSlideUp 0.22s cubic-bezier(0.2,1.3,0.4,1)}
  @keyframes econSlideUp{from{transform:translateY(60px);opacity:0}to{transform:translateY(0);opacity:1}}
  .m-econ-header{display:flex;align-items:center;justify-content:space-between;
    padding:14px 16px 0;flex-shrink:0}
  .m-econ-title{font-family:'Cinzel',serif;font-size:16px;font-weight:900;color:#c0a0f0;letter-spacing:2px}
  .m-econ-close{background:linear-gradient(180deg,#e04040,#b02020);border:2px solid #ff6060;
    color:#fff;width:30px;height:30px;border-radius:50%;font-size:18px;
    cursor:pointer;display:flex;align-items:center;justify-content:center;
    box-shadow:0 2px 0 #801010;flex-shrink:0}
  .m-econ-close:active{transform:scale(0.9)}
  .m-econ-tabs{display:flex;gap:0;padding:10px 16px 0;flex-shrink:0;border-bottom:1px solid #3a286066}
  .m-econ-tab{flex:1;padding:8px 4px;font-family:'Cinzel',serif;font-size:12px;font-weight:700;
    color:#8060a0;border:none;background:transparent;cursor:pointer;border-bottom:2px solid transparent;
    letter-spacing:1px;transition:0.15s;text-align:center}
  .m-econ-tab.active{color:#f0d060;border-bottom-color:#f0d060}
  .m-econ-tab:active{opacity:0.75}
  /* Right padding clears the wider bag scrollbar (scoped ::-webkit-scrollbar rule in lobby.html)
     plus a real visible gap past it, so the thumb isn't sitting flush against the item grid --
     it used to be 14px, which the 13px default rail almost entirely ate on its own. */
  #m-econ-body{flex:1;overflow-y:auto;-webkit-overflow-scrolling:touch;padding:12px 34px 24px 14px}
  /* Stash's own frame (big_frame.webp, see .m-econ-inner.treasure-mode in lobby.html) draws its gold
     border well in from the popup's true edge -- the generic padding above (tuned for Inventory/
     Craft's plain content) left .m-stash-row's two side frames poking past it. cqw/cqh so the inset
     stays proportional to the popup at any size, not a fixed px margin that reads differently on a
     1900px popup vs a 600px one. */
  .m-econ-inner.treasure-mode #m-econ-body{padding:7cqh 5cqw 4cqh}
  .m-econ-roster{display:flex;flex-direction:column;gap:10px}
  .m-econ-char{background:linear-gradient(180deg,#2e2456 0%,#1e183e 100%);
    border:2px solid #3a2860;border-radius:12px;padding:12px 14px;cursor:pointer;
    transition:border-color 0.15s}
  .m-econ-char.active{border-color:#f0d060;box-shadow:0 0 10px rgba(240,208,96,0.25)}
  .m-econ-char:active{transform:scale(0.98)}
  .m-econ-char-name{font-family:'Cinzel',serif;font-size:15px;font-weight:900;color:#fff;margin-bottom:2px}
  .m-econ-char-set{font-size:12px;color:#c0a0f0;margin-bottom:8px;letter-spacing:0.5px}
  .m-econ-char-actions{display:flex;gap:8px}
  .m-econ-char-actions button{padding:5px 12px;border-radius:8px;border:1px solid #4a3878;
    background:linear-gradient(180deg,#3a2870,#2a1e50);color:#c0a0f0;
    font-family:'Cinzel',serif;font-size:11px;font-weight:700;cursor:pointer;letter-spacing:0.5px}
  .m-econ-char-actions button:active{transform:scale(0.95);opacity:0.85}
  .m-econ-create-btn{width:100%;margin-top:12px;padding:12px;border-radius:12px;
    border:2px dashed #5a3aa0;background:rgba(90,58,160,0.15);
    color:#c0a0f0;font-family:'Cinzel',serif;font-size:14px;font-weight:700;
    cursor:pointer;letter-spacing:1px}
  .m-econ-create-btn:active{background:rgba(90,58,160,0.3)}
  .m-econ-note{text-align:center;color:#8060a0;font-size:12px;font-family:'Cinzel',serif;
    margin-top:12px;padding:10px}
  .m-econ-placeholder{text-align:center;color:#604880;font-size:13px;font-family:'Cinzel',serif;
    padding:40px 16px;opacity:0.7}
  .m-look-overlay{position:fixed;inset:0;background:rgba(8,4,20,.78);display:flex;align-items:center;justify-content:center;z-index:9000;padding:16px}
  .m-look-modal{background:linear-gradient(#28204a,#1a1535);border:1px solid #3a2860;border-radius:14px;padding:16px;width:min(420px,94vw);max-height:88vh;overflow:auto;color:#fff}
  .m-look-title{font-weight:700;color:#c0a0f0;text-align:center;margin-bottom:12px;letter-spacing:.04em}
  /* Bug report — was the one plain unskinned .m-look-modal box (see bug-report.js's buildPanel).
     Reuses the leaf-corner frame from the Stash redesign (heropopup/stash/big_frame.webp) rather than
     the plain heropopup/frame.webp every other popup uses, per Roman's ask for "these leaves from
     the new ones". Sized/scaled the same way .m-settings-land/.m-store-land are. */
  .m-bug-land{container-type:size;position:relative;
    /* Bigger again -- 672px->820px, 74vh->90vh (the real design-size terms), vw safety ceiling
       raised to 98vw since the popup is now large enough that it's a real constraint on a phone
       screen, not just headroom. Still all cqw/cqh below, so the whole popup -- text, button,
       icon -- keeps scaling together as one unit off this one width. */
    width:min(820px,98vw,calc(90vh*1125/680));aspect-ratio:1125/680;
    max-width:none;max-height:none;height:auto;display:flex;flex-direction:column;
    padding:0;overflow:visible;
    background:url('heropopup/stash/big_frame.webp') center/100% 100% no-repeat;
    border:none;border-radius:0;box-shadow:0 26px 80px #000d}
  .m-bug-close{position:absolute;top:1.4cqw;right:1.4cqw;width:9.8cqh;height:auto;aspect-ratio:1;
    z-index:4;padding:0;border:none;border-radius:0;box-shadow:none;font-size:0;cursor:pointer;
    color:transparent;background:url('heropopup/close.webp') center/contain no-repeat}
  .m-bug-close:hover{filter:brightness(1.12)}
  .m-bug-title{flex:none;text-align:center;font-family:'Cinzel',serif;font-weight:900;
    letter-spacing:.05em;text-transform:uppercase;font-size:3.4cqw;color:#f0d78f;
    padding:6cqh 12cqw 0;text-shadow:0 2px 4px #000b,0 0 1.2cqw #ffd98a33}
  /* Split into a scrollable top part (hint/gift/textarea) and a bottom bar that's a flex:none
     SIBLING, not just "the last thing in the flow" -- same docked-bar shape as .m-craft-bottombar,
     so the Send button stays pinned to the frame's bottom edge instead of drifting with content. */
  .m-bug-body{flex:1;min-height:0;display:flex;flex-direction:column;padding:1.6cqh 8cqw 3cqh;overflow:hidden}
  .m-bug-scroll{flex:1;min-height:0;display:flex;flex-direction:column;gap:1.6cqh;overflow-y:auto;padding-right:.2cqw}
  .m-bug-hint{font-size:2.5cqw;color:#c7bfe0;opacity:.85;line-height:1.4;text-align:center}
  /* Every report gets read; the reward line is what turns "why bother" into "worth ten seconds". */
  .m-bug-gift{font-size:1.9cqw;color:#ffd98a;text-align:center;line-height:1.4;font-weight:700}
  .m-bug-text{width:100%;box-sizing:border-box;resize:vertical;min-height:14cqh;flex:1;
    border-radius:1cqw;border:1px solid #4a3a7a;background:rgba(10,7,20,.55);color:#f0e4c0;
    font-family:'IBM Plex Sans',sans-serif;font-size:2.3cqw;padding:1.2cqh 1.4cqw}
  .m-bug-bottombar{flex:none;display:flex;flex-direction:column;align-items:center;gap:.8cqh;
    padding-top:1.4cqh;margin-top:1cqh;border-top:1px solid #3a2c6055}
  .m-bug-send{flex:none;position:relative;width:38%;aspect-ratio:723/202;
    border:none;padding:0;cursor:pointer;background:url('heropopup/golden_button.webp') center/100% 100% no-repeat;
    font-family:'Cinzel',serif;font-weight:900;letter-spacing:.06em;font-size:2.4cqw;color:#3a1c08;
    text-transform:uppercase;display:flex;align-items:center;justify-content:center}
  .m-bug-send:disabled{opacity:.55;cursor:default;filter:grayscale(.4)}
  .m-bug-send:not(:disabled):hover{filter:brightness(1.1)}
  .m-bug-status{text-align:center;min-height:1.6cqh;font-size:1.7cqw;color:#c0a0f0}
  .m-look-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:5px}
  /* Create Character is the one plain .m-look-modal left with real content (the others are all
     skinned frame.webp variants with their own width) -- widen just it via this override so its
     12-face grid lays out 6-across/2-row instead of 4-across/3-row. On the project's landscape
     mobile target (915x412) the 3-row version was taller than 88vh and forced an inner scroll;
     there's plenty of unused width in landscape to spend on this instead. */
  .m-createchar-land{width:min(580px,92vw);max-height:94vh;padding:18px 24px 12px;
    background:url('heropopup/frame.webp') center/100% 100% no-repeat;
    border:none;border-radius:0;box-shadow:0 26px 80px #000d}
  /* Back to 1fr columns filling the full row -- narrowing tiles via 12.5%-width columns +
     justify-content:center left empty gutters down BOTH sides of the grid, which just moved
     the "too much side space" problem from around each tile to around the whole grid instead.
     1fr + a narrower WINDOW gets small tiles that still fill edge-to-edge, no side gutters. */
  .m-createchar-land .m-look-grid{grid-template-columns:repeat(6,1fr)}
  .m-look-tile{background:#211a3e;border:2px solid #3a2860;border-radius:10px;padding:8px;cursor:pointer;display:flex;flex-direction:column;align-items:center;color:#c0a0f0}
  .m-look-tile img{width:100%;aspect-ratio:1/1;object-fit:contain}
  .m-look-tile span{font-size:11px;margin-top:2px}
  .m-look-tile.selected{border-color:#ffb74d;box-shadow:0 0 0 2px rgba(255,183,77,.4)}
  .m-look-name{width:100%;margin-top:12px;padding:10px;border-radius:8px;border:1px solid #3a2860;background:#1a1535;color:#fff;box-sizing:border-box}
  /* Name field: label + input SAME row (was label-above-input, its own line) to save vertical
     room now that the "pick a face" subtitle is gone and the row carries that job instead. */
  .m-look-name-row{display:flex;align-items:center;gap:10px;margin-top:25px}
  .m-look-name-label{flex:none;text-align:left;font-size:11px;font-weight:700;letter-spacing:.08em;color:#c0a0f0;opacity:.85;white-space:nowrap}
  .m-look-name-wrap{flex:1;position:relative;min-width:0}
  .m-look-name-wrap .m-look-name{margin-top:0;padding-right:38px}
  .m-look-name-pencil{position:absolute;right:12px;top:50%;transform:translateY(-50%);font-size:15px;opacity:.75;pointer-events:none}
  /* Plain gold hairline, same construction as the rule under .m-itemd-title/.m-settings-title --
     the craft_separator.webp image read badly stretched this wide against a flat card. */
  .m-look-sep{height:1px;margin:12px 0 8px;width:100%;
    background:linear-gradient(90deg,transparent,#d3ac5e 15%,#d3ac5e 85%,transparent)}
  .m-look-actions{display:flex}
  .m-look-actions button{flex:1;padding:10px;border-radius:8px;border:none;font-weight:700;cursor:pointer}
  .m-look-cancel{background:#2a2350;color:#c0a0f0}
  .m-look-confirm{background:#ffb74d;color:#241a00}
  /* Create Character's Create button — same golden_button.webp treatment as the Forge/Gem Altar
     action buttons, instead of the plain flat-orange .m-look-confirm every other confirm dialog
     still uses. */
  .m-createchar-land .m-look-actions{justify-content:center}
  .m-createchar-land .m-look-confirm{flex:none;width:209px;height:37px;max-width:88%;padding:0;
    display:flex;align-items:center;justify-content:center;font-size:13px;line-height:1;
    background:url('heropopup/golden_button.webp') center/100% 100% no-repeat;border-radius:0;
    color:#3a2408;text-shadow:0 1px 1px #ffd98a88;font-family:'Cinzel',serif;text-transform:uppercase;letter-spacing:.05em}
  .m-createchar-land .m-look-confirm:hover{filter:brightness(1.08)}
  /* ===== ECONOMY PANEL — Inventory Tab (Task 3) ===== */
  .m-econ-loadout{background:linear-gradient(180deg,#2e2456,#1e183e);border:1px solid #3a2860;
    border-radius:10px;padding:10px 12px;margin-bottom:14px}
  .m-econ-sub{font-family:'Cinzel',serif;font-size:11px;font-weight:700;color:#8060a0;
    letter-spacing:1px;text-transform:uppercase;margin-bottom:8px}
  .m-econ-slots{display:flex;gap:6px}
  .m-econ-slot{flex:1;background:rgba(0,0,0,0.3);border:1px solid #3a2860;border-radius:8px;
    padding:6px 4px;text-align:center;font-size:10px;color:#c0a0f0;font-family:'Cinzel',serif;
    min-height:54px;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:3px}
  .m-econ-slot button{padding:3px 6px;border-radius:5px;border:1px solid #5a3aa0;
    background:linear-gradient(180deg,#3a2870,#2a1e50);color:#c0a0f0;
    font-family:'Cinzel',serif;font-size:9px;font-weight:700;cursor:pointer}
  .m-econ-slot button:active{transform:scale(0.93)}
  .m-econ-empty{color:#4a3870;font-size:14px}
  .m-econ-invgroup{margin-bottom:14px}
  .m-econ-items{display:grid;grid-template-columns:repeat(2,1fr);gap:8px;margin-top:6px}
  .m-econ-item{background:linear-gradient(180deg,#2e2456,#1e183e);border:2px solid #3a2860;
    border-radius:10px;padding:10px 10px 8px;display:flex;flex-direction:column;gap:4px}
  .m-econ-item-name{font-family:'Cinzel',serif;font-size:12px;font-weight:700;
    line-height:1.2;word-break:break-word}
  .m-econ-item-rar{font-size:10px;color:#8060a0;text-transform:capitalize;letter-spacing:0.5px}
  .m-econ-item-actions{display:flex;gap:5px;flex-wrap:wrap;margin-top:4px}
  .m-econ-item-actions button{flex:1;padding:4px 6px;border-radius:7px;border:1px solid #4a3878;
    background:linear-gradient(180deg,#3a2870,#2a1e50);color:#c0a0f0;
    font-family:'Cinzel',serif;font-size:10px;font-weight:700;cursor:pointer;letter-spacing:0.3px}
  .m-econ-item-actions button:active{transform:scale(0.93);opacity:0.8}
  .m-econ-item-actions button.sell{background:linear-gradient(180deg,#6b2020,#4a1010);
    border-color:#aa3030;color:#ffaaaa}
  /* ===== PAPER-DOLL INVENTORY (equip slots around 3D preview + draggable grid) ===== */
  .m-pd-dock{ position:relative; width:100%; max-width:340px; margin:0 auto 14px;
    display:flex; align-items:stretch; gap:6px; }
  .m-pd-col{ display:flex; flex-direction:column; justify-content:space-between;
    gap:10px; flex:0 0 64px; padding:6px 0; }
  .m-pd-mid{ flex:1; display:flex; flex-direction:column; align-items:center; }
  /* taller preview so bottom-center Armor slot has room */
  .m-pd-mid .m-char-preview{ width:150px; height:210px; margin:0 auto; }
  .m-pd-look{ width:120px; height:120px; object-fit:contain; margin:4px auto; display:block; }
  .m-pd-bottom{ display:flex; justify-content:center; margin-top:4px; }
  /* an equipment slot square */
  .m-pd-slot{ width:60px; height:60px; border-radius:12px; box-sizing:border-box;
    border:2px solid #4a3878; background:rgba(0,0,0,0.32);
    display:flex; flex-direction:column; align-items:center; justify-content:center;
    position:relative; cursor:pointer; touch-action:none; overflow:hidden;
    transition:border-color .12s, box-shadow .12s, background .12s; }
  .m-pd-slot:active{ transform:scale(0.95); }
  .m-pd-slot img{ width:46px; height:46px; object-fit:contain; pointer-events:none; }
  .m-pd-slot .m-pd-slot-lbl{ font-family:'Cinzel',serif; font-size:8px; font-weight:700;
    color:#7a5fb0; letter-spacing:0.5px; text-transform:uppercase; }
  .m-pd-slot .m-pd-fallback{ font-family:'Cinzel',serif; font-size:8px; font-weight:700;
    line-height:1.05; padding:2px; text-align:center; word-break:break-word; }
  .m-pd-slot.filled{ background:rgba(20,10,40,0.55); }
  /* slot highlighted as a valid drop target during a drag */
  .m-pd-slot.drop-ok{ border-color:#7fffa0; box-shadow:0 0 12px rgba(120,255,150,0.7);
    background:rgba(40,90,40,0.35); }
  .m-pd-slot.drop-bad{ border-color:#ff7070; box-shadow:0 0 10px rgba(255,90,90,0.5); }
  /* While dragging an item: the one matching slot pulses, all others gray out so the
     player instantly sees where the item goes. */
  .m-pd-slot.pd-target{ border-color:#7fffa0; box-shadow:0 0 14px rgba(120,255,150,0.85);
    animation:m-pd-pulse 0.9s ease-in-out infinite; }
  .m-pd-slot.pd-dim{ opacity:0.28; filter:grayscale(1); }
  @keyframes m-pd-pulse{ 0%,100%{box-shadow:0 0 8px rgba(120,255,150,0.55);} 50%{box-shadow:0 0 16px rgba(120,255,150,0.95);} }
  @keyframes m-pd-shake{ 0%,100%{transform:translateX(0)} 25%{transform:translateX(-4px)}
    75%{transform:translateX(4px)} }
  .m-pd-shake{ animation:m-pd-shake .25s ease; }
  /* inventory grid of square cells */
  .m-pd-grid{ display:grid; grid-template-columns:repeat(4,1fr); gap:8px; margin-top:4px; }
  /* spatial backpack: fixed-size cells on an 8-wide board; items span their footprint */
  /* Diablo-style grid: adjacent cells, no gaps, no frames */
  .m-pd-grid.spatial{ --inv-cell:36px; grid-template-columns:repeat(var(--inv-cols,8), var(--inv-cell)); grid-auto-rows:var(--inv-cell); gap:0; justify-content:start; width:fit-content; margin:6px 0 0; }
  /* Left-align the board so ALL the leftover width becomes one wide right-hand gutter, plus a
     bottom scroll-pad — cells capture touch for drag, so scrolling must start off the grid. */
  .m-inv-scrollpad{ height:88px; }
  .m-pd-grid.spatial .m-pd-cell{ aspect-ratio:auto; width:auto; height:auto; z-index:1; }
  /* Faint board grid so you can read which cells are occupied vs free (Diablo squares) — this is a
     board line, NOT a frame around each item. Items themselves stay frameless. */
  .m-pd-grid.spatial .m-invcell-bg{ border:none; border-radius:0; background:#140d2e; box-shadow:inset 0 0 0 1px rgba(150,120,210,.11); }
  /* clean tile: transparent (no box/frame); the weapon icon fills its whole footprint; rarity = a glow filter */
  .m-pd-grid.spatial .m-pd-cell.m-pd-clean{ background:transparent; border:none; border-radius:0; overflow:visible; }
  .m-pd-grid.spatial .m-pd-cell.m-pd-clean img{ width:100%; height:100%; object-fit:contain; margin:0; }
  /* Per-item icon sizing (visual only — footprint unchanged; overflow is visible so it can spill past the cell).
     Keyed on data-fp (the footprint/shape kind), so 2H greatsword/hammer size correctly regardless of play tag.
     Order matters: the specific data-fp rules come AFTER the generic weapon rule so they win. */
  .m-pd-grid.spatial .m-pd-cell.m-pd-clean[data-slot="weapon"] img{ transform:scale(1.1); }
  /* spear + greatsword are both 1x3 (2-handed). Their icons are SQUARE, so a uniform scale-up spills
     sideways and reads as "2 wide". Grow them mostly VERTICALLY instead: fill the tall slot, stay ~1 cell wide. */
  .m-pd-grid.spatial .m-pd-cell.m-pd-clean[data-fp="spear"] img{ transform:scale(1.15, 2.3); }
  .m-pd-grid.spatial .m-pd-cell.m-pd-clean[data-fp="greatsword"] img{ transform:scale(1.15, 2.3); }
  .m-pd-grid.spatial .m-pd-cell.m-pd-clean[data-fp="hammer"] img{ transform:scale(1.25); }
  .m-pd-grid.spatial .m-pd-cell.m-pd-clean[data-fp="bow"] img{ transform:scale(0.95); }
  .m-pd-grid.spatial .m-pd-cell.m-pd-clean[data-slot="armor"] img{ transform:scale(0.95); }   /* 5% smaller */
  .m-pd-grid.spatial .m-pd-cell.m-pd-clean[data-slot="offhand"] img{ transform:scale(0.9); }   /* shield a bit smaller */
  /* no red frame on over-capacity tiles — the board is frameless (a bloated bag just scrolls). */
  .m-pd-grid.spatial .m-pd-cell.overcap{ outline:none; }
  /* While dragging: dim the OTHER items (the places you can't drop) so free cells stand out. */
  .m-pd-grid.spatial.pd-dragging .m-pd-cell[data-inst]:not(.drag-source){ opacity:0.4; transition:opacity .08s; }
  /* Live drop-target box: green where the item fits, red where it doesn't. */
  .m-pd-drophi{ position:relative; z-index:6; pointer-events:none; border-radius:3px; }
  .m-pd-drophi.ok{  background:rgba(70,215,120,0.30); box-shadow:inset 0 0 0 2px #46d06a; }
  .m-pd-drophi.bad{ background:rgba(220,70,70,0.30);  box-shadow:inset 0 0 0 2px #e05656; }
  .m-pd-grid.spatial .m-pd-cell.m-pd-clean .m-pd-name,
  .m-pd-grid.spatial .m-pd-cell.m-pd-clean .m-pd-rar,
  .m-pd-grid.spatial .m-pd-cell.m-pd-clean .m-pd-sell{ display:none; }
  .m-pd-cell.overcap{ outline:2px solid #d05656; outline-offset:-2px; }
  .m-inv-headbar{ display:flex; align-items:center; justify-content:space-between; margin:8px 0 4px; color:#c0a0f0; font-size:12px; }
  .m-inv-sortbtn{ background:#3a2860; border:1px solid #5a3a90; color:#fff; border-radius:8px; padding:4px 13px; font-size:12px; font-weight:600; cursor:pointer; }
  .m-pd-cell{ position:relative; aspect-ratio:1/1; border-radius:10px; box-sizing:border-box;
    border:2px solid #3a2860; background:linear-gradient(180deg,#2e2456,#1e183e);
    display:flex; align-items:center; justify-content:center;
    cursor:grab; touch-action:none; overflow:hidden;
    transition:transform .1s, box-shadow .1s; }
  .m-pd-cell:active{ transform:scale(0.94); }
  .m-pd-cell img{ width:70%; height:62%; object-fit:contain; pointer-events:none; margin-bottom:13%; }
  /* item name under the icon — one line, auto-ellipsis to fit the cell (~10-12 chars fit) */
  .m-pd-cell .m-pd-name{ position:absolute; left:2px; right:2px; bottom:1px; text-align:center;
    font-family:'Cinzel',serif; font-size:8px; font-weight:700; color:#e8dcff; line-height:1.1;
    white-space:nowrap; overflow:hidden; text-overflow:ellipsis; text-shadow:0 1px 2px #000;
    pointer-events:none; }
  .m-pd-cell .m-pd-fallback{ font-family:'Cinzel',serif; font-size:9px; font-weight:700;
    line-height:1.05; padding:3px; text-align:center; word-break:break-word; }
  .m-pd-cell.equipped{ opacity:0.55; }
  .m-pd-cell .m-pd-rar{ position:absolute; top:3px; left:3px; width:8px; height:8px;
    border-radius:50%; box-shadow:0 0 4px rgba(0,0,0,0.6); }
  /* Imbued-element badge (top-left corner) — glow is reserved for rarity now (see _rarityGlow),
     an element instead shows as this small icon so the two don't compete for the same signal.
     Used both in the spatial backpack grid (.m-pd-cell) AND the equip-slot boxes (.m-pd-slot,
     e.g. the equipped weapon). !important: .m-pd-grid.spatial .m-pd-cell.m-pd-clean img (4
     classes+tag), plain .m-pd-cell img, .m-chcard-inner.skinned .m-pd-slot img (3 classes+tag),
     and plain .m-pd-slot img all out-specificity a plain-class rule and were stretching this to
     fill the whole cell/slot -- confirmed via grep, not guessed. */
  /* cqw not px: this badge lives inside .m-chcard-inner.skinned's size container, which scales the
     whole card (and everything painted on it) as one unit -- a px badge would stay a fixed physical
     size while the card around it grows/shrinks with the screen. */
  .m-pd-cell .m-pd-elem, .m-pd-slot .m-pd-elem{ position:absolute!important; top:.3cqw!important; left:.3cqw!important;
    z-index:4; width:1.8cqw!important; height:1.8cqw!important; margin:0!important; object-fit:contain;
    pointer-events:none; filter:drop-shadow(0 1px 2px rgba(0,0,0,0.8)); }
  .m-pd-cell .m-pd-eq{ position:absolute; top:2px; right:3px; font-family:'Cinzel',serif;
    font-size:8px; font-weight:700; color:#9fff9f; letter-spacing:0.5px; }
  .m-pd-cell .m-pd-sell{ position:absolute; bottom:2px; right:3px; font-family:'Cinzel',serif;
    font-size:8px; font-weight:700; color:#ffb0b0; padding:1px 4px; border-radius:6px;
    background:rgba(90,16,16,0.85); cursor:pointer; pointer-events:auto; }
  .m-pd-cell.drag-source{ opacity:0.3; }
  /* Item the viewed hero can't yet equip (level/attr requirement unmet). UX only — server gates. */
  .m-pd-cell.req-unmet{ opacity:0.42; filter:grayscale(0.7); }
  .m-pd-cell .m-pd-req{ position:absolute; left:1px; right:1px; bottom:1px; z-index:5; text-align:center;
    font-family:'Cinzel',serif; font-size:8px; font-weight:700; color:#ff8f8f; line-height:1.1;
    white-space:nowrap; overflow:hidden; text-overflow:ellipsis; text-shadow:0 1px 2px #000;
    background:rgba(60,10,10,0.72); border-radius:5px; padding:0 2px; pointer-events:none; }
  .m-core-row{display:flex;flex-wrap:wrap;align-items:center;gap:8px;margin:8px 0;padding:8px;border:1px solid #3a2860;border-radius:10px;background:#1a1535}
  .m-core-gem{width:38px;height:38px;border-radius:9px;display:flex;align-items:center;justify-content:center;font-size:20px;color:#1a1535;position:relative;cursor:pointer;box-shadow:0 0 10px rgba(255,255,255,.15)}
  .m-core-gem.empty{background:#241c44;color:#6a5a9a;box-shadow:none}
  .m-core-gem .m-core-t{position:absolute;bottom:-2px;right:1px;font-size:9px;font-weight:800;color:#000}
  .m-core-lbl{font-size:11px;color:#c0a0f0;flex:1;min-width:120px}
  .m-core-pouch{display:flex;flex-wrap:wrap;gap:6px;width:100%}
  .m-core-chip{padding:4px 9px;border-radius:8px;border:1.5px solid #555;background:#241c44;color:#fff;font-size:11px;font-weight:700;cursor:pointer}
  .m-core-empty{font-size:11px;color:#8060a0}
  /* item detail popup */
  .m-itemd-meta{ font-family:'Cinzel',serif; font-size:12px; color:#c0a0f0; margin-bottom:6px; letter-spacing:1px; }
  /* a super FORGED onto the weapon (ability1/2), named in the meta line so same-gem swords read apart */
  .m-itemd-forged{ color:#ffd27a; }
  .m-itemd-set{ font-size:12px; color:#e8dcff; margin-bottom:10px; }
  .m-itemd-stats{ display:flex; flex-direction:column; gap:6px; margin-bottom:12px; }
  .m-itemd-stat{ background:#211a3e; border:1px solid #3a2860; border-radius:8px; padding:8px; color:#7ddf3c; font-weight:700; font-size:13px; }
  /* Rolled weapon damage window */
  .m-itemd-dmg{ font-family:'Cinzel',serif; font-size:16px; font-weight:800; color:#ffcf6b; margin:2px 0 8px; letter-spacing:0.5px; }
  /* Rolled affix chips (+n STR/INT/AGI/HP/MRES) */
  .m-itemd-afxrow{ display:flex; flex-wrap:wrap; gap:6px; justify-content:center; margin-bottom:10px; }
  .m-itemd-afx{ background:#2a2150; border:1px solid #4a3878; border-radius:12px; padding:3px 10px; color:#c0a0f0; font-weight:700; font-size:12px; }
  /* Equip requirement chips — green met, red unmet */
  .m-itemd-reqrow{ display:flex; flex-wrap:wrap; gap:6px; justify-content:center; align-items:center; margin:-4px 0 12px; }
  .m-itemd-req{ border-radius:8px; padding:3px 10px; font-family:'Cinzel',serif; font-weight:700; font-size:12px; letter-spacing:0.5px; }
  .m-itemd-req.ok{ background:rgba(40,80,30,0.55); border:1px solid #3f7a2f; color:#9fff9f; }
  .m-itemd-req.bad{ background:rgba(80,16,16,0.6); border:1px solid #a03030; color:#ff8f8f; }
  .m-itemd-reqwarn{ color:#ff8f8f; font-size:11px; font-weight:600; width:100%; }
  /* the floating ghost that follows the pointer */
  .m-pd-ghost{ position:fixed; z-index:5000; width:60px; height:60px; pointer-events:none; opacity:0.85;
    border:none; background:transparent; display:flex; align-items:center; justify-content:center;
    filter:drop-shadow(0 4px 10px rgba(0,0,0,0.7)); transform:translate(-50%,-50%); }
  /* moved by transform on its own layer (hero-main.js _pdMoveGhost, 2026-09-29) — the inline transform
     carries the -50%/-50% centring the rule above gives the left/top version */
  .m-pd-ghost.fx-t{ left:0; top:0; will-change:transform; }
  .m-pd-ghost img{ width:100%; height:100%; object-fit:contain; }
  .m-pd-ghost .m-pd-fallback{ font-family:'Cinzel',serif; font-size:9px; font-weight:700;
    text-align:center; line-height:1.05; }
  /* a drop-zone over the inventory grid for unequip while dragging an equipped slot */
  .m-pd-grid.unequip-arm{ box-shadow:0 0 0 2px rgba(255,180,90,0.6) inset; border-radius:12px; }
  .m-pd-hint{ text-align:center; color:#7a5fb0; font-size:10px; font-family:'Cinzel',serif;
    margin:2px 0 8px; letter-spacing:0.3px; }
  /* ===== CHARACTER PREVIEW (body + gear layers) ===== */
  .m-char-preview{ position:relative; width:160px; height:200px; margin:0 auto 10px; }
  .m-char-preview .m-prev-layer{ position:absolute; left:0; top:0; width:100%; height:100%; object-fit:contain; pointer-events:none; }
  /* 3D viewer canvas overlays the static PNG stack; only shown once a frame renders */
  .m-char-preview .hb3d-holder{ position:absolute; left:0; top:0; width:100%; height:100%; z-index:5; cursor:grab; }
  .m-char-preview .hb3d-holder:active{ cursor:grabbing; }
  .m-char-preview .hb3d-holder canvas{ display:block; width:100%; height:100%; touch-action:none; }
  /* Task 4: Craft tab */
  .m-econ-craftrows{display:flex;flex-direction:column;gap:8px;margin-top:6px;margin-bottom:14px}
  .m-econ-craftrow{display:flex;align-items:center;gap:8px;background:linear-gradient(180deg,#2e2456,#1e183e);
    border:1px solid #3a2860;border-radius:10px;padding:10px 12px}
  .m-econ-craft-slot{font-family:'Cinzel',serif;font-size:12px;font-weight:700;color:#c0a0f0;flex:0 0 56px}
  .m-econ-craft-frag{font-family:'Cinzel',serif;font-size:11px;color:#8060a0;flex:1;text-align:center}
  .m-econ-craft-btn{padding:6px 12px;border-radius:8px;border:1px solid #6a4ab0;
    background:linear-gradient(180deg,#5a3aa0,#3a2870);color:#f0d060;
    font-family:'Cinzel',serif;font-size:11px;font-weight:700;cursor:pointer;letter-spacing:0.5px;
    flex:0 0 auto;transition:opacity 0.2s}
  .m-econ-craft-btn:active{transform:scale(0.93);opacity:0.8}
  .m-econ-craft-btn[disabled]{opacity:0.35;cursor:default;pointer-events:none}
  /* 💎 gem craft picker */
  .m-gc-label{font-size:10px;color:#8a7aaa;letter-spacing:1px;text-transform:uppercase;margin:10px 0 4px}
  .m-gc-row{display:flex;gap:6px;overflow-x:auto;padding:2px 0 6px;-webkit-overflow-scrolling:touch}
  .m-gc-item{position:relative;flex:0 0 auto;width:52px;height:52px;background:#161029;border:2px solid #2a2246;border-radius:10px;padding:3px;cursor:pointer;transition:border-color .1s}
  .m-gc-item img{width:100%;height:100%;object-fit:contain}
  .m-gc-item.sel{border-color:#ffd48a;box-shadow:0 0 8px #ffd48a66}
  .m-gc-item:active{transform:scale(.93)}
  .m-gc-el{position:absolute;right:-3px;bottom:-3px;width:20px;height:20px;background:#0d0a18;border-radius:50%;padding:2px;border:1px solid #3a2860}
  .m-gc-el img{width:100%;height:100%}
  .m-gc-cnt{position:absolute;right:1px;bottom:0;font-size:9px;color:#ffcf6b;font-weight:700;text-shadow:0 1px 2px #000}
  .m-gc-socket{display:block;width:100%;margin-top:12px;text-align:center;padding:11px;font-size:14px}
  /* Gem ability preview: a grid of every ability that element could roll, each with its effect GIF. */
  .m-gc-abils{display:grid;grid-template-columns:repeat(2,1fr);gap:8px;margin:4px 0 2px}
  .m-gc-abil{background:#161029;border:1px solid #2a2246;border-radius:10px;padding:6px;text-align:center}
  .m-gc-abil img{width:100%;aspect-ratio:1;object-fit:contain;background:#0a0714;border-radius:6px;display:block}
  .m-gc-abil-n{font-family:'Cinzel',serif;font-weight:800;font-size:12px;color:#f0d060;margin-top:4px;line-height:1.15}
  .m-gc-abil-d{font-size:10px;color:#c0a0d0;line-height:1.3;margin-top:1px}
  /* Craft reveal overlay */
  #m-craft-reveal{display:none;position:fixed;inset:0;z-index:600;background:rgba(0,0,0,0.75);
    justify-content:center;align-items:center}
  #m-craft-reveal.open{display:flex}
  .m-craft-reveal-inner{background:linear-gradient(180deg,#2e2456,#1a1535);border:3px solid #fff;
    border-radius:18px;padding:28px 32px;text-align:center;min-width:200px;
    animation:craftPop 0.28s cubic-bezier(0.34,1.56,0.64,1) both}
  @keyframes craftPop{from{transform:scale(0.6);opacity:0}to{transform:scale(1);opacity:1}}
  .m-craft-reveal-rar{font-family:'Cinzel',serif;font-size:13px;font-weight:900;
    letter-spacing:3px;margin-bottom:8px;text-shadow:0 0 14px currentColor}
  .m-craft-reveal-name{font-family:'Cinzel',serif;font-size:20px;font-weight:900;color:#fff;
    margin-bottom:14px;line-height:1.2}
  .m-craft-reveal-tap{font-size:11px;color:#6048a0;font-family:'Cinzel',serif;letter-spacing:1px}

/* ══ IN-GAME PANEL MODE ═══════════════════════════════════════════════════════════
   The Unity bag button (HudUI) shows THIS popup on top of the running 3D battle via
   LobbyWebView.OpenInGamePanel — the WebView survives into the battle scene, so the
   in-game window is literally the lobby's, not a Unity rebuild.

   The WebView is composited transparently over the game, so everything the lobby would
   otherwise paint must be suppressed or it covers the battle. We use `visibility`
   rather than `display` so the card can be switched back on at any nesting depth
   without this file needing to know the DOM in between — and a hidden ancestor still
   paints no background. */
/* A MATCH IS RUNNING BEHIND THIS PAGE (hbSetInMatch, js/api-base.js). This class was toggled for a
   year and styled by nothing, so the JOURNEY and ARENA tiles stayed live under every in-game panel;
   pressing JOURNEY there started a second chapter over the running one. The launchers are refused in
   code too (hb3dLaunchBattle, LobbyWebView.StartMatch) — this just stops offering them. */
body.hb-in-match .cta.journey,
body.hb-in-match .cta.battle,
body.hb-in-match .m-journey-enter{display:none !important}
/* The chest's six spark animations are filter/drop-shadow keyframes — repainted every frame, and
   `visibility:hidden` does not stop a CSS animation. Nobody sees the chest during a fight. */
body.hb-in-match .chest .spark{animation:none !important}
/* And the gift button's glow + bounce (2026-09-29): an in-game panel only HIDES the lobby
   (visibility), which does not stop an animation — so a claimable gift kept the page producing frames
   under the bag, over the running battle. */
body.hb-in-match .rbtn.gift::before,
body.hb-in-match .rbtn.gift .ricon{animation:none !important}
body.hb-ingame-panel{background:transparent !important}
body.hb-ingame-panel *{visibility:hidden !important}
body.hb-ingame-panel #m-chcard,
body.hb-ingame-panel #m-chcard *{visibility:visible !important}
/* The card is not the only thing that must show. Tapping an item opens the ITEM-DETAIL popup
   (openItemDetail), and the lobby appends that overlay to document.BODY — outside #m-chcard — so the
   blanket hide above swallowed it: in-game the popup opened, invisibly, and tapping an item looked
   like it did nothing. Any .m-look-overlay modal is part of the bag flow, so show it too. */
body.hb-ingame-panel .m-look-overlay,
body.hb-ingame-panel .m-look-overlay *{visibility:visible !important}
/* The blacksmith opens the FORGE, which lives in the economy panel — another top-level element, so it
   needs the same exemption or it would open invisibly exactly like the item popup did. */
body.hb-ingame-panel #m-econ-panel,
body.hb-ingame-panel #m-econ-panel *{visibility:visible !important}
/* …and the FORGE'S OWN RESULT. #m-craft-sim (the success/fail clip with the gem composited into it)
   and #m-craft-reveal are both appended to document.BODY, so the blanket hide swallowed them too:
   in-game you'd imbue, the server would report success, and you'd see no video and no outcome at all
   — the third time this list has been the cause (item popup, then the forge panel, now the reveal).
   ANY new top-level overlay needs a line here, or it opens invisibly in-game and looks broken. */
body.hb-ingame-panel #m-craft-sim,
body.hb-ingame-panel #m-craft-sim *,
body.hb-ingame-panel #m-craft-reveal,
body.hb-ingame-panel #m-craft-reveal *{visibility:visible !important}
/* …and the GAME POPUP (game-popup.js: showGamePopup / showGameConfirm, root #game-popup-root) — the
   fourth top-level overlay this list swallowed. Every gear REFUSAL goes through it: unequip with a
   full bag answers 409 bag_full with a sentence to show, and in-game that sentence opened invisibly.
   Roman, 2026-09-02, ranger set on, bag full: "why doesn't Unequip work at all?" — it was refused,
   correctly, and the refusal was hidden by this file. */
body.hb-ingame-panel #game-popup-root,
body.hb-ingame-panel #game-popup-root *{visibility:visible !important}
/* …and THE REWARD TOAST — the FIFTH time, and the one this list was warned about above. Roman,
   2026-09-16, buying in the shop: "even on the FREE or AD track there should be a small popup at the
   bottom showing what we got… maybe there is one and the shop is above it?" There IS one, it already
   fires, and the shop is NOT above it — `.toast` sits at z-index 9700 against the store's 9000 since
   a2be184f. THIS is what hid it: the store opens with body.hb-ingame-panel (api-base.js openPanel
   {tab:'store'}), so every FREE / WATCH AD / gold->crystals claim has been calling showRewardToast
   and flyRewardToHud into an element the blanket hide above had already made invisible.
   `.m-fly-icon` is appended to document.body by flyRewardToHud and needs the same line. */
body.hb-ingame-panel .toast,
body.hb-ingame-panel .toast *,
body.hb-ingame-panel .m-fly-icon{visibility:visible !important}
/* lighter than the lobby's 0.78 so the fight stays readable behind the card */
body.hb-ingame-panel #m-chcard{background:rgba(0,0,0,0.55) !important}

/* Equipping mid-match USED to be blocked here, because the running fight was built from a
   loadout snapshot and a DB write could never reach it. It can now: /api/me/gear/equip and
   /gear/unequip re-gear the live hero (main.ts regearLiveJourneyPlayer -> Player.regear), and
   the client re-attaches the meshes when equippedGear changes (HeroFactory.ApplyGear). Journey
   only — in the shared arena the bag isn't even shown. So no pointer-events lock any more. */

/* (There was an explanatory banner here about run loot only reaching the bag at match end.
   Removed at the user's request — it ate a row of the grid every time the bag was opened.
   The behaviour is unchanged: round-manager still banks p.droppedItems when the match ends.) */

/* ═══════════ WEAPON ELEMENT TRACKS — Craft "Element Levels" + the item-detail popup ═══════════
   cqw/cqh, never px: both hosts are `container-type:size` boxes (.m-econ-inner for the forge,
   .m-itemd-land for the item popup, both in lobby.html) which scale the whole card — and
   everything painted on it — as ONE unit. Same reason as the .m-pd-elem badge comment above:
   a px row would stay a fixed physical size while the card around it grows/shrinks with the
   screen. Named m-etrack-* (element track) so it can't collide with lobby2.html's season
   .m-track-* rules. The sibling .m-craft-* rules live in lobby.html's inline <style>. */
.m-craft-etracks{flex:none;margin-top:1.2cqh;padding-top:1cqh;border-top:1px solid #3a2c6055}
.m-craft-etracks .m-craft-collabel{margin-bottom:.6cqh}
/* Level readout, up near the ability name where there's real room for it (not crammed into the
   bottom action row any more). */
.m-etrack-toplvl{display:flex;align-items:center;gap:.6cqw;margin:.3cqh 0 .6cqh;font-size:1.35cqw}
.m-etrack-name{flex:none;font-family:'Cinzel',serif;font-weight:800;letter-spacing:.04em;color:#f0d78f}
.m-etrack-lvl{flex:none;color:#fff;font-weight:800}
/* level 0 — the passive is bought but not switched on, so it reads as an absence, not a number */
.m-etrack-lvl.off{color:#8a93ad;font-weight:700;font-style:italic}
/* Read-only mirror on the item-detail popup. Its container (.m-itemd-land) is TALL and narrow, so
   those rules size in cqh — matched here so this block doesn't shrink with the card's width. */
.m-itemd-tracks{display:flex;flex-direction:column;gap:.3cqh;width:100%;margin:.4cqh 0}
.m-itemd-track{font-size:2.8cqh;color:#c9b8ee}
.m-itemd-track b{color:#f0d060}
.m-itemd-track i{color:#8a93ad;font-style:italic}

  /* RARITY GLOW BELONGS TO THE ITEM, NOT ITS CELL. _rarityGlow sets --rar-glow on the cell; the
     filter is applied here to the artwork alone, so the tile's frame, level chip and requirement
     badge stay unlit. */
  .m-pd-cell img:not(.m-pd-elem){ filter: var(--rar-glow, none); }

  /* THE RARITY GLOW BEHIND THE PICTURE (Roman, 2026-09-26: "I didn't know I had a rare helmet — instead
     of a frame, the picture glows behind it"). A disc of the rarity colour UNDER the artwork: --rar-halo,
     set by _rarityGlow (rare blue, epic purple, legendary gold; common none). The art is lifted above it;
     the frame, the level chip and the badges are untouched. Bag tiles and equipped slots. */
  .m-pd-cell::before, .m-pd-slot.filled::before{ content:''; position:absolute; left:6%; right:6%; top:3%; bottom:14%;
    background:var(--rar-halo, none); pointer-events:none; z-index:0; }
  .m-pd-cell > img:not(.m-pd-elem), .m-pd-slot.filled > img:not(.m-pd-elem){ position:relative; z-index:1; }

