virtual-tree-canvas 0.4.0 → 0.6.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 (94) hide show
  1. package/CHANGELOG.md +42 -0
  2. package/README.md +115 -28
  3. package/docs/icon-catalog.html +67 -0
  4. package/docs/icon-catalog.json +380 -0
  5. package/docs/icon-catalog.md +167 -0
  6. package/examples/generate-tree.js +86 -0
  7. package/examples/reorder-table.html +33 -0
  8. package/examples/units.html +43 -0
  9. package/package.json +7 -3
  10. package/resources/icons/bicycle.svg +1 -0
  11. package/resources/icons/bird.svg +1 -0
  12. package/resources/icons/box.svg +1 -0
  13. package/resources/icons/building.svg +1 -0
  14. package/resources/icons/calendar.svg +1 -0
  15. package/resources/icons/car.svg +1 -0
  16. package/resources/icons/cat.svg +1 -0
  17. package/resources/icons/child.svg +1 -0
  18. package/resources/icons/clock.svg +1 -0
  19. package/resources/icons/cloud.svg +1 -0
  20. package/resources/icons/data-bus.svg +1 -0
  21. package/resources/icons/database.svg +1 -0
  22. package/resources/icons/dog.svg +1 -0
  23. package/resources/icons/drone.svg +1 -0
  24. package/resources/icons/fish.svg +1 -0
  25. package/resources/icons/flower.svg +1 -0
  26. package/resources/icons/fog.svg +1 -0
  27. package/resources/icons/globe.svg +1 -0
  28. package/resources/icons/grip.svg +1 -0
  29. package/resources/icons/heart.svg +1 -0
  30. package/resources/icons/helicopter.svg +1 -0
  31. package/resources/icons/insect.svg +1 -0
  32. package/resources/icons/leaf.svg +1 -0
  33. package/resources/icons/link.svg +1 -0
  34. package/resources/icons/lock.svg +1 -0
  35. package/resources/icons/moon.svg +1 -0
  36. package/resources/icons/network.svg +1 -0
  37. package/resources/icons/people.svg +1 -0
  38. package/resources/icons/person.svg +1 -0
  39. package/resources/icons/pin.svg +1 -0
  40. package/resources/icons/radar.svg +1 -0
  41. package/resources/icons/rain.svg +1 -0
  42. package/resources/icons/seedling.svg +1 -0
  43. package/resources/icons/sensor.svg +1 -0
  44. package/resources/icons/server.svg +1 -0
  45. package/resources/icons/ship.svg +1 -0
  46. package/resources/icons/snow.svg +1 -0
  47. package/resources/icons/star.svg +1 -0
  48. package/resources/icons/storm.svg +1 -0
  49. package/resources/icons/sun.svg +1 -0
  50. package/resources/icons/thermometer.svg +1 -0
  51. package/resources/icons/tree.svg +1 -0
  52. package/resources/icons/wind.svg +1 -0
  53. package/src/assets/icons.js +73 -25
  54. package/src/core/icon-registry.js +6 -8
  55. package/src/core/theme-manager.js +15 -4
  56. package/src/core/tree-column-model.js +16 -3
  57. package/src/core/tree-model.js +20 -0
  58. package/src/core/view-options.js +30 -0
  59. package/src/index.d.ts +166 -5
  60. package/src/index.js +3 -0
  61. package/src/input/index.js +1 -0
  62. package/src/input/row-reorder-input.js +143 -0
  63. package/src/input/tree-filter-bar.js +55 -0
  64. package/src/input/tree-tooltip.js +55 -0
  65. package/src/input/tree-view-input-controller.js +5 -0
  66. package/src/inspector/cell-editor-manager.js +42 -22
  67. package/src/inspector/editor-resolver.js +6 -1
  68. package/src/inspector/numeric-layout.js +16 -0
  69. package/src/renderers/tree-row-renderer.js +79 -13
  70. package/src/tree-view-controller.js +261 -34
  71. package/src/tree-view.js +181 -0
  72. package/src/view/styles.js +14 -0
  73. package/src/assets/icons/air.svg +0 -1
  74. package/src/assets/icons/radar.svg +0 -1
  75. /package/{src/assets → resources}/icons/aircraft.svg +0 -0
  76. /package/{src/assets/icons/bus.svg → resources/icons/bus-vehicle.svg} +0 -0
  77. /package/{src/assets → resources}/icons/control.svg +0 -0
  78. /package/{src/assets → resources}/icons/damage.svg +0 -0
  79. /package/{src/assets → resources}/icons/error.svg +0 -0
  80. /package/{src/assets → resources}/icons/folder.svg +0 -0
  81. /package/{src/assets → resources}/icons/ground.svg +0 -0
  82. /package/{src/assets → resources}/icons/inspector-array.svg +0 -0
  83. /package/{src/assets → resources}/icons/inspector-object.svg +0 -0
  84. /package/{src/assets → resources}/icons/inspector-value.svg +0 -0
  85. /package/{src/assets → resources}/icons/munition.svg +0 -0
  86. /package/{src/assets → resources}/icons/placeholder.svg +0 -0
  87. /package/{src/assets → resources}/icons/point.svg +0 -0
  88. /package/{src/assets → resources}/icons/situation.svg +0 -0
  89. /package/{src/assets → resources}/icons/space.svg +0 -0
  90. /package/{src/assets → resources}/icons/subsurface.svg +0 -0
  91. /package/{src/assets → resources}/icons/surface.svg +0 -0
  92. /package/{src/assets → resources}/icons/task.svg +0 -0
  93. /package/{src/assets → resources}/icons/track.svg +0 -0
  94. /package/{src/assets → resources}/icons/warning.svg +0 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,42 @@
