Skip to content

Repository files navigation

SP Night — the Pico do Jaraguá at dusk, aviation beacon lit, the city's lights at the foot of the range

SP Night

The sodium lamp turns the whole city this colour.
A dark colour scheme with São Paulo as its reference — the sodium street lamp,
exposed concrete, the free span of the MASP, the drizzle before the rain.

Deploy to GitHub Pages 3 flavours 23 colours MIT license

sp-night.github.io  ·  palette  ·  spec  ·  ports  ·  contribute


The flavours

All three are dark, by decision. They differ in hue and chroma, never in brightness — nothing gets easier or harder to read when you switch.

Noite Paulista mark Garoa mark Pico do Jaraguá mark
Noite Paulista noite Garoa garoa Pico do Jaraguá jaragua
The city at 3 a.m. A blue-violet dark, with the sodium street lamp burning warm on top of it. The same window, seen through the drizzle. Flat grey — the garoa does not cool the city down, it fades it out. The same night, seen from the highest point in the city. Near-black, the forest left to the accents.

The palette

Five surfaces · four levels of text · eight accents · six bright pairs — 23 colours, each named after the thing in São Paulo it came from. Every pairing is measured before it ships, never eyeballed.

noite The 23 colours of noite, grouped: surfaces, text, accents, bright pairs

garoa The 23 colours of garoa, grouped: surfaces, text, accents, bright pairs

jaragua The 23 colours of jaragua, grouped: surfaces, text, accents, bright pairs

Full detail — glosses, OKLCH, WCAG ratios, the ANSI map — lives at sp-night.github.io/palette.

The 23 hex values, all three flavours
colour noite garoa jaragua
vao #0f101a #151719 #050806
laje #151723 #1c1e20 #0c100d
concreto #1d1f2d #26282a #151a17
vidro #272937 #313436 #202622
fiacao #373943 #414346 #323733
fg_vivo #e7ebff #dae1ea #e7eee9
fg #d3d7eb #c7cdd6 #d3dad5
fg_dim #868999 #8d949f #868b87
fg_muted #707380 #767d88 #707471
brasa #ea5d5d #d87676 #ea5d5d
sodio #f2984a #e3a068 #f2984a
taxi #f5c66b #e7cb8a #f5c66b
ibira #89d093 #9acaa2 #79d488
estaiada #38b59e #56b19f #05b89e
sereno #5dbec4 #77babf #60bfb8
marginal #6e92de #7993cb #6e92de
temporal #b094e2 #af97d3 #b094e2
brasa_vivo #ff716f #ed8988 #ff716f
taxi_vivo #ffdc9c #fbdf9d #ffdc9c
ibira_vivo #9ce4a6 #addeb5 #8ce99b
sereno_vivo #71d1d7 #8acdd2 #73d2cb
marginal_vivo #80a5f2 #8ba6df #80a5f2
temporal_vivo #c3a7f6 #c2aae7 #c3a7f6

Ports

One repository per themed app, each holding finished theme files — plain text, no build step to use them. A port is listed only once it is published, so everything below can be installed today, and each one has its own page with install instructions, the key-to-role table and a preview.

The catalogue lives in sp-night/sp-night at registry/ports.yml and is vendored here as src/data/ports.yml. The table below is generated from it by npm run assets, and npm test fails if it falls behind.

Port Group Installs to
Ghostty Terminals ~/.config/ghostty/themes/sp_night_{flavor}
kitty Terminals ~/.config/kitty/sp_night_{flavor}.conf
Alacritty Terminals ~/.config/alacritty/themes/sp_night_{flavor}.toml
eza Shell & CLI ~/.config/eza/theme.yml
Helix Editors ~/.config/helix/themes/sp_night_{flavor}.toml
herdr Multiplexers ~/.config/herdr/config.toml

Theming another app? See CONTRIBUTING.md. The palette and the role layer are published as data — /palette.json and /roles.json — so the colour decisions are already made and nothing needs to be copied by hand.

This repository

The website. A static Astro site, no UI framework. Colour data is vendored in src/data/ and flows through one typed module, src/data/palette.ts:

  • No component reads the JSON directly — everything derives at build time.
  • No hex literal exists outside src/data/ — enforced by a test that scans the tree.
  • The contrast policy (body text AAA on every surface, dim text AA, accents AA on the deepest background) is asserted in CI, so a palette drop that breaks it never deploys.
npm ci
npm run dev        # dev server
npm run check      # astro type-check
npm test           # vitest: colour maths, data shape, contrast policy, no-raw-hex rule
npm run build      # static build into dist/
npm run assets     # regenerate favicons, logos, OG cards, palette strips and the README tables

Every image in this README is generated from the palette by npm run assets — if the colours change, the brand follows.

Deploy

Push to maindeploy.yml runs type-check, tests and build, then publishes to GitHub Pages. Other branches and PRs run the same checks via ci.yml without deploying.

Updating the palette · adding ports

Everything in src/data/ except content.ts, palette.ts and ports.ts is vendored from sp-night/sp-night: the palette, the role layer, the audit summary and the port catalogue. Editing those copies here is a change that disappears at the next sync.

  • Palette, roles or catalogue change → make it in the engine. Its sync-ports.yml copies the files across, redraws public/previews/ and opens a pull request here, gated on this repository's own npm run check && npm test && npm run build.
  • A new port → list it in the engine's registry/ports.yml. Merging the sync pull request publishes /ports/<slug> — the page is generated from the entry, so there is nothing to write here.
  • Contributor listnpm run contributors, or leave it to the weekly workflow.

npm run assets regenerates the images and the README tables, and is the one step still run by hand — npm test fails when its output is stale.

Contributions are welcome — see CONTRIBUTING.md for how to propose a port or report a colour problem, and SITE.md for the full design plan and decision log.

SP Night — built by its contributors · MIT

About

A dark colour scheme with São Paulo as its reference — three flavours, 22 colours

Topics

Resources

Code of conduct

Contributing

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages