dialkit 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/hooks/useDialKit.ts","../src/store/DialStore.ts","../src/components/DialRoot.tsx","../src/components/Folder.tsx","../src/components/Slider.tsx","../src/components/SegmentedControl.tsx","../src/components/Toggle.tsx","../src/components/SpringVisualization.tsx","../src/components/SpringControl.tsx","../src/components/Panel.tsx","../src/components/ButtonGroup.tsx"],"sourcesContent":["import { useEffect, useId, useSyncExternalStore, useRef } from 'react';\nimport { DialStore, DialConfig, DialValue, ResolvedValues, SpringConfig } from '../store/DialStore';\n\nexport interface UseDialOptions {\n onAction?: (action: string) => void;\n}\n\nexport function useDialKit<T extends DialConfig>(\n name: string,\n config: T,\n options?: UseDialOptions\n): ResolvedValues<T> {\n const instanceId = useId();\n const panelId = `${name}-${instanceId}`;\n const configRef = useRef(config);\n const onActionRef = useRef(options?.onAction);\n onActionRef.current = options?.onAction;\n\n // Register panel on mount\n useEffect(() => {\n DialStore.registerPanel(panelId, name, configRef.current);\n return () => DialStore.unregisterPanel(panelId);\n }, [panelId, name]);\n\n // Subscribe to action events\n useEffect(() => {\n return DialStore.subscribeActions(panelId, (action) => {\n onActionRef.current?.(action);\n });\n }, [panelId]);\n\n // Subscribe to changes\n const values = useSyncExternalStore(\n (callback) => DialStore.subscribe(panelId, callback),\n () => DialStore.getValues(panelId),\n () => DialStore.getValues(panelId)\n );\n\n // Build resolved values object\n return buildResolvedValues(config, values, '') as ResolvedValues<T>;\n}\n\nfunction buildResolvedValues(\n config: DialConfig,\n flatValues: Record<string, DialValue>,\n prefix: string\n): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n\n for (const [key, configValue] of Object.entries(config)) {\n const path = prefix ? `${prefix}.${key}` : key;\n\n if (Array.isArray(configValue) && configValue.length === 3 && typeof configValue[0] === 'number') {\n // Range tuple\n result[key] = flatValues[path] ?? configValue[0];\n } else if (typeof configValue === 'number' || typeof configValue === 'boolean' || typeof configValue === 'string') {\n result[key] = flatValues[path] ?? configValue;\n } else if (isSpringConfig(configValue)) {\n result[key] = flatValues[path] ?? configValue;\n } else if (typeof configValue === 'object' && configValue !== null) {\n // Nested object\n result[key] = buildResolvedValues(configValue as DialConfig, flatValues, path);\n }\n }\n\n return result;\n}\n\nfunction isSpringConfig(value: unknown): value is SpringConfig {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'type' in value &&\n (value as SpringConfig).type === 'spring'\n );\n}\n","// Lightweight state store with subscriptions for dialkit\n\nexport type SpringConfig = {\n type: 'spring';\n stiffness?: number;\n damping?: number;\n mass?: number;\n visualDuration?: number;\n bounce?: number;\n};\n\nexport type ActionConfig = {\n type: 'action';\n label?: string;\n};\n\nexport type DialValue = number | boolean | string | SpringConfig | ActionConfig;\n\nexport type DialConfig = {\n [key: string]: DialValue | [number, number, number] | DialConfig;\n};\n\nexport type ResolvedValues<T extends DialConfig> = {\n [K in keyof T]: T[K] extends [number, number, number]\n ? number\n : T[K] extends SpringConfig\n ? SpringConfig\n : T[K] extends DialConfig\n ? ResolvedValues<T[K]>\n : T[K];\n};\n\nexport type ControlMeta = {\n type: 'slider' | 'toggle' | 'spring' | 'folder' | 'action';\n path: string;\n label: string;\n min?: number;\n max?: number;\n step?: number;\n children?: ControlMeta[];\n};\n\nexport type PanelConfig = {\n id: string;\n name: string;\n controls: ControlMeta[];\n values: Record<string, DialValue>;\n};\n\ntype Listener = () => void;\ntype ActionListener = (action: string) => void;\n\nclass DialStoreClass {\n private panels: Map<string, PanelConfig> = new Map();\n private listeners: Map<string, Set<Listener>> = new Map();\n private globalListeners: Set<Listener> = new Set();\n private snapshots: Map<string, Record<string, DialValue>> = new Map();\n private actionListeners: Map<string, Set<ActionListener>> = new Map();\n\n registerPanel(id: string, name: string, config: DialConfig): void {\n const controls = this.parseConfig(config, '');\n const values = this.flattenValues(config, '');\n\n this.panels.set(id, { id, name, controls, values });\n this.snapshots.set(id, { ...values });\n this.notifyGlobal();\n }\n\n unregisterPanel(id: string): void {\n this.panels.delete(id);\n this.listeners.delete(id);\n this.snapshots.delete(id);\n this.notifyGlobal();\n }\n\n updateValue(panelId: string, path: string, value: DialValue): void {\n const panel = this.panels.get(panelId);\n if (!panel) return;\n\n panel.values[path] = value;\n // Create a new snapshot reference so useSyncExternalStore detects the change\n this.snapshots.set(panelId, { ...panel.values });\n this.notify(panelId);\n }\n\n updateSpringMode(panelId: string, path: string, mode: 'simple' | 'advanced'): void {\n const panel = this.panels.get(panelId);\n if (!panel) return;\n\n // Store the mode preference\n panel.values[`${path}.__mode`] = mode;\n // Create a new snapshot reference\n this.snapshots.set(panelId, { ...panel.values });\n this.notify(panelId);\n }\n\n getSpringMode(panelId: string, path: string): 'simple' | 'advanced' {\n const panel = this.panels.get(panelId);\n if (!panel) return 'simple';\n return (panel.values[`${path}.__mode`] as 'simple' | 'advanced') || 'simple';\n }\n\n getValue(panelId: string, path: string): DialValue | undefined {\n const panel = this.panels.get(panelId);\n return panel?.values[path];\n }\n\n getValues(panelId: string): Record<string, DialValue> {\n // Return the snapshot for useSyncExternalStore compatibility\n return this.snapshots.get(panelId) ?? {};\n }\n\n getPanels(): PanelConfig[] {\n return Array.from(this.panels.values());\n }\n\n getPanel(id: string): PanelConfig | undefined {\n return this.panels.get(id);\n }\n\n subscribe(panelId: string, listener: Listener): () => void {\n if (!this.listeners.has(panelId)) {\n this.listeners.set(panelId, new Set());\n }\n this.listeners.get(panelId)!.add(listener);\n\n return () => {\n this.listeners.get(panelId)?.delete(listener);\n };\n }\n\n subscribeGlobal(listener: Listener): () => void {\n this.globalListeners.add(listener);\n return () => this.globalListeners.delete(listener);\n }\n\n subscribeActions(panelId: string, listener: ActionListener): () => void {\n if (!this.actionListeners.has(panelId)) {\n this.actionListeners.set(panelId, new Set());\n }\n this.actionListeners.get(panelId)!.add(listener);\n\n return () => {\n this.actionListeners.get(panelId)?.delete(listener);\n };\n }\n\n triggerAction(panelId: string, path: string): void {\n this.actionListeners.get(panelId)?.forEach(fn => fn(path));\n }\n\n private notify(panelId: string): void {\n this.listeners.get(panelId)?.forEach(fn => fn());\n }\n\n private notifyGlobal(): void {\n this.globalListeners.forEach(fn => fn());\n }\n\n private parseConfig(config: DialConfig, prefix: string): ControlMeta[] {\n const controls: ControlMeta[] = [];\n\n for (const [key, value] of Object.entries(config)) {\n const path = prefix ? `${prefix}.${key}` : key;\n const label = this.formatLabel(key);\n\n if (Array.isArray(value) && value.length === 3 && typeof value[0] === 'number') {\n // Range tuple: [default, min, max]\n controls.push({\n type: 'slider',\n path,\n label,\n min: value[1],\n max: value[2],\n step: this.inferStep(value[1], value[2]),\n });\n } else if (typeof value === 'number') {\n // Single number - auto-infer range\n const { min, max, step } = this.inferRange(value);\n controls.push({ type: 'slider', path, label, min, max, step });\n } else if (typeof value === 'boolean') {\n controls.push({ type: 'toggle', path, label });\n } else if (this.isSpringConfig(value)) {\n controls.push({ type: 'spring', path, label });\n } else if (this.isActionConfig(value)) {\n controls.push({ type: 'action', path, label: (value as ActionConfig).label || label });\n } else if (typeof value === 'object' && value !== null) {\n // Nested object becomes a folder\n controls.push({\n type: 'folder',\n path,\n label,\n children: this.parseConfig(value as DialConfig, path),\n });\n }\n }\n\n return controls;\n }\n\n private flattenValues(config: DialConfig, prefix: string): Record<string, DialValue> {\n const values: Record<string, DialValue> = {};\n\n for (const [key, value] of Object.entries(config)) {\n const path = prefix ? `${prefix}.${key}` : key;\n\n if (Array.isArray(value) && value.length === 3 && typeof value[0] === 'number') {\n values[path] = value[0]; // Default value\n } else if (typeof value === 'number' || typeof value === 'boolean' || typeof value === 'string') {\n values[path] = value;\n } else if (this.isSpringConfig(value)) {\n values[path] = value;\n } else if (this.isActionConfig(value)) {\n // Actions don't need stored values - they're just triggers\n values[path] = value;\n } else if (typeof value === 'object' && value !== null) {\n Object.assign(values, this.flattenValues(value as DialConfig, path));\n }\n }\n\n return values;\n }\n\n private isSpringConfig(value: unknown): value is SpringConfig {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'type' in value &&\n (value as SpringConfig).type === 'spring'\n );\n }\n\n private isActionConfig(value: unknown): value is ActionConfig {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'type' in value &&\n (value as ActionConfig).type === 'action'\n );\n }\n\n private formatLabel(key: string): string {\n // Convert camelCase to Title Case\n return key\n .replace(/([A-Z])/g, ' $1')\n .replace(/^./, str => str.toUpperCase())\n .trim();\n }\n\n private inferRange(value: number): { min: number; max: number; step: number } {\n // Infer reasonable range based on value\n if (value >= 0 && value <= 1) {\n return { min: 0, max: 1, step: 0.01 };\n } else if (value >= 0 && value <= 10) {\n return { min: 0, max: value * 2 || 10, step: 0.1 };\n } else if (value >= 0 && value <= 100) {\n return { min: 0, max: value * 2 || 100, step: 1 };\n } else if (value >= 0) {\n return { min: 0, max: value * 2 || 1000, step: 10 };\n } else {\n return { min: value * 2, max: -value * 2, step: 1 };\n }\n }\n\n private inferStep(min: number, max: number): number {\n const range = max - min;\n if (range <= 1) return 0.01;\n if (range <= 10) return 0.1;\n if (range <= 100) return 1;\n return 10;\n }\n}\n\n// Singleton instance\nexport const DialStore = new DialStoreClass();\n","import { useEffect, useState } from 'react';\nimport { createPortal } from 'react-dom';\nimport { DialStore, PanelConfig } from '../store/DialStore';\nimport { Panel } from './Panel';\n\nexport type DialPosition = 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left';\n\ninterface DialRootProps {\n position?: DialPosition;\n}\n\nexport function DialRoot({ position = 'top-right' }: DialRootProps) {\n const [panels, setPanels] = useState<PanelConfig[]>([]);\n const [mounted, setMounted] = useState(false);\n\n // Subscribe to global panel changes\n useEffect(() => {\n setMounted(true);\n setPanels(DialStore.getPanels());\n\n const unsubscribe = DialStore.subscribeGlobal(() => {\n setPanels(DialStore.getPanels());\n });\n\n return unsubscribe;\n }, []);\n\n // Don't render on server\n if (!mounted || typeof window === 'undefined') {\n return null;\n }\n\n // Don't render if no panels registered\n if (panels.length === 0) {\n return null;\n }\n\n const content = (\n <div className=\"dialkit-root\">\n <div className=\"dialkit-panel\" data-position={position}>\n {panels.map((panel) => (\n <Panel key={panel.id} panel={panel} />\n ))}\n </div>\n </div>\n );\n\n return createPortal(content, document.body);\n}\n","import { useState, ReactNode } from 'react';\nimport { motion, AnimatePresence } from 'motion/react';\nimport { DialStore } from '../store/DialStore';\n\ninterface FolderProps {\n title: string;\n children: ReactNode;\n defaultOpen?: boolean;\n isRoot?: boolean;\n panelId?: string;\n}\n\nexport function Folder({ title, children, defaultOpen = true, isRoot = false, panelId }: FolderProps) {\n const [isOpen, setIsOpen] = useState(defaultOpen);\n const [copied, setCopied] = useState(false);\n\n const handleCopy = (e: React.MouseEvent) => {\n e.stopPropagation();\n if (!panelId) return;\n\n const values = DialStore.getValues(panelId);\n const jsonStr = JSON.stringify(values, null, 2);\n\n // Build instruction for Claude Code\n const instruction = `Update the useDialKit configuration for \"${title}\" with these values:\n\n\\`\\`\\`json\n${jsonStr}\n\\`\\`\\`\n\nApply these values as the new defaults in the useDialKit call.`;\n\n navigator.clipboard.writeText(instruction);\n setCopied(true);\n setTimeout(() => setCopied(false), 1500);\n };\n\n const iconTransition = { type: 'spring' as const, visualDuration: 0.4, bounce: 0.1 };\n\n const folderContent = (\n <div className={`dialkit-folder ${isRoot ? 'dialkit-folder-root' : ''}`}>\n <div className=\"dialkit-folder-header\" onClick={() => setIsOpen(!isOpen)}>\n <div className=\"dialkit-folder-title-row\">\n <span className={`dialkit-folder-title ${isRoot ? 'dialkit-folder-title-root' : ''}`}>\n {title}\n </span>\n {isRoot && panelId && (\n <motion.button\n className=\"dialkit-folder-copy\"\n onClick={handleCopy}\n title=\"Copy parameters\"\n initial={false}\n animate={{\n opacity: isOpen ? 1 : 0,\n scale: isOpen ? 1 : 0.7,\n filter: isOpen ? 'blur(0px)' : 'blur(6px)',\n }}\n transition={iconTransition}\n style={{ pointerEvents: isOpen ? 'auto' : 'none' }}\n >\n <div style={{ position: 'relative', width: 14, height: 14 }}>\n {/* Copy icon */}\n <motion.svg\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n style={{ position: 'absolute', inset: 0 }}\n initial={false}\n animate={{\n opacity: copied ? 0 : 1,\n scale: copied ? 0.7 : 1,\n filter: copied ? 'blur(6px)' : 'blur(0px)',\n }}\n transition={iconTransition}\n >\n <rect x=\"9\" y=\"9\" width=\"13\" height=\"13\" rx=\"2\" ry=\"2\" />\n <path d=\"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1\" />\n </motion.svg>\n {/* Check icon */}\n <motion.svg\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n style={{ position: 'absolute', inset: 0 }}\n initial={false}\n animate={{\n opacity: copied ? 1 : 0,\n scale: copied ? 1 : 0.7,\n filter: copied ? 'blur(0px)' : 'blur(6px)',\n }}\n transition={iconTransition}\n >\n <polyline points=\"20 6 9 17 4 12\" />\n </motion.svg>\n </div>\n </motion.button>\n )}\n </div>\n {isRoot ? (\n // Root panel uses minus/plus icons with crossfade\n <div className=\"dialkit-folder-icon\" style={{ position: 'relative' }}>\n {/* Minus icon (when open) */}\n <motion.svg\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n style={{ position: 'absolute', inset: 0, width: '100%', height: '100%' }}\n initial={false}\n animate={{\n opacity: isOpen ? 1 : 0,\n scale: isOpen ? 1 : 0.7,\n filter: isOpen ? 'blur(0px)' : 'blur(6px)',\n }}\n transition={iconTransition}\n >\n <line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\" />\n </motion.svg>\n {/* Plus icon (when closed) */}\n <motion.svg\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n style={{ position: 'absolute', inset: 0, width: '100%', height: '100%' }}\n initial={false}\n animate={{\n opacity: isOpen ? 0 : 1,\n scale: isOpen ? 0.7 : 1,\n filter: isOpen ? 'blur(6px)' : 'blur(0px)',\n }}\n transition={iconTransition}\n >\n <line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\" />\n <line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\" />\n </motion.svg>\n </div>\n ) : (\n // Section folders use rotating chevron with gentle spring\n <motion.svg\n className=\"dialkit-folder-icon\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n initial={false}\n animate={{ rotate: isOpen ? 0 : 180 }}\n transition={{ type: 'spring', visualDuration: 0.35, bounce: 0.15 }}\n >\n <line x1=\"5\" y1=\"9\" x2=\"12\" y2=\"16\" />\n <line x1=\"19\" y1=\"9\" x2=\"12\" y2=\"16\" />\n </motion.svg>\n )}\n </div>\n\n <AnimatePresence initial={false}>\n {isOpen && (\n <motion.div\n className=\"dialkit-folder-content\"\n initial={{ height: 0, opacity: 0 }}\n animate={{ height: 'auto', opacity: 1 }}\n exit={{ height: 0, opacity: 0 }}\n transition={{ type: 'spring', visualDuration: 0.25, bounce: 0 }}\n >\n <div className=\"dialkit-folder-inner\">{children}</div>\n </motion.div>\n )}\n </AnimatePresence>\n </div>\n );\n\n // For root folders, wrap in animated panel container\n if (isRoot) {\n return (\n <motion.div\n className=\"dialkit-panel-inner\"\n initial={false}\n animate={{\n width: isOpen ? 280 : 160,\n boxShadow: isOpen\n ? '0 8px 32px rgba(0, 0, 0, 0.5)'\n : '0 4px 16px rgba(0, 0, 0, 0.25)',\n }}\n transition={{ type: 'spring', visualDuration: 0.4, bounce: 0.05 }}\n data-collapsed={!isOpen}\n >\n {folderContent}\n </motion.div>\n );\n }\n\n return folderContent;\n}\n","import { useRef, useState, useCallback, useEffect } from 'react';\nimport { motion } from 'motion/react';\n\ninterface SliderProps {\n label: string;\n value: number;\n onChange: (value: number) => void;\n min?: number;\n max?: number;\n step?: number;\n unit?: string;\n}\n\nexport function Slider({\n label,\n value,\n onChange,\n min = 0,\n max = 1,\n step = 0.01,\n unit,\n}: SliderProps) {\n const trackRef = useRef<HTMLDivElement>(null);\n const inputRef = useRef<HTMLInputElement>(null);\n const [isInteracting, setIsInteracting] = useState(false);\n const [isDragging, setIsDragging] = useState(false);\n const [isHovered, setIsHovered] = useState(false);\n const [isValueHovered, setIsValueHovered] = useState(false);\n const [isValueEditable, setIsValueEditable] = useState(false);\n const [showInput, setShowInput] = useState(false);\n const [inputValue, setInputValue] = useState('');\n const hoverTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const percentage = ((value - min) / (max - min)) * 100;\n const isAtMinimum = value <= min;\n const isActive = isInteracting || isHovered;\n\n const positionToValue = useCallback(\n (clientX: number) => {\n if (!trackRef.current) return value;\n const rect = trackRef.current.getBoundingClientRect();\n const x = clientX - rect.left;\n const percent = Math.max(0, Math.min(1, x / rect.width));\n const rawValue = min + percent * (max - min);\n return Math.max(min, Math.min(max, rawValue));\n },\n [min, max, value]\n );\n\n const handleMouseDown = useCallback(\n (e: React.MouseEvent) => {\n if (showInput) return;\n e.preventDefault();\n setIsInteracting(true);\n onChange(positionToValue(e.clientX));\n },\n [positionToValue, onChange, showInput]\n );\n\n const handleMouseMove = useCallback(\n (e: MouseEvent) => {\n if (!isInteracting) return;\n if (!isDragging) setIsDragging(true);\n onChange(positionToValue(e.clientX));\n },\n [isInteracting, isDragging, positionToValue, onChange]\n );\n\n const handleMouseUp = useCallback(() => {\n setIsInteracting(false);\n setIsDragging(false);\n }, []);\n\n const handleTouchStart = useCallback(\n (e: React.TouchEvent) => {\n if (showInput) return;\n e.preventDefault();\n setIsInteracting(true);\n const touch = e.touches[0];\n onChange(positionToValue(touch.clientX));\n },\n [positionToValue, onChange, showInput]\n );\n\n const handleTouchMove = useCallback(\n (e: TouchEvent) => {\n if (!isInteracting) return;\n if (!isDragging) setIsDragging(true);\n const touch = e.touches[0];\n onChange(positionToValue(touch.clientX));\n },\n [isInteracting, isDragging, positionToValue, onChange]\n );\n\n const handleTouchEnd = useCallback(() => {\n setIsInteracting(false);\n setIsDragging(false);\n }, []);\n\n useEffect(() => {\n if (isInteracting) {\n document.addEventListener('mousemove', handleMouseMove);\n document.addEventListener('mouseup', handleMouseUp);\n document.addEventListener('touchmove', handleTouchMove, { passive: false });\n document.addEventListener('touchend', handleTouchEnd);\n return () => {\n document.removeEventListener('mousemove', handleMouseMove);\n document.removeEventListener('mouseup', handleMouseUp);\n document.removeEventListener('touchmove', handleTouchMove);\n document.removeEventListener('touchend', handleTouchEnd);\n };\n }\n }, [isInteracting, handleMouseMove, handleMouseUp, handleTouchMove, handleTouchEnd]);\n\n // Handle value hover delay for editable state\n useEffect(() => {\n if (isValueHovered && !showInput && !isValueEditable) {\n hoverTimeoutRef.current = setTimeout(() => {\n setIsValueEditable(true);\n }, 800);\n } else if (!isValueHovered && !showInput) {\n if (hoverTimeoutRef.current) {\n clearTimeout(hoverTimeoutRef.current);\n hoverTimeoutRef.current = null;\n }\n setIsValueEditable(false);\n }\n return () => {\n if (hoverTimeoutRef.current) {\n clearTimeout(hoverTimeoutRef.current);\n }\n };\n }, [isValueHovered, showInput, isValueEditable]);\n\n // Focus input when it appears\n useEffect(() => {\n if (showInput && inputRef.current) {\n inputRef.current.focus();\n inputRef.current.select();\n }\n }, [showInput]);\n\n const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n setInputValue(e.target.value);\n };\n\n const handleInputSubmit = () => {\n const parsed = parseFloat(inputValue);\n if (!isNaN(parsed)) {\n const clamped = Math.max(min, Math.min(max, parsed));\n onChange(clamped);\n }\n setShowInput(false);\n setIsValueHovered(false);\n setIsValueEditable(false);\n };\n\n const handleValueClick = (e: React.MouseEvent) => {\n if (isValueEditable) {\n e.stopPropagation();\n e.preventDefault();\n setShowInput(true);\n setInputValue(step >= 1 ? value.toFixed(0) : value.toFixed(2));\n }\n };\n\n const handleInputKeyDown = (e: React.KeyboardEvent) => {\n if (e.key === 'Enter') {\n handleInputSubmit();\n } else if (e.key === 'Escape') {\n setShowInput(false);\n setIsValueHovered(false);\n }\n };\n\n const handleInputBlur = () => {\n handleInputSubmit();\n };\n\n const displayValue = step >= 1 ? value.toFixed(0) : value.toFixed(2);\n const shouldAnimate = !isDragging;\n const transition = shouldAnimate\n ? { type: 'spring' as const, visualDuration: 0.3, bounce: 0.15 }\n : { duration: 0 };\n\n const handleLeft = isAtMinimum ? 7 : `calc(${percentage}% - 9px)`;\n const fillBackground = isActive\n ? 'rgba(255, 255, 255, 0.15)'\n : 'rgba(255, 255, 255, 0.11)';\n\n const hashMarks = Array.from({ length: 7 }, (_, i) => (\n <span key={i} className=\"dialkit-slider-hashmark\">•</span>\n ));\n\n return (\n <div\n ref={trackRef}\n className={`dialkit-slider ${isActive ? 'dialkit-slider-active' : ''}`}\n onMouseDown={handleMouseDown}\n onTouchStart={handleTouchStart}\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n >\n <div className=\"dialkit-slider-hashmarks\">{hashMarks}</div>\n\n <motion.div\n className=\"dialkit-slider-fill\"\n style={{ background: fillBackground, width: `${percentage}%`, transition: 'background 0.15s' }}\n animate={{ width: `${percentage}%` }}\n transition={transition}\n />\n\n <motion.div\n className=\"dialkit-slider-handle\"\n style={{\n background: isInteracting ? 'rgba(255, 255, 255, 1)' : 'rgba(255, 255, 255, 0.5)',\n left: handleLeft,\n opacity: isActive ? 1 : 0,\n }}\n animate={{ left: handleLeft, opacity: isActive ? 1 : 0 }}\n transition={transition}\n />\n\n <span className=\"dialkit-slider-label\">\n {label}\n </span>\n\n {showInput ? (\n <input\n ref={inputRef}\n type=\"text\"\n className=\"dialkit-slider-input\"\n value={inputValue}\n onChange={handleInputChange}\n onKeyDown={handleInputKeyDown}\n onBlur={handleInputBlur}\n onClick={(e) => e.stopPropagation()}\n onMouseDown={(e) => e.stopPropagation()}\n />\n ) : (\n <span\n className={`dialkit-slider-value ${isValueEditable ? 'dialkit-slider-value-editable' : ''}`}\n onMouseEnter={() => setIsValueHovered(true)}\n onMouseLeave={() => setIsValueHovered(false)}\n onClick={handleValueClick}\n onMouseDown={(e) => isValueEditable && e.stopPropagation()}\n style={{ cursor: isValueEditable ? 'text' : 'default' }}\n >\n {displayValue}{unit}\n </span>\n )}\n </div>\n );\n}\n","import { useRef, useState, useLayoutEffect } from 'react';\nimport { motion } from 'motion/react';\n\ninterface SegmentedControlOption<T extends string> {\n value: T;\n label: string;\n}\n\ninterface SegmentedControlProps<T extends string> {\n options: SegmentedControlOption<T>[];\n value: T;\n onChange: (value: T) => void;\n}\n\nexport function SegmentedControl<T extends string>({\n options,\n value,\n onChange,\n}: SegmentedControlProps<T>) {\n const containerRef = useRef<HTMLDivElement>(null);\n const buttonRefs = useRef<Map<T, HTMLButtonElement>>(new Map());\n const [pillStyle, setPillStyle] = useState<{ left: number; width: number } | null>(null);\n const hasAnimated = useRef(false);\n\n useLayoutEffect(() => {\n const button = buttonRefs.current.get(value);\n const container = containerRef.current;\n if (button && container) {\n const containerRect = container.getBoundingClientRect();\n const buttonRect = button.getBoundingClientRect();\n setPillStyle({\n left: buttonRect.left - containerRect.left,\n width: buttonRect.width,\n });\n }\n }, [value]);\n\n return (\n <div ref={containerRef} className=\"dialkit-segmented\">\n {pillStyle && (\n <motion.div\n className=\"dialkit-segmented-pill\"\n style={{ left: pillStyle.left, width: pillStyle.width }}\n animate={{ left: pillStyle.left, width: pillStyle.width }}\n transition={\n hasAnimated.current\n ? { type: 'spring', visualDuration: 0.2, bounce: 0.15 }\n : { duration: 0 }\n }\n onAnimationComplete={() => { hasAnimated.current = true; }}\n />\n )}\n\n {options.map((option) => {\n const isActive = value === option.value;\n return (\n <button\n key={option.value}\n ref={(el) => { if (el) buttonRefs.current.set(option.value, el); }}\n onClick={() => onChange(option.value)}\n className=\"dialkit-segmented-button\"\n data-active={String(isActive)}\n >\n {option.label}\n </button>\n );\n })}\n </div>\n );\n}\n","import { SegmentedControl } from './SegmentedControl';\n\ninterface ToggleProps {\n label: string;\n checked: boolean;\n onChange: (checked: boolean) => void;\n}\n\nexport function Toggle({ label, checked, onChange }: ToggleProps) {\n return (\n <div className=\"dialkit-labeled-control\">\n <span className=\"dialkit-labeled-control-label\">{label}</span>\n <SegmentedControl\n options={[\n { value: 'off' as const, label: 'Off' },\n { value: 'on' as const, label: 'On' },\n ]}\n value={checked ? 'on' : 'off'}\n onChange={(val) => onChange(val === 'on')}\n />\n </div>\n );\n}\n","import { SpringConfig } from '../store/DialStore';\n\ninterface SpringVisualizationProps {\n spring: SpringConfig;\n isSimpleMode: boolean;\n}\n\nfunction generateSpringCurve(\n stiffness: number,\n damping: number,\n mass: number,\n duration: number\n): [number, number][] {\n const points: [number, number][] = [];\n const steps = 100;\n const dt = duration / steps;\n\n let position = 0;\n let velocity = 0;\n const target = 1;\n\n for (let i = 0; i <= steps; i++) {\n const time = i * dt;\n points.push([time, position]);\n\n const springForce = -stiffness * (position - target);\n const dampingForce = -damping * velocity;\n const acceleration = (springForce + dampingForce) / mass;\n\n velocity += acceleration * dt;\n position += velocity * dt;\n }\n\n return points;\n}\n\nexport function SpringVisualization({ spring, isSimpleMode }: SpringVisualizationProps) {\n const width = 256;\n const height = 140;\n\n let stiffness: number;\n let damping: number;\n let mass: number;\n\n if (isSimpleMode) {\n const visualDuration = spring.visualDuration ?? 0.3;\n const bounce = spring.bounce ?? 0.2;\n mass = 1;\n\n stiffness = (2 * Math.PI) / visualDuration;\n stiffness = Math.pow(stiffness, 2);\n\n const dampingRatio = 1 - bounce;\n damping = 2 * dampingRatio * Math.sqrt(stiffness * mass);\n } else {\n stiffness = spring.stiffness ?? 400;\n damping = spring.damping ?? 17;\n mass = spring.mass ?? 1;\n }\n\n const duration = 2;\n const points = generateSpringCurve(stiffness, damping, mass, duration);\n\n const values = points.map(([, value]) => value);\n const minValue = Math.min(...values);\n const maxValue = Math.max(...values);\n const valueRange = maxValue - minValue;\n\n const pathData = points\n .map(([time, value], i) => {\n const x = (time / duration) * width;\n const normalizedValue = (value - minValue) / (valueRange || 1);\n const y = height - (normalizedValue * height * 0.6 + height * 0.2);\n return `${i === 0 ? 'M' : 'L'} ${x} ${y}`;\n })\n .join(' ');\n\n const gridLines = [];\n for (let i = 1; i < 4; i++) {\n const x = (width / 4) * i;\n const y = (height / 4) * i;\n gridLines.push(\n <line key={`v-${i}`} x1={x} y1={0} x2={x} y2={height} stroke=\"rgba(255, 255, 255, 0.08)\" strokeWidth=\"1\" />,\n <line key={`h-${i}`} x1={0} y1={y} x2={width} y2={y} stroke=\"rgba(255, 255, 255, 0.08)\" strokeWidth=\"1\" />\n );\n }\n\n return (\n <svg viewBox={`0 0 ${width} ${height}`} className=\"dialkit-spring-viz\">\n {gridLines}\n <line\n x1={0}\n y1={height / 2}\n x2={width}\n y2={height / 2}\n stroke=\"rgba(255, 255, 255, 0.15)\"\n strokeWidth=\"1\"\n strokeDasharray=\"4,4\"\n />\n <path\n d={pathData}\n fill=\"none\"\n stroke=\"rgba(255, 255, 255, 0.6)\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n );\n}\n","import { SpringConfig, DialStore } from '../store/DialStore';\nimport { Folder } from './Folder';\nimport { Slider } from './Slider';\nimport { SegmentedControl } from './SegmentedControl';\nimport { SpringVisualization } from './SpringVisualization';\nimport { useSyncExternalStore } from 'react';\n\ninterface SpringControlProps {\n panelId: string;\n path: string;\n label: string;\n spring: SpringConfig;\n onChange: (spring: SpringConfig) => void;\n}\n\nexport function SpringControl({ panelId, path, label, spring, onChange }: SpringControlProps) {\n const mode = useSyncExternalStore(\n (cb) => DialStore.subscribe(panelId, cb),\n () => DialStore.getSpringMode(panelId, path),\n () => DialStore.getSpringMode(panelId, path)\n );\n\n const isSimpleMode = mode === 'simple';\n\n const handleModeChange = (newMode: 'simple' | 'advanced') => {\n DialStore.updateSpringMode(panelId, path, newMode);\n\n // When switching modes, update the spring config to remove conflicting properties\n if (newMode === 'simple') {\n // Remove physics properties, keep/add time-based properties\n const { stiffness, damping, mass, ...rest } = spring;\n onChange({\n ...rest,\n type: 'spring',\n visualDuration: spring.visualDuration ?? 0.3,\n bounce: spring.bounce ?? 0.2,\n });\n } else {\n // Remove time-based properties, keep/add physics properties\n const { visualDuration, bounce, ...rest } = spring;\n onChange({\n ...rest,\n type: 'spring',\n stiffness: spring.stiffness ?? 200,\n damping: spring.damping ?? 25,\n mass: spring.mass ?? 1,\n });\n }\n };\n\n const handleUpdate = (key: keyof SpringConfig, value: number) => {\n // When updating in simple mode, ensure physics props are removed\n if (isSimpleMode) {\n const { stiffness, damping, mass, ...rest } = spring;\n onChange({ ...rest, [key]: value });\n } else {\n // When updating in physics mode, ensure time-based props are removed\n const { visualDuration, bounce, ...rest } = spring;\n onChange({ ...rest, [key]: value });\n }\n };\n\n return (\n <Folder title={label} defaultOpen={true}>\n <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>\n <SpringVisualization spring={spring} isSimpleMode={isSimpleMode} />\n\n <div className=\"dialkit-labeled-control\">\n <span className=\"dialkit-labeled-control-label\">Type</span>\n <SegmentedControl\n options={[\n { value: 'simple' as const, label: 'Time' },\n { value: 'advanced' as const, label: 'Physics' },\n ]}\n value={mode}\n onChange={handleModeChange}\n />\n </div>\n\n {isSimpleMode ? (\n <>\n <Slider\n label=\"Duration\"\n value={spring.visualDuration ?? 0.3}\n onChange={(v) => handleUpdate('visualDuration', v)}\n min={0.1}\n max={1}\n step={0.05}\n unit=\"s\"\n />\n <Slider\n label=\"Bounce\"\n value={spring.bounce ?? 0.2}\n onChange={(v) => handleUpdate('bounce', v)}\n min={0}\n max={1}\n step={0.05}\n />\n </>\n ) : (\n <>\n <Slider\n label=\"Stiffness\"\n value={spring.stiffness ?? 400}\n onChange={(v) => handleUpdate('stiffness', v)}\n min={1}\n max={1000}\n step={10}\n />\n <Slider\n label=\"Damping\"\n value={spring.damping ?? 17}\n onChange={(v) => handleUpdate('damping', v)}\n min={1}\n max={100}\n step={1}\n />\n <Slider\n label=\"Mass\"\n value={spring.mass ?? 1}\n onChange={(v) => handleUpdate('mass', v)}\n min={0.1}\n max={10}\n step={0.1}\n />\n </>\n )}\n </div>\n </Folder>\n );\n}\n","import { DialStore, ControlMeta, PanelConfig, SpringConfig } from '../store/DialStore';\nimport { Folder } from './Folder';\nimport { Slider } from './Slider';\nimport { Toggle } from './Toggle';\nimport { SpringControl } from './SpringControl';\nimport { useSyncExternalStore } from 'react';\n\ninterface PanelProps {\n panel: PanelConfig;\n}\n\nexport function Panel({ panel }: PanelProps) {\n // Subscribe to panel value changes\n const values = useSyncExternalStore(\n (cb) => DialStore.subscribe(panel.id, cb),\n () => DialStore.getValues(panel.id),\n () => DialStore.getValues(panel.id)\n );\n\n const renderControl = (control: ControlMeta) => {\n const value = values[control.path];\n\n switch (control.type) {\n case 'slider':\n return (\n <Slider\n key={control.path}\n label={control.label}\n value={value as number}\n onChange={(v) => DialStore.updateValue(panel.id, control.path, v)}\n min={control.min}\n max={control.max}\n step={control.step}\n />\n );\n\n case 'toggle':\n return (\n <Toggle\n key={control.path}\n label={control.label}\n checked={value as boolean}\n onChange={(v) => DialStore.updateValue(panel.id, control.path, v)}\n />\n );\n\n case 'spring':\n return (\n <SpringControl\n key={control.path}\n panelId={panel.id}\n path={control.path}\n label={control.label}\n spring={value as SpringConfig}\n onChange={(v) => DialStore.updateValue(panel.id, control.path, v)}\n />\n );\n\n case 'folder':\n return (\n <Folder key={control.path} title={control.label}>\n {control.children?.map(renderControl)}\n </Folder>\n );\n\n default:\n return null;\n }\n };\n\n // Group consecutive actions together\n const renderControls = () => {\n const result: React.ReactNode[] = [];\n let i = 0;\n\n while (i < panel.controls.length) {\n const control = panel.controls[i];\n\n if (control.type === 'action') {\n // Collect consecutive actions\n const actions: ControlMeta[] = [control];\n while (i + 1 < panel.controls.length && panel.controls[i + 1].type === 'action') {\n i++;\n actions.push(panel.controls[i]);\n }\n\n // Render action group\n result.push(\n <div key={`actions-${actions[0].path}`} className=\"dialkit-labeled-control dialkit-actions-group\">\n <span className=\"dialkit-labeled-control-label\">Actions</span>\n <div className=\"dialkit-actions-stack\">\n {actions.map((action) => (\n <button\n key={action.path}\n className=\"dialkit-action-button\"\n onClick={() => DialStore.triggerAction(panel.id, action.path)}\n >\n {action.label}\n </button>\n ))}\n </div>\n </div>\n );\n } else {\n result.push(renderControl(control));\n }\n\n i++;\n }\n\n return result;\n };\n\n return (\n <Folder title={panel.name} defaultOpen={true} isRoot={true} panelId={panel.id}>\n {renderControls()}\n </Folder>\n );\n}\n","interface ButtonGroupProps {\n buttons: Array<{\n label: string;\n onClick: () => void;\n }>;\n}\n\nexport function ButtonGroup({ buttons }: ButtonGroupProps) {\n return (\n <div className=\"dialkit-button-group\">\n {buttons.map((button, index) => (\n <button\n key={index}\n className=\"dialkit-button\"\n onClick={button.onClick}\n >\n {button.label}\n </button>\n ))}\n </div>\n );\n}\n"],"mappings":"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","names":["useEffect","useState","useRef","useState","useEffect","motion","jsx","jsxs","useRef","useState","motion","jsx","jsxs","jsx","jsxs","jsx","jsxs","useSyncExternalStore","jsx","jsxs","useSyncExternalStore","jsx","jsxs","jsx","useState","useEffect","jsx"]}
@@ -0,0 +1,488 @@
1
+ /* Dialkit Theme - Dark glassmorphic design */
2
+ .dialkit-root {
3
+ /* Surfaces */
4
+ --dial-surface: rgba(255, 255, 255, 0.05);
5
+ --dial-surface-hover: rgba(255, 255, 255, 0.1);
6
+ --dial-surface-active: rgba(255, 255, 255, 0.11);
7
+
8
+ /* Text hierarchy - 3 levels */
9
+ --dial-text-root: #FFFFFF; /* Root title */
10
+ --dial-text-section: rgba(255, 255, 255, 0.7); /* Section titles + carets */
11
+ --dial-text-label: rgba(255, 255, 255, 0.7); /* Input labels */
12
+
13
+ /* Legacy aliases */
14
+ --dial-text-primary: rgba(255, 255, 255, 0.95);
15
+ --dial-text-secondary: rgba(255, 255, 255, 0.6);
16
+ --dial-text-tertiary: rgba(255, 255, 255, 0.4);
17
+
18
+ /* Borders */
19
+ --dial-border: rgba(255, 255, 255, 0.1);
20
+ --dial-border-hover: rgba(255, 255, 255, 0.15);
21
+
22
+ /* Glassmorphic panel */
23
+ --dial-glass-bg: #212121;
24
+ --dial-backdrop-blur: 20px;
25
+ --dial-radius: 8px;
26
+ --dial-shadow: 0 8px 32px rgba(0, 0, 0, 0.5);
27
+
28
+ /* Fonts */
29
+ font-family: system-ui, -apple-system, 'SF Pro Display', sans-serif;
30
+ -webkit-font-smoothing: antialiased;
31
+ -moz-osx-font-smoothing: grayscale;
32
+ }
33
+
34
+ .dialkit-panel {
35
+ position: fixed;
36
+ z-index: 9999;
37
+ max-height: calc(100vh - 32px);
38
+ overflow: visible;
39
+ }
40
+
41
+ .dialkit-panel-inner {
42
+ background: var(--dial-glass-bg);
43
+ border: 1px solid var(--dial-border);
44
+ border-radius: 14px;
45
+ backdrop-filter: blur(var(--dial-backdrop-blur));
46
+ -webkit-backdrop-filter: blur(var(--dial-backdrop-blur));
47
+ padding: 10px 12px 12px 12px;
48
+ transform: translateZ(0);
49
+ max-height: calc(100vh - 32px);
50
+ overflow-y: auto;
51
+ }
52
+
53
+
54
+ .dialkit-panel-inner[data-collapsed="true"] .dialkit-folder-root > .dialkit-folder-header {
55
+ padding-bottom: 0;
56
+ margin-bottom: 0;
57
+ border-bottom: none;
58
+ }
59
+
60
+ .dialkit-panel-inner::-webkit-scrollbar {
61
+ display: none;
62
+ }
63
+
64
+ .dialkit-panel-inner {
65
+ -ms-overflow-style: none;
66
+ scrollbar-width: none;
67
+ }
68
+
69
+ /* Position variants */
70
+ .dialkit-panel[data-position="top-right"] {
71
+ top: 16px;
72
+ right: 16px;
73
+ }
74
+
75
+ .dialkit-panel[data-position="top-left"] {
76
+ top: 16px;
77
+ left: 16px;
78
+ }
79
+
80
+ .dialkit-panel[data-position="bottom-right"] {
81
+ bottom: 16px;
82
+ right: 16px;
83
+ }
84
+
85
+ .dialkit-panel[data-position="bottom-left"] {
86
+ bottom: 16px;
87
+ left: 16px;
88
+ }
89
+
90
+ /* Folder */
91
+ .dialkit-folder {
92
+ padding-bottom: 8px;
93
+ margin-bottom: 8px;
94
+ border-bottom: 1px solid rgba(255, 255, 255, 0.06);
95
+ }
96
+
97
+ .dialkit-folder:last-child:not(.dialkit-folder-root) {
98
+ padding-bottom: 0;
99
+ margin-bottom: 0;
100
+ border-bottom: none;
101
+ }
102
+
103
+ .dialkit-folder-root {
104
+ padding-bottom: 0;
105
+ margin-bottom: 0;
106
+ border-bottom: none;
107
+ }
108
+
109
+ .dialkit-folder-root > .dialkit-folder-header {
110
+ padding-bottom: 12px;
111
+ margin-bottom: 12px;
112
+ border-bottom: 1px solid rgba(255, 255, 255, 0.06);
113
+ }
114
+
115
+ .dialkit-folder-header {
116
+ display: flex;
117
+ align-items: center;
118
+ justify-content: space-between;
119
+ padding: 0 0px 8px 0px;
120
+ cursor: pointer;
121
+ user-select: none;
122
+ }
123
+
124
+
125
+ .dialkit-folder-title {
126
+ font-size: 13px;
127
+ font-weight: 600;
128
+ color: var(--dial-text-section);
129
+ letter-spacing: -0.01em;
130
+ transition: color 0.15s;
131
+ }
132
+
133
+ .dialkit-folder-title-root {
134
+ font-size: 15px;
135
+ font-weight: 600;
136
+ color: var(--dial-text-root);
137
+ transform: translateZ(0);
138
+ }
139
+
140
+ .dialkit-folder-title-row {
141
+ display: flex;
142
+ align-items: center;
143
+ gap: 6px;
144
+ white-space: nowrap;
145
+ overflow: hidden;
146
+ }
147
+
148
+ .dialkit-folder-copy {
149
+ display: flex;
150
+ align-items: center;
151
+ justify-content: center;
152
+ width: 20px;
153
+ height: 20px;
154
+ padding: 0;
155
+ background: transparent;
156
+ border: none;
157
+ cursor: pointer;
158
+ }
159
+
160
+ .dialkit-folder-copy svg {
161
+ width: 14px;
162
+ height: 14px;
163
+ color: var(--dial-text-section);
164
+ }
165
+
166
+ .dialkit-folder-icon {
167
+ width: 14px;
168
+ height: 14px;
169
+ color: var(--dial-text-section);
170
+ opacity: 0.5;
171
+ transition: color 0.15s;
172
+ }
173
+
174
+ .dialkit-folder-content {
175
+ overflow: hidden;
176
+ }
177
+
178
+ .dialkit-folder-inner {
179
+ display: flex;
180
+ flex-direction: column;
181
+ gap: 6px;
182
+ }
183
+
184
+ /* Non-root folder header - no bottom padding, spacing handled by content */
185
+ .dialkit-folder:not(.dialkit-folder-root) > .dialkit-folder-header {
186
+ padding-bottom: 0;
187
+ }
188
+
189
+ /* Non-root folder when CLOSED - even spacing above and below title */
190
+ .dialkit-folder:not(.dialkit-folder-root):not(:has(.dialkit-folder-content)) {
191
+ padding-bottom: 14px;
192
+ }
193
+
194
+ /* Non-root folder when OPEN - 16px before the divider */
195
+ .dialkit-folder:not(.dialkit-folder-root):has(.dialkit-folder-content) {
196
+ padding-bottom: 16px;
197
+ }
198
+
199
+ /* Content padding - 8px between title and first item */
200
+ .dialkit-folder:not(.dialkit-folder-root) .dialkit-folder-inner {
201
+ padding-top: 8px;
202
+ }
203
+
204
+
205
+ /* Slider */
206
+ .dialkit-slider {
207
+ position: relative;
208
+ height: 36px;
209
+ cursor: pointer;
210
+ user-select: none;
211
+ overflow: hidden;
212
+ background: var(--dial-surface);
213
+ border-radius: var(--dial-radius);
214
+ }
215
+
216
+ .dialkit-slider-hashmarks {
217
+ position: absolute;
218
+ inset: 0;
219
+ display: flex;
220
+ align-items: center;
221
+ justify-content: space-between;
222
+ padding: 0 12.5%;
223
+ pointer-events: none;
224
+ }
225
+
226
+ .dialkit-slider-hashmark {
227
+ font-size: 8px;
228
+ color: rgba(255, 255, 255, 0);
229
+ transition: color 0.15s;
230
+ }
231
+
232
+ .dialkit-slider-active .dialkit-slider-hashmark {
233
+ color: rgba(255, 255, 255, 0.1);
234
+ }
235
+
236
+ .dialkit-slider-fill {
237
+ position: absolute;
238
+ top: 0;
239
+ bottom: 0;
240
+ left: 0;
241
+ transition: background 0.15s;
242
+ pointer-events: none;
243
+ }
244
+
245
+ .dialkit-slider-handle {
246
+ position: absolute;
247
+ top: 50%;
248
+ transform: translateY(-50%);
249
+ width: 2px;
250
+ height: 20px;
251
+ border-radius: 1px;
252
+ transition: background 0.15s;
253
+ pointer-events: none;
254
+ }
255
+
256
+ .dialkit-slider-label {
257
+ position: absolute;
258
+ left: 10px;
259
+ top: 50%;
260
+ transform: translateY(-50%);
261
+ font-size: 13px;
262
+ font-weight: 500;
263
+ color: var(--dial-text-label);
264
+ pointer-events: none;
265
+ transition: color 0.15s;
266
+ }
267
+
268
+ .dialkit-slider-value {
269
+ position: absolute;
270
+ right: 10px;
271
+ top: 50%;
272
+ transform: translateY(-50%);
273
+ font-size: 13px;
274
+ font-weight: 500;
275
+ font-family: ui-monospace, 'SF Mono', 'Courier New', monospace;
276
+ color: var(--dial-text-label);
277
+ pointer-events: auto;
278
+ transition: color 0.15s, border-color 0.15s;
279
+ border-bottom: 1px solid transparent;
280
+ padding-bottom: 1px;
281
+ }
282
+
283
+ .dialkit-slider-value-editable {
284
+ border-bottom-color: var(--dial-text-label);
285
+ }
286
+
287
+ .dialkit-slider-input {
288
+ position: absolute;
289
+ right: 10px;
290
+ top: 50%;
291
+ transform: translateY(-50%);
292
+ width: 4ch;
293
+ min-width: 3ch;
294
+ max-width: 6ch;
295
+ font-size: 13px;
296
+ font-weight: 500;
297
+ font-family: ui-monospace, 'SF Mono', 'Courier New', monospace;
298
+ color: var(--dial-text-label);
299
+ background: transparent;
300
+ border: none;
301
+ border-bottom: 1px solid var(--dial-text-label);
302
+ padding: 0 0 1px 0;
303
+ outline: none;
304
+ text-align: right;
305
+ }
306
+
307
+ /* Segmented Control */
308
+ .dialkit-segmented {
309
+ position: relative;
310
+ display: flex;
311
+ padding: 2px;
312
+ background: var(--dial-surface);
313
+ border-radius: var(--dial-radius);
314
+ }
315
+
316
+ .dialkit-segmented-pill {
317
+ position: absolute;
318
+ top: 2px;
319
+ bottom: 2px;
320
+ background: var(--dial-surface-active);
321
+ border-radius: 6px;
322
+ z-index: 0;
323
+ pointer-events: none;
324
+ }
325
+
326
+ .dialkit-segmented-button {
327
+ position: relative;
328
+ z-index: 1;
329
+ flex: 1;
330
+ padding: 8px 16px;
331
+ font-family: inherit;
332
+ font-size: 13px;
333
+ font-weight: 500;
334
+ background: transparent;
335
+ border: none;
336
+ cursor: pointer;
337
+ transition: color 0.15s;
338
+ }
339
+
340
+ .dialkit-segmented-button[data-active="true"] {
341
+ color: rgba(255, 255, 255, 0.8);
342
+ }
343
+
344
+ .dialkit-segmented-button[data-active="false"] {
345
+ color: var(--dial-text-label);
346
+ }
347
+
348
+ /* Toggle */
349
+ .dialkit-toggle {
350
+ display: flex;
351
+ align-items: center;
352
+ justify-content: space-between;
353
+ padding: 10px 16px;
354
+ background: var(--dial-surface);
355
+ border-radius: var(--dial-radius);
356
+ cursor: pointer;
357
+ user-select: none;
358
+ transition: background 0.15s;
359
+ }
360
+
361
+ .dialkit-toggle:hover {
362
+ background: var(--dial-surface-hover);
363
+ }
364
+
365
+ .dialkit-toggle-label {
366
+ font-size: 13px;
367
+ font-weight: 500;
368
+ color: var(--dial-text-label);
369
+ transition: color 0.15s;
370
+ }
371
+
372
+ .dialkit-toggle[data-checked="true"] .dialkit-toggle-label {
373
+ color: var(--dial-text-primary);
374
+ }
375
+
376
+ .dialkit-toggle-track {
377
+ width: 36px;
378
+ height: 20px;
379
+ border-radius: 10px;
380
+ background: var(--dial-surface-active);
381
+ transition: background 0.2s;
382
+ position: relative;
383
+ }
384
+
385
+ .dialkit-toggle[data-checked="true"] .dialkit-toggle-track {
386
+ background: rgba(255, 255, 255, 0.3);
387
+ }
388
+
389
+ .dialkit-toggle-thumb {
390
+ position: absolute;
391
+ top: 2px;
392
+ width: 16px;
393
+ height: 16px;
394
+ border-radius: 8px;
395
+ background: rgba(255, 255, 255, 0.8);
396
+ }
397
+
398
+ /* Button Group */
399
+ .dialkit-button-group {
400
+ display: flex;
401
+ gap: 6px;
402
+ }
403
+
404
+ .dialkit-button {
405
+ flex: 1;
406
+ padding: 10px 16px;
407
+ font-family: inherit;
408
+ font-size: 13px;
409
+ font-weight: 500;
410
+ color: var(--dial-text-secondary);
411
+ background: var(--dial-surface);
412
+ border: none;
413
+ border-radius: var(--dial-radius);
414
+ cursor: pointer;
415
+ transition: background 0.15s, color 0.15s;
416
+ }
417
+
418
+ .dialkit-button:hover {
419
+ background: var(--dial-surface-hover);
420
+ color: var(--dial-text-primary);
421
+ }
422
+
423
+ .dialkit-button:active {
424
+ background: var(--dial-surface-active);
425
+ }
426
+
427
+ /* Labeled Control Row (label + control side by side) */
428
+ .dialkit-labeled-control {
429
+ display: flex;
430
+ align-items: center;
431
+ justify-content: space-between;
432
+ gap: 12px;
433
+ }
434
+
435
+ .dialkit-labeled-control-label {
436
+ font-size: 13px;
437
+ font-weight: 500;
438
+ color: var(--dial-text-label);
439
+ flex-shrink: 0;
440
+ }
441
+
442
+ .dialkit-labeled-control .dialkit-segmented {
443
+ width: 160px;
444
+ flex-shrink: 0;
445
+ }
446
+
447
+ .dialkit-action-button {
448
+ width: 160px;
449
+ flex-shrink: 0;
450
+ padding: 10px 16px;
451
+ font-family: inherit;
452
+ font-size: 13px;
453
+ font-weight: 500;
454
+ color: var(--dial-text-secondary);
455
+ background: var(--dial-surface);
456
+ border: none;
457
+ border-radius: var(--dial-radius);
458
+ cursor: pointer;
459
+ transition: background 0.15s, color 0.15s;
460
+ }
461
+
462
+ .dialkit-action-button:hover {
463
+ background: var(--dial-surface-hover);
464
+ color: var(--dial-text-primary);
465
+ }
466
+
467
+ .dialkit-action-button:active {
468
+ background: var(--dial-surface-active);
469
+ }
470
+
471
+ .dialkit-actions-group {
472
+ align-items: flex-start;
473
+ }
474
+
475
+ .dialkit-actions-stack {
476
+ display: flex;
477
+ flex-direction: column;
478
+ gap: 6px;
479
+ width: 160px;
480
+ }
481
+
482
+ /* Spring Visualization */
483
+ .dialkit-spring-viz {
484
+ width: 100%;
485
+ border-radius: var(--dial-radius);
486
+ background: var(--dial-surface);
487
+ overflow: visible;
488
+ }