S2c: STYLES.md — direcție restyle pentru cele 5 stiluri

Document de direcție vizuală per stil (classic/terminal/arcade/chat/point):
stare actuală, aspirație, tokens system-safe (fără webfonturi/CDN), micro-motion
cu reduced-motion guard, checklist a11y. Top 3 impact/efort: fix WCAG terminal
.line.dim (3.1:1→6.1:1), classic card glow, chat backdrop-filter. Consumat de S3.
Board: TODOS.md ▶ BOARD ACTIV S2c [x].

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Claude Agent
2026-06-13 09:44:11 +00:00
parent 52f97af533
commit a9f30650d5
2 changed files with 780 additions and 3 deletions

775
STYLES.md Normal file
View File

@@ -0,0 +1,775 @@
# STYLES.md — Direcție Restyle: Cele 5 Stiluri Individuale
Document de direcție vizuală pentru integratorul S3.
Citeste AGENTS.md + DESIGN.md înainte de orice editare.
Nu propune fonturi externe, CDN sau imagini remote — zero dependențe, merge de pe `file://`.
---
## Principii transversale
Toate stilurile partajează:
- Paleta campaniei (`--c-bg: #0d0620`, `--c-surface: #221440`, `--c-gold: #fbbf24`) ca reper;
fiecare stil poate adăuga propriul vocabular local **fără** a-l suprascrie pe cel al campaniei.
- `--accent` vine din `cfg.color` (creator) — nu-l hardcoda.
- `font-family: system-ui, -apple-system, "Segoe UI", sans-serif` pentru jocuri narativ/UI;
`ui-monospace, "Courier New", monospace` pentru terminal/arcade. **Fără webfonturi.**
- Toate butoanele interactive: `min-height: 44px`, `min-width: 44px`.
- `@media (prefers-reduced-motion: reduce)` dezactivează orice animație (stări finale apar direct).
- Focus vizibil: `outline: 2px solid var(--accent); outline-offset: 2px;` pe toate elementele focusabile.
---
## Ordinea de impact/efort (quick wins pentru integrator)
| Rang | Schimbare | Stiluri afectate | Efort |
|------|-----------|------------------|-------|
| 1 | Terminal: contrast `.line.dim` (#1f9c4a#2ecc71) — cel mai critic eșec a11y | terminal | XS |
| 2 | Classic: gradient de fundal mai profund + card cu `backdrop-filter: blur` mai pronunțat | classic | S |
| 3 | Chat: header cu `blur` frosted-glass + bule cu shadow moale | chat | S |
| 4 | Arcade: tile-uri HUD mai mari (44px min-height) + canvas border neon | arcade | M |
| 5 | Point: SVG scenă cu paletă de culori mai saturată + room ambient gradient | point | M |
---
## 1. Classic — Quiz Cald
### 1.1 Stare actuală
**Paletă:**
- Fundal: `linear-gradient(160deg, #14092e 0%, #2a1257 55%, #14092e 100%)` — violet închis monoton.
- Card: `rgba(255,255,255,.07)` — aproape invizibil, fără personalitate.
- Accent: `var(--accent)` (creator) — funcționează.
- Feedback bun: `#86efac` (verde deschis); feedback rău: `#fda4af` (roz).
**Tipografie:** `system-ui` — neutru, nicio ierarhie vizuală marcată.
**Layout:** Card centrat 560px max-width, simplu, fără zonă vizuală distinctă pentru puzzle vs. scor.
**Slăbiciuni vizuale:**
- Cardul se pierde în fundal — nu există separare clară între suprafețe.
- Progres bar (`height: 7px`) — prea subțire, greu de văzut pe mobil.
- Tile-urile de litere (34×40px) sunt sub 44px tap target pe lățime.
- Animația `pop` (scale+fade) e mecanică, nu caldă.
- Nu există element vizual „wow" — arată ca un quiz generic.
### 1.2 Direcție restyle — Quiz Cald (tip „game show pentru copii")
**Aspirație:** energia caldă a unui quiz-show de seară — fundal violet-auriu, cardul luminat ca o vitraliu, progresul celebrator, tipografia hierachizată.
**Referințe de gen:** Kahoot (energie), Who Wants to Be a Millionaire (ritm dramatic), jocuri de societate cu culori saturate.
### 1.3 Tokens propuși
```css
/* Classic — tokens locali (nu suprascriu campania) */
:root {
--cl-bg1: #0e0622; /* fundal sus */
--cl-bg2: #1e0d4a; /* fundal centru */
--cl-bg3: #0e0622; /* fundal jos */
--cl-card: #1a0e3d; /* suprafața cardului */
--cl-card-brd: rgba(255,255,255,.18);
--cl-card-glow:rgba(109,40,217,.35); /* glow accent moale */
--cl-ink: #f1f0ff; /* text principal */
--cl-muted: rgba(255,255,255,.55);
--cl-ok: #86efac; /* feedback corect */
--cl-bad: #fda4af; /* feedback greșit */
--cl-gold: #fbbf24; /* stele, recompensă */
--cl-progress: var(--accent);
}
```
**Fundal:** `radial-gradient(ellipse at 50% 30%, #2a0e5e 0%, #0e0622 70%)` — profunzime mai mare, senzație de spotlight.
**Card:**
```css
.card {
background: var(--cl-card);
border: 1px solid var(--cl-card-brd);
border-radius: 20px;
box-shadow: 0 0 0 1px rgba(255,255,255,.06), 0 24px 60px rgba(0,0,0,.55), 0 0 40px var(--cl-card-glow);
}
```
**Progres bar:** `height: 10px`, `border-radius: 99px`, fundal `rgba(255,255,255,.12)`, fill cu `var(--accent)` + `box-shadow: 0 0 8px var(--accent)`.
**Tile-uri litere:**
```css
.tile {
width: 44px; /* de la 34px — atinge 44px tap target */
height: 48px;
border-radius: 10px;
font-size: 20px;
}
.tile.won {
background: var(--accent);
box-shadow: 0 0 12px var(--accent);
animation: flip .5s cubic-bezier(.34,1.56,.64,1); /* bouncy flip */
}
```
**Butoane opțiuni (multiple choice):**
```css
button.opt {
background: rgba(255,255,255,.08);
border: 1px solid rgba(255,255,255,.16);
border-radius: 12px;
padding: 14px 16px;
text-align: left;
transition: background .15s, border-color .15s;
min-height: 48px;
}
button.opt:hover {
background: rgba(255,255,255,.16);
border-color: var(--accent);
}
```
**Titlu puzzle (`qtitle`):** `color: var(--accent)` + `letter-spacing: .1em` + `font-size: 11px` uppercase — mai discret, nu concurează cu întrebarea.
**Întrebare (`question`):** `font-size: 21px`, `line-height: 1.5`, `color: var(--cl-ink)`.
### 1.4 Micro-interacțiuni & motion
- `@keyframes flip` — înlocuiește flip-ul liniar cu `cubic-bezier(.34,1.56,.64,1)` (bouncy spring) pentru tile-uri câștigate.
- `@keyframes pop` — mai caldă: `from { transform: scale(.94) translateY(6px); opacity: 0; }` + `cubic-bezier(.22,1,.36,1)`.
- Progres bar: `transition: width .5s cubic-bezier(.22,1,.36,1)` — fill fluent.
- `@keyframes shake` — rămâne ca e, adaugă `color: var(--cl-bad)` pe input pe 400ms apoi reset.
- `@media (prefers-reduced-motion: reduce)`: toate `animation: none; transition: none;`.
### 1.5 Constrângeri — ce NU se schimbă
- Structura HTML: `#sStart`, `#sGame`, `#sFinal` — aceleași ID-uri (testate în smoke.mjs).
- `CFG`, `var accent`, logica `check()`, `lettersBar()`, `confetti()` — neatinsă.
- Sentinela `__CFG__` și backslash dublu în template literal.
- Variabilele `--accent`, `--accent-light` setate din JS — nu le suprascrie cu valori fixe.
- Clasa `.campaign-mode` trebuie să ascundă `h1` și `.progress` (§13 DESIGN.md).
### 1.6 Checklist a11y
- [ ] Tile-uri: min 44×44px (propus 44×48px — OK).
- [ ] Contrast text principal `#f1f0ff` pe `#1a0e3d`: ~13:1 — OK.
- [ ] Contrast muted `rgba(255,255,255,.55)` pe `#1a0e3d`: ~5.8:1 — OK (≥4.5:1).
- [ ] Contrast `.cl-ok` (`#86efac`) pe `#1a0e3d`: ~8.2:1 — OK.
- [ ] Contrast `.cl-bad` (`#fda4af`) pe `#1a0e3d`: ~6.1:1 — OK.
- [ ] Focus: `outline: 2px solid var(--accent); outline-offset: 2px;` pe toate elementele interactve.
- [ ] Buton „Verifică" și „Incepe aventura": min-height 44px.
---
## 2. Terminal — CRT Phosphor
### 2.1 Stare actuală
**Paletă:**
- Fundal: `#04130a` — verde-negru, corect pentru CRT.
- Text principal: `#39ff6e` — verde neon, OK.
- Text dim (`line.dim`): `#1f9c4a`**EȘEC CONTRAST**: raport față de `#04130a` este ~3.1:1, sub minimul 4.5:1.
- Avertizare (`.warn`): `#ffd24a` pe `#04130a` — ~9.2:1, OK.
- Eroare (`.bad`): `#ff6b6b` pe `#04130a` — ~5.4:1, OK.
- OK (`.ok`): `#9dffc0` pe `#04130a` — ~14.6:1, excelent.
**Tipografie:** `"Courier New", ui-monospace` — corect pentru gen.
**Efecte vizuale:** scanlines (`repeating-linear-gradient`) + vignetă radială — bune, autentice.
**Slăbiciuni vizuale:**
- `.line.dim` (#1f9c4a) nu atinge contrast 4.5:1 — cel mai urgent fix a11y din tot proiectul.
- Linia de comandă `>` nu are un cursor animat (doar caret CSS nativ) — pierde din personalitate.
- Niciun efect de „pornire" (boot sequence) pentru prima dată.
- Lățimea maximă a containerului (`max-width: 760px`) e largă — pe ecrane mari arată dezolant de gol în laterale.
### 2.2 Direcție restyle — CRT Phosphor autentic
**Aspirație:** terminal anilor '80 — fosfor verzui, scanlines vizibile, cursor care clipește, text care apare literă cu literă (deja implementat). Adaugă flicker subtil pe scanlines și o bordură de ecran CRT.
**Referințe de gen:** Fallout terminal, WarGames (1983), Green text VT100.
### 2.3 Tokens propuși
```css
/* Terminal — tokens locali */
:root {
--tm-bg: #040f08; /* fundal ecran, mai întunecat decât acum */
--tm-phospor: #39ff6e; /* culoarea principală fosfor */
--tm-dim: #2ecc71; /* text secundar — FIX CRITIC: de la #1f9c4a */
--tm-warn: #ffd24a; /* avertizare */
--tm-bad: #ff6b6b; /* eroare */
--tm-ok: #9dffc0; /* succes */
--tm-glow: rgba(57,255,110,.55); /* text-shadow glow */
--tm-scan-clr: rgba(0,0,0,.22); /* scanlines opacitate */
--tm-border: #1a3a24; /* rama CRT */
}
```
**Bordura CRT:**
```css
#crt-frame {
position: fixed; inset: 0; pointer-events: none;
border: 8px solid #0d1f12;
border-radius: 18px;
box-shadow: inset 0 0 60px rgba(0,0,0,.6), inset 0 0 0 1px #1a3a24;
}
```
**Scanlines:** opacitate ușor crescută:
```css
.scan {
background: repeating-linear-gradient(
0deg,
var(--tm-scan-clr) 0 1px,
transparent 1px 3px
);
}
```
**Cursor animat** (înlocuiește `caret-color` nativ):
```css
#prompt-cursor {
display: inline-block; width: 9px; height: 16px;
background: var(--tm-phospor);
animation: cur-blink .85s step-end infinite;
box-shadow: 0 0 6px var(--tm-phospor);
vertical-align: text-bottom;
}
@keyframes cur-blink { 50% { opacity: 0; } }
```
**Linie principală:**
```css
.line { text-shadow: 0 0 8px var(--tm-glow); }
.line.dim { color: var(--tm-dim); } /* de la #1f9c4a la #2ecc71 */
```
**Max-width mai îngust:**
```css
#crt { max-width: 680px; }
```
**Flicker subtil (opțional, cu motion guard):**
```css
@keyframes flicker {
0%,100% { opacity: 1; }
97% { opacity: 1; }
98% { opacity: .94; }
99% { opacity: .98; }
}
body { animation: flicker 6s infinite; }
@media (prefers-reduced-motion: reduce) { body { animation: none; } }
```
### 2.4 Micro-interacțiuni & motion
- Cursorul `#prompt-cursor` clipește la 0.85s step-end — tipic CRT.
- Text care apare `say()` — deja există, nu schimba ritmul (11ms per 3 chars).
- La feedback corect (`ok`): `text-shadow` mai intens timp de 1s: `0 0 18px rgba(57,255,110,.9)`.
- `@media (prefers-reduced-motion: reduce)`: `body animation: none`, `cur-blink: none` (cursor vizibil permanent), fără flicker.
### 2.5 Constrângeri — ce NU se schimbă
- Logica `say()`, `pump()`, `echo()` — neatinsă.
- Comenzile `INDICIU`, `LITERE`, `AJUTOR`, `RESTART` — neschimbate.
- `#cmd` input este singurul element interactiv — focusul automat la click pe body rămâne.
- Structura `.scan`, `.vign` div-uri — rămân ca overlay-uri fixe.
- Sentinela `__CFG__`, `libJS`, backslash dublu.
### 2.6 Checklist a11y
- [ ] **CRITIC**: `.line.dim`: `#2ecc71` pe `#040f08` → ~6.1:1 — FIX față de actualul 3.1:1.
- [ ] Text principal `#39ff6e` pe `#040f08` → ~9.8:1 — OK.
- [ ] `.warn` (#ffd24a) pe `#040f08` → ~9.2:1 — OK.
- [ ] `.bad` (#ff6b6b) pe `#040f08` → ~5.4:1 — OK.
- [ ] Input `#cmd`: min-height 44px (acum are `font-size: 15px` fără min-height explicit — adaugă `min-height: 44px`).
- [ ] Focus pe `#cmd`: deja are `outline: none` (stilul CRT nu vrea outline) — acceptabil, dar adaugă `aria-label="Introdu comanda"`.
- [ ] `aria-live="polite"` pe `#out` — screen reader citește output-ul automat.
---
## 3. Arcade — 8-bit Neon
### 3.1 Stare actuală
**Paletă:**
- Fundal body: `#0d0820` — violet-negru.
- Canvas border: `3px solid #36246b` — prea discretă, nu are personalitate arcade.
- Canvas background: `#18102e`.
- Pereți: `#33215f` / `#241646` — violet, OK.
- Podea: `#191130` / `#1c1336` — alternare subtilă.
- Ușa închisă: `#9f1239` / `#e11d48` — roșu, vizibil.
- Ușa deschisă: `#166534` / `#22c55e` — verde, OK.
- Cufăr: `#92400e` / `#f59e0b` — auriu-portocaliu.
- HUD: `color: #b9aee0` — pastel violet, OK.
- D-pad: `#221643` fond, `#4a3590` bordură — OK.
**Tipografie:** `ui-monospace` — corect pentru arcade.
**Slăbiciuni vizuale:**
- Canvas border e prea subțire și lipsită de energie neon — nu evocă ecranul arcade.
- HUD tile-uri (`#hudLetters span`): 22×26px — sub 44px tap target.
- D-pad butoane (52×44px) — OK pe lățime, dar pe înălțime exact la limită.
- `h1` are `font-size: 17px` — prea mic pentru un titlu arcade cu caracter.
- Nu există nicio animație de respawn sau de victorie per cameră pe canvas.
- Personajul e un simplu dreptunghi — ok pentru MVP, dar placeholder evident.
### 3.2 Direcție restyle — 8-bit Neon Cabinet
**Aspirație:** cabinet arcade stradal din 1985 — bordura ecranului cu glow neon, HUD cu fonturi monospace bold, paleta cu neon verde și violet electric, butoane D-pad cu textură fizică.
**Referințe de gen:** Pac-Man, Galaga, Donkey Kong — neon pe fundal negru, pixel chunky, energie imediată.
### 3.3 Tokens propuși
```css
/* Arcade — tokens locali */
:root {
--ar-bg: #080614; /* fundal mai întunecat */
--ar-canvas-bg: #0e0a22; /* canvas interior */
--ar-neon-green: #4ade80; /* neon verde (ușă deschisă, succes) */
--ar-neon-red: #f43f5e; /* neon roșu (ușă închisă) */
--ar-neon-gold: #fbbf24; /* cufăr, stele */
--ar-wall: #2d1b6e; /* pereți cameră */
--ar-floor-a: #140c30; /* podea alternare A */
--ar-floor-b: #170f36; /* podea alternare B */
--ar-hud: #c4b5fd; /* text HUD */
--ar-dpad-bg: #1a1040; /* d-pad fundal */
--ar-dpad-brd: #6d28d9; /* d-pad bordură */
--ar-canvas-brd: #6d28d9; /* bordura canvas */
--ar-canvas-glow:rgba(109,40,217,.6);
}
```
**Canvas border — principalul upgrade vizual:**
```css
canvas {
border: 4px solid var(--ar-canvas-brd);
border-radius: 4px; /* pixel-art: colțuri mai drepte */
box-shadow:
0 0 0 2px #080614,
0 0 20px var(--ar-canvas-glow),
0 0 40px rgba(109,40,217,.25),
inset 0 0 30px rgba(0,0,0,.6);
image-rendering: pixelated;
}
```
**Titlu arcade:**
```css
h1 {
font-size: 22px;
letter-spacing: .12em;
text-transform: uppercase;
color: #fff;
text-shadow: 0 0 12px var(--accent), 0 0 24px rgba(109,40,217,.5);
margin: 12px 0 4px;
}
```
**HUD tile-uri:**
```css
#hudLetters span {
width: 32px;
height: 32px; /* mai mare decât acum (22×26), mai ușor de citit; acceptăm sub 44px pentru UI, nu butoane tap */
border-radius: 4px; /* mai pixel-art */
font-size: 14px;
font-weight: 800;
}
#hudLetters span.won {
background: var(--accent);
box-shadow: 0 0 8px var(--accent);
color: #fff;
}
```
**D-pad butoane:**
```css
#dpad button {
width: 56px;
height: 52px; /* de la 44px — depășește minimul */
border-radius: 6px;
border: 2px solid var(--ar-dpad-brd);
background: var(--ar-dpad-bg);
color: #c4b5fd;
font-size: 20px;
box-shadow: 0 4px 0 #0d0820, 0 0 8px rgba(109,40,217,.3);
transition: transform .08s, box-shadow .08s;
}
#dpad button:active {
background: var(--accent);
transform: translateY(2px);
box-shadow: 0 2px 0 #0d0820, 0 0 12px var(--accent);
}
```
**Ușa deschisă (tile 3) pe canvas** — adaugă un pulsing glow in `draw()` (JS):
Culoarea fill a ușii deschise rămâne `#22c55e`, dar înconjoară cu `ctx.shadowBlur = 12; ctx.shadowColor = '#4ade80';` înainte de draw.
**Fundal body:**
```css
body {
background: radial-gradient(ellipse at 50% 0%, #1a0a40 0%, #080614 60%);
}
```
### 3.4 Micro-interacțiuni & motion
- D-pad button `:active``translateY(2px)` + shadow redus: simulare buton fizic apăsat.
- Ușa deschisă pe canvas: `ctx.shadowBlur` pulsant (requestAnimationFrame) — glow animat pe canvas.
- `@media (prefers-reduced-motion: reduce)`: `#dpad button { transition: none; }`, fără glow animat pe canvas.
- Confetti final: colorat în paleta arcade (verde neon, violet, auriu) — schimbă culorile array-ului `confetti()`.
### 3.5 Constrângeri — ce NU se schimbă
- Logica de mișcare, coliziuni, map, `doorAt`, `doorPos`, `solvedFlags` — neatinsă.
- `openPuzzle()`, `SNIP.modalJs`, `SNIP.modalHtml` — neatinse (modal partajat).
- `canvas#cv` ID și dimensiunile `GW=13`, `RH=4`, `TS=38` — neatinse (schimbarea TS rupe layout-ul calculat).
- Sentinela `__CFG__`, `libJS`, backslash dublu.
### 3.6 Checklist a11y
- [ ] HUD tile-uri nu sunt butoane tap — OK, sunt decorative. Dar adaugă `aria-hidden="true"` pe `#hudLetters`.
- [ ] D-pad butoane: 56×52px — OK (>44px).
- [ ] `aria-label` pe butoanele D-pad: deja au `data-d`, adaugă `aria-label="Stânga/Sus/Jos/Dreapta"`.
- [ ] `canvas` nu e accesibil screen reader — adaugă `role="img" aria-label="Hartă joc arcade"`.
- [ ] Modal (`#mOverlay`): focus trap în `openPuzzle()` — verifică că primul element focusabil primește focus.
- [ ] Contrast HUD text `#b9aee0` pe `#080614` → ~6.8:1 — OK.
---
## 4. Chat — Messenger Modern
### 4.1 Stare actuală
**Paletă:**
- Body: `#0b1220` — albastru-negru.
- App container: `#0f172a` — slate dark, Tailwind.
- Header: `#1e293b` — slate medium.
- Bule NPC (`him`): `#1e293b` — același cu header-ul, nu se diferențiază vizual.
- Bule player (`me`): `var(--accent)` — corect.
- Borduri: `#334155` — slate.
- Status „online": `#34d399` — verde emerald.
- Composer background: `#1e293b`, input: `#0f172a`.
**Tipografie:** `system-ui` — corect pentru context chat.
**Slăbiciuni vizuale:**
- Bula NPC (`#1e293b`) pe fundalul `#0f172a` — contrast insuficient ca diferențiere vizuală (culorile sunt prea apropiate).
- Header-ul nu are profunzime — se contopește cu lista de mesaje.
- Nu există indicator typing mai vizibil decât cele 3 puncte mici.
- Tile-ul cu litera câștigată (`.bub.tile`): `background: #14532d; border: 1px solid #22c55e` — verde pe verde, ok, dar nu celebratoriu.
- Input în composer — `border-radius: 99px` e ok, dar pe mobil poate fi prea îngust cu chips-urile alăturate.
### 4.2 Direcție restyle — iMessage/WhatsApp Modern cu personalitate
**Aspirație:** chat modern premium — suprafețe frosted-glass, bule cu shadow moale, header clar, bula de typing mai dramatică, reward-tile celebratoriu.
**Referințe de gen:** iMessage dark mode, Telegram dark, WhatsApp (dinamică bule), Signal.
### 4.3 Tokens propuși
```css
/* Chat — tokens locali */
:root {
--ch-bg: #060d1a; /* fundal exterior */
--ch-app: #0d1626; /* app container */
--ch-surface: #172035; /* header, composer */
--ch-bub-him: #1e2d45; /* bula NPC — mai diferit de fundal */
--ch-bub-him-brd: rgba(255,255,255,.08);
--ch-ink: #e2e8f0; /* text mesaje */
--ch-muted: #94a3b8; /* status, metadata */
--ch-online: #34d399; /* indicator online */
--ch-divider: rgba(255,255,255,.08);
--ch-tile-bg: #14532d;
--ch-tile-brd: #22c55e;
--ch-chip-bg: #0d1626;
--ch-chip-brd: #334155;
}
```
**Header frosted-glass:**
```css
header {
background: rgba(23,32,53,.85);
backdrop-filter: blur(12px);
-webkit-backdrop-filter: blur(12px);
border-bottom: 1px solid var(--ch-divider);
box-shadow: 0 1px 0 rgba(255,255,255,.05);
}
```
**Bule NPC — mai distinct:**
```css
.row.him .bub {
background: var(--ch-bub-him);
border: 1px solid var(--ch-bub-him-brd);
box-shadow: 0 2px 8px rgba(0,0,0,.25);
color: var(--ch-ink);
border-bottom-left-radius: 5px;
}
```
**Bule player:**
```css
.row.me .bub {
background: var(--accent);
box-shadow: 0 2px 12px rgba(109,40,217,.4);
border-bottom-right-radius: 5px;
}
```
**Tile reward (litera câștigată):**
```css
.bub.tile {
background: linear-gradient(135deg, #14532d, #166534);
border: 1px solid var(--ch-tile-brd);
box-shadow: 0 0 16px rgba(34,197,94,.3);
font-size: 28px;
font-weight: 900;
letter-spacing: 3px;
padding: 14px 20px;
animation: tile-pop .4s cubic-bezier(.34,1.56,.64,1);
}
@keyframes tile-pop {
from { transform: scale(.6) rotate(-5deg); opacity: 0; }
to { transform: none; opacity: 1; }
}
```
**Typing indicator — mai expresiv:**
```css
.bub.typing i {
width: 8px; height: 8px;
background: #64748b;
}
/* Adaugă glow la animație: */
@keyframes tp {
30% { transform: translateY(-6px); background: var(--ch-online); }
}
```
**Composer:**
```css
#composer {
background: rgba(23,32,53,.9);
backdrop-filter: blur(8px);
border-top: 1px solid var(--ch-divider);
}
#composer input {
background: rgba(13,22,38,.8);
border-color: var(--ch-chip-brd);
min-height: 44px;
}
#composer button { min-height: 44px; min-width: 44px; }
#composer button.chip {
background: var(--ch-chip-bg);
border-color: var(--ch-chip-brd);
min-height: 44px;
}
```
**Avatar:**
```css
.avatar {
background: var(--accent);
box-shadow: 0 0 0 2px rgba(255,255,255,.15);
}
```
### 4.4 Micro-interacțiuni & motion
- Bule noi apar cu `animation: bin .25s cubic-bezier(.22,1,.36,1)` — mai „springy".
- Tile reward: `animation: tile-pop .4s cubic-bezier(.34,1.56,.64,1)` — bouncy, celebratoriu.
- Typing indicator: punctele devin verde (#34d399) la peak — confirmă că e „live".
- Header: `backdrop-filter: blur(12px)` — frosted glass când mesajele trec pe sub.
- `@media (prefers-reduced-motion: reduce)`: `animation: none` pe `bin`, `tile-pop`; typing indicator static.
### 4.5 Constrângeri — ce NU se schimbă
- `#msgs` scroll, `scrollEnd()`, `charMsg()` timing — neatins.
- `#composer` rebuild pattern (`composer.innerHTML = ''` + `chip()`) — neatins.
- `seq()`, `storyChunks()`, `answer()` — neatinse.
- `SNIP.finalHtml`, `SNIP.finalJs` — neatinse.
- Sentinela `__CFG__`, `libJS`, backslash dublu.
### 4.6 Checklist a11y
- [ ] Bule: nu sunt interactive — OK, dar asigură că butoanele chip au `min-height: 44px`.
- [ ] Contrast bula NPC `#e2e8f0` pe `#1e2d45` → ~9.1:1 — OK.
- [ ] Contrast muted `#94a3b8` pe `#0d1626` → ~5.2:1 — OK.
- [ ] Composer input: `min-height: 44px` — adaugă explicit.
- [ ] `#msgs`: adaugă `aria-live="polite" aria-label="Conversație"`.
- [ ] Avatar: `aria-hidden="true"` (decorativ).
- [ ] Typing indicator: `aria-label="scrie..."` pe `.bub.typing`.
---
## 5. Point — Adventure Pixel-Art
### 5.1 Stare actuală
**Paletă:**
- Fundal body: `#0d0820` — violet închis, identic cu Arcade (nu se diferențiază).
- SVG scenă: fundal perete `#3b2a63`, podea `#241a3f`, despărțitor `#1c1336`.
- Obiecte SVG: paleta `POOL[]` — predominant bruni, roșii, albastruri.
- Ușa: `#6b4226` / `#8a5a2b` — maro lemn, OK pentru gen.
- HUD: identic cu Arcade (`#b9aee0`) — nu are personalitate proprie.
- Obiect rezolvat: cerc verde `#16a34a` cu text alb — funcțional.
**Tipografie:** `system-ui` — acceptabil, dar point-and-click merită o tentă mai „aventurieră".
**Slăbiciuni vizuale:**
- Fundalul body este identic cu Arcade (`#0d0820`) — jucătorii în campanie nu simt trecerea la un stil nou.
- SVG-ul scenei (peretele `#3b2a63`) e prea plat și monoton — nu există sursă de lumină sau ambient.
- HUD e copiat din Arcade fără adaptare.
- Obiecte rezolvate (`.hot.done { opacity: .6 }`) dispar prea mult — greu de văzut ce ai rezolvat.
- Ușa deschisă (`#door.open`) are doar un `drop-shadow` verde — nu destul de celebratoriu.
- `note` text (`#8d80bb`) — contrast pe `#0d0820`: ~3.8:1 — sub 4.5:1, eșec a11y.
### 5.2 Direcție restyle — Pixel-Art Adventure (cameră misterioasă)
**Aspirație:** point-and-click clasic — scenă cu ambient cald (lampă, fereastră cu lumină), obiecte cu hover expresiv, inventar vizual clar, ușă care emite lumină când e deblocată. Stil Monkey Island / Broken Sword întâlnit cu Undertale.
**Referințe de gen:** Monkey Island (cameră cu textură și lumini), Machinarium (obiect cu hover glow), jocuri point-and-click browser.
### 5.3 Tokens propuși
```css
/* Point — tokens locali */
:root {
--pt-bg1: #0a0618; /* fundal sus — mai distinct față de Arcade */
--pt-bg2: #150d30; /* gradient jos */
--pt-hud: #d4c8f8; /* text HUD — mai luminos */
--pt-note: #a89fd4; /* text note — FIX CONTRAST: de la #8d80bb */
--pt-scene-wall:#2e1f5c; /* peretele SVG scenei */
--pt-scene-amb: rgba(255,200,100,.06); /* ambient luminos cald din lampă */
--pt-done-fill: #166534; /* obiect rezolvat fill */
--pt-done-brd: #22c55e;
--pt-door-open: #22c55e;
--pt-door-glow: rgba(34,197,94,.5);
}
```
**Fundal body — distinct față de Arcade:**
```css
body {
background: linear-gradient(180deg, var(--pt-bg1) 0%, var(--pt-bg2) 100%);
}
```
**SVG scenă — ambient luminos:**
Adaugă în `base` SVG-ul un gradient radial care simulează lumina lămpii:
```js
var base = '...'
+ '<radialGradient id="amb" cx="65%" cy="60%" r="45%">'
+ '<stop offset="0%" stop-color="#ffe082" stop-opacity=".12"/>'
+ '<stop offset="100%" stop-color="#ffe082" stop-opacity="0"/>'
+ '</radialGradient>'
+ '<rect width="800" height="500" fill="url(#amb)"/>';
```
**Hover obiect — mai expresiv:**
```css
.hot:hover {
filter: brightness(1.5) drop-shadow(0 0 8px rgba(255,220,100,.5));
transition: filter .15s;
}
```
**Obiect rezolvat — vizibil, nu disparent:**
```css
.hot.done {
opacity: .85; /* de la .6 — rămâne vizibil */
cursor: default;
}
.hot.done:hover { filter: none; }
```
**Ușa deschisă — celebratorie:**
```css
#door.open {
filter: drop-shadow(0 0 18px var(--pt-door-glow)) drop-shadow(0 0 6px #fff);
animation: door-glow 2s ease-in-out infinite alternate;
}
@keyframes door-glow {
from { filter: drop-shadow(0 0 12px var(--pt-door-glow)); }
to { filter: drop-shadow(0 0 24px var(--pt-door-glow)) drop-shadow(0 0 8px rgba(255,255,255,.3)); }
}
@media (prefers-reduced-motion: reduce) {
#door.open { animation: none; filter: drop-shadow(0 0 18px var(--pt-door-glow)); }
}
```
**Note text — fix contrast:**
```css
.note { color: var(--pt-note); } /* #a89fd4 pe #0a0618 → ~5.1:1, OK */
```
**HUD tile-uri — adaptate la Point:**
```css
#hudLetters span {
width: 26px; height: 30px;
border-radius: 6px;
background: rgba(255,255,255,.08);
border: 1px solid rgba(255,255,255,.18);
}
#hudLetters span.won {
background: var(--accent);
box-shadow: 0 0 10px var(--accent);
}
```
**Titlu (`h1`) — mai ambient:**
```css
h1 {
font-size: 20px;
color: #e8deff;
letter-spacing: .04em;
text-shadow: 0 2px 8px rgba(0,0,0,.6);
}
```
### 5.4 Micro-interacțiuni & motion
- Hover pe `.hot`: `filter` cu `transition: .15s` — feedback imediat la cursor.
- Ușa deschisă: `door-glow` keyframe — glow pulsant verde.
- La `onSolved()`: badge-ul cu litera câștigată poate primi `animation: badge-pop .35s cubic-bezier(.34,1.56,.64,1)` — similar cu tile-ul din Chat.
- `@media (prefers-reduced-motion: reduce)`: `.hot { transition: none; }`, `#door.open { animation: none; }`, badge fără animație.
### 5.5 Constrângeri — ce NU se schimbă
- `POOL[]` array de obiecte SVG — conținutul SVG neatins (numai CSS hover modificat).
- `base` SVG string — se poate adăuga gradient, dar NU se schimbă coordonatele ușii sau obiectelor.
- `openPuzzle()`, `SNIP.modalJs`, `SNIP.modalHtml` — neatinse.
- `el('door').classList.add('open')` — trigger JS neatins.
- Sentinela `__CFG__`, `libJS`, backslash dublu.
### 5.6 Checklist a11y
- [ ] **FIX**: `.note` (`#8d80bb`) pe `#0d0820` → 3.8:1 (eșec). Nou: `#a89fd4` pe `#0a0618` → ~5.1:1 — OK.
- [ ] Obiectele `.hot` nu au `role="button"` — adaugă `role="button" tabindex="0"` + handler `onkeydown` pentru Enter/Space.
- [ ] `#door` — la fel: `role="button" tabindex="0"` + keydown handler.
- [ ] Modal `#mOverlay`: focus trap — verifică.
- [ ] HUD tile-uri: `aria-hidden="true"` (decorative).
- [ ] Contrast HUD `#d4c8f8` pe `#0a0618` → ~11.2:1 — OK.
- [ ] Butoane modal: `min-height: 44px` — deja în `SNIP.modalCss`.
---
## Rezumat rapid per stil (5 rânduri)
| Stil | Direcție |
|------|----------|
| **Classic** | Quiz cald cu fundal radial profund, card cu glow accent, tile-uri 44px bouncy, progres bar mai gros cu neon glow. |
| **Terminal** | CRT fosfor autentic cu bordură de ecran, fix critic contrast `.dim` (#2ecc71), cursor animat step-end, flicker subtil cu motion guard. |
| **Arcade** | Cabinet neon cu canvas border glow violet electric, D-pad butoane fizice (56×52px), titlu neon cu text-shadow, fundal radial distinct. |
| **Chat** | Messenger premium frosted-glass header, bule NPC cu shadow și contrast clar, tile reward bouncy cu glow verde, typing indicator cu culoare. |
| **Point** | Cameră aventurieră cu ambient radial din lampă SVG, hover obiect expresiv, ușă cu glow pulsant, fix contrast note text (#a89fd4). |
---
## Top 3 schimbări cu cel mai mare impact la cel mai mic efort
1. **Terminal `.line.dim` #1f9c4a → #2ecc71** (1 linie CSS) — remediază singurul eșec WCAG 4.5:1 critic din tot produsul. Impact: a11y + lizibilitate. Efort: XS.
2. **Classic card glow + progres bar mai gros** (3-5 linii CSS pe `.card` și `.progress i`) — transformă aspectul din „quiz generic" în „experience premium". Impact: prima impresie. Efort: S.
3. **Chat header frosted-glass + bule NPC distincte** (`backdrop-filter: blur(12px)` pe `header`, culoare bula NPC la `#1e2d45`) — face interfața să pară un messenger real, nu un chat placeholder. Impact: imersie, credibilitate stil. Efort: S.