@dataimago/ui 0.1.0-alpha.4 → 0.1.0-alpha.43
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +31 -5
- package/dist/index.cjs +1086 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +386 -1
- package/dist/index.d.ts +386 -1
- package/dist/index.js +1066 -1
- package/dist/index.js.map +1 -1
- package/package.json +12 -9
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/Button.tsx","../src/brand/LogoMonogram.tsx","../src/brand/LogoMonogramBg.tsx","../src/brand/LogoWordmark.tsx"],"sourcesContent":["import * as React from 'react';\n\nexport type ButtonVariant = 'primary' | 'secondary' | 'ghost';\nexport type ButtonSize = 'sm' | 'md' | 'lg';\n\nexport interface ButtonProps\n extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n variant?: ButtonVariant;\n size?: ButtonSize;\n}\n\nconst variantClasses: Record<ButtonVariant, string> = {\n primary: 'di-ui-button--primary',\n secondary: 'di-ui-button--secondary',\n ghost: 'di-ui-button--ghost',\n};\n\nconst sizeClasses: Record<ButtonSize, string> = {\n sm: 'di-ui-button--sm',\n md: 'di-ui-button--md',\n lg: 'di-ui-button--lg',\n};\n\nconst baseStyle: React.CSSProperties = {\n alignItems: 'center',\n borderRadius: 'var(--radius-md, 0.5rem)',\n borderStyle: 'solid',\n borderWidth: '1px',\n cursor: 'pointer',\n display: 'inline-flex',\n fontFamily: 'var(--font-family-sans, system-ui, sans-serif)',\n fontWeight: 'var(--font-weight-medium, 500)',\n gap: 'var(--spacing-sm, 0.5rem)',\n justifyContent: 'center',\n textDecoration: 'none',\n transition: 'background-color 150ms ease, border-color 150ms ease, color 150ms ease',\n};\n\nconst variantStyles: Record<ButtonVariant, React.CSSProperties> = {\n primary: {\n backgroundColor: 'var(--color-interactive-primary)',\n borderColor: 'var(--color-interactive-primary)',\n color: 'var(--color-content-inverse)',\n },\n secondary: {\n backgroundColor: 'var(--color-surface-elevated)',\n borderColor: 'var(--color-border-moderate)',\n color: 'var(--color-content-primary)',\n },\n ghost: {\n backgroundColor: 'transparent',\n borderColor: 'transparent',\n color: 'var(--color-content-secondary)',\n },\n};\n\nconst sizeStyles: Record<ButtonSize, React.CSSProperties> = {\n sm: {\n fontSize: 'var(--font-size-small, 0.875rem)',\n minHeight: '2rem',\n padding: '0.375rem 0.75rem',\n },\n md: {\n fontSize: 'var(--font-size-base, 1rem)',\n minHeight: '2.5rem',\n padding: '0.625rem 1rem',\n },\n lg: {\n fontSize: 'var(--font-size-readable, 1.125rem)',\n minHeight: '3rem',\n padding: '0.75rem 1.25rem',\n },\n};\n\n/**\n * Smoke-level `<Button>` for the alpha release of @dataimago/ui.\n *\n * Styling is delegated to semantic CSS variables published by @dataimago/css\n * so that the component stays small and theme-aware.\n * Consumers that want to override visuals can pass their own className.\n */\nexport const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\n function Button(\n { variant = 'primary', size = 'md', className = '', style, type, children, ...rest },\n ref,\n ) {\n const classes = [\n 'di-ui-button',\n variantClasses[variant],\n sizeClasses[size],\n className,\n ]\n .filter(Boolean)\n .join(' ');\n\n return (\n <button\n ref={ref}\n type={type ?? 'button'}\n className={classes}\n style={{\n ...baseStyle,\n ...variantStyles[variant],\n ...sizeStyles[size],\n ...style,\n }}\n {...rest}\n >\n {children}\n </button>\n );\n },\n);\n","import * as React from 'react';\n\n/**\n * <LogoMonogram /> — the dataimago 'a + i' superimposed monogram, transparent\n * background. Glyphs are outlined paths (no font dependency at render time);\n * fill defaults to `currentColor` so the mark inherits from the surrounding\n * text color and respects light/dark theme switches automatically.\n *\n * Symbolism: 'a' (data, agency) superimposed with 'i' (imago, AI) — the\n * fusion is the brand's central idea. See wiki/principles/visual-identity.md\n * (Stage L follow-up) for the full brand-mark rationale.\n *\n * Source artwork: outlined-path SVG from\n * FOUNDATIONS/background/04_dataimago_Content/Design_Assets/logos/\n * ai_monogram_supreme_1_PATH.svg\n *\n * Usage:\n * <LogoMonogram size={48} aria-label=\"dataimago\" />\n * <span style={{ color: 'var(--color-interactive-primary)' }}>\n * <LogoMonogram size={32} />\n * </span>\n */\n\nexport interface LogoMonogramProps extends React.SVGAttributes<SVGSVGElement> {\n /** Render size in px (or any CSS length). Default: 24. Width and height match. */\n size?: number | string;\n /**\n * Accessible name announced by screen readers. Set to `undefined` (or pass\n * `aria-hidden` directly) when the mark is purely decorative.\n */\n title?: string;\n}\n\nexport function LogoMonogram({\n size = 24,\n title = 'dataimago',\n ...rest\n}: LogoMonogramProps) {\n const a11yProps = title ? { role: 'img' as const } : { 'aria-hidden': true as const };\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 480 480\"\n width={size}\n height={size}\n fill=\"currentColor\"\n aria-label={title}\n {...a11yProps}\n {...rest}\n >\n {title ? <title>{title}</title> : null}\n {/* 'i' (imago) glyph */}\n <path d=\"m 337.3457,97.089844 q 0,8.906246 -6.49414,15.400386 -6.49414,6.49415 -15.58594,6.49415 -9.09179,0 -15.77148,-6.67969 Q 293,105.25391 293,96.162109 q 0,-9.091797 6.30859,-15.40039 6.49414,-6.494141 15.40039,-6.494141 9.0918,0 15.77149,6.865234 6.86523,6.679688 6.86523,15.957032 z M 324.54297,180.21484 303.01953,355 h -41.00586 l 21.52344,-174.78516 z\" />\n {/* 'a' (data) glyph */}\n <path d=\"M 325.70312,176.01562 303.04687,360 h -43.16406 l 2.53906,-19.92188 Q 234.6875,364.29687 205,364.29687 q -36.52344,0 -59.57031,-24.80468 -23.04688,-24.80469 -23.04688,-64.25782 0,-45.50781 26.36719,-74.60937 26.75781,-29.10156 68.55469,-29.10156 19.72656,0 33.59375,6.44531 14.0625,6.44531 28.71093,22.26562 l 2.92969,-24.21875 z m -52.53906,86.71875 q 0,-24.41406 -14.0625,-39.64843 -14.0625,-15.42969 -36.32812,-15.42969 -24.21875,0 -40.625,18.94531 -16.40625,19.14063 -16.40625,46.875 0,24.21875 13.67187,39.64844 13.67188,15.42969 35.15625,15.42969 23.82813,0 41.21094,-19.33594 17.38281,-19.72656 17.38281,-46.48438 z\" />\n </svg>\n );\n}\n","import * as React from 'react';\n\n/**\n * <LogoMonogramBg /> — the dataimago 'a + i' monogram with a rounded accent\n * backplate. White letters on the brand-accent role\n * (var(--color-interactive-accent), iteration-2 sky-blue).\n *\n * Use this variant on neutral surfaces where the no-background monogram\n * would lack presence — favicons, app icons, social-media avatars, or any\n * branded chrome where the mark should read as a self-contained badge.\n *\n * Source artwork: outlined-path SVG from\n * FOUNDATIONS/background/04_dataimago_Content/Design_Assets/logos/\n * ai_monogram_supreme_bg_1_PATH.svg\n *\n * Theming: the background uses var(--color-interactive-accent), which\n * resolves via theme-colors.json's mode-aware role mapping — accent-500\n * (#1f618d) on light surfaces, accent-300 (#3498DB) on dark. The letter\n * fill is hard-set to white; both accent stops have AA-or-better contrast\n * with white letters (light-mode 6.66:1 AA, dark-mode 3.15:1 AA-large for\n * the dot-and-stem heading-size letters used in the monogram). The\n * literal-fallback in this component is light-mode (#1f618d, sky-blue\n * iteration-2) for rare non-CSS-aware contexts. Iteration-1's copper-red\n * fallback (#b54a27) was retired in iteration-2-B.2; see\n * wiki/decisions/iteration-2-blue-accent.md for the rationale.\n *\n * Usage:\n * <LogoMonogramBg size={64} aria-label=\"dataimago\" />\n */\n\nexport interface LogoMonogramBgProps extends React.SVGAttributes<SVGSVGElement> {\n /** Render size in px. Default: 32 (favicon-sized). Width and height match. */\n size?: number | string;\n /** Accessible name. Set undefined or pass aria-hidden for decorative use. */\n title?: string;\n}\n\nexport function LogoMonogramBg({\n size = 32,\n title = 'dataimago',\n ...rest\n}: LogoMonogramBgProps) {\n const a11yProps = title ? { role: 'img' as const } : { 'aria-hidden': true as const };\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 480 480\"\n width={size}\n height={size}\n aria-label={title}\n {...a11yProps}\n {...rest}\n >\n {title ? <title>{title}</title> : null}\n {/* Rounded accent backplate — themed via --color-interactive-accent\n (mode-aware: accent-500 #1f618d on light, accent-300 #3498DB on dark).\n Literal fallback is the light-mode canonical for non-CSS consumers. */}\n <rect\n width=\"100%\"\n height=\"100%\"\n rx=\"40\"\n ry=\"40\"\n fill=\"var(--color-interactive-accent, #1f618d)\"\n />\n {/* 'a' (data) glyph in white */}\n <path\n fill=\"#ffffff\"\n d=\"M 325.70312,176.01562 303.04687,360 h -43.16406 l 2.53906,-19.92188 Q 234.6875,364.29687 205,364.29687 q -36.52344,0 -59.57031,-24.80468 -23.04688,-24.80469 -23.04688,-64.25782 0,-45.50781 26.36719,-74.60937 26.75781,-29.10156 68.55469,-29.10156 19.72656,0 33.59375,6.44531 14.0625,6.44531 28.71093,22.26562 l 2.92969,-24.21875 z m -52.53906,86.71875 q 0,-24.41406 -14.0625,-39.64843 -14.0625,-15.42969 -36.32812,-15.42969 -24.21875,0 -40.625,18.94531 -16.40625,19.14063 -16.40625,46.875 0,24.21875 13.67187,39.64844 13.67188,15.42969 35.15625,15.42969 23.82813,0 41.21094,-19.33594 17.38281,-19.72656 17.38281,-46.48438 z\"\n />\n {/* 'i' (imago) glyph in white */}\n <path\n fill=\"#ffffff\"\n d=\"m 337.3457,97.089844 q 0,8.906246 -6.49414,15.400386 -6.49414,6.49415 -15.58594,6.49415 -9.09179,0 -15.77148,-6.67969 Q 293,105.25391 293,96.162109 q 0,-9.091797 6.30859,-15.40039 6.49414,-6.494141 15.40039,-6.494141 9.0918,0 15.77149,6.865234 6.86523,6.679688 6.86523,15.957032 z M 324.54297,180.21484 303.01953,355 h -41.00586 l 21.52344,-174.78516 z\"\n />\n </svg>\n );\n}\n","import * as React from 'react';\n\n/**\n * <LogoWordmark /> — the full \"dataimago\" wordmark with the 'ai' overlap.\n * White letters on a rounded accent backplate, themed via\n * var(--color-interactive-accent).\n *\n * Use this variant for primary brand surfaces: site headers, document\n * letterheads, large-format presentations, business materials. For compact\n * contexts (favicons, social avatars) use <LogoMonogramBg /> instead; for\n * inline use within prose use <LogoMonogram /> with currentColor.\n *\n * The wordmark preserves the philosophical idea of the brand: the visible\n * superposition of 'a' (data, human agency) and 'i' (imago, AI) creates a new\n * unified glyph that is neither pure human nor pure artificial — genuine\n * collaboration. See wiki/principles/visual-identity.md (Stage L follow-up).\n *\n * Source artwork: outlined-path SVG from\n * FOUNDATIONS/background/04_dataimago_Content/Design_Assets/logos/\n * dataimago_supreme_1_PATH.svg\n *\n * Theming: the backplate uses var(--color-interactive-accent), which resolves\n * via theme-colors.json's mode-aware role mapping — accent-500 (#1f618d) on\n * light surfaces, accent-300 (#3498DB) on dark. The literal-fallback in this\n * component is light-mode (#1f618d, sky-blue iteration-2) for the rare cases\n * where the SVG is consumed without CSS-variable resolution (printed PDFs from\n * raw SVG, third-party platforms that strip CSS). Iteration-1's copper-red\n * fallback (#b54a27) was retired in iteration-2-B.2; see\n * wiki/decisions/iteration-2-blue-accent.md for the rationale.\n *\n * Usage:\n * <LogoWordmark width={240} aria-label=\"dataimago\" />\n *\n * The wordmark's natural aspect ratio is 480x150 (~3.2:1). Pass `width` and\n * height auto-scales, or pass both explicitly.\n */\n\nexport interface LogoWordmarkProps extends React.SVGAttributes<SVGSVGElement> {\n /** Width in px. Default: 240. Height auto-scales to the 480:150 ratio. */\n width?: number | string;\n /** Accessible name. Set undefined or pass aria-hidden for decorative use. */\n title?: string;\n}\n\nexport function LogoWordmark({\n width = 240,\n title = 'dataimago',\n ...rest\n}: LogoWordmarkProps) {\n const a11yProps = title ? { role: 'img' as const } : { 'aria-hidden': true as const };\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 480 150\"\n width={width}\n aria-label={title}\n {...a11yProps}\n {...rest}\n >\n {title ? <title>{title}</title> : null}\n {/* Rounded accent backplate — themed via --color-interactive-accent\n (mode-aware: accent-500 #1f618d on light, accent-300 #3498DB on dark).\n Literal fallback is the light-mode canonical for non-CSS consumers. */}\n <rect\n width=\"100%\"\n height=\"100%\"\n rx=\"5\"\n ry=\"5\"\n fill=\"var(--color-interactive-accent, #1f618d)\"\n />\n {/* \"data\" — outlined glyphs, white fill */}\n <path\n fill=\"#ffffff\"\n d=\"M 104.80469,35.621094 97.492187,95 h -7.734375 l 0.421875,-3.550781 q -2.882812,2.566406 -4.992187,3.480468 -2.074219,0.84375 -5.132813,0.84375 -6.960937,0 -11.390625,-4.605468 -4.429687,-4.640625 -4.429687,-11.953125 0,-7.804688 4.851562,-12.972657 4.851563,-5.167968 12.199219,-5.167968 3.761719,0 6.328125,1.300781 2.671875,1.335937 5.589844,4.535156 L 97.035156,35.621094 Z M 92.007812,77 q 0,-4.21875 -2.601562,-6.820313 -2.601563,-2.601562 -6.820313,-2.601562 -4.570312,0 -7.558593,3.410156 -2.988282,3.410156 -2.988282,8.613281 0,4.394532 2.566407,7.066407 2.566406,2.636718 6.820312,2.636718 4.429688,0 7.488281,-3.585937 Q 92.007812,82.203125 92.007812,77 Z M 145.51562,61.882812 141.4375,95 h -7.76953 l 0.45703,-3.585938 q -4.99219,4.359375 -10.33594,4.359375 -6.57422,0 -10.72265,-4.464843 -4.14844,-4.464844 -4.14844,-11.566407 0,-8.191406 4.74609,-13.429687 4.81641,-5.238281 12.33985,-5.238281 3.55078,0 6.04687,1.160156 2.53125,1.160156 5.16797,4.007812 l 0.52734,-4.359375 z m -9.45703,15.609375 q 0,-4.394531 -2.53125,-7.136718 -2.53125,-2.777344 -6.53906,-2.777344 -4.35937,0 -7.3125,3.410156 -2.95312,3.445313 -2.95312,8.4375 0,4.359375 2.46093,7.136719 2.46094,2.777344 6.32813,2.777344 4.28906,0 7.41797,-3.480469 3.1289,-3.550781 3.1289,-8.367188 z M 163.79687,69.089844 160.59766,95 h -7.76954 l 3.19922,-25.910156 h -4.39453 l 0.87891,-7.207032 h 4.39453 l 1.89844,-15.363281 h 7.76953 l -1.89844,15.363281 h 7.17188 l -0.87891,7.207032 z M 211.29297,61.882812 207.21484,95 h -7.76953 l 0.45703,-3.585938 q -4.99218,4.359375 -10.33593,4.359375 -6.57422,0 -10.72266,-4.464843 -4.14844,-4.464844 -4.14844,-11.566407 0,-8.191406 4.7461,-13.429687 4.8164,-5.238281 12.33984,-5.238281 3.55078,0 6.04687,1.160156 2.53125,1.160156 5.16797,4.007812 l 0.52735,-4.359375 z m -9.45703,15.609375 q 0,-4.394531 -2.53125,-7.136718 -2.53125,-2.777344 -6.53907,-2.777344 -4.35937,0 -7.3125,3.410156 -2.95312,3.445313 -2.95312,8.4375 0,4.359375 2.46094,7.136719 2.46093,2.777344 6.32812,2.777344 4.28906,0 7.41797,-3.480469 3.12891,-3.550781 3.12891,-8.367188 z\"\n />\n {/* \"imago\" — outlined glyphs, white fill, superimposed at the 'a/i' overlap */}\n <path\n fill=\"#ffffff\"\n d=\"m 213.40234,46.132812 q 0,1.6875 -1.23047,2.917969 -1.23046,1.230469 -2.95312,1.230469 -1.72266,0 -2.98828,-1.265625 Q 205,47.679687 205,45.957031 q 0,-1.722656 1.19531,-2.917969 1.23047,-1.230468 2.91797,-1.230468 1.72266,0 2.98828,1.300781 1.30078,1.265625 1.30078,3.023437 z m -2.42578,15.75 L 206.89844,95 h -7.76953 l 4.07812,-33.117188 z m 18.87891,0 -0.35156,3.09375 q 3.9375,-3.9375 9.10546,-3.9375 3.12891,0 4.81641,1.160157 1.6875,1.089843 3.02344,4.113281 4.92187,-5.238281 10.61719,-5.238281 9.84375,0 9.84375,9.035156 0,0.914062 -0.17579,2.566406 -0.14062,1.652344 -0.42187,4.078125 L 264.0625,95 h -7.76953 l 2.39062,-19.160156 Q 259,73.167969 259,71.902344 q 0,-4.324219 -4.35938,-4.324219 -1.72265,0 -2.98828,0.527344 -1.26562,0.492187 -2.17968,1.582031 -0.87891,1.054687 -1.47657,2.777344 -0.5625,1.6875 -0.8789,4.042968 L 244.86719,95 h -7.76953 l 2.42578,-19.652344 q 0.3164,-2.671875 0.3164,-3.65625 0,-4.113281 -4.46484,-4.113281 -6.46875,0 -7.55859,8.964844 L 225.53125,95 h -7.76953 l 4.07812,-33.117188 z m 81.63281,0 L 307.41016,95 h -7.76954 l 0.45704,-3.585938 q -4.99219,4.359375 -10.33594,4.359375 -6.57422,0 -10.72266,-4.464843 -4.14844,-4.464844 -4.14844,-11.566407 0,-8.191406 4.7461,-13.429687 4.8164,-5.238281 12.33984,-5.238281 3.55078,0 6.04688,1.160156 2.53125,1.160156 5.16797,4.007812 l 0.52734,-4.359375 z m -9.45703,15.609375 q 0,-4.394531 -2.53125,-7.136718 -2.53125,-2.777344 -6.53906,-2.777344 -4.35938,0 -7.3125,3.410156 -2.95313,3.445313 -2.95313,8.4375 0,4.359375 2.46094,7.136719 2.46094,2.777344 6.32812,2.777344 4.28907,0 7.41797,-3.480469 3.12891,-3.550781 3.12891,-8.367188 z m 53.57812,-15.609375 -4.07812,33.363282 q -0.38672,2.988281 -0.87891,5.203126 -0.45703,2.21484 -1.05468,3.72656 -1.23047,3.09375 -3.65625,5.3086 -4.71094,4.21875 -12.23438,4.21875 -7.76953,0 -12.58594,-4.07813 -2.46093,-2.03906 -3.44531,-4.64062 -0.98437,-2.39063 -0.98437,-6.714849 h 7.52343 q 0.28125,4.675779 2.39063,6.785159 2.10937,2.14453 6.53906,2.14453 4.78125,0 7.27734,-2.56641 2.4961,-2.53125 3.16407,-8.085935 l 0.5625,-4.535156 q -4.92188,3.761718 -10.33594,3.761718 -6.75,0 -11.14453,-4.605468 -4.39453,-4.710938 -4.39453,-11.742188 0,-7.910156 5.09765,-13.113281 5.13282,-5.238281 12.83203,-5.238281 3.69141,0 5.97657,1.089843 2.49609,1.054688 5.16797,3.832032 l 0.49218,-4.113282 z m -8.92968,15.714844 q 0,-4.5 -2.74219,-7.242187 -2.74219,-2.777344 -7.17188,-2.777344 -4.60546,0 -7.66406,3.375 -3.02344,3.339844 -3.02344,8.402344 0,4.429687 2.60157,7.242187 2.63672,2.707031 6.96093,2.707031 4.81641,0 7.91016,-3.304687 3.12891,-3.339844 3.12891,-8.402344 z m 52.3125,0.527344 q 0,7.59375 -5.27344,12.761719 -5.23828,5.167968 -12.9375,5.167968 -8.05078,0 -13.14844,-4.886718 Q 362.5,86.246094 362.5,78.722656 q 0,-7.699219 5.30859,-12.796875 5.34375,-5.132812 13.35938,-5.132812 7.875,0 12.83203,4.851562 4.99219,4.78125 4.99219,12.480469 z m -7.83985,-0.386719 q 0,-4.78125 -2.77734,-7.558594 -2.77734,-2.882812 -7.27734,-2.882812 -4.67579,0 -7.73438,3.199219 -3.05859,3.234375 -3.05859,8.121093 0,4.921875 2.88281,7.910157 2.88281,3.058593 7.45312,3.058593 4.57032,0 7.52344,-3.339843 2.98828,-3.304688 2.98828,-8.507813 z\"\n />\n </svg>\n );\n}\n"],"mappings":"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","names":["Button","jsx","jsx","jsxs","jsx","jsxs"]}
|
|
1
|
+
{"version":3,"sources":["../src/Button.tsx","../src/brand/LogoMonogram.tsx","../src/brand/LogoMonogramBg.tsx","../src/brand/LogoWordmark.tsx","../src/brand/Logo.tsx","../src/brand/decorative.ts","../src/brand/CopulaLockup.tsx","../src/brand/BrandAnimation.tsx","../src/brand/NavbarLogo.tsx","../src/theme/ThemeToggle.tsx","../src/theme/theme.ts","../src/theme/ThemeScript.tsx","../src/video/CaptionedVideo.tsx","../src/video/CaptionLayer.tsx","../src/video/captions.ts","../src/video/mathml.ts"],"sourcesContent":["import * as React from 'react';\n\nexport type ButtonVariant = 'primary' | 'secondary' | 'ghost';\nexport type ButtonSize = 'sm' | 'md' | 'lg';\n\nexport interface ButtonProps\n extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n variant?: ButtonVariant;\n size?: ButtonSize;\n}\n\nconst variantClasses: Record<ButtonVariant, string> = {\n primary: 'di-ui-button--primary',\n secondary: 'di-ui-button--secondary',\n ghost: 'di-ui-button--ghost',\n};\n\nconst sizeClasses: Record<ButtonSize, string> = {\n sm: 'di-ui-button--sm',\n md: 'di-ui-button--md',\n lg: 'di-ui-button--lg',\n};\n\nconst baseStyle: React.CSSProperties = {\n alignItems: 'center',\n borderRadius: 'var(--radius-md, 0.5rem)',\n borderStyle: 'solid',\n borderWidth: '1px',\n cursor: 'pointer',\n display: 'inline-flex',\n fontFamily: 'var(--font-family-sans, system-ui, sans-serif)',\n fontWeight: 'var(--font-weight-medium, 500)',\n gap: 'var(--spacing-sm, 0.5rem)',\n justifyContent: 'center',\n textDecoration: 'none',\n transition: 'background-color 150ms ease, border-color 150ms ease, color 150ms ease',\n};\n\nconst variantStyles: Record<ButtonVariant, React.CSSProperties> = {\n primary: {\n backgroundColor: 'var(--color-interactive-primary)',\n borderColor: 'var(--color-interactive-primary)',\n color: 'var(--color-content-inverse)',\n },\n secondary: {\n backgroundColor: 'var(--color-surface-elevated)',\n borderColor: 'var(--color-border-moderate)',\n color: 'var(--color-content-primary)',\n },\n ghost: {\n backgroundColor: 'transparent',\n borderColor: 'transparent',\n color: 'var(--color-content-secondary)',\n },\n};\n\nconst sizeStyles: Record<ButtonSize, React.CSSProperties> = {\n sm: {\n fontSize: 'var(--font-size-small, 0.875rem)',\n minHeight: '2rem',\n padding: '0.375rem 0.75rem',\n },\n md: {\n fontSize: 'var(--font-size-base, 1rem)',\n minHeight: '2.5rem',\n padding: '0.625rem 1rem',\n },\n lg: {\n fontSize: 'var(--font-size-readable, 1.125rem)',\n minHeight: '3rem',\n padding: '0.75rem 1.25rem',\n },\n};\n\n/**\n * Smoke-level `<Button>` for the alpha release of @dataimago/ui.\n *\n * Styling is delegated to semantic CSS variables published by @dataimago/css\n * so that the component stays small and theme-aware.\n * Consumers that want to override visuals can pass their own className.\n */\nexport const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\n function Button(\n { variant = 'primary', size = 'md', className = '', style, type, children, ...rest },\n ref,\n ) {\n const classes = [\n 'di-ui-button',\n variantClasses[variant],\n sizeClasses[size],\n className,\n ]\n .filter(Boolean)\n .join(' ');\n\n return (\n <button\n ref={ref}\n type={type ?? 'button'}\n className={classes}\n style={{\n ...baseStyle,\n ...variantStyles[variant],\n ...sizeStyles[size],\n ...style,\n }}\n {...rest}\n >\n {children}\n </button>\n );\n },\n);\n","import * as React from 'react';\n\n/**\n * <LogoMonogram /> — the dataimago 'a + i' superimposed monogram, transparent\n * background. Glyphs are outlined paths (no font dependency at render time);\n * fill defaults to `currentColor` so the mark inherits from the surrounding\n * text color and respects light/dark theme switches automatically.\n *\n * Symbolism: 'a' (data, agency) superimposed with 'i' (imago, AI) — the\n * fusion is the brand's central idea. See wiki/principles/visual-identity.md\n * (Stage L follow-up) for the full brand-mark rationale.\n *\n * Source artwork: outlined-path SVG from\n * FOUNDATIONS/background/04_dataimago_Content/Design_Assets/logos/\n * ai_monogram_supreme_1_PATH.svg\n *\n * Usage:\n * <LogoMonogram size={48} aria-label=\"dataimago\" />\n * <span style={{ color: 'var(--color-interactive-primary)' }}>\n * <LogoMonogram size={32} />\n * </span>\n */\n\nexport interface LogoMonogramProps extends React.SVGAttributes<SVGSVGElement> {\n /** Render size in px (or any CSS length). Default: 24. Width and height match. */\n size?: number | string;\n /**\n * Accessible name announced by screen readers. Set to `undefined` (or pass\n * `aria-hidden` directly) when the mark is purely decorative.\n */\n title?: string;\n}\n\nexport function LogoMonogram({\n size = 24,\n title = 'dataimago',\n ...rest\n}: LogoMonogramProps) {\n const a11yProps = title ? { role: 'img' as const } : { 'aria-hidden': true as const };\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 480 480\"\n width={size}\n height={size}\n fill=\"currentColor\"\n aria-label={title}\n {...a11yProps}\n {...rest}\n >\n {title ? <title>{title}</title> : null}\n {/* 'i' (imago) glyph */}\n <path d=\"m 337.3457,97.089844 q 0,8.906246 -6.49414,15.400386 -6.49414,6.49415 -15.58594,6.49415 -9.09179,0 -15.77148,-6.67969 Q 293,105.25391 293,96.162109 q 0,-9.091797 6.30859,-15.40039 6.49414,-6.494141 15.40039,-6.494141 9.0918,0 15.77149,6.865234 6.86523,6.679688 6.86523,15.957032 z M 324.54297,180.21484 303.01953,355 h -41.00586 l 21.52344,-174.78516 z\" />\n {/* 'a' (data) glyph */}\n <path d=\"M 325.70312,176.01562 303.04687,360 h -43.16406 l 2.53906,-19.92188 Q 234.6875,364.29687 205,364.29687 q -36.52344,0 -59.57031,-24.80468 -23.04688,-24.80469 -23.04688,-64.25782 0,-45.50781 26.36719,-74.60937 26.75781,-29.10156 68.55469,-29.10156 19.72656,0 33.59375,6.44531 14.0625,6.44531 28.71093,22.26562 l 2.92969,-24.21875 z m -52.53906,86.71875 q 0,-24.41406 -14.0625,-39.64843 -14.0625,-15.42969 -36.32812,-15.42969 -24.21875,0 -40.625,18.94531 -16.40625,19.14063 -16.40625,46.875 0,24.21875 13.67187,39.64844 13.67188,15.42969 35.15625,15.42969 23.82813,0 41.21094,-19.33594 17.38281,-19.72656 17.38281,-46.48438 z\" />\n </svg>\n );\n}\n","import * as React from 'react';\n\n/**\n * <LogoMonogramBg /> — the dataimago 'a + i' monogram with a rounded accent\n * backplate. White letters on the brand-accent role\n * (var(--color-interactive-accent), iteration-2 sky-blue).\n *\n * Use this variant on neutral surfaces where the no-background monogram\n * would lack presence — favicons, app icons, social-media avatars, or any\n * branded chrome where the mark should read as a self-contained badge.\n *\n * Source artwork: outlined-path SVG from\n * FOUNDATIONS/background/04_dataimago_Content/Design_Assets/logos/\n * ai_monogram_supreme_bg_1_PATH.svg\n *\n * Theming: the background uses var(--color-interactive-accent), which\n * resolves via theme-colors.json's mode-aware role mapping — accent-500\n * (#1f618d) on light surfaces, accent-300 (#3498DB) on dark. The letter\n * fill is hard-set to white; both accent stops have AA-or-better contrast\n * with white letters (light-mode 6.66:1 AA, dark-mode 3.15:1 AA-large for\n * the dot-and-stem heading-size letters used in the monogram). The\n * literal-fallback in this component is light-mode (#1f618d, sky-blue\n * iteration-2) for rare non-CSS-aware contexts. Iteration-1's copper-red\n * fallback (#b54a27) was retired in iteration-2-B.2; see\n * wiki/decisions/iteration-2-blue-accent.md for the rationale.\n *\n * Usage:\n * <LogoMonogramBg size={64} aria-label=\"dataimago\" />\n */\n\nexport interface LogoMonogramBgProps extends React.SVGAttributes<SVGSVGElement> {\n /** Render size in px. Default: 32 (favicon-sized). Width and height match. */\n size?: number | string;\n /** Accessible name. Set undefined or pass aria-hidden for decorative use. */\n title?: string;\n}\n\nexport function LogoMonogramBg({\n size = 32,\n title = 'dataimago',\n ...rest\n}: LogoMonogramBgProps) {\n const a11yProps = title ? { role: 'img' as const } : { 'aria-hidden': true as const };\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 480 480\"\n width={size}\n height={size}\n aria-label={title}\n {...a11yProps}\n {...rest}\n >\n {title ? <title>{title}</title> : null}\n {/* Rounded accent backplate — themed via --color-interactive-accent\n (mode-aware: accent-500 #1f618d on light, accent-300 #3498DB on dark).\n Literal fallback is the light-mode canonical for non-CSS consumers. */}\n <rect\n width=\"100%\"\n height=\"100%\"\n rx=\"40\"\n ry=\"40\"\n fill=\"var(--color-interactive-accent, #1f618d)\"\n />\n {/* 'a' (data) glyph in white */}\n <path\n fill=\"#ffffff\"\n d=\"M 325.70312,176.01562 303.04687,360 h -43.16406 l 2.53906,-19.92188 Q 234.6875,364.29687 205,364.29687 q -36.52344,0 -59.57031,-24.80468 -23.04688,-24.80469 -23.04688,-64.25782 0,-45.50781 26.36719,-74.60937 26.75781,-29.10156 68.55469,-29.10156 19.72656,0 33.59375,6.44531 14.0625,6.44531 28.71093,22.26562 l 2.92969,-24.21875 z m -52.53906,86.71875 q 0,-24.41406 -14.0625,-39.64843 -14.0625,-15.42969 -36.32812,-15.42969 -24.21875,0 -40.625,18.94531 -16.40625,19.14063 -16.40625,46.875 0,24.21875 13.67187,39.64844 13.67188,15.42969 35.15625,15.42969 23.82813,0 41.21094,-19.33594 17.38281,-19.72656 17.38281,-46.48438 z\"\n />\n {/* 'i' (imago) glyph in white */}\n <path\n fill=\"#ffffff\"\n d=\"m 337.3457,97.089844 q 0,8.906246 -6.49414,15.400386 -6.49414,6.49415 -15.58594,6.49415 -9.09179,0 -15.77148,-6.67969 Q 293,105.25391 293,96.162109 q 0,-9.091797 6.30859,-15.40039 6.49414,-6.494141 15.40039,-6.494141 9.0918,0 15.77149,6.865234 6.86523,6.679688 6.86523,15.957032 z M 324.54297,180.21484 303.01953,355 h -41.00586 l 21.52344,-174.78516 z\"\n />\n </svg>\n );\n}\n","import * as React from 'react';\n\n/**\n * <LogoWordmark /> — the full \"dataimago\" wordmark with the 'ai' overlap.\n * White letters on a rounded accent backplate, themed via\n * var(--color-interactive-accent).\n *\n * Use this variant for primary brand surfaces: site headers, document\n * letterheads, large-format presentations, business materials. For compact\n * contexts (favicons, social avatars) use <LogoMonogramBg /> instead; for\n * inline use within prose use <LogoMonogram /> with currentColor.\n *\n * The wordmark preserves the philosophical idea of the brand: the visible\n * superposition of 'a' (data, human agency) and 'i' (imago, AI) creates a new\n * unified glyph that is neither pure human nor pure artificial — genuine\n * collaboration. See wiki/principles/visual-identity.md (Stage L follow-up).\n *\n * Source artwork: outlined-path SVG from\n * FOUNDATIONS/background/04_dataimago_Content/Design_Assets/logos/\n * dataimago_supreme_1_PATH.svg\n *\n * Theming: the backplate uses var(--color-interactive-accent), which resolves\n * via theme-colors.json's mode-aware role mapping — accent-500 (#1f618d) on\n * light surfaces, accent-300 (#3498DB) on dark. The literal-fallback in this\n * component is light-mode (#1f618d, sky-blue iteration-2) for the rare cases\n * where the SVG is consumed without CSS-variable resolution (printed PDFs from\n * raw SVG, third-party platforms that strip CSS). Iteration-1's copper-red\n * fallback (#b54a27) was retired in iteration-2-B.2; see\n * wiki/decisions/iteration-2-blue-accent.md for the rationale.\n *\n * Usage:\n * <LogoWordmark width={240} aria-label=\"dataimago\" />\n *\n * The wordmark's natural aspect ratio is 480x150 (~3.2:1). Pass `width` and\n * height auto-scales, or pass both explicitly.\n */\n\nexport interface LogoWordmarkProps extends React.SVGAttributes<SVGSVGElement> {\n /** Width in px. Default: 240. Height auto-scales to the 480:150 ratio. */\n width?: number | string;\n /** Accessible name. Set undefined or pass aria-hidden for decorative use. */\n title?: string;\n}\n\nexport function LogoWordmark({\n width = 240,\n title = 'dataimago',\n ...rest\n}: LogoWordmarkProps) {\n const a11yProps = title ? { role: 'img' as const } : { 'aria-hidden': true as const };\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 480 150\"\n width={width}\n aria-label={title}\n {...a11yProps}\n {...rest}\n >\n {title ? <title>{title}</title> : null}\n {/* Rounded accent backplate — themed via --color-interactive-accent\n (mode-aware: accent-500 #1f618d on light, accent-300 #3498DB on dark).\n Literal fallback is the light-mode canonical for non-CSS consumers. */}\n <rect\n width=\"100%\"\n height=\"100%\"\n rx=\"5\"\n ry=\"5\"\n fill=\"var(--color-interactive-accent, #1f618d)\"\n />\n {/* \"data\" — outlined glyphs, white fill */}\n <path\n fill=\"#ffffff\"\n d=\"M 104.80469,35.621094 97.492187,95 h -7.734375 l 0.421875,-3.550781 q -2.882812,2.566406 -4.992187,3.480468 -2.074219,0.84375 -5.132813,0.84375 -6.960937,0 -11.390625,-4.605468 -4.429687,-4.640625 -4.429687,-11.953125 0,-7.804688 4.851562,-12.972657 4.851563,-5.167968 12.199219,-5.167968 3.761719,0 6.328125,1.300781 2.671875,1.335937 5.589844,4.535156 L 97.035156,35.621094 Z M 92.007812,77 q 0,-4.21875 -2.601562,-6.820313 -2.601563,-2.601562 -6.820313,-2.601562 -4.570312,0 -7.558593,3.410156 -2.988282,3.410156 -2.988282,8.613281 0,4.394532 2.566407,7.066407 2.566406,2.636718 6.820312,2.636718 4.429688,0 7.488281,-3.585937 Q 92.007812,82.203125 92.007812,77 Z M 145.51562,61.882812 141.4375,95 h -7.76953 l 0.45703,-3.585938 q -4.99219,4.359375 -10.33594,4.359375 -6.57422,0 -10.72265,-4.464843 -4.14844,-4.464844 -4.14844,-11.566407 0,-8.191406 4.74609,-13.429687 4.81641,-5.238281 12.33985,-5.238281 3.55078,0 6.04687,1.160156 2.53125,1.160156 5.16797,4.007812 l 0.52734,-4.359375 z m -9.45703,15.609375 q 0,-4.394531 -2.53125,-7.136718 -2.53125,-2.777344 -6.53906,-2.777344 -4.35937,0 -7.3125,3.410156 -2.95312,3.445313 -2.95312,8.4375 0,4.359375 2.46093,7.136719 2.46094,2.777344 6.32813,2.777344 4.28906,0 7.41797,-3.480469 3.1289,-3.550781 3.1289,-8.367188 z M 163.79687,69.089844 160.59766,95 h -7.76954 l 3.19922,-25.910156 h -4.39453 l 0.87891,-7.207032 h 4.39453 l 1.89844,-15.363281 h 7.76953 l -1.89844,15.363281 h 7.17188 l -0.87891,7.207032 z M 211.29297,61.882812 207.21484,95 h -7.76953 l 0.45703,-3.585938 q -4.99218,4.359375 -10.33593,4.359375 -6.57422,0 -10.72266,-4.464843 -4.14844,-4.464844 -4.14844,-11.566407 0,-8.191406 4.7461,-13.429687 4.8164,-5.238281 12.33984,-5.238281 3.55078,0 6.04687,1.160156 2.53125,1.160156 5.16797,4.007812 l 0.52735,-4.359375 z m -9.45703,15.609375 q 0,-4.394531 -2.53125,-7.136718 -2.53125,-2.777344 -6.53907,-2.777344 -4.35937,0 -7.3125,3.410156 -2.95312,3.445313 -2.95312,8.4375 0,4.359375 2.46094,7.136719 2.46093,2.777344 6.32812,2.777344 4.28906,0 7.41797,-3.480469 3.12891,-3.550781 3.12891,-8.367188 z\"\n />\n {/* \"imago\" — outlined glyphs, white fill, superimposed at the 'a/i' overlap */}\n <path\n fill=\"#ffffff\"\n d=\"m 213.40234,46.132812 q 0,1.6875 -1.23047,2.917969 -1.23046,1.230469 -2.95312,1.230469 -1.72266,0 -2.98828,-1.265625 Q 205,47.679687 205,45.957031 q 0,-1.722656 1.19531,-2.917969 1.23047,-1.230468 2.91797,-1.230468 1.72266,0 2.98828,1.300781 1.30078,1.265625 1.30078,3.023437 z m -2.42578,15.75 L 206.89844,95 h -7.76953 l 4.07812,-33.117188 z m 18.87891,0 -0.35156,3.09375 q 3.9375,-3.9375 9.10546,-3.9375 3.12891,0 4.81641,1.160157 1.6875,1.089843 3.02344,4.113281 4.92187,-5.238281 10.61719,-5.238281 9.84375,0 9.84375,9.035156 0,0.914062 -0.17579,2.566406 -0.14062,1.652344 -0.42187,4.078125 L 264.0625,95 h -7.76953 l 2.39062,-19.160156 Q 259,73.167969 259,71.902344 q 0,-4.324219 -4.35938,-4.324219 -1.72265,0 -2.98828,0.527344 -1.26562,0.492187 -2.17968,1.582031 -0.87891,1.054687 -1.47657,2.777344 -0.5625,1.6875 -0.8789,4.042968 L 244.86719,95 h -7.76953 l 2.42578,-19.652344 q 0.3164,-2.671875 0.3164,-3.65625 0,-4.113281 -4.46484,-4.113281 -6.46875,0 -7.55859,8.964844 L 225.53125,95 h -7.76953 l 4.07812,-33.117188 z m 81.63281,0 L 307.41016,95 h -7.76954 l 0.45704,-3.585938 q -4.99219,4.359375 -10.33594,4.359375 -6.57422,0 -10.72266,-4.464843 -4.14844,-4.464844 -4.14844,-11.566407 0,-8.191406 4.7461,-13.429687 4.8164,-5.238281 12.33984,-5.238281 3.55078,0 6.04688,1.160156 2.53125,1.160156 5.16797,4.007812 l 0.52734,-4.359375 z m -9.45703,15.609375 q 0,-4.394531 -2.53125,-7.136718 -2.53125,-2.777344 -6.53906,-2.777344 -4.35938,0 -7.3125,3.410156 -2.95313,3.445313 -2.95313,8.4375 0,4.359375 2.46094,7.136719 2.46094,2.777344 6.32812,2.777344 4.28907,0 7.41797,-3.480469 3.12891,-3.550781 3.12891,-8.367188 z m 53.57812,-15.609375 -4.07812,33.363282 q -0.38672,2.988281 -0.87891,5.203126 -0.45703,2.21484 -1.05468,3.72656 -1.23047,3.09375 -3.65625,5.3086 -4.71094,4.21875 -12.23438,4.21875 -7.76953,0 -12.58594,-4.07813 -2.46093,-2.03906 -3.44531,-4.64062 -0.98437,-2.39063 -0.98437,-6.714849 h 7.52343 q 0.28125,4.675779 2.39063,6.785159 2.10937,2.14453 6.53906,2.14453 4.78125,0 7.27734,-2.56641 2.4961,-2.53125 3.16407,-8.085935 l 0.5625,-4.535156 q -4.92188,3.761718 -10.33594,3.761718 -6.75,0 -11.14453,-4.605468 -4.39453,-4.710938 -4.39453,-11.742188 0,-7.910156 5.09765,-13.113281 5.13282,-5.238281 12.83203,-5.238281 3.69141,0 5.97657,1.089843 2.49609,1.054688 5.16797,3.832032 l 0.49218,-4.113282 z m -8.92968,15.714844 q 0,-4.5 -2.74219,-7.242187 -2.74219,-2.777344 -7.17188,-2.777344 -4.60546,0 -7.66406,3.375 -3.02344,3.339844 -3.02344,8.402344 0,4.429687 2.60157,7.242187 2.63672,2.707031 6.96093,2.707031 4.81641,0 7.91016,-3.304687 3.12891,-3.339844 3.12891,-8.402344 z m 52.3125,0.527344 q 0,7.59375 -5.27344,12.761719 -5.23828,5.167968 -12.9375,5.167968 -8.05078,0 -13.14844,-4.886718 Q 362.5,86.246094 362.5,78.722656 q 0,-7.699219 5.30859,-12.796875 5.34375,-5.132812 13.35938,-5.132812 7.875,0 12.83203,4.851562 4.99219,4.78125 4.99219,12.480469 z m -7.83985,-0.386719 q 0,-4.78125 -2.77734,-7.558594 -2.77734,-2.882812 -7.27734,-2.882812 -4.67579,0 -7.73438,3.199219 -3.05859,3.234375 -3.05859,8.121093 0,4.921875 2.88281,7.910157 2.88281,3.058593 7.45312,3.058593 4.57032,0 7.52344,-3.339843 2.98828,-3.304688 2.98828,-8.507813 z\"\n />\n </svg>\n );\n}\n","import * as React from 'react';\nimport { svgs, type LogoId, type LogoVariant, type LogoKey } from '@dataimago/brand';\nimport { isDecorative, silenceSvg } from './decorative';\n\nexport interface LogoProps extends React.HTMLAttributes<HTMLSpanElement> {\n /** Mark id, e.g. `dissertation_ai_OVERLAP`. */\n name: LogoId;\n /** PATH (default), CUTOUT, BG, or LETTERS. See @dataimago/brand. */\n variant?: LogoVariant;\n /**\n * Render width (px number or any CSS length). Height scales proportionally\n * via the SVG viewBox. Omit to use the mark's intrinsic size.\n */\n width?: number | string;\n}\n\n/**\n * Manifest-driven brand mark from `@dataimago/brand`. Inlines the SVG string so\n * `currentColor` (PATH/LETTERS), the `--color-interactive-accent` badge fill\n * (CUTOUT/BG), and the per-letter interaction classes (`.glyph`, `.logo-*`) all\n * work — an `<img src>` can't receive those interior styles.\n *\n * Color flows from CSS: set `color` (PATH/LETTERS) on this element or an\n * ancestor. Size via `width` (or CSS on the wrapper).\n */\nexport function Logo({ name, variant = 'PATH', width, style, ...rest }: LogoProps) {\n const key = `${name}_${variant}` as LogoKey;\n let markup = svgs[key];\n\n if (!markup) {\n // eslint-disable-next-line no-console\n console.warn(`[@dataimago/ui] <Logo>: unknown mark \"${key}\".`);\n return null;\n }\n\n if (width != null) {\n // Set width + drop height so the viewBox preserves the aspect ratio.\n markup = markup\n .replace(/\\swidth=\"[^\"]*\"/, ` width=\"${width}\"`)\n .replace(/\\sheight=\"[^\"]*\"/, '');\n }\n\n // Decorative (aria-hidden): silence the <svg> itself — see decorative.ts.\n if (isDecorative(rest['aria-hidden'])) markup = silenceSvg(markup);\n\n return (\n <span\n style={{ display: 'inline-flex', ...style }}\n // The SVG is generated, font-free, and carries its own <title>/aria-label.\n dangerouslySetInnerHTML={{ __html: markup }}\n {...rest}\n />\n );\n}\n","/**\n * Make an inlined brand SVG silent to assistive technology.\n *\n * The generated marks carry `role=\"img\"`, an `aria-label` and a `<title>` so\n * they can stand alone. Inside a link that is already named, consumers pass\n * `aria-hidden` to the wrapper. VoiceOver in Safari ignored that wrapper and\n * read the SVG's title AND the text of its interior `<style>` block (the CSS)\n * aloud. That was the first thing heard on every dissertation.ai page, found in\n * the maintainer's AT pass, 2026-10-04. So a decorative mark is silenced on the\n * `<svg>` itself: aria-hidden + focusable=false, no role/label/title.\n */\nexport function silenceSvg(markup: string): string {\n return markup\n .replace(/<title\\b[^>]*>[\\s\\S]*?<\\/title>/gi, '')\n .replace(/<svg\\b([^>]*)>/i, (_m, attrs: string) => {\n const kept = attrs\n .replace(/\\srole=\"[^\"]*\"/i, '')\n .replace(/\\saria-label=\"[^\"]*\"/i, '')\n .replace(/\\saria-labelledby=\"[^\"]*\"/i, '');\n return `<svg${kept} aria-hidden=\"true\" focusable=\"false\">`;\n });\n}\n\n/** True when the caller marked the mark decorative (`aria-hidden` truthy). */\nexport function isDecorative(ariaHidden: unknown): boolean {\n return ariaHidden === true || ariaHidden === 'true';\n}\n","import * as React from 'react';\nimport { manifest, type LogoId } from '@dataimago/brand';\nimport { Logo } from './Logo';\n\n/** A link the lockup renders; pass one to route through a framework link (e.g. next/link). */\nexport interface CopulaLinkProps {\n href: string;\n 'aria-label': string;\n className?: string;\n style?: React.CSSProperties;\n children: React.ReactNode;\n}\n\nexport interface CopulaLockupProps extends React.HTMLAttributes<HTMLSpanElement> {\n /** The property's wordmark id, e.g. `dissertation_ai`. Its PATH variant is drawn. */\n property: LogoId;\n /** Accessible name of the property link, e.g. `dissertation-ai`. */\n propertyLabel: string;\n /** Where the property mark links. Defaults to `/`. */\n propertyHref?: string;\n /**\n * `shown` (default): \"<property> is dataimago\". `hidden`: the property mark\n * alone, with no badge, no dataimago wordmark and no link to dataimago, for\n * apps that keep dataimago out of view while it is in stealth.\n */\n dataimago?: 'shown' | 'hidden';\n /** Where the dataimago wordmark links. Defaults to https://dataimago.ai. */\n brandHref?: string;\n /** Wordmark height in px. Defaults to 32; the badge and spacing scale with it. */\n height?: number;\n /** Class for each link (colour and hover); both links share one treatment. */\n linkClassName?: string;\n /**\n * Class for the `is` disc. It is not a link, so `linkClassName` does not reach\n * it: give it the links' rest colour here (e.g. the same `text-*` class\n * without the hover). Without it the disc takes the lockup's colour.\n */\n badgeClassName?: string;\n /** Render the links with a framework component. Defaults to a plain `<a>`. */\n renderLink?: (props: CopulaLinkProps) => React.ReactNode;\n}\n\n// At the 32px reference size (the dissertation-ai footer, tuned by eye in\n// 2026-07 and checked with getBBox): the badge is 16px, each wordmark's ink edge\n// sits 19.7px from the badge centre, and each wordmark is cropped 10px top and\n// bottom so the cap-height band, not the canvas, is what centres on the badge.\nconst BADGE = 16 / 32;\nconst GAP = 19.7 / 32;\nconst CROP = 10 / 32;\n\nconst VISUALLY_HIDDEN: React.CSSProperties = {\n border: 0,\n clip: 'rect(0 0 0 0)',\n height: 1,\n margin: -1,\n overflow: 'hidden',\n padding: 0,\n position: 'absolute',\n whiteSpace: 'nowrap',\n width: 1,\n};\n\nconst round = (n: number) => Math.round(n * 100) / 100;\n\nfunction pathEntry(id: LogoId) {\n return manifest.find((e) => e.id === id && e.variant === 'PATH');\n}\n\nconst plainLink = ({ children, ...props }: CopulaLinkProps) => <a {...props}>{children}</a>;\n\n/**\n * The copula lockup, \"dissertation-ai **is** dataimago\": the property wordmark,\n * the `is_badge` disc and the dataimago wordmark, each wordmark its own link\n * (wiki/connections/is-copula-coupling.md). The badge is a mark, not a link: at\n * 16px it is below the 24px pointer-target floor (WCAG 2.5.8), so it is read as\n * \"is\" and the philosophy page stays reachable from the nav.\n *\n * Spacing is ink-symmetric about the badge centre, computed from each mark's\n * `ink` box in the @dataimago/brand manifest, so any property mark lines up\n * without hand-tuned margins. Geometry is inline style (no Tailwind), so a\n * consumer on plain CSS can use it too. Every piece is `currentColor`: the\n * wordmarks take their link's colour (`linkClassName`, or the page's link\n * colour), the disc takes `badgeClassName`'s, or the lockup's.\n */\nexport function CopulaLockup({\n property,\n propertyLabel,\n propertyHref = '/',\n dataimago = 'shown',\n brandHref = 'https://dataimago.ai',\n height = 32,\n linkClassName,\n badgeClassName,\n renderLink = plainLink,\n style,\n ...rest\n}: CopulaLockupProps) {\n const prop = pathEntry(property);\n const brand = pathEntry('dataimago');\n if (!prop || !brand) {\n // eslint-disable-next-line no-console\n console.warn(`[@dataimago/ui] <CopulaLockup>: unknown mark \"${property}\".`);\n return null;\n }\n\n const shown = dataimago === 'shown';\n const badge = BADGE * height;\n const reach = GAP * height - badge / 2;\n const crop = -CROP * height;\n const width = (e: { w: number; h: number }) => round((e.w * height) / e.h);\n // A wordmark's own whitespace between its canvas edge and its ink, in px.\n const trailing = ((prop.w - prop.ink.x2) * height) / prop.h;\n const leading = (brand.ink.x1 * height) / brand.h;\n\n return (\n <span\n style={{ alignItems: 'center', display: 'inline-flex', flexWrap: 'wrap', rowGap: 4, ...style }}\n {...rest}\n >\n {renderLink({\n href: propertyHref,\n 'aria-label': propertyLabel,\n className: linkClassName,\n // The crop only centres the cap-height band on the badge; alone (hidden),\n // the mark keeps its full box so nothing next to it can overlap it.\n style: {\n display: 'inline-flex',\n marginBlock: shown ? crop : 0,\n marginRight: shown ? round(reach - trailing) : 0,\n },\n children: <Logo name={property} aria-hidden width={width(prop)} />,\n })}\n {shown ? (\n <>\n <span className={badgeClassName} style={{ display: 'inline-flex' }}>\n <Logo name=\"is_badge\" variant=\"CUTOUT\" aria-hidden width={round(badge)} />\n <span style={VISUALLY_HIDDEN}>is</span>\n </span>\n {renderLink({\n href: brandHref,\n 'aria-label': 'dataimago',\n className: linkClassName,\n style: { display: 'inline-flex', marginBlock: crop, marginLeft: round(reach - leading) },\n children: <Logo name=\"dataimago\" aria-hidden width={width(brand)} />,\n })}\n </>\n ) : null}\n </span>\n );\n}\n","'use client';\n\nimport * as React from 'react';\nimport {\n animations,\n animationManifest,\n type AnimationId,\n type LogoId,\n type LogoVariant,\n} from '@dataimago/brand';\nimport { Logo } from './Logo';\n\nexport interface BrandAnimationProps\n extends React.HTMLAttributes<HTMLSpanElement> {\n /** Animation id, e.g. `dissertation-ai`. See @dataimago/brand animations.json. */\n name: AnimationId;\n /**\n * Render width (px number or any CSS length). Height scales via the SVG\n * viewBox. Omit to use the animation's intrinsic size.\n */\n width?: number | string;\n}\n\n/**\n * SSR-safe `prefers-reduced-motion` detection. Starts `true` (reduced) so the\n * server and the first client render agree on the static poster — no hydration\n * mismatch, and no motion flashes before JS decides. After mount it reflects the\n * real media query and updates live if the user toggles the OS setting.\n */\nfunction usePrefersReducedMotion(): boolean {\n const [reduced, setReduced] = React.useState(true);\n React.useEffect(() => {\n const mq = window.matchMedia('(prefers-reduced-motion: reduce)');\n setReduced(mq.matches);\n const onChange = (e: MediaQueryListEvent) => setReduced(e.matches);\n mq.addEventListener('change', onChange);\n return () => mq.removeEventListener('change', onChange);\n }, []);\n return reduced;\n}\n\n/**\n * Decorative brand animation from `@dataimago/brand` (the animation-foundry).\n * Inlines the pure-SMIL SVG string so its interior `<style>` works — an\n * `<img src>` can't receive those styles (same rationale as `<Logo>`).\n *\n * Motion-dignity: decorative brand animation is a distinct category from the\n * 300ms UI-transition ceiling, but it is contractually gated on\n * `prefers-reduced-motion`. When the user prefers reduced motion this renders\n * the static brand mark the animation settles to (its `poster`) via `<Logo>`,\n * so no consumer can ship the motion without the fallback.\n */\nexport function BrandAnimation({\n name,\n width,\n style,\n ...rest\n}: BrandAnimationProps) {\n const reduced = usePrefersReducedMotion();\n const entry = animationManifest.find((a) => a.id === name);\n let markup = animations[name];\n\n if (!entry || !markup) {\n // eslint-disable-next-line no-console\n console.warn(`[@dataimago/ui] <BrandAnimation>: unknown animation \"${name}\".`);\n return null;\n }\n\n if (reduced) {\n // Static settle-frame: the brand mark the animation resolves to.\n return (\n <Logo\n name={entry.poster.id as LogoId}\n variant={entry.poster.variant as LogoVariant}\n width={width}\n style={style}\n {...rest}\n />\n );\n }\n\n if (width != null) {\n markup = markup\n .replace(/\\swidth=\"[^\"]*\"/, ` width=\"${width}\"`)\n .replace(/\\sheight=\"[^\"]*\"/, '');\n }\n\n return (\n <span\n style={{ display: 'inline-flex', ...style }}\n dangerouslySetInnerHTML={{ __html: markup }}\n {...rest}\n />\n );\n}\n","'use client';\n\nimport * as React from 'react';\nimport {\n navbarLogos,\n navbarManifest,\n type NavbarLogoId,\n type LogoId,\n type LogoVariant,\n} from '@dataimago/brand';\nimport { Logo } from './Logo';\nimport { isDecorative, silenceSvg } from './decorative';\n\nexport interface NavbarLogoProps extends React.HTMLAttributes<HTMLSpanElement> {\n /** Navbar mark id, e.g. `dissertation-ai`. See @dataimago/brand navbar.json. */\n name: NavbarLogoId;\n /**\n * Render width (px number or any CSS length). Height scales via the SVG\n * viewBox. Omit to use the mark's intrinsic size.\n */\n width?: number | string;\n}\n\n/**\n * SSR-safe `prefers-reduced-motion`. Starts `true` (reduced) so server and first\n * client render agree on the static poster — no hydration mismatch, no motion\n * flash. After mount it reflects the real query and updates live. (Mirrors\n * BrandAnimation; kept local to avoid a shared-hook refactor.)\n */\nfunction usePrefersReducedMotion(): boolean {\n const [reduced, setReduced] = React.useState(true);\n React.useEffect(() => {\n const mq = window.matchMedia('(prefers-reduced-motion: reduce)');\n setReduced(mq.matches);\n const onChange = (e: MediaQueryListEvent) => setReduced(e.matches);\n mq.addEventListener('change', onChange);\n return () => mq.removeEventListener('change', onChange);\n }, []);\n return reduced;\n}\n\n/**\n * Animated brand mark for an app navbar, from `@dataimago/brand` (the\n * animation-foundry's navbar set). Inlines the self-contained CSS-animated SVG\n * so its interior `<style>` works — an `<img src>` can't receive those styles.\n *\n * Behaviour by mark kind (from the navbar manifest):\n * - `assemble` (L2: dissertation-ai, rpkg-ai, SGPc-ai): the trailing `a`/`i`\n * start apart and the `i` slides onto the `a`. Plays once on mount; replays\n * on pointer-enter via a remount (`replayKey`).\n * - `shimmer` (L1: dataimago-ai): the monogram is always superimposed; an\n * accent shimmer sweeps on `:hover` from the SVG's own CSS (no JS trigger).\n * - `dream` (promoted dream marks, `tools/dream-foundry/drop.mjs promote`):\n * a self-contained CSS hover gesture like liftwash; the poster is the mark's\n * own static form (`dream_<slug>` / `DREAM`). Ink is `currentColor`.\n *\n * Motion-dignity: the embedded CSS animation is <= 300ms and gated on\n * `@media (prefers-reduced-motion: no-preference)`. When the user prefers\n * reduced motion this renders the static settled mark (the manifest `poster`,\n * the superimposed monogram) via `<Logo>` — so no consumer can ship the motion\n * without the fallback.\n */\nexport function NavbarLogo({ name, width, style, ...rest }: NavbarLogoProps) {\n const reduced = usePrefersReducedMotion();\n\n const entry = navbarManifest.find((n) => n.id === name);\n let markup = navbarLogos[name];\n\n if (!entry || !markup) {\n // eslint-disable-next-line no-console\n console.warn(`[@dataimago/ui] <NavbarLogo>: unknown navbar mark \"${name}\".`);\n return null;\n }\n\n if (reduced) {\n // Static settle-frame: the superimposed mark the animation resolves to.\n return (\n <Logo\n name={entry.poster.id as LogoId}\n variant={entry.poster.variant as LogoVariant}\n width={width}\n style={style}\n {...rest}\n />\n );\n }\n\n if (width != null) {\n markup = markup\n .replace(/\\swidth=\"[^\"]*\"/, ` width=\"${width}\"`)\n .replace(/\\sheight=\"[^\"]*\"/, '');\n }\n\n // Decorative (aria-hidden): silence the <svg> itself — see decorative.ts.\n // (The reduced-motion branch above goes through <Logo>, which does the same.)\n if (isDecorative(rest['aria-hidden'])) markup = silenceSvg(markup);\n\n // The SVG is fully self-driving: it plays the assemble once on mount (its\n // `.di-play` class) and runs the smooth hover round-trip from its own `:hover`\n // CSS — no remount/replay logic here (remounting is what caused the teleport).\n return (\n <span\n style={{ display: 'inline-flex', ...style }}\n // Self-contained, font-free SVG; carries its own <title>/aria-label.\n dangerouslySetInnerHTML={{ __html: markup }}\n {...rest}\n />\n );\n}\n","import * as React from 'react';\nimport {\n resolveTheme,\n useResolvedTheme,\n useThemePreference,\n type ResolvedTheme,\n type ThemePreference,\n} from './theme.js';\n\nexport interface ThemeToggleLabels {\n /** What the control sets, read before the theme in effect (\"Theme: Light\"). */\n name: string;\n /** Added when the theme follows the operating system (\"Theme: Light (System)\"). */\n system: string;\n light: string;\n dark: string;\n}\n\nexport interface ThemeToggleProps\n extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'onClick' | 'children' | 'type'> {\n /** Accessible and tooltip text; pass the property's own wording. */\n labels?: Partial<ThemeToggleLabels>;\n}\n\nconst DEFAULT_LABELS: ThemeToggleLabels = {\n name: 'Theme',\n system: 'System',\n light: 'Light',\n dark: 'Dark',\n};\n\n/** The operating system's theme. */\nfunction systemTheme(): ResolvedTheme {\n return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';\n}\n\n/**\n * The choice one click makes: the other theme, stored as \"system\" when that is\n * the operating system's own, so the page goes back to following it.\n */\nexport function nextThemePreference(shown: ResolvedTheme, system: ResolvedTheme): ThemePreference {\n const next: ResolvedTheme = shown === 'dark' ? 'light' : 'dark';\n return next === system ? 'system' : next;\n}\n\nconst noSubscribe = () => () => {};\n\n/**\n * False in the server markup and during hydration, true after. The theme in\n * effect is only known on the client (the server snapshot is always light), so\n * until then the button claims no theme: its name is the bare `name` and its\n * icon is hidden, keeping the 48px box.\n */\nfunction useHydrated(): boolean {\n return React.useSyncExternalStore(noSubscribe, () => true, () => false);\n}\n\nfunction Icon({ theme }: { theme: ResolvedTheme }) {\n const common = {\n width: 20,\n height: 20,\n viewBox: '0 0 24 24',\n fill: 'none',\n stroke: 'currentColor',\n strokeWidth: 1.75,\n strokeLinecap: 'round' as const,\n strokeLinejoin: 'round' as const,\n 'aria-hidden': true,\n focusable: false,\n };\n if (theme === 'dark') {\n return (\n <svg {...common}>\n <path d=\"M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z\" />\n </svg>\n );\n }\n return (\n <svg {...common}>\n <circle cx=\"12\" cy=\"12\" r=\"4\" />\n <path d=\"M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M4.93 19.07l1.41-1.41M17.66 6.34l1.41-1.41\" />\n </svg>\n );\n}\n\n/**\n * Light/dark toggle for an app navbar: one button, and one click always flips\n * the theme on screen. The page follows the operating system until the first\n * click; a click that lands on the system's own theme goes back to following\n * it (no stored choice), and the other theme is stored and set as\n * `data-bs-theme` on the root, which the house tokens obey. The icon shows the\n * theme in effect: a sun in light, a moon in dark.\n *\n * A 48px target (the dataimago touch floor). The icon is `currentColor`.\n * Inline styles would beat a consumer's `:hover` rule, so the two colours a\n * navbar restyles read custom properties instead: set `--di-theme-toggle-fg`\n * and `--di-theme-toggle-bg` on `.di-ui-theme-toggle` (and its `:hover`).\n * Pair it with `<ThemeScript />` in `<head>` so a stored choice applies before\n * first paint.\n */\nexport function ThemeToggle({ labels, className = '', style, ...rest }: ThemeToggleProps) {\n const [preference, setPreference] = useThemePreference();\n const resolved = useResolvedTheme();\n const hydrated = useHydrated();\n const shown = hydrated ? resolved : undefined;\n const text = { ...DEFAULT_LABELS, ...labels };\n const label = shown\n ? `${text.name}: ${text[shown]}${preference === 'system' ? ` (${text.system})` : ''}`\n : text.name;\n return (\n <button\n {...rest}\n className={['di-ui-theme-toggle', className].filter(Boolean).join(' ')}\n aria-label={label}\n title={label}\n data-theme-preference={preference}\n data-theme={shown}\n style={{\n alignItems: 'center',\n background: 'var(--di-theme-toggle-bg, transparent)',\n border: 0,\n borderRadius: 'var(--radius-md, 0.5rem)',\n color: 'var(--di-theme-toggle-fg, inherit)',\n cursor: 'pointer',\n display: 'inline-flex',\n height: '48px',\n justifyContent: 'center',\n padding: 0,\n transition: 'background-color 150ms ease',\n width: '48px',\n ...style,\n }}\n // After the spread, so the control never submits a form or loses its flip.\n type=\"button\"\n // Live reads, not the rendered snapshot: a click always flips what is on screen.\n onClick={() => setPreference(nextThemePreference(resolveTheme(), systemTheme()))}\n >\n <span style={{ display: 'inline-flex', visibility: shown ? 'visible' : 'hidden' }}>\n <Icon theme={shown ?? 'light'} />\n </span>\n </button>\n );\n}\n","import * as React from 'react';\n\n/**\n * Light/dark theme preference for dataimago apps.\n *\n * The house tokens (`@dataimago/tokens`) follow the operating system through\n * `prefers-color-scheme` and yield to an explicit `data-bs-theme` on the root:\n * `light` or `dark` forces that theme, no attribute means \"follow the system\".\n * This module owns that attribute: it reads and stores the reader's choice,\n * applies it, and reports the theme actually in effect (for canvas and WebGL\n * surfaces that cannot read CSS variables).\n *\n * The choice is a per-browser convenience in localStorage. Every read and write\n * is guarded: in a private window or with storage blocked the page simply\n * follows the system.\n */\n\nexport type ThemePreference = 'system' | 'light' | 'dark';\nexport type ResolvedTheme = 'light' | 'dark';\n\nexport const THEME_STORAGE_KEY = 'dataimago-theme';\nexport const THEME_ATTRIBUTE = 'data-bs-theme';\n\n/** Fired on `window` whenever `setThemePreference` changes the choice. */\nconst CHANGE_EVENT = 'dataimago:themechange';\n\n/**\n * Inline this in `<head>` before any stylesheet paints, so a stored choice is\n * on the root before first paint (no flash of the other theme). The server\n * markup cannot know the choice, so the consumer also puts\n * `suppressHydrationWarning` on `<html>`. From a React server layout, render\n * `<ThemeScript />` instead: this package is a client bundle, so a server\n * component cannot import the string itself.\n *\n * ```tsx\n * <html lang=\"en\" suppressHydrationWarning>\n * <head><ThemeScript /></head>\n * ```\n */\nexport const themeInitScript =\n `(function(){try{var p=localStorage.getItem(${JSON.stringify(THEME_STORAGE_KEY)});` +\n `if(p==='light'||p==='dark'){document.documentElement.setAttribute(${JSON.stringify(THEME_ATTRIBUTE)},p);}}` +\n `catch(e){}})();`;\n\nfunction isPreference(value: unknown): value is ThemePreference {\n return value === 'system' || value === 'light' || value === 'dark';\n}\n\n/** The stored choice, or `'system'` when there is none (or storage is unavailable). */\nexport function readThemePreference(): ThemePreference {\n if (typeof window === 'undefined') return 'system';\n try {\n const stored = window.localStorage.getItem(THEME_STORAGE_KEY);\n return isPreference(stored) ? stored : 'system';\n } catch {\n return 'system';\n }\n}\n\nfunction applyAttribute(preference: ThemePreference): void {\n const root = document.documentElement;\n if (preference === 'system') root.removeAttribute(THEME_ATTRIBUTE);\n else root.setAttribute(THEME_ATTRIBUTE, preference);\n}\n\n/** Store, apply and announce a choice. `'system'` clears the stored choice. */\nexport function setThemePreference(preference: ThemePreference): void {\n if (typeof window === 'undefined') return;\n try {\n if (preference === 'system') window.localStorage.removeItem(THEME_STORAGE_KEY);\n else window.localStorage.setItem(THEME_STORAGE_KEY, preference);\n } catch {\n // Storage blocked: the choice still applies to this page view.\n }\n applyAttribute(preference);\n window.dispatchEvent(new Event(CHANGE_EVENT));\n}\n\n/** The theme in effect: the root attribute when set, otherwise the system's. */\nexport function resolveTheme(): ResolvedTheme {\n if (typeof document === 'undefined') return 'light';\n const forced = document.documentElement.getAttribute(THEME_ATTRIBUTE);\n if (forced === 'light' || forced === 'dark') return forced;\n return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';\n}\n\n/**\n * Put the stored choice on the root. `ThemeScript` does this before first\n * paint when it is server-rendered; this covers an app without it (or one that\n * inserts it on the client, where an inline script never runs). Idempotent.\n */\nfunction syncAttribute(): void {\n applyAttribute(readThemePreference());\n}\n\nfunction subscribePreference(onChange: () => void): () => void {\n syncAttribute();\n // Another tab changed the choice: follow it here too.\n const onStorage = (e: StorageEvent) => {\n if (e.key !== null && e.key !== THEME_STORAGE_KEY) return;\n applyAttribute(readThemePreference());\n onChange();\n };\n window.addEventListener(CHANGE_EVENT, onChange);\n window.addEventListener('storage', onStorage);\n return () => {\n window.removeEventListener(CHANGE_EVENT, onChange);\n window.removeEventListener('storage', onStorage);\n };\n}\n\nfunction subscribeResolved(onChange: () => void): () => void {\n // Watch first, then restore: the observer reports the restored attribute,\n // so a canvas surface hears about a stored choice applied on mount.\n const observer = new MutationObserver(onChange);\n observer.observe(document.documentElement, {\n attributes: true,\n attributeFilter: [THEME_ATTRIBUTE],\n });\n const media = window.matchMedia('(prefers-color-scheme: dark)');\n media.addEventListener('change', onChange);\n window.addEventListener(CHANGE_EVENT, onChange);\n syncAttribute();\n return () => {\n observer.disconnect();\n media.removeEventListener('change', onChange);\n window.removeEventListener(CHANGE_EVENT, onChange);\n };\n}\n\n/**\n * The reader's choice and a setter. Server render and hydration see\n * `'system'`; the stored choice arrives right after.\n */\nexport function useThemePreference(): [ThemePreference, (p: ThemePreference) => void] {\n const preference = React.useSyncExternalStore(\n subscribePreference,\n readThemePreference,\n () => 'system' as const,\n );\n return [preference, setThemePreference];\n}\n\n/**\n * The theme in effect, for surfaces that cannot read CSS variables (canvas,\n * WebGL maps). Follows the toggle and, under \"system\", the operating system.\n * Server render and hydration see `'light'`.\n */\nexport function useResolvedTheme(): ResolvedTheme {\n return React.useSyncExternalStore(subscribeResolved, resolveTheme, () => 'light' as const);\n}\n","import * as React from 'react';\nimport { themeInitScript } from './theme.js';\n\nexport interface ThemeScriptProps {\n /** Content-Security-Policy nonce, when the app sets one. */\n nonce?: string;\n}\n\n/**\n * Renders `themeInitScript` as an inline `<script>`, so a stored choice is on\n * the root before first paint. Use this from a server layout: this package is\n * a client bundle, so a server component cannot import the plain string, but\n * it can render this component. Put it in `<head>` and add\n * `suppressHydrationWarning` to `<html>` (the script changes its attributes\n * before React hydrates).\n */\nexport function ThemeScript({ nonce }: ThemeScriptProps) {\n return <script nonce={nonce} dangerouslySetInnerHTML={{ __html: themeInitScript }} />;\n}\n","import React, { useCallback, useEffect, useId, useRef, useState } from 'react';\nimport { CaptionLayer } from './CaptionLayer.js';\nimport { CAPTIONS_SCHEMA, paletteVar, type CaptionPage, type CaptionTrack } from './captions.js';\n\nexport interface CaptionedVideoProps {\n src: string;\n /** The release's poster frame: required, as the player shows it until the reader presses play (explanatory-video-carve-out, decision 2). */\n poster: string;\n /** The release's captions file (dataimago.video_captions.v1): pages, word timing, MathML. */\n captions: string;\n /** The release's WebVTT captions: the native track, and the text drawn if `captions` fails to load. */\n fallbackCaptions: string;\n /** The release's WebVTT chapters. */\n chapters?: string;\n /** A reduced-motion cut of the same video (same timing, so the same captions): played instead of `src` under `prefers-reduced-motion: reduce`. */\n reducedSrc?: string;\n /** The release's static storyboard: offered first, beside the video, under `prefers-reduced-motion: reduce` when there is no `reducedSrc`. */\n storyboard?: string;\n /** The video's accessible name. */\n title: string;\n /** BCP 47 language of the captions. */\n lang?: string;\n className?: string;\n style?: React.CSSProperties;\n}\n\n/** Where the reader's captions choice is kept (per browser). */\nexport const CAPTIONS_STORAGE_KEY = 'dataimago:video-captions';\n\nconst readCaptionsChoice = (): boolean => {\n try { return window.localStorage.getItem(CAPTIONS_STORAGE_KEY) !== 'off'; } catch { return true; }\n};\nconst writeCaptionsChoice = (on: boolean) => {\n try { window.localStorage.setItem(CAPTIONS_STORAGE_KEY, on ? 'on' : 'off'); } catch { /* private mode */ }\n};\n\nconst num = (x: unknown) => typeof x === 'number' && Number.isFinite(x);\nconst strings = (x: unknown) => Array.isArray(x) && x.every((y) => typeof y === 'string');\n\n/** A captions file the layer can draw; anything else takes the WebVTT fallback. */\nexport function isCaptionTrack(x: unknown): x is CaptionTrack {\n const t = x as CaptionTrack | null;\n if (!t || typeof t !== 'object' || t.schema !== CAPTIONS_SCHEMA) return false;\n const f = t.frame, st = t.style;\n if (!f || !num(f.width) || f.width <= 0 || !num(f.height) || f.height <= 0 || !num(f.fontSize) || f.fontSize <= 0 || !f.safe\n || !['top', 'right', 'bottom', 'left'].every((k) => num(f.safe[k as keyof typeof f.safe]))) return false;\n if (!st || !['editorial', 'frosted', 'boxed'].includes(st.treatment) || !num(st.weight) || !num(st.toneSeconds) || !num(st.lineHeight)) return false;\n if (st.colors !== undefined && !(st.colors && [st.colors.paper, st.colors.ink, st.colors.inkMute].every((x) => typeof x === 'string' && paletteVar(x)))) return false;\n // a file with no pages can't caption anything: take the VTT instead\n // pageAt binary-searches: pages must run forward, each start < end, none overlapping\n return Array.isArray(t.pages) && t.pages.length > 0 && t.pages.every((p, i) =>\n p && num(p.start) && num(p.end) && p.start < p.end && (i === 0 || p.start >= t.pages[i - 1]!.end)\n && strings(p.lines) && p.lines.length > 0 && Array.isArray(p.words) && p.words.length > 0\n && p.words.every((w) => w && typeof w.text === 'string' && num(w.at) && Number.isInteger(w.line) && w.line >= 0 && w.line < p.lines.length\n && (w.math === undefined || typeof w.math === 'string')));\n}\n\n/**\n * A WebVTT cue's lines as plain text. getCueAsHTML decodes the entities and drops the\n * <i>/<c> tags, but turns each line break into <br>, which textContent would lose, so the\n * fragment is walked and <br> read as a line break.\n */\nexport function cueLines(cue: VTTCue): string[] {\n let text = '';\n const walk = (n: Node) => {\n if (n.nodeType === Node.TEXT_NODE) text += n.textContent ?? '';\n else if ((n as Element).localName === 'br') text += '\\n';\n else n.childNodes.forEach(walk);\n };\n walk(cue.getCueAsHTML());\n return text.split('\\n').map((l) => l.trim()).filter(Boolean);\n}\n\n// The native controls show while paused and for a moment after the pointer moves;\n// meanwhile the captions keep clear of them, moving up only if their own place is lower.\nconst CONTROLS_HOLD_MS = 2500;\nconst CONTROLS_HEIGHT = 56;\n\n// The reader's motion preference, null until it is read. The caption tone treats null as\n// reduced (the safe side, as BrandAnimation does); with a reducedSrc, the video's source\n// waits for it, so a reduced-motion reader is never handed the full cut first.\nconst usePrefersReducedMotion = (): boolean | null => {\n const [reduced, setReduced] = useState<boolean | null>(null);\n useEffect(() => {\n const q = window.matchMedia?.('(prefers-reduced-motion: reduce)');\n if (!q) { setReduced(false); return; }\n setReduced(q.matches);\n const on = () => setReduced(q.matches);\n q.addEventListener('change', on);\n return () => q.removeEventListener('change', on);\n }, []);\n return reduced;\n};\n\n// the storyboard is the alternative the ADR asks for: it gets the same 48 px target as the buttons\nconst linkStyle: React.CSSProperties = {\n display: 'inline-flex', alignItems: 'center', justifyContent: 'center', minWidth: 48, minHeight: 48, padding: '0 8px',\n color: 'var(--color-palette-ink-900)', textUnderlineOffset: '0.2em',\n};\n\nconst videoOnlyFullscreen = () => typeof navigator !== 'undefined' && /iPhone|iPod/.test(navigator.userAgent);\n\nconst gateStyle: React.CSSProperties = {\n position: 'absolute', left: '50%', top: '50%', transform: 'translate(-50%, -50%)', maxWidth: 'min(90%, 26rem)',\n display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 10, padding: '14px 18px', textAlign: 'center',\n fontFamily: 'var(--font-family-sans)', fontSize: 15, lineHeight: 1.4,\n color: 'var(--color-palette-ink-900)', background: 'var(--color-palette-stone-50)',\n border: '1px solid var(--color-palette-ink-200)', borderRadius: 6,\n};\n\nconst buttonStyle: React.CSSProperties = {\n font: 'inherit', fontFamily: 'var(--font-family-sans)', fontWeight: 600, fontSize: 13, lineHeight: 1,\n color: 'var(--color-palette-paper-50)', background: 'color-mix(in srgb, var(--color-palette-ink-900) 72%, transparent)',\n border: '1px solid color-mix(in srgb, var(--color-palette-paper-50) 35%, transparent)', borderRadius: 4,\n padding: '6px 9px', cursor: 'pointer', pointerEvents: 'auto',\n // the house floor for touch targets ([[accessibility-beyond-compliance]]), as ThemeToggle\n minWidth: 48, minHeight: 48,\n};\n\n// Chrome keeps drawing its fullscreen button, disabled, under controlsList=\"nofullscreen\",\n// a few centimetres from the player's own, and its own captions button would switch the\n// native track on under the drawn captions. Two rules hide them on these players only.\n// They go in a constructed stylesheet, which a site's CSP does not treat as an inline <style>.\nconst NATIVE_FULLSCREEN_RULE = [\n 'video[data-dataimago-captioned-video]::-webkit-media-controls-fullscreen-button { display: none; }',\n 'video[data-dataimago-captioned-video]::-webkit-media-controls-toggle-closed-captions-button { display: none; }',\n].join('\\n');\nlet nativeRuleAdded = false;\nfunction hideNativeFullscreenButton() {\n if (nativeRuleAdded || typeof document === 'undefined' || !('adoptedStyleSheets' in document)) return;\n try {\n const sheet = new CSSStyleSheet();\n sheet.replaceSync(NATIVE_FULLSCREEN_RULE);\n document.adoptedStyleSheets = [...document.adoptedStyleSheets, sheet];\n nativeRuleAdded = true;\n } catch { /* a browser without the pseudo-element rejects the rule: nothing to hide */ }\n}\n\n/**\n * A video with the dataimago caption treatment drawn over it: the foundry's fonts,\n * word tone and mathematics, from the release's captions file. The native WebVTT\n * track stays hidden underneath, for assistive technology and as the fallback text.\n * Fullscreen takes the whole player, so the captions come along.\n */\nexport const CaptionedVideo: React.FC<CaptionedVideoProps> = ({\n src, poster, captions, fallbackCaptions, chapters, reducedSrc, storyboard, title, lang = 'en', className, style,\n}) => {\n const wrapRef = useRef<HTMLDivElement>(null);\n const stageRef = useRef<HTMLDivElement>(null);\n const videoRef = useRef<HTMLVideoElement>(null);\n const trackRef = useRef<HTMLTrackElement>(null);\n const chaptersRef = useRef<HTMLTrackElement>(null);\n const [track, setTrack] = useState<CaptionTrack | null>(null);\n const [failed, setFailed] = useState(false);\n const [cue, setCue] = useState<CaptionPage | null>(null);\n const [time, setTime] = useState(0);\n const [width, setWidth] = useState(0);\n const [on, setOn] = useState(true);\n const [full, setFull] = useState(false);\n // paused until the element says otherwise (autoplay may be blocked)\n const [paused, setPaused] = useState(true);\n const [active, setActive] = useState(false);\n const [focusWithin, setFocusWithin] = useState(false);\n const prefersReduced = usePrefersReducedMotion();\n const reducedMotion = prefersReduced !== false;\n // explanatory-video-carve-out, decision 2: under reduced motion the reduced-motion cut plays,\n // or, with none, the reader is told the video moves and offered the storyboard first; the\n // full cut stays theirs to choose. Nothing plays until they press play, either way.\n const [chosen, setChosen] = useState(false);\n const noticeId = useId();\n const gated = prefersReduced === true && !reducedSrc && !chosen;\n // with a choice of cut, the source waits for the preference; with none, src is there from the first paint (no JS too)\n const videoSrc = prefersReduced && reducedSrc ? reducedSrc : prefersReduced === null && reducedSrc ? undefined : src;\n\n useEffect(() => setOn(readCaptionsChoice()), []);\n\n // The captions file: only the URL given, same origin, no other request.\n useEffect(() => {\n let live = true;\n setTrack(null); setFailed(false);\n fetch(captions, { credentials: 'same-origin' })\n .then((r) => (r.ok ? r.json() : Promise.reject(new Error(String(r.status)))))\n .then((j: unknown) => { if (!live) return; if (isCaptionTrack(j)) setTrack(j); else setFailed(true); })\n .catch(() => { if (live) setFailed(true); });\n return () => { live = false; };\n }, [captions]);\n\n // The native track is hidden, not disabled, so its cues still change: the fallback text.\n // Subscribe first, then switch the mode, then read the cue already active (a cached\n // track can change before any listener is attached), and again once the file loads.\n useEffect(() => {\n const el = trackRef.current, t = el?.track;\n if (!el || !t) return;\n const change = () => {\n const c = t.activeCues?.[0] as VTTCue | undefined;\n const lines = c ? cueLines(c) : [];\n setCue(c ? { start: c.startTime, end: c.endTime, lines, words: lines.flatMap((l, line) => l.split(' ').map((w) => ({ text: w, at: c.startTime, line }))) } : null);\n };\n t.addEventListener('cuechange', change);\n el.addEventListener('load', change);\n t.mode = nativeViewRef.current && onRef.current ? 'showing' : 'hidden';\n change();\n return () => { t.removeEventListener('cuechange', change); el.removeEventListener('load', change); };\n }, [fallbackCaptions]);\n\n // The clock: every frame while the element plays, once on any other change.\n useEffect(() => {\n const v = videoRef.current;\n if (!v) return;\n let raf = 0;\n // the element is the truth: playing runs the clock every frame, anything else stops it\n const tick = () => { setTime(v.currentTime); raf = requestAnimationFrame(tick); };\n const sync = () => {\n setPaused(v.paused);\n setTime(v.currentTime);\n cancelAnimationFrame(raf);\n if (!v.paused && !v.ended) raf = requestAnimationFrame(tick);\n };\n // seeking/timeupdate follow a scrub while paused; emptied/loadstart a new src\n const events = ['play', 'playing', 'pause', 'seeking', 'seeked', 'timeupdate', 'ended', 'emptied', 'loadstart', 'loadedmetadata'] as const;\n for (const e of events) v.addEventListener(e, sync);\n sync();\n return () => { cancelAnimationFrame(raf); for (const e of events) v.removeEventListener(e, sync); };\n }, [videoSrc]);\n\n // Size: the captions keep the share of the frame they have in the burned-in cut.\n useEffect(() => {\n const el = stageRef.current;\n if (!el || typeof ResizeObserver === 'undefined') return;\n const ro = new ResizeObserver(([e]) => setWidth(e!.contentRect.width));\n ro.observe(el);\n return () => ro.disconnect();\n }, []);\n\n // Fullscreen of the player keeps the drawn captions. A native view of the bare <video>\n // can't show them: its fullscreen (a browser's own control, iOS Safari) or\n // picture-in-picture. There the native track shows instead (Safari draws it in PiP;\n // Chrome's PiP draws no text tracks for any page).\n const [nativeView, setNativeView] = useState(false);\n const nativeViewRef = useRef(false), onRef = useRef(true);\n nativeViewRef.current = nativeView; onRef.current = on;\n useEffect(() => {\n const v = videoRef.current;\n if (!v) return;\n let fs = false, pip = false;\n const update = () => setNativeView(fs || pip);\n const change = () => { setFull(document.fullscreenElement === wrapRef.current); fs = document.fullscreenElement === v; update(); };\n const flag = (set: (x: boolean) => void, x: boolean) => () => { set(x); update(); };\n const handlers: [EventTarget, string, () => void][] = [\n [document, 'fullscreenchange', change],\n [v, 'webkitbeginfullscreen', flag((x) => { fs = x; }, true)],\n [v, 'webkitendfullscreen', flag((x) => { fs = x; }, false)],\n [v, 'enterpictureinpicture', flag((x) => { pip = x; }, true)],\n [v, 'leavepictureinpicture', flag((x) => { pip = x; }, false)],\n ];\n for (const [t, e, h] of handlers) t.addEventListener(e, h);\n return () => { for (const [t, e, h] of handlers) t.removeEventListener(e, h); };\n }, []);\n // The native captions track shows only in those native views; a browser's own captions\n // control (Firefox, Safari) can't switch it on under the drawn captions.\n useEffect(() => {\n const v = videoRef.current;\n if (!v) return;\n const want = nativeView && on ? 'showing' : 'hidden';\n // read the track each time: a new fallbackCaptions src replaces its cues\n const hold = () => { const t = trackRef.current?.track; if (t && t.mode !== want) t.mode = want; };\n hold();\n v.textTracks.addEventListener('change', hold);\n trackRef.current?.addEventListener('load', hold);\n const el = trackRef.current;\n return () => { v.textTracks.removeEventListener('change', hold); el?.removeEventListener('load', hold); };\n }, [nativeView, on, fallbackCaptions]);\n\n useEffect(hideNativeFullscreenButton, []);\n\n // A track left `disabled` is never loaded: the chapters stay `hidden`, so their cues are\n // there for the browser and for a chapter menu (not drawn by this version).\n useEffect(() => {\n const t = chaptersRef.current?.track;\n if (t) t.mode = 'hidden';\n }, [chapters]);\n\n const holdRef = useRef<number>(0);\n const wake = useCallback(() => {\n setActive(true);\n window.clearTimeout(holdRef.current);\n holdRef.current = window.setTimeout(() => setActive(false), CONTROLS_HOLD_MS);\n }, []);\n useEffect(() => () => window.clearTimeout(holdRef.current), []);\n // a tap that starts playback moves no pointer: playing wakes the controls too\n useEffect(() => {\n const v = videoRef.current;\n if (!v) return;\n v.addEventListener('play', wake);\n return () => v.removeEventListener('play', wake);\n }, [wake]);\n\n const toggleCaptions = useCallback(() => setOn((x) => { writeCaptionsChoice(!x); return !x; }), []);\n const toggleFullscreen = useCallback(() => {\n const wrap = wrapRef.current;\n const v = videoRef.current as (HTMLVideoElement & { webkitEnterFullscreen?: () => void; webkitExitFullscreen?: () => void; webkitDisplayingFullscreen?: boolean }) | null;\n // only this player's fullscreen is ours to leave; another surface's stays as it is\n if (document.fullscreenElement === wrap) { void document.exitFullscreen(); return; }\n if (v?.webkitDisplayingFullscreen) { v.webkitExitFullscreen?.(); return; }\n // where only a video can go fullscreen, the video's own, called within the tap: from a\n // rejected promise the tap no longer counts and it would be refused. iPhone Safari has the\n // Fullscreen API (16.4+) yet refuses it for anything but a video, so it is named; iPadOS\n // can take the player, and reports itself as a Mac.\n if (!wrap?.requestFullscreen || !document.fullscreenEnabled || videoOnlyFullscreen()) { v?.webkitEnterFullscreen?.(); return; }\n wrap.requestFullscreen().catch(() => v?.webkitEnterFullscreen?.());\n }, []);\n const onKey = (e: React.KeyboardEvent) => {\n // the CC and Full buttons advertise c and f, so only text entry keeps its keys\n const t = e.target as HTMLElement;\n if (e.altKey || e.ctrlKey || e.metaKey || t.isContentEditable || t instanceof HTMLInputElement || t instanceof HTMLTextAreaElement || t instanceof HTMLSelectElement) return;\n if (e.key === 'c' || e.key === 'C') { e.preventDefault(); toggleCaptions(); }\n if (e.key === 'f' || e.key === 'F') { e.preventDefault(); toggleFullscreen(); }\n };\n\n const controlsUp = paused || active || focusWithin;\n // a native view (PiP, the bare video's fullscreen) shows the native track; nothing is drawn here\n // the VTT cue covers the time before the JSON arrives (or if it never does), in the same treatment\n const showLayer = on && width > 0 && !nativeView && (track !== null || cue !== null || failed);\n // the WebVTT fallback speaks the player's language\n const layerTrack = track ?? { ...FALLBACK_FRAME, lang };\n const frame = layerTrack.frame;\n\n return (\n <div\n ref={wrapRef}\n className={className}\n onPointerMove={wake}\n onPointerDown={wake}\n onFocus={() => { setFocusWithin(true); wake(); }}\n onBlur={(e) => { if (!e.currentTarget.contains(e.relatedTarget as Node | null)) setFocusWithin(false); }}\n onKeyDown={onKey}\n style={{\n position: 'relative', display: full ? 'flex' : 'block', alignItems: 'center', justifyContent: 'center',\n background: full ? 'var(--color-palette-ink-900)' : undefined, ...style,\n }}\n >\n <div ref={stageRef} style={{ position: 'relative', width: full ? `min(100vw, calc(100vh * ${frame.width / frame.height}))` : '100%', aspectRatio: `${frame.width} / ${frame.height}` }}>\n <video\n ref={videoRef}\n src={videoSrc}\n poster={poster}\n controls={!gated}\n controlsList=\"nofullscreen\"\n data-dataimago-captioned-video=\"\"\n playsInline\n preload=\"metadata\"\n aria-label={title}\n // while the notice asks first, the reader's choice is there, not on a video without controls\n aria-hidden={gated || undefined}\n style={{ display: 'block', width: '100%', height: '100%' }}\n >\n {/* default: before the script runs (first paint, no JS) the native player captions the video; the effects then hide it under the drawn captions */}\n <track ref={trackRef} kind=\"captions\" src={fallbackCaptions} srcLang={lang} label=\"Captions\" default />\n {chapters ? <track ref={chaptersRef} kind=\"chapters\" src={chapters} srcLang={lang} label=\"Chapters\" /> : null}\n </video>\n {showLayer ? (\n <CaptionLayer\n track={layerTrack}\n time={time}\n width={width}\n reducedMotion={reducedMotion}\n clearance={controlsUp ? CONTROLS_HEIGHT : 0}\n page={track ? undefined : cue}\n />\n ) : null}\n {gated ? (\n <div role=\"group\" aria-labelledby={noticeId} style={gateStyle}>\n <p id={noticeId} style={{ margin: 0 }}>This video is animated throughout.</p>\n <button\n type=\"button\"\n style={{ ...buttonStyle, pointerEvents: 'auto' }}\n onClick={() => { setChosen(true); void videoRef.current?.play().catch(() => { /* the native controls take over */ }); }}\n >\n Play the video\n </button>\n {storyboard ? <a href={storyboard} style={linkStyle}>View the storyboard instead</a> : null}\n </div>\n ) : null}\n <div style={{\n position: 'absolute', top: 8, right: 8, display: gated ? 'none' : 'flex', gap: 6, pointerEvents: 'none',\n // hidden once faded: an invisible button must not take a click or a Tab stop\n opacity: controlsUp ? 1 : 0, visibility: controlsUp ? 'visible' : 'hidden',\n transition: reducedMotion ? undefined : controlsUp ? 'opacity 200ms' : 'opacity 200ms, visibility 0s linear 200ms',\n }}>\n <button type=\"button\" style={buttonStyle} aria-pressed={on} aria-label=\"CC (captions)\" title=\"Captions (c)\" onClick={toggleCaptions} onFocus={wake}>\n CC\n </button>\n <button type=\"button\" style={buttonStyle} aria-pressed={full} aria-label={full ? 'Exit full screen' : 'Full screen'} title=\"Full screen (f)\" onClick={toggleFullscreen} onFocus={wake}>\n {full ? 'Exit' : 'Full'}\n </button>\n </div>\n </div>\n </div>\n );\n};\n\n// The WebVTT fallback has no layout of its own: it takes the dataimago-v1 16:9 frame.\nconst FALLBACK_FRAME: CaptionTrack = {\n schema: CAPTIONS_SCHEMA, work: '', version: '', lang: 'en', pages: [],\n style: { profile: 'dataimago-v1', treatment: 'frosted', weight: 500, toneSeconds: 0, lineHeight: 1.28 },\n frame: { width: 1920, height: 1080, fontSize: 44, safe: { top: 72, right: 96, bottom: 72, left: 96 } },\n};\n","import React, { useLayoutEffect, useRef } from 'react';\nimport { captionLook, pageAt, paletteVar, splitMath, toneColor, wordTone, type CaptionPage, type CaptionTrack } from './captions.js';\nimport { safeMathML } from './mathml.js';\n\n// The video's paper is light in both site themes, so captions take the palette the\n// foundry burns in, never --color-content-*: the track's own colour tokens when it carries\n// them, else dataimago-v1's (ink 900, ink 500, stone 50, the card colour).\nconst INK = 'var(--color-palette-ink-900)';\nconst INK_MUTE = 'var(--color-palette-ink-500)';\nconst PAPER = 'var(--color-palette-stone-50)';\n\nexport interface CaptionLayerProps {\n track: CaptionTrack;\n /** Seconds into the video. */\n time: number;\n /** The video's displayed width in CSS pixels; size and insets scale from the track's canvas. */\n width: number;\n /**\n * Show each page in full ink, as the foundry's reduced-motion render does. Defaults to\n * true, the safe side; pass the reader's `prefers-reduced-motion` (CaptionedVideo does).\n */\n reducedMotion?: boolean;\n /**\n * Keep the captions at least this far above the bottom edge, in CSS pixels (the\n * player's controls). They move up only when their own place would sit lower.\n */\n clearance?: number;\n /** A page to show instead of the track's (the WebVTT fallback, already in full ink). */\n page?: CaptionPage | null;\n}\n\n/**\n * One `$…$` span: the foundry's MathML, rebuilt from an allow-list. The span has no\n * React children, so React never owns a node the effect replaces; the TeX shows as\n * text if the MathML can't be used.\n */\nconst MathSpan: React.FC<{ markup: string; tex: string }> = ({ markup, tex }) => {\n const ref = useRef<HTMLSpanElement>(null);\n useLayoutEffect(() => {\n const host = ref.current;\n if (!host) return;\n const math = safeMathML(markup, host.ownerDocument) as HTMLElement | null;\n if (!math) { host.textContent = tex; return; }\n math.style.fontFamily = 'var(--font-family-math)';\n math.style.fontStyle = 'normal';\n host.replaceChildren(math);\n }, [markup, tex]);\n return <span ref={ref} style={{ whiteSpace: 'nowrap' }} />;\n};\n\n/**\n * The captions over a video, in the foundry's treatment, at time `time`. Pure\n * presentation: the caller supplies the clock and the size. The drawn layer is hidden\n * from assistive technology; the current page is also present as visually hidden plain\n * text, not a live region, so a braille or screen-reader user can find it without every\n * line being spoken over the narration.\n */\nexport const CaptionLayer: React.FC<CaptionLayerProps> = ({ track, time, width, reducedMotion = true, clearance = 0, page: given }) => {\n const page = given === undefined ? pageAt(track.pages, time) : given;\n const scale = width / track.frame.width;\n const size = track.frame.fontSize * scale;\n const { safe } = track.frame;\n const c = track.style.colors;\n const ink = (c && paletteVar(c.ink)) ?? INK, inkMute = (c && paletteVar(c.inkMute)) ?? INK_MUTE, paper = (c && paletteVar(c.paper)) ?? PAPER;\n const look = captionLook(track.style.treatment, {\n size, scale, weight: track.style.weight, lineHeight: track.style.lineHeight,\n family: 'var(--font-family-sans)', ink, paper,\n });\n const toned = look.toned && !reducedMotion && given === undefined;\n const lines = page ? page.lines.map((_, li) => page.words.filter((w) => w.line === li)) : [];\n const plain = page ? page.lines.map((l) => l.replace(/\\$([^$\\s]+)\\$/g, '$1')).join(' ') : '';\n return (\n <>\n <span data-caption-text=\"\" lang={track.lang || undefined} style={{ position: 'absolute', width: 1, height: 1, margin: -1, padding: 0, overflow: 'hidden', clip: 'rect(0 0 0 0)', clipPath: 'inset(50%)', whiteSpace: 'nowrap', border: 0 }}>{plain}</span>\n <div aria-hidden=\"true\" style={{ position: 'absolute', inset: 0, pointerEvents: 'none', overflow: 'hidden' }}>\n {page ? (\n <div style={{\n position: 'absolute', left: safe.left * scale, right: safe.right * scale,\n bottom: Math.max(safe.bottom * scale + look.lift, clearance),\n display: 'flex', justifyContent: 'center',\n }}>\n <div style={{ ...look.panel, ...look.text }}>\n {lines.map((ws, li) => (\n <div key={li}>\n {ws.map((w, wi) => {\n const m = splitMath(w.text);\n return (\n <span key={wi} style={look.toned ? { color: toned ? toneColor(wordTone(w.at, time, track.style.toneSeconds), ink, inkMute) : ink } : undefined}>\n {m && w.math ? <>{m.before}<MathSpan markup={w.math} tex={m.tex} />{m.after}</> : w.text}\n {wi < ws.length - 1 ? ' ' : ''}\n </span>\n );\n })}\n </div>\n ))}\n </div>\n </div>\n ) : null}\n </div>\n </>\n );\n};\n","// The caption treatment of the web player (CaptionedVideo), written to be shared with\n// the video-foundry's burned-in captions so the two can't drift apart. Pure: no React,\n// no DOM. The values match WorkVideo.tsx's Captions at scale 1.\n//\n// TODO(#407): the foundry's Captions (tools/video-foundry/src/remotion/WorkVideo.tsx)\n// still inlines this treatment. It imports captionLook, wordTone and toneColor from\n// here once this module is on main; until then a change here must be made there too.\n//\n// Line breaking is not here. The foundry breaks each page once, from the voice's\n// timing, and the page travels in the captions file as it was burned in.\n\n/** The captions file a video release carries beside its WebVTT fallback. */\nexport const CAPTIONS_SCHEMA = 'dataimago.video_captions.v1';\n\nexport type CaptionTreatment = 'editorial' | 'frosted' | 'boxed';\n\nexport interface CaptionWord {\n /** The word as the script spells it; inline math stays a `$…$` span. */\n text: string;\n /** Spoken start, in the page's time unit: the word tones from inkMute to ink from here. */\n at: number;\n /** The line of the page the word sits on. */\n line: number;\n /** MathML for the word's `$…$` span, rendered by the foundry (Temml) at export. */\n math?: string;\n}\n\nexport interface CaptionPage {\n start: number;\n end: number;\n lines: string[];\n words: CaptionWord[];\n}\n\nexport interface CaptionTrack {\n schema: typeof CAPTIONS_SCHEMA;\n work: string;\n version: string;\n lang: string;\n style: {\n profile: string;\n treatment: CaptionTreatment;\n /** Font weight of the caption text (400 when boxed). */\n weight: number;\n /** How long a word takes to tone from inkMute to ink, in seconds. */\n toneSeconds: number;\n lineHeight: number;\n /** The profile's colour tokens (`color.palette.<scale>.<step>`); the player maps them to CSS variables. */\n colors?: { paper: string; ink: string; inkMute: string };\n };\n /** The canvas the captions were laid out on, in pixels: scale everything by displayed width ÷ width. */\n frame: {\n width: number;\n height: number;\n fontSize: number;\n safe: { top: number; right: number; bottom: number; left: number };\n };\n /** In seconds from the start of the video, in order, never overlapping. */\n pages: CaptionPage[];\n}\n\n/** The page on screen at time t (start ≤ t < end), if any. Pages must be in order. */\nexport function pageAt<P extends { start: number; end: number }>(pages: readonly P[], t: number): P | undefined {\n let lo = 0, hi = pages.length - 1;\n while (lo <= hi) {\n const mid = (lo + hi) >> 1, p = pages[mid]!;\n if (t < p.start) hi = mid - 1;\n else if (t >= p.end) lo = mid + 1;\n else return p;\n }\n return undefined;\n}\n\n/** How far a word has toned toward ink at time t: 0 before it is spoken, 1 once it has settled. */\nexport function wordTone(at: number, t: number, span: number): number {\n if (span <= 0) return t >= at ? 1 : 0;\n return Math.min(1, Math.max(0, (t - at) / span));\n}\n\n/** The colour for a tone between inkMute (0) and ink (1). */\nexport function toneColor(tone: number, ink: string, inkMute: string): string {\n if (tone >= 1) return ink;\n if (tone <= 0) return inkMute;\n return `color-mix(in srgb, ${ink} ${Math.round(tone * 100)}%, ${inkMute})`;\n}\n\n/** A word's text split around its `$…$` span, or null when it carries no math. */\nexport function splitMath(text: string): { before: string; tex: string; after: string } | null {\n const m = text.match(/^(.*?)\\$([^$\\s]+)\\$(.*)$/);\n return m ? { before: m[1]!, tex: m[2]!, after: m[3]! } : null;\n}\n\n/** A palette token path as a CSS variable (`color.palette.stone.50` → `var(--color-palette-stone-50)`), or null if it is not one. */\nexport function paletteVar(token: string): string | null {\n return /^color\\.palette\\.[a-z]+\\.\\d{2,3}$/.test(token) ? `var(--${token.replace(/\\./g, '-')})` : null;\n}\n\nexport type CaptionStyle = Record<string, string | number>;\n\nexport interface CaptionLook {\n /** The panel around the lines. */\n panel: CaptionStyle;\n /** The text block: family, weight, size, line height. */\n text: CaptionStyle;\n /** Extra lift above the safe area, in pixels, so a panel's soft shadow stays inside it too. */\n lift: number;\n /** Whether words tone from inkMute to ink (boxed captions are one colour). */\n toned: boolean;\n}\n\n/**\n * The treatment at one size. `scale` multiplies the profile's fixed pixel measures\n * (blur, border, radius on a boxed panel) and is 1 on the foundry's canvas.\n */\nexport function captionLook(\n treatment: CaptionTreatment,\n o: { size: number; scale: number; weight: number; lineHeight: number; family: string; ink: string; paper: string },\n): CaptionLook {\n const { size, scale, ink, paper } = o;\n const halo = [2, 6, 14, 24].map((r) => `0 0 ${r * scale}px ${paper}`).join(', ');\n const panel: CaptionStyle =\n treatment === 'boxed' ? { background: ink, padding: '0.35em 0.7em', borderRadius: 4 * scale }\n : treatment === 'frosted' ? {\n background: `color-mix(in srgb, ${paper} 82%, transparent)`,\n backdropFilter: `blur(${14 * scale}px)`,\n WebkitBackdropFilter: `blur(${14 * scale}px)`,\n padding: '0.5em 0.95em',\n borderRadius: size * 0.6,\n boxShadow: `0 ${size * 0.15}px ${size * 0.8}px color-mix(in srgb, ${ink} 10%, transparent)`,\n border: `${Math.max(1, scale)}px solid color-mix(in srgb, ${ink} 8%, transparent)`,\n }\n : { padding: '0.2em 0.4em', textShadow: halo };\n const text: CaptionStyle = {\n fontFamily: o.family,\n fontWeight: treatment === 'boxed' ? 400 : o.weight,\n fontSize: size,\n lineHeight: o.lineHeight,\n textAlign: 'center',\n letterSpacing: treatment === 'boxed' ? 0 : '0.005em',\n ...(treatment === 'boxed' ? { color: paper } : {}),\n };\n return { panel, text, lift: treatment === 'frosted' ? Math.round(size * 0.95) : 0, toned: treatment !== 'boxed' };\n}\n","// MathML from a captions file, rebuilt element by element from an allow-list, so a\n// data file can never put script, links, styles or foreign elements into the page. The\n// browser lays the result out natively (MathML Core) in --font-family-math.\nconst MATHML_NS = 'http://www.w3.org/1998/Math/MathML';\n\nconst ELEMENTS = new Set([\n 'math', 'mrow', 'mi', 'mn', 'mo', 'ms', 'mtext', 'mspace', 'msub', 'msup', 'msubsup',\n 'mfrac', 'msqrt', 'mroot', 'mover', 'munder', 'munderover', 'mtable', 'mtr', 'mtd',\n 'mpadded', 'mphantom', 'mstyle', 'menclose', 'semantics', 'annotation',\n]);\n\n// No `style` and no `class`: a style could position the span anywhere on the page, and a\n// class could pick up the site's own CSS. Temml uses both only for accents and fonts the\n// captions don't need; the browser's MathML layout and --font-family-math set the rest.\nconst ATTRIBUTES = new Set([\n 'display', 'mathvariant', 'stretchy', 'fence', 'separator', 'form', 'lspace', 'rspace',\n 'accent', 'accentunder', 'movablelimits', 'largeop', 'symmetric', 'minsize', 'maxsize',\n 'width', 'height', 'depth', 'voffset', 'linethickness', 'columnalign', 'rowalign',\n 'columnspacing', 'rowspacing', 'scriptlevel', 'displaystyle', 'notation', 'encoding',\n]);\n\nfunction rebuild(node: Node, doc: Document): Node | null {\n if (node.nodeType === Node.TEXT_NODE) return doc.createTextNode(node.textContent ?? '');\n if (node.nodeType !== Node.ELEMENT_NODE) return null;\n const el = node as Element;\n const tag = el.localName;\n if (el.namespaceURI !== MATHML_NS || !ELEMENTS.has(tag)) return null;\n // the TeX source rides in an annotation; the rendered tree is what is read and shown\n if (tag === 'annotation') return null;\n const out = doc.createElementNS(MATHML_NS, tag);\n for (const a of Array.from(el.attributes)) {\n if (!ATTRIBUTES.has(a.name)) continue;\n out.setAttribute(a.name, a.value);\n }\n for (const child of Array.from(el.childNodes)) {\n const c = rebuild(child, doc);\n if (c) out.appendChild(c);\n }\n return out;\n}\n\nconst cache = new Map<string, Element | null>();\n\n/** A clean <math> element for the markup, or null when it holds no usable MathML. */\nexport function safeMathML(markup: string, doc: Document = document): Element | null {\n if (!cache.has(markup)) {\n const parsed = new DOMParser().parseFromString(`<!doctype html><body>${markup}`, 'text/html');\n const root = parsed.body.firstElementChild;\n const math = root && root.localName === 'math' ? rebuild(root, doc) : null;\n cache.set(markup, math as Element | null);\n }\n const hit = cache.get(markup);\n return hit ? (hit.cloneNode(true) as Element) : null;\n}\n"],"mappings":"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","names":["Button","jsx","jsx","jsxs","jsx","jsxs","jsx","jsx","jsxs","React","jsx","React","jsx","usePrefersReducedMotion","React","React","jsx","jsxs","jsx","useEffect","useRef","useState","Fragment","jsx","jsxs","jsx","jsxs","x","usePrefersReducedMotion","useState","useEffect","useRef"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dataimago/ui",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
3
|
+
"version": "0.1.0-alpha.43",
|
|
4
4
|
"description": "React components for the dataimago ethical AI design system",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -29,17 +29,18 @@
|
|
|
29
29
|
"README.md"
|
|
30
30
|
],
|
|
31
31
|
"peerDependencies": {
|
|
32
|
+
"@dataimago/brand": "^0.1.0-alpha.0",
|
|
32
33
|
"@dataimago/css": "^0.1.0-alpha.0",
|
|
33
34
|
"@dataimago/tokens": "^0.1.0-alpha.0",
|
|
34
35
|
"react": ">=18",
|
|
35
36
|
"react-dom": ">=18"
|
|
36
37
|
},
|
|
37
38
|
"devDependencies": {
|
|
38
|
-
"@storybook/addon-a11y": "^10.
|
|
39
|
-
"@storybook/addon-docs": "^10.
|
|
39
|
+
"@storybook/addon-a11y": "^10.4.2",
|
|
40
|
+
"@storybook/addon-docs": "^10.4.2",
|
|
40
41
|
"@storybook/addon-mcp": "^0.6.0",
|
|
41
|
-
"@storybook/addon-vitest": "^10.
|
|
42
|
-
"@storybook/react-vite": "^10.
|
|
42
|
+
"@storybook/addon-vitest": "^10.4.2",
|
|
43
|
+
"@storybook/react-vite": "^10.4.2",
|
|
43
44
|
"@types/react": "^18.3.0",
|
|
44
45
|
"@types/react-dom": "^18.3.0",
|
|
45
46
|
"@vitest/browser-playwright": "^4.1.5",
|
|
@@ -47,12 +48,13 @@
|
|
|
47
48
|
"playwright": "^1.59.1",
|
|
48
49
|
"react": "^18.3.1",
|
|
49
50
|
"react-dom": "^18.3.1",
|
|
50
|
-
"storybook": "^10.
|
|
51
|
+
"storybook": "^10.4.2",
|
|
51
52
|
"tsup": "^8.3.0",
|
|
52
53
|
"typescript": "^5.6.0",
|
|
53
54
|
"vitest": "^4.1.5",
|
|
54
|
-
"@dataimago/
|
|
55
|
-
"@dataimago/
|
|
55
|
+
"@dataimago/brand": "^0.1.0-alpha.8",
|
|
56
|
+
"@dataimago/css": "^0.1.0-alpha.41",
|
|
57
|
+
"@dataimago/tokens": "^0.1.0-alpha.33"
|
|
56
58
|
},
|
|
57
59
|
"keywords": [
|
|
58
60
|
"react",
|
|
@@ -64,6 +66,7 @@
|
|
|
64
66
|
"build": "tsup",
|
|
65
67
|
"dev": "tsup --watch",
|
|
66
68
|
"storybook": "storybook dev -p 6006",
|
|
67
|
-
"build-storybook": "storybook build"
|
|
69
|
+
"build-storybook": "storybook build",
|
|
70
|
+
"test-storybook": "vitest run --project=storybook"
|
|
68
71
|
}
|
|
69
72
|
}
|