/* The hub: a living sports menu — painted city, illustrated sport cards that
   lift and shine when picked, a big friendly scan-to-join card, and your
   friends' faces popping in as they join. Pure DOM/CSS: crisp on any TV and
   costs no 3D rendering while you choose. */
body[data-state="lobby"] #world { visibility: hidden; }
.hub { position: absolute; top: 0; right: 0; bottom: 0; left: 0; overflow: hidden; pointer-events: auto; background: #7cc6ef; }
.hub-bg { position: absolute; top: -3%; right: -3%; bottom: -3%; left: -3%; background: #8fd0f2 center / cover no-repeat; background-image: url('../assets/art/hub-bg.webp'), linear-gradient(180deg, #5fb3ec 0%, #aee0f7 55%, #f6e4c4 100%); animation: hub-drift 40s ease-in-out infinite alternate; }
.net-slow .hub-bg { background-image: url('../assets/art/hub-bg-lite.webp'), linear-gradient(180deg, #5fb3ec 0%, #aee0f7 55%, #f6e4c4 100%); }
.hub::after { content: ''; position: absolute; top: 0; right: 0; bottom: 0; left: 0; background: radial-gradient(120% 90% at 50% 40%, rgba(255,255,255,0) 40%, rgba(12,40,70,.35) 100%), linear-gradient(180deg, rgba(10,40,80,.28) 0%, rgba(10,40,80,0) 20%); pointer-events: none; }
@keyframes hub-drift { from { transform: scale(1.02) translateX(-.8%); } to { transform: scale(1.06) translateX(.8%); } }
.hub-spark { position: absolute; width: .9vh; height: .9vh; border-radius: 50%; background: radial-gradient(circle, #fff 0%, rgba(255,255,255,0) 70%); opacity: 0; animation: spark 5s ease-in-out infinite; pointer-events: none; z-index: 1; }
@keyframes spark { 0%, 100% { opacity: 0; transform: translateY(0) scale(.6); } 40% { opacity: .9; } 70% { opacity: .5; transform: translateY(-5vh) scale(1.1); } }

/* ---- top bar */
.hub-top { position: absolute; z-index: 3; top: 2.6vh; left: 3vw; right: 3vw; display: flex; align-items: center; justify-content: space-between; gap: 2vw; }
.hub-logo { display: grid; line-height: .9; font-family: var(--display); color: #fff; filter: drop-shadow(0 .5vh 0 rgba(10,40,90,.45)); -webkit-text-stroke: .35vh #1a4f9a; paint-order: stroke fill; }
.hub-logo b { font-weight: 400; font-size: 6.2vh; letter-spacing: .01em; }
.hub-logo span { font-size: 3.5vh; letter-spacing: .6em; margin-left: .3vh; }
.hub-logo em { font-style: normal; font-family: var(--body); font-weight: 800; font-size: 1.6vh; letter-spacing: .5em; -webkit-text-stroke: 0; color: #eaf6ff; margin-top: .9vh; }
.hub-tip { flex: 1; text-align: center; font-family: var(--display); font-size: 3vh; color: #fff; -webkit-text-stroke: .3vh #1a4f9a; paint-order: stroke fill; filter: drop-shadow(0 .4vh 0 rgba(10,40,90,.35)); animation: tip-bob 2.4s ease-in-out infinite; }
@keyframes tip-bob { 50% { transform: translateY(-.5vh); } }
.hub-right { display: flex; align-items: center; gap: 1.2vw; }
.hub .roster { display: flex; gap: .8vh; align-items: center; min-height: 7vh; justify-content: flex-end; }
.hub .avatar { width: 7vh; height: 7vh; border-radius: 50%; border: .5vh solid #fff; background-size: cover; background-position: center 30%; display: grid; place-items: center; font-family: var(--display); font-size: 3vh; color: #fff; box-shadow: 0 .7vh 0 rgba(10,40,90,.35); animation: pop-in .5s cubic-bezier(.2,1.8,.4,1) both; position: relative; text-shadow: 0 .2vh 0 rgba(0,0,0,.25); }
.hub .avatar b { position: absolute; bottom: -2.6vh; left: 50%; transform: translateX(-50%); font-family: var(--body); font-weight: 800; font-size: 1.5vh; white-space: nowrap; background: rgba(10,40,90,.75); padding: .1vh .8vh; border-radius: 99px; text-shadow: none; }
.hub .avatar.host::after { content: '★'; position: absolute; top: -1.2vh; right: -1vh; width: 3vh; height: 3vh; border-radius: 50%; background: #ffc53d; color: #6b3d00; font-size: 1.8vh; display: grid; place-items: center; box-shadow: 0 .3vh 0 rgba(0,0,0,.25); }
.hub .avatar.empty { background: rgba(255,255,255,.35); border-style: dashed; font-size: 4vh; color: #fff; box-shadow: none; }
.hub .room-pill { background: rgba(10,40,90,.55); color: #fff; }

/* ---- the grid: 4 × 2 sports + the tall scan card on the right */
.cards { position: absolute; z-index: 2; left: 3vw; right: 3vw; top: 17vh; bottom: 4vh; display: grid; grid-template-columns: repeat(4, 1fr) 1.02fr; grid-template-rows: 1fr 1fr; gap: 2.4vh 1.3vw; }
.cards .join-card { grid-column: 5; grid-row: 1 / span 2; grid-template-columns: 1fr; justify-items: center; align-content: center; text-align: center; gap: 2vh; }
.cards .join-card .join-copy { justify-items: center; }
.tile { position: relative; border: 0; padding: 0; border-radius: 2.4vh; overflow: hidden; background: var(--tc, #5aa); cursor: pointer; color: #fff; text-align: left; box-shadow: 0 0 0 .45vh rgba(255,255,255,.9), 0 1.2vh 2.4vh rgba(10,40,90,.35); transition: transform .28s cubic-bezier(.2,1.5,.4,1), box-shadow .28s, filter .28s; animation: card-in .6s cubic-bezier(.2,1.4,.4,1) both; }
.tile:nth-child(2) { animation-delay: .05s; } .tile:nth-child(3) { animation-delay: .1s; } .tile:nth-child(4) { animation-delay: .15s; } .tile:nth-child(5) { animation-delay: .2s; } .tile:nth-child(6) { animation-delay: .25s; } .tile:nth-child(7) { animation-delay: .3s; }
@keyframes card-in { from { transform: translateY(4vh) scale(.92); opacity: 0; } }
.tile .art { position: absolute; top: 0; right: 0; bottom: 0; left: 0; background: center / cover no-repeat var(--tc); transform-origin: 50% 60%; }
.tile .art::after { content: ''; position: absolute; top: 0; right: 0; bottom: 0; left: 0; background: linear-gradient(180deg, rgba(0,0,0,0) 55%, rgba(8,20,40,.6) 100%); }
.tile .shine { position: absolute; top: 0; right: 0; bottom: 0; left: 0; background: linear-gradient(105deg, transparent 30%, rgba(255,255,255,.45) 45%, transparent 60%); transform: translateX(-120%); pointer-events: none; }
.tile .head { position: absolute; left: 0; right: 0; top: 0; display: flex; align-items: center; gap: 1vh; padding: 1.1vh 1.2vh 1.6vh; }
.tile .head::before { content: ''; position: absolute; top: 0; right: 0; bottom: 0; left: 0; background: var(--tc); opacity: .94; -webkit-mask-image: linear-gradient(90deg, #000 45%, rgba(0,0,0,.55) 75%, transparent 100%); mask-image: linear-gradient(90deg, #000 45%, rgba(0,0,0,.55) 75%, transparent 100%); }
.tile .badge-ic { position: relative; flex: none; width: 6.4vh; height: 6.4vh; border-radius: 50%; background: #fff; display: grid; place-items: center; box-shadow: 0 0 0 .45vh rgba(255,255,255,.55), 0 .4vh 0 rgba(0,0,0,.2); }
.tile .badge-ic svg { width: 4.3vh; height: 4.3vh; }
.tile .t { position: relative; display: grid; line-height: 1.02; min-width: 0; }
.tile .t b { font-family: var(--display); font-weight: 400; font-size: 3.5vh; -webkit-text-stroke: .28vh rgba(10,30,60,.55); paint-order: stroke fill; }
.tile .t small { font-weight: 800; font-size: 1.65vh; text-shadow: 0 .2vh 0 rgba(0,0,0,.25); white-space: nowrap; }
.tile .count { position: relative; margin-left: auto; align-self: flex-start; display: flex; align-items: center; gap: .5vh; background: rgba(10,30,60,.55); padding: .5vh 1.1vh; border-radius: 99px; font-weight: 800; font-size: 1.8vh; white-space: nowrap; }
.tile .count svg { width: 2vh; height: 2vh; }
.tile .hints { position: absolute; left: 0; right: 0; bottom: 1vh; display: flex; justify-content: center; gap: 1.6vh; font-weight: 800; font-size: 1.6vh; text-shadow: 0 .2vh .4vh rgba(0,0,0,.5); }
.tile .hints span { display: flex; align-items: center; gap: .5vh; }
.tile .hints svg { width: 2.4vh; height: 2.4vh; filter: drop-shadow(0 .2vh .2vh rgba(0,0,0,.4)); }
.tile .go { position: absolute; right: 1.2vh; bottom: 4.4vh; font-family: var(--display); font-size: 2.2vh; background: #fff; color: var(--ink); padding: .8vh 1.8vh; border-radius: 99px; box-shadow: 0 .5vh 0 rgba(0,0,0,.25); opacity: 0; transform: scale(.6); transition: opacity .2s, transform .3s cubic-bezier(.2,1.8,.4,1); }
.cards.picked .tile:not(.on) { filter: saturate(.7) brightness(.82); transform: scale(.97); }
.tile.on { z-index: 2; transform: translateY(-1vh) scale(1.045); box-shadow: 0 0 0 .6vh #fff, 0 0 0 1.2vh var(--tc), 0 2vh 5vh rgba(10,40,90,.5); }
.tile.on .art { animation: kenburns 9s ease-in-out infinite alternate; will-change: transform; }
.tile.on .shine { animation: shine 2.8s ease-in-out infinite; }
.tile.on .go { opacity: 1; transform: scale(1); animation: go-pulse 1.2s ease-in-out infinite; }
@keyframes kenburns { from { transform: scale(1.02); } to { transform: scale(1.12) translate(-1.5%, -1%); } }
@keyframes shine { 0% { transform: translateX(-120%); } 45%, 100% { transform: translateX(120%); } }
@keyframes go-pulse { 50% { transform: scale(1.08); } }
.tile:not(.on):hover { transform: translateY(-.6vh); }

/* ---- the scan card */
.join-card { position: relative; z-index: 1; border-radius: 2.4vh; background: linear-gradient(160deg, #ffffff 0%, #eaf6ff 100%); color: var(--ink); box-shadow: 0 0 0 .45vh rgba(255,255,255,.9), 0 1.2vh 2.4vh rgba(10,40,90,.35); display: grid; grid-template-columns: auto 1fr; align-items: center; gap: 1.6vh; padding: 1.8vh 2vh; animation: card-in .6s .35s cubic-bezier(.2,1.4,.4,1) both; overflow: hidden; }
.join-card::before { content: ''; position: absolute; right: -6vh; top: -6vh; width: 20vh; height: 20vh; border-radius: 50%; background: radial-gradient(circle, rgba(255,197,61,.35), rgba(255,197,61,0) 70%); }
.join-card .qr-box { width: 21vh; height: 21vh; border-radius: 1.6vh; background: #fff; box-shadow: 0 0 0 .5vh #1a4f9a; display: grid; place-items: center; overflow: hidden; position: relative; }
.join-card .qr-box img { width: 100%; height: 100%; image-rendering: pixelated; }
.join-card .qr-box img:not([src]) { display: none; }
.join-card .join-copy { position: relative; display: grid; gap: .6vh; justify-items: start; }
.join-card .join-copy b { font-family: var(--display); font-weight: 400; font-size: 3.6vh; line-height: 1; color: #1a4f9a; }
.join-card .join-copy span { font-family: var(--display); font-size: 3.2vh; letter-spacing: .22em; color: var(--ink); background: #ffc53d; padding: .2vh 1.2vh; border-radius: 1vh; box-shadow: 0 .4vh 0 rgba(0,0,0,.15); }
.join-card .join-copy p { margin: 0; font-weight: 800; font-size: 1.7vh; color: #4a6078; line-height: 1.25; }
.join-card .join-copy small { font-size: 1.3vh; font-weight: 700; color: #7b8ea3; word-break: break-all; }
.join-card .phone-wave { position: absolute; right: 1.6vh; bottom: 1.4vh; font-size: 4vh; animation: wave 1.8s ease-in-out infinite; transform-origin: 70% 90%; }
@keyframes wave { 0%, 60%, 100% { transform: rotate(0); } 15% { transform: rotate(-18deg); } 30% { transform: rotate(14deg); } 45% { transform: rotate(-8deg); } }
.hub .play-hidden { position: absolute; width: 1px; height: 1px; overflow: hidden; opacity: 0; pointer-events: none; }
/* override the old tile rules from tv.css */
.hub .tile { width: auto; height: auto; display: block; place-items: normal; grid-template-rows: none; background: var(--tc, #5aa); }
.hub .tile span { font-family: var(--body); font-size: inherit; letter-spacing: 0; }
.hub .tile svg { width: auto; height: auto; }
.hub .tile .badge-ic svg { width: 4.3vh; height: 4.3vh; }
.hub .tile .count svg { width: 2vh; height: 2vh; }
.hub .tile .hints svg { width: 2.4vh; height: 2.4vh; }
.hub .tile.on { transform: translateY(-1vh) scale(1.045); }
.join-card .qr-box { width: 18vh; height: 18vh; }
.join-card .join-copy b { font-size: 3vh; }

/* ---- versus intro: portrait cards slam in */
.intro { background: radial-gradient(90% 70% at 50% 55%, rgba(10,30,60,0) 30%, rgba(10,30,60,.55) 100%); }
.intro-players { margin-top: 3.6vh; gap: 2.6vw; }
.intro-player { display: grid; justify-items: center; gap: .6vh; background: none; box-shadow: none; border: 0; padding: 0; color: #fff; }
.intro-player .intro-face { width: 17vh; height: 17vh; border-radius: 50%; background: var(--pc) center 30% / cover no-repeat; border: .8vh solid #fff; box-shadow: 0 0 0 .8vh var(--pc), 0 1.4vh 3vh rgba(0,0,0,.4); display: grid; place-items: center; font-family: var(--display); font-size: 7vh; font-style: normal; }
.intro-player b { font-family: var(--display); font-weight: 400; font-size: 3.4vh; background: var(--pc); padding: .3vh 2.2vh; border-radius: 99px; box-shadow: 0 .5vh 0 rgba(0,0,0,.3); -webkit-text-stroke: .2vh rgba(0,0,0,.25); paint-order: stroke fill; }
.intro-player small { font-weight: 800; font-size: 1.5vh; letter-spacing: .2em; opacity: .85; }
.intro-vs { font-size: 9vh; color: #ffd166; -webkit-text-stroke: .5vh #7a2e00; paint-order: stroke fill; animation: vs-pop .6s .9s cubic-bezier(.2,2,.4,1) both; }
@keyframes vs-pop { from { transform: scale(3) rotate(-20deg); opacity: 0; } }
/* HUD portraits (UI.setBoard turns colour dots into faces) */
.scoreboard i.face { width: 3.6vh !important; height: 3.6vh !important; border-radius: 50%; background-size: cover !important; background-position: center 30% !important; border: .3vh solid #fff; box-shadow: 0 .3vh 0 rgba(0,0,0,.25); flex: none; }
.scoreboard .sb-row.has-face { grid-template-columns: 3.6vh minmax(15vh, auto) 2vh 5vh 6.6vh; padding-left: .5vh; }
.scoreboard .sb-row i.face { margin: -.3vh 0; }
.scoreboard .ar-row.has-face { grid-template-columns: 3.6vh 1fr auto 5vh; }
/* big-moment callout */
.callout { position: absolute; left: 3vw; bottom: 9vh; display: flex; align-items: center; gap: 1.4vh; padding: 1vh 3vh 1vh 1vh; border-radius: 99px; background: linear-gradient(90deg, var(--pc) 0%, var(--pc) 60%, rgba(0,0,0,0) 100%); box-shadow: 0 1vh 2.4vh rgba(0,0,0,.3); animation: callout-in .45s cubic-bezier(.2,1.6,.4,1) both; z-index: 6; pointer-events: none; }
.callout.out { animation: callout-out .4s ease-in both; }
.callout i { width: 11vh; height: 11vh; border-radius: 50%; border: .7vh solid #fff; background: var(--pc) center 30% / cover no-repeat; box-shadow: 0 .6vh 0 rgba(0,0,0,.25); font-family: var(--display); font-style: normal; font-size: 5vh; color: #fff; display: grid; place-items: center; }
.callout-t { display: grid; line-height: 1; color: #fff; }
.callout-t b { font-family: var(--body); font-weight: 800; font-size: 2.2vh; letter-spacing: .08em; text-transform: uppercase; opacity: .95; }
.callout-t span { font-family: var(--display); font-size: 6vh; -webkit-text-stroke: .35vh rgba(0,0,0,.3); paint-order: stroke fill; filter: drop-shadow(0 .4vh 0 rgba(0,0,0,.25)); }
@keyframes callout-in { from { transform: translateX(-120%) skewX(-10deg); } 70% { transform: translateX(3%) skewX(3deg); } }
@keyframes callout-out { to { transform: translateX(-130%); opacity: 0; } }
.result-name i.face { width: 5vh !important; height: 5vh !important; border-radius: 50%; background-size: cover !important; background-position: center 30% !important; border: .35vh solid #fff; box-shadow: 0 .3vh 0 rgba(0,0,0,.25); }
.scoreboard .ar-dot.face { width: 3.4vh !important; height: 3.4vh !important; border-radius: 50%; background-size: cover !important; background-position: center 30% !important; border: .3vh solid #fff; display: inline-block; }

/* ---- results: side panel so the celebration stays on screen, winner hero, confetti */
.results { place-items: center end !important; padding-right: 4vw; background: linear-gradient(90deg, rgba(10,30,60,0) 35%, rgba(10,30,60,.45) 100%) !important; }
.results-card { position: relative; width: min(46vw, 78vh) !important; padding-top: 10vh !important; overflow: visible !important; animation: results-in .55s cubic-bezier(.2,1.4,.4,1) both; }
@keyframes results-in { from { transform: translateX(30vw) rotate(6deg); opacity: 0; } }
.results-hero { position: absolute; top: -9vh; left: 50%; transform: translateX(-50%); width: 18vh; height: 18vh; border-radius: 50%; border: .9vh solid #fff; box-shadow: 0 0 0 .9vh var(--pc), 0 1.6vh 3vh rgba(0,0,0,.35); background: var(--pc); overflow: hidden; animation: hero-bounce 1.6s .5s ease-in-out infinite; }
.results-hero i { position: absolute; top: 0; right: 0; bottom: 0; left: 0; background: center 30% / cover no-repeat; }
@keyframes hero-bounce { 50% { transform: translateX(-50%) translateY(-1vh) rotate(-3deg); } }
.results-crown { position: absolute; top: -12.5vh; left: 50%; transform: translateX(-50%) rotate(-8deg); font-size: 8vh !important; z-index: 2; }
#results-title { font-size: 5.2vh !important; }
.result-name i.face { width: 6vh !important; height: 6vh !important; }
.confetti { position: fixed; top: 0; right: 0; bottom: 0; left: 0; pointer-events: none; overflow: hidden; z-index: 0; }
.confetti i { position: absolute; top: -4vh; width: 1.1vh; height: 1.8vh; border-radius: .2vh; animation: fall linear infinite; opacity: .95; }
@keyframes fall { to { transform: translateY(110vh) rotate(var(--spin)); } }
.results { backdrop-filter: none !important; -webkit-backdrop-filter: none !important; }
/* 8 sports + the tall scan card: narrower cards — the player count moves under the header, hints tighten */
.cards .tile .count { position: absolute; left: auto; right: 1.1vh; top: 8.6vh; margin: 0; font-size: 1.6vh; padding: .4vh 1vh; }
.cards .tile .t b { font-size: 3.3vh; white-space: nowrap; }
.cards .tile .t small { font-size: 1.5vh; }
.cards .tile .hints { gap: 1.1vh; font-size: 1.45vh; }
.cards .tile .hints svg { width: 2.1vh; height: 2.1vh; }
/* high scores on this TV */
.results-records { display: flex; flex-wrap: wrap; justify-content: center; align-items: center; gap: .8vh 1vh; margin-top: .4vh; }
.results-records .rec-head { width: 100%; text-align: center; font-family: var(--display); font-weight: 400; font-size: 2.6vh; color: #b27a00; letter-spacing: .06em; }
.results-records.fresh .rec-head { font-size: 3.4vh; color: #e08a00; animation: go-pulse 1s ease-in-out infinite; }
.results-records .rec { display: flex; align-items: center; gap: .7vh; background: #eef3f6; border-radius: 99px; padding: .4vh 1.2vh .4vh .4vh; font-weight: 800; font-size: 1.8vh; }
.results-records .rec i { width: 2.8vh; height: 2.8vh; border-radius: 50%; background: var(--pc); color: #fff; display: grid; place-items: center; font-style: normal; font-size: 1.6vh; }
.results-records .rec em { font-style: normal; }
.results-records .rec strong { font-family: var(--display); font-weight: 400; font-size: 2.2vh; }
.results-records .rec.new { background: #fff3c4; box-shadow: 0 0 0 .3vh #ffc53d; }
