manual.sys — interface reference

Starwind

Interface Style Guide · v0.0.21 · style_guide() in the dev console

CRT-terminal aesthetic for a browser React/TypeScript space-trading game. Every CSS variable, shared class, animation, and layout rule lives in src/styles/global.css; one component .css file accompanies each .tsx. The whole interface is presented as a shipboard operating system — windows, chrome bars, and status readouts on the ship's console.

01 · Color Palette

Backgrounds

--void#0a0d14 · Page / fullscreen bg
--deep#0f1420 · Panel / card bg
--hull#1a2035 · Card bg, hover, chrome
--panel#1e2a3a · Borders, dividers
--grid#2a3a4a · Grid lines

Decoration — borders, fills, dots (never text)

--cyan#4dd9b8 · Primary UI, routes
--amber#e6a817 · Warnings, imports
--blue#4da6e8 · Fuel / nav
--alert#e85a6a · Danger, engine
--cargo#6bbf5a · Cargo / profit

Text — AA-compliant on --deep

--text-primary#e8eef7 · 16:1 · headings
--text-secondary#b8c5d6 · 9:1 · body copy
--text-muted#8ea0b8 · 5.2:1 · labels
--text-disabled#5a6b82 · 3.2:1 · large only

Never apply CSS opacity to text — use --text-muted / --text-disabled instead.

Text accents — brighter, interactive

--accent-cyan#5eead4 · hover / active
--accent-amber#fbbf24 · credits
--accent-blue#60a5fa · nav hints
--positive#86efac · profit / buy
--negative#f87171 · loss / danger

Station type & specialty

--mining-color#c07af0 · mining outposts
--agriculture-color#6bbf5a · agri colonies
--technology-color#4da6e8 · tech hubs
--purple#9370db · shields, gunship

02 · Typography

Three families, loaded via <link> in index.html.

--font-display · Orbitron · titles, headings, chrome labels, tabs STARWIND SECTOR COMMAND
--font-body · Inter · body copy, labels, buttons, descriptions Docking clamps engaged. Market and outfitting systems online.
--font-mono · JetBrains Mono · numbers, credits, fuel, code, hints ¢ 12,480 CR · FUEL 78% · DAY 123

Type scale

TokenSizeLHWeightUsed for
--fs-display28px1.15700Title screen, game over, arrival modal
--fs-h120px1.25700Event names, good-info name
--fs-h216px1.3700Info-card names, comms titles, panel headers
--fs-h314px1.35600Taglines, schematic names
--fs-body14px1.55400Body text, menu buttons, descriptions
--fs-small13px1.5400Secondary text, mission descriptions
--fs-micro12px1.4500Chrome labels, metadata, button labels
--fs-num14px1.2700Credits, fuel, distances
--fs-num-sm13px1.2500Costs, quantities, rep values

Each token has matching --fs-*, --lh-*, --fw-* vars. Compose with font: var(--fw-x) var(--fs-x)/var(--lh-x) var(--font-x).

03 · Layout System

Viewport & root

ElementRule
bodyheight: 100vh; display: flex; center; overflow: hidden; background: #000
#rootmin(1680px…) × min(1050px…) — 16:10 canvas, letterboxed, border-radius: 8px, background: var(--void)
.app-shellflex: 1; display: flex; flex-direction: column; min-height: 0

Borders & radius

ContextValue
Panel borders0.5px solid var(--panel) — never 1px
Accent left borderborder-left: 3px solid var(--accent-cyan) (selected/active)
Panel radiusvar(--radius) = 8px
Card / button radius4px
Pip / badge radius2–3px
Window compositionTitle bar (.chrome-bar) + body + optional .status-bar — see §05

Scanlines (CRT)

One global <div class="scanlines"> in App.tsx, pointer-events: none; z-index: 9999, always on.

background: repeating-linear-gradient(
  to bottom,
  transparent 0px, transparent 3px,
  rgba(0,0,0,0.15) 3px, rgba(0,0,0,0.15) 4px
);

Panel flex pattern

.panel-root {
  flex: 1;            /* fill available space */
  display: flex;
  flex-direction: column;
  min-height: 0;      /* allow scrolling children */
  overflow: hidden;   /* or overflow-y: auto when scrollable */
}

