:root {
  --bg-primary:#0a0c10;--bg-secondary:#11141b;--bg-card:#161a24;--bg-card-hover:#1c2230;
  --border:#252b3a;--border-accent:#3a2a30;--text-primary:#e8eaf0;--text-secondary:#8b92a8;--text-muted:#5a6178;
  --accent-red:#da292a;--accent-red-dim:#9a2122;--accent-blue:#3b8beb;--accent-cyan:#22d3ee;
  --accent-green:#34d399;--accent-purple:#a78bfa;--accent-yellow:#fbbf24;--accent-orange:#f59e0b;
  --r-heirloom:#e0383a;--r-legendary:#f0b232;--r-epic:#a855f7;--r-rare:#3b82f6;--r-common:#94a3b8;--r-uncommon:#22c55e;
  --glow-red:0 0 20px rgba(218,41,42,0.3);
}
*{margin:0;padding:0;box-sizing:border-box}
body{background:var(--bg-primary);color:var(--text-primary);font-family:'Exo 2',sans-serif;min-height:100vh}

.sticky-nav{position:sticky;top:0;z-index:100;background:#0a0c10;border-bottom:none}
.header{border-bottom:none;padding:0}
.header-inner{max-width:1600px;margin:0 auto;height:62px;padding:6px 32px 8px;display:flex;align-items:center;justify-content:space-between;border-bottom:none;background-image:linear-gradient(to right,transparent,var(--border) 20px,var(--border) calc(100% - 20px),transparent);background-size:100% 1px;background-position:bottom;background-repeat:no-repeat}
.logo{display:flex;align-items:center;gap:16px}
.logo-mark{width:40px;height:40px;border-radius:8px;object-fit:cover;display:block;border:1px solid rgba(218,41,42,0.5);box-shadow:var(--glow-red)}
.logo-text{font-family:'Rajdhani',sans-serif;font-weight:700;font-size:28px;letter-spacing:3px;white-space:nowrap;
  background:linear-gradient(110deg,rgba(255,255,255,0) 42%,rgba(255,255,255,0.95) 50%,rgba(255,255,255,0) 58%) no-repeat,linear-gradient(#da292a,#da292a);
  background-size:220% 100%,100% 100%;background-position:220% 0,0 0;
  -webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;
  animation:logoGlisten 12s linear infinite}
@keyframes logoGlisten{0%{background-position:220% 0,0 0}30%{background-position:-220% 0,0 0}100%{background-position:-220% 0,0 0}}
.logo-name{text-transform:none}
.logo-sub{font-family:'Share Tech Mono',monospace;font-size:11px;color:var(--text-muted);letter-spacing:4px;text-transform:uppercase;text-align:center}
.build-tag{font-size:8px;color:var(--text-muted);letter-spacing:1px;opacity:0.5;margin-top:6px}
.header-stats{display:flex;gap:24px;flex:1;justify-content:center}
.header-stat{text-align:center}
.header-stat-val{font-family:'Rajdhani',sans-serif;font-weight:700;font-size:24px;color:var(--accent-red)}
.header-stat-label{font-size:10px;color:var(--text-muted);text-transform:uppercase;letter-spacing:2px}

.controls{max-width:1600px;margin:0 auto;padding:4px 32px 5px;display:flex;gap:8px;flex-wrap:wrap;align-items:center;border-bottom:none;background-image:linear-gradient(to right,transparent,var(--border) 20px,var(--border) calc(100% - 20px),transparent);background-size:100% 1px;background-position:bottom;background-repeat:no-repeat}
.search-box{flex:1;min-width:220px;position:relative}
.search-box input{width:100%;display:block;padding:0 36px 0 40px;height:34px;background:var(--bg-secondary);border:1px solid var(--border);border-radius:8px;
  color:var(--text-primary);font-family:'Exo 2',sans-serif;font-size:13px;outline:none;transition:border-color 0.2s}
.search-box input:focus{border-color:var(--accent-red)}
.search-box input:-webkit-autofill,
.search-box input:-webkit-autofill:hover,
.search-box input:-webkit-autofill:focus{-webkit-box-shadow:0 0 0 1000px var(--bg-secondary) inset;-webkit-text-fill-color:var(--text-primary);caret-color:var(--text-primary)}
.search-box::before{content:'⌕';position:absolute;left:14px;top:50%;transform:translateY(-50%);color:var(--text-muted);font-size:14px}
.search-clear{position:absolute;right:10px;top:50%;transform:translateY(-50%);background:none;border:none;color:var(--text-muted);
  font-size:16px;cursor:pointer;padding:2px 6px;display:none;transition:color 0.15s}
.search-clear:hover{color:var(--text-primary)}
.search-box.has-query .search-clear{display:block}
select.fs{padding:4px 10px;background:var(--bg-card);border:1px solid var(--border);border-radius:6px;
  color:var(--text-secondary);font-family:'Exo 2',sans-serif;font-size:11px;outline:none;cursor:pointer;transition:all 0.15s}
select.fs:hover{border-color:var(--accent-red-dim);color:var(--text-primary)}
select.fs:focus{border-color:var(--accent-red)}
.view-toggle{display:flex;gap:4px;background:rgba(218,41,42,0.1);border:1px solid rgba(218,41,42,0.3);border-radius:8px;padding:2px;height:34px;align-self:center}
.view-btn{padding:0 12px;font-size:11px;font-family:'Exo 2',sans-serif;color:var(--text-secondary);background:transparent;
  border:none;border-radius:4px;cursor:pointer;transition:all 0.15s}
.view-btn:hover{color:var(--text-primary)}.view-btn.active{color:var(--accent-red);background:rgba(218,41,42,0.12)}

.sort-bar{max-width:1600px;margin:0 auto;padding:2px 32px 5px;display:flex;align-items:center;gap:6px;font-size:12px;color:var(--text-muted);background-color:var(--bg-primary);border-bottom:none;background-image:linear-gradient(to right,transparent,var(--border) 20px,var(--border) calc(100% - 20px),transparent);background-size:100% 1px;background-position:bottom;background-repeat:no-repeat}
.col-toggles{max-width:1600px;margin:0 auto;padding:2px 32px;display:none;align-items:center;gap:6px;font-size:11px;color:var(--text-muted);flex-wrap:wrap;background:var(--bg-primary)}
.col-toggles.show{display:flex}
.col-toggles label{display:flex;align-items:center;gap:3px;cursor:pointer;padding:2px 6px;border-radius:4px;background:rgba(255,255,255,0.03);border:1px solid var(--border)}
.col-toggles label:hover{border-color:var(--accent-red)}
.col-toggles input{accent-color:var(--accent-red)}
.col-toggle-btn{background:var(--bg-card);border:1px solid var(--border);color:var(--text-secondary);padding:4px 10px;border-radius:6px;font-size:11px;cursor:pointer;font-family:'Exo 2',sans-serif;transition:all 0.15s}
.col-toggle-btn:hover,.col-toggle-btn.active{color:var(--accent-red);border-color:var(--accent-red)}
.filter-chips{max-width:1600px;margin:0 auto;padding:2px 32px;margin-top:-1px;border:none;background-image:linear-gradient(to right,transparent,var(--border) 20px,var(--border) calc(100% - 20px),transparent),linear-gradient(to right,transparent,var(--border) 20px,var(--border) calc(100% - 20px),transparent);background-size:100% 1px,100% 1px;background-position:top,bottom;background-repeat:no-repeat,no-repeat;display:flex;gap:6px;flex-wrap:wrap;align-items:center;background-color:var(--bg-primary)}
.filter-chips:empty{display:none}
.chip{display:inline-flex;align-items:center;gap:5px;padding:4px 10px;font-family:'Exo 2',sans-serif;font-size:11px;font-weight:600;
  border-radius:4px;cursor:default;animation:chipIn 0.15s ease-out}
.chip .chip-x{cursor:pointer;opacity:0.6;font-size:13px;line-height:1;margin-left:2px;transition:opacity 0.15s}
.chip .chip-x:hover{opacity:1}
.chip-search{color:var(--accent-red);background:rgba(218,41,42,0.1);border:1px solid rgba(218,41,42,0.25)}
.chip-cat{color:#22d3ee;background:rgba(34,211,238,0.1);border:1px solid rgba(34,211,238,0.25)}
.chip-rarity{color:#a78bfa;background:rgba(167,139,250,0.1);border:1px solid rgba(167,139,250,0.25)}
.chip-clear{color:var(--text-muted);background:transparent;border:1px solid var(--border);cursor:pointer;font-weight:400;transition:all 0.15s}
.chip-clear:hover{color:var(--accent-red);border-color:var(--accent-red)}
@keyframes chipIn{from{opacity:0;transform:scale(0.9)}to{opacity:1;transform:scale(1)}}
.sort-btn{padding:4px 10px;font-family:'Exo 2',sans-serif;font-size:11px;color:var(--text-secondary);background:var(--bg-card);
  border:1px solid var(--border);border-radius:6px;cursor:pointer;transition:all 0.15s}
.sort-btn:hover{color:var(--text-primary);border-color:var(--accent-red-dim)}
.sort-btn.active{color:var(--accent-red);background:rgba(218,41,42,0.1);border-color:rgba(218,41,42,0.3)}

.content{max-width:1600px;margin:0 auto;padding:5px 32px 64px}

.card-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(340px,1fr));gap:10px}
.item-card{background:var(--bg-card);border:1px solid var(--border);border-radius:10px;padding:14px;
  transition:all 0.25s;cursor:default;position:relative;overflow:hidden;animation:fadeUp 0.3s ease both}
.item-card::before{content:'';position:absolute;top:0;left:0;right:0;height:3px;
  background:var(--card-accent,var(--accent-red));opacity:0;transition:opacity 0.25s}
.item-card:hover{border-color:var(--border-accent);background:var(--bg-card-hover);
  transform:translateY(-2px);box-shadow:0 8px 24px rgba(0,0,0,0.3)}
.item-card:hover::before{opacity:1}

.card-head{position:relative;min-height:110px;overflow:hidden}
.card-hero{display:flex;gap:10px;align-items:stretch}
.card-img-wrap{flex-shrink:0;display:flex}
.card-info{flex:1;min-width:0}
.card-name{font-family:'Rajdhani',sans-serif;font-weight:700;font-size:17px;line-height:1.2;padding-right:80px}
.card-cat{font-size:10px;font-weight:600;color:var(--text-muted);text-transform:uppercase;letter-spacing:1.5px;margin-top:6px}
.card-desc{font-size:10px;color:var(--text-muted);font-style:italic;margin-top:6px;line-height:1.4;height:5.6em;display:-webkit-box;-webkit-line-clamp:4;-webkit-box-orient:vertical;overflow:hidden}
.card-thumb{width:120px;height:120px;border-radius:6px;background:rgba(255,255,255,0.05);border:1px solid var(--border);flex-shrink:0;object-fit:contain;align-self:stretch;cursor:zoom-in}
.card-weapon .card-thumb{width:180px}
.card-legend .card-thumb{width:120px;height:130px;object-fit:cover;object-position:top}
.card-map .card-thumb{width:160px;height:120px;object-fit:cover}
.card-map .card-head{min-height:unset}
.card-body{margin-top:8px;padding-top:8px;border-top:1px solid var(--border)}
.card-head .badge-rarity{position:absolute;top:0;right:0}
.card-head .unlock-badge{position:absolute;top:0;right:0;margin-top:0}

.card-stats-grid{display:grid;grid-template-columns:auto minmax(0,1fr);gap:2px 10px;font-size:11px;align-items:baseline}
.card-weapon .card-stats-grid,.card-legend .card-stats-grid{grid-template-columns:auto minmax(0,1fr) auto minmax(0,1fr)}
.card-stats-grid .sg-cell{display:contents}
.card-stats-grid .sg-lbl{color:var(--text-muted);font-weight:600;text-transform:uppercase;font-size:8px;letter-spacing:0.5px;white-space:nowrap}
.card-stats-grid .sg-val{color:var(--text-secondary);overflow-wrap:anywhere}

.ammo-pill{font-size:9px;padding:1px 6px;border-radius:3px;background:rgba(240,178,50,0.12);border:1px solid rgba(240,178,50,0.3);color:var(--r-legendary);white-space:nowrap;font-family:'Share Tech Mono',monospace}
.mode-pill{font-size:9px;padding:1px 5px;border-radius:3px;background:rgba(34,211,238,0.1);border:1px solid rgba(34,211,238,0.2);color:var(--accent-cyan);white-space:nowrap;display:inline-block;margin:1px}

.tier-tabs{display:flex;gap:4px;margin:8px 0 6px;flex-wrap:wrap}
.mag-tab{padding:3px 10px;font-family:'Exo 2',sans-serif;font-size:10px;color:var(--text-secondary);
  background:var(--bg-card);border:1px solid var(--border);border-radius:4px;cursor:pointer;transition:all 0.15s}
.mag-tab:hover{border-color:var(--accent-red-dim);color:var(--text-primary)}
.mag-tab.active{color:var(--accent-red);background:rgba(218,41,42,0.1);border-color:rgba(218,41,42,0.3)}
.mag-panel{display:none}.mag-panel.active{display:block}

/* Attachments list */
.att-pill{display:inline-flex;align-items:center;gap:4px;font-size:9px;padding:2px 6px;border-radius:3px;background:rgba(255,255,255,0.04);border:1px solid var(--border);color:var(--text-secondary);white-space:nowrap}
.att-slot{font-family:'Share Tech Mono',monospace;font-size:8px;color:var(--text-muted);text-transform:uppercase}
.rar-dot{width:8px;height:8px;border-radius:50%;display:inline-block}
.tier-chip{font-size:9px;padding:1px 6px;border-radius:3px;background:transparent;border:1px solid var(--border);white-space:nowrap}

/* Legend abilities */
.legend-head{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-bottom:8px}
.legend-title{font-family:'Rajdhani',sans-serif;font-weight:600;font-size:14px;color:var(--text-primary)}
.class-pill{font-size:10px;font-weight:700;padding:2px 8px;border-radius:4px;font-family:'Share Tech Mono',monospace;text-transform:uppercase;letter-spacing:0.5px;color:#fff;background:rgba(255,255,255,0.08);border:1px solid var(--border)}
.class-assault{color:#ef4444;background:rgba(239,68,68,0.12);border-color:rgba(239,68,68,0.3)}
.class-skirmisher{color:#fbbf24;background:rgba(251,191,36,0.12);border-color:rgba(251,191,36,0.3)}
.class-recon{color:#22d3ee;background:rgba(34,211,238,0.12);border-color:rgba(34,211,238,0.3)}
.class-controller{color:#a78bfa;background:rgba(167,139,250,0.12);border-color:rgba(167,139,250,0.3)}
.class-support{color:#34d399;background:rgba(52,211,153,0.12);border-color:rgba(52,211,153,0.3)}
.abilities{display:flex;flex-direction:column;gap:6px}
.abil{padding:6px 8px;border-radius:6px;background:rgba(255,255,255,0.02);border:1px solid var(--border)}
.abil-top{display:flex;align-items:center;gap:6px;flex-wrap:wrap}
.abil-type{font-size:8px;font-weight:700;text-transform:uppercase;letter-spacing:0.5px;padding:1px 6px;border-radius:3px;color:var(--text-muted);background:rgba(255,255,255,0.05);border:1px solid var(--border)}
.abil-tactical{color:var(--accent-cyan);border-color:rgba(34,211,238,0.3)}
.abil-passive{color:var(--accent-green);border-color:rgba(52,211,153,0.3)}
.abil-ultimate{color:var(--accent-red);border-color:rgba(218,41,42,0.3)}
.abil-name{font-family:'Rajdhani',sans-serif;font-weight:600;font-size:13px;color:var(--text-primary)}
.abil-cd{margin-left:auto;font-family:'Share Tech Mono',monospace;font-size:10px;color:var(--accent-yellow)}
.abil-desc{font-size:10px;color:var(--text-secondary);margin-top:3px;line-height:1.4}

/* Gear level table */
.lvl-table-wrap{margin-top:8px;overflow-x:auto}
.lvl-table{width:100%;border-collapse:collapse;font-size:10px}
.lvl-table th{padding:4px 8px;text-align:left;color:var(--text-muted);font-family:'Rajdhani',sans-serif;font-weight:600;text-transform:uppercase;letter-spacing:0.5px;border-bottom:1px solid var(--border);background:var(--bg-secondary)}
.lvl-table td{padding:4px 8px;border-bottom:1px solid rgba(255,255,255,0.03);color:var(--text-secondary)}

.card-attrs{font-size:11px;color:var(--text-secondary);margin-top:6px;display:flex;flex-direction:column;gap:3px}
.card-attrs .attr-row{display:flex;gap:6px;line-height:1.4}
.card-attrs .attr-label{color:var(--text-muted);font-weight:600;min-width:52px;text-transform:uppercase;font-size:9px;letter-spacing:0.5px;padding-top:1px}
.card-attrs .attr-val{color:var(--text-secondary)}

.badge{padding:3px 8px;font-family:'Share Tech Mono',monospace;font-size:10px;border-radius:4px;letter-spacing:0.5px;white-space:nowrap}
.badge-rarity{font-weight:700}
.badge-rarity.Heirloom,.badge-rarity.Mythic{color:var(--r-heirloom);background:rgba(224,56,58,0.12);border:1px solid rgba(224,56,58,0.4)}
.badge-rarity.Legendary{color:var(--r-legendary);background:rgba(240,178,50,0.12);border:1px solid rgba(240,178,50,0.3)}
.badge-rarity.Epic{color:var(--r-epic);background:rgba(168,85,247,0.12);border:1px solid rgba(168,85,247,0.3)}
.badge-rarity.Rare{color:var(--r-rare);background:rgba(59,130,246,0.12);border:1px solid rgba(59,130,246,0.3)}
.badge-rarity.Common{color:var(--r-common);background:rgba(148,163,184,0.12);border:1px solid rgba(148,163,184,0.3)}

/* Tracking badges (favorite star + legend unlock) */
.card-track-row{margin-top:10px;display:flex;justify-content:flex-end}
.badge-track{color:var(--text-muted);background:rgba(255,255,255,0.05);border:1px solid var(--border);font-size:9px;padding:3px 10px;border-radius:4px;cursor:pointer;display:inline-flex;align-items:center;gap:6px;transition:all 0.15s;font-family:'Share Tech Mono',monospace}
.badge-track:hover{background:rgba(218,41,42,0.1);border-color:rgba(218,41,42,0.3);color:var(--text-secondary)}
.badge-track input{accent-color:var(--accent-red);cursor:pointer;width:12px;height:12px}
.fav-btn .fav-star{font-size:12px;color:var(--r-legendary)}
.badge-completed{color:var(--r-legendary)!important;background:rgba(240,178,50,0.12)!important;border-color:rgba(240,178,50,0.4)!important;font-weight:700}
.badge-completed input{accent-color:var(--r-legendary)!important}

.card-sources{display:flex;flex-wrap:wrap;align-items:baseline;gap:4px;padding:6px 0;border-top:1px solid var(--border);margin-top:6px}
.card-sources .attr-label{font-size:10px;color:var(--text-muted);margin-right:4px;white-space:nowrap;text-transform:uppercase;font-weight:600;letter-spacing:0.5px}
.source-list{display:flex;flex-wrap:wrap;gap:3px}
.source-pill{font-size:9px;padding:1px 6px;border-radius:3px;background:rgba(59,130,246,0.1);border:1px solid rgba(59,130,246,0.2);color:var(--accent-blue);white-space:nowrap}
.zone-pill{font-size:9px;padding:1px 6px;border-radius:3px;background:rgba(34,211,238,0.1);border:1px solid rgba(34,211,238,0.2);color:var(--accent-cyan);white-space:nowrap}
.card-note{font-size:11px;color:var(--text-secondary);margin-top:5px;line-height:1.3;font-style:italic}

.table-wrap{overflow-x:auto;border:1px solid var(--border);border-radius:10px;background:var(--bg-card)}
table.dt{width:100%;border-collapse:collapse;font-size:13px}
table.dt th{padding:10px 12px;font-family:'Rajdhani',sans-serif;font-weight:600;font-size:11px;text-transform:uppercase;
  letter-spacing:1.5px;color:var(--text-muted);background:var(--bg-secondary);border-bottom:1px solid var(--border);
  text-align:left;white-space:nowrap;cursor:pointer;user-select:none;transition:color 0.15s}
table.dt th:hover{color:var(--accent-red)}table.dt th.sorted{color:var(--accent-red)}
table.dt td{padding:8px 12px;border-bottom:1px solid rgba(255,255,255,0.03);vertical-align:top}
table.dt tr:hover td{background:rgba(255,255,255,0.02)}
.tbl-thumb{width:32px;height:32px;border-radius:4px;background:rgba(255,255,255,0.05);border:1px solid var(--border);object-fit:contain;vertical-align:middle}

.load-more-btn{display:block;width:100%;padding:12px;margin-top:10px;background:rgba(218,41,42,0.1);border:1px solid rgba(218,41,42,0.3);border-radius:8px;color:var(--accent-red);font-family:'Exo 2',sans-serif;font-size:13px;cursor:pointer;transition:all 0.15s}
.load-more-btn:hover{background:rgba(218,41,42,0.2);border-color:var(--accent-red)}
.linkish{background:none;border:none;color:var(--accent-red);cursor:pointer;text-decoration:underline;font-size:inherit}

/* Auth UI */
.auth-wrap{display:flex;gap:6px;align-items:center}
.auth-btn{padding:0 14px;height:34px;font-family:'Share Tech Mono',monospace;font-size:11px;color:var(--accent-red);
  background:rgba(218,41,42,0.1);border:1px solid rgba(218,41,42,0.3);border-radius:8px;cursor:pointer;transition:all 0.2s;white-space:nowrap;display:flex;align-items:center}
.auth-btn:hover{background:rgba(218,41,42,0.2);border-color:var(--accent-red)}
.auth-username{font-weight:600}
.dash-edit-btn{margin-left:8px;padding:0;background:none;border:none;color:var(--text-muted);font-size:15px;line-height:1;cursor:pointer;vertical-align:middle}
.dash-edit-btn:hover{color:var(--accent-red)}
.auth-modal-title{font-size:14px;font-weight:700;color:var(--text-primary);margin-bottom:12px;text-align:center;font-family:'Share Tech Mono',monospace}
.auth-user{position:relative}
.auth-dropdown{display:none;position:absolute;top:100%;right:0;margin-top:4px;background:#0a0c10;border:1px solid var(--border);border-radius:8px;overflow:hidden;z-index:200;min-width:120px}
.auth-dropdown.open{display:block}
.auth-dropdown a{display:block;padding:8px 16px;color:var(--text-secondary);text-decoration:none;font-size:11px;font-family:'Exo 2',sans-serif;transition:background 0.15s}
.auth-dropdown a:hover{background:rgba(218,41,42,0.1);color:var(--accent-red)}
.auth-modal{display:none;position:fixed;top:0;left:0;right:0;bottom:0;z-index:300;background:rgba(0,0,0,0.85);align-items:center;justify-content:center}
.auth-modal.open{display:flex}
.auth-modal-content{background:#0a0c10;border:1px solid var(--border);border-radius:12px;padding:24px;width:340px;max-width:90vw;position:relative}
.auth-modal-close{position:absolute;top:8px;right:12px;background:none;border:none;color:var(--text-muted);font-size:20px;cursor:pointer}
.auth-modal-close:hover{color:var(--text-primary)}
.auth-tabs{display:flex;gap:4px;margin-bottom:16px}
.auth-tab{flex:1;padding:8px;font-family:'Exo 2',sans-serif;font-size:12px;color:var(--text-secondary);background:var(--bg-card);border:1px solid var(--border);border-radius:6px;cursor:pointer;transition:all 0.15s}
.auth-tab.active{color:var(--accent-red);background:rgba(218,41,42,0.1);border-color:rgba(218,41,42,0.3)}
.auth-input{width:100%;padding:10px 14px;margin-bottom:8px;background:var(--bg-secondary);border:1px solid var(--border);border-radius:6px;color:var(--text-primary);font-family:'Exo 2',sans-serif;font-size:13px;outline:none;box-sizing:border-box}
.auth-input:focus{border-color:var(--accent-red)}
.auth-submit{width:100%;padding:10px;margin-top:4px;font-family:'Share Tech Mono',monospace;font-size:12px;color:var(--accent-red);background:rgba(218,41,42,0.1);border:1px solid rgba(218,41,42,0.3);border-radius:6px;cursor:pointer;transition:all 0.2s}
.auth-submit:hover{background:rgba(218,41,42,0.2);border-color:var(--accent-red)}
.auth-forgot{display:block;text-align:center;margin-top:8px;font-size:11px;color:var(--text-muted);text-decoration:none}
.auth-forgot:hover{color:var(--accent-red)}
.auth-hint{font-size:11px;color:var(--text-muted);margin-bottom:8px;text-align:center}
.auth-msg{font-size:11px;margin-bottom:8px;padding:6px 10px;border-radius:4px;display:none}
.auth-msg.error{display:block;color:#ef4444;background:rgba(239,68,68,0.1);border:1px solid rgba(239,68,68,0.2)}
.auth-msg.success{display:block;color:#22c55e;background:rgba(34,197,94,0.1);border:1px solid rgba(34,197,94,0.2)}
.auth-toast{position:fixed;top:20px;left:50%;transform:translateX(-50%);background:#22c55e;color:#000;padding:12px 24px;border-radius:6px;font-size:14px;font-weight:600;z-index:10000;animation:toastFade 5s ease-in-out}
@keyframes toastFade{0%{opacity:0;transform:translateX(-50%) translateY(-10px)}10%{opacity:1;transform:translateX(-50%) translateY(0)}80%{opacity:1}100%{opacity:0}}

/* Dashboard */
.dashboard{max-width:1600px;margin:0 auto;padding:5px 32px 64px}
.dash-hero{display:flex;align-items:center;gap:24px;padding:20px 24px;margin-bottom:5px;background:var(--bg-card);border:1px solid var(--border);border-radius:10px}
.dash-hero-ring{width:90px;height:90px;border-radius:50%;display:flex;align-items:center;justify-content:center;background:conic-gradient(var(--ring-color) calc(var(--pct) * 1%),rgba(255,255,255,0.05) 0);flex-shrink:0;position:relative}
.dash-hero-ring::before{content:'';position:absolute;width:70px;height:70px;border-radius:50%;background:var(--bg-card)}
.dash-hero-num{font-family:'Rajdhani',sans-serif;font-weight:700;font-size:24px;color:var(--text-primary);z-index:1}
.dash-hero-info{flex:1}
.dash-title{font-family:'Rajdhani',sans-serif;font-size:22px;color:var(--accent-red);margin-bottom:2px}
.dash-rank{font-family:'Share Tech Mono',monospace;font-size:14px;margin-bottom:8px;letter-spacing:1px}
.dash-hero-stats{display:flex;gap:16px;font-size:11px;color:var(--text-muted);font-family:'Share Tech Mono',monospace}
.dash-pct{font-family:'Rajdhani',sans-serif;font-weight:700;font-size:14px;margin-left:4px}
.dash-section{margin-bottom:5px;background:var(--bg-card);border:1px solid var(--border);border-radius:10px;overflow:hidden}
.dash-header{display:flex;align-items:center;gap:12px;padding:12px 16px;cursor:pointer;transition:background 0.15s}
.dash-header:hover{background:rgba(255,255,255,0.02)}
.dash-label{font-family:'Rajdhani',sans-serif;font-weight:700;font-size:16px;color:var(--text-primary)}
.dash-progress{font-family:'Share Tech Mono',monospace;font-size:12px;color:var(--accent-red);margin-left:auto}
.dash-bar{width:120px;height:6px;background:rgba(255,255,255,0.05);border-radius:3px;overflow:hidden}
.dash-fill{height:100%;background:var(--accent-red);border-radius:3px;transition:width 0.3s}
.dash-list{padding:8px 16px 16px;display:grid;grid-template-columns:repeat(2,1fr);gap:2px 12px}
.dash-list.collapsed{display:none}
.dash-item{display:flex;align-items:center;gap:10px;padding:8px 10px;border-radius:6px;cursor:pointer;font-size:13px;color:var(--text-secondary);transition:background 0.15s}
.dash-item:hover{background:rgba(255,255,255,0.03)}
.dash-item>span{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:1}
.dash-item.checked span{color:var(--r-legendary)}
.dash-thumb{width:28px;height:28px;border-radius:4px;object-fit:cover;flex-shrink:0}
.dash-item input{accent-color:var(--accent-red)}
.dash-fav-cat{flex:0 0 auto!important;font-size:9px;color:var(--text-muted);font-family:'Share Tech Mono',monospace;text-transform:uppercase}
.dash-empty{grid-column:1/-1;padding:16px;color:var(--text-muted);font-size:12px;font-style:italic}

.empty-state{text-align:center;padding:80px 32px;color:var(--text-muted)}
.empty-state .icon{font-size:48px;margin-bottom:16px;opacity:0.3}
@keyframes fadeUp{from{opacity:0;transform:translateY(12px)}to{opacity:1;transform:translateY(0)}}

.donate-wrap{position:relative;display:flex;align-items:center;gap:8px}
.creator-msg{font-family:'Share Tech Mono',monospace;font-size:10px;color:var(--text-muted);letter-spacing:1px;line-height:1.4;text-align:right}
.creator-msg strong{color:var(--accent-red)}
.donate-btn{padding:0 14px;height:34px;font-family:'Share Tech Mono',monospace;font-size:11px;color:var(--accent-red);background:rgba(218,41,42,0.1);display:flex;align-items:center;
  border:1px solid rgba(218,41,42,0.3);border-radius:8px;cursor:pointer;letter-spacing:0.5px;transition:all 0.2s;white-space:nowrap}
.donate-btn:hover{background:rgba(218,41,42,0.2);border-color:var(--accent-red)}
.donate-popup{display:none;position:absolute;top:100%;right:0;margin-top:8px;background:var(--bg-card);border:1px solid var(--border);
  border-radius:10px;padding:20px;z-index:200;box-shadow:0 12px 40px rgba(0,0,0,0.5);text-align:center;min-width:240px}
.donate-popup.open{display:block}
.donate-title{font-family:'Rajdhani',sans-serif;font-weight:700;font-size:15px;margin-bottom:10px;color:var(--text-primary)}
.donate-label{display:flex;align-items:center;justify-content:center;gap:6px;margin-bottom:8px}
.donate-crypto{font-family:'Share Tech Mono',monospace;font-size:11px;font-weight:700;color:var(--accent-red)}
.donate-crypto-name{font-size:10px;color:var(--text-muted)}
.donate-qr{border-radius:6px;width:160px;height:160px;display:block;margin:0 auto 10px}
.donate-copy{display:flex;align-items:center;gap:6px;background:var(--bg-secondary);border:1px solid var(--border);border-radius:6px;padding:6px 8px;cursor:pointer}
.donate-addr{font-family:'Share Tech Mono',monospace;font-size:9px;color:var(--text-secondary);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:1}
.donate-copy-txt{font-size:10px;color:var(--accent-red);font-weight:600;white-space:nowrap}
.site-footer{text-align:center;padding:24px 16px;margin-top:32px;border-top:1px solid var(--border);color:var(--text-muted);font-size:11px;line-height:1.6}
.visitor-counter{display:flex;align-items:center;justify-content:center;gap:8px;margin-bottom:12px}
.vc-label{font-family:'Share Tech Mono',monospace;font-size:10px;color:var(--text-muted);text-transform:uppercase;letter-spacing:2px}
.vc-num{font-family:'Rajdhani',sans-serif;font-weight:700;font-size:18px;color:var(--accent-red);letter-spacing:1px}

#mobilePanel{border-top:none}
#mobilePanel.collapsed{display:none}
#filterPanel{transition:max-height 0.25s ease,opacity 0.2s ease;overflow:hidden}
#filterPanel.collapsed{max-height:0!important;opacity:0;pointer-events:none}
.filter-row{max-width:1600px;margin:0 auto;display:flex;flex-wrap:wrap;gap:6px;padding:2px 32px}
.cat-bar{max-width:1600px;margin:-1px auto 0;display:flex;flex-wrap:wrap;gap:4px;padding:5px 32px 2px;overflow-x:auto;align-items:center;border-top:none;background-image:linear-gradient(to right,transparent,var(--border) 20px,var(--border) calc(100% - 20px),transparent);background-size:100% 1px;background-position:top;background-repeat:no-repeat}
#catBar{display:contents}
.cat-btn{background:var(--bg-card);border:1px solid var(--border);border-radius:6px;padding:4px 10px;font-size:11px;
  color:var(--text-secondary);cursor:pointer;white-space:nowrap;transition:all 0.15s ease;font-family:'Exo 2',sans-serif}
.cat-btn:hover{border-color:var(--accent-red-dim);color:var(--text-primary)}
.cat-btn.active{background:rgba(218,41,42,0.1);border-color:rgba(218,41,42,0.3);color:var(--accent-red);font-weight:600}
.cat-count{font-size:9px;color:var(--text-muted);margin-left:2px}
.cat-btn.active .cat-count{color:rgba(255,255,255,0.7)}

.card-overlay{position:fixed;top:0;left:0;right:0;bottom:0;z-index:200;background:rgba(0,0,0,0.85);display:flex;align-items:center;justify-content:center;cursor:pointer;padding:20px;overflow-y:auto}
.card-overlay-wrap{max-width:420px;width:100%;cursor:default}
.card-overlay-wrap .item-card{margin:0}
.img-overlay{position:fixed;top:0;left:0;right:0;bottom:0;z-index:200;background:rgba(0,0,0,0.8);display:flex;align-items:center;justify-content:center;cursor:pointer}
.img-overlay img{max-width:90vw;max-height:90vh;border-radius:8px;border:1px solid var(--border);background:var(--bg-card);padding:12px}
.buildlog-overlay{position:fixed;top:0;left:0;right:0;bottom:0;z-index:200;background:rgba(0,0,0,0.85);display:flex;align-items:center;justify-content:center;cursor:pointer;padding:20px}
.buildlog-wrap{max-width:560px;width:100%;max-height:85vh;display:flex;flex-direction:column;background:var(--bg-card);border:1px solid var(--border-accent);border-radius:10px;cursor:default;overflow:hidden;box-shadow:0 12px 40px rgba(0,0,0,0.5)}
.buildlog-head{display:flex;align-items:center;justify-content:space-between;padding:12px 16px;border-bottom:1px solid var(--border);font-family:'Share Tech Mono',monospace;font-weight:700;font-size:17px;letter-spacing:1px;color:var(--accent-red)}
.buildlog-head .buildlog-close{font-family:initial;color:var(--text-muted)}
.buildlog-close{background:none;border:none;color:var(--text-muted);font-size:22px;line-height:1;cursor:pointer;padding:0 4px}
.buildlog-close:hover{color:var(--text-primary)}
.buildlog-body{padding:14px 18px;overflow-y:auto;font-size:12px;line-height:1.5;color:var(--text-secondary)}
.buildlog-body>:first-child{margin-top:0}
.buildlog-body h3{font-size:13px;color:var(--text-primary);margin:14px 0 4px;border-bottom:1px solid var(--border);padding-bottom:3px}
.buildlog-body ul{margin:2px 0 8px;padding-left:16px}
.buildlog-body li{margin:2px 0}
.buildlog-body p{margin:4px 0}
.buildlog-body code{background:rgba(255,255,255,0.08);padding:1px 4px;border-radius:3px;font-size:11px;color:var(--accent-cyan)}
.version-tag,.build-tag{cursor:pointer}
.version-tag:hover,.build-tag:hover{color:var(--accent-red)}

.mobile-fab{display:none;position:fixed;top:10px;right:10px;z-index:200;background:var(--bg-card);border:1px solid var(--border);
  border-radius:10px;color:var(--text-secondary);font-size:18px;padding:8px 12px;cursor:pointer;line-height:1;
  opacity:0;transition:opacity 0.2s ease;pointer-events:none;box-shadow:0 2px 8px rgba(0,0,0,0.4)}
.mobile-fab.visible{opacity:1;pointer-events:auto}
.mobile-menu-btn{background:rgba(218,41,42,0.1);border:1px solid rgba(218,41,42,0.3);border-radius:8px;height:34px;display:flex;align-items:center;
  color:var(--accent-red);font-size:11px;font-family:'Share Tech Mono',monospace;padding:6px 12px;cursor:pointer;transition:all 0.2s;letter-spacing:0.5px;white-space:nowrap}
.mobile-menu-btn:hover,.mobile-menu-btn.open{background:rgba(218,41,42,0.2);border-color:var(--accent-red)}
.btn-short{display:none}
@media(max-width:768px){
  .header{padding:0}
  .header-inner{gap:6px;padding:4px 12px;height:auto}
  .header-stats{gap:8px}
  .logo{gap:4px}
  .logo-mark{width:24px;height:24px;font-size:16px}
  .logo-text{font-size:13px;letter-spacing:0.5px}
  .logo-sub{font-size:7px;letter-spacing:1px}
  .creator-msg{display:none}
  .header-stat-val{font-size:11px}
  .header-stat-label{font-size:7px;letter-spacing:1px}
  .auth-btn{height:22px;font-size:8px;padding:0 6px}
  .dash-edit-btn{font-size:13px}
  .auth-wrap{gap:4px}
  .donate-wrap{gap:4px}
  .mobile-donate-stack{display:flex;flex-direction:row;align-items:center;gap:4px}
  .donate-btn{font-size:8px;padding:0 6px;height:22px}
  .donate-btn .donate-btn-text{display:none}
  .mobile-menu-btn{padding:0 6px;height:22px}
  .btn-full{display:none}
  .btn-short{display:inline-block;font-size:7px;line-height:1.2;text-align:center}
  #mobilePanel{display:none}
  #mobilePanel.open{display:block}
  .controls,.filter-row,.cat-bar,.sort-bar,.col-toggles,.filter-chips,.content,.dashboard{padding-left:12px;padding-right:12px}
  .controls{flex-wrap:nowrap;padding-top:4px;padding-bottom:5px}
  .search-box{min-width:0}
  .view-toggle{height:22px}
  .view-btn{padding:0 6px;font-size:9px}
  .search-box input{height:22px;font-size:11px}
  .card-grid{grid-template-columns:1fr}
  .card-weapon .card-stats-grid,.card-legend .card-stats-grid{grid-template-columns:auto minmax(0,1fr)}
  .dash-hero{flex-direction:column;text-align:center;padding:14px 12px;gap:12px}
  .dash-hero-ring{width:72px;height:72px}
  .dash-hero-ring::before{width:56px;height:56px}
  .dash-hero-num{font-size:20px}
  .dash-title{font-size:18px}
  .dash-rank{font-size:12px}
  .dash-hero-stats{justify-content:center;flex-wrap:wrap;gap:8px;font-size:10px}
  .dash-header{padding:10px 12px;gap:8px}
  .dash-label{font-size:14px}
  .dash-progress{font-size:10px}
  .dash-bar{width:80px;height:5px}
  .dash-list{grid-template-columns:1fr;padding:6px 10px 12px}
  .dash-item{gap:8px;padding:6px 8px;font-size:12px}
  .dash-thumb{width:24px;height:24px}
  .card-head{min-height:90px}
  .card-thumb{width:100px;height:100px}
  .card-weapon .card-thumb{width:130px}
  .card-legend .card-thumb{width:100px;height:120px}
  .card-map .card-thumb{width:120px;height:90px}
  .card-name{font-size:15px;padding-right:70px}
  .auth-modal-content{padding:16px;width:calc(100vw - 24px)}
}



/* ==== ported from arc (Technique #54), recoloured to apex ==== */
/* ============================================================
   COMMAND BAR -- one row for search, every filter, sort and view.
   Appended last: same-specificity rules win by source order, so
   nothing above is edited. Replaces the category wall, the select
   row, the sort row and the column wall.
   ============================================================ */

.cmdbar{
  max-width:1600px;margin:0 auto;
  padding:5px 32px 6px;
  display:flex;align-items:center;gap:6px;
  flex-wrap:nowrap;
  position:relative;                 /* popover anchor */
  background-image:linear-gradient(to right,transparent,var(--border) 20px,var(--border) calc(100% - 20px),transparent);
  background-size:100% 1px;background-position:bottom;background-repeat:no-repeat;
}
/* Only the control strip scrolls. The bar itself must NOT, or it would clip
   the popover (a scroll container cannot have visible overflow on one axis). */
.cmd-controls{
  display:flex;align-items:center;gap:6px;
  flex:1 1 auto;min-width:0;
  overflow-x:auto;overflow-y:hidden;
  scrollbar-width:thin;
}
.cmd-controls::-webkit-scrollbar{height:4px}
.cmd-controls::-webkit-scrollbar-thumb{background:var(--border-accent);border-radius:2px}

/* -- Drawer --------------------------------------------------
   The whole bar retracts, not just the filters: search and the
   view toggle go with it, because the point is to hand the
   screen back to the content. Down by default. */
.cmdbar{transition:max-height .22s ease,opacity .18s ease,padding .22s ease;max-height:140px}
.cmdbar.retracted{max-height:0;opacity:0;padding-top:0;padding-bottom:0;overflow:hidden;pointer-events:none}
.cmd-handle{
  display:block;margin:0 auto;width:54px;height:15px;padding:0;
  background:var(--bg-card);border:1px solid var(--border);border-top:none;
  border-radius:0 0 8px 8px;color:var(--text-muted);cursor:pointer;
  font-size:10px;line-height:13px;
  transition:color .15s,border-color .15s,background .15s;
}
.cmd-handle:hover{color:var(--accent-red);border-color:var(--accent-red-dim);background:var(--bg-card-hover)}
.cmd-handle:focus-visible{outline:2px solid var(--accent-cyan);outline-offset:2px}
.cmd-handle-glyph{display:block;line-height:13px;pointer-events:none}
@media(prefers-reduced-motion:reduce){.cmdbar{transition:none!important}}

/* -- Collapsed handle fades to blue-gray ---------------------
   Keyed off aria-expanded, which setBarOpen already maintains, so
   this needs no extra class and does not depend on the handle
   staying adjacent to the bar in the markup. The existing
   transition:all .2s does the fading. Hover returns it to orange
   so it still reads as the thing you click to bring the bar back. */
.cmd-handle[aria-expanded="false"]{
  color:var(--text-secondary);
  background:rgba(139,146,168,0.10);
  border-color:rgba(139,146,168,0.30);
}
.cmd-handle[aria-expanded="false"]:hover{
  color:var(--text-primary);
  background:rgba(139,146,168,0.20);
  border-color:rgba(139,146,168,0.55);
}

/* -- Arrows: bigger and unmistakable -------------------------
   The handle used the SMALL triangles (U+25B4/25BE) at 10px, so
   up vs down was a guess. Solid U+25B2/25BC at 13px reads at a
   glance. The tab itself is shorter -- 38px instead of 54px --
   since a bigger glyph no longer needs a long bar to be findable. */
.cmd-handle{width:38px;height:17px;line-height:15px}
.cmd-handle-glyph{font-size:13px;line-height:15px}
/* sort direction: larger and heavier, it carries real meaning */
.cbtn-dir{font-size:15px;font-weight:700;line-height:1}
/* the menu carets are a hint, not a signal -- nudge, do not shout */
.cbtn-caret{font-size:10px;opacity:.7}
@media(max-width:768px){
  .cbtn-dir{font-size:13px}
  .cbtn-caret{font-size:9px}
  .cmd-handle{width:34px;height:15px;line-height:13px}
  .cmd-handle-glyph{font-size:11px;line-height:13px}
}

/* -- Mobile: two rows ----------------------------------------
   Row 1 is search + the card/table switch; row 2 is every filter
   control. On a phone one scrolling row buried the filters behind
   a sideways swipe, so they get their own full-width row.
   Placed after the drawer rules so the taller max-height wins;
   .cmdbar.retracted still beats both on specificity. */
@media(max-width:768px){
  .cmdbar{flex-wrap:wrap;row-gap:5px;max-height:220px}
  .cmdbar .search-box{order:1;flex:1 1 auto;min-width:0}
  .cmdbar .view-toggle{order:2;flex:0 0 auto}
  .cmd-controls{order:3;flex:1 0 100%;width:100%}
}

/* -- Mobile: match the card/table toggle ---------------------
   .view-toggle drops to 22px on mobile but the search wrapper and
   the control buttons were left at their 34px desktop height, so
   the row sat at three different heights. Everything on the bar
   now matches the toggle: 22px tall, 8px radius. Inner height is
   20px because the 1px borders live inside the 22px box. */
@media(max-width:768px){
  .cmdbar .search-box{height:22px;border-radius:8px;padding:0 24px 0 26px}
  .cmdbar .search-box input{height:20px;font-size:11px}
  .cmdbar .search-box::before{font-size:11px;left:9px}
  .search-chips .chip{padding:1px 5px;font-size:9px}
  .cbtn{height:22px;border-radius:8px}
  .cbtn-dir{font-size:11px}
  .cbtn-n{font-size:8px;padding:0 4px}
  .cbtn-caret{font-size:8px}
  .search-clear{right:7px;font-size:11px}
}

/* -- Desktop: tighter bar ------------------------------------
   Matching .auth-btn exactly (34px tall, 14px sides) made sense
   for one button in the header but reads bulky across nine
   controls in a row. The bar drops to 28px with 9px sides -- the
   28px desktop control height the rest of the site uses. Font
   stays Share Tech Mono 11px, so it still reads as the same
   family as login; only the box shrinks.
   Scoped to min-width so the mobile sizing you approved is
   untouchable from here. */
@media(min-width:769px){
  .cbtn{height:28px;padding:0 9px}
  .cbtn-dir{padding:0 8px}
  .view-toggle{height:28px}
  .view-btn{padding:0 10px}
  .cmdbar .search-box{height:28px}
  .cmdbar .search-box input{height:26px}
}

/* -- Pull-down tab: wider and shorter ------------------------
   Earlier "shorter" was read as length and the tab was narrowed;
   it meant height. Now wide and low at both sizes, scaled by the
   same ratio the bar uses (22/28 = 0.79). Radius drops with the
   height so a 13px tab does not render as a lozenge -- and the
   glyph is capped by the shorter box, so it is as large as fits. */
@media(min-width:769px){
  .cmd-handle{width:64px;height:13px;line-height:12px;border-radius:0 0 6px 6px}
  .cmd-handle-glyph{font-size:11px;line-height:12px}
}
@media(max-width:768px){
  .cmd-handle{width:50px;height:11px;line-height:10px;border-radius:0 0 5px 5px}
  .cmd-handle-glyph{font-size:9px;line-height:10px}
}

/* -- Desktop tab: taller target ------------------------------
   13px was a thin strip sitting on top of a card, so the click
   was fiddly and easy to miss into the card underneath. 18px is
   a comfortable target without turning the tab back into a slab.
   The glyph grows with it. Mobile is untouched -- it is fine and
   a finger is a bigger target than a cursor anyway. */
@media(min-width:769px){
  .cmd-handle{height:18px;line-height:17px}
  .cmd-handle-glyph{font-size:13px;line-height:17px}
}

/* -- Filter spacing matches the search row -------------------
   .cmdbar drops to a 4px gap on mobile but .cmd-controls kept its
   6px base gap, so the filter row sat looser than the search /
   view-toggle row above it. Same gap on both rows now. */
@media(max-width:768px){
  .cmd-controls{gap:4px}
}

/* -- Mobile: the popover interior ----------------------------
   The bar was tuned for mobile; the panels it opens never were,
   so a phone got 22px/8px controls opening a menu with 12px rows
   and a 28px search field. Scaled to match.

   Deliberate exception: option rows go to 10px, NOT the bar's 8px.
   The bar is 8px because it mirrors the login button, but these
   are a scrollable list you read and tap -- legibility and touch
   target win over strict symmetry, so the rows stay comfortable. */
@media(max-width:768px){
  .cmd-pop{padding:5px;max-height:min(58vh,380px)}
  .cpop-title{font-size:9px;padding:2px 6px 5px;letter-spacing:1.5px}
  .cpop-search{height:26px;font-size:11px;margin-bottom:5px}
  .copt{font-size:10px;padding:6px 7px;gap:7px}
  .copt-box{flex:0 0 13px;height:13px;line-height:11px;font-size:9px}
  .copt-n{font-size:8px;padding:1px 4px}
  .cpop-clear{font-size:10px;padding:5px 7px}
  .cpop-presets{gap:3px;padding:0 3px 5px}
  .cpop-preset{font-size:9px;padding:3px 6px}
  .cpop-none{font-size:10px;padding:6px}
  /* carry over the old .controls vertical padding, which was lost
     when that row was replaced by .cmdbar */
  .cmdbar{padding-top:4px;padding-bottom:5px}
}

/* -- One colour, not two -------------------------------------
   The bar was mixing orange (resting) with white (active, popover
   open, the Sort value, the active count). Everything is orange
   now; ACTIVE is still unmistakable because it carries a 28% fill,
   a solid border and an inset rail -- weight, not a second hue. */
.cbtn.on,.cbtn.open,.cbtn-v{color:var(--accent-red)}
.cbtn.on .cbtn-n{color:var(--accent-red);border-color:rgba(218,41,42,0.45)}

/* -- Bar colour: match donate / login ------------------------
   Resting state is now exactly .auth-btn / .donate-btn: orange
   text, 10% orange fill, 30% orange border, hover to 20% + solid.
   The view toggle already used this recipe, so the row is uniform.

   CONSEQUENCE HANDLED: that tint used to be how an ACTIVE filter
   announced itself. With every control wearing it at rest, active
   needs a louder signal -- a 28% fill, a solid border and an inset
   rail -- or you could no longer see which filters were applied. */
.cbtn,.cmd-handle{
  color:var(--accent-red);
  background:rgba(218,41,42,0.1);
  border:1px solid rgba(218,41,42,0.3);
  transition:all 0.2s;
}
.cmd-handle{border-top:none}
.cbtn:hover,.cmd-handle:hover{
  background:rgba(218,41,42,0.2);
  border-color:var(--accent-red);
  color:var(--accent-red);
}
/* active: unmistakably louder than the resting tint */
.cbtn.on{
  background:rgba(218,41,42,0.28);
  border-color:var(--accent-red);
  box-shadow:inset 2px 0 0 var(--accent-red);
  color:var(--text-primary);
}
/* popover open: solid border, mid fill */
.cbtn.open{
  background:rgba(218,41,42,0.22);
  border-color:var(--accent-red);
  color:var(--text-primary);
}
/* counts must stay legible on an orange fill, so they go dark */
.cbtn-n{background:rgba(0,0,0,0.42);color:var(--accent-red);border:1px solid rgba(218,41,42,0.25)}
.cbtn.on .cbtn-n{color:#fff;border-color:rgba(255,255,255,0.35)}
.cbtn-v{color:var(--text-primary)}
.cbtn-clear{color:var(--accent-red)}
.cbtn-clear:hover{color:var(--accent-red);border-color:var(--accent-red);background:rgba(239,68,68,0.15)}
/* the search field is a field, not a button: same palette, quieter fill */
.cmdbar .search-box{
  background:rgba(218,41,42,0.06);
  border:1px solid rgba(218,41,42,0.3);
}
.cmdbar .search-box:focus-within{border-color:var(--accent-red);background:rgba(218,41,42,0.12)}
.cmdbar .search-box input{color:var(--text-primary)}
.cmdbar .search-box::before{color:var(--accent-red)}


/* -- Bar typography: match the login button ------------------
   The bar borrowed its box metrics from the card/table toggle;
   its TEXT now comes from .auth-btn -- Share Tech Mono, 11px and
   14px of side padding on desktop, 8px and 6px on mobile. The
   Cards/Table toggle is included so the whole row reads as one
   control set rather than two typefaces sitting side by side. */
.cbtn,.view-btn,.cmdbar .search-box input{
  font-family:'Share Tech Mono',monospace;
  font-size:11px;
}
.cbtn,.view-btn{padding:0 14px}
.cbtn-dir{padding:0 10px}
@media(max-width:768px){
  .cbtn,.view-btn,.cmdbar .search-box input{font-size:8px}
  .cbtn,.view-btn{padding:0 6px}
  .cbtn-dir{padding:0 5px}
}


/* -- Card type system: ported from arc (Technique #54) --------
   Audit found 18 distinct treatments here vs arc's 10, with the
   SAME .attr-label class rendering at 10px/0.5px in one container
   and 9px/0.5px in another, .sg-lbl at 8px and .card-cat on its
   own -- arc's exact pre-fix state.

   Canonical label = the SCORE treatment, in this site's own login
   font (Share Tech Mono, same family apex's .auth-btn uses).
   Values, pills and the Rajdhani display sizes keep their roles. */
.score-label,
.card-stats-grid .sg-lbl,
.card-craft-grid .attr-label,
.card-attrs .attr-label,
.card-sources .attr-label,
.attr-label,
.card-cat,
.abil-type,
.use-head{
  font-family:'Share Tech Mono',monospace;
  font-size:10px;
  font-weight:400;
  text-transform:uppercase;
  letter-spacing:1px;
  color:var(--text-muted);
}
/* one italic prose treatment, one value size */
.card-desc,.card-note{font-size:11px;font-style:italic}
.abil-desc,.mag-tab{font-size:11px}
/* one 6px vertical rhythm */
.card-note,.card-locs,.card-attrs,.card-craft-grid,.combat-tips{margin-top:6px}
.card-sources{padding:6px 0}
/* the score row's box is taller than its 5px track, so a 6px margin
   here reads as ~11px -- 2px matches the rhythm optically */
.card-price-row{margin-top:2px}
/* last outliers: badge was sentence-case with different tracking; table cells
   were 10px while every other value is 11px; the ability cooldown is a value,
   not a label, so it joins the value treatment */
.badge{text-transform:uppercase;letter-spacing:1px}
.dt td{font-size:11px}
.abil-cd{font-family:'Exo 2',sans-serif;font-size:11px}
/* the port missed arc's float rule: the handle was position:static, so it
   reserved a full-width strip whose background painted beside the tab */
.cmd-handle{position:absolute;top:100%;left:50%;transform:translateX(-50%);margin:0;z-index:101;box-shadow:0 4px 10px rgba(0,0,0,0.45)}
/* wider Share Tech Mono labels shrank the value column; let long values wrap
   rather than overflow. The container rule ALONE is a no-op: each pill is an
   inline-block with white-space:nowrap, i.e. an ATOMIC box that overflow-wrap
   on the parent cannot break inside. The pills themselves have to be allowed
   to wrap and be capped to the track.
   Measured before: ammo-pill "Mythic Light Rounds" 106.3px in an 88.2px track
   (P2020) and mode-pill "Automatic Burst (4)" 92.5px in 88.2px (Nemesis Burst
   AR) -- the only 2 of 66 pills that exceeded their track. */
.card-stats-grid .sg-val{overflow-wrap:anywhere}
.ammo-pill,.mode-pill{display:inline-block;max-width:100%;white-space:normal;overflow-wrap:anywhere}

/* -- residual type outliers found by the arc parity diff (Technique #86:
   the acceptance test is a DIFF against the template, not "it renders").
   arc carries 12 treatments; these four were apex-only drift.
   NOTE none of these copy an arc LITERAL -- arc has no attachment pill and
   no legend block. They align apex to apex's OWN canonical scale, which is
   what Technique #86(c) asks for. */
/* 1. class-pill differed from badge ONLY in tracking (0.5px vs 1px) -- two
      near-identical treatments is exactly the drift the unification removed */
.class-pill{letter-spacing:1px}
/* 2. att-slot was the last 8px/normal-tracking label, the same shape sg-lbl
      had before the port. It is a micro-label INSIDE a 9px pill, so 10px
      would outsize the pill's own text; it takes the pill scale plus the
      canonical uppercase 1px tracking */
.att-slot{font-size:9px;letter-spacing:1px}
/* 3. ammo-pill was the only pill in Share Tech Mono; att/mode/source/tier/
      zone are all Exo 2 9px. Colour and border stay -- only the family
      joins the other pills */
.ammo-pill{font-family:'Exo 2',sans-serif}
/* 4. Rajdhani display weights: card-name is 700 and so is every Rajdhani
      size on arc, but these two sat at 600 */
.abil-name,.legend-title{font-weight:700}
/* 5. the last two 8px section margins, against the card's 6px rhythm. These
      put 59 cards in the spacing audit's uneven-gap bucket (every weapon:
      card-stats-grid->tier-tabs measured 8px where every other section
      transition measured 6px) */
.tier-tabs{margin-top:6px}
.lvl-table-wrap{margin-top:6px}
/* legend-head's 8px BOTTOM margin was the same 8-vs-6 break on all 28 legend
   cards. It does not appear in the audit's constants table, which reads
   margin-top only -- the gap had to be traced from the measured 8px */
.legend-head{margin-bottom:6px}

/* -- COMMAND BAR CHROME: the surface the port dropped ---------
   The ported block ended at .cmd-controls and never carried arc's
   structural rules for the search field or the buttons, so apex was
   running the OLD chrome underneath the new accent skin. Measured
   against arc, every one of these was wrong:

     search-box width   790 (arc)  vs  361      -- did not take the slack
     search-box radius  8px        vs  0px      -- square corners
     inner input        transparent, no border  vs its OWN dark box,
                                                   own border, own 8px
                                                   radius (a double box)
     .cbtn radius       8px        vs  0px
     .cbtn padding      0 9px      vs  0 14px
     .view-btn padding  0 10px     vs  0 14px

   The padding was not merely unported: apex's "match the login button"
   block (.cbtn,.view-btn{padding:0 14px}) sits AFTER its
   @media(min-width:769px){.cbtn{padding:0 9px}}. Media queries add no
   specificity, so the later 14px silently undid the desktop tightening.
   Appending here puts the correct values last.

   Box metrics are scoped to min-width:769px so the approved mobile
   sizing is untouchable; only the genuinely size-agnostic structure and
   the input reset are unscoped -- the input reset is REQUIRED on mobile
   too, or the double box shows there as well. Colour is deliberately
   absent: apex's accent skin already supplies bg/border/colour, and
   restating them here would overwrite the red with arc's orange. */
.cmdbar .search-box{
  display:flex;align-items:center;gap:4px;
  border-radius:8px;
  overflow-x:auto;scrollbar-width:none;
}
.cmdbar .search-box::-webkit-scrollbar{display:none}
/* strip the input's own box -- the WRAPPER is the visible field */
.cmdbar .search-box input{
  width:auto;flex:1 1 80px;min-width:80px;
  padding:0;background:transparent;border:none;border-radius:0;
}
.cmdbar .search-box input:focus{border-color:transparent}
.search-chips{display:flex;align-items:center;gap:4px;flex:0 0 auto}
.search-chips .chip{padding:2px 6px;font-size:10px;white-space:nowrap}
.cbtn{
  display:inline-flex;align-items:center;gap:5px;
  white-space:nowrap;border-radius:8px;
  cursor:pointer;transition:all .15s;
}
.cbtn-pair{display:inline-flex;gap:2px;flex:0 0 auto}

/* Desktop: the search field takes the slack up to the view toggle.
   It has to be BOTH halves of the swap -- the search grows AND
   .cmd-controls stops growing -- or the controls strip absorbs the free
   space and the search stays fixed no matter what its own flex says.
   That is exactly why apex's search sat at 361px with flex-grow:1. */
@media(min-width:769px){
  .cbtn{height:28px;padding:0 9px}
  .cbtn-dir{padding:0 8px}
  .view-toggle{height:28px}
  .view-btn{padding:0 10px}
  .cmdbar .search-box{height:28px;padding:0 30px 0 32px;flex:1 1 auto;min-width:220px}
  .cmdbar .search-box input{height:26px}
  .cmd-controls{flex:0 1 auto}
}

/* Mobile gutters: the bar has to line up with the header and the cards.
   .cmdbar keeps the desktop 32px side padding on phones unless this overrides
   it, which inset the search field and the view toggle 20px further than
   everything else on the page -- measured at 390px, search started at x=32 and
   the toggle ended at 358 while the cards ran 12 -> 378. arc has this rule;
   the marker-based port never carried it across. */
@media(max-width:768px){
  /* column-gap and row-gap SEPARATELY, never the `gap` shorthand. arc sets
     gap:4px here and row-gap:5px in a LATER block, so arc ends up 4px across
     and 5px between the two rows. Writing the shorthand last collapses
     row-gap to 4px, which made the bar 57px tall against arc's 58 and lifted
     the filter row 1px. */
  .cmdbar{padding-left:12px;padding-right:12px;column-gap:4px;row-gap:5px}
  /* The controls must FIT on one row -- not scroll behind a clipped sort
     arrow, and not wrap to extra rows. apex carries nine controls where arc
     carries six, and at 390px they needed 404.7px against 366px available.
     Tightening the side padding and the gap buys back more than the 38.7px
     shortfall, including the Clear button that appears once a filter is on.
     Sized from measurement, not guessed. */
  .cmd-controls{flex-wrap:nowrap;column-gap:3px}
  .cmd-controls .cbtn{padding:0 3px}
  /* Carets go: seven of them cost ~49px, and on a phone the buttons are
     obviously tappable without the glyph. Clear becomes its X only, worth
     another ~15px. Together that covers the 64px shortfall at 360px with a
     filter active (the widest case, since Clear only exists then). */
  .cbtn-caret{display:none}
  .cbtn-clear{font-size:0}
  .cbtn-clear::before{content:'\2715';font-size:9px;line-height:1}
}

/* The sort VALUE ("Default") rendered white while every other control is
   accent. Same ordering defect as the padding: apex has
   `.cbtn.on,.cbtn.open,.cbtn-v{color:var(--accent-red)}` at line 579 but a
   plain `.cbtn-v{color:var(--text-primary)}` at 619, and the later rule wins
   at equal specificity. arc has these two the other way round, which is why
   arc is correct. valheim is correct for the same reason -- it takes arc's
   rules in arc's own order through the selector extractor. */
.cbtn-v{color:var(--accent-red)}

/* Desktop: the control strip WRAPS instead of clipping.
   .cmd-controls is overflow-x:auto, so once the buttons need more room than
   the strip has, the last one (the sort direction arrow) is sliced and an
   internal scrollbar appears. arc rarely hits it because it carries fewer
   controls; apex has six filter buttons plus sort, direction and clear, and
   at 900px overflowed by 51px with the arrow clipped 51.7px.
   Wrapping to a second row is the same thing the bar already does on mobile,
   and it means no width can ever clip a control. max-height has to grow with
   it or .cmdbar's own drawer transition would crop the second row. */
@media(min-width:769px){
  .cmd-controls{flex-wrap:wrap;row-gap:5px;overflow-x:visible}
  .cmdbar{flex-wrap:wrap;row-gap:5px;max-height:220px}
}

/* On a phone the sort control shows its VALUE, not the word "Sort" -- the
   value ("Default", "Name", ...) plus the direction arrow says what it is,
   and the word costs ~22px on the one row everything has to fit into. */
@media(max-width:768px){
  .cbtn[data-dim="sort"] .cbtn-l{display:none}
}

/* Narrow phones (<=400px) need a little more: the widest case is a filter
   active, which adds the Clear control. */
@media(max-width:400px){
  .cmd-controls{column-gap:2px}
  .cmd-controls .cbtn{padding:0 2px}
}

/* Match the other three: soft radial accent glow over a vertical ramp. */
.img-overlay img{
  background:radial-gradient(circle at 50% 42%,rgba(218,41,42,0.10),rgba(0,0,0,0) 60%),linear-gradient(180deg,#11141b,#0a0c10);
  padding:16px;
}


/* Same backdrop on the CARD thumbnail as in the lightbox, so a thumbnail and
   its enlarged version read as the same object: a soft radial accent glow
   behind the subject over a card-to-background ramp. Uses the site's own
   accent and its own palette vars, so each site keeps its colour.
   Replaces the flat rgba(255,255,255,0.05) fill. */
.card-thumb{
  background:radial-gradient(circle at 50% 42%,rgba(218,41,42,0.10),rgba(0,0,0,0) 60%),linear-gradient(180deg,var(--bg-card),var(--bg-primary));
}
.tbl-thumb{
  background:radial-gradient(circle at 50% 42%,rgba(218,41,42,0.10),rgba(0,0,0,0) 60%),linear-gradient(180deg,var(--bg-card),var(--bg-primary));
}
