@vitreajs/vitrea 0.1.0

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.
package/LICENSE ADDED
@@ -0,0 +1,202 @@
1
+
2
+ Apache License
3
+ Version 2.0, January 2004
4
+ http://www.apache.org/licenses/
5
+
6
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
7
+
8
+ 1. Definitions.
9
+
10
+ "License" shall mean the terms and conditions for use, reproduction,
11
+ and distribution as defined by Sections 1 through 9 of this document.
12
+
13
+ "Licensor" shall mean the copyright owner or entity authorized by
14
+ the copyright owner that is granting the License.
15
+
16
+ "Legal Entity" shall mean the union of the acting entity and all
17
+ other entities that control, are controlled by, or are under common
18
+ control with that entity. For the purposes of this definition,
19
+ "control" means (i) the power, direct or indirect, to cause the
20
+ direction or management of such entity, whether by contract or
21
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
22
+ outstanding shares, or (iii) beneficial ownership of such entity.
23
+
24
+ "You" (or "Your") shall mean an individual or Legal Entity
25
+ exercising permissions granted by this License.
26
+
27
+ "Source" form shall mean the preferred form for making modifications,
28
+ including but not limited to software source code, documentation
29
+ source, and configuration files.
30
+
31
+ "Object" form shall mean any form resulting from mechanical
32
+ transformation or translation of a Source form, including but
33
+ not limited to compiled object code, generated documentation,
34
+ and conversions to other media types.
35
+
36
+ "Work" shall mean the work of authorship, whether in Source or
37
+ Object form, made available under the License, as indicated by a
38
+ copyright notice that is included in or attached to the work
39
+ (an example is provided in the Appendix below).
40
+
41
+ "Derivative Works" shall mean any work, whether in Source or Object
42
+ form, that is based on (or derived from) the Work and for which the
43
+ editorial revisions, annotations, elaborations, or other modifications
44
+ represent, as a whole, an original work of authorship. For the purposes
45
+ of this License, Derivative Works shall not include works that remain
46
+ separable from, or merely link (or bind by name) to the interfaces of,
47
+ the Work and Derivative Works thereof.
48
+
49
+ "Contribution" shall mean any work of authorship, including
50
+ the original version of the Work and any modifications or additions
51
+ to that Work or Derivative Works thereof, that is intentionally
52
+ submitted to Licensor for inclusion in the Work by the copyright owner
53
+ or by an individual or Legal Entity authorized to submit on behalf of
54
+ the copyright owner. For the purposes of this definition, "submitted"
55
+ means any form of electronic, verbal, or written communication sent
56
+ to the Licensor or its representatives, including but not limited to
57
+ communication on electronic mailing lists, source code control systems,
58
+ and issue tracking systems that are managed by, or on behalf of, the
59
+ Licensor for the purpose of discussing and improving the Work, but
60
+ excluding communication that is conspicuously marked or otherwise
61
+ designated in writing by the copyright owner as "Not a Contribution."
62
+
63
+ "Contributor" shall mean Licensor and any individual or Legal Entity
64
+ on behalf of whom a Contribution has been received by Licensor and
65
+ subsequently incorporated within the Work.
66
+
67
+ 2. Grant of Copyright License. Subject to the terms and conditions of
68
+ this License, each Contributor hereby grants to You a perpetual,
69
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
70
+ copyright license to reproduce, prepare Derivative Works of,
71
+ publicly display, publicly perform, sublicense, and distribute the
72
+ Work and such Derivative Works in Source or Object form.
73
+
74
+ 3. Grant of Patent License. Subject to the terms and conditions of
75
+ this License, each Contributor hereby grants to You a perpetual,
76
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
77
+ (except as stated in this section) patent license to make, have made,
78
+ use, offer to sell, sell, import, and otherwise transfer the Work,
79
+ where such license applies only to those patent claims licensable
80
+ by such Contributor that are necessarily infringed by their
81
+ Contribution(s) alone or by combination of their Contribution(s)
82
+ with the Work to which such Contribution(s) was submitted. If You
83
+ institute patent litigation against any entity (including a
84
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
85
+ or a Contribution incorporated within the Work constitutes direct
86
+ or contributory patent infringement, then any patent licenses
87
+ granted to You under this License for that Work shall terminate
88
+ as of the date such litigation is filed.
89
+
90
+ 4. Redistribution. You may reproduce and distribute copies of the
91
+ Work or Derivative Works thereof in any medium, with or without
92
+ modifications, and in Source or Object form, provided that You
93
+ meet the following conditions:
94
+
95
+ (a) You must give any other recipients of the Work or
96
+ Derivative Works a copy of this License; and
97
+
98
+ (b) You must cause any modified files to carry prominent notices
99
+ stating that You changed the files; and
100
+
101
+ (c) You must retain, in the Source form of any Derivative Works
102
+ that You distribute, all copyright, patent, trademark, and
103
+ attribution notices from the Source form of the Work,
104
+ excluding those notices that do not pertain to any part of
105
+ the Derivative Works; and
106
+
107
+ (d) If the Work includes a "NOTICE" text file as part of its
108
+ distribution, then any Derivative Works that You distribute must
109
+ include a readable copy of the attribution notices contained
110
+ within such NOTICE file, excluding those notices that do not
111
+ pertain to any part of the Derivative Works, in at least one
112
+ of the following places: within a NOTICE text file distributed
113
+ as part of the Derivative Works; within the Source form or
114
+ documentation, if provided along with the Derivative Works; or,
115
+ within a display generated by the Derivative Works, if and
116
+ wherever such third-party notices normally appear. The contents
117
+ of the NOTICE file are for informational purposes only and
118
+ do not modify the License. You may add Your own attribution
119
+ notices within Derivative Works that You distribute, alongside
120
+ or as an addendum to the NOTICE text from the Work, provided
121
+ that such additional attribution notices cannot be construed
122
+ as modifying the License.
123
+
124
+ You may add Your own copyright statement to Your modifications and
125
+ may provide additional or different license terms and conditions
126
+ for use, reproduction, or distribution of Your modifications, or
127
+ for any such Derivative Works as a whole, provided Your use,
128
+ reproduction, and distribution of the Work otherwise complies with
129
+ the conditions stated in this License.
130
+
131
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
132
+ any Contribution intentionally submitted for inclusion in the Work
133
+ by You to the Licensor shall be under the terms and conditions of
134
+ this License, without any additional terms or conditions.
135
+ Notwithstanding the above, nothing herein shall supersede or modify
136
+ the terms of any separate license agreement you may have executed
137
+ with Licensor regarding such Contributions.
138
+
139
+ 6. Trademarks. This License does not grant permission to use the trade
140
+ names, trademarks, service marks, or product names of the Licensor,
141
+ except as required for reasonable and customary use in describing the
142
+ origin of the Work and reproducing the content of the NOTICE file.
143
+
144
+ 7. Disclaimer of Warranty. Unless required by applicable law or
145
+ agreed to in writing, Licensor provides the Work (and each
146
+ Contributor provides its Contributions) on an "AS IS" BASIS,
147
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
148
+ implied, including, without limitation, any warranties or conditions
149
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
150
+ PARTICULAR PURPOSE. You are solely responsible for determining the
151
+ appropriateness of using or redistributing the Work and assume any
152
+ risks associated with Your exercise of permissions under this License.
153
+
154
+ 8. Limitation of Liability. In no event and under no legal theory,
155
+ whether in tort (including negligence), contract, or otherwise,
156
+ unless required by applicable law (such as deliberate and grossly
157
+ negligent acts) or agreed to in writing, shall any Contributor be
158
+ liable to You for damages, including any direct, indirect, special,
159
+ incidental, or consequential damages of any character arising as a
160
+ result of this License or out of the use or inability to use the
161
+ Work (including but not limited to damages for loss of goodwill,
162
+ work stoppage, computer failure or malfunction, or any and all
163
+ other commercial damages or losses), even if such Contributor
164
+ has been advised of the possibility of such damages.
165
+
166
+ 9. Accepting Warranty or Additional Liability. While redistributing
167
+ the Work or Derivative Works thereof, You may choose to offer,
168
+ and charge a fee for, acceptance of support, warranty, indemnity,
169
+ or other liability obligations and/or rights consistent with this
170
+ License. However, in accepting such obligations, You may act only
171
+ on Your own behalf and on Your sole responsibility, not on behalf
172
+ of any other Contributor, and only if You agree to indemnify,
173
+ defend, and hold each Contributor harmless for any liability
174
+ incurred by, or claims asserted against, such Contributor by reason
175
+ of your accepting any such warranty or additional liability.
176
+
177
+ END OF TERMS AND CONDITIONS
178
+
179
+ APPENDIX: How to apply the Apache License to your work.
180
+
181
+ To apply the Apache License to your work, attach the following
182
+ boilerplate notice, with the fields enclosed by brackets "[]"
183
+ replaced with your own identifying information. (Don't include
184
+ the brackets!) The text should be enclosed in the appropriate
185
+ comment syntax for the file format. We also recommend that a
186
+ file or class name and description of purpose be included on the
187
+ same "printed page" as the copyright notice for easier
188
+ identification within third-party archives.
189
+
190
+ Copyright [yyyy] [name of copyright owner]
191
+
192
+ Licensed under the Apache License, Version 2.0 (the "License");
193
+ you may not use this file except in compliance with the License.
194
+ You may obtain a copy of the License at
195
+
196
+ http://www.apache.org/licenses/LICENSE-2.0
197
+
198
+ Unless required by applicable law or agreed to in writing, software
199
+ distributed under the License is distributed on an "AS IS" BASIS,
200
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
201
+ See the License for the specific language governing permissions and
202
+ limitations under the License.
package/NOTICE ADDED
@@ -0,0 +1,36 @@
1
+ NOTICE — vitrea
2
+ ================
3
+
4
+ Copyright (c) 2026 Minhyeok Kim
5
+
6
+ Licensed under the Apache License, Version 2.0 (the "License"); you may not
7
+ use these files except in compliance with the License. You may obtain a copy
8
+ of the License in the LICENSE file distributed with this package, or at
9
+ http://www.apache.org/licenses/LICENSE-2.0
10
+
11
+ This package is original work. The internal packages bundled into it
12
+ (@vitrea/geometry, @vitrea/motion, @vitrea/renderer-webgpu) are part of the
13
+ same project and carry the same copyright and license.
14
+
15
+ Trademarks
16
+ -----------
17
+ "Liquid Glass" is the name of Apple Inc.'s design language. It is referenced
18
+ here descriptively — to state what material this library replicates and what
19
+ its fidelity is measured against — never as a claim of origin, endorsement, or
20
+ association. "Apple", "macOS", "SwiftUI", "Safari" and "Metal" are trademarks
21
+ of Apple Inc., and appear only in that descriptive sense.
22
+
23
+ vitrea is not affiliated with, endorsed by, or sponsored by Apple Inc. It is
24
+ not an Apple product, not built on Apple frameworks, and not a port of Apple
25
+ code. It is an independent open-source reimplementation of a published visual
26
+ material, calibrated against screen captures of Apple's own rendering on
27
+ macOS 26.5.
28
+
29
+ Other names appearing in this project's documentation ("Chromium", "Chrome",
30
+ "Firefox", "WebKit", "Figma") are trademarks of their respective owners and
31
+ are used only in descriptive reference.
32
+
33
+ Contact
34
+ -------
35
+ Minhyeok Kim <kimmi@l1ngual.com>
36
+ https://github.com/SSFSKIM/designer
package/README.md ADDED
@@ -0,0 +1,359 @@
1
+ # vitrea
2
+
3
+ **A production-oriented, reference-calibrated material compositor for semantic web
4
+ controls.**
5
+
6
+ vitrea replicates Apple's Liquid Glass material and interaction system — WWDC25's
7
+ `glassEffect`, `GlassEffectContainer`, `interactive()`, `glassEffectID` — on the
8
+ web, in TypeScript. Not a blur preset: real-time size-parameterized lensing,
9
+ per-element adaptation of tint and foreground to the live backdrop,
10
+ container-scoped sampling, and shape-to-shape morphing.
11
+
12
+ This is not the first WebGPU glass demo, and it does not claim to be. Prior art
13
+ exists and is good at what it does. What vitrea is built for is the part the
14
+ demos leave out: explicit backdrop contracts, shared sampling groups, coherent
15
+ cross-element morphing, adaptive accessibility, progressive fidelity tiers that
16
+ report what they actually resolved to, and fidelity numbers backed by a versioned
17
+ harness that diffs against native captures instead of against a screenshot
18
+ somebody eyeballed.
19
+
20
+ The label on every glass control stays real DOM. A `GlassButton` is a `<button>`:
21
+ selectable, focusable, IME-capable, and announced by a screen reader as a button.
22
+
23
+ ---
24
+
25
+ ## Install
26
+
27
+ ```bash
28
+ npm install @vitreajs/vitrea @vitreajs/vitrea-react
29
+ ```
30
+
31
+ The library is called vitrea and publishes under the npm scope `@vitreajs`.
32
+ `@vitreajs/vitrea` is the framework-agnostic runtime, `@vitreajs/vitrea-react`
33
+ the declarative surface. These two are the only published packages: the
34
+ geometry kernel, the motion kernel, the DOM host layer and the WebGPU renderer
35
+ are internal and bundled into them at publish time, so an app installs two
36
+ packages and gets zero transitive runtime dependencies beyond React itself.
37
+
38
+ ### Which package you actually import from
39
+
40
+ | You are… | Install | Import |
41
+ | --- | --- | --- |
42
+ | writing a React app | `@vitreajs/vitrea @vitreajs/vitrea-react` | `@vitreajs/vitrea-react` for components, `@vitreajs/vitrea` for types |
43
+ | reading the resolved capability state | either | `@vitreajs/vitrea` |
44
+ | writing a Vue/Svelte/WC adapter | `@vitreajs/vitrea` | not yet supported — see below |
45
+
46
+ **One honest limit up front.** `vitrea` contains no DOM code at all, by design
47
+ (the purity law: the core, geometry and motion packages never touch `window`,
48
+ `document` or `HTMLElement`). The browser host layer — element registration,
49
+ plane management, backdrop proxies, the CSS-tier renderer, the WebGPU lifecycle —
50
+ ships bundled *inside* `vitrea-react`. So in v1 the only way to render glass in a
51
+ browser is through the React bindings. `vitrea` on its own gives you the scene
52
+ model, the capability and tier resolver, the material and accessibility policy,
53
+ and the frame-scheduler contract; it does not give you a mounted root. A
54
+ framework-agnostic host entry point is post-v1 work, not a thing you can reach
55
+ today by installing `vitrea` alone.
56
+
57
+ ---
58
+
59
+ ## Quickstart
60
+
61
+ ```tsx
62
+ import { GlassRoot, GlassGroup, GlassToolbar, GlassButton, useGlassCapabilities } from "@vitreajs/vitrea-react";
63
+
64
+ export function App() {
65
+ return (
66
+ <GlassRoot renderer="webgpu">
67
+ {/* Your page. Ordinary DOM, and it stays ordinary DOM. */}
68
+ <YourPage />
69
+
70
+ {/* A toolbar creates its own sampling group; `hint` tells the runtime what
71
+ is behind it, because vitrea never pretends to analyse arbitrary DOM. */}
72
+ <GlassToolbar
73
+ aria-label="Actions"
74
+ groupProps={{ hint: { tone: "dark", luminance: 0.18 } }}
75
+ style={{ position: "fixed", bottom: 32, left: "50%", transform: "translateX(-50%)" }}
76
+ >
77
+ <GlassButton onClick={share}>Share</GlassButton>
78
+ <GlassButton onClick={save}>Save</GlassButton>
79
+ </GlassToolbar>
80
+ </GlassRoot>
81
+ );
82
+ }
83
+ ```
84
+
85
+ Surfaces that are not toolbar members go in an explicit group. A group is the
86
+ sampling unit — one backdrop proxy, one blur, shared between its members:
87
+
88
+ ```tsx
89
+ <GlassGroup id="hero" hint={{ tone: "light" }}>
90
+ <GlassSurface radius={20} thickness={10}>
91
+ <h1>Anything you like in here</h1>
92
+ </GlassSurface>
93
+ </GlassGroup>
94
+ ```
95
+
96
+ And to see what the runtime actually resolved to, rather than what you asked for:
97
+
98
+ ```tsx
99
+ function TierReadout() {
100
+ const state = useGlassCapabilities("hero");
101
+ if (state === undefined) return null;
102
+ return (
103
+ <p>
104
+ configured {state.configuredSource}, drawing on {state.activeRenderer},
105
+ sampling {state.samplingBackend}, refraction {state.refraction}
106
+ {state.health === "demoted" ? ` — demoted: ${state.demotionReason}` : ""}
107
+ </p>
108
+ );
109
+ }
110
+ ```
111
+
112
+ Run the demo app in this repository to see all of it working, including the
113
+ side-by-side native reference pairs:
114
+
115
+ ```bash
116
+ pnpm install && pnpm -r build
117
+ pnpm --filter demo dev # http://localhost:5173, add ?renderer=css to force the tier
118
+ ```
119
+
120
+ ---
121
+
122
+ ## The capability model: the honesty contract, as a feature
123
+
124
+ Most glass libraries have one quality knob and fail quietly when the platform
125
+ cannot honour it. vitrea separates what your app **configures** from what the
126
+ runtime **resolves**, and the resolved state is a closed set of legal
127
+ combinations rather than a free product of axes — because a free product admits
128
+ states that are meaningless (a registered GPU texture with no WebGPU; a
129
+ CORS-tainted video reported as exact analysis).
130
+
131
+ Every group reports:
132
+
133
+ ```ts
134
+ interface GlassGroupState {
135
+ configuredSource: "texture" | "dom"; // what you declared — never mutated
136
+ activeRenderer: "webgpu" | "css"; // what is actually drawing
137
+ samplingBackend: "gpu-texture" | "css-backdrop" | "none";
138
+ refraction: "true" | "approximate" | "none";
139
+ analysis: "exact" | "hint" | "none";
140
+ health: "ok" | "demoted";
141
+ demotionReason?: "no-webgpu" | "no-backdrop-filter" | "tainted-source"
142
+ | "incompatible-texture" | "device-lost" | "probe-failed"
143
+ | "governor";
144
+ }
145
+ ```
146
+
147
+ Three properties are worth knowing, because they are the reason the model exists:
148
+
149
+ **`configuredSource` survives demotion.** You can always see what you asked for
150
+ next to what you got. Nothing silently rewrites your intent.
151
+
152
+ **Every demotion names a reason and a recovery.** `device-lost` recovers when a
153
+ device is restored; `tainted-source` when the source is replaced;
154
+ `probe-failed` when the probe re-passes. `no-webgpu` names its recovery as
155
+ `"none"` — honestly unrecoverable inside the session, rather than implying a
156
+ retry that will never succeed.
157
+
158
+ **Choosing the CSS tier is not a fault.** A root that never requested WebGPU
159
+ resolves its groups to `activeRenderer: "css"` with `health: "ok"` and no
160
+ demotion reason. Labelling deliberate intent as a fault would invert the whole
161
+ point.
162
+
163
+ ### The three healthy configurations
164
+
165
+ | Configuration | What you get |
166
+ | --- | --- |
167
+ | **texture + exact** — you register an image, video, canvas or procedural texture as the group's backdrop | Full refraction. Edge lensing visibly bends the backdrop; a larger surface lenses deeper than a small one over the same content. Luminance, variance and edge-density analysis run on the GPU. |
168
+ | **dom + hint** — arbitrary page content, plus a `hint` (or an estimator provider) | The browser compositor does the blur through a masked backdrop proxy; the GPU renders rim lensing, tint, glow and morphs. Adaptation comes from your hint. |
169
+ | **dom + none** — arbitrary page content, no hint (the default) | Fixed regular material, geometry-driven rim and specular, foreground from tokens or `color-scheme`. |
170
+
171
+ vitrea does not automatically pixel-analyse arbitrary DOM, and never claims to.
172
+ There is a built-in best-effort estimator that reads known background colours and
173
+ images where CORS permits, and it is documented as an estimator every place it
174
+ appears — not as pixel analysis, because that is not what it is.
175
+
176
+ ### Tiers degrade within themselves before they switch
177
+
178
+ The quality governor first reduces refraction resolution, adaptation cadence and
179
+ edge analysis *inside* the current tier. Switching tiers happens only with long
180
+ hysteresis and a cooldown, and never mid-interaction. Intra-tier degradation is
181
+ not a state change, so it does not churn your readouts.
182
+
183
+ ---
184
+
185
+ ## Fidelity
186
+
187
+ vitrea's material is tuned against real captures of Apple's material, not against
188
+ recollection. `apps/reference-apple` is a SwiftUI harness running the actual
189
+ `glassEffect` API; `packages/calibration` captures both sides over identical
190
+ pre-rendered raster backgrounds and diffs them on shape, material, motion and
191
+ perceptual axes, keyed by native profile × web cell.
192
+
193
+ The full record is
194
+ [`docs/doperpowers/specs/c9a-fidelity-claims.md`](https://github.com/SSFSKIM/designer/blob/main/docs/doperpowers/specs/c9a-fidelity-claims.md).
195
+ The claims, in the words that document states them:
196
+
197
+ ### The texture tier
198
+
199
+ > **Reference-calibrated against macOS 26.5 captures.** vitrea's WebGPU texture
200
+ > tier — its own shader math over a GPU-owned backdrop — was calibrated against
201
+ > 30 ScreenCaptureKit captures of Apple's `glassEffect` material on macOS 26.5,
202
+ > in the cell *Chromium 151, `gpu-texture` backend, Apple Metal-3 adapter, sRGB,
203
+ > 1× scale*. Across the six scenes held out of tuning, the rendered result
204
+ > reaches a silhouette IoU of 0.9924 mean / 0.9612 worst, a contour distance of
205
+ > 0.18 px mean / 0.56 px worst-cell-mean, SSIM 0.9475 mean / 0.9007 worst, and
206
+ > OKLab ΔE 0.0320 mean / 0.0548 worst. Tuning improved every one of those axes
207
+ > over the untuned defaults. It is not pixel-identical to Apple's material and
208
+ > two named gaps remain open.
209
+
210
+ ### The CSS (dom) tier
211
+
212
+ > **No cross-engine pixel-wise fidelity claim is made for the dom tier, and none
213
+ > can be. On Chromium, in the same cell with `renderer: css` and
214
+ > `samplingBackend: css-backdrop`: OKLab ΔE 0.0091 mean / 0.0240 worst and SSIM
215
+ > 0.9700 mean / 0.9304 worst over the 12 light calibration cells, ΔE 0.0108 /
216
+ > 0.0273 over the 6 validation cells, and ΔE 0.0291 mean / 0.0560 worst with SSIM
217
+ > 0.9373 / 0.9205 on the six scenes held out of all tuning. Silhouette IoU 0.9424
218
+ > mean over the calibration cells and 0.9684 on holdout, with a 1.06 px mean
219
+ > contour distance.**
220
+
221
+ This tier does not hold a material of its own: it **converts** the one the root
222
+ carries, through a mapping whose single fitted constant is tuned against the
223
+ cross-tier difference rather than against the fixtures. That is a deliberate
224
+ trade, recorded rather than hidden — a CSS tier fitted independently against
225
+ Apple is free to drift from the GPU tier the moment either is retuned, while a
226
+ converted one inherits the GPU tier's fidelity by construction. The price is now
227
+ 0.0099 against Apple where an independent fit reached 0.0094.
228
+
229
+ > **Tier coherence, and only in this wording.** On Chromium, a group that demotes
230
+ > from the WebGPU texture tier to the CSS tier keeps the same material to within
231
+ > 1.3% of its interior level in the mean and 11% on the worst measured cell, at a
232
+ > cross-tier OKLab ΔE of 0.0063 mean / 0.0124 worst over the fitted sets and
233
+ > 0.0188 / 0.0313 over the held-out ones. It is **not** the same rendering —
234
+ > refraction is absent on the CSS tier by contract (`refraction: "none"`) — but
235
+ > the material's opacity, tint and frost do not change visibly on demotion.
236
+
237
+ Exact coherence is unreachable, and the arithmetic says so before any capture
238
+ does: the renderer applies its transfer function *after* the blend and the page
239
+ applies it *before*, so matching the two composites needs a different CSS alpha at
240
+ every backdrop level (0.761 at linear 0.05, 0.635 at 0.8). One scalar is exact at
241
+ one level and necessarily wrong either side of it. What remains is a property of
242
+ `backdrop-filter`, not a residual anyone can tune away.
243
+
244
+ The cross-engine absence is not laziness. Gecko and WebKit render
245
+ `backdrop-filter` as a complete no-op in every automatable capture path — headless
246
+ and headed Playwright, retail `--screenshot`, WebDriver BiDi, WKWebView
247
+ `takeSnapshot` — while rendering it correctly live. A screenshot comparison on
248
+ those engines measures a blank image. Their visual behaviour is verified by a
249
+ manual self-scoring page instead, and that is a release gate rather than a CI
250
+ check.
251
+
252
+ ### What is *not* claimed
253
+
254
+ - **Never "pixel-identical to Apple."** Every figure above is scoped to one
255
+ native profile and one web cell, and says so.
256
+ - **No press-state fidelity claim.** Apple's `Glass.interactive(true)` opts the
257
+ material into *responding* to press input rather than posing it pressed, and
258
+ Apple exposes no declarative pressed pose — so the native "pressed" captures
259
+ are byte-identical to their rest counterparts (verified by SHA-256, all four).
260
+ Those cells compare vitrea's pressed pose against Apple's rest pose. They were
261
+ also excluded from the tuning decision.
262
+ - **No adopted pass/fail thresholds.** The thresholds in the claims document are
263
+ *proposals for a human gate*, not self-certification.
264
+ - **1× only.** The capture machine reports `backingScaleFactor` 1.0, so every
265
+ figure is a 1× figure. The two accessibility-mode profiles have no captures at
266
+ all yet; macOS exposes those display modes as read-only, so each needs its own
267
+ capture run.
268
+ - **The glass-over-glass cells are a mixed-backend claim.** Natively the upper
269
+ `glassEffect` samples the lower one's rendered output; on the web that
270
+ relationship *is* the plane sandwich, so those cells resolve to
271
+ `gpu-texture + css-backdrop` with `refraction: "approximate"` even on the GPU
272
+ tier. They are counted in the holdout numbers, and they are the two lowest
273
+ SSIM figures in that set.
274
+ - **Tier coherence is a Chromium measurement of a material's level**, on one
275
+ profile, at 1×. It does not say the two tiers are identical, and it does not
276
+ hold on Gecko or WebKit — nothing measurable does there.
277
+
278
+ ---
279
+
280
+ ## Browser support
281
+
282
+ Two tiers, and the CSS tier is a hard requirement rather than a courtesy —
283
+ WebGPU is not everywhere, and pretending otherwise is what the capability model
284
+ exists to prevent.
285
+
286
+ | Engine | WebGPU (texture tier) | CSS tier |
287
+ | --- | --- | --- |
288
+ | **Chromium** (Chrome, Edge) | Default-on from 113 on desktop, 121 on Android | Yes. Byte-exact backdrop-proxy sampling equivalence, measured across 122 capture variants |
289
+ | **Safari / WebKit** | Default-on from Safari 26 | Yes, manually verified — automated capture cannot observe `backdrop-filter` on this engine |
290
+ | **Firefox / Gecko** | Default-on from 141 on Windows, 145 on ARM Mac; **still flagged on Linux** | Yes, manually verified — same automated-capture blindness |
291
+
292
+ Where WebGPU is missing, every group resolves to `activeRenderer: "css"` with
293
+ `demotionReason: "no-webgpu"`, renders presentable CSS-tier glass, and logs no
294
+ errors. Asking for the GPU tier is not the same as getting it, and
295
+ `useGlassCapabilities()` is how you find out which happened.
296
+
297
+ ### Contract limits you should know before designing around it
298
+
299
+ - All glass lives inside `GlassRoot`'s managed planes. v1 ships exactly two —
300
+ base and one overlay — and menus portal internally to the overlay plane.
301
+ Arbitrary interleaving with foreign stacking contexts is out of contract.
302
+ - Two glass surfaces must not overlap **within one plane**. This is a dev-mode
303
+ error rather than an assumption: the paint sandwich cannot place one surface's
304
+ body above another surface's DOM label. Overlap across planes is the supported
305
+ case and is what the morph uses.
306
+ - Glass hosts must not sit beneath an ancestor whose `filter`, `opacity`, `mask`
307
+ or `clip` changes the backdrop root. The relevant CSS specification explicitly
308
+ lacks working-group consensus here, so engines may legitimately differ — which
309
+ is why a startup conformance probe validates the proxy topology and demotes a
310
+ group to the CSS tier when sampling proves non-equivalent, rather than trusting
311
+ a support query.
312
+ - v1 corner radii are uniform. The `radii` API keeps its four-component shape,
313
+ but a non-uniform set is a dev-mode error; per-corner algebra is post-v1.
314
+
315
+ ---
316
+
317
+ ## Accessibility
318
+
319
+ Accessibility is policy in `vitrea`, applied by the host layer through media
320
+ queries, with per-root prop overrides. It is resolved, not bolted on: each
321
+ preference has a declared consequence for the material or the motion, and the
322
+ strictest active preference wins.
323
+
324
+ | Preference | What changes |
325
+ | --- | --- |
326
+ | `prefers-reduced-motion` | No elastic overshoot, no deformation, no shimmer travel. Morphs become non-elastic interpolation. Direct-manipulation positional continuity is preserved — reduced motion is not *no* motion. |
327
+ | `prefers-reduced-transparency` | More frost, less refraction, higher occlusion. |
328
+ | `prefers-contrast: more` | Stronger borders, near-monochrome foregrounds, reduced ambient tint. |
329
+ | `forced-colors: active` | System colours, borders, **no glass** — every optical axis goes with it. |
330
+
331
+ The first three are overridable per root:
332
+
333
+ ```tsx
334
+ <GlassRoot reducedTransparency={true} increasedContrast="system" />
335
+ ```
336
+
337
+ `forced-colors` deliberately has **no** override prop, and its absence is
338
+ enforced in the type system: an operating-system colour mandate is not an app's
339
+ to switch off.
340
+
341
+ `prefers-reduced-transparency` is not Baseline across engines. On a platform that
342
+ cannot answer the query, leaving it on `"system"` silently resolves it to false
343
+ and the user's preference is lost — so vitrea emits a diagnostic saying exactly
344
+ that. The explicit override is load-bearing, not a courtesy.
345
+
346
+ One documented obligation on your side: content that vitrea portals into a plane
347
+ leaves its original DOM position, so if that content was inside a landmark
348
+ region, you own re-establishing the landmark. A `role`/landmark seam on the morph
349
+ component is deferred post-v1 API work.
350
+
351
+ ---
352
+
353
+ ## License
354
+
355
+ Apache License 2.0. See [`LICENSE`](https://github.com/SSFSKIM/designer/blob/main/LICENSE).
356
+
357
+ "Liquid Glass" is the name of Apple Inc.'s design language, referenced here
358
+ descriptively to say what this library replicates. vitrea is not affiliated with,
359
+ endorsed by, or sponsored by Apple Inc. See [`NOTICE`](https://github.com/SSFSKIM/designer/blob/main/NOTICE).