04 · Icons & Glyphs

Starwind uses no icon font or SVG sprite — every icon is a Unicode glyph rendered in a colored <span>. Module/system icons live as components in src/components/icons/; planet icons come from getPlanetIcon() in engine/travel.ts; the rest are inline in component JSX.

Module & system icons src/components/icons/

CargoIconU+25A3 · cargo hold
FuelIconU+25AE · fuel tank
EngineIconU+25B6 · engine
CrewIconU+2609 · crew quarters
ScannerIconU+25CE · scanner
ShieldIconU+25CA · shielding
RepairIconU+271A · auto-repair
¢
CreditsIconU+00A2 · credits (700)

Default size 16px via size prop. ScannerIcon uses --cyan; ShieldIcon & RepairIcon render in currentColor (purple / cargo in context). The schematic maps these via ICON_MAP keyed on module type.

Planet-type icons getPlanetIcon()

terrestrialU+25CF
orbitalU+25CB
deep_spaceU+2606
ice_worldU+25C7
rogue_worldU+25C6
barrenU+25CC
asteroidU+25C8
asteroid_beltU+25EB
gas_giant_orbitU+25CE
debris_fieldU+25C9
dead_star_orbitU+2B24
(fallback)U+25A0

Tinted at render with getPlanetColor() (mining = purple, agriculture = green, technology = blue).

Bars, status & checkboxes

bar segmentU+2590 · fuel/hull/progress/stock
objective doneU+25A0 · filled checkbox
objective pendingU+25A1 · empty checkbox

Navigation, arrows & waypoints

section prefixU+25B8 · headings, services
route arrowU+2192 · origin → dest
ship markerU+25B6 · in-transit on route
transit shipU+25C4 · TransitScreen sprite
origin waypointU+25C9 · flight plan
destinationU+2299 · flight plan
roster toggleU+2261 · star-map menu
search hintU+2026 · placeholder

Notifications & trade markers

new missionU+2726 · toast
completeU+2713 · toast
ready to hand inU+25C8 · toast
story / exportU+25C6 · toast, export mkt
·
generic / dot sepU+00B7 · toast, separators
import marketU+25CF · sells at premium
neither marketU+25CB · not interested

Separators & utility

vertical sepU+2502 · TopBar fields
em dashU+2014 · label separator
°
degreeU+00B0 · temperature
×
multiplierU+00D7 · quantities
viewport warningU+26A0 · <1024px banner

05 · Window Chrome OS Windows

Every panel and modal is drawn as a shipboard OS window — the in-fiction STARWIND OS. A window has three parts: a title bar, a body, and an optional status bar footer. Title and status bars sit one shade lighter (var(--hull)) than the body (var(--deep)) so the chrome reads as window furniture. All of it derives from the .chrome-bar family in global.css.

station.sys
CERES OUTPOST — docking clamps engaged. Market, outfitting, and crew systems online. The body fills the window on var(--deep); chrome bars frame it top and bottom.
SECTOR 7 · GRID 14,22 ◇ 12,480 CR · FUEL 78%

Anatomy

PartClassContents
Title bar.chrome-barStatus lamps · window glyph · title · spacer · window controls
Body(panel-specific)Scrollable content on var(--deep)
Status bar.status-barMono readout — context (left), telemetry (right)
Frame.os-window-cornerOptional HUD corner brackets (cyan, 0.5px, 55% opacity)

Title-bar elements

ElementClassSpec
Status lamps.chrome-bar-dots / .chrome-bar-dotThree 7px dots — a system-state readout, not macOS traffic lights. Pattern encodes window state (below).
Window glyph.chrome-bar-glyphLeading mono icon in var(--accent-cyan) — the window class (▣ panel, ☰ log, ⚙ config)
Title.chrome-bar-label--font-display 12px/600, uppercase, 0.08em, var(--text-muted) — the *.sys / *.cfg / *.log name
Spacer.chrome-bar-spacerflex: 1
Window controls.chrome-bar-controls / .chrome-bar-ctrlRight cluster — minimize / maximize / close (below)

