Every visual decision routes through a CSS custom property. Designers and developers never write a hex value, a font name, or a magic number — they write a token. The names below are the ones that ship in styles.css.
| Token | Value | Usage |
|---|---|---|
| --bg | #FAF7F2 | Page |
| --surface | #F2EDE4 | Cards |
| --ink | #1A1410 | Type / fill |
| --ink-sec | #6B5E50 | Secondary |
| --gold | #B8974A | Accent / rules |
| --rust | #C4623A | Emphasis |
| --white | #FFFFFF | Modals |
| Token | Family | Notes |
|---|---|---|
| --f-display | Cormorant Garamond | 300 · 400 · italic |
| --f-body | DM Sans | Söhne substitute |
| --f-mono | JetBrains Mono | Data · labels |
| --f-thai | IBM Plex Sans Thai | TH body +2px |
| display-xl | 96 / 0.96 / −2.5% | Hero only |
| display-l | 56 / 1.0 / −1.5% | Section head |
| body-lg | 19 / 1.65 | Essay |
| eyebrow | 11 / +18% / UC | Labels |
The visible vocabulary of the site. Every atom carries: default, hover, active, disabled, focus. Every atom is built with tokens; nothing is one-off. If you find yourself reaching for a new value, look in the system first.
Inputs are framed in hairline, focused in gold, never filled. Help text is monospace. Validation is rust, never red. The booking calendar is the single richest form pattern — see the live prototype for its full state machine.
Three patterns carry the site: the editorial hero, the section header, and the essay column. Each has a fixed rhythm. Stick to the pattern; resist the urge to invent.
Three numbers I track weekly across the buildings I cover.
There is a particular hour in Sathorn — between the night-market sweep and the first embassy car of the day — when the soi feels almost private. The street sweepers have finished. The salt-pork porridge stall on Soi 12 is on its second pot. You can smell jasmine rice from the tower above the 7-Eleven, and pandan from the monks' alms round one block south.
"I know which lifts are slow on Mondays."
| Locale | Format | Example |
|---|---|---|
| THB | ฿0.00M | ฿28.50M |
| USD | $0.0k | $803.7k |
| CNY | ¥0.0k | ¥5,814.0k |
| JPY | ¥0k | ¥122,550k |
Movement is paper-coming-into-focus, not a Hollywood reveal. The signature curve is cubic-bezier(0.16, 1, 0.3, 1) — a long tail. Durations: 200–280ms for hovers, 600–900ms for reveals, 800ms for the page load fade-in.
| Element | Trigger | Motion | Duration |
|---|---|---|---|
| Page | Load | Fade from white → paper | 800ms ease-out |
| Essay section | In view | Translate-Y 20px + fade | 800ms ease-out |
| Pull quote | In view | Gold rule grows down (scaleY) | 600ms ease-out |
| Photo | Hover | Saturate 0.7 → 1.0 | 700ms ease-out |
| Button (primary) | Hover | Gold fill slides up from base | 380ms ease-out |
| Nav link | Hover | Gold underline scaleX 0 → 1 | 280ms ease-out |
| Booking card | Essay 80% scrolled | Slide up + fade | 600ms ease-out |
| Language toggle | Switch | Cross-fade content | 280ms ease-out |
Icons are rare. When they appear they are 1.4px stroke, no fills, 24×24 frame, drawn on a square grid. Decorative ornaments and emoji are not in the system. The wordmark does the heavy lifting.