openplanr 2.2.1 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/README.md +85 -466
  3. package/dist/cli/commands/spec.d.ts +0 -2
  4. package/dist/cli/commands/spec.d.ts.map +1 -1
  5. package/dist/cli/commands/spec.js +0 -2
  6. package/dist/cli/commands/spec.js.map +1 -1
  7. package/dist/models/types.d.ts +2 -3
  8. package/dist/models/types.d.ts.map +1 -1
  9. package/docs/ARTIFACT_REVIEW.md +2 -2
  10. package/docs/CLI.md +8 -8
  11. package/docs/CROSS_RUNTIME_SETUP.md +33 -26
  12. package/docs/TROUBLESHOOTING.md +44 -38
  13. package/lib/host-packages/adapter-registry.json +5 -5
  14. package/lib/host-packages/capability-map.json +1 -1
  15. package/lib/host-packages/claude/.claude-plugin/marketplace.json +2 -2
  16. package/lib/host-packages/claude/openplanr/.claude-plugin/plugin.json +1 -1
  17. package/lib/host-packages/claude/openplanr/.openplanr-content.json +13 -13
  18. package/lib/host-packages/claude/openplanr/skills/design/scripts/design.mjs +9 -26
  19. package/lib/host-packages/claude/openplanr/skills/design/scripts/runtime/packages/design/templates/studio/studio.css +2 -1
  20. package/lib/host-packages/claude/openplanr/skills/design-loop/scripts/design.mjs +9 -26
  21. package/lib/host-packages/claude/openplanr/skills/design-loop/scripts/runtime/packages/design/templates/studio/studio.css +2 -1
  22. package/lib/host-packages/claude/openplanr/skills/design-review/scripts/design.mjs +9 -26
  23. package/lib/host-packages/claude/openplanr/skills/design-review/scripts/runtime/packages/design/templates/studio/studio.css +2 -1
  24. package/lib/host-packages/claude/openplanr/skills/diagram/SKILL.md +11 -0
  25. package/lib/host-packages/claude/openplanr/skills/diagram/openplanr.skill.json +1 -1
  26. package/lib/host-packages/claude/openplanr/skills/diagram/references/diagram-intent-to-ir.md +21 -0
  27. package/lib/host-packages/claude/openplanr/skills/plan/scripts/design.mjs +9 -26
  28. package/lib/host-packages/claude/openplanr/skills/plan/scripts/runtime/packages/design/templates/studio/studio.css +2 -1
  29. package/lib/host-packages/cursor/openplanr/.openplanr-content.json +12 -12
  30. package/lib/host-packages/cursor/openplanr/manifest.json +1 -1
  31. package/lib/host-packages/cursor/openplanr/rules/planr-design/scripts/design.mjs +9 -26
  32. package/lib/host-packages/cursor/openplanr/rules/planr-design/scripts/runtime/packages/design/templates/studio/studio.css +2 -1
  33. package/lib/host-packages/cursor/openplanr/rules/planr-design-loop/scripts/design.mjs +9 -26
  34. package/lib/host-packages/cursor/openplanr/rules/planr-design-loop/scripts/runtime/packages/design/templates/studio/studio.css +2 -1
  35. package/lib/host-packages/cursor/openplanr/rules/planr-design-review/scripts/design.mjs +9 -26
  36. package/lib/host-packages/cursor/openplanr/rules/planr-design-review/scripts/runtime/packages/design/templates/studio/studio.css +2 -1
  37. package/lib/host-packages/cursor/openplanr/rules/planr-diagram/references/diagram-intent-to-ir.md +21 -0
  38. package/lib/host-packages/cursor/openplanr/rules/planr-diagram.mdc +11 -0
  39. package/lib/host-packages/cursor/openplanr/rules/planr-plan/scripts/design.mjs +9 -26
  40. package/lib/host-packages/cursor/openplanr/rules/planr-plan/scripts/runtime/packages/design/templates/studio/studio.css +2 -1
  41. package/lib/host-packages/openai/.claude-plugin/marketplace.json +2 -2
  42. package/lib/host-packages/openai/openplanr/.codex-plugin/plugin.json +1 -1
  43. package/lib/host-packages/openai/openplanr/.openplanr-content.json +13 -13
  44. package/lib/host-packages/openai/openplanr/skills/design/scripts/design.mjs +9 -26
  45. package/lib/host-packages/openai/openplanr/skills/design/scripts/runtime/packages/design/templates/studio/studio.css +2 -1
  46. package/lib/host-packages/openai/openplanr/skills/design-loop/scripts/design.mjs +9 -26
  47. package/lib/host-packages/openai/openplanr/skills/design-loop/scripts/runtime/packages/design/templates/studio/studio.css +2 -1
  48. package/lib/host-packages/openai/openplanr/skills/design-review/scripts/design.mjs +9 -26
  49. package/lib/host-packages/openai/openplanr/skills/design-review/scripts/runtime/packages/design/templates/studio/studio.css +2 -1
  50. package/lib/host-packages/openai/openplanr/skills/diagram/SKILL.md +11 -0
  51. package/lib/host-packages/openai/openplanr/skills/diagram/openplanr.skill.json +1 -1
  52. package/lib/host-packages/openai/openplanr/skills/diagram/references/diagram-intent-to-ir.md +21 -0
  53. package/lib/host-packages/openai/openplanr/skills/plan/scripts/design.mjs +9 -26
  54. package/lib/host-packages/openai/openplanr/skills/plan/scripts/runtime/packages/design/templates/studio/studio.css +2 -1
  55. package/package.json +2 -2
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openplanr",
3
- "version": "2.2.1",
3
+ "version": "2.3.0",
4
4
  "ruleCount": 27,
