Tokens · v0.1

The only values in the system.

Every surface, type scale, corner, shadow, and timing in Dagrun resolves to one of these values. If you’re writing a hard-coded #, px, or ms in a component — stop and find the token.
01 · Color · semantic

Light + dark semantics.

Never use a raw hex in a component — always a semantic name. Light and dark values resolve from the same name via the asset catalog / CSS variables.

name · light / darkswatchcssswiftui
token
bg
#F5F2EA ↔ #0A0A0A
css
var(--color-bg)
swiftui
Color("dagrun/bg")
token
bg.raised
#FFFFFF ↔ #1A1815
css
var(--color-bg-raised)
swiftui
Color("dagrun/bg/raised")
token
bg.sunken
#F8F5EE ↔ #050505
css
var(--color-bg-sunken)
swiftui
Color("dagrun/bg/sunken")
token
text.primary
#0A0A0A ↔ #F5F2EA
css
var(--color-text-primary)
swiftui
Color("dagrun/text/primary")
token
text.muted
rgba(10,10,10,0.62) ↔ rgba(245,242,234,0.62)
css
var(--color-text-muted)
swiftui
Color("dagrun/text/muted")
token
text.faint
rgba(10,10,10,0.38) ↔ rgba(245,242,234,0.38)
css
var(--color-text-faint)
swiftui
Color("dagrun/text/faint")
token
border
rgba(10,10,10,0.10) ↔ rgba(245,242,234,0.10)
css
var(--color-border)
swiftui
Color("dagrun/border")
token
border.strong
rgba(10,10,10,0.22) ↔ rgba(245,242,234,0.22)
css
var(--color-border-strong)
swiftui
Color("dagrun/border/strong")
token
accent
#FF4D1F ↔ #FF4D1F
css
var(--color-accent)
swiftui
Color("dagrun/accent")
token
success
#2E7D32 ↔ #7FC98A
css
var(--color-success)
swiftui
Color("dagrun/success")
token
warning
#C86B00 ↔ #E6A04D
css
var(--color-warning)
swiftui
Color("dagrun/warning")
token
danger
#C22E2E ↔ #E85A5A
css
var(--color-danger)
swiftui
Color("dagrun/danger")
swiftui
// Create Assets.xcassets > ColorSet entries named exactly:
//   dagrun/bg,  dagrun/bg/raised,  dagrun/bg/sunken,
//   dagrun/text/primary,  dagrun/text/muted,  dagrun/text/faint,
//   dagrun/border,  dagrun/border/strong,
//   dagrun/accent,  dagrun/success,  dagrun/warning,  dagrun/danger
//
// For each, set "Appearances: Any, Light, Dark" and paste the hex.
//
// Then in SwiftUI:
Color.dagrunBg
Color.dagrunTextPrimary
Color.dagrunAccent
  .opacity(0.12) // same pattern as the accent badge tint

02 · Spacing

2 / 4 / 8 ramp.

Eleven stops from 0 to 96px. Mac convention uses 8pt grid — the ramp stays compatible. Always refer by step number (space.5), not the literal px.

token
space.0
0px
css
padding: var(--space-0); /* 0px */
swiftui
.padding(0)
token
space.1
2px
css
padding: var(--space-1); /* 2px */
swiftui
.padding(2)
token
space.2
4px
css
padding: var(--space-2); /* 4px */
swiftui
.padding(4)
token
space.3
8px
css
padding: var(--space-3); /* 8px */
swiftui
.padding(8)
token
space.4
12px
css
padding: var(--space-4); /* 12px */
swiftui
.padding(12)
token
space.5
16px
css
padding: var(--space-5); /* 16px */
swiftui
.padding(16)
token
space.6
24px
css
padding: var(--space-6); /* 24px */
swiftui
.padding(24)
token
space.7
32px
css
padding: var(--space-7); /* 32px */
swiftui
.padding(32)
token
space.8
48px
css
padding: var(--space-8); /* 48px */
swiftui
.padding(48)
token
space.9
64px
css
padding: var(--space-9); /* 64px */
swiftui
.padding(64)
token
space.10
96px
css
padding: var(--space-10); /* 96px */
swiftui
.padding(96)

03 · Radius

Seven corners.

token
radius.none
0px
css
border-radius: var(--radius-none);
swiftui
.clipShape(RoundedRectangle(cornerRadius: 0, style: .continuous))
token
radius.xs
2px
css
border-radius: var(--radius-xs);
swiftui
.clipShape(RoundedRectangle(cornerRadius: 2, style: .continuous))
token
radius.sm
4px
css
border-radius: var(--radius-sm);
swiftui
.clipShape(RoundedRectangle(cornerRadius: 4, style: .continuous))
token
radius.md
8px
css
border-radius: var(--radius-md);
swiftui
.clipShape(RoundedRectangle(cornerRadius: 8, style: .continuous))
token
radius.lg
12px
css
border-radius: var(--radius-lg);
swiftui
.clipShape(RoundedRectangle(cornerRadius: 12, style: .continuous))
token
radius.xl
20px
css
border-radius: var(--radius-xl);
swiftui
.clipShape(RoundedRectangle(cornerRadius: 20, style: .continuous))
token
radius.pill
9999 (pill)
css
border-radius: var(--radius-pill);
swiftui
.clipShape(RoundedRectangle(cornerRadius: 32, style: .continuous))

