@avodado/render 0.2.0 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -11,7 +11,7 @@ import { Document, BlockType, BlockDataMap } from '@avodado/core';
11
11
  * standalone HTML produced by {@link renderDocument} (or copied verbatim into
12
12
  * a static stylesheet).
13
13
  */
14
- declare const houseCss = "*{box-sizing:border-box;margin:0;padding:0;}\nhtml{scroll-behavior:smooth;}\n/* Design tokens live on :root so a theme (applied as :root overrides) reaches\n the whole page \u2014 body chrome included, not just .docskin content. */\n:root{\n /* Default = \"textbook\": warm cream paper, deep academic navy, terracotta accent,\n classic serif display + body. Bigger headings for a printed-page feel. */\n --navy:#233a5e; --navy-tint:#c4d0e2; --blue:#2f5c8f; --light-blue:#e8eef6;\n --charcoal:#211f1a; --slate:#4a463d; --gray:#8a8475; --light-gray:#f2efe6;\n --rule:#e4dccb; --highlight:#9c4a2f; --highlight-soft:#f3e4dc;\n --positive:#3f7d4e; --positive-soft:#e3efe2; --negative:#a13b2e; --negative-soft:#f4e0db;\n --purple:#5b4a8a; --purple-soft:#ebe6f3; --teal:#2f6f6a; --teal-soft:#e0eeec; --white:#fcfbf7;\n --radius:4px;\n --font-display:\"Inter\",\"SF Pro Display\",-apple-system,BlinkMacSystemFont,\"Segoe UI\",Helvetica,Arial,sans-serif;\n --font-body:\"Inter\",-apple-system,BlinkMacSystemFont,\"Segoe UI\",Helvetica,Arial,sans-serif;\n --font-mono:\"SF Mono\",ui-monospace,Menlo,Consolas,\"Courier New\",monospace;\n}\nbody{background:var(--white);color:var(--charcoal);font-family:var(--font-body);font-size:15px;line-height:1.6;}\n.docskin{\n background:var(--white); color:var(--charcoal); font-family:var(--font-body); font-size:15px; line-height:1.6;\n max-width:1180px; margin:0 auto; padding:0 56px 128px;\n}\n.docskin .cover-bar{height:8px;background:var(--navy);margin:0 -56px 36px;}\n.docskin .cover-pad{padding:0 0 40px;margin-bottom:56px;border-bottom:1px solid var(--rule);}\n.docskin .cover-meta{display:flex;justify-content:space-between;flex-wrap:wrap;gap:16px;font-size:11px;text-transform:uppercase;letter-spacing:.12em;color:var(--gray);font-weight:600;margin-bottom:32px;}\n.docskin .cover-meta .accent{color:var(--highlight);}\n.docskin .cover-title{font-family:var(--font-display);font-weight:700;font-size:clamp(40px,5.2vw,62px);line-height:1.08;letter-spacing:-.015em;color:var(--navy);margin:0 0 22px;}\n.docskin .cover-sub{font-size:19px;line-height:1.55;color:var(--slate);max-width:860px;margin:0 0 36px;}\n.docskin .section{padding:0;margin-bottom:64px;}\n.docskin .section > *:last-child{margin-bottom:0;}\n.docskin .section-num{font-size:11px;text-transform:uppercase;letter-spacing:.14em;color:var(--highlight);font-weight:700;margin-bottom:8px;}\n.docskin .section-head{margin-bottom:28px;padding-bottom:16px;border-bottom:2px solid var(--navy);}\n.docskin .section-head .section-title{border-bottom:0;padding-bottom:0;margin-bottom:14px;}\n.docskin .section-title{font-family:var(--font-display);font-weight:700;font-size:clamp(28px,3.6vw,40px);line-height:1.15;letter-spacing:-.01em;color:var(--navy);margin:0 0 14px;padding-bottom:12px;border-bottom:2px solid var(--navy);}\n.docskin .section-lede{font-size:15.5px;color:var(--slate);line-height:1.6;max-width:860px;margin:0;}\n.docskin .section-block{margin-bottom:64px;}\n.docskin .section-block:last-child{margin-bottom:0;}\n.docskin .diagram{margin:28px 0 36px;border:1px solid var(--rule);background:var(--white);padding:22px 26px 18px;border-radius:var(--radius);}\n.docskin .diagram-head{display:flex;flex-wrap:wrap;align-items:baseline;gap:10px;padding-bottom:12px;margin-bottom:16px;border-bottom:1px dashed var(--rule);}\n.docskin .diagram-tag{font-family:var(--font-mono);font-size:10px;font-weight:700;padding:3px 9px;background:var(--navy);color:var(--white);letter-spacing:.08em;text-transform:uppercase;}\n.docskin .diagram-tag.post{background:var(--navy);} .docskin .diagram-tag.get{background:var(--positive);} .docskin .diagram-tag.c4{background:var(--blue);}\n.docskin .diagram-title{font-family:var(--font-display);font-weight:700;font-size:16px;color:var(--charcoal);flex:1;}\n.docskin .diagram-fignum{font-size:10px;color:var(--gray);text-transform:uppercase;letter-spacing:.1em;font-weight:700;}\n.docskin .diagram-desc{font-size:13px;color:var(--slate);margin:0 0 12px;}\n.docskin .diagram svg{display:block;margin:0 auto;max-width:100%;height:auto;}\n/* sequence */\n.docskin .lane-head{fill:var(--navy);} .docskin .lane-head.ext{fill:var(--slate);}\n.docskin .lane-head-text{fill:var(--white);font-family:var(--font-body);font-size:12px;font-weight:700;text-anchor:middle;}\n.docskin .lane-head-sub{fill:var(--navy-tint);font-family:var(--font-mono);font-size:9px;text-anchor:middle;letter-spacing:.06em;}\n.docskin .lane-head-sub.ext{fill:#cbd5e1;}\n.docskin .lifeline{stroke:var(--gray);stroke-width:1;stroke-dasharray:3 3;}\n.docskin .activation{fill:var(--light-blue);stroke:var(--navy);stroke-width:1;} .docskin .activation.pg{fill:var(--positive-soft);stroke:var(--positive);}\n.docskin .msg-line{stroke:var(--charcoal);stroke-width:1.2;fill:none;}\n.docskin .msg-line.dashed{stroke-dasharray:5 3;} .docskin .msg-line.err{stroke:var(--negative);stroke-width:1.4;}\n.docskin .msg-text{fill:var(--charcoal);font-family:var(--font-mono);font-size:10.5px;}\n.docskin .msg-text.em{fill:var(--navy);font-weight:700;} .docskin .msg-text.err{fill:var(--negative);font-weight:700;} .docskin .msg-text.note{fill:var(--gray);font-style:italic;}\n.docskin .step-badge{fill:var(--navy);} .docskin .step-badge.err{fill:var(--negative);}\n.docskin .step-badge-text{fill:var(--white);font-family:var(--font-mono);font-size:10px;font-weight:700;text-anchor:middle;}\n.docskin .seq-steps{margin-top:16px;padding:14px 18px;background:var(--light-gray);border:1px solid var(--rule);}\n.docskin .seq-steps-title{font-size:10px;text-transform:uppercase;letter-spacing:.12em;color:var(--navy);font-weight:700;margin-bottom:8px;}\n.docskin .seq-steps ol{list-style:none;counter-reset:step;padding:0;margin:0;}\n.docskin .seq-steps li{counter-increment:step;padding:7px 0 8px 40px;position:relative;border-bottom:1px solid var(--rule);}\n.docskin .seq-steps li:last-child{border-bottom:none;}\n.docskin .seq-steps li::before{content:counter(step);position:absolute;left:0;top:7px;width:26px;height:20px;background:var(--navy);color:var(--white);font-family:var(--font-mono);font-size:11px;font-weight:700;text-align:center;line-height:20px;border-radius:2px;}\n.docskin .seq-steps li.err::before{background:var(--negative);}\n.docskin .step-actor{font-family:var(--font-mono);font-size:11px;font-weight:700;color:var(--navy);margin-right:8px;text-transform:uppercase;letter-spacing:.06em;}\n.docskin .step-actor.err{color:var(--negative);}\n.docskin .step-summary{font-size:13px;color:var(--charcoal);}\n/* c4 */\n.docskin .c4-name{font-family:var(--font-display);font-size:14px;font-weight:700;}\n.docskin .c4-tech{font-family:var(--font-mono);font-size:9.5px;}\n.docskin .c4-desc{font-family:var(--font-body);font-size:10px;}\n.docskin .c4-chip{font-family:var(--font-body);font-size:8px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;}\n.docskin .edge-label{font-family:var(--font-body);font-size:9.5px;fill:var(--slate);text-anchor:middle;}\n.docskin .edge-label.err{fill:var(--negative);font-weight:700;}\n.docskin .c4-boundary{fill:none;stroke:var(--navy);stroke-width:1.4;stroke-dasharray:8 5;}\n.docskin .c4-boundary-label{font-family:var(--font-body);font-size:10px;font-weight:700;fill:var(--navy);letter-spacing:.08em;text-transform:uppercase;}\n.docskin .legend{display:flex;flex-wrap:wrap;gap:8px 16px;margin-top:14px;padding-top:12px;border-top:1px dashed var(--rule);}\n.docskin .legend .item{display:flex;align-items:center;gap:6px;font-size:11px;color:var(--slate);}\n.docskin .legend .sw{width:13px;height:13px;border-radius:3px;}\n/* code block */\n.docskin .code-block{margin:12px 0 16px;border:1px solid var(--rule);}\n.docskin .code-header{display:flex;justify-content:space-between;padding:6px 14px;background:var(--light-gray);font-family:var(--font-mono);font-size:11px;font-weight:700;color:var(--slate);border-bottom:1px solid var(--rule);letter-spacing:.04em;}\n.docskin .code-block pre{padding:14px 16px;font-family:var(--font-mono);font-size:12px;line-height:1.55;color:var(--charcoal);overflow-x:auto;background:var(--white);white-space:pre;margin:0;}\n.docskin .code-block .kw{color:var(--navy);font-weight:700;} .docskin .code-block .com{color:var(--gray);font-style:italic;}\n.docskin .code-block .str{color:var(--positive);} .docskin .code-block .num{color:var(--purple);} .docskin .code-block .fn{color:var(--blue);} .docskin .code-block .ty{color:var(--teal);}\n/* er */\n.docskin .er-head-text{fill:var(--white);font-family:var(--font-display);font-size:13px;font-weight:700;text-anchor:middle;}\n.docskin .er-col{font-family:var(--font-mono);font-size:10.5px;fill:var(--charcoal);} .docskin .er-col.dim{fill:var(--gray);}\n.docskin .er-key{font-family:var(--font-mono);font-size:9px;font-weight:700;fill:var(--navy);} .docskin .er-key.fk{fill:var(--highlight);}\n.docskin .er-rowline{stroke:var(--light-gray);stroke-width:1;}\n/* block / state / flow shared text */\n.docskin .blk-name{font-family:var(--font-display);font-size:13px;font-weight:700;}\n.docskin .blk-tech{font-family:var(--font-mono);font-size:9.5px;}\n.docskin .blk-chip{font-family:var(--font-body);font-size:8px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;}\n.docskin .grp-label{font-family:var(--font-body);font-size:10px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;}\n.docskin .sm-name{font-family:var(--font-display);font-size:13px;font-weight:700;text-anchor:middle;}\n.docskin .fc-label{font-family:var(--font-display);font-size:12px;font-weight:700;text-anchor:middle;}\n.docskin .endpoint-card{border:1px solid var(--rule);margin:16px 0;padding:18px 22px;background:var(--white);}\n.docskin .endpoint-header{display:flex;align-items:center;gap:12px;margin-bottom:10px;padding-bottom:10px;border-bottom:1px dashed var(--rule);}\n.docskin .endpoint-method{font-family:var(--font-mono);font-size:11px;font-weight:700;padding:4px 10px;color:var(--white);letter-spacing:.08em;text-transform:uppercase;}\n.docskin .endpoint-method.get{background:var(--positive);} .docskin .endpoint-method.post{background:var(--navy);} .docskin .endpoint-method.patch{background:var(--highlight);} .docskin .endpoint-method.delete{background:var(--negative);} .docskin .endpoint-method.put{background:var(--blue);}\n.docskin .endpoint-path{font-family:var(--font-mono);font-size:15px;font-weight:700;color:var(--charcoal);flex:1;}\n.docskin .endpoint-status{font-family:var(--font-mono);font-size:11.5px;color:var(--positive);font-weight:700;}\n.docskin .endpoint-desc{font-size:13px;color:var(--slate);margin:0 0 8px;}\n.docskin .endpoint-card h4{font-size:11px;text-transform:uppercase;letter-spacing:.12em;font-weight:700;color:var(--highlight);margin:14px 0 6px;}\n.docskin .endpoint-card ul{margin:0 0 0 20px;} .docskin .endpoint-card li{font-size:13px;margin-bottom:3px;}\n.docskin code{font-family:var(--font-mono);font-size:.86em;background:var(--light-gray);padding:2px 6px;border-radius:2px;border:1px solid var(--rule);}\n.docskin .transition-table{width:100%;border-collapse:collapse;margin:16px 0 8px;font-size:12px;}\n.docskin .transition-table thead{background:var(--navy);color:#fff;}\n.docskin .transition-table th{text-align:left;padding:8px 10px;font-size:9.5px;text-transform:uppercase;letter-spacing:.1em;}\n.docskin .transition-table td{padding:8px 10px;border-bottom:1px solid var(--rule);vertical-align:top;}\n.docskin .pill{display:inline-block;font-family:var(--font-mono);font-size:10px;font-weight:700;padding:2px 7px;border-radius:2px;text-transform:uppercase;}\n.docskin .pill-init{background:var(--light-gray);color:var(--slate);border:1px solid var(--rule);}\n.docskin .pill-active{background:var(--positive-soft);color:var(--positive);border:1px solid var(--positive);}\n.docskin .pill-wait{background:var(--highlight-soft);color:var(--highlight);border:1px solid var(--highlight);}\n.docskin .pill-end{background:var(--charcoal);color:#fff;}\n/* presentation: comparison table */\n.docskin .pres-table{width:100%;border-collapse:collapse;margin:14px 0;font-size:13px;}\n.docskin .pres-table thead{background:var(--navy);color:#fff;}\n.docskin .pres-table th{padding:9px 12px;text-align:left;font-family:var(--font-body);font-size:10.5px;text-transform:uppercase;letter-spacing:.08em;font-weight:700;}\n.docskin .pres-table th.r,.docskin .pres-table td.r{text-align:right;} .docskin .pres-table th.c,.docskin .pres-table td.c{text-align:center;}\n.docskin .pres-table th.hi{background:var(--highlight);}\n.docskin .pres-table td{padding:9px 12px;border-bottom:1px solid var(--rule);}\n.docskin .pres-table tbody tr:nth-child(even){background:var(--light-gray);}\n.docskin .pres-table td.lead{font-weight:700;color:var(--navy);font-family:var(--font-display);}\n.docskin .pres-table td.hi{background:var(--highlight-soft);}\n.docskin .cell-pos{color:var(--positive);font-weight:700;} .docskin .cell-neg{color:var(--negative);font-weight:700;} .docskin .cell-warn{color:var(--highlight);font-weight:700;} .docskin .cell-muted{color:var(--gray);}\n.docskin .badge{display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;border-radius:50%;font-size:12px;font-weight:700;}\n.docskin .badge.yes{background:var(--positive-soft);color:var(--positive);} .docskin .badge.no{background:var(--negative-soft);color:var(--negative);}\n.docskin .tbl-note{font-size:11px;color:var(--gray);font-style:italic;margin-top:6px;}\n/* presentation: stat cards */\n.docskin .stat-row{display:flex;flex-wrap:wrap;gap:14px;margin:16px 0;}\n.docskin .stat-card{flex:1 1 150px;border:1px solid var(--rule);border-top:3px solid var(--navy);padding:16px 18px;background:var(--white);}\n.docskin .stat-value{font-family:var(--font-display);font-size:30px;font-weight:700;color:var(--navy);line-height:1;}\n.docskin .stat-label{font-size:10.5px;text-transform:uppercase;letter-spacing:.1em;color:var(--gray);font-weight:700;margin-top:8px;}\n.docskin .stat-delta{font-family:var(--font-mono);font-size:12px;font-weight:700;margin-top:6px;}\n.docskin .stat-delta.up{color:var(--positive);} .docskin .stat-delta.down{color:var(--negative);} .docskin .stat-delta.flat{color:var(--gray);}\n/* presentation: timeline */\n.docskin .tl{position:relative;margin:18px 0;padding-left:8px;}\n.docskin .tl::before{content:\"\";position:absolute;left:9px;top:6px;bottom:6px;width:2px;background:var(--rule);}\n.docskin .tl-item{position:relative;padding:0 0 18px 30px;}\n.docskin .tl-item:last-child{padding-bottom:0;}\n.docskin .tl-dot{position:absolute;left:2px;top:2px;width:16px;height:16px;border-radius:50%;background:var(--white);border:3px solid var(--rule);box-sizing:border-box;}\n.docskin .tl-dot.done{background:var(--positive);border-color:var(--positive);} .docskin .tl-dot.current{background:var(--highlight);border-color:var(--highlight);} .docskin .tl-dot.next{border-color:var(--navy);}\n.docskin .tl-date{font-family:var(--font-mono);font-size:10.5px;font-weight:700;color:var(--highlight);text-transform:uppercase;letter-spacing:.06em;}\n.docskin .tl-label{font-family:var(--font-display);font-size:15px;font-weight:700;color:var(--navy);margin:1px 0 2px;}\n.docskin .tl-desc{font-size:12.5px;color:var(--slate);}\n/* presentation: quadrant */\n.docskin .quad-axis{stroke:var(--charcoal);stroke-width:1.5;}\n.docskin .quad-end{font-family:var(--font-body);font-size:10px;font-weight:700;fill:var(--gray);text-transform:uppercase;letter-spacing:.06em;}\n.docskin .quad-title{font-family:var(--font-body);font-size:11px;font-weight:700;fill:var(--navy);text-transform:uppercase;letter-spacing:.08em;}\n.docskin .quad-pt-label{font-family:var(--font-body);font-size:11px;font-weight:700;fill:var(--charcoal);}\n.docskin .toc{margin:18px 0 6px;padding:14px 20px;background:var(--light-gray);border:1px solid var(--rule);border-left:4px solid var(--highlight);}\n.docskin .toc-title{font-size:10px;text-transform:uppercase;letter-spacing:.12em;color:var(--navy);font-weight:700;margin-bottom:8px;}\n.docskin .toc ol{margin:0;padding-left:20px;} .docskin .toc li{font-size:13px;margin-bottom:4px;color:var(--slate);}\n.docskin .toc li span{color:var(--gray);font-family:var(--font-mono);font-size:11px;}\n/* swimlane */\n.docskin .sl-lane-label{font-family:var(--font-display);font-size:12px;font-weight:700;fill:#fff;}\n.docskin .sl-step{font-family:var(--font-body);font-size:11px;font-weight:700;text-anchor:middle;}\n/* callouts */\n.docskin .callout{border:1px solid var(--rule);border-left:4px solid var(--navy);padding:12px 16px;margin:10px 0;}\n.docskin .callout.note{border-left-color:var(--navy);background:var(--light-blue);} .docskin .callout.tip{border-left-color:var(--positive);background:var(--positive-soft);} .docskin .callout.warn{border-left-color:var(--highlight);background:var(--highlight-soft);} .docskin .callout.danger{border-left-color:var(--negative);background:var(--negative-soft);}\n.docskin .callout-title{font-size:10.5px;text-transform:uppercase;letter-spacing:.1em;font-weight:700;margin-bottom:4px;}\n.docskin .callout.note .callout-title{color:var(--navy);} .docskin .callout.tip .callout-title{color:var(--positive);} .docskin .callout.warn .callout-title{color:#b45309;} .docskin .callout.danger .callout-title{color:var(--negative);}\n.docskin .callout-body{font-size:13px;color:var(--slate);}\n/* prose */\n.docskin .prose h2{font-family:var(--font-display);font-weight:700;font-size:clamp(24px,3vw,32px);line-height:1.15;letter-spacing:-.015em;color:var(--navy);margin:40px 0 14px;padding-bottom:12px;border-bottom:2px solid var(--navy);}\n.docskin .prose h2:first-child{margin-top:0;}\n.docskin .prose h3{font-family:var(--font-display);font-weight:700;font-size:19px;letter-spacing:-.005em;color:var(--navy);margin:36px 0 12px;}\n.docskin .prose h4{font-size:11px;text-transform:uppercase;letter-spacing:.12em;font-weight:700;color:var(--highlight);margin:22px 0 8px;}\n.docskin .prose p{font-size:14px;color:var(--charcoal);margin:0 0 14px;line-height:1.6;max-width:880px;}\n.docskin .prose ul,.docskin .prose ol{margin:0 0 14px 22px;}\n.docskin .prose li{font-size:13.5px;color:var(--charcoal);margin-bottom:4px;max-width:880px;line-height:1.55;}\n.docskin .prose blockquote{border-left:3px solid var(--highlight);padding:4px 14px;margin:14px 0;color:var(--slate);font-style:italic;font-family:var(--font-display);}\n.docskin .prose code{font-family:var(--font-mono);font-size:.86em;background:var(--light-gray);padding:2px 6px;border-radius:2px;color:var(--charcoal);border:1px solid var(--rule);}\n.docskin .prose strong{font-weight:700;color:var(--charcoal);}\n.docskin .prose em{font-style:italic;}\n/* glossary */\n.docskin .glossary{margin:10px 0;}\n.docskin .glossary .row{display:grid;grid-template-columns:170px 1fr;gap:14px;padding:9px 0;border-bottom:1px solid var(--rule);}\n.docskin .glossary dt{font-family:var(--font-mono);font-size:13px;font-weight:700;color:var(--navy);}\n.docskin .glossary dd{margin:0;font-size:13px;color:var(--slate);}\n/* pros / cons */\n.docskin .pc{display:grid;grid-template-columns:1fr 1fr;gap:16px;margin:12px 0;}\n.docskin .pc-col{border:1px solid var(--rule);padding:14px 16px;}\n.docskin .pc-col.pro{border-top:3px solid var(--positive);} .docskin .pc-col.con{border-top:3px solid var(--negative);}\n.docskin .pc-head{font-size:11px;text-transform:uppercase;letter-spacing:.1em;font-weight:700;margin-bottom:8px;}\n.docskin .pc-col.pro .pc-head{color:var(--positive);} .docskin .pc-col.con .pc-head{color:var(--negative);}\n.docskin .pc-item{font-size:13px;color:var(--slate);padding:4px 0 4px 22px;position:relative;}\n.docskin .pc-item::before{position:absolute;left:0;top:4px;font-weight:700;}\n.docskin .pc-col.pro .pc-item::before{content:\"\\2713\";color:var(--positive);} .docskin .pc-col.con .pc-item::before{content:\"\\2717\";color:var(--negative);}\n/* current / target */\n.docskin .ct{display:flex;align-items:stretch;margin:12px 0;}\n.docskin .ct-panel{flex:1;border:1px solid var(--rule);padding:14px 18px;}\n.docskin .ct-panel.cur{background:var(--light-gray);} .docskin .ct-panel.tgt{border-top:3px solid var(--navy);}\n.docskin .ct-arrow{display:flex;align-items:center;padding:0 14px;color:var(--highlight);font-size:22px;font-weight:700;}\n.docskin .ct-label{font-size:11px;text-transform:uppercase;letter-spacing:.1em;font-weight:700;color:var(--gray);margin-bottom:8px;}\n.docskin .ct-panel.tgt .ct-label{color:var(--navy);}\n.docskin .ct-item{font-size:13px;color:var(--slate);padding:3px 0;}\n/* kanban */\n.docskin .kanban{display:flex;gap:14px;margin:12px 0;overflow-x:auto;}\n.docskin .kan-col{flex:1 1 0;min-width:150px;background:var(--light-gray);border:1px solid var(--rule);}\n.docskin .kan-head{background:var(--navy);color:#fff;font-size:11px;text-transform:uppercase;letter-spacing:.08em;font-weight:700;padding:8px 12px;}\n.docskin .kan-card{background:var(--white);border:1px solid var(--rule);border-left:3px solid var(--highlight);margin:8px;padding:9px 11px;}\n.docskin .kan-card-title{font-size:13px;font-weight:700;color:var(--charcoal);}\n.docskin .kan-card-tag{display:inline-block;font-family:var(--font-mono);font-size:9px;font-weight:700;text-transform:uppercase;letter-spacing:.06em;color:var(--gray);margin-top:4px;}\n/* pass 2 chart labels */\n.docskin .dfd-name{font-family:var(--font-display);font-size:12px;font-weight:700;text-anchor:middle;}\n.docskin .dfd-num{font-family:var(--font-mono);font-size:9px;font-weight:700;}\n.docskin .gantt-label{font-family:var(--font-body);font-size:11px;fill:var(--charcoal);}\n.docskin .gantt-head{font-family:var(--font-mono);font-size:9.5px;fill:var(--gray);text-anchor:middle;}\n.docskin .funnel-label{font-family:var(--font-display);font-size:13px;font-weight:700;fill:#fff;text-anchor:middle;}\n.docskin .funnel-val{font-family:var(--font-mono);font-size:11px;fill:#fff;text-anchor:middle;opacity:.9;}\n.docskin .pyr-label{font-family:var(--font-display);font-size:13px;font-weight:700;fill:#fff;text-anchor:middle;}\n.docskin .pyr-desc{font-family:var(--font-body);font-size:10px;fill:#fff;text-anchor:middle;opacity:.85;}\n/* indented tree */\n.docskin .tree-list{margin:10px 0;font-size:13px;}\n.docskin .tree-row{display:flex;align-items:baseline;padding:3px 0;}\n.docskin .tree-row .tw{color:var(--gray);margin-right:8px;font-family:var(--font-mono);font-size:11px;}\n.docskin .tree-row.branch .tw{color:var(--navy);}\n.docskin .tree-row .tlabel{color:var(--charcoal);font-family:var(--font-mono);}\n.docskin .tree-row.branch .tlabel{font-weight:700;color:var(--navy);}\n.docskin .tree-row .tnote{color:var(--gray);font-size:11px;margin-left:10px;font-family:var(--font-body);font-style:italic;}\n/* agenda */\n.docskin .agenda{margin:10px 0;}\n.docskin .agenda-row{display:grid;grid-template-columns:88px 1fr;gap:14px;padding:10px 0;border-bottom:1px solid var(--rule);}\n.docskin .agenda-time{font-family:var(--font-mono);font-size:12px;font-weight:700;color:var(--navy);}\n.docskin .agenda-dur{font-family:var(--font-mono);font-size:10px;color:var(--gray);margin-top:2px;}\n.docskin .agenda-title{font-family:var(--font-display);font-size:14px;font-weight:700;color:var(--charcoal);}\n.docskin .agenda-owner{font-size:10.5px;color:var(--highlight);font-weight:700;text-transform:uppercase;letter-spacing:.05em;margin-left:8px;}\n.docskin .agenda-desc{font-size:12.5px;color:var(--slate);margin-top:2px;}\n/* tracker */\n.docskin .trk{width:100%;border-collapse:collapse;margin:12px 0;font-size:13px;}\n.docskin .trk thead{background:var(--navy);color:#fff;} .docskin .trk th{padding:8px 10px;text-align:left;font-size:9.5px;text-transform:uppercase;letter-spacing:.08em;font-weight:700;}\n.docskin .trk td{padding:8px 10px;border-bottom:1px solid var(--rule);vertical-align:middle;}\n.docskin .trk tr.done .trk-task{text-decoration:line-through;color:var(--gray);}\n.docskin .st{display:inline-block;font-family:var(--font-mono);font-size:9.5px;font-weight:700;padding:2px 8px;border-radius:10px;text-transform:uppercase;letter-spacing:.04em;}\n.docskin .st.todo{background:var(--light-gray);color:var(--slate);border:1px solid var(--rule);} .docskin .st.doing{background:var(--highlight-soft);color:#b45309;} .docskin .st.done{background:var(--positive-soft);color:var(--positive);} .docskin .st.blocked{background:var(--negative-soft);color:var(--negative);}\n.docskin .pri{font-family:var(--font-mono);font-size:10px;font-weight:700;} .docskin .pri.high{color:var(--negative);} .docskin .pri.med{color:var(--highlight);} .docskin .pri.low{color:var(--gray);}\n/* cluster */\n.docskin .cl-head{font-family:var(--font-display);font-size:13px;font-weight:700;fill:#fff;}\n.docskin .cl-kind{font-family:var(--font-mono);font-size:9px;fill:#cfe0f3;text-anchor:end;text-transform:uppercase;letter-spacing:.06em;}\n/* user story */\n.docskin .story{border:1px solid var(--rule);border-left:4px solid var(--navy);padding:18px 22px;margin:12px 0;background:var(--white);}\n.docskin .story-stmt{font-family:var(--font-display);font-size:18px;line-height:1.55;color:var(--charcoal);}\n.docskin .story-stmt b{color:var(--navy);}\n.docskin .story-meta{display:flex;gap:8px;margin-top:12px;flex-wrap:wrap;}\n.docskin .story-chip{font-family:var(--font-mono);font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.05em;padding:3px 9px;border-radius:3px;background:var(--light-gray);color:var(--slate);border:1px solid var(--rule);}\n.docskin .ac-title{font-size:10.5px;text-transform:uppercase;letter-spacing:.12em;color:var(--highlight);font-weight:700;margin:16px 0 8px;}\n.docskin .ac-item{border:1px solid var(--rule);padding:10px 14px;margin-bottom:8px;background:var(--white);}\n.docskin .gwt{display:grid;grid-template-columns:60px 1fr;gap:4px 12px;font-size:13px;}\n.docskin .gwt .k{font-family:var(--font-mono);font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.06em;padding-top:1px;}\n.docskin .gwt .k.g{color:var(--positive);} .docskin .gwt .k.w{color:var(--navy);} .docskin .gwt .k.t{color:var(--highlight);}\n.docskin .gwt .v{color:var(--charcoal);}\n.docskin .links-row{display:flex;gap:8px;flex-wrap:wrap;}\n.docskin .link-chip{display:inline-flex;align-items:center;gap:6px;font-size:12px;font-weight:700;color:var(--navy);border:1px solid var(--navy);background:var(--white);padding:5px 11px;border-radius:20px;cursor:pointer;}\n.docskin .link-chip .lt{color:var(--gray);font-family:var(--font-mono);font-size:9px;text-transform:uppercase;letter-spacing:.06em;}\n.docskin .footer{margin-top:8px;padding:18px 32px 28px;border-top:2px solid var(--navy);font-size:11px;color:var(--gray);text-transform:uppercase;letter-spacing:.1em;font-weight:700;display:flex;justify-content:space-between;flex-wrap:wrap;gap:10px;}\n.docskin .footer .accent{color:var(--highlight);}\n.docskin .layer-label{font-family:var(--font-display);font-size:13px;font-weight:700;fill:#fff;}\n.docskin .uml-name{font-family:var(--font-display);font-size:13px;font-weight:700;text-anchor:middle;fill:#0a3a6e;}\n.docskin .uml-stereo{font-family:var(--font-body);font-size:9px;font-style:italic;text-anchor:middle;fill:#6b7280;}\n.docskin .uml-row{font-family:var(--font-mono);font-size:10.5px;fill:var(--charcoal);}\n.docskin .uml-sep{stroke:#0e54a1;stroke-width:1;}\n.docskin .ft-note{font-family:var(--font-mono);font-size:9px;}\n.docskin .tree-link{stroke:#9ca3af;stroke-width:1.3;fill:none;}\n/* wireframe / UI mockups */\n.docskin .wf-h{font-family:var(--font-display);font-size:18px;font-weight:700;}\n.docskin .wf-sub{font-family:var(--font-body);font-size:12px;font-weight:600;}\n.docskin .wf-btn{font-family:var(--font-body);font-size:11px;font-weight:700;fill:#fff;}\n.docskin .wf-ph-text{font-family:var(--font-body);font-size:10px;fill:var(--gray);}\n.docskin .wf-status{font-family:var(--font-mono);font-size:9px;fill:var(--charcoal);font-weight:700;}\n.docskin .wf-url{font-family:var(--font-mono);font-size:8.5px;fill:var(--gray);}\n.docskin .wf-tab{font-family:var(--font-body);font-size:8px;}\n.docskin .wf-caption{font-family:var(--font-mono);font-size:10px;fill:var(--gray);letter-spacing:.04em;}\n/* parse error */\n.docskin .err{font-family:var(--font-mono);font-size:12px;color:var(--negative);background:#fdf2f2;border:1px solid #f3c9c9;padding:8px 12px;margin:12px 0;white-space:pre-wrap;}";
14
+ declare const houseCss = "*{box-sizing:border-box;margin:0;padding:0;}\nhtml{scroll-behavior:smooth;}\n/* Design tokens live on :root so a theme (applied as :root overrides) reaches\n the whole page \u2014 body chrome included, not just .docskin content. */\n:root{\n /* Default = \"textbook\": warm cream paper, deep academic navy, terracotta accent,\n classic serif display + body. Bigger headings for a printed-page feel. */\n --navy:#233a5e; --navy-tint:#c4d0e2; --blue:#2f5c8f; --light-blue:#e8eef6;\n --charcoal:#211f1a; --slate:#4a463d; --gray:#8a8475; --light-gray:#f2efe6;\n --rule:#e4dccb; --highlight:#9c4a2f; --highlight-soft:#f3e4dc;\n --positive:#3f7d4e; --positive-soft:#e3efe2; --negative:#a13b2e; --negative-soft:#f4e0db;\n --purple:#5b4a8a; --purple-soft:#ebe6f3; --teal:#2f6f6a; --teal-soft:#e0eeec; --white:#fcfbf7;\n --radius:4px;\n --font-display:\"Inter\",\"SF Pro Display\",-apple-system,BlinkMacSystemFont,\"Segoe UI\",Helvetica,Arial,sans-serif;\n --font-body:\"Inter\",-apple-system,BlinkMacSystemFont,\"Segoe UI\",Helvetica,Arial,sans-serif;\n --font-mono:\"SF Mono\",ui-monospace,Menlo,Consolas,\"Courier New\",monospace;\n}\nbody{background:var(--white);color:var(--charcoal);font-family:var(--font-body);font-size:15px;line-height:1.6;}\n.docskin{\n background:var(--white); color:var(--charcoal); font-family:var(--font-body); font-size:15px; line-height:1.6;\n max-width:1180px; margin:0 auto; padding:0 56px 128px;\n}\n.docskin .cover-bar{height:8px;background:var(--navy);margin:0 -56px 36px;}\n.docskin .cover-pad{padding:0 0 40px;margin-bottom:56px;border-bottom:1px solid var(--rule);}\n.docskin .cover-meta{display:flex;justify-content:space-between;flex-wrap:wrap;gap:16px;font-size:11px;text-transform:uppercase;letter-spacing:.12em;color:var(--gray);font-weight:600;margin-bottom:32px;}\n.docskin .cover-meta .accent{color:var(--highlight);}\n.docskin .cover-title{font-family:var(--font-display);font-weight:700;font-size:clamp(40px,5.2vw,62px);line-height:1.08;letter-spacing:-.015em;color:var(--navy);margin:0 0 22px;}\n.docskin .cover-sub{font-size:19px;line-height:1.55;color:var(--slate);max-width:860px;margin:0 0 36px;}\n.docskin .section{padding:0;margin-bottom:64px;}\n.docskin .section > *:last-child{margin-bottom:0;}\n.docskin .section-num{font-size:11px;text-transform:uppercase;letter-spacing:.14em;color:var(--highlight);font-weight:700;margin-bottom:8px;}\n.docskin .section-head{margin-bottom:28px;padding-bottom:16px;border-bottom:2px solid var(--navy);}\n.docskin .section-head .section-title{border-bottom:0;padding-bottom:0;margin-bottom:14px;}\n.docskin .section-title{font-family:var(--font-display);font-weight:700;font-size:clamp(28px,3.6vw,40px);line-height:1.15;letter-spacing:-.01em;color:var(--navy);margin:0 0 14px;padding-bottom:12px;border-bottom:2px solid var(--navy);}\n.docskin .section-lede{font-size:15.5px;color:var(--slate);line-height:1.6;max-width:860px;margin:0;}\n.docskin .section-block{margin-bottom:64px;}\n.docskin .section-block:last-child{margin-bottom:0;}\n.docskin .diagram{margin:28px 0 36px;border:1px solid var(--rule);background:var(--white);padding:22px 26px 18px;border-radius:var(--radius);}\n.docskin .diagram-head{display:flex;flex-wrap:wrap;align-items:baseline;gap:10px;padding-bottom:12px;margin-bottom:16px;border-bottom:1px dashed var(--rule);}\n.docskin .diagram-tag{font-family:var(--font-mono);font-size:10px;font-weight:700;padding:3px 9px;background:var(--navy);color:var(--white);letter-spacing:.08em;text-transform:uppercase;}\n.docskin .diagram-tag.post{background:var(--navy);} .docskin .diagram-tag.get{background:var(--positive);} .docskin .diagram-tag.c4{background:var(--blue);}\n.docskin .diagram-title{font-family:var(--font-display);font-weight:700;font-size:16px;color:var(--charcoal);flex:1;}\n.docskin .diagram-fignum{font-size:10px;color:var(--gray);text-transform:uppercase;letter-spacing:.1em;font-weight:700;}\n.docskin .diagram-desc{font-size:13px;color:var(--slate);margin:0 0 12px;}\n.docskin .diagram svg{display:block;margin:0 auto;max-width:100%;height:auto;}\n/* sequence */\n.docskin .lane-head{fill:var(--navy);} .docskin .lane-head.ext{fill:var(--slate);}\n.docskin .lane-head-text{fill:var(--white);font-family:var(--font-body);font-size:12px;font-weight:700;text-anchor:middle;}\n.docskin .lane-head-sub{fill:var(--navy-tint);font-family:var(--font-mono);font-size:9px;text-anchor:middle;letter-spacing:.06em;}\n.docskin .lane-head-sub.ext{fill:#cbd5e1;}\n.docskin .lifeline{stroke:var(--gray);stroke-width:1;stroke-dasharray:3 3;}\n.docskin .activation{fill:var(--light-blue);stroke:var(--navy);stroke-width:1;} .docskin .activation.pg{fill:var(--positive-soft);stroke:var(--positive);}\n.docskin .msg-line{stroke:var(--charcoal);stroke-width:1.2;fill:none;}\n.docskin .msg-line.dashed{stroke-dasharray:5 3;} .docskin .msg-line.err{stroke:var(--negative);stroke-width:1.4;}\n.docskin .msg-text{fill:var(--charcoal);font-family:var(--font-mono);font-size:10.5px;}\n.docskin .msg-text.em{fill:var(--navy);font-weight:700;} .docskin .msg-text.err{fill:var(--negative);font-weight:700;} .docskin .msg-text.note{fill:var(--gray);font-style:italic;}\n.docskin .step-badge{fill:var(--navy);} .docskin .step-badge.err{fill:var(--negative);}\n.docskin .step-badge-text{fill:var(--white);font-family:var(--font-mono);font-size:10px;font-weight:700;text-anchor:middle;}\n.docskin .seq-steps{margin-top:16px;padding:14px 18px;background:var(--light-gray);border:1px solid var(--rule);}\n.docskin .seq-steps-title{font-size:10px;text-transform:uppercase;letter-spacing:.12em;color:var(--navy);font-weight:700;margin-bottom:8px;}\n.docskin .seq-steps ol{list-style:none;counter-reset:step;padding:0;margin:0;}\n.docskin .seq-steps li{counter-increment:step;padding:7px 0 8px 40px;position:relative;border-bottom:1px solid var(--rule);}\n.docskin .seq-steps li:last-child{border-bottom:none;}\n.docskin .seq-steps li::before{content:counter(step);position:absolute;left:0;top:7px;width:26px;height:20px;background:var(--navy);color:var(--white);font-family:var(--font-mono);font-size:11px;font-weight:700;text-align:center;line-height:20px;border-radius:2px;}\n.docskin .seq-steps li.err::before{background:var(--negative);}\n.docskin .step-actor{font-family:var(--font-mono);font-size:11px;font-weight:700;color:var(--navy);margin-right:8px;text-transform:uppercase;letter-spacing:.06em;}\n.docskin .step-actor.err{color:var(--negative);}\n.docskin .step-summary{font-size:13px;color:var(--charcoal);}\n/* c4 */\n.docskin .c4-name{font-family:var(--font-display);font-size:14px;font-weight:700;}\n.docskin .c4-tech{font-family:var(--font-mono);font-size:9.5px;}\n.docskin .c4-desc{font-family:var(--font-body);font-size:10px;}\n.docskin .c4-chip{font-family:var(--font-body);font-size:8px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;}\n.docskin .edge-label{font-family:var(--font-body);font-size:9.5px;fill:var(--slate);text-anchor:middle;}\n.docskin .edge-label.err{fill:var(--negative);font-weight:700;}\n.docskin .c4-boundary{fill:none;stroke:var(--navy);stroke-width:1.4;stroke-dasharray:8 5;}\n.docskin .c4-boundary-label{font-family:var(--font-body);font-size:10px;font-weight:700;fill:var(--navy);letter-spacing:.08em;text-transform:uppercase;}\n.docskin .legend{display:flex;flex-wrap:wrap;gap:8px 16px;margin-top:14px;padding-top:12px;border-top:1px dashed var(--rule);}\n.docskin .legend .item{display:flex;align-items:center;gap:6px;font-size:11px;color:var(--slate);}\n.docskin .legend .sw{width:13px;height:13px;border-radius:3px;}\n/* code block */\n.docskin .code-block{margin:12px 0 16px;border:1px solid var(--rule);}\n.docskin .code-header{display:flex;justify-content:space-between;padding:6px 14px;background:var(--light-gray);font-family:var(--font-mono);font-size:11px;font-weight:700;color:var(--slate);border-bottom:1px solid var(--rule);letter-spacing:.04em;}\n.docskin .code-block pre{padding:14px 16px;font-family:var(--font-mono);font-size:12px;line-height:1.55;color:var(--charcoal);overflow-x:auto;background:var(--white);white-space:pre;margin:0;}\n.docskin .code-block .kw{color:var(--navy);font-weight:700;} .docskin .code-block .com{color:var(--gray);font-style:italic;}\n.docskin .code-block .str{color:var(--positive);} .docskin .code-block .num{color:var(--purple);} .docskin .code-block .fn{color:var(--blue);} .docskin .code-block .ty{color:var(--teal);}\n/* er */\n.docskin .er-head-text{fill:var(--white);font-family:var(--font-display);font-size:13px;font-weight:700;text-anchor:middle;}\n.docskin .er-col{font-family:var(--font-mono);font-size:10.5px;fill:var(--charcoal);} .docskin .er-col.dim{fill:var(--gray);}\n.docskin .er-key{font-family:var(--font-mono);font-size:9px;font-weight:700;fill:var(--navy);} .docskin .er-key.fk{fill:var(--highlight);}\n.docskin .er-rowline{stroke:var(--light-gray);stroke-width:1;}\n/* block / state / flow shared text */\n.docskin .blk-name{font-family:var(--font-display);font-size:13px;font-weight:700;}\n.docskin .blk-tech{font-family:var(--font-mono);font-size:9.5px;}\n.docskin .blk-chip{font-family:var(--font-body);font-size:8px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;}\n.docskin .grp-label{font-family:var(--font-body);font-size:10px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;}\n.docskin .sm-name{font-family:var(--font-display);font-size:13px;font-weight:700;text-anchor:middle;}\n.docskin .fc-label{font-family:var(--font-display);font-size:12px;font-weight:700;text-anchor:middle;}\n.docskin .endpoint-card{border:1px solid var(--rule);margin:16px 0;padding:18px 22px;background:var(--white);}\n.docskin .endpoint-header{display:flex;align-items:center;gap:12px;margin-bottom:10px;padding-bottom:10px;border-bottom:1px dashed var(--rule);}\n.docskin .endpoint-method{font-family:var(--font-mono);font-size:11px;font-weight:700;padding:4px 10px;color:var(--white);letter-spacing:.08em;text-transform:uppercase;}\n.docskin .endpoint-method.get{background:var(--positive);} .docskin .endpoint-method.post{background:var(--navy);} .docskin .endpoint-method.patch{background:var(--highlight);} .docskin .endpoint-method.delete{background:var(--negative);} .docskin .endpoint-method.put{background:var(--blue);}\n.docskin .endpoint-path{font-family:var(--font-mono);font-size:15px;font-weight:700;color:var(--charcoal);flex:1;}\n.docskin .endpoint-status{font-family:var(--font-mono);font-size:11.5px;color:var(--positive);font-weight:700;}\n.docskin .endpoint-desc{font-size:13px;color:var(--slate);margin:0 0 8px;}\n.docskin .endpoint-card h4{font-size:11px;text-transform:uppercase;letter-spacing:.12em;font-weight:700;color:var(--highlight);margin:14px 0 6px;}\n.docskin .endpoint-card ul{margin:0 0 0 20px;} .docskin .endpoint-card li{font-size:13px;margin-bottom:3px;}\n.docskin code{font-family:var(--font-mono);font-size:.86em;background:var(--light-gray);padding:2px 6px;border-radius:2px;border:1px solid var(--rule);}\n.docskin .transition-table{width:100%;border-collapse:collapse;margin:16px 0 8px;font-size:12px;}\n.docskin .transition-table thead{background:var(--navy);color:#fff;}\n.docskin .transition-table th{text-align:left;padding:8px 10px;font-size:9.5px;text-transform:uppercase;letter-spacing:.1em;}\n.docskin .transition-table td{padding:8px 10px;border-bottom:1px solid var(--rule);vertical-align:top;}\n.docskin .pill{display:inline-block;font-family:var(--font-mono);font-size:10px;font-weight:700;padding:2px 7px;border-radius:2px;text-transform:uppercase;}\n.docskin .pill-init{background:var(--light-gray);color:var(--slate);border:1px solid var(--rule);}\n.docskin .pill-active{background:var(--positive-soft);color:var(--positive);border:1px solid var(--positive);}\n.docskin .pill-wait{background:var(--highlight-soft);color:var(--highlight);border:1px solid var(--highlight);}\n.docskin .pill-end{background:var(--charcoal);color:#fff;}\n/* presentation: comparison table */\n.docskin .pres-table{width:100%;border-collapse:collapse;margin:14px 0;font-size:13px;}\n.docskin .pres-table thead{background:var(--navy);color:#fff;}\n.docskin .pres-table th{padding:9px 12px;text-align:left;font-family:var(--font-body);font-size:10.5px;text-transform:uppercase;letter-spacing:.08em;font-weight:700;}\n.docskin .pres-table th.r,.docskin .pres-table td.r{text-align:right;} .docskin .pres-table th.c,.docskin .pres-table td.c{text-align:center;}\n.docskin .pres-table th.hi{background:var(--highlight);}\n.docskin .pres-table td{padding:9px 12px;border-bottom:1px solid var(--rule);}\n.docskin .pres-table tbody tr:nth-child(even){background:var(--light-gray);}\n.docskin .pres-table td.lead{font-weight:700;color:var(--navy);font-family:var(--font-display);}\n.docskin .pres-table td.hi{background:var(--highlight-soft);}\n.docskin .cell-pos{color:var(--positive);font-weight:700;} .docskin .cell-neg{color:var(--negative);font-weight:700;} .docskin .cell-warn{color:var(--highlight);font-weight:700;} .docskin .cell-muted{color:var(--gray);}\n.docskin .badge{display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;border-radius:50%;font-size:12px;font-weight:700;}\n.docskin .badge.yes{background:var(--positive-soft);color:var(--positive);} .docskin .badge.no{background:var(--negative-soft);color:var(--negative);}\n.docskin .tbl-note{font-size:11px;color:var(--gray);font-style:italic;margin-top:6px;}\n/* presentation: stat cards */\n.docskin .stat-row{display:flex;flex-wrap:wrap;gap:14px;margin:16px 0;}\n.docskin .stat-card{flex:1 1 150px;border:1px solid var(--rule);border-top:3px solid var(--navy);padding:16px 18px;background:var(--white);}\n.docskin .stat-value{font-family:var(--font-display);font-size:30px;font-weight:700;color:var(--navy);line-height:1;}\n.docskin .stat-label{font-size:10.5px;text-transform:uppercase;letter-spacing:.1em;color:var(--gray);font-weight:700;margin-top:8px;}\n.docskin .stat-delta{font-family:var(--font-mono);font-size:12px;font-weight:700;margin-top:6px;}\n.docskin .stat-delta.up{color:var(--positive);} .docskin .stat-delta.down{color:var(--negative);} .docskin .stat-delta.flat{color:var(--gray);}\n/* presentation: timeline */\n.docskin .tl{position:relative;margin:18px 0;padding-left:8px;}\n.docskin .tl::before{content:\"\";position:absolute;left:9px;top:6px;bottom:6px;width:2px;background:var(--rule);}\n.docskin .tl-item{position:relative;padding:0 0 18px 30px;}\n.docskin .tl-item:last-child{padding-bottom:0;}\n.docskin .tl-dot{position:absolute;left:2px;top:2px;width:16px;height:16px;border-radius:50%;background:var(--white);border:3px solid var(--rule);box-sizing:border-box;}\n.docskin .tl-dot.done{background:var(--positive);border-color:var(--positive);} .docskin .tl-dot.current{background:var(--highlight);border-color:var(--highlight);} .docskin .tl-dot.next{border-color:var(--navy);}\n.docskin .tl-date{font-family:var(--font-mono);font-size:10.5px;font-weight:700;color:var(--highlight);text-transform:uppercase;letter-spacing:.06em;}\n.docskin .tl-label{font-family:var(--font-display);font-size:15px;font-weight:700;color:var(--navy);margin:1px 0 2px;}\n.docskin .tl-desc{font-size:12.5px;color:var(--slate);}\n/* presentation: quadrant */\n.docskin .quad-axis{stroke:var(--charcoal);stroke-width:1.5;}\n.docskin .quad-end{font-family:var(--font-body);font-size:10px;font-weight:700;fill:var(--gray);text-transform:uppercase;letter-spacing:.06em;}\n.docskin .quad-title{font-family:var(--font-body);font-size:11px;font-weight:700;fill:var(--navy);text-transform:uppercase;letter-spacing:.08em;}\n.docskin .quad-pt-label{font-family:var(--font-body);font-size:11px;font-weight:700;fill:var(--charcoal);}\n.docskin .toc{margin:18px 0 6px;padding:14px 20px;background:var(--light-gray);border:1px solid var(--rule);border-left:4px solid var(--highlight);border-radius:0 var(--radius) var(--radius) 0;}\n.docskin .toc-title{font-size:10px;text-transform:uppercase;letter-spacing:.12em;color:var(--navy);font-weight:700;margin-bottom:8px;}\n.docskin .toc ol{margin:0;padding-left:20px;} .docskin .toc li{font-size:13px;margin-bottom:4px;color:var(--slate);}\n.docskin .toc li span{color:var(--gray);font-family:var(--font-mono);font-size:11px;}\n/* swimlane */\n.docskin .sl-lane-label{font-family:var(--font-display);font-size:12px;font-weight:700;fill:#fff;}\n.docskin .sl-step{font-family:var(--font-body);font-size:11px;font-weight:700;text-anchor:middle;}\n/* callouts */\n.docskin .callout{border:1px solid var(--rule);border-left:4px solid var(--navy);padding:12px 16px;margin:10px 0;border-radius:0 var(--radius) var(--radius) 0;}\n.docskin .callout.note{border-left-color:var(--navy);background:var(--light-blue);} .docskin .callout.tip{border-left-color:var(--positive);background:var(--positive-soft);} .docskin .callout.warn{border-left-color:var(--highlight);background:var(--highlight-soft);} .docskin .callout.danger{border-left-color:var(--negative);background:var(--negative-soft);}\n.docskin .callout-title{font-size:10.5px;text-transform:uppercase;letter-spacing:.1em;font-weight:700;margin-bottom:4px;}\n.docskin .callout.note .callout-title{color:var(--navy);} .docskin .callout.tip .callout-title{color:var(--positive);} .docskin .callout.warn .callout-title{color:#b45309;} .docskin .callout.danger .callout-title{color:var(--negative);}\n.docskin .callout-body{font-size:13px;color:var(--slate);}\n/* prose */\n.docskin .prose h2{font-family:var(--font-display);font-weight:700;font-size:clamp(24px,3vw,32px);line-height:1.15;letter-spacing:-.015em;color:var(--navy);margin:40px 0 14px;padding-bottom:12px;border-bottom:2px solid var(--navy);}\n.docskin .prose h2:first-child{margin-top:0;}\n.docskin .prose h3{font-family:var(--font-display);font-weight:700;font-size:19px;letter-spacing:-.005em;color:var(--navy);margin:36px 0 12px;}\n.docskin .prose h4{font-size:11px;text-transform:uppercase;letter-spacing:.12em;font-weight:700;color:var(--highlight);margin:22px 0 8px;}\n.docskin .prose p{font-size:14px;color:var(--charcoal);margin:0 0 14px;line-height:1.6;max-width:880px;}\n.docskin .prose ul,.docskin .prose ol{margin:0 0 14px 22px;}\n.docskin .prose li{font-size:13.5px;color:var(--charcoal);margin-bottom:4px;max-width:880px;line-height:1.55;}\n.docskin .prose blockquote{border-left:3px solid var(--highlight);padding:4px 14px;margin:14px 0;color:var(--slate);font-style:italic;font-family:var(--font-display);}\n.docskin .prose code{font-family:var(--font-mono);font-size:.86em;background:var(--light-gray);padding:2px 6px;border-radius:2px;color:var(--charcoal);border:1px solid var(--rule);}\n.docskin .prose strong{font-weight:700;color:var(--charcoal);}\n.docskin .prose em{font-style:italic;}\n/* glossary */\n.docskin .glossary{margin:10px 0;}\n.docskin .glossary .row{display:grid;grid-template-columns:170px 1fr;gap:14px;padding:9px 0;border-bottom:1px solid var(--rule);}\n.docskin .glossary dt{font-family:var(--font-mono);font-size:13px;font-weight:700;color:var(--navy);}\n.docskin .glossary dd{margin:0;font-size:13px;color:var(--slate);}\n/* pros / cons */\n.docskin .pc{display:grid;grid-template-columns:1fr 1fr;gap:16px;margin:12px 0;}\n.docskin .pc-col{border:1px solid var(--rule);padding:14px 16px;}\n.docskin .pc-col.pro{border-top:3px solid var(--positive);} .docskin .pc-col.con{border-top:3px solid var(--negative);}\n.docskin .pc-head{font-size:11px;text-transform:uppercase;letter-spacing:.1em;font-weight:700;margin-bottom:8px;}\n.docskin .pc-col.pro .pc-head{color:var(--positive);} .docskin .pc-col.con .pc-head{color:var(--negative);}\n.docskin .pc-item{font-size:13px;color:var(--slate);padding:4px 0 4px 22px;position:relative;}\n.docskin .pc-item::before{position:absolute;left:0;top:4px;font-weight:700;}\n.docskin .pc-col.pro .pc-item::before{content:\"\\2713\";color:var(--positive);} .docskin .pc-col.con .pc-item::before{content:\"\\2717\";color:var(--negative);}\n/* current / target */\n.docskin .ct{display:flex;align-items:stretch;margin:12px 0;}\n.docskin .ct-panel{flex:1;border:1px solid var(--rule);padding:14px 18px;}\n.docskin .ct-panel.cur{background:var(--light-gray);} .docskin .ct-panel.tgt{border-top:3px solid var(--navy);}\n.docskin .ct-arrow{display:flex;align-items:center;padding:0 14px;color:var(--highlight);font-size:22px;font-weight:700;}\n.docskin .ct-label{font-size:11px;text-transform:uppercase;letter-spacing:.1em;font-weight:700;color:var(--gray);margin-bottom:8px;}\n.docskin .ct-panel.tgt .ct-label{color:var(--navy);}\n.docskin .ct-item{font-size:13px;color:var(--slate);padding:3px 0;}\n/* kanban */\n.docskin .kanban{display:flex;gap:14px;margin:12px 0;overflow-x:auto;}\n.docskin .kan-col{flex:1 1 0;min-width:150px;background:var(--light-gray);border:1px solid var(--rule);}\n.docskin .kan-head{background:var(--navy);color:#fff;font-size:11px;text-transform:uppercase;letter-spacing:.08em;font-weight:700;padding:8px 12px;}\n.docskin .kan-card{background:var(--white);border:1px solid var(--rule);border-left:3px solid var(--highlight);margin:8px;padding:9px 11px;border-radius:0 var(--radius) var(--radius) 0;}\n.docskin .kan-card-title{font-size:13px;font-weight:700;color:var(--charcoal);}\n.docskin .kan-card-tag{display:inline-block;font-family:var(--font-mono);font-size:9px;font-weight:700;text-transform:uppercase;letter-spacing:.06em;color:var(--gray);margin-top:4px;}\n/* pass 2 chart labels */\n.docskin .dfd-name{font-family:var(--font-display);font-size:12px;font-weight:700;text-anchor:middle;}\n.docskin .dfd-num{font-family:var(--font-mono);font-size:9px;font-weight:700;}\n.docskin .gantt-label{font-family:var(--font-body);font-size:11px;fill:var(--charcoal);}\n.docskin .gantt-head{font-family:var(--font-mono);font-size:9.5px;fill:var(--gray);text-anchor:middle;}\n.docskin .funnel-label{font-family:var(--font-display);font-size:13px;font-weight:700;fill:#fff;text-anchor:middle;}\n.docskin .funnel-val{font-family:var(--font-mono);font-size:11px;fill:#fff;text-anchor:middle;opacity:.9;}\n.docskin .pyr-label{font-family:var(--font-display);font-size:13px;font-weight:700;fill:#fff;text-anchor:middle;}\n.docskin .pyr-desc{font-family:var(--font-body);font-size:10px;fill:#fff;text-anchor:middle;opacity:.85;}\n/* indented tree */\n.docskin .tree-list{margin:10px 0;font-size:13px;}\n.docskin .tree-row{display:flex;align-items:baseline;padding:3px 0;}\n.docskin .tree-row .tw{color:var(--gray);margin-right:8px;font-family:var(--font-mono);font-size:11px;}\n.docskin .tree-row.branch .tw{color:var(--navy);}\n.docskin .tree-row .tlabel{color:var(--charcoal);font-family:var(--font-mono);}\n.docskin .tree-row.branch .tlabel{font-weight:700;color:var(--navy);}\n.docskin .tree-row .tnote{color:var(--gray);font-size:11px;margin-left:10px;font-family:var(--font-body);font-style:italic;}\n/* agenda */\n.docskin .agenda{margin:10px 0;}\n.docskin .agenda-row{display:grid;grid-template-columns:88px 1fr;gap:14px;padding:10px 0;border-bottom:1px solid var(--rule);}\n.docskin .agenda-time{font-family:var(--font-mono);font-size:12px;font-weight:700;color:var(--navy);}\n.docskin .agenda-dur{font-family:var(--font-mono);font-size:10px;color:var(--gray);margin-top:2px;}\n.docskin .agenda-title{font-family:var(--font-display);font-size:14px;font-weight:700;color:var(--charcoal);}\n.docskin .agenda-owner{font-size:10.5px;color:var(--highlight);font-weight:700;text-transform:uppercase;letter-spacing:.05em;margin-left:8px;}\n.docskin .agenda-desc{font-size:12.5px;color:var(--slate);margin-top:2px;}\n/* tracker */\n.docskin .trk{width:100%;border-collapse:collapse;margin:12px 0;font-size:13px;}\n.docskin .trk thead{background:var(--navy);color:#fff;} .docskin .trk th{padding:8px 10px;text-align:left;font-size:9.5px;text-transform:uppercase;letter-spacing:.08em;font-weight:700;}\n.docskin .trk td{padding:8px 10px;border-bottom:1px solid var(--rule);vertical-align:middle;}\n.docskin .trk tr.done .trk-task{text-decoration:line-through;color:var(--gray);}\n.docskin .st{display:inline-block;font-family:var(--font-mono);font-size:9.5px;font-weight:700;padding:2px 8px;border-radius:10px;text-transform:uppercase;letter-spacing:.04em;}\n.docskin .st.todo{background:var(--light-gray);color:var(--slate);border:1px solid var(--rule);} .docskin .st.doing{background:var(--highlight-soft);color:#b45309;} .docskin .st.done{background:var(--positive-soft);color:var(--positive);} .docskin .st.blocked{background:var(--negative-soft);color:var(--negative);}\n.docskin .pri{font-family:var(--font-mono);font-size:10px;font-weight:700;} .docskin .pri.high{color:var(--negative);} .docskin .pri.med{color:var(--highlight);} .docskin .pri.low{color:var(--gray);}\n/* cluster */\n.docskin .cl-head{font-family:var(--font-display);font-size:13px;font-weight:700;fill:#fff;}\n.docskin .cl-kind{font-family:var(--font-mono);font-size:9px;fill:#cfe0f3;text-anchor:end;text-transform:uppercase;letter-spacing:.06em;}\n/* user story */\n.docskin .story{border:1px solid var(--rule);border-left:4px solid var(--navy);padding:18px 22px;margin:12px 0;background:var(--white);border-radius:0 var(--radius) var(--radius) 0;}\n.docskin .story-stmt{font-family:var(--font-display);font-size:18px;line-height:1.55;color:var(--charcoal);}\n.docskin .story-stmt b{color:var(--navy);}\n.docskin .story-meta{display:flex;gap:8px;margin-top:12px;flex-wrap:wrap;}\n.docskin .story-chip{font-family:var(--font-mono);font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.05em;padding:3px 9px;border-radius:3px;background:var(--light-gray);color:var(--slate);border:1px solid var(--rule);}\n.docskin .ac-title{font-size:10.5px;text-transform:uppercase;letter-spacing:.12em;color:var(--highlight);font-weight:700;margin:16px 0 8px;}\n.docskin .ac-item{border:1px solid var(--rule);padding:10px 14px;margin-bottom:8px;background:var(--white);}\n.docskin .gwt{display:grid;grid-template-columns:60px 1fr;gap:4px 12px;font-size:13px;}\n.docskin .gwt .k{font-family:var(--font-mono);font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.06em;padding-top:1px;}\n.docskin .gwt .k.g{color:var(--positive);} .docskin .gwt .k.w{color:var(--navy);} .docskin .gwt .k.t{color:var(--highlight);}\n.docskin .gwt .v{color:var(--charcoal);}\n.docskin .links-row{display:flex;gap:8px;flex-wrap:wrap;}\n.docskin .link-chip{display:inline-flex;align-items:center;gap:6px;font-size:12px;font-weight:700;color:var(--navy);border:1px solid var(--navy);background:var(--white);padding:5px 11px;border-radius:20px;cursor:pointer;}\n.docskin .link-chip .lt{color:var(--gray);font-family:var(--font-mono);font-size:9px;text-transform:uppercase;letter-spacing:.06em;}\n.docskin .footer{margin-top:8px;padding:18px 32px 28px;border-top:2px solid var(--navy);font-size:11px;color:var(--gray);text-transform:uppercase;letter-spacing:.1em;font-weight:700;display:flex;justify-content:space-between;flex-wrap:wrap;gap:10px;}\n.docskin .footer .accent{color:var(--highlight);}\n.docskin .layer-label{font-family:var(--font-display);font-size:13px;font-weight:700;fill:#fff;}\n.docskin .uml-name{font-family:var(--font-display);font-size:11px;font-weight:700;text-anchor:middle;fill:var(--navy);}\n.docskin .uml-stereo{font-family:var(--font-body);font-size:8px;font-style:italic;text-anchor:middle;fill:var(--gray);}\n.docskin .uml-row{font-family:var(--font-mono);font-size:9px;fill:var(--charcoal);}\n.docskin .uml-sep{stroke:var(--rule);stroke-width:1;}\n.docskin .ft-note{font-family:var(--font-mono);font-size:9px;}\n.docskin .tree-link{stroke:#9ca3af;stroke-width:1.3;fill:none;}\n/* wireframe / UI mockups */\n.docskin .wf-h{font-family:var(--font-display);font-size:18px;font-weight:700;}\n.docskin .wf-sub{font-family:var(--font-body);font-size:12px;font-weight:600;}\n.docskin .wf-btn{font-family:var(--font-body);font-size:11px;font-weight:700;fill:#fff;}\n.docskin .wf-ph-text{font-family:var(--font-body);font-size:10px;fill:var(--gray);}\n.docskin .wf-status{font-family:var(--font-mono);font-size:9px;fill:var(--charcoal);font-weight:700;}\n.docskin .wf-url{font-family:var(--font-mono);font-size:8.5px;fill:var(--gray);}\n.docskin .wf-tab{font-family:var(--font-body);font-size:8px;}\n.docskin .wf-caption{font-family:var(--font-mono);font-size:10px;fill:var(--gray);letter-spacing:.04em;}\n/* parse error */\n.docskin .err{font-family:var(--font-mono);font-size:12px;color:var(--negative);background:#fdf2f2;border:1px solid #f3c9c9;padding:8px 12px;margin:12px 0;white-space:pre-wrap;}";
15
15
 
