-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy patheditor.html
More file actions
447 lines (434 loc) · 32.8 KB
/
Copy patheditor.html
File metadata and controls
447 lines (434 loc) · 32.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="I built Nodes as a private place to draw program logic, connect each step, and turn a finished flow into code or a clean export.">
<meta name="author" content="@dev.mako (devkyato)">
<meta name="keywords" content="flowchart creator, flowchart maker, diagram editor, SVG flowchart, process diagram, free flowchart tool, browser diagram editor">
<meta name="robots" content="index, follow, max-image-preview:large">
<meta id="theme-color" name="theme-color" content="#f7f8fa">
<meta name="application-name" content="Flowchart Creator">
<link rel="canonical" href="https://nodesss.xyz/">
<meta property="og:type" content="website">
<meta property="og:site_name" content="Flowchart Creator">
<meta property="og:title" content="Nodes — a flowchart tool by @dev.mako">
<meta property="og:description" content="A personal browser-based editor for drawing clear program logic and turning it into usable code.">
<meta property="og:url" content="https://nodesss.xyz/">
<meta property="og:image" content="https://nodesss.xyz/og-release-1.4.png">
<meta property="og:image:width" content="1662">
<meta property="og:image:height" content="946">
<meta property="og:image:alt" content="Flowchart Creator by @dev.mako with a compact editable process diagram">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="Nodes — a flowchart tool by @dev.mako">
<meta name="twitter:description" content="I built this private browser workspace to make program logic easier to see and explain.">
<meta name="twitter:image" content="https://nodesss.xyz/og-release-1.4.png">
<title>Editor · Nodes</title>
<link rel="icon" href="data:,">
<link rel="manifest" href="site.webmanifest">
<link rel="stylesheet" href="flyon.css">
<link rel="stylesheet" href="style.css">
<script>
(() => {
const preference = localStorage.getItem("flowchart-creator-theme") || "system";
const theme = preference === "system"
? (matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light")
: preference;
document.documentElement.dataset.theme = theme;
document.documentElement.dataset.themePreference = preference;
})();
</script>
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "SoftwareApplication",
"name": "Flowchart Creator",
"url": "https://nodesss.xyz/",
"description": "A compact, dependency-free SVG flowchart editor for creating, saving, and exporting process diagrams.",
"applicationCategory": "DesignApplication",
"operatingSystem": "Any modern web browser",
"isAccessibleForFree": true,
"author": {
"@type": "Person",
"name": "@dev.mako",
"url": "https://github.com/devkyato"
},
"license": "https://opensource.org/license/mit"
}
</script>
</head>
<body>
<div id="app">
<header class="toolbar" aria-label="Editor toolbar">
<a class="brand-mark" href="./" aria-label="Back to your flowcharts" title="Back to your flowcharts">
<span class="brand-word">nodes<span class="brand-cursor">_</span></span>
</a>
<input id="document-title" class="document-title input input-sm" value="Untitled Flowchart" aria-label="Document title" title="Name your flowchart">
<span class="toolbar-separator"></span>
<div class="tool-group" aria-label="History">
<button type="button" class="btn btn-sm btn-text btn-square" data-action="undo" title="Undo (Ctrl+Z)" aria-label="Undo">↶</button>
<button type="button" class="btn btn-sm btn-text btn-square" data-action="redo" title="Redo (Ctrl+Shift+Z)" aria-label="Redo">↷</button>
</div>
<div class="tool-group tool-pills" aria-label="Tools">
<button type="button" class="tool-button btn btn-sm btn-soft active" data-mode="select" title="Select tool (V)">↖ Select</button>
<button type="button" class="tool-button btn btn-sm btn-text" data-mode="connect" title="Connector tool (C)">⤴ Connect</button>
<button type="button" class="tool-button btn btn-sm btn-text" data-mode="text" title="Text tool (T)">✎ Text</button>
</div>
<div class="tool-group pan-tool-group">
<button type="button" class="tool-button btn btn-sm btn-text" data-mode="pan" title="Hand tool (H)">Pan</button>
</div>
<div class="premium-toolbar-actions" aria-label="Editor actions">
<button type="button" class="topbar-action code-studio-action" data-inspector-open="code" aria-controls="code-sidebar" aria-expanded="false" title="Open code workspace">Code</button>
<button type="button" class="topbar-action save-action" data-action="save" title="Save checkpoint (Ctrl+S)" aria-label="Save checkpoint">Save</button>
<details class="native-menu">
<summary id="arrange-native">Arrange</summary>
<div class="native-menu-panel arrange-panel" role="menu" aria-labelledby="arrange-native">
<span class="native-menu-label">Align</span>
<div class="native-action-grid"><button data-arrange="left">Left</button><button data-arrange="center">Center</button><button data-arrange="right">Right</button><button data-arrange="top">Top</button><button data-arrange="middle">Middle</button><button data-arrange="bottom">Bottom</button></div>
<span class="native-menu-label">Selection</span>
<button data-panel-action="group">Group selection</button><button data-panel-action="ungroup">Ungroup</button><button data-panel-action="front">Bring to front</button><button data-panel-action="back">Send to back</button>
</div>
</details>
<details class="native-menu">
<summary id="view-native">View <span id="native-zoom-display">100%</span></summary>
<div class="native-menu-panel" role="menu" aria-labelledby="view-native">
<div class="native-zoom-row"><button data-action="zoom-out">−</button><button data-action="zoom-reset">100%</button><button data-action="zoom-in">+</button></div>
<button data-action="fit">Fit diagram</button><button data-view-action="grid">Toggle grid</button><button data-view-action="snap">Toggle snap</button>
</div>
</details>
<details class="native-menu">
<summary id="export-native">Export</summary>
<div class="native-menu-panel export-panel" role="menu" aria-labelledby="export-native">
<span class="native-menu-label">Project</span>
<button data-action="download-json">Download JSON <small>Editable backup</small></button><button data-action="download-xml">Download XML <small>Structured project</small></button><button data-action="import-project">Import project</button>
<span class="native-menu-label">Image</span>
<button data-action="export-svg">Export SVG <small>Vector quality</small></button><button data-action="export-png">Export PNG <small>High resolution</small></button>
</div>
</details>
<details class="native-menu appearance-menu">
<summary aria-label="Appearance">◐</summary>
<div class="native-menu-panel" role="menu"><button data-theme-value="light">☀ Light</button><button data-theme-value="dark">◒ Dark</button><button data-theme-value="system">◐ System</button></div>
</details>
<button type="button" class="topbar-icon" title="Settings" aria-label="Settings" data-overlay="#settings-modal">⚙</button>
</div>
<div class="toolbar-spacer"></div>
<div class="toolbar-actions" aria-label="Workspace actions">
<div class="dropdown relative inline-flex">
<button id="arrange-menu" type="button" class="dropdown-toggle btn btn-sm btn-text" aria-haspopup="menu" aria-controls="arrange-dropdown" aria-expanded="false">Arrange <span class="menu-caret">⌄</span></button>
<ul id="arrange-dropdown" class="dropdown-menu compact-menu dropdown-open:opacity-100 hidden min-w-56" role="menu" aria-orientation="vertical" aria-labelledby="arrange-menu">
<li class="dropdown-title">Align selection</li>
<li class="menu-grid menu-grid-3">
<button type="button" data-arrange="left" title="Align left">⇤</button>
<button type="button" data-arrange="center" title="Align center">↔</button>
<button type="button" data-arrange="right" title="Align right">⇥</button>
<button type="button" data-arrange="top" title="Align top">⤒</button>
<button type="button" data-arrange="middle" title="Align middle">↕</button>
<button type="button" data-arrange="bottom" title="Align bottom">⤓</button>
</li>
<li class="menu-divider"></li>
<li class="dropdown-title">Distribute & group</li>
<li class="menu-grid menu-grid-2">
<button type="button" data-arrange="horizontal">Horizontal</button>
<button type="button" data-arrange="vertical">Vertical</button>
<button type="button" data-panel-action="group">Group</button>
<button type="button" data-panel-action="ungroup">Ungroup</button>
</li>
<li class="menu-divider"></li>
<li class="menu-grid menu-grid-2">
<button type="button" data-panel-action="front">Bring front</button>
<button type="button" data-panel-action="forward">Forward</button>
<button type="button" data-panel-action="backward">Backward</button>
<button type="button" data-panel-action="back">Send back</button>
</li>
</ul>
</div>
<div class="dropdown relative inline-flex [--auto-close:inside]">
<button id="view-menu" type="button" class="dropdown-toggle btn btn-sm btn-text" aria-haspopup="menu" aria-controls="view-dropdown" aria-expanded="false">View <span id="zoom-display">100%</span> <span class="menu-caret">⌄</span></button>
<ul id="view-dropdown" class="dropdown-menu compact-menu dropdown-open:opacity-100 hidden min-w-52" role="menu" aria-orientation="vertical" aria-labelledby="view-menu">
<li class="dropdown-title">Canvas</li>
<li class="zoom-strip">
<button type="button" data-action="zoom-out" title="Zoom out">−</button>
<button type="button" data-action="zoom-reset" title="Reset zoom">100%</button>
<button type="button" data-action="zoom-in" title="Zoom in">+</button>
</li>
<li><button type="button" class="dropdown-item compact-item" data-action="fit"><span>⊡</span><span><strong>Fit diagram</strong><small>Show the full flow</small></span></button></li>
<li class="menu-divider"></li>
<li><button type="button" class="dropdown-item compact-item view-choice" data-view-action="grid"><span>#</span><span>Grid</span><span class="view-check">✓</span></button></li>
<li><button type="button" class="dropdown-item compact-item view-choice" data-view-action="snap"><span>⌁</span><span>Snap to grid</span><span class="view-check">✓</span></button></li>
</ul>
</div>
<div class="dropdown relative inline-flex">
<button id="project-menu" type="button" class="dropdown-toggle btn btn-sm btn-text" aria-haspopup="menu" aria-controls="project-dropdown" aria-expanded="false">File <span class="menu-caret">⌄</span></button>
<ul id="project-dropdown" class="dropdown-menu dropdown-open:opacity-100 hidden min-w-64" role="menu" aria-orientation="vertical" aria-labelledby="project-menu">
<li class="dropdown-title">Your local workspace</li>
<li><button type="button" class="dropdown-item" data-action="save"><span>💾</span><span><strong>Save checkpoint</strong><small>Keep a named copy in this browser</small></span></button></li>
<li><button type="button" class="dropdown-item" data-action="load"><span>📂</span><span><strong>Load checkpoint</strong><small>Restore your last manual save</small></span></button></li>
<li class="menu-divider"></li>
<li><button type="button" class="dropdown-item" data-action="download-json"><span>{ }</span><span><strong>Download JSON</strong><small>Portable project source</small></span></button></li>
<li><button type="button" class="dropdown-item" data-action="download-xml"><span></></span><span><strong>Download XML</strong><small>Structured interoperable project</small></span></button></li>
<li><button type="button" class="dropdown-item" data-action="import-project"><span>↥</span><span><strong>Import project</strong><small>Open JSON or XML</small></span></button></li>
<li class="menu-divider"></li>
<li class="dropdown-title">Export image</li>
<li><button type="button" class="dropdown-item" data-action="export-svg"><span>◇</span><span><strong>Vector SVG</strong><small>Sharp at every size</small></span></button></li>
<li><button type="button" class="dropdown-item" data-action="export-png"><span>▣</span><span><strong>High-res PNG</strong><small>Crisp transparent-safe image</small></span></button></li>
<li class="menu-divider"></li>
<li><button type="button" class="dropdown-item danger-item" title="Clear canvas" aria-haspopup="dialog" aria-expanded="false" aria-controls="clear-canvas-modal" data-overlay="#clear-canvas-modal"><span>×</span><span><strong>Clear canvas</strong><small>Start fresh; Undo remains available</small></span></button></li>
</ul>
</div>
<div class="dropdown relative inline-flex [--auto-close:inside]">
<button id="theme-toggle" type="button" class="dropdown-toggle btn btn-sm btn-text" aria-haspopup="menu" aria-controls="theme-dropdown" aria-expanded="false" aria-label="Appearance options"><span id="theme-icon">◐</span><span id="theme-label">System</span><span class="menu-caret">⌄</span></button>
<ul id="theme-dropdown" class="dropdown-menu dropdown-open:opacity-100 hidden min-w-48" role="menu" aria-orientation="vertical" aria-labelledby="theme-toggle">
<li class="dropdown-title">Appearance</li>
<li><button type="button" class="dropdown-item theme-choice" data-theme-value="light"><span>☀</span><span>Light</span><span class="theme-check">✓</span></button></li>
<li><button type="button" class="dropdown-item theme-choice" data-theme-value="dark"><span>◒</span><span>Dark</span><span class="theme-check">✓</span></button></li>
<li><button type="button" class="dropdown-item theme-choice" data-theme-value="system"><span>◐</span><span>System</span><span class="theme-check">✓</span></button></li>
</ul>
</div>
<button type="button" class="btn btn-sm btn-text command-trigger" title="Command menu (Ctrl+K)" aria-label="Open command menu" aria-haspopup="dialog" aria-expanded="false" aria-controls="command-modal" data-overlay="#command-modal">⌘K</button>
<button type="button" class="btn btn-sm btn-text btn-square" title="Settings" aria-label="Settings" aria-haspopup="dialog" aria-expanded="false" aria-controls="settings-modal" data-overlay="#settings-modal">⚙</button>
<button type="button" class="btn btn-sm btn-text btn-square" title="Keyboard shortcuts" aria-label="Keyboard shortcuts" aria-haspopup="dialog" aria-expanded="false" aria-controls="shortcuts-modal" data-overlay="#shortcuts-modal">?</button>
</div>
<input id="file-input" type="file" accept="application/json,application/xml,text/xml,.json,.xml" hidden>
</header>
<aside class="shape-panel" aria-label="Flowchart shapes">
<div class="panel-heading">
<span>Shapes</span>
<label class="snap-toggle" title="Snap objects to the grid">
<input id="snap-toggle" type="checkbox" checked> Snap
</label>
</div>
<label class="shape-search">
<span aria-hidden="true">⌕</span>
<input id="shape-search" type="search" placeholder="Find a shape…" autocomplete="off" aria-label="Find a shape">
</label>
<div id="shape-list" class="shape-list"></div>
</aside>
<main id="canvas-shell" class="canvas-shell" tabindex="0" aria-label="Flowchart canvas">
<svg id="canvas" xmlns="http://www.w3.org/2000/svg" role="application" aria-label="Diagram editing canvas">
<defs>
<pattern id="small-grid" width="20" height="20" patternUnits="userSpaceOnUse">
<path d="M 20 0 L 0 0 0 20" fill="none" stroke="#e8ebef" stroke-width="1" vector-effect="non-scaling-stroke"></path>
</pattern>
<pattern id="major-grid" width="100" height="100" patternUnits="userSpaceOnUse">
<path d="M 100 0 L 0 0 0 100" fill="none" stroke-width="1.25" vector-effect="non-scaling-stroke"></path>
</pattern>
<pattern id="page-grid" width="794" height="1123" patternUnits="userSpaceOnUse">
<rect x="0.5" y="0.5" width="793" height="1122" fill="none" stroke="currentColor" stroke-width="1" vector-effect="non-scaling-stroke"></rect>
</pattern>
<marker id="arrow-end" markerWidth="10" markerHeight="10" refX="8" refY="3" orient="auto" markerUnits="strokeWidth">
<path d="M0,0 L0,6 L9,3 z" fill="context-stroke"></path>
</marker>
<marker id="arrow-start" markerWidth="10" markerHeight="10" refX="1" refY="3" orient="auto-start-reverse" markerUnits="strokeWidth">
<path d="M9,0 L9,6 L0,3 z" fill="context-stroke"></path>
</marker>
<marker id="circle-end" markerWidth="8" markerHeight="8" refX="4" refY="4" orient="auto" markerUnits="strokeWidth">
<circle cx="4" cy="4" r="2.5" fill="context-stroke"></circle>
</marker>
<marker id="diamond-end" markerWidth="10" markerHeight="10" refX="8" refY="4" orient="auto" markerUnits="strokeWidth">
<path d="M0,4 L4,0 L8,4 L4,8 z" fill="context-stroke"></path>
</marker>
</defs>
<g id="viewport">
<rect class="workspace-bg" x="0" y="0" width="794" height="1123"></rect>
<rect class="grid" x="0" y="0" width="794" height="1123"></rect>
<rect class="major-grid" x="0" y="0" width="794" height="1123"></rect>
<rect class="page-grid" x="0" y="0" width="794" height="1123"></rect>
<g id="edge-layer"></g>
<g id="node-layer"></g>
<g id="overlay-layer"></g>
</g>
</svg>
<textarea id="inline-editor" class="inline-editor" aria-label="Edit text" spellcheck="true"></textarea>
<div id="context-toolbar" class="context-toolbar" role="toolbar" aria-label="Selection quick actions" hidden>
<span class="context-grip" aria-hidden="true">✥</span>
<button type="button" data-context-action="edit" title="Edit text (Enter)">✎ <span>Edit</span></button>
<button type="button" data-context-action="duplicate" title="Duplicate (Ctrl+D)">⧉ <span>Copy</span></button>
<button type="button" data-context-action="lock" title="Lock shape">♢ <span>Lock</span></button>
<button type="button" data-context-action="delete" class="context-danger" title="Delete">×</button>
</div>
</main>
<aside id="properties-panel" class="properties-panel premium-inspector" aria-label="Design inspector">
<div class="inspector-tabs" role="tablist" aria-label="Inspector workspace">
<button type="button" class="active" role="tab" aria-selected="true" data-inspector-tab="design" title="Design inspector">◇ <span>Design</span></button>
<button type="button" role="tab" aria-selected="false" data-inspector-tab="code" title="Code workspace"></> <span>Code</span></button>
</div>
<div class="panel-heading"><span id="properties-title">Design</span><span class="inspector-badge">Local</span></div>
<div id="properties-content" class="properties-content"></div>
<div id="code-sidebar" class="code-sidebar hidden" aria-label="Code workspace"></div>
</aside>
<footer class="statusbar">
<span id="status-text" aria-live="polite">Ready · H to pan · Ctrl + wheel to zoom</span>
<span id="selection-status">0 selected</span>
<span id="canvas-size-status">1 A4 page</span>
</footer>
</div>
<div id="clear-canvas-modal" class="overlay modal overlay-open:opacity-100 overlay-open:duration-300 hidden" role="dialog" tabindex="-1" aria-labelledby="clear-canvas-title">
<div class="modal-dialog overlay-open:mt-12 overlay-open:duration-300 transition-all ease-out">
<div class="modal-content premium-modal">
<div class="modal-header">
<div>
<span class="modal-kicker">Destructive action</span>
<h2 id="clear-canvas-title" class="modal-title">Clear this canvas?</h2>
</div>
<button type="button" class="btn btn-text btn-circle btn-sm" aria-label="Close" data-overlay="#clear-canvas-modal">×</button>
</div>
<div class="modal-body">
<p>Your current shapes and connectors will be removed. You can still use Undo immediately afterward.</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-sm btn-soft" data-overlay="#clear-canvas-modal">Keep editing</button>
<button type="button" class="btn btn-sm btn-error" data-confirm-clear data-overlay="#clear-canvas-modal">Clear canvas</button>
</div>
</div>
</div>
</div>
<div id="shortcuts-modal" class="overlay modal overlay-open:opacity-100 overlay-open:duration-300 hidden" role="dialog" tabindex="-1" aria-labelledby="shortcuts-title">
<div class="modal-dialog overlay-open:mt-12 overlay-open:duration-300 transition-all ease-out">
<div class="modal-content premium-modal">
<div class="modal-header">
<div>
<span class="modal-kicker">A few shortcuts I use</span>
<h2 id="shortcuts-title" class="modal-title">Keyboard shortcuts</h2>
</div>
<button type="button" class="btn btn-text btn-circle btn-sm" aria-label="Close" data-overlay="#shortcuts-modal">×</button>
</div>
<div class="modal-body shortcut-grid">
<span>Select</span><kbd>V</kbd>
<span>Hand / pan tool</span><kbd>H</kbd>
<span>Connect</span><kbd>C</kbd>
<span>Add text</span><kbd>T</kbd>
<span>Pan canvas</span><kbd>Space + drag</kbd>
<span>Duplicate</span><kbd>Ctrl / ⌘ + D</kbd>
<span>Undo</span><kbd>Ctrl / ⌘ + Z</kbd>
<span>Save checkpoint</span><kbd>Ctrl / ⌘ + S</kbd>
<span>Open Code Studio</span><kbd>Ctrl / ⌘ + Shift + C</kbd>
<span>Nudge precisely</span><kbd>Arrow keys</kbd>
<span>Pan with keys</span><kbd>Shift + Arrow</kbd>
<span>Zoom</span><kbd>+ / -</kbd>
<span>Fit diagram</span><kbd>0</kbd>
<span>Toggle grid</span><kbd>G</kbd>
</div>
<div class="modal-footer">
<span class="modal-note">Tip: double-click any shape or connector label to edit it.</span>
<button type="button" class="btn btn-sm btn-primary" data-overlay="#shortcuts-modal">Got it</button>
</div>
</div>
</div>
</div>
<div id="settings-modal" class="overlay modal overlay-open:opacity-100 overlay-open:duration-300 hidden" role="dialog" tabindex="-1" aria-labelledby="settings-title">
<div class="modal-dialog settings-dialog">
<div class="modal-content premium-modal">
<div class="modal-header">
<div>
<span class="modal-kicker">Make it feel yours</span>
<h2 id="settings-title" class="modal-title">Settings</h2>
</div>
<button type="button" class="btn btn-text btn-circle btn-sm" aria-label="Close settings" data-overlay="#settings-modal">×</button>
</div>
<div class="settings-layout">
<div class="tabs settings-tabs" role="tablist" aria-label="Settings sections">
<button type="button" class="tab active" role="tab" aria-selected="true" data-settings-tab="appearance">✦ Appearance</button>
<button type="button" class="tab" role="tab" aria-selected="false" data-settings-tab="canvas"># Canvas</button>
<button type="button" class="tab" role="tab" aria-selected="false" data-settings-tab="behavior">⌁ Behavior</button>
</div>
<div class="settings-panels">
<section class="settings-panel" data-settings-panel="appearance" role="tabpanel">
<div class="settings-section-heading"><div><strong>Theme</strong><small>I kept light, dark, and system modes so the workspace can match how you work.</small></div><span class="badge badge-soft badge-sm">Live</span></div>
<div class="theme-card-grid" role="radiogroup" aria-label="Color theme">
<button type="button" class="theme-card" data-theme-value="light" role="radio"><span class="theme-preview light-preview"></span><strong>Light</strong><small>Bright studio</small></button>
<button type="button" class="theme-card" data-theme-value="dark" role="radio"><span class="theme-preview dark-preview"></span><strong>Dark</strong><small>Cover-inspired</small></button>
<button type="button" class="theme-card" data-theme-value="system" role="radio"><span class="theme-preview system-preview"></span><strong>System</strong><small>Follow device</small></button>
</div>
<label class="setting-row"><span><strong>Reduce motion</strong><small>Pause shine and ambient movement.</small></span><input id="reduced-motion-toggle" type="checkbox" class="switch switch-sm switch-primary" role="switch"></label>
</section>
<section class="settings-panel" data-settings-panel="canvas" role="tabpanel" hidden>
<label class="setting-row"><span><strong>Show grid</strong><small>Display the alignment grid on the page.</small></span><input id="settings-grid-toggle" type="checkbox" class="switch switch-sm switch-primary" role="switch"></label>
<label class="setting-row"><span><strong>Snap to grid</strong><small>Keep shapes aligned while moving.</small></span><input id="settings-snap-toggle" type="checkbox" class="switch switch-sm switch-primary" role="switch"></label>
<div class="setting-row setting-action"><span><strong>Fit diagram</strong><small>Center everything in the available space.</small></span><button type="button" class="btn btn-sm btn-soft" data-settings-action="fit">Fit now</button></div>
</section>
<section class="settings-panel" data-settings-panel="behavior" role="tabpanel" hidden>
<label class="setting-row"><span><strong>Automatic local drafts</strong><small>Save changes privately in this browser.</small></span><input id="autosave-toggle" type="checkbox" class="switch switch-sm switch-primary" role="switch"></label>
<label class="setting-field"><span><strong>New connector path</strong><small>Default routing for newly drawn connectors.</small></span><select id="default-connector" class="select select-sm"><option value="straight">Straight</option><option value="elbow">Elbow</option><option value="curved">Curved</option></select></label>
<label class="setting-field"><span><strong>New connector end</strong><small>Default marker for newly drawn connectors.</small></span><select id="default-arrow" class="select select-sm"><option value="arrow">Arrow</option><option value="none">None</option><option value="circle">Circle</option><option value="diamond">Diamond</option></select></label>
</section>
</div>
</div>
<div class="modal-footer settings-footer"><span class="modal-note">Settings stay on this device.</span><button type="button" class="btn btn-sm btn-primary" data-overlay="#settings-modal">Done</button></div>
</div>
</div>
</div>
<div id="code-modal" class="overlay modal hidden" role="dialog" tabindex="-1" aria-labelledby="code-title">
<div class="modal-dialog code-dialog">
<div class="modal-content premium-modal code-modal-content">
<div class="modal-header">
<div>
<span class="modal-kicker">Where the logic becomes code</span>
<h2 id="code-title" class="modal-title">Code Studio</h2>
</div>
<button type="button" class="btn btn-text btn-circle btn-sm" aria-label="Close Code Studio" data-overlay="#code-modal">×</button>
</div>
<div class="code-workbench">
<aside class="code-validation" aria-label="Flow validation">
<div class="code-panel-heading"><strong>How the flow reads</strong><button type="button" data-code-action="validate" title="Check flow">Check</button></div>
<div id="code-issues" class="code-issues" aria-live="polite"></div>
<div class="text-flow-builder">
<div class="code-panel-heading"><strong>Flow script</strong><button type="button" data-code-action="load-text" title="Replace this script with the current diagram">Use canvas</button></div>
<textarea id="flow-text-input" spellcheck="false" aria-label="Text flow definition" placeholder="start
ask How many hours?
input hours
set gross_pay = hours * pay_rate
if gross_pay > 1000
display gross_pay
end"></textarea>
<p>Oh! On this part, write one instruction per line. I recognize: start, input, ask, set, if, display, process, document, and end.</p>
<button type="button" class="text-flow-apply" data-code-action="apply-text">Update canvas</button>
</div>
</aside>
<section class="code-preview-panel">
<div class="code-toolbar">
<div class="code-language-tabs" role="tablist" aria-label="Generated language">
<button type="button" class="active" role="tab" aria-selected="true" data-code-language="pseudo">Pseudocode</button>
<button type="button" role="tab" aria-selected="false" data-code-language="python">Python</button>
<button type="button" role="tab" aria-selected="false" data-code-language="cpp">C++</button>
</div>
<span id="code-summary">0 steps</span>
</div>
<pre class="code-output-wrap"><code id="code-output"></code></pre>
</section>
</div>
<div class="modal-footer code-footer">
<span class="modal-note">I generate this as a state machine so branches and loops still make sense when you run the code.</span>
<button type="button" class="btn btn-sm btn-soft" data-code-action="copy">Copy code</button>
<button type="button" class="btn btn-sm btn-primary" data-code-action="download">Download</button>
</div>
</div>
</div>
</div>
<div id="command-modal" class="overlay modal command-overlay hidden" role="dialog" tabindex="-1" aria-labelledby="command-title">
<div class="modal-dialog command-dialog">
<div class="modal-content premium-modal">
<div class="command-search-wrap">
<span aria-hidden="true">⌕</span>
<input id="command-search" class="input" type="search" placeholder="Type a command…" autocomplete="off" aria-labelledby="command-title">
<kbd>Esc</kbd>
</div>
<h2 id="command-title" class="sr-only">Command menu</h2>
<div id="command-list" class="command-list" role="listbox" aria-label="Editor commands">
<button type="button" data-command-action="save"><span>💾</span><span><strong>Save checkpoint</strong><small>Project</small></span><kbd>Ctrl S</kbd></button>
<button type="button" data-command-action="fit"><span>⊡</span><span><strong>Fit diagram</strong><small>View</small></span></button>
<button type="button" data-command-mode="select"><span>↖</span><span><strong>Select tool</strong><small>Tools</small></span><kbd>V</kbd></button>
<button type="button" data-command-mode="pan"><span>✋</span><span><strong>Pan canvas</strong><small>Tools</small></span><kbd>H</kbd></button>
<button type="button" data-command-mode="connect"><span>⤴</span><span><strong>Connector tool</strong><small>Tools</small></span><kbd>C</kbd></button>
<button type="button" data-command-mode="text"><span>✎</span><span><strong>Text tool</strong><small>Tools</small></span><kbd>T</kbd></button>
<button type="button" data-command-code><span></></span><span><strong>Open Code Studio</strong><small>Developer</small></span></button>
<button type="button" data-command-action="export-svg"><span>◇</span><span><strong>Export SVG</strong><small>File</small></span></button>
<button type="button" data-command-settings><span>⚙</span><span><strong>Open settings</strong><small>Workspace</small></span></button>
</div>
<div class="command-footer"><span><kbd>↑</kbd> <kbd>↓</kbd> Navigate</span><span><kbd>Enter</kbd> Run</span></div>
</div>
</div>
</div>
<div id="toast-region" class="toast-stack" role="region" aria-label="Notifications" aria-live="polite"></div>
<script src="script.js"></script>
</body>
</html>