/* ── JD Arena shared UI layer ──
   Loaded LAST on every player-facing page (after each page's own inline <style>), so
   these rules win on source order without !important wars. Holds only what should look
   the same everywhere: fonts, gutters, focus/press states, safe areas, the phone tab bar
   (markup injected by /ui.js) and the subpage top bar. Page-specific layout stays in the
   page. Bump the ?v= on every <link> to this file when it changes. */

:root{
  color-scheme:dark;
  --font-body:'Geist','Mukta',system-ui,-apple-system,'Segoe UI',Roboto,sans-serif;
  --font-display:'Barlow Condensed','Mukta',sans-serif;
  --gutter:clamp(16px,4vw,28px);
  --ease-out:cubic-bezier(.16,1,.3,1);
  --tabbar-h:62px;
  --safe-b:env(safe-area-inset-bottom,0px);
  --safe-t:env(safe-area-inset-top,0px);
  --ui-gold:#FFC83D;
  --ui-muted:#8A94A8;
  --ui-line:rgba(255,200,80,.14);
}
/* JD Arena app 2.0+ (html.jd-app, set by ui.js): the app already keeps the page clear of the status bar and the
   phone's back/home buttons, and newer Android WebViews report the same space again as safe-area insets - which
   lifted the bottom tabs far too high. Inside the app the page adds no safe-area space of its own. */
html.jd-app{--safe-b:0px;--safe-t:0px}