1
+ # Changelog
2
+
3
+ ## 0.6.0 — 2026-09-10
4
+
5
+ ### Added
6
+
7
+ - `TreeView(host, options)` mounts a complete tree or inspector with a canvas, filter, tooltip and editor. Use `configure()` to update its options.
8
+ - Manual row ordering with drag handles, Up/Down buttons, Alt+Arrow shortcuts, edge scrolling and cancellation. `rowreorder` reports changes for applications that save the order.
9
+ - `getRowOrder`, `moveRow`, `moveRowBy` and `setRowReorder` APIs. Manual ordering is available for data rows when filtering and column sorting are inactive.
10
+ - `autoRender`, `TreeTooltip`, configurable `iconsBaseUrl` and application-defined `iconResolver`.
11
+ - `setEditable`, `setInitialExpandDepth`, `setIconResolver`, `setHeaderFilter` and inspector writes by path with optional event suppression.
12
+ - Expanded SVG catalogue with 63 icons. Includes a visual catalogue and examples of units and manual ordering.
13
+
14
+ ### Changed
15
+
16
+ - Built-in SVGs are served from `resources/icons/` and loaded on demand. SVG sources and raster variants are cached.
17
+
18
+ ### Fixed
19
+
20
+ - Changing editability, filter visibility or icons preserves row order, selection and live values.
21
+ - Explicit row dimensions survive theme changes.
22
+ - Explicit data and model setters refresh mutated objects even when their reference is unchanged.
23
+ - Mode and expansion-depth options are applied; `columns: null` restores the current presentation's default columns.
24
+ - Filter controls reflect programmatic changes, including clearing the filter. Header filtering works in readonly tables.
25
+ - Cancelling an editor does not commit its value. Layout changes close editors whose position is no longer valid.
26
+ - Switching from inspector mode to data rows clears inspector-specific columns.
27
+
28
+ ### Migration
29
+
30
+ Applications that bundle the library must serve its resources and configure their public URL:
31
+
32
+ ```js
33
+ const view = new TreeView(host, {
34
+ iconsBaseUrl: '/node_modules/virtual-tree-canvas/resources/icons/'
35
+ });
36
+ ```
37
+
38
+ Update references to `src/assets/icons/` to use `resources/icons/`.
39
+
40
+ Existing `TreeViewController` integrations and explicit render loops remain supported.
41
+ Manual ordering and controller automatic rendering are opt-in. Numeric units and
42
+ display precision remain supported.
package/README.md CHANGED
@@ -19,50 +19,80 @@ grow.
19
19
  - **Easy to style.** Built-in dark, light and tactical themes, type-based styling, and editable SVG icons.
20
20
  - **Ready for inspectors.** Turn plain JavaScript objects into compact editable forms or property tables.
21
21
 
22
+ See [the changelog](./CHANGELOG.md) for the 0.6.0 migration notes and additions.
23
+
22
24
  ## Install
23
25
 
24
26
  ```bash
25
27
  npm install virtual-tree-canvas
26
28
  ```
27
29
 
28
- ## Quick start
30
+ ## Quick start: complete DOM view
29
31
 
30
- ```html
31
- <canvas id="assets-tree"></canvas>
32
- ```
32
+ Give the host an explicit height. `TreeView` mounts its canvas, filter, tooltip
33
+ and editors, observes size changes and schedules rendering itself.
33
34
 
34
- ```css
35
- #assets-tree {
36
- display: block;
37
- width: 100%;
38
- height: 480px;
39
- }
35
+ ```html
36
+ <div id="assets-tree" style="height:480px"></div>
40
37
  ```
41
38
 
42
39
  ```js
43
- import { TreeViewController } from 'virtual-tree-canvas';
40
+ import { TreeView } from 'virtual-tree-canvas';
44
41
 
