create-egregore 0.19.22 → 0.19.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (125) hide show
  1. package/assets/egregore-launcher.js +50 -7
  2. package/assets/egregore-launcher.sh +10 -2
  3. package/bin/cli.js +21 -3
  4. package/lib/codex-runtime.js +25 -3
  5. package/lib/connect-runtime.js +329 -0
  6. package/lib/pi-runtime.js +23 -3
  7. package/lib/setup.js +13 -0
  8. package/package.json +3 -3
  9. package/runtime/codex/.codex/skills/handoff/SKILL.md +99 -13
  10. package/runtime/codex/.codex/skills/save/SKILL.md +39 -4
  11. package/runtime/codex/.codex/spec-manifest.json +2 -2
  12. package/runtime/codex/AGENTS.md +18 -1
  13. package/runtime/codex/bin/agent.sh +28 -14
  14. package/runtime/codex/bin/attendant.sh +169 -6
  15. package/runtime/codex/bin/codex-render-spec.mjs +18 -1
  16. package/runtime/codex/bin/codex-session-start.sh +13 -0
  17. package/runtime/codex/bin/codex-skill-render.mjs +5 -0
  18. package/runtime/codex/bin/codex-sync-skills.sh +1 -0
  19. package/runtime/codex/bin/graph.sh +21 -1
  20. package/runtime/codex/bin/handoff-run.sh +88 -84
  21. package/runtime/codex/bin/index-handoff.sh +2 -1
  22. package/runtime/codex/bin/lib/context.sh +220 -172
  23. package/runtime/codex/bin/lib/dashboard-artifact.sh +113 -13
  24. package/runtime/codex/bin/lib/git-sync.sh +44 -8
  25. package/runtime/codex/bin/lib/greeting.sh +34 -11
  26. package/runtime/codex/bin/lib/identity.sh +32 -14
  27. package/runtime/codex/bin/person.py +20 -0
  28. package/runtime/codex/bin/publish-artifact.sh +25 -4
  29. package/runtime/codex/manifest.json +3 -72
  30. package/runtime/pi/.codex/skills/handoff/SKILL.md +99 -13
  31. package/runtime/pi/.codex/skills/save/SKILL.md +39 -4
  32. package/runtime/pi/.codex/spec-manifest.json +2 -2
  33. package/runtime/pi/.pi/APPEND_SYSTEM.md +18 -1
  34. package/runtime/pi/.pi/spec-manifest.json +2 -2
  35. package/runtime/pi/AGENTS.md +18 -1
  36. package/runtime/pi/bin/agent.sh +28 -14
  37. package/runtime/pi/bin/attendant.sh +169 -6
  38. package/runtime/pi/bin/codex-render-spec.mjs +18 -1
  39. package/runtime/pi/bin/codex-session-start.sh +13 -0
  40. package/runtime/pi/bin/codex-skill-render.mjs +5 -0
  41. package/runtime/pi/bin/codex-sync-skills.sh +1 -0
  42. package/runtime/pi/bin/graph.sh +21 -1
  43. package/runtime/pi/bin/handoff-run.sh +88 -84
  44. package/runtime/pi/bin/index-handoff.sh +2 -1
  45. package/runtime/pi/bin/lib/context.sh +220 -172
  46. package/runtime/pi/bin/lib/dashboard-artifact.sh +113 -13
  47. package/runtime/pi/bin/lib/git-sync.sh +44 -8
  48. package/runtime/pi/bin/lib/greeting.sh +34 -11
  49. package/runtime/pi/bin/lib/identity.sh +32 -14
  50. package/runtime/pi/bin/person.py +20 -0
  51. package/runtime/pi/bin/pi-product-workflows.mjs +19 -6
  52. package/runtime/pi/bin/publish-artifact.sh +25 -4
  53. package/runtime/pi/manifest.json +3 -72
  54. package/runtime/codex/.codex/skills/add/SKILL.md +0 -29
  55. package/runtime/codex/.codex/skills/answer/SKILL.md +0 -29
  56. package/runtime/codex/.codex/skills/ask/SKILL.md +0 -67
  57. package/runtime/codex/.codex/skills/audit/SKILL.md +0 -29
  58. package/runtime/codex/.codex/skills/autosave/SKILL.md +0 -29
  59. package/runtime/codex/.codex/skills/branch/SKILL.md +0 -29
  60. package/runtime/codex/.codex/skills/commit/SKILL.md +0 -29
  61. package/runtime/codex/.codex/skills/demo-mode/SKILL.md +0 -29
  62. package/runtime/codex/.codex/skills/deploy-bridge/SKILL.md +0 -29
  63. package/runtime/codex/.codex/skills/design/SKILL.md +0 -29
  64. package/runtime/codex/.codex/skills/egregore-voice/SKILL.md +0 -29
  65. package/runtime/codex/.codex/skills/emissary/SKILL.md +0 -45
  66. package/runtime/codex/.codex/skills/env/SKILL.md +0 -29
  67. package/runtime/codex/.codex/skills/ingest-google/SKILL.md +0 -29
  68. package/runtime/codex/.codex/skills/minion/SKILL.md +0 -29
  69. package/runtime/codex/.codex/skills/mock/SKILL.md +0 -29
  70. package/runtime/codex/.codex/skills/pr/SKILL.md +0 -29
  71. package/runtime/codex/.codex/skills/product-voice/SKILL.md +0 -29
  72. package/runtime/codex/.codex/skills/project/SKILL.md +0 -45
  73. package/runtime/codex/.codex/skills/pull/SKILL.md +0 -29
  74. package/runtime/codex/.codex/skills/push/SKILL.md +0 -29
  75. package/runtime/codex/.codex/skills/quest-suggest/SKILL.md +0 -29
  76. package/runtime/codex/.codex/skills/review-pr/SKILL.md +0 -45
  77. package/runtime/codex/.codex/skills/scroll/SKILL.md +0 -288
  78. package/runtime/codex/.codex/skills/scroll/agents/openai.yaml +0 -4
  79. package/runtime/codex/.codex/skills/scroll/assets/shell.html +0 -871
  80. package/runtime/codex/.codex/skills/search/SKILL.md +0 -79
  81. package/runtime/codex/.codex/skills/session-view/SKILL.md +0 -29
  82. package/runtime/codex/.codex/skills/setup/SKILL.md +0 -29
  83. package/runtime/codex/.codex/skills/summon/SKILL.md +0 -45
  84. package/runtime/codex/.codex/skills/task/SKILL.md +0 -29
  85. package/runtime/codex/.codex/skills/teams-connect/SKILL.md +0 -29
  86. package/runtime/codex/.codex/skills/telegram-connect/SKILL.md +0 -29
  87. package/runtime/codex/.codex/skills/the-spiral/SKILL.md +0 -84
  88. package/runtime/codex/.codex/skills/thread/SKILL.md +0 -29
  89. package/runtime/codex/.codex/skills/todo/SKILL.md +0 -45
  90. package/runtime/pi/.codex/skills/add/SKILL.md +0 -29
  91. package/runtime/pi/.codex/skills/answer/SKILL.md +0 -29
  92. package/runtime/pi/.codex/skills/ask/SKILL.md +0 -67
  93. package/runtime/pi/.codex/skills/audit/SKILL.md +0 -29
  94. package/runtime/pi/.codex/skills/autosave/SKILL.md +0 -29
  95. package/runtime/pi/.codex/skills/branch/SKILL.md +0 -29
  96. package/runtime/pi/.codex/skills/commit/SKILL.md +0 -29
  97. package/runtime/pi/.codex/skills/demo-mode/SKILL.md +0 -29
  98. package/runtime/pi/.codex/skills/deploy-bridge/SKILL.md +0 -29
  99. package/runtime/pi/.codex/skills/design/SKILL.md +0 -29
  100. package/runtime/pi/.codex/skills/egregore-voice/SKILL.md +0 -29
  101. package/runtime/pi/.codex/skills/emissary/SKILL.md +0 -45
  102. package/runtime/pi/.codex/skills/env/SKILL.md +0 -29
  103. package/runtime/pi/.codex/skills/ingest-google/SKILL.md +0 -29
  104. package/runtime/pi/.codex/skills/minion/SKILL.md +0 -29
  105. package/runtime/pi/.codex/skills/mock/SKILL.md +0 -29
  106. package/runtime/pi/.codex/skills/pr/SKILL.md +0 -29
  107. package/runtime/pi/.codex/skills/product-voice/SKILL.md +0 -29
  108. package/runtime/pi/.codex/skills/project/SKILL.md +0 -45
  109. package/runtime/pi/.codex/skills/pull/SKILL.md +0 -29
  110. package/runtime/pi/.codex/skills/push/SKILL.md +0 -29
  111. package/runtime/pi/.codex/skills/quest-suggest/SKILL.md +0 -29
  112. package/runtime/pi/.codex/skills/review-pr/SKILL.md +0 -45
  113. package/runtime/pi/.codex/skills/scroll/SKILL.md +0 -288
  114. package/runtime/pi/.codex/skills/scroll/agents/openai.yaml +0 -4
  115. package/runtime/pi/.codex/skills/scroll/assets/shell.html +0 -871
  116. package/runtime/pi/.codex/skills/search/SKILL.md +0 -79
  117. package/runtime/pi/.codex/skills/session-view/SKILL.md +0 -29
  118. package/runtime/pi/.codex/skills/setup/SKILL.md +0 -29
  119. package/runtime/pi/.codex/skills/summon/SKILL.md +0 -45
  120. package/runtime/pi/.codex/skills/task/SKILL.md +0 -29
  121. package/runtime/pi/.codex/skills/teams-connect/SKILL.md +0 -29
  122. package/runtime/pi/.codex/skills/telegram-connect/SKILL.md +0 -29
  123. package/runtime/pi/.codex/skills/the-spiral/SKILL.md +0 -84
  124. package/runtime/pi/.codex/skills/thread/SKILL.md +0 -29
  125. package/runtime/pi/.codex/skills/todo/SKILL.md +0 -45
