{
  "schemaVersion": 1,
  "package": "typeset.us",
  "version": "4.3.2",
  "status": "public-release",
  "mountOwnership": { "scope": "same target, same engine instance", "policy": "first claim owns; waiting controllers take over after release", "diagnostic": "controller.stats.overlappingTargets", "integration": "use disjoint text roots and one engine copy" },
  "inlineNoWrap": { "supported": "ordinary white-space:nowrap inline phrases within wrapping rich text", "preserves": ["protected break boundaries", "styled descendants", "source and author elements"], "overflow": "native:no-candidate with unbreakable-run constraint" },
  "nameGrouping": { "language": "declared English", "scope": "capitalized names followed by street or institution designators", "policy": "bounded soft preference; substantial final location words allowed in titles", "limit": "not a semantic parser or arbitrary brand recognition" },
  "keep": { "option": "keep: string[] (DOM, mount and both React adapters)", "matching": "case-insensitive; NBSP and runs of spaces count as one space; punctuation around the phrase ignored", "body": "never split where the phrase fits the measure; a phrase the browser splits may earn one extra line, except with density: compact; a phrase longer than the measure is split as few times as possible", "titles": "kept within the minimum line count", "retention": "a native layout is retained only if it splits no kept phrase" },
  "defaults": { "lineBreaks": "unicode", "density": "compact with one-line default body allowance for stranded sentence/clause openers; explicit compact/maxLines respected", "spacing": true, "tracking": true, "contour": "finished", "smartQuotes": false, "opticalHanging": false, "listStyling": "explicit" },
  "contentSecurityPolicy": { "styleSrc": "no 'unsafe-inline' needed: engine styles are written and restored through the CSSOM, never the style attribute", "scriptSrc": "no 'unsafe-eval' and no inline script; allow the origin that serves the bundle", "trustedTypes": "compatible with require-trusted-types-for 'script' and trusted-types 'none'; no HTML sinks", "injectedStyleElements": false, "evidence": "scripts/v4/verify-strict-csp.mjs" },
  "contour": { "basis": "predicted finished widths using the rendering space policy", "beamCompletedPool": 200, "shortParagraphs": "budgeted exhaustive search", "evidence": "result.search", "comparison": "contour: natural" },
  "spacing": { "scope": "composed, left-aligned body text", "level": "full V3 neighbor/median finish", "deltaBounds": "-20 percent to +33 percent of each measured natural space; authored spacing retained", "preserves": ["chosen breaks", "final line", "author elements", "source text"], "fallback": "retain unspaced composition and report native:spacing-verification" },
  "languages": ["en", "fr", "de", "es"],
  "tracking": { "scope": "default Unicode composed left-aligned body text, after verified word spacing", "maxDeltaEm": 0.01, "maxRuns": 256, "preserves": ["chosen breaks", "final line", "author elements", "source text", "authored spacing"], "excluded": ["code/kbd/samp", "joining scripts", "unresolved relative spacing", "legacy plain renderer"], "fallback": "roll back tracking only; report native:tracking-verification", "disable": "tracking: false, or data-typeset-tracking=false; spacing: false disables both finishes" },
  "scheduling": { "discovery": "changed subtrees; no whole-document rescan for unrelated mutations", "priority": "initially near-viewport targets", "batchTargetMs": 8, "hardDeadline": false, "recomposes": ["text", "font", "width", "context"], "limit": "one composition, initial discovery and browser layout may exceed the batch target" },
  "untaggedLanguage": "neutral Latin-script preferences; no language inference",
  "react": { "peerRange": "^18.2.0 || ^19.0.0", "peers": ["react", "react-dom"], "testedVersion": ["18.2.0", "18.3.1", "19.0.8", "19.1.9", "19.2.8", "19.3.0"], "evidence": "scripts/v4/verify-react-matrix.mjs: install, server render, hydration and composition in Chromium, WebKit and Firefox; strict types against @types/react 18.3, 19.0 and latest", "entry": "typeset.us/react", "formats": ["ESM (dist/react.js)", "CommonJS (dist/react.cjs)"], "as": ["p", "h1", "h2", "h3", "h4", "h5", "h6", "span", "div", "li", "blockquote", "figcaption", "dd", "dt", "td", "th", "caption", "label", "legend", "summary"], "ref": "the host element", "onResult": "each composition's Result, after the commit", "priority": { "auto": "blocks React renders in the browser compose before first paint when on screen (on-screen work beyond about 120 ms in one frame, the one-time setup not counted, continues in the next frame), offscreen blocks in idle time; server-rendered HTML paints natively and composes after hydration", "sync": "compose in the React commit" }, "observers": "one registry per document shared by every adapter", "customComponentChildren": "native:react-component (any component child, such as next/link's Link; a development warning says so)" },
  "node": ">=18.3",
  "nodeScope": "typeset-audit CLI only; the library runs in browsers and the package declares no engines field",
  "browserRequirements": ["Intl.Segmenter", "ResizeObserver", "MutationObserver", "Range geometry", "a layout engine"],
  "browserOptional": ["FontFaceSet"],
  "environment": { "outcome": "native:environment", "when": "jsdom, happy-dom, or an engine without a required API", "behaviour": "every entry imports; text stays as authored; typeset() and both adapters report the outcome; mount() returns an inert controller; nothing throws" },
  "liveRegions": { "outcome": "native:live-region", "regions": ["aria-live other than off (empty counts as absent)", "role status, alert, log, marquee or timer", "output"], "exception": "aria-live=off", "scope": "text inside a live region, and an element that contains one, through open shadow roots (slotted text, a component with a live slot) as they are when the text is composed; a role set through ElementInternals or in a closed shadow root is not seen: use data-no-typeset", "policy": "never measured, composed or rewritten; mount() and the loaders release an owned element whose region turns live, or that moves into or gains a live region, in the same mutation callback when the change is in the light DOM; a shadow tree that becomes live later (a component defined after the text composed, a role set inside its shadow root) is seen at the next resize or font load, which releases the text inside the region once: use data-no-typeset, or hide undefined components with :not(:defined)" },
  "lifecycle": { "recomposes": ["text edits, including framework writes to split Text nodes", "fonts, including stylesheet-requested fonts in WebKit", "width", "text-spacing overrides and browser font-size settings", "CSSOM rule changes", "font, spacing and line-height transitions and animations"], "ancestorRestyles": "recheck a computed layout key; compose only if it changed", "hidden": "compositions are kept while hidden and paint composed when shown", "resize": "native wrapping (data-ts-stale) while a block's composed lines no longer fit; recompose 100 ms after the size holds, or, with mount() and the loaders, once a block more than a viewport height offscreen comes that near (released to native meanwhile)", "print": "native wrapping at the paper width; composition pauses", "translation": "native:translated; breaks removed by moving Text nodes; TypesetRichText freezes", "iframes": "mount() works on same-origin iframe documents and elements", "scheduling": "near-viewport work in the next task, offscreen work in idle time or when near" },
  "cssHooks": { "--ts-break-display": "display of every generated break; none in print, inline on screen", "data-ts-stale": "set on a block showing native wrapping until it is recomposed", "stylesheet": "dist/styles.css; the engine also installs the rules as a constructable stylesheet" },
  "errors": { "typeset": "TypeError for a target that is not an element", "mount": "TypeError for a root that is not a Document, Element or selector string", "options": "development builds warn once per invalid value, unknown option or non-string selector; values keep their 4.2 behaviour; production bundles omit the checks" },
  "unsupported": ["automatic hyphenation", "soft hyphens", "mixed languages in one block", "RTL and vertical text", "justified text, and a text-align-last that differs from text-align (native:justify)", "editable text", "inline widgets", "unsupported inline box decoration", "scale, rotation, perspective and nonzero Z transforms"],
  "inlineCode": { "supported": "normal whitespace, overflow-wrap:break-word and nonnegative sliced padding/borders/margins measured in context", "tracking": false },
  "quotes": { "mode": "explicit English", "lengthPreserving": true, "dashesAndEllipses": "not changed", "richReactRequires": "lang=en on the adapter" },
  "opticalHanging": { "mode": "explicit", "scope": "full measured leading punctuation and raster-measured optical capitals on composed lines or fitting single lines", "capitalMaxEm": 0.08, "clipping": "full glyph must fit available clip/padding/scrollport; partial line coverage reported", "unsupported": ["centered or justified text", "insufficient clip room", "unknown clip paths/masks", "scale/rotation/perspective transforms", "author text indentation", "custom font-feature/variation settings unsupported by canvas, including onum"] },
  "lists": { "entry": "styleProseLists", "stylesheet": "typeset.us/styles.css", "scope": "explicit unordered prose lists", "marker": "native ::marker", "excluded": ["navigation", "ordered lists", "custom markerless lists", "flex and grid lists"] },
  "outcomes": { "reference": "OUTCOMES.md", "runtime": "OUTCOMES", "types": ["Outcome", "FeatureStatus"], "groups": ["composed", "nothing to improve", "unsupported content", "couldn't improve safely", "not processed"], "nativeMeans": "left as the browser set it, with the reason; not an error" },
  "verification": { "cli": "typeset-audit", "api": "auditJSON", "schemaVersion": 1, "passMeans": "nonempty scope, no hard errors, no unprocessed targets", "doesNotMean": "aesthetic perfection, all targets composed, or source preservation without a before capture" },
  "telemetry": "none",
  "websiteLoader": { "selector": "automatic prose and headings; data-typeset-selector overrides", "smartQuotes": "en", "opticalHanging": true, "npmGoSelector": "[data-typeset]", "npmAutoEntry": "typeset.us/auto (dist/auto.js), byte-identical to https://typeset.us/go@<version>.js", "noTargets": "each loader logs one console.info when no element matches", "pinnedPaths": ["go@<version>.js", "typeset@<version>.min.js", "typeset@<version>.esm.js"], "movingAliases": { "go@4.js": "latest 4.x", "go.js": "latest 4.x only; never moves to 5.0" }, "cdnDefault": "bare jsDelivr and unpkg package URLs serve dist/typeset.global.js" },
  "outstandingAcceptance": ["physical iOS and Android", "spoken VoiceOver and NVDA", "non-macOS and native-application rich clipboard", "representative-device performance"],
  "releaseApproval": "owner-approved with documented testing limits"
}