5
5
  "rules": [
6
6
  "rules/planr-artifact.mdc",
@@ -11837,11 +11837,14 @@ function activeMetadata(model) {
11837
11837
  if (!artifact) return "HTML \xB7 1440\xD7900";
11838
11838
  return `${artifact.kind.toUpperCase()} \xB7 ${artifact.viewport.width}\xD7${artifact.viewport.height}`;
11839
11839
  }
11840
+ function renderPlanrMark() {
11841
+ return '<span class="planr-mark" aria-hidden="true"><svg viewBox="0 0 160 160" focusable="false"><g transform="rotate(-45 80 80)"><path d="M125 50A52 52 0 1 0 125 110" fill="none" stroke="currentColor" stroke-width="12" stroke-linecap="round" stroke-linejoin="round"/><rect x="127" y="71" width="18" height="18" rx="3" fill="currentColor"/></g></svg></span>';
11842
+ }
11840
11843
  function renderArtifactToolbar(model) {
11841
11844
  const interact = model.reviewMode === "interact";
11842
11845
  const canvas = model.presentation === "canvas";
11843
11846
  return `<header class="planr-toolbar">
11844
- <div class="planr-brand" aria-label="OpenPlanr"><span class="planr-mark" aria-hidden="true"></span><span class="planr-title-block"><strong>${escapeHtml(model.title)}</strong>${canvas ? `<span>${escapeHtml(activeMetadata(model))}</span>` : ""}</span></div>
11847
+ <div class="planr-brand" aria-label="OpenPlanr">${renderPlanrMark()}<span class="planr-title-block"><strong>${escapeHtml(model.title)}</strong>${canvas ? `<span>${escapeHtml(activeMetadata(model))}</span>` : ""}</span></div>
11845
11848
  <span class="planr-privacy" data-privacy="${escapeHtml(model.privacy)}">${escapeHtml(model.privacyLabel)}</span>
11846
11849
  ${canvas ? ' <span class="planr-domain-toolbar" data-planr-slot="domain-toolbar" aria-label="Artifact workflow controls"></span>\n' : ""} <span class="planr-toolbar-spacer" aria-hidden="true"></span>
11847
11850
  ${canvas ? ` <div class="planr-segment" role="group" aria-label="Viewport controls"><button type="button" data-planr-action="zoom-out" aria-label="Zoom out">\u2212</button><button type="button" data-planr-action="zoom-reset" aria-label="Reset zoom">${model.zoom}%</button><button type="button" data-planr-action="zoom-in" aria-label="Zoom in">+</button></div>
@@ -11980,7 +11983,7 @@ function renderArtifactShareDialog() {
11980
11983
  }
11981
11984
  function renderHostedArtifactViewerSlot() {
11982
11985
  return `<section class="planr-hosted-viewer" data-planr-hosted-viewer data-planr-hosted-state="idle" role="status" aria-live="polite" aria-atomic="true" hidden>
11983
- <div><span class="planr-mark" aria-hidden="true"></span><strong data-planr-hosted-title></strong><p data-planr-hosted-detail></p><button type="button" data-planr-hosted-retry hidden></button></div>
11986
+ <div>${renderPlanrMark()}<strong data-planr-hosted-title></strong><p data-planr-hosted-detail></p><button type="button" data-planr-hosted-retry hidden></button></div>
11984
11987
  </section>`;
11985
11988
  }
11986
11989
  function renderArtifactShellMarkup(model) {
@@ -12107,28 +12110,8 @@ button:focus-visible, input:focus-visible, select:focus-visible, textarea:focus-
12107
12110
  background: color-mix(in srgb, var(--planr-color-chrome) 96%, transparent);
12108
12111
  }
12109
12112
  .planr-brand { min-width: 0; display: flex; align-items: center; gap: 9px; }
12110
- .planr-mark {
12111
- position: relative;
12112
- width: 20px;
12113
- height: 20px;
12114
- flex: none;
12115
- rotate: 45deg;
12116
- border: 1px solid color-mix(in srgb, var(--planr-color-primary) 70%, var(--planr-color-rule));
12117
- border-radius: var(--planr-radius-small);
12118
- }
12119
- .planr-mark::before, .planr-mark::after {
12120
- content: "";
12121
- position: absolute;
12122
- border-radius: 2px;
12123
- background: var(--planr-color-primary);
12124
- }
12125
- .planr-mark::before {
12126
- width: 4px;
12127
- height: 4px;
12128
- inset: 3px auto auto 3px;
12129
- box-shadow: 8px 8px 0 var(--planr-color-warning);
12130
- }
12131
- .planr-mark::after { width: 8px; height: 2px; inset: 9px auto auto 6px; rotate: -45deg; }
12113
+ .planr-mark { display: inline-grid; place-items: center; width: 22px; height: 22px; flex: none; color: var(--planr-color-primary); contain: paint; }
12114
+ .planr-mark svg { display: block; width: 100%; height: 100%; }
12132
12115
  .planr-title-block { min-width: 0; display: flex; align-items: baseline; gap: 8px; }
12133
12116
  .planr-title-block strong {
12134
12117
  max-width: 260px;
@@ -12887,7 +12870,7 @@ button:focus-visible, input:focus-visible, select:focus-visible, textarea:focus-
12887
12870
  text-align: center;
12888
12871
  box-shadow: 0 18px 60px color-mix(in srgb, var(--planr-color-background) 50%, transparent);
12889
12872
  }
12890
- .planr-hosted-viewer .planr-mark { display: inline-block; margin-bottom: 20px; }
12873
+ .planr-hosted-viewer .planr-mark { width: 40px; height: 40px; margin-bottom: 20px; }
12891
12874
  .planr-hosted-viewer strong { display: block; margin-bottom: 7px; font: 650 19px/1.2 var(--planr-font-display); }
12892
12875
  .planr-hosted-viewer p { margin: 0; color: var(--planr-color-text-muted); }
12893
12876
  .planr-hosted-viewer button { margin-top: 16px; border-color: var(--planr-color-primary); color: var(--planr-color-primary); }
@@ -13161,7 +13144,7 @@ function toolbar(document2) {
13161
13144
  return `<header class="planr-toolbar design-toolbar">
13162
13145
  <div class="design-toolbar-leading">
13163
13146
  ${iconButton("Screens", "left", 'data-design-toggle-nav aria-controls="design-navigator" aria-expanded="true"', "planr-toolbar-action design-panel-toggle")}
13164
- <div class="planr-brand"><span class="design-wordmark" aria-label="OpenPlanr">Open<span>Planr</span></span><span class="planr-title-block"><strong title="${escapeHtml(document2.title)}">${escapeHtml(document2.title)}</strong></span></div>
13147
+ <div class="planr-brand">${renderPlanrMark()}<span class="design-wordmark" aria-label="OpenPlanr">Open<span>Planr</span></span><span class="planr-title-block"><strong title="${escapeHtml(document2.title)}">${escapeHtml(document2.title)}</strong></span></div>
13165
13148
  </div>
13166
13149
  <div class="planr-segment design-view-picker" role="group" aria-label="Design view">${["canvas", "prototype", "walkthrough"].map((view) => iconButton(view[0].toUpperCase() + view.slice(1), view, `data-design-view="${view}" aria-pressed="${document2.defaultView === view}"`)).join("")}</div>
13167
13150
  <div class="design-toolbar-trailing">
@@ -46,7 +46,8 @@
46
46
  }
47
47
  .design-toolbar-leading, .design-toolbar-trailing { display:flex; align-items:center; gap:10px; min-width:0; }
48
48
  .design-toolbar-trailing { justify-content:flex-end; }
49
- .design-toolbar .planr-brand { display:grid; gap:3px; }
49
+ .design-toolbar .planr-brand { display:grid; grid-template-columns:auto minmax(0,1fr); grid-template-rows:auto auto; column-gap:8px; row-gap:1px; align-items:center; }
50
+ .design-toolbar .planr-brand .planr-mark { grid-row:1 / span 2; }
50
51
  .design-wordmark { font: 800 18px/1 var(--planr-font-display); letter-spacing:-.045em; white-space:nowrap; }
51
52
  .design-wordmark > span { color:var(--planr-color-primary); }
52
53
  .design-toolbar .planr-title-block strong { max-width: min(22vw, 270px); color:var(--planr-color-text-muted); font:400 10px/1.3 var(--planr-font-body); }
@@ -11837,11 +11837,14 @@ function activeMetadata(model) {
11837
11837
  if (!artifact) return "HTML \xB7 1440\xD7900";
11838
11838
  return `${artifact.kind.toUpperCase()} \xB7 ${artifact.viewport.width}\xD7${artifact.viewport.height}`;
11839
11839
  }
11840
+ function renderPlanrMark() {
11841
+ return '<span class="planr-mark" aria-hidden="true"><svg viewBox="0 0 160 160" focusable="false"><g transform="rotate(-45 80 80)"><path d="M125 50A52 52 0 1 0 125 110" fill="none" stroke="currentColor" stroke-width="12" stroke-linecap="round" stroke-linejoin="round"/><rect x="127" y="71" width="18" height="18" rx="3" fill="currentColor"/></g></svg></span>';
11842
+ }
11840
11843
  function renderArtifactToolbar(model) {
11841
11844
  const interact = model.reviewMode === "interact";
11842
11845
  const canvas = model.presentation === "canvas";
11843
11846
  return `<header class="planr-toolbar">
11844
- <div class="planr-brand" aria-label="OpenPlanr"><span class="planr-mark" aria-hidden="true"></span><span class="planr-title-block"><strong>${escapeHtml(model.title)}</strong>${canvas ? `<span>${escapeHtml(activeMetadata(model))}</span>` : ""}</span></div>
11847
+ <div class="planr-brand" aria-label="OpenPlanr">${renderPlanrMark()}<span class="planr-title-block"><strong>${escapeHtml(model.title)}</strong>${canvas ? `<span>${escapeHtml(activeMetadata(model))}</span>` : ""}</span></div>
11845
11848
  <span class="planr-privacy" data-privacy="${escapeHtml(model.privacy)}">${escapeHtml(model.privacyLabel)}</span>
11846
11849
  ${canvas ? ' <span class="planr-domain-toolbar" data-planr-slot="domain-toolbar" aria-label="Artifact workflow controls"></span>\n' : ""} <span class="planr-toolbar-spacer" aria-hidden="true"></span>
11847
11850
  ${canvas ? ` <div class="planr-segment" role="group" aria-label="Viewport controls"><button type="button" data-planr-action="zoom-out" aria-label="Zoom out">\u2212</button><button type="button" data-planr-action="zoom-reset" aria-label="Reset zoom">${model.zoom}%</button><button type="button" data-planr-action="zoom-in" aria-label="Zoom in">+</button></div>
@@ -11980,7 +11983,7 @@ function renderArtifactShareDialog() {
11980
11983
  }
11981
11984
  function renderHostedArtifactViewerSlot() {
11982
11985
  return `<section class="planr-hosted-viewer" data-planr-hosted-viewer data-planr-hosted-state="idle" role="status" aria-live="polite" aria-atomic="true" hidden>
11983
- <div><span class="planr-mark" aria-hidden="true"></span><strong data-planr-hosted-title></strong><p data-planr-hosted-detail></p><button type="button" data-planr-hosted-retry hidden></button></div>
11986
+ <div>${renderPlanrMark()}<strong data-planr-hosted-title></strong><p data-planr-hosted-detail></p><button type="button" data-planr-hosted-retry hidden></button></div>
11984
11987
  </section>`;
11985
11988
  }
11986
11989
  function renderArtifactShellMarkup(model) {
@@ -12107,28 +12110,8 @@ button:focus-visible, input:focus-visible, select:focus-visible, textarea:focus-
12107
12110
  background: color-mix(in srgb, var(--planr-color-chrome) 96%, transparent);
12108
12111
  }
12109
12112
  .planr-brand { min-width: 0; display: flex; align-items: center; gap: 9px; }
12110
- .planr-mark {
12111
- position: relative;
12112
- width: 20px;
12113
- height: 20px;
12114
- flex: none;
12115
- rotate: 45deg;
12116
- border: 1px solid color-mix(in srgb, var(--planr-color-primary) 70%, var(--planr-color-rule));
12117
- border-radius: var(--planr-radius-small);
12118
- }
12119
- .planr-mark::before, .planr-mark::after {
12120
- content: "";
12121
- position: absolute;
12122
- border-radius: 2px;
12123
- background: var(--planr-color-primary);
12124
- }
12125
- .planr-mark::before {
12126
- width: 4px;
12127
- height: 4px;
12128
- inset: 3px auto auto 3px;
12129
- box-shadow: 8px 8px 0 var(--planr-color-warning);
12130
- }
12131
- .planr-mark::after { width: 8px; height: 2px; inset: 9px auto auto 6px; rotate: -45deg; }
12113
+ .planr-mark { display: inline-grid; place-items: center; width: 22px; height: 22px; flex: none; color: var(--planr-color-primary); contain: paint; }
12114
+ .planr-mark svg { display: block; width: 100%; height: 100%; }
12132
12115
  .planr-title-block { min-width: 0; display: flex; align-items: baseline; gap: 8px; }
12133
12116
  .planr-title-block strong {
12134
12117
  max-width: 260px;
@@ -12887,7 +12870,7 @@ button:focus-visible, input:focus-visible, select:focus-visible, textarea:focus-
12887
12870
  text-align: center;
12888
12871
  box-shadow: 0 18px 60px color-mix(in srgb, var(--planr-color-background) 50%, transparent);
12889
12872
  }
12890
- .planr-hosted-viewer .planr-mark { display: inline-block; margin-bottom: 20px; }
12873
+ .planr-hosted-viewer .planr-mark { width: 40px; height: 40px; margin-bottom: 20px; }
12891
12874
  .planr-hosted-viewer strong { display: block; margin-bottom: 7px; font: 650 19px/1.2 var(--planr-font-display); }
12892
12875
  .planr-hosted-viewer p { margin: 0; color: var(--planr-color-text-muted); }
12893
12876
  .planr-hosted-viewer button { margin-top: 16px; border-color: var(--planr-color-primary); color: var(--planr-color-primary); }
@@ -13161,7 +13144,7 @@ function toolbar(document2) {
13161
13144
  return `<header class="planr-toolbar design-toolbar">
13162
13145
  <div class="design-toolbar-leading">
13163
13146
  ${iconButton("Screens", "left", 'data-design-toggle-nav aria-controls="design-navigator" aria-expanded="true"', "planr-toolbar-action design-panel-toggle")}
13164
- <div class="planr-brand"><span class="design-wordmark" aria-label="OpenPlanr">Open<span>Planr</span></span><span class="planr-title-block"><strong title="${escapeHtml(document2.title)}">${escapeHtml(document2.title)}</strong></span></div>
13147
+ <div class="planr-brand">${renderPlanrMark()}<span class="design-wordmark" aria-label="OpenPlanr">Open<span>Planr</span></span><span class="planr-title-block"><strong title="${escapeHtml(document2.title)}">${escapeHtml(document2.title)}</strong></span></div>
13165
13148
  </div>
13166
13149
  <div class="planr-segment design-view-picker" role="group" aria-label="Design view">${["canvas", "prototype", "walkthrough"].map((view) => iconButton(view[0].toUpperCase() + view.slice(1), view, `data-design-view="${view}" aria-pressed="${document2.defaultView === view}"`)).join("")}</div>
13167
13150
  <div class="design-toolbar-trailing">
@@ -46,7 +46,8 @@
46
46
  }
47
47
  .design-toolbar-leading, .design-toolbar-trailing { display:flex; align-items:center; gap:10px; min-width:0; }
48
48
  .design-toolbar-trailing { justify-content:flex-end; }
49
- .design-toolbar .planr-brand { display:grid; gap:3px; }
49
+ .design-toolbar .planr-brand { display:grid; grid-template-columns:auto minmax(0,1fr); grid-template-rows:auto auto; column-gap:8px; row-gap:1px; align-items:center; }
50
+ .design-toolbar .planr-brand .planr-mark { grid-row:1 / span 2; }
50
51
  .design-wordmark { font: 800 18px/1 var(--planr-font-display); letter-spacing:-.045em; white-space:nowrap; }
51
52
  .design-wordmark > span { color:var(--planr-color-primary); }
52
53
  .design-toolbar .planr-title-block strong { max-width: min(22vw, 270px); color:var(--planr-color-text-muted); font:400 10px/1.3 var(--planr-font-body); }
@@ -11837,11 +11837,14 @@ function activeMetadata(model) {
11837
11837
  if (!artifact) return "HTML \xB7 1440\xD7900";
11838
11838
  return `${artifact.kind.toUpperCase()} \xB7 ${artifact.viewport.width}\xD7${artifact.viewport.height}`;
11839
11839
  }
11840
+ function renderPlanrMark() {
11841
+ return '<span class="planr-mark" aria-hidden="true"><svg viewBox="0 0 160 160" focusable="false"><g transform="rotate(-45 80 80)"><path d="M125 50A52 52 0 1 0 125 110" fill="none" stroke="currentColor" stroke-width="12" stroke-linecap="round" stroke-linejoin="round"/><rect x="127" y="71" width="18" height="18" rx="3" fill="currentColor"/></g></svg></span>';
11842
+ }
11840
11843
  function renderArtifactToolbar(model) {
11841
11844
  const interact = model.reviewMode === "interact";
11842
11845
  const canvas = model.presentation === "canvas";
11843
11846
  return `<header class="planr-toolbar">
11844
- <div class="planr-brand" aria-label="OpenPlanr"><span class="planr-mark" aria-hidden="true"></span><span class="planr-title-block"><strong>${escapeHtml(model.title)}</strong>${canvas ? `<span>${escapeHtml(activeMetadata(model))}</span>` : ""}</span></div>
11847
+ <div class="planr-brand" aria-label="OpenPlanr">${renderPlanrMark()}<span class="planr-title-block"><strong>${escapeHtml(model.title)}</strong>${canvas ? `<span>${escapeHtml(activeMetadata(model))}</span>` : ""}</span></div>
11845
11848
  <span class="planr-privacy" data-privacy="${escapeHtml(model.privacy)}">${escapeHtml(model.privacyLabel)}</span>
11846
11849
  ${canvas ? ' <span class="planr-domain-toolbar" data-planr-slot="domain-toolbar" aria-label="Artifact workflow controls"></span>\n' : ""} <span class="planr-toolbar-spacer" aria-hidden="true"></span>
11847
11850
  ${canvas ? ` <div class="planr-segment" role="group" aria-label="Viewport controls"><button type="button" data-planr-action="zoom-out" aria-label="Zoom out">\u2212</button><button type="button" data-planr-action="zoom-reset" aria-label="Reset zoom">${model.zoom}%</button><button type="button" data-planr-action="zoom-in" aria-label="Zoom in">+</button></div>
@@ -11980,7 +11983,7 @@ function renderArtifactShareDialog() {
11980
11983
  }
11981
11984
  function renderHostedArtifactViewerSlot() {
11982
11985
  return `<section class="planr-hosted-viewer" data-planr-hosted-viewer data-planr-hosted-state="idle" role="status" aria-live="polite" aria-atomic="true" hidden>
11983
- <div><span class="planr-mark" aria-hidden="true"></span><strong data-planr-hosted-title></strong><p data-planr-hosted-detail></p><button type="button" data-planr-hosted-retry hidden></button></div>
11986
+ <div>${renderPlanrMark()}<strong data-planr-hosted-title></strong><p data-planr-hosted-detail></p><button type="button" data-planr-hosted-retry hidden></button></div>
11984
11987
  </section>`;
11985
11988
  }
11986
11989
  function renderArtifactShellMarkup(model) {
@@ -12107,28 +12110,8 @@ button:focus-visible, input:focus-visible, select:focus-visible, textarea:focus-
12107
12110
  background: color-mix(in srgb, var(--planr-color-chrome) 96%, transparent);
12108
12111
  }
12109
12112
  .planr-brand { min-width: 0; display: flex; align-items: center; gap: 9px; }
12110
- .planr-mark {
12111
- position: relative;
12112
- width: 20px;
12113
- height: 20px;
12114
- flex: none;
12115
- rotate: 45deg;
12116
- border: 1px solid color-mix(in srgb, var(--planr-color-primary) 70%, var(--planr-color-rule));
12117
- border-radius: var(--planr-radius-small);
12118
- }
12119
- .planr-mark::before, .planr-mark::after {
12120
- content: "";
12121
- position: absolute;
12122
- border-radius: 2px;
12123
- background: var(--planr-color-primary);
12124
- }
12125
- .planr-mark::before {
12126
- width: 4px;
12127
- height: 4px;
12128
- inset: 3px auto auto 3px;
12129
- box-shadow: 8px 8px 0 var(--planr-color-warning);
12130
- }
12131
- .planr-mark::after { width: 8px; height: 2px; inset: 9px auto auto 6px; rotate: -45deg; }
12113
+ .planr-mark { display: inline-grid; place-items: center; width: 22px; height: 22px; flex: none; color: var(--planr-color-primary); contain: paint; }
12114
+ .planr-mark svg { display: block; width: 100%; height: 100%; }
12132
12115
  .planr-title-block { min-width: 0; display: flex; align-items: baseline; gap: 8px; }
12133
12116
  .planr-title-block strong {
12134
12117
  max-width: 260px;
@@ -12887,7 +12870,7 @@ button:focus-visible, input:focus-visible, select:focus-visible, textarea:focus-
12887
12870
  text-align: center;
12888
12871
  box-shadow: 0 18px 60px color-mix(in srgb, var(--planr-color-background) 50%, transparent);
12889
12872
  }
12890
- .planr-hosted-viewer .planr-mark { display: inline-block; margin-bottom: 20px; }
12873
+ .planr-hosted-viewer .planr-mark { width: 40px; height: 40px; margin-bottom: 20px; }
12891
12874
  .planr-hosted-viewer strong { display: block; margin-bottom: 7px; font: 650 19px/1.2 var(--planr-font-display); }
12892
12875
  .planr-hosted-viewer p { margin: 0; color: var(--planr-color-text-muted); }
12893
12876
  .planr-hosted-viewer button { margin-top: 16px; border-color: var(--planr-color-primary); color: var(--planr-color-primary); }
@@ -13161,7 +13144,7 @@ function toolbar(document2) {
13161
13144
  return `<header class="planr-toolbar design-toolbar">
13162
13145
  <div class="design-toolbar-leading">
13163
13146
  ${iconButton("Screens", "left", 'data-design-toggle-nav aria-controls="design-navigator" aria-expanded="true"', "planr-toolbar-action design-panel-toggle")}
13164
- <div class="planr-brand"><span class="design-wordmark" aria-label="OpenPlanr">Open<span>Planr</span></span><span class="planr-title-block"><strong title="${escapeHtml(document2.title)}">${escapeHtml(document2.title)}</strong></span></div>
13147
+ <div class="planr-brand">${renderPlanrMark()}<span class="design-wordmark" aria-label="OpenPlanr">Open<span>Planr</span></span><span class="planr-title-block"><strong title="${escapeHtml(document2.title)}">${escapeHtml(document2.title)}</strong></span></div>
13165
13148
  </div>
13166
13149
  <div class="planr-segment design-view-picker" role="group" aria-label="Design view">${["canvas", "prototype", "walkthrough"].map((view) => iconButton(view[0].toUpperCase() + view.slice(1), view, `data-design-view="${view}" aria-pressed="${document2.defaultView === view}"`)).join("")}</div>
13167
13150
  <div class="design-toolbar-trailing">
@@ -46,7 +46,8 @@
46
46
  }
47
47
  .design-toolbar-leading, .design-toolbar-trailing { display:flex; align-items:center; gap:10px; min-width:0; }
48
48
  .design-toolbar-trailing { justify-content:flex-end; }
49
- .design-toolbar .planr-brand { display:grid; gap:3px; }
49
+ .design-toolbar .planr-brand { display:grid; grid-template-columns:auto minmax(0,1fr); grid-template-rows:auto auto; column-gap:8px; row-gap:1px; align-items:center; }
50
+ .design-toolbar .planr-brand .planr-mark { grid-row:1 / span 2; }
50
51
  .design-wordmark { font: 800 18px/1 var(--planr-font-display); letter-spacing:-.045em; white-space:nowrap; }
51
52
  .design-wordmark > span { color:var(--planr-color-primary); }
52
53
  .design-toolbar .planr-title-block strong { max-width: min(22vw, 270px); color:var(--planr-color-text-muted); font:400 10px/1.3 var(--planr-font-body); }
@@ -17,6 +17,27 @@ Use this reference only when turning natural-language intent into a Protocol 1.6
17
17
  5. Provide a useful accessible title, description, and semantic reading order.
18
18
  Keep labels concise enough to scan at the target size.
19
19
 
20
+ ## Layout heuristics
21
+
22
+ The renderer lays out deterministically; these choices decide whether the result
23
+ reads at a glance.
24
+
25
+ - Prefer `top-down` for graphs with relations. Use `left-right` for sequences
26
+ and timelines, where the flow axis is time.
27
+ - Keep fan-out to four relations per source and fan-in to four per target. Above
28
+ that, introduce an intermediate node or split the diagram.
29
+ - Keep a `balanced` render to twelve semantic nodes; use `faithful` only when the
30
+ reader needs every item and accepts a taller canvas.
31
+ - Prefer labels of one or two words. Put the explanation in the item
32
+ `description`; the studio shows it on selection.
33
+ - Use `flow` for the main path, `dependency` for "uses" or "reads", and
34
+ `transition` for a return or retry. Flow renders solid, dependency dashed.
35
+ - Add a back edge (a relation to an earlier node) only when the grammar is a
36
+ cycle by nature, such as `state-machine` or `loop-flywheel`. In `architecture`
37
+ and `flowchart` a back edge pushes its target to the bottom of the canvas.
38
+ - Use groups sparingly, at most one level, and never for the whole graph. Use
39
+ at most one annotation; more than that draws connectors across the canvas.
40
+
20
41
  Ask a question only if selecting a different answer would change the grammar,
21
42
  meaning, or audience. Infer presentation details from context and let the
22
43
  runtime validate them.
@@ -49,6 +49,17 @@ a source branch of an existing generated set; rerender its manifest with
49
49
  [fidelity guide](references/diagram-fidelity.md) when choosing an editable
50
50
  projection or explaining an omitted one.
51
51
 
52
+ ## Look before you hand over
53
+
54
+ A `pass` quality status is necessary, not sufficient. After every render, open
55
+ the PNG or SVG the command lists and check four signatures: a label that reads as
56
+ another node's caption, rectangles that overlap, a connector crossing the whole
57
+ canvas, and a node drawn below a step it precedes. Any `warning` check, in
58
+ particular `label-foreign-node`, names the first of these. When one appears,
59
+ restructure using the [layout heuristics](references/diagram-intent-to-ir.md)
60
+ (fewer relations per node, no back edge, no groups, shorter labels) and render
61
+ again before starting the studio. Report which signatures you checked.
62
+
52
63
  After a successful render or rerender, run the returned `nextAction` to start
53
64
  the native diagram studio (one SVG canvas, outline, pan/zoom, comments, and
54
65
  exports). Keep that process alive, wait for its startup
@@ -11837,11 +11837,14 @@ function activeMetadata(model) {
11837
11837
  if (!artifact) return "HTML \xB7 1440\xD7900";
11838
11838
  return `${artifact.kind.toUpperCase()} \xB7 ${artifact.viewport.width}\xD7${artifact.viewport.height}`;
11839
11839
  }
11840
+ function renderPlanrMark() {
11841
+ return '<span class="planr-mark" aria-hidden="true"><svg viewBox="0 0 160 160" focusable="false"><g transform="rotate(-45 80 80)"><path d="M125 50A52 52 0 1 0 125 110" fill="none" stroke="currentColor" stroke-width="12" stroke-linecap="round" stroke-linejoin="round"/><rect x="127" y="71" width="18" height="18" rx="3" fill="currentColor"/></g></svg></span>';
11842
+ }
11840
11843
  function renderArtifactToolbar(model) {
11841
11844
  const interact = model.reviewMode === "interact";
11842
11845
  const canvas = model.presentation === "canvas";
11843
11846
  return `<header class="planr-toolbar">
11844
- <div class="planr-brand" aria-label="OpenPlanr"><span class="planr-mark" aria-hidden="true"></span><span class="planr-title-block"><strong>${escapeHtml(model.title)}</strong>${canvas ? `<span>${escapeHtml(activeMetadata(model))}</span>` : ""}</span></div>
11847
+ <div class="planr-brand" aria-label="OpenPlanr">${renderPlanrMark()}<span class="planr-title-block"><strong>${escapeHtml(model.title)}</strong>${canvas ? `<span>${escapeHtml(activeMetadata(model))}</span>` : ""}</span></div>
11845
11848
  <span class="planr-privacy" data-privacy="${escapeHtml(model.privacy)}">${escapeHtml(model.privacyLabel)}</span>
11846
11849
  ${canvas ? ' <span class="planr-domain-toolbar" data-planr-slot="domain-toolbar" aria-label="Artifact workflow controls"></span>\n' : ""} <span class="planr-toolbar-spacer" aria-hidden="true"></span>
11847
11850
  ${canvas ? ` <div class="planr-segment" role="group" aria-label="Viewport controls"><button type="button" data-planr-action="zoom-out" aria-label="Zoom out">\u2212</button><button type="button" data-planr-action="zoom-reset" aria-label="Reset zoom">${model.zoom}%</button><button type="button" data-planr-action="zoom-in" aria-label="Zoom in">+</button></div>
@@ -11980,7 +11983,7 @@ function renderArtifactShareDialog() {
11980
11983
  }
11981
11984
  function renderHostedArtifactViewerSlot() {
11982
11985
  return `<section class="planr-hosted-viewer" data-planr-hosted-viewer data-planr-hosted-state="idle" role="status" aria-live="polite" aria-atomic="true" hidden>
11983
- <div><span class="planr-mark" aria-hidden="true"></span><strong data-planr-hosted-title></strong><p data-planr-hosted-detail></p><button type="button" data-planr-hosted-retry hidden></button></div>
11986
+ <div>${renderPlanrMark()}<strong data-planr-hosted-title></strong><p data-planr-hosted-detail></p><button type="button" data-planr-hosted-retry hidden></button></div>
11984
11987
  </section>`;
11985
11988
  }
11986
11989
  function renderArtifactShellMarkup(model) {
@@ -12107,28 +12110,8 @@ button:focus-visible, input:focus-visible, select:focus-visible, textarea:focus-
12107
12110
  background: color-mix(in srgb, var(--planr-color-chrome) 96%, transparent);
12108
12111
  }
12109
12112
  .planr-brand { min-width: 0; display: flex; align-items: center; gap: 9px; }
12110
- .planr-mark {
12111
- position: relative;
12112
- width: 20px;
12113
- height: 20px;
12114
- flex: none;
12115
- rotate: 45deg;
12116
- border: 1px solid color-mix(in srgb, var(--planr-color-primary) 70%, var(--planr-color-rule));
12117
- border-radius: var(--planr-radius-small);
12118
- }
12119
- .planr-mark::before, .planr-mark::after {
12120
- content: "";
12121
- position: absolute;
12122
- border-radius: 2px;
12123
- background: var(--planr-color-primary);
12124
- }
12125
- .planr-mark::before {
12126
- width: 4px;
12127
- height: 4px;
12128
- inset: 3px auto auto 3px;
12129
- box-shadow: 8px 8px 0 var(--planr-color-warning);
12130
- }
12131
- .planr-mark::after { width: 8px; height: 2px; inset: 9px auto auto 6px; rotate: -45deg; }
12113
+ .planr-mark { display: inline-grid; place-items: center; width: 22px; height: 22px; flex: none; color: var(--planr-color-primary); contain: paint; }
12114
+ .planr-mark svg { display: block; width: 100%; height: 100%; }
12132
12115
  .planr-title-block { min-width: 0; display: flex; align-items: baseline; gap: 8px; }
12133
12116
  .planr-title-block strong {
12134
12117
  max-width: 260px;
@@ -12887,7 +12870,7 @@ button:focus-visible, input:focus-visible, select:focus-visible, textarea:focus-
12887
12870
  text-align: center;
12888
12871
  box-shadow: 0 18px 60px color-mix(in srgb, var(--planr-color-background) 50%, transparent);
12889
12872
  }
12890
- .planr-hosted-viewer .planr-mark { display: inline-block; margin-bottom: 20px; }
12873
+ .planr-hosted-viewer .planr-mark { width: 40px; height: 40px; margin-bottom: 20px; }
12891
12874
  .planr-hosted-viewer strong { display: block; margin-bottom: 7px; font: 650 19px/1.2 var(--planr-font-display); }
12892
12875
  .planr-hosted-viewer p { margin: 0; color: var(--planr-color-text-muted); }
12893
12876
  .planr-hosted-viewer button { margin-top: 16px; border-color: var(--planr-color-primary); color: var(--planr-color-primary); }
@@ -13161,7 +13144,7 @@ function toolbar(document2) {
13161
13144
  return `<header class="planr-toolbar design-toolbar">
13162
13145
  <div class="design-toolbar-leading">
13163
13146
  ${iconButton("Screens", "left", 'data-design-toggle-nav aria-controls="design-navigator" aria-expanded="true"', "planr-toolbar-action design-panel-toggle")}
13164
- <div class="planr-brand"><span class="design-wordmark" aria-label="OpenPlanr">Open<span>Planr</span></span><span class="planr-title-block"><strong title="${escapeHtml(document2.title)}">${escapeHtml(document2.title)}</strong></span></div>
13147
+ <div class="planr-brand">${renderPlanrMark()}<span class="design-wordmark" aria-label="OpenPlanr">Open<span>Planr</span></span><span class="planr-title-block"><strong title="${escapeHtml(document2.title)}">${escapeHtml(document2.title)}</strong></span></div>
13165
13148
  </div>
13166
13149
  <div class="planr-segment design-view-picker" role="group" aria-label="Design view">${["canvas", "prototype", "walkthrough"].map((view) => iconButton(view[0].toUpperCase() + view.slice(1), view, `data-design-view="${view}" aria-pressed="${document2.defaultView === view}"`)).join("")}</div>
13167
13150
  <div class="design-toolbar-trailing">
@@ -46,7 +46,8 @@
46
46
  }
47
47
  .design-toolbar-leading, .design-toolbar-trailing { display:flex; align-items:center; gap:10px; min-width:0; }
48
48
  .design-toolbar-trailing { justify-content:flex-end; }
49
- .design-toolbar .planr-brand { display:grid; gap:3px; }
49
+ .design-toolbar .planr-brand { display:grid; grid-template-columns:auto minmax(0,1fr); grid-template-rows:auto auto; column-gap:8px; row-gap:1px; align-items:center; }
50
+ .design-toolbar .planr-brand .planr-mark { grid-row:1 / span 2; }
50
51
  .design-wordmark { font: 800 18px/1 var(--planr-font-display); letter-spacing:-.045em; white-space:nowrap; }
51
52
  .design-wordmark > span { color:var(--planr-color-primary); }
52
53
  .design-toolbar .planr-title-block strong { max-width: min(22vw, 270px); color:var(--planr-color-text-muted); font:400 10px/1.3 var(--planr-font-body); }
@@ -4,14 +4,14 @@
4
4
  "name": "AsemDevs"
5
5
  },
6
6
  "metadata": {
7
- "version": "2.2.1",
7
+ "version": "2.3.0",
8
8
  "description": "Generated local OpenPlanr package."
9
9
  },
10
10
  "plugins": [
11
11
  {
12
12
  "name": "planr",
13
13
  "source": "./openplanr",
14
- "version": "2.2.1",
14
+ "version": "2.3.0",
15
15
  "description": "Host-native OpenPlanr skills for OpenAI coding agents.",
16
16
  "strict": true
17
17
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "planr",
3
- "version": "2.2.1",
3
+ "version": "2.3.0",
4
4
  "description": "Host-native OpenPlanr planning, delivery, review, design, and operating skills.",
5
5
  "author": {
6
6
  "name": "AsemDevs"
@@ -8,7 +8,7 @@
8
8
  "files": [
9
9
  {
10
10
  "path": ".codex-plugin/plugin.json",
11
- "digest": "sha256:dc8045f946c76dc6483bf5f62f5eaf520ed2440db1dade92d4755815699c413b"
11
+ "digest": "sha256:9c69a297d5bf396b66997c3bdac8f244030a6ecbe7a77fc4ec38c3b3046122c6"
12
12
  },
13
13
  {
14
14
  "path": "skills/artifact/agents/openai.yaml",
@@ -328,7 +328,7 @@
328
328
  },
329
329
  {
330
330
  "path": "skills/design-loop/scripts/design.mjs",
331
- "digest": "sha256:c3973bd11ff96580c0e45dce24e10638f1a37590fdcfc618b21f3a4db813ec7d"
331
+ "digest": "sha256:159012cae538612641c4d142ec2fb5054278e5a17cdadf5decf33becf78533d1"
332
332
  },
333
333
  {
334
334
  "path": "skills/design-loop/scripts/runtime/notices/entities.txt",
@@ -360,7 +360,7 @@
360
360
  },
361
361
  {
362
362
  "path": "skills/design-loop/scripts/runtime/packages/design/templates/studio/studio.css",
363
- "digest": "sha256:8310b73b821764f5b1fc0fc9e0eda86f461f14ac89c683209b50b85a83f004d5"
363
+ "digest": "sha256:c7c58b1602368d8a27872c7618714b9246a6bc24fb1cb513aa6ae917c2858d1e"
364
364
  },
365
365
  {
366
366
  "path": "skills/design-loop/scripts/runtime/packages/design/templates/studio/studio.js",
@@ -500,7 +500,7 @@
500
500
  },
501
501
  {
502
502
  "path": "skills/design-review/scripts/design.mjs",
503
- "digest": "sha256:c3973bd11ff96580c0e45dce24e10638f1a37590fdcfc618b21f3a4db813ec7d"
503
+ "digest": "sha256:159012cae538612641c4d142ec2fb5054278e5a17cdadf5decf33becf78533d1"
504
504
  },
505
505
  {
506
506
  "path": "skills/design-review/scripts/runtime/notices/entities.txt",
@@ -532,7 +532,7 @@
532
532
  },
533
533
  {
534
534
  "path": "skills/design-review/scripts/runtime/packages/design/templates/studio/studio.css",
535
- "digest": "sha256:8310b73b821764f5b1fc0fc9e0eda86f461f14ac89c683209b50b85a83f004d5"
535
+ "digest": "sha256:c7c58b1602368d8a27872c7618714b9246a6bc24fb1cb513aa6ae917c2858d1e"
536
536
  },
537
537
  {
538
538
  "path": "skills/design-review/scripts/runtime/packages/design/templates/studio/studio.js",
@@ -672,7 +672,7 @@
672
672
  },
673
673
  {
674
674
  "path": "skills/design/scripts/design.mjs",
675
- "digest": "sha256:c3973bd11ff96580c0e45dce24e10638f1a37590fdcfc618b21f3a4db813ec7d"
675
+ "digest": "sha256:159012cae538612641c4d142ec2fb5054278e5a17cdadf5decf33becf78533d1"
676
676
  },
677
677
  {
678
678
  "path": "skills/design/scripts/runtime/notices/entities.txt",
@@ -704,7 +704,7 @@
704
704
  },
705
705
  {
706
706
  "path": "skills/design/scripts/runtime/packages/design/templates/studio/studio.css",
707
- "digest": "sha256:8310b73b821764f5b1fc0fc9e0eda86f461f14ac89c683209b50b85a83f004d5"
707
+ "digest": "sha256:c7c58b1602368d8a27872c7618714b9246a6bc24fb1cb513aa6ae917c2858d1e"
708
708
  },
709
709
  {
710
710
  "path": "skills/design/scripts/runtime/packages/design/templates/studio/studio.js",
@@ -792,7 +792,7 @@
792
792
  },
793
793
  {
794
794
  "path": "skills/diagram/openplanr.skill.json",
795
- "digest": "sha256:e66b2adbd7c1621d056fbd77ff24973eac57ffdc6aca04fbd6c013afc9c71b1c"
795
+ "digest": "sha256:1d8b8127914dd7a637ea475257c109a72544f860ddf5ec40c3a78563831a9906"
796
796
  },
797
797
  {
798
798
  "path": "skills/diagram/references/diagram-document.md",
@@ -804,11 +804,11 @@
804
804
  },
805
805
  {
806
806
  "path": "skills/diagram/references/diagram-intent-to-ir.md",
807
- "digest": "sha256:ce7d0107b02067c0d9fac6abe8e6a6ce8cb3f23aabcab801c6bb5a3824555c2e"
807
+ "digest": "sha256:6452ff367ad67efa0d6344fe557d3f6b432fcce06326a3dda68fe192a781006c"
808
808
  },
809
809
  {
810
810
  "path": "skills/diagram/SKILL.md",
811
- "digest": "sha256:61863f9cf08902953335355e48c7fbb18ff86e24ac0ef2693c8f697b6409db57"
811
+ "digest": "sha256:835246d34f87f0746ee927f461ebc32190679094793031a63e6fc29ddafa288d"
812
812
  },
813
813
  {
814
814
  "path": "skills/doctor/agents/openai.yaml",
@@ -928,7 +928,7 @@
928
928
  },
929
929
  {
930
930
  "path": "skills/plan/scripts/design.mjs",
931
- "digest": "sha256:c3973bd11ff96580c0e45dce24e10638f1a37590fdcfc618b21f3a4db813ec7d"
931
+ "digest": "sha256:159012cae538612641c4d142ec2fb5054278e5a17cdadf5decf33becf78533d1"
932
932
  },
933
933
  {
934
934
  "path": "skills/plan/scripts/planning-ids.mjs",
@@ -964,7 +964,7 @@
964
964
  },
965
965
  {
966
966
  "path": "skills/plan/scripts/runtime/packages/design/templates/studio/studio.css",
967
- "digest": "sha256:8310b73b821764f5b1fc0fc9e0eda86f461f14ac89c683209b50b85a83f004d5"
967
+ "digest": "sha256:c7c58b1602368d8a27872c7618714b9246a6bc24fb1cb513aa6ae917c2858d1e"
968
968
  },
969
969
  {
970
970
  "path": "skills/plan/scripts/runtime/packages/design/templates/studio/studio.js",
@@ -1171,5 +1171,5 @@
1171
1171
  "digest": "sha256:53698324b62f43b672ce8fe1654c526c96fb202e313442f09c6fc1e72268677e"
1172
1172
  }
1173
1173
  ],
1174
- "contentDigest": "sha256:9963363889925504a204561b21d636dafe00fff2da34a65a56e1c6fd04feaed6"
1174
+ "contentDigest": "sha256:7af1090afecbcaeeafff52e1a34e7472454ca38e74d65ccc1edd9ad8ac128fac"
1175
1175
  }
@@ -11837,11 +11837,14 @@ function activeMetadata(model) {
11837
11837
  if (!artifact) return "HTML \xB7 1440\xD7900";
11838
11838
  return `${artifact.kind.toUpperCase()} \xB7 ${artifact.viewport.width}\xD7${artifact.viewport.height}`;
11839
11839
  }
11840
+ function renderPlanrMark() {
11841
+ return '<span class="planr-mark" aria-hidden="true"><svg viewBox="0 0 160 160" focusable="false"><g transform="rotate(-45 80 80)"><path d="M125 50A52 52 0 1 0 125 110" fill="none" stroke="currentColor" stroke-width="12" stroke-linecap="round" stroke-linejoin="round"/><rect x="127" y="71" width="18" height="18" rx="3" fill="currentColor"/></g></svg></span>';
11842
+ }
11840
11843
  function renderArtifactToolbar(model) {
11841
11844
  const interact = model.reviewMode === "interact";
11842
11845
  const canvas = model.presentation === "canvas";
11843
11846
  return `<header class="planr-toolbar">
11844
- <div class="planr-brand" aria-label="OpenPlanr"><span class="planr-mark" aria-hidden="true"></span><span class="planr-title-block"><strong>${escapeHtml(model.title)}</strong>${canvas ? `<span>${escapeHtml(activeMetadata(model))}</span>` : ""}</span></div>
11847
+ <div class="planr-brand" aria-label="OpenPlanr">${renderPlanrMark()}<span class="planr-title-block"><strong>${escapeHtml(model.title)}</strong>${canvas ? `<span>${escapeHtml(activeMetadata(model))}</span>` : ""}</span></div>
11845
11848
  <span class="planr-privacy" data-privacy="${escapeHtml(model.privacy)}">${escapeHtml(model.privacyLabel)}</span>
11846
11849
  ${canvas ? ' <span class="planr-domain-toolbar" data-planr-slot="domain-toolbar" aria-label="Artifact workflow controls"></span>\n' : ""} <span class="planr-toolbar-spacer" aria-hidden="true"></span>
11847
11850
  ${canvas ? ` <div class="planr-segment" role="group" aria-label="Viewport controls"><button type="button" data-planr-action="zoom-out" aria-label="Zoom out">\u2212</button><button type="button" data-planr-action="zoom-reset" aria-label="Reset zoom">${model.zoom}%</button><button type="button" data-planr-action="zoom-in" aria-label="Zoom in">+</button></div>
@@ -11980,7 +11983,7 @@ function renderArtifactShareDialog() {
11980
11983
  }
11981
11984
  function renderHostedArtifactViewerSlot() {
11982
11985
  return `<section class="planr-hosted-viewer" data-planr-hosted-viewer data-planr-hosted-state="idle" role="status" aria-live="polite" aria-atomic="true" hidden>
11983
- <div><span class="planr-mark" aria-hidden="true"></span><strong data-planr-hosted-title></strong><p data-planr-hosted-detail></p><button type="button" data-planr-hosted-retry hidden></button></div>
11986
+ <div>${renderPlanrMark()}<strong data-planr-hosted-title></strong><p data-planr-hosted-detail></p><button type="button" data-planr-hosted-retry hidden></button></div>
11984
11987
  </section>`;
11985
11988
  }
11986
11989
  function renderArtifactShellMarkup(model) {
@@ -12107,28 +12110,8 @@ button:focus-visible, input:focus-visible, select:focus-visible, textarea:focus-
12107
12110
  background: color-mix(in srgb, var(--planr-color-chrome) 96%, transparent);
12108
12111
  }
12109
12112
  .planr-brand { min-width: 0; display: flex; align-items: center; gap: 9px; }
12110
- .planr-mark {
12111
- position: relative;
12112
- width: 20px;
12113
- height: 20px;
12114
- flex: none;
12115
- rotate: 45deg;
12116
- border: 1px solid color-mix(in srgb, var(--planr-color-primary) 70%, var(--planr-color-rule));
12117
- border-radius: var(--planr-radius-small);
12118
- }
12119
- .planr-mark::before, .planr-mark::after {
12120
- content: "";
12121
- position: absolute;
12122
- border-radius: 2px;
12123
- background: var(--planr-color-primary);
12124
- }
12125
- .planr-mark::before {
12126
- width: 4px;
12127
- height: 4px;
12128
- inset: 3px auto auto 3px;
12129
- box-shadow: 8px 8px 0 var(--planr-color-warning);
12130
- }
12131
- .planr-mark::after { width: 8px; height: 2px; inset: 9px auto auto 6px; rotate: -45deg; }
12113
+ .planr-mark { display: inline-grid; place-items: center; width: 22px; height: 22px; flex: none; color: var(--planr-color-primary); contain: paint; }
12114
+ .planr-mark svg { display: block; width: 100%; height: 100%; }
12132
12115
  .planr-title-block { min-width: 0; display: flex; align-items: baseline; gap: 8px; }
12133
12116
  .planr-title-block strong {
12134
12117
  max-width: 260px;
@@ -12887,7 +12870,7 @@ button:focus-visible, input:focus-visible, select:focus-visible, textarea:focus-
12887
12870
  text-align: center;
12888
12871
  box-shadow: 0 18px 60px color-mix(in srgb, var(--planr-color-background) 50%, transparent);
12889
12872
  }
12890
- .planr-hosted-viewer .planr-mark { display: inline-block; margin-bottom: 20px; }
12873
+ .planr-hosted-viewer .planr-mark { width: 40px; height: 40px; margin-bottom: 20px; }
12891
12874
  .planr-hosted-viewer strong { display: block; margin-bottom: 7px; font: 650 19px/1.2 var(--planr-font-display); }
12892
12875
  .planr-hosted-viewer p { margin: 0; color: var(--planr-color-text-muted); }
12893
12876
  .planr-hosted-viewer button { margin-top: 16px; border-color: var(--planr-color-primary); color: var(--planr-color-primary); }
@@ -13161,7 +13144,7 @@ function toolbar(document2) {
13161
13144
  return `<header class="planr-toolbar design-toolbar">
13162
13145
  <div class="design-toolbar-leading">
13163
13146
  ${iconButton("Screens", "left", 'data-design-toggle-nav aria-controls="design-navigator" aria-expanded="true"', "planr-toolbar-action design-panel-toggle")}
13164
- <div class="planr-brand"><span class="design-wordmark" aria-label="OpenPlanr">Open<span>Planr</span></span><span class="planr-title-block"><strong title="${escapeHtml(document2.title)}">${escapeHtml(document2.title)}</strong></span></div>
13147
+ <div class="planr-brand">${renderPlanrMark()}<span class="design-wordmark" aria-label="OpenPlanr">Open<span>Planr</span></span><span class="planr-title-block"><strong title="${escapeHtml(document2.title)}">${escapeHtml(document2.title)}</strong></span></div>
13165
13148
  </div>
13166
13149
  <div class="planr-segment design-view-picker" role="group" aria-label="Design view">${["canvas", "prototype", "walkthrough"].map((view) => iconButton(view[0].toUpperCase() + view.slice(1), view, `data-design-view="${view}" aria-pressed="${document2.defaultView === view}"`)).join("")}</div>
13167
13150
  <div class="design-toolbar-trailing">