ski-resort

byJonathan Witcoski

i am building out the game for www.globalskiatlas.com/playable/ in which teh user picks the ski resort, and three.js assets then take data from s3 about the ski resort (heightmap, tree areas, ect) and puts 3d game assets on it. I need to make the game richer and more vibrant

No preview

Comments (0)

No comments yet. Be the first!

System Requirements

Page 1 of 20

System Requirements Document for ski-resort

1. Introduction

This document specifies the system requirements for ski-resort, the playable 3D ski game delivered at www.globalskiatlas.com/playable/. The product intent is to let a visitor pick a real ski resort and then drive into a live Three.js scene built from that resort's actual data — heightmap, tree areas, and other terrain data — hosted on S3. Three.js assets consume that data and place 3D game assets onto the terrain, producing a playable alpine world rather than a page to read.

The explicit product goal is to make this game richer and more vibrant: a saturated, high-contrast, toy-like alpine world that feels like a physical object you can inspect and drive into, not a photoreal-muted simulation.

The audience is skiers, snowboarders, and armchair mountain enthusiasts who already know the resorts by name and arrive from the globe/atlas brand. They want to feel the mountain, not read about it.

Page 2 of 20

2. System Overview

The current system is a browser-playable 3D game with three first-party surfaces:

  • Landing — an anonymous public entry surface presenting the playable game and its entry into resort selection.
  • Resort Select — the surface where the player chooses the ski resort to load.
  • Resort Scene — the surface that renders the selected resort as a Three.js 3D scene populated from S3-sourced resort data.

The single accepted active human actor is the Ski Resort Player. S3 is a non-persona external data provider: it supplies resort data (heightmap, tree areas, and other terrain data) that the Three.js assets consume. Three.js is the rendering technology that constructs and renders the selected resort scene.

Accepted behavior in scope: resort selection by the player; retrieval of the selected resort's data from S3; construction and rendering of the resort scene with 3D game assets placed on the terrain; and the enrichment/vibrancy of that scene.

Narrow exclusions: no account, login, or identity system is required — all three surfaces are anonymously accessible. No resort authoring, editing, or upload capability is in scope. No social, sharing, leaderboard, or multiplayer capability is in scope. No photoreal texture pipeline is in scope; the visual language is deliberately low-poly and toy-like.

Page 3 of 20

2a. Product Interpretation and Delivery Boundary

The product is delivered as a playable web game at the path www.globalskiatlas.com/playable/. Delivery is first-party and browser-based; the player needs no account and no installation. All three surfaces are anonymously reachable, and no protected state exists, so there is no identity-establishment lifecycle in the current scope.

Resort data is owned by an external provider: the system reads heightmap, tree-area, and other terrain data from S3 for the selected resort. The system does not author, edit, or publish that data. Three.js is the rendering layer that consumes the S3 data and places 3D game assets onto the terrain.

The current horizon covers the playable game, resort selection, S3 data retrieval, Three.js scene construction, and the richer/more-vibrant visual treatment. Anything beyond that — additional game modes, progression, social features, or resort authoring — is out of current scope and is not part of current acceptance.

2b. Source Content Inventory

Not applicable. No reference directive in this project declares a content_source, so no source content inventory is produced.

2c. Page Content and Component Coverage

Page 4 of 20

Landing

  • Information and state: The playable game's identity and purpose; the invitation to pick a mountain and drive it; a live Three.js diorama of a generic alpine resort rendered as the hero subject; a status chip indicating the live Three.js rendering and S3 terrain data.
  • Primary action: Enter resort selection ("Choose your resort").
  • Supporting actions: None required beyond entry; the diorama is non-interactive scenery.
  • Domain entities: Generic resort diorama (terrain tile, conifers, lift towers, chair, groomed run ribbons, drifting snow); S3 terrain data as the diorama's source.
  • Component responsibilities:
    • Live Three.js diorama occupying the right 60% at desktop and the top 52vh at mobile, bleeding off the right and bottom edges.
    • Wordmark and headline block, flush-left and bottom-aligned over the empty left column, never centred.
    • Coral capsule CTA with a hard navy offset shadow and no blur.
    • Mint status chip reading the live Three.js / S3 terrain data provenance.
  • States:
    • Loading: illustrated skier mascot loading state while the diorama's Three.js scene initialises.
    • Empty: not applicable — the diorama is always present.
    • Success: diorama idles with a slow orbiting camera and drifting snow; headline and CTA are fully readable.
    • Error: if the diorama's Three.js scene cannot initialise, the hero area shows the mascot loading state with a retry affordance; the headline and CTA remain fully readable and functional so the player can still proceed to resort selection.
    • Recovery: retry re-attempts diorama initialisation without blocking entry to resort selection.
Page 5 of 20

