Live Sessions
design system · source of truth

the light that was always there

One living reference for the whole site — themes, tokens, type, the ◐ glyph, the glass nav and footer, the motion vocabulary, and the elements from Work With Me. Everything reads the same tokens, so a single palette swap reskins it all.

☀ / ☾ toggle top-right · scroll to render the scene · resize to feel the nav
01

themes

light · dark · auto (system)
light

warm paper. brass and slate. the reading surface for Work With Me and the essays. quiet, hand-made, high-key.

dark

the verified LUMA palette — charcoal room, cream text, warm gold when she glows. the book’s native world.

auto

follows the visitor’s system. the toggle overrides it; without a choice, the OS decides at dawn and dusk.

02

color tokens

values shift per theme · roles stay fixed
03

the type system

Nexa leads · Newsreader reads · JetBrains Mono for all utility
display · Nexa (League Spartan fallback) — wordmark, titles
clarity & perspective
AaAaAaAa
serif · Newsreader — the reading voice
The past is where power goes to hide. There is only now, generating what we call the past.
mono · JetBrains Mono — body, navigation, labels, everything utility
Book an inquiry call · Work with me · Live sessions · i · attention · 30 min · drop-in · 2026
04

the ◐ glyph

half-lit circle · favicon & brand mark
the mark
drawn as SVG, never a unicode char
zaheer merali
luma
on charcoal · gold

In-page mark: inline the SVG with currentColor on both the ring stroke and the lit-half fill. It inherits the surrounding text color, so it retints automatically on theme swap — brass on paper, gold on charcoal — with no duplicate markup. Set the color via the --accent token (or --accent-2 for the ring if you want it split).

Favicon: a favicon can’t be recolored by CSS, so the color is baked in. The site ships /favicon.svg — the same arc-path mark in LUMA gold #cfbf95 — linked from every page’s head.

05

glass nav & menu

borrows the page’s colours · never imposes its own

The header and footer are glass — they refract whatever passes beneath. On narrow widths the links collapse into the menu button: two lines that cross into an ×, and a sheet whose items surface out of the glass and sink back the same way.

Resize this window below 760px, or tap the button top-right, to feel the menu breathe. Live in the header above.

06

motion vocabulary

natural elements · no springs, no bounces
breath
8s · opacity + scale
exhale
cubic-bezier(.4,0,.2,1)
surface
fade + blur, both ways
press
instant scale(.96)
07

components

buttons · ramp links · tiers · circles & squares
seed
drop into a live session
per session · month-to-month
  • Weekly group inquiry
  • No commitment
join a session →
root
membership · continuity
by application
  • All live sessions
  • Member resources
apply for membership →
self-inquiry
1:1 · deep inner work
by invitation only
  • 12 × 90-min sessions
  • Direct access between
contact to scope →
<a class="btn primary" href="…">Book an inquiry call</a>
<a class="btn ghost" href="…">Read the essays</a>
<a class="ramp" href="…">self-guided → Clarity &amp; Perspective</a>   <!-- label + arrow, not a raw URL -->
08

hanging canvases

rail + teardrop hanger · framed painting · drag to explore
09

the infinity loop

the ◐ glyph tracing inward · outward · home
10

water & droplet

a drop falls · capillary waves radiate out
a drop falls every few seconds · ripples radiate out

