File size: 28,919 Bytes
9a1c501
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a4b1991
 
 
 
 
 
 
 
 
 
0a70aab
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a4b1991
9a1c501
5684452
55e5019
9a1c501
 
 
 
 
 
 
 
 
 
 
a4b1991
9a1c501
 
a4b1991
 
 
 
 
 
9a1c501
0a70aab
 
 
 
 
 
 
 
 
 
 
 
 
 
9a1c501
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a4b1991
9a1c501
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a4b1991
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9a1c501
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a4b1991
9a1c501
 
 
 
 
 
 
 
 
 
 
 
 
 
a4b1991
9a1c501
a4b1991
 
 
9a1c501
 
 
 
 
a4b1991
9a1c501
 
a4b1991
 
9a1c501
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0a70aab
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9a1c501
 
 
 
 
a4b1991
 
9a1c501
a4b1991
9a1c501
a4b1991
 
 
 
9a1c501
 
 
 
 
 
 
5684452
55e5019
9a1c501
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<!--
  KHIPU — Sovereign Ledger. A single screen fusing the whole SZL organism's
  HEALTH and SPEND into one living knotted-cord record (khipu: the Andean
  tactile ledger — a one-of-one metaphor for a hash-linked spend chain).

  Doctrine: 0 runtime CDN, 0 build step, pure inline CSS/JS. Honest by
  construction — every figure renders only if its own feed answered; nulls show
  "—", a dead feed shows "unreachable", nothing is ever fabricated. Frugal by
  construction — the SVG is rebuilt only on the 15s refresh; motion is CSS-only
  (GPU-composited), no requestAnimationFrame loop burns CPU.

  Feeds (all same-origin, all free):
    GET /api/a11oy/v1/engine/status   (szl.engine_status/v1)   — organs, mind, energy
    GET /api/a11oy/v1/spend/state     (szl_spend_cap)          — cap, spent, kill, chain
    GET /api/a11oy/v1/constellation   (szl.constellation_status/v1) — estate surfaces
