@fundamental-engine/elements 0.9.1 → 0.9.3

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.
@@ -84,7 +84,7 @@
84
84
  "declarations": [
85
85
  {
86
86
  "kind": "class",
87
- "description": "`<field-cell force=\"swirl\" color=\"#2dd4bf\">` — an in-frame field surface (§25.1).\n\nA standalone field sized to its container that renders *one* force, with its own\nlightweight particle pool, its own pointer interaction, and a lifecycle that pauses\nwhen off-screen. It is **not** the §-engine: it's a lighter \"demo/poster\" engine,\ncompletely separate from the page `<field-root>` and the core field loop.\n\n- `ResizeObserver` re-fits the canvas (DPR-aware) and rebuilds the pool.\n- `IntersectionObserver` gates the rAF loop — paused when off-screen.\n- Honours `prefers-reduced-motion`: renders one static frame, no animation.",
87
+ "description": "`<field-cell force=\"swirl\" color=\"#2dd4bf\">` — an in-frame field surface (§25.1).\n\nA standalone field sized to its container that renders *one* force, with its own\nlightweight particle pool, its own pointer interaction, and a lifecycle that pauses\nwhen off-screen. It is **not** the §-engine: it's a lighter \"demo/poster\" engine,\ncompletely separate from the page `<field-root>` and the core field loop.\n\n- `ResizeObserver` re-fits the canvas (DPR-aware) and rebuilds the pool.\n- `IntersectionObserver` gates the rAF loop — paused when off-screen.\n- Honours `prefers-reduced-motion`: renders one static frame, no animation.\n\n**Budgets & isolation (shadow-dom.md §31.19).** Each cell owns its *own* pool, so\nmany cells on a docs page never share or starve one budget. Hard caps keep that\nbudget cheap: `max-particles` clamps the pool ceiling (over both the auto-size and an\nexplicit `count`), and `fps` throttles the animation loop to a target framerate. Both\ncaps are enforced per instance — a saturating cell cannot spill particles or frame\ncost into a neighbour.",
88
88
  "name": "FieldCell",
89
89
  "members": [
90
90
  {
@@ -177,6 +177,16 @@
177
177
  "privacy": "private",
178
178
  "default": "null"
179
179
  },
180
+ {
181
+ "kind": "field",
182
+ "name": "lastStepTs",
183
+ "type": {
184
+ "text": "number"
185
+ },
186
+ "privacy": "private",
187
+ "default": "0",
188
+ "description": "rAF timestamp of the last rendered frame — drives the `fps` throttle (§31.19)."
189
+ },
180
190
  {
181
191
  "kind": "field",
182
192
  "name": "onPointerMove",
@@ -199,7 +209,7 @@
199
209
  "kind": "field",
200
210
  "name": "tick",
201
211
  "type": {
202
- "text": "() => void"
212
+ "text": "(ts?: number) => void"
203
213
  },
204
214
  "privacy": "private",
205
215
  "readonly": true
@@ -231,6 +241,24 @@
231
241
  "description": "particle count; `0` (default) means auto-size to the frame area.",
232
242
  "readonly": true
233
243
  },
244
+ {
245
+ "kind": "field",
246
+ "name": "maxParticles",
247
+ "type": {
248
+ "text": "number"
249
+ },
250
+ "description": "Hard ceiling on the pool size (§31.19 scoped local-cell budget); `0` (default) means\nno cap. Clamps *both* the auto-size and an explicit `count`, so a cell can never\nexceed its declared budget no matter how large its frame grows.",
251
+ "readonly": true
252
+ },
253
+ {
254
+ "kind": "field",
255
+ "name": "fps",
256
+ "type": {
257
+ "text": "number"
258
+ },
259
+ "description": "Target frames per second for the animation loop (§31.19); `0` (default) means run at\nthe display's native rAF cadence. A positive value throttles the loop so a page full\nof demo cells stays cheap — each cell keeps its own frame budget.",
260
+ "readonly": true
261
+ },
234
262
  {
235
263
  "kind": "method",
236
264
  "name": "isPrefersReducedMotion",
@@ -241,6 +269,36 @@
241
269
  }
242
270
  }
243
271
  },
272
+ {
273
+ "kind": "method",
274
+ "name": "rafNow",
275
+ "privacy": "private",
276
+ "return": {
277
+ "type": {
278
+ "text": "number"
279
+ }
280
+ },
281
+ "description": "A monotonic timestamp for the fps throttle, in ms (rAF-timestamp compatible)."
282
+ },
283
+ {
284
+ "kind": "method",
285
+ "name": "shouldRenderFrame",
286
+ "privacy": "private",
287
+ "return": {
288
+ "type": {
289
+ "text": "boolean"
290
+ }
291
+ },
292
+ "parameters": [
293
+ {
294
+ "name": "now",
295
+ "type": {
296
+ "text": "number"
297
+ }
298
+ }
299
+ ],
300
+ "description": "The per-cell frame-budget gate (§31.19). With no `fps` (0), every frame renders. With a\npositive `fps`, a frame renders only once its `1000/fps` ms interval has elapsed since the\nlast render; renders advance `lastStepTs`. Each cell keeps its own budget — one cell's rate\nnever affects another's."
301
+ },
244
302
  {
245
303
  "kind": "method",
246
304
  "name": "fit",
@@ -261,7 +319,7 @@
261
319
  "text": "void"
262
320
  }
263
321
  },