@@ -1,871 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en" data-theme="__THEME_DARK__" data-theme-pair="__THEME_PAIR__" data-theme-mode="auto">
3
- <head>
4
- <meta charset="utf-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1">
6
- <title>__TITLE__ · Egregore</title>
7
- <link rel="preconnect" href="https://fonts.googleapis.com">
8
- <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
9
- <link href="https://fonts.googleapis.com/css2?family=Fraunces:ital,opsz,wght@0,9..144,300..900;1,9..144,400..700&family=Hanken+Grotesk:wght@400;500;600;700&family=IBM+Plex+Mono:wght@400;500;600&display=swap" rel="stylesheet">
10
- <script>
11
- /* Meridian theme engine (light / auto / dark) + palette pairs — pre-paint, no network, no permissions. */
12
- (function(){
13
- var PAIRS={
14
- sovereign:{light:'ledger',dark:'bedrock'},
15
- meridian:{light:'vellum',dark:'nocturne'},
16
- agronomic:{light:'loam',dark:'soil'}
17
- };
18
- var PAIR_ORDER=['sovereign','meridian','agronomic'];
19
- var DEFAULT_PAIR='__THEME_PAIR__';
20
- var MODES=['light','auto','dark'], ICONS=['\u2600','\u25D0','\u263D'], LABELS=['light','auto','dark'];
21
- function prefersDark(){
22
- if(window.matchMedia('(prefers-color-scheme: dark)').matches) return true;
23
- if(window.matchMedia('(prefers-color-scheme: light)').matches) return false;
24
- var h=new Date().getHours(); return (h>=19||h<7);
25
- }
26
- function curPair(){ var p=null; try{p=localStorage.getItem('eg-theme-pair');}catch(e){}
27
- return PAIRS[p]?p:DEFAULT_PAIR; }
28
- function curMode(){ var m='auto'; try{m=localStorage.getItem('eg-theme-mode')||'auto';}catch(e){} return m; }
29
- function apply(mode){
30
- var pid=curPair(), pair=PAIRS[pid];
31
- var dark=mode==='auto'?prefersDark():(mode==='dark');
32
- var el=document.documentElement;
33
- el.setAttribute('data-theme', dark?pair.dark:pair.light);
34
- el.setAttribute('data-theme-pair', pid);
35
- el.setAttribute('data-theme-mode', mode);
36
- }
37
- apply(curMode());
38
- window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change',function(){
39
- if(curMode()==='auto') apply('auto');
40
- });
41
- window.__egTheme={
42
- cycle:function(){
43
- var next=MODES[(MODES.indexOf(curMode())+1)%3];
44
- try{localStorage.setItem('eg-theme-mode',next);}catch(e){}
45
- apply(next); this.paint();
46
- },
47
- cyclePair:function(){
48
- var next=PAIR_ORDER[(PAIR_ORDER.indexOf(curPair())+1)%PAIR_ORDER.length];
49
- try{localStorage.setItem('eg-theme-pair',next);}catch(e){}
50
- apply(curMode()); this.paint();
51
- },
52
- paint:function(){
53
- var i=MODES.indexOf(curMode()), b=document.getElementById('themebtn');
54
- if(b){ b.querySelector('.ic').textContent=ICONS[i]; b.querySelector('.tl').textContent=LABELS[i]; }
55
- var pb=document.getElementById('palbtn');
56
- if(pb){ pb.querySelector('.tl').textContent=curPair(); }
57
- },
58
- init:function(){this.paint();}
59
- };
60
- })();
61
- </script>
62
- <script id="scroll-logic">
63
- (function(root){
64
- 'use strict';
65
- var api={};
66
- function text(v){return v===undefined||v===null?'':String(v);}
67
- function lf(v){return text(v).replace(/\r\n?/g,'\n');}
68
- function nfc(v){var s=lf(v);return s.normalize?s.normalize('NFC'):s;}
69
- function has(obj,key){return Object.prototype.hasOwnProperty.call(obj,key);}
70
- function cleanLine(v){return lf(v).trim().replace(/\n+/g,' ');}
71
- function undecided(){return {key:'UNDECIDED',label:'Leave this open'};}
72
- function blankChannels(){return {single:{},multi:{},rank:{},weight:{},spectrum:{}};}
73
- function forkMode(meta,did){return ((meta.forkModes||{})[did])||'single';}
74
- function selectedFor(state,meta,did){
75
- if(state.undecided&&has(state.undecided,did))return undecided();
76
- var mode=forkMode(meta,did),channel=((state.channels||{})[mode])||{};
77
- return has(channel,did)?channel[did]:null;
78
- }
79
- function pruneState(state,meta){
80
- var source=state&&typeof state==='object'?state:{},out={channels:blankChannels(),undecided:{},decisions:{},notes:{},opens:{}};
81
- var decisions=source.decisions&&typeof source.decisions==='object'?source.decisions:{};
82
- var channels=source.channels&&typeof source.channels==='object'?source.channels:{};
83
- var explicitUndecided=source.undecided&&typeof source.undecided==='object'?source.undecided:{};
84
- var notes=source.notes&&typeof source.notes==='object'?source.notes:{};
85
- var opens=source.opens&&typeof source.opens==='object'?source.opens:{};
86
- (meta.forkOrder||[]).forEach(function(did){
87
- var mode=forkMode(meta,did),modeChannel=channels[mode]&&typeof channels[mode]==='object'?channels[mode]:{};
88
- var selected=modeChannel[did],legacy=decisions[did],allowed=(meta.forkOptions||{})[did],labels=(meta.forkLabels||{})[did]||{};
89
- var isUndecided=has(explicitUndecided,did)||(legacy&&typeof legacy==='object'&&cleanLine(legacy.key)==='UNDECIDED');
90
- if(mode==='single'){
91
- if(!selected&&legacy&&typeof legacy==='object'&&cleanLine(legacy.key)!=='UNDECIDED')selected=legacy;
92
- if(selected&&typeof selected==='object'){
93
- var key=cleanLine(selected.key),label=cleanLine(selected.label);
94
- if(key&&(!Array.isArray(allowed)||allowed.indexOf(key)!==-1)){
95
- out.channels.single[did]={key:key,label:label||cleanLine(labels[key])||key};
96
- out.decisions[did]=out.channels.single[did];isUndecided=false;
97
- }
98
- }
99
- }else if(mode==='multi'&&Array.isArray(selected)){
100
- var seen={},max=Number((meta.forkMax||{})[did]),picks=[];
101
- selected.forEach(function(entry){
102
- if(!entry||typeof entry!=='object')return;
103
- var key=cleanLine(entry.key),label=cleanLine(entry.label);
104
- if(!key||seen[key]||(Array.isArray(allowed)&&allowed.indexOf(key)===-1))return;
105
- seen[key]=true;picks.push({key:key,label:label||cleanLine(labels[key])||key});
106
- });
107
- if(Number.isInteger(max)&&max>0)picks=picks.slice(0,max);
108
- if(picks.length){out.channels.multi[did]=picks;isUndecided=false;}
109
- }else if(mode==='rank'&&Array.isArray(selected)){
110
- var rankSeen={},rankCount=0,ranks=[];
111
- selected.forEach(function(tier){
112
- if(!Array.isArray(tier)||rankCount>=5)return;
113
- var cleanTier=[];
114
- tier.forEach(function(entry){
115
- if(rankCount>=5||!entry||typeof entry!=='object')return;
116
- var key=cleanLine(entry.key),label=cleanLine(entry.label);
117
- if(!key||rankSeen[key]||(Array.isArray(allowed)&&allowed.indexOf(key)===-1))return;
118
- rankSeen[key]=true;rankCount++;cleanTier.push({key:key,label:label||cleanLine(labels[key])||key});
119
- });
120
- if(cleanTier.length)ranks.push(cleanTier);
121
- });
122
- if(ranks.length){out.channels.rank[did]=ranks;isUndecided=false;}
123
- }else if(mode==='spectrum'&&selected&&typeof selected==='object'){
124
- var position=Number(selected.position),positionKey=cleanLine(selected.position),label=cleanLine(selected.label),authoredLabel='';
125
- Object.keys(labels).some(function(key){
126
- if(Number(key)!==position)return false;
127
- authoredLabel=cleanLine(labels[key]);return true;
128
- });
129
- if(Number.isFinite(position)&&position>=0&&position<=1
130
- &&(!Array.isArray(allowed)||allowed.some(function(value){return Number(value)===position;}))){
131
- out.channels.spectrum[did]={position:position,label:label||authoredLabel||positionKey};
132
- isUndecided=false;
133
- }
134
- }
135
- if(isUndecided){
136
- out.undecided[did]=true;out.decisions[did]=undecided();
137
- }
138
- if(has(notes,did)&&lf(notes[did]).trim()){
139
- out.notes[did]=nfc(notes[did]);
140
- if(!selectedFor(out,meta,did)){out.undecided[did]=true;out.decisions[did]=undecided();}
141
- }
142
- });
143
- (meta.promptOrder||[]).forEach(function(oid){if(has(opens,oid)&&lf(opens[oid]).trim())out.opens[oid]=nfc(opens[oid]);});
144
- return out;
145
- }
146
- function decisionProgress(state,meta){
147
- var current=pruneState(state,meta),total=(meta.forkOrder||[]).length,done=0;
148
- (meta.forkOrder||[]).forEach(function(did){if(selectedFor(current,meta,did))done++;});
149
- return {done:Math.min(done,total),total:total};
150
- }
151
- function buildDecisionsFence(state,meta){
152
- var current=pruneState(state,meta),out='#'+meta.slug+'-decisions:v'+meta.version+'\n'
153
- +'surface: '+meta.surfaceId+'\n'+'harvest: '+meta.harvestId+'\n'+'date: '+meta.date+'\n\n';
154
- (meta.forkOrder||[]).forEach(function(did,i){
155
- var selected=selectedFor(current,meta,did),mode=forkMode(meta,did);
156
- if(!selected)return;
157
- if(selected.key==='UNDECIDED')out+='Q'+(i+1)+' '+did+': UNDECIDED\n';
158
- else if(mode==='multi'){
159
- out+='Q'+(i+1)+' '+did+': ['+selected.map(function(pick){return pick.key;}).join(', ')+'] ('
160
- +selected.map(function(pick){return '"'+pick.label+'"';}).join(' + ')+')\n';
161
- }else if(mode==='rank'){
162
- out+='Q'+(i+1)+' '+did+': '+selected.map(function(tier){
163
- return tier.map(function(pick){return pick.key;}).join(' = ');
164
- }).join(' > ')+'\n';
165
- }else if(mode==='spectrum'){
166
- var ends=(meta.forkEnds||{})[did]||[];
167
- out+='Q'+(i+1)+' '+did+': '+selected.position+' ('+cleanLine(ends[0])+'\u2192'+cleanLine(ends[1])+')\n';
168
- }else out+='Q'+(i+1)+' '+did+': '+selected.key+' ("'+selected.label+'")\n';
169
- var note=current.notes[did];
170
- if(note&&note.trim()){
171
- out+=' note: |\n';
172
- lf(note).split('\n').forEach(function(line){out+=' '+line+'\n';});
173
- }
174
- });
175
- if((meta.promptOrder||[]).length)out+='\n';
176
- (meta.promptOrder||[]).forEach(function(oid,i){var answer=has(current.opens,oid)?cleanLine(current.opens[oid]):'';out+='O'+(i+1)+' '+oid+': '+(answer||'UNDECIDED')+'\n';});
177
- return out;
178
- }
179
- api.pruneState=pruneState;api.decisionProgress=decisionProgress;api.buildDecisionsFence=buildDecisionsFence;
180
- root.__scroll=api;
181
- })(typeof window!=='undefined'?window:globalThis);
182
- </script>
183
- <style>
184
- /*__MERIDIAN_CSS__*/
185
-
186
- [data-theme="ledger"]{--sky:var(--steel)}
187
- [data-theme="bedrock"]{--sky:var(--steel)}
188
-
189
- /* ── Meridian compat: aliases the Threads components use, mapped to role tokens ── */
190
- :root{
191
- --surface:var(--card); --surface-2:var(--paper-2); --bg:var(--paper); --bg-soft:var(--paper-2);
192
- --text-faint:var(--ink-faint); --border-soft:var(--line-soft);
193
- --accent:var(--t1); --accent-2:var(--t1); --font:var(--sans);
194
- --s1:var(--ink-faint); --s2:var(--sky); --s3:var(--t1); --s4:var(--t3); --s5:var(--t2);
195
- --green:var(--t2); --red:var(--t3);
196
- --radius:14px; --maxw:920px;
197
- }
198
-
199
- /* ===== Threads components (press vocabulary, re-tokenised onto Meridian) ===== */
200
- *{box-sizing:border-box}
201
- html{scroll-behavior:smooth}
202
- body{margin:0;background:var(--bg);color:var(--text);font-family:var(--font);
203
- line-height:1.62;font-size:16.5px;-webkit-font-smoothing:antialiased;}
204
- .wrap{max-width:var(--maxw);margin:0 auto;padding:0 28px}
205
- a{color:var(--accent);text-decoration:none}
206
- h1,h2,h3{font-family:var(--serif);font-weight:400;line-height:1.18;letter-spacing:-.02em;color:var(--text)}
207
- h2{font-size:1.92rem;margin:0 0 6px}
208
- h3{font-size:1.28rem;margin:32px 0 10px}
209
- h4{font-family:var(--serif);font-weight:400}
210
- p{color:var(--text-dim)} p strong,li strong{color:var(--text);font-weight:600}
211
- em{font-style:italic}
212
- .mono{font-family:var(--mono)}
213
- code{font-family:var(--mono);font-size:.84em;background:var(--surface-2);
214
- border:1px solid var(--border);padding:1px 6px;border-radius:5px;color:var(--accent-2)}
215
-
216
- /* header */
217
- header{padding:62px 0 40px;border-bottom:1px dotted var(--line)}
218
- .brandmark{margin-bottom:26px}
219
- .brandmark svg{height:32px;width:auto;display:block}
220
- .kicker{font-family:var(--mono);font-size:.72rem;letter-spacing:2.5px;text-transform:uppercase;
221
- color:var(--accent);margin-bottom:18px}
222
- header h1{font-size:3rem;margin:0 0 20px;max-width:20ch;line-height:1.06}
223
- .lede{font-size:1.2rem;color:var(--text-dim);max-width:60ch;margin:0;font-family:var(--font)}
224
- .subtitle{font-family:var(--serif);font-size:1.35rem;color:var(--text-dim);font-weight:400;
225
- font-style:italic;margin:6px 0 0;letter-spacing:-.01em}
226
- .meta{display:flex;gap:26px;flex-wrap:wrap;margin-top:30px;font-family:var(--mono);
227
- font-size:.76rem;color:var(--text-faint)}
228
- .meta b{color:var(--text-dim);font-weight:500}
229
-
230
- /* sections + dotted divider w/ diamond */
231
- section{padding:46px 0;border-bottom:1px dotted var(--line);position:relative}
232
- section::after{content:"";position:absolute;left:50%;bottom:-4px;width:7px;height:7px;
233
- transform:translateX(-50%) rotate(45deg);background:var(--bg);
234
- border-right:1px dotted var(--line-soft);border-bottom:1px dotted var(--line-soft)}
235
- .secnum{font-family:var(--mono);font-size:.74rem;color:var(--accent);letter-spacing:2px;margin-bottom:4px}
236
- .lead-in{font-size:1.04rem;color:var(--text-dim);max-width:64ch}
237
-
238
- /* summary / stat cards */
239
- .summary{background:var(--surface);border:1px solid var(--border);border-radius:var(--radius);
240
- padding:32px 34px;margin:28px 0 8px}
241
- .summary h3{margin-top:0}
242
- .claims{display:grid;grid-template-columns:1fr 1fr;gap:16px;margin-top:24px}
243
- .claims.three{grid-template-columns:1fr 1fr 1fr}
244
- @media(max-width:680px){.claims,.claims.three{grid-template-columns:1fr}}
245
- .claim{background:var(--bg);border:1px solid var(--border);border-radius:10px;padding:18px 20px}
246
- .claim .n{font-family:var(--serif);font-size:1.62rem;color:var(--accent);font-weight:400}
247
- .claim .l{font-size:.85rem;color:var(--text-dim);margin-top:6px;line-height:1.45}
248
-
249
- /* callout */
250
- .callout{border-left:2px solid var(--accent);background:var(--surface);
251
- border-radius:0 10px 10px 0;padding:16px 22px;margin:24px 0;color:var(--text-dim)}
252
- .callout b{color:var(--text)}
253
-
254
- /* phase strip (progression of 2-4 explanatory phases) */
255
- .phase-strip{display:grid;gap:0;margin:26px 0 10px;grid-auto-flow:column;grid-auto-columns:1fr;
256
- border:1px solid var(--border);border-radius:var(--radius);overflow:hidden;background:var(--surface)}
257
- @media(max-width:680px){.phase-strip{grid-auto-flow:row}}
258
- .sp{padding:22px 22px 24px;border-right:1px solid var(--border-soft);position:relative}
259
- .sp:last-child{border-right:none}
260
- .sp.win{background:var(--t1-bg)}
261
- .sp .tag{font-family:var(--mono);font-size:.68rem;letter-spacing:1.2px;text-transform:uppercase;color:var(--text-faint)}
262
- .sp.win .tag{color:var(--accent)}
263
- .sp h4{margin:8px 0 6px;font-size:1.12rem;color:var(--text)}
264
- .sp p{font-size:.85rem;margin:0;color:var(--text-dim)}
265
- .sp .has{font-family:var(--mono);font-size:.72rem;margin-top:12px;color:var(--text-faint)}
266
- .sp .has .y{color:var(--green)} .sp .has .x{color:var(--red)}
267
-
268
- /* flow (process: node -> node -> node) */
269
- .flow{display:flex;flex-direction:column;gap:14px;margin:26px 0 8px}
270
- .frow{background:var(--surface);border:1px solid var(--border);border-radius:12px;padding:18px 22px}
271
- .frow.win{border-color:var(--line-soft);background:var(--t1-bg)}
272
- .fhead{display:flex;align-items:baseline;gap:12px;margin-bottom:14px;flex-wrap:wrap}
273
- .fhead .cnd{font-family:var(--mono);font-weight:500;font-size:.88rem}
274
- .fhead .gloss{color:var(--text-dim);font-size:.88rem}
275
- .chain{display:flex;align-items:stretch;gap:0;flex-wrap:wrap}
276
- .node{flex:1;min-width:118px;background:var(--bg);border:1px solid var(--border-soft);
277
- border-radius:9px;padding:11px 13px}
278
- .node .nt{font-size:.82rem;color:var(--text);font-weight:600}
279
- .node .nd{font-size:.74rem;color:var(--text-faint);margin-top:3px;line-height:1.4}
280
- .node.sub{border-color:var(--line-soft);background:var(--t1-bg)}
281
- .arrow{display:flex;align-items:center;padding:0 9px;color:var(--accent);font-size:1.1rem}
282
- .fmeta{display:flex;gap:16px;margin-top:13px;font-family:var(--mono);font-size:.72rem;color:var(--text-faint);flex-wrap:wrap}
283
- .fmeta .y{color:var(--green)} .fmeta .x{color:var(--red)}
284
- @media(max-width:680px){.chain{flex-direction:column}.arrow{transform:rotate(90deg);padding:4px 0;align-self:center}.node{width:100%}}
285
-
286
- dfn{font-style:normal;color:var(--text);font-weight:600;border-bottom:1px dotted var(--accent)}
287
-
288
- /* tables */
289
- table{width:100%;border-collapse:collapse;margin:24px 0;font-size:.9rem}
290
- th,td{text-align:left;padding:13px 14px;border-bottom:1px solid var(--border);vertical-align:top}
291
- th{font-family:var(--mono);font-size:.72rem;letter-spacing:.5px;text-transform:uppercase;
292
- color:var(--text-faint);font-weight:500}
293
- td{color:var(--text-dim)}
294
- tr td:first-child{color:var(--text)}
295
- td.num,th.num{text-align:right;font-family:var(--mono);font-size:.86rem}
296
- .tbl-overall td{border-top:2px solid var(--border);font-weight:600;color:var(--text)}
297
- .hl{color:var(--accent);font-weight:600}
298
- .pill{display:inline-block;font-family:var(--mono);font-size:.66rem;padding:2px 8px;border-radius:20px;
299
- border:1px solid var(--border);background:var(--bg)}
300
- .pill.on{color:var(--accent);border-color:var(--line-soft);background:var(--t1-bg)}
301
-
302
- /* charts */
303
- figure{margin:30px 0 8px;background:var(--surface);border:1px solid var(--border);
304
- border-radius:var(--radius);padding:26px 26px 18px}
305
- figcaption{font-size:.82rem;color:var(--text-faint);margin-top:14px;font-family:var(--mono)}
306
- .chart-title{font-family:var(--serif);font-size:1.1rem;color:var(--text);font-weight:400;margin-bottom:2px}
307
- .chart-sub{font-size:.82rem;color:var(--text-dim);margin-bottom:16px}
308
- svg{display:block;width:100%;height:auto;overflow:visible;font-family:var(--font)}
309
- svg .m{font-family:var(--mono)}
310
- .brandmark svg{width:auto;height:32px}
311
- .legend{display:flex;gap:20px;flex-wrap:wrap;margin-top:6px;font-size:.78rem;color:var(--text-dim);
312
- font-family:var(--mono)}
313
- .legend i{display:inline-block;width:11px;height:11px;border-radius:3px;margin-right:7px;vertical-align:middle}
314
-
315
- /* horizontal bars (completeness/fidelity style) */
316
- .barlist{margin:22px 0}
317
- .barrow{display:grid;grid-template-columns:130px 1fr;gap:14px;align-items:center;padding:10px 0;
318
- border-bottom:1px solid var(--border-soft)}
319
- .barrow .lab{font-family:var(--mono);font-size:.8rem;color:var(--text-dim)}
320
- .bars{display:flex;flex-direction:column;gap:6px}
321
- .barline{display:flex;align-items:center;gap:10px}
322
- .barline .t{font-family:var(--mono);font-size:.66rem;color:var(--text-faint);width:90px}
323
- .track{flex:1;height:9px;background:var(--surface-2);border-radius:6px;overflow:hidden}
324
- .fill{height:100%;border-radius:6px}
325
- .barline .v{font-family:var(--mono);font-size:.72rem;color:var(--text-dim);width:34px;text-align:right}
326
-
327
- /* numbered list (steps / findings) */
328
- .steps{counter-reset:step;margin:22px 0}
329
- .step{display:grid;grid-template-columns:34px 1fr;gap:16px;padding:16px 0;border-bottom:1px solid var(--border-soft)}
330
- .step .b{counter-increment:step;font-family:var(--serif);color:var(--accent);font-size:1.2rem}
331
- .step .b::before{content:counter(step)}
332
- .step h4{margin:0 0 4px;font-size:1.06rem;color:var(--text)}
333
- .step p{margin:0;font-size:.88rem}
334
-
335
- ul,ol{color:var(--text-dim)} li{margin:5px 0}
336
- .fin{font-size:1.04rem}
337
- footer{padding:42px 0 70px;color:var(--text-faint);font-size:.8rem;font-family:var(--mono)}
338
- .tag-row{display:flex;gap:10px;flex-wrap:wrap;margin-top:10px}
339
- .tg{font-family:var(--mono);font-size:.66rem;color:var(--text-faint);border:1px solid var(--border);
340
- border-radius:6px;padding:3px 9px;background:var(--surface)}
341
-
342
- /* ===== Agent-handoff artifact extensions — Meridian role tokens throughout ===== */
343
- html{scroll-behavior:smooth}
344
- body{background:var(--paper);color:var(--ink);font-family:var(--sans);line-height:1.62;font-size:16.5px;-webkit-font-smoothing:antialiased}
345
- .wrap{max-width:var(--maxw);margin:0 auto;padding:0 28px}
346
- ::selection{background:var(--t1);color:var(--paper)}
347
-
348
- .callout{background:var(--card);border:1px solid var(--line);border-left:3px solid var(--t2);border-radius:0 12px 12px 0;padding:16px 20px;color:var(--ink-soft);font-size:.94rem}
349
- .callout b{color:var(--ink)}
350
-
351
- /* top bar */
352
- .topbar{position:sticky;top:0;z-index:60;display:flex;align-items:center;gap:16px;padding:11px 22px;
353
- background:color-mix(in srgb, var(--paper) 86%, transparent);backdrop-filter:saturate(150%) blur(10px);
354
- border-bottom:1px solid var(--line)}
355
- .topbar .mark{font-family:var(--mono);font-size:.74rem;letter-spacing:2px;text-transform:uppercase;color:var(--t1);font-weight:600;white-space:nowrap}
356
- .topbar .mark .full{color:var(--ink-faint);font-weight:400}
357
- .topbar .spacer{flex:1}
358
- .seg{display:inline-flex;border:1px solid var(--line);border-radius:9px;overflow:hidden;background:var(--card)}
359
- .seg button{appearance:none;border:0;background:transparent;font-family:var(--mono);font-size:.74rem;letter-spacing:.5px;color:var(--ink-soft);padding:7px 15px;cursor:pointer;line-height:1.4}
360
- .seg button + button{border-left:1px solid var(--line)}
361
- .seg button.on{background:var(--t1);color:var(--paper)}
362
- .gbtn{appearance:none;border:1px solid var(--line);background:var(--card);border-radius:9px;font-family:var(--mono);font-size:.7rem;letter-spacing:.5px;color:var(--ink-soft);padding:7px 11px;cursor:pointer;white-space:nowrap;display:inline-flex;align-items:center;gap:6px}
363
- .gbtn .ic{font-size:.92rem;line-height:1}
364
- @media(max-width:680px){.topbar{gap:9px;padding:9px 13px}.topbar .mark .full{display:none}.gbtn .tl{display:none}}
365
-
366
- /* view switch */
367
- .view{display:none}
368
- .view.active{display:block;animation:fade .35s ease}
369
- @keyframes fade{from{opacity:0;transform:translateY(4px)}to{opacity:1;transform:none}}
370
-
371
- /* paper header */
372
- .phead{padding:58px 0 38px;border-bottom:1px solid var(--line)}
373
- .phead .kicker{font-family:var(--mono);font-size:.72rem;letter-spacing:2.5px;text-transform:uppercase;color:var(--t1);margin-bottom:16px}
374
- .phead h1{font-family:var(--serif);font-weight:380;font-size:3rem;line-height:1.05;letter-spacing:-.02em;margin:0 0 16px;color:var(--ink);max-width:22ch}
375
- .phead .subtitle{font-family:var(--serif);font-size:1.32rem;color:var(--ink-soft);font-style:italic;margin:0;letter-spacing:-.01em;max-width:54ch}
376
- .phead .meta{display:flex;gap:24px;flex-wrap:wrap;margin-top:26px;font-family:var(--mono);font-size:.74rem;color:var(--ink-faint)}
377
- .phead .meta b{color:var(--ink-soft);font-weight:500}
378
- @media(max-width:620px){.phead h1{font-size:2.1rem}}
379
-
380
- /* floating section rail — LEFT, fixed-width dot lane */
381
- .railnav{position:fixed;top:50%;left:15px;transform:translateY(-50%);z-index:40;display:flex;flex-direction:column;gap:4px;max-height:80vh;padding:6px 2px}
382
- .railnav a{position:relative;display:flex;align-items:center;justify-content:center;width:16px;height:16px;border-radius:6px}
383
- .railnav a .rdot{width:6px;height:6px;border-radius:50%;background:var(--line);flex:none;transition:background .2s,box-shadow .2s,transform .2s}
384
- .railnav a:hover .rdot{transform:scale(1.3);background:var(--ink-faint)}
385
- .railnav a .rlbl{position:absolute;left:20px;top:50%;transform:translateY(-50%) translateX(-4px);opacity:0;pointer-events:none;white-space:nowrap;max-width:240px;overflow:hidden;text-overflow:ellipsis;font-family:var(--mono);font-size:.64rem;color:var(--ink-soft);background:color-mix(in srgb, var(--card) 90%, transparent);border:1px solid var(--line);border-radius:7px;padding:3px 9px;backdrop-filter:blur(6px);box-shadow:var(--shadow);transition:opacity .16s,transform .16s}
386
- .railnav a:hover .rlbl{opacity:1;transform:translateY(-50%) translateX(0)}
387
- .railnav a.on .rdot{background:var(--t1);box-shadow:0 0 0 3px var(--t1-bg)}
388
- .railnav a.on .rlbl{color:var(--ink);border-color:var(--t1)}
389
- @media(max-width:1180px){.railnav{display:none}}
390
-
391
- /* thesis banner */
392
- .thesis{background:var(--card);border:1px solid var(--line-soft);border-left:3px solid var(--t1);border-radius:0 14px 14px 0;padding:26px 30px;margin:30px 0 6px}
393
- .thesis .tlab{font-family:var(--mono);font-size:.68rem;letter-spacing:2px;text-transform:uppercase;color:var(--t1);margin-bottom:12px}
394
- .thesis blockquote{margin:0;font-family:var(--serif);font-size:1.5rem;line-height:1.32;color:var(--ink);letter-spacing:-.01em;font-weight:380}
395
- @media(max-width:620px){.thesis blockquote{font-size:1.2rem}}
396
-
397
- /* layer stack */
398
- .layers{display:flex;flex-direction:column;gap:8px;margin:26px 0 10px}
399
- .layer{display:grid;grid-template-columns:86px 190px 1fr;gap:14px;align-items:baseline;background:var(--card);border:1px solid var(--line);border-radius:11px;padding:13px 18px}
400
- .layer .ln{font-family:var(--mono);font-size:.72rem;color:var(--t1);font-weight:600;letter-spacing:1px}
401
- .layer .lt{font-weight:600;color:var(--ink);font-size:.95rem}
402
- .layer .ld{color:var(--ink-soft);font-size:.9rem}
403
- .layer.mech{border-left:3px solid var(--t2)}
404
- .layer.policy{border-left:3px solid var(--t1)}
405
- .layer .mechtag{font-family:var(--mono);font-size:.6rem;letter-spacing:1px;text-transform:uppercase;border-radius:20px;padding:1px 8px;margin-left:8px;vertical-align:middle}
406
- .layer.mech .mechtag{color:var(--t2);border:1px solid var(--t2)}
407
- .layer.policy .mechtag{color:var(--t1);border:1px solid var(--t1)}
408
- @media(max-width:720px){.layer{grid-template-columns:1fr;gap:4px}}
409
-
410
- /* threat cards */
411
- .threats{display:grid;grid-template-columns:1fr 1fr;gap:14px;margin:26px 0 8px}
412
- @media(max-width:760px){.threats{grid-template-columns:1fr}}
413
- .tcard{background:var(--card);border:1px solid var(--line);border-radius:12px;padding:17px 19px}
414
- .tcard .tname{display:flex;align-items:center;gap:10px;font-weight:600;color:var(--ink);margin-bottom:7px;font-size:.96rem}
415
- .tcard .sev{font-family:var(--mono);font-size:.6rem;letter-spacing:1.2px;text-transform:uppercase;border-radius:20px;padding:2px 9px;flex:none}
416
- .sev.mit{color:var(--t2);border:1px solid var(--t2);background:var(--t2-bg)}
417
- .sev.res{color:var(--t1);border:1px solid var(--t1);background:var(--t1-bg)}
418
- .sev.open{color:var(--t3);border:1px solid var(--t3);background:transparent}
419
- .tcard p{margin:4px 0;font-size:.88rem;line-height:1.55}
420
- .tcard .mit-line b{color:var(--t2);font-weight:600}
421
- .tcard .res-line b{color:var(--t3);font-weight:600}
422
- .tcard .fork{font-family:var(--mono);font-size:.72rem;color:var(--t1);margin-top:8px}
423
- .tcard .fork a{color:var(--t1);border-bottom:1px dotted var(--t1);text-decoration:none;cursor:pointer}
424
-
425
- /* ===== Harvest surface ===== */
426
- #view-harvest .wrap{max-width:960px}
427
- .hv-hero{padding:50px 0 14px;border-bottom:1px solid var(--line)}
428
- .hv-hero .sig{font-family:var(--mono);font-size:.72rem;letter-spacing:2.5px;text-transform:uppercase;color:var(--t1);margin-bottom:14px}
429
- .hv-hero h1{font-family:var(--serif);font-weight:380;font-size:2.5rem;margin:0 0 14px;line-height:1.06;color:var(--ink)}
430
- .hv-hero p{font-size:1.06rem;color:var(--ink-soft);max-width:66ch}
431
- .hv-meta{display:flex;gap:22px;flex-wrap:wrap;margin-top:20px;font-family:var(--mono);font-size:.72rem;color:var(--ink-faint)}
432
- .hv-meta b{color:var(--ink-soft);font-weight:500}
433
-
434
- .band{padding:34px 0 8px}
435
- .band > .bhead{display:flex;align-items:baseline;gap:14px;flex-wrap:wrap;margin-bottom:4px;padding-bottom:10px;border-bottom:1px solid var(--line)}
436
- .band > .bhead .bnum{font-family:var(--mono);font-size:.74rem;letter-spacing:2px;color:var(--t1)}
437
- .band > .bhead h2{font-family:var(--serif);font-weight:400;font-size:1.5rem;margin:0;color:var(--ink)}
438
- .band > .bhead .bsub{color:var(--ink-faint);font-size:.86rem;font-family:var(--mono)}
439
-
440
- .dcard{background:var(--card);border:1px solid var(--line);border-radius:14px;padding:24px 26px;margin:22px 0}
441
- .dcard.answered{border-color:var(--t1);box-shadow:0 0 0 2px var(--t1-bg)}
442
- .dcard.left-open{border-color:var(--t3);box-shadow:0 0 0 2px color-mix(in srgb,var(--t3) 16%,transparent)}
443
- .dhead{display:flex;align-items:baseline;gap:12px;margin-bottom:6px}
444
- .dhead .dnum{font-family:var(--mono);font-size:.74rem;color:var(--t1);font-weight:600;flex:none;border:1px solid var(--t1);border-radius:6px;padding:1px 7px;background:var(--card)}
445
- .dhead h3{font-family:var(--serif);font-weight:400;margin:0;font-size:1.2rem;line-height:1.25;color:var(--ink)}
446
- .dframe{font-size:.96rem;color:var(--ink-soft);margin:6px 0 4px}
447
- .dframe .ref{font-family:var(--mono);font-size:.78rem;color:var(--ink-faint)}
448
- .modehint{margin:14px 0 -8px;font-family:var(--mono);font-size:.7rem;letter-spacing:.4px;color:var(--ink-faint)}
449
-
450
- .opts{display:grid;gap:12px;margin:18px 0 6px}
451
- .opts.two{grid-template-columns:1fr 1fr}.opts.three{grid-template-columns:1fr 1fr 1fr}
452
- @media(max-width:720px){.opts.two,.opts.three{grid-template-columns:1fr}}
453
- .opt{position:relative;border:1px solid var(--line);border-radius:11px;padding:15px 16px 14px;background:var(--paper);cursor:pointer;transition:.16s;display:flex;flex-direction:column;gap:10px}
454
- .opt:hover{border-color:var(--t1);background:var(--paper-2)}
455
- .opt.sel{border-color:var(--t1);background:var(--t1-bg);box-shadow:0 0 0 2px var(--t1)}
456
- .opt .ohead{display:flex;align-items:center;gap:9px}
457
- .opt .okey{font-family:var(--mono);font-size:.7rem;width:20px;height:20px;display:grid;place-items:center;border:1px solid var(--line);border-radius:5px;color:var(--ink-soft);flex:none;background:var(--card)}
458
- .opt.sel .okey{background:var(--t1);color:var(--paper);border-color:var(--t1)}
459
- .opt .olabel{font-weight:600;color:var(--ink);font-size:.96rem;line-height:1.25}
460
- .spectrum-poles{display:flex;justify-content:space-between;gap:20px;margin:17px 2px 8px;font-family:var(--mono);font-size:.72rem;color:var(--ink-soft)}
461
- .spectrum-poles span:last-child{text-align:right}
462
- .spectrum-stops{display:grid;grid-template-columns:repeat(auto-fit,minmax(96px,1fr));gap:8px;margin:10px 0 6px}
463
- .sstop{appearance:none;border:1px solid var(--line);border-radius:10px;padding:12px 9px;background:var(--paper);color:var(--ink);cursor:pointer;display:flex;flex-direction:column;align-items:center;gap:5px;text-align:center;font-family:var(--sans);transition:.16s}
464
- .sstop:hover{border-color:var(--t1);background:var(--paper-2)}
465
- .sstop.sel{border-color:var(--t1);background:var(--t1-bg);box-shadow:0 0 0 2px var(--t1)}
466
- .spos{font-family:var(--mono);font-size:.68rem;color:var(--ink-faint)}
467
- .slabel{font-size:.82rem;font-weight:600;line-height:1.25}
468
- .rank-list{display:flex;flex-direction:column;gap:9px;margin:18px 0 6px}
469
- .rank-item{position:relative;display:grid;grid-template-columns:minmax(0,1fr) auto;gap:8px 12px;align-items:start;border:1px solid var(--line);border-radius:11px;padding:12px 13px;background:var(--paper);transition:.16s}
470
- .rank-item.ranked{border-color:var(--t1);background:var(--t1-bg)}
471
- .rank-toggle{appearance:none;border:0;background:transparent;color:var(--ink);padding:2px;text-align:left;cursor:pointer;display:flex;align-items:center;gap:10px;font:inherit}
472
- .rank-toggle .rank-badge{font-family:var(--mono);font-size:.68rem;min-width:25px;height:25px;display:grid;place-items:center;border:1px solid var(--line);border-radius:6px;color:var(--ink-faint);background:var(--card)}
473
- .rank-item.ranked .rank-badge{border-color:var(--t1);background:var(--t1);color:var(--paper)}
474
- .rank-toggle .rank-label{font-weight:600;line-height:1.3}
475
- .rank-controls{display:flex;gap:5px;align-items:center}
476
- .rank-controls button{appearance:none;border:1px solid var(--line);border-radius:7px;background:var(--card);color:var(--ink-soft);font-family:var(--mono);font-size:.66rem;padding:5px 7px;cursor:pointer;min-height:29px}
477
- .rank-controls button:hover:not(:disabled){border-color:var(--t1);color:var(--t1)}
478
- .rank-controls button:disabled{opacity:.35;cursor:not-allowed}
479
- .rank-item .otrade{grid-column:1 / -1;padding-left:37px}
480
- .rank-summary{margin:12px 0 -7px;padding:9px 11px;border:1px dashed var(--line);border-radius:8px;background:var(--paper);font-family:var(--mono);font-size:.72rem;color:var(--ink-soft)}
481
- @media(max-width:620px){.rank-item{grid-template-columns:1fr}.rank-controls{padding-left:37px}.rank-item .otrade{padding-left:37px}}
482
- .oviz{font-family:var(--mono);font-size:.7rem;line-height:1.5;color:var(--ink-soft);background:var(--card);border:1px solid var(--line-soft);border-radius:8px;padding:9px 11px;white-space:pre-wrap;overflow-x:auto}
483
- .obadges{display:flex;flex-wrap:wrap;gap:6px}
484
- .obadges .bdg{font-family:var(--mono);font-size:.64rem;border:1px solid var(--line);border-radius:20px;padding:2px 9px;background:var(--card);color:var(--ink-soft)}
485
- .obadges .bdg.hot{border-color:var(--t1);background:var(--card);color:var(--t1)}
486
- .obadges .bdg.cool{border-color:var(--sky);background:var(--t2-bg);color:var(--sky)}
487
- .otrade{display:flex;flex-direction:column;gap:3px;margin-top:2px}
488
- .otrade span{font-size:.8rem;line-height:1.4}
489
- .otrade .plus{color:var(--t2)}.otrade .plus::before{content:"+ ";font-family:var(--mono)}
490
- .otrade .minus{color:var(--t3)}.otrade .minus::before{content:"\2212 ";font-family:var(--mono)}
491
- .orec{margin-top:14px;font-size:.88rem;color:var(--ink-soft);background:var(--paper);border:1px dashed var(--t1);border-radius:9px;padding:11px 14px}
492
- .orec b{color:var(--t1)}
493
- .orec::before{content:"\2605 lean ";font-family:var(--mono);font-size:.72rem;letter-spacing:1px;color:var(--t1);font-weight:600}
494
- .undecided-control{appearance:none;display:flex;align-items:baseline;gap:9px;width:100%;margin-top:14px;padding:10px 13px;border:1px dashed var(--line);border-radius:9px;background:transparent;color:var(--ink-soft);font-family:var(--sans);font-size:.86rem;text-align:left;cursor:pointer}
495
- .undecided-control:hover{border-color:var(--t3);background:var(--paper)}
496
- .undecided-control[aria-pressed="true"]{border-style:solid;border-color:var(--t3);background:color-mix(in srgb,var(--t3) 10%,var(--paper));color:var(--ink)}
497
- .undecided-control .uwhen{font-family:var(--mono);font-size:.68rem;color:var(--ink-faint)}
498
- .dnote,.otext{width:100%;margin-top:14px;font-family:var(--sans);font-size:.9rem;color:var(--ink);background:var(--paper);border:1px solid var(--line);border-radius:9px;padding:11px 13px;resize:vertical;min-height:46px;line-height:1.5}
499
- .dnote::placeholder,.otext::placeholder{color:var(--ink-faint)}
500
- .dnote:focus,.otext:focus,.opt:focus-visible,.sstop:focus-visible,.rank-toggle:focus-visible,.rank-controls button:focus-visible,.undecided-control:focus-visible{outline:2px solid var(--t1);outline-offset:1px}
501
- .oprompt{background:var(--card);border:1px solid var(--line);border-left:3px solid var(--sky);border-radius:14px;padding:22px 24px;margin:22px 0}
502
- .oprompt .otext{min-height:80px}
503
- .oprompt h3{font-family:var(--serif);font-weight:400;margin:0 0 8px;font-size:1.15rem;color:var(--ink)}
504
- .oprompt p{font-size:.92rem;color:var(--ink-soft);margin:0}
505
-
506
- .copydock{position:sticky;bottom:0;z-index:50;margin:38px 0 0;background:color-mix(in srgb, var(--paper) 92%, transparent);backdrop-filter:blur(8px);border-top:1px solid var(--line);padding:16px 0 22px}
507
- .copydock .row{display:flex;align-items:center;gap:14px;flex-wrap:wrap}
508
- .copydock .prog{font-family:var(--mono);font-size:.76rem;color:var(--ink-soft)}
509
- .copydock .prog b{color:var(--t1)}
510
- .copybtn{appearance:none;border:0;background:var(--t1);color:var(--paper);font-family:var(--mono);font-size:.78rem;letter-spacing:.5px;padding:10px 18px;border-radius:9px;cursor:pointer}
511
- .copybtn:hover{filter:brightness(1.08)}
512
- .copybtn.done{background:var(--t2)}
513
- .ghostbtn{appearance:none;border:1px solid var(--line);background:var(--card);color:var(--ink-soft);font-family:var(--mono);font-size:.74rem;padding:10px 14px;border-radius:9px;cursor:pointer}
514
- .copyblock{margin:14px 0 0;max-height:0;overflow:hidden;transition:max-height .3s ease}
515
- .copyblock.show{max-height:520px;overflow:auto}
516
- .copyblock pre{background:#0e151d;color:#e7ecf2;border-radius:11px;padding:16px 18px;margin:0;font-family:var(--mono);font-size:.74rem;line-height:1.6;overflow-x:auto;white-space:pre}
517
-
518
- .pfoot{padding:42px 0 70px;color:var(--ink-faint);font-size:.8rem;font-family:var(--mono);border-top:1px solid var(--line);margin-top:10px}
519
- .pfoot .src{margin-top:8px;line-height:1.7}
520
- .pfoot .tag-row{display:flex;gap:10px;flex-wrap:wrap;margin-top:12px}
521
- .pfoot .tg{font-family:var(--mono);font-size:.66rem;color:var(--ink-faint);border:1px solid var(--line);border-radius:6px;padding:3px 9px;background:var(--card)}
522
- </style>
523
- </head>
524
- <body>
525
-
526
- <nav class="topbar">
527
- <span class="mark">⊙ EGREGORE <span class="full">· __CONTEXT__</span></span>
528
- <span class="spacer"></span>
529
- <span class="seg" role="tablist">
530
- <button id="tab-paper" class="on" onclick="showView('paper')">SPEC</button>
531
- <button id="tab-harvest" onclick="showView('harvest')">HARVEST</button>
532
- </span>
533
- <button id="palbtn" class="gbtn" onclick="__egTheme.cyclePair()" title="Palette: sovereign / meridian / agronomic"><span class="ic">❖</span><span class="tl">__THEME_PAIR__</span></button>
534
- <button id="themebtn" class="gbtn" onclick="__egTheme.cycle()" title="Theme: light / auto / dark"><span class="ic">◐</span><span class="tl">auto</span></button>
535
- </nav>
536
-
537
- <div id="view-paper" class="view active">
538
- <div class="wrap">
539
- <!-- __FACE__ : replace this comment with the paper face. Composition semantics and module-fit rules live in SKILL.md; this is syntax reference only:
540
- <header class="phead"> kicker · h1 · subtitle · .meta (Author / Version vN — updates in place / Grounds / Date)
541
- <section id="s-…"> one block per chosen module; rail-nav builds from these; use h2 per section.
542
- Available structures: .claims for load-bearing numbers · .thesis for a reframe · .layers for anatomy · .steps for protocol · tokenized SVG <figure> (fill/stroke ONLY var(--token)) · .threats of .tcard · <a onclick="goFork('fork-id')"> for a cost priced by a fork.
543
- <footer class="pfoot"> title line · .src grounds + "updates in place" note · .tag-row
544
- -->
545
- </div>
546
- </div>
547
-
548
- <div id="view-harvest" class="view">
549
- <div class="wrap">
550
- <!-- __HARVEST__ : replace this comment with the decisions face. Question-design rules live in SKILL.md; this is syntax reference only:
551
- <div class="hv-hero"> .sig · h1 · lede naming every fork in one breath · .hv-meta (Respondent / Surface: N forks · M prompts / Loop: paste-back → vN+1 / Returns to)
552
- <div class="callout"> how-to-read
553
- <section class="band"> per band (2–4 bands), .bhead with .bnum letter:
554
- <div class="dcard" data-decision="fork-id"> for legacy/single, add data-mode="multi" data-max="N" for multi, add data-mode="rank" for rank, or add data-mode="spectrum" data-left="left pole" data-right="right pole" for spectrum · .dhead (.dnum A1 · h3 question) · .dframe with .ref grounds
555
- single/multi: .opts.two|.three of <div class="opt" data-opt="key" data-label="Label"> · .ohead (.okey letter · .olabel) · optional .oviz (mono sketch) / .obadges · .otrade (.plus + .minus)
556
- rank: .rank-list of 2–5 <div class="rank-item" data-opt="key" data-label="Label">, each containing one native <button type="button" class="rank-toggle"> and one .otrade; runtime adds ranking controls, badges, summary, and supports ties plus partial top-k
557
- spectrum: .spectrum-poles plus .spectrum-stops of 5–7 <button class="sstop" data-pos="0..1" data-label="fully labeled stop">; no slider and no selected class in authored HTML; runtime adds mode-correct radio/checkbox ARIA behavior and the explicit leave-open control
558
- optional <div class="orec"> · <textarea class="dnote">
559
- <div class="oprompt" data-openid="prompt-id"> open prompt
560
- copydock + harvest pfoot (keep from shell)
561
- -->
562
-
563
- <div class="copydock">
564
- <div class="row">
565
- <span class="prog" id="prog"></span>
566
- <span class="spacer" style="flex:1"></span>
567
- <button class="ghostbtn" onclick="togglePreview()">preview block</button>
568
- <button class="copybtn" id="copybtn" onclick="copyDecisions()">copy decisions</button>
569
- </div>
570
- <div class="copyblock" id="copyblock"><pre></pre></div>
571
- </div>
572
-
573
- <footer class="pfoot">
574
- <div>Egregore — harvest surface for __TITLE__</div>
575
- <div class="src">Copy your decisions and paste the block into this Egregore session · the paper updates in place and v__NEXT_VERSION__'s questions regenerate · “Leave this open” returns once in a different form; untouched questions do not enter the return block.</div>
576
- <div class="tag-row"><span class="tg">__HARVEST_ID__</span><span class="tg">__SURFACE_ID__</span></div>
577
- </footer>
578
- </div>
579
- </div>
580
-
581
- <nav class="railnav" id="railnav" aria-label="Sections"></nav>
582
-
583
- <script>
584
- function showView(v){
585
- document.getElementById('view-paper').classList.toggle('active', v==='paper');
586
- document.getElementById('view-harvest').classList.toggle('active', v==='harvest');
587
- document.getElementById('tab-paper').classList.toggle('on', v==='paper');
588
- document.getElementById('tab-harvest').classList.toggle('on', v==='harvest');
589
- document.getElementById('railnav').style.display = (v==='paper') ? '' : 'none';
590
- history.replaceState(null,'', '#'+v);
591
- window.scrollTo({top:0,behavior:'instant'});
592
- }
593
- function goFork(did){
594
- showView('harvest');
595
- var card=document.querySelector('.dcard[data-decision="'+did+'"]');
596
- if(card){ setTimeout(function(){ card.scrollIntoView({behavior:'smooth',block:'center'}); },80); }
597
- }
598
- function buildRail(){
599
- var rail=document.getElementById('railnav');
600
- var secs=document.querySelectorAll('#view-paper section[id]');
601
- rail.innerHTML='';
602
- secs.forEach(function(s){
603
- var h=(s.querySelector('h2')||{}).textContent||s.id;
604
- var a=document.createElement('a'); a.href='#'+s.id;
605
- a.innerHTML='<span class="rdot"></span><span class="rlbl">'+h+'</span>'; a.title=h;
606
- rail.appendChild(a);
607
- });
608
- var links=[].slice.call(rail.querySelectorAll('a'));
609
- var io=new IntersectionObserver(function(es){
610
- es.forEach(function(e){ if(e.isIntersecting){ var id=e.target.id;
611
- links.forEach(function(l){ l.classList.toggle('on', l.getAttribute('href')==='#'+id); }); } });
612
- },{rootMargin:'-30% 0px -60% 0px'});
613
- secs.forEach(function(s){io.observe(s);});
614
- }
615
-
616
- var SLUG='__SLUG__';
617
- var state={channels:{single:{},multi:{},rank:{},weight:{},spectrum:{}},undecided:{},decisions:{},notes:{},opens:{}};
618
- function loadState(){ try{Object.assign(state, JSON.parse(localStorage.getItem('__STORAGE_KEY__')||'{}'));}catch(e){}
619
- if(!state.channels)state.channels={};['single','multi','rank','weight','spectrum'].forEach(function(mode){if(!state.channels[mode])state.channels[mode]={};});
620
- if(!state.undecided)state.undecided={};if(!state.decisions)state.decisions={}; if(!state.notes)state.notes={}; if(!state.opens)state.opens={}; }
621
- function saveState(){ try{localStorage.setItem('__STORAGE_KEY__',JSON.stringify({channels:state.channels,undecided:state.undecided,decisions:state.decisions,notes:state.notes,opens:state.opens}));}catch(e){} }
622
- function hasState(obj,key){return Object.prototype.hasOwnProperty.call(obj,key);}
623
- function cardMode(card){return card.dataset.mode||'single';}
624
- function cardMax(card){var parsed=Number(card.dataset.max);return Number.isInteger(parsed)&&parsed>0?parsed:card.querySelectorAll('.opt').length;}
625
- function channelFor(mode){if(!state.channels[mode])state.channels[mode]={};return state.channels[mode];}
626
- function rankLocation(ranks,key){
627
- var found=null;(ranks||[]).some(function(tier,tierIndex){
628
- var itemIndex=tier.findIndex(function(item){return item.key===key;});
629
- if(itemIndex===-1)return false;found={tier:tierIndex,item:itemIndex};return true;
630
- });return found;
631
- }
632
- function rankCount(ranks){return (ranks||[]).reduce(function(total,tier){return total+tier.length;},0);}
633
- function selectedForDecision(did,mode){
634
- if(hasState(state.undecided,did))return {key:'UNDECIDED',label:'Leave this open'};
635
- var channel=channelFor(mode);return hasState(channel,did)?channel[did]:null;
636
- }
637
- function clearDecision(did,mode){delete channelFor(mode)[did];delete state.undecided[did];delete state.decisions[did];}
638
- function syncLegacyDecision(did,mode){
639
- delete state.decisions[did];
640
- if(hasState(state.undecided,did))state.decisions[did]={key:'UNDECIDED',label:'Leave this open'};
641
- else if(mode==='single'&&hasState(channelFor('single'),did))state.decisions[did]=channelFor('single')[did];
642
- }
643
- function renderDecision(card,did){
644
- var mode=cardMode(card),selected=selectedForDecision(did,mode),leftOpen=selected&&selected.key==='UNDECIDED';
645
- card.querySelectorAll('.opt').forEach(function(opt){
646
- var chosen=!!selected&&!leftOpen&&(mode==='multi'?selected.some(function(pick){return pick.key===opt.dataset.opt;}):selected.key===opt.dataset.opt);
647
- opt.classList.toggle('sel',chosen);opt.setAttribute('aria-checked',chosen?'true':'false');
648
- });
649
- card.querySelectorAll('.sstop').forEach(function(stop){
650
- var chosen=!!selected&&!leftOpen&&mode==='spectrum'&&Number(selected.position)===Number(stop.dataset.pos);
651
- stop.classList.toggle('sel',chosen);stop.setAttribute('aria-checked',chosen?'true':'false');
652
- });
653
- card.querySelectorAll('.rank-item').forEach(function(item){
654
- var key=item.dataset.opt,location=mode==='rank'&&Array.isArray(selected)?rankLocation(selected,key):null;
655
- item.classList.toggle('ranked',!!location);
656
- var toggle=item.querySelector('.rank-toggle'),badge=item.querySelector('.rank-badge');
657
- if(toggle)toggle.setAttribute('aria-pressed',location?'true':'false');
658
- if(badge)badge.textContent=location?String(location.tier+1)+(selected[location.tier].length>1?'='):'\u2014';
659
- item.querySelectorAll('.rank-controls button').forEach(function(button){
660
- var action=button.dataset.rankAction,disabled=!location;
661
- if(action==='up'||action==='tie')disabled=disabled||location.tier===0;
662
- if(action==='down')disabled=disabled||location.tier===selected.length-1;
663
- if(action==='untie')disabled=disabled||selected[location.tier].length<2;
664
- button.disabled=disabled;
665
- });
666
- });
667
- if(mode==='rank'){
668
- var rankList=card.querySelector('.rank-list'),rankItems=[].slice.call(card.querySelectorAll('.rank-item'));
669
- rankItems.sort(function(a,b){
670
- var aLocation=Array.isArray(selected)?rankLocation(selected,a.dataset.opt):null,bLocation=Array.isArray(selected)?rankLocation(selected,b.dataset.opt):null;
671
- if(aLocation&&bLocation)return aLocation.tier-bLocation.tier||aLocation.item-bLocation.item;
672
- if(aLocation)return -1;if(bLocation)return 1;
673
- return Number(a.dataset.rankSource)-Number(b.dataset.rankSource);
674
- });
675
- rankItems.forEach(function(item){rankList.appendChild(item);});
676
- }
677
- var control=card.querySelector('.undecided-control');
678
- if(control)control.setAttribute('aria-pressed',leftOpen?'true':'false');
679
- card.classList.toggle('answered',!!selected);
680
- card.classList.toggle('left-open',!!leftOpen);
681
- var hint=card.querySelector('.modehint');
682
- if(hint&&mode==='multi'){var count=Array.isArray(selected)?selected.length:0,max=cardMax(card);hint.textContent='Pick up to '+max+' · '+count+' selected'+(count===max?' · limit reached':'');}
683
- else if(hint&&mode==='spectrum'){var stops=card.querySelectorAll('.sstop').length;hint.textContent='Choose one of '+stops+' labeled stops · '+(selected&&!leftOpen?(selected.label||selected.position):leftOpen?'left open':'untouched');}
684
- else if(hint&&mode==='rank'){var count=Array.isArray(selected)?rankCount(selected):0,total=card.querySelectorAll('.rank-item').length;hint.textContent='Rank up to '+total+' · '+count+' ranked · ties allowed · partial order is okay';}
685
- var rankSummary=card.querySelector('.rank-summary');
686
- if(rankSummary)rankSummary.textContent=leftOpen?'Left open':Array.isArray(selected)&&selected.length
687
- ?selected.map(function(tier){return tier.map(function(item){return item.key;}).join(' = ');}).join(' > ')
688
- :'No ranking yet';
689
- }
690
- function wireHarvest(){
691
- document.querySelectorAll('.dcard').forEach(function(card){
692
- var did=card.dataset.decision,mode=cardMode(card),group=card.querySelector(mode==='spectrum'?'.spectrum-stops':mode==='rank'?'.rank-list':'.opts'),heading=card.querySelector('.dhead h3');
693
- if(heading&&!heading.id)heading.id='decision-'+String(did).replace(/[^a-zA-Z0-9_-]/g,'-')+'-question';
694
- if(group){
695
- group.setAttribute('role',mode==='rank'?'list':mode==='multi'?'group':'radiogroup');if(heading)group.setAttribute('aria-labelledby',heading.id);
696
- if(mode==='multi'||mode==='rank'||mode==='spectrum'){var hint=document.createElement('div');hint.className='modehint';hint.id=heading.id+'-mode';hint.setAttribute('aria-live','polite');card.insertBefore(hint,group);group.setAttribute('aria-describedby',hint.id);}
697
- if(mode==='rank'){var summary=document.createElement('div');summary.className='rank-summary';summary.setAttribute('aria-live','polite');summary.id=heading.id+'-rank-summary';card.insertBefore(summary,group);group.setAttribute('aria-describedby',heading.id+'-mode '+summary.id);}
698
- }
699
- var options=[].slice.call(card.querySelectorAll('.opt'));
700
- options.forEach(function(opt,index){
701
- var key=opt.dataset.opt,label=opt.dataset.label||(opt.querySelector('.olabel')||{}).textContent||key;
702
- opt.setAttribute('role',mode==='multi'?'checkbox':'radio');opt.setAttribute('tabindex','0');
703
- if(!opt.title)opt.title=mode==='multi'?'Add this choice. Activate it again to remove it.':'Choose this option. Activate it again to clear.';
704
- function activate(){
705
- delete state.undecided[did];
706
- if(mode==='multi'){
707
- var selected=(channelFor('multi')[did]||[]).slice(),at=selected.findIndex(function(pick){return pick.key===key;});
708
- if(at!==-1)selected.splice(at,1);else if(selected.length<cardMax(card))selected.push({key:key,label:label});
709
- if(selected.length)channelFor('multi')[did]=selected;else delete channelFor('multi')[did];
710
- }else{
711
- var selected=channelFor('single')[did],already=selected&&selected.key===key;
712
- if(already)delete channelFor('single')[did];else channelFor('single')[did]={key:key,label:label};
713
- }
714
- syncLegacyDecision(did,mode);
715
- renderDecision(card,did);saveState();updateProgress();
716
- }
717
- opt.addEventListener('click',activate);
718
- opt.addEventListener('keydown',function(event){
719
- if(event.key==='Enter'||event.key===' '){event.preventDefault();activate();return;}
720
- var next=index;
721
- if(event.key==='ArrowRight'||event.key==='ArrowDown')next=(index+1)%options.length;
722
- else if(event.key==='ArrowLeft'||event.key==='ArrowUp')next=(index+options.length-1)%options.length;
723
- else if(event.key==='Home')next=0;
724
- else if(event.key==='End')next=options.length-1;
725
- else return;
726
- event.preventDefault();options[next].focus();
727
- });
728
- });
729
- var rankItems=[].slice.call(card.querySelectorAll('.rank-item'));
730
- rankItems.forEach(function(item,index){
731
- var key=item.dataset.opt,label=item.dataset.label||(item.querySelector('.rank-label,.olabel')||{}).textContent||key;
732
- var toggle=item.querySelector('.rank-toggle');if(!toggle)return;
733
- item.dataset.rankSource=String(index);
734
- item.setAttribute('role','listitem');toggle.type='button';toggle.setAttribute('aria-pressed','false');
735
- if(!toggle.title)toggle.title='Add this item at the end of your ranking. Activate it again to remove it.';
736
- var badge=toggle.querySelector('.rank-badge');
737
- if(!badge){badge=document.createElement('span');badge.className='rank-badge';badge.setAttribute('aria-hidden','true');badge.textContent='\u2014';toggle.insertBefore(badge,toggle.firstChild);}
738
- function commit(ranks){
739
- delete state.undecided[did];
740
- if(ranks.length)channelFor('rank')[did]=ranks;else delete channelFor('rank')[did];
741
- syncLegacyDecision(did,mode);renderDecision(card,did);saveState();updateProgress();
742
- }
743
- function activate(){
744
- var ranks=(channelFor('rank')[did]||[]).map(function(tier){return tier.slice();}),location=rankLocation(ranks,key);
745
- if(location){ranks[location.tier].splice(location.item,1);if(!ranks[location.tier].length)ranks.splice(location.tier,1);}
746
- else ranks.push([{key:key,label:label}]);
747
- commit(ranks);
748
- }
749
- toggle.addEventListener('click',activate);
750
- toggle.addEventListener('keydown',function(event){
751
- var ordered=[].slice.call(card.querySelectorAll('.rank-toggle')),at=ordered.indexOf(toggle),next=at;
752
- if(event.key==='ArrowRight'||event.key==='ArrowDown')next=(at+1)%ordered.length;
753
- else if(event.key==='ArrowLeft'||event.key==='ArrowUp')next=(at+ordered.length-1)%ordered.length;
754
- else if(event.key==='Home')next=0;
755
- else if(event.key==='End')next=ordered.length-1;
756
- else return;
757
- event.preventDefault();ordered[next].focus();
758
- });
759
- var controls=document.createElement('div');controls.className='rank-controls';
760
- [['up','\u2191','Move this rank tier up'],['down','\u2193','Move this rank tier down'],['tie','=','Tie this item with the tier above'],['untie','\u2260','Move this item into its own tier below']].forEach(function(spec){
761
- var button=document.createElement('button');button.type='button';button.dataset.rankAction=spec[0];button.textContent=spec[1];button.setAttribute('aria-label',spec[2]);button.title=spec[2];
762
- button.addEventListener('click',function(){
763
- var ranks=(channelFor('rank')[did]||[]).map(function(tier){return tier.slice();}),location=rankLocation(ranks,key);if(!location)return;
764
- if(spec[0]==='up'&&location.tier>0){var above=ranks[location.tier-1];ranks[location.tier-1]=ranks[location.tier];ranks[location.tier]=above;}
765
- else if(spec[0]==='down'&&location.tier<ranks.length-1){var below=ranks[location.tier+1];ranks[location.tier+1]=ranks[location.tier];ranks[location.tier]=below;}
766
- else if(spec[0]==='tie'&&location.tier>0){var tied=ranks[location.tier].splice(location.item,1)[0];ranks[location.tier-1].push(tied);if(!ranks[location.tier].length)ranks.splice(location.tier,1);}
767
- else if(spec[0]==='untie'&&ranks[location.tier].length>1){var untied=ranks[location.tier].splice(location.item,1)[0];ranks.splice(location.tier+1,0,[untied]);}
768
- else return;
769
- commit(ranks);
770
- });controls.appendChild(button);
771
- });
772
- item.insertBefore(controls,item.querySelector('.otrade')||null);
773
- });
774
- var spectrumStops=[].slice.call(card.querySelectorAll('.sstop'));
775
- spectrumStops.forEach(function(stop,index){
776
- var position=Number(stop.dataset.pos),label=stop.dataset.label||(stop.querySelector('.slabel')||{}).textContent||String(position);
777
- stop.setAttribute('role','radio');stop.setAttribute('tabindex','0');
778
- if(!stop.title)stop.title='Choose this stop. Activate it again to clear.';
779
- function activate(){
780
- delete state.undecided[did];
781
- var selected=channelFor('spectrum')[did],already=selected&&Number(selected.position)===position;
782
- if(already)delete channelFor('spectrum')[did];else channelFor('spectrum')[did]={position:position,label:label};
783
- syncLegacyDecision(did,mode);renderDecision(card,did);saveState();updateProgress();
784
- }
785
- stop.addEventListener('click',activate);
786
- stop.addEventListener('keydown',function(event){
787
- if(event.key==='Enter'||event.key===' '){event.preventDefault();activate();return;}
788
- var next=index;
789
- if(event.key==='ArrowRight'||event.key==='ArrowDown')next=(index+1)%spectrumStops.length;
790
- else if(event.key==='ArrowLeft'||event.key==='ArrowUp')next=(index+spectrumStops.length-1)%spectrumStops.length;
791
- else if(event.key==='Home')next=0;
792
- else if(event.key==='End')next=spectrumStops.length-1;
793
- else return;
794
- event.preventDefault();spectrumStops[next].focus();
795
- });
796
- });
797
- var control=card.querySelector('.undecided-control');
798
- if(!control){
799
- control=document.createElement('button');control.type='button';control.className='undecided-control';
800
- var label=document.createElement('span'),when=document.createElement('span');
801
- label.textContent='Leave this open';when.className='uwhen';when.textContent='comes back once, differently';
802
- control.appendChild(label);control.appendChild(when);
803
- var noteField=card.querySelector('.dnote');card.insertBefore(control,noteField||null);
804
- }
805
- control.setAttribute('aria-label','Leave this question open; it will return once in a different form');
806
- control.addEventListener('click',function(){
807
- var already=hasState(state.undecided,did);clearDecision(did,mode);
808
- if(!already)state.undecided[did]=true;
809
- syncLegacyDecision(did,mode);
810
- renderDecision(card,did);saveState();updateProgress();
811
- });
812
- var nt=card.querySelector('.dnote');
813
- if(nt){
814
- if(state.notes[did])nt.value=state.notes[did];
815
- nt.addEventListener('input',function(){
816
- if(nt.value.trim()){
817
- state.notes[did]=nt.value;
818
- if(!selectedForDecision(did,mode))state.undecided[did]=true;
819
- }else delete state.notes[did];
820
- syncLegacyDecision(did,mode);
821
- renderDecision(card,did);saveState();updateProgress();
822
- });
823
- }
824
- renderDecision(card,did);
825
- });
826
- document.querySelectorAll('.oprompt .otext').forEach(function(t){
827
- var oid=t.dataset.open;
828
- if(state.opens[oid])t.value=state.opens[oid];
829
- t.addEventListener('input',function(){if(t.value.trim())state.opens[oid]=t.value;else delete state.opens[oid];saveState();updateProgress();});
830
- });
831
- updateProgress();
832
- }
833
- function fenceMeta(){
834
- return {slug:SLUG,version:__VERSION__,surfaceId:'__SURFACE_ID__',harvestId:'__HARVEST_ID__',date:'__DATE__',
835
- forkOrder:[].slice.call(document.querySelectorAll('.dcard')).map(function(c){return c.dataset.decision;}),
836
- forkOptions:[].slice.call(document.querySelectorAll('.dcard')).reduce(function(all,c){var mode=cardMode(c),selector=mode==='spectrum'?'.sstop':mode==='rank'?'.rank-item':'.opt';all[c.dataset.decision]=[].slice.call(c.querySelectorAll(selector)).map(function(o){return mode==='spectrum'?o.dataset.pos:o.dataset.opt;});return all;},{}),
837
- forkLabels:[].slice.call(document.querySelectorAll('.dcard')).reduce(function(all,c){var mode=cardMode(c),selector=mode==='spectrum'?'.sstop':mode==='rank'?'.rank-item':'.opt';all[c.dataset.decision]={};[].slice.call(c.querySelectorAll(selector)).forEach(function(o){var key=mode==='spectrum'?o.dataset.pos:o.dataset.opt;all[c.dataset.decision][key]=o.dataset.label||(o.querySelector(mode==='spectrum'?'.slabel':mode==='rank'?'.rank-label,.olabel':'.olabel')||{}).textContent||key;});return all;},{}),
838
- forkEnds:[].slice.call(document.querySelectorAll('.dcard')).reduce(function(all,c){if(cardMode(c)==='spectrum')all[c.dataset.decision]=[c.dataset.left,c.dataset.right];return all;},{}),
839
- forkModes:[].slice.call(document.querySelectorAll('.dcard')).reduce(function(all,c){all[c.dataset.decision]=cardMode(c);return all;},{}),
840
- forkMax:[].slice.call(document.querySelectorAll('.dcard')).reduce(function(all,c){if(cardMode(c)==='multi')all[c.dataset.decision]=cardMax(c);return all;},{}),
841
- promptOrder:[].slice.call(document.querySelectorAll('.oprompt')).map(function(o){return o.dataset.openid||(o.querySelector('.otext')||{}).dataset.open;})};
842
- }
843
- function buildBlock(){
844
- return window.__scroll.buildDecisionsFence(state,fenceMeta());
845
- }
846
- function updateProgress(){
847
- var progress=window.__scroll.decisionProgress(state,fenceMeta()),total=progress.total,done=progress.done;
848
- var oTotal=document.querySelectorAll('.oprompt').length, oDone=Object.values(state.opens).filter(function(v){return v&&v.trim();}).length;
849
- var el=document.getElementById('prog'); if(el) el.innerHTML='<b>'+done+'</b>/'+total+' forks · <b>'+oDone+'</b>/'+oTotal+' prompts';
850
- var pre=document.querySelector('#copyblock pre'); if(pre) pre.textContent=buildBlock();
851
- }
852
- function copyDecisions(){
853
- var txt=buildBlock(), btn=document.getElementById('copybtn');
854
- navigator.clipboard.writeText(txt).then(function(){
855
- btn.textContent='✓ copied — paste into your Egregore session'; btn.classList.add('done');
856
- setTimeout(function(){btn.textContent='copy decisions'; btn.classList.remove('done');},2600);
857
- }).catch(function(){togglePreview(true);});
858
- }
859
- function togglePreview(force){
860
- var cb=document.getElementById('copyblock');
861
- cb.classList.toggle('show', force===true?true:!cb.classList.contains('show'));
862
- }
863
- (function(){
864
- loadState();state=window.__scroll.pruneState(state,fenceMeta());saveState();
865
- if(window.__egTheme) __egTheme.init();
866
- buildRail(); wireHarvest();
867
- var h=location.hash.replace('#',''); if(h==='harvest') showView('harvest');
868
- })();
869
- </script>
870
- </body>
871
- </html>