source: Klonkt/src/assets/css/ward.css@ 084b046

Last change on this file since 084b046 was 084b046, checked in by Robin <roboburr@…>, 3 months ago

De Ward PWA: de avatarhemel achter de kaarten

Plak 3. Robins correctie: niet de hemel IN PLAATS VAN de kaarten, maar
allebei, met de hemel er altijd achter. Zelfde beweging als in Shaer: de
kaarten vallen weg en wat eronder lag was er al.

MODEL EN RENDERER APART, en die naad is het punt. orbitPlacement en
nearestFace zijn pure wiskunde en bestaan nu drie keer (Swift, Kotlin,
hier). Drie keer kans op drift, en drift zie je niet aan een screenshot:
je ziet het als gezichten ergens anders hangen dan in de app. Daarom in
een eigen module, met dezelfde eigenschappen bewaakt als AvatarSkyTest.kt.

CANVAS, GEEN ENGINE, en dat is een afweging en geen luiheid. De rem is
niet het aantal sprites maar het aantal texturen: alle avatars gaan een
keer in een atlas, daarna is elk gezicht een drawImage uit datzelfde
plaatje. Dat haalt duizenden. Wil het ooit meer, dan vervangt een
WebGL-variant alleen SkyRenderer en merkt de rest er niets van. De echte
schaaloplossing is trouwens niet sneller tekenen maar clusteren; dat
staat als bead voor later.

New file:
src/assets/js/ward-sky.js

  • orbitPlacement + nearestFace, letterlijke port
  • SkyRenderer: atlas, ademhaling, pan, zoom, tik

test/ward-sky.test.js

  • vers dichterbij dan oud, deterministisch, geen overlap, mikken kiest de dichtstbijzijnde en schaalt mee met de zoom

Changed files:
src/routes/ward.js

  • /api/conversations: per tegenpartij het jongste bericht
  • /sky.js als eigen asset

src/views/pages/ward.ejs

  • canvas achter alles, wisselknop, app.js als module

src/assets/js/ward.js

  • de wissel: kaarten of hemel, hemel draait altijd

src/assets/css/ward.css

  • hemel op z-index 0, kaarten erboven

src/services/i18n.js

  • drie sleutels in nl, en, de

remarks: 895 tests groen. Een tik op een gezicht wijst naar /ward/thread,
en die route bestaat nog niet; dat is de volgende plak.

-robo
Co-Authored-By: Claude Opus 4.8 <noreply@…>

  • Property mode set to 100644