Default engine: INTERVAL=3400, reversed-teardrop source. The Mirror variant (used on clarity-perspective/the-mirror/*): the water is a fixed full-page scene (#scene canvas + #wash) rather than a contained band. The waterline tracks the footer's top divider (the "horizon"); in the closing beat the ◐ glyph wrings a drop that falls to that line. Cadence is slow (INTERVAL=8700) for stillness between drops, and the water surface + drop + ripple bands are tinted by the article's --tint/--accent. All other constants (OOZE, FALL, WAVES) are unchanged. Full engine in the-mirror/article.js.

11

the mirror

a page built on the system · generated from Notion

The Mirror (reflections index + articles under clarity-perspective/the-mirror/) is the first content section built on this system. It's generated from Notion by sync/sync-the-mirror.mjs — you write posts in Notion, run the sync, and the pages regenerate. It adds these documented components on top of the core system:

Per-article theming

A named registry (themes.js): prism · lens · flame · compass · grove · sky · rose. Each theme drives --tint and the accent chain via applyTheme(), so the whole page shifts — page wash, reading panel, water scene, headings, links, glyph, dock. Assigned per post in the sync's POST_THEME (else round-robin). New theme = one entry in themes.js.

Two axes: theme × type

Theme = mood (palette). Type = structure from the Notion blocks: standard reflection (default), dialogue/transcript (the one true layout variant — alternating speaker bubbles), and mixed-media (images, tables, video, callouts layered onto either). Independent — any theme on any type.

Docked title tab

.nav .dock — a drop-down glass tab that hangs below the nav bar on scroll (so it never overlaps the links). Tinted in the article's theme accent. Driven by an IntersectionObserver on .a-head.

Reflective water scene

Fixed full-page canvas; the ◐ glyph in the closing beat wrings a drop that lands on the footer "horizon". Water + drop tinted per theme. Honors the Motion toggle. (Full note in §10.)

Self-hosted icons

Per-article Lucide icons assigned by slug in POST_ICON (Notion-icon parse is a fallback). The sync downloads each used icon to icons/<name>.svg; pages hydrate self-hosted-first via hydrateIcons(), falling back to the inline path in icons.js. No third-party runtime dependency. The ◐ mark stays the brand glyph.

Theme persistence

theme-toggle.js: each page sets a default via <body data-theme-default>; a reader's choice is saved to localStorage and persists across visits (desktop + mobile, local only). The toggle cycles light → dark → auto, its icon reflecting the state; auto follows the OS live.

Transparent footer + Motion toggle

Article footers are transparent (text on the scene), matching Work With Me: brand, nav, copy line, fine-print row. The Motion toggle flips body.reduced to still the scene (also honors prefers-reduced-motion).

Pinned posts

The sync's POST_PINNED registry sorts chosen posts to the top of the index (before reverse-chron), with a subtle pin badge and an accent edge on the card.

Share cards (OG)

Every article ships share-ready. The sync writes a purpose-built 1200×630 OG card per post (og/<slug>.html — the index-card look: cover + tint + title + dek + icon) and registers it in meta.config.json. scripts/generate-og.js screenshots each card to images/og/ and injects the <!--og--> + <!--favicon--> blocks. Run it before shipping.

Reading experience: no top dek (it lives on the index card + as the closing-quote fallback); the article opens on a larger inked lead-in paragraph; body capped at ~64ch serif at 18.5px/1.78; images render at natural aspect (portrait shows fully) and tap-to-expand in place (no modal). Adding a post → sync/ADDING-A-POST.md. Full block vocabulary → sync/style-contract.md. Generated files (*.html, images/, icons/) are never hand-edited.

12

building on the system

for anyone extending the site

a new static page

  1. Create a sibling folder = route: resources/index.html serves at /resources/.
  2. Reuse the tokens + type by declaring the same :root/body.dark token block (or link a shared stylesheet). Never hard-code a color — always var(--accent), var(--ink), etc., so a theme swap reskins the page.
  3. Copy the glass <header class="nav"> + .sheet and the <footer> from a page at the same depth. Mark the current section's nav link with class="current".
  4. Load theme-toggle.js and set a first-load default on the body.
  5. Compose from the components above; add class="reveal" to anything that should fade in on scroll.
  6. Before prod: add the page to meta.config.json and run node scripts/generate-og.js — it builds the share card and injects the OG + favicon tags. Every page must be share-ready.
<body data-theme-default="auto">
  <canvas id="scene"></canvas>        <!-- optional water scene -->
  <header class="nav">…glass nav + #theme + .mbtn…</header>
  <main> …compose .panel / .card / components… </main>
  <footer class="site">…brand · nav · copy · fine + motion-toggle…</footer>
  <script src="theme-toggle.js"></script>
</body>

a new Mirror reflection

  1. Write the post in Notion under The Mirror page, using the block vocabulary (sync/style-contract.md).
  2. Add a one-line dek to sync/deks.json, keyed by slug.
  3. Optional per-post registries in sync/sync-the-mirror.mjs: POST_THEME (palette), POST_ICON (Lucide), POST_PINNED (pin), POST_LIGHTNESS (default light/dark), DIALOGUE_POSTS (transcript).
  4. Run the sync, then test locally and push.
export NOTION_TOKEN=…            # once per shell (never commit)
node sync/sync-the-mirror.mjs --check   # dry run: NEW / CHANGED / REMOVED
node sync/sync-the-mirror.mjs           # writes index + articles + images + icons
Full walkthrough: sync/ADDING-A-POST.md. Generated files under the-mirror/ are disposable — edit templates, shared assets, or registries, never the output.
13

built on this system

what's live · click to open

The source of truth links to every page built on it, so you can see the components in real use. Add new pages here (and to the nav/footer) as they ship.