Window controls

ControlGlyphHoverBehavior
Minimize U+2013border & glyph → cyanCollapse to chrome — decorative on full-bleed panels
Maximize U+25A2border & glyph → cyanRestore / expand — decorative on root panels
Close U+2715border & glyph → --negativeFunctional on modals (mirrors Esc); muted & inert on root screens

Each control is an 18×16px mono glyph in a 0.5px solid var(--panel) box. Flat, no shadow; only border & text color change on hover, instantly.

Status-lamp variants

PatternMeaningWhere
red · amber · greenNormal operationTitle, TopBar, Station, Ship, Event, Controls, Story, Options
red · amber · redLocked / warningDeniedPanel
all redCritical / breachGameOverPanel

Window glyph & label reference

ScreenGlyphLabel
Title screenstarwind.sys — sector command interface
Options modaloptions.cfg
TopBarstarwind.sys
StationPanelstation.sys
ShipPanelship.sys
DeniedPanelstation.sys — LOCKED
GameOverPanelship.sys — BREACH
EventModalevents.sys
ControlsOverlaycontrols.sys
StoryPanel overlaymissions.log

CSS

/* global.css — window chrome */
.chrome-bar {                /* title bar */
  display: flex; align-items: center; gap: 8px;
  padding: 10px 18px;
  background: var(--hull);   /* chrome shade, lighter than body */
  border-bottom: 0.5px solid var(--panel);
  flex-shrink: 0;
}
.chrome-bar-dots { display: flex; gap: 5px; }
.chrome-bar-dot { width: 7px; height: 7px; border-radius: 50%; flex-shrink: 0; }
.chrome-bar-dot.red   { background: var(--negative); }
.chrome-bar-dot.amber { background: var(--accent-amber); }
.chrome-bar-dot.green { background: var(--positive); }
.chrome-bar-glyph { font-family: var(--font-mono); font-size: var(--fs-micro); color: var(--accent-cyan); }
.chrome-bar-label {
  font-family: var(--font-display); font-size: var(--fs-micro); font-weight: 600;
  color: var(--text-muted); letter-spacing: 0.08em; text-transform: uppercase;
}
.chrome-bar-spacer { flex: 1; }
.chrome-bar-controls { display: flex; gap: 6px; }
.chrome-bar-ctrl {
  font-family: var(--font-mono); font-size: var(--fs-micro); line-height: 1;
  color: var(--text-muted); width: 18px; height: 16px;
  display: flex; align-items: center; justify-content: center;
  border: 0.5px solid var(--panel); border-radius: 3px;
}
.chrome-bar-ctrl:hover       { border-color: var(--cyan);  color: var(--accent-cyan); }
.chrome-bar-ctrl.close:hover { border-color: var(--alert); color: var(--negative); }

.status-bar {                /* footer */
  display: flex; align-items: center; justify-content: space-between;
  padding: 6px 18px; background: var(--hull);
  border-top: 0.5px solid var(--panel);
  font-family: var(--font-mono); font-size: 11px;
  color: var(--text-muted); letter-spacing: 0.04em; flex-shrink: 0;
}

.os-window { position: relative; }   /* HUD corner brackets */
.os-window-corner {
  position: absolute; width: 10px; height: 10px;
  border: 0 solid var(--cyan); opacity: 0.55; pointer-events: none;
}
.os-window-corner.tl { top:5px; left:5px;  border-top-width:.5px;    border-left-width:.5px; }
.os-window-corner.tr { top:5px; right:5px; border-top-width:.5px;    border-right-width:.5px; }
.os-window-corner.bl { bottom:5px; left:5px;  border-bottom-width:.5px; border-left-width:.5px; }
.os-window-corner.br { bottom:5px; right:5px; border-bottom-width:.5px; border-right-width:.5px; }

06 · Buttons

Specialized variants · info · quantity stepper · jump (safe / warn / danger)
? 12 Jump · 4 fuel Jump · 9 fuel Jump · hostile

Base states (global.css)

