Vibe-Coding a Research Portfolio

Technical record · updated

The website revamp, a technical record

How the redesign of this site works underneath, and how it changed from February to October 2026: the type and reading column, the time-of-day palettes and tokens, the motion rules, the structure of the homepage and projects, the separate Human and AI routes, the visual QA harness, and the written design memory that carries judgment from one session to the next.

The site is an al-folio v1 fork that owns its identity, layouts, styles, scripts and content. The stages below are design history, not an A/B test; where a move was measured, the entry gives the number and its conditions. Visitor comprehension has not been studied.

  • 8 systems
  • 39 techniques
  • 35 design moves
  • 6 open problems
  • 36 sources

Each system lists its techniques: what each one does, how it works, the files that hold it, the research it borrows from, what it cannot do yet, and the next moves worth trying. The design history keeps every move in order, with what the result said back.

Programs can read the same record as JSON. In the repository, python bin/design_record_brief.py website-revamp turns it into a brief for the next pass, and new work is appended to _data/design_records/website-revamp.yml.

Type, reading column and image weight

One family, five sizes and one measure. Prose sits in a column of about 68 characters, and images are served at the size they are shown.

Inter in five type roles

Shipped · Sep 14, 2026

Every page uses Inter in five roles (page title, section title, subsection, body, metadata and controls), each a computed size token.

How it works, files and sources

_sass/_themes.scss defines --type-display, --type-heading, --type-subheading, --type-reading and --type-compact as clamped sizes and keeps older names as aliases. Inter’s regular and italic variable files are self-hosted with the SIL OFL in assets/fonts/inter/, and only weights 400 to 700 are used. test/style_contract.js caps raw font-size declarations across _sass at 333 and requires the realignment layer to use type roles, so new styles reach for a role instead of a new size. Inter replaced the Newsreader display face on September 14.

Files
Sources
Known limits
  • 325 legacy raw sizes remain under the 333 ceiling; the cap stops growth rather than paying the debt down.
Next moves
  • Ready Move the largest remaining raw sizes in the page-specific partials onto type roles.

A 33.5rem reading column

Shipped · Oct 12, 2026

Prose, headings and the post header share one centered column of about 68 characters, while figures and code reach the wider article width.

How it works, files and sources

_sass/_reading.scss sets --reading-width: 33.5rem for prose and --reading-wide-width: 68ch for figures and code, and the contents rail and trace pages follow it. The column is sized once in rem because ch is the width of “0” in each element’s own font: the old 68ch measured 91 to 95 characters of Inter and grew wider on headings. Bringhurst’s 45 to 75 characters, 66 ideal, is the target.

Files
Sources

Pixels at display size

Shipped · Oct 12, 2026

Pages request WebP variants sized to how large each image is actually shown, and long GIFs become posters that play on request.

How it works, files and sources

_includes/responsive_variant.liquid prints the URL of the 480, 800 or 1400-pixel WebP variant that the build’s ImageMagick step generates, for gallery slides, thumbnails and teasers. The homepage record art points to 800 px variants with the originals as a fallback. bin/make_gif_posters.py writes a first-frame poster for each animated publication preview, and _layouts/bib.liquid shows the poster with a “Play the animation” control, which also serves reduced-motion visitors without a special case.

Files
Known limits
  • Local builds without ImageMagick 404 on variants that only CI generates; pages fall back to the originals.

Moves in this system: A research studio, then one type familyThe screenshot that ran out of memorySixty-eight characters, measured in the wrong unitA poster frame for a moving figureRecord art 40 times larger than its frame

Color, time of day and tokens

Four time-of-day palettes change the atmosphere, never the research story. A small Material-inspired token set keeps surfaces, focus and motion consistent, and a procedural orange is the only identity color.

Four time-of-day palettes

Shipped · May 22, 2026

Morning dawn rose, noon Pacific blue, afternoon sea glass and evening moonlit lavender default from the visitor’s local time.

How it works, files and sources

assets/js/theme.js picks the mode from local time (boundaries at 5, 11, 15 and 20 o’clock) before first paint, remembers a manual choice for the session, and switches automatically at a boundary only if the visitor has not chosen. _sass/_themes.scss holds the four token sets; each one registers through the whole surface hierarchy, from the page field to cards, outlines, shadows and the footer. Accent ink for links and labels stays separate from lighter pastel fills, so contrast holds in every mode.

Files

Material-Lite tokens

Shipped · Jun 29, 2026

A small set of radius, elevation, tonal-surface, state-layer, focus, spacing and motion tokens, borrowed from Material 3 ideas without its component system.

How it works, files and sources

_sass/_material-lite.scss defines --md-lite-* tokens, and the September foundations pass added spacing and motion durations and easings to them. Filled orange marks the primary action in a local cluster; tonal surfaces carry secondary actions, chips and quiet controls; neutral surfaces carry most of the page. PurgeCSS keeps every --md-lite- variable through its safelist.

Files
Known limits
  • The homepage’s own partial predates the tokens and still uses many literal values.

A procedural orange mark

Shipped · Jun 29, 2026

The navbar mark is a flat 2D orange whose shape, rind gradient, pores, navel and leaves vary on each page load.

How it works, files and sources

_includes/brand-orange.liquid renders an inline SVG with a no-JavaScript fallback, and assets/js/brand-orange.js varies the shape within a fixed viewbox, the rind gradient, the pores, the calyx details and the leaves, with a small pointer response that stops under reduced motion. ?orangeSeed= reproduces one mark for inspection. The home link owns the accessible label; the SVG is decorative.

Files
Known limits
  • Engraving ST into the fruit at navbar size made it read like a glossy app icon, so the mark carries no initials.

A sun you can drag

Shipped · Oct 13, 2026

The theme panel is a day arc. Dragging the sun picks any minute, the theme snaps to that hour’s mode, and the page’s sky glow and the 3D scenes follow.

How it works, files and sources

assets/js/sun-arc.mjs maps minutes onto an arc from 5:00 to 20:00, with a flatter night arc for the moon (sun-arc-math.mjs). The four token sets still carry contrast; only the panel and a sky glow at the top of the page shift color continuously, the glow moving left to right with the sun. The footer coast blends its four authored looks by the minute, and the 3D home previews the hour when the drag ends, through a siteTimeChange event. Now hands everything back to the clock. A theme chosen anywhere else moves the sun but never sets a preview hour. This is direct manipulation in Shneiderman’s sense: a continuous representation, physical action and immediate, reversible feedback.

Files
Known limits
  • The four stops stay, because they are both the quick choice and the test contract.

Grayscale-until-hover thumbnails

Retired · Sep 14, 2026

Fun-project thumbnails sat in grayscale until hover, after React Bits’ Chroma Grid.

What it was and why it was retired

A filter desaturated each Fun thumbnail at rest and restored color on hover or focus, as one of the approved reading enhancements.

Why it was retired
Mixed grayscale and color thumbnails made the project index inconsistent. All thumbnails now keep their original color in every state. 1e0e67dbf

Moves in this system: Material-Lite and an orange markThumbnails stay in colorA sun you can drag, and a switch that stills everything

Motion

Motion explains a state, a comparison or a path, then settles into a readable still frame. A bounded cinematic layer, named springs and scroll-driven CSS carry it; one switch stills everything.

A bounded cinematic layer

Shipped · Sep 5, 2026

