North Star

DESIGN.md · §1

Creative North Star

The Reference Atlas

ClimateScope is a navigable, trusted reference object. It reads less like an app and more like a regional climate atlas you can interrogate, with the API and the map as twin first-class surfaces. Authority is earned through completeness and source-disclosure, not through visual volume. Every screen carries the weight of editorial restraint: the surface gets out of the way so the data can speak.

The system rejects three traps explicitly named in PRODUCT.md: generic SaaS dashboard chrome, weather-app clichés, and the AI-slop hero-metric template. It rejects them through type-led hierarchy, single-purpose color, generous whitespace, and a steadfast refusal to decorate. Where most tools shout their data, the Reference Atlas catalogues it.

Key Characteristics

  • Warm, cream-tinted canvas. Never #fff.
  • Single-family typography (Geist) doing all jobs: display, body, label, data.
  • Map is the hero on data surfaces; the ranked list and detail panel orbit it.
  • Color is reserved for meaning. Brand, secondary, caution, precipitation, neutral. Nothing decorative.
  • Flat by default. Shadows only as state response.
  • Source disclosure (dataset, normal period, model run) is visible on every numbers-bearing surface.

Named Rules

10 rules

The doctrinal one-liners that ClimateScope agents must internalize. Pulled verbatim from DESIGN.md. When a rule and a token disagree, the rule wins.

The One Voice Rule
Cartographer's Forest carries ≤10% of any given screen. Its rarity is its authority. If the green starts to fill more than a tenth of the surface, demote to Forest Soft or remove it. The brand color is a punctuation mark, not a wash.
The Single-Purpose Color Rule
Anomaly Clay is for caution. Precipitation Blue is for rain. Atlas Sage is for stable / positive. Cartographer's Forest is for brand / primary action. Every color has one job. A clay-tinted decorative button is forbidden. A blue-accent navigation chevron is forbidden. If a hue appears where it doesn't encode meaning, it has been misused.
The No-White Rule
Never #fff or #000. Every neutral is tinted toward the brand hue (green, chroma 0.005–0.012). Pure white feels clinical and breaks the editorial register.
The One-Family Rule
Geist carries every text element: display, body, label, data. No serif display, no second sans. Hierarchy lives in weight and size, never in family swap.
The Editorial Eyebrow Rule
Uppercase labels (.label) are scoped: they appear above section titles to identify the section type, never inside body content. Three eyebrows per surface, maximum. They lose force when overused.
The Flat-By-Default Rule
Resting surfaces have zero shadow. If a panel needs to feel "elevated" at rest, raise it tonally (use Page Chalk against Warm Off-Stone, add a Border Subtle) instead of casting a shadow. Shadow is reserved for response to user state (hover, focus, drag).
The Tinted-Shadow Rule
Every shadow is tinted toward the brand green (oklch(...) / low-alpha). Pure-black rgba(0,0,0,...) shadows are forbidden. They feel borrowed from another system.
The Map-Is-Hero Rule
On the climate-comparison surface, the Japan map occupies the dominant column. The ranked list and detail panel orbit it. Map width is never reduced to accommodate decoration. If a layout proposal shrinks the map below 50% of the surface, the layout is wrong.
The Source-Strip Rule
Every numbers-bearing panel terminates in a source strip: dataset, normal period, model run date, and a "View API response" affordance. Source disclosure is not a tooltip. It is visible chrome.
The Pair-Color-With-Text Rule
Every data flag pairs its color with explicit text. Color alone never communicates state. A region marked "above normal" must say "above normal" in the flag, the clay tint is the second cue, not the first.

Do's & Don'ts

DESIGN.md · §6

Concrete guardrails. The Don'ts mirror PRODUCT.md anti-references so the strategic line carries into the visual spec.

Do
  • Use Cartographer's Forest only on primary actions, active states, and the selected-region outline. ≤10% of any screen.
  • Tint every neutral toward green (chroma 0.005–0.012). #fff and #000 are prohibited.
  • Disclose dataset, normal period, and model run date on every numbers-bearing surface.
  • Pair every data flag color with an explicit text label.
  • Render the Japan map at ≥50% of the climate-comparison surface width.
  • Keep shadows transient. Hover, focus, drag only. Resting surfaces are flat.
  • Use 65–75ch line length for prose. Compact UI can run denser.
  • Respect prefers-reduced-motion. Disable region transitions, hover lifts, fade-ins.
Don't
  • Build generic SaaS dashboard chrome. Sidebar + top bar + tabs + KPI cards is the AI-slop default.
  • Use weather-app clichés. No gradient skies, no big sun/cloud icons, no emoji weather.
  • Ship the AI-slop hero-metric template. Big colorful number + supporting stats + gradient accent.
  • Default to dark mode or use neon/crypto/observability aesthetics.
  • Use border-left or border-right greater than 1px as a colored accent.
  • Use background-clip: text for gradient headlines.
  • Use glassmorphism as a default decorative move.
  • Use modals as a first thought. Inline and progressive disclosure first.
  • Use Anomaly Clay decoratively. Caution is its only job.
  • Use em dashes. Use commas, colons, semicolons, periods, or parentheses.
  • Introduce a second type family. Geist carries every job.
  • Put resting shadows on cards. Tonal layering and Border Subtle do the work.

Overview

role-based · OKLCH