264
- "description": "Build the particle pool sized to the frame area."
322
+ "description": "Build the particle pool sized to the frame area, capped by the cell's budget (§31.19)."
265
323
  },
266
324
  {
267
325
  "kind": "method",
@@ -320,6 +378,20 @@
320
378
  "text": "number"
321
379
  },
322
380
  "description": "Number of particles in the cell's pool."
381
+ },
382
+ {
383
+ "name": "max-particles",
384
+ "type": {
385
+ "text": "number"
386
+ },
387
+ "description": "Hard ceiling on the pool size (§31.19); caps both the auto-size and an explicit `count`."
388
+ },
389
+ {
390
+ "name": "fps",
391
+ "type": {
392
+ "text": "number"
393
+ },
394
+ "description": "Target frames per second for the animation loop (§31.19); throttles rAF so many cells stay cheap."
323
395
  }
324
396
  ],
325
397
  "superclass": {
@@ -368,7 +440,7 @@
368
440
  "privacy": "private",
369
441
  "static": true,
370
442
  "readonly": true,
371
- "default": "[ { key: 'density', attr: 'density', read: (el) => el.density }, { key: 'waves', attr: 'waves', read: (el) => el.waves }, { key: 'depth', attr: 'depth', read: (el) => el.depth }, { key: 'background', attr: 'background', read: (el) => el.background }, { key: 'render', attr: 'render', read: (el) => el.renderMode }, { key: 'overlay', attr: 'overlay', read: (el) => el.overlay }, { key: 'palette', attr: 'palette', read: (el) => el.palette }, { key: 'mass', attr: 'mass', read: (el) => el.mass }, { key: 'attention', attr: 'attention', read: (el) => el.attention }, { key: 'causality', attr: 'causality', read: (el) => el.causality }, { key: 'heatmap', attr: 'heatmap', read: (el) => el.heatmap }, { key: 'dprCap', attr: 'dpr-cap', read: (el) => el.dprCap }, { key: 'gridWarp', attr: 'grid-warp', read: (el) => el.gridWarp }, { key: 'gridIntensity', attr: 'grid-intensity', read: (el) => el.gridIntensity }, { key: 'theme', attr: 'theme', read: (el) => el.theme }, { key: 'gradientCool', attr: 'gradient-cool', read: (el) => el.gradientCool }, { key: 'gradientWarm', attr: 'gradient-warm', read: (el) => el.gradientWarm }, { key: 'waveBaseline', attr: 'wave-baseline', read: (el) => el.waveBaseline }, { key: 'waveStyle', attr: 'wave-style', read: (el) => el.waveStyle }, { key: 'waveCenter', attr: 'wave-center', read: (el) => el.waveCenter }, { key: 'separation', attr: 'separation', read: (el) => el.separation }, ]",
443
+ "default": "[ { key: 'density', attr: 'density', read: (el) => el.density }, { key: 'waves', attr: 'waves', read: (el) => el.waves }, { key: 'depth', attr: 'depth', read: (el) => el.depth }, { key: 'background', attr: 'background', read: (el) => el.background }, { key: 'render', attr: 'render', read: (el) => el.renderMode }, { key: 'overlay', attr: 'overlay', read: (el) => el.overlay }, { key: 'palette', attr: 'palette', read: (el) => el.palette }, { key: 'mass', attr: 'mass', read: (el) => el.mass }, { key: 'attention', attr: 'attention', read: (el) => el.attention }, { key: 'causality', attr: 'causality', read: (el) => el.causality }, { key: 'heatmap', attr: 'heatmap', read: (el) => el.heatmap }, { key: 'dprCap', attr: 'dpr-cap', read: (el) => el.dprCap }, { key: 'gridWarp', attr: 'grid-warp', read: (el) => el.gridWarp }, { key: 'gridIntensity', attr: 'grid-intensity', read: (el) => el.gridIntensity }, { key: 'theme', attr: 'theme', read: (el) => el.theme }, { key: 'gradientCool', attr: 'gradient-cool', read: (el) => el.gradientCool }, { key: 'gradientWarm', attr: 'gradient-warm', read: (el) => el.gradientWarm }, { key: 'waveBaseline', attr: 'wave-baseline', read: (el) => el.waveBaseline }, { key: 'waveStyle', attr: 'wave-style', read: (el) => el.waveStyle }, { key: 'waveCenter', attr: 'wave-center', read: (el) => el.waveCenter }, { key: 'separation', attr: 'separation', read: (el) => el.separation }, { key: 'ambientOrbit', attr: 'ambient-orbit', read: (el) => el.ambientOrbit }, { key: 'ambientWander', attr: 'ambient-wander', read: (el) => el.ambientWander }, { key: 'integrator', attr: 'integrator', read: (el) => el.integrator }, ]",
372
444
  "description": "The engine options `<field-root>` forwards to `createBrowserField`, as ONE declarative table —\nthe single source of truth for the option object built in `start()`, so a new forwarded\n`FieldOption` can never be silently dropped from forwarding the way `depth` once was. `accent`\n(raw passthrough so a `palette` with no `accent` adopts the palette stop) and\n`overlayCanvas`/`feedbackSink` (managed internally) are special-cased in `start()` and absent here.\n\n`observedAttributes` stays an explicit literal below — the Custom-Elements-Manifest analyzer reads\nit statically and can't enumerate a computed array — but the `option-attrs-observed` test pins it\nto this table (every `attr` here must be observed), so the two lists can't drift apart."
373
445
  },