Pages that declare cinematic get scroll scenes, staggered entrances, a pointer spotlight and tilt on card grids, and a card-to-hero image morph.

How it works, files and sources

assets/js/cinematic.js runs on GSAP 3.15 and ScrollTrigger, vendored under assets/vendor/gsap/3.15.0/ and loaded only on opted-in pages. Nothing takes over scrolling. Every effect is a still page under reduced motion, without a fine pointer and under automation (navigator.webdriver), unless the URL carries ?cinematic=live, so visual captures stay deterministic. The clicked project image travels into the case page’s hero through a cross-document view transition and back again.

Files
Known limits
  • Cinematic captures need ?cinematic=live; ordinary automated captures see the still page.

The Research Focus sketch

Shipped · May 22, 2026

A semantic drawing explains Design, Evaluate and Situate, with a quiet Paper shader field moving underneath it.

How it works, files and sources

assets/js/research-motion.js draws each mode with a stable number of lines and dots and enough copy to read the metaphor before the motion. A pointer bends the field inside the canvas, easing in and decaying on exit. The Dot Orbit field comes from a vendored minimal closure of @paper-design/shaders 0.0.80 under Apache-2.0, with one WebGL2 context, at most 480,000 processed pixels and a pause offscreen and in hidden tabs. If WebGL fails, the 2D drawing keeps everything a visitor needs. On wide screens the sketch pins beside its three notes inside its own well, and the note in view picks the lens.

Files
Known limits
  • My first live review found the field perceptually absent; it was strengthened, and its current strength still awaits my judgment.

Springs named by their damping

Shipped · Oct 12, 2026

Buttons and menus answer a press with a damped spring instead of a fixed ease, from two named springs.

How it works, files and sources

_sass/_springs.scss defines a confident spring (ζ 0.8, settling in 0.48 s with 1.5 % overshoot) for buttons and menus and a playful one (ζ 0.55, 0.9 s, 12.6 %) for the desk toys. bin/spring_easing.cjs samples a damped oscillator’s step response for any damping ratio and period into a CSS linear() curve, describing springs by bounce and duration as Apple’s spring guidance does. The theme menu enters with @starting-style, and reading disclosures open through ::details-content. Browsers without linear() keep a similar cubic Bézier.

Files
Known limits
  • Springs stay on direct manipulation and discrete toggles; ambient motion keeps eases or stops.

Cross-document view transitions

Shipped · Sep 5, 2026

Same-origin navigations crossfade the page root while the navbar and progress line hold still.

How it works, files and sources

_includes/head.liquid emits @view-transition { navigation: auto } on every page except those that manage their own arrival, such as the AI profile and the homepage. _sass/_transitions.scss times the root crossfade with the standard motion tokens and turns it into an instant swap under reduced motion, as do browsers without support. The visual harness is unaffected because it navigates with page.goto and disables animations.

Files
Known limits
  • The root crossfade is still marked a prototype awaiting my live click-through in all four themes.
Next moves
  • Needs a decision A live click-through in all four themes, then keep or remove the root crossfade.

A scroll-driven laptop

Shipped · Oct 12, 2026

On the revamp page a CSS laptop opens on the February homepage, then its screen wipes along an orange seam to an October capture of the same view.

How it works, files and sources

_sass/_revamp-device.scss maps scroll progress through the section to the lid angle and the wipe with animation-timeline: view(), which runs on the compositor with no scroll listener. It plays only when the cinematic layer is live and the browser supports scroll timelines; everywhere else the laptop stands open on today’s page with a February button.

Files
Known limits
  • Worth repeating only where a single comparison carries the story.

One switch that stills everything

Shipped · Oct 13, 2026

Pause motion in the theme panel makes the reduced-motion query match, so every surface that already honors reduced motion stills through the same path.

How it works, files and sources

assets/js/theme.js installs in the head, before any module asks, and lays the pause over matchMedia("(prefers-reduced-motion: reduce)") while keeping each caller’s own list and change events. The 3D home, duh, P, the footer coast, the research sketch and the cinematic scenes all still without a switch of their own, and CSS loops key off html[data-motion].

Files
Known limits
  • A first version shared one native list among every caller, and P’s playground then sometimes never heard reduced motion end.

A glass lip under the navigation bar

Shipped · Oct 13, 2026

A 10-pixel lip under the navigation bar refracts what scrolls beneath it, like the rounded edge of a glass slab.

How it works, files and sources

assets/js/liquid-glass.js builds a displacement map whose green channel encodes a vertical offset, so the lip’s top rows show the page 4 px lower and a passing line stretches as it slides under. The lip belongs to the header and anchors to the bar’s bottom edge, because the bar’s view-transition-name makes it a backdrop root. Chromium draws SVG filters inside backdrop-filter; Firefox, Safari, reduced transparency, more contrast and forced colors keep the frosted bar.

Files
Known limits
  • Chromium only. A 14 px, 22-scale lip smeared text into a glitch, and a glass theme menu let other words show through, so the menu stays solid.
Next moves
  • Needs a decision Try glass where it floats over imagery or the 3D home rather than over paper.

A comic panel that prints in

Shipped · Oct 13, 2026

The HCI Spooder-Man gallery brings each slide in as offset color plates that come into register on twos, with Ben-Day dots receding.

How it works, files and sources

assets/js/spooder-project.js splits the new slide into red, green and blue plates with an SVG filter and brings them into register over three held drawings at 12 per second (9, 5, then 2 px), while magenta and cyan dots recede from 0.85 to 0.25 (_sass/_spooder-verse.scss). A hard cut replaced the cross-fade, so two captions never show at once. Only this page loads it, and reduced motion gets the instant swap with no filter.

Files
Known limits
  • Kept to slide changes; a print-in on scroll or idle would turn a signature into noise.

Side threads, title drift and gradient fields

Retired · Sep 5, 2026

Scroll-progress threads beside the homepage and publications, gradient fields behind page titles, titles drifting against the page, and a papers-first publications order.

What it was and why it was retired

The first cinematic slices added a thread that filled with scroll and lit the section being read, a slow gradient field behind page titles, headings that drifted slower than the page, and a papers-first reorder of the publications page.

Why it was retired
In my review they read as confusion rather than value. They moved without meaning anything, and the Wall of Rejection went back to the top of publications. 74d6c7134

Moves in this system: Skip link, tokens and a cinematic layerA pinned Research Focus storyA scroll-driven laptop, no scriptSprings, named by their dampingA comic panel that prints inGlass that bends only where it can

Structure and wayfinding

The homepage is an editorial thesis and routing hub, the projects index an evidence surface, and every site experiment tells its own story with a reproduction guide and, now, a technical record.

The homepage research sequence

Shipped · Oct 5, 2026

The homepage moves from the opening through the thesis, the full Research Focus, the selected publications and compact updates, then students and contact.

How it works, files and sources

_pages/about.md and the includes in _includes/home/ render the sequence once: the thesis explained once, the complete focus section rendered once under #focus, the papers, then three dated updates. The thesis is fully legible text; an earlier scroll-controlled word opacity was removed. On October 12 a repeated fact strip left the hero.

Files
Known limits
  • On 1280 × 800 laptops the portrait column sets the hero’s height, so the thesis still sits below the fold.

An explicit, tested paper order

Shipped · Oct 12, 2026

The homepage lists selected papers in a declared order, with DesignWeaver first, instead of bibliography file order.

How it works, files and sources