16
16
  /**
17
17
  * HTML entity escaping, matching the reference renderer's `esc` semantics.
package/dist/index.js CHANGED
@@ -154,7 +154,7 @@ body{background:var(--white);color:var(--charcoal);font-family:var(--font-body);
154
154
  .docskin .quad-end{font-family:var(--font-body);font-size:10px;font-weight:700;fill:var(--gray);text-transform:uppercase;letter-spacing:.06em;}
155
155
  .docskin .quad-title{font-family:var(--font-body);font-size:11px;font-weight:700;fill:var(--navy);text-transform:uppercase;letter-spacing:.08em;}
156
156
  .docskin .quad-pt-label{font-family:var(--font-body);font-size:11px;font-weight:700;fill:var(--charcoal);}
157
- .docskin .toc{margin:18px 0 6px;padding:14px 20px;background:var(--light-gray);border:1px solid var(--rule);border-left:4px solid var(--highlight);}
157
+ .docskin .toc{margin:18px 0 6px;padding:14px 20px;background:var(--light-gray);border:1px solid var(--rule);border-left:4px solid var(--highlight);border-radius:0 var(--radius) var(--radius) 0;}
158
158
  .docskin .toc-title{font-size:10px;text-transform:uppercase;letter-spacing:.12em;color:var(--navy);font-weight:700;margin-bottom:8px;}
159
159
  .docskin .toc ol{margin:0;padding-left:20px;} .docskin .toc li{font-size:13px;margin-bottom:4px;color:var(--slate);}
160
160
  .docskin .toc li span{color:var(--gray);font-family:var(--font-mono);font-size:11px;}
@@ -162,7 +162,7 @@ body{background:var(--white);color:var(--charcoal);font-family:var(--font-body);
162
162
  .docskin .sl-lane-label{font-family:var(--font-display);font-size:12px;font-weight:700;fill:#fff;}
163
163
  .docskin .sl-step{font-family:var(--font-body);font-size:11px;font-weight:700;text-anchor:middle;}
164
164
  /* callouts */
