retire-provenance: superseded Q b/ objects (sha256 CAS, HOLO-LEAN-RESOLVER P1.3)
Browse files- sha256/0938ae54389aad007a2574cbe3641ef80db0f09701a41c51c04e5c6639e12af5 +1 -0
- sha256/0a65550d027ecaf8ee3e58e6c9221a09c376a3ea4cd8283e6376baeae525bab6 +539 -0
- sha256/543f372b4fffa7fb10f9daca3f52f737efaea8c84906758e6cd5ba2c5f1a7ab5 +0 -0
- sha256/5d86fac19fe2b8ef18160a86bb2914d56ce18f156e0dc2592cd622e1a291f5f0 +0 -0
- sha256/e3a7387f103315f9bb2e3356ddd39172f6ffd27e63974054096cf5739e6c4395 +0 -0
- sha256/f9697444f6098396afd5574c92dc0bae8e93779040f15eb425dfb8b5aac13475 +0 -0
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 ({ "&":"&","<":"<",">":">",'"':""" }[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
|
|
|