# client_web — Alternative Design Proposals: Neon Arcade Future A second aesthetic direction: bold, playful, unapologetically modern. Where the first proposal channels an 18th-century gaming salon, this one asks: *what if trictrac ran on a holographic table in a Tokyo arcade, 2089?* This document proposes a complete visual redesign with no obligation to mirror physical game objects. The priority is delight, readability, and memorability. --- ## Aesthetic Direction: "Holographic Arcade" **Core concept**: The board floats in dark space as a self-illuminated slab. Fields pulse with neon light. Checkers are luminous marbles that leave light trails as they move. Scoring events trigger particle explosions. Every interaction has a micro-animation. **The one unforgettable thing**: When a hole is won, the entire board floods with a colour wave — a full-screen shimmer that fades in 800ms — like a pinball machine tilting into multiball. **Color palette**: Built on darkness, with high-saturation accents — cyan, magenta, gold. Not gradients on white (the generic AI aesthetic); instead, near-black backgrounds with glowing, luminous elements. **Typography**: [Space Grotesk](https://fonts.google.com/specimen/Space+Grotesk) is overused. Instead: - Display: [Syne](https://fonts.google.com/specimen/Syne) — geometric, confident, slightly alien - Numerics: [DM Mono](https://fonts.google.com/specimen/DM+Mono) — for scores, dice values, field numbers — crisp monospace with personality - UI labels: [Outfit](https://fonts.google.com/specimen/Outfit) — friendly, modern, clear at small sizes ```css :root { /* Base */ --void: #09090f; /* near-black with blue tint */ --surface: #12121f; /* board slab */ --surface-raised: #1a1a2e; /* panels, cards */ --surface-glass: rgba(255,255,255,0.05); /* glassmorphism */ /* Neon accents */ --cyan: #00e5ff; --cyan-dim: #0099bb; --magenta: #e040fb; --gold: #ffd740; --gold-dim: #c8a820; --green-neon: #69ff47; --orange-neon: #ff6d3a; /* Player colors */ --player-white: #e8e0ff; /* soft violet-white */ --player-black: #1a0040; /* deep indigo-black */ --player-white-glow: #b39ddb; --player-black-glow: #7c4dff; /* Typography */ --font-display: 'Syne', sans-serif; --font-mono: 'DM Mono', monospace; --font-ui: 'Outfit', sans-serif; /* Glow radii */ --glow-sm: 0 0 8px; --glow-md: 0 0 16px; --glow-lg: 0 0 32px; } ``` --- ## 1. Board: A Floating Holographic Slab **Concept**: The board is a dark rectangular surface that appears to float — slight perspective tilt (CSS `perspective` + `rotateX(3deg)`), a thin neon border (1px cyan on top, 1px dimmer on bottom for depth), and a subtle inner glow that makes the board feel luminous from within. ```css .board { background: var(--surface); border: 1px solid var(--cyan-dim); box-shadow: 0 0 0 1px rgba(0,229,255,0.1), 0 0 40px rgba(0,229,255,0.08), 0 24px 60px rgba(0,0,0,0.8); transform: perspective(1200px) rotateX(2deg); transform-origin: center bottom; border-radius: 4px; } ``` The board background gets a very subtle **noise texture overlay** (SVG `` or a PNG grain layer at 3% opacity) — just enough to prevent it from looking like a flat rectangle, giving it material presence. The center bar and side bars become **glowing dividers**: 4px wide, gradient from `var(--cyan)` at top to `var(--magenta)` at bottom, with a matching glow. --- ## 2. Fields: Neon Triangles with Zone Color Identity Triangular fields (CSS `clip-path: polygon`) are essential here — they're geometric and modern, not just historically authentic. Each quarter gets its **own neon color identity**, using a very dark base with a glowing triangle border: | Quarter | Fields | Primary accent | Secondary (alternating) | |---------|--------|---------------|------------------------| | Small jan | 1–6 | `#00e5ff` (cyan) | `#0077aa` (dim cyan) | | Big jan | 7–12 | `#7c4dff` (violet) | `#4a2a99` (dim violet) | | Return jan | 13–18 | `#e040fb` (magenta) | `#991a99` (dim magenta) | | Last jan | 19–24 | `#ffd740` (gold) | `#aa8800` (dim gold) | The field itself is dark (`#14141f`). The color lives in a **glowing triangle border** — achieved with a layered `clip-path` + `::before` pseudo-element 2px larger that shows through as the border, with a CSS `filter: blur(3px)` outer glow: ```css .field { background: #14141f; clip-path: polygon(50% 0%, 0% 100%, 100% 100%); position: relative; } .field::before { content: ''; position: absolute; inset: -2px; background: var(--field-accent-color); clip-path: polygon(50% 0%, 0% 100%, 100% 100%); filter: blur(4px); opacity: 0.4; z-index: -1; } ``` **On hover (clickable fields)**: the glow intensifies (`opacity: 0.9`, `filter: blur(6px)`) and the field interior lightens slightly. A ripple animation radiates outward from the click point. **Selected field**: the entire field interior fills with a semi-transparent neon color — not just the border — and a 2px dashed animated border spins around it (`animation: spin-border 1s linear infinite`). --- ## 3. Checkers: Luminous Marbles Forget CSS circles with radial gradients. Each checker is a **glowing orb** with: - A dark, slightly translucent core - A radial highlight in the upper-left (simulating a point light source) - A colored halo that radiates outward onto the field triangle - A subtle inner reflection ring ```css .checker.white { background: radial-gradient(circle at 35% 30%, #ffffff, #c8c0e0 40%, #8878c0 70%, #3a2a60 ); box-shadow: inset 0 2px 6px rgba(255,255,255,0.8), inset 0 -2px 4px rgba(0,0,0,0.4), 0 0 12px rgba(179,157,219,0.6), /* violet-white glow */ 0 0 24px rgba(124,77,255,0.3); /* outer violet halo */ } .checker.black { background: radial-gradient(circle at 35% 30%, #7c4dff, #4a2d99 40%, #1a0a40 70%, #09040f ); box-shadow: inset 0 2px 6px rgba(124,77,255,0.5), inset 0 -2px 4px rgba(0,0,0,0.8), 0 0 12px rgba(124,77,255,0.7), 0 0 24px rgba(124,77,255,0.3); } ``` **Stack depth**: A stack of N checkers renders with each checker offset by 6px vertically and slightly scaled (0.97× per level deeper), creating genuine 3D stack depth without any 3D CSS transform. The count label floats above as a monospace number in `var(--gold)`. **Selection animation**: On click to select, the top checker of the stack does a quick `scale(1.2) translateY(-8px)` bounce (150ms spring easing), then settles at `scale(1.1) translateY(-4px)` while selected. **Movement animation**: When a move is confirmed (board state diff), selected checkers do a **light-trail arc** — a bezier path from origin field center to destination, with a fading cyan streak left behind (`box-shadow` animated along the path via `@property` interpolation or JS Web Animation API). Duration: 300ms. --- ## 4. Dice: Holographic Crystals Replace the SVG ivory dice with **translucent crystal cubes**: - Each die face is a dark glass square with a thin neon border - Pips are glowing dots — cyan for normal, gold for doubles - The die face has a subtle `backdrop-filter: blur(4px)` on a glass background ```css .die-face rect { fill: rgba(255, 255, 255, 0.04); stroke: var(--cyan); stroke-width: 1.5; rx: 6; filter: drop-shadow(0 0 6px var(--cyan)); } .die-face circle { fill: var(--cyan); filter: drop-shadow(0 0 4px var(--cyan)); } ``` **Double dice**: Both pips and borders switch to `var(--gold)`, with a stronger glow (`drop-shadow(0 0 8px var(--gold))`). **Roll animation**: 600ms sequence — 1. Both dice **shatter outward** (`scale(0) rotate(720deg)`, opacity 0 → 1) appearing from nothing 2. During 400ms they rapidly cycle through face values (random pips swap every 60ms via CSS `animation`) 3. Final 200ms they decelerate and **snap** to the rolled values with a brief flash pulse **Used die**: Fades the border to `rgba(255,255,255,0.1)` and dims pips to `rgba(255,255,255,0.2)` — the die goes "offline." A thin strikethrough line appears diagonally. --- ## 5. The Hole Tracker: Orbital Rings Instead of progress bars, score and hole progress are visualised as **concentric orbital rings** beside each player's name panel — inspired by loading spinners, but static and data-driven. - **Outer ring** (thick, 6px): hole progress. 12 segments, each one lights up as a hole is won. Segments are `var(--gold)` when won, near-invisible dark when empty. - **Inner ring** (thin, 3px): point progress within the current hole. Continuously filled arc from 0° to (points/12 × 360°). Color: `var(--cyan)` for the active player, `var(--magenta)` for the opponent. The arc fills animate with `stroke-dashoffset` transition (0.4s ease-out) on every point gain. **Bredouille state**: The outer ring segments pulse — a slow `opacity: 0.6 → 1 → 0.6` sinusoidal glow — as long as bredouille is active. A small flag icon (⚑) in `var(--gold)` appears beside the ring. --- ## 6. Scoring Events: Light Shows ### Hole won — Full-board colour wave A `position:fixed` `::after` overlay expands from the scoring player's side of the board: - Radial gradient expanding from one edge: `rgba(255,215,64,0)` → `rgba(255,215,64,0.15)` → `rgba(255,215,64,0)` - Duration: 800ms, ease-in-out - Simultaneously: the scoring player's orbital rings segments animate sequentially (each segment snaps on with a 50ms delay) - A large centered text `"+1 TROU"` in `var(--font-display)` at 3rem scales from 60% to 110% with `opacity: 0 → 1 → 0`, duration 1.2s ### Bredouille — The cascade On top of the hole wave, add: - A **confetti burst** of small colored squares (pure CSS: 20 `` elements with randomised `animation-delay` and `translate`/`rotate` keyframes) in cyan, magenta, gold - The `"+1 TROU"` text instead reads `"BREDOUILLE ×2"` in `var(--magenta)` - The board border flashes: `border-color` cycles cyan → magenta → gold → cyan over 0.6s ### Jan scored — Notification card Each jan scored gets a **toast card** that slides in from the right edge: - Dark glass background (`rgba(26,26,46,0.95)`) with a left border in the jan's quarter color - Jan name in `var(--font-ui)` bold, points in `var(--font-mono)` large - Progress: `"+4 pts"` in cyan, `"+6 pts (double)"` in gold - Cards stack vertically if multiple jans fire; each staggered by 80ms - Auto-dismiss with a rightward slide-out after 3s ### Hit scored — Ripple on the target checker When a hit is scored on a specific field, that field's checker emits a **sonar ripple**: - 3 concentric rings expand from the checker's center, each `opacity: 1 → 0, scale: 1 → 2.5` - Color: cyan for true hits, magenta for false hits (giving to opponent) - Duration: 600ms per ring, staggered by 200ms --- ## 7. Player Panels: Glassmorphism Cards Replace the cream `background: #f5edd8` panels with **glass cards** floating above the void: ```css .player-score-panel { background: rgba(255, 255, 255, 0.04); border: 1px solid rgba(255, 255, 255, 0.1); border-top: 1px solid rgba(255, 255, 255, 0.2); /* top catches light */ backdrop-filter: blur(12px) saturate(1.5); border-radius: 12px; box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.08); } ``` **Active player panel**: the border glow of the active player's card brightens: `border-color: var(--cyan)` with `box-shadow: 0 0 16px rgba(0,229,255,0.2)`. A tiny animated pulse on the left edge (`width: 3px, animation: pulse 1.5s ease-in-out infinite`) indicates it is their turn. **Player name**: Displayed in `var(--font-display)` at 1.1rem. A small colored dot (cyan for player 1, magenta for player 2) precedes the name — acts as the "you" indicator without needing a text suffix. --- ## 8. Status Bar: Dynamic Ambient Messaging Replace the single plain-text status line with a **contextual bar** that changes character per game stage: | Stage | Style | Color | |-------|-------|-------| | Waiting for opponent | Slow pulsing dots animation `... ` | Dim white | | Your turn (roll) | "YOUR MOVE" in `var(--font-display)` with a blinking cursor | Cyan | | Opponent's turn | Subtle shimmer on text | Dim magenta | | Move selection | "SELECT CHECKER ①" with animated underline on "SELECT" | Cyan | | Hold or Go | "SCORE!" with a spinning star ✦ | Gold | | Paused (continue) | The bar has a pulsing amber background strip | Amber | | Game over | Text cycles through all player colors | Full rainbow | The bar itself is 3px tall and spans the full board width, showing a **neon progress shimmer** during the opponent's turn (a traveling gleam, like CSS `animation: shimmer` on a gradient). --- ## 9. Jan Zone Awareness: Neon Underlay Rather than labels, the four quarters glow with their zone color in the background of the board — very subtle, just 4% opacity fills under the triangles: ```css .board-quarter-small-jan { background: rgba(0, 229, 255, 0.04); } .board-quarter-big-jan { background: rgba(124, 77, 255, 0.04); } .board-quarter-return-jan { background: rgba(224, 64, 251, 0.04); } .board-quarter-last-jan { background: rgba(255, 215, 64, 0.04); } ``` When hovering a scoring-notification row that references a specific jan (e.g. "Big jan conserved"), the corresponding quarter's background pulses from 4% → 15% opacity for 600ms. This replaces the arrow overlay with a spatial, zone-level highlight — more legible and visually coherent. --- ## 10. Rest Corner: The Crown Field Field 12 (White) and 13 (Black) get a distinct appearance: - The triangle is outlined in `var(--gold)` instead of its quarter's color - A small **crown SVG** (⚜ or ♛) floats centered in the triangle at 30% opacity when empty, brighter when held - When the player holds the corner (2 checkers there), the triangle interior fills with a very subtle gold shimmer animation (`background-position: 0% → 100%` on a diagonal gradient, 2s loop) - When the corner is available to be taken *par puissance*, the crown pulses at 1Hz --- ## 11. Login Screen: Warp Speed Entrance **Hero**: A dark void with an animated **particle field** — small white/cyan dots drifting slowly, like stars. Pure CSS with 50 `` elements (or a single `` for performance), each with randomised `animation-delay` and drift keyframe. **Title**: "TRICTRAC" in `var(--font-display)` at 5rem, with a **chromatic aberration effect** — three slightly offset copies in cyan, magenta, and white, blended with `mix-blend-mode: screen`. The word appears with a `clip-path: inset(100% 0 0 0) → inset(0% 0 0 0)` reveal animation (the text "rises" into view). **Tagline**: `"XVIIIe siècle · En ligne · ∞"` in `var(--font-mono)` at 0.85rem, appearing letter-by-letter with a 20ms interval. **Mode cards**: Instead of three buttons, three **holographic tiles** in a row: - Each is a glass card with an icon, label, and a colored accent strip on the bottom - On hover: the card lifts (`translateY(-4px)`) and the bottom strip color floods the card (low opacity fill) - CREATE: cyan accent; JOIN: violet accent; vs BOT: orange accent **Room code input**: Dark glass input with a cyan border glow on focus, monospace font for the code, no placeholder text (just a blinking cursor showing it's ready). The input border animates a traveling gleam on focus. --- ## 12. Game-Over Screen: Score Reveal Ceremony Instead of a modal over a frozen game, the game-over sequence is a **full-page takeover**: 1. **Board fades out** (800ms fade): the board dims to 20% opacity 2. **Score card rises** from the bottom: a tall glass card with both players' hole counts displayed large in `var(--font-display)` — `"8"` vs `"3"` — in their respective colors 3. **Winner highlight**: the winning number scales up to 200% with a gold burst radiation behind it 4. **Bredouille annotation**: if applicable, `"× 2"` appears beside the number with a magenta glow, then the number updates to the effective doubled count 5. **Continue options**: two buttons slide up last — "QUIT" and "REJOUER" — with the rejouer button pulsing in cyan --- ## 13. Global Micro-Interactions These apply throughout and give the interface a consistently tactile feel: - **Button press**: `scale(0.96)` on `:active`, 80ms, then spring back. No `opacity` change — scale is more physical. - **Button focus**: neon outline ring animated in from 0 to full radius (not the browser default outline). - **Panel hover**: glass cards shift `box-shadow` slightly for a lifted feel. - **Page load**: all elements stagger in with a `translateY(10px) → 0 + opacity 0 → 1`, each component with a `animation-delay` offset (board: 0ms, panels: 100ms, side panel: 200ms). - **Custom cursor** (optional): replace the default cursor with a small circle that trails slightly behind the real cursor position — creates a luxurious "lag" feeling. Pure JS: interpolate cursor position toward mouse position at 80% each frame. --- ## Implementation Notes for Leptos/WASM ### What's straightforward in pure CSS - All color variables, glass panels, glow effects, orbital rings (SVG `stroke-dashoffset`) - Dice roll animation (CSS keyframes) - Toast slide-ins (CSS `@keyframes` + `animation`) - Confetti (CSS `@keyframes` on positioned `
` elements) - Particle field on login (CSS-only with many `` elements) ### What needs a small JS/WASM component - **Board perspective tilt** with mouse-tracking (subtle parallax) — `mouse_position` signal driving CSS custom property - **Checker light-trail movement** — needs previous/next board diff, then Web Animation API or `requestAnimationFrame` - **Chromatic aberration on title** — CSS filter or SVG filter, but the animation needs JS timing ### What needs Rust/Leptos state - **Board diff for animation**: store previous `[i8; 24]` alongside current in `GameScreen` as a `Memo`, compute moved checkers - **Event timing for sequences**: hole-won wave → score reveal → dismiss must be orchestrated; a `RwSignal>` in `GameScreen` drives each phase ### Progressive approach The proposals above can be adopted incrementally. Suggested order: 1. CSS variables + dark theme + Syne/DM Mono fonts → immediate impact, zero logic change 2. Glass panels, neon borders, glow effects → pure CSS 3. Orbital ring score tracker → SVG component 4. Triangular fields + zone colors → `board.rs` structural change 5. Dice animation → CSS keyframes in `die.rs` 6. Toast notifications → new `toast.rs` component 7. Hole-won wave → CSS overlay + Leptos signal 8. Checker animation → board diff + Web Animation API