@oracle-agent/oracle 0.4.2 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/README.md +66 -17
  2. package/SETUP.md +13 -0
  3. package/bin/oracle-data-mcp.mjs +1 -1
  4. package/bin/oracle.mjs +33 -0
  5. package/docs/cli.md +19 -0
  6. package/docs/connectors.md +13 -0
  7. package/package.json +7 -3
  8. package/profiles/robinhood-agent/SOUL.md +5 -3
  9. package/public/agent-connect/app.js +16 -13
  10. package/public/oracle-splash/assets/wordmarks/across.svg +4 -0
  11. package/public/oracle-splash/assets/wordmarks/aerodrome.svg +23 -0
  12. package/public/oracle-splash/assets/wordmarks/balancer.svg +3 -0
  13. package/public/oracle-splash/assets/wordmarks/cowswap.svg +1 -0
  14. package/public/oracle-splash/assets/wordmarks/gmx.svg +13 -0
  15. package/public/oracle-splash/assets/wordmarks/hyperliquid.svg +21 -0
  16. package/public/oracle-splash/assets/wordmarks/hyperswap.svg +13 -0
  17. package/public/oracle-splash/assets/wordmarks/jupiter.svg +35 -0
  18. package/public/oracle-splash/assets/wordmarks/lifi.png +0 -0
  19. package/public/oracle-splash/assets/wordmarks/magic-eden.svg +1 -0
  20. package/public/oracle-splash/assets/wordmarks/morpho.svg +1 -0
  21. package/public/oracle-splash/assets/wordmarks/odos.svg +3 -0
  22. package/public/oracle-splash/assets/wordmarks/oneinch.svg +6 -0
  23. package/public/oracle-splash/assets/wordmarks/opensea.svg +1 -0
  24. package/public/oracle-splash/assets/wordmarks/pancakeswap.svg +18 -0
  25. package/public/oracle-splash/assets/wordmarks/paraswap.svg +16 -0
  26. package/public/oracle-splash/assets/wordmarks/pendle.png +0 -0
  27. package/public/oracle-splash/assets/wordmarks/polymarket.png +0 -0
  28. package/public/oracle-splash/assets/wordmarks/quickswap.png +0 -0
  29. package/public/oracle-splash/assets/wordmarks/relay.svg +8 -0
  30. package/public/oracle-splash/assets/wordmarks/stargate.svg +15 -0
  31. package/public/oracle-splash/assets/wordmarks/uniswap.svg +18 -0
  32. package/public/oracle-splash/assets/wordmarks/velodrome.svg +84 -0
  33. package/public/oracle-splash/index.html +789 -485
  34. package/scripts/check-doc-drift.mjs +111 -0
  35. package/src/cli/commands/credential.mjs +9 -0
  36. package/src/cli/commands/data-mcp.mjs +18 -0
  37. package/src/cli/commands/data.mjs +73 -0
  38. package/src/cli/commands/doctor.mjs +131 -0
  39. package/src/cli/commands/help.mjs +7 -0
  40. package/src/cli/commands/init.mjs +27 -0
  41. package/src/cli/commands/mcp.mjs +142 -0
  42. package/src/cli/commands/prepare.mjs +12 -0
  43. package/src/cli/commands/public.mjs +20 -0
  44. package/src/cli/commands/route.mjs +12 -0
  45. package/src/cli/commands/runner.mjs +9 -0
  46. package/src/cli/commands/scan.mjs +12 -0
  47. package/src/cli/commands/sign.mjs +21 -0
  48. package/src/cli/commands/signer.mjs +9 -0
  49. package/src/cli/commands/upgrade.mjs +12 -0
  50. package/src/cli/commands/vault.mjs +9 -0
  51. package/src/cli/commands/version.mjs +22 -0
  52. package/src/cli/first-run.mjs +20 -0
  53. package/src/cli/kernel.mjs +198 -0
  54. package/src/cli/mcp-targets/chatgpt.mjs +51 -0
  55. package/src/cli/mcp-targets/claude-code.mjs +39 -0
  56. package/src/cli/mcp-targets/claude-desktop.mjs +24 -0
  57. package/src/cli/mcp-targets/codex.mjs +41 -0
  58. package/src/cli/mcp-targets/shared.mjs +61 -0
  59. package/src/cli/operator-dispatch.mjs +258 -0
  60. package/src/cli/paths.mjs +78 -0
  61. package/src/cli/spawn-child.mjs +43 -0
  62. package/src/public-api/connect-agent.mjs +29 -10
@@ -4,12 +4,12 @@
4
4
  <meta charset="UTF-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
6
  <title>ORACLE</title>
7
- <meta name="description" content="Oracle multichain agent control. Routes across EVM + Solana. Self-custody. Powered by Hermes." />
7
+ <meta name="description" content="Oracle multichain agent control. 13 chains, six bounded surfaces, prepare-only public plane. Self-custody. Powered by Hermes." />
8
8
  <meta name="theme-color" content="#0B1018" />
9
9
  <meta name="robots" content="noindex,nofollow" />
10
10
  <link rel="preconnect" href="https://fonts.googleapis.com" />
11
11
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
12
- <link href="https://fonts.googleapis.com/css2?family=Cormorant+Garamond:ital,wght@0,300;0,400;0,500;1,300;1,400;1,500&family=Outfit:wght@300;400;500&family=IBM+Plex+Mono:wght@400;500&display=swap" rel="stylesheet" />
12
+ <link href="https://fonts.googleapis.com/css2?family=Archivo+Black&family=Cormorant+Garamond:ital,wght@0,300;0,400;0,500;1,300;1,400;1,500&family=DM+Sans:wght@500;700&family=IBM+Plex+Mono:wght@400;500&family=Inter:wght@500;650;750;850&family=Manrope:wght@600;800&family=Outfit:wght@300;400;500;700&family=Sora:wght@500;700&family=Space+Grotesk:wght@500;700&display=swap" rel="stylesheet" />
13
13
  <style>