374
446
  {
@@ -425,6 +497,16 @@
425
497
  "privacy": "private",
426
498
  "default": "true"
427
499
  },
500
+ {
501
+ "kind": "field",
502
+ "name": "fieldActiveMarked",
503
+ "type": {
504
+ "text": "boolean"
505
+ },
506
+ "privacy": "private",
507
+ "default": "false",
508
+ "description": "SSR pre-registration queue bookkeeping: true while this element counts as a live field, so a\nrebuild (start() after a destroy) does not double-count the active-field tally (#683)."
509
+ },
428
510
  {
429
511
  "kind": "field",
430
512
  "name": "platformRuntime",
@@ -466,14 +548,14 @@
466
548
  "type": {
467
549
  "text": "boolean"
468
550
  },
469
- "description": "draw the background Currents (§24).",
551
+ "description": "draw the background Currents (§24). OPT-IN (#979, mirrors the core default): the attribute\nmust be PRESENT (and not `\"false\"`) to build the waves — same semantics as `attention` /\n`causality` / `mass`. Absent = the bare field, no carrier waves.",
470
552
  "readonly": true
471
553
  },
472
554
  {
473
555
  "kind": "field",
474
556
  "name": "renderMode",
475
557
  "type": {
476
- "text": "'dots' | 'trails' | 'links' | 'metaballs' | 'voronoi' | 'streamlines' | 'flow' | 'none'"
558
+ "text": "| 'dots'\n | 'trails'\n | 'links'\n | 'metaballs'\n | 'voronoi'\n | 'streamlines'\n | 'flow'\n | 'knockout'\n | 'redshift'\n | 'blackbody'\n | 'depth'\n | 'none'"
477
559
  },
478
560
  "description": "render mode (§20.6); the DEFAULT is `none` (#538) — the signals-only engine: simulate + feed back,\nnever draw (#297). Set `render=\"dots\"` (or another drawing mode) to get a visible surface.",
479
561
  "readonly": true
@@ -586,6 +668,33 @@
586
668
  "description": "`separation` — particle-to-particle separation force strength ∈ [0,1]; undefined if absent/invalid.",
587
669
  "readonly": true
588
670
  },
671
+ {
672
+ "kind": "field",
673
+ "name": "ambientOrbit",
674
+ "type": {
675
+ "text": "number | undefined"
676
+ },
677
+ "description": "`ambient-orbit` — DECLARED resting-formation swirl on attract (#978); undefined (engine default\n0.1, the historical hardcoded value) if absent/invalid. `0` is valid (a purely radial attract).",
678
+ "readonly": true
679
+ },
680
+ {
681
+ "kind": "field",
682
+ "name": "ambientWander",
683
+ "type": {
684
+ "text": "number | undefined"
685
+ },
686
+ "description": "`ambient-wander` — DECLARED resting-formation drift (#978); undefined (engine default 1.0, the\nhistorical hardcoded value) if absent/invalid. `0` is valid (a still resting field).",
687
+ "readonly": true
688
+ },
689
+ {
690
+ "kind": "field",
691
+ "name": "integrator",
692
+ "type": {
693
+ "text": "IntegratorMode | undefined"
694
+ },
695
+ "description": "`integrator` — the integration scheme (substrate doc 04 §Step 3); `'fixed'` opts into the\nframe-rate-independent integrator, `'velocity-verlet'` into the second-order Verlet scheme\n(#659); anything else (incl. absent) is the default `'legacy'`.",
696
+ "readonly": true
697
+ },
589
698
  {
590
699
  "kind": "field",
591
700
  "name": "theme",
@@ -931,7 +1040,7 @@
931
1040
  {
932
1041
  "name": "mode",
933
1042
  "type": {
934
- "text": "'dots' | 'trails' | 'links' | 'metaballs' | 'voronoi' | 'streamlines' | 'flow' | 'none'"
1043
+ "text": "| 'dots'\n | 'trails'\n | 'links'\n | 'metaballs'\n | 'voronoi'\n | 'streamlines'\n | 'flow'\n | 'knockout'\n | 'redshift'\n | 'blackbody'\n | 'depth'\n | 'none'"
935
1044
  }
936
1045
  }
937
1046
  ],
@@ -1267,6 +1376,108 @@
1267
1376
  },
1268
1377
  "description": "kinetic/thermal/total energy snapshot for the current frame."
1269
1378
  },
