iStackyyy.
No session loaded

Ask your host for the session link, or paste the session code above.

--surface: #181F1D; --surface-raised: #202927; --surface-hover: #263330; --ink: var(--line-tape); --ink-muted: #8A9E96; --border-soft: rgba(242,244,240,0.07); --border-card: rgba(242,244,240,0.05); --court-green: var(--court-paint); --court-green-dark: var(--court-paint-deep); --court-green-mid: var(--court-paint-mid); --accent: var(--optic-yellow); --accent-ink: var(--optic-yellow-ink); --accent-glow: rgba(215,242,61,0.22); --winner-green: #4ECB7E; --loser-coral: var(--fault-coral); --resting-slate: var(--bench-slate); --waiting-blue: #6FA8E0; --line-paint: var(--line-tape); --kitchen-gold: var(--optic-yellow); --shadow-card: 0 1px 8px rgba(0,0,0,0.45), 0 0 0 1px rgba(242,244,240,0.04); --shadow-raised: 0 6px 28px rgba(0,0,0,0.55), 0 0 0 1px rgba(242,244,240,0.06); --watermark-opacity: 0.035; --net-glow: 0 0 18px 4px rgba(215,242,61,0.18), 0 0 6px 1px rgba(215,242,61,0.28); } html[data-theme="light"] { --night-court: #F0EDE4; --court-paint: #1B4D3E; --court-paint-deep: #123329; --court-paint-mid: #1A4339; --optic-yellow: #5E7A0A; --optic-yellow-ink: #FFFFFF; --line-tape: #15201C; --bench-slate: #8E9B97; --fault-coral: #D9523A; --bg: var(--night-court); --surface: #FAFAF7; --surface-raised: #FFFFFF; --surface-hover: #EAE7DD; --ink: var(--line-tape); --ink-muted: #5A6E67; --border-soft: rgba(21,32,28,0.09); --border-card: rgba(21,32,28,0.07); --court-green: var(--court-paint); --court-green-dark: var(--court-paint-deep); --court-green-mid: var(--court-paint-mid); --accent: var(--optic-yellow); --accent-ink: var(--optic-yellow-ink); --accent-glow: rgba(94,122,10,0.18); --winner-green: #2F9A5C; --loser-coral: var(--fault-coral); --resting-slate: var(--bench-slate); --waiting-blue: #4E7FB5; --line-paint: #F7F5EF; --kitchen-gold: var(--optic-yellow); --shadow-card: 0 1px 6px rgba(21,32,28,0.1), 0 0 0 1px rgba(21,32,28,0.06); --shadow-raised: 0 4px 20px rgba(21,32,28,0.15), 0 0 0 1px rgba(21,32,28,0.07); --watermark-opacity: 0.03; --net-glow: 0 0 14px 3px rgba(94,122,10,0.2), 0 0 5px 1px rgba(94,122,10,0.3); } :root { --font-display: 'Archivo Black', 'Arial Black', sans-serif; --font-body: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif; --font-mono: 'JetBrains Mono', 'Courier New', monospace; --radius: 10px; --radius-sm: 7px; --radius-xs: 4px; --kitchen-gold: var(--optic-yellow); --ease-bounce: cubic-bezier(0.34, 1.56, 0.64, 1); --ease-serve: cubic-bezier(0.22, 0.68, 0.36, 1); --ease-settle: cubic-bezier(0.16, 1, 0.3, 1); --dur-fast: 180ms; --dur-base: 340ms; --dur-shuffle: 450ms; --dur-pulse: 900ms; } *, *::before, *::after { box-sizing: border-box; -webkit-tap-highlight-color: transparent; } html { color-scheme: dark; } html[data-theme="light"] { color-scheme: light; } html, body { margin: 0; padding: 0; background: var(--bg); color: var(--ink); font-family: var(--font-body); overflow-x: hidden; transition: background var(--dur-base) var(--ease-settle), color var(--dur-base) var(--ease-settle); } h1, h2, h3, .display { font-family: var(--font-display); letter-spacing: -0.01em; text-transform: uppercase; } a { color: inherit; } button { font-family: var(--font-body); cursor: pointer; touch-action: manipulation; } ::selection { background: var(--accent); color: var(--accent-ink); } :focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 3px; } .mono { font-family: var(--font-mono); font-variant-numeric: tabular-nums; } /* Mono on all live-updating numbers */ .court-timer, .lane-pos, .lane-header .count, .recent-result-score, .recent-result-duration, .lb-stat, .lb-pts { font-family: var(--font-mono); font-variant-numeric: tabular-nums; } @media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation-duration: 0.001ms !important; animation-iteration-count: 1 !important; transition-duration: 0.001ms !important; } } input, select, textarea { font-size: 16px; min-height: 44px; background: var(--surface-raised); color: var(--ink); border-color: var(--border-soft); } button { min-height: 44px; } /* ── Animation keyframes (all existing hooks unchanged) ── */ @keyframes realtime-pulse { 0% { box-shadow: 0 0 0 0 var(--accent-glow); } 35% { box-shadow: 0 0 0 6px var(--accent-glow); } 100% { box-shadow: 0 0 0 0 rgba(0,0,0,0); } } .pulse-update { animation: realtime-pulse var(--dur-pulse) var(--ease-settle); } @keyframes drop-settle { 0% { opacity: 0; transform: translateY(-14px) scale(0.97); } 60% { opacity: 1; } 100% { opacity: 1; transform: translateY(0) scale(1); } } .drop-in { animation: drop-settle var(--dur-base) var(--ease-bounce) both; } .stagger-item { animation: drop-settle var(--dur-base) var(--ease-bounce) both; } .stagger-item:nth-child(1) { animation-delay: 0ms; } .stagger-item:nth-child(2) { animation-delay: 40ms; } .stagger-item:nth-child(3) { animation-delay: 80ms; } .stagger-item:nth-child(4) { animation-delay: 120ms; } .stagger-item:nth-child(5) { animation-delay: 160ms; } .stagger-item:nth-child(6) { animation-delay: 200ms; } .stagger-item:nth-child(7) { animation-delay: 240ms; } .stagger-item:nth-child(8) { animation-delay: 280ms; } @keyframes serve-in { 0% { opacity: 0; transform: translate(-10px, 8px) rotate(-1.2deg); } 100% { opacity: 1; transform: translate(0, 0) rotate(0deg); } } .serve-in { animation: serve-in var(--dur-fast) var(--ease-serve) both; } /* ── Signature: bouncing ball — use #2 of 3 optic-yellow uses ── */ @keyframes ball-bounce { 0% { transform: translateX(0) translateY(0); animation-timing-function: var(--ease-serve); } 20% { transform: translateX(40px) translateY(-28px); animation-timing-function: cubic-bezier(0.55, 0, 1, 0.45); } 38% { transform: translateX(80px) translateY(0); animation-timing-function: var(--ease-serve); } 55% { transform: translateX(100px) translateY(-14px); animation-timing-function: cubic-bezier(0.55, 0, 1, 0.45); } 68% { transform: translateX(120px) translateY(0); animation-timing-function: var(--ease-settle); } 100% { transform: translateX(120px) translateY(0); } } @keyframes ball-line-grow { 0% { width: 0; opacity: 0; } 38% { width: 80px; opacity: 1; } 68% { width: 120px; opacity: 1; } 100% { width: 120px; opacity: 0.35; } } .ball-loading { display: flex; flex-direction: column; align-items: flex-start; justify-content: center; min-height: 80px; padding: 24px 0 24px 24px; position: relative; } .ball-loading::before { content: ''; display: block; width: 10px; height: 10px; border-radius: 50%; background: var(--optic-yellow); position: absolute; bottom: 24px; left: 24px; animation: ball-bounce 1.1s var(--ease-bounce) infinite; box-shadow: 0 0 8px 2px rgba(215,242,61,0.35); } .ball-loading::after { content: ''; display: block; height: 1.5px; background: var(--bench-slate); position: absolute; bottom: 24px; left: 24px; animation: ball-line-grow 1.1s var(--ease-settle) infinite; } .ball-loading-label { font-size: 11px; font-weight: 700; color: var(--bench-slate); text-transform: uppercase; letter-spacing: 0.1em; margin-bottom: 28px; } @media (prefers-reduced-motion: reduce) { .ball-loading::before { animation: none; bottom: 22px; left: 60px; } .ball-loading::after { animation: none; width: 120px; opacity: 0.3; } } /* ── Theme toggle ── */ .theme-toggle { background: rgba(242,244,240,0.07); border: 1px solid rgba(242,244,240,0.1); border-radius: 999px; width: 36px; height: 36px; display: flex; align-items: center; justify-content: center; transition: transform var(--dur-fast) var(--ease-bounce), background var(--dur-fast) var(--ease-settle); flex-shrink: 0; } .theme-toggle:hover { transform: scale(1.1) rotate(-12deg); } .theme-toggle:active { transform: scale(0.92); } .theme-toggle svg { width: 16px; height: 16px; color: var(--line-paint); opacity: 0.7; } /* ── Watermark — correct pickleball court geometry ── */ body::before { content: ''; position: fixed; inset: 0; z-index: 0; pointer-events: none; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 900 560' preserveAspectRatio='xMidYMid slice'%3E%3Cg stroke='%23F2F4F0' fill='none'%3E%3Crect x='80' y='50' width='740' height='460' stroke-width='2.5'/%3E%3Cline x1='80' y1='280' x2='820' y2='280' stroke-width='3'/%3E%3Cline x1='80' y1='124' x2='820' y2='124' stroke-width='1.5'/%3E%3Cline x1='80' y1='436' x2='820' y2='436' stroke-width='1.5'/%3E%3Cline x1='450' y1='50' x2='450' y2='124' stroke-width='1.5'/%3E%3Cline x1='450' y1='436' x2='450' y2='510' stroke-width='1.5'/%3E%3C/g%3E%3C/svg%3E"); background-size: cover; opacity: var(--watermark-opacity); } body { padding-bottom: 88px; position: relative; z-index: 1; } /* ── Topbar ── */ .topbar { background: var(--court-paint-deep); border-bottom: 1px solid rgba(242,244,240,0.07); color: var(--line-paint); padding: 13px 18px; display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 10px; position: sticky; top: 0; z-index: 10; } .brand { display: flex; align-items: center; gap: 9px; } .brand-paddle { width: 19px; height: 26px; color: var(--line-paint); opacity: 0.8; flex-shrink: 0; } .brand .display { font-size: 19px; color: var(--line-paint); letter-spacing: 0.01em; } .brand .dot { color: rgba(215,242,61,0.55); } .session-name { font-size: 12px; opacity: 0.55; font-weight: 600; letter-spacing: 0.04em; } .session-picker { display: flex; gap: 8px; align-items: center; } .session-picker input { font-family: var(--font-mono); padding: 10px 12px; border-radius: var(--radius-sm); border: 1px solid rgba(242,244,240,0.16); width: 220px; font-size: 16px; background: rgba(242,244,240,0.09); color: white; font-variant-numeric: tabular-nums; } .session-picker input::placeholder { color: rgba(242,244,240,0.4); } .session-picker button { background: var(--court-paint); color: white; border: none; font-weight: 700; padding: 9px 14px; border-radius: var(--radius-sm); font-size: 13px; } .container { max-width: 1200px; margin: 0 auto; padding: 20px 18px; position: relative; z-index: 1; } /* ── Court cards ── */ .courts-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(268px, 1fr)); gap: 16px; margin-bottom: 28px; } .court-card { background: var(--surface); border-radius: var(--radius); box-shadow: var(--shadow-card); border: 1px solid var(--border-card); overflow: hidden; transition: transform var(--dur-fast) var(--ease-bounce), box-shadow var(--dur-fast) var(--ease-settle); } .court-card:hover { transform: translateY(-3px) scale(1.01); box-shadow: var(--shadow-raised); } .court-label { background: var(--court-paint-deep); color: var(--line-paint); padding: 9px 14px; display: flex; justify-content: space-between; align-items: center; border-bottom: 1px solid rgba(242,244,240,0.06); } .court-label .num { font-family: var(--font-display); font-size: 13px; letter-spacing: 0.06em; } /* Live timer: optic-yellow — use #1 of 3 */ .court-timer { font-family: var(--font-mono); font-weight: 700; font-size: 14px; color: var(--optic-yellow); font-variant-numeric: tabular-nums; letter-spacing: 0.05em; } .court-timer.idle { color: var(--bench-slate); font-weight: 500; } .court-diagram { background: linear-gradient(175deg, var(--court-paint) 0%, var(--court-paint-deep) 100%); aspect-ratio: 4/5; position: relative; display: flex; flex-direction: column; padding: 13px; overflow: hidden; } .court-diagram::before { content: ''; position: absolute; inset: 13px; border: 2px solid var(--line-paint); opacity: 0.75; z-index: 1; } /* Net glow: only on the net line when court-active */ .net-line { position: absolute; left: 13px; right: 13px; top: 50%; height: 2px; background: var(--line-paint); transform: translateY(-50%); opacity: 0.82; z-index: 2; transition: box-shadow var(--dur-base) var(--ease-settle); } .court-card.court-active .net-line { box-shadow: var(--net-glow); opacity: 0.95; } .net-line::after { content: ''; position: absolute; left: 0; right: 0; top: -3px; bottom: -3px; background: repeating-linear-gradient(90deg, rgba(10,22,19,0.45) 0 4px, transparent 4px 9px); } .net-ball { position: absolute; width: 16px; height: 16px; left: 50%; top: 50%; transform: translate(-50%,-50%); color: var(--optic-yellow); z-index: 4; filter: drop-shadow(0 1px 3px rgba(0,0,0,0.4)); } .kitchen-line-top, .kitchen-line-bottom { position: absolute; left: 13px; right: 13px; height: 1.5px; background: var(--line-paint); opacity: 0.45; z-index: 2; } .kitchen-line-top { top: 32%; } .kitchen-line-bottom { bottom: 32%; } .centerline-top, .centerline-bottom { position: absolute; left: 50%; width: 1.5px; background: var(--line-paint); opacity: 0.45; transform: translateX(-50%); z-index: 2; } .centerline-top { top: 13px; height: calc(32% - 13px); } .centerline-bottom { bottom: 13px; height: calc(32% - 13px); } .court-side { flex: 1; display: flex; align-items: center; justify-content: space-evenly; position: relative; z-index: 3; padding: 8px 13px; } .empty-court-msg { flex: 1; display: flex; align-items: center; justify-content: center; color: var(--bench-slate); opacity: 0.55; font-size: 11px; font-weight: 700; z-index: 3; text-transform: uppercase; letter-spacing: 0.1em; } .paddle-chip { display: flex; flex-direction: column; align-items: center; gap: 2px; width: 82px; flex: 1 1 0; max-width: 106px; } .paddle-chip-shape { width: 100%; aspect-ratio: 48/64; position: relative; filter: drop-shadow(0 2px 5px rgba(0,0,0,0.38)); } .paddle-chip-shape svg { width: 100%; height: 100%; display: block; color: var(--line-paint); } .paddle-chip-name { position: absolute; top: 30%; left: 50%; transform: translate(-50%,-50%); width: 74%; font-size: 12px; font-weight: 800; color: var(--court-paint-deep); text-align: center; line-height: 1.15; overflow: hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; word-break: break-word; } /* ── Divider ── */ .court-line-divider { height: 1px; margin: 16px 0; background: var(--border-soft); } /* ── Queue lanes ── */ .queues { display: grid; grid-template-columns: repeat(auto-fit, minmax(245px, 1fr)); gap: 12px; margin-bottom: 26px; } .lane { background: var(--surface); border-radius: var(--radius); box-shadow: var(--shadow-card); border: 1px solid var(--border-card); overflow: hidden; } .lane-header { padding: 10px 15px; font-family: var(--font-display); font-size: 11px; letter-spacing: 0.07em; color: white; display: flex; justify-content: space-between; align-items: center; } .lane-header .count { font-family: var(--font-mono); opacity: 0.85; font-variant-numeric: tabular-nums; } .lane.waiting .lane-header { background: var(--waiting-blue); } .lane.resting .lane-header { background: var(--bench-slate); } .lane.expected .lane-header { background: var(--court-paint-deep); } .lane-list { list-style: none; margin: 0; padding: 5px; min-height: 54px; } .lane-item { padding: 8px 10px; border-bottom: 1px solid var(--border-soft); font-size: 13px; font-weight: 600; display: flex; justify-content: space-between; align-items: center; transition: background var(--dur-fast) var(--ease-settle), padding-left var(--dur-fast) var(--ease-bounce); border-radius: var(--radius-xs); } .lane-item:hover { background: var(--surface-hover); padding-left: 14px; } .lane-item:last-child { border-bottom: none; } /* Queue #1: optic-yellow — use #3 of 3. Only the position number, not the name. */ .lane-item:first-child .lane-pos { color: var(--optic-yellow); font-weight: 800; } .lane-pos { font-family: var(--font-mono); color: var(--bench-slate); font-weight: 700; font-size: 11px; font-variant-numeric: tabular-nums; } .result-badge { display: inline-flex; align-items: center; justify-content: center; width: 14px; height: 14px; border-radius: 3px; font-size: 9px; font-weight: 800; margin-left: 5px; } .result-badge.won { background: var(--winner-green); color: white; } .result-badge.lost { background: var(--fault-coral); color: white; } .lane-empty { padding: 14px; text-align: center; color: var(--bench-slate); font-size: 12px; } /* ── Find me ── */ .find-me { background: var(--court-paint-mid); border: 1px solid rgba(242,244,240,0.09); border-radius: var(--radius); padding: 13px 15px; margin-bottom: 22px; display: flex; gap: 10px; align-items: center; flex-wrap: wrap; } .find-me input { flex: 1; min-width: 180px; padding: 11px; border-radius: var(--radius-sm); border: 1px solid rgba(242,244,240,0.16); font-size: 16px; background: rgba(242,244,240,0.1); color: white; } .find-me input::placeholder { color: rgba(242,244,240,0.4); } .find-me-result { font-weight: 700; font-size: 13px; background: rgba(242,244,240,0.12); color: white; padding: 8px 12px; border-radius: var(--radius-sm); border: 1px solid rgba(242,244,240,0.18); } /* ── Recent results ── */ .recent-results { margin-bottom: 20px; } .recent-results-title { font-size: 10px; margin: 0 0 9px; color: var(--bench-slate); text-transform: uppercase; letter-spacing: 0.09em; font-weight: 700; padding-bottom: 7px; border-bottom: 1px solid var(--border-soft); } .recent-results-list { display: flex; flex-direction: column; gap: 5px; } .recent-result-row { background: var(--surface); box-shadow: var(--shadow-card); border: 1px solid var(--border-card); border-radius: var(--radius-sm); padding: 9px 13px; display: grid; grid-template-columns: 1fr auto 1fr auto; gap: 10px; align-items: center; font-size: 13px; font-weight: 600; } .recent-result-score { font-size: 13px; font-weight: 700; color: var(--bench-slate); text-align: center; font-family: var(--font-mono); font-variant-numeric: tabular-nums; } .recent-result-duration { font-size: 11px; color: var(--bench-slate); text-align: right; font-family: var(--font-mono); font-variant-numeric: tabular-nums; opacity: 0.7; } .winner-name { color: var(--winner-green); } /* ── Leaderboard (player view) ── */ .lb-card { background: var(--surface); border-radius: var(--radius); box-shadow: var(--shadow-card); border: 1px solid var(--border-card); padding: 17px; margin-bottom: 22px; } .lb-card-title { font-size: 13px; margin: 0 0 12px; letter-spacing: 0.03em; } .roster-table { width: 100%; border-collapse: collapse; font-size: 13px; } .roster-table th { text-align: left; padding: 7px 10px; color: var(--bench-slate); font-size: 9px; text-transform: uppercase; letter-spacing: 0.08em; border-bottom: 1px solid var(--border-soft); } .roster-table td { padding: 8px 10px; border-bottom: 1px solid var(--border-soft); } .roster-table tr:last-child td { border-bottom: none; } .table-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; margin: 0 -2px; } .lb-won { color: var(--winner-green); font-weight: 700; } .lb-lost { color: var(--fault-coral); } .lb-pts { color: var(--ink); font-weight: 700; font-family: var(--font-mono); font-variant-numeric: tabular-nums; } .lb-highlight { background: rgba(78,203,126,0.06); border-radius: 4px; } /* ── Rest + message ── */ .rest-request-box { background: var(--surface); border-radius: var(--radius); box-shadow: var(--shadow-card); border: 1px solid var(--border-card); padding: 15px; margin-bottom: 12px; } .rest-request-box h3 { font-size: 12px; margin: 0 0 10px; font-family: var(--font-display); letter-spacing: 0.03em; } .rest-request-row { display: flex; gap: 8px; flex-wrap: wrap; } .rest-request-row select { flex: 1; min-width: 160px; padding: 11px; border: 1px solid var(--border-soft); border-radius: var(--radius-sm); font-size: 16px; background: var(--surface-raised); color: var(--ink); } .rest-request-row button { background: var(--waiting-blue); color: white; border: none; padding: 11px 16px; border-radius: var(--radius-sm); font-weight: 700; font-size: 13px; white-space: nowrap; } .message-box { background: var(--surface); border-radius: var(--radius); box-shadow: var(--shadow-card); border: 1px solid var(--border-card); padding: 15px; } .message-box h3 { font-size: 12px; margin: 0 0 10px; font-family: var(--font-display); letter-spacing: 0.03em; } .message-row { display: flex; gap: 8px; flex-wrap: wrap; } .message-row input { padding: 11px; border: 1px solid var(--border-soft); border-radius: var(--radius-sm); font-size: 16px; background: var(--surface-raised); color: var(--ink); } .message-row input[name="from"] { width: 120px; } .message-row input[name="msg"] { flex: 1; min-width: 160px; } .message-row button { background: var(--court-paint); color: white; border: none; padding: 9px 16px; border-radius: var(--radius-sm); font-weight: 700; font-size: 13px; } .message-hint { font-size: 11px; color: var(--bench-slate); margin-top: 7px; } /* ── Empty state ── */ .empty-state { text-align: center; padding: 52px 20px; color: var(--bench-slate); } .empty-state .display { font-size: 16px; color: var(--ink); margin-bottom: 8px; } .empty-state-paddle { width: 50px; height: 68px; color: var(--court-paint); opacity: 0.18; margin-bottom: 16px; } /* Empty state gets ball-loading when connecting */ .empty-state.connecting .empty-state-paddle { display: none; } /* ── Mobile ── */ @media (max-width: 768px) { .container { padding: 13px 12px; } .topbar { padding: 11px 13px; flex-wrap: wrap; } .brand { flex: 1 1 100%; } .session-picker { flex: 1 1 100%; } .session-picker input { width: 100%; } .courts-grid { grid-template-columns: 1fr; gap: 10px; margin-bottom: 20px; } .queues { grid-template-columns: 1fr; gap: 10px; margin-bottom: 20px; } .court-diagram { aspect-ratio: 3/4; } .paddle-chip { width: 66px; } .paddle-chip-name { font-size: 11px; } .find-me { flex-direction: column; align-items: stretch; padding: 12px; } .find-me input { width: 100%; } .find-me-result { text-align: center; } .message-row { flex-direction: column; } .message-row input[name="from"], .message-row input[name="msg"], .message-row button { width: 100%; } .rest-request-row { flex-direction: column; } .rest-request-row select, .rest-request-row button { width: 100%; } .recent-result-row { grid-template-columns: 1fr 1fr; gap: 5px; } .recent-result-duration { text-align: right; } h1 { font-size: 16px; } } @media (max-width: 420px) { .brand .display { font-size: 16px; } .empty-state { padding: 32px 12px; } }
iStackyyy.
No session loaded

Ask your host for the session link, or paste the session code above.