Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
233fec1
docs(site): plan the site surface and commit milestone 12 flow regions
thejustinwalsh Aug 25, 2026
50ef8aa
feat(site): render the wordmark through the library on the landing page
thejustinwalsh Aug 25, 2026
b3e1c76
feat(site): light the mark with a three-point rig and expose every dial
thejustinwalsh Aug 25, 2026
a71508d
feat(site): make the panel drive the render and anchor the controls t…
thejustinwalsh Aug 25, 2026
f5b4c3d
feat(site): add tooltips, anchor the controls, and repair panel reset
thejustinwalsh Aug 25, 2026
f472156
feat(site): set the mark over a multilingual chorus
thejustinwalsh Aug 25, 2026
ffef103
perf(site): take the landing page from 6fps to 60fps
thejustinwalsh Aug 25, 2026
2e0ca56
feat(site): render the chorus through Slug and separate entries with …
thejustinwalsh Aug 25, 2026
188e068
fix(site): tighten the chorus leading by dropping the two tallest faces
thejustinwalsh Aug 25, 2026
a9d87f3
feat(site): drift the camera on noise for parallax
thejustinwalsh Aug 25, 2026
56c27b3
feat(site): justify the chorus, filter the camera, slow the shake
thejustinwalsh Aug 25, 2026
c007fea
style(site): widen the column gutter to 110px
thejustinwalsh Aug 25, 2026
0e0a6bf
style(site): ease the column gutter back to 88px
thejustinwalsh Aug 25, 2026
e03758a
style(site): brighten the chorus to 0.20
thejustinwalsh Aug 25, 2026
7bbaab5
style(site): deepen and spread the control shadow
thejustinwalsh Aug 25, 2026
2a5cc6a
feat(site): toggle the dev overlays with space, and settle the chorus…
thejustinwalsh Aug 25, 2026
4ddd8a6
style(site): commit the dialled look
thejustinwalsh Aug 25, 2026
110aa1e
feat(site): shrink the chorus atlases and add the core API page shell
thejustinwalsh Aug 25, 2026
6847d5a
fix(site): merge the workspace release-age exclusions
thejustinwalsh Aug 25, 2026
7b8c6bf
fix(site): follow the engine surface forward
thejustinwalsh Aug 26, 2026
d2e60f0
feat(site): place the mark from its ink box
thejustinwalsh Aug 26, 2026
c6327c4
docs(packages): re-pin the concept digests
thejustinwalsh Aug 26, 2026
a099dab
fix(site): keep the formatter out of the MDX
thejustinwalsh Aug 26, 2026
cbeb5a9
fix(site): keep the dev watcher off the build output
thejustinwalsh Aug 26, 2026
1930951
fix(site): decorrelate the camera noise and let it rest
thejustinwalsh Aug 26, 2026
62db327
fix(site): drop the cross-origin isolation headers
thejustinwalsh Aug 26, 2026
78b6774
revert(site): keep the repository on the alpha.3 r3f pin
thejustinwalsh Aug 26, 2026
8c93844
fix(site): keep leva, the frame counter and the space toggle out of p…
thejustinwalsh Aug 26, 2026
822c9b9
fix(site): bind the dev server to every interface
thejustinwalsh Aug 26, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 23 additions & 7 deletions .claude/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,31 @@
"version": "0.0.1",
"configurations": [
{
"name": "dev",
"runtimeExecutable": "pnpm",
"runtimeArgs": ["--filter", "@pmndrs/glyph-benchmarks", "run", "dev", "--port", "5273", "--strictPort"],
"port": 5273
"name": "glyph-site",
"runtimeExecutable": "mise",
"runtimeArgs": [
"exec",
"--",
"pnpm",
"--filter",
"@pmndrs/glyph-site",
"dev",
"--port",
"5275",
"--strictPort"
],
"port": 5275
},
{
"name": "r3f",
"runtimeExecutable": "pnpm",
"runtimeArgs": ["--filter", "@pmndrs/glyph-r3f-hello-world", "run", "dev", "--port", "5274", "--strictPort"],
"name": "glyph-docs",
"runtimeExecutable": "npx",
"runtimeArgs": [
"-y",
"serve",
"site/dist/docs",
"-l",
"5274"
],
"port": 5274
}
]
Expand Down
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
1 change: 1 addition & 0 deletions apps/benchmarks/fixtures/fonts/noto-sans-v2026/OFL.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
404: Not Found
Binary file not shown.
93 changes: 93 additions & 0 deletions apps/benchmarks/fixtures/fonts/playwrite-us-trad-1.003/OFL.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
Copyright 2023 The Playwrite Project Authors (https://github.com/TypeTogether/Playwrite)

This Font Software is licensed under the SIL Open Font License, Version 1.1.
This license is copied below, and is also available with a FAQ at:
https://openfontlicense.org


-----------------------------------------------------------
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
-----------------------------------------------------------

PREAMBLE
The goals of the Open Font License (OFL) are to stimulate worldwide
development of collaborative font projects, to support the font creation
efforts of academic and linguistic communities, and to provide a free and
open framework in which fonts may be shared and improved in partnership
with others.

The OFL allows the licensed fonts to be used, studied, modified and
redistributed freely as long as they are not sold by themselves. The
fonts, including any derivative works, can be bundled, embedded,
redistributed and/or sold with any software provided that any reserved
names are not used by derivative works. The fonts and derivatives,
however, cannot be released under any other type of license. The
requirement for fonts to remain under this license does not apply
to any document created using the fonts or their derivatives.

DEFINITIONS
"Font Software" refers to the set of files released by the Copyright
Holder(s) under this license and clearly marked as such. This may
include source files, build scripts and documentation.

"Reserved Font Name" refers to any names specified as such after the
copyright statement(s).

"Original Version" refers to the collection of Font Software components as
distributed by the Copyright Holder(s).

"Modified Version" refers to any derivative made by adding to, deleting,
or substituting -- in part or in whole -- any of the components of the
Original Version, by changing formats or by porting the Font Software to a
new environment.

"Author" refers to any designer, engineer, programmer, technical
writer or other person who contributed to the Font Software.

PERMISSION & CONDITIONS
Permission is hereby granted, free of charge, to any person obtaining
a copy of the Font Software, to use, study, copy, merge, embed, modify,
redistribute, and sell modified and unmodified copies of the Font
Software, subject to the following conditions:

1) Neither the Font Software nor any of its individual components,
in Original or Modified Versions, may be sold by itself.

