@agent-scope/site 1.18.0 → 1.19.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.
package/dist/index.cjs CHANGED
@@ -70,21 +70,24 @@ function slugify(name) {
70
70
  }
71
71
  function renderDOMTree(node, depth = 0) {
72
72
  const indent = " ".repeat(depth);
73
- const attrs = Object.entries(node.attrs).map(
74
- ([k, v]) => ` <span class="dom-attr-name">${escapeHtml(k)}</span>=<span class="dom-attr-value">"${escapeHtml(v)}"</span>`
75
- ).join("");
73
+ const attrsHtml = Object.entries(node.attrs).map(([k, v]) => {
74
+ const display = v.length > 60 ? v.slice(0, 57) + "\u2026" : v;
75
+ return ` <span class="dom-attr-name">${escapeHtml(k)}</span>=<span class="dom-attr-value">"${escapeHtml(display)}"</span>`;
76
+ }).join("");
77
+ const nodeIdAttr = node.nodeId !== void 0 ? ` data-node-id="${node.nodeId}"` : "";
78
+ const clickable = node.nodeId !== void 0 ? " dom-node-clickable" : "";
76
79
  const hasChildren = node.children.length > 0;
77
80
  const hasText = node.text !== void 0 && node.text.trim().length > 0;
78
81
  if (!hasChildren && !hasText) {
79
- return `${indent}<span class="dom-tag-open">&lt;${escapeHtml(node.tag)}${attrs} /&gt;</span>
82
+ return `${indent}<span class="dom-tag-open${clickable}"${nodeIdAttr}>&lt;${escapeHtml(node.tag)}${attrsHtml} /&gt;</span>
80
83
  `;
81
84
  }
82
85
  const childrenHtml = node.children.map((child) => renderDOMTree(child, depth + 1)).join("");
83
86
  const textHtml = hasText ? `${indent} <span class="dom-text">${escapeHtml(node.text ?? "")}</span>
84
87
  ` : "";
85
- return `<details class="dom-node" ${depth < 2 ? "open" : ""}>
86
- ${indent}<summary><span class="dom-tag-open">&lt;${escapeHtml(node.tag)}${attrs}&gt;</span></summary>
87
- ${textHtml}${childrenHtml}${indent}<span class="dom-tag-open">&lt;/${escapeHtml(node.tag)}&gt;</span>
88
+ return `<details class="dom-node${clickable}" ${depth < 2 ? "open" : ""}${nodeIdAttr}>
89
+ ${indent}<summary><span class="dom-tag-open">&lt;${escapeHtml(node.tag)}${attrsHtml}&gt;</span></summary>
90
+ ${textHtml}${childrenHtml}${indent}<span class="dom-tag-close">&lt;/${escapeHtml(node.tag)}&gt;</span>
88
91
  </details>`;
89
92
  }
90
93
  function propTableRow(name, prop) {
@@ -300,6 +303,7 @@ body {
300
303
  max-width: 100%;
301
304
  }
302
305
  .render-preview img { display: block; max-width: 100%; }
306
+ .scope-screenshot { zoom: 0.5; display: block; image-rendering: -webkit-optimize-contrast; }
303
307
 
304
308
  /* Props table */
305
309
  .props-table { width: 100%; border-collapse: collapse; font-size: 13px; }
@@ -439,7 +443,7 @@ pre.code-block {
439
443
  overflow: hidden;
440
444
  }
441
445
  .matrix-cell { background: var(--color-bg); padding: 8px; text-align: center; }
442
- .matrix-cell img { max-width: 100%; border-radius: 2px; }
446
+ .matrix-cell img { border-radius: 2px; }
443
447
  .matrix-cell .cell-label { font-size: 10px; color: var(--color-muted); margin-top: 4px; }
444
448
  .matrix-header { background: var(--color-bg-subtle); padding: 6px 8px; font-size: 11px; font-weight: 600; color: var(--color-muted); }
445
449
 
@@ -448,6 +452,13 @@ pre.code-block {
448
452
  details.dom-node > summary { cursor: pointer; list-style: none; }
449
453
  details.dom-node > summary::-webkit-details-marker { display: none; }
450
454
  .dom-tag-open { color: #f07178; }
455
+ .dom-tag-close { color: #f07178; }
456
+ .dom-attr-name { color: #ffcb6b; }
457
+ .dom-attr-value { color: #c3e88d; }
458
+ .dom-text { color: #82aaff; font-style: italic; }
459
+ .dom-node-clickable { cursor: pointer; border-radius: 3px; transition: background 0.1s; }
460
+ .dom-node-clickable:hover, details.dom-node-clickable > summary:hover { background: rgba(255,255,255,0.08); }
461
+ .dom-node-selected, details.dom-node-selected > summary { background: rgba(99,179,237,0.15) !important; outline: 1px solid rgba(99,179,237,0.4); border-radius: 3px; }
451
462
  .dom-attr-name { color: #ffcb6b; }
452
463
  .dom-attr-value { color: #c3e88d; }
453
464
  .dom-text { color: #a0a0b0; font-style: italic; }
@@ -488,7 +499,7 @@ details.dom-node > summary::-webkit-details-marker { display: none; }
488
499
  justify-content: center;
489
500
  border-bottom: 1px solid var(--color-border);
490
501
  }
491
- .card-preview img { max-width: 100%; max-height: 100%; object-fit: contain; }
502
+ .card-preview img { object-fit: contain; }
492
503
  .card-preview .no-preview { color: var(--color-muted); font-size: 12px; }
493
504
  .card-body { padding: 12px 16px; }
494
505
  .card-name { font-weight: 600; font-size: 14px; margin-bottom: 4px; }
@@ -621,8 +632,11 @@ function renderPlayground(name, data) {
621
632
  ${props.map(([n, p]) => propTableRow(n, p)).join("\n ")}
622
633
  </tbody>
623
634
  </table>` : `<p style="color:var(--color-muted);font-size:13px">No props defined.</p>`;
635
+ const renderW = render?.width != null ? render.width : void 0;
636
+ const renderH = render?.height != null ? render.height : void 0;
637
+ const renderSizeAttr = renderW != null && renderH != null ? ` width="${renderW}" height="${renderH}"` : "";
624
638
  const renderHtml = render?.screenshot ? `<div class="render-preview">
625
- <img src="data:image/png;base64,${render.screenshot}" alt="${escapeHtml(name)} render" />
639
+ <img src="data:image/png;base64,${render.screenshot}" alt="${escapeHtml(name)} render"${renderSizeAttr} />
626
640
  </div>` : notGenerated("Render not generated. Run scope render to produce screenshots.");
627
641
  return sectionWrap(
628
642
  "playground",
@@ -646,7 +660,7 @@ function renderMatrix(name, data) {
646
660
  const cols = Math.ceil(Math.sqrt(cells.length));
647
661
  const cellsHtml = cells.map((cell) => {
648
662
  const label = cell.axisValues.join(" / ");
649
- const imgHtml = cell.screenshot ? `<img src="data:image/png;base64,${cell.screenshot}" alt="${escapeHtml(label)}" />` : `<span style="color:var(--color-muted);font-size:11px">${cell.error ? escapeHtml(cell.error) : "failed"}</span>`;
663
+ const imgHtml = cell.screenshot ? `<img class="scope-screenshot" src="data:image/png;base64,${cell.screenshot}" alt="${escapeHtml(label)}" />` : `<span style="color:var(--color-muted);font-size:11px">${cell.error ? escapeHtml(cell.error) : "failed"}</span>`;
650
664
  return `<div class="matrix-cell">${imgHtml}<div class="cell-label">${escapeHtml(label)}</div></div>`;
651
665
  }).join("\n");
652
666
  const grid = `<div class="matrix-grid" style="grid-template-columns: repeat(${cols}, 1fr)">
@@ -747,25 +761,56 @@ function renderXRay(name, data) {
747
761
  );
748
762
  }
749
763
  const dom = render.dom;
764
+ const nodeStylesMap = {};
765
+ if (render.computedStyles) {
766
+ for (const [key, styles] of Object.entries(render.computedStyles)) {
767
+ const m = key.match(/^#node-(\d+)$/);
768
+ if (m?.[1] !== void 0) nodeStylesMap[parseInt(m[1], 10)] = styles;
769
+ }
770
+ }
771
+ const nodeStylesJson = escapeHtml(JSON.stringify(nodeStylesMap));
750
772
  const treeHtml = `<div class="dom-tree">${renderDOMTree(dom.tree)}</div>`;
751
- const stylesHtml = render.computedStyles && Object.keys(render.computedStyles).length > 0 ? `<details style="margin-top:16px">
752
- <summary style="cursor:pointer;font-size:13px;font-weight:600;margin-bottom:8px">Computed Styles</summary>
753
- <table class="token-table" style="margin-top:8px">
754
- <thead><tr><th>Selector</th><th>Property</th><th>Value</th></tr></thead>
755
- <tbody>
756
- ${Object.entries(render.computedStyles).flatMap(
757
- ([selector, styles]) => Object.entries(styles).map(
758
- ([prop, val]) => `<tr><td class="token-path">${escapeHtml(selector)}</td><td>${escapeHtml(prop)}</td><td>${escapeHtml(val)}</td></tr>`
759
- )
760
- ).join("\n ")}
761
- </tbody>
773
+ const stylesPanelHtml = `
774
+ <div id="xray-styles-panel-${escapeHtml(name)}" class="xray-styles-panel" style="display:none;margin-top:16px;border:1px solid var(--color-border);border-radius:6px;overflow:hidden">
775
+ <div class="xray-styles-header" style="padding:8px 12px;background:var(--color-surface-2);font-size:12px;font-weight:600;color:var(--color-muted);display:flex;justify-content:space-between;align-items:center">
776
+ <span id="xray-styles-label-${escapeHtml(name)}">\u2014 no node selected \u2014</span>
777
+ <button onclick="document.getElementById('xray-styles-panel-${escapeHtml(name)}').style.display='none'" style="background:none;border:none;cursor:pointer;color:var(--color-muted);font-size:16px;line-height:1">\xD7</button>
778
+ </div>
779
+ <table class="token-table" style="margin:0">
780
+ <thead><tr><th>Property</th><th>Value</th></tr></thead>
781
+ <tbody id="xray-styles-body-${escapeHtml(name)}"></tbody>
762
782
  </table>
763
- </details>` : "";
783
+ </div>
784
+ <script>
785
+ (function() {
786
+ var nodeStyles = JSON.parse(${nodeStylesJson});
787
+ var container = document.currentScript.parentElement;
788
+ container.addEventListener("click", function(e) {
789
+ var el = e.target.closest("[data-node-id]");
790
+ if (!el) return;
791
+ var id = parseInt(el.getAttribute("data-node-id"), 10);
792
+ var styles = nodeStyles[id];
793
+ if (!styles) return;
794
+ var panel = document.getElementById("xray-styles-panel-${escapeHtml(name)}");
795
+ var label = document.getElementById("xray-styles-label-${escapeHtml(name)}");
796
+ var body = document.getElementById("xray-styles-body-${escapeHtml(name)}");
797
+ var tag = el.tagName === "DETAILS" ? el.querySelector("summary .dom-tag-open") : el;
798
+ label.textContent = tag ? tag.textContent.trim().slice(0, 60) : "node #" + id;
799
+ body.innerHTML = Object.entries(styles).map(function(e) {
800
+ return "<tr><td>" + e[0] + "</td><td style="font-family:monospace">" + e[1] + "</td></tr>";
801
+ }).join("");
802
+ panel.style.display = "block";
803
+ // Highlight selected node
804
+ container.querySelectorAll(".dom-node-selected").forEach(function(n) { n.classList.remove("dom-node-selected"); });
805
+ el.classList.add("dom-node-selected");
806
+ });
807
+ })();
808
+ </script>`;
764
809
  return sectionWrap(
765
810
  "x-ray",
766
811
  "X-Ray",
767
- `DOM structure \u2014 ${dom.elementCount} elements.`,
768
- `${treeHtml}${stylesHtml}`
812
+ `DOM structure \u2014 ${dom.elementCount} elements. Click any element to inspect its computed styles.`,
813
+ `${treeHtml}${stylesPanelHtml}`
769
814
  );
770
815
  }
771
816
  function renderTokens(name, data) {
@@ -948,7 +993,7 @@ function renderComponentIndex(data) {
948
993
  const render = data.renders.get(name);
949
994
  const propCount = Object.keys(component.props).length;
950
995
  const hookCount = component.detectedHooks.length;
951
- const previewHtml = render?.screenshot ? `<img src="data:image/png;base64,${render.screenshot}" alt="${escapeHtml(name)}" />` : `<span class="no-preview">No preview</span>`;
996
+ const previewHtml = render?.screenshot ? `<img class="scope-screenshot" src="data:image/png;base64,${render.screenshot}" alt="${escapeHtml(name)}" />` : `<span class="no-preview">No preview</span>`;
952
997
  return `<a class="component-card" href="${data.options.basePath}${slug}.html" data-name="${escapeHtml(name.toLowerCase())}">
953
998
  <div class="card-preview">${previewHtml}</div>
954
999
  <div class="card-body">
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/reader.ts","../src/utils.ts","../src/css.ts","../src/templates/layout.ts","../src/templates/component-detail.ts","../src/templates/component-index.ts","../src/templates/dashboard.ts","../src/builder.ts"],"names":["readFile","join","readdir","mkdir","writeFile"],"mappings":"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AA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAAA;AA0ZZ,EAAA,OAAO,CAAA;AAAA,EAAY,GAAG;AAAA,QAAA,CAAA;AACxB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","file":"index.cjs","sourcesContent":["import { readdir, readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport type {\n ComplianceBatchData,\n ManifestData,\n RenderFileData,\n SiteData,\n SiteOptions,\n} from \"./types.js\";\n\nfunction normalizeOptions(options?: SiteOptions): Required<SiteOptions> {\n return {\n inputDir: options?.inputDir ?? \".reactscope\",\n outputDir: options?.outputDir ?? \".reactscope/site\",\n basePath: options?.basePath ?? \"/\",\n compliancePath: options?.compliancePath ?? \"\",\n title: options?.title ?? \"Scope — Component Gallery\",\n };\n}\n\nexport { normalizeOptions };\n\nasync function readJsonFile<T>(filePath: string): Promise<T> {\n const content = await readFile(filePath, \"utf-8\");\n return JSON.parse(content) as T;\n}\n\nexport async function readSiteData(options: Required<SiteOptions>): Promise<SiteData> {\n // 1. Read manifest\n const manifestPath = join(options.inputDir, \"manifest.json\");\n const manifest = await readJsonFile<ManifestData>(manifestPath);\n\n // 2. Scan renders directory\n const renders = new Map<string, RenderFileData>();\n const rendersDir = join(options.inputDir, \"renders\");\n\n try {\n const entries = await readdir(rendersDir);\n const jsonFiles = entries.filter((f) => f.endsWith(\".json\"));\n\n await Promise.all(\n jsonFiles.map(async (file) => {\n const componentName = file.replace(/\\.json$/, \"\");\n const filePath = join(rendersDir, file);\n try {\n const renderData = await readJsonFile<RenderFileData>(filePath);\n renders.set(componentName, renderData);\n } catch (err) {\n console.warn(\n `[scope/site] Warning: could not read render file ${filePath}:`,\n err instanceof Error ? err.message : String(err),\n );\n }\n }),\n );\n } catch {\n // renders directory may not exist — that's fine\n }\n\n // 3. Optionally read compliance JSON\n let complianceBatch: ComplianceBatchData | undefined;\n if (options.compliancePath) {\n try {\n complianceBatch = await readJsonFile<ComplianceBatchData>(options.compliancePath);\n } catch (err) {\n console.warn(\n `[scope/site] Warning: could not read compliance file ${options.compliancePath}:`,\n err instanceof Error ? err.message : String(err),\n );\n }\n }\n\n return {\n manifest,\n renders,\n complianceBatch,\n options,\n };\n}\n","import type { DOMNodeData, PropData } from \"./types.js\";\n\nexport function escapeHtml(str: string): string {\n return str\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\")\n .replace(/'/g, \"&#39;\");\n}\n\nexport function slugify(name: string): string {\n return name\n .replace(/([A-Z])/g, (m) => `-${m.toLowerCase()}`)\n .replace(/^-/, \"\")\n .replace(/[^a-z0-9-]/g, \"-\")\n .replace(/-+/g, \"-\")\n .replace(/^-|-$/g, \"\");\n}\n\nexport function syntaxHighlightJSX(code: string): string {\n const escaped = escapeHtml(code);\n\n return (\n escaped\n // Comments\n .replace(/(\\/\\/[^\\n]*)/g, '<span class=\"token-comment\">$1</span>')\n .replace(/(\\/\\*[\\s\\S]*?\\*\\/)/g, '<span class=\"token-comment\">$1</span>')\n // JSX tags\n .replace(/(&lt;\\/?)([\\w.]+)/g, '<span class=\"token-tag\">$1$2</span>')\n // JSX attributes (word followed by =)\n .replace(/\\b([\\w-]+)(?==)/g, '<span class=\"token-attr\">$1</span>')\n // Strings\n .replace(\n /(&quot;[^&]*&quot;|&#39;[^&]*&#39;|`[^`]*`)/g,\n '<span class=\"token-string\">$1</span>',\n )\n // Keywords\n .replace(\n /\\b(import|export|from|default|const|let|var|function|return|if|else|for|while|class|extends|type|interface|async|await|new|typeof|instanceof)\\b/g,\n '<span class=\"token-keyword\">$1</span>',\n )\n // Numbers\n .replace(/\\b(\\d+\\.?\\d*)\\b/g, '<span class=\"token-number\">$1</span>')\n );\n}\n\nexport function renderDOMTree(node: DOMNodeData, depth = 0): string {\n const indent = \" \".repeat(depth);\n const attrs = Object.entries(node.attrs)\n .map(\n ([k, v]) =>\n ` <span class=\"dom-attr-name\">${escapeHtml(k)}</span>=<span class=\"dom-attr-value\">\"${escapeHtml(v)}\"</span>`,\n )\n .join(\"\");\n\n const hasChildren = node.children.length > 0;\n const hasText = node.text !== undefined && node.text.trim().length > 0;\n\n if (!hasChildren && !hasText) {\n return `${indent}<span class=\"dom-tag-open\">&lt;${escapeHtml(node.tag)}${attrs} /&gt;</span>\\n`;\n }\n\n const childrenHtml = node.children.map((child) => renderDOMTree(child, depth + 1)).join(\"\");\n const textHtml = hasText\n ? `${indent} <span class=\"dom-text\">${escapeHtml(node.text ?? \"\")}</span>\\n`\n : \"\";\n\n return `<details class=\"dom-node\" ${depth < 2 ? \"open\" : \"\"}>\n${indent}<summary><span class=\"dom-tag-open\">&lt;${escapeHtml(node.tag)}${attrs}&gt;</span></summary>\n${textHtml}${childrenHtml}${indent}<span class=\"dom-tag-open\">&lt;/${escapeHtml(node.tag)}&gt;</span>\n</details>`;\n}\n\nexport function propTableRow(name: string, prop: PropData): string {\n const valuesHtml =\n prop.values && prop.values.length > 0\n ? `<br><span style=\"color:var(--color-muted);font-size:11px\">${prop.values.map((v) => escapeHtml(v)).join(\" | \")}</span>`\n : \"\";\n\n const defaultHtml = prop.default !== undefined ? escapeHtml(prop.default) : \"—\";\n\n return `<tr>\n <td><span class=\"prop-name\">${escapeHtml(name)}</span></td>\n <td><span class=\"prop-type\">${escapeHtml(prop.type)}</span>${valuesHtml}</td>\n <td>${prop.required ? '<span class=\"prop-required\">required</span>' : '<span style=\"color:var(--color-muted)\">optional</span>'}</td>\n <td><span class=\"prop-default\">${defaultHtml}</span></td>\n </tr>`;\n}\n","export function generateCSS(): string {\n const css = `@import url('https://fonts.googleapis.com/css2?family=Inter:wght@100..900&family=JetBrains+Mono:wght@400;700&display=swap');\n\n:root {\n --color-text: #0f0f0f;\n --color-muted: #6b7280;\n --color-border: #e5e7eb;\n --color-bg: #ffffff;\n --color-bg-subtle: #f9fafb;\n --color-bg-code: #1a1a2e;\n --color-accent: #2563eb;\n --color-success: #16a34a;\n --color-warn: #d97706;\n --color-error: #dc2626;\n --font-body: 'Inter', system-ui, -apple-system, sans-serif;\n --font-mono: 'JetBrains Mono', 'Fira Code', monospace;\n --radius: 6px;\n --shadow-sm: 0 1px 2px rgba(0,0,0,0.05);\n --shadow: 0 1px 3px rgba(0,0,0,0.1), 0 1px 2px rgba(0,0,0,0.06);\n}\n\n*, *::before, *::after { box-sizing: border-box; }\n\nbody {\n font-family: var(--font-body);\n font-size: 14px;\n line-height: 1.6;\n color: var(--color-text);\n background: var(--color-bg);\n margin: 0;\n}\n\n/* Top nav */\n.top-nav {\n position: sticky;\n top: 0;\n z-index: 100;\n background: var(--color-bg);\n border-bottom: 1px solid var(--color-border);\n height: 52px;\n display: flex;\n align-items: center;\n padding: 0 24px;\n gap: 16px;\n}\n.top-nav .site-title { font-weight: 600; font-size: 15px; text-decoration: none; color: var(--color-text); }\n.top-nav .spacer { flex: 1; }\n.search-box {\n border: 1px solid var(--color-border);\n border-radius: var(--radius);\n padding: 6px 12px;\n font-family: var(--font-body);\n font-size: 13px;\n width: 240px;\n outline: none;\n background: var(--color-bg-subtle);\n}\n.search-box:focus { border-color: var(--color-accent); background: var(--color-bg); }\n\n/* Page layout */\n.page-layout {\n display: flex;\n min-height: calc(100vh - 52px);\n}\n\n/* Left sidebar (component list) */\n.sidebar {\n width: 220px;\n min-width: 220px;\n border-right: 1px solid var(--color-border);\n padding: 16px 0;\n position: sticky;\n top: 52px;\n height: calc(100vh - 52px);\n overflow-y: auto;\n}\n.sidebar-heading {\n font-size: 11px;\n font-weight: 600;\n letter-spacing: 0.06em;\n text-transform: uppercase;\n color: var(--color-muted);\n padding: 4px 16px 8px;\n}\n.sidebar a {\n display: block;\n padding: 5px 16px;\n font-size: 13px;\n color: var(--color-text);\n text-decoration: none;\n border-radius: 0;\n}\n.sidebar a:hover { background: var(--color-bg-subtle); }\n.sidebar a.active { color: var(--color-accent); font-weight: 500; }\n\n/* Main content */\n.main-content {\n flex: 1;\n min-width: 0;\n display: flex;\n}\n.content-body {\n flex: 1;\n min-width: 0;\n padding: 32px 40px;\n max-width: 900px;\n}\n\n/* On this page nav (right side) */\n.on-this-page {\n width: 200px;\n min-width: 200px;\n padding: 32px 16px;\n position: sticky;\n top: 52px;\n height: calc(100vh - 52px);\n overflow-y: auto;\n}\n.on-this-page h4 {\n font-size: 11px;\n font-weight: 600;\n letter-spacing: 0.06em;\n text-transform: uppercase;\n color: var(--color-muted);\n margin: 0 0 8px;\n}\n.on-this-page a {\n display: block;\n padding: 3px 0;\n font-size: 12px;\n color: var(--color-muted);\n text-decoration: none;\n}\n.on-this-page a:hover { color: var(--color-text); }\n\n/* Component header */\n.component-header { margin-bottom: 32px; }\n.component-header h1 { font-size: 28px; font-weight: 700; margin: 0 0 8px; }\n.component-header .meta {\n display: flex;\n gap: 8px;\n align-items: center;\n flex-wrap: wrap;\n margin-bottom: 8px;\n}\n.badge {\n display: inline-flex;\n align-items: center;\n padding: 2px 8px;\n border-radius: 999px;\n font-size: 11px;\n font-weight: 500;\n border: 1px solid var(--color-border);\n color: var(--color-muted);\n background: var(--color-bg-subtle);\n}\n.badge.complex { border-color: #fbbf24; color: #92400e; background: #fffbeb; }\n.badge.simple { border-color: #6ee7b7; color: #065f46; background: #ecfdf5; }\n.badge.memoized { border-color: #a5b4fc; color: #3730a3; background: #eef2ff; }\n\n.filepath {\n font-family: var(--font-mono);\n font-size: 12px;\n color: var(--color-muted);\n}\n\n/* Sections */\n.section {\n padding: 32px 0;\n border-bottom: 1px solid var(--color-border);\n}\n.section:last-child { border-bottom: none; }\n.section-header { margin-bottom: 20px; }\n.section-header h2 {\n font-size: 18px;\n font-weight: 600;\n margin: 0 0 4px;\n}\n.section-header p { color: var(--color-muted); margin: 0; font-size: 13px; }\n\n/* Not generated placeholder */\n.not-generated {\n background: var(--color-bg-subtle);\n border: 1px dashed var(--color-border);\n border-radius: var(--radius);\n padding: 32px;\n text-align: center;\n color: var(--color-muted);\n font-size: 13px;\n}\n\n/* Render preview */\n.render-preview {\n border: 1px solid var(--color-border);\n border-radius: var(--radius);\n overflow: hidden;\n background: #f8f8f8;\n display: inline-block;\n max-width: 100%;\n}\n.render-preview img { display: block; max-width: 100%; }\n\n/* Props table */\n.props-table { width: 100%; border-collapse: collapse; font-size: 13px; }\n.props-table th {\n text-align: left;\n font-weight: 600;\n font-size: 11px;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n color: var(--color-muted);\n padding: 8px 12px;\n border-bottom: 2px solid var(--color-border);\n}\n.props-table td {\n padding: 8px 12px;\n border-bottom: 1px solid var(--color-border);\n vertical-align: top;\n}\n.props-table tr:last-child td { border-bottom: none; }\n.prop-name { font-family: var(--font-mono); font-size: 12px; font-weight: 700; }\n.prop-type { font-family: var(--font-mono); font-size: 11px; color: var(--color-accent); }\n.prop-required { color: var(--color-error); font-size: 11px; }\n.prop-default { font-family: var(--font-mono); font-size: 11px; color: var(--color-muted); }\n\n/* Code blocks */\npre.code-block {\n background: var(--color-bg-code);\n color: #e2e8f0;\n border-radius: var(--radius);\n padding: 16px 20px;\n overflow-x: auto;\n font-family: var(--font-mono);\n font-size: 13px;\n line-height: 1.6;\n margin: 0;\n}\n.token-keyword { color: #c792ea; }\n.token-string { color: #c3e88d; }\n.token-comment { color: #546e7a; font-style: italic; }\n.token-tag { color: #f07178; }\n.token-attr { color: #ffcb6b; }\n.token-number { color: #f78c6c; }\n\n/* Stats grid */\n.stats-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));\n gap: 12px;\n margin-bottom: 24px;\n}\n.stat-card {\n background: var(--color-bg-subtle);\n border: 1px solid var(--color-border);\n border-radius: var(--radius);\n padding: 16px;\n}\n.stat-card .stat-label { font-size: 11px; color: var(--color-muted); text-transform: uppercase; letter-spacing: 0.05em; margin-bottom: 4px; }\n.stat-card .stat-value { font-size: 22px; font-weight: 700; }\n\n/* Analysis grid */\n.analysis-grid {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 16px;\n}\n.analysis-card {\n background: var(--color-bg-subtle);\n border: 1px solid var(--color-border);\n border-radius: var(--radius);\n padding: 16px;\n}\n.analysis-card h3 { font-size: 12px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; color: var(--color-muted); margin: 0 0 8px; }\n.analysis-card .value { font-size: 14px; }\n.tag-list { display: flex; flex-wrap: wrap; gap: 4px; }\n.tag {\n display: inline-block;\n padding: 2px 8px;\n background: var(--color-border);\n border-radius: 4px;\n font-family: var(--font-mono);\n font-size: 11px;\n}\n\n/* Token pills */\n.pill-on {\n display: inline-flex; align-items: center; gap: 4px;\n padding: 2px 8px; border-radius: 999px;\n background: #dcfce7; color: #166534;\n font-size: 11px; font-weight: 500;\n}\n.pill-off {\n display: inline-flex; align-items: center; gap: 4px;\n padding: 2px 8px; border-radius: 999px;\n background: #fef3c7; color: #92400e;\n font-size: 11px; font-weight: 500;\n}\n\n/* Compliance bar */\n.compliance-bar-container { margin-bottom: 16px; }\n.compliance-bar-bg { background: var(--color-border); border-radius: 999px; height: 8px; overflow: hidden; }\n.compliance-bar-fill { height: 100%; border-radius: 999px; background: var(--color-success); }\n.compliance-label { font-size: 13px; color: var(--color-muted); margin-bottom: 4px; }\n\n/* Token table */\n.token-table { width: 100%; border-collapse: collapse; font-size: 12px; }\n.token-table th {\n text-align: left; font-weight: 600; font-size: 11px;\n text-transform: uppercase; letter-spacing: 0.05em;\n color: var(--color-muted); padding: 6px 10px;\n border-bottom: 2px solid var(--color-border);\n}\n.token-table td { padding: 6px 10px; border-bottom: 1px solid var(--color-border); vertical-align: top; }\n.token-table tr:last-child td { border-bottom: none; }\n.token-path { font-family: var(--font-mono); color: var(--color-accent); }\n.token-value-swatch { display: inline-block; width: 12px; height: 12px; border-radius: 2px; border: 1px solid var(--color-border); margin-right: 4px; vertical-align: middle; }\n\n/* A11y violations */\n.violation-list { list-style: none; padding: 0; margin: 0; }\n.violation-list li {\n padding: 8px 12px;\n background: #fef2f2;\n border: 1px solid #fecaca;\n border-radius: var(--radius);\n margin-bottom: 6px;\n font-size: 13px;\n color: #991b1b;\n}\n.a11y-role-badge { font-family: var(--font-mono); font-size: 11px; background: var(--color-bg-subtle); border: 1px solid var(--color-border); padding: 2px 6px; border-radius: 4px; }\n\n/* Matrix grid */\n.matrix-grid {\n display: grid;\n gap: 1px;\n background: var(--color-border);\n border: 1px solid var(--color-border);\n border-radius: var(--radius);\n overflow: hidden;\n}\n.matrix-cell { background: var(--color-bg); padding: 8px; text-align: center; }\n.matrix-cell img { max-width: 100%; border-radius: 2px; }\n.matrix-cell .cell-label { font-size: 10px; color: var(--color-muted); margin-top: 4px; }\n.matrix-header { background: var(--color-bg-subtle); padding: 6px 8px; font-size: 11px; font-weight: 600; color: var(--color-muted); }\n\n/* DOM tree */\n.dom-tree { font-family: var(--font-mono); font-size: 12px; line-height: 1.8; }\ndetails.dom-node > summary { cursor: pointer; list-style: none; }\ndetails.dom-node > summary::-webkit-details-marker { display: none; }\n.dom-tag-open { color: #f07178; }\n.dom-attr-name { color: #ffcb6b; }\n.dom-attr-value { color: #c3e88d; }\n.dom-text { color: #a0a0b0; font-style: italic; }\n\n/* Composition graph */\n.composition-lists { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }\n.comp-list h3 { font-size: 13px; font-weight: 600; margin: 0 0 8px; color: var(--color-muted); }\n.comp-list ul { list-style: none; padding: 0; margin: 0; }\n.comp-list li { padding: 4px 0; font-size: 13px; border-bottom: 1px solid var(--color-border); }\n.comp-list a { color: var(--color-accent); text-decoration: none; }\n.comp-list a:hover { text-decoration: underline; }\n\n/* Index page */\n.index-header { margin-bottom: 32px; }\n.index-header h1 { font-size: 32px; font-weight: 700; margin: 0 0 8px; }\n.index-header p { color: var(--color-muted); font-size: 15px; margin: 0; }\n.component-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));\n gap: 16px;\n}\n.component-card {\n border: 1px solid var(--color-border);\n border-radius: var(--radius);\n overflow: hidden;\n text-decoration: none;\n color: var(--color-text);\n transition: box-shadow 0.15s;\n display: block;\n}\n.component-card:hover { box-shadow: var(--shadow); }\n.card-preview {\n background: #f8f8f8;\n height: 160px;\n overflow: hidden;\n display: flex;\n align-items: center;\n justify-content: center;\n border-bottom: 1px solid var(--color-border);\n}\n.card-preview img { max-width: 100%; max-height: 100%; object-fit: contain; }\n.card-preview .no-preview { color: var(--color-muted); font-size: 12px; }\n.card-body { padding: 12px 16px; }\n.card-name { font-weight: 600; font-size: 14px; margin-bottom: 4px; }\n.card-meta { font-size: 12px; color: var(--color-muted); display: flex; gap: 8px; }\n\n/* Dashboard */\n.dashboard-header { margin-bottom: 32px; }\n.dashboard-header h1 { font-size: 28px; font-weight: 700; margin: 0 0 8px; }\n.section-title { font-size: 16px; font-weight: 600; margin: 0 0 16px; }\n\n/* Responsive */\n@media (max-width: 1024px) {\n .on-this-page { display: none; }\n}\n@media (max-width: 768px) {\n .sidebar { display: none; }\n .content-body { padding: 20px 16px; }\n .analysis-grid { grid-template-columns: 1fr; }\n .composition-lists { grid-template-columns: 1fr; }\n}`;\n\n return `<style>\\n${css}\\n</style>`;\n}\n","import { generateCSS } from \"../css.js\";\nimport { escapeHtml, slugify } from \"../utils.js\";\n\nexport function sidebarLinks(\n components: string[],\n currentSlug: string | null,\n basePath: string,\n): string {\n const links = components\n .sort()\n .map((name) => {\n const slug = slugify(name);\n const isActive = slug === currentSlug;\n return `<a href=\"${basePath}${slug}.html\" class=\"${isActive ? \"active\" : \"\"}\">${escapeHtml(name)}</a>`;\n })\n .join(\"\\n\");\n\n return `<div class=\"sidebar-heading\">Components</div>\\n${links}`;\n}\n\nexport function htmlShell(options: {\n title: string;\n body: string;\n sidebar: string;\n onThisPage: string;\n basePath: string;\n}): string {\n const { title, body, sidebar, onThisPage, basePath } = options;\n\n return `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <title>${escapeHtml(title)}</title>\n ${generateCSS()}\n</head>\n<body>\n <nav class=\"top-nav\">\n <a class=\"site-title\" href=\"${basePath}index.html\">Scope</a>\n <div class=\"spacer\"></div>\n <input\n class=\"search-box\"\n type=\"search\"\n placeholder=\"Search components…\"\n id=\"sidebar-search\"\n aria-label=\"Search components\"\n />\n </nav>\n <div class=\"page-layout\">\n <nav class=\"sidebar\" id=\"sidebar\">\n ${sidebar}\n </nav>\n <div class=\"main-content\">\n <div class=\"content-body\">\n ${body}\n </div>\n <nav class=\"on-this-page\">\n <h4>On this page</h4>\n ${onThisPage}\n </nav>\n </div>\n </div>\n <script>\n (function () {\n var search = document.getElementById('sidebar-search');\n var sidebar = document.getElementById('sidebar');\n if (!search || !sidebar) return;\n search.addEventListener('input', function () {\n var q = search.value.toLowerCase();\n var links = sidebar.querySelectorAll('a');\n links.forEach(function (link) {\n var text = link.textContent || '';\n link.style.display = text.toLowerCase().includes(q) ? '' : 'none';\n });\n });\n })();\n </script>\n</body>\n</html>`;\n}\n","import type { SiteData } from \"../types.js\";\nimport { escapeHtml, propTableRow, renderDOMTree, slugify } from \"../utils.js\";\nimport { htmlShell, sidebarLinks } from \"./layout.js\";\n\nconst SECTIONS = [\n \"Playground\",\n \"Matrix\",\n \"Docs\",\n \"Analysis\",\n \"X-Ray\",\n \"Tokens\",\n \"Accessibility\",\n \"Composition\",\n \"Responsive\",\n \"Stress Tests\",\n];\n\nfunction notGenerated(message = \"Not generated\"): string {\n return `<div class=\"not-generated\">${escapeHtml(message)}</div>`;\n}\n\nfunction sectionWrap(id: string, title: string, description: string, content: string): string {\n return `<section class=\"section\" id=\"${id}\">\n <div class=\"section-header\">\n <h2>${escapeHtml(title)}</h2>\n <p>${escapeHtml(description)}</p>\n </div>\n ${content}\n</section>`;\n}\n\nfunction renderPlayground(name: string, data: SiteData): string {\n const component = data.manifest.components[name];\n const render = data.renders.get(name);\n\n const props = component ? Object.entries(component.props) : [];\n const propsTable =\n props.length > 0\n ? `<table class=\"props-table\">\n <thead>\n <tr>\n <th>Prop</th>\n <th>Type</th>\n <th>Required</th>\n <th>Default</th>\n </tr>\n </thead>\n <tbody>\n ${props.map(([n, p]) => propTableRow(n, p)).join(\"\\n \")}\n </tbody>\n</table>`\n : `<p style=\"color:var(--color-muted);font-size:13px\">No props defined.</p>`;\n\n const renderHtml = render?.screenshot\n ? `<div class=\"render-preview\">\n <img src=\"data:image/png;base64,${render.screenshot}\" alt=\"${escapeHtml(name)} render\" />\n</div>`\n : notGenerated(\"Render not generated. Run scope render to produce screenshots.\");\n\n return sectionWrap(\n \"playground\",\n \"Playground\",\n \"Props reference and rendered preview.\",\n `${propsTable}\n<div style=\"margin-top:24px\">${renderHtml}</div>`,\n );\n}\n\nfunction renderMatrix(name: string, data: SiteData): string {\n const render = data.renders.get(name);\n\n if (!render?.cells || render.cells.length === 0) {\n return sectionWrap(\n \"matrix\",\n \"Matrix\",\n \"Prop combination matrix renders.\",\n notGenerated(\"Matrix renders not generated. Run scope render --matrix to produce a matrix.\"),\n );\n }\n\n const cells = render.cells;\n const cols = Math.ceil(Math.sqrt(cells.length));\n\n const cellsHtml = cells\n .map((cell) => {\n const label = cell.axisValues.join(\" / \");\n const imgHtml = cell.screenshot\n ? `<img src=\"data:image/png;base64,${cell.screenshot}\" alt=\"${escapeHtml(label)}\" />`\n : `<span style=\"color:var(--color-muted);font-size:11px\">${cell.error ? escapeHtml(cell.error) : \"failed\"}</span>`;\n return `<div class=\"matrix-cell\">${imgHtml}<div class=\"cell-label\">${escapeHtml(label)}</div></div>`;\n })\n .join(\"\\n\");\n\n const grid = `<div class=\"matrix-grid\" style=\"grid-template-columns: repeat(${cols}, 1fr)\">\n${cellsHtml}\n</div>`;\n\n return sectionWrap(\"matrix\", \"Matrix\", \"Prop combination matrix renders.\", grid);\n}\n\nfunction renderDocs(): string {\n return sectionWrap(\n \"docs\",\n \"Docs\",\n \"Component documentation.\",\n `<p style=\"color:var(--color-muted);font-size:13px\">No documentation file found for this component.</p>`,\n );\n}\n\nfunction renderAnalysis(name: string, data: SiteData): string {\n const component = data.manifest.components[name];\n if (!component) {\n return sectionWrap(\"analysis\", \"Analysis\", \"Static analysis results.\", notGenerated());\n }\n\n const propCount = Object.keys(component.props).length;\n const hookCount = component.detectedHooks.length;\n const sideEffectCount =\n component.sideEffects.fetches.length +\n (component.sideEffects.timers ? 1 : 0) +\n component.sideEffects.subscriptions.length +\n (component.sideEffects.globalListeners ? 1 : 0);\n\n const statsGrid = `<div class=\"stats-grid\">\n <div class=\"stat-card\">\n <div class=\"stat-label\">Complexity</div>\n <div class=\"stat-value\"><span class=\"badge ${component.complexityClass}\">${escapeHtml(component.complexityClass)}</span></div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-label\">Props</div>\n <div class=\"stat-value\">${propCount}</div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-label\">Hooks</div>\n <div class=\"stat-value\">${hookCount}</div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-label\">Side Effects</div>\n <div class=\"stat-value\">${sideEffectCount}</div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-label\">Export</div>\n <div class=\"stat-value\" style=\"font-size:14px\">${escapeHtml(component.exportType)}</div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-label\">Memoized</div>\n <div class=\"stat-value\" style=\"font-size:14px\">${component.memoized ? \"Yes\" : \"No\"}</div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-label\">forwardedRef</div>\n <div class=\"stat-value\" style=\"font-size:14px\">${component.forwardedRef ? \"Yes\" : \"No\"}</div>\n </div>\n</div>`;\n\n function tagList(items: string[]): string {\n if (items.length === 0)\n return `<span style=\"color:var(--color-muted);font-size:12px\">None</span>`;\n return `<div class=\"tag-list\">${items.map((i) => `<span class=\"tag\">${escapeHtml(i)}</span>`).join(\"\")}</div>`;\n }\n\n const sideEffectItems: string[] = [\n ...component.sideEffects.fetches.map((f) => `fetch: ${f}`),\n ...(component.sideEffects.timers ? [\"timers\"] : []),\n ...component.sideEffects.subscriptions.map((s) => `sub: ${s}`),\n ...(component.sideEffects.globalListeners ? [\"global listeners\"] : []),\n ];\n\n const analysisGrid = `<div class=\"analysis-grid\">\n <div class=\"analysis-card\">\n <h3>Detected Hooks</h3>\n <div class=\"value\">${tagList(component.detectedHooks)}</div>\n </div>\n <div class=\"analysis-card\">\n <h3>Required Contexts</h3>\n <div class=\"value\">${tagList(component.requiredContexts)}</div>\n </div>\n <div class=\"analysis-card\">\n <h3>HOC Wrappers</h3>\n <div class=\"value\">${tagList(component.hocWrappers)}</div>\n </div>\n <div class=\"analysis-card\">\n <h3>Side Effects</h3>\n <div class=\"value\">${tagList(sideEffectItems)}</div>\n </div>\n</div>`;\n\n return sectionWrap(\n \"analysis\",\n \"Analysis\",\n \"Static analysis results for this component.\",\n `${statsGrid}${analysisGrid}`,\n );\n}\n\nfunction renderXRay(name: string, data: SiteData): string {\n const render = data.renders.get(name);\n\n if (!render?.dom) {\n return sectionWrap(\n \"x-ray\",\n \"X-Ray\",\n \"DOM structure and computed styles.\",\n notGenerated(\"X-Ray data not generated. Run scope render with DOM capture enabled.\"),\n );\n }\n\n const dom = render.dom;\n const treeHtml = `<div class=\"dom-tree\">${renderDOMTree(dom.tree)}</div>`;\n\n const stylesHtml =\n render.computedStyles && Object.keys(render.computedStyles).length > 0\n ? `<details style=\"margin-top:16px\">\n <summary style=\"cursor:pointer;font-size:13px;font-weight:600;margin-bottom:8px\">Computed Styles</summary>\n <table class=\"token-table\" style=\"margin-top:8px\">\n <thead><tr><th>Selector</th><th>Property</th><th>Value</th></tr></thead>\n <tbody>\n ${Object.entries(render.computedStyles)\n .flatMap(([selector, styles]) =>\n Object.entries(styles).map(\n ([prop, val]) =>\n `<tr><td class=\"token-path\">${escapeHtml(selector)}</td><td>${escapeHtml(prop)}</td><td>${escapeHtml(val)}</td></tr>`,\n ),\n )\n .join(\"\\n \")}\n </tbody>\n </table>\n</details>`\n : \"\";\n\n return sectionWrap(\n \"x-ray\",\n \"X-Ray\",\n `DOM structure — ${dom.elementCount} elements.`,\n `${treeHtml}${stylesHtml}`,\n );\n}\n\nfunction renderTokens(name: string, data: SiteData): string {\n if (!data.complianceBatch) {\n return sectionWrap(\n \"tokens\",\n \"Tokens\",\n \"Design token compliance.\",\n notGenerated(\"Compliance data not generated. Run scope tokens to audit design tokens.\"),\n );\n }\n\n const report = data.complianceBatch.components[name];\n if (!report) {\n return sectionWrap(\n \"tokens\",\n \"Tokens\",\n \"Design token compliance.\",\n notGenerated(\"No compliance report found for this component.\"),\n );\n }\n\n const pct = Math.round(report.compliance * 100);\n const barHtml = `<div class=\"compliance-bar-container\">\n <div class=\"compliance-label\">${pct}% on-system (${report.onSystem} / ${report.total} properties)</div>\n <div class=\"compliance-bar-bg\">\n <div class=\"compliance-bar-fill\" style=\"width:${pct}%\"></div>\n </div>\n</div>`;\n\n const rows = Object.entries(report.properties)\n .map(([prop, result]) => {\n const pill =\n result.status === \"on_system\"\n ? `<span class=\"pill-on\">✓ ${escapeHtml(result.token ?? \"\")}</span>`\n : `<span class=\"pill-off\">✗ off-system</span>`;\n\n const swatchStyle = result.value.startsWith(\"#\")\n ? ` style=\"background:${escapeHtml(result.value)}\"`\n : \"\";\n\n const nearestHtml = result.nearest\n ? `<span style=\"color:var(--color-muted);font-size:10px\"> nearest: ${escapeHtml(result.nearest.token)}</span>`\n : \"\";\n\n return `<tr>\n <td class=\"token-path\">${escapeHtml(prop)}</td>\n <td><span class=\"token-value-swatch\"${swatchStyle}></span>${escapeHtml(result.value)}</td>\n <td>${pill}${nearestHtml}</td>\n </tr>`;\n })\n .join(\"\\n \");\n\n const tableHtml = `<table class=\"token-table\">\n <thead><tr><th>Property</th><th>Value</th><th>Status</th></tr></thead>\n <tbody>${rows}</tbody>\n</table>`;\n\n return sectionWrap(\n \"tokens\",\n \"Tokens\",\n \"Design token compliance audit.\",\n `${barHtml}${tableHtml}`,\n );\n}\n\nfunction renderAccessibility(name: string, data: SiteData): string {\n const render = data.renders.get(name);\n\n if (!render?.accessibility) {\n return sectionWrap(\n \"accessibility\",\n \"Accessibility\",\n \"Accessibility audit results.\",\n notGenerated(\n \"Accessibility data not generated. Run scope render with accessibility capture enabled.\",\n ),\n );\n }\n\n const a11y = render.accessibility;\n const roleBadge = `<span class=\"a11y-role-badge\">${escapeHtml(a11y.role)}</span>`;\n\n const violationsHtml =\n a11y.violations.length > 0\n ? `<ul class=\"violation-list\">${a11y.violations.map((v) => `<li>${escapeHtml(v)}</li>`).join(\"\")}</ul>`\n : `<p style=\"color:var(--color-success);font-size:13px\">✓ No violations found.</p>`;\n\n return sectionWrap(\n \"accessibility\",\n \"Accessibility\",\n \"Accessibility audit results.\",\n `<p style=\"font-size:13px;margin:0 0 12px\">Role: ${roleBadge} &nbsp; Name: <em>${escapeHtml(a11y.name || \"(none)\")}</em></p>\n${violationsHtml}`,\n );\n}\n\nfunction renderComposition(name: string, data: SiteData): string {\n const component = data.manifest.components[name];\n\n if (!component || (component.composes.length === 0 && component.composedBy.length === 0)) {\n return sectionWrap(\n \"composition\",\n \"Composition\",\n \"Component dependency graph.\",\n `<p style=\"color:var(--color-muted);font-size:13px\">This component stands alone.</p>`,\n );\n }\n\n function compList(title: string, items: string[]): string {\n if (items.length === 0) {\n return `<div class=\"comp-list\"><h3>${escapeHtml(title)}</h3><p style=\"color:var(--color-muted);font-size:12px\">None</p></div>`;\n }\n const liItems = items\n .map(\n (n) => `<li><a href=\"${data.options.basePath}${slugify(n)}.html\">${escapeHtml(n)}</a></li>`,\n )\n .join(\"\");\n return `<div class=\"comp-list\"><h3>${escapeHtml(title)}</h3><ul>${liItems}</ul></div>`;\n }\n\n return sectionWrap(\n \"composition\",\n \"Composition\",\n \"Component dependency graph.\",\n `<div class=\"composition-lists\">\n ${compList(\"Composes\", component.composes)}\n ${compList(\"Composed By\", component.composedBy)}\n</div>`,\n );\n}\n\nexport function renderComponentDetail(name: string, data: SiteData): string {\n const component = data.manifest.components[name];\n const slug = slugify(name);\n\n const complexityBadge = component\n ? `<span class=\"badge ${component.complexityClass}\">${escapeHtml(component.complexityClass)}</span>`\n : \"\";\n const memoizedBadge = component?.memoized ? `<span class=\"badge memoized\">memo</span>` : \"\";\n const exportBadge = component\n ? `<span class=\"badge\">${escapeHtml(component.exportType)}</span>`\n : \"\";\n const filepath = component ? `<div class=\"filepath\">${escapeHtml(component.filePath)}</div>` : \"\";\n\n const header = `<div class=\"component-header\">\n <h1>${escapeHtml(name)}</h1>\n <div class=\"meta\">${complexityBadge}${memoizedBadge}${exportBadge}</div>\n ${filepath}\n</div>`;\n\n const sections = [\n renderPlayground(name, data),\n renderMatrix(name, data),\n renderDocs(),\n renderAnalysis(name, data),\n renderXRay(name, data),\n renderTokens(name, data),\n renderAccessibility(name, data),\n renderComposition(name, data),\n sectionWrap(\n \"responsive\",\n \"Responsive\",\n \"Multi-viewport renders.\",\n notGenerated(\n \"Responsive renders not generated. Multi-viewport rendering is a future feature.\",\n ),\n ),\n sectionWrap(\n \"stress-tests\",\n \"Stress Tests\",\n \"Edge case and stress test renders.\",\n notGenerated(\"Stress tests not generated. Stress render runs are a future feature.\"),\n ),\n ];\n\n const body = `${header}${sections.join(\"\\n\")}`;\n\n const onThisPage = SECTIONS.map((s) => {\n const id = s.toLowerCase().replace(/\\s+/g, \"-\");\n return `<a href=\"#${id}\">${escapeHtml(s)}</a>`;\n }).join(\"\\n\");\n\n const componentNames = Object.keys(data.manifest.components);\n const sidebar = sidebarLinks(componentNames, slug, data.options.basePath);\n\n return htmlShell({\n title: `${name} — ${data.options.title}`,\n body,\n sidebar,\n onThisPage,\n basePath: data.options.basePath,\n });\n}\n","import type { SiteData } from \"../types.js\";\nimport { escapeHtml, slugify } from \"../utils.js\";\nimport { htmlShell, sidebarLinks } from \"./layout.js\";\n\nexport function renderComponentIndex(data: SiteData): string {\n const components = Object.entries(data.manifest.components);\n const totalCount = components.length;\n const simpleCount = components.filter(([, c]) => c.complexityClass === \"simple\").length;\n const complexCount = components.filter(([, c]) => c.complexityClass === \"complex\").length;\n const memoizedCount = components.filter(([, c]) => c.memoized).length;\n\n const statsGrid = `<div class=\"stats-grid\">\n <div class=\"stat-card\">\n <div class=\"stat-label\">Total Components</div>\n <div class=\"stat-value\">${totalCount}</div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-label\">Simple</div>\n <div class=\"stat-value\">${simpleCount}</div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-label\">Complex</div>\n <div class=\"stat-value\">${complexCount}</div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-label\">Memoized</div>\n <div class=\"stat-value\">${memoizedCount}</div>\n </div>\n</div>`;\n\n const cards = components\n .sort(([a], [b]) => a.localeCompare(b))\n .map(([name, component]) => {\n const slug = slugify(name);\n const render = data.renders.get(name);\n const propCount = Object.keys(component.props).length;\n const hookCount = component.detectedHooks.length;\n\n const previewHtml = render?.screenshot\n ? `<img src=\"data:image/png;base64,${render.screenshot}\" alt=\"${escapeHtml(name)}\" />`\n : `<span class=\"no-preview\">No preview</span>`;\n\n return `<a class=\"component-card\" href=\"${data.options.basePath}${slug}.html\" data-name=\"${escapeHtml(name.toLowerCase())}\">\n <div class=\"card-preview\">${previewHtml}</div>\n <div class=\"card-body\">\n <div class=\"card-name\">${escapeHtml(name)}</div>\n <div class=\"card-meta\">\n <span>${propCount} props</span>\n <span class=\"badge ${component.complexityClass}\" style=\"font-size:10px\">${escapeHtml(component.complexityClass)}</span>\n ${hookCount > 0 ? `<span>${hookCount} hooks</span>` : \"\"}\n </div>\n </div>\n</a>`;\n })\n .join(\"\\n\");\n\n const cardGrid = `<div class=\"component-grid\" id=\"component-grid\">${cards}</div>`;\n\n const filterScript = `<script>\n(function () {\n var grid = document.getElementById('component-grid');\n var search = document.getElementById('sidebar-search');\n if (!grid || !search) return;\n var indexSearch = document.getElementById('index-search');\n function filter(q) {\n var cards = grid.querySelectorAll('.component-card');\n cards.forEach(function (card) {\n var name = card.getAttribute('data-name') || '';\n card.style.display = name.includes(q) ? '' : 'none';\n });\n }\n search.addEventListener('input', function () { filter(search.value.toLowerCase()); });\n if (indexSearch) {\n indexSearch.addEventListener('input', function () { filter(indexSearch.value.toLowerCase()); });\n }\n})();\n</script>`;\n\n const header = `<div class=\"index-header\">\n <h1>${escapeHtml(data.options.title)}</h1>\n <p>${totalCount} component${totalCount === 1 ? \"\" : \"s\"} analysed</p>\n <input class=\"search-box\" type=\"search\" id=\"index-search\" placeholder=\"Filter components…\" style=\"margin-top:12px\" />\n</div>`;\n\n const body = `${header}${statsGrid}${cardGrid}${filterScript}`;\n\n const componentNames = Object.keys(data.manifest.components);\n const sidebar = sidebarLinks(componentNames, null, data.options.basePath);\n\n const onThisPage = `<a href=\"#top\">Overview</a>\\n<a href=\"#component-grid\">Components</a>`;\n\n return htmlShell({\n title: data.options.title,\n body,\n sidebar,\n onThisPage,\n basePath: data.options.basePath,\n });\n}\n","import type { SiteData } from \"../types.js\";\nimport { escapeHtml, slugify } from \"../utils.js\";\nimport { htmlShell, sidebarLinks } from \"./layout.js\";\n\nexport function renderDashboard(data: SiteData): string {\n const components = Object.entries(data.manifest.components);\n const totalCount = components.length;\n\n const simpleCount = components.filter(([, c]) => c.complexityClass === \"simple\").length;\n const complexCount = components.filter(([, c]) => c.complexityClass === \"complex\").length;\n const renderedCount = components.filter(([name]) => data.renders.has(name)).length;\n\n const totalProps = components.reduce((sum, [, c]) => sum + Object.keys(c.props).length, 0);\n const avgProps = totalCount > 0 ? Math.round(totalProps / totalCount) : 0;\n\n let overallCompliance: number | null = null;\n if (data.complianceBatch) {\n const reports = Object.values(data.complianceBatch.components);\n if (reports.length > 0) {\n overallCompliance = Math.round(\n (reports.reduce((sum, r) => sum + r.compliance, 0) / reports.length) * 100,\n );\n }\n }\n\n const statsGrid = `<div class=\"stats-grid\" style=\"margin-bottom:32px\">\n <div class=\"stat-card\">\n <div class=\"stat-label\">Total Components</div>\n <div class=\"stat-value\">${totalCount}</div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-label\">Avg Props</div>\n <div class=\"stat-value\">${avgProps}</div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-label\">With Renders</div>\n <div class=\"stat-value\">${renderedCount}</div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-label\">Compliance</div>\n <div class=\"stat-value\">${overallCompliance !== null ? `${overallCompliance}%` : \"—\"}</div>\n </div>\n</div>`;\n\n // Complexity breakdown\n const complexitySection = `<div class=\"section\" style=\"padding:24px 0;border-bottom:1px solid var(--color-border)\">\n <h2 class=\"section-title\">Complexity Breakdown</h2>\n <div class=\"stats-grid\">\n <div class=\"stat-card\">\n <div class=\"stat-label\">Simple</div>\n <div class=\"stat-value\" style=\"color:var(--color-success)\">${simpleCount}</div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-label\">Complex</div>\n <div class=\"stat-value\" style=\"color:var(--color-warn)\">${complexCount}</div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-label\">Simple %</div>\n <div class=\"stat-value\">${totalCount > 0 ? Math.round((simpleCount / totalCount) * 100) : 0}%</div>\n </div>\n </div>\n</div>`;\n\n // Top components by prop count\n const topByProps = components\n .sort(([, a], [, b]) => Object.keys(b.props).length - Object.keys(a.props).length)\n .slice(0, 10);\n\n const topPropsRows = topByProps\n .map(([name, component]) => {\n const slug = slugify(name);\n const propCount = Object.keys(component.props).length;\n return `<tr>\n <td><a href=\"${data.options.basePath}${slug}.html\" style=\"color:var(--color-accent);text-decoration:none\">${escapeHtml(name)}</a></td>\n <td>${propCount}</td>\n <td><span class=\"badge ${component.complexityClass}\">${escapeHtml(component.complexityClass)}</span></td>\n </tr>`;\n })\n .join(\"\\n \");\n\n const topPropsSection = `<div class=\"section\" style=\"padding:24px 0;border-bottom:1px solid var(--color-border)\">\n <h2 class=\"section-title\">Top Components by Prop Count</h2>\n <table class=\"props-table\">\n <thead><tr><th>Component</th><th>Props</th><th>Complexity</th></tr></thead>\n <tbody>${topPropsRows}</tbody>\n </table>\n</div>`;\n\n // Compliance section\n let complianceSection = \"\";\n if (data.complianceBatch && overallCompliance !== null) {\n const complianceRows = Object.entries(data.complianceBatch.components)\n .sort(([, a], [, b]) => b.compliance - a.compliance)\n .map(([name, report]) => {\n const pct = Math.round(report.compliance * 100);\n const slug = slugify(name);\n const barHtml = `<div class=\"compliance-bar-bg\" style=\"min-width:120px\">\n <div class=\"compliance-bar-fill\" style=\"width:${pct}%\"></div>\n </div>`;\n return `<tr>\n <td><a href=\"${data.options.basePath}${slug}.html\" style=\"color:var(--color-accent);text-decoration:none\">${escapeHtml(name)}</a></td>\n <td>${pct}%</td>\n <td>${barHtml}</td>\n <td>${report.onSystem} / ${report.total}</td>\n </tr>`;\n })\n .join(\"\\n \");\n\n complianceSection = `<div class=\"section\" style=\"padding:24px 0\">\n <h2 class=\"section-title\">Design Token Compliance — ${overallCompliance}% overall</h2>\n <table class=\"props-table\">\n <thead><tr><th>Component</th><th>Score</th><th>Bar</th><th>On-System</th></tr></thead>\n <tbody>${complianceRows}</tbody>\n </table>\n</div>`;\n }\n\n const header = `<div class=\"dashboard-header\">\n <h1>Dashboard</h1>\n <p style=\"color:var(--color-muted);font-size:14px\">Overview of all ${totalCount} analysed components.</p>\n</div>`;\n\n const body = `${header}${statsGrid}${complexitySection}${topPropsSection}${complianceSection}`;\n\n const componentNames = Object.keys(data.manifest.components);\n const sidebar = sidebarLinks(componentNames, null, data.options.basePath);\n\n const onThisPage = `<a href=\"#top\">Overview</a>\n<a href=\"#complexity\">Complexity</a>\n<a href=\"#top-props\">Top by Props</a>\n${data.complianceBatch ? '<a href=\"#compliance\">Compliance</a>' : \"\"}`;\n\n return htmlShell({\n title: `Dashboard — ${data.options.title}`,\n body,\n sidebar,\n onThisPage,\n basePath: data.options.basePath,\n });\n}\n","import { mkdir, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { normalizeOptions, readSiteData } from \"./reader.js\";\nimport { renderComponentDetail } from \"./templates/component-detail.js\";\nimport { renderComponentIndex } from \"./templates/component-index.js\";\nimport { renderDashboard } from \"./templates/dashboard.js\";\nimport type { SiteOptions } from \"./types.js\";\nimport { slugify } from \"./utils.js\";\n\nexport async function buildSite(options?: SiteOptions): Promise<void> {\n const normalizedOptions = normalizeOptions(options);\n\n console.log(`[scope/site] Reading data from ${normalizedOptions.inputDir}…`);\n const data = await readSiteData(normalizedOptions);\n\n const componentNames = Object.keys(data.manifest.components);\n console.log(`[scope/site] Found ${componentNames.length} components.`);\n\n // Create output directory\n await mkdir(normalizedOptions.outputDir, { recursive: true });\n\n // Generate component detail pages\n for (const name of componentNames) {\n const slug = slugify(name);\n const html = renderComponentDetail(name, data);\n const outputPath = join(normalizedOptions.outputDir, `${slug}.html`);\n await writeFile(outputPath, html, \"utf-8\");\n console.log(`[scope/site] ✓ ${name} → ${slug}.html`);\n }\n\n // Generate index page\n const indexHtml = renderComponentIndex(data);\n await writeFile(join(normalizedOptions.outputDir, \"index.html\"), indexHtml, \"utf-8\");\n console.log(`[scope/site] ✓ index.html`);\n\n // Generate dashboard page\n const dashboardHtml = renderDashboard(data);\n await writeFile(join(normalizedOptions.outputDir, \"dashboard.html\"), dashboardHtml, \"utf-8\");\n console.log(`[scope/site] ✓ dashboard.html`);\n\n console.log(\n `[scope/site] Done. Site written to ${normalizedOptions.outputDir} (${componentNames.length + 2} files).`,\n );\n}\n"]}
1
+ {"version":3,"sources":["../src/reader.ts","../src/utils.ts","../src/css.ts","../src/templates/layout.ts","../src/templates/component-detail.ts","../src/templates/component-index.ts","../src/templates/dashboard.ts","../src/builder.ts"],"names":["readFile","join","readdir","mkdir","writeFile"],"mappings":"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AAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;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","file":"index.cjs","sourcesContent":["import { readdir, readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport type {\n ComplianceBatchData,\n ManifestData,\n RenderFileData,\n SiteData,\n SiteOptions,\n} from \"./types.js\";\n\nfunction normalizeOptions(options?: SiteOptions): Required<SiteOptions> {\n return {\n inputDir: options?.inputDir ?? \".reactscope\",\n outputDir: options?.outputDir ?? \".reactscope/site\",\n basePath: options?.basePath ?? \"/\",\n compliancePath: options?.compliancePath ?? \"\",\n title: options?.title ?? \"Scope — Component Gallery\",\n };\n}\n\nexport { normalizeOptions };\n\nasync function readJsonFile<T>(filePath: string): Promise<T> {\n const content = await readFile(filePath, \"utf-8\");\n return JSON.parse(content) as T;\n}\n\nexport async function readSiteData(options: Required<SiteOptions>): Promise<SiteData> {\n // 1. Read manifest\n const manifestPath = join(options.inputDir, \"manifest.json\");\n const manifest = await readJsonFile<ManifestData>(manifestPath);\n\n // 2. Scan renders directory\n const renders = new Map<string, RenderFileData>();\n const rendersDir = join(options.inputDir, \"renders\");\n\n try {\n const entries = await readdir(rendersDir);\n const jsonFiles = entries.filter((f) => f.endsWith(\".json\"));\n\n await Promise.all(\n jsonFiles.map(async (file) => {\n const componentName = file.replace(/\\.json$/, \"\");\n const filePath = join(rendersDir, file);\n try {\n const renderData = await readJsonFile<RenderFileData>(filePath);\n renders.set(componentName, renderData);\n } catch (err) {\n console.warn(\n `[scope/site] Warning: could not read render file ${filePath}:`,\n err instanceof Error ? err.message : String(err),\n );\n }\n }),\n );\n } catch {\n // renders directory may not exist — that's fine\n }\n\n // 3. Optionally read compliance JSON\n let complianceBatch: ComplianceBatchData | undefined;\n if (options.compliancePath) {\n try {\n complianceBatch = await readJsonFile<ComplianceBatchData>(options.compliancePath);\n } catch (err) {\n console.warn(\n `[scope/site] Warning: could not read compliance file ${options.compliancePath}:`,\n err instanceof Error ? err.message : String(err),\n );\n }\n }\n\n return {\n manifest,\n renders,\n complianceBatch,\n options,\n };\n}\n","import type { DOMNodeData, PropData } from \"./types.js\";\n\nexport function escapeHtml(str: string): string {\n return str\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\")\n .replace(/'/g, \"&#39;\");\n}\n\nexport function slugify(name: string): string {\n return name\n .replace(/([A-Z])/g, (m) => `-${m.toLowerCase()}`)\n .replace(/^-/, \"\")\n .replace(/[^a-z0-9-]/g, \"-\")\n .replace(/-+/g, \"-\")\n .replace(/^-|-$/g, \"\");\n}\n\nexport function syntaxHighlightJSX(code: string): string {\n const escaped = escapeHtml(code);\n\n return (\n escaped\n // Comments\n .replace(/(\\/\\/[^\\n]*)/g, '<span class=\"token-comment\">$1</span>')\n .replace(/(\\/\\*[\\s\\S]*?\\*\\/)/g, '<span class=\"token-comment\">$1</span>')\n // JSX tags\n .replace(/(&lt;\\/?)([\\w.]+)/g, '<span class=\"token-tag\">$1$2</span>')\n // JSX attributes (word followed by =)\n .replace(/\\b([\\w-]+)(?==)/g, '<span class=\"token-attr\">$1</span>')\n // Strings\n .replace(\n /(&quot;[^&]*&quot;|&#39;[^&]*&#39;|`[^`]*`)/g,\n '<span class=\"token-string\">$1</span>',\n )\n // Keywords\n .replace(\n /\\b(import|export|from|default|const|let|var|function|return|if|else|for|while|class|extends|type|interface|async|await|new|typeof|instanceof)\\b/g,\n '<span class=\"token-keyword\">$1</span>',\n )\n // Numbers\n .replace(/\\b(\\d+\\.?\\d*)\\b/g, '<span class=\"token-number\">$1</span>')\n );\n}\n\nexport function renderDOMTree(node: DOMNodeData, depth = 0): string {\n const indent = \" \".repeat(depth);\n\n // Filter to a short display version of attrs (skip long class strings for the summary line)\n const attrsHtml = Object.entries(node.attrs)\n .map(([k, v]) => {\n const display = v.length > 60 ? v.slice(0, 57) + \"…\" : v;\n return ` <span class=\"dom-attr-name\">${escapeHtml(k)}</span>=<span class=\"dom-attr-value\">\"${escapeHtml(display)}\"</span>`;\n })\n .join(\"\");\n\n const nodeIdAttr = node.nodeId !== undefined ? ` data-node-id=\"${node.nodeId}\"` : \"\";\n const clickable = node.nodeId !== undefined ? \" dom-node-clickable\" : \"\";\n\n const hasChildren = node.children.length > 0;\n const hasText = node.text !== undefined && node.text.trim().length > 0;\n\n if (!hasChildren && !hasText) {\n return `${indent}<span class=\"dom-tag-open${clickable}\"${nodeIdAttr}>&lt;${escapeHtml(node.tag)}${attrsHtml} /&gt;</span>\\n`;\n }\n\n const childrenHtml = node.children.map((child) => renderDOMTree(child, depth + 1)).join(\"\");\n const textHtml = hasText\n ? `${indent} <span class=\"dom-text\">${escapeHtml(node.text ?? \"\")}</span>\\n`\n : \"\";\n\n return `<details class=\"dom-node${clickable}\" ${depth < 2 ? \"open\" : \"\"}${nodeIdAttr}>\n${indent}<summary><span class=\"dom-tag-open\">&lt;${escapeHtml(node.tag)}${attrsHtml}&gt;</span></summary>\n${textHtml}${childrenHtml}${indent}<span class=\"dom-tag-close\">&lt;/${escapeHtml(node.tag)}&gt;</span>\n</details>`;\n}\n\nexport function propTableRow(name: string, prop: PropData): string {\n const valuesHtml =\n prop.values && prop.values.length > 0\n ? `<br><span style=\"color:var(--color-muted);font-size:11px\">${prop.values.map((v) => escapeHtml(v)).join(\" | \")}</span>`\n : \"\";\n\n const defaultHtml = prop.default !== undefined ? escapeHtml(prop.default) : \"—\";\n\n return `<tr>\n <td><span class=\"prop-name\">${escapeHtml(name)}</span></td>\n <td><span class=\"prop-type\">${escapeHtml(prop.type)}</span>${valuesHtml}</td>\n <td>${prop.required ? '<span class=\"prop-required\">required</span>' : '<span style=\"color:var(--color-muted)\">optional</span>'}</td>\n <td><span class=\"prop-default\">${defaultHtml}</span></td>\n </tr>`;\n}\n","export function generateCSS(): string {\n const css = `@import url('https://fonts.googleapis.com/css2?family=Inter:wght@100..900&family=JetBrains+Mono:wght@400;700&display=swap');\n\n:root {\n --color-text: #0f0f0f;\n --color-muted: #6b7280;\n --color-border: #e5e7eb;\n --color-bg: #ffffff;\n --color-bg-subtle: #f9fafb;\n --color-bg-code: #1a1a2e;\n --color-accent: #2563eb;\n --color-success: #16a34a;\n --color-warn: #d97706;\n --color-error: #dc2626;\n --font-body: 'Inter', system-ui, -apple-system, sans-serif;\n --font-mono: 'JetBrains Mono', 'Fira Code', monospace;\n --radius: 6px;\n --shadow-sm: 0 1px 2px rgba(0,0,0,0.05);\n --shadow: 0 1px 3px rgba(0,0,0,0.1), 0 1px 2px rgba(0,0,0,0.06);\n}\n\n*, *::before, *::after { box-sizing: border-box; }\n\nbody {\n font-family: var(--font-body);\n font-size: 14px;\n line-height: 1.6;\n color: var(--color-text);\n background: var(--color-bg);\n margin: 0;\n}\n\n/* Top nav */\n.top-nav {\n position: sticky;\n top: 0;\n z-index: 100;\n background: var(--color-bg);\n border-bottom: 1px solid var(--color-border);\n height: 52px;\n display: flex;\n align-items: center;\n padding: 0 24px;\n gap: 16px;\n}\n.top-nav .site-title { font-weight: 600; font-size: 15px; text-decoration: none; color: var(--color-text); }\n.top-nav .spacer { flex: 1; }\n.search-box {\n border: 1px solid var(--color-border);\n border-radius: var(--radius);\n padding: 6px 12px;\n font-family: var(--font-body);\n font-size: 13px;\n width: 240px;\n outline: none;\n background: var(--color-bg-subtle);\n}\n.search-box:focus { border-color: var(--color-accent); background: var(--color-bg); }\n\n/* Page layout */\n.page-layout {\n display: flex;\n min-height: calc(100vh - 52px);\n}\n\n/* Left sidebar (component list) */\n.sidebar {\n width: 220px;\n min-width: 220px;\n border-right: 1px solid var(--color-border);\n padding: 16px 0;\n position: sticky;\n top: 52px;\n height: calc(100vh - 52px);\n overflow-y: auto;\n}\n.sidebar-heading {\n font-size: 11px;\n font-weight: 600;\n letter-spacing: 0.06em;\n text-transform: uppercase;\n color: var(--color-muted);\n padding: 4px 16px 8px;\n}\n.sidebar a {\n display: block;\n padding: 5px 16px;\n font-size: 13px;\n color: var(--color-text);\n text-decoration: none;\n border-radius: 0;\n}\n.sidebar a:hover { background: var(--color-bg-subtle); }\n.sidebar a.active { color: var(--color-accent); font-weight: 500; }\n\n/* Main content */\n.main-content {\n flex: 1;\n min-width: 0;\n display: flex;\n}\n.content-body {\n flex: 1;\n min-width: 0;\n padding: 32px 40px;\n max-width: 900px;\n}\n\n/* On this page nav (right side) */\n.on-this-page {\n width: 200px;\n min-width: 200px;\n padding: 32px 16px;\n position: sticky;\n top: 52px;\n height: calc(100vh - 52px);\n overflow-y: auto;\n}\n.on-this-page h4 {\n font-size: 11px;\n font-weight: 600;\n letter-spacing: 0.06em;\n text-transform: uppercase;\n color: var(--color-muted);\n margin: 0 0 8px;\n}\n.on-this-page a {\n display: block;\n padding: 3px 0;\n font-size: 12px;\n color: var(--color-muted);\n text-decoration: none;\n}\n.on-this-page a:hover { color: var(--color-text); }\n\n/* Component header */\n.component-header { margin-bottom: 32px; }\n.component-header h1 { font-size: 28px; font-weight: 700; margin: 0 0 8px; }\n.component-header .meta {\n display: flex;\n gap: 8px;\n align-items: center;\n flex-wrap: wrap;\n margin-bottom: 8px;\n}\n.badge {\n display: inline-flex;\n align-items: center;\n padding: 2px 8px;\n border-radius: 999px;\n font-size: 11px;\n font-weight: 500;\n border: 1px solid var(--color-border);\n color: var(--color-muted);\n background: var(--color-bg-subtle);\n}\n.badge.complex { border-color: #fbbf24; color: #92400e; background: #fffbeb; }\n.badge.simple { border-color: #6ee7b7; color: #065f46; background: #ecfdf5; }\n.badge.memoized { border-color: #a5b4fc; color: #3730a3; background: #eef2ff; }\n\n.filepath {\n font-family: var(--font-mono);\n font-size: 12px;\n color: var(--color-muted);\n}\n\n/* Sections */\n.section {\n padding: 32px 0;\n border-bottom: 1px solid var(--color-border);\n}\n.section:last-child { border-bottom: none; }\n.section-header { margin-bottom: 20px; }\n.section-header h2 {\n font-size: 18px;\n font-weight: 600;\n margin: 0 0 4px;\n}\n.section-header p { color: var(--color-muted); margin: 0; font-size: 13px; }\n\n/* Not generated placeholder */\n.not-generated {\n background: var(--color-bg-subtle);\n border: 1px dashed var(--color-border);\n border-radius: var(--radius);\n padding: 32px;\n text-align: center;\n color: var(--color-muted);\n font-size: 13px;\n}\n\n/* Render preview */\n.render-preview {\n border: 1px solid var(--color-border);\n border-radius: var(--radius);\n overflow: hidden;\n background: #f8f8f8;\n display: inline-block;\n max-width: 100%;\n}\n.render-preview img { display: block; max-width: 100%; }\n.scope-screenshot { zoom: 0.5; display: block; image-rendering: -webkit-optimize-contrast; }\n\n/* Props table */\n.props-table { width: 100%; border-collapse: collapse; font-size: 13px; }\n.props-table th {\n text-align: left;\n font-weight: 600;\n font-size: 11px;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n color: var(--color-muted);\n padding: 8px 12px;\n border-bottom: 2px solid var(--color-border);\n}\n.props-table td {\n padding: 8px 12px;\n border-bottom: 1px solid var(--color-border);\n vertical-align: top;\n}\n.props-table tr:last-child td { border-bottom: none; }\n.prop-name { font-family: var(--font-mono); font-size: 12px; font-weight: 700; }\n.prop-type { font-family: var(--font-mono); font-size: 11px; color: var(--color-accent); }\n.prop-required { color: var(--color-error); font-size: 11px; }\n.prop-default { font-family: var(--font-mono); font-size: 11px; color: var(--color-muted); }\n\n/* Code blocks */\npre.code-block {\n background: var(--color-bg-code);\n color: #e2e8f0;\n border-radius: var(--radius);\n padding: 16px 20px;\n overflow-x: auto;\n font-family: var(--font-mono);\n font-size: 13px;\n line-height: 1.6;\n margin: 0;\n}\n.token-keyword { color: #c792ea; }\n.token-string { color: #c3e88d; }\n.token-comment { color: #546e7a; font-style: italic; }\n.token-tag { color: #f07178; }\n.token-attr { color: #ffcb6b; }\n.token-number { color: #f78c6c; }\n\n/* Stats grid */\n.stats-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));\n gap: 12px;\n margin-bottom: 24px;\n}\n.stat-card {\n background: var(--color-bg-subtle);\n border: 1px solid var(--color-border);\n border-radius: var(--radius);\n padding: 16px;\n}\n.stat-card .stat-label { font-size: 11px; color: var(--color-muted); text-transform: uppercase; letter-spacing: 0.05em; margin-bottom: 4px; }\n.stat-card .stat-value { font-size: 22px; font-weight: 700; }\n\n/* Analysis grid */\n.analysis-grid {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 16px;\n}\n.analysis-card {\n background: var(--color-bg-subtle);\n border: 1px solid var(--color-border);\n border-radius: var(--radius);\n padding: 16px;\n}\n.analysis-card h3 { font-size: 12px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; color: var(--color-muted); margin: 0 0 8px; }\n.analysis-card .value { font-size: 14px; }\n.tag-list { display: flex; flex-wrap: wrap; gap: 4px; }\n.tag {\n display: inline-block;\n padding: 2px 8px;\n background: var(--color-border);\n border-radius: 4px;\n font-family: var(--font-mono);\n font-size: 11px;\n}\n\n/* Token pills */\n.pill-on {\n display: inline-flex; align-items: center; gap: 4px;\n padding: 2px 8px; border-radius: 999px;\n background: #dcfce7; color: #166534;\n font-size: 11px; font-weight: 500;\n}\n.pill-off {\n display: inline-flex; align-items: center; gap: 4px;\n padding: 2px 8px; border-radius: 999px;\n background: #fef3c7; color: #92400e;\n font-size: 11px; font-weight: 500;\n}\n\n/* Compliance bar */\n.compliance-bar-container { margin-bottom: 16px; }\n.compliance-bar-bg { background: var(--color-border); border-radius: 999px; height: 8px; overflow: hidden; }\n.compliance-bar-fill { height: 100%; border-radius: 999px; background: var(--color-success); }\n.compliance-label { font-size: 13px; color: var(--color-muted); margin-bottom: 4px; }\n\n/* Token table */\n.token-table { width: 100%; border-collapse: collapse; font-size: 12px; }\n.token-table th {\n text-align: left; font-weight: 600; font-size: 11px;\n text-transform: uppercase; letter-spacing: 0.05em;\n color: var(--color-muted); padding: 6px 10px;\n border-bottom: 2px solid var(--color-border);\n}\n.token-table td { padding: 6px 10px; border-bottom: 1px solid var(--color-border); vertical-align: top; }\n.token-table tr:last-child td { border-bottom: none; }\n.token-path { font-family: var(--font-mono); color: var(--color-accent); }\n.token-value-swatch { display: inline-block; width: 12px; height: 12px; border-radius: 2px; border: 1px solid var(--color-border); margin-right: 4px; vertical-align: middle; }\n\n/* A11y violations */\n.violation-list { list-style: none; padding: 0; margin: 0; }\n.violation-list li {\n padding: 8px 12px;\n background: #fef2f2;\n border: 1px solid #fecaca;\n border-radius: var(--radius);\n margin-bottom: 6px;\n font-size: 13px;\n color: #991b1b;\n}\n.a11y-role-badge { font-family: var(--font-mono); font-size: 11px; background: var(--color-bg-subtle); border: 1px solid var(--color-border); padding: 2px 6px; border-radius: 4px; }\n\n/* Matrix grid */\n.matrix-grid {\n display: grid;\n gap: 1px;\n background: var(--color-border);\n border: 1px solid var(--color-border);\n border-radius: var(--radius);\n overflow: hidden;\n}\n.matrix-cell { background: var(--color-bg); padding: 8px; text-align: center; }\n.matrix-cell img { border-radius: 2px; }\n.matrix-cell .cell-label { font-size: 10px; color: var(--color-muted); margin-top: 4px; }\n.matrix-header { background: var(--color-bg-subtle); padding: 6px 8px; font-size: 11px; font-weight: 600; color: var(--color-muted); }\n\n/* DOM tree */\n.dom-tree { font-family: var(--font-mono); font-size: 12px; line-height: 1.8; }\ndetails.dom-node > summary { cursor: pointer; list-style: none; }\ndetails.dom-node > summary::-webkit-details-marker { display: none; }\n.dom-tag-open { color: #f07178; }\n.dom-tag-close { color: #f07178; }\n.dom-attr-name { color: #ffcb6b; }\n.dom-attr-value { color: #c3e88d; }\n.dom-text { color: #82aaff; font-style: italic; }\n.dom-node-clickable { cursor: pointer; border-radius: 3px; transition: background 0.1s; }\n.dom-node-clickable:hover, details.dom-node-clickable > summary:hover { background: rgba(255,255,255,0.08); }\n.dom-node-selected, details.dom-node-selected > summary { background: rgba(99,179,237,0.15) !important; outline: 1px solid rgba(99,179,237,0.4); border-radius: 3px; }\n.dom-attr-name { color: #ffcb6b; }\n.dom-attr-value { color: #c3e88d; }\n.dom-text { color: #a0a0b0; font-style: italic; }\n\n/* Composition graph */\n.composition-lists { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }\n.comp-list h3 { font-size: 13px; font-weight: 600; margin: 0 0 8px; color: var(--color-muted); }\n.comp-list ul { list-style: none; padding: 0; margin: 0; }\n.comp-list li { padding: 4px 0; font-size: 13px; border-bottom: 1px solid var(--color-border); }\n.comp-list a { color: var(--color-accent); text-decoration: none; }\n.comp-list a:hover { text-decoration: underline; }\n\n/* Index page */\n.index-header { margin-bottom: 32px; }\n.index-header h1 { font-size: 32px; font-weight: 700; margin: 0 0 8px; }\n.index-header p { color: var(--color-muted); font-size: 15px; margin: 0; }\n.component-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));\n gap: 16px;\n}\n.component-card {\n border: 1px solid var(--color-border);\n border-radius: var(--radius);\n overflow: hidden;\n text-decoration: none;\n color: var(--color-text);\n transition: box-shadow 0.15s;\n display: block;\n}\n.component-card:hover { box-shadow: var(--shadow); }\n.card-preview {\n background: #f8f8f8;\n height: 160px;\n overflow: hidden;\n display: flex;\n align-items: center;\n justify-content: center;\n border-bottom: 1px solid var(--color-border);\n}\n.card-preview img { object-fit: contain; }\n.card-preview .no-preview { color: var(--color-muted); font-size: 12px; }\n.card-body { padding: 12px 16px; }\n.card-name { font-weight: 600; font-size: 14px; margin-bottom: 4px; }\n.card-meta { font-size: 12px; color: var(--color-muted); display: flex; gap: 8px; }\n\n/* Dashboard */\n.dashboard-header { margin-bottom: 32px; }\n.dashboard-header h1 { font-size: 28px; font-weight: 700; margin: 0 0 8px; }\n.section-title { font-size: 16px; font-weight: 600; margin: 0 0 16px; }\n\n/* Responsive */\n@media (max-width: 1024px) {\n .on-this-page { display: none; }\n}\n@media (max-width: 768px) {\n .sidebar { display: none; }\n .content-body { padding: 20px 16px; }\n .analysis-grid { grid-template-columns: 1fr; }\n .composition-lists { grid-template-columns: 1fr; }\n}`;\n\n return `<style>\\n${css}\\n</style>`;\n}\n","import { generateCSS } from \"../css.js\";\nimport { escapeHtml, slugify } from \"../utils.js\";\n\nexport function sidebarLinks(\n components: string[],\n currentSlug: string | null,\n basePath: string,\n): string {\n const links = components\n .sort()\n .map((name) => {\n const slug = slugify(name);\n const isActive = slug === currentSlug;\n return `<a href=\"${basePath}${slug}.html\" class=\"${isActive ? \"active\" : \"\"}\">${escapeHtml(name)}</a>`;\n })\n .join(\"\\n\");\n\n return `<div class=\"sidebar-heading\">Components</div>\\n${links}`;\n}\n\nexport function htmlShell(options: {\n title: string;\n body: string;\n sidebar: string;\n onThisPage: string;\n basePath: string;\n}): string {\n const { title, body, sidebar, onThisPage, basePath } = options;\n\n return `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <title>${escapeHtml(title)}</title>\n ${generateCSS()}\n</head>\n<body>\n <nav class=\"top-nav\">\n <a class=\"site-title\" href=\"${basePath}index.html\">Scope</a>\n <div class=\"spacer\"></div>\n <input\n class=\"search-box\"\n type=\"search\"\n placeholder=\"Search components…\"\n id=\"sidebar-search\"\n aria-label=\"Search components\"\n />\n </nav>\n <div class=\"page-layout\">\n <nav class=\"sidebar\" id=\"sidebar\">\n ${sidebar}\n </nav>\n <div class=\"main-content\">\n <div class=\"content-body\">\n ${body}\n </div>\n <nav class=\"on-this-page\">\n <h4>On this page</h4>\n ${onThisPage}\n </nav>\n </div>\n </div>\n <script>\n (function () {\n var search = document.getElementById('sidebar-search');\n var sidebar = document.getElementById('sidebar');\n if (!search || !sidebar) return;\n search.addEventListener('input', function () {\n var q = search.value.toLowerCase();\n var links = sidebar.querySelectorAll('a');\n links.forEach(function (link) {\n var text = link.textContent || '';\n link.style.display = text.toLowerCase().includes(q) ? '' : 'none';\n });\n });\n })();\n </script>\n</body>\n</html>`;\n}\n","import type { SiteData } from \"../types.js\";\nimport { escapeHtml, propTableRow, renderDOMTree, slugify } from \"../utils.js\";\nimport { htmlShell, sidebarLinks } from \"./layout.js\";\n\nconst SECTIONS = [\n \"Playground\",\n \"Matrix\",\n \"Docs\",\n \"Analysis\",\n \"X-Ray\",\n \"Tokens\",\n \"Accessibility\",\n \"Composition\",\n \"Responsive\",\n \"Stress Tests\",\n];\n\nfunction notGenerated(message = \"Not generated\"): string {\n return `<div class=\"not-generated\">${escapeHtml(message)}</div>`;\n}\n\nfunction sectionWrap(id: string, title: string, description: string, content: string): string {\n return `<section class=\"section\" id=\"${id}\">\n <div class=\"section-header\">\n <h2>${escapeHtml(title)}</h2>\n <p>${escapeHtml(description)}</p>\n </div>\n ${content}\n</section>`;\n}\n\nfunction renderPlayground(name: string, data: SiteData): string {\n const component = data.manifest.components[name];\n const render = data.renders.get(name);\n\n const props = component ? Object.entries(component.props) : [];\n const propsTable =\n props.length > 0\n ? `<table class=\"props-table\">\n <thead>\n <tr>\n <th>Prop</th>\n <th>Type</th>\n <th>Required</th>\n <th>Default</th>\n </tr>\n </thead>\n <tbody>\n ${props.map(([n, p]) => propTableRow(n, p)).join(\"\\n \")}\n </tbody>\n</table>`\n : `<p style=\"color:var(--color-muted);font-size:13px\">No props defined.</p>`;\n\n const renderW = render?.width != null ? render.width : undefined;\n const renderH = render?.height != null ? render.height : undefined;\n const renderSizeAttr =\n renderW != null && renderH != null ? ` width=\"${renderW}\" height=\"${renderH}\"` : \"\";\n const renderHtml = render?.screenshot\n ? `<div class=\"render-preview\">\n <img src=\"data:image/png;base64,${render.screenshot}\" alt=\"${escapeHtml(name)} render\"${renderSizeAttr} />\n</div>`\n : notGenerated(\"Render not generated. Run scope render to produce screenshots.\");\n\n return sectionWrap(\n \"playground\",\n \"Playground\",\n \"Props reference and rendered preview.\",\n `${propsTable}\n<div style=\"margin-top:24px\">${renderHtml}</div>`,\n );\n}\n\nfunction renderMatrix(name: string, data: SiteData): string {\n const render = data.renders.get(name);\n\n if (!render?.cells || render.cells.length === 0) {\n return sectionWrap(\n \"matrix\",\n \"Matrix\",\n \"Prop combination matrix renders.\",\n notGenerated(\"Matrix renders not generated. Run scope render --matrix to produce a matrix.\"),\n );\n }\n\n const cells = render.cells;\n const cols = Math.ceil(Math.sqrt(cells.length));\n\n const cellsHtml = cells\n .map((cell) => {\n const label = cell.axisValues.join(\" / \");\n const imgHtml = cell.screenshot\n ? `<img class=\"scope-screenshot\" src=\"data:image/png;base64,${cell.screenshot}\" alt=\"${escapeHtml(label)}\" />`\n : `<span style=\"color:var(--color-muted);font-size:11px\">${cell.error ? escapeHtml(cell.error) : \"failed\"}</span>`;\n return `<div class=\"matrix-cell\">${imgHtml}<div class=\"cell-label\">${escapeHtml(label)}</div></div>`;\n })\n .join(\"\\n\");\n\n const grid = `<div class=\"matrix-grid\" style=\"grid-template-columns: repeat(${cols}, 1fr)\">\n${cellsHtml}\n</div>`;\n\n return sectionWrap(\"matrix\", \"Matrix\", \"Prop combination matrix renders.\", grid);\n}\n\nfunction renderDocs(): string {\n return sectionWrap(\n \"docs\",\n \"Docs\",\n \"Component documentation.\",\n `<p style=\"color:var(--color-muted);font-size:13px\">No documentation file found for this component.</p>`,\n );\n}\n\nfunction renderAnalysis(name: string, data: SiteData): string {\n const component = data.manifest.components[name];\n if (!component) {\n return sectionWrap(\"analysis\", \"Analysis\", \"Static analysis results.\", notGenerated());\n }\n\n const propCount = Object.keys(component.props).length;\n const hookCount = component.detectedHooks.length;\n const sideEffectCount =\n component.sideEffects.fetches.length +\n (component.sideEffects.timers ? 1 : 0) +\n component.sideEffects.subscriptions.length +\n (component.sideEffects.globalListeners ? 1 : 0);\n\n const statsGrid = `<div class=\"stats-grid\">\n <div class=\"stat-card\">\n <div class=\"stat-label\">Complexity</div>\n <div class=\"stat-value\"><span class=\"badge ${component.complexityClass}\">${escapeHtml(component.complexityClass)}</span></div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-label\">Props</div>\n <div class=\"stat-value\">${propCount}</div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-label\">Hooks</div>\n <div class=\"stat-value\">${hookCount}</div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-label\">Side Effects</div>\n <div class=\"stat-value\">${sideEffectCount}</div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-label\">Export</div>\n <div class=\"stat-value\" style=\"font-size:14px\">${escapeHtml(component.exportType)}</div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-label\">Memoized</div>\n <div class=\"stat-value\" style=\"font-size:14px\">${component.memoized ? \"Yes\" : \"No\"}</div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-label\">forwardedRef</div>\n <div class=\"stat-value\" style=\"font-size:14px\">${component.forwardedRef ? \"Yes\" : \"No\"}</div>\n </div>\n</div>`;\n\n function tagList(items: string[]): string {\n if (items.length === 0)\n return `<span style=\"color:var(--color-muted);font-size:12px\">None</span>`;\n return `<div class=\"tag-list\">${items.map((i) => `<span class=\"tag\">${escapeHtml(i)}</span>`).join(\"\")}</div>`;\n }\n\n const sideEffectItems: string[] = [\n ...component.sideEffects.fetches.map((f) => `fetch: ${f}`),\n ...(component.sideEffects.timers ? [\"timers\"] : []),\n ...component.sideEffects.subscriptions.map((s) => `sub: ${s}`),\n ...(component.sideEffects.globalListeners ? [\"global listeners\"] : []),\n ];\n\n const analysisGrid = `<div class=\"analysis-grid\">\n <div class=\"analysis-card\">\n <h3>Detected Hooks</h3>\n <div class=\"value\">${tagList(component.detectedHooks)}</div>\n </div>\n <div class=\"analysis-card\">\n <h3>Required Contexts</h3>\n <div class=\"value\">${tagList(component.requiredContexts)}</div>\n </div>\n <div class=\"analysis-card\">\n <h3>HOC Wrappers</h3>\n <div class=\"value\">${tagList(component.hocWrappers)}</div>\n </div>\n <div class=\"analysis-card\">\n <h3>Side Effects</h3>\n <div class=\"value\">${tagList(sideEffectItems)}</div>\n </div>\n</div>`;\n\n return sectionWrap(\n \"analysis\",\n \"Analysis\",\n \"Static analysis results for this component.\",\n `${statsGrid}${analysisGrid}`,\n );\n}\n\nfunction renderXRay(name: string, data: SiteData): string {\n const render = data.renders.get(name);\n\n if (!render?.dom) {\n return sectionWrap(\n \"x-ray\",\n \"X-Ray\",\n \"DOM structure and computed styles.\",\n notGenerated(\"X-Ray data not generated. Run scope render with DOM capture enabled.\"),\n );\n }\n\n const dom = render.dom;\n\n // Extract per-node styles keyed by nodeId from computedStyles map\n const nodeStylesMap: Record<number, Record<string, string>> = {};\n if (render.computedStyles) {\n for (const [key, styles] of Object.entries(render.computedStyles)) {\n const m = key.match(/^#node-(\\d+)$/);\n if (m?.[1] !== undefined) nodeStylesMap[parseInt(m[1], 10)] = styles;\n }\n }\n const nodeStylesJson = escapeHtml(JSON.stringify(nodeStylesMap));\n\n const treeHtml = `<div class=\"dom-tree\">${renderDOMTree(dom.tree)}</div>`;\n\n // Styles panel — populated by JS when user clicks a node\n const stylesPanelHtml = `\n<div id=\"xray-styles-panel-${escapeHtml(name)}\" class=\"xray-styles-panel\" style=\"display:none;margin-top:16px;border:1px solid var(--color-border);border-radius:6px;overflow:hidden\">\n <div class=\"xray-styles-header\" style=\"padding:8px 12px;background:var(--color-surface-2);font-size:12px;font-weight:600;color:var(--color-muted);display:flex;justify-content:space-between;align-items:center\">\n <span id=\"xray-styles-label-${escapeHtml(name)}\">— no node selected —</span>\n <button onclick=\"document.getElementById('xray-styles-panel-${escapeHtml(name)}').style.display='none'\" style=\"background:none;border:none;cursor:pointer;color:var(--color-muted);font-size:16px;line-height:1\">×</button>\n </div>\n <table class=\"token-table\" style=\"margin:0\">\n <thead><tr><th>Property</th><th>Value</th></tr></thead>\n <tbody id=\"xray-styles-body-${escapeHtml(name)}\"></tbody>\n </table>\n</div>\n<script>\n(function() {\n var nodeStyles = JSON.parse(${nodeStylesJson});\n var container = document.currentScript.parentElement;\n container.addEventListener(\"click\", function(e) {\n var el = e.target.closest(\"[data-node-id]\");\n if (!el) return;\n var id = parseInt(el.getAttribute(\"data-node-id\"), 10);\n var styles = nodeStyles[id];\n if (!styles) return;\n var panel = document.getElementById(\"xray-styles-panel-${escapeHtml(name)}\");\n var label = document.getElementById(\"xray-styles-label-${escapeHtml(name)}\");\n var body = document.getElementById(\"xray-styles-body-${escapeHtml(name)}\");\n var tag = el.tagName === \"DETAILS\" ? el.querySelector(\"summary .dom-tag-open\") : el;\n label.textContent = tag ? tag.textContent.trim().slice(0, 60) : \"node #\" + id;\n body.innerHTML = Object.entries(styles).map(function(e) {\n return \"<tr><td>\" + e[0] + \"</td><td style=\"font-family:monospace\">\" + e[1] + \"</td></tr>\";\n }).join(\"\");\n panel.style.display = \"block\";\n // Highlight selected node\n container.querySelectorAll(\".dom-node-selected\").forEach(function(n) { n.classList.remove(\"dom-node-selected\"); });\n el.classList.add(\"dom-node-selected\");\n });\n})();\n</script>`;\n\n return sectionWrap(\n \"x-ray\",\n \"X-Ray\",\n `DOM structure — ${dom.elementCount} elements. Click any element to inspect its computed styles.`,\n `${treeHtml}${stylesPanelHtml}`,\n );\n}\n\nfunction renderTokens(name: string, data: SiteData): string {\n if (!data.complianceBatch) {\n return sectionWrap(\n \"tokens\",\n \"Tokens\",\n \"Design token compliance.\",\n notGenerated(\"Compliance data not generated. Run scope tokens to audit design tokens.\"),\n );\n }\n\n const report = data.complianceBatch.components[name];\n if (!report) {\n return sectionWrap(\n \"tokens\",\n \"Tokens\",\n \"Design token compliance.\",\n notGenerated(\"No compliance report found for this component.\"),\n );\n }\n\n const pct = Math.round(report.compliance * 100);\n const barHtml = `<div class=\"compliance-bar-container\">\n <div class=\"compliance-label\">${pct}% on-system (${report.onSystem} / ${report.total} properties)</div>\n <div class=\"compliance-bar-bg\">\n <div class=\"compliance-bar-fill\" style=\"width:${pct}%\"></div>\n </div>\n</div>`;\n\n const rows = Object.entries(report.properties)\n .map(([prop, result]) => {\n const pill =\n result.status === \"on_system\"\n ? `<span class=\"pill-on\">✓ ${escapeHtml(result.token ?? \"\")}</span>`\n : `<span class=\"pill-off\">✗ off-system</span>`;\n\n const swatchStyle = result.value.startsWith(\"#\")\n ? ` style=\"background:${escapeHtml(result.value)}\"`\n : \"\";\n\n const nearestHtml = result.nearest\n ? `<span style=\"color:var(--color-muted);font-size:10px\"> nearest: ${escapeHtml(result.nearest.token)}</span>`\n : \"\";\n\n return `<tr>\n <td class=\"token-path\">${escapeHtml(prop)}</td>\n <td><span class=\"token-value-swatch\"${swatchStyle}></span>${escapeHtml(result.value)}</td>\n <td>${pill}${nearestHtml}</td>\n </tr>`;\n })\n .join(\"\\n \");\n\n const tableHtml = `<table class=\"token-table\">\n <thead><tr><th>Property</th><th>Value</th><th>Status</th></tr></thead>\n <tbody>${rows}</tbody>\n</table>`;\n\n return sectionWrap(\n \"tokens\",\n \"Tokens\",\n \"Design token compliance audit.\",\n `${barHtml}${tableHtml}`,\n );\n}\n\nfunction renderAccessibility(name: string, data: SiteData): string {\n const render = data.renders.get(name);\n\n if (!render?.accessibility) {\n return sectionWrap(\n \"accessibility\",\n \"Accessibility\",\n \"Accessibility audit results.\",\n notGenerated(\n \"Accessibility data not generated. Run scope render with accessibility capture enabled.\",\n ),\n );\n }\n\n const a11y = render.accessibility;\n const roleBadge = `<span class=\"a11y-role-badge\">${escapeHtml(a11y.role)}</span>`;\n\n const violationsHtml =\n a11y.violations.length > 0\n ? `<ul class=\"violation-list\">${a11y.violations.map((v) => `<li>${escapeHtml(v)}</li>`).join(\"\")}</ul>`\n : `<p style=\"color:var(--color-success);font-size:13px\">✓ No violations found.</p>`;\n\n return sectionWrap(\n \"accessibility\",\n \"Accessibility\",\n \"Accessibility audit results.\",\n `<p style=\"font-size:13px;margin:0 0 12px\">Role: ${roleBadge} &nbsp; Name: <em>${escapeHtml(a11y.name || \"(none)\")}</em></p>\n${violationsHtml}`,\n );\n}\n\nfunction renderComposition(name: string, data: SiteData): string {\n const component = data.manifest.components[name];\n\n if (!component || (component.composes.length === 0 && component.composedBy.length === 0)) {\n return sectionWrap(\n \"composition\",\n \"Composition\",\n \"Component dependency graph.\",\n `<p style=\"color:var(--color-muted);font-size:13px\">This component stands alone.</p>`,\n );\n }\n\n function compList(title: string, items: string[]): string {\n if (items.length === 0) {\n return `<div class=\"comp-list\"><h3>${escapeHtml(title)}</h3><p style=\"color:var(--color-muted);font-size:12px\">None</p></div>`;\n }\n const liItems = items\n .map(\n (n) => `<li><a href=\"${data.options.basePath}${slugify(n)}.html\">${escapeHtml(n)}</a></li>`,\n )\n .join(\"\");\n return `<div class=\"comp-list\"><h3>${escapeHtml(title)}</h3><ul>${liItems}</ul></div>`;\n }\n\n return sectionWrap(\n \"composition\",\n \"Composition\",\n \"Component dependency graph.\",\n `<div class=\"composition-lists\">\n ${compList(\"Composes\", component.composes)}\n ${compList(\"Composed By\", component.composedBy)}\n</div>`,\n );\n}\n\nexport function renderComponentDetail(name: string, data: SiteData): string {\n const component = data.manifest.components[name];\n const slug = slugify(name);\n\n const complexityBadge = component\n ? `<span class=\"badge ${component.complexityClass}\">${escapeHtml(component.complexityClass)}</span>`\n : \"\";\n const memoizedBadge = component?.memoized ? `<span class=\"badge memoized\">memo</span>` : \"\";\n const exportBadge = component\n ? `<span class=\"badge\">${escapeHtml(component.exportType)}</span>`\n : \"\";\n const filepath = component ? `<div class=\"filepath\">${escapeHtml(component.filePath)}</div>` : \"\";\n\n const header = `<div class=\"component-header\">\n <h1>${escapeHtml(name)}</h1>\n <div class=\"meta\">${complexityBadge}${memoizedBadge}${exportBadge}</div>\n ${filepath}\n</div>`;\n\n const sections = [\n renderPlayground(name, data),\n renderMatrix(name, data),\n renderDocs(),\n renderAnalysis(name, data),\n renderXRay(name, data),\n renderTokens(name, data),\n renderAccessibility(name, data),\n renderComposition(name, data),\n sectionWrap(\n \"responsive\",\n \"Responsive\",\n \"Multi-viewport renders.\",\n notGenerated(\n \"Responsive renders not generated. Multi-viewport rendering is a future feature.\",\n ),\n ),\n sectionWrap(\n \"stress-tests\",\n \"Stress Tests\",\n \"Edge case and stress test renders.\",\n notGenerated(\"Stress tests not generated. Stress render runs are a future feature.\"),\n ),\n ];\n\n const body = `${header}${sections.join(\"\\n\")}`;\n\n const onThisPage = SECTIONS.map((s) => {\n const id = s.toLowerCase().replace(/\\s+/g, \"-\");\n return `<a href=\"#${id}\">${escapeHtml(s)}</a>`;\n }).join(\"\\n\");\n\n const componentNames = Object.keys(data.manifest.components);\n const sidebar = sidebarLinks(componentNames, slug, data.options.basePath);\n\n return htmlShell({\n title: `${name} — ${data.options.title}`,\n body,\n sidebar,\n onThisPage,\n basePath: data.options.basePath,\n });\n}\n","import type { SiteData } from \"../types.js\";\nimport { escapeHtml, slugify } from \"../utils.js\";\nimport { htmlShell, sidebarLinks } from \"./layout.js\";\n\nexport function renderComponentIndex(data: SiteData): string {\n const components = Object.entries(data.manifest.components);\n const totalCount = components.length;\n const simpleCount = components.filter(([, c]) => c.complexityClass === \"simple\").length;\n const complexCount = components.filter(([, c]) => c.complexityClass === \"complex\").length;\n const memoizedCount = components.filter(([, c]) => c.memoized).length;\n\n const statsGrid = `<div class=\"stats-grid\">\n <div class=\"stat-card\">\n <div class=\"stat-label\">Total Components</div>\n <div class=\"stat-value\">${totalCount}</div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-label\">Simple</div>\n <div class=\"stat-value\">${simpleCount}</div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-label\">Complex</div>\n <div class=\"stat-value\">${complexCount}</div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-label\">Memoized</div>\n <div class=\"stat-value\">${memoizedCount}</div>\n </div>\n</div>`;\n\n const cards = components\n .sort(([a], [b]) => a.localeCompare(b))\n .map(([name, component]) => {\n const slug = slugify(name);\n const render = data.renders.get(name);\n const propCount = Object.keys(component.props).length;\n const hookCount = component.detectedHooks.length;\n\n const previewHtml = render?.screenshot\n ? `<img class=\"scope-screenshot\" src=\"data:image/png;base64,${render.screenshot}\" alt=\"${escapeHtml(name)}\" />`\n : `<span class=\"no-preview\">No preview</span>`;\n\n return `<a class=\"component-card\" href=\"${data.options.basePath}${slug}.html\" data-name=\"${escapeHtml(name.toLowerCase())}\">\n <div class=\"card-preview\">${previewHtml}</div>\n <div class=\"card-body\">\n <div class=\"card-name\">${escapeHtml(name)}</div>\n <div class=\"card-meta\">\n <span>${propCount} props</span>\n <span class=\"badge ${component.complexityClass}\" style=\"font-size:10px\">${escapeHtml(component.complexityClass)}</span>\n ${hookCount > 0 ? `<span>${hookCount} hooks</span>` : \"\"}\n </div>\n </div>\n</a>`;\n })\n .join(\"\\n\");\n\n const cardGrid = `<div class=\"component-grid\" id=\"component-grid\">${cards}</div>`;\n\n const filterScript = `<script>\n(function () {\n var grid = document.getElementById('component-grid');\n var search = document.getElementById('sidebar-search');\n if (!grid || !search) return;\n var indexSearch = document.getElementById('index-search');\n function filter(q) {\n var cards = grid.querySelectorAll('.component-card');\n cards.forEach(function (card) {\n var name = card.getAttribute('data-name') || '';\n card.style.display = name.includes(q) ? '' : 'none';\n });\n }\n search.addEventListener('input', function () { filter(search.value.toLowerCase()); });\n if (indexSearch) {\n indexSearch.addEventListener('input', function () { filter(indexSearch.value.toLowerCase()); });\n }\n})();\n</script>`;\n\n const header = `<div class=\"index-header\">\n <h1>${escapeHtml(data.options.title)}</h1>\n <p>${totalCount} component${totalCount === 1 ? \"\" : \"s\"} analysed</p>\n <input class=\"search-box\" type=\"search\" id=\"index-search\" placeholder=\"Filter components…\" style=\"margin-top:12px\" />\n</div>`;\n\n const body = `${header}${statsGrid}${cardGrid}${filterScript}`;\n\n const componentNames = Object.keys(data.manifest.components);\n const sidebar = sidebarLinks(componentNames, null, data.options.basePath);\n\n const onThisPage = `<a href=\"#top\">Overview</a>\\n<a href=\"#component-grid\">Components</a>`;\n\n return htmlShell({\n title: data.options.title,\n body,\n sidebar,\n onThisPage,\n basePath: data.options.basePath,\n });\n}\n","import type { SiteData } from \"../types.js\";\nimport { escapeHtml, slugify } from \"../utils.js\";\nimport { htmlShell, sidebarLinks } from \"./layout.js\";\n\nexport function renderDashboard(data: SiteData): string {\n const components = Object.entries(data.manifest.components);\n const totalCount = components.length;\n\n const simpleCount = components.filter(([, c]) => c.complexityClass === \"simple\").length;\n const complexCount = components.filter(([, c]) => c.complexityClass === \"complex\").length;\n const renderedCount = components.filter(([name]) => data.renders.has(name)).length;\n\n const totalProps = components.reduce((sum, [, c]) => sum + Object.keys(c.props).length, 0);\n const avgProps = totalCount > 0 ? Math.round(totalProps / totalCount) : 0;\n\n let overallCompliance: number | null = null;\n if (data.complianceBatch) {\n const reports = Object.values(data.complianceBatch.components);\n if (reports.length > 0) {\n overallCompliance = Math.round(\n (reports.reduce((sum, r) => sum + r.compliance, 0) / reports.length) * 100,\n );\n }\n }\n\n const statsGrid = `<div class=\"stats-grid\" style=\"margin-bottom:32px\">\n <div class=\"stat-card\">\n <div class=\"stat-label\">Total Components</div>\n <div class=\"stat-value\">${totalCount}</div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-label\">Avg Props</div>\n <div class=\"stat-value\">${avgProps}</div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-label\">With Renders</div>\n <div class=\"stat-value\">${renderedCount}</div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-label\">Compliance</div>\n <div class=\"stat-value\">${overallCompliance !== null ? `${overallCompliance}%` : \"—\"}</div>\n </div>\n</div>`;\n\n // Complexity breakdown\n const complexitySection = `<div class=\"section\" style=\"padding:24px 0;border-bottom:1px solid var(--color-border)\">\n <h2 class=\"section-title\">Complexity Breakdown</h2>\n <div class=\"stats-grid\">\n <div class=\"stat-card\">\n <div class=\"stat-label\">Simple</div>\n <div class=\"stat-value\" style=\"color:var(--color-success)\">${simpleCount}</div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-label\">Complex</div>\n <div class=\"stat-value\" style=\"color:var(--color-warn)\">${complexCount}</div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-label\">Simple %</div>\n <div class=\"stat-value\">${totalCount > 0 ? Math.round((simpleCount / totalCount) * 100) : 0}%</div>\n </div>\n </div>\n</div>`;\n\n // Top components by prop count\n const topByProps = components\n .sort(([, a], [, b]) => Object.keys(b.props).length - Object.keys(a.props).length)\n .slice(0, 10);\n\n const topPropsRows = topByProps\n .map(([name, component]) => {\n const slug = slugify(name);\n const propCount = Object.keys(component.props).length;\n return `<tr>\n <td><a href=\"${data.options.basePath}${slug}.html\" style=\"color:var(--color-accent);text-decoration:none\">${escapeHtml(name)}</a></td>\n <td>${propCount}</td>\n <td><span class=\"badge ${component.complexityClass}\">${escapeHtml(component.complexityClass)}</span></td>\n </tr>`;\n })\n .join(\"\\n \");\n\n const topPropsSection = `<div class=\"section\" style=\"padding:24px 0;border-bottom:1px solid var(--color-border)\">\n <h2 class=\"section-title\">Top Components by Prop Count</h2>\n <table class=\"props-table\">\n <thead><tr><th>Component</th><th>Props</th><th>Complexity</th></tr></thead>\n <tbody>${topPropsRows}</tbody>\n </table>\n</div>`;\n\n // Compliance section\n let complianceSection = \"\";\n if (data.complianceBatch && overallCompliance !== null) {\n const complianceRows = Object.entries(data.complianceBatch.components)\n .sort(([, a], [, b]) => b.compliance - a.compliance)\n .map(([name, report]) => {\n const pct = Math.round(report.compliance * 100);\n const slug = slugify(name);\n const barHtml = `<div class=\"compliance-bar-bg\" style=\"min-width:120px\">\n <div class=\"compliance-bar-fill\" style=\"width:${pct}%\"></div>\n </div>`;\n return `<tr>\n <td><a href=\"${data.options.basePath}${slug}.html\" style=\"color:var(--color-accent);text-decoration:none\">${escapeHtml(name)}</a></td>\n <td>${pct}%</td>\n <td>${barHtml}</td>\n <td>${report.onSystem} / ${report.total}</td>\n </tr>`;\n })\n .join(\"\\n \");\n\n complianceSection = `<div class=\"section\" style=\"padding:24px 0\">\n <h2 class=\"section-title\">Design Token Compliance — ${overallCompliance}% overall</h2>\n <table class=\"props-table\">\n <thead><tr><th>Component</th><th>Score</th><th>Bar</th><th>On-System</th></tr></thead>\n <tbody>${complianceRows}</tbody>\n </table>\n</div>`;\n }\n\n const header = `<div class=\"dashboard-header\">\n <h1>Dashboard</h1>\n <p style=\"color:var(--color-muted);font-size:14px\">Overview of all ${totalCount} analysed components.</p>\n</div>`;\n\n const body = `${header}${statsGrid}${complexitySection}${topPropsSection}${complianceSection}`;\n\n const componentNames = Object.keys(data.manifest.components);\n const sidebar = sidebarLinks(componentNames, null, data.options.basePath);\n\n const onThisPage = `<a href=\"#top\">Overview</a>\n<a href=\"#complexity\">Complexity</a>\n<a href=\"#top-props\">Top by Props</a>\n${data.complianceBatch ? '<a href=\"#compliance\">Compliance</a>' : \"\"}`;\n\n return htmlShell({\n title: `Dashboard — ${data.options.title}`,\n body,\n sidebar,\n onThisPage,\n basePath: data.options.basePath,\n });\n}\n","import { mkdir, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { normalizeOptions, readSiteData } from \"./reader.js\";\nimport { renderComponentDetail } from \"./templates/component-detail.js\";\nimport { renderComponentIndex } from \"./templates/component-index.js\";\nimport { renderDashboard } from \"./templates/dashboard.js\";\nimport type { SiteOptions } from \"./types.js\";\nimport { slugify } from \"./utils.js\";\n\nexport async function buildSite(options?: SiteOptions): Promise<void> {\n const normalizedOptions = normalizeOptions(options);\n\n console.log(`[scope/site] Reading data from ${normalizedOptions.inputDir}…`);\n const data = await readSiteData(normalizedOptions);\n\n const componentNames = Object.keys(data.manifest.components);\n console.log(`[scope/site] Found ${componentNames.length} components.`);\n\n // Create output directory\n await mkdir(normalizedOptions.outputDir, { recursive: true });\n\n // Generate component detail pages\n for (const name of componentNames) {\n const slug = slugify(name);\n const html = renderComponentDetail(name, data);\n const outputPath = join(normalizedOptions.outputDir, `${slug}.html`);\n await writeFile(outputPath, html, \"utf-8\");\n console.log(`[scope/site] ✓ ${name} → ${slug}.html`);\n }\n\n // Generate index page\n const indexHtml = renderComponentIndex(data);\n await writeFile(join(normalizedOptions.outputDir, \"index.html\"), indexHtml, \"utf-8\");\n console.log(`[scope/site] ✓ index.html`);\n\n // Generate dashboard page\n const dashboardHtml = renderDashboard(data);\n await writeFile(join(normalizedOptions.outputDir, \"dashboard.html\"), dashboardHtml, \"utf-8\");\n console.log(`[scope/site] ✓ dashboard.html`);\n\n console.log(\n `[scope/site] Done. Site written to ${normalizedOptions.outputDir} (${componentNames.length + 2} files).`,\n );\n}\n"]}
package/dist/index.js CHANGED
@@ -68,21 +68,24 @@ function slugify(name) {
68
68
  }
69
69
  function renderDOMTree(node, depth = 0) {
70
70
  const indent = " ".repeat(depth);
71
- const attrs = Object.entries(node.attrs).map(
72
- ([k, v]) => ` <span class="dom-attr-name">${escapeHtml(k)}</span>=<span class="dom-attr-value">"${escapeHtml(v)}"</span>`
73
- ).join("");
71
+ const attrsHtml = Object.entries(node.attrs).map(([k, v]) => {
72
+ const display = v.length > 60 ? v.slice(0, 57) + "\u2026" : v;
73
+ return ` <span class="dom-attr-name">${escapeHtml(k)}</span>=<span class="dom-attr-value">"${escapeHtml(display)}"</span>`;
74
+ }).join("");
75
+ const nodeIdAttr = node.nodeId !== void 0 ? ` data-node-id="${node.nodeId}"` : "";
76
+ const clickable = node.nodeId !== void 0 ? " dom-node-clickable" : "";
74
77
  const hasChildren = node.children.length > 0;
75
78
  const hasText = node.text !== void 0 && node.text.trim().length > 0;
76
79
  if (!hasChildren && !hasText) {
77
- return `${indent}<span class="dom-tag-open">&lt;${escapeHtml(node.tag)}${attrs} /&gt;</span>
80
+ return `${indent}<span class="dom-tag-open${clickable}"${nodeIdAttr}>&lt;${escapeHtml(node.tag)}${attrsHtml} /&gt;</span>
78
81
  `;
79
82
  }
80
83
  const childrenHtml = node.children.map((child) => renderDOMTree(child, depth + 1)).join("");
81
84
  const textHtml = hasText ? `${indent} <span class="dom-text">${escapeHtml(node.text ?? "")}</span>
82
85
  ` : "";
83
- return `<details class="dom-node" ${depth < 2 ? "open" : ""}>
84
- ${indent}<summary><span class="dom-tag-open">&lt;${escapeHtml(node.tag)}${attrs}&gt;</span></summary>
85
- ${textHtml}${childrenHtml}${indent}<span class="dom-tag-open">&lt;/${escapeHtml(node.tag)}&gt;</span>
86
+ return `<details class="dom-node${clickable}" ${depth < 2 ? "open" : ""}${nodeIdAttr}>
87
+ ${indent}<summary><span class="dom-tag-open">&lt;${escapeHtml(node.tag)}${attrsHtml}&gt;</span></summary>
88
+ ${textHtml}${childrenHtml}${indent}<span class="dom-tag-close">&lt;/${escapeHtml(node.tag)}&gt;</span>
86
89
  </details>`;
87
90
  }
88
91
  function propTableRow(name, prop) {
@@ -298,6 +301,7 @@ body {
298
301
  max-width: 100%;
299
302
  }
300
303
  .render-preview img { display: block; max-width: 100%; }
304
+ .scope-screenshot { zoom: 0.5; display: block; image-rendering: -webkit-optimize-contrast; }
301
305
 
302
306
  /* Props table */
303
307
  .props-table { width: 100%; border-collapse: collapse; font-size: 13px; }
@@ -437,7 +441,7 @@ pre.code-block {
437
441
  overflow: hidden;
438
442
  }
439
443
  .matrix-cell { background: var(--color-bg); padding: 8px; text-align: center; }
440
- .matrix-cell img { max-width: 100%; border-radius: 2px; }
444
+ .matrix-cell img { border-radius: 2px; }
441
445
  .matrix-cell .cell-label { font-size: 10px; color: var(--color-muted); margin-top: 4px; }
442
446
  .matrix-header { background: var(--color-bg-subtle); padding: 6px 8px; font-size: 11px; font-weight: 600; color: var(--color-muted); }
443
447
 
@@ -446,6 +450,13 @@ pre.code-block {
446
450
  details.dom-node > summary { cursor: pointer; list-style: none; }
447
451
  details.dom-node > summary::-webkit-details-marker { display: none; }
448
452
  .dom-tag-open { color: #f07178; }
453
+ .dom-tag-close { color: #f07178; }
454
+ .dom-attr-name { color: #ffcb6b; }
455
+ .dom-attr-value { color: #c3e88d; }
456
+ .dom-text { color: #82aaff; font-style: italic; }
457
+ .dom-node-clickable { cursor: pointer; border-radius: 3px; transition: background 0.1s; }
458
+ .dom-node-clickable:hover, details.dom-node-clickable > summary:hover { background: rgba(255,255,255,0.08); }
459
+ .dom-node-selected, details.dom-node-selected > summary { background: rgba(99,179,237,0.15) !important; outline: 1px solid rgba(99,179,237,0.4); border-radius: 3px; }
449
460
  .dom-attr-name { color: #ffcb6b; }
450
461
  .dom-attr-value { color: #c3e88d; }
451
462
  .dom-text { color: #a0a0b0; font-style: italic; }
@@ -486,7 +497,7 @@ details.dom-node > summary::-webkit-details-marker { display: none; }
486
497
  justify-content: center;
487
498
  border-bottom: 1px solid var(--color-border);
488
499
  }
489
- .card-preview img { max-width: 100%; max-height: 100%; object-fit: contain; }
500
+ .card-preview img { object-fit: contain; }
490
501
  .card-preview .no-preview { color: var(--color-muted); font-size: 12px; }
491
502
  .card-body { padding: 12px 16px; }
492
503
  .card-name { font-weight: 600; font-size: 14px; margin-bottom: 4px; }
@@ -619,8 +630,11 @@ function renderPlayground(name, data) {
619
630
  ${props.map(([n, p]) => propTableRow(n, p)).join("\n ")}
620
631
  </tbody>
621
632
  </table>` : `<p style="color:var(--color-muted);font-size:13px">No props defined.</p>`;
633
+ const renderW = render?.width != null ? render.width : void 0;
634
+ const renderH = render?.height != null ? render.height : void 0;
635
+ const renderSizeAttr = renderW != null && renderH != null ? ` width="${renderW}" height="${renderH}"` : "";
622
636
  const renderHtml = render?.screenshot ? `<div class="render-preview">
623
- <img src="data:image/png;base64,${render.screenshot}" alt="${escapeHtml(name)} render" />
637
+ <img src="data:image/png;base64,${render.screenshot}" alt="${escapeHtml(name)} render"${renderSizeAttr} />
624
638
  </div>` : notGenerated("Render not generated. Run scope render to produce screenshots.");
625
639
  return sectionWrap(
626
640
  "playground",
@@ -644,7 +658,7 @@ function renderMatrix(name, data) {
644
658
  const cols = Math.ceil(Math.sqrt(cells.length));
645
659
  const cellsHtml = cells.map((cell) => {
646
660
  const label = cell.axisValues.join(" / ");
647
- const imgHtml = cell.screenshot ? `<img src="data:image/png;base64,${cell.screenshot}" alt="${escapeHtml(label)}" />` : `<span style="color:var(--color-muted);font-size:11px">${cell.error ? escapeHtml(cell.error) : "failed"}</span>`;
661
+ const imgHtml = cell.screenshot ? `<img class="scope-screenshot" src="data:image/png;base64,${cell.screenshot}" alt="${escapeHtml(label)}" />` : `<span style="color:var(--color-muted);font-size:11px">${cell.error ? escapeHtml(cell.error) : "failed"}</span>`;
648
662
  return `<div class="matrix-cell">${imgHtml}<div class="cell-label">${escapeHtml(label)}</div></div>`;
649
663
  }).join("\n");
650
664
  const grid = `<div class="matrix-grid" style="grid-template-columns: repeat(${cols}, 1fr)">
@@ -745,25 +759,56 @@ function renderXRay(name, data) {
745
759
  );
746
760
  }
747
761
  const dom = render.dom;
762
+ const nodeStylesMap = {};
763
+ if (render.computedStyles) {
764
+ for (const [key, styles] of Object.entries(render.computedStyles)) {
765
+ const m = key.match(/^#node-(\d+)$/);
766
+ if (m?.[1] !== void 0) nodeStylesMap[parseInt(m[1], 10)] = styles;
767
+ }
768
+ }
769
+ const nodeStylesJson = escapeHtml(JSON.stringify(nodeStylesMap));
748
770
  const treeHtml = `<div class="dom-tree">${renderDOMTree(dom.tree)}</div>`;
749
- const stylesHtml = render.computedStyles && Object.keys(render.computedStyles).length > 0 ? `<details style="margin-top:16px">
750
- <summary style="cursor:pointer;font-size:13px;font-weight:600;margin-bottom:8px">Computed Styles</summary>
751
- <table class="token-table" style="margin-top:8px">
752
- <thead><tr><th>Selector</th><th>Property</th><th>Value</th></tr></thead>
753
- <tbody>
754
- ${Object.entries(render.computedStyles).flatMap(
755
- ([selector, styles]) => Object.entries(styles).map(
756
- ([prop, val]) => `<tr><td class="token-path">${escapeHtml(selector)}</td><td>${escapeHtml(prop)}</td><td>${escapeHtml(val)}</td></tr>`
757
- )
758
- ).join("\n ")}
759
- </tbody>
771
+ const stylesPanelHtml = `
772
+ <div id="xray-styles-panel-${escapeHtml(name)}" class="xray-styles-panel" style="display:none;margin-top:16px;border:1px solid var(--color-border);border-radius:6px;overflow:hidden">
773
+ <div class="xray-styles-header" style="padding:8px 12px;background:var(--color-surface-2);font-size:12px;font-weight:600;color:var(--color-muted);display:flex;justify-content:space-between;align-items:center">
774
+ <span id="xray-styles-label-${escapeHtml(name)}">\u2014 no node selected \u2014</span>
775
+ <button onclick="document.getElementById('xray-styles-panel-${escapeHtml(name)}').style.display='none'" style="background:none;border:none;cursor:pointer;color:var(--color-muted);font-size:16px;line-height:1">\xD7</button>
776
+ </div>
777
+ <table class="token-table" style="margin:0">
778
+ <thead><tr><th>Property</th><th>Value</th></tr></thead>
779
+ <tbody id="xray-styles-body-${escapeHtml(name)}"></tbody>
760
780
  </table>
761
- </details>` : "";
781
+ </div>
782
+ <script>
783
+ (function() {
784
+ var nodeStyles = JSON.parse(${nodeStylesJson});
785
+ var container = document.currentScript.parentElement;
786
+ container.addEventListener("click", function(e) {
787
+ var el = e.target.closest("[data-node-id]");
788
+ if (!el) return;
789
+ var id = parseInt(el.getAttribute("data-node-id"), 10);
790
+ var styles = nodeStyles[id];
791
+ if (!styles) return;
792
+ var panel = document.getElementById("xray-styles-panel-${escapeHtml(name)}");
793
+ var label = document.getElementById("xray-styles-label-${escapeHtml(name)}");
794
+ var body = document.getElementById("xray-styles-body-${escapeHtml(name)}");
795
+ var tag = el.tagName === "DETAILS" ? el.querySelector("summary .dom-tag-open") : el;
796
+ label.textContent = tag ? tag.textContent.trim().slice(0, 60) : "node #" + id;
797
+ body.innerHTML = Object.entries(styles).map(function(e) {
798
+ return "<tr><td>" + e[0] + "</td><td style="font-family:monospace">" + e[1] + "</td></tr>";
799
+ }).join("");
800
+ panel.style.display = "block";
801
+ // Highlight selected node
802
+ container.querySelectorAll(".dom-node-selected").forEach(function(n) { n.classList.remove("dom-node-selected"); });
803
+ el.classList.add("dom-node-selected");
804
+ });
805
+ })();
806
+ </script>`;
762
807
  return sectionWrap(
763
808
  "x-ray",
764
809
  "X-Ray",
765
- `DOM structure \u2014 ${dom.elementCount} elements.`,
766
- `${treeHtml}${stylesHtml}`
810
+ `DOM structure \u2014 ${dom.elementCount} elements. Click any element to inspect its computed styles.`,
811
+ `${treeHtml}${stylesPanelHtml}`
767
812
  );
768
813
  }
769
814
  function renderTokens(name, data) {
@@ -946,7 +991,7 @@ function renderComponentIndex(data) {
946
991
  const render = data.renders.get(name);
947
992
  const propCount = Object.keys(component.props).length;
948
993
  const hookCount = component.detectedHooks.length;
949
- const previewHtml = render?.screenshot ? `<img src="data:image/png;base64,${render.screenshot}" alt="${escapeHtml(name)}" />` : `<span class="no-preview">No preview</span>`;
994
+ const previewHtml = render?.screenshot ? `<img class="scope-screenshot" src="data:image/png;base64,${render.screenshot}" alt="${escapeHtml(name)}" />` : `<span class="no-preview">No preview</span>`;
950
995
  return `<a class="component-card" href="${data.options.basePath}${slug}.html" data-name="${escapeHtml(name.toLowerCase())}">
951
996
  <div class="card-preview">${previewHtml}</div>
952
997
  <div class="card-body">
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/reader.ts","../src/utils.ts","../src/css.ts","../src/templates/layout.ts","../src/templates/component-detail.ts","../src/templates/component-index.ts","../src/templates/dashboard.ts","../src/builder.ts"],"names":["join"],"mappings":"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AAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAAA;AA0ZZ,EAAA,OAAO,CAAA;AAAA,EAAY,GAAG;AAAA,QAAA,CAAA;AACxB;;;ACzZO,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","file":"index.js","sourcesContent":["import { readdir, readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport type {\n ComplianceBatchData,\n ManifestData,\n RenderFileData,\n SiteData,\n SiteOptions,\n} from \"./types.js\";\n\nfunction normalizeOptions(options?: SiteOptions): Required<SiteOptions> {\n return {\n inputDir: options?.inputDir ?? \".reactscope\",\n outputDir: options?.outputDir ?? \".reactscope/site\",\n basePath: options?.basePath ?? \"/\",\n compliancePath: options?.compliancePath ?? \"\",\n title: options?.title ?? \"Scope — Component Gallery\",\n };\n}\n\nexport { normalizeOptions };\n\nasync function readJsonFile<T>(filePath: string): Promise<T> {\n const content = await readFile(filePath, \"utf-8\");\n return JSON.parse(content) as T;\n}\n\nexport async function readSiteData(options: Required<SiteOptions>): Promise<SiteData> {\n // 1. Read manifest\n const manifestPath = join(options.inputDir, \"manifest.json\");\n const manifest = await readJsonFile<ManifestData>(manifestPath);\n\n // 2. Scan renders directory\n const renders = new Map<string, RenderFileData>();\n const rendersDir = join(options.inputDir, \"renders\");\n\n try {\n const entries = await readdir(rendersDir);\n const jsonFiles = entries.filter((f) => f.endsWith(\".json\"));\n\n await Promise.all(\n jsonFiles.map(async (file) => {\n const componentName = file.replace(/\\.json$/, \"\");\n const filePath = join(rendersDir, file);\n try {\n const renderData = await readJsonFile<RenderFileData>(filePath);\n renders.set(componentName, renderData);\n } catch (err) {\n console.warn(\n `[scope/site] Warning: could not read render file ${filePath}:`,\n err instanceof Error ? err.message : String(err),\n );\n }\n }),\n );\n } catch {\n // renders directory may not exist — that's fine\n }\n\n // 3. Optionally read compliance JSON\n let complianceBatch: ComplianceBatchData | undefined;\n if (options.compliancePath) {\n try {\n complianceBatch = await readJsonFile<ComplianceBatchData>(options.compliancePath);\n } catch (err) {\n console.warn(\n `[scope/site] Warning: could not read compliance file ${options.compliancePath}:`,\n err instanceof Error ? err.message : String(err),\n );\n }\n }\n\n return {\n manifest,\n renders,\n complianceBatch,\n options,\n };\n}\n","import type { DOMNodeData, PropData } from \"./types.js\";\n\nexport function escapeHtml(str: string): string {\n return str\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\")\n .replace(/'/g, \"&#39;\");\n}\n\nexport function slugify(name: string): string {\n return name\n .replace(/([A-Z])/g, (m) => `-${m.toLowerCase()}`)\n .replace(/^-/, \"\")\n .replace(/[^a-z0-9-]/g, \"-\")\n .replace(/-+/g, \"-\")\n .replace(/^-|-$/g, \"\");\n}\n\nexport function syntaxHighlightJSX(code: string): string {\n const escaped = escapeHtml(code);\n\n return (\n escaped\n // Comments\n .replace(/(\\/\\/[^\\n]*)/g, '<span class=\"token-comment\">$1</span>')\n .replace(/(\\/\\*[\\s\\S]*?\\*\\/)/g, '<span class=\"token-comment\">$1</span>')\n // JSX tags\n .replace(/(&lt;\\/?)([\\w.]+)/g, '<span class=\"token-tag\">$1$2</span>')\n // JSX attributes (word followed by =)\n .replace(/\\b([\\w-]+)(?==)/g, '<span class=\"token-attr\">$1</span>')\n // Strings\n .replace(\n /(&quot;[^&]*&quot;|&#39;[^&]*&#39;|`[^`]*`)/g,\n '<span class=\"token-string\">$1</span>',\n )\n // Keywords\n .replace(\n /\\b(import|export|from|default|const|let|var|function|return|if|else|for|while|class|extends|type|interface|async|await|new|typeof|instanceof)\\b/g,\n '<span class=\"token-keyword\">$1</span>',\n )\n // Numbers\n .replace(/\\b(\\d+\\.?\\d*)\\b/g, '<span class=\"token-number\">$1</span>')\n );\n}\n\nexport function renderDOMTree(node: DOMNodeData, depth = 0): string {\n const indent = \" \".repeat(depth);\n const attrs = Object.entries(node.attrs)\n .map(\n ([k, v]) =>\n ` <span class=\"dom-attr-name\">${escapeHtml(k)}</span>=<span class=\"dom-attr-value\">\"${escapeHtml(v)}\"</span>`,\n )\n .join(\"\");\n\n const hasChildren = node.children.length > 0;\n const hasText = node.text !== undefined && node.text.trim().length > 0;\n\n if (!hasChildren && !hasText) {\n return `${indent}<span class=\"dom-tag-open\">&lt;${escapeHtml(node.tag)}${attrs} /&gt;</span>\\n`;\n }\n\n const childrenHtml = node.children.map((child) => renderDOMTree(child, depth + 1)).join(\"\");\n const textHtml = hasText\n ? `${indent} <span class=\"dom-text\">${escapeHtml(node.text ?? \"\")}</span>\\n`\n : \"\";\n\n return `<details class=\"dom-node\" ${depth < 2 ? \"open\" : \"\"}>\n${indent}<summary><span class=\"dom-tag-open\">&lt;${escapeHtml(node.tag)}${attrs}&gt;</span></summary>\n${textHtml}${childrenHtml}${indent}<span class=\"dom-tag-open\">&lt;/${escapeHtml(node.tag)}&gt;</span>\n</details>`;\n}\n\nexport function propTableRow(name: string, prop: PropData): string {\n const valuesHtml =\n prop.values && prop.values.length > 0\n ? `<br><span style=\"color:var(--color-muted);font-size:11px\">${prop.values.map((v) => escapeHtml(v)).join(\" | \")}</span>`\n : \"\";\n\n const defaultHtml = prop.default !== undefined ? escapeHtml(prop.default) : \"—\";\n\n return `<tr>\n <td><span class=\"prop-name\">${escapeHtml(name)}</span></td>\n <td><span class=\"prop-type\">${escapeHtml(prop.type)}</span>${valuesHtml}</td>\n <td>${prop.required ? '<span class=\"prop-required\">required</span>' : '<span style=\"color:var(--color-muted)\">optional</span>'}</td>\n <td><span class=\"prop-default\">${defaultHtml}</span></td>\n </tr>`;\n}\n","export function generateCSS(): string {\n const css = `@import url('https://fonts.googleapis.com/css2?family=Inter:wght@100..900&family=JetBrains+Mono:wght@400;700&display=swap');\n\n:root {\n --color-text: #0f0f0f;\n --color-muted: #6b7280;\n --color-border: #e5e7eb;\n --color-bg: #ffffff;\n --color-bg-subtle: #f9fafb;\n --color-bg-code: #1a1a2e;\n --color-accent: #2563eb;\n --color-success: #16a34a;\n --color-warn: #d97706;\n --color-error: #dc2626;\n --font-body: 'Inter', system-ui, -apple-system, sans-serif;\n --font-mono: 'JetBrains Mono', 'Fira Code', monospace;\n --radius: 6px;\n --shadow-sm: 0 1px 2px rgba(0,0,0,0.05);\n --shadow: 0 1px 3px rgba(0,0,0,0.1), 0 1px 2px rgba(0,0,0,0.06);\n}\n\n*, *::before, *::after { box-sizing: border-box; }\n\nbody {\n font-family: var(--font-body);\n font-size: 14px;\n line-height: 1.6;\n color: var(--color-text);\n background: var(--color-bg);\n margin: 0;\n}\n\n/* Top nav */\n.top-nav {\n position: sticky;\n top: 0;\n z-index: 100;\n background: var(--color-bg);\n border-bottom: 1px solid var(--color-border);\n height: 52px;\n display: flex;\n align-items: center;\n padding: 0 24px;\n gap: 16px;\n}\n.top-nav .site-title { font-weight: 600; font-size: 15px; text-decoration: none; color: var(--color-text); }\n.top-nav .spacer { flex: 1; }\n.search-box {\n border: 1px solid var(--color-border);\n border-radius: var(--radius);\n padding: 6px 12px;\n font-family: var(--font-body);\n font-size: 13px;\n width: 240px;\n outline: none;\n background: var(--color-bg-subtle);\n}\n.search-box:focus { border-color: var(--color-accent); background: var(--color-bg); }\n\n/* Page layout */\n.page-layout {\n display: flex;\n min-height: calc(100vh - 52px);\n}\n\n/* Left sidebar (component list) */\n.sidebar {\n width: 220px;\n min-width: 220px;\n border-right: 1px solid var(--color-border);\n padding: 16px 0;\n position: sticky;\n top: 52px;\n height: calc(100vh - 52px);\n overflow-y: auto;\n}\n.sidebar-heading {\n font-size: 11px;\n font-weight: 600;\n letter-spacing: 0.06em;\n text-transform: uppercase;\n color: var(--color-muted);\n padding: 4px 16px 8px;\n}\n.sidebar a {\n display: block;\n padding: 5px 16px;\n font-size: 13px;\n color: var(--color-text);\n text-decoration: none;\n border-radius: 0;\n}\n.sidebar a:hover { background: var(--color-bg-subtle); }\n.sidebar a.active { color: var(--color-accent); font-weight: 500; }\n\n/* Main content */\n.main-content {\n flex: 1;\n min-width: 0;\n display: flex;\n}\n.content-body {\n flex: 1;\n min-width: 0;\n padding: 32px 40px;\n max-width: 900px;\n}\n\n/* On this page nav (right side) */\n.on-this-page {\n width: 200px;\n min-width: 200px;\n padding: 32px 16px;\n position: sticky;\n top: 52px;\n height: calc(100vh - 52px);\n overflow-y: auto;\n}\n.on-this-page h4 {\n font-size: 11px;\n font-weight: 600;\n letter-spacing: 0.06em;\n text-transform: uppercase;\n color: var(--color-muted);\n margin: 0 0 8px;\n}\n.on-this-page a {\n display: block;\n padding: 3px 0;\n font-size: 12px;\n color: var(--color-muted);\n text-decoration: none;\n}\n.on-this-page a:hover { color: var(--color-text); }\n\n/* Component header */\n.component-header { margin-bottom: 32px; }\n.component-header h1 { font-size: 28px; font-weight: 700; margin: 0 0 8px; }\n.component-header .meta {\n display: flex;\n gap: 8px;\n align-items: center;\n flex-wrap: wrap;\n margin-bottom: 8px;\n}\n.badge {\n display: inline-flex;\n align-items: center;\n padding: 2px 8px;\n border-radius: 999px;\n font-size: 11px;\n font-weight: 500;\n border: 1px solid var(--color-border);\n color: var(--color-muted);\n background: var(--color-bg-subtle);\n}\n.badge.complex { border-color: #fbbf24; color: #92400e; background: #fffbeb; }\n.badge.simple { border-color: #6ee7b7; color: #065f46; background: #ecfdf5; }\n.badge.memoized { border-color: #a5b4fc; color: #3730a3; background: #eef2ff; }\n\n.filepath {\n font-family: var(--font-mono);\n font-size: 12px;\n color: var(--color-muted);\n}\n\n/* Sections */\n.section {\n padding: 32px 0;\n border-bottom: 1px solid var(--color-border);\n}\n.section:last-child { border-bottom: none; }\n.section-header { margin-bottom: 20px; }\n.section-header h2 {\n font-size: 18px;\n font-weight: 600;\n margin: 0 0 4px;\n}\n.section-header p { color: var(--color-muted); margin: 0; font-size: 13px; }\n\n/* Not generated placeholder */\n.not-generated {\n background: var(--color-bg-subtle);\n border: 1px dashed var(--color-border);\n border-radius: var(--radius);\n padding: 32px;\n text-align: center;\n color: var(--color-muted);\n font-size: 13px;\n}\n\n/* Render preview */\n.render-preview {\n border: 1px solid var(--color-border);\n border-radius: var(--radius);\n overflow: hidden;\n background: #f8f8f8;\n display: inline-block;\n max-width: 100%;\n}\n.render-preview img { display: block; max-width: 100%; }\n\n/* Props table */\n.props-table { width: 100%; border-collapse: collapse; font-size: 13px; }\n.props-table th {\n text-align: left;\n font-weight: 600;\n font-size: 11px;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n color: var(--color-muted);\n padding: 8px 12px;\n border-bottom: 2px solid var(--color-border);\n}\n.props-table td {\n padding: 8px 12px;\n border-bottom: 1px solid var(--color-border);\n vertical-align: top;\n}\n.props-table tr:last-child td { border-bottom: none; }\n.prop-name { font-family: var(--font-mono); font-size: 12px; font-weight: 700; }\n.prop-type { font-family: var(--font-mono); font-size: 11px; color: var(--color-accent); }\n.prop-required { color: var(--color-error); font-size: 11px; }\n.prop-default { font-family: var(--font-mono); font-size: 11px; color: var(--color-muted); }\n\n/* Code blocks */\npre.code-block {\n background: var(--color-bg-code);\n color: #e2e8f0;\n border-radius: var(--radius);\n padding: 16px 20px;\n overflow-x: auto;\n font-family: var(--font-mono);\n font-size: 13px;\n line-height: 1.6;\n margin: 0;\n}\n.token-keyword { color: #c792ea; }\n.token-string { color: #c3e88d; }\n.token-comment { color: #546e7a; font-style: italic; }\n.token-tag { color: #f07178; }\n.token-attr { color: #ffcb6b; }\n.token-number { color: #f78c6c; }\n\n/* Stats grid */\n.stats-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));\n gap: 12px;\n margin-bottom: 24px;\n}\n.stat-card {\n background: var(--color-bg-subtle);\n border: 1px solid var(--color-border);\n border-radius: var(--radius);\n padding: 16px;\n}\n.stat-card .stat-label { font-size: 11px; color: var(--color-muted); text-transform: uppercase; letter-spacing: 0.05em; margin-bottom: 4px; }\n.stat-card .stat-value { font-size: 22px; font-weight: 700; }\n\n/* Analysis grid */\n.analysis-grid {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 16px;\n}\n.analysis-card {\n background: var(--color-bg-subtle);\n border: 1px solid var(--color-border);\n border-radius: var(--radius);\n padding: 16px;\n}\n.analysis-card h3 { font-size: 12px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; color: var(--color-muted); margin: 0 0 8px; }\n.analysis-card .value { font-size: 14px; }\n.tag-list { display: flex; flex-wrap: wrap; gap: 4px; }\n.tag {\n display: inline-block;\n padding: 2px 8px;\n background: var(--color-border);\n border-radius: 4px;\n font-family: var(--font-mono);\n font-size: 11px;\n}\n\n/* Token pills */\n.pill-on {\n display: inline-flex; align-items: center; gap: 4px;\n padding: 2px 8px; border-radius: 999px;\n background: #dcfce7; color: #166534;\n font-size: 11px; font-weight: 500;\n}\n.pill-off {\n display: inline-flex; align-items: center; gap: 4px;\n padding: 2px 8px; border-radius: 999px;\n background: #fef3c7; color: #92400e;\n font-size: 11px; font-weight: 500;\n}\n\n/* Compliance bar */\n.compliance-bar-container { margin-bottom: 16px; }\n.compliance-bar-bg { background: var(--color-border); border-radius: 999px; height: 8px; overflow: hidden; }\n.compliance-bar-fill { height: 100%; border-radius: 999px; background: var(--color-success); }\n.compliance-label { font-size: 13px; color: var(--color-muted); margin-bottom: 4px; }\n\n/* Token table */\n.token-table { width: 100%; border-collapse: collapse; font-size: 12px; }\n.token-table th {\n text-align: left; font-weight: 600; font-size: 11px;\n text-transform: uppercase; letter-spacing: 0.05em;\n color: var(--color-muted); padding: 6px 10px;\n border-bottom: 2px solid var(--color-border);\n}\n.token-table td { padding: 6px 10px; border-bottom: 1px solid var(--color-border); vertical-align: top; }\n.token-table tr:last-child td { border-bottom: none; }\n.token-path { font-family: var(--font-mono); color: var(--color-accent); }\n.token-value-swatch { display: inline-block; width: 12px; height: 12px; border-radius: 2px; border: 1px solid var(--color-border); margin-right: 4px; vertical-align: middle; }\n\n/* A11y violations */\n.violation-list { list-style: none; padding: 0; margin: 0; }\n.violation-list li {\n padding: 8px 12px;\n background: #fef2f2;\n border: 1px solid #fecaca;\n border-radius: var(--radius);\n margin-bottom: 6px;\n font-size: 13px;\n color: #991b1b;\n}\n.a11y-role-badge { font-family: var(--font-mono); font-size: 11px; background: var(--color-bg-subtle); border: 1px solid var(--color-border); padding: 2px 6px; border-radius: 4px; }\n\n/* Matrix grid */\n.matrix-grid {\n display: grid;\n gap: 1px;\n background: var(--color-border);\n border: 1px solid var(--color-border);\n border-radius: var(--radius);\n overflow: hidden;\n}\n.matrix-cell { background: var(--color-bg); padding: 8px; text-align: center; }\n.matrix-cell img { max-width: 100%; border-radius: 2px; }\n.matrix-cell .cell-label { font-size: 10px; color: var(--color-muted); margin-top: 4px; }\n.matrix-header { background: var(--color-bg-subtle); padding: 6px 8px; font-size: 11px; font-weight: 600; color: var(--color-muted); }\n\n/* DOM tree */\n.dom-tree { font-family: var(--font-mono); font-size: 12px; line-height: 1.8; }\ndetails.dom-node > summary { cursor: pointer; list-style: none; }\ndetails.dom-node > summary::-webkit-details-marker { display: none; }\n.dom-tag-open { color: #f07178; }\n.dom-attr-name { color: #ffcb6b; }\n.dom-attr-value { color: #c3e88d; }\n.dom-text { color: #a0a0b0; font-style: italic; }\n\n/* Composition graph */\n.composition-lists { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }\n.comp-list h3 { font-size: 13px; font-weight: 600; margin: 0 0 8px; color: var(--color-muted); }\n.comp-list ul { list-style: none; padding: 0; margin: 0; }\n.comp-list li { padding: 4px 0; font-size: 13px; border-bottom: 1px solid var(--color-border); }\n.comp-list a { color: var(--color-accent); text-decoration: none; }\n.comp-list a:hover { text-decoration: underline; }\n\n/* Index page */\n.index-header { margin-bottom: 32px; }\n.index-header h1 { font-size: 32px; font-weight: 700; margin: 0 0 8px; }\n.index-header p { color: var(--color-muted); font-size: 15px; margin: 0; }\n.component-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));\n gap: 16px;\n}\n.component-card {\n border: 1px solid var(--color-border);\n border-radius: var(--radius);\n overflow: hidden;\n text-decoration: none;\n color: var(--color-text);\n transition: box-shadow 0.15s;\n display: block;\n}\n.component-card:hover { box-shadow: var(--shadow); }\n.card-preview {\n background: #f8f8f8;\n height: 160px;\n overflow: hidden;\n display: flex;\n align-items: center;\n justify-content: center;\n border-bottom: 1px solid var(--color-border);\n}\n.card-preview img { max-width: 100%; max-height: 100%; object-fit: contain; }\n.card-preview .no-preview { color: var(--color-muted); font-size: 12px; }\n.card-body { padding: 12px 16px; }\n.card-name { font-weight: 600; font-size: 14px; margin-bottom: 4px; }\n.card-meta { font-size: 12px; color: var(--color-muted); display: flex; gap: 8px; }\n\n/* Dashboard */\n.dashboard-header { margin-bottom: 32px; }\n.dashboard-header h1 { font-size: 28px; font-weight: 700; margin: 0 0 8px; }\n.section-title { font-size: 16px; font-weight: 600; margin: 0 0 16px; }\n\n/* Responsive */\n@media (max-width: 1024px) {\n .on-this-page { display: none; }\n}\n@media (max-width: 768px) {\n .sidebar { display: none; }\n .content-body { padding: 20px 16px; }\n .analysis-grid { grid-template-columns: 1fr; }\n .composition-lists { grid-template-columns: 1fr; }\n}`;\n\n return `<style>\\n${css}\\n</style>`;\n}\n","import { generateCSS } from \"../css.js\";\nimport { escapeHtml, slugify } from \"../utils.js\";\n\nexport function sidebarLinks(\n components: string[],\n currentSlug: string | null,\n basePath: string,\n): string {\n const links = components\n .sort()\n .map((name) => {\n const slug = slugify(name);\n const isActive = slug === currentSlug;\n return `<a href=\"${basePath}${slug}.html\" class=\"${isActive ? \"active\" : \"\"}\">${escapeHtml(name)}</a>`;\n })\n .join(\"\\n\");\n\n return `<div class=\"sidebar-heading\">Components</div>\\n${links}`;\n}\n\nexport function htmlShell(options: {\n title: string;\n body: string;\n sidebar: string;\n onThisPage: string;\n basePath: string;\n}): string {\n const { title, body, sidebar, onThisPage, basePath } = options;\n\n return `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <title>${escapeHtml(title)}</title>\n ${generateCSS()}\n</head>\n<body>\n <nav class=\"top-nav\">\n <a class=\"site-title\" href=\"${basePath}index.html\">Scope</a>\n <div class=\"spacer\"></div>\n <input\n class=\"search-box\"\n type=\"search\"\n placeholder=\"Search components…\"\n id=\"sidebar-search\"\n aria-label=\"Search components\"\n />\n </nav>\n <div class=\"page-layout\">\n <nav class=\"sidebar\" id=\"sidebar\">\n ${sidebar}\n </nav>\n <div class=\"main-content\">\n <div class=\"content-body\">\n ${body}\n </div>\n <nav class=\"on-this-page\">\n <h4>On this page</h4>\n ${onThisPage}\n </nav>\n </div>\n </div>\n <script>\n (function () {\n var search = document.getElementById('sidebar-search');\n var sidebar = document.getElementById('sidebar');\n if (!search || !sidebar) return;\n search.addEventListener('input', function () {\n var q = search.value.toLowerCase();\n var links = sidebar.querySelectorAll('a');\n links.forEach(function (link) {\n var text = link.textContent || '';\n link.style.display = text.toLowerCase().includes(q) ? '' : 'none';\n });\n });\n })();\n </script>\n</body>\n</html>`;\n}\n","import type { SiteData } from \"../types.js\";\nimport { escapeHtml, propTableRow, renderDOMTree, slugify } from \"../utils.js\";\nimport { htmlShell, sidebarLinks } from \"./layout.js\";\n\nconst SECTIONS = [\n \"Playground\",\n \"Matrix\",\n \"Docs\",\n \"Analysis\",\n \"X-Ray\",\n \"Tokens\",\n \"Accessibility\",\n \"Composition\",\n \"Responsive\",\n \"Stress Tests\",\n];\n\nfunction notGenerated(message = \"Not generated\"): string {\n return `<div class=\"not-generated\">${escapeHtml(message)}</div>`;\n}\n\nfunction sectionWrap(id: string, title: string, description: string, content: string): string {\n return `<section class=\"section\" id=\"${id}\">\n <div class=\"section-header\">\n <h2>${escapeHtml(title)}</h2>\n <p>${escapeHtml(description)}</p>\n </div>\n ${content}\n</section>`;\n}\n\nfunction renderPlayground(name: string, data: SiteData): string {\n const component = data.manifest.components[name];\n const render = data.renders.get(name);\n\n const props = component ? Object.entries(component.props) : [];\n const propsTable =\n props.length > 0\n ? `<table class=\"props-table\">\n <thead>\n <tr>\n <th>Prop</th>\n <th>Type</th>\n <th>Required</th>\n <th>Default</th>\n </tr>\n </thead>\n <tbody>\n ${props.map(([n, p]) => propTableRow(n, p)).join(\"\\n \")}\n </tbody>\n</table>`\n : `<p style=\"color:var(--color-muted);font-size:13px\">No props defined.</p>`;\n\n const renderHtml = render?.screenshot\n ? `<div class=\"render-preview\">\n <img src=\"data:image/png;base64,${render.screenshot}\" alt=\"${escapeHtml(name)} render\" />\n</div>`\n : notGenerated(\"Render not generated. Run scope render to produce screenshots.\");\n\n return sectionWrap(\n \"playground\",\n \"Playground\",\n \"Props reference and rendered preview.\",\n `${propsTable}\n<div style=\"margin-top:24px\">${renderHtml}</div>`,\n );\n}\n\nfunction renderMatrix(name: string, data: SiteData): string {\n const render = data.renders.get(name);\n\n if (!render?.cells || render.cells.length === 0) {\n return sectionWrap(\n \"matrix\",\n \"Matrix\",\n \"Prop combination matrix renders.\",\n notGenerated(\"Matrix renders not generated. Run scope render --matrix to produce a matrix.\"),\n );\n }\n\n const cells = render.cells;\n const cols = Math.ceil(Math.sqrt(cells.length));\n\n const cellsHtml = cells\n .map((cell) => {\n const label = cell.axisValues.join(\" / \");\n const imgHtml = cell.screenshot\n ? `<img src=\"data:image/png;base64,${cell.screenshot}\" alt=\"${escapeHtml(label)}\" />`\n : `<span style=\"color:var(--color-muted);font-size:11px\">${cell.error ? escapeHtml(cell.error) : \"failed\"}</span>`;\n return `<div class=\"matrix-cell\">${imgHtml}<div class=\"cell-label\">${escapeHtml(label)}</div></div>`;\n })\n .join(\"\\n\");\n\n const grid = `<div class=\"matrix-grid\" style=\"grid-template-columns: repeat(${cols}, 1fr)\">\n${cellsHtml}\n</div>`;\n\n return sectionWrap(\"matrix\", \"Matrix\", \"Prop combination matrix renders.\", grid);\n}\n\nfunction renderDocs(): string {\n return sectionWrap(\n \"docs\",\n \"Docs\",\n \"Component documentation.\",\n `<p style=\"color:var(--color-muted);font-size:13px\">No documentation file found for this component.</p>`,\n );\n}\n\nfunction renderAnalysis(name: string, data: SiteData): string {\n const component = data.manifest.components[name];\n if (!component) {\n return sectionWrap(\"analysis\", \"Analysis\", \"Static analysis results.\", notGenerated());\n }\n\n const propCount = Object.keys(component.props).length;\n const hookCount = component.detectedHooks.length;\n const sideEffectCount =\n component.sideEffects.fetches.length +\n (component.sideEffects.timers ? 1 : 0) +\n component.sideEffects.subscriptions.length +\n (component.sideEffects.globalListeners ? 1 : 0);\n\n const statsGrid = `<div class=\"stats-grid\">\n <div class=\"stat-card\">\n <div class=\"stat-label\">Complexity</div>\n <div class=\"stat-value\"><span class=\"badge ${component.complexityClass}\">${escapeHtml(component.complexityClass)}</span></div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-label\">Props</div>\n <div class=\"stat-value\">${propCount}</div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-label\">Hooks</div>\n <div class=\"stat-value\">${hookCount}</div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-label\">Side Effects</div>\n <div class=\"stat-value\">${sideEffectCount}</div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-label\">Export</div>\n <div class=\"stat-value\" style=\"font-size:14px\">${escapeHtml(component.exportType)}</div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-label\">Memoized</div>\n <div class=\"stat-value\" style=\"font-size:14px\">${component.memoized ? \"Yes\" : \"No\"}</div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-label\">forwardedRef</div>\n <div class=\"stat-value\" style=\"font-size:14px\">${component.forwardedRef ? \"Yes\" : \"No\"}</div>\n </div>\n</div>`;\n\n function tagList(items: string[]): string {\n if (items.length === 0)\n return `<span style=\"color:var(--color-muted);font-size:12px\">None</span>`;\n return `<div class=\"tag-list\">${items.map((i) => `<span class=\"tag\">${escapeHtml(i)}</span>`).join(\"\")}</div>`;\n }\n\n const sideEffectItems: string[] = [\n ...component.sideEffects.fetches.map((f) => `fetch: ${f}`),\n ...(component.sideEffects.timers ? [\"timers\"] : []),\n ...component.sideEffects.subscriptions.map((s) => `sub: ${s}`),\n ...(component.sideEffects.globalListeners ? [\"global listeners\"] : []),\n ];\n\n const analysisGrid = `<div class=\"analysis-grid\">\n <div class=\"analysis-card\">\n <h3>Detected Hooks</h3>\n <div class=\"value\">${tagList(component.detectedHooks)}</div>\n </div>\n <div class=\"analysis-card\">\n <h3>Required Contexts</h3>\n <div class=\"value\">${tagList(component.requiredContexts)}</div>\n </div>\n <div class=\"analysis-card\">\n <h3>HOC Wrappers</h3>\n <div class=\"value\">${tagList(component.hocWrappers)}</div>\n </div>\n <div class=\"analysis-card\">\n <h3>Side Effects</h3>\n <div class=\"value\">${tagList(sideEffectItems)}</div>\n </div>\n</div>`;\n\n return sectionWrap(\n \"analysis\",\n \"Analysis\",\n \"Static analysis results for this component.\",\n `${statsGrid}${analysisGrid}`,\n );\n}\n\nfunction renderXRay(name: string, data: SiteData): string {\n const render = data.renders.get(name);\n\n if (!render?.dom) {\n return sectionWrap(\n \"x-ray\",\n \"X-Ray\",\n \"DOM structure and computed styles.\",\n notGenerated(\"X-Ray data not generated. Run scope render with DOM capture enabled.\"),\n );\n }\n\n const dom = render.dom;\n const treeHtml = `<div class=\"dom-tree\">${renderDOMTree(dom.tree)}</div>`;\n\n const stylesHtml =\n render.computedStyles && Object.keys(render.computedStyles).length > 0\n ? `<details style=\"margin-top:16px\">\n <summary style=\"cursor:pointer;font-size:13px;font-weight:600;margin-bottom:8px\">Computed Styles</summary>\n <table class=\"token-table\" style=\"margin-top:8px\">\n <thead><tr><th>Selector</th><th>Property</th><th>Value</th></tr></thead>\n <tbody>\n ${Object.entries(render.computedStyles)\n .flatMap(([selector, styles]) =>\n Object.entries(styles).map(\n ([prop, val]) =>\n `<tr><td class=\"token-path\">${escapeHtml(selector)}</td><td>${escapeHtml(prop)}</td><td>${escapeHtml(val)}</td></tr>`,\n ),\n )\n .join(\"\\n \")}\n </tbody>\n </table>\n</details>`\n : \"\";\n\n return sectionWrap(\n \"x-ray\",\n \"X-Ray\",\n `DOM structure — ${dom.elementCount} elements.`,\n `${treeHtml}${stylesHtml}`,\n );\n}\n\nfunction renderTokens(name: string, data: SiteData): string {\n if (!data.complianceBatch) {\n return sectionWrap(\n \"tokens\",\n \"Tokens\",\n \"Design token compliance.\",\n notGenerated(\"Compliance data not generated. Run scope tokens to audit design tokens.\"),\n );\n }\n\n const report = data.complianceBatch.components[name];\n if (!report) {\n return sectionWrap(\n \"tokens\",\n \"Tokens\",\n \"Design token compliance.\",\n notGenerated(\"No compliance report found for this component.\"),\n );\n }\n\n const pct = Math.round(report.compliance * 100);\n const barHtml = `<div class=\"compliance-bar-container\">\n <div class=\"compliance-label\">${pct}% on-system (${report.onSystem} / ${report.total} properties)</div>\n <div class=\"compliance-bar-bg\">\n <div class=\"compliance-bar-fill\" style=\"width:${pct}%\"></div>\n </div>\n</div>`;\n\n const rows = Object.entries(report.properties)\n .map(([prop, result]) => {\n const pill =\n result.status === \"on_system\"\n ? `<span class=\"pill-on\">✓ ${escapeHtml(result.token ?? \"\")}</span>`\n : `<span class=\"pill-off\">✗ off-system</span>`;\n\n const swatchStyle = result.value.startsWith(\"#\")\n ? ` style=\"background:${escapeHtml(result.value)}\"`\n : \"\";\n\n const nearestHtml = result.nearest\n ? `<span style=\"color:var(--color-muted);font-size:10px\"> nearest: ${escapeHtml(result.nearest.token)}</span>`\n : \"\";\n\n return `<tr>\n <td class=\"token-path\">${escapeHtml(prop)}</td>\n <td><span class=\"token-value-swatch\"${swatchStyle}></span>${escapeHtml(result.value)}</td>\n <td>${pill}${nearestHtml}</td>\n </tr>`;\n })\n .join(\"\\n \");\n\n const tableHtml = `<table class=\"token-table\">\n <thead><tr><th>Property</th><th>Value</th><th>Status</th></tr></thead>\n <tbody>${rows}</tbody>\n</table>`;\n\n return sectionWrap(\n \"tokens\",\n \"Tokens\",\n \"Design token compliance audit.\",\n `${barHtml}${tableHtml}`,\n );\n}\n\nfunction renderAccessibility(name: string, data: SiteData): string {\n const render = data.renders.get(name);\n\n if (!render?.accessibility) {\n return sectionWrap(\n \"accessibility\",\n \"Accessibility\",\n \"Accessibility audit results.\",\n notGenerated(\n \"Accessibility data not generated. Run scope render with accessibility capture enabled.\",\n ),\n );\n }\n\n const a11y = render.accessibility;\n const roleBadge = `<span class=\"a11y-role-badge\">${escapeHtml(a11y.role)}</span>`;\n\n const violationsHtml =\n a11y.violations.length > 0\n ? `<ul class=\"violation-list\">${a11y.violations.map((v) => `<li>${escapeHtml(v)}</li>`).join(\"\")}</ul>`\n : `<p style=\"color:var(--color-success);font-size:13px\">✓ No violations found.</p>`;\n\n return sectionWrap(\n \"accessibility\",\n \"Accessibility\",\n \"Accessibility audit results.\",\n `<p style=\"font-size:13px;margin:0 0 12px\">Role: ${roleBadge} &nbsp; Name: <em>${escapeHtml(a11y.name || \"(none)\")}</em></p>\n${violationsHtml}`,\n );\n}\n\nfunction renderComposition(name: string, data: SiteData): string {\n const component = data.manifest.components[name];\n\n if (!component || (component.composes.length === 0 && component.composedBy.length === 0)) {\n return sectionWrap(\n \"composition\",\n \"Composition\",\n \"Component dependency graph.\",\n `<p style=\"color:var(--color-muted);font-size:13px\">This component stands alone.</p>`,\n );\n }\n\n function compList(title: string, items: string[]): string {\n if (items.length === 0) {\n return `<div class=\"comp-list\"><h3>${escapeHtml(title)}</h3><p style=\"color:var(--color-muted);font-size:12px\">None</p></div>`;\n }\n const liItems = items\n .map(\n (n) => `<li><a href=\"${data.options.basePath}${slugify(n)}.html\">${escapeHtml(n)}</a></li>`,\n )\n .join(\"\");\n return `<div class=\"comp-list\"><h3>${escapeHtml(title)}</h3><ul>${liItems}</ul></div>`;\n }\n\n return sectionWrap(\n \"composition\",\n \"Composition\",\n \"Component dependency graph.\",\n `<div class=\"composition-lists\">\n ${compList(\"Composes\", component.composes)}\n ${compList(\"Composed By\", component.composedBy)}\n</div>`,\n );\n}\n\nexport function renderComponentDetail(name: string, data: SiteData): string {\n const component = data.manifest.components[name];\n const slug = slugify(name);\n\n const complexityBadge = component\n ? `<span class=\"badge ${component.complexityClass}\">${escapeHtml(component.complexityClass)}</span>`\n : \"\";\n const memoizedBadge = component?.memoized ? `<span class=\"badge memoized\">memo</span>` : \"\";\n const exportBadge = component\n ? `<span class=\"badge\">${escapeHtml(component.exportType)}</span>`\n : \"\";\n const filepath = component ? `<div class=\"filepath\">${escapeHtml(component.filePath)}</div>` : \"\";\n\n const header = `<div class=\"component-header\">\n <h1>${escapeHtml(name)}</h1>\n <div class=\"meta\">${complexityBadge}${memoizedBadge}${exportBadge}</div>\n ${filepath}\n</div>`;\n\n const sections = [\n renderPlayground(name, data),\n renderMatrix(name, data),\n renderDocs(),\n renderAnalysis(name, data),\n renderXRay(name, data),\n renderTokens(name, data),\n renderAccessibility(name, data),\n renderComposition(name, data),\n sectionWrap(\n \"responsive\",\n \"Responsive\",\n \"Multi-viewport renders.\",\n notGenerated(\n \"Responsive renders not generated. Multi-viewport rendering is a future feature.\",\n ),\n ),\n sectionWrap(\n \"stress-tests\",\n \"Stress Tests\",\n \"Edge case and stress test renders.\",\n notGenerated(\"Stress tests not generated. Stress render runs are a future feature.\"),\n ),\n ];\n\n const body = `${header}${sections.join(\"\\n\")}`;\n\n const onThisPage = SECTIONS.map((s) => {\n const id = s.toLowerCase().replace(/\\s+/g, \"-\");\n return `<a href=\"#${id}\">${escapeHtml(s)}</a>`;\n }).join(\"\\n\");\n\n const componentNames = Object.keys(data.manifest.components);\n const sidebar = sidebarLinks(componentNames, slug, data.options.basePath);\n\n return htmlShell({\n title: `${name} — ${data.options.title}`,\n body,\n sidebar,\n onThisPage,\n basePath: data.options.basePath,\n });\n}\n","import type { SiteData } from \"../types.js\";\nimport { escapeHtml, slugify } from \"../utils.js\";\nimport { htmlShell, sidebarLinks } from \"./layout.js\";\n\nexport function renderComponentIndex(data: SiteData): string {\n const components = Object.entries(data.manifest.components);\n const totalCount = components.length;\n const simpleCount = components.filter(([, c]) => c.complexityClass === \"simple\").length;\n const complexCount = components.filter(([, c]) => c.complexityClass === \"complex\").length;\n const memoizedCount = components.filter(([, c]) => c.memoized).length;\n\n const statsGrid = `<div class=\"stats-grid\">\n <div class=\"stat-card\">\n <div class=\"stat-label\">Total Components</div>\n <div class=\"stat-value\">${totalCount}</div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-label\">Simple</div>\n <div class=\"stat-value\">${simpleCount}</div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-label\">Complex</div>\n <div class=\"stat-value\">${complexCount}</div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-label\">Memoized</div>\n <div class=\"stat-value\">${memoizedCount}</div>\n </div>\n</div>`;\n\n const cards = components\n .sort(([a], [b]) => a.localeCompare(b))\n .map(([name, component]) => {\n const slug = slugify(name);\n const render = data.renders.get(name);\n const propCount = Object.keys(component.props).length;\n const hookCount = component.detectedHooks.length;\n\n const previewHtml = render?.screenshot\n ? `<img src=\"data:image/png;base64,${render.screenshot}\" alt=\"${escapeHtml(name)}\" />`\n : `<span class=\"no-preview\">No preview</span>`;\n\n return `<a class=\"component-card\" href=\"${data.options.basePath}${slug}.html\" data-name=\"${escapeHtml(name.toLowerCase())}\">\n <div class=\"card-preview\">${previewHtml}</div>\n <div class=\"card-body\">\n <div class=\"card-name\">${escapeHtml(name)}</div>\n <div class=\"card-meta\">\n <span>${propCount} props</span>\n <span class=\"badge ${component.complexityClass}\" style=\"font-size:10px\">${escapeHtml(component.complexityClass)}</span>\n ${hookCount > 0 ? `<span>${hookCount} hooks</span>` : \"\"}\n </div>\n </div>\n</a>`;\n })\n .join(\"\\n\");\n\n const cardGrid = `<div class=\"component-grid\" id=\"component-grid\">${cards}</div>`;\n\n const filterScript = `<script>\n(function () {\n var grid = document.getElementById('component-grid');\n var search = document.getElementById('sidebar-search');\n if (!grid || !search) return;\n var indexSearch = document.getElementById('index-search');\n function filter(q) {\n var cards = grid.querySelectorAll('.component-card');\n cards.forEach(function (card) {\n var name = card.getAttribute('data-name') || '';\n card.style.display = name.includes(q) ? '' : 'none';\n });\n }\n search.addEventListener('input', function () { filter(search.value.toLowerCase()); });\n if (indexSearch) {\n indexSearch.addEventListener('input', function () { filter(indexSearch.value.toLowerCase()); });\n }\n})();\n</script>`;\n\n const header = `<div class=\"index-header\">\n <h1>${escapeHtml(data.options.title)}</h1>\n <p>${totalCount} component${totalCount === 1 ? \"\" : \"s\"} analysed</p>\n <input class=\"search-box\" type=\"search\" id=\"index-search\" placeholder=\"Filter components…\" style=\"margin-top:12px\" />\n</div>`;\n\n const body = `${header}${statsGrid}${cardGrid}${filterScript}`;\n\n const componentNames = Object.keys(data.manifest.components);\n const sidebar = sidebarLinks(componentNames, null, data.options.basePath);\n\n const onThisPage = `<a href=\"#top\">Overview</a>\\n<a href=\"#component-grid\">Components</a>`;\n\n return htmlShell({\n title: data.options.title,\n body,\n sidebar,\n onThisPage,\n basePath: data.options.basePath,\n });\n}\n","import type { SiteData } from \"../types.js\";\nimport { escapeHtml, slugify } from \"../utils.js\";\nimport { htmlShell, sidebarLinks } from \"./layout.js\";\n\nexport function renderDashboard(data: SiteData): string {\n const components = Object.entries(data.manifest.components);\n const totalCount = components.length;\n\n const simpleCount = components.filter(([, c]) => c.complexityClass === \"simple\").length;\n const complexCount = components.filter(([, c]) => c.complexityClass === \"complex\").length;\n const renderedCount = components.filter(([name]) => data.renders.has(name)).length;\n\n const totalProps = components.reduce((sum, [, c]) => sum + Object.keys(c.props).length, 0);\n const avgProps = totalCount > 0 ? Math.round(totalProps / totalCount) : 0;\n\n let overallCompliance: number | null = null;\n if (data.complianceBatch) {\n const reports = Object.values(data.complianceBatch.components);\n if (reports.length > 0) {\n overallCompliance = Math.round(\n (reports.reduce((sum, r) => sum + r.compliance, 0) / reports.length) * 100,\n );\n }\n }\n\n const statsGrid = `<div class=\"stats-grid\" style=\"margin-bottom:32px\">\n <div class=\"stat-card\">\n <div class=\"stat-label\">Total Components</div>\n <div class=\"stat-value\">${totalCount}</div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-label\">Avg Props</div>\n <div class=\"stat-value\">${avgProps}</div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-label\">With Renders</div>\n <div class=\"stat-value\">${renderedCount}</div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-label\">Compliance</div>\n <div class=\"stat-value\">${overallCompliance !== null ? `${overallCompliance}%` : \"—\"}</div>\n </div>\n</div>`;\n\n // Complexity breakdown\n const complexitySection = `<div class=\"section\" style=\"padding:24px 0;border-bottom:1px solid var(--color-border)\">\n <h2 class=\"section-title\">Complexity Breakdown</h2>\n <div class=\"stats-grid\">\n <div class=\"stat-card\">\n <div class=\"stat-label\">Simple</div>\n <div class=\"stat-value\" style=\"color:var(--color-success)\">${simpleCount}</div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-label\">Complex</div>\n <div class=\"stat-value\" style=\"color:var(--color-warn)\">${complexCount}</div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-label\">Simple %</div>\n <div class=\"stat-value\">${totalCount > 0 ? Math.round((simpleCount / totalCount) * 100) : 0}%</div>\n </div>\n </div>\n</div>`;\n\n // Top components by prop count\n const topByProps = components\n .sort(([, a], [, b]) => Object.keys(b.props).length - Object.keys(a.props).length)\n .slice(0, 10);\n\n const topPropsRows = topByProps\n .map(([name, component]) => {\n const slug = slugify(name);\n const propCount = Object.keys(component.props).length;\n return `<tr>\n <td><a href=\"${data.options.basePath}${slug}.html\" style=\"color:var(--color-accent);text-decoration:none\">${escapeHtml(name)}</a></td>\n <td>${propCount}</td>\n <td><span class=\"badge ${component.complexityClass}\">${escapeHtml(component.complexityClass)}</span></td>\n </tr>`;\n })\n .join(\"\\n \");\n\n const topPropsSection = `<div class=\"section\" style=\"padding:24px 0;border-bottom:1px solid var(--color-border)\">\n <h2 class=\"section-title\">Top Components by Prop Count</h2>\n <table class=\"props-table\">\n <thead><tr><th>Component</th><th>Props</th><th>Complexity</th></tr></thead>\n <tbody>${topPropsRows}</tbody>\n </table>\n</div>`;\n\n // Compliance section\n let complianceSection = \"\";\n if (data.complianceBatch && overallCompliance !== null) {\n const complianceRows = Object.entries(data.complianceBatch.components)\n .sort(([, a], [, b]) => b.compliance - a.compliance)\n .map(([name, report]) => {\n const pct = Math.round(report.compliance * 100);\n const slug = slugify(name);\n const barHtml = `<div class=\"compliance-bar-bg\" style=\"min-width:120px\">\n <div class=\"compliance-bar-fill\" style=\"width:${pct}%\"></div>\n </div>`;\n return `<tr>\n <td><a href=\"${data.options.basePath}${slug}.html\" style=\"color:var(--color-accent);text-decoration:none\">${escapeHtml(name)}</a></td>\n <td>${pct}%</td>\n <td>${barHtml}</td>\n <td>${report.onSystem} / ${report.total}</td>\n </tr>`;\n })\n .join(\"\\n \");\n\n complianceSection = `<div class=\"section\" style=\"padding:24px 0\">\n <h2 class=\"section-title\">Design Token Compliance — ${overallCompliance}% overall</h2>\n <table class=\"props-table\">\n <thead><tr><th>Component</th><th>Score</th><th>Bar</th><th>On-System</th></tr></thead>\n <tbody>${complianceRows}</tbody>\n </table>\n</div>`;\n }\n\n const header = `<div class=\"dashboard-header\">\n <h1>Dashboard</h1>\n <p style=\"color:var(--color-muted);font-size:14px\">Overview of all ${totalCount} analysed components.</p>\n</div>`;\n\n const body = `${header}${statsGrid}${complexitySection}${topPropsSection}${complianceSection}`;\n\n const componentNames = Object.keys(data.manifest.components);\n const sidebar = sidebarLinks(componentNames, null, data.options.basePath);\n\n const onThisPage = `<a href=\"#top\">Overview</a>\n<a href=\"#complexity\">Complexity</a>\n<a href=\"#top-props\">Top by Props</a>\n${data.complianceBatch ? '<a href=\"#compliance\">Compliance</a>' : \"\"}`;\n\n return htmlShell({\n title: `Dashboard — ${data.options.title}`,\n body,\n sidebar,\n onThisPage,\n basePath: data.options.basePath,\n });\n}\n","import { mkdir, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { normalizeOptions, readSiteData } from \"./reader.js\";\nimport { renderComponentDetail } from \"./templates/component-detail.js\";\nimport { renderComponentIndex } from \"./templates/component-index.js\";\nimport { renderDashboard } from \"./templates/dashboard.js\";\nimport type { SiteOptions } from \"./types.js\";\nimport { slugify } from \"./utils.js\";\n\nexport async function buildSite(options?: SiteOptions): Promise<void> {\n const normalizedOptions = normalizeOptions(options);\n\n console.log(`[scope/site] Reading data from ${normalizedOptions.inputDir}…`);\n const data = await readSiteData(normalizedOptions);\n\n const componentNames = Object.keys(data.manifest.components);\n console.log(`[scope/site] Found ${componentNames.length} components.`);\n\n // Create output directory\n await mkdir(normalizedOptions.outputDir, { recursive: true });\n\n // Generate component detail pages\n for (const name of componentNames) {\n const slug = slugify(name);\n const html = renderComponentDetail(name, data);\n const outputPath = join(normalizedOptions.outputDir, `${slug}.html`);\n await writeFile(outputPath, html, \"utf-8\");\n console.log(`[scope/site] ✓ ${name} → ${slug}.html`);\n }\n\n // Generate index page\n const indexHtml = renderComponentIndex(data);\n await writeFile(join(normalizedOptions.outputDir, \"index.html\"), indexHtml, \"utf-8\");\n console.log(`[scope/site] ✓ index.html`);\n\n // Generate dashboard page\n const dashboardHtml = renderDashboard(data);\n await writeFile(join(normalizedOptions.outputDir, \"dashboard.html\"), dashboardHtml, \"utf-8\");\n console.log(`[scope/site] ✓ dashboard.html`);\n\n console.log(\n `[scope/site] Done. Site written to ${normalizedOptions.outputDir} (${componentNames.length + 2} files).`,\n );\n}\n"]}
1
+ {"version":3,"sources":["../src/reader.ts","../src/utils.ts","../src/css.ts","../src/templates/layout.ts","../src/templates/component-detail.ts","../src/templates/component-index.ts","../src/templates/dashboard.ts","../src/builder.ts"],"names":["join"],"mappings":"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AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAA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","file":"index.js","sourcesContent":["import { readdir, readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport type {\n ComplianceBatchData,\n ManifestData,\n RenderFileData,\n SiteData,\n SiteOptions,\n} from \"./types.js\";\n\nfunction normalizeOptions(options?: SiteOptions): Required<SiteOptions> {\n return {\n inputDir: options?.inputDir ?? \".reactscope\",\n outputDir: options?.outputDir ?? \".reactscope/site\",\n basePath: options?.basePath ?? \"/\",\n compliancePath: options?.compliancePath ?? \"\",\n title: options?.title ?? \"Scope — Component Gallery\",\n };\n}\n\nexport { normalizeOptions };\n\nasync function readJsonFile<T>(filePath: string): Promise<T> {\n const content = await readFile(filePath, \"utf-8\");\n return JSON.parse(content) as T;\n}\n\nexport async function readSiteData(options: Required<SiteOptions>): Promise<SiteData> {\n // 1. Read manifest\n const manifestPath = join(options.inputDir, \"manifest.json\");\n const manifest = await readJsonFile<ManifestData>(manifestPath);\n\n // 2. Scan renders directory\n const renders = new Map<string, RenderFileData>();\n const rendersDir = join(options.inputDir, \"renders\");\n\n try {\n const entries = await readdir(rendersDir);\n const jsonFiles = entries.filter((f) => f.endsWith(\".json\"));\n\n await Promise.all(\n jsonFiles.map(async (file) => {\n const componentName = file.replace(/\\.json$/, \"\");\n const filePath = join(rendersDir, file);\n try {\n const renderData = await readJsonFile<RenderFileData>(filePath);\n renders.set(componentName, renderData);\n } catch (err) {\n console.warn(\n `[scope/site] Warning: could not read render file ${filePath}:`,\n err instanceof Error ? err.message : String(err),\n );\n }\n }),\n );\n } catch {\n // renders directory may not exist — that's fine\n }\n\n // 3. Optionally read compliance JSON\n let complianceBatch: ComplianceBatchData | undefined;\n if (options.compliancePath) {\n try {\n complianceBatch = await readJsonFile<ComplianceBatchData>(options.compliancePath);\n } catch (err) {\n console.warn(\n `[scope/site] Warning: could not read compliance file ${options.compliancePath}:`,\n err instanceof Error ? err.message : String(err),\n );\n }\n }\n\n return {\n manifest,\n renders,\n complianceBatch,\n options,\n };\n}\n","import type { DOMNodeData, PropData } from \"./types.js\";\n\nexport function escapeHtml(str: string): string {\n return str\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\")\n .replace(/'/g, \"&#39;\");\n}\n\nexport function slugify(name: string): string {\n return name\n .replace(/([A-Z])/g, (m) => `-${m.toLowerCase()}`)\n .replace(/^-/, \"\")\n .replace(/[^a-z0-9-]/g, \"-\")\n .replace(/-+/g, \"-\")\n .replace(/^-|-$/g, \"\");\n}\n\nexport function syntaxHighlightJSX(code: string): string {\n const escaped = escapeHtml(code);\n\n return (\n escaped\n // Comments\n .replace(/(\\/\\/[^\\n]*)/g, '<span class=\"token-comment\">$1</span>')\n .replace(/(\\/\\*[\\s\\S]*?\\*\\/)/g, '<span class=\"token-comment\">$1</span>')\n // JSX tags\n .replace(/(&lt;\\/?)([\\w.]+)/g, '<span class=\"token-tag\">$1$2</span>')\n // JSX attributes (word followed by =)\n .replace(/\\b([\\w-]+)(?==)/g, '<span class=\"token-attr\">$1</span>')\n // Strings\n .replace(\n /(&quot;[^&]*&quot;|&#39;[^&]*&#39;|`[^`]*`)/g,\n '<span class=\"token-string\">$1</span>',\n )\n // Keywords\n .replace(\n /\\b(import|export|from|default|const|let|var|function|return|if|else|for|while|class|extends|type|interface|async|await|new|typeof|instanceof)\\b/g,\n '<span class=\"token-keyword\">$1</span>',\n )\n // Numbers\n .replace(/\\b(\\d+\\.?\\d*)\\b/g, '<span class=\"token-number\">$1</span>')\n );\n}\n\nexport function renderDOMTree(node: DOMNodeData, depth = 0): string {\n const indent = \" \".repeat(depth);\n\n // Filter to a short display version of attrs (skip long class strings for the summary line)\n const attrsHtml = Object.entries(node.attrs)\n .map(([k, v]) => {\n const display = v.length > 60 ? v.slice(0, 57) + \"…\" : v;\n return ` <span class=\"dom-attr-name\">${escapeHtml(k)}</span>=<span class=\"dom-attr-value\">\"${escapeHtml(display)}\"</span>`;\n })\n .join(\"\");\n\n const nodeIdAttr = node.nodeId !== undefined ? ` data-node-id=\"${node.nodeId}\"` : \"\";\n const clickable = node.nodeId !== undefined ? \" dom-node-clickable\" : \"\";\n\n const hasChildren = node.children.length > 0;\n const hasText = node.text !== undefined && node.text.trim().length > 0;\n\n if (!hasChildren && !hasText) {\n return `${indent}<span class=\"dom-tag-open${clickable}\"${nodeIdAttr}>&lt;${escapeHtml(node.tag)}${attrsHtml} /&gt;</span>\\n`;\n }\n\n const childrenHtml = node.children.map((child) => renderDOMTree(child, depth + 1)).join(\"\");\n const textHtml = hasText\n ? `${indent} <span class=\"dom-text\">${escapeHtml(node.text ?? \"\")}</span>\\n`\n : \"\";\n\n return `<details class=\"dom-node${clickable}\" ${depth < 2 ? \"open\" : \"\"}${nodeIdAttr}>\n${indent}<summary><span class=\"dom-tag-open\">&lt;${escapeHtml(node.tag)}${attrsHtml}&gt;</span></summary>\n${textHtml}${childrenHtml}${indent}<span class=\"dom-tag-close\">&lt;/${escapeHtml(node.tag)}&gt;</span>\n</details>`;\n}\n\nexport function propTableRow(name: string, prop: PropData): string {\n const valuesHtml =\n prop.values && prop.values.length > 0\n ? `<br><span style=\"color:var(--color-muted);font-size:11px\">${prop.values.map((v) => escapeHtml(v)).join(\" | \")}</span>`\n : \"\";\n\n const defaultHtml = prop.default !== undefined ? escapeHtml(prop.default) : \"—\";\n\n return `<tr>\n <td><span class=\"prop-name\">${escapeHtml(name)}</span></td>\n <td><span class=\"prop-type\">${escapeHtml(prop.type)}</span>${valuesHtml}</td>\n <td>${prop.required ? '<span class=\"prop-required\">required</span>' : '<span style=\"color:var(--color-muted)\">optional</span>'}</td>\n <td><span class=\"prop-default\">${defaultHtml}</span></td>\n </tr>`;\n}\n","export function generateCSS(): string {\n const css = `@import url('https://fonts.googleapis.com/css2?family=Inter:wght@100..900&family=JetBrains+Mono:wght@400;700&display=swap');\n\n:root {\n --color-text: #0f0f0f;\n --color-muted: #6b7280;\n --color-border: #e5e7eb;\n --color-bg: #ffffff;\n --color-bg-subtle: #f9fafb;\n --color-bg-code: #1a1a2e;\n --color-accent: #2563eb;\n --color-success: #16a34a;\n --color-warn: #d97706;\n --color-error: #dc2626;\n --font-body: 'Inter', system-ui, -apple-system, sans-serif;\n --font-mono: 'JetBrains Mono', 'Fira Code', monospace;\n --radius: 6px;\n --shadow-sm: 0 1px 2px rgba(0,0,0,0.05);\n --shadow: 0 1px 3px rgba(0,0,0,0.1), 0 1px 2px rgba(0,0,0,0.06);\n}\n\n*, *::before, *::after { box-sizing: border-box; }\n\nbody {\n font-family: var(--font-body);\n font-size: 14px;\n line-height: 1.6;\n color: var(--color-text);\n background: var(--color-bg);\n margin: 0;\n}\n\n/* Top nav */\n.top-nav {\n position: sticky;\n top: 0;\n z-index: 100;\n background: var(--color-bg);\n border-bottom: 1px solid var(--color-border);\n height: 52px;\n display: flex;\n align-items: center;\n padding: 0 24px;\n gap: 16px;\n}\n.top-nav .site-title { font-weight: 600; font-size: 15px; text-decoration: none; color: var(--color-text); }\n.top-nav .spacer { flex: 1; }\n.search-box {\n border: 1px solid var(--color-border);\n border-radius: var(--radius);\n padding: 6px 12px;\n font-family: var(--font-body);\n font-size: 13px;\n width: 240px;\n outline: none;\n background: var(--color-bg-subtle);\n}\n.search-box:focus { border-color: var(--color-accent); background: var(--color-bg); }\n\n/* Page layout */\n.page-layout {\n display: flex;\n min-height: calc(100vh - 52px);\n}\n\n/* Left sidebar (component list) */\n.sidebar {\n width: 220px;\n min-width: 220px;\n border-right: 1px solid var(--color-border);\n padding: 16px 0;\n position: sticky;\n top: 52px;\n height: calc(100vh - 52px);\n overflow-y: auto;\n}\n.sidebar-heading {\n font-size: 11px;\n font-weight: 600;\n letter-spacing: 0.06em;\n text-transform: uppercase;\n color: var(--color-muted);\n padding: 4px 16px 8px;\n}\n.sidebar a {\n display: block;\n padding: 5px 16px;\n font-size: 13px;\n color: var(--color-text);\n text-decoration: none;\n border-radius: 0;\n}\n.sidebar a:hover { background: var(--color-bg-subtle); }\n.sidebar a.active { color: var(--color-accent); font-weight: 500; }\n\n/* Main content */\n.main-content {\n flex: 1;\n min-width: 0;\n display: flex;\n}\n.content-body {\n flex: 1;\n min-width: 0;\n padding: 32px 40px;\n max-width: 900px;\n}\n\n/* On this page nav (right side) */\n.on-this-page {\n width: 200px;\n min-width: 200px;\n padding: 32px 16px;\n position: sticky;\n top: 52px;\n height: calc(100vh - 52px);\n overflow-y: auto;\n}\n.on-this-page h4 {\n font-size: 11px;\n font-weight: 600;\n letter-spacing: 0.06em;\n text-transform: uppercase;\n color: var(--color-muted);\n margin: 0 0 8px;\n}\n.on-this-page a {\n display: block;\n padding: 3px 0;\n font-size: 12px;\n color: var(--color-muted);\n text-decoration: none;\n}\n.on-this-page a:hover { color: var(--color-text); }\n\n/* Component header */\n.component-header { margin-bottom: 32px; }\n.component-header h1 { font-size: 28px; font-weight: 700; margin: 0 0 8px; }\n.component-header .meta {\n display: flex;\n gap: 8px;\n align-items: center;\n flex-wrap: wrap;\n margin-bottom: 8px;\n}\n.badge {\n display: inline-flex;\n align-items: center;\n padding: 2px 8px;\n border-radius: 999px;\n font-size: 11px;\n font-weight: 500;\n border: 1px solid var(--color-border);\n color: var(--color-muted);\n background: var(--color-bg-subtle);\n}\n.badge.complex { border-color: #fbbf24; color: #92400e; background: #fffbeb; }\n.badge.simple { border-color: #6ee7b7; color: #065f46; background: #ecfdf5; }\n.badge.memoized { border-color: #a5b4fc; color: #3730a3; background: #eef2ff; }\n\n.filepath {\n font-family: var(--font-mono);\n font-size: 12px;\n color: var(--color-muted);\n}\n\n/* Sections */\n.section {\n padding: 32px 0;\n border-bottom: 1px solid var(--color-border);\n}\n.section:last-child { border-bottom: none; }\n.section-header { margin-bottom: 20px; }\n.section-header h2 {\n font-size: 18px;\n font-weight: 600;\n margin: 0 0 4px;\n}\n.section-header p { color: var(--color-muted); margin: 0; font-size: 13px; }\n\n/* Not generated placeholder */\n.not-generated {\n background: var(--color-bg-subtle);\n border: 1px dashed var(--color-border);\n border-radius: var(--radius);\n padding: 32px;\n text-align: center;\n color: var(--color-muted);\n font-size: 13px;\n}\n\n/* Render preview */\n.render-preview {\n border: 1px solid var(--color-border);\n border-radius: var(--radius);\n overflow: hidden;\n background: #f8f8f8;\n display: inline-block;\n max-width: 100%;\n}\n.render-preview img { display: block; max-width: 100%; }\n.scope-screenshot { zoom: 0.5; display: block; image-rendering: -webkit-optimize-contrast; }\n\n/* Props table */\n.props-table { width: 100%; border-collapse: collapse; font-size: 13px; }\n.props-table th {\n text-align: left;\n font-weight: 600;\n font-size: 11px;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n color: var(--color-muted);\n padding: 8px 12px;\n border-bottom: 2px solid var(--color-border);\n}\n.props-table td {\n padding: 8px 12px;\n border-bottom: 1px solid var(--color-border);\n vertical-align: top;\n}\n.props-table tr:last-child td { border-bottom: none; }\n.prop-name { font-family: var(--font-mono); font-size: 12px; font-weight: 700; }\n.prop-type { font-family: var(--font-mono); font-size: 11px; color: var(--color-accent); }\n.prop-required { color: var(--color-error); font-size: 11px; }\n.prop-default { font-family: var(--font-mono); font-size: 11px; color: var(--color-muted); }\n\n/* Code blocks */\npre.code-block {\n background: var(--color-bg-code);\n color: #e2e8f0;\n border-radius: var(--radius);\n padding: 16px 20px;\n overflow-x: auto;\n font-family: var(--font-mono);\n font-size: 13px;\n line-height: 1.6;\n margin: 0;\n}\n.token-keyword { color: #c792ea; }\n.token-string { color: #c3e88d; }\n.token-comment { color: #546e7a; font-style: italic; }\n.token-tag { color: #f07178; }\n.token-attr { color: #ffcb6b; }\n.token-number { color: #f78c6c; }\n\n/* Stats grid */\n.stats-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));\n gap: 12px;\n margin-bottom: 24px;\n}\n.stat-card {\n background: var(--color-bg-subtle);\n border: 1px solid var(--color-border);\n border-radius: var(--radius);\n padding: 16px;\n}\n.stat-card .stat-label { font-size: 11px; color: var(--color-muted); text-transform: uppercase; letter-spacing: 0.05em; margin-bottom: 4px; }\n.stat-card .stat-value { font-size: 22px; font-weight: 700; }\n\n/* Analysis grid */\n.analysis-grid {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 16px;\n}\n.analysis-card {\n background: var(--color-bg-subtle);\n border: 1px solid var(--color-border);\n border-radius: var(--radius);\n padding: 16px;\n}\n.analysis-card h3 { font-size: 12px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; color: var(--color-muted); margin: 0 0 8px; }\n.analysis-card .value { font-size: 14px; }\n.tag-list { display: flex; flex-wrap: wrap; gap: 4px; }\n.tag {\n display: inline-block;\n padding: 2px 8px;\n background: var(--color-border);\n border-radius: 4px;\n font-family: var(--font-mono);\n font-size: 11px;\n}\n\n/* Token pills */\n.pill-on {\n display: inline-flex; align-items: center; gap: 4px;\n padding: 2px 8px; border-radius: 999px;\n background: #dcfce7; color: #166534;\n font-size: 11px; font-weight: 500;\n}\n.pill-off {\n display: inline-flex; align-items: center; gap: 4px;\n padding: 2px 8px; border-radius: 999px;\n background: #fef3c7; color: #92400e;\n font-size: 11px; font-weight: 500;\n}\n\n/* Compliance bar */\n.compliance-bar-container { margin-bottom: 16px; }\n.compliance-bar-bg { background: var(--color-border); border-radius: 999px; height: 8px; overflow: hidden; }\n.compliance-bar-fill { height: 100%; border-radius: 999px; background: var(--color-success); }\n.compliance-label { font-size: 13px; color: var(--color-muted); margin-bottom: 4px; }\n\n/* Token table */\n.token-table { width: 100%; border-collapse: collapse; font-size: 12px; }\n.token-table th {\n text-align: left; font-weight: 600; font-size: 11px;\n text-transform: uppercase; letter-spacing: 0.05em;\n color: var(--color-muted); padding: 6px 10px;\n border-bottom: 2px solid var(--color-border);\n}\n.token-table td { padding: 6px 10px; border-bottom: 1px solid var(--color-border); vertical-align: top; }\n.token-table tr:last-child td { border-bottom: none; }\n.token-path { font-family: var(--font-mono); color: var(--color-accent); }\n.token-value-swatch { display: inline-block; width: 12px; height: 12px; border-radius: 2px; border: 1px solid var(--color-border); margin-right: 4px; vertical-align: middle; }\n\n/* A11y violations */\n.violation-list { list-style: none; padding: 0; margin: 0; }\n.violation-list li {\n padding: 8px 12px;\n background: #fef2f2;\n border: 1px solid #fecaca;\n border-radius: var(--radius);\n margin-bottom: 6px;\n font-size: 13px;\n color: #991b1b;\n}\n.a11y-role-badge { font-family: var(--font-mono); font-size: 11px; background: var(--color-bg-subtle); border: 1px solid var(--color-border); padding: 2px 6px; border-radius: 4px; }\n\n/* Matrix grid */\n.matrix-grid {\n display: grid;\n gap: 1px;\n background: var(--color-border);\n border: 1px solid var(--color-border);\n border-radius: var(--radius);\n overflow: hidden;\n}\n.matrix-cell { background: var(--color-bg); padding: 8px; text-align: center; }\n.matrix-cell img { border-radius: 2px; }\n.matrix-cell .cell-label { font-size: 10px; color: var(--color-muted); margin-top: 4px; }\n.matrix-header { background: var(--color-bg-subtle); padding: 6px 8px; font-size: 11px; font-weight: 600; color: var(--color-muted); }\n\n/* DOM tree */\n.dom-tree { font-family: var(--font-mono); font-size: 12px; line-height: 1.8; }\ndetails.dom-node > summary { cursor: pointer; list-style: none; }\ndetails.dom-node > summary::-webkit-details-marker { display: none; }\n.dom-tag-open { color: #f07178; }\n.dom-tag-close { color: #f07178; }\n.dom-attr-name { color: #ffcb6b; }\n.dom-attr-value { color: #c3e88d; }\n.dom-text { color: #82aaff; font-style: italic; }\n.dom-node-clickable { cursor: pointer; border-radius: 3px; transition: background 0.1s; }\n.dom-node-clickable:hover, details.dom-node-clickable > summary:hover { background: rgba(255,255,255,0.08); }\n.dom-node-selected, details.dom-node-selected > summary { background: rgba(99,179,237,0.15) !important; outline: 1px solid rgba(99,179,237,0.4); border-radius: 3px; }\n.dom-attr-name { color: #ffcb6b; }\n.dom-attr-value { color: #c3e88d; }\n.dom-text { color: #a0a0b0; font-style: italic; }\n\n/* Composition graph */\n.composition-lists { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }\n.comp-list h3 { font-size: 13px; font-weight: 600; margin: 0 0 8px; color: var(--color-muted); }\n.comp-list ul { list-style: none; padding: 0; margin: 0; }\n.comp-list li { padding: 4px 0; font-size: 13px; border-bottom: 1px solid var(--color-border); }\n.comp-list a { color: var(--color-accent); text-decoration: none; }\n.comp-list a:hover { text-decoration: underline; }\n\n/* Index page */\n.index-header { margin-bottom: 32px; }\n.index-header h1 { font-size: 32px; font-weight: 700; margin: 0 0 8px; }\n.index-header p { color: var(--color-muted); font-size: 15px; margin: 0; }\n.component-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));\n gap: 16px;\n}\n.component-card {\n border: 1px solid var(--color-border);\n border-radius: var(--radius);\n overflow: hidden;\n text-decoration: none;\n color: var(--color-text);\n transition: box-shadow 0.15s;\n display: block;\n}\n.component-card:hover { box-shadow: var(--shadow); }\n.card-preview {\n background: #f8f8f8;\n height: 160px;\n overflow: hidden;\n display: flex;\n align-items: center;\n justify-content: center;\n border-bottom: 1px solid var(--color-border);\n}\n.card-preview img { object-fit: contain; }\n.card-preview .no-preview { color: var(--color-muted); font-size: 12px; }\n.card-body { padding: 12px 16px; }\n.card-name { font-weight: 600; font-size: 14px; margin-bottom: 4px; }\n.card-meta { font-size: 12px; color: var(--color-muted); display: flex; gap: 8px; }\n\n/* Dashboard */\n.dashboard-header { margin-bottom: 32px; }\n.dashboard-header h1 { font-size: 28px; font-weight: 700; margin: 0 0 8px; }\n.section-title { font-size: 16px; font-weight: 600; margin: 0 0 16px; }\n\n/* Responsive */\n@media (max-width: 1024px) {\n .on-this-page { display: none; }\n}\n@media (max-width: 768px) {\n .sidebar { display: none; }\n .content-body { padding: 20px 16px; }\n .analysis-grid { grid-template-columns: 1fr; }\n .composition-lists { grid-template-columns: 1fr; }\n}`;\n\n return `<style>\\n${css}\\n</style>`;\n}\n","import { generateCSS } from \"../css.js\";\nimport { escapeHtml, slugify } from \"../utils.js\";\n\nexport function sidebarLinks(\n components: string[],\n currentSlug: string | null,\n basePath: string,\n): string {\n const links = components\n .sort()\n .map((name) => {\n const slug = slugify(name);\n const isActive = slug === currentSlug;\n return `<a href=\"${basePath}${slug}.html\" class=\"${isActive ? \"active\" : \"\"}\">${escapeHtml(name)}</a>`;\n })\n .join(\"\\n\");\n\n return `<div class=\"sidebar-heading\">Components</div>\\n${links}`;\n}\n\nexport function htmlShell(options: {\n title: string;\n body: string;\n sidebar: string;\n onThisPage: string;\n basePath: string;\n}): string {\n const { title, body, sidebar, onThisPage, basePath } = options;\n\n return `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <title>${escapeHtml(title)}</title>\n ${generateCSS()}\n</head>\n<body>\n <nav class=\"top-nav\">\n <a class=\"site-title\" href=\"${basePath}index.html\">Scope</a>\n <div class=\"spacer\"></div>\n <input\n class=\"search-box\"\n type=\"search\"\n placeholder=\"Search components…\"\n id=\"sidebar-search\"\n aria-label=\"Search components\"\n />\n </nav>\n <div class=\"page-layout\">\n <nav class=\"sidebar\" id=\"sidebar\">\n ${sidebar}\n </nav>\n <div class=\"main-content\">\n <div class=\"content-body\">\n ${body}\n </div>\n <nav class=\"on-this-page\">\n <h4>On this page</h4>\n ${onThisPage}\n </nav>\n </div>\n </div>\n <script>\n (function () {\n var search = document.getElementById('sidebar-search');\n var sidebar = document.getElementById('sidebar');\n if (!search || !sidebar) return;\n search.addEventListener('input', function () {\n var q = search.value.toLowerCase();\n var links = sidebar.querySelectorAll('a');\n links.forEach(function (link) {\n var text = link.textContent || '';\n link.style.display = text.toLowerCase().includes(q) ? '' : 'none';\n });\n });\n })();\n </script>\n</body>\n</html>`;\n}\n","import type { SiteData } from \"../types.js\";\nimport { escapeHtml, propTableRow, renderDOMTree, slugify } from \"../utils.js\";\nimport { htmlShell, sidebarLinks } from \"./layout.js\";\n\nconst SECTIONS = [\n \"Playground\",\n \"Matrix\",\n \"Docs\",\n \"Analysis\",\n \"X-Ray\",\n \"Tokens\",\n \"Accessibility\",\n \"Composition\",\n \"Responsive\",\n \"Stress Tests\",\n];\n\nfunction notGenerated(message = \"Not generated\"): string {\n return `<div class=\"not-generated\">${escapeHtml(message)}</div>`;\n}\n\nfunction sectionWrap(id: string, title: string, description: string, content: string): string {\n return `<section class=\"section\" id=\"${id}\">\n <div class=\"section-header\">\n <h2>${escapeHtml(title)}</h2>\n <p>${escapeHtml(description)}</p>\n </div>\n ${content}\n</section>`;\n}\n\nfunction renderPlayground(name: string, data: SiteData): string {\n const component = data.manifest.components[name];\n const render = data.renders.get(name);\n\n const props = component ? Object.entries(component.props) : [];\n const propsTable =\n props.length > 0\n ? `<table class=\"props-table\">\n <thead>\n <tr>\n <th>Prop</th>\n <th>Type</th>\n <th>Required</th>\n <th>Default</th>\n </tr>\n </thead>\n <tbody>\n ${props.map(([n, p]) => propTableRow(n, p)).join(\"\\n \")}\n </tbody>\n</table>`\n : `<p style=\"color:var(--color-muted);font-size:13px\">No props defined.</p>`;\n\n const renderW = render?.width != null ? render.width : undefined;\n const renderH = render?.height != null ? render.height : undefined;\n const renderSizeAttr =\n renderW != null && renderH != null ? ` width=\"${renderW}\" height=\"${renderH}\"` : \"\";\n const renderHtml = render?.screenshot\n ? `<div class=\"render-preview\">\n <img src=\"data:image/png;base64,${render.screenshot}\" alt=\"${escapeHtml(name)} render\"${renderSizeAttr} />\n</div>`\n : notGenerated(\"Render not generated. Run scope render to produce screenshots.\");\n\n return sectionWrap(\n \"playground\",\n \"Playground\",\n \"Props reference and rendered preview.\",\n `${propsTable}\n<div style=\"margin-top:24px\">${renderHtml}</div>`,\n );\n}\n\nfunction renderMatrix(name: string, data: SiteData): string {\n const render = data.renders.get(name);\n\n if (!render?.cells || render.cells.length === 0) {\n return sectionWrap(\n \"matrix\",\n \"Matrix\",\n \"Prop combination matrix renders.\",\n notGenerated(\"Matrix renders not generated. Run scope render --matrix to produce a matrix.\"),\n );\n }\n\n const cells = render.cells;\n const cols = Math.ceil(Math.sqrt(cells.length));\n\n const cellsHtml = cells\n .map((cell) => {\n const label = cell.axisValues.join(\" / \");\n const imgHtml = cell.screenshot\n ? `<img class=\"scope-screenshot\" src=\"data:image/png;base64,${cell.screenshot}\" alt=\"${escapeHtml(label)}\" />`\n : `<span style=\"color:var(--color-muted);font-size:11px\">${cell.error ? escapeHtml(cell.error) : \"failed\"}</span>`;\n return `<div class=\"matrix-cell\">${imgHtml}<div class=\"cell-label\">${escapeHtml(label)}</div></div>`;\n })\n .join(\"\\n\");\n\n const grid = `<div class=\"matrix-grid\" style=\"grid-template-columns: repeat(${cols}, 1fr)\">\n${cellsHtml}\n</div>`;\n\n return sectionWrap(\"matrix\", \"Matrix\", \"Prop combination matrix renders.\", grid);\n}\n\nfunction renderDocs(): string {\n return sectionWrap(\n \"docs\",\n \"Docs\",\n \"Component documentation.\",\n `<p style=\"color:var(--color-muted);font-size:13px\">No documentation file found for this component.</p>`,\n );\n}\n\nfunction renderAnalysis(name: string, data: SiteData): string {\n const component = data.manifest.components[name];\n if (!component) {\n return sectionWrap(\"analysis\", \"Analysis\", \"Static analysis results.\", notGenerated());\n }\n\n const propCount = Object.keys(component.props).length;\n const hookCount = component.detectedHooks.length;\n const sideEffectCount =\n component.sideEffects.fetches.length +\n (component.sideEffects.timers ? 1 : 0) +\n component.sideEffects.subscriptions.length +\n (component.sideEffects.globalListeners ? 1 : 0);\n\n const statsGrid = `<div class=\"stats-grid\">\n <div class=\"stat-card\">\n <div class=\"stat-label\">Complexity</div>\n <div class=\"stat-value\"><span class=\"badge ${component.complexityClass}\">${escapeHtml(component.complexityClass)}</span></div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-label\">Props</div>\n <div class=\"stat-value\">${propCount}</div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-label\">Hooks</div>\n <div class=\"stat-value\">${hookCount}</div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-label\">Side Effects</div>\n <div class=\"stat-value\">${sideEffectCount}</div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-label\">Export</div>\n <div class=\"stat-value\" style=\"font-size:14px\">${escapeHtml(component.exportType)}</div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-label\">Memoized</div>\n <div class=\"stat-value\" style=\"font-size:14px\">${component.memoized ? \"Yes\" : \"No\"}</div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-label\">forwardedRef</div>\n <div class=\"stat-value\" style=\"font-size:14px\">${component.forwardedRef ? \"Yes\" : \"No\"}</div>\n </div>\n</div>`;\n\n function tagList(items: string[]): string {\n if (items.length === 0)\n return `<span style=\"color:var(--color-muted);font-size:12px\">None</span>`;\n return `<div class=\"tag-list\">${items.map((i) => `<span class=\"tag\">${escapeHtml(i)}</span>`).join(\"\")}</div>`;\n }\n\n const sideEffectItems: string[] = [\n ...component.sideEffects.fetches.map((f) => `fetch: ${f}`),\n ...(component.sideEffects.timers ? [\"timers\"] : []),\n ...component.sideEffects.subscriptions.map((s) => `sub: ${s}`),\n ...(component.sideEffects.globalListeners ? [\"global listeners\"] : []),\n ];\n\n const analysisGrid = `<div class=\"analysis-grid\">\n <div class=\"analysis-card\">\n <h3>Detected Hooks</h3>\n <div class=\"value\">${tagList(component.detectedHooks)}</div>\n </div>\n <div class=\"analysis-card\">\n <h3>Required Contexts</h3>\n <div class=\"value\">${tagList(component.requiredContexts)}</div>\n </div>\n <div class=\"analysis-card\">\n <h3>HOC Wrappers</h3>\n <div class=\"value\">${tagList(component.hocWrappers)}</div>\n </div>\n <div class=\"analysis-card\">\n <h3>Side Effects</h3>\n <div class=\"value\">${tagList(sideEffectItems)}</div>\n </div>\n</div>`;\n\n return sectionWrap(\n \"analysis\",\n \"Analysis\",\n \"Static analysis results for this component.\",\n `${statsGrid}${analysisGrid}`,\n );\n}\n\nfunction renderXRay(name: string, data: SiteData): string {\n const render = data.renders.get(name);\n\n if (!render?.dom) {\n return sectionWrap(\n \"x-ray\",\n \"X-Ray\",\n \"DOM structure and computed styles.\",\n notGenerated(\"X-Ray data not generated. Run scope render with DOM capture enabled.\"),\n );\n }\n\n const dom = render.dom;\n\n // Extract per-node styles keyed by nodeId from computedStyles map\n const nodeStylesMap: Record<number, Record<string, string>> = {};\n if (render.computedStyles) {\n for (const [key, styles] of Object.entries(render.computedStyles)) {\n const m = key.match(/^#node-(\\d+)$/);\n if (m?.[1] !== undefined) nodeStylesMap[parseInt(m[1], 10)] = styles;\n }\n }\n const nodeStylesJson = escapeHtml(JSON.stringify(nodeStylesMap));\n\n const treeHtml = `<div class=\"dom-tree\">${renderDOMTree(dom.tree)}</div>`;\n\n // Styles panel — populated by JS when user clicks a node\n const stylesPanelHtml = `\n<div id=\"xray-styles-panel-${escapeHtml(name)}\" class=\"xray-styles-panel\" style=\"display:none;margin-top:16px;border:1px solid var(--color-border);border-radius:6px;overflow:hidden\">\n <div class=\"xray-styles-header\" style=\"padding:8px 12px;background:var(--color-surface-2);font-size:12px;font-weight:600;color:var(--color-muted);display:flex;justify-content:space-between;align-items:center\">\n <span id=\"xray-styles-label-${escapeHtml(name)}\">— no node selected —</span>\n <button onclick=\"document.getElementById('xray-styles-panel-${escapeHtml(name)}').style.display='none'\" style=\"background:none;border:none;cursor:pointer;color:var(--color-muted);font-size:16px;line-height:1\">×</button>\n </div>\n <table class=\"token-table\" style=\"margin:0\">\n <thead><tr><th>Property</th><th>Value</th></tr></thead>\n <tbody id=\"xray-styles-body-${escapeHtml(name)}\"></tbody>\n </table>\n</div>\n<script>\n(function() {\n var nodeStyles = JSON.parse(${nodeStylesJson});\n var container = document.currentScript.parentElement;\n container.addEventListener(\"click\", function(e) {\n var el = e.target.closest(\"[data-node-id]\");\n if (!el) return;\n var id = parseInt(el.getAttribute(\"data-node-id\"), 10);\n var styles = nodeStyles[id];\n if (!styles) return;\n var panel = document.getElementById(\"xray-styles-panel-${escapeHtml(name)}\");\n var label = document.getElementById(\"xray-styles-label-${escapeHtml(name)}\");\n var body = document.getElementById(\"xray-styles-body-${escapeHtml(name)}\");\n var tag = el.tagName === \"DETAILS\" ? el.querySelector(\"summary .dom-tag-open\") : el;\n label.textContent = tag ? tag.textContent.trim().slice(0, 60) : \"node #\" + id;\n body.innerHTML = Object.entries(styles).map(function(e) {\n return \"<tr><td>\" + e[0] + \"</td><td style=\"font-family:monospace\">\" + e[1] + \"</td></tr>\";\n }).join(\"\");\n panel.style.display = \"block\";\n // Highlight selected node\n container.querySelectorAll(\".dom-node-selected\").forEach(function(n) { n.classList.remove(\"dom-node-selected\"); });\n el.classList.add(\"dom-node-selected\");\n });\n})();\n</script>`;\n\n return sectionWrap(\n \"x-ray\",\n \"X-Ray\",\n `DOM structure — ${dom.elementCount} elements. Click any element to inspect its computed styles.`,\n `${treeHtml}${stylesPanelHtml}`,\n );\n}\n\nfunction renderTokens(name: string, data: SiteData): string {\n if (!data.complianceBatch) {\n return sectionWrap(\n \"tokens\",\n \"Tokens\",\n \"Design token compliance.\",\n notGenerated(\"Compliance data not generated. Run scope tokens to audit design tokens.\"),\n );\n }\n\n const report = data.complianceBatch.components[name];\n if (!report) {\n return sectionWrap(\n \"tokens\",\n \"Tokens\",\n \"Design token compliance.\",\n notGenerated(\"No compliance report found for this component.\"),\n );\n }\n\n const pct = Math.round(report.compliance * 100);\n const barHtml = `<div class=\"compliance-bar-container\">\n <div class=\"compliance-label\">${pct}% on-system (${report.onSystem} / ${report.total} properties)</div>\n <div class=\"compliance-bar-bg\">\n <div class=\"compliance-bar-fill\" style=\"width:${pct}%\"></div>\n </div>\n</div>`;\n\n const rows = Object.entries(report.properties)\n .map(([prop, result]) => {\n const pill =\n result.status === \"on_system\"\n ? `<span class=\"pill-on\">✓ ${escapeHtml(result.token ?? \"\")}</span>`\n : `<span class=\"pill-off\">✗ off-system</span>`;\n\n const swatchStyle = result.value.startsWith(\"#\")\n ? ` style=\"background:${escapeHtml(result.value)}\"`\n : \"\";\n\n const nearestHtml = result.nearest\n ? `<span style=\"color:var(--color-muted);font-size:10px\"> nearest: ${escapeHtml(result.nearest.token)}</span>`\n : \"\";\n\n return `<tr>\n <td class=\"token-path\">${escapeHtml(prop)}</td>\n <td><span class=\"token-value-swatch\"${swatchStyle}></span>${escapeHtml(result.value)}</td>\n <td>${pill}${nearestHtml}</td>\n </tr>`;\n })\n .join(\"\\n \");\n\n const tableHtml = `<table class=\"token-table\">\n <thead><tr><th>Property</th><th>Value</th><th>Status</th></tr></thead>\n <tbody>${rows}</tbody>\n</table>`;\n\n return sectionWrap(\n \"tokens\",\n \"Tokens\",\n \"Design token compliance audit.\",\n `${barHtml}${tableHtml}`,\n );\n}\n\nfunction renderAccessibility(name: string, data: SiteData): string {\n const render = data.renders.get(name);\n\n if (!render?.accessibility) {\n return sectionWrap(\n \"accessibility\",\n \"Accessibility\",\n \"Accessibility audit results.\",\n notGenerated(\n \"Accessibility data not generated. Run scope render with accessibility capture enabled.\",\n ),\n );\n }\n\n const a11y = render.accessibility;\n const roleBadge = `<span class=\"a11y-role-badge\">${escapeHtml(a11y.role)}</span>`;\n\n const violationsHtml =\n a11y.violations.length > 0\n ? `<ul class=\"violation-list\">${a11y.violations.map((v) => `<li>${escapeHtml(v)}</li>`).join(\"\")}</ul>`\n : `<p style=\"color:var(--color-success);font-size:13px\">✓ No violations found.</p>`;\n\n return sectionWrap(\n \"accessibility\",\n \"Accessibility\",\n \"Accessibility audit results.\",\n `<p style=\"font-size:13px;margin:0 0 12px\">Role: ${roleBadge} &nbsp; Name: <em>${escapeHtml(a11y.name || \"(none)\")}</em></p>\n${violationsHtml}`,\n );\n}\n\nfunction renderComposition(name: string, data: SiteData): string {\n const component = data.manifest.components[name];\n\n if (!component || (component.composes.length === 0 && component.composedBy.length === 0)) {\n return sectionWrap(\n \"composition\",\n \"Composition\",\n \"Component dependency graph.\",\n `<p style=\"color:var(--color-muted);font-size:13px\">This component stands alone.</p>`,\n );\n }\n\n function compList(title: string, items: string[]): string {\n if (items.length === 0) {\n return `<div class=\"comp-list\"><h3>${escapeHtml(title)}</h3><p style=\"color:var(--color-muted);font-size:12px\">None</p></div>`;\n }\n const liItems = items\n .map(\n (n) => `<li><a href=\"${data.options.basePath}${slugify(n)}.html\">${escapeHtml(n)}</a></li>`,\n )\n .join(\"\");\n return `<div class=\"comp-list\"><h3>${escapeHtml(title)}</h3><ul>${liItems}</ul></div>`;\n }\n\n return sectionWrap(\n \"composition\",\n \"Composition\",\n \"Component dependency graph.\",\n `<div class=\"composition-lists\">\n ${compList(\"Composes\", component.composes)}\n ${compList(\"Composed By\", component.composedBy)}\n</div>`,\n );\n}\n\nexport function renderComponentDetail(name: string, data: SiteData): string {\n const component = data.manifest.components[name];\n const slug = slugify(name);\n\n const complexityBadge = component\n ? `<span class=\"badge ${component.complexityClass}\">${escapeHtml(component.complexityClass)}</span>`\n : \"\";\n const memoizedBadge = component?.memoized ? `<span class=\"badge memoized\">memo</span>` : \"\";\n const exportBadge = component\n ? `<span class=\"badge\">${escapeHtml(component.exportType)}</span>`\n : \"\";\n const filepath = component ? `<div class=\"filepath\">${escapeHtml(component.filePath)}</div>` : \"\";\n\n const header = `<div class=\"component-header\">\n <h1>${escapeHtml(name)}</h1>\n <div class=\"meta\">${complexityBadge}${memoizedBadge}${exportBadge}</div>\n ${filepath}\n</div>`;\n\n const sections = [\n renderPlayground(name, data),\n renderMatrix(name, data),\n renderDocs(),\n renderAnalysis(name, data),\n renderXRay(name, data),\n renderTokens(name, data),\n renderAccessibility(name, data),\n renderComposition(name, data),\n sectionWrap(\n \"responsive\",\n \"Responsive\",\n \"Multi-viewport renders.\",\n notGenerated(\n \"Responsive renders not generated. Multi-viewport rendering is a future feature.\",\n ),\n ),\n sectionWrap(\n \"stress-tests\",\n \"Stress Tests\",\n \"Edge case and stress test renders.\",\n notGenerated(\"Stress tests not generated. Stress render runs are a future feature.\"),\n ),\n ];\n\n const body = `${header}${sections.join(\"\\n\")}`;\n\n const onThisPage = SECTIONS.map((s) => {\n const id = s.toLowerCase().replace(/\\s+/g, \"-\");\n return `<a href=\"#${id}\">${escapeHtml(s)}</a>`;\n }).join(\"\\n\");\n\n const componentNames = Object.keys(data.manifest.components);\n const sidebar = sidebarLinks(componentNames, slug, data.options.basePath);\n\n return htmlShell({\n title: `${name} — ${data.options.title}`,\n body,\n sidebar,\n onThisPage,\n basePath: data.options.basePath,\n });\n}\n","import type { SiteData } from \"../types.js\";\nimport { escapeHtml, slugify } from \"../utils.js\";\nimport { htmlShell, sidebarLinks } from \"./layout.js\";\n\nexport function renderComponentIndex(data: SiteData): string {\n const components = Object.entries(data.manifest.components);\n const totalCount = components.length;\n const simpleCount = components.filter(([, c]) => c.complexityClass === \"simple\").length;\n const complexCount = components.filter(([, c]) => c.complexityClass === \"complex\").length;\n const memoizedCount = components.filter(([, c]) => c.memoized).length;\n\n const statsGrid = `<div class=\"stats-grid\">\n <div class=\"stat-card\">\n <div class=\"stat-label\">Total Components</div>\n <div class=\"stat-value\">${totalCount}</div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-label\">Simple</div>\n <div class=\"stat-value\">${simpleCount}</div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-label\">Complex</div>\n <div class=\"stat-value\">${complexCount}</div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-label\">Memoized</div>\n <div class=\"stat-value\">${memoizedCount}</div>\n </div>\n</div>`;\n\n const cards = components\n .sort(([a], [b]) => a.localeCompare(b))\n .map(([name, component]) => {\n const slug = slugify(name);\n const render = data.renders.get(name);\n const propCount = Object.keys(component.props).length;\n const hookCount = component.detectedHooks.length;\n\n const previewHtml = render?.screenshot\n ? `<img class=\"scope-screenshot\" src=\"data:image/png;base64,${render.screenshot}\" alt=\"${escapeHtml(name)}\" />`\n : `<span class=\"no-preview\">No preview</span>`;\n\n return `<a class=\"component-card\" href=\"${data.options.basePath}${slug}.html\" data-name=\"${escapeHtml(name.toLowerCase())}\">\n <div class=\"card-preview\">${previewHtml}</div>\n <div class=\"card-body\">\n <div class=\"card-name\">${escapeHtml(name)}</div>\n <div class=\"card-meta\">\n <span>${propCount} props</span>\n <span class=\"badge ${component.complexityClass}\" style=\"font-size:10px\">${escapeHtml(component.complexityClass)}</span>\n ${hookCount > 0 ? `<span>${hookCount} hooks</span>` : \"\"}\n </div>\n </div>\n</a>`;\n })\n .join(\"\\n\");\n\n const cardGrid = `<div class=\"component-grid\" id=\"component-grid\">${cards}</div>`;\n\n const filterScript = `<script>\n(function () {\n var grid = document.getElementById('component-grid');\n var search = document.getElementById('sidebar-search');\n if (!grid || !search) return;\n var indexSearch = document.getElementById('index-search');\n function filter(q) {\n var cards = grid.querySelectorAll('.component-card');\n cards.forEach(function (card) {\n var name = card.getAttribute('data-name') || '';\n card.style.display = name.includes(q) ? '' : 'none';\n });\n }\n search.addEventListener('input', function () { filter(search.value.toLowerCase()); });\n if (indexSearch) {\n indexSearch.addEventListener('input', function () { filter(indexSearch.value.toLowerCase()); });\n }\n})();\n</script>`;\n\n const header = `<div class=\"index-header\">\n <h1>${escapeHtml(data.options.title)}</h1>\n <p>${totalCount} component${totalCount === 1 ? \"\" : \"s\"} analysed</p>\n <input class=\"search-box\" type=\"search\" id=\"index-search\" placeholder=\"Filter components…\" style=\"margin-top:12px\" />\n</div>`;\n\n const body = `${header}${statsGrid}${cardGrid}${filterScript}`;\n\n const componentNames = Object.keys(data.manifest.components);\n const sidebar = sidebarLinks(componentNames, null, data.options.basePath);\n\n const onThisPage = `<a href=\"#top\">Overview</a>\\n<a href=\"#component-grid\">Components</a>`;\n\n return htmlShell({\n title: data.options.title,\n body,\n sidebar,\n onThisPage,\n basePath: data.options.basePath,\n });\n}\n","import type { SiteData } from \"../types.js\";\nimport { escapeHtml, slugify } from \"../utils.js\";\nimport { htmlShell, sidebarLinks } from \"./layout.js\";\n\nexport function renderDashboard(data: SiteData): string {\n const components = Object.entries(data.manifest.components);\n const totalCount = components.length;\n\n const simpleCount = components.filter(([, c]) => c.complexityClass === \"simple\").length;\n const complexCount = components.filter(([, c]) => c.complexityClass === \"complex\").length;\n const renderedCount = components.filter(([name]) => data.renders.has(name)).length;\n\n const totalProps = components.reduce((sum, [, c]) => sum + Object.keys(c.props).length, 0);\n const avgProps = totalCount > 0 ? Math.round(totalProps / totalCount) : 0;\n\n let overallCompliance: number | null = null;\n if (data.complianceBatch) {\n const reports = Object.values(data.complianceBatch.components);\n if (reports.length > 0) {\n overallCompliance = Math.round(\n (reports.reduce((sum, r) => sum + r.compliance, 0) / reports.length) * 100,\n );\n }\n }\n\n const statsGrid = `<div class=\"stats-grid\" style=\"margin-bottom:32px\">\n <div class=\"stat-card\">\n <div class=\"stat-label\">Total Components</div>\n <div class=\"stat-value\">${totalCount}</div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-label\">Avg Props</div>\n <div class=\"stat-value\">${avgProps}</div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-label\">With Renders</div>\n <div class=\"stat-value\">${renderedCount}</div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-label\">Compliance</div>\n <div class=\"stat-value\">${overallCompliance !== null ? `${overallCompliance}%` : \"—\"}</div>\n </div>\n</div>`;\n\n // Complexity breakdown\n const complexitySection = `<div class=\"section\" style=\"padding:24px 0;border-bottom:1px solid var(--color-border)\">\n <h2 class=\"section-title\">Complexity Breakdown</h2>\n <div class=\"stats-grid\">\n <div class=\"stat-card\">\n <div class=\"stat-label\">Simple</div>\n <div class=\"stat-value\" style=\"color:var(--color-success)\">${simpleCount}</div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-label\">Complex</div>\n <div class=\"stat-value\" style=\"color:var(--color-warn)\">${complexCount}</div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-label\">Simple %</div>\n <div class=\"stat-value\">${totalCount > 0 ? Math.round((simpleCount / totalCount) * 100) : 0}%</div>\n </div>\n </div>\n</div>`;\n\n // Top components by prop count\n const topByProps = components\n .sort(([, a], [, b]) => Object.keys(b.props).length - Object.keys(a.props).length)\n .slice(0, 10);\n\n const topPropsRows = topByProps\n .map(([name, component]) => {\n const slug = slugify(name);\n const propCount = Object.keys(component.props).length;\n return `<tr>\n <td><a href=\"${data.options.basePath}${slug}.html\" style=\"color:var(--color-accent);text-decoration:none\">${escapeHtml(name)}</a></td>\n <td>${propCount}</td>\n <td><span class=\"badge ${component.complexityClass}\">${escapeHtml(component.complexityClass)}</span></td>\n </tr>`;\n })\n .join(\"\\n \");\n\n const topPropsSection = `<div class=\"section\" style=\"padding:24px 0;border-bottom:1px solid var(--color-border)\">\n <h2 class=\"section-title\">Top Components by Prop Count</h2>\n <table class=\"props-table\">\n <thead><tr><th>Component</th><th>Props</th><th>Complexity</th></tr></thead>\n <tbody>${topPropsRows}</tbody>\n </table>\n</div>`;\n\n // Compliance section\n let complianceSection = \"\";\n if (data.complianceBatch && overallCompliance !== null) {\n const complianceRows = Object.entries(data.complianceBatch.components)\n .sort(([, a], [, b]) => b.compliance - a.compliance)\n .map(([name, report]) => {\n const pct = Math.round(report.compliance * 100);\n const slug = slugify(name);\n const barHtml = `<div class=\"compliance-bar-bg\" style=\"min-width:120px\">\n <div class=\"compliance-bar-fill\" style=\"width:${pct}%\"></div>\n </div>`;\n return `<tr>\n <td><a href=\"${data.options.basePath}${slug}.html\" style=\"color:var(--color-accent);text-decoration:none\">${escapeHtml(name)}</a></td>\n <td>${pct}%</td>\n <td>${barHtml}</td>\n <td>${report.onSystem} / ${report.total}</td>\n </tr>`;\n })\n .join(\"\\n \");\n\n complianceSection = `<div class=\"section\" style=\"padding:24px 0\">\n <h2 class=\"section-title\">Design Token Compliance — ${overallCompliance}% overall</h2>\n <table class=\"props-table\">\n <thead><tr><th>Component</th><th>Score</th><th>Bar</th><th>On-System</th></tr></thead>\n <tbody>${complianceRows}</tbody>\n </table>\n</div>`;\n }\n\n const header = `<div class=\"dashboard-header\">\n <h1>Dashboard</h1>\n <p style=\"color:var(--color-muted);font-size:14px\">Overview of all ${totalCount} analysed components.</p>\n</div>`;\n\n const body = `${header}${statsGrid}${complexitySection}${topPropsSection}${complianceSection}`;\n\n const componentNames = Object.keys(data.manifest.components);\n const sidebar = sidebarLinks(componentNames, null, data.options.basePath);\n\n const onThisPage = `<a href=\"#top\">Overview</a>\n<a href=\"#complexity\">Complexity</a>\n<a href=\"#top-props\">Top by Props</a>\n${data.complianceBatch ? '<a href=\"#compliance\">Compliance</a>' : \"\"}`;\n\n return htmlShell({\n title: `Dashboard — ${data.options.title}`,\n body,\n sidebar,\n onThisPage,\n basePath: data.options.basePath,\n });\n}\n","import { mkdir, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { normalizeOptions, readSiteData } from \"./reader.js\";\nimport { renderComponentDetail } from \"./templates/component-detail.js\";\nimport { renderComponentIndex } from \"./templates/component-index.js\";\nimport { renderDashboard } from \"./templates/dashboard.js\";\nimport type { SiteOptions } from \"./types.js\";\nimport { slugify } from \"./utils.js\";\n\nexport async function buildSite(options?: SiteOptions): Promise<void> {\n const normalizedOptions = normalizeOptions(options);\n\n console.log(`[scope/site] Reading data from ${normalizedOptions.inputDir}…`);\n const data = await readSiteData(normalizedOptions);\n\n const componentNames = Object.keys(data.manifest.components);\n console.log(`[scope/site] Found ${componentNames.length} components.`);\n\n // Create output directory\n await mkdir(normalizedOptions.outputDir, { recursive: true });\n\n // Generate component detail pages\n for (const name of componentNames) {\n const slug = slugify(name);\n const html = renderComponentDetail(name, data);\n const outputPath = join(normalizedOptions.outputDir, `${slug}.html`);\n await writeFile(outputPath, html, \"utf-8\");\n console.log(`[scope/site] ✓ ${name} → ${slug}.html`);\n }\n\n // Generate index page\n const indexHtml = renderComponentIndex(data);\n await writeFile(join(normalizedOptions.outputDir, \"index.html\"), indexHtml, \"utf-8\");\n console.log(`[scope/site] ✓ index.html`);\n\n // Generate dashboard page\n const dashboardHtml = renderDashboard(data);\n await writeFile(join(normalizedOptions.outputDir, \"dashboard.html\"), dashboardHtml, \"utf-8\");\n console.log(`[scope/site] ✓ dashboard.html`);\n\n console.log(\n `[scope/site] Done. Site written to ${normalizedOptions.outputDir} (${componentNames.length + 2} files).`,\n );\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-scope/site",
3
- "version": "1.18.0",
3
+ "version": "1.19.0",
4
4
  "description": "Static HTML gallery generator for Scope — reads .reactscope/ output and produces a component gallery website",
5
5
  "license": "MIT",
6
6
  "type": "module",