1379
+ {
1380
+ "kind": "method",
1381
+ "name": "query",
1382
+ "return": {
1383
+ "type": {
1384
+ "text": "FieldQueryResult"
1385
+ }
1386
+ },
1387
+ "parameters": [
1388
+ {
1389
+ "name": "q",
1390
+ "optional": true,
1391
+ "type": {
1392
+ "text": "FieldQuery"
1393
+ }
1394
+ }
1395
+ ],
1396
+ "description": "Ask the live field a structured question (bodies/metrics/relationships/influences) — read-only.\nReturns an empty reading before the field starts. See FieldHandle.query. EXPERIMENTAL."
1397
+ },
1398
+ {
1399
+ "kind": "method",
1400
+ "name": "snapshot",
1401
+ "return": {
1402
+ "type": {
1403
+ "text": "FieldSnapshot"
1404
+ }
1405
+ },
1406
+ "parameters": [
1407
+ {
1408
+ "name": "opts",
1409
+ "optional": true,
1410
+ "type": {
1411
+ "text": "FieldSnapshotOptions"
1412
+ }
1413
+ }
1414
+ ],
1415
+ "description": "Capture field state — a portable, versioned FieldSnapshot. Empty before start. EXPERIMENTAL."
1416
+ },
1417
+ {
1418
+ "kind": "method",
1419
+ "name": "diff",
1420
+ "return": {
1421
+ "type": {
1422
+ "text": "FieldDiff"
1423
+ }
1424
+ },
1425
+ "parameters": [
1426
+ {
1427
+ "name": "a",
1428
+ "type": {
1429
+ "text": "FieldSnapshot"
1430
+ }
1431
+ },
1432
+ {
1433
+ "name": "b",
1434
+ "type": {
1435
+ "text": "FieldSnapshot"
1436
+ }
1437
+ }
1438
+ ],
1439
+ "description": "Compare two snapshots — pure (works before the field starts). See FieldHandle.diff. EXPERIMENTAL."
1440
+ },
1441
+ {
1442
+ "kind": "method",
1443
+ "name": "replay",
1444
+ "return": {
1445
+ "type": {
1446
+ "text": "CausalReplay"
1447
+ }
1448
+ },
1449
+ "parameters": [
1450
+ {
1451
+ "name": "a",
1452
+ "type": {
1453
+ "text": "FieldSnapshot"
1454
+ }
1455
+ },
1456
+ {
1457
+ "name": "b",
1458
+ "type": {
1459
+ "text": "FieldSnapshot"
1460
+ }
1461
+ },
1462
+ {
1463
+ "name": "opts",
1464
+ "optional": true,
1465
+ "type": {
1466
+ "text": "ReplayOptions"
1467
+ }
1468
+ }
1469
+ ],
1470
+ "description": "Explain how the field changed between two snapshots — pure (works before start). See FieldHandle.replay. EXPERIMENTAL."
1471
+ },
1472
+ {
1473
+ "kind": "field",
1474
+ "name": "projections",
1475
+ "type": {
1476
+ "text": "ProjectionRegistry"
1477
+ },
1478
+ "description": "The field's projection registry — a no-op registry before the field starts. See FieldHandle.projections. EXPERIMENTAL.",
1479
+ "readonly": true
1480
+ },
1270
1481
  {
1271
1482
  "kind": "method",
1272
1483
  "name": "sample",
@@ -1418,6 +1629,17 @@
1418
1629
  ],
1419
1630
  "description": "pause/resume drawing (the simulation keeps running) — the element also does this automatically\nfrom its IntersectionObserver, so a manual call is for explicit control."
1420
1631
  },
1632
+ {
1633
+ "kind": "method",
1634
+ "name": "ensureOverlayCanvas",
1635
+ "privacy": "private",
1636
+ "return": {
1637
+ "type": {
1638
+ "text": "HTMLCanvasElement | null"
1639
+ }
1640
+ },
1641
+ "description": "Field Surfaces: lazily create + attach the front overlay surface (light DOM — the shadow host is\nz-index:0, behind content). A fixed, full-viewport, click-through, mix-blend canvas above content;\ncore sizes its backing store and draws the overlay mode onto it. Created ONCE, on the first overlay\nthat actually goes active (#676) — core invokes this as `overlayCanvasProvider` — and reused across\nrebuilds. Idempotent: returns the existing canvas on every later call, never a second element."
1642
+ },
1421
1643
  {
1422
1644
  "kind": "method",
1423
1645
  "name": "start",
@@ -1498,6 +1720,15 @@
1498
1720
  {
1499
1721
  "name": "separation"
1500
1722
  },
1723
+ {
1724
+ "name": "ambient-orbit"
1725
+ },
1726
+ {
1727
+ "name": "ambient-wander"
1728
+ },
1729
+ {
1730
+ "name": "integrator"
1731
+ },
1501
1732
  {
1502
1733
  "name": "background"
1503
1734
  },
@@ -1677,6 +1908,27 @@
1677
1908
  "module": "src/index.ts"
1678
1909
  }
1679
1910
  },