Resort Select

  • Information and state: The set of available ski resorts; per-resort identity (name); per-resort preview rendered from that resort's real S3 heightmap as a small auto-rotating low-poly thumbnail; the currently selected resort.
  • Primary action: Select a resort, which loads that resort's S3 data and enters the resort scene.
  • Supporting actions: Change the current selection before entering; return to the landing surface.
  • Domain entities: Resort (name, S3 heightmap, S3 tree-area mask, other S3 terrain data); resort thumbnail (low-poly mesh derived from the resort's real heightmap).
  • Component responsibilities:
    • Tile grid: 3-up at desktop, 2-up at 768px, 1-up at 375px.
    • Each tile renders its own auto-rotating low-poly thumbnail from that resort's real S3 heightmap, so the picker is itself a preview of the game.
    • Selected state is a full coral fill with the outline going navy-on-coral; unselected tiles are white with the outline only.
    • Tiles carry a 24px radius, a 3px navy outline, and a hard 6px offset navy shadow with no blur.
  • States:
    • Loading: tiles show the illustrated skier mascot loading state while each resort's S3 heightmap is fetched and its thumbnail mesh is built.
    • Empty: if no resorts are available from S3, the grid area shows an explicit empty message with a retry affordance; the return-to-landing action remains available.
    • Success: every available resort appears as a tile with its auto-rotating thumbnail; the selected tile is fully coral-filled.
    • Error: if a resort's S3 data cannot be retrieved, that tile shows an error state with a retry affordance and cannot be entered; other tiles remain selectable.
    • Recovery: retrying a failed tile re-attempts that resort's S3 data retrieval and thumbnail build without disturbing the rest of the grid.
Page 6 of 20

Resort Scene

  • Information and state: The selected resort rendered as a live Three.js 3D scene filling the viewport edge-to-edge; resort name; altitude; selected run; the S3 asset manifest (heightmap, tree masks, texture sets) as a legend with mint colour swatches; current camera mode.
  • Primary action: Drive the resort — move through the terrain with physics-driven camera follow.
  • Supporting actions: Change camera mode; change the selected run; return to resort selection.
  • Domain entities: Terrain mesh built from the S3 heightmap; instanced conifer clusters driven by S3 tree-area masks; lift towers and chair lines; groomed-run ribbons; snow fences; start gate; skier; carve trail; day-cycle sky.
  • Component responsibilities:
    • Canvas fills the viewport edge-to-edge; no readable chrome overlaps the canvas centre.
    • Bottom-left HUD capsule: resort name in Fredoka, altitude and selected run in tabular numerals, a mint S3-asset legend chip; collapses to a single pill at 375px.
    • Top-right control cluster: camera mode, run selector, back to resorts; inset 16px.
    • Collapsible right rail: S3 asset manifest legend with mint colour swatches.
    • In-scene: physics-driven camera follow with slight spring lag; persistent carve trails that fade over ~12s; lift chairs travelling their real line with subtle sway; tree instances swaying on a wind field; day-cycle sky shifting sun position and snow specular.
  • States:
    • Loading: the illustrated skier mascot loading state while the selected resort's S3 heightmap, tree-area masks, and other terrain data are fetched and the Three.js scene is constructed.
    • Empty: not applicable — a resort scene is only entered after a resort is selected.
    • Success: the resort renders as a live drivable Three.js scene with 3D game assets placed on the S3-derived terrain; HUD and controls are fully readable and never cover the canvas centre.
    • Error: if the selected resort's S3 data fails to load or the scene cannot be constructed, the scene area shows an explicit error state with a retry affordance and a return-to-resort-selection action.
    • Recovery: retry re-attempts S3 data retrieval and scene construction for the same resort; returning to resort selection lets the player pick a different resort.
Page 7 of 20

3. Functional Requirements

FR-1 — Enter the playable game As a Ski Resort Player, I should be able to arrive at the playable game at www.globalskiatlas.com/playable/ and understand that I can pick a mountain and drive it, so that I can begin.

  • Provenance: explicit.
  • Trigger/input: the player navigates to the playable path.
  • Observable result: the Landing surface renders with a live Three.js diorama of a generic alpine resort, the headline, and the coral "Choose your resort" capsule CTA.
  • Access state: anonymous; no account required.
  • Failure/recovery: if the diorama's Three.js scene cannot initialise, the hero area shows the mascot loading state with a retry affordance while the headline and CTA remain readable and functional.
  • Continuation: the player activates the CTA to enter resort selection.

FR-2 — Pick a ski resort As a Ski Resort Player, I should be able to pick a ski resort from the available resorts, so that the game loads the mountain I want to play.

  • Provenance: explicit.
  • Trigger/input: the player opens Resort Select and chooses a resort tile.
  • Observable result: the chosen tile enters the selected state (full coral fill, navy-on-coral outline) and the resort's S3 data begins loading.
  • Access state: anonymous; no account required.
  • Failure/recovery: if a resort's S3 data cannot be retrieved, that tile shows an error state with a retry affordance and cannot be entered; other tiles remain selectable.
  • Continuation: on successful load, the player enters the Resort Scene for that resort.

FR-3 — Preview each resort from its real S3 heightmap As a Ski Resort Player, I should see each resort tile render a small auto-rotating low-poly thumbnail built from that resort's real S3 heightmap, so that choosing a mountain is already playing it.

  • Provenance: explicit (the picker is itself a preview of the game, per the accepted creative direction).
  • Trigger/input: Resort Select loads the available resorts.
  • Observable result: each tile shows an auto-rotating low-poly thumbnail derived from that resort's actual S3 heightmap.
  • Access state: anonymous.
  • Failure/recovery: a tile whose heightmap cannot be fetched shows the mascot loading state, then an error state with retry.
  • Continuation: the player selects a tile to enter the resort scene.

FR-4 — Load resort data from S3 As a Ski Resort Player, I should have the selected resort's data — heightmap, tree areas, and other terrain data — retrieved from S3, so that the scene is built from the real mountain.

  • Provenance: explicit (S3 sourcing is a hard constraint); the retrievability of heightmaps and tree areas is required_inference.
  • Trigger/input: the player selects a resort.
  • Observable result: the selected resort's heightmap, tree-area masks, and other terrain data are retrieved from S3 and made available to the Three.js scene.
  • Access state: anonymous; S3 is an external data provider owned outside the application.
  • Failure/recovery: if retrieval fails, the Resort Scene shows an explicit error state with a retry affordance and a return-to-resort-selection action.
  • Continuation: on success, the Three.js scene is constructed from the retrieved data.

FR-5 — Construct and render the resort scene with Three.js As a Ski Resort Player, I should see the selected resort rendered as a live Three.js 3D scene, so that I can drive into the mountain.

  • Provenance: explicit; the availability of Three.js assets to construct and render the scene is required_inference.
  • Trigger/input: the selected resort's S3 data has been retrieved.
  • Observable result: the Resort Scene renders the resort as a live Three.js 3D scene filling the viewport edge-to-edge.
  • Access state: anonymous.
  • Failure/recovery: if the scene cannot be constructed, the scene area shows an explicit error state with retry and return-to-resort-selection.
  • Continuation: the player drives the scene.

FR-6 — Place 3D game assets on the terrain As a Ski Resort Player, I should see 3D game assets placed onto the resort terrain, so that the mountain reads as a populated, playable world.

  • Provenance: explicit.
  • Trigger/input: the Three.js scene is constructed from the S3 data.
  • Observable result: 3D game assets are placed onto the terrain — instanced conifer clusters driven by the S3 tree-area masks, lift towers and chair lines, groomed-run ribbons, snow fences, and a start gate.
  • Access state: anonymous.
  • Failure/recovery: if an asset set cannot be placed, the scene still renders the terrain and the remaining assets; the S3 asset manifest legend reflects what loaded.
  • Continuation: the player drives through the populated scene.

FR-7 — Drive the resort with physics-driven camera follow As a Ski Resort Player, I should be able to drive through the resort scene with a physics-driven camera that follows with slight spring lag, so that the mountain feels like a place I am moving through.

  • Provenance: explicit (accepted creative direction for the playable scene).
  • Trigger/input: the player moves within the Resort Scene.
  • Observable result: the camera follows the player's movement with slight spring lag; the skier leaves a persistent carve trail that fades over ~12s.
  • Access state: anonymous.
  • Failure/recovery: if input is lost, the camera settles to a stable follow position rather than drifting.
  • Continuation: the player continues driving or changes camera mode.

FR-8 — Change camera mode and selected run As a Ski Resort Player, I should be able to change the camera mode and the selected run from the top-right control cluster, so that I can view and play the mountain the way I want.

  • Provenance: explicit (accepted creative direction for the Resort Scene chrome).
  • Trigger/input: the player activates a control in the top-right cluster.
  • Observable result: the camera mode or selected run changes; the bottom-left HUD capsule reflects the new selected run.
  • Access state: anonymous.
  • Failure/recovery: if a run selection cannot be applied, the previous selection remains and the HUD is unchanged.
  • Continuation: the player continues driving.

FR-9 — Read the resort HUD and S3 asset manifest As a Ski Resort Player, I should see the resort name, altitude, and selected run in a bottom-left HUD capsule and the S3 asset manifest as a collapsible right-rail legend, so that I always know where I am and what data built the scene.

  • Provenance: explicit (accepted creative direction for the Resort Scene chrome).
  • Trigger/input: the Resort Scene is active.
  • Observable result: the bottom-left HUD capsule shows the resort name in Fredoka and altitude and selected run in tabular numerals, with a mint S3-asset legend chip; the collapsible right rail shows the S3 asset manifest (heightmap, tree masks, texture sets) with mint colour swatches. Neither overlaps the canvas centre. At 375px the HUD collapses to a single pill.
  • Access state: anonymous.
  • Failure/recovery: if the manifest cannot be enumerated, the legend shows the assets that did load and marks the rest as unavailable.
  • Continuation: the player continues driving or collapses the rail.

FR-10 — Return to resort selection As a Ski Resort Player, I should be able to return to resort selection from the Resort Scene, so that I can pick a different mountain.

  • Provenance: explicit (accepted creative direction for the Resort Scene chrome).
  • Trigger/input: the player activates "back to resorts" in the top-right control cluster.
  • Observable result: the player returns to Resort Select with the previously selected resort still indicated.
  • Access state: anonymous.
  • Failure/recovery: if the return transition fails, the player remains in the Resort Scene with the control still available.
  • Continuation: the player selects a different resort.

FR-11 — Experience a richer, more vibrant resort world As a Ski Resort Player, I should experience the resort as a saturated, high-contrast, toy-like world rather than a photoreal-muted one, so that the game feels richer and more vibrant.

  • Provenance: explicit.
  • Trigger/input: any surface of the game renders.
  • Observable result: the visual language is applied consistently — the pastel sky ground, the coral primary, the mint accent, the navy ink outlines, the fat rounded capsules, the hard offset shadows with no blur, the low-poly faceted geometry, and the in-scene palette (snow #F4FAFF with #D9E8F5 shadow, conifers #1F6B4A→#2E9E63, rock #7C6A5B, lift towers #FF5A4E, groomed runs #FFF3C4, sky dome gradient #8FD3F4→#EAF4FB).
  • Access state: anonymous.
  • Failure/recovery: if a visual token cannot be applied, the fallback remains within the same palette and shape language; no photoreal or muted fallback is used.
  • Continuation: the player continues through the game.

FR-12 — Live in-scene motion As a Ski Resort Player, I should see the resort scene alive with motion — lift chairs travelling their real line with subtle sway, tree instances swaying on a wind field, and a day-cycle sky shifting the sun position and snow specular — so that the terrain reads as live data rather than a texture.

  • Provenance: explicit (accepted creative direction for the playable scene).
  • Trigger/input: the Resort Scene is active.
  • Observable result: lift chairs travel their line with subtle sway; tree instances sway on a wind field; the day-cycle sky shifts sun position and snow specular.
  • Access state: anonymous.
  • Failure/recovery: if a motion system cannot run, the scene holds a stable composed frame rather than failing.
  • Continuation: the player continues driving.

FR-13 — Reduced-motion behavior As a Ski Resort Player who prefers reduced motion, I should get a still, composed experience, so that the game is usable without decorative motion.

  • Provenance: explicit (accepted creative direction).
  • Trigger/input: prefers-reduced-motion is set.
  • Observable result: the landing diorama holds a single static hero frame; particles and sway stop; the camera push-in becomes a crossfade; the tile grid shows static thumbnails; moving and scrollable content stops and shows whole items, wrapping into rows or sitting in a horizontally scrollable row.
  • Access state: anonymous.
  • Failure/recovery: not applicable — this is the stable state.
  • Continuation: the player proceeds through the game normally.
Page 8 of 20

4. User Personas

Page 9 of 20

Ski Resort Player

Product context. The Ski Resort Player arrives at www.globalskiatlas.com/playable/ from the globe/atlas brand. They already know ski resorts by name and want to feel a mountain rather than read about it. They are on a browser, with no account and no installation, and they expect the game to start playing itself before they click anything.

Primary goal. Pick a real ski resort and drive into a live, richer, more vibrant Three.js scene built from that resort's actual S3 terrain data.

Distinct accepted responsibilities.

  • Entering the playable game and understanding the pick-a-mountain premise from the live diorama.
  • Choosing a resort from the available resorts, using each tile's auto-rotating thumbnail — rendered from that resort's real S3 heightmap — as the basis for the choice.
  • Driving the selected resort scene with physics-driven camera follow, leaving persistent carve trails.
  • Changing camera mode and selected run, and reading the resort name, altitude, and selected run from the HUD.
  • Reading the S3 asset manifest legend to understand what data built the scene.
  • Returning to resort selection to pick a different mountain.

Relevant inputs or decisions. Which resort to pick; which camera mode to use; which run to select; whether to consult the S3 asset manifest; whether to return to resort selection.

Interactions with other accepted participants. The Ski Resort Player is the only accepted active human actor. The player's interaction with S3 is mediated by the system: S3 is an external data provider that supplies the resort's heightmap, tree-area masks, and other terrain data, and the player observes the result as the rendered scene and the asset manifest legend. Three.js is the rendering technology, not a participant.

Observable success. The player is driving a live, saturated, toy-like Three.js resort scene built from the real S3 terrain data of the resort they picked, with readable HUD and controls that never cover the canvas centre, and can return to pick another mountain.

What makes this role's work different. This is a play role, not an administrative or authoring role. The player never creates, edits, or publishes resort data; they select from what exists and then inhabit it. Their success is measured by the felt richness and vibrancy of the world they are driving through, not by a record they produce.

Page 10 of 20

5. Core User Flows

Flow 1 — Enter the game and pick a mountain

  1. The Ski Resort Player navigates to www.globalskiatlas.com/playable/.
  2. The Landing surface renders: a live Three.js diorama of a generic alpine resort occupies the right 60% at desktop (top 52vh at mobile), bleeding off the right and bottom edges, idling with a slow orbiting camera and drifting snow. The wordmark and the headline "PICK A MOUNTAIN. DRIVE IT." sit flush-left and bottom-aligned over the empty left column, with the coral capsule CTA "CHOOSE YOUR RESORT →" pinned beneath and the mint chip reading "LIVE THREE.JS · S3 TERRAIN DATA".
  3. If the diorama's Three.js scene cannot initialise, the hero area shows the illustrated skier mascot loading state with a retry affordance; the headline and CTA remain fully readable and functional. The player may retry or proceed.
  4. The player activates the coral CTA. It depresses 6px into its own hard navy offset shadow, then a coral wipe transitions into Resort Select.
  5. Resort Select shows the available resorts as a tile grid — 3-up at desktop, 2-up at 768px, 1-up at 375px. Each tile renders a small auto-rotating low-poly thumbnail built from that resort's real S3 heightmap, so the picker is itself a preview of the game.
  6. While each resort's S3 heightmap is fetched and its thumbnail mesh is built, that tile shows the mascot loading state. If a resort's S3 data cannot be retrieved, that tile shows an error state with a retry affordance and cannot be entered; the other tiles remain selectable. If no resorts are available at all, the grid area shows an explicit empty message with a retry affordance, and the return-to-landing action remains available.
  7. The player selects a resort tile. The tile enters the selected state — a full coral fill with the outline going navy-on-coral.
  8. On successful load, the player enters the Resort Scene for that resort.

Flow 2 — Drive the selected resort

  1. The Ski Resort Player arrives at the Resort Scene from Resort Select. A 900ms camera push-in runs from orbit to the player's start gate with a coral wipe.
  2. While the selected resort's S3 heightmap, tree-area masks, and other terrain data are fetched and the Three.js scene is constructed, the illustrated skier mascot loading state is shown.
  3. The scene renders: the canvas fills the viewport edge-to-edge. The terrain mesh is built from the S3 heightmap; instanced conifer clusters are placed from the S3 tree-area masks; lift towers and chair lines, groomed-run ribbons, snow fences, and a start gate are placed on the terrain.
  4. The player drives. The camera follows with slight spring lag, and the skier leaves a persistent carve trail that fades over ~12s.
  5. In-scene motion runs: lift chairs travel their real line with subtle sway, tree instances sway on a wind field, and the day-cycle sky shifts the sun position and snow specular.
  6. The bottom-left HUD capsule shows the resort name in Fredoka and the altitude and selected run in tabular numerals, with a mint S3-asset legend chip. The top-right control cluster holds camera mode, run selector, and back to resorts. Both are inset 16px and never overlap the canvas centre. At 375px the HUD collapses to a single pill.
  7. The player may open the collapsible right rail to read the S3 asset manifest (heightmap, tree masks, texture sets) as a legend with mint colour swatches.
  8. If the selected resort's S3 data fails to load or the scene cannot be constructed, the scene area shows an explicit error state with a retry affordance and a return-to-resort-selection action. Retrying re-attempts S3 data retrieval and scene construction for the same resort.
Page 11 of 20

Flow 3 — Change camera mode or run

  1. While driving in the Resort Scene, the Ski Resort Player activates a control in the top-right cluster.
  2. The camera mode or the selected run changes, and the bottom-left HUD capsule reflects the new selected run.
  3. If a run selection cannot be applied, the previous selection remains and the HUD is unchanged.
  4. The player continues driving.

Flow 4 — Return to resort selection and pick another mountain

  1. While in the Resort Scene, the Ski Resort Player activates "back to resorts" in the top-right control cluster.
  2. The player returns to Resort Select, with the previously selected resort still indicated.
  3. If the return transition fails, the player remains in the Resort Scene with the control still available.
  4. The player selects a different resort tile, which enters the selected state and loads that resort's S3 data, and the player enters the Resort Scene for the new mountain.

Flow 5 — Reduced-motion play

  1. The Ski Resort Player has prefers-reduced-motion set and navigates to www.globalskiatlas.com/playable/.
  2. The Landing diorama holds a single static hero frame; particles and sway stop; the headline and CTA remain fully readable.
  3. The player activates the CTA; the camera push-in becomes a crossfade into Resort Select.
  4. The tile grid shows static thumbnails instead of auto-rotating ones. Any moving or scrollable content stops and shows whole items, wrapping into rows or sitting in a horizontally scrollable row.
  5. The player selects a resort and enters the Resort Scene, where decorative motion is stopped and the scene holds a stable composed frame. The player can still drive, change camera mode and run, read the HUD and manifest, and return to resort selection.
Page 12 of 20

6. Visuals Colors and Theme

Muse and headline. Bruno Simon — playable alpine worlds: toy-box 3D you drive, not a page you read. The explicit brief is "richer and more vibrant", so the visual language is saturated, high-contrast, and alive rather than photoreal-muted.

Color tokens (light mode).

RoleHex
Background#EAF4FB
Surface#FFFFFF
Text#17233A
Primary#FF5A4E
Accent#2ED3B7
Muted#6B7C93

The pastel sky ground #EAF4FB lets the 3D scene float like a diorama on paper. Pure white cards carry 3px ink outlines and offset soft shadows. Primary coral #FF5A4E is the resort-pick and CTA colour — the "ski lift" colour, used on buttons, selected resort tiles, and the start-run gate. Accent mint #2ED3B7 is the data/secondary voice: S3 asset badges, tree-area legend, telemetry chips. Deep navy ink #17233A is all type and all outlines — never pure black, never grey. Muted slate #6B7C93 is for metadata and secondary labels.

In-scene palette.

ElementHex
Snow#F4FAFF
Snow shadow#D9E8F5
Low-poly conifers#1F6B4A → #2E9E63
Rock#7C6A5B
Lift towers#FF5A4E
Groomed runs#FFF3C4
Sky dome gradient#8FD3F4 → #EAF4FB

No blue-on-white SaaS accent, no indigo, no glassmorphism.

Typography. Headings use Fredoka at 600–700 weight, tight tracking (-0.01em), sentence case, at huge sizes for resort names and section openers; numerals are tabular so vertical drop, altitude, and run counts align in the data strip. Body and UI use Nunito 400/700 at 17px base with 1.6 line-height — rounded terminals keep the toy-box warmth without becoming childish.

Type scale. 1.333 modular: 96 / 72 / 54 / 40 / 28 / 21 / 17 / 14. Display: clamp(56px, 9vw, 128px) for the landing headline; resort names clamp(40px, 6vw, 88px); section openers 40px; body 17px; labels 14px uppercase with 0.08em tracking.

Shape language. Fat rounded capsules (radius 22–999px) for every button, chip, and tile. Cards use a 24px radius with a 3px navy outline plus a hard 6px offset shadow in the same navy (no blur), so panels look like pressed plastic toys. Selected states use a full coral fill with the outline going navy-on-coral; unselected tiles are white with the outline only. Diagonal 45° snow-scatter dots serve as section dividers. In-scene geometry is deliberately low-poly: faceted conifers, chunky lift towers, flat-shaded rock — silhouettes readable at 375px, not photoreal.

Layout. Three surfaces share one system. Landing: a full-bleed live Three.js diorama of a generic resort occupying the right 60% at desktop and the top 52vh at mobile, with the headline and resort entry stacked flush-left over the empty left column — never centred. Resort Select: a 3-up tile grid (1-up at 375px, 2-up at 768px) of resorts, each tile carrying a tiny auto-rotating low-poly thumbnail rendered from that resort's real S3 heightmap. Resort Scene: canvas fills the viewport edge-to-edge; all readable chrome lives in a bottom-left HUD capsule (resort name, altitude, selected run) and a top-right control cluster (camera mode, run selector, back to resorts), both inset 16px and never overlapping the canvas centre. A collapsible right rail shows the S3 asset manifest (heightmap, tree masks, texture sets) as a legend with mint colour swatches.

Imagery. Imagery IS the game: low-poly Three.js geometry built from real S3 data — heightmap terrain meshes, instanced conifer clusters driven by tree-area masks, lift towers and chair lines, groomed-run ribbons, snow fences, a start gate. No stock photography anywhere. Supporting 2D art is flat vector in the same toy language: a pictogram set for run difficulty (green circle, blue square, black diamond, double-black), a small illustrated skier mascot used as the loading state, and isometric mini-diagrams of what each S3 asset contributes to the scene.

Page 13 of 20

7. Signature Design Concept

The mountain as a physical object on paper.

The public entry is not a marketing hero with a screenshot. The first screen is a live, running Three.js diorama of a generic alpine resort — a floating terrain tile with faceted conifers, two lift towers with a moving chair, groomed run ribbons, and drifting snow — rendered on a pastel sky (#EAF4FB) ground so the world reads as a physical object sitting on paper. It bleeds off the right and bottom edges of the viewport at desktop and is cropped to the top 52vh at mobile.

Over the empty left column, flush-left and bottom-aligned: the wordmark, then "PICK A MOUNTAIN. DRIVE IT." set in Fredoka at clamp(56px, 9vw, 128px) in navy #17233A, stacked over three lines with tight leading, with the coral #FF5A4E capsule CTA "CHOOSE YOUR RESORT →" pinned directly beneath it and a mint #2ED3B7 chip reading "LIVE THREE.JS · S3 TERRAIN DATA".

The diorama's camera orbits slowly; the headline does not move. No gradient blob, no centred stack, no blue button.

The signature moves that carry the concept through the rest of the game:

  • The resort picker renders each resort's actual S3 heightmap as a small auto-rotating low-poly thumbnail inside its tile, so choosing a mountain is already playing it; tiles are 3-up/2-up/1-up and the selected state is a full coral fill.
  • A persistent bottom-left HUD capsule — resort name in Fredoka, altitude and selected run in tabular numerals, a mint S3-asset legend chip — that never covers the canvas centre and collapses to a single pill at 375px.
  • "CHOOSE YOUR RESORT" is a coral capsule with a hard 6px navy offset shadow and no blur; on press it depresses 6px into its own shadow, then a coral wipe transitions into the 900ms camera push-in to the start gate.
  • An in-scene carve trail: the skier leaves a persistent groomed ribbon that fades over ~12s, and lift chairs travel their real line with a subtle sway — motion that proves the terrain is live data, not a texture.
Page 14 of 20

8. Interaction Model & Motion Direction

Interaction Model: Animated Motion Tempo: cinematic Hero Dimensionality: webgl

Page 15 of 20

Landing Hero Motion Brief

Focal subject. A live, running Three.js diorama of a generic alpine resort: a floating terrain tile with faceted conifers, two lift towers with a moving chair, groomed run ribbons, and drifting snow, rendered on a pastel sky ground.

Input → transformation → outcome thesis. The page loads → the Three.js diorama initialises and begins its slow 20s orbiting camera with drifting snow particles → the player sees a real, running resort world before clicking anything, and the coral CTA invites them to pick their own mountain.

Motion vocabulary. Cinematic playable motion: a slow 20s orbiting camera on the landing diorama; drifting snow particles; a 900ms camera push-in from orbit to the player's start gate with a coral wipe on entering a resort; physics-driven camera follow with slight spring lag in-scene; persistent carve trails that fade over ~12s; lift chairs travelling their real line with subtle sway; tree instances swaying on a wind field; a day-cycle sky shifting sun position and snow specular. UI motion is snappy and bouncy (cubic-bezier(.34,1.56,.64,1), 180–320ms) — chips pop, HUD capsules slide in from the edge.

Composed first frame. The diorama occupies the right 60% at desktop (top 52vh at mobile), bleeding off the right and bottom edges. The wordmark and "PICK A MOUNTAIN. DRIVE IT." sit flush-left and bottom-aligned over the empty left column, with the coral capsule CTA pinned beneath and the mint chip beside it. The camera is mid-orbit; snow is drifting; the chair is mid-travel.

Reduced-motion state. The diorama holds a single static hero frame, particles and sway stop, the camera push-in becomes a crossfade, and the tile grid shows static thumbnails. Moving and scrollable content stops and shows whole items, wrapping into rows or sitting in a horizontally scrollable row.

Page 16 of 20

Landing Hero 3D Scene Brief — DIRECTION-DERIVED

A single crafted real-time scene: a floating low-poly alpine terrain tile built from a generic heightmap, with faceted conifers (#1F6B4A→#2E9E63), two chunky lift towers (#FF5A4E) with a chair travelling its line, groomed run ribbons (#FFF3C4), flat-shaded rock (#7C6A5B), snow (#F4FAFF) with #D9E8F5 shadow, and a sky dome gradient (#8FD3F4→#EAF4FB). The scene shows the product's defining state: a real resort world running live in the browser, built from terrain data, before the player has clicked anything. The camera orbits slowly on a 20s loop; snow drifts; the chair moves. Under prefers-reduced-motion, the scene holds one composed frame.

Page 17 of 20

9. Non-Functional Requirements

NFR-1 — Delivery path. The game is delivered at the path www.globalskiatlas.com/playable/. Provenance: explicit hard constraint. Rationale: the user specified the exact delivery path.

NFR-2 — S3 data sourcing. Resort data — heightmap, tree areas, and other terrain data — is sourced from S3. Provenance: explicit hard constraint. Rationale: the user specified S3 as the data source; the system reads this data and does not author or publish it.

NFR-3 — Three.js rendering. The resort scene is constructed and rendered with Three.js, which consumes the S3 data and places 3D game assets onto the terrain. Provenance: explicit. Rationale: the user specified Three.js as the rendering technology.

NFR-4 — Anonymous access. All three surfaces are anonymously accessible; no account, login, or identity system is required. Provenance: explicit (all surfaces carry access_requirement: none). Rationale: the game is a public playable experience.

NFR-5 — Readable text and controls at every viewport. Headlines, wordmarks, labels, numbers, cards' text, and controls stay entirely inside the viewport and their container at 375px, 768px, and 1280px, wrapping or scaling (for example font-size: clamp(...) with its mobile size) to fit, and no other element covers any part of them. Imagery, decoration, and motion may be cropped, bled off an edge, rotated, overlapped, or cut as the direction asks, as long as it covers no readable text or control. Provenance: explicit (accepted creative direction). Rationale: the direction's bleed and crop gestures must not compromise legibility.

NFR-6 — Reduced-motion support. Under prefers-reduced-motion, decorative motion stops: the diorama holds a single composed frame, particles and sway stop, the camera push-in becomes a crossfade, and the tile grid shows static thumbnails. Moving and scrollable content stops and shows whole items, wrapping into rows or sitting in a horizontally scrollable row. Provenance: explicit (accepted creative direction). Rationale: accessibility without losing the composed visual.

NFR-7 — No photoreal or muted fallback. The visual language is saturated, high-contrast, and toy-like; photoreal textures, PBR snow with heavy normal maps, and muted desaturated alpine photography are excluded. Provenance: explicit (accepted creative direction). Rationale: the brief asks for richer and more vibrant.

NFR-8 — No glassmorphism or gradient blobs. Glassmorphism, backdrop blur, frosted panels, and gradient blobs are excluded; the world is opaque toy plastic. Provenance: explicit (accepted creative direction). Rationale: the direction's shape language requires opaque surfaces with hard outlines and offset shadows.

NFR-9 — No neutral grotesque typefaces. Inter, Roboto, Poppins, Arial, system-ui, and any neutral grotesque are excluded for headings and body. Provenance: explicit (accepted creative direction). Rationale: Fredoka and Nunito carry the toy-box warmth.

NFR-10 — No blue/indigo primary buttons on white. The only CTA colour is coral #FF5A4E. Provenance: explicit (accepted creative direction). Rationale: the generic indigo/blue-on-white SaaS template is forbidden for this project.

NFR-11 — HUD never covers the canvas centre. Readable HUD text and controls are never placed over the canvas centre, and no label is cropped at 375/768/1280px. Provenance: explicit (accepted creative direction). Rationale: the scene must remain fully visible while the chrome stays readable.

Page 18 of 20

10. Tech Stack

  • Three.js — the rendering technology that constructs and renders the selected resort scene, consumes S3 resort data, and places 3D game assets onto the terrain. Source-specified.
  • S3 — the external data provider for resort data (heightmap, tree areas, and other terrain data). Source-specified.
  • Web front end — the game is delivered in the browser at www.globalskiatlas.com/playable/. [Default — not specified by user] React is used for the surrounding UI surfaces (Landing, Resort Select, Resort Scene chrome), with the Three.js scene mounted inside the Resort Scene surface.
  • Styling — [Default — not specified by user] CSS with the token set defined in Section 6; no CSS framework is required by the source.
  • Backend — [Default — not specified by user] No first-party backend is required by the source; resort data is read directly from S3. If a signing or proxy layer becomes necessary for S3 access, [Default — not specified by user] Python/FastAPI is the default choice.
  • Deployment — [Default — not specified by user] Static hosting for the playable path; Docker/docker-compose and Kubernetes are not required by the source.
Page 19 of 20

11. Assumptions and Constraints

Assumptions.

  • A1 — The set of available ski resorts is defined by the resort data present in S3; the system does not author or curate that set. [Default — not specified by user]
  • A2 — Each resort's S3 data includes at least a heightmap and tree-area masks, and may include other terrain data such as texture sets. [Default — not specified by user]
  • A3 — The player's browser supports WebGL, which is required for the Three.js scene. [Default — not specified by user]
  • A4 — The Landing diorama uses a generic resort rather than a specific resort's data, so the entry surface does not depend on a particular S3 dataset. [Default — not specified by user]

Constraints.

  • C1 — The game is delivered at www.globalskiatlas.com/playable/. Explicit.
  • C2 — Resort data (heightmap, tree areas, etc.) is sourced from S3. Explicit.
  • C3 — Three.js assets consume the S3 resort data and place 3D game assets onto the terrain. Explicit.
  • C4 — The player picks the ski resort as the entry step into the game. Explicit.
  • C5 — The game must be richer and more vibrant. Explicit.
  • C6 — All three surfaces are anonymously accessible; no account is required. Explicit.
  • C7 — The generic indigo/blue-on-white SaaS template is forbidden for this project. Explicit.
  • C8 — No static screenshot or marketing photograph stands in for the 3D scene on the landing hero. Explicit.
  • C9 — Readable text and controls stay whole at 375px, 768px, and 1280px. Explicit.

Out of current scope. Resort authoring, editing, or upload; accounts, login, or identity; social, sharing, leaderboard, or multiplayer features; progression or game modes beyond driving the selected resort; photoreal texture pipelines.

Page 20 of 20

12. Glossary

  • Playable path — www.globalskiatlas.com/playable/, the delivery location of the game.
  • Resort — A ski resort whose data (heightmap, tree areas, and other terrain data) is available in S3 and which the player can pick.
  • Heightmap — S3-hosted terrain elevation data used to build the resort's terrain mesh.
  • Tree-area mask — S3-hosted data that drives the placement of instanced conifer clusters on the terrain.
  • S3 asset manifest — The list of S3 assets that built the current scene (heightmap, tree masks, texture sets), shown as a collapsible right-rail legend with mint colour swatches.
  • Resort Scene — The surface that renders the selected resort as a live Three.js 3D scene.
  • Resort Select — The surface where the player picks a resort.
  • Landing — The anonymous public entry surface presenting the playable game.
  • Diorama — The live Three.js scene of a generic alpine resort on the Landing surface, rendered as a floating terrain tile on a pastel sky ground.
  • Carve trail — The persistent groomed ribbon the skier leaves in the Resort Scene, fading over ~12s.
  • HUD capsule — The bottom-left chrome in the Resort Scene showing resort name, altitude, and selected run.
  • Ski Resort Player — The single accepted active human actor of the game.

No completed page designs yet.

Completed design pages will appear here when they are ready to preview.

Landing: Arrive at playable game
Landing: 1. Watch live diorama render
Landing: 2. Retry diorama initialisation
Landing: 3. Choose your resort
Resort Select: 4. Browse resort tiles
Resort Select: Preview heightmap thumbnails
Resort Select: Retry failed tile data
Resort Select: Retry empty resort list
Resort Select: 5. Return to landing
Resort Select: Select a resort
Resort Scene: 1. Watch scene construct
Resort Scene: 2. Retry failed scene load
Resort Scene: 3. Drive the resort
Resort Scene: 4. Change camera mode
Resort Scene: 5. Change selected run
Resort Scene: 6. Read resort HUD
Resort Scene: 7. Read S3 asset manifest
Resort Scene: 8. Back to resorts
Resort Select: 9. Select a different resort

No completed page designs yet.

Completed design pages will appear here when they are ready to preview.

Landing: Arrive at playable game
Landing: 1. Watch live diorama render
Landing: 2. Retry diorama initialisation
Landing: 3. Choose your resort
Resort Select: 4. Browse resort tiles
Resort Select: Preview heightmap thumbnails
Resort Select: Retry failed tile data
Resort Select: Retry empty resort list
Resort Select: 5. Return to landing
Resort Select: Select a resort
Resort Scene: 1. Watch scene construct
Resort Scene: 2. Retry failed scene load
Resort Scene: 3. Drive the resort
Resort Scene: 4. Change camera mode
Resort Scene: 5. Change selected run
Resort Scene: 6. Read resort HUD
Resort Scene: 7. Read S3 asset manifest
Resort Scene: 8. Back to resorts
Resort Select: 9. Select a different resort