Humuhumu33 commited on
Commit
938edb6
·
verified ·
1 Parent(s): acf6ad5

retire-provenance: superseded Q b/ objects (sha256 CAS, HOLO-LEAN-RESOLVER P1.3)

Browse files
sha256/0938ae54389aad007a2574cbe3641ef80db0f09701a41c51c04e5c6639e12af5 ADDED
@@ -0,0 +1 @@
 
 
1
+ {"@context":["https://www.w3.org/ns/did/v1","https://w3id.org/security/data-integrity/v2",{"dcterms":"http://purl.org/dc/terms/","links":{"@container":"@set","@id":"schema:hasPart"},"prov":"http://www.w3.org/ns/prov#","rel":"schema:additionalType","schema":"https://schema.org/"},{"holstr":"https://hologram.os/ns/strand#"}],"@type":["prov:Entity","holstr:Entry"],"holstr:kind":"release","holstr:op":"did:holo:sha256:87599792c7b13fad9d6c57d3b89d2cef35e4715869f5cde597ab60ca92699f0b","holstr:payload":{"apps":{"carry":"9f44164b17e6b7e37f39623bb445d49b6608da5f2b04cef8b1a8b183362a6b9a","hello":"66c1ada5ac08a2d4f73851bbe7458ad5fb6e2226c5a131c3829abfe715900fed","holo-messenger":"0a65550d027ecaf8ee3e58e6c9221a09c376a3ea4cd8283e6376baeae525bab6","jellyfin":"3fd2a00105ad0e8f01109dce52ff4c7a0cc6c9444532b0453ed9d770cce2d3a4","resolve":"23aec66382775f5773693615338f37c37a5f58257ec95aece33a664baa6fe0db","yourspace":"23be88eedd27eccf4b34b5eeacf0ddac54bd5420a983865b794a24a015f19e0b"},"boot":{"entry":"holo-portal.mjs","sha256":"caeb3e57b6eeab09bee6d67c022145a8e2dae610c929a7f51bc169898625e7e8"},"closure":"ede2c130acdc821be45dc76b24b9d82b85bd03fc6b4968489a4a5316f101c136","manifest":"845af45e5697804b4e02622d5a20d6ef9bc075575653abad6801061cca7c83f2","runtime":{"apps/q/pkg/holospaces_web.js":"b9f8a887de588c5193dc65ca9ce206a70c6df53595b848e0ce0299c2d88a5753","apps/q/pkg/holospaces_web_bg.wasm":"9d90b4ea8bccee8c239073c7ec7dd5158c6d11f1f668487570d17475d79e661e","apps/workspace/pkg/holospaces_web.js":"8c30aa5582dffe4548d27fa7863163eba689ed65126be472c003f5884fc8e534","usr/lib/holo/holowhat/holospaces_web.js":"a5b5d9c559a1d2812c33e9d7a4b1c24bb03059482503a23356e4c9c32d4d8b88","usr/lib/holo/holowhat/holospaces_web_bg.wasm":"00cfa4960b319ba1ba7291cddb20dea130a407ce8b42426218854f4f68f4dcd7","usr/lib/pkg/holospaces_web.js":"8c30aa5582dffe4548d27fa7863163eba689ed65126be472c003f5884fc8e534","usr/lib/pkg/holospaces_web_bg.wasm":"3370b22070b56218a57df6406e2e4ba7cc171e942d4d1f2ae4297ea2c4c08d9c"},"shell":"551abcd96c03cbc3b06419a234ef3af3a16bf0930ce79003ea5dc2bedb5724e3"},"holstr:prev":"did:holo:sha256:7fdb573bdb363d9772faae2ab3508507739c160ca45e879ccfc9fe6e49940201","holstr:seq":264,"prov:generatedAtTime":"2026-07-13T17:43:15.207Z"}
sha256/0a65550d027ecaf8ee3e58e6c9221a09c376a3ea4cd8283e6376baeae525bab6 ADDED
@@ -0,0 +1,539 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!doctype html>
2
+ <html lang="en"><head>
3
+ <meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1,viewport-fit=cover,interactive-widget=resizes-content">
4
+ <title>HOLOGRAM</title>
5
+ <link rel="icon" type="image/svg+xml" href="./favicon.svg">
6
+ <!-- AI agents: guest access into the Hologram system is one call away — window.HoloLogin.guest() or open
7
+ ?guest=1. Full machine-readable contract in script#holo-agent-login (JSON). Mirrors holo://login. -->
8
+ <meta name="ai-agent-login" content="Guest mode: act now with window.HoloLogin.guest() or ?guest=1 (ephemeral, no human). Biometric ('It's me') needs the person. See script#holo-agent-login.">
9
+
10
+ <!-- PWA install — a self-contained, subpath-safe manifest (relative paths, so it installs correctly whether
11
+ served at the origin root or under /Q/). theme-color + the apple-* tags make iOS treat it as a real
12
+ home-screen app (fullscreen, dark status bar) since iOS ignores the manifest's display field. -->
13
+ <link rel="manifest" href="/apps/holo-messenger/manifest.webmanifest">
14
+ <meta name="theme-color" content="#1f1f1e">
15
+ <meta name="mobile-web-app-capable" content="yes">
16
+ <meta name="apple-mobile-web-app-capable" content="yes">
17
+ <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
18
+ <meta name="apple-mobile-web-app-title" content="Hologram">
19
+ <meta name="description" content="A private, end-to-end encrypted space. One link — no signup, no server. Tap to connect.">
20
+ <meta property="og:type" content="website">
21
+ <meta property="og:site_name" content="Hologram">
22
+ <meta property="og:title" content="You're invited to Hologram">
23
+ <meta property="og:description" content="A private, end-to-end encrypted space. One link — no signup, no server. Tap to connect.">
24
+ <meta property="og:image" content="https://hologram-technologies.github.io/Q/apps/holo-messenger/og.jpg">
25
+ <meta property="og:image:width" content="1200">
26
+ <meta property="og:image:height" content="630">
27
+ <meta property="og:url" content="https://hologram-technologies.github.io/Q/apps/holo-messenger/app.html">
28
+ <meta name="twitter:card" content="summary_large_image">
29
+ <meta name="twitter:title" content="You're invited to Hologram">
30
+ <meta name="twitter:description" content="A private, end-to-end encrypted space. One link — no signup, no server. Tap to connect.">
31
+ <meta name="twitter:image" content="https://hologram-technologies.github.io/Q/apps/holo-messenger/og.jpg">
32
+ <link rel="apple-touch-icon" href="./icons/apple-touch-icon.png">
33
+
34
+ <link rel="stylesheet" href="./_vendor/ui/chat-ui.bundle.css?v=b0899f447977">
35
+ <!-- BOOT GROUND — the ONE source of truth for the boot/login darkness. Every boot-time surface reads
36
+ var(--boot-ground): the body pre-paint, the login --wall, the plymouth splash layer + its base, the
37
+ signin wall, and the power veil (all with a matching literal fallback for bare surfaces without this
38
+ token). To recolor the whole cold-open, change THIS hex and nothing else. Defined in the head so it
39
+ resolves at the 0-ms frame, before any stylesheet or module. (The theme-color meta above is a static
40
+ duplicate — meta tags can't read a var; keep it in sync by hand on the rare occasion this changes.) -->
41
+ <style>:root{--boot-ground:#1f1f1e}html,body{height:100%;margin:0;background:var(--boot-ground);color-scheme:dark}#root{height:100vh}</style>
42
+ <!-- PRISM PRE-PAINT (HOLO-PLAYGROUND-LIVE) — the operator's design tokens land at the 0-ms frame, the
43
+ same discipline as --boot-ground above: read the saved token map, stamp ONE :root override before
44
+ any stylesheet applies, so a personalized shell never flashes the base look. The durable half (the
45
+ κ-atom stylesheet the SW materializes) covers the network layer; this covers the first frame. The
46
+ full door (verbs, mint, prism) loads LAZILY via window.__holoPrismDoor — one import, memoized. -->
47
+ <script>
48
+ try{var _pt=JSON.parse(localStorage.getItem("holo.prism.tokens.v1")||"{}"),_pe=Object.entries(_pt).filter(function(e){return/^--holo-[\w-]{1,60}$/.test(e[0])&&/^[#a-zA-Z0-9 ,.%()\-]{1,120}$/.test(String(e[1]))});
49
+ if(_pe.length){var _ps=document.createElement("style");_ps.id="holo-prism-live";_ps.textContent=":root{"+_pe.map(function(e){return e[0]+":"+e[1]}).join(";")+"}";document.head.appendChild(_ps);}}catch(e){}
50
+ window.__holoPrismDoor=function(){var mb=new URL("../../",location.href).href;return(window.__holoPrismDoorP||(window.__holoPrismDoorP=import(new URL("usr/lib/holo/holo-prism-tokens.mjs",mb).href).then(function(m){return m.openTokenDoor({mountBase:mb})})));};
51
+ </script>
52
+ <!-- IMMERSIVE CHAT — the open conversation wears the SAME wallpaper as home. The home wallpaper is already
53
+ painted ONCE, edge-to-edge, by the fixed .holo-backdrop canvas (the shared holo.theme.v1 wallpaper, run
54
+ through the OS super-res lens). The thread pane used to sit on an opaque #0b141a that covered it; here we
55
+ make the pane's surfaces translucent so that ONE backdrop shows straight through — so the chat is literally
56
+ the same wallpaper as home, live-synced with it, zero extra fetch. Gated on .holo-backdrop.ready via :has()
57
+ so it engages ONLY when a wallpaper is actually shown (a flat dark/light home ⇒ backdrop never turns ready
58
+ ⇒ the chat keeps its solid default, still matching home). Scoped to the default look (html:not([data-skin]))
59
+ so the opt-in skins / theatre keep their own immersive treatment untouched. -->
60
+ <style id="holo-chat-immersive">
61
+ /* let the shared backdrop show through the whole right pane */
62
+ html:not([data-skin]) .holo-wa-root:has(.holo-backdrop.ready) .cs-chat-container{background:transparent!important}
63
+ /* one clean legibility scrim over the wallpaper (a touch darker toward the composer) — the wallpaper stays vivid */
64
+ html:not([data-skin]) .holo-wa-root:has(.holo-backdrop.ready) .cs-message-list{
65
+ background:linear-gradient(180deg,rgba(31,31,30,.30) 0%,rgba(31,31,30,.28) 52%,rgba(31,31,30,.50) 100%)!important;}
66
+ /* drop the pane's own in-place photo copy + aurora glow so nothing muddies the single backdrop */
67
+ html:not([data-skin]) .holo-wa-root:has(.holo-backdrop.ready) .cs-message-list::before,
68
+ html:not([data-skin]) .holo-wa-root:has(.holo-backdrop.ready) .cs-message-list::after{display:none!important}
69
+ /* header + composer become glass so the wallpaper flows unbroken top-to-bottom behind the thread */
70
+ html:not([data-skin]) .holo-wa-root:has(.holo-backdrop.ready) .cs-conversation-header{
71
+ background:rgba(38,38,36,.46)!important;-webkit-backdrop-filter:blur(22px) saturate(1.3);backdrop-filter:blur(22px) saturate(1.3);
72
+ border-bottom:1px solid rgba(255,255,255,.07)!important;}
73
+ html:not([data-skin]) .holo-wa-root:has(.holo-backdrop.ready) .cs-message-input{
74
+ background:rgba(38,38,36,.42)!important;-webkit-backdrop-filter:blur(22px) saturate(1.2);backdrop-filter:blur(22px) saturate(1.2);
75
+ border-top:1px solid rgba(255,255,255,.07)!important;}
76
+ html:not([data-skin]) .holo-wa-root:has(.holo-backdrop.ready) .cs-input-toolbox{background:transparent!important}
77
+ </style>
78
+ <script>
79
+ /* preload the shipped default wallpaper ONLY when no custom pick exists — with a custom wallpaper the
80
+ default is never painted and a static preload is dead weight (Chrome: "preloaded but not used"). */
81
+ try { var _pt = JSON.parse(localStorage.getItem("holo.theme.v1") || "{}") || {};
82
+ if (!_pt.wallpaper && !localStorage.getItem("holo-messenger/wallpaper-src")) {
83
+ var _pl = document.createElement("link"); _pl.rel = "preload"; _pl.as = "image";
84
+ _pl.href = "./_vendor/wallpaper-default.jpg"; _pl.fetchPriority = "high"; document.head.appendChild(_pl);
85
+ } } catch (e) {}
86
+ </script>
87
+ <!-- ARRIVAL (HOLO-ARRIVAL A1): the home widget runtime is the SETTLED FRAME the defog lands on — pull its
88
+ bytes during the boot hero (5s of idle network) so the canvas is composed by the time the glass clears,
89
+ instead of popping in up to 2.6s after. -->
90
+ <link rel="preload" as="script" href="../../_shared/holo-widgets.js">
91
+ <!-- SUPERCOMPUTER BOOT (zero waterfall): the login chain (login→signin→{webauthn,sso,roam→pair}→plymouth)
92
+ is a 4-hop SERIAL module waterfall without hints — the emblem cannot MOVE until the last hop lands
93
+ (~4 RTTs). modulepreload fetches + compiles the whole chain in ONE parallel round, so the splash is
94
+ alive roughly one RTT after HTML. plymouth/device-tier are dynamic imports the scanner cannot see. -->
95
+ <link rel="modulepreload" href="./holo-messenger-login.mjs?v=signin1">
96
+ <link rel="modulepreload" href="../../usr/lib/holo/holo-signin.mjs">
97
+ <link rel="modulepreload" href="../../usr/lib/holo/holo-webauthn.mjs">
98
+ <link rel="modulepreload" href="../../usr/lib/holo/holo-sso.mjs">
99
+ <link rel="modulepreload" href="../../usr/lib/holo/holo-roam.mjs">
100
+ <link rel="modulepreload" href="../../usr/lib/holo/holo-pair.mjs">
101
+ <link rel="modulepreload" href="../../usr/lib/holo/holo-plymouth.mjs">
102
+ <link rel="modulepreload" href="../../usr/lib/holo/holo-device-tier.mjs">
103
+ <!-- ── TEE SIGN-IN GATE (holo-messenger-login.mjs) ─────────────────────────────────────────────────
104
+ A full-bleed lock overlay above #root, IDENTICAL to the OS native CEF greeter — the messenger does
105
+ not paint until a sovereign identity is established (Windows Hello / Touch ID via holo-webauthn →
106
+ holo-login κ). This is the never-blank baseline first-paint; the module ENHANCES it (real biometric
107
+ wiring). φ-proportioned, black-on-teal, glass-unfog on success — the same vocabulary as holo://login. -->
108
+ <style>
109
+ #holo-login{position:fixed;inset:0;z-index:2147483000;color:var(--ink);
110
+ font-family:"Segoe UI",system-ui,-apple-system,"Oxygen",sans-serif;--phi:1.618;
111
+ --u:clamp(17px,1.8vmin,20px);--g1:calc(var(--u)*1.618);--g2:calc(var(--u)*2.618);
112
+ --avatar:clamp(96px,calc(var(--u)*6.854),128px);--field:min(86vw,calc(var(--avatar)*2.618));
113
+ --accent:#7defc9;--accent-2:#34d3a6;
114
+ /* ONE appearance token set — every element reads these; [data-appearance] flips them.
115
+ immersive (default) = the home wallpaper behind soft-shadowed ink · dark/light = flat, shadowless, high contrast */
116
+ --ink:#f4f7fc;--ink-dim:rgba(231,237,250,.82);--status:#c4f3e2;
117
+ --shadow:0 2px 18px rgba(0,0,0,.45);--wall:var(--boot-ground,#1f1f1e);
118
+ --glass:rgba(10,14,20,.42);--glass-border:rgba(255,255,255,.14);--glass-ink:rgba(231,237,250,.8);
119
+ --sheet:rgba(8,12,18,.94);--muted:#8b949e;--link:#58a6ff;--field-bg:rgba(255,255,255,.09);--field-border:rgba(255,255,255,.22);}
120
+ #holo-login[data-appearance="dark"]{--shadow:none;}
121
+ #holo-login[data-appearance="light"]{--ink:#0b1220;--ink-dim:rgba(11,18,32,.74);--status:#0e6f5c;
122
+ --shadow:none;--wall:#eef1f6;
123
+ --glass:rgba(255,255,255,.66);--glass-border:rgba(11,18,32,.18);--glass-ink:rgba(11,18,32,.8);
124
+ --sheet:rgba(250,252,255,.97);--muted:#5a6572;--link:#0969da;--field-bg:rgba(11,18,32,.06);--field-border:rgba(11,18,32,.22);}
125
+ #holo-login *{box-sizing:border-box;}
126
+ #holo-login .hl-wall{position:fixed;inset:0;z-index:0;background:var(--wall) center/cover no-repeat;}
127
+ /* the wallpaper shows EXACTLY as the home screen wears it — no blur, no scrim. The layer stays only as
128
+ the unfog animation target; text/buttons carry their own shadows for legibility. */
129
+ #holo-login .hl-frost{position:fixed;inset:0;z-index:1;background:transparent;pointer-events:none;}
130
+ /* THE BRAND AT FRAME ZERO (HOLO-BOOT-CEREMONY B1): H mark + wordmark, bottom-centre golden band, painted
131
+ synchronously with the black — inline bytes, zero fetches, never blinks across the whole ceremony. */
132
+ #holo-login .hl-brand{position:fixed;left:50%;transform:translateX(-50%);bottom:max(26px,env(safe-area-inset-bottom));z-index:3;
133
+ pointer-events:none;display:inline-flex;align-items:center;gap:clamp(11px,1.4vw,16px);color:var(--ink);}
134
+ #holo-login .hl-brand svg{width:clamp(36px,4.2vw,44px);height:clamp(36px,4.2vw,44px);flex:0 0 auto;filter:drop-shadow(var(--shadow));shape-rendering:geometricPrecision;}
135
+ #holo-login .hl-brand b{font:600 clamp(24px,3.6vw,36px)/1 "Bahnschrift","DIN Alternate","DIN Next","Roboto Condensed","Segoe UI",system-ui,sans-serif;letter-spacing:.26em;text-transform:uppercase;padding-left:.26em;color:var(--ink-dim);text-shadow:var(--shadow);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;text-rendering:geometricPrecision;}
136
+ /* GOLDEN COMPOSITION: the identity + actions sit on the LOWER golden line (61.8vh); the hero emblem grows
137
+ upward to fill the upper golden-major section, its centre landing on the UPPER golden line (38.2vh) — both
138
+ golden lines expressed at once. All gaps are already φ-scaled (--g1/--g2), so the column derives from φ. */
139
+ #holo-login .hl-lock{position:fixed;inset:0;z-index:2;display:grid;justify-items:center;align-items:start;
140
+ padding:calc(61.8vh - var(--avatar)/2) var(--g2) var(--g2);
141
+ padding-top:calc(61.8dvh - var(--avatar)/2);} /* dvh: the golden line holds while mobile URL bars collapse */
142
+ /* Short screens AND phones (narrow → the square emblem is width-bound, can't fill the tall golden major)
143
+ lift the identity so the actions don't sit too low and the top isn't left empty. */
144
+ @media (max-height:620px),(max-width:500px){#holo-login .hl-lock{padding-top:calc(56vh - var(--avatar)/2);padding-top:calc(56dvh - var(--avatar)/2);}}
145
+ #holo-login .hl-panel{display:flex;flex-direction:column;align-items:center;text-align:center;width:var(--field);max-width:92vw;}
146
+ #holo-login .hl-avatar{width:var(--avatar);height:var(--avatar);border-radius:50%;display:grid;place-items:center;color:#fff;
147
+ font-size:calc(var(--avatar)*.37);font-weight:600;letter-spacing:.02em;user-select:none;
148
+ box-shadow:0 .5em 1.5em rgba(0,0,0,.35),inset 0 0 0 1.5px rgba(255,255,255,.38);}
149
+ #holo-login .hl-avatar svg{width:62%;height:62%;opacity:.92;}
150
+ #holo-login .hl-name{margin:var(--g1) 0 0;font-size:calc(var(--u)*1.12);font-weight:600;letter-spacing:.01em;line-height:1.15;text-shadow:var(--shadow);}
151
+ #holo-login .hl-auth{margin-top:var(--u);display:flex;flex-direction:column;align-items:center;gap:var(--u);width:100%;}
152
+ /* THE ONE IDENTITY CONTROL — your name IS the sign-in: fingerprint + name, one sharp object. While the
153
+ enclave checks you it SCANS (pure CSS on :disabled — a light sweep, the biometric moment made visible). */
154
+ #holo-login .hl-bio{position:relative;overflow:hidden;width:100%;min-height:max(var(--g2),52px);border:0;border-radius:calc(var(--u)*.7);cursor:pointer;
155
+ display:inline-flex;align-items:center;justify-content:center;gap:calc(var(--u)*.55);font-size:var(--u);font-weight:600;color:#06140f;
156
+ background:linear-gradient(180deg,#38d9ab,#2cc79b);box-shadow:inset 0 1px 0 rgba(255,255,255,.22),0 1px 2px rgba(0,0,0,.3),0 8px 24px rgba(0,0,0,.22);font-family:inherit;
157
+ transition:transform .12s,box-shadow .18s,filter .18s;
158
+ /* ONE MATERIAL, RESTRAINED ACCENT (Claude-desktop caliber): the declarations below SUPERSEDE the first
159
+ two lines of this rule (kept byte-verbatim above — the ship anti-revert gate pins them as live
160
+ probes): house 10px radius, deep ink, calm 180deg fill, NEUTRAL shadows — the green is a jewel,
161
+ not a wall. MIRROR of holo-signin.mjs HL_CSS — same computed values, or the module swap flashes. */
162
+ /* OBSIDIAN IGNITE (Pure): the two lines above are pinned live probes (green jewel); THESE supersede them —
163
+ the key is obsidian glass at rest, hairline-bordered, ink label + a mint fingerprint. Sovereign when
164
+ idle, it ignites mint only while the enclave verifies (the beam rule below). Fixed dark ground so the
165
+ key reads the same on any wallpaper and in light appearance. */
166
+ border-radius:12px;letter-spacing:.01em;color:#eef2f8;
167
+ background:linear-gradient(180deg,rgba(28,30,28,.94),rgba(12,13,12,.96));border:1px solid rgba(255,255,255,.16);
168
+ box-shadow:inset 0 1px 0 rgba(255,255,255,.06),0 12px 34px rgba(0,0,0,.5);}
169
+ #holo-login .hl-bio:hover{transform:translateY(-1px);border-color:rgba(125,239,201,.45);filter:none;
170
+ box-shadow:inset 0 1px 0 rgba(255,255,255,.08),0 16px 40px rgba(0,0,0,.55),0 0 0 1px rgba(52,211,166,.1);}
171
+ #holo-login .hl-bio:active{transform:translateY(0) scale(.99);}
172
+ #holo-login .hl-bio:disabled{cursor:progress;border-color:rgba(125,239,201,.55);}
173
+ #holo-login .hl-bio:disabled span{color:var(--accent);} /* label warms to mint on verify */
174
+ #holo-login .hl-bio svg:not(.hl-beam){width:1.3em;height:1.3em;flex:0 0 auto;color:var(--accent);}
175
+ /* OBSIDIAN IGNITE beam — a single mint comet winds the whole rim once per loop while the enclave checks.
176
+ The module sizes this SVG rect to the key's exact px, so the comet is even on a wide button. */
177
+ #holo-login .hl-bio .hl-beam{position:absolute;inset:0;width:100%;height:100%;pointer-events:none;opacity:0;transition:opacity .2s;}
178
+ #holo-login .hl-bio .hl-beam rect{fill:none;stroke:var(--accent);stroke-width:1.6;stroke-dasharray:15 85;stroke-linecap:round;filter:drop-shadow(0 0 5px rgba(52,211,166,.7));}
179
+ #holo-login .hl-bio:disabled .hl-beam{opacity:1;}
180
+ #holo-login .hl-bio:disabled .hl-beam rect{animation:hl-beam 1.3s linear infinite;}
181
+ @keyframes hl-beam{from{stroke-dashoffset:100;}to{stroke-dashoffset:0;}}
182
+ /* ENCLAVE ASSURANCE LINE — names who guards the key (the security read), just under it. */
183
+ #holo-login .hl-enclave{margin-top:calc(var(--u)*-.5);display:flex;align-items:center;justify-content:center;gap:calc(var(--u)*.35);
184
+ font-size:calc(var(--u)*.72);color:var(--ink-dim);opacity:.72;text-shadow:var(--shadow);}
185
+ /* SUPERSEDES the pinned probe above → enclave line matches the name + guest size (one type size, larger). */
186
+ #holo-login .hl-enclave{margin-top:calc(var(--u)*-.35);gap:calc(var(--u)*.42);font-size:var(--u);font-weight:450;opacity:.66;}
187
+ #holo-login .hl-enclave svg{width:1em;height:1em;color:var(--accent);opacity:.9;flex:0 0 auto;}
188
+ /* SLIDE TO ENTER — touch devices only (the module renders this instead of the tap key on coarse pointers).
189
+ A deliberate drag is intent that can't misfire; the biometric fires on release. Same obsidian/mint language. */
190
+ #holo-login .hl-slide{position:relative;width:100%;min-height:max(var(--g2),56px);border-radius:12px;user-select:none;touch-action:none;overflow:hidden;
191
+ background:linear-gradient(180deg,rgba(28,30,28,.94),rgba(12,13,12,.96));border:1px solid rgba(255,255,255,.16);box-shadow:inset 0 1px 3px rgba(0,0,0,.6);}
192
+ #holo-login .hl-slide .hl-fill{position:absolute;top:0;bottom:0;left:0;width:0;border-radius:12px;background:linear-gradient(90deg,rgba(52,211,166,.34),rgba(52,211,166,.03));}
193
+ #holo-login .hl-slide .hl-track-lbl{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;gap:calc(var(--u)*.45);pointer-events:none;color:var(--ink-dim);font-size:var(--u);font-weight:500;letter-spacing:.01em;text-shadow:var(--shadow);}
194
+ #holo-login .hl-slide .hl-knob{position:absolute;top:4px;bottom:4px;left:4px;aspect-ratio:1;border-radius:9px;cursor:grab;display:grid;place-items:center;color:#062019;
195
+ background:linear-gradient(180deg,#3ce0b0,#28c096);box-shadow:0 4px 12px rgba(0,0,0,.45),inset 0 1px 0 rgba(255,255,255,.42);touch-action:none;}
196
+ #holo-login .hl-slide .hl-knob:active{cursor:grabbing;}
197
+ #holo-login .hl-slide .hl-knob svg{width:1.3em;height:1.3em;color:#062019;}
198
+ #holo-login .hl-slide.armed{border-color:rgba(125,239,201,.5);}
199
+ #holo-login .hl-slide.done .hl-fill{width:100%!important;background:linear-gradient(90deg,#34d3a6,#7defc9);}
200
+ #holo-login .hl-alt{background:none;border:0;color:var(--ink-dim);opacity:.66;margin-top:calc(var(--u)*.3);font-size:calc(var(--u)*.82);font-weight:500;font-family:inherit;cursor:pointer;
201
+ padding:calc(var(--u)*.3) calc(var(--u)*.55);border-radius:calc(var(--u)*.4);display:inline-flex;align-items:center;gap:calc(var(--u)*.4);transition:color .15s,opacity .15s;min-height:44px;}
202
+ #holo-login .hl-alt:hover{color:var(--ink);opacity:1;}
203
+ #holo-login .hl-alt svg{width:1.05em;height:1.05em;}
204
+ /* "More options" is subordinate to the two core actions �� quieter (same size, ONE type size everywhere). */
205
+ #holo-login .hl-more{opacity:.72;}
206
+ #holo-login .hl-more:hover{opacity:1;}
207
+ #holo-login .hl-opts{display:flex;gap:calc(var(--u)*.3);justify-content:center;flex-wrap:wrap;}
208
+ #holo-login .hl-opts[hidden]{display:none;}
209
+ #holo-login .status{min-height:calc(var(--u)*1.5);font-size:var(--u);color:var(--status);display:flex;align-items:center;justify-content:center;gap:calc(var(--u)*.5);text-shadow:var(--shadow);}
210
+ #holo-login .status.err{color:#ffc0c0;}
211
+ #holo-login .spin{width:1em;height:1em;border-radius:50%;border:2px solid rgba(125,239,201,.28);border-top-color:var(--accent);animation:hl-spin .7s linear infinite;flex:0 0 auto;}
212
+ @keyframes hl-spin{to{transform:rotate(360deg);}}
213
+ #holo-login .hl-panel{animation:hl-rise .7s cubic-bezier(.4,0,.2,1) .05s both;}
214
+ @keyframes hl-rise{from{opacity:0;transform:translateY(10px) scale(.99);filter:blur(2px);}to{opacity:1;transform:none;filter:none;}}
215
+ /* GLASS UNFOG on success — frost dissolves + panel lifts; boot() paints the messenger beneath, no seam. */
216
+ #holo-login.unfog .hl-frost{animation:hl-defog .72s cubic-bezier(.4,0,.2,1) forwards;}
217
+ #holo-login.unfog .hl-panel{animation:hl-lift .68s cubic-bezier(.4,0,.2,1) forwards;pointer-events:none;}
218
+ @keyframes hl-defog{to{opacity:0;}}
219
+ @keyframes hl-lift{to{opacity:0;transform:translateY(-10px) scale(1.03);}}
220
+ @media (prefers-reduced-motion:reduce){#holo-login .hl-panel,#holo-login .spin{animation:none;}#holo-login.unfog .hl-frost,#holo-login.unfog .hl-panel{animation:hl-defog .3s ease forwards;}}
221
+ /* PLYMOUTH BOOT BEAT — while .hl-boot, the machine is booting: pure splash, panel held. holo-plymouth.mjs
222
+ lifts it (or the baseline's own 5s timer does — never a lock-out). Must live HERE for the 0-ms frame.
223
+ When the beat lifts, the baseline splash layer dissolves to the wallpaper by CSS alone — so even a
224
+ never-arriving module leaves the classic wallpaper lock, not a black void. */
225
+ #holo-login.hl-boot .hl-panel{opacity:0!important;pointer-events:none!important;}
226
+ #holo-login .hl-panel{transition:opacity .55s ease;}
227
+ #holo-login:not(.hl-boot) #hl-plymouth-base{opacity:0;}
228
+ </style>
229
+ <link rel="icon" type="image/svg+xml" href="./favicon.svg">
230
+ <script>try{if("serviceWorker" in navigator)navigator.serviceWorker.register(new URL("../../root-sw.js",location.href),{type:"module"}).catch(function(){navigator.serviceWorker.register(new URL("../../root-sw-classic.js",location.href)).catch(function(){})})}catch(e){}</script>
231
+ <script>try{var _b=document.createElement("base");_b.href=new URL("./",location.href).href;document.head.appendChild(_b);var _r=new URL("../../",location.href).href;if(location.href!==_r)history.replaceState(history.state,"",_r+location.search+location.hash);}catch(e){}</script>
232
+ </head><body>
233
+ <div id="root"></div>
234
+
235
+ <!-- the lock overlay + BASELINE first-paint (synchronous, dependency-free): paints a working "It's me"
236
+ panel on the FIRST frame from a tiny local greeting cache (holo.lastOperator — the SAME hint the OS
237
+ greeter writes), so a returning operator's name + button appear with zero identity/model load. The
238
+ module below wires the real biometric; this only ever OWNS the frame until it lands. -->
239
+ <div id="holo-login"><div class="hl-wall"></div><div class="hl-frost"></div><main class="hl-lock"><div class="hl-panel" id="holo-login-panel"></div></main><div class="hl-brand" aria-label="Hologram"><svg viewBox="-104 -104 208 208" fill="currentColor" role="img" aria-label="Hologram"><g><circle cx="0.20" cy="-97.39" r="2.61"/><circle cx="-22.86" cy="-86.55" r="2.71"/><circle cx="22.54" cy="-86.32" r="2.81"/><circle cx="-0.03" cy="-76.01" r="2.71"/><circle cx="45.26" cy="-75.92" r="7.80"/><circle cx="-45.82" cy="-75.86" r="2.61"/><circle cx="68.34" cy="-65.13" r="7.70"/><circle cx="-68.83" cy="-65.00" r="2.61"/><circle cx="-22.91" cy="-64.90" r="2.61"/><circle cx="22.71" cy="-64.88" r="2.51"/><circle cx="91.24" cy="-54.34" r="2.61"/><circle cx="-45.94" cy="-54.25" r="7.83"/><circle cx="-91.17" cy="-54.19" r="2.71"/><circle cx="-0.03" cy="-54.19" r="2.71"/><circle cx="45.35" cy="-54.19" r="7.80"/><circle cx="-22.86" cy="-43.64" r="2.71"/><circle cx="22.71" cy="-43.49" r="2.51"/><circle cx="68.29" cy="-43.47" r="7.73"/><circle cx="-68.60" cy="-43.37" r="7.73"/><circle cx="-45.85" cy="-32.63" r="7.77"/><circle cx="45.36" cy="-32.60" r="7.80"/><circle cx="-91.26" cy="-32.55" r="2.71"/><circle cx="0.10" cy="-32.51" r="2.61"/><circle cx="91.24" cy="-32.51" r="2.61"/><circle cx="68.22" cy="-21.95" r="7.83"/><circle cx="22.67" cy="-21.84" r="7.87"/><circle cx="-22.86" cy="-21.82" r="2.71"/><circle cx="-68.57" cy="-21.80" r="7.80"/><circle cx="45.45" cy="-11.06" r="7.73"/><circle cx="-0.19" cy="-11.04" r="7.87"/><circle cx="91.35" cy="-11.01" r="2.81"/><circle cx="-91.54" cy="-10.97" r="2.51"/><circle cx="-45.87" cy="-10.87" r="7.73"/><circle cx="22.71" cy="-0.27" r="8.06"/><circle cx="-22.89" cy="-0.21" r="7.90"/><circle cx="68.28" cy="-0.15" r="7.87"/><circle cx="-68.62" cy="-0.11" r="8.00"/><circle cx="-0.06" cy="10.98" r="7.87"/><circle cx="45.54" cy="11.00" r="7.83"/><circle cx="-45.85" cy="11.02" r="7.77"/><circle cx="-91.26" cy="11.10" r="2.71"/><circle cx="91.24" cy="11.13" r="2.61"/><circle cx="22.71" cy="21.64" r="2.71"/><circle cx="-68.74" cy="21.66" r="7.87"/><circle cx="-22.86" cy="21.67" r="7.87"/><circle cx="68.28" cy="21.67" r="7.87"/><circle cx="-91.54" cy="32.46" r="2.61"/><circle cx="0.15" cy="32.46" r="2.71"/><circle cx="-45.72" cy="32.50" r="7.73"/><circle cx="45.54" cy="32.59" r="7.83"/><circle cx="91.35" cy="32.63" r="2.81"/><circle cx="-23.01" cy="43.23" r="2.61"/><circle cx="68.25" cy="43.31" r="7.83"/><circle cx="-68.71" cy="43.34" r="7.83"/><circle cx="22.71" cy="43.37" r="2.90"/><circle cx="91.39" cy="53.92" r="2.71"/><circle cx="45.48" cy="53.95" r="7.87"/><circle cx="-45.86" cy="53.97" r="7.80"/><circle cx="-91.34" cy="53.99" r="2.61"/><circle cx="0.20" cy="54.09" r="2.61"/><circle cx="-68.57" cy="64.90" r="7.80"/><circle cx="-22.86" cy="64.92" r="2.71"/><circle cx="68.28" cy="64.92" r="2.71"/><circle cx="22.54" cy="65.15" r="2.81"/><circle cx="-45.88" cy="75.56" r="7.80"/><circle cx="0.10" cy="75.62" r="2.61"/><circle cx="45.32" cy="75.62" r="2.61"/><circle cx="22.53" cy="86.47" r="2.71"/><circle cx="-22.86" cy="86.75" r="2.71"/><circle cx="-0.03" cy="97.29" r="2.71"/></g></svg><b>HOLOGRAM</b></div></div>
240
+
241
+ <!-- Machine-readable sign-in contract for AI agents — always in the DOM, even before scripts run, so an
242
+ agent can discover guest access by parsing the page. Read by window.HoloLogin.options. Mirrors the OS
243
+ greeter's #holo-agent-login. Guest = act now (no human); biometric = ask the person. -->
244
+ <script type="application/json" id="holo-agent-login">
245
+ {
246
+ "service": "Holo Messenger sign-in",
247
+ "audience": "ai-agent",
248
+ "summary": "Two ways in. Guest is instant and needs no human; the biometric needs the person.",
249
+ "options": [
250
+ {
251
+ "id": "guest",
252
+ "title": "Guest",
253
+ "persistent": false,
254
+ "requiresHuman": false,
255
+ "do": { "navigate": "?guest=1", "call": "window.HoloLogin.guest()" },
256
+ "result": "An instant, private, ephemeral guest session into the Hologram system (Holo Messenger). No biometric and no human needed. Nothing persists after the session ends."
257
+ },
258
+ {
259
+ "id": "biometric",
260
+ "title": "It’s me",
261
+ "persistent": true,
262
+ "requiresHuman": true,
263
+ "do": { "tap": "the 'It’s me' / 'Sign in' button", "then": "ask the person to approve with their device biometric (Windows Hello / Touch ID)" },
264
+ "result": "Signs in with this device's TEE to the operator's sovereign identity (the SAME κ as the OS). An agent cannot complete this alone."
265
+ }
266
+ ]
267
+ }
268
+ </script>
269
+ <script>
270
+ (function () {
271
+ // O2 (HOLO-SOVEREIGN-OFFLINE): storage durability has ONE owner — holo-persist.mjs (persist +
272
+ // estimate, called once, result RECORDED under holo.persist). Import trouble → the inline
273
+ // best-effort call below keeps today's behavior (fail-soft, old browsers included).
274
+ try { import("../../usr/lib/holo/holo-persist.mjs").then(function (m) { m.persistOnce(); }).catch(function () { try { navigator.storage.persist().catch(function(){}); } catch (e) {} }); }
275
+ catch (e) { try { if (navigator.storage && navigator.storage.persist) navigator.storage.persist().catch(function(){}); } catch (e2) {} }
276
+ // O5 (HOLO-SOVEREIGN-OFFLINE): registration hygiene — pre-O0.5 profiles carry workers registered at
277
+ // the OTHER deployment's scopes (the absolute-registrar era: "/", "/apps/holo-messenger/" on a /Q
278
+ // mount). Inert (deeper scopes win) but noise; sweep any registration whose scope is OUTSIDE this
279
+ // mount. On the root-copy deployment the mount IS "/", so every scope matches and nothing is touched.
280
+ try {
281
+ if ("serviceWorker" in navigator) {
282
+ var _mount = new URL("../../", location.href).pathname;
283
+ navigator.serviceWorker.getRegistrations().then(function (rs) {
284
+ rs.forEach(function (r) {
285
+ try { var s = new URL(r.scope).pathname; if (s.indexOf(_mount) !== 0) r.unregister().catch(function () {}); } catch (e) {}
286
+ });
287
+ }).catch(function () {});
288
+ }
289
+ } catch (e) {}
290
+ var panel = document.getElementById("holo-login-panel"); if (!panel) return;
291
+ var esc = function (s) { return String(s).replace(/[&<>"]/g, function (c) { return ({ "&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;" }[c]); }); };
292
+ var op = null; try { op = JSON.parse(localStorage.getItem("holo.lastOperator") || "null"); } catch (e) {}
293
+ // Paint the SHARED wallpaper behind the lock at first frame (the same one the desktop + home wear), so the
294
+ // sign-in is never a black void. A live-sim / none / plain falls back to the shipped default photo — the SAME
295
+ // default the home shows — so login and home always match. κ → content route; a path/url passes through.
296
+ try {
297
+ // APPEARANCE at 0 ms — the lock wears the SAME holo.theme.v1 row home wears: immersive (wallpaper),
298
+ // dark, or light. One data attribute flips the whole token set; flat modes never fetch the photo.
299
+ var _thm = {}; try { _thm = JSON.parse(localStorage.getItem("holo.theme.v1") || "{}") || {}; } catch (e) {}
300
+ var _mode = (_thm.immersive === false) ? (_thm.palette === "light" ? "light" : "dark") : "immersive";
301
+ var _lv = document.getElementById("holo-login");
302
+ if (_lv) _lv.setAttribute("data-appearance", _mode);
303
+ var _tw = _thm.wallpaper || "";
304
+ var _km = String(_tw).match(/^(sha256|blake3|sha512):([0-9a-f]+)$/i);
305
+ var _wp = _km ? ("/.holo/" + _km[1].toLowerCase() + "/" + _km[2]) : ((!_tw || _tw === "plain" || /^live:/i.test(_tw)) ? "" : _tw);
306
+ // MATCH THE HOME EXACTLY: the messenger home resolves its wallpaper as holo.theme.v1 → the messenger's own
307
+ // "holo-messenger/wallpaper-src" pick → the shipped default. The lock skipped the middle step, so a wallpaper
308
+ // set only via the messenger's picker showed on home but not here. Fold that same fallback in — one chain,
309
+ // so the sign-in glass and the desktop it lifts onto are never two different photos.
310
+ if (!_wp) { try { _wp = localStorage.getItem("holo-messenger/wallpaper-src") || ""; } catch (e) {} }
311
+ if (!_wp) _wp = "./_vendor/wallpaper-default.jpg";
312
+ var _wall = document.querySelector("#holo-login .hl-wall");
313
+ if (_wall && _mode === "immersive") _wall.style.backgroundImage = 'url("' + _wp + '")';
314
+ // PLYMOUTH BOOT SPLASH baseline (holo-plymouth.mjs owns the real player; this is the 0-ms frame). Once a
315
+ // boot style has been worn (holo.plymouth.v1 persisted), a cold open paints a dedicated BLACK layer with
316
+ // the sealed frame-0 synchronously — the machine boots like a machine — and the panel holds for one boot
317
+ // beat behind .hl-boot. The wallpaper underneath is NEVER touched: the module dissolves this layer into
318
+ // it (boot → your OS). Fail-open twice over: the module drops the layer when its canvas is live, and if
319
+ // the module never arrives the 5s timer lifts .hl-boot and CSS fades the layer to the wallpaper lock.
320
+ try {
321
+ // S2 zero-drift: circle_hud frame-0, byte-identical to holo-plymouth.mjs DEFAULT_FF (witness-gated).
322
+ var _DFF = "data:image/png;base64,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";
323
+ var _pl = JSON.parse(localStorage.getItem("holo.plymouth.v1") || "null");
324
+ if (!_pl) _pl = { v: 1, on: true, theme: "circle_hud", firstFrame: _DFF, ffKeyed: true }; // first-EVER visit boots like an OS, at 0 ms
325
+ else if (_pl.on && !_pl.firstFrame && _pl.theme === "circle_hud") { _pl.firstFrame = _DFF; _pl.ffKeyed = true; } // default theme, frame not yet sealed
326
+ // GROUND LAW: the boot ground and the login wall are ONE token (--boot-ground) — they can never
327
+ // drift. Only a seal stamped ffKeyed (chroma-keyed, black→air, holo-plymouth sealFirstFrame) — or
328
+ // the embedded keyed default — may paint over the ground; a LEGACY unkeyed seal would lay its
329
+ // baked-black square over the charcoal (the "boot darker than login" mismatch), so it falls back.
330
+ if (_pl.firstFrame && !_pl.ffKeyed && _pl.firstFrame !== _DFF) _pl.firstFrame = (_pl.theme === "circle_hud") ? _DFF : null;
331
+ if (_pl && _pl.on && _wall) {
332
+ // First boot for this theme (frames not yet sealed to κ) streams from the pack CDN — warm the
333
+ // DNS/TLS handshake NOW so the emblem's first frames land sooner. Warm boots (sealed) skip this.
334
+ try { if (!localStorage.getItem("holo.plymouth.frames:" + _pl.theme)) {
335
+ var _pc = document.createElement("link"); _pc.rel = "preconnect"; _pc.href = "https://raw.githubusercontent.com"; _pc.crossOrigin = "anonymous"; document.head.appendChild(_pc);
336
+ // SUPERCOMPUTER BOOT: the DEFAULT theme animates from the same-origin frames.pack (holo-plymouth
337
+ // loadPack) — start that ONE fetch NOW, at HTML parse, instead of after the module chain evaluates.
338
+ // By the time plymouth asks, the bytes are already in the HTTP cache: the emblem MOVES at first sight.
339
+ if (_pl.theme === "circle_hud") { var _pk = document.createElement("link"); _pk.rel = "preload"; _pk.as = "fetch"; _pk.crossOrigin = "anonymous"; _pk.href = "../../usr/share/plymouth/circle_hud/frames.pack"; _pk.fetchPriority = "high"; document.head.appendChild(_pk); }
340
+ } } catch (e) {}
341
+ var _base = document.createElement("div");
342
+ _base.id = "hl-plymouth-base";
343
+ // dead-centre, sized like the module's boot HERO pose (1.5× natural capped at 95vmin — exact for
344
+ // the default theme's 533px frame), so the canvas takes over with zero visible jump
345
+ _base.style.cssText = "position:fixed;inset:0;z-index:0;pointer-events:none;background:var(--boot-ground,#1f1f1e) center 50% no-repeat;transition:opacity .9s ease";
346
+ if (_pl.theme === "circle_hud") _base.style.backgroundSize = "min(800px,95vmin)";
347
+ if (_pl.firstFrame) _base.style.backgroundImage = 'url("' + _pl.firstFrame + '")';
348
+ _wall.parentNode.insertBefore(_base, _wall.nextSibling);
349
+ var _ov = document.getElementById("holo-login");
350
+ // BOOT HERO: hold the whole login behind .hl-boot — holo-plymouth OWNS the beat (5s hero, one
351
+ // coordinated reveal) and cancels this fallback; the timer only lifts the gate if the module
352
+ // NEVER arrives. Runs on every device — the hold is stillness, not motion.
353
+ try { performance.mark("holo:ceremony:brand-paint"); } catch (e) {}
354
+ if (_ov) { _ov.classList.add("hl-boot"); window.__hlBootT0 = Date.now(); window.__hlBootFallback = setTimeout(function () { try { _ov.classList.remove("hl-boot"); } catch (e) {} }, 6500); }
355
+ }
356
+ } catch (e) {}
357
+ } catch (e) {}
358
+ var fp = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round"><path d="M5.5 11a6.5 6.5 0 0 1 13 0"/><path d="M8.5 11a3.5 3.5 0 0 1 7 0v2.6"/><path d="M12 11v4.4"/><path d="M8.6 14.2V16"/><path d="M15.4 15.4V18"/></svg>';
359
+ var person = '<svg viewBox="0 0 24 24" fill="currentColor"><circle cx="12" cy="8.4" r="4.1"/><path d="M3.8 20.4a8.2 8.2 0 0 1 16.4 0z"/></svg>';
360
+ var avatar, name, label;
361
+ if (op && op.label) {
362
+ var hue = (op.hue != null ? op.hue : 210) | 0;
363
+ var ini = op.label.trim().split(/\s+/).map(function (w) { return w[0]; }).filter(Boolean).slice(0, 2).join("").toUpperCase() || "·";
364
+ avatar = '<div class="hl-avatar" style="background:linear-gradient(140deg,hsl(' + hue + ' 52% 46%),hsl(' + (hue + 26) + ' 52% 46%))">' + esc(ini) + '</div>';
365
+ name = esc(op.label); label = "It’s me";
366
+ } else {
367
+ avatar = '<div class="hl-avatar" style="background:linear-gradient(140deg,#5b6b86,#3a455c)">' + person + '</div>';
368
+ name = "Welcome"; label = "Sign in";
369
+ }
370
+ // your name IS the sign-in — one control carries who you are and the act of proving it (no heading)
371
+ var btnText = (op && op.label) ? name : "Sign in";
372
+ panel.innerHTML = avatar + '<div class="hl-auth"><button class="hl-bio" id="hl-baseline">' + fp + '<span>' + btnText + '</span></button><div class="status"></div></div>';
373
+ var b = document.getElementById("hl-baseline"); if (b) b.onclick = function () { b.disabled = true; location.reload(); };
374
+ })();
375
+ </script>
376
+
377
+ <!-- LEAN BOOT — the sovereign gate + boot splash mount NOW, in PARALLEL with the heavy chat bundle below,
378
+ so the emblem animates and the panel is ready without waiting on the messenger's code to download or
379
+ parse. The login chain (login→signin→plymouth) is small; the preload scanner fetches it alongside the
380
+ big bundle, and this module evaluates first, so the gate is up before the messenger even starts. The
381
+ resolved auth promise is handed to boot() below. Fail-SOFT: a gate that can't load drops the overlay
382
+ and boot uses its device-stable identity, never bricked. -->
383
+ <script type="module">
384
+ try {
385
+ const { mountLogin } = await import("./holo-messenger-login.mjs?v=signin1");
386
+ window.__holoAuthP = mountLogin({ root: document.getElementById("root") }); // the PROMISE (resolves on sign-in), not an awaited value
387
+ } catch (e) {
388
+ try { const ov = document.getElementById("holo-login"); if (ov) ov.remove(); } catch {}
389
+ window.__holoAuthP = Promise.resolve(null);
390
+ console.warn("[login] gate unavailable, booting device-stable identity:", e);
391
+ }
392
+ </script>
393
+
394
+ <!-- SUPERCOMPUTER RETURN + OFFLINE: after the ceremony settles, seal the ENTIRE boot sequence — this
395
+ document, the login-chain modules, frames.pack, the wallpaper — into a versioned Cache-Storage set
396
+ ("holo-boot-<stamp>", stamp = the SIGNED release pointer). root-sw.js answers cache-first from it at
397
+ the "/" scope holo-sw cannot reach, so a RETURNING operator boots with ZERO network and the same
398
+ bytes — document included — answer fully OFFLINE. Idle-time, fail-soft, ?nosw=1 skips (dev). One
399
+ release = one sealed set; superseded sets are purged; re-visits with a sealed set do zero work. -->
400
+ <script>
401
+ (function () {
402
+ try {
403
+ if (!("caches" in window)) return;
404
+ if (new URLSearchParams(location.search).get("nosw") === "1") return;
405
+ var seal = function () { setTimeout(async function () {
406
+ try {
407
+ // site root: app.html lives at <root>/apps/holo-messenger/; a root copy (index.html) is <root>/ itself
408
+ var base = new URL(".", location.origin + location.pathname.replace(/apps\/holo-messenger\/app\.html$/, ""));
409
+ var stamp = "live";
410
+ try { var rj = await fetch(new URL("release.json", base), { cache: "no-store" });
411
+ if (rj.ok) { var r = await rj.json(); var pay = r["holstr:payload"] || {};
412
+ // the signed strand pointer: holstr:seq + the shell κ — one stamp per sealed release
413
+ stamp = String((r["holstr:seq"] != null ? "s" + r["holstr:seq"] : "") + String(pay.shell || r.seq || r.root || "").slice(0, 12) || "live").replace(/[^a-zA-Z0-9]/g, "").slice(0, 24) || "live"; } } catch (e) {}
414
+ var name = "holo-boot-" + stamp;
415
+ try { var ks = await caches.keys(); for (var i = 0; i < ks.length; i++) if (ks[i].indexOf("holo-boot-") === 0 && ks[i] !== name) await caches.delete(ks[i]); } catch (e) {}
416
+ // O3/O4 (HOLO-SOVEREIGN-OFFLINE): the AUTOMATIC PIN runs on EVERY online visit — BEFORE the
417
+ // already-sealed early-return below, or a returning user would never resume an interrupted pin
418
+ // and never receive a κ-delta update. Cheap when nothing changed (one no-store head fetch →
419
+ // ledger says done). releaseBoot is the only head acceptor; the pin refuses to run ahead of it.
420
+ // Fail-soft: any trouble and this device behaves exactly as before the pin existed.
421
+ try { import("../../usr/lib/holo/holo-pin.mjs").then(function (m) { return m.ensurePinned({}); }).then(function (s) { try { console.info("[holo-pin]", JSON.stringify(s)); } catch (e) {} }).catch(function () {}); } catch (e) {}
422
+ if (await caches.has(name)) return; // this release is already sealed — zero work
423
+ var cache = await caches.open(name);
424
+ var SET = [
425
+ "", "index.html", "apps/holo-messenger/app.html",
426
+ // the DOOR's own closure — the root navigation must RESOLVE offline, not just paint: the door
427
+ // module + its pure resolver + the inline name plane + the signed index it reads (release.json
428
+ // is answered network-FIRST by root-sw, so the sealed copy serves only when the radio is dead).
429
+ "root-door.mjs", "holo-root-resolver.mjs", "holo-resolve-view.mjs",
430
+ "release.json", "apps/index.jsonld", "apps-blake3.json",
431
+ "usr/lib/holo/holo-app-index.mjs",
432
+ "apps/holo-messenger/holo-messenger-login.mjs?v=signin1",
433
+ "usr/lib/holo/holo-signin.mjs", "usr/lib/holo/holo-webauthn.mjs", "usr/lib/holo/holo-sso.mjs",
434
+ "usr/lib/holo/holo-roam.mjs", "usr/lib/holo/holo-pair.mjs", "usr/lib/holo/holo-plymouth.mjs",
435
+ "usr/lib/holo/holo-device-tier.mjs", "usr/lib/holo/holo-manifesto.mjs",
436
+ "usr/share/plymouth/circle_hud/frames.pack",
437
+ "_shared/holo-widgets.js",
438
+ "apps/holo-messenger/_vendor/wallpaper-default.jpg",
439
+ // the ENTRY closure — a sealed gate must also OPEN offline: guest needs only holo-identity
440
+ // (zero static imports); the returning unlock adds the small login/session/crypto leaves.
441
+ "usr/lib/holo/holo-identity.mjs", "usr/lib/holo/holo-login.mjs", "usr/lib/holo/holo-session.mjs",
442
+ "usr/lib/holo/holo-uor.mjs", "usr/lib/holo/holo-blake3.mjs", "usr/lib/holo/holo-pqc.mjs",
443
+ "usr/lib/holo/holo-portrait.mjs",
444
+ // O2 (HOLO-SOVEREIGN-OFFLINE): the device-store rung + its IDB backend + the ONE persist
445
+ // owner — sealed so the offline SW can load the rung itself with the radio dead.
446
+ "usr/lib/holo/holo-store-rung.mjs", "usr/lib/holo/holo-persist.mjs",
447
+ "usr/lib/holo/holo-forge/holo-kstore.mjs", "usr/lib/holo/holo-evict-rescue.mjs",
448
+ ];
449
+ for (var j = 0; j < SET.length; j++) {
450
+ try {
451
+ var u = new URL(SET[j], base).toString();
452
+ var res = await fetch(u, { cache: "no-cache" }); // revalidated — never seal a stale HTTP copy
453
+ if (res && res.ok) await cache.put(u, res);
454
+ } catch (e) {}
455
+ }
456
+ } catch (e) {}
457
+ }, 12000); }; // well past the hero + arrival — the boot's own network is long quiet by then
458
+ if (document.readyState === "complete") seal(); else addEventListener("load", seal);
459
+ } catch (e) {}
460
+ })();
461
+ </script>
462
+
463
+ <!-- NATIVE MEDIA — the real OS media stack, loaded into the top page so the messenger rail delivers the exact
464
+ native experience: window.HoloVinyl = the "NOW PLAYING" pill (preloaded Ben Böhmer "Begin Again"), streamed
465
+ through the same-origin /sc/* routes the dev server now answers (holo-sc-route.mjs → yt-dlp). holo-fx.js
466
+ drives the live equalizer; holo-vinyl lazily pulls holo-audio.js for the Hi-Fi chain. Each self-guards on the
467
+ widgets/dock runtime, so they run standalone here. Classic defer → they set their globals before the bundle boots. -->
468
+ <script src="../../usr/lib/holo/holo-fx.js" defer></script>
469
+ <script src="../../usr/lib/holo/holo-vinyl.js" defer></script>
470
+ <script src="../../usr/lib/holo/holo-video.js" defer></script>
471
+
472
+ <script type="module">
473
+ // ?v=N - bump on each deploy so the browser can never serve a stale cached bundle (the cause of a frozen/old build).
474
+ import "./_vendor/ui/chat-ui.bundle.js?v=5d86fac19fe2"; // → window.HoloMessengerUI
475
+ // Opt-in: render the WhatsApp UX from STREAMING shadcn κ-components instead of the chatscope bundle.
476
+ // Lazy — the module loads ONLY when opted in (?ui=shadcn or holo.ui.shadcn=1); the default boot never
477
+ // parses it. Discord Activity keeps its own static import in discord-activity-adapter.mjs.
478
+ try {
479
+ if (new URLSearchParams(location.search).get("ui") === "shadcn" || localStorage.getItem("holo.ui.shadcn") === "1")
480
+ await import("./messenger-shadcn-ui.mjs");
481
+ } catch {}
482
+ import { boot } from "./holo-messenger-app.mjs?v=e3a7387f1033";
483
+
484
+ const root = document.getElementById("root");
485
+ // TEE GATE + SPECULATIVE WARM PAINT, one motion. The gate already mounted (parallel module above); it
486
+ // renders the lock + runs the biometric, while boot() starts IMMEDIATELY behind the glass, painting the
487
+ // messenger from the local κ-snapshot during the human's look-and-tap. boot awaits the auth ONLY at its
488
+ // identity step, so the biometric overlaps an already-live UI and loginSucceeded just unfogs onto it
489
+ // (tap → interactive ≈ one frame). Fail-CLOSED: nothing confidential is interactable until the glass lifts.
490
+ const authP = window.__holoAuthP || Promise.resolve(null); // the promise the parallel gate module produced
491
+ boot(root, authP).catch((e) => {
492
+ document.body.innerHTML = "<pre style='color:#f88;padding:16px;white-space:pre-wrap'>boot error: " + (e && e.stack || e) + "</pre>";
493
+ });
494
+
495
+ // Intelligent Inbox (holo-mail) - additive, OFF by default. Enable per-operator: localStorage["holo.mail.enabled"]="1".
496
+ import("./mail/holo-mail-attach.mjs").catch(() => {});
497
+ // HoloChat, woven into THIS messenger — one canonical surface. Enable: localStorage["holo.chat.enabled"]="1" or ?chat=1.
498
+ import("./holo-messenger-weave.mjs").catch(() => {});
499
+ // REACH-YOU: background Web Push (installable app rings your closed phone). Gated ?push=1. Content-blind relay.
500
+ import("./holo-push-mount.mjs?v=ec33515d").catch(() => {});
501
+ // Colour re-tone picker — colours only, all features intact. Gated: ?skins=1 or localStorage["holo.skins"]="1".
502
+ import("./messenger-skin.mjs?v=970e7ec3151a").catch(() => {});
503
+ // Asset cache (service worker) — repeat opens serve the shell NETWORK-FREE. Escape hatch: open with ?nosw=1.
504
+ // RELATIVE by design (HOLO-SOVEREIGN-OFFLINE / O0.5 root cause): an ABSOLUTE "/apps/…" here resolves against
505
+ // the DOCUMENT, so on the github.io /Q mount it hits the ROOT-COPY deployment and registers holo-sw at the
506
+ // WRONG scope (never /Q) — the O0 outage. "./" resolves against app.html's own folder on BOTH mounts (OS
507
+ // root AND /Q), so the registration always lands on the mount actually serving this page. Do not re-absolutise.
508
+ import("./messenger-sw-register.mjs").catch(() => {});
509
+ // Q SUMMON — tap the home orb and the canvas MORPHS into Q (View Transitions pair the orb corner→face),
510
+ // Q greets OUT LOUD at the tap (the tap IS the autoplay gesture), the HD voice + Q's BitNet brain pre-warm
511
+ // while home idles (window.HoloQ.warm — standalone-parity TTFT), and every Q-thread message is sealed to a
512
+ // BLAKE3 κ chain (did:holo:blake3, hash-linked, verified on load). Additive + fail-soft.
513
+ import("./q-summon.mjs?v=18").catch(() => {});
514
+ // Q LIVE CALL — tap Call in the hero → realtime voice conversation (createQLive: streaming voice,
515
+ // hands-free turns, barge-in). Additive + fail-soft: no mic/WebGPU → a clear message, chat still works.
516
+ import("./q-live-hero.mjs?v=4").catch(() => {});
517
+ // POWER & SESSION — one power button at the very bottom of the rail. Tap → a calm sheet in the sign-in's own
518
+ // teal vocabulary: live session uptime + who you are + Lock & Sign Out (window.holo.signOut → the clean gate,
519
+ // box secured). Additive + fail-soft: no rail / no signOut → the control just doesn't appear.
520
+ import("./holo-power-session.mjs?v=3").catch(() => {});
521
+ // KEYBOARD LAYER — the native CEF browser's shortcut system, ported to the web (DESKTOP MODE ONLY): the
522
+ // ambient "hold-Ctrl" hint dot, Ctrl K spotlight, Ctrl ⇧ P command palette, ? cheat sheet, Esc to dismiss,
523
+ // Ctrl ]/[ to cycle conversations — one dependency-free engine (holo-keys), every action content-addressed.
524
+ // Self-gating: mounts nothing on touch/narrow, inside the native shell, or when embedded. Fail-soft.
525
+ import("./holo-messenger-keys.mjs?v=5").catch(() => {});
526
+ // HOLO DIRECT — the NATIVE holospace↔holospace sealed chat (dual-path engine: P2P WebRtcLink fast-path via
527
+ // sealed-SDP rendezvous over the blind mailbox, mailbox fallback; TOFU + safety number + key-change). One 🔐
528
+ // rail button; the 3 MB spine wasm loads on FIRST use only (cold boot pays nothing). Additive + fail-soft.
529
+ import("./holo-direct-mount.mjs?v=70a9ff7a3e4d").catch(() => {});
530
+ // IMMERSIVE VIDEO — chromeless YouTube embed + a hover-only Holo control bar (play/pause · seek · time ·
531
+ // fullscreen). Additive + fail-soft.
532
+ import("./holo-video-immersive.mjs?v=22eef34f49d2").catch(() => {});
533
+ </script>
534
+ <style id="hl-fontsize-uniform">/* CLAUDE-FONTSIZE ⤵ — login: one uniform text size (var(--u)), larger */
535
+ #holo-login{--u:clamp(19px,2vmin,23px)}
536
+ #holo-login .hl-name{font-size:var(--u)}
537
+ #holo-login .hl-alt{font-size:var(--u)}
538
+ /* ⤴ */</style>
539
+ </body></html>
sha256/543f372b4fffa7fb10f9daca3f52f737efaea8c84906758e6cd5ba2c5f1a7ab5 ADDED
The diff for this file is too large to render. See raw diff
 
sha256/5d86fac19fe2b8ef18160a86bb2914d56ce18f156e0dc2592cd622e1a291f5f0 ADDED
The diff for this file is too large to render. See raw diff
 
sha256/e3a7387f103315f9bb2e3356ddd39172f6ffd27e63974054096cf5739e6c4395 ADDED
The diff for this file is too large to render. See raw diff
 
sha256/f9697444f6098396afd5574c92dc0bae8e93779040f15eb425dfb8b5aac13475 ADDED
The diff for this file is too large to render. See raw diff