lightview 2.3.7 → 2.4.4

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 (43) hide show
  1. package/.gemini/CODE_ANALYSIS_AND_IMPROVEMENT_PLAN.md +56 -0
  2. package/AI-GUIDANCE.md +259 -0
  3. package/README.md +35 -0
  4. package/components/data-display/diff.js +36 -4
  5. package/docs/api/hypermedia.html +75 -5
  6. package/docs/api/index.html +3 -3
  7. package/docs/api/nav.html +0 -16
  8. package/docs/articles/html-vs-json-partials.md +102 -0
  9. package/docs/articles/lightview-vs-htmx.md +610 -0
  10. package/docs/benchmarks/tagged-fragment.js +36 -0
  11. package/docs/cdom.html +6 -5
  12. package/docs/components/chart.html +157 -210
  13. package/docs/components/component-nav.html +1 -1
  14. package/docs/components/diff.html +33 -21
  15. package/docs/components/gallery.html +107 -4
  16. package/docs/components/index.css +18 -3
  17. package/docs/components/index.html +20 -9
  18. package/docs/dom-benchmark.html +644 -0
  19. package/docs/getting-started/index.html +2 -2
  20. package/docs/hypermedia/index.html +391 -0
  21. package/docs/hypermedia/nav.html +17 -0
  22. package/docs/index.html +128 -18
  23. package/index.html +59 -10
  24. package/lightview-all.js +223 -67
  25. package/lightview-cdom.js +1 -2
  26. package/lightview-x.js +144 -13
  27. package/lightview.js +85 -277
  28. package/package.json +2 -2
  29. package/src/lightview-cdom.js +1 -5
  30. package/src/lightview-x.js +158 -27
  31. package/src/lightview.js +94 -60
  32. package/1769196538097-package.json +0 -43
  33. package/build_tmp/lightview-router.js +0 -185
  34. package/build_tmp/lightview-x.js +0 -1608
  35. package/build_tmp/lightview.js +0 -932
  36. package/docs/articles/calculator-no-javascript-hackernoon.md +0 -283
  37. package/docs/articles/calculator-no-javascript.md +0 -290
  38. package/docs/articles/part1-reference.md +0 -236
  39. package/lightview.js.bak +0 -1
  40. package/test-xpath.html +0 -63
  41. package/test_error.txt +0 -0
  42. package/test_output.txt +0 -0
  43. package/test_output_full.txt +0 -0