1911
+ {
1912
+ "name": "ambient-orbit",
1913
+ "inheritedFrom": {
1914
+ "name": "FieldField",
1915
+ "module": "src/index.ts"
1916
+ }
1917
+ },
1918
+ {
1919
+ "name": "ambient-wander",
1920
+ "inheritedFrom": {
1921
+ "name": "FieldField",
1922
+ "module": "src/index.ts"
1923
+ }
1924
+ },
1925
+ {
1926
+ "name": "integrator",
1927
+ "inheritedFrom": {
1928
+ "name": "FieldField",
1929
+ "module": "src/index.ts"
1930
+ }
1931
+ },
1680
1932
  {
1681
1933
  "name": "background",
1682
1934
  "inheritedFrom": {
@@ -1702,7 +1954,7 @@
1702
1954
  "privacy": "private",
1703
1955
  "static": true,
1704
1956
  "readonly": true,
1705
- "default": "[ { key: 'density', attr: 'density', read: (el) => el.density }, { key: 'waves', attr: 'waves', read: (el) => el.waves }, { key: 'depth', attr: 'depth', read: (el) => el.depth }, { key: 'background', attr: 'background', read: (el) => el.background }, { key: 'render', attr: 'render', read: (el) => el.renderMode }, { key: 'overlay', attr: 'overlay', read: (el) => el.overlay }, { key: 'palette', attr: 'palette', read: (el) => el.palette }, { key: 'mass', attr: 'mass', read: (el) => el.mass }, { key: 'attention', attr: 'attention', read: (el) => el.attention }, { key: 'causality', attr: 'causality', read: (el) => el.causality }, { key: 'heatmap', attr: 'heatmap', read: (el) => el.heatmap }, { key: 'dprCap', attr: 'dpr-cap', read: (el) => el.dprCap }, { key: 'gridWarp', attr: 'grid-warp', read: (el) => el.gridWarp }, { key: 'gridIntensity', attr: 'grid-intensity', read: (el) => el.gridIntensity }, { key: 'theme', attr: 'theme', read: (el) => el.theme }, { key: 'gradientCool', attr: 'gradient-cool', read: (el) => el.gradientCool }, { key: 'gradientWarm', attr: 'gradient-warm', read: (el) => el.gradientWarm }, { key: 'waveBaseline', attr: 'wave-baseline', read: (el) => el.waveBaseline }, { key: 'waveStyle', attr: 'wave-style', read: (el) => el.waveStyle }, { key: 'waveCenter', attr: 'wave-center', read: (el) => el.waveCenter }, { key: 'separation', attr: 'separation', read: (el) => el.separation }, ]",
1957
+ "default": "[ { key: 'density', attr: 'density', read: (el) => el.density }, { key: 'waves', attr: 'waves', read: (el) => el.waves }, { key: 'depth', attr: 'depth', read: (el) => el.depth }, { key: 'background', attr: 'background', read: (el) => el.background }, { key: 'render', attr: 'render', read: (el) => el.renderMode }, { key: 'overlay', attr: 'overlay', read: (el) => el.overlay }, { key: 'palette', attr: 'palette', read: (el) => el.palette }, { key: 'mass', attr: 'mass', read: (el) => el.mass }, { key: 'attention', attr: 'attention', read: (el) => el.attention }, { key: 'causality', attr: 'causality', read: (el) => el.causality }, { key: 'heatmap', attr: 'heatmap', read: (el) => el.heatmap }, { key: 'dprCap', attr: 'dpr-cap', read: (el) => el.dprCap }, { key: 'gridWarp', attr: 'grid-warp', read: (el) => el.gridWarp }, { key: 'gridIntensity', attr: 'grid-intensity', read: (el) => el.gridIntensity }, { key: 'theme', attr: 'theme', read: (el) => el.theme }, { key: 'gradientCool', attr: 'gradient-cool', read: (el) => el.gradientCool }, { key: 'gradientWarm', attr: 'gradient-warm', read: (el) => el.gradientWarm }, { key: 'waveBaseline', attr: 'wave-baseline', read: (el) => el.waveBaseline }, { key: 'waveStyle', attr: 'wave-style', read: (el) => el.waveStyle }, { key: 'waveCenter', attr: 'wave-center', read: (el) => el.waveCenter }, { key: 'separation', attr: 'separation', read: (el) => el.separation }, { key: 'ambientOrbit', attr: 'ambient-orbit', read: (el) => el.ambientOrbit }, { key: 'ambientWander', attr: 'ambient-wander', read: (el) => el.ambientWander }, { key: 'integrator', attr: 'integrator', read: (el) => el.integrator }, ]",
1706
1958
  "description": "The engine options `<field-root>` forwards to `createBrowserField`, as ONE declarative table —\nthe single source of truth for the option object built in `start()`, so a new forwarded\n`FieldOption` can never be silently dropped from forwarding the way `depth` once was. `accent`\n(raw passthrough so a `palette` with no `accent` adopts the palette stop) and\n`overlayCanvas`/`feedbackSink` (managed internally) are special-cased in `start()` and absent here.\n\n`observedAttributes` stays an explicit literal below — the Custom-Elements-Manifest analyzer reads\nit statically and can't enumerate a computed array — but the `option-attrs-observed` test pins it\nto this table (every `attr` here must be observed), so the two lists can't drift apart.",
1707
1959
  "inheritedFrom": {
1708
1960
  "name": "FieldField",
@@ -1787,6 +2039,20 @@
1787
2039
  "module": "src/index.ts"
1788
2040
  }
1789
2041
  },
2042
+ {
2043
+ "kind": "field",
2044
+ "name": "fieldActiveMarked",
2045
+ "type": {
2046
+ "text": "boolean"
2047
+ },
2048
+ "privacy": "private",
2049
+ "default": "false",
2050
+ "description": "SSR pre-registration queue bookkeeping: true while this element counts as a live field, so a\nrebuild (start() after a destroy) does not double-count the active-field tally (#683).",
2051
+ "inheritedFrom": {
2052
+ "name": "FieldField",
2053
+ "module": "src/index.ts"
2054
+ }
2055
+ },
1790
2056
  {
1791
2057
  "kind": "field",
1792
2058
  "name": "platformRuntime",
@@ -1844,7 +2110,7 @@
1844
2110
  "type": {
1845
2111
  "text": "boolean"
1846
2112
  },
1847
- "description": "draw the background Currents (§24).",
2113
+ "description": "draw the background Currents (§24). OPT-IN (#979, mirrors the core default): the attribute\nmust be PRESENT (and not `\"false\"`) to build the waves — same semantics as `attention` /\n`causality` / `mass`. Absent = the bare field, no carrier waves.",
1848
2114
  "readonly": true,
1849
2115
  "inheritedFrom": {
1850
2116
  "name": "FieldField",
@@ -1855,7 +2121,7 @@
1855
2121
  "kind": "field",
1856
2122
  "name": "renderMode",
1857
2123
  "type": {
1858
- "text": "'dots' | 'trails' | 'links' | 'metaballs' | 'voronoi' | 'streamlines' | 'flow' | 'none'"
2124
+ "text": "| 'dots'\n | 'trails'\n | 'links'\n | 'metaballs'\n | 'voronoi'\n | 'streamlines'\n | 'flow'\n | 'knockout'\n | 'redshift'\n | 'blackbody'\n | 'depth'\n | 'none'"
1859
2125
  },
1860
2126
  "description": "render mode (§20.6); the DEFAULT is `none` (#538) — the signals-only engine: simulate + feed back,\nnever draw (#297). Set `render=\"dots\"` (or another drawing mode) to get a visible surface.",
1861
2127
  "readonly": true,
@@ -2020,6 +2286,45 @@
2020
2286
  "module": "src/index.ts"
2021
2287
  }
2022
2288
  },
2289
+ {
2290
+ "kind": "field",
2291
+ "name": "ambientOrbit",
2292
+ "type": {
2293
+ "text": "number | undefined"
2294
+ },
2295
+ "description": "`ambient-orbit` — DECLARED resting-formation swirl on attract (#978); undefined (engine default\n0.1, the historical hardcoded value) if absent/invalid. `0` is valid (a purely radial attract).",
2296
+ "readonly": true,
2297
+ "inheritedFrom": {
2298
+ "name": "FieldField",
2299
+ "module": "src/index.ts"
2300
+ }
2301
+ },
2302
+ {
2303
+ "kind": "field",
2304
+ "name": "ambientWander",
2305
+ "type": {
2306
+ "text": "number | undefined"
2307
+ },
2308
+ "description": "`ambient-wander` — DECLARED resting-formation drift (#978); undefined (engine default 1.0, the\nhistorical hardcoded value) if absent/invalid. `0` is valid (a still resting field).",
2309
+ "readonly": true,
2310
+ "inheritedFrom": {
2311
+ "name": "FieldField",
2312
+ "module": "src/index.ts"
2313
+ }
2314
+ },
2315
+ {
2316
+ "kind": "field",
2317
+ "name": "integrator",
2318
+ "type": {
2319
+ "text": "IntegratorMode | undefined"
2320
+ },
2321
+ "description": "`integrator` — the integration scheme (substrate doc 04 §Step 3); `'fixed'` opts into the\nframe-rate-independent integrator, `'velocity-verlet'` into the second-order Verlet scheme\n(#659); anything else (incl. absent) is the default `'legacy'`.",
2322
+ "readonly": true,
2323
+ "inheritedFrom": {
2324
+ "name": "FieldField",
2325
+ "module": "src/index.ts"
2326
+ }
2327
+ },
2023
2328
  {
2024
2329
  "kind": "field",
2025
2330
  "name": "theme",
@@ -2457,7 +2762,7 @@
2457
2762
  {
2458
2763
  "name": "mode",
2459
2764
  "type": {
2460
- "text": "'dots' | 'trails' | 'links' | 'metaballs' | 'voronoi' | 'streamlines' | 'flow' | 'none'"
2765
+ "text": "| 'dots'\n | 'trails'\n | 'links'\n | 'metaballs'\n | 'voronoi'\n | 'streamlines'\n | 'flow'\n | 'knockout'\n | 'redshift'\n | 'blackbody'\n | 'depth'\n | 'none'"
2461
2766
  }
2462
2767
  }
2463
2768
  ],
@@ -2865,6 +3170,128 @@
2865
3170
  "module": "src/index.ts"
2866
3171
  }