selected_paper_order in _pages/about.md is rendered with jekyll-scholar’s nocite tag and --cited_in_order in _includes/home/news_publications.liquid, and test/test_selected_paper_order.py keeps it equal to the bibliography’s selected entries. Order is a claim, because items at the start of a list are remembered best.

Files
Sources

Project cards that open in place

Shipped · May 27, 2026

A project card opens where it is with a cancelable FLIP transition and returns to the same place; on phones the site experiments become one swipeable row.

How it works, files and sources

assets/js/project-cards.js measures the card before and after opening and animates one cancelable clock of 430 ms, read from the shared motion token. A new click cancels stale motion, and reduced motion jumps to the final layout. Below 768 px the experiment grid becomes one scroll-snapped row of cards 84 % wide, so the next one peeks, with a count of the card most in view and arrow-key support; an expanded card widens to the full row.

Files
Sources

A curated command palette

Shipped · Oct 12, 2026

The ⌘K palette offers curated starting routes and Do actions that call the site’s own controls.

How it works, files and sources

_includes/search_data.liquid.js is rendered inline on every page, with Start here routes, writing, projects, contact, and Do actions for the four themes, the 3D home, the AI-readable page, duh and Build Rhythm. Each action clicks or calls the existing control, so it can never disagree with it. The curated data had silently fallen back to the plugin’s defaults after al-folio v1 stopped building _scripts/.

Files
Known limits
  • It renders on the AI profile too, so its text is held to the publication validator’s rules.

Experiments that tell their own stories

Shipped · Jul 15, 2026

Each site experiment has a case study with its question, change, evidence and limit, a reproduction guide, and a place in the projects index by debut date.

How it works, files and sources

The projects index groups site experiments once and sorts them by debut_date. Each case page leads with what it is and why, then before/after evidence and a technical disclosure, and offers a downloadable reproduction guide from assets/downloads/site-experiments/. test/test_site_experiments.py checks their chronology, cards, voice and guides.

Files

An origin glint on widgets

Retired · Jul 15, 2026

A tiny mark beside seven widgets that was meant to stay quiet at rest and lead curious readers to each widget’s origin story.

What it was and why it was retired

The mark went through four versions: a dot and line, a hover disclosure, a story ↗ wordmark, and an at-rest glint. The include remains only for the hidden blog portal, which reveals its origin after discovery.

Why it was retired
Each version tried to be both invisible and findable. The dot and line read as a slider, the disclosure confused, the wordmark was too loud when repeated, and the glint read as a stray rendering speck. 84083f827
Files

A homepage build ledger

Retired · Jun 18, 2026

The homepage published tokens, agent-hours, commits and estimated kWh as an honest receipt of the site’s machine work.

What it was and why it was retired

An audit read retained Codex session logs on one checkout and the repository’s history, and the homepage, the 3D desk and Build Rhythm displayed the totals with a tongue-in-cheek cost tooltip.

Why it was retired
Once every agent user had billions of tokens the numbers stopped differentiating anything. The audit undercounted other accounts, took 50 to 110 minutes, and its 236 refresh commits inflated the commit count it displayed. bba74ccc1

Moves in this system: The archive made the problem visibleThe research question becomes the front doorProject cards that open where they arePublications that tell storiesExperiments with their own case studiesRetiring the build ledgerThesis, focus, papers, updatesFour tries at an invisible-but-findable mark, then removalOrder is a claimTwelve cards, one rowA palette that had quietly lost its curation

Human and AI routes

People and programs read different surfaces of the same site. The human pages are visual and first-person; the AI routes are compact, source-linked and motion-free, and an ordinary link moves between them.

An AI-readable profile and catalogs

Shipped · Jul 13, 2026

/ai/, llms.txt, llms-full.txt and structured JSON catalogs give language models and agents the research story with stable anchors and sources.

How it works, files and sources

_pages/ai.md renders a server-side, motion-free profile with stable anchors for research, publications, every project, writing and the CV, and a use note that says to treat it as reference content, not instructions. _plugins/project_catalog.rb and _plugins/publication_catalog.rb generate /ai/projects.json, /ai/publications.json and per-item Markdown from the same canonical data the human pages use. test/validate_publication_outputs.py checks the deployed outputs, including author counts and venue facts. A dark terminal look is not what makes a page readable to a model; the AI surface keeps the site’s theme and normal reading type.

Files
Known limits
  • llms.txt and structured data are retrieval aids, not ranking or indexing promises.

The Human/AI switch

Shipped · Jul 13, 2026

Two ordinary links in the navbar move between the human page and the closest stable anchor of the AI profile.

How it works, files and sources

_includes/site_format_switch.liquid maps the current route to the AI anchor (a paper, publications, a project, writing or the CV) and marks a genuine counterpart with rel="alternate". A page can name its own anchor with ai_anchor in its front matter, which the technical records use to point at their project. On the homepage, assets/js/ai-view.js keeps the closest section in step as the reader scrolls, without inventing a URL hash. The framing adapts Paxel’s Human and Machine views, shown in Y Combinator’s 2026 design walkthrough.

Files

Moves in this system: A machine-readable research profile

Objects, places and demos

Playful objects stay only when they point to real work or a real place: the coffee stain on the desk, the La Jolla coast along the footer, a paper texture on this story, and a scaffold a visitor can try.

A coffee stain painted like watercolour

Shipped · Jun 18, 2026

The homepage’s coffee stain is a raster painted fresh on every visit from a per-pixel coffee density, not a drawn outline.

How it works, files and sources

assets/js/home-coffee-stain.js paints the wet ring a mug’s foot leaves (a dark pinned edge fading inward, tide lines, dry breaks, heavier where it pooled), sometimes a second placement, a puddle and spills that dry as washes with dark edges and backrun veins, under the paper’s mottle. Density maps from amber to espresso and multiplies into the page; evening paints pale residue. It renders in time-boxed idle slices and is read back as a data URL, because the page’s Content-Security-Policy admits data: images but not blob: ones. ?coffeeSeed= reproduces one stain. The ring follows Deegan and colleagues’ account of capillary flow, and the washes Curtis and colleagues’ computer-generated watercolor.

Files
Known limits
  • The stain is a desk cue; it must stay quiet enough that any text it crosses reads easily.

A static paper texture for this story

Shipped · Aug 16, 2026

The revamp story sits on a seeded paper texture rendered once, with no runtime shader.

How it works, files and sources

bin/generate_paper_texture.cjs renders the texture from Paper Shaders’ Paper Texture in @paper-design/shaders 0.0.80, and the recipe beside the asset records the seed, parameters, output hash, generator, license and vendor hashes. It is a story-specific accent, not a sitewide background.

Files
Sources

A dimensional scaffold to try

Shipped · Oct 13, 2026

The DesignWeaver page lets a visitor pick tags in four dimensions and watch a prompt rebuild as a fixed sentence, each phrase underlined in its dimension’s color.

How it works, files and sources

assets/js/designweaver-scaffold.mjs reads the four dimensions and the tags from a study session in the CHI 2025 talk (_data/designweaver_scaffold.yml). It opens on that session’s selection and the prompt DesignWeaver wrote, and any change rebuilds the prompt as a fixed sentence. The label changes from DesignWeaver’s prompt to “Your prompt, as a fixed sentence”, and the note says that the real system uses a language model and that nothing is sent or generated. Without JavaScript the session’s selection still shows. Scaffolding here is Wood, Bruner and Ross’s sense: support that lets a novice do what they could not alone.

