Skip to content

Repository files navigation

cth-design

The shared visual identity for tanghoong.com and every sub-domain, published at design.tanghoong.com.

One green, one typeface, one set of rules — the mark, the colour, the spacing and the motion, decided once and reused everywhere. The CSS files in assets/css/ are the artefact other repos consume; the pages are live specimens of them.

Quick reference

I want to… Go to
Start a new sub-domain template/ — copy index.html, it is already wired
Point an agent at the system llms.txt — the whole spec, one fetch
Pin the rules inside a repo pages/prompt.html — a CLAUDE.md block
Change a colour or a size assets/css/tokens.css — and nowhere else
Use the mark correctly pages/brand.html
Check a page follows the system node scripts/conform.mjs <file>
Check the repos that consume it node scripts/drift.mjs
See what changed CHANGELOG.md
Regenerate the chart ramp node scripts/ramp.mjs <n>

Layout of the repo

llms.txt          the whole system as one plain-text spec, for agents
template/         a working starter page for a new sub-domain
favicon.svg       the site mark — the master every icon is generated from
assets/css/       the design system — this is what other repos consume
assets/js/        theme toggle, nav sheet and menus, docs-site chrome
pages/            the reference pages
index.html        overview, the agent path, and the reference index
404.html          not-found page
_headers          cache and CORS policy (both Cloudflare flows)
wrangler.jsonc    Workers Builds config — only used if asked for a deploy command

The CSS layers

Link them in this order. Order matters: tokens must resolve before anything references them, and utilities come last so they can win.

File What it holds
tokens.css Every colour, size, radius, shadow and duration. The single source of truth.
base.css Reset and element defaults. Unclassed HTML already looks right.
layout.css Container, sections, header, footer, grids, sidebars, hero.
components.css Buttons, chips, badges, cards, panels, notes, stats, rows, tables, tabs.
forms.css Fields, labels, validation, checkboxes, radios, switches.
overlays.css Modal, drawer, menu, tooltip, toast, accordion, nav sheet.
content.css Long-form prose, quotes, code, steps, print.
utilities.css Small single-purpose classes.
docs.css This site only. Specimen frames and swatches. Never ship it.

The reference pages

# Page Covers
01 Logo & identity Construction geometry, the fixed colour pair, sizes, clear space, favicon set
02 Foundations Surfaces, ink, accent, status, type, space, radius, shadow, motion, focus, themes
03 Layout Container, section banding, header, footer, grids, sidebars, breakpoints
04 Components Buttons, chips, badges, cards, panels, notes, stats, rows, tables, lists, tabs
05 Forms Inputs, validation, choices, switches, file drops, form layout
06 Overlays Modals, drawers, menus, nav sheet, tooltips, toasts, accordions
07 Loading & motion Skeletons, spinners, async states, the sanctioned animation list, title convention
08 Content & prose Article typography, leads, quotes, code, steps, measure, print
09 SVG & data Icons, the chart ramp, and seven charting idioms with live specimens
10 Patterns Whole page compositions — hero, work index, case study, CTA band
11 Agent prompt The block to paste into a repo's CLAUDE.md

Starting a new sub-domain

See template/README.md for the full walkthrough. In short: copy assets/css/ (minus docs.css), the icon set, and template/index.html; then change the meta block, the wordmark and the nav links.

Running locally

No build step — the CSS files are the artefact. Serve the folder with anything:

npx http-server -p 8099 -c-1

-c-1 disables caching, so edits show on refresh.

Deploying

Static hosting, no build step. Cloudflare now has two flows — classic Pages, and Workers Builds which asks for a deploy command (npx wrangler deploy). Both are covered in DEPLOY.md, and wrangler.jsonc for the second is committed. _headers sets the cache policy for Cloudflare Pages and allows cross-origin reads of assets/ and llms.txt, so another sub-domain can link the stylesheets directly rather than vendoring a copy that will drift.

Checking your work

Three dependency-free scripts. Full notes in scripts/README.md.

node scripts/conform.mjs index.html pages --fail   # does the page follow the system?
node scripts/contrast.mjs --fail                   # do the tokens still pass WCAG?
node scripts/drift.mjs --fail                      # has a consuming repo gone stale?

This is how you check an agent's output: point it at llms.txt, let it write the page, then run conform.mjs over the result. It enforces only what is documented — if a rule is not in llms.txt or on a reference page, it does not belong in the script. drift.mjs is the other direction: it checks the repos that consume this one, where a copied token value or contrast figure goes stale without anyone noticing. None of the three can see computed styles or runtime behaviour, so they are a first pass, not a substitute for opening the page in both themes and tabbing through it.

Editing the system

  • A colour, size or duration change goes in tokens.css and nowhere else.
  • A new component goes in the layer file it belongs to, with a comment saying what it is for and when not to use it.
  • Update llms.txt in the same commit as any token or class change — it is a description of the CSS, not a second source of truth, and agents read it instead of the pages. Bump the version line at the top.
  • Regenerate the raster icons from favicon.svg with the ImageMagick commands on the brand page. Never hand-edit a generated file.
  • Every page's header and footer are inlined rather than templated. That is deliberate: the chrome is itself a specimen, and a reference site should show its own markup in source. If you change the header, change it in all eleven files and in template/index.html.

Regenerating the chart ramp

node scripts/ramp.mjs         # the six steps in tokens.css
node scripts/ramp.mjs 12 --json

It reads --c-from and --c-to from tokens.css and interpolates in OKLab. Not sRGB — that is the obvious choice and it produces perceptually uneven steps that bunch at one end. See the comment at the top of the script for what that cost the first time.

About

My digital design styling guide

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages