A guest
Specimen text
Hi, we land late on Friday. Is self check-in still possible after midnight?
Thanks!
From the CentrOS iOS app
This page documents the design system every page of this site is built from: the CentrOS iOS app’s sky, clear Liquid Glass sections, iOS system colours and text styles, and its floating control layer. Every page loads two shared stylesheets with no build step: public/css/style.css, and public/css/sky.css (the sky’s gradient ground, shown before the first WebGL frame); the case-study pages and this page add a small page-local file from public/css/pages/. Every token value below is read live from public/css/style.css with getComputedStyle, and every specimen is the real markup.
5
When a new component is in doubt, it has to serve one of these.
Every value prints from getComputedStyle and follows the appearance you chose in the contact sheet. Literal colours live only in the token block at the top of style.css.
13
The iOS 26 system colours, exact. Dots, icons and tiles use them; text uses the AA-safe Tone colours below.
--blue--green--yellow--orange--red--purple--cyan--teal--mint--indigo--pink--brown--gray16
--label--label-2--label-2-sky--label-3--label-4--fill-1--fill-2--fill-3--fill-4--fill-quiet--separator--bg--bg-grouped-2--bg-elevated--bg-elevated-2--focus5
One meaning each (Tone.swift). The system colour marks dots and icons, --fg-* is the text colour and --wash-* the 16 % fill behind a chip.
--fg-action --fg-waiting --fg-settled --fg-caution --fg-stop 6
Each page lights the sky in its own hue with <body data-sky>. Show one here to watch this page’s sky, and the glass rims with it, cross-fade over 3.5 s. Reload to return to ash.
accent · HomeApp: Home. Blue, Tone.actionviolet · CentrOSApp: World. “Indigo: the night sky, not a purple”teal · AXEDApp: Activity. Cyanrose · Ask sheet only (never a page sky)App: Ask. “Amber: sitting at the fire”ash · Style guideApp: Kept out. Graystop · Not used as a pageApp: a draft a check refused. RedDark is the default; Light and Match device are in the contact sheet. Both previews re-declare the token block, so each value prints as that appearance resolves it.
Dark
--label--label-2--separator--fill-3--blue--green--yellow--orange--red--fg-action--glass-card-bgLight
--label--label-2--separator--fill-3--blue--green--yellow--orange--red--fg-action--glass-card-bg14
The system font (SF on Apple devices) in iOS text styles at the default Dynamic Type size, in rem so browser text size scales them. Sentence case, no uppercase, no italics: emphasis is weight. Sizes print as rendered here.
--t-large · · opens every page; grows to 52 px on wide screens--t-title1 · --t-title2 · · stat numbers--t-title3 · · card titles, intro claims--t-headline · · section headers, inline title, buttons--t-body · · prose; row titles at weight 500--t-callout · · bullets--t-subhead · · row subtitles, pills at 600--t-footnote · · row meta, header details--t-caption1 · · chips at 500--t-caption2 · --t-tab · · tab bar labels--font-mono · · the machine voice: footnote in mono--font-mail · · mail and quotes: 17/25.5 serifMeasured from the app at 1 pt = 1 CSS px. Each bar is drawn from its value and measured live; bars longer than the box are cut.
4
Concentric: a rounded thing inside another echoes its curve, so the inner radius is the outer one minus the inset.
Card
Radius , continuous in the app. A section is one card with hairlines, or cards apart with 10 px of sky between.
Sheet → group , inset : 42 − 16 = 26.
Tab bar → selected capsule , inset : 31 − 6 = 25.
Hit box (dashed) → visible capsule 32 px, from a 6 px transparent border. Every target is at least 44 × 44.
Content is the surface; controls float above it. No content sits inside a second pane of glass: wells inside cards use --fill-4.
5
Glass is used sparingly so content stays dominant: one clear layer for content, one regular layer for the controls above it. Values print for the current appearance.
.card--glass-card-bg --glass-card-filter content sections; the rim takes the page’s sky hue in dark, white in light; no shadow.glass--glass-ctl-bg --glass-ctl-filter tab bar, Contact circle, account capsule, back circle, Done.sheet--glass-sheet-bg --glass-sheet-filter the system sheet: neutral grey, dense enough that nothing bleeds under text.tabbar__thumb--tab-selected the selection is the lighter capsule, never a tint.topbar::before--edge-dim an 8 px blur plus a dim under the toolbar row, fading out 28 px belowA clear card. The sky shows through, blurred, with its hue intact; the rim is 1 px, lighter than the inside.
The back circle, the account capsule and a capsule, all .glass. They brighten and grow a little when pressed.
The real tab bar floats at the bottom of every page (top centre from 1024 px). This one is static; its tabs link back here and its mail circle starts an email.
A static sheet group. The real one is a native <dialog>: a floating bottom sheet on phones, a centred 540 px form sheet from 768 px.
A footer under a group, in footnote.
--bg-grouped-2) with no rim; controls, the sheet and the scroll edge turn opaque. The sky still shows between cards.CanvasText borders.backdrop-filter support: glass falls back to near-opaque fills.Every specimen is the real markup with the shared classes listed above it. Specimen ids are prefixed sg-, and links stay on this page unless they say otherwise.
.sec__head .sec__icon .sec__title .sec__detail .sec__intro .sec__foot
Needs you
3
An intro on the sky, in subheadline.
Symbol 20 px, title in headline, detail in footnote, all secondary label colour. On a page the title is an h2, or an h3 in a group.
.lt .lt__title .lt__sub .intro .intro__title .intro__text
An intro title states a section’s claim
Its text follows in subheadline, on the sky.
The large title is this page’s own heading above; once it scrolls under the toolbar row, the inline .topbar__title fades in.
.card .list .list--glyph .list--tile .list--avatar .row .row--top .row--avatar .row__text .row__title .row__sub .row__meta .row__trail .row__chev .row__ext .row__body .row__go .row__link
.disc .disc__body .disc__note .disc__stack .disc__role .disc__when .more
The body is in the DOM all along, so it prints, searches and works without JavaScript. A deep link to an id inside opens it.
Stack HTML · CSS · no build step
A role, a companyMonth 20XX – Month 20XX · Place
.chip .chip--action .chip--waiting .chip--settled .chip--caution .chip--stop
A chip states something and never acts. 20 px tall, caption 1 at 500, on its tone’s 16 % wash.
.pill .pill--primary .pill--tinted .is-done .copy
A pill always does something. The visible capsule is 32 px inside a 44 px hit box. The Copy pill appears only on https, where copying can work.
.btn .btn--inverse .btn.glass .btn--block .actions
50 px capsules for the one or two main actions of a page; a secondary button set on the sky floats as glass.
.avatar .avatar--co .avatar--30 .avatar--56 .av-1…9 .badge-dot .tile .tile--40 .tile--text .tile--everything .glyph .dot
People are round, companies rounded squares, initials on a gradient lighter at the top. Tiles are 32 px (40 where one stands in for a company). The rainbow tile is the app’s one gradient, kept here and nowhere else.
.row--pick .pick .seg .seg__opt .switch
The picker row is the contact sheet’s own control: a native <select> under a blue trailing value. These specimens change nothing; Appearance and Background live in the sheet.
.claims .claim .claim__why .claims--terms .bullets .bullets--sm
.stat .stat__n .stat__l .timeline .timeline__when
Numbers use tabular digits, as rows, never count-ups.
.trace .trace__head .trace__who .trace__what .trace__foot .receipt .receipt__arrow .proposal__label .proposal__claim .proposal__not
Specimenwho did what
Waitingfor the owner
Proposed
A proposal’s claim
Not done until someone approves it
Result
What actually happened
Labels in mono are the machine voice.
.mail .mail__head .mail__from .mail__when .mail__body .quote
A guest
Specimen text
Hi, we land late on Friday. Is self check-in still possible after midnight?
Thanks!
Words a person wrote are set in serif.
Serif appears only here: words someone wrote.
.flow .flow__step .flow__arrow .flow__label .flow__detail
Contract closed and durable. Evidence, tool calls, gate decisions, and approver (if any) are retained for audit. Read-only from this point — the audit trail outlives the runtime.
The CentrOS contract lifecycle. Nodes ship disabled, so without JavaScript they are static chips and the archived definition is already on the page. With JavaScript, one node at a time is aria-pressed and the detail is announced politely.
.table
| Role | Token | Where |
|---|---|---|
| Section header | --t-headline | .sec__title |
| Row subtitle | --t-subhead | .row__sub |
| Chip | --t-caption1 | .chip |
Below 560 px each row stacks, label over value.
.work .work__head .work__title .work__status .work__why .work__flow .work__receipts .work__actions .stub .frame__bar
In productionsince Feb 2026
An orchestration platform that turns messy business workflows into agent systems — agents draft guest replies, process refunds and vendor invoices, and an owner approves anything irreversible.
router → executor → adversary → verifier → owner inbox
23-unit hospitality operation · 3,980+ tests on main
In progressUnbuilt things carry a stub like this one instead of a fake button. Until then, try the live demo.
The CentrOS demo’s iframe sits below this bar from 768 px; on phones a poster shows instead.
.topbar .topbar__back .topbar__title .topbar__account .tabbar .tabbar__tabs .tabbar__thumb .tab .tab__label .tabbar__ask .sheet .sheet__bar .sheet__grab .sheet__title .sheet__done .sheet__scroll .sgroup .sgroup__foot .sheet__fine
.skip .wrap .foot .vh .nobr .nums .js-only .kicker .card--text .card--pad .apart .group
.skip is the first Tab stop and moves focus to main. .vh hides text visually but keeps it for screen readers, such as “(opens in a new tab)” after every external link. .wrap is the one reading column.
66
Lucide, ISC licence. One sprite, public/images/icons.svg; each icon is <svg class="i"><use href="…#name">, 2 px strokes in currentColor, the web twin of the app’s SF Symbols.
Nothing moves unless you do something, except the sky.
9
Never animated: no keyframes, load animations, count-ups, scroll-linked effects or parallax on content. Under reduced motion the sheet fades instead of sliding and the tab bar and chevrons change instantly.
The slowest thing on the screen.
The chevron turned 90° over 0.3 s because you opened it. The body appears without a height tween. Under reduced motion the chevron turns instantly.
Every preference the browser exposes is handled in the last block of style.css, after every component, so it always wins.
:focus-visible ring (Highlight under forced colours). “Skip to content” is the first Tab stop and moves focus to main; scroll padding keeps a focused element clear of the top bar and the tab bar.--label-2 and the --fg-* tone colours are raised above the app’s values to get there, and a soft halo sits behind text set straight on the sky.<details>, the tab bar stays expanded, the Contact buttons jump to the page’s Contact section, and lifecycle nodes stay static chips.h1 per page, an h2 for every section, and no skipped levels. Landmarks: one main, one primary nav, one footer.