s1t. design system · v2 · Japandi
00 · Principles

Paper against neon.

Open any modern SaaS: dark-blue cosmos, neon gradients, glass panels, glowing borders. Everything shouts "the future is here" — and ten minutes later your eyes are tired of that future.

I wanted the opposite. Warm paper, ink, one quiet accent — and geometry: simple glyphs, registration crosses, dimension lines. Like a good blueprint: nothing extra, every mark carries meaning. I consider this design system my own — it deliberately pushes back against neon and epicness.

Three decisions

python · config.py
ACCENT = "#5d7052"  # moss

Cozy is when the interface doesn't compete for your attention — it just lies at hand.

01 · Tokens · color
--paperpage background
--raisedcards, fields
--sunkencode, skeletons
--linehairline rules
--inktext
--softsecondary text
--faintmetadata
--accentochre · links, focus
--mossdone, active
--ochreattention, draft
--clayerror
--washaccent ~11% · selected

Dark theme is the same tokens, overridden in html[data-theme="dark"]. The dark accent is derived from the base via color-mix — never hand-picked.

02 · Tokens · misc
--serif   Literata          headings, longreads
--sans    Golos Text        interface
--mono    JetBrains Mono    dates, numbers, code, #id suffixes

--r-s 4px · --r-m 8px       corner radii
--measure 68ch              longread width (tweak 56-84)
--entry-pad 26px            feed density (tighter: 16px)
--grain .5                  paper grain 0..1
--page-w 1200px             container
--shadow                    one shadow, barely there — floating elements only
03 · Typography
.t-displayQuiet notes
.t-h1 · 34Real-time inference
.t-h2 · 23Latency budget
.t-h3 · 16 sansSkill group
body · 16 sansInterface text — Golos Text, calm and practical.
.prose · 17.5 serifLongread — Literata, like a page of a good book.
.t-overlineFresh posts
.t-meta · mono2026·06·10 · 8 min · nickname#7f3a
04 · Buttons and fields · states
<BaseButton>default · hover · disabled
<BaseField>default · focus · error · disabled

at least 3 characters.

radio · checkbox · selection
05 · Tags and statuses
<TagChip>default · hover · active(filter) · with counter
#rust #rust #realtime #ml 12 active building paused
06 · PostCard
<PostCard>feed: date on the left, title-link, excerpt, meta
····

second card is the loading state (.skeleton)

empty · error — feed state blocks
· · ·Nothing under this tag yet.
×Failed to load — try again.
07 · ReactionBar and PollWidget
<ReactionBar>default · hover · pressed (1 per voter_key)
<PollWidget>left: open, not voted · right: voted (live %)

What should I cover in depth?

open

One vote. Closes in a week.

72 votes · anonymous vote

What should I cover in depth?

open

One vote. Closes in a week.

72 votes · your vote is in.
08 · CommentThread
<CommentThread>registered (nickname#4·base36) · author · anon (nickname#12·hex) · hidden
M
mlops_enjoyer#7f3a2 days ago

Backpressure before the model — spot on. We only added the fallback after the second incident.

S
sense1tapo4ek#s1t0author2 days ago

Classic: the design doc gets written in the on-call's blood.

A
anon-kitten#a91f3c02d8e4anonyesterday

What do you monitor p99 with?

·
hidden by moderatoryesterday

Comment hidden (spam).

09 · Porting to Nuxt/Vue

One CSS file of tokens and components — s1t.css. Classes map to the components from design.md:

.pc        -> PostCard          .prose     -> PostBody
.cthread   -> CommentThread     .poll      -> PollWidget
.rbar      -> ReactionBar       .tag       -> TagChip
.field     -> BaseField         .btn       -> BaseButton
.state-block / .skeleton -> empty / loading / error states

themes:   html[data-theme="light|dark"]  (stored in a cookie for flash-free SSR)
a11y:     focus — outline 2px --accent; contrast pairs verified in both themes