1# gioser-web
2
3Landing page de **GioSer · En el centro, el ser**: chacana animada con
4shaders WebGL2, nebulosa procedural y cuatro botones cardinales
5(AIRE · FUEGO · TIERRA · AGUA).
6
7## Arquitectura
8
9```
10crates/modules/gioser/
11├── gioser-geom/ geometría agnóstica de la chacana (20 vértices)
12├── gioser-physics/ resorte-amortiguador N-dim crítico-amortiguado
13├── gioser-palette/ 4 elementos + cosmos en RGB lineal
14├── gioser-shaders/ sources GLSL ES 3.00 (FBM cósmico + SDF chacana)
15└── gioser-canvas-web/ renderer WebGL2 que compone todo
16
17crates/apps/gioser-web/ cdylib WASM + index.html + styles.css
18```
19
20Los cuatro primeros son agnósticos del runtime (compilan en cualquier
21target). `gioser-canvas-web` agrega la dependencia de WebGL2 / web-sys.
22Cuando exista `yahweh-web`, los agnósticos siguen tal cual y el renderer
23se enchufa al runtime equivalente a `yahweh_launcher::launch_app`.
24
25## Cómo se ve
26
27- **Fondo:** vacío violeta-noche con tres capas de FBM (5 octavas) en
28 parallax con el mouse + estrellas titilantes + viñeta radial.
29- **Chacana:** SDF de la cruz escalonada con outline gaussiano cyan,
30 glow ámbar exterior, aro circular envolvente y rayos sutiles
31 (calendario andino).
32- **Sol central:** gauss + corona, late con sin(t).
33- **Tilt físico:** spring-damper sub-crítico (ζ=0.72, 2.2 Hz) que apunta
34 hacia el mouse — overshoot suave, settle de ~600 ms.
35- **Botones:** DOM real (accesibles, navegables por teclado, deep-link
36 por hash) proyectados desde 3D al viewport cada frame.
37
38---
39
40## Requisitos
41
42- **Rust** con el target `wasm32-unknown-unknown` instalado.
43 - Con `rustup`: `rustup target add wasm32-unknown-unknown`.
44 - En Artix/Arch con Rust del sistema: el target suele venir incluido en
45 `/usr/lib/rustlib/wasm32-unknown-unknown` (verificá con
46 `ls /usr/lib/rustlib | grep wasm`). Si falta: `pacman -S rust-wasm`
47 (no existe — el target viene con el paquete `rust` base).
48- **wasm-bindgen-cli** (versión exacta 0.2.121, debe matchear la dep del
49 `Cargo.lock`). Verificá con
50 `grep -A1 '^name = "wasm-bindgen"$' Cargo.lock | head` antes de instalar.
51
52```sh
53# Una sola vez:
54cargo install wasm-bindgen-cli --version 0.2.121 --locked
55```
56
57> La versión del CLI **debe** coincidir con la del crate `wasm-bindgen`
58> en `Cargo.lock`. Si no coincide, el output JS no carga el `.wasm`
59> generado. Si actualizás el workspace y wasm-bindgen sube de versión,
60> reinstalá el CLI con la nueva versión.
61
62- Un static server para probar local: `python3 -m http.server` alcanza.
63
64---
65
66## Flujo rápido (un comando)
67
68Hay un wrapper que hace cargo build + wasm-bindgen + copia salida:
69
70```sh
71# Dev — sin optimización, build rápido (~10 s).
72./scripts/build-gioser-web.sh dev
73
74# Release — opt-level=3, lto, strip, ~30 s pero binario pequeño.
75./scripts/build-gioser-web.sh release
76```
77
78El output queda en `crates/apps/gioser-web/pkg/`:
79```
80pkg/
81├── gioser_web.js ← bindings JS (referenciados por index.html)
82├── gioser_web_bg.wasm ← binario WASM
83└── gioser_web.d.ts ← typings (no se usan en runtime, son para IDE)
84```
85
86---
87
88## Probarlo local
89
90```sh
91./scripts/build-gioser-web.sh dev
92python3 -m http.server -d crates/apps/gioser-web 8080
93# Abrir http://localhost:8080/
94```
95
96Si cambiás Rust: re-ejecutar el script y refrescar el browser.
97Si cambiás `index.html` / `styles.css`: alcanza con refrescar.
98
99---
100
101## Build release y deploy
102
103```sh
104./scripts/build-gioser-web.sh release
105```
106
107El binario release optimiza:
108- `opt-level = 3`, `lto = "thin"`, `codegen-units = 1`,
109 `panic = "abort"`, `strip = "symbols"` (del perfil `[profile.release]`
110 del workspace).
111- WASM resultante típico: **~120 KB** (canvas + shaders + bindings) sin
112 comprimir, **~50 KB** gzippeado. wasm-bindgen pasa por
113 `wasm-opt` automáticamente si lo encontrás en `$PATH` (instalable via
114 `binaryen`).
115
116Para deploy, los **artefactos a subir al host estático** son sólo
117cuatro archivos:
118
119```
120crates/apps/gioser-web/
121├── index.html ← entry point
122├── styles.css ← estilos
123└── pkg/
124 ├── gioser_web.js
125 └── gioser_web_bg.wasm
126```
127
128Funciona en cualquier static host (Nginx, GitHub Pages, S3+CloudFront,
129Caddy, netlify, fly, Vercel static). **Importante:**
130
131- El server debe servir `.wasm` con `Content-Type: application/wasm`.
132 Nginx/Caddy lo hacen por default; algunos hosts muy viejos no — fijate.
133- `index.html` referencia `./pkg/gioser_web.js` con `type="module"`,
134 o sea que el browser usa el ES module loader. Eso requiere servir por
135 HTTP/HTTPS (no `file://`).
136- Fonts de Google: el `<link>` apunta a `fonts.googleapis.com`. Para uso
137 offline o sin tracking, descargá las fuentes y servilas locales.
138
139### Comando deploy "tar + scp"
140
141```sh
142./scripts/build-gioser-web.sh release
143tar czf gioser-web-dist.tar.gz \
144 -C crates/apps/gioser-web \
145 index.html styles.css pkg/
146
147# Subir al server:
148scp gioser-web-dist.tar.gz user@host:/var/www/gioser/
149ssh user@host 'cd /var/www/gioser && tar xzf gioser-web-dist.tar.gz'
150```
151
152### GitHub Pages / gitea pages
153
154Configurá la branch de pages a apuntar a un directorio que contenga
155sólo los 4 archivos. Un workflow CI que corra el script y commitee el
156`pkg/` a la branch de deploy hace el trabajo.
157
158---
159
160## Routing
161
162Los `<a href="#aire|fuego|tierra|agua">` apuntan a anchors locales.
163Cuando definamos rutas reales (otras páginas, sub-apps, etc.), basta con
164cambiar el `href` en `index.html` o interceptar el click desde JS.
165
166---
167
168## Tests de los crates agnósticos
169
170Los cuatro crates sin gpui/web tienen tests unitarios estándar:
171
172```sh
173cargo test -p gioser-geom -p gioser-physics -p gioser-palette -p gioser-shaders
174```
175
176`gioser-canvas-web` no tiene tests (depende de WebGL2 que sólo existe
177en browser).
178
179---
180
181## Troubleshooting
182
183**Pantalla en blanco + error en consola "no link/binding found"**
184→ Versión de `wasm-bindgen-cli` no coincide con la del `Cargo.lock`.
185Reinstalá con `cargo install wasm-bindgen-cli --version <X.Y.Z>`
186donde `<X.Y.Z>` sale de `grep '^version' Cargo.lock` cerca de la entrada
187`wasm-bindgen`.
188
189**"WebGL2 not supported"** en algunos navegadores viejos
190→ No hay fallback. WebGL2 es soporte universal en navegadores modernos
191(Chrome/Edge/Firefox/Safari desde 2017). Para targets ancestrales habría
192que escribir un renderer WebGL1, no contemplado por ahora.
193
194**Build muy lento por las deps de web-sys**
195→ Las features de web-sys están minimizadas en el Cargo.toml; sólo se
196importan las que el renderer usa. El primer build sí es lento (~1 min),
197los incrementales son rápidos.
README.md
gioser-web
Landing page de GioSer · En el centro, el ser: chacana animada con
shaders WebGL2, nebulosa procedural y cuatro botones cardinales
(AIRE · FUEGO · TIERRA · AGUA).
Arquitectura
crates/modules/gioser/
├── gioser-geom/ geometría agnóstica de la chacana (20 vértices)
├── gioser-physics/ resorte-amortiguador N-dim crítico-amortiguado
├── gioser-palette/ 4 elementos + cosmos en RGB lineal
├── gioser-shaders/ sources GLSL ES 3.00 (FBM cósmico + SDF chacana)
└── gioser-canvas-web/ renderer WebGL2 que compone todo
crates/apps/gioser-web/ cdylib WASM + index.html + styles.css
Los cuatro primeros son agnósticos del runtime (compilan en cualquier
target). gioser-canvas-web agrega la dependencia de WebGL2 / web-sys.
Cuando exista yahweh-web, los agnósticos siguen tal cual y el renderer
se enchufa al runtime equivalente a yahweh_launcher::launch_app.
Cómo se ve
- Fondo: vacío violeta-noche con tres capas de FBM (5 octavas) en
parallax con el mouse + estrellas titilantes + viñeta radial.
- Chacana: SDF de la cruz escalonada con outline gaussiano cyan,
glow ámbar exterior, aro circular envolvente y rayos sutiles
(calendario andino).
- Sol central: gauss + corona, late con sin(t).
- Tilt físico: spring-damper sub-crítico (ζ=0.72, 2.2 Hz) que apunta
hacia el mouse — overshoot suave, settle de ~600 ms.
- Botones: DOM real (accesibles, navegables por teclado, deep-link
por hash) proyectados desde 3D al viewport cada frame.
Requisitos
- Rust con el target
wasm32-unknown-unknown instalado.
- Con
rustup: rustup target add wasm32-unknown-unknown.
- En Artix/Arch con Rust del sistema: el target suele venir incluido en
/usr/lib/rustlib/wasm32-unknown-unknown (verificá con
ls /usr/lib/rustlib | grep wasm). Si falta: pacman -S rust-wasm
(no existe — el target viene con el paquete rust base).
- wasm-bindgen-cli (versión exacta 0.2.121, debe matchear la dep del
Cargo.lock). Verificá con
grep -A1 '^name = "wasm-bindgen"$' Cargo.lock | head antes de instalar.
# Una sola vez:
cargo install wasm-bindgen-cli --version 0.2.121 --locked
La versión del CLI debe coincidir con la del crate wasm-bindgen
en Cargo.lock. Si no coincide, el output JS no carga el .wasm
generado. Si actualizás el workspace y wasm-bindgen sube de versión,
reinstalá el CLI con la nueva versión.
- Un static server para probar local:
python3 -m http.server alcanza.
Flujo rápido (un comando)
Hay un wrapper que hace cargo build + wasm-bindgen + copia salida:
# Dev — sin optimización, build rápido (~10 s).
./scripts/build-gioser-web.sh dev
# Release — opt-level=3, lto, strip, ~30 s pero binario pequeño.
./scripts/build-gioser-web.sh release
El output queda en crates/apps/gioser-web/pkg/:
pkg/
├── gioser_web.js ← bindings JS (referenciados por index.html)
├── gioser_web_bg.wasm ← binario WASM
└── gioser_web.d.ts ← typings (no se usan en runtime, son para IDE)
Probarlo local
./scripts/build-gioser-web.sh dev
python3 -m http.server -d crates/apps/gioser-web 8080
# Abrir http://localhost:8080/
Si cambiás Rust: re-ejecutar el script y refrescar el browser.
Si cambiás index.html / styles.css: alcanza con refrescar.
Build release y deploy
./scripts/build-gioser-web.sh release
El binario release optimiza:
opt-level = 3, lto = "thin", codegen-units = 1,
panic = "abort", strip = "symbols" (del perfil [profile.release]
del workspace).
- WASM resultante típico: ~120 KB (canvas + shaders + bindings) sin
comprimir, ~50 KB gzippeado. wasm-bindgen pasa por
wasm-opt automáticamente si lo encontrás en $PATH (instalable via
binaryen).
Para deploy, los artefactos a subir al host estático son sólo
cuatro archivos:
crates/apps/gioser-web/
├── index.html ← entry point
├── styles.css ← estilos
└── pkg/
├── gioser_web.js
└── gioser_web_bg.wasm
Funciona en cualquier static host (Nginx, GitHub Pages, S3+CloudFront,
Caddy, netlify, fly, Vercel static). Importante:
- El server debe servir
.wasm con Content-Type: application/wasm.
Nginx/Caddy lo hacen por default; algunos hosts muy viejos no — fijate.
index.html referencia ./pkg/gioser_web.js con type="module",
o sea que el browser usa el ES module loader. Eso requiere servir por
HTTP/HTTPS (no file://).
- Fonts de Google: el
<link> apunta a fonts.googleapis.com. Para uso
offline o sin tracking, descargá las fuentes y servilas locales.
Comando deploy "tar + scp"
./scripts/build-gioser-web.sh release
tar czf gioser-web-dist.tar.gz \
-C crates/apps/gioser-web \
index.html styles.css pkg/
# Subir al server:
scp gioser-web-dist.tar.gz user@host:/var/www/gioser/
ssh user@host 'cd /var/www/gioser && tar xzf gioser-web-dist.tar.gz'
GitHub Pages / gitea pages
Configurá la branch de pages a apuntar a un directorio que contenga
sólo los 4 archivos. Un workflow CI que corra el script y commitee el
pkg/ a la branch de deploy hace el trabajo.
Routing
Los <a href="#aire|fuego|tierra|agua"> apuntan a anchors locales.
Cuando definamos rutas reales (otras páginas, sub-apps, etc.), basta con
cambiar el href en index.html o interceptar el click desde JS.
Tests de los crates agnósticos
Los cuatro crates sin gpui/web tienen tests unitarios estándar:
cargo test -p gioser-geom -p gioser-physics -p gioser-palette -p gioser-shaders
gioser-canvas-web no tiene tests (depende de WebGL2 que sólo existe
en browser).
Troubleshooting
Pantalla en blanco + error en consola "no link/binding found"
→ Versión de wasm-bindgen-cli no coincide con la del Cargo.lock.
Reinstalá con cargo install wasm-bindgen-cli --version <X.Y.Z>
donde <X.Y.Z> sale de grep '^version' Cargo.lock cerca de la entrada
wasm-bindgen.
"WebGL2 not supported" en algunos navegadores viejos
→ No hay fallback. WebGL2 es soporte universal en navegadores modernos
(Chrome/Edge/Firefox/Safari desde 2017). Para targets ancestrales habría
que escribir un renderer WebGL1, no contemplado por ahora.
Build muy lento por las deps de web-sys
→ Las features de web-sys están minimizadas en el Cargo.toml; sólo se
importan las que el renderer usa. El primer build sí es lento (~1 min),
los incrementales son rápidos.