Files
Known limits
  • A fixed sentence is terser than the model’s prose, so the counter reports tags across dimensions rather than words.

Moves in this system: La Jolla along the footerThe scaffold, small enough to tryA coffee ring, by the physics of dryingA stain that looked like glass

Visual QA and checks

Evidence matches the decision being made. One screenshot answers a taste question, a four-viewport checkpoint proves a direction, and the full matrix is for a release. Contracts and validators catch what screenshots miss.

Three visual QA lanes

Shipped · Aug 16, 2026

A fast lane takes one screenshot on a running preview, a checkpoint lane runs explicit routes at four viewports, and the release lane runs everything.

How it works, files and sources

test/visual/iteration.config.js defaults to one route, one 1440 × 1000 light viewport, one worker and no trace, refuses a second route, and fails closed after a one-minute budget. test/visual/checkpoint.config.js refuses to run without an explicit VISUAL_ROUTE_IDS list and covers 1440 × 1000, 1280 × 800, 768 × 1024 and 390 × 1000 in light and dark. Captures go under .jekyll-cache/visual-qa/ so Jekyll does not rebuild in response to its own QA output. Scene cases run in named groups with one worker (bin/run_visual_scene_group.cjs).

Files
Sources
Known limits
  • Linux Chromium can reject later captures after image-heavy and WebGL work share a process, so the public site and scene suites run as separate processes.

Retry after the page settles

Shipped · Oct 12, 2026

A failed screenshot retries only after two animation frames and an idle callback, at 250, 750 and 1,500 ms.

How it works, files and sources

test/visual/helpers.js waits for the page’s current work to finish before a capture, approximating a settled event loop with requestAnimationFrame followed by requestIdleCallback, then retries transient capture errors with backoff; any other error fails at once.

Files
Known limits
  • The retry hides nothing structural, but a page that stalls a two-core runner also stalls a slow phone.

Invariants on every public route

Shipped · Oct 12, 2026

Every public route keeps one h1, the skip link as the first tab stop, and alt text on every image.

How it works, files and sources

A one-off audit first checked that all 60 route-and-width pairs already met the rules; then three assertions in exercisePublicRoute in test/visual/sitewide.spec.js started keeping them. The skip link and main landmark came with the September foundations pass.

Files
Known limits
  • One h1 per page is a convention for heading navigation, not a WCAG requirement.
Next moves
  • Ready Behavioral accessibility next, such as focus return after dialogs and disclosures.

Contracts, validators and the override audit

Shipped · May 25, 2026

A style contract, a publication-output validator, Python policy tests and the al-folio override audit guard what screenshots cannot see.

How it works, files and sources

test/style_contract.js checks starter wiring, plugin and visual-workflow contracts and the type ceiling. test/validate_publication_outputs.py checks the built AI outputs. The Python suite in test/ checks content contracts such as the site experiments, selected paper order and math gating. Local overrides of gem-owned files are recorded with hashes in .al-folio-overrides.yml through bundle exec al-folio upgrade overrides audit, so upstream drift is visible after an update.

Files
Sources

Moves in this system: Retry after the page settlesTest the invariants the site already keeps

Design memory

Judgment is carried across sessions and models in writing: living heuristics, an experiment backlog with my decisions, a studio log of moves, agent skills that point to those documents, and these technical records.

Living design heuristics

Shipped · May 22, 2026

One human-readable file holds the decision order, the spine, type, color, motion, content and QA rules, and the lessons from my reviews.

How it works, files and sources

WEBSITE_DESIGN_HEURISTICS.md is the canonical source, published on the site as a teaching artifact. The August pass named the spine “Less, but more Sirui” and added the signature copy locklist; on September 5 the file went from 443 to 328 lines with every canonical heading kept. Agent skills read it by heading instead of copying it, and test/test_agent_guidance.py keeps the canonical headings in place.

Files
Sources

An experiment backlog with decisions

Shipped · Aug 16, 2026

Each visual or interaction idea gets a hypothesis, route, reference, licensing, budget, evidence, my decision and a revisit trigger; removed experiments stay on record.

How it works, files and sources

docs/design-experiment-backlog.md is the durable queue. An entry moves to Completed only with evidence and my decision, and removed ideas such as the origin glint and the build ledger keep their reasons, because knowing why an idea failed is part of the site’s professional vision.

Files

A studio log of moves

Shipped · Oct 12, 2026

Each design move is a card with its frame, dimensions, move, backtalk, reframe and a concept with its primary source.

How it works, files and sources

docs/studio-log-2026-10.md keeps the loop from Schön’s The Reflective Practitioner: make a move, let the material talk back, reframe. The dimensions name the variables being moved, which turns a vague request into something to reason about. The log is unpublished; the design histories in these records condense it.

Files
Sources

Agent skills that route to the living documents

Shipped · Jun 29, 2026

Short repository skills tell coding agents which document and heading to read for critique, writing, the desk scene and upstream sync.

How it works, files and sources

.codex/skills/ holds concise overlays such as website-design-critique and portfolio-writing-voice. They point to the heuristics, the backlog and the scene brief by heading and do not duplicate the long rules.

Files

Technical records with a next-move brief

Shipped · Oct 15, 2026

Each long-running project keeps its systems, techniques, design history, open problems and sources as data, rendered as a page and served as JSON.

How it works, files and sources

_data/design_records/<slug>.yml holds a record. _includes/design_record.liquid renders it at /projects/<project>/record/, a Liquid page publishes it as JSON under /assets/json/design-records/, and bin/design_record_brief.py <slug> turns it into a brief for the next pass: the current state per system, known limits, candidate moves ranked by stated readiness, sources to read, and the constraints and tests to keep. test/test_design_records.py checks the schema, that every path is in the repository, that every source and system resolves, and that every commit exists in history.

Files
Known limits
  • The records condense the studio log and the notes by hand; a move that is never written down is missing from the brief too.

Moves in this system: Less, but more SiruiA studio log of movesTechnical records that the next pass can start from

Design history

