# NASA/JPL Eyes on the Solar System — Web App Design Spec

> Source: eyes.nasa.gov/apps/solar-system/ (live DOM, computed styles), 2026-08-03; desktop 1512px.
> Coverage: the standalone real-time 3D app (Home view + Featured-Stories rail + time-control scrubber + instrument rail). Published `--*` token set read from `:root`; hover/focus from stylesheet rules. sheetsBlocked 0.
> Reality check: hint ("space data-viz — dark cosmic, mission-control instrumentation") is ACCURATE for this surface — but note the root domain `eyes.nasa.gov` now redirects to `science.nasa.gov/eyes/`, a generic WordPress/USWDS portal that is NOT distinctive; the design language lives in the standalone `/apps/solar-system/` Three.js app captured here.

## 1. Visual Theme & Atmosphere

A mission-control instrument panel floating over deep space. The entire surface is a pure-black WebGL void (a live Three.js scene of orbits, planets and spacecraft) with thin HUD chrome laid on top: a story-card rail on the left, a time scrubber pinned to the bottom, and a vertical instrument-icon rail on the right. Colour is functional and rationed — a green "live" pulse, an amber spacecraft/paused accent, a CTA blue — while the real chromatic richness is a *published per-celestial-body palette* (each planet, the sun, comets and constellations carry their own token trio). Type stays quiet: geometric Metropolis at a light 300 for titles and a small wide-tracked uppercase 600 for the wordmark and scene labels. Nothing is decorative; every pixel reads as an instrument. Feels: cosmic, precise, instrumented, cinematic.

## 2. Color Palette & Roles

### Text
| Token | Hex | Role / usage |
|---|---|---|
| white | `#ffffff` | Primary text, active labels, planet labels |
| grayLight | `#eaeaeb` | Menu items, bright secondary labels |
| grayMed | `#c6c6c9` | Secondary text, the uppercase wordmark, button text |
| gray | `#95959d` | Tertiary / muted labels, inactive controls |

### Surfaces
| Token | Hex | Role / usage |
|---|---|---|
| black | `#000000` | Canvas — the space void |
| grayDark | `#252527` | HUD panels, story cards, menu sheets |
| grayblueBackground | `#151a1d` | Deep panel / settings background |
| grayDarkAlpha80 | `#252527cc` | Translucent panel fills over the scene |

### Borders / dividers
| Token | Hex | Role / usage |
|---|---|---|
| grayDivider | `#37373a` | Hairline dividers between cards/rows |
| tab-border-gray | `#606060` | Control / tab borders (also `#636363`) |
| grayblueButton | `#425571` | Slate control fill / button border |

### Accent & semantic
| Token | Hex | Role / usage |
|---|---|---|
| cta-blue | `#3e63dd` | Primary CTA fill |
| nasa-blue | `#288bff` | Brand blue, links |
| settings | `#0d67ff` | Settings / active-control accent |
| live | `#47da84` | "LIVE" + "REAL RATE" indicator, scrubber handle (green) |
| spacecraft | `#cd9745` | Spacecraft labels + story-card dates (amber) |
| paused | `#ff9a42` | Paused-clock state (orange) |
| error | `#d55033` | Errors / warnings |

### Celestial data palette (signature — one token trio per body)
| Token | Hex | Token | Hex |
|---|---|---|---|
| sun | `#f7f4df` | jupiter | `#da8b72` |
| mercury | `#9768ac` | saturn | `#d5c187` |
| venus | `#b07919` | uranus | `#68ccda` |
| earth | `#0099cc` | neptune | `#708ce3` |
| mars | `#9a4e19` | constellation | `#59b2ff` |
| moon | `#b6acac` | comet | `#7e86b0` |
| dwarfPlanet | `#929871` | asteroid | `#806262` |

Rule: chrome colour is rationed to green (live), amber (spacecraft/paused) and blue (CTA/links); all other saturated colour belongs to a specific celestial body, never to UI furniture.

## 3. Typography Rules

- Families: **Metropolis** (geometric sans, the display + wordmark face, 481 uses) + **Inter** (UI/buttons, 106) + a rare `monospace`.
- Body base: 16px. Specimen swap: **Montserrat** stands in for licensed Metropolis; Inter is the real face.