2) Original or Modified Versions of the Font Software may be bundled,
redistributed and/or sold with any software, provided that each copy
contains the above copyright notice and this license. These can be
included either as stand-alone text files, human-readable headers or
in the appropriate machine-readable metadata fields within text or
binary files as long as those fields can be easily viewed by the user.

3) No Modified Version of the Font Software may use the Reserved Font
Name(s) unless explicit written permission is granted by the corresponding
Copyright Holder. This restriction only applies to the primary font name as
presented to the users.

4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
Software shall not be used to promote, endorse or advertise any
Modified Version, except to acknowledge the contribution(s) of the
Copyright Holder(s) and the Author(s) or with their explicit written
permission.

5) The Font Software, modified or unmodified, in part or in whole,
must be distributed entirely under this license, and must not be
distributed under any other license. The requirement for fonts to
remain under this license does not apply to any document created
using the Font Software.

TERMINATION
This license becomes null and void if any of the above conditions are
not met.

DISCLAIMER
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
OTHER DEALINGS IN THE FONT SOFTWARE.
Binary file not shown.
Binary file not shown.
129 changes: 129 additions & 0 deletions apps/benchmarks/scripts/sync-noto-sans-fixture.mts
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
import { resolve } from 'node:path';

import { syncImmutableFixture } from './support/immutable-fixture.mts';