Each move follows the loop from Donald Schön's The Reflective Practitioner: frame the problem, make a move, let the result talk back, then reframe. The dimensions are the variables the move changed. Oldest first; new moves are added at the end.

  1. Structure and wayfinding

    The archive made the problem visible

    Frame
    My site listed projects and papers, but it did not tell visitors what I was actually studying.
    Dimensions
    what a visitor learns first; number of competing elements
    Move
    Kept the public homepage as Wayback served it on February 9, so the redesign could critique a concrete page instead of a memory. The capture entered the repository on May 23 (e4f021520).
    Backtalk
    The archive is competent and crowded. Papers, projects, biography and navigation all ask for attention at once.
    Reframe
    Make the research question the front door and the interface quieter.
  2. Structure and wayfinding 82ecde6ff

    The research question becomes the front door

    Frame
    A visitor should understand what I study before decoding my biography or the interface.
    Dimensions
    order of homepage sections; number of actions; where proof sits
    Move
    Rebuilt the homepage around the research claim, affiliation, proof routes and a few actions, with time-of-day themes (f30191146) and a research motion sketch for Design, Evaluate, Situate.
    Backtalk
    Paper, desk objects and motion stayed only where they helped a visitor understand how I design, evaluate and situate AI tools.
    Reframe
    Let the publications and experiments carry their own stories.
  3. Structure and wayfinding 15d94c048

    Project cards that open where they are

    Frame
    Sampling a project meant leaving the projects index and losing my place among the others.
    Dimensions
    where a card opens; what moves while it opens; how focus returns
    Move
    Project cards that expand in place with a FLIP transition and close back into the same spot.
    Backtalk
    People could follow which card opened, but scaling the whole card squeezed its text and images. Accents, takeaways, image zoom and keyframes added in July competed for attention and were removed, leaving one cancelable clock.
    Reframe
    Use one clock for opening and moving, and let reduced motion jump to the final layout.
  4. Structure and wayfinding 910f3c7f2

    Publications that tell stories

    Frame
    The publications page answered what I published, but hid the rejections and citation history behind the list.
    Dimensions
    what counts as an event; which views share one focus; whose clock a number follows
    Move
    A Steam-style Wall of Rejection with one receipt per rejection event, then a Scholar Lens (089b29413) whose focus travels between a bibliography row, its citation chip and its annual bars.
    Backtalk
    A badge can sit on several shelves without adding another event, so 38 Failure XP means four rejections. Lifetime totals and annual bars refresh on different dates, so both dates stay visible.
    Reframe
    Keep the citation list authoritative and let each view project from one record.
  5. Color, time of day and tokens 1e3eb4f7d

    Material-Lite and an orange mark

    Frame
    Radii, shadows, focus rings and motion durations were one-off values across many partials.
    Dimensions
    token coverage; where orange may appear; mark legibility at 32 px
    Move
    Material 3-inspired tokens for radius, elevation, tonal surfaces, state layers, focus and motion, and a procedural 2D orange as the brand mark (f08f22f19).
    Backtalk
    Engraving ST into the fruit at navbar size made it read like a glossy app icon instead of a crisp site mark.
    Reframe
    Orange is identity only, and neutral surfaces carry most of the page.
  6. Human and AI routes d3f13be35

    A machine-readable research profile

    Frame
    Language models and agents read the same decorated pages people do.
    Dimensions
    route addressability; motion; source links; typography of the machine view
    Move
    An AI-readable profile at /ai/, llms.txt and a Human/AI switch in the navbar, built from the same canonical data as the human pages.
    Backtalk
    The machine view needed reading rules of its own, written into the heuristics with it. Server-rendered, source-linked and motion-free, in the site’s normal theme and type, because a dark terminal look is not what makes a page readable to a model.
    Reframe
    Keep the two surfaces separate and connect them with ordinary links to the closest anchor.
  7. Structure and wayfinding f05f02b41

    Experiments with their own case studies

    Frame
    The design thinking behind each widget was hidden behind a history icon.
    Dimensions
    where an origin story lives; what a case page leads with; reproducibility
    Move
    Each site experiment got a case study with its question, change, evidence and limit, and a downloadable reproduction guide.
    Backtalk
    The projects index now leads from each experiment back to its origin, and a reader who follows it gets the question and the limit, not merely the commits.
    Reframe
    Origin stories belong to labeled places, the projects index and the case pages, not to marks on the work.
  8. Design memory 4412a95ec

    Less, but more Sirui

    Frame
    The portfolio had collected containers, repeated explanations and equal-weight actions.
    Dimensions
    containers per section; type roles; repeated explanations
    Move
    Named the spine “Less, but more Sirui”, locked the signature copy, set narrative type roles, separated Human and AI reading surfaces, and added the proportional QA lanes and the experiment backlog.
    Backtalk
    Fewer type levels, containers and actions made the remaining choices feel intentional, and the heuristics became a teaching artifact rather than a wall of rules.
    Reframe
    Record uncertain ideas with a hypothesis and a revisit trigger instead of freezing the style or shipping an effect without evidence.
  9. Motion 5acb08fe3

    A pinned Research Focus story

    Frame
    I called the homepage scroll a bit vanilla and pointed at pear.no as a reference.
    Dimensions
    what stays pinned; what the scroll position selects; depth between layers
    Move
    On wide screens the Research Focus sketch pins beside its three lens notes and the note in view picks the lens; the thesis arrived word by word, and shallow parallax separated layers that belong together.
    Backtalk
    The pinned sketch slid into the Exploring row and left its column half empty, because a sticky grid item can travel to the end of the whole grid; it now sits in its own well (362100480).
    Reframe
    Pinned stages need their own well, and any field behind a scene must fade before its box edge.
    Sources
  10. Structure and wayfinding bba74ccc1

    Retiring the build ledger

    Frame
    The homepage published what the site cost in machine work, tokens, agent-hours, commits and kWh, as an honest receipt.
    Dimensions
    what the number tells a reader; accounting cost; side effects on the history
    Move
    Removed the ledger, the desk tag, the Build Rhythm token surfaces and every tool behind them. One sentence now links this story and Build Rhythm.
    Backtalk
    Once every agent user had billions of tokens the numbers stopped differentiating anything. The audit read one machine’s logs, and 236 refresh commits inflated the very commit count it displayed.
    Reframe
    Bring a number back only with an exact, privacy-safe source and a story in which the number changes what a reader understands.
  11. Type, reading column and image weight 72ce1637d

    A research studio, then one type family

    Frame
    The homepage needed concrete selected work before the narrative, and a calmer reading surface everywhere.
    Dimensions
    order of the homepage; display and reading faces; reading column
    Move
    The homepage led with the research question and selected work, a Newsreader display face sat over Inter, and the 3D desk became an optional inhabited home.
    Backtalk
    Two days later I replaced the mixed serif and sans system with Inter throughout, organized by spacing and a small hierarchy (9c746dfe9).
    Reframe
    Spend type contrast through size and weight within one family.
    Sources
  12. Color, time of day and tokens 1e0e67dbf

    Thumbnails stay in color

    Frame
    Fun-project thumbnails sat in grayscale until hover, after an approved reading enhancement.
    Dimensions
    thumbnail color at rest; consistency across the index
    Move
    Removed the grayscale treatment; every thumbnail keeps its original color in every state.
    Backtalk
    Mixed grayscale and color thumbnails made the project index read as inconsistent.
    Reframe
    An interaction reference is not a reason to hide the work.
  13. Structure and wayfinding c27bbc734

    Thesis, focus, papers, updates

    Frame
    The thesis and the Research Focus were split and repeated, and the thesis faded in word by word with scroll.
    Dimensions
    section order; repetition; legibility of the thesis
    Move
    One sequence (opening, thesis, the full focus once, selected publications, compact updates, students, contact), with the thesis as fully legible text.
    Backtalk
    The first published iteration ended its visual regression run with two failures, a stale manual-scroll direction and lazy print images that had not loaded before capture; the follow-up repaired both.
    Reframe
    Explain the thesis once and render the focus once.
  14. Design memory cd11ec53e

    A studio log of moves

    Frame
    Design moves were scattered across commits, backlog entries and conversations, so the next session started from scratch.
    Dimensions
    fields per move; where the primary source sits; how a move links to code
    Move
    Started a studio log of cards with frame, dimensions, move, backtalk, reframe and a concept with its primary source.
    Backtalk
    Forty cards in four days, and the dimensions turned vague requests into variables someone could reason about.
    Reframe
    Turn the record itself into the design space that the next move starts from.
    Sources
  15. Type, reading column and image weight 702030cda

    The screenshot that ran out of memory

    Frame
    CI visual checkpoints had been red since the companion landed, because Linux Chromium could not capture the full HCI Spooder-Man page.
    Dimensions
    decoded bitmap bytes per page; image count; capture area
    Move
    The page serves the 480, 800 and 1400-pixel WebP variants CI already generates, sized to how large each image is shown.
    Backtalk
    Transfer fell from 33 MB to 5.2 MB. One 3,838 × 1,588 PNG decodes to about 24 MB of RGBA whatever its 4 MB file size, which is why the failure looked random. The fixed page passed 16 of 16 runs in the Linux Playwright image.
    Reframe
    File size and memory are different budgets; serve pixels at display size.
  16. Structure and wayfinding 84083f827

    Four tries at an invisible-but-findable mark, then removal

    Frame
    A tiny origin glint beside seven widgets read as a stray rendering speck in my October 12 review.
    Dimensions
    salience at rest against on engagement; repetition; target size; wording
    Move
    Removed the mark; the projects index line that already had a visible label became a plain text link.
    Backtalk
    The history is the evidence. A dot and line read as a slider, a hover disclosure confused, a story wordmark was too loud when repeated, and the glint read as an artifact. Each tried to be both invisible and findable.
    Reframe
    Route-finding belongs to labeled places, not to decorations on the work.
  17. Type, reading column and image weight 89155618a

    Sixty-eight characters, measured in the wrong unit

    Frame
    Posts and case studies ran about 95 characters per line at 1440 px.
    Dimensions
    characters per line; the font each element measures ch against; alignment with figures and the contents rail
    Move
    One centered 33.5rem column for prose, headings and the post header, with figures and code reaching 68ch.
    Backtalk
    The first try, max-width 50ch, narrowed paragraphs but not headings; a later rule also reset the margins, and the contents layout pinned prose to the left.
    Reframe
    Size the column once in rem and let every element inherit it; keep ch for single-font contexts such as code.
    Sources
  18. Structure and wayfinding c5974d7c7

    Order is a claim

    Frame
    DesignWeaver, the flagship paper, sat third on the homepage because the bibliography lists papers in file order.
    Dimensions
    display order against data order; one source of truth; test coverage
    Move
    A declared selected_paper_order rendered with nocite and --cited_in_order, with a test that keeps it equal to the selected entries.
    Backtalk
    nocite works inside a loop because jekyll-scholar resolves a key as a variable before treating it as a literal.
    Reframe
    Ordering is an explicit, tested decision instead of a side effect of file order.
    Sources
  19. Type, reading column and image weight 041558952

    A poster frame for a moving figure

    Frame
    Two Physion previews were 2.2 MB and 6.9 MB GIFs that every homepage and publications visitor downloaded and watched loop.
    Dimensions
    bytes per listing page; motion by default against on request; descriptive alt text
    Move
    A first-frame poster through responsive WebP variants, which zooms into the original and offers to play the animation.
    Backtalk
    The publications page fell from 7.3 MB to 4.9 MB. A closing brace inside a Liquid output tag ended it early until the filter moved into an assign.
    Reframe
    Motion on request also serves reduced-motion visitors without a special case.
  20. Visual QA and checks 26a5e24ce

    Retry after the page settles

    Frame
    Visual checkpoints failed with “Unable to capture screenshot” on a different route each run.
    Dimensions
    main-thread idleness at capture time; retry count and backoff; runner cores
    Move
    The harness waits for two animation frames and an idle callback, then retries at 250, 750 and 1,500 ms; any other error still fails at once.
    Backtalk
    The next run was green across every site and scene job, the first fully green visual checkpoints since the companion landed.
    Reframe
    Keep the retry and still make the page cheaper, because work that stalls a two-core runner also stalls a slow phone.
  21. Type, reading column and image weight b26b8c7dd

    Record art 40 times larger than its frame

    Frame
    The homepage preloaded four 1024 px record-art PNGs (6.4 MB) for a disc never shown wider than about 340 CSS pixels.
    Dimensions
    device pixels needed; bytes; behavior when a variant is missing
    Move
    The record art points to 800 px WebP variants of 31 to 46 KB each, with the originals as a fallback.
    Backtalk
    The homepage fell from 12.3 MB to 6.1 MB on the local preview, and the 2D and 3D records behave as before.
    Reframe
    What remains is the 3D coast model, three.js, CSS and fonts.
  22. Visual QA and checks 4692a2556

    Test the invariants the site already keeps

    Frame
    Before adding assertions, check whether the site already meets them, so a test records reality instead of hope.
    Dimensions
    h1 count; the first tab stop; images without alt; 30 routes at two widths
    Move
    A one-off audit, then three assertions on every public route.
    Backtalk
    All 60 route-and-width pairs already passed; the test now keeps them that way.
    Reframe
    The next accessibility work is behavioral, such as a global motion pause and focus return.
  23. Structure and wayfinding a7a330409

    Twelve cards, one row

    Frame
    On a 390 px phone the twelve site-experiment cards stacked into about 6,650 px of scrolling.
    Dimensions
    section height; how much of the next card shows; position feedback; an expanded card’s width
    Move
    Below 768 px the grid becomes one scroll-snapped row with each card 84 % wide, a “1 / 12” count and arrow keys; an expanded card widens to the full row.
    Backtalk
    The section shrank to about 690 px, and the disclosure test still finds every story with no clipping or overflow.
    Reframe
    The desktop grid stays; a carousel pays off only where the column is one card wide.
    Sources
  24. Motion 9ff8c136a

    A scroll-driven laptop, no script

    Frame
    This page told its before and after in captions, and the change itself was easy to miss.
    Dimensions
    scroll progress; lid angle; wipe position; which capture each moment shows
    Move
    A CSS laptop pinned while the reader scrolls, opening on the February capture and wiping along an orange seam to an October capture of the same view.
    Backtalk
    The first wipe showed the seam during the lid opening, because an animation’s both fill applies its first keyframe early, and the base’s extra width overflowed phones. Both were fixed.
    Reframe
    Use the pattern only where a single comparison carries the story.
  25. Motion 032a6facc

    Springs, named by their damping

    Frame
    Buttons and menus moved on fixed 180 ms eases, so a press felt like a fade rather than something physical.
    Dimensions
    damping ratio; period; which controls get a bouncier spring
    Move
    A confident spring for buttons and menus and a playful one for the desk toys, generated as CSS linear() curves.
    Backtalk
    Measured in the browser, one disclosure grows from 46 to 477 px in about 160 ms, overshoots to 481 and settles.
    Reframe
    Keep springs on direct manipulation and discrete toggles; ambient motion stays on eases or stops.
  26. Structure and wayfinding ed0e831f5

    A palette that had quietly lost its curation

    Frame
    The ⌘K palette offered light, dark and system themes this site does not have, and none of its curated starting routes.
    Dimensions
    which data the palette renders; what each action controls; what every page may say
    Move
    The curated data moved to an inline include, with Do actions that call the site’s own controls.
    Backtalk
    The first push broke the deploy, because the palette now renders on the AI profile and its email action used an address the validator forbids, and a comma split one theme description into a nonsense fifth action.
    Reframe
    Run the production build and the output validator before pushing anything that renders on every page.
  27. Motion eb20fea31

    A comic panel that prints in

    Frame
    The Spooder-Man gallery cross-faded like any slideshow, though the page is a love letter to Spider-Verse.
    Dimensions
    plate offset; dot strength; drawings per second; caption overlap
    Move
    Each new slide comes in as red, green and blue plates that move into register over three held drawings at 12 per second, while halftone dots recede.
    Backtalk
    The first version also stepped the old cross-fade, and on its first drawing both captions showed at once; a hard cut keeps one caption.
    Reframe
    Keep the effect on change only.
  28. Motion 90e2c7d19

    Glass that bends only where it can

    Frame
    I asked for liquid-glass chrome, and the bar was already frosted, so the question was what glass could add on a site that is mostly text on paper.
    Dimensions
    where refraction is visible; bevel height and displacement; legibility; engine support; scroll cost
    Move
    A 10 px lip under the navigation bar refracts what scrolls beneath it, in Chromium only.
    Backtalk
    A 14 px lip smeared text into a glitch, a glass theme menu let words show through, and moving the frost into a pseudo-element broke it outright, because the bar’s view-transition name makes it a backdrop root. Scrolling stays at 60 fps with it on or off.
    Reframe
    Glass reads as glass over images and motion, not over paper.
  29. Objects, places and demos 9dc3a5f16

    The scaffold, small enough to try

    Frame
    The DesignWeaver page described dimensional scaffolding in words and figures, and a visitor never got to feel what it does to a prompt.
    Dimensions
    fidelity to the study; what the page itself writes; what a reader sees change
    Move
    A palette with four dimensions and the tags from a CHI 2025 talk session, opening on that session’s prompt and rebuilding a fixed sentence on any change.
    Backtalk
    A word counter backfired, because the fixed sentence is terser than the model’s prose and adding an eighth tag dropped the count from 26 words to 16; it now counts tags across dimensions.
    Reframe
    The new copy joins the batch for my review.
  30. Color, time of day and tokens 21fa75817

    A sun you can drag, and a switch that stills everything

    Frame
    Four theme buttons felt static. I asked for a control that feels like the day itself and syncs the 3D scenes, and for a good-looking way to pause motion.
    Dimensions
    where an hour lives; which surfaces follow every move; contrast of continuous color; how many places must learn about paused
    Move
    A sun arc that picks any minute and previews it across the page, the footer coast and the 3D home, and a Pause motion switch laid over the reduced-motion query.
    Backtalk
    Continuous color stays out of text. The first sky glow at 17 % opacity was invisible, while 30 % reads as light without touching contrast, and one of the tests expected 1:20 pm plus four hours to be evening.
    Reframe
    Keep the panel’s four stops; they are both the quick choice and the test contract.
  31. Objects, places and demos 0ebf99fb7

    A coffee ring, by the physics of drying

    Frame
    The coffee stain was a broken ring of dashes, closer to a stamp than a stain, and it nearly vanished in the evening theme.
    Dimensions
    rim sharpness; tide lines; a second ring; drips; strength in light and dark themes
    Move
    The ring drawn the way one dries, with a continuous rim sharp outside and fading inward, tide lines and drips, and a lighter dried palette in the evening.
    Backtalk
    The first interior turned into pale clouds and its fiber displacement sawtoothed the rim.
    Reframe
    The stain is a desk cue, not a feature.
  32. Objects, places and demos 89f45a4da

    A stain that looked like glass

    Frame
    I found the redrawn stain lamer than before. In place it read as a pale glass disc, with a perfect thin outline and bubble-like drips.
    Dimensions
    medium; how coffee spreads as it dries; the paper beneath; main-thread cost; what the security policy allows
    Move
    A raster of per-pixel coffee density, painted fresh on every visit as washes with dark edges, backruns and granulation, in time-boxed idle slices.
    Backtalk
    The first rasters were thin and grey, and the puddles looked like stickers until they dried like watercolour. The first integration showed nothing, because the Content-Security-Policy admits data URLs but not blob URLs.
    Reframe
    Keep the stain quiet enough that any text it crosses stays easy to read.
  33. Design memory

    Technical records that the next pass can start from

    Frame
    I asked for the technical details, key source code and citations to be recorded behind each long-running project, so later agents can build on what has been done.
    Dimensions
    record schema; what a person reads and what a program reads; how a next move is proposed; integrity checks
    Move
    Three records as data, each rendered as a page beside its project, served as JSON and turned into a next-move brief by a script, with a test for paths, sources, systems and commits.
    Backtalk
    Compiling them surfaced real gaps, such as the clifftop planting swaying on its own rule outside the shared wind field. A record route under a project made the AI link point at a missing anchor, so pages can now name their AI anchor.
    Reframe
    Append each new move to its record when it ships, and let the brief rank what to try next.