45
- const tree = new TreeViewController({
46
- canvas: document.querySelector('#assets-tree'),
42
+ const view = new TreeView(document.querySelector('#assets-tree'), {
47
43
  initialExpandDepth: 2,
44
+ rowReorder: true,
45
+ iconsBaseUrl: '/node_modules/virtual-tree-canvas/resources/icons/'
48
46
  });
49
-
50
- tree.setData([
51
- { id: 'fleet', label: 'Fleet', type: 'root' },
52
- { id: 'radar-1', parentId: 'fleet', label: 'Forward radar', type: 'sensor' },
53
- { id: 'track-100', parentId: 'radar-1', label: 'Track T-100', type: 'track' },
47
+ view.setData([
48
+ { id: 'fleet', label: 'Fleet', icon: 'folder' },
49
+ { id: 'radar-1', parentId: 'fleet', label: 'Forward radar', icon: 'radar' },
50
+ { id: 'track-100', parentId: 'radar-1', label: 'Track T-100', icon: 'track' }
54
51
  ]);
52
+ view.setDynamicState([{ id: 'track-100', state: { value: 430 } }]);
53
+ view.configure({ editable: false, rowHeight: 32 });
54
+ view.on('rowreorder', ({ detail }) => console.log(detail.order));
55
+ const tree = view.controller; // optional lower-level operations
56
+ // On permanent unmount: view.destroy();
57
+ ```
55
58
 
56
- tree.setDynamicState([
57
- { id: 'radar-1', state: { status: 0, progress: 0.72 } },
58
- { id: 'track-100', state: { status: 1, value: 430 } },
59
- ]);
59
+ `configure(patch)` batches changes in a microtask. Public operations and reading
60
+ `view.controller` flush pending configuration first; `view.flush()` is also
61
+ available. Editability, theme, filter visibility and icon resolution preserve
62
+ manual order, selection, expansion and live values. `setData` and `setModel`
63
+ explicitly reinstall data even when the same mutated reference is supplied.
64
+
65
+ - `mode`: `tree` (default) or `inspector`; `presentation`: `pane` or `table`.
66
+ - `filterPlacement`: `auto` (bar in tree/pane, first-column header in inspector
67
+ table), `bar` or `header`. Set `filter: false` to hide it. Hiding the control
68
+ preserves its query; call `clearFilter()` to clear the query.
69
+ - `columns: null` restores defaults for the current presentation.
70
+ - Explicit `rowHeight` and `indentWidth` override the theme; configure them as
71
+ `undefined` to resume theme defaults. `initialExpandDepth` applies to future
72
+ data installations; it does not expand or collapse the current tree.
73
+ - `fontFamily: 'inherit'` follows the host font and refreshes after fonts load.
74
+ - `iconsBaseUrl`, `iconRegistry` and `nativeScrollbars` are construction options.
75
+ - `setInspectorValue(path, value, {emit: false})` updates a value without emitting
76
+ `valuechange` or `modelchange`. Normal writes include `source: 'api'`; editor
77
+ writes use `source: 'user'`. Both include the model in their event details.
78
+
79
+ Use `view.configure` for view configuration. Direct controller operations are
80
+ available for interaction state (filtering, selection, sorting, navigation);
81
+ changing data or presentation through the view keeps its configuration coherent.
82
+
83
+ ## Low-level canvas integration
84
+
85
+ Existing applications can keep `TreeViewController` and manage their own DOM:
60
86
 
61
- tree.render();
87
+ ```js
88
+ import { TreeViewController } from 'virtual-tree-canvas';
89
+ const tree = new TreeViewController({ canvas, host, autoRender: true });
90
+ tree.setData(rows);
62
91
  ```
63
92
 
64
- The controller observes the canvas size. Call `tree.render()` from your own
65
- animation loop when the data is live, or after changing data in a static view.
93
+ The controller owns state and editing, including `setEditable`,
94
+ `setInspectorValue`, `closeEditor` and layout precedence. With `autoRender`
95
+ omitted, use your existing explicit `tree.render()` loop.
66
96
 
67
97
  ![Virtual tree-table with status, progress and SVG icons](./docs/tree-demo.png)
68
98
 
@@ -166,11 +196,24 @@ tree.setTheme({
166
196
  });
167
197
  ```
168
198
 
169
- Built-in icons are editable SVG files in [`src/assets/icons`](./src/assets/icons).
170
- They are preloaded and rasterized once per icon, colour, CSS size and device
199
+ Built-in icons are editable SVG files in [`resources/icons`](./resources/icons).
200
+ They are loaded on demand and rasterized once per icon, colour, CSS size and device
171
201
  pixel ratio. Rendering rows then uses a cached `drawImage`, not SVG parsing or
172
202
  path drawing.
173
203
 
204
+ When bundling the library, configure the public directory containing its built-in SVGs:
205
+
206
+ ```js
207
+ const tree = new TreeViewController({
208
+ canvas,
209
+ iconsBaseUrl: '/node_modules/virtual-tree-canvas/resources/icons/'
210
+ });
211
+ ```
212
+
213
+ `iconsBaseUrl` also works with `new IconRegistry({ iconsBaseUrl })`. It accepts an absolute URL (including a CDN), a root-relative path, or a document-relative path. A trailing slash is optional. Supply it when constructing the controller or registry, before built-in icons begin loading. A custom `iconRegistry` takes precedence over the controller's `iconsBaseUrl`.
214
+
215
+ Without this option, unbundled modules load the icons from the package's `resources/icons/` directory. Publish that directory alongside the package; the bundler does not need to extract or rename its SVGs.
216
+
174
217
  Register application icons from an SVG URL, inline SVG or an image:
175
218
 
176
219
  ```js
@@ -197,7 +240,7 @@ tree.setModel(
197
240
  {
198
241
  'sensor.range': { min: 0, max: 120, step: 1, integer: true },
199
242
  'sensor.mode': { options: { Search: 'search', Track: 'track' } },
200
- 'tracks.*.speed': { min: 0, max: 900, step: 5 },
243
+ 'tracks.*.speed': { min: 0, max: 900, step: 5, unit: 'm/s', precision: 2 },
201
244
  'tracks.*.id': { readonly: true },
202
245
  },
203
246
  { presentation: 'pane', flatRoot: true },
@@ -209,6 +252,15 @@ Choose `presentation: 'pane'` for a compact folder-and-controls view, or
209
252
  Editors are inferred from data and metadata: checkbox, range, number, text,
210
253
  select, colour, button, object and array.
211
254
 
255
+ Numeric metadata supports `unit` (a display-only string suffix) and `precision`
256
+ (decimal places, 0–20). The unit has a reserved slot beside the number in both
257
+ pane and table presentations, including range sliders. It stays visible while
258
+ editing; the editor receives the full original numeric value and emits a number.
259
+ Precision changes display only, not stored values, limits or step size. Omit both
260
+ options to keep the existing formatting. Invalid precision values are ignored.
261
+ Customize the suffix with `theme.unitFont` and `theme.colors.unit` (defaults to
262
+ `textMuted`). Long units are truncated to fit the available cell width.
263
+
212
264
  Listen for user edits and actions with `valuechange`, `modelchange` and
213
265
  `action` events.
214
266
 
@@ -273,3 +325,38 @@ Open <http://localhost:4173/demo/> for the large-tree benchmark, or
273
325
  ```bash
274
326
  npm test
275
327
  ```
328
+
329
+ ## Manual row order
330
+
331
+ `rowReorder: true` adds a dedicated handle and Up/Down controls to a data table. Dragging commits only on drop; Escape or dropping outside cancels. Alt+Up / Alt+Down moves the focused row. Edge scrolling works while dragging.
332
+
333
+ ```js
334
+ const tree = new TreeViewController({
335
+ canvas, host,
336
+ iconsBaseUrl: '/node_modules/virtual-tree-canvas/resources/icons/',
337
+ rowReorder: true,
338
+ autoRender: true,
339
+ tooltip: true,
340
+ columns: [
341
+ { id: 'name', kind: 'tree', label: 'Property', width: 300 },
342
+ { id: 'value', label: 'Value', width: 120, value: (_node, state) => state.value }
343
+ ]
344
+ });
345
+ tree.setData(favoriteRows);
346
+ tree.on('rowreorder', ({ detail }) => saveOrder(detail.order));
347
+ ```
348
+
349
+ - `moveRow(id, targetIndex)` uses a zero-based index among siblings. `moveRowBy(id, offset)` and `getRowOrder(parentId = null)` are also available.
350
+ - Reordering preserves IDs, parent relationships, expansion, selected IDs and live dynamic state. `setDynamicState()` does not change order. `setData()` intentionally installs the order supplied by the host; restore a saved order before calling it.
351
+ - Reordering is disabled during sorting/filtering and for object-inspector models (`setModel`). It does not reorder JavaScript object properties or mutate inspected arrays. Use data rows (`setData`) for favorites, with stable IDs and dynamic value columns.
352
+ - The `rowreorder` detail contains `nodeId`, `parentId`, `fromIndex`, `toIndex`, `siblingOrder`, `order` and `source`. The host owns persistence and live subscriptions. One row is moved at a time, including its subtree, without reparenting.
353
+ - The order column is fixed at 72 CSS px (three 24 px targets) and cannot be sorted, resized or moved. The mode can be toggled with `setRowReorder(enabled)`. Sticky ancestor rows are omitted in this mode.
354
+ - `autoRender` coalesces rendering into an animation frame and cancels pending work on `destroy()`. It is opt-in so existing hosts with their own render loop continue to work.
355
+ - `tooltip: true` creates a reusable tooltip in `host` (or the canvas parent). The host must provide a positioned container. `attachTooltip({ host })` is also available.
356
+ - `setData(nodes, { iconResolver })` allows host-independent visual mapping without mutating the input nodes.
357
+
358
+ Open [the reorder demo](./examples/reorder-table.html) through a local HTTP server to try a table with live values. The demo's localStorage is illustrative; the library never persists user data itself.
359
+
360
+ ## Icon catalogue
361
+
362
+ 63 SVGs are included, with a [visual sheet](./docs/icon-catalog.html) and a [reference of available icons](./docs/icon-catalog.md). `builtinIconNames` exposes available IDs.
@@ -0,0 +1,67 @@
1
+ <!doctype html><html lang="es"><meta charset="utf-8"><meta name="viewport" content="width=device-width"><title>Catálogo de iconos · virtual-tree-canvas</title>
2
+ <style>body{font:15px system-ui;margin:32px;background:#0f172a;color:#e2e8f0}body.light{background:#f8fafc;color:#162033}h1{font-size:26px}header{display:flex;gap:12px;align-items:center;flex-wrap:wrap;margin:24px 0}input,button,select{font:inherit;padding:9px;border:1px solid #64748b;border-radius:6px;background:transparent;color:inherit}main{display:grid;grid-template-columns:repeat(auto-fill,minmax(155px,1fr));gap:12px}article{border:1px solid #64748b55;border-radius:9px;display:flex;flex-direction:column;gap:6px;padding:16px;min-height:118px}article[hidden]{display:none}.glyph{height:40px;display:flex;align-items:center;color:#38bdf8}body.light .glyph{color:#0369a1}svg{width:var(--icon-size,24px);height:var(--icon-size,24px)}small{font-size:11px;opacity:.75}code{font-size:12px}p{max-width:850px;line-height:1.5}option{color:#162033}</style>
3
+ <h1>Iconos · virtual-tree-canvas</h1><p>63 SVG disponibles. Bus de datos y autobús son símbolos diferentes. Prueba el tamaño real de una fila y ambos fondos; la etiqueta siempre acompaña al icono.</p>
4
+ <header><input aria-label="Buscar iconos" id="search" type="search" placeholder="Buscar nombre o familia"><label>Tamaño <select id="size"><option>16</option><option>20</option><option selected>24</option><option>32</option></select></label><button id="theme">Cambiar fondo</button></header><main><article data-search="person persona personas y organización"><div class="glyph"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="7" r="4"/><path d="M4 21v-2a8 8 0 0 1 16 0v2"/></svg>
5
+ </div><strong>Persona</strong><code>person</code><small>Personas y organización</small></article><article data-search="people grupo personas y organización"><div class="glyph"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><circle cx="9" cy="7" r="3"/><path d="M2 21v-3a7 7 0 0 1 14 0v3M17 4a3 3 0 0 1 0 6m2 4a6 6 0 0 1 3 5v2"/></svg>
6
+ </div><strong>Grupo</strong><code>people</code><small>Personas y organización</small></article><article data-search="child infancia personas y organización"><div class="glyph"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="5" r="3"/><path d="M12 8v8m-6-5 6 2 6-2m-6 5-4 5m4-5 4 5"/></svg>
7
+ </div><strong>Infancia</strong><code>child</code><small>Personas y organización</small></article><article data-search="dog perro animales"><div class="glyph"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M8 6q4-3 8 0l2 10q-6 8-12 0ZM8 6 4 5 2 13l4 3M16 6l4-1 2 8-4 3M9 11h.01M15 11h.01m-4 4 1 1 1-1"/></svg>
8
+ </div><strong>Perro</strong><code>dog</code><small>Animales</small></article><article data-search="cat gato animales"><div class="glyph"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="m5 9-1-6 6 4h4l6-4-1 6a7 7 0 1 1-14 0ZM2 13h5m10 0h5M9 11h.01M15 11h.01m-4 4 1 1 1-1"/></svg>
9
+ </div><strong>Gato</strong><code>cat</code><small>Animales</small></article><article data-search="bird ave animales"><div class="glyph"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M3 13q6 0 8-7 3-4 6 0l4 2-4 2q0 9-11 9l-3-6Zm5 2 5-4M10 19v3m4-4v4"/><circle cx="15" cy="6" r=".6" fill="currentColor"/></svg>
10
+ </div><strong>Ave</strong><code>bird</code><small>Animales</small></article><article data-search="fish pez animales"><div class="glyph"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M3 12q7-12 15-2l4-5v14l-4-5Q10 24 3 12Zm10-7v14"/><circle cx="8" cy="11" r=".7" fill="currentColor"/></svg>
11
+ </div><strong>Pez</strong><code>fish</code><small>Animales</small></article><article data-search="insect insecto animales"><div class="glyph"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><ellipse cx="12" cy="14" rx="5" ry="7"/><path d="M9 7V5l-2-2m8 4V5l2-2M7 11 3 8m4 7H2m5 3-4 3m14-10 4-3m-4 7h5m-5 3 4 3M12 7v14"/></svg>
12
+ </div><strong>Insecto</strong><code>insect</code><small>Animales</small></article><article data-search="tree árbol plantas y ecosistemas"><div class="glyph"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="m12 2-6 8h3l-6 7h7v5h4v-5h7l-6-7h3Z"/></svg>
13
+ </div><strong>Árbol</strong><code>tree</code><small>Plantas y ecosistemas</small></article><article data-search="leaf hoja plantas y ecosistemas"><div class="glyph"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M20 3Q3 1 3 13q0 8 8 8 12-1 9-18ZM3 21 16 8"/></svg>
14
+ </div><strong>Hoja</strong><code>leaf</code><small>Plantas y ecosistemas</small></article><article data-search="flower flor plantas y ecosistemas"><div class="glyph"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M12 14v8m0-4q-7 1-7-4 5-1 7 4m0 2q7 0 7-4-5-1-7 4M9 6C5 0 1 7 7 9c-5 5 3 9 5 3 3 6 10 1 5-3 6-2 1-9-3-3 1-7-7-7-5 0Z"/><circle cx="12" cy="8" r="2"/></svg>
15
+ </div><strong>Flor</strong><code>flower</code><small>Plantas y ecosistemas</small></article><article data-search="seedling brote plantas y ecosistemas"><div class="glyph"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M12 22V11M12 15C3 15 2 10 3 5c6-1 10 2 9 10Zm0-4c0-7 4-9 9-8 1 5-2 9-9 8Z"/></svg>
16
+ </div><strong>Brote</strong><code>seedling</code><small>Plantas y ecosistemas</small></article><article data-search="sun sol tiempo atmosférico"><div class="glyph"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="4"/><path d="M12 2v2m0 16v2M2 12h2m16 0h2M5 5l1 1m12 12 1 1M5 19l1-1M18 6l1-1"/></svg>
17
+ </div><strong>Sol</strong><code>sun</code><small>Tiempo atmosférico</small></article><article data-search="moon luna tiempo atmosférico"><div class="glyph"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M20 15A9 9 0 0 1 9 3a9 9 0 1 0 11 12Z"/></svg>
18
+ </div><strong>Luna</strong><code>moon</code><small>Tiempo atmosférico</small></article><article data-search="cloud nube tiempo atmosférico"><div class="glyph"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M6 18a5 5 0 1 1 1-10 6 6 0 0 1 11 1 4.5 4.5 0 0 1 0 9Z"/></svg>
19
+ </div><strong>Nube</strong><code>cloud</code><small>Tiempo atmosférico</small></article><article data-search="rain lluvia tiempo atmosférico"><div class="glyph"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M5 15a4 4 0 1 1 1-8 5 5 0 0 1 10 1 3.5 3.5 0 0 1 2 7M7 18l-1 3m6-3-1 3m6-3-1 3"/></svg>
20
+ </div><strong>Lluvia</strong><code>rain</code><small>Tiempo atmosférico</small></article><article data-search="snow nieve tiempo atmosférico"><div class="glyph"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M12 2v20M3 7l18 10M3 17 21 7M9 4l3 3 3-3m-6 16 3-3 3 3M3 10l4-1-1-4m12 14-1-4 4-1M3 14l4 1-1 4M18 5l-1 4 4 1"/></svg>
21
+ </div><strong>Nieve</strong><code>snow</code><small>Tiempo atmosférico</small></article><article data-search="wind viento tiempo atmosférico"><div class="glyph"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M3 8h12a3 3 0 1 0-3-3M2 12h17a3 3 0 1 1-3 3M4 16h5a3 3 0 1 1-3 3"/></svg>
22
+ </div><strong>Viento</strong><code>wind</code><small>Tiempo atmosférico</small></article><article data-search="storm tormenta tiempo atmosférico"><div class="glyph"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M6 15a4 4 0 1 1 0-8 5 5 0 0 1 10 1 3.5 3.5 0 0 1 2 7m-5-4-5 7h5l-2 5 6-8h-5Z"/></svg>
23
+ </div><strong>Tormenta</strong><code>storm</code><small>Tiempo atmosférico</small></article><article data-search="fog niebla tiempo atmosférico"><div class="glyph"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M6 11a3.5 3.5 0 0 1-.6-6.95A5 5 0 0 1 15 5h2a3 3 0 0 1 0 6H6Z"/><path d="M4 15h16M2 19h7m4 0h9"/></svg>
24
+ </div><strong>Niebla</strong><code>fog</code><small>Tiempo atmosférico</small></article><article data-search="ground dominio terrestre terreno y agua"><div class="glyph"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M4 10h12l3 3v5H4zm4-3h7v3H8zM6.5 17a2 2 0 1 0 0 4 2 2 0 0 0 0-4m10 0a2 2 0 1 0 0 4 2 2 0 0 0 0-4"/></svg>
25
+ </div><strong>Dominio terrestre</strong><code>ground</code><small>Terreno y agua</small></article><article data-search="surface dominio de superficie terreno y agua"><div class="glyph"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"><path d="M3 14h14l4 3-16 2zM9 8h5v6H9zM12 4v4"/><path d="M4 21c2-1.5 4-1.5 6 0s4 1.5 6 0" fill="none" stroke-linecap="round"/></svg>
26
+ </div><strong>Dominio de superficie</strong><code>surface</code><small>Terreno y agua</small></article><article data-search="subsurface dominio submarino terreno y agua"><div class="glyph"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"><path d="M3 14c2-3 16-3 18 0-2 3-16 3-18 0M10 8h4v5h-4zM9 7h6"/><path d="M4 20c2-1.5 4-1.5 6 0s4 1.5 6 0" fill="none" stroke-linecap="round"/></svg>
27
+ </div><strong>Dominio submarino</strong><code>subsurface</code><small>Terreno y agua</small></article><article data-search="car coche transporte terrestre"><div class="glyph"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="m4 10 2-6h12l2 6M3 10h18v8H3Zm2 8v3m14-3v3M6 14h2m8 0h2"/></svg>
28
+ </div><strong>Coche</strong><code>car</code><small>Transporte terrestre</small></article><article data-search="bicycle bicicleta transporte terrestre"><div class="glyph"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><circle cx="5" cy="16" r="4"/><circle cx="19" cy="16" r="4"/><path d="m5 16 5-9 5 9H5m10 0 3-12h-4M8 7h5m5-3h3"/></svg>
29
+ </div><strong>Bicicleta</strong><code>bicycle</code><small>Transporte terrestre</small></article><article data-search="bus-vehicle autobús de pasajeros transporte terrestre"><div class="glyph"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M6 4h12v13H6zM4 8h2m12 0h2M6 17l-2 3m14-3 2 3"/><path d="M8 7h3v4H8zm5 0h3v4h-3zM8 15h.01M16 15h.01"/></svg>
30
+ </div><strong>Autobús de pasajeros</strong><code>bus-vehicle</code><small>Transporte terrestre</small></article><article data-search="aircraft avión aviación y espacio"><div class="glyph"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M12 2.5l1.4 8.1 7.2 4.2-7.9-1.3L12 21.5l-.7-8-7.9 1.3 7.2-4.2z"/><path d="M9.8 18.8L6.5 21M14.2 18.8l3.3 2.2" fill="none"/></svg>
31
+ </div><strong>Avión</strong><code>aircraft</code><small>Aviación y espacio</small></article><article data-search="helicopter helicóptero aviación y espacio"><div class="glyph"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M6 17V9h8q6 0 6 7l-5 2H6L2 8m4 5H2m9-4V4M3 4h17M7 18v3m9-3v3M4 21h16M14 9v5h5"/></svg>
32
+ </div><strong>Helicóptero</strong><code>helicopter</code><small>Aviación y espacio</small></article><article data-search="drone dron aviación y espacio"><div class="glyph"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="6" height="6" rx="2"/><path d="m9 9-4-4m10 4 4-4M9 15l-4 4m10-4 4 4"/><circle cx="5" cy="5" r="3"/><circle cx="19" cy="5" r="3"/><circle cx="5" cy="19" r="3"/><circle cx="19" cy="19" r="3"/></svg>
33
+ </div><strong>Dron</strong><code>drone</code><small>Aviación y espacio</small></article><article data-search="space dominio espacial aviación y espacio"><div class="glyph"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"><circle cx="12" cy="12" r="3" fill="currentColor"/><path d="M3 9h5v6H3zm13 0h5v6h-5zM8 12h8M4 18c4-3 12-3 16 0"/></svg>
34
+ </div><strong>Dominio espacial</strong><code>space</code><small>Aviación y espacio</small></article><article data-search="ship buque entorno marítimo"><div class="glyph"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="m3 13 9-4 9 4-3 6M6 19l-3-6m4-2V5h10v6M12 5V2M2 21q3-4 6 0 4-4 8 0 3-4 6 0"/></svg>
35
+ </div><strong>Buque</strong><code>ship</code><small>Entorno marítimo</small></article><article data-search="box caja objetos e instalaciones"><div class="glyph"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="m3 7 9-5 9 5v10l-9 5-9-5Zm0 0 9 5 9-5m-9 5v10M8 4l9 5"/></svg>
36
+ </div><strong>Caja</strong><code>box</code><small>Objetos e instalaciones</small></article><article data-search="building edificio objetos e instalaciones"><div class="glyph"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M4 22V3h16v19M2 22h20M9 22v-5h6v5M8 7h1m6 0h1M8 12h1m6 0h1"/></svg>
37
+ </div><strong>Edificio</strong><code>building</code><small>Objetos e instalaciones</small></article><article data-search="data-bus bus de datos datos y redes"><div class="glyph"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M3 12h18M6 8v4m6 0v4m6-8v4"/><rect x="3" y="3" width="6" height="5" rx="1"/><rect x="15" y="3" width="6" height="5" rx="1"/><rect x="9" y="16" width="6" height="5" rx="1"/></svg>
38
+ </div><strong>Bus de datos</strong><code>data-bus</code><small>Datos y redes</small></article><article data-search="network red datos y redes"><div class="glyph"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="2" width="6" height="5" rx="1"/><rect x="2" y="17" width="6" height="5" rx="1"/><rect x="16" y="17" width="6" height="5" rx="1"/><path d="M12 7v5M5 17v-5h14v5"/></svg>
39
+ </div><strong>Red</strong><code>network</code><small>Datos y redes</small></article><article data-search="server servidor datos y redes"><div class="glyph"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="18" height="7" rx="2"/><rect x="3" y="14" width="18" height="7" rx="2"/><path d="M7 6.5h.01M7 17.5h.01M12 6.5h5m-5 11h5"/></svg>
40
+ </div><strong>Servidor</strong><code>server</code><small>Datos y redes</small></article><article data-search="database base de datos datos y redes"><div class="glyph"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><ellipse cx="12" cy="5" rx="9" ry="3"/><path d="M3 5v14c0 4 18 4 18 0V5M3 12c0 4 18 4 18 0"/></svg>
41
+ </div><strong>Base de datos</strong><code>database</code><small>Datos y redes</small></article><article data-search="link enlace datos y redes"><div class="glyph"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="m9 15 6-6m-4-4 2-2a5 5 0 0 1 7 7l-3 3a5 5 0 0 1-6 1m2 5-2 2a5 5 0 0 1-7-7l3-3a5 5 0 0 1 6-1"/></svg>
42
+ </div><strong>Enlace</strong><code>link</code><small>Datos y redes</small></article><article data-search="sensor sensor genérico sensores y mediciones"><div class="glyph"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="2"/><path d="M7 7a7 7 0 0 0 0 10m10-10a7 7 0 0 1 0 10M4 4a11 11 0 0 0 0 16M20 4a11 11 0 0 1 0 16"/></svg>
43
+ </div><strong>Sensor genérico</strong><code>sensor</code><small>Sensores y mediciones</small></article><article data-search="radar radar sensores y mediciones"><div class="glyph"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="9"/><circle cx="12" cy="12" r="4.5"/><path d="m12 12 6.4-6.4"/><g fill="currentColor" stroke="none"><circle cx="12" cy="12" r="1.1"/><circle cx="7" cy="15" r="1.1"/></g></svg>
44
+ </div><strong>Radar</strong><code>radar</code><small>Sensores y mediciones</small></article><article data-search="thermometer termómetro sensores y mediciones"><div class="glyph"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M9 14V5a3 3 0 0 1 6 0v9a5 5 0 1 1-6 0ZM12 8v9"/></svg>
45
+ </div><strong>Termómetro</strong><code>thermometer</code><small>Sensores y mediciones</small></article><article data-search="globe globo terrestre geografía y navegación"><div class="glyph"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><ellipse cx="12" cy="12" rx="4" ry="10"/><path d="M2 12h20"/></svg>
46
+ </div><strong>Globo terrestre</strong><code>globe</code><small>Geografía y navegación</small></article><article data-search="point punto geografía y navegación"><div class="glyph"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><circle cx="12" cy="12" r="3" fill="currentColor"/><circle cx="12" cy="12" r="8"/><path d="M12 2v3m0 14v3M2 12h3m14 0h3"/></svg>
47
+ </div><strong>Punto</strong><code>point</code><small>Geografía y navegación</small></article><article data-search="track traza geografía y navegación"><div class="glyph"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><circle cx="12" cy="12" r="7"/><path d="M12 3v18M3 12h18"/></svg>
48
+ </div><strong>Traza</strong><code>track</code><small>Geografía y navegación</small></article><article data-search="folder carpeta inspector y documentos"><div class="glyph"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M3 6.5A2.5 2.5 0 0 1 5.5 4H10l2.1 2H18.5A2.5 2.5 0 0 1 21 8.5v8A2.5 2.5 0 0 1 18.5 19h-13A2.5 2.5 0 0 1 3 16.5z"/></svg>
49
+ </div><strong>Carpeta</strong><code>folder</code><small>Inspector y documentos</small></article><article data-search="inspector-object objeto de datos inspector y documentos"><div class="glyph"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linejoin="round"><rect x="5" y="5" width="14" height="14" rx="1"/><path d="M10 5v14m4-14v14"/></svg>
50
+ </div><strong>Objeto de datos</strong><code>inspector-object</code><small>Inspector y documentos</small></article><article data-search="inspector-array array inspector y documentos"><div class="glyph"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="8" cy="12" r="4"/><circle cx="16" cy="12" r="4"/></svg>
51
+ </div><strong>Array</strong><code>inspector-array</code><small>Inspector y documentos</small></article><article data-search="inspector-value valor escalar inspector y documentos"><div class="glyph"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="7"/><circle cx="12" cy="12" r="2.5" fill="currentColor" stroke="none"/></svg>
52
+ </div><strong>Valor escalar</strong><code>inspector-value</code><small>Inspector y documentos</small></article><article data-search="warning advertencia estados y alertas"><div class="glyph"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M10.27 3.3a2 2 0 0 1 3.46 0l8.02 13.9A2 2 0 0 1 20.02 20H3.98a2 2 0 0 1-1.73-2.8zM11 9v5h2V9zm0 7v2h2v-2z"/></svg>
53
+ </div><strong>Advertencia</strong><code>warning</code><small>Estados y alertas</small></article><article data-search="error error estados y alertas"><div class="glyph"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round"><circle cx="12" cy="12" r="8.5"/><path d="m9 9 6 6m0-6-6 6"/></svg>
54
+ </div><strong>Error</strong><code>error</code><small>Estados y alertas</small></article><article data-search="placeholder tipo desconocido estados y alertas"><div class="glyph"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linejoin="round"><rect x="4" y="4" width="16" height="16" rx="2"/></svg>
55
+ </div><strong>Tipo desconocido</strong><code>placeholder</code><small>Estados y alertas</small></article><article data-search="damage daño estados y alertas"><div class="glyph"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" stroke="currentColor" stroke-linejoin="round"><path d="m12 2 2.5 5L21 5l-3 5 4 3-5.5 1L17 21l-5-3-5 3 .5-7L2 13l4-3-3-5 6.5 2z"/><circle cx="12" cy="12" r="2.2" fill="#fff"/></svg>
56
+ </div><strong>Daño</strong><code>damage</code><small>Estados y alertas</small></article><article data-search="situation situación estados y alertas"><div class="glyph"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"><circle cx="12" cy="12" r="9"/><circle cx="12" cy="12" r="4" opacity=".55"/><path d="M3 12h18M12 3v18m0-9 6-5"/><circle cx="16" cy="8.5" r="1" fill="currentColor" stroke="none"/></svg>
57
+ </div><strong>Situación</strong><code>situation</code><small>Estados y alertas</small></article><article data-search="lock bloqueado estados y alertas"><div class="glyph"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><rect x="4" y="10" width="16" height="12" rx="2"/><path d="M7 10V7a5 5 0 0 1 10 0v3M12 15v3"/></svg>
58
+ </div><strong>Bloqueado</strong><code>lock</code><small>Estados y alertas</small></article><article data-search="control control acciones y controles"><div class="glyph"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linejoin="round" stroke-linecap="round"><path d="M4 17h16l2 3H2zM12 17l-2-8"/><circle cx="9.5" cy="7" r="2" fill="currentColor"/><circle cx="16" cy="19" r=".8" fill="currentColor"/><circle cx="19" cy="19" r=".8" fill="currentColor"/></svg>
59
+ </div><strong>Control</strong><code>control</code><small>Acciones y controles</small></article><article data-search="task tarea acciones y controles"><div class="glyph"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="5" y="4" width="14" height="16" rx="2"/><path d="M9 4.5h6M8.5 11.5l2 2 4-4M9 16h6"/></svg>
60
+ </div><strong>Tarea</strong><code>task</code><small>Acciones y controles</small></article><article data-search="star favorito acciones y controles"><div class="glyph"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="m12 2 3 6 7 1-5 5 1 7-6-3-6 3 1-7-5-5 7-1Z"/></svg>
61
+ </div><strong>Favorito</strong><code>star</code><small>Acciones y controles</small></article><article data-search="pin fijado acciones y controles"><div class="glyph"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="m8 3 8 0-1 6 4 4v2H5v-2l4-4-1-6ZM12 15v7"/></svg>
62
+ </div><strong>Fijado</strong><code>pin</code><small>Acciones y controles</small></article><article data-search="heart preferencia afectiva acciones y controles"><div class="glyph"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M12 21 3 12C-2 5 7-1 12 6c5-7 14-1 9 6Z"/></svg>
63
+ </div><strong>Preferencia afectiva</strong><code>heart</code><small>Acciones y controles</small></article><article data-search="grip asa de arrastre acciones y controles"><div class="glyph"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><circle cx="9" cy="5" r="1"/><circle cx="15" cy="5" r="1"/><circle cx="9" cy="12" r="1"/><circle cx="15" cy="12" r="1"/><circle cx="9" cy="19" r="1"/><circle cx="15" cy="19" r="1"/></svg>
64
+ </div><strong>Asa de arrastre</strong><code>grip</code><small>Acciones y controles</small></article><article data-search="clock reloj tiempo y simulación"><div class="glyph"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="M12 6v6l4 2"/></svg>
65
+ </div><strong>Reloj</strong><code>clock</code><small>Tiempo y simulación</small></article><article data-search="calendar calendario tiempo y simulación"><div class="glyph"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="4" width="18" height="18" rx="2"/><path d="M3 10h18M8 2v5m8-5v5M7 14h2m3 0h2m3 0h1M7 18h2m3 0h2"/></svg>
66
+ </div><strong>Calendario</strong><code>calendar</code><small>Tiempo y simulación</small></article><article data-search="munition munición tiempo y simulación"><div class="glyph"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" stroke="currentColor" stroke-linejoin="round"><path d="m12 2 3 5v10l-3 5-3-5V7z"/><path d="m9 14-6 5 6-1m6-4 6 5-6-1" fill="none" stroke-width="2" stroke-linecap="round"/></svg>
67
+ </div><strong>Munición</strong><code>munition</code><small>Tiempo y simulación</small></article></main><script>search.oninput=()=>document.querySelectorAll('article').forEach(el=>el.hidden=!el.dataset.search.includes(search.value.toLowerCase()));size.onchange=()=>document.documentElement.style.setProperty('--icon-size',size.value+'px');theme.onclick=()=>document.body.classList.toggle('light');</script></html>