// google/fonts ships Noto as variable, which the baker rejects outright with
// UnsupportedVariableFont. The Noto project's own site repository carries hinted
// static builds of every script, so the fixture takes them from there and no
// font instancer — and no Python — enters the repository.
const commit = '3a06b1c521155492df224d33464b3c7b2852d861';
const directory = resolve('fixtures/fonts/noto-sans-v2026');
const check = process.argv.includes('--check');
const files = [
{
localName: 'NotoSans-Regular.ttf',
remotePath: 'fonts/NotoSans/hinted/ttf/NotoSans-Regular.ttf',
sha256: '478c558ea716033cd60c03438f628dfa75694dcf6b5f6d505a2f05fd2b4f3823',
},
{
localName: 'NotoSansArabic-Regular.ttf',
remotePath: 'fonts/NotoSansArabic/hinted/ttf/NotoSansArabic-Regular.ttf',
sha256: 'bdff3e5659d67e67def05b33f749683b9376ae819d65d3dd62ac4640b3aaef48',
},
{
localName: 'NotoSansDevanagari-Regular.ttf',
remotePath: 'fonts/NotoSansDevanagari/hinted/ttf/NotoSansDevanagari-Regular.ttf',
sha256: '306b53ecfb182a504dd8a7446093c316387d2fd8dc350d0792ed1753fe0996cd',
},
{
localName: 'NotoSansHebrew-Regular.ttf',
remotePath: 'fonts/NotoSansHebrew/hinted/ttf/NotoSansHebrew-Regular.ttf',
sha256: 'cdefaf8efd47045f6820928eba84db5bed7557539328952b5f828315485e02ee',
},
{
localName: 'NotoSansThai-Regular.ttf',
remotePath: 'fonts/NotoSansThai/hinted/ttf/NotoSansThai-Regular.ttf',
sha256: '61cf814eec46b294d6ea4401ac295d0cecd5207bd2331dcc5a15e7301d30ee44',
},
{
localName: 'NotoSansGeorgian-Regular.ttf',
remotePath: 'fonts/NotoSansGeorgian/hinted/ttf/NotoSansGeorgian-Regular.ttf',
sha256: 'd3e33254b09e7bb2c5cf0f17e554b80462056c5a107097f258d495168c3a9346',
},
{
localName: 'NotoSansArmenian-Regular.ttf',
remotePath: 'fonts/NotoSansArmenian/hinted/ttf/NotoSansArmenian-Regular.ttf',
sha256: '720df88c332417a235b4d6209d14ec2e2bf4bfe2a954b7453d869ea593bfce1e',
},
{
localName: 'NotoSansBengali-Regular.ttf',
remotePath: 'fonts/NotoSansBengali/hinted/ttf/NotoSansBengali-Regular.ttf',
sha256: 'b55c62ee531e3214da6c0701daecea89a52ba42db7d8206b92e6b51f397a3193',
},
{
localName: 'NotoSansTamil-Regular.ttf',
remotePath: 'fonts/NotoSansTamil/hinted/ttf/NotoSansTamil-Regular.ttf',
sha256: '3c0a186feb3c63c7f6d63e1511dcdc144e745ae09b98e217c83f3e317974f6f9',
},
{
localName: 'NotoSansTelugu-Regular.ttf',
remotePath: 'fonts/NotoSansTelugu/hinted/ttf/NotoSansTelugu-Regular.ttf',
sha256: 'b274780b69d1d23fe84b55e809a152cb2ac5306d33864b1f87622f6971871aae',
},
{
localName: 'NotoSansKhmer-Regular.ttf',
remotePath: 'fonts/NotoSansKhmer/hinted/ttf/NotoSansKhmer-Regular.ttf',
sha256: 'e66675f2082788f0511a714bef5a1748928294b38c8e286a96ea73a864b5e605',
},
{
localName: 'NotoSansLao-Regular.ttf',
remotePath: 'fonts/NotoSansLao/hinted/ttf/NotoSansLao-Regular.ttf',
sha256: '0a86e5e1ccfe34ca78c43fac6829dc751b42bcc469272a9a55325aae587bfbe7',
},
{
localName: 'NotoSansMyanmar-Regular.ttf',
remotePath: 'fonts/NotoSansMyanmar/hinted/ttf/NotoSansMyanmar-Regular.ttf',
sha256: 'fafce4db400bc0b214907ccdbfb0ad2f18a57bfefd08c8a571830b84088cf2fc',
},
{
localName: 'NotoSansSinhala-Regular.ttf',
remotePath: 'fonts/NotoSansSinhala/hinted/ttf/NotoSansSinhala-Regular.ttf',
sha256: '9e32612d47004552f3125e78648a9e2e7899a216ccd3cefbb93a9b5f4c809feb',
},
{
localName: 'NotoSansEthiopic-Regular.ttf',
remotePath: 'fonts/NotoSansEthiopic/hinted/ttf/NotoSansEthiopic-Regular.ttf',
sha256: 'f6f7fc379db9438959a2b0527e7a2cf36ea9c84626d56ec444fff37fc24c3c10',
},
{
localName: 'NotoSansGujarati-Regular.ttf',
remotePath: 'fonts/NotoSansGujarati/hinted/ttf/NotoSansGujarati-Regular.ttf',
sha256: '9b5a7aaeeb649a2e75a49d8b006a1f87db1b61c0df3b001609f4e0725d88dbf6',
},
{
localName: 'NotoSansKannada-Regular.ttf',
remotePath: 'fonts/NotoSansKannada/hinted/ttf/NotoSansKannada-Regular.ttf',
sha256: '9ad74dc64838c6855b96f671fc08e425a58921b9d0c71712ea79c328a27e6e38',
},
{
localName: 'NotoSansMalayalam-Regular.ttf',
remotePath: 'fonts/NotoSansMalayalam/hinted/ttf/NotoSansMalayalam-Regular.ttf',
sha256: 'c08de7fa8d032a5d6a4d120fb82c78cec60b362a4e73fa26360d89759ff2a7f9',
},
{
localName: 'NotoSansGurmukhi-Regular.ttf',
remotePath: 'fonts/NotoSansGurmukhi/hinted/ttf/NotoSansGurmukhi-Regular.ttf',
sha256: '658d0207da305a1411c539a8b0bbeda64d4146e54fb4827facddb890b6b90d74',
},
{
localName: 'NotoSansOriya-Regular.ttf',
remotePath: 'fonts/NotoSansOriya/hinted/ttf/NotoSansOriya-Regular.ttf',
sha256: 'a16645d056017927406546aa78e4ce15e782fd8783467267b75450453d007415',
},
] as const;