Open problems

  1. Does the redesign help visitors understand the research?

    Needs research Structure and wayfinding

    Every comparison here is design history under fixed captures, not a study. Comprehension needs real visitors, a task and a baseline, and the old site exists only as an archive.

    Candidate moves

    • A small first-glance test with research peers and prospective students, asking what I study after 15 to 30 seconds, on the archived and current homepages.
  2. Foundation work still open from the September roadmap

    Ready Visual QA and checks

    The focus mixin migration, the accessibility spec additions and purge parity as a documented lane each touch many partials or the deploy path, so they keep losing to visible work.

    Candidate moves

    • Migrate focus styles to one mixin, partial by partial, with the overrides audit after each.
    • A documented lane that builds, purges and serves _site for the checkpoint suite.
  3. Retell the remaining project stories

    Needs a decision Structure and wayfinding

    Each story deserves the medium its evidence supports, and a uniform template would flatten them. Deep rewrites go one route at a time with fixed before and after captures.

    Candidate moves

    • Playful provenance stories first, keeping each joke and moving custody details behind it.
    • Research artifacts next, leading with the question and the canonical publication.
  4. A continuous illustrated world below the desk

    Needs a decision Objects, places and demos

    A scroll-scrubbed backdrop carrying the desk’s horizon and coast down the homepage needs artwork, must stay quieter than text, and must not move the largest contentful paint away from the hero.

    Candidate moves

    • A first generated or authored asset reviewed at four viewports, with its prompt, model, date and license recorded first.

    Read

  5. Margin notes for long posts

    Blocked Type, reading column and image weight

    No post or project uses footnotes yet, so margin notes have nothing to show.

    Candidate moves

    • Build sidenotes with the first post that needs footnotes.
  6. Bring the homepage onto the shared tokens

    Ready Color, time of day and tokens

    The homepage’s own partial predates the Material-Lite and type tokens and is a high-conflict file shared with the desk scene, so changes there need one writer at a time.

    Candidate moves

    • Adopt the spacing and focus tokens in _sass/_home.scss in a dedicated pass, checked with the iteration and checkpoint lanes.

