/* Player app styles: mirrors core's player app (player_host/player_frontend, Tailwind classes copied as plain CSS: navy page, blue gradient column, white 14px cards, green italic buttons, dashboard pills and cards); club skins (skins v2 theme files) swap in their colours the way core's Leverkusen variant does; plus the SIM layout rules (tablet-portrait column, upright desktop column, "turn upright" overlay on touch devices held sideways). */
:root {
  /* core Default palette */
  --p-page: #001934;
  --p-col-top: #005fc5;
  --p-col-bottom: #00142a;
  --p-card: #ffffff;
  --p-media-frame-bg: #000000; /* the area around a sponsor / Grand Prize picture that doesn't fill the middle frame */
  --p-card-shadow: 0 0 21px #001934;
  --p-title: #004590;
  --p-title-style: italic;
  --p-btn: #31cb8b;
  --p-btn-text: #ffffff;
  --p-btn-glow: 0 0 21px #2dffa7;
  --p-btn-style: italic;
  --p-btn-size: 20px;
  --p-btn-off: #9ca3af;
  --p-outline: #6ec1e4;
  --p-option: #eaeaea;
  --p-option-text: #004590;
  --p-select: #31cb8b;
  --p-soft: #abcff5;
  --p-icon: #6ec1e4;
  --p-pill: rgba(255, 255, 255, 0.15);
  --p-prize-bg: rgba(255, 255, 255, 0.15);
  --p-foot-bg: rgba(255, 255, 255, 0.2);
  --p-foot-text: rgba(175, 199, 209, 0.6);
  --p-font: system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  --p-font-head: var(--p-font);
  --p-col: 378px;
  --p-dash: 424px;
  /* button of a picture, text and button banner: blue in the default skin (same fill as the planned default blue buttons, --p-btn-fill when that lands) */
  --p-cta-fill: var(--ds-btn-fade, linear-gradient(#4CC5F7, #0098D7));
  --p-cta-text: #ffffff;
  --p-cta-glow: 0 0 12px #7FDBFF;
}
/* Club skins (core's Leverkusen variant: red-to-black page, black titles, solid accent buttons, no glow), colours from the theme file. */
html[data-skin-club] {
  --p-page: var(--ds-bg, #000);
  --p-col-top: var(--ds-accent-press, #bd0000);
  --p-col-bottom: var(--ds-bg, #000);
  --p-title: #000000;
  --p-title-style: normal;
  --p-btn: var(--ds-accent-strong, #ff0000);
  --p-btn-text: var(--ds-on-accent, #fff);
  --p-btn-glow: none;
  --p-btn-style: normal;
  --p-btn-size: 16px;
  --p-btn-off: #c2c2c2;
  --p-cta-fill: var(--p-btn);
  --p-cta-text: var(--p-btn-text);
  --p-cta-glow: none;
  --p-outline: var(--ds-accent-strong, #ff0000);
  --p-option-text: var(--ds-accent-press, #d00217);
  --p-select: var(--ds-accent-strong, #ff0000);
  --p-soft: rgba(255, 255, 255, 0.5);
  --p-icon: rgba(255, 255, 255, 0.5);
  --p-prize-bg: rgba(0, 0, 0, 0.5);
  --p-font: var(--ds-font, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif);
  --p-font-head: var(--ds-font-head, var(--p-font));
}
* { box-sizing: border-box; }
[hidden] { display: none !important; }
html, body { margin: 0; min-height: 100%; background: var(--p-page); color: #fff; font-family: var(--p-font); -webkit-tap-highlight-color: transparent; -webkit-text-size-adjust: 100%; }
html[data-skin-club] body { background: linear-gradient(to bottom, var(--p-col-top), var(--p-col-bottom)) fixed; }
button { font-family: inherit; }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

/* ---------- card pages (core: flex h-dvh centred; column sm:max-w-[378px] p-6 with blue gradient) ---------- */
.page { min-height: 100vh; display: flex; justify-content: center; align-items: center; }
@supports (height: 100dvh) { .page { min-height: 100dvh; } }
.col {
  width: 100%;
  max-width: var(--p-col);
  padding: max(24px, env(safe-area-inset-top)) max(24px, env(safe-area-inset-right)) max(16px, env(safe-area-inset-bottom)) max(24px, env(safe-area-inset-left));
}
@media (min-width: 640px) { .col { background: linear-gradient(to bottom, var(--p-col-top), var(--p-col-bottom)); } }
.screen.center { display: flex; justify-content: center; align-items: center; min-height: 60vh; }
.card {
  background: var(--p-card);
  border-radius: 14px;
  padding: 20px 16px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  box-shadow: var(--p-card-shadow);
  color: var(--p-title);
}
.logo { width: 180px; height: auto; }
.logo.mb { margin-bottom: 16px; }
.crest { display: none; width: 50px; height: 50px; background: var(--ds-crest, none) center / contain no-repeat; }
.crest.small { width: 50px; height: 50px; }
html[data-skin-club] .crest { display: block; }
html[data-skin-club] .logo { display: none; }
.hero { width: 200px; max-width: 70%; height: auto; }
.card-txt { text-align: center; display: flex; flex-direction: column; gap: 8px; }
.card-title { margin: 0; padding: 0 8px; font: 700 22px/26px var(--p-font-head); font-style: var(--p-title-style); text-transform: uppercase; color: var(--p-title); overflow-wrap: anywhere; }
.card-p { margin: 0; padding: 0 8px; font-size: 14px; line-height: 16px; color: var(--p-title); }
.card-p.small { font-size: 12px; line-height: 15px; opacity: 0.85; }
.btns { display: flex; flex-direction: column; gap: 16px; width: 100%; margin-top: 12px; }
.powered { margin: 14px 0 0; text-align: center; color: rgba(255, 255, 255, 0.7); font-size: 12px; font-weight: 600; }
.error { margin: 4px 0 0; width: 100%; padding: 8px 10px; border-radius: 9px; background: #fde2e2; color: #b91c1c; font-size: 14px; text-align: center; }

/* buttons (core: py-2 rounded-[9px] uppercase bold italic 20px, green with glow / 4px outline) */
.btn { display: flex; align-items: center; justify-content: center; width: 100%; min-height: 44px; padding: 8px 12px; border-radius: 9px; border: 0; font: 700 var(--p-btn-size)/1.5 var(--p-font); font-style: var(--p-btn-style); text-transform: uppercase; cursor: pointer; }
.btn.primary { background: var(--p-btn); color: var(--p-btn-text); box-shadow: var(--p-btn-glow); }
.btn.primary:disabled { background: var(--p-btn-off); box-shadow: none; cursor: not-allowed; }
.btn.outline { background: transparent; border: 4px solid var(--p-outline); color: var(--p-outline); }
html[data-skin-club] .btn.outline { color: #000; }
.btn.big { padding: 16px 12px; font-size: calc(var(--p-btn-size) + 4px); margin-top: 16px; }
html[data-skin-club] .btn.big { font-size: 20px; }
.link { background: none; border: 0; margin-top: 10px; padding: 6px; color: var(--p-title); font: 600 14px var(--p-font); text-decoration: underline; cursor: pointer; opacity: 0.8; }
.btn:focus-visible, .link:focus-visible, .option:focus-visible, .icon-btn:focus-visible, .foot-item:focus-visible { outline: 3px solid #fde047; outline-offset: 2px; }

/* ---------- dashboard (core Dashboard.tsx: column max-w-[424px] min-h-dvh, py-3 px-3 gap-[8.6px]) ---------- */
.dash-page { align-items: stretch; }
@media (min-width: 640px) { .dash-page { padding: 0 16px; align-items: center; } }
.dash {
  width: 100%;
  max-width: var(--p-dash);
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  background: linear-gradient(to bottom, var(--p-col-top), var(--p-col-bottom));
  position: relative;
}
@supports (height: 100dvh) { .dash { min-height: 100dvh; } }
.dash-body { display: flex; flex-direction: column; gap: 8.6px; padding: max(12px, env(safe-area-inset-top)) 12px 12px; }
.dash-top { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.dash-tools { display: flex; align-items: center; flex: none; gap: 4px; }
/* Team row (Micha 23 Oct 18:43): the old "Team:" pill is now the first team strip (shared/team-strip.js look) with the pencil at its end. Share, then Settings, sit on the right. */
.dsp-strip.team-row { flex: 1; min-width: 0; pointer-events: auto; padding: 2px 2px 2px 10px; gap: 5px; }
.team-row .dsp-strip-name { flex: 0 100 auto; } /* the name gives way first, the place + points only once the name is at its minimum */
.team-row-stats { display: flex; align-items: center; gap: 5px; flex: 0 0 auto; min-width: 0; max-width: calc(100% - 59px - 2.5em); overflow: hidden; } /* place + points keep their full width (a sub-pixel shrink would cut "2. Platz" to "2. Pl…"): the name gives way first; only once it is at its 2.5em minimum (59px = swatch + pencil + gaps) does the place, then the points, shorten with an ellipsis */
.team-row-stats > span { flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.team-row-stats .dsp-strip-rank { flex-shrink: 50; } /* the place gives way before the fan's points */
@media (max-width: 339px) { .dsp-strip.team-row { font-size: 11px; } } /* very narrow phones (320 px): slightly smaller text so place + points still fit */
.team-row-stats:empty { display: none; }
.team-row .icon-btn { margin-left: auto; }
.icon-btn { position: relative; flex: none; display: grid; place-items: center; min-width: 32px; min-height: 32px; padding: 4px; background: none; border: 0; cursor: pointer; }
.icon-btn::after { content: ""; position: absolute; inset: -6px; } /* 44 px hit area, same look (deep test XC tap targets) */
.icon-btn svg { width: 18px; height: 18px; fill: none; stroke: rgba(255, 255, 255, 0.5); stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.icon-btn.share svg { width: 24px; height: 24px; stroke: #fff; }
/* Settings (Micha 24 Oct): same top row as Share, immediately to its right. Gear + the word, white on the style background. */
.icon-btn.settings { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 0; min-width: 44px; min-height: 44px; padding: 2px 4px; color: #fff; font: 600 10px/1.15 var(--p-font); }
.icon-btn.settings svg { width: 20px; height: 20px; stroke: #fff; }
.icon-btn.settings span { white-space: nowrap; }
.icon-btn.settings::after { inset: -2px; }
.icon-btn.dark svg { width: 26px; height: 26px; stroke: var(--p-outline); }
/* Team lock: Change team greyed out once the event's first game has started (aria-disabled, still tappable). The note under the top row shows on that tap and hides with the toast. */
.icon-btn.locked { opacity: 0.35; cursor: not-allowed; }
.team-lock-note { margin: 0; padding: 0 4px; color: var(--p-soft); font-size: 12px; line-height: 16px; text-align: center; }
/* Event title (Micha 24 Oct, t1073u): the arena photo / title frame is gone. In its place, a bar with the same
   shape as the Main "Sponsored by" strip (.wait-sponsor: 48 px, 10 px radius, club card radius) and the same
   fill as that strip's DynamicStadiums panel (#wait-sponsor[data-kind=logo]). Only the event title, centered. */
.arena { position: relative; width: 100%; background: transparent; background-image: none; }
.arena-name { display: block; box-sizing: border-box; width: 100%; height: 48px; margin: 0; padding: 0 40px; border-radius: 10px; background: rgba(0, 20, 42, 0.88); color: #fff; text-align: center; font: 800 18px/48px var(--p-font-head); text-transform: uppercase; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
html[data-skin-club] .arena-name { border-radius: var(--p-r-card, 10px); }
/* Band chip is absolutely placed at the bottom-left of this header. Reserve a row under the bar so it does not cover the title. */
.arena:has(.band-chip:not([hidden])) { padding-bottom: 44px; }
/* Middle sponsor card (where core's Dashboard.tsx had its fixed sponsor picture, 650x405): the games' "Sponsored by" + DS logo block (shared/waiting.js) on the games' stadium photo.
   Event sponsors rotate inside this card (player.js spinSponsors). It stays on screen and keeps this size, which is larger than the banner slot (.banners is 68px). */
.sponsor { position: relative; overflow: hidden; width: 100%; aspect-ratio: 650 / 405; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 12px; padding: 12px; border-radius: 6px; background: #00142a url("./assets/stadium_bg.png") center 40% / cover no-repeat; color: #fff; text-align: center; }
.sponsor::before { content: ""; position: absolute; inset: 0; background: rgba(0, 0, 0, 0.45); }
.sponsor > * { position: relative; margin: 0; }
.sponsor [hidden] { display: none; }
.sponsor-logo { display: block; width: 12rem; max-width: 70%; height: auto; filter: drop-shadow(0 2px 6px rgba(0, 0, 0, 0.6)); }
.sponsor-name { max-width: 100%; overflow-wrap: anywhere; font: 800 34px/1.1 var(--p-font-head); text-transform: uppercase; filter: drop-shadow(0 2px 6px rgba(0, 0, 0, 0.6)); }
/* Faces of the middle card (mid-rotator.js): stacked in the card's fixed 650:405 box, so swapping never changes the layout. The Grand Prize face is opaque and
   fades its opacity over the sponsor face = a cross-fade of the two pictures (0.9 s, FADE_MS); prefers-reduced-motion switches without the fade. */
.sponsor > .mid-face { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 12px; padding: 12px; }
/* Event sponsor picture (Micha 25 Oct): no "Sponsored by" heading (sponsors put it in their graphic); the whole picture, centred, not stretched, on the media frame colour */
.sponsor-img { display: block; width: 100%; height: 100%; min-height: 0; object-fit: contain; object-position: center; }
.sponsor > .sponsor-face:has(> .sponsor-img:not([hidden])) { padding: 0; background: var(--p-media-frame-bg, #000); }
.sponsor > .gp-face { padding: 0; background: var(--p-media-frame-bg, #000); color: var(--p-title); opacity: 0; transition: opacity 0.9s ease-in-out; pointer-events: none; }
.sponsor[data-mid=gp] > .gp-face { opacity: 1; pointer-events: auto; }
.gp-img { display: block; width: 100%; height: 100%; object-fit: contain; }
.gp-card { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px; width: 100%; height: 100%; padding: 16px; text-align: center; background: linear-gradient(160deg, var(--p-col-top), var(--p-col-bottom)); color: #fff; }
.gp-star { font-size: 34px; line-height: 1; color: var(--p-btn); filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.5)); }
.gp-cap { margin: 0; font: 900 18px/1.3 var(--p-font); text-transform: uppercase; letter-spacing: 0.2em; }
.gp-name { margin: 0; max-width: 100%; overflow-wrap: anywhere; font: 800 30px/1.1 var(--p-font-head); text-transform: uppercase; filter: drop-shadow(0 2px 6px rgba(0, 0, 0, 0.5)); }
.gp-tag { position: absolute; top: 8px; left: 8px; padding: 3px 8px; border-radius: 999px; background: var(--p-btn); color: var(--p-btn-text); font: 800 11px/1.3 var(--p-font); text-transform: uppercase; letter-spacing: 0.08em; }
.sponsor[data-gp=card] .gp-tag { display: none; }
@media (prefers-reduced-motion: reduce) { .sponsor > .gp-face { transition: none; } }
/* prize sponsor (Manager step 5, per prize): small "Sponsored by <name>" + graphic on the chosen-prize card */
.prize-sponsor { display: flex; align-items: center; gap: 6px; margin: 4px 0 0; font-size: 12px; opacity: 0.9; }
.prize-sponsor[hidden] { display: none; }
.prize-sponsor span { min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.prize-sponsor img { display: block; flex: none; height: 20px; max-width: 96px; width: auto; object-fit: contain; border-radius: 3px; }
.prize-sponsor img[hidden] { display: none; }
/* Banner strips under the sponsor card (same surface as the prize card, so each strip follows the skin).
   Banners that take turns share one strip: fixed height, cross-fade (player.js rotate()). A stacked banner is its own strip and stays on screen. */
.banners { display: flex; flex-direction: column; gap: 6px; color: #fff; }
.bstrip { position: relative; flex: none; height: 68px; border-radius: 10px; overflow: hidden; background: var(--p-prize-bg); }
.banner { position: absolute; inset: 0; display: flex; align-items: center; gap: 12px; padding: 8px 16px; opacity: 0; transition: opacity 0.6s ease; }
.banner.on { opacity: 1; }
.banners.instant .banner { transition: none; }
.banner .bpic { flex: 1 1 auto; min-width: 0; height: 100%; display: flex; align-items: center; justify-content: center; }
.banner.has-caption .bpic { flex: 0 1 44%; justify-content: flex-start; }
.banner .bpic img { display: block; max-width: 100%; max-height: 100%; object-fit: contain; }
.banner .btxt { flex: 1 1 auto; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-weight: 700; font-size: 15px; line-height: 1.3; } /* one clear line; the full text is the card's title */
.banner .bcap { flex: 1 1 0; min-width: 0; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; font-weight: 700; font-size: 14px; line-height: 1.3; } /* caption next to the picture: up to 2 lines */
.banner .bmark { flex: none; width: 4px; align-self: stretch; margin: 6px 0; border-radius: 2px; background: var(--p-select); }
/* picture, text and button banner: picture left, text and the skin's button right; that strip is taller while one is in it */
.bstrip.has-cta, .bstrip.has-poll { height: 124px; }
.banner.kind-cta { display: grid; grid-template-columns: minmax(0, 40%) minmax(0, 1fr); grid-template-rows: minmax(0, 1fr) auto; gap: 6px 12px; padding: 8px 12px 10px; }
.banner.kind-cta:not(.on) { pointer-events: none; }
.banner.kind-cta .bpic { grid-row: 1 / span 2; justify-content: center; }
.banner.kind-cta .bcap { -webkit-line-clamp: 3; align-self: center; font-size: 14px; line-height: 1.25; overflow-wrap: anywhere; }
.banner .bbtn { display: flex; align-items: center; justify-content: center; min-height: 44px; min-width: 0; padding: 2px 8px; border-radius: 9px; background: var(--p-btn-fill, var(--p-cta-fill)); color: var(--p-cta-text); box-shadow: var(--p-cta-glow);
  font: 700 14px/1.15 var(--p-font); font-style: var(--p-btn-style); text-transform: uppercase; text-decoration: none; text-align: center; overflow-wrap: anywhere; overflow: hidden; } /* a long button text wraps to a second line on narrow phones instead of being cut */
.banner .bbtn:focus-visible { outline: 3px solid #fff; outline-offset: 2px; }
.bstrip.has-cta .bdots, .bstrip.has-poll .bdots { bottom: 2px; right: 50%; transform: translateX(50%); }
/* Poll: picture, question, two checks. The tick and cross stay the fixed signal colours; the squares are white. */
.banner.kind-poll { display: grid; grid-template-columns: minmax(0, 40%) minmax(0, 1fr); grid-template-rows: minmax(0, 1fr) auto; gap: 6px 12px; padding: 8px 12px 10px; }
.banner.kind-poll:not(.on) { pointer-events: none; }
.banner.kind-poll .bpic { grid-row: 1 / span 2; justify-content: center; }
.banner.kind-poll .bcap { -webkit-line-clamp: 3; align-self: center; font-size: 14px; line-height: 1.25; overflow-wrap: anywhere; }
.bpoll { display: flex; gap: 8px; align-items: center; }
.bcheck { width: 44px; height: 44px; border: 0; border-radius: 8px; background: #fff; padding: 0; display: inline-flex; flex-direction: column; align-items: center; justify-content: center; font: 800 22px/1 var(--p-font); cursor: pointer; }
.bcheck.yes { color: #22c55e; }
.bcheck.no { color: #ef4444; }
.bcheck.on { box-shadow: inset 0 0 0 3px currentColor; }
.bcheck .bpct { font: 700 10px/1 var(--p-font); }
.bcheck:focus-visible { outline: 3px solid #fff; outline-offset: 2px; }
.bcheck:disabled { cursor: default; }
.bdots { position: absolute; right: 10px; bottom: 6px; display: flex; gap: 4px; }
.bdots i { width: 5px; height: 5px; border-radius: 50%; background: rgba(255, 255, 255, 0.35); }
.bdots i.on { background: #fff; }
@media (prefers-reduced-motion: reduce) { .banner { transition: none; } }
.prize-card { margin-top: 4px; background: var(--p-prize-bg); border-radius: 10px; padding: 12px 16px; }
.prize-head { display: flex; justify-content: space-between; align-items: center; gap: 12px; }
.prize-cap { margin: 0; font-size: 16px; font-weight: 700; text-transform: uppercase; color: #fff; }
.prize-row { display: flex; justify-content: space-between; align-items: center; gap: 12px; margin-top: 12px; }
.prize-l { display: flex; align-items: center; gap: 20px; min-width: 0; }
.prize-pic { flex: none; width: 70px; height: 70px; border-radius: 50%; background: #fff; display: grid; place-items: center; overflow: hidden; color: var(--p-title); font: 800 24px var(--p-font-head); }
.prize-pic img { width: 100%; height: 100%; object-fit: cover; }
.prize-name { margin: 0 0 2px; color: #fff; font-weight: 700; font-size: 14px; text-transform: uppercase; overflow-wrap: anywhere; }
.prize-name:empty { display: none; }
.prize-points { margin: 0; color: var(--p-soft); font-size: 18px; font-weight: 400; font-variant-numeric: tabular-nums; }
html[data-skin-club] .prize-points { color: #fff; }
.prize-points b { font-weight: 700; }
.prize-unit { display: block; font-size: 13px; line-height: 1.25; hyphens: auto; overflow-wrap: break-word; } /* "Prize points" under the numbers (Micha 23 Oct 18:43) */
.btn.claim { width: auto; flex: none; font: 700 18px var(--p-font); font-style: normal; border-radius: 12px; padding: 12px 20px; margin-top: 12px; background: var(--p-btn); color: #fff; border: 0; }
.btn.claim:disabled { background: transparent; color: var(--p-outline); border: 4px solid var(--p-outline); padding: 8px 16px; cursor: default; }
html[data-skin-club] .btn.claim:disabled { color: #4a4a4a; border-color: #282828; background: #282828; }
.bar { margin-top: 10px; height: 6px; border-radius: 999px; background: rgba(255, 255, 255, 0.15); overflow: hidden; }
.bar i { display: block; height: 100%; width: 0; background: var(--p-btn); border-radius: inherit; transition: width 0.6s ease; }
.prize-card.none .bar, .prize-card.none .btn.claim { display: none; }
/* voucher lottery (Micha 23 Oct): draw state line, notifications nudge, pick button, winner's Claim, greyed-out drawn prizes in the picker */
.prize-state { margin: 10px 0 0; font-size: 16px; font-weight: 700; color: inherit; }
.prize-state[data-state="won"] { color: var(--p-btn); font-size: 18px; }
.prize-state[data-state="not_won"], .prize-state[data-state="closed"], .prize-state[data-state="no_pick"] { opacity: 0.8; font-weight: 400; }
.prize-nudge { display: block; margin-top: 6px; font-size: 14px; text-align: left; }
.prize-pick { margin-top: 12px; }
.btn.claim.won { box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.35); }
.option.prize.drawn { opacity: 0.45; cursor: not-allowed; filter: grayscale(1); }
.toast { margin: 0; padding: 10px 12px; border-radius: 10px; background: rgba(0, 0, 0, 0.45); color: #fff; font-size: 14px; text-align: center; }
/* Waiting / ended line (Micha 23 Oct 18:43): core's VT323 white uppercase marquee look, but fixed and centred (no scrolling); one line that fits 360 px, the font steps down with the screen width */
.wait-line { width: 100%; box-sizing: border-box; padding: 4px 12px; text-align: center; }
.wait-line-txt { display: block; font: 400 min(24px, 6.4vw)/1.2 'VT323', ui-monospace, 'SFMono-Regular', Menlo, monospace; color: #fff; text-transform: uppercase; white-space: normal; overflow-wrap: anywhere; text-wrap: balance; }
.wait-line.ended .wait-line-txt { white-space: normal; font-size: 20px; }
.keep-open { margin: 2px 0 0; font: 500 14px/1.3 system-ui, sans-serif; color: rgba(255,255,255,.75); text-align: center; }
.keep-open[hidden] { display: none; }
.dash-foot { background: var(--p-foot-bg); display: flex; align-items: center; justify-content: flex-end; gap: 8px; padding: 12px 16px max(12px, env(safe-area-inset-bottom)); }
/* Core #68 (iPhone 8 and iPhone 16 Pro): the Powered-by line sits at the bottom of the screen on tall phones (no empty band under it)
   and stays on screen when Main is taller than a small phone. Settings is in the top row, right of Share. */
.dash-foot { margin-top: auto; position: sticky; bottom: 0; z-index: 5; }
.foot-item { display: flex; flex-direction: column; align-items: center; gap: 4px; background: none; border: 0; color: var(--p-foot-text); font-size: 12px; line-height: 16px; cursor: pointer; min-width: 44px; min-height: 44px; justify-content: center; }
.foot-item svg { width: 16px; height: 16px; fill: none; stroke: #fff; stroke-width: 2; }
.foot-powered { margin: 0; color: var(--p-foot-text); font-size: 12px; font-weight: 600; text-align: right; }

/* ---------- dialogs (core: fixed inset-0, panel w-full max-w-sm rounded-xl bg-white p-6) ---------- */
.modal { position: fixed; inset: 0; z-index: 20; overflow-y: auto; display: flex; align-items: center; justify-content: center; padding: 16px; background: rgba(0, 0, 0, 0.4); }
/* Claim is centred when it fits. safe falls back to start when the card is taller than a short phone, so Close stays reachable instead of being clipped off the bottom. */
#claim-modal { align-items: safe center; }
/* Countdown / "Game starting soon" (Micha 26 Oct 2026 00:41): a fully opaque full-screen backdrop, so nothing of the main screen (the top
   Sponsored by / Grand Prize card, the side cards, the footer, band notices) peeks out around or above the card. The card itself is unchanged. */
#countdown-modal { z-index: 45; background: var(--p-page); }
.panel { width: 100%; max-width: 384px; background: #fff; border-radius: 12px; padding: 24px; color: var(--p-title); display: flex; flex-direction: column; align-items: stretch; text-align: center; }
.panel .crest { align-self: center; margin-bottom: 16px; }
.panel-title { margin: 4px 0 24px; font: 700 20px/28px var(--p-font-head); font-style: var(--p-title-style); text-transform: uppercase; color: var(--p-title); }
.panel-p { margin: 0 0 12px; font-size: 18px; font-weight: 500; color: var(--p-title); }
.panel-p.small { font-size: 16px; margin: 12px 0 4px; }
.panel-note { margin: 12px 0 0; font-size: 13px; opacity: 0.75; }
.options { display: flex; flex-direction: column; gap: 12px; }
.option { width: 100%; background: var(--p-option); border: 4px solid transparent; border-radius: 24px; padding: 16px; cursor: pointer; display: flex; align-items: center; justify-content: center; gap: 24px; text-align: center; color: var(--p-option-text); }
.option[aria-checked="true"] { border: 6px solid var(--p-select); background: #fff; padding: 14px; }
.option .oname { font: 700 24px/1.2 var(--p-font-head); color: var(--p-option-text); overflow-wrap: anywhere; }
html[data-skin-club] .option .oname { font-size: 20px; text-transform: uppercase; }
.option.prize .oname { font-size: 18px; text-transform: uppercase; }
.option .osub { display: block; font-size: 13px; font-weight: 600; opacity: 0.75; margin-top: 2px; text-transform: none; }
.option img { max-width: 56px; max-height: 56px; }
/* Share window (core QRcode.tsx: max-w-96 white panel, 2xl title, xl text, 152 px QR, copy link + icon, "Copied!", 4px outline Close). Colours only from the panel's own text colour (--p-title) so every skin stays readable; the QR always sits on white with a quiet zone so it scans; safe-area insets; short landscape screens get QR left, text right. */
.share-modal { align-items: flex-start; padding: max(16px, env(safe-area-inset-top)) max(16px, env(safe-area-inset-right)) max(16px, env(safe-area-inset-bottom)) max(16px, env(safe-area-inset-left)); }
.share-panel { margin: auto; }
.share-panel .panel-title { margin-bottom: 12px; font-size: 24px; line-height: 30px; }
.share-panel .panel-p { margin: 0; font-size: 18px; line-height: 24px; }
.share-panel :focus-visible { outline: 3px solid var(--p-title); outline-offset: 2px; }
.qr-box { align-self: center; display: grid; place-items: center; width: 176px; min-height: 176px; margin: 16px auto 0; padding: 12px; background: #fff; border-radius: 8px; box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.12); }
.qr { display: block; width: 152px; height: 152px; image-rendering: pixelated; }
.share-modal[data-qr='loading'] .qr { visibility: hidden; }
.qr-fail { margin: 0; color: #111; font-size: 14px; line-height: 18px; text-align: center; }
/* Facebook / WhatsApp / Picture row (core: 32 px icons in a row under the QR); outline circles in the panel's text colour, label under each, 44 px+ targets. */
.share-apps { display: flex; justify-content: center; gap: 12px; margin-top: 16px; }
.share-app { display: flex; flex-direction: column; align-items: center; gap: 4px; min-width: 76px; min-height: 44px; padding: 4px 2px; background: none; border: 0; border-radius: 10px; color: var(--p-title); font: 700 13px/1.2 var(--p-font); text-decoration: none; cursor: pointer; }
.share-app svg { width: 48px; height: 48px; padding: 10px; border: 2px solid var(--p-title); border-radius: 50%; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; box-sizing: border-box; }
.share-app:active svg { background: color-mix(in srgb, var(--p-title) 12%, transparent); }
.share-status { margin: 8px 0 0; color: var(--p-title); font-size: 15px; font-weight: 700; }
.btn.share-native { display: inline-flex; align-items: center; justify-content: center; gap: 8px; width: auto; align-self: center; min-height: 44px; margin-top: 16px; padding: 8px 20px; border: 2px solid var(--p-title); border-radius: 999px; background: transparent; color: var(--p-title); font: 700 16px/1.2 var(--p-font); font-style: normal; text-transform: none; }
.btn.share-native[hidden] { display: none; }
.share-native svg, .copy-row svg { flex: none; width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.share-panel .share-cap { margin-top: 16px; font-size: 16px; }
.copy-row { display: flex; align-items: center; justify-content: center; gap: 10px; min-height: 44px; width: 100%; margin-top: 4px; padding: 6px 8px; background: none; border: 0; border-radius: 8px; color: var(--p-title); cursor: pointer; font: inherit; }
.copy-link { min-width: 0; font-size: 15px; font-weight: 700; text-decoration: underline; overflow-wrap: anywhere; color: var(--p-title); }
.copied { margin: 4px 0 0; color: var(--p-title); font-size: 15px; font-weight: 700; }
.copied::before { content: '\2713\00a0'; color: inherit; }
.btn.share-close, html[data-skin-club] .btn.share-close { margin-top: 20px; border-radius: 12px; }
html:not([data-skin-club]) .btn.share-close { color: var(--p-title); }
@media (orientation: portrait) and (min-width: 700px) {
  .share-panel .panel-p { font-size: 22px; line-height: 30px; }
  .qr-box { width: 244px; min-height: 244px; } .qr { width: 220px; height: 220px; }
  .copy-link { font-size: 18px; }
  .share-app { min-width: 96px; font-size: 16px; } .share-app svg { width: 60px; height: 60px; padding: 13px; } .share-apps { gap: 20px; }
  .btn.share-native { min-height: 52px; font-size: 20px; } .share-panel .share-cap { font-size: 20px; } .copied { font-size: 18px; }
}
@media (orientation: landscape) and (max-height: 560px) {
  .share-panel { max-width: 640px; display: grid; grid-template-columns: auto 1fr; column-gap: 20px; align-items: center; }
  .share-panel > * { grid-column: 2; }
  .share-panel > .panel-title, .share-panel > .share-close { grid-column: 1 / -1; }
  .share-panel > .qr-box { grid-column: 1; grid-row: 2 / span 7; margin: 0; }
  .share-apps { margin-top: 8px; gap: 8px; }
  .share-app { flex-direction: row; gap: 6px; min-width: 0; padding: 2px 6px; } .share-app svg { width: 40px; height: 40px; padding: 8px; }
  .share-panel .panel-title { margin-bottom: 6px; }
  .share-panel .panel-p { font-size: 16px; line-height: 21px; }
  .btn.share-native { justify-self: center; margin-top: 6px; } .share-panel .share-cap { margin-top: 4px; }
  .btn.share-close { margin-top: 8px; padding: 10px 12px; }
}
.field { display: flex; flex-direction: column; gap: 12px; text-align: left; }
.field-cap { font-size: 18px; font-weight: 600; font-style: var(--p-title-style); }
.field select { font: 16px var(--p-font); padding: 8px; border: 1px solid #d1d5db; border-radius: 8px; color: #111; background: #fff; }
/* core ReadyCountDown: timer circle, label 16px uppercase #6EC1E4, title 20px bold italic */
.panel.ready { border-radius: 14px; padding: 20px 16px; box-shadow: var(--p-card-shadow); align-items: center; gap: 12px; }
.timer { position: relative; width: 120px; height: 120px; }
.timer svg { width: 100%; height: 100%; transform: rotate(-90deg); }
.timer-bg { fill: none; stroke: #e5e7eb; stroke-width: 8; }
.timer-fg { fill: none; stroke: var(--p-btn); stroke-width: 8; stroke-linecap: round; stroke-dasharray: 276.46; stroke-dashoffset: 0; transition: stroke-dashoffset 0.25s linear; }
.timer-num { position: absolute; inset: 0; display: grid; place-items: center; font: 800 44px var(--p-font-head); color: var(--p-title); font-variant-numeric: tabular-nums; }
.ready-label { margin: 7px 0 0; color: var(--p-icon); font-weight: 600; font-size: 16px; text-transform: uppercase; }
html[data-skin-club] .ready-label { color: var(--ds-accent-strong, #ff0000); font-weight: 700; }
.ready-title { margin: 0; font: 700 20px var(--p-font-head); font-style: var(--p-title-style); text-transform: uppercase; color: var(--p-title); }
/* Pre-game ad (US-P9a): full panel width on top of the countdown, picture shown whole (contain) on the panel's own colour; the timer gets smaller while it shows. Hidden until the picture has loaded, so never an empty box. */
.cd-ad { margin: -20px -16px 0; width: calc(100% + 32px); overflow: hidden; border-radius: 14px 14px 0 0; background: var(--p-card, #fff); animation: cd-ad-in 0.25s ease-out; }
.cd-ad[hidden] { display: none; }
.cd-ad img { display: block; width: 100%; height: auto; max-height: min(52vh, 460px); object-fit: contain; }
html[data-skin-club] .cd-ad { border-radius: var(--p-r-card) var(--p-r-card) 0 0; }
.panel.ready.with-ad { gap: 8px; }
.panel.ready.with-ad .timer { width: 84px; height: 84px; }
.panel.ready.with-ad .timer-num { font-size: 32px; }
/* US-M8a: "Sponsored by" on the countdown dialog (#cd-sponsor uses .wait-sponsor). Last row of the panel, under "Game starting soon"
   (the pre-game ad keeps the top). The picture is scaled into the slot (contain, never cropped) so wide and tall logos both fit. No event
   picture and no event name: the DS logo (ds-logo-light.png), and the slot stays visible. That logo is the light wordmark, so the countdown
   strip (a white panel) goes dark only for this fallback. Main has no sponsor strip above the waiting line (Micha 24 Oct 2026). */
.wait-sponsor { display: flex; align-items: center; justify-content: center; gap: 10px; min-width: 0; height: 48px; padding: 6px 14px; border-radius: 10px; background: rgba(0, 0, 0, 0.28); color: #fff; }
.wait-sponsor[hidden], .wait-sponsor [hidden] { display: none; }
.ws-cap { flex: none; font: 700 11px/1.2 var(--p-font); text-transform: uppercase; letter-spacing: 0.14em; color: var(--p-soft); white-space: nowrap; }
.ws-img { display: block; flex: 0 1 auto; min-width: 0; max-width: 62%; max-height: 100%; width: auto; height: auto; object-fit: contain; }
.ws-name { min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; font: 800 18px/1.2 var(--p-font-head); text-transform: uppercase; }
html[data-skin-club] .wait-sponsor { border-radius: var(--p-r-card, 10px); }
.cd-sponsor { align-self: stretch; height: 56px; margin: 4px -16px -20px; padding: 8px 16px 10px; border-radius: 0 0 14px 14px; background: transparent; color: var(--p-title); border-top: 1px solid rgba(0, 0, 0, 0.08); }
.cd-sponsor .ws-cap { color: var(--p-icon); }
html[data-skin-club] .cd-sponsor { border-radius: 0 0 var(--p-r-card, 14px) var(--p-r-card, 14px); border-top-color: rgba(127, 127, 127, 0.25); }
html[data-skin-club] .cd-sponsor .ws-cap { color: var(--ds-accent-strong, #ff0000); }
/* DS logo fallback only: the light wordmark needs a dark strip (the countdown panel is white). */
.cd-sponsor[data-kind="logo"] { background: #00142a; color: #fff; }
.cd-sponsor[data-kind="logo"] .ws-cap { color: #abcff5; }
html[data-skin-club] .cd-sponsor[data-kind="logo"] .ws-cap { color: rgba(255, 255, 255, 0.78); }
.panel.ready.with-ad .cd-sponsor { height: 44px; padding-top: 6px; padding-bottom: 6px; }
/* Short landscape windows (desktop/laptop; phones in landscape get the rotate card): keep the countdown, the title and the sponsor on one screen. */
@media (orientation: landscape) and (max-height: 560px) {
  #countdown-modal { padding: 8px; }
  .panel.ready { gap: 6px; padding-top: 12px; }
  .panel.ready .timer { width: 84px; height: 84px; }
  .panel.ready .timer-num { font-size: 32px; }
  .panel.ready.with-ad .timer { width: 64px; height: 64px; }
  .panel.ready.with-ad .timer-num { font-size: 26px; }
  .cd-ad { margin-top: -12px; }
  .cd-ad img { max-height: 30vh; }
  .ready-label { margin-top: 0; }
  .cd-sponsor, .panel.ready.with-ad .cd-sponsor { height: 40px; padding-top: 5px; padding-bottom: 5px; }
}
@keyframes cd-ad-in { from { opacity: 0; } to { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .cd-ad { animation: none; } .timer-fg { transition: none; } }
/* Settings: Sound and vibration switch (>= 44 px tap row) */
.toggle { display: flex; align-items: center; justify-content: space-between; gap: 12px; min-height: 44px; margin: 16px 0 4px; text-align: left; cursor: pointer; }
.toggle-txt { display: flex; flex-direction: column; gap: 2px; }
.toggle-hint { font-size: 13px; opacity: 0.75; }
.toggle input { flex: none; appearance: none; -webkit-appearance: none; width: 52px; height: 32px; border-radius: 999px; background: #9ca3af; position: relative; cursor: pointer; margin: 0; transition: background 0.15s; }
.toggle input::after { content: ''; position: absolute; top: 3px; left: 3px; width: 26px; height: 26px; border-radius: 50%; background: #fff; box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3); transition: transform 0.15s; }
.toggle input:checked { background: var(--p-btn); }
.toggle input:checked::after { transform: translateX(20px); }
.toggle input:focus-visible { outline: 3px solid var(--p-select, #2563eb); outline-offset: 2px; }
@media (prefers-reduced-motion: reduce) { .toggle input, .toggle input::after { transition: none; } }

.spinner { width: 40px; height: 40px; border-radius: 50%; border: 4px solid #d1d5db; border-top-color: #4b5563; animation: spin 0.9s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }
.status-bar { position: fixed; left: 50%; top: max(8px, env(safe-area-inset-top)); transform: translateX(-50%); z-index: 30; padding: 8px 14px; border-radius: 999px; background: #f59e0b; color: #111; font-weight: 700; font-size: 14px; box-shadow: 0 2px 10px rgba(0, 0, 0, 0.35); white-space: nowrap; }

/* ---------- Layout (SIM rules, docs/LAYOUT.md on feat/layouts, re-implemented) ---------- */
/* Tablet portrait: a wider single column, larger type. */
@media (orientation: portrait) and (min-width: 700px) {
  :root { --p-col: 560px; --p-dash: 680px; }
  .card { padding: 32px 28px; gap: 14px; }
  .logo { width: 240px; } .hero { width: 280px; }
  .card-title { font-size: 30px; line-height: 36px; } .card-p { font-size: 18px; line-height: 22px; } .card-p.small { font-size: 15px; line-height: 19px; }
  .btn { font-size: calc(var(--p-btn-size) + 6px); padding: 12px; }
  .dash-body { gap: 14px; padding: 20px 20px 16px; }
  .team-lock-note { font-size: 15px; line-height: 20px; }
  .arena-name { font-size: 22px; } .prize-cap { font-size: 20px; } .prize-points { font-size: 24px; } .prize-unit { font-size: 16px; } .prize-pic { width: 92px; height: 92px; }
  .wait-line-txt { font-size: 32px; } .foot-item, .foot-powered { font-size: 15px; }
  .panel { max-width: 520px; padding: 32px; } .panel-title { font-size: 26px; line-height: 34px; }
}
/* Desktop (mouse) landscape: an upright centred column that grows with the window height. */
@media (orientation: landscape) and (min-width: 900px) and (min-height: 860px) and (hover: hover) { .col, .dash, .panel { zoom: 1.15; } }
@media (orientation: landscape) and (min-width: 900px) and (min-height: 1040px) and (hover: hover) { .col, .dash, .panel { zoom: 1.3; } }

/* Phones and tablets held sideways: "Turn your device upright". */
.rotate { display: none; position: fixed; inset: 0; z-index: 100; flex-direction: column; align-items: center; justify-content: center; gap: 12px; padding: 16px 24px; background: var(--p-page); color: #fff; text-align: center; }
.rotate-icon { font-size: 72px; animation: turn 2.4s ease-in-out infinite; }
.rotate-title { margin: 0; font-size: 22px; font-weight: 800; text-transform: uppercase; max-width: 28rem; }
.rotate-note { margin: 0; color: var(--p-soft); max-width: 28rem; }
@keyframes turn { 0%, 20% { transform: rotate(-90deg); } 55%, 100% { transform: rotate(0deg); } }
@media (hover: none) and (pointer: coarse) and (orientation: landscape) { .rotate { display: flex; } html, body { overflow: hidden; } }
@media (hover: none) and (pointer: coarse) and (orientation: landscape) and (min-width: 900px) and (min-height: 600px) { .rotate-icon { font-size: 112px; } .rotate-title { font-size: 32px; } .rotate-note { font-size: 19px; } }
@media (prefers-reduced-motion: reduce) { .rotate-icon, .spinner { animation: none; } }
/* Light club skins (theme "tone": "light", e.g. f95): the dark-skin page gradient ends in the light --ds-bg, so the white page text (waiting line, footer, Powered by) became unreadable; use the club's own red gradient end to end instead. */
html[data-skin-tone='light'] {
  --p-page: var(--ds-accent-press, #931818);
  --p-col-top: var(--ds-accent-strong, #e30613);
  --p-col-bottom: var(--ds-accent-press, #931818);
}
/* Club look from the theme file (skins v2 keys, no club names in the CSS): cards and dialogs in the theme's surface / text colour and card radius, buttons and options in its button radius, the selected option as a solid accent block, dialog titles as a solid accent title bar; dark skins on the plain page colour with surface-coloured prize card. */
html[data-skin-club] {
  --p-card: var(--ds-surface, #ffffff);
  --p-media-frame-bg: var(--ds-media-frame-bg, #000000); /* theme JSON vars: "--ds-media-frame-bg" */
  --p-card-shadow: none;
  --p-title: var(--ds-text, #000000);
  --p-option: var(--ds-surface-2, #eaeaea);
  --p-option-text: var(--ds-text, #000000);
  --p-r-card: var(--ds-radius-card, 14px);
  --p-r-btn: var(--ds-radius, 9px);
}
html[data-skin-tone='dark'] { --p-col-top: var(--ds-bg, #000000); --p-prize-bg: var(--ds-surface, #181818); }
html[data-skin-club] :is(.card, .panel, .panel.ready) { background: var(--p-card); color: var(--p-title); border-radius: var(--p-r-card); box-shadow: none; }
html[data-skin-club] :is(.btn, .btn.claim, .toast, .error) { border-radius: var(--p-r-btn); }
html[data-skin-club] :is(.prize-card, .bstrip, .sponsor) { border-radius: var(--p-r-card); }
html[data-skin-club] .prize-pic { background: var(--ds-surface-2, #ffffff); color: var(--ds-text, #000000); }
html[data-skin-club] .btn.outline { background: transparent; border: 2px solid var(--p-outline); color: var(--p-outline); }
html[data-skin-club] .option { border: 0; border-radius: var(--p-r-btn); padding: 16px; }
html[data-skin-club] .option[aria-checked="true"] { border: 0; padding: 16px; background: var(--ds-accent-strong, #ff0000); }
html[data-skin-club] .option[aria-checked="true"] .oname { color: var(--ds-on-accent, #ffffff); }
html[data-skin-club] .panel-title { order: -1; margin: -24px -24px 20px; padding: 12px 16px; background: var(--ds-accent-strong, #ff0000); color: var(--ds-on-accent, #ffffff); border-radius: var(--p-r-card) var(--p-r-card) 0 0; font-style: normal; }
@media (orientation: portrait) and (min-width: 700px) { html[data-skin-club] .panel-title { margin: -32px -32px 24px; } }

/* Heartbeat dot (Micha 22 Oct 09:26): 8 px in the arena header's top-right corner, absolutely placed (no layout shift), away from the banners
   (sponsor graphics) below the header; a soft pulse on every heartbeat ack. Green = last ack within the expected interval, amber = one missed,
   grey = lost (with the Reconnecting bar). Tap for a tiny tooltip. Fixed colours with a light ring so it reads on every skin. */
.hb { position: absolute; top: 4px; right: 4px; width: 32px; height: 32px; padding: 0; border: 0; background: none; display: flex; align-items: center; justify-content: center; cursor: pointer; -webkit-tap-highlight-color: transparent; z-index: 2; }
.hb-dot { position: relative; width: 8px; height: 8px; border-radius: 50%; background: #9ca3af; box-shadow: 0 0 0 1.5px rgba(255, 255, 255, 0.85), 0 1px 3px rgba(0, 0, 0, 0.45); transition: background-color 0.4s; }
.hb[data-state=ok] .hb-dot { background: #22c55e; }
.hb[data-state=missed] .hb-dot { background: #f59e0b; }
.hb[data-state=lost] .hb-dot { background: #9ca3af; }
.hb-dot::after { content: ""; position: absolute; inset: 0; border-radius: 50%; background: inherit; opacity: 0; }
.hb.pulse .hb-dot::after { animation: hb-pulse 0.9s ease-out; }
@keyframes hb-pulse { 0% { transform: scale(1); opacity: 0.55; } 100% { transform: scale(2.6); opacity: 0; } }
.hb:focus-visible { outline: 2px solid #fff; outline-offset: -4px; border-radius: 50%; }
.hb-tip { position: absolute; top: 34px; right: 6px; z-index: 3; max-width: calc(100% - 12px); padding: 5px 9px; border-radius: 8px; background: rgba(17, 24, 39, 0.92); color: #fff; font: 500 12px/1.3 system-ui, sans-serif; white-space: nowrap; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.35); pointer-events: none; }
@media (prefers-reduced-motion: reduce) { .hb.pulse .hb-dot::after { animation: none; } .hb-dot { transition: none; } }
/* Always blinking (Micha 22 Oct 19:26, "Should be blinking all the time"): a steady 1.2 s CSS blink in EVERY state (wait / ok / missed / lost),
   not tied to single heartbeats; the colour above still tells the state. Deliberately no prefers-reduced-motion exception (Micha's call). */
.hb-dot { animation: hb-blink 1.2s ease-in-out infinite; }
@keyframes hb-blink { 0%, 100% { opacity: 1; } 50% { opacity: 0.35; } }
/* Game-start alerts step (notify-modal) and the iPhone Add to Home Screen guide; Home Screen "event over" card */
.notify-bell { align-self: center; display: inline-flex; align-items: center; justify-content: center; width: 64px; height: 64px; border-radius: 50%; background: var(--p-btn); color: var(--p-btn-text, #fff); margin-bottom: 8px; }
.notify-panel .panel-title { margin-bottom: 12px; }
.panel-text { margin: 0 0 4px; font: 400 16px/1.45 var(--p-font); color: var(--p-title); }
.guide-title { margin: 0 0 12px; font: 700 16px/1.3 var(--p-font); color: var(--p-title); }
.guide { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 12px; text-align: left; }
.guide li { display: flex; align-items: center; gap: 10px; padding: 10px 12px; border-radius: 10px; background: rgba(0, 25, 52, 0.06); font: 500 15px/1.35 var(--p-font); color: var(--p-title); }
.guide .gicon { flex: none; display: inline-flex; align-items: center; justify-content: center; width: 40px; height: 40px; border-radius: 10px; background: #fff; color: #0a84ff; box-shadow: 0 1px 3px rgba(0, 0, 0, 0.18); }
.guide .gicon.app img { border-radius: 6px; }
.guide .gnum { flex: none; font: 700 15px var(--p-font); opacity: 0.6; }
.over-tip { margin-top: 12px; opacity: 0.85; }

/* Claim screen (vouchers, Micha 22 Oct 21:44/21:50): prize picture beside the name, the push check box.
   Close (expired, sold out, not enough points, …) is the dismiss. The club title bar normally uses a
   negative margin equal to the panel padding. On this flex column that margin shrinks the card and the
   bottom edge cuts #claim-close on a narrow iPhone. Zero the top padding instead, so the bar stays flush
   with the card and the bottom padding stays under Close. */
.claim-panel { display: flex; flex-direction: column; gap: 12px; flex-shrink: 0; }
html[data-skin-club] .claim-panel { padding-top: 0; }
html[data-skin-club] .claim-panel > .panel-title { margin: 0 -24px 20px; }
@media (orientation: portrait) and (min-width: 700px) {
  html[data-skin-club] .claim-panel > .panel-title { margin-left: -32px; margin-right: -32px; }
}
.claim-panel > #claim-close { /* a full-width outlined button (Micha 26 Oct 2026: the small underlined "Close" link looked like a stray tiny button) */
  flex-shrink: 0;
  width: 100%;
  min-height: 48px;
  margin: 4px 0 0;
  padding: 10px 16px;
  line-height: 20px;
  text-decoration: none;
  opacity: 1;
  -webkit-appearance: none;
  appearance: none;
}
.claim-prize { display: flex; align-items: center; gap: 14px; }
.claim-prize-name { margin: 0; font-weight: 700; font-size: 20px; color: var(--ds-accent, inherit); }
.claim-gate[data-state="ok"] p, .claim-gate[data-state="checking"] p { display: none; }
@media (max-width: 360px) { .claim-prize { flex-direction: column; text-align: center; } }
/* QR voucher screen (voucher.html): picture beside the prize name (club colours), QR at full size on white with its quiet zone; narrow phones stack picture, name, details, QR */
.vpage { min-height: 100dvh; margin: 0; display: flex; justify-content: center; background: var(--ds-bg, #001934); color: var(--ds-text, #fff); font-family: var(--ds-font, system-ui, sans-serif); }
.vcard { width: min(440px, 100%); padding: max(16px, env(safe-area-inset-top)) 16px 24px; display: flex; flex-direction: column; align-items: center; gap: 10px; box-sizing: border-box; }
.vtitle { margin: 4px 0; font-size: 20px; }
.vhead { width: 100%; display: flex; align-items: center; gap: 14px; }
.vinfo { min-width: 0; }
.vinfo p { margin: 2px 0; }
.vprize { font-size: 22px; font-weight: 800; color: var(--ds-accent, #ffd400); }
.vvalue { font-weight: 600; } .vnote { opacity: .9; }
.vsponsor { display: flex; align-items: center; justify-content: center; gap: 8px; margin: 2px 0 4px; font-size: 14px; opacity: .9; }
.vsponsor[hidden], .vsponsor img[hidden] { display: none; }
.vsponsor img { max-height: 36px; max-width: 140px; object-fit: contain; background: #fff; border-radius: 6px; padding: 2px 6px; }
.vstatus { margin: 4px 0; padding: 6px 14px; border-radius: 999px; font-weight: 800; background: rgba(255,255,255,.12); }
.vcard[data-status="redeemed"] .vstatus { background: #15803d; color: #fff; font-size: 20px; }
.vcard[data-status="voided"] .vstatus, .vcard[data-status="expired"] .vstatus { background: #b91c1c; color: #fff; }
.vvalid { margin: 0; font-size: 14px; opacity: .85; }
.vcard[data-status="expired"] .vvalid { opacity: 1; font-weight: 700; }
.vqr-box { flex: none; padding: 16px; background: #fff; border-radius: 12px; line-height: 0; }
.vqr { display: block; width: 256px; height: 256px; max-width: calc(100vw - 64px); max-height: calc(100vw - 64px); image-rendering: pixelated; }
.vcard[data-status="redeemed"] .vqr, .vcard[data-status="voided"] .vqr, .vcard[data-status="expired"] .vqr { opacity: .25; }
.vcode { margin: 0; font: 700 18px/1.2 ui-monospace, monospace; letter-spacing: .08em; }
.vcode.short { font-size: 40px; letter-spacing: .25em; }
.vhint { margin: 0; opacity: .85; text-align: center; }
.vback { margin-top: 8px; color: inherit; }
@media (max-width: 360px) { .vhead { flex-direction: column; text-align: center; } }
/* Band chip + crossing notice (Micha 22 Oct 22:08-22:12): a 3-segment vertical bar that fills from the bottom (1 = Bottom/red, 2 = Middle/yellow, 3 = Top/green) + the text label, so shape, colour and words all say the band (works in greyscale).
   Solid backing (dark on dark skins, white on light skins) with high-contrast outlines; unfilled segments are outlines only. Each step eases briefly (BAND_EASE_MS 250 ms); no ease under reduced motion. */
.bandbar { --bb-w: 10px; --bb-h: 6px; --bb-gap: 2px; --bb-line: #ffffff; display: inline-flex; flex-direction: column; gap: var(--bb-gap); flex: none; }
.bandbar i { display: block; width: var(--bb-w); height: var(--bb-h); border: 1.5px solid var(--bb-line); border-radius: 2px; background: transparent; transition: background-color 0.25s ease, transform 0.25s ease; }
.bandbar[data-band=green] i.on { background: #00e05a; }
.bandbar[data-band=yellow] i.on { background: #ffd400; }
.bandbar[data-band=red] i.on { background: #ff2d2d; }
.bandbar i.on { transform: scaleX(1.08); }
.band-chip { position: absolute; left: 6px; bottom: 6px; z-index: 2; display: inline-flex; align-items: center; gap: 6px; padding: 4px 9px 4px 6px; border-radius: 999px; background: rgba(8, 10, 18, 0.88); border: 1.5px solid #ffffff; color: #ffffff; font: 700 12px/1 var(--p-font); text-transform: uppercase; letter-spacing: 0.02em; pointer-events: none; }
.band-notice { position: fixed; left: 50%; bottom: calc(max(12px, env(safe-area-inset-bottom)) + 88px); /* above the sticky footer, clear of the header buttons and the heartbeat dot */ transform: translateX(-50%); z-index: 40; width: min(calc(100% - 24px), 400px); display: flex; align-items: center; gap: 14px; padding: 12px 16px; border-radius: 14px; background: rgba(8, 10, 18, 0.94); border: 2px solid #ffffff; color: #ffffff; font: 700 16px/1.3 var(--p-font); box-shadow: 0 6px 24px rgba(0, 0, 0, 0.45); pointer-events: none; }
.band-notice .bandbar { --bb-w: 26px; --bb-h: 14px; --bb-gap: 3px; }
.band-notice .bandbar i { border-width: 2px; border-radius: 3px; }
.band-chip[hidden], .band-notice[hidden] { display: none; }
/* light club skins (f95): white backing, dark outlines, deeper colours so yellow still stands out from white (also in greyscale) */
html[data-skin-tone='light'] .band-chip, html[data-skin-tone='light'] .band-notice { background: #ffffff; border-color: #111111; color: #111111; }
html[data-skin-tone='light'] .bandbar { --bb-line: #111111; }
html[data-skin-tone='light'] .bandbar[data-band=green] i.on { background: #008a3c; }
html[data-skin-tone='light'] .bandbar[data-band=yellow] i.on { background: #e0a100; }
html[data-skin-tone='light'] .bandbar[data-band=red] i.on { background: #d10000; }
@media (prefers-reduced-motion: reduce) { .bandbar i { transition: none; } }

/* Per-game team sets: the team pick inside the countdown (team-choice.js) */
.tc { width: 100%; margin-top: 10px; text-align: center; }
.tc-title { margin: 0 0 2px; font: 700 17px var(--p-font-head); color: var(--p-title); }
.tc-set { margin: 0; font-weight: 600; color: var(--p-option-text); }
.tc-body { margin: 2px 0 0; font-size: 14px; color: var(--p-option-text); opacity: 0.8; }
.tc-list { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin: 10px 0 6px; }
.tc-team { min-height: 52px; padding: 8px; border: 0; border-radius: 12px; background: var(--p-btn); color: var(--p-btn-text); font: 700 17px var(--p-font); overflow-wrap: anywhere; cursor: pointer; }
.tc-team:active { transform: scale(0.97); }
.tc-team.tc-none { grid-column: 1 / -1; min-height: 44px; background: var(--p-option); color: var(--p-option-text); font-weight: 600; }
.tc-note { margin: 0; font-size: 13px; color: var(--p-option-text); opacity: 0.8; }
.tc-yours { margin: 0; font-weight: 700; color: var(--p-title); }
#team-text { margin: 0 0 12px; } /* Team Sets: the default set's short text under the dialog title */

/* Prize menu: sponsor row on top of a prize button (logo + "Sponsored by {name}"), then the picture, name and points */
.option.prize { flex-wrap: wrap; }
.option .osp { flex: 0 0 100%; display: flex; align-items: center; justify-content: center; gap: 8px; min-width: 0; font: 700 13px/1.2 var(--p-font); opacity: 0.85; }
.option .osp img { height: 20px; width: auto; max-width: 60px; object-fit: contain; border-radius: 3px; }
.option .osp span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Main top row without the team pill (Micha 25 Oct): Share sits on the right; Settings lives in the bottom bar */
.dsp-strip.team-row[hidden] { display: none; }
.dash-tools { margin-left: auto; }
.dash-foot .icon-btn.settings { margin-left: auto; }
.dash-foot .icon-btn.settings { color: var(--p-foot-text); }
.dash-foot .icon-btn.settings svg { stroke: currentColor; }
.arena[hidden] { display: none; }
/* home re-layout (Micha 25 Oct 2026): sponsor, team strip, points, banners with one tiny shared gap; Share + Settings in the bottom bar */
:root { --p-gap: 6px; }
.dash-body { gap: var(--p-gap); padding: max(var(--p-gap), env(safe-area-inset-top)) var(--p-gap) var(--p-gap); }
.dash-body > * { margin-top: 0; margin-bottom: 0; }
.banners { gap: var(--p-gap); }
.legacy-top[hidden], .team-strips-mount[hidden], .team-fans[hidden] { display: none; }
.team-fans { display: flex; gap: var(--p-gap); padding: 8px 10px; border-radius: 6px; background: rgba(0,0,0,.25); color: #fff; font-size: 14px; font-weight: 700; justify-content: space-around; flex-wrap: wrap; }
.team-fan { display: inline-flex; align-items: center; gap: 6px; min-width: 0; }
.team-fan-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 9em; font-weight: 600; opacity: .9; }
.team-fan-dot { width: 9px; height: 9px; border-radius: 50%; flex: none; background: var(--dsp-team, #9aa); }
.team-fan.mine .team-fan-name { text-decoration: underline; }
.dash-foot { justify-content: space-between; }
.dash-foot .icon-btn.share { color: var(--p-foot-text); }
.dash-foot .icon-btn.share svg { stroke: currentColor; }
.powered[hidden]{display:none}
/* Let's play one size up (Micha 25 Oct 21:45): thicker and bigger lettering */
#join-btn { min-height: 56px; padding: 14px 12px; font-size: calc(var(--p-btn-size) + 4px); }
/* prize picker (Micha 25 Oct 21:48): picture twice as big, on the left; no sponsor row */
.option.prize { justify-content: flex-start; text-align: left; gap: 16px; }
.option.prize img, .option.prize .prize-img, .option.prize [data-testid=prize-option-image] { max-width: 96px; max-height: 96px; width: 96px; height: 96px; flex: none; object-fit: contain; }
.option.prize .osub { font-size: 18px; font-weight: 800; opacity: 0.9; margin-top: 4px; } /* points bigger, under the name (Micha 25 Oct 21:48) */
/* org switch prizes.show_sponsor_on_buttons: sponsor row under the prize picture block, full width; its logo stays small (not the 96px prize picture) */
.option.prize .osp { justify-content: flex-start; }
.option.prize .osp img { width: auto; height: 28px; max-width: 90px; max-height: 28px; }
/* chosen-prize strip (Micha 25 Oct 21:55): no prize name, no "/ 120"; "Prize points" right of the big number at the same size */
#prize-name { display: none; }
#prize-points { color: #fff; font-size: 24px; }
#prize-points b, #prize-points .prize-need, #prize-points .prize-unit { display: inline; font-size: inherit; font-weight: 700; line-height: 1.2; }
/* the points + sponsor column never runs under the Claim button */
.prize-row .prize-l { flex: 1 1 auto; min-width: 0; }
.prize-row .prize-l > div { min-width: 0; }
#prize-sponsor { flex-wrap: wrap; }
/* points on one line between the picture and Claim on a 393px phone (Micha 25 Oct 22:03) */
#prize-points { font-size: clamp(13px, 4.2vw, 20px); white-space: nowrap; } /* "28 out of 120 Prize points" stays on one line at 360 px */
/* event sponsor area about one third of the screen HEIGHT (Micha 25 Oct 22:04), picture centred on black, never stretched */
.sponsor { aspect-ratio: auto; height: 33vh; height: 33dvh; background: #000; }
.sponsor::before { display: none; }
.sponsor > .sponsor-face { background: #000; }
/* never a black screen (Micha 25 Oct 22:12): reconnecting overlay from index.html */
.ds-down { position: fixed; inset: 0; z-index: 99999; display: flex; align-items: center; justify-content: center; text-align: center; padding: 24px; color: #fff; background: radial-gradient(circle at 50% 30%, #0b3a6e 0, #001934 70%); font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif; }
.ds-down[hidden] { display: none; }
.ds-down-box { max-width: 340px; }
.ds-down-logo { font-weight: 800; letter-spacing: .04em; font-size: 28px; line-height: 1.1; }
.ds-down-logo small { display: block; font-size: 12px; letter-spacing: .45em; margin-top: 4px; }
.ds-down h2 { font-size: 21px; margin: 24px 0 8px; }
.ds-down p { opacity: .85; margin: 0 0 20px; }
.ds-down-spin { width: 32px; height: 32px; margin: 0 auto 18px; border: 4px solid rgba(255,255,255,.25); border-top-color: #23b4ff; border-radius: 50%; animation: ds-down-s 1s linear infinite; }
@keyframes ds-down-s { to { transform: rotate(360deg); } }
.ds-down button { font: inherit; font-weight: 700; color: #001934; background: #fff; border: 0; border-radius: 10px; padding: 11px 24px; }
/* Player version at the bottom of Settings (Micha 25 Oct 23:34): small, unobtrusive */
.version-tag { margin: 10px 0 0; text-align: center; font-size: 11px; opacity: 0.45; letter-spacing: 0.04em; }
.version-tag[hidden] { display: none; }

.prize-choose-link { background:none; border:0; padding:0; font:inherit; font-weight:800; color:inherit; text-decoration:underline; cursor:pointer; }
.alerts-steps { font-size: 13px; text-align: left; margin: 4px 0; }
.alerts-row .toggle input:disabled { opacity: 0.5; cursor: not-allowed; }
.alerts-row #alerts-act { display: block; margin: 2px 0 8px; }
/* wins strip (Micha 26 Oct 2026): same look as the team strip, smaller; below the prize card, above the banners */
.wins-strip { display: flex; gap: var(--p-gap); padding: 4px 10px; border-radius: 6px; background: rgba(0,0,0,.25); color: #fff; font-size: 12px; font-weight: 600; justify-content: space-around; }
.wins-strip[hidden] { display: none; }
.wins-strip b { font-weight: 800; margin-left: 4px; }

/* Poll results (host "Show results on phones", Micha 26 Oct): the poll strip (picture + question) with the Host's "Yes N (P%) · No N (P%)" line in place of the buttons */
.banner.kind-poll-results .bres { font-size: 13px; font-weight: 700; line-height: 1.2; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-variant-numeric: tabular-nums; opacity: 0.92; }

/* tier strip (Micha 26 Oct 10:59, Option B podium); colours from the skin, tier accents overridable per skin */
.tier-strip { --ts-top: var(--p-tier-top, var(--p-btn)); --ts-mid: var(--p-tier-mid, #f5c542); --ts-low: var(--p-tier-low, #f87171); --ts-gold: var(--p-tier-gold, #f5c542);
  display: flex; align-items: center; gap: 12px; padding: 8px 14px; border: 2px solid var(--ts-top); border-radius: 16px; background: rgba(255,255,255,.08); color: var(--p-btn-text); font-family: var(--p-font); font-size: 14px; line-height: 1.35; }
.tier-strip[hidden] { display: none; }
.tier-strip[data-tier='mid'] { border-color: var(--ts-mid); }
.tier-strip[data-tier='low'] { border-color: var(--ts-low); }
.ts-podium { flex: none; display: flex; }
.ts-podium .ts-step { fill: var(--p-soft); opacity: .45; }
.ts-podium .ts-lit { fill: var(--ts-top); }
.ts-podium text { font-size: 11px; font-weight: 700; fill: #fff; }
.ts-podium .ts-star { fill: var(--ts-gold); stroke: #fff; stroke-width: 1; }
.ts-text { display: flex; flex-direction: column; align-items: flex-start; gap: 5px; }
.ts-badge { background: var(--ts-gold); color: var(--p-col-bottom); font-size: 11px; font-weight: 800; border-radius: 999px; padding: 2px 9px; }
.ts-badge[hidden] { display: none; }
html[data-skin-tone='light'] .tier-strip { color: var(--p-title); background: rgba(0,0,0,.04); }
.ts-gp-open { margin-top: 8px; padding: 10px 14px; border: 0; border-radius: 10px; font-weight: 700; background: var(--ts-gold); color: #1a1a1a; cursor: pointer; }
.ts-gp-open[hidden] { display: none; }
.tier-strip[data-gp='won'] { border-color: var(--ts-gold); }
.hb-wrap { position: relative; display: inline-flex; align-items: center; }
.dash-foot .hb { position: static; }
.dash-foot .hb-tip { top: auto; bottom: 36px; right: 0; max-width: none; }
