mewkit 1.16.0 → 1.16.1

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.
@@ -1 +1 @@
1
- {"version":3,"file":"export-plan.d.ts","sourceRoot":"","sources":["../../../src/visual-plan/application/export-plan.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAOH,MAAM,WAAW,YAAY;IAC5B,EAAE,EAAE,OAAO,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAqCD,gFAAgF;AAChF,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,YAAY,CAS5D"}
1
+ {"version":3,"file":"export-plan.d.ts","sourceRoot":"","sources":["../../../src/visual-plan/application/export-plan.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAQH,MAAM,WAAW,YAAY;IAC5B,EAAE,EAAE,OAAO,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAoDD,gFAAgF;AAChF,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,YAAY,CAS5D"}
@@ -12,6 +12,7 @@
12
12
  import { readArtifactRaw } from "../infrastructure/visual-plan-repository.js";
13
13
  import { sanitizeWireframeHtml } from "../infrastructure/wireframe-sanitizer.js";
14
14
  import { computeCoverage } from "../domain/coverage.js";
15
+ import { WIREFRAME_THEME_CSS } from "../domain/wireframe-theme.js";
15
16
  import { VisualPlanSchema } from "../domain/schemas.js";
16
17
  /** HTML-entity-encode a plan-sourced string for safe text/attribute placement. */
17
18
  function esc(s) {
@@ -22,11 +23,11 @@ function coverageSection(plan) {
22
23
  const rows = plan.uiCoverage.surfaces
23
24
  .flatMap((s) => s.states.map((st) => `<tr><td>${esc(s.label ?? s.id)}</td><td>${esc(st.label ?? st.id)}</td><td>${st.frameIds.length > 0 ? "framed" : st.omitted ? esc(st.omitted.reason) : "unresolved"}</td></tr>`))
24
25
  .join("");
25
- return `<h2>Coverage</h2><p class="vp-sum">${summary.resolved} resolved · ${summary.planned} planned · ${summary.omitted} omitted · ${summary.unresolved} unresolved</p><table><thead><tr><th>Surface</th><th>State</th><th>Closure</th></tr></thead><tbody>${rows}</tbody></table>`;
26
+ return `<h2>Coverage</h2><p class="vp-sum">${summary.resolved} resolved · ${summary.planned} planned · ${summary.omitted} omitted · ${summary.unresolved} unresolved</p><table class="vp-coverage-table"><thead><tr><th>Surface</th><th>State</th><th>Closure</th></tr></thead><tbody>${rows}</tbody></table>`;
26
27
  }
27
28
  function framesSection(plan) {
28
29
  const cards = plan.canvas.frames
29
- .map((f) => `<article class="vp-frame"><header><strong>${esc(f.label)}</strong> <span class="vp-badge">${esc(f.surface)} · ${esc(f.changeMode)}</span></header><div class="wf-root">${sanitizeWireframeHtml(f.wireframe.html)}</div></article>`)
30
+ .map((f) => `<article class="vp-frame" data-surface="${esc(f.surface)}"><header><strong>${esc(f.label)}</strong> <span class="vp-badge">${esc(f.surface)} · ${esc(f.changeMode)}</span></header><div class="vp-frame-body"><div class="wf-root">${sanitizeWireframeHtml(f.wireframe.html)}</div></div></article>`)
30
31
  .join("");
31
32
  return `<h2>Frames</h2><div class="vp-frames">${cards}</div>`;
32
33
  }
@@ -36,14 +37,28 @@ function docsSection(plan) {
36
37
  const items = plan.documentBlocks.map((b) => `<li>${b.title ? `<strong>${esc(b.title)}:</strong> ` : ""}${esc(b.body)}</li>`).join("");
37
38
  return `<h2>Mechanics</h2><ul>${items}</ul>`;
38
39
  }
39
- const STYLE = `body{font:14px/1.5 system-ui,sans-serif;margin:0;padding:24px;background:#fff;color:#1c2430}
40
- h1{margin:0 0 4px}h2{margin:24px 0 8px;border-bottom:1px solid #d7dbe0;padding-bottom:4px}
41
- table{border-collapse:collapse;width:100%}th,td{border:1px solid #d7dbe0;padding:4px 8px;text-align:left;font-size:13px}
42
- .vp-sum{color:#64707d}.vp-frames{display:flex;flex-wrap:wrap;gap:16px}
43
- .vp-frame{border:1px solid #d7dbe0;border-radius:8px;overflow:hidden;width:340px}
44
- .vp-frame header{padding:6px 10px;border-bottom:1px solid #d7dbe0;background:#f4f5f7}
45
- .vp-badge{color:#64707d;font-size:12px}.wf-root{padding:10px}.wf-root .wf-button{display:inline-block;padding:6px 12px;background:#3563e9;color:#fff;border-radius:6px;text-decoration:none}
46
- .wf-root .wf-input{height:30px;border:1px solid #d7dbe0;border-radius:6px;background:#eef1f4}.wf-root .wf-error{color:#c0392b}`;
40
+ /**
41
+ * Page shell CSS; the wireframe look itself comes from the SHARED theme.
42
+ * Shell selectors are scoped (`body>h2`, `.vp-coverage-table`) so they never
43
+ * leak into `.wf-root` wireframe content — parity with the studio. Frame
44
+ * bodies are auto-height (plan content is never clipped); widths follow the
45
+ * surface footprint so mobile frames keep their studio aspect.
46
+ */
47
+ const PAGE_STYLE = `body{font:14px/1.5 system-ui,sans-serif;margin:0;padding:24px;background:#eef0f3;color:#1c2430}
48
+ body>h1{margin:0 0 4px}body>h2{margin:24px 0 8px;border-bottom:1px solid #d7dbe0;padding-bottom:4px}
49
+ .vp-coverage-table{border-collapse:collapse;width:100%}
50
+ .vp-coverage-table th,.vp-coverage-table td{border:1px solid #d7dbe0;padding:4px 8px;text-align:left;font-size:13px}
51
+ .vp-sum{color:#64707d}.vp-frames{display:flex;flex-wrap:wrap;gap:28px;align-items:flex-start}
52
+ .vp-frame{width:420px;max-width:100%}
53
+ .vp-frame[data-surface="mobile"]{width:300px}
54
+ .vp-frame[data-surface="popover"]{width:360px}
55
+ .vp-frame header{padding:0 2px 6px;font-size:13px}
56
+ .vp-frame-body{border:1.5px solid #d3d9e0;border-radius:14px;overflow:hidden;box-shadow:0 1px 3px rgba(16,22,32,.06)}
57
+ .vp-frame-body .wf-root{height:auto;min-height:120px}
58
+ .vp-frame[data-surface="mobile"] .vp-frame-body{border-radius:30px}
59
+ .vp-badge{color:#64707d;font-size:11px}
60
+ @media (prefers-color-scheme: dark){body{background:#0b0e13;color:#e8edf3}body>h2{border-color:#263041}.vp-frame-body{border-color:#2c3646}}`;
61
+ const STYLE = `${PAGE_STYLE}\n${WIREFRAME_THEME_CSS}`;
47
62
  /** Build the self-contained plan.html string from the artifact at `planDir`. */
48
63
  export function exportPlanHtml(planDir) {
49
64
  const read = readArtifactRaw(planDir);
@@ -1 +1 @@
1
- {"version":3,"file":"export-plan.js","sourceRoot":"","sources":["../../../src/visual-plan/application/export-plan.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"export-plan.js","sourceRoot":"","sources":["../../../src/visual-plan/application/export-plan.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Shared wireframe theme — the SINGLE source of truth for how sanitized
3
+ * `.wf-*` semantic HTML looks, consumed by BOTH renderers (same pattern as
4
+ * sanitizer-config.ts): the studio injects it at boot, `export --format html`
5
+ * embeds it in the exported page. One theme, two surfaces, no drift.
6
+ *
7
+ * Visual language follows the agent-native plan renderer (ISC), re-expressed
8
+ * for MeowKit's vocabulary: a scoped ink/paper/card/accent token palette with
9
+ * soft variants, hand-drawn font by DEFAULT (sketchy is the primary register;
10
+ * `[data-style="clean"]` swaps to the sans stack), 1.4px strokes, 9px radii,
11
+ * and a `[data-rough-ready]` hook that hides crisp borders once the rough.js
12
+ * overlay has redrawn them so outlines are never doubled.
13
+ *
14
+ * Pure data — no DOM, no imports — so the Node exporter and the Vite bundle
15
+ * can both consume it.
16
+ */
17
+ export declare const WIREFRAME_THEME_CSS = "\n/* ---- tokens (scoped to .wf-root; light + dark) ---- */\n.wf-root {\n --wf-ink: #222b38; --wf-ink-soft: #6b7684; --wf-line: #d3d9e0; --wf-sketch: #94a0ad;\n --wf-paper: #ffffff; --wf-card: #f6f8fa;\n --wf-accent: #4c6ef5; --wf-accent-fg: #ffffff; --wf-accent-soft: rgba(76, 110, 245, 0.12);\n --wf-warn: #d64545; --wf-warn-soft: rgba(214, 69, 69, 0.12); --wf-ok: #2f9e63;\n --wf-radius: 9px; --wf-stroke: 1.4px;\n --wf-font-hand: \"Architects Daughter\", \"Comic Sans MS\", \"Bradley Hand\", \"Marker Felt\", cursive;\n --wf-font-clean: ui-sans-serif, system-ui, -apple-system, \"Segoe UI\", sans-serif;\n --wf-font: var(--wf-font-hand);\n background: var(--wf-paper); color: var(--wf-ink);\n font-family: var(--wf-font); font-size: 14px; line-height: 1.45;\n padding: 14px; height: 100%; overflow: hidden; position: relative;\n}\n.wf-root, .wf-root * { box-sizing: border-box; min-width: 0; }\n[data-style=\"clean\"] .wf-root { --wf-font: var(--wf-font-clean); }\n@media (prefers-color-scheme: dark) {\n .wf-root {\n --wf-ink: #e9edf3; --wf-ink-soft: #93a0ae; --wf-line: #2c3646; --wf-sketch: #5d6a7a;\n --wf-paper: #171d26; --wf-card: #1e2733;\n --wf-accent: #7c9aff; --wf-accent-fg: #10141c; --wf-accent-soft: rgba(124, 154, 255, 0.16);\n --wf-warn: #ef7070; --wf-warn-soft: rgba(239, 112, 112, 0.16); --wf-ok: #52c184;\n }\n}\n\n/* ---- bare semantic elements ---- */\n.wf-root h1 { font-size: 21px; font-weight: 700; line-height: 1.15; margin: 0 0 8px; }\n.wf-root h2 { font-size: 17px; font-weight: 700; line-height: 1.2; margin: 0 0 6px; }\n.wf-root h3, .wf-root h4, .wf-root h5, .wf-root h6 { font-size: 14px; font-weight: 700; margin: 0 0 4px; }\n.wf-root p { margin: 0 0 8px; }\n.wf-root small { color: var(--wf-ink-soft); font-size: 12.5px; }\n.wf-root a { color: var(--wf-accent); text-decoration: none; }\n.wf-root hr { border: 0; border-top: var(--wf-stroke) solid var(--wf-line); margin: 10px 0; }\n.wf-root ul, .wf-root ol { margin: 0 0 8px; padding-left: 1.2em; }\n.wf-root li { margin: 2px 0; }\n.wf-root label { font-size: 12.5px; font-weight: 700; color: var(--wf-ink-soft); }\n.wf-root blockquote { margin: 0 0 8px; padding: 6px 12px; border-left: 3px solid var(--wf-line); color: var(--wf-ink-soft); }\n.wf-root code, .wf-root pre { font-family: ui-monospace, Menlo, monospace; font-size: 12.5px; background: var(--wf-card); border-radius: 5px; }\n.wf-root pre { padding: 8px 10px; overflow: auto; margin: 0 0 8px; }\n.wf-root table { width: 100%; border-collapse: collapse; margin: 0 0 8px; font-size: 13px; }\n.wf-root th { text-align: left; font-weight: 700; border-bottom: var(--wf-stroke) solid var(--wf-line); padding: 6px 8px; }\n.wf-root td { padding: 6px 8px; border-bottom: 1px solid var(--wf-line); }\n.wf-root figure { margin: 0 0 8px; }\n.wf-root figcaption { font-size: 12.5px; color: var(--wf-ink-soft); }\n\n/* ---- structure ---- */\n.wf-root .wf-screen { display: flex; flex-direction: column; gap: 10px; min-height: 100%; }\n.wf-root .wf-topbar, .wf-root header { display: flex; align-items: center; gap: 10px; border-bottom: var(--wf-stroke) solid var(--wf-line); padding-bottom: 8px; }\n.wf-root .wf-topbar :is(h1, h2, h3, p), .wf-root header :is(h1, h2, h3, p) { margin: 0; }\n.wf-root .wf-content, .wf-root main { display: flex; flex-direction: column; gap: 10px; flex: 1; min-height: 0; }\n.wf-root footer, .wf-root .wf-footer { display: flex; align-items: center; gap: 10px; border-top: var(--wf-stroke) solid var(--wf-line); padding-top: 8px; margin-top: auto; }\n.wf-root nav, .wf-root .wf-nav { display: flex; align-items: center; gap: 12px; }\n.wf-root aside, .wf-root .wf-sidebar { display: flex; flex-direction: column; gap: 8px; border-right: var(--wf-stroke) solid var(--wf-line); padding-right: 10px; }\n.wf-root .wf-row { display: flex; align-items: center; gap: 8px; }\n.wf-root .wf-col { display: flex; flex-direction: column; gap: 8px; }\n.wf-root .wf-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }\n.wf-root .wf-spacer { flex: 1; }\n\n/* ---- surfaces & controls ---- */\n.wf-root .wf-card, .wf-root .wf-box, .wf-root .wf-panel {\n background: var(--wf-card); border: var(--wf-stroke) solid var(--wf-line);\n border-radius: var(--wf-radius); padding: 12px;\n}\n.wf-root .wf-button {\n display: inline-flex; align-items: center; justify-content: center; gap: 6px;\n font: inherit; font-weight: 700; color: var(--wf-ink); background: var(--wf-paper);\n border: var(--wf-stroke) solid var(--wf-line); border-radius: var(--wf-radius);\n padding: 7px 14px; text-decoration: none; cursor: default; width: fit-content;\n}\n.wf-root .wf-button:is(.primary, .wf-primary) {\n background: var(--wf-accent); border-color: var(--wf-accent); color: var(--wf-accent-fg);\n}\n.wf-root .wf-input, .wf-root .wf-field, .wf-root .wf-select, .wf-root .wf-textarea {\n display: flex; align-items: center; min-height: 34px; width: 100%;\n color: var(--wf-ink-soft); background: var(--wf-card);\n border: var(--wf-stroke) solid var(--wf-line); border-radius: var(--wf-radius); padding: 6px 10px;\n}\n.wf-root .wf-textarea { min-height: 64px; align-items: flex-start; }\n.wf-root .wf-form { display: flex; flex-direction: column; gap: 8px; }\n.wf-root .wf-checkbox, .wf-root .wf-radio {\n display: inline-block; width: 15px; height: 15px; flex: 0 0 auto;\n border: var(--wf-stroke) solid var(--wf-sketch); background: var(--wf-paper);\n}\n.wf-root .wf-checkbox { border-radius: 4px; }\n.wf-root .wf-radio { border-radius: 999px; }\n\n/* ---- chips, badges, status ---- */\n.wf-root :is(.wf-badge, .wf-chip, .wf-pill, .wf-tag) {\n display: inline-flex; align-items: center; gap: 5px; width: fit-content; max-width: 100%;\n border: var(--wf-stroke) solid var(--wf-line); border-radius: 999px;\n padding: 2px 10px; font-size: 12.5px; background: var(--wf-paper);\n}\n.wf-root :is(.wf-badge, .wf-chip, .wf-pill, .wf-tag).accent { border-color: var(--wf-accent); color: var(--wf-accent); background: var(--wf-accent-soft); }\n.wf-root .wf-muted { color: var(--wf-ink-soft); }\n.wf-root .wf-hint { color: var(--wf-ink-soft); font-size: 12.5px; }\n.wf-root .wf-error { color: var(--wf-warn); }\n.wf-root :is(.wf-alert, .wf-banner) { background: var(--wf-warn-soft); border: var(--wf-stroke) solid var(--wf-warn); border-radius: var(--wf-radius); padding: 8px 12px; color: var(--wf-warn); }\n\n/* ---- lists ---- */\n.wf-root .wf-list { list-style: none; margin: 0 0 8px; padding: 0; display: flex; flex-direction: column; gap: 6px; }\n.wf-root .wf-list-item {\n display: flex; align-items: center; justify-content: space-between; gap: 10px; margin: 0;\n background: var(--wf-card); border: var(--wf-stroke) solid var(--wf-line);\n border-radius: var(--wf-radius); padding: 9px 12px;\n}\n\n/* ---- media & placeholders ---- */\n.wf-root :is(.wf-image, .wf-img, .wf-media) {\n display: block; min-height: 84px; background: var(--wf-card);\n background-image: linear-gradient(to top right, transparent 49.55%, var(--wf-line) 49.55%, var(--wf-line) 50.45%, transparent 50.45%),\n linear-gradient(to bottom right, transparent 49.55%, var(--wf-line) 49.55%, var(--wf-line) 50.45%, transparent 50.45%);\n border: var(--wf-stroke) solid var(--wf-line); border-radius: var(--wf-radius);\n}\n.wf-root .wf-avatar {\n display: inline-flex; align-items: center; justify-content: center; flex: 0 0 auto;\n width: 32px; height: 32px; border-radius: 999px; font-size: 12px; font-weight: 700;\n background: var(--wf-card); border: var(--wf-stroke) solid var(--wf-line);\n}\n.wf-root .wf-loading {\n display: block; height: 12px; width: 70%; border-radius: 999px; border: 0;\n background: var(--wf-line);\n}\n@media (prefers-reduced-motion: no-preference) {\n .wf-root .wf-loading { animation: wf-pulse 1.6s ease-in-out infinite; }\n}\n@keyframes wf-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.55; } }\n\n/* ---- rough handoff: once the overlay has drawn hand-drawn outlines, hide the\n crisp borders it replaced (fills and text stay) so nothing is doubled. ---- */\n[data-rough-ready=\"true\"] .wf-root :is(\n .wf-button, .wf-input, .wf-field, .wf-select, .wf-textarea,\n .wf-card, .wf-box, .wf-panel, .wf-badge, .wf-chip, .wf-pill, .wf-tag,\n .wf-list-item, .wf-avatar, .wf-image, .wf-img, .wf-media, .wf-alert, .wf-banner,\n .wf-checkbox, .wf-radio, hr\n) { border-color: transparent !important; }\n";
18
+ /**
19
+ * Class names the theme MUST style (superset of the generation contract's
20
+ * common vocabulary). The coverage test asserts each appears in the CSS so a
21
+ * generated artifact can never render a bare, unstyled block again.
22
+ */
23
+ export declare const WIREFRAME_THEME_CLASSES: readonly string[];
24
+ //# sourceMappingURL=wireframe-theme.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wireframe-theme.d.ts","sourceRoot":"","sources":["../../../src/visual-plan/domain/wireframe-theme.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,eAAO,MAAM,mBAAmB,2uQAwI/B,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,uBAAuB,EAAE,SAAS,MAAM,EASpD,CAAC"}
@@ -0,0 +1,169 @@
1
+ /**
2
+ * Shared wireframe theme — the SINGLE source of truth for how sanitized
3
+ * `.wf-*` semantic HTML looks, consumed by BOTH renderers (same pattern as
4
+ * sanitizer-config.ts): the studio injects it at boot, `export --format html`
5
+ * embeds it in the exported page. One theme, two surfaces, no drift.
6
+ *
7
+ * Visual language follows the agent-native plan renderer (ISC), re-expressed
8
+ * for MeowKit's vocabulary: a scoped ink/paper/card/accent token palette with
9
+ * soft variants, hand-drawn font by DEFAULT (sketchy is the primary register;
10
+ * `[data-style="clean"]` swaps to the sans stack), 1.4px strokes, 9px radii,
11
+ * and a `[data-rough-ready]` hook that hides crisp borders once the rough.js
12
+ * overlay has redrawn them so outlines are never doubled.
13
+ *
14
+ * Pure data — no DOM, no imports — so the Node exporter and the Vite bundle
15
+ * can both consume it.
16
+ */
17
+ export const WIREFRAME_THEME_CSS = `
18
+ /* ---- tokens (scoped to .wf-root; light + dark) ---- */
19
+ .wf-root {
20
+ --wf-ink: #222b38; --wf-ink-soft: #6b7684; --wf-line: #d3d9e0; --wf-sketch: #94a0ad;
21
+ --wf-paper: #ffffff; --wf-card: #f6f8fa;
22
+ --wf-accent: #4c6ef5; --wf-accent-fg: #ffffff; --wf-accent-soft: rgba(76, 110, 245, 0.12);
23
+ --wf-warn: #d64545; --wf-warn-soft: rgba(214, 69, 69, 0.12); --wf-ok: #2f9e63;
24
+ --wf-radius: 9px; --wf-stroke: 1.4px;
25
+ --wf-font-hand: "Architects Daughter", "Comic Sans MS", "Bradley Hand", "Marker Felt", cursive;
26
+ --wf-font-clean: ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
27
+ --wf-font: var(--wf-font-hand);
28
+ background: var(--wf-paper); color: var(--wf-ink);
29
+ font-family: var(--wf-font); font-size: 14px; line-height: 1.45;
30
+ padding: 14px; height: 100%; overflow: hidden; position: relative;
31
+ }
32
+ .wf-root, .wf-root * { box-sizing: border-box; min-width: 0; }
33
+ [data-style="clean"] .wf-root { --wf-font: var(--wf-font-clean); }
34
+ @media (prefers-color-scheme: dark) {
35
+ .wf-root {
36
+ --wf-ink: #e9edf3; --wf-ink-soft: #93a0ae; --wf-line: #2c3646; --wf-sketch: #5d6a7a;
37
+ --wf-paper: #171d26; --wf-card: #1e2733;
38
+ --wf-accent: #7c9aff; --wf-accent-fg: #10141c; --wf-accent-soft: rgba(124, 154, 255, 0.16);
39
+ --wf-warn: #ef7070; --wf-warn-soft: rgba(239, 112, 112, 0.16); --wf-ok: #52c184;
40
+ }
41
+ }
42
+
43
+ /* ---- bare semantic elements ---- */
44
+ .wf-root h1 { font-size: 21px; font-weight: 700; line-height: 1.15; margin: 0 0 8px; }
45
+ .wf-root h2 { font-size: 17px; font-weight: 700; line-height: 1.2; margin: 0 0 6px; }
46
+ .wf-root h3, .wf-root h4, .wf-root h5, .wf-root h6 { font-size: 14px; font-weight: 700; margin: 0 0 4px; }
47
+ .wf-root p { margin: 0 0 8px; }
48
+ .wf-root small { color: var(--wf-ink-soft); font-size: 12.5px; }
49
+ .wf-root a { color: var(--wf-accent); text-decoration: none; }
50
+ .wf-root hr { border: 0; border-top: var(--wf-stroke) solid var(--wf-line); margin: 10px 0; }
51
+ .wf-root ul, .wf-root ol { margin: 0 0 8px; padding-left: 1.2em; }
52
+ .wf-root li { margin: 2px 0; }
53
+ .wf-root label { font-size: 12.5px; font-weight: 700; color: var(--wf-ink-soft); }
54
+ .wf-root blockquote { margin: 0 0 8px; padding: 6px 12px; border-left: 3px solid var(--wf-line); color: var(--wf-ink-soft); }
55
+ .wf-root code, .wf-root pre { font-family: ui-monospace, Menlo, monospace; font-size: 12.5px; background: var(--wf-card); border-radius: 5px; }
56
+ .wf-root pre { padding: 8px 10px; overflow: auto; margin: 0 0 8px; }
57
+ .wf-root table { width: 100%; border-collapse: collapse; margin: 0 0 8px; font-size: 13px; }
58
+ .wf-root th { text-align: left; font-weight: 700; border-bottom: var(--wf-stroke) solid var(--wf-line); padding: 6px 8px; }
59
+ .wf-root td { padding: 6px 8px; border-bottom: 1px solid var(--wf-line); }
60
+ .wf-root figure { margin: 0 0 8px; }
61
+ .wf-root figcaption { font-size: 12.5px; color: var(--wf-ink-soft); }
62
+
63
+ /* ---- structure ---- */
64
+ .wf-root .wf-screen { display: flex; flex-direction: column; gap: 10px; min-height: 100%; }
65
+ .wf-root .wf-topbar, .wf-root header { display: flex; align-items: center; gap: 10px; border-bottom: var(--wf-stroke) solid var(--wf-line); padding-bottom: 8px; }
66
+ .wf-root .wf-topbar :is(h1, h2, h3, p), .wf-root header :is(h1, h2, h3, p) { margin: 0; }
67
+ .wf-root .wf-content, .wf-root main { display: flex; flex-direction: column; gap: 10px; flex: 1; min-height: 0; }
68
+ .wf-root footer, .wf-root .wf-footer { display: flex; align-items: center; gap: 10px; border-top: var(--wf-stroke) solid var(--wf-line); padding-top: 8px; margin-top: auto; }
69
+ .wf-root nav, .wf-root .wf-nav { display: flex; align-items: center; gap: 12px; }
70
+ .wf-root aside, .wf-root .wf-sidebar { display: flex; flex-direction: column; gap: 8px; border-right: var(--wf-stroke) solid var(--wf-line); padding-right: 10px; }
71
+ .wf-root .wf-row { display: flex; align-items: center; gap: 8px; }
72
+ .wf-root .wf-col { display: flex; flex-direction: column; gap: 8px; }
73
+ .wf-root .wf-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
74
+ .wf-root .wf-spacer { flex: 1; }
75
+
76
+ /* ---- surfaces & controls ---- */
77
+ .wf-root .wf-card, .wf-root .wf-box, .wf-root .wf-panel {
78
+ background: var(--wf-card); border: var(--wf-stroke) solid var(--wf-line);
79
+ border-radius: var(--wf-radius); padding: 12px;
80
+ }
81
+ .wf-root .wf-button {
82
+ display: inline-flex; align-items: center; justify-content: center; gap: 6px;
83
+ font: inherit; font-weight: 700; color: var(--wf-ink); background: var(--wf-paper);
84
+ border: var(--wf-stroke) solid var(--wf-line); border-radius: var(--wf-radius);
85
+ padding: 7px 14px; text-decoration: none; cursor: default; width: fit-content;
86
+ }
87
+ .wf-root .wf-button:is(.primary, .wf-primary) {
88
+ background: var(--wf-accent); border-color: var(--wf-accent); color: var(--wf-accent-fg);
89
+ }
90
+ .wf-root .wf-input, .wf-root .wf-field, .wf-root .wf-select, .wf-root .wf-textarea {
91
+ display: flex; align-items: center; min-height: 34px; width: 100%;
92
+ color: var(--wf-ink-soft); background: var(--wf-card);
93
+ border: var(--wf-stroke) solid var(--wf-line); border-radius: var(--wf-radius); padding: 6px 10px;
94
+ }
95
+ .wf-root .wf-textarea { min-height: 64px; align-items: flex-start; }
96
+ .wf-root .wf-form { display: flex; flex-direction: column; gap: 8px; }
97
+ .wf-root .wf-checkbox, .wf-root .wf-radio {
98
+ display: inline-block; width: 15px; height: 15px; flex: 0 0 auto;
99
+ border: var(--wf-stroke) solid var(--wf-sketch); background: var(--wf-paper);
100
+ }
101
+ .wf-root .wf-checkbox { border-radius: 4px; }
102
+ .wf-root .wf-radio { border-radius: 999px; }
103
+
104
+ /* ---- chips, badges, status ---- */
105
+ .wf-root :is(.wf-badge, .wf-chip, .wf-pill, .wf-tag) {
106
+ display: inline-flex; align-items: center; gap: 5px; width: fit-content; max-width: 100%;
107
+ border: var(--wf-stroke) solid var(--wf-line); border-radius: 999px;
108
+ padding: 2px 10px; font-size: 12.5px; background: var(--wf-paper);
109
+ }
110
+ .wf-root :is(.wf-badge, .wf-chip, .wf-pill, .wf-tag).accent { border-color: var(--wf-accent); color: var(--wf-accent); background: var(--wf-accent-soft); }
111
+ .wf-root .wf-muted { color: var(--wf-ink-soft); }
112
+ .wf-root .wf-hint { color: var(--wf-ink-soft); font-size: 12.5px; }
113
+ .wf-root .wf-error { color: var(--wf-warn); }
114
+ .wf-root :is(.wf-alert, .wf-banner) { background: var(--wf-warn-soft); border: var(--wf-stroke) solid var(--wf-warn); border-radius: var(--wf-radius); padding: 8px 12px; color: var(--wf-warn); }
115
+
116
+ /* ---- lists ---- */
117
+ .wf-root .wf-list { list-style: none; margin: 0 0 8px; padding: 0; display: flex; flex-direction: column; gap: 6px; }
118
+ .wf-root .wf-list-item {
119
+ display: flex; align-items: center; justify-content: space-between; gap: 10px; margin: 0;
120
+ background: var(--wf-card); border: var(--wf-stroke) solid var(--wf-line);
121
+ border-radius: var(--wf-radius); padding: 9px 12px;
122
+ }
123
+
124
+ /* ---- media & placeholders ---- */
125
+ .wf-root :is(.wf-image, .wf-img, .wf-media) {
126
+ display: block; min-height: 84px; background: var(--wf-card);
127
+ background-image: linear-gradient(to top right, transparent 49.55%, var(--wf-line) 49.55%, var(--wf-line) 50.45%, transparent 50.45%),
128
+ linear-gradient(to bottom right, transparent 49.55%, var(--wf-line) 49.55%, var(--wf-line) 50.45%, transparent 50.45%);
129
+ border: var(--wf-stroke) solid var(--wf-line); border-radius: var(--wf-radius);
130
+ }
131
+ .wf-root .wf-avatar {
132
+ display: inline-flex; align-items: center; justify-content: center; flex: 0 0 auto;
133
+ width: 32px; height: 32px; border-radius: 999px; font-size: 12px; font-weight: 700;
134
+ background: var(--wf-card); border: var(--wf-stroke) solid var(--wf-line);
135
+ }
136
+ .wf-root .wf-loading {
137
+ display: block; height: 12px; width: 70%; border-radius: 999px; border: 0;
138
+ background: var(--wf-line);
139
+ }
140
+ @media (prefers-reduced-motion: no-preference) {
141
+ .wf-root .wf-loading { animation: wf-pulse 1.6s ease-in-out infinite; }
142
+ }
143
+ @keyframes wf-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.55; } }
144
+
145
+ /* ---- rough handoff: once the overlay has drawn hand-drawn outlines, hide the
146
+ crisp borders it replaced (fills and text stay) so nothing is doubled. ---- */
147
+ [data-rough-ready="true"] .wf-root :is(
148
+ .wf-button, .wf-input, .wf-field, .wf-select, .wf-textarea,
149
+ .wf-card, .wf-box, .wf-panel, .wf-badge, .wf-chip, .wf-pill, .wf-tag,
150
+ .wf-list-item, .wf-avatar, .wf-image, .wf-img, .wf-media, .wf-alert, .wf-banner,
151
+ .wf-checkbox, .wf-radio, hr
152
+ ) { border-color: transparent !important; }
153
+ `;
154
+ /**
155
+ * Class names the theme MUST style (superset of the generation contract's
156
+ * common vocabulary). The coverage test asserts each appears in the CSS so a
157
+ * generated artifact can never render a bare, unstyled block again.
158
+ */
159
+ export const WIREFRAME_THEME_CLASSES = [
160
+ "wf-screen", "wf-topbar", "wf-content", "wf-footer", "wf-nav", "wf-sidebar",
161
+ "wf-row", "wf-col", "wf-grid", "wf-spacer",
162
+ "wf-card", "wf-box", "wf-panel", "wf-button", "wf-input", "wf-field", "wf-select", "wf-textarea", "wf-form",
163
+ "wf-checkbox", "wf-radio",
164
+ "wf-badge", "wf-chip", "wf-pill", "wf-tag",
165
+ "wf-muted", "wf-hint", "wf-error", "wf-alert", "wf-banner",
166
+ "wf-list", "wf-list-item",
167
+ "wf-image", "wf-img", "wf-media", "wf-avatar", "wf-loading",
168
+ ];
169
+ //# sourceMappingURL=wireframe-theme.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wireframe-theme.js","sourceRoot":"","sources":["../../../src/visual-plan/domain/wireframe-theme.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,MAAM,CAAC,MAAM,mBAAmB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwIlC,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAsB;IACzD,WAAW,EAAE,WAAW,EAAE,YAAY,EAAE,WAAW,EAAE,QAAQ,EAAE,YAAY;IAC3E,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,WAAW;IAC1C,SAAS,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,aAAa,EAAE,SAAS;IAC3G,aAAa,EAAE,UAAU;IACzB,UAAU,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ;IAC1C,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW;IAC1D,SAAS,EAAE,cAAc;IACzB,UAAU,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAW,EAAE,YAAY;CAC3D,CAAC"}
@@ -1 +1 @@
1
- @font-face{font-family:Architects Daughter;font-style:normal;font-display:swap;font-weight:400;src:url(/architects-daughter-latin-ext-400-normal.woff2) format("woff2"),url(/architects-daughter-latin-ext-400-normal.woff) format("woff");unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:Architects Daughter;font-style:normal;font-display:swap;font-weight:400;src:url(/architects-daughter-latin-400-normal.woff2) format("woff2"),url(/architects-daughter-latin-400-normal.woff) format("woff");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}:root{--vp-bg: #f4f5f7;--vp-surface: #ffffff;--vp-border: #d7dbe0;--vp-text: #1c2430;--vp-muted: #64707d;--vp-accent: #3563e9;--wf-bg: #ffffff;--wf-fg: #1c2430;--wf-line: #d7dbe0;--wf-muted: #eef1f4}@media(prefers-color-scheme:dark){:root{--vp-bg: #0b0e13;--vp-surface: #141a22;--vp-border: #263041;--vp-text: #e8edf3;--vp-muted: #93a1b0;--vp-accent: #6f97ff;--wf-bg: #161d27;--wf-fg: #e8edf3;--wf-line: #2b3648;--wf-muted: #1e2733}}*{box-sizing:border-box}html,body,#root{height:100%;margin:0}body{font-family:system-ui,-apple-system,Segoe UI,sans-serif;background:var(--vp-bg);color:var(--vp-text)}.vp-app{display:flex;flex-direction:column;height:100%}.vp-loading,.vp-error{padding:2rem;color:var(--vp-muted)}.vp-error{color:#c0392b}.vp-toolbar{display:flex;align-items:center;gap:.75rem;padding:.5rem 1rem;background:var(--vp-surface);border-bottom:1px solid var(--vp-border)}.vp-toolbar-title{font-weight:600}.vp-toolbar-meta{color:var(--vp-muted);font-size:.85rem}.vp-error-banner{font-size:.75rem;color:#fff;background:#c0392b;padding:.1rem .6rem;border-radius:6px}.vp-save-status{font-size:.75rem;color:var(--vp-muted);padding:.1rem .5rem;border-radius:999px;border:1px solid var(--vp-border)}.vp-save-status[data-state=saving]{color:var(--vp-accent)}.vp-save-status[data-state=stale],.vp-save-status[data-state=error]{color:#c0392b;border-color:#c0392b}.vp-mode-toggle{font-size:.78rem;padding:.15rem .6rem;border:1px solid var(--vp-border);border-radius:6px;background:var(--vp-surface);color:var(--vp-text);cursor:pointer}.vp-toolbar-review{margin-left:auto;font-size:.8rem;padding:.1rem .5rem;border-radius:999px;border:1px solid var(--vp-border)}.vp-sketch .vp-artboard-title,.vp-sketch .wf-root{font-family:Architects Daughter,Comic Sans MS,cursive}.vp-sketch .vp-artboard{border-color:transparent}.vp-toolbar-review[data-status=approved]{color:#1f8a4c;border-color:#1f8a4c}.vp-body{display:grid;grid-template-columns:1fr 260px 260px;flex:1;min-height:0}.vp-viewport{position:relative;overflow:hidden;background:var(--vp-bg);outline:none}.vp-world{position:absolute;top:0;left:0}@media(prefers-reduced-motion:no-preference){.vp-world{transition:transform 80ms ease-out}}.vp-lane{border:1px dashed var(--vp-border);border-radius:12px;background:color-mix(in srgb,var(--vp-surface) 40%,transparent)}.vp-lane-label{font-size:.75rem;color:var(--vp-muted);padding:.4rem .7rem;text-transform:uppercase;letter-spacing:.04em}.vp-artboard{border:1px solid var(--vp-border);border-radius:10px;background:var(--vp-surface);overflow:hidden;cursor:pointer;box-shadow:0 1px 3px #00000014}.vp-artboard.is-selected{outline:2px solid var(--vp-accent)}.vp-artboard-header{display:flex;align-items:center;justify-content:space-between;padding:.35rem .6rem;border-bottom:1px solid var(--vp-border);font-size:.8rem}.vp-artboard-surface{font-size:.7rem;color:var(--vp-muted)}.vp-artboard-surface[data-change=target]{color:var(--vp-accent)}.vp-artboard-body{overflow:hidden;background:var(--wf-bg)}.vp-zoom-controls{position:absolute;bottom:12px;right:12px;display:flex;gap:4px;align-items:center;background:var(--vp-surface);border:1px solid var(--vp-border);border-radius:8px;padding:2px 6px}.vp-zoom-controls button{border:none;background:transparent;color:var(--vp-text);cursor:pointer;font-size:.9rem;padding:2px 6px}.vp-zoom-level{font-size:.75rem;color:var(--vp-muted);min-width:40px;text-align:center}.vp-side{border-left:1px solid var(--vp-border);background:var(--vp-surface);overflow-y:auto;display:flex;flex-direction:column}.vp-edit-controls{padding:.5rem .75rem;border-top:1px solid var(--vp-border);display:flex;gap:10px;flex-wrap:wrap}.vp-edit-field{display:flex;flex-direction:column;font-size:.72rem;color:var(--vp-muted);gap:2px}.vp-edit-field select,.vp-edit-field input{font-size:.8rem;padding:2px 4px;border:1px solid var(--vp-border);border-radius:4px;background:var(--vp-bg);color:var(--vp-text)}.vp-feedback{padding:.75rem;border-top:1px solid var(--vp-border);display:flex;flex-direction:column;gap:6px}.vp-feedback-ops{list-style:none;margin:0;padding:0;font-size:.78rem;display:flex;flex-direction:column;gap:2px}.vp-fb-type{color:var(--vp-muted);font-size:.7rem}.vp-feedback select,.vp-feedback textarea{font-size:.8rem;border:1px solid var(--vp-border);border-radius:4px;background:var(--vp-bg);color:var(--vp-text);padding:4px}.vp-feedback textarea{min-height:48px;resize:vertical}.vp-fb-hint{font-size:.72rem;color:#c0392b;margin:0}.vp-copy-command{display:flex;flex-direction:column;gap:4px;background:var(--vp-bg);border:1px solid var(--vp-border);border-radius:6px;padding:6px}.vp-copy-command code{font-size:.72rem;word-break:break-all}.vp-coverage-panel,.vp-inspector{background:var(--vp-surface);padding:.75rem}.vp-coverage-panel{border-left:1px solid var(--vp-border);overflow-y:auto}.vp-panel-title{font-size:.9rem;margin:0 0 .5rem}.vp-coverage-summary{display:flex;flex-wrap:wrap;gap:4px;margin-bottom:.6rem}.vp-cov-chip{font-size:.7rem;padding:.1rem .4rem;border-radius:999px;border:1px solid var(--vp-border)}.vp-cov-chip[data-mode=unresolved]{color:#c0392b;border-color:#c0392b}.vp-cov-chip[data-mode=resolved]{color:#1f8a4c}.vp-coverage-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:2px}.vp-coverage-row{display:flex;gap:6px;font-size:.78rem;padding:.2rem .3rem;border-radius:6px}.vp-coverage-row[data-mode=unresolved]{background:color-mix(in srgb,#c0392b 12%,transparent)}.vp-cov-surface{color:var(--vp-muted);margin-left:auto}.vp-inspector-fields{display:grid;grid-template-columns:auto 1fr;gap:4px 10px;font-size:.8rem;margin:0}.vp-inspector-fields dt{color:var(--vp-muted)}.vp-inspector-refs{margin:0;padding-left:1rem}.vp-inspector-empty{color:var(--vp-muted);font-size:.85rem}.vp-connector-path{stroke:var(--vp-muted);stroke-width:2}.vp-connector-arrow{fill:var(--vp-muted)}.vp-connector-label{fill:var(--vp-muted);font-size:11px;paint-order:stroke;stroke:var(--vp-bg);stroke-width:3px}.vp-annotation-layer{position:absolute;top:0;left:0}.vp-note{background:color-mix(in srgb,#f4c542 22%,var(--vp-surface));border:1px solid color-mix(in srgb,#f4c542 55%,var(--vp-border));border-radius:8px;padding:6px 8px;font-size:12px;color:var(--vp-text);box-shadow:0 1px 2px #00000014}.vp-markup{color:#c0392b;font-size:12px;font-weight:600}.wf-root{color:var(--wf-fg);font:14px/1.4 system-ui,sans-serif;padding:12px}.wf-root .wf-screen{display:flex;flex-direction:column;gap:10px}.wf-root .wf-topbar{border-bottom:1px solid var(--wf-line);padding-bottom:6px}.wf-root h1,.wf-root h2,.wf-root h3{margin:0}.wf-root .wf-form{display:flex;flex-direction:column;gap:6px}.wf-root .wf-input{height:32px;border:1px solid var(--wf-line);border-radius:6px;background:var(--wf-muted)}.wf-root .wf-button{display:inline-block;padding:8px 14px;background:var(--vp-accent);color:#fff;border-radius:6px;text-align:center;text-decoration:none}.wf-root .wf-error{color:#c0392b}.wf-root .wf-list{padding-left:1.1rem;margin:0}.wf-root a{color:var(--vp-accent)}
1
+ @font-face{font-family:Architects Daughter;font-style:normal;font-display:swap;font-weight:400;src:url(/architects-daughter-latin-ext-400-normal.woff2) format("woff2"),url(/architects-daughter-latin-ext-400-normal.woff) format("woff");unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:Architects Daughter;font-style:normal;font-display:swap;font-weight:400;src:url(/architects-daughter-latin-400-normal.woff2) format("woff2"),url(/architects-daughter-latin-400-normal.woff) format("woff");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}:root{--vp-bg: #f4f5f7;--vp-canvas: #e9ebef;--vp-grid: rgba(28, 36, 48, .035);--vp-surface: #ffffff;--vp-chrome: rgba(255, 255, 255, .88);--vp-border: #d7dbe0;--vp-text: #1c2430;--vp-muted: #64707d;--vp-accent: #4c6ef5;--vp-warn: #c0392b;--vp-ok: #1f8a4c;--vp-shadow: 0 8px 24px rgba(20, 28, 40, .1)}@media(prefers-color-scheme:dark){:root{--vp-bg: #0b0e13;--vp-canvas: #090c11;--vp-grid: rgba(232, 237, 243, .03);--vp-surface: #141a22;--vp-chrome: rgba(20, 26, 34, .88);--vp-border: #263041;--vp-text: #e8edf3;--vp-muted: #93a1b0;--vp-accent: #7c9aff;--vp-warn: #ef7070;--vp-ok: #52c184;--vp-shadow: 0 8px 24px rgba(0, 0, 0, .45)}}*{box-sizing:border-box}html,body,#root{height:100%;margin:0}body{font-family:system-ui,-apple-system,Segoe UI,sans-serif;background:var(--vp-bg);color:var(--vp-text)}.vp-app{display:flex;flex-direction:column;height:100%}.vp-loading,.vp-error{padding:2rem;color:var(--vp-muted)}.vp-error{color:var(--vp-warn)}.vp-toolbar{display:flex;align-items:center;gap:.75rem;padding:.5rem 1rem;background:var(--vp-surface);border-bottom:1px solid var(--vp-border)}.vp-toolbar-title{font-weight:600}.vp-toolbar-meta{color:var(--vp-muted);font-size:.85rem}.vp-error-banner{font-size:.75rem;color:#fff;background:var(--vp-warn);padding:.1rem .6rem;border-radius:6px}.vp-save-status{font-size:.75rem;color:var(--vp-muted);padding:.1rem .5rem;border-radius:999px;border:1px solid var(--vp-border)}.vp-save-status[data-state=saving]{color:var(--vp-accent)}.vp-save-status[data-state=stale],.vp-save-status[data-state=error]{color:var(--vp-warn);border-color:var(--vp-warn)}.vp-mode-toggle{font-size:.78rem;padding:.15rem .6rem;border:1px solid var(--vp-border);border-radius:6px;background:var(--vp-surface);color:var(--vp-text);cursor:pointer}.vp-mode-toggle:hover{border-color:var(--vp-accent);color:var(--vp-accent)}.vp-toolbar-review{margin-left:auto;font-size:.8rem;padding:.1rem .5rem;border-radius:999px;border:1px solid var(--vp-border)}.vp-toolbar-review[data-status=approved]{color:var(--vp-ok);border-color:var(--vp-ok)}.vp-body{display:grid;grid-template-columns:1fr 260px 260px;flex:1;min-height:0}.vp-viewport{position:relative;overflow:hidden;outline:none;background-color:var(--vp-canvas);background-image:linear-gradient(var(--vp-grid) 1px,transparent 1px),linear-gradient(90deg,var(--vp-grid) 1px,transparent 1px)}.vp-world{position:absolute;top:0;left:0}@media(prefers-reduced-motion:no-preference){.vp-world{transition:transform 80ms ease-out}}.vp-lane{border:1px dashed color-mix(in srgb,var(--vp-border) 70%,transparent);border-radius:20px;background:color-mix(in srgb,var(--vp-text) 1.5%,transparent)}.vp-lane-label{font-size:1.05rem;font-weight:600;letter-spacing:-.01em;color:var(--vp-text);padding:.7rem 1.2rem 0}.vp-artboard{cursor:pointer}.vp-artboard-caption{position:absolute;bottom:100%;left:2px;padding-bottom:6px;display:flex;align-items:baseline;gap:8px;white-space:nowrap;pointer-events:none}.vp-artboard-title{font-size:13px;font-weight:600;color:var(--vp-text)}.vp-artboard-surface{font-size:11px;color:var(--vp-muted)}.vp-artboard-surface[data-change=target]{color:var(--vp-accent)}.vp-artboard-body{position:relative;overflow:hidden;height:100%;background:var(--vp-surface);border:1.5px solid var(--vp-border);box-shadow:0 1px 3px #1016200f}.vp-artboard:hover .vp-artboard-body{box-shadow:var(--vp-shadow)}.vp-artboard.is-selected .vp-artboard-body{outline:2px solid var(--vp-accent);outline-offset:3px}.vp-sketch .vp-artboard-body[data-rough-ready=true]{border-color:transparent}.vp-sketch .vp-artboard-title{font-family:Architects Daughter,Comic Sans MS,cursive;font-size:14px}@media(prefers-reduced-motion:no-preference){.vp-sketch .vp-artboard-body{filter:url(#vp-wobble)}}.vp-zoom-controls{position:absolute;bottom:12px;left:12px;z-index:10;display:flex;gap:2px;align-items:center;background:var(--vp-chrome);border:1px solid var(--vp-border);border-radius:10px;padding:3px 5px;box-shadow:var(--vp-shadow);-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px)}.vp-zoom-controls button{border:none;background:transparent;color:var(--vp-text);cursor:pointer;font-size:.85rem;padding:2px 7px;border-radius:6px}.vp-zoom-controls button:hover{background:color-mix(in srgb,var(--vp-text) 8%,transparent)}.vp-zoom-level{font-size:.72rem;font-weight:600;font-variant-numeric:tabular-nums;color:var(--vp-muted);min-width:40px;text-align:center}.vp-side{border-left:1px solid var(--vp-border);background:var(--vp-surface);overflow-y:auto;display:flex;flex-direction:column}.vp-edit-controls{padding:.5rem .75rem;border-top:1px solid var(--vp-border);display:flex;gap:10px;flex-wrap:wrap}.vp-edit-field{display:flex;flex-direction:column;font-size:.72rem;color:var(--vp-muted);gap:2px}.vp-edit-field select,.vp-edit-field input{font-size:.8rem;padding:2px 4px;border:1px solid var(--vp-border);border-radius:4px;background:var(--vp-bg);color:var(--vp-text)}.vp-feedback{padding:.75rem;border-top:1px solid var(--vp-border);display:flex;flex-direction:column;gap:6px}.vp-feedback-ops{list-style:none;margin:0;padding:0;font-size:.78rem;display:flex;flex-direction:column;gap:2px}.vp-fb-type{color:var(--vp-muted);font-size:.7rem}.vp-feedback select,.vp-feedback textarea{font-size:.8rem;border:1px solid var(--vp-border);border-radius:4px;background:var(--vp-bg);color:var(--vp-text);padding:4px}.vp-feedback textarea{min-height:48px;resize:vertical}.vp-fb-hint{font-size:.72rem;color:var(--vp-warn);margin:0}.vp-copy-command{display:flex;flex-direction:column;gap:4px;background:var(--vp-bg);border:1px solid var(--vp-border);border-radius:6px;padding:6px}.vp-copy-command code{font-size:.72rem;word-break:break-all}.vp-coverage-panel,.vp-inspector{background:var(--vp-surface);padding:.75rem}.vp-coverage-panel{border-left:1px solid var(--vp-border);overflow-y:auto}.vp-panel-title{font-size:.9rem;margin:0 0 .5rem}.vp-coverage-summary{display:flex;flex-wrap:wrap;gap:4px;margin-bottom:.6rem}.vp-cov-chip{font-size:.7rem;padding:.1rem .4rem;border-radius:999px;border:1px solid var(--vp-border)}.vp-cov-chip[data-mode=unresolved]{color:var(--vp-warn);border-color:var(--vp-warn)}.vp-cov-chip[data-mode=resolved]{color:var(--vp-ok)}.vp-coverage-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:2px}.vp-coverage-row{display:flex;gap:6px;font-size:.78rem;padding:.2rem .3rem;border-radius:6px}.vp-coverage-row[data-mode=unresolved]{background:color-mix(in srgb,var(--vp-warn) 12%,transparent)}.vp-cov-surface{color:var(--vp-muted);margin-left:auto}.vp-inspector-fields{display:grid;grid-template-columns:auto 1fr;gap:4px 10px;font-size:.8rem;margin:0}.vp-inspector-fields dt{color:var(--vp-muted)}.vp-inspector-refs{margin:0;padding-left:1rem}.vp-inspector-empty{color:var(--vp-muted);font-size:.85rem}.vp-connector-path{stroke:var(--vp-accent);stroke-width:2.4;stroke-linecap:round;stroke-linejoin:round;fill:none}.vp-connector-head{stroke:var(--vp-accent);stroke-width:2.4;stroke-linecap:round;fill:none}.vp-connector-label-box{fill:var(--vp-chrome);stroke:var(--vp-border);stroke-width:1}.vp-connector-label{fill:var(--vp-accent);font-size:12px;font-weight:600}@media(prefers-reduced-motion:no-preference){.vp-sketch .vp-connector-path,.vp-sketch .vp-connector-head{filter:url(#vp-wobble)}}.vp-annotation-layer{position:absolute;top:0;left:0}.vp-note{width:240px;font-size:13px;line-height:1.55;color:var(--vp-muted)}.vp-note:before{content:"✎ ";color:var(--vp-accent)}.vp-sketch .vp-note{font-family:Architects Daughter,Comic Sans MS,cursive}.vp-markup{max-width:280px;font-size:12.5px;color:var(--vp-text);background:var(--vp-chrome);border:1px solid color-mix(in srgb,var(--vp-accent) 35%,transparent);border-radius:8px;padding:6px 10px;box-shadow:var(--vp-shadow);-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px)}