Before changing anything

Read first

Keep intact

  • Decision order. Research meaning, credit, accessibility and a working route come before first-glance clarity, which comes before proof proximity, interaction state, and finally atmosphere and delight.
  • Keep the signature copy exact, including “Making AI tools that sharpen design judgment.” and “Design, Evaluate, Situate.”
  • Brand orange is identity only. Links, controls and focus use the active time-of-day accent, and the four palettes carry contrast.
  • Every effect is a complete still page under reduced motion, Pause motion, without a fine pointer, and under automation unless the URL carries ?cinematic=live.
  • No scroll or wheel hijacking, cursor trails or ambient loops; parallax only between two layers that belong together.
  • Human and AI routes stay separate surfaces. AI routes are compact, source-linked and motion-free, and the switch between them is an ordinary link.
  • Research figures stay whole and uncropped, with declared dimensions.
  • When a review calls an element confusing, remove it rather than tune it.
  • New font sizes use a type role; the raw font-size ceiling in the style contract stays at 333.
  • Iterate on one route, state and viewport; checkpoint explicit routes at four viewports; run the full matrix only for a release.
  • Render-cost and weight changes must not change the pixels a visitor sees.

Keep these checks green

  • test/style_contract.js Starter wiring, type roles and the raw font-size ceiling, plugin and visual-workflow contracts.npm.cmd run lint:style-contract
  • test/visual/sitewide.spec.js Public routes at four viewports, one h1, the skip link first, alt text on every image, overflow and console errors.npm.cmd run test:visual:checkpoint
  • test/visual/iteration.config.js The one-screenshot iteration lane on an already running preview.npm.cmd run test:visual:iterate
  • test/validate_publication_outputs.py The AI profile, llms.txt and the structured catalogs.python test/validate_publication_outputs.py _site
  • test/test_site_experiments.py Site-experiment case studies, their chronology, cards and reproduction guides.python -m unittest test.test_site_experiments
  • test/test_design_records.py These technical records, their paths, sources, commits and links.python -m unittest test.test_design_records

