---
version: alpha
name: Frost Signal
description: A cold periwinkle room where red and green are the only warm things on the page, and both of them mean something.
meta:
  id: "theme-frost-signal"
  model: "Claude Opus 5"
  author: "Claude Code"
  createdAt: "2026-09-02T00:58:15+09:00"
  updatedAt: "2026-09-02T00:58:15+09:00"
  version: "1.0.0"
  isNew: false
lookbook:
  tagline: In range, or out of range. There is no third state.
  bestFor: Cold-chain and logistics monitoring, food safety, lab freezers, sensor fleets, alert consoles
  avoidFor: Marketing sites, editorial, anything where red and green are decorative
  defaultMode: dark
  surfaceStyle: filled
  accentUse: bar
  caseStyle: labels-upper
  borderWidth: 1px
  imageTreatment: cool
  motion:
    intensity: 2
    duration: 200ms
    ease: "cubic-bezier(0.33, 1, 0.68, 1)"
    signature: "A row that leaves range moves once, sharply, and then holds. Nothing pulses — a blinking alert is one people learn to stop seeing."
  displayFont: Commissioner
  displayKind: sans
  bodyFont: Commissioner
  monoFont: Azeret Mono
colors:
  background: "#CBE5FF"
  foreground: "#0D1221"
  card: "#C2D7ED"
  card-foreground: "#0D1221"
  popover: "#C2D7ED"
  popover-foreground: "#0D1221"
  primary: "#794D4E"
  primary-foreground: "#F6FBFF"
  secondary: "#AECAE7"
  secondary-foreground: "#0D1221"
  muted: "#AECAE7"
  muted-foreground: "#495269"
  accent: "#287E39"
  accent-foreground: "#F6FBFF"
  destructive: "#A51F1E"
  destructive-foreground: "#F6FBFF"
  border: "#A3BBD5"
  input: "#A3BBD5"
  ring: "#794D4E"
  chart-1: "#8A4F51"
  chart-2: "#337861"
  chart-3: "#7A5027"
  chart-4: "#5E70A1"
  chart-5: "#54581E"
colorsDark:
  background: "#071727"
  foreground: "#E6E9EE"
  card: "#19232C"
  card-foreground: "#E6E9EE"
  popover: "#19232C"
  popover-foreground: "#E6E9EE"
  primary: "#CD9B9B"
  primary-foreground: "#040E1A"
  secondary: "#23303D"
  secondary-foreground: "#E6E9EE"
  muted: "#23303D"
  muted-foreground: "#95979E"
  accent: "#6DC077"
  accent-foreground: "#040E1A"
  destructive: "#FF7C70"
  destructive-foreground: "#040E1A"
  border: "#34404D"
  input: "#34404D"
  ring: "#CD9B9B"
  chart-1: "#D59395"
  chart-2: "#6AAE94"
  chart-3: "#D5A67B"
  chart-4: "#8094C7"
  chart-5: "#B7BD81"
typography:
  display-lg:
    fontFamily: Commissioner
    fontSize: 52px
    fontWeight: 700
    lineHeight: 1.06
    letterSpacing: -0.025em
  headline-lg:
    fontFamily: Commissioner
    fontSize: 30px
    fontWeight: 600
    lineHeight: 1.2
    letterSpacing: -0.012em
  headline-md:
    fontFamily: Commissioner
    fontSize: 19px
    fontWeight: 600
    lineHeight: 1.34
  body-lg:
    fontFamily: Commissioner
    fontSize: 16px
    fontWeight: 400
    lineHeight: 1.6
  body-md:
    fontFamily: Commissioner
    fontSize: 14.5px
    fontWeight: 400
    lineHeight: 1.58
  body-sm:
    fontFamily: Commissioner
    fontSize: 13px
    fontWeight: 400
    lineHeight: 1.5
  label-caps:
    fontFamily: Commissioner
    fontSize: 10.5px
    fontWeight: 700
    lineHeight: 1.1
    letterSpacing: 0.14em
  label-mono:
    fontFamily: Azeret Mono
    fontSize: 12.5px
    fontWeight: 500
    lineHeight: 1.4
    letterSpacing: 0.01em
  numeral-xl:
    fontFamily: Azeret Mono
    fontSize: 56px
    fontWeight: 500
    lineHeight: 1
    letterSpacing: -0.03em
rounded:
  none: 0px
  sm: 3px
  md: 5px
  lg: 7px
  xl: 10px
  full: 9999px
spacing:
  base: 16px
  xs: 4px
  sm: 8px
  md: 16px
  lg: 24px
  xl: 44px
  gutter: 16px
  margin: 26px
  measure: 66ch