File size: 5.4 KB
RevLine 
[303bfc4]1/* De Ward PWA: rustig, groot genoeg voor een kind, donker als de rest. */
2:root {
3 --bg: #141a24;
4 --card: #1c2431;
5 --ink: #eef2f8;
6 --dim: #9aa7bb;
7 --accent: #5a32e6;
8 --alarm: #ef9f27;
9 --ok: #46c26a;
10}
11* { box-sizing: border-box; }
12body {
13 margin: 0; padding: 16px calc(16px + env(safe-area-inset-right)) 32px calc(16px + env(safe-area-inset-left));
14 background: var(--bg); color: var(--ink);
15 font: 16px/1.5 system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
16}
17h1 { font-size: 1.4rem; margin: 8px 0 20px; }
18h2 { font-size: 1rem; margin: 24px 0 10px; color: var(--dim); font-weight: 600; }
19
20/* De hulpknop is het belangrijkste element op deze pagina en ziet er ook zo
21 uit: vol breed, grote raakzone, geen concurrentie eromheen. */
22.help button {
23 width: 100%; padding: 18px; border: 0; border-radius: 14px;
24 background: var(--accent); color: #fff; font-size: 1.1rem; font-weight: 600;
25}
26.help button:disabled { background: #3a3f4d; color: var(--dim); }
27.help .hint { margin: 8px 2px 0; color: var(--dim); font-size: .85rem; }
28
29.list { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; }
30.card { background: var(--card); border-radius: 12px; padding: 12px 14px; }
31.row { display: flex; align-items: center; gap: 10px; }
32.name { font-weight: 600; margin: 0; }
33.hint { color: var(--dim); font-size: .85rem; margin: 6px 0 0; }
34.empty { color: var(--dim); }
35
36.chip { margin-left: auto; font-size: .75rem; padding: 3px 9px; border-radius: 999px; background: #2a3342; color: var(--dim); }
37.chip.ok { background: rgba(70,194,106,.16); color: var(--ok); }
38.chip.away { background: rgba(239,159,39,.16); color: var(--alarm); }
39
40/* Misvormd krijgt de alarmkleur, onbereikbaar bewust NIET: niet-weten is geen
41 misconfiguratie. Maar het is ook geen goedkeuring, dus het staat er wel. */
42.note { margin: 8px 0 0; font-size: .85rem; padding: 6px 9px; border-radius: 8px; }
43.note.alarm { background: rgba(239,159,39,.16); color: var(--alarm); }
44.note.unknown { background: rgba(154,167,187,.14); color: var(--dim); }
[a5a6249]45
46/* ── De feed ──────────────────────────────────────────────────────────── */
47.cards { display: grid; gap: 12px; }
48.post { background: var(--card); border-radius: 12px; padding: 12px 14px; border: 2px solid transparent; }
49.post .avatar { width: 28px; height: 28px; border-radius: 50%; object-fit: cover; }
50.post .when { margin-left: auto; color: var(--dim); font-size: .8rem; }
51.post .cw { color: var(--alarm); font-size: .85rem; margin: 6px 0 0; }
52.post .body { margin-top: 8px; overflow-wrap: anywhere; }
53.post .body img, .post .body video { max-width: 100%; height: auto; border-radius: 8px; }
54/* Waar de boei zou landen. Zichtbaar oplichten, want mikken met een vinger
55 zonder terugkoppeling is gokken. */
56.post.hover { border-color: var(--accent); }
57
58/* ── De reddingsboei ──────────────────────────────────────────────────── */
59#buoy {
60 position: fixed; right: 18px; bottom: calc(18px + env(safe-area-inset-bottom));
61 width: 76px; height: 76px; border: 0; border-radius: 50%;
62 background: transparent; font-size: 52px; line-height: 1;
63 /* Zonder dit vecht slepen met scrollen en verlies je hem halverwege. */
64 touch-action: none; cursor: grab; z-index: 50;
65}
66#buoy.dragging { cursor: grabbing; transform: scale(1.1); }
67
68dialog#help-dialog {
69 border: 0; border-radius: 16px; padding: 18px; max-width: 420px; width: calc(100% - 32px);
70 background: var(--card); color: var(--ink);
71}
72dialog#help-dialog::backdrop { background: rgba(0,0,0,.5); }
73dialog#help-dialog h2 { margin: 0 0 10px; font-size: 1.05rem; color: var(--ink); }
74dialog#help-dialog label { display: block; color: var(--dim); font-size: .85rem; margin-bottom: 4px; }
75dialog#help-dialog textarea {
76 width: 100%; border-radius: 10px; border: 1px solid #2a3342;
77 background: #131a25; color: var(--ink); padding: 8px; font: inherit;
78}
79dialog#help-dialog menu { display: flex; gap: 8px; justify-content: flex-end; margin: 14px 0 0; padding: 0; }
80dialog#help-dialog button { border: 0; border-radius: 10px; padding: 10px 14px; background: #2a3342; color: var(--ink); font: inherit; }
81dialog#help-dialog button.primary { background: var(--accent); color: #fff; font-weight: 600; }
82
83/* Voor schermlezers, niet voor het oog. */
84.sr-only {
85 position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
86 overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
87}
[084b046]88
89/* ── De hemel ─────────────────────────────────────────────────────────── */
90/* Ligt achter alles en draait altijd. In kaartenstand is hij decor; in
91 berichtenstand vallen de kaarten weg en is hij de interface. */
92#sky { position: fixed; inset: 0; width: 100%; height: 100%; z-index: 0; }
93#app { position: relative; z-index: 1; }
94.topbar { display: flex; align-items: center; gap: 12px; }
95.topbar h1 { margin: 8px 0 20px; }
96.topbar #mode {
97 margin-left: auto; border: 0; border-radius: 999px; padding: 8px 16px;
98 background: #2a3342; color: var(--ink); font: inherit;
99}
100/* De kaarten vallen weg, de hemel blijft: dezelfde beweging als in de app. */
101body.messages-mode .help, body.messages-mode .cards { display: none; }
Note: See TracBrowser for help on using the repository browser.