Files
NHL-Scoreboard/app/static/styles.css
T
josh 2da60e27ae
CI / Lint (push) Failing after 10s
CI / Test (push) Has been skipped
CI / Build & Push (push) Has been skipped
feat: add 10 UX improvements from interface review
- Stale data banner after 3 consecutive fetch failures, auto-clears on recovery
- Date navigation with left/right arrows (Yesterday/Today/Tomorrow labels),
  fetches from NHL API for non-today dates, disables auto-refresh on history
- Empty state message when no games are scheduled
- Series detail page auto-refreshes every 30s when a game is live
- Notification permission deferred until a playoff OT actually occurs
- Scroll position saved/restored when navigating to/from series detail
- Team records rendered with better contrast and tabular nums
- Active bracket round highlighted with gold heading + underline,
  completed rounds dimmed more aggressively, mobile accordion auto-opens
  current round
- Browser tab title shows live game count (e.g. "NHL Scoreboard (3 Live)")
- Service worker update shows a dismissable toast instead of force-reloading

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-23 20:22:03 -04:00

1314 lines
27 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
:root {
--bg: #111;
--card: #1c1c1c;
--card-border: #2a2a2a;
--badge-bg: #2a2a2a;
--text: #f0f0f0;
--text-muted: #666;
--green-bg: #14532d;
--green-text: #86efac;
--green-accent: #22c55e;
--red: #ef4444;
--gap: 1rem;
--radius: 12px;
--card-w: 290px;
/* Cup theme palette — only referenced when body.playoff-mode is set */
--cup-gold-1: #d4af37;
--cup-gold-2: #f5d76e;
--cup-gold-dim: #8a6d1a;
--cup-silver-1: #c0c8d0;
--cup-silver-2: #e8ecef;
--cup-silver-dim: #6b7580;
--ice-1: #0a1628;
--ice-2: #162844;
--ice-accent: #4fc3f7;
--gold-gradient: linear-gradient(90deg, var(--cup-gold-dim), var(--cup-gold-2) 50%, var(--cup-gold-1));
--banner-bg: radial-gradient(ellipse at top, rgba(22, 40, 68, 0.55), transparent 70%), #141418;
--radius-sm: 6px;
}
*, *::before, *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
background: var(--bg);
color: var(--text);
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
min-height: 100vh;
}
/* ── Header ─────────────────────────────────────── */
header {
padding: 1rem 1.25rem 0.25rem;
text-align: center;
}
.header-title {
font-size: 2rem;
font-weight: 700;
color: var(--text);
}
/* ── Date Navigation ───────────────────────────── */
.date-nav {
display: flex;
align-items: center;
justify-content: center;
gap: 0.6rem;
padding-bottom: 0.5rem;
}
.date-btn {
background: var(--badge-bg);
border: 1px solid var(--card-border);
border-radius: var(--radius-sm);
color: var(--text);
font-size: 0.85rem;
font-weight: 600;
padding: 0.25rem 0.6rem;
cursor: pointer;
transition: background 0.12s ease, border-color 0.12s ease;
}
.date-btn:hover {
background: #333;
border-color: #555;
}
.date-btn:focus-visible {
outline: 2px solid var(--cup-gold-1);
outline-offset: 2px;
}
.date-label {
font-size: 0.85rem;
font-weight: 600;
color: var(--text-muted);
min-width: 6rem;
text-align: center;
}
/* ── Layout ─────────────────────────────────────── */
main {
padding: 0.75rem 1.25rem 2rem;
max-width: 1800px;
margin-left: auto;
margin-right: auto;
}
.section {
margin-bottom: 2rem;
}
.section.hidden {
display: none;
}
.update-toast {
position: fixed;
bottom: 1.5rem;
left: 50%;
transform: translateX(-50%);
background: var(--card);
border: 1px solid var(--card-border);
border-radius: var(--radius);
padding: 0.6rem 1rem;
font-size: 0.82rem;
color: var(--text);
display: flex;
align-items: center;
gap: 0.75rem;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.5);
z-index: 1000;
}
.update-toast-btn {
background: var(--cup-gold-1);
color: #1a1200;
border: none;
border-radius: var(--radius-sm);
padding: 0.3rem 0.7rem;
font-size: 0.78rem;
font-weight: 700;
cursor: pointer;
}
.update-toast-btn:hover {
background: var(--cup-gold-2);
}
.stale-banner {
text-align: center;
padding: 0.45rem 1rem;
background: rgba(239, 68, 68, 0.12);
color: #fca5a5;
font-size: 0.78rem;
font-weight: 600;
letter-spacing: 0.03em;
}
.stale-banner.hidden {
display: none;
}
main.stale {
opacity: 0.6;
}
.empty-state {
text-align: center;
padding: 4rem 1rem;
}
.empty-state.hidden {
display: none;
}
.empty-state-heading {
font-size: 1.1rem;
font-weight: 600;
color: var(--text-muted);
margin-bottom: 0.4rem;
}
.empty-state-sub {
font-size: 0.85rem;
color: #555;
}
.section-heading {
font-size: 0.7rem;
font-weight: 700;
text-align: center;
text-transform: uppercase;
letter-spacing: 0.12em;
color: var(--text-muted);
margin-bottom: 0.875rem;
margin-top: 0.25rem;
}
.games-grid {
display: flex;
flex-wrap: wrap;
gap: var(--gap);
justify-content: center;
}
/* ── Game Card ──────────────────────────────────── */
.game-box {
background: var(--card);
border: 1px solid var(--card-border);
border-radius: var(--radius);
padding: 1rem 1rem 0.875rem;
width: var(--card-w);
flex-shrink: 0;
border-top-width: 3px;
box-shadow:
0 1px 2px rgba(0, 0, 0, 0.4),
0 4px 12px rgba(0, 0, 0, 0.25);
}
.game-box-live {
border-top-color: var(--green-accent);
}
.game-box-intermission {
border-top-color: #f59e0b;
}
/* ── Card Header (badges + live dot) ───────────── */
.card-header {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 0.5rem;
min-height: 1.25rem;
}
.badges {
display: flex;
gap: 0.3rem;
align-items: center;
flex-wrap: wrap;
}
.badge {
font-size: 0.65rem;
font-weight: 700;
padding: 0.2rem 0.45rem;
border-radius: var(--radius-sm);
text-transform: uppercase;
letter-spacing: 0.05em;
background: var(--badge-bg);
color: var(--text);
white-space: nowrap;
}
.badge-live {
background: var(--green-bg);
color: var(--green-text);
}
.badge-muted {
color: var(--text-muted);
}
.live-dot {
width: 7px;
height: 7px;
background: var(--red);
border-radius: 50%;
flex-shrink: 0;
animation: pulse 1.8s ease-in-out infinite;
}
@keyframes pulse {
0%, 100% { opacity: 1; }
50% { opacity: 0.4; }
}
/* ── Team Rows ──────────────────────────────────── */
.team-row {
display: flex;
align-items: center;
gap: 0.625rem;
padding: 0.55rem 0;
}
.team-row + .team-row {
border-top: 1px solid var(--card-border);
}
.team-logo {
width: 40px;
height: 40px;
object-fit: contain;
flex-shrink: 0;
filter: drop-shadow(0 0 2px rgba(255, 255, 255, 0.35));
}
.team-meta {
flex: 1;
min-width: 0;
display: flex;
flex-direction: column;
gap: 0.1rem;
}
.team-name {
font-size: 0.825rem;
font-weight: 600;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.team-sog {
font-size: 0.78rem;
color: #b8b8b8;
font-weight: 500;
font-variant-numeric: tabular-nums;
}
.team-pp {
font-size: 0.78rem;
color: var(--red);
font-weight: 600;
font-variant-numeric: tabular-nums;
}
.team-subline {
display: flex;
align-items: baseline;
gap: 0.5rem;
}
.team-score {
font-size: 1.6rem;
font-weight: 700;
margin-left: auto;
flex-shrink: 0;
min-width: 1.75rem;
text-align: right;
letter-spacing: -0.02em;
}
.team-record {
font-size: 0.78rem;
color: #999;
font-weight: 500;
font-variant-numeric: tabular-nums;
margin-left: auto;
flex-shrink: 0;
white-space: nowrap;
}
/* ── Hype Meter ─────────────────────────────────── */
.hype-meter {
margin-top: 0.75rem;
}
.hype-label {
display: block;
font-size: 0.6rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.1em;
color: var(--text-muted);
margin-bottom: 0.3rem;
}
.gauge-track {
height: 4px;
background: var(--badge-bg);
border-radius: 99px;
overflow: hidden;
}
.gauge {
height: 100%;
border-radius: 99px;
width: 0;
transition: width 0.5s ease;
}
/* ── Desktop ────────────────────────────────────── */
@media (min-width: 900px) {
:root {
--card-w: 340px;
--gap: 1.25rem;
}
main {
padding: 1rem 2rem 2.5rem;
}
.header-title {
font-size: 2.4rem;
}
.section-heading {
font-size: 0.85rem;
}
.game-box {
padding: 1.125rem 1.125rem 1rem;
}
.team-logo {
width: 48px;
height: 48px;
}
.badge {
font-size: 0.75rem;
}
.team-name {
font-size: 0.95rem;
}
.team-score {
font-size: 1.9rem;
}
.hype-label {
font-size: 0.7rem;
}
}
@media (min-width: 1400px) {
:root {
--card-w: 400px;
--gap: 1.5rem;
}
main {
padding: 1.25rem 2.5rem 3rem;
}
.header-title {
font-size: 2.8rem;
}
.section-heading {
font-size: 0.95rem;
}
.game-box {
padding: 1.25rem 1.25rem 1.125rem;
}
.team-logo {
width: 56px;
height: 56px;
}
.badge {
font-size: 0.82rem;
}
.team-name {
font-size: 1.05rem;
}
.team-score {
font-size: 2.2rem;
}
.hype-label {
font-size: 0.76rem;
}
}
/* ── Mobile ─────────────────────────────────────── */
@media (max-width: 640px) {
:root {
--card-w: 100%;
}
.games-grid {
flex-direction: column;
}
}
/* Narrow-phone (≤480px) playoff polish — banner, series, bracket, headings */
@media (max-width: 480px) {
.playoff-banner { gap: 0.5rem; }
.banner-main { gap: 0.6rem; }
.banner-trophy { width: 30px; height: 36px; }
.banner-title { font-size: 0.82rem; letter-spacing: 0.08em; }
.banner-year { margin-left: 0.25rem; }
.banner-meta {
flex-direction: column;
gap: 0.15rem;
font-size: 0.7rem;
letter-spacing: 0.05em;
}
.banner-meta > span:not(.hidden) + span:not(.hidden)::before {
content: none;
}
.series-hero { padding: 1rem 0.875rem; gap: 0.75rem; }
.series-team-logo { width: 48px; height: 48px; }
.series-team-name { font-size: 0.95rem; }
.series-team-wins { font-size: 2rem; }
.series-next-matchup { font-size: 1rem; }
.bracket-round-summary { padding: 0.65rem 0.85rem; }
.bracket-round-body { padding: 0 0.65rem 0.65rem; }
.bracket-matchup { padding: 0.4rem 0.5rem; }
.bracket-team {
font-size: 0.8rem;
grid-template-columns: 20px 1fr auto auto;
gap: 0.35rem;
}
.bracket-team-logo { width: 20px; height: 20px; }
.playoff-mode .section-heading-gold { letter-spacing: 0.14em; }
}
/* ── Playoff Banner ─────────────────────────────── */
.playoff-banner {
display: flex;
align-items: center;
justify-content: center;
gap: 1rem;
padding: 1rem 1.25rem 1.125rem;
background: var(--banner-bg);
position: relative;
}
.playoff-banner::after {
content: "";
position: absolute;
left: 12%;
right: 12%;
bottom: 0;
height: 1px;
background: linear-gradient(
90deg,
transparent,
rgba(212, 175, 55, 0.45) 30%,
rgba(245, 215, 110, 0.6) 50%,
rgba(212, 175, 55, 0.45) 70%,
transparent
);
pointer-events: none;
}
.playoff-banner.hidden {
display: none;
}
.banner-main {
display: flex;
align-items: center;
gap: 1rem;
min-width: 0;
color: inherit;
text-decoration: none;
border-radius: 10px;
padding: 0.25rem 0.5rem;
transition: background 120ms ease;
}
.banner-main:hover,
.banner-main:focus-visible {
background: rgba(212, 175, 55, 0.08);
}
.banner-main:focus-visible {
outline: 2px solid var(--cup-gold-1);
outline-offset: 2px;
}
.banner-trophy {
width: 36px;
height: 44px;
flex-shrink: 0;
filter: drop-shadow(0 0 6px rgba(212, 175, 55, 0.25));
}
.banner-text {
min-width: 0;
text-align: center;
}
.banner-title {
font-size: 0.95rem;
font-weight: 800;
letter-spacing: 0.12em;
background: var(--gold-gradient);
-webkit-background-clip: text;
background-clip: text;
color: transparent;
line-height: 1.2;
}
.banner-year {
color: var(--cup-silver-2);
-webkit-text-fill-color: var(--cup-silver-2);
font-weight: 700;
margin-left: 0.35rem;
}
.banner-meta {
margin-top: 0.2rem;
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: 0.4rem 0.7rem;
font-size: 0.75rem;
color: var(--cup-silver-1);
letter-spacing: 0.03em;
}
.banner-meta > span.hidden { display: none; }
.banner-meta > span:not(.hidden) + span:not(.hidden)::before {
content: "\00b7";
color: var(--cup-gold-dim);
margin-right: 0.7rem;
}
.meta-elim, .meta-game7 {
color: var(--cup-gold-2);
font-weight: 700;
}
@media (min-width: 900px) {
.playoff-banner {
padding: 1.125rem 2rem;
gap: 1.25rem;
}
.banner-trophy { width: 44px; height: 54px; }
.banner-title { font-size: 1.15rem; }
.banner-meta { font-size: 0.85rem; }
}
@media (max-width: 640px) {
.playoff-banner {
padding: 0.75rem 1rem;
}
}
/* ── Playoff Game Cards ─────────────────────────── */
.playoff-mode .section-heading {
color: var(--cup-gold-1);
opacity: 0.85;
}
.playoff-mode .section-heading-gold {
background: var(--gold-gradient);
-webkit-background-clip: text;
background-clip: text;
color: transparent;
-webkit-text-fill-color: transparent;
letter-spacing: 0.18em;
font-weight: 800;
opacity: 1;
}
.game-box-playoff {
background:
linear-gradient(var(--card), var(--card)) padding-box,
var(--gold-gradient) border-box;
border: 1px solid transparent;
border-top-width: 3px;
}
.game-box-pinned {
box-shadow: 0 0 0 1px rgba(212, 175, 55, 0.35),
0 6px 20px rgba(212, 175, 55, 0.1);
}
.game-box-sudden-death {
border-top-width: 3px;
animation: pulse-gold 2.2s ease-in-out infinite;
}
@keyframes pulse-gold {
0%, 100% {
box-shadow: 0 0 0 1px rgba(212, 175, 55, 0.35),
0 0 10px rgba(212, 175, 55, 0.25);
}
50% {
box-shadow: 0 0 0 1px rgba(245, 215, 110, 0.75),
0 0 22px rgba(245, 215, 110, 0.45);
}
}
/* Playoff context row above the period badges */
.playoff-context {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 0.35rem 0.6rem;
margin-bottom: 0.5rem;
padding-bottom: 0.5rem;
border-bottom: 1px solid var(--card-border);
}
.series-summary {
font-size: 0.72rem;
color: var(--cup-silver-1);
font-weight: 600;
letter-spacing: 0.02em;
}
/* Playoff stake badges */
.badge-round {
background: rgba(212, 175, 55, 0.08);
color: var(--cup-gold-1);
border: 1px solid rgba(212, 175, 55, 0.28);
}
.badge-round-link {
text-decoration: none;
transition: border-color 0.12s ease, color 0.12s ease, background 0.12s ease;
}
.badge-round-link:hover {
border-color: var(--cup-gold-1);
color: var(--cup-gold-2);
background: rgba(212, 175, 55, 0.16);
}
.badge-conf {
background: rgba(79, 195, 247, 0.12);
color: var(--ice-accent);
border-color: rgba(79, 195, 247, 0.4);
}
.badge-cup {
background: linear-gradient(90deg, rgba(212, 175, 55, 0.25), rgba(245, 215, 110, 0.25));
color: #1a1200;
border: 1px solid var(--cup-gold-1);
font-weight: 800;
}
.badge-game7 {
background: linear-gradient(90deg, var(--cup-gold-dim), var(--cup-gold-1));
color: #1a1200;
border: 1px solid var(--cup-gold-2);
font-weight: 800;
letter-spacing: 0.1em;
}
.badge-clincher {
background: rgba(239, 68, 68, 0.15);
color: #fca5a5;
border: 1px solid rgba(239, 68, 68, 0.45);
}
.badge-pivotal {
background: rgba(79, 195, 247, 0.12);
color: var(--ice-accent);
border: 1px solid rgba(79, 195, 247, 0.4);
}
.badge-sudden-death {
background: linear-gradient(90deg, var(--cup-gold-dim), var(--cup-gold-1));
color: #1a1200;
border: 1px solid var(--cup-gold-2);
font-weight: 800;
letter-spacing: 0.08em;
}
.series-blurb {
margin-top: 0.65rem;
padding-top: 0.55rem;
border-top: 1px solid var(--card-border);
font-size: 0.72rem;
color: var(--cup-silver-1);
letter-spacing: 0.01em;
font-style: italic;
text-align: center;
}
/* In playoff mode, retint the hype meter to silver → gold */
.playoff-mode .hype-label {
color: var(--cup-silver-dim);
}
/* Override the red live dot with gold for playoff-mode bodies */
.playoff-mode .game-box-playoff .live-dot {
background: var(--cup-gold-1);
box-shadow: 0 0 6px rgba(245, 215, 110, 0.7);
}
@media (min-width: 900px) {
.series-summary { font-size: 0.82rem; }
.series-blurb { font-size: 0.82rem; }
}
@media (min-width: 1400px) {
.series-summary { font-size: 0.9rem; }
.series-blurb { font-size: 0.9rem; }
}
.series-header {
display: flex;
align-items: center;
justify-content: space-between;
gap: 1rem;
padding: 1rem 1.25rem 0.25rem;
}
.series-header .header-title {
font-size: 1.3rem;
}
/* Clickable playoff card wrapper */
.series-link {
display: contents;
color: inherit;
text-decoration: none;
}
.series-link .game-box {
cursor: pointer;
transition: transform 0.12s ease, box-shadow 0.12s ease;
}
.series-link:hover .game-box {
transform: translateY(-2px);
box-shadow:
0 2px 4px rgba(0, 0, 0, 0.45),
0 10px 24px rgba(0, 0, 0, 0.35),
0 0 0 1px rgba(212, 175, 55, 0.35);
}
.series-link:focus-visible .game-box {
outline: 2px solid var(--cup-gold-2);
outline-offset: 2px;
}
/* ── Series detail page (/series/<id>) ──────────── */
.header-link {
text-decoration: none;
color: var(--cup-silver-2);
}
.series-main {
padding: 1rem 1.25rem 3rem;
max-width: 1000px;
margin: 0 auto;
display: flex;
flex-direction: column;
gap: 1.5rem;
}
.series-hero {
background: var(--banner-bg);
border: 1px solid var(--cup-gold-dim);
border-radius: var(--radius);
padding: 1.25rem;
display: flex;
flex-direction: column;
gap: 1rem;
align-items: center;
text-align: center;
}
.series-hero-eyebrow {
display: flex;
gap: 0.4rem;
flex-wrap: wrap;
justify-content: center;
}
.series-teams {
display: grid;
grid-template-columns: 1fr 1fr;
align-items: center;
gap: 1rem;
width: 100%;
}
.series-team {
display: flex;
flex-direction: column;
align-items: center;
gap: 0.35rem;
padding: 0.5rem;
border-radius: 10px;
border: 1px solid transparent;
}
.series-team-leader {
border-color: var(--cup-gold-dim);
background: rgba(212, 175, 55, 0.06);
}
.series-team-logo {
width: 72px;
height: 72px;
object-fit: contain;
}
.series-team-name {
font-weight: 600;
font-size: 1.05rem;
color: var(--cup-silver-2);
}
.series-team-meta {
font-size: 0.78rem;
color: var(--cup-silver-dim);
letter-spacing: 0.04em;
text-transform: uppercase;
}
.series-team-wins {
font-size: 2.5rem;
font-weight: 700;
color: var(--cup-gold-2);
line-height: 1;
margin-top: 0.25rem;
}
.series-next-card {
background: var(--card);
border: 1px solid var(--cup-gold-dim);
border-radius: 10px;
padding: 0.9rem 1rem;
display: flex;
flex-direction: column;
gap: 0.4rem;
align-items: center;
margin-top: 0.6rem;
}
.series-next-matchup {
display: flex;
gap: 0.6rem;
align-items: center;
font-size: 1.2rem;
font-weight: 600;
}
.series-next-team {
color: var(--cup-silver-2);
}
.series-next-at {
color: var(--cup-silver-dim);
font-size: 0.9rem;
}
.series-next-meta {
font-size: 0.85rem;
color: var(--cup-silver-1);
text-align: center;
}
.series-games {
list-style: none;
display: flex;
flex-direction: column;
gap: 0.5rem;
margin-top: 0.6rem;
}
.series-game {
display: grid;
grid-template-columns: 90px 1fr auto;
gap: 0.75rem;
align-items: center;
padding: 0.7rem 0.9rem;
background: var(--card);
border: 1px solid var(--card-border);
border-radius: 10px;
}
.series-game-live,
.series-game-completed {
border-color: var(--cup-gold-dim);
}
.series-game-col-number {
font-weight: 600;
color: var(--cup-silver-1);
letter-spacing: 0.03em;
font-size: 0.85rem;
}
.series-game-col-matchup {
display: flex;
flex-direction: column;
gap: 0.2rem;
}
.series-game-team {
display: flex;
justify-content: space-between;
gap: 0.6rem;
font-size: 0.95rem;
}
.series-game-abbrev {
font-weight: 600;
color: var(--cup-silver-2);
}
.series-game-score {
color: var(--cup-silver-1);
font-variant-numeric: tabular-nums;
min-width: 1.6em;
text-align: right;
}
.series-game-winner {
color: var(--cup-gold-2);
font-weight: 700;
}
.series-game-state {
font-size: 0.8rem;
color: var(--cup-silver-dim);
text-align: right;
}
@media (max-width: 600px) {
.series-teams {
grid-template-columns: 1fr;
}
.series-team-logo {
width: 56px;
height: 56px;
}
.series-game {
grid-template-columns: 70px 1fr;
}
.series-game-col-state {
grid-column: 1 / -1;
text-align: left;
}
.series-game-state {
text-align: left;
}
}
/* ── Bracket page (/bracket) ─────────────────────── */
.bracket-main {
padding: 1rem 1.25rem 3rem;
max-width: 1800px;
margin: 0 auto;
}
.bracket-hero {
text-align: center;
margin-bottom: 1.5rem;
}
.bracket-title {
font-size: 1.6rem;
font-weight: 700;
color: var(--cup-silver-2);
letter-spacing: 0.05em;
background: var(--gold-gradient);
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
}
.bracket-subtitle {
color: var(--cup-silver-dim);
font-size: 0.9rem;
margin-top: 0.25rem;
}
/* Desktop grid layout */
.bracket-grid {
display: grid;
grid-template-columns: repeat(7, minmax(0, 1fr));
gap: 0.75rem;
align-items: stretch;
}
.bracket-col {
display: flex;
flex-direction: column;
justify-content: space-around;
gap: 0.6rem;
}
.bracket-col-heading {
font-size: 0.72rem;
letter-spacing: 0.1em;
text-transform: uppercase;
color: var(--cup-silver-dim);
text-align: center;
margin-bottom: 0.25rem;
}
.bracket-cup-heading {
color: var(--cup-gold-2);
}
.bracket-col-cup {
justify-content: center;
}
.bracket-matchup {
display: flex;
flex-direction: column;
gap: 2px;
background: var(--card);
border: 1px solid var(--card-border);
border-radius: 8px;
padding: 0.45rem 0.55rem;
text-decoration: none;
color: inherit;
transition: border-color 0.12s ease, transform 0.12s ease;
}
.bracket-matchup:hover {
border-color: var(--cup-gold-1);
transform: translateY(-1px);
}
.bracket-matchup:focus-visible {
outline: 2px solid var(--cup-gold-2);
outline-offset: 2px;
}
.bracket-matchup-active {
border-color: var(--cup-gold-dim);
}
.bracket-matchup-complete {
opacity: 0.55;
}
.bracket-col-active {
color: var(--cup-gold-2);
border-bottom: 2px solid var(--cup-gold-1);
padding-bottom: 0.2rem;
}
.bracket-matchup-empty {
background: transparent;
border-style: dashed;
}
.bracket-col-cup .bracket-matchup {
border-color: var(--cup-gold-dim);
background: var(--banner-bg);
padding: 0.7rem 0.6rem;
}
.bracket-col-cup .bracket-matchup:hover {
border-color: var(--cup-gold-2);
}
.bracket-team {
display: grid;
grid-template-columns: 22px 1fr auto auto;
align-items: center;
gap: 0.4rem;
padding: 0.2rem 0;
font-size: 0.85rem;
}
.bracket-team-logo {
width: 22px;
height: 22px;
object-fit: contain;
}
.bracket-team-abbrev {
font-weight: 600;
color: var(--cup-silver-2);
}
.bracket-team-seed {
font-size: 0.7rem;
color: var(--cup-silver-dim);
letter-spacing: 0.03em;
}
.bracket-team-wins {
font-variant-numeric: tabular-nums;
min-width: 1.2em;
text-align: right;
color: var(--cup-silver-1);
font-weight: 600;
}
.bracket-team-winner {
color: var(--cup-gold-2);
}
.bracket-team-winner .bracket-team-abbrev,
.bracket-team-winner .bracket-team-wins {
color: var(--cup-gold-2);
}
.bracket-team-placeholder {
color: var(--cup-silver-dim);
text-align: center;
padding: 0.3rem 0;
font-size: 0.8rem;
grid-template-columns: 1fr;
}
/* Mobile accordion — hidden on desktop */
.bracket-accordion {
display: none;
flex-direction: column;
gap: 0.75rem;
margin-top: 1rem;
}
.bracket-round {
background: var(--card);
border: 1px solid var(--card-border);
border-radius: 10px;
overflow: hidden;
}
.bracket-round-summary {
padding: 0.8rem 1rem;
cursor: pointer;
font-weight: 600;
color: var(--cup-gold-1);
letter-spacing: 0.03em;
list-style: none;
display: flex;
justify-content: space-between;
align-items: center;
}
.bracket-round-summary::after {
content: "+";
color: var(--cup-silver-dim);
font-size: 1.2rem;
}
.bracket-round[open] .bracket-round-summary::after {
content: "";
}
.bracket-round-body {
padding: 0 0.8rem 0.8rem;
display: flex;
flex-direction: column;
gap: 0.8rem;
}
.bracket-round-half-heading {
font-size: 0.7rem;
letter-spacing: 0.1em;
text-transform: uppercase;
color: var(--cup-silver-dim);
margin-bottom: 0.3rem;
}
.bracket-round-half {
display: flex;
flex-direction: column;
gap: 0.4rem;
}
/* Switch layout at narrow widths */
@media (max-width: 900px) {
.bracket-grid { display: none; }
.bracket-accordion { display: flex; }
}
/* Scale up the bracket on wide displays so it fills the screen */
@media (min-width: 1400px) {
.bracket-main { padding: 1.5rem 2rem 4rem; }
.bracket-title { font-size: 2rem; }
.bracket-subtitle { font-size: 1rem; }
.bracket-grid { gap: 1rem; }
.bracket-col { gap: 0.85rem; }
.bracket-col-heading { font-size: 0.85rem; margin-bottom: 0.4rem; }
.bracket-matchup { padding: 0.65rem 0.75rem; border-radius: 10px; }
.bracket-col-cup .bracket-matchup { padding: 0.95rem 0.85rem; }
.bracket-team {
grid-template-columns: 28px 1fr auto auto;
gap: 0.55rem;
padding: 0.3rem 0;
font-size: 1rem;
}
.bracket-team-logo { width: 28px; height: 28px; }
.bracket-team-seed { font-size: 0.8rem; }
}
@media (min-width: 1900px) {
.bracket-main { padding: 2rem 2.5rem 5rem; max-width: 2200px; }
.bracket-title { font-size: 2.5rem; }
.bracket-subtitle { font-size: 1.15rem; }
.bracket-grid { gap: 1.25rem; }
.bracket-col { gap: 1rem; }
.bracket-col-heading { font-size: 1rem; margin-bottom: 0.55rem; }
.bracket-matchup { padding: 0.85rem 0.95rem; border-radius: 12px; }
.bracket-col-cup .bracket-matchup { padding: 1.2rem 1rem; }
.bracket-team {
grid-template-columns: 36px 1fr auto auto;
gap: 0.7rem;
padding: 0.4rem 0;
font-size: 1.15rem;
}
.bracket-team-logo { width: 36px; height: 36px; }
.bracket-team-seed { font-size: 0.9rem; }
}