domflax 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/README.md +159 -0
  2. package/dist/{chunk-4HHISSMR.js → chunk-DNHOGPYV.js} +2675 -1503
  3. package/dist/chunk-DNHOGPYV.js.map +1 -0
  4. package/dist/{chunk-ZJ2S36GY.js → chunk-DOQEBGWB.js} +33 -20
  5. package/dist/chunk-DOQEBGWB.js.map +1 -0
  6. package/dist/{chunk-77SLHRN6.js → chunk-DWLB7FRR.js} +341 -176
  7. package/dist/chunk-DWLB7FRR.js.map +1 -0
  8. package/dist/cli.cjs +2209 -774
  9. package/dist/cli.cjs.map +1 -1
  10. package/dist/cli.js +234 -116
  11. package/dist/cli.js.map +1 -1
  12. package/dist/index.cjs +3021 -1699
  13. package/dist/index.cjs.map +1 -1
  14. package/dist/index.d.cts +477 -54
  15. package/dist/index.d.ts +477 -54
  16. package/dist/index.js +49 -3
  17. package/dist/pattern-CV607P87.d.ts +547 -0
  18. package/dist/pattern-F5xBtIE-.d.cts +547 -0
  19. package/dist/pattern-kit.cjs +60 -39
  20. package/dist/pattern-kit.cjs.map +1 -1
  21. package/dist/pattern-kit.d.cts +3 -18
  22. package/dist/pattern-kit.d.ts +3 -18
  23. package/dist/pattern-kit.js +3 -1
  24. package/dist/pattern-kit.js.map +1 -1
  25. package/dist/{types-BQ7l6dVe.d.ts → resolve-ops-DIwEelH-.d.cts} +26 -251
  26. package/dist/{types-BQ7l6dVe.d.cts → resolve-ops-DIwEelH-.d.ts} +26 -251
  27. package/dist/verify.d.cts +1 -1
  28. package/dist/verify.d.ts +1 -1
  29. package/dist/webpack-loader.cjs +2975 -1699
  30. package/dist/webpack-loader.cjs.map +1 -1
  31. package/dist/webpack-loader.d.cts +2 -2
  32. package/dist/webpack-loader.d.ts +2 -2
  33. package/dist/webpack-loader.js +3 -3
  34. package/package.json +3 -6
  35. package/dist/chunk-4HHISSMR.js.map +0 -1
  36. package/dist/chunk-77SLHRN6.js.map +0 -1
  37. package/dist/chunk-ZJ2S36GY.js.map +0 -1
  38. package/dist/pattern-CX6iBzTD.d.ts +0 -237
  39. package/dist/pattern-P4FIKAUB.d.cts +0 -237
package/dist/index.d.ts CHANGED
@@ -1,16 +1,14 @@
1
- import { n as IRDocument, J as ApplyResult, K as RewriteGroup, L as ApplyContext, O as RewriteOp, Q as FixpointConfig, T as StyleResolver, U as SelectorIndex, W as Pass, X as PassManager, x as RewriteFactory, Y as PhaseRunResult, Z as Pipeline, _ as SyntheticSink, c as StyleNormalizer, w as Captures, P as Pattern, v as SafetyLevel, $ as EncodedSourceMap } from './types-BQ7l6dVe.js';
2
- export { a0 as AppliedOp, A as AttrMap, a1 as AttrValue, a2 as Backend, a3 as BackendContext, k as Backref, B as BackrefTable, a4 as Brand, g as ClassList, a5 as ClassListForm, a6 as ClassSegment, a7 as ClassToken, a8 as CodegenResult, a9 as CommentSpec, e as ConditionKey, C as CssProperty, aa as CssValue, ab as DeclSignature, ac as DeepReadonly, H as Diagnostic, ad as DiagnosticCode, ae as DistributiveOmit, af as EditPlan, E as ElementLike, ag as ElementSpec, ah as EmitContext, ai as EmitResult, aj as ExprKind, ak as ExprRecord, p as ExprRef, r as ExprRegistry, al as ExprSpec, am as FileKind, an as FragmentSpec, ao as Frontend, ap as FrontendConfig, F as FrontendKind, aq as FrontendParseContext, ar as HaltReason, m as IRComment, o as IRElement, q as IRExpr, s as IRFragment, f as IRNamespace, l as IRNode, as as IRNodeBase, I as IRNodeId, at as IRNodeKind, u as IRText, t as IdAllocator, au as InheritedPropertyTable, h as InlineStyle, M as MatchContext, y as MatchResult, N as NodeLike, j as NodeMeta, av as NodeRefSpec, b as NodeSpec, aw as OpOrigin, ax as OpValidationIssue, ay as OpaqueReason, az as OpaqueToken, aA as ParentLayoutContext, aB as ParseResult, z as PassCategory, aC as PassPhase, aD as PassTraceEntry, G as PatternDoc, aE as PatternName, aF as PipelineConfig, aG as PipelineInput, aH as PipelineOutput, aI as PipelineStats, aJ as Position, D as PreconditionSketch, aK as ReindentSpec, aL as Reporter, aM as ResolveInput, aN as ResolveResult, aO as ResolverDiagnostic, aP as RewriteContext, R as RewriteOpDraft, aQ as SelectorUsage, aR as Severity, aS as SkippedOpGroup, aT as SourceFile, aU as SourceFileId, i as SourceSpan, aV as StructuralInverse, aW as StyleBlock, d as StyleCondition, a as StyleConflictPolicy, aX as StyleDecl, S as StyleMap, aY as StyleOrigin, aZ as StylePredicate, a_ as SyntheticClass, a$ as TextEdit, b0 as TextSpec, b1 as TreeShapeSketch, b2 as VisitContext, b3 as VisitSignal, V as Visitor } from './types-BQ7l6dVe.js';
3
- import { A as AuthoredPattern } from './pattern-CX6iBzTD.js';
4
- export { B as BASE_CONDITION, u as BASE_CONDITION_KEY, v as ElementInit, w as MutableBackrefTable, x as childIds, y as conditionKey, z as createBackrefTable, C as createComment, G as createDocument, H as createElement, I as createExpr, J as createExprRegistry, K as createFragment, L as createIdAllocator, N as createText, O as defaultMeta, Q as elementIds, S as emptyAttrMap, T as emptyClassList, U as emptyInlineStyle, i as emptyStyleMap, V as getElement, W as getNode, X as walk } from './pattern-CX6iBzTD.js';
1
+ import { e as IRDocument, d as RewriteOp, I as IRNodeId, h as StyleResolver, g as SelectorIndex, f as SafetyLevel, l as PassPhase, r as RewriteFactory, i as Diagnostic, c as StyleNormalizer, R as RewriteOpDraft, j as SyntheticSink } from './resolve-ops-DIwEelH-.js';
2
+ export { A as AttrMap, Q as AttrValue, y as Backref, B as BackrefTable, T as Brand, w as ClassList, U as ClassListForm, W as ClassSegment, X as ClassToken, Y as CommentSpec, u as ConditionKey, C as CssProperty, Z as CssValue, _ as DeclSignature, o as DeepReadonly, D as DiagnosticCode, $ as DistributiveOmit, E as ElementLike, a0 as ElementSpec, a1 as EmitContext, a2 as EmitResult, a3 as ExprKind, a4 as ExprRecord, H as ExprRef, K as ExprRegistry, a5 as ExprSpec, F as FileKind, a6 as FragmentSpec, G as FrontendKind, z as IRComment, p as IRElement, J as IRExpr, L as IRFragment, v as IRNamespace, q as IRNode, a7 as IRNodeBase, a8 as IRNodeKind, O as IRText, M as IdAllocator, a9 as InheritedPropertyTable, x as InlineStyle, N as NodeLike, n as NodeMeta, aa as NodeRefSpec, b as NodeSpec, ab as OpOrigin, ac as OpaqueReason, ad as OpaqueToken, m as PassCategory, ae as PassTraceEntry, P as PatternName, af as Position, s as Reporter, ag as ResolveInput, ah as ResolveResult, ai as ResolverDiagnostic, aj as SelectorUsage, ak as Severity, al as SourceFile, am as SourceFileId, k as SourceSpan, an as StyleBlock, t as StyleCondition, a as StyleConflictPolicy, ao as StyleDecl, S as StyleMap, ap as StyleOrigin, aq as SyntheticClass, ar as TextSpec, as as VisitContext, at as VisitSignal, V as Visitor } from './resolve-ops-DIwEelH-.js';
3
+ import { y as ApplyResult, z as RewriteGroup, B as ApplyContext, C as MatchContext, E as FixpointConfig, H as HaltReason, G as Pass, I as PassManager, J as Pattern, K as PhaseRunResult, L as Pipeline, A as AuthoredPattern, N as Captures, O as EncodedSourceMap } from './pattern-CV607P87.js';
4
+ export { Q as AppliedOp, S as BASE_CONDITION, U as BASE_CONDITION_KEY, V as Backend, W as BackendContext, X as CodegenResult, Y as EditPlan, Z as ElementInit, _ as FlattenGate, $ as Frontend, a0 as FrontendConfig, a1 as FrontendParseContext, a2 as MatchResult, a3 as MutableBackrefTable, a4 as OpValidationIssue, a5 as ParentLayoutContext, a6 as ParseResult, a7 as PatternDoc, a8 as PipelineConfig, a9 as PipelineInput, aa as PipelineOutput, ab as PipelineStats, ac as PreconditionSketch, ad as ReindentSpec, ae as RewriteContext, af as SkippedOpGroup, ag as StructuralInverse, ah as StylePredicate, ai as TextEdit, aj as TreeShapeSketch, ak as childIds, al as conditionKey, am as createBackrefTable, an as createComment, ao as createDocument, ap as createElement, aq as createExpr, ar as createExprRegistry, as as createFragment, at as createIdAllocator, au as createText, av as defaultMeta, aw as elementIds, ax as emptyAttrMap, ay as emptyClassList, az as emptyInlineStyle, l as emptyStyleMap, aA as getElement, aB as getNode, aC as walk } from './pattern-CV607P87.js';
5
5
 
