anentrypoint-design 0.0.454 → 0.0.456
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/247420.css +46 -3
- package/dist/247420.js +112 -29
- package/dist/index.html +86 -3
- package/package.json +1 -1
- package/src/components/agent-chat/controls.js +6 -2
- package/src/components/agent-chat/surface.js +2 -2
- package/src/components/git-status.js +6 -2
- package/src/components/sessions/dashboard.js +5 -1
- package/src/css/app-shell/data-density.css +18 -0
- package/src/css/app-shell/hero-content.css +22 -2
- package/src/css/app-shell/topbar.css +6 -1
- package/src/page-html/client-script.js +62 -1
- package/src/page-html/page-styles.js +23 -1
- package/types/components.d.ts +2 -0
package/dist/index.html
CHANGED
|
@@ -76,7 +76,13 @@
|
|
|
76
76
|
a.row:hover .ds-row-arrow { opacity: 1 }
|
|
77
77
|
/* hero stat strip — all badges as a wrapping inline rhythm, not one empty panel */
|
|
78
78
|
.ds-hero-stats { display: flex; flex-wrap: wrap; gap: var(--space-3, 16px) var(--space-5, 32px); margin-top: var(--space-2, 8px) }
|
|
79
|
-
.ds-hero-stat
|
|
79
|
+
/* hero-content.css's .ds-hero-stat is styled for a vertical stacked list
|
|
80
|
+
(border-bottom row divider, meant to read top-to-bottom); this page renders
|
|
81
|
+
badges in a horizontal row instead (.ds-hero-stats above), where that same
|
|
82
|
+
border reads as an underlined tab strip -- an affordance for a set of
|
|
83
|
+
plain, non-interactive metadata chips. Reset both inherited properties so a
|
|
84
|
+
row of badges never borrows tab-bar chrome it did not opt into. */
|
|
85
|
+
.ds-hero-stat { display: flex; align-items: baseline; gap: var(--space-2, 8px); border-bottom: none !important; padding-bottom: 0 !important }
|
|
80
86
|
.ds-hero-stat-n { font-family: var(--ff-body); font-weight: 700; font-size: var(--fs-lg, 18px); color: var(--fg) }
|
|
81
87
|
.ds-hero-stat-l { font-size: var(--fs-sm, 15px); color: var(--fg-3) }
|
|
82
88
|
/* accent sits on its own line, muted, so it reads as a distinct aside instead
|
|
@@ -93,8 +99,24 @@ a.row:hover .ds-row-arrow { opacity: 1 }
|
|
|
93
99
|
.ds-feature-title { font-weight: 600; font-size: var(--fs-lg, 18px); color: var(--fg) }
|
|
94
100
|
.ds-feature-desc { font-size: var(--fs-sm, 15px); color: var(--fg-2); line-height: 1.5; overflow-wrap: anywhere }
|
|
95
101
|
.ds-feature-benefit { font-style: italic; font-size: var(--fs-sm, 15px); color: var(--fg-3); margin-top: var(--space-1, 4px) }
|
|
102
|
+
/* Real closing content instead of the page simply stopping after its last
|
|
103
|
+
panel — a tonal divider line, a copyright string, and the same external
|
|
104
|
+
links the topbar already carries (footer.js reuses data.navItems, so this
|
|
105
|
+
is never invented content). Sits inside .app-stage's own grid gap like
|
|
106
|
+
every other block, no extra margin needed. */
|
|
107
|
+
.ds-page-footer {
|
|
108
|
+
display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
|
|
109
|
+
gap: var(--space-3, 16px);
|
|
110
|
+
padding-top: var(--space-5, 32px);
|
|
111
|
+
margin-top: var(--space-3, 16px);
|
|
112
|
+
border-top: 1px solid var(--rule, var(--bg-3));
|
|
113
|
+
color: var(--fg-3); font-size: var(--fs-sm, 15px);
|
|
114
|
+
}
|
|
115
|
+
.ds-page-footer-links { display: flex; gap: var(--space-4, 24px) }
|
|
116
|
+
.ds-page-footer-links a { color: var(--fg-3) }
|
|
117
|
+
.ds-page-footer-links a:hover { color: var(--fg) }
|
|
96
118
|
</style>
|
|
97
|
-
<script id="__site__" type="application/json">{"title":"design","slug":"index","siteName":"design","navItems":[["247420","https://247420.xyz"],["GitHub","https://github.com/AnEntrypoint"]],"theme":"auto","hero":{"heading":"design","subheading":"the 247420 design system","body":"shadcn-neutral. oversized display type, a grayscale accent, print texture inert. every 247420 surface runs on it.","badges":[{"label":"design-system"},{"label":"tokens"},{"label":"web"}],"ctas":[{"label":"GitHub","href":"https://github.com/AnEntrypoint/design","primary":true},{"label":"247420","href":"https://247420.xyz"}]},"sections":[],"examples":[{"label":"index shell","desc":"full navigation shell with tabs, filters, and row interactions.","href":"./index.html"},{"label":"homepage kit","desc":"hero + works layout and updated readable type scale.","href":"./ui_kits/homepage/"},{"label":"project page kit","desc":"overview, install, receipt, and changelog template.","href":"./ui_kits/project_page/"},{"label":"docs kit","desc":"technical documentation layout with sidebar and prose.","href":"./ui_kits/docs/"},{"label":"blog kit","desc":"long-form writing layout tuned for readability.","href":"./ui_kits/blog/"},{"label":"chat kit","desc":"message thread + composer with pill bubbles and room sidebar.","href":"./ui_kits/chat/"},{"label":"aicat kit","desc":"ai assistant with cat persona — ascii portrait + mood face.","href":"./ui_kits/aicat/"},{"label":"slide deck","desc":"16:9 deck stage with improved presenter controls text.","href":"./slides/"},{"label":"dashboard kit","desc":"kpis, tables, receipts, changelog — operations surface.","href":"./ui_kits/dashboard/"},{"label":"terminal kit","desc":"cli prompt, command lines, log viewer.","href":"./ui_kits/terminal/"},{"label":"settings kit","desc":"sectioned forms, toggles, segmented buttons, save bar.","href":"./ui_kits/settings/"},{"label":"signin kit","desc":"auth panel, providers, magic link.","href":"./ui_kits/signin/"},{"label":"search kit","desc":"query bar, faceted filters, ranked results.","href":"./ui_kits/search/"},{"label":"404 kit","desc":"empty-state hero with suggested routes.","href":"./ui_kits/error_404/"},{"label":"gallery kit","desc":"visual grid + lightbox over tonal cards.","href":"./ui_kits/gallery/"},{"label":"preview samples","desc":"design previews and component samples.","href":"./preview/buttons.html"}],"bodyHtml":"","sidebar":{"sections":[{"group":"open","items":[{"glyph":"+","label":"open","href":"./ui_kits/homepage/"}]},{"group":"bins","items":[{"label":"everything","href":"#all","count":23,"active":true},{"label":"pinned","href":"#kits","count":5},{"label":"shipped","href":"#previews","count":12},{"label":"drafts","href":"#decks","count":6}]},{"group":"labels","items":[{"label":"ui kits","href":"#kits","count":4},{"label":"decks","href":"#decks","count":1},{"label":"previews","href":"#previews","count":20},{"label":"docs","href":"#docs","count":3}]},{"group":"more","items":[{"label":"readme","href":"https://github.com/AnEntrypoint/design/blob/main/README.md"},{"label":"skill","href":"https://github.com/AnEntrypoint/design/blob/main/SKILL.md"},{"label":"tokens","href":"https://github.com/AnEntrypoint/design/blob/main/colors_and_type.css"},{"label":"source","href":"https://github.com/AnEntrypoint/design"}]}]},"marquee":{"items":["open source","design tokens","buildless components","zero raw color literals"],"sep":"/"},"panels":[{"id":"kits","title":"ui kits","count":"14 surfaces","items":[{"code":"","title":"homepage","sub":"marquee + works grid","meta":"open ->","href":"./ui_kits/homepage/"},{"code":"","title":"project page","sub":"hero receipt install changelog","meta":"open ->","href":"./ui_kits/project_page/"},{"code":"","title":"docs","sub":"long-form prose chrome","meta":"open ->","href":"./ui_kits/docs/"},{"code":"","title":"blog","sub":"dated index + reading view","meta":"open ->","href":"./ui_kits/blog/"},{"code":"","title":"chat","sub":"message thread + composer","meta":"open ->","href":"./ui_kits/chat/"},{"code":"","title":"aicat","sub":"ai assistant with cat persona","meta":"open ->","href":"./ui_kits/aicat/"},{"code":"","title":"file browser","sub":"rails by file type drop preview","meta":"open ->","href":"./ui_kits/file_browser/"},{"code":"","title":"dashboard","sub":"kpis tables receipts changelog","meta":"open ->","href":"./ui_kits/dashboard/"},{"code":"","title":"terminal","sub":"cli prompt command lines log view","meta":"open ->","href":"./ui_kits/terminal/"},{"code":"","title":"settings","sub":"sectioned forms toggles save bar","meta":"open ->","href":"./ui_kits/settings/"},{"code":"","title":"signin","sub":"auth providers magic link","meta":"open ->","href":"./ui_kits/signin/"},{"code":"","title":"search","sub":"topbar query faceted filters rows","meta":"open ->","href":"./ui_kits/search/"},{"code":"","title":"404","sub":"empty-state hero suggested routes","meta":"open ->","href":"./ui_kits/error_404/"},{"code":"","title":"gallery","sub":"visual grid tonal cards lightbox","meta":"open ->","href":"./ui_kits/gallery/"}]},{"id":"file_browser","title":"file browser","count":"primitives","items":[{"code":"fb","title":"file_browser kit","sub":"drop, list, preview, dialogs","meta":"open kit","href":"./ui_kits/file_browser/"},{"code":"fb","title":"FileRow","sub":"rail icon name meta","meta":"preview","href":"./preview/file-row.html"},{"code":"fb","title":"FileGrid","sub":"stack of rows in a panel","meta":"preview","href":"./preview/file-grid.html"},{"code":"fb","title":"DropZone","sub":"tonal upload target","meta":"preview","href":"./preview/dropzone.html"},{"code":"fb","title":"FileViewer","sub":"modal preview keyed head","meta":"preview","href":"./preview/file-viewer.html"},{"code":"fb","title":"FileToolbar","sub":"actions breadcrumb upload","meta":"preview","href":"./preview/file-toolbar.html"},{"code":"fb","title":"fsbrowse","sub":"Express + busboy backend","meta":"source","href":"https://github.com/AnEntrypoint/fsbrowse"}]},{"id":"desktop_os","title":"desktop os shell","count":"in-page wm","items":[{"code":"os","title":"createDesktopShell","sub":"menubar apps launcher taskbar window manager","meta":"shell.js","href":"https://github.com/AnEntrypoint/design/blob/main/src/desktop/shell.js"},{"code":"os","title":"icons set","sub":"svg glyphs for menubar + taskbar","meta":"icons.js","href":"https://github.com/AnEntrypoint/design/blob/main/src/desktop/icons.js"},{"code":"os","title":"theme.css","sub":"os chrome tokens menubar launcher wm","meta":"theme.css","href":"https://github.com/AnEntrypoint/design/blob/main/src/desktop/theme.css"},{"code":"os","title":"import path","sub":"anentrypoint-design/desktop","meta":"exports","href":"https://github.com/AnEntrypoint/design/blob/main/package.json"}]},{"id":"web_components","title":"web components","count":"1 element","items":[{"code":"wc","title":"\u003cds-chat>","sub":"auto-registers when the sdk loads in a browser","meta":"ds-chat.js","href":"https://github.com/AnEntrypoint/design/blob/main/src/web-components/ds-chat.js"},{"code":"wc","title":"registerChatElement","sub":"manual register helper","meta":"source","href":"https://github.com/AnEntrypoint/design/blob/main/src/index.js"}]},{"id":"api_exports","title":"public api","count":"sdk surface","items":[{"code":"api","title":"h / applyDiff","sub":"webjsx createElement + diff","meta":"index.js","href":"https://github.com/AnEntrypoint/design/blob/main/src/index.js"},{"code":"api","title":"installStyles / scope","sub":"ds-247420 css scope + bootstrap","meta":"styles.js","href":"https://github.com/AnEntrypoint/design/blob/main/src/styles.js"},{"code":"api","title":"loadCss","sub":"fetch the bundled css string","meta":"styles.js","href":"https://github.com/AnEntrypoint/design/blob/main/src/styles.js"},{"code":"api","title":"mount / mountKit","sub":"ds shell + ui_kit bootstrap","meta":"bootstrap.js","href":"https://github.com/AnEntrypoint/design/blob/main/src/bootstrap.js"},{"code":"api","title":"registerDeckStage / getDeckStage","sub":"16:9 deck stage api","meta":"deck-stage.js","href":"https://github.com/AnEntrypoint/design/blob/main/src/deck-stage.js"},{"code":"api","title":"renderMarkdown","sub":"marked v15 + dompurify lazy stack","meta":"markdown.js","href":"https://github.com/AnEntrypoint/design/blob/main/src/markdown.js"},{"code":"api","title":"ensurePrism / highlightAllUnder","sub":"prism core + per-language","meta":"highlight.js","href":"https://github.com/AnEntrypoint/design/blob/main/src/highlight.js"},{"code":"api","title":"renderPageHtml","sub":"static page html template","meta":"page-html.js","href":"https://github.com/AnEntrypoint/design/blob/main/src/page-html.js"},{"code":"api","title":"components / motion / debug","sub":"namespaces from the default export","meta":"components.js","href":"https://github.com/AnEntrypoint/design/blob/main/src/components.js"}]},{"id":"decks","title":"decks","count":1,"items":[{"code":"","title":"deck template","sub":"16:9 stage with auto-fit","meta":"open ->","href":"./slides/"}]},{"id":"docs","title":"docs","count":3,"items":[{"code":"md","title":"readme","sub":"overview, manifesto, conventions","meta":"open ->","href":"https://github.com/AnEntrypoint/design/blob/main/README.md"},{"code":"md","title":"skill","sub":"authoring rules for the agent","meta":"open ->","href":"https://github.com/AnEntrypoint/design/blob/main/SKILL.md"},{"code":"css","title":"tokens","sub":"colors, type, panel surface tokens","meta":"open ->","href":"https://github.com/AnEntrypoint/design/blob/main/colors_and_type.css"}]},{"id":"features","title":"why design","count":4,"items":[{"code":"","title":"layered surfaces","sub":"panel-on-panel rhythm; loud content sits inside quiet chrome.","meta":"panel-row.css","href":"https://github.com/AnEntrypoint/design/blob/main/src/css/app-shell/panel-row.css"},{"code":"","title":"monospace labels","sub":"mono only for codes/labels/CLI; sans for everything legible.","meta":"colors_and_type.css","href":"https://github.com/AnEntrypoint/design/blob/main/colors_and_type.css"},{"code":"","title":"indicator rails","sub":"color-coded inset rails for category separation, never borders.","meta":"panel-row.css","href":"https://github.com/AnEntrypoint/design/blob/main/src/css/app-shell/panel-row.css#L126"},{"code":"","title":"tokens-only","sub":"every surface, type ramp, accent driven by --panel-* / --fs-* tokens.","meta":"colors_and_type.css","href":"https://github.com/AnEntrypoint/design/blob/main/colors_and_type.css"}]},{"id":"previews","title":"previews","count":25,"items":[{"code":"","title":"buttons","sub":"preview · buttons.html","meta":"open ->","href":"./preview/buttons.html"},{"code":"","title":"colors core","sub":"preview · colors-core.html","meta":"open ->","href":"./preview/colors-core.html"},{"code":"","title":"colors lore","sub":"preview · colors-lore.html","meta":"open ->","href":"./preview/colors-lore.html"},{"code":"","title":"colors semantic","sub":"preview · colors-semantic.html","meta":"open ->","href":"./preview/colors-semantic.html"},{"code":"","title":"dateline","sub":"preview · dateline.html","meta":"open ->","href":"./preview/dateline.html"},{"code":"","title":"dropzone","sub":"preview · dropzone.html","meta":"open ->","href":"./preview/dropzone.html"},{"code":"","title":"file grid","sub":"preview · file-grid.html","meta":"open ->","href":"./preview/file-grid.html"},{"code":"","title":"file row","sub":"preview · file-row.html","meta":"open ->","href":"./preview/file-row.html"},{"code":"","title":"file toolbar","sub":"preview · file-toolbar.html","meta":"open ->","href":"./preview/file-toolbar.html"},{"code":"","title":"file viewer","sub":"preview · file-viewer.html","meta":"open ->","href":"./preview/file-viewer.html"},{"code":"","title":"header","sub":"preview · header.html","meta":"open ->","href":"./preview/header.html"},{"code":"","title":"icons unicode","sub":"preview · icons-unicode.html","meta":"open ->","href":"./preview/icons-unicode.html"},{"code":"","title":"index row","sub":"preview · index-row.html","meta":"open ->","href":"./preview/index-row.html"},{"code":"","title":"inputs","sub":"preview · inputs.html","meta":"open ->","href":"./preview/inputs.html"},{"code":"","title":"manifesto","sub":"preview · manifesto.html","meta":"open ->","href":"./preview/manifesto.html"},{"code":"","title":"rules","sub":"preview · rules.html","meta":"open ->","href":"./preview/rules.html"},{"code":"","title":"spacing","sub":"preview · spacing.html","meta":"open ->","href":"./preview/spacing.html"},{"code":"","title":"stamps","sub":"preview · stamps.html","meta":"open ->","href":"./preview/stamps.html"},{"code":"","title":"stamps lore","sub":"preview · stamps-lore.html","meta":"open ->","href":"./preview/stamps-lore.html"},{"code":"","title":"theme ink","sub":"preview · theme-ink.html","meta":"open ->","href":"./preview/theme-ink.html"},{"code":"","title":"type display","sub":"preview · type-display.html","meta":"open ->","href":"./preview/type-display.html"},{"code":"","title":"type mono","sub":"preview · type-mono.html","meta":"open ->","href":"./preview/type-mono.html"},{"code":"","title":"type prose","sub":"preview · type-prose.html","meta":"open ->","href":"./preview/type-prose.html"},{"code":"","title":"type scale","sub":"preview · type-scale.html","meta":"open ->","href":"./preview/type-scale.html"},{"code":"","title":"wordmarks","sub":"preview · wordmarks.html","meta":"open ->","href":"./preview/wordmarks.html"}]}],"quickstart":{"heading":"quick start","lines":[{"kind":"cmt","text":"# install via importmap (no bundler)"},{"kind":"cmd","text":"\u003cscript type='importmap'>{\"imports\":{\"anentrypoint-design\":\"https://unpkg.com/anentrypoint-design@latest/dist/247420.js\"}}\u003c/script>"},{"kind":"cmt","text":"# or clone the source"},{"kind":"cmd","text":"git clone https://github.com/AnEntrypoint/design.git"}]},"statusLeft":["main","utf-8","lf"],"statusRight":["247420 · mmxxvi","probably emerging"]}</script>
|
|
119
|
+
<script id="__site__" type="application/json">{"title":"design","slug":"index","siteName":"design","navItems":[["247420","https://247420.xyz"],["AnEntrypoint ->","https://github.com/AnEntrypoint"]],"theme":"auto","hero":{"heading":"design","subheading":"the 247420 design system","body":"14 kit surfaces, zero raw color literals, one importmap script tag to install. every panel, row, and form control in this system reads its color, radius, and spacing from a single token file — swap the tokens and every surface built on them changes with it.","badges":[{"label":"design-system"},{"label":"tokens"},{"label":"web"}],"ctas":[{"label":"GitHub","href":"https://github.com/AnEntrypoint/design","primary":true},{"label":"247420","href":"https://247420.xyz"}]},"sections":[],"examples":[{"label":"index shell","desc":"full navigation shell with tabs, filters, and row interactions.","href":"./index.html"},{"label":"homepage kit","desc":"hero + works layout and updated readable type scale.","href":"./ui_kits/homepage/"},{"label":"project page kit","desc":"overview, install, receipt, and changelog template.","href":"./ui_kits/project_page/"},{"label":"docs kit","desc":"technical documentation layout with sidebar and prose.","href":"./ui_kits/docs/"},{"label":"blog kit","desc":"long-form writing layout tuned for readability.","href":"./ui_kits/blog/"},{"label":"chat kit","desc":"message thread + composer with pill bubbles and room sidebar.","href":"./ui_kits/chat/"},{"label":"aicat kit","desc":"ai assistant with cat persona — ascii portrait + mood face.","href":"./ui_kits/aicat/"},{"label":"slide deck","desc":"16:9 deck stage with improved presenter controls text.","href":"./slides/"},{"label":"dashboard kit","desc":"kpis, tables, receipts, changelog — operations surface.","href":"./ui_kits/dashboard/"},{"label":"terminal kit","desc":"cli prompt, command lines, log viewer.","href":"./ui_kits/terminal/"},{"label":"settings kit","desc":"sectioned forms, toggles, segmented buttons, save bar.","href":"./ui_kits/settings/"},{"label":"signin kit","desc":"auth panel, providers, magic link.","href":"./ui_kits/signin/"},{"label":"search kit","desc":"query bar, faceted filters, ranked results.","href":"./ui_kits/search/"},{"label":"404 kit","desc":"empty-state hero with suggested routes.","href":"./ui_kits/error_404/"},{"label":"gallery kit","desc":"visual grid + lightbox over tonal cards.","href":"./ui_kits/gallery/"},{"label":"preview samples","desc":"design previews and component samples.","href":"./preview/buttons.html"}],"bodyHtml":"","sidebar":{"sections":[{"group":"open","items":[{"glyph":"+","label":"open","href":"./ui_kits/homepage/"}]},{"group":"bins","items":[{"label":"everything","href":"#all","active":true,"count":43},{"label":"pinned","href":"#kits","count":14},{"label":"shipped","href":"#previews","count":25},{"label":"drafts","href":"#decks","count":1}]},{"group":"labels","items":[{"label":"ui kits","href":"#kits","count":14},{"label":"decks","href":"#decks","count":1},{"label":"previews","href":"#previews","count":25},{"label":"docs","href":"#docs","count":3}]},{"group":"more","items":[{"label":"readme","href":"https://github.com/AnEntrypoint/design/blob/main/README.md"},{"label":"skill","href":"https://github.com/AnEntrypoint/design/blob/main/SKILL.md"},{"label":"tokens","href":"https://github.com/AnEntrypoint/design/blob/main/colors_and_type.css"},{"label":"source","href":"https://github.com/AnEntrypoint/design"}]}]},"marquee":{"items":["open source","design tokens","buildless components","zero raw color literals"],"sep":"/"},"panels":[{"id":"kits","title":"ui kits","count":"14 surfaces","items":[{"code":"","title":"homepage","sub":"marquee + works grid","meta":"open ->","href":"./ui_kits/homepage/"},{"code":"","title":"project page","sub":"hero receipt install changelog","meta":"open ->","href":"./ui_kits/project_page/"},{"code":"","title":"docs","sub":"long-form prose chrome","meta":"open ->","href":"./ui_kits/docs/"},{"code":"","title":"blog","sub":"dated index + reading view","meta":"open ->","href":"./ui_kits/blog/"},{"code":"","title":"chat","sub":"message thread + composer","meta":"open ->","href":"./ui_kits/chat/"},{"code":"","title":"aicat","sub":"ai assistant with cat persona","meta":"open ->","href":"./ui_kits/aicat/"},{"code":"","title":"file browser","sub":"rails by file type drop preview","meta":"open ->","href":"./ui_kits/file_browser/"},{"code":"","title":"dashboard","sub":"kpis tables receipts changelog","meta":"open ->","href":"./ui_kits/dashboard/"},{"code":"","title":"terminal","sub":"cli prompt command lines log view","meta":"open ->","href":"./ui_kits/terminal/"},{"code":"","title":"settings","sub":"sectioned forms toggles save bar","meta":"open ->","href":"./ui_kits/settings/"},{"code":"","title":"signin","sub":"auth providers magic link","meta":"open ->","href":"./ui_kits/signin/"},{"code":"","title":"search","sub":"topbar query faceted filters rows","meta":"open ->","href":"./ui_kits/search/"},{"code":"","title":"404","sub":"empty-state hero suggested routes","meta":"open ->","href":"./ui_kits/error_404/"},{"code":"","title":"gallery","sub":"visual grid tonal cards lightbox","meta":"open ->","href":"./ui_kits/gallery/"}]},{"id":"file_browser","title":"file browser","count":"primitives","items":[{"code":"fb","title":"file_browser kit","sub":"drop, list, preview, dialogs","meta":"open kit","href":"./ui_kits/file_browser/"},{"code":"fb","title":"FileRow","sub":"rail icon name meta","meta":"preview","href":"./preview/file-row.html"},{"code":"fb","title":"FileGrid","sub":"stack of rows in a panel","meta":"preview","href":"./preview/file-grid.html"},{"code":"fb","title":"DropZone","sub":"tonal upload target","meta":"preview","href":"./preview/dropzone.html"},{"code":"fb","title":"FileViewer","sub":"modal preview keyed head","meta":"preview","href":"./preview/file-viewer.html"},{"code":"fb","title":"FileToolbar","sub":"actions breadcrumb upload","meta":"preview","href":"./preview/file-toolbar.html"},{"code":"fb","title":"fsbrowse","sub":"Express + busboy backend","meta":"source","href":"https://github.com/AnEntrypoint/fsbrowse"}]},{"id":"desktop_os","title":"desktop os shell","count":"in-page wm","items":[{"code":"os","title":"createDesktopShell","sub":"menubar apps launcher taskbar window manager","meta":"shell.js","href":"https://github.com/AnEntrypoint/design/blob/main/src/desktop/shell.js"},{"code":"os","title":"icons set","sub":"svg glyphs for menubar + taskbar","meta":"icons.js","href":"https://github.com/AnEntrypoint/design/blob/main/src/desktop/icons.js"},{"code":"os","title":"theme.css","sub":"os chrome tokens menubar launcher wm","meta":"theme.css","href":"https://github.com/AnEntrypoint/design/blob/main/src/desktop/theme.css"},{"code":"os","title":"import path","sub":"anentrypoint-design/desktop","meta":"exports","href":"https://github.com/AnEntrypoint/design/blob/main/package.json"}]},{"id":"web_components","title":"web components","count":"1 element","items":[{"code":"wc","title":"\u003cds-chat>","sub":"auto-registers when the sdk loads in a browser","meta":"ds-chat.js","href":"https://github.com/AnEntrypoint/design/blob/main/src/web-components/ds-chat.js"},{"code":"wc","title":"registerChatElement","sub":"manual register helper","meta":"source","href":"https://github.com/AnEntrypoint/design/blob/main/src/index.js"}]},{"id":"api_exports","title":"public api","count":"sdk surface","items":[{"code":"api","title":"h / applyDiff","sub":"webjsx createElement + diff","meta":"index.js","href":"https://github.com/AnEntrypoint/design/blob/main/src/index.js"},{"code":"api","title":"installStyles / scope","sub":"ds-247420 css scope + bootstrap","meta":"styles.js","href":"https://github.com/AnEntrypoint/design/blob/main/src/styles.js"},{"code":"api","title":"loadCss","sub":"fetch the bundled css string","meta":"styles.js","href":"https://github.com/AnEntrypoint/design/blob/main/src/styles.js"},{"code":"api","title":"mount / mountKit","sub":"ds shell + ui_kit bootstrap","meta":"bootstrap.js","href":"https://github.com/AnEntrypoint/design/blob/main/src/bootstrap.js"},{"code":"api","title":"registerDeckStage / getDeckStage","sub":"16:9 deck stage api","meta":"deck-stage.js","href":"https://github.com/AnEntrypoint/design/blob/main/src/deck-stage.js"},{"code":"api","title":"renderMarkdown","sub":"marked v15 + dompurify lazy stack","meta":"markdown.js","href":"https://github.com/AnEntrypoint/design/blob/main/src/markdown.js"},{"code":"api","title":"ensurePrism / highlightAllUnder","sub":"prism core + per-language","meta":"highlight.js","href":"https://github.com/AnEntrypoint/design/blob/main/src/highlight.js"},{"code":"api","title":"renderPageHtml","sub":"static page html template","meta":"page-html.js","href":"https://github.com/AnEntrypoint/design/blob/main/src/page-html.js"},{"code":"api","title":"components / motion / debug","sub":"namespaces from the default export","meta":"components.js","href":"https://github.com/AnEntrypoint/design/blob/main/src/components.js"}]},{"id":"decks","title":"decks","count":1,"items":[{"code":"","title":"deck template","sub":"16:9 stage with auto-fit","meta":"open ->","href":"./slides/"}]},{"id":"docs","title":"docs","count":3,"items":[{"code":"md","title":"readme","sub":"overview, manifesto, conventions","meta":"open ->","href":"https://github.com/AnEntrypoint/design/blob/main/README.md"},{"code":"md","title":"skill","sub":"authoring rules for the agent","meta":"open ->","href":"https://github.com/AnEntrypoint/design/blob/main/SKILL.md"},{"code":"css","title":"tokens","sub":"colors, type, panel surface tokens","meta":"open ->","href":"https://github.com/AnEntrypoint/design/blob/main/colors_and_type.css"}]},{"id":"features","title":"why design","count":4,"items":[{"code":"","title":"layered surfaces","sub":"panel-on-panel rhythm; loud content sits inside quiet chrome.","meta":"panel-row.css","href":"https://github.com/AnEntrypoint/design/blob/main/src/css/app-shell/panel-row.css"},{"code":"","title":"monospace labels","sub":"mono only for codes/labels/CLI; sans for everything legible.","meta":"colors_and_type.css","href":"https://github.com/AnEntrypoint/design/blob/main/colors_and_type.css"},{"code":"","title":"indicator rails","sub":"color-coded inset rails for category separation, never borders.","meta":"panel-row.css","href":"https://github.com/AnEntrypoint/design/blob/main/src/css/app-shell/panel-row.css#L126"},{"code":"","title":"tokens-only","sub":"every surface, type ramp, accent driven by --panel-* / --fs-* tokens.","meta":"colors_and_type.css","href":"https://github.com/AnEntrypoint/design/blob/main/colors_and_type.css"}]},{"id":"previews","title":"previews","count":25,"items":[{"code":"","title":"buttons","sub":"preview · buttons.html","meta":"open ->","href":"./preview/buttons.html"},{"code":"","title":"colors core","sub":"preview · colors-core.html","meta":"open ->","href":"./preview/colors-core.html"},{"code":"","title":"colors lore","sub":"preview · colors-lore.html","meta":"open ->","href":"./preview/colors-lore.html"},{"code":"","title":"colors semantic","sub":"preview · colors-semantic.html","meta":"open ->","href":"./preview/colors-semantic.html"},{"code":"","title":"dateline","sub":"preview · dateline.html","meta":"open ->","href":"./preview/dateline.html"},{"code":"","title":"dropzone","sub":"preview · dropzone.html","meta":"open ->","href":"./preview/dropzone.html"},{"code":"","title":"file grid","sub":"preview · file-grid.html","meta":"open ->","href":"./preview/file-grid.html"},{"code":"","title":"file row","sub":"preview · file-row.html","meta":"open ->","href":"./preview/file-row.html"},{"code":"","title":"file toolbar","sub":"preview · file-toolbar.html","meta":"open ->","href":"./preview/file-toolbar.html"},{"code":"","title":"file viewer","sub":"preview · file-viewer.html","meta":"open ->","href":"./preview/file-viewer.html"},{"code":"","title":"header","sub":"preview · header.html","meta":"open ->","href":"./preview/header.html"},{"code":"","title":"icons unicode","sub":"preview · icons-unicode.html","meta":"open ->","href":"./preview/icons-unicode.html"},{"code":"","title":"index row","sub":"preview · index-row.html","meta":"open ->","href":"./preview/index-row.html"},{"code":"","title":"inputs","sub":"preview · inputs.html","meta":"open ->","href":"./preview/inputs.html"},{"code":"","title":"manifesto","sub":"preview · manifesto.html","meta":"open ->","href":"./preview/manifesto.html"},{"code":"","title":"rules","sub":"preview · rules.html","meta":"open ->","href":"./preview/rules.html"},{"code":"","title":"spacing","sub":"preview · spacing.html","meta":"open ->","href":"./preview/spacing.html"},{"code":"","title":"stamps","sub":"preview · stamps.html","meta":"open ->","href":"./preview/stamps.html"},{"code":"","title":"stamps lore","sub":"preview · stamps-lore.html","meta":"open ->","href":"./preview/stamps-lore.html"},{"code":"","title":"theme ink","sub":"preview · theme-ink.html","meta":"open ->","href":"./preview/theme-ink.html"},{"code":"","title":"type display","sub":"preview · type-display.html","meta":"open ->","href":"./preview/type-display.html"},{"code":"","title":"type mono","sub":"preview · type-mono.html","meta":"open ->","href":"./preview/type-mono.html"},{"code":"","title":"type prose","sub":"preview · type-prose.html","meta":"open ->","href":"./preview/type-prose.html"},{"code":"","title":"type scale","sub":"preview · type-scale.html","meta":"open ->","href":"./preview/type-scale.html"},{"code":"","title":"wordmarks","sub":"preview · wordmarks.html","meta":"open ->","href":"./preview/wordmarks.html"}]}],"quickstart":{"heading":"quick start","lines":[{"kind":"cmt","text":"# install via importmap (no bundler)"},{"kind":"cmd","text":"\u003cscript type='importmap'>{\"imports\":{\"anentrypoint-design\":\"https://unpkg.com/anentrypoint-design@latest/dist/247420.js\"}}\u003c/script>"},{"kind":"cmt","text":"# or clone the source"},{"kind":"cmd","text":"git clone https://github.com/AnEntrypoint/design.git"}]},"statusLeft":["main","utf-8","lf"],"statusRight":["anentrypoint-design@latest","14 kits"]}</script>
|
|
98
120
|
<style>html,body{margin:0;padding:0}body{background:var(--bg,#F6F5F1);color:var(--fg,#131318);font-family:var(--ff-body,system-ui,sans-serif)}</style>
|
|
99
121
|
</head>
|
|
100
122
|
<body>
|
|
@@ -183,6 +205,39 @@ function marqueeNode(marquee) {
|
|
|
183
205
|
return C.Marquee ? C.Marquee({ items: marquee.items, sep: marquee.sep || '/' }) : null;
|
|
184
206
|
}
|
|
185
207
|
|
|
208
|
+
let __copyResetTimer = null;
|
|
209
|
+
function copyQuickstart(text, btnEl) {
|
|
210
|
+
const done = (ok) => {
|
|
211
|
+
if (!btnEl) return;
|
|
212
|
+
btnEl.textContent = ok ? 'copied' : 'copy failed';
|
|
213
|
+
clearTimeout(__copyResetTimer);
|
|
214
|
+
__copyResetTimer = setTimeout(() => { btnEl.textContent = 'copy'; }, 1600);
|
|
215
|
+
};
|
|
216
|
+
if (navigator.clipboard && navigator.clipboard.writeText) {
|
|
217
|
+
navigator.clipboard.writeText(text).then(() => done(true), () => copyViaTextarea(text, done));
|
|
218
|
+
} else {
|
|
219
|
+
copyViaTextarea(text, done);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
// Fallback for non-secure contexts / browsers without navigator.clipboard:
|
|
223
|
+
// a hidden textarea + document.execCommand('copy'), the standard shim.
|
|
224
|
+
function copyViaTextarea(text, done) {
|
|
225
|
+
try {
|
|
226
|
+
const ta = document.createElement('textarea');
|
|
227
|
+
ta.value = text;
|
|
228
|
+
ta.style.position = 'fixed';
|
|
229
|
+
ta.style.opacity = '0';
|
|
230
|
+
document.body.appendChild(ta);
|
|
231
|
+
ta.focus();
|
|
232
|
+
ta.select();
|
|
233
|
+
const ok = document.execCommand('copy');
|
|
234
|
+
document.body.removeChild(ta);
|
|
235
|
+
done(ok);
|
|
236
|
+
} catch (_e) {
|
|
237
|
+
done(false);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
186
241
|
function quickstartNode(quickstart) {
|
|
187
242
|
if (!quickstart || !Array.isArray(quickstart.lines) || !quickstart.lines.length) return null;
|
|
188
243
|
// A single .cli wrapper holding .ds-cli-row/.ds-cli-comment children, not
|
|
@@ -196,7 +251,19 @@ function quickstartNode(quickstart) {
|
|
|
196
251
|
: h('div', { key: 'q' + i, class: 'ds-cli-row' },
|
|
197
252
|
h('span', { class: 'prompt' }, '$'),
|
|
198
253
|
h('span', { class: 'cmd' }, l.text)));
|
|
199
|
-
|
|
254
|
+
// Copy the whole snippet (comment lines included) as one paste-ready block,
|
|
255
|
+
// not just the command lines -- a reader copying "the quick start" expects
|
|
256
|
+
// what they see, not a silently filtered subset.
|
|
257
|
+
const fullText = quickstart.lines.map((l) => l.text).join('\n');
|
|
258
|
+
const copyBtn = h('button', {
|
|
259
|
+
type: 'button', class: 'copy ds-quickstart-copy',
|
|
260
|
+
'aria-label': 'copy quick start snippet',
|
|
261
|
+
onclick: (e) => copyQuickstart(fullText, e.currentTarget),
|
|
262
|
+
}, 'copy');
|
|
263
|
+
return C.Panel({
|
|
264
|
+
title: quickstart.heading || 'quick start',
|
|
265
|
+
children: h('div', { class: 'cli ds-quickstart-cli' }, h('div', { class: 'ds-cli-block' }, ...lineNodes), copyBtn),
|
|
266
|
+
});
|
|
200
267
|
}
|
|
201
268
|
|
|
202
269
|
function sideNode(sidebar) {
|
|
@@ -227,6 +294,21 @@ function __md(md) {
|
|
|
227
294
|
|
|
228
295
|
const bodyNode = data.bodyHtml ? C.Section({ children: h('div', { class: 'page-body', innerHTML: data.bodyHtml }) }) : null;
|
|
229
296
|
|
|
297
|
+
// A real closing block: the page previously just stopped after its last
|
|
298
|
+
// panel, leaving nothing but the app-stage's own bottom padding as unexplained
|
|
299
|
+
// empty space. Reuses data already on the page (nav links, siteName, year) —
|
|
300
|
+
// no invented content.
|
|
301
|
+
function footerNode() {
|
|
302
|
+
const year = new Date().getFullYear();
|
|
303
|
+
const links = (data.navItems || []).filter(([, href]) => /^https?:/.test(String(href)));
|
|
304
|
+
return h('footer', { class: 'ds-page-footer' },
|
|
305
|
+
h('span', { class: 'ds-page-footer-copy' }, String(year) + ' · ' + data.siteName),
|
|
306
|
+
links.length ? h('nav', { class: 'ds-page-footer-links', 'aria-label': 'footer' },
|
|
307
|
+
...links.map(([label, href], i) => h('a', { key: i, href }, String(label).replace(' ->', '')))
|
|
308
|
+
) : null,
|
|
309
|
+
);
|
|
310
|
+
}
|
|
311
|
+
|
|
230
312
|
function tierNode(tier, children) {
|
|
231
313
|
const kids = children.filter(Boolean);
|
|
232
314
|
if (!kids.length) return null;
|
|
@@ -264,6 +346,7 @@ const mainChildren = [
|
|
|
264
346
|
...tierNodes,
|
|
265
347
|
...leftoverPanels,
|
|
266
348
|
bodyNode,
|
|
349
|
+
footerNode(),
|
|
267
350
|
].filter(Boolean);
|
|
268
351
|
|
|
269
352
|
mount(document.getElementById('app'), () => C.AppShell({
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "anentrypoint-design",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.456",
|
|
4
4
|
"description": "247420 design system SDK — webjsx + modified ripple-ui, single-file ESM bundle for reproducible use of the AnEntrypoint design.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/247420.js",
|
|
@@ -81,7 +81,7 @@ export function AgentControls({ agents, selectedAgent, models, selectedModel, bu
|
|
|
81
81
|
// renders them as a breadcrumb + clickable dir list right in the composer
|
|
82
82
|
// — no round-trip through the Files tab and back required anymore.
|
|
83
83
|
export function CwdBar({ cwd, editing, draft, onEdit, onSave, onCancel, onClear, onDraft, error, checking,
|
|
84
|
-
roots, recent, browse, onBrowseCrumb, onBrowseEnter, onBrowsePick, onBrowseToggle }) {
|
|
84
|
+
roots, recent, browse, onBrowseCrumb, onBrowseEnter, onBrowsePick, onBrowseToggle, defaultCwd }) {
|
|
85
85
|
if (editing) {
|
|
86
86
|
const hint = checking ? 'checking…' : (error || null);
|
|
87
87
|
const rootsRow = (roots && roots.length)
|
|
@@ -139,5 +139,9 @@ export function CwdBar({ cwd, editing, draft, onEdit, onSave, onCancel, onClear,
|
|
|
139
139
|
h('span', { class: 'agentchat-cwd-text', title: cwd || 'server default working directory' },
|
|
140
140
|
'cwd: ' + (cwd || 'server default')),
|
|
141
141
|
h('button', { type: 'button', class: 'agentchat-cwd-btn', onclick: () => onEdit && onEdit() }, cwd ? 'change' : 'set'),
|
|
142
|
-
|
|
142
|
+
// What "default" resolves to previously wasn't visible until clicked -
|
|
143
|
+
// a title tooltip on the button itself answers that before the click.
|
|
144
|
+
cwd ? h('button', { type: 'button', class: 'agentchat-cwd-btn',
|
|
145
|
+
title: defaultCwd ? ('resets to: ' + defaultCwd) : 'reset to the server default working directory',
|
|
146
|
+
onclick: () => onClear && onClear() }, 'use default') : null);
|
|
143
147
|
}
|
|
@@ -28,7 +28,7 @@ export function AgentChat(props = {}) {
|
|
|
28
28
|
agents = [], selectedAgent = '', models = [], selectedModel = '', modelsLoading = false, agentsLoading = false,
|
|
29
29
|
messages = [], busy = false, draft = '', status, banners = [],
|
|
30
30
|
cwd = '', cwdEditing = false, cwdDraft, cwdError, cwdChecking = false,
|
|
31
|
-
cwdRoots, cwdRecent, cwdBrowse,
|
|
31
|
+
cwdRoots, cwdRecent, cwdBrowse, defaultCwd,
|
|
32
32
|
agentName, placeholder,
|
|
33
33
|
onSelectAgent, onSelectModel, onSend, onStop, onNewChat, onInput,
|
|
34
34
|
onCwdEdit, onCwdSave, onCwdCancel, onCwdClear, onCwdDraft,
|
|
@@ -197,7 +197,7 @@ export function AgentChat(props = {}) {
|
|
|
197
197
|
AgentControls({ agents, selectedAgent, models, selectedModel, busy, status, modelsLoading, agentsLoading,
|
|
198
198
|
onSelectAgent, onSelectModel, onNewChat, onStop, exportActions }),
|
|
199
199
|
CwdBar({ cwd, editing: cwdEditing, draft: cwdDraft, error: cwdError, checking: cwdChecking,
|
|
200
|
-
roots: cwdRoots, recent: cwdRecent, browse: cwdBrowse,
|
|
200
|
+
roots: cwdRoots, recent: cwdRecent, browse: cwdBrowse, defaultCwd,
|
|
201
201
|
onEdit: onCwdEdit, onSave: onCwdSave, onCancel: onCwdCancel, onClear: onCwdClear, onDraft: onCwdDraft,
|
|
202
202
|
onBrowseToggle: onCwdBrowseToggle, onBrowseCrumb: onCwdBrowseCrumb, onBrowseEnter: onCwdBrowseEnter, onBrowsePick: onCwdBrowsePick }),
|
|
203
203
|
...(banners || []).filter(Boolean),
|
|
@@ -144,7 +144,7 @@ function langFromFilename(filename = '') {
|
|
|
144
144
|
// highlight.js's Prism loader for language detection by file extension; the
|
|
145
145
|
// +/- marker column is drawn by CSS (tone classes), Prism only tokenizes the
|
|
146
146
|
// code content inside each line.
|
|
147
|
-
export function GitDiffView({ diff = '', filename } = {}) {
|
|
147
|
+
export function GitDiffView({ diff = '', filename, binary = false } = {}) {
|
|
148
148
|
const hunks = parseUnifiedDiff(diff);
|
|
149
149
|
const lang = langFromFilename(filename);
|
|
150
150
|
const highlightRef = (el) => {
|
|
@@ -152,7 +152,11 @@ export function GitDiffView({ diff = '', filename } = {}) {
|
|
|
152
152
|
try { highlightAllUnder(el); } catch { /* swallow: progressive enhancement only */ }
|
|
153
153
|
};
|
|
154
154
|
if (!hunks.length) {
|
|
155
|
-
|
|
155
|
+
// A binary changed file produces no unified diff at all - saying
|
|
156
|
+
// "no diff to show" reads as "nothing changed", which is wrong and
|
|
157
|
+
// misleading; name the real reason instead.
|
|
158
|
+
return h('div', { class: 'ds-git-diff-empty', role: 'status' },
|
|
159
|
+
binary ? 'binary file, diff not shown' : 'no diff to show');
|
|
156
160
|
}
|
|
157
161
|
return h('div', { class: 'ds-git-diff', ref: highlightRef },
|
|
158
162
|
filename ? h('div', { class: 'ds-git-diff-head' }, h('span', { class: 'name' }, filename)) : null,
|
|
@@ -156,7 +156,11 @@ export function SessionDashboard({ sessions = [], onStop, onOpen, onView, onStop
|
|
|
156
156
|
selectable && selCount
|
|
157
157
|
? h('span', { key: 'cnt', class: 'ds-dash-count', role: 'status', 'aria-live': 'polite' }, selCount + ' selected')
|
|
158
158
|
: (breakdown || h('span', { key: 'cnt', class: 'ds-dash-count', role: 'status', 'aria-live': 'polite' },
|
|
159
|
-
|
|
159
|
+
// A "0 running" count is only trustworthy once the stream has
|
|
160
|
+
// actually connected - while still connecting/offline, zero means
|
|
161
|
+
// "no data yet", not "verified empty", and must read as such.
|
|
162
|
+
sessions.length ? sessions.length + ' running'
|
|
163
|
+
: (streamState && streamState !== 'connected' ? '— running (' + (STREAM_WORD[streamState] || streamState) + ')' : '0 running'))),
|
|
160
164
|
selectAllCtl, clearCtl, streamLine,
|
|
161
165
|
h('span', { key: 'spread', class: 'spread' }),
|
|
162
166
|
// No stop control without a session to stop; the empty dashboard keeps
|
|
@@ -127,6 +127,24 @@
|
|
|
127
127
|
static readouts). */
|
|
128
128
|
.ds-session-row[role="button"], a.ds-session-row { cursor: pointer; }
|
|
129
129
|
|
|
130
|
+
/* ConversationList's title/meta layout had no dedicated rule anywhere (only a
|
|
131
|
+
stray cross-reference comment in panel-row.css), so the title sat at flex's
|
|
132
|
+
default 0-basis and lost the space race to its meta siblings (agent name,
|
|
133
|
+
status dot) - titles truncated to a character or two ("d…") well before the
|
|
134
|
+
row ran out of real width. .ds-session-main grows to fill the row; its
|
|
135
|
+
title/sub children get the min-width:0 an ellipsis needs inside a flex
|
|
136
|
+
item; the meta/actions siblings take only what their content needs. */
|
|
137
|
+
.ds-session-main { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 0; }
|
|
138
|
+
.ds-session-title {
|
|
139
|
+
display: block; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
|
|
140
|
+
font-size: var(--fs-sm); font-weight: 500; color: var(--fg);
|
|
141
|
+
}
|
|
142
|
+
.ds-session-sub {
|
|
143
|
+
display: block; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
|
|
144
|
+
font-size: var(--fs-micro); color: var(--fg-3);
|
|
145
|
+
}
|
|
146
|
+
.ds-session-meta, .ds-session-row-actions { flex: 0 0 auto; display: flex; align-items: center; gap: var(--space-1); }
|
|
147
|
+
|
|
130
148
|
/* Sub-parts that decorate the row above. */
|
|
131
149
|
.ds-session-row-id {
|
|
132
150
|
font-family: var(--ff-mono); font-size: var(--fs-micro); color: var(--accent-ink);
|
|
@@ -217,13 +217,33 @@
|
|
|
217
217
|
padding: 3px 0;
|
|
218
218
|
}
|
|
219
219
|
.ds-cli-row .prompt { color: var(--green-2); flex: 0 0 auto; user-select: none; }
|
|
220
|
-
|
|
220
|
+
/* `overflow-wrap: break-word` only breaks a token when it genuinely cannot
|
|
221
|
+
fit the line at all (last resort); `word-break: break-word` (its
|
|
222
|
+
predecessor here) breaks ANY overflowing token eagerly, which is what
|
|
223
|
+
split "anentrypoint-design" mid-identifier inside the importmap JSON line.
|
|
224
|
+
`min-width: 0` lets the flex child actually shrink to trigger wrapping
|
|
225
|
+
instead of pushing the panel wider. */
|
|
226
|
+
.ds-cli-row .cmd { flex: 1 1 auto; min-width: 0; white-space: pre-wrap; overflow-wrap: break-word; word-break: normal; color: var(--paper); }
|
|
221
227
|
.ds-cli-comment {
|
|
222
228
|
color: var(--fg-3);
|
|
223
229
|
font-family: var(--ff-mono); font-size: var(--fs-tiny); line-height: 1.6;
|
|
224
|
-
padding: 3px 0; white-space: pre-wrap;
|
|
230
|
+
padding: 3px 0; white-space: pre-wrap; overflow-wrap: break-word; word-break: normal;
|
|
225
231
|
}
|
|
226
232
|
|
|
233
|
+
/* Quickstart copy button: sits below the multi-line block (Install's inline
|
|
234
|
+
copy button assumes a single-line row with room beside it; the stacked
|
|
235
|
+
quickstart block has no such side room). */
|
|
236
|
+
.ds-quickstart-cli { flex-direction: column; align-items: stretch; gap: var(--space-2); }
|
|
237
|
+
.ds-quickstart-copy {
|
|
238
|
+
align-self: flex-end;
|
|
239
|
+
padding: 8px 16px; background: transparent; color: var(--paper);
|
|
240
|
+
font-family: var(--ff-mono); font-size: var(--fs-tiny); text-transform: uppercase; letter-spacing: var(--tr-caps);
|
|
241
|
+
cursor: pointer; box-shadow: inset 0 0 0 1px var(--rule-strong);
|
|
242
|
+
border-radius: var(--r-pill); border: none;
|
|
243
|
+
}
|
|
244
|
+
.ds-quickstart-copy:hover { background: var(--fg-3); }
|
|
245
|
+
.ds-quickstart-copy:focus-visible { outline: var(--focus-w) solid var(--focus-color); outline-offset: var(--focus-offset); }
|
|
246
|
+
|
|
227
247
|
/* ============================================================
|
|
228
248
|
Receipt — key/value table
|
|
229
249
|
============================================================ */
|
|
@@ -155,7 +155,12 @@ body.canvas-host { background: transparent !important; }
|
|
|
155
155
|
.app-crumb .leaf { color: var(--fg); font-weight: 600; }
|
|
156
156
|
.app-crumb .crumb-right { margin-left: auto; color: var(--fg-3); }
|
|
157
157
|
|
|
158
|
-
.app-
|
|
158
|
+
/* The shell is the grid cell (.app-body's fixed sidebar column); it must own
|
|
159
|
+
its own scroll, not just size to content, because .app-body's row track is
|
|
160
|
+
`minmax(0, 1fr)` — a real height the sidebar can overflow once bins +
|
|
161
|
+
labels + more exceed it. Without this the extra rows were silently chopped
|
|
162
|
+
at the viewport edge with no way to reach them. */
|
|
163
|
+
.app-side-shell { background: var(--bg); overflow-y: auto; min-height: 0; }
|
|
159
164
|
.app-body { display: grid; grid-template-columns: var(--sidebar-width) minmax(0, 1fr); grid-template-rows: minmax(0, 1fr); align-items: stretch; align-content: stretch; flex: 1; min-height: 0; }
|
|
160
165
|
.app-body.no-side { grid-template-columns: minmax(0, 1fr); }
|
|
161
166
|
/* When there is no sidebar, the empty side-shell must not occupy a grid row,
|
|
@@ -91,6 +91,39 @@ function marqueeNode(marquee) {
|
|
|
91
91
|
return C.Marquee ? C.Marquee({ items: marquee.items, sep: marquee.sep || '/' }) : null;
|
|
92
92
|
}
|
|
93
93
|
|
|
94
|
+
let __copyResetTimer = null;
|
|
95
|
+
function copyQuickstart(text, btnEl) {
|
|
96
|
+
const done = (ok) => {
|
|
97
|
+
if (!btnEl) return;
|
|
98
|
+
btnEl.textContent = ok ? 'copied' : 'copy failed';
|
|
99
|
+
clearTimeout(__copyResetTimer);
|
|
100
|
+
__copyResetTimer = setTimeout(() => { btnEl.textContent = 'copy'; }, 1600);
|
|
101
|
+
};
|
|
102
|
+
if (navigator.clipboard && navigator.clipboard.writeText) {
|
|
103
|
+
navigator.clipboard.writeText(text).then(() => done(true), () => copyViaTextarea(text, done));
|
|
104
|
+
} else {
|
|
105
|
+
copyViaTextarea(text, done);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
// Fallback for non-secure contexts / browsers without navigator.clipboard:
|
|
109
|
+
// a hidden textarea + document.execCommand('copy'), the standard shim.
|
|
110
|
+
function copyViaTextarea(text, done) {
|
|
111
|
+
try {
|
|
112
|
+
const ta = document.createElement('textarea');
|
|
113
|
+
ta.value = text;
|
|
114
|
+
ta.style.position = 'fixed';
|
|
115
|
+
ta.style.opacity = '0';
|
|
116
|
+
document.body.appendChild(ta);
|
|
117
|
+
ta.focus();
|
|
118
|
+
ta.select();
|
|
119
|
+
const ok = document.execCommand('copy');
|
|
120
|
+
document.body.removeChild(ta);
|
|
121
|
+
done(ok);
|
|
122
|
+
} catch (_e) {
|
|
123
|
+
done(false);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
94
127
|
function quickstartNode(quickstart) {
|
|
95
128
|
if (!quickstart || !Array.isArray(quickstart.lines) || !quickstart.lines.length) return null;
|
|
96
129
|
// A single .cli wrapper holding .ds-cli-row/.ds-cli-comment children, not
|
|
@@ -104,7 +137,19 @@ function quickstartNode(quickstart) {
|
|
|
104
137
|
: h('div', { key: 'q' + i, class: 'ds-cli-row' },
|
|
105
138
|
h('span', { class: 'prompt' }, '$'),
|
|
106
139
|
h('span', { class: 'cmd' }, l.text)));
|
|
107
|
-
|
|
140
|
+
// Copy the whole snippet (comment lines included) as one paste-ready block,
|
|
141
|
+
// not just the command lines -- a reader copying "the quick start" expects
|
|
142
|
+
// what they see, not a silently filtered subset.
|
|
143
|
+
const fullText = quickstart.lines.map((l) => l.text).join('\\n');
|
|
144
|
+
const copyBtn = h('button', {
|
|
145
|
+
type: 'button', class: 'copy ds-quickstart-copy',
|
|
146
|
+
'aria-label': 'copy quick start snippet',
|
|
147
|
+
onclick: (e) => copyQuickstart(fullText, e.currentTarget),
|
|
148
|
+
}, 'copy');
|
|
149
|
+
return C.Panel({
|
|
150
|
+
title: quickstart.heading || 'quick start',
|
|
151
|
+
children: h('div', { class: 'cli ds-quickstart-cli' }, h('div', { class: 'ds-cli-block' }, ...lineNodes), copyBtn),
|
|
152
|
+
});
|
|
108
153
|
}
|
|
109
154
|
|
|
110
155
|
function sideNode(sidebar) {
|
|
@@ -135,6 +180,21 @@ function __md(md) {
|
|
|
135
180
|
|
|
136
181
|
const bodyNode = data.bodyHtml ? C.Section({ children: h('div', { class: 'page-body', innerHTML: data.bodyHtml }) }) : null;
|
|
137
182
|
|
|
183
|
+
// A real closing block: the page previously just stopped after its last
|
|
184
|
+
// panel, leaving nothing but the app-stage's own bottom padding as unexplained
|
|
185
|
+
// empty space. Reuses data already on the page (nav links, siteName, year) —
|
|
186
|
+
// no invented content.
|
|
187
|
+
function footerNode() {
|
|
188
|
+
const year = new Date().getFullYear();
|
|
189
|
+
const links = (data.navItems || []).filter(([, href]) => /^https?:/.test(String(href)));
|
|
190
|
+
return h('footer', { class: 'ds-page-footer' },
|
|
191
|
+
h('span', { class: 'ds-page-footer-copy' }, String(year) + ' · ' + data.siteName),
|
|
192
|
+
links.length ? h('nav', { class: 'ds-page-footer-links', 'aria-label': 'footer' },
|
|
193
|
+
...links.map(([label, href], i) => h('a', { key: i, href }, String(label).replace(' ->', '')))
|
|
194
|
+
) : null,
|
|
195
|
+
);
|
|
196
|
+
}
|
|
197
|
+
|
|
138
198
|
function tierNode(tier, children) {
|
|
139
199
|
const kids = children.filter(Boolean);
|
|
140
200
|
if (!kids.length) return null;
|
|
@@ -172,6 +232,7 @@ const mainChildren = [
|
|
|
172
232
|
...tierNodes,
|
|
173
233
|
...leftoverPanels,
|
|
174
234
|
bodyNode,
|
|
235
|
+
footerNode(),
|
|
175
236
|
].filter(Boolean);
|
|
176
237
|
|
|
177
238
|
mount(document.getElementById('app'), () => C.AppShell({
|
|
@@ -51,7 +51,13 @@ export const PAGE_INLINE_STYLES = `
|
|
|
51
51
|
a.row:hover .ds-row-arrow { opacity: 1 }
|
|
52
52
|
/* hero stat strip — all badges as a wrapping inline rhythm, not one empty panel */
|
|
53
53
|
.ds-hero-stats { display: flex; flex-wrap: wrap; gap: var(--space-3, 16px) var(--space-5, 32px); margin-top: var(--space-2, 8px) }
|
|
54
|
-
.ds-hero-stat
|
|
54
|
+
/* hero-content.css's .ds-hero-stat is styled for a vertical stacked list
|
|
55
|
+
(border-bottom row divider, meant to read top-to-bottom); this page renders
|
|
56
|
+
badges in a horizontal row instead (.ds-hero-stats above), where that same
|
|
57
|
+
border reads as an underlined tab strip -- an affordance for a set of
|
|
58
|
+
plain, non-interactive metadata chips. Reset both inherited properties so a
|
|
59
|
+
row of badges never borrows tab-bar chrome it did not opt into. */
|
|
60
|
+
.ds-hero-stat { display: flex; align-items: baseline; gap: var(--space-2, 8px); border-bottom: none !important; padding-bottom: 0 !important }
|
|
55
61
|
.ds-hero-stat-n { font-family: var(--ff-body); font-weight: 700; font-size: var(--fs-lg, 18px); color: var(--fg) }
|
|
56
62
|
.ds-hero-stat-l { font-size: var(--fs-sm, 15px); color: var(--fg-3) }
|
|
57
63
|
/* accent sits on its own line, muted, so it reads as a distinct aside instead
|
|
@@ -68,4 +74,20 @@ a.row:hover .ds-row-arrow { opacity: 1 }
|
|
|
68
74
|
.ds-feature-title { font-weight: 600; font-size: var(--fs-lg, 18px); color: var(--fg) }
|
|
69
75
|
.ds-feature-desc { font-size: var(--fs-sm, 15px); color: var(--fg-2); line-height: 1.5; overflow-wrap: anywhere }
|
|
70
76
|
.ds-feature-benefit { font-style: italic; font-size: var(--fs-sm, 15px); color: var(--fg-3); margin-top: var(--space-1, 4px) }
|
|
77
|
+
/* Real closing content instead of the page simply stopping after its last
|
|
78
|
+
panel — a tonal divider line, a copyright string, and the same external
|
|
79
|
+
links the topbar already carries (footer.js reuses data.navItems, so this
|
|
80
|
+
is never invented content). Sits inside .app-stage's own grid gap like
|
|
81
|
+
every other block, no extra margin needed. */
|
|
82
|
+
.ds-page-footer {
|
|
83
|
+
display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
|
|
84
|
+
gap: var(--space-3, 16px);
|
|
85
|
+
padding-top: var(--space-5, 32px);
|
|
86
|
+
margin-top: var(--space-3, 16px);
|
|
87
|
+
border-top: 1px solid var(--rule, var(--bg-3));
|
|
88
|
+
color: var(--fg-3); font-size: var(--fs-sm, 15px);
|
|
89
|
+
}
|
|
90
|
+
.ds-page-footer-links { display: flex; gap: var(--space-4, 24px) }
|
|
91
|
+
.ds-page-footer-links a { color: var(--fg-3) }
|
|
92
|
+
.ds-page-footer-links a:hover { color: var(--fg) }
|
|
71
93
|
`.trim();
|
package/types/components.d.ts
CHANGED