/* ── base ── */
html{-webkit-text-size-adjust:100%;text-size-adjust:100%}
body{font-family:var(--font-body);-webkit-tap-highlight-color:rgba(255,200,61,.14);font-feature-settings:'ss01' 0}
a,button,input,select,textarea,label,summary,[role="button"]{touch-action:manipulation}
h1,h2,h3,.sec-h h2{text-wrap:balance}
p,li{text-wrap:pretty}
table,.stat b,.pts-pill b,.nm-count,.tm-urg,[class*="pts"],[class*="score"]{font-variant-numeric:tabular-nums}
select{background-color:#111827;color:#fff}
img{max-width:100%}
@media(pointer:fine){html{overscroll-behavior-y:none}}

/* one focus ring everywhere (the old per-page rules only covered some elements) */
:where(a,button,input,select,textarea,summary,[tabindex]):focus-visible{
  outline:2px solid var(--ui-gold);outline-offset:3px;border-radius:8px}

/* tactile press feedback on every primary/secondary action */
:where(.btn-primary,.btn-ghost,.btn,.lang-btn,.pill,.chip-link,.fx-plan,.tabbar a,.nm-btn,.fab):active{
  transform:translateY(1px) scale(.98)}

/* sticky header must never hide a focused or anchored element */
[id]{scroll-margin-top:84px}

/* ── layout: gutters ──
   index.html's `.sec{padding:… 0 20px}` came after `.wrap{padding:0 28px}` and zeroed
   the side padding, so every section below the hero touched the screen edge on any
   window narrower than the 1450px container (phones and tablets included). */
.wrap{padding-left:var(--gutter);padding-right:var(--gutter)}
.sec.wrap,section.wrap{padding-left:var(--gutter);padding-right:var(--gutter)}

/* ── homepage hero: tighter on phones so the tournaments are one swipe away ──
   Scoped to the homepage's own markup (.hero-content/.hero-inner): challenges, about,
   profile and wallet each have their own unrelated `section.hero`. The homepage
   section's padding lives in index.html for the same reason. */
@media(max-width:640px){
  .hero-content{padding-left:var(--gutter)!important;padding-right:var(--gutter)!important}
  .hero-inner .eye{margin-bottom:14px}
  .hero-inner h1{font-size:clamp(2.6rem,12vw,3.4rem);margin-bottom:14px}
  .hero-inner p{font-size:1rem;line-height:1.55;margin-bottom:22px}
  .hero-inner .btns{display:grid;grid-template-columns:1fr 1fr;gap:10px}
  .hero-inner .btns a{display:flex;align-items:center;justify-content:center;text-align:center;padding:13px 10px;font-size:.92rem;line-height:1.25;min-height:48px}
  .arena-stats{margin:22px var(--gutter) 0!important;border-radius:18px}
  .arena-stats .stat{padding:12px 6px}
  .arena-stats .stat b{font-size:1.75rem}
  /* 4 stacked full-width feature cards pushed tournaments ~2 screens down: make them a
     compact 2x2 of icon + title (the one-line descriptions read fine on desktop only) */
  .feature-strip{grid-template-columns:1fr 1fr!important;gap:10px;margin-top:14px}
  .feature-card{padding:12px;gap:10px;border-radius:14px}
  .feature-card svg{width:22px;height:22px}
  .feature-card b{font-size:.8rem;line-height:1.25}
  .feature-card span{display:none}
  .sec{padding-top:40px}
  .sec-h{flex-wrap:wrap;row-gap:4px;margin-bottom:20px}
  .sec-h .ln{display:none}
  .sec-h .tag{flex-basis:100%}
}
@media(max-width:340px){.hero-inner .btns{grid-template-columns:1fr}}

/* ── phone bottom tab bar (markup from /ui.js) ── */
.tabbar{display:none}
@media(max-width:640px){
  .tabbar{
    display:grid;grid-template-columns:repeat(6,1fr);
    /* 45: above page content, below every overlay (confirm dialogs .ov 50, drawer
       scrim 55, modals 60), so an open dialog dims and blocks the tab bar too */
    position:fixed;left:0;right:0;bottom:0;z-index:45;
    height:calc(var(--tabbar-h) + var(--safe-b));padding:0 4px var(--safe-b);
    background:rgba(9,12,20,.94);border-top:1px solid var(--ui-line);
    box-shadow:0 -10px 30px rgba(3,5,10,.55)}
  @supports(backdrop-filter:blur(1px)){
    .tabbar{background:rgba(9,12,20,.82);backdrop-filter:blur(16px) saturate(150%);-webkit-backdrop-filter:blur(16px) saturate(150%)}}
  /* phones: a live blur behind the fixed tab bar is redrawn every scroll frame and left pages blank while scrolling */
  @media(pointer:coarse){.tabbar{background:rgba(9,12,20,.97);backdrop-filter:none;-webkit-backdrop-filter:none}}
  .tabbar a{
    position:relative;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:3px;
    min-height:48px;color:var(--ui-muted);font:600 .64rem/1.1 var(--font-body);letter-spacing:.01em;
    text-decoration:none;transition:color .2s var(--ease-out),transform .15s var(--ease-out)}
  .tabbar svg{width:22px;height:22px;flex:none}
  .tabbar .tb-me{width:24px;height:24px;flex:none;border-radius:50%;overflow:hidden;display:grid;place-items:center;font-size:.7rem;font-weight:800;background:var(--ui-gold,#FFC83D);color:#0A0A12;box-shadow:0 0 0 1.5px rgba(255,255,255,.25)}
  .tabbar .tb-me img{width:100%;height:100%;object-fit:cover}
  .tabbar a[aria-current="page"] .tb-me{box-shadow:0 0 0 2px var(--ui-gold,#FFC83D)}
  .tabbar a span{max-width:100%;padding:0 2px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .tabbar a[aria-current="page"]{color:var(--ui-gold)}
  .tabbar a[aria-current="page"]::before{
    content:'';position:absolute;top:0;left:30%;right:30%;height:2px;border-radius:0 0 2px 2px;background:var(--ui-gold)}
  body.has-tabbar{padding-bottom:calc(var(--tabbar-h) + var(--safe-b))}
  /* everything that floats at the bottom moves up above the bar */
  body.has-tabbar .fab{bottom:calc(var(--tabbar-h) + var(--safe-b) + 12px);right:14px;padding:9px 13px;font-size:.78rem;box-shadow:0 6px 18px rgba(3,5,10,.5)}
  body.has-tabbar .fab-nudge{bottom:calc(var(--tabbar-h) + var(--safe-b) + 66px)}
  body.has-tabbar .fb-panel{bottom:calc(var(--tabbar-h) + var(--safe-b) + 8px);max-height:calc(100dvh - var(--tabbar-h) - var(--safe-b) - 80px)}
  body.has-tabbar .next-match{bottom:calc(var(--tabbar-h) + var(--safe-b) + 66px)!important}
  body.has-tabbar .toast{bottom:calc(var(--tabbar-h) + var(--safe-b) + 14px)}
  body.has-tabbar .tut{bottom:calc(var(--tabbar-h) + var(--safe-b))}
  /* the drawer's own nav links duplicate the tab bar; keep account actions only */
  body.nav-locked .fab,body.nav-locked .fab-nudge,body.nav-locked .storage-note{visibility:hidden}
}
@media(max-width:640px) and (prefers-reduced-motion:reduce){.tabbar a{transition:none}}

/* ── subpage top bar (challenges / profile / wallet) ──
   These pages shared one `.top` row whose link chips wrapped into a 4-line
   "← Back to Arena" and overflowed the phone width on /profile/. */
.top{display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:nowrap;min-height:56px;padding-top:max(10px,var(--safe-t))}
.top .back{display:inline-flex;align-items:center;gap:10px;white-space:nowrap;font-weight:600;min-height:44px}
.top .back img{width:34px;height:34px;border-radius:9px;flex:none}
.top-links{display:flex;gap:8px;overflow-x:auto;scrollbar-width:none;min-width:0}
.top-links::-webkit-scrollbar{display:none}
.chip-link{white-space:nowrap;min-height:40px;display:inline-flex;align-items:center}
@media(max-width:640px){
  .top-links{display:none} /* same destinations live in the tab bar */
}

/* ── tables never break the page width ── */
.tbl-scroll,.lb-table-wrap{overflow-x:auto;-webkit-overflow-scrolling:touch;overscroll-behavior-x:contain}

/* ── drawers and modals keep scroll inside ── */
.zmodal,.bar-nav,.fb-panel{overscroll-behavior:contain}
.zmodal{max-height:calc(100dvh - 40px)}
@media(max-width:640px){
  /* bottom-sheet modals on phones: thumb-reachable, full width */
  .zoverlay{align-items:flex-end;padding:0}
  .zoverlay .zmodal{width:100%;border-radius:22px 22px 0 0;max-height:calc(100dvh - 24px);padding-bottom:calc(22px + var(--safe-b))}
}

/* ── tablet (641–1024): roomier cards, header that doesn't squash ── */
@media(min-width:641px) and (max-width:1024px){
  .feature-strip{grid-template-columns:repeat(2,1fr)}
}

@media(prefers-reduced-motion:reduce){
  :where(.btn-primary,.btn-ghost,.btn,.lang-btn,.pill,.chip-link,.fx-plan,.tabbar a,.nm-btn,.fab):active{transform:none}
}

/* ── standings tables on phones (homepage Best-of-3 + /leaderboard.html share
   .pts-table: rank, squad, R1-R3 kills, total). Six table columns at 360px wrapped every
   squad name onto 2-3 lines and clipped "Total" off the right edge, so each row becomes
   a card: rank | squad name (one line) over a small "R1 25 · R2 23 · R3 6" kills line |
   big total. Markup is unchanged (it's JS-rendered, and the leaderboard animates rows). */
@media(max-width:640px){
  .pts-table,.pts-table tbody{display:block;width:100%}
  .pts-table thead{display:none}
  .pts-table tr{
    display:grid;grid-template-columns:30px auto auto auto 1fr auto;
    grid-template-areas:"rk team team team team tot" "rk r1 r2 r3 . tot";
    align-items:center;column-gap:10px;row-gap:3px;
    margin:0 0 8px;padding:11px 14px 11px 12px;border-radius:14px}
  .pts-table tr:not(.sqfx){background:var(--panel,#111827);border:1px solid rgba(255,200,80,.08)}
  .pts-table td,.pts-table tr:hover td,.pts-table tr.mine td{
    display:block;padding:0!important;background:none!important;border-radius:0!important;box-shadow:none!important;border:0!important}
  .pts-table tbody tr:nth-child(1):not(.sqfx){border-color:rgba(255,213,74,.45);background:linear-gradient(100deg,rgba(255,200,61,.12),var(--panel,#111827) 60%)}
  .pts-table tbody tr:nth-child(2):not(.sqfx){border-color:rgba(217,222,232,.28)}
  .pts-table tbody tr:nth-child(3):not(.sqfx){border-color:rgba(227,161,95,.32)}
  .pts-table tr.mine{background:rgba(94,219,149,.11);box-shadow:inset 3px 0 0 #5EDB95}
  .pts-table td.rk{grid-area:rk;font-size:1.45rem;line-height:1;text-align:center}
  .pts-table td:nth-of-type(2){
    grid-area:team;min-width:0;display:flex!important;align-items:center;gap:8px;
    font-weight:700;font-size:.95rem;white-space:nowrap;overflow:hidden}
  .pts-table td:nth-of-type(2) img{width:26px!important;height:26px!important;flex:none;margin:0!important}
  .pts-table td:nth-of-type(2) .team-name,.pts-table td:nth-of-type(2)>.fxn{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .pts-table td:nth-of-type(2) .team-name{display:flex;align-items:center;gap:6px}
  .pts-table td:nth-of-type(2) .team-name>.fxn{min-width:0;overflow:hidden;text-overflow:ellipsis}
  .pts-table .fxn-tag{flex:none;font-size:.58rem!important;padding:1px 6px!important;margin-left:6px}
  .pts-table td:nth-of-type(3){grid-area:r1}
  .pts-table td:nth-of-type(4){grid-area:r2}
  .pts-table td:nth-of-type(5){grid-area:r3}
  .pts-table td.num{font-size:.74rem;color:var(--silver,#A6AFC2);text-align:left;white-space:nowrap;display:flex!important;align-items:center;gap:2px}
  .pts-table td.num::before{color:rgba(166,175,194,.6);font-weight:600;margin-right:3px}
  .pts-table td:nth-of-type(3).num::before{content:'M1'}
  .pts-table td:nth-of-type(4).num::before{content:'M2'}
  .pts-table td:nth-of-type(5).num::before{content:'M3'}
  .pts-table td.num .mv{font-size:.62rem;margin-left:1px}
  .pts-table td.tot{grid-area:tot;font-family:var(--font-display);font-weight:700;font-size:1.7rem;line-height:1;text-align:right;color:var(--gold-l,#FFDD85)}
  .pts-table td.tot::after{content:'pts';display:block;font-family:var(--font-body);font-size:.58rem;font-weight:600;color:var(--silver,#A6AFC2);letter-spacing:.04em;margin-top:2px}

  /* podium: three equal columns sharing the width (the fixed 100px slots cut every
     name to "Ancient Og…"); names may take two lines; step bars attach to the cards */
  .podium{flex-wrap:nowrap!important;gap:8px!important;align-items:flex-end}
  .pod-slot{width:auto!important;flex:1 1 0;min-width:0}
  .pod-card{padding:14px 8px 12px!important;border-radius:14px 14px 0 0!important}
  .pod-name{white-space:normal!important;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;line-height:1.2;min-height:2.4em;font-size:.78rem!important;overflow-wrap:anywhere}
  .pod-bar{margin-top:0!important;border-radius:0 0 10px 10px!important;font-size:1.6rem!important}
}

/* leaderboard podium on tablets: fixed 150px slots cut longer squad names; let names wrap
   to two lines and keep the step bars attached to their cards at every width */
@media(min-width:641px){
  .pod-name{white-space:normal!important;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;line-height:1.2;overflow-wrap:anywhere}
  .pod-slot{width:170px!important}
  .pod-card{border-radius:14px 14px 0 0!important}
  .pod-bar{margin-top:0!important}
}

/* leaderboard podium steps: solid gold / silver / bronze like the homepage podium
   (they were a faint dark fade with a barely visible rank number) */
.pod-slot .pod-bar{color:rgba(7,9,15,.72)!important;font-size:1.8rem;align-items:center!important;padding-top:0!important;box-shadow:inset 0 1px 0 rgba(255,255,255,.35)}
.pod-slot.p1 .pod-bar{background:linear-gradient(180deg,#FFE27A,#E9B33A)!important}
.pod-slot.p2 .pod-bar{background:linear-gradient(180deg,#E9EDF3,#AEB6C6)!important}
.pod-slot.p3 .pod-bar{background:linear-gradient(180deg,#EDAE72,#B8733B)!important}

/* ── upcoming/live cards on phones: same content, about half the height ── */
@media(max-width:640px){
  .arena-grid{gap:14px}
  .tcard:not(.past) .tcard-media{height:132px}
  .tcard:not(.past) .tcard-body{padding:16px 16px 18px}
  .tcard:not(.past) .tbadge{margin-bottom:8px}
  .tcard:not(.past) .tname{font-size:1.4rem}
  .tcard:not(.past) .tgame{margin-bottom:12px}
  .tcard:not(.past) .tmeta{display:grid;grid-template-columns:1fr 1fr;gap:10px 14px;margin-bottom:14px}
  .tcard:not(.past) .tmeta .row{flex-direction:column;justify-content:flex-start;gap:1px}
  .tcard:not(.past) .tmeta .row span{font-size:.66rem;color:var(--silver,#A6AFC2)}
  .tcard:not(.past) .tmeta .row b{font-size:.84rem;text-align:left;font-weight:600}
  .tcard:not(.past) .troster{display:none} /* who's in: "N/12 squads · tap to view" opens the full list */
  .tcard:not(.past) .tslots-label{margin-bottom:12px}

  /* fewer buttons on phones: one main action in the hero (Discord has its own section
     further down), and no "Back to site" on the leaderboard (the tab bar has Home) */
  .hero-inner .btns{grid-template-columns:1fr!important}
  .hero-inner .btns .discord-cta{display:none!important}
  header .back-btn{display:none}
  /* the leaderboard showed the winner 3 times (photo banner, podium, row 1): the podium's
     crowned #1 is enough on a phone */
  #champ:not(.hw){display:none!important}   /* the 🎃 Halloween banner still shows */
}

/* squad-effects showcase: it pauses its animations off-screen (.fx-paused), which also froze
   the entry fade (chipIn) at opacity 0, leaving empty boxes until the observer caught up.
   !important beats the animated value, so previews are always visible; the effect loops
   themselves are untouched. */
#fx-show .sqitem{opacity:1!important;transform:none!important}
@media(max-width:640px){
  /* 8 stacked effect previews were ~900px of scrolling: swipe through them instead */
  #fx-show{display:flex!important;flex-direction:row!important;flex-wrap:nowrap!important;max-height:none!important;overflow-x:auto!important;overflow-y:hidden!important;scroll-snap-type:x mandatory;gap:10px!important;
    margin:-10px calc(var(--gutter)*-1) 0!important;padding:14px var(--gutter) 18px!important;scrollbar-width:none;overscroll-behavior-x:contain}
  #fx-show::-webkit-scrollbar{display:none}
  #fx-show .fx-show-item{flex:0 0 84%;scroll-snap-align:center}
}

/* ── homepage tutorial ("How to join"): numbered steps that read as one path ──
   Desktop: five cards in a row joined by a thin gold line. Phones: a vertical timeline. */
.howto-list{list-style:none;margin:0;padding:0;display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:14px;position:relative;counter-reset:none}
.howto-list::before{content:'';position:absolute;left:8%;right:8%;top:34px;height:1px;background:linear-gradient(90deg,transparent,var(--gold-m,rgba(255,200,80,.42)),transparent)}
.howto-step{position:relative;display:flex;flex-direction:column;gap:12px;padding:18px 16px 18px;border-radius:16px;background:var(--panel,#111827);border:1px solid var(--line,rgba(255,200,80,.14))}
.howto-step .snum{display:inline-flex;align-items:center;justify-content:center;width:34px;height:34px;border-radius:50%;flex:none;background:linear-gradient(135deg,var(--gold,#FFC83D),var(--gold-2,#FFAE00));color:#07090F;font-weight:800;font-size:.95rem;box-shadow:0 0 0 5px var(--bg,#07090F)}
.howto-step b{display:block;font-size:1rem;margin-bottom:4px;color:var(--cream,#fff)}
.howto-step span:not(.snum){display:block;font-size:.84rem;line-height:1.5;color:var(--silver,#A6AFC2)}
.howto-link{display:inline-block;margin-top:8px;font-size:.82rem;font-weight:700;color:var(--gold-l,#FFDD85)}
.howto-link:hover{text-decoration:underline;text-underline-offset:3px}
@media(max-width:1024px){
  .howto-list{grid-template-columns:1fr;gap:0}
  .howto-list::before{left:33px;right:auto;top:24px;bottom:24px;width:1px;height:auto;background:linear-gradient(180deg,var(--gold-m,rgba(255,200,80,.42)),rgba(255,200,80,.08))}
  .howto-step{flex-direction:row;align-items:flex-start;gap:14px;padding:14px 0 14px 16px;background:none;border:0;border-radius:0}
}

/* links under the event grid + empty state */
.ev-links{display:flex;flex-wrap:wrap;gap:10px;margin-top:4px}
.ev-link{display:inline-flex;align-items:center;gap:6px;min-height:44px;padding:10px 18px;border-radius:999px;border:1px solid var(--line,rgba(255,200,80,.14));background:rgba(255,255,255,.03);font-weight:600;font-size:.88rem;color:var(--cream,#fff);transition:border-color .2s,background .2s}
.ev-link:hover{border-color:var(--gold-m,rgba(255,200,80,.42));background:rgba(255,200,61,.06)}
.ev-empty{grid-column:1/-1;text-align:center;color:var(--silver,#A6AFC2);padding:34px 18px;border:1px dashed var(--line,rgba(255,200,80,.14));border-radius:16px;margin:0}
.ev-empty a{color:var(--gold-l,#FFDD85);text-decoration:underline;text-underline-offset:3px}
@media(max-width:640px){.ev-links{display:grid;grid-template-columns:1fr 1fr}.ev-link{justify-content:center;padding:10px}}

/* ── /events/: past events archive ── */
.pe-head{margin:0 0 22px}
.pe-head h1{font-family:var(--font-display);font-weight:700;font-size:clamp(2.2rem,6vw,3.2rem);line-height:1;margin:0 0 8px}
.pe-head p{margin:0;color:var(--silver,#A6AFC2)}
.pe-stats{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:10px;margin:18px 0 26px}
.pe-stats div{padding:14px 16px;min-width:0;border-radius:14px;background:var(--panel,#111827);border:1px solid var(--line,rgba(255,200,80,.14))}
.pe-stats b{display:block;font-family:var(--font-display);font-size:1.9rem;line-height:1;color:var(--gold-l,#FFDD85)}
.pe-stats span{font-size:.76rem;color:var(--silver,#A6AFC2)}
.pe-list{display:grid;gap:12px}
.pe-card{display:grid;grid-template-columns:96px 1fr auto;gap:16px;align-items:center;padding:12px;border-radius:16px;background:var(--panel,#111827);border:1px solid var(--line,rgba(255,200,80,.14));cursor:pointer;text-align:left;width:100%;color:inherit;font:inherit;transition:border-color .2s,transform .2s var(--ease-out)}
.pe-card:hover{border-color:var(--gold-m,rgba(255,200,80,.42))}
.pe-img{width:96px;height:96px;border-radius:12px;background-size:cover;background-position:center;background-color:#0d1320}
.pe-main{min-width:0}
.pe-name{font-family:var(--font-display);font-weight:700;font-size:1.35rem;line-height:1.1;margin:0 0 4px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.pe-meta{display:flex;flex-wrap:wrap;gap:4px 14px;font-size:.8rem;color:var(--silver,#A6AFC2)}
.pe-meta b{color:var(--cream,#fff);font-weight:600}
.pe-win{margin-top:8px;display:inline-flex;align-items:center;gap:6px;padding:4px 10px;border-radius:999px;background:rgba(255,200,61,.1);border:1px solid rgba(255,200,61,.3);font-size:.8rem;font-weight:700;color:var(--gold-l,#FFDD85);max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pe-status{font-size:.72rem;font-weight:700;padding:4px 10px;border-radius:999px;background:rgba(255,255,255,.06);color:var(--silver,#A6AFC2);white-space:nowrap}
.pe-status.cancelled{background:rgba(255,138,138,.1);color:#FF8A8A}
.pe-card.slim{grid-template-columns:1fr auto;padding:14px 16px}
.pe-squads{grid-column:1/-1;display:none;flex-wrap:wrap;gap:6px;padding-top:4px;border-top:1px solid var(--line,rgba(255,200,80,.14));margin-top:2px}
.pe-card.open .pe-squads{display:flex;padding-top:12px}
.pe-squads span{display:inline-flex;align-items:center;gap:6px;padding:5px 10px;border-radius:999px;background:rgba(255,255,255,.05);font-size:.8rem}
.pe-squads img{width:20px;height:20px;border-radius:50%;object-fit:cover}
.pe-empty{text-align:center;color:var(--silver,#A6AFC2);padding:40px 16px;border:1px dashed var(--line,rgba(255,200,80,.14));border-radius:16px}
@media(max-width:640px){
  .pe-card{grid-template-columns:64px 1fr;gap:12px;padding:10px}
  .pe-img{width:64px;height:64px}
  .pe-name{font-size:1.15rem}
  .pe-card>.pe-status{display:none}
  .pe-card.slim{grid-template-columns:1fr auto}
  .pe-card.slim>.pe-status{display:inline-block}
}
@media(prefers-reduced-motion:reduce){.pe-card,.ev-link{transition:none}}

/* ── no sideways page scroll on any page: anything wider than the screen is clipped (clip,
   unlike hidden, doesn't break position:sticky) ── */
html{overflow-x:hidden}
@supports (overflow:clip){html,body{overflow-x:clip}}
img,video,canvas,iframe{max-width:100%}
/* ── footer added by /ui.js on pages that had none ── */
.site-foot{margin:40px auto 0;padding:24px 16px 32px;border-top:1px solid var(--ui-line,rgba(255,255,255,.08));text-align:center;font-size:.82rem;color:var(--silver,#A6AFC2)}
/* ── site links (injected into every footer by /ui.js) ── */
.site-links{display:flex;flex-wrap:wrap;justify-content:center;gap:4px 18px;margin-top:12px;font-size:.84rem}
.site-links a{color:var(--gold-l,#FFDD85);text-decoration:none;min-height:32px;display:inline-flex;align-items:center}
.site-links a:hover{text-decoration:underline;text-underline-offset:3px}
/* ── legal links (injected into every footer by /ui.js) ── */
.legal-links{display:flex;flex-wrap:wrap;justify-content:center;gap:6px 16px;margin-top:14px;font-size:.8rem}
.legal-links a{color:var(--silver,#A6AFC2);text-decoration:underline;text-underline-offset:3px;min-height:32px;display:inline-flex;align-items:center}
.legal-links a:hover{color:var(--gold-l,#FFDD85)}
.legal-links span{flex-basis:100%;text-align:center;color:var(--ui-muted);font-size:.74rem}
/* one-time storage notice: sits above the phone tab bar, out of the way of content */
.storage-note{position:fixed;left:16px;bottom:16px;z-index:44;max-width:380px;display:flex;align-items:center;gap:12px;padding:12px 14px;border-radius:14px;background:#111827;border:1px solid var(--ui-line);box-shadow:0 12px 30px rgba(3,5,10,.6);font-size:.8rem;color:#C9D0DD}
.storage-note p{margin:0}
.storage-note a{color:#FFDD85;text-decoration:underline;text-underline-offset:2px}
.storage-note button{flex:none;min-height:40px;padding:8px 16px;border-radius:999px;border:0;background:var(--ui-gold);color:#07090F;font:700 .82rem var(--font-body);cursor:pointer}
@media(max-width:640px){.storage-note{left:12px;right:12px;max-width:none;bottom:calc(var(--tabbar-h) + var(--safe-b) + 64px)}}

/* /events/ reviews (inside an opened event card) */
.pe-rev{grid-column:1/-1;display:none}
.pe-card.open .pe-rev{display:block;padding-top:12px;border-top:1px solid var(--line,rgba(255,200,80,.14));cursor:default}
.pe-rev:empty{display:none!important}
.pe-rev-sum{font-size:.84rem;color:var(--cream,#fff);margin-bottom:6px}
.pe-stars{color:#FFC83D;letter-spacing:1px}
.pe-rev-item{margin:4px 0;font-size:.82rem;color:var(--silver,#A6AFC2)}
.pe-rate{margin-top:6px;min-height:40px;padding:8px 14px;border-radius:999px;border:1px solid var(--gold-m,rgba(255,200,80,.42));background:none;color:var(--gold-l,#FFDD85);font:600 .82rem var(--font-body);cursor:pointer}
.pe-form{display:grid;gap:8px;margin-top:8px;font-size:.84rem}
.pe-form fieldset{border:0;padding:0;margin:0;display:flex;flex-wrap:wrap;gap:10px}
.pe-form legend{padding:0;margin-bottom:4px;color:var(--cream,#fff)}
.pe-form label{display:inline-flex;align-items:center;gap:4px;min-height:32px}
.pe-form textarea{width:100%;min-height:70px;border-radius:10px;border:1px solid var(--line,rgba(255,200,80,.14));background:#0D111B;color:#fff;padding:8px;font:inherit}
.pe-form button{justify-self:start;min-height:40px;padding:8px 16px;border-radius:999px;border:0;background:var(--ui-gold);color:#07090F;font-weight:700;cursor:pointer}
.pe-msg{margin:0;color:var(--silver,#A6AFC2)}

/* ── app-required screen on phone browsers (/ui.js) ── */
html.app-gated,html.app-gated body{overflow:hidden!important}
html.app-gated .tabbar,html.app-gated .fab,html.app-gated .storage-note,html.app-gated .fab-nudge,html.app-gated #preloader{display:none!important}
.app-gate{position:fixed;inset:0;z-index:2147483000;overflow-y:auto;background:radial-gradient(900px 500px at 50% -10%,rgba(255,200,61,.14),transparent 60%),#07090F;color:#fff;display:flex;justify-content:center;padding:max(28px,var(--safe-t)) 16px calc(28px + var(--safe-b))}
.ag-card{width:100%;max-width:420px;margin:auto 0;text-align:center}
.ag-card img{border-radius:16px;margin-bottom:14px}
.ag-card h1{font-family:var(--font-display);font-weight:700;font-size:2.2rem;line-height:1.05;margin:0 0 10px}
.ag-lead{color:#C9D0DD;font-size:.95rem;line-height:1.55;margin:0 0 18px}
.ag-btn{display:flex;align-items:center;justify-content:center;width:100%;min-height:52px;border:0;border-radius:14px;background:linear-gradient(100deg,#FFC83D,#FFAE00);color:#07090F;font:800 1.02rem var(--font-body);text-decoration:none;cursor:pointer;margin-bottom:14px}
.ag-btn[hidden],.ag-steps[hidden],.ag-installed[hidden]{display:none}
.ag-ghost{width:100%;min-height:46px;border-radius:14px;border:1px solid rgba(255,200,80,.42);background:none;color:#FFDD85;font:700 .92rem var(--font-body);cursor:pointer;margin-bottom:14px;overflow-wrap:anywhere}
.ag-steps{text-align:left;margin:0 0 18px;padding:14px 16px 14px 36px;border-radius:14px;background:#111827;border:1px solid rgba(255,200,80,.14);font-size:.92rem;line-height:1.6;color:#C9D0DD}
.ag-steps li{margin:4px 0}.ag-steps b{color:#fff}
.ag-perks{list-style:none;text-align:left;margin:0 0 14px;padding:0;display:grid;gap:8px}
.ag-perks li{padding:10px 12px;border-radius:12px;background:rgba(255,255,255,.04);font-size:.86rem;color:#E4E8F0}
.ag-installed{color:#5EDB95;font-size:.9rem;margin:0 0 12px}
.ag-foot{font-size:.8rem;color:#8A94A8;margin:6px 0 0}.ag-foot a{color:#A6AFC2}
.ag-ok{margin:0 0 16px;padding:12px 14px;border-radius:14px;background:rgba(94,219,149,.1);border:1px solid rgba(94,219,149,.35);color:#BFF2D6;font-size:.95rem}

/* Chat tab: unread count from 💬 Messages (chat.js setBadges) */
.tabbar a{position:relative}
.tabbar .tb-count{position:absolute;top:4px;left:calc(50% + 4px);min-width:17px;height:17px;padding:0 5px;border-radius:9px;background:#FF3B5C;color:#fff;font:800 .62rem/17px var(--font-body,system-ui);text-align:center;box-shadow:0 0 0 2px #07090F}
.tabbar .tb-count[hidden]{display:none}

/* Motion polish: page-to-page cross-fade (Chrome/WebView 126+, ignored elsewhere), a press-down on buttons and
   tabs, and the Lottie success tick from jdSuccess() in ui.js. All off with prefers-reduced-motion. */
@view-transition{navigation:auto}
::view-transition-old(root),::view-transition-new(root){animation-duration:.18s}
.tabbar a:active,button:not(:disabled):active,.btn:active,[role="button"]:active{scale:.96}
.tabbar a[aria-current="page"] svg{animation:jd-tab-pop .32s cubic-bezier(.34,1.56,.64,1)}
@keyframes jd-tab-pop{0%{transform:scale(.8)}100%{transform:scale(1)}}
.jd-lottie-pop{position:fixed;left:50%;top:42%;width:150px;height:150px;margin:-75px 0 0 -75px;z-index:2147483000;pointer-events:none;transition:opacity .25s,transform .25s}
.jd-lottie-pop.out{opacity:0;transform:scale(.9)}
@media(prefers-reduced-motion:reduce){
  @view-transition{navigation:none}
  .tabbar a:active,button:active,.btn:active,[role="button"]:active{scale:none}
  .tabbar a[aria-current="page"] svg{animation:none}
}

/* Effects show without their names: the squad's look (glow, thunder, steel...) speaks for itself, so the label chip
   next to the name is hidden everywhere it is rendered (home/events squad cards, leaderboard, challenge cards). */
.sqfx-tag,.fxt{display:none!important}
