ndrstnd 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +56 -0
- package/dist/server/agent.d.ts +51 -0
- package/dist/server/agent.js +77 -0
- package/dist/server/agent.js.map +1 -0
- package/dist/server/analysis-core.d.ts +93 -0
- package/dist/server/analysis-core.js +442 -0
- package/dist/server/analysis-core.js.map +1 -0
- package/dist/server/analyze.d.ts +55 -0
- package/dist/server/analyze.js +72 -0
- package/dist/server/analyze.js.map +1 -0
- package/dist/server/artifact.d.ts +8 -0
- package/dist/server/artifact.js +43 -0
- package/dist/server/artifact.js.map +1 -0
- package/dist/server/claude.d.ts +29 -0
- package/dist/server/claude.js +243 -0
- package/dist/server/claude.js.map +1 -0
- package/dist/server/cli-support.d.ts +7 -0
- package/dist/server/cli-support.js +13 -0
- package/dist/server/cli-support.js.map +1 -0
- package/dist/server/cli.d.ts +2 -0
- package/dist/server/cli.js +276 -0
- package/dist/server/cli.js.map +1 -0
- package/dist/server/codex.d.ts +34 -0
- package/dist/server/codex.js +256 -0
- package/dist/server/codex.js.map +1 -0
- package/dist/server/conversation.d.ts +9 -0
- package/dist/server/conversation.js +57 -0
- package/dist/server/conversation.js.map +1 -0
- package/dist/server/evidence-ordering.d.ts +13 -0
- package/dist/server/evidence-ordering.js +143 -0
- package/dist/server/evidence-ordering.js.map +1 -0
- package/dist/server/git-model.d.ts +15 -0
- package/dist/server/git-model.js +156 -0
- package/dist/server/git-model.js.map +1 -0
- package/dist/server/git.d.ts +29 -0
- package/dist/server/git.js +124 -0
- package/dist/server/git.js.map +1 -0
- package/dist/server/http.d.ts +14 -0
- package/dist/server/http.js +139 -0
- package/dist/server/http.js.map +1 -0
- package/dist/server/preview-fixture.d.ts +1 -0
- package/dist/server/preview-fixture.js +23 -0
- package/dist/server/preview-fixture.js.map +1 -0
- package/dist/server/review-presentation.d.ts +3 -0
- package/dist/server/review-presentation.js +14 -0
- package/dist/server/review-presentation.js.map +1 -0
- package/dist/server/skill.d.ts +14 -0
- package/dist/server/skill.js +94 -0
- package/dist/server/skill.js.map +1 -0
- package/dist/server/store.d.ts +36 -0
- package/dist/server/store.js +134 -0
- package/dist/server/store.js.map +1 -0
- package/dist/server/version.d.ts +2 -0
- package/dist/server/version.js +13 -0
- package/dist/server/version.js.map +1 -0
- package/dist/shared/analysis-schema.d.ts +325 -0
- package/dist/shared/analysis-schema.js +50 -0
- package/dist/shared/analysis-schema.js.map +1 -0
- package/dist/shared/domain.d.ts +33 -0
- package/dist/shared/domain.js +2 -0
- package/dist/shared/domain.js.map +1 -0
- package/dist/web/evidence-model.d.ts +36 -0
- package/dist/web/evidence-model.js +134 -0
- package/dist/web/evidence-model.js.map +1 -0
- package/dist/web/frozen-review-data.d.ts +3 -0
- package/dist/web/frozen-review-data.js +202 -0
- package/dist/web/frozen-review-data.js.map +1 -0
- package/dist/web/language.d.ts +4 -0
- package/dist/web/language.js +14 -0
- package/dist/web/language.js.map +1 -0
- package/dist/web/page.d.ts +10 -0
- package/dist/web/page.js +1038 -0
- package/dist/web/page.js.map +1 -0
- package/dist/web/review-data.d.ts +20 -0
- package/dist/web/review-data.js +2 -0
- package/dist/web/review-data.js.map +1 -0
- package/dist/web/test-plan-model.d.ts +27 -0
- package/dist/web/test-plan-model.js +89 -0
- package/dist/web/test-plan-model.js.map +1 -0
- package/package.json +47 -0
- package/src/skill-assets/ndrstnd/SKILL.md +22 -0
- package/src/skill-assets/ndrstnd/agents/openai.yaml +4 -0
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ReviewPresentationData } from "./review-data.js";
|
|
2
|
+
export declare function renderArtifact(data: ReviewPresentationData): Promise<string>;
|
|
3
|
+
/**
|
|
4
|
+
* The ndrstnd galley system. One stylesheet, three typographic voices:
|
|
5
|
+
* sans speaks UI chrome, mono speaks identifiers, serif speaks the story.
|
|
6
|
+
* Light paper surfaces, hairline rules, a single cobalt accent, no gradients.
|
|
7
|
+
*/
|
|
8
|
+
export declare const styles = "\n:root{color-scheme:light dark;--sans:-apple-system,BlinkMacSystemFont,\"SF Pro Text\",\"Segoe UI\",system-ui,sans-serif;--mono:ui-monospace,\"SF Mono\",SFMono-Regular,Menlo,Consolas,monospace;--surface:#fff;--rail:#f6f6f4;--well:#fafaf8;--ink:#1c2126;--ink-2:#4a5258;--ink-3:#66707a;--faint:#6d7781;--hair:#e8e7e3;--hair-2:#d7d6d1;--accent:#2757cf;--wash:#eef2fb;--low:#2e8f53;--contained:#4d94c9;--elevated:#a97c15;--high:#b85f2e;--critical:#bf4840;--add-ink:#1c7a41;--add-bg:#eefaf1;--del-ink:#b04a3d;--del-bg:#fdf1ee;--shadow:0 18px 44px #191e2821}\n*{box-sizing:border-box}html{overflow-x:hidden}body{margin:0;min-width:320px;background:var(--surface);color:var(--ink);font:13px/1.5 var(--sans);-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility}\n[hidden]{display:none!important}\n::selection{background:#d9e3f8}\nbutton{font-family:inherit}\nbutton:focus-visible,select:focus-visible,summary:focus-visible,[role=\"button\"]:focus-visible{outline:2px solid var(--accent);outline-offset:2px}\n\n.app-shell{display:grid;grid-template-columns:236px minmax(0,1fr) 264px;min-height:100vh;transition:grid-template-columns 220ms ease}\n.app-shell.sidebar-collapsed{grid-template-columns:64px minmax(0,1fr) 264px}\n.app-shell.inspector-collapsed{grid-template-columns:236px minmax(0,1fr) 64px}\n.app-shell.sidebar-collapsed.inspector-collapsed{grid-template-columns:64px minmax(0,1fr) 64px}\n\n.sidebar{position:sticky;top:0;height:100vh;background:var(--rail);border-right:1px solid var(--hair);padding:20px 14px;overflow:hidden}\n.brand{display:flex;align-items:center;gap:9px;padding:2px 6px 24px}\n.brand-mark{width:19px;height:21px;flex:none;color:var(--ink)}\n.brand-mark path{fill:none;stroke:currentColor;stroke-width:2.2;stroke-linecap:round;stroke-linejoin:round}\n.brand-mark .mark-deep{stroke:var(--accent)}\n.brand-name{font:600 14px/1 var(--mono);letter-spacing:-.02em;color:var(--ink)}\n.panel-toggle{display:grid;place-items:center;width:30px;height:30px;flex:none;padding:0;border:0;border-radius:7px;background:transparent;color:var(--ink-3);cursor:pointer;transition:background-color 140ms ease,color 140ms ease,transform 200ms ease}\n.panel-toggle svg{width:16px;height:16px;fill:none;stroke:currentColor;stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round}\n.panel-toggle:hover{background:#ebebe8;color:var(--ink)}\n.collapse-sidebar{margin-left:auto}\n.mobile-inspector-toggle{display:none}\n.sidebar nav{display:grid;gap:2px}\n.nav-item{position:relative;display:flex;align-items:center;gap:10px;width:100%;min-height:38px;padding:9px 10px;border:0;border-radius:7px;background:transparent;color:var(--ink-2);font:500 13px/1.2 var(--sans);text-align:left;cursor:pointer;transition:background-color 140ms ease,color 140ms ease}\n.nav-icon{display:grid;place-items:center;width:18px;height:18px;flex:none}\n.nav-icon svg{display:block;width:17px;height:17px;fill:none;stroke:currentColor;stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round}\n.nav-item:hover{background:#ecece9;color:var(--ink)}\n.nav-item.active{color:var(--accent)}\n.nav-item.active::before{content:\"\";position:absolute;left:-14px;top:9px;bottom:9px;width:2px;border-radius:2px;background:var(--accent)}\n.sidebar.collapsed{padding:20px 10px}\n.sidebar.collapsed .brand{flex-direction:column;gap:12px;padding:2px 0 20px}\n.sidebar.collapsed .brand-name{display:none}\n.sidebar.collapsed .collapse-sidebar{margin:0;transform:rotate(180deg)}\n.sidebar.collapsed .nav-item{justify-content:center;gap:0;min-height:42px;padding:10px 0;font-size:0}\n.sidebar.collapsed .nav-item.active::before{left:-11px}\n\n.main{min-width:0;width:100%;max-width:1040px;margin:0 auto;padding:38px 44px 96px}\n.page-header{border-bottom:1px solid var(--hair);padding:0 280px 20px 0}\n.masthead{min-width:0}\n.masthead-overline{margin:0 0 12px;font:600 10px/1 var(--mono);letter-spacing:.16em;text-transform:uppercase;color:var(--ink-3)}\n.page-header h1{margin:0 0 9px;font:600 22px/1.3 var(--mono);letter-spacing:-.02em;color:var(--ink);word-break:break-word}\n.breadcrumbs{display:flex;flex-wrap:wrap;align-items:center;gap:14px;font-size:12px;color:var(--ink-3)}\n.breadcrumbs strong{color:var(--ink-2);font-weight:600}\n.breadcrumbs code{font:500 11.5px var(--mono);color:var(--ink-2);background:var(--well);border:1px solid var(--hair);border-radius:6px;padding:2px 6px}\n.view-bar{position:sticky;top:0;z-index:15;height:0;pointer-events:none}\n.view-bar::before{content:\"\";position:absolute;top:0;left:-44px;right:-44px;height:62px;background:var(--surface);border-bottom:1px solid var(--hair);box-shadow:0 6px 20px #191e280f;opacity:0;transition:opacity 200ms ease}\n.view-bar.view-bar-stuck::before{opacity:1;pointer-events:auto}\n.view-bar .story-zoom-controls{position:absolute;top:-112px;right:0;pointer-events:auto;transition:top 240ms cubic-bezier(.2,.8,.2,1)}\n.view-bar.view-bar-stuck .story-zoom-controls{top:5px}\n.view-bar-ref{position:absolute;left:0;top:20px;max-width:40%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font:600 11.5px/1.4 var(--mono);color:var(--ink-3);opacity:0;transition:opacity 200ms ease}\n.view-bar.view-bar-stuck .view-bar-ref{opacity:1}\n\n.story-zoom-controls{position:relative;display:flex;align-items:flex-start;gap:2px;height:52px;padding-top:2px}\n.story-zoom-controls[hidden]{display:none!important}\n.story-zoom-controls>button[data-zoom-step]{width:30px;height:30px;border:0;border-radius:8px;background:transparent;color:var(--ink-3);font:400 17px/1 var(--sans);cursor:pointer;transition:background-color 140ms ease,color 140ms ease}\n.story-zoom-controls>button[data-zoom-step]:hover{background:var(--well);color:var(--ink)}\n.zoom{position:relative;display:flex;align-items:flex-end;justify-content:space-between;width:186px;height:30px;padding:0 5px;border:0}\n.zoom::before{content:\"\";position:absolute;left:9px;right:9px;bottom:3px;height:1px;background:var(--hair-2)}\n.zoom button{position:relative;z-index:1;width:24px;height:30px;min-height:0;padding:0;border:0;background:transparent;cursor:pointer}\n.zoom button::before{content:\"\";position:absolute;left:50%;bottom:3px;width:2px;height:9px;border-radius:1px 1px 0 0;background:var(--hair-2);transform:translateX(-50%);transition:background-color 160ms ease,height 200ms cubic-bezier(.3,1.3,.4,1),width 160ms ease}\n.zoom button:hover::before{background:var(--ink-3);height:13px}\n.zoom button.active::before{background:var(--accent);height:17px;width:2.5px}\n.zoom button::after{content:\"\";position:absolute;left:50%;bottom:23px;width:5px;height:5px;border-radius:50%;background:var(--accent);transform:translateX(-50%) scale(0);opacity:0;transition:transform 200ms cubic-bezier(.3,1.3,.4,1),opacity 160ms ease}\n.zoom button.active::after{opacity:1;transform:translateX(-50%) scale(1)}\n.zoom-callout{position:absolute;left:50%;top:calc(100% + 3px);transform:translateX(-50%);white-space:nowrap;text-align:center;pointer-events:none;transition:opacity 160ms ease}\n.zoom-callout output{font:700 10px/1 var(--mono);letter-spacing:.14em;text-transform:uppercase;color:var(--accent)}\n.zoom-callout span{margin-left:8px;font:400 11px/1 var(--sans);color:var(--ink-3)}\n.zoom.is-changing .zoom-callout{opacity:.45}\n\n.view{display:none}\n.view.active{display:block;animation:view-in 240ms ease}\n.review-summary{margin:30px 0 10px;max-width:42em;font:400 20px/1.55 var(--sans);letter-spacing:-.01em;color:var(--ink)}\n.coverage{margin:0 0 22px;font-size:12px;color:var(--ink-3);font-variant-numeric:tabular-nums}\n.story-toolbar{display:flex;align-items:center;justify-content:space-between;gap:12px;margin:0 0 12px}\n.map{display:flex;flex-wrap:wrap;gap:8px 18px}\n.map div{display:inline-flex;align-items:center;gap:7px;font:500 11px/1 var(--sans);letter-spacing:.02em;color:var(--ink-2);text-transform:capitalize}\n.map strong{color:var(--ink);font-weight:600;font-variant-numeric:tabular-nums}\n.dot{width:7px;height:7px;border-radius:50%;background:var(--low)}\n.dot.contained{background:var(--contained)}.dot.elevated{background:var(--elevated)}.dot.high{background:var(--high)}.dot.critical{background:var(--critical)}\n#collapse-all{margin-left:auto;border:0;border-radius:7px;background:transparent;min-height:30px;padding:6px 10px;font:500 12px var(--sans);color:var(--ink-3);cursor:pointer;transition:background-color 140ms ease,color 140ms ease}\n#collapse-all:hover{background:var(--well);color:var(--ink)}\nbody.story-level-0 #collapse-all,body.story-level-1 #collapse-all{display:none}\n\n.chapter-list{border:1px solid var(--hair);border-radius:12px;background:var(--surface);overflow:hidden}\n.chapter{border-bottom:1px solid var(--hair)}\n.chapter:last-child{border-bottom:0}\n.chapter-toggle{display:grid;grid-template-columns:46px minmax(0,1fr) 18px;align-items:start;gap:12px;width:100%;padding:17px 18px 15px;border:0;background:transparent;text-align:left;cursor:pointer;transition:background-color 140ms ease}\n.chapter-toggle:hover,.chapter.open .chapter-toggle{background:var(--well)}\n.chapter-number{position:relative;font:700 12.5px/1 var(--mono);letter-spacing:.08em;color:var(--ink-3);padding:6px 0 15px}\n.chapter-number::after{content:\"\";position:absolute;left:1px;bottom:2px;width:16px;height:3px;border-radius:2px;background:var(--hair-2)}\n.chapter-number.attention-low{color:var(--low)}\n.chapter-number.attention-contained{color:var(--contained)}\n.chapter-number.attention-elevated{color:var(--elevated)}\n.chapter-number.attention-high{color:var(--high)}\n.chapter-number.attention-critical{color:var(--critical)}\n.chapter-number.attention-low::after{background:var(--low)}\n.chapter-number.attention-contained::after{background:var(--contained)}\n.chapter-number.attention-elevated::after{background:var(--elevated)}\n.chapter-number.attention-high::after{background:var(--high)}\n.chapter-number.attention-critical::after{background:var(--critical)}\n.chapter-copy{display:grid;gap:4px;min-width:0}\n.chapter-copy strong{font:600 14.5px/1.4 var(--sans);color:var(--ink)}\n.chapter-copy small{font:400 12.5px/1.5 var(--sans);color:var(--ink-3)}\n.chapter-tags,.chapter-steps{display:flex;flex-wrap:wrap;gap:5px 6px;margin-top:8px}\n.chapter-tag{display:inline-flex;align-items:center;gap:5px;padding:4px 9px;border:1px solid var(--hair);border-radius:999px;background:var(--surface);font:600 9.5px/1 var(--mono);letter-spacing:.12em;text-transform:uppercase;color:var(--ink-3)}\n.step-chip,.evidence-step-tag{display:inline-flex;align-items:center;min-height:22px;padding:3px 8px;border:0;border-radius:7px;background:var(--well);font:700 9.5px/1 var(--mono);letter-spacing:.1em;text-transform:uppercase;color:var(--accent);cursor:pointer}\n.step-chip:hover,.evidence-step-tag:hover{background:var(--wash)}\n.tag-icon{width:12px;height:12px;fill:none;stroke:currentColor;stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round}\n.chevron{display:grid;place-items:center;width:18px;height:18px;margin-top:3px;color:var(--faint);transition:transform 200ms ease,color 140ms ease}\n.chevron svg{width:12px;height:12px;fill:none;stroke:currentColor;stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round}\n.chapter-toggle:hover .chevron{color:var(--ink-2)}\n.chapter.open .chevron{transform:rotate(180deg)}\n.chapter-list,.map,.chapter-detail,.semantic,.evidence-stack,.evidence{transition:opacity 220ms ease,transform 220ms ease,max-height 260ms ease,margin 220ms ease,padding 220ms ease}\n.chapter-detail{max-height:0;opacity:0;overflow:hidden;padding:0 18px 0 76px;transform:translateY(-4px)}\n.chapter.open .chapter-detail{max-height:4000px;opacity:1;padding-top:2px;padding-bottom:22px;transform:none}\n\n.raw-code,.raw-label{display:none}\n.story-level-0 .chapter-list{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:14px;border:0;border-radius:0;background:transparent;overflow:visible;pointer-events:none}\n.story-level-0 .chapter{border:1px solid var(--hair);border-radius:12px;background:var(--surface);animation:rise 240ms ease both}\n.story-level-0 .chapter:nth-child(2){animation-delay:35ms}\n.story-level-0 .chapter:nth-child(3){animation-delay:70ms}\n.story-level-0 .chapter:nth-child(4){animation-delay:105ms}\n.story-level-0 .chapter:nth-child(5){animation-delay:140ms}\n.story-level-0 .chapter:nth-child(n+6){animation-delay:175ms}\n.story-level-0 .chapter-toggle{grid-template-columns:38px minmax(0,1fr);gap:12px;min-height:132px;padding:16px;cursor:default}\n.story-level-0 .chapter-toggle:hover{background:transparent}\n.story-level-0 .chapter-copy{min-height:96px;gap:7px}\n.story-level-0 .chapter-copy strong{font-size:15px}\n.story-level-0 .chapter-copy small{display:none}\n.story-level-0 .chevron{display:none}\n.story-level-0 .chapter-detail{display:none!important}\n.chapter-map-meta,.chapter-churn-bar{display:none}\n.story-level-0 .chapter-map-meta{display:flex;align-items:center;flex-wrap:wrap;gap:6px 10px;margin-top:auto;font:400 10.5px/1.3 var(--mono);color:var(--ink-3)}\n.story-level-0 .chapter-churn{display:flex;gap:7px;font:600 11px/1.2 var(--mono)}\n.story-level-0 .chapter-map-meta .additions{color:var(--add-ink)}\n.story-level-0 .chapter-map-meta .deletions{color:var(--del-ink)}\n.story-level-0 .chapter-churn-bar{display:flex;width:100%;height:3px;margin-top:4px;overflow:hidden;border-radius:999px;background:var(--hair)}\n.story-level-0 .chapter-churn-bar i{display:block}\n.story-level-0 .chapter-churn-bar .additions{width:calc(var(--add) * 1%);background:#79bd93}\n.story-level-0 .chapter-churn-bar .deletions{width:calc(var(--delete) * 1%);background:#dd9d92}\n.story-level-0 .map{animation:rise 240ms ease both}\n.zoom-revealed{animation:story-enter 260ms ease both}\n.story-level-1 .chapter-toggle{cursor:default}\n.story-level-1 .chapter-toggle:hover{background:transparent}\n.story-level-1 .chapter-detail{max-height:0!important;opacity:0!important;padding-top:0!important;padding-bottom:0!important;transform:translateY(-4px)!important}\n.story-level-1 .chevron{display:none}\n.story-level-2 .evidence-stack{display:none}\n.story-level-3 .evidence pre{max-height:238px;overflow-y:auto}\n.story-level-4 .focused-code,.story-level-4 .focused-label,.story-level-4 .evidence-context{display:none}\n.story-level-4 .raw-code{display:block}\n.story-level-4 .raw-label{display:inline}\n\n.semantic{display:grid;grid-template-columns:1fr 1fr;gap:22px;padding:14px 0 16px;border-bottom:1px solid var(--hair);margin-bottom:14px}\n.semantic>div+div{border-left:1px solid var(--hair);padding-left:22px}\n.semantic strong{display:block;font:600 10px/1 var(--mono);letter-spacing:.14em;text-transform:uppercase;color:var(--ink-3)}\n.semantic p{margin:7px 0 0;font:400 13px/1.6 var(--sans);color:var(--ink-2)}\n.evidence{border:1px solid var(--hair);border-radius:10px;overflow:hidden;margin-top:12px;background:var(--surface)}\n.evidence header{display:flex;justify-content:space-between;align-items:baseline;gap:14px;padding:8px 12px;border-bottom:1px solid var(--hair);background:var(--well);font:400 11px/1.4 var(--mono);color:var(--ink-3)}\n.evidence-path{font-weight:600;color:var(--ink-2);min-width:0;overflow-wrap:anywhere}\n.evidence pre{margin:0;padding:8px 0;background:var(--surface);overflow-x:auto;-webkit-overflow-scrolling:touch;font:12px/1.6 var(--mono)}\n.line{display:grid;grid-template-columns:40px 40px 1fr;min-width:max-content;padding:0 12px}\n.line b{font-weight:400;font-size:11px;color:var(--faint);text-align:right;padding-right:10px;user-select:none;font-variant-numeric:tabular-nums}\n.line code{font:inherit;color:#24292e}\n.line.addition{background:var(--add-bg)}\n.line.deletion{background:var(--del-bg)}\n.diff-prefix{display:inline-block;width:1.2ch;color:var(--faint);user-select:none}\n.line.addition .diff-prefix{color:var(--add-ink)}\n.line.deletion .diff-prefix{color:var(--del-ink)}\n.token-italic{font-style:italic}\n.line.omission{display:block;min-width:0;padding:4px 12px}\n.omission-divider{display:flex;align-items:center;gap:8px;color:var(--faint)}\n.omission-divider i{height:0;flex:1;border-top:1px dashed var(--hair-2)}\n.omission-divider b{font:600 12px/1 var(--mono);letter-spacing:-2px}\n.evidence-context{margin:0;padding:6px 12px;border-top:1px solid var(--hair);background:var(--well);font-size:10.5px;color:var(--ink-3)}\n.omitted{margin-top:16px;border:1px dashed var(--hair-2);border-radius:10px;padding:12px 14px;color:var(--ink-3);font-size:12px}\n.omitted summary{cursor:pointer;color:var(--ink-2);font-weight:500}\n.omitted p{margin:8px 0 0;line-height:1.5}\n.omitted strong{color:var(--ink-2)}\n.other-files{margin-top:16px;border:1px solid var(--hair);border-radius:12px;overflow:hidden;background:var(--surface)}\n.other-files h2{margin:0;padding:11px 14px;border-bottom:1px solid var(--hair);background:var(--well);font:600 10px/1 var(--mono);letter-spacing:.14em;text-transform:uppercase;color:var(--ink-3)}\n.other-files ul{margin:0;padding:0;list-style:none}\n.other-files li{display:flex;align-items:center;justify-content:space-between;gap:12px;min-height:38px;padding:9px 14px;font:12px/1.3 var(--mono);color:var(--ink-2)}\n.other-files li>span{min-width:0;overflow-wrap:anywhere}\n.other-files li+li{border-top:1px solid var(--hair)}\n.other-files small{display:flex;gap:8px;font:600 11px/1 var(--mono);font-variant-numeric:tabular-nums}\n.other-files .additions{color:var(--add-ink)}\n.other-files .deletions{color:var(--del-ink)}\n\n.section-title{margin:30px 0 6px;font:600 10px/1 var(--mono);letter-spacing:.16em;text-transform:uppercase;color:var(--ink-3)}\n.timeline{position:relative;margin-top:16px}\n.timeline-rail{position:sticky;top:70px;z-index:10;display:grid;grid-template-columns:30px minmax(0,1fr) 30px;align-items:center;column-gap:8px;margin:0 0 16px;padding:9px 12px 7px;border:1px solid var(--hair);border-radius:12px;background:var(--surface)}\n.rail-nav{display:grid;place-items:center;width:30px;height:30px;border:0;border-radius:8px;background:transparent;color:var(--ink-3);cursor:pointer;transition:background-color 140ms ease,color 140ms ease}\n.rail-nav:hover{background:var(--well);color:var(--ink)}\n.rail-nav[disabled]{opacity:.35;cursor:default}\n.rail-nav[disabled]:hover{background:transparent;color:var(--ink-3)}\n.rail-nav svg{width:14px;height:14px;fill:none;stroke:currentColor;stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round}\n.rail-ticks{position:relative;display:flex;align-items:flex-end;height:28px;min-width:0}\n.rail-ticks::before{content:\"\";position:absolute;left:2px;right:2px;bottom:4px;height:1px;background:var(--hair-2)}\n.rail-tick{position:relative;flex:1;min-width:4px;height:28px;padding:0;border:0;background:transparent;cursor:pointer}\n.rail-tick::before{content:\"\";position:absolute;left:50%;bottom:4px;width:2px;height:9px;border-radius:1px 1px 0 0;background:var(--hair-2);transform:translateX(-50%);transition:background-color 160ms ease,height 200ms cubic-bezier(.3,1.3,.4,1),width 160ms ease}\n.rail-tick.attention-low::before{background:var(--low)}\n.rail-tick.attention-contained::before{background:var(--contained)}\n.rail-tick.attention-elevated::before{background:var(--elevated)}\n.rail-tick.attention-high::before{background:var(--high)}\n.rail-tick.attention-critical::before{background:var(--critical)}\n.rail-tick:hover::before{height:13px}\n.rail-tick.active::before{background:var(--accent);height:17px;width:2.5px}\n.rail-readout{grid-column:1/-1;display:flex;align-items:baseline;gap:10px;margin:4px 2px 0!important;max-width:none!important;min-width:0}\n.rail-readout output{flex:none;font:700 10px/1 var(--mono);letter-spacing:.14em;color:var(--accent);font-variant-numeric:tabular-nums}\n.rail-readout span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font:500 11.5px/1.3 var(--sans);color:var(--ink-2)}\n.timeline-plan{position:relative;display:none}\n.timeline-plan::before{content:\"\";position:absolute;left:9px;top:26px;bottom:26px;width:1px;background:var(--hair)}\n.timeline-plan-step{position:relative;display:grid;grid-template-columns:40px minmax(0,1fr);gap:12px;width:100%;padding:15px 2px 15px 30px;border:0;border-bottom:1px solid var(--hair);background:transparent;text-align:left;cursor:pointer}\n.timeline-plan-step:last-child{border-bottom:0}\n.timeline-plan-step::before{content:\"\";position:absolute;left:5.5px;top:21px;width:8px;height:8px;border-radius:50%;background:var(--low);box-shadow:0 0 0 3px var(--surface)}\n.timeline-plan-step.attention-contained::before{background:var(--contained)}\n.timeline-plan-step.attention-elevated::before{background:var(--elevated)}\n.timeline-plan-step.attention-high::before{background:var(--high)}\n.timeline-plan-step.attention-critical::before{background:var(--critical)}\n.timeline-plan-step>span{padding-top:2px;font:700 12.5px/1 var(--mono);letter-spacing:.08em;color:var(--low)}\n.timeline-plan-step.attention-contained>span{color:var(--contained)}\n.timeline-plan-step.attention-elevated>span{color:var(--elevated)}\n.timeline-plan-step.attention-high>span{color:var(--high)}\n.timeline-plan-step.attention-critical>span{color:var(--critical)}\n.timeline-plan-step strong{display:block;font:600 14.5px/1.4 var(--sans);color:var(--ink);transition:color 140ms ease}\n.timeline-plan-step p{margin:3px 0 0}\n.timeline-plan-step:hover strong{color:var(--accent)}\n.timeline-state{display:none}\n.timeline-state.active{display:block}\n.timeline-card{display:grid;grid-template-columns:44px minmax(0,1fr);gap:12px;padding:16px 0;border-top:1px solid var(--hair);border-bottom:1px solid var(--hair)}\n.timeline-card h2{margin:0 0 6px;font:600 16px/1.35 var(--sans);color:var(--ink)}\n.timeline-index{font:700 12.5px/1 var(--mono);letter-spacing:.08em;color:var(--ink-3);padding-top:5px}\n.timeline-index.attention-low{color:var(--low)}\n.timeline-index.attention-contained{color:var(--contained)}\n.timeline-index.attention-elevated{color:var(--elevated)}\n.timeline-index.attention-high{color:var(--high)}\n.timeline-index.attention-critical{color:var(--critical)}\n.timeline p{margin:0;max-width:60em;font:400 12.5px/1.55 var(--sans);color:var(--ink-3)}\n.timeline-summary,.timeline-explanation{border:1px solid var(--hair);border-radius:10px;background:var(--surface);padding:14px;margin-top:14px}\n.timeline-summary strong,.timeline-explanation h3{display:block;margin:0 0 7px;font:700 10px/1 var(--mono);letter-spacing:.14em;text-transform:uppercase;color:var(--ink-3)}\n.timeline-summary p{color:var(--ink-2)}\n.timeline-explanation{grid-template-columns:1fr 1fr;gap:18px}\n.timeline-explanation section+section{border-left:1px solid var(--hair);padding-left:18px}\n.timeline-explanation ul{margin:0;padding-left:18px;color:var(--ink-2)}\n.timeline-explanation li{margin:4px 0;font-size:12.5px}\n.timeline-explanation button,.timeline-chapter-links button{border:0;border-radius:7px;background:var(--well);min-height:24px;padding:4px 8px;color:var(--accent);font:600 11px/1 var(--sans);cursor:pointer}\n.timeline-chapter-links{display:flex;flex-wrap:wrap;gap:6px;margin-top:10px}\n.timeline-evidence,.timeline-raw{margin-top:14px}\n.timeline-evidence-divider{margin:20px 0 2px!important;font:600 10px/1 var(--mono)!important;letter-spacing:.14em;text-transform:uppercase;color:var(--ink-3)!important}\n.timeline-evidence-item{opacity:.62}\n.timeline-evidence-item.current{opacity:1}\n.timeline-evidence-item.current .evidence{border-color:#c9d5f5;box-shadow:0 0 0 1px #d9e3f8}\n.timeline-summary,.timeline-explanation,.timeline-evidence,.timeline-raw{display:none}\n.story-level-0 #timeline .timeline-rail{display:none}\n.story-level-0 #timeline .timeline-plan{display:block}\n.story-level-0 #timeline .timeline-states{display:none}\n.story-level-1 #timeline .timeline-summary{display:block}\n.story-level-2 #timeline .timeline-summary{display:block}\n.story-level-2 #timeline .timeline-explanation{display:grid}\n.story-level-3 #timeline .timeline-explanation{display:grid}\n.story-level-3 #timeline .timeline-evidence{display:block}\n.story-level-4 #timeline .timeline-raw{display:block}\n.timeline-files{display:flex;flex-direction:column;gap:4px;margin-top:10px}\n.timeline-file{display:flex;align-items:center;gap:12px;font:11px/1.4 var(--mono);color:var(--ink-2)}\n.timeline-file>span{min-width:0;overflow-wrap:anywhere}\n.timeline-file small{display:flex;gap:7px;font:600 10.5px/1 var(--mono)}\n.timeline-file .additions{color:var(--add-ink)}\n.timeline-file .deletions{color:var(--del-ink)}\n\n.file{border:1px solid var(--hair);border-radius:12px;margin:12px 0;overflow:hidden;background:var(--surface)}\n.file>summary{display:flex;align-items:center;gap:12px;padding:11px 14px;background:var(--well);cursor:pointer;list-style:none}\n.file>summary::-webkit-details-marker{display:none}\n.file-path{font:600 12px/1.4 var(--mono);color:var(--ink-2);min-width:0;overflow-wrap:anywhere}\n.file>summary small{margin-left:auto;flex:none;color:var(--ink-3);font-size:11.5px}\n.file>summary::after{content:\"\";width:7px;height:7px;flex:none;margin-top:-2px;border-right:1.6px solid var(--ink-3);border-bottom:1.6px solid var(--ink-3);transform:rotate(-45deg);transition:transform 180ms ease}\n.file[open]>summary::after{margin-top:-4px;transform:rotate(45deg)}\n.diff-block{border-top:1px solid var(--hair)}\n.diff-hunk-header{padding:6px 12px;background:var(--well);border-bottom:1px solid var(--hair);font:11px/1.4 var(--mono);color:var(--ink-3)}\n.diff-block pre{margin:0;padding:8px 0;overflow-x:auto;-webkit-overflow-scrolling:touch;font:12px/1.6 var(--mono)}\n\n.test-plan-subtitle,.view-subtitle{margin:8px 0 18px;max-width:56em;font:400 13px/1.6 var(--sans);color:var(--ink-2)}\n.test-plan-summary{display:flex;flex-wrap:wrap;gap:7px;margin:0 0 18px}\n.test-plan-summary span,.test-inline-meta span,.test-theme-meta span,.test-refs span,.test-state{display:inline-flex;align-items:center;min-height:24px;padding:3px 10px;border:1px solid var(--hair);border-radius:999px;background:var(--surface);color:var(--ink-2);font:500 11px/1.2 var(--sans);font-variant-numeric:tabular-nums}\n.test-plan-level{display:none}\n.story-level-0 #tests .test-plan-map,.story-level-1 #tests .test-plan-summary-level,.story-level-2 #tests .test-plan-explanation,.story-level-3 #tests .test-plan-evidence,.story-level-4 #tests .test-plan-raw{display:block}\n.test-generated-summary{margin:0 0 14px;max-width:56em;font:400 13px/1.6 var(--sans);color:var(--ink-2)}\n.test-theme-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:14px}\n.test-theme-card{display:flex;flex-direction:column;min-height:128px;border:1px solid var(--hair);border-radius:12px;background:var(--surface);padding:16px}\n.test-theme-card h2{margin:0 0 6px;font:600 14px/1.4 var(--sans);color:var(--ink)}\n.test-theme-card p{margin:0;font:400 12.5px/1.5 var(--sans);color:var(--ink-3)}\n.test-theme-meta{display:flex;flex-wrap:wrap;gap:6px;margin-top:auto;padding-top:14px}\n.test-behavior-group,.test-explanation-group,.test-raw-section{border:1px solid var(--hair);border-radius:12px;background:var(--surface);margin:0 0 14px;padding:16px}\n.test-behavior-group h2,.test-explanation-group h2{margin:0 0 8px;font:600 14px/1.4 var(--sans);color:var(--ink)}\n.test-raw-section>h2{margin:0 0 8px;font:600 10px/1 var(--mono);letter-spacing:.14em;text-transform:uppercase;color:var(--ink-3)}\n.test-behavior{border-top:1px solid var(--hair);padding:12px 0}\n.test-behavior:first-of-type{border-top:0}\n.test-behavior button{display:grid;gap:4px;width:100%;border:0;background:transparent;padding:0;text-align:left;cursor:pointer}\n.test-behavior button:hover strong{color:var(--accent)}\n.test-behavior strong,.test-evidence-card summary strong{font:600 13.5px/1.4 var(--sans);color:var(--ink);transition:color 140ms ease}\n.test-behavior button span,.test-evidence-card summary small{font:400 12px/1.5 var(--sans);color:var(--ink-3)}\n.test-inline-meta{display:flex;flex-wrap:wrap;gap:6px;margin-top:9px}\n.test-explanation-card{border-top:1px solid var(--hair);padding:14px 0}\n.test-explanation-card:first-of-type{border-top:0}\n.test-explanation-card h3{margin:0 0 10px;font:600 13.5px/1.4 var(--sans);color:var(--ink)}\n.test-explanation-card .semantic{margin:0 0 12px;padding-top:0}\n.test-what{margin:0 0 12px;max-width:56em;font:400 13px/1.6 var(--sans);color:var(--ink-2)}\n.test-refs{display:flex;flex-wrap:wrap;gap:6px}\n.test-ref-file{font-family:var(--mono);font-size:10.5px;min-width:0;overflow-wrap:anywhere}\n.test-evidence-card{border:1px solid var(--hair);border-radius:12px;background:var(--surface);margin:0 0 12px;overflow:hidden}\n.test-evidence-card summary{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:12px 14px;cursor:pointer;background:var(--well);list-style:none}\n.test-evidence-card summary::-webkit-details-marker{display:none}\n.test-evidence-card summary>span:first-child{display:grid;gap:3px;min-width:0}\n.test-evidence-card .evidence{border-left:0;border-right:0;border-bottom:0;border-radius:0;margin:0}\n.test-evidence-meta{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:10px;padding:12px 14px;border-top:1px solid var(--hair)}\n.test-evidence-meta div{display:grid;gap:3px}\n.test-evidence-meta strong{font:600 10px/1.4 var(--mono);letter-spacing:.12em;text-transform:uppercase;color:var(--ink-3)}\n.test-evidence-meta span{font-size:12px;color:var(--ink-2)}\n.test-raw-artifact{margin:12px 0 0}\n.test-raw-artifact h2{margin:0 0 8px;font:600 12px/1.4 var(--mono);color:var(--ink-2);overflow-wrap:anywhere}\n.test-raw-section .empty-note{margin:4px 0 0}\n.test-run{display:flex;flex-wrap:wrap;align-items:baseline;gap:8px;margin:8px 0;font:12.5px/1.5 var(--sans);color:var(--ink-2)}\n.test-run code{font:11.5px var(--mono);color:var(--ink)}\n.test-run p{margin:0;flex-basis:100%}\n.test-run small{color:var(--ink-3)}\n.run-outcome{font:600 11px/1 var(--sans);text-transform:uppercase;letter-spacing:.04em}\n.run-outcome-passed{color:var(--low)}\n.run-outcome-failed{color:var(--critical)}\n.run-outcome-mixed,.run-outcome-unknown{color:var(--elevated)}\n.empty-note{font:400 12.5px/1.5 var(--sans);color:var(--ink-3)}\n\n.inspector{position:sticky;top:0;height:100vh;overflow-y:auto;background:var(--rail);border-left:1px solid var(--hair);padding:22px 20px}\n.inspector-header{display:flex;align-items:center;justify-content:space-between;gap:10px;min-height:30px}\n.inspector h2{margin:0;font:600 13px/1.2 var(--sans);color:var(--ink)}\n.inspector-content{min-width:0}\n.inspector section{padding:18px 0;border-bottom:1px solid var(--hair)}\n.inspector section:last-of-type{border-bottom:0}\n.inspector h3{margin:0 0 10px;font:600 10px/1 var(--mono);letter-spacing:.14em;text-transform:uppercase;color:var(--ink-3)}\n.stat-row{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:5px 0;font-size:12.5px;color:var(--ink-2);font-variant-numeric:tabular-nums}\n.stat-row>span{display:inline-flex;align-items:center;gap:8px;min-width:0}\n.stat-category>span{text-transform:capitalize}\n.stat-row strong{font:600 12px/1.4 var(--mono);color:var(--ink)}\n.stat-row .tag-icon{width:14px;height:14px;flex:none;color:var(--ink-3)}\n.inspector-action{display:flex;align-items:center;gap:9px;width:100%;min-height:36px;margin-top:8px;padding:8px 11px;border:0;border-radius:8px;background:#ecece9;color:var(--ink);font:500 12.5px/1.2 var(--sans);cursor:pointer;transition:background-color 140ms ease}\n.inspector-action:first-of-type{margin-top:0}\n.inspector-action:hover{background:#e2e2de}\n.inspector-action svg{width:15px;height:15px;flex:none;fill:none;stroke:currentColor;stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round;color:var(--ink-3)}\n.inspector-collapsed .inspector{padding:22px 10px}\n.inspector-collapsed .inspector-header{justify-content:center}\n.inspector-collapsed .inspector h2,.inspector-collapsed .inspector-content{display:none}\n.inspector-collapsed .collapse-inspector{transform:rotate(180deg)}\n\n.colophon{display:flex;align-items:center;gap:9px;margin-top:56px;padding-top:16px;border-top:1px solid var(--hair);font:600 10px/1.6 var(--mono);letter-spacing:.14em;text-transform:uppercase;color:var(--ink-3)}\n.colophon svg{width:12px;height:13px;flex:none;color:var(--faint)}\n.colophon svg path{fill:none;stroke:currentColor;stroke-width:2.2;stroke-linecap:round;stroke-linejoin:round}\n.colophon svg .mark-deep{stroke:var(--accent)}\n.selection-menu{position:fixed;z-index:30;display:flex;gap:2px;max-width:calc(100vw - 16px);overflow-x:auto;padding:4px;border:1px solid var(--hair);border-radius:11px;background:var(--surface);box-shadow:var(--shadow)}\n.selection-menu[hidden]{display:none!important}\n.selection-menu button{border:0;background:transparent;min-height:36px;padding:8px 11px;border-radius:8px;color:var(--ink-2);font:500 12px/1.2 var(--sans);cursor:pointer;white-space:nowrap;transition:background-color 120ms ease,color 120ms ease}\n.selection-menu button:hover{background:var(--wash);color:var(--accent)}\n.md-code{font:500 .92em var(--mono);letter-spacing:0;background:var(--well);border-radius:4px;padding:1px 4px;color:var(--ink)}\n.toast{position:fixed;right:20px;bottom:20px;z-index:40;max-width:calc(100vw - 32px);background:#22262b;color:#f5f5f3;border-radius:9px;padding:11px 14px;font:500 12.5px/1.4 var(--sans);box-shadow:var(--shadow);animation:rise 200ms ease}\n\n@keyframes story-enter{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}\n@keyframes rise{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}\n@keyframes view-in{from{opacity:0;transform:translateY(5px)}to{opacity:1;transform:none}}\n@keyframes sheet-in{from{opacity:0;transform:translateY(28px)}to{opacity:1;transform:none}}\n@keyframes fade-in{from{opacity:0}to{opacity:1}}\n\n@media(max-width:1160px){.app-shell{grid-template-columns:204px minmax(0,1fr) 236px}.app-shell.sidebar-collapsed{grid-template-columns:64px minmax(0,1fr) 236px}.app-shell.inspector-collapsed{grid-template-columns:204px minmax(0,1fr) 64px}.app-shell.sidebar-collapsed.inspector-collapsed{grid-template-columns:64px minmax(0,1fr) 64px}.main{padding:32px 28px 72px}.view-bar::before{left:-28px;right:-28px}.story-level-0 .chapter-list,.test-theme-grid{grid-template-columns:repeat(2,minmax(0,1fr))}}\n@media(max-width:980px){.test-evidence-meta{grid-template-columns:1fr}}\n@media(max-width:1080px){\n.app-shell,.app-shell.inspector-collapsed{grid-template-columns:204px minmax(0,1fr)}\n.app-shell.sidebar-collapsed,.app-shell.sidebar-collapsed.inspector-collapsed{grid-template-columns:64px minmax(0,1fr)}\n.mobile-inspector-toggle{display:grid;margin-left:6px}\n.inspector{display:none}\n.app-shell.mobile-inspector-open::before{content:\"\";position:fixed;inset:0;z-index:35;background:rgba(17,21,28,.32);animation:fade-in 220ms ease both}\n.app-shell.mobile-inspector-open .inspector{display:block;position:fixed;z-index:40;inset:auto 10px calc(10px + env(safe-area-inset-bottom)) 10px;height:auto;max-height:min(76vh,600px);overflow:auto;border:1px solid var(--hair);border-radius:14px;padding:18px;background:var(--surface);box-shadow:var(--shadow);animation:sheet-in 300ms cubic-bezier(.2,.9,.25,1) both}\n.app-shell.mobile-inspector-open .inspector-content{display:block}\n.app-shell.mobile-inspector-open .inspector h2{display:block}\n.app-shell.mobile-inspector-open .collapse-inspector{transform:rotate(180deg)}\n.inspector-collapsed .inspector{padding:18px}\n.inspector-collapsed .inspector h2,.inspector-collapsed .inspector-content{display:block}\n.inspector-collapsed .inspector-header{justify-content:space-between}\n}\n@media(max-width:760px){\n.app-shell,.app-shell.sidebar-collapsed,.app-shell.inspector-collapsed,.app-shell.sidebar-collapsed.inspector-collapsed{display:block}\n.sidebar,.sidebar.collapsed{position:sticky;top:0;z-index:20;width:auto;height:auto;padding:8px 14px 0;background:var(--surface);border-right:0;border-bottom:1px solid var(--hair);overflow:visible}\n.brand,.sidebar.collapsed .brand{flex-direction:row;gap:9px;min-height:44px;padding:2px 0 8px}\n.brand-name,.sidebar.collapsed .brand-name{display:inline}\n.collapse-sidebar,.sidebar.collapsed .collapse-sidebar{margin:0 0 0 auto}\n.collapse-sidebar{transform:rotate(90deg)}\n.sidebar.collapsed .collapse-sidebar{transform:rotate(-90deg)}\n.mobile-inspector-toggle{display:grid;margin-left:6px}\n.sidebar nav,.sidebar.collapsed nav{display:grid;grid-auto-flow:column;grid-auto-columns:1fr;gap:0;margin:0 -14px;border-top:1px solid var(--hair);overflow:hidden;max-height:64px;transition:max-height 200ms ease,border-color 200ms ease}\n.sidebar.collapsed nav{max-height:0;border-top-color:transparent}\n.nav-item,.sidebar.collapsed .nav-item{flex-direction:column;justify-content:center;gap:5px;width:auto;min-height:56px;padding:8px 4px;border-radius:0;font:500 11px/1 var(--sans);color:var(--ink-3)}\n.nav-icon svg{width:19px;height:19px}\n.nav-item.active,.sidebar.collapsed .nav-item.active{color:var(--accent);background:transparent;box-shadow:inset 0 -2px var(--accent)}\n.nav-item.active::before{display:none}\n.main{padding:22px 16px 150px}\n.page-header{display:block;padding:0 0 16px}\n.page-header h1{font-size:17px}\n.breadcrumbs{gap:10px;font-size:11.5px}\n.view-bar{position:fixed;left:12px;right:12px;top:auto;bottom:calc(10px + env(safe-area-inset-bottom));z-index:25;display:flex;flex-wrap:wrap;gap:0;height:auto;margin:0;padding:4px 10px 6px;background:var(--surface);border:1px solid var(--hair);border-radius:16px;box-shadow:var(--shadow);pointer-events:auto}\n.view-bar::before{display:none}\n.view-bar .story-zoom-controls{position:relative;top:0;right:auto}\n.view-bar-ref{display:none}\n.view-bar.view-bar-empty{display:none}\n.story-zoom-controls{flex:1;width:100%;height:66px;padding-top:0}\n.zoom{flex:1;width:auto;height:46px;padding:0 6px}\n.zoom button{width:40px;height:46px}\n.zoom::before{left:26px;right:26px;bottom:10px}\n.zoom button::before{bottom:10px}\n.zoom button::after{bottom:32px}\n.story-zoom-controls>button[data-zoom-step]{width:40px;height:46px;font-size:19px}\n.zoom-callout{top:calc(100% - 1px)}\n.review-summary{margin-top:22px;font-size:17px}\n.story-toolbar{flex-wrap:wrap}\n.chapter-toggle{grid-template-columns:38px minmax(0,1fr) 16px;gap:10px;padding:14px}\n.chapter-number{font-size:16px}\n.chapter-detail{padding:0 14px}\n.chapter.open .chapter-detail{padding-top:2px;padding-bottom:18px}\n.semantic{grid-template-columns:1fr;gap:12px}\n.semantic>div+div{border-left:0;border-top:1px solid var(--hair);padding-left:0;padding-top:12px}\n.evidence header{flex-direction:column;align-items:flex-start;gap:3px}\n.line{grid-template-columns:34px 34px 1fr;padding:0 8px}\n.line.omission{padding:4px 8px}\n.file>summary{flex-wrap:wrap}\n.story-level-0 .chapter-list{grid-template-columns:1fr;gap:10px}\n.story-level-0 .chapter-toggle{min-height:0}\n.story-level-0 .chapter-copy{min-height:0}\n.test-theme-grid{grid-template-columns:1fr}\n.test-evidence-card summary{flex-direction:column;align-items:flex-start}\n.timeline-rail{top:8px;grid-template-columns:34px minmax(0,1fr) 34px;padding:8px 8px 6px}\n.rail-nav{width:34px;height:34px}\n.timeline-explanation{grid-template-columns:1fr}\n.story-level-2 #timeline .timeline-explanation,.story-level-3 #timeline .timeline-explanation{grid-template-columns:1fr}\n.timeline-explanation section+section{border-left:0;border-top:1px solid var(--hair);padding-left:0;padding-top:14px}\n.timeline-card{grid-template-columns:36px minmax(0,1fr)}\n.selection-menu{left:8px!important;right:8px;top:auto!important;bottom:calc(94px + env(safe-area-inset-bottom))}\n.toast{left:16px;right:16px;bottom:calc(98px + env(safe-area-inset-bottom));text-align:center}\n}\n@media(max-width:380px){.main{padding-left:12px;padding-right:12px}.breadcrumbs code{font-size:10.5px}.nav-item,.sidebar.collapsed .nav-item{font-size:10px}}\n@media(prefers-color-scheme:dark){\n:root{--surface:#15181c;--rail:#1b1f24;--well:#191d22;--ink:#e7eaed;--ink-2:#b4bbc2;--ink-3:#868f97;--faint:#7c858e;--hair:#272c33;--hair-2:#3a414a;--accent:#7b9ce8;--wash:#1c2536;--low:#46a86c;--contained:#6cb6e6;--elevated:#cfa145;--high:#dd8a5b;--critical:#e07268;--add-ink:#5cb883;--add-bg:#152b1d;--del-ink:#e08a7a;--del-bg:#2f1b17;--shadow:0 18px 44px #00000059}\n::selection{background:#2c3e66}\n.panel-toggle:hover{background:#262c33}\n.nav-item:hover{background:#232930}\n.line code{color:#c9d1d9}\n.line code .tk{color:var(--shiki-dark,currentColor)!important}\n.chapter-churn-bar .additions{background:#3f7f57}\n.chapter-churn-bar .deletions{background:#96584e}\n.inspector-action{background:#232930}\n.inspector-action:hover{background:#2b323a}\n.toast{border:1px solid #3a414a}\n.app-shell.mobile-inspector-open::before{background:rgba(0,0,0,.5)}\n}\n@media(prefers-reduced-motion:reduce){*,*::before,*::after{transition:none!important;animation:none!important}}\n";
|
|
9
|
+
export declare const artifactClientScript = "\n(() => {\n const byId = (id) => document.getElementById(id);\n const agentName = document.body.dataset.agent || 'your agent';\n let toastTimer = 0;\n const toast = (message) => { const node = byId('toast'); node.textContent = message; node.hidden = false; window.clearTimeout(toastTimer); toastTimer = window.setTimeout(() => { node.hidden = true; }, 3600); };\n let selectedText = '';\n let selectedPath = '';\n const currentStoryLevel = () => Number(document.body.dataset.storyLevel ?? 1);\n const setActiveView = (view, viewButton) => { document.querySelectorAll('[data-view]').forEach((node) => node.classList.toggle('active', node === viewButton)); document.querySelectorAll('.view').forEach((node) => node.classList.toggle('active', node.id === view)); const zoomControls = document.querySelector('.story-zoom-controls'); if (zoomControls) zoomControls.hidden = view !== 'trailer' && view !== 'timeline' && view !== 'tests'; };\n document.addEventListener('click', (event) => {\n const target = event.target instanceof Element ? event.target : null;\n if (!target) return;\n const viewButton = target.closest('[data-view]');\n if (viewButton) { setActiveView(viewButton.getAttribute('data-view'), viewButton); return; }\n const chapterButton = target.closest('.chapter-toggle');\n // Step chips inside the toggle navigate to the Timeline; they must not also flip the chapter.\n if (chapterButton && !target.closest('.step-chip')) { if (currentStoryLevel() <= 1) return; const chapter = chapterButton.closest('.chapter'); openChapter(chapter, !chapter.classList.contains('open')); return; }\n const askButton = target.closest('[data-question], [data-action=\"ask\"]');\n if (askButton) { const menu = byId('selection-menu'); menu.hidden = true; delete menu.dataset.pressed; if (!selectedText) return; const question = askButton.getAttribute('data-question'); if (question) copyPrompt(selectionPrompt(question), 'Prompt copied. Paste it into ' + agentName + ' to continue.'); else copyPrompt(selectionPrompt(), 'Selection copied. Paste it into ' + agentName + ' and add your question.'); return; }\n const action = target.closest('[data-action]')?.getAttribute('data-action');\n if (action === 'export') { downloadReview(); toast('Review exported as an HTML file.'); return; }\n if (action === 'copy-summary') copyPrompt(summaryPrompt(), 'Summary prompt copied for ' + agentName + '.');\n });\n // Elements that carry role=button (the chapter toggles) must react to Enter and Space like real buttons.\n document.addEventListener('keydown', (event) => { if (event.key !== 'Enter' && event.key !== ' ') return; const target = event.target instanceof Element ? event.target.closest('[role=\"button\"][tabindex]') : null; if (!target) return; event.preventDefault(); target.click(); });\n document.addEventListener('selectionchange', () => { const menu = byId('selection-menu'); if (document.body.dataset.selectingPointer === 'true') { if (menu.dataset.pressed !== 'true') menu.hidden = true; return; } const selection = window.getSelection(); const anchor = selection && !selection.isCollapsed ? selection.anchorNode : null; const anchorElement = anchor ? (anchor instanceof Element ? anchor : anchor.parentElement) : null; const source = anchorElement ? anchorElement.closest('.evidence, .full-diff-file') : null; const text = source ? selection.toString().trim() : ''; if (!text) { if (menu.dataset.pressed !== 'true') menu.hidden = true; return; } selectedText = text; selectedPath = source.querySelector('.evidence-path, .file-path')?.textContent?.trim() || ''; const rect = selection.getRangeAt(0).getBoundingClientRect(); menu.style.left = Math.max(8, rect.left) + 'px'; menu.style.top = Math.max(8, rect.top - 42) + 'px'; menu.hidden = false; });\n function openChapter(chapter, open) { if (!chapter) return; chapter.classList.toggle('open', open); chapter.querySelector('.chapter-detail').hidden = !open; chapter.querySelector('.chapter-toggle').setAttribute('aria-expanded', String(open)); }\n function downloadReview() { const blob = new Blob(['<!doctype html>\\n' + document.documentElement.outerHTML], { type: 'text/html' }); const link = document.createElement('a'); link.href = URL.createObjectURL(blob); link.download = document.title.replace(/[^a-z0-9]+/gi, '-').replace(/^-|-$/g, '').toLowerCase() + '.html'; document.body.append(link); link.click(); link.remove(); window.setTimeout(() => URL.revokeObjectURL(link.href), 1000); }\n function copyPrompt(text, successMessage) { const write = navigator.clipboard?.writeText?.(text); if (write && typeof write.then === 'function') { write.then(() => toast(successMessage)).catch(() => showManualCopy(text)); return; } showManualCopy(text); }\n function showManualCopy(text) { window.prompt('Copy this prompt for ' + agentName + ':', text); toast('Copy prompt shown for ' + agentName + '.'); }\n function summaryPrompt() { const story = document.querySelector('#trailer')?.innerText?.trim() || document.querySelector('.main')?.innerText?.trim() || document.title; return 'Use this ndrstnd review summary to help me understand the implementation, decisions, risks, and tests.\\n\\n' + story; }\n function selectionPrompt(question) { const subject = document.title.replace(/^ndrstnd \u00B7 /, ''); const context = 'Context: ndrstnd review of ' + subject + (selectedPath ? '; selected excerpt from ' + selectedPath : '') + '.\\n\\nSelected lines:\\n' + selectedText; return question ? question + '\\n\\n' + context : context + '\\n\\nMy question: '; }\n})();\n";
|
|
10
|
+
export declare const portableEnhancements = "\n(() => {\n const byId = (id) => document.getElementById(id);\n // Analysis-supplied ids (chapters, steps) may contain selector metacharacters; every runtime selector interpolation goes through this.\n const cssAttr = (value) => window.CSS && CSS.escape ? CSS.escape(String(value)) : String(value).replace(/[\"\\\\]/g, '\\\\$&');\n const storyLevels = [{ name: 'Map', description: 'Themes and risk distribution' }, { name: 'Summary', description: 'Story claims and summaries' }, { name: 'Explanation', description: 'Before and after meaning' }, { name: 'Evidence', description: 'Focused code excerpts' }, { name: 'Raw', description: 'Complete change evidence' }];\n const timelineLevels = [{ name: 'Map', description: 'Complete build path' }, { name: 'Summary', description: 'Goals and postconditions' }, { name: 'Explanation', description: 'Deferred concerns and forward references' }, { name: 'Evidence', description: 'Cumulative evidence by step' }, { name: 'Raw', description: 'Cumulative patch through this step' }];\n const testLevels = [{ name: 'Map', description: 'Change themes and test activity' }, { name: 'Summary', description: 'Tested behaviors' }, { name: 'Explanation', description: 'Behavior meaning' }, { name: 'Evidence', description: 'Test cases and excerpts' }, { name: 'Raw', description: 'Complete test artifacts' }];\n const activeView = () => document.querySelector('[data-view].active')?.getAttribute('data-view') || 'trailer';\n const levelsForView = () => activeView() === 'tests' ? testLevels : activeView() === 'timeline' ? timelineLevels : storyLevels;\n const updateZoomLabel = (level) => {\n const levels = levelsForView();\n const label = document.getElementById('zoom-label');\n if (label) label.textContent = levels[level].name;\n const description = document.getElementById('zoom-description');\n if (description) description.textContent = levels[level].description;\n };\n const ensureRawEvidence = (article) => {\n if (!article || article.querySelector('.raw-code')) return;\n const source = document.querySelector('#diff [data-diff-hunk=\"' + cssAttr(article.getAttribute('data-evidence-id')) + '\"] pre');\n if (!source) return;\n const raw = document.createElement('pre');\n raw.className = 'raw-code';\n raw.innerHTML = source.innerHTML;\n article.appendChild(raw);\n };\n const materializeTestSlots = () => {\n const templateFor = (id) => [...document.querySelectorAll('[data-test-excerpt-template]')].find((node) => node.getAttribute('data-test-excerpt-template') === id);\n document.querySelectorAll('.test-excerpt-slot:not([data-materialized])').forEach((slot) => { const template = templateFor(slot.getAttribute('data-test-hunk')); if (!template) return; slot.appendChild(template.content.cloneNode(true)); slot.dataset.materialized = 'true'; });\n document.querySelectorAll('.test-raw-slot:not([data-materialized])').forEach((slot) => { const id = slot.getAttribute('data-test-hunk'); const block = [...document.querySelectorAll('#diff [data-diff-hunk]')].find((node) => node.getAttribute('data-diff-hunk') === id); const source = block ? block.querySelector('pre') : null; if (!source) return; const copy = document.createElement('pre'); copy.innerHTML = source.innerHTML; slot.appendChild(copy); slot.dataset.materialized = 'true'; });\n };\n const materializeEvidenceStack = (stack) => {\n if (!stack || stack.dataset.materialized === 'true' || stack.dataset.evidenceList === undefined) return;\n stack.dataset.evidenceList.split(' ').filter(Boolean).forEach((id) => { const template = document.querySelector('[data-evidence-template=\"' + cssAttr(id) + '\"]'); if (template) stack.appendChild(template.content.cloneNode(true)); });\n stack.dataset.materialized = 'true';\n if (Number(document.body.dataset.storyLevel ?? 1) >= 4) stack.querySelectorAll('.evidence[data-evidence-id]').forEach((article) => ensureRawEvidence(article));\n };\n const setChapterDetail = (chapter, expanded, animate) => { const detail = chapter.querySelector('.chapter-detail'); if (!detail) return; chapter.querySelector('.chapter-toggle')?.setAttribute('aria-expanded', String(expanded)); window.clearTimeout(Number(detail.dataset.zoomCollapseTimer)); if (expanded) { detail.hidden = false; materializeEvidenceStack(detail.querySelector('.evidence-stack')); if (animate) void detail.offsetHeight; chapter.classList.add('open'); detail.classList.toggle('zoom-revealed', animate); return; } chapter.classList.remove('open'); detail.classList.remove('zoom-revealed'); if (!animate) { detail.hidden = true; return; } detail.dataset.zoomCollapseTimer = String(window.setTimeout(() => { if (!chapter.classList.contains('open')) detail.hidden = true; }, 260)); };\n const setZoom = (level) => { level = Math.max(0, Math.min(4, level)); const current = Number(document.body.dataset.storyLevel ?? 1); const changed = current !== level; const zoom = document.getElementById('zoom-control'); zoom?.classList.toggle('is-changing', changed); document.body.dataset.storyLevel = String(level); document.body.className = document.body.className.replace(/story-level-\\d/g, '') + ' story-level-' + level; document.querySelectorAll('[data-zoom]').forEach((button) => { const active = Number(button.dataset.zoom) === level; button.classList.toggle('active', active); button.setAttribute('aria-pressed', String(active)); }); updateZoomLabel(level); const map = document.getElementById('map'); if (map) map.hidden = level !== 0; document.querySelectorAll('.chapter').forEach((chapter) => setChapterDetail(chapter, level >= 2, changed)); if (level >= 3) materializeTestSlots(); if (level >= 4) document.querySelectorAll('.evidence[data-evidence-id]').forEach((article) => ensureRawEvidence(article)); if (changed) window.setTimeout(() => zoom?.classList.remove('is-changing'), 260); };\n setZoom(1);\n const setZoomControlsVisible = (view) => { const hidden = view !== 'trailer' && view !== 'timeline' && view !== 'tests'; const controls = document.querySelector('.story-zoom-controls'); if (controls) controls.hidden = hidden; document.querySelector('.view-bar')?.classList.toggle('view-bar-empty', hidden); updateZoomLabel(Number(document.body.dataset.storyLevel ?? 1)); };\n setZoomControlsVisible(document.querySelector('[data-view].active')?.getAttribute('data-view') || 'trailer');\n const materializeTimelineState = (state) => {\n if (!state || state.dataset.materialized === 'true') return;\n const evidence = state.querySelector('.timeline-evidence');\n if (!evidence || evidence.dataset.currentEvidence === undefined) return;\n const current = evidence.dataset.currentEvidence.split(' ').filter(Boolean);\n // Prior evidence is the union of earlier steps' own evidence; deriving it here keeps the attributes O(hunks) instead of O(steps x hunks).\n const states = [...document.querySelectorAll('.timeline-state')];\n const prior = states.slice(0, states.indexOf(state)).flatMap((previous) => { const container = previous.querySelector('.timeline-evidence'); return container && container.dataset.currentEvidence ? container.dataset.currentEvidence.split(' ') : []; }).filter(Boolean);\n const append = (id, isCurrent) => { const template = document.querySelector('[data-evidence-template=\"' + cssAttr(id) + '\"]'); if (!template) return; const item = document.createElement('div'); item.className = 'timeline-evidence-item' + (isCurrent ? ' current' : ''); item.setAttribute('data-evidence-id', id); item.appendChild(template.content.cloneNode(true)); evidence.appendChild(item); };\n current.forEach((id) => append(id, true));\n if (prior.length > 0) { const divider = document.createElement('p'); divider.className = 'timeline-evidence-divider'; divider.textContent = 'Already in place from earlier steps'; evidence.appendChild(divider); prior.forEach((id) => append(id, false)); }\n const raw = state.querySelector('.timeline-raw');\n if (raw) { const wanted = new Set(current.concat(prior)); document.querySelectorAll('#diff details.full-diff-file').forEach((file) => { const blocks = [...file.querySelectorAll('[data-diff-hunk]')].filter((block) => wanted.has(block.getAttribute('data-diff-hunk'))); if (blocks.length === 0) return; const copy = document.createElement('details'); copy.className = file.className; copy.open = true; const summary = file.querySelector('summary'); if (summary) copy.appendChild(summary.cloneNode(true)); blocks.forEach((block) => copy.appendChild(block.cloneNode(true))); raw.appendChild(copy); }); }\n if (Number(document.body.dataset.storyLevel ?? 1) >= 4) state.querySelectorAll('.evidence[data-evidence-id]').forEach((article) => ensureRawEvidence(article));\n state.dataset.materialized = 'true';\n };\n const clearTimelineState = (state) => {\n if (!state || state.dataset.materialized !== 'true') return;\n const evidence = state.querySelector('.timeline-evidence');\n if (evidence) evidence.replaceChildren();\n const raw = state.querySelector('.timeline-raw');\n if (raw) raw.replaceChildren();\n state.dataset.materialized = 'false';\n };\n materializeTimelineState(document.querySelector('.timeline-state.active'));\n const selectTimelineStep = (stepId) => { document.querySelectorAll('[data-timeline-state]').forEach((state) => { const active = state.getAttribute('data-timeline-state') === stepId; state.classList.toggle('active', active); state.hidden = !active; if (active) materializeTimelineState(state); else clearTimelineState(state); }); document.querySelectorAll('[data-timeline-select]').forEach((button) => { const active = button.getAttribute('data-timeline-select') === stepId; button.classList.toggle('active', active); if (button.getAttribute('role') === 'tab') button.setAttribute('aria-selected', String(active)); }); const ticks = [...document.querySelectorAll('.rail-tick')]; const index = ticks.findIndex((tick) => tick.getAttribute('data-timeline-select') === stepId); if (index < 0) return; const pad = (value) => String(value).padStart(2, '0'); const stepOutput = byId('rail-step'); if (stepOutput) stepOutput.textContent = pad(index + 1) + ' / ' + pad(ticks.length); const titleOutput = byId('rail-title'); if (titleOutput) titleOutput.textContent = ticks[index].getAttribute('data-step-title') || ''; document.querySelectorAll('[data-timeline-move]').forEach((nav) => { const next = index + Number(nav.getAttribute('data-timeline-move')); nav.toggleAttribute('disabled', next < 0 || next >= ticks.length); }); };\n const moveTimelineStep = (delta) => { const ticks = [...document.querySelectorAll('.rail-tick')]; const index = ticks.findIndex((tick) => tick.classList.contains('active')); const next = ticks[index + delta]; if (next) selectTimelineStep(next.getAttribute('data-timeline-select')); };\n // Chapter ids come from the analysis and may contain anything; matching by attribute value avoids selector parsing entirely.\n const openStoryChapter = (id) => { document.querySelector('[data-view=\"trailer\"]')?.click(); const chapter = [...document.querySelectorAll('.chapter[data-chapter]')].find((node) => node.getAttribute('data-chapter') === id); if (chapter) { setZoom(Math.max(2, Number(document.body.dataset.storyLevel ?? 1))); chapter.classList.add('open'); chapter.querySelector('.chapter-toggle')?.setAttribute('aria-expanded', 'true'); const detail = chapter.querySelector('.chapter-detail'); detail.hidden = false; materializeEvidenceStack(detail.querySelector('.evidence-stack')); chapter.scrollIntoView({ behavior: 'smooth', block: 'center' }); } };\n document.addEventListener('click', (event) => { const target = event.target instanceof Element ? event.target : null; if (!target) return; if (!target.closest('.selection-menu') && !target.closest('.evidence') && !target.closest('.full-diff-file')) byId('selection-menu').hidden = true; const chapterToggle = target.closest('.chapter-toggle'); if (chapterToggle) { const detail = chapterToggle.closest('.chapter')?.querySelector('.chapter-detail'); if (detail && !detail.hidden) materializeEvidenceStack(detail.querySelector('.evidence-stack')); } const timelineMove = target.closest('[data-timeline-move]'); if (timelineMove) { moveTimelineStep(Number(timelineMove.getAttribute('data-timeline-move'))); return; } const timelineSelect = target.closest('[data-timeline-select]'); if (timelineSelect) { selectTimelineStep(timelineSelect.getAttribute('data-timeline-select')); if (Number(document.body.dataset.storyLevel ?? 1) === 0) setZoom(1); return; } const storyStep = target.closest('[data-story-step]'); if (storyStep) { document.querySelector('[data-view=\"timeline\"]')?.click(); selectTimelineStep(storyStep.getAttribute('data-story-step')); setZoom(Math.max(1, Number(document.body.dataset.storyLevel ?? 1))); document.querySelector('.timeline-rail')?.scrollIntoView({ behavior: 'smooth', block: 'start' }); return; } const storyStepIndex = target.closest('[data-story-step-index]'); if (storyStepIndex) { const index = Number(storyStepIndex.getAttribute('data-story-step-index')); const state = document.querySelector('.timeline-state[data-step-index=\"' + index + '\"]'); document.querySelector('[data-view=\"timeline\"]')?.click(); if (state) selectTimelineStep(state.getAttribute('data-timeline-state')); setZoom(3); document.querySelector('.timeline-rail')?.scrollIntoView({ behavior: 'smooth', block: 'start' }); return; } const collapse = target.closest('.collapse-sidebar'); if (collapse) { document.querySelector('.sidebar')?.classList.toggle('collapsed'); return; } const all = target.closest('#collapse-all'); if (all) { document.querySelectorAll('.chapter').forEach((chapter) => { chapter.classList.remove('open'); chapter.querySelector('.chapter-detail').hidden = true; chapter.querySelector('.chapter-toggle')?.setAttribute('aria-expanded', 'false'); }); return; } const testJump = target.closest('[data-test-jump]'); if (testJump) { const id = testJump.getAttribute('data-test-jump'); setZoom(3); window.setTimeout(() => { const card = [...document.querySelectorAll('.test-plan-evidence [data-test-case]')].find((node) => node.getAttribute('data-test-case') === id); if (card) { card.open = true; card.scrollIntoView({ behavior: 'smooth', block: 'center' }); } }, 0); return; } const chapterJump = target.closest('[data-step-chapter]'); if (chapterJump) { openStoryChapter(chapterJump.getAttribute('data-step-chapter')); return; } const view = target.closest('[data-view]')?.getAttribute('data-view'); if (view) setZoomControlsVisible(view); const step = target.closest('[data-zoom-step]'); if (step) { const active = Number(document.querySelector('[data-zoom].active')?.getAttribute('data-zoom') ?? 1); setZoom(active + Number(step.getAttribute('data-zoom-step'))); return; } const zoom = target.closest('[data-zoom]'); if (zoom) setZoom(Number(zoom.getAttribute('data-zoom'))); });\n const selectionMenu = byId('selection-menu');\n if (selectionMenu) {\n selectionMenu.addEventListener('mousedown', (event) => event.preventDefault());\n selectionMenu.addEventListener('touchstart', () => { selectionMenu.dataset.pressed = 'true'; window.setTimeout(() => { delete selectionMenu.dataset.pressed; }, 700); }, { passive: true });\n const dismissSelectionMenu = () => { selectionMenu.hidden = true; };\n window.addEventListener('scroll', dismissSelectionMenu, { capture: true, passive: true });\n window.addEventListener('resize', dismissSelectionMenu, { passive: true });\n // The menu appears only when the pointer is released, never mid-drag.\n document.addEventListener('pointerdown', (event) => { const target = event.target instanceof Element ? event.target : null; if (target && target.closest('.selection-menu')) return; document.body.dataset.selectingPointer = 'true'; }, true);\n const releaseSelectionPointer = () => { if (document.body.dataset.selectingPointer !== 'true') return; delete document.body.dataset.selectingPointer; document.dispatchEvent(new Event('selectionchange')); };\n document.addEventListener('pointerup', releaseSelectionPointer, true);\n document.addEventListener('pointercancel', releaseSelectionPointer, true);\n }\n})();\n(() => {\n const shell = document.querySelector('.app-shell');\n const bar = document.querySelector('.view-bar');\n const masthead = document.querySelector('.page-header');\n if (bar && masthead && typeof IntersectionObserver === 'function') {\n new IntersectionObserver((entries) => { bar.classList.toggle('view-bar-stuck', entries[0].boundingClientRect.top < 1); }, { threshold: [0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1] }).observe(masthead);\n }\n document.addEventListener('click', (event) => {\n const target = event.target instanceof Element ? event.target : null;\n if (!target) return;\n if (shell?.classList.contains('mobile-inspector-open') && window.innerWidth <= 1080 && !target.closest('.inspector') && !target.closest('.mobile-inspector-toggle')) {\n shell.classList.remove('mobile-inspector-open');\n document.querySelector('.mobile-inspector-toggle')?.setAttribute('aria-expanded', 'false');\n // A sidebar-collapse click also dismisses the sheet, but its own handling below must still run or the shell grid and aria state desync.\n if (!target.closest('.collapse-sidebar')) return;\n }\n if (target.closest('.collapse-sidebar')) {\n const collapsed = document.querySelector('.sidebar')?.classList.contains('collapsed') ?? false;\n shell?.classList.toggle('sidebar-collapsed', collapsed);\n target.closest('.collapse-sidebar')?.setAttribute('aria-expanded', String(!collapsed));\n return;\n }\n const mobileInspector = target.closest('.mobile-inspector-toggle');\n if (mobileInspector) {\n const open = shell?.classList.toggle('mobile-inspector-open') ?? false;\n mobileInspector.setAttribute('aria-expanded', String(open));\n return;\n }\n const inspectorToggle = target.closest('.collapse-inspector');\n if (!inspectorToggle) return;\n if (window.innerWidth <= 1080) {\n shell?.classList.remove('mobile-inspector-open');\n document.querySelector('.mobile-inspector-toggle')?.setAttribute('aria-expanded', 'false');\n return;\n }\n const collapsed = shell?.classList.toggle('inspector-collapsed') ?? false;\n inspectorToggle.setAttribute('aria-expanded', String(!collapsed));\n });\n})();\n(() => {\n const preferenceKey = 'ndrstnd-artifact-ui-preferences-v1';\n const readPreferences = () => {\n try {\n const value = JSON.parse(localStorage.getItem(preferenceKey) || '{}');\n return value && typeof value === 'object' ? value : {};\n } catch { return {}; }\n };\n const savePreferences = (update) => {\n try { localStorage.setItem(preferenceKey, JSON.stringify({ ...readPreferences(), ...update })); } catch {}\n };\n const preferences = readPreferences();\n const shell = document.querySelector('.app-shell');\n const sidebar = document.querySelector('.sidebar');\n if (typeof preferences.sidebarCollapsed === 'boolean') {\n sidebar?.classList.toggle('collapsed', preferences.sidebarCollapsed);\n shell?.classList.toggle('sidebar-collapsed', preferences.sidebarCollapsed);\n document.querySelector('.collapse-sidebar')?.setAttribute('aria-expanded', String(!preferences.sidebarCollapsed));\n }\n if (typeof preferences.inspectorCollapsed === 'boolean') {\n shell?.classList.toggle('inspector-collapsed', preferences.inspectorCollapsed);\n document.querySelector('.collapse-inspector')?.setAttribute('aria-expanded', String(!preferences.inspectorCollapsed));\n }\n if (Number.isInteger(preferences.zoom) && preferences.zoom >= 0 && preferences.zoom <= 4) document.querySelector('[data-zoom=\"' + preferences.zoom + '\"]')?.click();\n // A tampered stored view name must not throw out of this script and take the other startup wiring with it.\n if (typeof preferences.view === 'string' && /^[a-z-]+$/.test(preferences.view)) document.querySelector('[data-view=\"' + preferences.view + '\"]')?.click();\n document.addEventListener('click', (event) => {\n const target = event.target instanceof Element ? event.target : null;\n if (!target) return;\n const view = target.closest('[data-view]')?.getAttribute('data-view');\n if (view) savePreferences({ view });\n const zoom = target.closest('[data-zoom]')?.getAttribute('data-zoom');\n if (zoom !== null && zoom !== undefined) savePreferences({ zoom: Number(zoom) });\n if (target.closest('.collapse-sidebar')) savePreferences({ sidebarCollapsed: document.querySelector('.sidebar')?.classList.contains('collapsed') ?? false });\n if (target.closest('.collapse-inspector') && window.innerWidth > 1080) savePreferences({ inspectorCollapsed: shell?.classList.contains('inspector-collapsed') ?? false });\n });\n})();\n";
|