Skip to main content

localize

Use when creating or fixing translated / localized variants of an existing CoDesign / CE.SDK design (e.g. de/ja/ru/ar editions); when a localized edition's text blocks or decorative elements have drifted, re-centered, or resized away from the source layout; when translated copy is tofu, overflowing, mis-tracked, or the wrong font after a language swap; or when loading a non-Latin script (Cyrillic / CJK / Arabic RTL / Vietnamese) font into a scene. Also for animated / video designs: longer holds, re-timed reveals, a new voice-over and captions per language.

Quellinformationen

Repository
imgly/codesign
Letzte Quellaktivität
29. September 2026 um 16:31
Erkannte Sprache von SKILL.md
Englisch
Sterne
42
Forks
0

Installationsoptionen

Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.

Quelldateien prüfen

Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.

Datei-Explorer
8 Dateien

SKILL.md wird angezeigt

SKILL.md
Quellanweisungen · Schreibgeschützte Vorschau
name
localize
description
Use when creating or fixing translated / localized variants of an existing CoDesign / CE.SDK design (e.g. de/ja/ru/ar editions); when a localized edition's text blocks or decorative elements have drifted, re-centered, or resized away from the source layout; when translated copy is tofu, overflowing, mis-tracked, or the wrong font after a language swap; or when loading a non-Latin script (Cyrillic / CJK / Arabic RTL / Vietnamese) font into a scene. Also for animated / video designs: longer holds, re-timed reveals, a new voice-over and captions per language.
# localize Point this skill at the current design and the target locales, and it produces or repairs the localized editions. It operates on the **latest revision of the current design** (re-ground via `list()` / `history()` if unsure — handbook §1); each locale lands as its own revision, forked from the source. Single home for localizing CoDesign designs: the **operational workflow**, the **font-loading mechanics**, and the **per-language quality rules**. It builds on two things it does _not_ restate: handbook §6.1 (general typographic thresholds — leading, tracking, all-caps, the content-area line-height conversion (`design.font`), smart punctuation, reshape-recolor) and handbook §6.7 (general Latin font mechanics — single-URI `text.font` declarations, static-vs-variable, blank-glyph diagnosis). This skill is the non-Latin / localization extension of both. **Scoring:** localizing is judged with the `judge` skill — every applicable axis ≥ 8, no averaging, N/A = 10. A single tofu glyph, an overflow after expansion, un-mirrored RTL, or a block that drifted off the source grid fails the edition (the `localization` axis). ## Reference files (load on demand) This `SKILL.md` holds the always-needed spine: inputs, core principle, workflow, block classification, and the snap-to-reference routine. Two situational bodies of rules live beside it and are pulled in only when the task needs them: - **`reference/font-loading.md`** — getting a non-Latin / non-handbook face to render (jsDelivr picks, the variable-bold trap, font-declaration gotchas, the silent-sans failure). Read it whenever the target locale needs a Cyrillic / CJK / Arabic / Vietnamese font, or copy came out tofu / wrong face. - **`reference/language-rules.md`** — the cross-language spine: preserve-vs-localize, translation quality, layout integrity after translation, and the localization pass checklist. - **`reference/<family>.md`** — per-script-family conventions, numeric leading bands, and quotation marks, one file per family: `latin-expansion.md` (de/fr/es…), `arabic.md`, `cjk.md` (ja/zh/ko), `vietnamese.md`, `cyrillic.md` (ru…). Read the file(s) for the **target locale(s)** you're building, e.g. `reference/arabic.md`. Several locales of one design, or re-applying a master fix to locales you already built: the **master → editions** workflow, `../resize/editions.md`. For an animated or video design, read **Video and animated designs** below as well. ## Inputs — what to localize, and into what Resolved before any work by the intake contract — derive, ask once, echo, invent nothing: `../handbook/intake.md`. **R** = required, no default; **A** = ask if underived; **D** = defaultable. | Parameter | Kind | Chips / values | Default | | -------------- | ------- | --------------------------------------------------------------------------- | ------------------------------------- | | target locales | **R** | `German` · `French` · `Spanish` · `Japanese` · `Chinese` · `Arabic` · Other | none | | source locale | A | detected from the design's copy · Other | detected, stated in the echo | | source design | derived | — | latest revision of the current design | **1. The source (reference)** — the latest revision of the current design in its source language (usually `en`). That revision's geometry is the grid every target locale snaps to. Never localize _from_ a non-reference locale — always fork each locale from the source revision. If the user means an earlier design, find it via `list()` / `history()` first. **2. The locales** — the target languages, e.g. `de ja ru ar`. If omitted, **ask** — _**Which languages do you need?**_ — with the chips above; there is no defaulting to a language the user didn't name. Then echo the resolved set ("1 design × 3 locales, source `en` (detected)") before building. **Never invent copy.** A translation is the user's own content: if a block's meaning is ambiguous, or a term is a name/product you cannot safely render in the target script, ask rather than guess — see the keep-byte-identical list in `reference/language-rules.md` §1. **Per locale, then:** run the Workflow below (fork the source revision, or reuse+snap an existing localized revision). Give each locale's revision a `note` naming the locale. Preview every locale before reporting done. ## Core principle — localize, then snap back to the reference Localizing is **surgical**: change the words + the font the new script forces, and **nothing else**. Then **snap every block back to the reference variant's geometry** so the localized edition is positionally identical to the source. - The **reference** is the source-locale variant (usually `en`) **of the same size**. Each size has its own reference grid. - **Never re-center or re-size a block per variant "to fit better."** That independent re-fitting is exactly what makes a localized set drift — the eyebrow creeps up, the quote grows, the rule and footer slide down, and the editions stop matching. If there is room for the translated text at the reference position/size, keep the reference position/size. - Deviate from the reference **only** when the translated text genuinely overflows (expansion languages) — then shrink _that block's_ font within its band; do not move its neighbours. - **Swap the script font per block, not per scene.** Apply the new face **only to blocks whose copy is actually in the target script.** A block that stays in the source script — a personal name, brand/wordmark, `@handle`, URL, email, number, date, or product/tech name (the "keep byte-identical" list in `reference/language-rules.md` §1) — **keeps its original typeface.** Re-fonting it to the script face is drift even though its text was correctly preserved: a Latin name rendered in the Arabic/CJK serif is the classic tell. So a localized edition differs from its reference in **only the translated blocks' text + face**; every untranslated block is byte-identical (position mirrored for RTL). ## When to use - Producing new locale editions (de/ja/ru/ar/…) of a finished design, across one or more sizes. - Fixing a localized set whose blocks drifted / re-centered / resized vs the source. - Post-translation breakage: tofu, overflow, wrong tracking, Latin-looking sans where a script font should be. - Loading a non-Latin or non-handbook typeface into a scene. **Not for:** the original design build (that's the handbook + §6); pure copy edits in the same language. To change the **size/format** — re-compose a design for a new aspect rather than translate it — use the **resize** skill (localize snaps geometry; resize re-derives it). ## Reuse an existing localized build vs build fresh - **The workspace already has the locale** (an earlier pass built it — check `history()`): **reuse its build** — the translated copy, script fonts, and RTL are already solved — but still **snap it to the reference geometry**. Earlier builds commonly drift; reuse the assets, fix the positions. - **No existing build:** fork the reference revision and swap text + font. Either way the last step is the same: every block lands on the reference grid. ## Workflow 1. **Capture the reference geometry.** Load the source-locale variant of that size and read, per block: `x, y, width, widthMode, heightMode, fontSize (Pixel), lineHeight, letterSpacing, alignment`, plus page `w/h`, the ghost's anchor (left / centered), and the rule position. 2. **Load the target** — the localized scene to fix, or fork the reference for a fresh build. 3. **Classify blocks by role** (see below). 4. **Apply the reference geometry** to each corresponding block; keep the localized **text** and the **script font** (for a non-Latin/non-handbook face see `reference/font-loading.md`). Set per-locale: `letterSpacing = 0` for CJK & Arabic; RTL ghost mirrored to the right; alignment as the reference (centered-symmetric stays centered — see `reference/arabic.md`). 5. **Reconcile ghost count.** Keep the reference's number of decorative glyphs. If the localized scene has extra ones (e.g. an Arabic closing-quote bookend the English lacks), **destroy the extras**; mirror the kept one for RTL. 6. **Overflow guard.** After setting the reference font size, measure the quote's frame height; if it collides with the element below, step the font size down (only that block) until it fits. Never move neighbours to make room. 7. **Re-apply rich text after a TRANSLATED string lands.** Font/size/line-height changes via `setProps` auto-reshape with every style range preserved — no manual step. A **translated string** is different: the write replays ranges at their OLD offsets, which are source-string indices. Capture each block with `getProps(id, ['text.ranges'])` first (each range carries its `text` substring), re-apply semantically after. ⚠ `getTextColors(id)[0]` is **not** a capture — it reads the first run only, so re-applying it flattens a two-color headline onto one color and the accent is gone with no error. Paragraph state (`getProps(id, ['text.paragraphs'])` — listStyle/listLevel per paragraph) survives a same-string reshape but not a **re-write**, so re-apply it whenever the string itself changed. **Ranges are index-based on the source string** — a translated string has different offsets, so never replay `from`/`to` verbatim; re-locate the styled substring in the target language (§ "Carrying rich text across a translation"). 8. **`loadResources` → `preview`.** One preview per locale — tofu / RTL / overflow / position match are only visible in the render. A video design needs several per locale, at different `time`s (below). Then apply the per-locale quality rules in `reference/language-rules.md` **and the family file(s) for the target locale(s)** (`reference/latin-expansion.md`, `arabic.md`, `cjk.md`, `vietnamese.md`, `cyrillic.md`), and dry-run the localization pass checklist against the render before reporting done. ## Block-role classification Classify by measurable properties, not hard-coded ids (ids are session-scoped). For a quote-card family the roles are: - **ghost** (oversized decorative quote) — largest font size **and** trimmed string length ≤ 2. A design may have **more than one** (opening + closing bookend); collect all. - **footer / handle** — text containing `@`. - **quote / headline** — the largest remaining text after removing ghosts + footer. - **eyebrow** vs **attribution** — the two small texts; eyebrow sits **above** the quote, attribution **below**. - **rule / divider** — the graphic (non-text) block. Roles are design-specific. The general rule: **map each localized block to its reference block by role, or by index across the shared fork lineage** (localized variants forked from the same base keep the same child order), then restore that reference block's geometry. ## The snap-to-reference routine A single CoDesign `edit` body. Fill the `EN` reference geometry (from step 1) and the locale flags, then it classifies, restores geometry, reconciles ghosts, applies per-locale tracking / RTL mirroring, guards overflow, and re-applies colors across the reshape. ⚠ This routine is a **worked example, not a template**: every number in `EN` below is from one example quote-card, and the classification heuristics (`fs >= 150`, `s.includes('@')`, …) are that card's — never reuse either literally. Fill `EN` only from your own reference capture (the read at the bottom), and rewrite the classification for the actual design's roles. ```js // --- config: reference geometry (read from the source-locale variant of THIS size) --- const PW = 1080, PH = 1350; // page dims const EN = { // lh = VISUAL leading target (from the target locale's script band, NOT the reference's // raw engine number) — setLeading() converts it through each block's target face. For a // localized display headline in a diacritic language, this is where the conditional +0.2 // lives (latin-expansion.md): bump ≤1.2 → ~1.35 only if the rendered gap needs it. ghost: { x: 70, y: 55, fs: 300, lh: 1 }, // Auto-sized; keep size+lh, reposition eyebrow: { x: 110, y: 395, w: 860, fs: 16, lh: 1, ls: 0.25 }, quote: { x: 110, y: 529, w: 860, fs: 62, lh: 0.85 }, // ls always 0 rule: { x: 504, y: 930, w: 72 }, // graphic attribution: { x: 110, y: 960, w: 860, fs: 16, lh: 1, ls: 0.25 }, footer: { x: 110, y: 1225, w: 860, fs: 15, lh: 1, ls: 0.12 } }; const RTL = false; // true for Arabic const trackOK = true; // false for CJK/Arabic → force letterSpacing 0 on eyebrow/attr/footer const ghostAnchor = 'left'; // 'left' (post/square) mirrors to the right for RTL; 'center' (story) stays centered const belowQuoteY = EN.rule.y; // element the quote must stay above const page = engine.scene.getPages()[0]; const all = []; (function walk(id) { all.push(id); for (const c of engine.block.getChildren(id)) walk(c); })(page); const blocks = all.filter((id) => id !== page); const texts = blocks.filter((id) => engine.block.getType(id).includes('text')); const graphic = blocks.find((id) => engine.block.getType(id).includes('graphic') ); await engine.design.loadResources([page]); const meta = (id) => ({ id, s: engine.block.getString(id, 'text/text'), fs: engine.block.getTextFontSizes(id, { unit: 'Pixel' })[0], y: engine.block.getPositionY(id) }); const tm = texts.map(meta); // classify const ghosts = tm.filter((t) => t.fs >= 150 && t.s.trim().length <= 2); let ghost = ghosts.find((t) => t.s.includes('“')) || ghosts.slice().sort((a, b) => a.y - b.y)[0]; for (const g of ghosts.filter((t) => t !== ghost)) await engine.design.destroy(g.id); // drop extra bookend glyphs const footer = tm.find((t) => t.s.includes('@')); const rest = tm.filter((t) => !ghosts.includes(t) && t !== footer); const quote = rest.reduce((a, b) => (b.fs > a.fs ? b : a)); const others = rest.filter((t) => t !== quote); const eyebrow = others.reduce((a, b) => (b.y < a.y ? b : a)); const attribution = others.find((t) => t !== eyebrow); // capture rich text — each range carries its run's `text` substring, which is // what semantic re-location needs (offsets are source-string indices). const runsOf = (id) => { try { return (await engine.design.getProps(id, ['text.ranges'])).text.ranges; } catch (e) { return []; } }; const runs = Object.fromEntries( [ghost, eyebrow, quote, attribution, footer].map((t) => [t.id, runsOf(t.id)]) ); // Re-apply captured styling as ONE ranges assignment. Run 0 is the base style // and covers the whole block; any further run is an accent whose SOURCE offsets // are meaningless once the string is translated, so it is re-located by its // target-language substring (SPANS below).
Auf GitHub ansehen
Diese SKILL.md ist sehr gross, daher zeigt SkillsMP hier nur den ersten Abschnitt. Auf GitHub ansehen