-->
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>KHIPU · Sovereign Ledger</title>
<style>
  :root{
    --void:#080c14; --void2:#0b1220; --panel:#0d1524; --line:#173049;
    --teal:#3af4c8; --teal-dim:#1c8f78; --amber:#f5a623; --amber-dim:#7a5410;
    --red:#ff5470; --ink:#e8f6f1; --mute:#6f8c9c;
    --mono:ui-monospace,"SF Mono",Menlo,Consolas,monospace;
    --sans:"Inter",system-ui,-apple-system,Segoe UI,Roboto,sans-serif;
  }
  *{box-sizing:border-box}
  html,body{margin:0;height:100%}
  body{
    background:
      radial-gradient(1200px 700px at 78% -10%, rgba(58,244,200,.08), transparent 60%),
      radial-gradient(900px 600px at 8% 110%, rgba(245,166,35,.06), transparent 60%),
      var(--void);
    color:var(--ink); font-family:var(--sans); -webkit-font-smoothing:antialiased;
    display:flex; flex-direction:column; min-height:100%;
  }
  a{color:inherit;text-decoration:none}
  .wrap{max-width:1280px;width:100%;margin:0 auto;padding:22px 22px 40px;flex:1;display:flex;flex-direction:column}
  /* header */
  header{display:flex;align-items:flex-end;justify-content:space-between;gap:16px;flex-wrap:wrap;margin-bottom:18px}
  .brand{display:flex;align-items:baseline;gap:14px}
  .brand h1{font-family:var(--mono);font-size:30px;letter-spacing:.42em;margin:0;font-weight:600;
    background:linear-gradient(90deg,var(--teal),#bfeee2);-webkit-background-clip:text;background-clip:text;color:transparent}
  .brand .tag{color:var(--mute);font-size:12.5px;letter-spacing:.02em}
  .brand .tag b{color:var(--teal-dim);font-weight:600}
  .clock{font-family:var(--mono);font-size:11.5px;color:var(--mute);text-align:right;line-height:1.7}
  .clock .dot{display:inline-block;width:7px;height:7px;border-radius:50%;background:var(--teal);margin-right:6px;
    box-shadow:0 0 8px var(--teal);animation:beat 2.4s ease-in-out infinite}
  /* stat strip */
  .strip{display:grid;grid-template-columns:repeat(4,1fr);gap:12px;margin-bottom:14px}
  .lamps{display:grid;grid-template-columns:repeat(4,1fr);gap:12px;margin-bottom:20px}
  .card{background:linear-gradient(180deg,var(--panel),var(--void2));border:1px solid var(--line);
    border-radius:14px;padding:15px 17px;position:relative;overflow:hidden}
  .card::before{content:"";position:absolute;inset:0 auto 0 0;width:3px;background:var(--teal-dim);opacity:.6}
  .card.amber::before{background:var(--amber)}
  .card.red::before{background:var(--red)}
  .card .k{font-size:10.5px;letter-spacing:.18em;text-transform:uppercase;color:var(--mute)}
  .card .v{font-family:var(--mono);font-size:29px;margin-top:7px;line-height:1;letter-spacing:-.01em}
  .card .v small{font-size:14px;color:var(--mute)}
  .card.amber .v{color:var(--amber)}
  .card .sub{font-size:11px;color:var(--mute);margin-top:7px;font-family:var(--mono)}
  /* lamps */
  .lamp{display:flex;align-items:center;gap:11px;background:var(--void2);border:1px solid var(--line);
    border-radius:12px;padding:13px 15px}
  .lamp .bulb{width:12px;height:12px;border-radius:50%;flex:none;background:var(--mute);box-shadow:0 0 0 rgba(0,0,0,0)}
  .lamp.ok .bulb{background:var(--teal);box-shadow:0 0 12px var(--teal);animation:beat 2.6s ease-in-out infinite}
  .lamp.warn .bulb{background:var(--amber);box-shadow:0 0 12px var(--amber)}
  .lamp.bad .bulb{background:var(--red);box-shadow:0 0 14px var(--red);animation:beat 1s ease-in-out infinite}
  .lamp .lt{display:flex;flex-direction:column;gap:2px;min-width:0}
  .lamp .lt .n{font-size:10px;letter-spacing:.16em;text-transform:uppercase;color:var(--mute)}
  .lamp .lt .s{font-family:var(--mono);font-size:15px;letter-spacing:.02em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .lamp.ok .s{color:var(--teal)} .lamp.warn .s{color:var(--amber)} .lamp.bad .s{color:var(--red)}
  /* khipu */
  .khipu{background:linear-gradient(180deg,rgba(13,21,36,.7),rgba(8,12,20,.7));
    border:1px solid var(--line);border-radius:16px;padding:8px 6px 4px;flex:1;min-height:360px;position:relative}
  .khipu svg{display:block;width:100%;height:100%}
  .cordwrap{transform-box:fill-box;transform-origin:top center}
  .sway0{animation:sway 7s ease-in-out infinite}
  .sway1{animation:sway 8.5s ease-in-out infinite;animation-delay:-2s}
  .sway2{animation:sway 6.2s ease-in-out infinite;animation-delay:-4s}
  .knot{transform-box:fill-box;transform-origin:center}
  .knot.live{animation:pulse 2.8s ease-in-out infinite}
  .lgd{display:flex;gap:18px;flex-wrap:wrap;justify-content:center;margin-top:6px;color:var(--mute);font-size:11px}
  .lgd i{display:inline-block;width:9px;height:9px;border-radius:50%;margin-right:6px;vertical-align:middle}
  footer{margin-top:16px;color:var(--mute);font-size:11.5px;text-align:center;line-height:1.7}
  footer b{color:var(--teal-dim)}
  @keyframes beat{0%,100%{opacity:1}50%{opacity:.35}}
  @keyframes pulse{0%,100%{opacity:1;transform:scale(1)}50%{opacity:.5;transform:scale(1.55)}}
  @keyframes sway{0%,100%{transform:translateX(-3px) rotate(-.5deg)}50%{transform:translateX(3px) rotate(.5deg)}}
  @media (max-width:760px){.strip,.lamps{grid-template-columns:repeat(2,1fr)}.brand h1{font-size:22px;letter-spacing:.3em}}
  @media (prefers-reduced-motion:reduce){*{animation:none!important}}
  /* federated (authoritative box) spend panel */
  .localttl{font-family:var(--mono);font-size:10.5px;letter-spacing:.14em;text-transform:uppercase;color:var(--mute);margin:2px 2px 8px}
  .fedwrap{margin:6px 0 18px;padding:14px 15px 15px;border:1px solid var(--teal-dim);border-radius:14px;
    background:linear-gradient(180deg,rgba(58,244,200,.05),rgba(8,12,20,.5))}
  .fedttl{font-family:var(--mono);font-size:12.5px;letter-spacing:.06em;color:var(--ink);margin-bottom:6px;display:flex;align-items:center;gap:10px;flex-wrap:wrap}
  .fedttl .badge{font-size:9.5px;letter-spacing:.16em;background:var(--teal);color:#04241d;padding:3px 8px;border-radius:20px;font-weight:700}
  .fedttl .fedsrc{color:var(--mute);font-size:10.5px;letter-spacing:.02em}
  .fednote{color:var(--mute);font-size:10.5px;margin:0 0 12px;line-height:1.5}
  .fedwrap .strip{margin-bottom:12px}
  .fedwrap .lamps{margin-bottom:0}
  /* governed frontier console */
  .frin,.frta{width:100%;background:rgba(8,12,20,.7);border:1px solid var(--line);color:var(--ink);
    font-family:var(--mono);font-size:12px;border-radius:9px;padding:9px 10px;outline:none;box-sizing:border-box}
  .frin:focus,.frta:focus{border-color:var(--teal-dim)}
  .frta{resize:vertical;min-height:40px;line-height:1.5}
  .frrow{display:flex;gap:8px;align-items:flex-start;margin:8px 0}
  .frbtn{white-space:nowrap;background:var(--teal);color:#04241d;border:none;font-weight:700;
    font-family:var(--mono);font-size:11.5px;letter-spacing:.04em;padding:9px 14px;border-radius:9px;cursor:pointer}
  .frbtn.ghost{background:transparent;color:var(--teal-dim);border:1px solid var(--teal-dim);font-weight:600}
  .frbtn:disabled{opacity:.45;cursor:default}
  .frout{margin-top:6px}
  .frchips{display:flex;flex-wrap:wrap;gap:6px;margin:8px 0}
  .chip{font-family:var(--mono);font-size:10px;letter-spacing:.04em;padding:3px 8px;border-radius:20px;
    border:1px solid var(--line);color:var(--mute);background:rgba(8,12,20,.5)}
  .chip.ok{border-color:var(--teal-dim);color:var(--teal);background:rgba(58,244,200,.08)}
  .chip.bad{border-color:#ff5470;color:#ff5470;background:rgba(255,84,112,.08)}
  .chip.amber{border-color:#f5a623;color:#f5a623;background:rgba(245,166,35,.08)}
  .franswer{white-space:pre-wrap;font-size:13px;line-height:1.55;color:var(--ink);background:rgba(8,12,20,.5);
    border:1px solid var(--line);border-radius:10px;padding:11px 12px;margin:6px 0}
  .frraw{margin-top:6px}
  .frraw summary{cursor:pointer;color:var(--mute);font-family:var(--mono);font-size:10.5px;letter-spacing:.04em}
  .frraw pre{white-space:pre-wrap;word-break:break-all;font-family:var(--mono);font-size:10px;color:var(--mute);
    background:rgba(8,12,20,.6);border:1px solid var(--line);border-radius:8px;padding:10px;margin:6px 0 0;max-height:220px;overflow:auto}

</style>
  <link rel="stylesheet" href="/assets/szl-flow.css" data-szl-flow-asset="style" />
  <link rel="stylesheet" href="/assets/szl-holo-v2.css" data-szl-holo-asset="style-v2" />
</head>
<body>
<div class="wrap">
  <header>
    <div class="brand">
      <h1>KHIPU</h1>
      <div class="tag">Sovereign Ledger &mdash; the whole organism's <b>health</b> &amp; <b>spend</b>, one screen &middot; honest by construction</div>
    </div>
    <div class="clock"><span><span class="dot"></span><span id="live">live</span></span><br/><span id="ts">&mdash;</span></div>
  </header>

  <div class="localttl">a11oy module ledger &mdash; local / advisory (in-container)</div>
  <section class="strip" id="strip"></section>
  <section class="lamps" id="lamps"></section>
  <section class="fedwrap">
    <div class="fedttl"><span class="badge">AUTHORITATIVE</span> Live Sovereign Router &mdash; real paid spend on the box ledger <span class="fedsrc" id="fedsrc">&mdash;</span></div>
    <div class="fednote">read live from the box router at request time &middot; chain state as reported by the source &middot; never summed with the local advisory ledger above</div>
    <div class="strip" id="fedstrip"></div>
    <div class="lamps" id="fedlamps"></div>
  </section>

  <section class="fedwrap frontier">
    <div class="fedttl"><span class="badge">GOVERNED</span> Frontier Console &mdash; one capped call, receipt verified locally <span class="fedsrc" id="frstate">&mdash;</span></div>
    <div class="fednote">operator-gated &middot; model pinned &middot; max 256 tokens &middot; 8s cooldown &middot; 50/day &middot; the box router meters &amp; kill-switches every call. a11oy verifies the DSSE / ECDSA-P256 receipt against a <b>pinned</b> key &mdash; the router is never trusted, the math is checked here.</div>
    <div class="frrow">
      <input id="frop" class="frin" type="password" autocomplete="off" spellcheck="false" placeholder="operator token (kept only in this browser)"/>
      <button id="frsave" class="frbtn ghost" type="button">remember</button>
    </div>
    <div class="frrow">
      <textarea id="frprompt" class="frta" rows="2" maxlength="600" placeholder="Ask the sovereign router something&hellip; (governed, capped, receipted &middot; &#8984;/Ctrl+Enter)"></textarea>
      <button id="frask" class="frbtn" type="button">Ask &rarr;</button>
    </div>
    <div id="frout" class="frout"></div>
  </section>

  <section class="khipu"><div id="khipu"></div></section>
  <div class="lgd">
    <span><i style="background:#3af4c8"></i>live / intact</span>
    <span><i style="background:#f5a623"></i>spend</span>
    <span><i style="background:#ff5470"></i>down / tripped</span>
    <span><i style="background:#6f8c9c"></i>unknown / &mdash;</span>
  </div>

  <footer>
    Every value comes from a live feed; a silent source renders <b>&mdash;</b> or <b>unreachable</b>, never fake-green (Doctrine v11).
    &nbsp;&middot;&nbsp; Free-first: sovereign compute + free grid; paid inference is capped and kill-switched, never quiet.
    &nbsp;&middot;&nbsp; refresh 15s
  </footer>
</div>

<script>
(function(){
  "use strict";
  var $=function(id){return document.getElementById(id)};
  function esc(s){return String(s==null?"":s).replace(/[&<>"]/g,function(c){return {"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;"}[c]})}
  function money(x){ if(x==null||isNaN(x)) return null; return "$"+Number(x).toLocaleString(undefined,{minimumFractionDigits:2,maximumFractionDigits:2}); }
  function money6(x){ if(x==null||isNaN(x)) return null; var n=Number(x); if(n===0) return "$0.00"; if(Math.abs(n)<0.01) return "$"+n.toFixed(6); return "$"+n.toLocaleString(undefined,{minimumFractionDigits:2,maximumFractionDigits:2}); }
  function fetchJSON(url){
    return fetch(url,{headers:{accept:"application/json"},cache:"no-store"})
      .then(function(r){ if(!r.ok) throw new Error("HTTP "+r.status); return r.json(); })
      .catch(function(){ return null; });
  }
  // reachability, tolerant of several honest shapes
  function reach(o){
    if(!o||typeof o!=="object") return null;
    var v = (o.reachable!=null?o.reachable : (o.ok!=null?o.ok : (o.up!=null?o.up : (o.alive!=null?o.alive : null))));
    if(v==null && typeof o.status==="string") v = /^(up|live|ok|ready|running|healthy)$/i.test(o.status);
    return v;
  }
  function stateClass(v){ return v===true?"live":(v===false?"down":"na"); }
  function colorOf(v){ return v===true?"#3af4c8":(v===false?"#ff5470":"#6f8c9c"); }

  // ---------- cockpit strip + lamps (from spend/state) ----------
  function renderSpend(sp){
    var strip=$("strip"), lamps=$("lamps");
    if(!sp){
      strip.innerHTML = '<div class="card red"><div class="k">Spend ledger</div><div class="v">unreachable</div><div class="sub">the spend feed did not answer</div></div>';
      lamps.innerHTML=""; return;
    }
    var cap=sp.cap_usd, spent=sp.spent_usd, rem=sp.remaining_usd, pct=sp.pct_used;
    var overspend = (rem!=null && rem<=0);
    strip.innerHTML =
      card("Hard cap", money(cap), "ceiling · $"+ (cap!=null?cap:"—"), "") +
      card("Spent", money(spent)||"—", (sp.entries!=null?sp.entries+" ledger entries":""), "amber") +
      card("Remaining", money(rem)||"—", "", overspend?"red":"") +
      card("Utilisation", (pct!=null? pct+"% ":"—"), bar(pct), pct!=null&&pct>=90?"red":(pct!=null&&pct>=60?"amber":""));

    lamps.innerHTML =
      lamp("Spend cap", sp.armed===true?"ARMED":"—", sp.armed===true?"ok":"na") +
      lamp("Status", sp.tripped===true?"TRIPPED":(sp.tripped===false?"CLEAR":"—"), sp.tripped===true?"bad":(sp.tripped===false?"ok":"na")) +
      lamp("Kill-switch", sp.kill_file_engaged===true?"ENGAGED":(sp.kill_file_engaged===false?"ready":"—"), sp.kill_file_engaged===true?"bad":(sp.kill_file_engaged===false?"ok":"na")) +
      lamp("Ledger chain", (sp.chain&&sp.chain.intact===true)?"INTACT":((sp.chain&&sp.chain.intact===false)?"BROKEN":"—"), (sp.chain&&sp.chain.intact===true)?"ok":((sp.chain&&sp.chain.intact===false)?"bad":"na"));
  }
  function card(k,v,sub,cls){
    return '<div class="card '+(cls||"")+'"><div class="k">'+esc(k)+'</div><div class="v">'+(v==null?"&mdash;":v)+'</div>'+(sub?'<div class="sub">'+sub+'</div>':'')+'</div>';
  }
  function bar(pct){
    if(pct==null) return "";
    var p=Math.max(0,Math.min(100,pct));
    var col = p>=90?"#ff5470":(p>=60?"#f5a623":"#3af4c8");
    return '<div style="height:5px;border-radius:3px;background:#122;overflow:hidden;margin-top:8px"><div style="height:100%;width:'+p+'%;background:'+col+'"></div></div>';
  }
  function lamp(n,s,cls){
    return '<div class="lamp '+cls+'"><span class="bulb"></span><span class="lt"><span class="n">'+esc(n)+'</span><span class="s">'+esc(s)+'</span></span></div>';
  }

  // ---------- federated (authoritative box-router) spend panel ----------
  function renderFed(fs){
    var strip=$("fedstrip"), lamps=$("fedlamps"), src=$("fedsrc");
    if(!strip) return;
    function down(msg,sub,cls){ strip.innerHTML='<div class="card '+(cls||"")+'"><div class="k">Router spend</div><div class="v">'+esc(msg)+'</div>'+(sub?'<div class="sub">'+esc(sub)+'</div>':'')+'</div>'; lamps.innerHTML=""; src.textContent=""; }
    if(!fs){ down("unreachable","the federation feed did not answer","red"); return; }
    if(fs.state==="not_configured"){ down("not configured","set SZL_ROUTER_SPEND_URL to federate the box ledger",""); return; }
    if(fs.state!=="live" || fs.reachable!==true){ down("unreachable","box router did not answer (http "+(fs.http_status!=null?fs.http_status:"?")+")","red"); return; }
    var cap=fs.cap_usd, spent=fs.spent_usd, rem=fs.remaining_usd, pct=fs.pct_used;
    var overspend=(rem!=null && rem<=0);
    strip.innerHTML =
      card("Hard cap", money6(cap), "ceiling", "") +
      card("Spent (real, paid)", money6(spent)||"&mdash;", (fs.entries!=null?fs.entries+" ledger entries":""), "amber") +
      card("Remaining", money6(rem)||"&mdash;", "", overspend?"red":"") +
      card("Utilisation", (pct!=null? pct+"% ":"&mdash;"), bar(pct), pct!=null&&pct>=90?"red":(pct!=null&&pct>=60?"amber":""));
    lamps.innerHTML =
      lamp("Spend cap", fs.armed===true?"ARMED":"\u2014", fs.armed===true?"ok":"na") +
      lamp("Status", fs.tripped===true?"TRIPPED":(fs.tripped===false?"CLEAR":"\u2014"), fs.tripped===true?"bad":(fs.tripped===false?"ok":"na")) +
      lamp("Kill-switch", fs.kill_file_engaged===true?"ENGAGED":(fs.kill_file_engaged===false?"ready":"\u2014"), fs.kill_file_engaged===true?"bad":(fs.kill_file_engaged===false?"ok":"na")) +
      lamp("Ledger chain", fs.chain_intact===true?"INTACT":(fs.chain_intact===false?"BROKEN":"\u2014"), fs.chain_intact===true?"ok":(fs.chain_intact===false?"bad":"na"));
    var when = fs.upstream_generated || fs.checked_at || "";
    src.textContent = (when? "\u00b7 as of "+when : "") + (fs.cache? " ("+fs.cache+")":"");
  }

  // ---------- the khipu (organs + spend sources + estate) ----------
  var VW=1200, VH=460, TOP=78, BASE=430;
  function pendant(x, len, knots, cls, label, swayCls){
    var bx = x + (Math.sin(x)*8);              // gentle static bow, deterministic
    var path = 'M '+x+' '+TOP+' Q '+((x+bx)/2)+' '+((TOP+len)/2)+' '+bx+' '+len;
    var s = '<g class="cordwrap '+swayCls+'">';
    s += '<path d="'+path+'" fill="none" stroke="'+colorOf(cls==="live"?true:(cls==="down"?false:null))+'" stroke-width="1.6" opacity="'+(cls==="na"?.4:.75)+'"/>';
    var n = Math.max(1, knots|0);
    for(var i=0;i<n;i++){
      var t=(i+1)/(n+1);
      var kx = x + (bx-x)*t, ky = TOP + (len-TOP)*t;
      var kn = (cls==="live"?"knot live":"knot");
      s += '<circle class="'+kn+'" cx="'+kx.toFixed(1)+'" cy="'+ky.toFixed(1)+'" r="'+(cls==="down"?4.6:4)+'" fill="'+colorOf(cls==="live"?true:(cls==="down"?false:null))+'" opacity="'+(cls==="na"?.5:.95)+'" style="animation-delay:'+(i*0.3).toFixed(1)+'s"/>';
    }
    s += '<circle cx="'+x+'" cy="'+TOP+'" r="2.6" fill="#bfeee2"/>';
    s += '<text x="'+bx.toFixed(1)+'" y="'+(len+16)+'" text-anchor="middle" font-family="ui-monospace,Menlo,monospace" font-size="10" fill="#6f8c9c">'+esc(label)+'</text>';
    s += '</g>';
    return s;
  }
  function sectionLabel(cx, text){
    return '<text x="'+cx+'" y="44" text-anchor="middle" font-family="ui-monospace,Menlo,monospace" font-size="11" letter-spacing="3" fill="#3af4c8" opacity=".8">'+esc(text)+'</text>';
  }
  function spread(x0,x1,n){ var a=[]; if(n<=0) return a; if(n===1){a.push((x0+x1)/2);return a;} for(var i=0;i<n;i++)a.push(x0+(x1-x0)*i/(n-1)); return a; }

  function renderKhipu(eng, sp, con, fed){
    var svg='<svg viewBox="0 0 '+VW+' '+VH+'" preserveAspectRatio="xMidYMid meet" role="img" aria-label="Sovereign khipu">';
    svg += '<line x1="48" y1="'+TOP+'" x2="'+(VW-48)+'" y2="'+TOP+'" stroke="#173049" stroke-width="3" stroke-linecap="round"/>';
    // section 1: VITALS (organs)
    var organs = (eng&&eng.organs&&typeof eng.organs==="object")?eng.organs:null;
    svg += sectionLabel(250,"VITALS");
    if(organs){
      var names=Object.keys(organs); var xs=spread(90,430,Math.max(1,names.length));
      for(var i=0;i<names.length;i++){
        var v=reach(organs[names[i]]); var len=BASE-((i%3)*26);
        svg += pendant(xs[i], len, 3, stateClass(v), names[i].slice(0,7), "sway0");
      }
      if(!names.length) svg += emptyCord(250,"no organs reported","sway0");
    } else svg += emptyCord(250, eng?"no organ data":"engine unreachable","sway0");

    // section 2: SPEND (real box-router ledger; falls back to local advisory)
    svg += sectionLabel(600,"SPEND");
    var spendSrc = (fed && fed.state==="live" && fed.reachable===true) ? fed : sp;
    if(spendSrc){
      var tail=(spendSrc.tail&&spendSrc.tail.length)?spendSrc.tail.slice(-6):[];
      if(tail.length){
        var total=tail.reduce(function(a,e){return a+(+e.amount_usd||0)},0)||1;
        var xs2=spread(480,720,tail.length);
        for(var j=0;j<tail.length;j++){
          var amt=+tail[j].amount_usd||0; var kk=Math.max(1,Math.min(9,Math.round(1+8*(amt/total))));
          svg += pendantAmber(xs2[j], BASE-((j%2)*30), kk, (tail[j].source||"?").slice(0,8), money6(amt)||"", "sway1");
        }
      } else {
        var sv=(spendSrc.spent_usd!=null?spendSrc.spent_usd:null);
        svg += emptyCord(600, (sv? money6(sv):"$0.00")+" spent","sway1");
      }
    } else svg += emptyCord(600,"spend unreachable","sway1");

    // section 3: ESTATE (constellation surfaces)
    svg += sectionLabel(955,"ESTATE");
    var surfaces = con && (Array.isArray(con.surfaces)?con.surfaces:(Array.isArray(con)?con:null));
    if(surfaces){
      var ss=surfaces.slice(0,9); var xs3=spread(772,1140,Math.max(1,ss.length));
      for(var k=0;k<ss.length;k++){
        var s=ss[k]; var v3=reach(s); var nm=(s.name||s.id||s.slug||"?");
        svg += pendant(xs3[k], BASE-((k%3)*24), 2, stateClass(v3), String(nm).slice(0,9), "sway2");
      }
      if(!ss.length) svg += emptyCord(955,"no surfaces reported","sway2");
    } else svg += emptyCord(955, con?"no estate data":"constellation unreachable","sway2");

    svg += '</svg>';
    $("khipu").innerHTML = svg;
  }
  function pendantAmber(x,len,knots,label,val,swayCls){
    var bx=x+(Math.sin(x)*8);
    var path='M '+x+' '+TOP+' Q '+((x+bx)/2)+' '+((TOP+len)/2)+' '+bx+' '+len;
    var s='<g class="cordwrap '+swayCls+'"><path d="'+path+'" fill="none" stroke="#f5a623" stroke-width="1.6" opacity=".8"/>';
    var n=Math.max(1,knots|0);
    for(var i=0;i<n;i++){var t=(i+1)/(n+1);var kx=x+(bx-x)*t,ky=TOP+(len-TOP)*t;
      s+='<circle cx="'+kx.toFixed(1)+'" cy="'+ky.toFixed(1)+'" r="3.7" fill="#f5a623" opacity=".95"/>';}
    s+='<circle cx="'+x+'" cy="'+TOP+'" r="2.6" fill="#f5d18a"/>';
    s+='<text x="'+bx.toFixed(1)+'" y="'+(len+16)+'" text-anchor="middle" font-family="ui-monospace,Menlo,monospace" font-size="10" fill="#a9803a">'+esc(label)+'</text>';
    s+='<text x="'+bx.toFixed(1)+'" y="'+(len+28)+'" text-anchor="middle" font-family="ui-monospace,Menlo,monospace" font-size="9" fill="#6f8c9c">'+esc(val)+'</text></g>';
    return s;
  }
  function emptyCord(cx,text,swayCls){
    return '<g class="cordwrap '+swayCls+'"><line x1="'+cx+'" y1="'+TOP+'" x2="'+cx+'" y2="'+(TOP+120)+'" stroke="#173049" stroke-width="1.4" stroke-dasharray="3 5"/>'+
      '<circle cx="'+cx+'" cy="'+TOP+'" r="2.6" fill="#3a5568"/>'+
      '<text x="'+cx+'" y="'+(TOP+140)+'" text-anchor="middle" font-family="ui-monospace,Menlo,monospace" font-size="10.5" fill="#6f8c9c">'+esc(text)+'</text></g>';
  }

  // ---------- governed frontier console ----------
  var FR_KEY="szl_frontier_op";
  function frToken(){ try{return localStorage.getItem(FR_KEY)||"";}catch(e){return "";} }
  function frChip(label,cls){ return '<span class="chip '+(cls||"")+'">'+esc(label)+'</span>'; }
  function frRender(d){
    var out=$("frout"), st=$("frstate");
    if(!d){ out.innerHTML='<div class="franswer">the console could not reach a11oy (network).</div>'; st.textContent="\u2014"; return; }
    var s=d.state||"?";
    var label={verified:"RECEIPT VERIFIED",verify_failed:"VERIFY FAILED",receipt_unsigned:"UNSIGNED",receipt_missing:"NO RECEIPT",receipt_unparseable:"BAD RECEIPT",not_configured:"NOT CONFIGURED",unauthorized:"UNAUTHORIZED",bad_request:"BAD REQUEST",unreachable:"ROUTER UNREACHABLE",cooldown:"COOLDOWN",daily_cap:"DAILY CAP",busy:"BUSY"}[s]||String(s).toUpperCase();
    var cls=(s==="verified")?"ok":((s==="verify_failed"||s==="unauthorized"||s==="unreachable")?"bad":"amber");
    st.innerHTML=frChip(label,cls);
    if(s==="not_configured"){ out.innerHTML='<div class="franswer">Frontier edge/operator not provisioned yet.</div>'; return; }
    if(s==="unauthorized"){ out.innerHTML='<div class="franswer">Operator token rejected. Paste your token above and try again.</div>'; return; }
    if(s==="cooldown"){ out.innerHTML='<div class="franswer">Cooling down &mdash; retry in '+esc(d.retry_after_s)+'s (governance).</div>'; return; }
    if(s==="daily_cap"){ out.innerHTML='<div class="franswer">Daily governed-call cap reached ('+esc(d.daily_cap)+').</div>'; return; }
    if(s==="busy"){ out.innerHTML='<div class="franswer">A governed call is already in flight &mdash; one at a time.</div>'; return; }
    if(s==="unreachable"){ out.innerHTML='<div class="franswer">Box router did not answer (http '+esc(d.http_status)+').</div>'; return; }
    if(s==="bad_request"){ out.innerHTML='<div class="franswer">'+esc(d.detail||"bad request")+'</div>'; return; }
    var html="";
    if(d.answer){ html+='<div class="franswer">'+esc(d.answer)+'</div>'; }
    var r=d.receipt||{}, p=d.provenance||{}, u=d.usage||{};
    var chips="";
    chips+=frChip((r.verified?"\u2713 ":"\u2717 ")+"DSSE "+(r.verified?"verified":(r.reason||"unverified")), r.verified?"ok":"bad");
    if(p.tier) chips+=frChip("tier "+p.tier,"");
    if(p.served_by) chips+=frChip("via "+p.served_by,"");
    if(p.upstream_model||p.model) chips+=frChip("model "+(p.upstream_model||p.model),"");
    if(p.amount_usd!=null) chips+=frChip((p.estimated?"~":"")+(money6(p.amount_usd)||"$0.00")+" this call","amber");
    if(u.total_tokens!=null) chips+=frChip(u.total_tokens+" tok","");
    if(r.keyid) chips+=frChip("keyid "+String(r.keyid).slice(0,12),"");
    if(r.organ) chips+=frChip("organ "+r.organ,"");
    if(p.request_digest) chips+=frChip("req "+String(p.request_digest).slice(0,10),"");
    html+='<div class="frchips">'+chips+'</div>';
    if(d.envelope){ html+='<details class="frraw"><summary>raw DSSE receipt &mdash; verify it yourself</summary><pre>'+esc(JSON.stringify(d.envelope,null,2))+'</pre></details>'; }
    out.innerHTML=html;
  }
  function frAsk(){
    var tok=(($("frop").value||"")||frToken()).trim();
    var prompt=($("frprompt").value||"").trim();
    var btn=$("frask");
    if(!prompt){ $("frprompt").focus(); return; }
    btn.disabled=true; $("frstate").innerHTML='<span class="chip amber">calling\u2026</span>';
    $("frout").innerHTML='<div class="franswer">routing one governed call\u2026</div>';
    fetch("/api/a11oy/v1/frontier/ask",{method:"POST",cache:"no-store",
      headers:{"content-type":"application/json","accept":"application/json","x-szl-operator":tok},
      body:JSON.stringify({prompt:prompt})})
      .then(function(r){ return r.json().catch(function(){return null;}); })
      .then(function(d){ frRender(d); })
      .catch(function(){ frRender(null); })
      .then(function(){ btn.disabled=false; });
  }
  (function frInit(){
    var op=$("frop"); if(op){ var t=frToken(); if(t) op.value=t; }
    var save=$("frsave"); if(save) save.addEventListener("click",function(){ try{ localStorage.setItem(FR_KEY,($("frop").value||"").trim()); save.textContent="saved"; setTimeout(function(){save.textContent="remember";},1200);}catch(e){} });
    var ask=$("frask"); if(ask) ask.addEventListener("click",frAsk);
    var pr=$("frprompt"); if(pr) pr.addEventListener("keydown",function(e){ if((e.metaKey||e.ctrlKey)&&e.key==="Enter"){ e.preventDefault(); frAsk(); } });
  })();

  // ---------- tick ----------
  function tick(){
    Promise.all([
      fetchJSON("/api/a11oy/v1/engine/status"),
      fetchJSON("/api/a11oy/v1/spend/state"),
      fetchJSON("/api/a11oy/v1/constellation"),
      fetchJSON("/api/a11oy/v1/spend/federated")
    ]).then(function(res){
      var eng=res[0], sp=res[1], con=res[2], fed=res[3];
      renderSpend(sp);
      renderFed(fed);
      renderKhipu(eng, sp, con, fed);
      var live=$("live"); live.textContent = (fed||sp)?"live":"degraded";
      live.style.color = (fed||sp)?"#3af4c8":"#ff5470";
      $("ts").textContent = new Date().toISOString().replace("T"," ").replace(/\..+/,"Z");
    });
  }
  tick();
  setInterval(tick, 15000);
})();
</script>
  <script src="/assets/szl-flow.js" defer data-szl-flow-asset="script"></script>
  <script src="/assets/szl-holo-v2.js" defer data-szl-holo-asset="script-v2"></script>
</body>
</html>