diff --git a/package.json b/package.json index 1b46cc4..b509ad0 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "url": "git+https://github.com/0xferit/schelling-games.git" }, "keywords": [], - "author": "", + "author": "Ferit Tuncer", "license": "ISC", "type": "module", "bugs": { diff --git a/public/app.html b/public/app.html index b831391..d5fd3e0 100644 --- a/public/app.html +++ b/public/app.html @@ -60,7 +60,7 @@ - + @@ -71,10 +71,18 @@
-
-
Multiplayer coordination lobby
-

Schelling Games

-
+ + + Schelling Games +
- - + +
-

Sign In

@@ -125,7 +132,6 @@

Sign In

-
@@ -185,18 +191,15 @@

Public Queue

-
-
Commit
30
-
Game 1 / 10
@@ -220,7 +223,6 @@

Public Queue

-
-

Players

@@ -261,7 +262,6 @@

Leave Match

-
@@ -276,10 +276,10 @@

Final

Final stack
-
+
-
-
-
Start —
+
-
+
Start -
@@ -318,7 +318,6 @@

Final Stack

-
diff --git a/public/favicon.svg b/public/favicon.svg index ec2f892..38ae156 100644 --- a/public/favicon.svg +++ b/public/favicon.svg @@ -1,4 +1,10 @@ - - - S + + + + + + + + + diff --git a/public/index.html b/public/index.html index 6b63375..188983c 100644 --- a/public/index.html +++ b/public/index.html @@ -5,37 +5,36 @@ -Schelling Games — Coordination Theory Meets Crypto-Native Play +Schelling Games - Coordination Theory Meets Crypto-Native Play + content="Can you predict what strangers will choose? Schelling Games is a commit-reveal coordination game inspired by Thomas Schelling's focal point theory. Play now - no install required."/> - - - - - - + + + + + + - - - - + + + + - - + + - - + @@ -45,13 +44,13 @@ "@type": "WebApplication", "name": "Schelling Games", "url": "https://schelling.games/", - "description": "A commit-reveal coordination game inspired by Thomas Schelling's focal point theory. Players simultaneously commit secret choices, then reveal — plurality wins.", + "description": "A commit-reveal coordination game inspired by Thomas Schelling's focal point theory. Players simultaneously commit secret choices, then reveal - plurality wins.", "applicationCategory": "GameApplication", "browserRequirements": "Requires JavaScript. Requires an Ethereum-compatible browser wallet.", "inLanguage": "en", "author": { "@type": "Person", - "name": "Ferit Tunçer", + "name": "Ferit Tuncer", "url": "https://github.com/0xferit" }, "genre": ["Coordination Game", "Game Theory", "Blockchain Game"], @@ -67,392 +66,354 @@ - - -
- - -
- -
A coordination game
-

Think Like
Everyone Else

-

- No safe collusion. No shortcuts. Just you and a prompt. - Pick the answer you think most others will pick. -

- Play Now -
Ethereum wallet required · any EIP-1193 wallet works
-
- - -
-
- - -

Thomas Schelling

-

- In 1960, economist Thomas Schelling posed a deceptively simple question: - if two strangers had to meet in New York City with no way to communicate, - where would they go? Most people said Grand Central Station at noon. - He called these natural meeting points focal points and showed that - coordination without communication is not only possible, it is predictable. - Schelling won the 2005 Nobel Prize in Economics for his work on - conflict and cooperation through game-theory analysis. - This game is a playable adaptation of that idea, built around a fixed seed set of canonical coordination prompts. -

-
+ -
- - -
-
- -

Focal Points

-

- In 1960, economist Thomas Schelling discovered that people can coordinate - without communicating by gravitating toward answers that feel naturally - prominent: focal points. -

-
- People can often concert their intentions or expectations with - others if each knows that the other is trying to do the same. -
-

Thomas C. Schelling, The Strategy of Conflict (1960)

+ -
+ - -
-
- -

What if winning meant
agreeing with strangers?

-

- Schelling Games puts you in a room with other players. Everyone sees the same - Schelling prompt. Everyone picks an answer alone. Those who converge on the most - popular answer bucket split the pot. The rest lose their ante. -

-
-
-
01
-

No Safe Collusion

-

You can talk, but you cannot prove what you will pick. Anyone who tries to coordinate by pre-revealing their choice opens themselves up to betrayal. The mechanism is designed to make focal-point reasoning the most reliable approach.

-
-
-
02
-

Commit-Reveal

-

Answers are cryptographically locked before anyone reveals. You cannot simply wait to see what others chose, then copy them.

-
-
-
03
-

Plurality Wins

-

The most popular answer wins the game. If two answers tie for first, both groups win. Everyone else loses their ante.

-
-
-
04
-

10 Games

-

Each match is 10 games of different prompts. Over many games, consistent coordination is rewarded more than any single lucky guess.

+
+
+
+
+
+ Shared salience + Live multiplayer protocol + Commit -> Reveal -> Settle +
+
+
+

Coordination without communication

+

Schelling Games

+

Pick what you think everyone else will independently converge on. The answer gets sealed, revealed together, then rewarded by plurality.

+
+ Play Now +

Ethereum wallet required · any crowd from 3 to 21 players

+
+
+
+
+ Games Per Match + 10 +

The table resets every round, but the match rewards consistent coordination.

+
+
+ Winning Condition + Plurality +

The largest answer cluster wins. Ties split the pot. Cleverness does not beat salience.

+
+
+ Blind commitment + No reactive copying + Shared intuition wins +
+
+
+
-
-
+ - -
-
- -

Commit, reveal, normalize, settle

-
-
- I -

Commit

-

Read the prompt, pick your answer, lock it in with a cryptographic hash. 60 seconds. No take-backs.

-
-
- II -

Reveal

-

When commit closes, the reveal window opens. You submit the exact answer and salt behind your commitment so the hash can be verified.

-
-
- III -

Normalize

-

Open-text answers pass through an AI normalization step so equivalent signals such as NYC and New York can land in the same bucket.

+
+
+
+
+ New York / 1960 + The Strategy of Conflict + Focal points enter the room +
+
+ 19 + 60 +
+

Schelling frames coordination as a search for the answer that feels obvious enough to strangers.

-
- IV -

Settle

-

The plurality wins. An ante is collected from all players, then redistributed to those who converged. Any indivisible remainder is burned.

+
+ +

Meet Thomas Schelling

+

In 1960, economist Thomas Schelling published The Strategy of Conflict, a landmark study in how people coordinate without explicit communication. He found that, when pushed to guess what others will choose, people drift toward answers that feel prominent or natural. He called these focal points.

+

Schelling Games turns that idea into a live multiplayer format. Every round asks the same question in a harsher environment: can you find the answer that a room of strangers will independently recognize as the coordination target?

+
+ Nobel Prize in Economics, 2005 + Coordination without communication + Shared intuition as game mechanic +
-
-
+
- -
-
-
-
- -

What will the
crowd choose?

-

- 100 is the only non-prime, the only round number, and the only three-digit number in the set. - When you reason about what others will pick, that salience makes it the natural coordination target: the focal point. -

+
+
+
+ +

The protocol loop

+

Each game follows the same sealed cycle. Choices are committed before the table can read them, then opened together, then settled by plurality.

-
-
Pick the number you think most others will pick.
-
- -
- - - - - - - - - - - - - - - - - - -
+
+
+ 01 +

Commit

+

Read the prompt, pick your answer, hash it with a salt, and submit. The table can speculate, but it cannot see your actual choice yet.

+ Blind commitment +
+
+ 02 +

Reveal

+

When the commit window closes, everyone reveals the answer behind their hash. Select prompts verify exact options and open-text prompts verify canonical buckets.

+ Shared reveal window +
+
+ 03 +

Settle

+

The largest matching group wins. Ties split the pot. The mechanism rewards whatever answer a room of strangers can independently recognize as obvious.

+ Plurality payout +
-
-
- - -
-
+
- -
- -

What is a Schelling Point?

-

- A Schelling point (or focal point) is a solution people naturally converge on - without communicating. It works because some answers feel more obvious, more - prominent, or more "default" than others. -

-
- If two strangers are told to meet somewhere in New York City with no further - instructions, most choose Grand Central Station at noon. Nobody told them to. - It is simply the most obvious choice. -
- Adapted from Thomas Schelling, The Strategy of Conflict (1960) +
+
+
+ +

Salience becomes strategy

+

The mechanism works because every part of the loop points toward the same equilibrium. Plurality rewards convergence, commit-reveal removes reactive copying, and the prompt forces each player to model what the group will find most legible.

+
+
+ Plurality wins +

The best move is to identify the answer that feels most shared, not the answer that feels smartest.

+
+
+ Blind commitment +

Everyone crosses the same cryptographic boundary before they can inspect the table.

+
+
+ Truth as equilibrium +

When the salient answer is also the profitable answer, shared intuition becomes a stable coordination target.

+
+
+
+
+
+
+ Ethereum Context + 2014 / SchellingCoin + Mechanism beyond the game +
+

From theory to on-chain mechanism

+

Vitalik Buterin's early SchellingCoin idea pushed the same incentive shape into blockchain design: reward the report that matches the majority, and honest reporting can become the best strategy available. That logic later shows up in oracle systems, prediction market resolution, dispute systems, and governance coordination.

+
+
+
+ 01 +

Oracles

+

Decentralized price feeds rely on independent reporters converging on the same truth.

+
+
+ 02 +

Prediction Markets

+

Disputed outcomes can resolve through shared reporting instead of a single trusted judge.

+
+
+ 03 +

Decentralized Courts

+

Jurors are rewarded for arriving at the same verdict without direct coordination.

+
+
+ 04 +

Governance

+

Protocol communities can coordinate around parameters that feel publicly legible and stable.

+
-

- Schelling showed experimentally that people succeed at these coordination tasks - far more often than chance would predict. The key insight: shared context and - cultural salience create natural convergence points. -

+
- -
- -

Why does this mechanism work?

-

- Schelling Games turns focal-point theory into a playable incentive structure. - Four properties make it robust: -

-
-
-
01
-

Plurality Wins

-

The answer picked by the largest group wins. Ties split the pot. The Nash equilibrium is to pick the most obvious choice, not to be clever or contrarian.

+
+
+
+ +

What will the crowd choose?

+

One prompt. Eighteen options. The point is not your favorite answer, but the answer you think a room of strangers will independently recognize as the coordination target.

+
+
+
+ Single-prompt coordination puzzle + Blind pick + Plurality readout
-
-
02
-

Blind Commitment

-

Commit-reveal cryptography means you lock your answer before seeing anyone else's. No copying, no last-second switches.

+
+
+
Pick the number you think most others will pick.
+
+ +
+
+

When a number feels visibly more legible than the rest, it becomes the focal point.

+
+ One obvious outlier + No direct signaling + Shared salience wins +
+
-
-
03
-

Truth as Equilibrium

-

When the most obvious answer is always the best strategy, "pick what's salient" becomes the dominant play.

+
+ + + + + + + + + + + + + + + + + +
-
-
04
-

Beyond the Game

-

This is exactly why the mechanism is useful in the real world: it produces consensus without requiring trust or a central authority.

+
+

100 is the only non-prime, the only round number, and the only three-digit number in the set. That salience makes it the natural coordination target: the focal point.

+
+
- -
- -

Where Schelling games are used

-
-
-
Oracles
-

Decentralized Price Feeds

-

Example: a derivatives protocol needs the ETH/USD price at exactly 4:00 PM UTC to settle expiring contracts. Independent reporters submit the price they observed, and the coordinated result becomes the onchain settlement value, as in UMA's oracle and DVM.

-
-
-
Prediction Markets
-

Outcome Resolution

-

Example: a market asks whether a merger closed before the deadline. Reporters review the filings, submit yes or no independently, and the majority answer resolves the market without a central judge. This is the same reporting and dispute pattern used by Augur.

-
-
-
Justice
-

Decentralized Courts

-

Example: a freelancer and client dispute whether a milestone was actually delivered. Jurors review the contract, messages, and submitted work in isolation, then vote; jurors who align with the majority are rewarded. Kleros Escrow applies this model to real dispute resolution.

+
+
+
+ +

Why some answers feel inevitable

+

Why do two strangers drift toward Grand Central? Why does the number 100 pull a room of players toward itself? Some answers feel naturally prominent before anyone has spoken. Schelling called these focal points: answers that become coordination anchors because each person expects the others to notice the same thing.

+
+ Salience over originality + Mutual expectation over direct planning + The crowd converges on what feels obvious
+
+
- -
- -

From theory to cryptographic mechanism

-
-

- In 2014, Vitalik Buterin proposed SchellingCoin: the first design - for using Schelling-point incentives on a blockchain. The idea was simple: if you - reward participants for reporting values that match the majority, honest reporting - becomes the dominant strategy. This concept underpins oracle designs, curation - markets, and governance systems across Ethereum where decentralized truth is needed - without a trusted authority. -

+
+
+
+ +

The game is active

+

Any crowd from 3 to 21 players can form a match. No need to fill a massive lobby before the coordination problem becomes live.

+
+
+
- -
- Further Reading - -
- -
-
- - - - - -
-

Ready to find the focal point?

-

Any crowd from 3 to 21 players. 10 games. One prompt: can you think like everyone else?

- Play Now -
- +
-
- -
- diff --git a/public/scripts/landing.js b/public/scripts/landing.js index 91be31a..4d521ea 100644 --- a/public/scripts/landing.js +++ b/public/scripts/landing.js @@ -1,95 +1,3 @@ -/* ── Convergence Canvas ──────────────────── */ -(function() { - const canvas = document.getElementById('convergence'); - const ctx = canvas.getContext('2d'); - let w, h, particles, center; - const PARTICLE_COUNT = 80; - - function resize() { - var rect = canvas.parentElement.getBoundingClientRect(); - w = canvas.width = rect.width || window.innerWidth; - h = canvas.height = rect.height || window.innerHeight; - center = { x: w / 2, y: h / 2 }; - } - - function init() { - resize(); - particles = []; - for (let i = 0; i < PARTICLE_COUNT; i++) { - particles.push({ - x: Math.random() * w, - y: Math.random() * h, - vx: (Math.random() - 0.5) * 0.3, - vy: (Math.random() - 0.5) * 0.3, - r: Math.random() * 1.5 + 0.5, - alpha: Math.random() * 0.4 + 0.1, - phase: Math.random() * Math.PI * 2, - }); - } - } - - function draw() { - ctx.clearRect(0, 0, w, h); - const focal = { x: center.x, y: center.y * 0.9 }; - const t = Date.now() * 0.001; - - for (const p of particles) { - // gentle pull toward focal point - const dx = focal.x - p.x; - const dy = focal.y - p.y; - const pull = 0.00015; - p.vx += dx * pull; - p.vy += dy * pull; - - // slight orbital drift - p.vx += Math.sin(t + p.phase) * 0.003; - p.vy += Math.cos(t + p.phase) * 0.003; - - // damping - p.vx *= 0.995; - p.vy *= 0.995; - - p.x += p.vx; - p.y += p.vy; - - // wrap - if (p.x < -20) p.x = w + 20; - if (p.x > w + 20) p.x = -20; - if (p.y < -20) p.y = h + 20; - if (p.y > h + 20) p.y = -20; - - // draw - const glow = Math.sin(t * 0.5 + p.phase) * 0.15 + 0.85; - ctx.beginPath(); - ctx.arc(p.x, p.y, p.r, 0, Math.PI * 2); - ctx.fillStyle = `rgba(201,168,76,${p.alpha * glow})`; - ctx.fill(); - - // draw lines to nearby particles - for (const q of particles) { - if (q === p) continue; - const ddx = q.x - p.x; - const ddy = q.y - p.y; - const d = Math.sqrt(ddx * ddx + ddy * ddy); - if (d < 100) { - ctx.beginPath(); - ctx.moveTo(p.x, p.y); - ctx.lineTo(q.x, q.y); - ctx.strokeStyle = `rgba(201,168,76,${0.04 * (1 - d / 100)})`; - ctx.lineWidth = 0.5; - ctx.stroke(); - } - } - } - - requestAnimationFrame(draw); - } - - init(); - draw(); - window.addEventListener('resize', resize); -})(); - var gameConfigPromise = fetch('/api/game-config') .then(function(response) { if (!response.ok) throw new Error('Unable to load game config'); @@ -99,33 +7,78 @@ var gameConfigPromise = fetch('/api/game-config') return { commitDuration: null, revealDuration: null, - turnstileSiteKey: null + turnstileSiteKey: null, }; }); -/* ── Example option interaction ──────────── */ (function() { - var demo = document.querySelector('.example-layout'); - var opts = document.querySelectorAll('.example-opt'); - var insight = document.querySelector('.example-insight'); + var nav = document.getElementById('mainNav'); + var button = document.getElementById('navHamburger'); + var mobileLinks = document.querySelectorAll('.nav-mobile a'); + + if (!nav || !button) return; + + button.addEventListener('click', function() { + var open = nav.classList.toggle('menu-open'); + button.setAttribute('aria-expanded', open ? 'true' : 'false'); + }); + + mobileLinks.forEach(function(link) { + link.addEventListener('click', function() { + nav.classList.remove('menu-open'); + button.setAttribute('aria-expanded', 'false'); + }); + }); +})(); + +(function() { + var nodes = document.querySelectorAll('.reveal'); + if (!nodes.length) return; + + if (!('IntersectionObserver' in window)) { + nodes.forEach(function(node) { + node.classList.add('is-visible'); + }); + return; + } + + var observer = new IntersectionObserver(function(entries) { + entries.forEach(function(entry) { + if (!entry.isIntersecting) return; + entry.target.classList.add('is-visible'); + observer.unobserve(entry.target); + }); + }, { threshold: 0.15 }); + + nodes.forEach(function(node) { + observer.observe(node); + }); +})(); + +(function() { + var shell = document.querySelector('.example-shell'); + var grid = document.getElementById('exampleGrid'); + var options = document.querySelectorAll('.example-opt'); + var insight = document.querySelector('.example-insight p'); var status = document.querySelector('.example-vote-status'); var turnstileContainer = document.getElementById('example-turnstile'); - var configLoaded = false; - var siteKey = null; + var resetButton = document.getElementById('exReset'); var widgetId = null; var widgetInitPromise = null; var pendingChallenge = null; + var siteKey = null; - if (!demo || !opts.length || !insight || !status || !turnstileContainer) return; + if (!shell || !grid || !options.length || !insight || !status || !turnstileContainer) { + return; + } - // Inject vote-bar and vote-pct elements into each option - opts.forEach(function(opt) { + options.forEach(function(option) { var bar = document.createElement('div'); - bar.className = 'vote-bar'; var pct = document.createElement('div'); + bar.className = 'vote-bar'; pct.className = 'vote-pct'; - opt.appendChild(bar); - opt.appendChild(pct); + option.appendChild(bar); + option.appendChild(pct); }); function setStatus(message, tone) { @@ -134,8 +87,12 @@ var gameConfigPromise = fetch('/api/game-config') if (tone) status.classList.add(tone); } - function setDemoDisabled(disabled) { - demo.classList.toggle('demo-disabled', disabled); + function setDisabled(disabled) { + shell.classList.toggle('demo-disabled', disabled); + options.forEach(function(option) { + option.classList.toggle('disabled', disabled); + option.disabled = disabled; + }); } function rejectPendingChallenge(message) { @@ -204,7 +161,7 @@ var gameConfigPromise = fetch('/api/game-config') }, 'timeout-callback': function() { rejectPendingChallenge('Verification timed out. Please try again.'); - } + }, }); return widgetId; }) @@ -225,22 +182,28 @@ var gameConfigPromise = fetch('/api/game-config') window.turnstile.execute(id); } catch (error) { pendingChallenge = null; - reject(error instanceof Error ? error : new Error('Human verification failed. Please try again.')); + reject( + error instanceof Error + ? error + : new Error('Human verification failed. Please try again.'), + ); } }); }); } - function submitExampleVote(idx, token) { + function submitExampleVote(index, token) { return fetch('/api/example-vote', { method: 'POST', headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ optionIndex: idx, turnstileToken: token }) + body: JSON.stringify({ optionIndex: index, turnstileToken: token }), }).then(function(response) { if (response.ok) return response.json(); return response.json() - .catch(function() { return {}; }) + .catch(function() { + return {}; + }) .then(function(body) { var message = body && body.error ? body.error : 'Unable to record vote right now.'; throw new Error(message); @@ -250,158 +213,119 @@ var gameConfigPromise = fetch('/api/game-config') function renderTally(data) { if (!data || !data.total) return; - // Build a lookup: optionIndex -> count + var counts = {}; var maxCount = 0; - data.votes.forEach(function(v) { - counts[v.optionIndex] = v.count; - if (v.count > maxCount) maxCount = v.count; + + data.votes.forEach(function(vote) { + counts[vote.optionIndex] = vote.count; + if (vote.count > maxCount) maxCount = vote.count; }); - // Animate bars and show percentages - opts.forEach(function(opt, idx) { - var count = counts[idx] || 0; + options.forEach(function(option, index) { + var count = counts[index] || 0; var pct = data.total > 0 ? Math.round((count / data.total) * 100) : 0; - var bar = opt.querySelector('.vote-bar'); - var label = opt.querySelector('.vote-pct'); - label.textContent = pct > 0 ? pct + '%' : ''; - // Use maxCount for bar scaling so the top answer fills 100% - var barWidth = maxCount > 0 ? Math.round((count / maxCount) * 100) : 0; - setTimeout(function() { bar.style.width = barWidth + '%'; }, 50); + var pctNode = option.querySelector('.vote-pct'); + var barNode = option.querySelector('.vote-bar'); + pctNode.textContent = pct > 0 ? pct + '%' : ''; + if (barNode) { + barNode.style.height = (maxCount > 0 ? Math.round((count / maxCount) * 100) : 0) + '%'; + } }); - demo.classList.add('has-tally'); - - // Update insight with the winner - var topVote = data.votes.reduce(function(a, b) { return b.count > a.count ? b : a; }, { count: 0 }); - var topPct = Math.round((topVote.count / data.total) * 100); - var topLabel = opts[topVote.optionIndex] ? opts[topVote.optionIndex].childNodes[0].textContent.trim() : '?'; - insight.textContent = topPct + '% of ' + data.total + ' visitors picked ' + topLabel + '. ' - + 'It is the only non-prime, the only round number, and the only three-digit number in the set. ' - + 'That salience makes it the natural coordination target: the focal point.'; + grid.classList.add('revealed'); + insight.textContent = "100 is the only non-prime, the only round number, and the only three-digit number in the set. That salience makes it the natural coordination target: the focal point."; } function revealWithTally() { - demo.classList.add('revealed'); - demo.classList.remove('verifying', 'demo-disabled'); - turnstileContainer.hidden = true; - opts.forEach(function(o) { o.style.cursor = 'default'; }); fetch('/api/example-tally') - .then(function(r) { if (!r.ok) return; return r.json(); }) + .then(function(response) { return response.json(); }) .then(renderTally) .catch(function() {}); } - // If already voted, show results immediately and mark their pick - var votedIdx = localStorage.getItem('example-voted'); - if (votedIdx !== null) { - var idx = parseInt(votedIdx, 10); - if (!isNaN(idx) && opts[idx]) opts[idx].classList.add('my-pick'); - revealWithTally(); - } else { - setStatus('Loading human verification…', 'pending'); - - gameConfigPromise.then(function(cfg) { - configLoaded = true; - siteKey = cfg && typeof cfg.turnstileSiteKey === 'string' && cfg.turnstileSiteKey.trim() - ? cfg.turnstileSiteKey.trim() - : null; - - if (!siteKey) { - setDemoDisabled(true); - setStatus('Demo voting is temporarily unavailable.', 'error'); - return; - } + function resetExample() { + localStorage.removeItem('example-voted'); + setStatus('', ''); + grid.classList.remove('revealed'); + options.forEach(function(option) { + option.classList.remove('my-pick'); + option.classList.remove('disabled'); + option.disabled = false; + var pctNode = option.querySelector('.vote-pct'); + var barNode = option.querySelector('.vote-bar'); + if (pctNode) pctNode.textContent = ''; + if (barNode) barNode.style.height = '0'; + }); + resetTurnstileWidget(); + turnstileContainer.hidden = true; + insight.textContent = "100 is the only non-prime, the only round number, and the only three-digit number in the set. That salience makes it the natural coordination target: the focal point."; + } - setDemoDisabled(false); - setStatus('', ''); + if (resetButton) { + resetButton.addEventListener('click', function() { + resetExample(); }); + } - opts.forEach(function(opt, idx) { - opt.addEventListener('click', function() { - if ( - demo.classList.contains('revealed') || - demo.classList.contains('verifying') || - demo.classList.contains('demo-disabled') - ) { - return; - } - if (!configLoaded) { - setStatus('Loading human verification…', 'pending'); - return; - } + var votedIndex = localStorage.getItem('example-voted'); + if (votedIndex !== null) { + var restored = parseInt(votedIndex, 10); + if (!Number.isNaN(restored) && options[restored]) { + options[restored].classList.add('my-pick'); + revealWithTally(); + } + } else { + options.forEach(function(option, index) { + option.addEventListener('click', function() { + if (grid.classList.contains('revealed')) return; - opt.classList.add('my-pick'); - demo.classList.add('verifying'); - setStatus('Checking that you are human…', 'pending'); + setDisabled(true); + setStatus('Verifying that you are human...', 'pending'); runTurnstileChallenge() .then(function(token) { - return submitExampleVote(idx, token); + setStatus('Submitting your vote...', 'pending'); + return submitExampleVote(index, token); }) .then(function() { - localStorage.setItem('example-voted', String(idx)); - setStatus('Vote recorded. Loading tally…', 'success'); + localStorage.setItem('example-voted', String(index)); + option.classList.add('my-pick'); + setStatus('Vote recorded. Loading the crowd readout...', 'success'); revealWithTally(); }) .catch(function(error) { - demo.classList.remove('verifying'); + setStatus(error instanceof Error ? error.message : 'Unable to record vote right now.', 'error'); resetTurnstileWidget(); - turnstileContainer.hidden = false; - setStatus( - error && error.message ? error.message : 'Unable to record vote right now.', - 'error', - ); + }) + .finally(function() { + setDisabled(false); }); }); }); } -})(); - -/* ── Phase durations from server (single source of truth) ── */ -gameConfigPromise.then(function(cfg) { - var commitSeconds = document.getElementById('commit-seconds'); - if (commitSeconds && typeof cfg.commitDuration === 'number') { - commitSeconds.textContent = cfg.commitDuration; - } -}).catch(function() {}); -/* ── Landing stats ───────────────────────── */ -(function() { - function formatInt(value) { - return new Intl.NumberFormat().format(value); - } - - fetch('/api/landing-stats').then(function(r) { if (!r.ok) return; return r.json(); }).then(function(stats) { - if (!stats) return; - document.getElementById('stat-players-24h').textContent = formatInt(stats.playersLast24h || 0); - document.getElementById('stat-completed-matches').textContent = formatInt(stats.completedMatches || 0); - document.getElementById('stat-longest-streak').textContent = formatInt(stats.longestStreak || 0); - }).catch(function() {}); + gameConfigPromise.then(function(cfg) { + siteKey = cfg && typeof cfg.turnstileSiteKey === 'string' && cfg.turnstileSiteKey.trim() + ? cfg.turnstileSiteKey.trim() + : null; + }); })(); -/* ── Build stamp formatting ───────────────── */ (function() { - var stamp = document.querySelector('.build-stamp'); - if (!stamp) return; - - var hash = stamp.getAttribute('data-build-hash'); - var rawDate = stamp.getAttribute('data-build-date'); - if (!hash || !rawDate) return; - - var parsed = new Date(rawDate); - if (Number.isNaN(parsed.getTime())) return; - - var formatter = new Intl.DateTimeFormat(undefined, { - year: 'numeric', - month: 'short', - day: 'numeric', - hour: '2-digit', - minute: '2-digit', - hour12: false, - timeZoneName: 'short' - }); - - stamp.textContent = hash + ' · ' + formatter.format(parsed); - stamp.title = rawDate + ' UTC'; + fetch('/api/landing-stats') + .then(function(response) { return response.json(); }) + .then(function(data) { + if (!data) return; + if (data.playersLast24h != null) { + document.getElementById('stat-players-24h').textContent = Number(data.playersLast24h).toLocaleString(); + } + if (data.completedMatches != null) { + document.getElementById('stat-completed-matches').textContent = Number(data.completedMatches).toLocaleString(); + } + if (data.longestStreak != null) { + document.getElementById('stat-longest-streak').textContent = Number(data.longestStreak).toLocaleString(); + } + }) + .catch(function() {}); })(); diff --git a/public/styles/app-shell.css b/public/styles/app-shell.css index 102cef0..7263835 100644 --- a/public/styles/app-shell.css +++ b/public/styles/app-shell.css @@ -10,3 +10,7 @@ .dialog-title-reset{margin:0} .dialog-actions-inline{display:flex;gap:.5rem} .rules-example-spaced{margin-bottom:.5rem} +#build-info{margin-top:auto;text-align:center;padding:2rem 1rem 1rem;font-size:.78rem;color:#555;letter-spacing:.04em;font-family:var(--mono);display:flex;justify-content:center;align-items:center;gap:1rem} +#app::before{content:'';position:fixed;inset:0;background:linear-gradient(180deg,rgba(230,60,20,.06) 0%,rgba(230,60,20,0) 16%);pointer-events:none;z-index:-1} +.view.active{animation:viewIn .4s ease forwards} +@keyframes viewIn{from{opacity:0;transform:translateY(12px)}to{opacity:1;transform:none}} diff --git a/public/styles/base.css b/public/styles/base.css index f502a8b..37e1de4 100644 --- a/public/styles/base.css +++ b/public/styles/base.css @@ -1,22 +1,23 @@ /* ── Layout ─────────────────────────────────────────────────────── */ -#app{flex:1 0 auto;width:100%;max-width:none;margin:0;padding:clamp(1rem,1.8vw,1.5rem) var(--app-gutter) 2.5rem;position:relative} -header{display:grid;grid-template-columns:minmax(0,1fr) auto minmax(0,1fr);align-items:end;gap:1rem 1.25rem;border-bottom:1px solid rgba(255,255,255,.05);background:rgba(10,10,10,.82);backdrop-filter:blur(16px);position:sticky;top:0;z-index:100;padding:.85rem 0;margin:0 0 clamp(1.25rem,2.5vw,2rem)} +#app{flex:1 0 auto;width:100%;max-width:1760px;margin:0 auto;padding:clamp(1rem,1.8vw,1.5rem) var(--app-gutter) 2.5rem;position:relative} +header{display:grid;grid-template-columns:auto 1fr auto;align-items:center;gap:1rem 1.5rem;border-bottom:1px solid rgba(255,255,255,.05);background:rgba(10,10,10,.9);backdrop-filter:blur(16px);position:sticky;top:0;z-index:100;padding:.95rem 0 .85rem;margin:0 0 clamp(1.5rem,2.5vw,2.4rem)} .header-brand{display:flex;align-items:center;justify-self:start;min-width:0} -.header-brand-copy{display:flex;flex-direction:column;gap:.2rem;min-width:0} -.header-kicker{font-size:.78rem;font-weight:500;letter-spacing:.18em;text-transform:uppercase;color:var(--muted)} -header h1{font-family:var(--serif);font-size:clamp(1.45rem,2vw,1.9rem);font-weight:700;letter-spacing:.03em;color:var(--text);line-height:.95} -header h1 a{display:inline-block} -header h1 span{color:var(--accent)} -#header-profile{display:flex;align-items:center;justify-self:end;align-self:center;justify-content:flex-end;gap:.8rem;font-size:.9rem;color:var(--muted);flex-wrap:wrap} -#header-profile .identity{display:flex;flex-direction:column;align-items:flex-end;gap:.12rem;line-height:1.1} -#header-profile .name{color:var(--text);font-weight:600} -#header-profile .bal{color:var(--accent)} -.header-actions{display:flex;align-items:center;gap:.45rem} -#logout-btn{padding:.4rem .6rem;font-size:.78rem;line-height:1} -nav{display:flex;align-items:center;justify-self:center;align-self:end;gap:.45rem;flex-wrap:wrap;justify-content:center;min-width:0} -header .btn-ghost,header .button-link{padding:.48rem .78rem;font-size:.78rem;letter-spacing:.12em} +.header-brand a{display:inline-flex;align-items:center;justify-content:center;color:var(--text);text-decoration:none} +.brand-mark{width:2.15rem;height:2.15rem;flex-shrink:0;display:block} +.brand-mark-dot{fill:var(--accent)} +.header-brand-copy,.header-kicker,header h1{display:none} +#header-profile{display:flex;justify-self:end;align-items:center;align-self:center;gap:.55rem;font-size:.9rem;color:var(--muted);min-width:0;flex-wrap:wrap;justify-content:flex-end} +#header-profile .identity{display:flex;align-items:center;gap:.55rem;line-height:1.1} +#header-profile .name{color:var(--text);font-family:var(--mono);font-size:.75rem;font-weight:500;letter-spacing:.14em;text-transform:uppercase} +#header-profile .bal{display:inline-flex;align-items:center;justify-content:center;padding:.5rem .82rem;border:1px solid rgba(230,60,20,.35);background:rgba(230,60,20,.08);color:var(--accent);font-size:.72rem;font-family:var(--mono);font-weight:500;letter-spacing:.14em;text-transform:uppercase} +.header-actions{display:flex;align-items:center;justify-content:flex-end;gap:.45rem;flex-wrap:wrap} +#logout-btn{padding:.46rem .72rem;font-size:.72rem;line-height:1;color:var(--muted);border-color:rgba(255,255,255,.1)} +#logout-btn:hover:not(:disabled){border-color:rgba(230,60,20,.5);color:var(--text)} +nav{display:flex;align-items:center;justify-self:center;align-self:center;gap:.45rem;flex-wrap:wrap;justify-content:center;min-width:0} +header .btn-ghost,header .button-link{padding:.48rem .78rem;font-size:.72rem;letter-spacing:.16em} /* ── Views ──────────────────────────────────────────────────────── */ -.view{display:none}.view.active{display:block} +.view{display:none} +.view.active{display:block} /* Auth */ #auth-view{max-width:420px;margin:2rem auto;text-align:center} #auth-view h2{margin-bottom:1rem} @@ -47,7 +48,7 @@ header .btn-ghost,header .button-link{padding:.48rem .78rem;font-size:.78rem;let #rules-overlay .rules-text{font-size:.92rem;color:var(--text);line-height:1.6;margin:.25rem 0 0} #rules-overlay .rules-example{background:var(--surface2);border:1px solid var(--border);border-radius:var(--radius);padding:.75rem;font-size:.92rem;line-height:1.6;color:var(--text)} #rules-overlay .rules-example strong{color:var(--accent)} -.info-banner{background:rgba(255,152,0,.1);border:1px solid rgba(255,152,0,.45);border-radius:var(--radius);padding:.8rem 1rem;font-size:.92rem;line-height:1.6;color:var(--text)} +.info-banner{background:rgba(255,77,37,.1);border:1px solid rgba(255,77,37,.45);border-radius:var(--radius);padding:.8rem 1rem;font-size:.92rem;line-height:1.6;color:var(--text)} .info-banner strong{color:var(--orange)} .danger-banner{background:var(--surface);border:1px solid rgba(229,57,53,.28);border-radius:var(--radius);padding:.9rem 1rem;font-size:.92rem;line-height:1.6;color:var(--text)} .danger-banner strong{color:#f09a97} diff --git a/public/styles/components.css b/public/styles/components.css index 10d9233..7b682aa 100644 --- a/public/styles/components.css +++ b/public/styles/components.css @@ -2,20 +2,21 @@ .timer-wrap{display:flex;align-items:center;gap:.75rem;font-size:.94rem;color:var(--muted)} .timer-bar-outer{flex:1;height:6px;background:var(--border);border-radius:3px;overflow:hidden} .timer-bar{height:100%;background:var(--accent);transition:width .25s linear,background .3s} -.timer-num{font-family:var(--serif);font-weight:700;font-size:1rem;min-width:2.5rem;text-align:right} +.timer-num{font-family:var(--display);font-weight:700;font-size:1.35rem;min-width:2.5rem;text-align:right;letter-spacing:-.03em} .timer-num.urgent{color:var(--red);animation:pulse .5s infinite alternate} @keyframes pulse{to{opacity:.3}} /* Question */ -#question-card{background:var(--surface);border:1px solid var(--border);border-radius:var(--radius);padding:1.25rem} +#question-card{position:relative;background:linear-gradient(180deg,rgba(255,255,255,.02),rgba(255,255,255,0)),var(--surface);border:1px solid rgba(255,255,255,.08);border-radius:var(--radius);padding:1.35rem 1.45rem 1.25rem;overflow:hidden} +#question-card::before{content:'';position:absolute;left:0;top:0;right:0;height:1px;background:linear-gradient(90deg,var(--accent),rgba(255,255,255,.08) 28%,rgba(255,255,255,0))} .question-meta-row{display:flex;align-items:flex-start;justify-content:space-between;gap:.75rem;flex-wrap:wrap;margin-bottom:.85rem} #phase-label{font-size:.78rem;font-weight:600;text-transform:uppercase;letter-spacing:.25em;margin:0;color:var(--accent)} #off-record-banner{display:inline-flex;align-items:flex-start;justify-content:flex-end;gap:.45rem;max-width:25rem;font-size:.82rem;line-height:1.5;color:var(--muted);text-align:right} #off-record-banner strong{font-size:.78rem;font-weight:600;letter-spacing:.16em;text-transform:uppercase;color:var(--accent2);white-space:nowrap} -#question-text{font-family:var(--serif);font-size:1.4rem;font-weight:600;margin-bottom:1rem;line-height:1.3} +#question-text{font-family:var(--display);letter-spacing:-.015em;font-size:clamp(2rem,3vw,2.7rem);font-weight:700;margin-bottom:1.1rem;line-height:.98;max-width:14ch;text-wrap:balance} #select-grid{display:grid;grid-template-columns:1fr 1fr;gap:.6rem} -.opt-btn{background:var(--surface2);border:1px solid var(--border);border-radius:3px;padding:.75rem 1rem;cursor:pointer;text-align:left;font-family:var(--sans);font-size:.96rem;font-weight:400;text-transform:none;letter-spacing:0;color:var(--text);transition:border-color .2s,background .2s,color .2s;user-select:none;appearance:none} +.opt-btn{display:flex;align-items:center;min-height:4.45rem;background:rgba(255,255,255,.02);border:1px solid rgba(255,255,255,.08);border-radius:3px;padding:.72rem 1rem;cursor:pointer;text-align:left;font-family:var(--display);font-size:clamp(1.15rem,1.9vw,1.55rem);font-weight:700;text-transform:none;letter-spacing:-.01em;color:var(--text);transition:border-color .2s,background .2s,color .2s,transform .2s;user-select:none;appearance:none} .opt-btn:hover:not(.disabled){border-color:var(--accent);color:var(--accent)} -.opt-btn.selected{border-color:var(--accent);background:rgba(201,168,76,.08);color:var(--accent);font-weight:500} +.opt-btn.selected{border-color:var(--accent);background:rgba(230,60,20,.09);color:var(--accent);font-weight:700;transform:translateY(-1px)} .opt-btn.disabled{opacity:.4;cursor:default;pointer-events:none} .opt-btn:focus-visible{outline:2px solid var(--accent);outline-offset:2px} .text-answer-wrap{display:flex;flex-direction:column;gap:.45rem} @@ -27,12 +28,12 @@ .card-picker-label{font-size:.74rem;font-weight:600;letter-spacing:.14em;text-transform:uppercase;color:var(--muted)} .card-picker-preview{font-size:.88rem;color:var(--text);min-height:1.3rem} .text-answer-hint{font-size:.8rem;color:var(--muted);line-height:1.45} -#commit-area{display:flex;align-items:center;gap:.75rem;flex-wrap:wrap;margin-top:.75rem} -#commit-btn{flex:1;min-width:140px} -#commit-status{font-size:.9rem;color:var(--muted)} -#reveal-area{display:flex;align-items:center;gap:.75rem;flex-wrap:wrap;margin-top:.75rem} -#reveal-btn{flex:1;min-width:140px} -#reveal-status{font-size:.9rem;color:var(--muted)} +#commit-area{display:flex;align-items:center;justify-content:flex-end;gap:.75rem;flex-wrap:wrap;margin-top:.9rem;padding-top:.85rem;border-top:1px solid rgba(255,255,255,.06)} +#commit-btn{min-width:180px} +#commit-status{font-size:.9rem;color:var(--muted);text-align:right} +#reveal-area{display:flex;align-items:center;justify-content:flex-end;gap:.75rem;flex-wrap:wrap;margin-top:.9rem;padding-top:.85rem;border-top:1px solid rgba(255,255,255,.06)} +#reveal-btn{min-width:180px} +#reveal-status{font-size:.9rem;color:var(--muted);text-align:right} /* Game result overlay */ #game-result-banner{background:var(--surface);border:1px solid var(--border);border-radius:var(--radius);padding:1rem;margin-top:.75rem} #game-result-banner h3{font-size:.78rem;font-weight:600;margin-bottom:.6rem;color:var(--accent);text-transform:uppercase;letter-spacing:.25em} @@ -48,8 +49,9 @@ .delta-zero{color:var(--muted)} /* Sidebar */ #play-sidebar{display:flex;flex-direction:column;gap:.75rem} -#players-panel{background:var(--surface);border:1px solid var(--border);border-radius:var(--radius);padding:1rem} -#players-panel h3{font-size:.78rem;font-weight:600;text-transform:uppercase;letter-spacing:.25em;color:var(--accent);margin-bottom:.6rem} +#players-panel{position:relative;overflow:hidden;background:var(--surface);border:1px solid rgba(255,255,255,.08);border-radius:var(--radius);padding:1rem} +#players-panel::before{content:'';position:absolute;left:0;top:0;right:0;height:1px;background:linear-gradient(90deg,var(--accent),rgba(255,255,255,.08) 38%,rgba(255,255,255,0))} +#players-panel h3{font-size:.78rem;font-weight:600;text-transform:uppercase;letter-spacing:.25em;color:var(--accent);margin-bottom:.75rem} .player-row{display:flex;align-items:center;justify-content:space-between;padding:.3rem 0;border-bottom:1px solid var(--border);font-size:.92rem} .player-row:last-child{border-bottom:none} .player-name{display:flex;align-items:center;gap:.4rem;flex-wrap:wrap} @@ -59,48 +61,47 @@ .dot.revealed{background:var(--green)} .dot.forfeited{background:var(--red)} .dot.disconnected{background:var(--red);animation:pulse 1s infinite alternate} -.balance-badge{font-family:var(--serif);font-size:.86rem;color:var(--muted)} -#live-stats-panel{position:relative;overflow:hidden;background:linear-gradient(180deg,rgba(201,168,76,.08),rgba(17,17,17,.98) 72%);border:1px solid rgba(201,168,76,.24);border-radius:var(--radius);padding:1rem;transition:border-color .2s ease,transform .2s ease,box-shadow .2s ease} -#live-stats-panel::before{content:'';position:absolute;inset:-30% auto auto 38%;width:180px;height:180px;background:radial-gradient(circle,rgba(201,168,76,.16),transparent 72%);pointer-events:none;opacity:.75;transform:translateY(-18%);transition:transform .35s ease,opacity .35s ease} -#live-stats-panel:hover{border-color:rgba(201,168,76,.4);transform:translateY(-1px);box-shadow:0 16px 34px rgba(0,0,0,.22)} -#live-stats-panel:hover::before{opacity:1;transform:translateY(-10%)} +.balance-badge{font-family:var(--mono);font-size:.72rem;letter-spacing:.12em;color:var(--muted);text-transform:uppercase} +#live-stats-panel{position:relative;overflow:hidden;background:var(--surface);border:1px solid rgba(255,255,255,.08);border-radius:var(--radius);padding:1rem;transition:border-color .2s ease,transform .2s ease} +#live-stats-panel::before{content:'';position:absolute;left:0;top:0;right:0;height:1px;background:linear-gradient(90deg,var(--accent),rgba(255,255,255,.08) 38%,rgba(255,255,255,0))} +#live-stats-panel:hover{border-color:rgba(230,60,20,.32);transform:translateY(-1px)} #live-stats-panel.is-updated{animation:liveStatsFlash .72s ease} @keyframes liveStatsFlash{ - 0%{border-color:rgba(201,168,76,.22);box-shadow:none} - 28%{border-color:rgba(223,192,106,.78);box-shadow:0 18px 38px rgba(0,0,0,.28)} - 100%{border-color:rgba(201,168,76,.24);box-shadow:none} + 0%{border-color:rgba(230,60,20,.22);box-shadow:none} + 28%{border-color:rgba(255,77,37,.78);box-shadow:0 18px 38px rgba(0,0,0,.28)} + 100%{border-color:rgba(230,60,20,.24);box-shadow:none} } .live-stats-kicker{font-size:.78rem;font-weight:600;letter-spacing:.18em;text-transform:uppercase;color:var(--accent)} -.live-stats-headline{margin-top:.45rem;font-family:var(--serif);font-size:1.28rem;font-weight:600;line-height:1.05;color:var(--text)} +.live-stats-headline{margin-top:.45rem;font-family:var(--display);letter-spacing:-.01em;font-size:1.28rem;font-weight:600;line-height:1.05;color:var(--text)} .live-stats-subhead{margin-top:.4rem;font-size:.9rem;line-height:1.55;color:var(--muted);max-width:22rem} #live-stats-strip{display:grid;gap:.35rem;margin-top:1rem} .live-step{display:flex;flex-direction:column;align-items:center;gap:.35rem;min-width:0} .live-step-bar{position:relative;width:100%;height:56px;border-radius:999px;border:1px solid rgba(255,255,255,.08);background:linear-gradient(180deg,rgba(255,255,255,.02),rgba(255,255,255,.05));overflow:hidden;transition:transform .2s ease,border-color .2s ease,background .2s ease,opacity .2s ease} .live-step-bar::after{content:'';position:absolute;left:50%;top:7px;width:8px;height:8px;border-radius:50%;background:transparent;transform:translateX(-50%);transition:background .2s ease,box-shadow .2s ease} -.live-step.current .live-step-bar{transform:translateY(-2px);border-color:rgba(201,168,76,.62);box-shadow:0 0 0 1px rgba(201,168,76,.18)} +.live-step.current .live-step-bar{transform:translateY(-2px);border-color:rgba(230,60,20,.62);box-shadow:0 0 0 1px rgba(230,60,20,.18)} .live-step.win .live-step-bar{background:linear-gradient(180deg,rgba(76,175,80,.1),rgba(76,175,80,.38));border-color:rgba(76,175,80,.35)} .live-step.loss .live-step-bar{background:linear-gradient(180deg,rgba(229,57,53,.05),rgba(229,57,53,.28));border-color:rgba(229,57,53,.26)} -.live-step.void .live-step-bar{background:linear-gradient(180deg,rgba(255,152,0,.06),rgba(255,152,0,.3));border-color:rgba(255,152,0,.28)} +.live-step.void .live-step-bar{background:linear-gradient(180deg,rgba(255,77,37,.06),rgba(255,77,37,.3));border-color:rgba(255,77,37,.28)} .live-step.forfeited .live-step-bar{background:linear-gradient(180deg,rgba(229,57,53,.08),rgba(108,18,16,.48));border-color:rgba(229,57,53,.34)} .live-step.future .live-step-bar{opacity:.5} .live-step.unknown .live-step-bar{background:repeating-linear-gradient(180deg,rgba(255,255,255,.02) 0 8px,rgba(255,255,255,.06) 8px 16px);border-color:rgba(255,255,255,.12)} -.live-step.coord .live-step-bar::after{background:var(--accent2);box-shadow:0 0 14px rgba(223,192,106,.38)} +.live-step.coord .live-step-bar::after{background:var(--accent2);box-shadow:0 0 14px rgba(255,77,37,.38)} .live-step-label{font-size:.74rem;font-weight:600;letter-spacing:.12em;color:var(--muted)} #live-stats-grid{display:flex;flex-direction:column;gap:.42rem;margin-top:.95rem;padding-top:.85rem;border-top:1px solid rgba(255,255,255,.06)} .live-stat-row{display:flex;align-items:baseline;justify-content:space-between;gap:.85rem;padding-bottom:.38rem;border-bottom:1px solid rgba(255,255,255,.04)} .live-stat-row:last-child{padding-bottom:0;border-bottom:none} .live-stat-label{font-size:.78rem;font-weight:600;letter-spacing:.1em;text-transform:uppercase;color:var(--muted)} -.live-stat-value{font-family:var(--serif);font-size:1rem;font-weight:600;line-height:1;color:var(--text);text-align:right} +.live-stat-value{font-family:var(--display);font-size:1.2rem;font-weight:700;line-height:.9;color:var(--text);text-align:right;letter-spacing:-.03em} .live-stat-value.delta-pos,.live-stat-value.delta-neg,.live-stat-value.delta-zero{font-family:var(--sans);font-size:.95rem} #live-stats-foot{margin-top:.75rem;font-size:.84rem;line-height:1.55;color:var(--muted)} -#forfeit-panel{background:var(--surface);border:1px solid var(--border);border-radius:var(--radius);padding:1rem} +#forfeit-panel{position:relative;overflow:hidden;background:var(--surface);border:1px solid rgba(255,255,255,.08);border-radius:var(--radius);padding:1rem} +#forfeit-panel::before{content:'';position:absolute;left:0;top:0;right:0;height:1px;background:linear-gradient(90deg,var(--accent),rgba(255,255,255,.08) 38%,rgba(255,255,255,0))} #forfeit-panel.is-locked{border-color:rgba(229,57,53,.24)} #forfeit-panel h3{font-size:.78rem;font-weight:600;text-transform:uppercase;letter-spacing:.25em;color:var(--muted);margin:0} .forfeit-copy{margin-top:.5rem;font-size:.9rem;line-height:1.6;color:var(--muted)} #forfeit-match-btn{width:100%;margin-top:.85rem} #forfeit-match-btn:hover:not(:disabled){transform:translateY(-1px);filter:brightness(1.03)} #forfeit-panel.is-locked .forfeit-copy{color:var(--muted)} - /* Notifications */ #notif{position:fixed;top:1rem;right:1rem;display:flex;flex-direction:column;gap:.4rem;z-index:999;pointer-events:none} .notif-item{background:var(--surface);border:1px solid var(--border);border-radius:var(--radius);padding:.6rem 1rem;font-size:.9rem;min-width:220px;animation:slideIn .2s ease;pointer-events:auto} @@ -122,18 +123,20 @@ #confirm-forfeit-btn{background:linear-gradient(180deg,rgba(229,57,53,.92),rgba(188,32,28,.92));border:1px solid rgba(255,179,169,.16);color:#fff} #confirm-forfeit-btn:hover:not(:disabled){transform:translateY(-1px);box-shadow:0 14px 26px rgba(92,10,8,.34)} @keyframes forfeitDialogIn{from{opacity:0;transform:translateY(16px) scale(.98)}to{opacity:1;transform:none}} -@media(max-width:1100px){ - header{grid-template-columns:1fr;align-items:start} - nav{justify-self:start;align-self:start;justify-content:flex-start} - #header-profile{justify-self:start;align-self:start;justify-content:flex-start} - #header-profile .identity{align-items:flex-start} - #summary-header{grid-template-columns:1fr} +@media(max-width:650px){ + #select-grid{grid-template-columns:1fr} } -@media(max-width:960px){ - .queue-shell{grid-template-columns:1fr} - .queue-inline-roster{display:flex} - .queue-side{display:none} - #summary-stats{grid-template-columns:repeat(2,minmax(0,1fr))} - #summary-podium{grid-template-columns:1fr} - .summary-podium-slot{min-height:unset} +@media(max-width:560px){ + .question-meta-row{margin-bottom:.7rem} + #off-record-banner{max-width:none;justify-content:flex-start;text-align:left} + .card-picker-grid{grid-template-columns:1fr} +} +@media(max-width:480px){ + #commit-area,#reveal-area,#rating-row,.queue-action-row{flex-direction:column;align-items:stretch} + #commit-btn,#reveal-btn{min-width:0} + #rating-row{text-align:left} + .queue-action-row button,.action-row button{width:100%} + .action-row{flex-direction:column} + .forfeit-dialog-actions{flex-direction:column} + .forfeit-dialog-actions button{width:100%} } diff --git a/public/styles/landing.css b/public/styles/landing.css index a87a3fd..f3f80d0 100644 --- a/public/styles/landing.css +++ b/public/styles/landing.css @@ -1,800 +1,269 @@ -*,*::before,*::after{margin:0;padding:0;box-sizing:border-box} +*,*::before,*::after{box-sizing:border-box;margin:0;padding:0} :root{ --bg:#0a0a0a; --surface:#111; - --surface2:#1a1a1a; - --border:#222; - --text:#e8e4de; - --muted:#807a6f; - --muted-strong:#b9b1a4; - --muted-soft:#9c9589; - --accent:#c9a84c; - --accent2:#dfc06a; + --surface-strong:#0d0d0d; + --surface-soft:rgba(255,255,255,.03); + --border:rgba(237,231,221,.12); + --text:#ede7dd; + --muted:#a59b8d; + --muted-strong:#cfc6b8; + --accent:#e63c14; + --accent-strong:#ff4d25; + --accent-soft:rgba(230,60,20,.12); + --accent-line:rgba(230,60,20,.38); --serif:'Cormorant Garamond',Georgia,serif; --sans:'Outfit',system-ui,sans-serif; + --display:'Barlow Condensed','Impact',sans-serif; + --mono:'SF Mono',SFMono-Regular,Consolas,'Liberation Mono',Menlo,monospace; + --page-x:clamp(1.1rem,3vw,2rem); + --content-max:1180px; + --radius:4px; } -html{scroll-behavior:smooth;scroll-padding-top:5rem;scrollbar-color:rgba(201,168,76,.25) transparent;scrollbar-width:thin} +html{scroll-behavior:smooth;scroll-padding-top:6rem;scrollbar-color:rgba(230,60,20,.25) transparent;scrollbar-width:thin} body{ - background:var(--bg); + min-height:100vh; + background-color:var(--bg); + background-image:radial-gradient(circle, rgba(230,60,20,.16) 1px, transparent 1.25px); + background-size:40px 40px; color:var(--text); font-family:var(--sans); - font-weight:300; + font-weight:400; line-height:1.7; overflow-x:hidden; -webkit-font-smoothing:antialiased; } - -/* ── SKIP LINK ──────────────────────────── */ +a{color:inherit} +button{font:inherit} +.sr-only{position:absolute!important;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0} .skip-link{ - position:absolute; - left:-9999px; - top:auto; - width:1px; - height:1px; - overflow:hidden; - z-index:200; - font-family:var(--sans); - font-size:.9rem; - font-weight:500; - color:var(--bg); - background:var(--accent); - padding:.75rem 1.5rem; - text-decoration:none; - border-radius:0 0 3px 3px; -} -.skip-link:focus{ - position:fixed; - left:1rem; - top:0; - width:auto; - height:auto; - overflow:visible; -} - -/* ── NAV ─────────────────────────────────── */ -nav{ - position:fixed;top:0;left:0;right:0;z-index:100; - padding:1.25rem 2rem; - display:flex;align-items:center;justify-content:space-between; - background:rgba(10,10,10,.85); - backdrop-filter:blur(12px); - border-bottom:1px solid rgba(255,255,255,.04); - transition:background .3s; -} -nav .logo{ - font-family:var(--serif); - font-size:1.3rem; - font-weight:700; - letter-spacing:.03em; - color:var(--text); + position:absolute;left:-9999px;top:auto;width:1px;height:1px;overflow:hidden;z-index:200; + padding:.75rem 1.25rem;border-radius:0 0 var(--radius) var(--radius); + background:var(--accent);color:#120c09;text-decoration:none;font-weight:600; } -nav .logo span{color:var(--accent)} -nav .play-link{ - font-size:.9rem; - font-weight:500; - letter-spacing:.08em; - text-transform:uppercase; - color:var(--accent); - text-decoration:none; - padding:.5rem 1.25rem; - border:1px solid var(--accent); - border-radius:2px; - transition:all .2s; -} -nav .play-link:hover{background:var(--accent);color:var(--bg)} - -/* ── HERO ────────────────────────────────── */ -.hero{ - min-height:100vh; - display:flex;flex-direction:column; - align-items:center;justify-content:center; - text-align:center; - padding:6rem 2rem 2rem; - position:relative; - overflow:hidden; -} -.hero::before{ - content:'';position:absolute;inset:0; - background: - radial-gradient(ellipse 60% 50% at 50% 45%, rgba(201,168,76,.06) 0%, transparent 70%), - radial-gradient(ellipse 80% 60% at 50% 100%, rgba(201,168,76,.03) 0%, transparent 50%); - pointer-events:none; -} -.hero-canvas{ - position:absolute;inset:0; - pointer-events:none; - opacity:.7; -} -.hero-overtitle{ - font-size:.84rem; - font-weight:500; - letter-spacing:.25em; - text-transform:uppercase; - color:var(--muted); - margin-bottom:1.5rem; - position:relative; -} -.hero h1{ - font-family:var(--serif); - font-size:clamp(3rem, 8vw, 6.5rem); - font-weight:700; - line-height:1.05; - letter-spacing:-.02em; - margin-bottom:1.5rem; - position:relative; -} -.hero h1 em{ - font-style:italic; - color:var(--accent); -} -.hero-sub{ - font-size:clamp(1rem, 2.5vw, 1.25rem); - color:var(--muted); - max-width:540px; - margin-bottom:2.5rem; - position:relative; -} -.hero-cta{ - display:inline-block; - font-family:var(--sans); - font-size:.94rem; - font-weight:600; - letter-spacing:.12em; - text-transform:uppercase; - color:var(--bg); - background:var(--accent); - padding:.9rem 2.5rem; - border:none; - border-radius:2px; - text-decoration:none; - cursor:pointer; - position:relative; - transition:all .25s; -} -.hero-cta:hover{background:var(--accent2);transform:translateY(-1px)} -.hero-wallet-note{ - font-family:var(--sans); - font-size:.82rem; - color:var(--muted); - letter-spacing:.06em; - margin-top:.75rem; - opacity:.82; -} -.hero-scroll{ - position:absolute; - bottom:1.5rem; - display:flex; - flex-direction:column; - align-items:center; - gap:.35rem; - color:var(--muted); - opacity:.5; - transition:opacity .3s; -} -.hero-scroll:hover{opacity:.8} -.hero-scroll-chevron{ - width:20px; - height:20px; - border-right:1.5px solid var(--muted); - border-bottom:1.5px solid var(--muted); - transform:rotate(45deg); - animation:scrollBounce 2s ease-in-out infinite; -} -@keyframes scrollBounce{ - 0%,100%{transform:rotate(45deg) translateY(0);opacity:.4} - 50%{transform:rotate(45deg) translateY(5px);opacity:.9} -} - -/* ── SECTIONS ────────────────────────────── */ -section{padding:6rem 2rem} -.container{max-width:960px;margin:0 auto} -.origin-container{position:relative} - +.skip-link:focus{position:fixed;left:1rem;top:0;width:auto;height:auto;overflow:visible} +.container{width:min(var(--content-max),calc(100vw - (var(--page-x) * 2)));margin:0 auto} +.section{padding:clamp(4.5rem,8vw,6.5rem) 0} .section-label{ - font-size:.78rem; - font-weight:600; - letter-spacing:.3em; - text-transform:uppercase; - color:var(--accent); - margin-bottom:1rem; -} -.section-title{ - font-family:var(--serif); - font-size:clamp(2rem, 5vw, 3.2rem); - font-weight:600; - line-height:1.15; - margin-bottom:1.5rem; -} -.section-body{ - color:var(--muted); - font-size:1.05rem; - max-width:620px; -} - -/* ── ORIGIN ─────────────────────────────── */ -.origin{border-top:1px solid var(--border)} + display:inline-flex;align-items:center;gap:.55rem;font-family:var(--mono);font-size:.72rem;font-weight:500; + letter-spacing:.18em;text-transform:uppercase;color:var(--accent); +} +.section-label::before{content:'/';color:var(--accent-strong)} +.section-head{display:grid;gap:.75rem;max-width:44rem;margin-bottom:1.5rem} +.section-head h2,.origin-copy h2,.context-copy h2,.theory-copy h2,.final-main h2{ + font-family:var(--display);font-size:clamp(2.6rem,6vw,4.4rem);line-height:.88;letter-spacing:-.04em;text-transform:uppercase; +} +.section-head p,.origin-copy p,.context-copy p,.context-panel p,.theory-copy p,.social-card p,.footer-copy,.hero-summary,.hero-note,.hero-stat p{color:var(--muted)} +em{font-style:normal;color:var(--accent)} +.panel-top{ + display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:.65rem; + padding:.9rem 1rem;border-bottom:1px solid var(--border);font-family:var(--mono);font-size:.68rem; + letter-spacing:.16em;text-transform:uppercase;color:var(--muted);background:rgba(255,255,255,.015); +} +.panel-top span:nth-child(2){text-align:center} +.panel-top span:last-child{text-align:right} +.reveal{opacity:0;transform:translateY(18px);transition:opacity .5s ease,transform .5s ease} +.reveal.is-visible{opacity:1;transform:none} +.site-nav{ + position:sticky;top:0;z-index:100;background:rgba(10,10,10,.9);backdrop-filter:blur(16px); + border-bottom:1px solid rgba(255,255,255,.05);padding:.95rem var(--page-x); + display:grid;grid-template-columns:auto 1fr auto;align-items:center;gap:1rem; +} +.brand{display:inline-flex;align-items:center;gap:.7rem;text-decoration:none} +.brand-mark{width:2rem;height:2rem;display:block;flex:0 0 auto} +.brand-mark-dot{fill:var(--accent)} +.brand-wordmark{ + font-family:var(--display);font-size:1.4rem;font-weight:700;letter-spacing:-.03em;text-transform:uppercase; +} +.brand-wordmark span{color:var(--accent)} +.nav-links{display:flex;align-items:center;justify-content:center;gap:1.2rem;flex-wrap:wrap} +.nav-links a,.nav-mobile a{ + text-decoration:none;font-family:var(--mono);font-size:.72rem;font-weight:500;letter-spacing:.16em;text-transform:uppercase;color:var(--muted); +} +.nav-links a:hover,.nav-mobile a:hover{color:var(--text)} +.nav-actions{display:flex;align-items:center;justify-content:flex-end;gap:.75rem} +.nav-cta,.hero-cta,.example-reset{ + display:inline-flex;align-items:center;justify-content:center;min-height:2.8rem;padding:.72rem 1.25rem;border-radius:var(--radius); + border:1px solid rgba(230,60,20,.4);background:var(--accent);color:#120c09;text-decoration:none; + font-family:var(--mono);font-size:.74rem;font-weight:600;letter-spacing:.16em;text-transform:uppercase; + transition:transform .2s ease,background .2s ease,border-color .2s ease; +} +.nav-cta:hover,.hero-cta:hover,.example-reset:hover{background:var(--accent-strong);border-color:var(--accent-strong);transform:translateY(-1px)} +.nav-hamburger{ + display:none;flex-direction:column;justify-content:center;gap:4px;width:2.1rem;height:2.1rem; + border:1px solid var(--border);border-radius:var(--radius);background:transparent;color:var(--text); +} +.nav-hamburger span[aria-hidden='true']{display:block;height:1px;background:currentColor} +.nav-mobile{ + display:none;grid-column:1 / -1;padding-top:.75rem;border-top:1px solid rgba(255,255,255,.06); + flex-direction:column;gap:.8rem; +} +.nav-mobile-cta{color:var(--accent)!important} +.hero{padding-top:clamp(2rem,6vw,3.5rem)} +.hero-panel,.origin-stage,.context-panel,.example-shell,.quote-card,.final-panel{ + position:relative;overflow:hidden;background:linear-gradient(180deg,rgba(255,255,255,.02),rgba(255,255,255,0)),var(--surface); + border:1px solid var(--border);border-radius:var(--radius); +} +.hero-panel::before,.origin-stage::before,.context-panel::before,.example-shell::before,.quote-card::before,.final-panel::before{ + content:'';position:absolute;left:0;top:0;right:0;height:1px;background:linear-gradient(90deg,var(--accent),rgba(255,255,255,.08) 36%,rgba(255,255,255,0)); +} +.hero-grid{ + display:grid;grid-template-columns:minmax(0,1.15fr) minmax(280px,.85fr);gap:1.25rem; + padding:clamp(1.35rem,3vw,2rem); +} +.eyebrow{ + font-family:var(--mono);font-size:.72rem;font-weight:500;letter-spacing:.18em;text-transform:uppercase;color:var(--accent); +} +.hero-copy h1{ + margin-top:.55rem;font-family:var(--display);font-size:clamp(4.6rem,11vw,8.8rem);line-height:.82; + letter-spacing:-.05em;text-transform:uppercase; +} +.hero-copy h1 span{ + display:block;color:transparent;-webkit-text-stroke:1.2px var(--accent);text-stroke:1.2px var(--accent); +} +.hero-summary{max-width:36rem;margin-top:1rem;font-size:1.04rem} +.hero-actions{display:flex;flex-wrap:wrap;align-items:center;gap:1rem;margin-top:1.35rem} +.hero-note{font-size:.85rem} +.hero-side{display:grid;gap:.95rem} +.hero-stat{ + padding:1rem;background:var(--surface-soft);border:1px solid rgba(255,255,255,.08);border-radius:var(--radius); +} +.hero-stat-label,.phase-index,.quote-label,.social-label,.footer-brand,.context-panel h3,.use-case span{ + font-family:var(--mono);font-size:.72rem;font-weight:500;letter-spacing:.16em;text-transform:uppercase; +} +.hero-stat strong{ + display:block;margin-top:.45rem;font-family:var(--display);font-size:2rem;line-height:.85;letter-spacing:-.04em;text-transform:uppercase; +} +.hero-tags{display:flex;flex-wrap:wrap;gap:.5rem} +.hero-tags span,.phase-chip,.info-list span,.example-meta-list span{ + display:inline-flex;align-items:center;padding:.28rem .62rem;border-radius:999px;border:1px solid rgba(255,255,255,.1); + background:rgba(255,255,255,.03);font-family:var(--mono);font-size:.72rem;letter-spacing:.12em;text-transform:uppercase;color:var(--muted); +} +.hero-footer{ + display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:.75rem;padding:0 1.25rem 1.2rem; +} +.hero-footer span{ + min-height:3rem;display:flex;align-items:center;justify-content:center;padding:.75rem;border:1px solid rgba(255,255,255,.08); + border-radius:var(--radius);font-family:var(--mono);font-size:.68rem;letter-spacing:.16em;text-transform:uppercase;color:var(--muted); +} +.origin-grid,.context-grid,.theory-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:1.25rem;align-items:start} +.origin-stage{padding-bottom:1.1rem} .origin-year{ - font-family:var(--serif); - font-size:clamp(6rem, 15vw, 12rem); - font-weight:700; - color:rgba(201,168,76,.06); - position:absolute; - top:50%;left:50%; - transform:translate(-50%,-50%); - line-height:1; - user-select:none; - pointer-events:none; - white-space:nowrap; - z-index:0; -} -.origin .section-label, -.origin .section-title, -.origin-body, -.origin-accent{position:relative;z-index:1} -.origin-body{ - color:var(--muted); - font-size:1.05rem; - max-width:620px; -} -.origin-accent{ - width:40px;height:1px; - background:var(--accent); - margin-top:2rem; - opacity:.5; -} - -/* ── THEORY ──────────────────────────────── */ -.theory{border-top:1px solid var(--border)} -.theory-quote{ - font-family:var(--serif); - font-size:clamp(1.4rem, 3.5vw, 2rem); - font-weight:400; - font-style:italic; - line-height:1.5; - color:var(--text); - max-width:700px; - margin:3rem 0 1rem; - position:relative; - padding-left:2rem; -} -.theory-quote::before{ - content:''; - position:absolute; - left:0;top:0;bottom:0; - width:2px; - background:var(--accent); -} -.theory-attrib{ - font-size:.92rem; - color:var(--muted); - padding-left:2rem; -} - -/* ── CONCEPT (The Rules) ─────────────────── */ -.concept{border-top:1px solid var(--border)} -.concept-grid{ - display:grid; - grid-template-columns:1fr 1fr; - gap:3rem; - margin-top:3rem; -} -.concept-card{ - background:var(--surface); - border:1px solid var(--border); - border-radius:3px; - padding:2rem; - transition:border-color .3s; -} -.concept-card:hover{border-color:var(--accent)} -.concept-card .num{ - font-family:var(--serif); - font-size:2.5rem; - font-weight:700; - color:rgba(223,192,106,.58); - line-height:1; - margin-bottom:.75rem; -} -.concept-card h3{ - font-family:var(--serif); - font-size:1.3rem; - font-weight:600; - margin-bottom:.5rem; -} -.concept-card p{color:var(--muted-strong);font-size:.98rem} - -/* ── MECHANICS ───────────────────────────── */ -.mechanics{border-top:1px solid var(--border)} -.mech-steps{ - display:grid; - grid-template-columns:repeat(4,1fr); - gap:2rem; - margin-top:3rem; -} -.mech-step{position:relative;padding-left:0} -.mech-step .icon{ - font-size:1.8rem; - margin-bottom:.75rem; - display:block; - filter:grayscale(.3); -} -.mech-step h3{ - font-family:var(--serif); - font-size:1.15rem; - font-weight:600; - margin-bottom:.4rem; -} -.mech-step p{color:var(--muted);font-size:.95rem} - -/* ── EXAMPLE ─────────────────────────────── */ -.example{background:var(--surface);border-top:1px solid var(--border);border-bottom:1px solid var(--border)} -.example-layout{ - display:grid; - grid-template-columns:280px 1fr; - gap:3rem; - align-items:start; -} -.example-left{position:sticky;top:6rem} -.example-left .section-title{margin-bottom:1.5rem} -.example-demo{} -.example-question{ - font-family:var(--serif); - font-size:1.6rem; - font-weight:600; - margin-bottom:1.5rem; - line-height:1.3; -} -.example-options{ - display:grid; - grid-template-columns:repeat(6,1fr); - gap:.6rem; + display:flex;gap:.2rem;padding:1.2rem 1rem .5rem;font-family:var(--display);font-size:clamp(5rem,15vw,8rem);line-height:.82;letter-spacing:-.06em;text-transform:uppercase; +} +.origin-year .accent{color:var(--accent)} +.origin-stage-copy{padding:0 1rem;color:var(--muted);max-width:24rem} +.origin-copy{display:grid;gap:1rem;padding-top:.3rem} +.info-list{display:flex;flex-wrap:wrap;gap:.55rem} +.phase-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:1rem} +.phase-card,.use-case,.social-card{ + padding:1rem;background:var(--surface);border:1px solid var(--border);border-radius:var(--radius); +} +.phase-card h3,.social-value,.use-case h4{ + margin-top:.55rem;font-family:var(--display);font-size:2rem;line-height:.86;letter-spacing:-.04em;text-transform:uppercase; +} +.phase-card p,.use-case p{margin-top:.6rem;color:var(--muted)} +.phase-chip{margin-top:1rem;color:var(--accent)} +.context-copy{display:grid;gap:1rem} +.context-principles{display:grid;gap:.85rem} +.context-principles div,.example-meta{ + padding:1rem;background:var(--surface-soft);border:1px solid rgba(255,255,255,.08);border-radius:var(--radius); +} +.context-principles strong{display:block;font-family:var(--display);font-size:1.5rem;line-height:.9;letter-spacing:-.03em;text-transform:uppercase} +.context-panel{padding-bottom:1rem} +.context-panel h3{padding:1.05rem 1rem 0;color:var(--accent)} +.context-panel p{padding:0 1rem;margin-top:.65rem} +.use-case-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:.85rem;margin-top:.85rem} +.use-case h4{font-size:1.5rem} +.example-shell{padding-bottom:1rem} +.example-main{ + display:grid;grid-template-columns:minmax(0,1fr) minmax(240px,.8fr);gap:1rem;padding:1.15rem 1rem 0; +} +.example-question{font-family:var(--display);font-size:clamp(2rem,5vw,3rem);line-height:.88;letter-spacing:-.04em;text-transform:uppercase} +.example-vote-status{min-height:1.5rem;margin-top:.7rem;font-size:.9rem;color:var(--muted)} +.example-vote-status.pending{color:var(--accent)} +.example-vote-status.error{color:#d79a97} +.example-vote-status.success{color:#8fcf92} +.example-turnstile{margin-top:.8rem} +.example-meta{display:grid;gap:.8rem;align-content:start} +.example-grid{ + display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:.7rem;padding:1rem; } .example-opt{ - background:var(--surface2); - border:1px solid var(--border); - border-radius:3px; - padding:.6rem .5rem; - font-family:var(--sans); - font-size:.96rem; - font-weight:400; - color:var(--text); - cursor:pointer; - transition:all .2s; - text-align:center; -} -.example-opt:hover{border-color:var(--accent);color:var(--accent)} -.example-opt .vote-bar{ - display:none; - height:5px; - border-radius:2.5px; - background:var(--accent); - margin-top:.4rem; - width:0; - transition:width .6s ease; -} -.example-opt .vote-pct{ - display:none; - font-size:.78rem; - font-weight:700; - letter-spacing:.05em; - color:var(--muted-strong); - margin-top:.2rem; -} -.example-layout.revealed .example-opt .vote-bar, -.example-layout.revealed .example-opt .vote-pct{display:block} -/* Dim all options in revealed state, then un-dim popular and my-pick */ -.example-layout.revealed .example-opt{ - opacity:1; - cursor:default; - background:#151515; - border-color:#38332a; - color:var(--muted-strong); -} -.example-layout.revealed .example-opt.popular, -.example-layout.revealed .example-opt.my-pick{opacity:1} -.example-opt.popular{position:relative} -.example-layout.revealed .example-opt.popular{ - border:2px solid var(--accent2); - background:rgba(223,192,106,.18); - color:var(--accent2); - font-weight:600; - box-shadow:0 0 16px rgba(223,192,106,.18),0 0 4px rgba(223,192,106,.12); -} -.example-opt.popular::after{ - content:'focal point'; - display:none; - font-size:.78rem; - font-weight:600; - letter-spacing:.1em; - text-transform:uppercase; - opacity:.6; - margin-top:.15rem; -} -.example-layout.revealed:not(.has-tally) .example-opt.popular::after{display:block} -/* User's own pick */ -.example-opt.my-pick{position:relative} -.example-layout.revealed .example-opt.my-pick{ - border:2px solid var(--text); - background:rgba(232,228,222,.08); - color:var(--text); - font-weight:500; -} -.example-layout.revealed .example-opt.my-pick::before{ - content:'your pick'; - display:block; - font-size:.78rem; - font-weight:600; - letter-spacing:.1em; - text-transform:uppercase; - color:var(--text); - white-space:nowrap; - opacity:.7; - margin-bottom:.15rem; -} -/* When the user picked the popular option, gold wins */ -.example-layout.revealed .example-opt.my-pick.popular{ - border-color:var(--accent); - color:var(--accent); -} -/* Hide the absolutely-positioned ::before; it overlaps the cell above */ -.example-layout.revealed .example-opt.my-pick.popular::before{ - display:none; -} -/* Repurpose ::after to say "your pick" instead of "focal point" */ -.example-layout.revealed .example-opt.my-pick.popular::after{ - content:'your pick \b7 focal point'; - display:block; -} -.example-layout.revealed .example-insight{display:block} + position:relative;display:flex;flex-direction:column;justify-content:flex-end;gap:.15rem;min-height:7rem;padding:.85rem; + overflow:hidden;background:rgba(255,255,255,.02);border:1px solid rgba(255,255,255,.08);border-radius:var(--radius);color:var(--text); + transition:border-color .2s ease,transform .2s ease,color .2s ease,background .2s ease; +} +.example-opt:hover:not(.disabled){border-color:var(--accent);transform:translateY(-2px)} +.example-opt.my-pick{border-color:var(--accent);background:rgba(230,60,20,.08);color:var(--accent)} +.example-opt.popular{box-shadow:inset 0 0 0 1px rgba(230,60,20,.16)} +.opt-n{position:relative;z-index:1;font-family:var(--display);font-size:1.9rem;line-height:.85;letter-spacing:-.04em;text-transform:uppercase} +.opt-meta{position:relative;z-index:1;font-family:var(--mono);font-size:.64rem;letter-spacing:.12em;text-transform:uppercase;color:var(--muted)} +.vote-bar{ + position:absolute;left:0;right:0;bottom:0;height:0;background:linear-gradient(180deg,rgba(230,60,20,.22),rgba(230,60,20,.5)); + transition:height .4s ease;width .4s ease; +} +.vote-pct{ + position:absolute;right:.65rem;top:.65rem;font-family:var(--mono);font-size:.66rem;letter-spacing:.12em;text-transform:uppercase;color:var(--muted-strong); +} +.example-grid.revealed .example-opt{cursor:default} .example-insight{ - margin-top:1.5rem; - font-size:.92rem; - color:var(--muted-strong); - display:none; - font-style:italic; - padding-left:1rem; - border-left:2px solid var(--accent); -} -.example-vote-status{ - min-height:1.5rem; - margin:.85rem 0 1rem; - font-size:.88rem; - color:var(--muted); -} -.example-vote-status.pending{color:var(--accent)} -.example-vote-status.error{color:#d9a29a} -.example-vote-status.success{color:var(--muted-strong)} -.example-turnstile{ - min-height:66px; - margin:0 0 1rem; -} -.example-turnstile[hidden]{display:none} -.example-layout.verifying .example-opt, -.example-layout.demo-disabled .example-opt{ - pointer-events:none; -} -.example-layout.verifying .example-opt{ - opacity:.72; -} -.example-layout.demo-disabled .example-opt{ - cursor:not-allowed; - opacity:.55; -} -.example-layout.demo-disabled .example-opt:hover{ - border-color:var(--border); - color:var(--text); -} - -/* ── LEARN (Educational) ────────────────── */ -.learn{border-top:1px solid var(--border)} -.learn-subsection{margin-top:4rem} -.learn-subsection:first-child{margin-top:0} - -.learn-callout{ - background:linear-gradient(135deg, rgba(201,168,76,.04) 0%, rgba(17,17,17,.6) 100%); - border:1px solid rgba(201,168,76,.12); - border-left:3px solid var(--accent); - border-radius:0 3px 3px 0; - padding:2rem 2.5rem; - margin:2rem 0; - font-family:var(--serif); - font-size:clamp(1.1rem, 2.5vw, 1.35rem); - font-style:italic; - line-height:1.6; - color:var(--text); -} -.learn-callout-attrib{ - font-family:var(--sans); - font-style:normal; - font-size:.86rem; - color:var(--muted); - margin-top:.75rem; - letter-spacing:.03em; -} - -.learn-steps{ - display:grid; - grid-template-columns:1fr 1fr; - gap:2rem; - margin-top:2rem; -} -.learn-step{ - background:var(--surface); - border:1px solid var(--border); - border-radius:3px; - padding:1.75rem; - transition:border-color .3s; -} -.learn-step:hover{border-color:var(--accent)} -.learn-step .num{ - font-family:var(--serif); - font-size:2rem; - font-weight:700; - color:rgba(223,192,106,.58); - line-height:1; - margin-bottom:.5rem; -} -.learn-step h3{ - font-family:var(--serif); - font-size:1.15rem; - font-weight:600; - margin-bottom:.4rem; -} -.learn-step p{color:var(--muted-strong);font-size:.96rem} - -.learn-apps{ - display:grid; - grid-template-columns:1fr 1fr; - gap:1.5rem; - margin-top:2rem; -} -.learn-app{ - background:var(--surface); - border:1px solid var(--border); - border-radius:3px; - padding:1.75rem; - transition:border-color .3s; -} -.learn-app:hover{border-color:var(--accent)} -.learn-app-label{ - font-size:.74rem; - font-weight:600; - letter-spacing:.2em; - text-transform:uppercase; - color:var(--accent); - margin-bottom:.5rem; -} -.learn-app h3{ - font-family:var(--serif); - font-size:1.1rem; - font-weight:600; - margin-bottom:.4rem; -} -.learn-app p{color:var(--muted-strong);font-size:.95rem} -.learn-app a{ - color:var(--accent); - text-decoration:underline; - text-decoration-thickness:1px; - text-underline-offset:.16em; - transition:color .2s,text-decoration-color .2s; -} -.learn-app a:hover{color:var(--accent2);text-decoration-color:var(--accent2)} - -.learn-ethereum{ - position:relative; - background:linear-gradient(180deg, rgba(201,168,76,.03) 0%, transparent 100%); - border:1px solid rgba(201,168,76,.1); - border-radius:3px; - padding:2.5rem; - margin-top:2rem; -} -.learn-ethereum p{ - color:var(--muted); - font-size:1rem; - max-width:680px; -} -.learn-ethereum strong{color:var(--text);font-weight:500} - -.learn-reading{ - margin-top:3rem; - border:1px solid var(--border); - border-radius:3px; - background:var(--surface); -} -.learn-reading summary{ - padding:1.25rem 1.75rem; - font-family:var(--serif); - font-size:1.1rem; - font-weight:600; - color:var(--text); - cursor:pointer; - list-style:none; - display:flex; - align-items:center; - gap:.75rem; - transition:color .2s; -} -.learn-reading summary:hover{color:var(--accent)} -.learn-reading summary::-webkit-details-marker{display:none} -.learn-reading summary::before{ - content:'+'; - font-family:var(--sans); - font-size:1.2rem; - font-weight:300; - color:var(--accent); - width:1.5rem; - text-align:center; - transition:transform .2s; -} -.learn-reading[open] summary::before{content:'\2212'} -.learn-reading-list{ - padding:0 1.75rem 1.5rem; - border-top:1px solid var(--border); -} -.learn-reading-list li{ - list-style:none; - padding:.6rem 0; - border-bottom:1px solid rgba(34,34,34,.6); - font-size:.92rem; - color:var(--muted); -} -.learn-reading-list li:last-child{border-bottom:none} -.learn-reading-list a{ - color:var(--accent); - text-decoration:none; - transition:color .2s; -} -.learn-reading-list a:hover{color:var(--accent2)} -.learn-reading-list .reading-year{ - font-size:.82rem; - color:#555; - margin-left:.5rem; -} - -/* ── SOCIAL PROOF ───────────────────────── */ -.social-proof{border-top:1px solid var(--border)} -.social-proof-grid{ - display:grid; - grid-template-columns:repeat(3,1fr); - gap:1rem; - margin-top:3rem; -} -.social-card{ - position:relative; - overflow:hidden; - background:linear-gradient(180deg, rgba(201,168,76,.06), rgba(17,17,17,.96)); - border:1px solid var(--border); - border-radius:3px; - padding:1.5rem; -} -.social-card::before{ - content:''; - position:absolute; - inset:0 auto auto 0; - width:100%; - height:1px; - background:linear-gradient(90deg, transparent, rgba(201,168,76,.5), transparent); -} -.social-value{ - font-family:var(--serif); - font-size:clamp(2.6rem, 6vw, 4rem); - font-weight:600; - line-height:1; - color:var(--accent); - margin-bottom:.75rem; -} -.social-label{ - font-size:.78rem; - font-weight:600; - letter-spacing:.14em; - text-transform:uppercase; - color:var(--text); - margin-bottom:.5rem; -} -.social-copy{ - color:var(--muted); - font-size:.96rem; - max-width:24ch; -} -.social-proof-note{ - color:var(--muted); - font-size:.95rem; - margin-top:1.25rem; -} - -/* ── FINAL CTA ───────────────────────────── */ -.final-cta{ - text-align:center; - padding:8rem 2rem; - border-top:1px solid var(--border); - position:relative; -} -.final-cta::before{ - content:'';position:absolute;inset:0; - background:radial-gradient(ellipse 50% 60% at 50% 60%, rgba(201,168,76,.05) 0%, transparent 70%); - pointer-events:none; -} -.final-cta .section-title{margin-bottom:1rem;position:relative} -.final-cta p{color:var(--muted);margin-bottom:2.5rem;position:relative} -.final-cta .hero-cta{position:relative} - -/* ── FOOTER ──────────────────────────────── */ -footer{ - padding:2.5rem 2rem; - border-top:1px solid var(--border); - font-size:.82rem; - color:var(--muted-soft); - letter-spacing:.03em; -} -.footer-inner{ - max-width:960px; - margin:0 auto; - display:flex; - justify-content:space-between; - align-items:center; - gap:2rem; - flex-wrap:wrap; + display:flex;align-items:center;justify-content:space-between;gap:1rem;padding:0 1rem; +} +.example-insight p{color:var(--muted);max-width:48rem} +.example-reset{background:transparent;color:var(--text)} +.example-reset:hover{color:#120c09} +.theory-copy{display:grid;gap:1rem} +.quote-card{padding:1rem} +.quote-label{color:var(--accent)} +.quote-card blockquote{ + margin-top:.75rem;font-family:var(--serif);font-size:clamp(1.6rem,4vw,2.4rem);font-style:italic;line-height:1.4;color:var(--text); +} +.quote-card p{margin-top:1rem;color:var(--muted)} +.social-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:1rem} +.social-value{font-size:clamp(2.4rem,6vw,3.5rem)} +.social-card p{margin-top:.5rem} +.final-section{padding-bottom:5rem} +.final-panel{padding-bottom:1rem} +.final-main{ + display:grid;grid-template-columns:minmax(0,1fr) auto;gap:1rem;padding:1.2rem 1rem; +} +.final-actions{display:grid;justify-items:start;gap:1rem;align-content:center} +.footer-grid{ + display:grid;grid-template-columns:1.4fr .8fr .8fr;gap:1rem;padding:0 1rem 1rem;border-top:1px solid rgba(255,255,255,.06);margin-top:1rem;padding-top:1rem; } .footer-brand{ - font-family:var(--serif); - font-size:1rem; - font-weight:700; - color:var(--muted); - letter-spacing:.03em; + font-family:var(--display);font-size:1.6rem;font-weight:700;letter-spacing:-.03em;text-transform:uppercase; } .footer-brand span{color:var(--accent)} -.footer-desc{ - color:var(--muted-soft); - font-size:.78rem; - margin-top:.25rem; -} -.footer-links{ - display:flex; - gap:1.5rem; - align-items:center; -} -.footer-links a{ - color:var(--muted); - text-decoration:none; - transition:color .2s; -} -.footer-links a:hover{color:var(--accent)} +.footer-links{display:grid;gap:.45rem;align-content:start} +.footer-links a{text-decoration:none;color:var(--muted)} +.footer-links a:hover{color:var(--text)} .footer-meta{ - display:flex; - align-items:center; - gap:1rem; - font-family:'SF Mono',SFMono-Regular,Consolas,'Liberation Mono',Menlo,monospace; - font-size:.74rem; - color:var(--muted-soft); -} - -/* ── RESPONSIVE ──────────────────────────── */ -@media(max-width:700px){ - .concept-grid{grid-template-columns:1fr} - .mech-steps{grid-template-columns:1fr} - .example-layout{grid-template-columns:1fr} - .learn-steps{grid-template-columns:1fr} - .learn-apps{grid-template-columns:1fr} - .learn-callout{padding:1.5rem} - .social-proof-grid{grid-template-columns:1fr} - .example-left{position:static} - .example-options{grid-template-columns:repeat(3,1fr)} - nav{padding:1rem 1.25rem} - section{padding:4rem 1.25rem} - .hero{padding:5rem 1.25rem 2rem} - .footer-inner{flex-direction:column;text-align:center;gap:1rem} -} - -/* ── HERO ENTRANCE ────────────────────────── */ -@keyframes heroIn{from{opacity:0;transform:translateY(24px)}to{opacity:1;transform:none}} -.hero-anim{animation:heroIn .7s ease forwards;opacity:0} -.ha-1{animation-delay:.15s} -.ha-2{animation-delay:.3s} -.ha-3{animation-delay:.45s} - -/* ── SCROLL ANIMATIONS ───────────────────── */ -@keyframes revealUp{from{opacity:0;transform:translateY(16px)}to{opacity:1;transform:none}} -.reveal{animation:revealUp .5s ease both} -.reveal-delay-1{animation-delay:.08s} -.reveal-delay-2{animation-delay:.16s} -.reveal-delay-3{animation-delay:.24s} -.reveal-delay-4{animation-delay:.32s} + padding:0 1rem;font-family:var(--mono);font-size:.72rem;letter-spacing:.12em;text-transform:uppercase;color:var(--muted); +} +@media(max-width:980px){ + .hero-grid,.origin-grid,.context-grid,.theory-grid,.final-main,.example-main,.footer-grid{grid-template-columns:1fr} + .phase-grid,.social-grid{grid-template-columns:1fr} + .use-case-grid{grid-template-columns:1fr 1fr} + .panel-top span:nth-child(2),.panel-top span:last-child{text-align:left} +} +@media(max-width:760px){ + .site-nav{grid-template-columns:auto auto} + .nav-links{display:none} + .nav-hamburger{display:flex} + .nav-mobile{display:none} + .site-nav.menu-open .nav-mobile{display:flex} + .nav-mobile{grid-column:1 / -1} + .hero-copy h1{font-size:clamp(3.7rem,19vw,6rem)} + .hero-footer{grid-template-columns:repeat(2,minmax(0,1fr))} + .example-grid{grid-template-columns:repeat(2,minmax(0,1fr))} + .use-case-grid{grid-template-columns:1fr} +} +@media(max-width:560px){ + .panel-top{grid-template-columns:1fr} + .hero-actions,.example-insight{align-items:flex-start;flex-direction:column} + .example-grid{grid-template-columns:1fr} + .footer-grid{grid-template-columns:1fr} + .hero-footer{grid-template-columns:1fr} +} diff --git a/public/styles/layout.css b/public/styles/layout.css index 0cc742b..1c3f8e7 100644 --- a/public/styles/layout.css +++ b/public/styles/layout.css @@ -4,40 +4,39 @@ .queue-main{display:flex;flex-direction:column;gap:1.25rem;min-width:0;padding:.15rem 0} .queue-main-top{display:flex;align-items:flex-end;justify-content:space-between;gap:1rem;flex-wrap:wrap;padding-bottom:1.1rem;border-bottom:1px solid rgba(255,255,255,.06)} .section-kicker{font-size:.78rem;font-weight:600;letter-spacing:.18em;text-transform:uppercase;color:var(--accent)} -.queue-title-wrap h2{font-size:clamp(2.2rem,4.6vw,3.6rem);line-height:.9} +.queue-title-wrap h2{font-family:var(--display);letter-spacing:-.02em;font-size:clamp(2.2rem,4.6vw,3.6rem);line-height:.9} .queue-intro{max-width:34rem;color:var(--muted);font-size:1rem;line-height:1.65;margin-top:.65rem} .queue-stat-block{display:flex;flex-direction:column;align-items:flex-end;gap:.3rem;min-width:10rem} .queue-stat-label{font-size:.78rem;font-weight:500;letter-spacing:.18em;text-transform:uppercase;color:var(--muted)} -.queue-stat-value{font-family:var(--serif);font-size:clamp(2.4rem,5vw,3.4rem);font-weight:600;line-height:.88} +.queue-stat-value{font-family:var(--display);font-size:clamp(2.6rem,5vw,3.6rem);font-weight:700;line-height:.85;letter-spacing:-.04em} .queue-inline-roster{display:none;flex-direction:column;gap:.85rem;padding:1rem 0 1.05rem;border-bottom:1px solid rgba(255,255,255,.06)} .queue-inline-roster-head{display:flex;align-items:baseline;justify-content:space-between;gap:1rem;flex-wrap:wrap} .queue-inline-roster-title{font-size:.78rem;font-weight:600;letter-spacing:.18em;text-transform:uppercase;color:var(--accent)} .queue-inline-roster-meta{font-size:.8rem;letter-spacing:.12em;text-transform:uppercase;color:var(--muted)} .queue-flow{display:flex;flex-direction:column;gap:1rem;max-width:none} -#active-match-banner{display:flex;flex-direction:column;gap:.35rem;background:rgba(201,168,76,.08);border:1px solid rgba(201,168,76,.35);border-radius:var(--radius);padding:.85rem 1rem;font-size:.92rem;color:var(--text)} +#active-match-banner{display:flex;flex-direction:column;gap:.35rem;background:rgba(230,60,20,.08);border:1px solid rgba(230,60,20,.35);border-radius:var(--radius);padding:.85rem 1rem;font-size:.92rem;color:var(--text)} #active-match-banner strong{font-size:.72rem;font-weight:600;letter-spacing:.16em;text-transform:uppercase;color:var(--accent)} #active-match-banner.is-forfeited{background:rgba(229,57,53,.08);border-color:rgba(229,57,53,.35)} #active-match-banner.is-forfeited strong{color:#f09a97} -#forming-banner{display:grid;grid-template-columns:minmax(0,1fr) auto;grid-template-areas:'main side' 'foot foot';gap:1rem 1.5rem;align-items:start;background:linear-gradient(135deg,rgba(201,168,76,.08),rgba(255,152,0,.05));border:1px solid rgba(201,168,76,.48);border-radius:var(--radius);padding:1rem 1.1rem;font-size:.92rem;color:var(--text);text-align:left;margin-top:0;position:relative;overflow:hidden;transition:border-color .2s ease,background .2s ease,transform .2s ease} -#forming-banner.is-armed{border-color:rgba(201,168,76,.72);background:linear-gradient(135deg,rgba(201,168,76,.15),rgba(255,152,0,.08));transform:translateY(-1px)} -#forming-banner::before{content:'';position:absolute;left:0;top:0;bottom:0;width:1px;background:linear-gradient(to bottom,transparent,rgba(201,168,76,.65),transparent)} +#forming-banner{display:grid;grid-template-columns:minmax(0,1fr) auto;grid-template-areas:'main side' 'foot foot';gap:1rem 1.5rem;align-items:start;background:linear-gradient(135deg,rgba(230,60,20,.08),rgba(255,77,37,.05));border:1px solid rgba(230,60,20,.48);border-radius:var(--radius);padding:1rem 1.1rem;font-size:.92rem;color:var(--text);text-align:left;margin-top:0;position:relative;overflow:hidden;transition:border-color .2s ease,background .2s ease,transform .2s ease} +#forming-banner.is-armed{border-color:rgba(230,60,20,.72);background:linear-gradient(135deg,rgba(230,60,20,.15),rgba(255,77,37,.08));transform:translateY(-1px)} +#forming-banner::before{content:'';position:absolute;left:0;top:0;bottom:0;width:1px;background:linear-gradient(to bottom,transparent,rgba(230,60,20,.65),transparent)} .forming-main,.forming-side,.forming-banner-foot{position:relative;z-index:1} .forming-main{grid-area:main} .forming-label{font-size:.78rem;font-weight:600;letter-spacing:.18em;text-transform:uppercase;color:var(--accent);margin-bottom:.45rem} -.forming-title{font-family:var(--serif);font-size:1.45rem;line-height:1;margin-bottom:.35rem} +.forming-title{font-family:var(--display);font-size:clamp(1.85rem,2.6vw,2.25rem);line-height:.9;letter-spacing:-.03em;margin-bottom:.35rem;text-transform:uppercase} .forming-title strong{color:var(--accent2);font-weight:600} .forming-copy{font-size:.96rem;line-height:1.65;color:var(--muted);max-width:30rem} -.forming-side{grid-area:side} -.forming-side{display:flex;flex-direction:column;align-items:flex-end;gap:.15rem;white-space:nowrap} +.forming-side{grid-area:side;display:flex;flex-direction:column;align-items:flex-end;gap:.15rem;white-space:nowrap} .forming-side-label{font-size:.78rem;letter-spacing:.14em;text-transform:uppercase;color:var(--muted)} -.forming-side-value{font-family:var(--serif);font-size:1.2rem} +.forming-side-value{font-family:var(--display);font-size:1.15rem;letter-spacing:-.02em;text-transform:uppercase} .forming-side-value strong{font-size:1.85rem;color:var(--accent2);font-weight:600} .forming-banner-foot{grid-area:foot;display:flex;align-items:flex-end;justify-content:space-between;gap:.85rem;flex-wrap:wrap;padding-top:.35rem;border-top:1px solid rgba(255,255,255,.06)} .forming-readiness{display:flex;flex-direction:column;gap:.1rem;max-width:27rem} #start-now-meta{font-size:.84rem;font-weight:600;letter-spacing:.14em;text-transform:uppercase;color:var(--text)} #start-now-note{font-size:.88rem;color:var(--muted);line-height:1.5} #start-now-btn{min-width:170px} -#start-now-btn[aria-pressed='true']{border-color:var(--accent);color:var(--accent);background:rgba(201,168,76,.08)} +#start-now-btn[aria-pressed='true']{border-color:var(--accent);color:var(--accent);background:rgba(230,60,20,.08)} .queue-action-row{align-items:center;gap:.75rem;margin-top:.25rem} .queue-action-row button{min-height:3rem;min-width:11rem} .queue-side{--queue-side-top-inset:.15rem;position:relative;min-width:0;display:flex;flex-direction:column;gap:1rem;padding:var(--queue-side-top-inset) 0 0 clamp(1rem,1.8vw,1.5rem)} @@ -47,24 +46,23 @@ .queue-side-copy{font-size:.96rem;line-height:1.65;color:var(--muted);margin-top:.45rem} .queue-players-list{list-style:none;display:flex;flex-wrap:wrap;align-content:flex-start;gap:.65rem;margin:0;padding:0} .queue-players-list li{display:inline-flex;align-items:center;max-width:100%;padding:.48rem .82rem;background:transparent;border:1px solid var(--border);border-radius:999px;font-size:.9rem;letter-spacing:.03em;color:var(--text);line-height:1.25;overflow-wrap:anywhere;transition:border-color .2s,background .2s,color .2s} -.queue-players-list li.is-self{border-color:rgba(201,168,76,.55);background:rgba(201,168,76,.08);color:var(--accent);font-weight:600} +.queue-players-list li.is-self{border-color:rgba(230,60,20,.55);background:rgba(230,60,20,.08);color:var(--accent);font-weight:600} .queue-empty-state{display:block;width:100%;padding:.15rem 0;color:var(--muted);font-size:.92rem;letter-spacing:.01em;line-height:1.65} .queue-side-note{font-size:.88rem;color:var(--muted);line-height:1.65;padding-top:.2rem;border-top:1px solid rgba(255,255,255,.06)} /* Play */ -#play-view.active{display:grid;grid-template-columns:minmax(0,1fr) minmax(320px,420px);gap:var(--workspace-gap);align-items:start} +#play-view.active{display:grid;grid-template-columns:minmax(0,1fr) minmax(340px,390px);gap:clamp(1.1rem,2vw,1.8rem);align-items:start} #play-main,#play-sidebar{min-width:0} #play-main{display:flex;flex-direction:column;gap:.75rem} - /* Summary */ #summary-view .summary-shell{ max-width:none; margin:0; padding:clamp(1.35rem,2.5vw,2.35rem); background: - radial-gradient(circle at top right, rgba(201,168,76,.16), transparent 28%), + radial-gradient(circle at top right, rgba(230,60,20,.16), transparent 28%), linear-gradient(180deg, rgba(255,255,255,.025), rgba(255,255,255,0)), var(--surface); - border:1px solid rgba(201,168,76,.18); + border:1px solid rgba(230,60,20,.18); position:relative; overflow:hidden; } @@ -88,502 +86,135 @@ z-index:1; } .summary-hero-copy{display:flex;flex-direction:column;gap:.85rem} -.summary-kicker{ - font-size:.78rem; - font-weight:600; - letter-spacing:.24em; - text-transform:uppercase; - color:var(--muted); -} +.summary-kicker{font-size:.78rem;font-weight:600;letter-spacing:.24em;text-transform:uppercase;color:var(--muted)} #summary-title{ - font-family:var(--serif); + font-family:var(--display); font-size:clamp(3rem,7vw,5.8rem); + font-weight:700; line-height:.88; letter-spacing:-.03em; + text-transform:uppercase; } -#summary-headline{ - max-width:32rem; - font-size:1rem; - line-height:1.6; - color:var(--muted-strong); -} +#summary-headline{max-width:32rem;font-size:1rem;line-height:1.6;color:var(--muted-strong)} .summary-hero-meta{display:flex;align-items:center;gap:.6rem;flex-wrap:wrap} #summary-placement{ - display:inline-flex; - align-items:center; - justify-content:center; - padding:.38rem .82rem; - border:1px solid rgba(201,168,76,.45); - border-radius:999px; - background:rgba(201,168,76,.08); - color:var(--accent); - font-size:.8rem; - font-weight:600; - letter-spacing:.1em; - text-transform:uppercase; -} -.summary-scoreboard{ - display:grid; - grid-template-columns:minmax(0,1.05fr) minmax(0,.95fr); - gap:.9rem; - align-items:stretch; + display:inline-flex;align-items:center;justify-content:center;padding:.38rem .82rem; + border:1px solid rgba(230,60,20,.45);border-radius:999px;background:rgba(230,60,20,.08); + color:var(--accent);font-size:.8rem;font-weight:600;letter-spacing:.1em;text-transform:uppercase; } +.summary-scoreboard{display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,.95fr);gap:.9rem;align-items:stretch} .summary-balance-card{ - background:rgba(255,255,255,.03); - border:1px solid rgba(255,255,255,.08); - border-radius:var(--radius); - padding:1rem; - display:flex; - flex-direction:column; - justify-content:space-between; - min-height:100%; -} -.summary-balance-label{ - font-size:.78rem; - font-weight:600; - letter-spacing:.18em; - text-transform:uppercase; - color:var(--muted); + background:rgba(255,255,255,.03);border:1px solid rgba(255,255,255,.08);border-radius:var(--radius); + padding:1rem;display:flex;flex-direction:column;justify-content:space-between;min-height:100%; } +.summary-balance-label{font-size:.78rem;font-weight:600;letter-spacing:.18em;text-transform:uppercase;color:var(--muted)} #summary-balance-value{ - display:block; - margin-top:.55rem; - font-family:var(--serif); - font-size:clamp(2.5rem,5vw,4.25rem); - line-height:.9; -} -.summary-balance-meta{ - display:flex; - flex-wrap:wrap; - align-items:center; - gap:.55rem; - margin-top:.9rem; + display:block;margin-top:.55rem;font-family:var(--display);font-size:clamp(2.5rem,5vw,4.25rem); + font-weight:700;line-height:.9;letter-spacing:-.03em;text-transform:uppercase; } +.summary-balance-meta{display:flex;flex-wrap:wrap;align-items:center;gap:.55rem;margin-top:.9rem} .summary-net-pill{ - display:inline-flex; - align-items:center; - justify-content:center; - min-height:2rem; - padding:.35rem .72rem; - border-radius:999px; - border:1px solid rgba(255,255,255,.12); - background:rgba(255,255,255,.03); - font-size:.88rem; - font-weight:600; -} -.summary-net-pill.delta-pos{ - color:var(--green); - border-color:rgba(76,175,80,.35); - background:rgba(76,175,80,.08); -} -.summary-net-pill.delta-neg{ - color:var(--red); - border-color:rgba(229,57,53,.35); - background:rgba(229,57,53,.08); + display:inline-flex;align-items:center;justify-content:center;min-height:2rem;padding:.35rem .72rem;border-radius:999px; + border:1px solid rgba(255,255,255,.12);background:rgba(255,255,255,.03);font-size:.88rem;font-weight:600; } +.summary-net-pill.delta-pos{color:var(--green);border-color:rgba(76,175,80,.35);background:rgba(76,175,80,.08)} +.summary-net-pill.delta-neg{color:var(--red);border-color:rgba(229,57,53,.35);background:rgba(229,57,53,.08)} .summary-net-pill.delta-zero{color:var(--muted)} -.summary-balance-start{ - font-size:.82rem; - letter-spacing:.14em; - text-transform:uppercase; - color:var(--muted); -} -#summary-rings{ - display:grid; - grid-template-columns:repeat(2,minmax(120px,1fr)); - gap:.85rem; -} +.summary-balance-start{font-size:.82rem;letter-spacing:.14em;text-transform:uppercase;color:var(--muted)} +#summary-rings{display:grid;grid-template-columns:repeat(2,minmax(120px,1fr));gap:.85rem} .summary-ring-card{ - min-height:168px; - padding:.85rem .75rem; - display:flex; - flex-direction:column; - align-items:center; - justify-content:center; - gap:.65rem; - background:rgba(255,255,255,.03); - border:1px solid var(--border); - border-radius:var(--radius); + min-height:168px;padding:.85rem .75rem;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:.65rem; + background:rgba(255,255,255,.03);border:1px solid var(--border);border-radius:var(--radius); } .summary-ring{ - --ratio:0; - --ring-color:var(--accent); - width:102px; - aspect-ratio:1; - border-radius:50%; - display:grid; - place-items:center; - background: - radial-gradient(circle, var(--surface) 56%, transparent 57%), - conic-gradient(var(--ring-color) calc(var(--ratio) * 1turn), rgba(255,255,255,.08) 0); -} -.summary-ring-center{ - display:flex; - flex-direction:column; - align-items:center; - gap:.18rem; -} -.summary-ring strong{ - font-family:var(--serif); - font-size:1.45rem; - line-height:.9; -} -.summary-ring span{ - font-size:.72rem; - letter-spacing:.12em; - text-transform:uppercase; - color:var(--muted); -} -.summary-ring-label{ - font-size:.76rem; - font-weight:600; - letter-spacing:.16em; - text-transform:uppercase; - color:var(--text); -} -#summary-stats{ - display:grid; - grid-template-columns:repeat(4,minmax(160px,1fr)); - gap:.85rem; - margin-top:1rem; - position:relative; - z-index:1; -} -.summary-stat{ - background:rgba(255,255,255,.03); - border:1px solid var(--border); - border-radius:var(--radius); - padding:.9rem; -} -.summary-stat-label{ - font-size:.74rem; - color:var(--muted); - text-transform:uppercase; - letter-spacing:.12em; -} + --ratio:0;--ring-color:var(--accent);width:102px;aspect-ratio:1;border-radius:50%;display:grid;place-items:center; + background:radial-gradient(circle, var(--surface) 56%, transparent 57%),conic-gradient(var(--ring-color) calc(var(--ratio) * 1turn), rgba(255,255,255,.08) 0); +} +.summary-ring-center{display:flex;flex-direction:column;align-items:center;gap:.18rem} +.summary-ring strong{font-family:var(--display);font-size:1.65rem;font-weight:700;line-height:.85;letter-spacing:-.03em} +.summary-ring span{font-size:.72rem;letter-spacing:.12em;text-transform:uppercase;color:var(--muted)} +.summary-ring-label{font-size:.76rem;font-weight:600;letter-spacing:.16em;text-transform:uppercase;color:var(--text)} +#summary-stats{display:grid;grid-template-columns:repeat(4,minmax(160px,1fr));gap:.85rem;margin-top:1rem;position:relative;z-index:1} +.summary-stat{background:rgba(255,255,255,.03);border:1px solid var(--border);border-radius:var(--radius);padding:.9rem} +.summary-stat-label{font-size:.74rem;color:var(--muted);text-transform:uppercase;letter-spacing:.12em} .summary-stat-value{ - font-family:var(--serif); - font-size:clamp(1.6rem,2.6vw,2.2rem); - line-height:.95; - margin-top:.45rem; - word-break:break-word; -} -.summary-stat-copy{ - font-size:.82rem; - color:var(--muted); - line-height:1.4; - margin-top:.35rem; -} -.summary-section{ - margin-top:1.15rem; - position:relative; - z-index:1; -} -.summary-section-header{ - display:flex; - align-items:center; - justify-content:space-between; - gap:.75rem; - flex-wrap:wrap; - margin-bottom:.7rem; -} -.summary-section-header h3{ - font-size:.82rem; - font-weight:600; - text-transform:uppercase; - letter-spacing:.18em; - color:var(--accent); -} -.summary-section-note{ - font-size:.82rem; - color:var(--muted); -} -#summary-runway{ - background:rgba(0,0,0,.18); - border:1px solid var(--border); - border-radius:var(--radius); - padding:1rem; -} + font-family:var(--display);font-size:clamp(1.8rem,2.8vw,2.35rem);font-weight:700;line-height:.88;letter-spacing:-.03em; + margin-top:.45rem;word-break:break-word; +} +.summary-stat-copy{font-size:.82rem;color:var(--muted);line-height:1.4;margin-top:.35rem} +.summary-section{margin-top:1.15rem;position:relative;z-index:1} +.summary-section-header{display:flex;align-items:center;justify-content:space-between;gap:.75rem;flex-wrap:wrap;margin-bottom:.7rem} +.summary-section-header h3{font-size:.78rem;font-family:var(--mono);font-weight:500;text-transform:uppercase;letter-spacing:.16em;color:var(--accent)} +.summary-section-note{font-size:.8rem;font-family:var(--mono);letter-spacing:.06em;color:var(--muted)} +#summary-runway{background:rgba(0,0,0,.18);border:1px solid var(--border);border-radius:var(--radius);padding:1rem} .summary-runway-chart{height:220px} .summary-runway-svg{width:100%;height:100%;display:block} -.summary-runway-grid{ - stroke:rgba(255,255,255,.08); - stroke-width:1; -} +.summary-runway-grid{stroke:rgba(255,255,255,.08);stroke-width:1} +.summary-round-delta,.summary-standing-rank,.summary-standing-balance{font-family:var(--display);font-weight:700;letter-spacing:-.03em;text-transform:uppercase} +.summary-round-delta{font-size:1.15rem;line-height:.9} +.summary-podium-name{font-family:var(--sans);font-weight:600;letter-spacing:.01em} +.player-status-text,.summary-balance-label,.summary-stat-label,.summary-kicker,.summary-balance-start{font-family:var(--mono);font-weight:500} .summary-runway-fill{fill:url(#summary-runway-fill)} -.summary-runway-line{ - fill:none; - stroke:var(--accent2); - stroke-width:3; - stroke-linecap:round; - stroke-linejoin:round; -} -.summary-runway-point{ - fill:var(--accent2); - stroke:var(--bg); - stroke-width:2; -} -.summary-runway-axis{ - --axis-count:4; - display:grid; - grid-template-columns:repeat(var(--axis-count),minmax(0,1fr)); - gap:.4rem; - margin-top:.85rem; -} -.summary-runway-tick{ - font-size:.72rem; - letter-spacing:.12em; - text-transform:uppercase; - color:var(--muted); -} -.summary-runway-highlow{ - display:flex; - flex-wrap:wrap; - gap:.45rem; - margin-top:.8rem; -} -.summary-chip{ - display:inline-flex; - align-items:center; - padding:.28rem .58rem; - border-radius:999px; - background:rgba(255,255,255,.03); - border:1px solid var(--border); - font-size:.8rem; - color:var(--muted); - line-height:1.2; -} -#summary-round-grid{ - display:grid; - grid-template-columns:repeat(auto-fit,minmax(150px,1fr)); - gap:.85rem; -} +.summary-runway-line{fill:none;stroke:var(--accent2);stroke-width:3;stroke-linecap:round;stroke-linejoin:round} +.summary-runway-point{fill:var(--accent2);stroke:var(--bg);stroke-width:2} +.summary-runway-axis{--axis-count:4;display:grid;grid-template-columns:repeat(var(--axis-count),minmax(0,1fr));gap:.4rem;margin-top:.85rem} +.summary-runway-tick{font-size:.72rem;letter-spacing:.12em;text-transform:uppercase;color:var(--muted)} +.summary-runway-highlow{display:flex;flex-wrap:wrap;gap:.45rem;margin-top:.8rem} +.summary-chip{display:inline-flex;align-items:center;padding:.28rem .58rem;border-radius:999px;background:rgba(255,255,255,.03);border:1px solid var(--border);font-size:.8rem;color:var(--muted);line-height:1.2} +#summary-round-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:.85rem} .summary-round{ - --round-color:rgba(201,168,76,.78); - position:relative; - min-height:148px; - padding:.9rem; - overflow:hidden; - background:rgba(255,255,255,.03); - border:1px solid var(--border); - border-radius:var(--radius); -} -.summary-round::before{ - content:''; - position:absolute; - left:0; - top:0; - bottom:0; - width:4px; - background:var(--round-color); + --round-color:rgba(230,60,20,.78);position:relative;min-height:148px;padding:.9rem;overflow:hidden; + background:rgba(255,255,255,.03);border:1px solid var(--border);border-radius:var(--radius); } +.summary-round::before{content:'';position:absolute;left:0;top:0;bottom:0;width:4px;background:var(--round-color)} .summary-round.won{--round-color:rgba(76,175,80,.9)} .summary-round.lost{--round-color:rgba(229,57,53,.78)} -.summary-round.void{--round-color:rgba(255,152,0,.82)} +.summary-round.void{--round-color:rgba(255,77,37,.82)} .summary-round.forfeited{--round-color:rgba(229,57,53,.95)} -.summary-round.missing{ - --round-color:rgba(255,255,255,.22); - border-style:dashed; - background:rgba(255,255,255,.015); -} -.summary-round-top{ - display:flex; - align-items:flex-start; - justify-content:space-between; - gap:.5rem; -} -.summary-round-num{ - font-size:.74rem; - letter-spacing:.16em; - text-transform:uppercase; - color:var(--muted); -} +.summary-round.missing{--round-color:rgba(255,255,255,.22);border-style:dashed;background:rgba(255,255,255,.015)} +.summary-round-top{display:flex;align-items:flex-start;justify-content:space-between;gap:.5rem} +.summary-round-num{font-size:.74rem;letter-spacing:.16em;text-transform:uppercase;color:var(--muted)} .summary-round-state{ - display:inline-flex; - align-items:center; - justify-content:center; - padding:.22rem .48rem; - border:1px solid rgba(255,255,255,.12); - border-radius:999px; - background:rgba(255,255,255,.03); - font-size:.7rem; - font-weight:600; - letter-spacing:.1em; - text-transform:uppercase; - color:var(--text); -} -.summary-round-delta{ - margin-top:.7rem; - font-family:var(--serif); - font-size:2rem; - line-height:.88; + display:inline-flex;align-items:center;justify-content:center;padding:.22rem .48rem;border:1px solid rgba(255,255,255,.12); + border-radius:999px;background:rgba(255,255,255,.03);font-size:.7rem;font-weight:600;letter-spacing:.1em;text-transform:uppercase;color:var(--text); } +.summary-round-delta{margin-top:.7rem;font-size:1.35rem} .summary-round-pick{ - margin-top:.55rem; - min-height:2.35em; - font-size:.86rem; - line-height:1.35; - color:var(--text); - display:-webkit-box; - -webkit-line-clamp:2; - -webkit-box-orient:vertical; - overflow:hidden; + margin-top:.55rem;min-height:2.35em;font-size:.86rem;line-height:1.35;color:var(--text);display:-webkit-box; + -webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden; } .summary-round-pick.is-muted{color:var(--muted)} -.summary-round-meter{ - height:6px; - margin-top:.8rem; - overflow:hidden; - border-radius:999px; - background:rgba(255,255,255,.06); -} -.summary-round-meter span{ - display:block; - height:100%; - width:var(--strength,0%); - background:linear-gradient(90deg,var(--round-color),rgba(255,255,255,.88)); -} -.summary-round-foot{ - display:flex; - justify-content:space-between; - gap:.5rem; - margin-top:.55rem; - font-size:.72rem; - color:var(--muted); - letter-spacing:.08em; - text-transform:uppercase; -} -#summary-podium{ - display:grid; - grid-template-columns:repeat(3,minmax(0,1fr)); - gap:.9rem; - align-items:end; - margin-bottom:1rem; -} -.summary-podium-slot{ - display:flex; - align-items:flex-end; - min-height:220px; -} +.summary-round-meter{height:6px;margin-top:.8rem;overflow:hidden;border-radius:999px;background:rgba(255,255,255,.06)} +.summary-round-meter span{display:block;height:100%;width:var(--strength,0%);background:linear-gradient(90deg,var(--round-color),rgba(255,255,255,.88))} +.summary-round-foot{display:flex;justify-content:space-between;gap:.5rem;margin-top:.55rem;font-size:.72rem;color:var(--muted);letter-spacing:.08em;text-transform:uppercase} +#summary-podium{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:.9rem;align-items:end;margin-bottom:1rem} +.summary-podium-slot{display:flex;align-items:flex-end;min-height:220px} .summary-podium-step{ - width:100%; - height:var(--podium-height,150px); - padding:.85rem .8rem 1rem; - position:relative; - overflow:hidden; - display:flex; - flex-direction:column; - justify-content:flex-end; - gap:.35rem; - background:linear-gradient(180deg,rgba(255,255,255,.05),rgba(255,255,255,.02)); - border:1px solid var(--border); - border-radius:var(--radius) var(--radius) 0 0; -} -.summary-podium-step::before{ - content:''; - position:absolute; - inset:0; - background:linear-gradient(180deg,rgba(201,168,76,.18),transparent 55%); - opacity:.6; - pointer-events:none; -} -.summary-podium-step.me{border-color:rgba(201,168,76,.45)} -.summary-podium-rank{ - font-size:.78rem; - font-weight:600; - letter-spacing:.18em; - text-transform:uppercase; - color:var(--muted); -} -.summary-podium-name{ - font-family:var(--serif); - font-size:1.45rem; - line-height:.95; - overflow-wrap:anywhere; -} + width:100%;height:var(--podium-height,150px);padding:.85rem .8rem 1rem;position:relative;overflow:hidden; + display:flex;flex-direction:column;justify-content:flex-end;gap:.35rem; + background:linear-gradient(180deg,rgba(255,255,255,.05),rgba(255,255,255,.02));border:1px solid var(--border);border-radius:var(--radius) var(--radius) 0 0; +} +.summary-podium-step::before{content:'';position:absolute;inset:0;background:linear-gradient(180deg,rgba(230,60,20,.18),transparent 55%);opacity:.6;pointer-events:none} +.summary-podium-step.me{border-color:rgba(230,60,20,.45)} +.summary-podium-rank{font-size:.78rem;font-weight:600;letter-spacing:.18em;text-transform:uppercase;color:var(--muted)} +.summary-podium-name{font-size:1.45rem;line-height:.95;overflow-wrap:anywhere} .summary-podium-balance{font-size:1rem;color:var(--text)} .summary-podium-net{font-size:.82rem} -#summary-standings{ - display:flex; - flex-direction:column; - gap:.75rem; -} -.summary-standing{ - display:grid; - grid-template-columns:auto minmax(0,1fr) auto; - gap:.9rem; - align-items:center; - padding:.9rem 0; - border-top:1px solid rgba(255,255,255,.06); -} +#summary-standings{display:flex;flex-direction:column;gap:.75rem} +.summary-standing{display:grid;grid-template-columns:auto minmax(0,1fr) auto;gap:.9rem;align-items:center;padding:.9rem 0;border-top:1px solid rgba(255,255,255,.06)} .summary-standing:first-child{border-top:none} -.summary-standing.me{ - padding:.9rem .85rem; - background:rgba(201,168,76,.06); - border-radius:var(--radius); -} -.summary-standing-rank{ - font-family:var(--serif); - font-size:1.2rem; - color:var(--accent); -} -.summary-standing-main{ - display:flex; - flex-direction:column; - gap:.4rem; - min-width:0; -} -.summary-standing-top{ - display:flex; - align-items:baseline; - justify-content:space-between; - gap:.75rem; - flex-wrap:wrap; -} -.summary-standing-name{ - min-width:0; - font-size:1rem; - font-weight:600; - overflow-wrap:anywhere; -} -.summary-standing-status{ - font-size:.72rem; - letter-spacing:.12em; - text-transform:uppercase; - color:var(--muted); -} -.summary-standing-bar{ - height:10px; - overflow:hidden; - border-radius:999px; - background:rgba(255,255,255,.06); -} -.summary-standing-fill{ - display:block; - height:100%; - width:var(--standing-width,0%); - background:linear-gradient(90deg,var(--accent),var(--accent2)); -} -.summary-standing-values{ - display:flex; - flex-direction:column; - gap:.2rem; - text-align:right; -} -.summary-standing-balance{ - font-family:var(--serif); - font-size:1.25rem; - line-height:.95; -} -.summary-standing-net{ - font-size:.82rem; - font-weight:600; -} -.summary-actions{ - align-items:center; - position:relative; - z-index:1; -} +.summary-standing.me{padding:.9rem .85rem;background:rgba(230,60,20,.06);border-radius:var(--radius)} +.summary-standing-rank{font-size:1.2rem;color:var(--accent)} +.summary-standing-main{display:flex;flex-direction:column;gap:.4rem;min-width:0} +.summary-standing-top{display:flex;align-items:baseline;justify-content:space-between;gap:.75rem;flex-wrap:wrap} +.summary-standing-name{min-width:0;font-size:1rem;font-weight:600;overflow-wrap:anywhere} +.summary-standing-status{font-size:.72rem;letter-spacing:.12em;text-transform:uppercase;color:var(--muted)} +.summary-standing-bar{height:10px;overflow:hidden;border-radius:999px;background:rgba(255,255,255,.06)} +.summary-standing-fill{display:block;height:100%;width:var(--standing-width,0%);background:linear-gradient(90deg,var(--accent),var(--accent2))} +.summary-standing-values{display:flex;flex-direction:column;gap:.2rem;text-align:right} +.summary-standing-balance{font-size:1.25rem;line-height:.95} +.summary-standing-net{font-size:.82rem;font-weight:600} +.summary-actions{align-items:center;position:relative;z-index:1} /* Leaderboard */ #leaderboard-view.active{display:flex;flex-direction:column;gap:1rem} .leaderboard-head{display:flex;align-items:flex-end;justify-content:space-between;gap:1rem;flex-wrap:wrap} @@ -595,16 +226,28 @@ #lb-table th,#lb-table td{padding:.75rem 1rem;text-align:left;border-bottom:1px solid var(--border);white-space:nowrap} #lb-table th{color:var(--muted);font-weight:600;font-size:.78rem;text-transform:uppercase;letter-spacing:.08em} #lb-table tr:last-child td{border-bottom:none} -#lb-table tr.me td{background:rgba(201,168,76,.08);color:var(--accent)} -#my-rank-card{margin-bottom:0;background:rgba(201,168,76,.08);border-color:var(--accent)} +#lb-table tr.me td{background:rgba(230,60,20,.08);color:var(--accent)} +#my-rank-card{margin-bottom:0;background:rgba(230,60,20,.08);border-color:var(--accent)} #lb-table tr.provisional td.stat-metric{color:var(--muted);opacity:.55} #lb-table tr.provisional.me td.stat-metric{color:var(--accent);opacity:.55} .provisional-note{font-size:.82rem;color:var(--muted);margin-top:.3rem} - -/* ── Narrow viewport (phones) ─────────────────────────────────── */ +@media(max-width:1100px){ + header{grid-template-columns:1fr;align-items:start} + nav{justify-self:start;align-self:start;justify-content:flex-start} + #header-profile{justify-self:start;align-self:start;justify-content:flex-start} + #header-profile .identity{align-items:flex-start} + #summary-header{grid-template-columns:1fr} +} +@media(max-width:960px){ + .queue-shell{grid-template-columns:1fr} + .queue-inline-roster{display:flex} + .queue-side{display:none} + #summary-stats{grid-template-columns:repeat(2,minmax(0,1fr))} + #summary-podium{grid-template-columns:1fr} + .summary-podium-slot{min-height:unset} +} @media(max-width:650px){ #play-view.active{grid-template-columns:1fr} - #select-grid{grid-template-columns:1fr} .queue-main-top{align-items:flex-start} .queue-stat-block{align-items:flex-start} .queue-inline-roster-head{align-items:flex-start;flex-direction:column;gap:.3rem} @@ -615,30 +258,7 @@ .summary-scoreboard{grid-template-columns:1fr} } @media(max-width:560px){ - .question-meta-row{margin-bottom:.7rem} - #off-record-banner{max-width:none;justify-content:flex-start;text-align:left} - .card-picker-grid{grid-template-columns:1fr} #summary-rings,#summary-stats{grid-template-columns:1fr} .summary-standing{grid-template-columns:1fr} .summary-standing-values{text-align:left} } -@media(max-width:480px){ - header{padding:.7rem 0} - .header-kicker{display:none} - #header-profile{width:100%;justify-content:space-between} - nav{justify-content:flex-start} - #commit-area,#reveal-area,#rating-row,.queue-action-row{flex-direction:column;align-items:stretch} - #commit-btn,#reveal-btn{min-width:0} - #rating-row{text-align:left} - .queue-action-row button,.action-row button{width:100%} - .action-row{flex-direction:column} - .forfeit-dialog-actions{flex-direction:column} - .forfeit-dialog-actions button{width:100%} -} -.mt1{margin-top:.5rem}.mt2{margin-top:1rem} -#build-info{margin-top:auto;text-align:center;padding:2rem 1rem 1rem;font-size:.78rem;color:#555;letter-spacing:.04em;font-family:'SF Mono',SFMono-Regular,Consolas,'Liberation Mono',Menlo,monospace;display:flex;justify-content:center;align-items:center;gap:1rem} - -/* ── Atmosphere ────────────────────────────────────────────────── */ -#app::before{content:'';position:fixed;inset:0;background:radial-gradient(ellipse 60% 50% at 50% 30%,rgba(201,168,76,.03) 0%,transparent 70%);pointer-events:none;z-index:-1} -.view.active{animation:viewIn .4s ease forwards} -@keyframes viewIn{from{opacity:0;transform:translateY(12px)}to{opacity:1;transform:none}} diff --git a/public/styles/tokens.css b/public/styles/tokens.css index 6b6f68a..baac7ae 100644 --- a/public/styles/tokens.css +++ b/public/styles/tokens.css @@ -1,28 +1,35 @@ /* ── Reset & tokens ─────────────────────────────────────────────── */ *,*::before,*::after{box-sizing:border-box;margin:0;padding:0} :root{ - --bg:#0a0a0a;--surface:#111;--surface2:#1a1a1a;--border:#222; - --text:#e8e4de;--muted:#9a9488;--muted-strong:#b7b0a4;--accent:#c9a84c;--accent2:#dfc06a; - --green:#4caf50;--red:#e53935;--orange:#ff9800;--yellow:#fdd835; + --bg:#0a0a0a;--surface:#101010;--surface2:#171717;--border:rgba(255,255,255,.09); + --text:#ece6dd;--muted:#a0998c;--muted-strong:#cdc5b7;--accent:#e63c14;--accent2:#ff4d25; + --green:#4caf50;--red:#e53935;--orange:#ff4d25;--yellow:#fdd835;--display:'Barlow Condensed','Impact',sans-serif; --radius:3px;--serif:'Cormorant Garamond',Georgia,serif;--sans:'Outfit',system-ui,sans-serif; + --mono:'SF Mono',SFMono-Regular,Consolas,'Liberation Mono',Menlo,monospace; --app-gutter:clamp(1rem,3vw,3rem);--workspace-gap:clamp(1.5rem,3vw,3.75rem); } -html{scrollbar-color:rgba(201,168,76,.25) transparent;scrollbar-width:thin} -html,body{height:100%;background:var(--bg);color:var(--text);font-family:var(--sans);font-size:16px;line-height:1.7;font-weight:300;-webkit-font-smoothing:antialiased} -body{display:flex;flex-direction:column;min-height:100vh;min-height:100svh} -button,.button-link{cursor:pointer;border:none;border-radius:var(--radius);padding:.5rem 1.1rem;font-size:.84rem;font-family:var(--sans);font-weight:600;text-transform:uppercase;letter-spacing:.1em;transition:all .2s} +html{scrollbar-color:rgba(230,60,20,.25) transparent;scrollbar-width:thin} +html,body{height:100%;background:var(--bg);color:var(--text);font-family:var(--sans);font-size:16px;line-height:1.7;font-weight:400;-webkit-font-smoothing:antialiased} +body{ + display:flex;flex-direction:column;min-height:100vh;min-height:100svh; + background-color:var(--bg); + background-image:radial-gradient(circle, rgba(230,60,20,.16) 1px, transparent 1.25px); + background-size:40px 40px; +} +button,.button-link{cursor:pointer;border:1px solid rgba(255,255,255,.1);border-radius:var(--radius);padding:.55rem .98rem;font-size:.76rem;font-family:var(--mono);font-weight:500;text-transform:uppercase;letter-spacing:.16em;transition:all .2s} .button-link{display:inline-flex;align-items:center;justify-content:center;text-decoration:none} button:active,.button-link:active{transform:scale(.97)} button:disabled{opacity:.4;cursor:default;transform:none} -.btn-primary{background:var(--accent);color:var(--bg)}.btn-primary:hover:not(:disabled){background:var(--accent2);transform:translateY(-1px)} +.btn-primary{background:var(--accent);border-color:rgba(230,60,20,.45);color:var(--bg)} +.btn-primary:hover:not(:disabled){background:var(--accent2);transform:translateY(-1px)} .btn-danger{background:var(--red);color:#fff} -.btn-ghost{background:transparent;border:1px solid var(--border);color:var(--text);font-size:.84rem;letter-spacing:.08em;font-weight:500} +.btn-ghost{background:transparent;border:1px solid var(--border);color:var(--text);font-size:.76rem;letter-spacing:.16em;font-weight:500} .btn-ghost:hover:not(:disabled){border-color:var(--accent);color:var(--accent)} .btn-ghost[aria-disabled='true'],.btn-ghost[aria-disabled='true']:hover{opacity:.55;border-color:var(--border);color:var(--muted);cursor:help;transform:none} .sr-only{position:absolute!important;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0} input{background:var(--surface2);border:1px solid var(--border);border-radius:var(--radius);color:var(--text);font-family:var(--sans);font-size:.95rem;padding:.5rem .75rem;width:100%;outline:none;transition:border-color .15s} input:focus{border-color:var(--accent)} label{font-size:.92rem;color:var(--muted);display:block;margin-bottom:.3rem} -h2{font-family:var(--serif);font-weight:600} +h2{font-family:var(--display);font-weight:700;letter-spacing:-.02em;text-transform:uppercase} .card{background:var(--surface);border:1px solid var(--border);border-radius:var(--radius);padding:1.35rem;transition:border-color .3s} .hidden{display:none!important}