Mercurial
comparison mrjunejune/src/public/component-sandbox.html @ 273:e02e2036ef84 default tip
add Layer 2 JRPG component system
Add reusable content and window modals, an isolated component sandbox, shared cyberpunk scroll areas, production-safe cache freshness, and server-rendered JRPG panel state.
Co-authored-by: Copilot <[email protected]>
| author | MrJuneJune <me@mrjunejune.com> |
|---|---|
| date | Sat, 08 Aug 2026 02:08:08 -0700 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 272:41a49c29a28f | 273:e02e2036ef84 |
|---|---|
| 1 <!doctype html> | |
| 2 <html lang="en" data-zen-theme="cyberpunk"> | |
| 3 <head> | |
| 4 <meta charset="UTF-8"> | |
| 5 <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| 6 <title>AI Component Sandbox | MrJuneJune</title> | |
| 7 <link rel="stylesheet" href="/public/design-system/styles/tokens.css"> | |
| 8 <link rel="stylesheet" href="/public/design-system/styles/themes.css"> | |
| 9 <link rel="stylesheet" href="/public/design-system/styles/components.css"> | |
| 10 <script type="module" src="/public/design-system/components/index.js"></script> | |
| 11 <script type="module"> | |
| 12 const version = Date.now(); | |
| 13 const styles = [ | |
| 14 "/public/mjj-modal.css", | |
| 15 "/public/component-sandbox.css", | |
| 16 ]; | |
| 17 await Promise.all(styles.map(href => new Promise((resolve, reject) => { | |
| 18 const link = document.createElement("link"); | |
| 19 link.rel = "stylesheet"; | |
| 20 link.href = `${href}?sandbox=${version}`; | |
| 21 link.addEventListener("load", resolve, { once: true }); | |
| 22 link.addEventListener("error", reject, { once: true }); | |
| 23 document.head.append(link); | |
| 24 }))); | |
| 25 await import(`/public/mjj-modal.js?sandbox=${version}`); | |
| 26 void navigator.serviceWorker?.getRegistration() | |
| 27 .then(registration => registration?.update()); | |
| 28 </script> | |
| 29 </head> | |
| 30 <body> | |
| 31 <main> | |
| 32 <header class="sandbox-heading"> | |
| 33 <p class="sandbox-muted">Isolated browser fixture</p> | |
| 34 <h1>AI Component Sandbox</h1> | |
| 35 <p> | |
| 36 Edit one component family, refresh this page, and inspect desktop or | |
| 37 mobile behavior without application chrome. | |
| 38 </p> | |
| 39 <dl class="sandbox-layers" aria-label="Component dependency layers"> | |
| 40 <div> | |
| 41 <dt>Layer 0 · Foundation</dt> | |
| 42 <dd>API mapping, i18n, and semantic themes.</dd> | |
| 43 </div> | |
| 44 <div> | |
| 45 <dt>Layer 1 · Primitives</dt> | |
| 46 <dd>Zenbu icons, fields, buttons, and dialog behavior.</dd> | |
| 47 </div> | |
| 48 <div> | |
| 49 <dt>Layer 2 · Composites</dt> | |
| 50 <dd>MrJuneJune composers and modal families.</dd> | |
| 51 </div> | |
| 52 </dl> | |
| 53 <p class="sandbox-rule"> | |
| 54 Dependency rule: Layer 2 may consume Layers 1 and 0. Application | |
| 55 routes, persistence, and business state stay above this sandbox. | |
| 56 </p> | |
| 57 </header> | |
| 58 | |
| 59 <section class="sandbox-grid" aria-label="Modal component variants"> | |
| 60 <article class="sandbox-card"> | |
| 61 <h2>Content modal</h2> | |
| 62 <p> | |
| 63 Editorial reading surface for blogs, notes, release details, and | |
| 64 long-form content. | |
| 65 </p> | |
| 66 <mjj-content-modal data-component-layer="2"> | |
| 67 <zen-dialog> | |
| 68 <zen-button size="md"> | |
| 69 <button type="button" data-zen-trigger> | |
| 70 Open article | |
| 71 <zen-icon name="external"></zen-icon> | |
| 72 </button> | |
| 73 </zen-button> | |
| 74 <dialog> | |
| 75 <header data-modal-header> | |
| 76 <div data-modal-heading> | |
| 77 <p data-modal-kicker>Engineering note · 8 min read</p> | |
| 78 <h2 data-modal-title>Designing durable agent interfaces</h2> | |
| 79 </div> | |
| 80 <div data-modal-header-actions> | |
| 81 <zen-button variant="quiet" size="sm"> | |
| 82 <button type="button" data-zen-close aria-label="Close article"> | |
| 83 <zen-icon name="close"></zen-icon> | |
| 84 </button> | |
| 85 </zen-button> | |
| 86 </div> | |
| 87 </header> | |
| 88 <zen-scroll-area | |
| 89 data-modal-body | |
| 90 data-cyber-scroll | |
| 91 tabindex="0" | |
| 92 aria-label="Article content" | |
| 93 > | |
| 94 <article data-modal-article> | |
| 95 <p data-modal-description> | |
| 96 A content modal should feel like a focused reading room: | |
| 97 enough structure to orient the reader, but no window chrome | |
| 98 competing with the article. | |
| 99 </p> | |
| 100 <h2>Start with a strict shell</h2> | |
| 101 <p> | |
| 102 Header, body, and footer are stable regions. The article | |
| 103 owns its semantic headings, paragraphs, lists, and code. | |
| 104 The modal only supplies rhythm, containment, scrolling, | |
| 105 and depth. | |
| 106 </p> | |
| 107 <blockquote> | |
| 108 Content should remain ordinary HTML even when the | |
| 109 presentation becomes cinematic. | |
| 110 </blockquote> | |
| 111 <h3>Keep the body readable</h3> | |
| 112 <p> | |
| 113 The reading column stays bounded while the dialog itself | |
| 114 can grow. This avoids very long lines on desktop and keeps | |
| 115 padding deliberate on small screens. | |
| 116 </p> | |
| 117 <h3>Use a visible scroll channel</h3> | |
| 118 <p> | |
| 119 Cyan marks the active rail, violet separates the track, | |
| 120 and magenta appears on hover. Keyboard users can focus the | |
| 121 region and scroll without moving the modal chrome. | |
| 122 </p> | |
| 123 <p> | |
| 124 The header and footer stay fixed while this article moves. | |
| 125 That stable frame keeps context visible during longer blog | |
| 126 posts, documentation, and generated explanations. | |
| 127 </p> | |
| 128 <p> | |
| 129 Layer 2 only chooses layout and presentation. The Layer 1 | |
| 130 scroll primitive still owns the native overflow behavior. | |
| 131 </p> | |
| 132 <pre><code><mjj-content-modal> | |
| 133 <header data-modal-header>...</header> | |
| 134 <zen-scroll-area data-modal-body data-cyber-scroll> | |
| 135 ... | |
| 136 </zen-scroll-area> | |
| 137 <footer data-modal-footer>...</footer> | |
| 138 </mjj-content-modal></code></pre> | |
| 139 </article> | |
| 140 </zen-scroll-area> | |
| 141 <footer data-modal-footer> | |
| 142 <p>Updated August 7, 2026</p> | |
| 143 <div data-modal-footer-actions> | |
| 144 <zen-button variant="quiet" size="md"> | |
| 145 <button type="button" data-zen-close>Done reading</button> | |
| 146 </zen-button> | |
| 147 </div> | |
| 148 </footer> | |
| 149 </dialog> | |
| 150 </zen-dialog> | |
| 151 </mjj-content-modal> | |
| 152 </article> | |
| 153 | |
| 154 <article class="sandbox-card"> | |
| 155 <h2>Window modal</h2> | |
| 156 <p> | |
| 157 Structured workspace for tools and multi-region interfaces with | |
| 158 fixed chrome and a bounded scrolling body. | |
| 159 </p> | |
| 160 <mjj-window-modal data-component-layer="2"> | |
| 161 <zen-dialog> | |
| 162 <zen-button size="md"> | |
| 163 <button type="button" data-zen-trigger> | |
| 164 Open workspace | |
| 165 <zen-icon name="external"></zen-icon> | |
| 166 </button> | |
| 167 </zen-button> | |
| 168 <dialog> | |
| 169 <header data-modal-header> | |
| 170 <div data-modal-heading> | |
| 171 <p data-modal-kicker>Workspace · Read only</p> | |
| 172 <h2 data-modal-title>Component inspector</h2> | |
| 173 </div> | |
| 174 <div data-modal-header-actions> | |
| 175 <zen-button variant="quiet" size="sm"> | |
| 176 <button type="button" aria-label="Component settings"> | |
| 177 <zen-icon name="settings"></zen-icon> | |
| 178 </button> | |
| 179 </zen-button> | |
| 180 <zen-button variant="quiet" size="sm"> | |
| 181 <button type="button" data-zen-close aria-label="Close workspace"> | |
| 182 <zen-icon name="close"></zen-icon> | |
| 183 </button> | |
| 184 </zen-button> | |
| 185 </div> | |
| 186 </header> | |
| 187 <zen-scroll-area | |
| 188 data-modal-body | |
| 189 data-modal-layout="split" | |
| 190 data-cyber-scroll | |
| 191 tabindex="0" | |
| 192 aria-label="Workspace content" | |
| 193 > | |
| 194 <zen-scroll-area | |
| 195 data-modal-pane | |
| 196 data-cyber-scroll | |
| 197 tabindex="0" | |
| 198 aria-label="Inspector regions" | |
| 199 > | |
| 200 <aside class="sandbox-pane"> | |
| 201 <h3>Regions</h3> | |
| 202 <ul class="sandbox-list"> | |
| 203 <li>Header</li> | |
| 204 <li>Body</li> | |
| 205 <li>Footer</li> | |
| 206 </ul> | |
| 207 </aside> | |
| 208 </zen-scroll-area> | |
| 209 <zen-scroll-area | |
| 210 data-modal-pane="primary" | |
| 211 data-cyber-scroll | |
| 212 tabindex="0" | |
| 213 aria-label="Inspector body content" | |
| 214 > | |
| 215 <article class="sandbox-pane"> | |
| 216 <h3>Body content</h3> | |
| 217 <p data-modal-description> | |
| 218 The window body can host split panes, editors, previews, | |
| 219 or tools without changing the surrounding contract. | |
| 220 </p> | |
| 221 <zen-field size="md"> | |
| 222 <label for="sandbox-component-name">Component name</label> | |
| 223 <input | |
| 224 id="sandbox-component-name" | |
| 225 value="mjj-window-modal" | |
| 226 readonly | |
| 227 > | |
| 228 <small>The active light-DOM fixture.</small> | |
| 229 </zen-field> | |
| 230 <ol class="sandbox-audit"> | |
| 231 <li><strong>01</strong> Header region validated</li> | |
| 232 <li><strong>02</strong> Title association generated</li> | |
| 233 <li><strong>03</strong> Body region bounded</li> | |
| 234 <li><strong>04</strong> Scroll primitive connected</li> | |
| 235 <li><strong>05</strong> Footer actions discovered</li> | |
| 236 <li><strong>06</strong> Pixel typography inherited</li> | |
| 237 <li><strong>07</strong> Cyberpunk theme resolved</li> | |
| 238 <li><strong>08</strong> Keyboard scrolling enabled</li> | |
| 239 <li><strong>09</strong> Responsive split verified</li> | |
| 240 <li><strong>10</strong> Layer contract ready</li> | |
| 241 </ol> | |
| 242 </article> | |
| 243 </zen-scroll-area> | |
| 244 </zen-scroll-area> | |
| 245 <footer data-modal-footer> | |
| 246 <p>3 required regions · contract valid</p> | |
| 247 <div data-modal-footer-actions> | |
| 248 <zen-button variant="quiet" size="md"> | |
| 249 <button type="button" data-zen-close>Cancel</button> | |
| 250 </zen-button> | |
| 251 <zen-button size="md"> | |
| 252 <button type="button" data-zen-close>Apply</button> | |
| 253 </zen-button> | |
| 254 </div> | |
| 255 </footer> | |
| 256 </dialog> | |
| 257 </zen-dialog> | |
| 258 </mjj-window-modal> | |
| 259 </article> | |
| 260 </section> | |
| 261 </main> | |
| 262 </body> | |
| 263 </html> |