14
14
  :root{
15
15
  --bg:#0B1018;
@@ -45,12 +45,27 @@ body{
45
45
  ::selection{background:var(--blue);color:#061018}
46
46
  a{color:inherit;text-decoration:none}
47
47
  button{font:inherit;color:inherit;background:none;border:0;cursor:pointer}
48
+ img{display:inline-block}
48
49
 
49
50
  .grain{
50
51
  position:fixed;inset:-40%;z-index:40;pointer-events:none;opacity:.04;mix-blend-mode:soft-light;
51
52
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='220' height='220'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 .55 0'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");
52
53
  }
53
54
 
55
+ /* ── orbital oracle mark ───────────────────────────── */
56
+ .orbital{position:relative;display:inline-block}
57
+ .orbital svg{display:block;overflow:visible;width:100%;height:100%}
58
+ .orbital .ring{transform-origin:50% 50%;fill:none;stroke:var(--blue);stroke-width:2;opacity:.55}
59
+ .orbital .ring ellipse{vector-effect:non-scaling-stroke}
60
+ .orbital .r1{animation:orb-spin 13s linear infinite}
61
+ .orbital .r2{animation:orb-spin 21s linear infinite reverse;opacity:.4}
62
+ .orbital .r3{animation:orb-spin 32s linear infinite;opacity:.28}
63
+ .orbital .tickring{transform-origin:50% 50%;fill:none;stroke:rgba(124,196,255,.35);stroke-width:1.4;stroke-dasharray:2 7;animation:orb-spin 46s linear infinite reverse}
64
+ .orbital .core{fill:var(--blue);animation:core-pulse 3.2s var(--ease) infinite}
65
+ .orbital .halo{fill:none;stroke:rgba(124,196,255,.22);stroke-width:5;filter:blur(3px)}
66
+ @keyframes orb-spin{to{transform:rotate(360deg)}}
67
+ @keyframes core-pulse{0%,100%{opacity:1}50%{opacity:.55}}
68
+
54
69
  .loader{
55
70
  position:fixed;inset:0;z-index:50;background:var(--bg);
56
71
  display:grid;place-items:center;
@@ -58,20 +73,24 @@ button{font:inherit;color:inherit;background:none;border:0;cursor:pointer}
58
73
  }
59
74
  .loader.out{opacity:0;visibility:hidden;pointer-events:none}
60
75
  .loader-inner{display:flex;flex-direction:column;align-items:center;gap:18px}
61
- .loader-mark{width:42px;height:42px;position:relative}
62
- .loader-mark i{position:absolute;inset:0;border:1px solid var(--blue);border-radius:50%;animation:pulse 1.4s var(--ease) infinite;opacity:.35}
63
- .loader-mark b{position:absolute;inset:12px;border-radius:50%;background:var(--blue);box-shadow:0 0 24px rgba(124,196,255,.5)}
76
+ .loader-mark{width:64px;height:64px;filter:drop-shadow(0 0 18px rgba(124,196,255,.4))}
64
77
  .loader-word{font-family:var(--display);font-size:18px;letter-spacing:.08em;text-transform:none;color:var(--cool);font-style:italic}
65
78
  .loader-bar{width:120px;height:1px;background:rgba(124,196,255,.15);overflow:hidden}
66
79
  .loader-bar span{display:block;height:100%;width:0;background:var(--blue);transition:width 1.1s var(--ease)}
67
- @keyframes pulse{0%{transform:scale(.85);opacity:.55}70%{transform:scale(1.35);opacity:0}100%{transform:scale(1.35);opacity:0}}
80
+
81
+ .progress{
82
+ position:fixed;top:0;left:0;right:0;height:2px;z-index:35;pointer-events:none;
83
+ background:linear-gradient(90deg,var(--blue),var(--blue2));
84
+ transform-origin:0 50%;transform:scaleX(0);
85
+ box-shadow:0 0 12px rgba(124,196,255,.5);
86
+ }
68
87
 
69
88
  .nav{
70
89
  position:fixed;top:0;left:0;right:0;z-index:30;
71
90
  display:grid;
72
- grid-template-columns:1fr auto 1fr;
91
+ grid-template-columns:1fr auto;
73
92
  align-items:center;gap:16px;
74
- padding:16px var(--pad);
93
+ padding:14px var(--pad);
75
94
  background:rgba(11,16,24,.82);
76
95
  backdrop-filter:blur(14px);
77
96
  border-bottom:1px solid var(--line);
@@ -81,23 +100,17 @@ button{font:inherit;color:inherit;background:none;border:0;cursor:pointer}
81
100
  font-family:var(--display);font-size:24px;font-weight:400;letter-spacing:.02em;
82
101
  text-transform:none;justify-self:start;
83
102
  }
84
- .brand .orb{width:8px;height:8px;border-radius:50%;background:var(--blue);box-shadow:0 0 14px rgba(124,196,255,.85)}
85
- .nav-mid{
86
- display:flex;flex-wrap:wrap;align-items:center;justify-content:center;gap:10px 18px;
87
- font-family:var(--mono);font-size:9px;letter-spacing:.18em;text-transform:uppercase;color:var(--mute);
88
- }
89
- .nav-mid b{color:var(--blue2);font-weight:500}
90
- .nav-mid a.hermes{
91
- color:var(--blue);font-weight:600;border-bottom:1px solid transparent;
92
- transition:border-color .25s,color .25s;
93
- }
94
- .nav-mid a.hermes:hover{border-bottom-color:var(--blue);color:var(--ink)}
103
+ .brand .orbital{width:26px;height:26px;filter:drop-shadow(0 0 10px rgba(124,196,255,.6))}
95
104
  .nav-links{
96
105
  display:flex;align-items:center;gap:18px;justify-self:end;
97
106
  font-family:var(--mono);font-size:10px;letter-spacing:.18em;text-transform:uppercase;color:var(--cool);
98
107
  }
99
108
  .nav-links a{opacity:.78;transition:opacity .25s,color .25s}
100
109
  .nav-links a:hover{opacity:1;color:var(--blue2)}
110
+ .nav-chip{
111
+ font-family:var(--mono);font-size:9px;letter-spacing:.16em;text-transform:uppercase;
112
+ border:1px solid rgba(124,196,255,.3);border-radius:999px;padding:7px 11px;color:var(--blue2);opacity:.95;
113
+ }
101
114
  .nav-cta{
102
115
  border:1px solid rgba(124,196,255,.28);border-radius:999px;padding:10px 16px;color:var(--ink);
103
116
  transition:border-color .3s,color .3s,box-shadow .3s;
@@ -109,13 +122,79 @@ button{font:inherit;color:inherit;background:none;border:0;cursor:pointer}
109
122
  .veil{
110
123
  position:fixed;inset:0;z-index:1;pointer-events:none;
111
124
  background:
112
- radial-gradient(60% 50% at 50% 28%, rgba(124,196,255,.08), transparent 58%),
113
- linear-gradient(180deg, rgba(11,16,24,.2), var(--bg) 88%);
125
+ radial-gradient(60% 50% at 50% 28%, rgba(124,196,255,.08), transparent 58%),
126
+ linear-gradient(180deg, rgba(11,16,24,.2), var(--bg) 88%);
114
127
  }
115
128
  main{position:relative;z-index:2;padding-top:84px}
116
129
 
117
- /* kill old hero */
118
- .hero,.hero-core,.title-powered,.scroll-cue,.eyebrow,.lede,.actions,.btn,.meta-row{display:none!important}
130
+
131
+ /* homepage */
132
+ .home{
133
+ min-height:calc(100dvh - 84px);
134
+ display:grid;place-items:center;
135
+ padding:clamp(20px,4vh,44px) var(--pad) clamp(56px,9vh,96px);
136
+ position:relative;overflow:hidden;text-align:center;
137
+ }
138
+ .home::after{
139
+ content:"";position:absolute;left:50%;bottom:22px;width:1px;height:74px;
140
+ background:linear-gradient(180deg, rgba(124,196,255,.65), transparent);
141
+ transform-origin:50% 0;animation:drop-line 2.8s var(--ease) infinite;
142
+ }
143
+ .home-inner{max-width:min(1100px,100%);width:100%;margin:0 auto;position:relative;display:flex;flex-direction:column;align-items:center}
144
+ .home-kicker{
145
+ font-family:var(--mono);font-size:10px;letter-spacing:.34em;text-transform:uppercase;color:var(--blue);
146
+ margin-bottom:6px;position:relative;z-index:3;
147
+ }
148
+ .hero-stage{position:relative;width:100%;display:grid;place-items:center;min-height:clamp(360px,52vh,560px)}
149
+ .hero-art{position:absolute;inset:0;display:grid;place-items:center;z-index:1;pointer-events:none}
150
+ #orb-gl{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);width:min(96vw,840px);aspect-ratio:1;display:none}
151
+ .webgl-orb #orb-gl{display:block}
152
+ .webgl-orb .hero-orb{display:none}
153
+ .hero-orb{
154
+ width:clamp(380px,50vw,640px);aspect-ratio:1;position:relative;transform-style:preserve-3d;
155
+ animation:orb-slew 22s linear infinite;
156
+ }
157
+ .hero-orb .lat{position:absolute;inset:0;border-radius:50%;border:1.4px solid rgba(124,196,255,.5);transform-style:preserve-3d;box-shadow:0 0 26px rgba(124,196,255,.12)}
158
+ .hero-orb .lat.l1{transform:rotateY(0deg)}
159
+ .hero-orb .lat.l2{transform:rotateY(45deg)}
160
+ .hero-orb .lat.l3{transform:rotateY(90deg)}
161
+ .hero-orb .lat.l4{transform:rotateY(135deg)}
162
+ .hero-orb .par{position:absolute;left:50%;top:50%;border-radius:50%;border:1.2px solid rgba(124,196,255,.38);transform-style:preserve-3d}
163
+ .hero-orb .par.p1{width:96%;height:96%;transform:translate(-50%,-50%) rotateX(90deg)}
164
+ .hero-orb .par.p2{width:78%;height:78%;transform:translate(-50%,-50%) rotateX(90deg) translateZ(calc(clamp(380px,50vw,640px) * .31))}
165
+ .hero-orb .par.p3{width:78%;height:78%;transform:translate(-50%,-50%) rotateX(90deg) translateZ(calc(clamp(380px,50vw,640px) * -.31))}
166
+ .hero-orb .eq{position:absolute;inset:-4%;border-radius:50%;border:2px solid rgba(167,216,255,.75);transform:rotateX(76deg);box-shadow:0 0 40px rgba(124,196,255,.35)}
167
+ .hero-orb .core-glow{
168
+ position:absolute;inset:33%;border-radius:50%;
169
+ background:radial-gradient(circle at 40% 36%, rgba(232,241,250,.9), rgba(124,196,255,.65) 34%, rgba(124,196,255,.12) 68%, transparent);
170
+ box-shadow:0 0 46px rgba(124,196,255,.45), 0 0 110px rgba(124,196,255,.18);
171
+ animation:core-pulse 3.4s var(--ease) infinite;
172
+ }
173
+ .hero-orb .orbit-dot{position:absolute;width:10px;height:10px;border-radius:50%;background:var(--blue2);box-shadow:0 0 20px rgba(167,216,255,.9);left:calc(50% - 5px);top:calc(50% - 5px);transform:rotateX(76deg) translateX(clamp(170px,23vw,280px));animation:none}
174
+ .home-title{
175
+ position:relative;z-index:2;
176
+ font-family:var(--display);font-weight:300;font-size:clamp(96px,17vw,230px);line-height:.9;letter-spacing:-.045em;
177
+ text-transform:uppercase;color:var(--ink);
178
+ text-shadow:0 2px 30px rgba(0,0,0,.6);
179
+ }
180
+ .home-title em{font-style:italic;color:var(--blue2)}
181
+ .home-copy{position:relative;z-index:3;display:flex;flex-direction:column;align-items:center}
182
+ .home-copy p:not(.home-kicker){max-width:56ch;color:#aac0d6;font-size:16px;line-height:1.7;margin:18px 0 0;text-shadow:0 1px 20px rgba(0,0,0,.65)}
183
+ .home-actions{display:flex;flex-wrap:wrap;gap:14px;margin-top:26px;align-items:center;justify-content:center}
184
+ .enter-cta{
185
+ display:inline-flex;align-items:center;gap:12px;border:1px solid rgba(124,196,255,.45);border-radius:999px;
186
+ padding:14px 22px;color:var(--ink);font-family:var(--mono);font-size:10px;letter-spacing:.18em;text-transform:uppercase;
187
+ background:linear-gradient(180deg, rgba(124,196,255,.12), rgba(124,196,255,.035));
188
+ box-shadow:0 0 0 1px rgba(124,196,255,.08),0 20px 46px rgba(0,0,0,.3);
189
+ transition:transform .35s var(--ease),border-color .35s,box-shadow .35s;
190
+ }
191
+ .enter-cta::after{content:"↓";font-size:13px;color:var(--blue)}
192
+ .enter-cta:hover{transform:translateY(-2px);border-color:var(--blue);box-shadow:0 0 0 1px rgba(124,196,255,.18),0 24px 58px rgba(0,0,0,.36)}
193
+ .hero-note{font-family:var(--mono);font-size:10px;letter-spacing:.16em;text-transform:uppercase;color:var(--mute)}
194
+ @keyframes orb-slew{0%{transform:rotateX(18deg) rotateZ(-8deg) rotateY(0deg)}100%{transform:rotateX(18deg) rotateZ(-8deg) rotateY(360deg)}}
195
+ @keyframes home-breathe{0%,100%{opacity:.65;transform:scale(1)}50%{opacity:1;transform:scale(1.07)}}
196
+ @keyframes drop-line{0%,100%{opacity:.25;transform:translateX(-50%) scaleY(.45)}50%{opacity:1;transform:translateX(-50%) scaleY(1)}}}
197
+
119
198
 
120
199
  .section{
121
200
  position:relative;z-index:2;max-width:var(--max);margin:0 auto;
@@ -124,85 +203,15 @@ main{position:relative;z-index:2;padding-top:84px}
124
203
  .section:first-of-type{padding-top:clamp(18px,3vh,28px)}
125
204
  .section-label{
126
205
  font-family:var(--mono);font-size:10px;letter-spacing:.34em;text-transform:uppercase;color:var(--blue);margin-bottom:14px;
127
- }
128
- .veil{
129
- position:absolute;inset:0;z-index:1;pointer-events:none;
130
- background:
131
- radial-gradient(70% 55% at 50% 42%, transparent 0%, rgba(11,16,24,.3) 48%, var(--bg) 82%),
132
- linear-gradient(180deg, rgba(11,16,24,.28) 0%, transparent 24%, transparent 70%, var(--bg) 100%);
133
- }
134
- .hero-core{
135
- position:relative;z-index:2;width:min(920px,100%);
136
- display:flex;flex-direction:column;align-items:center;text-align:center;
137
- gap:clamp(18px,3vw,28px);
138
- }
139
- .eyebrow{
140
- font-family:var(--mono);font-size:11px;letter-spacing:.46em;text-transform:uppercase;color:var(--blue);
141
206
  display:inline-flex;align-items:center;gap:12px;
142
207
  }
143
- .eyebrow::before,.eyebrow::after{content:"";width:28px;height:1px;background:var(--blue-dim)}
144
- h1{
145
- font-family:var(--display);font-weight:300;
146
- font-size:clamp(78px,17vw,176px);line-height:.86;letter-spacing:.01em;
147
- text-transform:none;
148
- }
149
- h1 em{
150
- font-style:italic;font-weight:400;
151
- background:linear-gradient(110deg, var(--blue2) 8%, var(--blue) 48%, #cfe9ff 100%);
152
- -webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;
153
- }
154
- .title-powered{
155
- display:inline-flex;align-items:center;gap:10px;
156
- margin-top:-6px;
157
- font-family:var(--mono);font-size:11px;letter-spacing:.28em;text-transform:uppercase;color:var(--mute);
158
- }
159
- .title-powered .mark{
160
- width:6px;height:6px;border-radius:50%;background:var(--blue);
161
- box-shadow:0 0 10px rgba(124,196,255,.7);
162
- }
163
- .title-powered a{
164
- color:var(--blue);font-weight:500;border-bottom:1px solid transparent;
165
- transition:border-color .25s,color .25s;letter-spacing:.2em;
166
- }
167
- .title-powered a:hover{border-bottom-color:var(--blue);color:var(--ink)}
168
- .lede{max-width:34ch;font-size:clamp(15px,1.7vw,18px);line-height:1.65;color:var(--cool);font-weight:300}
169
- .actions{display:flex;flex-wrap:wrap;gap:12px;justify-content:center;margin-top:6px}
170
- .btn{
171
- font-family:var(--mono);font-size:11px;letter-spacing:.2em;text-transform:uppercase;
172
- border-radius:999px;padding:15px 26px;
173
- transition:transform .3s var(--ease),box-shadow .35s,background .3s,border-color .3s,color .3s;
174
- }
175
- .btn-primary{background:var(--blue);color:#061018;font-weight:500}
176
- .btn-primary:hover{transform:translateY(-2px);box-shadow:0 14px 36px rgba(124,196,255,.28)}
177
- .btn-ghost{border:1px solid var(--line);color:var(--cool)}
178
- .btn-ghost:hover{border-color:var(--blue-dim);color:var(--blue2)}
179
- .meta-row{
180
- margin-top:10px;display:flex;flex-wrap:wrap;gap:18px;justify-content:center;
181
- font-family:var(--mono);font-size:10px;letter-spacing:.18em;text-transform:uppercase;color:var(--mute);
182
- }
183
- .meta-row span{display:inline-flex;align-items:center;gap:8px}
184
- .meta-row i{width:5px;height:5px;border-radius:50%;background:var(--blue);opacity:.75;box-shadow:0 0 8px rgba(124,196,255,.6)}
185
- .scroll-cue{
186
- position:absolute;left:50%;bottom:28px;transform:translateX(-50%);z-index:2;
187
- display:flex;flex-direction:column;align-items:center;gap:10px;
188
- font-family:var(--mono);font-size:9px;letter-spacing:.32em;text-transform:uppercase;color:var(--mute);
189
- }
190
- .scroll-cue .line{width:1px;height:42px;background:linear-gradient(var(--blue),transparent)}
191
-
192
- .section{
193
- position:relative;z-index:2;max-width:var(--max);margin:0 auto;
194
- padding:clamp(72px,12vh,130px) var(--pad) 0;
195
- }
196
- .section-label{
197
- font-family:var(--mono);font-size:10px;letter-spacing:.34em;text-transform:uppercase;color:var(--blue);margin-bottom:14px;
198
- }
199
208
  .section-title{
200
209
  font-family:var(--display);font-weight:400;
201
210
  font-size:clamp(34px,5vw,54px);line-height:1.06;letter-spacing:-.01em;
202
- max-width:16ch;margin-bottom:12px;
211
+ max-width:18ch;margin-bottom:12px;
203
212
  }
204
213
  .section-title em{font-style:italic;color:var(--blue2)}
205
- .section-lede{max-width:50ch;color:var(--cool);font-size:15px;line-height:1.65;margin-bottom:clamp(28px,4vw,44px)}
214
+ .section-lede{max-width:52ch;color:var(--cool);font-size:15px;line-height:1.65;margin-bottom:clamp(28px,4vw,44px)}
206
215
 
207
216
  /* orchestration graph */
208
217
  .graph-shell{
@@ -243,33 +252,48 @@ h1 em{
243
252
  }
244
253
  .node:hover{transform:translateY(-2px);box-shadow:0 12px 30px rgba(0,0,0,.28)}
245
254
  .node.hub{
246
- width:min(280px,100%);
255
+ width:min(300px,100%);
247
256
  border-color:rgba(124,196,255,.5);
248
257
  background:linear-gradient(180deg, rgba(124,196,255,.12), rgba(11,16,24,.88));
249
258
  box-shadow:0 0 0 1px rgba(124,196,255,.08), 0 16px 40px rgba(0,0,0,.3);
250
- padding:18px 16px;
259
+ padding:18px 16px 20px;
260
+ display:flex;flex-direction:column;align-items:center;
251
261
  }
262
+ .node.hub .orbital{width:74px;height:74px;margin:2px 0 10px;filter:drop-shadow(0 0 20px rgba(124,196,255,.35))}
252
263
  .node .tag{font-family:var(--mono);font-size:9px;letter-spacing:.2em;text-transform:uppercase;color:var(--mute);margin-bottom:8px}
253
264
  .node.hub .tag{color:var(--blue)}
254
265
  .node .name{font-family:var(--display);font-size:22px;line-height:1;letter-spacing:.01em;margin-bottom:6px}
255
- .node.hub .name{font-size:34px;font-weight:400}
266
+ .node.hub .name{font-size:34px;font-weight:400;font-style:italic}
256
267
  .node .sub{font-family:var(--mono);font-size:10px;letter-spacing:.06em;color:var(--cool);line-height:1.45}
257
- .node.route{min-height:132px;display:flex;flex-direction:column;justify-content:flex-start;text-align:left;padding:14px}
268
+ .node.route{min-height:138px;display:flex;flex-direction:column;justify-content:flex-start;text-align:left;padding:14px}
258
269
  .node.route .name{font-size:18px;margin-bottom:8px}
259
270
  .node.route .chains{
260
271
  margin-top:auto;padding-top:10px;
261
- font-family:var(--mono);font-size:10px;letter-spacing:.04em;line-height:1.55;
272
+ font-family:var(--mono);font-size:10px;letter-spacing:.04em;line-height:1.7;
273
+ display:flex;flex-wrap:wrap;gap:4px 10px;align-items:center;
262
274
  }
275
+ .ch{display:inline-flex;align-items:center;gap:5px;white-space:nowrap}
276
+ .ch img{width:13px;height:13px;border-radius:50%;object-fit:cover;background:rgba(255,255,255,.06)}
263
277
  .node.add{
264
278
  border-style:dashed;border-color:rgba(124,196,255,.28);
265
279
  background:rgba(11,16,24,.35);
266
- min-height:132px;display:flex;flex-direction:column;justify-content:center;align-items:flex-start;
280
+ min-height:138px;display:flex;flex-direction:column;justify-content:center;align-items:flex-start;
267
281
  text-align:left;padding:14px;
268
282
  }
269
283
  .node.add .name{font-size:18px;color:var(--blue2)}
270
284
  .node.add .sub{color:var(--mute)}
271
285
  .node.add:hover{border-color:rgba(124,196,255,.55);background:rgba(124,196,255,.06)}
272
286
 
287
+ .builder-row{margin-top:0;display:flex;justify-content:center}
288
+ .node.builder-sink{width:min(430px,100%);text-align:center;align-items:center;min-height:162px;position:relative}
289
+ .node.builder-sink .name{font-size:26px}
290
+ .node.builder-sink .chains{justify-content:center}
291
+ .wires.funnel{height:62px}
292
+ .wires.funnel path{stroke:rgba(255,176,137,.48)}
293
+ .wires.funnel path:nth-child(2n){stroke:rgba(124,196,255,.32)}
294
+ .wires.funnel circle{fill:#ffb089}
295
+
296
+
273
297
  /* protocol colors */
274
298
  .node.p-hl{border-color:rgba(80,210,193,.45);background:linear-gradient(180deg, rgba(80,210,193,.14), rgba(11,16,24,.88))}
275
299
  .node.p-hl .tag,.node.p-hl .name{color:var(--hl)}
@@ -338,16 +362,13 @@ h1 em{
338
362
  .moat-card{
339
363
  background:var(--bg);padding:clamp(20px,3vw,28px);min-height:140px;
340
364
  display:flex;flex-direction:column;gap:10px;
365
+ transition:background .35s;
341
366
  }
342
367
  .moat-card:hover{background:var(--panel-2)}
343
368
  .moat-card .n{font-family:var(--mono);font-size:10px;letter-spacing:.2em;text-transform:uppercase;color:var(--blue)}
344
369
  .moat-card h3{font-family:var(--display);font-weight:400;font-size:clamp(20px,2.2vw,26px)}
345
- .moat-card p{color:var(--cool);font-size:14px;line-height:1.55;max-width:40ch}
370
+ .moat-card p{color:var(--cool);font-size:14px;line-height:1.55;max-width:44ch}
346
371
  @media (max-width:860px){.moat-grid{grid-template-columns:1fr}}
347
- .posture-chip{
348
- font-family:var(--mono);font-size:9px;letter-spacing:.16em;text-transform:uppercase;
349
- border:1px solid rgba(124,196,255,.35);border-radius:999px;padding:6px 10px;color:var(--blue2);
350
- }
351
372
  .evolve-rail{
352
373
  display:flex;flex-wrap:wrap;gap:8px;justify-content:center;
353
374
  padding:14px 16px 4px;
@@ -360,20 +381,26 @@ h1 em{
360
381
 
361
382
  .wires{height:40px;position:relative}
362
383
  .wires svg{width:100%;height:100%;display:block;overflow:visible}
363
- .wires path{fill:none;stroke:rgba(124,196,255,.35);stroke-width:1.25;stroke-linecap:round}
364
- .wires circle{fill:var(--blue)}
384
+ .wires path{
385
+ fill:none;stroke:rgba(124,196,255,.35);stroke-width:1.25;stroke-linecap:round;
386
+ stroke-dasharray:1;stroke-dashoffset:1;
387
+ transition:stroke-dashoffset 1.3s var(--ease);
388
+ }
389
+ .wires.in path{stroke-dashoffset:0}
390
+ .wires path.w-2{transition-delay:.12s}
391
+ .wires path.w-3{transition-delay:.2s}
392
+ .wires path.w-4{transition-delay:.28s}
393
+ .wires path.w-5{transition-delay:.36s}
394
+ .wires circle{fill:var(--blue);opacity:0;transition:opacity .5s var(--ease) .7s}
395
+ .wires.in circle{opacity:1}
365
396
  .wires.multi path.w-poly{stroke:rgba(59,130,246,.55)}
366
397
  .wires.multi path.w-hl{stroke:rgba(80,210,193,.55)}
367
398
  .wires.multi path.w-rh{stroke:rgba(215,255,77,.6)}
368
399
  .wires.multi path.w-sol{stroke:rgba(153,69,255,.55)}
369
- .wires.multi path.w-stable{stroke:rgba(240,185,11,.55)}
370
- .wires.multi path.w-add{stroke:rgba(124,196,255,.35);stroke-dasharray:3 3}
371
400
  .wires.multi circle.c-poly{fill:var(--poly)}
372
401
  .wires.multi circle.c-hl{fill:var(--hl)}
373
402
  .wires.multi circle.c-rh{fill:var(--rh)}
374
403
  .wires.multi circle.c-sol{fill:var(--sol)}
375
- .wires.multi circle.c-stable{fill:var(--stable)}
376
- .wires.multi circle.c-add{fill:var(--blue2)}
377
404
 
378
405
  /* route detail cards */
379
406
  .route-card{
@@ -381,7 +408,8 @@ h1 em{
381
408
  display:flex;flex-direction:column;gap:10px;transition:background .35s;
382
409
  }
383
410
  .route-card:hover{background:var(--panel-2)}
384
- .route-card h3{font-family:var(--display);font-weight:400;font-size:26px}
411
+ .route-card h3{font-family:var(--display);font-weight:400;font-size:26px;display:flex;align-items:center;gap:10px}
412
+ .route-card h3 img{width:20px;height:20px;border-radius:50%;object-fit:cover;background:rgba(255,255,255,.06)}
385
413
  .route-card .where{font-family:var(--mono);font-size:10px;letter-spacing:.16em;text-transform:uppercase;color:var(--blue)}
386
414
  .route-card p{color:var(--cool);font-size:13.5px;line-height:1.55}
387
415
  .route-card .chips{display:flex;flex-wrap:wrap;gap:6px;margin-top:auto}
@@ -389,10 +417,6 @@ h1 em{
389
417
  font-family:var(--mono);font-size:9px;letter-spacing:.1em;text-transform:uppercase;
390
418
  border:1px solid var(--line);border-radius:999px;padding:5px 8px;color:var(--cool);
391
419
  }
392
- .route-card .why{
393
- margin-top:4px;padding-top:12px;border-top:1px solid var(--line);
394
- font-family:var(--display);font-style:italic;font-size:17px;line-height:1.45;color:var(--blue2);
395
- }
396
420
  .why-band{
397
421
  border-top:1px solid var(--line);
398
422
  padding:22px 24px 24px;
@@ -417,9 +441,10 @@ h1 em{
417
441
  transition:border-color .3s,transform .3s var(--ease);
418
442
  }
419
443
  .chain:hover{border-color:rgba(124,196,255,.35);transform:translateY(-2px)}
420
- .chain-top{display:flex;justify-content:space-between;gap:8px}
421
- .chain .nm{font-family:var(--display);font-size:20px}
422
- .chain .id{font-family:var(--mono);font-size:11px;color:var(--blue)}
444
+ .chain-top{display:flex;justify-content:space-between;gap:8px;align-items:flex-start}
445
+ .chain .nm{font-family:var(--display);font-size:20px;display:flex;align-items:center;gap:8px}
446
+ .chain .nm img{width:18px;height:18px;border-radius:50%;object-fit:cover;background:rgba(255,255,255,.06)}
447
+ .chain .id{font-family:var(--mono);font-size:11px;color:var(--blue);white-space:nowrap;padding-top:4px}
423
448
  .chain .meta{
424
449
  display:flex;justify-content:space-between;gap:8px;
425
450
  font-family:var(--mono);font-size:10px;letter-spacing:.12em;text-transform:uppercase;color:var(--mute);
@@ -431,14 +456,47 @@ h1 em{
431
456
  .venues-head{
432
457
  padding:11px 14px;border-bottom:1px solid var(--line);
433
458
  font-family:var(--mono);font-size:10px;letter-spacing:.2em;text-transform:uppercase;color:var(--mute);
459
+ display:flex;justify-content:space-between;gap:10px;flex-wrap:wrap;
434
460
  }
461
+ .venues-head b{color:var(--blue);font-weight:500}
435
462
  .marquee{overflow:hidden;white-space:nowrap;mask-image:linear-gradient(90deg,transparent,#000 6%,#000 94%,transparent)}
436
- .track{display:inline-flex;gap:24px;padding:13px 0;animation:scroll 42s linear infinite;will-change:transform}
463
+ .marquee + .marquee{border-top:1px solid rgba(124,196,255,.08)}
464
+ .track{display:inline-flex;gap:26px;padding:12px 0;animation:scroll 48s linear infinite;will-change:transform}
465
+ .marquee.rev .track{animation-direction:reverse;animation-duration:56s}
437
466
  .chip{
438
- display:inline-flex;align-items:center;gap:8px;
439
- font-family:var(--mono);font-size:11px;letter-spacing:.1em;text-transform:uppercase;color:var(--cool);
467
+ display:inline-flex;align-items:center;gap:10px;
468
+ font-size:15px;letter-spacing:-.015em;text-transform:none;color:var(--proto-color,var(--cool));
469
+ padding:8px 13px;border:1px solid rgba(124,196,255,.1);border-radius:999px;background:rgba(11,16,24,.38);
470
+ box-shadow:inset 0 0 0 1px rgba(255,255,255,.025);
440
471
  }
441
- .chip::before{content:"";width:5px;height:5px;border-radius:50%;background:var(--blue);opacity:.75}
472
+ .chip img{width:18px;height:18px;border-radius:50%;object-fit:cover;background:rgba(255,255,255,.06)}
473
+ .chip.wm-chip{padding:10px 16px}
474
+ .chip img.wm{width:auto;height:20px;max-width:150px;border-radius:0;object-fit:contain;background:none;opacity:.92}
475
+
476
+ .chip .wordmark{font-family:var(--proto-font,var(--sans));font-weight:var(--proto-weight,750);font-style:var(--proto-style,normal);text-transform:var(--proto-transform,none);letter-spacing:var(--proto-track,-.025em);line-height:1.2}
477
+ .proto-uniswap{--proto-font:"Inter",var(--sans);--proto-color:#ff4dcb;--proto-weight:850}
478
+ .proto-hyperliquid{--proto-font:var(--display);--proto-style:italic;--proto-color:#50d2c1;--proto-weight:500;--proto-track:.01em}
479
+ .proto-polymarket{--proto-font:"Manrope",var(--sans);--proto-color:#7aa7ff;--proto-weight:800;--proto-track:-.035em}
480
+ .proto-aerodrome,.proto-velodrome{--proto-font:"Space Grotesk",var(--sans);--proto-color:#f2f7ff;--proto-weight:700;--proto-transform:lowercase}
481
+ .proto-pancakeswap{--proto-font:"DM Sans",var(--sans);--proto-color:#d1884f;--proto-weight:700}
482
+ .proto-quickswap{--proto-font:"Archivo Black",var(--sans);--proto-color:#35a7ff;--proto-weight:800;--proto-transform:uppercase;--proto-track:.005em}
483
+ .proto-lfj{--proto-font:"Sora",var(--sans);--proto-color:#ff6357;--proto-weight:700;--proto-transform:uppercase;--proto-track:.05em}
484
+ .proto-hyperswap{--proto-font:"Space Grotesk",var(--sans);--proto-color:#69f0d8;--proto-weight:700}
485
+ .proto-curve{--proto-font:"Times New Roman",serif;--proto-color:#f7f3dd;--proto-weight:700;--proto-track:.01em}
486
+ .proto-balancer{--proto-font:"Inter",var(--sans);--proto-color:#f6f6f6;--proto-weight:850;--proto-track:-.055em}
487
+ .proto-pendle{--proto-font:"Sora",var(--sans);--proto-color:#a7f3d0;--proto-weight:700}
488
+ .proto-morpho{--proto-font:"Manrope",var(--sans);--proto-color:#75b9ff;--proto-weight:800;--proto-track:-.04em}
489
+ .proto-gmx{--proto-font:"Archivo Black",var(--sans);--proto-color:#41d3ff;--proto-weight:800;--proto-transform:uppercase;--proto-track:.04em}
490
+ .proto-lifi{--proto-font:"Inter",var(--sans);--proto-color:#d8b4fe;--proto-weight:850;--proto-transform:uppercase;--proto-track:.02em}
491
+ .proto-relay{--proto-font:"Space Grotesk",var(--sans);--proto-color:#f2f7ff;--proto-weight:700;--proto-transform:lowercase}
492
+ .proto-paraswap{--proto-font:"Manrope",var(--sans);--proto-color:#ff9a76;--proto-weight:800}
493
+ .proto-odos{--proto-font:"Sora",var(--sans);--proto-color:#f0f9ff;--proto-weight:700;--proto-transform:lowercase}
494
+ .proto-cow{--proto-font:"DM Sans",var(--sans);--proto-color:#fcd34d;--proto-weight:700}
495
+ .proto-oneinch{--proto-font:"Inter",var(--sans);--proto-color:#9ec5ff;--proto-weight:850;--proto-track:-.045em}
496
+ .proto-jupiter{--proto-font:"Space Grotesk",var(--sans);--proto-color:#f6a5ff;--proto-weight:700}
497
+ .proto-across{--proto-font:"Manrope",var(--sans);--proto-color:#ff6b9b;--proto-weight:800}
498
+ .proto-stargate{--proto-font:"Sora",var(--sans);--proto-color:#9ddcff;--proto-weight:700}
499
+ .proto-magic-eden{--proto-font:"Archivo Black",var(--sans);--proto-color:#dfc7ff;--proto-weight:800;--proto-track:.01em}
442
500
  @keyframes scroll{from{transform:translateX(0)}to{transform:translateX(-50%)}}
443
501
 
444
502
  .wallet-grid{
@@ -463,7 +521,7 @@ h1 em{
463
521
  .wallet-grid{grid-template-columns:1fr}
464
522
  }
465
523
 
466
- footer{margin-top:clamp(72px,12vh,120px);border-top:1px solid var(--line);padding:32px var(--pad) 40px}
524
+ footer{margin-top:clamp(72px,12vh,120px);border-top:1px solid var(--line);padding:32px var(--pad) 40px;position:relative;z-index:2}
467
525
  .foot-row{
468
526
  max-width:var(--max);margin:0 auto 14px;
469
527
  display:flex;flex-wrap:wrap;gap:14px 24px;justify-content:space-between;align-items:center;
@@ -483,12 +541,13 @@ footer{margin-top:clamp(72px,12vh,120px);border-top:1px solid var(--line);paddin
483
541
  font-family:var(--mono);font-size:10px;letter-spacing:.16em;text-transform:uppercase;color:var(--mute);
484
542
  }
485
543
 
486
- .js .rv{opacity:0;transform:translateY(16px)}
487
- .js .rv.in{opacity:1;transform:none;transition:opacity 1s var(--ease),transform 1s var(--ease)}
544
+ .js .rv{opacity:0;transform:translateY(18px);filter:blur(4px)}
545
+ .js .rv.in{opacity:1;transform:none;filter:blur(0);transition:opacity 1s var(--ease),transform 1s var(--ease),filter .9s var(--ease)}
546
+ .js .rv.done{filter:none;transform:none;will-change:auto}
488
547
 
489
548
  @media (max-width:960px){
490
- .nav{grid-template-columns:1fr auto}
491
- .nav-mid{display:none}
549
+ .hero-stage{min-height:clamp(300px,44vh,460px)}.home-title{font-size:clamp(80px,20vw,150px)}
550
+ .nav-chip{display:none}
492
551
  .nav-links .hide-sm{display:none}
493
552
  .route-strip{grid-template-columns:1fr}
494
553
  .chain-grid{grid-template-columns:repeat(2,minmax(0,1fr))}
@@ -496,42 +555,57 @@ footer{margin-top:clamp(72px,12vh,120px);border-top:1px solid var(--line);paddin
496
555
  .row.profiles{grid-template-columns:repeat(2,minmax(0,1fr))}
497
556
  }
498
557
  @media (max-width:560px){
558
+ .home{min-height:auto;padding-top:36px}.hero-stage{min-height:280px}.hero-orb{width:min(84vw,340px)}
499
559
  .chain-grid{grid-template-columns:1fr}
500
560
  .row.profiles{grid-template-columns:1fr}
501
- h1{font-size:clamp(68px,18vw,96px)}
502
561
  }
503
562
  @media (prefers-reduced-motion:reduce){
504
563
  html{scroll-behavior:auto}
505
- .js .rv{opacity:1;transform:none}
506
- .loader-mark i,.track{animation:none}
564
+ .js .rv{opacity:1;transform:none;filter:none}
565
+ .track,.orbital .ring,.orbital .tickring,.orbital .core,.hero-orb,.hero-art::before,.home::after{animation:none}
566
+ .wires path{stroke-dasharray:none;stroke-dashoffset:0}
567
+ .wires circle{opacity:1}
507
568
  .node:hover,.chain:hover{transform:none}
508
569
  }
509
570
  </style>
510
571
  </head>
511
572
  <body>
512
573
  <div class="grain" aria-hidden="true"></div>
574
+ <div class="progress" id="progress" aria-hidden="true"></div>
513
575
 
514
576
  <div class="loader" id="loader" aria-hidden="true">
515
577
  <div class="loader-inner">
516
- <div class="loader-mark" aria-hidden="true"><i></i><b></b></div>
517
- <div class="loader-word">oracle</div>
518
- <div class="loader-bar"><span id="loader-fill"></span></div>
578
+ <div class="loader-mark orbital" aria-hidden="true">
579
+ <svg viewBox="0 0 100 100">
580
+ <g class="ring r1"><ellipse cx="50" cy="50" rx="44" ry="15"/></g>
581
+ <g class="ring r2"><ellipse cx="50" cy="50" rx="44" ry="15" transform="rotate(62 50 50)"/></g>
582
+ <g class="ring r3"><ellipse cx="50" cy="50" rx="44" ry="15" transform="rotate(124 50 50)"/></g>
583
+ <circle class="tickring" cx="50" cy="50" r="30"/>
584
+ <circle class="halo" cx="50" cy="50" r="9"/>
585
+ <circle class="core" cx="50" cy="50" r="6.5"/>
586
+ </svg>
587
+ </div>
588
+ <div class="loader-word">oracle</div>
589
+ <div class="loader-bar"><span id="loader-fill"></span></div>
519
590
  </div>
520
591
  </div>
521
592
 
522
593
  <header class="nav">
523
- <a class="brand" href="#top"><span class="orb" aria-hidden="true"></span>oracle</a>
524
- <div class="nav-mid" aria-label="Status">
525
- <span>for <b>users</b></span>
526
- <span>full crypto pack // protocol builder</span>
527
- <span class="posture-chip">disarmed by default</span>
528
- <span>powered by <a class="hermes" href="https://hermes-agent.nousresearch.com" target="_blank" rel="noopener noreferrer">Hermes</a></span>
529
- </div>
594
+ <a class="brand" href="#top">
595
+ <span class="orbital" aria-hidden="true">
596
+ <svg viewBox="0 0 100 100">
597
+ <g class="ring r1"><ellipse cx="50" cy="50" rx="45" ry="17"/></g>
598
+ <g class="ring r2"><ellipse cx="50" cy="50" rx="45" ry="17" transform="rotate(64 50 50)"/></g>
599
+ <circle class="halo" cx="50" cy="50" r="13"/>
600
+ <circle class="core" cx="50" cy="50" r="11"/>
601
+ </svg>
602
+ </span>
603
+ oracle</a>
530
604
  <nav class="nav-links" aria-label="Primary">
531
- <a class="hide-sm" href="#orchestration">How it works</a>
532
- <a class="hide-sm" href="#wallets">Wallets</a>
533
- <a class="hide-sm" href="#chains">Chains</a>
534
- <a class="nav-cta" href="/oracle-console/">Open console</a>
605
+ <span class="nav-chip">13 chains · 6 bounded surfaces</span>
606
+ <a class="hide-sm" href="#orchestration">How it works</a>
607
+ <a class="hide-sm" href="#wallets">Wallets</a>
608
+ <a class="hide-sm" href="#chains">Chains</a>
535
609
  </nav>
536
610
  </header>
537
611
 
@@ -539,322 +613,373 @@ footer{margin-top:clamp(72px,12vh,120px);border-top:1px solid var(--line);paddin
539
613
  <canvas id="gl" aria-hidden="true"></canvas>
540
614
  <div class="veil" aria-hidden="true"></div>
541
615
 
616
+ <section class="home" id="home">
617
+ <div class="home-inner">
618
+ <div class="hero-stage">
619
+ <div class="hero-art" aria-hidden="true">
620
+ <canvas id="orb-gl"></canvas>
621
+ <div class="hero-orb" id="hero-orb">
622
+ <span class="lat l1"></span><span class="lat l2"></span><span class="lat l3"></span><span class="lat l4"></span>
623
+ <span class="par p1"></span><span class="par p2"></span><span class="par p3"></span>
624
+ <span class="eq"></span>
625
+ <span class="core-glow"></span>
626
+ <span class="orbit-dot"></span>
627
+ </div>
628
+ </div>
629
+ <h1 class="home-title" id="hero-title">OR<em>ACLE</em></h1>
630
+ </div>
631
+ <div class="home-copy">
632
+ <p class="home-kicker">self-custody agent control</p>
633
+ <p>One control plane for Hyperliquid, Polymarket, EVM, Bitcoin, Solana, Stable, Robinhood Chain, and new protocol builds. The model prepares. Policy bounds. You enter when your wallet signs.</p>
634
+ <div class="home-actions">
635
+ <a class="enter-cta" href="#orchestration">Enter oracle</a>
636
+ <span class="hero-note">13 chains · 6 bounded surfaces · protocol builder</span>
637
+ </div>
638
+ </div>
639
+ </div>
640
+ </section>
641
+
542
642
  <section class="section" id="orchestration">
543
643
  <p class="section-label rv">How it works</p>
544
644
  <h2 class="section-title rv">Multi-profile. <em>Customizable.</em></h2>
545
- <p class="section-lede rv">Not one bot. A mesh: Input / Command hits the oracle control plane, then fans out across venue profiles, multi-chain EVM, Bitcoin, and a protocol builder - with prepare-only custody.</p>
645
+ <p class="section-lede rv">Not one bot. A mesh: Input / Command hits the oracle control plane, then fans out across venue profiles, multi-chain EVM, Bitcoin, Solana, and a protocol builder. The public plane is prepare-only. Your wallet signs.</p>
546
646
 
547
647
  <div class="graph-shell rv">
548
- <div class="graph-top">
549
- <span>for <b>users</b></span>
550
- <span>multi-profile // protocol builder // multi-chain</span>
551
- <span>powered by Hermes</span>
552
- </div>
648
+ <div class="graph-top">
649
+ <span>for <b>users</b></span>
650
+ <span>multi-profile // protocol builder // multi-chain</span>
651
+ <span><b>prepare-only</b> public plane</span>
652
+ </div>
553
653
 
554
- <div class="evolve-rail">
555
- <span class="evolve-pill on">full crypto pack</span>
556
- <span class="evolve-pill on">customizable</span>
557
- <span class="evolve-pill on">protocol builder</span>
558
- <span class="evolve-pill on">more chains</span>
559
- <span class="evolve-pill on"><a href="https://hermes-agent.nousresearch.com" target="_blank" rel="noopener noreferrer" style="color:inherit">powered by Hermes</a></span>
560
- </div>
654
+ <div class="evolve-rail">
655
+ <span class="evolve-pill on">customizable</span>
656
+ <span class="evolve-pill on">protocol builder</span>
657
+ <span class="evolve-pill on">more chains</span>
658
+ </div>
561
659
 
562
- <div class="graph-canvas">
563
- <div class="orch" aria-label="Oracle multi-profile graph">
564
- <div class="row">
565
- <div class="node" style="width:220px">
566
- <div class="tag">you</div>
567
- <div class="name">Input / Command</div>
568
- <div class="sub">what you type or ask</div>
569
- </div>
570
- </div>
660
+ <div class="graph-canvas">
661
+ <div class="orch" aria-label="Oracle multi-profile graph">
662
+ <div class="row">
663
+ <div class="node" style="width:220px">
664
+ <div class="tag">you</div>
665
+ <div class="name">Input / Command</div>
666
+ <div class="sub">what you type or ask</div>
667
+ </div>
668
+ </div>
571
669
 
572
- <div class="wires" aria-hidden="true">
573
- <svg viewBox="0 0 100 36" preserveAspectRatio="none">
574
- <path d="M50 2 V34"/><circle cx="50" cy="2" r="1.4"/><circle cx="50" cy="34" r="1.4"/>
575
- </svg>
576
- </div>
670
+ <div class="wires" aria-hidden="true">
671
+ <svg viewBox="0 0 100 36" preserveAspectRatio="none">
672
+ <path d="M50 2 V34" pathLength="1"/><circle cx="50" cy="2" r="1.4"/><circle cx="50" cy="34" r="1.4"/>
673
+ </svg>
674
+ </div>
577
675
 
578
- <div class="row">
579
- <div class="node hub">
580
- <div class="tag">control plane</div>
581
- <div class="name">oracle</div>
582
- <div class="sub">route · bound · evolve</div>
583
- </div>
584
- </div>
676
+ <div class="row">
677
+ <div class="node hub">
678
+ <div class="tag">control plane</div>
679
+ <div class="orbital" aria-hidden="true">
680
+ <svg viewBox="0 0 100 100">
681
+ <g class="ring r1"><ellipse cx="50" cy="50" rx="46" ry="16"/></g>
682
+ <g class="ring r2"><ellipse cx="50" cy="50" rx="46" ry="16" transform="rotate(60 50 50)"/></g>
683
+ <g class="ring r3"><ellipse cx="50" cy="50" rx="46" ry="16" transform="rotate(120 50 50)"/></g>
684
+ <circle class="tickring" cx="50" cy="50" r="32"/>
685
+ <circle class="halo" cx="50" cy="50" r="10"/>
686
+ <circle class="core" cx="50" cy="50" r="7.5"/>
687
+ </svg>
688
+ </div>
689
+ <div class="name">oracle</div>
690
+ <div class="sub">route · bound · evolve</div>
691
+ </div>
692
+ </div>
585
693
 
586
- <div class="wires multi" aria-hidden="true">
587
- <svg viewBox="0 0 100 44" preserveAspectRatio="none">
588
- <path d="M50 2 V12"/>
589
- <path class="w-poly" d="M12.5 42 V20 H50 V12"/>
590
- <path class="w-hl" d="M37.5 42 V20 H50 V12"/>
591
- <path class="w-rh" d="M62.5 42 V20 H50 V12"/>
592
- <path class="w-sol" d="M87.5 42 V20 H50 V12"/>
593
- <circle cx="50" cy="2" r="1.3"/>
594
- <circle class="c-poly" cx="12.5" cy="42" r="1.3"/>
595
- <circle class="c-hl" cx="37.5" cy="42" r="1.3"/>
596
- <circle class="c-rh" cx="62.5" cy="42" r="1.3"/>
597
- <circle class="c-sol" cx="87.5" cy="42" r="1.3"/>
598
- </svg>
599
- </div>
694
+ <div class="wires multi" aria-hidden="true">
695
+ <svg viewBox="0 0 100 44" preserveAspectRatio="none">
696
+ <path d="M50 2 V12" pathLength="1"/>
697
+ <path class="w-poly w-2" d="M12.5 42 V20 H50 V12" pathLength="1"/>
698
+ <path class="w-hl w-3" d="M37.5 42 V20 H50 V12" pathLength="1"/>
699
+ <path class="w-rh w-4" d="M62.5 42 V20 H50 V12" pathLength="1"/>
700
+ <path class="w-sol w-5" d="M87.5 42 V20 H50 V12" pathLength="1"/>
701
+ <circle cx="50" cy="2" r="1.3"/>
702
+ <circle class="c-poly" cx="12.5" cy="42" r="1.3"/>
703
+ <circle class="c-hl" cx="37.5" cy="42" r="1.3"/>
704
+ <circle class="c-rh" cx="62.5" cy="42" r="1.3"/>
705
+ <circle class="c-sol" cx="87.5" cy="42" r="1.3"/>
706
+ </svg>
707
+ </div>
600
708
 
601
- <div class="row profiles" id="profile-grid">
602
- <div class="node route p-poly">
603
- <div class="tag">profile</div>
604
- <div class="name">polymarket agent</div>
605
- <div class="sub">events · arb · markets</div>
606
- <div class="chains">Polymarket</div>
607
- </div>
608
- <div class="node route p-hl">
609
- <div class="tag">profile</div>
610
- <div class="name">hyperliquid agent</div>
611
- <div class="sub">perps · hip-3/4 · ta</div>
612
- <div class="chains">Hyperliquid · HyperEVM 999</div>
613
- </div>
614
- <div class="node route p-rh">
615
- <div class="tag">profile</div>
616
- <div class="name">robinhood agent</div>
617
- <div class="sub">markets · nfts · names</div>
618
- <div class="chains">Robinhood Chain 4663</div>
619
- </div>
620
- <div class="node route p-sol">
621
- <div class="tag">profile</div>
622
- <div class="name">solana agent</div>
623
- <div class="sub">jup · nfts · dexs</div>
624
- <div class="chains">Solana mainnet</div>
625
- </div>
626
- <div class="node route p-btc">
627
- <div class="tag">profile</div>
628
- <div class="name">bitcoin agent</div>
629
- <div class="sub">ord · runes · research</div>
630
- <div class="chains">Bitcoin · inscriptions</div>
631
- </div>
632
- <div class="node route p-evm">
633
- <div class="tag">profile</div>
634
- <div class="name">evm / bridge agent</div>
635
- <div class="sub">swaps · bridges · defi</div>
636
- <div class="chains">ETH · Base · Arb · OP · BNB · Polygon · Avax</div>
637
- </div>
638
- <div class="node route p-stable">
639
- <div class="tag">profile</div>
640
- <div class="name">stable agent</div>
641
- <div class="sub">launches · venue ops</div>
642
- <div class="chains">Stable 988</div>
643
- </div>
644
- <div class="node route p-build">
645
- <div class="tag">builder</div>
646
- <div class="name">protocol builder</div>
647
- <div class="sub">scaffold · security · deploy prep</div>
648
- <div class="chains">any EVM · user-signed deploys</div>
649
- </div>
650
- <div class="node add">
651
- <div class="tag">open slot</div>
652
- <div class="name">+ add agent</div>
653
- <div class="sub">new chain · new venue · your rules</div>
654
- <div class="chains" style="margin-top:12px;font-family:var(--mono);font-size:10px;color:var(--blue2)">full crypto pack · powered by Hermes</div>
655
- </div>
656
- </div> </div>
657
- </div>
658
- </div>
709
+ <div class="row profiles" id="profile-grid">
710
+ <div class="node route p-poly">
711
+ <div class="tag">profile</div>
712
+ <div class="name">polymarket agent</div>
713
+ <div class="sub">events · arb · markets</div>
714
+ <div class="chains"><span class="ch">Polymarket <img src="https://icons.llamao.fi/icons/protocols/polymarket?w=24&h=24" alt="" loading="lazy"></span></div>
715
+ </div>
716
+ <div class="node route p-hl">
717
+ <div class="tag">profile</div>
718
+ <div class="name">hyperliquid agent</div>
719
+ <div class="sub">perps · hip-3/4 · ta</div>
720
+ <div class="chains"><span class="ch">Hyperliquid <img src="https://icons.llamao.fi/icons/protocols/hyperliquid?w=24&h=24" alt="" loading="lazy"></span><span class="ch">Hyperliquid 999 <img src="https://icons.llamao.fi/icons/chains/rsz_hyperliquid?w=24&h=24" alt="" loading="lazy"></span></div>
721
+ </div>
722
+ <div class="node route p-rh">
723
+ <div class="tag">profile</div>
724
+ <div class="name">robinhood agent</div>
725
+ <div class="sub">markets · nfts · names</div>
726
+ <div class="chains"><span class="ch">Robinhood Chain 4663 <img src="https://icons.llamao.fi/icons/chains/rsz_robinhood?w=24&h=24" alt="" loading="lazy"></span></div>
727
+ </div>
728
+ <div class="node route p-sol">
729
+ <div class="tag">profile</div>
730
+ <div class="name">solana agent</div>
731
+ <div class="sub">jup · nfts · dexs</div>
732
+ <div class="chains"><span class="ch">Solana <img src="https://icons.llamao.fi/icons/chains/rsz_solana?w=24&h=24" alt="" loading="lazy"></span></div>
733
+ </div>
734
+ <div class="node route p-btc">
735
+ <div class="tag">profile</div>
736
+ <div class="name">bitcoin agent</div>
737
+ <div class="sub">ord · runes · research</div>
738
+ <div class="chains"><span class="ch">Bitcoin <img src="https://icons.llamao.fi/icons/chains/rsz_bitcoin?w=24&h=24" alt="" loading="lazy"></span><span class="ch">inscriptions</span></div>
739
+ </div>
740
+ <div class="node route p-evm">
741
+ <div class="tag">profile</div>
742
+ <div class="name">evm / bridge agent</div>
743
+ <div class="sub">swaps · bridges · defi</div>
744
+ <div class="chains"><span class="ch">ETH <img src="https://icons.llamao.fi/icons/chains/rsz_ethereum?w=24&h=24" alt="" loading="lazy"></span><span class="ch">Base <img src="https://icons.llamao.fi/icons/chains/rsz_base?w=24&h=24" alt="" loading="lazy"></span><span class="ch">Arb <img src="https://icons.llamao.fi/icons/chains/rsz_arbitrum?w=24&h=24" alt="" loading="lazy"></span><span class="ch">OP <img src="https://icons.llamao.fi/icons/chains/rsz_optimism?w=24&h=24" alt="" loading="lazy"></span><span class="ch">BNB <img src="https://icons.llamao.fi/icons/chains/rsz_binance?w=24&h=24" alt="" loading="lazy"></span><span class="ch">Polygon <img src="https://icons.llamao.fi/icons/chains/rsz_polygon?w=24&h=24" alt="" loading="lazy"></span><span class="ch">Avax <img src="https://icons.llamao.fi/icons/chains/rsz_avalanche?w=24&h=24" alt="" loading="lazy"></span></div>
745
+ </div>
746
+ <div class="node route p-stable">
747
+ <div class="tag">profile</div>
748
+ <div class="name">stable agent</div>
749
+ <div class="sub">launches · venue ops</div>
750
+ <div class="chains"><span class="ch">Stable 988 <img src="https://icons.llamao.fi/icons/chains/rsz_stable?w=24&h=24" alt="" loading="lazy"></span></div>
751
+ </div>
752
+ <div class="node add">
753
+ <div class="tag">open slot</div>
754
+ <div class="name">+ add agent</div>
755
+ <div class="sub">new chain · new venue · your rules</div>
756
+ <div class="chains" style="margin-top:12px;font-family:var(--mono);font-size:10px;color:var(--blue2)">sits beside stable · same custody</div>
757
+ </div>
758
+ </div>
659
759
 
660
- <div class="route-strip">
661
- <article class="route-card p-poly">
662
- <div class="where">polymarket agent →</div>
663
- <h3>Polymarket</h3>
664
- <p>Event markets, sports, arb paths, and prediction flow under bounds you set.</p>
665
- <div class="chips">
666
- <span class="chip-s">events</span>
667
- <span class="chip-s">arb</span>
668
- <span class="chip-s">Polymarket</span>
669
- </div>
670
- </article>
671
- <article class="route-card p-hl">
672
- <div class="where">hyperliquid agent →</div>
673
- <h3>Hyperliquid</h3>
674
- <p>Native perps, HIP-3/4, TA, event risk, and HyperEVM when you need HL’s EVM surface.</p>
675
- <div class="chips">
676
- <span class="chip-s">perps</span>
677
- <span class="chip-s">HIP-3/4</span>
678
- <span class="chip-s">HyperEVM</span>
679
- </div>
680
- </article>
681
- <article class="route-card p-rh">
682
- <div class="where">robinhood agent →</div>
683
- <h3>Robinhood</h3>
684
- <p>RH Chain markets, NFTs, names, and chain-local execution on 4663.</p>
685
- <div class="chips">
686
- <span class="chip-s">markets</span>
687
- <span class="chip-s">NFTs</span>
688
- <span class="chip-s">4663</span>
689
- </div>
690
- </article>
691
- <article class="route-card p-sol">
692
- <div class="where">solana agent →</div>
693
- <h3>Solana</h3>
694
- <p>Swaps, research, Jupiter routes, and wallet-signed execution as the lane activates.</p>
695
- <div class="chips">
696
- <span class="chip-s">Jupiter</span>
697
- <span class="chip-s">swaps</span>
698
- <span class="chip-s">research</span>
699
- </div>
700
- </article>
701
- <article class="route-card p-btc">
702
- <div class="where">bitcoin agent →</div>
703
- <h3>Bitcoin</h3>
704
- <p>Ordinals, runes, and BTC research. Prepare inscriptions; you control signing.</p>
705
- <div class="chips">
706
- <span class="chip-s">ordinals</span>
707
- <span class="chip-s">runes</span>
708
- <span class="chip-s">BTC</span>
709
- </div>
710
- </article>
711
- <article class="route-card p-evm">
712
- <div class="where">evm / bridge agent →</div>
713
- <h3>Multi-chain EVM</h3>
714
- <p>DEX routes, LiFi/Relay bridges, and DeFi across ETH and L2s - always prepare-only until you sign.</p>
715
- <div class="chips">
716
- <span class="chip-s">ETH</span>
717
- <span class="chip-s">Base · Arb</span>
718
- <span class="chip-s">bridges</span>
719
- </div>
720
- </article>
721
- <article class="route-card p-stable">
722
- <div class="where">stable agent →</div>
723
- <h3>Stable</h3>
724
- <p>Stable mainnet launches and venue ops on chain 988.</p>
725
- <div class="chips">
726
- <span class="chip-s">launches</span>
727
- <span class="chip-s">Stable 988</span>
728
- </div>
729
- </article>
730
- <article class="route-card p-build">
731
- <div class="where">protocol builder →</div>
732
- <h3>Build protocols</h3>
733
- <p>Scaffold contracts, run security gates (Foundry + static checks), prepare unsigned deploys. You still sign every deploy.</p>
734
- <div class="chips">
735
- <span class="chip-s">scaffold</span>
736
- <span class="chip-s">security gate</span>
737
- <span class="chip-s">unsigned deploy</span>
738
- </div>
739
- </article>
740
- <article class="route-card p-add">
741
- <div class="where">+ add agent →</div>
742
- <h3>Next chain</h3>
743
- <p>Drop in another profile for a new chain or venue. Same custody model - your wallet, your limits, your revoke.</p>
744
- <div class="chips">
745
- <span class="chip-s">custom profile</span>
746
- <span class="chip-s">more chains</span>
747
- <span class="chip-s">powered by Hermes</span>
748
- </div>
749
- </article>
750
- </div>
760
+ <div class="wires funnel" aria-hidden="true">
761
+ <svg viewBox="0 0 100 62" preserveAspectRatio="none">
762
+ <path class="w-1" d="M6 2 C6 30 50 22 50 60" pathLength="1"/>
763
+ <path class="w-2" d="M19 2 C19 28 50 26 50 60" pathLength="1"/>
764
+ <path class="w-3" d="M32 2 C32 34 50 34 50 60" pathLength="1"/>
765
+ <path class="w-4" d="M45 2 C45 38 50 42 50 60" pathLength="1"/>
766
+ <path class="w-5" d="M55 2 C55 38 50 42 50 60" pathLength="1"/>
767
+ <path class="w-3" d="M68 2 C68 34 50 34 50 60" pathLength="1"/>
768
+ <path class="w-2" d="M81 2 C81 28 50 26 50 60" pathLength="1"/>
769
+ <path class="w-1" d="M94 2 C94 30 50 22 50 60" pathLength="1"/>
770
+ <circle cx="50" cy="60" r="1.8"/>
771
+ </svg>
772
+ </div>
751
773
 
752
- <div class="why-band">
753
- <p>The model proposes. Policy bounds. You own signatures. Multi-profile desks - not one omniscient chatbot. Input / Command, vaults, perps, bridges, and protocol scaffolds - not just swaps. Disarmed by default.</p>
754
- <span>powered by Hermes · claims without receipts don't count</span>
755
- </div>
774
+ <div class="row builder-row">
775
+ <div class="node route p-build builder-sink">
776
+ <div class="tag">bottom layer</div>
777
+ <div class="name">protocol builder</div>
778
+ <div class="sub">every profile can funnel into new contracts, scripts, checks, deploy prep, and chain-specific scaffolds.</div>
779
+ <div class="chains"><span class="ch">any EVM · pinned factories · user-signed deploys</span></div>
780
+ </div>
781
+ </div>
782
+ </div>
783
+ </div>
784
+
785
+ <div class="route-strip">
786
+ <article class="route-card p-poly">
787
+ <div class="where">polymarket agent →</div>
788
+ <h3>Polymarket <img src="https://icons.llamao.fi/icons/protocols/polymarket?w=40&h=40" alt="Polymarket" loading="lazy"></h3>
789
+ <p>Event markets, sports, arb paths, and prediction flow under bounds you set. CLOB prepare shipped in the public plane.</p>
790
+ <div class="chips">
791
+ <span class="chip-s">events</span>
792
+ <span class="chip-s">arb</span>
793
+ <span class="chip-s">clob prepare</span>
794
+ </div>
795
+ </article>
796
+ <article class="route-card p-hl">
797
+ <div class="where">hyperliquid agent →</div>
798
+ <h3>Hyperliquid <img src="https://icons.llamao.fi/icons/protocols/hyperliquid?w=40&h=40" alt="Hyperliquid" loading="lazy"></h3>
799
+ <p>Native perps, HIP-3/4 asset resolve, TA, event risk, and Hyperliquid when you need HL's EVM surface.</p>
800
+ <div class="chips">
801
+ <span class="chip-s">perps</span>
802
+ <span class="chip-s">HIP-3/4</span>
803
+ <span class="chip-s">Hyperliquid</span>
804
+ </div>
805
+ </article>
806
+ <article class="route-card p-rh">
807
+ <div class="where">robinhood agent →</div>
808
+ <h3>Robinhood <img src="https://icons.llamao.fi/icons/chains/rsz_robinhood?w=40&h=40" alt="Robinhood Chain" loading="lazy"></h3>
809
+ <p>RH Chain markets, NFTs, names, token scans, and chain-local routing on 4663.</p>
810
+ <div class="chips">
811
+ <span class="chip-s">markets</span>
812
+ <span class="chip-s">NFTs</span>
813
+ <span class="chip-s">4663</span>
814
+ </div>
815
+ </article>
816
+ <article class="route-card p-sol">
817
+ <div class="where">solana agent →</div>
818
+ <h3>Solana <img src="https://icons.llamao.fi/icons/chains/rsz_solana?w=40&h=40" alt="Solana" loading="lazy"></h3>
819
+ <p>Swaps, research, Jupiter routes. The bounded lane decodes every instruction and bans delegation ops outright.</p>
820
+ <div class="chips">
821
+ <span class="chip-s">Jupiter</span>
822
+ <span class="chip-s">swaps</span>
823
+ <span class="chip-s">decoded ix</span>
824
+ </div>
825
+ </article>
826
+ <article class="route-card p-btc">
827
+ <div class="where">bitcoin agent →</div>
828
+ <h3>Bitcoin <img src="https://icons.llamao.fi/icons/chains/rsz_bitcoin?w=40&h=40" alt="Bitcoin" loading="lazy"></h3>
829
+ <p>Ordinals, runes, and BTC research. Every PSBT input carries proven provenance, so fees are computed, not asserted.</p>
830
+ <div class="chips">
831
+ <span class="chip-s">ordinals</span>
832
+ <span class="chip-s">runes</span>
833
+ <span class="chip-s">psbt proof</span>
834
+ </div>
835
+ </article>
836
+ <article class="route-card p-evm">
837
+ <div class="where">evm / bridge agent →</div>
838
+ <h3>Multi-chain EVM <img src="https://icons.llamao.fi/icons/chains/rsz_ethereum?w=40&h=40" alt="Ethereum" loading="lazy"></h3>
839
+ <p>DEX routes, LI.FI and Relay bridges, DeFi across ETH and L2s. Bounded evm-swap and evm-bridge lanes, prepare-only until you sign.</p>
840
+ <div class="chips">
841
+ <span class="chip-s">evm-swap</span>
842
+ <span class="chip-s">evm-bridge</span>
843
+ <span class="chip-s">best route</span>
844
+ </div>
845
+ </article>
846
+ <article class="route-card p-stable">
847
+ <div class="where">stable agent →</div>
848
+ <h3>Stable <img src="https://icons.llamao.fi/icons/chains/rsz_stable?w=40&h=40" alt="Stable" loading="lazy"></h3>
849
+ <p>Stable mainnet launch radar and venue ops on chain 988, scanned straight from the chain's own logs.</p>
850
+ <div class="chips">
851
+ <span class="chip-s">launches</span>
852
+ <span class="chip-s">Stable 988</span>
853
+ </div>
854
+ </article>
855
+ <article class="route-card p-build">
856
+ <div class="where">protocol builder →</div>
857
+ <h3>Build protocols</h3>
858
+ <p>Scaffold contracts, run security gates (Foundry + static checks), prepare unsigned deploys through pinned factories. You still sign every deploy.</p>
859
+ <div class="chips">
860
+ <span class="chip-s">scaffold</span>
861
+ <span class="chip-s">security gate</span>
862
+ <span class="chip-s">unsigned deploy</span>
863
+ </div>
864
+ </article>
865
+ <article class="route-card p-add">
866
+ <div class="where">+ add agent →</div>
867
+ <h3>Next chain</h3>
868
+ <p>Drop in another profile for a new chain or venue. Same custody model, your wallet, your limits, your revoke.</p>
869
+ <div class="chips">
870
+ <span class="chip-s">custom profile</span>
871
+ <span class="chip-s">more chains</span>
872
+ <span class="chip-s">same custody</span>
873
+ </div>
874
+ </article>
875
+ </div>
876
+
877
+ <div class="why-band">
878
+ <p>The model proposes. Policy bounds. You own signatures. Multi-profile desks, not one omniscient chatbot. Vaults, perps, bridges, and protocol scaffolds, not just swaps. Empty allowlists refuse everything until you configure them.</p>
879
+ <span>claims without receipts don't count</span>
880
+ </div>
756
881
  </div>
757
882
 
758
883
  <div class="moat-grid rv" style="margin-top:28px">
759
- <article class="moat-card">
760
- <div class="n">bound grants</div>
761
- <h3>Wallet with temporary agent permission</h3>
762
- <p>Max value, chain, venue, destinations, and TTL. Outside the grant = hard refuse - not an agent with a free wallet.</p>
763
- </article>
764
- <article class="moat-card">
765
- <div class="n">receipts</div>
766
- <h3>Claims without receipts don't count</h3>
767
- <p>Money claims end in tx hash, receipt status, balance delta, and allowance state. No “looks filled.”</p>
768
- </article>
769
- <article class="moat-card">
770
- <div class="n">custody</div>
771
- <h3>Self-custodial by default</h3>
772
- <p>You sign with your wallet. Agentic dust is optional, capped, and never your main capital as the always-on signer.</p>
773
- </article>
774
- <article class="moat-card">
775
- <div class="n">intent desk + build</div>
776
- <h3>Trade and build protocols</h3>
777
- <p>Orders, vaults, perps, bridges - and protocol scaffold/deploy prep. Full crypto skills included. You sign.</p>
778
- </article>
779
- <article class="moat-card">
780
- <div class="n">simulation</div>
781
- <h3>Show the work before you sign</h3>
782
- <p>minOut, impact, spender, and decoded calldata before approval. Export unsigned artifacts for hardware wallets.</p>
783
- </article>
784
- <article class="moat-card">
785
- <div class="n">allowlists</div>
786
- <h3>Where money may land</h3>
787
- <p>Destination allowlists stop silent router drift. New contracts stay blocked until you add them.</p>
788
- </article>
884
+ <article class="moat-card">
885
+ <div class="n">bound grants</div>
886
+ <h3>Wallet with temporary agent permission</h3>
887
+ <p>Max value, chain, venue, destinations, and TTL. Outside the grant = hard refuse, not an agent with a free wallet.</p>
888
+ </article>
889
+ <article class="moat-card">
890
+ <div class="n">bounded surfaces</div>
891
+ <h3>Six lanes, each with its own decoder</h3>
892
+ <p>hl, poly, evm-swap, evm-bridge, btc, sol. Each decodes its own envelope, proves every value-moving field, and refuses while its allowlists are empty.</p>
893
+ </article>
894
+ <article class="moat-card">
895
+ <div class="n">receipts</div>
896
+ <h3>Claims without receipts don't count</h3>
897
+ <p>Prepared actions ship as stamped, hash-bound envelopes. Money claims end in tx hash, receipt status, balance delta, and allowance state. No “looks filled.”</p>
898
+ </article>
899
+ <article class="moat-card">
900
+ <div class="n">simulation</div>
901
+ <h3>Show the work before you sign</h3>
902
+ <p>minOut, impact, spender, and decoded calldata before approval. Export unsigned artifacts for hardware wallets.</p>
903
+ </article>
904
+ <article class="moat-card">
905
+ <div class="n">allowlists</div>
906
+ <h3>Where money may land</h3>
907
+ <p>Destination allowlists stop silent router drift. New contracts stay blocked until you add them.</p>
908
+ </article>
909
+ <article class="moat-card">
910
+ <div class="n">fail closed</div>
911
+ <h3>Unconfigured means refused</h3>
912
+ <p>A fresh install signs nothing. Every lane refuses while its allowlists are empty, so nothing moves until you set the bounds.</p>
913
+ </article>
789
914
  </div>
790
915
  </section>
791
916
 
792
917
  <section class="section" id="wallets">
793
918
  <p class="section-label rv">Wallets</p>
794
919
  <h2 class="section-title rv">Your wallets. <em>Your limits.</em></h2>
795
- <p class="section-lede rv">Use one wallet everywhere, or separate wallets per chain. Permissions are per wallet - change them, tighten them, or revoke them anytime.</p>
920
+ <p class="section-lede rv">Use one wallet everywhere, or separate wallets per chain. Permissions are per wallet. Change them, tighten them, or revoke them anytime.</p>
796
921
 
797
922
  <div class="wallet-grid rv">
798
- <article class="wallet-card">
799
- <div class="n">setup</div>
800
- <h3>Single or multi</h3>
801
- <p>One wallet across chains, or a dedicated wallet per chain. Same desk either way.</p>
802
- </article>
803
- <article class="wallet-card">
804
- <div class="n">control</div>
805
- <h3>Limit per wallet</h3>
806
- <p>Caps, allowed actions, and scopes sit on each wallet - not a global free pass.</p>
807
- </article>
808
- <article class="wallet-card">
809
- <div class="n">lifecycle</div>
810
- <h3>Change · revoke</h3>
811
- <p>Edit permissions when risk changes. Revoke a wallets access without killing the whole account.</p>
812
- </article>
923
+ <article class="wallet-card">
924
+ <div class="n">setup</div>
925
+ <h3>Single or multi</h3>
926
+ <p>One wallet across chains, or a dedicated wallet per chain. Same desk either way.</p>
927
+ </article>
928
+ <article class="wallet-card">
929
+ <div class="n">control</div>
930
+ <h3>Limit per wallet</h3>
931
+ <p>Caps, allowed actions, and scopes sit on each wallet, not a global free pass.</p>
932
+ </article>
933
+ <article class="wallet-card">
934
+ <div class="n">lifecycle</div>
935
+ <h3>Change · revoke</h3>
936
+ <p>Edit permissions when risk changes. Revoke a wallet's access without killing the whole account.</p>
937
+ </article>
813
938
  </div>
814
939
  </section>
815
940
 
816
941
  <section class="section" id="chains">
817
942
  <p class="section-label rv">Chains</p>
818
943
  <h2 class="section-title rv">Where you can <em>operate.</em></h2>
819
- <p class="section-lede rv">Live coverage grows with the profile mesh. Each chain maps to an agent - and new agents can join.</p>
944
+ <p class="section-lede rv">Live coverage grows with the profile mesh. Each chain maps to an agent, and new agents can join.</p>
820
945
  <div class="chain-grid" id="chain-grid"></div>
821
946
  <div class="venues rv">
822
- <div class="venues-head">protocols // venues</div>
823
- <div class="marquee" aria-hidden="true"><div class="track" id="proto-track"></div></div>
947
+ <div class="venues-head"><span>protocols // venues</span><span><b>routed by name</b> · quotes ranked · prepare-only</span></div>
948
+ <div class="marquee" aria-hidden="true"><div class="track" id="proto-track-a"></div></div>
949
+ <div class="marquee rev" aria-hidden="true"><div class="track" id="proto-track-b"></div></div>
824
950
  </div>
825
951
  </section>
826
952
 
827
953
  <section class="section" id="custody" style="padding-top:clamp(48px,8vh,80px)">
828
- <div class="strip-inner rv" style="border:1px solid var(--line);border-radius:16px;padding:22px 24px;display:flex;flex-wrap:wrap;gap:18px 28px;align-items:center;justify-content:space-between;background:linear-gradient(180deg, rgba(124,196,255,.05), transparent)">
829
- <div class="strip-left">
830
- <strong style="font-family:var(--display);font-weight:400;font-size:26px;display:block;margin-bottom:6px">You keep custody.</strong>
831
- <span style="font-family:var(--mono);font-size:10px;letter-spacing:.18em;text-transform:uppercase;color:var(--mute)">oracle never holds your keys</span>
832
- </div>
833
- <div class="strip-right" style="display:flex;flex-wrap:wrap;gap:10px">
834
- <span class="pill on" style="font-family:var(--mono);font-size:10px;letter-spacing:.16em;text-transform:uppercase;border:1px solid rgba(124,196,255,.35);border-radius:999px;padding:9px 12px;color:var(--blue)">Multi-wallet</span>
835
- <span class="pill on" style="font-family:var(--mono);font-size:10px;letter-spacing:.16em;text-transform:uppercase;border:1px solid rgba(124,196,255,.35);border-radius:999px;padding:9px 12px;color:var(--blue)">Per-wallet limits</span>
836
- <span class="pill" style="font-family:var(--mono);font-size:10px;letter-spacing:.16em;text-transform:uppercase;border:1px solid var(--line);border-radius:999px;padding:9px 12px;color:var(--cool)">Revoke anytime</span>
837
- </div>
838
- </div>
954
+ <div class="strip-inner rv" style="border:1px solid var(--line);border-radius:16px;padding:22px 24px;display:flex;flex-wrap:wrap;gap:18px 28px;align-items:center;justify-content:space-between;background:linear-gradient(180deg, rgba(124,196,255,.05), transparent)">
955
+ <div class="strip-left">
956
+ <strong style="font-family:var(--display);font-weight:400;font-size:26px;display:block;margin-bottom:6px">You keep custody.</strong>
957
+ <span style="font-family:var(--mono);font-size:10px;letter-spacing:.18em;text-transform:uppercase;color:var(--mute)">oracle never holds your keys</span>
958
+ </div>
959
+ <div class="strip-right" style="display:flex;flex-wrap:wrap;gap:10px">
960
+ <span class="pill on" style="font-family:var(--mono);font-size:10px;letter-spacing:.16em;text-transform:uppercase;border:1px solid rgba(124,196,255,.35);border-radius:999px;padding:9px 12px;color:var(--blue)">Multi-wallet</span>
961
+ <span class="pill on" style="font-family:var(--mono);font-size:10px;letter-spacing:.16em;text-transform:uppercase;border:1px solid rgba(124,196,255,.35);border-radius:999px;padding:9px 12px;color:var(--blue)">Per-wallet limits</span>
962
+ <span class="pill" style="font-family:var(--mono);font-size:10px;letter-spacing:.16em;text-transform:uppercase;border:1px solid var(--line);border-radius:999px;padding:9px 12px;color:var(--cool)">Revoke anytime</span>
963
+ </div>
964
+ </div>
839
965
  </section>
840
966
  </main>
841
967
 
842
968
  <footer>
843
969
  <div class="foot-row">
844
- <div class="powered">
845
- <span class="mark" aria-hidden="true"></span>
846
- powered by
847
- <a href="https://hermes-agent.nousresearch.com" target="_blank" rel="noopener noreferrer">Hermes</a>
848
- </div>
849
- <div class="foot-links">
850
- <a href="/oracle-console/">Console</a>
851
- <a href="https://hermes-agent.nousresearch.com/docs" target="_blank" rel="noopener noreferrer">Docs</a>
852
- </div>
970
+ <div class="powered">
971
+ powered by
972
+ <a href="https://hermes-agent.nousresearch.com" target="_blank" rel="noopener noreferrer">Hermes</a>
973
+ </div>
974
+ <div class="foot-links">
975
+ <a href="/oracle-console/">Console</a>
976
+ <a href="https://hermes-agent.nousresearch.com/docs" target="_blank" rel="noopener noreferrer">Docs</a>
977
+ </div>
853
978
  </div>
854
979
  <div class="foot-meta">
855
- <span>oracle · for users</span>
856
- <span>full crypto pack · protocol builder · powered by Hermes</span>
857
- <span>you sign // no house custody</span>
980
+ <span>oracle · for users</span>
981
+ <span>13 chains · six bounded surfaces · protocol builder</span>
982
+ <span>you sign // no house custody</span>
858
983
  </div>
859
984
  </footer>
860
985
 
@@ -863,56 +988,235 @@ footer{margin-top:clamp(72px,12vh,120px);border-top:1px solid var(--line);paddin
863
988
  "use strict";
864
989
  document.documentElement.classList.add("js");
865
990
 
991
+ var ICON = "https://icons.llamao.fi/icons/";
866
992
  var CHAINS = [
867
- { name: "Ethereum", id: "1", note: "open / add agent", badge: "live" },
868
- { name: "Base", id: "8453", note: "open / add agent", badge: "live" },
869
- { name: "Arbitrum", id: "42161", note: "open / add agent", badge: "live" },
870
- { name: "Optimism", id: "10", note: "open / add agent", badge: "live" },
871
- { name: "Polygon", id: "137", note: "open / add agent", badge: "live" },
872
- { name: "BNB Chain", id: "56", note: "open / add agent", badge: "live" },
873
- { name: "Avalanche", id: "43114", note: "open / add agent", badge: "live" },
874
- { name: "HyperEVM", id: "999", note: "hyperliquid agent", badge: "live" },
875
- { name: "Abstract", id: "2741", note: "open / add agent", badge: "live" },
876
- { name: "Stable", id: "988", note: "stable agent", badge: "live" },
877
- { name: "Robinhood", id: "4663", note: "robinhood agent", badge: "live" },
878
- { name: "Solana", id: " - ", note: "solana agent", badge: "live" }
993
+ { name: "Ethereum", id: "1", logo: "chains/rsz_ethereum", note: "evm / bridge agent", badge: "live" },
994
+ { name: "Base", id: "8453", logo: "chains/rsz_base", note: "evm / bridge agent", badge: "live" },
995
+ { name: "Arbitrum", id: "42161", logo: "chains/rsz_arbitrum", note: "evm / bridge agent", badge: "live" },
996
+ { name: "Optimism", id: "10", logo: "chains/rsz_optimism", note: "evm / bridge agent", badge: "live" },
997
+ { name: "Polygon", id: "137", logo: "chains/rsz_polygon", note: "evm / bridge agent", badge: "live" },
998
+ { name: "BNB Chain", id: "56", logo: "chains/rsz_binance", note: "evm / bridge agent", badge: "live" },
999
+ { name: "Avalanche", id: "43114", logo: "chains/rsz_avalanche", note: "evm / bridge agent", badge: "live" },
1000
+ { name: "Hyperliquid", id: "999", logo: "chains/rsz_hyperliquid", note: "hyperliquid agent", badge: "live" },
1001
+ { name: "Abstract", id: "2741", logo: "chains/rsz_abstract", note: "open / add agent", badge: "live" },
1002
+ { name: "Stable", id: "988", logo: "chains/rsz_stable", note: "stable agent", badge: "live" },
1003
+ { name: "Robinhood", id: "4663", logo: "chains/rsz_robinhood", note: "robinhood agent", badge: "live" },
1004
+ { name: "Solana", id: "SOL", logo: "chains/rsz_solana", note: "solana agent", badge: "live" },
1005
+ { name: "Bitcoin", id: "BTC", logo: "chains/rsz_bitcoin", note: "bitcoin agent", badge: "live" }
879
1006
  ];
880
- var PROTOS = [
881
- "uniswap-v3","aerodrome","velodrome","pancakeswap","quickswap",
882
- "lfj","hyperswap","curve","balancer","pendle","morpho","gmx-v2",
883
- "lifi","relay","paraswap","odos","cow","jupiter","across","stargate"
884
- ];
885
-
886
1007
  document.getElementById("chain-grid").innerHTML = CHAINS.map(function (c) {
887
- var cls = c.badge === "live" ? "badge live" : "badge";
888
- var label = c.badge === "live" ? "live" : "read";
889
- return '<article class="chain rv"><div class="chain-top"><div class="nm">' + c.name + '</div><div class="id">' + c.id + '</div></div><div class="meta"><span>' + c.note + '</span><span class="' + cls + '">' + label + '</span></div></article>';
1008
+ var cls = c.badge === "live" ? "badge live" : "badge";
1009
+ var label = c.badge === "live" ? "live" : "read";
1010
+ return '<article class="chain rv"><div class="chain-top"><div class="nm">' + c.name +
1011
+ ' <img src="' + ICON + c.logo + '?w=36&h=36" alt="' + c.name + ' logo" loading="lazy"></div><div class="id">' + c.id +
1012
+ '</div></div><div class="meta"><span>' + c.note + '</span><span class="' + cls + '">' + label + '</span></div></article>';
890
1013
  }).join("");
891
1014
 
892
- var seq = PROTOS.concat(PROTOS);
893
- document.getElementById("proto-track").innerHTML = seq.map(function (x) {
894
- return '<span class="chip">' + x + '</span>';
895
- }).join("");
1015
+ var WM = "assets/wordmarks/";
1016
+ var PROTOS_A = [
1017
+ { n: "Uniswap", wm: "uniswap.svg" },
1018
+ { n: "Hyperliquid", wm: "hyperliquid.svg" },
1019
+ { n: "Polymarket", wm: "polymarket.png" },
1020
+ { n: "Aerodrome", wm: "aerodrome.svg" },
1021
+ { n: "Velodrome", wm: "velodrome.svg" },
1022
+ { n: "PancakeSwap", wm: "pancakeswap.svg" },
1023
+ { n: "QuickSwap", wm: "quickswap.png" },
1024
+ { n: "LFJ", c: "lfj", s: "protocols/lfj" },
1025
+ { n: "HyperSwap", wm: "hyperswap.svg" },
1026
+ { n: "Curve", c: "curve", s: "protocols/curve-dex" },
1027
+ { n: "Balancer", wm: "balancer.svg" },
1028
+ { n: "Pendle", wm: "pendle.png" }
1029
+ ];
1030
+ var PROTOS_B = [
1031
+ { n: "Morpho", wm: "morpho.svg" },
1032
+ { n: "GMX", wm: "gmx.svg" },
1033
+ { n: "LI.FI", wm: "lifi.png" },
1034
+ { n: "Relay", wm: "relay.svg" },
1035
+ { n: "Velora", wm: "paraswap.svg" },
1036
+ { n: "Odos", wm: "odos.svg" },
1037
+ { n: "CoW Swap", wm: "cowswap.svg" },
1038
+ { n: "1inch", wm: "oneinch.svg" },
1039
+ { n: "Jupiter", wm: "jupiter.svg" },
1040
+ { n: "OpenSea", wm: "opensea.svg" },
1041
+ { n: "Across", wm: "across.svg" },
1042
+ { n: "Stargate", wm: "stargate.svg" },
1043
+ { n: "Magic Eden", wm: "magic-eden.svg" }
1044
+ ];
1045
+
1046
+ function chipRow(list) {
1047
+ var seq = list.concat(list);
1048
+ return seq.map(function (x) {
1049
+ if (x.wm) {
1050
+ return '<span class="chip wm-chip"><img class="wm" src="' + WM + x.wm + '" alt="' + x.n + '" loading="lazy"></span>';
1051
+ }
1052
+ return '<span class="chip proto-' + x.c + '"><img src="' + ICON + x.s + '?w=32&h=32" alt="" loading="lazy"><span class="wordmark">' + x.n + '</span></span>';
1053
+ }).join("");
1054
+ }
1055
+ document.getElementById("proto-track-a").innerHTML = chipRow(PROTOS_A);
1056
+ document.getElementById("proto-track-b").innerHTML = chipRow(PROTOS_B);
896
1057
 
897
1058
  var loader = document.getElementById("loader");
898
1059
  var fill = document.getElementById("loader-fill");
899
1060
  requestAnimationFrame(function () { fill.style.width = "100%"; });
900
1061
  window.addEventListener("load", function () {
901
- setTimeout(function () { loader.classList.add("out"); }, 650);
1062
+ setTimeout(function () { loader.classList.add("out"); }, 650);
902
1063
  });
903
1064
 
904
1065
  var reduced = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
905
1066
  var coarse = window.matchMedia("(pointer: coarse)").matches;
906
- var nodes = Array.prototype.slice.call(document.querySelectorAll(".rv"));
1067
+
1068
+ var progress = document.getElementById("progress");
1069
+ var ticking = false;
1070
+ function onScroll() {
1071
+ if (ticking) return;
1072
+ ticking = true;
1073
+ requestAnimationFrame(function () {
1074
+ var h = document.documentElement;
1075
+ var max = h.scrollHeight - h.clientHeight;
1076
+ progress.style.transform = "scaleX(" + (max > 0 ? h.scrollTop / max : 0) + ")";
1077
+ ticking = false;
1078
+ });
1079
+ }
1080
+ window.addEventListener("scroll", onScroll, { passive: true });
1081
+ onScroll();
1082
+
1083
+ var heroOrb = document.getElementById("hero-orb");
1084
+ var heroTitle = document.getElementById("hero-title");
1085
+ if (heroOrb && heroTitle && !reduced) {
1086
+ var px = false;
1087
+ window.addEventListener("scroll", function () {
1088
+ if (px) return;
1089
+ px = true;
1090
+ requestAnimationFrame(function () {
1091
+ var y = window.scrollY;
1092
+ var lim = window.innerHeight * .8;
1093
+ var f = Math.min(y / lim, 1);
1094
+ var art = heroOrb.parentElement;
1095
+ art.style.opacity = String(1 - f);
1096
+ art.style.visibility = f >= 1 ? "hidden" : "visible";
1097
+ art.style.transform = "translateY(" + (Math.min(y, lim) * .28) + "px)";
1098
+ heroTitle.style.transform = "translateY(" + (Math.min(y, lim) * .16) + "px)";
1099
+ heroTitle.style.opacity = String(1 - f * .8);
1100
+ px = false;
1101
+ });
1102
+ }, { passive: true });
1103
+ }
1104
+
1105
+ (function () {
1106
+ var cv = document.getElementById("orb-gl");
1107
+ if (!cv || reduced) return;
1108
+ var g = cv.getContext("webgl", { antialias: true, alpha: true, premultipliedAlpha: false });
1109
+ if (!g) return;
1110
+ document.querySelector(".hero-art").classList.add("webgl-orb");
1111
+ document.body.classList.add("webgl-orb");
1112
+
1113
+ var N = 4200;
1114
+ var pos = new Float32Array(N * 4);
1115
+ var GA = Math.PI * (3 - Math.sqrt(5));
1116
+ for (var i = 0; i < N; i++) {
1117
+ var y = 1 - (i / (N - 1)) * 2;
1118
+ var r = Math.sqrt(1 - y * y);
1119
+ var th = GA * i;
1120
+ pos[i * 4] = Math.cos(th) * r;
1121
+ pos[i * 4 + 1] = y;
1122
+ pos[i * 4 + 2] = Math.sin(th) * r;
1123
+ pos[i * 4 + 3] = (i % 97) / 97;
1124
+ }
1125
+ var vs = [
1126
+ "attribute vec4 p;",
1127
+ "uniform float t; uniform float dpr; uniform vec2 m;",
1128
+ "varying float vd; varying float vtw;",
1129
+ "void main(){",
1130
+ " float a = t*.22 + m.x*.35;",
1131
+ " float ca=cos(a), sa=sin(a);",
1132
+ " vec3 q = vec3(p.x*ca + p.z*sa, p.y, -p.x*sa + p.z*ca);",
1133
+ " float b = .42 + m.y*.22;",
1134
+ " float cb=cos(b), sb=sin(b);",
1135
+ " q = vec3(q.x, q.y*cb - q.z*sb, q.y*sb + q.z*cb);",
1136
+ " float persp = 2.2/(2.2 - q.z*.9);",
1137
+ " vd = q.z*.5+.5;",
1138
+ " vtw = p.w;",
1139
+ " gl_Position = vec4(q.x*.58*persp, q.y*.58*persp, 0., 1.);",
1140
+ " gl_PointSize = (1.8 + vd*4.2) * dpr;",
1141
+ "}"
1142
+ ].join("\n");
1143
+ var fs = [
1144
+ "precision mediump float;",
1145
+ "uniform float t;",
1146
+ "varying float vd; varying float vtw;",
1147
+ "void main(){",
1148
+ " vec2 c = gl_PointCoord - .5;",
1149
+ " float d = length(c);",
1150
+ " if (d > .5) discard;",
1151
+ " float soft = smoothstep(.5, .28, d);",
1152
+ " float tw = .82 + .18*sin(t*2.2 + vtw*40.0);",
1153
+ " vec3 near = vec3(.86,.95,1.0);",
1154
+ " vec3 far = vec3(.24,.44,.68);",
1155
+ " vec3 col = mix(far, near, vd);",
1156
+ " float alpha = soft * mix(.2, 1.0, vd*vd) * tw;",
1157
+ " gl_FragColor = vec4(col*alpha, alpha);",
1158
+ "}"
1159
+ ].join("\n");
1160
+ function sh(ty, src) { var s = g.createShader(ty); g.shaderSource(s, src); g.compileShader(s); return s; }
1161
+ var pr = g.createProgram();
1162
+ g.attachShader(pr, sh(g.VERTEX_SHADER, vs));
1163
+ g.attachShader(pr, sh(g.FRAGMENT_SHADER, fs));
1164
+ g.linkProgram(pr); g.useProgram(pr);
1165
+ var buf = g.createBuffer();
1166
+ g.bindBuffer(g.ARRAY_BUFFER, buf);
1167
+ g.bufferData(g.ARRAY_BUFFER, pos, g.STATIC_DRAW);
1168
+ var loc = g.getAttribLocation(pr, "p");
1169
+ g.enableVertexAttribArray(loc);
1170
+ g.vertexAttribPointer(loc, 4, g.FLOAT, false, 0, 0);
1171
+ var uT = g.getUniformLocation(pr, "t");
1172
+ var uD = g.getUniformLocation(pr, "dpr");
1173
+ var uM = g.getUniformLocation(pr, "m");
1174
+ var mx = 0, my = 0, tx = 0, ty = 0;
1175
+ window.addEventListener("pointermove", function (e) {
1176
+ tx = (e.clientX / window.innerWidth - .5) * 2;
1177
+ ty = (e.clientY / window.innerHeight - .5) * 2;
1178
+ }, { passive: true });
1179
+ g.enable(g.BLEND);
1180
+ g.blendFunc(g.ONE, g.ONE_MINUS_SRC_ALPHA);
1181
+ var dpr = Math.min(window.devicePixelRatio || 1, 2);
1182
+ function size() {
1183
+ var w = Math.floor(cv.clientWidth * dpr), h = Math.floor(cv.clientHeight * dpr);
1184
+ if (cv.width !== w || cv.height !== h) { cv.width = w; cv.height = h; g.viewport(0, 0, w, h); }
1185
+ }
1186
+ var run = true;
1187
+ function frame(now) {
1188
+ if (!run) return;
1189
+ size();
1190
+ g.clearColor(0, 0, 0, 0);
1191
+ g.clear(g.COLOR_BUFFER_BIT);
1192
+ mx += (tx - mx) * .04; my += (ty - my) * .04;
1193
+ g.uniform1f(uT, now * .001);
1194
+ g.uniform1f(uD, dpr);
1195
+ g.uniform2f(uM, mx, my);
1196
+ g.drawArrays(g.POINTS, 0, N);
1197
+ requestAnimationFrame(frame);
1198
+ }
1199
+ document.addEventListener("visibilitychange", function () {
1200
+ run = document.visibilityState === "visible";
1201
+ if (run) requestAnimationFrame(frame);
1202
+ });
1203
+ requestAnimationFrame(frame);
1204
+ })();
1205
+
1206
+ var nodes = Array.prototype.slice.call(document.querySelectorAll(".rv, .wires"));
907
1207
  if (reduced || !("IntersectionObserver" in window)) {
908
- nodes.forEach(function (n) { n.classList.add("in"); });
1208
+ nodes.forEach(function (n) { n.classList.add("in"); n.classList.add("done"); });
909
1209
  } else {
910
- var io = new IntersectionObserver(function (entries) {
911
- entries.forEach(function (e) {
912
- if (e.isIntersecting) { e.target.classList.add("in"); io.unobserve(e.target); }
913
- });
914
- }, { threshold: 0.1, rootMargin: "0px 0px -6% 0px" });
915
- nodes.forEach(function (n) { io.observe(n); });
1210
+ var io = new IntersectionObserver(function (entries) {
1211
+ entries.forEach(function (e) {
1212
+ if (e.isIntersecting) {
1213
+ e.target.classList.add("in");
1214
+ (function (el) { setTimeout(function () { el.classList.add("done"); }, 1100); })(e.target);
1215
+ io.unobserve(e.target);
1216
+ }
1217
+ });
1218
+ }, { threshold: 0.1, rootMargin: "0px 0px -6% 0px" });
1219
+ nodes.forEach(function (n) { io.observe(n); });
916
1220
  }
917
1221
 
918
1222
  var canvas = document.getElementById("gl");
@@ -922,29 +1226,29 @@ footer{margin-top:clamp(72px,12vh,120px);border-top:1px solid var(--line);paddin
922
1226
 
923
1227
  var vs = "attribute vec2 p;void main(){gl_Position=vec4(p,0.,1.);}";
924
1228
  var fs = [
925
- "precision highp float;",
926
- "uniform vec2 r; uniform float t;",
927
- "float hash(vec2 p){return fract(sin(dot(p,vec2(127.1,311.7)))*43758.5453);}",
928
- "float noise(vec2 p){vec2 i=floor(p),f=fract(p);float a=hash(i),b=hash(i+vec2(1.,0.)),c=hash(i+vec2(0.,1.)),d=hash(i+vec2(1.,1.));vec2 u=f*f*(3.-2.*f);return mix(a,b,u.x)+(c-a)*u.y*(1.-u.x)+(d-b)*u.x*u.y;}",
929
- "void main(){",
930
- " vec2 uv=(gl_FragCoord.xy-.5*r)/min(r.x,r.y);",
931
- " vec2 p=uv*1.15; float tt=t*.08;",
932
- " float n=noise(p*2.2+vec2(tt*.6,-tt*.4)); n+=.5*noise(p*4.6-vec2(tt,tt*.7)); n*=.55;",
933
- " vec2 g=abs(fract(p*6.5)-.5); float grid=smoothstep(.06,0.,min(g.x,g.y));",
934
- " float d=length(p); float rings=0.;",
935
- " for(float i=0.;i<4.;i++){float ph=fract(tt*.35+i*.21);float rad=.08+ph*1.15;rings+=exp(-pow((d-rad)*28.,2.))*(1.-ph);}",
936
- " float nodes=0.;",
937
- " for(float i=0.;i<12.;i++){float a=i*2.399963;vec2 o=vec2(cos(a+tt*.2),sin(a-tt*.15))*(.18+.05*sin(tt+i));nodes+=exp(-dot(p-o,p-o)*420.);}",
938
- " vec3 bg=vec3(0.043,0.063,0.094);",
939
- " vec3 blue=vec3(0.486,0.769,1.0);",
940
- " vec3 cool=vec3(0.655,0.847,1.0);",
941
- " vec3 col=bg;",
942
- " col+=blue*(n*.2); col+=blue*grid*.05;",
943
- " col+=mix(blue,cool,.35)*rings*.22; col+=blue*nodes*.5;",
944
- " col+=blue*exp(-d*d*1.8)*.08;",
945
- " float vig=pow(max(1.-dot(uv*.72,uv*.72),0.),1.55);",
946
- " col*=vig; gl_FragColor=vec4(col,1.);",
947
- "}"
1229
+ "precision highp float;",
1230
+ "uniform vec2 r; uniform float t;",
1231
+ "float hash(vec2 p){return fract(sin(dot(p,vec2(127.1,311.7)))*43758.5453);}",
1232
+ "float noise(vec2 p){vec2 i=floor(p),f=fract(p);float a=hash(i),b=hash(i+vec2(1.,0.)),c=hash(i+vec2(0.,1.)),d=hash(i+vec2(1.,1.));vec2 u=f*f*(3.-2.*f);return mix(a,b,u.x)+(c-a)*u.y*(1.-u.x)+(d-b)*u.x*u.y;}",
1233
+ "void main(){",
1234
+ " vec2 uv=(gl_FragCoord.xy-.5*r)/min(r.x,r.y);",
1235
+ " vec2 p=uv*1.15; float tt=t*.08;",
1236
+ " float n=noise(p*2.2+vec2(tt*.6,-tt*.4)); n+=.5*noise(p*4.6-vec2(tt,tt*.7)); n*=.55;",
1237
+ " vec2 g=abs(fract(p*6.5)-.5); float grid=smoothstep(.06,0.,min(g.x,g.y));",
1238
+ " float d=length(p); float rings=0.;",
1239
+ " for(float i=0.;i<4.;i++){float ph=fract(tt*.35+i*.21);float rad=.08+ph*1.15;rings+=exp(-pow((d-rad)*28.,2.))*(1.-ph);}",
1240
+ " float nodes=0.;",
1241
+ " for(float i=0.;i<12.;i++){float a=i*2.399963;vec2 o=vec2(cos(a+tt*.2),sin(a-tt*.15))*(.18+.05*sin(tt+i));nodes+=exp(-dot(p-o,p-o)*420.);}",
1242
+ " vec3 bg=vec3(0.043,0.063,0.094);",
1243
+ " vec3 blue=vec3(0.486,0.769,1.0);",
1244
+ " vec3 cool=vec3(0.655,0.847,1.0);",
1245
+ " vec3 col=bg;",
1246
+ " col+=blue*(n*.2); col+=blue*grid*.05;",
1247
+ " col+=mix(blue,cool,.35)*rings*.22; col+=blue*nodes*.5;",
1248
+ " col+=blue*exp(-d*d*1.8)*.08;",
1249
+ " float vig=pow(max(1.-dot(uv*.72,uv*.72),0.),1.55);",
1250
+ " col*=vig; gl_FragColor=vec4(col,1.);",
1251
+ "}"
948
1252
  ].join("\n");
949
1253
 
950
1254
  function compile(type, src){var s=gl.createShader(type);gl.shaderSource(s,src);gl.compileShader(s);return s;}
@@ -958,17 +1262,17 @@ footer{margin-top:clamp(72px,12vh,120px);border-top:1px solid var(--line);paddin
958
1262
  var uR=gl.getUniformLocation(prog,"r"), uT=gl.getUniformLocation(prog,"t");
959
1263
  var running=true;
960
1264
  function resize(){
961
- var dpr=Math.min(window.devicePixelRatio||1,1.5);
962
- var w=Math.floor(canvas.clientWidth*dpr), h=Math.floor(canvas.clientHeight*dpr);
963
- if(canvas.width!==w||canvas.height!==h){canvas.width=w;canvas.height=h;gl.viewport(0,0,w,h);}
1265
+ var dpr=Math.min(window.devicePixelRatio||1,1.5);
1266
+ var w=Math.floor(canvas.clientWidth*dpr), h=Math.floor(canvas.clientHeight*dpr);
1267
+ if(canvas.width!==w||canvas.height!==h){canvas.width=w;canvas.height=h;gl.viewport(0,0,w,h);}
964
1268
  }
965
1269
  function frame(now){
966
- if(!running) return;
967
- resize();
968
- gl.uniform2f(uR,canvas.width,canvas.height);
969
- gl.uniform1f(uT,now*0.001);
970
- gl.drawArrays(gl.TRIANGLES,0,3);
971
- requestAnimationFrame(frame);
1270
+ if(!running) return;
1271
+ resize();
1272
+ gl.uniform2f(uR,canvas.width,canvas.height);
1273
+ gl.uniform1f(uT,now*0.001);
1274
+ gl.drawArrays(gl.TRIANGLES,0,3);
1275
+ requestAnimationFrame(frame);
972
1276
  }
973
1277
  function fit(){canvas.style.width="100%";canvas.style.height="100%";resize();}
974
1278
  fit();