@biela.dev/core 1.7.4 → 1.7.6

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/lite.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/math/conversions.ts","../src/math/scale-engine.ts","../src/hooks/useContainerSize.ts","../src/hooks/useAdaptiveScale.ts","../src/hooks/useDeviceContract.ts","../src/hooks/useVolumeControl.ts","../src/hooks/useScreenPower.ts","../src/hooks/useOrientation.ts","../src/components/ErrorBoundary.tsx","../src/components/SafeAreaOverlay.tsx","../src/components/ScaleBar.tsx","../src/components/DeviceFrame.tsx","../src/components/DeviceCompare.tsx","../src/components/SafeAreaView.tsx","../src/components/VolumeHUD.tsx","../src/components/HardwareButtons.tsx","../src/components/DynamicStatusBar.tsx","../src/components/StatusBarIndicators.tsx","../src/storage/CustomSVGStore.ts"],"names":["useMemo","useState","useEffect","useCallback","jsxs","jsx","useRef","contract","getDeviceContract","Fragment","getDeviceMetadata"],"mappings":"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","file":"lite.js","sourcesContent":["/**\n * Design token dimension math — conversion utilities.\n * All device dimensions are in logical points (CSS pixels at 1x).\n */\n\n/** Convert logical points to physical pixels */\nexport function ptsToPx(pts: number, dpr: number): number {\n return Math.round(pts * dpr);\n}\n\n/** Convert physical pixels to logical points */\nexport function pxToPts(px: number, dpr: number): number {\n return px / dpr;\n}\n\n/** Convert points to percentage of a total dimension */\nexport function ptsToPercent(pts: number, total: number): number {\n if (total === 0) return 0;\n return (pts / total) * 100;\n}\n\n/** Apply uniform scale factor to any dimension value */\nexport function scaleValue(value: number, scaleFactor: number): number {\n return value * scaleFactor;\n}\n","/**\n * Scale Engine Math — mirrors Xcode Simulator \"fit to screen\" behavior.\n *\n * Rules:\n * 1. Inner content ALWAYS at 1:1 logical point size\n * 2. Scale derived from available container space, never hardcoded\n * 3. SVG frame chrome scales WITH content as one atomic unit\n * 4. Host layout reserves SCALED dimensions\n * 5. Maximum scale always 1.0 — never larger than the real device\n */\n\n/** Discrete scale steps matching Xcode Simulator presets */\nexport const SCALE_STEPS = [0.25, 0.33, 0.5, 0.75, 1.0] as const;\n\n/**\n * Compute the adaptive scale factor for a device in a given container.\n * Mirrors Xcode \"fit to screen\" exactly.\n *\n * @param deviceWidth - Logical points width of the device screen\n * @param deviceHeight - Logical points height of the device screen\n * @param containerWidth - Available CSS px width of the host container\n * @param containerHeight - Available CSS px height of the host container\n * @param padding - Breathing room in px (subtracted from each side)\n * @param maxScale - Upper cap — never exceed 1.0 (real device size)\n * @param minScale - Lower floor — prevent invisibly small render\n */\nexport function computeAdaptiveScale(\n deviceWidth: number,\n deviceHeight: number,\n containerWidth: number,\n containerHeight: number,\n padding: number = 24,\n maxScale: number = 1.0,\n minScale: number = 0.1,\n): number {\n const availW = containerWidth - padding * 2;\n const availH = containerHeight - padding * 2;\n\n if (availW <= 0 || availH <= 0) return minScale;\n\n const scaleW = availW / deviceWidth;\n const scaleH = availH / deviceHeight;\n const raw = Math.min(scaleW, scaleH, maxScale);\n\n return Math.max(raw, minScale);\n}\n\n/**\n * Snap a raw scale to the nearest discrete step that does not exceed it.\n * Fixed version: filters steps to only those <= raw, takes max.\n * Falls back to raw if no step qualifies.\n */\nexport function snapToStep(raw: number): number {\n const valid = SCALE_STEPS.filter((s) => s <= raw + 0.001); // tiny epsilon for floating point\n if (valid.length === 0) return raw;\n return valid[valid.length - 1]!; // steps are sorted ascending, last valid is the largest\n}\n\n/**\n * Derive host container size from device dimensions + scale.\n * The host div occupies these dimensions in normal document flow.\n */\nexport function computeHostSize(\n deviceWidth: number,\n deviceHeight: number,\n scale: number,\n): { width: number; height: number } {\n return {\n width: Math.round(deviceWidth * scale),\n height: Math.round(deviceHeight * scale),\n };\n}\n\n/** Result returned by the scale computation */\nexport interface AdaptiveScaleResult {\n /** Computed scale factor e.g. 0.735 */\n scale: number;\n /** Host container width = deviceWidth * scale */\n scaledWidth: number;\n /** Host container height = deviceHeight * scale */\n scaledHeight: number;\n /** Raw logical pts — scaler div width */\n deviceWidth: number;\n /** Raw logical pts — scaler div height */\n deviceHeight: number;\n /** True when scale === maxScale (showing at real size) */\n isAtMaxScale: boolean;\n /** True when scale < maxScale (container is limiting) */\n isConstrained: boolean;\n /** Display string e.g. \"73%\" */\n scalePercent: string;\n}\n\n/**\n * Full scale computation returning all derived values.\n */\nexport function computeFullScale(\n deviceWidth: number,\n deviceHeight: number,\n containerWidth: number,\n containerHeight: number,\n options: {\n padding?: number;\n maxScale?: number;\n minScale?: number;\n snapToSteps?: boolean;\n } = {},\n): AdaptiveScaleResult {\n const { padding = 24, maxScale = 1.0, minScale = 0.1, snapToSteps = false } = options;\n\n let scale = computeAdaptiveScale(\n deviceWidth,\n deviceHeight,\n containerWidth,\n containerHeight,\n padding,\n maxScale,\n minScale,\n );\n\n if (snapToSteps) {\n scale = snapToStep(scale);\n }\n\n const { width: scaledWidth, height: scaledHeight } = computeHostSize(\n deviceWidth,\n deviceHeight,\n scale,\n );\n\n return {\n scale,\n scaledWidth,\n scaledHeight,\n deviceWidth,\n deviceHeight,\n isAtMaxScale: scale >= maxScale - 0.001,\n isConstrained: scale < maxScale - 0.001,\n scalePercent: `${Math.round(scale * 100)}%`,\n };\n}\n","import { useState, useEffect, type RefObject } from \"react\";\n\ninterface ContainerSize {\n width: number;\n height: number;\n}\n\n/**\n * Observes an element's content box dimensions via ResizeObserver.\n * Foundation of adaptive scaling — same mechanism as Xcode's window resize detection.\n * Uses the actual canvas div, not the window, so it's panel-independent.\n *\n * Safety: clamps reported size to the visual viewport so that a mis-sized\n * parent (e.g. height: auto or height: 100% with no fixed ancestor) can never\n * cause the device frame to render larger than the screen.\n */\nexport function useContainerSize(ref: RefObject<HTMLElement | null>): ContainerSize {\n const [size, setSize] = useState<ContainerSize>({ width: 0, height: 0 });\n\n useEffect(() => {\n const el = ref.current;\n if (!el) return;\n\n const observer = new ResizeObserver(([entry]) => {\n if (!entry) return;\n let { width, height } = entry.contentRect;\n\n // Clamp to viewport — prevents oversized rendering when parent\n // has no explicit height constraint (common AI-generated code mistake)\n if (typeof window !== \"undefined\") {\n width = Math.min(width, window.innerWidth);\n height = Math.min(height, window.innerHeight);\n }\n\n setSize((prev) => {\n if (prev.width === width && prev.height === height) return prev;\n return { width, height };\n });\n });\n\n observer.observe(el);\n return () => observer.disconnect();\n }, [ref]);\n\n return size;\n}\n","import { useMemo } from \"react\";\nimport { computeFullScale, type AdaptiveScaleResult } from \"../math/scale-engine\";\nimport type { DeviceMeta } from \"@biela.dev/devices\";\n\nexport interface UseAdaptiveScaleOptions {\n /** Device metadata (screen dimensions) */\n device: DeviceMeta;\n /** Container width from useContainerSize */\n containerWidth: number;\n /** Container height from useContainerSize */\n containerHeight: number;\n /** Breathing room in px (default: 24) */\n padding?: number;\n /** Upper cap — never exceed 1.0 (default: 1.0) */\n maxScale?: number;\n /** Lower floor (default: 0.1) */\n minScale?: number;\n /** Snap to discrete 25/33/50/75/100% steps (default: false) */\n snapToSteps?: boolean;\n}\n\n/**\n * Full adaptive scale hook — mirrors Xcode \"fit to screen\".\n * Recalculates live as container resizes via ResizeObserver.\n */\nexport function useAdaptiveScale(options: UseAdaptiveScaleOptions): AdaptiveScaleResult {\n const {\n device,\n containerWidth,\n containerHeight,\n padding = 24,\n maxScale = 1.0,\n minScale = 0.1,\n snapToSteps = false,\n } = options;\n\n return useMemo(\n () =>\n computeFullScale(device.screen.width, device.screen.height, containerWidth, containerHeight, {\n padding,\n maxScale,\n minScale,\n snapToSteps,\n }),\n [device.screen.width, device.screen.height, containerWidth, containerHeight, padding, maxScale, minScale, snapToSteps],\n );\n}\n","import { useMemo } from \"react\";\nimport type { DeviceLayoutContract } from \"@biela.dev/devices\";\nimport { getDeviceContract } from \"@biela.dev/devices\";\n\ninterface UseDeviceContractResult {\n contract: DeviceLayoutContract;\n cssVariables: DeviceLayoutContract[\"cssVariables\"];\n contentZone: DeviceLayoutContract[\"contentZone\"][\"portrait\"];\n}\n\n/**\n * Hook to access the Device Layout Contract for a given device.\n * Returns the contract, CSS variables, and content zone for the current orientation.\n */\nexport function useDeviceContract(\n deviceId: string,\n orientation: \"portrait\" | \"landscape\" = \"portrait\",\n): UseDeviceContractResult {\n return useMemo(() => {\n const contract = getDeviceContract(deviceId, orientation);\n return {\n contract,\n cssVariables: contract.cssVariables,\n contentZone: contract.contentZone[orientation],\n };\n }, [deviceId, orientation]);\n}\n","import { useState, useCallback, useRef, useEffect } from \"react\";\n\nexport interface VolumeState {\n /** Current volume level 0–1 (16 steps, each = 1/16) */\n level: number;\n /** Is audio muted? */\n muted: boolean;\n /** Should the HUD be visible? */\n hudVisible: boolean;\n /** Increase volume by one step */\n volumeUp: () => void;\n /** Decrease volume by one step */\n volumeDown: () => void;\n /** Toggle mute */\n toggleMute: () => void;\n}\n\nconst STEPS = 16;\nconst STEP_SIZE = 1 / STEPS;\nconst HUD_DISPLAY_MS = 1500;\n\n/**\n * Volume control hook — 16-step volume with auto-hiding HUD.\n * Applies volume to all <audio> and <video> elements inside `.bielaframe-content`.\n */\nexport function useVolumeControl(initialVolume = 1): VolumeState {\n const [level, setLevel] = useState(initialVolume);\n const [muted, setMuted] = useState(false);\n const [hudVisible, setHudVisible] = useState(false);\n const hudTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const showHud = useCallback(() => {\n setHudVisible(true);\n if (hudTimerRef.current) clearTimeout(hudTimerRef.current);\n hudTimerRef.current = setTimeout(() => setHudVisible(false), HUD_DISPLAY_MS);\n }, []);\n\n const volumeUp = useCallback(() => {\n setLevel((prev) => {\n const next = Math.min(1, Math.round((prev + STEP_SIZE) * STEPS) / STEPS);\n return next;\n });\n setMuted(false);\n showHud();\n }, [showHud]);\n\n const volumeDown = useCallback(() => {\n setLevel((prev) => {\n const next = Math.max(0, Math.round((prev - STEP_SIZE) * STEPS) / STEPS);\n return next;\n });\n setMuted(false);\n showHud();\n }, [showHud]);\n\n const toggleMute = useCallback(() => {\n setMuted((prev) => !prev);\n showHud();\n }, [showHud]);\n\n // Apply volume to media elements\n const effectiveVolume = muted ? 0 : level;\n useEffect(() => {\n const container = document.querySelector(\".bielaframe-content\");\n if (!container) return;\n const mediaEls = container.querySelectorAll(\"audio, video\");\n mediaEls.forEach((el) => {\n (el as HTMLMediaElement).volume = effectiveVolume;\n });\n }, [effectiveVolume]);\n\n // Cleanup timer\n useEffect(() => {\n return () => {\n if (hudTimerRef.current) clearTimeout(hudTimerRef.current);\n };\n }, []);\n\n return { level, muted, hudVisible, volumeUp, volumeDown, toggleMute };\n}\n","import { useState, useCallback } from \"react\";\n\nexport interface ScreenPowerState {\n /** Is the screen off? */\n isOff: boolean;\n /** Toggle screen on/off */\n toggle: () => void;\n}\n\n/**\n * Screen power hook — manages on/off state for the power button.\n */\nexport function useScreenPower(): ScreenPowerState {\n const [isOff, setIsOff] = useState(false);\n\n const toggle = useCallback(() => {\n setIsOff((prev) => !prev);\n }, []);\n\n return { isOff, toggle };\n}\n","import { useState, useCallback } from \"react\";\n\nexport interface UseOrientationResult {\n /** Current orientation */\n orientation: \"portrait\" | \"landscape\";\n /** Convenience boolean */\n isLandscape: boolean;\n /** Toggle between portrait and landscape */\n toggle: () => void;\n /** Set orientation directly */\n setOrientation: (o: \"portrait\" | \"landscape\") => void;\n}\n\n/**\n * Hook for managing device orientation state with a toggle function.\n *\n * ```tsx\n * const { orientation, toggle } = useOrientation();\n * <button onClick={toggle}>Rotate</button>\n * <DeviceFrame deviceId=\"iphone-17-pro\" orientation={orientation} />\n * ```\n */\nexport function useOrientation(\n initial: \"portrait\" | \"landscape\" = \"portrait\",\n): UseOrientationResult {\n const [orientation, setOrientation] = useState<\"portrait\" | \"landscape\">(initial);\n\n const toggle = useCallback(\n () => setOrientation((o) => (o === \"portrait\" ? \"landscape\" : \"portrait\")),\n [],\n );\n\n return {\n orientation,\n isLandscape: orientation === \"landscape\",\n toggle,\n setOrientation,\n };\n}\n","import { Component, type ErrorInfo, type ReactNode } from \"react\";\n\ninterface Props {\n children: ReactNode;\n fallback?: ReactNode;\n}\n\ninterface State {\n hasError: boolean;\n error: Error | null;\n}\n\n/**\n * Error Boundary wrapping the children slot in DeviceFrame.\n * AI-generated components will crash — this catches them gracefully\n * and renders a fallback inside the device screen area.\n */\nexport class DeviceErrorBoundary extends Component<Props, State> {\n constructor(props: Props) {\n super(props);\n this.state = { hasError: false, error: null };\n }\n\n static getDerivedStateFromError(error: Error): State {\n return { hasError: true, error };\n }\n\n componentDidCatch(error: Error, errorInfo: ErrorInfo): void {\n console.error(\"[BielaFrame] Component error caught by boundary:\", error, errorInfo);\n }\n\n render(): ReactNode {\n if (this.state.hasError) {\n if (this.props.fallback) return this.props.fallback;\n\n return (\n <div\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n width: \"100%\",\n height: \"100%\",\n padding: \"24px\",\n fontFamily: \"-apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif\",\n color: \"#ef4444\",\n backgroundColor: \"#1a1a1a\",\n textAlign: \"center\",\n }}\n >\n <div style={{ fontSize: \"32px\", marginBottom: \"12px\" }}>!</div>\n <div style={{ fontSize: \"14px\", fontWeight: 600, marginBottom: \"8px\" }}>\n Component Error\n </div>\n <div style={{ fontSize: \"11px\", color: \"#888\", maxWidth: \"280px\", lineHeight: 1.4 }}>\n {this.state.error?.message ?? \"An unexpected error occurred in the rendered component.\"}\n </div>\n </div>\n );\n }\n\n return this.props.children;\n }\n}\n","import type { CSSProperties } from \"react\";\nimport type { DeviceLayoutContract } from \"@biela.dev/devices\";\n\ninterface SafeAreaOverlayProps {\n contract: DeviceLayoutContract;\n orientation: \"portrait\" | \"landscape\";\n}\n\n/**\n * Dev overlay showing safe zones when showSafeAreaOverlay={true}.\n * Does NOT affect layout — position: absolute, pointerEvents: none.\n *\n * Colors:\n * - Red: status bar zone + home indicator zone (restricted)\n * - Orange: hardware overlay (Dynamic Island / punch-hole)\n * - Green: content zone (usable area)\n * - White dimension labels at each edge\n */\nexport function SafeAreaOverlay({ contract, orientation }: SafeAreaOverlayProps) {\n const sa = contract.safeArea[orientation];\n const cz = contract.contentZone[orientation];\n const screen = contract.screen;\n const overlay = contract.hardwareOverlays;\n\n const base: CSSProperties = {\n position: \"absolute\",\n pointerEvents: \"none\",\n boxSizing: \"border-box\",\n };\n\n const labelStyle: CSSProperties = {\n position: \"absolute\",\n fontSize: \"9px\",\n fontFamily: \"monospace\",\n color: \"white\",\n textShadow: \"0 1px 2px rgba(0,0,0,0.8)\",\n whiteSpace: \"nowrap\",\n };\n\n return (\n <div\n style={{\n position: \"absolute\",\n inset: 0,\n pointerEvents: \"none\",\n zIndex: 20,\n }}\n >\n {/* Status bar zone — red */}\n <div\n style={{\n ...base,\n top: 0,\n left: 0,\n right: 0,\n height: `${contract.statusBar.height}px`,\n backgroundColor: \"rgba(239, 68, 68, 0.25)\",\n borderBottom: \"1px dashed rgba(239, 68, 68, 0.6)\",\n }}\n >\n <span style={{ ...labelStyle, top: \"2px\", left: \"4px\" }}>\n status: {contract.statusBar.height}pt\n </span>\n </div>\n\n {/* Hardware overlay — orange */}\n {overlay.type !== \"none\" && (\n <div\n style={{\n ...base,\n left: `${overlay.portrait.x}px`,\n top: `${overlay.portrait.y}px`,\n width: `${overlay.portrait.width}px`,\n height: `${overlay.portrait.height}px`,\n backgroundColor: \"rgba(249, 115, 22, 0.35)\",\n border: \"1px solid rgba(249, 115, 22, 0.7)\",\n borderRadius:\n overlay.portrait.shape === \"pill\"\n ? `${overlay.portrait.height / 2}px`\n : overlay.portrait.shape === \"circle\"\n ? \"50%\"\n : \"4px\",\n }}\n >\n <span style={{ ...labelStyle, top: \"-14px\", left: \"0px\" }}>\n {overlay.type}: {overlay.portrait.width}×{overlay.portrait.height}\n </span>\n </div>\n )}\n\n {/* Safe area top — red strip below status bar to safe-top */}\n {sa.top > contract.statusBar.height && (\n <div\n style={{\n ...base,\n top: `${contract.statusBar.height}px`,\n left: 0,\n right: 0,\n height: `${sa.top - contract.statusBar.height}px`,\n backgroundColor: \"rgba(239, 68, 68, 0.15)\",\n borderBottom: \"1px dashed rgba(239, 68, 68, 0.4)\",\n }}\n />\n )}\n\n {/* Content zone — green */}\n <div\n style={{\n ...base,\n left: `${cz.x}px`,\n top: `${cz.y}px`,\n width: `${cz.width}px`,\n height: `${cz.height}px`,\n backgroundColor: \"rgba(34, 197, 94, 0.08)\",\n border: \"1px dashed rgba(34, 197, 94, 0.4)\",\n }}\n >\n <span style={{ ...labelStyle, bottom: \"2px\", right: \"4px\" }}>\n content: {cz.width}×{cz.height}pt\n </span>\n </div>\n\n {/* Home indicator zone — red */}\n {sa.bottom > 0 && (\n <div\n style={{\n ...base,\n bottom: 0,\n left: 0,\n right: 0,\n height: `${sa.bottom}px`,\n backgroundColor: \"rgba(239, 68, 68, 0.25)\",\n borderTop: \"1px dashed rgba(239, 68, 68, 0.6)\",\n }}\n >\n <span style={{ ...labelStyle, bottom: \"2px\", right: \"4px\" }}>\n bottom: {sa.bottom}pt\n </span>\n </div>\n )}\n\n {/* Safe area dimension labels */}\n <span style={{ ...labelStyle, top: `${sa.top + 2}px`, left: \"4px\" }}>\n safe-top: {sa.top}pt\n </span>\n <span style={{ ...labelStyle, bottom: `${sa.bottom + 2}px`, left: \"4px\" }}>\n safe-bottom: {sa.bottom}pt\n </span>\n\n {/* Screen dimensions label */}\n <span\n style={{\n ...labelStyle,\n top: \"50%\",\n left: \"50%\",\n transform: \"translate(-50%, -50%)\",\n fontSize: \"11px\",\n backgroundColor: \"rgba(0,0,0,0.6)\",\n padding: \"2px 6px\",\n borderRadius: \"3px\",\n }}\n >\n {screen.width}×{screen.height}pt\n </span>\n </div>\n );\n}\n","interface ScaleBarProps {\n deviceName: string;\n deviceWidth: number;\n deviceHeight: number;\n scale: number;\n scalePercent: string;\n isAtMaxScale: boolean;\n isConstrained: boolean;\n onScaleChange?: (scale: number) => void;\n onFit?: () => void;\n onRealSize?: () => void;\n}\n\n/**\n * Persistent footer below device showing scale state:\n * [ iPhone 16 Pro · 402×874pt | ━━━●━━━━━ 66% | Fit ↗ | 1:1 ]\n *\n * Accessibility:\n * - role=\"slider\" with aria-valuenow on scrubber\n * - aria-label on the component\n * - aria-live=\"polite\" on scale announcements\n */\nexport function ScaleBar({\n deviceName,\n deviceWidth,\n deviceHeight,\n scale,\n scalePercent,\n isAtMaxScale,\n isConstrained,\n onScaleChange,\n onFit,\n onRealSize,\n}: ScaleBarProps) {\n return (\n <div\n aria-label={`Scale bar for ${deviceName}`}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: \"12px\",\n padding: \"6px 12px\",\n marginTop: \"8px\",\n backgroundColor: \"rgba(0, 0, 0, 0.6)\",\n borderRadius: \"8px\",\n fontSize: \"11px\",\n fontFamily: \"-apple-system, BlinkMacSystemFont, 'SF Mono', 'Fira Code', monospace\",\n color: \"#ccc\",\n userSelect: \"none\",\n width: \"fit-content\",\n alignSelf: \"center\",\n }}\n >\n {/* Device name + dimensions */}\n <span style={{ color: \"#fff\", fontWeight: 500 }}>\n {deviceName}\n </span>\n <span style={{ color: \"#666\" }}>·</span>\n <span>{deviceWidth}×{deviceHeight}pt</span>\n <span style={{ color: \"#666\" }}>|</span>\n\n {/* Scale slider */}\n <input\n type=\"range\"\n role=\"slider\"\n aria-label=\"Device scale\"\n aria-valuenow={Math.round(scale * 100)}\n aria-valuemin={10}\n aria-valuemax={100}\n min={10}\n max={100}\n step={1}\n value={Math.round(scale * 100)}\n onChange={(e) => onScaleChange?.(Number(e.target.value) / 100)}\n style={{\n width: \"80px\",\n accentColor: \"#3b82f6\",\n cursor: \"pointer\",\n }}\n />\n\n {/* Scale percentage — announced to screen readers */}\n <span aria-live=\"polite\" style={{ minWidth: \"32px\", textAlign: \"center\", fontWeight: 600 }}>\n {scalePercent}\n </span>\n\n <span style={{ color: \"#666\" }}>|</span>\n\n {/* Fit button */}\n <button\n onClick={onFit}\n aria-label=\"Fit device to container\"\n style={{\n background: isConstrained ? \"rgba(59, 130, 246, 0.2)\" : \"transparent\",\n border: \"1px solid rgba(59, 130, 246, 0.4)\",\n borderRadius: \"4px\",\n color: isConstrained ? \"#60a5fa\" : \"#666\",\n fontSize: \"10px\",\n padding: \"2px 6px\",\n cursor: \"pointer\",\n fontWeight: isConstrained ? 600 : 400,\n }}\n >\n Fit\n </button>\n\n {/* 1:1 button */}\n <button\n onClick={onRealSize}\n aria-label=\"Show at real device size\"\n style={{\n background: isAtMaxScale ? \"rgba(234, 179, 8, 0.2)\" : \"transparent\",\n border: `1px solid ${isAtMaxScale ? \"rgba(234, 179, 8, 0.6)\" : \"rgba(102, 102, 102, 0.4)\"}`,\n borderRadius: \"4px\",\n color: isAtMaxScale ? \"#eab308\" : \"#666\",\n fontSize: \"10px\",\n padding: \"2px 6px\",\n cursor: \"pointer\",\n fontWeight: isAtMaxScale ? 600 : 400,\n }}\n >\n 1:1\n </button>\n </div>\n );\n}\n","import { useRef, useEffect, useMemo, useState, type ReactNode } from \"react\";\nimport type { DeviceLayoutContract, DeviceMeta } from \"@biela.dev/devices\";\nimport { getDeviceContract, getDeviceMetadata, scopeSVGIds } from \"@biela.dev/devices\";\nimport { useContainerSize } from \"../hooks/useContainerSize\";\nimport { useAdaptiveScale } from \"../hooks/useAdaptiveScale\";\nimport { DeviceErrorBoundary } from \"./ErrorBoundary\";\nimport { SafeAreaOverlay } from \"./SafeAreaOverlay\";\nimport { ScaleBar } from \"./ScaleBar\";\n\n/**\n * Resolve device SVG component by ID.\n * This is a lookup registry — devices register their SVG components here.\n */\ntype DeviceSVGComponent = React.ComponentType<{\n colorScheme?: \"light\" | \"dark\";\n style?: React.CSSProperties;\n}>;\n\ninterface FrameInfo {\n bezelTop: number;\n bezelBottom: number;\n bezelLeft: number;\n bezelRight: number;\n totalWidth: number;\n totalHeight: number;\n screenWidth: number;\n screenHeight: number;\n screenRadius: number;\n}\n\nconst SVG_REGISTRY: Record<string, { component: DeviceSVGComponent; frame: FrameInfo }> = {};\n\n/** Register a device SVG component for use with DeviceFrame */\nexport function registerDeviceSVG(\n deviceId: string,\n component: DeviceSVGComponent,\n frame: FrameInfo,\n): void {\n SVG_REGISTRY[deviceId] = { component, frame };\n}\n\n/** Optional crop area to rewrite the SVG viewBox (e.g., to exclude side buttons) */\nexport interface SVGCropArea {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\n/** Screen rectangle in SVG native coordinates — used to punch a transparent hole */\nexport interface SVGScreenRect {\n x: number;\n y: number;\n width: number;\n height: number;\n rx?: number;\n}\n\n/**\n * Register a custom device SVG from a raw SVG string.\n *\n * Creates a React component that renders the SVG with scoped IDs\n * and registers it in the SVG_REGISTRY.\n *\n * The inner <svg> element is rewritten to use width=\"100%\" height=\"100%\"\n * so it fills the parent container (which is sized by the frame info).\n *\n * If `cropViewBox` is provided, the SVG viewBox is set to that area,\n * cropping out external elements like side buttons.\n *\n * If `screenRect` is provided, a mask is injected to punch a transparent\n * hole where the screen is, so content underneath shows through.\n */\nexport function registerCustomDeviceSVG(\n deviceId: string,\n svgString: string,\n frame: FrameInfo,\n cropViewBox?: SVGCropArea,\n screenRect?: SVGScreenRect,\n): void {\n const scopedSVG = scopeSVGIds(svgString, deviceId);\n\n // Rewrite the <svg> tag so it fills its container instead of using its native dimensions.\n let processedSVG = scopedSVG.replace(\n /<svg\\b([^>]*)>/i,\n (_match, attrs: string) => {\n if (cropViewBox) {\n // Replace the viewBox with the crop area to exclude side buttons\n attrs = attrs.replace(/\\bviewBox\\s*=\\s*[\"'][^\"']*[\"']/gi, \"\");\n attrs += ` viewBox=\"${cropViewBox.x} ${cropViewBox.y} ${cropViewBox.width} ${cropViewBox.height}\"`;\n } else if (!/viewBox/i.test(attrs)) {\n // If there's no viewBox, create one from the existing width/height\n const wMatch = attrs.match(/\\bwidth\\s*=\\s*[\"']?(\\d+\\.?\\d*)[\"']?/i);\n const hMatch = attrs.match(/\\bheight\\s*=\\s*[\"']?(\\d+\\.?\\d*)[\"']?/i);\n if (wMatch && hMatch) {\n attrs += ` viewBox=\"0 0 ${wMatch[1]} ${hMatch[1]}\"`;\n }\n }\n\n // Remove any existing width/height attributes\n let cleaned = attrs\n .replace(/\\bwidth\\s*=\\s*[\"'][^\"']*[\"']/gi, \"\")\n .replace(/\\bheight\\s*=\\s*[\"'][^\"']*[\"']/gi, \"\");\n\n // Add preserveAspectRatio if not present\n if (!/preserveAspectRatio/i.test(cleaned)) {\n cleaned += ` preserveAspectRatio=\"xMidYMid meet\"`;\n }\n\n return `<svg${cleaned} width=\"100%\" height=\"100%\">`;\n },\n );\n\n // Make the screen area transparent so content underneath shows through.\n // Strategy: inject an SVG <mask> that hides the screen rectangle area,\n // then apply it to every <rect> that fully covers the screen (body rect, screen rect).\n // Other elements (Dynamic Island, status icons, camera) are NOT masked — they\n // remain fully visible on top, exactly like the real device.\n if (screenRect) {\n const { x: sx, y: sy, width: sw, height: sh, rx: sr } = screenRect;\n const r = sr ?? 0;\n\n // Get viewBox dimensions for the mask\n const vbMatch = processedSVG.match(/viewBox\\s*=\\s*[\"']([^\"']+)[\"']/i);\n let svgW = 10000, svgH = 10000;\n if (vbMatch) {\n const parts = vbMatch[1]!.split(/[\\s,]+/).map(Number);\n if (parts.length >= 4) { svgW = parts[2]!; svgH = parts[3]!; }\n }\n\n // Build SVG mask: white = visible, black = hidden.\n // The mask is white everywhere except the screen rect (which is black).\n const maskId = `${deviceId}__screen-mask`;\n let innerPath: string;\n if (r > 0) {\n innerPath =\n `M${sx + r},${sy} H${sx + sw - r} A${r},${r} 0 0 1 ${sx + sw},${sy + r} ` +\n `V${sy + sh - r} A${r},${r} 0 0 1 ${sx + sw - r},${sy + sh} ` +\n `H${sx + r} A${r},${r} 0 0 1 ${sx},${sy + sh - r} ` +\n `V${sy + r} A${r},${r} 0 0 1 ${sx + r},${sy} Z`;\n } else {\n innerPath = `M${sx},${sy} V${sy + sh} H${sx + sw} V${sy} Z`;\n }\n\n const maskDef =\n `<mask id=\"${maskId}\" maskUnits=\"userSpaceOnUse\" x=\"0\" y=\"0\" width=\"${svgW}\" height=\"${svgH}\">` +\n `<path fill-rule=\"evenodd\" d=\"M0,0 H${svgW} V${svgH} H0 Z ${innerPath}\" fill=\"white\"/>` +\n `</mask>`;\n\n // Inject mask into <defs>\n if (/<defs[\\s>]/i.test(processedSVG)) {\n processedSVG = processedSVG.replace(/<\\/defs>/i, `${maskDef}</defs>`);\n } else {\n processedSVG = processedSVG.replace(\n /(<svg\\b[^>]*>)/i,\n `$1<defs>${maskDef}</defs>`,\n );\n }\n\n // Apply the mask to every <rect> whose area fully covers the screen rect.\n // This catches both the black body rect and the white screen rect,\n // but NOT small elements like Dynamic Island, status icons, etc.\n // IMPORTANT: Only apply to rects in the main SVG body, NOT inside <defs>.\n const defsMatch = processedSVG.match(/(<defs[\\s>][\\s\\S]*?<\\/defs>)/i);\n const defsContent = defsMatch ? defsMatch[1]! : \"\";\n const defsPlaceholder = \"<!--BIELAFRAME_DEFS_PLACEHOLDER-->\";\n\n // Temporarily remove <defs> to avoid masking rects inside clipPaths/filters\n let bodySVG = defsMatch\n ? processedSVG.replace(defsContent, defsPlaceholder)\n : processedSVG;\n\n bodySVG = bodySVG.replace(/<rect\\b([^>]*?)\\/?>/gi, (fullMatch, attrs: string) => {\n if (/\\bmask\\s*=/i.test(fullMatch)) return fullMatch;\n\n const xVal = parseFloat(attrs.match(/\\bx\\s*=\\s*[\"']?(-?\\d+\\.?\\d*)[\"']?/i)?.[1] ?? \"0\");\n const yVal = parseFloat(attrs.match(/\\by\\s*=\\s*[\"']?(-?\\d+\\.?\\d*)[\"']?/i)?.[1] ?? \"0\");\n const wVal = parseFloat(attrs.match(/\\bwidth\\s*=\\s*[\"']?(\\d+\\.?\\d*)[\"']?/i)?.[1] ?? \"0\");\n const hVal = parseFloat(attrs.match(/\\bheight\\s*=\\s*[\"']?(\\d+\\.?\\d*)[\"']?/i)?.[1] ?? \"0\");\n\n // Check if this rect fully covers the screen area (with tolerance)\n if (wVal > 0 && hVal > 0 &&\n xVal <= sx + 2 && yVal <= sy + 2 &&\n (xVal + wVal) >= (sx + sw - 2) &&\n (yVal + hVal) >= (sy + sh - 2)) {\n return fullMatch.replace(/(\\/?>)$/, ` mask=\"url(#${maskId})\"$1`);\n }\n return fullMatch;\n });\n\n // Restore <defs>\n processedSVG = bodySVG.replace(defsPlaceholder, defsContent);\n }\n\n // Recompute frame dimensions from the SVG viewBox + screenRect so the\n // CSS container aspect ratio matches the SVG exactly (no letterboxing).\n // The screenRect tells us where the screen is in SVG coordinates, and\n // frame.screenWidth/screenHeight is the CSS size — we derive the scale.\n let correctedFrame = frame;\n if (screenRect && screenRect.width > 0 && screenRect.height > 0) {\n const finalVBMatch = processedSVG.match(/viewBox\\s*=\\s*[\"']([^\"']+)[\"']/i);\n if (finalVBMatch) {\n const vbParts = finalVBMatch[1]!.split(/[\\s,]+/).map(Number);\n if (vbParts.length >= 4) {\n const vbW = vbParts[2]!;\n const vbH = vbParts[3]!;\n if (vbW > 0 && vbH > 0) {\n // SVG-to-CSS scale: how many CSS px per SVG unit\n const sx = frame.screenWidth / screenRect.width;\n const sy = frame.screenHeight / screenRect.height;\n const s = Math.min(sx, sy); // uniform scale\n\n correctedFrame = {\n ...frame,\n bezelLeft: Math.round(screenRect.x * s),\n bezelTop: Math.round(screenRect.y * s),\n bezelRight: Math.round((vbW - screenRect.x - screenRect.width) * s),\n bezelBottom: Math.round((vbH - screenRect.y - screenRect.height) * s),\n totalWidth: Math.round(vbW * s),\n totalHeight: Math.round(vbH * s),\n };\n }\n }\n }\n }\n\n const CustomSVGComponent: DeviceSVGComponent = ({ style }) => (\n <div\n style={style}\n dangerouslySetInnerHTML={{ __html: processedSVG }}\n />\n );\n\n SVG_REGISTRY[deviceId] = { component: CustomSVGComponent, frame: correctedFrame };\n}\n\nexport interface DeviceFrameProps {\n /** Device ID e.g. \"iphone-16-pro\" */\n device?: string;\n /** Alias for device — accepts either prop name */\n deviceId?: string;\n /** Orientation */\n orientation?: \"portrait\" | \"landscape\";\n /** Scale mode: \"fit\" auto-scales, \"manual\" uses manualScale value */\n scaleMode?: \"fit\" | \"manual\" | \"steps\";\n /** Manual scale override (0.1–1.0), only when scaleMode=\"manual\" */\n manualScale?: number;\n /** Show safe zone overlay (dev tool) */\n showSafeAreaOverlay?: boolean;\n /** Show DLC JSON panel */\n showDLCPanel?: boolean;\n /** Show scale bar (default: true) */\n showScaleBar?: boolean;\n /** Frame color scheme */\n colorScheme?: \"light\" | \"dark\";\n /** Callback when DLC is ready */\n onContractReady?: (dlc: DeviceLayoutContract) => void;\n /** Callback when scale changes */\n onScaleChange?: (scale: number) => void;\n /** Content rendered inside the device screen at real resolution */\n children?: ReactNode;\n}\n\n/**\n * DeviceFrame — the main BielaFrame component.\n *\n * Implements the Two-World Rendering Model:\n * - Inner content renders at 1:1 device resolution (e.g. 402×874px)\n * - Visual presentation scales via CSS transform: scale()\n * - The AI component always thinks it's on a real device\n *\n * DOM structure:\n * bielaframe-sentinel (fills parent, ResizeObserver target)\n * └── bielaframe-host (scaled dimensions in flow)\n * └── bielaframe-scaler (real device dims, transform: scale(N))\n * ├── bielaframe-content (clipped to screen, CSS vars injected)\n * │ └── children (AI-generated component)\n * ├── SVG frame overlay (pointer-events: none)\n * └── SafeAreaOverlay (optional dev tool)\n * └── ScaleBar (outside scaler, in normal flow)\n */\nexport function DeviceFrame({\n device: deviceProp,\n deviceId,\n orientation = \"portrait\",\n scaleMode = \"fit\",\n manualScale,\n showSafeAreaOverlay = false,\n showScaleBar = false,\n colorScheme = \"dark\",\n onContractReady,\n onScaleChange,\n children,\n}: DeviceFrameProps) {\n // Accept either \"device\" or \"deviceId\" prop\n const device = deviceProp ?? deviceId ?? \"\";\n\n const sentinelRef = useRef<HTMLDivElement>(null);\n const frameOverlayRef = useRef<HTMLDivElement>(null);\n const hostRef = useRef<HTMLDivElement>(null);\n const scalerRef = useRef<HTMLDivElement>(null);\n const { width: containerW, height: containerH } = useContainerSize(sentinelRef);\n\n // Look up device metadata and contract — memoized by device+orientation\n // to prevent infinite re-render loops (these return new objects each call)\n const deviceLookup = useMemo(() => {\n if (!device) {\n return { meta: null, contract: null, error: \"(no device specified)\" };\n }\n try {\n const meta = getDeviceMetadata(device);\n const contract = getDeviceContract(device, orientation);\n if (!meta || !meta.screen) {\n return { meta: null, contract: null, error: device };\n }\n return { meta, contract, error: null as string | null };\n } catch {\n return { meta: null, contract: null, error: device };\n }\n }, [device, orientation]);\n\n if (deviceLookup.error || !deviceLookup.meta || !deviceLookup.contract) {\n return (\n <div\n ref={sentinelRef}\n style={{\n width: \"100%\",\n height: \"100%\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n color: \"#ef4444\",\n fontFamily: \"monospace\",\n fontSize: \"14px\",\n }}\n >\n Device not found: &quot;{deviceLookup.error || \"(unknown)\"}&quot;\n </div>\n );\n }\n\n const deviceMeta = deviceLookup.meta;\n const contract = deviceLookup.contract;\n\n // Look up SVG component\n const svgEntry = SVG_REGISTRY[device];\n\n // Compute scale\n const [overrideScale, setOverrideScale] = useState<number | null>(null);\n\n const effectiveMaxScale =\n scaleMode === \"manual\" && manualScale != null ? manualScale : 1.0;\n\n // The full frame dimensions (including bezels) also scale\n const frameInfo = svgEntry?.frame;\n const frameTotalW = frameInfo?.totalWidth ?? deviceMeta.screen.width;\n const frameTotalH = frameInfo?.totalHeight ?? deviceMeta.screen.height;\n const frameBezelLeft = frameInfo?.bezelLeft ?? 0;\n const frameBezelTop = frameInfo?.bezelTop ?? 0;\n\n const isLandscape = orientation === \"landscape\";\n\n // In landscape, the scaler is still portrait-sized but visually rotated -90deg.\n // The host bounding box swaps W↔H to contain the rotated rectangle.\n const effectiveHostW = isLandscape ? frameTotalH : frameTotalW;\n const effectiveHostH = isLandscape ? frameTotalW : frameTotalH;\n\n // Create a pseudo DeviceMeta with effective dimensions for scale computation.\n // This ensures the entire frame (including bezels) fits within the container.\n const scaleDevice = useMemo((): DeviceMeta => ({\n ...deviceMeta,\n screen: {\n ...deviceMeta.screen,\n width: effectiveHostW,\n height: effectiveHostH,\n },\n }), [device, effectiveHostW, effectiveHostH]);\n\n const scaleResult = useAdaptiveScale({\n device: scaleDevice,\n containerWidth: scaleMode === \"manual\" ? Infinity : containerW,\n containerHeight: scaleMode === \"manual\" ? Infinity : containerH,\n maxScale: effectiveMaxScale,\n snapToSteps: scaleMode === \"steps\",\n });\n\n const activeScale = overrideScale ?? scaleResult.scale;\n\n const hostWidth = Math.round(effectiveHostW * activeScale);\n const hostHeight = Math.round(effectiveHostH * activeScale);\n\n // Build the scaler CSS transform:\n // Portrait: scale(s)\n // Landscape: scale(s) translate(0, W) rotate(-90deg)\n // CSS transforms apply right-to-left:\n // 1. rotate(-90deg) around top-left: (x,y) → (y, -x)\n // 2. translate(0, W): (y, -x) → (y, -x + W) — shifts into positive y\n // 3. scale(s): → (s*y, s*(W-x))\n // Result: bounding box [0,0] → [s*H, s*W] = exactly the host dimensions.\n // Both states MUST have identical transform function lists so CSS can\n // smoothly interpolate between them (mismatched lists cause a discrete jump).\n const scalerTransform = isLandscape\n ? `scale(${activeScale}) translate(0px, ${frameTotalW}px) rotate(-90deg)`\n : `scale(${activeScale}) translate(0px, 0px) rotate(0deg)`;\n\n // CSS variables at REAL unscaled values — use landscape safe areas when rotated\n const cssVarStyle = useMemo(() => {\n const vars: Record<string, string> = {};\n for (const [key, value] of Object.entries(contract.cssVariables)) {\n vars[key] = value;\n }\n // Override safe area vars with landscape values when in landscape\n if (isLandscape) {\n const lsa = contract.safeArea.landscape;\n vars[\"--safe-top\"] = `${lsa.top}px`;\n vars[\"--safe-bottom\"] = `${lsa.bottom}px`;\n vars[\"--safe-left\"] = `${lsa.left}px`;\n vars[\"--safe-right\"] = `${lsa.right}px`;\n }\n return vars;\n }, [device, orientation]);\n\n // Callbacks — use device+orientation as stable deps instead of contract object ref\n const onContractReadyRef = useRef(onContractReady);\n onContractReadyRef.current = onContractReady;\n const onScaleChangeRef = useRef(onScaleChange);\n onScaleChangeRef.current = onScaleChange;\n\n useEffect(() => {\n onContractReadyRef.current?.(contract);\n }, [device, orientation]);\n\n useEffect(() => {\n onScaleChangeRef.current?.(activeScale);\n }, [activeScale]);\n\n const DeviceSVGComponent = svgEntry?.component;\n\n // Don't render the device until the container has been measured\n const hasMeasured = containerW > 0 && containerH > 0;\n\n return (\n <div\n ref={sentinelRef}\n className=\"bielaframe-sentinel\"\n style={{\n width: \"100%\",\n height: \"100%\",\n minHeight: 0,\n maxHeight: \"100%\",\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n overflow: \"hidden\",\n }}\n >\n {hasMeasured && (\n <>\n {/* Host: occupies SCALED dimensions in document flow */}\n <div\n ref={hostRef}\n className=\"bielaframe-host\"\n aria-label={`${contract.device.name} device frame at ${Math.round(activeScale * 100)}% scale`}\n style={{\n width: hostWidth,\n height: hostHeight,\n position: \"relative\",\n flexShrink: 0,\n transition: \"width 400ms cubic-bezier(0.4, 0, 0.2, 1), height 400ms cubic-bezier(0.4, 0, 0.2, 1)\",\n }}\n >\n {/* Scaler: renders at REAL device dimensions, scaled (and rotated) visually */}\n <div\n ref={scalerRef}\n className=\"bielaframe-scaler\"\n style={{\n width: frameTotalW,\n height: frameTotalH,\n transform: scalerTransform,\n transformOrigin: \"top left\",\n position: \"absolute\",\n top: 0,\n left: 0,\n willChange: \"transform\",\n transition: \"transform 400ms cubic-bezier(0.4, 0, 0.2, 1)\",\n }}\n >\n {/* Content zone — children live here at real device resolution */}\n <div\n className=\"bielaframe-content\"\n style={{\n position: \"absolute\",\n left: frameBezelLeft,\n top: frameBezelTop,\n width: deviceMeta.screen.width,\n height: deviceMeta.screen.height,\n clipPath: `inset(0 round ${contract.screen.cornerRadius}px)`,\n overflow: \"hidden\",\n backfaceVisibility: \"hidden\",\n transform: \"translateZ(0)\",\n ...cssVarStyle,\n }}\n >\n <DeviceErrorBoundary>\n {children}\n </DeviceErrorBoundary>\n </div>\n\n {/* SVG Frame Overlay — ON TOP of content, pointer-events: none\n so content underneath remains interactive. */}\n {DeviceSVGComponent && (\n <div ref={frameOverlayRef}>\n <DeviceSVGComponent\n colorScheme={colorScheme}\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n width: frameTotalW,\n height: frameTotalH,\n pointerEvents: \"none\",\n zIndex: 10,\n }}\n />\n </div>\n )}\n\n {/* Dev: Safe Area Overlay (inside the screen area) */}\n {showSafeAreaOverlay && (\n <div\n style={{\n position: \"absolute\",\n left: frameBezelLeft,\n top: frameBezelTop,\n width: deviceMeta.screen.width,\n height: deviceMeta.screen.height,\n pointerEvents: \"none\",\n zIndex: 15,\n }}\n >\n <SafeAreaOverlay contract={contract} orientation={orientation} />\n </div>\n )}\n </div>\n </div>\n\n {/* Scale Bar — outside scaler, in normal flow below device */}\n {showScaleBar && (\n <ScaleBar\n deviceName={contract.device.name}\n deviceWidth={deviceMeta.screen.width}\n deviceHeight={deviceMeta.screen.height}\n scale={activeScale}\n scalePercent={`${Math.round(activeScale * 100)}%`}\n isAtMaxScale={activeScale >= 0.999}\n isConstrained={activeScale < 0.999}\n onScaleChange={(s) => setOverrideScale(s)}\n onFit={() => setOverrideScale(null)}\n onRealSize={() => setOverrideScale(1.0)}\n />\n )}\n </>\n )}\n </div>\n );\n}\n","import type { ReactNode } from \"react\";\nimport type { DeviceLayoutContract } from \"@biela.dev/devices\";\nimport { DeviceFrame } from \"./DeviceFrame\";\n\nexport interface DeviceCompareProps {\n /** First device ID */\n deviceA: string;\n /** Second device ID */\n deviceB: string;\n /** Orientation for both devices */\n orientation?: \"portrait\" | \"landscape\";\n /** Frame color scheme */\n colorScheme?: \"light\" | \"dark\";\n /** Show safe area overlays */\n showSafeAreaOverlay?: boolean;\n /** Show scale bars */\n showScaleBar?: boolean;\n /** Layout direction — \"auto\" picks row for portrait, column for landscape */\n layout?: \"horizontal\" | \"vertical\" | \"auto\";\n /** Gap between the two frames in px (default: 24) */\n gap?: number;\n /** Content rendered inside BOTH device frames */\n children?: ReactNode;\n /** Content for device A only (overrides children for A) */\n childrenA?: ReactNode;\n /** Content for device B only (overrides children for B) */\n childrenB?: ReactNode;\n /** Callback when device A contract is ready */\n onContractReadyA?: (dlc: DeviceLayoutContract) => void;\n /** Callback when device B contract is ready */\n onContractReadyB?: (dlc: DeviceLayoutContract) => void;\n}\n\n/**\n * DeviceCompare — renders two device frames side-by-side for comparison.\n *\n * Layout defaults to \"auto\": horizontal (row) in portrait, vertical (column) in landscape.\n * Each frame auto-scales independently to fit its half of the container.\n *\n * Must be placed inside a container with explicit width and height.\n */\nexport function DeviceCompare({\n deviceA,\n deviceB,\n orientation = \"portrait\",\n colorScheme = \"dark\",\n showSafeAreaOverlay = false,\n showScaleBar = false,\n layout = \"auto\",\n gap = 24,\n children,\n childrenA,\n childrenB,\n onContractReadyA,\n onContractReadyB,\n}: DeviceCompareProps) {\n const isLandscape = orientation === \"landscape\";\n\n const effectiveLayout =\n layout === \"auto\"\n ? isLandscape\n ? \"vertical\"\n : \"horizontal\"\n : layout;\n\n const flexDirection = effectiveLayout === \"horizontal\" ? \"row\" : \"column\";\n\n return (\n <div\n className=\"bielaframe-compare\"\n style={{\n width: \"100%\",\n height: \"100%\",\n display: \"flex\",\n flexDirection: flexDirection as \"row\" | \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n gap,\n overflow: \"hidden\",\n }}\n >\n {/* Device A */}\n <div\n style={{\n flex: 1,\n width: effectiveLayout === \"horizontal\" ? 0 : \"100%\",\n height: effectiveLayout === \"vertical\" ? 0 : \"100%\",\n minWidth: 0,\n minHeight: 0,\n }}\n >\n <DeviceFrame\n device={deviceA}\n orientation={orientation}\n colorScheme={colorScheme}\n showSafeAreaOverlay={showSafeAreaOverlay}\n showScaleBar={showScaleBar}\n onContractReady={onContractReadyA}\n >\n {childrenA ?? children}\n </DeviceFrame>\n </div>\n\n {/* Device B */}\n <div\n style={{\n flex: 1,\n width: effectiveLayout === \"horizontal\" ? 0 : \"100%\",\n height: effectiveLayout === \"vertical\" ? 0 : \"100%\",\n minWidth: 0,\n minHeight: 0,\n }}\n >\n <DeviceFrame\n device={deviceB}\n orientation={orientation}\n colorScheme={colorScheme}\n showSafeAreaOverlay={showSafeAreaOverlay}\n showScaleBar={showScaleBar}\n onContractReady={onContractReadyB}\n >\n {childrenB ?? children}\n </DeviceFrame>\n </div>\n </div>\n );\n}\n","import { type ReactNode, type CSSProperties } from \"react\";\n\ninterface SafeAreaViewProps {\n /** Which edges to apply safe area padding to (default: all) */\n edges?: Array<\"top\" | \"bottom\" | \"left\" | \"right\">;\n children: ReactNode;\n style?: CSSProperties;\n}\n\n/**\n * Convenience wrapper that applies safe area padding via CSS variables.\n * Uses var(--safe-top), var(--safe-bottom), etc. — injected by DeviceFrame.\n *\n * Usage inside a generated app:\n * <SafeAreaView edges={[\"top\", \"bottom\"]}>\n * {content that never overlaps hardware elements}\n * </SafeAreaView>\n */\nexport function SafeAreaView({ edges, children, style }: SafeAreaViewProps) {\n const allEdges = !edges || edges.length === 0;\n\n const padding: CSSProperties = {\n paddingTop: allEdges || edges?.includes(\"top\") ? \"var(--safe-top)\" : undefined,\n paddingBottom: allEdges || edges?.includes(\"bottom\") ? \"var(--safe-bottom)\" : undefined,\n paddingLeft: allEdges || edges?.includes(\"left\") ? \"var(--safe-left)\" : undefined,\n paddingRight: allEdges || edges?.includes(\"right\") ? \"var(--safe-right)\" : undefined,\n };\n\n return (\n <div style={{ width: \"100%\", height: \"100%\", boxSizing: \"border-box\", ...padding, ...style }}>\n {children}\n </div>\n );\n}\n","import type { CSSProperties } from \"react\";\n\ninterface VolumeHUDProps {\n level: number;\n muted: boolean;\n visible: boolean;\n platform: \"ios\" | \"android\";\n}\n\n/**\n * Volume HUD overlay — iOS-style vertical pill or Android-style horizontal bar.\n */\nexport function VolumeHUD({ level, muted, visible, platform }: VolumeHUDProps) {\n if (platform === \"ios\") {\n return <IOSVolumeHUD level={level} muted={muted} visible={visible} />;\n }\n return <AndroidVolumeHUD level={level} muted={muted} visible={visible} />;\n}\n\nfunction IOSVolumeHUD({ level, muted, visible }: Omit<VolumeHUDProps, \"platform\">) {\n const fillPercent = muted ? 0 : level * 100;\n\n return (\n <div\n style={{\n ...iosStyles.container,\n opacity: visible ? 1 : 0,\n pointerEvents: \"none\",\n transition: visible ? \"opacity 100ms ease-in\" : \"opacity 300ms ease-out\",\n }}\n >\n {/* Glassmorphism background */}\n <div style={iosStyles.track}>\n {/* Fill from bottom */}\n <div\n style={{\n ...iosStyles.fill,\n height: `${fillPercent}%`,\n }}\n />\n </div>\n {/* Mute indicator */}\n {muted && (\n <div style={iosStyles.muteIcon}>\n <svg width=\"10\" height=\"10\" viewBox=\"0 0 10 10\" fill=\"none\">\n <line x1=\"1\" y1=\"1\" x2=\"9\" y2=\"9\" stroke=\"white\" strokeWidth=\"1.5\" strokeLinecap=\"round\" />\n <line x1=\"9\" y1=\"1\" x2=\"1\" y2=\"9\" stroke=\"white\" strokeWidth=\"1.5\" strokeLinecap=\"round\" />\n </svg>\n </div>\n )}\n </div>\n );\n}\n\nfunction AndroidVolumeHUD({ level, muted, visible }: Omit<VolumeHUDProps, \"platform\">) {\n const fillPercent = muted ? 0 : level * 100;\n\n return (\n <div\n style={{\n ...androidStyles.container,\n opacity: visible ? 1 : 0,\n pointerEvents: \"none\",\n transition: visible ? \"opacity 100ms ease-in\" : \"opacity 300ms ease-out\",\n }}\n >\n <div style={androidStyles.track}>\n <div\n style={{\n ...androidStyles.fill,\n width: `${fillPercent}%`,\n }}\n />\n </div>\n </div>\n );\n}\n\nconst iosStyles: Record<string, CSSProperties> = {\n container: {\n position: \"absolute\",\n left: 8,\n top: \"50%\",\n transform: \"translateY(-50%)\",\n zIndex: 60,\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n gap: 4,\n },\n track: {\n width: 6,\n height: 160,\n borderRadius: 3,\n background: \"rgba(255, 255, 255, 0.15)\",\n backdropFilter: \"blur(20px)\",\n WebkitBackdropFilter: \"blur(20px)\",\n overflow: \"hidden\",\n position: \"relative\",\n display: \"flex\",\n flexDirection: \"column\",\n justifyContent: \"flex-end\",\n border: \"0.5px solid rgba(255, 255, 255, 0.2)\",\n },\n fill: {\n width: \"100%\",\n background: \"rgba(255, 255, 255, 0.85)\",\n borderRadius: 3,\n transition: \"height 80ms ease-out\",\n },\n muteIcon: {\n marginTop: 2,\n },\n};\n\nconst androidStyles: Record<string, CSSProperties> = {\n container: {\n position: \"absolute\",\n top: 8,\n left: \"50%\",\n transform: \"translateX(-50%)\",\n zIndex: 60,\n width: \"60%\",\n },\n track: {\n width: \"100%\",\n height: 4,\n borderRadius: 2,\n background: \"rgba(255, 255, 255, 0.2)\",\n overflow: \"hidden\",\n },\n fill: {\n height: \"100%\",\n background: \"rgba(255, 255, 255, 0.85)\",\n borderRadius: 2,\n transition: \"width 80ms ease-out\",\n },\n};\n","import { useEffect, useRef, useCallback, useState, type ReactElement } from \"react\";\n\nexport type ButtonName = \"volumeUp\" | \"volumeDown\" | \"power\" | \"actionButton\" | \"cameraControl\";\n\ninterface HardwareButtonsProps {\n /** The container element that holds the SVG frame overlay */\n frameContainerRef: React.RefObject<HTMLDivElement | null>;\n /** Callbacks for button actions */\n onButtonPress?: (button: ButtonName) => void;\n /** Whether interactive buttons are enabled */\n enabled?: boolean;\n /** Current orientation — triggers button position re-discovery */\n orientation?: \"portrait\" | \"landscape\";\n}\n\n/** Map from data-button attribute values to ButtonName */\nconst BUTTON_ATTR_MAP: Record<string, ButtonName> = {\n \"volume-up\": \"volumeUp\",\n \"volume-down\": \"volumeDown\",\n \"power\": \"power\",\n \"action\": \"actionButton\",\n \"camera\": \"cameraControl\",\n};\n\nconst PRESS_ANIMATION_IN = 80;\nconst PRESS_ANIMATION_OUT = 120;\n\n// Hold-to-repeat config\nconst REPEAT_INITIAL_DELAY = 500;\nconst REPEAT_INTERVAL = 150;\nconst REPEAT_FAST_INTERVAL = 80;\nconst REPEAT_FAST_THRESHOLD = 1000; // switch to fast after 1s\n\ninterface ButtonHitTarget {\n name: ButtonName;\n side: \"left\" | \"right\";\n /** Position in CSS pixels relative to the scaler container */\n top: number;\n left: number;\n width: number;\n height: number;\n /** Reference to the original SVG element for press animation */\n svgEl: SVGElement | HTMLElement;\n}\n\n/**\n * HardwareButtons — creates invisible click-target overlays positioned\n * over the SVG button elements.\n *\n * Because the SVG frame overlay has pointer-events: none (so content\n * underneath remains interactive), we can't attach event listeners directly\n * to SVG elements. Instead, we:\n * 1. Find all [data-button] elements in the SVG\n * 2. Read their bounding rects relative to the scaler container\n * 3. Render transparent absolutely-positioned divs at those positions\n * 4. Handle mouse/touch events on those divs\n * 5. Apply press animation to the original SVG elements\n */\nexport function HardwareButtons({\n frameContainerRef,\n onButtonPress,\n enabled = true,\n orientation = \"portrait\",\n}: HardwareButtonsProps): ReactElement | null {\n const [hitTargets, setHitTargets] = useState<ButtonHitTarget[]>([]);\n const repeatTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const repeatIntervalRef = useRef<ReturnType<typeof setInterval> | null>(null);\n const pressStartRef = useRef(0);\n\n const clearRepeat = useCallback(() => {\n if (repeatTimerRef.current) {\n clearTimeout(repeatTimerRef.current);\n repeatTimerRef.current = null;\n }\n if (repeatIntervalRef.current) {\n clearInterval(repeatIntervalRef.current);\n repeatIntervalRef.current = null;\n }\n }, []);\n\n // Discover button positions from the SVG.\n // Reads positional attributes (x, y, width, height, cx, cy, r) directly from\n // SVG elements to get coordinates in SVG userspace, which maps 1:1 to scaler space.\n const discoverButtons = useCallback(() => {\n const container = frameContainerRef.current;\n if (!container) return false;\n\n const buttonEls = container.querySelectorAll(\"[data-button]\");\n if (buttonEls.length === 0) return false;\n\n const targets: ButtonHitTarget[] = [];\n const seen = new Set<ButtonName>();\n\n buttonEls.forEach((el) => {\n const attrValue = el.getAttribute(\"data-button\");\n if (!attrValue) return;\n const buttonName = BUTTON_ATTR_MAP[attrValue];\n if (!buttonName) return;\n\n // Deduplicate: keep only one hit target per button name\n if (seen.has(buttonName)) return;\n seen.add(buttonName);\n\n const side = (el.getAttribute(\"data-side\") || \"right\") as \"left\" | \"right\";\n\n // Read position directly from SVG attributes (these are in SVG userspace\n // which maps 1:1 to the scaler's coordinate space since the SVG viewBox\n // matches the frame totalW x totalH).\n let localLeft: number, localTop: number, localWidth: number, localHeight: number;\n const tag = el.tagName.toLowerCase();\n\n if (tag === \"circle\") {\n const cx = parseFloat(el.getAttribute(\"cx\") || \"0\");\n const cy = parseFloat(el.getAttribute(\"cy\") || \"0\");\n const r = parseFloat(el.getAttribute(\"r\") || \"0\");\n localLeft = cx - r;\n localTop = cy - r;\n localWidth = r * 2;\n localHeight = r * 2;\n } else {\n // rect, or any element with x/y/width/height\n localLeft = parseFloat(el.getAttribute(\"x\") || \"0\");\n localTop = parseFloat(el.getAttribute(\"y\") || \"0\");\n localWidth = parseFloat(el.getAttribute(\"width\") || \"0\");\n localHeight = parseFloat(el.getAttribute(\"height\") || \"0\");\n }\n\n // Skip elements with no meaningful dimensions\n if (localWidth <= 0 && localHeight <= 0) return;\n\n // Add padding for easier clicking (buttons are very thin ~3px)\n const pad = 10;\n targets.push({\n name: buttonName,\n side,\n top: localTop - pad,\n left: localLeft - pad,\n width: localWidth + pad * 2,\n height: localHeight + pad * 2,\n svgEl: el as SVGElement,\n });\n });\n\n setHitTargets(targets);\n return targets.length > 0;\n }, [frameContainerRef]);\n\n useEffect(() => {\n if (!enabled) return;\n\n // Try immediately — button positions are read from SVG attributes\n // (not getBoundingClientRect), so no need to wait for CSS transitions.\n if (discoverButtons()) return;\n\n // SVG not ready yet — retry with increasing delays\n let retryCount = 0;\n const maxRetries = 10;\n let timer: ReturnType<typeof setTimeout>;\n\n const retry = () => {\n if (retryCount >= maxRetries) return;\n retryCount++;\n timer = setTimeout(() => {\n if (!discoverButtons()) retry();\n }, retryCount < 3 ? 100 : 300);\n };\n retry();\n\n return () => clearTimeout(timer);\n }, [enabled, orientation, discoverButtons]);\n\n const applyPress = useCallback((target: ButtonHitTarget) => {\n const pressOffset = target.side === \"left\" ? \"-2px\" : \"2px\";\n const el = target.svgEl;\n (el as HTMLElement).style.transform = `translateX(${pressOffset})`;\n (el as HTMLElement).style.opacity = \"0.7\";\n (el as HTMLElement).style.transition =\n `transform ${PRESS_ANIMATION_IN}ms ease-out, opacity ${PRESS_ANIMATION_IN}ms ease-out`;\n }, []);\n\n const releasePress = useCallback((target: ButtonHitTarget) => {\n const el = target.svgEl;\n (el as HTMLElement).style.transform = \"\";\n (el as HTMLElement).style.opacity = \"\";\n (el as HTMLElement).style.transition =\n `transform ${PRESS_ANIMATION_OUT}ms ease-in, opacity ${PRESS_ANIMATION_OUT}ms ease-in`;\n }, []);\n\n const startRepeat = useCallback((target: ButtonHitTarget) => {\n const isVolumeButton = target.name === \"volumeUp\" || target.name === \"volumeDown\";\n if (!isVolumeButton) return;\n pressStartRef.current = Date.now();\n\n repeatTimerRef.current = setTimeout(() => {\n repeatIntervalRef.current = setInterval(() => {\n onButtonPress?.(target.name);\n const elapsed = Date.now() - pressStartRef.current;\n if (elapsed > REPEAT_FAST_THRESHOLD && repeatIntervalRef.current) {\n clearInterval(repeatIntervalRef.current);\n repeatIntervalRef.current = setInterval(() => {\n onButtonPress?.(target.name);\n }, REPEAT_FAST_INTERVAL);\n }\n }, REPEAT_INTERVAL);\n }, REPEAT_INITIAL_DELAY);\n }, [onButtonPress, clearRepeat]);\n\n if (!enabled || hitTargets.length === 0) return null;\n\n return (\n <>\n {hitTargets.map((target) => (\n <div\n key={target.name}\n style={{\n position: \"absolute\",\n top: target.top,\n left: target.left,\n width: target.width,\n height: target.height,\n cursor: \"pointer\",\n zIndex: 11,\n // Transparent but clickable\n background: \"transparent\",\n }}\n onMouseDown={(e) => {\n e.preventDefault();\n e.stopPropagation();\n applyPress(target);\n onButtonPress?.(target.name);\n startRepeat(target);\n }}\n onMouseUp={(e) => {\n e.preventDefault();\n releasePress(target);\n clearRepeat();\n }}\n onMouseLeave={() => {\n releasePress(target);\n clearRepeat();\n }}\n onTouchStart={(e) => {\n e.preventDefault();\n e.stopPropagation();\n applyPress(target);\n onButtonPress?.(target.name);\n startRepeat(target);\n }}\n onTouchEnd={(e) => {\n e.preventDefault();\n releasePress(target);\n clearRepeat();\n }}\n />\n ))}\n </>\n );\n}\n","import { useState, useEffect, type CSSProperties } from \"react\";\nimport type { DeviceLayoutContract } from \"@biela.dev/devices\";\n\ninterface DynamicStatusBarProps {\n contract: DeviceLayoutContract;\n orientation: \"portrait\" | \"landscape\";\n colorScheme: \"light\" | \"dark\";\n /** Show a live updating clock (default: true) */\n showLiveClock?: boolean;\n /** Fixed time string override (e.g. \"9:41\") — disables live clock */\n fixedTime?: string;\n}\n\nfunction formatTime(date: Date): string {\n const h = date.getHours();\n const m = date.getMinutes();\n const hour = h % 12 || 12;\n return `${hour}:${m.toString().padStart(2, \"0\")}`;\n}\n\n/**\n * DynamicStatusBar — renders ONLY a live clock overlay.\n *\n * The SVG frame already provides all decorative status bar elements\n * (signal bars, wifi, battery). This component only replaces the\n * static time text (e.g. \"9:41\") with a live-updating clock.\n *\n * It renders a small opaque patch behind the clock text so the\n * SVG's baked-in static time is fully covered, then draws the\n * live time on top.\n *\n * Platform-specific clock positions:\n * - iOS Dynamic Island: left side, paddingLeft ~20\n * - iOS Notch: left side, paddingLeft ~20\n * - iOS SE: centered\n * - Android: left side, paddingLeft ~16\n */\nexport function DynamicStatusBar({\n contract,\n orientation,\n colorScheme,\n showLiveClock = true,\n fixedTime,\n}: DynamicStatusBarProps) {\n const [time, setTime] = useState(() => formatTime(new Date()));\n\n useEffect(() => {\n if (fixedTime || !showLiveClock) return;\n\n const interval = setInterval(() => {\n setTime(formatTime(new Date()));\n }, 1000);\n\n return () => clearInterval(interval);\n }, [fixedTime, showLiveClock]);\n\n // iOS hides the status bar in landscape mode\n // (placed after hooks to avoid violating Rules of Hooks)\n if (orientation === \"landscape\" && contract.device.platform === \"ios\") {\n return null;\n }\n\n const displayTime = fixedTime ?? time;\n const { platform } = contract.device;\n const statusBarHeight = contract.statusBar.height;\n const statusBarStyle = contract.statusBar.style;\n\n const textColor = colorScheme === \"dark\" ? \"#fff\" : \"#000\";\n const bgColor = colorScheme === \"dark\" ? \"#000\" : \"#fff\";\n const fontFamily = platform === \"ios\"\n ? \"-apple-system, 'SF Pro Text', 'Helvetica Neue', sans-serif\"\n : \"'Roboto', 'Google Sans', sans-serif\";\n\n const baseFontSize = platform === \"ios\" ? 15 : 12;\n\n // Clock patch: a small opaque box that covers the SVG's static time text,\n // with the live time rendered on top.\n const clockStyle: CSSProperties = {\n color: textColor,\n fontFamily,\n fontSize: baseFontSize,\n fontWeight: platform === \"ios\" ? 600 : 400,\n letterSpacing: platform === \"ios\" ? 0.3 : 0,\n lineHeight: `${statusBarHeight}px`,\n whiteSpace: \"nowrap\",\n };\n\n // The patch background — covers the SVG's static time text\n const patchStyle: CSSProperties = {\n position: \"absolute\",\n top: 0,\n height: statusBarHeight,\n display: \"flex\",\n alignItems: \"center\",\n background: bgColor,\n pointerEvents: \"none\",\n };\n\n // iOS SE / older: centered time\n if (platform === \"ios\" && statusBarStyle !== \"dynamic-island\" && statusBarStyle !== \"notch\") {\n return (\n <div style={{ ...patchStyle, left: \"50%\", transform: \"translateX(-50%)\", paddingLeft: 6, paddingRight: 6 }}>\n <span style={{ ...clockStyle, fontWeight: 500, fontSize: baseFontSize - 1 }}>\n {displayTime}\n </span>\n </div>\n );\n }\n\n // iOS Dynamic Island / Notch: time on the left\n if (platform === \"ios\") {\n return (\n <div style={{ ...patchStyle, left: 0, paddingLeft: 20, paddingRight: 8 }}>\n <span style={clockStyle}>\n {displayTime}\n </span>\n </div>\n );\n }\n\n // Android: time on the left\n return (\n <div style={{ ...patchStyle, left: 0, paddingLeft: 16, paddingRight: 8 }}>\n <span style={clockStyle}>\n {displayTime}\n </span>\n </div>\n );\n}\n","import type { CSSProperties } from \"react\";\n\ninterface StatusBarIndicatorsProps {\n platform: \"ios\" | \"android\";\n colorScheme: \"light\" | \"dark\";\n}\n\n/**\n * Static decorative status bar indicators — signal, wifi, battery.\n * Rendered as small inline SVGs, platform-specific styling.\n */\nexport function StatusBarIndicators({ platform, colorScheme }: StatusBarIndicatorsProps) {\n const color = colorScheme === \"dark\" ? \"#fff\" : \"#000\";\n\n return (\n <div style={styles.container}>\n {/* Signal bars */}\n <svg width=\"17\" height=\"11\" viewBox=\"0 0 17 11\" fill=\"none\">\n <rect x=\"0\" y=\"7\" width=\"3\" height=\"4\" rx=\"0.5\" fill={color} opacity=\"0.4\" />\n <rect x=\"4.5\" y=\"5\" width=\"3\" height=\"6\" rx=\"0.5\" fill={color} opacity=\"0.6\" />\n <rect x=\"9\" y=\"2.5\" width=\"3\" height=\"8.5\" rx=\"0.5\" fill={color} opacity=\"0.8\" />\n <rect x=\"13.5\" y=\"0\" width=\"3\" height=\"11\" rx=\"0.5\" fill={color} />\n </svg>\n\n {/* WiFi icon */}\n <svg width=\"15\" height=\"11\" viewBox=\"0 0 15 11\" fill=\"none\" style={{ marginLeft: 5 }}>\n <path d=\"M7.5 10.5a1 1 0 1 0 0-2 1 1 0 0 0 0 2z\" fill={color} />\n <path d=\"M4.5 7.5a4.2 4.2 0 0 1 6 0\" stroke={color} strokeWidth=\"1.2\" strokeLinecap=\"round\" fill=\"none\" />\n <path d=\"M2 5a7.1 7.1 0 0 1 11 0\" stroke={color} strokeWidth=\"1.2\" strokeLinecap=\"round\" fill=\"none\" />\n <path d=\"M0 2.5a10 10 0 0 1 15 0\" stroke={color} strokeWidth=\"1.2\" strokeLinecap=\"round\" fill=\"none\" />\n </svg>\n\n {/* Battery */}\n <svg width=\"25\" height=\"12\" viewBox=\"0 0 25 12\" fill=\"none\" style={{ marginLeft: 5 }}>\n <rect x=\"0.5\" y=\"0.5\" width=\"21\" height=\"11\" rx=\"2\" stroke={color} strokeWidth=\"1\" fill=\"none\" />\n <rect x=\"2\" y=\"2\" width=\"15\" height=\"8\" rx=\"1\" fill={color} opacity={platform === \"ios\" ? \"0.85\" : \"0.7\"} />\n <path d=\"M22.5 4v4a1.5 1.5 0 0 0 0-4z\" fill={color} opacity=\"0.5\" />\n </svg>\n </div>\n );\n}\n\nconst styles: Record<string, CSSProperties> = {\n container: {\n display: \"flex\",\n alignItems: \"center\",\n gap: 0,\n },\n};\n","import { registerCustomDeviceSVG, type SVGScreenRect } from \"../components/DeviceFrame\";\nimport { getDeviceMetadata } from \"@biela.dev/devices\";\n\nconst SVG_OVERRIDES_KEY = \"bielaframe-svg-overrides\";\n\nexport interface SVGOverrideEntry {\n deviceId: string;\n svgString: string;\n bezelTop: number;\n bezelBottom: number;\n bezelLeft: number;\n bezelRight: number;\n screenRect?: SVGScreenRect;\n updatedAt: string;\n}\n\n/**\n * Persistent storage for custom SVG overrides.\n *\n * When a user uploads a custom SVG frame for a device, it's stored in\n * localStorage and automatically applied on subsequent imports.\n *\n * SSR-safe: falls back to no-op storage when localStorage is unavailable.\n */\nexport class CustomSVGStore {\n private storage: Storage | null;\n\n constructor(storage?: Storage | null) {\n if (storage !== undefined) {\n this.storage = storage;\n } else {\n this.storage =\n typeof localStorage !== \"undefined\" ? localStorage : null;\n }\n }\n\n /** Load all stored overrides */\n getAll(): Record<string, SVGOverrideEntry> {\n if (!this.storage) return {};\n try {\n const raw = this.storage.getItem(SVG_OVERRIDES_KEY);\n if (raw) return JSON.parse(raw);\n } catch { /* ignore */ }\n return {};\n }\n\n /** Save an override and register it in the SVG registry */\n save(entry: SVGOverrideEntry): void {\n const all = this.getAll();\n all[entry.deviceId] = entry;\n this.persist(all);\n\n // Also live-register so the change takes effect immediately\n this.applyEntry(entry);\n }\n\n /** Remove an override (revert to built-in) */\n remove(deviceId: string): void {\n const all = this.getAll();\n delete all[deviceId];\n this.persist(all);\n }\n\n /** Check if a device has a custom override */\n has(deviceId: string): boolean {\n return this.getAll()[deviceId] !== undefined;\n }\n\n /** Get a single override by device ID */\n get(deviceId: string): SVGOverrideEntry | undefined {\n return this.getAll()[deviceId];\n }\n\n /**\n * Apply all stored overrides to the SVG registry.\n * Called during auto-registration to restore user customizations.\n */\n applyAll(): void {\n const all = this.getAll();\n for (const entry of Object.values(all)) {\n this.applyEntry(entry);\n }\n }\n\n private applyEntry(entry: SVGOverrideEntry): void {\n let screenW = 402;\n let screenH = 874;\n let screenR = 0;\n\n try {\n const meta = getDeviceMetadata(entry.deviceId);\n screenW = meta.screen.width;\n screenH = meta.screen.height;\n screenR = meta.screen.cornerRadius;\n } catch {\n // Device not in registry — use screen rect dimensions if available\n if (entry.screenRect) {\n screenW = entry.screenRect.width;\n screenH = entry.screenRect.height;\n }\n }\n\n const frame = {\n bezelTop: entry.bezelTop,\n bezelBottom: entry.bezelBottom,\n bezelLeft: entry.bezelLeft,\n bezelRight: entry.bezelRight,\n totalWidth: entry.bezelLeft + entry.bezelRight + screenW,\n totalHeight: entry.bezelTop + entry.bezelBottom + screenH,\n screenWidth: screenW,\n screenHeight: screenH,\n screenRadius: screenR,\n };\n\n try {\n registerCustomDeviceSVG(\n entry.deviceId,\n entry.svgString,\n frame,\n undefined,\n entry.screenRect,\n );\n } catch {\n // Registration may fail for missing metadata; skip silently\n }\n }\n\n private persist(all: Record<string, SVGOverrideEntry>): void {\n if (!this.storage) return;\n const json = JSON.stringify(all);\n try {\n this.storage.setItem(SVG_OVERRIDES_KEY, json);\n } catch { /* storage full or unavailable */ }\n }\n}\n\n// Singleton\nlet _store: CustomSVGStore | null = null;\n\n/** Get the default CustomSVGStore instance (singleton, uses localStorage) */\nexport function getCustomSVGStore(): CustomSVGStore {\n if (!_store) {\n _store = new CustomSVGStore();\n }\n return _store;\n}\n"]}
1
+ {"version":3,"sources":["../src/math/conversions.ts","../src/math/scale-engine.ts","../src/hooks/useContainerSize.ts","../src/hooks/useAdaptiveScale.ts","../src/hooks/useDeviceContract.ts","../src/hooks/useVolumeControl.ts","../src/hooks/useScreenPower.ts","../src/hooks/useOrientation.ts","../src/components/ErrorBoundary.tsx","../src/components/SafeAreaOverlay.tsx","../src/components/ScaleBar.tsx","../src/components/DeviceFrame.tsx","../src/components/DeviceCompare.tsx","../src/components/SafeAreaView.tsx","../src/components/VolumeHUD.tsx","../src/components/HardwareButtons.tsx","../src/components/DynamicStatusBar.tsx","../src/components/StatusBarIndicators.tsx","../src/storage/CustomSVGStore.ts"],"names":["useMemo","useState","useEffect","useCallback","jsxs","jsx","useRef","contract","getDeviceContract","Fragment","getDeviceMetadata"],"mappings":"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","file":"lite.js","sourcesContent":["/**\n * Design token dimension math — conversion utilities.\n * All device dimensions are in logical points (CSS pixels at 1x).\n */\n\n/** Convert logical points to physical pixels */\nexport function ptsToPx(pts: number, dpr: number): number {\n return Math.round(pts * dpr);\n}\n\n/** Convert physical pixels to logical points */\nexport function pxToPts(px: number, dpr: number): number {\n return px / dpr;\n}\n\n/** Convert points to percentage of a total dimension */\nexport function ptsToPercent(pts: number, total: number): number {\n if (total === 0) return 0;\n return (pts / total) * 100;\n}\n\n/** Apply uniform scale factor to any dimension value */\nexport function scaleValue(value: number, scaleFactor: number): number {\n return value * scaleFactor;\n}\n","/**\n * Scale Engine Math — mirrors Xcode Simulator \"fit to screen\" behavior.\n *\n * Rules:\n * 1. Inner content ALWAYS at 1:1 logical point size\n * 2. Scale derived from available container space, never hardcoded\n * 3. SVG frame chrome scales WITH content as one atomic unit\n * 4. Host layout reserves SCALED dimensions\n * 5. Maximum scale always 1.0 — never larger than the real device\n */\n\n/** Discrete scale steps matching Xcode Simulator presets */\nexport const SCALE_STEPS = [0.25, 0.33, 0.5, 0.75, 1.0] as const;\n\n/**\n * Compute the adaptive scale factor for a device in a given container.\n * Mirrors Xcode \"fit to screen\" exactly.\n *\n * @param deviceWidth - Logical points width of the device screen\n * @param deviceHeight - Logical points height of the device screen\n * @param containerWidth - Available CSS px width of the host container\n * @param containerHeight - Available CSS px height of the host container\n * @param padding - Breathing room in px (subtracted from each side)\n * @param maxScale - Upper cap — never exceed 1.0 (real device size)\n * @param minScale - Lower floor — prevent invisibly small render\n */\nexport function computeAdaptiveScale(\n deviceWidth: number,\n deviceHeight: number,\n containerWidth: number,\n containerHeight: number,\n padding: number = 24,\n maxScale: number = 1.0,\n minScale: number = 0.1,\n): number {\n const availW = containerWidth - padding * 2;\n const availH = containerHeight - padding * 2;\n\n if (availW <= 0 || availH <= 0) return minScale;\n\n const scaleW = availW / deviceWidth;\n const scaleH = availH / deviceHeight;\n const raw = Math.min(scaleW, scaleH, maxScale);\n\n return Math.max(raw, minScale);\n}\n\n/**\n * Snap a raw scale to the nearest discrete step that does not exceed it.\n * Fixed version: filters steps to only those <= raw, takes max.\n * Falls back to raw if no step qualifies.\n */\nexport function snapToStep(raw: number): number {\n const valid = SCALE_STEPS.filter((s) => s <= raw + 0.001); // tiny epsilon for floating point\n if (valid.length === 0) return raw;\n return valid[valid.length - 1]!; // steps are sorted ascending, last valid is the largest\n}\n\n/**\n * Derive host container size from device dimensions + scale.\n * The host div occupies these dimensions in normal document flow.\n */\nexport function computeHostSize(\n deviceWidth: number,\n deviceHeight: number,\n scale: number,\n): { width: number; height: number } {\n return {\n width: Math.round(deviceWidth * scale),\n height: Math.round(deviceHeight * scale),\n };\n}\n\n/** Result returned by the scale computation */\nexport interface AdaptiveScaleResult {\n /** Computed scale factor e.g. 0.735 */\n scale: number;\n /** Host container width = deviceWidth * scale */\n scaledWidth: number;\n /** Host container height = deviceHeight * scale */\n scaledHeight: number;\n /** Raw logical pts — scaler div width */\n deviceWidth: number;\n /** Raw logical pts — scaler div height */\n deviceHeight: number;\n /** True when scale === maxScale (showing at real size) */\n isAtMaxScale: boolean;\n /** True when scale < maxScale (container is limiting) */\n isConstrained: boolean;\n /** Display string e.g. \"73%\" */\n scalePercent: string;\n}\n\n/**\n * Full scale computation returning all derived values.\n */\nexport function computeFullScale(\n deviceWidth: number,\n deviceHeight: number,\n containerWidth: number,\n containerHeight: number,\n options: {\n padding?: number;\n maxScale?: number;\n minScale?: number;\n snapToSteps?: boolean;\n } = {},\n): AdaptiveScaleResult {\n const { padding = 24, maxScale = 1.0, minScale = 0.1, snapToSteps = false } = options;\n\n let scale = computeAdaptiveScale(\n deviceWidth,\n deviceHeight,\n containerWidth,\n containerHeight,\n padding,\n maxScale,\n minScale,\n );\n\n if (snapToSteps) {\n scale = snapToStep(scale);\n }\n\n const { width: scaledWidth, height: scaledHeight } = computeHostSize(\n deviceWidth,\n deviceHeight,\n scale,\n );\n\n return {\n scale,\n scaledWidth,\n scaledHeight,\n deviceWidth,\n deviceHeight,\n isAtMaxScale: scale >= maxScale - 0.001,\n isConstrained: scale < maxScale - 0.001,\n scalePercent: `${Math.round(scale * 100)}%`,\n };\n}\n","import { useState, useEffect, type RefObject } from \"react\";\n\ninterface ContainerSize {\n width: number;\n height: number;\n}\n\n/**\n * Observes an element's content box dimensions via ResizeObserver.\n * Foundation of adaptive scaling — same mechanism as Xcode's window resize detection.\n *\n * Safety features:\n * 1. Clamps reported size to the visual viewport so a mis-sized parent\n * can never cause the device frame to render larger than the screen.\n * 2. When the element has 0 height (common AI-generated code mistake:\n * height: auto or height: 100% without explicit ancestor height),\n * uses a viewport-based fallback so the device still renders.\n * 3. Listens for window resize to stay in sync.\n */\nexport function useContainerSize(ref: RefObject<HTMLElement | null>): ContainerSize {\n const [size, setSize] = useState<ContainerSize>({ width: 0, height: 0 });\n\n useEffect(() => {\n const el = ref.current;\n if (!el) return;\n\n const update = () => {\n const rect = el.getBoundingClientRect();\n let width = rect.width;\n let height = rect.height;\n\n if (typeof window !== \"undefined\") {\n // Fallback: element has 0 height due to broken CSS layout.\n // Use viewport height minus the element's top offset.\n if (height <= 0) {\n height = Math.max(200, window.innerHeight - Math.max(0, rect.top));\n }\n if (width <= 0) {\n width = window.innerWidth;\n }\n\n // Clamp to viewport\n width = Math.min(width, window.innerWidth);\n height = Math.min(height, window.innerHeight);\n }\n\n setSize((prev) => {\n if (prev.width === width && prev.height === height) return prev;\n return { width, height };\n });\n };\n\n const observer = new ResizeObserver(() => update());\n observer.observe(el);\n\n // Initial measurement (ResizeObserver may not fire immediately)\n update();\n\n window.addEventListener(\"resize\", update);\n\n return () => {\n observer.disconnect();\n window.removeEventListener(\"resize\", update);\n };\n }, [ref]);\n\n return size;\n}\n","import { useMemo } from \"react\";\nimport { computeFullScale, type AdaptiveScaleResult } from \"../math/scale-engine\";\nimport type { DeviceMeta } from \"@biela.dev/devices\";\n\nexport interface UseAdaptiveScaleOptions {\n /** Device metadata (screen dimensions) */\n device: DeviceMeta;\n /** Container width from useContainerSize */\n containerWidth: number;\n /** Container height from useContainerSize */\n containerHeight: number;\n /** Breathing room in px (default: 24) */\n padding?: number;\n /** Upper cap — never exceed 1.0 (default: 1.0) */\n maxScale?: number;\n /** Lower floor (default: 0.1) */\n minScale?: number;\n /** Snap to discrete 25/33/50/75/100% steps (default: false) */\n snapToSteps?: boolean;\n}\n\n/**\n * Full adaptive scale hook — mirrors Xcode \"fit to screen\".\n * Recalculates live as container resizes via ResizeObserver.\n */\nexport function useAdaptiveScale(options: UseAdaptiveScaleOptions): AdaptiveScaleResult {\n const {\n device,\n containerWidth,\n containerHeight,\n padding = 24,\n maxScale = 1.0,\n minScale = 0.1,\n snapToSteps = false,\n } = options;\n\n return useMemo(\n () =>\n computeFullScale(device.screen.width, device.screen.height, containerWidth, containerHeight, {\n padding,\n maxScale,\n minScale,\n snapToSteps,\n }),\n [device.screen.width, device.screen.height, containerWidth, containerHeight, padding, maxScale, minScale, snapToSteps],\n );\n}\n","import { useMemo } from \"react\";\nimport type { DeviceLayoutContract } from \"@biela.dev/devices\";\nimport { getDeviceContract } from \"@biela.dev/devices\";\n\ninterface UseDeviceContractResult {\n contract: DeviceLayoutContract;\n cssVariables: DeviceLayoutContract[\"cssVariables\"];\n contentZone: DeviceLayoutContract[\"contentZone\"][\"portrait\"];\n}\n\n/**\n * Hook to access the Device Layout Contract for a given device.\n * Returns the contract, CSS variables, and content zone for the current orientation.\n */\nexport function useDeviceContract(\n deviceId: string,\n orientation: \"portrait\" | \"landscape\" = \"portrait\",\n): UseDeviceContractResult {\n return useMemo(() => {\n const contract = getDeviceContract(deviceId, orientation);\n return {\n contract,\n cssVariables: contract.cssVariables,\n contentZone: contract.contentZone[orientation],\n };\n }, [deviceId, orientation]);\n}\n","import { useState, useCallback, useRef, useEffect } from \"react\";\n\nexport interface VolumeState {\n /** Current volume level 0–1 (16 steps, each = 1/16) */\n level: number;\n /** Is audio muted? */\n muted: boolean;\n /** Should the HUD be visible? */\n hudVisible: boolean;\n /** Increase volume by one step */\n volumeUp: () => void;\n /** Decrease volume by one step */\n volumeDown: () => void;\n /** Toggle mute */\n toggleMute: () => void;\n}\n\nconst STEPS = 16;\nconst STEP_SIZE = 1 / STEPS;\nconst HUD_DISPLAY_MS = 1500;\n\n/**\n * Volume control hook — 16-step volume with auto-hiding HUD.\n * Applies volume to all <audio> and <video> elements inside `.bielaframe-content`.\n */\nexport function useVolumeControl(initialVolume = 1): VolumeState {\n const [level, setLevel] = useState(initialVolume);\n const [muted, setMuted] = useState(false);\n const [hudVisible, setHudVisible] = useState(false);\n const hudTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const showHud = useCallback(() => {\n setHudVisible(true);\n if (hudTimerRef.current) clearTimeout(hudTimerRef.current);\n hudTimerRef.current = setTimeout(() => setHudVisible(false), HUD_DISPLAY_MS);\n }, []);\n\n const volumeUp = useCallback(() => {\n setLevel((prev) => {\n const next = Math.min(1, Math.round((prev + STEP_SIZE) * STEPS) / STEPS);\n return next;\n });\n setMuted(false);\n showHud();\n }, [showHud]);\n\n const volumeDown = useCallback(() => {\n setLevel((prev) => {\n const next = Math.max(0, Math.round((prev - STEP_SIZE) * STEPS) / STEPS);\n return next;\n });\n setMuted(false);\n showHud();\n }, [showHud]);\n\n const toggleMute = useCallback(() => {\n setMuted((prev) => !prev);\n showHud();\n }, [showHud]);\n\n // Apply volume to media elements\n const effectiveVolume = muted ? 0 : level;\n useEffect(() => {\n const container = document.querySelector(\".bielaframe-content\");\n if (!container) return;\n const mediaEls = container.querySelectorAll(\"audio, video\");\n mediaEls.forEach((el) => {\n (el as HTMLMediaElement).volume = effectiveVolume;\n });\n }, [effectiveVolume]);\n\n // Cleanup timer\n useEffect(() => {\n return () => {\n if (hudTimerRef.current) clearTimeout(hudTimerRef.current);\n };\n }, []);\n\n return { level, muted, hudVisible, volumeUp, volumeDown, toggleMute };\n}\n","import { useState, useCallback } from \"react\";\n\nexport interface ScreenPowerState {\n /** Is the screen off? */\n isOff: boolean;\n /** Toggle screen on/off */\n toggle: () => void;\n}\n\n/**\n * Screen power hook — manages on/off state for the power button.\n */\nexport function useScreenPower(): ScreenPowerState {\n const [isOff, setIsOff] = useState(false);\n\n const toggle = useCallback(() => {\n setIsOff((prev) => !prev);\n }, []);\n\n return { isOff, toggle };\n}\n","import { useState, useCallback } from \"react\";\n\nexport interface UseOrientationResult {\n /** Current orientation */\n orientation: \"portrait\" | \"landscape\";\n /** Convenience boolean */\n isLandscape: boolean;\n /** Toggle between portrait and landscape */\n toggle: () => void;\n /** Set orientation directly */\n setOrientation: (o: \"portrait\" | \"landscape\") => void;\n}\n\n/**\n * Hook for managing device orientation state with a toggle function.\n *\n * ```tsx\n * const { orientation, toggle } = useOrientation();\n * <button onClick={toggle}>Rotate</button>\n * <DeviceFrame deviceId=\"iphone-17-pro\" orientation={orientation} />\n * ```\n */\nexport function useOrientation(\n initial: \"portrait\" | \"landscape\" = \"portrait\",\n): UseOrientationResult {\n const [orientation, setOrientation] = useState<\"portrait\" | \"landscape\">(initial);\n\n const toggle = useCallback(\n () => setOrientation((o) => (o === \"portrait\" ? \"landscape\" : \"portrait\")),\n [],\n );\n\n return {\n orientation,\n isLandscape: orientation === \"landscape\",\n toggle,\n setOrientation,\n };\n}\n","import { Component, type ErrorInfo, type ReactNode } from \"react\";\n\ninterface Props {\n children: ReactNode;\n fallback?: ReactNode;\n}\n\ninterface State {\n hasError: boolean;\n error: Error | null;\n}\n\n/**\n * Error Boundary wrapping the children slot in DeviceFrame.\n * AI-generated components will crash — this catches them gracefully\n * and renders a fallback inside the device screen area.\n */\nexport class DeviceErrorBoundary extends Component<Props, State> {\n constructor(props: Props) {\n super(props);\n this.state = { hasError: false, error: null };\n }\n\n static getDerivedStateFromError(error: Error): State {\n return { hasError: true, error };\n }\n\n componentDidCatch(error: Error, errorInfo: ErrorInfo): void {\n console.error(\"[BielaFrame] Component error caught by boundary:\", error, errorInfo);\n }\n\n render(): ReactNode {\n if (this.state.hasError) {\n if (this.props.fallback) return this.props.fallback;\n\n return (\n <div\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n width: \"100%\",\n height: \"100%\",\n padding: \"24px\",\n fontFamily: \"-apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif\",\n color: \"#ef4444\",\n backgroundColor: \"#1a1a1a\",\n textAlign: \"center\",\n }}\n >\n <div style={{ fontSize: \"32px\", marginBottom: \"12px\" }}>!</div>\n <div style={{ fontSize: \"14px\", fontWeight: 600, marginBottom: \"8px\" }}>\n Component Error\n </div>\n <div style={{ fontSize: \"11px\", color: \"#888\", maxWidth: \"280px\", lineHeight: 1.4 }}>\n {this.state.error?.message ?? \"An unexpected error occurred in the rendered component.\"}\n </div>\n </div>\n );\n }\n\n return this.props.children;\n }\n}\n","import type { CSSProperties } from \"react\";\nimport type { DeviceLayoutContract } from \"@biela.dev/devices\";\n\ninterface SafeAreaOverlayProps {\n contract: DeviceLayoutContract;\n orientation: \"portrait\" | \"landscape\";\n}\n\n/**\n * Dev overlay showing safe zones when showSafeAreaOverlay={true}.\n * Does NOT affect layout — position: absolute, pointerEvents: none.\n *\n * Colors:\n * - Red: status bar zone + home indicator zone (restricted)\n * - Orange: hardware overlay (Dynamic Island / punch-hole)\n * - Green: content zone (usable area)\n * - White dimension labels at each edge\n */\nexport function SafeAreaOverlay({ contract, orientation }: SafeAreaOverlayProps) {\n const sa = contract.safeArea[orientation];\n const cz = contract.contentZone[orientation];\n const screen = contract.screen;\n const overlay = contract.hardwareOverlays;\n\n const base: CSSProperties = {\n position: \"absolute\",\n pointerEvents: \"none\",\n boxSizing: \"border-box\",\n };\n\n const labelStyle: CSSProperties = {\n position: \"absolute\",\n fontSize: \"9px\",\n fontFamily: \"monospace\",\n color: \"white\",\n textShadow: \"0 1px 2px rgba(0,0,0,0.8)\",\n whiteSpace: \"nowrap\",\n };\n\n return (\n <div\n style={{\n position: \"absolute\",\n inset: 0,\n pointerEvents: \"none\",\n zIndex: 20,\n }}\n >\n {/* Status bar zone — red */}\n <div\n style={{\n ...base,\n top: 0,\n left: 0,\n right: 0,\n height: `${contract.statusBar.height}px`,\n backgroundColor: \"rgba(239, 68, 68, 0.25)\",\n borderBottom: \"1px dashed rgba(239, 68, 68, 0.6)\",\n }}\n >\n <span style={{ ...labelStyle, top: \"2px\", left: \"4px\" }}>\n status: {contract.statusBar.height}pt\n </span>\n </div>\n\n {/* Hardware overlay — orange */}\n {overlay.type !== \"none\" && (\n <div\n style={{\n ...base,\n left: `${overlay.portrait.x}px`,\n top: `${overlay.portrait.y}px`,\n width: `${overlay.portrait.width}px`,\n height: `${overlay.portrait.height}px`,\n backgroundColor: \"rgba(249, 115, 22, 0.35)\",\n border: \"1px solid rgba(249, 115, 22, 0.7)\",\n borderRadius:\n overlay.portrait.shape === \"pill\"\n ? `${overlay.portrait.height / 2}px`\n : overlay.portrait.shape === \"circle\"\n ? \"50%\"\n : \"4px\",\n }}\n >\n <span style={{ ...labelStyle, top: \"-14px\", left: \"0px\" }}>\n {overlay.type}: {overlay.portrait.width}×{overlay.portrait.height}\n </span>\n </div>\n )}\n\n {/* Safe area top — red strip below status bar to safe-top */}\n {sa.top > contract.statusBar.height && (\n <div\n style={{\n ...base,\n top: `${contract.statusBar.height}px`,\n left: 0,\n right: 0,\n height: `${sa.top - contract.statusBar.height}px`,\n backgroundColor: \"rgba(239, 68, 68, 0.15)\",\n borderBottom: \"1px dashed rgba(239, 68, 68, 0.4)\",\n }}\n />\n )}\n\n {/* Content zone — green */}\n <div\n style={{\n ...base,\n left: `${cz.x}px`,\n top: `${cz.y}px`,\n width: `${cz.width}px`,\n height: `${cz.height}px`,\n backgroundColor: \"rgba(34, 197, 94, 0.08)\",\n border: \"1px dashed rgba(34, 197, 94, 0.4)\",\n }}\n >\n <span style={{ ...labelStyle, bottom: \"2px\", right: \"4px\" }}>\n content: {cz.width}×{cz.height}pt\n </span>\n </div>\n\n {/* Home indicator zone — red */}\n {sa.bottom > 0 && (\n <div\n style={{\n ...base,\n bottom: 0,\n left: 0,\n right: 0,\n height: `${sa.bottom}px`,\n backgroundColor: \"rgba(239, 68, 68, 0.25)\",\n borderTop: \"1px dashed rgba(239, 68, 68, 0.6)\",\n }}\n >\n <span style={{ ...labelStyle, bottom: \"2px\", right: \"4px\" }}>\n bottom: {sa.bottom}pt\n </span>\n </div>\n )}\n\n {/* Safe area dimension labels */}\n <span style={{ ...labelStyle, top: `${sa.top + 2}px`, left: \"4px\" }}>\n safe-top: {sa.top}pt\n </span>\n <span style={{ ...labelStyle, bottom: `${sa.bottom + 2}px`, left: \"4px\" }}>\n safe-bottom: {sa.bottom}pt\n </span>\n\n {/* Screen dimensions label */}\n <span\n style={{\n ...labelStyle,\n top: \"50%\",\n left: \"50%\",\n transform: \"translate(-50%, -50%)\",\n fontSize: \"11px\",\n backgroundColor: \"rgba(0,0,0,0.6)\",\n padding: \"2px 6px\",\n borderRadius: \"3px\",\n }}\n >\n {screen.width}×{screen.height}pt\n </span>\n </div>\n );\n}\n","interface ScaleBarProps {\n deviceName: string;\n deviceWidth: number;\n deviceHeight: number;\n scale: number;\n scalePercent: string;\n isAtMaxScale: boolean;\n isConstrained: boolean;\n onScaleChange?: (scale: number) => void;\n onFit?: () => void;\n onRealSize?: () => void;\n}\n\n/**\n * Persistent footer below device showing scale state:\n * [ iPhone 16 Pro · 402×874pt | ━━━●━━━━━ 66% | Fit ↗ | 1:1 ]\n *\n * Accessibility:\n * - role=\"slider\" with aria-valuenow on scrubber\n * - aria-label on the component\n * - aria-live=\"polite\" on scale announcements\n */\nexport function ScaleBar({\n deviceName,\n deviceWidth,\n deviceHeight,\n scale,\n scalePercent,\n isAtMaxScale,\n isConstrained,\n onScaleChange,\n onFit,\n onRealSize,\n}: ScaleBarProps) {\n return (\n <div\n aria-label={`Scale bar for ${deviceName}`}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: \"12px\",\n padding: \"6px 12px\",\n marginTop: \"8px\",\n backgroundColor: \"rgba(0, 0, 0, 0.6)\",\n borderRadius: \"8px\",\n fontSize: \"11px\",\n fontFamily: \"-apple-system, BlinkMacSystemFont, 'SF Mono', 'Fira Code', monospace\",\n color: \"#ccc\",\n userSelect: \"none\",\n width: \"fit-content\",\n alignSelf: \"center\",\n }}\n >\n {/* Device name + dimensions */}\n <span style={{ color: \"#fff\", fontWeight: 500 }}>\n {deviceName}\n </span>\n <span style={{ color: \"#666\" }}>·</span>\n <span>{deviceWidth}×{deviceHeight}pt</span>\n <span style={{ color: \"#666\" }}>|</span>\n\n {/* Scale slider */}\n <input\n type=\"range\"\n role=\"slider\"\n aria-label=\"Device scale\"\n aria-valuenow={Math.round(scale * 100)}\n aria-valuemin={10}\n aria-valuemax={100}\n min={10}\n max={100}\n step={1}\n value={Math.round(scale * 100)}\n onChange={(e) => onScaleChange?.(Number(e.target.value) / 100)}\n style={{\n width: \"80px\",\n accentColor: \"#3b82f6\",\n cursor: \"pointer\",\n }}\n />\n\n {/* Scale percentage — announced to screen readers */}\n <span aria-live=\"polite\" style={{ minWidth: \"32px\", textAlign: \"center\", fontWeight: 600 }}>\n {scalePercent}\n </span>\n\n <span style={{ color: \"#666\" }}>|</span>\n\n {/* Fit button */}\n <button\n onClick={onFit}\n aria-label=\"Fit device to container\"\n style={{\n background: isConstrained ? \"rgba(59, 130, 246, 0.2)\" : \"transparent\",\n border: \"1px solid rgba(59, 130, 246, 0.4)\",\n borderRadius: \"4px\",\n color: isConstrained ? \"#60a5fa\" : \"#666\",\n fontSize: \"10px\",\n padding: \"2px 6px\",\n cursor: \"pointer\",\n fontWeight: isConstrained ? 600 : 400,\n }}\n >\n Fit\n </button>\n\n {/* 1:1 button */}\n <button\n onClick={onRealSize}\n aria-label=\"Show at real device size\"\n style={{\n background: isAtMaxScale ? \"rgba(234, 179, 8, 0.2)\" : \"transparent\",\n border: `1px solid ${isAtMaxScale ? \"rgba(234, 179, 8, 0.6)\" : \"rgba(102, 102, 102, 0.4)\"}`,\n borderRadius: \"4px\",\n color: isAtMaxScale ? \"#eab308\" : \"#666\",\n fontSize: \"10px\",\n padding: \"2px 6px\",\n cursor: \"pointer\",\n fontWeight: isAtMaxScale ? 600 : 400,\n }}\n >\n 1:1\n </button>\n </div>\n );\n}\n","import { useRef, useEffect, useMemo, useState, type ReactNode } from \"react\";\nimport type { DeviceLayoutContract, DeviceMeta } from \"@biela.dev/devices\";\nimport { getDeviceContract, getDeviceMetadata, scopeSVGIds } from \"@biela.dev/devices\";\nimport { useContainerSize } from \"../hooks/useContainerSize\";\nimport { useAdaptiveScale } from \"../hooks/useAdaptiveScale\";\nimport { DeviceErrorBoundary } from \"./ErrorBoundary\";\nimport { SafeAreaOverlay } from \"./SafeAreaOverlay\";\nimport { ScaleBar } from \"./ScaleBar\";\n\n/**\n * Resolve device SVG component by ID.\n * This is a lookup registry — devices register their SVG components here.\n */\ntype DeviceSVGComponent = React.ComponentType<{\n colorScheme?: \"light\" | \"dark\";\n style?: React.CSSProperties;\n}>;\n\ninterface FrameInfo {\n bezelTop: number;\n bezelBottom: number;\n bezelLeft: number;\n bezelRight: number;\n totalWidth: number;\n totalHeight: number;\n screenWidth: number;\n screenHeight: number;\n screenRadius: number;\n}\n\nconst SVG_REGISTRY: Record<string, { component: DeviceSVGComponent; frame: FrameInfo }> = {};\n\n/** Register a device SVG component for use with DeviceFrame */\nexport function registerDeviceSVG(\n deviceId: string,\n component: DeviceSVGComponent,\n frame: FrameInfo,\n): void {\n SVG_REGISTRY[deviceId] = { component, frame };\n}\n\n/** Optional crop area to rewrite the SVG viewBox (e.g., to exclude side buttons) */\nexport interface SVGCropArea {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\n/** Screen rectangle in SVG native coordinates — used to punch a transparent hole */\nexport interface SVGScreenRect {\n x: number;\n y: number;\n width: number;\n height: number;\n rx?: number;\n}\n\n/**\n * Register a custom device SVG from a raw SVG string.\n *\n * Creates a React component that renders the SVG with scoped IDs\n * and registers it in the SVG_REGISTRY.\n *\n * The inner <svg> element is rewritten to use width=\"100%\" height=\"100%\"\n * so it fills the parent container (which is sized by the frame info).\n *\n * If `cropViewBox` is provided, the SVG viewBox is set to that area,\n * cropping out external elements like side buttons.\n *\n * If `screenRect` is provided, a mask is injected to punch a transparent\n * hole where the screen is, so content underneath shows through.\n */\nexport function registerCustomDeviceSVG(\n deviceId: string,\n svgString: string,\n frame: FrameInfo,\n cropViewBox?: SVGCropArea,\n screenRect?: SVGScreenRect,\n): void {\n const scopedSVG = scopeSVGIds(svgString, deviceId);\n\n // Rewrite the <svg> tag so it fills its container instead of using its native dimensions.\n let processedSVG = scopedSVG.replace(\n /<svg\\b([^>]*)>/i,\n (_match, attrs: string) => {\n if (cropViewBox) {\n // Replace the viewBox with the crop area to exclude side buttons\n attrs = attrs.replace(/\\bviewBox\\s*=\\s*[\"'][^\"']*[\"']/gi, \"\");\n attrs += ` viewBox=\"${cropViewBox.x} ${cropViewBox.y} ${cropViewBox.width} ${cropViewBox.height}\"`;\n } else if (!/viewBox/i.test(attrs)) {\n // If there's no viewBox, create one from the existing width/height\n const wMatch = attrs.match(/\\bwidth\\s*=\\s*[\"']?(\\d+\\.?\\d*)[\"']?/i);\n const hMatch = attrs.match(/\\bheight\\s*=\\s*[\"']?(\\d+\\.?\\d*)[\"']?/i);\n if (wMatch && hMatch) {\n attrs += ` viewBox=\"0 0 ${wMatch[1]} ${hMatch[1]}\"`;\n }\n }\n\n // Remove any existing width/height attributes\n let cleaned = attrs\n .replace(/\\bwidth\\s*=\\s*[\"'][^\"']*[\"']/gi, \"\")\n .replace(/\\bheight\\s*=\\s*[\"'][^\"']*[\"']/gi, \"\");\n\n // Add preserveAspectRatio if not present\n if (!/preserveAspectRatio/i.test(cleaned)) {\n cleaned += ` preserveAspectRatio=\"xMidYMid meet\"`;\n }\n\n return `<svg${cleaned} width=\"100%\" height=\"100%\">`;\n },\n );\n\n // Make the screen area transparent so content underneath shows through.\n // Strategy: inject an SVG <mask> that hides the screen rectangle area,\n // then apply it to every <rect> that fully covers the screen (body rect, screen rect).\n // Other elements (Dynamic Island, status icons, camera) are NOT masked — they\n // remain fully visible on top, exactly like the real device.\n if (screenRect) {\n const { x: sx, y: sy, width: sw, height: sh, rx: sr } = screenRect;\n const r = sr ?? 0;\n\n // Get viewBox dimensions for the mask\n const vbMatch = processedSVG.match(/viewBox\\s*=\\s*[\"']([^\"']+)[\"']/i);\n let svgW = 10000, svgH = 10000;\n if (vbMatch) {\n const parts = vbMatch[1]!.split(/[\\s,]+/).map(Number);\n if (parts.length >= 4) { svgW = parts[2]!; svgH = parts[3]!; }\n }\n\n // Build SVG mask: white = visible, black = hidden.\n // The mask is white everywhere except the screen rect (which is black).\n const maskId = `${deviceId}__screen-mask`;\n let innerPath: string;\n if (r > 0) {\n innerPath =\n `M${sx + r},${sy} H${sx + sw - r} A${r},${r} 0 0 1 ${sx + sw},${sy + r} ` +\n `V${sy + sh - r} A${r},${r} 0 0 1 ${sx + sw - r},${sy + sh} ` +\n `H${sx + r} A${r},${r} 0 0 1 ${sx},${sy + sh - r} ` +\n `V${sy + r} A${r},${r} 0 0 1 ${sx + r},${sy} Z`;\n } else {\n innerPath = `M${sx},${sy} V${sy + sh} H${sx + sw} V${sy} Z`;\n }\n\n const maskDef =\n `<mask id=\"${maskId}\" maskUnits=\"userSpaceOnUse\" x=\"0\" y=\"0\" width=\"${svgW}\" height=\"${svgH}\">` +\n `<path fill-rule=\"evenodd\" d=\"M0,0 H${svgW} V${svgH} H0 Z ${innerPath}\" fill=\"white\"/>` +\n `</mask>`;\n\n // Inject mask into <defs>\n if (/<defs[\\s>]/i.test(processedSVG)) {\n processedSVG = processedSVG.replace(/<\\/defs>/i, `${maskDef}</defs>`);\n } else {\n processedSVG = processedSVG.replace(\n /(<svg\\b[^>]*>)/i,\n `$1<defs>${maskDef}</defs>`,\n );\n }\n\n // Apply the mask to every <rect> whose area fully covers the screen rect.\n // This catches both the black body rect and the white screen rect,\n // but NOT small elements like Dynamic Island, status icons, etc.\n // IMPORTANT: Only apply to rects in the main SVG body, NOT inside <defs>.\n const defsMatch = processedSVG.match(/(<defs[\\s>][\\s\\S]*?<\\/defs>)/i);\n const defsContent = defsMatch ? defsMatch[1]! : \"\";\n const defsPlaceholder = \"<!--BIELAFRAME_DEFS_PLACEHOLDER-->\";\n\n // Temporarily remove <defs> to avoid masking rects inside clipPaths/filters\n let bodySVG = defsMatch\n ? processedSVG.replace(defsContent, defsPlaceholder)\n : processedSVG;\n\n bodySVG = bodySVG.replace(/<rect\\b([^>]*?)\\/?>/gi, (fullMatch, attrs: string) => {\n if (/\\bmask\\s*=/i.test(fullMatch)) return fullMatch;\n\n const xVal = parseFloat(attrs.match(/\\bx\\s*=\\s*[\"']?(-?\\d+\\.?\\d*)[\"']?/i)?.[1] ?? \"0\");\n const yVal = parseFloat(attrs.match(/\\by\\s*=\\s*[\"']?(-?\\d+\\.?\\d*)[\"']?/i)?.[1] ?? \"0\");\n const wVal = parseFloat(attrs.match(/\\bwidth\\s*=\\s*[\"']?(\\d+\\.?\\d*)[\"']?/i)?.[1] ?? \"0\");\n const hVal = parseFloat(attrs.match(/\\bheight\\s*=\\s*[\"']?(\\d+\\.?\\d*)[\"']?/i)?.[1] ?? \"0\");\n\n // Check if this rect fully covers the screen area (with tolerance)\n if (wVal > 0 && hVal > 0 &&\n xVal <= sx + 2 && yVal <= sy + 2 &&\n (xVal + wVal) >= (sx + sw - 2) &&\n (yVal + hVal) >= (sy + sh - 2)) {\n return fullMatch.replace(/(\\/?>)$/, ` mask=\"url(#${maskId})\"$1`);\n }\n return fullMatch;\n });\n\n // Restore <defs>\n processedSVG = bodySVG.replace(defsPlaceholder, defsContent);\n }\n\n // Recompute frame dimensions from the SVG viewBox + screenRect so the\n // CSS container aspect ratio matches the SVG exactly (no letterboxing).\n // The screenRect tells us where the screen is in SVG coordinates, and\n // frame.screenWidth/screenHeight is the CSS size — we derive the scale.\n let correctedFrame = frame;\n if (screenRect && screenRect.width > 0 && screenRect.height > 0) {\n const finalVBMatch = processedSVG.match(/viewBox\\s*=\\s*[\"']([^\"']+)[\"']/i);\n if (finalVBMatch) {\n const vbParts = finalVBMatch[1]!.split(/[\\s,]+/).map(Number);\n if (vbParts.length >= 4) {\n const vbW = vbParts[2]!;\n const vbH = vbParts[3]!;\n if (vbW > 0 && vbH > 0) {\n // SVG-to-CSS scale: how many CSS px per SVG unit\n const sx = frame.screenWidth / screenRect.width;\n const sy = frame.screenHeight / screenRect.height;\n const s = Math.min(sx, sy); // uniform scale\n\n correctedFrame = {\n ...frame,\n bezelLeft: Math.round(screenRect.x * s),\n bezelTop: Math.round(screenRect.y * s),\n bezelRight: Math.round((vbW - screenRect.x - screenRect.width) * s),\n bezelBottom: Math.round((vbH - screenRect.y - screenRect.height) * s),\n totalWidth: Math.round(vbW * s),\n totalHeight: Math.round(vbH * s),\n };\n }\n }\n }\n }\n\n const CustomSVGComponent: DeviceSVGComponent = ({ style }) => (\n <div\n style={style}\n dangerouslySetInnerHTML={{ __html: processedSVG }}\n />\n );\n\n SVG_REGISTRY[deviceId] = { component: CustomSVGComponent, frame: correctedFrame };\n}\n\nexport interface DeviceFrameProps {\n /** Device ID e.g. \"iphone-16-pro\" */\n device?: string;\n /** Alias for device — accepts either prop name */\n deviceId?: string;\n /** Orientation */\n orientation?: \"portrait\" | \"landscape\";\n /** Scale mode: \"fit\" auto-scales, \"manual\" uses manualScale value */\n scaleMode?: \"fit\" | \"manual\" | \"steps\";\n /** Manual scale override (0.1–1.0), only when scaleMode=\"manual\" */\n manualScale?: number;\n /** Show safe zone overlay (dev tool) */\n showSafeAreaOverlay?: boolean;\n /** Show DLC JSON panel */\n showDLCPanel?: boolean;\n /** Show scale bar (default: true) */\n showScaleBar?: boolean;\n /** Frame color scheme */\n colorScheme?: \"light\" | \"dark\";\n /** Callback when DLC is ready */\n onContractReady?: (dlc: DeviceLayoutContract) => void;\n /** Callback when scale changes */\n onScaleChange?: (scale: number) => void;\n /** Content rendered inside the device screen at real resolution */\n children?: ReactNode;\n}\n\n/**\n * DeviceFrame — the main BielaFrame component.\n *\n * Implements the Two-World Rendering Model:\n * - Inner content renders at 1:1 device resolution (e.g. 402×874px)\n * - Visual presentation scales via CSS transform: scale()\n * - The AI component always thinks it's on a real device\n *\n * DOM structure:\n * bielaframe-sentinel (fills parent, ResizeObserver target)\n * └── bielaframe-host (scaled dimensions in flow)\n * └── bielaframe-scaler (real device dims, transform: scale(N))\n * ├── bielaframe-content (clipped to screen, CSS vars injected)\n * │ └── children (AI-generated component)\n * ├── SVG frame overlay (pointer-events: none)\n * └── SafeAreaOverlay (optional dev tool)\n * └── ScaleBar (outside scaler, in normal flow)\n */\nexport function DeviceFrame({\n device: deviceProp,\n deviceId,\n orientation = \"portrait\",\n scaleMode = \"fit\",\n manualScale,\n showSafeAreaOverlay = false,\n showScaleBar = false,\n colorScheme = \"dark\",\n onContractReady,\n onScaleChange,\n children,\n}: DeviceFrameProps) {\n // Accept either \"device\" or \"deviceId\" prop\n const device = deviceProp ?? deviceId ?? \"\";\n\n const sentinelRef = useRef<HTMLDivElement>(null);\n const frameOverlayRef = useRef<HTMLDivElement>(null);\n const hostRef = useRef<HTMLDivElement>(null);\n const scalerRef = useRef<HTMLDivElement>(null);\n const { width: containerW, height: containerH } = useContainerSize(sentinelRef);\n\n // Look up device metadata and contract — memoized by device+orientation\n // to prevent infinite re-render loops (these return new objects each call)\n const deviceLookup = useMemo(() => {\n if (!device) {\n return { meta: null, contract: null, error: \"(no device specified)\" };\n }\n try {\n const meta = getDeviceMetadata(device);\n const contract = getDeviceContract(device, orientation);\n if (!meta || !meta.screen) {\n return { meta: null, contract: null, error: device };\n }\n return { meta, contract, error: null as string | null };\n } catch {\n return { meta: null, contract: null, error: device };\n }\n }, [device, orientation]);\n\n if (deviceLookup.error || !deviceLookup.meta || !deviceLookup.contract) {\n return (\n <div\n ref={sentinelRef}\n style={{\n width: \"100%\",\n height: \"100%\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n color: \"#ef4444\",\n fontFamily: \"monospace\",\n fontSize: \"14px\",\n }}\n >\n Device not found: &quot;{deviceLookup.error || \"(unknown)\"}&quot;\n </div>\n );\n }\n\n const deviceMeta = deviceLookup.meta;\n const contract = deviceLookup.contract;\n\n // Look up SVG component\n const svgEntry = SVG_REGISTRY[device];\n\n // Compute scale\n const [overrideScale, setOverrideScale] = useState<number | null>(null);\n\n const effectiveMaxScale =\n scaleMode === \"manual\" && manualScale != null ? manualScale : 1.0;\n\n // The full frame dimensions (including bezels) also scale\n const frameInfo = svgEntry?.frame;\n const frameTotalW = frameInfo?.totalWidth ?? deviceMeta.screen.width;\n const frameTotalH = frameInfo?.totalHeight ?? deviceMeta.screen.height;\n const frameBezelLeft = frameInfo?.bezelLeft ?? 0;\n const frameBezelTop = frameInfo?.bezelTop ?? 0;\n\n const isLandscape = orientation === \"landscape\";\n\n // In landscape, the scaler is still portrait-sized but visually rotated -90deg.\n // The host bounding box swaps W↔H to contain the rotated rectangle.\n const effectiveHostW = isLandscape ? frameTotalH : frameTotalW;\n const effectiveHostH = isLandscape ? frameTotalW : frameTotalH;\n\n // Create a pseudo DeviceMeta with effective dimensions for scale computation.\n // This ensures the entire frame (including bezels) fits within the container.\n const scaleDevice = useMemo((): DeviceMeta => ({\n ...deviceMeta,\n screen: {\n ...deviceMeta.screen,\n width: effectiveHostW,\n height: effectiveHostH,\n },\n }), [device, effectiveHostW, effectiveHostH]);\n\n const scaleResult = useAdaptiveScale({\n device: scaleDevice,\n containerWidth: scaleMode === \"manual\" ? Infinity : containerW,\n containerHeight: scaleMode === \"manual\" ? Infinity : containerH,\n maxScale: effectiveMaxScale,\n snapToSteps: scaleMode === \"steps\",\n });\n\n const activeScale = overrideScale ?? scaleResult.scale;\n\n const hostWidth = Math.round(effectiveHostW * activeScale);\n const hostHeight = Math.round(effectiveHostH * activeScale);\n\n // Build the scaler CSS transform:\n // Portrait: scale(s)\n // Landscape: scale(s) translate(0, W) rotate(-90deg)\n // CSS transforms apply right-to-left:\n // 1. rotate(-90deg) around top-left: (x,y) → (y, -x)\n // 2. translate(0, W): (y, -x) → (y, -x + W) — shifts into positive y\n // 3. scale(s): → (s*y, s*(W-x))\n // Result: bounding box [0,0] → [s*H, s*W] = exactly the host dimensions.\n // Both states MUST have identical transform function lists so CSS can\n // smoothly interpolate between them (mismatched lists cause a discrete jump).\n const scalerTransform = isLandscape\n ? `scale(${activeScale}) translate(0px, ${frameTotalW}px) rotate(-90deg)`\n : `scale(${activeScale}) translate(0px, 0px) rotate(0deg)`;\n\n // CSS variables at REAL unscaled values — use landscape safe areas when rotated\n const cssVarStyle = useMemo(() => {\n const vars: Record<string, string> = {};\n for (const [key, value] of Object.entries(contract.cssVariables)) {\n vars[key] = value;\n }\n // Override safe area vars with landscape values when in landscape\n if (isLandscape) {\n const lsa = contract.safeArea.landscape;\n vars[\"--safe-top\"] = `${lsa.top}px`;\n vars[\"--safe-bottom\"] = `${lsa.bottom}px`;\n vars[\"--safe-left\"] = `${lsa.left}px`;\n vars[\"--safe-right\"] = `${lsa.right}px`;\n }\n return vars;\n }, [device, orientation]);\n\n // Callbacks — use device+orientation as stable deps instead of contract object ref\n const onContractReadyRef = useRef(onContractReady);\n onContractReadyRef.current = onContractReady;\n const onScaleChangeRef = useRef(onScaleChange);\n onScaleChangeRef.current = onScaleChange;\n\n useEffect(() => {\n onContractReadyRef.current?.(contract);\n }, [device, orientation]);\n\n useEffect(() => {\n onScaleChangeRef.current?.(activeScale);\n }, [activeScale]);\n\n const DeviceSVGComponent = svgEntry?.component;\n\n // Don't render the device until the container has been measured\n const hasMeasured = containerW > 0 && containerH > 0;\n\n return (\n <div\n ref={sentinelRef}\n className=\"bielaframe-sentinel\"\n style={{\n width: \"100%\",\n height: containerH > 0 ? containerH : \"100%\",\n minHeight: 0,\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n overflow: \"hidden\",\n }}\n >\n {hasMeasured && (\n <>\n {/* Host: occupies SCALED dimensions in document flow */}\n <div\n ref={hostRef}\n className=\"bielaframe-host\"\n aria-label={`${contract.device.name} device frame at ${Math.round(activeScale * 100)}% scale`}\n style={{\n width: hostWidth,\n height: hostHeight,\n position: \"relative\",\n flexShrink: 0,\n transition: \"width 400ms cubic-bezier(0.4, 0, 0.2, 1), height 400ms cubic-bezier(0.4, 0, 0.2, 1)\",\n }}\n >\n {/* Scaler: renders at REAL device dimensions, scaled (and rotated) visually */}\n <div\n ref={scalerRef}\n className=\"bielaframe-scaler\"\n style={{\n width: frameTotalW,\n height: frameTotalH,\n transform: scalerTransform,\n transformOrigin: \"top left\",\n position: \"absolute\",\n top: 0,\n left: 0,\n willChange: \"transform\",\n transition: \"transform 400ms cubic-bezier(0.4, 0, 0.2, 1)\",\n }}\n >\n {/* Content zone — children live here at real device resolution */}\n <div\n className=\"bielaframe-content\"\n style={{\n position: \"absolute\",\n left: frameBezelLeft,\n top: frameBezelTop,\n width: deviceMeta.screen.width,\n height: deviceMeta.screen.height,\n clipPath: `inset(0 round ${contract.screen.cornerRadius}px)`,\n overflow: \"hidden\",\n backfaceVisibility: \"hidden\",\n transform: \"translateZ(0)\",\n ...cssVarStyle,\n }}\n >\n <DeviceErrorBoundary>\n {children}\n </DeviceErrorBoundary>\n </div>\n\n {/* SVG Frame Overlay — ON TOP of content, pointer-events: none\n so content underneath remains interactive. */}\n {DeviceSVGComponent && (\n <div ref={frameOverlayRef}>\n <DeviceSVGComponent\n colorScheme={colorScheme}\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n width: frameTotalW,\n height: frameTotalH,\n pointerEvents: \"none\",\n zIndex: 10,\n }}\n />\n </div>\n )}\n\n {/* Dev: Safe Area Overlay (inside the screen area) */}\n {showSafeAreaOverlay && (\n <div\n style={{\n position: \"absolute\",\n left: frameBezelLeft,\n top: frameBezelTop,\n width: deviceMeta.screen.width,\n height: deviceMeta.screen.height,\n pointerEvents: \"none\",\n zIndex: 15,\n }}\n >\n <SafeAreaOverlay contract={contract} orientation={orientation} />\n </div>\n )}\n </div>\n </div>\n\n {/* Scale Bar — outside scaler, in normal flow below device */}\n {showScaleBar && (\n <ScaleBar\n deviceName={contract.device.name}\n deviceWidth={deviceMeta.screen.width}\n deviceHeight={deviceMeta.screen.height}\n scale={activeScale}\n scalePercent={`${Math.round(activeScale * 100)}%`}\n isAtMaxScale={activeScale >= 0.999}\n isConstrained={activeScale < 0.999}\n onScaleChange={(s) => setOverrideScale(s)}\n onFit={() => setOverrideScale(null)}\n onRealSize={() => setOverrideScale(1.0)}\n />\n )}\n </>\n )}\n </div>\n );\n}\n","import type { ReactNode } from \"react\";\nimport type { DeviceLayoutContract } from \"@biela.dev/devices\";\nimport { DeviceFrame } from \"./DeviceFrame\";\n\nexport interface DeviceCompareProps {\n /** First device ID */\n deviceA: string;\n /** Second device ID */\n deviceB: string;\n /** Orientation for both devices */\n orientation?: \"portrait\" | \"landscape\";\n /** Frame color scheme */\n colorScheme?: \"light\" | \"dark\";\n /** Show safe area overlays */\n showSafeAreaOverlay?: boolean;\n /** Show scale bars */\n showScaleBar?: boolean;\n /** Layout direction — \"auto\" picks row for portrait, column for landscape */\n layout?: \"horizontal\" | \"vertical\" | \"auto\";\n /** Gap between the two frames in px (default: 24) */\n gap?: number;\n /** Content rendered inside BOTH device frames */\n children?: ReactNode;\n /** Content for device A only (overrides children for A) */\n childrenA?: ReactNode;\n /** Content for device B only (overrides children for B) */\n childrenB?: ReactNode;\n /** Callback when device A contract is ready */\n onContractReadyA?: (dlc: DeviceLayoutContract) => void;\n /** Callback when device B contract is ready */\n onContractReadyB?: (dlc: DeviceLayoutContract) => void;\n}\n\n/**\n * DeviceCompare — renders two device frames side-by-side for comparison.\n *\n * Layout defaults to \"auto\": horizontal (row) in portrait, vertical (column) in landscape.\n * Each frame auto-scales independently to fit its half of the container.\n *\n * Must be placed inside a container with explicit width and height.\n */\nexport function DeviceCompare({\n deviceA,\n deviceB,\n orientation = \"portrait\",\n colorScheme = \"dark\",\n showSafeAreaOverlay = false,\n showScaleBar = false,\n layout = \"auto\",\n gap = 24,\n children,\n childrenA,\n childrenB,\n onContractReadyA,\n onContractReadyB,\n}: DeviceCompareProps) {\n const isLandscape = orientation === \"landscape\";\n\n const effectiveLayout =\n layout === \"auto\"\n ? isLandscape\n ? \"vertical\"\n : \"horizontal\"\n : layout;\n\n const flexDirection = effectiveLayout === \"horizontal\" ? \"row\" : \"column\";\n\n return (\n <div\n className=\"bielaframe-compare\"\n style={{\n width: \"100%\",\n height: \"100%\",\n display: \"flex\",\n flexDirection: flexDirection as \"row\" | \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n gap,\n overflow: \"hidden\",\n }}\n >\n {/* Device A */}\n <div\n style={{\n flex: 1,\n width: effectiveLayout === \"horizontal\" ? 0 : \"100%\",\n height: effectiveLayout === \"vertical\" ? 0 : \"100%\",\n minWidth: 0,\n minHeight: 0,\n }}\n >\n <DeviceFrame\n device={deviceA}\n orientation={orientation}\n colorScheme={colorScheme}\n showSafeAreaOverlay={showSafeAreaOverlay}\n showScaleBar={showScaleBar}\n onContractReady={onContractReadyA}\n >\n {childrenA ?? children}\n </DeviceFrame>\n </div>\n\n {/* Device B */}\n <div\n style={{\n flex: 1,\n width: effectiveLayout === \"horizontal\" ? 0 : \"100%\",\n height: effectiveLayout === \"vertical\" ? 0 : \"100%\",\n minWidth: 0,\n minHeight: 0,\n }}\n >\n <DeviceFrame\n device={deviceB}\n orientation={orientation}\n colorScheme={colorScheme}\n showSafeAreaOverlay={showSafeAreaOverlay}\n showScaleBar={showScaleBar}\n onContractReady={onContractReadyB}\n >\n {childrenB ?? children}\n </DeviceFrame>\n </div>\n </div>\n );\n}\n","import { type ReactNode, type CSSProperties } from \"react\";\n\ninterface SafeAreaViewProps {\n /** Which edges to apply safe area padding to (default: all) */\n edges?: Array<\"top\" | \"bottom\" | \"left\" | \"right\">;\n children: ReactNode;\n style?: CSSProperties;\n}\n\n/**\n * Convenience wrapper that applies safe area padding via CSS variables.\n * Uses var(--safe-top), var(--safe-bottom), etc. — injected by DeviceFrame.\n *\n * Usage inside a generated app:\n * <SafeAreaView edges={[\"top\", \"bottom\"]}>\n * {content that never overlaps hardware elements}\n * </SafeAreaView>\n */\nexport function SafeAreaView({ edges, children, style }: SafeAreaViewProps) {\n const allEdges = !edges || edges.length === 0;\n\n const padding: CSSProperties = {\n paddingTop: allEdges || edges?.includes(\"top\") ? \"var(--safe-top)\" : undefined,\n paddingBottom: allEdges || edges?.includes(\"bottom\") ? \"var(--safe-bottom)\" : undefined,\n paddingLeft: allEdges || edges?.includes(\"left\") ? \"var(--safe-left)\" : undefined,\n paddingRight: allEdges || edges?.includes(\"right\") ? \"var(--safe-right)\" : undefined,\n };\n\n return (\n <div style={{ width: \"100%\", height: \"100%\", boxSizing: \"border-box\", ...padding, ...style }}>\n {children}\n </div>\n );\n}\n","import type { CSSProperties } from \"react\";\n\ninterface VolumeHUDProps {\n level: number;\n muted: boolean;\n visible: boolean;\n platform: \"ios\" | \"android\";\n}\n\n/**\n * Volume HUD overlay — iOS-style vertical pill or Android-style horizontal bar.\n */\nexport function VolumeHUD({ level, muted, visible, platform }: VolumeHUDProps) {\n if (platform === \"ios\") {\n return <IOSVolumeHUD level={level} muted={muted} visible={visible} />;\n }\n return <AndroidVolumeHUD level={level} muted={muted} visible={visible} />;\n}\n\nfunction IOSVolumeHUD({ level, muted, visible }: Omit<VolumeHUDProps, \"platform\">) {\n const fillPercent = muted ? 0 : level * 100;\n\n return (\n <div\n style={{\n ...iosStyles.container,\n opacity: visible ? 1 : 0,\n pointerEvents: \"none\",\n transition: visible ? \"opacity 100ms ease-in\" : \"opacity 300ms ease-out\",\n }}\n >\n {/* Glassmorphism background */}\n <div style={iosStyles.track}>\n {/* Fill from bottom */}\n <div\n style={{\n ...iosStyles.fill,\n height: `${fillPercent}%`,\n }}\n />\n </div>\n {/* Mute indicator */}\n {muted && (\n <div style={iosStyles.muteIcon}>\n <svg width=\"10\" height=\"10\" viewBox=\"0 0 10 10\" fill=\"none\">\n <line x1=\"1\" y1=\"1\" x2=\"9\" y2=\"9\" stroke=\"white\" strokeWidth=\"1.5\" strokeLinecap=\"round\" />\n <line x1=\"9\" y1=\"1\" x2=\"1\" y2=\"9\" stroke=\"white\" strokeWidth=\"1.5\" strokeLinecap=\"round\" />\n </svg>\n </div>\n )}\n </div>\n );\n}\n\nfunction AndroidVolumeHUD({ level, muted, visible }: Omit<VolumeHUDProps, \"platform\">) {\n const fillPercent = muted ? 0 : level * 100;\n\n return (\n <div\n style={{\n ...androidStyles.container,\n opacity: visible ? 1 : 0,\n pointerEvents: \"none\",\n transition: visible ? \"opacity 100ms ease-in\" : \"opacity 300ms ease-out\",\n }}\n >\n <div style={androidStyles.track}>\n <div\n style={{\n ...androidStyles.fill,\n width: `${fillPercent}%`,\n }}\n />\n </div>\n </div>\n );\n}\n\nconst iosStyles: Record<string, CSSProperties> = {\n container: {\n position: \"absolute\",\n left: 8,\n top: \"50%\",\n transform: \"translateY(-50%)\",\n zIndex: 60,\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n gap: 4,\n },\n track: {\n width: 6,\n height: 160,\n borderRadius: 3,\n background: \"rgba(255, 255, 255, 0.15)\",\n backdropFilter: \"blur(20px)\",\n WebkitBackdropFilter: \"blur(20px)\",\n overflow: \"hidden\",\n position: \"relative\",\n display: \"flex\",\n flexDirection: \"column\",\n justifyContent: \"flex-end\",\n border: \"0.5px solid rgba(255, 255, 255, 0.2)\",\n },\n fill: {\n width: \"100%\",\n background: \"rgba(255, 255, 255, 0.85)\",\n borderRadius: 3,\n transition: \"height 80ms ease-out\",\n },\n muteIcon: {\n marginTop: 2,\n },\n};\n\nconst androidStyles: Record<string, CSSProperties> = {\n container: {\n position: \"absolute\",\n top: 8,\n left: \"50%\",\n transform: \"translateX(-50%)\",\n zIndex: 60,\n width: \"60%\",\n },\n track: {\n width: \"100%\",\n height: 4,\n borderRadius: 2,\n background: \"rgba(255, 255, 255, 0.2)\",\n overflow: \"hidden\",\n },\n fill: {\n height: \"100%\",\n background: \"rgba(255, 255, 255, 0.85)\",\n borderRadius: 2,\n transition: \"width 80ms ease-out\",\n },\n};\n","import { useEffect, useRef, useCallback, useState, type ReactElement } from \"react\";\n\nexport type ButtonName = \"volumeUp\" | \"volumeDown\" | \"power\" | \"actionButton\" | \"cameraControl\";\n\ninterface HardwareButtonsProps {\n /** The container element that holds the SVG frame overlay */\n frameContainerRef: React.RefObject<HTMLDivElement | null>;\n /** Callbacks for button actions */\n onButtonPress?: (button: ButtonName) => void;\n /** Whether interactive buttons are enabled */\n enabled?: boolean;\n /** Current orientation — triggers button position re-discovery */\n orientation?: \"portrait\" | \"landscape\";\n}\n\n/** Map from data-button attribute values to ButtonName */\nconst BUTTON_ATTR_MAP: Record<string, ButtonName> = {\n \"volume-up\": \"volumeUp\",\n \"volume-down\": \"volumeDown\",\n \"power\": \"power\",\n \"action\": \"actionButton\",\n \"camera\": \"cameraControl\",\n};\n\nconst PRESS_ANIMATION_IN = 80;\nconst PRESS_ANIMATION_OUT = 120;\n\n// Hold-to-repeat config\nconst REPEAT_INITIAL_DELAY = 500;\nconst REPEAT_INTERVAL = 150;\nconst REPEAT_FAST_INTERVAL = 80;\nconst REPEAT_FAST_THRESHOLD = 1000; // switch to fast after 1s\n\ninterface ButtonHitTarget {\n name: ButtonName;\n side: \"left\" | \"right\";\n /** Position in CSS pixels relative to the scaler container */\n top: number;\n left: number;\n width: number;\n height: number;\n /** Reference to the original SVG element for press animation */\n svgEl: SVGElement | HTMLElement;\n}\n\n/**\n * HardwareButtons — creates invisible click-target overlays positioned\n * over the SVG button elements.\n *\n * Because the SVG frame overlay has pointer-events: none (so content\n * underneath remains interactive), we can't attach event listeners directly\n * to SVG elements. Instead, we:\n * 1. Find all [data-button] elements in the SVG\n * 2. Read their bounding rects relative to the scaler container\n * 3. Render transparent absolutely-positioned divs at those positions\n * 4. Handle mouse/touch events on those divs\n * 5. Apply press animation to the original SVG elements\n */\nexport function HardwareButtons({\n frameContainerRef,\n onButtonPress,\n enabled = true,\n orientation = \"portrait\",\n}: HardwareButtonsProps): ReactElement | null {\n const [hitTargets, setHitTargets] = useState<ButtonHitTarget[]>([]);\n const repeatTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const repeatIntervalRef = useRef<ReturnType<typeof setInterval> | null>(null);\n const pressStartRef = useRef(0);\n\n const clearRepeat = useCallback(() => {\n if (repeatTimerRef.current) {\n clearTimeout(repeatTimerRef.current);\n repeatTimerRef.current = null;\n }\n if (repeatIntervalRef.current) {\n clearInterval(repeatIntervalRef.current);\n repeatIntervalRef.current = null;\n }\n }, []);\n\n // Discover button positions from the SVG.\n // Reads positional attributes (x, y, width, height, cx, cy, r) directly from\n // SVG elements to get coordinates in SVG userspace, which maps 1:1 to scaler space.\n const discoverButtons = useCallback(() => {\n const container = frameContainerRef.current;\n if (!container) return false;\n\n const buttonEls = container.querySelectorAll(\"[data-button]\");\n if (buttonEls.length === 0) return false;\n\n const targets: ButtonHitTarget[] = [];\n const seen = new Set<ButtonName>();\n\n buttonEls.forEach((el) => {\n const attrValue = el.getAttribute(\"data-button\");\n if (!attrValue) return;\n const buttonName = BUTTON_ATTR_MAP[attrValue];\n if (!buttonName) return;\n\n // Deduplicate: keep only one hit target per button name\n if (seen.has(buttonName)) return;\n seen.add(buttonName);\n\n const side = (el.getAttribute(\"data-side\") || \"right\") as \"left\" | \"right\";\n\n // Read position directly from SVG attributes (these are in SVG userspace\n // which maps 1:1 to the scaler's coordinate space since the SVG viewBox\n // matches the frame totalW x totalH).\n let localLeft: number, localTop: number, localWidth: number, localHeight: number;\n const tag = el.tagName.toLowerCase();\n\n if (tag === \"circle\") {\n const cx = parseFloat(el.getAttribute(\"cx\") || \"0\");\n const cy = parseFloat(el.getAttribute(\"cy\") || \"0\");\n const r = parseFloat(el.getAttribute(\"r\") || \"0\");\n localLeft = cx - r;\n localTop = cy - r;\n localWidth = r * 2;\n localHeight = r * 2;\n } else {\n // rect, or any element with x/y/width/height\n localLeft = parseFloat(el.getAttribute(\"x\") || \"0\");\n localTop = parseFloat(el.getAttribute(\"y\") || \"0\");\n localWidth = parseFloat(el.getAttribute(\"width\") || \"0\");\n localHeight = parseFloat(el.getAttribute(\"height\") || \"0\");\n }\n\n // Skip elements with no meaningful dimensions\n if (localWidth <= 0 && localHeight <= 0) return;\n\n // Add padding for easier clicking (buttons are very thin ~3px)\n const pad = 10;\n targets.push({\n name: buttonName,\n side,\n top: localTop - pad,\n left: localLeft - pad,\n width: localWidth + pad * 2,\n height: localHeight + pad * 2,\n svgEl: el as SVGElement,\n });\n });\n\n setHitTargets(targets);\n return targets.length > 0;\n }, [frameContainerRef]);\n\n useEffect(() => {\n if (!enabled) return;\n\n // Try immediately — button positions are read from SVG attributes\n // (not getBoundingClientRect), so no need to wait for CSS transitions.\n if (discoverButtons()) return;\n\n // SVG not ready yet — retry with increasing delays\n let retryCount = 0;\n const maxRetries = 10;\n let timer: ReturnType<typeof setTimeout>;\n\n const retry = () => {\n if (retryCount >= maxRetries) return;\n retryCount++;\n timer = setTimeout(() => {\n if (!discoverButtons()) retry();\n }, retryCount < 3 ? 100 : 300);\n };\n retry();\n\n return () => clearTimeout(timer);\n }, [enabled, orientation, discoverButtons]);\n\n const applyPress = useCallback((target: ButtonHitTarget) => {\n const pressOffset = target.side === \"left\" ? \"-2px\" : \"2px\";\n const el = target.svgEl;\n (el as HTMLElement).style.transform = `translateX(${pressOffset})`;\n (el as HTMLElement).style.opacity = \"0.7\";\n (el as HTMLElement).style.transition =\n `transform ${PRESS_ANIMATION_IN}ms ease-out, opacity ${PRESS_ANIMATION_IN}ms ease-out`;\n }, []);\n\n const releasePress = useCallback((target: ButtonHitTarget) => {\n const el = target.svgEl;\n (el as HTMLElement).style.transform = \"\";\n (el as HTMLElement).style.opacity = \"\";\n (el as HTMLElement).style.transition =\n `transform ${PRESS_ANIMATION_OUT}ms ease-in, opacity ${PRESS_ANIMATION_OUT}ms ease-in`;\n }, []);\n\n const startRepeat = useCallback((target: ButtonHitTarget) => {\n const isVolumeButton = target.name === \"volumeUp\" || target.name === \"volumeDown\";\n if (!isVolumeButton) return;\n pressStartRef.current = Date.now();\n\n repeatTimerRef.current = setTimeout(() => {\n repeatIntervalRef.current = setInterval(() => {\n onButtonPress?.(target.name);\n const elapsed = Date.now() - pressStartRef.current;\n if (elapsed > REPEAT_FAST_THRESHOLD && repeatIntervalRef.current) {\n clearInterval(repeatIntervalRef.current);\n repeatIntervalRef.current = setInterval(() => {\n onButtonPress?.(target.name);\n }, REPEAT_FAST_INTERVAL);\n }\n }, REPEAT_INTERVAL);\n }, REPEAT_INITIAL_DELAY);\n }, [onButtonPress, clearRepeat]);\n\n if (!enabled || hitTargets.length === 0) return null;\n\n return (\n <>\n {hitTargets.map((target) => (\n <div\n key={target.name}\n style={{\n position: \"absolute\",\n top: target.top,\n left: target.left,\n width: target.width,\n height: target.height,\n cursor: \"pointer\",\n zIndex: 11,\n // Transparent but clickable\n background: \"transparent\",\n }}\n onMouseDown={(e) => {\n e.preventDefault();\n e.stopPropagation();\n applyPress(target);\n onButtonPress?.(target.name);\n startRepeat(target);\n }}\n onMouseUp={(e) => {\n e.preventDefault();\n releasePress(target);\n clearRepeat();\n }}\n onMouseLeave={() => {\n releasePress(target);\n clearRepeat();\n }}\n onTouchStart={(e) => {\n e.preventDefault();\n e.stopPropagation();\n applyPress(target);\n onButtonPress?.(target.name);\n startRepeat(target);\n }}\n onTouchEnd={(e) => {\n e.preventDefault();\n releasePress(target);\n clearRepeat();\n }}\n />\n ))}\n </>\n );\n}\n","import { useState, useEffect, type CSSProperties } from \"react\";\nimport type { DeviceLayoutContract } from \"@biela.dev/devices\";\n\ninterface DynamicStatusBarProps {\n contract: DeviceLayoutContract;\n orientation: \"portrait\" | \"landscape\";\n colorScheme: \"light\" | \"dark\";\n /** Show a live updating clock (default: true) */\n showLiveClock?: boolean;\n /** Fixed time string override (e.g. \"9:41\") — disables live clock */\n fixedTime?: string;\n}\n\nfunction formatTime(date: Date): string {\n const h = date.getHours();\n const m = date.getMinutes();\n const hour = h % 12 || 12;\n return `${hour}:${m.toString().padStart(2, \"0\")}`;\n}\n\n/**\n * DynamicStatusBar — renders ONLY a live clock overlay.\n *\n * The SVG frame already provides all decorative status bar elements\n * (signal bars, wifi, battery). This component only replaces the\n * static time text (e.g. \"9:41\") with a live-updating clock.\n *\n * It renders a small opaque patch behind the clock text so the\n * SVG's baked-in static time is fully covered, then draws the\n * live time on top.\n *\n * Platform-specific clock positions:\n * - iOS Dynamic Island: left side, paddingLeft ~20\n * - iOS Notch: left side, paddingLeft ~20\n * - iOS SE: centered\n * - Android: left side, paddingLeft ~16\n */\nexport function DynamicStatusBar({\n contract,\n orientation,\n colorScheme,\n showLiveClock = true,\n fixedTime,\n}: DynamicStatusBarProps) {\n const [time, setTime] = useState(() => formatTime(new Date()));\n\n useEffect(() => {\n if (fixedTime || !showLiveClock) return;\n\n const interval = setInterval(() => {\n setTime(formatTime(new Date()));\n }, 1000);\n\n return () => clearInterval(interval);\n }, [fixedTime, showLiveClock]);\n\n // iOS hides the status bar in landscape mode\n // (placed after hooks to avoid violating Rules of Hooks)\n if (orientation === \"landscape\" && contract.device.platform === \"ios\") {\n return null;\n }\n\n const displayTime = fixedTime ?? time;\n const { platform } = contract.device;\n const statusBarHeight = contract.statusBar.height;\n const statusBarStyle = contract.statusBar.style;\n\n const textColor = colorScheme === \"dark\" ? \"#fff\" : \"#000\";\n const bgColor = colorScheme === \"dark\" ? \"#000\" : \"#fff\";\n const fontFamily = platform === \"ios\"\n ? \"-apple-system, 'SF Pro Text', 'Helvetica Neue', sans-serif\"\n : \"'Roboto', 'Google Sans', sans-serif\";\n\n const baseFontSize = platform === \"ios\" ? 15 : 12;\n\n // Clock patch: a small opaque box that covers the SVG's static time text,\n // with the live time rendered on top.\n const clockStyle: CSSProperties = {\n color: textColor,\n fontFamily,\n fontSize: baseFontSize,\n fontWeight: platform === \"ios\" ? 600 : 400,\n letterSpacing: platform === \"ios\" ? 0.3 : 0,\n lineHeight: `${statusBarHeight}px`,\n whiteSpace: \"nowrap\",\n };\n\n // The patch background — covers the SVG's static time text\n const patchStyle: CSSProperties = {\n position: \"absolute\",\n top: 0,\n height: statusBarHeight,\n display: \"flex\",\n alignItems: \"center\",\n background: bgColor,\n pointerEvents: \"none\",\n };\n\n // iOS SE / older: centered time\n if (platform === \"ios\" && statusBarStyle !== \"dynamic-island\" && statusBarStyle !== \"notch\") {\n return (\n <div style={{ ...patchStyle, left: \"50%\", transform: \"translateX(-50%)\", paddingLeft: 6, paddingRight: 6 }}>\n <span style={{ ...clockStyle, fontWeight: 500, fontSize: baseFontSize - 1 }}>\n {displayTime}\n </span>\n </div>\n );\n }\n\n // iOS Dynamic Island / Notch: time on the left\n if (platform === \"ios\") {\n return (\n <div style={{ ...patchStyle, left: 0, paddingLeft: 20, paddingRight: 8 }}>\n <span style={clockStyle}>\n {displayTime}\n </span>\n </div>\n );\n }\n\n // Android: time on the left\n return (\n <div style={{ ...patchStyle, left: 0, paddingLeft: 16, paddingRight: 8 }}>\n <span style={clockStyle}>\n {displayTime}\n </span>\n </div>\n );\n}\n","import type { CSSProperties } from \"react\";\n\ninterface StatusBarIndicatorsProps {\n platform: \"ios\" | \"android\";\n colorScheme: \"light\" | \"dark\";\n}\n\n/**\n * Static decorative status bar indicators — signal, wifi, battery.\n * Rendered as small inline SVGs, platform-specific styling.\n */\nexport function StatusBarIndicators({ platform, colorScheme }: StatusBarIndicatorsProps) {\n const color = colorScheme === \"dark\" ? \"#fff\" : \"#000\";\n\n return (\n <div style={styles.container}>\n {/* Signal bars */}\n <svg width=\"17\" height=\"11\" viewBox=\"0 0 17 11\" fill=\"none\">\n <rect x=\"0\" y=\"7\" width=\"3\" height=\"4\" rx=\"0.5\" fill={color} opacity=\"0.4\" />\n <rect x=\"4.5\" y=\"5\" width=\"3\" height=\"6\" rx=\"0.5\" fill={color} opacity=\"0.6\" />\n <rect x=\"9\" y=\"2.5\" width=\"3\" height=\"8.5\" rx=\"0.5\" fill={color} opacity=\"0.8\" />\n <rect x=\"13.5\" y=\"0\" width=\"3\" height=\"11\" rx=\"0.5\" fill={color} />\n </svg>\n\n {/* WiFi icon */}\n <svg width=\"15\" height=\"11\" viewBox=\"0 0 15 11\" fill=\"none\" style={{ marginLeft: 5 }}>\n <path d=\"M7.5 10.5a1 1 0 1 0 0-2 1 1 0 0 0 0 2z\" fill={color} />\n <path d=\"M4.5 7.5a4.2 4.2 0 0 1 6 0\" stroke={color} strokeWidth=\"1.2\" strokeLinecap=\"round\" fill=\"none\" />\n <path d=\"M2 5a7.1 7.1 0 0 1 11 0\" stroke={color} strokeWidth=\"1.2\" strokeLinecap=\"round\" fill=\"none\" />\n <path d=\"M0 2.5a10 10 0 0 1 15 0\" stroke={color} strokeWidth=\"1.2\" strokeLinecap=\"round\" fill=\"none\" />\n </svg>\n\n {/* Battery */}\n <svg width=\"25\" height=\"12\" viewBox=\"0 0 25 12\" fill=\"none\" style={{ marginLeft: 5 }}>\n <rect x=\"0.5\" y=\"0.5\" width=\"21\" height=\"11\" rx=\"2\" stroke={color} strokeWidth=\"1\" fill=\"none\" />\n <rect x=\"2\" y=\"2\" width=\"15\" height=\"8\" rx=\"1\" fill={color} opacity={platform === \"ios\" ? \"0.85\" : \"0.7\"} />\n <path d=\"M22.5 4v4a1.5 1.5 0 0 0 0-4z\" fill={color} opacity=\"0.5\" />\n </svg>\n </div>\n );\n}\n\nconst styles: Record<string, CSSProperties> = {\n container: {\n display: \"flex\",\n alignItems: \"center\",\n gap: 0,\n },\n};\n","import { registerCustomDeviceSVG, type SVGScreenRect } from \"../components/DeviceFrame\";\nimport { getDeviceMetadata } from \"@biela.dev/devices\";\n\nconst SVG_OVERRIDES_KEY = \"bielaframe-svg-overrides\";\n\nexport interface SVGOverrideEntry {\n deviceId: string;\n svgString: string;\n bezelTop: number;\n bezelBottom: number;\n bezelLeft: number;\n bezelRight: number;\n screenRect?: SVGScreenRect;\n updatedAt: string;\n}\n\n/**\n * Persistent storage for custom SVG overrides.\n *\n * When a user uploads a custom SVG frame for a device, it's stored in\n * localStorage and automatically applied on subsequent imports.\n *\n * SSR-safe: falls back to no-op storage when localStorage is unavailable.\n */\nexport class CustomSVGStore {\n private storage: Storage | null;\n\n constructor(storage?: Storage | null) {\n if (storage !== undefined) {\n this.storage = storage;\n } else {\n this.storage =\n typeof localStorage !== \"undefined\" ? localStorage : null;\n }\n }\n\n /** Load all stored overrides */\n getAll(): Record<string, SVGOverrideEntry> {\n if (!this.storage) return {};\n try {\n const raw = this.storage.getItem(SVG_OVERRIDES_KEY);\n if (raw) return JSON.parse(raw);\n } catch { /* ignore */ }\n return {};\n }\n\n /** Save an override and register it in the SVG registry */\n save(entry: SVGOverrideEntry): void {\n const all = this.getAll();\n all[entry.deviceId] = entry;\n this.persist(all);\n\n // Also live-register so the change takes effect immediately\n this.applyEntry(entry);\n }\n\n /** Remove an override (revert to built-in) */\n remove(deviceId: string): void {\n const all = this.getAll();\n delete all[deviceId];\n this.persist(all);\n }\n\n /** Check if a device has a custom override */\n has(deviceId: string): boolean {\n return this.getAll()[deviceId] !== undefined;\n }\n\n /** Get a single override by device ID */\n get(deviceId: string): SVGOverrideEntry | undefined {\n return this.getAll()[deviceId];\n }\n\n /**\n * Apply all stored overrides to the SVG registry.\n * Called during auto-registration to restore user customizations.\n */\n applyAll(): void {\n const all = this.getAll();\n for (const entry of Object.values(all)) {\n this.applyEntry(entry);\n }\n }\n\n private applyEntry(entry: SVGOverrideEntry): void {\n let screenW = 402;\n let screenH = 874;\n let screenR = 0;\n\n try {\n const meta = getDeviceMetadata(entry.deviceId);\n screenW = meta.screen.width;\n screenH = meta.screen.height;\n screenR = meta.screen.cornerRadius;\n } catch {\n // Device not in registry — use screen rect dimensions if available\n if (entry.screenRect) {\n screenW = entry.screenRect.width;\n screenH = entry.screenRect.height;\n }\n }\n\n const frame = {\n bezelTop: entry.bezelTop,\n bezelBottom: entry.bezelBottom,\n bezelLeft: entry.bezelLeft,\n bezelRight: entry.bezelRight,\n totalWidth: entry.bezelLeft + entry.bezelRight + screenW,\n totalHeight: entry.bezelTop + entry.bezelBottom + screenH,\n screenWidth: screenW,\n screenHeight: screenH,\n screenRadius: screenR,\n };\n\n try {\n registerCustomDeviceSVG(\n entry.deviceId,\n entry.svgString,\n frame,\n undefined,\n entry.screenRect,\n );\n } catch {\n // Registration may fail for missing metadata; skip silently\n }\n }\n\n private persist(all: Record<string, SVGOverrideEntry>): void {\n if (!this.storage) return;\n const json = JSON.stringify(all);\n try {\n this.storage.setItem(SVG_OVERRIDES_KEY, json);\n } catch { /* storage full or unavailable */ }\n }\n}\n\n// Singleton\nlet _store: CustomSVGStore | null = null;\n\n/** Get the default CustomSVGStore instance (singleton, uses localStorage) */\nexport function getCustomSVGStore(): CustomSVGStore {\n if (!_store) {\n _store = new CustomSVGStore();\n }\n return _store;\n}\n"]}