| Role | Family | Size/Line | Weight | Tracking | Case |
|---|---|---|---|---|---|
| Wordmark (h1) | Metropolis | 16 / 19.2 | 600 | +0.64px | UPPERCASE, `#c6c6c9` |
| Story title (h2) | Metropolis | 29 / 27.55 | 300 | -0.58px | none, `#ffffff` |
| Overlay heading (h3) | Metropolis | 28.8 / 27.36 | 300 | -0.576px | none |
| Menu item | Metropolis | 17.6 / — | 500 | +0.352px | none, `#eaeaeb` |
| Card date / label | Metropolis | 14 / — | 600 | +0.28px | UPPERCASE, `#cd9745` |
| Scene label (planets) | Metropolis | ~13–14 | 600 | wide | UPPERCASE, `#ffffff` |
| Button / UI | Inter | 16 / 24 | 500 | +0.32px | none, `#c6c6c9` |

Patterns: big titles are LIGHT (weight 300) with tight negative tracking; small labels are heavier (600) UPPERCASE with positive tracking. Weight never sits at a middle 400 for display.

## 4. Component Stylings

### Buttons
- **Ghost/HUD (default)**: transparent bg, text `#c6c6c9`/`#eaeaeb`, radius 6px, h 40px, Inter 16/500 (+0.32px), no border, no shadow. Hover: amber tint bg `rgba(252,181,0,.06)` + text brightens to `#ffcb47`.
- **Primary CTA**: fill `#3e63dd` (cta-blue), white text, 6px radius (used on overlays/embeds).
- **Icon controls (instrument rail)**: 40px square hit targets, transparent; hover `transform: scale(1.1)` + `filter: brightness(1.4)`, or a `#646464` fill on segmented controls.

| Component | Rest | Hover | Focus | Active | Disabled |
|---|---|---|---|---|---|
| HUD button | transparent, `#c6c6c9` | bg `rgba(252,181,0,.06)`, text `#ffcb47` | outline `0px` (suppressed — see §9) | brightness(1.1) | opacity lowered |
| Icon control | transparent | `scale(1.1)` + brightness(1.4) | outline `0px` | — | — |

### Inputs
- Search field: dark translucent fill over the scene, 1px `#37373a` border, ~6px radius, placeholder `#95959d`. (No explicit focus ring captured — see §9.)

### Cards (story rail)
- bg `#252527` (grayDark), 1px `#37373a` divider between cards, ~3px radius, padding ~16px; title (light Metropolis 29px) over an UPPERCASE amber `#cd9745` date line, spacecraft thumbnail right-aligned.

### Time scrubber (signature)
- Full-width bottom bar: green `#47da84` "LIVE" dot + "REAL RATE" label, date/time flanking a horizontal track, a glowing green circular handle (radial glow) at centre. Handle sits on a hairline `#37373a` rail.

### Instrument rail (right)
- Vertical stack of 40px icon buttons: info, layers, zoom +/−, contrast, fullscreen, settings — grouped with hairline separators.

## 5. Layout Principles

- Full-viewport WebGL canvas is the "page"; all UI is absolutely-positioned HUD over it.
- Left rail: ~365px story-card column, collapsible (a `«` toggle).
- Top bar: NASA meatball + wordmark left; search / Share / Menu right (h ~75px, `--gridHeaderHeight:75px`).
- Bottom: centred time-control bar spanning the scene.
- Right: vertical instrument-icon rail.
- Spacing is compact HUD density; panels are translucent `#252527` sheets with hairline `#37373a` dividers.

## 6. Depth & Elevation

- Radii: dominant **3px**, then 4.8px, 6px (buttons), 8px, 10px, 14px; circular handles/avatars full.
- Elevation is a glow, not a drop: `box-shadow: rgba(0,0,0,.4) 0 0 12px 4px` around floating panels, plus `backdrop-filter: blur(8px)` (also 4/3.2/1.6px) on translucent sheets over the scene.
- Borders do most structural work: 1px `#37373a` dividers, 1px `#252527`, 1px `#636363`, 1.5px `#c6d4f9` (highlighted).

## 7. Motion

| Property | Duration | Easing | Applies to |
|---|---|---|---|
| opacity | 0.1s | ease-in-out | HUD fades (dominant, 38×) |
| opacity, transform | 0.75s | ease / ease-in-out | panel + card entrances |
| opacity | 0.2s–0.25s | ease-out | tooltips, labels |
| background-color | 0.3s | ease | button/hover fills |

- House transition: fast `opacity 0.1s ease-in-out`; a published `--ease-out-bezier: cubic-bezier(0.2,0.2,0,1)` and a springy `cubic-bezier(0.54,1.5,0.38,1.11)` for pop-in.
- Keyframes by name: `load`, `loading-bar`, `fadeInDelayed`, `interactanimation`, `animated-cursor`, `text-pulse`, `pulse`, `flash`, `blink`, `tap-hint`, `gradient` / `mobile-gradient`, `fade-in/out` (+ `-left`/`-bottom`), `spin`.
- No animation library detected in JS globals (custom engine); the 3D itself is **Three.js** (`window.THREE` present). **No `prefers-reduced-motion` block (reducedMotionBlocks: 0)** despite the live scene + pulse loops — an anti-pattern.