2867
3172
  },
3173
+ {
3174
+ "kind": "method",
3175
+ "name": "query",
3176
+ "return": {
3177
+ "type": {
3178
+ "text": "FieldQueryResult"
3179
+ }
3180
+ },
3181
+ "parameters": [
3182
+ {
3183
+ "name": "q",
3184
+ "optional": true,
3185
+ "type": {
3186
+ "text": "FieldQuery"
3187
+ }
3188
+ }
3189
+ ],
3190
+ "description": "Ask the live field a structured question (bodies/metrics/relationships/influences) — read-only.\nReturns an empty reading before the field starts. See FieldHandle.query. EXPERIMENTAL.",
3191
+ "inheritedFrom": {
3192
+ "name": "FieldField",
3193
+ "module": "src/index.ts"
3194
+ }
3195
+ },
3196
+ {
3197
+ "kind": "method",
3198
+ "name": "snapshot",
3199
+ "return": {
3200
+ "type": {
3201
+ "text": "FieldSnapshot"
3202
+ }
3203
+ },
3204
+ "parameters": [
3205
+ {
3206
+ "name": "opts",
3207
+ "optional": true,
3208
+ "type": {
3209
+ "text": "FieldSnapshotOptions"
3210
+ }
3211
+ }
3212
+ ],
3213
+ "description": "Capture field state — a portable, versioned FieldSnapshot. Empty before start. EXPERIMENTAL.",
3214
+ "inheritedFrom": {
3215
+ "name": "FieldField",
3216
+ "module": "src/index.ts"
3217
+ }
3218
+ },
3219
+ {
3220
+ "kind": "method",
3221
+ "name": "diff",
3222
+ "return": {
3223
+ "type": {
3224
+ "text": "FieldDiff"
3225
+ }
3226
+ },
3227
+ "parameters": [
3228
+ {
3229
+ "name": "a",
3230
+ "type": {
3231
+ "text": "FieldSnapshot"
3232
+ }
3233
+ },
3234
+ {
3235
+ "name": "b",
3236
+ "type": {
3237
+ "text": "FieldSnapshot"
3238
+ }
3239
+ }
3240
+ ],
3241
+ "description": "Compare two snapshots — pure (works before the field starts). See FieldHandle.diff. EXPERIMENTAL.",
3242
+ "inheritedFrom": {
3243
+ "name": "FieldField",
3244
+ "module": "src/index.ts"
3245
+ }
3246
+ },
3247
+ {
3248
+ "kind": "method",
3249
+ "name": "replay",
3250
+ "return": {
3251
+ "type": {
3252
+ "text": "CausalReplay"
3253
+ }
3254
+ },
3255
+ "parameters": [
3256
+ {
3257
+ "name": "a",
3258
+ "type": {
3259
+ "text": "FieldSnapshot"
3260
+ }
3261
+ },
3262
+ {
3263
+ "name": "b",
3264
+ "type": {
3265
+ "text": "FieldSnapshot"
3266
+ }
3267
+ },
3268
+ {
3269
+ "name": "opts",
3270
+ "optional": true,
3271
+ "type": {
3272
+ "text": "ReplayOptions"
3273
+ }
3274
+ }
3275
+ ],
3276
+ "description": "Explain how the field changed between two snapshots — pure (works before start). See FieldHandle.replay. EXPERIMENTAL.",
3277
+ "inheritedFrom": {
3278
+ "name": "FieldField",
3279
+ "module": "src/index.ts"
3280
+ }
3281
+ },
3282
+ {
3283
+ "kind": "field",
3284
+ "name": "projections",
3285
+ "type": {
3286
+ "text": "ProjectionRegistry"
3287
+ },
3288
+ "description": "The field's projection registry — a no-op registry before the field starts. See FieldHandle.projections. EXPERIMENTAL.",
3289
+ "readonly": true,
3290
+ "inheritedFrom": {
3291
+ "name": "FieldField",
3292
+ "module": "src/index.ts"
3293
+ }
3294
+ },
2868
3295
  {
2869
3296
  "kind": "method",
2870
3297
  "name": "sample",
@@ -3048,6 +3475,21 @@
3048
3475
  "module": "src/index.ts"
3049
3476
  }