await syncImmutableFixture({
baseUrl: `https://raw.githubusercontent.com/notofonts/notofonts.github.io/${commit}`,
check,
directory,
files,
});

/* @workflow
{
"name": "font:noto-sans:sync",
"summary": "Synchronize the authenticated Noto Sans static fixtures for every scripted language.",
"requirements": "Network access to the pinned source.",
"writes": "Checked-in static fonts."
}
*/
44 changes: 44 additions & 0 deletions apps/benchmarks/scripts/sync-playwrite-fixture.mts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { resolve } from 'node:path';

import { syncImmutableFixture } from './support/immutable-fixture.mts';

// google/fonts ships only the variable build, which the baker rejects with
// UnsupportedVariableFont. The designers' own release carries static instances
// at the same commit google/fonts pins, so the fixture takes them from upstream
// and no font instancer enters the repository.
const commit = '02e4e15767f5b6c2109413429fc51879b9507ab4';
const directory = resolve('fixtures/fonts/playwrite-us-trad-1.003');
const check = process.argv.includes('--check');
const files = [
{
localName: 'PlaywriteUSTrad-Regular.ttf',
remotePath: 'fonts/ttf/PlaywriteUSTrad-Regular.ttf',
sha256: 'ac59d71c6487bee243777be1db788d8051d371e4d6ddf7798576e594908bfcf6',
},
{
localName: 'PlaywriteUSTradGuides-Regular.ttf',
remotePath: 'fonts/ttf/PlaywriteUSTradGuides-Regular.ttf',
sha256: '1eac92a6a9349a33f9f6829ffc2c3c758ec91536e711427988a74099db395c82',
},
{
localName: 'OFL.txt',
remotePath: 'OFL.txt',
sha256: '0370f5946020846b0ca65e44950d11411ea3bd3c4c0d755916470f9f96cd8cb8',
},
] as const;