StateCSS
Defaultbackground: var(--hull); border: 0.5px solid var(--panel); color: var(--text-primary); padding: 8px 16px; border-radius: 4px
Hoverborder-color: var(--cyan); background: var(--panel); color: var(--accent-cyan)
Activebackground: var(--hull)
Disabledcolor: var(--text-disabled); border-color: var(--hull); cursor: not-allowed

Variants

VariantPatternUsed in
PrimaryCyan border, accent-cyan text, cyan-tinted hover bgTitle New Game, arrival Dock
DangerAlert border, negative textDelete save, confirm delete
Compactpadding: 3px 12px; --fs-micro; 600; uppercaseTopBar SAVE, MENU
Dock / actionCyan border, accent-cyan, uppercase micro[M] DOCK, [M] MAP
GhostTransparent bg, panel borderOptions actions, event decline
TabNo bg, transparent bottom border, active = solidStation / Ship / Story tabs
Info22×22px circle, muted → cyan on hoverMarket ? info
Quantitypadding: 3px 8px; --fs-micro; 600, +/− pairsBuy/sell qty
JumpFlex 1, 3 states (safe / warn / danger)Info-card jump
Schematic actionSmall, uppercase, 0.10em trackingStow, sell, dismantle
Fire crewNegative text, alert border, uppercaseCrew panel
Modal closebackground: none; border: none; color: var(--text-muted); 18pxAll modals

07 · Inputs & Selects

Live · text · focused · select

Click a field to see the cyan focus border live.

StateCSS
Defaultbackground: var(--hull); border: 0.5px solid var(--panel); color: var(--text-primary); padding: 6px 10px; border-radius: 4px
Focusoutline: none; border-color: var(--cyan)

Scrollbar

8px wide, --hull track, --panel thumb, 3px radius.

Scrollable region
Stardate 2417.6 — docking clamps engaged at Ceres Outpost.
Cargo manifest verified: 12 units refined ore, 4 units medical supplies.
Reputation with Free Traders increased to Trusted.
New contract available in Comms: supply run to Helix Station.
Fuel reserves at 78%. Hull integrity nominal.
Scanner sweep complete — 3 adjacent systems charted.

08 · Panels & Cards

Panel backgrounds

