Design
The rules this site sets itself by, and why they were settled that way.
A lab that argues for measurement should measure its own screen. The values and contrast figures on this page are read from the live stylesheet at build time, and the decisions below are a record of what was run into while building it.
Two grounds
Day and dark. The visitor's system setting decides, and an explicit choice wins over it. The accent is the same yellow in both — a colour that changes with the ground is not one colour. What changes is that yellow when it has to carry text.
Day
- ground#f7f6f2
- card#fff
- soft#eae8df
- hairline#b0b0a1
- muted#4a4a41
- ink#14140f
- accent#ffc600
- accent as text#7d5c00
- on accent#0f0f0f
- beat#1a5f58
body 17.08:1 / muted 8.27:1 / on accent 12.17:1
Dark
- ground#0f0f0f
- card#1a1918
- soft#161615
- hairline#333130
- muted#9a9691
- ink#f1eeea
- accent#ffc600
- accent as text#ffc600
- on accent#0f0f0f
- beat#6fb3a6
body 16.57:1 / muted 6.52:1 / on accent 12.17:1
Type
Cormorant Garamond + Gowun Batang / 300 / display
Pretendard / 400 / body
IBM Plex Mono / the machine-readable margins
Sizes
Five steps, no more. The figures are desktop then phone, and every step grows on a phone, where the same size reads smaller.
Space
The homepage and all site pages share the same content width. Side margins are at least 7% on desktop, 5% at widths up to 1,100px, and 24px at widths up to 760px. Long text has a separate reading width.
- 1080pxmaximum content width
- 7vw / 24pxdesktop / mobile margins
- 80pxbetween sections
- 1pxhairline, used 48 times
Steps
Twelve steps, and nothing in between. The small ones pad the inside of things; the large ones are the breath between sections. The figures are desktop then phone, and only the large steps shrink on a phone — what a narrow screen needs less of is air between sections, not padding inside a button.
Shape
The mark
The drawn circle is the state as measured; the filled one is the state a design aims for. Everything the lab does is the distance between them.
Decisions
Latin display sizes are not reused for Hangul
A 96px Latin headline, copied over, landed far heavier in Hangul, which fills its em where Latin leaves air. Titles came down from 124px to 82px.
No monospace on lines that mix scripts
No monospace face carries Hangul, so a participant list split its typography mid-line, with only the Latin names landing on the mono face.
Text on the accent comes from a token
The accent is dark by day and light on the dark ground, so a button with white text baked in measured 1.9:1 on one of them.
One accent-filled surface per screen
Colour means something only while it stays rare. Here it marks the present state, the state a design aims for, and the invitation to join.
Contrast is measured, not claimed
The figures here are computed at build time from the stylesheet itself, so the document cannot drift from the site.
Every step grows on a phone
The same size reads smaller at arm's length. Text under 15px fell from 77% to 14%, and what is left there is tags and dates.
The hours
What this site cost to build. The columns are hands-on hours: reading, deciding, typing. Time spent waiting is not in them. Posting news and correcting a member is running the site rather than building it, so it is counted separately: 4.0 hours of it.
- 29.0building, hours
- 4.0content, hours
- 470commits
- 46days with a commit
As a table
| Date | Building | Content | Wall-clock | Messages |
|---|---|---|---|---|
| 2026-08-21 | 0.28 | 0.0 | 0.21 | 14 |
| 2026-08-24 | 0.78 | 0.2 | 0.94 | 15 |
| 2026-08-25 | 4.57 | 1.22 | 6.44 | 71 |
| 2026-08-26 | 1.52 | 0.08 | 1.95 | 24 |
| 2026-08-27 | 1.0 | 0.46 | 1.39 | 18 |
| 2026-08-28 | 1.32 | 0.15 | 1.55 | 26 |
| 2026-08-29 | 1.02 | 0.1 | 1.49 | 22 |
| 2026-08-30 | 0.61 | 0.0 | 0.97 | 8 |
| 2026-08-31 | 2.3 | 0.24 | 2.68 | 33 |
| 2026-09-01 | 3.01 | 0.53 | 4.41 | 45 |
| 2026-09-02 | 0.63 | 0.0 | 0.9 | 18 |
| 2026-09-04 | 0.91 | 0.0 | 1.23 | 17 |
| 2026-09-06 | 0.42 | 0.08 | 0.79 | 8 |
| 2026-09-07 | 0.23 | 0.0 | 0.62 | 2 |
| 2026-09-08 | 1.28 | 0.3 | 1.93 | 23 |
| 2026-09-09 | 1.87 | 0.09 | 2.17 | 41 |
| 2026-09-10 | 0.13 | 0.0 | 0.41 | 4 |
| 2026-09-11 | 0.63 | 0.14 | 0.84 | 18 |
| 2026-09-12 | 1.33 | 0.19 | 1.43 | 44 |
| 2026-09-13 | 0.34 | 0.0 | 0.21 | 11 |
| 2026-09-14 | 0.61 | 0.0 | 0.65 | 14 |
| 2026-09-15 | 1.14 | 0.0 | 1.57 | 36 |
| 2026-09-16 | 0.51 | 0.0 | 0.72 | 11 |
| 2026-09-17 | 0.57 | 0.17 | 0.69 | 61 |
| 2026-09-18 | 1.42 | 0.0 | 1.19 | 78 |
| 2026-09-19 | 0.12 | 0.0 | 0.09 | 4 |
| 2026-09-20 | 0.44 | 0.0 | 0.38 | 9 |
2026-08-24 to 2026-10-15, over 675 messages. The commits and the span are read from git at build time like the other figures here. The hours are not: they are measured from working-session records that are not in the repository, so the build cannot recompute them; the date and method sit beside the numbers in data/buildlog.yml and scripts/measure_worklog.py takes the measurement again. A break longer than 15 minutes starts a new stretch of work, and a gap of more than 12 minutes between messages counts as stepping away. What separates building from content is the files the commits in a stretch touched. Content work never once formed a stretch of its own — it always rode along with building — so the content figure is apportioned by that commit mix rather than measured. As a check, all 470 commits fall inside a detected stretch.