await syncImmutableFixture({
baseUrl: `https://raw.githubusercontent.com/TypeTogether/Playwrite/${commit}`,
check,
directory,
files,
});

/* @workflow
{
"name": "font:playwrite:sync",
"summary": "Synchronize the authenticated Playwrite US Trad fixture.",
"requirements": "Network access to the pinned source.",
"writes": "Checked-in static fonts and license."
}
*/
1 change: 1 addition & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ okf_version: '0.2'
- [Project README](../README.md) — product overview, API preview, implementation order, and local setup.
- [Project brief](planning/project-brief.md) — product outcome, scope, non-goals, and success criteria.
- [Canonical roadmap](roadmap/roadmap.md) — implementation sequence, issue-sized milestones, dependencies, and exit gates.
- [Documentation site and landing page](planning/docs-site.md) — the `site/` workspace surface, its two composed static outputs, and the publication decision it defers.
- [Merged v0 runtime and bake API](planning/api-shapes.md) — superseded migration fixture; it describes the merged v0 surface that the Rust render-plan cutover deleted.
- [Three.js text API](planning/three-api.md) — authoritative Three-native loader, explicit `TextGroup` batching, reusable text across group disposal, retained non-throwing errors, ordering, and lifecycle contract.
- [Core text API](planning/core-api.md) — authoritative API for ordered font stacks, batch-owned paragraph handles, identity-preserving capacity changes, fixed-capacity failure, synchronized updates, and renderer-ready glyph batches.
Expand Down
20 changes: 20 additions & 0 deletions docs/log.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,26 @@
its hand-written identity builder, its parallel-array assertion over six public arrays, and its
double-snapshot staleness re-check: 271 lines to 204, with the three things it was compensating for now
guaranteed by construction.
- **The published site becomes a third top-level surface, and the wordmark becomes a proof** — `site/` joins
`packages/` and `apps/` because a deployable web surface is neither a library nor an example, and root
`docs/` is already the knowledge bundle, so the pmndrs convention of MDX-at-`docs/` moves one level down to
`site/docs`. One private package composes two static outputs into `site/dist` exactly as GitHub Pages serves
them; uikit's `static.yml` is the precedent for merging a reusable-workflow artifact with sibling outputs
under one `deploy-pages`. Nothing publishes yet, so no workflow file ships and there is nothing to disable.
Three capability questions were answered from source rather than assumed. Contour hole-punching does not
exist and is not close: the v1 boundary states plainly that body text cannot flow around a contour, so the
landing composition ships three justified columns with no exclusions at all, and Milestone 12's core —
authored two-dimensional exclusions, not glyph-ink contours — is committed immediately after (D-259).
Multi-column justified flow and `defineTextMaterial` both already exist and carry the design. And
`@react-three/postprocessing` cannot: it wraps the WebGL `EffectComposer`, so the WebGPU path is
`useRenderPipeline` with TSL display nodes, which is what paris-site does and why it carries no such
dependency. Two earlier readings were wrong and are corrected here: the reusable docs workflow composes fine
rather than owning the artifact, and drei ships a matching `11.0.0-alpha.5` under its `alpha` tag — the
incompatible peer range came from reading `latest`. Playwrite is variable-only in `google/fonts`, which the
baker rejects outright, but the upstream project ships statics at the same pinned commit, so no font
instancer and no Python toolchain enter the repository. The hero sets `glÿph` decomposed as `y` + `U+0308`:
the diaeresis is decorative and phonetically inert, and encoding it decomposed makes the wordmark its own
GPOS mark-attachment proof.

## 2026-08-18

