Skip to content

Design System

Karthik P edited this page Oct 27, 2026 · 7 revisions

This section describes how the workclock website looks, reads and behaves: the design tokens, the components built from them, the page structure and the rules for writing. It is the reference for anyone building or changing the site in website/, and the log of every design decision the owner has taken.

It is not the library's specification. What workclock computes is defined in DESIGN.md and summarised in Design and ADRs.

Who the site is for

Two readers, served by the same pages:

  • Developers deciding whether to use workclock, or using it. They want to see what it does, check that it is correct, and copy an example that runs.
  • Their coding agents, which read the docs to write code that calls workclock. They need self-contained pages, plain Markdown and exact type names. Agent Experience covers what the site provides for them.

The site has one job for both: show that the library is correct and useful, with evidence the reader can check.

Principles

  1. Show the arithmetic. Every claim points at something the reader can run or check: an example ID in DESIGN.md, a test, the live demo, or benchmarks/RESULTS.md. A claim without a link is rewritten until it has one, or removed.
  2. Quiet by default, amber for due. The site is monochrome cool grey. Amber marks five things only: the due marker, the active tab, the current page, the logo dot and warning callouts. Amber anywhere else is a bug. See Color.
  3. Numbers line up. Every time, duration and benchmark figure uses tabular figures. Numeric table columns are right-aligned with one unit per column. Times are 24-hour HH:MM. See Typography.
  4. Same answer in every language. Examples use one scenario, the London support desk from the README, and show Rust, Python and JavaScript reaching the same instant: due at 09:30 on 30 December 2026. See Writing Style.
  5. Every page stands alone. Full imports in every sample, full type names, no "see above". This serves readers who land from search and agents that fetch one page.
  6. Nothing to accept. No analytics, no cookies, no consent banner, and no request to a third party when a page loads. Fonts are self-hosted at build time. See Website Tech Stack.

Pages in this section

Page What it covers
Design Tokens Every token value and how it maps to CSS variables, Tailwind v4 @theme and Fumadocs UI. The source of truth for values.
Color Palette, the amber rule, status colours and contrast ratios.
Typography Instrument Sans and JetBrains Mono, the type scale, tabular figures.
Layout and Spacing Spacing scale, widths, breakpoints, page grids, stacking order.
Shape Elevation and Motion Radii, borders, shadows, the one animated moment, reduced motion.
Icons and Illustration Icons, language names instead of logos, diagrams, social images.
Components Every UI component, including the week strip.
Docs Site Structure Navigation, URLs, page list and templates, the 404 page.
Landing Page The home page, section by section, with a wireframe.
Agent Experience llms.txt, Markdown versions of pages, page actions, the agent prompt.
Accessibility The WCAG 2.2 AA checklist and how to test it.
Writing Style Voice, terms, times and dates, code samples.
Brand Name, descriptions, logo and brand files.
Website Tech Stack Packages, folder layout, configuration, deploy, CI.

How design changes are made

The owner decides everything visual. Nothing visual changes on the site without the owner's choice.

  1. Open an issue describing the problem, not the solution.
  2. Show options as pictures. Two or three mockups, light and dark, side by side. Each option names the tokens it would change.
  3. The owner chooses. Record the choice in the decision log below, with the options and the reason.
  4. Tokens first. Change the values on Design Tokens before touching components. A component never hard-codes a colour, size or duration.
  5. Update the pages that describe the area, and mark anything still undecided Proposed.
  6. Check accessibility against Accessibility before merging.

A design change follows the repository's usual rules: a branch, Conventional Commits and one PR per concern (CONTRIBUTING.md).

Decision log

Newest first. Owner choices were made from the options shown on 2026-10-24: the "pick a stack and a look" comparison page, later option pages, and the Canva design "Workclock logo concepts". Rows whose "Why" starts with "Basis:" are technical calls made on evidence, not owner choices; the owner can reopen them like any other.

