diff options
Diffstat (limited to '_ds/pantograph-design-system-56a1c74e-41c1-486b-ba3c-4eabdfacef31')
10 files changed, 2818 insertions, 0 deletions
diff --git a/_ds/pantograph-design-system-56a1c74e-41c1-486b-ba3c-4eabdfacef31/_adherence.oxlintrc.json b/_ds/pantograph-design-system-56a1c74e-41c1-486b-ba3c-4eabdfacef31/_adherence.oxlintrc.json new file mode 100644 index 0000000..d745f07 --- /dev/null +++ b/_ds/pantograph-design-system-56a1c74e-41c1-486b-ba3c-4eabdfacef31/_adherence.oxlintrc.json @@ -0,0 +1,425 @@ +{ + "plugins": [ + "react", + "import" + ], + "rules": { + "react/forbid-elements": [ + "warn", + { + "forbid": [] + } + ], + "no-restricted-imports": [ + "warn", + { + "patterns": [ + { + "group": [ + "components/code/**", + "components/core/**", + "components/forms/**", + "components/navigation/**", + "ui_kits/docs/**", + "ui_kits/home/**" + ], + "message": "Import design-system components from 'index.js', not component internals." + } + ] + } + ], + "no-restricted-syntax": [ + "warn", + { + "selector": "Literal[value=/#[0-9a-fA-F]{3,8}\\b/]", + "message": "Raw hex color — use a design-system color token via var()." + }, + { + "selector": "Literal[value=/\\b\\d+px\\b/]", + "message": "Raw px value — use a design-system spacing token via var()." + }, + { + "selector": "Literal[value=/font-family\\s*:\\s*(?!['\\\"]?(?:IBM Plex Mono|Saira Condensed))/i]", + "message": "Font not provided by the design system. Available: IBM Plex Mono, Saira Condensed." + }, + { + "selector": "JSXOpeningElement[name.name='Badge'] > JSXAttribute > JSXIdentifier[name!=/^(?:variant|dot|children|key|ref|className|style|children)$/]", + "message": "<Badge> doesn't accept that prop. Declared props: variant, dot, children." + }, + { + "selector": "JSXOpeningElement[name.name='Badge'] > JSXAttribute[name.name='variant'] > Literal[value!=/^(?:neutral|danger|success|ink|outline)$/]", + "message": "<Badge> variant must be one of 'neutral' | 'danger' | 'success' | 'ink' | 'outline'." + }, + { + "selector": "JSXOpeningElement[name.name='Button'] > JSXAttribute > JSXIdentifier[name!=/^(?:variant|size|block|icon|iconRight|as|children|key|ref|className|style|children)$/]", + "message": "<Button> doesn't accept that prop. Declared props: variant, size, block, icon, iconRight, as, children." + }, + { + "selector": "JSXOpeningElement[name.name='Button'] > JSXAttribute[name.name='variant'] > Literal[value!=/^(?:primary|accent|secondary|ghost|danger)$/]", + "message": "<Button> variant must be one of 'primary' | 'accent' | 'secondary' | 'ghost' | 'danger'." + }, + { + "selector": "JSXOpeningElement[name.name='Button'] > JSXAttribute[name.name='size'] > Literal[value!=/^(?:sm|md|lg)$/]", + "message": "<Button> size must be one of 'sm' | 'md' | 'lg'." + }, + { + "selector": "JSXOpeningElement[name.name='Button'] > JSXAttribute[name.name='as'] > Literal[value!=/^(?:button|a)$/]", + "message": "<Button> as must be one of 'button' | 'a'." + }, + { + "selector": "JSXOpeningElement[name.name='Callout'] > JSXAttribute > JSXIdentifier[name!=/^(?:variant|title|icon|children|key|ref|className|style|children)$/]", + "message": "<Callout> doesn't accept that prop. Declared props: variant, title, icon, children." + }, + { + "selector": "JSXOpeningElement[name.name='Callout'] > JSXAttribute[name.name='variant'] > Literal[value!=/^(?:note|tip|warn|danger)$/]", + "message": "<Callout> variant must be one of 'note' | 'tip' | 'warn' | 'danger'." + }, + { + "selector": "JSXOpeningElement[name.name='Card'] > JSXAttribute > JSXIdentifier[name!=/^(?:variant|ruled|interactive|title|actions|footer|children|key|ref|className|style|children)$/]", + "message": "<Card> doesn't accept that prop. Declared props: variant, ruled, interactive, title, actions, footer, children." + }, + { + "selector": "JSXOpeningElement[name.name='Card'] > JSXAttribute[name.name='variant'] > Literal[value!=/^(?:default|flat|sunken|accent)$/]", + "message": "<Card> variant must be one of 'default' | 'flat' | 'sunken' | 'accent'." + }, + { + "selector": "JSXOpeningElement[name.name='CodeBlock'] > JSXAttribute > JSXIdentifier[name!=/^(?:code|language|filename|showBar|children|key|ref|className|style|children)$/]", + "message": "<CodeBlock> doesn't accept that prop. Declared props: code, language, filename, showBar, children." + }, + { + "selector": "JSXOpeningElement[name.name='IconButton'] > JSXAttribute > JSXIdentifier[name!=/^(?:size|bordered|active|label|children|key|ref|className|style|children)$/]", + "message": "<IconButton> doesn't accept that prop. Declared props: size, bordered, active, label, children." + }, + { + "selector": "JSXOpeningElement[name.name='IconButton'] > JSXAttribute[name.name='size'] > Literal[value!=/^(?:sm|md|lg)$/]", + "message": "<IconButton> size must be one of 'sm' | 'md' | 'lg'." + }, + { + "selector": "JSXOpeningElement[name.name='Input'] > JSXAttribute > JSXIdentifier[name!=/^(?:label|hint|error|icon|mono|required|key|ref|className|style|children)$/]", + "message": "<Input> doesn't accept that prop. Declared props: label, hint, error, icon, mono, required." + }, + { + "selector": "JSXOpeningElement[name.name='SelectOption'] > JSXAttribute > JSXIdentifier[name!=/^(?:value|label|key|ref|className|style|children)$/]", + "message": "<SelectOption> doesn't accept that prop. Declared props: value, label." + }, + { + "selector": "JSXOpeningElement[name.name='Switch'] > JSXAttribute > JSXIdentifier[name!=/^(?:checked|defaultChecked|label|key|ref|className|style|children)$/]", + "message": "<Switch> doesn't accept that prop. Declared props: checked, defaultChecked, label." + }, + { + "selector": "JSXOpeningElement[name.name='TabItem'] > JSXAttribute > JSXIdentifier[name!=/^(?:id|label|icon|key|ref|className|style|children)$/]", + "message": "<TabItem> doesn't accept that prop. Declared props: id, label, icon." + }, + { + "selector": "JSXOpeningElement[name.name='Tag'] > JSXAttribute > JSXIdentifier[name!=/^(?:dot|onRemove|interactive|children|key|ref|className|style|children)$/]", + "message": "<Tag> doesn't accept that prop. Declared props: dot, onRemove, interactive, children." + }, + { + "selector": "JSXOpeningElement[name.name='TerminalLine'] > JSXAttribute > JSXIdentifier[name!=/^(?:type|text|shell|key|ref|className|style|children)$/]", + "message": "<TerminalLine> doesn't accept that prop. Declared props: type, text, shell." + }, + { + "selector": "JSXOpeningElement[name.name='TerminalLine'] > JSXAttribute[name.name='type'] > Literal[value!=/^(?:cmd|out|ok|err|com)$/]", + "message": "<TerminalLine> type must be one of 'cmd' | 'out' | 'ok' | 'err' | 'com'." + }, + { + "selector": "JSXOpeningElement[name.name='TerminalLine'] > JSXAttribute[name.name='shell'] > Literal[value!=/^(?:shell|panto)$/]", + "message": "<TerminalLine> shell must be one of 'shell' | 'panto'." + } + ] + }, + "overrides": [ + { + "files": [ + "**/index.js" + ], + "rules": { + "no-restricted-imports": "off" + } + } + ], + "x-omelette": { + "components": { + "Badge": { + "replaces": [] + }, + "Button": { + "replaces": [] + }, + "Callout": { + "replaces": [] + }, + "Card": { + "replaces": [] + }, + "CodeBlock": { + "replaces": [] + }, + "IconButton": { + "replaces": [] + }, + "Input": { + "replaces": [] + }, + "SelectOption": { + "replaces": [] + }, + "Switch": { + "replaces": [] + }, + "TabItem": { + "replaces": [] + }, + "Tag": { + "replaces": [] + }, + "TerminalLine": { + "replaces": [] + } + }, + "tokens": [ + "--accent", + "--accent-deep", + "--border-default", + "--border-hairline", + "--border-medium", + "--border-strong", + "--border-thick", + "--border-thin", + "--brass", + "--container-prose", + "--container-wide", + "--dur-base", + "--dur-fast", + "--dur-slow", + "--ease-out", + "--ease-slide", + "--focus-ring", + "--font-display", + "--font-mono", + "--font-primary", + "--font-sans", + "--font-serif", + "--green", + "--green-deep", + "--green-soft", + "--green-wash", + "--ink-0", + "--ink-1", + "--ink-2", + "--ink-3", + "--ink-4", + "--leading-mono", + "--leading-normal", + "--leading-relaxed", + "--leading-snug", + "--leading-tight", + "--link", + "--link-hover", + "--paper-0", + "--paper-1", + "--paper-2", + "--paper-3", + "--paper-4", + "--radius-lg", + "--radius-md", + "--radius-none", + "--radius-pill", + "--radius-sm", + "--radius-xs", + "--red", + "--red-deep", + "--red-soft", + "--red-wash", + "--role-body", + "--role-code", + "--role-display", + "--role-h1", + "--role-h2", + "--role-h3", + "--role-label", + "--role-prose", + "--rule-tick", + "--shadow-inset", + "--shadow-lg", + "--shadow-md", + "--shadow-sm", + "--shadow-xs", + "--sidebar-width", + "--space-0", + "--space-1", + "--space-2", + "--space-3", + "--space-4", + "--space-5", + "--space-6", + "--space-7", + "--space-8", + "--space-9", + "--status-danger", + "--status-danger-bg", + "--status-info", + "--status-info-bg", + "--status-success", + "--status-success-bg", + "--surface-card", + "--surface-code", + "--surface-inverse", + "--surface-page", + "--surface-sunken", + "--text-2xl", + "--text-2xs", + "--text-3xl", + "--text-4xl", + "--text-5xl", + "--text-base", + "--text-body", + "--text-faint", + "--text-lg", + "--text-md", + "--text-muted", + "--text-on-accent", + "--text-on-ink", + "--text-placeholder", + "--text-sm", + "--text-strong", + "--text-xl", + "--text-xs", + "--tick-gradient", + "--tick-h-major", + "--tick-h-minor", + "--tick-pitch", + "--tracking-label", + "--tracking-normal", + "--tracking-tight", + "--weight-bold", + "--weight-medium", + "--weight-regular", + "--weight-semibold" + ], + "tokenKinds": { + "--paper-0": "color", + "--paper-1": "color", + "--paper-2": "color", + "--paper-3": "color", + "--paper-4": "color", + "--ink-0": "color", + "--ink-1": "color", + "--ink-2": "color", + "--ink-3": "color", + "--ink-4": "color", + "--red-deep": "color", + "--red": "color", + "--red-soft": "color", + "--red-wash": "color", + "--green-deep": "color", + "--green": "color", + "--green-soft": "color", + "--green-wash": "color", + "--brass": "color", + "--surface-page": "color", + "--surface-card": "color", + "--surface-sunken": "color", + "--surface-code": "color", + "--surface-inverse": "color", + "--text-strong": "font", + "--text-body": "font", + "--text-muted": "font", + "--text-faint": "font", + "--text-placeholder": "font", + "--text-on-ink": "font", + "--text-on-accent": "font", + "--border-hairline": "color", + "--border-default": "color", + "--border-strong": "color", + "--rule-tick": "color", + "--accent": "color", + "--accent-deep": "color", + "--link": "color", + "--link-hover": "color", + "--status-danger": "color", + "--status-danger-bg": "color", + "--status-success": "color", + "--status-success-bg": "color", + "--status-info": "color", + "--status-info-bg": "color", + "--focus-ring": "color", + "--font-primary": "font", + "--font-mono": "font", + "--font-display": "font", + "--font-sans": "font", + "--font-serif": "font", + "--text-2xs": "font", + "--text-xs": "font", + "--text-sm": "font", + "--text-base": "font", + "--text-md": "font", + "--text-lg": "font", + "--text-xl": "font", + "--text-2xl": "font", + "--text-3xl": "font", + "--text-4xl": "font", + "--text-5xl": "font", + "--weight-regular": "font", + "--weight-medium": "font", + "--weight-semibold": "font", + "--weight-bold": "font", + "--leading-tight": "font", + "--leading-snug": "font", + "--leading-normal": "font", + "--leading-relaxed": "font", + "--leading-mono": "font", + "--tracking-label": "font", + "--tracking-tight": "font", + "--tracking-normal": "font", + "--role-display": "color", + "--role-h1": "color", + "--role-h2": "color", + "--role-h3": "color", + "--role-body": "color", + "--role-prose": "color", + "--role-code": "color", + "--role-label": "color", + "--space-0": "spacing", + "--space-1": "spacing", + "--space-2": "spacing", + "--space-3": "spacing", + "--space-4": "spacing", + "--space-5": "spacing", + "--space-6": "spacing", + "--space-7": "spacing", + "--space-8": "spacing", + "--space-9": "spacing", + "--radius-none": "radius", + "--radius-xs": "radius", + "--radius-sm": "radius", + "--radius-md": "radius", + "--radius-lg": "radius", + "--radius-pill": "radius", + "--border-thin": "spacing", + "--border-medium": "spacing", + "--border-thick": "spacing", + "--shadow-xs": "shadow", + "--shadow-sm": "shadow", + "--shadow-md": "shadow", + "--shadow-lg": "shadow", + "--shadow-inset": "shadow", + "--tick-pitch": "spacing", + "--tick-h-major": "spacing", + "--tick-h-minor": "color", + "--tick-gradient": "color", + "--ease-slide": "other", + "--ease-out": "other", + "--dur-fast": "other", + "--dur-base": "other", + "--dur-slow": "other", + "--container-prose": "spacing", + "--container-wide": "spacing", + "--sidebar-width": "spacing" + }, + "fontFamilies": [ + "IBM Plex Mono", + "Saira Condensed" + ] + } +}
\ No newline at end of file diff --git a/_ds/pantograph-design-system-56a1c74e-41c1-486b-ba3c-4eabdfacef31/_ds_bundle.js b/_ds/pantograph-design-system-56a1c74e-41c1-486b-ba3c-4eabdfacef31/_ds_bundle.js new file mode 100644 index 0000000..f584806 --- /dev/null +++ b/_ds/pantograph-design-system-56a1c74e-41c1-486b-ba3c-4eabdfacef31/_ds_bundle.js @@ -0,0 +1,1878 @@ +/* @ds-bundle: {"format":3,"namespace":"PantographDesignSystem_56a1c7","components":[{"name":"Callout","sourcePath":"components/code/Callout.jsx"},{"name":"CodeBlock","sourcePath":"components/code/CodeBlock.jsx"},{"name":"Terminal","sourcePath":"components/code/Terminal.jsx"},{"name":"Badge","sourcePath":"components/core/Badge.jsx"},{"name":"Button","sourcePath":"components/core/Button.jsx"},{"name":"Card","sourcePath":"components/core/Card.jsx"},{"name":"IconButton","sourcePath":"components/core/IconButton.jsx"},{"name":"Tag","sourcePath":"components/core/Tag.jsx"},{"name":"Input","sourcePath":"components/forms/Input.jsx"},{"name":"Select","sourcePath":"components/forms/Select.jsx"},{"name":"Switch","sourcePath":"components/forms/Switch.jsx"},{"name":"Tabs","sourcePath":"components/navigation/Tabs.jsx"}],"sourceHashes":{"components/code/Callout.jsx":"dc74992ca3a8","components/code/CodeBlock.jsx":"75f95cdb07d4","components/code/Terminal.jsx":"32207bf1f8d8","components/core/Badge.jsx":"c04491952135","components/core/Button.jsx":"c43631b0d758","components/core/Card.jsx":"b4474a239d87","components/core/IconButton.jsx":"bd55860ce51f","components/core/Tag.jsx":"c8a2e8432e9a","components/forms/Input.jsx":"4c58262a357e","components/forms/Select.jsx":"a2a13ccf0cb7","components/forms/Switch.jsx":"2737a3f2e747","components/navigation/Tabs.jsx":"d3f184460fa6","ui_kits/docs/App.jsx":"7a59cd523900","ui_kits/docs/DocsHeader.jsx":"2eb476264c51","ui_kits/docs/DocsSidebar.jsx":"a091bd208645","ui_kits/docs/ReferencePage.jsx":"d0855f29aced","ui_kits/home/Features.jsx":"48ac29e811d8","ui_kits/home/Hero.jsx":"2dc3333c9b3b","ui_kits/home/HomeApp.jsx":"f2a18138face","ui_kits/home/HomeHeader.jsx":"dfc98c37e66f","ui_kits/home/InstallSection.jsx":"aec2cdd7dae8"},"inlinedExternals":[],"unexposedExports":[]} */ + +(() => { + +const __ds_ns = (window.PantographDesignSystem_56a1c7 = window.PantographDesignSystem_56a1c7 || {}); + +const __ds_scope = {}; + +(__ds_ns.__errors = __ds_ns.__errors || []); + +// components/code/Callout.jsx +try { (() => { +function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); } +const STYLE_ID = 'pg-callout-css'; +function ensureStyles() { + if (typeof document === 'undefined' || document.getElementById(STYLE_ID)) return; + const el = document.createElement('style'); + el.id = STYLE_ID; + el.textContent = ` + .pg-callout { + display: flex; gap: 12px; + padding: 13px 15px; + background: var(--paper-0); + border: var(--border-thin) solid var(--border-hairline); + border-left: var(--border-thick) solid var(--ink-3); + border-radius: var(--radius-sm); + } + .pg-callout__icon { flex: none; width: 18px; height: 18px; margin-top: 1px; color: var(--ink-3); } + .pg-callout__icon svg { width: 100%; height: 100%; } + .pg-callout__body { font: var(--weight-regular) var(--text-sm)/1.55 var(--font-sans); color: var(--ink-1); } + .pg-callout__title { + font: var(--weight-semibold) var(--text-2xs)/1 var(--font-display); + letter-spacing: var(--tracking-label); text-transform: uppercase; + margin: 0 0 5px; color: var(--ink-2); + } + .pg-callout__body :last-child { margin-bottom: 0; } + .pg-callout--note { border-left-color: var(--ink-3); } + .pg-callout--tip { border-left-color: var(--green); background: var(--green-wash); } + .pg-callout--tip .pg-callout__icon, .pg-callout--tip .pg-callout__title { color: var(--green-deep); } + .pg-callout--warn { border-left-color: var(--brass); background: #F0E7D0; } + .pg-callout--warn .pg-callout__icon, .pg-callout--warn .pg-callout__title { color: #7A5E20; } + .pg-callout--danger { border-left-color: var(--red); background: var(--red-wash); } + .pg-callout--danger .pg-callout__icon, .pg-callout--danger .pg-callout__title { color: var(--red-deep); } + `; + document.head.appendChild(el); +} +const ICONS = { + note: /*#__PURE__*/React.createElement("svg", { + viewBox: "0 0 24 24", + fill: "none", + stroke: "currentColor", + strokeWidth: "2", + strokeLinecap: "round", + strokeLinejoin: "round" + }, /*#__PURE__*/React.createElement("circle", { + cx: "12", + cy: "12", + r: "10" + }), /*#__PURE__*/React.createElement("path", { + d: "M12 16v-4" + }), /*#__PURE__*/React.createElement("path", { + d: "M12 8h.01" + })), + tip: /*#__PURE__*/React.createElement("svg", { + viewBox: "0 0 24 24", + fill: "none", + stroke: "currentColor", + strokeWidth: "2", + strokeLinecap: "round", + strokeLinejoin: "round" + }, /*#__PURE__*/React.createElement("path", { + d: "M9 18h6" + }), /*#__PURE__*/React.createElement("path", { + d: "M10 22h4" + }), /*#__PURE__*/React.createElement("path", { + d: "M15.09 14c.18-.98.65-1.74 1.41-2.5A4.65 4.65 0 0 0 18 8 6 6 0 0 0 6 8c0 1 .23 2.23 1.5 3.5A4.61 4.61 0 0 1 8.91 14" + })), + warn: /*#__PURE__*/React.createElement("svg", { + viewBox: "0 0 24 24", + fill: "none", + stroke: "currentColor", + strokeWidth: "2", + strokeLinecap: "round", + strokeLinejoin: "round" + }, /*#__PURE__*/React.createElement("path", { + d: "m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3Z" + }), /*#__PURE__*/React.createElement("path", { + d: "M12 9v4" + }), /*#__PURE__*/React.createElement("path", { + d: "M12 17h.01" + })), + danger: /*#__PURE__*/React.createElement("svg", { + viewBox: "0 0 24 24", + fill: "none", + stroke: "currentColor", + strokeWidth: "2", + strokeLinecap: "round", + strokeLinejoin: "round" + }, /*#__PURE__*/React.createElement("circle", { + cx: "12", + cy: "12", + r: "10" + }), /*#__PURE__*/React.createElement("path", { + d: "m15 9-6 6" + }), /*#__PURE__*/React.createElement("path", { + d: "m9 9 6 6" + })) +}; +const DEFAULT_TITLES = { + note: 'Note', + tip: 'Tip', + warn: 'Warning', + danger: 'Danger' +}; + +/** + * Callout — a documentation admonition (note / tip / warn / danger). + */ +function Callout({ + variant = 'note', + title, + icon, + className = '', + children, + ...rest +}) { + ensureStyles(); + const heading = title === undefined ? DEFAULT_TITLES[variant] : title; + return /*#__PURE__*/React.createElement("div", _extends({ + className: ['pg-callout', `pg-callout--${variant}`, className].filter(Boolean).join(' ') + }, rest), /*#__PURE__*/React.createElement("span", { + className: "pg-callout__icon" + }, icon || ICONS[variant]), /*#__PURE__*/React.createElement("div", { + className: "pg-callout__body" + }, heading ? /*#__PURE__*/React.createElement("p", { + className: "pg-callout__title" + }, heading) : null, children)); +} +Object.assign(__ds_scope, { Callout }); +})(); } catch (e) { __ds_ns.__errors.push({ path: "components/code/Callout.jsx", error: String((e && e.message) || e) }); } + +// components/code/CodeBlock.jsx +try { (() => { +function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); } +const STYLE_ID = 'pg-codeblock-css'; +function ensureStyles() { + if (typeof document === 'undefined' || document.getElementById(STYLE_ID)) return; + const el = document.createElement('style'); + el.id = STYLE_ID; + el.textContent = ` + .pg-code { + background: var(--surface-code); + border: var(--border-thin) solid var(--border-default); + border-radius: var(--radius-md); + overflow: hidden; + font-family: var(--font-mono); + } + .pg-code__bar { + display: flex; align-items: center; gap: 10px; + padding: 8px 12px; background: var(--paper-2); + border-bottom: var(--border-thin) solid var(--border-hairline); + } + .pg-code__name { font: var(--weight-medium) var(--text-xs)/1 var(--font-mono); color: var(--ink-2); } + .pg-code__lang { + font: var(--weight-semibold) var(--text-2xs)/1 var(--font-display); + letter-spacing: var(--tracking-label); text-transform: uppercase; color: var(--ink-3); + margin-left: auto; padding-right: 4px; + } + .pg-code__copy { + display: inline-flex; align-items: center; gap: 5px; + font: var(--weight-medium) var(--text-2xs)/1 var(--font-display); + letter-spacing: 0.1em; text-transform: uppercase; + color: var(--ink-3); background: none; border: 0; cursor: pointer; + padding: 4px 6px; border-radius: var(--radius-xs); + transition: color var(--dur-fast) var(--ease-out), background var(--dur-fast) var(--ease-out); + } + .pg-code__copy:hover { color: var(--ink-0); background: var(--paper-1); } + .pg-code__copy--done { color: var(--green-deep); } + .pg-code__copy svg { width: 13px; height: 13px; } + .pg-code__scroll { overflow-x: auto; padding: 14px 16px; } + .pg-code pre { font-size: var(--text-sm); line-height: var(--leading-mono); color: var(--ink-1); margin: 0; } + .pg-code--nobar { } + /* token colors for hand-marked spans */ + .pg-code .tok-kw { color: var(--green-deep); } + .pg-code .tok-str { color: var(--red-deep); } + .pg-code .tok-com { color: var(--ink-4); font-style: italic; } + .pg-code .tok-fn { color: var(--ink-0); font-weight: 500; } + .pg-code .tok-num { color: var(--brass); } + `; + document.head.appendChild(el); +} +const CopyGlyph = () => /*#__PURE__*/React.createElement("svg", { + viewBox: "0 0 24 24", + fill: "none", + stroke: "currentColor", + strokeWidth: "2", + strokeLinecap: "round", + strokeLinejoin: "round" +}, /*#__PURE__*/React.createElement("rect", { + x: "9", + y: "9", + width: "11", + height: "11", + rx: "2" +}), /*#__PURE__*/React.createElement("path", { + d: "M5 15V5a2 2 0 0 1 2-2h10" +})); +const CheckGlyph = () => /*#__PURE__*/React.createElement("svg", { + viewBox: "0 0 24 24", + fill: "none", + stroke: "currentColor", + strokeWidth: "2.5", + strokeLinecap: "round", + strokeLinejoin: "round" +}, /*#__PURE__*/React.createElement("path", { + d: "m20 6-11 11-5-5" +})); + +/** + * CodeBlock — a code surface with an optional title bar, language label, + * and copy button. Pass a raw `code` string or pre-marked JSX children. + */ +function CodeBlock({ + code = null, + language = null, + filename = null, + showBar = true, + className = '', + children, + ...rest +}) { + ensureStyles(); + const [copied, setCopied] = React.useState(false); + const preRef = React.useRef(null); + const copy = () => { + const text = code != null ? code : preRef.current ? preRef.current.innerText : ''; + if (navigator.clipboard) navigator.clipboard.writeText(text); + setCopied(true); + setTimeout(() => setCopied(false), 1400); + }; + return /*#__PURE__*/React.createElement("div", _extends({ + className: ['pg-code', className].filter(Boolean).join(' ') + }, rest), showBar ? /*#__PURE__*/React.createElement("div", { + className: "pg-code__bar" + }, filename ? /*#__PURE__*/React.createElement("span", { + className: "pg-code__name" + }, filename) : null, language ? /*#__PURE__*/React.createElement("span", { + className: "pg-code__lang" + }, language) : null, /*#__PURE__*/React.createElement("button", { + className: ['pg-code__copy', copied ? 'pg-code__copy--done' : ''].join(' '), + onClick: copy + }, copied ? /*#__PURE__*/React.createElement(CheckGlyph, null) : /*#__PURE__*/React.createElement(CopyGlyph, null), copied ? 'Copied' : 'Copy')) : null, /*#__PURE__*/React.createElement("div", { + className: "pg-code__scroll" + }, /*#__PURE__*/React.createElement("pre", { + ref: preRef + }, /*#__PURE__*/React.createElement("code", null, children != null ? children : code)))); +} +Object.assign(__ds_scope, { CodeBlock }); +})(); } catch (e) { __ds_ns.__errors.push({ path: "components/code/CodeBlock.jsx", error: String((e && e.message) || e) }); } + +// components/code/Terminal.jsx +try { (() => { +function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); } +const STYLE_ID = 'pg-terminal-css'; +function ensureStyles() { + if (typeof document === 'undefined' || document.getElementById(STYLE_ID)) return; + const el = document.createElement('style'); + el.id = STYLE_ID; + el.textContent = ` + .pg-term { + background: var(--ink-1); + border: var(--border-thin) solid var(--ink-0); + border-radius: var(--radius-md); + overflow: hidden; + box-shadow: var(--shadow-md); + font-family: var(--font-mono); + } + .pg-term__bar { + display: flex; align-items: center; gap: 8px; + padding: 9px 12px; background: #232B3B; + border-bottom: var(--border-thin) solid #2E3749; + } + .pg-term__dot { width: 9px; height: 9px; border-radius: var(--radius-pill); } + .pg-term__title { + margin-left: 6px; + font: var(--weight-semibold) var(--text-2xs)/1 var(--font-display); + letter-spacing: var(--tracking-label); text-transform: uppercase; color: var(--paper-4); + } + .pg-term__body { padding: 14px 16px; overflow-x: auto; font-size: var(--text-sm); line-height: 1.65; } + .pg-term__line { white-space: pre; color: var(--paper-2); } + .pg-term__line .pg-term__prompt { color: var(--green-soft); user-select: none; } + .pg-term__line .pg-term__panto { color: var(--red-soft); user-select: none; } + .pg-term__line--cmd { color: var(--paper-0); } + .pg-term__line--out { color: var(--paper-4); } + .pg-term__line--ok { color: var(--green-soft); } + .pg-term__line--err { color: var(--red-soft); } + .pg-term__line--com { color: #6E7689; font-style: italic; } + .pg-term__cursor { + display: inline-block; width: 8px; height: 1.05em; vertical-align: text-bottom; + background: var(--red); margin-left: 2px; + animation: pg-term-blink 1.1s steps(1) infinite; + } + @keyframes pg-term-blink { 50% { opacity: 0; } } + @media (prefers-reduced-motion: reduce) { .pg-term__cursor { animation: none; } } + `; + document.head.appendChild(el); +} + +/** + * Terminal — a panto CLI window. Render with a `lines` array, or pass + * children for full control. Line types: cmd, out, ok, err, com. + */ +function Terminal({ + title = 'panto', + lines = null, + cursor = false, + className = '', + children, + ...rest +}) { + ensureStyles(); + return /*#__PURE__*/React.createElement("div", _extends({ + className: ['pg-term', className].filter(Boolean).join(' ') + }, rest), /*#__PURE__*/React.createElement("div", { + className: "pg-term__bar" + }, /*#__PURE__*/React.createElement("span", { + className: "pg-term__dot", + style: { + background: 'var(--red)' + } + }), /*#__PURE__*/React.createElement("span", { + className: "pg-term__dot", + style: { + background: 'var(--brass)' + } + }), /*#__PURE__*/React.createElement("span", { + className: "pg-term__dot", + style: { + background: 'var(--green)' + } + }), /*#__PURE__*/React.createElement("span", { + className: "pg-term__title" + }, title)), /*#__PURE__*/React.createElement("div", { + className: "pg-term__body" + }, lines ? lines.map((l, i) => { + const type = l.type || 'out'; + if (type === 'cmd') { + return /*#__PURE__*/React.createElement("div", { + key: i, + className: "pg-term__line pg-term__line--cmd" + }, /*#__PURE__*/React.createElement("span", { + className: l.shell === 'panto' ? 'pg-term__panto' : 'pg-term__prompt' + }, l.shell === 'panto' ? 'panto ▸ ' : '$ '), l.text); + } + return /*#__PURE__*/React.createElement("div", { + key: i, + className: `pg-term__line pg-term__line--${type}` + }, l.text); + }) : children, cursor ? /*#__PURE__*/React.createElement("span", { + className: "pg-term__cursor" + }) : null)); +} +Object.assign(__ds_scope, { Terminal }); +})(); } catch (e) { __ds_ns.__errors.push({ path: "components/code/Terminal.jsx", error: String((e && e.message) || e) }); } + +// components/core/Badge.jsx +try { (() => { +function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); } +const STYLE_ID = 'pg-badge-css'; +function ensureStyles() { + if (typeof document === 'undefined' || document.getElementById(STYLE_ID)) return; + const el = document.createElement('style'); + el.id = STYLE_ID; + el.textContent = ` + .pg-badge { + display: inline-flex; align-items: center; gap: 5px; + font-family: var(--font-display); font-weight: var(--weight-semibold); + font-size: var(--text-2xs); letter-spacing: var(--tracking-label); + text-transform: uppercase; line-height: 1; white-space: nowrap; + padding: 4px 7px; border-radius: var(--radius-xs); + border: var(--border-thin) solid transparent; + } + .pg-badge__dot { width: 6px; height: 6px; border-radius: var(--radius-pill); background: currentColor; } + .pg-badge--neutral { color: var(--ink-2); background: var(--paper-2); border-color: var(--paper-3); } + .pg-badge--danger { color: var(--red-deep); background: var(--red-wash); border-color: var(--red-soft); } + .pg-badge--success { color: var(--green-deep); background: var(--green-wash); border-color: var(--green-soft); } + .pg-badge--ink { color: var(--paper-0); background: var(--ink-1); border-color: var(--ink-1); } + .pg-badge--outline { color: var(--ink-2); background: transparent; border-color: var(--border-default); } + `; + document.head.appendChild(el); +} + +/** + * Badge — a small engraved-label status marker (Stable, Beta, Deprecated, …). + */ +function Badge({ + variant = 'neutral', + dot = false, + className = '', + children, + ...rest +}) { + ensureStyles(); + const cls = ['pg-badge', `pg-badge--${variant}`, className].filter(Boolean).join(' '); + return /*#__PURE__*/React.createElement("span", _extends({ + className: cls + }, rest), dot ? /*#__PURE__*/React.createElement("span", { + className: "pg-badge__dot" + }) : null, children); +} +Object.assign(__ds_scope, { Badge }); +})(); } catch (e) { __ds_ns.__errors.push({ path: "components/core/Badge.jsx", error: String((e && e.message) || e) }); } + +// components/core/Button.jsx +try { (() => { +function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); } +/* Injects the Button stylesheet once. Components in this system are + self-contained: they reference design tokens via CSS custom + properties and ship their own scoped CSS. */ +const STYLE_ID = 'pg-button-css'; +function ensureStyles() { + if (typeof document === 'undefined' || document.getElementById(STYLE_ID)) return; + const el = document.createElement('style'); + el.id = STYLE_ID; + el.textContent = ` + .pg-btn { + --_bg: var(--ink-1); --_fg: var(--paper-0); --_bd: var(--ink-1); + display: inline-flex; align-items: center; justify-content: center; + gap: var(--space-2); box-sizing: border-box; + font-family: var(--font-sans); font-weight: var(--weight-semibold); + line-height: 1; letter-spacing: 0.01em; white-space: nowrap; + background: var(--_bg); color: var(--_fg); + border: var(--border-medium) solid var(--_bd); + border-radius: var(--radius-sm); + cursor: pointer; text-decoration: none; user-select: none; + transition: background var(--dur-fast) var(--ease-out), + border-color var(--dur-fast) var(--ease-out), + transform var(--dur-fast) var(--ease-out), + box-shadow var(--dur-fast) var(--ease-out); + box-shadow: var(--shadow-xs); + } + .pg-btn:hover { background: var(--_bgh, var(--_bg)); border-color: var(--_bdh, var(--_bd)); } + .pg-btn:active { transform: translateY(1px); box-shadow: none; } + .pg-btn:focus-visible { outline: var(--border-thick) solid var(--focus-ring); outline-offset: 2px; } + .pg-btn[disabled] { cursor: not-allowed; opacity: 0.45; box-shadow: none; transform: none; } + + .pg-btn--sm { font-size: var(--text-xs); padding: 6px 12px; } + .pg-btn--md { font-size: var(--text-sm); padding: 9px 16px; } + .pg-btn--lg { font-size: var(--text-base); padding: 12px 22px; } + .pg-btn--block { display: flex; width: 100%; } + + .pg-btn--primary { --_bg: var(--ink-1); --_fg: var(--paper-0); --_bd: var(--ink-1); --_bgh: var(--ink-0); --_bdh: var(--ink-0); } + .pg-btn--accent { --_bg: var(--red); --_fg: var(--paper-0); --_bd: var(--red); --_bgh: var(--red-deep); --_bdh: var(--red-deep); } + .pg-btn--secondary { --_bg: var(--paper-0); --_fg: var(--ink-1); --_bd: var(--border-default); --_bgh: var(--paper-2); --_bdh: var(--ink-3); } + .pg-btn--ghost { --_bg: transparent; --_fg: var(--ink-1); --_bd: transparent; --_bgh: var(--paper-2); --_bdh: transparent; box-shadow: none; } + .pg-btn--danger { --_bg: transparent; --_fg: var(--red-deep); --_bd: var(--red); --_bgh: var(--red-wash); --_bdh: var(--red-deep); box-shadow: none; } + .pg-btn__icon { display: inline-flex; width: 1.05em; height: 1.05em; } + .pg-btn__icon svg { width: 100%; height: 100%; } + `; + document.head.appendChild(el); +} + +/** + * Button — the primary action control. Machined edges, instrument palette. + */ +function Button({ + variant = 'primary', + size = 'md', + block = false, + icon = null, + iconRight = null, + disabled = false, + as = 'button', + className = '', + children, + ...rest +}) { + ensureStyles(); + const Tag = as; + const cls = ['pg-btn', `pg-btn--${variant}`, `pg-btn--${size}`, block ? 'pg-btn--block' : '', className].filter(Boolean).join(' '); + return /*#__PURE__*/React.createElement(Tag, _extends({ + className: cls, + disabled: Tag === 'button' ? disabled : undefined + }, rest), icon ? /*#__PURE__*/React.createElement("span", { + className: "pg-btn__icon" + }, icon) : null, children, iconRight ? /*#__PURE__*/React.createElement("span", { + className: "pg-btn__icon" + }, iconRight) : null); +} +Object.assign(__ds_scope, { Button }); +})(); } catch (e) { __ds_ns.__errors.push({ path: "components/core/Button.jsx", error: String((e && e.message) || e) }); } + +// components/core/Card.jsx +try { (() => { +function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); } +const STYLE_ID = 'pg-card-css'; +function ensureStyles() { + if (typeof document === 'undefined' || document.getElementById(STYLE_ID)) return; + const el = document.createElement('style'); + el.id = STYLE_ID; + el.textContent = ` + .pg-card { + display: block; box-sizing: border-box; + background: var(--surface-card); + border: var(--border-thin) solid var(--border-hairline); + border-radius: var(--radius-md); + box-shadow: var(--shadow-sm); + overflow: hidden; + } + .pg-card--flat { box-shadow: none; } + .pg-card--sunken { background: var(--surface-sunken); box-shadow: var(--shadow-inset); border-color: var(--paper-3); } + .pg-card--interactive { cursor: pointer; transition: box-shadow var(--dur-base) var(--ease-out), transform var(--dur-base) var(--ease-out), border-color var(--dur-base) var(--ease-out); } + .pg-card--interactive:hover { box-shadow: var(--shadow-md); border-color: var(--border-default); transform: translateY(-1px); } + /* top engraved tick rule, like a scale edge */ + .pg-card--ruled { border-top: var(--border-thick) solid var(--ink-1); } + .pg-card--ruled.pg-card--accent { border-top-color: var(--red); } + + .pg-card__header { + display: flex; align-items: center; gap: var(--space-3); + padding: var(--space-4) var(--space-5); + border-bottom: var(--border-thin) solid var(--border-hairline); + } + .pg-card__title { font: var(--weight-semibold) var(--text-lg)/1.2 var(--font-sans); color: var(--text-strong); margin: 0; } + .pg-card__body { padding: var(--space-5); } + .pg-card__footer { + padding: var(--space-4) var(--space-5); + border-top: var(--border-thin) solid var(--border-hairline); + background: var(--paper-1); + display: flex; align-items: center; gap: var(--space-3); + } + `; + document.head.appendChild(el); +} + +/** + * Card — the primary surface container. Header / body / footer are optional. + */ +function Card({ + variant = 'default', + ruled = false, + interactive = false, + title = null, + actions = null, + footer = null, + className = '', + children, + ...rest +}) { + ensureStyles(); + const cls = ['pg-card', variant !== 'default' ? `pg-card--${variant}` : '', ruled ? 'pg-card--ruled' : '', interactive ? 'pg-card--interactive' : '', className].filter(Boolean).join(' '); + const hasHeader = title != null || actions != null; + return /*#__PURE__*/React.createElement("div", _extends({ + className: cls + }, rest), hasHeader ? /*#__PURE__*/React.createElement("div", { + className: "pg-card__header" + }, title ? /*#__PURE__*/React.createElement("h3", { + className: "pg-card__title" + }, title) : null, actions ? /*#__PURE__*/React.createElement("div", { + style: { + marginLeft: 'auto', + display: 'flex', + gap: 'var(--space-2)' + } + }, actions) : null) : null, /*#__PURE__*/React.createElement("div", { + className: "pg-card__body" + }, children), footer ? /*#__PURE__*/React.createElement("div", { + className: "pg-card__footer" + }, footer) : null); +} +Object.assign(__ds_scope, { Card }); +})(); } catch (e) { __ds_ns.__errors.push({ path: "components/core/Card.jsx", error: String((e && e.message) || e) }); } + +// components/core/IconButton.jsx +try { (() => { +function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); } +const STYLE_ID = 'pg-iconbutton-css'; +function ensureStyles() { + if (typeof document === 'undefined' || document.getElementById(STYLE_ID)) return; + const el = document.createElement('style'); + el.id = STYLE_ID; + el.textContent = ` + .pg-iconbtn { + display: inline-flex; align-items: center; justify-content: center; + box-sizing: border-box; padding: 0; cursor: pointer; + color: var(--ink-2); background: transparent; + border: var(--border-thin) solid transparent; + border-radius: var(--radius-sm); + transition: background var(--dur-fast) var(--ease-out), + color var(--dur-fast) var(--ease-out), + border-color var(--dur-fast) var(--ease-out), + transform var(--dur-fast) var(--ease-out); + } + .pg-iconbtn:hover { background: var(--paper-2); color: var(--ink-0); } + .pg-iconbtn:active { transform: translateY(1px); } + .pg-iconbtn:focus-visible { outline: var(--border-thick) solid var(--focus-ring); outline-offset: 2px; } + .pg-iconbtn[disabled] { cursor: not-allowed; opacity: 0.4; } + .pg-iconbtn--bordered { border-color: var(--border-default); background: var(--paper-0); } + .pg-iconbtn--bordered:hover { border-color: var(--ink-3); } + .pg-iconbtn--active { background: var(--paper-2); color: var(--red-deep); border-color: var(--border-default); } + .pg-iconbtn--sm { width: 28px; height: 28px; } + .pg-iconbtn--md { width: 36px; height: 36px; } + .pg-iconbtn--lg { width: 44px; height: 44px; } + .pg-iconbtn svg { width: 1.15em; height: 1.15em; display: block; } + .pg-iconbtn--sm svg { font-size: 15px; } + .pg-iconbtn--md svg { font-size: 18px; } + .pg-iconbtn--lg svg { font-size: 21px; } + `; + document.head.appendChild(el); +} + +/** + * IconButton — a square, icon-only control for toolbars and dense UI. + */ +function IconButton({ + size = 'md', + bordered = false, + active = false, + label, + disabled = false, + className = '', + children, + ...rest +}) { + ensureStyles(); + const cls = ['pg-iconbtn', `pg-iconbtn--${size}`, bordered ? 'pg-iconbtn--bordered' : '', active ? 'pg-iconbtn--active' : '', className].filter(Boolean).join(' '); + return /*#__PURE__*/React.createElement("button", _extends({ + type: "button", + className: cls, + "aria-label": label, + title: label, + disabled: disabled + }, rest), children); +} +Object.assign(__ds_scope, { IconButton }); +})(); } catch (e) { __ds_ns.__errors.push({ path: "components/core/IconButton.jsx", error: String((e && e.message) || e) }); } + +// components/core/Tag.jsx +try { (() => { +function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); } +const STYLE_ID = 'pg-tag-css'; +function ensureStyles() { + if (typeof document === 'undefined' || document.getElementById(STYLE_ID)) return; + const el = document.createElement('style'); + el.id = STYLE_ID; + el.textContent = ` + .pg-tag { + display: inline-flex; align-items: center; gap: 6px; + font-family: var(--font-mono); font-weight: var(--weight-medium); + font-size: var(--text-xs); line-height: 1; white-space: nowrap; + color: var(--ink-1); background: var(--paper-0); + padding: 5px 9px; border-radius: var(--radius-pill); + border: var(--border-thin) solid var(--border-default); + } + .pg-tag__dot { width: 7px; height: 7px; border-radius: var(--radius-pill); flex: none; background: var(--ink-3); } + .pg-tag--interactive { cursor: pointer; transition: border-color var(--dur-fast) var(--ease-out), background var(--dur-fast) var(--ease-out); } + .pg-tag--interactive:hover { border-color: var(--ink-3); background: var(--paper-2); } + .pg-tag__remove { + display: inline-flex; align-items: center; justify-content: center; + width: 14px; height: 14px; margin-right: -2px; padding: 0; + border: 0; background: none; cursor: pointer; color: var(--ink-3); + font-family: var(--font-sans); font-size: 14px; line-height: 1; border-radius: var(--radius-pill); + } + .pg-tag__remove:hover { color: var(--red); } + `; + document.head.appendChild(el); +} + +/** + * Tag — a monospace chip for languages, keywords, and filters. + */ +function Tag({ + dot = null, + onRemove = null, + interactive = false, + className = '', + children, + ...rest +}) { + ensureStyles(); + const cls = ['pg-tag', interactive || rest.onClick ? 'pg-tag--interactive' : '', className].filter(Boolean).join(' '); + return /*#__PURE__*/React.createElement("span", _extends({ + className: cls + }, rest), dot ? /*#__PURE__*/React.createElement("span", { + className: "pg-tag__dot", + style: { + background: dot === true ? undefined : dot + } + }) : null, children, onRemove ? /*#__PURE__*/React.createElement("button", { + type: "button", + className: "pg-tag__remove", + "aria-label": "Remove", + onClick: e => { + e.stopPropagation(); + onRemove(e); + } + }, "\xD7") : null); +} +Object.assign(__ds_scope, { Tag }); +})(); } catch (e) { __ds_ns.__errors.push({ path: "components/core/Tag.jsx", error: String((e && e.message) || e) }); } + +// components/forms/Input.jsx +try { (() => { +function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); } +const STYLE_ID = 'pg-input-css'; +function ensureStyles() { + if (typeof document === 'undefined' || document.getElementById(STYLE_ID)) return; + const el = document.createElement('style'); + el.id = STYLE_ID; + el.textContent = ` + .pg-field { display: flex; flex-direction: column; gap: 6px; } + .pg-field__label { + font: var(--weight-semibold) var(--text-xs)/1 var(--font-display); + letter-spacing: var(--tracking-label); text-transform: uppercase; color: var(--ink-2); + } + .pg-field__req { color: var(--red); margin-left: 3px; } + .pg-input-wrap { position: relative; display: flex; align-items: center; } + .pg-input-wrap__icon { + position: absolute; left: 11px; display: inline-flex; color: var(--ink-3); pointer-events: none; + } + .pg-input-wrap__icon svg { width: 16px; height: 16px; } + .pg-input { + width: 100%; box-sizing: border-box; + font: var(--weight-regular) var(--text-sm)/1.4 var(--font-sans); + color: var(--ink-1); background: var(--paper-0); + border: var(--border-thin) solid var(--border-default); + border-radius: var(--radius-xs); + padding: 9px 12px; + transition: border-color var(--dur-fast) var(--ease-out), box-shadow var(--dur-fast) var(--ease-out); + } + .pg-input--mono { font-family: var(--font-mono); } + .pg-input--has-icon { padding-left: 34px; } + .pg-input::placeholder { color: var(--text-placeholder); } + .pg-input:hover { border-color: var(--ink-4); } + .pg-input:focus { outline: none; border-color: var(--green); box-shadow: 0 0 0 3px var(--green-wash); } + .pg-input--invalid { border-color: var(--red); } + .pg-input--invalid:focus { border-color: var(--red); box-shadow: 0 0 0 3px var(--red-wash); } + .pg-input:disabled { background: var(--paper-2); color: var(--ink-3); cursor: not-allowed; } + .pg-field__hint { font: var(--weight-regular) var(--text-xs)/1.4 var(--font-sans); color: var(--ink-3); } + .pg-field__hint--error { color: var(--red-deep); } + `; + document.head.appendChild(el); +} + +/** + * Input — single-line text field with optional label, icon, and validation. + */ +function Input({ + label = null, + hint = null, + error = null, + icon = null, + mono = false, + required = false, + id, + className = '', + ...rest +}) { + ensureStyles(); + const inputId = id || (label ? `pg-in-${Math.random().toString(36).slice(2, 8)}` : undefined); + const cls = ['pg-input', mono ? 'pg-input--mono' : '', icon ? 'pg-input--has-icon' : '', error ? 'pg-input--invalid' : '', className].filter(Boolean).join(' '); + return /*#__PURE__*/React.createElement("div", { + className: "pg-field" + }, label ? /*#__PURE__*/React.createElement("label", { + className: "pg-field__label", + htmlFor: inputId + }, label, required ? /*#__PURE__*/React.createElement("span", { + className: "pg-field__req" + }, "*") : null) : null, /*#__PURE__*/React.createElement("div", { + className: "pg-input-wrap" + }, icon ? /*#__PURE__*/React.createElement("span", { + className: "pg-input-wrap__icon" + }, icon) : null, /*#__PURE__*/React.createElement("input", _extends({ + id: inputId, + className: cls, + "aria-invalid": !!error + }, rest))), error ? /*#__PURE__*/React.createElement("span", { + className: "pg-field__hint pg-field__hint--error" + }, error) : hint ? /*#__PURE__*/React.createElement("span", { + className: "pg-field__hint" + }, hint) : null); +} +Object.assign(__ds_scope, { Input }); +})(); } catch (e) { __ds_ns.__errors.push({ path: "components/forms/Input.jsx", error: String((e && e.message) || e) }); } + +// components/forms/Select.jsx +try { (() => { +function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); } +const STYLE_ID = 'pg-select-css'; +function ensureStyles() { + if (typeof document === 'undefined' || document.getElementById(STYLE_ID)) return; + const el = document.createElement('style'); + el.id = STYLE_ID; + el.textContent = ` + .pg-select-field { display: flex; flex-direction: column; gap: 6px; } + .pg-select-field__label { + font: var(--weight-semibold) var(--text-xs)/1 var(--font-display); + letter-spacing: var(--tracking-label); text-transform: uppercase; color: var(--ink-2); + } + .pg-select-wrap { position: relative; display: flex; align-items: center; } + .pg-select { + width: 100%; box-sizing: border-box; appearance: none; + font: var(--weight-regular) var(--text-sm)/1.4 var(--font-sans); + color: var(--ink-1); background: var(--paper-0); + border: var(--border-thin) solid var(--border-default); + border-radius: var(--radius-xs); + padding: 9px 34px 9px 12px; cursor: pointer; + transition: border-color var(--dur-fast) var(--ease-out), box-shadow var(--dur-fast) var(--ease-out); + } + .pg-select:hover { border-color: var(--ink-4); } + .pg-select:focus { outline: none; border-color: var(--green); box-shadow: 0 0 0 3px var(--green-wash); } + .pg-select:disabled { background: var(--paper-2); color: var(--ink-3); cursor: not-allowed; } + .pg-select-wrap__chevron { + position: absolute; right: 11px; pointer-events: none; color: var(--ink-3); + width: 16px; height: 16px; + } + `; + document.head.appendChild(el); +} + +/** + * Select — native dropdown styled to the system, with a custom chevron. + */ +function Select({ + label = null, + options = [], + placeholder = null, + id, + className = '', + children, + ...rest +}) { + ensureStyles(); + const selId = id || (label ? `pg-sel-${Math.random().toString(36).slice(2, 8)}` : undefined); + return /*#__PURE__*/React.createElement("div", { + className: "pg-select-field" + }, label ? /*#__PURE__*/React.createElement("label", { + className: "pg-select-field__label", + htmlFor: selId + }, label) : null, /*#__PURE__*/React.createElement("div", { + className: "pg-select-wrap" + }, /*#__PURE__*/React.createElement("select", _extends({ + id: selId, + className: ['pg-select', className].filter(Boolean).join(' ') + }, rest), placeholder ? /*#__PURE__*/React.createElement("option", { + value: "", + disabled: true + }, placeholder) : null, children, options.map(o => { + const value = typeof o === 'string' ? o : o.value; + const optLabel = typeof o === 'string' ? o : o.label; + return /*#__PURE__*/React.createElement("option", { + key: value, + value: value + }, optLabel); + })), /*#__PURE__*/React.createElement("svg", { + className: "pg-select-wrap__chevron", + viewBox: "0 0 24 24", + fill: "none", + stroke: "currentColor", + strokeWidth: "2", + strokeLinecap: "round", + strokeLinejoin: "round" + }, /*#__PURE__*/React.createElement("path", { + d: "m6 9 6 6 6-6" + })))); +} +Object.assign(__ds_scope, { Select }); +})(); } catch (e) { __ds_ns.__errors.push({ path: "components/forms/Select.jsx", error: String((e && e.message) || e) }); } + +// components/forms/Switch.jsx +try { (() => { +function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); } +const STYLE_ID = 'pg-switch-css'; +function ensureStyles() { + if (typeof document === 'undefined' || document.getElementById(STYLE_ID)) return; + const el = document.createElement('style'); + el.id = STYLE_ID; + el.textContent = ` + .pg-switch { display: inline-flex; align-items: center; gap: 10px; cursor: pointer; user-select: none; } + .pg-switch input { position: absolute; opacity: 0; width: 0; height: 0; } + .pg-switch__track { + position: relative; flex: none; width: 38px; height: 22px; + background: var(--paper-3); border: var(--border-thin) solid var(--border-default); + border-radius: var(--radius-pill); + transition: background var(--dur-base) var(--ease-slide), border-color var(--dur-base) var(--ease-slide); + } + .pg-switch__thumb { + position: absolute; top: 2px; left: 2px; width: 16px; height: 16px; + background: var(--paper-0); border-radius: var(--radius-pill); + box-shadow: var(--shadow-sm); + transition: transform var(--dur-base) var(--ease-slide); + } + .pg-switch input:checked + .pg-switch__track { background: var(--green); border-color: var(--green-deep); } + .pg-switch input:checked + .pg-switch__track .pg-switch__thumb { transform: translateX(16px); } + .pg-switch input:focus-visible + .pg-switch__track { outline: var(--border-thick) solid var(--focus-ring); outline-offset: 2px; } + .pg-switch input:disabled + .pg-switch__track { opacity: 0.45; cursor: not-allowed; } + .pg-switch__label { font: var(--weight-regular) var(--text-sm)/1.3 var(--font-sans); color: var(--ink-1); } + `; + document.head.appendChild(el); +} + +/** + * Switch — a toggle. The "on" state slides to instrument green. + */ +function Switch({ + checked, + defaultChecked, + onChange, + disabled = false, + label = null, + id, + className = '', + ...rest +}) { + ensureStyles(); + const swId = id || `pg-sw-${Math.random().toString(36).slice(2, 8)}`; + return /*#__PURE__*/React.createElement("label", { + className: ['pg-switch', className].filter(Boolean).join(' '), + htmlFor: swId + }, /*#__PURE__*/React.createElement("input", _extends({ + id: swId, + type: "checkbox", + checked: checked, + defaultChecked: defaultChecked, + onChange: onChange, + disabled: disabled + }, rest)), /*#__PURE__*/React.createElement("span", { + className: "pg-switch__track" + }, /*#__PURE__*/React.createElement("span", { + className: "pg-switch__thumb" + })), label ? /*#__PURE__*/React.createElement("span", { + className: "pg-switch__label" + }, label) : null); +} +Object.assign(__ds_scope, { Switch }); +})(); } catch (e) { __ds_ns.__errors.push({ path: "components/forms/Switch.jsx", error: String((e && e.message) || e) }); } + +// components/navigation/Tabs.jsx +try { (() => { +function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); } +const STYLE_ID = 'pg-tabs-css'; +function ensureStyles() { + if (typeof document === 'undefined' || document.getElementById(STYLE_ID)) return; + const el = document.createElement('style'); + el.id = STYLE_ID; + el.textContent = ` + .pg-tabs { display: flex; align-items: stretch; gap: 2px; border-bottom: var(--border-thin) solid var(--border-hairline); } + .pg-tabs--pill { border-bottom: 0; gap: 4px; background: var(--paper-2); padding: 3px; border-radius: var(--radius-sm); width: max-content; } + .pg-tab { + display: inline-flex; align-items: center; gap: 7px; + font: var(--weight-medium) var(--text-sm)/1 var(--font-sans); + color: var(--ink-3); background: none; border: 0; cursor: pointer; + padding: 10px 14px; position: relative; white-space: nowrap; + transition: color var(--dur-fast) var(--ease-out); + } + .pg-tab:hover { color: var(--ink-1); } + .pg-tab__icon { display: inline-flex; width: 15px; height: 15px; } + .pg-tab__icon svg { width: 100%; height: 100%; } + /* underline indicator — the engraved cursor line */ + .pg-tabs:not(.pg-tabs--pill) .pg-tab::after { + content: ''; position: absolute; left: 8px; right: 8px; bottom: -1px; height: 2px; + background: var(--red); transform: scaleX(0); transform-origin: center; + transition: transform var(--dur-base) var(--ease-slide); + } + .pg-tabs:not(.pg-tabs--pill) .pg-tab[aria-selected="true"] { color: var(--ink-0); font-weight: var(--weight-semibold); } + .pg-tabs:not(.pg-tabs--pill) .pg-tab[aria-selected="true"]::after { transform: scaleX(1); } + .pg-tab:focus-visible { outline: var(--border-thick) solid var(--focus-ring); outline-offset: -2px; border-radius: var(--radius-xs); } + /* pill variant */ + .pg-tabs--pill .pg-tab { border-radius: var(--radius-xs); padding: 7px 13px; font-family: var(--font-mono); font-size: var(--text-xs); } + .pg-tabs--pill .pg-tab[aria-selected="true"] { background: var(--paper-0); color: var(--ink-0); box-shadow: var(--shadow-xs); } + `; + document.head.appendChild(el); +} + +/** + * Tabs — segmented navigation. Default variant draws the engraved red cursor + * underline; `pill` variant is a compact monospace switch (e.g. language picker). + */ +function Tabs({ + tabs = [], + value, + onChange, + variant = 'underline', + className = '', + ...rest +}) { + ensureStyles(); + const cls = ['pg-tabs', variant === 'pill' ? 'pg-tabs--pill' : '', className].filter(Boolean).join(' '); + return /*#__PURE__*/React.createElement("div", _extends({ + className: cls, + role: "tablist" + }, rest), tabs.map(t => { + const id = typeof t === 'string' ? t : t.id; + const label = typeof t === 'string' ? t : t.label; + const icon = typeof t === 'string' ? null : t.icon; + const selected = id === value; + return /*#__PURE__*/React.createElement("button", { + key: id, + role: "tab", + "aria-selected": selected, + className: "pg-tab", + onClick: () => onChange && onChange(id) + }, icon ? /*#__PURE__*/React.createElement("span", { + className: "pg-tab__icon" + }, icon) : null, label); + })); +} +Object.assign(__ds_scope, { Tabs }); +})(); } catch (e) { __ds_ns.__errors.push({ path: "components/navigation/Tabs.jsx", error: String((e && e.message) || e) }); } + +// ui_kits/docs/App.jsx +try { (() => { +// App — composes the docs shell: header, sidebar, content, on-this-page TOC. +(function () { + const React = window.React; + const TOC = [{ + id: 'example', + label: 'Example' + }, { + id: 'parameters', + label: 'Parameters' + }, { + id: 'returns', + label: 'Returns' + }]; + function App() { + const [active, setActive] = React.useState('complete()'); + const [menuOpen, setMenuOpen] = React.useState(false); + return /*#__PURE__*/React.createElement("div", { + className: "dk-app" + }, /*#__PURE__*/React.createElement(window.DocsHeader, { + onMenu: () => setMenuOpen(v => !v) + }), /*#__PURE__*/React.createElement("div", { + className: "dk-shell" + }, /*#__PURE__*/React.createElement(window.DocsSidebar, { + active: active, + onSelect: it => { + setActive(it); + setMenuOpen(false); + }, + open: menuOpen + }), menuOpen ? /*#__PURE__*/React.createElement("div", { + className: "dk-scrim", + onClick: () => setMenuOpen(false) + }) : null, /*#__PURE__*/React.createElement("main", { + className: "dk-main" + }, /*#__PURE__*/React.createElement(window.ReferencePage, null)), /*#__PURE__*/React.createElement("aside", { + className: "dk-toc" + }, /*#__PURE__*/React.createElement("p", { + className: "dk-toc__title" + }, "On this page"), /*#__PURE__*/React.createElement("ul", { + className: "dk-toc__list" + }, TOC.map(t => /*#__PURE__*/React.createElement("li", { + key: t.id + }, /*#__PURE__*/React.createElement("a", { + href: '#' + t.id, + className: "dk-toc__link" + }, t.label)))), /*#__PURE__*/React.createElement("div", { + className: "panto-tick-rule", + style: { + margin: 'var(--space-5) 0 var(--space-4)' + } + }), /*#__PURE__*/React.createElement("a", { + className: "dk-edit", + href: "#" + }, "Edit this page \u2192")))); + } + window.DocsApp = App; +})(); +})(); } catch (e) { __ds_ns.__errors.push({ path: "ui_kits/docs/App.jsx", error: String((e && e.message) || e) }); } + +// ui_kits/docs/DocsHeader.jsx +try { (() => { +// Lucide-derived inline icons (ISC) + DocsHeader. Icons live here (a JSX file) +// so the design-system compiler treats them as kit-local, not a bundle module. +(function () { + const React = window.React; + const S = (paths, extra = {}) => props => React.createElement('svg', Object.assign({ + viewBox: '0 0 24 24', + fill: 'none', + stroke: 'currentColor', + strokeWidth: 2, + strokeLinecap: 'round', + strokeLinejoin: 'round', + width: '1em', + height: '1em' + }, extra, props), paths.map((d, i) => React.createElement('path', { + key: i, + d + }))); + const M = (children, extra = {}) => props => React.createElement('svg', Object.assign({ + viewBox: '0 0 24 24', + fill: 'none', + stroke: 'currentColor', + strokeWidth: 2, + strokeLinecap: 'round', + strokeLinejoin: 'round', + width: '1em', + height: '1em' + }, extra, props), children(React)); + window.Icons = { + Search: M(R => [R.createElement('circle', { + key: 0, + cx: 11, + cy: 11, + r: 8 + }), R.createElement('path', { + key: 1, + d: 'm21 21-4.3-4.3' + })]), + ChevronRight: S(['m9 18 6-6-6-6']), + Hash: S(['M4 9h16', 'M4 15h16', 'M10 3 8 21', 'M16 3l-2 18']), + Book: S(['M4 19.5v-15A2.5 2.5 0 0 1 6.5 2H20v20H6.5a2.5 2.5 0 0 1 0-5H20']), + Terminal: S(['m4 17 6-6-6-6', 'M12 19h8']), + Github: M(R => [R.createElement('path', { + key: 0, + d: 'M15 22v-4a4.8 4.8 0 0 0-1-3.5c3 0 6-2 6-5.5.08-1.25-.27-2.48-1-3.5.28-1.15.28-2.35 0-3.5 0 0-1 0-3 1.5-2.64-.5-5.36-.5-8 0C6 .5 5 .5 5 .5c-.3 1.15-.3 2.35 0 3.5A5.4 5.4 0 0 0 4 7.5c0 3.5 3 5.5 6 5.5-.39.49-.68 1.05-.85 1.65-.17.6-.22 1.23-.15 1.85v4' + }), R.createElement('path', { + key: 1, + d: 'M9 18c-4.51 2-5-2-7-2' + })]), + Zap: S(['M4 14a1 1 0 0 1-.78-1.63l9.9-10.2a.5.5 0 0 1 .86.46l-1.92 6.02A1 1 0 0 0 13 10h7a1 1 0 0 1 .78 1.63l-9.9 10.2a.5.5 0 0 1-.86-.46l1.92-6.02A1 1 0 0 0 11 14z']), + Boxes: S(['M2.97 12.92A2 2 0 0 0 2 14.63v3.24a2 2 0 0 0 .97 1.71l3 1.8a2 2 0 0 0 2.06 0L12 19v-5.5l-5-3-4.03 2.42Z', 'm7 16.5-4.74-2.85', 'm7 16.5 5-3', 'M7 16.5v5.17', 'M12 13.5V19l3.97 2.38a2 2 0 0 0 2.06 0l3-1.8a2 2 0 0 0 .97-1.71v-3.24a2 2 0 0 0-.97-1.71L17 10.5l-5 3Z', 'm17 16.5-5-3', 'm17 16.5 4.74-2.85', 'M17 16.5v5.17', 'M7.97 4.42A2 2 0 0 0 7 6.13v4.37l5 3 5-3V6.13a2 2 0 0 0-.97-1.71l-3-1.8a2 2 0 0 0-2.06 0l-3 1.8Z', 'M12 8 7.26 5.15', 'm12 8 4.74-2.85', 'M12 13.5V8']), + Layers: S(['m12.83 2.18a2 2 0 0 0-1.66 0L2.6 6.08a1 1 0 0 0 0 1.83l8.58 3.91a2 2 0 0 0 1.66 0l8.58-3.9a1 1 0 0 0 0-1.83Z', 'M2 12a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 12', 'M2 17a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 17']), + Menu: S(['M4 12h16', 'M4 6h16', 'M4 18h16']), + Check: S(['M20 6 9 17l-5-5']), + Compass: M(R => [R.createElement('path', { + key: 0, + d: 'm16.24 7.76-1.804 5.411a2 2 0 0 1-1.265 1.265L7.76 16.24l1.804-5.411a2 2 0 0 1 1.265-1.265z' + }), R.createElement('circle', { + key: 1, + cx: 12, + cy: 12, + r: 10 + })]) + }; +})(); + +// DocsHeader — top bar: logo lockup, primary nav, search, github. +(function () { + const React = window.React; + const { + Badge, + IconButton + } = window.PantographDesignSystem_56a1c7; + const I = window.Icons; + function DocsHeader({ + onMenu + }) { + return /*#__PURE__*/React.createElement("header", { + className: "dk-header" + }, /*#__PURE__*/React.createElement("div", { + className: "dk-header__left" + }, /*#__PURE__*/React.createElement("button", { + className: "dk-menu", + "aria-label": "Menu", + onClick: onMenu + }, /*#__PURE__*/React.createElement(I.Menu, null)), /*#__PURE__*/React.createElement("a", { + className: "dk-brand", + href: "#" + }, /*#__PURE__*/React.createElement("img", { + src: "../../assets/logo-mark.svg", + width: "28", + height: "28", + alt: "" + }), /*#__PURE__*/React.createElement("span", { + className: "dk-brand__word" + }, "pantograph"), /*#__PURE__*/React.createElement("span", { + className: "dk-brand__div" + }, "/"), /*#__PURE__*/React.createElement("span", { + className: "dk-brand__sub" + }, "libpanto")), /*#__PURE__*/React.createElement(Badge, { + variant: "outline" + }, "v2.4")), /*#__PURE__*/React.createElement("nav", { + className: "dk-nav" + }, /*#__PURE__*/React.createElement("a", { + href: "#", + className: "dk-nav__link" + }, "Guides"), /*#__PURE__*/React.createElement("a", { + href: "#", + className: "dk-nav__link dk-nav__link--active" + }, "Reference"), /*#__PURE__*/React.createElement("a", { + href: "#", + className: "dk-nav__link" + }, "CLI"), /*#__PURE__*/React.createElement("a", { + href: "#", + className: "dk-nav__link" + }, "Changelog")), /*#__PURE__*/React.createElement("div", { + className: "dk-header__right" + }, /*#__PURE__*/React.createElement("label", { + className: "dk-search" + }, /*#__PURE__*/React.createElement("span", { + className: "dk-search__icon" + }, /*#__PURE__*/React.createElement(I.Search, null)), /*#__PURE__*/React.createElement("input", { + className: "dk-search__input", + placeholder: "Search the docs" + }), /*#__PURE__*/React.createElement("kbd", { + className: "dk-search__kbd" + }, "/")), /*#__PURE__*/React.createElement(IconButton, { + label: "GitHub", + bordered: true + }, /*#__PURE__*/React.createElement(I.Github, null)))); + } + window.DocsHeader = DocsHeader; +})(); +})(); } catch (e) { __ds_ns.__errors.push({ path: "ui_kits/docs/DocsHeader.jsx", error: String((e && e.message) || e) }); } + +// ui_kits/docs/DocsSidebar.jsx +try { (() => { +// DocsSidebar — grouped navigation tree. +(function () { + const React = window.React; + const I = window.Icons; + const NAV = [{ + group: 'Getting Started', + items: ['Installation', 'Quickstart', 'Authentication'] + }, { + group: 'Guides', + items: ['Streaming', 'Tool use', 'Structured output', 'Retries & timeouts'] + }, { + group: 'Reference', + items: ['Client', 'complete()', 'respond()', 'Response', 'Errors'] + }, { + group: 'CLI · panto', + items: ['panto run', 'panto chat', 'Configuration'] + }]; + function DocsSidebar({ + active, + onSelect, + open + }) { + return /*#__PURE__*/React.createElement("aside", { + className: 'dk-sidebar' + (open ? ' dk-sidebar--open' : '') + }, /*#__PURE__*/React.createElement("div", { + className: "dk-sidebar__scroll" + }, NAV.map(sec => /*#__PURE__*/React.createElement("div", { + className: "dk-navsec", + key: sec.group + }, /*#__PURE__*/React.createElement("p", { + className: "dk-navsec__title" + }, sec.group), /*#__PURE__*/React.createElement("ul", { + className: "dk-navsec__list" + }, sec.items.map(it => /*#__PURE__*/React.createElement("li", { + key: it + }, /*#__PURE__*/React.createElement("a", { + href: "#", + className: 'dk-navsec__link' + (it === active ? ' dk-navsec__link--active' : ''), + onClick: e => { + e.preventDefault(); + onSelect(it); + } + }, it)))))))); + } + window.DocsSidebar = DocsSidebar; +})(); +})(); } catch (e) { __ds_ns.__errors.push({ path: "ui_kits/docs/DocsSidebar.jsx", error: String((e && e.message) || e) }); } + +// ui_kits/docs/ReferencePage.jsx +try { (() => { +// ReferencePage — the main documentation view for client.complete(). +(function () { + const React = window.React; + const { + Badge, + Tag, + Tabs, + CodeBlock, + Callout, + Card + } = window.PantographDesignSystem_56a1c7; + const I = window.Icons; + const SAMPLES = { + python: /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("span", { + className: "tok-kw" + }, "import"), " panto", "\n\n", "client = panto.", /*#__PURE__*/React.createElement("span", { + className: "tok-fn" + }, "Client"), "()", "\n", "resp = client.", /*#__PURE__*/React.createElement("span", { + className: "tok-fn" + }, "complete"), "(", "\n", " ", "prompt=", /*#__PURE__*/React.createElement("span", { + className: "tok-str" + }, "\"explain this stack trace\""), ",", "\n", " ", "model=", /*#__PURE__*/React.createElement("span", { + className: "tok-str" + }, "\"claude-sonnet\""), ",", "\n", " ", "max_tokens=", /*#__PURE__*/React.createElement("span", { + className: "tok-num" + }, "1024"), ",", "\n", ")", "\n", /*#__PURE__*/React.createElement("span", { + className: "tok-kw" + }, "print"), "(resp.text)"), + rust: /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("span", { + className: "tok-kw" + }, "use"), " panto::Client;", "\n\n", /*#__PURE__*/React.createElement("span", { + className: "tok-kw" + }, "let"), " client = Client::", /*#__PURE__*/React.createElement("span", { + className: "tok-fn" + }, "new"), "()?;", "\n", /*#__PURE__*/React.createElement("span", { + className: "tok-kw" + }, "let"), " resp = client", "\n", " ", ".", /*#__PURE__*/React.createElement("span", { + className: "tok-fn" + }, "complete"), "(", /*#__PURE__*/React.createElement("span", { + className: "tok-str" + }, "\"explain this stack trace\""), ")", "\n", " ", ".", /*#__PURE__*/React.createElement("span", { + className: "tok-fn" + }, "model"), "(", /*#__PURE__*/React.createElement("span", { + className: "tok-str" + }, "\"claude-sonnet\""), ")", "\n", " ", ".", /*#__PURE__*/React.createElement("span", { + className: "tok-fn" + }, "max_tokens"), "(", /*#__PURE__*/React.createElement("span", { + className: "tok-num" + }, "1024"), ")", "\n", " ", ".", /*#__PURE__*/React.createElement("span", { + className: "tok-fn" + }, "send"), "().", /*#__PURE__*/React.createElement("span", { + className: "tok-kw" + }, "await"), "?;", "\n", /*#__PURE__*/React.createElement("span", { + className: "tok-fn" + }, "println!"), "(", /*#__PURE__*/React.createElement("span", { + className: "tok-str" + }, "\"", `{}`, "\""), ", resp.text);"), + typescript: /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("span", { + className: "tok-kw" + }, "import"), " ", "{ Client }", " ", /*#__PURE__*/React.createElement("span", { + className: "tok-kw" + }, "from"), " ", /*#__PURE__*/React.createElement("span", { + className: "tok-str" + }, "\"panto\""), ";", "\n\n", /*#__PURE__*/React.createElement("span", { + className: "tok-kw" + }, "const"), " client = ", /*#__PURE__*/React.createElement("span", { + className: "tok-kw" + }, "new"), " ", /*#__PURE__*/React.createElement("span", { + className: "tok-fn" + }, "Client"), "();", "\n", /*#__PURE__*/React.createElement("span", { + className: "tok-kw" + }, "const"), " resp = ", /*#__PURE__*/React.createElement("span", { + className: "tok-kw" + }, "await"), " client.", /*#__PURE__*/React.createElement("span", { + className: "tok-fn" + }, "complete"), "(", "{", "\n", " ", "prompt: ", /*#__PURE__*/React.createElement("span", { + className: "tok-str" + }, "\"explain this stack trace\""), ",", "\n", " ", "model: ", /*#__PURE__*/React.createElement("span", { + className: "tok-str" + }, "\"claude-sonnet\""), ",", "\n", " ", "maxTokens: ", /*#__PURE__*/React.createElement("span", { + className: "tok-num" + }, "1024"), ",", "\n", "});", "\n", "console.", /*#__PURE__*/React.createElement("span", { + className: "tok-fn" + }, "log"), "(resp.text);") + }; + const FILE = { + python: 'main.py', + rust: 'src/main.rs', + typescript: 'index.ts' + }; + const PARAMS = [['prompt', 'string', 'required', 'The input message sent to the model.'], ['model', 'string', '"claude-sonnet"', 'Provider-agnostic model alias. Resolved per provider.'], ['max_tokens', 'int', '1024', 'Upper bound on generated tokens.'], ['stream', 'bool', 'false', 'Return an async iterator of deltas instead of a full Response.'], ['tools', 'Tool[]', '[]', 'Tool definitions the model may call.']]; + function ReferencePage() { + const [lang, setLang] = React.useState('python'); + return /*#__PURE__*/React.createElement("article", { + className: "dk-doc" + }, /*#__PURE__*/React.createElement("div", { + className: "dk-crumbs" + }, /*#__PURE__*/React.createElement("span", null, "Reference"), /*#__PURE__*/React.createElement(I.ChevronRight, null), /*#__PURE__*/React.createElement("span", { + className: "dk-crumbs__here" + }, "complete()")), /*#__PURE__*/React.createElement("p", { + className: "panto-eyebrow" + }, "SDK Reference"), /*#__PURE__*/React.createElement("h1", { + className: "dk-doc__h1" + }, "client.complete()"), /*#__PURE__*/React.createElement("div", { + className: "dk-doc__meta" + }, /*#__PURE__*/React.createElement(Badge, { + variant: "success", + dot: true + }, "Stable"), /*#__PURE__*/React.createElement(Badge, { + variant: "neutral" + }, "since v2.0"), /*#__PURE__*/React.createElement(Tag, { + dot: "#3572A5" + }, "python"), /*#__PURE__*/React.createElement(Tag, { + dot: "#DEA584" + }, "rust"), /*#__PURE__*/React.createElement(Tag, { + dot: "#3178C6" + }, "typescript")), /*#__PURE__*/React.createElement("p", { + className: "dk-lead" + }, "Send a single prompt and receive one complete response. The same call signature is reproduced across every binding \u2014 write it once, scale it to any language."), /*#__PURE__*/React.createElement("h2", { + className: "dk-h2", + id: "example" + }, "Example"), /*#__PURE__*/React.createElement("div", { + className: "dk-langbar" + }, /*#__PURE__*/React.createElement(Tabs, { + variant: "pill", + value: lang, + onChange: setLang, + tabs: ['python', 'rust', 'typescript'] + })), /*#__PURE__*/React.createElement(CodeBlock, { + filename: FILE[lang], + language: lang + }, SAMPLES[lang]), /*#__PURE__*/React.createElement(Callout, { + variant: "tip" + }, "Set ", /*#__PURE__*/React.createElement("code", null, "PANTO_KEY"), " in your environment once. Every binding \u2014 and the ", /*#__PURE__*/React.createElement("code", null, "panto"), " CLI \u2014 reads it automatically."), /*#__PURE__*/React.createElement("h2", { + className: "dk-h2", + id: "parameters" + }, "Parameters"), /*#__PURE__*/React.createElement("div", { + className: "dk-table-wrap" + }, /*#__PURE__*/React.createElement("table", { + className: "dk-table" + }, /*#__PURE__*/React.createElement("thead", null, /*#__PURE__*/React.createElement("tr", null, /*#__PURE__*/React.createElement("th", null, "Name"), /*#__PURE__*/React.createElement("th", null, "Type"), /*#__PURE__*/React.createElement("th", null, "Default"), /*#__PURE__*/React.createElement("th", null, "Description"))), /*#__PURE__*/React.createElement("tbody", null, PARAMS.map(p => /*#__PURE__*/React.createElement("tr", { + key: p[0] + }, /*#__PURE__*/React.createElement("td", null, /*#__PURE__*/React.createElement("code", null, p[0])), /*#__PURE__*/React.createElement("td", null, /*#__PURE__*/React.createElement("span", { + className: "dk-type" + }, p[1])), /*#__PURE__*/React.createElement("td", null, p[2] === 'required' ? /*#__PURE__*/React.createElement(Badge, { + variant: "danger" + }, "required") : /*#__PURE__*/React.createElement("code", { + className: "dk-default" + }, p[2])), /*#__PURE__*/React.createElement("td", null, p[3])))))), /*#__PURE__*/React.createElement("h2", { + className: "dk-h2", + id: "returns" + }, "Returns"), /*#__PURE__*/React.createElement("p", { + className: "dk-body" + }, "A ", /*#__PURE__*/React.createElement("a", { + href: "#" + }, "Response"), " object with ", /*#__PURE__*/React.createElement("code", null, ".text"), ", ", /*#__PURE__*/React.createElement("code", null, ".usage"), ", and ", /*#__PURE__*/React.createElement("code", null, ".stop_reason"), ". When ", /*#__PURE__*/React.createElement("code", null, "stream=true"), ", returns an async iterator yielding ", /*#__PURE__*/React.createElement("code", null, "Delta"), " objects instead."), /*#__PURE__*/React.createElement(Callout, { + variant: "danger", + title: "Deprecated argument" + }, "The ", /*#__PURE__*/React.createElement("code", null, "temperature"), " float is removed in v3 \u2014 pass a", /*#__PURE__*/React.createElement("code", null, "Sampling"), " config instead. See the migration guide.")); + } + window.ReferencePage = ReferencePage; +})(); +})(); } catch (e) { __ds_ns.__errors.push({ path: "ui_kits/docs/ReferencePage.jsx", error: String((e && e.message) || e) }); } + +// ui_kits/home/Features.jsx +try { (() => { +// Features — a grid of capability cards. +(function () { + const React = window.React; + const { + Card, + Badge + } = window.PantographDesignSystem_56a1c7; + const I = window.Icons; + const FEATURES = [{ + icon: /*#__PURE__*/React.createElement(I.Boxes, null), + title: 'Provider-agnostic', + body: 'One client targets OpenAI, Anthropic, or a local model. Swap providers with a string — no rewrites.' + }, { + icon: /*#__PURE__*/React.createElement(I.Zap, null), + title: 'Streaming & tools', + body: 'First-class async iterators for token streams and a typed tool-use loop across every binding.' + }, { + icon: /*#__PURE__*/React.createElement(I.Layers, null), + title: 'Typed responses', + body: 'complete() returns a structured Response — text, usage, stop reason — not a raw string.' + }, { + icon: /*#__PURE__*/React.createElement(I.Terminal, null), + title: 'The panto agent', + body: 'A terminal coding agent built on libpanto — a minimal system prompt and tool set you can swap out entirely. Written in Zig, extended in Lua.' + }]; + function Features() { + return /*#__PURE__*/React.createElement("section", { + className: "hm-features" + }, /*#__PURE__*/React.createElement("div", { + className: "hm-section-head" + }, /*#__PURE__*/React.createElement("p", { + className: "panto-eyebrow" + }, "Why pantograph"), /*#__PURE__*/React.createElement("h2", { + className: "hm-h2" + }, "A small instrument, precisely built.")), /*#__PURE__*/React.createElement("div", { + className: "hm-feature-grid" + }, FEATURES.map(f => /*#__PURE__*/React.createElement(Card, { + key: f.title, + className: "hm-feature" + }, /*#__PURE__*/React.createElement("span", { + className: "hm-feature__icon" + }, f.icon), /*#__PURE__*/React.createElement("h3", { + className: "hm-feature__title" + }, f.title), /*#__PURE__*/React.createElement("p", { + className: "hm-feature__body" + }, f.body))))); + } + window.Features = Features; +})(); +})(); } catch (e) { __ds_ns.__errors.push({ path: "ui_kits/home/Features.jsx", error: String((e && e.message) || e) }); } + +// ui_kits/home/Hero.jsx +try { (() => { +// Hero — headline, install command, CTAs, and a live-looking terminal. +(function () { + const React = window.React; + const { + Button, + Badge, + Terminal + } = window.PantographDesignSystem_56a1c7; + const I = window.Icons; + function CopyCommand({ + text + }) { + const [done, setDone] = React.useState(false); + return /*#__PURE__*/React.createElement("button", { + className: "hm-cmd", + onClick: () => { + if (navigator.clipboard) navigator.clipboard.writeText(text); + setDone(true); + setTimeout(() => setDone(false), 1400); + } + }, /*#__PURE__*/React.createElement("span", { + className: "hm-cmd__prompt" + }, "$"), /*#__PURE__*/React.createElement("span", { + className: "hm-cmd__text" + }, text), /*#__PURE__*/React.createElement("span", { + className: 'hm-cmd__copy' + (done ? ' hm-cmd__copy--done' : '') + }, done ? /*#__PURE__*/React.createElement(I.Check, null) : /*#__PURE__*/React.createElement(I.Compass, null))); + } + function Hero() { + return /*#__PURE__*/React.createElement("section", { + className: "hm-hero" + }, /*#__PURE__*/React.createElement("div", { + className: "hm-hero__copy" + }, /*#__PURE__*/React.createElement("p", { + className: "panto-eyebrow" + }, "Open source \xB7 MIT \xB7 v2.4"), /*#__PURE__*/React.createElement("h1", { + className: "hm-hero__h1" + }, "Scale one prompt", /*#__PURE__*/React.createElement("br", null), "to every provider."), /*#__PURE__*/React.createElement("p", { + className: "hm-hero__lead" + }, /*#__PURE__*/React.createElement("strong", null, "libpanto"), " is a single, small set of motions \u2014 faithfully reproduced across OpenAI, Anthropic, and your local models. ", /*#__PURE__*/React.createElement("strong", null, "panto"), " ", "is the terminal coding agent built on top."), /*#__PURE__*/React.createElement(CopyCommand, { + text: "pip install panto" + }), /*#__PURE__*/React.createElement("div", { + className: "hm-hero__cta" + }, /*#__PURE__*/React.createElement(Button, { + variant: "accent", + size: "lg", + icon: /*#__PURE__*/React.createElement(I.Terminal, null) + }, "Get started"), /*#__PURE__*/React.createElement(Button, { + variant: "secondary", + size: "lg", + icon: /*#__PURE__*/React.createElement(I.Github, null) + }, "Star on GitHub")), /*#__PURE__*/React.createElement("div", { + className: "hm-hero__langs" + }, /*#__PURE__*/React.createElement("span", { + className: "hm-hero__langlabel" + }, "Bindings"), /*#__PURE__*/React.createElement("span", { + className: "hm-langdot", + style: { + background: '#3572A5' + } + }), "python", /*#__PURE__*/React.createElement("span", { + className: "hm-langdot", + style: { + background: '#DEA584' + } + }), "rust", /*#__PURE__*/React.createElement("span", { + className: "hm-langdot", + style: { + background: '#3178C6' + } + }), "typescript", /*#__PURE__*/React.createElement("span", { + className: "hm-hero__more" + }, "+ 1 in beta"))), /*#__PURE__*/React.createElement("div", { + className: "hm-hero__demo" + }, /*#__PURE__*/React.createElement(Terminal, { + title: "panto \xB7 run", + cursor: true, + lines: [{ + type: 'cmd', + shell: 'shell', + text: 'panto run "add a --json flag to the export command"' + }, { + type: 'com', + text: '• indexed 41 files · 3 relevant' + }, { + type: 'cmd', + shell: 'panto', + text: "I'll add a --json flag and route output through the serializer." + }, { + type: 'out', + text: ' cli/export.py +18 −2' + }, { + type: 'out', + text: ' cli/__init__.py +3' + }, { + type: 'ok', + text: '✓ applied · 2 files changed in 0.3s' + }] + }))); + } + window.Hero = Hero; +})(); +})(); } catch (e) { __ds_ns.__errors.push({ path: "ui_kits/home/Hero.jsx", error: String((e && e.message) || e) }); } + +// ui_kits/home/HomeApp.jsx +try { (() => { +// HomeApp — composes the marketing page + footer. +(function () { + const React = window.React; + function Footer() { + const COLS = [{ + h: 'SDK', + items: ['Installation', 'Reference', 'Streaming', 'Tool use'] + }, { + h: 'panto CLI', + items: ['Quickstart', 'Commands', 'Configuration'] + }, { + h: 'Project', + items: ['GitHub', 'Changelog', 'Roadmap', 'License (MIT)'] + }]; + return /*#__PURE__*/React.createElement("footer", { + className: "hm-footer" + }, /*#__PURE__*/React.createElement("div", { + className: "hm-footer__inner" + }, /*#__PURE__*/React.createElement("div", { + className: "hm-footer__brand" + }, /*#__PURE__*/React.createElement("div", { + className: "hm-brand" + }, /*#__PURE__*/React.createElement("img", { + src: "../../assets/logo-mark.svg", + width: "28", + height: "28", + alt: "" + }), /*#__PURE__*/React.createElement("span", { + className: "hm-brand__word" + }, "pantograph")), /*#__PURE__*/React.createElement("p", { + className: "hm-footer__tag" + }, "Scale one prompt to every provider.")), COLS.map(c => /*#__PURE__*/React.createElement("div", { + className: "hm-footer__col", + key: c.h + }, /*#__PURE__*/React.createElement("p", { + className: "hm-footer__h" + }, c.h), c.items.map(it => /*#__PURE__*/React.createElement("a", { + key: it, + href: "#", + className: "hm-footer__link" + }, it))))), /*#__PURE__*/React.createElement("div", { + className: "hm-footer__bar" + }, /*#__PURE__*/React.createElement("span", null, "\xA9 2026 the pantograph authors"), /*#__PURE__*/React.createElement("span", { + className: "hm-footer__mono" + }, "built with libpanto"))); + } + function HomeApp() { + return /*#__PURE__*/React.createElement("div", { + className: "hm-app" + }, /*#__PURE__*/React.createElement(window.HomeHeader, null), /*#__PURE__*/React.createElement("main", null, /*#__PURE__*/React.createElement(window.Hero, null), /*#__PURE__*/React.createElement("div", { + className: "hm-ruler", + "aria-hidden": "true" + }), /*#__PURE__*/React.createElement(window.InstallSection, null), /*#__PURE__*/React.createElement(window.Features, null)), /*#__PURE__*/React.createElement(Footer, null)); + } + window.HomeApp = HomeApp; +})(); +})(); } catch (e) { __ds_ns.__errors.push({ path: "ui_kits/home/HomeApp.jsx", error: String((e && e.message) || e) }); } + +// ui_kits/home/HomeHeader.jsx +try { (() => { +// Lucide-derived inline icons (ISC) + HomeHeader. Icons live here (a JSX file) +// so the design-system compiler treats them as kit-local, not a bundle module. +(function () { + const React = window.React; + const S = (paths, extra = {}) => props => React.createElement('svg', Object.assign({ + viewBox: '0 0 24 24', + fill: 'none', + stroke: 'currentColor', + strokeWidth: 2, + strokeLinecap: 'round', + strokeLinejoin: 'round', + width: '1em', + height: '1em' + }, extra, props), paths.map((d, i) => React.createElement('path', { + key: i, + d + }))); + const M = (children, extra = {}) => props => React.createElement('svg', Object.assign({ + viewBox: '0 0 24 24', + fill: 'none', + stroke: 'currentColor', + strokeWidth: 2, + strokeLinecap: 'round', + strokeLinejoin: 'round', + width: '1em', + height: '1em' + }, extra, props), children(React)); + window.Icons = { + ChevronRight: S(['m9 18 6-6-6-6']), + Book: S(['M4 19.5v-15A2.5 2.5 0 0 1 6.5 2H20v20H6.5a2.5 2.5 0 0 1 0-5H20']), + Terminal: S(['m4 17 6-6-6-6', 'M12 19h8']), + Github: M(R => [R.createElement('path', { + key: 0, + d: 'M15 22v-4a4.8 4.8 0 0 0-1-3.5c3 0 6-2 6-5.5.08-1.25-.27-2.48-1-3.5.28-1.15.28-2.35 0-3.5 0 0-1 0-3 1.5-2.64-.5-5.36-.5-8 0C6 .5 5 .5 5 .5c-.3 1.15-.3 2.35 0 3.5A5.4 5.4 0 0 0 4 7.5c0 3.5 3 5.5 6 5.5-.39.49-.68 1.05-.85 1.65-.17.6-.22 1.23-.15 1.85v4' + }), R.createElement('path', { + key: 1, + d: 'M9 18c-4.51 2-5-2-7-2' + })]), + Zap: S(['M4 14a1 1 0 0 1-.78-1.63l9.9-10.2a.5.5 0 0 1 .86.46l-1.92 6.02A1 1 0 0 0 13 10h7a1 1 0 0 1 .78 1.63l-9.9 10.2a.5.5 0 0 1-.86-.46l1.92-6.02A1 1 0 0 0 11 14z']), + Boxes: S(['M2.97 12.92A2 2 0 0 0 2 14.63v3.24a2 2 0 0 0 .97 1.71l3 1.8a2 2 0 0 0 2.06 0L12 19v-5.5l-5-3-4.03 2.42Z', 'm7 16.5-4.74-2.85', 'm7 16.5 5-3', 'M7 16.5v5.17', 'M12 13.5V19l3.97 2.38a2 2 0 0 0 2.06 0l3-1.8a2 2 0 0 0 .97-1.71v-3.24a2 2 0 0 0-.97-1.71L17 10.5l-5 3Z', 'm17 16.5-5-3', 'm17 16.5 4.74-2.85', 'M17 16.5v5.17', 'M7.97 4.42A2 2 0 0 0 7 6.13v4.37l5 3 5-3V6.13a2 2 0 0 0-.97-1.71l-3-1.8a2 2 0 0 0-2.06 0l-3 1.8Z', 'M12 8 7.26 5.15', 'm12 8 4.74-2.85', 'M12 13.5V8']), + Layers: S(['m12.83 2.18a2 2 0 0 0-1.66 0L2.6 6.08a1 1 0 0 0 0 1.83l8.58 3.91a2 2 0 0 0 1.66 0l8.58-3.9a1 1 0 0 0 0-1.83Z', 'M2 12a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 12', 'M2 17a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 17']), + Check: S(['M20 6 9 17l-5-5']), + Compass: M(R => [R.createElement('path', { + key: 0, + d: 'm16.24 7.76-1.804 5.411a2 2 0 0 1-1.265 1.265L7.76 16.24l1.804-5.411a2 2 0 0 1 1.265-1.265z' + }), R.createElement('circle', { + key: 1, + cx: 12, + cy: 12, + r: 10 + })]) + }; +})(); + +// HomeHeader — marketing top bar. +(function () { + const React = window.React; + const { + Button + } = window.PantographDesignSystem_56a1c7; + const I = window.Icons; + function HomeHeader() { + return /*#__PURE__*/React.createElement("header", { + className: "hm-header" + }, /*#__PURE__*/React.createElement("a", { + className: "hm-brand", + href: "#" + }, /*#__PURE__*/React.createElement("img", { + src: "../../assets/logo-mark.svg", + width: "30", + height: "30", + alt: "" + }), /*#__PURE__*/React.createElement("span", { + className: "hm-brand__word" + }, "pantograph")), /*#__PURE__*/React.createElement("nav", { + className: "hm-nav" + }, /*#__PURE__*/React.createElement("a", { + href: "#", + className: "hm-nav__link" + }, "Docs"), /*#__PURE__*/React.createElement("a", { + href: "#", + className: "hm-nav__link" + }, "SDK"), /*#__PURE__*/React.createElement("a", { + href: "#", + className: "hm-nav__link" + }, "CLI"), /*#__PURE__*/React.createElement("a", { + href: "#", + className: "hm-nav__link" + }, "Blog")), /*#__PURE__*/React.createElement("div", { + className: "hm-header__right" + }, /*#__PURE__*/React.createElement("a", { + href: "#", + className: "hm-stars" + }, /*#__PURE__*/React.createElement(I.Github, null), " 14.2k"), /*#__PURE__*/React.createElement(Button, { + variant: "primary", + size: "sm", + icon: /*#__PURE__*/React.createElement(I.Book, null) + }, "Read the docs"))); + } + window.HomeHeader = HomeHeader; +})(); +})(); } catch (e) { __ds_ns.__errors.push({ path: "ui_kits/home/HomeHeader.jsx", error: String((e && e.message) || e) }); } + +// ui_kits/home/InstallSection.jsx +try { (() => { +// InstallSection — "same call, every language" with a language switcher. +(function () { + const React = window.React; + const { + Tabs, + CodeBlock + } = window.PantographDesignSystem_56a1c7; + const INSTALL = { + python: 'pip install panto', + rust: 'cargo add panto', + typescript: 'npm install panto' + }; + const FILE = { + python: 'main.py', + rust: 'src/main.rs', + typescript: 'index.ts' + }; + const CODE = { + python: /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("span", { + className: "tok-kw" + }, "import"), " panto", "\n\n", "resp = panto.", /*#__PURE__*/React.createElement("span", { + className: "tok-fn" + }, "Client"), "().", /*#__PURE__*/React.createElement("span", { + className: "tok-fn" + }, "complete"), "(", /*#__PURE__*/React.createElement("span", { + className: "tok-str" + }, "\"name three uses for a pantograph\""), ")", "\n", /*#__PURE__*/React.createElement("span", { + className: "tok-kw" + }, "print"), "(resp.text)"), + rust: /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("span", { + className: "tok-kw" + }, "use"), " panto::Client;", "\n\n", /*#__PURE__*/React.createElement("span", { + className: "tok-kw" + }, "let"), " resp = Client::", /*#__PURE__*/React.createElement("span", { + className: "tok-fn" + }, "new"), "()?", "\n", " ", ".", /*#__PURE__*/React.createElement("span", { + className: "tok-fn" + }, "complete"), "(", /*#__PURE__*/React.createElement("span", { + className: "tok-str" + }, "\"name three uses for a pantograph\""), ")", "\n", " ", ".", /*#__PURE__*/React.createElement("span", { + className: "tok-fn" + }, "send"), "().", /*#__PURE__*/React.createElement("span", { + className: "tok-kw" + }, "await"), "?;", "\n", /*#__PURE__*/React.createElement("span", { + className: "tok-fn" + }, "println!"), "(", /*#__PURE__*/React.createElement("span", { + className: "tok-str" + }, "\"", `{}`, "\""), ", resp.text);"), + typescript: /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("span", { + className: "tok-kw" + }, "import"), " ", "{ Client }", " ", /*#__PURE__*/React.createElement("span", { + className: "tok-kw" + }, "from"), " ", /*#__PURE__*/React.createElement("span", { + className: "tok-str" + }, "\"panto\""), ";", "\n\n", /*#__PURE__*/React.createElement("span", { + className: "tok-kw" + }, "const"), " resp = ", /*#__PURE__*/React.createElement("span", { + className: "tok-kw" + }, "await"), " ", /*#__PURE__*/React.createElement("span", { + className: "tok-kw" + }, "new"), " ", /*#__PURE__*/React.createElement("span", { + className: "tok-fn" + }, "Client"), "()", "\n", " ", ".", /*#__PURE__*/React.createElement("span", { + className: "tok-fn" + }, "complete"), "(", /*#__PURE__*/React.createElement("span", { + className: "tok-str" + }, "\"name three uses for a pantograph\""), ");", "\n", "console.", /*#__PURE__*/React.createElement("span", { + className: "tok-fn" + }, "log"), "(resp.text);") + }; + function InstallSection() { + const [lang, setLang] = React.useState('python'); + return /*#__PURE__*/React.createElement("section", { + className: "hm-install" + }, /*#__PURE__*/React.createElement("div", { + className: "hm-section-head" + }, /*#__PURE__*/React.createElement("p", { + className: "panto-eyebrow" + }, "The SDK"), /*#__PURE__*/React.createElement("h2", { + className: "hm-h2" + }, "Same call, every language."), /*#__PURE__*/React.createElement("p", { + className: "hm-section-sub" + }, "The signature doesn't change when the language does. Learn it once.")), /*#__PURE__*/React.createElement("div", { + className: "hm-install__panel" + }, /*#__PURE__*/React.createElement("div", { + className: "hm-install__tabs" + }, /*#__PURE__*/React.createElement(Tabs, { + variant: "pill", + value: lang, + onChange: setLang, + tabs: ['python', 'rust', 'typescript'] + })), /*#__PURE__*/React.createElement(CodeBlock, { + filename: "install", + language: "shell", + showBar: true, + code: INSTALL[lang] + }), /*#__PURE__*/React.createElement(CodeBlock, { + filename: FILE[lang], + language: lang + }, CODE[lang]))); + } + window.InstallSection = InstallSection; +})(); +})(); } catch (e) { __ds_ns.__errors.push({ path: "ui_kits/home/InstallSection.jsx", error: String((e && e.message) || e) }); } + +__ds_ns.Callout = __ds_scope.Callout; + +__ds_ns.CodeBlock = __ds_scope.CodeBlock; + +__ds_ns.Terminal = __ds_scope.Terminal; + +__ds_ns.Badge = __ds_scope.Badge; + +__ds_ns.Button = __ds_scope.Button; + +__ds_ns.Card = __ds_scope.Card; + +__ds_ns.IconButton = __ds_scope.IconButton; + +__ds_ns.Tag = __ds_scope.Tag; + +__ds_ns.Input = __ds_scope.Input; + +__ds_ns.Select = __ds_scope.Select; + +__ds_ns.Switch = __ds_scope.Switch; + +__ds_ns.Tabs = __ds_scope.Tabs; + +})(); diff --git a/_ds/pantograph-design-system-56a1c74e-41c1-486b-ba3c-4eabdfacef31/_ds_manifest.json b/_ds/pantograph-design-system-56a1c74e-41c1-486b-ba3c-4eabdfacef31/_ds_manifest.json new file mode 100644 index 0000000..df50d41 --- /dev/null +++ b/_ds/pantograph-design-system-56a1c74e-41c1-486b-ba3c-4eabdfacef31/_ds_manifest.json @@ -0,0 +1 @@ +{"namespace":"PantographDesignSystem_56a1c7","components":[{"name":"Callout","sourcePath":"components/code/Callout.jsx"},{"name":"CodeBlock","sourcePath":"components/code/CodeBlock.jsx"},{"name":"Terminal","sourcePath":"components/code/Terminal.jsx"},{"name":"Badge","sourcePath":"components/core/Badge.jsx"},{"name":"Button","sourcePath":"components/core/Button.jsx"},{"name":"Card","sourcePath":"components/core/Card.jsx"},{"name":"IconButton","sourcePath":"components/core/IconButton.jsx"},{"name":"Tag","sourcePath":"components/core/Tag.jsx"},{"name":"Input","sourcePath":"components/forms/Input.jsx"},{"name":"Select","sourcePath":"components/forms/Select.jsx"},{"name":"Switch","sourcePath":"components/forms/Switch.jsx"},{"name":"Tabs","sourcePath":"components/navigation/Tabs.jsx"}],"startingPoints":[{"name":"Button","path":"components/core/Button.jsx","previewPath":"components/core/core.card.html","kind":"component","section":"Core","subtitle":"Buttons in every variant & size","viewport":"700x220"},{"name":"Card","path":"components/core/Card.jsx","previewPath":"components/core/core.card.html","kind":"component","section":"Core","subtitle":"Surface container with header/body/footer","viewport":"700x320"},{"name":"docs","path":"ui_kits/docs/index.html","previewPath":"ui_kits/docs/index.html","kind":"screen","section":"Docs","subtitle":"libpanto SDK documentation site","viewport":"1280x800"},{"name":"home","path":"ui_kits/home/index.html","previewPath":"ui_kits/home/index.html","kind":"screen","section":"Marketing","subtitle":"pantograph project homepage","viewport":"1280x860"}],"cards":[{"path":"guidelines/brand-logo-variants.card.html","group":"Brand","viewport":"700x160","subtitle":"On paper, on ink, and the monochrome mark. Keep one mark of clearspace.","name":"Logo — variants & placement"},{"path":"guidelines/brand-logo.card.html","group":"Brand","viewport":"700x200","subtitle":"A parallelogram linkage: anchored fulcrum, scaling axis, red pen tip.","name":"Logo — the pantograph mark"},{"path":"guidelines/brand-voice.card.html","group":"Brand","viewport":"700x210","subtitle":"Light, straightforward, fast, minimal. Everything you specify, nothing you don't.","name":"Voice & tone"},{"path":"guidelines/color-accents.card.html","group":"Colors","viewport":"700x190","subtitle":"The only two accents. Used like a draftsman: sparingly, for meaning.","name":"Instrument accents — red & green"},{"path":"guidelines/color-ink.card.html","group":"Colors","viewport":"700x150","subtitle":"Text ramp. The darkest is a blue-black, never pure black.","name":"Ink — deep blue-black marks"},{"path":"guidelines/color-paper.card.html","group":"Colors","viewport":"700x150","subtitle":"Faint warm tint, close to white. No pure #FFF, no yellow cast.","name":"Paper — near-white surfaces"},{"path":"guidelines/color-status.card.html","group":"Colors","viewport":"700x150","subtitle":"Semantic aliases — reference these, not the raw ramp.","name":"Status & surfaces"},{"path":"components/code/code.card.html","group":"Components","viewport":"700x520","subtitle":"The documentation & CLI surfaces.","name":"Code — CodeBlock, Terminal, Callout"},{"path":"components/core/core.card.html","group":"Components","viewport":"700x430","subtitle":"The instrument-palette primitives.","name":"Core — Button, IconButton, Badge, Tag, Card"},{"path":"components/forms/forms.card.html","group":"Components","viewport":"700x340","subtitle":"Green focus ring, red invalid state, engraved labels.","name":"Forms — Input, Select, Switch"},{"path":"components/navigation/navigation.card.html","group":"Components","viewport":"700x200","subtitle":"Engraved red cursor underline, plus a compact pill switch.","name":"Navigation — Tabs"},{"path":"ui_kits/docs/index.html","group":"libpanto Docs","viewport":"1280x800","subtitle":"Header, nav tree, language-switching reference page, TOC.","name":"SDK reference site"},{"path":"ui_kits/home/index.html","group":"panto Home","viewport":"1280x860","subtitle":"Hero with live terminal, language-switching install, feature grid.","name":"Project homepage"},{"path":"guidelines/space-borders.card.html","group":"Spacing","viewport":"700x190","subtitle":"Hairlines, and the engraved tick rule — the standard section separator.","name":"Borders, ticks & rules"},{"path":"guidelines/space-radius.card.html","group":"Spacing","viewport":"700x140","subtitle":"Barely rounded. The instrument body has sharp, machined corners.","name":"Radius — machined edges"},{"path":"guidelines/space-scale.card.html","group":"Spacing","viewport":"700x150","subtitle":"4px base unit. Rigid and gridded, like engraved ticks.","name":"Spacing scale"},{"path":"guidelines/space-shadow.card.html","group":"Spacing","viewport":"700x160","subtitle":"Warm, low, ink-tinted. Like an object resting on a drafting table.","name":"Shadows — ink on paper"},{"path":"guidelines/type-display.card.html","group":"Type","viewport":"700x160","subtitle":"The primary face at display scale. Tall, narrow, engraved character.","name":"Display — Saira Condensed"},{"path":"guidelines/type-eyebrow.card.html","group":"Type","viewport":"700x130","subtitle":"Saira Condensed, caps, +0.14em tracking. The slide-rule scale label.","name":"Engraved label / eyebrow"},{"path":"guidelines/type-mono.card.html","group":"Type","viewport":"700x170","subtitle":"Code, terminals, the panto CLI. The machine voice.","name":"Mono — IBM Plex Mono"},{"path":"guidelines/type-prose.card.html","group":"Type","viewport":"700x300","subtitle":"The primary face carries running body copy too. A full paragraph, set for reading.","name":"Prose — Saira Condensed"},{"path":"guidelines/type-sans.card.html","group":"Type","viewport":"700x190","subtitle":"The primary face also runs the interface: headings, buttons, labels, table data, short copy.","name":"UI & body — Saira Condensed"},{"path":"guidelines/type-scale.card.html","group":"Type","viewport":"700x230","subtitle":"1.250 major-third ramp, rooted at 16px.","name":"Type scale"}],"templates":[],"globalCssPaths":["tokens/fonts.css","tokens/colors.css","tokens/typography.css","tokens/spacing.css","tokens/base.css","styles.css"],"tokens":[{"name":"--paper-0","value":"#FCFAF5","kind":"color","definedIn":"tokens/colors.css"},{"name":"--paper-1","value":"#F8F4EB","kind":"color","definedIn":"tokens/colors.css"},{"name":"--paper-2","value":"#EFE9DC","kind":"color","definedIn":"tokens/colors.css"},{"name":"--paper-3","value":"#DFD7C6","kind":"color","definedIn":"tokens/colors.css"},{"name":"--paper-4","value":"#C7BCA4","kind":"color","definedIn":"tokens/colors.css"},{"name":"--ink-0","value":"#161B27","kind":"color","definedIn":"tokens/colors.css"},{"name":"--ink-1","value":"#1E2533","kind":"color","definedIn":"tokens/colors.css"},{"name":"--ink-2","value":"#3B4456","kind":"color","definedIn":"tokens/colors.css"},{"name":"--ink-3","value":"#6E6B5C","kind":"color","definedIn":"tokens/colors.css"},{"name":"--ink-4","value":"#8C8470","kind":"color","definedIn":"tokens/colors.css"},{"name":"--red-deep","value":"#8F2B22","kind":"color","definedIn":"tokens/colors.css"},{"name":"--red","value":"#B23A2E","kind":"color","definedIn":"tokens/colors.css"},{"name":"--red-soft","value":"#E7C3BB","kind":"color","definedIn":"tokens/colors.css"},{"name":"--red-wash","value":"#EBD9D0","kind":"color","definedIn":"tokens/colors.css"},{"name":"--green-deep","value":"#245138","kind":"color","definedIn":"tokens/colors.css"},{"name":"--green","value":"#2F6B4A","kind":"color","definedIn":"tokens/colors.css"},{"name":"--green-soft","value":"#BCD2BF","kind":"color","definedIn":"tokens/colors.css"},{"name":"--green-wash","value":"#D6DECB","kind":"color","definedIn":"tokens/colors.css"},{"name":"--brass","value":"#9A7B3F","kind":"color","definedIn":"tokens/colors.css"},{"name":"--surface-page","value":"var(--paper-1)","kind":"color","definedIn":"tokens/colors.css"},{"name":"--surface-card","value":"var(--paper-0)","kind":"color","definedIn":"tokens/colors.css"},{"name":"--surface-sunken","value":"var(--paper-2)","kind":"color","definedIn":"tokens/colors.css"},{"name":"--surface-code","value":"#F4EEE1","kind":"color","definedIn":"tokens/colors.css"},{"name":"--surface-inverse","value":"var(--ink-1)","kind":"color","definedIn":"tokens/colors.css"},{"name":"--text-strong","value":"var(--ink-0)","kind":"font","definedIn":"tokens/colors.css"},{"name":"--text-body","value":"var(--ink-1)","kind":"font","definedIn":"tokens/colors.css"},{"name":"--text-muted","value":"var(--ink-2)","kind":"font","definedIn":"tokens/colors.css"},{"name":"--text-faint","value":"var(--ink-3)","kind":"font","definedIn":"tokens/colors.css"},{"name":"--text-placeholder","value":"var(--ink-4)","kind":"font","definedIn":"tokens/colors.css"},{"name":"--text-on-ink","value":"var(--paper-0)","kind":"font","definedIn":"tokens/colors.css"},{"name":"--text-on-accent","value":"var(--paper-0)","kind":"font","definedIn":"tokens/colors.css"},{"name":"--border-hairline","value":"var(--paper-3)","kind":"color","definedIn":"tokens/colors.css"},{"name":"--border-default","value":"var(--paper-4)","kind":"color","definedIn":"tokens/colors.css"},{"name":"--border-strong","value":"var(--ink-3)","kind":"color","definedIn":"tokens/colors.css"},{"name":"--rule-tick","value":"var(--paper-4)","kind":"color","definedIn":"tokens/colors.css"},{"name":"--accent","value":"var(--red)","kind":"color","definedIn":"tokens/colors.css"},{"name":"--accent-deep","value":"var(--red-deep)","kind":"color","definedIn":"tokens/colors.css"},{"name":"--link","value":"var(--red-deep)","kind":"color","definedIn":"tokens/colors.css"},{"name":"--link-hover","value":"var(--red)","kind":"color","definedIn":"tokens/colors.css"},{"name":"--status-danger","value":"var(--red)","kind":"color","definedIn":"tokens/colors.css"},{"name":"--status-danger-bg","value":"var(--red-wash)","kind":"color","definedIn":"tokens/colors.css"},{"name":"--status-success","value":"var(--green)","kind":"color","definedIn":"tokens/colors.css"},{"name":"--status-success-bg","value":"var(--green-wash)","kind":"color","definedIn":"tokens/colors.css"},{"name":"--status-info","value":"var(--ink-2)","kind":"color","definedIn":"tokens/colors.css"},{"name":"--status-info-bg","value":"var(--paper-2)","kind":"color","definedIn":"tokens/colors.css"},{"name":"--focus-ring","value":"var(--green)","kind":"color","definedIn":"tokens/colors.css"},{"name":"--font-primary","value":"'Saira Condensed', 'Arial Narrow', sans-serif","kind":"font","definedIn":"tokens/typography.css"},{"name":"--font-mono","value":"'IBM Plex Mono', ui-monospace, 'SF Mono', Menlo, monospace","kind":"font","definedIn":"tokens/typography.css"},{"name":"--font-display","value":"var(--font-primary)","kind":"font","definedIn":"tokens/typography.css"},{"name":"--font-sans","value":"var(--font-primary)","kind":"font","definedIn":"tokens/typography.css"},{"name":"--font-serif","value":"var(--font-primary)","kind":"font","definedIn":"tokens/typography.css"},{"name":"--text-2xs","value":"0.6875rem","kind":"font","definedIn":"tokens/typography.css"},{"name":"--text-xs","value":"0.75rem","kind":"font","definedIn":"tokens/typography.css"},{"name":"--text-sm","value":"0.875rem","kind":"font","definedIn":"tokens/typography.css"},{"name":"--text-base","value":"1rem","kind":"font","definedIn":"tokens/typography.css"},{"name":"--text-md","value":"1.125rem","kind":"font","definedIn":"tokens/typography.css"},{"name":"--text-lg","value":"1.375rem","kind":"font","definedIn":"tokens/typography.css"},{"name":"--text-xl","value":"1.75rem","kind":"font","definedIn":"tokens/typography.css"},{"name":"--text-2xl","value":"2.25rem","kind":"font","definedIn":"tokens/typography.css"},{"name":"--text-3xl","value":"3rem","kind":"font","definedIn":"tokens/typography.css"},{"name":"--text-4xl","value":"4rem","kind":"font","definedIn":"tokens/typography.css"},{"name":"--text-5xl","value":"5.5rem","kind":"font","definedIn":"tokens/typography.css"},{"name":"--weight-regular","value":"400","kind":"font","definedIn":"tokens/typography.css"},{"name":"--weight-medium","value":"500","kind":"font","definedIn":"tokens/typography.css"},{"name":"--weight-semibold","value":"600","kind":"font","definedIn":"tokens/typography.css"},{"name":"--weight-bold","value":"700","kind":"font","definedIn":"tokens/typography.css"},{"name":"--leading-tight","value":"1.05","kind":"font","definedIn":"tokens/typography.css"},{"name":"--leading-snug","value":"1.25","kind":"font","definedIn":"tokens/typography.css"},{"name":"--leading-normal","value":"1.5","kind":"font","definedIn":"tokens/typography.css"},{"name":"--leading-relaxed","value":"1.7","kind":"font","definedIn":"tokens/typography.css"},{"name":"--leading-mono","value":"1.6","kind":"font","definedIn":"tokens/typography.css"},{"name":"--tracking-label","value":"0.14em","kind":"font","definedIn":"tokens/typography.css"},{"name":"--tracking-tight","value":"-0.01em","kind":"font","definedIn":"tokens/typography.css"},{"name":"--tracking-normal","value":"0","kind":"font","definedIn":"tokens/typography.css"},{"name":"--role-display","value":"var(--weight-bold) var(--text-4xl)/var(--leading-tight) var(--font-display)","kind":"color","definedIn":"tokens/typography.css"},{"name":"--role-h1","value":"var(--weight-bold) var(--text-3xl)/var(--leading-snug) var(--font-display)","kind":"color","definedIn":"tokens/typography.css"},{"name":"--role-h2","value":"var(--weight-semibold) var(--text-2xl)/var(--leading-snug) var(--font-sans)","kind":"color","definedIn":"tokens/typography.css"},{"name":"--role-h3","value":"var(--weight-semibold) var(--text-xl)/var(--leading-snug) var(--font-sans)","kind":"color","definedIn":"tokens/typography.css"},{"name":"--role-body","value":"var(--weight-regular) var(--text-base)/var(--leading-normal) var(--font-sans)","kind":"color","definedIn":"tokens/typography.css"},{"name":"--role-prose","value":"var(--weight-regular) var(--text-md)/var(--leading-relaxed) var(--font-primary)","kind":"color","definedIn":"tokens/typography.css"},{"name":"--role-code","value":"var(--weight-regular) var(--text-sm)/var(--leading-mono) var(--font-mono)","kind":"color","definedIn":"tokens/typography.css"},{"name":"--role-label","value":"var(--weight-semibold) var(--text-xs)/1 var(--font-display)","kind":"color","definedIn":"tokens/typography.css"},{"name":"--space-0","value":"0","kind":"spacing","definedIn":"tokens/spacing.css"},{"name":"--space-1","value":"0.25rem","kind":"spacing","definedIn":"tokens/spacing.css"},{"name":"--space-2","value":"0.5rem","kind":"spacing","definedIn":"tokens/spacing.css"},{"name":"--space-3","value":"0.75rem","kind":"spacing","definedIn":"tokens/spacing.css"},{"name":"--space-4","value":"1rem","kind":"spacing","definedIn":"tokens/spacing.css"},{"name":"--space-5","value":"1.5rem","kind":"spacing","definedIn":"tokens/spacing.css"},{"name":"--space-6","value":"2rem","kind":"spacing","definedIn":"tokens/spacing.css"},{"name":"--space-7","value":"3rem","kind":"spacing","definedIn":"tokens/spacing.css"},{"name":"--space-8","value":"4rem","kind":"spacing","definedIn":"tokens/spacing.css"},{"name":"--space-9","value":"6rem","kind":"spacing","definedIn":"tokens/spacing.css"},{"name":"--radius-none","value":"0","kind":"radius","definedIn":"tokens/spacing.css"},{"name":"--radius-xs","value":"2px","kind":"radius","definedIn":"tokens/spacing.css"},{"name":"--radius-sm","value":"3px","kind":"radius","definedIn":"tokens/spacing.css"},{"name":"--radius-md","value":"5px","kind":"radius","definedIn":"tokens/spacing.css"},{"name":"--radius-lg","value":"8px","kind":"radius","definedIn":"tokens/spacing.css"},{"name":"--radius-pill","value":"999px","kind":"radius","definedIn":"tokens/spacing.css"},{"name":"--border-thin","value":"1px","kind":"spacing","definedIn":"tokens/spacing.css"},{"name":"--border-medium","value":"1.5px","kind":"spacing","definedIn":"tokens/spacing.css"},{"name":"--border-thick","value":"2px","kind":"spacing","definedIn":"tokens/spacing.css"},{"name":"--shadow-xs","value":"0 1px 0 rgba(30, 37, 51, 0.06)","kind":"shadow","definedIn":"tokens/spacing.css"},{"name":"--shadow-sm","value":"0 1px 2px rgba(30, 37, 51, 0.10)","kind":"shadow","definedIn":"tokens/spacing.css"},{"name":"--shadow-md","value":"0 2px 6px rgba(30, 37, 51, 0.12), 0 1px 0 rgba(30, 37, 51, 0.04)","kind":"shadow","definedIn":"tokens/spacing.css"},{"name":"--shadow-lg","value":"0 8px 24px rgba(30, 37, 51, 0.16)","kind":"shadow","definedIn":"tokens/spacing.css"},{"name":"--shadow-inset","value":"inset 0 1px 2px rgba(30, 37, 51, 0.10)","kind":"shadow","definedIn":"tokens/spacing.css"},{"name":"--tick-pitch","value":"8px","kind":"spacing","definedIn":"tokens/spacing.css"},{"name":"--tick-h-major","value":"14px","kind":"spacing","definedIn":"tokens/spacing.css"},{"name":"--tick-h-minor","value":"calc(var(--tick-h-major) / 2)","kind":"color","definedIn":"tokens/spacing.css"},{"name":"--tick-gradient","value":"repeating-linear-gradient(90deg, var(--rule-tick) 0 1px, transparent 1px var(--tick-pitch))\n 0 50% / 100% var(--tick-h-minor) repeat-x,\n repeating-linear-gradient(90deg, var(--rule-tick) 0 1px, transparent 1px calc(var(--tick-pitch) * 5))\n 0 50% / 100% var(--tick-h-major) repeat-x","kind":"color","definedIn":"tokens/spacing.css"},{"name":"--ease-slide","value":"cubic-bezier(0.3, 0.0, 0.2, 1)","kind":"other","definedIn":"tokens/spacing.css","annotation":"other"},{"name":"--ease-out","value":"cubic-bezier(0.2, 0.0, 0.0, 1)","kind":"other","definedIn":"tokens/spacing.css","annotation":"other"},{"name":"--dur-fast","value":"120ms","kind":"other","definedIn":"tokens/spacing.css","annotation":"other"},{"name":"--dur-base","value":"200ms","kind":"other","definedIn":"tokens/spacing.css","annotation":"other"},{"name":"--dur-slow","value":"320ms","kind":"other","definedIn":"tokens/spacing.css","annotation":"other"},{"name":"--container-prose","value":"720px","kind":"spacing","definedIn":"tokens/spacing.css"},{"name":"--container-wide","value":"1140px","kind":"spacing","definedIn":"tokens/spacing.css"},{"name":"--sidebar-width","value":"264px","kind":"spacing","definedIn":"tokens/spacing.css"}],"themes":[],"fonts":[],"brandFonts":[{"family":"Saira Condensed","status":"ok","tokens":["--font-primary"],"path":"tokens/typography.css"},{"family":"IBM Plex Mono","status":"ok","tokens":["--font-mono"],"path":"tokens/typography.css"}],"source":"spa"}
\ No newline at end of file diff --git a/_ds/pantograph-design-system-56a1c74e-41c1-486b-ba3c-4eabdfacef31/readme.md b/_ds/pantograph-design-system-56a1c74e-41c1-486b-ba3c-4eabdfacef31/readme.md new file mode 100644 index 0000000..8ea0b0e --- /dev/null +++ b/_ds/pantograph-design-system-56a1c74e-41c1-486b-ba3c-4eabdfacef31/readme.md @@ -0,0 +1,144 @@ +# Pantograph Design System + +The design system for **pantograph** — an open-source project comprising: + +- **libpanto** — an LLM provider SDK, imported as `panto` in each language. It gives one provider-agnostic call signature, faithfully reproduced across its (currently three, "and counting") language bindings: **Python, Rust, TypeScript**. +- **panto** — a terminal coding agent built on top of libpanto. A minimal system prompt and a small, swappable tool set. libpanto and the panto CLI are written in **Zig** (native binaries — maximally fast and resource-efficient); the CLI embeds a **Lua** interpreter for extensions (about as fast as a dynamic scripting language gets). + +This system dresses the project's **web resources**: the libpanto SDK reference docs and the panto CLI docs, plus the marketing homepage. + +> **The metaphor.** A *pantograph* is an old drafting instrument: a linkage of hinged arms that reproduces a small drawing at a larger scale. One small motion in, one faithful enlargement out. That is exactly what libpanto does for language models — write the motion once, scale it to any provider. + +> **The reference object.** The visual language is taken from a **1970s Post Versalog slide rule**: an eggshell, bamboo-bodied precision instrument printed in black, red, and green. So: **no pure white and no pure black** anywhere — warm eggshell "paper" surfaces, deep blue-black "ink" marks, and two engraved accents (instrument red, instrument green). + +--- + +## Sources + +This is a **greenfield** system — no codebase, Figma file, or prior brand was supplied. Everything here is derived from the written brief (the pantograph concept + the Post Versalog slide rule as a physical reference). If a repository or design file exists, link it here so future work can cross-reference: + +- Repository: _(none provided — add the GitHub URL here)_ +- Design file: _(none provided)_ +- Reference object: Post Versalog slide rule (c. 1970s), eggshell over bamboo, black/red/green markings. + +--- + +## CONTENT FUNDAMENTALS + +How pantograph writes. The voice is that of a **well-made instrument manual**: plainspoken, precise, and quietly confident. It never oversells. The throughline is **minimalism** — pantograph is light, straightforward, and fast. *Everything you specify, nothing you don't.* + +- **Tone:** Calm, technical, exact. We describe what the tool *does*, in the order it does it. The pantograph metaphor is used sparingly and only when it clarifies ("write the motion once, scale it to any provider") — never as decoration. +- **Lead with minimalism, not magic.** The product is small on purpose: a minimal system prompt, a small tool set, swap any of it out. It is fast and lean because it is written in Zig (native binaries) and extended in Lua. Say *what isn't there* as a feature. +- **Don't claim gates it doesn't have.** panto has **no permission prompts** — that would be more, not less. So avoid "waits for yes / waits for approval." And avoid "install with one line" as a headline; the story is restraint, not convenience tricks. +- **Person:** Address the reader as **you**; the project refers to itself by name (**panto**, **libpanto**, **pantograph**) or as **we** in prose. Avoid "I". +- **Casing:** The product names are **always lowercase** in body and wordmark: `pantograph`, `panto`, `libpanto`. Sentence case for headings and UI ("Same call, every language"). Engraved labels/eyebrows are **UPPERCASE** with wide tracking (the slide-rule scale-label voice): `SDK REFERENCE`, `GETTING STARTED`. +- **Commands read like commands.** CLI examples use the imperative, lowercase, quoted: `panto run "add rate limiting to the login route"`. +- **Numbers & specifics over adjectives.** "Returns a typed Response — text, usage, stop reason" beats "powerful, flexible responses". Cite versions (`since v2.0`), diffs (`+24 −3`), counts ("3 and counting"). +- **No hype, no emoji.** Never "🚀 unlock the power of next-gen AI". Emoji are **not** used in the brand. (See `guidelines/brand-voice.card.html` for the say/don't-say pairs.) +- **Status is stated, not implied:** `Stable`, `Beta`, `Deprecated`, `since v2.0`, `removed in v3`. + +**Specimen copy** +- Headline: *"Scale one prompt to every provider."* +- Lead: *"libpanto is a single, small set of motions — faithfully reproduced across OpenAI, Anthropic, and your local models."* +- Positioning line: *"Everything you specify, nothing you don't."* +- Callout: *"A minimal prompt and tool set — swap any piece for your own. Written in Zig, extended in Lua."* + +--- + +## VISUAL FOUNDATIONS + +The whole system is an eggshell instrument printed in ink. Restraint is the point. + +### Color +- **Two ramps, two accents, nothing else.** Warm **paper** (eggshell, `#F6F0E2 → #BFAE8A`) for surfaces; deep blue-black **ink** (`#161B27 → #8C8470`) for marks. The darkest ink is a *blue*-black, never `#000`; the lightest paper is eggshell, never `#fff`. +- **Instrument red** (`#B23A2E`) = the cursor line, danger, and the single primary accent. **Instrument green** (`#2F6B4A`) = success, the "folded" scales, focus rings. Used like a draftsman: *sparingly, for meaning, never as fields.* A page should read black-on-eggshell with red/green appearing only at points of emphasis. +- **Brass** (`#9A7B3F`) is a rare hardware accent (the cursor slide, warning admonitions). +- Tokens in `tokens/colors.css`; always reference the **semantic aliases** (`--surface-card`, `--text-body`, `--accent`, `--status-*`) rather than the raw ramp. + +### Type +Two voices — minimal, like the product (see `tokens/typography.css`): +- **Saira Condensed** — **THE primary face**, used everywhere: display headlines, headings, UI, buttons, tables, body, long-form prose, eyebrows, and scale numerals. Tall and narrow with engraved-instrument character; it carries running body copy as well as display. Set in caps with `0.14em` tracking for labels. The `--font-display`, `--font-sans`, and `--font-serif` tokens all alias the primary face, so role tokens and existing components keep working. +- **IBM Plex Mono** — code, terminals, the CLI, tags, tabular numerals — the machine voice. +- Scale is a 1.250 major third rooted at 16px (`--text-xs … --text-5xl`). + +### Backgrounds & texture +- Flat eggshell paper — **no photographic backgrounds, no gradients as fields, no glassmorphism.** The one recurring graphic device is the **engraved tick rule** (`--tick-gradient`, `.panto-tick-rule`) — the **standard separator between sections**: short ticks every `--tick-pitch` (8px) with **every 5th tick at double height**, all centered on a common axis. The homepage hero also carries a slide-rule **ruler strip**: a literal printed scale. +- The terminal is the **only** dark surface in the system — the one place ink becomes a background. + +### Shape, borders, radius +- **Machined, minimal corners.** `--radius-xs:2px` (inputs), `sm:3px` (buttons/badges), `md:5px` (cards), `lg:8px` (dialogs). `pill` is reserved for tags and the switch, used deliberately. +- **Hairline rules** (`--border-hairline`) divide; **engraved top rules** (a thick ink or red bar on a `ruled` Card) mark importance. Borders are warm paper/ink tones, never cool gray. + +### Shadow +- Warm, low, **ink-tinted** (never neutral or blue): `--shadow-xs … --shadow-lg`, plus `--shadow-inset` for sunken fields. Like an object resting on a drafting table. Cards sit on a shallow `sm`; they lift to `md` on hover. + +### Cards +- Raised eggshell (`--surface-card`, lighter than the page), hairline border, `--radius-md`, shallow shadow. `sunken` variant inverts to an inset secondary surface. `ruled` adds the engraved top scale-rule (ink, or red for `accent`). + +### Motion +- **Mechanical, precise, no bounce** — like a sliding cursor. `--ease-slide` / `--ease-out`; durations `120 / 200 / 320ms`. Tabs slide their red underline; switches glide; buttons press *down 1px* with the shadow collapsing. The terminal cursor blinks (respecting `prefers-reduced-motion`). No floaty fades, no spring overshoot. + +### States +- **Hover:** darker fill (primary → `ink-0`), or a paper-2 wash for low-emphasis controls; links shift red and underline. +- **Press:** `translateY(1px)` with shadow removed. +- **Focus:** a 2px **instrument-green** outline (`--focus-ring`) at 2px offset, or a green ring + tinted glow on inputs. +- **Invalid:** instrument red border + red wash glow. +- **Disabled:** ~45% opacity, no shadow, `not-allowed`. + +### Layout +- Reading column `--container-prose: 720px`; app/marketing `--container-wide: 1140px`; docs sidebar `264px`. Sticky header + sticky sidebar/TOC; content stays in a measured column. Generous vertical rhythm on the 4px grid. + +### Transparency & blur +- Used **once**: the sticky docs header is `color-mix` paper at ~88% with an 8px backdrop blur, so content scrolls under it. Otherwise surfaces are opaque. + +--- + +## ICONOGRAPHY + +- **System set: [Lucide](https://lucide.dev)** — clean line icons, 2px stroke, 24px grid, rounded caps and joins. Their precision and uniform weight suit a drafting instrument. + - **Substitution flag:** because this is greenfield with no supplied icon assets, Lucide is a *chosen* set, not a recreation of an existing one. The UI kits inline a curated subset of Lucide-derived paths in `Icons.jsx` (Lucide is ISC-licensed). If the project later ships its own icons, replace `Icons.jsx` and document here. +- **Icons inherit `currentColor`** and ride the ink ramp; they pick up red/green only inside an accented context (feature tiles, active states). +- **The logo mark is the one bespoke glyph** (`assets/logo-mark.svg`): a pantograph parallelogram linkage — anchored fulcrum, dashed scaling axis, **red pen tip**. `logo-mark-mono.svg` is the single-color variant. Arms inherit `currentColor`. +- **No emoji.** No decorative illustration. No multi-color icons. Status uses the engraved `Badge`, not an icon. + +--- + +## INDEX — what's in this system + +**Foundations / global CSS** +- `styles.css` — entry point (consumers link this one file); `@import`s only. +- `tokens/fonts.css` — webfonts (Google Fonts; see substitution note below). +- `tokens/colors.css` · `tokens/typography.css` · `tokens/spacing.css` — the token ramps + semantic aliases. +- `tokens/base.css` — base element styling + helpers (`.panto-prose`, `.panto-eyebrow`, `.panto-tick-rule`). + +**Specimen cards** (Design System tab) — in `guidelines/` +- Colors: paper, ink, accents, status & surfaces. +- Type: display, sans, prose, mono, scale, eyebrow. +- Spacing: scale, radius, shadows, borders & ticks. +- Brand: logo, logo variants, voice & tone. + +**Components** — in `components/` (React, reference tokens via CSS vars) +- `core/` — **Button, IconButton, Badge, Tag, Card** +- `forms/` — **Input, Select, Switch** +- `navigation/` — **Tabs** (underline + pill) +- `code/` — **CodeBlock, Terminal, Callout** + +Each directory has `<Name>.jsx` + `<Name>.d.ts` + `<Name>.prompt.md` and one `@dsCard` showcase HTML. + +**UI kits** — in `ui_kits/` +- `docs/` — the **libpanto SDK reference site** (header, nav tree, language-switching reference page, TOC). +- `home/` — the **pantograph project homepage** (hero + live terminal, install switcher, feature grid, footer). + +**Brand assets** — in `assets/` +- `logo-mark.svg` (red pen tip) · `logo-mark-mono.svg` (single color). + +**Other** +- `SKILL.md` — makes this folder usable as a downloadable Agent Skill. + +--- + +## Font note — self-host when ready + +Both typefaces load from **Google Fonts** via `@import` in `tokens/fonts.css` (so the compiler reports **0 `@font-face` rules** — fonts come from Google's network CSS, not self-hosted binaries). The system deliberately runs on just two: **Saira Condensed** (the single primary face) and **IBM Plex Mono**. + +If you want self-hosted fonts (offline, no Google dependency) or have specific licensed faces in mind, send the font files and I'll wire real `@font-face` rules. The mono could become JetBrains Mono or Berkeley Mono; if Saira Condensed ever feels too narrow for long-form docs, a slightly wider engineering gothic is the natural fallback — but the brief is one primary face, used everywhere. diff --git a/_ds/pantograph-design-system-56a1c74e-41c1-486b-ba3c-4eabdfacef31/styles.css b/_ds/pantograph-design-system-56a1c74e-41c1-486b-ba3c-4eabdfacef31/styles.css new file mode 100644 index 0000000..c6b7224 --- /dev/null +++ b/_ds/pantograph-design-system-56a1c74e-41c1-486b-ba3c-4eabdfacef31/styles.css @@ -0,0 +1,13 @@ +/* ============================================================ + Pantograph Design System — global entry point + ------------------------------------------------------------ + Consumers link THIS one file. It is a manifest of @imports + only — no rules live here. Everything reachable from here is + shipped to consuming projects. + ============================================================ */ + +@import url('tokens/fonts.css'); +@import url('tokens/colors.css'); +@import url('tokens/typography.css'); +@import url('tokens/spacing.css'); +@import url('tokens/base.css'); diff --git a/_ds/pantograph-design-system-56a1c74e-41c1-486b-ba3c-4eabdfacef31/tokens/base.css b/_ds/pantograph-design-system-56a1c74e-41c1-486b-ba3c-4eabdfacef31/tokens/base.css new file mode 100644 index 0000000..6b8272a --- /dev/null +++ b/_ds/pantograph-design-system-56a1c74e-41c1-486b-ba3c-4eabdfacef31/tokens/base.css @@ -0,0 +1,113 @@ +/* ============================================================ + Pantograph — base element styling + ------------------------------------------------------------ + A light, opinionated reset that binds the tokens to real + elements. Optional for consumers, but every specimen card, + component card, and UI kit in this system assumes it. + ============================================================ */ + +*, *::before, *::after { box-sizing: border-box; } + +html { -webkit-text-size-adjust: 100%; } + +body { + margin: 0; + background-color: var(--surface-page); + color: var(--text-body); + font: var(--role-body); + letter-spacing: var(--tracking-normal); + -webkit-font-smoothing: antialiased; + text-rendering: optimizeLegibility; +} + +/* Headings default to the engraved display voice */ +h1, h2, h3, h4, h5, h6 { + margin: 0 0 var(--space-3); + color: var(--text-strong); + font-family: var(--font-sans); + font-weight: var(--weight-semibold); + line-height: var(--leading-snug); + letter-spacing: var(--tracking-tight); + text-wrap: balance; +} +h1 { font: var(--role-h1); letter-spacing: var(--tracking-tight); } +h2 { font: var(--role-h2); } +h3 { font: var(--role-h3); } + +p { margin: 0 0 var(--space-4); text-wrap: pretty; } + +a { + color: var(--link); + text-decoration: none; + text-underline-offset: 0.18em; + text-decoration-thickness: 1px; + transition: color var(--dur-fast) var(--ease-out); +} +a:hover { color: var(--link-hover); text-decoration: underline; } + +strong, b { font-weight: var(--weight-semibold); color: var(--text-strong); } + +code, kbd, samp, pre { + font-family: var(--font-mono); + font-size: 0.92em; +} + +code { + background: var(--surface-code); + border: var(--border-thin) solid var(--border-hairline); + border-radius: var(--radius-xs); + padding: 0.08em 0.36em; + color: var(--ink-1); +} + +pre { + font-size: var(--text-sm); + line-height: var(--leading-mono); + margin: 0; +} +pre code { background: none; border: none; padding: 0; } + +hr { + border: 0; + height: 1px; + background: var(--border-hairline); + margin: var(--space-6) 0; +} + +/* The engraved-tick rule: THE standard section separator. + Short ticks with every 5th at double height (see + --tick-gradient in tokens/spacing.css). Height = the tall + tick; short ticks center on the same axis. */ +.panto-tick-rule { + border: 0; + height: var(--tick-h-major); + background: var(--tick-gradient); + opacity: 0.85; + margin: var(--space-6) 0; +} + +::selection { background: var(--green-soft); color: var(--ink-0); } + +:focus-visible { + outline: var(--border-thick) solid var(--focus-ring); + outline-offset: 2px; +} + +/* Long-form documentation prose — the primary face, set larger + and looser for comfortable reading */ +.panto-prose { + font: var(--role-prose); + color: var(--text-body); + max-width: var(--container-prose); +} +.panto-prose p { margin-bottom: var(--space-5); } + +/* Engraved eyebrow / kicker label */ +.panto-eyebrow { + font-family: var(--font-display); + font-weight: var(--weight-semibold); + font-size: var(--text-xs); + letter-spacing: var(--tracking-label); + text-transform: uppercase; + color: var(--text-faint); +} diff --git a/_ds/pantograph-design-system-56a1c74e-41c1-486b-ba3c-4eabdfacef31/tokens/colors.css b/_ds/pantograph-design-system-56a1c74e-41c1-486b-ba3c-4eabdfacef31/tokens/colors.css new file mode 100644 index 0000000..7fef466 --- /dev/null +++ b/_ds/pantograph-design-system-56a1c74e-41c1-486b-ba3c-4eabdfacef31/tokens/colors.css @@ -0,0 +1,87 @@ +/* ============================================================ + Pantograph — Color tokens + ------------------------------------------------------------ + Inspired by a 1970s Post Versalog slide rule: an eggshell + bamboo body printed in black, red, and green. There is NO + pure white and NO pure black anywhere in the system. + + Base ramp = warm "paper" (eggshell) surfaces and "ink" + (deep blue-black) marks. Two engraved accents: instrument + red and instrument green. Use accents like a draftsman — + sparingly, for emphasis and meaning, never as fields. + ============================================================ */ + +:root { + /* --- Paper (near-white surfaces, faint warm tint, lightest → deepest) --- */ + --paper-0: #FCFAF5; /* raised cards, popovers, code surfaces */ + --paper-1: #F8F4EB; /* default page background */ + --paper-2: #EFE9DC; /* sunken / secondary fields, table stripes */ + --paper-3: #DFD7C6; /* hairline rules, dividers, engraved ticks */ + --paper-4: #C7BCA4; /* strong borders, disabled fills */ + + /* --- Ink (deep blue-black marks, darkest → lightest) --- */ + --ink-0: #161B27; /* near-black blue ink: max-contrast headings */ + --ink-1: #1E2533; /* primary body text, the default mark color */ + --ink-2: #3B4456; /* secondary text, captions */ + --ink-3: #6E6B5C; /* muted / warm-gray metadata */ + --ink-4: #8C8470; /* faint hints, placeholder text */ + + /* --- Instrument Red (cursor line, warnings, the C/D scale) --- */ + --red-deep: #8F2B22; + --red: #B23A2E; /* the canonical slide-rule red */ + --red-soft: #E7C3BB; /* tinted backgrounds */ + --red-wash: #EBD9D0; /* faintest red wash on paper */ + + /* --- Instrument Green (folded scales, success, positive) --- */ + --green-deep: #245138; + --green: #2F6B4A; /* the canonical slide-rule green */ + --green-soft: #BCD2BF; /* tinted backgrounds */ + --green-wash: #D6DECB; /* faintest green wash on paper */ + + /* --- Brass (the cursor / hardware accent, used very rarely) --- */ + --brass: #9A7B3F; + + /* ============================================================ + Semantic aliases — reference THESE in components, not the + raw ramp above. + ============================================================ */ + + /* Surfaces */ + --surface-page: var(--paper-1); + --surface-card: var(--paper-0); + --surface-sunken: var(--paper-2); + --surface-code: #F4EEE1; /* code blocks: a hair warmer than card */ + --surface-inverse: var(--ink-1); + + /* Text */ + --text-strong: var(--ink-0); + --text-body: var(--ink-1); + --text-muted: var(--ink-2); + --text-faint: var(--ink-3); + --text-placeholder: var(--ink-4); + --text-on-ink: var(--paper-0); + --text-on-accent: var(--paper-0); + + /* Lines */ + --border-hairline: var(--paper-3); + --border-default: var(--paper-4); + --border-strong: var(--ink-3); + --rule-tick: var(--paper-4); + + /* Accents */ + --accent: var(--red); /* primary brand accent */ + --accent-deep: var(--red-deep); + --link: var(--red-deep); + --link-hover: var(--red); + + /* Status */ + --status-danger: var(--red); + --status-danger-bg: var(--red-wash); + --status-success: var(--green); + --status-success-bg:var(--green-wash); + --status-info: var(--ink-2); + --status-info-bg: var(--paper-2); + + /* Focus ring */ + --focus-ring: var(--green); +} diff --git a/_ds/pantograph-design-system-56a1c74e-41c1-486b-ba3c-4eabdfacef31/tokens/fonts.css b/_ds/pantograph-design-system-56a1c74e-41c1-486b-ba3c-4eabdfacef31/tokens/fonts.css new file mode 100644 index 0000000..637c1a1 --- /dev/null +++ b/_ds/pantograph-design-system-56a1c74e-41c1-486b-ba3c-4eabdfacef31/tokens/fonts.css @@ -0,0 +1,19 @@ +/* ============================================================ + Pantograph — Webfonts + ------------------------------------------------------------ + Two families, loaded from Google Fonts. The system runs on a + single primary face plus a monospace — minimal by design, the + way the product is. See readme.md → VISUAL FOUNDATIONS. + + Saira Condensed → THE primary face. Display, headings, UI, + body, labels, prose. Tall, narrow, and + precise — engraved-instrument character. + IBM Plex Mono → code, terminals, the panto CLI, tabular + numerals — the machine voice. + + Saira Condensed loads 400–700 (plus 400/500 italic) so it can + carry running body copy, not just display. @import MUST be the + first statement, before any other rule. + ============================================================ */ + +@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;600&family=Saira+Condensed:ital,wght@0,400;0,500;0,600;0,700;1,400;1,500&display=swap'); diff --git a/_ds/pantograph-design-system-56a1c74e-41c1-486b-ba3c-4eabdfacef31/tokens/spacing.css b/_ds/pantograph-design-system-56a1c74e-41c1-486b-ba3c-4eabdfacef31/tokens/spacing.css new file mode 100644 index 0000000..b06cdc8 --- /dev/null +++ b/_ds/pantograph-design-system-56a1c74e-41c1-486b-ba3c-4eabdfacef31/tokens/spacing.css @@ -0,0 +1,72 @@ +/* ============================================================ + Pantograph — Spacing, radius, borders, shadow, motion + ------------------------------------------------------------ + A slide rule is a precision instrument: spacing is rigid and + gridded (4px base unit), corners are barely rounded (the body + has sharp machined edges), and shadows are shallow and warm, + like an object resting on a drafting table — never glassy + blue drop-shadows. + ============================================================ */ + +:root { + /* Spacing scale (4px base) */ + --space-0: 0; + --space-1: 0.25rem; /* 4px */ + --space-2: 0.5rem; /* 8px */ + --space-3: 0.75rem; /* 12px */ + --space-4: 1rem; /* 16px */ + --space-5: 1.5rem; /* 24px */ + --space-6: 2rem; /* 32px */ + --space-7: 3rem; /* 48px */ + --space-8: 4rem; /* 64px */ + --space-9: 6rem; /* 96px */ + + /* Radius — machined, minimal. Nothing pill-shaped except by intent. */ + --radius-none: 0; + --radius-xs: 2px; /* inputs, code chips */ + --radius-sm: 3px; /* buttons, badges */ + --radius-md: 5px; /* cards, panels */ + --radius-lg: 8px; /* large surfaces, dialogs */ + --radius-pill: 999px; /* tags, switches — use deliberately */ + + /* Border widths */ + --border-thin: 1px; + --border-medium: 1.5px; + --border-thick: 2px; + + /* Shadows — warm, low, like ink/paper on a table. Tinted with + ink, never neutral gray, never blue. Keep them shallow. */ + --shadow-xs: 0 1px 0 rgba(30, 37, 51, 0.06); + --shadow-sm: 0 1px 2px rgba(30, 37, 51, 0.10); + --shadow-md: 0 2px 6px rgba(30, 37, 51, 0.12), 0 1px 0 rgba(30, 37, 51, 0.04); + --shadow-lg: 0 8px 24px rgba(30, 37, 51, 0.16); + --shadow-inset: inset 0 1px 2px rgba(30, 37, 51, 0.10); + + /* Engraved-tick separator: THE standard section break. + A ruled scale — short ticks every --tick-pitch, with every + 5th tick at DOUBLE height, all centered on a common axis. + The short ticks sit 20% shorter than a plain rule would, so + the tall ones stand out without making the whole rule tall. + Drive size with --tick-h-major (= the rule's height); the + short tick is exactly half of it. */ + --tick-pitch: 8px; /* spacing between ticks */ + --tick-h-major: 14px; /* tall (every-5th) tick = rule height */ + --tick-h-minor: calc(var(--tick-h-major) / 2); /* short tick — half the tall one */ + --tick-gradient: + repeating-linear-gradient(90deg, var(--rule-tick) 0 1px, transparent 1px var(--tick-pitch)) + 0 50% / 100% var(--tick-h-minor) repeat-x, + repeating-linear-gradient(90deg, var(--rule-tick) 0 1px, transparent 1px calc(var(--tick-pitch) * 5)) + 0 50% / 100% var(--tick-h-major) repeat-x; + + /* Motion — mechanical, precise, no bounce. Like a sliding cursor. */ + --ease-slide: cubic-bezier(0.3, 0.0, 0.2, 1); /* @kind other */ + --ease-out: cubic-bezier(0.2, 0.0, 0.0, 1); /* @kind other */ + --dur-fast: 120ms; /* @kind other */ + --dur-base: 200ms; /* @kind other */ + --dur-slow: 320ms; /* @kind other */ + + /* Layout */ + --container-prose: 720px; /* documentation reading column */ + --container-wide: 1140px; /* app / marketing max width */ + --sidebar-width: 264px; +} diff --git a/_ds/pantograph-design-system-56a1c74e-41c1-486b-ba3c-4eabdfacef31/tokens/typography.css b/_ds/pantograph-design-system-56a1c74e-41c1-486b-ba3c-4eabdfacef31/tokens/typography.css new file mode 100644 index 0000000..be943df --- /dev/null +++ b/_ds/pantograph-design-system-56a1c74e-41c1-486b-ba3c-4eabdfacef31/tokens/typography.css @@ -0,0 +1,66 @@ +/* ============================================================ + Pantograph — Typography tokens + ------------------------------------------------------------ + Two voices. Minimal, like the product: + • Saira Condensed — THE primary face. Display, headings, + UI, body, prose, eyebrows, scale numerals. Tall and + narrow; reads as engraved instrument lettering. + • IBM Plex Mono — code, terminals, the panto CLI, tabular + numerals, anything "machine". + + --font-sans / --font-serif / --font-display all resolve to + Saira Condensed, so role tokens and existing components keep + working while the system runs on a single primary face. + ============================================================ */ + +:root { + /* Families — one primary face, one mono */ + --font-primary: 'Saira Condensed', 'Arial Narrow', sans-serif; + --font-mono: 'IBM Plex Mono', ui-monospace, 'SF Mono', Menlo, monospace; + + /* Aliases — all point at the primary face (legacy role names) */ + --font-display: var(--font-primary); + --font-sans: var(--font-primary); + --font-serif: var(--font-primary); + + /* Type scale (1.250 major-third, rooted at 16px) */ + --text-2xs: 0.6875rem; /* 11px — tick labels, legal */ + --text-xs: 0.75rem; /* 12px — captions, eyebrows */ + --text-sm: 0.875rem; /* 14px — secondary UI text */ + --text-base: 1rem; /* 16px — body */ + --text-md: 1.125rem; /* 18px — lead paragraph */ + --text-lg: 1.375rem; /* 22px — h4 / card titles */ + --text-xl: 1.75rem; /* 28px — h3 */ + --text-2xl: 2.25rem; /* 36px — h2 */ + --text-3xl: 3rem; /* 48px — h1 */ + --text-4xl: 4rem; /* 64px — display */ + --text-5xl: 5.5rem; /* 88px — hero display */ + + /* Weights */ + --weight-regular: 400; + --weight-medium: 500; + --weight-semibold: 600; + --weight-bold: 700; + + /* Line heights */ + --leading-tight: 1.05; /* display */ + --leading-snug: 1.25; /* headings */ + --leading-normal: 1.5; /* UI / sans body */ + --leading-relaxed: 1.7; /* serif prose */ + --leading-mono: 1.6; /* code */ + + /* Letter spacing */ + --tracking-label: 0.14em; /* ALL-CAPS engraved labels */ + --tracking-tight: -0.01em; /* large display */ + --tracking-normal: 0; + + /* ---- Semantic roles ---- */ + --role-display: var(--weight-bold) var(--text-4xl)/var(--leading-tight) var(--font-display); + --role-h1: var(--weight-bold) var(--text-3xl)/var(--leading-snug) var(--font-display); + --role-h2: var(--weight-semibold) var(--text-2xl)/var(--leading-snug) var(--font-sans); + --role-h3: var(--weight-semibold) var(--text-xl)/var(--leading-snug) var(--font-sans); + --role-body: var(--weight-regular) var(--text-base)/var(--leading-normal) var(--font-sans); + --role-prose: var(--weight-regular) var(--text-md)/var(--leading-relaxed) var(--font-primary); + --role-code: var(--weight-regular) var(--text-sm)/var(--leading-mono) var(--font-mono); + --role-label: var(--weight-semibold) var(--text-xs)/1 var(--font-display); +} |