## 8. Backgrounds, Effects & WebGL

- One full-viewport **WebGL canvas (Three.js)** rendering the real-time solar system: orbit ellipses, per-body colour, star field, 98 raster texture layers (planet/spacecraft imagery).
- HUD atmosphere: dark vertical gradients (`linear-gradient(#252527 0.7%, #000)` menu, `linear-gradient(#272527, rgba(37,37,39,.8) 52%, rgba(37,37,39,0))` panels) + text scrims (`linear-gradient(0deg,#000000cc,#00000000)`).
- `backdrop-filter` blur (8/4/3.2/1.6px) on translucent panels. No grain, no background `<video>`.

## 9. Do's and Don'ts

### Do
- Keep the canvas pure black `#000000`; float translucent `#252527` HUD panels with hairline `#37373a` dividers over a live scene.
- Ration chrome colour: green `#47da84` for live/real-time, amber `#cd9745` for spacecraft/paused, blue `#3e63dd`/`#288bff` for CTA/links.
- Reserve every other saturated colour for a specific celestial body via its published token (`--mars`, `--earth`, `--saturn`…).
- Set big titles in LIGHT Metropolis (300) with tight negative tracking; small labels in 600 UPPERCASE with positive tracking.
- Use glow (`0 0 12px 4px rgba(0,0,0,.4)`) + backdrop-blur for depth, not opaque drop shadows.
- Keep HUD transitions fast (opacity 0.1s ease-in-out).

### Don't
- Don't put celestial colours on UI furniture, or invent a second CTA colour.
- Don't set display titles bold — the display weight is 300, not 700.
- Don't switch the canvas to a light surface; this is dark-only (darkSchemeBlocks 0).
- Don't suppress focus rings (the app does — `outline:0` on carousel nav; add a visible ring instead).
- Don't ship the animated scene without a `prefers-reduced-motion` fallback (the app omits one).

## 10. Responsive Behavior

- Dense device breakpoint ladder: 320, 481, 640, 641, 660, 767, 768, 915, 960, 961, 1024, 1025, 1300 (px). The many paired min/max seams mark a hand-tuned HUD that reflows the rail/scrubber per size.
- Mobile swaps to a `--mobileBgGradient` and a bottom-sheet layout; story rail collapses.
- Single dark theme — no light mode, no theme toggle (`darkSchemeBlocks: 0`, `hasDarkToggle: false`). No container queries.

## 11. Agent Prompt Guide

Quick token reference:

- Canvas `#000000` · Text `#ffffff` / muted `#95959d` · Panel `#252527` · Divider `#37373a` · Accent green `#47da84` / amber `#cd9745` / CTA `#3e63dd`
- Font: Metropolis (display, 300 titles / 600 uppercase labels) + Inter (UI 16/500) · Body 16px · Radius 3px/6px · Control h 40px
- Focus: none captured (app suppresses — recommend a visible ring) · Hover fill: `rgba(252,181,0,.06)` + text `#ffcb47`

<nasa-eyes-marketing_design_language>
Use the NASA Eyes design language: a mission-control HUD floating over a pure-black `#000000` live 3D space scene (Three.js). Text white `#ffffff`, secondary `#c6c6c9`, muted `#95959d`; translucent panels `#252527` with 1px `#37373a` hairline dividers and glow depth (`0 0 12px 4px rgba(0,0,0,.4)` + backdrop-blur 8px), not drop shadows. Ration chrome colour to a green live pulse `#47da84`, an amber spacecraft/paused accent `#cd9745`, and a CTA blue `#3e63dd`/`#288bff`; reserve all other saturated colour for specific celestial bodies via published tokens (`--mars #9a4e19`, `--earth #0099cc`, `--saturn #d5c187`, `--sun #f7f4df`…). Type is geometric Metropolis — LIGHT weight 300 with tight negative tracking (-0.58px) for titles, small 600 UPPERCASE with positive tracking (+0.64px) for the wordmark and scene labels — over Inter for UI (16/500, +0.32px). Controls are 40px ghost buttons at 3–6px radius; a bottom time-scrubber and a right instrument-icon rail. Fast HUD motion (opacity 0.1s ease-in-out), `cubic-bezier(0.2,0.2,0,1)`. Feels: cosmic, precise, instrumented. Avoid: putting planet colours on UI, bold display type, a light theme, and shipping the scene with no reduced-motion fallback.
</nasa-eyes-marketing_design_language>