ClimateScope's palette is role-based, not scalar. Each color family has a specific job: Forest is brand, Sage is secondary, Earth is caution, Rain is precipitation, Slate is neutrals, Stone is surfaces. Tokens are authored in OKLCH for perceptual consistency; hex values shown for designer reference. Mock anchors pin specific roles to a hex from the design mockup at docs/design/inspiration/design and mock.png.

Color scales

primitives

Each row is one color family stepped from light to dark. Hover a chip to lift it.

Stone
#F4F2EC · 100
surfaces
chalk#FAF8F5
50#FAFAF4
100#F4F2EC
200#ECEDE4
alt#EEF0EC
border#E1E6E2
Forest
#415C4A · 500
primary · brand
300#829D88
400#66836C
500#415C4A
600#364D3E
700#243F2B
Sage
#B4C4A8 · 300
secondary · stable
100#DCE5D5
200#C9D6C0
300#B4C4A8
400#A4B594
Earth
#C7A28F · 400
caution · above-normal
200#DEC5B8
300#D0B09F
400#C7A28F
500#B08874
Slate
#53635A · 600
text · icons · neutrals
200#C4CDC8
300#A5B2AB
400#8A9A92
500#65766E
600#53635A
Rain
#6D8FA3 · 400
precip · below-normal · data
200#AFC9D3
300#8BABB7
400#6D8FA3
500#456D7B
Ink
#191E15 · strong
text emphasis
ink#2F332B
strong#191E15

Semantic roles

aliases

Always prefer the semantic alias over the primitive when writing component CSS. These are the names components should reach for.

TokenRoleResolves to
--cs-color-canvasPage backgroundStone 100
--cs-color-surfaceCard / panelChalk
--cs-color-surface-mutedSecondary panelSurface Alt
--cs-color-borderDefault borderBorder Subtle
--cs-color-border-strongEmphasis borderSlate 300
--cs-color-textPrimary textInk Strong
--cs-color-text-mutedSecondary text, icons, labelsSlate 600
--cs-color-primaryBrand · primary actionForest 500
--cs-color-primary-hoverPrimary hoverForest 600
--cs-color-secondarySecondary · stable stateSage 300
--cs-color-secondary-softSoft sage fillSage 100
--cs-color-thresholdCaution · above-normal anomalyEarth 400
--cs-color-precipitationRain / below-normal precipRain 400
--cs-color-focusFocus ringRain 400

Mock anchors

design-locked

Tokens pinned to exact hex values from the design mockup. Diverging from these means diverging from the design.

TokenMock hexRole
--cs-forest-500#415C4APrimary Forest Green
--cs-forest-600#364D3EPrimary Hover · Darker Forest
--cs-sage-300#B4C4A8Secondary Sage
--cs-sage-400#A4B594Sage Deep · hover
--cs-earth-400#C7A28FAccent Clay · caution
--cs-slate-600#53635ASlate Text / Icons
--cs-rain-400#6D8FA3Data Rain Blue · precip
--cs-surface-alt#EEF0ECSurface Alt Panel
--cs-border-subtle#E1E6E2Border Subtle

Typography

Geist + Geist Mono
h1 · 32/44 · -0.02em
The quick brown fox jumps
h2 · 28/36 · -0.02em
The quick brown fox jumps
h3 · 24/32 · -0.02em
The quick brown fox jumps
h4 · 20/28
The quick brown fox jumps
h5 · 18/24
The quick brown fox jumps
h6 · 16/24
The quick brown fox jumps
p-lg · 18/28
Body text at lg size for content and interfaces.
p-md · 16/24
Body text at md size for content and interfaces.
p-sm · 14/20
Body text at sm size for content and interfaces.
p-xs · 12/16
Body text at xs size for content and interfaces.
label-lg · 16/18 · 500
Label Lg
label-md · 14/16 · 500
Label Md
label-sm · 12/16 · 500
Label Sm
label-xs · 10/14 · 500
Label Xs

Spacing

4px base
space-1
4
space-2
8
space-3
12
space-4
16
space-5
20
space-6
24
space-8
32
space-10
40
space-12
48
space-16
64

Border Radius

7 values
sm
4px
md
8px
lg
12px
xl
16px
2xl
20px
3xl
24px
full
pill

Elevation

3 levels

Restraint. Shadows appear only as a response to state (hover, lifted content). Most surfaces are flat by default.

none
lift
panel

Opacity

9 values

For state overlays, disabled treatments, and faint backdrops. Chip color is --cs-color-primary; you're seeing it through each opacity level.

5
10
20
30
40
50
60
75
90

Buttons

primary · secondary · ghost

Segmented control

metric switch

Data flags

status pills

Flags encode meaning through color. Clay = above-normal anomaly. Rain blue = below-normal precipitation. Sage = stable / good.

Stable +1.0°C above normal −12% precipitation

Usage guide

do · don't
✓ Prefer semantic aliases
.button {
  background: var(--cs-color-primary);
  color: var(--cs-color-primary-contrast);
}
✗ Avoid raw primitives in components
.button {
  background: var(--cs-forest-500);
  color: var(--cs-chalk);
}
✓ Caution is for anomalies
.metric-above-normal {
  color: var(--cs-color-threshold);
}
✗ Don't use caution decoratively
/* Clay is not a brand accent. */
.tag {
  background: var(--cs-color-threshold);
}