Files
ulicraft-server-v1/plan/09-landing.md
Oier Bravo Urtasun 67d1f82e6a refactor!: unify into one compose, drop airgap/mirror/dnsmasq/avahi/blessingskin
Collapse the override-file matrix into a single docker-compose.yml holding the
whole stack: drasl, minecraft, mc-backup, caddy, nmsr, uptime-kuma. Bring-up is
now just `docker compose up -d --build`.

Removed features (dead-ends for this deployment):
- airgap / full asset mirror (mirror-airgap.sh, mirror-mods.sh, 20-mirror.caddy,
  caddy local-CA export, /ca.crt)
- dnsmasq + avahi/mDNS + dns-records.sh + mdns-host-setup.sh + ENABLE_MDNS;
  DNS is now handled outside this repo (HOST_LAN_IP dropped)
- Blessing Skin auth variant (compose + 00-core-blessingskin.caddy + BS_* env)
- host-nginx-static variant (docker-compose.nginx.yml, nginx/ulicraft.conf.tmpl)
- build-stack.sh and its run modes (online/airgap/core)

Production ingress is the only path now: host nginx terminates TLS (LE certs)
in front of caddy on a localhost-only port; caddy routes every vhost by Host
header. Launcher downloads move mirror/launcher -> launcher/.

Docs: README, deploy skill, and plan/ rewritten to match; obsolete plan docs
(dnsmasq, blessing-skin, assets-mirror, full-airgap-mirror, dns-and-run-modes)
deleted.

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

5.7 KiB
Raw Blame History

Landing page — guest onboarding site

Summary

Apex ulicraft.net 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 serves at the apex (behind host nginx). 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 vendored 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.net"). Bake before deploy: BASE_DOMAIN=ulicraft.net 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 (self-contained)
└── 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 locally

The design pulled fonts from Google Fonts CDN; we vendor them instead to keep the page self-contained. 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 — 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 → 3 packwiz import (pack.${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 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 Caddy 10-static.caddy).

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.net 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 ./launcher
  • Optional: try mood: nether / hero: split for party day
  • Optional: wire real player count (option C) via mc-monitor JSON if wanted