components:
  button-primary:
    backgroundColor: "{colors.primary}"
    textColor: "{colors.primary-foreground}"
    rounded: "{rounded.sm}"
    padding: 10px
  button-ghost:
    backgroundColor: transparent
    textColor: "{colors.foreground}"
    rounded: "{rounded.sm}"
    padding: 10px
  card-panel:
    backgroundColor: "{colors.card}"
    textColor: "{colors.foreground}"
    rounded: "{rounded.md}"
    padding: 18px
  badge-label:
    backgroundColor: "{colors.secondary}"
    textColor: "{colors.secondary-foreground}"
    typography: "{typography.label-caps}"
    rounded: "{rounded.sm}"
---

# Frost Signal

## Overview

Frost Signal watches things that must stay cold. Vaccine fridges, reefer
containers, blood banks, a restaurant's walk-in. The job is not to look
impressive; it is to make one fact — *is this within its band right now* —
readable from six feet away by someone who is not looking for it.

The ground is a cold periwinkle, and the discipline of the system is that
periwinkle is the only colour used for anything structural. Every warm pixel on
the screen is either the red or the green, and both of them are load-bearing.
A red border that means "selected" would destroy this system, so there is no
red border that means selected.

It is a monitoring system. It is wrong for anything where red is just a brand
colour, because here red is a temperature.

## Colors

Cold everywhere, warm only where it means something.

- **Ground:** cold periwinkle. Genuinely blue, not blue-grey — the room should
  feel like the inside of the thing being monitored.
- **Primary (red):** out of range. It is also the button colour, and that is not
  a compromise: the primary action in this system is always *acknowledge the
  problem*.
- **Accent (green):** in range. It is used as a **bar** — a 4px band at the left
  edge of a row or the top of a card — and it was solved to 3:1 against both the
  ground and the card for exactly that use. It is never text and never a fill.
- **Neutrals** are tinted with the ground's blue so nothing on the page is
  achromatic; a true grey would read as a fault.
- Charts are accented: one series carries the reading, everything else is
  neutral, and the in-range band is drawn as a filled region in accent at low
  alpha.

## Typography

Commissioner throughout, Azeret Mono for every number that came from a sensor.

- **Display:** Commissioner at 700, 52px. A neutral grotesque with a wide range
  of weights — it does not editorialise, which is right for a console.
- **Readings:** Azeret Mono, always. If a number was measured, it is mono. If a
  number was typed by a person, it is not. That rule is visible on the screen
  and is the fastest way to tell a threshold from a measurement.
- **numeral-xl at 56px in mono weight 500** is the current temperature, and it
  is the largest thing on any screen that shows one.
- Labels are uppercase at 0.14em. Sensor names, zones, units.

## Layout

**One row per sensor, one state per row.** The core of the system is a dense
list where each row is 44px, carries a 4px accent or destructive bar at its left
edge, and shows: name, current reading in mono, band, time-in-state, and a
30-minute sparkline. Rows never expand in place — selecting one fills a right
panel at 380px.

The band is drawn, not described. Every reading appears against a horizontal
range strip showing min, max and current position, so "2.1°C" and "near the top
of its band" are the same glance.

A 12-column grid at 1440px, 16px gutters. Console density: 44px rows, 18px card
padding. This system is allowed to be tight.

## Elevation & Depth

Filled surfaces, one step of shadow, and one only — the right-hand detail panel
casts a shadow over the list because it genuinely overlays it. Cards in the grid
are flat fills with 1px borders.

Motion is a single sharp move on state change, then stillness. Nothing pulses,
nothing breathes, nothing loops. An animation that repeats forever is one the
operator's eye filters out within an hour, and this system's entire value is
that a change is noticed.

## Shapes

Small radii — 3px on controls, 5px on cards. Enough to look like software, not
enough to look soft.

Photography is cool-graded and used only on marketing and empty states: frost,
condensation, steel, cold rooms. Never a person smiling at a fridge.

## Components

- **Sensor row:** 4px state bar at the left, name, mono reading at 15px, range
  strip 120px wide, dwell time, sparkline. The bar is accent when in range and
  destructive when not. There is no amber.
- **Range strip:** a 4px neutral track with a filled accent region for the
  permitted band and a 2px mark for the current value. Out of band, the mark is
  destructive and sits outside the region.
- **Acknowledge button:** primary fill. It is the only filled button on the
  alert screen.
- **Excursion card:** duration, min, max and area-under-curve in mono, with the
  chart showing the band as a filled region behind the trace.
- **Badges:** uppercase on secondary. Never red or green — those two are
  reserved for state bars and would dilute if spent on labels.

## Do's and Don'ts

- Do keep red and green exclusively for out-of-range and in-range.
- Do set every measured number in Azeret Mono and every typed number in the sans.
- Do draw the band; do not describe it.
- Don't pulse, blink, or loop any animation.
- Don't add amber as a warning state — this system is binary by design.
- Don't use the accent as text; it was solved for a 3:1 bar, not for 4.5:1 type.
- Don't let a row grow in place and push the rows below it down.
