linguclaw 0.4.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 (168) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +161 -0
  3. package/dist/agent-system.d.ts +196 -0
  4. package/dist/agent-system.d.ts.map +1 -0
  5. package/dist/agent-system.js +738 -0
  6. package/dist/agent-system.js.map +1 -0
  7. package/dist/alphabeta.d.ts +54 -0
  8. package/dist/alphabeta.d.ts.map +1 -0
  9. package/dist/alphabeta.js +193 -0
  10. package/dist/alphabeta.js.map +1 -0
  11. package/dist/browser.d.ts +62 -0
  12. package/dist/browser.d.ts.map +1 -0
  13. package/dist/browser.js +224 -0
  14. package/dist/browser.js.map +1 -0
  15. package/dist/cli.d.ts +7 -0
  16. package/dist/cli.d.ts.map +1 -0
  17. package/dist/cli.js +565 -0
  18. package/dist/cli.js.map +1 -0
  19. package/dist/code-parser.d.ts +39 -0
  20. package/dist/code-parser.d.ts.map +1 -0
  21. package/dist/code-parser.js +385 -0
  22. package/dist/code-parser.js.map +1 -0
  23. package/dist/config.d.ts +66 -0
  24. package/dist/config.d.ts.map +1 -0
  25. package/dist/config.js +232 -0
  26. package/dist/config.js.map +1 -0
  27. package/dist/core/engine.d.ts +359 -0
  28. package/dist/core/engine.d.ts.map +1 -0
  29. package/dist/core/engine.js +127 -0
  30. package/dist/core/engine.js.map +1 -0
  31. package/dist/daemon.d.ts +29 -0
  32. package/dist/daemon.d.ts.map +1 -0
  33. package/dist/daemon.js +212 -0
  34. package/dist/daemon.js.map +1 -0
  35. package/dist/email-receiver.d.ts +63 -0
  36. package/dist/email-receiver.d.ts.map +1 -0
  37. package/dist/email-receiver.js +553 -0
  38. package/dist/email-receiver.js.map +1 -0
  39. package/dist/git-integration.d.ts +180 -0
  40. package/dist/git-integration.d.ts.map +1 -0
  41. package/dist/git-integration.js +850 -0
  42. package/dist/git-integration.js.map +1 -0
  43. package/dist/inbox.d.ts +84 -0
  44. package/dist/inbox.d.ts.map +1 -0
  45. package/dist/inbox.js +198 -0
  46. package/dist/inbox.js.map +1 -0
  47. package/dist/index.d.ts +6 -0
  48. package/dist/index.d.ts.map +1 -0
  49. package/dist/index.js +41 -0
  50. package/dist/index.js.map +1 -0
  51. package/dist/languages/cpp.d.ts +51 -0
  52. package/dist/languages/cpp.d.ts.map +1 -0
  53. package/dist/languages/cpp.js +930 -0
  54. package/dist/languages/cpp.js.map +1 -0
  55. package/dist/languages/csharp.d.ts +79 -0
  56. package/dist/languages/csharp.d.ts.map +1 -0
  57. package/dist/languages/csharp.js +1776 -0
  58. package/dist/languages/csharp.js.map +1 -0
  59. package/dist/languages/go.d.ts +50 -0
  60. package/dist/languages/go.d.ts.map +1 -0
  61. package/dist/languages/go.js +882 -0
  62. package/dist/languages/go.js.map +1 -0
  63. package/dist/languages/java.d.ts +47 -0
  64. package/dist/languages/java.d.ts.map +1 -0
  65. package/dist/languages/java.js +649 -0
  66. package/dist/languages/java.js.map +1 -0
  67. package/dist/languages/python.d.ts +47 -0
  68. package/dist/languages/python.d.ts.map +1 -0
  69. package/dist/languages/python.js +655 -0
  70. package/dist/languages/python.js.map +1 -0
  71. package/dist/languages/rust.d.ts +61 -0
  72. package/dist/languages/rust.d.ts.map +1 -0
  73. package/dist/languages/rust.js +1064 -0
  74. package/dist/languages/rust.js.map +1 -0
  75. package/dist/logger.d.ts +20 -0
  76. package/dist/logger.d.ts.map +1 -0
  77. package/dist/logger.js +133 -0
  78. package/dist/logger.js.map +1 -0
  79. package/dist/longterm-memory.d.ts +47 -0
  80. package/dist/longterm-memory.d.ts.map +1 -0
  81. package/dist/longterm-memory.js +300 -0
  82. package/dist/longterm-memory.js.map +1 -0
  83. package/dist/memory.d.ts +42 -0
  84. package/dist/memory.d.ts.map +1 -0
  85. package/dist/memory.js +274 -0
  86. package/dist/memory.js.map +1 -0
  87. package/dist/messaging.d.ts +103 -0
  88. package/dist/messaging.d.ts.map +1 -0
  89. package/dist/messaging.js +645 -0
  90. package/dist/messaging.js.map +1 -0
  91. package/dist/multi-provider.d.ts +69 -0
  92. package/dist/multi-provider.d.ts.map +1 -0
  93. package/dist/multi-provider.js +484 -0
  94. package/dist/multi-provider.js.map +1 -0
  95. package/dist/orchestrator.d.ts +65 -0
  96. package/dist/orchestrator.d.ts.map +1 -0
  97. package/dist/orchestrator.js +441 -0
  98. package/dist/orchestrator.js.map +1 -0
  99. package/dist/plugins.d.ts +52 -0
  100. package/dist/plugins.d.ts.map +1 -0
  101. package/dist/plugins.js +215 -0
  102. package/dist/plugins.js.map +1 -0
  103. package/dist/prism-orchestrator.d.ts +26 -0
  104. package/dist/prism-orchestrator.d.ts.map +1 -0
  105. package/dist/prism-orchestrator.js +191 -0
  106. package/dist/prism-orchestrator.js.map +1 -0
  107. package/dist/prism.d.ts +46 -0
  108. package/dist/prism.d.ts.map +1 -0
  109. package/dist/prism.js +188 -0
  110. package/dist/prism.js.map +1 -0
  111. package/dist/privacy.d.ts +23 -0
  112. package/dist/privacy.d.ts.map +1 -0
  113. package/dist/privacy.js +220 -0
  114. package/dist/privacy.js.map +1 -0
  115. package/dist/proactive.d.ts +30 -0
  116. package/dist/proactive.d.ts.map +1 -0
  117. package/dist/proactive.js +260 -0
  118. package/dist/proactive.js.map +1 -0
  119. package/dist/refactoring-engine.d.ts +100 -0
  120. package/dist/refactoring-engine.d.ts.map +1 -0
  121. package/dist/refactoring-engine.js +717 -0
  122. package/dist/refactoring-engine.js.map +1 -0
  123. package/dist/resilience.d.ts +43 -0
  124. package/dist/resilience.d.ts.map +1 -0
  125. package/dist/resilience.js +200 -0
  126. package/dist/resilience.js.map +1 -0
  127. package/dist/safety.d.ts +40 -0
  128. package/dist/safety.d.ts.map +1 -0
  129. package/dist/safety.js +133 -0
  130. package/dist/safety.js.map +1 -0
  131. package/dist/sandbox.d.ts +33 -0
  132. package/dist/sandbox.d.ts.map +1 -0
  133. package/dist/sandbox.js +173 -0
  134. package/dist/sandbox.js.map +1 -0
  135. package/dist/scheduler.d.ts +72 -0
  136. package/dist/scheduler.d.ts.map +1 -0
  137. package/dist/scheduler.js +374 -0
  138. package/dist/scheduler.js.map +1 -0
  139. package/dist/semantic-memory.d.ts +70 -0
  140. package/dist/semantic-memory.d.ts.map +1 -0
  141. package/dist/semantic-memory.js +430 -0
  142. package/dist/semantic-memory.js.map +1 -0
  143. package/dist/skills.d.ts +97 -0
  144. package/dist/skills.d.ts.map +1 -0
  145. package/dist/skills.js +575 -0
  146. package/dist/skills.js.map +1 -0
  147. package/dist/static/dashboard.html +853 -0
  148. package/dist/static/hub.html +772 -0
  149. package/dist/static/index.html +818 -0
  150. package/dist/static/logo.svg +24 -0
  151. package/dist/static/workflow-editor.html +913 -0
  152. package/dist/tools.d.ts +67 -0
  153. package/dist/tools.d.ts.map +1 -0
  154. package/dist/tools.js +303 -0
  155. package/dist/tools.js.map +1 -0
  156. package/dist/types.d.ts +295 -0
  157. package/dist/types.d.ts.map +1 -0
  158. package/dist/types.js +90 -0
  159. package/dist/types.js.map +1 -0
  160. package/dist/web.d.ts +76 -0
  161. package/dist/web.d.ts.map +1 -0
  162. package/dist/web.js +2139 -0
  163. package/dist/web.js.map +1 -0
  164. package/dist/workflow-engine.d.ts +114 -0
  165. package/dist/workflow-engine.d.ts.map +1 -0
  166. package/dist/workflow-engine.js +855 -0
  167. package/dist/workflow-engine.js.map +1 -0
  168. package/package.json +77 -0