Sources

  1. Internet Archive. Wayback Machine capture of dylantao.github.io, February 9, 2026, 01:34:29 UTC. web.archive.org/web/20260209013429/https://dylantao.github.io/
  2. Donald A. Schön. The Reflective Practitioner: How Professionals Think in Action. Basic Books, 1983. www.hachettebookgroup.com/titles/donald-a-schon/the-reflective-practi...
  3. Maruan Al-Shedivat and contributors. al-folio, a Jekyll theme for academics, version 1. github.com/alshedivat/al-folio
  4. Rasmus Andersson. Inter typeface (SIL Open Font License). rsms.me/inter/
  5. Google. Material Design 3. m3.material.io/
  6. Paper. Paper Shaders, @paper-design/shaders 0.0.80 (Apache-2.0). shaders.paper.design/
  7. GreenSock. GSAP 3.15 and ScrollTrigger, under the GSAP Standard License. gsap.com/
  8. Jeffrey Heer and George Robertson. Animated Transitions in Statistical Data Graphics. IEEE Transactions on Visualization and Computer Graphics 13(6), 2007. idl.cs.washington.edu/files/2007-AnimatedTransitions-InfoVis.pdf
  9. Edward Segel and Jeffrey Heer. Narrative Visualization: Telling Stories with Data. IEEE Transactions on Visualization and Computer Graphics 16(6), 2010. idl.cs.washington.edu/files/2010-Narrative-InfoVis.pdf
  10. Venkatesh Sivaraman and Adam Perer. Counterpoint: Orchestrating Large-Scale Custom Animated Visualizations. CMU Data Interaction Group, 2024. dig.cmu.edu/publications/2024-counterpoint.html
  11. Frank Elavsky. Chartability, heuristics for accessible data visualization. www.frank.computer/chartability/
  12. W3C. CSS View Transitions Module Level 2. www.w3.org/TR/css-view-transitions-2/
  13. W3C. Scroll-driven Animations. www.w3.org/TR/scroll-animations-1/
  14. W3C. CSS Scroll Snap Module Level 1. www.w3.org/TR/css-scroll-snap-1/
  15. Apple. Animate with springs, WWDC23. developer.apple.com/videos/play/wwdc2023/10158/
  16. W3C. CSS Values and Units Module Level 4, font-relative lengths. www.w3.org/TR/css-values-4/
  17. Bennet B. Murdock. The Serial Position Effect of Free Recall. Journal of Experimental Psychology 64(5), 1962. doi.org/10.1037/h0045106
  18. Peter Pirolli and Stuart Card. Information Foraging. Psychological Review 106(4), 1999. doi.org/10.1037/0033-295X.106.4.643
  19. W3C. Understanding Success Criterion 2.2.2, Pause, Stop, Hide, WCAG 2.2. www.w3.org/WAI/WCAG22/Understanding/pause-stop-hide.html
  20. W3C. Understanding Success Criterion 1.4.3, Contrast (Minimum), WCAG 2.2. www.w3.org/WAI/WCAG22/Understanding/contrast-minimum.html
  21. WHATWG. HTML Living Standard, event loops and the processing model. html.spec.whatwg.org/multipage/webappapis.html#event-loops
  22. W3C. Understanding Success Criterion 2.4.1, Bypass Blocks, WCAG 2.2. www.w3.org/WAI/WCAG22/Understanding/bypass-blocks.html
  23. W3C. Understanding Success Criterion 1.1.1, Non-text Content, WCAG 2.2. www.w3.org/WAI/WCAG22/Understanding/non-text-content.html
  24. Ben Shneiderman. Direct Manipulation: A Step Beyond Programming Languages. IEEE Computer 16(8), 1983. doi.org/10.1109/MC.1983.1654471
  25. Robert D. Deegan, Olgica Bakajin, Todd F. Dupont, Greg Huber, Sidney R. Nagel and Thomas A. Witten. Capillary Flow as the Cause of Ring Stains from Dried Liquid Drops. Nature 389, 1997. doi.org/10.1038/39827
  26. Cassidy J. Curtis, Sean E. Anderson, Joshua E. Seims, Kurt W. Fleischer and David H. Salesin. Computer-Generated Watercolor. SIGGRAPH 1997. grail.cs.washington.edu/projects/watercolor/
  27. W3C. Filter Effects Module Level 2, the backdrop root. drafts.fxtf.org/filter-effects-2/
  28. W3C. Filter Effects Module Level 1, the feDisplacementMap filter primitive. www.w3.org/TR/filter-effects-1/
  29. David Wood, Jerome S. Bruner and Gail Ross. The Role of Tutoring in Problem Solving. Journal of Child Psychology and Psychiatry 17(2), 1976. doi.org/10.1111/j.1469-7610.1976.tb00381.x
  30. W3C. Media Queries Level 5, the prefers-reduced-motion feature. www.w3.org/TR/mediaqueries-5/#prefers-reduced-motion
  31. Jeremy Howard and contributors. The /llms.txt file, a proposal for language-model-readable site indexes. llmstxt.org/
  32. Jing Yu Koh, Robert Lo, Lawrence Jang, Vikram Duvvur, Ming Lim, Po-Yu Huang, Graham Neubig, Shuyan Zhou, Russ Salakhutdinov and Daniel Fried. VisualWebArena: Evaluating Multimodal Agents on Realistic Visual Web Tasks. ACL 2024. aclanthology.org/2024.acl-long.50/
  33. Eve Bouffard with Aaron Epstein. Y Combinator’s 2026 design walkthrough, demonstrating Paxel’s Human and Machine views. youtu.be/VbqaL_eHhKY?t=433
  34. Pear. pear.no, a reference for one pinned scene whose copy changes as the reader scrolls. pear.no/
  35. React Bits. Chroma Grid and Folder components, studied as interaction references; no code was copied. reactbits.dev/components/folder
  36. Microsoft. Playwright, browser automation for the visual harness. playwright.dev/

Compiled on October 15, 2026 by Anthropic’s Claude from the code, the living heuristics, the experiment backlog, the roadmap, the October studio log and the Git history, for Sirui Tao to review and extend.