165
- .docskin .callout{border:1px solid var(--rule);border-left:4px solid var(--navy);padding:12px 16px;margin:10px 0;}
165
+ .docskin .callout{border:1px solid var(--rule);border-left:4px solid var(--navy);padding:12px 16px;margin:10px 0;border-radius:0 var(--radius) var(--radius) 0;}
166
166
  .docskin .callout.note{border-left-color:var(--navy);background:var(--light-blue);} .docskin .callout.tip{border-left-color:var(--positive);background:var(--positive-soft);} .docskin .callout.warn{border-left-color:var(--highlight);background:var(--highlight-soft);} .docskin .callout.danger{border-left-color:var(--negative);background:var(--negative-soft);}
167
167
  .docskin .callout-title{font-size:10.5px;text-transform:uppercase;letter-spacing:.1em;font-weight:700;margin-bottom:4px;}
168
168
  .docskin .callout.note .callout-title{color:var(--navy);} .docskin .callout.tip .callout-title{color:var(--positive);} .docskin .callout.warn .callout-title{color:#b45309;} .docskin .callout.danger .callout-title{color:var(--negative);}
@@ -205,7 +205,7 @@ body{background:var(--white);color:var(--charcoal);font-family:var(--font-body);
205
205
  .docskin .kanban{display:flex;gap:14px;margin:12px 0;overflow-x:auto;}
206
206
  .docskin .kan-col{flex:1 1 0;min-width:150px;background:var(--light-gray);border:1px solid var(--rule);}
207
207
  .docskin .kan-head{background:var(--navy);color:#fff;font-size:11px;text-transform:uppercase;letter-spacing:.08em;font-weight:700;padding:8px 12px;}
208
- .docskin .kan-card{background:var(--white);border:1px solid var(--rule);border-left:3px solid var(--highlight);margin:8px;padding:9px 11px;}
208
+ .docskin .kan-card{background:var(--white);border:1px solid var(--rule);border-left:3px solid var(--highlight);margin:8px;padding:9px 11px;border-radius:0 var(--radius) var(--radius) 0;}
209
209
  .docskin .kan-card-title{font-size:13px;font-weight:700;color:var(--charcoal);}
210
210
  .docskin .kan-card-tag{display:inline-block;font-family:var(--font-mono);font-size:9px;font-weight:700;text-transform:uppercase;letter-spacing:.06em;color:var(--gray);margin-top:4px;}
211
211
  /* pass 2 chart labels */
@@ -245,7 +245,7 @@ body{background:var(--white);color:var(--charcoal);font-family:var(--font-body);
245
245
  .docskin .cl-head{font-family:var(--font-display);font-size:13px;font-weight:700;fill:#fff;}
246
246
  .docskin .cl-kind{font-family:var(--font-mono);font-size:9px;fill:#cfe0f3;text-anchor:end;text-transform:uppercase;letter-spacing:.06em;}
247
247
  /* user story */
248
- .docskin .story{border:1px solid var(--rule);border-left:4px solid var(--navy);padding:18px 22px;margin:12px 0;background:var(--white);}
248
+ .docskin .story{border:1px solid var(--rule);border-left:4px solid var(--navy);padding:18px 22px;margin:12px 0;background:var(--white);border-radius:0 var(--radius) var(--radius) 0;}
249
249
  .docskin .story-stmt{font-family:var(--font-display);font-size:18px;line-height:1.55;color:var(--charcoal);}
250
250
  .docskin .story-stmt b{color:var(--navy);}
251
251
  .docskin .story-meta{display:flex;gap:8px;margin-top:12px;flex-wrap:wrap;}
@@ -262,10 +262,10 @@ body{background:var(--white);color:var(--charcoal);font-family:var(--font-body);
262
262
  .docskin .footer{margin-top:8px;padding:18px 32px 28px;border-top:2px solid var(--navy);font-size:11px;color:var(--gray);text-transform:uppercase;letter-spacing:.1em;font-weight:700;display:flex;justify-content:space-between;flex-wrap:wrap;gap:10px;}
263
263
  .docskin .footer .accent{color:var(--highlight);}
264
264
  .docskin .layer-label{font-family:var(--font-display);font-size:13px;font-weight:700;fill:#fff;}
265
- .docskin .uml-name{font-family:var(--font-display);font-size:13px;font-weight:700;text-anchor:middle;fill:#0a3a6e;}
266
- .docskin .uml-stereo{font-family:var(--font-body);font-size:9px;font-style:italic;text-anchor:middle;fill:#6b7280;}
267
- .docskin .uml-row{font-family:var(--font-mono);font-size:10.5px;fill:var(--charcoal);}
268
- .docskin .uml-sep{stroke:#0e54a1;stroke-width:1;}
265
+ .docskin .uml-name{font-family:var(--font-display);font-size:11px;font-weight:700;text-anchor:middle;fill:var(--navy);}
266
+ .docskin .uml-stereo{font-family:var(--font-body);font-size:8px;font-style:italic;text-anchor:middle;fill:var(--gray);}
267
+ .docskin .uml-row{font-family:var(--font-mono);font-size:9px;fill:var(--charcoal);}
268
+ .docskin .uml-sep{stroke:var(--rule);stroke-width:1;}
269
269
  .docskin .ft-note{font-family:var(--font-mono);font-size:9px;}
270
270
  .docskin .tree-link{stroke:#9ca3af;stroke-width:1.3;fill:none;}
271
271
  /* wireframe / UI mockups */
@@ -2729,7 +2729,7 @@ function edgePill(p2, label, err = false) {
2729
2729
  if (label === void 0 || label === "") return "";
2730
2730
  const w2 = Math.max(26, label.length * 5.4);
2731
2731
  const errClass = err ? " err" : "";
2732
- return `<g><rect x="${p2.lx - w2 / 2}" y="${p2.ly - 9}" width="${w2}" height="18" rx="9" fill="#fff" stroke="#d1d5db"/><text x="${p2.lx}" y="${p2.ly + 3}" class="edge-label${errClass}">${escapeHtml(label)}</text></g>`;
2732
+ return `<g><rect x="${p2.lx - w2 / 2}" y="${p2.ly - 9}" width="${w2}" height="18" rx="9" fill="var(--white)" stroke="var(--rule)"/><text x="${p2.lx}" y="${p2.ly + 3}" class="edge-label${errClass}">${escapeHtml(label)}</text></g>`;
2733
2733
  }
2734
2734
 
2735
2735
  // src/blocks/autoLayout.ts
@@ -2815,6 +2815,7 @@ function renderFlowSvg(data) {
2815
2815
  const width = padX * 2 + cols * cellW + (cols - 1) * gapX;
2816
2816
  const height = padTop + rows * cellH + (rows - 1) * gapY + padBot;
2817
2817
  let s = `<svg viewBox="0 0 ${width} ${height}" role="img"><title>Flowchart</title>`;
2818
+ const labels = [];
2818
2819
  for (const e of edges) {
2819
2820
  const A2 = byId.get(e.from);
2820
2821
  const B2 = byId.get(e.to);
@@ -2824,7 +2825,8 @@ function renderFlowSvg(data) {
2824
2825
  const stroke = isErr ? "#991b1b" : "#1a1a2e";
2825
2826
  const marker = isErr ? "gErr" : "gArrow";
2826
2827
  const sw = isErr ? 1.6 : 1.4;
2827
- s += `<g><path d="${p2.d}" fill="none" stroke="${stroke}" stroke-width="${sw}" marker-end="url(#${marker})"/>` + edgePill(p2, e.label, isErr) + `</g>`;
2828
+ s += `<path d="${p2.d}" fill="none" stroke="${stroke}" stroke-width="${sw}" marker-end="url(#${marker})"/>`;
2829
+ labels.push(edgePill(p2, e.label, isErr));
2828
2830
  }
2829
2831
  for (const n of nodes) {
2830
2832
  const r = rectFor2(n);
@@ -2845,6 +2847,7 @@ function renderFlowSvg(data) {
2845
2847
  ).join("");
2846
2848
  s += `<g filter="url(#gshadow)">${shape}${texts}</g>`;
2847
2849
  }
2850
+ s += labels.join("");
2848
2851
  s += `</svg>`;
2849
2852
  return s;
2850
2853
  }
@@ -2899,6 +2902,7 @@ function renderState(data) {
2899
2902
  const height = padTop * 2 + rows * cellH + (rows - 1) * gapY + padBot;
2900
2903
  const byId = new Map(states.map((s2) => [s2.id, s2]));
2901
2904
  let s = `<svg viewBox="0 0 ${width} ${height}" role="img"><title>State machine</title>`;
2905
+ const labels = [];
2902
2906
  for (const t of trans) {
2903
2907
  const A2 = byId.get(t.from);
2904
2908
  const B2 = byId.get(t.to);
@@ -2906,14 +2910,16 @@ function renderState(data) {
2906
2910
  const label = t.event + (t.guard !== void 0 ? ` ${t.guard}` : "");
2907
2911
  if (t.from === t.to) {
2908
2912
  const r = rectFor(A2, cellW, cellH, gapX, gapY, padX, padTop);
2909
- s += `<g><path d="M ${r.cx - 12} ${r.y} C ${r.cx - 30} ${r.y - 32}, ${r.cx + 30} ${r.y - 32}, ${r.cx + 12} ${r.y}" fill="none" stroke="#1a1a2e" stroke-width="1.3" marker-end="url(#gArrow)"/>` + edgePill({ lx: r.cx, ly: r.y - 28 }, label) + `</g>`;
2913
+ s += `<path d="M ${r.cx - 12} ${r.y} C ${r.cx - 30} ${r.y - 32}, ${r.cx + 30} ${r.y - 32}, ${r.cx + 12} ${r.y}" fill="none" stroke="#1a1a2e" stroke-width="1.3" marker-end="url(#gArrow)"/>`;
2914
+ labels.push(edgePill({ lx: r.cx, ly: r.y - 28 }, label));
2910
2915
  continue;
2911
2916
  }
2912
2917
  const p2 = ortho(
2913
2918
  rectFor(A2, cellW, cellH, gapX, gapY, padX, padTop),
2914
2919
  rectFor(B2, cellW, cellH, gapX, gapY, padX, padTop)
2915
2920
  );
2916
- s += `<g><path d="${p2.d}" fill="none" stroke="#1a1a2e" stroke-width="1.3" marker-end="url(#gArrow)"/>` + edgePill(p2, label) + `</g>`;
2921
+ s += `<path d="${p2.d}" fill="none" stroke="#1a1a2e" stroke-width="1.3" marker-end="url(#gArrow)"/>`;
2922
+ labels.push(edgePill(p2, label));
2917
2923
  }
2918
2924
  for (const st2 of states) {
2919
2925
  const r = rectFor(st2, cellW, cellH, gapX, gapY, padX, padTop);
@@ -2927,6 +2933,7 @@ function renderState(data) {
2927
2933
  s += `<g filter="url(#gshadow)"><rect x="${r.x}" y="${r.y}" width="${r.w}" height="${r.h}" rx="23" fill="${fill}" stroke="${stroke}" stroke-width="1.5"/><text x="${r.cx}" y="${r.cy + 4.5}" class="sm-name" fill="#1a1a2e">${escapeHtml(st2.name ?? "")}</text></g>`;
2928
2934
  }
2929
2935
  }
2936
+ s += labels.join("");
2930
2937
  s += `</svg>`;
2931
2938
  const name = (id) => byId.get(id)?.name ?? id;
2932
2939
  const rows2 = trans.map(
@@ -2959,10 +2966,10 @@ function dfdStyle(kind) {
2959
2966
  function renderDfd(data) {
2960
2967
  const edges = data.edges ?? [];
2961
2968
  const nodes = ensureGrid(data.nodes ?? [], edges, "LR");
2962
- const cellW = 168;
2963
- const cellH = 76;
2964
- const gapX = 60;
2965
- const gapY = 58;
2969
+ const cellW = 148;
2970
+ const cellH = 66;
2971
+ const gapX = 104;
2972
+ const gapY = 54;
2966
2973
  const padX = 26;
2967
2974
  const padTop = 26;
2968
2975
  const padBot = 20;
@@ -2975,12 +2982,14 @@ function renderDfd(data) {
2975
2982
  const width = padX * 2 + cols * cellW + (cols - 1) * gapX;
2976
2983
  const height = padTop + rows * cellH + (rows - 1) * gapY + padBot;
2977
2984
  let s = `<svg viewBox="0 0 ${width} ${height}" role="img"><title>Data-flow diagram</title>`;
2985
+ const labels = [];
2978
2986
  for (const e of edges) {
2979
2987
  const A2 = byId.get(e.from);
2980
2988
  const B2 = byId.get(e.to);
2981
2989
  if (!A2 || !B2) continue;
2982
2990
  const p2 = ortho(rectFor2(A2), rectFor2(B2));
2983
- s += `<g><path d="${p2.d}" fill="none" stroke="#1a1a2e" stroke-width="1.4" marker-end="url(#gArrow)"/>` + edgePill(p2, e.label) + `</g>`;
2991
+ s += `<path d="${p2.d}" fill="none" stroke="#1a1a2e" stroke-width="1.4" marker-end="url(#gArrow)"/>`;
2992
+ labels.push(edgePill(p2, e.label));
2984
2993
  }
2985
2994
  for (const n of nodes) {
2986
2995
  const r = rectFor2(n);
@@ -2997,6 +3006,7 @@ function renderDfd(data) {
2997
3006
  const num = n.num !== void 0 && k2 === "process" ? `<text x="${r.x + 12}" y="${r.y + 18}" class="dfd-num" fill="${st2.text}">${escapeHtml(n.num)}</text>` : "";
2998
3007
  s += `<g filter="url(#gshadow)">${shape}${num}<text x="${r.x + r.w / 2}" y="${r.y + r.h / 2 + 4}" class="dfd-name" fill="${st2.text}">${escapeHtml(n.name)}</text></g>`;
2999
3008
  }
3009
+ s += labels.join("");
3000
3010
  s += `</svg>`;
3001
3011
  return diagramFrame(
3002
3012
  {
@@ -3359,6 +3369,12 @@ var GEDGE = {
3359
3369
  error: { stroke: "#991b1b", sw: 1.6, dash: "", marker: "gErr", err: true }
3360
3370
  };
3361
3371
 
3372
+ // src/svg/shapes.ts
3373
+ function rectRoundRight(x2, y, w2, h, r) {
3374
+ const rr2 = Math.min(r, w2 / 2, h / 2);
3375
+ return `M${x2},${y} h${w2 - rr2} a${rr2},${rr2} 0 0 1 ${rr2},${rr2} v${h - 2 * rr2} a${rr2},${rr2} 0 0 1 ${-rr2},${rr2} h${-(w2 - rr2)} z`;
3376
+ }
3377
+
3362
3378
  // src/blocks/c4.ts
3363
3379
  function c4Style(n) {
3364
3380
  const f = (n.family ?? "").toLowerCase();
@@ -3513,6 +3529,7 @@ function renderC4(data) {
3513
3529
  }
3514
3530
  }
3515
3531
  let s = `<svg viewBox="0 0 ${width} ${height}" role="img"><title>C4 diagram</title>${boundarySvg}`;
3532
+ const labels = [];
3516
3533
  for (const e of edges) {
3517
3534
  const A2 = byId.get(e.from);
3518
3535
  const B2 = byId.get(e.to);
@@ -3525,7 +3542,8 @@ function renderC4(data) {
3525
3542
  marker: "gArrow",
3526
3543
  err: false
3527
3544
  };
3528
- s += `<g><path d="${p2.d}" fill="none" stroke="${st2.stroke}" stroke-width="${st2.sw}" stroke-dasharray="${st2.dash}" marker-end="url(#${st2.marker})"/>` + edgePill(p2, e.label, st2.err) + `</g>`;
3545
+ s += `<path d="${p2.d}" fill="none" stroke="${st2.stroke}" stroke-width="${st2.sw}" stroke-dasharray="${st2.dash}" marker-end="url(#${st2.marker})"/>`;
3546
+ labels.push(edgePill(p2, e.label, st2.err));
3529
3547
  }
3530
3548
  for (const n of nodes) {
3531
3549
  const r = rectFor2(n);
@@ -3535,15 +3553,17 @@ function renderC4(data) {
3535
3553
  const strokeWidth = st2.solid === true ? 0 : 1.2;
3536
3554
  const strokeAttr = st2.solid === true ? "none" : st2.accent;
3537
3555
  const dashAttr = st2.dash !== void 0 ? ` stroke-dasharray="${st2.dash}"` : "";
3538
- const stripe = st2.solid === true ? "" : `<rect x="${r.x}" y="${r.y}" width="5" height="${r.h}" rx="2" fill="${st2.accent}"/>`;
3539
- const personGlyph = n.kind === "person" ? `<g fill="${st2.text}"><circle cx="${px + 6}" cy="${r.y + 19}" r="6"/><path d="M ${px} ${r.y + 34} a 6 7 0 0 1 12 0 z"/></g>` : "";
3540
- const chipX = n.kind === "person" ? px + 22 : px;
3556
+ const stripe = st2.solid === true ? "" : `<rect x="${r.x}" y="${r.y}" width="5" height="${r.h}" fill="${st2.accent}"/>`;
3557
+ const card = st2.solid === true ? `<rect x="${r.x}" y="${r.y}" width="${r.w}" height="${r.h}" rx="10" fill="${st2.fill}" stroke="${strokeAttr}" stroke-width="${strokeWidth}"${dashAttr}/>` : `<path d="${rectRoundRight(r.x, r.y, r.w, r.h, 10)}" fill="${st2.fill}" stroke="${strokeAttr}" stroke-width="${strokeWidth}"${dashAttr}/>`;
3558
+ const gx = r.x + r.w - 26;
3559
+ const personGlyph = n.kind === "person" ? `<g fill="${st2.text}"><circle cx="${gx + 7}" cy="${r.y + 18}" r="6"/><path d="M ${gx} ${r.y + 33} a 7 8 0 0 1 14 0 z"/></g>` : "";
3560
+ const chipX = px;
3541
3561
  const chipFill = st2.solid === true ? st2.sub : st2.accent;
3542
3562
  const techLine = n.tech !== void 0 ? `<text x="${px}" y="${r.y + 60}" class="c4-tech" fill="${st2.sub}">${escapeHtml(n.tech)}</text>` : "";
3543
3563
  const descLines = desc.map(
3544
3564
  (ln2, j2) => `<text x="${px}" y="${r.y + 77 + j2 * 13}" class="c4-desc" fill="${st2.sub}">${escapeHtml(ln2)}</text>`
3545
3565
  ).join("");
3546
- s += `<g filter="url(#gshadow)"><rect x="${r.x}" y="${r.y}" width="${r.w}" height="${r.h}" rx="10" fill="${st2.fill}" stroke="${strokeAttr}" stroke-width="${strokeWidth}"${dashAttr}/>` + stripe + personGlyph + `<text x="${chipX}" y="${r.y + 22}" class="c4-chip" fill="${chipFill}">${escapeHtml(st2.chip)}</text><text x="${px}" y="${r.y + 44}" class="c4-name" fill="${st2.text}">${escapeHtml(n.name)}</text>` + techLine + descLines + `</g>`;
3566
+ s += `<g filter="url(#gshadow)">` + card + stripe + personGlyph + `<text x="${chipX}" y="${r.y + 22}" class="c4-chip" fill="${chipFill}">${escapeHtml(st2.chip)}</text><text x="${px}" y="${r.y + 44}" class="c4-name" fill="${st2.text}">${escapeHtml(n.name)}</text>` + techLine + descLines + `</g>`;
3547
3567
  }
3548
3568
  s += `</svg>`;
3549
3569
  const legend = `<div class="legend">` + LEGEND.map(
@@ -3582,14 +3602,14 @@ function umlRel(kind) {
3582
3602
  function renderUml(data) {
3583
3603
  const rels = data.rels ?? [];
3584
3604
  const classes = ensureGrid(data.classes ?? [], rels, "TB");
3585
- const colW = 204;
3586
- const gapX = 64;
3587
- const gapY = 50;
3588
- const padX = 26;
3589
- const padTop = 30;
3590
- const padBot = 22;
3591
- const rowH = 17;
3592
- const headH = (c) => 28 + (c.stereotype !== void 0 ? 12 : 0);
3605
+ const colW = 150;
3606
+ const gapX = 76;
3607
+ const gapY = 58;
3608
+ const padX = 24;
3609
+ const padTop = 28;
3610
+ const padBot = 20;
3611
+ const rowH = 14;
3612
+ const headH = (c) => 22 + (c.stereotype !== void 0 ? 10 : 0);
3593
3613
  const compH = (list) => (list !== void 0 && list.length > 0 ? list.length * rowH : 6) + 8;
3594
3614
  const clsH = (c) => headH(c) + compH(c.attrs) + compH(c.methods);
3595
3615
  const cols = Math.max(1, ...classes.map((c) => c.col));
@@ -3615,6 +3635,7 @@ function renderUml(data) {
3615
3635
  const width = padX * 2 + cols * colW + (cols - 1) * gapX;
3616
3636
  const height = acc - gapY + padBot;
3617
3637
  let s = `<svg viewBox="0 0 ${width} ${height}" role="img"><title>UML class diagram</title><defs><marker id="umlTri" viewBox="0 0 14 14" refX="13" refY="7" markerWidth="15" markerHeight="15" orient="auto-start-reverse"><path d="M1,1 L13,7 L1,13 z" fill="#fff" stroke="#1a1a2e" stroke-width="1.2"/></marker><marker id="umlDiaF" viewBox="0 0 20 12" refX="19" refY="6" markerWidth="20" markerHeight="12" orient="auto-start-reverse"><path d="M1,6 L10,1 L19,6 L10,11 z" fill="#1a1a2e"/></marker><marker id="umlDiaH" viewBox="0 0 20 12" refX="19" refY="6" markerWidth="20" markerHeight="12" orient="auto-start-reverse"><path d="M1,6 L10,1 L19,6 L10,11 z" fill="#fff" stroke="#1a1a2e" stroke-width="1.2"/></marker><marker id="umlOpen" viewBox="0 0 12 12" refX="10" refY="6" markerWidth="12" markerHeight="12" orient="auto-start-reverse"><path d="M1,1 L11,6 L1,11" fill="none" stroke="#1a1a2e" stroke-width="1.3"/></marker></defs>`;
3638
+ const labels = [];
3618
3639
  for (const rl of rels) {
3619
3640
  const A2 = byId.get(rl.from);
3620
3641
  const B2 = byId.get(rl.to);
@@ -3623,7 +3644,8 @@ function renderUml(data) {
3623
3644
  const st2 = umlRel(rl.kind);
3624
3645
  const start = st2.start !== void 0 ? ` marker-start="url(#${st2.start})"` : "";
3625
3646
  const end = st2.end !== void 0 ? ` marker-end="url(#${st2.end})"` : "";
3626
- s += `<g><path d="${p2.d}" fill="none" stroke="#1a1a2e" stroke-width="1.3" stroke-dasharray="${st2.dash}"${start}${end}/>` + edgePill(p2, rl.label) + `</g>`;
3647
+ s += `<path d="${p2.d}" fill="none" stroke="#1a1a2e" stroke-width="1.3" stroke-dasharray="${st2.dash}"${start}${end}/>`;
3648
+ labels.push(edgePill(p2, rl.label));
3627
3649
  }
3628
3650
  for (const c of classes) {
3629
3651
  const r = rectFor2(c);
@@ -3637,8 +3659,9 @@ function renderUml(data) {
3637
3659
  const methods = (c.methods ?? []).map(
3638
3660
  (m, j2) => `<text x="${r.x + 10}" y="${r.y + hh + aH + 14 + j2 * rowH}" class="uml-row">${escapeHtml(m)}</text>`
3639
3661
  ).join("");
3640
- s += `<g filter="url(#gshadow)"><rect x="${r.x}" y="${r.y}" width="${r.w}" height="${r.h}" rx="3" fill="#fff" stroke="#0e54a1" stroke-width="1.3"/>` + stereo + `<text x="${r.x + r.w / 2}" y="${nameY}" class="uml-name">${escapeHtml(c.name)}</text><line x1="${r.x}" y1="${r.y + hh}" x2="${r.x + r.w}" y2="${r.y + hh}" class="uml-sep"/>` + attrs + `<line x1="${r.x}" y1="${r.y + hh + aH}" x2="${r.x + r.w}" y2="${r.y + hh + aH}" class="uml-sep"/>` + methods + `</g>`;
3662
+ s += `<g filter="url(#gshadow)"><rect x="${r.x}" y="${r.y}" width="${r.w}" height="${r.h}" rx="3" fill="var(--white)" stroke="var(--navy)" stroke-width="1.3"/>` + stereo + `<text x="${r.x + r.w / 2}" y="${nameY}" class="uml-name">${escapeHtml(c.name)}</text><line x1="${r.x}" y1="${r.y + hh}" x2="${r.x + r.w}" y2="${r.y + hh}" class="uml-sep"/>` + attrs + `<line x1="${r.x}" y1="${r.y + hh + aH}" x2="${r.x + r.w}" y2="${r.y + hh + aH}" class="uml-sep"/>` + methods + `</g>`;
3641
3663
  }
3664
+ s += labels.join("");
3642
3665
  s += `</svg>`;
3643
3666
  return diagramFrame(
3644
3667
  {
@@ -3964,13 +3987,13 @@ function renderGrid(data) {
3964
3987
  const groups = data.groups ?? [];
3965
3988
  const nodes = data.nodes ?? [];
3966
3989
  const edges = data.edges ?? [];
3967
- const cellW = 184;
3968
- const cellH = 82;
3969
- const gapX = 56;
3970
- const gapY = 58;
3971
- const padX = 26;
3972
- const padTop = 30;
3973
- const padBot = 20;
3990
+ const cellW = 178;
3991
+ const cellH = 80;
3992
+ const gapX = 54;
3993
+ const gapY = 60;
3994
+ const padX = 32;
3995
+ const padTop = 46;
3996
+ const padBot = 28;
3974
3997
  const cols = Math.max(
3975
3998
  1,
3976
3999
  ...nodes.map((n) => (n.col ?? 1) + ((n.w ?? 1) - 1)),
@@ -4011,13 +4034,15 @@ function renderGrid(data) {
4011
4034
  const label = isContainer ? `<rect x="${r.x + (r.w - badgeW) / 2}" y="${r.y - 1}" width="${badgeW}" height="20" rx="10" fill="${col}"/><text x="${r.x + r.w / 2}" y="${r.y + 13}" class="grp-label" fill="#fff" text-anchor="middle">${escapeHtml(g.label)}</text>` : `<path d="M${r.x} ${r.y + 20} L${r.x} ${r.y + 10} a10 10 0 0 1 10 -10 h${badgeW - 10} v20 z" fill="${col}"/><text x="${r.x + badgeW / 2}" y="${r.y + 14}" class="grp-label" fill="#fff" text-anchor="middle">${escapeHtml(g.label)}</text>`;
4012
4035
  s += `<g>${zone}${label}</g>`;
4013
4036
  }
4037
+ const labels = [];
4014
4038
  for (const e of edges) {
4015
4039
  const A2 = byId.get(e.from);
4016
4040
  const B2 = byId.get(e.to);
4017
4041
  if (!A2 || !B2) continue;
4018
4042
  const p2 = ortho(rectFor2(A2), rectFor2(B2));
4019
4043
  const st2 = GEDGE[e.kind ?? "solid"] ?? GEDGE["solid"] ?? FALLBACK_EDGE;
4020
- s += `<g><path d="${p2.d}" fill="none" stroke="${st2.stroke}" stroke-width="${st2.sw}" stroke-dasharray="${st2.dash}" marker-end="url(#${st2.marker})"/>` + edgePill(p2, e.label, st2.err) + `</g>`;
4044
+ s += `<path d="${p2.d}" fill="none" stroke="${st2.stroke}" stroke-width="${st2.sw}" stroke-dasharray="${st2.dash}" marker-end="url(#${st2.marker})"/>`;
4045
+ labels.push(edgePill(p2, e.label, st2.err));
4021
4046
  }
4022
4047
  for (const n of nodes) {
4023
4048
  const r = rectFor2(n);
@@ -4026,8 +4051,9 @@ function renderGrid(data) {
4026
4051
  const nx = gl.length > 0 ? r.x + 42 : r.x + 16;
4027
4052
  const chip = gl.length === 0 && n.kind !== void 0 ? `<text x="${r.x + 16}" y="${r.y + 22}" class="blk-chip" fill="${st2.accent}">${escapeHtml(n.kind)}</text>` : "";
4028
4053
  const tech = n.tech !== void 0 ? `<text x="${nx}" y="${r.y + (gl.length > 0 ? 50 : 60)}" class="blk-tech" fill="${st2.accent}">${escapeHtml(n.tech)}</text>` : "";
4029
- s += `<g filter="url(#gshadow)"><rect x="${r.x}" y="${r.y}" width="${r.w}" height="${r.h}" rx="9" fill="${st2.fill}" stroke="${st2.accent}" stroke-width="1.2"/><rect x="${r.x}" y="${r.y}" width="5" height="${r.h}" rx="2" fill="${st2.accent}"/>` + gl + chip + `<text x="${nx}" y="${r.y + (gl.length > 0 ? 34 : 44)}" class="blk-name" fill="${st2.text}">${escapeHtml(n.name)}</text>` + tech + `</g>`;
4054
+ s += `<g filter="url(#gshadow)"><path d="${rectRoundRight(r.x, r.y, r.w, r.h, 9)}" fill="${st2.fill}" stroke="${st2.accent}" stroke-width="1.2"/><rect x="${r.x}" y="${r.y}" width="5" height="${r.h}" fill="${st2.accent}"/>` + gl + chip + `<text x="${nx}" y="${r.y + (gl.length > 0 ? 34 : 44)}" class="blk-name" fill="${st2.text}">${escapeHtml(n.name)}</text>` + tech + `</g>`;
4030
4055
  }
4056
+ s += labels.join("");
4031
4057
  s += `</svg>`;
4032
4058
  return s;
4033
4059
  }
@@ -4069,22 +4095,24 @@ function renderLayered(data) {
4069
4095
  });
4070
4096
  });
4071
4097
  });
4072
- let s = `<svg viewBox="0 0 ${width} ${height}" role="img"><title>Layered architecture</title><rect x="${outerPad}" y="${outerPad}" width="${width - outerPad * 2}" height="${height - outerPad * 2}" rx="12" fill="none" stroke="#0e54a1" stroke-width="1.5"/>`;
4098
+ let s = `<svg viewBox="0 0 ${width} ${height}" role="img"><title>Layered architecture</title><rect x="${outerPad}" y="${outerPad}" width="${width - outerPad * 2}" height="${height - outerPad * 2}" rx="12" fill="none" stroke="var(--navy)" stroke-width="1.5"/>`;
4073
4099
  if (data.systemLabel !== void 0) {
4074
- s += `<text x="${outerPad + 14}" y="${outerPad + 18}" class="grp-label" fill="#0e54a1">${escapeHtml(data.systemLabel)}</text>`;
4100
+ s += `<text x="${outerPad + 14}" y="${outerPad + 18}" class="grp-label" fill="var(--navy)">${escapeHtml(data.systemLabel)}</text>`;
4075
4101
  }
4076
4102
  for (let i = 0; i < layers.length; i++) {
4077
4103
  const L2 = layers[i];
4078
4104
  if (L2 === void 0) continue;
4079
- s += `<g><rect x="${innerX}" y="${bandY(i)}" width="${labelW + bandInnerW}" height="${bandH}" rx="6" fill="#f3f4f6" stroke="#d1d5db"/><rect x="${innerX}" y="${bandY(i)}" width="${labelW}" height="${bandH}" rx="6" fill="#0e54a1"/><rect x="${innerX + labelW - 8}" y="${bandY(i)}" width="8" height="${bandH}" fill="#0e54a1"/><text x="${innerX + 14}" y="${bandY(i) + bandH / 2 + 4}" class="layer-label">${escapeHtml(L2.label)}</text></g>`;
4105
+ s += `<g><rect x="${innerX}" y="${bandY(i)}" width="${labelW + bandInnerW}" height="${bandH}" rx="6" fill="var(--light-gray)" stroke="var(--rule)"/><rect x="${innerX}" y="${bandY(i)}" width="${labelW}" height="${bandH}" rx="6" fill="var(--navy)"/><rect x="${innerX + labelW - 8}" y="${bandY(i)}" width="8" height="${bandH}" fill="var(--navy)"/><text x="${innerX + 14}" y="${bandY(i) + bandH / 2 + 4}" class="layer-label">${escapeHtml(L2.label)}</text></g>`;
4080
4106
  }
4107
+ const labels = [];
4081
4108
  for (const e of edges) {
4082
4109
  const A2 = rects.get(e.from);
4083
4110
  const B2 = rects.get(e.to);
4084
4111
  if (!A2 || !B2) continue;
4085
4112
  const p2 = ortho(A2, B2);
4086
4113
  const st2 = GEDGE[e.kind ?? "solid"] ?? GEDGE["solid"] ?? FALLBACK_EDGE;
4087
- s += `<g><path d="${p2.d}" fill="none" stroke="${st2.stroke}" stroke-width="${st2.sw}" stroke-dasharray="${st2.dash}" marker-end="url(#${st2.marker})"/>` + edgePill(p2, e.label, st2.err) + `</g>`;
4114
+ s += `<path d="${p2.d}" fill="none" stroke="${st2.stroke}" stroke-width="${st2.sw}" stroke-dasharray="${st2.dash}" marker-end="url(#${st2.marker})"/>`;
4115
+ labels.push(edgePill(p2, e.label, st2.err));
4088
4116
  }
4089
4117
  for (const n of nodes) {
4090
4118
  const r = rects.get(n.id);
@@ -4093,8 +4121,9 @@ function renderLayered(data) {
4093
4121
  const gl = nodeGlyph(n.kind, r.x + 12, r.y + 12, st2.accent);
4094
4122
  const nx = gl.length > 0 ? r.x + 34 : r.x + 14;
4095
4123
  const tech = n.tech !== void 0 ? `<text x="${nx}" y="${r.y + 42}" class="blk-tech" fill="${st2.accent}">${escapeHtml(n.tech)}</text>` : "";
4096
- s += `<g filter="url(#gshadow)"><rect x="${r.x}" y="${r.y}" width="${r.w}" height="${r.h}" rx="8" fill="${st2.fill}" stroke="${st2.accent}" stroke-width="1.2"/><rect x="${r.x}" y="${r.y}" width="5" height="${r.h}" rx="2" fill="${st2.accent}"/>` + gl + `<text x="${nx}" y="${r.y + (n.tech !== void 0 ? 26 : 33)}" class="blk-name" fill="${st2.text}">${escapeHtml(n.name)}</text>` + tech + `</g>`;
4124
+ s += `<g filter="url(#gshadow)"><path d="${rectRoundRight(r.x, r.y, r.w, r.h, 8)}" fill="${st2.fill}" stroke="${st2.accent}" stroke-width="1.2"/><rect x="${r.x}" y="${r.y}" width="5" height="${r.h}" fill="${st2.accent}"/>` + gl + `<text x="${nx}" y="${r.y + (n.tech !== void 0 ? 26 : 33)}" class="blk-name" fill="${st2.text}">${escapeHtml(n.name)}</text>` + tech + `</g>`;
4097
4125
  }
4126
+ s += labels.join("");
4098
4127
  s += `</svg>`;
4099
4128
  return s;
4100
4129
  }
@@ -4291,10 +4320,11 @@ function renderFelogicGraph(data, frame) {
4291
4320
  const noteY = r.y + (st2.stereo !== void 0 ? 56 : 52);
4292
4321
  const stroke = st2.solid === true ? "none" : st2.accent;
4293
4322
  const dashAttr = st2.dash !== void 0 ? ` stroke-dasharray="${st2.dash}"` : "";
4294
- const stripe = st2.solid === true ? "" : `<rect x="${r.x}" y="${r.y}" width="5" height="${r.h}" rx="2" fill="${st2.accent}"/>`;
4323
+ const stripe = st2.solid === true ? "" : `<rect x="${r.x}" y="${r.y}" width="5" height="${r.h}" fill="${st2.accent}"/>`;
4324
+ const card = st2.solid === true ? `<rect x="${r.x}" y="${r.y}" width="${r.w}" height="${r.h}" rx="9" fill="${st2.fill}" stroke="${stroke}" stroke-width="1.2"${dashAttr}/>` : `<path d="${rectRoundRight(r.x, r.y, r.w, r.h, 9)}" fill="${st2.fill}" stroke="${stroke}" stroke-width="1.2"${dashAttr}/>`;
4295
4325
  const stereo = st2.stereo !== void 0 ? `<text x="${r.x + r.w / 2}" y="${r.y + 20}" class="uml-stereo">\xAB${escapeHtml(st2.stereo)}\xBB</text>` : "";
4296
4326
  const note = n.note !== void 0 ? `<text x="${nx}" y="${noteY}" class="blk-tech" fill="${st2.solid === true ? "#cfe0f3" : st2.accent}" text-anchor="${anchor}">${escapeHtml(n.note)}</text>` : "";
4297
- s += `<g filter="url(#gshadow)"><rect x="${r.x}" y="${r.y}" width="${r.w}" height="${r.h}" rx="9" fill="${st2.fill}" stroke="${stroke}" stroke-width="1.2"${dashAttr}/>` + stripe + gl + stereo + `<text x="${nx}" y="${nameY}" class="blk-name" fill="${st2.text}" text-anchor="${anchor}">${escapeHtml(n.name)}</text>` + note + `</g>`;
4327
+ s += `<g filter="url(#gshadow)">` + card + stripe + gl + stereo + `<text x="${nx}" y="${nameY}" class="blk-name" fill="${st2.text}" text-anchor="${anchor}">${escapeHtml(n.name)}</text>` + note + `</g>`;
4298
4328
  }
4299
4329
  s += `</svg>`;
4300
4330
  return diagramFrame(