Red means look here.
Vermilion paints decorators, channel operators and escapes, and nothing else. The pigments around it are softer, so it never has to compete.
The palette behind this site, made official. Paper for daylight, Ink for the dark, warm ink for strings, and a single vermilion for what deserves your attention.
Paper
use io
decl Reading { sensor: string; value: f64; live: bool }
@mm(arena)
fn ingest(src: Channel[->Reading]) {
loop r in src {
if r.live == true && r.value > 40.0 {
// strings in warm ink, numbers in ochre
io.println("hot: {{r.sensor}} at {{r.value}}")
}
}
}
reply := store <-> batch timeout(5s)package main
import "fmt"
type Reading struct {
Sensor string
Value float64
Live bool
}
func ingest(src <-chan Reading) {
for r := range src {
if r.Live == true && r.Value > 40.0 {
// strings in warm ink, numbers in ochre
fmt.Printf("hot: %s at %.1f\n", r.Sensor, r.Value)
}
}
}use std::sync::mpsc::Receiver;
#[derive(Debug)]
struct Reading { sensor: String, value: f64, live: bool }
fn ingest(src: Receiver<Reading>) {
for r in src {
if r.live == true && r.value > 40.0 {
// strings in warm ink, numbers in ochre
println!("hot: {} at {}", r.sensor, r.value);
}
}
}interface Reading { sensor: string; value: number; live: boolean }
export async function ingest(src: AsyncIterable<Reading>): Promise<void> {
for await (const r of src) {
if (r.live === true && r.value > 40) {
// strings in warm ink, numbers in ochre
console.log(`hot: ${r.sensor} at ${r.value}`);
}
}
}Ink
use io
decl Reading { sensor: string; value: f64; live: bool }
@mm(arena)
fn ingest(src: Channel[->Reading]) {
loop r in src {
if r.live == true && r.value > 40.0 {
// strings in warm ink, numbers in ochre
io.println("hot: {{r.sensor}} at {{r.value}}")
}
}
}
reply := store <-> batch timeout(5s)package main
import "fmt"
type Reading struct {
Sensor string
Value float64
Live bool
}
func ingest(src <-chan Reading) {
for r := range src {
if r.Live == true && r.Value > 40.0 {
// strings in warm ink, numbers in ochre
fmt.Printf("hot: %s at %.1f\n", r.Sensor, r.Value)
}
}
}use std::sync::mpsc::Receiver;
#[derive(Debug)]
struct Reading { sensor: String, value: f64, live: bool }
fn ingest(src: Receiver<Reading>) {
for r in src {
if r.live == true && r.value > 40.0 {
// strings in warm ink, numbers in ochre
println!("hot: {} at {}", r.sensor, r.value);
}
}
}interface Reading { sensor: string; value: number; live: boolean }
export async function ingest(src: AsyncIterable<Reading>): Promise<void> {
for await (const r of src) {
if (r.live === true && r.value > 40) {
// strings in warm ink, numbers in ochre
console.log(`hot: ${r.sensor} at ${r.value}`);
}
}
}Three grounds for each paper, three weights of text for each, the vermilion family, and four pigments that tell code apart. Each variant prints with its own half of the set.
Click any ink to copy it. The few in-between tones, like the code ground or the color of function names, are mixes of two inks, never new colors.
A deep tone that reads on Paper and a light one that reads on Ink. In code the pigments name what each token is; the vermilion stays the one that asks for attention. Measured on the code ground: 5.6 to 5.8:1 on Paper, 4.2 to 8.6:1 on Ink.
Decorators, channel operators, escapes
@mm(arena) <->@mm(arena) <->Strings
"hot: 40.0""hot: 40.0"Numbers; warnings
40.0 5s 0xff40.0 5s 0xffFunctions; success
ingest printlningest printlnTypes; information
Reading f64Reading f64Constants; hints
true nonetrue noneEach swatch is shown where it lives, with its contrast measured against that ground. Syntax colors sit on the code background, text sits on the page.
fn match loop spawnfn match loop spawnReading Result ChannelReading Result Channelingest printlningest printlnsrc value batchsrc value batch"hot: {{r.sensor}}""hot: {{r.sensor}}"40.0 5s 0xff 64kib40.0 5s 0xff 64kibtrue false nonetrue false none// quiet on purpose// quiet on purpose@mm(arena) <-> {{ }}@mm(arena) <-> {{ }}:= -> == +:= -> == +Vermilion paints decorators, channel operators and escapes, and nothing else. The pigments around it are softer, so it never has to compete.
Strings in warm ink, numbers in ochre, constants in plum, types in indigo, functions in moss. Learn the five and a line reads at a glance.
Keywords keep the text color and go bold; operators and comments step back. The shape of the program comes from weight, its meaning from color.
Measured on the code ground and computed from the palette when this page builds. Below the line: decorators and channels on Ink (4.2:1), kept to short tokens. Nothing drops under 4.2:1, past the 3:1 bar for large text.
Paper Ink lives in its own repository as a single palette file: 24 inks, and every theme generated from them. Today it highlights this site; editor and terminal ports come later.