6
6
  /**
7
- * @domflax/core — the pure applier (the one trusted mutator).
7
+ * @domflax/core — applier runtime helpers (shared by the per-op handlers in `./apply`).
8
8
  *
9
- * {@link applyOps} takes an {@link IRDocument} plus a flat list of {@link RewriteOp}s and returns
10
- * a NEW, mutated document (the input document is left untouched — "pure" in the input-immutability
11
- * sense). Every op is validated against the safety ceiling and node-local safety floor before it
12
- * runs; rejected ops are collected into {@link ApplyResult.skipped} with {@link Diagnostic}s rather
13
- * than throwing. Dependency-free: only the `./types` contract and `./builders` runtime helpers.
9
+ * Pure, dependency-free building blocks for the trusted mutator: input-preserving cloning, the
10
+ * mutable apply state, small tree helpers, detached-spec materialization, and style merging.
11
+ * Only depends on the `../types` contract and `../builders` runtime helpers.
14
12
  */
15
13
 
16
14
  interface ApplyOutcome {
@@ -20,6 +18,15 @@ interface ApplyOutcome {
20
18
  }
21
19
  /** Shallow-immutable clone: input doc and its node objects are never mutated. */
22
20
  declare function cloneDocument(doc: IRDocument): IRDocument;
21
+
22
+ /**
23
+ * @domflax/core — the per-op handlers + public apply entry points.
24
+ *
25
+ * {@link applyOps} validates each {@link RewriteOp} against the safety ceiling / node-local floor
26
+ * and commits it to a clone of the document; {@link applyGroups} commits whole {@link RewriteGroup}s
27
+ * atomically. Rejected ops are collected into {@link ApplyResult.skipped} rather than throwing.
28
+ */
29
+
23
30
  /**
24
31
  * Apply a flat list of ops to a copy of `doc`. The input document is never mutated.
25
32
  * Each op is independently validated; failing ops are skipped (collected in
@@ -32,17 +39,6 @@ declare function applyOps(doc: IRDocument, ops: readonly RewriteOp[], ctx?: Part
32
39
  */
33
40
  declare function applyGroups(doc: IRDocument, groups: readonly RewriteGroup[], ctx?: Partial<ApplyContext>): ApplyOutcome;
34
41
 
35
- /**
36
- * @domflax/core — pass manager + supporting contexts.
37
- *
38
- * Runs {@link Pattern}s grouped by {@link PassCategory} in declared order, driving the `flatten`
39
- * phase to a fixpoint under a max-iteration budget, and isolating per-node pattern errors into
40
- * {@link Diagnostic}s (a thrown pattern never aborts the run — it becomes `DF_PATTERN_THREW`).
41
- *
42
- * Dependency-free: only the `./types` contract plus `./builders` + `./ops` runtime helpers.
43
- */
44
-
45
- declare const DEFAULT_FIXPOINT: FixpointConfig;
46
42
  /** A no-op resolver: owns nothing, resolves to empty styles. Useful as an injection default. */
47
43
  declare function createNullResolver(): StyleResolver;
48
44
  /** A SelectorIndex that reports zero CSS-targeting (no combinator/structural coupling). */
@@ -63,10 +59,75 @@ declare function createNullSelectorIndex(): SelectorIndex;
63
59
  declare function buildSelectorIndex(doc: IRDocument, resolver: StyleResolver): SelectorIndex;
64
60
  /** The pattern-kit factory: produces op DRAFTS and detached NodeSpecs without any allocation. */
65
61
  declare function createRewriteFactory(): RewriteFactory;
62
+ /** Build the read-only {@link MatchContext} a pattern's `evaluate` receives for one element. */
63
+ declare function buildMatchContext(doc: IRDocument, elementId: IRNodeId, resolver: StyleResolver, selectors: SelectorIndex, safety: SafetyLevel, phase: PassPhase, iteration: number): MatchContext;
64
+
66
65
  /**
67
- * Runs `passes` over `doc` to a per-phase fixpoint. This is the concrete entry the pipeline calls
68
- * (the {@link PassManager} interface keeps passes on the call site; we accept them explicitly here
69
- * so the manager stays stateless).
66
+ * @domflax/core pass manager (the sync, static flatten driver).
67
+ *
68
+ * Runs {@link Pattern}s grouped by {@link PassPhase} in declared order, driving the `flatten` phase to
69
+ * a fixpoint under a max-iteration budget, isolating per-node pattern errors into {@link Diagnostic}s
70
+ * (a thrown pattern never aborts the run — it becomes `DF_PATTERN_THREW`), and applying the static
71
+ * flatten policy ({@link ApplyContext.gate}) — under `'provably-safe'` only provably layout-neutral
72
+ * flattens commit, so the transform never changes rendering and never launches a browser.
73
+ *
74
+ * The supporting contexts (resolvers, selector index, rewrite factory, match context) live in
75
+ * `./pass-context`; the static flatten classifier in `./flatten-safety`. Dependency-free: only the
76
+ * `./types` contract + sibling runtime helpers.
77
+ */
78
+
79
+ declare const DEFAULT_FIXPOINT: FixpointConfig;
80
+ declare const PHASE_ORDER: readonly PassPhase[];
81
+ declare function stampOrigin(draft: RewriteOpDraft, pattern: Pattern): RewriteOp;
82
+ declare function patternsForPhase(passes: readonly Pass[], phase: PassPhase): Pattern[];
83
+ interface RunState {
84
+ doc: IRDocument;
85
+ }
86
+ /**
87
+ * T5 — flatten must never DROP a style it can't reproduce. After a flatten transfers declarations onto
88
+ * a surviving (rewritable) element, if the resolver can no longer EXACTLY reverse-emit that element's
89
+ * computed style — and it could before — the flatten would silently lose the residual declarations
90
+ * during reverse-emit, so the whole flatten is reverted (the wrapper is kept). Pre-existing residue
91
+ * (already non-exact before the flatten) is not blamed on the flatten and does not trigger a revert.
92
+ */
93
+ declare function flattenWouldDropStyle(before: IRDocument, after: IRDocument, ops: readonly RewriteOp[], resolver: StyleResolver, normalizer: StyleNormalizer): boolean;
94
+ type FlattenVerdict = 'commit' | 'revert';
95
+ /**
96
+ * Decide what to do with a freshly-applied flatten op-group, given the gate. Returns:
97
+ * • `'commit'` — keep the outcome (the historical path for `'all'`, and provably-safe flattens).
98
+ * • `'revert'` — discard + bar the node (residual-drop, or a needs-verification flatten under the
99
+ * `'provably-safe'` gate).
100
+ *
101
+ * `before`/`after` are the docs immediately around the group's application.
102
+ */
103
+ declare function flattenVerdict(before: IRDocument, after: IRDocument, ops: readonly RewriteOp[], ctx: ApplyContext): FlattenVerdict;
104
+ /**
105
+ * Evaluate every pattern against `elId` until one produces ops; returns the stamped op list (and its
106
+ * pattern), or null when no pattern matched. Pattern throws become `DF_PATTERN_THREW` diagnostics.
107
+ */
108
+ declare function evaluateElement(doc: IRDocument, elId: IRNodeId, patterns: readonly Pattern[], ctx: ApplyContext, factory: RewriteFactory, phase: PassPhase, iteration: number, diagnostics: Diagnostic[]): {
109
+ ops: RewriteOp[];
110
+ pattern: Pattern;
111
+ } | null;
112
+ /** Emit the diagnostic recorded when a flatten is reverted by the gate / residual guard. */
113
+ declare function revertDiagnostic(pattern: Pattern, elId: IRNodeId, phase: PassPhase, iteration: number, resolverId: string): Diagnostic;
114
+ /** Cheap structural fingerprint of the document for oscillation detection. */
115
+ declare function docFingerprint(doc: IRDocument): string;
116
+ /** A single phase's terminal result, built from the loop's accounting. */
117
+ interface PhaseLoopState {
118
+ iterations: number;
119
+ converged: boolean;
120
+ haltReason: HaltReason;
121
+ readonly touched: Set<IRNodeId>;
122
+ readonly diagnostics: Diagnostic[];
123
+ readonly seen: Set<string>;
124
+ }
125
+ /** Record the budget-exhausted diagnostic + finalize a phase result. Shared by sync + async drivers. */
126
+ declare function finalizePhase(phase: PassPhase, s: PhaseLoopState, budget: number, onBudgetExhausted: 'warn' | 'error'): PhaseRunResult;
127
+ /**
128
+ * Runs `passes` over `doc` to a per-phase fixpoint (synchronous). This is the concrete entry the
129
+ * pipeline calls. Under the `'provably-safe'` gate, flattens that are not provably layout-neutral are
130
+ * reverted — the transform is fully static and never changes rendering.
70
131
  */
71
132
  declare function runPasses(doc: IRDocument, passes: readonly Pass[], ctx: ApplyContext, config?: FixpointConfig): {
72
133
  readonly doc: IRDocument;
@@ -75,6 +136,49 @@ declare function runPasses(doc: IRDocument, passes: readonly Pass[], ctx: ApplyC
75
136
  /** A {@link PassManager} that runs the given passes (carried on the manager instance). */
76
137
  declare function createPassManager(passes: readonly Pass[]): PassManager;
77
138
 
139
+ /**
140
+ * @domflax/core — static classification of a flatten (the VERIFIER-GATED safety core).
141
+ *
142
+ * A flatten pattern matches on `paintsNothing` + a structural/style signature, but unwrapping a
143
+ * wrapper can still change rendering: a wrapper with non-paint layout styles (e.g. `px-4 py-4`) drops
144
+ * that padding when removed (it is NOT reproduced on the surviving child), and a centering wrapper
145
+ * collapsed to `place-self:center` only stays centered when the child's NEW parent is flex/grid. The
146
+ * existing emittability revert only checks the ADDED style is re-emittable — not that the wrapper's
147
+ * own styles survive, nor that the parent context holds.
148
+ *
149
+ * {@link classifyFlattenOps} answers, for one applied flatten op-group, whether it is:
150
+ *
151
+ * • `'provably-safe'` — removing the wrapper changes NOTHING renderable: the wrapper
152
+ * establishes no box/formatting/stacking context, has no non-inherited
153
+ * own declaration that the rewrite does not reproduce on the surviving
154
+ * child, AND the rewrite adds no parent-context-dependent self-alignment
155
+ * (unless the new parent is statically flex/grid). Examples: passthrough
156
+ * / empty-style / display-contents / redundant-fragment wrappers.
157
+ * • `'needs-verification'` — anything else (drops/relies on a style, or centering→place-self).
158
+ *
159
+ * Pure + dependency-free: only the `./types` contract + `./builders` accessors.
160
+ */
161
+
162
+ /** The static verdict for one flatten op-group. */
163
+ type FlattenClass = 'provably-safe' | 'needs-verification';
164
+ /** A classified flatten plus the structural anchors a verifier needs to render before/after. */
165
+ interface FlattenClassification {
166
+ readonly kind: FlattenClass;
167
+ /** The unwrapped wrapper (in the BEFORE doc), or null when the group removes no element box. */
168
+ readonly wrapperId: IRNodeId | null;
169
+ /** The surviving child styles fold onto (the AFTER subtree root), or null. */
170
+ readonly childId: IRNodeId | null;
171
+ }
172
+ /**
173
+ * Statically classify one applied flatten op-group. `before` is the doc as it was BEFORE the group's
174
+ * ops; `after` is the result of applying them.
175
+ *
176
+ * A group that unwraps no element box (e.g. {@link redundant-fragment}, or a style-only flatten) is
177
+ * `provably-safe` — there is no box whose removal could move/resize anything. Otherwise the three
178
+ * criteria above decide.
179
+ */
180
+ declare function classifyFlattenOps(before: IRDocument, after: IRDocument, ops: readonly RewriteOp[], norm: StyleNormalizer): FlattenClassification;
181
+
78
182
  /**
79
183
  * @domflax/core — the pure, single-file pipeline.
80
184
  *
@@ -121,6 +225,36 @@ declare function createPipeline(): Pipeline;
121
225
  */
122
226
  declare function syncClassesFromComputed(doc: IRDocument, resolver: StyleResolver, norm: StyleNormalizer): void;
123
227
 
228
+ /**
229
+ * @domflax/patterns — flatten pattern: `display-contents-wrapper`.
230
+ *
231
+ * Collapses a wrapper that has explicitly opted OUT of generating a box:
232
+ *
233
+ * <div style="display:contents"><Child/></div> → <Child/>
234
+ *
235
+ * `display:contents` makes an element generate NO box of its own — its children render exactly as if
236
+ * they were direct children of the element's parent. A `display:contents` wrapper with a single
237
+ * element child is therefore already a layout passthrough: it contributes nothing to flow, paint
238
+ * (a contents box paints nothing), formatting, stacking, or containing-block resolution. Removing it
239
+ * and hoisting the child produces a tree that is layout-identical — the wrapper's only remaining
240
+ * effect was inheritance, which is preserved by folding inheritable declarations onto the child first.
241
+ *
242
+ * This is the safest possible wrapper-elimination: the box being removed provably did not exist.
243
+ * The opacity-barrier + selector-safety guards (ref/handlers/dynamic-children/raw-html/combinator/
244
+ * reparent-impact) are auto-applied for every `flatten/*` pattern; the `where` predicates add the
245
+ * passthrough-specific requirements (no own attrs / dynamic-or-spread classes, no `var()` coupling,
246
+ * not a component, not a structural-pseudo subject).
247
+ *
248
+ * (Chosen as the safe variant of the size-hoisting "full-size passthrough" idea: hoisting an explicit
249
+ * `width/height:100%` onto a child is only sound when the child is block-level and unsized, which is
250
+ * not knowable from the wrapper alone — whereas a `display:contents` box is a passthrough by definition.)
251
+ */
252
+ /**
253
+ * Flatten a `display:contents` wrapper (a box that generates no box) into its sole element child,
254
+ * folding any inheritable styles down first so inherited values survive the removal.
255
+ */
256
+ declare const displayContentsWrapper: AuthoredPattern<Captures>;
257
+
124
258
  /**
125
259
  * @domflax/patterns — flatten pattern: `empty-style-div`.
126
260
  *
@@ -135,11 +269,11 @@ declare function syncClassesFromComputed(doc: IRDocument, resolver: StyleResolve
135
269
  * a descendant might read. Its box is therefore indistinguishable from "not being there", so it can
136
270
  * be unwrapped into its sole child.
137
271
  *
138
- * Authored with the declarative {@link pattern} API. The opacity-barrier + selector-safety guards
139
- * (ref/handlers/dynamic-children/raw-html/combinator/reparent-impact) are applied automatically for
140
- * every `flatten/*` pattern; the `where` predicates below add the LAYOUT-neutrality requirements
141
- * specific to this pattern (no non-block display, no box/formatting/stacking context, no containing
142
- * block, no custom-property coupling, no structural-pseudo targeting).
272
+ * Authored with the declarative {@link definePattern} API. The opacity-barrier + selector-safety
273
+ * guards (ref/handlers/dynamic-children/raw-html/combinator/reparent-impact) are applied
274
+ * automatically for every `flatten/*` pattern; the `where` predicates below add the LAYOUT-neutrality
275
+ * requirements specific to this pattern (no non-block display, no box/formatting/stacking context, no
276
+ * containing block, no custom-property coupling, no structural-pseudo targeting).
143
277
  */
144
278
  /**
145
279
  * Flatten a layout-neutral, style-free `<div>` wrapper into its sole element child.
@@ -157,11 +291,11 @@ declare const emptyStyleDiv: AuthoredPattern<Captures>;
157
291
  * The wrapper only exists to center one element; once `place-self:center` lives on the child the
158
292
  * wrapper is pure structural noise and can go.
159
293
  *
160
- * Authored with the declarative {@link pattern} API: the match is the flex-centering computed-style
161
- * signature on a single-element-child `<div>` that paints nothing of its own; the recipe folds
162
- * inheritable styles onto the child, grants it `place-self:center`, then unwraps the wrapper
163
- * (id-preserving). The opacity-barrier + selector-safety guards are applied automatically by the
164
- * `pattern()` factory for every `flatten/*` pattern.
294
+ * Authored with the declarative {@link definePattern} API: the match is the flex-centering
295
+ * computed-style signature on a single-element-child `<div>` that paints nothing of its own; the
296
+ * recipe folds inheritable styles onto the child, grants it `place-self:center`, then unwraps the
297
+ * wrapper (id-preserving). The opacity-barrier + selector-safety guards are applied automatically by
298
+ * the `definePattern` factory for every `flatten/*` pattern.
165
299
  */
166
300
  /**
167
301
  * Flatten a flex-centering `<div>` wrapper into its sole element child, granting the child
@@ -169,6 +303,29 @@ declare const emptyStyleDiv: AuthoredPattern<Captures>;
169
303
  */
170
304
  declare const flexCenterWrapper: AuthoredPattern<Captures>;
171
305
 
306
+ /**
307
+ * @domflax/patterns — flatten pattern: `inline-flex-center-wrapper`.
308
+ *
309
+ * Collapses the inline-flex flavour of the "centering wrapper" idiom
310
+ *
311
+ * <div style="display:inline-flex; align-items:center; justify-content:center"><Child/></div>
312
+ *
313
+ * into its sole child, pushing the centering intent down onto the child as `place-self: center`.
314
+ * Like its block-level `flex-center-wrapper` sibling the wrapper only exists to center one element;
315
+ * once `place-self:center` lives on the child the wrapper is pure structural noise and can go.
316
+ *
317
+ * Authored with the declarative {@link definePattern} API: the match is the inline-flex-centering
318
+ * computed-style signature on a single-element-child `<div>` that paints nothing of its own; the
319
+ * recipe folds inheritable styles onto the child, grants it `place-self:center`, then unwraps the
320
+ * wrapper (id-preserving). The opacity-barrier + selector-safety guards are applied automatically by
321
+ * the `definePattern` factory for every `flatten/*` pattern.
322
+ */
323
+ /**
324
+ * Flatten an inline-flex-centering `<div>` wrapper into its sole element child, granting the child
325
+ * `place-self:center`.
326
+ */
327
+ declare const inlineFlexCenterWrapper: AuthoredPattern<Captures>;
328
+
172
329
  /**
173
330
  * @domflax/patterns — flatten pattern: `nested-flex-merge`.
174
331
  *
@@ -196,6 +353,33 @@ declare const flexCenterWrapper: AuthoredPattern<Captures>;
196
353
  */
197
354
  declare const nestedFlexMerge: AuthoredPattern<Captures>;
198
355
 
356
+ /**
357
+ * @domflax/patterns — flatten pattern: `nested-grid-merge`.
358
+ *
359
+ * Collapses a redundant nesting of two grid containers
360
+ *
361
+ * <div style="display:grid; gap:8px">
362
+ * <div style="display:grid; grid-template-columns:1fr 1fr"> … </div>
363
+ * </div>
364
+ *
365
+ * where the OUTER grid container's sole element child is ITSELF a grid container, into a single grid
366
+ * container carrying the union of both elements' grid declarations. The outer wrapper's box is then
367
+ * structural noise (it paints nothing and only establishes a grid context the merged child now also
368
+ * establishes), so it is removed.
369
+ *
370
+ * This is the grid analogue of `nested-flex-merge`. The declarative match is a grid `<div>` with a
371
+ * single element child painting nothing of its own (auto-guarded against opacity barriers / combinator
372
+ * targeting like every `flatten/*` pattern). The value-relational reasoning — the child must also be a
373
+ * (non-combinator) grid container, the wrapper must carry only transferable grid/inheritable
374
+ * declarations, and the two must not conflict on any shared grid property — lives in the `rewrite`
375
+ * op-draft factory escape hatch, which folds inherited styles, transfers the wrapper's grid
376
+ * declarations onto the child (target-wins), then unwraps the wrapper.
377
+ */
378
+ /**
379
+ * Flatten a grid container whose sole child is a compatible grid container into a single container.
380
+ */
381
+ declare const nestedGridMerge: AuthoredPattern<Captures>;
382
+
199
383
  /**
200
384
  * @domflax/patterns — flatten pattern: `passthrough-wrapper`.
201
385
  *
@@ -209,11 +393,11 @@ declare const nestedFlexMerge: AuthoredPattern<Captures>;
209
393
  * Such a `<div>` is pure DOM noise: removing it and hoisting the child is invisible to both paint
210
394
  * and layout.
211
395
  *
212
- * Authored with the declarative {@link pattern} API. The opacity-barrier + selector-safety guards
213
- * (ref/handlers/dynamic-children/raw-html/combinator/reparent-impact) are applied automatically for
214
- * every `flatten/*` pattern; the `where` predicates add the passthrough-specific requirements (no
215
- * box/formatting/stacking context, no own attrs, no dynamic/spread classes, not a component, not a
216
- * structural-pseudo subject).
396
+ * Authored with the declarative {@link definePattern} API. The opacity-barrier + selector-safety
397
+ * guards (ref/handlers/dynamic-children/raw-html/combinator/reparent-impact) are applied
398
+ * automatically for every `flatten/*` pattern; the `where` predicates add the passthrough-specific
399
+ * requirements (no box/formatting/stacking context, no own attrs, no dynamic/spread classes, not a
400
+ * component, not a structural-pseudo subject).
217
401
  */
218
402
  /**
219
403
  * Flatten a do-nothing `<div>` wrapper into its sole element child, folding any inheritable styles
@@ -245,6 +429,86 @@ declare const passthroughWrapper: AuthoredPattern<Captures>;
245
429
  */
246
430
  declare const redundantFragment: AuthoredPattern<Captures>;
247
431
 
432
+ /**
433
+ * @domflax/patterns — flatten pattern: `redundant-inline-wrapper`.
434
+ *
435
+ * Collapses a purely-structural INLINE wrapper:
436
+ *
437
+ * <span><Child/></span> (display:inline, no own style)
438
+ *
439
+ * An inline `<span>` that paints nothing, establishes no box / formatting / stacking context, carries
440
+ * no attributes beyond an (optional) inert class, declares no custom properties, and holds exactly one
441
+ * element child is pure inline noise. An empty inline box merely wraps its child's box; removing it and
442
+ * hoisting the child leaves both paint and layout untouched (the surviving child folds the inheritable
443
+ * declarations the span carried).
444
+ *
445
+ * This is the inline sibling of `passthrough-wrapper` (which targets `<div>`): the same opacity-barrier
446
+ * + selector-safety guards are auto-applied by the `pattern()` factory for every `flatten/*` pattern;
447
+ * the `where` predicates add the inline-passthrough requirements (display must be the inline default,
448
+ * no box/formatting/stacking context or var coupling, no own attrs / dynamic-or-spread classes, not a
449
+ * component, not a structural-pseudo subject).
450
+ */
451
+ /**
452
+ * Flatten a do-nothing inline `<span>` wrapper into its sole element child, folding any inheritable
453
+ * styles down first so inherited values survive the box removal.
454
+ */
455
+ declare const redundantInlineWrapper: AuthoredPattern<Captures>;
456
+
457
+ /**
458
+ * @domflax/patterns — compress pattern: `border-radius-shorthand`.
459
+ *
460
+ * Collapses an element whose four corner radii are expressed as separate longhand declarations and
461
+ * are ALL EQUAL into the single CSS `border-radius` shorthand:
462
+ *
463
+ * border-top-left-radius:0.5rem; border-top-right-radius:0.5rem;
464
+ * border-bottom-right-radius:0.5rem; border-bottom-left-radius:0.5rem
465
+ * ⇒ border-radius:0.5rem (Tailwind `rounded-lg`)
466
+ *
467
+ * The IR's computed StyleMap keeps each corner as its own longhand (Tailwind's `rounded-tl-*` /
468
+ * `rounded-tr-*` / … each resolve to one corner property). This pass runs the collapse in reverse on
469
+ * the computed map ONLY when all four corners share one value — the single case that maps cleanly to
470
+ * a single Tailwind utility (the CSS 2-value `border-radius` form is DIAGONAL, which has no clean
471
+ * `rounded-*` edge utility, so per-corner differences are intentionally left alone). Rebuilding the
472
+ * map with one `border-radius` decl lets the minimizing reverse-emit pick the single `rounded-*`
473
+ * token covering all four corners instead of two edge tokens.
474
+ *
475
+ * Authored with the declarative {@link pattern} API: `definePattern` auto-applies the compress safety guards — a dynamic or opaque class list
476
+ * and combinator-subject selectors are excluded (a ref / event handler / dynamic child / dangerous
477
+ * HTML never blocks a class-only rewrite); the
478
+ * `rewriteClasses` recipe rebuilds the class StyleMap, declining (`null`) unless the four corners are
479
+ * present, concrete, equal, and share an `!important` flag.
480
+ */
481
+ /** Fold four equal corner radii into the single `border-radius` shorthand. */
482
+ declare const borderRadiusShorthand: AuthoredPattern<Captures>;
483
+
484
+ /**
485
+ * @domflax/patterns — compress pattern: `border-shorthand`.
486
+ *
487
+ * Collapses an element whose four border-side WIDTHS are expressed as separate longhand declarations
488
+ * back into the shortest equivalent `border-width` shorthand:
489
+ *
490
+ * border-top-width:2px; border-right-width:2px; border-bottom-width:2px; border-left-width:2px
491
+ * ⇒ border-width:2px (Tailwind `border-2`)
492
+ *
493
+ * border-top-width:2px; border-bottom-width:2px; border-left-width:4px; border-right-width:4px
494
+ * ⇒ border-width:2px 4px (Tailwind `border-y-2 border-x-4`)
495
+ *
496
+ * Tailwind's per-side / per-axis width utilities (`border-t-*`, `border-x-*`, …) each resolve to the
497
+ * matching `border-*-width` longhand(s); the shared normalizer keeps them longhand. This pass runs
498
+ * the expansion in reverse on the computed map ONLY when the four widths fold cleanly into a 1- or
499
+ * 2-value form — i.e. `top===bottom` AND `left===right`. Rebuilding the map with one `border-width`
500
+ * shorthand lets the minimizing reverse-emit pick the single/paired utility (`border-2`, or
501
+ * `border-x-* border-y-*`) instead of four per-side tokens. Only WIDTH is folded — border style and
502
+ * color are independent longhands the resolver carries separately, so this never disturbs them.
503
+ *
504
+ * Authored with the declarative {@link pattern} API: `definePattern` auto-applies the compress safety guards — a dynamic or opaque class list
505
+ * and combinator-subject selectors are excluded (a ref / event handler / dynamic child / dangerous
506
+ * HTML never blocks a class-only rewrite); the `rewriteClasses`
507
+ * recipe rebuilds the class StyleMap, declining (`null`) unless the four widths fold cleanly.
508
+ */
509
+ /** Compress an element's four equal/paired border-width longhands into the shortest shorthand. */
510
+ declare const borderShorthand: AuthoredPattern<Captures>;
511
+
248
512
  /**
249
513
  * @domflax/patterns — compress pattern: `dedupe-classes`.
250
514
  *
@@ -265,8 +529,9 @@ declare const redundantFragment: AuthoredPattern<Captures>;
265
529
  * is NOT the winning `origin` of any declaration across ANY style condition. Such a token can
266
530
  * be deleted with zero effect on the computed style.
267
531
  *
268
- * Authored with the declarative {@link pattern} API: the `where` guards exclude opacity barriers,
269
- * dynamic/opaque class lists, and combinator subjects; the `dropClasses` recipe returns the set of
532
+ * Authored with the declarative {@link pattern} API: `definePattern` auto-applies the compress safety guards a dynamic or opaque class list
533
+ * and combinator-subject selectors are excluded (a ref / event handler / dynamic child / dangerous
534
+ * HTML never blocks a class-only rewrite); the `dropClasses` recipe returns the set of
270
535
  * fully-overridden, resolver-droppable tokens to delete (their `shadowed` provenance is pruned
271
536
  * automatically before the minimal class StyleMap is re-installed).
272
537
  */
@@ -276,6 +541,29 @@ declare const redundantFragment: AuthoredPattern<Captures>;
276
541
  */
277
542
  declare const dedupeClasses: AuthoredPattern<Captures>;
278
543
 
544
+ /**
545
+ * @domflax/patterns — compress pattern: `gap-shorthand`.
546
+ *
547
+ * Collapses an element whose grid/flex gutters are expressed as two equal axis longhands back into
548
+ * the single `gap` shorthand:
549
+ *
550
+ * row-gap:16px; column-gap:16px ⇒ gap:16px (Tailwind `gap-x-4 gap-y-4` → `gap-4`)
551
+ *
552
+ * The IR's computed StyleMap is canonically LONGHAND (the shared normalizer expands the `gap`
553
+ * shorthand into `row-gap` + `column-gap` at parse time). This pass runs the expansion in reverse on
554
+ * the computed map ONLY when both axes carry the SAME value and `!important` flag — i.e. when the two
555
+ * gutters genuinely fold into a single-value `gap`. When the axes differ it declines, leaving the two
556
+ * longhands verbatim (an asymmetric gutter has no equivalent single-value shorthand).
557
+ *
558
+ * Authored with the declarative {@link pattern} API: `definePattern` auto-applies the compress safety guards — a dynamic or opaque class list
559
+ * and combinator-subject selectors are excluded (a ref / event handler / dynamic child / dangerous
560
+ * HTML never blocks a class-only rewrite); the
561
+ * `rewriteClasses` recipe rebuilds the class StyleMap, declining (`null`) unless the two axis gaps
562
+ * are present, equal, and share an `!important` flag.
563
+ */
564
+ /** Fold an equal `row-gap`/`column-gap` pair into the single `gap` shorthand. */
565
+ declare const gapShorthand: AuthoredPattern<Captures>;
566
+
279
567
  /**
280
568
  * @domflax/patterns — compress pattern: `inset-shorthand`.
281
569
  *
@@ -290,8 +578,9 @@ declare const dedupeClasses: AuthoredPattern<Captures>;
290
578
  * collapses only the block axis and keeps the `left`/`right` longhands verbatim. When nothing
291
579
  * collapses (all four distinct, or fewer than a full pair present) the pattern declines.
292
580
  *
293
- * Authored with the declarative {@link pattern} API: the `where` guards exclude opacity barriers,
294
- * dynamic class lists, and combinator subjects; the `rewriteClasses` recipe rebuilds the class
581
+ * Authored with the declarative {@link pattern} API: `definePattern` auto-applies the compress safety guards a dynamic or opaque class list
582
+ * and combinator-subject selectors are excluded (a ref / event handler / dynamic child / dangerous
583
+ * HTML never blocks a class-only rewrite); the `rewriteClasses` recipe rebuilds the class
295
584
  * StyleMap, declining (`null`) unless at least one inset axis collapses.
296
585
  */
297
586
  /**
@@ -319,8 +608,9 @@ declare const insetShorthand: AuthoredPattern<Captures>;
319
608
  * It is a pure representation change: the resolved box model is identical, only the declaration
320
609
  * count shrinks from four to one, which the backend can then re-emit as a single shorthand utility.
321
610
  *
322
- * Authored with the declarative {@link pattern} API: the `where` guards exclude opacity barriers,
323
- * dynamic class lists, and combinator subjects; the `rewriteClasses` recipe rebuilds the class
611
+ * Authored with the declarative {@link pattern} API: `definePattern` auto-applies the compress safety guards a dynamic or opaque class list
612
+ * and combinator-subject selectors are excluded (a ref / event handler / dynamic child / dangerous
613
+ * HTML never blocks a class-only rewrite); the `rewriteClasses` recipe rebuilds the class
324
614
  * StyleMap, declining (`null`) unless all four margin longhands are present with a uniform
325
615
  * (non-)`!important` flag.
326
616
  */
@@ -329,6 +619,56 @@ declare const insetShorthand: AuthoredPattern<Captures>;
329
619
  */
330
620
  declare const marginShorthand: AuthoredPattern<Captures>;
331
621
 
622
+ /**
623
+ * @domflax/patterns — compress pattern: `overflow-shorthand`.
624
+ *
625
+ * Collapses an element whose two overflow axes are expressed as equal longhands back into the single
626
+ * `overflow` shorthand:
627
+ *
628
+ * overflow-x:auto; overflow-y:auto ⇒ overflow:auto (Tailwind `overflow-x-auto overflow-y-auto`
629
+ * → `overflow-auto`)
630
+ *
631
+ * Unlike the box shorthands, the shared normalizer leaves `overflow-x` / `overflow-y` as independent
632
+ * longhands (it does not synthesize an `overflow` shorthand), so an element styled with two equal
633
+ * axis utilities keeps two separate declarations until this pass folds them. The fold runs ONLY when
634
+ * both axes carry the SAME value and `!important` flag; an asymmetric pair (`overflow-x !==
635
+ * overflow-y`) has no single-keyword `overflow` equivalent and is declined.
636
+ *
637
+ * Authored with the declarative {@link pattern} API: `definePattern` auto-applies the compress safety guards — a dynamic or opaque class list
638
+ * and combinator-subject selectors are excluded (a ref / event handler / dynamic child / dangerous
639
+ * HTML never blocks a class-only rewrite); the
640
+ * `rewriteClasses` recipe rebuilds the class StyleMap, declining (`null`) unless both overflow axes
641
+ * are present, equal, and share an `!important` flag.
642
+ */
643
+ /** Fold an equal `overflow-x`/`overflow-y` pair into the single `overflow` shorthand. */
644
+ declare const overflowShorthand: AuthoredPattern<Captures>;
645
+
646
+ /**
647
+ * @domflax/patterns — compress pattern: `overscroll-behavior-shorthand`.
648
+ *
649
+ * Collapses an element whose two overscroll-behavior axes are expressed as separate longhand
650
+ * declarations and are EQUAL into the single CSS `overscroll-behavior` shorthand:
651
+ *
652
+ * overscroll-behavior-x:contain; overscroll-behavior-y:contain
653
+ * ⇒ overscroll-behavior:contain (Tailwind `overscroll-x-contain overscroll-y-contain` → `overscroll-contain`)
654
+ *
655
+ * Tailwind's `overscroll-x-*` / `overscroll-y-*` utilities each resolve to the matching
656
+ * `overscroll-behavior-{x,y}` axis longhand, and the shared normalizer keeps `overscroll-behavior`
657
+ * un-expanded (it is NOT one of the box/gap shorthands the normalizer splits). So only the equal-axis
658
+ * form maps cleanly to a single `overscroll-*` utility. This pass runs the collapse in reverse on the
659
+ * computed map ONLY when both axes carry the SAME value and `!important` flag, replacing them with one
660
+ * `overscroll-behavior` decl so the minimizing reverse-emit can pick a single `overscroll-*` token
661
+ * instead of two axis tokens. When the axes differ it declines, leaving the two longhands verbatim.
662
+ *
663
+ * Authored with the declarative {@link pattern} API: `definePattern` auto-applies the compress safety guards — a dynamic or opaque class list
664
+ * and combinator-subject selectors are excluded (a ref / event handler / dynamic child / dangerous
665
+ * HTML never blocks a class-only rewrite); the
666
+ * `rewriteClasses` recipe rebuilds the class StyleMap, declining (`null`) unless both axes are
667
+ * present, concrete, equal, and share an `!important` flag.
668
+ */
669
+ /** Fold an equal overscroll-behavior x/y pair into the single `overscroll-behavior` shorthand. */
670
+ declare const overscrollBehaviorShorthand: AuthoredPattern<Captures>;
671
+
332
672
  /**
333
673
  * @domflax/patterns — compress pattern: `padding-shorthand`.
334
674
  *
@@ -345,8 +685,9 @@ declare const marginShorthand: AuthoredPattern<Captures>;
345
685
  * shorthand at parse time). This pass runs the expansion in reverse on the computed map ONLY when
346
686
  * the four sides fold cleanly into a 1- or 2-value form — i.e. `top===bottom` AND `left===right`.
347
687
  *
348
- * Authored with the declarative {@link pattern} API: the `where` guards exclude opacity barriers,
349
- * dynamic class lists, spread/component identity, and combinator subjects; the `rewriteClasses`
688
+ * Authored with the declarative {@link pattern} API: `definePattern` auto-applies the compress safety guards a dynamic or opaque class list
689
+ * and combinator-subject selectors are excluded (a ref / event handler / dynamic child / dangerous
690
+ * HTML never blocks a class-only rewrite); the `rewriteClasses`
350
691
  * recipe rebuilds the class StyleMap, declining (`null`) unless the four sides fold cleanly.
351
692
  */
352
693
  /**
@@ -354,6 +695,84 @@ declare const marginShorthand: AuthoredPattern<Captures>;
354
695
  */
355
696
  declare const paddingShorthand: AuthoredPattern<Captures>;
356
697
 
698
+ /**
699
+ * @domflax/patterns — compress pattern: `place-shorthand`.
700
+ *
701
+ * Recompacts the grid/flex alignment longhands on an element's computed style into the CSS `place-*`
702
+ * shorthands whenever the two axes of a pair agree:
703
+ *
704
+ * • align-items == justify-items → `place-items: <v>` (Tailwind `items-* justify-items-*`)
705
+ * • align-content == justify-content → `place-content: <v>` (Tailwind `content-* justify-*`)
706
+ *
707
+ * The two collapses are INDEPENDENT: an element whose items pair agrees but whose content pair does
708
+ * not collapses only `place-items` and keeps the content longhands verbatim. The shared normalizer
709
+ * leaves all four alignment properties as independent longhands (it synthesizes no `place-*`
710
+ * shorthand), so an element styled with two matching axis utilities keeps the longhands until this
711
+ * pass folds them. When neither pair agrees the pattern declines.
712
+ *
713
+ * Authored with the declarative {@link pattern} API: `definePattern` auto-applies the compress safety guards — a dynamic or opaque class list
714
+ * and combinator-subject selectors are excluded (a ref / event handler / dynamic child / dangerous
715
+ * HTML never blocks a class-only rewrite); the
716
+ * `rewriteClasses` recipe rebuilds the class StyleMap, declining (`null`) unless at least one
717
+ * alignment pair collapses.
718
+ */
719
+ /** Fold matching align/justify pairs into the `place-items` / `place-content` shorthands. */
720
+ declare const placeShorthand: AuthoredPattern<Captures>;
721
+
722
+ /**
723
+ * @domflax/patterns — compress pattern: `scroll-margin-shorthand`.
724
+ *
725
+ * Collapses an element whose four scroll-margin sides are expressed as separate longhand
726
+ * declarations and are ALL EQUAL into the single CSS `scroll-margin` shorthand:
727
+ *
728
+ * scroll-margin-top:1rem; scroll-margin-right:1rem;
729
+ * scroll-margin-bottom:1rem; scroll-margin-left:1rem
730
+ * ⇒ scroll-margin:1rem (Tailwind `scroll-m-4`)
731
+ *
732
+ * Tailwind's `scroll-mt-*` / `scroll-mx-*` / … utilities each resolve to the matching
733
+ * `scroll-margin-*` longhand(s), and the shared normalizer keeps `scroll-margin` un-expanded (it is
734
+ * NOT one of the box shorthands the normalizer splits). So only the all-equal (1-value) form maps
735
+ * cleanly to a single `scroll-m-*` utility — the 2-value (`scroll-mx`/`scroll-my`) shape is left to
736
+ * the resolver's own reverse-emit. This pass runs the collapse in reverse on the computed map ONLY
737
+ * when all four sides share one value, replacing them with one `scroll-margin` decl so the minimizing
738
+ * reverse-emit can pick a single `scroll-m-*` token instead of two axis tokens.
739
+ *
740
+ * Authored with the declarative {@link pattern} API: `definePattern` auto-applies the compress safety guards — a dynamic or opaque class list
741
+ * and combinator-subject selectors are excluded (a ref / event handler / dynamic child / dangerous
742
+ * HTML never blocks a class-only rewrite); the
743
+ * `rewriteClasses` recipe rebuilds the class StyleMap, declining (`null`) unless the four sides are
744
+ * present, concrete, equal, and share an `!important` flag.
745
+ */
746
+ /** Fold four equal scroll-margin sides into the single `scroll-margin` shorthand. */
747
+ declare const scrollMarginShorthand: AuthoredPattern<Captures>;
748
+
749
+ /**
750
+ * @domflax/patterns — compress pattern: `scroll-padding-shorthand`.
751
+ *
752
+ * Collapses an element whose four scroll-padding sides are expressed as separate longhand
753
+ * declarations and are ALL EQUAL into the single CSS `scroll-padding` shorthand:
754
+ *
755
+ * scroll-padding-top:1rem; scroll-padding-right:1rem;
756
+ * scroll-padding-bottom:1rem; scroll-padding-left:1rem
757
+ * ⇒ scroll-padding:1rem (Tailwind `scroll-p-4`)
758
+ *
759
+ * Tailwind's `scroll-pt-*` / `scroll-px-*` / … utilities each resolve to the matching
760
+ * `scroll-padding-*` longhand(s), and the shared normalizer keeps `scroll-padding` un-expanded (it is
761
+ * NOT one of the box shorthands the normalizer splits). So only the all-equal (1-value) form maps
762
+ * cleanly to a single `scroll-p-*` utility — the 2-value (`scroll-px`/`scroll-py`) shape is left to
763
+ * the resolver's own reverse-emit. This pass runs the collapse in reverse on the computed map ONLY
764
+ * when all four sides share one value, replacing them with one `scroll-padding` decl so the minimizing
765
+ * reverse-emit can pick a single `scroll-p-*` token instead of two axis tokens.
766
+ *
767
+ * Authored with the declarative {@link pattern} API: `definePattern` auto-applies the compress safety guards — a dynamic or opaque class list
768
+ * and combinator-subject selectors are excluded (a ref / event handler / dynamic child / dangerous
769
+ * HTML never blocks a class-only rewrite); the
770
+ * `rewriteClasses` recipe rebuilds the class StyleMap, declining (`null`) unless the four sides are
771
+ * present, concrete, equal, and share an `!important` flag.
772
+ */
773
+ /** Fold four equal scroll-padding sides into the single `scroll-padding` shorthand. */
774
+ declare const scrollPaddingShorthand: AuthoredPattern<Captures>;
775
+
357
776
  /**
358
777
  * @domflax/patterns — compress pattern: `size-shorthand`.
359
778
  *
@@ -368,8 +787,9 @@ declare const paddingShorthand: AuthoredPattern<Captures>;
368
787
  * at codegen). Both longhands are removed and replaced by the merged `size` decl, so the rewrite is
369
788
  * idempotent — once collapsed there is no `width`+`height` pair left to re-match.
370
789
  *
371
- * Authored with the declarative {@link pattern} API: the `where` guards exclude opacity barriers,
372
- * dynamic class lists, and combinator subjects (compress patterns get NO auto-guards); the
790
+ * Authored with the declarative {@link pattern} API: `definePattern` auto-applies the compress safety guards a dynamic or opaque class list
791
+ * and combinator-subject selectors are excluded (a ref / event handler / dynamic child / dangerous
792
+ * HTML never blocks a class-only rewrite); the
373
793
  * `rewriteClasses` recipe rebuilds the class StyleMap, returning `null` (decline) unless the BASE
374
794
  * width/height are equal, concrete, and share an `!important` flag.
375
795
  */
@@ -380,8 +800,8 @@ declare const sizeShorthand: AuthoredPattern<Captures>;
380
800
  * AUTO-GENERATED by `scripts/gen-registry.mjs` — DO NOT EDIT BY HAND.
381
801
  *
382
802
  * Regenerate with `npm run generate` (also runs automatically before build/typecheck/test).
383
- * Patterns are discovered by the `*.pattern.ts` file convention under `src/flatten` and
384
- * `src/compress`; the array below is sorted flatten-before-compress.
803
+ * Patterns are discovered by the `*.pattern.ts` file convention under `src/library/flatten`
804
+ * and `src/library/compress`; the array below is sorted flatten-before-compress.
385
805
  */
386
806
 
387
807
  /** Every built-in pattern, in registration order (flatten patterns before compress). */
@@ -442,8 +862,10 @@ interface Domflax {
442
862
  readonly resolver: StyleResolver;
443
863
  readonly patterns: readonly Pattern[];
444
864
  /**
445
- * Transform one file. For `.jsx`/`.tsx` this runs the full pipeline (parse → resolve → flatten →
446
- * reverse-emitprint); every other (or unsupported) file is returned unchanged.
865
+ * Transform one file (SYNCHRONOUS, fully static, never launches a browser). For `.jsx`/`.tsx` this
866
+ * runs the full pipeline (parse resolve flatten[provably-safe only] reverse-emit print);
867
+ * every other (or unsupported) file is returned unchanged. Only provably layout-neutral flattens are
868
+ * applied — domflax never changes rendering.
447
869
  */
448
870
  transform(code: string, id: string): DomflaxTransformResult;
449
871
  }
@@ -457,6 +879,7 @@ declare function createDomflax(options?: DomflaxOptions): Domflax;
457
879
  interface DomflaxVitePlugin {
458
880
  readonly name: string;
459
881
  readonly enforce: 'pre';
882
+ /** Vite's per-file source hook. Fully synchronous and browser-free. */
460
883
  transform(code: string, id: string): DomflaxTransformResult | null;
461
884
  }
462
885
  /**
@@ -536,4 +959,4 @@ interface DomflaxDefault {
536
959
  /** Default export: an object exposing `vite`, `webpack`, and the programmatic `createDomflax`. */
537
960
  declare const domflax: DomflaxDefault;
538
961
 
539
- export { ApplyContext, type ApplyOutcome, ApplyResult, Captures, DEFAULT_FIXPOINT, type Domflax, type DomflaxDefault, type DomflaxOptions, type DomflaxProvider, type DomflaxTransformResult, type DomflaxVitePlugin, type DomflaxWebpackCompiler, type DomflaxWebpackPlugin, EncodedSourceMap, FixpointConfig, IRDocument, Pass, PassManager, Pattern, PhaseRunResult, Pipeline, type ResolvedDomflaxOptions, RewriteFactory, RewriteGroup, RewriteOp, SafetyLevel, SelectorIndex, StyleNormalizer, StyleResolver, SyntheticSink, applyGroups, applyOps, buildSelectorIndex, builtinPatterns, cloneDocument, createDomflax, createNullResolver, createNullSelectorIndex, createPassManager, createPipeline, createRewriteFactory, createSyntheticSink, dedupeClasses, domflax as default, emptyStyleDiv, flexCenterWrapper, insetShorthand, marginShorthand, nestedFlexMerge, paddingShorthand, passthroughWrapper, redundantFragment, runPasses, sizeShorthand, syncClassesFromComputed, vite, webpack };
962
+ export { ApplyContext, type ApplyOutcome, ApplyResult, Captures, DEFAULT_FIXPOINT, Diagnostic, type Domflax, type DomflaxDefault, type DomflaxOptions, type DomflaxProvider, type DomflaxTransformResult, type DomflaxVitePlugin, type DomflaxWebpackCompiler, type DomflaxWebpackPlugin, EncodedSourceMap, FixpointConfig, type FlattenClass, type FlattenClassification, type FlattenVerdict, HaltReason, IRDocument, IRNodeId, MatchContext, PHASE_ORDER, Pass, PassManager, PassPhase, Pattern, type PhaseLoopState, PhaseRunResult, Pipeline, type ResolvedDomflaxOptions, RewriteFactory, RewriteGroup, RewriteOp, RewriteOpDraft, type RunState, SafetyLevel, SelectorIndex, StyleNormalizer, StyleResolver, SyntheticSink, applyGroups, applyOps, borderRadiusShorthand, borderShorthand, buildMatchContext, buildSelectorIndex, builtinPatterns, classifyFlattenOps, cloneDocument, createDomflax, createNullResolver, createNullSelectorIndex, createPassManager, createPipeline, createRewriteFactory, createSyntheticSink, dedupeClasses, domflax as default, displayContentsWrapper, docFingerprint, emptyStyleDiv, evaluateElement, finalizePhase, flattenVerdict, flattenWouldDropStyle, flexCenterWrapper, gapShorthand, inlineFlexCenterWrapper, insetShorthand, marginShorthand, nestedFlexMerge, nestedGridMerge, overflowShorthand, overscrollBehaviorShorthand, paddingShorthand, passthroughWrapper, patternsForPhase, placeShorthand, redundantFragment, redundantInlineWrapper, revertDiagnostic, runPasses, scrollMarginShorthand, scrollPaddingShorthand, sizeShorthand, stampOrigin, syncClassesFromComputed, vite, webpack };