@@ -0,0 +1,818 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>LinguClaw — AI-Powered Multi-Agent System</title>
7
+ <meta name="description" content="Open-source codebase-aware multi-agent orchestration with visual workflows, semantic memory, 6-language analysis, and a community skill marketplace.">
8
+ <meta property="og:title" content="LinguClaw — Build Smarter with AI Agent Teams">
9
+ <meta property="og:description" content="Multi-agent orchestration with visual workflows, semantic memory, and a community skill hub.">
10
+ <meta property="og:type" content="website">
11
+ <meta name="theme-color" content="#6c5ce7">
12
+ <link rel="icon" type="image/svg+xml" href="logo.svg">
13
+ <style>
14
+ @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800;900&family=JetBrains+Mono:wght@400;500;600&display=swap');
15
+ :root{--bg:#06060a;--bg1:#0c0c12;--bg2:#12121a;--bg3:#1a1a24;--border:#1e1e2a;--accent:#6c5ce7;--accent2:#a29bfe;--accent3:#5b4cdb;--glow:rgba(108,92,231,.18);--glow2:rgba(108,92,231,.06);--green:#00e676;--cyan:#18ffff;--pink:#ff6b9d;--orange:#ffa726;--yellow:#ffee58;--text:#eeeef0;--dim:#9e9eb0;--muted:#5e5e72;--r:12px;--r2:20px;--r3:28px}
16
+ *{box-sizing:border-box;margin:0;padding:0}
17
+ html{scroll-behavior:smooth;overflow-x:hidden}
18
+ body{font-family:'Inter',system-ui,-apple-system,sans-serif;background:var(--bg);color:var(--text);line-height:1.6;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}
19
+ ::-webkit-scrollbar{width:6px}::-webkit-scrollbar-track{background:transparent}::-webkit-scrollbar-thumb{background:var(--border);border-radius:3px}
20
+ ::selection{background:var(--accent);color:#fff}
21
+ a{color:inherit;text-decoration:none;transition:color .2s}
22
+ img{max-width:100%;display:block}
23
+
24
+ /* ============ ANIMATIONS ============ */
25
+ @keyframes pulse-glow{0%,100%{box-shadow:0 0 20px var(--glow),0 0 60px var(--glow2)}50%{box-shadow:0 0 40px var(--glow),0 0 100px var(--glow2)}}
26
+ @keyframes gradient-shift{0%{background-position:0% 50%}50%{background-position:100% 50%}100%{background-position:0% 50%}}
27
+ @keyframes slide-up{from{opacity:0;transform:translateY(40px)}to{opacity:1;transform:translateY(0)}}
28
+ @keyframes particle{0%{transform:translateY(0) scale(1);opacity:.5}100%{transform:translateY(-100vh) scale(0);opacity:0}}
29
+ @keyframes morph{0%,100%{border-radius:60% 40% 30% 70%/60% 30% 70% 40%}50%{border-radius:30% 60% 70% 40%/50% 60% 30% 60%}}
30
+ @keyframes float{0%,100%{transform:translateY(0)}50%{transform:translateY(-14px)}}
31
+ @keyframes shimmer{0%{background-position:-200% 0}100%{background-position:200% 0}}
32
+ @keyframes spin-slow{from{transform:rotate(0deg)}to{transform:rotate(360deg)}}
33
+ @keyframes dash{to{stroke-dashoffset:0}}
34
+ @keyframes scale-in{from{opacity:0;transform:scale(.85)}to{opacity:1;transform:scale(1)}}
35
+
36
+ .reveal{opacity:0;transform:translateY(30px);transition:opacity .8s cubic-bezier(.16,1,.3,1),transform .8s cubic-bezier(.16,1,.3,1)}.reveal.visible{opacity:1;transform:translateY(0)}
37
+ .reveal-left{opacity:0;transform:translateX(-40px);transition:opacity .8s cubic-bezier(.16,1,.3,1),transform .8s cubic-bezier(.16,1,.3,1)}.reveal-left.visible{opacity:1;transform:translateX(0)}
38
+ .reveal-right{opacity:0;transform:translateX(40px);transition:opacity .8s cubic-bezier(.16,1,.3,1),transform .8s cubic-bezier(.16,1,.3,1)}.reveal-right.visible{opacity:1;transform:translateX(0)}
39
+ .reveal-scale{opacity:0;transform:scale(.9);transition:opacity .8s cubic-bezier(.16,1,.3,1),transform .8s cubic-bezier(.16,1,.3,1)}.reveal-scale.visible{opacity:1;transform:scale(1)}
40
+ .d1{transition-delay:.1s}.d2{transition-delay:.2s}.d3{transition-delay:.3s}.d4{transition-delay:.4s}.d5{transition-delay:.5s}.d6{transition-delay:.6s}
41
+
42
+ /* ============ LAYOUT ============ */
43
+ .container{max-width:1200px;margin:0 auto;padding:0 24px}
44
+ section{padding:120px 0;position:relative;overflow:hidden}
45
+
46
+ /* ============ NAVBAR ============ */
47
+ .navbar{position:fixed;top:0;left:0;right:0;z-index:1000;padding:14px 0;transition:all .35s ease}
48
+ .navbar.scrolled{background:rgba(6,6,10,.88);backdrop-filter:blur(20px) saturate(1.4);border-bottom:1px solid var(--border);padding:10px 0}
49
+ .nav-inner{display:flex;align-items:center;justify-content:space-between}
50
+ .nav-brand{display:flex;align-items:center;gap:10px;font-weight:800;font-size:20px;letter-spacing:-.5px}
51
+ .nav-logo{width:34px;height:34px;border-radius:10px;background:linear-gradient(135deg,#0ea5e9,#2563eb);display:flex;align-items:center;justify-content:center;padding:4px;box-shadow:0 2px 12px rgba(14,165,233,.3)}
52
+ .nav-logo img{width:100%;height:100%;filter:brightness(10)}
53
+ .nav-brand-text{background:linear-gradient(135deg,var(--accent2),var(--cyan));-webkit-background-clip:text;-webkit-text-fill-color:transparent}
54
+ .nav-links{display:flex;align-items:center;gap:4px}
55
+ .nav-link{padding:8px 16px;border-radius:8px;font-size:13.5px;font-weight:500;color:var(--dim);transition:all .2s}
56
+ .nav-link:hover{color:var(--text);background:rgba(255,255,255,.04)}
57
+ .nav-link.active{color:var(--accent2)}
58
+ .nav-cta{padding:9px 22px;border-radius:10px;font-size:13.5px;font-weight:700;background:var(--accent);color:#fff;border:none;cursor:pointer;transition:all .3s;margin-left:8px}
59
+ .nav-cta:hover{background:var(--accent3);transform:translateY(-1px);box-shadow:0 6px 24px var(--glow)}
60
+ .hamburger{display:none;background:none;border:none;color:var(--dim);padding:8px;cursor:pointer}
61
+ .hamburger svg{width:24px;height:24px}
62
+
63
+ /* ============ HERO ============ */
64
+ .hero{min-height:100vh;display:flex;align-items:center;position:relative;padding-top:80px;padding-bottom:40px}
65
+ .hero-bg{position:absolute;inset:0;overflow:hidden;pointer-events:none}
66
+ .hero-grid{position:absolute;inset:0;background-image:linear-gradient(rgba(108,92,231,.06) 1px,transparent 1px),linear-gradient(90deg,rgba(108,92,231,.06) 1px,transparent 1px);background-size:64px 64px;mask-image:radial-gradient(ellipse 70% 60% at 50% 40%,black 20%,transparent 70%)}
67
+ .hero-orb{position:absolute;border-radius:50%;filter:blur(100px);opacity:.25;animation:morph 18s ease-in-out infinite}
68
+ .hero-orb.a{width:550px;height:550px;background:var(--accent);top:-15%;right:5%}
69
+ .hero-orb.b{width:400px;height:400px;background:var(--cyan);bottom:0;left:0;animation-delay:-6s}
70
+ .hero-orb.c{width:300px;height:300px;background:var(--pink);bottom:10%;right:25%;animation-delay:-12s}
71
+ .particles{position:absolute;inset:0;overflow:hidden}
72
+ .ptcl{position:absolute;width:2px;height:2px;background:var(--accent2);border-radius:50%;animation:particle linear infinite;opacity:0}
73
+
74
+ .hero-content{position:relative;z-index:2;text-align:center;max-width:820px;margin:0 auto}
75
+ .hero-eyebrow{display:inline-flex;align-items:center;gap:8px;padding:6px 16px 6px 8px;border-radius:100px;font-size:12px;font-weight:600;letter-spacing:.3px;background:rgba(108,92,231,.1);border:1px solid rgba(108,92,231,.25);color:var(--accent2);margin-bottom:28px;animation:slide-up .7s ease both}
76
+ .hero-eyebrow .dot{width:8px;height:8px;border-radius:50%;background:var(--green);box-shadow:0 0 8px var(--green)}
77
+ .hero-eyebrow .tag{padding:3px 10px;border-radius:100px;background:rgba(108,92,231,.2);font-weight:700;font-size:11px;margin-right:4px}
78
+
79
+ .hero h1{font-size:clamp(42px,7.5vw,80px);font-weight:900;letter-spacing:-2.5px;line-height:1.05;margin-bottom:24px;animation:slide-up .7s ease .08s both}
80
+ .hero h1 .grad{background:linear-gradient(135deg,var(--accent2) 0%,var(--cyan) 50%,var(--accent2) 100%);background-size:200% 200%;-webkit-background-clip:text;-webkit-text-fill-color:transparent;animation:gradient-shift 5s ease infinite}
81
+ .hero .sub{font-size:clamp(15px,2.2vw,19px);color:var(--dim);max-width:580px;margin:0 auto 40px;animation:slide-up .7s ease .15s both;font-weight:400;line-height:1.75}
82
+
83
+ .hero-actions{display:flex;gap:14px;justify-content:center;flex-wrap:wrap;animation:slide-up .7s ease .22s both}
84
+ .btn-h{padding:15px 32px;border-radius:var(--r);font-size:15px;font-weight:700;border:none;cursor:pointer;display:inline-flex;align-items:center;gap:9px;transition:all .3s ease;text-decoration:none}
85
+ .btn-h svg{width:18px;height:18px}
86
+ .btn-h.primary{background:linear-gradient(135deg,var(--accent),var(--accent3));color:#fff;box-shadow:0 4px 24px var(--glow)}
87
+ .btn-h.primary:hover{transform:translateY(-2px);box-shadow:0 8px 36px rgba(108,92,231,.35)}
88
+ .btn-h.secondary{background:var(--bg2);color:var(--text);border:1px solid var(--border)}
89
+ .btn-h.secondary:hover{border-color:var(--accent);background:var(--bg3);transform:translateY(-2px)}
90
+
91
+ /* trusted by */
92
+ .trusted{margin-top:64px;animation:slide-up .7s ease .3s both}
93
+ .trusted-label{font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:1.5px;color:var(--muted);margin-bottom:16px}
94
+ .trusted-logos{display:flex;justify-content:center;gap:36px;align-items:center;flex-wrap:wrap;opacity:.5}
95
+ .trusted-logos span{font-size:15px;font-weight:700;letter-spacing:-.3px;color:var(--dim)}
96
+
97
+ /* ============ SHOWCASE TERMINAL ============ */
98
+ .showcase{padding:0 0 100px;position:relative}
99
+ .showcase .container{position:relative;z-index:2}
100
+ .sc-terminal{max-width:780px;margin:0 auto;border-radius:var(--r2);overflow:hidden;border:1px solid var(--border);background:var(--bg1);box-shadow:0 24px 80px rgba(0,0,0,.5),0 0 0 1px rgba(108,92,231,.05)}
101
+ .sc-bar{display:flex;align-items:center;gap:8px;padding:14px 18px;background:var(--bg2);border-bottom:1px solid var(--border)}
102
+ .sc-dot{width:11px;height:11px;border-radius:50%}
103
+ .sc-dot.r{background:#ff5f57}.sc-dot.y{background:#febc2e}.sc-dot.g{background:#28c840}
104
+ .sc-title{font-size:11px;color:var(--muted);margin-left:auto;font-family:'JetBrains Mono',monospace}
105
+ .sc-body{padding:24px;font-family:'JetBrains Mono',monospace;font-size:13px;line-height:2}
106
+ .sc-line{display:flex;gap:8px;opacity:0;animation:slide-up .4s ease both}
107
+ .sc-line:nth-child(1){animation-delay:.3s}.sc-line:nth-child(2){animation-delay:.7s}
108
+ .sc-line:nth-child(3){animation-delay:1.1s}.sc-line:nth-child(4){animation-delay:1.5s}
109
+ .sc-line:nth-child(5){animation-delay:1.9s}.sc-line:nth-child(6){animation-delay:2.3s}
110
+ .sc-line:nth-child(7){animation-delay:2.7s}
111
+ .t-prompt{color:var(--accent2);white-space:nowrap}.t-cmd{color:var(--green)}.t-out{color:var(--dim)}.t-flag{color:var(--orange)}.t-link{color:var(--cyan)}
112
+
113
+ /* ============ FEATURES ============ */
114
+ .features{background:linear-gradient(180deg,var(--bg),var(--bg1))}
115
+ .sh{text-align:center;max-width:620px;margin:0 auto 72px}
116
+ .sh-badge{display:inline-flex;align-items:center;gap:6px;padding:5px 14px;border-radius:100px;font-size:11px;font-weight:700;letter-spacing:.8px;text-transform:uppercase;background:var(--bg2);border:1px solid var(--border);color:var(--accent2);margin-bottom:18px}
117
+ .sh h2{font-size:clamp(30px,4.5vw,46px);font-weight:800;letter-spacing:-1.5px;margin-bottom:14px}
118
+ .sh p{color:var(--dim);font-size:15.5px;line-height:1.7}
119
+ .feat-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:18px}
120
+ .feat{padding:30px;border-radius:var(--r2);background:var(--bg2);border:1px solid var(--border);transition:all .4s cubic-bezier(.16,1,.3,1);position:relative;overflow:hidden}
121
+ .feat::after{content:'';position:absolute;top:0;left:0;right:0;height:2px;background:linear-gradient(90deg,transparent,var(--accent2),transparent);opacity:0;transition:opacity .4s}
122
+ .feat:hover{border-color:rgba(108,92,231,.35);transform:translateY(-4px);box-shadow:0 12px 40px rgba(0,0,0,.25)}
123
+ .feat:hover::after{opacity:1}
124
+ .feat-ico{width:48px;height:48px;border-radius:var(--r);display:flex;align-items:center;justify-content:center;margin-bottom:20px;font-size:24px;background:linear-gradient(135deg,var(--glow),var(--glow2));border:1px solid rgba(108,92,231,.15)}
125
+ .feat h3{font-size:16px;font-weight:700;margin-bottom:8px;letter-spacing:-.2px}
126
+ .feat p{font-size:13px;color:var(--dim);line-height:1.7}
127
+ .feat .tag{display:inline-block;margin-top:14px;font-size:10px;padding:3px 10px;border-radius:6px;background:var(--bg3);color:var(--muted);font-weight:600;letter-spacing:.3px}
128
+
129
+ /* ============ WORKFLOW SHOWCASE ============ */
130
+ .wf-section{background:var(--bg1);position:relative}
131
+ .wf-section::before{content:'';position:absolute;top:50%;left:50%;width:800px;height:800px;transform:translate(-50%,-50%);background:radial-gradient(circle,rgba(108,92,231,.06),transparent 70%);pointer-events:none}
132
+ .wf-grid{display:grid;grid-template-columns:1fr 1fr;gap:64px;align-items:center}
133
+ .wf-text h3{font-size:clamp(24px,3.5vw,36px);font-weight:800;letter-spacing:-1px;margin-bottom:16px}
134
+ .wf-text p{color:var(--dim);font-size:14.5px;line-height:1.8;margin-bottom:28px}
135
+ .wf-features{list-style:none}
136
+ .wf-features li{display:flex;align-items:center;gap:12px;padding:8px 0;font-size:14px;color:var(--dim)}
137
+ .wf-features li .ico{width:28px;height:28px;border-radius:8px;display:flex;align-items:center;justify-content:center;font-size:14px;background:var(--bg3);border:1px solid var(--border);flex-shrink:0}
138
+ .wf-visual{position:relative}
139
+ .wf-mock{background:var(--bg2);border:1px solid var(--border);border-radius:var(--r2);overflow:hidden;box-shadow:0 20px 60px rgba(0,0,0,.4)}
140
+ .wf-mock-bar{padding:10px 14px;background:var(--bg3);border-bottom:1px solid var(--border);display:flex;gap:6px;align-items:center}
141
+ .wf-mock-dot{width:8px;height:8px;border-radius:50%;background:var(--border)}
142
+ .wf-canvas{padding:32px;min-height:340px;position:relative}
143
+ .wf-node{position:absolute;padding:12px 18px;border-radius:12px;background:var(--bg3);border:1px solid var(--border);font-size:12px;font-weight:600;display:flex;align-items:center;gap:8px;transition:all .3s;animation:float 4s ease-in-out infinite}
144
+ .wf-node .nd{width:8px;height:8px;border-radius:50%}
145
+ .wf-node:hover{border-color:var(--accent);transform:translateY(-2px)!important}
146
+
147
+ /* ============ LANGUAGES ============ */
148
+ .langs{background:linear-gradient(180deg,var(--bg1),var(--bg))}
149
+ .lang-grid{display:grid;grid-template-columns:repeat(6,1fr);gap:16px;margin-top:48px}
150
+ .lang-card{text-align:center;padding:28px 16px;border-radius:var(--r2);background:var(--bg2);border:1px solid var(--border);transition:all .3s}
151
+ .lang-card:hover{border-color:rgba(108,92,231,.3);transform:translateY(-4px);box-shadow:0 8px 32px rgba(0,0,0,.2)}
152
+ .lang-card .lang-icon{font-size:36px;margin-bottom:12px;display:block}
153
+ .lang-card .lang-name{font-size:13px;font-weight:700;margin-bottom:4px}
154
+ .lang-card .lang-info{font-size:11px;color:var(--muted)}
155
+
156
+ /* ============ PROVIDERS ============ */
157
+ .providers{background:var(--bg)}
158
+ .prov-row{display:flex;justify-content:center;gap:20px;flex-wrap:wrap;margin-top:48px}
159
+ .prov-card{padding:24px 32px;border-radius:var(--r2);background:var(--bg2);border:1px solid var(--border);text-align:center;min-width:180px;transition:all .3s}
160
+ .prov-card:hover{border-color:rgba(108,92,231,.3);transform:translateY(-3px)}
161
+ .prov-card .prov-name{font-size:15px;font-weight:700;margin-bottom:4px}
162
+ .prov-card .prov-type{font-size:11px;color:var(--muted)}
163
+
164
+ /* ============ CLAWLING HUB ============ */
165
+ .hub{background:linear-gradient(180deg,var(--bg),var(--bg1));position:relative}
166
+ .hub::before{content:'';position:absolute;top:-100px;left:50%;transform:translateX(-50%);width:700px;height:700px;background:radial-gradient(circle,rgba(24,255,255,.04),transparent 70%);pointer-events:none}
167
+ .hub-intro{display:grid;grid-template-columns:1fr 1fr;gap:64px;align-items:center;margin-bottom:72px}
168
+ .hub-intro-text h3{font-size:clamp(24px,3.5vw,36px);font-weight:800;letter-spacing:-1px;margin-bottom:16px}
169
+ .hub-intro-text h3 .grad{background:linear-gradient(135deg,var(--cyan),var(--accent2));-webkit-background-clip:text;-webkit-text-fill-color:transparent}
170
+ .hub-intro-text p{color:var(--dim);font-size:14.5px;line-height:1.8;margin-bottom:20px}
171
+ .hub-intro-text .hub-stats{display:flex;gap:24px}
172
+ .hub-intro-text .hs{text-align:center}
173
+ .hub-intro-text .hs .val{font-size:28px;font-weight:800;color:var(--text)}
174
+ .hub-intro-text .hs .lbl{font-size:10px;color:var(--muted);text-transform:uppercase;letter-spacing:.8px}
175
+ .hub-code{border-radius:var(--r2);overflow:hidden;border:1px solid var(--border);background:var(--bg1);box-shadow:0 16px 48px rgba(0,0,0,.3)}
176
+ .hub-code-bar{padding:10px 14px;background:var(--bg2);border-bottom:1px solid var(--border);font-size:11px;color:var(--muted);font-family:'JetBrains Mono',monospace;display:flex;align-items:center;gap:8px}
177
+ .hub-code-bar .lang-dot{width:8px;height:8px;border-radius:50%;background:var(--cyan)}
178
+ .hub-code-body{padding:20px;font-family:'JetBrains Mono',monospace;font-size:12px;line-height:1.9;color:var(--dim);overflow-x:auto;white-space:pre}
179
+ .hub-code-body .kw{color:var(--accent2)}.hub-code-body .fn{color:var(--cyan)}.hub-code-body .str{color:var(--green)}.hub-code-body .cm{color:var(--muted);font-style:italic}.hub-code-body .tp{color:var(--orange)}
180
+
181
+ .hub-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:16px}
182
+ .hub-card{border-radius:var(--r2);background:var(--bg2);border:1px solid var(--border);overflow:hidden;transition:all .4s cubic-bezier(.16,1,.3,1)}
183
+ .hub-card:hover{border-color:rgba(108,92,231,.35);transform:translateY(-4px);box-shadow:0 12px 40px rgba(0,0,0,.25)}
184
+ .hc-head{padding:18px 18px 0;display:flex;align-items:center;gap:12px}
185
+ .hc-ico{width:40px;height:40px;border-radius:10px;display:flex;align-items:center;justify-content:center;font-size:20px;background:linear-gradient(135deg,var(--glow),var(--glow2));border:1px solid rgba(108,92,231,.15);flex-shrink:0}
186
+ .hc-meta{flex:1;min-width:0}
187
+ .hc-meta h4{font-size:14px;font-weight:700;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
188
+ .hc-meta .author{font-size:11px;color:var(--muted)}
189
+ .hc-body{padding:12px 18px}
190
+ .hc-body p{font-size:12px;color:var(--dim);line-height:1.7;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
191
+ .hc-foot{padding:8px 18px 14px;display:flex;align-items:center;gap:6px;flex-wrap:wrap}
192
+ .hc-tag{padding:2px 8px;border-radius:6px;font-size:10px;font-weight:600;background:var(--bg3);color:var(--muted)}
193
+ .hc-tag.lang{color:var(--cyan);border:1px solid rgba(24,255,255,.12);background:rgba(24,255,255,.04)}
194
+ .hc-stats{margin-left:auto;display:flex;gap:10px;font-size:11px;color:var(--muted)}
195
+ .hc-stats span{display:flex;align-items:center;gap:3px}
196
+ .hc-stats svg{width:12px;height:12px}
197
+ .hub-more{text-align:center;margin-top:48px}
198
+
199
+ /* ============ HOW IT WORKS ============ */
200
+ .how{background:var(--bg1)}
201
+ .how-steps{display:grid;grid-template-columns:repeat(4,1fr);gap:24px;position:relative;margin-top:8px}
202
+ .how-step{text-align:center;position:relative;padding:32px 16px}
203
+ .step-num{width:52px;height:52px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:20px;font-weight:800;margin:0 auto 18px;background:linear-gradient(135deg,var(--accent),var(--accent3));color:#fff;box-shadow:0 4px 20px var(--glow)}
204
+ .how-step h3{font-size:15px;font-weight:700;margin-bottom:8px}
205
+ .how-step p{font-size:12.5px;color:var(--dim);line-height:1.7}
206
+ .how-line{position:absolute;top:58px;left:0;right:0;height:2px;background:linear-gradient(90deg,transparent,var(--border),var(--border),transparent);z-index:0;pointer-events:none}
207
+
208
+ /* ============ ARCHITECTURE ============ */
209
+ .arch{background:linear-gradient(180deg,var(--bg1),var(--bg))}
210
+ .arch-grid{display:grid;grid-template-columns:1fr 1fr;gap:56px;align-items:center}
211
+ .arch-text h3{font-size:clamp(24px,3.5vw,34px);font-weight:800;letter-spacing:-1px;margin-bottom:16px}
212
+ .arch-text p{color:var(--dim);font-size:14px;line-height:1.8;margin-bottom:24px}
213
+ .arch-checks{list-style:none}
214
+ .arch-checks li{display:flex;align-items:center;gap:10px;padding:8px 0;font-size:13px;color:var(--dim)}
215
+ .arch-checks li::before{content:'✓';width:22px;height:22px;border-radius:50%;background:rgba(0,230,118,.1);color:var(--green);display:flex;align-items:center;justify-content:center;font-size:11px;font-weight:700;flex-shrink:0}
216
+ .arch-diagram{background:var(--bg2);border:1px solid var(--border);border-radius:var(--r2);padding:28px;font-family:'JetBrains Mono',monospace;font-size:11.5px}
217
+ .arch-diagram .ad-label{font-size:9px;color:var(--muted);text-transform:uppercase;letter-spacing:1px;margin-bottom:14px}
218
+ .ad-node{padding:11px 16px;border-radius:10px;border:1px solid var(--border);margin:5px 0;display:flex;align-items:center;gap:10px;transition:all .25s;background:var(--bg3)}
219
+ .ad-node:hover{border-color:var(--accent);transform:translateX(4px)}
220
+ .ad-node .dot{width:8px;height:8px;border-radius:50%;flex-shrink:0}
221
+ .ad-node .name{font-weight:600;color:var(--text);font-size:12px}
222
+ .ad-node .desc{color:var(--muted);margin-left:auto;font-size:10px}
223
+
224
+ /* ============ GET STARTED ============ */
225
+ .getstarted{background:var(--bg);position:relative}
226
+ .gs-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:20px}
227
+ .gs-card{padding:32px;border-radius:var(--r2);background:var(--bg2);border:1px solid var(--border);transition:all .3s;text-align:center}
228
+ .gs-card:hover{border-color:rgba(108,92,231,.3);transform:translateY(-3px)}
229
+ .gs-card .gs-step{width:40px;height:40px;border-radius:50%;background:linear-gradient(135deg,var(--accent),var(--accent3));color:#fff;font-weight:800;font-size:16px;display:flex;align-items:center;justify-content:center;margin:0 auto 16px}
230
+ .gs-card h3{font-size:15px;font-weight:700;margin-bottom:8px}
231
+ .gs-card p{font-size:12.5px;color:var(--dim);line-height:1.7}
232
+ .gs-card code{display:inline-block;margin-top:12px;padding:8px 16px;border-radius:8px;background:var(--bg);border:1px solid var(--border);font-family:'JetBrains Mono',monospace;font-size:12px;color:var(--green)}
233
+
234
+ /* ============ CTA ============ */
235
+ .cta{text-align:center;padding:100px 0 120px;position:relative}
236
+ .cta::before{content:'';position:absolute;inset:0;background:radial-gradient(ellipse at center,rgba(108,92,231,.05),transparent 70%);pointer-events:none}
237
+ .cta h2{font-size:clamp(28px,4vw,42px);font-weight:900;letter-spacing:-1.5px;margin-bottom:14px}
238
+ .cta p{color:var(--dim);font-size:15px;margin-bottom:36px;max-width:480px;margin-left:auto;margin-right:auto;line-height:1.7}
239
+
240
+ /* ============ FOOTER ============ */
241
+ .footer{border-top:1px solid var(--border);padding:48px 0 32px;background:var(--bg)}
242
+ .footer-grid{display:grid;grid-template-columns:2fr 1fr 1fr 1fr;gap:40px;margin-bottom:32px}
243
+ .footer-brand{display:flex;align-items:center;gap:8px;font-weight:800;font-size:17px;margin-bottom:12px}
244
+ .footer-brand .fl{width:28px;height:28px;border-radius:8px;background:linear-gradient(135deg,var(--accent),var(--accent3));display:flex;align-items:center;justify-content:center;font-size:14px}
245
+ .footer-brand-text{background:linear-gradient(135deg,var(--accent2),var(--cyan));-webkit-background-clip:text;-webkit-text-fill-color:transparent}
246
+ .footer-desc{font-size:13px;color:var(--muted);line-height:1.7;max-width:280px}
247
+ .footer-col h4{font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:1px;color:var(--dim);margin-bottom:14px}
248
+ .footer-col a{display:block;font-size:13px;color:var(--muted);padding:4px 0;transition:color .2s}
249
+ .footer-col a:hover{color:var(--accent2)}
250
+ .footer-bottom{display:flex;justify-content:space-between;align-items:center;padding-top:24px;border-top:1px solid var(--border);font-size:12px;color:var(--muted)}
251
+ .footer-social{display:flex;gap:12px}
252
+ .footer-social a{width:32px;height:32px;border-radius:8px;background:var(--bg2);border:1px solid var(--border);display:flex;align-items:center;justify-content:center;color:var(--muted);transition:all .2s}
253
+ .footer-social a:hover{border-color:var(--accent);color:var(--accent2)}
254
+ .footer-social a svg{width:15px;height:15px}
255
+
256
+ /* ============ RESPONSIVE ============ */
257
+ @media(max-width:1024px){.feat-grid{grid-template-columns:repeat(2,1fr)}.lang-grid{grid-template-columns:repeat(3,1fr)}.footer-grid{grid-template-columns:1fr 1fr}}
258
+ @media(max-width:768px){
259
+ .feat-grid,.gs-grid{grid-template-columns:1fr}
260
+ .arch-grid,.wf-grid,.hub-intro{grid-template-columns:1fr}
261
+ .how-steps{grid-template-columns:repeat(2,1fr)}.how-line{display:none}
262
+ .lang-grid{grid-template-columns:repeat(2,1fr)}
263
+ .nav-links{display:none}.hamburger{display:block}
264
+ .footer-grid{grid-template-columns:1fr}
265
+ section{padding:80px 0}
266
+ .trusted-logos{gap:20px}
267
+ .prov-row{gap:12px}.prov-card{min-width:140px;padding:18px 20px}
268
+ }
269
+ @media(max-width:480px){
270
+ .lang-grid{grid-template-columns:repeat(2,1fr)}
271
+ .how-steps{grid-template-columns:1fr}
272
+ }
273
+ </style>
274
+ </head>
275
+ <body>
276
+
277
+ <!-- ======== NAVBAR ======== -->
278
+ <nav class="navbar" id="navbar">
279
+ <div class="container nav-inner">
280
+ <a href="#" class="nav-brand">
281
+ <div class="nav-logo"><img src="logo.svg" alt="LinguClaw"></div>
282
+ <span class="nav-brand-text">LinguClaw</span>
283
+ </a>
284
+ <div class="nav-links" id="navLinks">
285
+ <a href="#features" class="nav-link">Features</a>
286
+ <a href="#workflows" class="nav-link">Workflows</a>
287
+ <a href="#hub" class="nav-link">Hub</a>
288
+ <a href="#architecture" class="nav-link">Architecture</a>
289
+ <a href="hub.html" class="nav-link">ClawLing Hub</a>
290
+ <a href="https://github.com/LinguDeep/LinguClaw" target="_blank" class="nav-cta">
291
+ <svg viewBox="0 0 24 24" fill="currentColor" width="16" height="16" style="width:16px;height:16px"><path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23A11.509 11.509 0 0112 5.803c1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576C20.566 21.797 24 17.3 24 12c0-6.627-5.373-12-12-12z"/></svg>
292
+ GitHub
293
+ </a>
294
+ </div>
295
+ <button class="hamburger" id="hamburger" aria-label="Menu"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="3" y1="6" x2="21" y2="6"/><line x1="3" y1="12" x2="21" y2="12"/><line x1="3" y1="18" x2="21" y2="18"/></svg></button>
296
+ </div>
297
+ </nav>
298
+
299
+ <!-- ======== HERO ======== -->
300
+ <section class="hero" id="hero">
301
+ <div class="hero-bg">
302
+ <div class="hero-grid"></div>
303
+ <div class="hero-orb a"></div>
304
+ <div class="hero-orb b"></div>
305
+ <div class="hero-orb c"></div>
306
+ <div class="particles" id="particles"></div>
307
+ </div>
308
+ <div class="container hero-content">
309
+ <div class="hero-eyebrow">
310
+ <span class="tag">v0.4.0</span>
311
+ <span class="dot"></span>
312
+ Open Source &middot; Multi-Agent &middot; TypeScript
313
+ </div>
314
+ <h1>Build Smarter with<br><span class="grad">AI Agent Teams</span></h1>
315
+ <p class="sub">Codebase-aware multi-agent orchestration with visual workflows, semantic memory, and a community-driven skill marketplace.</p>
316
+ <div class="hero-actions">
317
+ <a href="#getstarted" class="btn-h primary">
318
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polygon points="5 3 19 12 5 21"/></svg>
319
+ Get Started
320
+ </a>
321
+ <a href="https://github.com/LinguDeep/LinguClaw" target="_blank" class="btn-h secondary">
322
+ <svg viewBox="0 0 24 24" fill="currentColor"><path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23A11.509 11.509 0 0112 5.803c1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576C20.566 21.797 24 17.3 24 12c0-6.627-5.373-12-12-12z"/></svg>
323
+ Star on GitHub
324
+ </a>
325
+ </div>
326
+ <div class="trusted">
327
+ <div class="trusted-label">Trusted technologies</div>
328
+ <div class="trusted-logos">
329
+ <span>TypeScript</span>
330
+ <span>Node.js</span>
331
+ <span>Docker</span>
332
+ <span>SQLite</span>
333
+ <span>Express</span>
334
+ <span>WebSocket</span>
335
+ </div>
336
+ </div>
337
+ </div>
338
+ </section>
339
+
340
+ <!-- ======== TERMINAL SHOWCASE ======== -->
341
+ <section class="showcase">
342
+ <div class="container">
343
+ <div class="sc-terminal reveal-scale">
344
+ <div class="sc-bar">
345
+ <div class="sc-dot r"></div><div class="sc-dot y"></div><div class="sc-dot g"></div>
346
+ <div class="sc-title">linguclaw &mdash; fish</div>
347
+ </div>
348
+ <div class="sc-body">
349
+ <div class="sc-line"><span class="t-prompt">❯</span> <span class="t-cmd">npm install -g linguclaw</span></div>
350
+ <div class="sc-line"><span class="t-prompt">❯</span> <span class="t-cmd">linguclaw init</span> <span class="t-flag">--provider ollama</span></div>
351
+ <div class="sc-line"><span class="t-out">🦀 LinguClaw v0.4.0 initialized</span></div>
352
+ <div class="sc-line"><span class="t-out"> ✓ Multi-agent system ready (Coder, Reviewer, Architect)</span></div>
353
+ <div class="sc-line"><span class="t-out"> ✓ Semantic memory indexed files across <strong style="color:var(--text)">6</strong> languages</span></div>
354
+ <div class="sc-line"><span class="t-out"> ✓ Workflow engine loaded <strong style="color:var(--text)">22</strong> node types</span></div>
355
+ <div class="sc-line"><span class="t-out"> 🌐 Web UI → <span class="t-link">http://localhost:3000</span></span></div>
356
+ </div>
357
+ </div>
358
+ </div>
359
+ </section>
360
+
361
+ <!-- ======== FEATURES ======== -->
362
+ <section class="features" id="features">
363
+ <div class="container">
364
+ <div class="sh reveal">
365
+ <div class="sh-badge">✦ Core Features</div>
366
+ <h2>Everything you need to build intelligent agents</h2>
367
+ <p>From visual workflows to semantic code search — production-ready out of the box.</p>
368
+ </div>
369
+ <div class="feat-grid">
370
+ <div class="feat reveal d1">
371
+ <div class="feat-ico">🧠</div>
372
+ <h3>Multi-Agent Orchestration</h3>
373
+ <p>Coordinate specialized AI agents — Coder, Reviewer, Architect — working together on complex tasks with shared context.</p>
374
+ <span class="tag">Alpha-Beta Strategy</span>
375
+ </div>
376
+ <div class="feat reveal d2">
377
+ <div class="feat-ico">⚡</div>
378
+ <h3>Visual Workflow Editor</h3>
379
+ <p>Drag-and-drop n8n-style node editor. Build automation pipelines visually with 22 built-in node types.</p>
380
+ <span class="tag">22 Node Types</span>
381
+ </div>
382
+ <div class="feat reveal d3">
383
+ <div class="feat-ico">🔍</div>
384
+ <h3>Semantic Code Memory</h3>
385
+ <p>TF-IDF + cosine similarity search over your entire codebase. The agent actually understands your code structure.</p>
386
+ <span class="tag">RAG-Powered</span>
387
+ </div>
388
+ <div class="feat reveal d1">
389
+ <div class="feat-ico">🔌</div>
390
+ <h3>Multi-Provider LLM</h3>
391
+ <p>OpenRouter, OpenAI, Anthropic, Ollama, LM Studio — switch providers seamlessly with built-in resilience.</p>
392
+ <span class="tag">5 Providers</span>
393
+ </div>
394
+ <div class="feat reveal d2">
395
+ <div class="feat-ico">💻</div>
396
+ <h3>6-Language Analysis</h3>
397
+ <p>Deep AST-level understanding for TypeScript, Python, Rust, Go, Java, and C++. Extract functions, classes, dependencies.</p>
398
+ <span class="tag">AST-Based</span>
399
+ </div>
400
+ <div class="feat reveal d3">
401
+ <div class="feat-ico">🛡️</div>
402
+ <h3>Docker Sandboxing</h3>
403
+ <p>Every command runs inside an isolated Docker container with memory limits, CPU caps, and network restrictions.</p>
404
+ <span class="tag">Secure Execution</span>
405
+ </div>
406
+ </div>
407
+ </div>
408
+ </section>
409
+
410
+ <!-- ======== WORKFLOW SHOWCASE ======== -->
411
+ <section class="wf-section" id="workflows">
412
+ <div class="container">
413
+ <div class="sh reveal">
414
+ <div class="sh-badge">🔗 Workflows</div>
415
+ <h2>Automate anything visually</h2>
416
+ <p>Build powerful automation pipelines with a drag-and-drop node editor.</p>
417
+ </div>
418
+ <div class="wf-grid">
419
+ <div class="wf-text reveal-left">
420
+ <h3>n8n-Style Visual Workflows</h3>
421
+ <p>Create complex automation pipelines by connecting nodes visually. No code required for common tasks — but fully extensible with custom TypeScript nodes.</p>
422
+ <ul class="wf-features">
423
+ <li><span class="ico">📥</span> Trigger nodes: HTTP, Cron, Webhook, File Watch</li>
424
+ <li><span class="ico">🧠</span> AI nodes: LLM, Classifier, Summarizer, Q&amp;A</li>
425
+ <li><span class="ico">⚙️</span> Logic: Condition, Switch, Loop, Merge, Delay</li>
426
+ <li><span class="ico">📤</span> Output: Email, Slack, HTTP Request, File Write</li>
427
+ <li><span class="ico">🧩</span> Custom: Build your own nodes with the Plugin API</li>
428
+ </ul>
429
+ </div>
430
+ <div class="wf-visual reveal-right">
431
+ <div class="wf-mock">
432
+ <div class="wf-mock-bar">
433
+ <div class="wf-mock-dot"></div><div class="wf-mock-dot"></div><div class="wf-mock-dot"></div>
434
+ <span style="margin-left:auto;font-size:10px;color:var(--muted);font-family:'JetBrains Mono',monospace">workflow-editor</span>
435
+ </div>
436
+ <div class="wf-canvas" id="wfCanvas">
437
+ <svg style="position:absolute;inset:0;width:100%;height:100%;pointer-events:none;overflow:visible" id="wfSvg"></svg>
438
+ </div>
439
+ </div>
440
+ </div>
441
+ </div>
442
+ </div>
443
+ </section>
444
+
445
+ <!-- ======== LANGUAGES ======== -->
446
+ <section class="langs" id="languages">
447
+ <div class="container">
448
+ <div class="sh reveal">
449
+ <div class="sh-badge">💻 Languages</div>
450
+ <h2>Deep understanding across 6 languages</h2>
451
+ <p>AST-level code analysis that truly understands your codebase structure.</p>
452
+ </div>
453
+ <div class="lang-grid">
454
+ <div class="lang-card reveal d1"><span class="lang-icon">🟦</span><div class="lang-name">TypeScript</div><div class="lang-info">Full AST + Types</div></div>
455
+ <div class="lang-card reveal d2"><span class="lang-icon">🐍</span><div class="lang-name">Python</div><div class="lang-info">Functions + Classes</div></div>
456
+ <div class="lang-card reveal d3"><span class="lang-icon">🦀</span><div class="lang-name">Rust</div><div class="lang-info">Structs + Traits</div></div>
457
+ <div class="lang-card reveal d4"><span class="lang-icon">🐹</span><div class="lang-name">Go</div><div class="lang-info">Packages + Interfaces</div></div>
458
+ <div class="lang-card reveal d5"><span class="lang-icon">☕</span><div class="lang-name">Java</div><div class="lang-info">Classes + Annotations</div></div>
459
+ <div class="lang-card reveal d6"><span class="lang-icon">⚙️</span><div class="lang-name">C++</div><div class="lang-info">Headers + Templates</div></div>
460
+ </div>
461
+ </div>
462
+ </section>
463
+
464
+ <!-- ======== PROVIDERS ======== -->
465
+ <section class="providers">
466
+ <div class="container">
467
+ <div class="sh reveal">
468
+ <div class="sh-badge">🔌 Providers</div>
469
+ <h2>Works with your favorite LLM</h2>
470
+ <p>Switch between providers with a single config change. Circuit breakers and retry logic built-in.</p>
471
+ </div>
472
+ <div class="prov-row">
473
+ <div class="prov-card reveal d1"><div class="prov-name">OpenAI</div><div class="prov-type">GPT-4 / o1</div></div>
474
+ <div class="prov-card reveal d2"><div class="prov-name">Anthropic</div><div class="prov-type">Claude 4</div></div>
475
+ <div class="prov-card reveal d3"><div class="prov-name">OpenRouter</div><div class="prov-type">100+ Models</div></div>
476
+ <div class="prov-card reveal d4"><div class="prov-name">Ollama</div><div class="prov-type">Local / Free</div></div>
477
+ <div class="prov-card reveal d5"><div class="prov-name">LM Studio</div><div class="prov-type">Desktop</div></div>
478
+ </div>
479
+ </div>
480
+ </section>
481
+
482
+ <!-- ======== CLAWLING HUB ======== -->
483
+ <section class="hub" id="hub">
484
+ <div class="container">
485
+ <div class="sh reveal">
486
+ <div class="sh-badge">🧩 Community</div>
487
+ <h2>ClawLing Hub</h2>
488
+ <p>Discover, share, and install community-built skills. Extend LinguClaw's capabilities with one click.</p>
489
+ </div>
490
+
491
+ <div class="hub-intro">
492
+ <div class="hub-intro-text reveal-left">
493
+ <h3>Write skills.<br>Share with the <span class="grad">community</span>.</h3>
494
+ <p>ClawLing Hub is a marketplace for reusable AI skills. Anyone can publish a skill — from web scraping to sentiment analysis — and the community can install them instantly.</p>
495
+ <div class="hub-stats">
496
+ <div class="hs"><div class="val" data-count="49">0</div><div class="lbl">Modules</div></div>
497
+ <div class="hs"><div class="val" data-count="8">0</div><div class="lbl">Categories</div></div>
498
+ <div class="hs"><div class="val" data-count="3">0</div><div class="lbl">Plugins</div></div>
499
+ </div>
500
+ </div>
501
+ <div class="hub-code reveal-right">
502
+ <div class="hub-code-bar"><span class="lang-dot"></span> my-skill.ts</div>
503
+ <div class="hub-code-body"><span class="kw">import</span> { BaseSkill } <span class="kw">from</span> <span class="str">'linguclaw'</span>;
504
+
505
+ <span class="kw">export class</span> <span class="fn">WebScraperSkill</span> <span class="kw">extends</span> BaseSkill {
506
+ NAME = <span class="str">'web-scraper'</span>;
507
+ DESCRIPTION = <span class="str">'Scrape any website'</span>;
508
+ VERSION = <span class="str">'1.0.0'</span>;
509
+ AUTHOR = <span class="str">'LinguClaw'</span>;
510
+ TYPE = <span class="str">'automation'</span>;
511
+
512
+ <span class="kw">async</span> <span class="fn">execute</span>(input: <span class="tp">SkillInput</span>) {
513
+ <span class="cm">// Your skill logic here</span>
514
+ <span class="kw">const</span> data = <span class="kw">await</span> this.<span class="fn">scrape</span>(input.url);
515
+ <span class="kw">return</span> { success: <span class="orange">true</span>, data };
516
+ }
517
+ }</div>
518
+ </div>
519
+ </div>
520
+
521
+ <div class="hub-grid" id="hubGrid"></div>
522
+ <div class="hub-more reveal">
523
+ <a href="hub.html" class="btn-h primary" style="margin:0 8px">
524
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>
525
+ Browse All Skills
526
+ </a>
527
+ <a href="hub.html" class="btn-h secondary" style="margin:0 8px">
528
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg>
529
+ Publish a Skill
530
+ </a>
531
+ </div>
532
+ </div>
533
+ </section>
534
+
535
+ <!-- ======== HOW IT WORKS ======== -->
536
+ <section class="how" id="how">
537
+ <div class="container">
538
+ <div class="sh reveal">
539
+ <div class="sh-badge">⚡ Quick Start</div>
540
+ <h2>Up and running in 4 steps</h2>
541
+ </div>
542
+ <div style="position:relative">
543
+ <div class="how-line"></div>
544
+ <div class="how-steps">
545
+ <div class="how-step reveal d1">
546
+ <div class="step-num">1</div>
547
+ <h3>Install</h3>
548
+ <p>One command to install globally via npm. Zero dependencies beyond Node.js.</p>
549
+ </div>
550
+ <div class="how-step reveal d2">
551
+ <div class="step-num">2</div>
552
+ <h3>Configure</h3>
553
+ <p>Choose your LLM provider — Ollama for free local models, or any cloud API.</p>
554
+ </div>
555
+ <div class="how-step reveal d3">
556
+ <div class="step-num">3</div>
557
+ <h3>Build</h3>
558
+ <p>Create workflows visually, or describe tasks in natural language via CLI.</p>
559
+ </div>
560
+ <div class="how-step reveal d4">
561
+ <div class="step-num">4</div>
562
+ <h3>Deploy</h3>
563
+ <p>Run as a daemon, schedule tasks, or integrate via the REST API.</p>
564
+ </div>
565
+ </div>
566
+ </div>
567
+ </div>
568
+ </section>
569
+
570
+ <!-- ======== ARCHITECTURE ======== -->
571
+ <section class="arch" id="architecture">
572
+ <div class="container">
573
+ <div class="sh reveal">
574
+ <div class="sh-badge">🏗 Architecture</div>
575
+ <h2>Built for production</h2>
576
+ <p>A layered architecture with resilience patterns, circuit breakers, and sandboxed execution.</p>
577
+ </div>
578
+ <div class="arch-grid">
579
+ <div class="arch-text reveal-left">
580
+ <h3>Modular &amp; Extensible</h3>
581
+ <p>Every component is a first-class module. Swap providers, add skills, extend with plugins. The architecture handles failure gracefully at every layer.</p>
582
+ <ul class="arch-checks">
583
+ <li>Circuit breakers on all external calls</li>
584
+ <li>Exponential backoff + adaptive retry</li>
585
+ <li>Path traversal &amp; injection protection</li>
586
+ <li>Privacy-first with local-only mode</li>
587
+ <li>Plugin system with sandboxed loading</li>
588
+ <li>Graceful degradation on provider failure</li>
589
+ </ul>
590
+ </div>
591
+ <div class="arch-diagram reveal-right">
592
+ <div class="ad-label">System Layers</div>
593
+ <div class="ad-node"><div class="dot" style="background:var(--cyan)"></div><span class="name">CLI / Web UI</span><span class="desc">User Interface</span></div>
594
+ <div class="ad-node"><div class="dot" style="background:var(--accent2)"></div><span class="name">Orchestrator</span><span class="desc">Task Routing</span></div>
595
+ <div class="ad-node"><div class="dot" style="background:var(--green)"></div><span class="name">Agent System</span><span class="desc">Multi-Agent Pool</span></div>
596
+ <div class="ad-node"><div class="dot" style="background:var(--orange)"></div><span class="name">PRISM Engine</span><span class="desc">Faceted Reasoning</span></div>
597
+ <div class="ad-node"><div class="dot" style="background:var(--pink)"></div><span class="name">Workflow Engine</span><span class="desc">22 Node Types</span></div>
598
+ <div class="ad-node"><div class="dot" style="background:var(--cyan)"></div><span class="name">Semantic Memory</span><span class="desc">TF-IDF + SQLite</span></div>
599
+ <div class="ad-node"><div class="dot" style="background:var(--green)"></div><span class="name">Multi-Provider LLM</span><span class="desc">5 Backends</span></div>
600
+ <div class="ad-node"><div class="dot" style="background:var(--accent2)"></div><span class="name">Docker Sandbox</span><span class="desc">Isolation Layer</span></div>
601
+ </div>
602
+ </div>
603
+ </div>
604
+ </section>
605
+
606
+ <!-- ======== GET STARTED ======== -->
607
+ <section class="getstarted" id="getstarted">
608
+ <div class="container">
609
+ <div class="sh reveal">
610
+ <div class="sh-badge">🚀 Get Started</div>
611
+ <h2>Start building in under a minute</h2>
612
+ <p>No API key required if you run Ollama locally.</p>
613
+ </div>
614
+ <div class="gs-grid">
615
+ <div class="gs-card reveal d1">
616
+ <div class="gs-step">1</div>
617
+ <h3>Install</h3>
618
+ <p>Install LinguClaw globally from npm.</p>
619
+ <code>npm i -g linguclaw</code>
620
+ </div>
621
+ <div class="gs-card reveal d2">
622
+ <div class="gs-step">2</div>
623
+ <h3>Initialize</h3>
624
+ <p>Set up your project with your preferred LLM provider.</p>
625
+ <code>linguclaw init</code>
626
+ </div>
627
+ <div class="gs-card reveal d3">
628
+ <div class="gs-step">3</div>
629
+ <h3>Launch</h3>
630
+ <p>Start the web dashboard and begin creating workflows.</p>
631
+ <code>linguclaw --web</code>
632
+ </div>
633
+ </div>
634
+ </div>
635
+ </section>
636
+
637
+ <!-- ======== CTA ======== -->
638
+ <section class="cta">
639
+ <div class="container reveal">
640
+ <h2>Ready to build with AI agent teams?</h2>
641
+ <p>Join the growing community of developers automating their workflows with LinguClaw.</p>
642
+ <div style="display:flex;gap:14px;justify-content:center;flex-wrap:wrap">
643
+ <a href="https://github.com/LinguDeep/LinguClaw" target="_blank" class="btn-h primary">
644
+ <svg viewBox="0 0 24 24" fill="currentColor" style="width:18px;height:18px"><path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23A11.509 11.509 0 0112 5.803c1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576C20.566 21.797 24 17.3 24 12c0-6.627-5.373-12-12-12z"/></svg>
645
+ View on GitHub
646
+ </a>
647
+ <a href="hub.html" class="btn-h secondary">
648
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="width:18px;height:18px"><path d="M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5"/></svg>
649
+ Explore ClawLing Hub
650
+ </a>
651
+ </div>
652
+ </div>
653
+ </section>
654
+
655
+ <!-- ======== FOOTER ======== -->
656
+ <footer class="footer">
657
+ <div class="container">
658
+ <div class="footer-grid">
659
+ <div>
660
+ <div class="footer-brand">
661
+ <div class="fl"><img src="logo.svg" alt="" style="width:24px;height:24px;filter:brightness(10)"></div>
662
+ <span class="footer-brand-text">LinguClaw</span>
663
+ </div>
664
+ <p class="footer-desc">Open-source AI multi-agent system with visual workflows, semantic memory, and a community skill marketplace.</p>
665
+ </div>
666
+ <div class="footer-col">
667
+ <h4>Product</h4>
668
+ <a href="#features">Features</a>
669
+ <a href="#workflows">Workflows</a>
670
+ <a href="#architecture">Architecture</a>
671
+ <a href="#getstarted">Get Started</a>
672
+ </div>
673
+ <div class="footer-col">
674
+ <h4>Community</h4>
675
+ <a href="hub.html">ClawLing Hub</a>
676
+ <a href="https://github.com/LinguDeep/LinguClaw/blob/main/CONTRIBUTING.md" target="_blank">Contributing</a>
677
+ <a href="https://github.com/LinguDeep/LinguClaw/blob/main/CHANGELOG.md" target="_blank">Changelog</a>
678
+ </div>
679
+ <div class="footer-col">
680
+ <h4>Resources</h4>
681
+ <a href="https://github.com/LinguDeep/LinguClaw" target="_blank">GitHub</a>
682
+ <a href="https://github.com/LinguDeep/LinguClaw/blob/main/LICENSE" target="_blank">MIT License</a>
683
+ <a href="https://github.com/LinguDeep/LinguClaw/issues" target="_blank">Issues</a>
684
+ </div>
685
+ </div>
686
+ <div class="footer-bottom">
687
+ <span>&copy; 2026 LinguDeep. Open source under MIT.</span>
688
+ <div class="footer-social">
689
+ <a href="https://github.com/LinguDeep/LinguClaw" target="_blank" aria-label="GitHub"><svg viewBox="0 0 24 24" fill="currentColor"><path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23A11.509 11.509 0 0112 5.803c1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576C20.566 21.797 24 17.3 24 12c0-6.627-5.373-12-12-12z"/></svg></a>
690
+ </div>
691
+ </div>
692
+ </div>
693
+ </footer>
694
+
695
+ <script>
696
+ // ===== Particles =====
697
+ !function(){var c=document.getElementById('particles');for(var i=0;i<25;i++){var d=document.createElement('div');d.className='ptcl';d.style.left=Math.random()*100+'%';d.style.top=100+Math.random()*20+'%';d.style.animationDuration=(10+Math.random()*15)+'s';d.style.animationDelay=Math.random()*10+'s';d.style.width=d.style.height=(1+Math.random()*2.5)+'px';c.appendChild(d)}}();
698
+
699
+ // ===== Navbar =====
700
+ var nb=document.getElementById('navbar');
701
+ window.addEventListener('scroll',function(){nb.classList.toggle('scrolled',window.scrollY>40)});
702
+
703
+ // ===== Mobile menu =====
704
+ document.getElementById('hamburger').addEventListener('click',function(){
705
+ var links=document.getElementById('navLinks');
706
+ var open=links.style.display==='flex';
707
+ links.style.display=open?'none':'flex';
708
+ links.style.position='fixed';links.style.top='60px';links.style.left='0';links.style.right='0';
709
+ links.style.background='rgba(6,6,10,.96)';links.style.flexDirection='column';links.style.padding='16px';
710
+ links.style.borderBottom='1px solid var(--border)';links.style.backdropFilter='blur(20px)';
711
+ if(open){links.removeAttribute('style')}
712
+ });
713
+
714
+ // ===== Reveal =====
715
+ var obs=new IntersectionObserver(function(es){es.forEach(function(e){if(e.isIntersecting){e.target.classList.add('visible');obs.unobserve(e.target)}})},{threshold:.08,rootMargin:'0px 0px -30px 0px'});
716
+ document.querySelectorAll('.reveal,.reveal-left,.reveal-right,.reveal-scale').forEach(function(el){obs.observe(el)});
717
+
718
+ // ===== Counter animation =====
719
+ var countDone={};
720
+ function animateCount(el){
721
+ var id=el.textContent+el.parentElement.textContent;
722
+ if(countDone[id])return;countDone[id]=true;
723
+ var target=parseInt(el.dataset.count);
724
+ var dur=1400,start=Date.now();
725
+ !function tick(){
726
+ var p=Math.min((Date.now()-start)/dur,1);
727
+ var e=1-Math.pow(1-p,3);
728
+ el.textContent=Math.round(target*e).toLocaleString();
729
+ if(p<1)requestAnimationFrame(tick);
730
+ }();
731
+ }
732
+ var cObs=new IntersectionObserver(function(es){es.forEach(function(e){if(e.isIntersecting)animateCount(e.target)})},{threshold:.5});
733
+ document.querySelectorAll('[data-count]').forEach(function(el){cObs.observe(el)});
734
+
735
+ // ===== Hub skills — real modules from the codebase =====
736
+ var hubSkills=[
737
+ {name:'Telegram',author:'LinguClaw',icon:'✈️',desc:'Telegram bot integration with markdown formatting and inline keyboards.',tags:['messaging','bot'],lang:'TypeScript',cat:'messaging'},
738
+ {name:'Apple Notes',author:'LinguClaw',icon:'🍎',desc:'Apple Notes integration for macOS. Read and create notes locally.',tags:['productivity','macos'],lang:'TypeScript',cat:'productivity'},
739
+ {name:'Home Assistant',author:'LinguClaw',icon:'🏠',desc:'Home Assistant smart home hub. Control devices, scenes, and automations.',tags:['smart-home','iot'],lang:'TypeScript',cat:'smart-home'},
740
+ {name:'Spotify',author:'LinguClaw',icon:'🎵',desc:'Spotify playback control. Play, pause, skip, and search your library.',tags:['smart-home','music'],lang:'TypeScript',cat:'smart-home'},
741
+ {name:'1Password',author:'LinguClaw',icon:'🔐',desc:'1Password secrets access via service account tokens.',tags:['utility','secrets'],lang:'TypeScript',cat:'utility'},
742
+ {name:'Signal',author:'LinguClaw',icon:'🔒',desc:'Signal private messaging via signal-cli. End-to-end encrypted.',tags:['messaging','privacy'],lang:'TypeScript',cat:'messaging'},
743
+ ];
744
+ !function(){
745
+ var g=document.getElementById('hubGrid'),h='';
746
+ hubSkills.forEach(function(s,i){
747
+ h+='<div class="hub-card reveal d'+(i%3+1)+'">'
748
+ +'<div class="hc-head"><div class="hc-ico">'+s.icon+'</div>'
749
+ +'<div class="hc-meta"><h4>'+s.name+'</h4><div class="author">by '+s.author+'</div></div></div>'
750
+ +'<div class="hc-body"><p>'+s.desc+'</p></div>'
751
+ +'<div class="hc-foot">';
752
+ s.tags.forEach(function(t){h+='<span class="hc-tag">'+t+'</span>'});
753
+ h+='<span class="hc-tag lang">'+s.lang+'</span>'
754
+ +'<span class="hc-tag" style="color:var(--accent2)">'+s.cat+'</span></div></div>';
755
+ });
756
+ g.innerHTML=h;
757
+ g.querySelectorAll('.reveal').forEach(function(el){obs.observe(el)});
758
+ }();
759
+
760
+ // ===== Workflow mock nodes =====
761
+ !function(){
762
+ var canvas=document.getElementById('wfCanvas');
763
+ var nodes=[
764
+ {x:20,y:30,label:'HTTP Trigger',color:'var(--cyan)',delay:0},
765
+ {x:180,y:20,label:'LLM Process',color:'var(--accent2)',delay:1},
766
+ {x:340,y:50,label:'Condition',color:'var(--orange)',delay:2},
767
+ {x:180,y:120,label:'Database',color:'var(--green)',delay:1.5},
768
+ {x:340,y:160,label:'Send Email',color:'var(--pink)',delay:2.5},
769
+ {x:500,y:90,label:'Slack Alert',color:'var(--yellow)',delay:3},
770
+ ];
771
+ nodes.forEach(function(n){
772
+ var el=document.createElement('div');
773
+ el.className='wf-node';
774
+ el.style.left=n.x+'px';el.style.top=n.y+'px';
775
+ el.style.animationDelay=n.delay+'s';
776
+ el.innerHTML='<div class="nd" style="background:'+n.color+'"></div>'+n.label;
777
+ canvas.appendChild(el);
778
+ });
779
+ // draw connections
780
+ var svg=document.getElementById('wfSvg');
781
+ var conns=[[0,1],[1,2],[1,3],[2,5],[3,4]];
782
+ conns.forEach(function(c){
783
+ var a=nodes[c[0]],b=nodes[c[1]];
784
+ var x1=a.x+80,y1=a.y+20,x2=b.x,y2=b.y+20;
785
+ var path=document.createElementNS('http://www.w3.org/2000/svg','path');
786
+ var mx=(x1+x2)/2;
787
+ path.setAttribute('d','M'+x1+','+y1+' C'+mx+','+y1+' '+mx+','+y2+' '+x2+','+y2);
788
+ path.setAttribute('stroke','rgba(108,92,231,.3)');
789
+ path.setAttribute('stroke-width','2');
790
+ path.setAttribute('fill','none');
791
+ svg.appendChild(path);
792
+ });
793
+ }();
794
+
795
+ // ===== Smooth scroll =====
796
+ document.querySelectorAll('a[href^="#"]').forEach(function(a){
797
+ a.addEventListener('click',function(e){
798
+ var t=document.querySelector(this.getAttribute('href'));
799
+ if(t){e.preventDefault();t.scrollIntoView({behavior:'smooth',block:'start'})}
800
+ });
801
+ });
802
+
803
+ // ===== Active nav on scroll =====
804
+ var sections=document.querySelectorAll('section[id]');
805
+ window.addEventListener('scroll',function(){
806
+ var y=window.scrollY+100;
807
+ sections.forEach(function(s){
808
+ var top=s.offsetTop,h=s.offsetHeight,id=s.id;
809
+ var link=document.querySelector('.nav-link[href="#'+id+'"]');
810
+ if(link){
811
+ if(y>=top&&y<top+h)link.classList.add('active');
812
+ else link.classList.remove('active');
813
+ }
814
+ });
815
+ });
816
+ </script>
817
+ </body>
818
+ </html>