How General Translation diagrams are drawn.
pnpm skills:install gt-diagrams --project <dir>Run it from a Prototemplate checkout. It links skills/gt-diagrams into the project’s .claude/skills and .agents/skills; --copy vendors the folder instead, and --dry-run prints each step first.
A General Translation (GT) diagram follows one grammar on every surface: the Prototemplate site, the landing app, the brand deck, blog graphics and the films. Pages and slides draw it as inline SVG; the blog graphics are HTML pages and some films draw on a canvas. It mounts a drawn component before it draws anything new, links objects with the doubled line, and is read by eye at 2x in both themes, because the line auditor skips everything inside an SVG. Paths are relative to a Prototemplate checkout ($PROTOTEMPLATE, github.com/Kevin-Liu-01/Prototemplate, Kevin's design hub with the canon in DESIGN.md and BRAND.md) unless they name $GT_CLOUD (a checkout of github.com/generaltranslation/gt-cloud at origin/main, whose apps/landing serves generaltranslation.com).
A diagram earns its place when it shows a relationship the text alone does not: a flow of three to six steps, a before and after pair, a scale or an axis, a stacked layer model, a grid or a ladder, or a timeline (deck/DECK-GRAMMAR.md, Diagrams). A clean list of statements stays a list, set as ruled rows. Boxes that restate a list with no relationship drawn between them fail review.
app/page.tsx and the three JSON files the config writes; SentenceWidth lays out and measures each locale; SdkLedger replaced a plate stack that drew slabs where the package names belonged. Grey bars or squiggles in place of text fail review.src/app/d/_v0/sections/StackTower.tsx). Text seated in an isometric face at chip scale is never legible, so the enterprise diagram's three context keys stay bare and a stage label names them.Kevin measures diagrams against generaltranslation.com and resend.com (Kevin, 2026-07-30). On 2026-08-11 he restarted the landing diagrams: "these diagrams are so bad. i literally want you to restart these". Build one exemplar, get his sign-off on its grammar, then repeat it (redesign-v0-verdict). Explorations stay on localhost until he has reviewed them.
Mount an existing component when the content matches. The redesign's Figma mocks were screenshots of these components (Kevin, 2026-08-04). A new drawing is for new content only, seated inside a framed cell.
The lookup from content to component (translation flow, locale routing, text expansion, context, plurals, right to left, writing systems, the glossary and preview surfaces, delivery from the edge, the full stack, context inheritance, the SDKs, numbers, locale names, connectors and isometric objects) opens references/components.md. Every file is under src/app/d/toolchain/diagrams/; the connector is src/components/shared/diagrams/DoubledLine.tsx, and isometric objects are section 10.
No route in Prototemplate mounts the rows marked unmounted, nor TcStackTrace or the TcMini set. Read them as reference drawings and check them against sections 3 to 6 before mounting one: TcCtxLayers draws its thread as two separate paths and ends it in a 14 by 11 arrowhead, which breaks both rules. Five directions keep forked copies of the lang/ or surface/ set under src/app/d/<direction>/diagrams/; change the toolchain original.
The components also run live on /docs (the build log, with the DoubledLine and iso plates), in the deck (slides 30, 31, 33, 35 and 74; start a new slide diagram from their markup) and in gt-cloud's landing ports; the files are in references/components.md ("Where the components run live").
references/components.md lists every component with what it shows and where its accent goes.
The deck's grammar (deck/DECK-GRAMMAR.md, Diagrams; slide 33) states the rules for every surface:
class="ink" (ink), class="mid" (--ink-2, the body text tone) and class="hair" (--hair). On a page the root's semantic layer gives the same three, for example --tc-ink, --tc-ink-2 and --tc-hair on the toolchain root.stroke-width 1 or 1.5. Square caps, no rounded joins. A 1px line at a 1:1 scale sits on a half-pixel coordinate (y1="70.5") so it fills one row of device pixels.var(--ink), var(--paper) and var(--plate) on the deck; the root's tokens on a page; currentColor with fill-opacity steps for faces. A hex written as an SVG attribute passes no-hex-colors, so review catches it; which lint covers which folder is in references/color.md.vector-effect: non-scaling-stroke, so a 1px line stays 1px.DECK-GRAMMAR.md tolerates a filled triangle up to 8px, and older toolchain drawings carry arrowheads (a 14 by 11 triangle in tc-ctx-layers.tsx, IsoArrow in IsoSolid.tsx); slide 33 states the stricter rule, and new drawings follow it.docs/GRAPHICS.md).Each surface spends the accent differently.
| surface | accent rule | source |
|---|---|---|
| site page | One spectral accent per page (#2f5ce0 on paper, #86a8ff on the dark band), spent by each drawing on exactly one element. On the toolchain page the accent's six places are all diagram states. | DESIGN.md sections 1 and 6; src/app/d/toolchain/styles.css |
| deck | No accent on text, lineEach surface spends the accent differently: one element per drawing on a site page, none on text, lines or fills in the deck, one edge at a time in a film (whose palette since round 4 is its material), and red for removed with blue for the replacement in a blog graphic (references/color.md). s in technical diagrams as an instrument and avoids them where possible; the deck uses no mono outside its .panel. The shared DiagramFrame set's 9.5px mono text predates this rule. |
lang and dir (DESIGN.md section 8).Label sizes and floors differ by surface.
| surface | label sizes | floor |
|---|---|---|
| deck sheet, 1600 by 900 | 20px in --ink-2 (svg.dia text), 26px in ink at weight 500 (.lab) | 18px (.sm); any text under 15px on the sheet is a defect |
| blog graphic, 1600 by 900 stage shown at 0.44x in the article column | label chips 28px Inter 600; measurement labels 28px Geist Mono on a backing pill | 26px after zoom-to-fit (MIN_TEXT in graphics/build/gen-lib.js, held by pnpm graphics:audit) |
| film, 1920 by 1080 | the deck ladder at 1920 in motion/kit/tokens.css (.t-cap 18 to .t-display 106) | 18px |
| page | the page's own type tokens | the page's smallest label token, at the narrowest width the figure renders (check 390) |
Size after scale. A viewBox that does not render 1:1 scales its text with it. Compute the rendered scale and size the text so it lands on the target. Slide 31's 800-unit viewBox renders at 0.914 in its column, so its labels are set at 22px and land at 20.1px; the slide records that in a comment beside the rule. scripts/figure-check.mjs in this skill prints every label's rendered size. In a blog graphic a composition wider than 90% of the frame is scaled down with its labels, so the fix for a small label is a narrower composition.
The doubled line is the brand's connector. It is one path stroked twice: a full-width stroke in ink, then a narrower stroke in the surface color on top, which leaves two parallel threads at a constant gap along any curve (DESIGN.md section 5). Kevin asked for it in diagrams on 2026-07-29 ("the double line 'adidas' like aesthetic of gt").
--thread-gauge: 1.5px per thread, --thread-gap: 3px between them. The thread layer is 6px wide and the core is 3px. Use the tokens; do not invent gauges.DoubledLine (src/components/shared/diagrams/DoubledLine.tsx) takes d, core (required), gauge, gap, ink, inkB with splitD, and children for the pulse. In markup the same three layers are classes, as in .tf-thread, .tf-pulse and .tf-core in src/app/d/toolchain/diagrams/flow.css.core is the actual surface behind the drawing (var(--tc-plate), var(--tc-panel), var(--color-ink)). A core in another color shows as a painted stripe.d is rewritten to the slice under the window on each tick. It never moves by stroke-dasharray, which drifts under a stretched viewBox. It ships hidden in CSS, and under reduced motion it never starts.splitD, the same center path closed off one side of the viewBox. The seam lies inside the core's gap on every bend.references/doubled-line.md has the code, the pulse helpers and their timing, the two-tone recipe, the sizes per surface and the auditor's allow list for doubled lines drawn in CSS.
Every line has one owner (DESIGN.md section 2).
non-scaling-stroke; slide 30 draws a 15-unit plus at stroke-width 1.5 in ink; the sheet's corner crosses are 11px in --cross.preserveAspectRatio="none" lets a connector strip fill a fluid column; TranslationFlow's fork is a 72 by 260 viewBox stretched between two panels. Under that stretch:
vector-effect: non-scaling-stroke;So a stretched SVG holds straight taps and no text. The sign-in workflow diagram replaced its quadratic connectors with straight taps for this reason (k-pages-restart-round, 2026-08-11). TranslationFlow's fork predates that round and still bends its branches with cubic curves; figure-check.mjs warns on each one, and a new stretched strip uses straight taps. Labels for a stretched strip live in HTML beside it. Under 620px TranslationFlow hides the fork and stacks its panels; a figure that cannot hold its shape on a phone reflows and is never squashed.
Dashes and draw-ons carry their own traps (DESIGN.md section 9; gt-motion section 7). The ones that decide how a diagram is built are in references/dashes.md: pathLength is ignored under non-scaling-stroke in Chromium, a traveling dash tiles on a scaled SVG, dashes clip at the end of a closed subpath, the sign of a parked offset sets which end a draw-on reveals from, and the source d is cached and an empty path guarded before an animation rewrites it.
currentColor, so dark mode is a token remap and the drawing needs no second version (DESIGN.md section 1). IsoFrame and the toolchain family take no color props; a page themes the whole family from one ancestor.figure-check.mjs fails a figure whose box or label count differs between themes.core a token that remaps with the ground; a literal paper core shows as a white stripe in the dark theme.<mask style={{ maskType: 'alpha' }}> holding the mark's image (public/brand/no-bg-gt-logo-light.png; gt-logo-light.svg may carry a background), with a currentColor or token-filled rect drawn through the mask, so the mark takes the surface's ink in both themes. references/isometric.md section 5 has the construction, the asset for each size and the seat inside a plane() face. The Locadex diagram carries the Locadex mark and is never a gif (Kevin, 2026-08-04), and gt-ui's no-gif-mark rule fails a gif used as a mark. The deck pastes marks as currentColor markup from public/marks and never redraws them.data-theme flip (DESIGN.md section 11).data-dark twin where one exists in deck/shots/, and otherwise keeps a 1px --hair border. Blog covers ship in a dark and a light version at the same framing.--tc-panel white), so check every dark plate in the light theme.The line auditor (scripts/lint/lines.mjs) returns early for any element inside an svg or a canvas, so a figure's strokes, junctions and crossings are checked by eye at 2x crops in both themes (DESIGN.md section 2). scripts/figure-check.mjs in this skill captures the figure and its crops at 2x in light and dark, prints each SVG's viewBox and scale, and fails on a label under --min, a distorted label, a stroke in a stretched viewBox without non-scaling-stroke, a pathLength dash under non-scaling-stroke, and geometry that differs between themes; scripts/deck-page.mjs assembles the deck for a slide check. It cannot judge a junction: read every crop for one clean pair at each merge and fork, a border cross at each crossing, no seam where a leader meets a hull, 12px clear around each label, and a complete still under reduced motion. The commands, the crop syntax and the surface gates (deck/shoot-slide.mjs, pnpm graphics:audit, pnpm check:pages, pnpm lint:lines:shell) are in references/checking.md.
GT draws every three-dimensional figure in one isometric family: one 30 degree projection (iso.ts, which every React figure imports), light from the upper left with fixed face tones (4, 9 and 15 percent), the extrusion recipe (opaque hull, face fills, hairlines), IsoPrism and plane(), one corner radius, plate thickness and air, depth by per-plate stroke alpha, one accent object per drawing, brand marks seated as alpha masks, the DitheredMark Bayer shimmer, and the build and scan animations. The Locadex isometric is the reference standard: it was the one element of the first v0 build that Kevin approved (2026-08-04).
references/isometric.md holds the family in full, with its section numbers kept (1 the projection, 2 light and tone, 3 the extrusion recipe, 4 proportions, depth and the accent, 5 seating marks, 6 the shimmer, 7 animating iso, 8 the reference drawings to copy) and its own review checklist; references/isometric-recipes.md holds the copyable code. Read both before drawing, animating or reviewing any isometric figure, follow the order of work at the top of references/isometric.md (mount an existing drawing first; plates in world units with one accent; the extrusion recipe in the opaque material in both themes; artifacts and marks laid in their faces with plane(); motion last, paused until on screen, with a designed still), and run its checklist as well as the one below.
non-scaling-stroke where the SVG scales, square caps, no rounded joins.currentColor; no raw hex in a page component, including SVG attributes the lint does not read.pathLength under non-scaling-stroke.figure-check.mjs passes and its 2x junction crops were read in light and dark.Related skills: create-graphics (choosing a route for a figure outside these surfaces), design-engineering-polish (the final visual pass), hyperframes-animation and hyperframes-keyframes (diagrams that move in a film), animated-component-libraries (before hand-building a chart or interaction). In this set: gt-verify (captures and live checks), gt-dither (Bayer grounds behind a figure), gt-deck (slide layout), gt-graphics (blog graphics), gt-motion (lines in motion and the full dash traps) and gt-films (diagrams in a film), gt-lints (the line law and its auditor), gt-voice (label and caption copy). The wiki's diagram-to-html is not used for GT work: its Nacelle type, 700 weights and uppercase labels conflict with the brand's type rules (Inter at 400 and 500, sentence case).
Dated provenance for every rule is in references/sources.md, the isometric family's included: DESIGN.md and BRAND.md, the components and the kit, the deck slides, the gt-cloud ports, and Kevin's dated directives.
The folder skills/gt-diagrams as agents fetch it. Each file opens raw.
SKILL.mdreferences/checking.mdreferences/color.mdreferences/components.mdreferences/dashes.mdreferences/doubled-line.mdreferences/isometric-recipes.mdreferences/isometric.mdreferences/sources.mdscripts/deck-page.mjsscripts/figure-check.mjs