How a General Translation design exploration runs from research to one landed design.
node scripts/install-skills.mjs gt-explorations --project <dir>Run it from a Prototemplate checkout. It links skills/gt-explorations into the project’s .claude/skills and .agents/skills; --copy vendors the folder instead, and --dry-run prints each step first.
General Translation (GT) builds localization tools for developers, and Kevin Liu does its design, website and product work. He designs in rounds. He asks for several directions, compares them live, picks by number, and asks for variants of the pick until one design lands. A direction is one complete design of a page or a site, built as its own running route. This skill holds the mechanics of a round, from the research before it to the cleanup after it, and gt-aesthetic holds the taste each round is judged by.
Paths are relative to a checkout. $PROTOTEMPLATE is Prototemplate, Kevin's design lab and the public hub at prototemplate.com, where the site directions live. $GT_CLOUD is gt-cloud, the monorepo of GT's site, docs and dashboard. Kevin's wiki is github.com/Kevin-Liu-01/Kevin-Wiki, and its paths below are relative to its checkout. references/rounds.md records every round from July to October 2026 with what was asked, what Kevin picked and the rule it set. scripts/distinct-set.mjs checks that a set of options differ before Kevin sees it.
wiki/design/README.md is the index, and ui-library-ranking.md, component-library-sources.md and x-bookmarks-design-ui.md list the libraries and references he trusts), his X bookmarks, and every post he links. Kevin, 2026-07-28: "read the x posts and ingest artifacts using fieldtheory and see the pictures to see what i want".ft, wiki page wiki/tools/fieldtheory.md). ft sync downloads new bookmarks and their media, ft search "<terms>" searches them, and ft show <id> --json prints one. A post Kevin links without bookmarking it is captured with the wiki skill absorb-sources, media included.$PROTOTEMPLATE/docs/research/STORYBOARD.md opens with the July references, each named for the section it governs (the hero mechanic, the hero background, the story window), and docs/research/inspo.md ranks the reference sites from the bookmarks with what to take from each.gt-aesthetic, "Measuring the reference"). Kevin, 2026-07-29: "first we need to delve deep into what makes the vite plus and oxlint websites tick". The answer was docs/research/teardown-measured.md, which read every value with getComputedStyle and found that the two sites are one system in two modes./d/singularity-dossier) governs the site, and the brand deck governs product surfaces (gt-aesthetic section 1). Each round names its reference in its brief.docs/reference-shots/<site>/ holds the July captures of generaltranslation.com, oxc, resend and viteplus. The July documents under docs/research/ show the method. Their aesthetic mandates (black, white and metallic, Switzer headings) were replaced later, and gt-aesthetic holds the current ones.Before cloning a product or building a feature that answers one, research the product and write the findings down before the first direction:
Kevin asked for this on 2026-09-12 and 2026-10-01 on a project of his own, and the method applies to GT work unchanged. docs/research/feature-inventory.md is the GT example: each capability with the proof a visual must show and the misunderstanding it must prevent.
docs/research/MODULES_PLAN.md came from that ask. It is a build contract written so that five builders could work in parallel without inventing anything, ordered module by module the way Kevin reviews.Build one section, page or state, show it, and replicate it only after Kevin signs off on its grammar (gt-aesthetic section 5). On 2026-08-04 Kevin kept one element of a full build made on an unconfirmed reading, the Locadex isometric.
A direction differs from the others on three axes.
| Axis | The question it answers | Examples from the registry |
|---|---|---|
| Silhouette | What shape does the page or its hero make at thumbnail size? | one ruled column; stepped terraces; a concentric disk; a wall of courses |
| Material | What is the surface made of, and which engine draws it? | hairlines alone; an ordered-dither field; glyph rain; a lensing shader |
| Action | What is the one motion moment, and what visibly changes? | words condense out of rain; a component crosses a lens and exits translated |
A palette, a title or a new arrangement of the same parts does not make a new direction. On 2026-09-14 a deco round rebuilt ten directions as forks of one earlier direction, and seven of the ten heroes came out with the same layout, headline and hero visual. Kevin rejected the round. Before building, write a table with one row per direction and these three columns. Two rows that match in every column are one direction. The registry keeps each direction's action as signature.
bash node skills/gt-explorations/scripts/distinct-set.mjs public/shots/light/<slug-a>.jpg public/shots/light/<slug-b>.jpg node skills/gt-explorations/scripts/distinct-set.mjs <folder of frames> --strict
It flags a pair under 2% mean difference as the same picture and a pair whose tone grids correlate at 0.9 or above as the same composition. A clean report means only that no two options are near copies. The silhouette, material and action table is still checked by eye.
src/app/d/<slug>/, with its CSS scoped under its own root class (.<name>-root) so it never restyles another direction. $PROTOTEMPLATE/skills/prototemplate/references/adding.md ("A direction") gives the steps file by file.$PROTOTEMPLATE/src/lib/directions.ts (DIRECTIONS) is the one list. The gallery at /, /directions/<slug>, /compare, the presenter at /present, the sitemap and the page check (scripts/site-pages.mjs) all read it, so a direction is registered once.
| Field | What it holds |
|---|---|
label | the number Kevin uses, as two digits |
n | the round or exploration number the direction came from |
slug | the route under /d, fixed for the life of the direction |
name, concept, signature, tone | the name, the idea in one or two sentences, the one motion moment, the theme family |
site | a full site with its own /enterprise page |
reference | the shipped outcome |
The shipped outcome carries no label. It is what the rounds produced, and a number would enter it in the comparison (commit 127960d, 2026-08-25). src/lib/marks.ts keeps the current mark the same way, as REFERENCE_MARK, and never offers it as a candidate.
docs/research/ITERATION_SPEC.md mapped each position to its slug before work began. Today the gallery's book view shows label, and the viewer shell's sidebar and toolbar count positions in the site map's order (pad2(position + 1) in src/app/directions/sections.ts), so Toolchain is label 01 and row 05 on the shell. When a number could name two directions, find which view he was on, and ask once if it is still unclear.DIRECTIONS held 27 entries while README.md, public/llms.txt and src/app/directions/DirectionViewer.tsx said seventeen, ARCHITECTURE.md and src/app/craft/CraftArticle.tsx said sixteen, src/app/GalleryViewer.tsx said 17 and thirteen, and a comment in src/lib/directions.ts itself said thirteen explorations. After any registry change, find the counts and fix them in the same change:bash grep -rniE "\b(thirteen|sixteen|seventeen|twenty|[0-9]+ directions)\b" README.md ARCHITECTURE.md public/llms.txt src/app src/lib src/components | grep -v "src/app/d/"
Kevin compares directions live in one place. Kevin, 2026-07-28: "give me one place to switch between all of these". Prototemplate has four views over the registry.
| Route | What it shows | Source |
|---|---|---|
/ | the gallery: every direction as an article (Book), one live 1440 exhibit at a time (Live), or every capture at once (Grid) | src/app/GalleryViewer.tsx |
/directions/<slug> | one direction on the shell: its summary, both captures and a live frame | src/app/directions/ |
/compare | two directions side by side in scroll-locked same-origin frames, with the pair in the hash (#a=<slug>&b=<slug>) | src/app/compare/ |
/present | the presenter: the opening slides, every prototype live with a note and a star rating, and a closing gallery | src/app/present/ |
localStorage key gt-presenter-review:v1, src/app/present/viewer/reviewStore.ts). They never reach another machine or an agent, so ask Kevin for his notes in chat. src/app/present/directions.ts filters the presenter's list; Signal has been out since 2026-09-09.?chrome=0. Every capture uses it, so the control is never judged as part of a design.For variants of a production page in gt-cloud, put the switch on the real route. The variants round of 2026-08-12 (seven pages, five variants each) used:
?v=1..5 parameter with a per-page cookie;The dispatcher stayed thin so that removing the losers was one delete. Kevin chose slot 1 on all seven pages, and the flatten removed about 16k lines (gt-cloud commit 1db410568). The plan, VARIANTS-PLAN.md at the root of the commit before it, also set the copy law for every variant: production wording, approved wording, or no words.
Shaders, dithers, hover effects and palettes get an options menu inside the page, so Kevin tries each one in place. Kevin, 2026-08-05: "add an option menu around the bottom right of the singularity hero component".
src/components/shared/FieldEffectsMenu.tsx is the pattern for a hero's cursor effects: a row of chips docked at the bottom right of the field, one per mode plus off. Hover or focus previews a mode, and a click commits it.BAYER_PRESETS in src/lib/studio-field.ts is the roster of the Bayer family. src/components/shared/HeroFieldSwitcher.tsx swaps the Dossier hero's field through it, and the craft page's Bayer demo maps over the same list.gt-aesthetic, "Local review"). A change to one area is still shown as before and after crops (gt-aesthetic, "Showing the work").gt-reporting section 1).public/shots/light/<slug>.jpg and public/shots/dark/<slug>.jpg: the first fold at 1440 by 900 under ?chrome=0, which directionShots() in src/lib/directions.ts reads. docs/harness/shoot-one.mjs <slug> public/shots writes them. Its address is fixed to the July port 3006, and it saves a capture even when the page fails to load, so set the address to the running server and open every capture before using it.A review of many directions goes module by module: one module across every direction, then the next. Kevin's July list was hero, story, product bentos, banners, Locadex, footer, context groups, dashboard, integrations and pricing (2026-07-29). Write the plan in that order (docs/research/MODULES_PLAN.md) so one module can be pulled up across every direction and rated alone. The July viewer for this is tools/module-review on gt-cloud's redesign/diagram-standard branch. It frames one module across every direction and rates each out of five.
docs/research/ITERATION_SPEC.md is the July table.src/app/d/toolchain and rescope its CSS under their own root class (ARCHITECTURE.md, "The SSOT rule").src/lib/studio-field.ts).A round converges through a separate harsh critic who scores the work against the reference side by side. gt-orchestration section 4 holds the loop, the bar and the July rubric (docs/research/DESIGN_STANDARD.md section 8). A design round feeds the critic composites.
docs/harness/gallery-shoot.mjs does this for the Dossier's sections. Its default address is the July port 3006, so run it with REDESIGN_BASE=http://localhost:3005.docs/composites/ holds the July composites of the work beside resend, oxc and viteplus. Two captures join at a common height with ffmpeg:bash ffmpeg -i ours.png -i reference.png -filter_complex "[0]scale=-2:900[a];[1]scale=-2:900[b];[a][b]hstack=inputs=2" composite.png
gt-aesthetic section 2). Kevin, 2026-08-11: "these diagrams are so bad. i literally want you to restart these lol".The exemplar Kevin picks becomes the documented default, with its parameters in code and a comment that names the pick. BAYER_DEFAULT_ID in src/lib/studio-field.ts names 02 bayer-8x8 as the shared default, and the landing hero's measured composite is the strength every later field is held to (gt-aesthetic, "Material").
DIRECTIONS with its in-page switches until Kevin cuts or retires it. HeroFieldSwitcher still swaps the Dossier hero's field on 2026-10-05. A direction cut inside a round leaves in a commit that names it: b6a7eba names the three revival directions cut on 2026-09-14, and its parent holds their code.git diff <before> -- <winner's paths> prints nothing), and capture its route before and after at the same viewport. On 2026-08-12 the flattened sign-in route was checked byte-identical to the committed page.src/lib/archive.ts: its slug and name, a 1440 first-fold capture and a full-page capture under public/shots/archive, and the last commit that held its code. /archive/<slug> shows it, and git checkout <lastCommit> -- src/app/d/<slug> restores it. Retiring also prunes its paths from scripts/lint-practices.baseline.json.motion/out/v<N>/ folder before it is overwritten, and each film folder keeps archive/ for earlier compositions (gt-films, "Renders").gt-local-dev section 1).gt-ship section 8 holds the landing steps for the shared checkout.k/<topic> branch in its own worktree and becomes a PR when Kevin asks for one (gt-ship section 1).distinct-set.mjs flags no pair.DIRECTIONS once, its label is the number Kevin uses, and every count written in prose matches the registry.GT skills: gt-aesthetic (the references, the verdicts and the review loop), gt-orchestration (the critic loop and the agents that run it), gt-verify (what each kind of check proves), gt-reporting (showing a round to Kevin), gt-local-dev (review servers), gt-ship (landing), prototemplate (the registries and adding a direction), gt-dither (the Bayer engines and presets) and gt-films (film rounds and their archive). Wiki skills: absorb-sources and x-bookmark-absorb (ingesting posts and bookmarks), design-engineering-polish (its references/signature-first-exploration.md applies the same duplicate test to signature visuals), animated-component-libraries (component sources) and agent-browser.
src/lib/directions.ts, archive.ts, marks.ts and studio-field.ts; src/components/shared/FieldEffectsMenu.tsx and HeroFieldSwitcher.tsx; src/app/craft/BayerDemo.tsx; src/app/GalleryViewer.tsx; src/app/directions/sections.ts and DirectionViewer.tsx; src/app/compare/; src/app/present/ (directions.ts, viewer/reviewStore.ts, viewer/Scoreboard.tsx); src/app/craft/CraftArticle.tsx; ARCHITECTURE.md ("The direction registry", "The SSOT rule", "The gallery pipeline"); docs/research/STORYBOARD.md, inspo.md, teardown-measured.md, teardown-oxc.md, teardown-viteplus.md, feature-inventory.md, MODULES_PLAN.md, ITERATION_SPEC.md and DESIGN_STANDARD.md; docs/reference-shots/; docs/composites/; docs/harness/gallery-shoot.mjs and shoot-one.mjs; skills/prototemplate/references/adding.md; skills/gt-aesthetic/SKILL.md; skills/gt-orchestration/SKILL.md section 4; skills/gt-local-dev/SKILL.md section 1; skills/gt-ship/SKILL.md sections 1 and 8; skills/gt-films/SKILL.md. Commits fee151f, 1d3bd12, db06905, 156ca85, e80aea8, b6a7eba and 2d6f32b (the deco rounds, 2026-09-14), 127960d (2026-08-25) and c064945 (2026-09-08). All read 2026-10-05 on speed-marks at 2a8453c.1db410568 (the variants flatten, 2026-08-12) and VARIANTS-PLAN.md in its parent; tools/module-review on the branch redesign/diagram-standard (commit ab9beeb2e).wiki/design/README.md, ui-library-ranking.md, component-library-sources.md and x-bookmarks-design-ui.md; wiki/tools/fieldtheory.md; skills/engineering/design-engineering-polish/references/signature-first-exploration.md.The folder skills/gt-explorations as agents fetch it. Each file opens raw.
SKILL.mdreferences/rounds.mdscripts/distinct-set.mjs