Date Decision Options shown Chosen Why
2026-10-27 Hosting GitHub Pages project URL; custom domain GitHub Pages at https://workclock.karthik.nz/, served from the domain root (no basePath) Replaces the project URL. A custom domain removes the /workclock prefix from every path.
2026-10-25 Per-page share cards The proposed layout on Icons and Illustration; the same with the page description under the title The proposed layout, as rendered Approved from rendered cards. Drawn with next/og from the static Instrument Sans Regular and SemiBold TTFs in website/assets/fonts/, taken from the typeface's own repository with its OFL (Basis: next/og reads TTF, OTF and WOFF, not WOFF2).
2026-10-25 Playground layout Inputs left with the strip right; inputs above like the landing demo Inputs left, strip right; code tabs below; stacks on phones Approved from wireframes.
2026-10-25 Playground inputs Beyond the landing demo's: working days, break, holidays, time zone, each optional All four Every input a Schedule takes, except per-rule time zones.
2026-10-25 404 page helper A static page; a script that shows the requested path and suggests the page for a missing .md Static Nothing on the 404 page needs JavaScript beyond the search button.
2026-10-25 Home share image Re-export from Canva at 1200 × 630; scale the approved 1280 × 640 card Scaled to 1200 × 600 and centred on 1200 × 630 white Basis: the card's background is white and its margins stay over 75 px; the Canva free plan has no resizes left.
2026-10-25 Reference parameter tables Fumadocs TypeTable; Markdown tables Markdown tables Basis: the .md version of each page stays a plain table with no conversion code, and the decided "hand-written tables" are met either way.
2026-10-24 Markdown page URLs Next to the page (/docs/install.md), copied by scripts/copy-markdown.mjs; Fumadocs' /llms.mdx/docs/<slug>/content.md Next to the page The address an agent would guess, as llmstxt.org suggests.
2026-10-24 Agent features llms.txt header; the agent prompt on Install; build checks; the text/markdown alternate link; a landing index.md All but the landing index.md See Agent Experience. The Markdown shapes tabs, callouts, accordions and cards with a remark plugin (Basis: replaceSource in fumadocs-core 16.17.8).
2026-10-24 Docs page list As planned on Docs Site Structure; the same without the two added pages As planned, including Inputs and precision and the workclock.compat reference The page list, URLs and templates there are approved.
2026-10-24 Repository files in the docs Include them; copy the text Include: <RepoFile> around Fumadocs' <include>, which drops the file's H1 and points its relative links at GitHub The changelog, benchmark results and migration lists cannot drift from the repository.
2026-10-24 Reference pages Hand-written tables; generated with fumadocs-typescript and fumadocs-python Hand-written, checked in review No new packages and no Python build step in CI.
2026-10-24 Header links Fumadocs links; a site component A small NavLink component Basis: Fumadocs marks an active header link with data-active, which in the sidebar drawer picked up the amber current-page bar; the current section must be ink (Components).
2026-10-24 Landing demo controls SLA hours 1 to 40; opened day and time; editable working hours; the call it made All four Shown as options with previews. Times are HH:MM text fields (Basis: <input type="time"> shows a 12-hour clock in some locales); the opened day is a select, so controls stay outside the drawing. See Landing Page.
2026-10-24 Week strip range Opened day to due day, 7 to 14 days; always 7 days Opened to due, 7 to 14 days, a chevron past 14 Long SLAs still end on the strip.
2026-10-24 Benchmarks on the landing page Numbers read at build time; link only The single medians for Rust, JavaScript, Python and businesstimedelta 1.0.1, read from benchmarks/RESULTS.md at build time, with the date and CPU Evidence on the page, nothing typed by hand; the build fails if the file's format changes.
2026-10-24 "Coming from businesstimedelta?" link Yes; no Yes, under the install commands, to the migration note Python users find the one-line migration quickly.
2026-10-24 Header logo size A. Mark 24 px, wordmark 18 px. B. Mark 20 px, wordmark 18 px. C. Mark 28 px, wordmark 20 px. Shown in the built header, light and dark. A Keeps the six-bar mark at the 24 px minimum; matches the review page. See Brand.
2026-10-24 Build-time week strips Node.js entry; serverExternalPackages; workclock/web initialised with the .wasm bytes; committed JSON workclock/web with init({ module_or_path: <bytes read from node_modules/workclock/pkg/web/workclock_bg.wasm> }) in a server component Basis: prototype on 2026-10-24. Turbopack rewrites __dirname, so the Node.js entry cannot find its .wasm, and serverExternalPackages does not apply to a package linked with file:../js. In the browser, Turbopack copies the .wasm to _next/static/media/ with the base path, so no copy step is needed. See Website Tech Stack.
2026-10-24 "Open in" link formats Fumadocs' formats; other query names https://claude.ai/new?q=<prompt> and https://chatgpt.com/?prompt=<prompt>&hints=search. Check both before launch. Basis: fumadocs-ui 16.17.8, layouts/shared/page-actions.js. Neither service documents the format. See Agent Experience.
2026-10-24 Language marks Logos; text labels Text labels. No Rust, Python or JavaScript logos. Basis: the Rust, PSF, TypeScript and GitHub trademark rules on Icons and Illustration.
2026-10-24 Trailing slashes On; off trailingSlash: true Basis: each page becomes x/index.html, which GitHub Pages serves at /x/ (Next.js: trailingSlash).
2026-10-24 Code themes Fumadocs default (github-light / github-dark); github-light-default / github-dark-default; github-light-high-contrast / github-dark-default; others github-light-high-contrast (light), github-dark-default (dark) Basis: the only measured pair where every syntax colour reaches 4.5:1 on surface (Color).
2026-10-24 Accessibility fixes Required for WCAG 2.2 AA Form-control borders in text-3; a 2 px bg outline on the due marker; a text label on every week-strip row; Fumadocs' d theme hotkey off (theme={{ hotKey: false }}); a skip link; one global visible focus style Basis: WCAG 2.2 SC 1.4.11, 2.1.4, 2.4.1 and 2.4.7 (Accessibility).
2026-10-24 Dialog overlay Fumadocs default (black at 20%); a token Token overlay: light rgb(15 23 41 / .2), dark rgb(0 0 0 / .5) Basis: Fumadocs' default alpha in light (css/lib/default-colors.css), tinted with our ink; dark matches the dark popover shadow.
2026-10-24 Mobile sidebar breakpoint 768 px; 1024 px Drawer below 768 px Basis: fumadocs-ui 16.17.8 Notebook sidebar is max-md:hidden.
2026-10-24 Extras Approve or leave out, each Approved: a website build job in CI that counts toward ci-ok; accessibility checks with axe and Playwright (@axe-core/playwright, @playwright/test, dev only); a link check with the lychee GitHub Action, pinned by SHA; a "Docs problem" issue form, .github/ISSUE_TEMPLATE/docs.yml A broken site, an accessibility regression or a dead link fails the PR instead of reaching readers. See Website Tech Stack.
2026-10-24 Social images Per-page cards plus one Canva card; one Canva card everywhere Per-page cards drawn at build time with next/og (needs a committed Instrument Sans TTF, which the OFL allows), plus one Canva card for the home page and the GitHub social preview A shared docs link shows the page's own title. See Icons and Illustration.
2026-10-24 Prose width 600 px; 640 px; 720 px 640 px, about 85 characters a line Comfortable line length without wasting the content column. See Layout and Spacing.
2026-10-24 Warning callouts Amber; neutral with an icon Amber: bar and icon accent, title accent-text Warnings stay distinct from notes. Amber's allowed uses are now five (Color).
2026-10-24 Docs layout Fumadocs Notebook layout with a top header; default Docs layout (navigation in the sidebar only) Notebook layout, nav: { mode: 'top' } A full-width header over sidebar, content and table of contents, like nextjs.org/docs. See Layout and Spacing.
2026-10-24 Demo source Built from the repository's js/ folder; published npm package only The site builds the workclock package from js/ The demo matches the commit it is built from and works before 0.1.0. See Website Tech Stack.
2026-10-24 Third code tab label JavaScript; TypeScript JavaScript, everywhere: tabs, cards, badges, the quickstart (/docs/quickstart/javascript/) Matches the README. The package ships its types, so TypeScript readers are covered.
2026-10-24 Landing headline A. "Add 8 working hours. Land on Wednesday at 09:30." B. "When is it due, counting only working hours?" C. "Working hours, breaks, holidays and time zones in one calculation." A Shows the answer, and matches the demo's default state. It must change if the demo's defaults change. See Landing Page.
2026-10-24 Docs framework Fumadocs on Next.js; Rspress 2; Astro Starlight. Also researched: Docusaurus, VitePress, Nextra, Mintlify (cannot be self-hosted on a free plan). Fumadocs (fumadocs-core, fumadocs-ui, fumadocs-mdx) on Next.js, static export (output: 'export') Closest to the reference look; the landing page and the live demo are ordinary React components; llms.txt and per-page Markdown are built in. Cost accepted: the most moving parts, and a static export under a sub-path needs care.
2026-10-24 Hosting GitHub Pages project URL; custom domain GitHub Pages at https://karthik-beta.github.io/workclock/ (basePath: '/workclock'), no custom domain Free, next to the code, no server.
2026-10-24 Site folder No alternatives shown website/ at the repository root with its own package.json; never shipped to library users Keeps site dependencies out of the published packages.
2026-10-24 Site packages Core set; core plus API page generators; review each first Core set: next, react, react-dom, fumadocs-core, fumadocs-ui, fumadocs-mdx, tailwindcss v4, @tailwindcss/postcss, typescript, @types/*, lucide-react (already a fumadocs-ui dependency) A short, known list. Anything else needs the owner's approval first.
2026-10-24 Visual direction A. Timetable: quiet, cool greys, one typeface, amber only for "due" (from nextjs.org/docs). B. Night shift: dark first, working hours lit like office windows, serif landing headline (from resend.com). C. Timesheet: editorial, serif headings, ledger-green paper, carmine "stamp" for the due time. A. Timetable: precise and quiet like a railway timetable. Cool greys, monochrome, one typeface, tight headings, aligned numbers, one amber signal. Matches what the library does: exact times, nothing decorative. B was the most likely to look generic.
2026-10-24 Typeface Instrument Sans; Geist; IBM Plex Sans Instrument Sans (text and headings), JetBrains Mono (code). Both SIL OFL 1.1, self-hosted via next/font/google. Crisp and not tied to another brand. Geist is Vercel's face; IBM Plex Sans reads as corporate.
2026-10-24 Accent colour Amber; red; blue; green Amber, picked from a mockup at #D98A00. The site uses #C27C00 in light mode; the logo keeps #D98A00. Amber reads as "attention" without meaning "error". Red means danger, blue is link blue, green means success. Why the light value is darker: Color.
2026-10-24 Theme Follow system; light first; dark first Follows the visitor's OS setting, with a light/dark toggle Respects the visitor's setting and lets them override it.
2026-10-24 Landing hero Live demo; static picture and code A live demo running the real workclock package, built from the repository, as WebAssembly in the browser: a week strip where the visitor changes the SLA, hours and holidays and watches the due time move Shows the library working instead of describing it. See Landing Page.
2026-10-24 Logo Three Canva concepts: a clock outline with hands; a week of bars labelled Monday to Sunday; bars clipped to a circle with an amber dot. Then a refined round. "Bars + amber dot": six working-hour bars clipped to a circle; the fourth stops short and is followed by an amber dot, the due time. Lowercase wordmark "workclock" in Instrument Sans. Draws the library's model (blocks of working time) and its answer (the due instant). See Brand.
2026-10-24 Favicon Mark only with four bars; bars inside a ring Four bars clipped to a circle, the third short and followed by the dot. One SVG that switches colours with prefers-color-scheme. Six bars are too thin at 16 px; four keep each bar about 2.75 px tall.
2026-10-24 Analytics None; cookieless counter (GoatCounter) None. No cookies, no banner. Nothing to consent to, nothing to maintain.
2026-10-24 Coding agents as readers Address agents and ship agent features; agent features with neutral wording; no agent features Allow for the audience: the site may address coding agents as readers and ship agent features (llms.txt, llms-full.txt, a Markdown version of every page, "Copy page", "Open in Claude", "Open in ChatGPT") Many readers reach docs through an agent. See Agent Experience.

Clone this wiki locally