ContextBackgroundBorderRadius
Fullscreen panelvar(--deep)None (fills #root)
Embedded panelvar(--deep)0.5px solid var(--panel)8px
Module / info cardvar(--hull)0.5px solid var(--panel)4–6px
Cargo rowvar(--void)0.5px solid var(--panel)4px
Modal panelvar(--deep)0.5px solid var(--panel)4px

Layout classes

ClassWhere
.dock-layoutTerminal-framed 2-panel dock (Station + Ship), flex row, 1px margin
.station-panel / .ship-panel20–24px padded, scrollable flex column; ship has border-left
.denied-panel / .gameover-panelFixed fullscreen, centered content, var(--deep)
.starmap-rootFlex 1, relative, overflow hidden, cursor grab
.story-panelFlex column, gap 18px, scrollable
.transit-screenFlex center, void bg + radial grid

Examples

Module card · default + installed
Cargo Hold Mk II
+8 cargo · 220 mass · ¢ 4,200
Pulse ScannerInstalled
+2 scan range · cyan border-left + tint
Market rows · export / import
◆ Refined OreBUY 84 · SELL 61
● Medical SuppliesBUY 210 · SELL 188
Crew row · hireable / locked
Navigator — Vex Aldair
−12% fuel burn · ¢ 90/day
Gunner — [LOCKED]Rep 40
Requires Free Traders rank

Card classes & state variants

ClassSpec / state
.lore-entry / .story-stepvar(--hull), 0.5px border, 6px radius
.comms-mission-rowvar(--deep), 0.5px border, 8px radius
.cargo-rowvar(--void), 0.5px border, 4px radius
.outfit-mod-row / .crew-rowvar(--hull), 0.5px border, 4px radius
.module-row-vertvar(--hull), 3px left-border colored by module type
.market-item.export-itemborder-left-color: var(--cargo)
.market-item.import-itemborder-left-color: var(--amber)
.outfit-mod-row.installedborder-color: var(--cyan), cyan-tinted bg
.crew-row.lockedborder-color: var(--hull); color: var(--text-disabled)
.story-step.ready-handinamber border + 3px amber left-border
.story-step.auto-complete / .comms-mission-row.handinborder-color: var(--cargo)

09 · Tabs

Station tabs (cyan active) · Ship tabs (amber active)
Info Market Outfitting Comms2
Ship Schematic Cargo Missions
ComponentClassesActive color
StationPanel.station-tabs / .station-tabvar(--accent-cyan)
ShipPanel.ship-panel-tabs / .ship-tabvar(--accent-amber)
StoryPanel.story-tabs / .story-tab-btnvar(--accent-cyan)
/* tab button */
background: none; border: none;
border-bottom: 2px solid transparent;
color: var(--text-muted);
font-family: var(--font-display); font-size: var(--fs-micro);
font-weight: 700; text-transform: uppercase;
transition: none;        /* snap — no smooth transitions */
/* active */ color: var(--accent-cyan); border-bottom-color: var(--cyan);

Tab badge (count): amber pill, min-width: 20px; height: 18px; border-radius: 9px, --void text, badge-pulse 2s step-end.

10 · Stat Bars

Block-character gauges using (U+2590) in spans — on = opacity 1, off = opacity 0.22.

FUEL    HULL

BarSegmentsColorWhere
Fuel12–18var(--blue)TopBar, ShipPanel
Hull6Conditional green / amber / redTopBar
Progress18var(--cyan)TransitScreen
Cargoby capacityvar(--cargo)ShipPanel
.bar-gauge { display: flex; gap: 2px; letter-spacing: -1px; }
.bar-seg { font-size: var(--fs-micro); line-height: 1; }
.bar-seg.on  { opacity: 1; }
.bar-seg.off { opacity: 0.22; }

11 · Modals

ModalOverlayPanelz-index
Controls.controls-overlay.controls-panel300
Event.event-overlay.event-modal200
Good Info.goodinfo-overlay.goodinfo-modal200
Arrival.arrival-overlay.arrival-modal60
Options (title).options-overlay.options-panel10

All overlays: position: absolute; inset: 0; background: rgba(10,13,20,0.82); flex center. All panels: var(--deep), 0.5px solid var(--panel), each with a .chrome-bar header.

Event modal
events.sys
⚠ Distress Call

Drifting Freighter

A damaged hauler hails you on an open channel, hold breached and venting atmosphere.

Arrival modal
arrival.sys
Now arriving

Ceres Outpost

Type
Mining
Faction
Free Traders
Region
Sector 7
Good Info modal
good.sys

Refined Ore

Industrial · Tier 1
HELD 12AVG ¢ 64P&L +240

Smelted metal stock — the backbone of station fabrication.

◆ Exports · Ceres, Halberd
● Imports · Helix, Vega
Controls overlay
controls.sys
MDock / return to map
LMission log
SSave game
?Toggle this overlay
EscClose modal
ModalNotable details
EventBorder tinted by category; category tag + icon before title; numbered choice buttons (mono prefix); effect pills using currentColor; locked decline = dashed, negative, not-allowed
Arrival4-col action grid (Dock / Scan / Trade / Leave); Dock = primary, Leave = ghost; blinking cyan tick eyebrow; 3-col facts grid; title at --fs-display
Good InfoName+meta header; holdings bar (qty, avg paid, P&L) on hull; amber-left-border description; export/import/neither station lists; full-width close

12 · Notifications

Toasts bottom-right, z-index 500, column-reverse (newest at bottom). Slide-in 0.3s steps(6). Subtitle (micro, uppercase, muted) + Title (small, bold, primary).

Toast stack
New Mission
Supply Run: Ceres → Helix
Mission Complete
Ore delivered
Ready to Hand In
Return to Helix Station
·
Log
Fuel topped up
TypeIconLeft border
New mission (pulses)var(--cyan) 3px
Mission completevar(--cargo) 3px
Mission hand-invar(--amber) 3px
Storyvar(--text-muted) 3px
Generic·var(--text-muted) 3px

13 · Title Screen

The game entry screen (state.screen === 'title'). Full-bleed background image (/title-screen.png) with a semi-transparent chrome bar pinned to the top, centered brand + menu, and a footer bar. Launches the Options modal (options.cfg).

Title screen
starwind.sys — sector command interface
Starwind
Sector Command Interface
Options modal
options.cfg
Versionv0.0.20
Save DataPresent

Key classes

ElementClassStyling
Brand name.title-game-name58px --font-display 700, accent-cyan, 0.14em, uppercase
Tagline.title-tagline--font-mono, muted, 0.22em tracking, uppercase
Menu button.title-btn380px, --font-display, 3px left-border (cyan on hover), chevron + keycap shortcut
Primary.title-btn.primaryCyan border + accent-cyan text + cyan-tinted bg (New Game)
Footer.title-footerLore quote (left) + version (right), --font-mono micro on translucent bar
Options panel.options-panel380px, var(--deep), chrome options.cfg, version/save rows, Delete-Save danger action with inline confirm

Legibility over the background image comes from opaque translucent fills (rgba(10,13,20,0.80–0.88)) on the chrome, buttons, and footer — no blur (the interface uses zero backdrop-filter). Keyboard: N new · C continue · O options · Esc closes options.

14 · TopBar (Header)

Live header bar
starwind.sys DAY 123 ¢ 12,480 FUEL HULL Ceres Outpost
ElementClassStyling
Chrome dots.chrome-bar-dots/-dotUnified from global.css
Label.chrome-bar-labelstarwind.sys
Separators.topbar-sep, panel color
Day.topbar-valMono, fs-num, tabular-nums
Credits.topbar-creditsAmber
Fuel.topbar-fuel-barBlue , 12 segs
Hull.topbar-hull-bar6 segs, conditional color
Location.topbar-loc-name/-typeDisplay cyan name + type badge
SAVE / MENU / DOCK.topbar-*-btnCompact, uppercase, micro
Mission dot.topbar-story-dot8px amber, pulse

15 · Star Map

Node scale & states (approximate)
Hub
Station
Outpost
Beacon
Current
Selected
??? Undiscovered

Node sizes (SVG units)

CategoryRadius
Hub24
Station20
Anomaly18
Outpost / Depot / Derelict14
Beacon12

Lines & labels

ElementValue
Base edges1.2px dashed var(--panel)
Route edges2.6px dashed var(--cyan), animated dash flow
Transit path / trail2.0px dashed / 3.6px solid var(--cyan)
Station labels18px --font-display uppercase (current 19px accent-cyan)
Edge distance labels17px --font-mono
Region watermarks52px --font-display, 10% opacity

Node states & fog of war

StateClassVisual
Current.is-currentCyan pulse ring + brightness + larger label
Selected.is-selectedDashed cyan ring + brighter node
Hovered.is-hoveredBrighter node, label → text-primary
On route.is-on-routeBrightness boost
Hostile.is-hostileRed tint
VisitedFull size, name, faction color, center dot
Adjacent (undiscovered).is-discovered55% size, ??? label 13px, faded 0.25, dashed ring, no dot
HiddenNot rendered

Info card: top-right, 340px, faction-colored bullet + name, stats (type/faction/region/hazard); when routed, 3-col distance/fuel/ETA grid + color-coded jump button. HUD: corner legend top-left, zoom top-right, route/transit info bottom center.

16 · Station Panel (Docked)

7 tabs: Info · Market · Outfitting · Shipyard · Crew · Comms · Gather (Gather only when station has gatherables).

TabContents
InfoStation name (26px display, accent-cyan), planet-type icon+label, description, fields (faction/region/type/temp/gravity/atmosphere), reputation (rank + value + 6px cyan bar), services with prefixes
MarketGrouped Exports ( cargo) / Imports ( amber) / Neither; per-item name+category+?; Buy/Sell columns; held stock (amber) + P&L; green buy / red sell qty; rep-locked = LOCKED badge; sticky cargo footer
OutfittingModules grouped by type with category icon; install/buy button; installed = cyan border-left + tint; compare panel when replacing; slot badge G/E/WS; amber trade-in
ShipyardShip name (amber display) + slot pips + stats; tier + archetype badge (balanced=cyan, fast=red, heavy=amber, gunship=purple); Repair (cargo) + Refuel (blue) with Max/Fill/Clear
CrewRoles grouped; skill + bonus + rep req + salary; locked = disabled/hull; hire + hired list with fire
CommsAvailable missions (accept) + ready-to-hand-in (green border); title (display fs-h2) + reward; objectives ■/□ + counters; done = green check, strikethrough
GatherResource name (display uppercase) + yield/fuel/time; amber gather button; cooldown = muted left-border

17 · Ship Panel (Docked)

4 tabs: Ship · Schematic · Cargo · Missions (+ Codex within Missions).

Badges · tier / archetype / slot type
Tier 2 Balanced Fast Heavy Gunship G E WS
Performance readout
CARGO
FUEL
SPEED
MASS
TabContents
ShipHull name (26px display, accent-amber) + tier/archetype badges; Performance bars (cargo, fuel, speed, mass) + Systems (scanner, crew, shield, signature); installed modules color-coded with sell; empty slots dashed; hired crew with fire
SchematicSee §17
CargoHeld goods (name, category badge, qty); avg paid + P&L; ? info; summary card (items, value, capacity)
MissionsActive steps (title, description, objectives, rewards); story chains with progress + status badges; completed = amber label
CodexDiscovered lore: title + body, amber discover timestamp

18 · Schematic (Ship Build View)

Main row: ship SVG (hull fill, archetype-colored stroke, alert-red engine glow with stepped pulse) + absolute-positioned slot boxes + detail panel. Warehouse cards below; drag-and-drop slots ↔ warehouse.

Hull silhouette · slots over SVG · engine glow
Selected-slot detail panel
Scanner
Pulse Array Mk II
Tier 2 · 60 mass

Wide-band sensor sweep — charts adjacent systems two jumps out.

+2 scan range · +1 detection

Slot states

StateVisual
Empty45% opacity, type label (G / E / WS)
FilledColored by module type
SelectedCyan border + bg
Drag source35% opacity, dashed border
Valid / invalid targetCyan / red border + bg

Slot colors by module type

Slot grid · filled by type + empty
Cargo
Fuel
Engine
Crew
Scanner
Shield
GEmpty
ModuleIconBorder / label
Cargo Hold--amber / accent-amber
Fuel Tank--blue / accent-blue
Engine--alert / negative
Crew Quarters--cargo / positive
Scanner--cyan / accent-cyan
Shielding--purple
Auto-Repair--cargo / positive

19 · Transit Screen

Fullscreen, radial dot-grid over void.

Transit readout
▐▐ In Transit ▐▐
Ceres Outpost → Helix Station
61%
DISTANCE 14 LY · ETA 2 DAYS · RISK LOW
ElementSpec
Header▐▐ IN TRANSIT ▐▐ — fs-h1 display, accent-cyan, uppercase
RouteOrigin Destination, display font
Progress18 segs cyan + 34px mono accent-cyan %
MetaDistance · ETA · Risk (label + mono value)
ShipAmber chevron / sprite on route line
Particle layerColorDuration
Nearvar(--cyan)0.3–0.8s
Midvar(--blue) 30%0.8–1.6s
Farvar(--text-muted) 15%1.5–3.0s

20 · Story Panel

Two tabs: Missions & Codex (opens on L).

Active mission step
Supply Run

Deliver refined ore to Helix Station before day 130.

Acquire 20 Refined Ore 20/20
Deliver to Helix Station 0/1
Reward · ¢ 3,200 + rep
Ready to hand in
Courier: Sealed Datapad
Carry datapad to Vega done

21 · Denied & Game Over

Access denied
station.sys — LOCKED
Access Denied
Reputation too low to dock at this station.
— PRESS [M] TO RETURN TO MAP —
Game over
ship.sys — BREACH
Hull Breach
Life support failing. The void claims another trader.
PanelChromeCenterDetail
DeniedPanelred·amber·red · station.sys — LOCKEDBlinking 48px negativeTitle ACCESS DENIED (26px display, negative); rep explanation; hint — PRESS [M] TO RETURN TO MAP —
GameOverPanelall red · ship.sys — BREACHBlinking ! 56px negative (0.8s step-end)Title HULL BREACH (fs-display); stats card (stations, crew, ship, lore, missions, credits, top rep); RESET (alert) + CONTINUE (muted)

22 · Animations

All animations use step-end or steps(N) — never ease, ease-in-out, linear, or cubic-bezier. Hover states snap instantly (transition: none).

Banned

/* NEVER */
transition: all 0.3s ease-in-out;
box-shadow / text-shadow / filter: drop-shadow();
backdrop-filter: blur();        /* never — use opaque translucent rgba fills instead */
linear-gradient / radial-gradient  /* except scanlines, star-map bg, starfield */

Global keyframes

NameEffectTiming
blinkopacity 1 ↔ 01s step-end
pulse-stepopacity 0.6 ↔ 0.32s steps(4)

Component keyframes

NameEffectTimingFile
starmap-route-flowDash offset1.2s linearStarMap
starmap-cell-pulsePulse ring2.4s steps(4)StarMap
starmap-ship-pulseShip glow1.4s steps(4)StarMap
info-card-inCard slide0.18s steps(4)StarMap
arrival-modal-inScale + fade0.22s steps(4)ArrivalModal
arrival-tick-blinkTick blink1.2s steps(2)ArrivalModal
event-popScale pop-in0.3s steps(4)EventModal
engine-pulseEngine glow2s steps(4)ShipSchematic
detail-inDetail fade/slide0.15s steps(4)ShipSchematic
step-highlightNew-mission fade3s steps(6)StoryPanel
badge-pulseTab badge2s step-endStationPanel
confirm-pulseConfirm flash0.4s step-end ×3StationPanel
story-dot-pulseTopBar mission dot1.5s step-endTopBar
particle-driftTransit particles1s steps(4)TransitScreen
toast-in / toast-pulseSlide / icon pulse0.3s steps(6) / 2s step-endNotificationToast

23 · Screen Reference

state.screenComponents
'title'TitleScreen (bg image + centered menu + options modal)
'map'TopBar + StarMap
'transit'TopBar + StarMap (transit overlay)
'docked'TopBar + DockPanel (Station + Ship, 7 tabs)
'denied'TopBar + DeniedPanel
'gameover'TopBar + GameOverPanel
OverlayTrigger
EventModalstate.activeEvent
StoryPanelL key
ControlsOverlay? / / key
NotificationToastMission events
ArrivalModalTransit completes on map
GoodInfoModalMarket / cargo ?
#root
├── .scanlines (CRT, always on)
├── .small-viewport-warning (< 1024px)
└── .app-shell
    └── GameShell (screen router)
        ├── TitleScreen
        ├── TopBar (all non-title screens)
        ├── StarMap / DockPanel / DeniedPanel / GameOverPanel
        ├── EventModal · ControlsOverlay (conditional)
        └── NotificationToast

24 · CSS File Map

FileLinesCovers
styles/global.css255Variables, reset, body, #root, chrome-bar, buttons, inputs, scanlines, blink/pulse
TitleScreen.css270Title screen (bg, branding, menu, options modal)
TopBar.css192Header (stats, fuel/hull gauges, location, actions)
StarMap.css739Map (nodes, edges, labels, HUDs, info card, transit overlay)
StationPanel.css1413Dock tabs (info, market, outfit, shipyard, crew, comms, gather)
ShipPanel.css575Ship (stats, modules, cargo, missions, codex)
ShipSchematic.css463Build view (SVG hull, slots, warehouse, drag-drop)
StoryPanel.css388Missions + codex
ArrivalModal.css253Arrival card (facts grid, action grid)
TransitScreen.css218Warp (particles, progress, route)
EventModal.css210Event popup (choices, effects, decline)
GoodInfoModal.css162Good detail popup
GameOverPanel.css113Game over (stats card, actions)
ControlsOverlay.css105Keyboard shortcuts overlay
NotificationToast.css92Toast notifications
App.css80App shell, story overlay, action buttons
DeniedPanel.css72Access denied
DockPanel.css8Dock 2-panel split border frame

Starwind Interface Style Guide · Updated 2026-05-30 · style_guide() to open