Note: SwiftUI .continuous corners match macOS squircles. Always prefer RoundedRectangle(…, style: .continuous) over the default .cornerRadius(…).


04 · Elevation · shadow

Five steps.

shadow.xs
shadow.sm
shadow.md
shadow.lg
shadow.xl
swiftui
// Sources/AgentOSApp/DesignSystem/Shadow.swift
import SwiftUI

enum DagrunElevation: CaseIterable {
    case xs, sm, md, lg, xl
}

extension View {
    @ViewBuilder
    func dagrunShadow(_ level: DagrunElevation) -> some View {
        switch level {
        case .xs: self.shadow(color: .black.opacity(0.06), radius: 2,  x: 0, y: 1)
        case .sm: self.shadow(color: .black.opacity(0.06), radius: 4,  x: 0, y: 2)
                       .shadow(color: .black.opacity(0.08), radius: 2,  x: 0, y: 1)
        case .md: self.shadow(color: .black.opacity(0.08), radius: 12, x: 0, y: 4)
                       .shadow(color: .black.opacity(0.06), radius: 4,  x: 0, y: 2)
        case .lg: self.shadow(color: .black.opacity(0.10), radius: 32, x: 0, y: 12)
                       .shadow(color: .black.opacity(0.06), radius: 8,  x: 0, y: 4)
        case .xl: self.shadow(color: .black.opacity(0.14), radius: 64, x: 0, y: 24)
                       .shadow(color: .black.opacity(0.08), radius: 16, x: 0, y: 8)
        }
    }
}

// Usage:
MyCard()
    .background(.dagrunBgRaised, in: RoundedRectangle(cornerRadius: 10, style: .continuous))
    .dagrunShadow(.md)

05 · Motion

Four curves.

Duration is the first decision; curve is the second. Default to base. Use spring only for moments that should feel physical — drawer open, approval accepted.

token
motion.fast
120ms cubic-bezier(0.2,0,0,1)
css
transition: transform var(--motion-fast);
swiftui
.animation(.easeOut(duration: 0.12), value: …)
token
motion.base
200ms cubic-bezier(0.2,0,0,1)
css
transition: transform var(--motion-base);
swiftui
.animation(.easeOut(duration: 0.20), value: …)
token
motion.slow
360ms cubic-bezier(0.2,0,0,1)
css
transition: transform var(--motion-slow);
swiftui
.animation(.easeOut(duration: 0.36), value: …)
token
motion.spring
420ms cubic-bezier(0.34,1.56,0.64,1)
css
transition: transform var(--motion-spring);
swiftui
.animation(.interpolatingSpring(stiffness: 260, damping: 20), value: …)
swiftui
// Sources/AgentOSApp/DesignSystem/Motion.swift
import SwiftUI

extension Animation {
    static let dagrunFast   = Animation.easeOut(duration: 0.12)
    static let dagrunBase   = Animation.easeOut(duration: 0.20)
    static let dagrunSlow   = Animation.easeOut(duration: 0.36)
    static let dagrunSpring = Animation
        .interpolatingSpring(stiffness: 260, damping: 20)
}

// Usage:
.animation(.dagrunBase, value: isExpanded)

06 · Type scale

Size ramp.

token
size.xs
11px / 11pt
Aa
css
font-size: 11px;
swiftui
.font(.dagrunBody(11))
token
size.sm
12px / 12pt
Aa
css
font-size: 12px;
swiftui
.font(.dagrunBody(12))
token
size.base
14px / 14pt
Aa
css
font-size: 14px;
swiftui
.font(.dagrunBody(14))
token
size.md
15px / 15pt
Aa
css
font-size: 15px;
swiftui
.font(.dagrunBody(15))
token
size.lg
18px / 18pt
Aa
css
font-size: 18px;
swiftui
.font(.dagrunBody(18))
token
size.xl
24px / 24pt
Aa
css
font-size: 24px;
swiftui
.font(.dagrunBody(24))
token
size.2xl
32px / 32pt
Aa
css
font-size: 32px;
swiftui
.font(.dagrunBody(32))
token
size.3xl
48px / 48pt
Aa
css
font-size: 48px;
swiftui
.font(.dagrunBody(48))
token
size.4xl
72px / 72pt
Aa
css
font-size: 72px;
swiftui
.font(.dagrunBody(72))

07 · Export

One canonical token file.

Source of truth is src/lib/tokens.ts on this repo. The CSS variables are generated into globals.css. For SwiftUI, the asset catalog is the source — see each section above for the exact key names.

typescript
// src/lib/tokens.ts — TS + React (web)
import { palette, light, dark, tokens } from "@/lib/tokens";

// src/app/globals.css — CSS custom properties
// --color-paper, --color-ink, --color-signal, --font-display, ...

// Swift side:
// Assets.xcassets       → colors (light+dark)
// DesignSystem/         → Color, Font, Animation, Shadow extensions
// Resources/Fonts/*.ttf → Inter Tight, Inter, JetBrains Mono
// Info.plist            → ATSApplicationFontsPath = "Fonts"