@@ -0,0 +1,391 @@
1
+ <!-- SEO-friendly SPA Shim -->
2
+ <script src="/lightview-router.js?base=/index.html"></script>
3
+
4
+ <div class="docs-layout">
5
+ <aside class="docs-sidebar" src="/docs/hypermedia/nav.html" data-preserve-scroll="docs-nav"></aside>
6
+
7
+ <main class="docs-content">
8
+ <h1>Hypermedia</h1>
9
+ <p>
10
+ HTMX-style patterns, built right in. Load HTML fragments, fetch vDOM/Object DOM, clone templates - all with
11
+ the
12
+ <code>src</code> and <code>href</code> attributes.
13
+ <em>Requires lightview-x.js</em>
14
+ </p>
15
+ <p>
16
+ If you look at the source for the navigation to the left, you will see that this page is built using a
17
+ hypermedia approach.
18
+ </p>
19
+
20
+ <h2 id="fetching-content">Fetching Content</h2>
21
+ <h3 id="html">HTML</h3>
22
+ <p>
23
+ Point <code>src</code> at an HTML file and Lightview loads it as children:
24
+ </p>
25
+ <pre><code>&lt;!-- Load HTML partials into specific elements --&gt;
26
+ &lt;div&gt;
27
+ &lt;header src="/partials/nav.html"&gt;&lt;/header&gt;
28
+ &lt;main src="/partials/content.html"&gt;&lt;/main&gt;
29
+ &lt;/div&gt;
30
+
31
+ &lt;!-- The HTML is fetched, parsed, and made reactive automatically! --&gt;</code></pre>
32
+
33
+ <p>
34
+ By default, Lightview enforces a <strong>Same-Domain security policy</strong> for all remote fetches.
35
+ Content can only be fetched from the same domain or its subdomains. External domains are blocked to prevent
36
+ Cross-Site Scripting (XSS) and unauthorized data ingestion. Different ports on the same host (e.g.,
37
+ localhost:3000 and localhost:4000) are <strong>allowed</strong> by default.
38
+ </p>
39
+ <p>
40
+ <strong>Relative Paths:</strong> Any URL that does not specify a protocol (e.g., <code>./data.html</code>,
41
+ <code>/api/user</code>) is automatically considered valid. This ensures reliability in sandboxed
42
+ environments (like iframes) where the global origin might be reported as <code>null</code>.
43
+ </p>
44
+
45
+ <h4>Controlling Access with validateUrl</h4>
46
+ <p>
47
+ You can customize or disable this security policy using the <code>validateUrl</code> hook. This hook is
48
+ checked before any <code>src</code> fetch or non-standard <code>href</code> navigation.
49
+ </p>
50
+
51
+ <pre><code>// Allow specific external CDNs
52
+ Lightview.hooks.validateUrl = (url) => {
53
+ const target = new URL(url, location.origin);
54
+ const allowed = ['trusted-api.com', 'cdn.content.org', 'localhost'];
55
+ return allowed.includes(target.hostname) || target.hostname.endsWith('.mysite.com');
56
+ };
57
+
58
+ // Disable security (Not recommended for production)
59
+ Lightview.hooks.validateUrl = () => true;</code></pre>
60
+
61
+ <h4>Dangerous Protocol Blocking</h4>
62
+ <p>
63
+ Lightview automatically blocks dangerous URI protocols in <code>src</code> and <code>href</code> attributes,
64
+ including <code>javascript:</code>, <code>vbscript:</code>, and certain <code>data:</code> types. If a
65
+ dangerous protocol is detected, the action is cancelled and a warning is logged to the console.
66
+ </p>
67
+
68
+ <h3 id="vdom-object-dom">vDOM and Object DOM</h3>
69
+ <p>
70
+ Files with <code>.<a id="vdom" href="/docs/api/elements#vdom">vdom</a></code>,
71
+ <code>.<a id="odom" href="/docs/api/elements#object-dom">odom</a></code> or
72
+ <code>.<a id="cdom" href="/docs/cdom">cdom</a></code> extensions are parsed as JSON and converted to
73
+ elements.
74
+ Any <a href="#template-literals">Template Literals</a> within the JSON values are automatically resolved.
75
+ </p>
76
+ <pre><code>// /api/cards.vdom
77
+ [
78
+ { "tag": "div", "attributes": { "class": "card" }, "children": ["Card 1"] },
79
+ { "tag": "div", "attributes": { "class": "card" }, "children": ["Card 2"] }
80
+ ]
81
+
82
+ // Load vDOM
83
+ div({ src: '/api/cards.vdom' })
84
+
85
+ // Load safe, reactive HTML
86
+ div({ src: '/api/ai-generated.cdom' })
87
+ </code></pre>
88
+
89
+ <h2 id="advanced-fetches">Advanced Fetches (data-method & data-body)</h2>
90
+ <p>
91
+ You can customize the HTTP request method and body for any <code>src</code> or <code>href</code> action
92
+ using <code>data-method</code> and <code>data-body</code>.
93
+ </p>
94
+
95
+ <h3>1. Request Methods</h3>
96
+ <p>Use <code>data-method</code> to specify an HTTP verb. Defaults to <code>GET</code>.</p>
97
+ <pre><code>&lt;!-- Send a DELETE request --&gt;
98
+ &lt;button href="/api/items/123" data-method="DELETE" target="#status-log"&gt;
99
+ Delete Item
100
+ &lt;/button&gt;</code></pre>
101
+
102
+ <h3>2. Request Bodies</h3>
103
+ <p>Use <code>data-body</code> to send data. The prefixes <code>css:</code>, <code>json:</code>, and
104
+ <code>text:</code> can be used to control exactly how the body is constructed. If no prefix is used, it is
105
+ treated as a CSS selector.</p>
106
+
107
+ <h4>CSS Selectors (Default)</h4>
108
+ <p>Grabs data from the DOM based on the element type:</p>
109
+ <ul>
110
+ <li><strong>Forms:</strong> If the selector points to a <code>&lt;form&gt;</code>, the entire form is
111
+ serialized as <code>FormData</code>.
112
+ </li>
113
+ <li><strong>Checkboxes/Radios:</strong> Only sends the <code>value</code> if the element is
114
+ <code>checked</code>. Otherwise, no data is sent.
115
+ </li>
116
+ <li><strong>Input/Select/Textarea:</strong> Sends the current <code>value</code>.</li>
117
+ <li><strong>Other Elements:</strong> Sends the <code>innerText</code> (e.g., from a <code>&lt;div&gt;</code>
118
+ or <code>&lt;span&gt;</code>).
119
+ </li>
120
+ </ul>
121
+ <pre><code>&lt;!-- Send the value of an input (Query param search?body=...) --&gt;
122
+ &lt;button href="/api/search" data-body="#search-input" target="#results"&gt;Search&lt;/button&gt;
123
+ &lt;input id="search-input" type="text"&gt;
124
+
125
+ &lt;!-- Send an entire form as POST --&gt;
126
+ &lt;button href="/api/user/update" data-method="POST" data-body="#user-form"&gt;Save&lt;/button&gt;
127
+ &lt;form id="user-form"&gt;
128
+ &lt;input name="email" value="user@example.com"&gt;
129
+ &lt;/form&gt;</code></pre>
130
+
131
+ <h4>Prefixes</h4>
132
+ <p>You can use prefixes to control exactly how the body is constructed:</p>
133
+ <ul>
134
+ <li><code>javascript:</code> - Evaluates an expression (has access to <code>state</code> and
135
+ <code>signal</code>).
136
+ </li>
137
+ <li><code>json:</code> - Sends a literal JSON string (sets <code>Content-Type: application/json</code>).
138
+ </li>
139
+ <li><code>text:</code> - Sends raw text (sets <code>Content-Type: text/plain</code>).</li>
140
+ </ul>
141
+ <pre><code>&lt;!-- Dynamic calculation --&gt;
142
+ &lt;button href="/api/log" data-body="javascript:state.user.id"&gt;Log ID&lt;/button&gt;
143
+
144
+ &lt;!-- Literal JSON --&gt;
145
+ &lt;button href="/api/config" data-method="POST" data-body='json:{"theme": "dark"}'&gt;Set Dark Mode&lt;/button&gt;</code></pre>
146
+
147
+ <h4>GET Request Handling</h4>
148
+ <p>If the method is <code>GET</code>, the data provided via <code>data-body</code> is automatically converted
149
+ into <strong>URL Query Parameters</strong>. If multiple values are found (like in a form), all are
150
+ appended to the URL.</p>
151
+
152
+ <h2 id="cloning-dom-elements">Cloning DOM Elements</h2>
153
+ <p>
154
+ Use CSS selectors to clone existing elements:
155
+ </p>
156
+ <pre><code>// Clone a template
157
+ div({ src: '#my-template' })
158
+
159
+ // Clone multiple elements
160
+ div({ src: '.card-template' })</code></pre>
161
+ <pre><code>&lt;!-- Hidden template in HTML --&gt;
162
+ &lt;template id="my-template"&gt;
163
+ &lt;div class="modal"&gt;
164
+ &lt;h2&gt;Modal Title&lt;/h2&gt;
165
+ &lt;p&gt;Modal content here&lt;/p&gt;
166
+ &lt;/div&gt;
167
+ &lt;/template&gt;</code></pre>
168
+
169
+ <h2 id="href-navigation">HREF Navigation</h2>
170
+ <p>
171
+ Add <code>href</code> to any element to make it interactive. The behavior depends on the <code>target</code>
172
+ attribute:
173
+ </p>
174
+ <p><strong>Note:</strong> The same <a href="#fetching-content">src Fetch Security</a> controls (same-domain
175
+ policy
176
+ and protocol
177
+ blocking) apply to all interactive <code>href</code> navigations.</p>
178
+
179
+ <h3>1. Self-Loading (Default)</h3>
180
+ <p>If no target is specified, clicking sets the element's own <code>src</code> to the <code>href</code> value:
181
+ </p>
182
+ <pre><code>// Loads content into itself on click
183
+ button({ href: '/partials/data.html' }, 'Load Data')</code></pre>
184
+
185
+ <h3>2. Browser Navigation</h3>
186
+ <p>Use standard underscore targets for window navigation:</p>
187
+ <pre><code>// Opens new tab
188
+ button({ href: 'https://example.com', target: '_blank' }, 'Open External')
189
+
190
+ // Navigates current page
191
+ div({ href: '/home', target: '_self' }, 'Go Home')</code></pre>
192
+
193
+ <h3>3. Targeting Other Elements</h3>
194
+ <p>Use a CSS selector as the target to load content into other elements:</p>
195
+ <pre><code>// Loads content into element with id="main"
196
+ button({ href: '/pages/about.html', target: '#main' }, 'Load About Page')
197
+
198
+ div({ id: 'main' }) // Content appears here</code></pre>
199
+
200
+ <h3>4. Positioning Content</h3>
201
+ <p>Control where content is inserted using the <code>location</code> attribute or a target suffix.</p>
202
+ <p><strong>Supported locations:</strong> <code>innerhtml</code> (default), <code>outerhtml</code>,
203
+ <code>beforebegin</code>, <code>afterbegin</code>, <code>beforeend</code>, <code>afterend</code>,
204
+ <code>shadow</code>.
205
+ </p>
206
+
207
+ <pre><code>// Option A: Suffix syntax for href (Target Selector:Location)
208
+ button({
209
+ href: '/partials/item.html',
210
+ target: '#list:beforeend' // Append to list
211
+ }, 'Add Item')
212
+
213
+ // Option B: Explicit attribute on target for src
214
+ div({
215
+ src: '/partials/banner.html',
216
+ location: 'afterbegin'
217
+ })</code></pre>
218
+
219
+ <p><strong>Smart Replacement:</strong> Lightview tracks inserted content. Fetching the same content to the same
220
+ location is a no-op. Fetching different content replaces the previous content at that specific location.</p>
221
+
222
+ <h3>5. Hash Scrolling</h3>
223
+ <p>If an <code>href</code> or <code>src</code> includes a hash (e.g., <code>/page.html#section-1</code>),
224
+ Lightview will automatically
225
+ attempt to scroll to the element with that ID after the content is loaded and injected. This works for both
226
+ standard document targets and Shadow DOM targets (where it searches within the specific
227
+ <code>shadowRoot</code>).
228
+ </p>
229
+ <pre><code>// Scrolls to #details within the loaded content
230
+ button({ href: '/api/items.html#details', target: '#content' }, 'View Details')</code></pre>
231
+
232
+ <h2 id="event-gating">Declarative Event Gating (lv-before)</h2>
233
+ <p>
234
+ The <code>lv-before</code> attribute provides a declarative way to intercept, filter, and modify events
235
+ <em>before</em> they reach your standard handlers (like <code>onclick</code>) or trigger native browser
236
+ behavior.
237
+ </p>
238
+ <div class="alert alert-info">
239
+ <p>
240
+ <strong>Important:</strong> Custom gating functions must be defined in the <code>globalThis</code> scope
241
+ (e.g., <code>window.myGate = ...</code>) to be accessible to the declarative parser.
242
+ </p>
243
+ </div>
244
+
245
+ <h3>1. Selection & Exclusions</h3>
246
+ <p>You must specify which events to gate by name, or use <code>*</code> to gate all common (sensible) UI and
247
+ form events. You can
248
+ also exclude specific events:</p>
249
+ <pre><code>&lt;!-- Gate only clicks --&gt;
250
+ &lt;button lv-before="click myGate()"&gt;Click Me&lt;/button&gt;
251
+
252
+ &lt;!-- Gate all common events EXCEPT keyboard events --&gt;
253
+ &lt;div lv-before="* !keydown !keyup logInteraction()"&gt;...&lt;/div&gt;</code></pre>
254
+
255
+ <h3>2. Rate Limiting (Throttle & Debounce)</h3>
256
+ <p>Lightview-X provides built-in "Gate Modifiers" for common timing patterns. These return <code>true</code>
257
+ only when the timing condition is met, effectively filtering the event stream.</p>
258
+ <pre><code>&lt;!-- Prevent button spam (only 1 click per second) --&gt;
259
+ &lt;button lv-before="click throttle(1000)" onclick="saveData()"&gt;Save&lt;/button&gt;
260
+
261
+ &lt;!-- Wait for 500ms of silence before processing input --&gt;
262
+ &lt;input lv-before="input debounce(500)" oninput="search(this.value)"&gt;</code></pre>
263
+
264
+ <h3>3. Sequence & Async Pipelines</h3>
265
+ <p>You can chain multiple gates in a space-separated list. They execute sequentially and can be asynchronous.
266
+ If any function returns <code>false</code>, <code>null</code>, or <code>undefined</code>, the entire event
267
+ is aborted.</p>
268
+ <p><strong>Parsing Note:</strong> Expressions are fundamentally space-separated. However, spaces within single
269
+ quotes (<code>'</code>), double quotes (<code>"</code>), or parentheses (<code>()</code>) are preserved.
270
+ This allows you to pass strings with spaces to your gate functions, such as confirmation messages.</p>
271
+ <pre><code>&lt;!-- Chained: Throttled first, then a confirmation --&gt;
272
+ &lt;button lv-before="click throttle(2000) confirm('Really delete?')"
273
+ onclick="doDelete()"&gt;Delete&lt;/button&gt;</code></pre>
274
+
275
+ <h3>4. Context & Arguments</h3>
276
+ <p>Inside an <code>lv-before</code> expression, <code>this</code> refers to the current element. You can pass
277
+ the
278
+ native
279
+ <code>event</code> object, as well as <code>state</code> and <code>signal</code> registries, to your
280
+ custom gate functions.
281
+ </p>
282
+ <pre><code>&lt;!-- Pass event to a custom logic function --&gt;
283
+ &lt;button lv-before="click validateClick(event)" onclick="proceed()"&gt;...&lt;/button&gt;</code></pre>
284
+
285
+ <h2 id="template-literals">Template Literals</h2>
286
+ <p>
287
+ External HTML, <code>.vdom</code> and <code>.odom</code> files, can reference named signals or state with
288
+ template syntax:
289
+ </p>
290
+ <pre><code>// main.js - Register named signals and state
291
+ const count = signal(0, 'count');
292
+ const userName = signal('Guest', 'userName');
293
+ const userPrefs = state({ theme: 'dark', lang: 'en' }, 'userPrefs');
294
+
295
+ // Load template that uses them
296
+ div({ src: '/partials/dashboard.html' })
297
+ div({ src: '/partials/dashboard.vdom' })
298
+ div({ src: '/partials/dashboard.odom' })</code></pre>
299
+
300
+ <pre><code>&lt;!-- /partials/dashboard.html --&gt;
301
+ &lt;div class="dashboard"&gt;
302
+ &lt;h1&gt;Welcome, ${signal.get('userName').value}!&lt;/h1&gt;
303
+ &lt;p&gt;You have ${signal.get('count').value} notifications.&lt;/p&gt;
304
+ &lt;p&gt;Theme: ${state.get('userPrefs').theme}&lt;/p&gt;
305
+ &lt;/div&gt;</code></pre>
306
+
307
+ <pre><code>// /partials/dashboard.vdom (JSON Array)
308
+ [
309
+ {
310
+ "tag": "div",
311
+ "attributes": { "class": "dashboard" },
312
+ "children": [
313
+ { "tag": "h1", "children": ["Welcome, ${signal.get('userName').value}!"] },
314
+ { "tag": "p", "children": ["Theme: ${state.get('userPrefs').theme}"] }
315
+ ]
316
+ }
317
+ ]</code></pre>
318
+
319
+ <pre><code>// /partials/dashboard.odom (Object DOM)
320
+ {
321
+ "div": {
322
+ "class": "dashboard",
323
+ "children": [
324
+ { "h1": { "children": ["Welcome, ${signal.get('userName').value}!"] } },
325
+ { "p": { "children": ["Theme: ${state.get('userPrefs').theme}"] } }
326
+ ]
327
+ }
328
+ }</code></pre>
329
+
330
+ <h2 id="shadow-dom">Shadow DOM</h2>
331
+ <p>
332
+ Load content into shadow DOM for style isolation using <code>location="shadow"</code> or the
333
+ <code>:shadow</code> suffix:
334
+ </p>
335
+ <pre><code>// Option A: location attribute
336
+ div({ src: '/components/widget.html', location: 'shadow' })
337
+
338
+ // Option B: target suffix
339
+ button({ href: '/components/widget.html', target: '#container:shadow' }, 'Load Widget')</code></pre>
340
+
341
+ <h2 id="htmx-style-apps">HTMX-style Apps</h2>
342
+ <p>
343
+ Combine <code>src</code> and <code>href</code> for hypermedia-driven UIs. You can use <code>lv-before</code>
344
+ for confirmation or validation before navigation.
345
+ </p>
346
+
347
+ <h3>Using Tag Functions</h3>
348
+ <pre><code>const { tags } = Lightview;
349
+ const { div, nav, button, main } = tags;
350
+
351
+ const app = div({ class: 'app' },
352
+ nav({ class: 'sidebar' },
353
+ button({
354
+ href: '/pages/dashboard.html',
355
+ target: '#content'
356
+ }, '📊 Dashboard'),
357
+ button({
358
+ href: '/pages/settings.html',
359
+ target: '#content',
360
+ 'lv-before': "click confirm('Go to settings?')" // Event gate
361
+ }, '⚙️ Settings')
362
+ ),
363
+ main({
364
+ id: 'content',
365
+ src: '/pages/dashboard.html' // Initial content
366
+ })
367
+ );</code></pre>
368
+
369
+ <h3>Using Ligthview Plain HTML</h3>
370
+ <pre><code>&lt;div class="app"&gt;
371
+ &lt;nav class="sidebar"&gt;
372
+ &lt;button href="/pages/dashboard.html" target="#content"&gt;📊 Dashboard&lt;/button&gt;
373
+ &lt;button href="/pages/settings.html" target="#content"
374
+ lv-before="click confirm('Go to settings?')"&gt;⚙️ Settings&lt;/button&gt;
375
+ &lt;/nav&gt;
376
+ &lt;main id="content" src="/pages/dashboard.html"&gt;&lt;/main&gt;
377
+ &lt;/div&gt;</code></pre>
378
+
379
+ <h3>vs. Using HTMX</h3>
380
+ <pre><code>&lt;div class="app"&gt;
381
+ &lt;nav class="sidebar"&gt;
382
+ &lt;button hx-get="/pages/dashboard.html" hx-target="#content"&gt;📊 Dashboard&lt;/button&gt;
383
+ &lt;button hx-get="/pages/settings.html" hx-target="#content"
384
+ hx-confirm="Go to settings?"&gt;⚙️ Settings&lt;/button&gt;
385
+ &lt;/nav&gt;
386
+ &lt;main id="content" hx-get="/pages/dashboard.html" hx-trigger="load"&gt;&lt;/main&gt;
387
+ &lt;/div&gt;</code></pre>
388
+
389
+
390
+ </main>
391
+ </div>
@@ -0,0 +1,17 @@
1
+ <nav data-preserve-scroll="docs-nav" class="docs-nav">
2
+ <div class="docs-nav-section">
3
+ <div class="docs-nav-title">Hypermedia</div>
4
+ <a href="#fetching-content" class="docs-nav-link">Fetching Content</a>
5
+ <div class="docs-nav-subsection" style="margin-left: 1rem; border-left: 1px solid var(--site-border);">
6
+ <a href="#html" class="docs-nav-link" style="font-size: 0.85em;">HTML</a>
7
+ <a href="#vdom-object-dom" class="docs-nav-link" style="font-size: 0.85em;">vDOM & oDOM</a>
8
+ </div>
9
+ <a href="#advanced-fetches" class="docs-nav-link">Advanced Fetches</a>
10
+ <a href="#cloning-dom-elements" class="docs-nav-link">Cloning DOM Elements</a>
11
+ <a href="#href-navigation" class="docs-nav-link">HREF Navigation</a>
12
+ <a href="#event-gating" class="docs-nav-link">Event Gating (lv-before)</a>
13
+ <a href="#template-literals" class="docs-nav-link">Template Literals</a>
14
+ <a href="#shadow-dom" class="docs-nav-link">Shadow DOM</a>
15
+ <a href="#htmx-style-apps" class="docs-nav-link">HTMX-style Apps</a>
16
+ </div>
17
+ </nav>
package/docs/index.html CHANGED
@@ -9,9 +9,13 @@
9
9
  <p class="hero-tagline">Reactive UI's done light</p>
10
10
  <p class="hero-description">
11
11
  More power. Less energy.
12
+ <br>
13
+ <a id="link-hero-ai-safe" href="#ai-safe"
14
+ style="color: var(--site-primary); font-size: 1.25rem; font-weight: 700; text-decoration: none; display: inline-block; margin-top: 0.5rem; border-bottom: 2px solid var(--site-primary); padding-bottom: 2px;">AI
15
+ Safe</a>
12
16
  </p>
13
17
  <div class="hero-actions">
14
- <a href="./getting-started/" class="btn btn-primary btn-lg">Get Started</a>
18
+ <a id="link-hero-get-started" href="./getting-started/" class="btn btn-primary btn-lg">Get Started</a>
15
19
  </div>
16
20
  <div class="hero-stats">
17
21
  <div class="hero-stat">
@@ -40,76 +44,182 @@
40
44
  </p>
41
45
  </div>
42
46
  <div class="feature-grid">
43
- <a href="./api/signals.html" class="feature-card" style="text-decoration: none; color: inherit;">
47
+ <div class="feature-card">
44
48
  <div class="feature-icon">
45
49
  <svg viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" stroke-width="2">
46
50
  <circle cx="12" cy="12" r="10" />
47
51
  <path d="M12 6v6l4 2" />
48
52
  </svg>
49
53
  </div>
50
- <h3 class="feature-title">Signals and Object State Reactivity</h3>
54
+ <h3><a id="link-feature-signals" href="./api/signals.html" class="feature-title">Signals and Object
55
+ State Reactivity</a></h3>
51
56
  <p class="feature-description">
52
57
  Fine-grained reactivity with signals and obejct state. Updates propagate automatically—no virtual
53
58
  DOM diffing needed. As a bonus, session and local storage are also supported.
54
59
  </p>
55
- </a>
56
- <a href="./api/elements.html" class="feature-card" style="text-decoration: none; color: inherit;">
60
+ </div>
61
+ <div class="feature-card">
57
62
  <div class="feature-icon">
58
63
  <svg viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" stroke-width="2">
59
64
  <rect x="3" y="3" width="18" height="18" rx="2" />
60
65
  <path d="M3 9h18M9 21V9" />
61
66
  </svg>
62
67
  </div>
63
- <h3 class="feature-title">Multiple Syntaxes</h3>
68
+ <h3><a id="link-feature-elements" href="./api/elements.html" class="feature-title">Multiple Syntaxes</a>
69
+ </h3>
64
70
  <p class="feature-description">
65
71
  Tagged API, vDOM, Object DOM, HTML. Pick your style—they all work together.
66
72
  </p>
67
- </a>
68
- <a href="./api/hypermedia.html" class="feature-card" style="text-decoration: none; color: inherit;">
73
+ </div>
74
+ <div class="feature-card">
69
75
  <div class="feature-icon">
70
76
  <svg viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" stroke-width="2">
71
77
  <path
72
78
  d="M21 12a9 9 0 01-9 9m9-9a9 9 0 00-9-9m9 9H3m9 9a9 9 0 01-9-9m9 9c1.66 0 3-4 3-9s-1.34-9-3-9m0 18c-1.66 0-3-4-3-9s1.34-9 3-9" />
73
79
  </svg>
74
80
  </div>
75
- <h3 class="feature-title">Hypermedia Ready</h3>
81
+ <h3><a id="link-feature-hypermedia" href="/docs/hypermedia/" class="feature-title">Hypermedia
82
+ Ready</a></h3>
76
83
  <p class="feature-description">
77
84
  Fetch HTML, vDOM, or Object DOM with the <code>src</code> attribute. HTMX-like patterns for
78
85
  <code>src</code> and <code>href</code> built right
79
86
  in.
80
87
  </p>
81
- </a>
82
- <a href="./components/index.html" class="feature-card" style="text-decoration: none; color: inherit;">
88
+ </div>
89
+ <div class="feature-card">
83
90
  <div class="feature-icon">
84
91
  <svg viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" stroke-width="2">
85
92
  <path d="M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5" />
86
93
  </svg>
87
94
  </div>
88
- <h3 class="feature-title">Component Library</h3>
95
+ <h3><a id="link-feature-components" href="./components/index.html" class="feature-title">Component
96
+ Library</a></h3>
89
97
  <p class="feature-description">
90
98
  Beautiful, accessible components ready to use. Buttons, modals, forms, charts, and more.
91
99
  </p>
92
- </a>
93
- <a href="./getting-started/index.html" class="feature-card" style="text-decoration: none; color: inherit;">
100
+ </div>
101
+ <div class="feature-card">
94
102
  <div class="feature-icon">
95
103
  <svg viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" stroke-width="2">
96
104
  <path
97
105
  d="M14.7 6.3a1 1 0 000 1.4l1.6 1.6a1 1 0 001.4 0l3.77-3.77a6 6 0 01-7.94 7.94l-6.91 6.91a2.12 2.12 0 01-3-3l6.91-6.91a6 6 0 017.94-7.94l-3.76 3.76z" />
98
106
  </svg>
99
107
  </div>
100
- <h3 class="feature-title">Zero Build Step</h3>
108
+ <h3><a id="link-feature-zerobuild" href="./getting-started/index.html" class="feature-title">Zero Build
109
+ Step</a></h3>
101
110
  <p class="feature-description">
102
111
  No bundler required. Drop in a script tag and start building. Works everywhere.
103
112
  </p>
104
- </a>
113
+ </div>
105
114
 
106
115
  </div>
107
116
  </div>
108
117
  </section>
109
118
 
119
+ <!-- AI Catch Section -->
120
+ <section class="section" id="ai-safe">
121
+ <div class="section-content"
122
+ style="background: linear-gradient(135deg, #1a1c2c 0%, #4a1942 100%); color: white; border-radius: 2rem; padding: 4rem 2rem; border: 1px solid rgba(255, 255, 255, 0.1); box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.5); position: relative; overflow: hidden;">
123
+ <!-- Glowing background elements -->
124
+ <div
125
+ style="position: absolute; top: -20%; left: -10%; width: 50%; height: 140%; background: radial-gradient(circle, rgba(138, 43, 226, 0.2) 0%, transparent 70%); filter: blur(60px); pointer-events: none;">
126
+ </div>
127
+ <div
128
+ style="position: absolute; bottom: -20%; right: -10%; width: 50%; height: 140%; background: radial-gradient(circle, rgba(255, 20, 147, 0.15) 0%, transparent 70%); filter: blur(60px); pointer-events: none;">
129
+ </div>
110
130
 
131
+ <div style="position: relative; z-index: 1;">
132
+ <div class="section-header">
133
+ <h2 class="section-title" style="color: white; font-size: 2.5rem;">The AI-Safe UI Engine</h2>
134
+ <p class="section-subtitle" style="color: rgba(255, 255, 255, 0.85); max-width: 800px; margin: 0 auto;">
135
+ Lightview's <strong>cDOM</strong> and <strong>JPRX</strong> are purpose-built for the era of
136
+ AI-driven development, providing a safe, standard-based foundation for agentic UI generation.
137
+ </p>
138
+ </div>
139
+
140
+ <div
141
+ style="display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); gap: 2.5rem; margin-top: 3.5rem;">
142
+ <div
143
+ style="background: rgba(255, 255, 255, 0.05); backdrop-filter: blur(12px); border: 1px solid rgba(255, 255, 255, 0.1); border-radius: 1.5rem; padding: 2.5rem; transition: transform 0.3s ease;">
144
+ <div
145
+ style="width: 48px; height: 48px; background: rgba(138, 43, 226, 0.2); border-radius: 12px; display: flex; align-items: center; justify-content: center; margin-bottom: 1.5rem;">
146
+ <svg viewBox="0 0 24 24" width="28" height="28" fill="none" stroke="#a78bfa" stroke-width="2">
147
+ <path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z" />
148
+ </svg>
149
+ </div>
150
+ <h3 style="color: white; font-size: 1.5rem; margin-bottom: 1rem;">Execution Safety</h3>
151
+ <p style="color: rgba(255, 255, 255, 0.75); line-height: 1.6;">AI-generated UIs usually require
152
+ risky JavaScript strings. cDOM creates reactive interfaces using <strong>pure JSON
153
+ data</strong> and <a id="link-ai-safe-cdom-helpers" href="/docs/cdom.html#helpers"
154
+ style="color: #a78bfa; text-decoration: underline; font-weight: 600;">over 50 built-in
155
+ functions</a> that bring spreadsheet-like
156
+ functionality to the DOM. No <code>eval()</code>, no <code>new Function()</code>, and <strong>no
157
+ access to global JavaScript context</strong>. When used in conjunction with <a
158
+ id="link-ai-safe-hypermedia" href="/docs/hypermedia/"
159
+ style="color: #a78bfa; text-decoration: underline; font-weight: 600;">Lightview hypermedia
160
+ support</a>, it strictly limits security exposure.</p>
161
+ </div>
162
+
163
+ <div
164
+ style="background: rgba(255, 255, 255, 0.05); backdrop-filter: blur(12px); border: 1px solid rgba(255, 255, 255, 0.1); border-radius: 1.5rem; padding: 2.5rem; transition: transform 0.3s ease;">
165
+ <div
166
+ style="width: 48px; height: 48px; background: rgba(255, 20, 147, 0.2); border-radius: 12px; display: flex; align-items: center; justify-content: center; margin-bottom: 1.5rem;">
167
+ <svg viewBox="0 0 24 24" width="28" height="28" fill="none" stroke="#fb7185" stroke-width="2">
168
+ <path d="M7 21h10M12 21V3m0 0l-5 5m5-5l5 5" />
169
+ </svg>
170
+ </div>
171
+ <h3 style="color: white; font-size: 1.5rem; margin-bottom: 1rem;">Standards-First Design</h3>
172
+ <p style="color: rgba(255, 255, 255, 0.75); line-height: 1.6;"><a id="link-ai-safe-cdom"
173
+ href="/docs/cdom.html"
174
+ style="color: #fb7185; text-decoration: underline; font-weight: 600;">cDOM</a>
175
+ (Computational DOM) and <a id="link-ai-safe-jprx" href="/docs/cdom.html#JPRX"
176
+ style="color: #fb7185; text-decoration: underline; font-weight: 600;">JPRX</a> (JSON Pointer
177
+ Reactive eXpressions) built based on <a id="link-ai-safe-json-pointers"
178
+ href="https://datatracker.ietf.org/doc/html/rfc6901" target="_blank"
179
+ style="color: #fb7185; text-decoration: underline; font-weight: 600;">JSON
180
+ Pointers</a> (RFC 6901), <a id="link-ai-safe-json-schema" href="https://json-schema.org/"
181
+ target="_blank" style="color: #fb7185; text-decoration: underline; font-weight: 600;">JSON
182
+ Schema</a>, and
183
+ <a id="link-ai-safe-xpath" href="https://www.w3.org/TR/xpath/" target="_blank"
184
+ style="color: #fb7185; text-decoration: underline; font-weight: 600;">XPath</a>. AI agents
185
+ describe complex relationships through proven standards and path languages, not imperative
186
+ logic.
187
+ </p>
188
+ </div>
189
+
190
+ <div
191
+ style="background: rgba(255, 255, 255, 0.05); backdrop-filter: blur(12px); border: 1px solid rgba(255, 255, 255, 0.1); border-radius: 1.5rem; padding: 2.5rem; transition: transform 0.3s ease;">
192
+ <div
193
+ style="width: 48px; height: 48px; background: rgba(56, 189, 248, 0.2); border-radius: 12px; display: flex; align-items: center; justify-content: center; margin-bottom: 1.5rem;">
194
+ <svg viewBox="0 0 24 24" width="28" height="28" fill="none" stroke="#38bdf8" stroke-width="2">
195
+ <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path>
196
+ <polyline points="14 2 14 8 20 8"></polyline>
197
+ <line x1="16" y1="13" x2="8" y2="13"></line>
198
+ <line x1="16" y1="17" x2="8" y2="17"></line>
199
+ <polyline points="10 9 9 9 8 9"></polyline>
200
+ </svg>
201
+ </div>
202
+ <h3 style="color: white; font-size: 1.5rem; margin-bottom: 1rem;">Context for Agents</h3>
203
+ <p style="color: rgba(255, 255, 255, 0.75); line-height: 1.6;">
204
+ Accelerate development by pointing your AI assistant to the
205
+ <a id="link-ai-safe-guidance" href="/AI-GUIDANCE.md" target="_blank"
206
+ style="color: #38bdf8; text-decoration: underline; font-weight: 600;">AI Guidance
207
+ Manual</a>.
208
+ A definitive implementation guide optimized for LLM consumption.
209
+ </p>
210
+ </div>
211
+ </div>
212
+
213
+ <div style="text-align: center; margin-top: 4rem;">
214
+ <a id="link-ai-safe-cta" href="/docs/cdom.html" class="btn btn-primary btn-lg"
215
+ style="background: white; color: #1a1c2c; border: none; font-weight: 600;">
216
+ Unleash the Power of cDOM
217
+ </a>
218
+ </div>
219
+ </div>
220
+ </div>
221
+ </section>
111
222
 
112
- <!-- Call to Action -->
113
223
  <section class="section">
114
224
  <div class="section-content">
115
225
  <div class="section-header">
@@ -119,7 +229,7 @@
119
229
  </p>
120
230
  </div>
121
231
  <div style="text-align: center;">
122
- <a href="/docs/getting-started/" class="btn btn-primary btn-lg">Enlighten Your UI</a>
232
+ <a id="link-footer-cta" href="/docs/getting-started/" class="btn btn-primary btn-lg">Enlighten Your UI</a>
123
233
  </div>
124
234
  </div>
125
235
  </section>