@opendata-ai/openchart-vue 8.0.0-rc.3 → 8.0.0-rc.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +5 -11
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/styles.css.map +1 -1
- package/package.json +4 -4
- package/src/Map.ts +8 -10
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { BarListSpec, ThemeConfig, DarkMode, ChartSpec, LayerSpec, GraphSpec, ElementRef, MarkEvent, Annotation, TextAnnotation, AnnotationOffset, ElementEdit, MapSpec, ChartLayout, TableSpec, SortState, SankeySpec, TileMapSpec, VizSpec } from '@opendata-ai/openchart-core';
|
|
2
2
|
export * from '@opendata-ai/openchart-core';
|
|
3
|
-
import { MountOptions, ChartInstance, GraphInstance, TableInstance, TableState, TableMountOptions } from '@opendata-ai/openchart-vanilla';
|
|
3
|
+
import { MountOptions, ChartInstance, GraphInstance, TableInstance, TableState, TableMountOptions, MapMarkEvent } from '@opendata-ai/openchart-vanilla';
|
|
4
4
|
export { JPGExportOptions, PNGExportOptions, exportCSV, exportJPG, exportPNG, exportSVG } from '@opendata-ai/openchart-vanilla';
|
|
5
5
|
export { ChartRenderer, CompileResult, CompiledGraphEdge, CompiledGraphNode, GraphCompilation, NormalizedBarListSpec, NormalizedChartSpec, NormalizedChrome, NormalizedGraphSpec, NormalizedMapSpec, NormalizedSankeySpec, NormalizedSpec, NormalizedTableSpec, SimulationConfig, ValidationError, ValidationErrorCode, ValidationResult, clearRenderers, compile, compileBarList, compileChart, compileGraph, compileMap, compileSankey, compileTable, getChartRenderer, normalizeSpec, registerChartRenderer, validateSpec } from '@opendata-ai/openchart-engine';
|
|
6
6
|
import * as vue from 'vue';
|
|
@@ -606,12 +606,6 @@ declare const Graph: vue.DefineComponent<vue.ExtractPropTypes<{
|
|
|
606
606
|
style: string | CSSProperties;
|
|
607
607
|
}, {}, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
|
|
608
608
|
|
|
609
|
-
type MapFeatureEvent = {
|
|
610
|
-
id: string | number;
|
|
611
|
-
name?: string;
|
|
612
|
-
data: Record<string, unknown> | null;
|
|
613
|
-
};
|
|
614
|
-
|
|
615
609
|
interface MapProps {
|
|
616
610
|
spec: MapSpec;
|
|
617
611
|
theme?: ThemeConfig;
|
|
@@ -643,8 +637,8 @@ declare const GeoMap: vue.DefineComponent<vue.ExtractPropTypes<{
|
|
|
643
637
|
}>, () => vue.VNode<vue.RendererNode, vue.RendererElement, {
|
|
644
638
|
[key: string]: any;
|
|
645
639
|
}>, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {
|
|
646
|
-
'mark-click': (_event:
|
|
647
|
-
'mark-hover': (_event:
|
|
640
|
+
'mark-click': (_event: MapMarkEvent) => true;
|
|
641
|
+
'mark-hover': (_event: MapMarkEvent | null) => true;
|
|
648
642
|
}, string, vue.PublicProps, Readonly<vue.ExtractPropTypes<{
|
|
649
643
|
spec: {
|
|
650
644
|
type: PropType<MapSpec>;
|
|
@@ -667,8 +661,8 @@ declare const GeoMap: vue.DefineComponent<vue.ExtractPropTypes<{
|
|
|
667
661
|
default: undefined;
|
|
668
662
|
};
|
|
669
663
|
}>> & Readonly<{
|
|
670
|
-
"onMark-click"?: ((_event:
|
|
671
|
-
"onMark-hover"?: ((_event:
|
|
664
|
+
"onMark-click"?: ((_event: MapMarkEvent) => any) | undefined;
|
|
665
|
+
"onMark-hover"?: ((_event: MapMarkEvent | null) => any) | undefined;
|
|
672
666
|
}>, {
|
|
673
667
|
theme: ThemeConfig;
|
|
674
668
|
darkMode: DarkMode;
|
package/dist/index.js
CHANGED
|
@@ -966,7 +966,9 @@ var Graph = defineComponent5({
|
|
|
966
966
|
});
|
|
967
967
|
|
|
968
968
|
// src/Map.ts
|
|
969
|
-
import {
|
|
969
|
+
import {
|
|
970
|
+
createMap
|
|
971
|
+
} from "@opendata-ai/openchart-vanilla";
|
|
970
972
|
import {
|
|
971
973
|
defineComponent as defineComponent6,
|
|
972
974
|
h as h6,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/BarList.ts","../src/context.ts","../src/Chart.ts","../src/ChartStory.ts","../src/composables/useChart.ts","../src/composables/useDarkMode.ts","../src/composables/useGraph.ts","../src/composables/useTable.ts","../src/composables/useTableState.ts","../src/DataTable.ts","../src/Graph.ts","../src/Map.ts","../src/Sankey.ts","../src/ThemeProvider.ts","../src/TileMap.ts","../src/Visualization.ts"],"sourcesContent":["/**\n * @opendata-ai/openchart-vue\n *\n * Vue 3 adapter for openchart. Provides <Chart />, <DataTable />, <Graph />,\n * and <VizThemeProvider /> components that wrap the vanilla adapter with\n * Vue lifecycle management.\n *\n * Re-exports the full core type system and utilities so Vue consumers\n * only need a single @opendata-ai/openchart-vue dependency.\n */\n\n// ---------------------------------------------------------------------------\n// Core: full type system, theme, colors, locale, accessibility, helpers\n// ---------------------------------------------------------------------------\n\nexport * from '@opendata-ai/openchart-core';\n\n// ---------------------------------------------------------------------------\n// Vanilla: export utilities (SVG/PNG/JPG/CSV)\n// ---------------------------------------------------------------------------\n\nexport type { JPGExportOptions, PNGExportOptions } from '@opendata-ai/openchart-vanilla';\nexport { exportCSV, exportJPG, exportPNG, exportSVG } from '@opendata-ai/openchart-vanilla';\n\n// ---------------------------------------------------------------------------\n// Engine: compile API and types not covered by core\n// ---------------------------------------------------------------------------\n\nexport type {\n ChartRenderer,\n CompiledGraphEdge,\n CompiledGraphNode,\n CompileResult,\n GraphCompilation,\n NormalizedBarListSpec,\n NormalizedChartSpec,\n NormalizedChrome,\n NormalizedGraphSpec,\n NormalizedMapSpec,\n NormalizedSankeySpec,\n NormalizedSpec,\n NormalizedTableSpec,\n SimulationConfig,\n ValidationError,\n ValidationErrorCode,\n ValidationResult,\n} from '@opendata-ai/openchart-engine';\nexport {\n clearRenderers,\n compile,\n compileBarList,\n compileChart,\n compileGraph,\n compileMap,\n compileSankey,\n compileTable,\n getChartRenderer,\n normalizeSpec,\n registerChartRenderer,\n validateSpec,\n} from '@opendata-ai/openchart-engine';\nexport type { BarListProps, BarListRowEvent } from './BarList';\nexport { BarList } from './BarList';\n// Components\nexport type { ChartProps } from './Chart';\nexport { Chart } from './Chart';\nexport type { ChartStoryProps } from './ChartStory';\n// Scrollytelling\nexport { ChartStory } from './ChartStory';\n// Composables\nexport type { UseChartOptions, UseChartReturn } from './composables/useChart';\nexport { useChart } from './composables/useChart';\nexport { useDarkMode } from './composables/useDarkMode';\nexport type { GraphHandle, UseGraphReturn } from './composables/useGraph';\nexport { useGraph } from './composables/useGraph';\nexport type { UseTableReturn } from './composables/useTable';\nexport { useTable } from './composables/useTable';\nexport type { UseTableStateOptions, UseTableStateReturn } from './composables/useTableState';\nexport { useTableState } from './composables/useTableState';\n// Context (injection keys and composables)\nexport { useVizDarkMode, useVizTheme, VizDarkModeKey, VizThemeKey } from './context';\nexport type { DataTableProps } from './DataTable';\nexport { DataTable } from './DataTable';\nexport type { GraphProps } from './Graph';\nexport { Graph } from './Graph';\nexport type { MapProps } from './Map';\nexport { GeoMap } from './Map';\nexport type { SankeyProps } from './Sankey';\nexport { Sankey } from './Sankey';\nexport type { VizThemeProviderProps } from './ThemeProvider';\nexport { VizThemeProvider } from './ThemeProvider';\nexport type { TileMapProps } from './TileMap';\nexport { TileMap } from './TileMap';\nexport type { VisualizationProps } from './Visualization';\nexport { Visualization } from './Visualization';\n","/**\n * Vue BarList component: thin wrapper around the vanilla adapter.\n */\n\nimport type { BarListSpec, DarkMode, ThemeConfig } from '@opendata-ai/openchart-core';\nimport {\n type BarListInstance,\n type BarListMountOptions,\n createBarList,\n} from '@opendata-ai/openchart-vanilla';\nimport {\n type CSSProperties,\n defineComponent,\n h,\n inject,\n onMounted,\n onUnmounted,\n type PropType,\n ref,\n watch,\n} from 'vue';\nimport { VizDarkModeKey, VizThemeKey } from './context';\n\nexport interface BarListRowEvent {\n label: string;\n value: number;\n data: Record<string, unknown>;\n}\n\nexport interface BarListProps {\n spec: BarListSpec;\n theme?: ThemeConfig;\n darkMode?: DarkMode;\n class?: string;\n style?: string | CSSProperties;\n}\n\nexport const BarList = defineComponent({\n name: 'BarList',\n props: {\n spec: {\n type: Object as PropType<BarListSpec>,\n required: true,\n },\n theme: {\n type: Object as PropType<ThemeConfig>,\n default: undefined,\n },\n darkMode: {\n type: String as PropType<DarkMode>,\n default: undefined,\n },\n class: {\n type: String,\n default: undefined,\n },\n style: {\n type: [String, Object] as PropType<string | CSSProperties>,\n default: undefined,\n },\n },\n emits: {\n 'row-click': (_row: BarListRowEvent) => true,\n 'row-hover': (_row: BarListRowEvent | null) => true,\n },\n setup(props, { emit, expose }) {\n const containerRef = ref<HTMLDivElement | null>(null);\n let instance: BarListInstance | null = null;\n let prevSpec = '';\n\n const contextTheme = inject(VizThemeKey, undefined);\n const contextDarkMode = inject(VizDarkModeKey, undefined);\n\n function resolveTheme(): ThemeConfig | undefined {\n return props.theme ?? contextTheme?.value;\n }\n\n function resolveDarkMode(): DarkMode | undefined {\n return props.darkMode ?? contextDarkMode?.value;\n }\n\n function mountBarList() {\n const container = containerRef.value;\n if (!container) return;\n\n const options: BarListMountOptions = {\n theme: resolveTheme(),\n darkMode: resolveDarkMode(),\n onRowClick: (row: BarListRowEvent) => emit('row-click', row),\n onRowHover: (row: BarListRowEvent | null) => emit('row-hover', row),\n responsive: true,\n };\n\n instance = createBarList(container, props.spec, options);\n prevSpec = JSON.stringify(props.spec);\n }\n\n function destroyBarList() {\n instance?.destroy();\n instance = null;\n prevSpec = '';\n }\n\n expose({\n get instance() {\n return instance;\n },\n });\n\n onMounted(() => {\n mountBarList();\n });\n\n onUnmounted(() => {\n destroyBarList();\n });\n\n watch(\n () => JSON.stringify(props.spec),\n (newVal) => {\n if (!instance) return;\n if (newVal !== prevSpec) {\n prevSpec = newVal;\n instance.update(props.spec);\n }\n },\n );\n\n watch(\n [\n () => props.theme,\n () => props.darkMode,\n () => contextTheme?.value,\n () => contextDarkMode?.value,\n ],\n () => {\n if (!containerRef.value) return;\n destroyBarList();\n mountBarList();\n },\n );\n\n const rootClass = () => {\n const base = 'oc-barlist-root';\n return props.class ? `${base} ${props.class}` : base;\n };\n\n return () =>\n h('div', {\n ref: containerRef,\n class: rootClass(),\n style: props.style,\n });\n },\n});\n","/**\n * Theme injection context for Vue.\n *\n * Provides typed injection keys and composables for accessing theme\n * and dark mode from any descendant component within a VizThemeProvider.\n */\n\nimport type { DarkMode, ThemeConfig } from '@opendata-ai/openchart-core';\nimport { type ComputedRef, computed, type InjectionKey, inject, type Ref } from 'vue';\n\n/** Injection key for the theme config ref. */\nexport const VizThemeKey: InjectionKey<Ref<ThemeConfig | undefined>> = Symbol('VizTheme');\n\n/** Injection key for the dark mode ref. */\nexport const VizDarkModeKey: InjectionKey<Ref<DarkMode | undefined>> = Symbol('VizDarkMode');\n\n/**\n * Read the current theme from the nearest VizThemeProvider.\n * Returns a computed ref that stays reactive to provider changes.\n */\nexport function useVizTheme(): ComputedRef<ThemeConfig | undefined> {\n const theme = inject(VizThemeKey, undefined);\n return computed(() => theme?.value);\n}\n\n/**\n * Read the current dark mode preference from the nearest VizThemeProvider.\n * Returns a computed ref that stays reactive to provider changes.\n */\nexport function useVizDarkMode(): ComputedRef<DarkMode | undefined> {\n const darkMode = inject(VizDarkModeKey, undefined);\n return computed(() => darkMode?.value);\n}\n","/**\n * Vue Chart component: thin wrapper around the vanilla adapter.\n *\n * Mounts a chart instance on render, updates when spec changes,\n * and cleans up on unmount. All heavy lifting is done by the vanilla\n * createChart() function.\n */\n\nimport type {\n Annotation,\n AnnotationOffset,\n ChartSpec,\n DarkMode,\n ElementEdit,\n ElementRef,\n GraphSpec,\n LayerSpec,\n MarkEvent,\n TextAnnotation,\n ThemeConfig,\n} from '@opendata-ai/openchart-core';\nimport { type ChartInstance, createChart, type MountOptions } from '@opendata-ai/openchart-vanilla';\nimport {\n type CSSProperties,\n defineComponent,\n getCurrentInstance,\n h,\n inject,\n onMounted,\n onUnmounted,\n type PropType,\n ref,\n watch,\n} from 'vue';\nimport { VizDarkModeKey, VizThemeKey } from './context';\n\nexport interface ChartProps {\n spec: ChartSpec | LayerSpec | GraphSpec;\n theme?: ThemeConfig;\n darkMode?: DarkMode;\n class?: string;\n style?: string | CSSProperties;\n}\n\nexport const Chart = defineComponent({\n name: 'Chart',\n props: {\n spec: {\n type: Object as PropType<ChartSpec | LayerSpec | GraphSpec>,\n required: true,\n },\n theme: {\n type: Object as PropType<ThemeConfig>,\n default: undefined,\n },\n darkMode: {\n type: String as PropType<DarkMode>,\n default: undefined,\n },\n class: {\n type: String,\n default: undefined,\n },\n style: {\n type: [String, Object] as PropType<string | CSSProperties>,\n default: undefined,\n },\n selectedElement: {\n type: Object as PropType<ElementRef>,\n default: undefined,\n },\n highlight: {\n type: [Array, null] as unknown as PropType<string[] | null>,\n default: undefined,\n },\n },\n emits: {\n 'mark-click': (_event: MarkEvent) => true,\n 'mark-hover': (_event: MarkEvent) => true,\n 'mark-leave': () => true,\n 'legend-toggle': (_series: string, _visible: boolean) => true,\n 'annotation-click': (_annotation: Annotation, _event: MouseEvent) => true,\n 'annotation-edit': (_annotation: TextAnnotation, _updatedOffset: AnnotationOffset) => true,\n edit: (_edit: ElementEdit) => true,\n select: (_element: ElementRef) => true,\n deselect: (_element: ElementRef) => true,\n 'text-edit': (_element: ElementRef, _oldText: string, _newText: string) => true,\n 'data-point-click': (_data: Record<string, unknown>) => true,\n },\n setup(props, { emit, expose }) {\n const containerRef = ref<HTMLDivElement | null>(null);\n let instance: ChartInstance | null = null;\n let prevSpec = '';\n\n // Inject theme/darkMode from provider as fallbacks\n const contextTheme = inject(VizThemeKey, undefined);\n const contextDarkMode = inject(VizDarkModeKey, undefined);\n\n // Check which event listeners are bound by the parent.\n // Vue 3 passes listeners as onXxx props on the component vnode.\n // We cache this at setup time since it won't change.\n const vm = getCurrentInstance();\n const vnodeProps = vm?.vnode.props ?? {};\n const hasAnnotationEditListener =\n 'onAnnotation-edit' in vnodeProps || 'onAnnotationEdit' in vnodeProps;\n const hasEditListener = 'onEdit' in vnodeProps;\n const hasSelectListener = 'onSelect' in vnodeProps;\n const hasDeselectListener = 'onDeselect' in vnodeProps;\n const hasTextEditListener = 'onText-edit' in vnodeProps || 'onTextEdit' in vnodeProps;\n\n function resolveTheme(): ThemeConfig | undefined {\n return props.theme ?? contextTheme?.value;\n }\n\n function resolveDarkMode(): DarkMode | undefined {\n return props.darkMode ?? contextDarkMode?.value;\n }\n\n function mountChart() {\n const container = containerRef.value;\n if (!container) return;\n\n const options: MountOptions = {\n theme: resolveTheme(),\n darkMode: resolveDarkMode(),\n onDataPointClick: (data: Record<string, unknown>) => emit('data-point-click', data),\n onMarkClick: (event: MarkEvent) => emit('mark-click', event),\n onMarkHover: (event: MarkEvent) => emit('mark-hover', event),\n onMarkLeave: () => emit('mark-leave'),\n onLegendToggle: (series: string, visible: boolean) =>\n emit('legend-toggle', series, visible),\n onAnnotationClick: (annotation: Annotation, event: MouseEvent) =>\n emit('annotation-click', annotation, event),\n // Only include editing callbacks when the parent binds a listener.\n // Without this gate, every chart gets drag editing wired up.\n ...(hasAnnotationEditListener\n ? {\n onAnnotationEdit: (annotation: TextAnnotation, updatedOffset: AnnotationOffset) =>\n emit('annotation-edit', annotation, updatedOffset),\n }\n : {}),\n ...(hasEditListener ? { onEdit: (edit: ElementEdit) => emit('edit', edit) } : {}),\n ...(hasSelectListener\n ? { onSelect: (element: ElementRef) => emit('select', element) }\n : {}),\n ...(hasDeselectListener\n ? { onDeselect: (element: ElementRef) => emit('deselect', element) }\n : {}),\n ...(hasTextEditListener\n ? {\n onTextEdit: (element: ElementRef, oldText: string, newText: string) =>\n emit('text-edit', element, oldText, newText),\n }\n : {}),\n ...(props.selectedElement ? { selectedElement: props.selectedElement } : {}),\n responsive: true,\n };\n\n instance = createChart(container, props.spec, options);\n prevSpec = JSON.stringify(props.spec);\n if (props.highlight !== undefined) {\n instance.setHighlight(props.highlight ?? null);\n }\n }\n\n function destroyChart() {\n instance?.destroy();\n instance = null;\n prevSpec = '';\n }\n\n // Expose imperative methods for parent ref access\n expose({\n getSelectedElement(): ElementRef | null {\n return instance?.getSelectedElement() ?? null;\n },\n select(elementRef: ElementRef): void {\n instance?.select(elementRef);\n },\n deselect(): void {\n instance?.deselect();\n },\n get instance() {\n return instance;\n },\n });\n\n onMounted(() => {\n mountChart();\n });\n\n onUnmounted(() => {\n destroyChart();\n });\n\n // Watch spec changes: update if only spec changed, recreate if theme/darkMode changed\n watch(\n () => JSON.stringify(props.spec),\n (newVal) => {\n if (!instance) return;\n if (newVal !== prevSpec) {\n prevSpec = newVal;\n instance.update(props.spec, { selectedElement: props.selectedElement });\n }\n },\n );\n\n // Watch selectedElement prop changes\n watch(\n () => props.selectedElement,\n (newVal) => {\n if (!instance) return;\n if (newVal) {\n instance.select(newVal);\n } else {\n instance.deselect();\n }\n },\n );\n\n // Watch highlight prop changes\n watch(\n () => props.highlight,\n (newVal) => {\n if (!instance) return;\n instance.setHighlight(newVal ?? null);\n },\n );\n\n // Recreate chart when theme or darkMode change\n watch(\n [\n () => props.theme,\n () => props.darkMode,\n () => contextTheme?.value,\n () => contextDarkMode?.value,\n ],\n () => {\n if (!containerRef.value) return;\n destroyChart();\n mountChart();\n },\n );\n\n const rootClass = () => {\n const base = 'oc-chart-root';\n return props.class ? `${base} ${props.class}` : base;\n };\n\n return () =>\n h('div', {\n ref: containerRef,\n class: rootClass(),\n style: props.style,\n });\n },\n});\n","/**\n * Vue scrollytelling shell around the vanilla `createChartStory`.\n *\n * Mirrors the React `<ChartStory>`: a sticky chart panel plus a scrolling\n * narrative column whose blocks advance the story. The vanilla driver owns\n * cumulative patch application, mark morphing, crossfade, and camera; this\n * component owns only Vue lifecycle and the sticky layout.\n *\n * Narrative is provided as the default slot's children (one root node per\n * step) or via the `narrative` prop (an array of vnodes/strings). Pass `step`\n * to drive it externally; omit for self-driving scroll.\n */\n\nimport type { ChartSpec, GraphSpec, LayerSpec, MapSpec } from '@opendata-ai/openchart-core';\nimport type { MountOptions } from '@opendata-ai/openchart-vanilla';\nimport {\n type ChartStoryInstance,\n type ChartStoryOptions,\n createChartStory,\n} from '@opendata-ai/openchart-vanilla/story';\nimport {\n type CSSProperties,\n defineComponent,\n h,\n onMounted,\n onUnmounted,\n type PropType,\n ref,\n type VNode,\n watch,\n} from 'vue';\n\nexport interface ChartStoryProps {\n spec: ChartSpec | LayerSpec | GraphSpec | MapSpec;\n steps: ChartStoryOptions['steps'];\n narrative?: VNode[];\n step?: number;\n triggerPosition?: number;\n cameraMode?: 'step' | 'scrub';\n mountOptions?: MountOptions;\n}\n\nconst sectionStyle: CSSProperties = {\n position: 'relative',\n display: 'grid',\n gridTemplateColumns: 'minmax(0, 26rem) minmax(0, 1fr)',\n gap: '3rem',\n alignItems: 'start',\n};\n\nconst stepStyle: CSSProperties = {\n minHeight: '80vh',\n display: 'flex',\n alignItems: 'center',\n};\n\nconst panelStyle: CSSProperties = {\n position: 'sticky',\n top: '2rem',\n height: 'calc(100vh - 4rem)',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n};\n\nexport const ChartStory = defineComponent({\n name: 'ChartStory',\n props: {\n spec: {\n type: Object as PropType<ChartSpec | LayerSpec | GraphSpec | MapSpec>,\n required: true,\n },\n steps: {\n type: Array as PropType<ChartStoryOptions['steps']>,\n required: true,\n },\n narrative: {\n type: Array as PropType<VNode[]>,\n default: undefined,\n },\n step: {\n type: Number,\n default: undefined,\n },\n triggerPosition: {\n type: Number,\n default: undefined,\n },\n cameraMode: {\n type: String as PropType<'step' | 'scrub'>,\n default: undefined,\n },\n mountOptions: {\n type: Object as PropType<MountOptions>,\n default: undefined,\n },\n },\n setup(props, { slots, expose }) {\n const sectionRef = ref<HTMLElement | null>(null);\n const mountRef = ref<HTMLDivElement | null>(null);\n const stepEls = ref<Array<HTMLElement | null>>([]);\n let story: ChartStoryInstance | null = null;\n\n onMounted(() => {\n const mount = mountRef.value;\n if (!mount) return;\n\n const blocks = props.narrative ?? [];\n if (blocks.length > 0 && blocks.length !== props.steps.length) {\n console.warn(\n `[openchart] ChartStory: narrative length (${blocks.length}) does not match steps length (${props.steps.length}). Each step should have a corresponding narrative element.`,\n );\n }\n\n story = createChartStory(\n mount,\n {\n spec: props.spec,\n steps: props.steps,\n triggerPosition: props.triggerPosition,\n cameraMode: props.cameraMode,\n },\n props.mountOptions,\n );\n if (sectionRef.value) story.setContainer(sectionRef.value);\n stepEls.value.forEach((el, i) => {\n if (el) story?.registerStep(i, el);\n });\n if (props.step !== undefined) story.goTo(props.step);\n });\n\n watch(\n () => props.step,\n (next) => {\n if (next !== undefined) story?.goTo(next);\n },\n );\n\n onUnmounted(() => {\n story?.destroy();\n story = null;\n });\n\n expose({\n goTo(index: number) {\n story?.goTo(index);\n },\n get instance() {\n return story;\n },\n });\n\n return () => {\n // Prefer the `narrative` prop; fall back to default slot children so\n // consumers can author steps as template markup.\n const blocks = props.narrative ?? slots.default?.() ?? [];\n return h('section', { ref: sectionRef, style: sectionStyle }, [\n h(\n 'div',\n { style: { position: 'relative' } },\n blocks.map((content, i) =>\n h(\n 'div',\n {\n // Steps are a fixed ordered list, so the index is the stable\n // identity. Do not reorder or splice narrative entries at runtime\n // (that would remap step refs to the wrong content); rebuild the\n // whole story instead.\n key: i,\n ref: (el: unknown) => {\n stepEls.value[i] = el as HTMLElement | null;\n },\n 'data-oc-story-step': i,\n style: stepStyle,\n },\n [h('div', { style: { maxWidth: '36rem' } }, [content])],\n ),\n ),\n ),\n h('div', { style: panelStyle }, [h('div', { ref: mountRef, style: { width: '100%' } })]),\n ]);\n };\n },\n});\n","/**\n * useChart: composable for manual chart lifecycle control.\n *\n * Provides a template ref to attach to a container div. The chart\n * mounts automatically and updates when the spec changes.\n */\n\nimport type {\n ChartLayout,\n ChartSpec,\n DarkMode,\n GraphSpec,\n LayerSpec,\n ThemeConfig,\n} from '@opendata-ai/openchart-core';\nimport { type ChartInstance, createChart, type MountOptions } from '@opendata-ai/openchart-vanilla';\nimport { onMounted, onUnmounted, type Ref, ref, type ShallowRef, shallowRef, watch } from 'vue';\n\nexport interface UseChartOptions {\n /** Theme overrides. */\n theme?: ThemeConfig;\n /** Dark mode setting. */\n darkMode?: DarkMode;\n /** Data point click handler. */\n onDataPointClick?: MountOptions['onDataPointClick'];\n /** Enable responsive resizing. Defaults to true. */\n responsive?: boolean;\n}\n\nexport interface UseChartReturn {\n /** Template ref to attach to the container div. */\n containerRef: Ref<HTMLDivElement | null>;\n /** The chart instance (null until mounted). */\n chart: ShallowRef<ChartInstance | null>;\n /** The current compiled layout (null until mounted). */\n layout: ShallowRef<ChartLayout | null>;\n}\n\n/**\n * Composable for manual chart lifecycle control.\n *\n * Attach the returned containerRef to a container div via `ref=\"containerRef\"`.\n * The chart mounts automatically and updates when the spec changes.\n */\nexport function useChart(\n spec: Ref<ChartSpec | LayerSpec | GraphSpec>,\n options?: UseChartOptions,\n): UseChartReturn {\n const containerRef = ref<HTMLDivElement | null>(null);\n const chart = shallowRef<ChartInstance | null>(null);\n const layout = shallowRef<ChartLayout | null>(null);\n\n function mount() {\n const container = containerRef.value;\n if (!container) return;\n\n const mountOpts: MountOptions = {\n theme: options?.theme,\n darkMode: options?.darkMode,\n onDataPointClick: options?.onDataPointClick,\n responsive: options?.responsive,\n };\n\n const instance = createChart(container, spec.value, mountOpts);\n chart.value = instance;\n layout.value = instance.layout;\n }\n\n function destroy() {\n chart.value?.destroy();\n chart.value = null;\n layout.value = null;\n }\n\n onMounted(() => {\n mount();\n });\n\n onUnmounted(() => {\n destroy();\n });\n\n // Update on spec change\n watch(spec, (newSpec) => {\n const instance = chart.value;\n if (!instance) return;\n instance.update(newSpec);\n layout.value = instance.layout;\n });\n\n return {\n containerRef,\n chart,\n layout,\n };\n}\n","/**\n * useDarkMode: composable that resolves a DarkMode preference to a boolean.\n *\n * - \"force\" -> true\n * - \"off\" -> false\n * - \"auto\" -> matches system preference (reactive to changes)\n */\n\nimport type { DarkMode } from '@opendata-ai/openchart-core';\nimport { onUnmounted, type Ref, ref, watch } from 'vue';\n\n/**\n * Resolve a DarkMode preference to a reactive boolean.\n *\n * For \"auto\" mode, watches the system `prefers-color-scheme` media query\n * and updates reactively when the user changes their OS theme.\n */\nexport function useDarkMode(mode: Ref<DarkMode | undefined>): Ref<boolean> {\n const isDark = ref(resolveInitial(mode.value));\n let cleanup: (() => void) | null = null;\n\n function setup(currentMode: DarkMode | undefined) {\n // Clean up previous listener\n cleanup?.();\n cleanup = null;\n\n if (currentMode !== 'auto') {\n isDark.value = currentMode === 'force';\n return;\n }\n\n if (typeof window === 'undefined' || !window.matchMedia) {\n isDark.value = false;\n return;\n }\n\n const mq = window.matchMedia('(prefers-color-scheme: dark)');\n isDark.value = mq.matches;\n\n const handler = (e: MediaQueryListEvent) => {\n isDark.value = e.matches;\n };\n mq.addEventListener('change', handler);\n cleanup = () => mq.removeEventListener('change', handler);\n }\n\n // Run setup for initial value\n setup(mode.value);\n\n // React to mode changes\n watch(mode, (newMode) => {\n setup(newMode);\n });\n\n onUnmounted(() => {\n cleanup?.();\n cleanup = null;\n });\n\n return isDark;\n}\n\nfunction resolveInitial(mode?: DarkMode): boolean {\n if (mode === 'force') return true;\n if (mode === 'off' || mode === undefined) return false;\n // \"auto\"\n if (typeof window !== 'undefined' && window.matchMedia) {\n return window.matchMedia('(prefers-color-scheme: dark)').matches;\n }\n return false;\n}\n","/**\n * useGraph: composable for imperative graph control.\n *\n * Provides a template ref to pass to <Graph /> and exposes graph methods\n * (search, zoom, select) for programmatic control of the graph instance.\n */\n\nimport type { GraphInstance } from '@opendata-ai/openchart-vanilla';\nimport { type Ref, ref } from 'vue';\n\n/** Handle exposed by Graph component via expose(). */\nexport interface GraphHandle {\n search: (query: string) => void;\n clearSearch: () => void;\n zoomToFit: () => void;\n zoomToNode: (nodeId: string) => void;\n selectNode: (nodeId: string) => void;\n getSelectedNodes: () => string[];\n /** The underlying GraphInstance from the vanilla adapter. */\n instance: GraphInstance | null;\n}\n\nexport interface UseGraphReturn {\n /** Template ref to pass to <Graph ref={graphRef} />. */\n graphRef: Ref<GraphHandle | null>;\n /** Search for nodes matching a query string. */\n search: (query: string) => void;\n /** Clear the current search. */\n clearSearch: () => void;\n /** Zoom to fit all nodes in view. */\n zoomToFit: () => void;\n /** Zoom and center on a specific node. */\n zoomToNode: (nodeId: string) => void;\n /** Select a node by id. */\n selectNode: (nodeId: string) => void;\n /** Get the currently selected node ids. */\n getSelectedNodes: () => string[];\n}\n\n/**\n * Composable for imperative graph control.\n *\n * Usage:\n * ```vue\n * <script setup>\n * const { graphRef, search, zoomToFit } = useGraph();\n * </script>\n * <template>\n * <Graph ref=\"graphRef\" :spec=\"spec\" />\n * </template>\n * ```\n */\nexport function useGraph(): UseGraphReturn {\n const graphRef = ref<GraphHandle | null>(null);\n\n function search(query: string) {\n graphRef.value?.search(query);\n }\n\n function clearSearch() {\n graphRef.value?.clearSearch();\n }\n\n function zoomToFit() {\n graphRef.value?.zoomToFit();\n }\n\n function zoomToNode(nodeId: string) {\n graphRef.value?.zoomToNode(nodeId);\n }\n\n function selectNode(nodeId: string) {\n graphRef.value?.selectNode(nodeId);\n }\n\n function getSelectedNodes(): string[] {\n return graphRef.value?.getSelectedNodes() ?? [];\n }\n\n return {\n graphRef,\n search,\n clearSearch,\n zoomToFit,\n zoomToNode,\n selectNode,\n getSelectedNodes,\n };\n}\n","/**\n * useTable: composable for manual table lifecycle control.\n *\n * Attaches to a container ref, mounts a vanilla table instance,\n * and exposes the instance and current state.\n */\n\nimport type { TableSpec } from '@opendata-ai/openchart-core';\nimport {\n createTable,\n type TableInstance,\n type TableMountOptions,\n type TableState,\n} from '@opendata-ai/openchart-vanilla';\nimport { onMounted, onUnmounted, type Ref, ref, type ShallowRef, shallowRef, watch } from 'vue';\n\nexport interface UseTableReturn {\n /** Template ref to attach to the container div. */\n containerRef: Ref<HTMLDivElement | null>;\n /** The table instance (null until mounted). */\n table: ShallowRef<TableInstance | null>;\n /** The current table state (sort, search, page). */\n state: Ref<TableState>;\n}\n\n/**\n * Composable for manual table lifecycle control.\n *\n * Attach the returned containerRef to a container div via `ref=\"containerRef\"`.\n * The table mounts automatically and updates when the spec changes.\n */\nexport function useTable(spec: Ref<TableSpec>, options?: TableMountOptions): UseTableReturn {\n const containerRef = ref<HTMLDivElement | null>(null);\n const table = shallowRef<TableInstance | null>(null);\n const state = ref<TableState>({\n sort: null,\n search: '',\n page: 0,\n });\n\n const originalOnStateChange = options?.onStateChange;\n\n function handleStateChange(newState: TableState) {\n state.value = newState;\n originalOnStateChange?.(newState);\n }\n\n function mount() {\n const container = containerRef.value;\n if (!container) return;\n\n const mountOpts: TableMountOptions = {\n ...options,\n onStateChange: handleStateChange,\n };\n\n const instance = createTable(container, spec.value, mountOpts);\n table.value = instance;\n state.value = instance.getState();\n }\n\n function destroy() {\n table.value?.destroy();\n table.value = null;\n }\n\n onMounted(() => {\n mount();\n });\n\n onUnmounted(() => {\n destroy();\n });\n\n // Update on spec change\n watch(spec, (newSpec) => {\n const instance = table.value;\n if (!instance) return;\n instance.update(newSpec);\n state.value = instance.getState();\n });\n\n return {\n containerRef,\n table,\n state,\n };\n}\n","/**\n * useTableState: managed state composable for controlled table usage.\n *\n * Provides individual sort/search/page state with setters and a\n * resetState function to return to initial values.\n */\n\nimport type { SortState } from '@opendata-ai/openchart-core';\nimport { type Ref, ref } from 'vue';\n\nexport interface UseTableStateReturn {\n sort: Ref<SortState | null>;\n setSort: (sort: SortState | null) => void;\n search: Ref<string>;\n setSearch: (query: string) => void;\n page: Ref<number>;\n setPage: (page: number) => void;\n resetState: () => void;\n}\n\nexport interface UseTableStateOptions {\n sort?: SortState | null;\n search?: string;\n page?: number;\n}\n\n/**\n * Composable for managing table state (sort, search, page).\n *\n * Use with the DataTable component's controlled props:\n * ```vue\n * <script setup>\n * const { sort, search, page, setSort, setSearch, setPage } = useTableState();\n * </script>\n * <template>\n * <DataTable\n * :spec=\"spec\"\n * :sort=\"sort\"\n * :search=\"search\"\n * :page=\"page\"\n * @update:sort=\"setSort\"\n * @update:search=\"setSearch\"\n * @update:page=\"setPage\"\n * />\n * </template>\n * ```\n */\nexport function useTableState(initialState?: UseTableStateOptions): UseTableStateReturn {\n const sort = ref<SortState | null>(initialState?.sort ?? null);\n const search = ref(initialState?.search ?? '');\n const page = ref(initialState?.page ?? 0);\n\n function setSort(newSort: SortState | null) {\n sort.value = newSort;\n }\n\n function setSearch(query: string) {\n search.value = query;\n }\n\n function setPage(newPage: number) {\n page.value = newPage;\n }\n\n function resetState() {\n sort.value = initialState?.sort ?? null;\n search.value = initialState?.search ?? '';\n page.value = initialState?.page ?? 0;\n }\n\n return {\n sort,\n setSort,\n search,\n setSearch,\n page,\n setPage,\n resetState,\n };\n}\n","/**\n * DataTable component: Vue wrapper around the vanilla table adapter.\n *\n * Mounts a table instance on render, updates when spec changes,\n * and cleans up on unmount. Supports both controlled and uncontrolled modes\n * for sort, search, and pagination state.\n */\n\nimport type { DarkMode, SortState, TableSpec, ThemeConfig } from '@opendata-ai/openchart-core';\nimport {\n createTable,\n type TableInstance,\n type TableMountOptions,\n} from '@opendata-ai/openchart-vanilla';\nimport {\n type CSSProperties,\n defineComponent,\n h,\n inject,\n onMounted,\n onUnmounted,\n type PropType,\n ref,\n watch,\n} from 'vue';\nimport { VizDarkModeKey, VizThemeKey } from './context';\n\nexport interface DataTableProps {\n spec: TableSpec;\n theme?: ThemeConfig;\n darkMode?: DarkMode;\n class?: string;\n style?: string | CSSProperties;\n sort?: SortState | null;\n search?: string;\n page?: number;\n}\n\nexport const DataTable = defineComponent({\n name: 'DataTable',\n props: {\n spec: {\n type: Object as PropType<TableSpec>,\n required: true,\n },\n theme: {\n type: Object as PropType<ThemeConfig>,\n default: undefined,\n },\n darkMode: {\n type: String as PropType<DarkMode>,\n default: undefined,\n },\n class: {\n type: String,\n default: undefined,\n },\n style: {\n type: [String, Object] as PropType<string | CSSProperties>,\n default: undefined,\n },\n sort: {\n type: [Object, null] as PropType<SortState | null>,\n default: undefined,\n },\n search: {\n type: String,\n default: undefined,\n },\n page: {\n type: Number,\n default: undefined,\n },\n },\n emits: {\n 'row-click': (_row: Record<string, unknown>) => true,\n 'update:sort': (_sort: SortState | null) => true,\n 'update:search': (_query: string) => true,\n 'update:page': (_page: number) => true,\n },\n setup(props, { emit }) {\n const containerRef = ref<HTMLDivElement | null>(null);\n let instance: TableInstance | null = null;\n\n // Inject theme/darkMode from provider as fallbacks\n const contextTheme = inject(VizThemeKey, undefined);\n const contextDarkMode = inject(VizDarkModeKey, undefined);\n\n function resolveTheme(): ThemeConfig | undefined {\n return props.theme ?? contextTheme?.value;\n }\n\n function resolveDarkMode(): DarkMode | undefined {\n return props.darkMode ?? contextDarkMode?.value;\n }\n\n function isControlled(): boolean {\n return props.sort !== undefined || props.search !== undefined || props.page !== undefined;\n }\n\n let prevSpec = '';\n\n function mountTable() {\n const container = containerRef.value;\n if (!container) return;\n\n const mountOptions: TableMountOptions = {\n theme: resolveTheme(),\n darkMode: resolveDarkMode(),\n onRowClick: (row: Record<string, unknown>) => emit('row-click', row),\n responsive: true,\n onStateChange: (state) => {\n if (state.sort !== undefined) emit('update:sort', state.sort);\n if (state.search !== undefined) emit('update:search', state.search);\n if (state.page !== undefined) emit('update:page', state.page);\n },\n };\n\n if (isControlled()) {\n mountOptions.externalState = {\n sort: props.sort ?? null,\n search: props.search ?? '',\n page: props.page ?? 0,\n };\n }\n\n instance = createTable(container, props.spec, mountOptions);\n prevSpec = JSON.stringify(props.spec);\n }\n\n function destroyTable() {\n instance?.destroy();\n instance = null;\n prevSpec = '';\n }\n\n onMounted(() => {\n mountTable();\n });\n\n onUnmounted(() => {\n destroyTable();\n });\n\n // Watch spec changes via JSON.stringify comparison (consistent with Chart/Graph)\n watch(\n () => JSON.stringify(props.spec),\n (newVal) => {\n if (!instance) return;\n if (newVal !== prevSpec) {\n prevSpec = newVal;\n instance.update(props.spec);\n }\n },\n );\n\n // Recreate when theme or darkMode change\n watch(\n [\n () => props.theme,\n () => props.darkMode,\n () => contextTheme?.value,\n () => contextDarkMode?.value,\n ],\n () => {\n if (!containerRef.value) return;\n destroyTable();\n mountTable();\n },\n );\n\n // Sync controlled state without remounting\n watch([() => props.sort, () => props.search, () => props.page], () => {\n if (!instance || !isControlled()) return;\n instance.setState({\n sort: props.sort ?? null,\n search: props.search ?? '',\n page: props.page ?? 0,\n });\n });\n\n const rootClass = () => {\n const base = 'oc-table-root';\n return props.class ? `${base} ${props.class}` : base;\n };\n\n return () =>\n h('div', {\n ref: containerRef,\n class: rootClass(),\n style: props.style,\n });\n },\n});\n","/**\n * Vue Graph component: thin wrapper around the vanilla adapter.\n *\n * Mounts a graph instance on render, updates when spec changes,\n * and cleans up on unmount. All heavy lifting is done by the vanilla\n * createGraph() function.\n *\n * Exposes imperative methods via defineExpose for use with useGraph().\n */\n\nimport type { DarkMode, GraphSpec, ThemeConfig } from '@opendata-ai/openchart-core';\nimport {\n createGraph,\n type GraphInstance,\n type GraphMountOptions,\n} from '@opendata-ai/openchart-vanilla';\nimport {\n type CSSProperties,\n defineComponent,\n h,\n inject,\n onMounted,\n onUnmounted,\n type PropType,\n ref,\n watch,\n} from 'vue';\nimport { VizDarkModeKey, VizThemeKey } from './context';\n\nexport interface GraphProps {\n spec: GraphSpec;\n theme?: ThemeConfig;\n darkMode?: DarkMode;\n class?: string;\n style?: string | CSSProperties;\n}\n\nexport const Graph = defineComponent({\n name: 'Graph',\n props: {\n spec: {\n type: Object as PropType<GraphSpec>,\n required: true,\n },\n theme: {\n type: Object as PropType<ThemeConfig>,\n default: undefined,\n },\n darkMode: {\n type: String as PropType<DarkMode>,\n default: undefined,\n },\n class: {\n type: String,\n default: undefined,\n },\n style: {\n type: [String, Object] as PropType<string | CSSProperties>,\n default: undefined,\n },\n },\n emits: {\n 'node-click': (_node: Record<string, unknown>) => true,\n 'node-double-click': (_node: Record<string, unknown>) => true,\n 'selection-change': (_nodeIds: string[]) => true,\n },\n setup(props, { emit, expose }) {\n const containerRef = ref<HTMLDivElement | null>(null);\n let instance: GraphInstance | null = null;\n let prevSpec = '';\n\n // Inject theme/darkMode from provider as fallbacks\n const contextTheme = inject(VizThemeKey, undefined);\n const contextDarkMode = inject(VizDarkModeKey, undefined);\n\n function resolveTheme(): ThemeConfig | undefined {\n return props.theme ?? contextTheme?.value;\n }\n\n function resolveDarkMode(): DarkMode | undefined {\n return props.darkMode ?? contextDarkMode?.value;\n }\n\n function mountGraph() {\n const container = containerRef.value;\n if (!container) return;\n\n const options: GraphMountOptions = {\n theme: resolveTheme(),\n darkMode: resolveDarkMode(),\n onNodeClick: (node: Record<string, unknown>) => emit('node-click', node),\n onNodeDoubleClick: (node: Record<string, unknown>) => emit('node-double-click', node),\n onSelectionChange: (nodeIds: string[]) => emit('selection-change', nodeIds),\n responsive: true,\n };\n\n instance = createGraph(container, props.spec, options);\n prevSpec = JSON.stringify(props.spec);\n }\n\n function destroyGraph() {\n instance?.destroy();\n instance = null;\n prevSpec = '';\n }\n\n // Expose imperative methods for useGraph() composable\n expose({\n search(query: string) {\n instance?.search(query);\n },\n clearSearch() {\n instance?.clearSearch();\n },\n zoomToFit() {\n instance?.zoomToFit();\n },\n zoomToNode(nodeId: string) {\n instance?.zoomToNode(nodeId);\n },\n selectNode(nodeId: string) {\n instance?.selectNode(nodeId);\n },\n getSelectedNodes(): string[] {\n return instance?.getSelectedNodes() ?? [];\n },\n get instance() {\n return instance;\n },\n });\n\n onMounted(() => {\n mountGraph();\n });\n\n onUnmounted(() => {\n destroyGraph();\n });\n\n // Watch spec changes\n watch(\n () => JSON.stringify(props.spec),\n (newVal) => {\n if (!instance) return;\n if (newVal !== prevSpec) {\n prevSpec = newVal;\n instance.update(props.spec);\n }\n },\n );\n\n // Recreate graph when theme or darkMode change\n watch(\n [\n () => props.theme,\n () => props.darkMode,\n () => contextTheme?.value,\n () => contextDarkMode?.value,\n ],\n () => {\n if (!containerRef.value) return;\n destroyGraph();\n mountGraph();\n },\n );\n\n const rootClass = () => {\n const base = 'oc-graph-root';\n return props.class ? `${base} ${props.class}` : base;\n };\n\n return () =>\n h('div', {\n ref: containerRef,\n class: rootClass(),\n style: props.style,\n });\n },\n});\n","/**\n * Vue Map component: thin wrapper around the vanilla adapter.\n *\n * Mounts a map instance on render, updates when spec changes,\n * and cleans up on unmount. All heavy lifting is done by the vanilla\n * createMap() function.\n */\n\nimport type { DarkMode, MapSpec, ThemeConfig } from '@opendata-ai/openchart-core';\n\ntype MapFeatureEvent = {\n id: string | number;\n name?: string;\n data: Record<string, unknown> | null;\n};\n\nimport { createMap, type MapInstance, type MapMountOptions } from '@opendata-ai/openchart-vanilla';\nimport {\n type CSSProperties,\n defineComponent,\n h,\n inject,\n onMounted,\n onUnmounted,\n type PropType,\n ref,\n watch,\n} from 'vue';\nimport { VizDarkModeKey, VizThemeKey } from './context';\n\nexport interface MapProps {\n spec: MapSpec;\n theme?: ThemeConfig;\n darkMode?: DarkMode;\n class?: string;\n style?: string | CSSProperties;\n}\n\nexport const GeoMap = defineComponent({\n name: 'GeoMap',\n props: {\n spec: {\n type: Object as PropType<MapSpec>,\n required: true,\n },\n theme: {\n type: Object as PropType<ThemeConfig>,\n default: undefined,\n },\n darkMode: {\n type: String as PropType<DarkMode>,\n default: undefined,\n },\n class: {\n type: String,\n default: undefined,\n },\n style: {\n type: [String, Object] as PropType<string | CSSProperties>,\n default: undefined,\n },\n },\n emits: {\n 'mark-click': (_event: MapFeatureEvent) => true,\n 'mark-hover': (_event: MapFeatureEvent | null) => true,\n },\n setup(props, { emit, expose }) {\n const containerRef = ref<HTMLDivElement | null>(null);\n let instance: MapInstance | null = null;\n let prevSpec = '';\n\n // Inject theme/darkMode from provider as fallbacks\n const contextTheme = inject(VizThemeKey, undefined);\n const contextDarkMode = inject(VizDarkModeKey, undefined);\n\n function resolveTheme(): ThemeConfig | undefined {\n return props.theme ?? contextTheme?.value;\n }\n\n function resolveDarkMode(): DarkMode | undefined {\n return props.darkMode ?? contextDarkMode?.value;\n }\n\n function mountMap() {\n const container = containerRef.value;\n if (!container) return;\n\n const options: MapMountOptions = {\n theme: resolveTheme(),\n darkMode: resolveDarkMode(),\n onMarkClick: (feature) => emit('mark-click', feature),\n onMarkHover: (feature) => emit('mark-hover', feature),\n responsive: true,\n };\n\n instance = createMap(container, props.spec, options);\n prevSpec = JSON.stringify(props.spec);\n }\n\n function destroyMap() {\n instance?.destroy();\n instance = null;\n prevSpec = '';\n }\n\n // Expose imperative access to the instance\n expose({\n get instance() {\n return instance;\n },\n });\n\n onMounted(() => {\n mountMap();\n });\n\n onUnmounted(() => {\n destroyMap();\n });\n\n // Watch spec changes\n watch(\n () => JSON.stringify(props.spec),\n (newVal) => {\n if (!instance) return;\n if (newVal !== prevSpec) {\n prevSpec = newVal;\n instance.update(props.spec);\n }\n },\n );\n\n // Recreate map when theme or darkMode change\n watch(\n [\n () => props.theme,\n () => props.darkMode,\n () => contextTheme?.value,\n () => contextDarkMode?.value,\n ],\n () => {\n if (!containerRef.value) return;\n destroyMap();\n mountMap();\n },\n );\n\n const rootClass = () => {\n const base = 'oc-map-root';\n return props.class ? `${base} ${props.class}` : base;\n };\n\n return () =>\n h('div', {\n ref: containerRef,\n class: rootClass(),\n style: props.style,\n });\n },\n});\n","/**\n * Vue Sankey component: thin wrapper around the vanilla adapter.\n *\n * Mounts a sankey instance on render, updates when spec changes,\n * and cleans up on unmount. All heavy lifting is done by the vanilla\n * createSankey() function.\n */\n\nimport type { DarkMode, SankeySpec, ThemeConfig } from '@opendata-ai/openchart-core';\nimport {\n createSankey,\n type SankeyInstance,\n type SankeyMountOptions,\n} from '@opendata-ai/openchart-vanilla';\nimport {\n type CSSProperties,\n defineComponent,\n h,\n inject,\n onMounted,\n onUnmounted,\n type PropType,\n ref,\n watch,\n} from 'vue';\nimport { VizDarkModeKey, VizThemeKey } from './context';\n\nexport interface SankeyProps {\n spec: SankeySpec;\n theme?: ThemeConfig;\n darkMode?: DarkMode;\n class?: string;\n style?: string | CSSProperties;\n}\n\nexport const Sankey = defineComponent({\n name: 'Sankey',\n props: {\n spec: {\n type: Object as PropType<SankeySpec>,\n required: true,\n },\n theme: {\n type: Object as PropType<ThemeConfig>,\n default: undefined,\n },\n darkMode: {\n type: String as PropType<DarkMode>,\n default: undefined,\n },\n class: {\n type: String,\n default: undefined,\n },\n style: {\n type: [String, Object] as PropType<string | CSSProperties>,\n default: undefined,\n },\n },\n emits: {\n 'node-click': (_node: Record<string, unknown>) => true,\n 'link-click': (_link: Record<string, unknown>) => true,\n 'node-hover': (_node: Record<string, unknown> | null) => true,\n 'link-hover': (_link: Record<string, unknown> | null) => true,\n },\n setup(props, { emit, expose }) {\n const containerRef = ref<HTMLDivElement | null>(null);\n let instance: SankeyInstance | null = null;\n let prevSpec = '';\n\n // Inject theme/darkMode from provider as fallbacks\n const contextTheme = inject(VizThemeKey, undefined);\n const contextDarkMode = inject(VizDarkModeKey, undefined);\n\n function resolveTheme(): ThemeConfig | undefined {\n return props.theme ?? contextTheme?.value;\n }\n\n function resolveDarkMode(): DarkMode | undefined {\n return props.darkMode ?? contextDarkMode?.value;\n }\n\n function mountSankey() {\n const container = containerRef.value;\n if (!container) return;\n\n const options: SankeyMountOptions = {\n theme: resolveTheme(),\n darkMode: resolveDarkMode(),\n onNodeClick: (node: Record<string, unknown>) => emit('node-click', node),\n onLinkClick: (link: Record<string, unknown>) => emit('link-click', link),\n onNodeHover: (node: Record<string, unknown> | null) => emit('node-hover', node),\n onLinkHover: (link: Record<string, unknown> | null) => emit('link-hover', link),\n responsive: true,\n };\n\n instance = createSankey(container, props.spec, options);\n prevSpec = JSON.stringify(props.spec);\n }\n\n function destroySankey() {\n instance?.destroy();\n instance = null;\n prevSpec = '';\n }\n\n // Expose imperative access to the instance\n expose({\n get instance() {\n return instance;\n },\n });\n\n onMounted(() => {\n mountSankey();\n });\n\n onUnmounted(() => {\n destroySankey();\n });\n\n // Watch spec changes\n watch(\n () => JSON.stringify(props.spec),\n (newVal) => {\n if (!instance) return;\n if (newVal !== prevSpec) {\n prevSpec = newVal;\n instance.update(props.spec);\n }\n },\n );\n\n // Recreate sankey when theme or darkMode change\n watch(\n [\n () => props.theme,\n () => props.darkMode,\n () => contextTheme?.value,\n () => contextDarkMode?.value,\n ],\n () => {\n if (!containerRef.value) return;\n destroySankey();\n mountSankey();\n },\n );\n\n const rootClass = () => {\n const base = 'oc-sankey-root';\n return props.class ? `${base} ${props.class}` : base;\n };\n\n return () =>\n h('div', {\n ref: containerRef,\n class: rootClass(),\n style: props.style,\n });\n },\n});\n","/**\n * VizThemeProvider: provides a theme and dark mode preference to all\n * descendant Chart, DataTable, and Graph components without prop drilling.\n *\n * Components use the context values as fallbacks when no explicit\n * `theme` or `darkMode` prop is passed.\n */\n\nimport type { DarkMode, ThemeConfig } from '@opendata-ai/openchart-core';\nimport { computed, defineComponent, type PropType, provide } from 'vue';\nimport { VizDarkModeKey, VizThemeKey } from './context';\n\nexport interface VizThemeProviderProps {\n theme: ThemeConfig | undefined;\n darkMode?: DarkMode;\n}\n\nexport const VizThemeProvider = defineComponent({\n name: 'VizThemeProvider',\n props: {\n theme: {\n type: Object as PropType<ThemeConfig | undefined>,\n default: undefined,\n },\n darkMode: {\n type: String as PropType<DarkMode>,\n default: undefined,\n },\n },\n setup(props, { slots }) {\n // Wrap in computed() so changes to props propagate reactively\n // through the injection system.\n const themeRef = computed(() => props.theme);\n const darkModeRef = computed(() => props.darkMode);\n\n provide(VizThemeKey, themeRef);\n provide(VizDarkModeKey, darkModeRef);\n\n return () => slots.default?.();\n },\n});\n","/**\n * Vue TileMap component: thin wrapper around the vanilla adapter.\n *\n * Mounts a tilemap instance on render, updates when spec changes,\n * and cleans up on unmount. All heavy lifting is done by the vanilla\n * createTileMap() function.\n */\n\nimport type { DarkMode, ThemeConfig, TileMapSpec } from '@opendata-ai/openchart-core';\nimport {\n createTileMap,\n type TileMapInstance,\n type TileMapMountOptions,\n} from '@opendata-ai/openchart-vanilla';\nimport {\n type CSSProperties,\n defineComponent,\n h,\n inject,\n onMounted,\n onUnmounted,\n type PropType,\n ref,\n watch,\n} from 'vue';\nimport { VizDarkModeKey, VizThemeKey } from './context';\n\nexport interface TileMapTileEvent {\n stateCode: string;\n stateName: string;\n value: number | null;\n data: Record<string, unknown>;\n}\n\nexport interface TileMapProps {\n spec: TileMapSpec;\n theme?: ThemeConfig;\n darkMode?: DarkMode;\n class?: string;\n style?: string | CSSProperties;\n}\n\nexport const TileMap = defineComponent({\n name: 'TileMap',\n props: {\n spec: {\n type: Object as PropType<TileMapSpec>,\n required: true,\n },\n theme: {\n type: Object as PropType<ThemeConfig>,\n default: undefined,\n },\n darkMode: {\n type: String as PropType<DarkMode>,\n default: undefined,\n },\n class: {\n type: String,\n default: undefined,\n },\n style: {\n type: [String, Object] as PropType<string | CSSProperties>,\n default: undefined,\n },\n },\n emits: {\n 'tile-click': (_tile: TileMapTileEvent) => true,\n 'tile-hover': (_tile: TileMapTileEvent | null) => true,\n },\n setup(props, { emit, expose }) {\n const containerRef = ref<HTMLDivElement | null>(null);\n let instance: TileMapInstance | null = null;\n let prevSpec = '';\n\n // Inject theme/darkMode from provider as fallbacks\n const contextTheme = inject(VizThemeKey, undefined);\n const contextDarkMode = inject(VizDarkModeKey, undefined);\n\n function resolveTheme(): ThemeConfig | undefined {\n return props.theme ?? contextTheme?.value;\n }\n\n function resolveDarkMode(): DarkMode | undefined {\n return props.darkMode ?? contextDarkMode?.value;\n }\n\n function mountTileMap() {\n const container = containerRef.value;\n if (!container) return;\n\n const options: TileMapMountOptions = {\n theme: resolveTheme(),\n darkMode: resolveDarkMode(),\n onTileClick: (tile: TileMapTileEvent) => emit('tile-click', tile),\n onTileHover: (tile: TileMapTileEvent | null) => emit('tile-hover', tile),\n responsive: true,\n };\n\n instance = createTileMap(container, props.spec, options);\n prevSpec = JSON.stringify(props.spec);\n }\n\n function destroyTileMap() {\n instance?.destroy();\n instance = null;\n prevSpec = '';\n }\n\n // Expose imperative access to the instance\n expose({\n get instance() {\n return instance;\n },\n });\n\n onMounted(() => {\n mountTileMap();\n });\n\n onUnmounted(() => {\n destroyTileMap();\n });\n\n // Watch spec changes\n watch(\n () => JSON.stringify(props.spec),\n (newVal) => {\n if (!instance) return;\n if (newVal !== prevSpec) {\n prevSpec = newVal;\n instance.update(props.spec);\n }\n },\n );\n\n // Recreate tilemap when theme or darkMode change\n watch(\n [\n () => props.theme,\n () => props.darkMode,\n () => contextTheme?.value,\n () => contextDarkMode?.value,\n ],\n () => {\n if (!containerRef.value) return;\n destroyTileMap();\n mountTileMap();\n },\n );\n\n const rootClass = () => {\n const base = 'oc-tilemap-root';\n return props.class ? `${base} ${props.class}` : base;\n };\n\n return () =>\n h('div', {\n ref: containerRef,\n class: rootClass(),\n style: props.style,\n });\n },\n});\n","/**\n * Visualization routing component: renders Chart, DataTable, or Graph\n * based on the spec type. Use this when rendering arbitrary VizSpec values.\n *\n * For event handlers, use the specific component (Chart, DataTable, Graph) directly.\n */\n\nimport type { DarkMode, ThemeConfig, VizSpec } from '@opendata-ai/openchart-core';\nimport {\n isBarListSpec,\n isGraphSpec,\n isMapSpec,\n isSankeySpec,\n isTableSpec,\n isTileMapSpec,\n} from '@opendata-ai/openchart-core';\nimport { type CSSProperties, defineComponent, h, type PropType } from 'vue';\nimport { BarList } from './BarList';\nimport { Chart } from './Chart';\nimport { DataTable } from './DataTable';\nimport { Graph } from './Graph';\nimport { GeoMap } from './Map';\nimport { Sankey } from './Sankey';\nimport { TileMap } from './TileMap';\n\nexport interface VisualizationProps {\n spec: VizSpec;\n theme?: ThemeConfig;\n darkMode?: DarkMode;\n class?: string;\n style?: string | CSSProperties;\n}\n\nexport const Visualization = defineComponent({\n name: 'Visualization',\n props: {\n spec: {\n type: Object as PropType<VizSpec>,\n required: true,\n },\n theme: {\n type: Object as PropType<ThemeConfig>,\n default: undefined,\n },\n darkMode: {\n type: String as PropType<DarkMode>,\n default: undefined,\n },\n class: {\n type: String,\n default: undefined,\n },\n style: {\n type: [String, Object] as PropType<string | CSSProperties>,\n default: undefined,\n },\n },\n setup(props) {\n return () => {\n const { spec, theme, darkMode, class: className, style } = props;\n const sharedProps = { theme, darkMode, class: className, style };\n\n if (isTableSpec(spec)) {\n return h(DataTable, { ...sharedProps, spec });\n }\n if (isGraphSpec(spec)) {\n return h(Graph, { ...sharedProps, spec });\n }\n if (isSankeySpec(spec)) {\n return h(Sankey, { ...sharedProps, spec });\n }\n if (isTileMapSpec(spec)) {\n return h(TileMap, { ...sharedProps, spec });\n }\n if (isBarListSpec(spec)) {\n return h(BarList, { ...sharedProps, spec });\n }\n if (isMapSpec(spec)) {\n return h(GeoMap, { ...sharedProps, spec });\n }\n return h(Chart, { ...sharedProps, spec });\n };\n },\n});\n"],"mappings":"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","names":["inject","inject","defineComponent","h","inject","onMounted","onUnmounted","ref","watch","defineComponent","ref","inject","onMounted","onUnmounted","watch","h","defineComponent","h","onMounted","onUnmounted","ref","watch","createChart","onMounted","onUnmounted","ref","watch","onUnmounted","ref","watch","ref","onMounted","onUnmounted","ref","shallowRef","watch","ref","createTable","defineComponent","h","inject","onMounted","onUnmounted","ref","watch","defineComponent","ref","inject","createTable","onMounted","onUnmounted","watch","h","defineComponent","h","inject","onMounted","onUnmounted","ref","watch","defineComponent","ref","inject","onMounted","onUnmounted","watch","h","defineComponent","h","inject","onMounted","onUnmounted","ref","watch","defineComponent","ref","inject","onMounted","onUnmounted","watch","h","defineComponent","h","inject","onMounted","onUnmounted","ref","watch","defineComponent","ref","inject","onMounted","onUnmounted","watch","h","computed","defineComponent","defineComponent","computed","defineComponent","h","inject","onMounted","onUnmounted","ref","watch","defineComponent","ref","inject","onMounted","onUnmounted","watch","h","defineComponent","h","defineComponent","h"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/BarList.ts","../src/context.ts","../src/Chart.ts","../src/ChartStory.ts","../src/composables/useChart.ts","../src/composables/useDarkMode.ts","../src/composables/useGraph.ts","../src/composables/useTable.ts","../src/composables/useTableState.ts","../src/DataTable.ts","../src/Graph.ts","../src/Map.ts","../src/Sankey.ts","../src/ThemeProvider.ts","../src/TileMap.ts","../src/Visualization.ts"],"sourcesContent":["/**\n * @opendata-ai/openchart-vue\n *\n * Vue 3 adapter for openchart. Provides <Chart />, <DataTable />, <Graph />,\n * and <VizThemeProvider /> components that wrap the vanilla adapter with\n * Vue lifecycle management.\n *\n * Re-exports the full core type system and utilities so Vue consumers\n * only need a single @opendata-ai/openchart-vue dependency.\n */\n\n// ---------------------------------------------------------------------------\n// Core: full type system, theme, colors, locale, accessibility, helpers\n// ---------------------------------------------------------------------------\n\nexport * from '@opendata-ai/openchart-core';\n\n// ---------------------------------------------------------------------------\n// Vanilla: export utilities (SVG/PNG/JPG/CSV)\n// ---------------------------------------------------------------------------\n\nexport type { JPGExportOptions, PNGExportOptions } from '@opendata-ai/openchart-vanilla';\nexport { exportCSV, exportJPG, exportPNG, exportSVG } from '@opendata-ai/openchart-vanilla';\n\n// ---------------------------------------------------------------------------\n// Engine: compile API and types not covered by core\n// ---------------------------------------------------------------------------\n\nexport type {\n ChartRenderer,\n CompiledGraphEdge,\n CompiledGraphNode,\n CompileResult,\n GraphCompilation,\n NormalizedBarListSpec,\n NormalizedChartSpec,\n NormalizedChrome,\n NormalizedGraphSpec,\n NormalizedMapSpec,\n NormalizedSankeySpec,\n NormalizedSpec,\n NormalizedTableSpec,\n SimulationConfig,\n ValidationError,\n ValidationErrorCode,\n ValidationResult,\n} from '@opendata-ai/openchart-engine';\nexport {\n clearRenderers,\n compile,\n compileBarList,\n compileChart,\n compileGraph,\n compileMap,\n compileSankey,\n compileTable,\n getChartRenderer,\n normalizeSpec,\n registerChartRenderer,\n validateSpec,\n} from '@opendata-ai/openchart-engine';\nexport type { BarListProps, BarListRowEvent } from './BarList';\nexport { BarList } from './BarList';\n// Components\nexport type { ChartProps } from './Chart';\nexport { Chart } from './Chart';\nexport type { ChartStoryProps } from './ChartStory';\n// Scrollytelling\nexport { ChartStory } from './ChartStory';\n// Composables\nexport type { UseChartOptions, UseChartReturn } from './composables/useChart';\nexport { useChart } from './composables/useChart';\nexport { useDarkMode } from './composables/useDarkMode';\nexport type { GraphHandle, UseGraphReturn } from './composables/useGraph';\nexport { useGraph } from './composables/useGraph';\nexport type { UseTableReturn } from './composables/useTable';\nexport { useTable } from './composables/useTable';\nexport type { UseTableStateOptions, UseTableStateReturn } from './composables/useTableState';\nexport { useTableState } from './composables/useTableState';\n// Context (injection keys and composables)\nexport { useVizDarkMode, useVizTheme, VizDarkModeKey, VizThemeKey } from './context';\nexport type { DataTableProps } from './DataTable';\nexport { DataTable } from './DataTable';\nexport type { GraphProps } from './Graph';\nexport { Graph } from './Graph';\nexport type { MapProps } from './Map';\nexport { GeoMap } from './Map';\nexport type { SankeyProps } from './Sankey';\nexport { Sankey } from './Sankey';\nexport type { VizThemeProviderProps } from './ThemeProvider';\nexport { VizThemeProvider } from './ThemeProvider';\nexport type { TileMapProps } from './TileMap';\nexport { TileMap } from './TileMap';\nexport type { VisualizationProps } from './Visualization';\nexport { Visualization } from './Visualization';\n","/**\n * Vue BarList component: thin wrapper around the vanilla adapter.\n */\n\nimport type { BarListSpec, DarkMode, ThemeConfig } from '@opendata-ai/openchart-core';\nimport {\n type BarListInstance,\n type BarListMountOptions,\n createBarList,\n} from '@opendata-ai/openchart-vanilla';\nimport {\n type CSSProperties,\n defineComponent,\n h,\n inject,\n onMounted,\n onUnmounted,\n type PropType,\n ref,\n watch,\n} from 'vue';\nimport { VizDarkModeKey, VizThemeKey } from './context';\n\nexport interface BarListRowEvent {\n label: string;\n value: number;\n data: Record<string, unknown>;\n}\n\nexport interface BarListProps {\n spec: BarListSpec;\n theme?: ThemeConfig;\n darkMode?: DarkMode;\n class?: string;\n style?: string | CSSProperties;\n}\n\nexport const BarList = defineComponent({\n name: 'BarList',\n props: {\n spec: {\n type: Object as PropType<BarListSpec>,\n required: true,\n },\n theme: {\n type: Object as PropType<ThemeConfig>,\n default: undefined,\n },\n darkMode: {\n type: String as PropType<DarkMode>,\n default: undefined,\n },\n class: {\n type: String,\n default: undefined,\n },\n style: {\n type: [String, Object] as PropType<string | CSSProperties>,\n default: undefined,\n },\n },\n emits: {\n 'row-click': (_row: BarListRowEvent) => true,\n 'row-hover': (_row: BarListRowEvent | null) => true,\n },\n setup(props, { emit, expose }) {\n const containerRef = ref<HTMLDivElement | null>(null);\n let instance: BarListInstance | null = null;\n let prevSpec = '';\n\n const contextTheme = inject(VizThemeKey, undefined);\n const contextDarkMode = inject(VizDarkModeKey, undefined);\n\n function resolveTheme(): ThemeConfig | undefined {\n return props.theme ?? contextTheme?.value;\n }\n\n function resolveDarkMode(): DarkMode | undefined {\n return props.darkMode ?? contextDarkMode?.value;\n }\n\n function mountBarList() {\n const container = containerRef.value;\n if (!container) return;\n\n const options: BarListMountOptions = {\n theme: resolveTheme(),\n darkMode: resolveDarkMode(),\n onRowClick: (row: BarListRowEvent) => emit('row-click', row),\n onRowHover: (row: BarListRowEvent | null) => emit('row-hover', row),\n responsive: true,\n };\n\n instance = createBarList(container, props.spec, options);\n prevSpec = JSON.stringify(props.spec);\n }\n\n function destroyBarList() {\n instance?.destroy();\n instance = null;\n prevSpec = '';\n }\n\n expose({\n get instance() {\n return instance;\n },\n });\n\n onMounted(() => {\n mountBarList();\n });\n\n onUnmounted(() => {\n destroyBarList();\n });\n\n watch(\n () => JSON.stringify(props.spec),\n (newVal) => {\n if (!instance) return;\n if (newVal !== prevSpec) {\n prevSpec = newVal;\n instance.update(props.spec);\n }\n },\n );\n\n watch(\n [\n () => props.theme,\n () => props.darkMode,\n () => contextTheme?.value,\n () => contextDarkMode?.value,\n ],\n () => {\n if (!containerRef.value) return;\n destroyBarList();\n mountBarList();\n },\n );\n\n const rootClass = () => {\n const base = 'oc-barlist-root';\n return props.class ? `${base} ${props.class}` : base;\n };\n\n return () =>\n h('div', {\n ref: containerRef,\n class: rootClass(),\n style: props.style,\n });\n },\n});\n","/**\n * Theme injection context for Vue.\n *\n * Provides typed injection keys and composables for accessing theme\n * and dark mode from any descendant component within a VizThemeProvider.\n */\n\nimport type { DarkMode, ThemeConfig } from '@opendata-ai/openchart-core';\nimport { type ComputedRef, computed, type InjectionKey, inject, type Ref } from 'vue';\n\n/** Injection key for the theme config ref. */\nexport const VizThemeKey: InjectionKey<Ref<ThemeConfig | undefined>> = Symbol('VizTheme');\n\n/** Injection key for the dark mode ref. */\nexport const VizDarkModeKey: InjectionKey<Ref<DarkMode | undefined>> = Symbol('VizDarkMode');\n\n/**\n * Read the current theme from the nearest VizThemeProvider.\n * Returns a computed ref that stays reactive to provider changes.\n */\nexport function useVizTheme(): ComputedRef<ThemeConfig | undefined> {\n const theme = inject(VizThemeKey, undefined);\n return computed(() => theme?.value);\n}\n\n/**\n * Read the current dark mode preference from the nearest VizThemeProvider.\n * Returns a computed ref that stays reactive to provider changes.\n */\nexport function useVizDarkMode(): ComputedRef<DarkMode | undefined> {\n const darkMode = inject(VizDarkModeKey, undefined);\n return computed(() => darkMode?.value);\n}\n","/**\n * Vue Chart component: thin wrapper around the vanilla adapter.\n *\n * Mounts a chart instance on render, updates when spec changes,\n * and cleans up on unmount. All heavy lifting is done by the vanilla\n * createChart() function.\n */\n\nimport type {\n Annotation,\n AnnotationOffset,\n ChartSpec,\n DarkMode,\n ElementEdit,\n ElementRef,\n GraphSpec,\n LayerSpec,\n MarkEvent,\n TextAnnotation,\n ThemeConfig,\n} from '@opendata-ai/openchart-core';\nimport { type ChartInstance, createChart, type MountOptions } from '@opendata-ai/openchart-vanilla';\nimport {\n type CSSProperties,\n defineComponent,\n getCurrentInstance,\n h,\n inject,\n onMounted,\n onUnmounted,\n type PropType,\n ref,\n watch,\n} from 'vue';\nimport { VizDarkModeKey, VizThemeKey } from './context';\n\nexport interface ChartProps {\n spec: ChartSpec | LayerSpec | GraphSpec;\n theme?: ThemeConfig;\n darkMode?: DarkMode;\n class?: string;\n style?: string | CSSProperties;\n}\n\nexport const Chart = defineComponent({\n name: 'Chart',\n props: {\n spec: {\n type: Object as PropType<ChartSpec | LayerSpec | GraphSpec>,\n required: true,\n },\n theme: {\n type: Object as PropType<ThemeConfig>,\n default: undefined,\n },\n darkMode: {\n type: String as PropType<DarkMode>,\n default: undefined,\n },\n class: {\n type: String,\n default: undefined,\n },\n style: {\n type: [String, Object] as PropType<string | CSSProperties>,\n default: undefined,\n },\n selectedElement: {\n type: Object as PropType<ElementRef>,\n default: undefined,\n },\n highlight: {\n type: [Array, null] as unknown as PropType<string[] | null>,\n default: undefined,\n },\n },\n emits: {\n 'mark-click': (_event: MarkEvent) => true,\n 'mark-hover': (_event: MarkEvent) => true,\n 'mark-leave': () => true,\n 'legend-toggle': (_series: string, _visible: boolean) => true,\n 'annotation-click': (_annotation: Annotation, _event: MouseEvent) => true,\n 'annotation-edit': (_annotation: TextAnnotation, _updatedOffset: AnnotationOffset) => true,\n edit: (_edit: ElementEdit) => true,\n select: (_element: ElementRef) => true,\n deselect: (_element: ElementRef) => true,\n 'text-edit': (_element: ElementRef, _oldText: string, _newText: string) => true,\n 'data-point-click': (_data: Record<string, unknown>) => true,\n },\n setup(props, { emit, expose }) {\n const containerRef = ref<HTMLDivElement | null>(null);\n let instance: ChartInstance | null = null;\n let prevSpec = '';\n\n // Inject theme/darkMode from provider as fallbacks\n const contextTheme = inject(VizThemeKey, undefined);\n const contextDarkMode = inject(VizDarkModeKey, undefined);\n\n // Check which event listeners are bound by the parent.\n // Vue 3 passes listeners as onXxx props on the component vnode.\n // We cache this at setup time since it won't change.\n const vm = getCurrentInstance();\n const vnodeProps = vm?.vnode.props ?? {};\n const hasAnnotationEditListener =\n 'onAnnotation-edit' in vnodeProps || 'onAnnotationEdit' in vnodeProps;\n const hasEditListener = 'onEdit' in vnodeProps;\n const hasSelectListener = 'onSelect' in vnodeProps;\n const hasDeselectListener = 'onDeselect' in vnodeProps;\n const hasTextEditListener = 'onText-edit' in vnodeProps || 'onTextEdit' in vnodeProps;\n\n function resolveTheme(): ThemeConfig | undefined {\n return props.theme ?? contextTheme?.value;\n }\n\n function resolveDarkMode(): DarkMode | undefined {\n return props.darkMode ?? contextDarkMode?.value;\n }\n\n function mountChart() {\n const container = containerRef.value;\n if (!container) return;\n\n const options: MountOptions = {\n theme: resolveTheme(),\n darkMode: resolveDarkMode(),\n onDataPointClick: (data: Record<string, unknown>) => emit('data-point-click', data),\n onMarkClick: (event: MarkEvent) => emit('mark-click', event),\n onMarkHover: (event: MarkEvent) => emit('mark-hover', event),\n onMarkLeave: () => emit('mark-leave'),\n onLegendToggle: (series: string, visible: boolean) =>\n emit('legend-toggle', series, visible),\n onAnnotationClick: (annotation: Annotation, event: MouseEvent) =>\n emit('annotation-click', annotation, event),\n // Only include editing callbacks when the parent binds a listener.\n // Without this gate, every chart gets drag editing wired up.\n ...(hasAnnotationEditListener\n ? {\n onAnnotationEdit: (annotation: TextAnnotation, updatedOffset: AnnotationOffset) =>\n emit('annotation-edit', annotation, updatedOffset),\n }\n : {}),\n ...(hasEditListener ? { onEdit: (edit: ElementEdit) => emit('edit', edit) } : {}),\n ...(hasSelectListener\n ? { onSelect: (element: ElementRef) => emit('select', element) }\n : {}),\n ...(hasDeselectListener\n ? { onDeselect: (element: ElementRef) => emit('deselect', element) }\n : {}),\n ...(hasTextEditListener\n ? {\n onTextEdit: (element: ElementRef, oldText: string, newText: string) =>\n emit('text-edit', element, oldText, newText),\n }\n : {}),\n ...(props.selectedElement ? { selectedElement: props.selectedElement } : {}),\n responsive: true,\n };\n\n instance = createChart(container, props.spec, options);\n prevSpec = JSON.stringify(props.spec);\n if (props.highlight !== undefined) {\n instance.setHighlight(props.highlight ?? null);\n }\n }\n\n function destroyChart() {\n instance?.destroy();\n instance = null;\n prevSpec = '';\n }\n\n // Expose imperative methods for parent ref access\n expose({\n getSelectedElement(): ElementRef | null {\n return instance?.getSelectedElement() ?? null;\n },\n select(elementRef: ElementRef): void {\n instance?.select(elementRef);\n },\n deselect(): void {\n instance?.deselect();\n },\n get instance() {\n return instance;\n },\n });\n\n onMounted(() => {\n mountChart();\n });\n\n onUnmounted(() => {\n destroyChart();\n });\n\n // Watch spec changes: update if only spec changed, recreate if theme/darkMode changed\n watch(\n () => JSON.stringify(props.spec),\n (newVal) => {\n if (!instance) return;\n if (newVal !== prevSpec) {\n prevSpec = newVal;\n instance.update(props.spec, { selectedElement: props.selectedElement });\n }\n },\n );\n\n // Watch selectedElement prop changes\n watch(\n () => props.selectedElement,\n (newVal) => {\n if (!instance) return;\n if (newVal) {\n instance.select(newVal);\n } else {\n instance.deselect();\n }\n },\n );\n\n // Watch highlight prop changes\n watch(\n () => props.highlight,\n (newVal) => {\n if (!instance) return;\n instance.setHighlight(newVal ?? null);\n },\n );\n\n // Recreate chart when theme or darkMode change\n watch(\n [\n () => props.theme,\n () => props.darkMode,\n () => contextTheme?.value,\n () => contextDarkMode?.value,\n ],\n () => {\n if (!containerRef.value) return;\n destroyChart();\n mountChart();\n },\n );\n\n const rootClass = () => {\n const base = 'oc-chart-root';\n return props.class ? `${base} ${props.class}` : base;\n };\n\n return () =>\n h('div', {\n ref: containerRef,\n class: rootClass(),\n style: props.style,\n });\n },\n});\n","/**\n * Vue scrollytelling shell around the vanilla `createChartStory`.\n *\n * Mirrors the React `<ChartStory>`: a sticky chart panel plus a scrolling\n * narrative column whose blocks advance the story. The vanilla driver owns\n * cumulative patch application, mark morphing, crossfade, and camera; this\n * component owns only Vue lifecycle and the sticky layout.\n *\n * Narrative is provided as the default slot's children (one root node per\n * step) or via the `narrative` prop (an array of vnodes/strings). Pass `step`\n * to drive it externally; omit for self-driving scroll.\n */\n\nimport type { ChartSpec, GraphSpec, LayerSpec, MapSpec } from '@opendata-ai/openchart-core';\nimport type { MountOptions } from '@opendata-ai/openchart-vanilla';\nimport {\n type ChartStoryInstance,\n type ChartStoryOptions,\n createChartStory,\n} from '@opendata-ai/openchart-vanilla/story';\nimport {\n type CSSProperties,\n defineComponent,\n h,\n onMounted,\n onUnmounted,\n type PropType,\n ref,\n type VNode,\n watch,\n} from 'vue';\n\nexport interface ChartStoryProps {\n spec: ChartSpec | LayerSpec | GraphSpec | MapSpec;\n steps: ChartStoryOptions['steps'];\n narrative?: VNode[];\n step?: number;\n triggerPosition?: number;\n cameraMode?: 'step' | 'scrub';\n mountOptions?: MountOptions;\n}\n\nconst sectionStyle: CSSProperties = {\n position: 'relative',\n display: 'grid',\n gridTemplateColumns: 'minmax(0, 26rem) minmax(0, 1fr)',\n gap: '3rem',\n alignItems: 'start',\n};\n\nconst stepStyle: CSSProperties = {\n minHeight: '80vh',\n display: 'flex',\n alignItems: 'center',\n};\n\nconst panelStyle: CSSProperties = {\n position: 'sticky',\n top: '2rem',\n height: 'calc(100vh - 4rem)',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n};\n\nexport const ChartStory = defineComponent({\n name: 'ChartStory',\n props: {\n spec: {\n type: Object as PropType<ChartSpec | LayerSpec | GraphSpec | MapSpec>,\n required: true,\n },\n steps: {\n type: Array as PropType<ChartStoryOptions['steps']>,\n required: true,\n },\n narrative: {\n type: Array as PropType<VNode[]>,\n default: undefined,\n },\n step: {\n type: Number,\n default: undefined,\n },\n triggerPosition: {\n type: Number,\n default: undefined,\n },\n cameraMode: {\n type: String as PropType<'step' | 'scrub'>,\n default: undefined,\n },\n mountOptions: {\n type: Object as PropType<MountOptions>,\n default: undefined,\n },\n },\n setup(props, { slots, expose }) {\n const sectionRef = ref<HTMLElement | null>(null);\n const mountRef = ref<HTMLDivElement | null>(null);\n const stepEls = ref<Array<HTMLElement | null>>([]);\n let story: ChartStoryInstance | null = null;\n\n onMounted(() => {\n const mount = mountRef.value;\n if (!mount) return;\n\n const blocks = props.narrative ?? [];\n if (blocks.length > 0 && blocks.length !== props.steps.length) {\n console.warn(\n `[openchart] ChartStory: narrative length (${blocks.length}) does not match steps length (${props.steps.length}). Each step should have a corresponding narrative element.`,\n );\n }\n\n story = createChartStory(\n mount,\n {\n spec: props.spec,\n steps: props.steps,\n triggerPosition: props.triggerPosition,\n cameraMode: props.cameraMode,\n },\n props.mountOptions,\n );\n if (sectionRef.value) story.setContainer(sectionRef.value);\n stepEls.value.forEach((el, i) => {\n if (el) story?.registerStep(i, el);\n });\n if (props.step !== undefined) story.goTo(props.step);\n });\n\n watch(\n () => props.step,\n (next) => {\n if (next !== undefined) story?.goTo(next);\n },\n );\n\n onUnmounted(() => {\n story?.destroy();\n story = null;\n });\n\n expose({\n goTo(index: number) {\n story?.goTo(index);\n },\n get instance() {\n return story;\n },\n });\n\n return () => {\n // Prefer the `narrative` prop; fall back to default slot children so\n // consumers can author steps as template markup.\n const blocks = props.narrative ?? slots.default?.() ?? [];\n return h('section', { ref: sectionRef, style: sectionStyle }, [\n h(\n 'div',\n { style: { position: 'relative' } },\n blocks.map((content, i) =>\n h(\n 'div',\n {\n // Steps are a fixed ordered list, so the index is the stable\n // identity. Do not reorder or splice narrative entries at runtime\n // (that would remap step refs to the wrong content); rebuild the\n // whole story instead.\n key: i,\n ref: (el: unknown) => {\n stepEls.value[i] = el as HTMLElement | null;\n },\n 'data-oc-story-step': i,\n style: stepStyle,\n },\n [h('div', { style: { maxWidth: '36rem' } }, [content])],\n ),\n ),\n ),\n h('div', { style: panelStyle }, [h('div', { ref: mountRef, style: { width: '100%' } })]),\n ]);\n };\n },\n});\n","/**\n * useChart: composable for manual chart lifecycle control.\n *\n * Provides a template ref to attach to a container div. The chart\n * mounts automatically and updates when the spec changes.\n */\n\nimport type {\n ChartLayout,\n ChartSpec,\n DarkMode,\n GraphSpec,\n LayerSpec,\n ThemeConfig,\n} from '@opendata-ai/openchart-core';\nimport { type ChartInstance, createChart, type MountOptions } from '@opendata-ai/openchart-vanilla';\nimport { onMounted, onUnmounted, type Ref, ref, type ShallowRef, shallowRef, watch } from 'vue';\n\nexport interface UseChartOptions {\n /** Theme overrides. */\n theme?: ThemeConfig;\n /** Dark mode setting. */\n darkMode?: DarkMode;\n /** Data point click handler. */\n onDataPointClick?: MountOptions['onDataPointClick'];\n /** Enable responsive resizing. Defaults to true. */\n responsive?: boolean;\n}\n\nexport interface UseChartReturn {\n /** Template ref to attach to the container div. */\n containerRef: Ref<HTMLDivElement | null>;\n /** The chart instance (null until mounted). */\n chart: ShallowRef<ChartInstance | null>;\n /** The current compiled layout (null until mounted). */\n layout: ShallowRef<ChartLayout | null>;\n}\n\n/**\n * Composable for manual chart lifecycle control.\n *\n * Attach the returned containerRef to a container div via `ref=\"containerRef\"`.\n * The chart mounts automatically and updates when the spec changes.\n */\nexport function useChart(\n spec: Ref<ChartSpec | LayerSpec | GraphSpec>,\n options?: UseChartOptions,\n): UseChartReturn {\n const containerRef = ref<HTMLDivElement | null>(null);\n const chart = shallowRef<ChartInstance | null>(null);\n const layout = shallowRef<ChartLayout | null>(null);\n\n function mount() {\n const container = containerRef.value;\n if (!container) return;\n\n const mountOpts: MountOptions = {\n theme: options?.theme,\n darkMode: options?.darkMode,\n onDataPointClick: options?.onDataPointClick,\n responsive: options?.responsive,\n };\n\n const instance = createChart(container, spec.value, mountOpts);\n chart.value = instance;\n layout.value = instance.layout;\n }\n\n function destroy() {\n chart.value?.destroy();\n chart.value = null;\n layout.value = null;\n }\n\n onMounted(() => {\n mount();\n });\n\n onUnmounted(() => {\n destroy();\n });\n\n // Update on spec change\n watch(spec, (newSpec) => {\n const instance = chart.value;\n if (!instance) return;\n instance.update(newSpec);\n layout.value = instance.layout;\n });\n\n return {\n containerRef,\n chart,\n layout,\n };\n}\n","/**\n * useDarkMode: composable that resolves a DarkMode preference to a boolean.\n *\n * - \"force\" -> true\n * - \"off\" -> false\n * - \"auto\" -> matches system preference (reactive to changes)\n */\n\nimport type { DarkMode } from '@opendata-ai/openchart-core';\nimport { onUnmounted, type Ref, ref, watch } from 'vue';\n\n/**\n * Resolve a DarkMode preference to a reactive boolean.\n *\n * For \"auto\" mode, watches the system `prefers-color-scheme` media query\n * and updates reactively when the user changes their OS theme.\n */\nexport function useDarkMode(mode: Ref<DarkMode | undefined>): Ref<boolean> {\n const isDark = ref(resolveInitial(mode.value));\n let cleanup: (() => void) | null = null;\n\n function setup(currentMode: DarkMode | undefined) {\n // Clean up previous listener\n cleanup?.();\n cleanup = null;\n\n if (currentMode !== 'auto') {\n isDark.value = currentMode === 'force';\n return;\n }\n\n if (typeof window === 'undefined' || !window.matchMedia) {\n isDark.value = false;\n return;\n }\n\n const mq = window.matchMedia('(prefers-color-scheme: dark)');\n isDark.value = mq.matches;\n\n const handler = (e: MediaQueryListEvent) => {\n isDark.value = e.matches;\n };\n mq.addEventListener('change', handler);\n cleanup = () => mq.removeEventListener('change', handler);\n }\n\n // Run setup for initial value\n setup(mode.value);\n\n // React to mode changes\n watch(mode, (newMode) => {\n setup(newMode);\n });\n\n onUnmounted(() => {\n cleanup?.();\n cleanup = null;\n });\n\n return isDark;\n}\n\nfunction resolveInitial(mode?: DarkMode): boolean {\n if (mode === 'force') return true;\n if (mode === 'off' || mode === undefined) return false;\n // \"auto\"\n if (typeof window !== 'undefined' && window.matchMedia) {\n return window.matchMedia('(prefers-color-scheme: dark)').matches;\n }\n return false;\n}\n","/**\n * useGraph: composable for imperative graph control.\n *\n * Provides a template ref to pass to <Graph /> and exposes graph methods\n * (search, zoom, select) for programmatic control of the graph instance.\n */\n\nimport type { GraphInstance } from '@opendata-ai/openchart-vanilla';\nimport { type Ref, ref } from 'vue';\n\n/** Handle exposed by Graph component via expose(). */\nexport interface GraphHandle {\n search: (query: string) => void;\n clearSearch: () => void;\n zoomToFit: () => void;\n zoomToNode: (nodeId: string) => void;\n selectNode: (nodeId: string) => void;\n getSelectedNodes: () => string[];\n /** The underlying GraphInstance from the vanilla adapter. */\n instance: GraphInstance | null;\n}\n\nexport interface UseGraphReturn {\n /** Template ref to pass to <Graph ref={graphRef} />. */\n graphRef: Ref<GraphHandle | null>;\n /** Search for nodes matching a query string. */\n search: (query: string) => void;\n /** Clear the current search. */\n clearSearch: () => void;\n /** Zoom to fit all nodes in view. */\n zoomToFit: () => void;\n /** Zoom and center on a specific node. */\n zoomToNode: (nodeId: string) => void;\n /** Select a node by id. */\n selectNode: (nodeId: string) => void;\n /** Get the currently selected node ids. */\n getSelectedNodes: () => string[];\n}\n\n/**\n * Composable for imperative graph control.\n *\n * Usage:\n * ```vue\n * <script setup>\n * const { graphRef, search, zoomToFit } = useGraph();\n * </script>\n * <template>\n * <Graph ref=\"graphRef\" :spec=\"spec\" />\n * </template>\n * ```\n */\nexport function useGraph(): UseGraphReturn {\n const graphRef = ref<GraphHandle | null>(null);\n\n function search(query: string) {\n graphRef.value?.search(query);\n }\n\n function clearSearch() {\n graphRef.value?.clearSearch();\n }\n\n function zoomToFit() {\n graphRef.value?.zoomToFit();\n }\n\n function zoomToNode(nodeId: string) {\n graphRef.value?.zoomToNode(nodeId);\n }\n\n function selectNode(nodeId: string) {\n graphRef.value?.selectNode(nodeId);\n }\n\n function getSelectedNodes(): string[] {\n return graphRef.value?.getSelectedNodes() ?? [];\n }\n\n return {\n graphRef,\n search,\n clearSearch,\n zoomToFit,\n zoomToNode,\n selectNode,\n getSelectedNodes,\n };\n}\n","/**\n * useTable: composable for manual table lifecycle control.\n *\n * Attaches to a container ref, mounts a vanilla table instance,\n * and exposes the instance and current state.\n */\n\nimport type { TableSpec } from '@opendata-ai/openchart-core';\nimport {\n createTable,\n type TableInstance,\n type TableMountOptions,\n type TableState,\n} from '@opendata-ai/openchart-vanilla';\nimport { onMounted, onUnmounted, type Ref, ref, type ShallowRef, shallowRef, watch } from 'vue';\n\nexport interface UseTableReturn {\n /** Template ref to attach to the container div. */\n containerRef: Ref<HTMLDivElement | null>;\n /** The table instance (null until mounted). */\n table: ShallowRef<TableInstance | null>;\n /** The current table state (sort, search, page). */\n state: Ref<TableState>;\n}\n\n/**\n * Composable for manual table lifecycle control.\n *\n * Attach the returned containerRef to a container div via `ref=\"containerRef\"`.\n * The table mounts automatically and updates when the spec changes.\n */\nexport function useTable(spec: Ref<TableSpec>, options?: TableMountOptions): UseTableReturn {\n const containerRef = ref<HTMLDivElement | null>(null);\n const table = shallowRef<TableInstance | null>(null);\n const state = ref<TableState>({\n sort: null,\n search: '',\n page: 0,\n });\n\n const originalOnStateChange = options?.onStateChange;\n\n function handleStateChange(newState: TableState) {\n state.value = newState;\n originalOnStateChange?.(newState);\n }\n\n function mount() {\n const container = containerRef.value;\n if (!container) return;\n\n const mountOpts: TableMountOptions = {\n ...options,\n onStateChange: handleStateChange,\n };\n\n const instance = createTable(container, spec.value, mountOpts);\n table.value = instance;\n state.value = instance.getState();\n }\n\n function destroy() {\n table.value?.destroy();\n table.value = null;\n }\n\n onMounted(() => {\n mount();\n });\n\n onUnmounted(() => {\n destroy();\n });\n\n // Update on spec change\n watch(spec, (newSpec) => {\n const instance = table.value;\n if (!instance) return;\n instance.update(newSpec);\n state.value = instance.getState();\n });\n\n return {\n containerRef,\n table,\n state,\n };\n}\n","/**\n * useTableState: managed state composable for controlled table usage.\n *\n * Provides individual sort/search/page state with setters and a\n * resetState function to return to initial values.\n */\n\nimport type { SortState } from '@opendata-ai/openchart-core';\nimport { type Ref, ref } from 'vue';\n\nexport interface UseTableStateReturn {\n sort: Ref<SortState | null>;\n setSort: (sort: SortState | null) => void;\n search: Ref<string>;\n setSearch: (query: string) => void;\n page: Ref<number>;\n setPage: (page: number) => void;\n resetState: () => void;\n}\n\nexport interface UseTableStateOptions {\n sort?: SortState | null;\n search?: string;\n page?: number;\n}\n\n/**\n * Composable for managing table state (sort, search, page).\n *\n * Use with the DataTable component's controlled props:\n * ```vue\n * <script setup>\n * const { sort, search, page, setSort, setSearch, setPage } = useTableState();\n * </script>\n * <template>\n * <DataTable\n * :spec=\"spec\"\n * :sort=\"sort\"\n * :search=\"search\"\n * :page=\"page\"\n * @update:sort=\"setSort\"\n * @update:search=\"setSearch\"\n * @update:page=\"setPage\"\n * />\n * </template>\n * ```\n */\nexport function useTableState(initialState?: UseTableStateOptions): UseTableStateReturn {\n const sort = ref<SortState | null>(initialState?.sort ?? null);\n const search = ref(initialState?.search ?? '');\n const page = ref(initialState?.page ?? 0);\n\n function setSort(newSort: SortState | null) {\n sort.value = newSort;\n }\n\n function setSearch(query: string) {\n search.value = query;\n }\n\n function setPage(newPage: number) {\n page.value = newPage;\n }\n\n function resetState() {\n sort.value = initialState?.sort ?? null;\n search.value = initialState?.search ?? '';\n page.value = initialState?.page ?? 0;\n }\n\n return {\n sort,\n setSort,\n search,\n setSearch,\n page,\n setPage,\n resetState,\n };\n}\n","/**\n * DataTable component: Vue wrapper around the vanilla table adapter.\n *\n * Mounts a table instance on render, updates when spec changes,\n * and cleans up on unmount. Supports both controlled and uncontrolled modes\n * for sort, search, and pagination state.\n */\n\nimport type { DarkMode, SortState, TableSpec, ThemeConfig } from '@opendata-ai/openchart-core';\nimport {\n createTable,\n type TableInstance,\n type TableMountOptions,\n} from '@opendata-ai/openchart-vanilla';\nimport {\n type CSSProperties,\n defineComponent,\n h,\n inject,\n onMounted,\n onUnmounted,\n type PropType,\n ref,\n watch,\n} from 'vue';\nimport { VizDarkModeKey, VizThemeKey } from './context';\n\nexport interface DataTableProps {\n spec: TableSpec;\n theme?: ThemeConfig;\n darkMode?: DarkMode;\n class?: string;\n style?: string | CSSProperties;\n sort?: SortState | null;\n search?: string;\n page?: number;\n}\n\nexport const DataTable = defineComponent({\n name: 'DataTable',\n props: {\n spec: {\n type: Object as PropType<TableSpec>,\n required: true,\n },\n theme: {\n type: Object as PropType<ThemeConfig>,\n default: undefined,\n },\n darkMode: {\n type: String as PropType<DarkMode>,\n default: undefined,\n },\n class: {\n type: String,\n default: undefined,\n },\n style: {\n type: [String, Object] as PropType<string | CSSProperties>,\n default: undefined,\n },\n sort: {\n type: [Object, null] as PropType<SortState | null>,\n default: undefined,\n },\n search: {\n type: String,\n default: undefined,\n },\n page: {\n type: Number,\n default: undefined,\n },\n },\n emits: {\n 'row-click': (_row: Record<string, unknown>) => true,\n 'update:sort': (_sort: SortState | null) => true,\n 'update:search': (_query: string) => true,\n 'update:page': (_page: number) => true,\n },\n setup(props, { emit }) {\n const containerRef = ref<HTMLDivElement | null>(null);\n let instance: TableInstance | null = null;\n\n // Inject theme/darkMode from provider as fallbacks\n const contextTheme = inject(VizThemeKey, undefined);\n const contextDarkMode = inject(VizDarkModeKey, undefined);\n\n function resolveTheme(): ThemeConfig | undefined {\n return props.theme ?? contextTheme?.value;\n }\n\n function resolveDarkMode(): DarkMode | undefined {\n return props.darkMode ?? contextDarkMode?.value;\n }\n\n function isControlled(): boolean {\n return props.sort !== undefined || props.search !== undefined || props.page !== undefined;\n }\n\n let prevSpec = '';\n\n function mountTable() {\n const container = containerRef.value;\n if (!container) return;\n\n const mountOptions: TableMountOptions = {\n theme: resolveTheme(),\n darkMode: resolveDarkMode(),\n onRowClick: (row: Record<string, unknown>) => emit('row-click', row),\n responsive: true,\n onStateChange: (state) => {\n if (state.sort !== undefined) emit('update:sort', state.sort);\n if (state.search !== undefined) emit('update:search', state.search);\n if (state.page !== undefined) emit('update:page', state.page);\n },\n };\n\n if (isControlled()) {\n mountOptions.externalState = {\n sort: props.sort ?? null,\n search: props.search ?? '',\n page: props.page ?? 0,\n };\n }\n\n instance = createTable(container, props.spec, mountOptions);\n prevSpec = JSON.stringify(props.spec);\n }\n\n function destroyTable() {\n instance?.destroy();\n instance = null;\n prevSpec = '';\n }\n\n onMounted(() => {\n mountTable();\n });\n\n onUnmounted(() => {\n destroyTable();\n });\n\n // Watch spec changes via JSON.stringify comparison (consistent with Chart/Graph)\n watch(\n () => JSON.stringify(props.spec),\n (newVal) => {\n if (!instance) return;\n if (newVal !== prevSpec) {\n prevSpec = newVal;\n instance.update(props.spec);\n }\n },\n );\n\n // Recreate when theme or darkMode change\n watch(\n [\n () => props.theme,\n () => props.darkMode,\n () => contextTheme?.value,\n () => contextDarkMode?.value,\n ],\n () => {\n if (!containerRef.value) return;\n destroyTable();\n mountTable();\n },\n );\n\n // Sync controlled state without remounting\n watch([() => props.sort, () => props.search, () => props.page], () => {\n if (!instance || !isControlled()) return;\n instance.setState({\n sort: props.sort ?? null,\n search: props.search ?? '',\n page: props.page ?? 0,\n });\n });\n\n const rootClass = () => {\n const base = 'oc-table-root';\n return props.class ? `${base} ${props.class}` : base;\n };\n\n return () =>\n h('div', {\n ref: containerRef,\n class: rootClass(),\n style: props.style,\n });\n },\n});\n","/**\n * Vue Graph component: thin wrapper around the vanilla adapter.\n *\n * Mounts a graph instance on render, updates when spec changes,\n * and cleans up on unmount. All heavy lifting is done by the vanilla\n * createGraph() function.\n *\n * Exposes imperative methods via defineExpose for use with useGraph().\n */\n\nimport type { DarkMode, GraphSpec, ThemeConfig } from '@opendata-ai/openchart-core';\nimport {\n createGraph,\n type GraphInstance,\n type GraphMountOptions,\n} from '@opendata-ai/openchart-vanilla';\nimport {\n type CSSProperties,\n defineComponent,\n h,\n inject,\n onMounted,\n onUnmounted,\n type PropType,\n ref,\n watch,\n} from 'vue';\nimport { VizDarkModeKey, VizThemeKey } from './context';\n\nexport interface GraphProps {\n spec: GraphSpec;\n theme?: ThemeConfig;\n darkMode?: DarkMode;\n class?: string;\n style?: string | CSSProperties;\n}\n\nexport const Graph = defineComponent({\n name: 'Graph',\n props: {\n spec: {\n type: Object as PropType<GraphSpec>,\n required: true,\n },\n theme: {\n type: Object as PropType<ThemeConfig>,\n default: undefined,\n },\n darkMode: {\n type: String as PropType<DarkMode>,\n default: undefined,\n },\n class: {\n type: String,\n default: undefined,\n },\n style: {\n type: [String, Object] as PropType<string | CSSProperties>,\n default: undefined,\n },\n },\n emits: {\n 'node-click': (_node: Record<string, unknown>) => true,\n 'node-double-click': (_node: Record<string, unknown>) => true,\n 'selection-change': (_nodeIds: string[]) => true,\n },\n setup(props, { emit, expose }) {\n const containerRef = ref<HTMLDivElement | null>(null);\n let instance: GraphInstance | null = null;\n let prevSpec = '';\n\n // Inject theme/darkMode from provider as fallbacks\n const contextTheme = inject(VizThemeKey, undefined);\n const contextDarkMode = inject(VizDarkModeKey, undefined);\n\n function resolveTheme(): ThemeConfig | undefined {\n return props.theme ?? contextTheme?.value;\n }\n\n function resolveDarkMode(): DarkMode | undefined {\n return props.darkMode ?? contextDarkMode?.value;\n }\n\n function mountGraph() {\n const container = containerRef.value;\n if (!container) return;\n\n const options: GraphMountOptions = {\n theme: resolveTheme(),\n darkMode: resolveDarkMode(),\n onNodeClick: (node: Record<string, unknown>) => emit('node-click', node),\n onNodeDoubleClick: (node: Record<string, unknown>) => emit('node-double-click', node),\n onSelectionChange: (nodeIds: string[]) => emit('selection-change', nodeIds),\n responsive: true,\n };\n\n instance = createGraph(container, props.spec, options);\n prevSpec = JSON.stringify(props.spec);\n }\n\n function destroyGraph() {\n instance?.destroy();\n instance = null;\n prevSpec = '';\n }\n\n // Expose imperative methods for useGraph() composable\n expose({\n search(query: string) {\n instance?.search(query);\n },\n clearSearch() {\n instance?.clearSearch();\n },\n zoomToFit() {\n instance?.zoomToFit();\n },\n zoomToNode(nodeId: string) {\n instance?.zoomToNode(nodeId);\n },\n selectNode(nodeId: string) {\n instance?.selectNode(nodeId);\n },\n getSelectedNodes(): string[] {\n return instance?.getSelectedNodes() ?? [];\n },\n get instance() {\n return instance;\n },\n });\n\n onMounted(() => {\n mountGraph();\n });\n\n onUnmounted(() => {\n destroyGraph();\n });\n\n // Watch spec changes\n watch(\n () => JSON.stringify(props.spec),\n (newVal) => {\n if (!instance) return;\n if (newVal !== prevSpec) {\n prevSpec = newVal;\n instance.update(props.spec);\n }\n },\n );\n\n // Recreate graph when theme or darkMode change\n watch(\n [\n () => props.theme,\n () => props.darkMode,\n () => contextTheme?.value,\n () => contextDarkMode?.value,\n ],\n () => {\n if (!containerRef.value) return;\n destroyGraph();\n mountGraph();\n },\n );\n\n const rootClass = () => {\n const base = 'oc-graph-root';\n return props.class ? `${base} ${props.class}` : base;\n };\n\n return () =>\n h('div', {\n ref: containerRef,\n class: rootClass(),\n style: props.style,\n });\n },\n});\n","/**\n * Vue Map component: thin wrapper around the vanilla adapter.\n *\n * Mounts a map instance on render, updates when spec changes,\n * and cleans up on unmount. All heavy lifting is done by the vanilla\n * createMap() function.\n */\n\nimport type { DarkMode, MapSpec, ThemeConfig } from '@opendata-ai/openchart-core';\nimport {\n createMap,\n type MapInstance,\n type MapMarkEvent,\n type MapMountOptions,\n} from '@opendata-ai/openchart-vanilla';\nimport {\n type CSSProperties,\n defineComponent,\n h,\n inject,\n onMounted,\n onUnmounted,\n type PropType,\n ref,\n watch,\n} from 'vue';\nimport { VizDarkModeKey, VizThemeKey } from './context';\n\nexport interface MapProps {\n spec: MapSpec;\n theme?: ThemeConfig;\n darkMode?: DarkMode;\n class?: string;\n style?: string | CSSProperties;\n}\n\nexport const GeoMap = defineComponent({\n name: 'GeoMap',\n props: {\n spec: {\n type: Object as PropType<MapSpec>,\n required: true,\n },\n theme: {\n type: Object as PropType<ThemeConfig>,\n default: undefined,\n },\n darkMode: {\n type: String as PropType<DarkMode>,\n default: undefined,\n },\n class: {\n type: String,\n default: undefined,\n },\n style: {\n type: [String, Object] as PropType<string | CSSProperties>,\n default: undefined,\n },\n },\n emits: {\n 'mark-click': (_event: MapMarkEvent) => true,\n 'mark-hover': (_event: MapMarkEvent | null) => true,\n },\n setup(props, { emit, expose }) {\n const containerRef = ref<HTMLDivElement | null>(null);\n let instance: MapInstance | null = null;\n let prevSpec = '';\n\n // Inject theme/darkMode from provider as fallbacks\n const contextTheme = inject(VizThemeKey, undefined);\n const contextDarkMode = inject(VizDarkModeKey, undefined);\n\n function resolveTheme(): ThemeConfig | undefined {\n return props.theme ?? contextTheme?.value;\n }\n\n function resolveDarkMode(): DarkMode | undefined {\n return props.darkMode ?? contextDarkMode?.value;\n }\n\n function mountMap() {\n const container = containerRef.value;\n if (!container) return;\n\n const options: MapMountOptions = {\n theme: resolveTheme(),\n darkMode: resolveDarkMode(),\n onMarkClick: (feature) => emit('mark-click', feature),\n onMarkHover: (feature) => emit('mark-hover', feature),\n responsive: true,\n };\n\n instance = createMap(container, props.spec, options);\n prevSpec = JSON.stringify(props.spec);\n }\n\n function destroyMap() {\n instance?.destroy();\n instance = null;\n prevSpec = '';\n }\n\n // Expose imperative access to the instance\n expose({\n get instance() {\n return instance;\n },\n });\n\n onMounted(() => {\n mountMap();\n });\n\n onUnmounted(() => {\n destroyMap();\n });\n\n // Watch spec changes\n watch(\n () => JSON.stringify(props.spec),\n (newVal) => {\n if (!instance) return;\n if (newVal !== prevSpec) {\n prevSpec = newVal;\n instance.update(props.spec);\n }\n },\n );\n\n // Recreate map when theme or darkMode change\n watch(\n [\n () => props.theme,\n () => props.darkMode,\n () => contextTheme?.value,\n () => contextDarkMode?.value,\n ],\n () => {\n if (!containerRef.value) return;\n destroyMap();\n mountMap();\n },\n );\n\n const rootClass = () => {\n const base = 'oc-map-root';\n return props.class ? `${base} ${props.class}` : base;\n };\n\n return () =>\n h('div', {\n ref: containerRef,\n class: rootClass(),\n style: props.style,\n });\n },\n});\n","/**\n * Vue Sankey component: thin wrapper around the vanilla adapter.\n *\n * Mounts a sankey instance on render, updates when spec changes,\n * and cleans up on unmount. All heavy lifting is done by the vanilla\n * createSankey() function.\n */\n\nimport type { DarkMode, SankeySpec, ThemeConfig } from '@opendata-ai/openchart-core';\nimport {\n createSankey,\n type SankeyInstance,\n type SankeyMountOptions,\n} from '@opendata-ai/openchart-vanilla';\nimport {\n type CSSProperties,\n defineComponent,\n h,\n inject,\n onMounted,\n onUnmounted,\n type PropType,\n ref,\n watch,\n} from 'vue';\nimport { VizDarkModeKey, VizThemeKey } from './context';\n\nexport interface SankeyProps {\n spec: SankeySpec;\n theme?: ThemeConfig;\n darkMode?: DarkMode;\n class?: string;\n style?: string | CSSProperties;\n}\n\nexport const Sankey = defineComponent({\n name: 'Sankey',\n props: {\n spec: {\n type: Object as PropType<SankeySpec>,\n required: true,\n },\n theme: {\n type: Object as PropType<ThemeConfig>,\n default: undefined,\n },\n darkMode: {\n type: String as PropType<DarkMode>,\n default: undefined,\n },\n class: {\n type: String,\n default: undefined,\n },\n style: {\n type: [String, Object] as PropType<string | CSSProperties>,\n default: undefined,\n },\n },\n emits: {\n 'node-click': (_node: Record<string, unknown>) => true,\n 'link-click': (_link: Record<string, unknown>) => true,\n 'node-hover': (_node: Record<string, unknown> | null) => true,\n 'link-hover': (_link: Record<string, unknown> | null) => true,\n },\n setup(props, { emit, expose }) {\n const containerRef = ref<HTMLDivElement | null>(null);\n let instance: SankeyInstance | null = null;\n let prevSpec = '';\n\n // Inject theme/darkMode from provider as fallbacks\n const contextTheme = inject(VizThemeKey, undefined);\n const contextDarkMode = inject(VizDarkModeKey, undefined);\n\n function resolveTheme(): ThemeConfig | undefined {\n return props.theme ?? contextTheme?.value;\n }\n\n function resolveDarkMode(): DarkMode | undefined {\n return props.darkMode ?? contextDarkMode?.value;\n }\n\n function mountSankey() {\n const container = containerRef.value;\n if (!container) return;\n\n const options: SankeyMountOptions = {\n theme: resolveTheme(),\n darkMode: resolveDarkMode(),\n onNodeClick: (node: Record<string, unknown>) => emit('node-click', node),\n onLinkClick: (link: Record<string, unknown>) => emit('link-click', link),\n onNodeHover: (node: Record<string, unknown> | null) => emit('node-hover', node),\n onLinkHover: (link: Record<string, unknown> | null) => emit('link-hover', link),\n responsive: true,\n };\n\n instance = createSankey(container, props.spec, options);\n prevSpec = JSON.stringify(props.spec);\n }\n\n function destroySankey() {\n instance?.destroy();\n instance = null;\n prevSpec = '';\n }\n\n // Expose imperative access to the instance\n expose({\n get instance() {\n return instance;\n },\n });\n\n onMounted(() => {\n mountSankey();\n });\n\n onUnmounted(() => {\n destroySankey();\n });\n\n // Watch spec changes\n watch(\n () => JSON.stringify(props.spec),\n (newVal) => {\n if (!instance) return;\n if (newVal !== prevSpec) {\n prevSpec = newVal;\n instance.update(props.spec);\n }\n },\n );\n\n // Recreate sankey when theme or darkMode change\n watch(\n [\n () => props.theme,\n () => props.darkMode,\n () => contextTheme?.value,\n () => contextDarkMode?.value,\n ],\n () => {\n if (!containerRef.value) return;\n destroySankey();\n mountSankey();\n },\n );\n\n const rootClass = () => {\n const base = 'oc-sankey-root';\n return props.class ? `${base} ${props.class}` : base;\n };\n\n return () =>\n h('div', {\n ref: containerRef,\n class: rootClass(),\n style: props.style,\n });\n },\n});\n","/**\n * VizThemeProvider: provides a theme and dark mode preference to all\n * descendant Chart, DataTable, and Graph components without prop drilling.\n *\n * Components use the context values as fallbacks when no explicit\n * `theme` or `darkMode` prop is passed.\n */\n\nimport type { DarkMode, ThemeConfig } from '@opendata-ai/openchart-core';\nimport { computed, defineComponent, type PropType, provide } from 'vue';\nimport { VizDarkModeKey, VizThemeKey } from './context';\n\nexport interface VizThemeProviderProps {\n theme: ThemeConfig | undefined;\n darkMode?: DarkMode;\n}\n\nexport const VizThemeProvider = defineComponent({\n name: 'VizThemeProvider',\n props: {\n theme: {\n type: Object as PropType<ThemeConfig | undefined>,\n default: undefined,\n },\n darkMode: {\n type: String as PropType<DarkMode>,\n default: undefined,\n },\n },\n setup(props, { slots }) {\n // Wrap in computed() so changes to props propagate reactively\n // through the injection system.\n const themeRef = computed(() => props.theme);\n const darkModeRef = computed(() => props.darkMode);\n\n provide(VizThemeKey, themeRef);\n provide(VizDarkModeKey, darkModeRef);\n\n return () => slots.default?.();\n },\n});\n","/**\n * Vue TileMap component: thin wrapper around the vanilla adapter.\n *\n * Mounts a tilemap instance on render, updates when spec changes,\n * and cleans up on unmount. All heavy lifting is done by the vanilla\n * createTileMap() function.\n */\n\nimport type { DarkMode, ThemeConfig, TileMapSpec } from '@opendata-ai/openchart-core';\nimport {\n createTileMap,\n type TileMapInstance,\n type TileMapMountOptions,\n} from '@opendata-ai/openchart-vanilla';\nimport {\n type CSSProperties,\n defineComponent,\n h,\n inject,\n onMounted,\n onUnmounted,\n type PropType,\n ref,\n watch,\n} from 'vue';\nimport { VizDarkModeKey, VizThemeKey } from './context';\n\nexport interface TileMapTileEvent {\n stateCode: string;\n stateName: string;\n value: number | null;\n data: Record<string, unknown>;\n}\n\nexport interface TileMapProps {\n spec: TileMapSpec;\n theme?: ThemeConfig;\n darkMode?: DarkMode;\n class?: string;\n style?: string | CSSProperties;\n}\n\nexport const TileMap = defineComponent({\n name: 'TileMap',\n props: {\n spec: {\n type: Object as PropType<TileMapSpec>,\n required: true,\n },\n theme: {\n type: Object as PropType<ThemeConfig>,\n default: undefined,\n },\n darkMode: {\n type: String as PropType<DarkMode>,\n default: undefined,\n },\n class: {\n type: String,\n default: undefined,\n },\n style: {\n type: [String, Object] as PropType<string | CSSProperties>,\n default: undefined,\n },\n },\n emits: {\n 'tile-click': (_tile: TileMapTileEvent) => true,\n 'tile-hover': (_tile: TileMapTileEvent | null) => true,\n },\n setup(props, { emit, expose }) {\n const containerRef = ref<HTMLDivElement | null>(null);\n let instance: TileMapInstance | null = null;\n let prevSpec = '';\n\n // Inject theme/darkMode from provider as fallbacks\n const contextTheme = inject(VizThemeKey, undefined);\n const contextDarkMode = inject(VizDarkModeKey, undefined);\n\n function resolveTheme(): ThemeConfig | undefined {\n return props.theme ?? contextTheme?.value;\n }\n\n function resolveDarkMode(): DarkMode | undefined {\n return props.darkMode ?? contextDarkMode?.value;\n }\n\n function mountTileMap() {\n const container = containerRef.value;\n if (!container) return;\n\n const options: TileMapMountOptions = {\n theme: resolveTheme(),\n darkMode: resolveDarkMode(),\n onTileClick: (tile: TileMapTileEvent) => emit('tile-click', tile),\n onTileHover: (tile: TileMapTileEvent | null) => emit('tile-hover', tile),\n responsive: true,\n };\n\n instance = createTileMap(container, props.spec, options);\n prevSpec = JSON.stringify(props.spec);\n }\n\n function destroyTileMap() {\n instance?.destroy();\n instance = null;\n prevSpec = '';\n }\n\n // Expose imperative access to the instance\n expose({\n get instance() {\n return instance;\n },\n });\n\n onMounted(() => {\n mountTileMap();\n });\n\n onUnmounted(() => {\n destroyTileMap();\n });\n\n // Watch spec changes\n watch(\n () => JSON.stringify(props.spec),\n (newVal) => {\n if (!instance) return;\n if (newVal !== prevSpec) {\n prevSpec = newVal;\n instance.update(props.spec);\n }\n },\n );\n\n // Recreate tilemap when theme or darkMode change\n watch(\n [\n () => props.theme,\n () => props.darkMode,\n () => contextTheme?.value,\n () => contextDarkMode?.value,\n ],\n () => {\n if (!containerRef.value) return;\n destroyTileMap();\n mountTileMap();\n },\n );\n\n const rootClass = () => {\n const base = 'oc-tilemap-root';\n return props.class ? `${base} ${props.class}` : base;\n };\n\n return () =>\n h('div', {\n ref: containerRef,\n class: rootClass(),\n style: props.style,\n });\n },\n});\n","/**\n * Visualization routing component: renders Chart, DataTable, or Graph\n * based on the spec type. Use this when rendering arbitrary VizSpec values.\n *\n * For event handlers, use the specific component (Chart, DataTable, Graph) directly.\n */\n\nimport type { DarkMode, ThemeConfig, VizSpec } from '@opendata-ai/openchart-core';\nimport {\n isBarListSpec,\n isGraphSpec,\n isMapSpec,\n isSankeySpec,\n isTableSpec,\n isTileMapSpec,\n} from '@opendata-ai/openchart-core';\nimport { type CSSProperties, defineComponent, h, type PropType } from 'vue';\nimport { BarList } from './BarList';\nimport { Chart } from './Chart';\nimport { DataTable } from './DataTable';\nimport { Graph } from './Graph';\nimport { GeoMap } from './Map';\nimport { Sankey } from './Sankey';\nimport { TileMap } from './TileMap';\n\nexport interface VisualizationProps {\n spec: VizSpec;\n theme?: ThemeConfig;\n darkMode?: DarkMode;\n class?: string;\n style?: string | CSSProperties;\n}\n\nexport const Visualization = defineComponent({\n name: 'Visualization',\n props: {\n spec: {\n type: Object as PropType<VizSpec>,\n required: true,\n },\n theme: {\n type: Object as PropType<ThemeConfig>,\n default: undefined,\n },\n darkMode: {\n type: String as PropType<DarkMode>,\n default: undefined,\n },\n class: {\n type: String,\n default: undefined,\n },\n style: {\n type: [String, Object] as PropType<string | CSSProperties>,\n default: undefined,\n },\n },\n setup(props) {\n return () => {\n const { spec, theme, darkMode, class: className, style } = props;\n const sharedProps = { theme, darkMode, class: className, style };\n\n if (isTableSpec(spec)) {\n return h(DataTable, { ...sharedProps, spec });\n }\n if (isGraphSpec(spec)) {\n return h(Graph, { ...sharedProps, spec });\n }\n if (isSankeySpec(spec)) {\n return h(Sankey, { ...sharedProps, spec });\n }\n if (isTileMapSpec(spec)) {\n return h(TileMap, { ...sharedProps, spec });\n }\n if (isBarListSpec(spec)) {\n return h(BarList, { ...sharedProps, spec });\n }\n if (isMapSpec(spec)) {\n return h(GeoMap, { ...sharedProps, spec });\n }\n return h(Chart, { ...sharedProps, spec });\n };\n },\n});\n"],"mappings":"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","names":["inject","inject","defineComponent","h","inject","onMounted","onUnmounted","ref","watch","defineComponent","ref","inject","onMounted","onUnmounted","watch","h","defineComponent","h","onMounted","onUnmounted","ref","watch","createChart","onMounted","onUnmounted","ref","watch","onUnmounted","ref","watch","ref","onMounted","onUnmounted","ref","shallowRef","watch","ref","createTable","defineComponent","h","inject","onMounted","onUnmounted","ref","watch","defineComponent","ref","inject","createTable","onMounted","onUnmounted","watch","h","defineComponent","h","inject","onMounted","onUnmounted","ref","watch","defineComponent","ref","inject","onMounted","onUnmounted","watch","h","defineComponent","h","inject","onMounted","onUnmounted","ref","watch","defineComponent","ref","inject","onMounted","onUnmounted","watch","h","defineComponent","h","inject","onMounted","onUnmounted","ref","watch","defineComponent","ref","inject","onMounted","onUnmounted","watch","h","computed","defineComponent","defineComponent","computed","defineComponent","h","inject","onMounted","onUnmounted","ref","watch","defineComponent","ref","inject","onMounted","onUnmounted","watch","h","defineComponent","h","defineComponent","h"]}
|
package/dist/styles.css
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
@layer oc.tokens{.oc-root,.oc-chart-root,.oc-table-wrapper,.oc-table-root,.oc-graph-wrapper,.oc-graph-root,.oc-sankey-root,.oc-tilemap-root,.oc-barlist-root,.oc-map-root{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;-webkit-text-size-adjust:100%;-moz-text-size-adjust:100%;-ms-text-size-adjust:100%;text-size-adjust:100%;--oc-font-family:"Inter Variable", Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;--oc-font-mono:"JetBrains Mono", "Fira Code", "Cascadia Code", monospace;--oc-ease-smooth:linear(0, .157, .438, .64, .766, .85, .906, .941, .964, .978, .988, .994, .998, 1);--oc-ease-snappy:linear(0, .012, .048, .108, .194, .302, .426, .559, .69, .808, .905, .973, 1.013, 1.028, 1.023, 1.006, .984, .966, .957, .957, .964, .975, .986, .995, 1, 1.003, 1.002, 1, .998, .998, .999, 1);--oc-animation-duration:.5s;--oc-animation-stagger:80ms;--oc-annotation-delay:.2s;--oc-title-size:26px;--oc-title-weight:590;--oc-title-tracking:-.022em;--oc-subtitle-size:14px;--oc-subtitle-weight:450;--oc-source-size:11px;--oc-source-weight:450;--oc-body-size:13px;--oc-eyebrow-size:11px;--oc-eyebrow-weight:550;--oc-eyebrow-tracking:.08em;--oc-bg:#fff;--oc-card:#fff;--oc-secondary:#f4f4f5;--oc-text:#09090b;--oc-text-secondary:#3f3f46;--oc-text-muted:#71717a;--oc-text-faint:#d4d4d8;--oc-gridline:rgba(0,0,0,.1);--oc-axis:rgba(0,0,0,.1);--oc-border:rgba(0,0,0,.08);--oc-border-radius:2px;--oc-accent:#06b6d4;--oc-accent-strong:#0891b2;--oc-positive:#10b981;--oc-negative:#e11d48;--oc-focus:#3b82f6;--oc-focus-ring:rgba(59,130,246,.1);--oc-focus-ring-strong:rgba(59,130,246,.25);--oc-editable-hover:rgba(79,70,229,.35);--oc-space-2:8px;--oc-space-4:16px;--oc-hover-bg:rgba(0,0,0,.024);--oc-tooltip-bg:rgba(255,255,255,.88);--oc-tooltip-border:rgba(0,0,0,.08);--oc-tooltip-shadow:0 2px 8px rgba(0,0,0,.08), 0 0 1px rgba(0,0,0,.12);--oc-tooltip-text:#09090b;--oc-legend-text:#3f3f46}.oc-dark{--oc-bg:#09090b;--oc-card:#111113;--oc-secondary:#27272a;--oc-text:#f7f8f8;--oc-text-secondary:#d0d6e0;--oc-text-muted:#a1a1aa;--oc-text-faint:#52525b;--oc-gridline:rgba(255,255,255,.05);--oc-axis:rgba(255,255,255,.1);--oc-border:rgba(255,255,255,.1);--oc-accent:#06b6d4;--oc-accent-strong:#06b6d4;--oc-positive:#34d399;--oc-negative:#fb7185;--oc-focus:#60a5fa;--oc-hover-bg:rgba(255,255,255,.05);--oc-tooltip-bg:rgba(17,17,19,.92);--oc-tooltip-border:rgba(255,255,255,.08);--oc-tooltip-shadow:0 2px 8px rgba(0,0,0,.3), 0 0 1px rgba(0,0,0,.4);--oc-tooltip-text:#f7f8f8;--oc-legend-text:#d0d6e0}}@layer oc.base{.oc-chart-root,.oc-table-root,.oc-graph-root,.oc-sankey-root,.oc-barlist-root,.oc-tilemap-root,.oc-map-root{width:100%;height:100%}.oc-table-root{overflow:auto}.oc-chart{font-family:var(--oc-font-family);width:100%;display:block}.oc-tilemap,.oc-map{width:100%;height:auto;display:block}.oc-map-feature{transition:opacity .4s}.oc-barlist{width:100%;display:block}.oc-sr-only{clip-path:inset(50%);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.oc-editable-hover{outline:1.5px solid var(--oc-editable-hover);outline-offset:2px;border-radius:2px}.oc-root:focus-visible{outline:2px solid var(--oc-focus);outline-offset:2px}.oc-mark-focused{outline:2px solid var(--oc-focus);outline-offset:1px;border-radius:2px}}@layer oc.components{.oc-chrome{font-family:var(--oc-font-family)}.oc-eyebrow{font-size:var(--oc-eyebrow-size);font-weight:var(--oc-eyebrow-weight);letter-spacing:var(--oc-eyebrow-tracking);text-transform:uppercase;fill:var(--oc-accent)}.oc-title{font-size:var(--oc-title-size);font-weight:var(--oc-title-weight);letter-spacing:var(--oc-title-tracking);fill:var(--oc-text)}.oc-subtitle{font-size:var(--oc-subtitle-size);font-weight:var(--oc-subtitle-weight);fill:var(--oc-text-muted)}.oc-source,.oc-byline,.oc-footer{font-size:var(--oc-source-size);font-weight:var(--oc-source-weight);fill:var(--oc-text-muted)}.oc-brand{letter-spacing:.02em;fill:var(--oc-text-faint);font-size:11px;font-weight:510}.oc-brand-dot,.oc-eyebrow-dot{fill:var(--oc-accent)}.oc-metrics{font-family:var(--oc-font-family)}.oc-metric-label{letter-spacing:.08em;text-transform:uppercase;fill:var(--oc-text-muted);font-size:10px;font-weight:510}.oc-metric-value{letter-spacing:-.01em;fill:var(--oc-text);font-variant-numeric:tabular-nums;font-size:22px;font-weight:510}.oc-metric-delta-up{fill:var(--oc-positive);font-size:12px;font-weight:510}.oc-metric-delta-down{fill:var(--oc-negative);font-size:12px;font-weight:510}.oc-metric-secondary{fill:var(--oc-positive);font-size:12px;font-weight:400}.oc-axis-tick-inline{fill:var(--oc-text-muted);font-size:11px;font-weight:400}.oc-endpoint-labels{font-family:var(--oc-font-family)}.oc-endpoint-label{fill:var(--oc-endpoint-label-color,var(--oc-text))}.oc-endpoint-value{fill:var(--oc-endpoint-value-color,var(--oc-text-muted))}.oc-endpoint-leader{stroke:var(--oc-endpoint-leader-color,currentColor)}.oc-annotation-subtitle{fill:var(--oc-annotation-subtitle-color,var(--oc-text-muted))}.oc-table-footer-row{align-items:baseline;gap:16px;padding:16px 16px 4px;display:flex}.oc-chrome-footer{padding-top:0}.oc-table-footer-row .oc-table-ref{text-align:right;flex-shrink:0;margin-left:auto}.oc-tooltip{pointer-events:none;z-index:1000;background:var(--oc-tooltip-bg);-webkit-backdrop-filter:blur(14px);backdrop-filter:blur(14px);border:1px solid var(--oc-tooltip-border);border-radius:var(--oc-border-radius,2px);box-shadow:var(--oc-tooltip-shadow);color:var(--oc-tooltip-text);font-family:var(--oc-font-family);min-width:160px;max-width:280px;padding:0;font-size:12px;line-height:1.4;transition:left .1s ease-in-out,top .1s ease-in-out;animation:.12s ease-out oc-tooltip-in;display:none;position:absolute}.oc-tooltip .oc-tooltip-header{align-items:center;gap:8px;padding:8px 12px 6px;display:flex}.oc-tooltip .oc-tooltip-dot{border-radius:50%;flex-shrink:0;width:8px;height:8px}.oc-tooltip .oc-tooltip-title{letter-spacing:.04em;text-transform:uppercase;color:var(--oc-text-muted);white-space:nowrap;text-overflow:ellipsis;font-size:11px;font-weight:590;overflow:hidden}.oc-tooltip .oc-tooltip-body{border-top:1px solid var(--oc-tooltip-border);padding:6px 12px 10px}.oc-tooltip .oc-tooltip-body:first-child{border-top:none;padding-top:10px}.oc-tooltip .oc-tooltip-row{justify-content:space-between;align-items:baseline;gap:16px;padding:2px 0;display:flex}.oc-tooltip .oc-tooltip-row-swatch{border-radius:50%;flex-shrink:0;width:8px;height:8px;margin-right:6px;display:inline-block;transform:translateY(-1px)}.oc-tooltip .oc-tooltip-label{color:var(--oc-text-secondary);white-space:nowrap;flex-shrink:0;align-items:center;font-size:12px;font-weight:400;display:inline-flex}.oc-tooltip .oc-tooltip-value{font-variant-numeric:tabular-nums;color:var(--oc-tooltip-text);text-align:right;text-overflow:ellipsis;white-space:nowrap;font-size:12px;font-weight:510;overflow:hidden}.oc-crosshair{pointer-events:none;transition:x1 50ms ease-in-out,x2 50ms ease-in-out}.oc-snap-dots circle{pointer-events:none;transition:cx 50ms ease-in-out,cy 50ms ease-in-out}.oc-legend{font-family:var(--oc-font-family);font-size:var(--oc-body-size)}.oc-legend-entry{cursor:default}.oc-legend text{fill:var(--oc-legend-text)}.oc-series-search{font-family:var(--oc-font-family);z-index:10;justify-content:flex-end;align-items:center;gap:8px;display:flex;position:absolute}.oc-series-search-chips{scrollbar-width:none;align-items:center;gap:6px;min-width:0;display:flex;overflow-x:auto}.oc-series-search-chips::-webkit-scrollbar{display:none}.oc-series-search-chip{border:1px solid var(--oc-border);background:var(--oc-secondary);color:var(--oc-text-secondary);white-space:nowrap;border-radius:999px;align-items:center;gap:4px;padding:3px 4px 3px 10px;font-size:12px;font-weight:500;line-height:16px;display:inline-flex}.oc-series-search-chip-remove{width:16px;height:16px;color:var(--oc-text-muted);cursor:pointer;background:0 0;border:none;border-radius:50%;justify-content:center;align-items:center;margin:-4px -2px -4px -4px;padding:4px;transition:color .15s,background-color .15s;display:inline-flex}.oc-series-search-chip-remove:hover{color:var(--oc-text);background:var(--oc-hover-bg)}.oc-series-search-chip-remove:focus-visible{outline:2px solid var(--oc-focus);outline-offset:1px}.oc-series-search-chip-remove svg{display:block}.oc-series-search-box{flex:0 220px;min-width:120px;position:relative}.oc-series-search-icon{color:var(--oc-text-muted);pointer-events:none;position:absolute;top:50%;left:9px;transform:translateY(-50%)}.oc-series-search-input{height:32px;padding:0 10px 0 28px}.oc-series-search-listbox{border:1px solid var(--oc-border);background:var(--oc-card);min-width:100%;max-height:240px;box-shadow:var(--oc-tooltip-shadow);z-index:20;border-radius:8px;margin:0;padding:4px;list-style:none;position:absolute;top:calc(100% + 4px);right:0;overflow-y:auto}.oc-series-search-option{color:var(--oc-text);cursor:pointer;white-space:nowrap;text-overflow:ellipsis;border-radius:4px;padding:6px 10px;font-size:13px;overflow:hidden}.oc-series-search-option[aria-selected=true],.oc-series-search-option:hover{background:var(--oc-hover-bg)}.oc-series-search-match{font-weight:600}.oc-series-search-empty{color:var(--oc-text-muted);padding:6px 10px;font-size:12px}.oc-ydi-region{opacity:.35;transition:opacity .4s}.oc-ydi-region[data-ydi-hidden=true]{opacity:0}.oc-ydi-boundary{stroke:var(--oc-text-muted);stroke-width:1px;stroke-dasharray:3 3;stroke-opacity:.6}.oc-ydi-guess{stroke:var(--oc-focus);stroke-width:2.5px;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:1 6}.oc-ydi-comparison{stroke:var(--oc-text-muted);stroke-width:1.5px;stroke-opacity:.5;stroke-dasharray:4 4}.oc-ydi-clip-rect.oc-ydi-clip-animate{transition:width .7s cubic-bezier(.22,1,.36,1)}.oc-ydi-controls{pointer-events:none;font-family:var(--oc-font-family);box-sizing:border-box;z-index:10;flex-direction:column;justify-content:space-between;align-items:flex-end;padding:8px;display:flex}.oc-ydi-prompt{background:var(--oc-card);border:1px solid var(--oc-border);max-width:100%;color:var(--oc-text-secondary);text-align:center;box-shadow:var(--oc-tooltip-shadow);border-radius:6px;align-self:center;padding:6px 12px;font-size:13px;font-weight:500;line-height:16px}.oc-ydi-controls.oc-ydi-revealed .oc-ydi-prompt{display:none}.oc-ydi-reveal-button{pointer-events:auto;border:1px solid var(--oc-border);background:var(--oc-bg);color:var(--oc-text);cursor:pointer;box-shadow:var(--oc-tooltip-shadow);border-radius:6px;justify-content:center;align-items:center;padding:6px 14px;font-family:inherit;font-size:13px;font-weight:500;transition:background-color .15s,border-color .15s;display:inline-flex}.oc-ydi-reveal-button:hover{background:var(--oc-hover-bg)}.oc-ydi-reveal-button:focus-visible{outline:2px solid var(--oc-focus);outline-offset:2px}.oc-ydi-reveal-button:disabled{opacity:.5;cursor:default}.oc-table-wrapper{font-family:var(--oc-font-family);color:var(--oc-text);background:var(--oc-bg)}.oc-table-wrapper>.oc-chrome{margin-bottom:16px;padding-left:16px;padding-right:16px}.oc-table-wrapper>.oc-chrome:first-child{padding-top:4px}.oc-table-wrapper table{border-collapse:collapse;width:100%}.oc-table-wrapper th{text-align:left;border-bottom:1px solid var(--oc-border);padding:10px 16px}.oc-table-wrapper td{text-align:left;border-bottom:1px solid var(--oc-border);padding:10px 16px}.oc-table-wrapper th{text-transform:uppercase;letter-spacing:.05em;color:var(--oc-text-secondary);white-space:nowrap;font-size:12px;font-weight:600}.oc-table-wrapper thead{z-index:2;background:var(--oc-bg);position:sticky;top:0}.oc-table-wrapper thead th{border-bottom-width:2px}.oc-table-wrapper td{font-variant-numeric:tabular-nums;font-size:14px}.oc-table-wrapper th:focus{outline:2px solid var(--oc-focus);outline-offset:-2px}.oc-table-wrapper tbody:focus{outline:none}.oc-table-title{font-size:var(--oc-title-computed-size,var(--oc-title-size));font-weight:var(--oc-title-computed-weight,var(--oc-title-weight));color:var(--oc-title-computed-color,var(--oc-text));margin-bottom:4px}.oc-table-subtitle{font-size:var(--oc-subtitle-computed-size,var(--oc-subtitle-size));font-weight:var(--oc-subtitle-computed-weight,var(--oc-subtitle-weight));color:var(--oc-subtitle-computed-color,var(--oc-text-secondary));margin-bottom:8px}.oc-table-source{font-size:var(--oc-source-computed-size,var(--oc-source-size));color:var(--oc-source-computed-color,var(--oc-text-muted))}.oc-table-footer-text{font-size:var(--oc-footer-computed-size,var(--oc-source-size));color:var(--oc-footer-computed-color,var(--oc-text-muted))}.oc-table-scroll{overflow-x:auto}.oc-table--sticky th:first-child{z-index:1;background:var(--oc-bg);position:sticky;left:0}.oc-table--sticky td:first-child{z-index:1;background:var(--oc-bg);position:sticky;left:0}.oc-table-sort-btn{cursor:pointer;vertical-align:middle;background:0 0;border:none;flex-direction:column;align-items:center;gap:2px;margin-left:6px;padding:2px;display:inline-flex}.oc-table-sort-btn:before{content:"";border-left:5px solid transparent;border-right:5px solid transparent;width:0;height:0;transition:opacity .15s,border-color .15s;display:block}.oc-table-sort-btn:after{content:"";border-left:5px solid transparent;border-right:5px solid transparent;width:0;height:0;transition:opacity .15s,border-color .15s;display:block}.oc-table-sort-btn:before{border-bottom:4.5px solid var(--oc-text-secondary);opacity:.45}.oc-table-sort-btn:after{border-top:4.5px solid var(--oc-text-secondary);opacity:.45}.oc-table-sort-btn:hover:before{opacity:.75}.oc-table-sort-btn:hover:after{opacity:.75}th[aria-sort=ascending] .oc-table-sort-btn:before{opacity:1;border-bottom-color:var(--oc-text)}th[aria-sort=ascending] .oc-table-sort-btn:after{opacity:.15}th[aria-sort=descending] .oc-table-sort-btn:after{opacity:1;border-top-color:var(--oc-text)}th[aria-sort=descending] .oc-table-sort-btn:before{opacity:.15}.oc-table-search input,.oc-series-search-input{border:1px solid var(--oc-border);background:var(--oc-bg);width:100%;color:var(--oc-text);box-sizing:border-box;border-radius:6px;font-family:inherit;font-size:13px;transition:border-color .15s}.oc-table-search input::-ms-input-placeholder{color:var(--oc-text-muted);font-size:13px}.oc-table-search input::placeholder{color:var(--oc-text-muted);font-size:13px}.oc-series-search-input::-ms-input-placeholder{color:var(--oc-text-muted);font-size:13px}.oc-series-search-input::placeholder{color:var(--oc-text-muted);font-size:13px}.oc-table-search input:focus,.oc-series-search-input:focus{border-color:var(--oc-focus);box-shadow:0 0 0 3px var(--oc-focus-ring);outline:none}.oc-table-search{padding:8px 0}.oc-table-search input{padding:8px 12px}.oc-table-pagination{color:var(--oc-text-secondary);justify-content:space-between;align-items:center;padding:12px 0 4px;font-size:13px;display:flex}.oc-table-pagination button{border:1px solid var(--oc-border);background:var(--oc-bg);color:var(--oc-text);cursor:pointer;border-radius:6px;padding:6px 14px;font-family:inherit;font-size:13px;transition:background .15s,border-color .15s}.oc-table-pagination button:disabled{opacity:.35;cursor:not-allowed}.oc-table-pagination button:hover:not(:disabled){background:var(--oc-hover-bg);border-color:var(--oc-axis)}.oc-table-pagination button:focus-visible{outline:2px solid var(--oc-focus);outline-offset:1px}.oc-table-pagination-info{font-variant-numeric:tabular-nums}.oc-table-pagination-btns{gap:8px;display:flex}.oc-table-bar{position:relative}.oc-table-bar-fill{opacity:.15;pointer-events:none;border-radius:2px;position:absolute;top:6px;bottom:6px;left:0}.oc-table-bar-value{z-index:1;position:relative}.oc-table-sparkline{width:100%;display:block;position:relative}.oc-table-sparkline svg{width:100%;display:block;overflow:visible}.oc-table-sparkline-dot{border-radius:50%;width:5px;height:5px;position:absolute}.oc-table-sparkline-labels{justify-content:space-between;font-size:11px;line-height:1;display:flex}.oc-table-image{vertical-align:middle;display:inline-block}.oc-table-image img{object-fit:cover}.oc-table-image-rounded img{border-radius:50%}.oc-table-flag{font-size:1.2em}.oc-table--compact th{padding:4px 8px;font-size:13px}.oc-table--compact td{padding:4px 8px;font-size:13px}.oc-table--compact th{font-size:11px}.oc-table--clickable tbody tr{cursor:pointer}.oc-table--clickable tbody tr:hover{background:var(--oc-hover-bg)}.oc-table-cell-focus{outline:2px solid var(--oc-focus);outline-offset:-2px}.oc-table-empty{text-align:center;color:var(--oc-text-secondary);padding:32px 16px;font-size:14px;font-style:italic}.oc-graph-wrapper{background:var(--oc-bg);font-family:var(--oc-font-family);width:100%;height:100%;position:relative;overflow:hidden}.oc-graph-canvas{cursor:grab;width:100%;height:100%;display:block}.oc-graph-canvas--dragging{cursor:grabbing}.oc-graph-chrome{z-index:2;pointer-events:none;padding:16px 16px 8px;position:absolute;top:0;left:0;right:0}.oc-graph-chrome .oc-title{font-size:var(--oc-title-size);font-weight:var(--oc-title-weight);letter-spacing:var(--oc-title-tracking);color:var(--oc-text);--_stroke:color-mix(in srgb, var(--oc-bg) 80%, transparent);text-shadow:-2px -2px 0 var(--_stroke), 2px -2px 0 var(--_stroke), -2px 2px 0 var(--_stroke), 2px 2px 0 var(--_stroke), 0 -2px 0 var(--_stroke), 0 2px 0 var(--_stroke), -2px 0 0 var(--_stroke), 2px 0 0 var(--_stroke);margin:0 0 4px}.oc-graph-chrome .oc-subtitle{font-size:var(--oc-subtitle-size);color:var(--oc-text-secondary);--_stroke:color-mix(in srgb, var(--oc-bg) 80%, transparent);text-shadow:-1px -1px 0 var(--_stroke), 1px -1px 0 var(--_stroke), -1px 1px 0 var(--_stroke), 1px 1px 0 var(--_stroke);margin:0}.oc-graph-legend{background:var(--oc-bg);border:1px solid var(--oc-border);border-radius:var(--oc-border-radius);color:var(--oc-text-secondary);max-height:200px;padding:8px 12px;font-size:12px;position:absolute;top:8px;right:8px;overflow-y:auto}.oc-graph-legend-item{align-items:center;gap:6px;padding:2px 0;display:flex}.oc-graph-legend-swatch{border-radius:50%;flex-shrink:0;width:10px;height:10px}.oc-graph-search{position:absolute;top:8px;left:8px}.oc-graph-search input{font-family:var(--oc-font-family);font-size:var(--oc-body-size);border:1px solid var(--oc-border);border-radius:var(--oc-border-radius);background:var(--oc-bg);color:var(--oc-text);outline:none;padding:6px 10px}.oc-graph-search input:focus{border-color:var(--oc-focus);box-shadow:0 0 0 2px var(--oc-focus-ring-strong)}.oc-dark .oc-graph-wrapper,.oc-graph-wrapper.oc-dark{--oc-bg:#0d1117}.oc-dark .oc-graph-legend,.oc-dark.oc-graph-wrapper .oc-graph-legend,.oc-dark .oc-graph-search input{border-color:var(--oc-border);background:rgba(13,17,23,.85)}.oc-chart[data-display=sparkline]{margin:0;padding:0;display:block}}@layer oc.animation{.oc-table-wrapper.oc-animate>.oc-chrome{animation:oc-enter-fade calc(var(--oc-animation-duration) * .6) var(--oc-animation-ease,var(--oc-ease-smooth)) both}.oc-table-wrapper.oc-animate thead{animation:oc-enter-fade-only calc(var(--oc-animation-duration) * .4) var(--oc-animation-ease,var(--oc-ease-smooth)) both}.oc-table-wrapper.oc-animate tbody tr{animation:oc-table-enter-row var(--oc-animation-duration) var(--oc-animation-ease,var(--oc-ease-smooth)) both;animation-delay:calc(var(--oc-animation-stagger) * var(--oc-row-index,0))}.oc-table-wrapper.oc-animate tbody td{animation:oc-enter-fade-only calc(var(--oc-animation-duration) * .5) var(--oc-animation-ease,var(--oc-ease-smooth)) both;animation-delay:calc(var(--oc-animation-stagger) * var(--oc-row-index,0))}.oc-table-wrapper.oc-animate td.oc-table-heatmap{animation:oc-enter-fade-only calc(var(--oc-animation-duration) * .7) var(--oc-animation-ease,var(--oc-ease-smooth)) both;animation-delay:calc(var(--oc-animation-stagger) * var(--oc-row-index,0) + var(--oc-animation-duration) * .3)}.oc-table-wrapper.oc-animate td.oc-table-category{animation:oc-enter-fade-only calc(var(--oc-animation-duration) * .7) var(--oc-animation-ease,var(--oc-ease-smooth)) both;animation-delay:calc(var(--oc-animation-stagger) * var(--oc-row-index,0) + var(--oc-animation-duration) * .3)}.oc-table-wrapper.oc-animate .oc-table-bar-fill{animation:oc-table-enter-bar-fill calc(var(--oc-animation-duration) * .8) var(--oc-animation-ease,var(--oc-ease-smooth)) both;animation-delay:calc(var(--oc-animation-stagger) * var(--oc-row-index,0) + var(--oc-animation-duration) * .3)}.oc-table-wrapper.oc-animate .oc-table-sparkline>svg{animation:oc-enter-line calc(var(--oc-animation-duration) * .8) var(--oc-animation-ease,var(--oc-ease-smooth)) both;animation-delay:calc(var(--oc-animation-stagger) * var(--oc-row-index,0) + var(--oc-animation-duration) * .4)}.oc-table-wrapper.oc-animate .oc-table-sparkline-dot{animation:oc-enter-fade-only calc(var(--oc-animation-duration) * .3) var(--oc-animation-ease,var(--oc-ease-smooth)) both;animation-delay:calc(var(--oc-animation-stagger) * var(--oc-row-index,0) + var(--oc-animation-duration) * .8)}.oc-table-wrapper.oc-animate .oc-table-sparkline-labels{animation:oc-enter-fade-only calc(var(--oc-animation-duration) * .3) var(--oc-animation-ease,var(--oc-ease-smooth)) both;animation-delay:calc(var(--oc-animation-stagger) * var(--oc-row-index,0) + var(--oc-animation-duration) * .8)}.oc-table-wrapper.oc-animate .oc-table-search{animation:oc-enter-fade-only calc(var(--oc-animation-duration) * .5) var(--oc-animation-ease,var(--oc-ease-smooth)) both}.oc-table-wrapper.oc-animate .oc-table-pagination{animation:oc-enter-fade-only calc(var(--oc-animation-duration) * .5) var(--oc-animation-ease,var(--oc-ease-smooth)) both}@keyframes oc-enter-bar{0%{clip-path:inset(100% 0 0);opacity:0}75%{opacity:1}to{clip-path:inset(0);opacity:1}}@keyframes oc-enter-bar-h{0%{clip-path:inset(0 100% 0 0);opacity:0}75%{opacity:1}to{clip-path:inset(0);opacity:1}}@keyframes oc-enter-line{0%{clip-path:inset(0 100% 0 0);opacity:0}15%{opacity:1}to{clip-path:inset(0);opacity:1}}@keyframes oc-enter-point{0%{opacity:0;transform:scale(.3)}to{opacity:1;transform:scale(1)}}@keyframes oc-enter-map-fill{0%{fill:var(--oc-secondary);opacity:0}to{fill:var(--oc-feature-fill);opacity:1}}@keyframes oc-enter-fade-only{0%{opacity:0}to{opacity:1}}@keyframes oc-enter-fade{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}@keyframes oc-table-enter-row{0%{transform:translateY(6px)}to{transform:translateY(0)}}@keyframes oc-table-enter-bar-fill{0%{clip-path:inset(0 100% 0 0)}to{clip-path:inset(0)}}@keyframes oc-tooltip-in{0%{opacity:0;transform:translateY(2px)}to{opacity:1;transform:translateY(0)}}.oc-animate .oc-mark-rect rect{animation:oc-enter-bar var(--oc-animation-duration) var(--oc-ease-smooth) both;animation-delay:calc(var(--oc-animation-stagger) * var(--oc-mark-index,0))}.oc-animate .oc-mark-bar rect{animation:oc-enter-bar var(--oc-animation-duration) var(--oc-ease-smooth) both;animation-delay:calc(var(--oc-animation-stagger) * var(--oc-mark-index,0))}.oc-animate .oc-mark-rect[data-orient=horizontal] rect{animation-name:oc-enter-bar-h}.oc-animate .oc-mark-bar[data-orient=horizontal] rect{animation-name:oc-enter-bar-h}.oc-animate .oc-mark-rect[data-stack-pos] rect{animation-duration:var(--oc-stack-segment-duration,.15s);animation-timing-function:linear;animation-delay:calc(var(--oc-animation-stagger) * var(--oc-mark-index,0) + var(--oc-stack-pos,0) * var(--oc-stack-segment-duration,.15s))}.oc-animate .oc-mark-line{animation:oc-enter-line var(--oc-animation-duration) var(--oc-animation-ease,var(--oc-ease-smooth)) both;animation-delay:calc(var(--oc-animation-stagger) * var(--oc-mark-index,0))}.oc-animate .oc-mark-area{animation:oc-enter-line var(--oc-animation-duration) var(--oc-animation-ease,var(--oc-ease-smooth)) both;animation-delay:calc(var(--oc-animation-stagger) * var(--oc-mark-index,0))}.oc-animate .oc-mark-arc{animation:oc-enter-fade-only var(--oc-animation-duration) var(--oc-animation-ease,var(--oc-ease-smooth)) both;animation-delay:calc(var(--oc-animation-stagger) * var(--oc-mark-index,0))}.oc-animate circle.oc-mark-point{animation:oc-enter-fade-only calc(var(--oc-animation-duration) * .4) var(--oc-animation-ease,var(--oc-ease-smooth)) both;animation-delay:calc(var(--oc-animation-stagger) * var(--oc-mark-index,0))}.oc-animate circle.oc-mark-circle{animation:oc-enter-fade-only calc(var(--oc-animation-duration) * .4) var(--oc-animation-ease,var(--oc-ease-smooth)) both;animation-delay:calc(var(--oc-animation-stagger) * var(--oc-mark-index,0))}.oc-animate .oc-mark-line~circle.oc-mark-point{animation-delay:calc(var(--oc-animation-duration) * .35 + var(--oc-animation-stagger) * var(--oc-mark-index,0))}.oc-animate .oc-mark-area~circle.oc-mark-point{animation-delay:calc(var(--oc-animation-duration) * .35 + var(--oc-animation-stagger) * var(--oc-mark-index,0))}.oc-animate .oc-mark-text text{animation:oc-enter-fade calc(var(--oc-animation-duration) * .6) var(--oc-animation-ease,var(--oc-ease-smooth)) both;animation-delay:calc(var(--oc-animation-stagger) * var(--oc-mark-index,0))}.oc-animate .oc-mark-rule line{animation:oc-enter-fade calc(var(--oc-animation-duration) * .5) var(--oc-animation-ease,var(--oc-ease-smooth)) both;animation-delay:calc(var(--oc-animation-stagger) * var(--oc-mark-index,0))}.oc-animate .oc-mark-tick line{animation:oc-enter-fade calc(var(--oc-animation-duration) * .5) var(--oc-animation-ease,var(--oc-ease-smooth)) both;animation-delay:calc(var(--oc-animation-stagger) * var(--oc-mark-index,0))}.oc-animate .oc-mark-label{animation:oc-enter-fade .3s var(--oc-ease-smooth) both;animation-delay:calc(var(--oc-animation-stagger) * var(--oc-mark-index,0) + var(--oc-animation-duration) * .7)}.oc-animate .oc-annotation{animation:oc-enter-fade .4s var(--oc-ease-smooth) both;animation-delay:calc(var(--oc-animation-duration) + var(--oc-annotation-delay,.2s))}.oc-animate .oc-tilemap-tile{animation:oc-enter-fade-only calc(var(--oc-animation-duration) * .35) ease-in both;animation-delay:var(--oc-tile-delay,0s)}.oc-animate .oc-map-feature{animation:oc-enter-map-fill var(--oc-animation-duration) var(--oc-animation-ease,var(--oc-ease-smooth)) both;animation-delay:var(--oc-map-delay,0s)}.oc-animate .oc-map-features[data-bulk-animate]{animation:oc-enter-fade-only var(--oc-animation-duration) var(--oc-animation-ease,var(--oc-ease-smooth)) both}.oc-animate .oc-map-features[data-bulk-animate] .oc-map-feature{animation:none}.oc-animate .oc-map-borders path{animation:oc-enter-fade-only calc(var(--oc-animation-duration) * .4) ease-in both;animation-delay:calc(var(--oc-animation-duration) * .7)}.oc-animate .oc-map-point{animation:oc-enter-fade-only calc(var(--oc-animation-duration) * .4) ease-in both;animation-delay:calc(var(--oc-animation-duration) * .8 + var(--oc-mark-index,0) * 15ms)}.oc-animate .oc-sankey-node rect{animation:oc-enter-fade-only var(--oc-animation-duration) var(--oc-animation-ease,var(--oc-ease-smooth)) both;animation-delay:calc(var(--oc-animation-stagger) * var(--oc-mark-index,0))}.oc-animate .oc-sankey-link path{animation:oc-enter-fade-only var(--oc-animation-duration) var(--oc-animation-ease,var(--oc-ease-smooth)) both;animation-delay:calc(var(--oc-animation-duration) * .3 + var(--oc-animation-stagger) * var(--oc-mark-index,0))}.oc-animate .oc-barlist-row{animation:oc-enter-fade calc(var(--oc-animation-duration) * .6) var(--oc-animation-ease,var(--oc-ease-smooth)) both;animation-delay:var(--oc-row-delay,0s)}.oc-animate .oc-barlist-bar{animation:oc-enter-bar-h var(--oc-animation-duration) var(--oc-animation-ease,var(--oc-ease-smooth)) both;animation-delay:var(--oc-row-delay,0s)}.oc-animate[data-display=sparkline] .oc-mark-line,.oc-animate[data-display=sparkline] .oc-mark-area{animation-timing-function:cubic-bezier(.16,1,.3,1)}}@layer oc.reduced-motion{@media (prefers-reduced-motion:reduce){:is(.oc-root,.oc-chart-root,.oc-table-wrapper,.oc-table-root,.oc-graph-wrapper,.oc-graph-root,.oc-sankey-root,.oc-tilemap-root,.oc-barlist-root,.oc-map-root){transition:none;animation:none}:is(.oc-root,.oc-chart-root,.oc-table-wrapper,.oc-table-root,.oc-graph-wrapper,.oc-graph-root,.oc-sankey-root,.oc-tilemap-root,.oc-barlist-root,.oc-map-root) *{transition:none;animation:none}:is(.oc-root,.oc-chart-root,.oc-table-wrapper,.oc-table-root,.oc-graph-wrapper,.oc-graph-root,.oc-sankey-root,.oc-tilemap-root,.oc-barlist-root,.oc-map-root) :before{transition:none;animation:none}:is(.oc-root,.oc-chart-root,.oc-table-wrapper,.oc-table-root,.oc-graph-wrapper,.oc-graph-root,.oc-sankey-root,.oc-tilemap-root,.oc-barlist-root,.oc-map-root) :after{transition:none;animation:none}}}
|
|
1
|
+
@layer oc.tokens{.oc-root,.oc-chart-root,.oc-table-wrapper,.oc-table-root,.oc-graph-wrapper,.oc-graph-root,.oc-sankey-root,.oc-tilemap-root,.oc-barlist-root,.oc-map-root{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;-webkit-text-size-adjust:100%;-moz-text-size-adjust:100%;-ms-text-size-adjust:100%;text-size-adjust:100%;--oc-font-family:"Inter Variable", Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;--oc-font-mono:"JetBrains Mono", "Fira Code", "Cascadia Code", monospace;--oc-ease-smooth:linear(0, .157, .438, .64, .766, .85, .906, .941, .964, .978, .988, .994, .998, 1);--oc-ease-snappy:linear(0, .012, .048, .108, .194, .302, .426, .559, .69, .808, .905, .973, 1.013, 1.028, 1.023, 1.006, .984, .966, .957, .957, .964, .975, .986, .995, 1, 1.003, 1.002, 1, .998, .998, .999, 1);--oc-animation-duration:.5s;--oc-animation-stagger:80ms;--oc-annotation-delay:.2s;--oc-title-size:26px;--oc-title-weight:590;--oc-title-tracking:-.022em;--oc-subtitle-size:14px;--oc-subtitle-weight:450;--oc-source-size:11px;--oc-source-weight:450;--oc-body-size:13px;--oc-eyebrow-size:11px;--oc-eyebrow-weight:550;--oc-eyebrow-tracking:.08em;--oc-bg:#fff;--oc-card:#fff;--oc-secondary:#f4f4f5;--oc-text:#09090b;--oc-text-secondary:#3f3f46;--oc-text-muted:#71717a;--oc-text-faint:#d4d4d8;--oc-gridline:rgba(0,0,0,.1);--oc-axis:rgba(0,0,0,.1);--oc-border:rgba(0,0,0,.08);--oc-border-radius:2px;--oc-accent:#06b6d4;--oc-accent-strong:#0891b2;--oc-positive:#10b981;--oc-negative:#e11d48;--oc-focus:#3b82f6;--oc-focus-ring:rgba(59,130,246,.1);--oc-focus-ring-strong:rgba(59,130,246,.25);--oc-editable-hover:rgba(79,70,229,.35);--oc-space-2:8px;--oc-space-4:16px;--oc-hover-bg:rgba(0,0,0,.024);--oc-tooltip-bg:rgba(255,255,255,.88);--oc-tooltip-border:rgba(0,0,0,.08);--oc-tooltip-shadow:0 2px 8px rgba(0,0,0,.08), 0 0 1px rgba(0,0,0,.12);--oc-tooltip-text:#09090b;--oc-legend-text:#3f3f46}.oc-dark{--oc-bg:#09090b;--oc-card:#111113;--oc-secondary:#27272a;--oc-text:#f7f8f8;--oc-text-secondary:#d0d6e0;--oc-text-muted:#a1a1aa;--oc-text-faint:#52525b;--oc-gridline:rgba(255,255,255,.05);--oc-axis:rgba(255,255,255,.1);--oc-border:rgba(255,255,255,.1);--oc-accent:#06b6d4;--oc-accent-strong:#06b6d4;--oc-positive:#34d399;--oc-negative:#fb7185;--oc-focus:#60a5fa;--oc-hover-bg:rgba(255,255,255,.05);--oc-tooltip-bg:rgba(17,17,19,.92);--oc-tooltip-border:rgba(255,255,255,.08);--oc-tooltip-shadow:0 2px 8px rgba(0,0,0,.3), 0 0 1px rgba(0,0,0,.4);--oc-tooltip-text:#f7f8f8;--oc-legend-text:#d0d6e0}}@layer oc.base{.oc-chart-root,.oc-table-root,.oc-graph-root,.oc-sankey-root,.oc-barlist-root,.oc-tilemap-root,.oc-map-root{width:100%;height:100%}.oc-table-root{overflow:auto}.oc-chart{font-family:var(--oc-font-family);width:100%;display:block}.oc-tilemap,.oc-map{width:100%;height:auto;display:block}.oc-map-feature{transition:opacity .4s}.oc-barlist{width:100%;display:block}.oc-sr-only{clip-path:inset(50%);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.oc-editable-hover{outline:1.5px solid var(--oc-editable-hover);outline-offset:2px;border-radius:2px}.oc-root:focus-visible{outline:2px solid var(--oc-focus);outline-offset:2px}.oc-mark-focused{outline:2px solid var(--oc-focus);outline-offset:1px;border-radius:2px}}@layer oc.components{.oc-chrome{font-family:var(--oc-font-family)}.oc-eyebrow{font-size:var(--oc-eyebrow-size);font-weight:var(--oc-eyebrow-weight);letter-spacing:var(--oc-eyebrow-tracking);text-transform:uppercase;fill:var(--oc-accent)}.oc-title{font-size:var(--oc-title-size);font-weight:var(--oc-title-weight);letter-spacing:var(--oc-title-tracking);fill:var(--oc-text)}.oc-subtitle{font-size:var(--oc-subtitle-size);font-weight:var(--oc-subtitle-weight);fill:var(--oc-text-muted)}.oc-source,.oc-byline,.oc-footer{font-size:var(--oc-source-size);font-weight:var(--oc-source-weight);fill:var(--oc-text-muted)}.oc-brand{letter-spacing:.02em;fill:var(--oc-text-faint);font-size:11px;font-weight:510}.oc-brand-dot,.oc-eyebrow-dot{fill:var(--oc-accent)}.oc-metrics{font-family:var(--oc-font-family)}.oc-metric-label{letter-spacing:.08em;text-transform:uppercase;fill:var(--oc-text-muted);font-size:10px;font-weight:510}.oc-metric-value{letter-spacing:-.01em;fill:var(--oc-text);font-variant-numeric:tabular-nums;font-size:22px;font-weight:510}.oc-metric-delta-up{fill:var(--oc-positive);font-size:12px;font-weight:510}.oc-metric-delta-down{fill:var(--oc-negative);font-size:12px;font-weight:510}.oc-metric-secondary{fill:var(--oc-positive);font-size:12px;font-weight:400}.oc-axis-tick-inline{fill:var(--oc-text-muted);font-size:11px;font-weight:400}.oc-endpoint-labels{font-family:var(--oc-font-family)}.oc-endpoint-label{fill:var(--oc-endpoint-label-color,var(--oc-text))}.oc-endpoint-value{fill:var(--oc-endpoint-value-color,var(--oc-text-muted))}.oc-endpoint-leader{stroke:var(--oc-endpoint-leader-color,currentColor)}.oc-annotation-subtitle{fill:var(--oc-annotation-subtitle-color,var(--oc-text-muted))}.oc-table-footer-row{align-items:baseline;gap:16px;padding:16px 16px 4px;display:flex}.oc-chrome-footer{padding-top:0}.oc-table-footer-row .oc-table-ref{text-align:right;flex-shrink:0;margin-left:auto}.oc-tooltip{pointer-events:none;z-index:1000;background:var(--oc-tooltip-bg);-webkit-backdrop-filter:blur(14px);backdrop-filter:blur(14px);border:1px solid var(--oc-tooltip-border);border-radius:var(--oc-border-radius,2px);box-shadow:var(--oc-tooltip-shadow);color:var(--oc-tooltip-text);font-family:var(--oc-font-family);min-width:160px;max-width:280px;padding:0;font-size:12px;line-height:1.4;transition:left .1s ease-in-out,top .1s ease-in-out;animation:.12s ease-out oc-tooltip-in;display:none;position:absolute}.oc-tooltip .oc-tooltip-header{align-items:center;gap:8px;padding:8px 12px 6px;display:flex}.oc-tooltip .oc-tooltip-dot{border-radius:50%;flex-shrink:0;width:8px;height:8px}.oc-tooltip .oc-tooltip-title{letter-spacing:.04em;text-transform:uppercase;color:var(--oc-text-muted);white-space:nowrap;text-overflow:ellipsis;font-size:11px;font-weight:590;overflow:hidden}.oc-tooltip .oc-tooltip-body{border-top:1px solid var(--oc-tooltip-border);padding:6px 12px 10px}.oc-tooltip .oc-tooltip-body:first-child{border-top:none;padding-top:10px}.oc-tooltip .oc-tooltip-row{justify-content:space-between;align-items:baseline;gap:16px;padding:2px 0;display:flex}.oc-tooltip .oc-tooltip-row-swatch{border-radius:50%;flex-shrink:0;width:8px;height:8px;margin-right:6px;display:inline-block;transform:translateY(-1px)}.oc-tooltip .oc-tooltip-label{color:var(--oc-text-secondary);white-space:nowrap;flex-shrink:0;align-items:center;font-size:12px;font-weight:400;display:inline-flex}.oc-tooltip .oc-tooltip-value{font-variant-numeric:tabular-nums;color:var(--oc-tooltip-text);text-align:right;text-overflow:ellipsis;white-space:nowrap;font-size:12px;font-weight:510;overflow:hidden}.oc-crosshair{pointer-events:none;transition:x1 50ms ease-in-out,x2 50ms ease-in-out}.oc-snap-dots circle{pointer-events:none;transition:cx 50ms ease-in-out,cy 50ms ease-in-out}.oc-legend{font-family:var(--oc-font-family);font-size:var(--oc-body-size)}.oc-legend-entry{cursor:default}.oc-legend text{fill:var(--oc-legend-text)}.oc-series-search{font-family:var(--oc-font-family);z-index:10;justify-content:flex-end;align-items:center;gap:8px;display:flex;position:absolute}.oc-series-search-chips{scrollbar-width:none;align-items:center;gap:6px;min-width:0;display:flex;overflow-x:auto}.oc-series-search-chips::-webkit-scrollbar{display:none}.oc-series-search-chip{border:1px solid var(--oc-border);background:var(--oc-secondary);color:var(--oc-text-secondary);white-space:nowrap;border-radius:999px;align-items:center;gap:4px;padding:3px 4px 3px 10px;font-size:12px;font-weight:500;line-height:16px;display:inline-flex}.oc-series-search-chip-remove{width:16px;height:16px;color:var(--oc-text-muted);cursor:pointer;background:0 0;border:none;border-radius:50%;justify-content:center;align-items:center;margin:-4px -2px -4px -4px;padding:4px;transition:color .15s,background-color .15s;display:inline-flex}.oc-series-search-chip-remove:hover{color:var(--oc-text);background:var(--oc-hover-bg)}.oc-series-search-chip-remove:focus-visible{outline:2px solid var(--oc-focus);outline-offset:1px}.oc-series-search-chip-remove svg{display:block}.oc-series-search-box{flex:0 220px;min-width:120px;position:relative}.oc-series-search-icon{color:var(--oc-text-muted);pointer-events:none;position:absolute;top:50%;left:9px;transform:translateY(-50%)}.oc-series-search-input{height:32px;padding:0 10px 0 28px}.oc-series-search-listbox{border:1px solid var(--oc-border);background:var(--oc-card);min-width:100%;max-height:240px;box-shadow:var(--oc-tooltip-shadow);z-index:20;border-radius:8px;margin:0;padding:4px;list-style:none;position:absolute;top:calc(100% + 4px);right:0;overflow-y:auto}.oc-series-search-option{color:var(--oc-text);cursor:pointer;white-space:nowrap;text-overflow:ellipsis;border-radius:4px;padding:6px 10px;font-size:13px;overflow:hidden}.oc-series-search-option[aria-selected=true],.oc-series-search-option:hover{background:var(--oc-hover-bg)}.oc-series-search-match{font-weight:600}.oc-series-search-empty{color:var(--oc-text-muted);padding:6px 10px;font-size:12px}.oc-ydi-region{opacity:.35;transition:opacity .4s}.oc-ydi-region[data-ydi-hidden=true]{opacity:0}.oc-ydi-boundary{stroke:var(--oc-text-muted);stroke-width:1px;stroke-dasharray:3 3;stroke-opacity:.6}.oc-ydi-guess{stroke:var(--oc-focus);stroke-width:2.5px;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:1 6}.oc-ydi-comparison{stroke:var(--oc-text-muted);stroke-width:1.5px;stroke-opacity:.5;stroke-dasharray:4 4}.oc-ydi-clip-rect.oc-ydi-clip-animate{transition:width .7s cubic-bezier(.22,1,.36,1)}.oc-ydi-controls{pointer-events:none;font-family:var(--oc-font-family);box-sizing:border-box;z-index:10;flex-direction:column;justify-content:space-between;align-items:flex-end;padding:8px;display:flex}.oc-ydi-prompt{background:var(--oc-card);border:1px solid var(--oc-border);max-width:100%;color:var(--oc-text-secondary);text-align:center;box-shadow:var(--oc-tooltip-shadow);border-radius:6px;align-self:center;padding:6px 12px;font-size:13px;font-weight:500;line-height:16px}.oc-ydi-controls.oc-ydi-revealed .oc-ydi-prompt{display:none}.oc-ydi-reveal-button{pointer-events:auto;border:1px solid var(--oc-border);background:var(--oc-bg);color:var(--oc-text);cursor:pointer;box-shadow:var(--oc-tooltip-shadow);border-radius:6px;justify-content:center;align-items:center;padding:6px 14px;font-family:inherit;font-size:13px;font-weight:500;transition:background-color .15s,border-color .15s;display:inline-flex}.oc-ydi-reveal-button:hover{background:var(--oc-hover-bg)}.oc-ydi-reveal-button:focus-visible{outline:2px solid var(--oc-focus);outline-offset:2px}.oc-ydi-reveal-button:disabled{opacity:.5;cursor:default}.oc-table-wrapper{font-family:var(--oc-font-family);color:var(--oc-text);background:var(--oc-bg)}.oc-table-wrapper>.oc-chrome{margin-bottom:16px;padding-left:16px;padding-right:16px}.oc-table-wrapper>.oc-chrome:first-child{padding-top:4px}.oc-table-wrapper table{border-collapse:collapse;width:100%}.oc-table-wrapper th{text-align:left;border-bottom:1px solid var(--oc-border);padding:10px 16px}.oc-table-wrapper td{text-align:left;border-bottom:1px solid var(--oc-border);padding:10px 16px}.oc-table-wrapper th{text-transform:uppercase;letter-spacing:.05em;color:var(--oc-text-secondary);white-space:nowrap;font-size:12px;font-weight:600}.oc-table-wrapper thead{z-index:2;background:var(--oc-bg);position:sticky;top:0}.oc-table-wrapper thead th{border-bottom-width:2px}.oc-table-wrapper td{font-variant-numeric:tabular-nums;font-size:14px}.oc-table-wrapper th:focus{outline:2px solid var(--oc-focus);outline-offset:-2px}.oc-table-wrapper tbody:focus{outline:none}.oc-table-title{font-size:var(--oc-title-computed-size,var(--oc-title-size));font-weight:var(--oc-title-computed-weight,var(--oc-title-weight));color:var(--oc-title-computed-color,var(--oc-text));margin-bottom:4px}.oc-table-subtitle{font-size:var(--oc-subtitle-computed-size,var(--oc-subtitle-size));font-weight:var(--oc-subtitle-computed-weight,var(--oc-subtitle-weight));color:var(--oc-subtitle-computed-color,var(--oc-text-secondary));margin-bottom:8px}.oc-table-source{font-size:var(--oc-source-computed-size,var(--oc-source-size));color:var(--oc-source-computed-color,var(--oc-text-muted))}.oc-table-footer-text{font-size:var(--oc-footer-computed-size,var(--oc-source-size));color:var(--oc-footer-computed-color,var(--oc-text-muted))}.oc-table-scroll{overflow-x:auto}.oc-table--sticky th:first-child{z-index:1;background:var(--oc-bg);position:sticky;left:0}.oc-table--sticky td:first-child{z-index:1;background:var(--oc-bg);position:sticky;left:0}.oc-table-sort-btn{cursor:pointer;vertical-align:middle;background:0 0;border:none;flex-direction:column;align-items:center;gap:2px;margin-left:6px;padding:2px;display:inline-flex}.oc-table-sort-btn:before{content:"";border-left:5px solid transparent;border-right:5px solid transparent;width:0;height:0;transition:opacity .15s,border-color .15s;display:block}.oc-table-sort-btn:after{content:"";border-left:5px solid transparent;border-right:5px solid transparent;width:0;height:0;transition:opacity .15s,border-color .15s;display:block}.oc-table-sort-btn:before{border-bottom:4.5px solid var(--oc-text-secondary);opacity:.45}.oc-table-sort-btn:after{border-top:4.5px solid var(--oc-text-secondary);opacity:.45}.oc-table-sort-btn:hover:before{opacity:.75}.oc-table-sort-btn:hover:after{opacity:.75}th[aria-sort=ascending] .oc-table-sort-btn:before{opacity:1;border-bottom-color:var(--oc-text)}th[aria-sort=ascending] .oc-table-sort-btn:after{opacity:.15}th[aria-sort=descending] .oc-table-sort-btn:after{opacity:1;border-top-color:var(--oc-text)}th[aria-sort=descending] .oc-table-sort-btn:before{opacity:.15}.oc-table-search input,.oc-series-search-input{border:1px solid var(--oc-border);background:var(--oc-bg);width:100%;color:var(--oc-text);box-sizing:border-box;border-radius:6px;font-family:inherit;font-size:13px;transition:border-color .15s}.oc-table-search input::-ms-input-placeholder{color:var(--oc-text-muted);font-size:13px}.oc-table-search input::placeholder{color:var(--oc-text-muted);font-size:13px}.oc-series-search-input::-ms-input-placeholder{color:var(--oc-text-muted);font-size:13px}.oc-series-search-input::placeholder{color:var(--oc-text-muted);font-size:13px}.oc-table-search input:focus,.oc-series-search-input:focus{border-color:var(--oc-focus);box-shadow:0 0 0 3px var(--oc-focus-ring);outline:none}.oc-table-search{padding:8px 0}.oc-table-search input{padding:8px 12px}.oc-table-pagination{color:var(--oc-text-secondary);justify-content:space-between;align-items:center;padding:12px 0 4px;font-size:13px;display:flex}.oc-table-pagination button{border:1px solid var(--oc-border);background:var(--oc-bg);color:var(--oc-text);cursor:pointer;border-radius:6px;padding:6px 14px;font-family:inherit;font-size:13px;transition:background .15s,border-color .15s}.oc-table-pagination button:disabled{opacity:.35;cursor:not-allowed}.oc-table-pagination button:hover:not(:disabled){background:var(--oc-hover-bg);border-color:var(--oc-axis)}.oc-table-pagination button:focus-visible{outline:2px solid var(--oc-focus);outline-offset:1px}.oc-table-pagination-info{font-variant-numeric:tabular-nums}.oc-table-pagination-btns{gap:8px;display:flex}.oc-table-bar{position:relative}.oc-table-bar-fill{opacity:.15;pointer-events:none;border-radius:2px;position:absolute;top:6px;bottom:6px;left:0}.oc-table-bar-value{z-index:1;position:relative}.oc-table-sparkline{width:100%;display:block;position:relative}.oc-table-sparkline svg{width:100%;display:block;overflow:visible}.oc-table-sparkline-dot{border-radius:50%;width:5px;height:5px;position:absolute}.oc-table-sparkline-labels{justify-content:space-between;font-size:11px;line-height:1;display:flex}.oc-table-image{vertical-align:middle;display:inline-block}.oc-table-image img{object-fit:cover}.oc-table-image-rounded img{border-radius:50%}.oc-table-flag{font-size:1.2em}.oc-table--compact th{padding:4px 8px;font-size:13px}.oc-table--compact td{padding:4px 8px;font-size:13px}.oc-table--compact th{font-size:11px}.oc-table--clickable tbody tr{cursor:pointer}.oc-table--clickable tbody tr:hover{background:var(--oc-hover-bg)}.oc-table-cell-focus{outline:2px solid var(--oc-focus);outline-offset:-2px}.oc-table-empty{text-align:center;color:var(--oc-text-secondary);padding:32px 16px;font-size:14px;font-style:italic}.oc-graph-wrapper{background:var(--oc-bg);font-family:var(--oc-font-family);width:100%;height:100%;position:relative;overflow:hidden}.oc-graph-canvas{cursor:grab;width:100%;height:100%;display:block}.oc-graph-canvas--dragging{cursor:grabbing}.oc-graph-chrome{z-index:2;pointer-events:none;padding:16px 16px 8px;position:absolute;top:0;left:0;right:0}.oc-graph-chrome .oc-title{font-size:var(--oc-title-size);font-weight:var(--oc-title-weight);letter-spacing:var(--oc-title-tracking);color:var(--oc-text);--_stroke:color-mix(in srgb, var(--oc-bg) 80%, transparent);text-shadow:-2px -2px 0 var(--_stroke), 2px -2px 0 var(--_stroke), -2px 2px 0 var(--_stroke), 2px 2px 0 var(--_stroke), 0 -2px 0 var(--_stroke), 0 2px 0 var(--_stroke), -2px 0 0 var(--_stroke), 2px 0 0 var(--_stroke);margin:0 0 4px}.oc-graph-chrome .oc-subtitle{font-size:var(--oc-subtitle-size);color:var(--oc-text-secondary);--_stroke:color-mix(in srgb, var(--oc-bg) 80%, transparent);text-shadow:-1px -1px 0 var(--_stroke), 1px -1px 0 var(--_stroke), -1px 1px 0 var(--_stroke), 1px 1px 0 var(--_stroke);margin:0}.oc-graph-legend{background:var(--oc-bg);border:1px solid var(--oc-border);border-radius:var(--oc-border-radius);color:var(--oc-text-secondary);max-height:200px;padding:8px 12px;font-size:12px;position:absolute;top:8px;right:8px;overflow-y:auto}.oc-graph-legend-item{align-items:center;gap:6px;padding:2px 0;display:flex}.oc-graph-legend-swatch{border-radius:50%;flex-shrink:0;width:10px;height:10px}.oc-graph-search{position:absolute;top:8px;left:8px}.oc-graph-search input{font-family:var(--oc-font-family);font-size:var(--oc-body-size);border:1px solid var(--oc-border);border-radius:var(--oc-border-radius);background:var(--oc-bg);color:var(--oc-text);outline:none;padding:6px 10px}.oc-graph-search input:focus{border-color:var(--oc-focus);box-shadow:0 0 0 2px var(--oc-focus-ring-strong)}.oc-dark .oc-graph-wrapper,.oc-graph-wrapper.oc-dark{--oc-bg:#0d1117}.oc-dark .oc-graph-legend,.oc-dark.oc-graph-wrapper .oc-graph-legend,.oc-dark .oc-graph-search input{border-color:var(--oc-border);background:rgba(13,17,23,.85)}.oc-chart[data-display=sparkline]{margin:0;padding:0;display:block}}@layer oc.animation{.oc-table-wrapper.oc-animate>.oc-chrome{animation:oc-enter-fade calc(var(--oc-animation-duration) * .6) var(--oc-animation-ease,var(--oc-ease-smooth)) both}.oc-table-wrapper.oc-animate thead{animation:oc-enter-fade-only calc(var(--oc-animation-duration) * .4) var(--oc-animation-ease,var(--oc-ease-smooth)) both}.oc-table-wrapper.oc-animate tbody tr{animation:oc-table-enter-row var(--oc-animation-duration) var(--oc-animation-ease,var(--oc-ease-smooth)) both;animation-delay:calc(var(--oc-animation-stagger) * var(--oc-row-index,0))}.oc-table-wrapper.oc-animate tbody td{animation:oc-enter-fade-only calc(var(--oc-animation-duration) * .5) var(--oc-animation-ease,var(--oc-ease-smooth)) both;animation-delay:calc(var(--oc-animation-stagger) * var(--oc-row-index,0))}.oc-table-wrapper.oc-animate td.oc-table-heatmap{animation:oc-enter-fade-only calc(var(--oc-animation-duration) * .7) var(--oc-animation-ease,var(--oc-ease-smooth)) both;animation-delay:calc(var(--oc-animation-stagger) * var(--oc-row-index,0) + var(--oc-animation-duration) * .3)}.oc-table-wrapper.oc-animate td.oc-table-category{animation:oc-enter-fade-only calc(var(--oc-animation-duration) * .7) var(--oc-animation-ease,var(--oc-ease-smooth)) both;animation-delay:calc(var(--oc-animation-stagger) * var(--oc-row-index,0) + var(--oc-animation-duration) * .3)}.oc-table-wrapper.oc-animate .oc-table-bar-fill{animation:oc-table-enter-bar-fill calc(var(--oc-animation-duration) * .8) var(--oc-animation-ease,var(--oc-ease-smooth)) both;animation-delay:calc(var(--oc-animation-stagger) * var(--oc-row-index,0) + var(--oc-animation-duration) * .3)}.oc-table-wrapper.oc-animate .oc-table-sparkline>svg{animation:oc-enter-line calc(var(--oc-animation-duration) * .8) var(--oc-animation-ease,var(--oc-ease-smooth)) both;animation-delay:calc(var(--oc-animation-stagger) * var(--oc-row-index,0) + var(--oc-animation-duration) * .4)}.oc-table-wrapper.oc-animate .oc-table-sparkline-dot{animation:oc-enter-fade-only calc(var(--oc-animation-duration) * .3) var(--oc-animation-ease,var(--oc-ease-smooth)) both;animation-delay:calc(var(--oc-animation-stagger) * var(--oc-row-index,0) + var(--oc-animation-duration) * .8)}.oc-table-wrapper.oc-animate .oc-table-sparkline-labels{animation:oc-enter-fade-only calc(var(--oc-animation-duration) * .3) var(--oc-animation-ease,var(--oc-ease-smooth)) both;animation-delay:calc(var(--oc-animation-stagger) * var(--oc-row-index,0) + var(--oc-animation-duration) * .8)}.oc-table-wrapper.oc-animate .oc-table-search{animation:oc-enter-fade-only calc(var(--oc-animation-duration) * .5) var(--oc-animation-ease,var(--oc-ease-smooth)) both}.oc-table-wrapper.oc-animate .oc-table-pagination{animation:oc-enter-fade-only calc(var(--oc-animation-duration) * .5) var(--oc-animation-ease,var(--oc-ease-smooth)) both}@keyframes oc-enter-bar{0%{clip-path:inset(100% 0 0);opacity:0}75%{opacity:1}to{clip-path:inset(0);opacity:1}}@keyframes oc-enter-bar-h{0%{clip-path:inset(0 100% 0 0);opacity:0}75%{opacity:1}to{clip-path:inset(0);opacity:1}}@keyframes oc-enter-line{0%{clip-path:inset(0 100% 0 0);opacity:0}15%{opacity:1}to{clip-path:inset(0);opacity:1}}@keyframes oc-enter-point{0%{opacity:0;transform:scale(.3)}to{opacity:1;transform:scale(1)}}@keyframes oc-enter-map-fill{0%{fill:var(--oc-secondary);opacity:0}to{fill:var(--oc-feature-fill);opacity:var(--oc-feature-target-opacity,1)}}@keyframes oc-enter-map-point{0%{opacity:0;transform:scale(.75)}to{opacity:1;transform:scale(1)}}@keyframes oc-enter-fade-only{0%{opacity:0}to{opacity:1}}@keyframes oc-enter-fade{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}@keyframes oc-table-enter-row{0%{transform:translateY(6px)}to{transform:translateY(0)}}@keyframes oc-table-enter-bar-fill{0%{clip-path:inset(0 100% 0 0)}to{clip-path:inset(0)}}@keyframes oc-tooltip-in{0%{opacity:0;transform:translateY(2px)}to{opacity:1;transform:translateY(0)}}.oc-animate .oc-mark-rect rect{animation:oc-enter-bar var(--oc-animation-duration) var(--oc-ease-smooth) both;animation-delay:calc(var(--oc-animation-stagger) * var(--oc-mark-index,0))}.oc-animate .oc-mark-bar rect{animation:oc-enter-bar var(--oc-animation-duration) var(--oc-ease-smooth) both;animation-delay:calc(var(--oc-animation-stagger) * var(--oc-mark-index,0))}.oc-animate .oc-mark-rect[data-orient=horizontal] rect{animation-name:oc-enter-bar-h}.oc-animate .oc-mark-bar[data-orient=horizontal] rect{animation-name:oc-enter-bar-h}.oc-animate .oc-mark-rect[data-stack-pos] rect{animation-duration:var(--oc-stack-segment-duration,.15s);animation-timing-function:linear;animation-delay:calc(var(--oc-animation-stagger) * var(--oc-mark-index,0) + var(--oc-stack-pos,0) * var(--oc-stack-segment-duration,.15s))}.oc-animate .oc-mark-line{animation:oc-enter-line var(--oc-animation-duration) var(--oc-animation-ease,var(--oc-ease-smooth)) both;animation-delay:calc(var(--oc-animation-stagger) * var(--oc-mark-index,0))}.oc-animate .oc-mark-area{animation:oc-enter-line var(--oc-animation-duration) var(--oc-animation-ease,var(--oc-ease-smooth)) both;animation-delay:calc(var(--oc-animation-stagger) * var(--oc-mark-index,0))}.oc-animate .oc-mark-arc{animation:oc-enter-fade-only var(--oc-animation-duration) var(--oc-animation-ease,var(--oc-ease-smooth)) both;animation-delay:calc(var(--oc-animation-stagger) * var(--oc-mark-index,0))}.oc-animate circle.oc-mark-point{animation:oc-enter-fade-only calc(var(--oc-animation-duration) * .4) var(--oc-animation-ease,var(--oc-ease-smooth)) both;animation-delay:calc(var(--oc-animation-stagger) * var(--oc-mark-index,0))}.oc-animate circle.oc-mark-circle{animation:oc-enter-fade-only calc(var(--oc-animation-duration) * .4) var(--oc-animation-ease,var(--oc-ease-smooth)) both;animation-delay:calc(var(--oc-animation-stagger) * var(--oc-mark-index,0))}.oc-animate .oc-mark-line~circle.oc-mark-point{animation-delay:calc(var(--oc-animation-duration) * .35 + var(--oc-animation-stagger) * var(--oc-mark-index,0))}.oc-animate .oc-mark-area~circle.oc-mark-point{animation-delay:calc(var(--oc-animation-duration) * .35 + var(--oc-animation-stagger) * var(--oc-mark-index,0))}.oc-animate .oc-mark-text text{animation:oc-enter-fade calc(var(--oc-animation-duration) * .6) var(--oc-animation-ease,var(--oc-ease-smooth)) both;animation-delay:calc(var(--oc-animation-stagger) * var(--oc-mark-index,0))}.oc-animate .oc-mark-rule line{animation:oc-enter-fade calc(var(--oc-animation-duration) * .5) var(--oc-animation-ease,var(--oc-ease-smooth)) both;animation-delay:calc(var(--oc-animation-stagger) * var(--oc-mark-index,0))}.oc-animate .oc-mark-tick line{animation:oc-enter-fade calc(var(--oc-animation-duration) * .5) var(--oc-animation-ease,var(--oc-ease-smooth)) both;animation-delay:calc(var(--oc-animation-stagger) * var(--oc-mark-index,0))}.oc-animate .oc-mark-label{animation:oc-enter-fade .3s var(--oc-ease-smooth) both;animation-delay:calc(var(--oc-animation-stagger) * var(--oc-mark-index,0) + var(--oc-animation-duration) * .7)}.oc-animate .oc-annotation{animation:oc-enter-fade .4s var(--oc-ease-smooth) both;animation-delay:calc(var(--oc-animation-duration) + var(--oc-annotation-delay,.2s))}.oc-animate .oc-tilemap-tile{animation:oc-enter-fade-only calc(var(--oc-animation-duration) * .35) ease-in both;animation-delay:var(--oc-tile-delay,0s)}.oc-animate .oc-map-feature{animation:oc-enter-map-fill var(--oc-animation-duration) var(--oc-animation-ease,var(--oc-ease-smooth)) both;animation-delay:var(--oc-map-delay,0s)}.oc-animate .oc-map-features[data-bulk-animate]{animation:oc-enter-fade-only var(--oc-animation-duration) var(--oc-animation-ease,var(--oc-ease-smooth)) both}.oc-animate .oc-map-features[data-bulk-animate] .oc-map-feature{animation:none}.oc-animate .oc-map-borders path{animation:oc-enter-fade-only calc(var(--oc-animation-duration) * .4) ease-in both;animation-delay:calc(var(--oc-animation-duration) * .7)}.oc-animate .oc-map-point{animation:oc-enter-map-point calc(var(--oc-animation-duration) * .4) var(--oc-animation-ease,var(--oc-ease-smooth)) both;animation-delay:calc(var(--oc-animation-duration) * .8 + var(--oc-mark-index,0) * 60ms)}.oc-animate .oc-sankey-node rect{animation:oc-enter-fade-only var(--oc-animation-duration) var(--oc-animation-ease,var(--oc-ease-smooth)) both;animation-delay:calc(var(--oc-animation-stagger) * var(--oc-mark-index,0))}.oc-animate .oc-sankey-link path{animation:oc-enter-fade-only var(--oc-animation-duration) var(--oc-animation-ease,var(--oc-ease-smooth)) both;animation-delay:calc(var(--oc-animation-duration) * .3 + var(--oc-animation-stagger) * var(--oc-mark-index,0))}.oc-animate .oc-barlist-row{animation:oc-enter-fade calc(var(--oc-animation-duration) * .6) var(--oc-animation-ease,var(--oc-ease-smooth)) both;animation-delay:var(--oc-row-delay,0s)}.oc-animate .oc-barlist-bar{animation:oc-enter-bar-h var(--oc-animation-duration) var(--oc-animation-ease,var(--oc-ease-smooth)) both;animation-delay:var(--oc-row-delay,0s)}.oc-animate[data-display=sparkline] .oc-mark-line,.oc-animate[data-display=sparkline] .oc-mark-area{animation-timing-function:cubic-bezier(.16,1,.3,1)}}@layer oc.reduced-motion{@media (prefers-reduced-motion:reduce){:is(.oc-root,.oc-chart-root,.oc-table-wrapper,.oc-table-root,.oc-graph-wrapper,.oc-graph-root,.oc-sankey-root,.oc-tilemap-root,.oc-barlist-root,.oc-map-root){transition:none;animation:none}:is(.oc-root,.oc-chart-root,.oc-table-wrapper,.oc-table-root,.oc-graph-wrapper,.oc-graph-root,.oc-sankey-root,.oc-tilemap-root,.oc-barlist-root,.oc-map-root) *{transition:none;animation:none}:is(.oc-root,.oc-chart-root,.oc-table-wrapper,.oc-table-root,.oc-graph-wrapper,.oc-graph-root,.oc-sankey-root,.oc-tilemap-root,.oc-barlist-root,.oc-map-root) :before{transition:none;animation:none}:is(.oc-root,.oc-chart-root,.oc-table-wrapper,.oc-table-root,.oc-graph-wrapper,.oc-graph-root,.oc-sankey-root,.oc-tilemap-root,.oc-barlist-root,.oc-map-root) :after{transition:none;animation:none}}}
|
|
2
2
|
/*# sourceMappingURL=styles.css.map */
|
package/dist/styles.css.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"mappings":"AAWA,iBCEE,62DIFA,4lBLAF,eSNE,mIAeA,6BAQA,qEAUA,yDAOA,uCAIA,qCASA,gJAgBA,qGAcA,4EAQA,yFTrFF,qBWNE,6CAIA,2KAQA,wIAOA,+GAMA,+HAQA,wFAOA,oDAYA,8CAIA,wHAQA,4HAQA,2EAMA,6EAMA,4EAWA,8EAgBA,sDAIA,sEAMA,4EAIA,wEAaA,sFAUA,sFASA,gCAMA,mFIhKA,ogBAsBE,4FAOA,iFAOA,gMAWA,iGAMA,0EAKA,mHAQA,yJAUA,oKAUA,uMAkBF,qFAOA,4FHlHA,2EAKA,gCAIA,2CEJA,kJAaA,iHASA,wDAIA,sRAeA,6RAoBA,uFAKA,iGAKA,gDAMA,qEAMA,oIAWA,0DAKA,2RAiBA,yKAWA,0GAMA,wCAIA,mFZtIA,kDAKA,+CAKA,qGASA,wHAUA,yGAWA,qFAKA,0MAYA,oRAeA,6DAOA,mXAoBA,0DAIA,yFAKA,yDKpHA,iGAKE,qFAMA,yDAIA,4DAKA,gGAAA,gGAOA,oJASA,gFAOA,mDAIA,sEAKA,iFAKA,2CAKF,sNAOA,kPAOA,2IAKA,gJAKA,iCASE,0FAAA,0FAaF,oLAYE,mLAAA,kLAaA,yFAKA,qFAKA,4CAAA,2CAOA,+FAKA,6DAMA,4FAKA,+DAaF,iPAaA,wFAAA,8EAAA,yFAAA,+EAMA,+IAOA,+BAGE,wCASF,oJAQE,6OAaE,oEAKA,2GAKA,+FAOJ,4DAIA,+CASA,gCAIA,iHAUA,gDASA,+DAKE,kEAOF,iFAOA,mGAWA,2DAIE,qCAKF,8CAQA,+BASE,qDAAA,qDAMA,qCAUA,6CAIA,kEASF,2EASA,oHMjYA,qIASA,kEAOA,2CAIA,4GASE,8bAkBA,2RAaF,qPAcA,4EAOA,+EAOA,oDAKE,0OAUE,2GAQJ,qEAYA,iKVtHA,oEHCF,oBUJI,4JAMA,4JAOA,8NAOA,yOAOA,wRAAA,yRAcA,4RAaA,uRAYA,4RAAA,+RAaA,uKAAA,2KJ/EF,8GAgBA,kHAgBA,iHAeA,4FAaA,6GAaA,yDAUA,sGAaA,uFAWA,yFAUA,sGFpHE,yLAAA,wLAOA,qFAAA,oFASA,oRAYA,8MAOA,8MASA,kNAUA,qOAAA,sOAQA,+JAAA,+JAWA,8NAOA,8NAOA,8NAOA,iMAWA,sKAOA,wJAQA,gLASA,8JAKA,+EAKA,2KAQA,oMAMA,0NAQA,8PAYA,uLAMA,6KAeF,wJJ/LF,yBQDE,uCACE,6LAAA,+LAAA,qMAAA","sources":["../src/styles/index.css","../src/styles/tokens.css","../src/styles/sparkline.css","../src/styles/you-draw-it.css","../src/styles/animation.css","../src/styles/dark.css","../src/styles/keyframes.css","../src/styles/table.css","../src/styles/reduced-motion.css","../src/styles/base.css","../src/styles/table-animation.css","../src/styles/chrome.css","../src/styles/legend.css","../src/styles/tooltip.css","../src/styles/series-search.css","../src/styles/graph.css"],"sourcesContent":["/**\n * @opendata-ai/openchart-core styles\n *\n * CSS with oc- prefix for all class names.\n * CSS custom properties for theme overrides.\n * Dark mode via .oc-dark class on the container.\n * Cascade layers: oc.tokens, oc.base, oc.components, oc.animation, oc.reduced-motion.\n */\n\n/* For optimal typography, load Inter: https://fonts.google.com/specimen/Inter */\n\n@layer oc.tokens, oc.base, oc.components, oc.animation, oc.reduced-motion;\n\n@import \"./tokens.css\";\n@import \"./dark.css\";\n@import \"./base.css\";\n@import \"./chrome.css\";\n@import \"./tooltip.css\";\n@import \"./legend.css\";\n@import \"./series-search.css\";\n@import \"./you-draw-it.css\";\n@import \"./table.css\";\n@import \"./table-animation.css\";\n@import \"./graph.css\";\n@import \"./sparkline.css\";\n@import \"./keyframes.css\";\n@import \"./animation.css\";\n@import \"./reduced-motion.css\";\n","/* GENERATED FILE — do not edit. Source: packages/core/src/styles/token-definitions.ts. Regenerate: bun run generate:tokens */\n\n@layer oc.tokens {\n /* ---------------------------------------------------------------------------\n * Custom properties (light mode defaults)\n *\n * These are FALLBACK defaults. At runtime, the JS theme engine stamps the\n * resolved theme as inline --oc-* custom properties on each .oc-root\n * container (see packages/vanilla/src/theme-tokens.ts). These CSS values\n * serve as fallbacks for contexts where JS hasn't mounted yet (SSR, static\n * HTML examples).\n * --------------------------------------------------------------------------- */\n\n .oc-root,\n .oc-chart-root,\n .oc-table-wrapper,\n .oc-table-root,\n .oc-graph-wrapper,\n .oc-graph-root,\n .oc-sankey-root,\n .oc-tilemap-root,\n .oc-barlist-root,\n .oc-map-root {\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n\n /* Opt out of iOS text auto-inflation so measured widths match rendered text. */\n -webkit-text-size-adjust: 100%;\n text-size-adjust: 100%;\n\n --oc-font-family:\n \"Inter Variable\", Inter, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n --oc-font-mono: \"JetBrains Mono\", \"Fira Code\", \"Cascadia Code\", monospace;\n\n /* Animation easing presets via CSS linear() */\n --oc-ease-smooth: linear(\n 0,\n 0.157,\n 0.438,\n 0.64,\n 0.766,\n 0.85,\n 0.906,\n 0.941,\n 0.964,\n 0.978,\n 0.988,\n 0.994,\n 0.998,\n 1\n );\n --oc-ease-snappy: linear(\n 0,\n 0.012,\n 0.048,\n 0.108,\n 0.194,\n 0.302,\n 0.426,\n 0.559,\n 0.69,\n 0.808,\n 0.905,\n 0.973,\n 1.013,\n 1.028,\n 1.023,\n 1.006,\n 0.984,\n 0.966,\n 0.957,\n 0.957,\n 0.964,\n 0.975,\n 0.986,\n 0.995,\n 1,\n 1.003,\n 1.002,\n 1,\n 0.998,\n 0.998,\n 0.999,\n 1\n );\n\n /* Animation timing defaults */\n --oc-animation-duration: 500ms;\n --oc-animation-stagger: 80ms;\n --oc-annotation-delay: 200ms;\n\n /* Typography scale (editorial design system) */\n --oc-title-size: 26px;\n --oc-title-weight: 590;\n --oc-title-tracking: -0.022em;\n --oc-subtitle-size: 14px;\n --oc-subtitle-weight: 450;\n --oc-source-size: 11px;\n --oc-source-weight: 450;\n --oc-body-size: 13px;\n --oc-eyebrow-size: 11px;\n --oc-eyebrow-weight: 550;\n --oc-eyebrow-tracking: 0.08em;\n\n /* Surfaces (light mode defaults) */\n --oc-bg: #ffffff;\n --oc-card: #ffffff;\n --oc-secondary: #f4f4f5; /* zinc-100, raised surface */\n\n /*\n * Text levels. Names invert across modes: in light mode \"muted\" sits at\n * a lighter zinc step than \"subtle\" because both are picked relative to\n * the active background, not from a fixed lightness ladder. The intent\n * is \"muted = first step away from primary text\"; \"subtle = next step\n * down\"; etc.\n *\n * Light mode: text=zinc-950, secondary=zinc-700, muted=zinc-500,\n * subtle=zinc-400, faint=zinc-300\n * Dark mode (dark.css): inverts the surface tokens but keeps the same\n * muted -> subtle -> faint progression away from primary.\n */\n --oc-text: #09090b;\n --oc-text-secondary: #3f3f46;\n --oc-text-muted: #71717a;\n --oc-text-faint: #d4d4d8;\n\n /* Lines */\n --oc-gridline: rgba(0, 0, 0, 0.1);\n --oc-axis: rgba(0, 0, 0, 0.1);\n --oc-border: rgba(0, 0, 0, 0.08);\n --oc-border-radius: 2px;\n\n /* Brand and semantic */\n --oc-accent: #06b6d4;\n --oc-accent-strong: #0891b2; /* darker cyan for line strokes on light bg */\n --oc-positive: #10b981;\n --oc-negative: #e11d48;\n --oc-focus: #3b82f6;\n /* static, intentionally NOT derived from --oc-focus and NOT flipped in dark mode */\n --oc-focus-ring: rgba(59, 130, 246, 0.1);\n --oc-focus-ring-strong: rgba(59, 130, 246, 0.25);\n --oc-editable-hover: rgba(79, 70, 229, 0.35); /* edit-mode hover outline, indigo one-off */\n\n /* Spacing scale (4px base) — only --oc-space-2/4 are consumed (JS-stamped) */\n --oc-space-2: 8px;\n --oc-space-4: 16px;\n\n /* Interactive states */\n --oc-hover-bg: rgba(0, 0, 0, 0.025);\n --oc-tooltip-bg: rgba(255, 255, 255, 0.88);\n --oc-tooltip-border: rgba(0, 0, 0, 0.08);\n --oc-tooltip-shadow: 0 2px 8px rgba(0, 0, 0, 0.08), 0 0 1px rgba(0, 0, 0, 0.12);\n --oc-tooltip-text: #09090b;\n --oc-legend-text: #3f3f46;\n }\n}\n","@layer oc.components {\n /**\n * Sparkline display mode.\n *\n * Stamped on the SVG root as data-display=\"sparkline\" by the renderer when\n * the spec sets display: 'sparkline'. Strips any inherited padding/margin\n * so the mark renders truly edge-to-edge in tight container layouts (KPI\n * cards, table cells, dashboard tiles).\n */\n\n .oc-chart[data-display=\"sparkline\"] {\n display: block;\n margin: 0;\n padding: 0;\n }\n}\n","@layer oc.components {\n /* ---------------------------------------------------------------------------\n * You draw it (youDrawIt)\n *\n * NYT-style draw-then-reveal. SVG-space elements (hatched region, guess path,\n * reveal clip) render inside the chart SVG; the prompt + skip-to-reveal button\n * are an absolutely-positioned HTML overlay the vanilla adapter sizes over the\n * drawing region (inline left/top/width/height). All colors come from --oc-*\n * tokens so they flip in .oc-dark.\n * --------------------------------------------------------------------------- */\n\n /* Hatched \"draw here\" region. Fill comes from an SVG <pattern> (line color =\n * the target series color); this only governs overall opacity + fade-out. */\n .oc-ydi-region {\n opacity: 0.35;\n transition: opacity 0.4s ease;\n }\n\n .oc-ydi-region[data-ydi-hidden=\"true\"] {\n opacity: 0;\n }\n\n /* The vertical rule at `from` where drawing begins. */\n .oc-ydi-boundary {\n stroke: var(--oc-text-muted);\n stroke-width: 1;\n stroke-dasharray: 3 3;\n stroke-opacity: 0.6;\n }\n\n /* Reader's guess: a distinct pen-like stroke that reads as \"yours\" against the\n * solid real line. Dashed + focus-blue so it stays legible in both modes. */\n .oc-ydi-guess {\n stroke: var(--oc-focus);\n stroke-width: 2.5;\n stroke-linecap: round;\n stroke-linejoin: round;\n stroke-dasharray: 1 6;\n }\n\n /* Host-supplied comparison line (\"what everyone else guessed\"). Muted so it\n * sits behind the reader's guess and the real line. */\n .oc-ydi-comparison {\n stroke: var(--oc-text-muted);\n stroke-width: 1.5;\n stroke-opacity: 0.5;\n stroke-dasharray: 4 4;\n }\n\n /* Reveal clip rect: the width animates from the `from` boundary to the full\n * area on reveal, wiping the real line in left-to-right. The vanilla adapter\n * adds .oc-ydi-clip-animate right before setting the final width; reduced\n * motion skips the class so the width snaps. */\n .oc-ydi-clip-rect.oc-ydi-clip-animate {\n transition: width 0.7s cubic-bezier(0.22, 1, 0.36, 1);\n }\n\n /* HTML controls overlay: prompt (top) + reveal button (bottom-right). */\n .oc-ydi-controls {\n display: flex;\n flex-direction: column;\n justify-content: space-between;\n align-items: flex-end;\n pointer-events: none;\n font-family: var(--oc-font-family);\n padding: 8px;\n box-sizing: border-box;\n z-index: 10;\n }\n\n .oc-ydi-prompt {\n align-self: center;\n max-width: 100%;\n padding: 6px 12px;\n border-radius: 6px;\n background: var(--oc-card);\n border: 1px solid var(--oc-border);\n color: var(--oc-text-secondary);\n font-size: 13px;\n font-weight: 500;\n line-height: 16px;\n text-align: center;\n box-shadow: var(--oc-tooltip-shadow);\n }\n\n .oc-ydi-controls.oc-ydi-revealed .oc-ydi-prompt {\n display: none;\n }\n\n /* Skip-to-reveal button. pointer-events re-enabled (the overlay disables it)\n * so it stays clickable and keyboard-reachable. Min height enforced inline by\n * the adapter (>= 24px effective touch target). */\n .oc-ydi-reveal-button {\n pointer-events: auto;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n padding: 6px 14px;\n border: 1px solid var(--oc-border);\n border-radius: 6px;\n background: var(--oc-bg);\n color: var(--oc-text);\n font-family: inherit;\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n box-shadow: var(--oc-tooltip-shadow);\n transition:\n background-color 0.15s,\n border-color 0.15s;\n }\n\n .oc-ydi-reveal-button:hover {\n background: var(--oc-hover-bg);\n }\n\n .oc-ydi-reveal-button:focus-visible {\n outline: 2px solid var(--oc-focus);\n outline-offset: 2px;\n }\n\n .oc-ydi-reveal-button:disabled {\n opacity: 0.5;\n cursor: default;\n }\n}\n","@layer oc.animation {\n /* ---------------------------------------------------------------------------\n * Animation scoped rules (.oc-animate enables animation on the chart root)\n * --------------------------------------------------------------------------- */\n\n .oc-animate {\n /* Vertical bars (default): smooth ease-out, no overshoot.\n oc-mark-bar is reserved for future mark type aliases. */\n & .oc-mark-rect rect,\n & .oc-mark-bar rect {\n animation: oc-enter-bar var(--oc-animation-duration) var(--oc-ease-smooth) both;\n animation-delay: calc(var(--oc-animation-stagger) * var(--oc-mark-index, 0));\n }\n\n /* Horizontal bars (data-orient is on the mark group, not the SVG root) */\n & .oc-mark-rect[data-orient=\"horizontal\"] rect,\n & .oc-mark-bar[data-orient=\"horizontal\"] rect {\n animation-name: oc-enter-bar-h;\n }\n\n /* Stacked bar/column segments: chain sequentially so each segment starts\n right when the previous one finishes, creating one fluid reveal.\n Uses linear easing so handoffs between segments are seamless (no\n deceleration/acceleration stutter at segment boundaries). */\n & .oc-mark-rect[data-stack-pos] rect {\n animation-duration: var(--oc-stack-segment-duration, 150ms);\n animation-timing-function: linear;\n animation-delay: calc(\n var(--oc-animation-stagger) *\n var(--oc-mark-index, 0) +\n var(--oc-stack-pos, 0) *\n var(--oc-stack-segment-duration, 150ms)\n );\n }\n\n /* Line marks: entire group clips left-to-right (no WAAPI needed) */\n & .oc-mark-line {\n animation: oc-enter-line var(--oc-animation-duration)\n var(--oc-animation-ease, var(--oc-ease-smooth)) both;\n animation-delay: calc(var(--oc-animation-stagger) * var(--oc-mark-index, 0));\n }\n\n /* Area marks: entire group clips left-to-right + fades in */\n & .oc-mark-area {\n animation: oc-enter-line var(--oc-animation-duration)\n var(--oc-animation-ease, var(--oc-ease-smooth)) both;\n animation-delay: calc(var(--oc-animation-stagger) * var(--oc-mark-index, 0));\n }\n\n /* Arc marks (pie/donut slices): simple fade in.\n Scale transforms break arc positioning because arcs use translate()\n on parent groups. A clean fade is more elegant for pie/donut anyway. */\n & .oc-mark-arc {\n animation: oc-enter-fade-only var(--oc-animation-duration)\n var(--oc-animation-ease, var(--oc-ease-smooth)) both;\n animation-delay: calc(var(--oc-animation-stagger) * var(--oc-mark-index, 0));\n }\n\n /* Point marks (scatter, dot).\n Points render as bare <circle> elements with class oc-mark-point directly,\n not wrapped in a group, so we target circle.oc-mark-point (not descendant).\n Duration is 40% of the configured duration (quick pop-in relative to other marks). */\n & circle.oc-mark-point,\n & circle.oc-mark-circle {\n animation: oc-enter-fade-only calc(var(--oc-animation-duration) * 0.4)\n var(--oc-animation-ease, var(--oc-ease-smooth)) both;\n animation-delay: calc(var(--oc-animation-stagger) * var(--oc-mark-index, 0));\n }\n\n /* Points on line/area charts: delay so they pop in as the line draws through. */\n & .oc-mark-line ~ circle.oc-mark-point,\n & .oc-mark-area ~ circle.oc-mark-point {\n animation-delay: calc(\n var(--oc-animation-duration) *\n 0.35 +\n var(--oc-animation-stagger) *\n var(--oc-mark-index, 0)\n );\n }\n\n /* Text marks: fade + slight slide up */\n & .oc-mark-text text {\n animation: oc-enter-fade calc(var(--oc-animation-duration) * 0.6)\n var(--oc-animation-ease, var(--oc-ease-smooth)) both;\n animation-delay: calc(var(--oc-animation-stagger) * var(--oc-mark-index, 0));\n }\n\n /* Rule marks: fade in */\n & .oc-mark-rule line {\n animation: oc-enter-fade calc(var(--oc-animation-duration) * 0.5)\n var(--oc-animation-ease, var(--oc-ease-smooth)) both;\n animation-delay: calc(var(--oc-animation-stagger) * var(--oc-mark-index, 0));\n }\n\n /* Tick marks: fade in */\n & .oc-mark-tick line {\n animation: oc-enter-fade calc(var(--oc-animation-duration) * 0.5)\n var(--oc-animation-ease, var(--oc-ease-smooth)) both;\n animation-delay: calc(var(--oc-animation-stagger) * var(--oc-mark-index, 0));\n }\n\n /* Data labels: fade after their parent mark */\n & .oc-mark-label {\n animation: oc-enter-fade 300ms var(--oc-ease-smooth) both;\n animation-delay: calc(\n var(--oc-animation-stagger) *\n var(--oc-mark-index, 0) +\n var(--oc-animation-duration) *\n 0.7\n );\n }\n\n /* Annotations: fade in after marks finish */\n & .oc-annotation {\n animation: oc-enter-fade 400ms var(--oc-ease-smooth) both;\n animation-delay: calc(var(--oc-animation-duration) + var(--oc-annotation-delay, 200ms));\n }\n\n /* Tilemap tiles: fade in with jittered stagger for organic feel.\n Per-tile delay is computed in the renderer with pseudo-random variation. */\n & .oc-tilemap-tile {\n animation: oc-enter-fade-only calc(var(--oc-animation-duration) * 0.35) ease-in both;\n animation-delay: var(--oc-tile-delay, 0ms);\n }\n\n /* Map features: fill color reveal with shuffled stagger.\n Per-feature --oc-map-delay is computed in the renderer via a seeded\n Fisher-Yates shuffle so features pop in organically. */\n & .oc-map-feature {\n animation: oc-enter-map-fill var(--oc-animation-duration)\n var(--oc-animation-ease, var(--oc-ease-smooth)) both;\n animation-delay: var(--oc-map-delay, 0ms);\n }\n\n /* Bulk mode: high feature counts (counties, ~3k+) get a single group\n fade instead of per-feature fill animations. opacity is GPU-compositable\n so this stays smooth regardless of child count. */\n & .oc-map-features[data-bulk-animate] {\n animation: oc-enter-fade-only var(--oc-animation-duration)\n var(--oc-animation-ease, var(--oc-ease-smooth)) both;\n }\n\n & .oc-map-features[data-bulk-animate] .oc-map-feature {\n animation: none;\n }\n\n /* Map borders: fade in near the end of the feature sweep */\n & .oc-map-borders path {\n animation: oc-enter-fade-only calc(var(--oc-animation-duration) * 0.4) ease-in both;\n animation-delay: calc(var(--oc-animation-duration) * 0.7);\n }\n\n /* Map points: fade in after borders with staggered delay.\n Pure opacity fade (no scale transform) to avoid conflicting with\n camera counter-scaling of the r attribute. */\n & .oc-map-point {\n animation: oc-enter-fade-only calc(var(--oc-animation-duration) * 0.4) ease-in both;\n animation-delay: calc(var(--oc-animation-duration) * 0.8 + var(--oc-mark-index, 0) * 15ms);\n }\n\n /* Sankey nodes: fade in with stagger by column depth (left-to-right) */\n & .oc-sankey-node rect {\n animation: oc-enter-fade-only var(--oc-animation-duration)\n var(--oc-animation-ease, var(--oc-ease-smooth)) both;\n animation-delay: calc(var(--oc-animation-stagger) * var(--oc-mark-index, 0));\n }\n\n /* Sankey links: fade in after nodes, with stagger.\n Links delay by 30% of duration so nodes appear first, then links flow in. */\n & .oc-sankey-link path {\n animation: oc-enter-fade-only var(--oc-animation-duration)\n var(--oc-animation-ease, var(--oc-ease-smooth)) both;\n animation-delay: calc(\n var(--oc-animation-duration) *\n 0.3 +\n var(--oc-animation-stagger) *\n var(--oc-mark-index, 0)\n );\n }\n\n /* Barlist rows: fade + slide up per row, bars grow left-to-right */\n & .oc-barlist-row {\n animation: oc-enter-fade calc(var(--oc-animation-duration) * 0.6)\n var(--oc-animation-ease, var(--oc-ease-smooth)) both;\n animation-delay: var(--oc-row-delay, 0ms);\n }\n\n & .oc-barlist-bar {\n animation: oc-enter-bar-h var(--oc-animation-duration)\n var(--oc-animation-ease, var(--oc-ease-smooth)) both;\n animation-delay: var(--oc-row-delay, 0ms);\n }\n }\n\n /* ---------------------------------------------------------------------------\n * Sparkline mode: pair the line/area reveal with a stronger ease-out so it\n * doesn't read as a uniform left-to-right swipe. cubic-bezier(0.16, 1, 0.3, 1)\n * is \"expo-out\" — fast initial draw that decelerates noticeably at the end,\n * giving the trend a hand-drawn feel. Duration is bumped via the engine\n * (compile.ts) so the cleanup timer stays in sync.\n * --------------------------------------------------------------------------- */\n\n .oc-animate[data-display=\"sparkline\"] .oc-mark-line,\n .oc-animate[data-display=\"sparkline\"] .oc-mark-area {\n animation-timing-function: cubic-bezier(0.16, 1, 0.3, 1);\n }\n}\n","/* GENERATED FILE — do not edit. Source: packages/core/src/styles/token-definitions.ts. Regenerate: bun run generate:tokens */\n\n@layer oc.tokens {\n /* ---------------------------------------------------------------------------\n * Dark mode overrides (fallback defaults)\n *\n * At runtime, the JS theme engine stamps dark-adapted --oc-* custom\n * properties on each .oc-root container. These CSS values serve as\n * fallbacks for contexts where JS hasn't mounted yet.\n * --------------------------------------------------------------------------- */\n\n .oc-dark {\n /* Surfaces (zinc-based achromatic ramp) */\n --oc-bg: #09090b;\n --oc-card: #111113;\n --oc-secondary: #27272a;\n\n /* Text levels — see tokens.css for the cross-mode naming rationale */\n --oc-text: #f7f8f8;\n --oc-text-secondary: #d0d6e0;\n --oc-text-muted: #a1a1aa;\n --oc-text-faint: #52525b;\n\n /* Lines */\n --oc-gridline: rgba(255, 255, 255, 0.05);\n --oc-axis: rgba(255, 255, 255, 0.1);\n --oc-border: rgba(255, 255, 255, 0.1);\n\n /* Brand and semantic — accent stays cyan (no darkening on dark bg) */\n --oc-accent: #06b6d4;\n --oc-accent-strong: #06b6d4;\n --oc-positive: #34d399;\n --oc-negative: #fb7185;\n --oc-focus: #60a5fa;\n\n /* Interactive states */\n --oc-hover-bg: rgba(255, 255, 255, 0.05);\n --oc-tooltip-bg: rgba(17, 17, 19, 0.92);\n --oc-tooltip-border: rgba(255, 255, 255, 0.08);\n --oc-tooltip-shadow: 0 2px 8px rgba(0, 0, 0, 0.3), 0 0 1px rgba(0, 0, 0, 0.4);\n --oc-tooltip-text: #f7f8f8;\n --oc-legend-text: #d0d6e0;\n }\n}\n","@layer oc.animation {\n /* ---------------------------------------------------------------------------\n * Animation keyframes\n * --------------------------------------------------------------------------- */\n\n /* Bar entrance: clip-path reveal bottom-to-top + fade in (vertical columns).\n Bars grow upward from baseline with a soft opacity fade. */\n @keyframes oc-enter-bar {\n from {\n clip-path: inset(100% 0 0 0);\n opacity: 0;\n }\n 75% {\n opacity: 1;\n }\n to {\n clip-path: inset(0 0 0 0);\n opacity: 1;\n }\n }\n\n /* Bar entrance: clip-path reveal left-to-right + fade in (horizontal bars).\n Bars grow rightward from axis with a soft opacity fade. */\n @keyframes oc-enter-bar-h {\n from {\n clip-path: inset(0 100% 0 0);\n opacity: 0;\n }\n 75% {\n opacity: 1;\n }\n to {\n clip-path: inset(0 0 0 0);\n opacity: 1;\n }\n }\n\n /* Line/area entrance: clip-path reveal left-to-right + fade in.\n Lines draw in following reading direction with a soft lead-in. */\n @keyframes oc-enter-line {\n from {\n clip-path: inset(0 100% 0 0);\n opacity: 0;\n }\n 15% {\n opacity: 1;\n }\n to {\n clip-path: inset(0 0 0 0);\n opacity: 1;\n }\n }\n\n /* Point/arc entrance: scale up + fade in from center */\n @keyframes oc-enter-point {\n from {\n opacity: 0;\n transform: scale(0.3);\n }\n to {\n opacity: 1;\n transform: scale(1);\n }\n }\n\n /* Map feature entrance: fade in while transitioning fill from a neutral base\n to the data-driven color stored in --oc-feature-fill. */\n @keyframes oc-enter-map-fill {\n from {\n fill: var(--oc-secondary);\n opacity: 0;\n }\n to {\n fill: var(--oc-feature-fill);\n opacity: 1;\n }\n }\n\n /* Pure opacity fade (no transform). Safe for elements with existing transforms\n like arc groups that use translate() for positioning. */\n @keyframes oc-enter-fade-only {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n }\n\n /* Fade + subtle slide up for text, rule, tick, annotations */\n @keyframes oc-enter-fade {\n from {\n opacity: 0;\n transform: translateY(4px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n }\n\n /* Table row entrance: slide up only, no opacity (cells fade independently\n to avoid opacity compounding between row and cell animations) */\n @keyframes oc-table-enter-row {\n from {\n transform: translateY(6px);\n }\n to {\n transform: translateY(0);\n }\n }\n\n /* Table bar fill entrance: clip-path grow only, no opacity\n (preserves resting opacity: 0.15 from table.css) */\n @keyframes oc-table-enter-bar-fill {\n from {\n clip-path: inset(0 100% 0 0);\n }\n to {\n clip-path: inset(0 0 0 0);\n }\n }\n\n /* Tooltip entrance */\n @keyframes oc-tooltip-in {\n from {\n opacity: 0;\n transform: translateY(2px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n }\n}\n","@layer oc.components {\n /* ---------------------------------------------------------------------------\n * Table base\n * --------------------------------------------------------------------------- */\n\n .oc-table-wrapper {\n font-family: var(--oc-font-family);\n color: var(--oc-text);\n background: var(--oc-bg);\n\n & > .oc-chrome {\n margin-bottom: 16px;\n padding-left: 16px;\n padding-right: 16px;\n }\n\n & > .oc-chrome:first-child {\n padding-top: 4px;\n }\n\n & table {\n width: 100%;\n border-collapse: collapse;\n }\n\n & th,\n & td {\n padding: 10px 16px;\n text-align: left;\n border-bottom: 1px solid var(--oc-border);\n }\n\n & th {\n font-weight: 600;\n font-size: 12px;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n color: var(--oc-text-secondary);\n white-space: nowrap;\n }\n\n & thead {\n position: sticky;\n top: 0;\n z-index: 2;\n background: var(--oc-bg);\n }\n\n & thead th {\n border-bottom-width: 2px;\n }\n\n & td {\n font-size: 14px;\n font-variant-numeric: tabular-nums;\n }\n\n & th:focus {\n outline: 2px solid var(--oc-focus);\n outline-offset: -2px;\n }\n\n & tbody:focus {\n outline: none;\n }\n }\n\n .oc-table-title {\n margin-bottom: 4px;\n font-size: var(--oc-title-computed-size, var(--oc-title-size));\n font-weight: var(--oc-title-computed-weight, var(--oc-title-weight));\n color: var(--oc-title-computed-color, var(--oc-text));\n }\n\n .oc-table-subtitle {\n margin-bottom: 8px;\n font-size: var(--oc-subtitle-computed-size, var(--oc-subtitle-size));\n font-weight: var(--oc-subtitle-computed-weight, var(--oc-subtitle-weight));\n color: var(--oc-subtitle-computed-color, var(--oc-text-secondary));\n }\n\n .oc-table-source {\n font-size: var(--oc-source-computed-size, var(--oc-source-size));\n color: var(--oc-source-computed-color, var(--oc-text-muted));\n }\n\n .oc-table-footer-text {\n font-size: var(--oc-footer-computed-size, var(--oc-source-size));\n color: var(--oc-footer-computed-color, var(--oc-text-muted));\n }\n\n .oc-table-scroll {\n overflow-x: auto;\n }\n\n /* ---------------------------------------------------------------------------\n * Sticky first column\n * --------------------------------------------------------------------------- */\n\n .oc-table--sticky {\n & th:first-child,\n & td:first-child {\n position: sticky;\n left: 0;\n z-index: 1;\n background: var(--oc-bg);\n }\n }\n\n /* ---------------------------------------------------------------------------\n * Sort controls\n * --------------------------------------------------------------------------- */\n\n .oc-table-sort-btn {\n background: none;\n border: none;\n cursor: pointer;\n padding: 2px;\n margin-left: 6px;\n display: inline-flex;\n flex-direction: column;\n align-items: center;\n vertical-align: middle;\n gap: 2px;\n\n &::before,\n &::after {\n content: \"\";\n display: block;\n width: 0;\n height: 0;\n border-left: 5px solid transparent;\n border-right: 5px solid transparent;\n transition:\n opacity 0.15s,\n border-color 0.15s;\n }\n\n &::before {\n border-bottom: 4.5px solid var(--oc-text-secondary);\n opacity: 0.45;\n }\n\n &::after {\n border-top: 4.5px solid var(--oc-text-secondary);\n opacity: 0.45;\n }\n\n &:hover::before,\n &:hover::after {\n opacity: 0.75;\n }\n }\n\n th[aria-sort=\"ascending\"] .oc-table-sort-btn {\n &::before {\n opacity: 1;\n border-bottom-color: var(--oc-text);\n }\n\n &::after {\n opacity: 0.15;\n }\n }\n\n th[aria-sort=\"descending\"] .oc-table-sort-btn {\n &::after {\n opacity: 1;\n border-top-color: var(--oc-text);\n }\n\n &::before {\n opacity: 0.15;\n }\n }\n\n /* ---------------------------------------------------------------------------\n * Search\n * --------------------------------------------------------------------------- */\n\n /* Shared search-input skin (table + series-search).\n Padding excluded: it diverges (table: 8px 12px; series: 0 10px 0 28px)\n and series-search.css is imported before table.css — a padding declaration\n here would beat the series-search override by source order. */\n .oc-table-search input,\n .oc-series-search-input {\n width: 100%;\n border: 1px solid var(--oc-border);\n border-radius: 6px;\n font-size: 13px;\n font-family: inherit;\n background: var(--oc-bg);\n color: var(--oc-text);\n box-sizing: border-box;\n transition: border-color 0.15s;\n }\n\n .oc-table-search input::placeholder,\n .oc-series-search-input::placeholder {\n color: var(--oc-text-muted);\n font-size: 13px;\n }\n\n .oc-table-search input:focus,\n .oc-series-search-input:focus {\n outline: none;\n border-color: var(--oc-focus);\n box-shadow: 0 0 0 3px var(--oc-focus-ring);\n }\n\n .oc-table-search {\n padding: 8px 0;\n\n & input {\n padding: 8px 12px;\n }\n }\n\n /* ---------------------------------------------------------------------------\n * Pagination\n * --------------------------------------------------------------------------- */\n\n .oc-table-pagination {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px 0 4px;\n font-size: 13px;\n color: var(--oc-text-secondary);\n\n & button {\n padding: 6px 14px;\n border: 1px solid var(--oc-border);\n border-radius: 6px;\n background: var(--oc-bg);\n color: var(--oc-text);\n cursor: pointer;\n font-size: 13px;\n font-family: inherit;\n transition:\n background 0.15s,\n border-color 0.15s;\n\n &:disabled {\n opacity: 0.35;\n cursor: not-allowed;\n }\n\n &:hover:not(:disabled) {\n background: var(--oc-hover-bg);\n border-color: var(--oc-axis);\n }\n\n &:focus-visible {\n outline: 2px solid var(--oc-focus);\n outline-offset: 1px;\n }\n }\n }\n\n .oc-table-pagination-info {\n font-variant-numeric: tabular-nums;\n }\n\n .oc-table-pagination-btns {\n display: flex;\n gap: 8px;\n }\n\n /* ---------------------------------------------------------------------------\n * Bar cells\n * --------------------------------------------------------------------------- */\n\n .oc-table-bar {\n position: relative;\n }\n\n .oc-table-bar-fill {\n position: absolute;\n top: 6px;\n left: 0;\n bottom: 6px;\n border-radius: 2px;\n opacity: 0.15;\n pointer-events: none;\n }\n\n .oc-table-bar-value {\n position: relative;\n z-index: 1;\n }\n\n /* ---------------------------------------------------------------------------\n * Sparkline cells\n * --------------------------------------------------------------------------- */\n\n .oc-table-sparkline {\n display: block;\n width: 100%;\n position: relative;\n\n & svg {\n display: block;\n width: 100%;\n overflow: visible;\n }\n }\n\n .oc-table-sparkline-dot {\n position: absolute;\n border-radius: 50%;\n width: 5px;\n height: 5px;\n }\n\n .oc-table-sparkline-labels {\n display: flex;\n justify-content: space-between;\n font-size: 11px;\n line-height: 1;\n }\n\n /* ---------------------------------------------------------------------------\n * Image cells\n * --------------------------------------------------------------------------- */\n\n .oc-table-image {\n display: inline-block;\n vertical-align: middle;\n\n & img {\n object-fit: cover;\n }\n }\n\n .oc-table-image-rounded img {\n border-radius: 50%;\n }\n\n /* ---------------------------------------------------------------------------\n * Flag cells\n * --------------------------------------------------------------------------- */\n\n .oc-table-flag {\n font-size: 1.2em;\n }\n\n /* ---------------------------------------------------------------------------\n * Compact mode\n * --------------------------------------------------------------------------- */\n\n .oc-table--compact {\n & th,\n & td {\n padding: 4px 8px;\n font-size: 13px;\n }\n\n & th {\n font-size: 11px;\n }\n }\n\n /* ---------------------------------------------------------------------------\n * Row hover (when onRowClick is set)\n * --------------------------------------------------------------------------- */\n\n .oc-table--clickable tbody {\n & tr {\n cursor: pointer;\n }\n\n & tr:hover {\n background: var(--oc-hover-bg);\n }\n }\n\n /* ---------------------------------------------------------------------------\n * Keyboard cell focus indicator\n * --------------------------------------------------------------------------- */\n\n .oc-table-cell-focus {\n outline: 2px solid var(--oc-focus);\n outline-offset: -2px;\n }\n\n /* ---------------------------------------------------------------------------\n * Empty state\n * --------------------------------------------------------------------------- */\n\n .oc-table-empty {\n padding: 32px 16px;\n text-align: center;\n color: var(--oc-text-secondary);\n font-size: 14px;\n font-style: italic;\n }\n}\n","/* ---------------------------------------------------------------------------\n * Reduced motion\n *\n * Catch-all: last-declared layer beats every earlier layer regardless of\n * specificity. No !important, no hand-maintained selector mirror.\n *\n * Selector list matches CSS_TOKEN_ROOT_SELECTORS in token-definitions.ts.\n * --------------------------------------------------------------------------- */\n\n@layer oc.reduced-motion {\n @media (prefers-reduced-motion: reduce) {\n :is(\n .oc-root,\n .oc-chart-root,\n .oc-table-wrapper,\n .oc-table-root,\n .oc-graph-wrapper,\n .oc-graph-root,\n .oc-sankey-root,\n .oc-tilemap-root,\n .oc-barlist-root,\n .oc-map-root\n ),\n :is(\n .oc-root,\n .oc-chart-root,\n .oc-table-wrapper,\n .oc-table-root,\n .oc-graph-wrapper,\n .oc-graph-root,\n .oc-sankey-root,\n .oc-tilemap-root,\n .oc-barlist-root,\n .oc-map-root\n )\n *,\n :is(\n .oc-root,\n .oc-chart-root,\n .oc-table-wrapper,\n .oc-table-root,\n .oc-graph-wrapper,\n .oc-graph-root,\n .oc-sankey-root,\n .oc-tilemap-root,\n .oc-barlist-root,\n .oc-map-root\n )\n *::before,\n :is(\n .oc-root,\n .oc-chart-root,\n .oc-table-wrapper,\n .oc-table-root,\n .oc-graph-wrapper,\n .oc-graph-root,\n .oc-sankey-root,\n .oc-tilemap-root,\n .oc-barlist-root,\n .oc-map-root\n )\n *::after {\n animation: none;\n transition: none;\n }\n }\n}\n","@layer oc.base {\n /* ---------------------------------------------------------------------------\n * Wrapper roots\n * --------------------------------------------------------------------------- */\n\n .oc-chart-root {\n width: 100%;\n height: 100%;\n }\n\n .oc-table-root,\n .oc-graph-root,\n .oc-sankey-root,\n .oc-barlist-root,\n .oc-tilemap-root,\n .oc-map-root {\n width: 100%;\n height: 100%;\n }\n\n .oc-table-root {\n overflow: auto;\n }\n\n /* ---------------------------------------------------------------------------\n * Chart container\n * --------------------------------------------------------------------------- */\n\n .oc-chart {\n font-family: var(--oc-font-family);\n display: block;\n width: 100%;\n }\n\n /* ---------------------------------------------------------------------------\n * BarList SVG container\n * --------------------------------------------------------------------------- */\n\n .oc-tilemap,\n .oc-map {\n display: block;\n width: 100%;\n height: auto;\n }\n\n .oc-map-feature {\n transition: opacity 400ms ease;\n }\n\n .oc-barlist {\n display: block;\n width: 100%;\n }\n\n /* ---------------------------------------------------------------------------\n * Screen reader only utility\n * --------------------------------------------------------------------------- */\n\n .oc-sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip-path: inset(50%);\n white-space: nowrap;\n border-width: 0;\n }\n\n /* ---------------------------------------------------------------------------\n * Editable hover feedback\n * --------------------------------------------------------------------------- */\n\n .oc-editable-hover {\n outline: 1.5px solid var(--oc-editable-hover);\n outline-offset: 2px;\n border-radius: 2px;\n }\n\n /* ---------------------------------------------------------------------------\n * Keyboard focus indicators\n *\n * --oc-focus carries a light value in tokens.css and a dark value in\n * dark.css, so both rings stay visible in either mode.\n * --------------------------------------------------------------------------- */\n\n /* Container ring when the chart itself receives keyboard focus. */\n .oc-root:focus-visible {\n outline: 2px solid var(--oc-focus);\n outline-offset: 2px;\n }\n\n /* Mark ring during arrow-key navigation (see wireKeyboardNav). Outline on\n * SVG elements draws around the mark's bounding box, same technique as\n * .oc-editable-hover above. */\n .oc-mark-focused {\n outline: 2px solid var(--oc-focus);\n outline-offset: 1px;\n border-radius: 2px;\n }\n}\n","@layer oc.animation {\n /* ---------------------------------------------------------------------------\n * Table entrance animations (.oc-table-wrapper.oc-animate)\n * --------------------------------------------------------------------------- */\n\n .oc-table-wrapper.oc-animate {\n /* Chrome (title/subtitle): fade + slide up */\n & > .oc-chrome {\n animation: oc-enter-fade calc(var(--oc-animation-duration) * 0.6)\n var(--oc-animation-ease, var(--oc-ease-smooth)) both;\n }\n\n /* Table header: quick fade before rows start */\n & thead {\n animation: oc-enter-fade-only calc(var(--oc-animation-duration) * 0.4)\n var(--oc-animation-ease, var(--oc-ease-smooth)) both;\n }\n\n /* Row entrance: slide up only, no opacity (cells handle their own fading\n to avoid opacity compounding between row and cell animations) */\n & tbody tr {\n animation: oc-table-enter-row var(--oc-animation-duration)\n var(--oc-animation-ease, var(--oc-ease-smooth)) both;\n animation-delay: calc(var(--oc-animation-stagger) * var(--oc-row-index, 0));\n }\n\n /* Cell text: fade in synced with row slide */\n & tbody td {\n animation: oc-enter-fade-only calc(var(--oc-animation-duration) * 0.5)\n var(--oc-animation-ease, var(--oc-ease-smooth)) both;\n animation-delay: calc(var(--oc-animation-stagger) * var(--oc-row-index, 0));\n }\n\n /* Heatmap/category cell backgrounds: longer fade, delayed after row appears */\n & td.oc-table-heatmap,\n & td.oc-table-category {\n animation: oc-enter-fade-only calc(var(--oc-animation-duration) * 0.7)\n var(--oc-animation-ease, var(--oc-ease-smooth)) both;\n animation-delay: calc(\n var(--oc-animation-stagger) *\n var(--oc-row-index, 0) +\n var(--oc-animation-duration) *\n 0.3\n );\n }\n\n /* Bar fill: clip-path grow only (no opacity change to preserve resting\n opacity: 0.15 from table.css) */\n & .oc-table-bar-fill {\n animation: oc-table-enter-bar-fill calc(var(--oc-animation-duration) * 0.8)\n var(--oc-animation-ease, var(--oc-ease-smooth)) both;\n animation-delay: calc(\n var(--oc-animation-stagger) *\n var(--oc-row-index, 0) +\n var(--oc-animation-duration) *\n 0.3\n );\n }\n\n /* Sparkline SVG: clip-path reveal left-to-right. Targets the SVG directly\n (not the wrapper) to avoid clipping absolutely-positioned dots and labels. */\n & .oc-table-sparkline > svg {\n animation: oc-enter-line calc(var(--oc-animation-duration) * 0.8)\n var(--oc-animation-ease, var(--oc-ease-smooth)) both;\n animation-delay: calc(\n var(--oc-animation-stagger) *\n var(--oc-row-index, 0) +\n var(--oc-animation-duration) *\n 0.4\n );\n }\n\n /* Sparkline dots and labels: fade in after the line draws through */\n & .oc-table-sparkline-dot,\n & .oc-table-sparkline-labels {\n animation: oc-enter-fade-only calc(var(--oc-animation-duration) * 0.3)\n var(--oc-animation-ease, var(--oc-ease-smooth)) both;\n animation-delay: calc(\n var(--oc-animation-stagger) *\n var(--oc-row-index, 0) +\n var(--oc-animation-duration) *\n 0.8\n );\n }\n\n /* Search and pagination: quick fade on mount */\n & .oc-table-search,\n & .oc-table-pagination {\n animation: oc-enter-fade-only calc(var(--oc-animation-duration) * 0.5)\n var(--oc-animation-ease, var(--oc-ease-smooth)) both;\n }\n }\n}\n","@layer oc.components {\n /* ---------------------------------------------------------------------------\n * Chrome (eyebrow, title, subtitle, source, byline, footer, brand)\n * --------------------------------------------------------------------------- */\n\n .oc-chrome {\n font-family: var(--oc-font-family);\n }\n\n .oc-eyebrow {\n font-size: var(--oc-eyebrow-size);\n font-weight: var(--oc-eyebrow-weight);\n letter-spacing: var(--oc-eyebrow-tracking);\n text-transform: uppercase;\n fill: var(--oc-accent);\n }\n\n .oc-title {\n font-size: var(--oc-title-size);\n font-weight: var(--oc-title-weight);\n letter-spacing: var(--oc-title-tracking);\n fill: var(--oc-text);\n }\n\n .oc-subtitle {\n font-size: var(--oc-subtitle-size);\n font-weight: var(--oc-subtitle-weight);\n fill: var(--oc-text-muted);\n }\n\n .oc-source,\n .oc-byline,\n .oc-footer {\n font-size: var(--oc-source-size);\n font-weight: var(--oc-source-weight);\n fill: var(--oc-text-muted);\n }\n\n .oc-brand {\n font-size: 11px;\n font-weight: 510;\n letter-spacing: 0.02em;\n fill: var(--oc-text-faint);\n }\n\n .oc-brand-dot {\n fill: var(--oc-accent);\n }\n\n .oc-eyebrow-dot {\n fill: var(--oc-accent);\n }\n\n /* ---------------------------------------------------------------------------\n * Metric bar (.oc-metrics) — optional row of label/value cells above chart\n * --------------------------------------------------------------------------- */\n\n .oc-metrics {\n font-family: var(--oc-font-family);\n }\n\n .oc-metric-label {\n font-size: 10px;\n font-weight: 510;\n letter-spacing: 0.08em;\n text-transform: uppercase;\n fill: var(--oc-text-muted);\n }\n\n .oc-metric-value {\n font-size: 22px;\n font-weight: 510;\n letter-spacing: -0.01em;\n fill: var(--oc-text);\n font-variant-numeric: tabular-nums;\n }\n\n .oc-metric-delta-up {\n fill: var(--oc-positive);\n font-size: 12px;\n font-weight: 510;\n }\n\n .oc-metric-delta-down {\n fill: var(--oc-negative);\n font-size: 12px;\n font-weight: 510;\n }\n\n .oc-metric-secondary {\n fill: var(--oc-positive);\n font-size: 12px;\n font-weight: 400;\n }\n\n /* ---------------------------------------------------------------------------\n * Axis tick labels — inline variant sits above each gridline at the\n * chart-area left edge (no left gutter). Used by line/area y-axes.\n * --------------------------------------------------------------------------- */\n\n .oc-axis-tick-inline {\n font-size: 11px;\n font-weight: 400;\n fill: var(--oc-text-muted);\n }\n\n /* ---------------------------------------------------------------------------\n * Endpoint labels (right-side per-series column for line/area charts)\n *\n * Swatch idiom: a thicker colored stroke segment with an optional thinner\n * lighter strip below. Mirrors the refreshed traditional legend swatch so a\n * single chart never shows two swatch idioms (mock-2 alignment). Per-series\n * color is stamped inline by the renderer; CSS tokens here cover the muted\n * value text and the leader line so theme overrides flow through naturally.\n * --------------------------------------------------------------------------- */\n\n .oc-endpoint-labels {\n font-family: var(--oc-font-family);\n }\n\n .oc-endpoint-label {\n /* Color set inline per series; this fallback only kicks in if the renderer\n ever omits the inline fill. */\n fill: var(--oc-endpoint-label-color, var(--oc-text));\n }\n\n .oc-endpoint-value {\n fill: var(--oc-endpoint-value-color, var(--oc-text-muted));\n }\n\n .oc-endpoint-leader {\n stroke: var(--oc-endpoint-leader-color, currentColor);\n }\n\n /* .oc-endpoint-marker — fill/stroke set inline (open-ring style: bg fill, series stroke). */\n /* .oc-endpoint-swatch — color set inline per series. */\n\n /* ---------------------------------------------------------------------------\n * Annotation dot + subtitle (text-annotation extensions)\n * --------------------------------------------------------------------------- */\n\n /* .oc-annotation-dot — fill/stroke resolved by the engine (open-ring default = bg fill, series stroke). */\n\n .oc-annotation-subtitle {\n fill: var(--oc-annotation-subtitle-color, var(--oc-text-muted));\n }\n\n /* ---------------------------------------------------------------------------\n * Table footer chrome\n * --------------------------------------------------------------------------- */\n\n /* Footer row: source/footer text on the left, brand watermark on the right,\n * sharing a single baseline. gap keeps them apart if the row gets narrow. */\n .oc-table-footer-row {\n display: flex;\n align-items: baseline;\n gap: 16px;\n padding: 16px 16px 4px;\n }\n\n /* Chrome block sits inside the flex row now, so it no longer owns the\n * footer's top padding or horizontal inset (the row provides both). */\n .oc-chrome-footer {\n padding-top: 0;\n }\n\n /* Brand watermark: pushed to the right edge (margin-left:auto holds it there\n * even when the source text is absent), never shrinks below its own text. */\n .oc-table-footer-row .oc-table-ref {\n margin-left: auto;\n flex-shrink: 0;\n text-align: right;\n }\n}\n","@layer oc.components {\n /* ---------------------------------------------------------------------------\n * Legend\n * --------------------------------------------------------------------------- */\n\n .oc-legend {\n font-family: var(--oc-font-family);\n font-size: var(--oc-body-size);\n }\n\n .oc-legend-entry {\n cursor: default;\n }\n\n .oc-legend text {\n fill: var(--oc-legend-text);\n }\n}\n","@layer oc.components {\n /* ---------------------------------------------------------------------------\n * Tooltip\n * Editorial card matching the new design system: zinc surface, cyan accent,\n * Inter Variable, mono numerics. Sized for a slice tooltip that lists every\n * series at the snapped x.\n * --------------------------------------------------------------------------- */\n\n .oc-tooltip {\n position: absolute;\n display: none;\n pointer-events: none;\n z-index: 1000;\n background: var(--oc-tooltip-bg);\n backdrop-filter: blur(14px);\n border: 1px solid var(--oc-tooltip-border);\n border-radius: var(--oc-border-radius, 2px);\n box-shadow: var(--oc-tooltip-shadow);\n color: var(--oc-tooltip-text);\n font-family: var(--oc-font-family);\n font-size: 12px;\n padding: 0;\n max-width: 280px;\n min-width: 160px;\n line-height: 1.4;\n animation: oc-tooltip-in 120ms ease-out;\n transition:\n left 100ms ease-in-out,\n top 100ms ease-in-out;\n\n & .oc-tooltip-header {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px 6px;\n }\n\n & .oc-tooltip-dot {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n flex-shrink: 0;\n }\n\n & .oc-tooltip-title {\n font-weight: 590;\n font-size: 11px;\n letter-spacing: 0.04em;\n text-transform: uppercase;\n color: var(--oc-text-muted);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n & .oc-tooltip-body {\n padding: 6px 12px 10px;\n border-top: 1px solid var(--oc-tooltip-border);\n }\n\n /* No separator when body is the only child */\n & .oc-tooltip-body:first-child {\n border-top: none;\n padding-top: 10px;\n }\n\n & .oc-tooltip-row {\n display: flex;\n align-items: baseline;\n justify-content: space-between;\n gap: 16px;\n padding: 2px 0;\n }\n\n & .oc-tooltip-row-swatch {\n display: inline-block;\n width: 8px;\n height: 8px;\n border-radius: 50%;\n margin-right: 6px;\n flex-shrink: 0;\n transform: translateY(-1px);\n }\n\n & .oc-tooltip-label {\n color: var(--oc-text-secondary);\n font-size: 12px;\n font-weight: 400;\n white-space: nowrap;\n flex-shrink: 0;\n display: inline-flex;\n align-items: center;\n }\n\n & .oc-tooltip-value {\n font-weight: 510;\n font-size: 12px;\n font-variant-numeric: tabular-nums;\n color: var(--oc-tooltip-text);\n text-align: right;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n }\n\n /* ---------------------------------------------------------------------------\n * Crosshair guideline + per-series snap dots (line/area charts)\n * Animate the snap between adjacent points so the indicator slides instead\n * of jumping. ~50ms ease-in-out keeps the motion crisp without lagging.\n * --------------------------------------------------------------------------- */\n\n .oc-crosshair {\n pointer-events: none;\n transition:\n x1 50ms ease-in-out,\n x2 50ms ease-in-out;\n }\n\n .oc-snap-dots circle {\n pointer-events: none;\n transition:\n cx 50ms ease-in-out,\n cy 50ms ease-in-out;\n }\n}\n","@layer oc.components {\n /* ---------------------------------------------------------------------------\n * Series search (seriesSearch)\n *\n * DOM combobox overlaid on the SVG band the engine reserves below chrome.\n * The wrapper is absolutely positioned by the vanilla adapter (inline\n * left/top/width/height), so everything here is visual only. All colors come\n * from --oc-* tokens, which flip in .oc-dark.\n * --------------------------------------------------------------------------- */\n\n .oc-series-search {\n position: absolute;\n display: flex;\n align-items: center;\n justify-content: flex-end;\n gap: 8px;\n font-family: var(--oc-font-family);\n z-index: 10;\n }\n\n /* Chips: removable filter tokens for the current selection. They flow to the\n * left of the input and scroll horizontally rather than wrapping over the\n * chart when a reader picks many series. */\n .oc-series-search-chips {\n display: flex;\n align-items: center;\n gap: 6px;\n min-width: 0;\n overflow-x: auto;\n scrollbar-width: none;\n }\n\n .oc-series-search-chips::-webkit-scrollbar {\n display: none;\n }\n\n .oc-series-search-chip {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 3px 4px 3px 10px;\n border: 1px solid var(--oc-border);\n border-radius: 999px;\n background: var(--oc-secondary);\n color: var(--oc-text-secondary);\n font-size: 12px;\n font-weight: 500;\n line-height: 16px;\n white-space: nowrap;\n }\n\n .oc-series-search-chip-remove {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n /* 16px glyph, but a >=24px hit area (WCAG 2.5.5 target size) via padding\n pulled back with negative margin so the chip layout stays tight. */\n width: 16px;\n height: 16px;\n padding: 4px;\n margin: -4px -2px -4px -4px;\n border: none;\n border-radius: 50%;\n background: transparent;\n color: var(--oc-text-muted);\n cursor: pointer;\n transition:\n color 0.15s,\n background-color 0.15s;\n }\n\n .oc-series-search-chip-remove:hover {\n color: var(--oc-text);\n background: var(--oc-hover-bg);\n }\n\n .oc-series-search-chip-remove:focus-visible {\n outline: 2px solid var(--oc-focus);\n outline-offset: 1px;\n }\n\n .oc-series-search-chip-remove svg {\n display: block;\n }\n\n /* Combobox: input + popup listbox. Styling matches the table search input\n * (border, radius, focus ring) so the two search surfaces read as one system. */\n .oc-series-search-box {\n position: relative;\n flex: 0 1 220px;\n min-width: 120px;\n }\n\n .oc-series-search-icon {\n position: absolute;\n left: 9px;\n top: 50%;\n transform: translateY(-50%);\n color: var(--oc-text-muted);\n pointer-events: none;\n }\n\n /* Shared skin provided by the grouped rule in table.css.\n Only divergent props live here. */\n .oc-series-search-input {\n height: 32px;\n padding: 0 10px 0 28px;\n }\n\n .oc-series-search-listbox {\n position: absolute;\n top: calc(100% + 4px);\n right: 0;\n min-width: 100%;\n max-height: 240px;\n overflow-y: auto;\n margin: 0;\n padding: 4px;\n list-style: none;\n border: 1px solid var(--oc-border);\n border-radius: 8px;\n background: var(--oc-card);\n box-shadow: var(--oc-tooltip-shadow);\n z-index: 20;\n }\n\n .oc-series-search-option {\n padding: 6px 10px;\n border-radius: 4px;\n font-size: 13px;\n color: var(--oc-text);\n cursor: pointer;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n .oc-series-search-option[aria-selected=\"true\"],\n .oc-series-search-option:hover {\n background: var(--oc-hover-bg);\n }\n\n /* The typed substring within each suggestion. */\n .oc-series-search-match {\n font-weight: 600;\n }\n\n .oc-series-search-empty {\n padding: 6px 10px;\n font-size: 12px;\n color: var(--oc-text-muted);\n }\n}\n","@layer oc.components {\n /* ---------------------------------------------------------------------------\n * Graph\n * --------------------------------------------------------------------------- */\n\n .oc-graph-wrapper {\n position: relative;\n overflow: hidden;\n background: var(--oc-bg);\n font-family: var(--oc-font-family);\n width: 100%;\n height: 100%;\n }\n\n .oc-graph-canvas {\n display: block;\n width: 100%;\n height: 100%;\n cursor: grab;\n }\n\n .oc-graph-canvas--dragging {\n cursor: grabbing;\n }\n\n .oc-graph-chrome {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n z-index: 2;\n padding: 16px 16px 8px;\n pointer-events: none;\n\n & .oc-title {\n font-size: var(--oc-title-size);\n font-weight: var(--oc-title-weight);\n letter-spacing: var(--oc-title-tracking);\n color: var(--oc-text);\n margin: 0 0 4px;\n --_stroke: color-mix(in srgb, var(--oc-bg) 80%, transparent);\n text-shadow:\n -2px -2px 0 var(--_stroke),\n 2px -2px 0 var(--_stroke),\n -2px 2px 0 var(--_stroke),\n 2px 2px 0 var(--_stroke),\n 0 -2px 0 var(--_stroke),\n 0 2px 0 var(--_stroke),\n -2px 0 0 var(--_stroke),\n 2px 0 0 var(--_stroke);\n }\n\n & .oc-subtitle {\n font-size: var(--oc-subtitle-size);\n color: var(--oc-text-secondary);\n margin: 0;\n --_stroke: color-mix(in srgb, var(--oc-bg) 80%, transparent);\n text-shadow:\n -1px -1px 0 var(--_stroke),\n 1px -1px 0 var(--_stroke),\n -1px 1px 0 var(--_stroke),\n 1px 1px 0 var(--_stroke);\n }\n }\n\n .oc-graph-legend {\n position: absolute;\n top: 8px;\n right: 8px;\n background: var(--oc-bg);\n border: 1px solid var(--oc-border);\n border-radius: var(--oc-border-radius);\n padding: 8px 12px;\n font-size: 12px;\n color: var(--oc-text-secondary);\n max-height: 200px;\n overflow-y: auto;\n }\n\n .oc-graph-legend-item {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 2px 0;\n }\n\n .oc-graph-legend-swatch {\n width: 10px;\n height: 10px;\n border-radius: 50%;\n flex-shrink: 0;\n }\n\n .oc-graph-search {\n position: absolute;\n top: 8px;\n left: 8px;\n\n & input {\n font-family: var(--oc-font-family);\n font-size: var(--oc-body-size);\n padding: 6px 10px;\n border: 1px solid var(--oc-border);\n border-radius: var(--oc-border-radius);\n background: var(--oc-bg);\n color: var(--oc-text);\n outline: none;\n\n &:focus {\n border-color: var(--oc-focus);\n box-shadow: 0 0 0 2px var(--oc-focus-ring-strong);\n }\n }\n }\n\n /* Dark mode graph overrides (darker bg for canvas-based rendering) */\n .oc-dark .oc-graph-wrapper,\n .oc-graph-wrapper.oc-dark {\n /* GitHub-dark canvas background, intentionally not a token */\n --oc-bg: #0d1117;\n }\n\n /*\n * graph-mount.ts stamps .oc-dark on both .oc-graph-wrapper and\n * .oc-graph-container simultaneously, so the self-variant\n * (.oc-dark.oc-graph-wrapper) and descendant variant\n * (.oc-dark .oc-graph-legend) resolve identically.\n */\n .oc-dark .oc-graph-legend,\n .oc-dark.oc-graph-wrapper .oc-graph-legend,\n .oc-dark .oc-graph-search input {\n background: rgba(13, 17, 23, 0.85);\n border-color: var(--oc-border);\n }\n}\n"],"names":[]}
|
|
1
|
+
{"version":3,"mappings":"AAWA,iBGEE,62DCFA,4lBJAF,eQNE,mIAeA,6BAQA,qEAUA,yDAOA,uCAIA,qCASA,gJAgBA,qGAcA,4EAQA,yFRrFF,qBENE,6CAIA,2KAQA,wIAOA,+GAMA,+HAQA,wFAOA,oDAYA,8CAIA,wHAQA,4HAQA,2EAMA,6EAMA,4EAWA,8EAgBA,sDAIA,sEAMA,4EAIA,wEAaA,sFAUA,sFASA,gCAMA,mFKhKA,ogBAsBE,4FAOA,iFAOA,gMAWA,iGAMA,0EAKA,mHAQA,yJAUA,oKAUA,uMAkBF,qFAOA,4FDlHA,2EAKA,gCAIA,2CIJA,kJAaA,iHASA,wDAIA,sRAeA,6RAoBA,uFAKA,iGAKA,gDAMA,qEAMA,oIAWA,0DAKA,2RAiBA,yKAWA,0GAMA,wCAIA,mFTtIA,kDAKA,+CAKA,qGASA,wHAUA,yGAWA,qFAKA,0MAYA,oRAeA,6DAOA,mXAoBA,0DAIA,yFAKA,yDIpHA,iGAKE,qFAMA,yDAIA,4DAKA,gGAAA,gGAOA,oJASA,gFAOA,mDAIA,sEAKA,iFAKA,2CAKF,sNAOA,kPAOA,2IAKA,gJAKA,iCASE,0FAAA,0FAaF,oLAYE,mLAAA,kLAaA,yFAKA,qFAKA,4CAAA,2CAOA,+FAKA,6DAMA,4FAKA,+DAaF,iPAaA,wFAAA,8EAAA,yFAAA,+EAMA,+IAOA,+BAGE,wCASF,oJAQE,6OAaE,oEAKA,2GAKA,+FAOJ,4DAIA,+CASA,gCAIA,iHAUA,gDASA,+DAKE,kEAOF,iFAOA,mGAWA,2DAIE,qCAKF,8CAQA,+BASE,qDAAA,qDAMA,qCAUA,6CAIA,kEASF,2EASA,oHQjYA,qIASA,kEAOA,2CAIA,4GASE,8bAkBA,2RAaF,qPAcA,4EAOA,+EAOA,oDAKE,0OAUE,2GAQJ,qEAYA,iKFtHA,oEXCF,oBSJI,4JAMA,4JAOA,8NAOA,yOAOA,wRAAA,yRAcA,4RAaA,uRAYA,4RAAA,+RAaA,uKAAA,2KK/EF,8GAgBA,kHAgBA,iHAeA,4FAgBA,8IAaA,iGAaA,yDAUA,sGAaA,uFAWA,yFAUA,sGFpIE,yLAAA,wLAOA,qFAAA,oFASA,oRAYA,8MAOA,8MASA,kNAUA,qOAAA,sOAQA,+JAAA,+JAWA,8NAOA,8NAOA,8NAOA,iMAWA,sKAOA,wJAQA,gLASA,8JAKA,+EAKA,2KAQA,2OAOA,0NAQA,8PAYA,uLAMA,6KAeF,wJZhMF,yBeDE,uCACE,6LAAA,+LAAA,qMAAA","sources":["../src/styles/index.css","../src/styles/you-draw-it.css","../src/styles/tokens.css","../src/styles/chrome.css","../src/styles/dark.css","../src/styles/table.css","../src/styles/legend.css","../src/styles/tooltip.css","../src/styles/base.css","../src/styles/table-animation.css","../src/styles/series-search.css","../src/styles/sparkline.css","../src/styles/keyframes.css","../src/styles/graph.css","../src/styles/reduced-motion.css","../src/styles/animation.css"],"sourcesContent":["/**\n * @opendata-ai/openchart-core styles\n *\n * CSS with oc- prefix for all class names.\n * CSS custom properties for theme overrides.\n * Dark mode via .oc-dark class on the container.\n * Cascade layers: oc.tokens, oc.base, oc.components, oc.animation, oc.reduced-motion.\n */\n\n/* For optimal typography, load Inter: https://fonts.google.com/specimen/Inter */\n\n@layer oc.tokens, oc.base, oc.components, oc.animation, oc.reduced-motion;\n\n@import \"./tokens.css\";\n@import \"./dark.css\";\n@import \"./base.css\";\n@import \"./chrome.css\";\n@import \"./tooltip.css\";\n@import \"./legend.css\";\n@import \"./series-search.css\";\n@import \"./you-draw-it.css\";\n@import \"./table.css\";\n@import \"./table-animation.css\";\n@import \"./graph.css\";\n@import \"./sparkline.css\";\n@import \"./keyframes.css\";\n@import \"./animation.css\";\n@import \"./reduced-motion.css\";\n","@layer oc.components {\n /* ---------------------------------------------------------------------------\n * You draw it (youDrawIt)\n *\n * NYT-style draw-then-reveal. SVG-space elements (hatched region, guess path,\n * reveal clip) render inside the chart SVG; the prompt + skip-to-reveal button\n * are an absolutely-positioned HTML overlay the vanilla adapter sizes over the\n * drawing region (inline left/top/width/height). All colors come from --oc-*\n * tokens so they flip in .oc-dark.\n * --------------------------------------------------------------------------- */\n\n /* Hatched \"draw here\" region. Fill comes from an SVG <pattern> (line color =\n * the target series color); this only governs overall opacity + fade-out. */\n .oc-ydi-region {\n opacity: 0.35;\n transition: opacity 0.4s ease;\n }\n\n .oc-ydi-region[data-ydi-hidden=\"true\"] {\n opacity: 0;\n }\n\n /* The vertical rule at `from` where drawing begins. */\n .oc-ydi-boundary {\n stroke: var(--oc-text-muted);\n stroke-width: 1;\n stroke-dasharray: 3 3;\n stroke-opacity: 0.6;\n }\n\n /* Reader's guess: a distinct pen-like stroke that reads as \"yours\" against the\n * solid real line. Dashed + focus-blue so it stays legible in both modes. */\n .oc-ydi-guess {\n stroke: var(--oc-focus);\n stroke-width: 2.5;\n stroke-linecap: round;\n stroke-linejoin: round;\n stroke-dasharray: 1 6;\n }\n\n /* Host-supplied comparison line (\"what everyone else guessed\"). Muted so it\n * sits behind the reader's guess and the real line. */\n .oc-ydi-comparison {\n stroke: var(--oc-text-muted);\n stroke-width: 1.5;\n stroke-opacity: 0.5;\n stroke-dasharray: 4 4;\n }\n\n /* Reveal clip rect: the width animates from the `from` boundary to the full\n * area on reveal, wiping the real line in left-to-right. The vanilla adapter\n * adds .oc-ydi-clip-animate right before setting the final width; reduced\n * motion skips the class so the width snaps. */\n .oc-ydi-clip-rect.oc-ydi-clip-animate {\n transition: width 0.7s cubic-bezier(0.22, 1, 0.36, 1);\n }\n\n /* HTML controls overlay: prompt (top) + reveal button (bottom-right). */\n .oc-ydi-controls {\n display: flex;\n flex-direction: column;\n justify-content: space-between;\n align-items: flex-end;\n pointer-events: none;\n font-family: var(--oc-font-family);\n padding: 8px;\n box-sizing: border-box;\n z-index: 10;\n }\n\n .oc-ydi-prompt {\n align-self: center;\n max-width: 100%;\n padding: 6px 12px;\n border-radius: 6px;\n background: var(--oc-card);\n border: 1px solid var(--oc-border);\n color: var(--oc-text-secondary);\n font-size: 13px;\n font-weight: 500;\n line-height: 16px;\n text-align: center;\n box-shadow: var(--oc-tooltip-shadow);\n }\n\n .oc-ydi-controls.oc-ydi-revealed .oc-ydi-prompt {\n display: none;\n }\n\n /* Skip-to-reveal button. pointer-events re-enabled (the overlay disables it)\n * so it stays clickable and keyboard-reachable. Min height enforced inline by\n * the adapter (>= 24px effective touch target). */\n .oc-ydi-reveal-button {\n pointer-events: auto;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n padding: 6px 14px;\n border: 1px solid var(--oc-border);\n border-radius: 6px;\n background: var(--oc-bg);\n color: var(--oc-text);\n font-family: inherit;\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n box-shadow: var(--oc-tooltip-shadow);\n transition:\n background-color 0.15s,\n border-color 0.15s;\n }\n\n .oc-ydi-reveal-button:hover {\n background: var(--oc-hover-bg);\n }\n\n .oc-ydi-reveal-button:focus-visible {\n outline: 2px solid var(--oc-focus);\n outline-offset: 2px;\n }\n\n .oc-ydi-reveal-button:disabled {\n opacity: 0.5;\n cursor: default;\n }\n}\n","/* GENERATED FILE — do not edit. Source: packages/core/src/styles/token-definitions.ts. Regenerate: bun run generate:tokens */\n\n@layer oc.tokens {\n /* ---------------------------------------------------------------------------\n * Custom properties (light mode defaults)\n *\n * These are FALLBACK defaults. At runtime, the JS theme engine stamps the\n * resolved theme as inline --oc-* custom properties on each .oc-root\n * container (see packages/vanilla/src/theme-tokens.ts). These CSS values\n * serve as fallbacks for contexts where JS hasn't mounted yet (SSR, static\n * HTML examples).\n * --------------------------------------------------------------------------- */\n\n .oc-root,\n .oc-chart-root,\n .oc-table-wrapper,\n .oc-table-root,\n .oc-graph-wrapper,\n .oc-graph-root,\n .oc-sankey-root,\n .oc-tilemap-root,\n .oc-barlist-root,\n .oc-map-root {\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n\n /* Opt out of iOS text auto-inflation so measured widths match rendered text. */\n -webkit-text-size-adjust: 100%;\n text-size-adjust: 100%;\n\n --oc-font-family:\n \"Inter Variable\", Inter, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n --oc-font-mono: \"JetBrains Mono\", \"Fira Code\", \"Cascadia Code\", monospace;\n\n /* Animation easing presets via CSS linear() */\n --oc-ease-smooth: linear(\n 0,\n 0.157,\n 0.438,\n 0.64,\n 0.766,\n 0.85,\n 0.906,\n 0.941,\n 0.964,\n 0.978,\n 0.988,\n 0.994,\n 0.998,\n 1\n );\n --oc-ease-snappy: linear(\n 0,\n 0.012,\n 0.048,\n 0.108,\n 0.194,\n 0.302,\n 0.426,\n 0.559,\n 0.69,\n 0.808,\n 0.905,\n 0.973,\n 1.013,\n 1.028,\n 1.023,\n 1.006,\n 0.984,\n 0.966,\n 0.957,\n 0.957,\n 0.964,\n 0.975,\n 0.986,\n 0.995,\n 1,\n 1.003,\n 1.002,\n 1,\n 0.998,\n 0.998,\n 0.999,\n 1\n );\n\n /* Animation timing defaults */\n --oc-animation-duration: 500ms;\n --oc-animation-stagger: 80ms;\n --oc-annotation-delay: 200ms;\n\n /* Typography scale (editorial design system) */\n --oc-title-size: 26px;\n --oc-title-weight: 590;\n --oc-title-tracking: -0.022em;\n --oc-subtitle-size: 14px;\n --oc-subtitle-weight: 450;\n --oc-source-size: 11px;\n --oc-source-weight: 450;\n --oc-body-size: 13px;\n --oc-eyebrow-size: 11px;\n --oc-eyebrow-weight: 550;\n --oc-eyebrow-tracking: 0.08em;\n\n /* Surfaces (light mode defaults) */\n --oc-bg: #ffffff;\n --oc-card: #ffffff;\n --oc-secondary: #f4f4f5; /* zinc-100, raised surface */\n\n /*\n * Text levels. Names invert across modes: in light mode \"muted\" sits at\n * a lighter zinc step than \"subtle\" because both are picked relative to\n * the active background, not from a fixed lightness ladder. The intent\n * is \"muted = first step away from primary text\"; \"subtle = next step\n * down\"; etc.\n *\n * Light mode: text=zinc-950, secondary=zinc-700, muted=zinc-500,\n * subtle=zinc-400, faint=zinc-300\n * Dark mode (dark.css): inverts the surface tokens but keeps the same\n * muted -> subtle -> faint progression away from primary.\n */\n --oc-text: #09090b;\n --oc-text-secondary: #3f3f46;\n --oc-text-muted: #71717a;\n --oc-text-faint: #d4d4d8;\n\n /* Lines */\n --oc-gridline: rgba(0, 0, 0, 0.1);\n --oc-axis: rgba(0, 0, 0, 0.1);\n --oc-border: rgba(0, 0, 0, 0.08);\n --oc-border-radius: 2px;\n\n /* Brand and semantic */\n --oc-accent: #06b6d4;\n --oc-accent-strong: #0891b2; /* darker cyan for line strokes on light bg */\n --oc-positive: #10b981;\n --oc-negative: #e11d48;\n --oc-focus: #3b82f6;\n /* static, intentionally NOT derived from --oc-focus and NOT flipped in dark mode */\n --oc-focus-ring: rgba(59, 130, 246, 0.1);\n --oc-focus-ring-strong: rgba(59, 130, 246, 0.25);\n --oc-editable-hover: rgba(79, 70, 229, 0.35); /* edit-mode hover outline, indigo one-off */\n\n /* Spacing scale (4px base) — only --oc-space-2/4 are consumed (JS-stamped) */\n --oc-space-2: 8px;\n --oc-space-4: 16px;\n\n /* Interactive states */\n --oc-hover-bg: rgba(0, 0, 0, 0.025);\n --oc-tooltip-bg: rgba(255, 255, 255, 0.88);\n --oc-tooltip-border: rgba(0, 0, 0, 0.08);\n --oc-tooltip-shadow: 0 2px 8px rgba(0, 0, 0, 0.08), 0 0 1px rgba(0, 0, 0, 0.12);\n --oc-tooltip-text: #09090b;\n --oc-legend-text: #3f3f46;\n }\n}\n","@layer oc.components {\n /* ---------------------------------------------------------------------------\n * Chrome (eyebrow, title, subtitle, source, byline, footer, brand)\n * --------------------------------------------------------------------------- */\n\n .oc-chrome {\n font-family: var(--oc-font-family);\n }\n\n .oc-eyebrow {\n font-size: var(--oc-eyebrow-size);\n font-weight: var(--oc-eyebrow-weight);\n letter-spacing: var(--oc-eyebrow-tracking);\n text-transform: uppercase;\n fill: var(--oc-accent);\n }\n\n .oc-title {\n font-size: var(--oc-title-size);\n font-weight: var(--oc-title-weight);\n letter-spacing: var(--oc-title-tracking);\n fill: var(--oc-text);\n }\n\n .oc-subtitle {\n font-size: var(--oc-subtitle-size);\n font-weight: var(--oc-subtitle-weight);\n fill: var(--oc-text-muted);\n }\n\n .oc-source,\n .oc-byline,\n .oc-footer {\n font-size: var(--oc-source-size);\n font-weight: var(--oc-source-weight);\n fill: var(--oc-text-muted);\n }\n\n .oc-brand {\n font-size: 11px;\n font-weight: 510;\n letter-spacing: 0.02em;\n fill: var(--oc-text-faint);\n }\n\n .oc-brand-dot {\n fill: var(--oc-accent);\n }\n\n .oc-eyebrow-dot {\n fill: var(--oc-accent);\n }\n\n /* ---------------------------------------------------------------------------\n * Metric bar (.oc-metrics) — optional row of label/value cells above chart\n * --------------------------------------------------------------------------- */\n\n .oc-metrics {\n font-family: var(--oc-font-family);\n }\n\n .oc-metric-label {\n font-size: 10px;\n font-weight: 510;\n letter-spacing: 0.08em;\n text-transform: uppercase;\n fill: var(--oc-text-muted);\n }\n\n .oc-metric-value {\n font-size: 22px;\n font-weight: 510;\n letter-spacing: -0.01em;\n fill: var(--oc-text);\n font-variant-numeric: tabular-nums;\n }\n\n .oc-metric-delta-up {\n fill: var(--oc-positive);\n font-size: 12px;\n font-weight: 510;\n }\n\n .oc-metric-delta-down {\n fill: var(--oc-negative);\n font-size: 12px;\n font-weight: 510;\n }\n\n .oc-metric-secondary {\n fill: var(--oc-positive);\n font-size: 12px;\n font-weight: 400;\n }\n\n /* ---------------------------------------------------------------------------\n * Axis tick labels — inline variant sits above each gridline at the\n * chart-area left edge (no left gutter). Used by line/area y-axes.\n * --------------------------------------------------------------------------- */\n\n .oc-axis-tick-inline {\n font-size: 11px;\n font-weight: 400;\n fill: var(--oc-text-muted);\n }\n\n /* ---------------------------------------------------------------------------\n * Endpoint labels (right-side per-series column for line/area charts)\n *\n * Swatch idiom: a thicker colored stroke segment with an optional thinner\n * lighter strip below. Mirrors the refreshed traditional legend swatch so a\n * single chart never shows two swatch idioms (mock-2 alignment). Per-series\n * color is stamped inline by the renderer; CSS tokens here cover the muted\n * value text and the leader line so theme overrides flow through naturally.\n * --------------------------------------------------------------------------- */\n\n .oc-endpoint-labels {\n font-family: var(--oc-font-family);\n }\n\n .oc-endpoint-label {\n /* Color set inline per series; this fallback only kicks in if the renderer\n ever omits the inline fill. */\n fill: var(--oc-endpoint-label-color, var(--oc-text));\n }\n\n .oc-endpoint-value {\n fill: var(--oc-endpoint-value-color, var(--oc-text-muted));\n }\n\n .oc-endpoint-leader {\n stroke: var(--oc-endpoint-leader-color, currentColor);\n }\n\n /* .oc-endpoint-marker — fill/stroke set inline (open-ring style: bg fill, series stroke). */\n /* .oc-endpoint-swatch — color set inline per series. */\n\n /* ---------------------------------------------------------------------------\n * Annotation dot + subtitle (text-annotation extensions)\n * --------------------------------------------------------------------------- */\n\n /* .oc-annotation-dot — fill/stroke resolved by the engine (open-ring default = bg fill, series stroke). */\n\n .oc-annotation-subtitle {\n fill: var(--oc-annotation-subtitle-color, var(--oc-text-muted));\n }\n\n /* ---------------------------------------------------------------------------\n * Table footer chrome\n * --------------------------------------------------------------------------- */\n\n /* Footer row: source/footer text on the left, brand watermark on the right,\n * sharing a single baseline. gap keeps them apart if the row gets narrow. */\n .oc-table-footer-row {\n display: flex;\n align-items: baseline;\n gap: 16px;\n padding: 16px 16px 4px;\n }\n\n /* Chrome block sits inside the flex row now, so it no longer owns the\n * footer's top padding or horizontal inset (the row provides both). */\n .oc-chrome-footer {\n padding-top: 0;\n }\n\n /* Brand watermark: pushed to the right edge (margin-left:auto holds it there\n * even when the source text is absent), never shrinks below its own text. */\n .oc-table-footer-row .oc-table-ref {\n margin-left: auto;\n flex-shrink: 0;\n text-align: right;\n }\n}\n","/* GENERATED FILE — do not edit. Source: packages/core/src/styles/token-definitions.ts. Regenerate: bun run generate:tokens */\n\n@layer oc.tokens {\n /* ---------------------------------------------------------------------------\n * Dark mode overrides (fallback defaults)\n *\n * At runtime, the JS theme engine stamps dark-adapted --oc-* custom\n * properties on each .oc-root container. These CSS values serve as\n * fallbacks for contexts where JS hasn't mounted yet.\n * --------------------------------------------------------------------------- */\n\n .oc-dark {\n /* Surfaces (zinc-based achromatic ramp) */\n --oc-bg: #09090b;\n --oc-card: #111113;\n --oc-secondary: #27272a;\n\n /* Text levels — see tokens.css for the cross-mode naming rationale */\n --oc-text: #f7f8f8;\n --oc-text-secondary: #d0d6e0;\n --oc-text-muted: #a1a1aa;\n --oc-text-faint: #52525b;\n\n /* Lines */\n --oc-gridline: rgba(255, 255, 255, 0.05);\n --oc-axis: rgba(255, 255, 255, 0.1);\n --oc-border: rgba(255, 255, 255, 0.1);\n\n /* Brand and semantic — accent stays cyan (no darkening on dark bg) */\n --oc-accent: #06b6d4;\n --oc-accent-strong: #06b6d4;\n --oc-positive: #34d399;\n --oc-negative: #fb7185;\n --oc-focus: #60a5fa;\n\n /* Interactive states */\n --oc-hover-bg: rgba(255, 255, 255, 0.05);\n --oc-tooltip-bg: rgba(17, 17, 19, 0.92);\n --oc-tooltip-border: rgba(255, 255, 255, 0.08);\n --oc-tooltip-shadow: 0 2px 8px rgba(0, 0, 0, 0.3), 0 0 1px rgba(0, 0, 0, 0.4);\n --oc-tooltip-text: #f7f8f8;\n --oc-legend-text: #d0d6e0;\n }\n}\n","@layer oc.components {\n /* ---------------------------------------------------------------------------\n * Table base\n * --------------------------------------------------------------------------- */\n\n .oc-table-wrapper {\n font-family: var(--oc-font-family);\n color: var(--oc-text);\n background: var(--oc-bg);\n\n & > .oc-chrome {\n margin-bottom: 16px;\n padding-left: 16px;\n padding-right: 16px;\n }\n\n & > .oc-chrome:first-child {\n padding-top: 4px;\n }\n\n & table {\n width: 100%;\n border-collapse: collapse;\n }\n\n & th,\n & td {\n padding: 10px 16px;\n text-align: left;\n border-bottom: 1px solid var(--oc-border);\n }\n\n & th {\n font-weight: 600;\n font-size: 12px;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n color: var(--oc-text-secondary);\n white-space: nowrap;\n }\n\n & thead {\n position: sticky;\n top: 0;\n z-index: 2;\n background: var(--oc-bg);\n }\n\n & thead th {\n border-bottom-width: 2px;\n }\n\n & td {\n font-size: 14px;\n font-variant-numeric: tabular-nums;\n }\n\n & th:focus {\n outline: 2px solid var(--oc-focus);\n outline-offset: -2px;\n }\n\n & tbody:focus {\n outline: none;\n }\n }\n\n .oc-table-title {\n margin-bottom: 4px;\n font-size: var(--oc-title-computed-size, var(--oc-title-size));\n font-weight: var(--oc-title-computed-weight, var(--oc-title-weight));\n color: var(--oc-title-computed-color, var(--oc-text));\n }\n\n .oc-table-subtitle {\n margin-bottom: 8px;\n font-size: var(--oc-subtitle-computed-size, var(--oc-subtitle-size));\n font-weight: var(--oc-subtitle-computed-weight, var(--oc-subtitle-weight));\n color: var(--oc-subtitle-computed-color, var(--oc-text-secondary));\n }\n\n .oc-table-source {\n font-size: var(--oc-source-computed-size, var(--oc-source-size));\n color: var(--oc-source-computed-color, var(--oc-text-muted));\n }\n\n .oc-table-footer-text {\n font-size: var(--oc-footer-computed-size, var(--oc-source-size));\n color: var(--oc-footer-computed-color, var(--oc-text-muted));\n }\n\n .oc-table-scroll {\n overflow-x: auto;\n }\n\n /* ---------------------------------------------------------------------------\n * Sticky first column\n * --------------------------------------------------------------------------- */\n\n .oc-table--sticky {\n & th:first-child,\n & td:first-child {\n position: sticky;\n left: 0;\n z-index: 1;\n background: var(--oc-bg);\n }\n }\n\n /* ---------------------------------------------------------------------------\n * Sort controls\n * --------------------------------------------------------------------------- */\n\n .oc-table-sort-btn {\n background: none;\n border: none;\n cursor: pointer;\n padding: 2px;\n margin-left: 6px;\n display: inline-flex;\n flex-direction: column;\n align-items: center;\n vertical-align: middle;\n gap: 2px;\n\n &::before,\n &::after {\n content: \"\";\n display: block;\n width: 0;\n height: 0;\n border-left: 5px solid transparent;\n border-right: 5px solid transparent;\n transition:\n opacity 0.15s,\n border-color 0.15s;\n }\n\n &::before {\n border-bottom: 4.5px solid var(--oc-text-secondary);\n opacity: 0.45;\n }\n\n &::after {\n border-top: 4.5px solid var(--oc-text-secondary);\n opacity: 0.45;\n }\n\n &:hover::before,\n &:hover::after {\n opacity: 0.75;\n }\n }\n\n th[aria-sort=\"ascending\"] .oc-table-sort-btn {\n &::before {\n opacity: 1;\n border-bottom-color: var(--oc-text);\n }\n\n &::after {\n opacity: 0.15;\n }\n }\n\n th[aria-sort=\"descending\"] .oc-table-sort-btn {\n &::after {\n opacity: 1;\n border-top-color: var(--oc-text);\n }\n\n &::before {\n opacity: 0.15;\n }\n }\n\n /* ---------------------------------------------------------------------------\n * Search\n * --------------------------------------------------------------------------- */\n\n /* Shared search-input skin (table + series-search).\n Padding excluded: it diverges (table: 8px 12px; series: 0 10px 0 28px)\n and series-search.css is imported before table.css — a padding declaration\n here would beat the series-search override by source order. */\n .oc-table-search input,\n .oc-series-search-input {\n width: 100%;\n border: 1px solid var(--oc-border);\n border-radius: 6px;\n font-size: 13px;\n font-family: inherit;\n background: var(--oc-bg);\n color: var(--oc-text);\n box-sizing: border-box;\n transition: border-color 0.15s;\n }\n\n .oc-table-search input::placeholder,\n .oc-series-search-input::placeholder {\n color: var(--oc-text-muted);\n font-size: 13px;\n }\n\n .oc-table-search input:focus,\n .oc-series-search-input:focus {\n outline: none;\n border-color: var(--oc-focus);\n box-shadow: 0 0 0 3px var(--oc-focus-ring);\n }\n\n .oc-table-search {\n padding: 8px 0;\n\n & input {\n padding: 8px 12px;\n }\n }\n\n /* ---------------------------------------------------------------------------\n * Pagination\n * --------------------------------------------------------------------------- */\n\n .oc-table-pagination {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px 0 4px;\n font-size: 13px;\n color: var(--oc-text-secondary);\n\n & button {\n padding: 6px 14px;\n border: 1px solid var(--oc-border);\n border-radius: 6px;\n background: var(--oc-bg);\n color: var(--oc-text);\n cursor: pointer;\n font-size: 13px;\n font-family: inherit;\n transition:\n background 0.15s,\n border-color 0.15s;\n\n &:disabled {\n opacity: 0.35;\n cursor: not-allowed;\n }\n\n &:hover:not(:disabled) {\n background: var(--oc-hover-bg);\n border-color: var(--oc-axis);\n }\n\n &:focus-visible {\n outline: 2px solid var(--oc-focus);\n outline-offset: 1px;\n }\n }\n }\n\n .oc-table-pagination-info {\n font-variant-numeric: tabular-nums;\n }\n\n .oc-table-pagination-btns {\n display: flex;\n gap: 8px;\n }\n\n /* ---------------------------------------------------------------------------\n * Bar cells\n * --------------------------------------------------------------------------- */\n\n .oc-table-bar {\n position: relative;\n }\n\n .oc-table-bar-fill {\n position: absolute;\n top: 6px;\n left: 0;\n bottom: 6px;\n border-radius: 2px;\n opacity: 0.15;\n pointer-events: none;\n }\n\n .oc-table-bar-value {\n position: relative;\n z-index: 1;\n }\n\n /* ---------------------------------------------------------------------------\n * Sparkline cells\n * --------------------------------------------------------------------------- */\n\n .oc-table-sparkline {\n display: block;\n width: 100%;\n position: relative;\n\n & svg {\n display: block;\n width: 100%;\n overflow: visible;\n }\n }\n\n .oc-table-sparkline-dot {\n position: absolute;\n border-radius: 50%;\n width: 5px;\n height: 5px;\n }\n\n .oc-table-sparkline-labels {\n display: flex;\n justify-content: space-between;\n font-size: 11px;\n line-height: 1;\n }\n\n /* ---------------------------------------------------------------------------\n * Image cells\n * --------------------------------------------------------------------------- */\n\n .oc-table-image {\n display: inline-block;\n vertical-align: middle;\n\n & img {\n object-fit: cover;\n }\n }\n\n .oc-table-image-rounded img {\n border-radius: 50%;\n }\n\n /* ---------------------------------------------------------------------------\n * Flag cells\n * --------------------------------------------------------------------------- */\n\n .oc-table-flag {\n font-size: 1.2em;\n }\n\n /* ---------------------------------------------------------------------------\n * Compact mode\n * --------------------------------------------------------------------------- */\n\n .oc-table--compact {\n & th,\n & td {\n padding: 4px 8px;\n font-size: 13px;\n }\n\n & th {\n font-size: 11px;\n }\n }\n\n /* ---------------------------------------------------------------------------\n * Row hover (when onRowClick is set)\n * --------------------------------------------------------------------------- */\n\n .oc-table--clickable tbody {\n & tr {\n cursor: pointer;\n }\n\n & tr:hover {\n background: var(--oc-hover-bg);\n }\n }\n\n /* ---------------------------------------------------------------------------\n * Keyboard cell focus indicator\n * --------------------------------------------------------------------------- */\n\n .oc-table-cell-focus {\n outline: 2px solid var(--oc-focus);\n outline-offset: -2px;\n }\n\n /* ---------------------------------------------------------------------------\n * Empty state\n * --------------------------------------------------------------------------- */\n\n .oc-table-empty {\n padding: 32px 16px;\n text-align: center;\n color: var(--oc-text-secondary);\n font-size: 14px;\n font-style: italic;\n }\n}\n","@layer oc.components {\n /* ---------------------------------------------------------------------------\n * Legend\n * --------------------------------------------------------------------------- */\n\n .oc-legend {\n font-family: var(--oc-font-family);\n font-size: var(--oc-body-size);\n }\n\n .oc-legend-entry {\n cursor: default;\n }\n\n .oc-legend text {\n fill: var(--oc-legend-text);\n }\n}\n","@layer oc.components {\n /* ---------------------------------------------------------------------------\n * Tooltip\n * Editorial card matching the new design system: zinc surface, cyan accent,\n * Inter Variable, mono numerics. Sized for a slice tooltip that lists every\n * series at the snapped x.\n * --------------------------------------------------------------------------- */\n\n .oc-tooltip {\n position: absolute;\n display: none;\n pointer-events: none;\n z-index: 1000;\n background: var(--oc-tooltip-bg);\n backdrop-filter: blur(14px);\n border: 1px solid var(--oc-tooltip-border);\n border-radius: var(--oc-border-radius, 2px);\n box-shadow: var(--oc-tooltip-shadow);\n color: var(--oc-tooltip-text);\n font-family: var(--oc-font-family);\n font-size: 12px;\n padding: 0;\n max-width: 280px;\n min-width: 160px;\n line-height: 1.4;\n animation: oc-tooltip-in 120ms ease-out;\n transition:\n left 100ms ease-in-out,\n top 100ms ease-in-out;\n\n & .oc-tooltip-header {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px 6px;\n }\n\n & .oc-tooltip-dot {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n flex-shrink: 0;\n }\n\n & .oc-tooltip-title {\n font-weight: 590;\n font-size: 11px;\n letter-spacing: 0.04em;\n text-transform: uppercase;\n color: var(--oc-text-muted);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n & .oc-tooltip-body {\n padding: 6px 12px 10px;\n border-top: 1px solid var(--oc-tooltip-border);\n }\n\n /* No separator when body is the only child */\n & .oc-tooltip-body:first-child {\n border-top: none;\n padding-top: 10px;\n }\n\n & .oc-tooltip-row {\n display: flex;\n align-items: baseline;\n justify-content: space-between;\n gap: 16px;\n padding: 2px 0;\n }\n\n & .oc-tooltip-row-swatch {\n display: inline-block;\n width: 8px;\n height: 8px;\n border-radius: 50%;\n margin-right: 6px;\n flex-shrink: 0;\n transform: translateY(-1px);\n }\n\n & .oc-tooltip-label {\n color: var(--oc-text-secondary);\n font-size: 12px;\n font-weight: 400;\n white-space: nowrap;\n flex-shrink: 0;\n display: inline-flex;\n align-items: center;\n }\n\n & .oc-tooltip-value {\n font-weight: 510;\n font-size: 12px;\n font-variant-numeric: tabular-nums;\n color: var(--oc-tooltip-text);\n text-align: right;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n }\n\n /* ---------------------------------------------------------------------------\n * Crosshair guideline + per-series snap dots (line/area charts)\n * Animate the snap between adjacent points so the indicator slides instead\n * of jumping. ~50ms ease-in-out keeps the motion crisp without lagging.\n * --------------------------------------------------------------------------- */\n\n .oc-crosshair {\n pointer-events: none;\n transition:\n x1 50ms ease-in-out,\n x2 50ms ease-in-out;\n }\n\n .oc-snap-dots circle {\n pointer-events: none;\n transition:\n cx 50ms ease-in-out,\n cy 50ms ease-in-out;\n }\n}\n","@layer oc.base {\n /* ---------------------------------------------------------------------------\n * Wrapper roots\n * --------------------------------------------------------------------------- */\n\n .oc-chart-root {\n width: 100%;\n height: 100%;\n }\n\n .oc-table-root,\n .oc-graph-root,\n .oc-sankey-root,\n .oc-barlist-root,\n .oc-tilemap-root,\n .oc-map-root {\n width: 100%;\n height: 100%;\n }\n\n .oc-table-root {\n overflow: auto;\n }\n\n /* ---------------------------------------------------------------------------\n * Chart container\n * --------------------------------------------------------------------------- */\n\n .oc-chart {\n font-family: var(--oc-font-family);\n display: block;\n width: 100%;\n }\n\n /* ---------------------------------------------------------------------------\n * BarList SVG container\n * --------------------------------------------------------------------------- */\n\n .oc-tilemap,\n .oc-map {\n display: block;\n width: 100%;\n height: auto;\n }\n\n .oc-map-feature {\n transition: opacity 400ms ease;\n }\n\n .oc-barlist {\n display: block;\n width: 100%;\n }\n\n /* ---------------------------------------------------------------------------\n * Screen reader only utility\n * --------------------------------------------------------------------------- */\n\n .oc-sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip-path: inset(50%);\n white-space: nowrap;\n border-width: 0;\n }\n\n /* ---------------------------------------------------------------------------\n * Editable hover feedback\n * --------------------------------------------------------------------------- */\n\n .oc-editable-hover {\n outline: 1.5px solid var(--oc-editable-hover);\n outline-offset: 2px;\n border-radius: 2px;\n }\n\n /* ---------------------------------------------------------------------------\n * Keyboard focus indicators\n *\n * --oc-focus carries a light value in tokens.css and a dark value in\n * dark.css, so both rings stay visible in either mode.\n * --------------------------------------------------------------------------- */\n\n /* Container ring when the chart itself receives keyboard focus. */\n .oc-root:focus-visible {\n outline: 2px solid var(--oc-focus);\n outline-offset: 2px;\n }\n\n /* Mark ring during arrow-key navigation (see wireKeyboardNav). Outline on\n * SVG elements draws around the mark's bounding box, same technique as\n * .oc-editable-hover above. */\n .oc-mark-focused {\n outline: 2px solid var(--oc-focus);\n outline-offset: 1px;\n border-radius: 2px;\n }\n}\n","@layer oc.animation {\n /* ---------------------------------------------------------------------------\n * Table entrance animations (.oc-table-wrapper.oc-animate)\n * --------------------------------------------------------------------------- */\n\n .oc-table-wrapper.oc-animate {\n /* Chrome (title/subtitle): fade + slide up */\n & > .oc-chrome {\n animation: oc-enter-fade calc(var(--oc-animation-duration) * 0.6)\n var(--oc-animation-ease, var(--oc-ease-smooth)) both;\n }\n\n /* Table header: quick fade before rows start */\n & thead {\n animation: oc-enter-fade-only calc(var(--oc-animation-duration) * 0.4)\n var(--oc-animation-ease, var(--oc-ease-smooth)) both;\n }\n\n /* Row entrance: slide up only, no opacity (cells handle their own fading\n to avoid opacity compounding between row and cell animations) */\n & tbody tr {\n animation: oc-table-enter-row var(--oc-animation-duration)\n var(--oc-animation-ease, var(--oc-ease-smooth)) both;\n animation-delay: calc(var(--oc-animation-stagger) * var(--oc-row-index, 0));\n }\n\n /* Cell text: fade in synced with row slide */\n & tbody td {\n animation: oc-enter-fade-only calc(var(--oc-animation-duration) * 0.5)\n var(--oc-animation-ease, var(--oc-ease-smooth)) both;\n animation-delay: calc(var(--oc-animation-stagger) * var(--oc-row-index, 0));\n }\n\n /* Heatmap/category cell backgrounds: longer fade, delayed after row appears */\n & td.oc-table-heatmap,\n & td.oc-table-category {\n animation: oc-enter-fade-only calc(var(--oc-animation-duration) * 0.7)\n var(--oc-animation-ease, var(--oc-ease-smooth)) both;\n animation-delay: calc(\n var(--oc-animation-stagger) *\n var(--oc-row-index, 0) +\n var(--oc-animation-duration) *\n 0.3\n );\n }\n\n /* Bar fill: clip-path grow only (no opacity change to preserve resting\n opacity: 0.15 from table.css) */\n & .oc-table-bar-fill {\n animation: oc-table-enter-bar-fill calc(var(--oc-animation-duration) * 0.8)\n var(--oc-animation-ease, var(--oc-ease-smooth)) both;\n animation-delay: calc(\n var(--oc-animation-stagger) *\n var(--oc-row-index, 0) +\n var(--oc-animation-duration) *\n 0.3\n );\n }\n\n /* Sparkline SVG: clip-path reveal left-to-right. Targets the SVG directly\n (not the wrapper) to avoid clipping absolutely-positioned dots and labels. */\n & .oc-table-sparkline > svg {\n animation: oc-enter-line calc(var(--oc-animation-duration) * 0.8)\n var(--oc-animation-ease, var(--oc-ease-smooth)) both;\n animation-delay: calc(\n var(--oc-animation-stagger) *\n var(--oc-row-index, 0) +\n var(--oc-animation-duration) *\n 0.4\n );\n }\n\n /* Sparkline dots and labels: fade in after the line draws through */\n & .oc-table-sparkline-dot,\n & .oc-table-sparkline-labels {\n animation: oc-enter-fade-only calc(var(--oc-animation-duration) * 0.3)\n var(--oc-animation-ease, var(--oc-ease-smooth)) both;\n animation-delay: calc(\n var(--oc-animation-stagger) *\n var(--oc-row-index, 0) +\n var(--oc-animation-duration) *\n 0.8\n );\n }\n\n /* Search and pagination: quick fade on mount */\n & .oc-table-search,\n & .oc-table-pagination {\n animation: oc-enter-fade-only calc(var(--oc-animation-duration) * 0.5)\n var(--oc-animation-ease, var(--oc-ease-smooth)) both;\n }\n }\n}\n","@layer oc.components {\n /* ---------------------------------------------------------------------------\n * Series search (seriesSearch)\n *\n * DOM combobox overlaid on the SVG band the engine reserves below chrome.\n * The wrapper is absolutely positioned by the vanilla adapter (inline\n * left/top/width/height), so everything here is visual only. All colors come\n * from --oc-* tokens, which flip in .oc-dark.\n * --------------------------------------------------------------------------- */\n\n .oc-series-search {\n position: absolute;\n display: flex;\n align-items: center;\n justify-content: flex-end;\n gap: 8px;\n font-family: var(--oc-font-family);\n z-index: 10;\n }\n\n /* Chips: removable filter tokens for the current selection. They flow to the\n * left of the input and scroll horizontally rather than wrapping over the\n * chart when a reader picks many series. */\n .oc-series-search-chips {\n display: flex;\n align-items: center;\n gap: 6px;\n min-width: 0;\n overflow-x: auto;\n scrollbar-width: none;\n }\n\n .oc-series-search-chips::-webkit-scrollbar {\n display: none;\n }\n\n .oc-series-search-chip {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 3px 4px 3px 10px;\n border: 1px solid var(--oc-border);\n border-radius: 999px;\n background: var(--oc-secondary);\n color: var(--oc-text-secondary);\n font-size: 12px;\n font-weight: 500;\n line-height: 16px;\n white-space: nowrap;\n }\n\n .oc-series-search-chip-remove {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n /* 16px glyph, but a >=24px hit area (WCAG 2.5.5 target size) via padding\n pulled back with negative margin so the chip layout stays tight. */\n width: 16px;\n height: 16px;\n padding: 4px;\n margin: -4px -2px -4px -4px;\n border: none;\n border-radius: 50%;\n background: transparent;\n color: var(--oc-text-muted);\n cursor: pointer;\n transition:\n color 0.15s,\n background-color 0.15s;\n }\n\n .oc-series-search-chip-remove:hover {\n color: var(--oc-text);\n background: var(--oc-hover-bg);\n }\n\n .oc-series-search-chip-remove:focus-visible {\n outline: 2px solid var(--oc-focus);\n outline-offset: 1px;\n }\n\n .oc-series-search-chip-remove svg {\n display: block;\n }\n\n /* Combobox: input + popup listbox. Styling matches the table search input\n * (border, radius, focus ring) so the two search surfaces read as one system. */\n .oc-series-search-box {\n position: relative;\n flex: 0 1 220px;\n min-width: 120px;\n }\n\n .oc-series-search-icon {\n position: absolute;\n left: 9px;\n top: 50%;\n transform: translateY(-50%);\n color: var(--oc-text-muted);\n pointer-events: none;\n }\n\n /* Shared skin provided by the grouped rule in table.css.\n Only divergent props live here. */\n .oc-series-search-input {\n height: 32px;\n padding: 0 10px 0 28px;\n }\n\n .oc-series-search-listbox {\n position: absolute;\n top: calc(100% + 4px);\n right: 0;\n min-width: 100%;\n max-height: 240px;\n overflow-y: auto;\n margin: 0;\n padding: 4px;\n list-style: none;\n border: 1px solid var(--oc-border);\n border-radius: 8px;\n background: var(--oc-card);\n box-shadow: var(--oc-tooltip-shadow);\n z-index: 20;\n }\n\n .oc-series-search-option {\n padding: 6px 10px;\n border-radius: 4px;\n font-size: 13px;\n color: var(--oc-text);\n cursor: pointer;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n .oc-series-search-option[aria-selected=\"true\"],\n .oc-series-search-option:hover {\n background: var(--oc-hover-bg);\n }\n\n /* The typed substring within each suggestion. */\n .oc-series-search-match {\n font-weight: 600;\n }\n\n .oc-series-search-empty {\n padding: 6px 10px;\n font-size: 12px;\n color: var(--oc-text-muted);\n }\n}\n","@layer oc.components {\n /**\n * Sparkline display mode.\n *\n * Stamped on the SVG root as data-display=\"sparkline\" by the renderer when\n * the spec sets display: 'sparkline'. Strips any inherited padding/margin\n * so the mark renders truly edge-to-edge in tight container layouts (KPI\n * cards, table cells, dashboard tiles).\n */\n\n .oc-chart[data-display=\"sparkline\"] {\n display: block;\n margin: 0;\n padding: 0;\n }\n}\n","@layer oc.animation {\n /* ---------------------------------------------------------------------------\n * Animation keyframes\n * --------------------------------------------------------------------------- */\n\n /* Bar entrance: clip-path reveal bottom-to-top + fade in (vertical columns).\n Bars grow upward from baseline with a soft opacity fade. */\n @keyframes oc-enter-bar {\n from {\n clip-path: inset(100% 0 0 0);\n opacity: 0;\n }\n 75% {\n opacity: 1;\n }\n to {\n clip-path: inset(0 0 0 0);\n opacity: 1;\n }\n }\n\n /* Bar entrance: clip-path reveal left-to-right + fade in (horizontal bars).\n Bars grow rightward from axis with a soft opacity fade. */\n @keyframes oc-enter-bar-h {\n from {\n clip-path: inset(0 100% 0 0);\n opacity: 0;\n }\n 75% {\n opacity: 1;\n }\n to {\n clip-path: inset(0 0 0 0);\n opacity: 1;\n }\n }\n\n /* Line/area entrance: clip-path reveal left-to-right + fade in.\n Lines draw in following reading direction with a soft lead-in. */\n @keyframes oc-enter-line {\n from {\n clip-path: inset(0 100% 0 0);\n opacity: 0;\n }\n 15% {\n opacity: 1;\n }\n to {\n clip-path: inset(0 0 0 0);\n opacity: 1;\n }\n }\n\n /* Point/arc entrance: scale up + fade in from center */\n @keyframes oc-enter-point {\n from {\n opacity: 0;\n transform: scale(0.3);\n }\n to {\n opacity: 1;\n transform: scale(1);\n }\n }\n\n /* Map feature entrance: fade in while transitioning fill from a neutral base\n to the data-driven color stored in --oc-feature-fill. The target opacity is\n --oc-feature-target-opacity (default 1) so features under a focus dim\n animate straight to their dimmed rest opacity instead of hitting 1 and then\n snapping down when the dim is applied post-animation. */\n @keyframes oc-enter-map-fill {\n from {\n fill: var(--oc-secondary);\n opacity: 0;\n }\n to {\n fill: var(--oc-feature-fill);\n opacity: var(--oc-feature-target-opacity, 1);\n }\n }\n\n /* Map point pop-in: gentle scale from 0.75 + fade. Uses transform-origin to\n scale from the circle's own center (cx/cy) rather than the SVG origin. */\n @keyframes oc-enter-map-point {\n from {\n opacity: 0;\n transform: scale(0.75);\n }\n to {\n opacity: 1;\n transform: scale(1);\n }\n }\n\n /* Pure opacity fade (no transform). Safe for elements with existing transforms\n like arc groups that use translate() for positioning. */\n @keyframes oc-enter-fade-only {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n }\n\n /* Fade + subtle slide up for text, rule, tick, annotations */\n @keyframes oc-enter-fade {\n from {\n opacity: 0;\n transform: translateY(4px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n }\n\n /* Table row entrance: slide up only, no opacity (cells fade independently\n to avoid opacity compounding between row and cell animations) */\n @keyframes oc-table-enter-row {\n from {\n transform: translateY(6px);\n }\n to {\n transform: translateY(0);\n }\n }\n\n /* Table bar fill entrance: clip-path grow only, no opacity\n (preserves resting opacity: 0.15 from table.css) */\n @keyframes oc-table-enter-bar-fill {\n from {\n clip-path: inset(0 100% 0 0);\n }\n to {\n clip-path: inset(0 0 0 0);\n }\n }\n\n /* Tooltip entrance */\n @keyframes oc-tooltip-in {\n from {\n opacity: 0;\n transform: translateY(2px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n }\n}\n","@layer oc.components {\n /* ---------------------------------------------------------------------------\n * Graph\n * --------------------------------------------------------------------------- */\n\n .oc-graph-wrapper {\n position: relative;\n overflow: hidden;\n background: var(--oc-bg);\n font-family: var(--oc-font-family);\n width: 100%;\n height: 100%;\n }\n\n .oc-graph-canvas {\n display: block;\n width: 100%;\n height: 100%;\n cursor: grab;\n }\n\n .oc-graph-canvas--dragging {\n cursor: grabbing;\n }\n\n .oc-graph-chrome {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n z-index: 2;\n padding: 16px 16px 8px;\n pointer-events: none;\n\n & .oc-title {\n font-size: var(--oc-title-size);\n font-weight: var(--oc-title-weight);\n letter-spacing: var(--oc-title-tracking);\n color: var(--oc-text);\n margin: 0 0 4px;\n --_stroke: color-mix(in srgb, var(--oc-bg) 80%, transparent);\n text-shadow:\n -2px -2px 0 var(--_stroke),\n 2px -2px 0 var(--_stroke),\n -2px 2px 0 var(--_stroke),\n 2px 2px 0 var(--_stroke),\n 0 -2px 0 var(--_stroke),\n 0 2px 0 var(--_stroke),\n -2px 0 0 var(--_stroke),\n 2px 0 0 var(--_stroke);\n }\n\n & .oc-subtitle {\n font-size: var(--oc-subtitle-size);\n color: var(--oc-text-secondary);\n margin: 0;\n --_stroke: color-mix(in srgb, var(--oc-bg) 80%, transparent);\n text-shadow:\n -1px -1px 0 var(--_stroke),\n 1px -1px 0 var(--_stroke),\n -1px 1px 0 var(--_stroke),\n 1px 1px 0 var(--_stroke);\n }\n }\n\n .oc-graph-legend {\n position: absolute;\n top: 8px;\n right: 8px;\n background: var(--oc-bg);\n border: 1px solid var(--oc-border);\n border-radius: var(--oc-border-radius);\n padding: 8px 12px;\n font-size: 12px;\n color: var(--oc-text-secondary);\n max-height: 200px;\n overflow-y: auto;\n }\n\n .oc-graph-legend-item {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 2px 0;\n }\n\n .oc-graph-legend-swatch {\n width: 10px;\n height: 10px;\n border-radius: 50%;\n flex-shrink: 0;\n }\n\n .oc-graph-search {\n position: absolute;\n top: 8px;\n left: 8px;\n\n & input {\n font-family: var(--oc-font-family);\n font-size: var(--oc-body-size);\n padding: 6px 10px;\n border: 1px solid var(--oc-border);\n border-radius: var(--oc-border-radius);\n background: var(--oc-bg);\n color: var(--oc-text);\n outline: none;\n\n &:focus {\n border-color: var(--oc-focus);\n box-shadow: 0 0 0 2px var(--oc-focus-ring-strong);\n }\n }\n }\n\n /* Dark mode graph overrides (darker bg for canvas-based rendering) */\n .oc-dark .oc-graph-wrapper,\n .oc-graph-wrapper.oc-dark {\n /* GitHub-dark canvas background, intentionally not a token */\n --oc-bg: #0d1117;\n }\n\n /*\n * graph-mount.ts stamps .oc-dark on both .oc-graph-wrapper and\n * .oc-graph-container simultaneously, so the self-variant\n * (.oc-dark.oc-graph-wrapper) and descendant variant\n * (.oc-dark .oc-graph-legend) resolve identically.\n */\n .oc-dark .oc-graph-legend,\n .oc-dark.oc-graph-wrapper .oc-graph-legend,\n .oc-dark .oc-graph-search input {\n background: rgba(13, 17, 23, 0.85);\n border-color: var(--oc-border);\n }\n}\n","/* ---------------------------------------------------------------------------\n * Reduced motion\n *\n * Catch-all: last-declared layer beats every earlier layer regardless of\n * specificity. No !important, no hand-maintained selector mirror.\n *\n * Selector list matches CSS_TOKEN_ROOT_SELECTORS in token-definitions.ts.\n * --------------------------------------------------------------------------- */\n\n@layer oc.reduced-motion {\n @media (prefers-reduced-motion: reduce) {\n :is(\n .oc-root,\n .oc-chart-root,\n .oc-table-wrapper,\n .oc-table-root,\n .oc-graph-wrapper,\n .oc-graph-root,\n .oc-sankey-root,\n .oc-tilemap-root,\n .oc-barlist-root,\n .oc-map-root\n ),\n :is(\n .oc-root,\n .oc-chart-root,\n .oc-table-wrapper,\n .oc-table-root,\n .oc-graph-wrapper,\n .oc-graph-root,\n .oc-sankey-root,\n .oc-tilemap-root,\n .oc-barlist-root,\n .oc-map-root\n )\n *,\n :is(\n .oc-root,\n .oc-chart-root,\n .oc-table-wrapper,\n .oc-table-root,\n .oc-graph-wrapper,\n .oc-graph-root,\n .oc-sankey-root,\n .oc-tilemap-root,\n .oc-barlist-root,\n .oc-map-root\n )\n *::before,\n :is(\n .oc-root,\n .oc-chart-root,\n .oc-table-wrapper,\n .oc-table-root,\n .oc-graph-wrapper,\n .oc-graph-root,\n .oc-sankey-root,\n .oc-tilemap-root,\n .oc-barlist-root,\n .oc-map-root\n )\n *::after {\n animation: none;\n transition: none;\n }\n }\n}\n","@layer oc.animation {\n /* ---------------------------------------------------------------------------\n * Animation scoped rules (.oc-animate enables animation on the chart root)\n * --------------------------------------------------------------------------- */\n\n .oc-animate {\n /* Vertical bars (default): smooth ease-out, no overshoot.\n oc-mark-bar is reserved for future mark type aliases. */\n & .oc-mark-rect rect,\n & .oc-mark-bar rect {\n animation: oc-enter-bar var(--oc-animation-duration) var(--oc-ease-smooth) both;\n animation-delay: calc(var(--oc-animation-stagger) * var(--oc-mark-index, 0));\n }\n\n /* Horizontal bars (data-orient is on the mark group, not the SVG root) */\n & .oc-mark-rect[data-orient=\"horizontal\"] rect,\n & .oc-mark-bar[data-orient=\"horizontal\"] rect {\n animation-name: oc-enter-bar-h;\n }\n\n /* Stacked bar/column segments: chain sequentially so each segment starts\n right when the previous one finishes, creating one fluid reveal.\n Uses linear easing so handoffs between segments are seamless (no\n deceleration/acceleration stutter at segment boundaries). */\n & .oc-mark-rect[data-stack-pos] rect {\n animation-duration: var(--oc-stack-segment-duration, 150ms);\n animation-timing-function: linear;\n animation-delay: calc(\n var(--oc-animation-stagger) *\n var(--oc-mark-index, 0) +\n var(--oc-stack-pos, 0) *\n var(--oc-stack-segment-duration, 150ms)\n );\n }\n\n /* Line marks: entire group clips left-to-right (no WAAPI needed) */\n & .oc-mark-line {\n animation: oc-enter-line var(--oc-animation-duration)\n var(--oc-animation-ease, var(--oc-ease-smooth)) both;\n animation-delay: calc(var(--oc-animation-stagger) * var(--oc-mark-index, 0));\n }\n\n /* Area marks: entire group clips left-to-right + fades in */\n & .oc-mark-area {\n animation: oc-enter-line var(--oc-animation-duration)\n var(--oc-animation-ease, var(--oc-ease-smooth)) both;\n animation-delay: calc(var(--oc-animation-stagger) * var(--oc-mark-index, 0));\n }\n\n /* Arc marks (pie/donut slices): simple fade in.\n Scale transforms break arc positioning because arcs use translate()\n on parent groups. A clean fade is more elegant for pie/donut anyway. */\n & .oc-mark-arc {\n animation: oc-enter-fade-only var(--oc-animation-duration)\n var(--oc-animation-ease, var(--oc-ease-smooth)) both;\n animation-delay: calc(var(--oc-animation-stagger) * var(--oc-mark-index, 0));\n }\n\n /* Point marks (scatter, dot).\n Points render as bare <circle> elements with class oc-mark-point directly,\n not wrapped in a group, so we target circle.oc-mark-point (not descendant).\n Duration is 40% of the configured duration (quick pop-in relative to other marks). */\n & circle.oc-mark-point,\n & circle.oc-mark-circle {\n animation: oc-enter-fade-only calc(var(--oc-animation-duration) * 0.4)\n var(--oc-animation-ease, var(--oc-ease-smooth)) both;\n animation-delay: calc(var(--oc-animation-stagger) * var(--oc-mark-index, 0));\n }\n\n /* Points on line/area charts: delay so they pop in as the line draws through. */\n & .oc-mark-line ~ circle.oc-mark-point,\n & .oc-mark-area ~ circle.oc-mark-point {\n animation-delay: calc(\n var(--oc-animation-duration) *\n 0.35 +\n var(--oc-animation-stagger) *\n var(--oc-mark-index, 0)\n );\n }\n\n /* Text marks: fade + slight slide up */\n & .oc-mark-text text {\n animation: oc-enter-fade calc(var(--oc-animation-duration) * 0.6)\n var(--oc-animation-ease, var(--oc-ease-smooth)) both;\n animation-delay: calc(var(--oc-animation-stagger) * var(--oc-mark-index, 0));\n }\n\n /* Rule marks: fade in */\n & .oc-mark-rule line {\n animation: oc-enter-fade calc(var(--oc-animation-duration) * 0.5)\n var(--oc-animation-ease, var(--oc-ease-smooth)) both;\n animation-delay: calc(var(--oc-animation-stagger) * var(--oc-mark-index, 0));\n }\n\n /* Tick marks: fade in */\n & .oc-mark-tick line {\n animation: oc-enter-fade calc(var(--oc-animation-duration) * 0.5)\n var(--oc-animation-ease, var(--oc-ease-smooth)) both;\n animation-delay: calc(var(--oc-animation-stagger) * var(--oc-mark-index, 0));\n }\n\n /* Data labels: fade after their parent mark */\n & .oc-mark-label {\n animation: oc-enter-fade 300ms var(--oc-ease-smooth) both;\n animation-delay: calc(\n var(--oc-animation-stagger) *\n var(--oc-mark-index, 0) +\n var(--oc-animation-duration) *\n 0.7\n );\n }\n\n /* Annotations: fade in after marks finish */\n & .oc-annotation {\n animation: oc-enter-fade 400ms var(--oc-ease-smooth) both;\n animation-delay: calc(var(--oc-animation-duration) + var(--oc-annotation-delay, 200ms));\n }\n\n /* Tilemap tiles: fade in with jittered stagger for organic feel.\n Per-tile delay is computed in the renderer with pseudo-random variation. */\n & .oc-tilemap-tile {\n animation: oc-enter-fade-only calc(var(--oc-animation-duration) * 0.35) ease-in both;\n animation-delay: var(--oc-tile-delay, 0ms);\n }\n\n /* Map features: fill color reveal with shuffled stagger.\n Per-feature --oc-map-delay is computed in the renderer via a seeded\n Fisher-Yates shuffle so features pop in organically. */\n & .oc-map-feature {\n animation: oc-enter-map-fill var(--oc-animation-duration)\n var(--oc-animation-ease, var(--oc-ease-smooth)) both;\n animation-delay: var(--oc-map-delay, 0ms);\n }\n\n /* Bulk mode: high feature counts (counties, ~3k+) get a single group\n fade instead of per-feature fill animations. opacity is GPU-compositable\n so this stays smooth regardless of child count. */\n & .oc-map-features[data-bulk-animate] {\n animation: oc-enter-fade-only var(--oc-animation-duration)\n var(--oc-animation-ease, var(--oc-ease-smooth)) both;\n }\n\n & .oc-map-features[data-bulk-animate] .oc-map-feature {\n animation: none;\n }\n\n /* Map borders: fade in near the end of the feature sweep */\n & .oc-map-borders path {\n animation: oc-enter-fade-only calc(var(--oc-animation-duration) * 0.4) ease-in both;\n animation-delay: calc(var(--oc-animation-duration) * 0.7);\n }\n\n /* Map points: gentle scale (0.75->1) + fade pop-in after borders.\n transform-origin set per-circle in the renderer so scale happens\n around each circle's own center, not the SVG origin. */\n & .oc-map-point {\n animation: oc-enter-map-point calc(var(--oc-animation-duration) * 0.4)\n var(--oc-animation-ease, var(--oc-ease-smooth)) both;\n animation-delay: calc(var(--oc-animation-duration) * 0.8 + var(--oc-mark-index, 0) * 60ms);\n }\n\n /* Sankey nodes: fade in with stagger by column depth (left-to-right) */\n & .oc-sankey-node rect {\n animation: oc-enter-fade-only var(--oc-animation-duration)\n var(--oc-animation-ease, var(--oc-ease-smooth)) both;\n animation-delay: calc(var(--oc-animation-stagger) * var(--oc-mark-index, 0));\n }\n\n /* Sankey links: fade in after nodes, with stagger.\n Links delay by 30% of duration so nodes appear first, then links flow in. */\n & .oc-sankey-link path {\n animation: oc-enter-fade-only var(--oc-animation-duration)\n var(--oc-animation-ease, var(--oc-ease-smooth)) both;\n animation-delay: calc(\n var(--oc-animation-duration) *\n 0.3 +\n var(--oc-animation-stagger) *\n var(--oc-mark-index, 0)\n );\n }\n\n /* Barlist rows: fade + slide up per row, bars grow left-to-right */\n & .oc-barlist-row {\n animation: oc-enter-fade calc(var(--oc-animation-duration) * 0.6)\n var(--oc-animation-ease, var(--oc-ease-smooth)) both;\n animation-delay: var(--oc-row-delay, 0ms);\n }\n\n & .oc-barlist-bar {\n animation: oc-enter-bar-h var(--oc-animation-duration)\n var(--oc-animation-ease, var(--oc-ease-smooth)) both;\n animation-delay: var(--oc-row-delay, 0ms);\n }\n }\n\n /* ---------------------------------------------------------------------------\n * Sparkline mode: pair the line/area reveal with a stronger ease-out so it\n * doesn't read as a uniform left-to-right swipe. cubic-bezier(0.16, 1, 0.3, 1)\n * is \"expo-out\" — fast initial draw that decelerates noticeably at the end,\n * giving the trend a hand-drawn feel. Duration is bumped via the engine\n * (compile.ts) so the cleanup timer stays in sync.\n * --------------------------------------------------------------------------- */\n\n .oc-animate[data-display=\"sparkline\"] .oc-mark-line,\n .oc-animate[data-display=\"sparkline\"] .oc-mark-area {\n animation-timing-function: cubic-bezier(0.16, 1, 0.3, 1);\n }\n}\n"],"names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@opendata-ai/openchart-vue",
|
|
3
|
-
"version": "8.0.0-rc.
|
|
3
|
+
"version": "8.0.0-rc.5",
|
|
4
4
|
"description": "Vue 3 components for openchart: <Chart />, <DataTable />, <Graph />, <VizThemeProvider />",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "Riley Hilliard",
|
|
@@ -49,9 +49,9 @@
|
|
|
49
49
|
"typecheck": "tsc --noEmit"
|
|
50
50
|
},
|
|
51
51
|
"dependencies": {
|
|
52
|
-
"@opendata-ai/openchart-core": "8.0.0-rc.
|
|
53
|
-
"@opendata-ai/openchart-engine": "8.0.0-rc.
|
|
54
|
-
"@opendata-ai/openchart-vanilla": "8.0.0-rc.
|
|
52
|
+
"@opendata-ai/openchart-core": "8.0.0-rc.5",
|
|
53
|
+
"@opendata-ai/openchart-engine": "8.0.0-rc.5",
|
|
54
|
+
"@opendata-ai/openchart-vanilla": "8.0.0-rc.5"
|
|
55
55
|
},
|
|
56
56
|
"peerDependencies": {
|
|
57
57
|
"vue": ">=3.3.0"
|
package/src/Map.ts
CHANGED
|
@@ -7,14 +7,12 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import type { DarkMode, MapSpec, ThemeConfig } from '@opendata-ai/openchart-core';
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
import { createMap, type MapInstance, type MapMountOptions } from '@opendata-ai/openchart-vanilla';
|
|
10
|
+
import {
|
|
11
|
+
createMap,
|
|
12
|
+
type MapInstance,
|
|
13
|
+
type MapMarkEvent,
|
|
14
|
+
type MapMountOptions,
|
|
15
|
+
} from '@opendata-ai/openchart-vanilla';
|
|
18
16
|
import {
|
|
19
17
|
type CSSProperties,
|
|
20
18
|
defineComponent,
|
|
@@ -61,8 +59,8 @@ export const GeoMap = defineComponent({
|
|
|
61
59
|
},
|
|
62
60
|
},
|
|
63
61
|
emits: {
|
|
64
|
-
'mark-click': (_event:
|
|
65
|
-
'mark-hover': (_event:
|
|
62
|
+
'mark-click': (_event: MapMarkEvent) => true,
|
|
63
|
+
'mark-hover': (_event: MapMarkEvent | null) => true,
|
|
66
64
|
},
|
|
67
65
|
setup(props, { emit, expose }) {
|
|
68
66
|
const containerRef = ref<HTMLDivElement | null>(null);
|