Expand Down
2 changes: 1 addition & 1 deletion docs/packages/benchmarks.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ description: Provides the shared interactive and automated benchmark product sur
resource: ../../apps/benchmarks
workspace_package: '@pmndrs/glyph-benchmarks'
documentation_type: reference
source_digest: 'sha256:b9c76d97e56f3245ce979687973d1472ea581b50fd9e3f22a3f8b419c9e1869b'
source_digest: 'sha256:6f339759add78dbf8c316c058b9f5cedfc2b88f87c869cbbfaf938b7bfb9b76d'
tags: [package, benchmarks, react, vite, product-e2e]
sources:
- id: manifest
Expand Down
2 changes: 1 addition & 1 deletion docs/packages/glyph.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ description: Implements portable font loading, retained Rust shaping and layout,
resource: ../../packages/glyph
workspace_package: '@pmndrs/glyph'
documentation_type: reference
source_digest: 'sha256:ef2e753861cc155d1b53842529718e4dad5066e9aa88c55b2fb95c6a679605de'
source_digest: 'sha256:8db072a8c3d465cb7f98e4ae0b40e192b2641ec2fac4d69c120f6354c01bc629'
tags: [package, public-api, rust, wasm, threejs, typography]
sources:
- id: manifest
Expand Down
1 change: 1 addition & 0 deletions docs/planning/decision-register.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ Implementation and passing fixtures are evidence, not approval. A proposed row c
| D-086 | Raster-baker descriptors must satisfy `JsonValue` in the public TypeScript contract and are still validated as untrusted plugin output; each descriptor/key pair is resolved once and reused for ordering, packaging, and baking. | Accepted |
| D-087 | `@pmndrs/glyph` solely owns the optimized font-baker Wasm, Rust source, tooling, and canonical URL. `@pmndrs/glyph/bake` is its Node programmatic surface and `@pmndrs/glyph/runtime-bake` is its explicit browser host; the root graph cannot reach baker or validator code. No second font-baker package is published. | Accepted |
| D-016 | The root `rust-toolchain.toml` is the sole product Rust authority. The isolated coverage-fuzz workspace has one exact dated nightly authority because libFuzzer needs unstable compiler instrumentation. Root and nested mise configurations consume their contextual idiomatic files instead of duplicating Rust versions; pnpm and Cargo remain the normal command interface. | Settled for V0 |
| D-259 | The published web surface lives in `site/`, a third top-level category beside `packages/` (libraries) and `apps/` (examples and maintainer tools), because a deployable site is neither. One private package composes two static outputs into `site/dist` exactly as GitHub Pages serves them: a `@pmndrs/docs` MDX export under `/docs` and a WebGPU landing page at `/`. Root `docs/` remains the Open Knowledge Format bundle, so the generator reads `site/docs` rather than the upstream `docs` convention. The landing hero renders the wordmark `glÿph` through the library itself — Slug curves at display scale, a `defineTextMaterial` node material carrying rim, glints, and an emissive floor into TSL bloom, and a three-column justified multi-script field resolved through one ordered font stack — so every visual claim on the page is the library's own output rather than an illustration of it. The diaeresis is decorative and encoded decomposed, which makes the wordmark its own GPOS mark-attachment proof. Nothing publishes until a separate publish decision fixes the base path and the Pages workflow together. The composition uses no exclusions: text that reflows around the wordmark is committed as Milestone 12 core — authored two-dimensional exclusions, not glyph-ink contours — sequenced after the composition lands. | Accepted |

D-004/005 follow the established uikit split: the core owns every feature and React only reconciles lifecycle and props. Nested text follows React Native's attributed-text model; direct props and Suspense match uikit/Drei conventions. D-006 makes the short string form canonical while preserving explicit source/baked overrides and preload identity. D-007 fixes native ESM, explicit subpath exports, module workers, and `import()`-based lazy boundaries as package invariants. D-008/009 adopt Koota's value-oriented inference at raster/plugin boundaries without applying type-level models to runtime binary data. See the [API contract](api-shapes.md).

Expand Down
Loading
Loading