3050
3477
  },
3478
+ {
3479
+ "kind": "method",
3480
+ "name": "ensureOverlayCanvas",
3481
+ "privacy": "private",
3482
+ "return": {
3483
+ "type": {
3484
+ "text": "HTMLCanvasElement | null"
3485
+ }
3486
+ },
3487
+ "description": "Field Surfaces: lazily create + attach the front overlay surface (light DOM — the shadow host is\nz-index:0, behind content). A fixed, full-viewport, click-through, mix-blend canvas above content;\ncore sizes its backing store and draws the overlay mode onto it. Created ONCE, on the first overlay\nthat actually goes active (#676) — core invokes this as `overlayCanvasProvider` — and reused across\nrebuilds. Idempotent: returns the existing canvas on every later call, never a second element.",
3488
+ "inheritedFrom": {
3489
+ "name": "FieldField",
3490
+ "module": "src/index.ts"
3491
+ }
3492
+ },
3051
3493
  {
3052
3494
  "kind": "method",
3053
3495
  "name": "start",
@@ -3501,6 +3943,140 @@
3501
3943
  }
3502
3944
  }
3503
3945
  ]
3946
+ },
3947
+ {
3948
+ "kind": "javascript-module",
3949
+ "path": "src/preregistration-queue.ts",
3950
+ "declarations": [
3951
+ {
3952
+ "kind": "function",
3953
+ "name": "installPreRegistrationQueue",
3954
+ "return": {
3955
+ "type": {
3956
+ "text": "void"
3957
+ }
3958
+ },
3959
+ "description": "Install the capturing document listeners — idempotent, SSR-guarded. Called from the custom\nelement's constructor so it runs on the client before the element upgrades its peers, and never on\nthe server (no `document`). Capturing (`{ capture: true }`) so the queue sees the event on the way\ndown, independent of any later-added bubble-phase field listener."
3960
+ },
3961
+ {
3962
+ "kind": "function",
3963
+ "name": "markFieldActive",
3964
+ "return": {
3965
+ "type": {
3966
+ "text": "void"
3967
+ }
3968
+ },
3969
+ "description": "Mark that a field has become live. The first live field is what makes subsequent registration\nevents skip the queue and reach the field directly. Paired with markFieldInactive."
3970
+ },
3971
+ {
3972
+ "kind": "function",
3973
+ "name": "markFieldInactive",
3974
+ "return": {
3975
+ "type": {
3976
+ "text": "void"
3977
+ }
3978
+ },
3979
+ "description": "Mark that a live field has torn down. When the last field goes away the queue resumes buffering, so\nan element that (re)connects during a field-less window is captured for the next field that boots."
3980
+ },
3981
+ {
3982
+ "kind": "function",
3983
+ "name": "flushPreRegistrationQueue",
3984
+ "return": {
3985
+ "type": {
3986
+ "text": "void"
3987
+ }
3988
+ },
3989
+ "description": "Replay every buffered registration event on its source element, then clear the buffer. Called by a\nfield immediately after it wires its body-event listeners, so the events bubble (composed) to the\ndocument and the field registers them through its normal, idempotent path. Safe to call with an\nempty queue (the common client-only case) — it does nothing."
3990
+ },
3991
+ {
3992
+ "kind": "function",
3993
+ "name": "pendingRegistrationCount",
3994
+ "return": {
3995
+ "type": {
3996
+ "text": "number"
3997
+ }
3998
+ },
3999
+ "description": "Test-only: the number of events currently buffered (0 once drained)."
4000
+ },
4001
+ {
4002
+ "kind": "function",
4003
+ "name": "resetPreRegistrationQueue",
4004
+ "return": {
4005
+ "type": {
4006
+ "text": "void"
4007
+ }
4008
+ },
4009
+ "description": "Test-only: reset all module state (queue, active-field count, install flag) between tests."
4010
+ },
4011
+ {
4012
+ "kind": "function",
4013
+ "name": "isBuffering",
4014
+ "return": {
4015
+ "type": {
4016
+ "text": "boolean"
4017
+ }
4018
+ },
4019
+ "description": "Whether the queue is currently buffering (no field live). Test/introspection helper."
4020
+ }
4021
+ ],
4022
+ "exports": [
4023
+ {
4024
+ "kind": "js",
4025
+ "name": "installPreRegistrationQueue",
4026
+ "declaration": {
4027
+ "name": "installPreRegistrationQueue",
4028
+ "module": "src/preregistration-queue.ts"
4029
+ }
4030
+ },
4031
+ {
4032
+ "kind": "js",
4033
+ "name": "markFieldActive",
4034
+ "declaration": {
4035
+ "name": "markFieldActive",
4036
+ "module": "src/preregistration-queue.ts"
4037
+ }
4038
+ },
4039
+ {
4040
+ "kind": "js",
4041
+ "name": "markFieldInactive",
4042
+ "declaration": {
4043
+ "name": "markFieldInactive",
4044
+ "module": "src/preregistration-queue.ts"
4045
+ }
4046
+ },
4047
+ {
4048
+ "kind": "js",
4049
+ "name": "flushPreRegistrationQueue",
4050
+ "declaration": {
4051
+ "name": "flushPreRegistrationQueue",
4052
+ "module": "src/preregistration-queue.ts"
4053
+ }
4054
+ },
4055
+ {
4056
+ "kind": "js",
4057
+ "name": "pendingRegistrationCount",
4058
+ "declaration": {
4059
+ "name": "pendingRegistrationCount",
4060
+ "module": "src/preregistration-queue.ts"
4061
+ }
4062
+ },
4063
+ {
4064
+ "kind": "js",
4065
+ "name": "resetPreRegistrationQueue",
4066
+ "declaration": {
4067
+ "name": "resetPreRegistrationQueue",
4068
+ "module": "src/preregistration-queue.ts"
4069
+ }
4070
+ },
4071
+ {
4072
+ "kind": "js",
4073
+ "name": "isBuffering",
4074
+ "declaration": {
4075
+ "name": "isBuffering",
4076
+ "module": "src/preregistration-queue.ts"
4077
+ }
4078
+ }
4079
+ ]
3504
4080
  }
3505
4081
  ]
3506
4082
  }