Files
ulicraft-server-v1/plan/09-landing.md
Oier Bravo Urtasun 3d52951355 feat(landing): pixel design ported to static Astro + en/es/eu i18n
Adopt the "Carved from stone" pixel design (landing/design/) as the apex
onboarding page, ported from its React/Babel-via-CDN prototype to static
Astro so it works on an offline LAN. Real modded-LAN content replaces the
prototype's fictional public-SMP copy.

- Vendor web fonts locally (tooling/fetch-fonts.sh -> public/fonts/) so the
  page renders without the Google Fonts CDN at party time.
- Port the design system (main.css: mood/hero/bevels) and split markup into
  Astro components (Creeper, PixelIcon, CopyChip, ServerListPanel).
- site.ts holds language-neutral config + theme knobs (mood/hero/headFont/
  dust) that replace the design's in-browser TweaksPanel; LITERALS holds
  never-translated product/in-game terms.
- i18n: English (/), Spanish (/es/), Euskera (/eu/) generated from one
  [...lang].astro via getStaticPaths; copy lives in src/i18n/ui.ts. Nav has
  an EN/ES/EU switcher; html lang + hreflang set per page.
- Status panel shows a static server-list row + honest stat tiles (no fake
  live count). Copy + scroll-reveal are the only client JS.

Build emits to ../www (gitignored). Euskera strings pending a native review.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 18:18:36 +02:00

5.7 KiB
Raw Permalink Blame History

Landing page — guest onboarding site

Summary

Apex ulicraft.local serves a static page guiding guests through joining: download launcher → add account → import modpack → connect. Built with Astro + TypeScript in ./landing/; pnpm run build emits straight into ./www/, which Caddy/nginx serve at the apex. No runtime framework — output is plain HTML/CSS plus one tiny vanilla script (copy-to-clipboard + scroll reveal).

The visual is the "Carved from stone" pixel design ("Claude Design", landing/design/): dark overworld palette, MC-GUI bevel buttons, pixel type, creeper mark, server-list panel. That design was a React/Babel-via-CDN prototype for a fictional public SMP; it was ported to static Astro with the real modded-LAN content and offline-safe assets.

Stack & wiring

  • landing/ — Astro project (own package.json, tsconfig). pnpm only.
  • astro.config.mjsoutDir: "../www". Build overwrites www/; www/ is gitignored (generated artifact).
  • BASE_DOMAIN env read at build time in src/data/site.ts (process.env.BASE_DOMAIN ?? "ulicraft.local"). Bake before deploy: BASE_DOMAIN=ulicraft.local pnpm run build.
  • Logo: wide wordmark from the design at landing/public/logo.png (hero + favicon). image-rendering: pixelated keeps it crisp.

Source layout

landing/
├── design/                     # "Claude Design" prototype (reference, not built)
├── public/
│   ├── logo.png                # hero wordmark (from design/assets/ulicraft-logo.png)
│   └── fonts/                  # vendored woff2 + fonts.css (offline-safe)
└── src/
    ├── data/site.ts            # single source: content + theme knobs
    ├── styles/main.css         # ported design system (mood/hero/bevels)
    ├── components/             # Creeper, PixelIcon, CopyChip, ServerListPanel
    └── pages/index.astro       # composition + copy/reveal script + dust

Fonts — vendored for offline LAN

The design pulled fonts from Google Fonts CDN; that breaks on offline LAN day. tooling/fetch-fonts.sh downloads the woff2 + a URL-rewritten fonts.css into landing/public/fonts/. index.astro links /fonts/fonts.css. Re-run the script only if the font set changes (keep families in sync with main.css --font-*): Pixelify Sans, Space Grotesk, Press Start 2P, Silkscreen, VT323.

Theme config (replaces the design's in-browser TweaksPanel)

site.ts theme is baked at build — edit + rebuild to change:

  • mood: grass (default) | nether | end
  • hero: centered (default) | split | spotlight
  • headFont: pixelify (default) | 8bit | silkscreen
  • dust: floating hero particles (CSS animation; respects reduced-motion)

index.astro sets <html data-mood data-hero data-head> + --font-head from these.

Languages (i18n)

Three locales, static, build-time, offline-safe — English (default, /), Spanish (/es/), Euskera (/eu/).

  • One template src/pages/[...lang].astro with getStaticPaths emits all three routes (/, /es/, /eu/). No runtime/JS routing.
  • Translatable copy lives in src/i18n/ui.ts (ui[locale]), keyed identically across locales. site.ts holds only language-neutral config (URLs, theme, launcher files, stat/feature structure).
  • Product / in-game literals never translated — site.ts LITERALS (authlib-injector, Multiplayer, Add Server). OS names + version too.
  • Sentences with links/kbd are split into parts (pre/post/link, pa/pb) so markup stays in the template, not the strings.
  • Nav has a pixel EN · ES · EU switcher (.lang-switch); active locale highlighted. <html lang> + <link rel="alternate" hreflang> set per page.
  • Adding a locale: extend the Lang union + ui/LANG_* maps in ui.ts, add a getStaticPaths entry. No template change.

Content (real modded-LAN flow, all in site.ts)

  • Hero: wordmark, eyebrow Modded LAN · NeoForge 1.21.1, tagline, sub, server address mc.${BASE_DOMAIN} (copy chip), "How to Join".
  • Status: static server-list panel (no fake live count — option B) + 4 honest stat tiles (Mods / NeoForge ver / Player slots / Backups).
  • Features ×4: kitchen-sink pack · self-hosted Drasl identity+skins · one-click packwiz · built-to-last (homelab + 6h backups).
  • How to Join ×4: 1 Fjord launcher (3 OS) → 2 authlib account (auth.${BASE_DOMAIN}/authlib-injector) + register link + CA-cert note → 3 packwiz import (packwiz.${BASE_DOMAIN}/pack.toml) → 4 connect.
  • Footer: Mojang trademark disclaimer.

Page links to fixed names so they survive launcher version bumps:

  • fjord-windows-setup.exe
  • fjord-macos.dmg
  • fjord-linux-x86_64.AppImage

tooling/fetch-launcher.sh must create these as symlinks under mirror/launcher/latest/ pointing at the real versioned assets. Keep the names in sync between site.ts and the script. Mounted so they resolve at /launcher/latest/… (see nginx/Caddy ingress).

Tasks

  • Vendor fonts (tooling/fetch-fonts.sh) → public/fonts/
  • Port design → static Astro (components + main.css + index.astro)
  • Real content in site.ts; theme knobs replace TweaksPanel
  • i18n: en/es/eu via [...lang].astro + i18n/ui.ts; nav language switcher
  • BASE_DOMAIN=ulicraft.local pnpm run build → verified www/ output + screenshot
  • Extend fetch-launcher.sh: symlink stable names → versioned files
  • Confirm ingress serves apex from ./www and /launcher/latest/* from mirror
  • Optional: try mood: nether / hero: split for party day
  • Optional: wire real player count (option C) via mc-monitor JSON if wanted