afterbefore 0.2.26 → 0.2.27
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/overlay/index.js +628 -437
- package/dist/overlay/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/overlay/index.tsx","../../src/overlay/state.ts","../../src/overlay/capture.ts","../../src/overlay/font.ts","../../src/overlay/ui/toolbar.tsx","../../src/overlay/ui/icons.tsx","../../src/overlay/color.ts","../../src/overlay/ui/screenshots-panel.tsx","../../src/overlay/ui/settings-panel.tsx","../../src/overlay/ui/inspector.tsx"],"sourcesContent":["\"use client\";\n\nimport React, { useState, useCallback, useEffect } from \"react\";\nimport { useOverlayState } from \"./state\";\nimport type { CaptureMode } from \"./state\";\nimport { capture, renderFrame, DEFAULT_FRAME_SETTINGS, type FrameSettings } from \"./capture\";\nimport { injectInterFont } from \"./font\";\nimport { Toolbar } from \"./ui/toolbar\";\nimport { Inspector } from \"./ui/inspector\";\n\nasync function saveCapture(\n mode: CaptureMode,\n renderedDataUrl: string,\n rawDataUrl: string,\n viewportDataUrl: string | null,\n) {\n try {\n const res = await fetch(\"/__afterbefore/save\", {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n mode,\n image: renderedDataUrl,\n rawImage: rawDataUrl,\n viewportImage: viewportDataUrl,\n }),\n });\n if (!res.ok) throw new Error(\"Save failed\");\n } catch {\n const link = document.createElement(\"a\");\n link.download = \"screenshot.png\";\n link.href = renderedDataUrl;\n link.click();\n }\n}\n\nexport function AfterBefore() {\n const { state, captureComplete, reset } = useOverlayState();\n const [toolbarActive, setToolbarActive] = useState(false);\n const [inspectorActive, setInspectorActive] = useState(false);\n const [loading, setLoading] = useState(false);\n const [selectedMode, setSelectedMode] = useState<CaptureMode>(\"component\");\n const [frameSettings, setFrameSettings] = useState<FrameSettings>(DEFAULT_FRAME_SETTINGS);\n\n useEffect(() => {\n injectInterFont();\n }, []);\n\n useEffect(() => {\n try {\n const stored = localStorage.getItem(\"ab-frame-settings\");\n if (stored) {\n setFrameSettings({ ...DEFAULT_FRAME_SETTINGS, ...JSON.parse(stored) });\n } else if (localStorage.getItem(\"ab-frame-black\") === \"true\") {\n // Migration from old boolean setting\n const migrated = { ...DEFAULT_FRAME_SETTINGS, enabled: true };\n setFrameSettings(migrated);\n localStorage.setItem(\"ab-frame-settings\", JSON.stringify(migrated));\n localStorage.removeItem(\"ab-frame-black\");\n }\n } catch {\n setFrameSettings(DEFAULT_FRAME_SETTINGS);\n }\n }, []);\n\n useEffect(() => {\n if (state.phase === \"ready\") {\n const timer = setTimeout(() => {\n reset();\n }, 1500);\n return () => clearTimeout(timer);\n }\n }, [state.phase, reset]);\n\n const handleToggle = useCallback(() => {\n if (loading) return;\n\n if (state.phase === \"ready\") {\n reset();\n }\n\n if (toolbarActive || inspectorActive) {\n setToolbarActive(false);\n setInspectorActive(false);\n } else {\n if (selectedMode === \"component\") {\n setToolbarActive(true);\n setInspectorActive(true);\n } else {\n setToolbarActive(true);\n setInspectorActive(false);\n }\n }\n }, [state.phase, loading, toolbarActive, inspectorActive, selectedMode, reset]);\n\n const performCapture = useCallback(\n async (\n mode: CaptureMode,\n element?: HTMLElement,\n ) => {\n setLoading(true);\n try {\n const raw = await capture({ mode, element });\n\n // Choose the right image for rendering: viewport when chrome is ON, else component\n const primaryImage = frameSettings.browserChrome && raw.viewportDataUrl\n ? raw.viewportDataUrl\n : raw.dataUrl;\n const renderedDataUrl = await renderFrame(primaryImage, frameSettings);\n\n await saveCapture(mode, renderedDataUrl, raw.dataUrl, raw.viewportDataUrl);\n captureComplete({\n dataUrl: renderedDataUrl,\n mode,\n timestamp: Date.now(),\n });\n } catch (err) {\n console.error(\"[afterbefore] Capture failed:\", err);\n } finally {\n setLoading(false);\n }\n },\n [captureComplete, frameSettings],\n );\n\n const handleToolbarCapture = useCallback(\n (mode: CaptureMode) => {\n if (mode === \"viewport\") {\n setToolbarActive(false);\n performCapture(\"viewport\");\n } else if (mode === \"fullpage\") {\n setToolbarActive(false);\n performCapture(\"fullpage\");\n } else if (mode === \"component\") {\n setInspectorActive(true);\n }\n },\n [performCapture],\n );\n\n const handleToolbarCancel = useCallback(() => {\n setToolbarActive(false);\n setInspectorActive(false);\n }, []);\n\n const handleComponentSelect = useCallback(\n (element: HTMLElement) => {\n setInspectorActive(false);\n setToolbarActive(false);\n performCapture(\"component\", element);\n },\n [performCapture],\n );\n\n const handleComponentCancel = useCallback(() => {\n setInspectorActive(false);\n setToolbarActive(true);\n }, []);\n\n const handleFrameSettingsChange = useCallback((next: FrameSettings) => {\n setFrameSettings(next);\n try {\n localStorage.setItem(\"ab-frame-settings\", JSON.stringify(next));\n } catch {\n // noop\n }\n }, []);\n\n const handleModeChange = useCallback((mode: CaptureMode) => {\n setSelectedMode(mode);\n setInspectorActive(mode === \"component\");\n }, []);\n\n return (\n <div data-afterbefore=\"true\">\n <Toolbar\n expanded={toolbarActive}\n onToggle={handleToggle}\n phase={state.phase}\n loading={loading}\n selectedMode={selectedMode}\n onModeChange={handleModeChange}\n onCapture={handleToolbarCapture}\n onCancel={handleToolbarCancel}\n frameSettings={frameSettings}\n onFrameSettingsChange={handleFrameSettingsChange}\n />\n\n {inspectorActive && (\n <Inspector onSelect={handleComponentSelect} onCancel={handleComponentCancel} />\n )}\n </div>\n );\n}\n","import { useState, useCallback } from \"react\";\n\nexport type CaptureMode = \"viewport\" | \"fullpage\" | \"component\";\n\nexport type OverlayPhase = \"idle\" | \"ready\";\n\nexport interface CaptureResult {\n dataUrl: string;\n mode: CaptureMode;\n timestamp: number;\n}\n\nexport interface OverlayState {\n phase: OverlayPhase;\n lastCapture: CaptureResult | null;\n}\n\nconst initialState: OverlayState = {\n phase: \"idle\",\n lastCapture: null,\n};\n\nexport function useOverlayState() {\n const [state, setState] = useState<OverlayState>(initialState);\n\n const captureComplete = useCallback(\n (result: CaptureResult) => {\n setState({ phase: \"ready\", lastCapture: result });\n },\n [],\n );\n\n const reset = useCallback(() => {\n setState(initialState);\n }, []);\n\n return { state, captureComplete, reset };\n}\n","import { snapdom } from \"@zumer/snapdom\";\nimport type { CaptureMode } from \"./state\";\n\nexport interface FrameSettings {\n enabled: boolean;\n size: { w: number; h: number };\n bgType: \"color\" | \"gradient\" | \"image\";\n bgColor: string;\n bgGradient: string;\n bgImage: string | null;\n padding: number;\n browserChrome: boolean;\n browserTheme: \"light\" | \"dark\";\n browserUrl: string;\n browserShadow: number;\n browserRadius: number;\n}\n\nexport const GRADIENT_PRESETS = [\n \"linear-gradient(135deg, #a78bfa 0%, #f472b6 100%)\",\n \"linear-gradient(135deg, #3b82f6 0%, #06b6d4 100%)\",\n \"linear-gradient(135deg, #34d399 0%, #6ee7b7 100%)\",\n \"linear-gradient(135deg, #f97316 0%, #ef4444 100%)\",\n \"linear-gradient(180deg, #1e293b 0%, #0f172a 100%)\",\n];\n\nexport const COLOR_PRESETS = [\n \"#FFFFFF\",\n \"#F5F5F5\",\n \"#F8F4ED\",\n \"#1E1E1E\",\n \"#000000\",\n];\n\nexport const DEFAULT_FRAME_SETTINGS: FrameSettings = {\n enabled: false,\n size: { w: 1920, h: 1080 },\n bgType: \"color\",\n bgColor: \"#F5F5F5\",\n bgGradient: GRADIENT_PRESETS[0],\n bgImage: null,\n padding: 40,\n browserChrome: false,\n browserTheme: \"dark\",\n browserUrl: \"localhost\",\n browserShadow: 50,\n browserRadius: 8,\n};\n\nexport const FRAME_SIZE_PRESETS: { label: string; hint: string; w: number; h: number }[] = [\n { label: \"1920 x 1080\", hint: \"Desktop / HD\", w: 1920, h: 1080 },\n { label: \"1080 x 1080\", hint: \"Social square\", w: 1080, h: 1080 },\n { label: \"1200 x 630\", hint: \"Open Graph / link preview\", w: 1200, h: 630 },\n { label: \"1080 x 1920\", hint: \"Story / portrait\", w: 1080, h: 1920 },\n];\n\nexport interface RawCapture {\n dataUrl: string;\n viewportDataUrl: string | null;\n}\n\ninterface CaptureOptions {\n mode: CaptureMode;\n element?: HTMLElement;\n}\n\n/** Selectors for dev tool UI that should be excluded from capture */\nconst DEV_UI_SELECTORS = [\n // Afterbefore overlay\n \"[data-afterbefore]\",\n // Next.js dev indicators\n \"[data-nextjs-toast]\",\n \"[data-nextjs-dev-overlay]\",\n \"[data-nextjs-dialog]\",\n \"[data-nextjs-dialog-backdrop]\",\n \"[data-next-badge]\",\n \"[data-next-mark]\",\n];\n\nconst SNAPDOM_BASE = {\n exclude: DEV_UI_SELECTORS,\n excludeMode: \"remove\" as const,\n};\n\nasync function toPngDataUrl(\n el: Element,\n opts?: Record<string, unknown>,\n): Promise<string> {\n const result = await snapdom(el, { ...SNAPDOM_BASE, ...opts });\n const img = await result.toPng();\n return img.src;\n}\n\nexport async function capture(options: CaptureOptions): Promise<RawCapture> {\n const { mode, element } = options;\n\n if (mode === \"viewport\") {\n return { dataUrl: await captureRawViewport(), viewportDataUrl: null };\n }\n if (mode === \"fullpage\") {\n return { dataUrl: await captureFullPage(), viewportDataUrl: null };\n }\n if (mode === \"component\" && element) {\n const dataUrl = await toPngDataUrl(element);\n const viewportDataUrl = await captureRawViewport();\n return { dataUrl, viewportDataUrl };\n }\n throw new Error(`Invalid capture mode: ${mode}`);\n}\n\nasync function captureRawViewport(): Promise<string> {\n const dpr = window.devicePixelRatio || 1;\n const vw = window.innerWidth;\n const vh = window.innerHeight;\n const scrollY = window.scrollY;\n\n const fullDataUrl = await captureFullPage();\n const fullImg = await loadImage(fullDataUrl);\n\n const canvas = document.createElement(\"canvas\");\n canvas.width = vw * dpr;\n canvas.height = vh * dpr;\n\n const ctx = canvas.getContext(\"2d\")!;\n ctx.drawImage(\n fullImg,\n 0,\n scrollY * dpr,\n vw * dpr,\n vh * dpr,\n 0,\n 0,\n vw * dpr,\n vh * dpr,\n );\n\n return canvas.toDataURL(\"image/png\");\n}\n\nfunction drawBrowserChrome(\n img: HTMLImageElement,\n theme: \"light\" | \"dark\",\n dpr: number,\n url = \"localhost\",\n): string {\n const TITLE_BAR_H = 40;\n const URL_BAR_H = 28;\n const URL_BAR_MARGIN_TOP = 6;\n const URL_BAR_MARGIN_BOTTOM = 6;\n const CHROME_H = TITLE_BAR_H + URL_BAR_H + URL_BAR_MARGIN_TOP + URL_BAR_MARGIN_BOTTOM;\n\n const imgW = img.width;\n const imgH = img.height;\n\n const canvas = document.createElement(\"canvas\");\n canvas.width = imgW;\n canvas.height = imgH + CHROME_H * dpr;\n\n const ctx = canvas.getContext(\"2d\")!;\n\n // Theme colors\n const colors =\n theme === \"dark\"\n ? { titleBar: \"#1C1C1C\", urlBar: \"#262626\", text: \"#7B7B7B\", border: \"#333333\" }\n : { titleBar: \"#F5F5F5\", urlBar: \"#FFFFFF\", text: \"#999999\", border: \"#EBEBEB\" };\n\n // Title bar background\n ctx.fillStyle = colors.titleBar;\n ctx.fillRect(0, 0, canvas.width, CHROME_H * dpr);\n\n // Bottom border of chrome\n ctx.fillStyle = colors.border;\n ctx.fillRect(0, (CHROME_H - 1) * dpr, canvas.width, dpr);\n\n // Traffic light dots\n const dotY = (TITLE_BAR_H / 2) * dpr;\n const dotR = 6 * dpr;\n const dotStartX = 18 * dpr;\n const dotGap = 20 * dpr;\n const dotColors = [\"#FF5F57\", \"#FEBC2E\", \"#28C840\"];\n\n for (let i = 0; i < 3; i++) {\n ctx.beginPath();\n ctx.arc(dotStartX + i * dotGap, dotY, dotR, 0, Math.PI * 2);\n ctx.fillStyle = dotColors[i];\n ctx.fill();\n }\n\n // URL bar (centered in remaining space below title bar)\n const urlBarY = (TITLE_BAR_H + URL_BAR_MARGIN_TOP) * dpr;\n const urlBarPadX = 80 * dpr;\n const urlBarX = urlBarPadX;\n const urlBarW = canvas.width - urlBarPadX * 2;\n const urlBarH = URL_BAR_H * dpr;\n const urlBarR = 6 * dpr;\n\n ctx.fillStyle = colors.urlBar;\n roundRect(ctx, urlBarX, urlBarY, urlBarW, urlBarH, urlBarR);\n ctx.fill();\n\n if (theme === \"light\") {\n ctx.strokeStyle = colors.border;\n ctx.lineWidth = dpr;\n roundRect(ctx, urlBarX, urlBarY, urlBarW, urlBarH, urlBarR);\n ctx.stroke();\n }\n\n // URL text placeholder\n ctx.fillStyle = colors.text;\n ctx.font = `${11 * dpr}px -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif`;\n ctx.textAlign = \"center\";\n ctx.textBaseline = \"middle\";\n ctx.fillText(url, canvas.width / 2, urlBarY + urlBarH / 2);\n\n // Draw the viewport image below chrome\n ctx.drawImage(img, 0, CHROME_H * dpr);\n\n return canvas.toDataURL(\"image/png\");\n}\n\nfunction roundRect(\n ctx: CanvasRenderingContext2D,\n x: number,\n y: number,\n w: number,\n h: number,\n r: number,\n) {\n ctx.beginPath();\n ctx.moveTo(x + r, y);\n ctx.lineTo(x + w - r, y);\n ctx.quadraticCurveTo(x + w, y, x + w, y + r);\n ctx.lineTo(x + w, y + h - r);\n ctx.quadraticCurveTo(x + w, y + h, x + w - r, y + h);\n ctx.lineTo(x + r, y + h);\n ctx.quadraticCurveTo(x, y + h, x, y + h - r);\n ctx.lineTo(x, y + r);\n ctx.quadraticCurveTo(x, y, x + r, y);\n ctx.closePath();\n}\n\nasync function captureFullPage(): Promise<string> {\n const scrollY = window.scrollY;\n const body = document.body;\n const html = document.documentElement;\n\n const fullHeight = Math.max(\n body.scrollHeight,\n body.offsetHeight,\n html.clientHeight,\n html.scrollHeight,\n html.offsetHeight,\n );\n\n const prevOverflow = html.style.overflow;\n const prevHeight = html.style.height;\n html.style.overflow = \"visible\";\n html.style.height = `${fullHeight}px`;\n\n try {\n return await toPngDataUrl(document.documentElement, {\n width: window.innerWidth,\n height: fullHeight,\n });\n } finally {\n html.style.overflow = prevOverflow;\n html.style.height = prevHeight;\n window.scrollTo(0, scrollY);\n }\n}\n\nexport async function renderFrame(\n imageDataUrl: string,\n frameSettings: FrameSettings,\n): Promise<string> {\n if (!frameSettings.enabled) {\n return imageDataUrl;\n }\n\n const img = await loadImage(imageDataUrl);\n const dpr = window.devicePixelRatio || 1;\n\n const FRAME_W = frameSettings.size.w;\n const FRAME_H = frameSettings.size.h;\n const pad = frameSettings.padding ?? 40;\n\n // If browser chrome is ON, wrap content in chrome first\n let contentImg = img;\n if (frameSettings.browserChrome) {\n const chromeDataUrl = drawBrowserChrome(img, frameSettings.browserTheme, dpr, frameSettings.browserUrl);\n contentImg = await loadImage(chromeDataUrl);\n }\n\n // Content dimensions in CSS pixels\n const contentW = contentImg.width / dpr;\n const contentH = contentImg.height / dpr;\n\n // Scale to fit within frame minus padding on all sides\n const maxW = FRAME_W - pad * 2;\n const maxH = FRAME_H - pad * 2;\n const scale = Math.min(maxW / contentW, maxH / contentH, 1);\n\n const drawW = contentW * scale * dpr;\n const drawH = contentH * scale * dpr;\n\n const canvas = document.createElement(\"canvas\");\n canvas.width = FRAME_W * dpr;\n canvas.height = FRAME_H * dpr;\n\n const ctx = canvas.getContext(\"2d\")!;\n\n // Draw background\n if (frameSettings.bgType === \"image\" && frameSettings.bgImage) {\n try {\n const bgImg = await loadImage(frameSettings.bgImage);\n drawCover(ctx, bgImg, canvas.width, canvas.height);\n } catch {\n ctx.fillStyle = frameSettings.bgColor;\n ctx.fillRect(0, 0, canvas.width, canvas.height);\n }\n } else if (frameSettings.bgType === \"gradient\") {\n fillCssGradient(ctx, frameSettings.bgGradient, canvas.width, canvas.height);\n } else if (frameSettings.bgColor !== \"transparent\") {\n ctx.fillStyle = frameSettings.bgColor;\n ctx.fillRect(0, 0, canvas.width, canvas.height);\n }\n\n // Center the content\n const dx = (canvas.width - drawW) / 2;\n const dy = (canvas.height - drawH) / 2;\n\n // Apply shadow when browser chrome is ON\n const shadowVal = frameSettings.browserShadow ?? 50;\n if (frameSettings.browserChrome && shadowVal > 0) {\n const alpha = (shadowVal / 100) * 0.6;\n ctx.shadowColor = `rgba(0, 0, 0, ${alpha})`;\n ctx.shadowBlur = (shadowVal / 100) * 40 * dpr;\n ctx.shadowOffsetY = (shadowVal / 100) * 8 * dpr;\n ctx.shadowOffsetX = 0;\n }\n\n ctx.drawImage(contentImg, dx, dy, drawW, drawH);\n\n // Reset shadow\n ctx.shadowColor = \"transparent\";\n ctx.shadowBlur = 0;\n ctx.shadowOffsetY = 0;\n\n return canvas.toDataURL(\"image/png\");\n}\n\n/** Draw image with cover-fit (like CSS background-size: cover) */\nfunction drawCover(\n ctx: CanvasRenderingContext2D,\n img: HTMLImageElement,\n cw: number,\n ch: number,\n) {\n const scale = Math.max(cw / img.width, ch / img.height);\n const sw = cw / scale;\n const sh = ch / scale;\n const sx = (img.width - sw) / 2;\n const sy = (img.height - sh) / 2;\n ctx.drawImage(img, sx, sy, sw, sh, 0, 0, cw, ch);\n}\n\nfunction loadImage(src: string): Promise<HTMLImageElement> {\n return new Promise((resolve, reject) => {\n const img = new Image();\n img.onload = () => resolve(img);\n img.onerror = reject;\n img.src = src;\n });\n}\n\n/** Parse a CSS linear-gradient and draw it on a canvas context */\nfunction fillCssGradient(\n ctx: CanvasRenderingContext2D,\n css: string,\n w: number,\n h: number,\n) {\n const match = css.match(\n /linear-gradient\\(\\s*([\\d.]+)deg\\s*,\\s*(.+)\\)/,\n );\n if (!match) {\n ctx.fillStyle = \"#000\";\n ctx.fillRect(0, 0, w, h);\n return;\n }\n\n const angle = (parseFloat(match[1]) * Math.PI) / 180;\n const stopsRaw = match[2].split(/,\\s*(?=#|\\w)/).map((s) => s.trim());\n\n // Gradient line endpoints from CSS angle\n const cx = w / 2;\n const cy = h / 2;\n const len = Math.abs(w * Math.sin(angle)) + Math.abs(h * Math.cos(angle));\n const x0 = cx - (Math.sin(angle) * len) / 2;\n const y0 = cy + (Math.cos(angle) * len) / 2;\n const x1 = cx + (Math.sin(angle) * len) / 2;\n const y1 = cy - (Math.cos(angle) * len) / 2;\n\n const grad = ctx.createLinearGradient(x0, y0, x1, y1);\n for (const stop of stopsRaw) {\n const parts = stop.match(/^(.+?)\\s+([\\d.]+)%$/);\n if (parts) {\n grad.addColorStop(parseFloat(parts[2]) / 100, parts[1]);\n }\n }\n ctx.fillStyle = grad;\n ctx.fillRect(0, 0, w, h);\n}\n","import type React from \"react\";\n\nexport const FONT_FAMILY =\n \"'Inter var', 'Inter', system-ui, -apple-system, sans-serif\";\n\nexport const FONT_FEATURE_SETTINGS = \"'ss11' 1, 'calt' 1\";\n\n/** Spread on root container to set font family + features */\nexport const fontBase: React.CSSProperties = {\n fontFamily: FONT_FAMILY,\n fontFeatureSettings: FONT_FEATURE_SETTINGS,\n};\n\n// ---------------------------------------------------------------------------\n// Align UI Type System — Inter\n// ---------------------------------------------------------------------------\n//\n// Four categories: title, label, paragraph, subheading\n// Font: Inter | Weight: 500 (label/title/subheading), 400 (paragraph)\n// Subheadings are uppercase by default.\n//\n// Letter-spacing values are from Inter's dynamic metrics\n// (percentages converted to em: -1% → -0.01em).\n// ---------------------------------------------------------------------------\n\nfunction style(\n fontSize: number,\n lineHeight: number,\n fontWeight: 400 | 500,\n letterSpacing: string,\n extra?: React.CSSProperties,\n): React.CSSProperties {\n return { fontSize, lineHeight: `${lineHeight}px`, fontWeight, letterSpacing, ...extra };\n}\n\nexport const text = {\n // --- Title (Medium 500) ---\n title: {\n h1: style(56, 64, 500, \"-0.01em\"),\n h2: style(48, 56, 500, \"-0.01em\"),\n h3: style(40, 48, 500, \"-0.01em\"),\n h4: style(32, 40, 500, \"-0.005em\"),\n h5: style(24, 32, 500, \"0em\"),\n h6: style(20, 28, 500, \"0em\"),\n },\n\n // --- Label (Medium 500) ---\n label: {\n xl: style(24, 32, 500, \"-0.015em\"),\n lg: style(18, 24, 500, \"-0.015em\"),\n md: style(16, 24, 500, \"-0.011em\"),\n sm: style(14, 20, 500, \"-0.006em\"),\n xs: style(12, 16, 500, \"0em\"),\n },\n\n // --- Paragraph (Regular 400) ---\n paragraph: {\n xl: style(24, 32, 400, \"-0.015em\"),\n lg: style(18, 24, 400, \"-0.015em\"),\n md: style(16, 24, 400, \"-0.011em\"),\n sm: style(14, 20, 400, \"-0.006em\"),\n xs: style(12, 16, 400, \"0em\"),\n },\n\n // --- Subheading (Medium 500, uppercase) ---\n subheading: {\n md: style(16, 24, 500, \"0.06em\", { textTransform: \"uppercase\" }),\n sm: style(14, 20, 500, \"0.06em\", { textTransform: \"uppercase\" }),\n xs: style(12, 16, 500, \"0.04em\", { textTransform: \"uppercase\" }),\n xxs: style(11, 12, 500, \"0.02em\", { textTransform: \"uppercase\" }),\n },\n} as const;\n\n// ---------------------------------------------------------------------------\n// Font injection (loads Inter from rsms.me at runtime)\n// ---------------------------------------------------------------------------\n\nconst INTER_CSS_ID = \"afterbefore-inter-font\";\n\nexport function injectInterFont() {\n if (document.getElementById(INTER_CSS_ID)) return;\n\n const preconnect = document.createElement(\"link\");\n preconnect.rel = \"preconnect\";\n preconnect.href = \"https://rsms.me/\";\n document.head.appendChild(preconnect);\n\n const stylesheet = document.createElement(\"link\");\n stylesheet.id = INTER_CSS_ID;\n stylesheet.rel = \"stylesheet\";\n stylesheet.href = \"https://rsms.me/inter/inter.css\";\n document.head.appendChild(stylesheet);\n}\n","\"use client\";\n\nimport React, { useCallback, useEffect, useRef, useState } from \"react\";\nimport {\n ChevronDown,\n LoaderCircle,\n FileText,\n Monitor,\n} from \"lucide-react\";\nimport { CameraIcon, CheckmarkIcon, CloseIcon } from \"./icons\";\nimport type { CaptureMode } from \"../state\";\nimport type { OverlayPhase } from \"../state\";\nimport { type FrameSettings } from \"../capture\";\nimport { fontBase, text } from \"../font\";\nimport { bg, fg, stroke, state, accent as accentToken, shadow } from \"../color\";\nimport { ScreenshotsPanel } from \"./screenshots-panel\";\n\n// --- Tooltip warmup: delay on first hover, instant while \"warm\" ---\nconst TOOLTIP_DELAY = 500; // ms before first tooltip appears\nconst TOOLTIP_COOLDOWN = 300; // ms after leaving before delay resets\n\nlet tooltipWarm = false;\nlet tooltipCooldownTimer: ReturnType<typeof setTimeout> | null = null;\n\nfunction useTooltipDelay(hovered: boolean) {\n const [visible, setVisible] = useState(false);\n const delayRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n useEffect(() => {\n if (!hovered) {\n setVisible(false);\n if (delayRef.current) { clearTimeout(delayRef.current); delayRef.current = null; }\n // Start cooldown — if no other tooltip opens, reset warmup\n if (tooltipCooldownTimer) clearTimeout(tooltipCooldownTimer);\n tooltipCooldownTimer = setTimeout(() => { tooltipWarm = false; }, TOOLTIP_COOLDOWN);\n return;\n }\n\n // Hovering\n if (tooltipCooldownTimer) { clearTimeout(tooltipCooldownTimer); tooltipCooldownTimer = null; }\n\n if (tooltipWarm) {\n setVisible(true);\n } else {\n delayRef.current = setTimeout(() => {\n tooltipWarm = true;\n setVisible(true);\n }, TOOLTIP_DELAY);\n }\n\n return () => { if (delayRef.current) { clearTimeout(delayRef.current); delayRef.current = null; } };\n }, [hovered]);\n\n return visible;\n}\n\ntype Corner = \"bottom-right\" | \"bottom-left\" | \"top-right\" | \"top-left\";\nconst EDGE_MARGIN = 24;\nconst CONTAINER_SIZE = 38;\n\nfunction getCornerStyle(corner: Corner): React.CSSProperties {\n switch (corner) {\n case \"bottom-right\":\n return { bottom: EDGE_MARGIN, right: EDGE_MARGIN };\n case \"bottom-left\":\n return { bottom: EDGE_MARGIN, left: EDGE_MARGIN };\n case \"top-right\":\n return { top: EDGE_MARGIN, right: EDGE_MARGIN };\n case \"top-left\":\n return { top: EDGE_MARGIN, left: EDGE_MARGIN };\n }\n}\n\nfunction isBottomCorner(corner: Corner): boolean {\n return corner === \"bottom-right\" || corner === \"bottom-left\";\n}\n\nfunction isRightCorner(corner: Corner): boolean {\n return corner === \"bottom-right\" || corner === \"top-right\";\n}\n\nfunction snapToCorner(x: number, y: number): Corner {\n const cx = window.innerWidth / 2;\n const cy = window.innerHeight / 2;\n if (x < cx) {\n return y < cy ? \"top-left\" : \"bottom-left\";\n }\n return y < cy ? \"top-right\" : \"bottom-right\";\n}\n\nfunction getCornerPosition(corner: Corner, w: number, h: number): { x: number; y: number } {\n const vw = window.innerWidth;\n const vh = window.innerHeight;\n switch (corner) {\n case \"bottom-right\":\n return { x: vw - EDGE_MARGIN - w, y: vh - EDGE_MARGIN - h };\n case \"bottom-left\":\n return { x: EDGE_MARGIN, y: vh - EDGE_MARGIN - h };\n case \"top-right\":\n return { x: vw - EDGE_MARGIN - w, y: EDGE_MARGIN };\n case \"top-left\":\n return { x: EDGE_MARGIN, y: EDGE_MARGIN };\n }\n}\n\ninterface ToolbarProps {\n expanded: boolean;\n onToggle: () => void;\n phase: OverlayPhase;\n loading: boolean;\n selectedMode: CaptureMode;\n onModeChange: (mode: CaptureMode) => void;\n onCapture: (mode: CaptureMode) => void;\n onCancel: () => void;\n frameSettings: FrameSettings;\n onFrameSettingsChange: (settings: FrameSettings) => void;\n}\n\nconst MODES: { mode: CaptureMode; label: string; icon: React.ComponentType<{ size?: number; strokeWidth?: number }> }[] = [\n { mode: \"component\", label: \"Component\", icon: CameraIcon },\n { mode: \"viewport\", label: \"Viewport\", icon: Monitor },\n { mode: \"fullpage\", label: \"Full Page\", icon: FileText },\n];\n\nexport function Toolbar({\n expanded,\n onToggle,\n phase,\n loading,\n selectedMode,\n onModeChange,\n onCapture,\n onCancel,\n frameSettings,\n onFrameSettingsChange,\n}: ToolbarProps) {\n const [historyOpen, setHistoryOpen] = useState(false);\n const [modesExpanded, setModesExpanded] = useState(false);\n\n // Animate toolbar expand/collapse\n const [buttonsVisible, setButtonsVisible] = useState(expanded);\n const [animIn, setAnimIn] = useState(expanded);\n const [animDone, setAnimDone] = useState(expanded);\n\n useEffect(() => {\n if (expanded) {\n setAnimDone(false);\n setButtonsVisible(true);\n setAnimIn(false);\n requestAnimationFrame(() => {\n requestAnimationFrame(() => setAnimIn(true));\n });\n const timer = setTimeout(() => setAnimDone(true), 250);\n return () => clearTimeout(timer);\n } else if (buttonsVisible) {\n setHistoryOpen(false);\n setAnimDone(false);\n setAnimIn(false);\n const timer = setTimeout(() => setButtonsVisible(false), 150);\n return () => clearTimeout(timer);\n }\n }, [expanded]);\n const [corner, setCorner] = useState<Corner>(() => {\n try {\n const stored = localStorage.getItem(\"ab-toolbar-corner\");\n if (stored && [\"bottom-right\", \"bottom-left\", \"top-right\", \"top-left\"].includes(stored)) {\n return stored as Corner;\n }\n } catch {}\n return \"bottom-right\";\n });\n\n // Drag state\n const [dragging, setDragging] = useState(false);\n const [dragPos, setDragPos] = useState<{ x: number; y: number } | null>(null);\n const [snapAnim, setSnapAnim] = useState<{ x: number; y: number; animate: boolean } | null>(null);\n const dragState = useRef<{\n dragging: boolean;\n startX: number;\n startY: number;\n origX: number;\n origY: number;\n distance: number;\n } | null>(null);\n const toolbarRef = useRef<HTMLDivElement>(null);\n\n // Camera button hover\n const [cameraHovered, setCameraHovered] = useState(false);\n const cameraTooltipVisible = useTooltipDelay(cameraHovered && !!expanded);\n\n useEffect(() => {\n if (!expanded) return;\n const onKey = (e: KeyboardEvent) => {\n if ((e.target as HTMLElement)?.tagName === \"INPUT\") {\n if (e.key === \"Escape\") {\n (e.target as HTMLElement).blur();\n }\n return;\n }\n\n if (e.key === \"Escape\") {\n if (historyOpen) {\n setHistoryOpen(false);\n return;\n }\n onCancel();\n } else if (e.key === \"Enter\") {\n onCapture(selectedMode);\n }\n };\n\n document.addEventListener(\"keydown\", onKey);\n return () => document.removeEventListener(\"keydown\", onKey);\n }, [expanded, onCancel, onCapture, selectedMode, historyOpen]);\n\n // Drag handlers\n const handleMouseDown = useCallback(\n (e: React.MouseEvent) => {\n e.preventDefault();\n const el = toolbarRef.current;\n if (!el) return;\n const rect = el.getBoundingClientRect();\n setDragging(true);\n setDragPos({ x: rect.left, y: rect.top });\n dragState.current = {\n dragging: true,\n startX: e.clientX,\n startY: e.clientY,\n origX: rect.left,\n origY: rect.top,\n distance: 0,\n };\n },\n [],\n );\n\n useEffect(() => {\n const handleMouseMove = (e: MouseEvent) => {\n const ds = dragState.current;\n if (!ds || !ds.dragging) return;\n\n const dx = e.clientX - ds.startX;\n const dy = e.clientY - ds.startY;\n ds.distance = Math.sqrt(dx * dx + dy * dy);\n\n setDragPos({\n x: ds.origX + dx,\n y: ds.origY + dy,\n });\n };\n\n const handleMouseUp = (e: MouseEvent) => {\n const ds = dragState.current;\n if (!ds) return;\n\n if (ds.distance < 5) {\n onToggle();\n setDragging(false);\n setDragPos(null);\n dragState.current = null;\n } else {\n // Snap to nearest corner based on toolbar center\n const el = toolbarRef.current;\n const w = el?.offsetWidth ?? CONTAINER_SIZE;\n const h = el?.offsetHeight ?? CONTAINER_SIZE;\n const currentX = ds.origX + (e.clientX - ds.startX);\n const currentY = ds.origY + (e.clientY - ds.startY);\n const centerX = currentX + w / 2;\n const centerY = currentY + h / 2;\n const newCorner = snapToCorner(centerX, centerY);\n setCorner(newCorner);\n try {\n localStorage.setItem(\"ab-toolbar-corner\", newCorner);\n } catch {}\n\n // Animate snap: first render at current position, then transition to target\n const targetPos = getCornerPosition(newCorner, w, h);\n setDragging(false);\n setDragPos(null);\n setSnapAnim({ x: currentX, y: currentY, animate: false });\n dragState.current = null;\n\n requestAnimationFrame(() => {\n requestAnimationFrame(() => {\n setSnapAnim({ ...targetPos, animate: true });\n setTimeout(() => setSnapAnim(null), 300);\n });\n });\n }\n };\n\n window.addEventListener(\"mousemove\", handleMouseMove);\n window.addEventListener(\"mouseup\", handleMouseUp);\n return () => {\n window.removeEventListener(\"mousemove\", handleMouseMove);\n window.removeEventListener(\"mouseup\", handleMouseUp);\n };\n }, [onToggle]);\n\n const panelSide: \"left\" | \"right\" = isRightCorner(corner) ? \"left\" : \"right\";\n const tooltipSide: \"left\" | \"right\" = panelSide;\n const bottom = isBottomCorner(corner);\n\n // Build position style\n const positionStyle: React.CSSProperties = dragging && dragPos\n ? { left: dragPos.x, top: dragPos.y }\n : snapAnim\n ? {\n left: snapAnim.x,\n top: snapAnim.y,\n ...(snapAnim.animate && {\n transition: \"left 0.3s cubic-bezier(0.23, 1, 0.32, 1), top 0.3s cubic-bezier(0.23, 1, 0.32, 1)\",\n }),\n }\n : getCornerStyle(corner);\n\n const cameraTooltipLabel = expanded ? \"Close\" : undefined;\n const cameraTooltipStyle: React.CSSProperties | undefined = cameraTooltipLabel\n ? tooltipSide === \"left\"\n ? { right: \"calc(100% + 10px)\", top: \"50%\", transform: \"translateY(-50%)\" }\n : { left: \"calc(100% + 10px)\", top: \"50%\", transform: \"translateY(-50%)\" }\n : undefined;\n\n const cameraButton = (\n <div style={{ position: \"relative\" }}>\n {cameraTooltipLabel && cameraTooltipVisible && !dragging && (\n <div\n style={{\n position: \"absolute\",\n ...cameraTooltipStyle,\n background: bg.base,\n border: `1px solid ${stroke.default}`,\n borderRadius: 6,\n padding: \"0 8px\",\n height: 24,\n display: \"flex\",\n alignItems: \"center\",\n color: fg.strong,\n ...text.label.xs,\n whiteSpace: \"nowrap\",\n boxShadow: shadow.tooltip,\n pointerEvents: \"none\",\n }}\n >\n {cameraTooltipLabel}\n </div>\n )}\n <div\n onMouseDown={handleMouseDown}\n onMouseEnter={() => setCameraHovered(true)}\n onMouseLeave={() => setCameraHovered(false)}\n style={{\n width: 32,\n height: 32,\n padding: 0,\n borderRadius: \"50%\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n cursor: dragging ? \"grabbing\" : \"pointer\",\n background: expanded && cameraHovered ? state.hoverStrong : \"transparent\",\n transition: \"background 0.12s ease\",\n }}\n >\n <style\n dangerouslySetInnerHTML={{\n __html: `\n@keyframes ab-spin {\n 0% { transform: rotate(0deg); }\n 100% { transform: rotate(360deg); }\n}\n@keyframes ab-panel-in {\n from { opacity: 0; transform: translateY(4px); }\n to { opacity: 1; transform: translateY(0); }\n}\n`,\n }}\n />\n {loading ? (\n <LoaderCircle\n size={16}\n strokeWidth={2}\n style={{ animation: \"ab-spin 0.8s linear infinite\", color: \"white\" }}\n />\n ) : phase === \"ready\" ? (\n <CheckmarkIcon size={20} color={fg.default} />\n ) : expanded ? (\n <CloseIcon\n size={20}\n color={cameraHovered ? fg.strong : fg.default}\n />\n ) : (\n <CameraIcon\n size={20}\n color={cameraHovered ? fg.strong : fg.default}\n />\n )}\n </div>\n </div>\n );\n\n const toolbarButtons = buttonsVisible ? (\n <div\n style={{\n overflow: animDone ? \"visible\" : \"hidden\",\n maxHeight: animIn ? 195 : 0,\n transition: animIn\n ? \"max-height 250ms cubic-bezier(0.23, 1, 0.32, 1)\"\n : \"max-height 150ms cubic-bezier(0.23, 1, 0.32, 1)\",\n }}\n >\n <div\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n opacity: animIn ? 1 : 0,\n transform: animIn ? \"translateY(0)\" : `translateY(${bottom ? 6 : -6}px)`,\n transition: animIn\n ? \"opacity 200ms cubic-bezier(0.23, 1, 0.32, 1), transform 200ms cubic-bezier(0.23, 1, 0.32, 1)\"\n : \"opacity 150ms cubic-bezier(0.23, 1, 0.32, 1), transform 150ms cubic-bezier(0.23, 1, 0.32, 1)\",\n willChange: \"transform, opacity\",\n }}\n >\n <div style={{ paddingBottom: 2 }}>\n <IconButton\n active={selectedMode === \"component\" && !historyOpen}\n tooltipSide={tooltipSide}\n tooltip=\"Component\"\n onClick={() => {\n\n setHistoryOpen(false);\n onModeChange(\"component\");\n }}\n >\n <CameraIcon size={20} />\n </IconButton>\n </div>\n\n {MODES.filter((m) => m.mode !== \"component\").map(({ mode, label, icon: ModeIcon }) => (\n <div\n key={mode}\n style={{\n maxHeight: modesExpanded ? 34 : 0,\n opacity: modesExpanded ? 1 : 0,\n transition: \"max-height 200ms cubic-bezier(0.23, 1, 0.32, 1), opacity 150ms cubic-bezier(0.23, 1, 0.32, 1)\",\n }}\n >\n <IconButton\n active={selectedMode === mode && !historyOpen}\n tooltipSide={tooltipSide}\n tooltip={label}\n onClick={() => {\n \n setHistoryOpen(false);\n onModeChange(mode);\n onCapture(mode);\n }}\n >\n <ModeIcon size={16} strokeWidth={1.7} />\n </IconButton>\n </div>\n ))}\n\n <Separator\n vertical={false}\n onClick={() => setModesExpanded((p) => !p)}\n />\n\n <ScreenshotsPanel\n open={historyOpen}\n onClick={() => {\n setHistoryOpen((prev) => !prev);\n }}\n selectedMode={selectedMode}\n frameSettings={frameSettings}\n onFrameSettingsChange={onFrameSettingsChange}\n tooltipSide={tooltipSide}\n />\n </div>\n </div>\n ) : null;\n\n return (\n <div\n ref={toolbarRef}\n data-afterbefore=\"true\"\n style={{\n position: \"fixed\",\n ...positionStyle,\n zIndex: 2147483647,\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n background: bg.base,\n borderRadius: 999,\n padding: 6,\n boxShadow: shadow.toolbar,\n ...fontBase,\n userSelect: \"none\",\n }}\n >\n {bottom ? (\n <>\n {toolbarButtons}\n {cameraButton}\n </>\n ) : (\n <>\n {cameraButton}\n {toolbarButtons}\n </>\n )}\n </div>\n );\n}\n\nexport function IconButton({\n children,\n active,\n tooltip,\n tooltipSide = \"left\",\n onClick,\n}: {\n children: React.ReactNode;\n active?: boolean;\n tooltip?: string;\n tooltipSide?: \"left\" | \"right\";\n onClick: () => void;\n}) {\n const [hovered, setHovered] = useState(false);\n const tooltipVisible = useTooltipDelay(hovered && !!tooltip);\n\n const tooltipStyle: React.CSSProperties = tooltipSide === \"left\"\n ? {\n right: \"calc(100% + 10px)\",\n top: \"50%\",\n transform: \"translateY(-50%)\",\n }\n : {\n left: \"calc(100% + 10px)\",\n top: \"50%\",\n transform: \"translateY(-50%)\",\n };\n\n return (\n <div style={{ position: \"relative\" }}>\n {tooltip && tooltipVisible && (\n <div\n style={{\n position: \"absolute\",\n ...tooltipStyle,\n background: bg.base,\n border: `1px solid ${stroke.default}`,\n borderRadius: 6,\n padding: \"0 8px\",\n height: 24,\n display: \"flex\",\n alignItems: \"center\",\n color: fg.strong,\n ...text.label.xs,\n whiteSpace: \"nowrap\",\n boxShadow: shadow.tooltip,\n pointerEvents: \"none\",\n }}\n >\n {tooltip}\n </div>\n )}\n\n <button\n onClick={onClick}\n onMouseEnter={() => setHovered(true)}\n onMouseLeave={() => setHovered(false)}\n style={{\n width: 32,\n height: 32,\n borderRadius: \"50%\",\n border: \"none\",\n background: active || hovered\n ? state.hoverStrong\n : \"transparent\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n cursor: \"pointer\",\n padding: 0,\n color: active || hovered\n ? fg.strong\n : fg.default,\n transition: \"background 0.12s ease, color 0.12s ease\",\n }}\n >\n {children}\n </button>\n </div>\n );\n}\n\n\n\n\n\nexport function DropItem({\n children,\n onClick,\n active,\n accent,\n}: {\n children: React.ReactNode;\n onClick: () => void;\n active?: boolean;\n accent?: boolean;\n}) {\n return (\n <button\n onClick={onClick}\n style={{\n display: \"block\",\n width: \"100%\",\n padding: \"7px 12px\",\n background: active ? state.active : \"transparent\",\n border: \"none\",\n color: accent\n ? accentToken.highlight\n : fg.strong,\n textAlign: \"left\",\n cursor: \"pointer\",\n ...text.paragraph.sm,\n fontFamily: \"inherit\",\n }}\n >\n {children}\n </button>\n );\n}\n\nexport function Separator({\n vertical = true,\n onClick,\n}: {\n vertical?: boolean;\n onClick?: () => void;\n}) {\n return (\n <div\n onClick={onClick}\n style={{\n position: \"relative\",\n width: vertical ? 1 : 24,\n height: vertical ? 18 : 1,\n background: stroke.strong,\n flexShrink: 0,\n margin: vertical ? \"0 6px\" : \"6px 0\",\n cursor: onClick ? \"pointer\" : undefined,\n }}\n >\n {onClick && (\n <div style={{ position: \"absolute\", inset: vertical ? \"0 -8px\" : \"-8px 0\" }} />\n )}\n </div>\n );\n}\n\n\n\nexport function FilterDropdown({\n label,\n value,\n options,\n isOpen,\n onToggle,\n onSelect,\n}: {\n label: string;\n value: string | null;\n options: string[];\n isOpen: boolean;\n onToggle: () => void;\n onSelect: (value: string) => void;\n}) {\n return (\n <div>\n <div\n style={{\n ...text.subheading.xxs,\n color: fg.sub,\n marginBottom: 3,\n }}\n >\n {label}\n </div>\n <div style={{ position: \"relative\" }}>\n <button\n onClick={onToggle}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n gap: 6,\n width: \"100%\",\n height: 30,\n padding: \"0 8px\",\n borderRadius: 7,\n border: `1px solid ${stroke.default}`,\n background: state.input,\n color: fg.strong,\n cursor: \"pointer\",\n ...text.label.xs,\n fontFamily: \"inherit\",\n }}\n >\n <span\n style={{\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n }}\n >\n {value || \"\\u2014\"}\n </span>\n <ChevronDown size={12} strokeWidth={2} />\n </button>\n\n {isOpen && options.length > 0 && (\n <div\n style={{\n position: \"absolute\",\n top: \"calc(100% + 4px)\",\n left: 0,\n right: 0,\n maxHeight: 160,\n overflowY: \"auto\",\n background: bg.base,\n border: `1px solid ${stroke.default}`,\n borderRadius: 8,\n padding: \"4px 0\",\n boxShadow: shadow.dropdown,\n zIndex: 1,\n }}\n >\n {options.map((opt) => (\n <DropItem\n key={opt}\n active={opt === value}\n onClick={() => onSelect(opt)}\n >\n {opt}\n </DropItem>\n ))}\n </div>\n )}\n </div>\n </div>\n );\n}\n\nexport function ActionButton({\n children,\n onClick,\n disabled,\n}: {\n children: React.ReactNode;\n onClick: () => void;\n disabled?: boolean;\n}) {\n const [hovered, setHovered] = useState(false);\n\n return (\n <button\n onClick={onClick}\n disabled={disabled}\n onMouseEnter={() => setHovered(true)}\n onMouseLeave={() => setHovered(false)}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 6,\n width: \"100%\",\n padding: \"6px 8px\",\n border: \"none\",\n background: hovered ? state.active : \"transparent\",\n color: fg.default,\n ...text.label.xs,\n borderRadius: 6,\n cursor: disabled ? \"wait\" : \"pointer\",\n textAlign: \"left\" as const,\n fontFamily: \"inherit\",\n transition: \"background 0.1s ease\",\n }}\n >\n {children}\n </button>\n );\n}\n\n","import React from \"react\";\n\ninterface IconProps {\n size?: number;\n color?: string;\n strokeWidth?: number;\n}\n\nexport function CameraIcon({ size = 32, color }: IconProps) {\n return (\n <svg width={size} height={size} viewBox=\"0 0 32 32\" fill=\"none\" style={{ color }}>\n <path\n d=\"M23.2119 13.8662C23.8759 13.8662 24.4228 13.3193 24.4228 12.6553C24.4228 11.9814 23.8759 11.4443 23.2119 11.4443C22.538 11.4443 22.0009 11.9814 22.0009 12.6553C22.0009 13.3193 22.538 13.8662 23.2119 13.8662ZM6.89356 24.999H24.7451C26.7763 24.999 27.8115 23.9834 27.8115 21.9717V11.7471C27.8115 9.73536 26.7763 8.7295 24.7451 8.7295H21.9521C21.1806 8.7295 20.9462 8.57325 20.5068 8.08496L19.7255 7.20605C19.2373 6.66895 18.7392 6.37598 17.7333 6.37598H13.8369C12.8311 6.37598 12.333 6.66895 11.8447 7.20605L11.0635 8.08496C10.624 8.56348 10.3799 8.7295 9.61817 8.7295H6.89356C4.85254 8.7295 3.82715 9.73536 3.82715 11.7471V21.9717C3.82715 23.9834 4.85254 24.999 6.89356 24.999ZM6.91309 23.4268C5.95606 23.4268 5.39942 22.9092 5.39942 21.8936V11.835C5.39942 10.8193 5.95606 10.3018 6.91309 10.3018H10.0088C10.8877 10.3018 11.3662 10.1357 11.8545 9.58887L12.6162 8.7295C13.1728 8.1045 13.4658 7.94825 14.3251 7.94825H17.2451C18.1044 7.94825 18.3974 8.1045 18.9541 8.7295L19.7158 9.58887C20.2041 10.1357 20.6826 10.3018 21.5615 10.3018H24.7158C25.6826 10.3018 26.2392 10.8193 26.2392 11.835V21.8936C26.2392 22.9092 25.6826 23.4268 24.7158 23.4268H6.91309ZM15.8193 22.0205C18.7685 22.0205 21.1416 19.6572 21.1416 16.6787C21.1416 13.71 18.7783 11.3467 15.8193 11.3467C12.8603 11.3467 10.4873 13.71 10.4873 16.6787C10.4873 19.6572 12.8603 22.0205 15.8193 22.0205ZM15.8193 20.5362C13.7002 20.5362 11.9619 18.8272 11.9619 16.6787C11.9619 14.54 13.6904 12.8213 15.8193 12.8213C17.9482 12.8213 19.6669 14.54 19.6669 16.6787C19.6669 18.8272 17.9482 20.5362 15.8193 20.5362Z\"\n fill=\"currentColor\"\n />\n </svg>\n );\n}\n\nexport function ImageIcon({ size = 32, color }: IconProps) {\n return (\n <svg width={size} height={size} viewBox=\"0 0 32 32\" fill=\"none\" style={{ color }}>\n <path\n d=\"M7.30371 24.3056H23.6709C25.4385 24.3056 26.3272 23.3193 26.3272 21.4443L20.5264 15.9951C20.0967 15.5947 19.5791 15.3897 19.0518 15.3897C18.5147 15.3897 18.0362 15.5752 17.5869 15.9756L13.1729 19.9209L11.3662 18.29C10.9561 17.9189 10.5068 17.7334 10.0479 17.7334C9.60839 17.7334 9.18847 17.9091 8.78808 18.2802L5.06738 21.6396C5.12598 23.4072 5.84863 24.3056 7.30371 24.3056ZM7.37207 24.9892H24.2666C26.3174 24.9892 27.333 23.9834 27.333 21.9716V10.0381C27.333 8.02636 26.3174 7.01074 24.2666 7.01074H7.37207C5.33105 7.01074 4.30566 8.02636 4.30566 10.0381V21.9716C4.30566 23.9834 5.33105 24.9892 7.37207 24.9892ZM7.3916 23.4169C6.41504 23.4169 5.87793 22.8994 5.87793 21.8837V10.126C5.87793 9.11035 6.41504 8.58301 7.3916 8.58301H24.2471C25.2139 8.58301 25.7608 9.11035 25.7608 10.126V21.8837C25.7608 22.8994 25.2139 23.4169 24.2471 23.4169H7.3916Z\"\n fill=\"currentColor\"\n />\n <path\n d=\"M11.5811 16.0928C12.8408 16.0928 13.876 15.0576 13.876 13.7881C13.876 12.5283 12.8408 11.4834 11.5811 11.4834C10.3115 11.4834 9.27637 12.5283 9.27637 13.7881C9.27637 15.0576 10.3115 16.0928 11.5811 16.0928Z\"\n fill=\"currentColor\"\n />\n </svg>\n );\n}\n\nexport function CheckmarkIcon({ size = 32, color }: IconProps) {\n return (\n <svg width={size} height={size} viewBox=\"0 0 32 32\" fill=\"none\" style={{ color }}>\n <path\n d=\"M15.8193 25.9561C21.3174 25.9561 25.7803 21.4932 25.7803 15.9951C25.7803 10.4971 21.3174 6.03418 15.8193 6.03418C10.3213 6.03418 5.8584 10.4971 5.8584 15.9951C5.8584 21.4932 10.3213 25.9561 15.8193 25.9561ZM15.8193 24.2959C11.2295 24.2959 7.51856 20.585 7.51856 15.9951C7.51856 11.4053 11.2295 7.69434 15.8193 7.69434C20.4092 7.69434 24.1201 11.4053 24.1201 15.9951C24.1201 20.585 20.4092 24.2959 15.8193 24.2959Z\"\n fill=\"currentColor\"\n />\n <path\n d=\"M14.7451 20.6338C15.0674 20.6338 15.3408 20.4776 15.5361 20.1748L19.999 13.1533C20.1064 12.958 20.2334 12.7432 20.2334 12.5283C20.2334 12.0889 19.8428 11.8057 19.4326 11.8057C19.1885 11.8057 18.9443 11.9619 18.7588 12.2451L14.7061 18.749L12.7822 16.2588C12.5478 15.9463 12.333 15.8682 12.0596 15.8682C11.6396 15.8682 11.3076 16.21 11.3076 16.6397C11.3076 16.8545 11.3955 17.0596 11.5322 17.2451L13.915 20.1748C14.1592 20.4971 14.4228 20.6338 14.7451 20.6338Z\"\n fill=\"currentColor\"\n />\n </svg>\n );\n}\n\nexport function CloseIcon({ size = 32, color }: IconProps) {\n return (\n <svg width={size} height={size} viewBox=\"0 0 32 32\" fill=\"none\" style={{ color }}>\n <path\n d=\"M22.0693 8.52467L8.32911 22.2649C7.99708 22.5969 7.98732 23.1633 8.32911 23.4953C8.67091 23.8274 9.23732 23.8274 9.56935 23.4953L23.3096 9.75514C23.6416 9.42311 23.6514 8.8567 23.3096 8.52467C22.9678 8.18287 22.4111 8.17311 22.0693 8.52467ZM23.3096 22.2649L9.56935 8.52467C9.23732 8.18287 8.66115 8.17311 8.32911 8.52467C7.99708 8.86647 7.99708 9.42311 8.32911 9.75514L22.0693 23.4953C22.4014 23.8274 22.9775 23.8371 23.3096 23.4953C23.6416 23.1535 23.6416 22.5969 23.3096 22.2649Z\"\n fill=\"currentColor\"\n />\n </svg>\n );\n}\n","// ---------------------------------------------------------------------------\n// Align UI — Neutral Gray palette + dark-theme semantic tokens\n// ---------------------------------------------------------------------------\n\nexport const gray = {\n 950: \"oklch(0.162 0 0)\",\n 900: \"oklch(0.195 0 0)\",\n 800: \"oklch(0.254 0 0)\",\n 700: \"oklch(0.302 0 0)\",\n 600: \"oklch(0.348 0 0)\",\n 500: \"oklch(0.396 0 0)\",\n 400: \"oklch(0.459 0 0)\",\n 300: \"oklch(0.549 0 0)\",\n 200: \"oklch(0.649 0 0)\",\n 100: \"oklch(0.72 0 0)\",\n 50: \"oklch(0.863 0 0)\",\n 0: \"oklch(0.933 0 0)\",\n} as const;\n\n// --- Surfaces ---\n\nexport const bg = {\n base: gray[900],\n elevated: gray[950],\n dropdown: gray[900],\n} as const;\n\n// --- Foreground (text / icons) ---\n\nexport const fg = {\n strong: gray[200], // ~5.6:1 — headings, input values\n default: \"oklch(0.6 0 0)\", // ~4.6:1 — body text, interactive labels (AA)\n sub: gray[300], // ~3.8:1 — secondary labels, icons\n muted: \"oklch(0.5 0 0)\", // ~3:1 — inline labels, decorative\n faint: gray[500], // ~2:1 — non-essential hints only\n} as const;\n\n// --- Stroke / borders ---\n\nexport const stroke = {\n soft: \"rgba(255, 255, 255, 0.08)\",\n default: \"rgba(255, 255, 255, 0.1)\",\n strong: \"rgba(255, 255, 255, 0.12)\",\n interactive: \"rgba(255, 255, 255, 0.18)\",\n} as const;\n\n// --- Interactive state backgrounds ---\n\nexport const state = {\n subtle: \"rgba(255, 255, 255, 0.04)\",\n button: \"rgba(255, 255, 255, 0.06)\",\n input: \"rgba(255, 255, 255, 0.07)\",\n active: \"rgba(255, 255, 255, 0.08)\",\n hover: \"rgba(255, 255, 255, 0.1)\",\n hoverStrong: \"rgba(255, 255, 255, 0.12)\",\n pressed: \"rgba(255, 255, 255, 0.14)\",\n} as const;\n\n// --- Accent ---\n\nexport const accent = {\n primary: \"#335CFF\",\n toggle: \"#38bdf8\",\n check: \"#4ade80\",\n highlight: \"rgba(125, 211, 252, 0.96)\",\n} as const;\n\n// --- Feedback ---\n\nexport const feedback = {\n success: \"rgba(34, 197, 94, 0.9)\",\n error: \"rgba(239, 68, 68, 0.9)\",\n errorText: \"rgba(239, 68, 68, 0.9)\",\n errorBg: \"rgba(239, 68, 68, 0.1)\",\n} as const;\n\n// --- Shadows ---\n\nexport const shadow = {\n toolbar: \"0 8px 32px rgba(0, 0, 0, 0.4)\",\n panel: \"0 14px 36px rgba(0, 0, 0, 0.32)\",\n dropdown: \"0 10px 30px rgba(0, 0, 0, 0.3)\",\n tooltip: \"0 8px 28px rgba(0, 0, 0, 0.28)\",\n toast: \"0 2px 8px rgba(0, 0, 0, 0.3)\",\n status: \"0 4px 20px rgba(0, 0, 0, 0.4), 0 0 0 1px rgba(255, 255, 255, 0.08)\",\n} as const;\n","\"use client\";\n\nimport React, { useCallback, useEffect, useState } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport {\n Trash2,\n X,\n} from \"lucide-react\";\nimport { ImageIcon } from \"./icons\";\nimport type { CaptureMode } from \"../state\";\nimport type { FrameSettings } from \"../capture\";\nimport { fontBase, text } from \"../font\";\nimport { bg, fg, stroke, state, accent as accentToken, feedback, shadow } from \"../color\";\nimport { SettingsContent } from \"./settings-panel\";\nimport { IconButton, FilterDropdown } from \"./toolbar\";\n\ninterface ScreenshotMeta {\n filename: string;\n timestamp: string;\n}\n\nfunction BrowserChromeBar({ theme, url = \"localhost\" }: { theme: \"light\" | \"dark\"; url?: string }) {\n const colors =\n theme === \"dark\"\n ? { titleBar: \"#1C1C1C\", urlBar: \"#262626\", text: \"#7B7B7B\", border: \"#333333\" }\n : { titleBar: \"#F5F5F5\", urlBar: \"#FFFFFF\", text: \"#999999\", border: \"#EBEBEB\" };\n\n return (\n <div style={{ background: colors.titleBar, flexShrink: 0, padding: \"4px 6px\" }}>\n <div style={{ display: \"flex\", alignItems: \"center\", gap: 6, height: 14 }}>\n <div style={{ display: \"flex\", gap: 5, flexShrink: 0 }}>\n {[\"#FF5F57\", \"#FEBC2E\", \"#28C840\"].map((c) => (\n <div key={c} style={{ width: 6, height: 6, borderRadius: \"50%\", background: c }} />\n ))}\n </div>\n <div\n style={{\n flex: 1,\n height: 14,\n background: colors.urlBar,\n borderRadius: 3,\n display: \"flex\",\n alignItems: \"center\",\n paddingLeft: 6,\n ...(theme === \"light\" ? { border: `1px solid ${colors.border}` } : {}),\n boxSizing: \"border-box\" as const,\n }}\n >\n <span\n style={{\n fontSize: 7,\n lineHeight: 1,\n color: colors.text,\n fontFamily: '-apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif',\n }}\n >\n {url}\n </span>\n </div>\n </div>\n </div>\n );\n}\n\nfunction FramePreview({\n componentUrl,\n viewportUrl,\n frameSettings,\n loading,\n}: {\n componentUrl: string | null;\n viewportUrl: string | null;\n frameSettings: FrameSettings;\n loading: boolean;\n}) {\n const { enabled: frameEnabled, browserChrome, browserTheme, browserUrl, browserShadow = 50, browserRadius = 8, size, bgType, bgColor, bgGradient, bgImage, padding } = frameSettings;\n const [viewportAvailable, setViewportAvailable] = useState(true);\n\n // Reset viewport availability when file changes\n useEffect(() => { setViewportAvailable(true); }, [componentUrl]);\n\n const previewUrl = browserChrome && viewportUrl && viewportAvailable\n ? viewportUrl\n : componentUrl;\n\n const aspectRatio = frameEnabled ? `${size.w} / ${size.h}` : \"16 / 10\";\n\n const outerBg: React.CSSProperties = frameEnabled\n ? bgType === \"image\" && bgImage\n ? { backgroundImage: `url(${bgImage})`, backgroundSize: \"cover\", backgroundPosition: \"center\" }\n : bgType === \"gradient\"\n ? { background: bgGradient }\n : { background: bgColor }\n : { background: bg.elevated };\n\n const emptyState = (\n <span style={{ ...text.paragraph.xs, color: fg.sub }}>\n {loading ? \"Loading...\" : \"No screenshots yet\"}\n </span>\n );\n\n const imageEl = previewUrl ? (\n <img\n src={previewUrl}\n alt=\"\"\n onError={() => {\n if (browserChrome && viewportUrl && viewportAvailable) {\n setViewportAvailable(false);\n }\n }}\n style={{\n maxWidth: \"100%\",\n maxHeight: \"100%\",\n objectFit: \"contain\" as const,\n display: \"block\",\n }}\n />\n ) : null;\n\n const padPct = frameEnabled ? `${(padding / size.h) * 100}%` : undefined;\n\n // Shadow for browser window\n const shadowAlpha = (browserShadow / 100) * 0.6;\n const shadowBlur = (browserShadow / 100) * 40;\n const shadowY = (browserShadow / 100) * 8;\n const browserBoxShadow = browserChrome && browserShadow > 0\n ? `0 ${shadowY}px ${shadowBlur}px rgba(0, 0, 0, ${shadowAlpha})`\n : \"none\";\n\n return (\n <div\n style={{\n width: \"100%\",\n aspectRatio,\n borderRadius: 10,\n overflow: \"hidden\",\n border: `1px solid ${stroke.soft}`,\n marginBottom: 10,\n display: \"flex\",\n flexDirection: \"column\" as const,\n ...outerBg,\n ...(padPct ? { padding: padPct } : {}),\n }}\n >\n {browserChrome ? (\n <div style={{ flex: 1, display: \"flex\", flexDirection: \"column\" as const, borderRadius: browserRadius, overflow: \"hidden\", minHeight: 0, boxShadow: browserBoxShadow }}>\n <BrowserChromeBar theme={browserTheme} url={browserUrl} />\n <div\n style={{\n flex: 1,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n minHeight: 0,\n }}\n >\n {imageEl || emptyState}\n </div>\n </div>\n ) : (\n <div\n style={{\n flex: 1,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n minHeight: 0,\n }}\n >\n {imageEl || emptyState}\n </div>\n )}\n </div>\n );\n}\n\nfunction formatTimestamp(filename: string): string {\n const iso = filename\n .replace(/\\.png$/, \"\")\n .replace(/T(\\d{2})-(\\d{2})-(\\d{2})-(\\d+)Z$/, \"T$1:$2:$3.$4Z\");\n const date = new Date(iso);\n if (Number.isNaN(date.getTime())) return filename.replace(/\\.png$/, \"\");\n\n const now = new Date();\n const diffMs = now.getTime() - date.getTime();\n const diffMin = Math.floor(diffMs / 60000);\n\n if (diffMin < 1) return \"Just now\";\n if (diffMin < 60) return `${diffMin}m ago`;\n const diffHr = Math.floor(diffMin / 60);\n if (diffHr < 24) return `${diffHr}h ago`;\n\n return date.toLocaleDateString(undefined, { month: \"short\", day: \"numeric\", hour: \"2-digit\", minute: \"2-digit\" });\n}\n\nexport function ScreenshotsPanel({\n open,\n onClick,\n selectedMode,\n frameSettings,\n onFrameSettingsChange,\n tooltipSide,\n}: {\n open: boolean;\n onClick: () => void;\n selectedMode: CaptureMode;\n frameSettings: FrameSettings;\n onFrameSettingsChange: (settings: FrameSettings) => void;\n tooltipSide: \"left\" | \"right\";\n}) {\n const [toast, setToast] = useState<{ message: string; type: \"success\" | \"error\" } | null>(null);\n const [saveDir, setSaveDir] = useState<string | null>(null);\n const [picking, setPicking] = useState(false);\n\n const [repos, setRepos] = useState<string[]>([]);\n const [branches, setBranches] = useState<string[]>([]);\n const [screenshots, setScreenshots] = useState<ScreenshotMeta[]>([]);\n const [selectedRepo, setSelectedRepo] = useState<string | null>(null);\n const [selectedBranch, setSelectedBranch] = useState<string | null>(null);\n const [loading, setLoading] = useState(false);\n const [repoDropOpen, setRepoDropOpen] = useState(false);\n const [branchDropOpen, setBranchDropOpen] = useState(false);\n const [editingFile, setEditingFile] = useState<string | null>(null);\n const [editValue, setEditValue] = useState(\"\");\n const [selectedFile, setSelectedFile] = useState<string | null>(null);\n\n useEffect(() => {\n if (!open) return;\n fetch(\"/__afterbefore/config\")\n .then((r) => r.json())\n .then((data) => setSaveDir(data.saveDir))\n .catch(() => {});\n }, [open]);\n\n const handlePickFolder = async () => {\n setPicking(true);\n try {\n const res = await fetch(\"/__afterbefore/pick-folder\", { method: \"POST\" });\n const data = await res.json();\n if (data.folder) {\n await fetch(\"/__afterbefore/config\", {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ saveDir: data.folder }),\n });\n setSaveDir(data.folder);\n }\n } catch {\n // noop\n } finally {\n setPicking(false);\n }\n };\n\n const shortDir = saveDir\n ? saveDir.replace(/^\\/Users\\/[^/]+\\//, \"\")\n : \"Desktop\";\n\n useEffect(() => {\n if (!open) {\n setRepoDropOpen(false);\n setBranchDropOpen(false);\n return;\n }\n setLoading(true);\n const params = new URLSearchParams();\n if (selectedRepo) params.set(\"repo\", selectedRepo);\n if (selectedBranch) params.set(\"branch\", selectedBranch);\n fetch(`/__afterbefore/history?${params}`)\n .then((r) => r.json())\n .then((data) => {\n setRepos(data.repos || []);\n setBranches(data.branches || []);\n const shots: ScreenshotMeta[] = data.screenshots || [];\n setScreenshots(shots);\n if (shots.length > 0) {\n setSelectedFile((prev) =>\n prev && shots.some((s) => s.filename === prev) ? prev : shots[0].filename,\n );\n } else {\n setSelectedFile(null);\n }\n if (!selectedRepo && data.currentRepo) setSelectedRepo(data.currentRepo);\n if (!selectedBranch && data.currentBranch) setSelectedBranch(data.currentBranch);\n })\n .catch(() => {})\n .finally(() => setLoading(false));\n }, [open, selectedRepo, selectedBranch]);\n\n const showToast = useCallback((message: string, type: \"success\" | \"error\") => {\n setToast({ message, type });\n setTimeout(() => setToast(null), 3000);\n }, []);\n\n const handleRename = async (oldName: string, newName: string) => {\n if (!newName.trim() || newName.trim() === oldName.replace(/\\.png$/, \"\")) {\n setEditingFile(null);\n return;\n }\n try {\n const res = await fetch(\"/__afterbefore/history/rename\", {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n repo: selectedRepo,\n branch: selectedBranch,\n oldName,\n newName: newName.trim(),\n }),\n });\n if (!res.ok) throw new Error();\n const data = await res.json();\n setScreenshots((prev) =>\n prev.map((s) =>\n s.filename === oldName\n ? { ...s, filename: data.filename, timestamp: data.filename.replace(/\\.png$/, \"\") }\n : s,\n ),\n );\n if (selectedFile === oldName) setSelectedFile(data.filename);\n showToast(\"Renamed\", \"success\");\n } catch {\n showToast(\"Rename failed\", \"error\");\n }\n setEditingFile(null);\n };\n\n const handleDelete = async (filename: string) => {\n try {\n const res = await fetch(\"/__afterbefore/history/delete\", {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n repo: selectedRepo,\n branch: selectedBranch,\n file: filename,\n }),\n });\n if (!res.ok) throw new Error();\n setScreenshots((prev) => prev.filter((s) => s.filename !== filename));\n if (selectedFile === filename) {\n const remaining = screenshots.filter((s) => s.filename !== filename);\n setSelectedFile(remaining.length > 0 ? remaining[0].filename : null);\n }\n showToast(\"Deleted\", \"success\");\n } catch {\n showToast(\"Delete failed\", \"error\");\n }\n };\n\n\n const baseImageUrl = selectedFile\n ? `/__afterbefore/history/image?repo=${encodeURIComponent(selectedRepo || \"\")}&branch=${encodeURIComponent(selectedBranch || \"\")}&file=${encodeURIComponent(selectedFile)}`\n : null;\n const viewportUrl = baseImageUrl ? `${baseImageUrl}&variant=viewport` : null;\n\n return (\n <>\n <IconButton active={open} tooltipSide={tooltipSide} tooltip={!open ? \"Screenshots\" : undefined} onClick={onClick}>\n <ImageIcon size={20} />\n </IconButton>\n\n {open && createPortal(\n <div\n data-afterbefore=\"true\"\n onClick={onClick}\n style={{\n position: \"fixed\",\n inset: 0,\n zIndex: 2147483647,\n background: \"rgba(0, 0, 0, 0.45)\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n ...fontBase,\n }}\n >\n <style\n dangerouslySetInnerHTML={{\n __html: `\n@keyframes ab-panel-in {\n from { opacity: 0; transform: translateY(4px); }\n to { opacity: 1; transform: translateY(0); }\n}\n`,\n }}\n />\n <div\n onClick={(e) => e.stopPropagation()}\n style={{\n width: 900,\n height: \"70vh\",\n borderRadius: 14,\n background: bg.base,\n border: `1px solid ${stroke.default}`,\n boxShadow: shadow.panel,\n display: \"flex\",\n flexDirection: \"column\",\n overflow: \"hidden\",\n animation: \"ab-panel-in 150ms cubic-bezier(0.23, 1, 0.32, 1)\",\n }}\n >\n {/* Header */}\n <div style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n padding: \"16px 20px\",\n borderBottom: `1px solid ${stroke.soft}`,\n }}>\n <div>\n <div style={{ ...text.label.sm, color: fg.strong }}>Screenshots</div>\n <div style={{ ...text.paragraph.xs, color: fg.sub, marginTop: 2 }}>\n Capture history & settings\n </div>\n </div>\n <button\n onClick={onClick}\n style={{\n width: 28,\n height: 28,\n borderRadius: 7,\n border: \"none\",\n background: \"transparent\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n cursor: \"pointer\",\n color: fg.sub,\n padding: 0,\n transition: \"background 0.12s ease, color 0.12s ease\",\n }}\n onMouseEnter={(e) => {\n (e.currentTarget as HTMLButtonElement).style.background = state.hover;\n (e.currentTarget as HTMLButtonElement).style.color = fg.strong;\n }}\n onMouseLeave={(e) => {\n (e.currentTarget as HTMLButtonElement).style.background = \"transparent\";\n (e.currentTarget as HTMLButtonElement).style.color = fg.sub;\n }}\n >\n <X size={14} strokeWidth={2} />\n </button>\n </div>\n\n {/* Two-column body */}\n <div style={{ display: \"flex\", flex: 1, overflow: \"hidden\", minHeight: 0 }}>\n {/* Left column — preview & file management */}\n <div style={{ flex: 1, overflowY: \"auto\", padding: \"16px 20px 20px\", minHeight: 0 }}>\n <FramePreview\n componentUrl={baseImageUrl}\n viewportUrl={viewportUrl}\n frameSettings={frameSettings}\n loading={loading}\n />\n\n {selectedFile && !loading && (\n <div style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 8,\n marginBottom: 12,\n }}>\n <div style={{ flex: 1, minWidth: 0 }}>\n {editingFile === selectedFile ? (\n <input\n autoFocus\n value={editValue}\n onChange={(e) => setEditValue(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") handleRename(selectedFile, editValue);\n if (e.key === \"Escape\") setEditingFile(null);\n }}\n onBlur={() => handleRename(selectedFile, editValue)}\n style={{\n width: \"100%\",\n ...text.label.xs,\n color: fg.strong,\n background: state.hover,\n border: `1px solid ${stroke.interactive}`,\n borderRadius: 4,\n padding: \"2px 6px\",\n outline: \"none\",\n fontFamily: \"inherit\",\n }}\n />\n ) : (\n <div\n onClick={() => {\n setEditingFile(selectedFile);\n setEditValue(selectedFile.replace(/\\.png$/, \"\"));\n }}\n style={{\n ...text.label.xs,\n color: fg.strong,\n cursor: \"pointer\",\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n }}\n title=\"Click to rename\"\n >\n {formatTimestamp(selectedFile)}\n </div>\n )}\n </div>\n <button\n onClick={() => handleDelete(selectedFile)}\n title=\"Delete screenshot\"\n style={{\n flexShrink: 0,\n width: 28,\n height: 28,\n borderRadius: 6,\n border: \"none\",\n background: \"transparent\",\n color: fg.muted,\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n padding: 0,\n }}\n onMouseEnter={(e) => {\n (e.currentTarget as HTMLButtonElement).style.color = feedback.error;\n (e.currentTarget as HTMLButtonElement).style.background = feedback.errorBg;\n }}\n onMouseLeave={(e) => {\n (e.currentTarget as HTMLButtonElement).style.color = fg.muted;\n (e.currentTarget as HTMLButtonElement).style.background = \"transparent\";\n }}\n >\n <Trash2 size={14} strokeWidth={1.8} />\n </button>\n </div>\n )}\n\n {/* Filters */}\n <div style={{ display: \"flex\", gap: 10, marginBottom: 10 }}>\n <div style={{ flex: 1, position: \"relative\" }}>\n <FilterDropdown\n label=\"Project\"\n value={selectedRepo}\n options={repos}\n isOpen={repoDropOpen}\n onToggle={() => {\n setRepoDropOpen((p) => !p);\n setBranchDropOpen(false);\n }}\n onSelect={(repo) => {\n setSelectedRepo(repo);\n setSelectedBranch(null);\n setRepoDropOpen(false);\n }}\n />\n </div>\n <div style={{ flex: 1, position: \"relative\" }}>\n <FilterDropdown\n label=\"Branch\"\n value={selectedBranch}\n options={branches}\n isOpen={branchDropOpen}\n onToggle={() => {\n setBranchDropOpen((p) => !p);\n setRepoDropOpen(false);\n }}\n onSelect={(branch) => {\n setSelectedBranch(branch);\n setBranchDropOpen(false);\n }}\n />\n </div>\n </div>\n\n {/* Thumbnail strip */}\n {screenshots.length > 0 && (\n <div\n style={{\n display: \"flex\",\n gap: 6,\n overflowX: \"auto\",\n paddingBottom: 4,\n marginBottom: 10,\n }}\n >\n {screenshots.map((shot) => {\n const thumbUrl = `/__afterbefore/history/image?repo=${encodeURIComponent(selectedRepo || \"\")}&branch=${encodeURIComponent(selectedBranch || \"\")}&file=${encodeURIComponent(shot.filename)}`;\n const isSelected = selectedFile === shot.filename;\n return (\n <div\n key={shot.filename}\n onClick={() => setSelectedFile(shot.filename)}\n style={{\n width: 64,\n height: 44,\n flexShrink: 0,\n borderRadius: 6,\n overflow: \"hidden\",\n cursor: \"pointer\",\n border: isSelected\n ? `2px solid ${accentToken.highlight}`\n : `1px solid ${stroke.soft}`,\n opacity: isSelected ? 1 : 0.7,\n transition: \"opacity 0.12s ease, border-color 0.12s ease\",\n }}\n >\n <img\n src={thumbUrl}\n alt=\"\"\n style={{\n width: \"100%\",\n height: \"100%\",\n objectFit: \"cover\",\n display: \"block\",\n }}\n />\n </div>\n );\n })}\n </div>\n )}\n\n </div>\n\n {/* Vertical divider */}\n <div style={{ width: 1, flexShrink: 0, background: stroke.soft }} />\n\n {/* Right column — settings */}\n <div style={{ width: 300, flexShrink: 0, overflowY: \"auto\", padding: \"16px 16px 12px\", minHeight: 0, display: \"flex\", flexDirection: \"column\" }}>\n <div style={{ flex: 1 }}>\n <SettingsContent\n frameSettings={frameSettings}\n onFrameSettingsChange={onFrameSettingsChange}\n saveDir={shortDir}\n picking={picking}\n onPickFolder={handlePickFolder}\n />\n </div>\n {/* Footer */}\n <div style={{ display: \"flex\", alignItems: \"center\", gap: 8, paddingTop: 12, paddingBottom: 2, marginTop: 12, borderTop: `1px solid ${stroke.soft}`, marginLeft: -16, marginRight: -16, paddingLeft: 16 }}>\n <span style={{ ...text.paragraph.xs, color: fg.muted }}>made by Paulius Kairevicius</span>\n <a\n href=\"https://github.com/kairevicius\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n style={{ color: fg.muted, display: \"flex\", transition: \"color 0.12s\" }}\n onMouseEnter={(e) => { (e.currentTarget as HTMLElement).style.color = fg.strong; }}\n onMouseLeave={(e) => { (e.currentTarget as HTMLElement).style.color = fg.muted; }}\n >\n <svg width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M12 0C5.37 0 0 5.37 0 12c0 5.31 3.435 9.795 8.205 11.385.6.105.825-.255.825-.57 0-.285-.015-1.23-.015-2.235-3.015.555-3.795-.735-4.035-1.41-.135-.345-.72-1.41-1.23-1.695-.42-.225-1.02-.78-.015-.795.945-.015 1.62.87 1.845 1.23 1.08 1.815 2.805 1.305 3.495.99.105-.78.42-1.305.765-1.605-2.67-.3-5.46-1.335-5.46-5.925 0-1.305.465-2.385 1.23-3.225-.12-.3-.54-1.53.12-3.18 0 0 1.005-.315 3.3 1.23.96-.27 1.98-.405 3-.405s2.04.135 3 .405c2.295-1.56 3.3-1.23 3.3-1.23.66 1.65.24 2.88.12 3.18.765.84 1.23 1.905 1.23 3.225 0 4.605-2.805 5.625-5.475 5.925.435.375.81 1.095.81 2.22 0 1.605-.015 2.895-.015 3.3 0 .315.225.69.825.57A12.02 12.02 0 0 0 24 12c0-6.63-5.37-12-12-12z\"/></svg>\n </a>\n <a\n href=\"https://x.com/kairevicius\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n style={{ color: fg.muted, display: \"flex\", transition: \"color 0.12s\" }}\n onMouseEnter={(e) => { (e.currentTarget as HTMLElement).style.color = fg.strong; }}\n onMouseLeave={(e) => { (e.currentTarget as HTMLElement).style.color = fg.muted; }}\n >\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z\"/></svg>\n </a>\n </div>\n </div>\n </div>\n </div>\n\n {toast && (\n <div\n onClick={(e) => e.stopPropagation()}\n style={{\n position: \"fixed\",\n bottom: 32,\n left: \"50%\",\n transform: \"translateX(-50%)\",\n padding: \"6px 14px\",\n borderRadius: 8,\n ...text.label.xs,\n whiteSpace: \"nowrap\",\n color: \"white\",\n background:\n toast.type === \"success\"\n ? feedback.success\n : feedback.error,\n boxShadow: shadow.toast,\n }}\n >\n {toast.message}\n </div>\n )}\n </div>,\n document.body,\n )}\n\n </>\n );\n}\n","\"use client\";\n\nimport React, { useEffect, useRef, useState } from \"react\";\nimport {\n AppWindow,\n Check,\n ChevronDown,\n LayoutGrid,\n Pipette,\n Trash2,\n Upload,\n} from \"lucide-react\";\nimport { FRAME_SIZE_PRESETS, GRADIENT_PRESETS, COLOR_PRESETS, type FrameSettings } from \"../capture\";\nimport { text as T } from \"../font\";\nimport { bg, fg, stroke, state, accent, shadow } from \"../color\";\n\n/** Settings rows — for embedding in the screenshots panel */\nexport function SettingsContent({\n frameSettings,\n onFrameSettingsChange,\n saveDir,\n picking,\n onPickFolder,\n}: {\n frameSettings: FrameSettings;\n onFrameSettingsChange: (settings: FrameSettings) => void;\n saveDir?: string;\n picking?: boolean;\n onPickFolder?: () => void;\n}) {\n return (\n <>\n <BackgroundSetting\n frameSettings={frameSettings}\n onFrameSettingsChange={onFrameSettingsChange}\n />\n\n <SettingsDivider />\n\n <BrowserFrameSetting\n enabled={frameSettings.browserChrome}\n theme={frameSettings.browserTheme}\n shadow={frameSettings.browserShadow ?? 50}\n radius={frameSettings.browserRadius ?? 8}\n url={frameSettings.browserUrl ?? \"localhost\"}\n onToggle={() =>\n onFrameSettingsChange({ ...frameSettings, browserChrome: !frameSettings.browserChrome })\n }\n onSelect={(theme) =>\n onFrameSettingsChange({ ...frameSettings, browserChrome: true, browserTheme: theme })\n }\n onShadowChange={(v) =>\n onFrameSettingsChange({ ...frameSettings, browserShadow: v })\n }\n onRadiusChange={(v) =>\n onFrameSettingsChange({ ...frameSettings, browserRadius: v })\n }\n onUrlChange={(v) =>\n onFrameSettingsChange({ ...frameSettings, browserUrl: v })\n }\n />\n\n <SettingsDivider />\n\n {saveDir !== undefined && onPickFolder && (\n <SettingsRow\n title=\"Save Location\"\n description={\n <span\n style={{\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n display: \"block\",\n }}\n title={saveDir}\n >\n {saveDir}\n </span>\n }\n control={\n <SmallButton onClick={onPickFolder}>\n {picking ? \"...\" : \"Change\"}\n </SmallButton>\n }\n />\n )}\n </>\n );\n}\n\nexport function SettingsRow({\n title,\n description,\n control,\n}: {\n title: string;\n description?: string | React.ReactNode;\n control: React.ReactNode;\n}) {\n return (\n <div style={{ display: \"flex\", alignItems: \"center\", justifyContent: \"space-between\", gap: 16, padding: \"14px 0\" }}>\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 2, flex: 1, minWidth: 0 }}>\n <span style={{ ...T.label.sm, color: fg.strong }}>\n {title}\n </span>\n {description && (\n <span style={{ ...T.paragraph.xs, color: fg.sub }}>\n {description}\n </span>\n )}\n </div>\n <div style={{ flexShrink: 0 }}>\n {control}\n </div>\n </div>\n );\n}\n\nexport function SettingsDivider() {\n return (\n <div\n style={{\n borderBottom: `1px solid ${stroke.soft}`,\n margin: \"0 -16px\",\n }}\n />\n );\n}\n\nexport function ToggleSwitch({\n enabled,\n onChange,\n}: {\n enabled: boolean;\n onChange: () => void;\n}) {\n return (\n <button\n type=\"button\"\n onClick={onChange}\n style={{\n width: 38,\n height: 22,\n borderRadius: 999,\n border: \"none\",\n background: enabled ? accent.toggle : stroke.interactive,\n position: \"relative\",\n cursor: \"pointer\",\n padding: 0,\n flexShrink: 0,\n transition: \"background 0.12s ease\",\n }}\n >\n <span\n style={{\n position: \"absolute\",\n top: 2,\n left: enabled ? 18 : 2,\n width: 18,\n height: 18,\n borderRadius: \"50%\",\n background: \"#fff\",\n transition: \"left 0.12s ease\",\n }}\n />\n </button>\n );\n}\n\nexport function FrameSizeControl({\n size,\n onChange,\n}: {\n size: { w: number; h: number };\n onChange: (size: { w: number; h: number }) => void;\n}) {\n const [sizeOpen, setSizeOpen] = useState(false);\n const [editing, setEditing] = useState<\"w\" | \"h\" | null>(null);\n const [text, setText] = useState(\"\");\n\n const currentPreset = FRAME_SIZE_PRESETS.find((p) => p.w === size.w && p.h === size.h);\n const isCustom = !currentPreset;\n\n const commitValue = (field: \"w\" | \"h\", raw: string) => {\n const n = parseInt(raw, 10);\n if (!Number.isNaN(n) && n > 0) onChange({ ...size, [field]: n });\n };\n\n const inputStyle: React.CSSProperties = {\n flex: 1,\n minWidth: 0,\n border: \"none\",\n background: \"transparent\",\n color: fg.strong,\n ...T.label.xs,\n fontFamily: \"inherit\",\n textAlign: \"left\",\n outline: \"none\",\n padding: \"0 2px 0 6px\",\n };\n\n return (\n <div style={{ marginTop: 16, paddingBottom: 14 }}>\n {/* Size heading + W/H inputs */}\n <span style={{ ...T.label.sm, color: fg.strong }}>Size</span>\n <div style={{ display: \"flex\", gap: 6, marginTop: 8 }}>\n {([\"w\", \"h\"] as const).map((field) => (\n <div\n key={field}\n style={{\n flex: 1,\n minWidth: 0,\n display: \"flex\",\n alignItems: \"center\",\n height: 30,\n padding: \"0 8px\",\n background: state.input,\n borderRadius: 7,\n }}\n >\n <span style={{ ...T.label.xs, color: fg.sub, flexShrink: 0, userSelect: \"none\" }}>\n {field.toUpperCase()}\n </span>\n <input\n type=\"text\"\n value={editing === field ? text : String(size[field])}\n onFocus={() => { setEditing(field); setText(String(size[field])); }}\n onBlur={() => { setEditing(null); commitValue(field, text); }}\n onChange={(e) => setText(e.target.value)}\n onKeyDown={(e) => { if (e.key === \"Enter\") (e.target as HTMLElement).blur(); }}\n style={inputStyle}\n />\n </div>\n ))}\n </div>\n\n {/* Presets */}\n <div style={{ marginTop: 16 }}>\n <span style={{ ...T.label.sm, color: fg.strong, display: \"block\", marginBottom: 8 }}>Presets</span>\n <div style={{ position: \"relative\" }}>\n <button\n onClick={() => setSizeOpen((prev) => !prev)}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n width: \"100%\",\n gap: 6,\n height: 28,\n padding: \"0 8px\",\n borderRadius: 7,\n border: `1px solid ${stroke.default}`,\n background: state.input,\n color: fg.sub,\n cursor: \"pointer\",\n ...T.label.xs,\n fontFamily: \"inherit\",\n whiteSpace: \"nowrap\",\n }}\n >\n {currentPreset ? currentPreset.label : \"Custom\"}\n <ChevronDown size={12} strokeWidth={2} />\n </button>\n\n {sizeOpen && (\n <div\n style={{\n position: \"absolute\",\n bottom: \"calc(100% + 4px)\",\n right: 0,\n minWidth: 180,\n background: bg.base,\n border: `1px solid ${stroke.default}`,\n borderRadius: 8,\n padding: \"4px 0\",\n boxShadow: shadow.dropdown,\n zIndex: 1,\n }}\n >\n {FRAME_SIZE_PRESETS.map((preset) => (\n <DropItem\n key={preset.label}\n active={!isCustom && preset.w === size.w && preset.h === size.h}\n onClick={() => {\n onChange({ w: preset.w, h: preset.h });\n setSizeOpen(false);\n }}\n >\n <span>{preset.label}</span>\n <span style={{ marginLeft: 6, fontSize: 10, color: fg.muted }}>\n {preset.hint}\n </span>\n </DropItem>\n ))}\n </div>\n )}\n </div>\n </div>\n </div>\n );\n}\n\ntype BgTab = \"gradient\" | \"solid\" | \"image\";\n\nfunction BackgroundSetting({\n frameSettings,\n onFrameSettingsChange,\n}: {\n frameSettings: FrameSettings;\n onFrameSettingsChange: (settings: FrameSettings) => void;\n}) {\n const [tab, setTab] = useState<BgTab>(\n frameSettings.bgType === \"image\" ? \"image\" : frameSettings.bgType === \"gradient\" ? \"gradient\" : \"solid\",\n );\n const [moreOpen, setMoreOpen] = useState(false);\n const fileInputRef = useRef<HTMLInputElement>(null);\n\n const handleFileSelect = (e: React.ChangeEvent<HTMLInputElement>) => {\n const file = e.target.files?.[0];\n if (!file) return;\n const reader = new FileReader();\n reader.onload = () => {\n const dataUrl = reader.result as string;\n if (dataUrl.length > 2 * 1024 * 1024) {\n downscaleImage(dataUrl, frameSettings.size.w, frameSettings.size.h).then((scaled) => {\n onFrameSettingsChange({ ...frameSettings, bgType: \"image\", bgImage: scaled });\n });\n } else {\n onFrameSettingsChange({ ...frameSettings, bgType: \"image\", bgImage: dataUrl });\n }\n };\n reader.readAsDataURL(file);\n e.target.value = \"\";\n };\n\n const selectGradient = (g: string) => {\n onFrameSettingsChange({ ...frameSettings, bgType: \"gradient\", bgGradient: g });\n };\n\n const selectColor = (c: string) => {\n onFrameSettingsChange({ ...frameSettings, bgType: \"color\", bgColor: c });\n };\n\n const currentBg = frameSettings.bgType === \"gradient\" ? frameSettings.bgGradient : frameSettings.bgColor;\n\n return (\n <div>\n {/* Header */}\n <div style={{ display: \"flex\", alignItems: \"center\", justifyContent: \"space-between\", gap: 16 }}>\n <div style={{ display: \"flex\", alignItems: \"center\", gap: 8 }}>\n <LayoutGrid size={16} strokeWidth={1.6} color={fg.sub} />\n <span style={{ ...T.label.sm, color: fg.strong }}>Background</span>\n </div>\n <ToggleSwitch\n enabled={frameSettings.enabled}\n onChange={() => onFrameSettingsChange({ ...frameSettings, enabled: !frameSettings.enabled })}\n />\n </div>\n\n {/* Tab bar */}\n <div style={{ display: \"flex\", gap: 2, marginTop: 12, background: state.subtle, borderRadius: 8, padding: 2 }}>\n {([\"solid\", \"gradient\", \"image\"] as BgTab[]).map((t) => (\n <button\n key={t}\n onClick={() => setTab(t)}\n style={{\n flex: 1,\n padding: \"6px 0\",\n border: \"none\",\n borderRadius: 6,\n background: tab === t ? state.button : \"transparent\",\n color: tab === t ? fg.strong : fg.default,\n ...T.label.xs,\n fontFamily: \"inherit\",\n cursor: \"pointer\",\n transition: \"background 0.12s ease, color 0.12s ease\",\n textTransform: \"capitalize\" as const,\n }}\n >\n {t}\n </button>\n ))}\n </div>\n\n {/* Gradient presets */}\n {tab === \"gradient\" && (\n <div style={{ display: \"flex\", gap: 8, marginTop: 12, padding: \"4px 4px 14px\", flexWrap: \"wrap\" }}>\n {GRADIENT_PRESETS.map((g) => {\n const selected = frameSettings.bgType === \"gradient\" && frameSettings.bgGradient === g;\n return (\n <PresetSwatch\n key={g}\n background={g}\n selected={selected}\n onClick={() => selectGradient(g)}\n />\n );\n })}\n </div>\n )}\n\n {/* Solid color presets */}\n {tab === \"solid\" && (\n <>\n <div style={{ display: \"flex\", gap: 8, marginTop: 12, padding: \"4px 4px 14px\", flexWrap: \"wrap\" }}>\n {COLOR_PRESETS.map((c) => {\n const selected = frameSettings.bgType === \"color\" && frameSettings.bgColor === c;\n return (\n <PresetSwatch\n key={c}\n background={c}\n selected={selected}\n onClick={() => selectColor(c)}\n />\n );\n })}\n {(() => {\n const customColor = frameSettings.bgColor;\n const isCustom = !COLOR_PRESETS.includes(customColor.toUpperCase());\n const bg = isCustom ? customColor : \"transparent\";\n // Determine if icon should be light or dark based on background luminance\n const iconColor = isCustom ? (hexLuminance(customColor) > 0.4 ? \"rgba(0,0,0,0.5)\" : \"rgba(255,255,255,0.7)\") : fg.sub;\n return (\n <button\n onClick={async () => {\n if (!(\"EyeDropper\" in window)) return;\n try {\n // @ts-expect-error EyeDropper API not yet in all TS libs\n const result = await new window.EyeDropper().open();\n selectColor(result.sRGBHex);\n } catch { /* user cancelled */ }\n }}\n style={{\n width: 32,\n height: 32,\n borderRadius: \"50%\",\n border: isCustom ? `1px solid ${stroke.soft}` : `1px dashed ${stroke.default}`,\n outline: isCustom ? `2px solid ${accent.toggle}` : \"none\",\n outlineOffset: 1,\n background: bg,\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n color: iconColor,\n }}\n >\n <Pipette size={14} strokeWidth={2} />\n </button>\n );\n })()}\n </div>\n <div style={{ paddingBottom: 4 }}>\n <ColorHexInput value={frameSettings.bgColor} onChange={selectColor} />\n </div>\n </>\n )}\n\n {/* Image upload */}\n {tab === \"image\" && (\n <div style={{ marginTop: 12 }}>\n <input\n ref={fileInputRef}\n type=\"file\"\n accept=\"image/*\"\n onChange={handleFileSelect}\n style={{ display: \"none\" }}\n />\n {frameSettings.bgImage ? (\n <div style={{ display: \"flex\", alignItems: \"center\", gap: 8 }}>\n <img\n src={frameSettings.bgImage}\n alt=\"\"\n style={{\n width: 48,\n height: 28,\n borderRadius: 4,\n objectFit: \"cover\",\n border: `1px solid ${stroke.strong}`,\n }}\n />\n <SmallButton onClick={() => fileInputRef.current?.click()}>\n <Upload size={11} strokeWidth={2} />\n Replace\n </SmallButton>\n <SmallButton onClick={() => onFrameSettingsChange({ ...frameSettings, bgImage: null })}>\n <Trash2 size={11} strokeWidth={2} />\n </SmallButton>\n </div>\n ) : (\n <SmallButton onClick={() => fileInputRef.current?.click()}>\n <Upload size={11} strokeWidth={2} />\n Upload image\n </SmallButton>\n )}\n </div>\n )}\n\n {/* More options toggle */}\n <button\n onClick={() => setMoreOpen(!moreOpen)}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 4,\n marginTop: 12,\n marginBottom: moreOpen ? 0 : 14,\n background: \"none\",\n border: \"none\",\n cursor: \"pointer\",\n color: fg.sub,\n ...T.label.xs,\n fontFamily: \"inherit\",\n padding: 0,\n }}\n >\n <ChevronDown\n size={12}\n strokeWidth={2}\n style={{\n transform: moreOpen ? \"rotate(180deg)\" : \"rotate(0deg)\",\n transition: \"transform 0.15s ease\",\n }}\n />\n More options\n </button>\n\n {moreOpen && (\n <div style={{ marginTop: 8 }}>\n {/* Padding */}\n <div>\n <span style={{ ...T.label.sm, color: fg.strong }}>Padding</span>\n <div style={{ display: \"flex\", alignItems: \"center\", gap: 8, marginTop: 8, paddingLeft: 4 }}>\n <SlimSlider\n min={0}\n max={200}\n step={5}\n value={frameSettings.padding}\n onChange={(v) => onFrameSettingsChange({ ...frameSettings, padding: v })}\n />\n <SliderInput\n value={frameSettings.padding}\n onChange={(n) => onFrameSettingsChange({ ...frameSettings, padding: n })}\n />\n </div>\n </div>\n\n {/* Size */}\n <FrameSizeControl\n size={frameSettings.size}\n onChange={(size) => onFrameSettingsChange({ ...frameSettings, size })}\n />\n </div>\n )}\n </div>\n );\n}\n\nexport function SlimSlider({\n min,\n max,\n step,\n value,\n onChange,\n}: {\n min: number;\n max: number;\n step: number;\n value: number;\n onChange: (value: number) => void;\n}) {\n const trackRef = useRef<HTMLDivElement>(null);\n const pct = ((value - min) / (max - min)) * 100;\n\n const update = (clientX: number) => {\n const rect = trackRef.current!.getBoundingClientRect();\n const ratio = Math.max(0, Math.min(1, (clientX - rect.left) / rect.width));\n const raw = min + ratio * (max - min);\n const snapped = Math.round(raw / step) * step;\n onChange(Math.max(min, Math.min(max, snapped)));\n };\n\n const onPointerDown = (e: React.PointerEvent) => {\n e.preventDefault();\n (e.target as HTMLElement).setPointerCapture(e.pointerId);\n update(e.clientX);\n };\n\n const onPointerMove = (e: React.PointerEvent) => {\n if (e.buttons === 0) return;\n update(e.clientX);\n };\n\n return (\n <div\n ref={trackRef}\n onPointerDown={onPointerDown}\n onPointerMove={onPointerMove}\n style={{\n flex: 1,\n minWidth: 0,\n height: 20,\n display: \"flex\",\n alignItems: \"center\",\n cursor: \"pointer\",\n touchAction: \"none\",\n }}\n >\n <div style={{ position: \"relative\", width: \"100%\", height: 3, borderRadius: 2, background: stroke.default }}>\n <div style={{ position: \"absolute\", left: 0, top: 0, height: \"100%\", width: `${pct}%`, borderRadius: 2, background: fg.sub }} />\n <div\n style={{\n position: \"absolute\",\n top: \"50%\",\n left: `${pct}%`,\n width: 10,\n height: 10,\n borderRadius: \"50%\",\n background: fg.strong,\n transform: \"translate(-50%, -50%)\",\n }}\n />\n </div>\n </div>\n );\n}\n\nfunction PresetSwatch({\n background,\n selected,\n onClick,\n}: {\n background: string;\n selected: boolean;\n onClick: () => void;\n}) {\n return (\n <div\n onClick={onClick}\n style={{\n width: 32,\n height: 32,\n borderRadius: \"50%\",\n background,\n cursor: \"pointer\",\n border: `1px solid ${stroke.soft}`,\n outline: selected ? `2px solid ${accent.toggle}` : \"none\",\n outlineOffset: 1,\n position: \"relative\",\n transition: \"outline-color 0.12s ease\",\n flexShrink: 0,\n }}\n >\n {selected && (\n <div\n style={{\n position: \"absolute\",\n inset: 0,\n borderRadius: \"50%\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n background: \"rgba(0,0,0,0.2)\",\n }}\n >\n <Check size={16} strokeWidth={3} color=\"#fff\" />\n </div>\n )}\n </div>\n );\n}\n\n/** Approximate relative luminance from a hex color (0 = black, 1 = white) */\nfunction hexLuminance(hex: string): number {\n const n = parseInt(hex.replace(\"#\", \"\"), 16);\n const r = ((n >> 16) & 0xff) / 255;\n const g = ((n >> 8) & 0xff) / 255;\n const b = (n & 0xff) / 255;\n return 0.2126 * r + 0.7152 * g + 0.0722 * b;\n}\n\n/** Darken/lighten a hex color by an amount (-255 to 255) */\nfunction adjustColor(hex: string, amount: number): string {\n const num = parseInt(hex.replace(\"#\", \"\"), 16);\n const r = Math.min(255, Math.max(0, ((num >> 16) & 0xff) + amount));\n const g = Math.min(255, Math.max(0, ((num >> 8) & 0xff) + amount));\n const b = Math.min(255, Math.max(0, (num & 0xff) + amount));\n return `#${((r << 16) | (g << 8) | b).toString(16).padStart(6, \"0\")}`;\n}\n\nfunction BrowserFrameSetting({\n enabled,\n theme,\n shadow,\n radius,\n url,\n onToggle,\n onSelect,\n onShadowChange,\n onRadiusChange,\n onUrlChange,\n}: {\n enabled: boolean;\n theme: \"light\" | \"dark\";\n shadow: number;\n radius: number;\n url: string;\n onToggle: () => void;\n onSelect: (theme: \"light\" | \"dark\") => void;\n onShadowChange: (value: number) => void;\n onRadiusChange: (value: number) => void;\n onUrlChange: (value: string) => void;\n}) {\n const [moreOpen, setMoreOpen] = useState(false);\n\n const trafficLights = (\n <div style={{ display: \"flex\", gap: 4 }}>\n {[\"#FF5F57\", \"#FEBC2E\", \"#28C840\"].map((c) => (\n <div key={c} style={{ width: 5, height: 5, borderRadius: \"50%\", background: c }} />\n ))}\n </div>\n );\n\n const themes: { value: \"dark\" | \"light\"; label: string; titleBar: string; urlBar: string; border: string }[] = [\n { value: \"dark\", label: \"macOS Dark\", titleBar: \"#1C1C1C\", urlBar: \"#262626\", border: \"#333333\" },\n { value: \"light\", label: \"macOS Light\", titleBar: \"#F5F5F5\", urlBar: \"#FFFFFF\", border: \"#EBEBEB\" },\n ];\n\n return (\n <div style={{ padding: \"14px 0\" }}>\n <div style={{ display: \"flex\", alignItems: \"center\", justifyContent: \"space-between\", gap: 16 }}>\n <div style={{ display: \"flex\", alignItems: \"center\", gap: 8 }}>\n <AppWindow size={16} strokeWidth={1.6} color={fg.sub} />\n <span style={{ ...T.label.sm, color: fg.strong }}>Browser Frame</span>\n </div>\n <ToggleSwitch enabled={enabled} onChange={onToggle} />\n </div>\n\n <div style={{ display: \"flex\", gap: 10, marginTop: 12 }}>\n {themes.map((t) => {\n const selected = enabled && theme === t.value;\n return (\n <div\n key={t.value}\n onClick={() => onSelect(t.value)}\n style={{\n flex: 1,\n cursor: \"pointer\",\n borderRadius: 10,\n border: selected ? `2px solid ${accent.toggle}` : `1px solid ${stroke.soft}`,\n padding: selected ? 7 : 8,\n position: \"relative\",\n background: state.subtle,\n transition: \"border-color 0.12s ease\",\n }}\n >\n {/* Mini browser chrome preview */}\n <div\n style={{\n background: t.titleBar,\n borderRadius: 6,\n overflow: \"hidden\",\n border: t.value === \"light\" ? `1px solid ${t.border}` : \"none\",\n display: \"flex\",\n alignItems: \"center\",\n gap: 6,\n padding: \"6px 8px\",\n }}\n >\n {trafficLights}\n <div\n style={{\n flex: 1,\n height: 8,\n background: t.urlBar,\n borderRadius: 2,\n ...(t.value === \"light\" ? { border: `1px solid ${t.border}` } : {}),\n }}\n />\n </div>\n\n <div style={{ textAlign: \"center\" as const, marginTop: 8, ...T.label.xs, color: fg.default }}>\n {t.label}\n </div>\n\n {/* Selection checkmark */}\n {selected && (\n <div\n style={{\n position: \"absolute\",\n top: -5,\n right: -5,\n width: 18,\n height: 18,\n borderRadius: \"50%\",\n background: accent.toggle,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n }}\n >\n <Check size={10} strokeWidth={3} color=\"#fff\" />\n </div>\n )}\n </div>\n );\n })}\n </div>\n\n {/* More options toggle */}\n <button\n onClick={() => setMoreOpen(!moreOpen)}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 4,\n marginTop: 12,\n background: \"none\",\n border: \"none\",\n cursor: \"pointer\",\n color: fg.sub,\n ...T.label.xs,\n fontFamily: \"inherit\",\n padding: 0,\n }}\n >\n <ChevronDown\n size={12}\n strokeWidth={2}\n style={{\n transform: moreOpen ? \"rotate(180deg)\" : \"rotate(0deg)\",\n transition: \"transform 0.15s ease\",\n }}\n />\n More options\n </button>\n\n {moreOpen && (\n <div style={{ marginTop: 8 }}>\n {/* URL */}\n <div>\n <span style={{ ...T.label.sm, color: fg.strong }}>URL</span>\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n height: 30,\n padding: \"0 8px\",\n background: state.input,\n borderRadius: 7,\n marginTop: 8,\n }}\n >\n <input\n type=\"text\"\n value={url}\n onChange={(e) => onUrlChange(e.target.value)}\n placeholder=\"localhost\"\n style={{\n flex: 1,\n minWidth: 0,\n border: \"none\",\n background: \"transparent\",\n color: fg.strong,\n ...T.label.xs,\n fontFamily: \"inherit\",\n outline: \"none\",\n padding: 0,\n }}\n />\n </div>\n </div>\n\n {/* Shadow */}\n <div style={{ marginTop: 12 }}>\n <span style={{ ...T.label.sm, color: fg.strong }}>Shadow</span>\n <div style={{ display: \"flex\", alignItems: \"center\", gap: 8, marginTop: 8, paddingLeft: 4 }}>\n <SlimSlider\n min={0}\n max={100}\n step={5}\n value={shadow}\n onChange={onShadowChange}\n />\n <SliderInput\n value={shadow}\n onChange={onShadowChange}\n min={0}\n max={100}\n suffix=\"\"\n />\n </div>\n </div>\n\n {/* Rounding */}\n <div style={{ marginTop: 12 }}>\n <span style={{ ...T.label.sm, color: fg.strong }}>Rounding</span>\n <div style={{ display: \"flex\", alignItems: \"center\", gap: 8, marginTop: 8, paddingLeft: 4 }}>\n <SlimSlider\n min={0}\n max={8}\n step={1}\n value={radius}\n onChange={onRadiusChange}\n />\n <SliderInput\n value={radius}\n onChange={onRadiusChange}\n min={0}\n max={8}\n suffix=\"px\"\n />\n </div>\n </div>\n </div>\n )}\n </div>\n );\n}\n\nexport function SegmentButton({\n children,\n active,\n onClick,\n style,\n}: {\n children: React.ReactNode;\n active: boolean;\n onClick: () => void;\n style?: React.CSSProperties;\n}) {\n return (\n <button\n onClick={onClick}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 4,\n height: 28,\n padding: \"0 10px\",\n border: `1px solid ${stroke.default}`,\n background: active ? state.pressed : state.subtle,\n color: active ? fg.strong : fg.default,\n cursor: \"pointer\",\n ...T.label.xs,\n fontFamily: \"inherit\",\n transition: \"background 0.12s ease, color 0.12s ease\",\n ...style,\n }}\n >\n {children}\n </button>\n );\n}\n\nexport function ColorSwatch({\n color,\n onChange,\n}: {\n color: string;\n onChange: (color: string) => void;\n}) {\n const inputRef = useRef<HTMLInputElement>(null);\n\n return (\n <div style={{ position: \"relative\" }}>\n <button\n onClick={() => inputRef.current?.click()}\n style={{\n width: 24,\n height: 24,\n borderRadius: 6,\n border: `1px solid ${stroke.interactive}`,\n background: color,\n cursor: \"pointer\",\n padding: 0,\n }}\n />\n <input\n ref={inputRef}\n type=\"color\"\n value={color}\n onChange={(e) => onChange(e.target.value)}\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n width: 0,\n height: 0,\n opacity: 0,\n pointerEvents: \"none\",\n }}\n />\n </div>\n );\n}\n\nexport function SmallButton({\n children,\n onClick,\n}: {\n children: React.ReactNode;\n onClick: () => void;\n}) {\n const [hovered, setHovered] = useState(false);\n\n return (\n <button\n onClick={onClick}\n onMouseEnter={() => setHovered(true)}\n onMouseLeave={() => setHovered(false)}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 4,\n padding: \"4px 10px\",\n borderRadius: 6,\n border: `1px solid ${stroke.strong}`,\n background: hovered ? state.hoverStrong : state.button,\n color: fg.default,\n ...T.label.xs,\n cursor: \"pointer\",\n fontFamily: \"inherit\",\n transition: \"background 0.12s ease\",\n }}\n >\n {children}\n </button>\n );\n}\n\nexport function NumInput({\n value,\n onChange,\n}: {\n value: number;\n onChange: (value: string) => void;\n}) {\n const [editing, setEditing] = useState(false);\n const [text, setText] = useState(String(value));\n\n useEffect(() => {\n if (!editing) {\n setText(String(value));\n }\n }, [editing, value]);\n\n return (\n <input\n type=\"text\"\n value={editing ? text : String(value)}\n onFocus={() => {\n setEditing(true);\n setText(String(value));\n }}\n onBlur={() => {\n setEditing(false);\n onChange(text);\n }}\n onChange={(e) => setText(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") {\n (e.target as HTMLElement).blur();\n }\n }}\n style={{\n width: 54,\n padding: \"4px 6px\",\n background: state.input,\n border: `1px solid ${stroke.default}`,\n borderRadius: 7,\n color: fg.strong,\n ...T.label.xs,\n fontFamily: \"inherit\",\n textAlign: \"center\",\n outline: \"none\",\n }}\n />\n );\n}\n\nfunction SliderInput({\n value,\n onChange,\n min = 0,\n max = 200,\n suffix = \"px\",\n}: {\n value: number;\n onChange: (value: number) => void;\n min?: number;\n max?: number;\n suffix?: string;\n}) {\n const [editing, setEditing] = useState(false);\n const [text, setText] = useState(String(value));\n\n useEffect(() => {\n if (!editing) setText(String(value));\n }, [editing, value]);\n\n return (\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n height: 30,\n padding: \"0 8px\",\n background: state.input,\n borderRadius: 7,\n flexShrink: 0,\n width: 68,\n }}\n >\n <input\n type=\"text\"\n value={editing ? text : String(value)}\n onFocus={() => { setEditing(true); setText(String(value)); }}\n onBlur={() => {\n setEditing(false);\n const n = parseInt(text, 10);\n if (!Number.isNaN(n) && n >= min && n <= max) onChange(n);\n }}\n onChange={(e) => setText(e.target.value)}\n onKeyDown={(e) => { if (e.key === \"Enter\") (e.target as HTMLElement).blur(); }}\n style={{\n flex: 1,\n minWidth: 0,\n border: \"none\",\n background: \"transparent\",\n color: fg.strong,\n ...T.label.xs,\n fontFamily: \"inherit\",\n textAlign: \"left\",\n outline: \"none\",\n padding: 0,\n }}\n />\n {suffix && <span style={{ ...T.label.xs, color: fg.sub, flexShrink: 0, userSelect: \"none\", marginLeft: 4 }}>{suffix}</span>}\n </div>\n );\n}\n\nfunction ColorHexInput({\n value,\n onChange,\n}: {\n value: string;\n onChange: (color: string) => void;\n}) {\n const [editing, setEditing] = useState(false);\n const [text, setText] = useState(value.replace(\"#\", \"\"));\n\n useEffect(() => {\n if (!editing) setText(value.replace(\"#\", \"\"));\n }, [editing, value]);\n\n const commit = (raw: string) => {\n const hex = raw.startsWith(\"#\") ? raw : `#${raw}`;\n if (/^#[0-9a-fA-F]{6}$/.test(hex)) onChange(hex);\n };\n\n return (\n <div\n style={{\n flex: 1,\n minWidth: 0,\n display: \"flex\",\n alignItems: \"center\",\n height: 30,\n padding: \"0 8px\",\n background: state.input,\n borderRadius: 7,\n gap: 6,\n }}\n >\n <span style={{ ...T.label.xs, color: fg.sub, flexShrink: 0, userSelect: \"none\" }}>#</span>\n <input\n type=\"text\"\n value={editing ? text : value.replace(\"#\", \"\")}\n onFocus={() => { setEditing(true); setText(value.replace(\"#\", \"\")); }}\n onBlur={() => { setEditing(false); commit(text); }}\n onChange={(e) => setText(e.target.value)}\n onKeyDown={(e) => { if (e.key === \"Enter\") (e.target as HTMLElement).blur(); }}\n style={{\n flex: 1,\n minWidth: 0,\n border: \"none\",\n background: \"transparent\",\n color: fg.strong,\n ...T.label.xs,\n fontFamily: \"inherit\",\n textAlign: \"left\",\n outline: \"none\",\n padding: 0,\n }}\n />\n </div>\n );\n}\n\nexport function HexInput({\n value,\n onChange,\n}: {\n value: string;\n onChange: (color: string) => void;\n}) {\n const [editing, setEditing] = useState(false);\n const [text, setText] = useState(value);\n\n useEffect(() => {\n if (!editing) {\n setText(value);\n }\n }, [editing, value]);\n\n const commit = (raw: string) => {\n const hex = raw.startsWith(\"#\") ? raw : `#${raw}`;\n if (/^#[0-9a-fA-F]{6}$/.test(hex)) {\n onChange(hex);\n }\n };\n\n return (\n <input\n type=\"text\"\n value={editing ? text : value}\n onFocus={() => {\n setEditing(true);\n setText(value);\n }}\n onBlur={() => {\n setEditing(false);\n commit(text);\n }}\n onChange={(e) => setText(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") {\n (e.target as HTMLElement).blur();\n }\n }}\n style={{\n width: 72,\n padding: \"4px 6px\",\n background: state.input,\n border: `1px solid ${stroke.default}`,\n borderRadius: 7,\n color: fg.strong,\n ...T.label.xs,\n fontFamily: \"inherit\",\n textAlign: \"left\",\n outline: \"none\",\n }}\n />\n );\n}\n\nexport function StaticText({ children }: { children: React.ReactNode }) {\n return (\n <span\n style={{\n fontSize: 11,\n color: fg.muted,\n minWidth: 8,\n textAlign: \"center\",\n }}\n >\n {children}\n </span>\n );\n}\n\nexport function DropItem({\n children,\n onClick,\n active,\n}: {\n children: React.ReactNode;\n onClick: () => void;\n active?: boolean;\n}) {\n return (\n <button\n onClick={onClick}\n style={{\n display: \"block\",\n width: \"100%\",\n padding: \"7px 12px\",\n background: active ? state.active : \"transparent\",\n border: \"none\",\n color: fg.strong,\n textAlign: \"left\",\n cursor: \"pointer\",\n ...T.paragraph.sm,\n fontFamily: \"inherit\",\n }}\n >\n {children}\n </button>\n );\n}\n\nasync function downscaleImage(dataUrl: string, maxW: number, maxH: number): Promise<string> {\n return new Promise((resolve) => {\n const img = new Image();\n img.onload = () => {\n const canvas = document.createElement(\"canvas\");\n const scale = Math.min(maxW / img.width, maxH / img.height, 1);\n canvas.width = img.width * scale;\n canvas.height = img.height * scale;\n const ctx = canvas.getContext(\"2d\")!;\n ctx.drawImage(img, 0, 0, canvas.width, canvas.height);\n resolve(canvas.toDataURL(\"image/jpeg\", 0.85));\n };\n img.onerror = () => resolve(dataUrl);\n img.src = dataUrl;\n });\n}\n","\"use client\";\n\nimport React, { useEffect, useRef, useCallback, useState } from \"react\";\n\ninterface InspectorProps {\n onSelect: (element: HTMLElement) => void;\n onCancel: () => void;\n}\n\nexport function Inspector({ onSelect, onCancel }: InspectorProps) {\n const [highlight, setHighlight] = useState<{\n x: number;\n y: number;\n width: number;\n height: number;\n } | null>(null);\n const hoveredEl = useRef<HTMLElement | null>(null);\n const styleEl = useRef<HTMLStyleElement | null>(null);\n\n // Inject global crosshair cursor style\n useEffect(() => {\n const style = document.createElement(\"style\");\n style.setAttribute(\"data-afterbefore\", \"true\");\n style.textContent = [\n \"* { cursor: crosshair !important; }\",\n \"[data-afterbefore], [data-afterbefore] * { cursor: auto !important; }\",\n \"[data-afterbefore] button, [data-afterbefore] label, [data-afterbefore] a { cursor: pointer !important; }\",\n \"[data-afterbefore] input, [data-afterbefore] textarea { cursor: text !important; }\",\n ].join(\"\\n\");\n document.head.appendChild(style);\n styleEl.current = style;\n return () => {\n style.remove();\n };\n }, []);\n\n const isOverlayElement = useCallback((el: Element | null): boolean => {\n let node = el;\n while (node) {\n if (node instanceof HTMLElement && node.dataset.afterbefore) return true;\n node = node.parentElement;\n }\n return false;\n }, []);\n\n const handleMouseMove = useCallback(\n (e: MouseEvent) => {\n const el = document.elementFromPoint(e.clientX, e.clientY);\n if (!el || !(el instanceof HTMLElement) || isOverlayElement(el)) {\n setHighlight(null);\n hoveredEl.current = null;\n return;\n }\n hoveredEl.current = el;\n const rect = el.getBoundingClientRect();\n setHighlight({\n x: rect.x,\n y: rect.y,\n width: rect.width,\n height: rect.height,\n });\n },\n [isOverlayElement],\n );\n\n const handleClick = useCallback(\n (e: MouseEvent) => {\n if (isOverlayElement(e.target as Element)) return;\n e.preventDefault();\n e.stopPropagation();\n e.stopImmediatePropagation();\n if (hoveredEl.current) {\n onSelect(hoveredEl.current);\n }\n },\n [onSelect, isOverlayElement],\n );\n\n const handleKeyDown = useCallback(\n (e: KeyboardEvent) => {\n if (e.key === \"Escape\") {\n onCancel();\n }\n },\n [onCancel],\n );\n\n useEffect(() => {\n document.addEventListener(\"mousemove\", handleMouseMove, true);\n document.addEventListener(\"click\", handleClick, true);\n document.addEventListener(\"keydown\", handleKeyDown);\n return () => {\n document.removeEventListener(\"mousemove\", handleMouseMove, true);\n document.removeEventListener(\"click\", handleClick, true);\n document.removeEventListener(\"keydown\", handleKeyDown);\n };\n }, [handleMouseMove, handleClick, handleKeyDown]);\n\n return (\n <div data-afterbefore=\"true\" style={{ position: \"fixed\", inset: 0, zIndex: 2147483646, pointerEvents: \"none\" }}>\n {highlight && (\n <div\n style={{\n position: \"fixed\",\n left: highlight.x,\n top: highlight.y,\n width: highlight.width,\n height: highlight.height,\n background: \"transparent\",\n border: \"1px solid #fff\",\n borderRadius: 2,\n boxShadow: \"0 0 0 9999px rgba(0, 0, 0, 0.5)\",\n pointerEvents: \"none\",\n }}\n />\n )}\n\n </div>\n );\n}\n"],"mappings":"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","names":["useState","useCallback","useEffect","state","useCallback","useEffect","useRef","useState","ChevronDown","useCallback","useEffect","useState","Trash2","useState","jsx","jsxs","useState","text","bg","shadow","useState","jsx","jsxs","useState","jsx","useState","text","jsxs","jsx","jsx","Fragment","jsx","jsxs","useState","useEffect","useCallback","Trash2","Fragment","jsx","jsxs","useState","useRef","useEffect","useCallback","DropItem","accent","ChevronDown","useEffect","useRef","useCallback","useState","jsx","style","jsx","jsxs","state","useState","useEffect","useCallback"]}
|
|
1
|
+
{"version":3,"sources":["../../src/overlay/index.tsx","../../src/overlay/state.ts","../../src/overlay/capture.ts","../../src/overlay/font.ts","../../src/overlay/ui/toolbar.tsx","../../src/overlay/color.ts","../../src/overlay/ui/screenshots-panel.tsx","../../src/overlay/ui/settings-panel.tsx","../../src/overlay/ui/inspector.tsx"],"sourcesContent":["\"use client\";\n\nimport React, { useState, useCallback, useEffect } from \"react\";\nimport { useOverlayState } from \"./state\";\nimport type { CaptureMode } from \"./state\";\nimport { capture, renderFrame, DEFAULT_FRAME_SETTINGS, type FrameSettings } from \"./capture\";\nimport { injectInterFont } from \"./font\";\nimport { Toolbar } from \"./ui/toolbar\";\nimport { Inspector } from \"./ui/inspector\";\n\nasync function saveCapture(\n mode: CaptureMode,\n renderedDataUrl: string,\n rawDataUrl: string,\n viewportDataUrl: string | null,\n) {\n try {\n const res = await fetch(\"/__afterbefore/save\", {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n mode,\n image: renderedDataUrl,\n rawImage: rawDataUrl,\n viewportImage: viewportDataUrl,\n }),\n });\n if (!res.ok) throw new Error(\"Save failed\");\n } catch {\n const link = document.createElement(\"a\");\n link.download = \"screenshot.png\";\n link.href = renderedDataUrl;\n link.click();\n }\n}\n\nexport function AfterBefore() {\n const { state, captureComplete, reset } = useOverlayState();\n const [toolbarActive, setToolbarActive] = useState(false);\n const [inspectorActive, setInspectorActive] = useState(false);\n const [loading, setLoading] = useState(false);\n const [selectedMode, setSelectedMode] = useState<CaptureMode>(\"component\");\n const [frameSettings, setFrameSettings] = useState<FrameSettings>(DEFAULT_FRAME_SETTINGS);\n\n useEffect(() => {\n injectInterFont();\n }, []);\n\n useEffect(() => {\n try {\n const stored = localStorage.getItem(\"ab-frame-settings\");\n if (stored) {\n setFrameSettings({ ...DEFAULT_FRAME_SETTINGS, ...JSON.parse(stored) });\n } else if (localStorage.getItem(\"ab-frame-black\") === \"true\") {\n // Migration from old boolean setting\n const migrated = { ...DEFAULT_FRAME_SETTINGS, enabled: true };\n setFrameSettings(migrated);\n localStorage.setItem(\"ab-frame-settings\", JSON.stringify(migrated));\n localStorage.removeItem(\"ab-frame-black\");\n }\n } catch {\n setFrameSettings(DEFAULT_FRAME_SETTINGS);\n }\n }, []);\n\n useEffect(() => {\n if (state.phase === \"ready\") {\n const timer = setTimeout(() => {\n reset();\n }, 1500);\n return () => clearTimeout(timer);\n }\n }, [state.phase, reset]);\n\n const handleToggle = useCallback(() => {\n if (loading) return;\n\n if (state.phase === \"ready\") {\n reset();\n }\n\n if (toolbarActive || inspectorActive) {\n setToolbarActive(false);\n setInspectorActive(false);\n } else {\n if (selectedMode === \"component\") {\n setToolbarActive(true);\n setInspectorActive(true);\n } else {\n setToolbarActive(true);\n setInspectorActive(false);\n }\n }\n }, [state.phase, loading, toolbarActive, inspectorActive, selectedMode, reset]);\n\n const performCapture = useCallback(\n async (\n mode: CaptureMode,\n element?: HTMLElement,\n ) => {\n setLoading(true);\n try {\n const raw = await capture({ mode, element });\n\n // Choose the right image for rendering: viewport when chrome is ON, else component\n const primaryImage = frameSettings.browserChrome && raw.viewportDataUrl\n ? raw.viewportDataUrl\n : raw.dataUrl;\n const renderedDataUrl = await renderFrame(primaryImage, frameSettings);\n\n await saveCapture(mode, renderedDataUrl, raw.dataUrl, raw.viewportDataUrl);\n captureComplete({\n dataUrl: renderedDataUrl,\n mode,\n timestamp: Date.now(),\n });\n\n // Re-expand toolbar so the screenshots panel can auto-open\n try {\n if (localStorage.getItem(\"ab-auto-open-panel\") !== \"false\") {\n setToolbarActive(true);\n }\n } catch {}\n\n } catch (err) {\n console.error(\"[afterbefore] Capture failed:\", err);\n } finally {\n setLoading(false);\n }\n },\n [captureComplete, frameSettings],\n );\n\n const handleToolbarCapture = useCallback(\n (mode: CaptureMode) => {\n if (mode === \"viewport\") {\n setToolbarActive(false);\n performCapture(\"viewport\");\n } else if (mode === \"fullpage\") {\n setToolbarActive(false);\n performCapture(\"fullpage\");\n } else if (mode === \"component\") {\n setInspectorActive(true);\n }\n },\n [performCapture],\n );\n\n const handleToolbarCancel = useCallback(() => {\n setToolbarActive(false);\n setInspectorActive(false);\n }, []);\n\n const handleComponentSelect = useCallback(\n (element: HTMLElement) => {\n setInspectorActive(false);\n setToolbarActive(false);\n performCapture(\"component\", element);\n },\n [performCapture],\n );\n\n const handleComponentCancel = useCallback(() => {\n setInspectorActive(false);\n setToolbarActive(true);\n }, []);\n\n const handleFrameSettingsChange = useCallback((next: FrameSettings) => {\n setFrameSettings(next);\n try {\n localStorage.setItem(\"ab-frame-settings\", JSON.stringify(next));\n } catch {\n // noop\n }\n }, []);\n\n const handleModeChange = useCallback((mode: CaptureMode) => {\n setSelectedMode(mode);\n setInspectorActive(mode === \"component\");\n }, []);\n\n return (\n <div data-afterbefore=\"true\">\n <Toolbar\n expanded={toolbarActive}\n onToggle={handleToggle}\n phase={state.phase}\n loading={loading}\n selectedMode={selectedMode}\n onModeChange={handleModeChange}\n onCapture={handleToolbarCapture}\n onCancel={handleToolbarCancel}\n frameSettings={frameSettings}\n onFrameSettingsChange={handleFrameSettingsChange}\n />\n\n {inspectorActive && (\n <Inspector onSelect={handleComponentSelect} onCancel={handleComponentCancel} />\n )}\n </div>\n );\n}\n","import { useState, useCallback } from \"react\";\n\nexport type CaptureMode = \"viewport\" | \"fullpage\" | \"component\";\n\nexport type OverlayPhase = \"idle\" | \"ready\";\n\nexport interface CaptureResult {\n dataUrl: string;\n mode: CaptureMode;\n timestamp: number;\n}\n\nexport interface OverlayState {\n phase: OverlayPhase;\n lastCapture: CaptureResult | null;\n}\n\nconst initialState: OverlayState = {\n phase: \"idle\",\n lastCapture: null,\n};\n\nexport function useOverlayState() {\n const [state, setState] = useState<OverlayState>(initialState);\n\n const captureComplete = useCallback(\n (result: CaptureResult) => {\n setState({ phase: \"ready\", lastCapture: result });\n },\n [],\n );\n\n const reset = useCallback(() => {\n setState(initialState);\n }, []);\n\n return { state, captureComplete, reset };\n}\n","import { snapdom } from \"@zumer/snapdom\";\nimport type { CaptureMode } from \"./state\";\n\nexport interface FrameSettings {\n enabled: boolean;\n size: { w: number; h: number };\n bgType: \"color\" | \"gradient\" | \"image\";\n bgColor: string;\n bgGradient: string;\n bgImage: string | null;\n padding: number;\n browserChrome: boolean;\n browserTheme: \"light\" | \"dark\";\n browserUrl: string;\n browserShadow: number;\n browserRadius: number;\n afterbefore: boolean;\n}\n\nexport const GRADIENT_PRESETS = [\n \"linear-gradient(135deg, #a78bfa 0%, #f472b6 100%)\",\n \"linear-gradient(135deg, #3b82f6 0%, #06b6d4 100%)\",\n \"linear-gradient(135deg, #34d399 0%, #6ee7b7 100%)\",\n \"linear-gradient(135deg, #f97316 0%, #ef4444 100%)\",\n \"linear-gradient(180deg, #1e293b 0%, #0f172a 100%)\",\n];\n\nexport const COLOR_PRESETS = [\n \"#FFFFFF\",\n \"#F5F5F5\",\n \"#F8F4ED\",\n \"#1E1E1E\",\n \"#000000\",\n];\n\nexport const DEFAULT_FRAME_SETTINGS: FrameSettings = {\n enabled: false,\n size: { w: 1920, h: 1080 },\n bgType: \"color\",\n bgColor: \"#F5F5F5\",\n bgGradient: GRADIENT_PRESETS[0],\n bgImage: null,\n padding: 192,\n browserChrome: false,\n browserTheme: \"dark\",\n browserUrl: \"localhost\",\n browserShadow: 50,\n browserRadius: 8,\n afterbefore: false,\n};\n\nexport const FRAME_SIZE_PRESETS: { label: string; hint: string; w: number; h: number }[] = [\n { label: \"1920 x 1080\", hint: \"Desktop / HD\", w: 1920, h: 1080 },\n { label: \"1080 x 1080\", hint: \"Social square\", w: 1080, h: 1080 },\n { label: \"1200 x 630\", hint: \"Open Graph / link preview\", w: 1200, h: 630 },\n { label: \"1080 x 1920\", hint: \"Story / portrait\", w: 1080, h: 1920 },\n];\n\nexport interface RawCapture {\n dataUrl: string;\n viewportDataUrl: string | null;\n}\n\ninterface CaptureOptions {\n mode: CaptureMode;\n element?: HTMLElement;\n}\n\n/** Selectors for dev tool UI that should be excluded from capture */\nconst DEV_UI_SELECTORS = [\n // Afterbefore overlay\n \"[data-afterbefore]\",\n // Next.js dev indicators\n \"[data-nextjs-toast]\",\n \"[data-nextjs-dev-overlay]\",\n \"[data-nextjs-dialog]\",\n \"[data-nextjs-dialog-backdrop]\",\n \"[data-next-badge]\",\n \"[data-next-mark]\",\n];\n\n/** Minimum 2x resolution for crisp output on all displays */\nconst MIN_DPR = 2;\n\nfunction getDpr(): number {\n return Math.max(window.devicePixelRatio || 1, MIN_DPR);\n}\n\nconst SNAPDOM_BASE = {\n exclude: DEV_UI_SELECTORS,\n excludeMode: \"remove\" as const,\n};\n\nasync function toPngDataUrl(\n el: Element,\n opts?: Record<string, unknown>,\n): Promise<string> {\n const result = await snapdom(el, { ...SNAPDOM_BASE, ...opts });\n const img = await result.toPng();\n return img.src;\n}\n\nexport async function capture(options: CaptureOptions): Promise<RawCapture> {\n const { mode, element } = options;\n\n if (mode === \"viewport\") {\n return { dataUrl: await captureRawViewport(), viewportDataUrl: null };\n }\n if (mode === \"fullpage\") {\n return { dataUrl: await captureFullPage(), viewportDataUrl: null };\n }\n if (mode === \"component\" && element) {\n const dataUrl = await toPngDataUrl(element);\n const viewportDataUrl = await captureRawViewport();\n return { dataUrl, viewportDataUrl };\n }\n throw new Error(`Invalid capture mode: ${mode}`);\n}\n\n/** Find the bottom edge of actual content (ignoring min-height/vh stretching) */\nfunction getContentBottom(): number {\n let maxBottom = 0;\n for (const child of document.body.children) {\n if ((child as HTMLElement).dataset?.afterbefore != null) continue;\n if ((child as HTMLElement).id === \"afterbefore-root\") continue;\n const rect = child.getBoundingClientRect();\n if (rect.height > 0) {\n maxBottom = Math.max(maxBottom, rect.bottom);\n }\n }\n return maxBottom + window.scrollY;\n}\n\nasync function captureRawViewport(): Promise<string> {\n const dpr = window.devicePixelRatio || 1;\n const vw = window.innerWidth;\n const scrollY = window.scrollY;\n\n // Use content bottom instead of full viewport to avoid empty space below content\n const contentBottom = getContentBottom();\n const vh = Math.min(window.innerHeight, Math.ceil(contentBottom - scrollY));\n\n const fullDataUrl = await captureFullPage();\n const fullImg = await loadImage(fullDataUrl);\n\n const canvas = document.createElement(\"canvas\");\n canvas.width = vw * dpr;\n canvas.height = vh * dpr;\n\n const ctx = canvas.getContext(\"2d\")!;\n ctx.fillStyle = \"#ffffff\";\n ctx.fillRect(0, 0, canvas.width, canvas.height);\n ctx.drawImage(\n fullImg,\n 0,\n scrollY * dpr,\n vw * dpr,\n vh * dpr,\n 0,\n 0,\n vw * dpr,\n vh * dpr,\n );\n\n return canvas.toDataURL(\"image/png\");\n}\n\nfunction drawBrowserChrome(\n img: HTMLImageElement,\n theme: \"light\" | \"dark\",\n dpr: number,\n url = \"localhost\",\n): string {\n // Single-row compact chrome bar (dots + URL bar on same line)\n const CHROME_H = 28;\n const BAR_PAD_X = 10;\n const DOT_R = 3.5;\n const DOT_START_X = 12;\n const DOT_GAP = 12;\n const DOTS_END = DOT_START_X + DOT_GAP * 2 + DOT_R + 6;\n const URL_BAR_H = 16;\n const URL_BAR_R = 4;\n\n const imgW = img.width;\n const imgH = img.height;\n\n const canvas = document.createElement(\"canvas\");\n canvas.width = imgW;\n canvas.height = imgH + CHROME_H * dpr;\n\n const ctx = canvas.getContext(\"2d\")!;\n\n const colors =\n theme === \"dark\"\n ? { titleBar: \"#1C1C1C\", urlBar: \"#262626\", text: \"#7B7B7B\", border: \"#333333\" }\n : { titleBar: \"#F5F5F5\", urlBar: \"#FFFFFF\", text: \"#999999\", border: \"#EBEBEB\" };\n\n // Chrome background\n ctx.fillStyle = colors.titleBar;\n ctx.fillRect(0, 0, canvas.width, CHROME_H * dpr);\n\n // Bottom border\n ctx.fillStyle = colors.border;\n ctx.fillRect(0, (CHROME_H - 1) * dpr, canvas.width, dpr);\n\n // Traffic light dots (vertically centered)\n const dotY = (CHROME_H / 2) * dpr;\n const dotColors = [\"#FF5F57\", \"#FEBC2E\", \"#28C840\"];\n for (let i = 0; i < 3; i++) {\n ctx.beginPath();\n ctx.arc((DOT_START_X + i * DOT_GAP) * dpr, dotY, DOT_R * dpr, 0, Math.PI * 2);\n ctx.fillStyle = dotColors[i];\n ctx.fill();\n }\n\n // URL bar (same row, to the right of dots)\n const urlBarX = DOTS_END * dpr;\n const urlBarY = ((CHROME_H - URL_BAR_H) / 2) * dpr;\n const urlBarW = canvas.width - urlBarX - BAR_PAD_X * dpr;\n const urlBarH = URL_BAR_H * dpr;\n\n ctx.fillStyle = colors.urlBar;\n roundRect(ctx, urlBarX, urlBarY, urlBarW, urlBarH, URL_BAR_R * dpr);\n ctx.fill();\n\n if (theme === \"light\") {\n ctx.strokeStyle = colors.border;\n ctx.lineWidth = dpr;\n roundRect(ctx, urlBarX, urlBarY, urlBarW, urlBarH, URL_BAR_R * dpr);\n ctx.stroke();\n }\n\n // URL text (left-aligned inside URL bar)\n ctx.fillStyle = colors.text;\n ctx.font = `${9 * dpr}px -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif`;\n ctx.textAlign = \"left\";\n ctx.textBaseline = \"middle\";\n ctx.fillText(url, urlBarX + 8 * dpr, urlBarY + urlBarH / 2);\n\n // Draw the viewport image below chrome\n ctx.drawImage(img, 0, CHROME_H * dpr);\n\n return canvas.toDataURL(\"image/png\");\n}\n\nfunction roundRect(\n ctx: CanvasRenderingContext2D,\n x: number,\n y: number,\n w: number,\n h: number,\n r: number,\n) {\n ctx.beginPath();\n ctx.moveTo(x + r, y);\n ctx.lineTo(x + w - r, y);\n ctx.quadraticCurveTo(x + w, y, x + w, y + r);\n ctx.lineTo(x + w, y + h - r);\n ctx.quadraticCurveTo(x + w, y + h, x + w - r, y + h);\n ctx.lineTo(x + r, y + h);\n ctx.quadraticCurveTo(x, y + h, x, y + h - r);\n ctx.lineTo(x, y + r);\n ctx.quadraticCurveTo(x, y, x + r, y);\n ctx.closePath();\n}\n\nasync function captureFullPage(): Promise<string> {\n const scrollY = window.scrollY;\n const body = document.body;\n const html = document.documentElement;\n\n const fullHeight = Math.max(\n body.scrollHeight,\n body.offsetHeight,\n html.clientHeight,\n html.scrollHeight,\n html.offsetHeight,\n );\n\n const prevOverflow = html.style.overflow;\n const prevHeight = html.style.height;\n html.style.overflow = \"visible\";\n html.style.height = `${fullHeight}px`;\n\n try {\n return await toPngDataUrl(document.documentElement, {\n width: window.innerWidth,\n height: fullHeight,\n });\n } finally {\n html.style.overflow = prevOverflow;\n html.style.height = prevHeight;\n window.scrollTo(0, scrollY);\n }\n}\n\nexport async function renderFrame(\n imageDataUrl: string,\n frameSettings: FrameSettings,\n): Promise<string> {\n if (!frameSettings.enabled) {\n return imageDataUrl;\n }\n\n const img = await loadImage(imageDataUrl);\n const dpr = getDpr();\n\n const FRAME_W = frameSettings.size.w;\n const FRAME_H = frameSettings.size.h;\n const pad = frameSettings.padding ?? 40;\n\n // If browser chrome is ON, wrap content in chrome first\n let contentImg = img;\n if (frameSettings.browserChrome) {\n const chromeDataUrl = drawBrowserChrome(img, frameSettings.browserTheme, dpr, frameSettings.browserUrl);\n contentImg = await loadImage(chromeDataUrl);\n }\n\n // Content dimensions in CSS pixels\n const contentW = contentImg.width / dpr;\n const contentH = contentImg.height / dpr;\n\n // Scale to fit within frame minus padding (constrain by both width and height)\n const maxW = FRAME_W - pad * 2;\n const maxH = FRAME_H - pad * 2;\n const scale = Math.min(maxW / contentW, maxH / contentH, 1);\n\n const drawW = contentW * scale * dpr;\n const drawH = contentH * scale * dpr;\n\n const canvas = document.createElement(\"canvas\");\n canvas.width = FRAME_W * dpr;\n canvas.height = FRAME_H * dpr;\n\n const ctx = canvas.getContext(\"2d\")!;\n\n await drawBackground(ctx, frameSettings, canvas.width, canvas.height);\n\n // Center content — shift up slightly when browser chrome is on to account for\n // shadow extending below and chrome bar visual weight at top\n const dx = (canvas.width - drawW) / 2;\n const shadowShift = frameSettings.browserChrome\n ? ((frameSettings.browserShadow ?? 50) / 100) * 12 * dpr\n : 0;\n const dy = (canvas.height - drawH) / 2 - shadowShift;\n\n if (frameSettings.browserChrome) {\n const radius = (frameSettings.browserRadius ?? 8) * scale * dpr;\n\n // Draw shadow first (behind the rounded rect)\n const shadowVal = frameSettings.browserShadow ?? 50;\n if (shadowVal > 0) {\n ctx.save();\n ctx.shadowColor = `rgba(0, 0, 0, ${(shadowVal / 100) * 0.6})`;\n ctx.shadowBlur = (shadowVal / 100) * 40 * dpr;\n ctx.shadowOffsetY = (shadowVal / 100) * 8 * dpr;\n ctx.shadowOffsetX = 0;\n ctx.fillStyle = \"rgba(0,0,0,1)\";\n roundRect(ctx, dx, dy, drawW, drawH, radius);\n ctx.fill();\n ctx.restore();\n }\n\n // Clip to rounded rect, fill white background, then draw content\n ctx.save();\n roundRect(ctx, dx, dy, drawW, drawH, radius);\n ctx.clip();\n ctx.fillStyle = \"#ffffff\";\n ctx.fillRect(dx, dy, drawW, drawH);\n ctx.drawImage(contentImg, dx, dy, drawW, drawH);\n ctx.restore();\n } else {\n ctx.drawImage(contentImg, dx, dy, drawW, drawH);\n }\n\n return canvas.toDataURL(\"image/png\");\n}\n\nasync function drawBackground(\n ctx: CanvasRenderingContext2D,\n frameSettings: FrameSettings,\n w: number,\n h: number,\n) {\n if (frameSettings.bgType === \"image\" && frameSettings.bgImage) {\n try {\n const bgImg = await loadImage(frameSettings.bgImage);\n drawCover(ctx, bgImg, w, h);\n } catch {\n ctx.fillStyle = frameSettings.bgColor;\n ctx.fillRect(0, 0, w, h);\n }\n } else if (frameSettings.bgType === \"gradient\") {\n fillCssGradient(ctx, frameSettings.bgGradient, w, h);\n } else if (frameSettings.bgColor !== \"transparent\") {\n ctx.fillStyle = frameSettings.bgColor;\n ctx.fillRect(0, 0, w, h);\n }\n}\n\nexport async function renderAfterbeforeFrame(\n beforeDataUrl: string,\n afterDataUrl: string,\n frameSettings: FrameSettings,\n): Promise<string> {\n const dpr = getDpr();\n const FRAME_W = 1920;\n const FRAME_H = 1080;\n const pad = frameSettings.padding ?? 192;\n const gap = 40;\n const labelSpace = 48;\n\n const canvas = document.createElement(\"canvas\");\n canvas.width = FRAME_W * dpr;\n canvas.height = FRAME_H * dpr;\n const ctx = canvas.getContext(\"2d\")!;\n\n await drawBackground(ctx, frameSettings, canvas.width, canvas.height);\n\n const beforeImg = await loadImage(beforeDataUrl);\n const afterImg = await loadImage(afterDataUrl);\n\n const availW = FRAME_W - pad * 2;\n const availH = FRAME_H - pad * 2 - labelSpace;\n const slotW = (availW - gap) / 2;\n\n for (const [i, img] of [beforeImg, afterImg].entries()) {\n const imgW = img.width / dpr;\n const imgH = img.height / dpr;\n const s = Math.min(slotW / imgW, availH / imgH, 1);\n const drawW = imgW * s * dpr;\n const drawH = imgH * s * dpr;\n const slotX = (pad + i * (slotW + gap)) * dpr;\n const dx = slotX + (slotW * dpr - drawW) / 2;\n const dy = pad * dpr + (availH * dpr - drawH) / 2;\n\n // White background behind each image\n ctx.fillStyle = \"#ffffff\";\n ctx.fillRect(dx, dy, drawW, drawH);\n ctx.drawImage(img, dx, dy, drawW, drawH);\n }\n\n // Draw labels\n ctx.fillStyle = frameSettings.bgColor === \"#FFFFFF\" || frameSettings.bgColor === \"#F5F5F5\" || frameSettings.bgColor === \"#F8F4ED\"\n ? \"#666666\"\n : \"#ffffff\";\n ctx.font = `500 ${14 * dpr}px -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif`;\n ctx.textAlign = \"center\";\n ctx.textBaseline = \"top\";\n const labelY = (FRAME_H - pad - labelSpace + 16) * dpr;\n const labels = [\"Before\", \"After\"];\n for (let i = 0; i < 2; i++) {\n const slotX = (pad + i * (slotW + gap)) * dpr;\n const centerX = slotX + (slotW * dpr) / 2;\n ctx.fillText(labels[i], centerX, labelY);\n }\n\n return canvas.toDataURL(\"image/png\");\n}\n\n/** Draw image with cover-fit (like CSS background-size: cover) */\nfunction drawCover(\n ctx: CanvasRenderingContext2D,\n img: HTMLImageElement,\n cw: number,\n ch: number,\n) {\n const scale = Math.max(cw / img.width, ch / img.height);\n const sw = cw / scale;\n const sh = ch / scale;\n const sx = (img.width - sw) / 2;\n const sy = (img.height - sh) / 2;\n ctx.drawImage(img, sx, sy, sw, sh, 0, 0, cw, ch);\n}\n\nfunction loadImage(src: string): Promise<HTMLImageElement> {\n return new Promise((resolve, reject) => {\n const img = new Image();\n img.onload = () => resolve(img);\n img.onerror = reject;\n img.src = src;\n });\n}\n\n/** Parse a CSS linear-gradient and draw it on a canvas context */\nfunction fillCssGradient(\n ctx: CanvasRenderingContext2D,\n css: string,\n w: number,\n h: number,\n) {\n const match = css.match(\n /linear-gradient\\(\\s*([\\d.]+)deg\\s*,\\s*(.+)\\)/,\n );\n if (!match) {\n ctx.fillStyle = \"#000\";\n ctx.fillRect(0, 0, w, h);\n return;\n }\n\n const angle = (parseFloat(match[1]) * Math.PI) / 180;\n const stopsRaw = match[2].split(/,\\s*(?=#|\\w)/).map((s) => s.trim());\n\n // Gradient line endpoints from CSS angle\n const cx = w / 2;\n const cy = h / 2;\n const len = Math.abs(w * Math.sin(angle)) + Math.abs(h * Math.cos(angle));\n const x0 = cx - (Math.sin(angle) * len) / 2;\n const y0 = cy + (Math.cos(angle) * len) / 2;\n const x1 = cx + (Math.sin(angle) * len) / 2;\n const y1 = cy - (Math.cos(angle) * len) / 2;\n\n const grad = ctx.createLinearGradient(x0, y0, x1, y1);\n for (const stop of stopsRaw) {\n const parts = stop.match(/^(.+?)\\s+([\\d.]+)%$/);\n if (parts) {\n grad.addColorStop(parseFloat(parts[2]) / 100, parts[1]);\n }\n }\n ctx.fillStyle = grad;\n ctx.fillRect(0, 0, w, h);\n}\n","import type React from \"react\";\n\nexport const FONT_FAMILY =\n \"'Inter var', 'Inter', system-ui, -apple-system, sans-serif\";\n\nexport const FONT_FEATURE_SETTINGS = \"'ss11' 1, 'calt' 1\";\n\n/** Spread on root container to set font family + features */\nexport const fontBase: React.CSSProperties = {\n fontFamily: FONT_FAMILY,\n fontFeatureSettings: FONT_FEATURE_SETTINGS,\n};\n\n// ---------------------------------------------------------------------------\n// Align UI Type System — Inter\n// ---------------------------------------------------------------------------\n//\n// Four categories: title, label, paragraph, subheading\n// Font: Inter | Weight: 500 (label/title/subheading), 400 (paragraph)\n// Subheadings are uppercase by default.\n//\n// Letter-spacing values are from Inter's dynamic metrics\n// (percentages converted to em: -1% → -0.01em).\n// ---------------------------------------------------------------------------\n\nfunction style(\n fontSize: number,\n lineHeight: number,\n fontWeight: 400 | 500,\n letterSpacing: string,\n extra?: React.CSSProperties,\n): React.CSSProperties {\n return { fontSize, lineHeight: `${lineHeight}px`, fontWeight, letterSpacing, ...extra };\n}\n\nexport const text = {\n // --- Title (Medium 500) ---\n title: {\n h1: style(56, 64, 500, \"-0.01em\"),\n h2: style(48, 56, 500, \"-0.01em\"),\n h3: style(40, 48, 500, \"-0.01em\"),\n h4: style(32, 40, 500, \"-0.005em\"),\n h5: style(24, 32, 500, \"0em\"),\n h6: style(20, 28, 500, \"0em\"),\n },\n\n // --- Label (Medium 500) ---\n label: {\n xl: style(24, 32, 500, \"-0.015em\"),\n lg: style(18, 24, 500, \"-0.015em\"),\n md: style(16, 24, 500, \"-0.011em\"),\n sm: style(14, 20, 500, \"-0.006em\"),\n xs: style(12, 16, 500, \"0em\"),\n },\n\n // --- Paragraph (Regular 400) ---\n paragraph: {\n xl: style(24, 32, 400, \"-0.015em\"),\n lg: style(18, 24, 400, \"-0.015em\"),\n md: style(16, 24, 400, \"-0.011em\"),\n sm: style(14, 20, 400, \"-0.006em\"),\n xs: style(12, 16, 400, \"0em\"),\n },\n\n // --- Subheading (Medium 500, uppercase) ---\n subheading: {\n md: style(16, 24, 500, \"0.06em\", { textTransform: \"uppercase\" }),\n sm: style(14, 20, 500, \"0.06em\", { textTransform: \"uppercase\" }),\n xs: style(12, 16, 500, \"0.04em\", { textTransform: \"uppercase\" }),\n xxs: style(11, 12, 500, \"0.02em\", { textTransform: \"uppercase\" }),\n },\n} as const;\n\n// ---------------------------------------------------------------------------\n// Font injection (loads Inter from rsms.me at runtime)\n// ---------------------------------------------------------------------------\n\nconst INTER_CSS_ID = \"afterbefore-inter-font\";\n\nexport function injectInterFont() {\n if (document.getElementById(INTER_CSS_ID)) return;\n\n const preconnect = document.createElement(\"link\");\n preconnect.rel = \"preconnect\";\n preconnect.href = \"https://rsms.me/\";\n document.head.appendChild(preconnect);\n\n const stylesheet = document.createElement(\"link\");\n stylesheet.id = INTER_CSS_ID;\n stylesheet.rel = \"stylesheet\";\n stylesheet.href = \"https://rsms.me/inter/inter.css\";\n document.head.appendChild(stylesheet);\n}\n","\"use client\";\n\nimport React, { useCallback, useEffect, useRef, useState } from \"react\";\nimport {\n ChevronDown,\n LoaderCircle,\n FileText,\n Monitor,\n} from \"lucide-react\";\nimport { Camera, Check, X, Image } from \"lucide-react\";\nimport type { CaptureMode } from \"../state\";\nimport type { OverlayPhase } from \"../state\";\nimport { type FrameSettings } from \"../capture\";\nimport { fontBase, text } from \"../font\";\nimport { bg, fg, stroke, state, accent as accentToken, shadow } from \"../color\";\nimport { ScreenshotsPanel } from \"./screenshots-panel\";\n\n// --- Tooltip warmup: delay on first hover, instant while \"warm\" ---\nconst TOOLTIP_DELAY = 500; // ms before first tooltip appears\nconst TOOLTIP_COOLDOWN = 300; // ms after leaving before delay resets\n\nlet tooltipWarm = false;\nlet tooltipCooldownTimer: ReturnType<typeof setTimeout> | null = null;\n\nfunction useTooltipDelay(hovered: boolean) {\n const [visible, setVisible] = useState(false);\n const delayRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n useEffect(() => {\n if (!hovered) {\n setVisible(false);\n if (delayRef.current) { clearTimeout(delayRef.current); delayRef.current = null; }\n // Start cooldown — if no other tooltip opens, reset warmup\n if (tooltipCooldownTimer) clearTimeout(tooltipCooldownTimer);\n tooltipCooldownTimer = setTimeout(() => { tooltipWarm = false; }, TOOLTIP_COOLDOWN);\n return;\n }\n\n // Hovering\n if (tooltipCooldownTimer) { clearTimeout(tooltipCooldownTimer); tooltipCooldownTimer = null; }\n\n if (tooltipWarm) {\n setVisible(true);\n } else {\n delayRef.current = setTimeout(() => {\n tooltipWarm = true;\n setVisible(true);\n }, TOOLTIP_DELAY);\n }\n\n return () => { if (delayRef.current) { clearTimeout(delayRef.current); delayRef.current = null; } };\n }, [hovered]);\n\n return visible;\n}\n\ntype Corner = \"bottom-right\" | \"bottom-left\" | \"top-right\" | \"top-left\";\nconst EDGE_MARGIN = 24;\nconst CONTAINER_SIZE = 38;\n\nfunction getCornerStyle(corner: Corner): React.CSSProperties {\n switch (corner) {\n case \"bottom-right\":\n return { bottom: EDGE_MARGIN, right: EDGE_MARGIN };\n case \"bottom-left\":\n return { bottom: EDGE_MARGIN, left: EDGE_MARGIN };\n case \"top-right\":\n return { top: EDGE_MARGIN, right: EDGE_MARGIN };\n case \"top-left\":\n return { top: EDGE_MARGIN, left: EDGE_MARGIN };\n }\n}\n\nfunction isBottomCorner(corner: Corner): boolean {\n return corner === \"bottom-right\" || corner === \"bottom-left\";\n}\n\nfunction isRightCorner(corner: Corner): boolean {\n return corner === \"bottom-right\" || corner === \"top-right\";\n}\n\nfunction snapToCorner(x: number, y: number): Corner {\n const cx = window.innerWidth / 2;\n const cy = window.innerHeight / 2;\n if (x < cx) {\n return y < cy ? \"top-left\" : \"bottom-left\";\n }\n return y < cy ? \"top-right\" : \"bottom-right\";\n}\n\nfunction getCornerPosition(corner: Corner, w: number, h: number): { x: number; y: number } {\n const vw = window.innerWidth;\n const vh = window.innerHeight;\n switch (corner) {\n case \"bottom-right\":\n return { x: vw - EDGE_MARGIN - w, y: vh - EDGE_MARGIN - h };\n case \"bottom-left\":\n return { x: EDGE_MARGIN, y: vh - EDGE_MARGIN - h };\n case \"top-right\":\n return { x: vw - EDGE_MARGIN - w, y: EDGE_MARGIN };\n case \"top-left\":\n return { x: EDGE_MARGIN, y: EDGE_MARGIN };\n }\n}\n\ninterface ToolbarProps {\n expanded: boolean;\n onToggle: () => void;\n phase: OverlayPhase;\n loading: boolean;\n selectedMode: CaptureMode;\n onModeChange: (mode: CaptureMode) => void;\n onCapture: (mode: CaptureMode) => void;\n onCancel: () => void;\n frameSettings: FrameSettings;\n onFrameSettingsChange: (settings: FrameSettings) => void;\n}\n\nconst MODES: { mode: CaptureMode; label: string; icon: React.ComponentType<{ size?: number; strokeWidth?: number }> }[] = [\n { mode: \"component\", label: \"Component\", icon: Camera },\n { mode: \"viewport\", label: \"Viewport\", icon: Monitor },\n { mode: \"fullpage\", label: \"Full Page\", icon: FileText },\n];\n\nexport function Toolbar({\n expanded,\n onToggle,\n phase,\n loading,\n selectedMode,\n onModeChange,\n onCapture,\n onCancel,\n frameSettings,\n onFrameSettingsChange,\n}: ToolbarProps) {\n const [historyOpen, setHistoryOpen] = useState(false);\n const [modesExpanded, setModesExpanded] = useState(false);\n\n // Auto-open screenshots panel after capture\n useEffect(() => {\n if (phase === \"ready\") {\n try {\n if (localStorage.getItem(\"ab-auto-open-panel\") !== \"false\") {\n setHistoryOpen(true);\n }\n } catch {}\n }\n }, [phase]);\n\n // Animate toolbar expand/collapse\n const [buttonsVisible, setButtonsVisible] = useState(expanded);\n const [animIn, setAnimIn] = useState(expanded);\n const [animDone, setAnimDone] = useState(expanded);\n\n useEffect(() => {\n if (expanded) {\n setAnimDone(false);\n setButtonsVisible(true);\n setAnimIn(false);\n requestAnimationFrame(() => {\n requestAnimationFrame(() => setAnimIn(true));\n });\n const timer = setTimeout(() => setAnimDone(true), 250);\n return () => clearTimeout(timer);\n } else if (buttonsVisible) {\n setHistoryOpen(false);\n setAnimDone(false);\n setAnimIn(false);\n const timer = setTimeout(() => setButtonsVisible(false), 150);\n return () => clearTimeout(timer);\n }\n }, [expanded]);\n const [corner, setCorner] = useState<Corner>(() => {\n try {\n const stored = localStorage.getItem(\"ab-toolbar-corner\");\n if (stored && [\"bottom-right\", \"bottom-left\", \"top-right\", \"top-left\"].includes(stored)) {\n return stored as Corner;\n }\n } catch {}\n return \"bottom-right\";\n });\n\n // Drag state\n const [dragging, setDragging] = useState(false);\n const [dragPos, setDragPos] = useState<{ x: number; y: number } | null>(null);\n const [snapAnim, setSnapAnim] = useState<{ x: number; y: number; animate: boolean } | null>(null);\n const dragState = useRef<{\n dragging: boolean;\n startX: number;\n startY: number;\n origX: number;\n origY: number;\n distance: number;\n } | null>(null);\n const toolbarRef = useRef<HTMLDivElement>(null);\n\n // Camera button hover\n const [cameraHovered, setCameraHovered] = useState(false);\n const cameraTooltipVisible = useTooltipDelay(cameraHovered && !!expanded);\n\n useEffect(() => {\n if (!expanded) return;\n const onKey = (e: KeyboardEvent) => {\n if ((e.target as HTMLElement)?.tagName === \"INPUT\") {\n if (e.key === \"Escape\") {\n (e.target as HTMLElement).blur();\n }\n return;\n }\n\n if (e.key === \"Escape\") {\n if (historyOpen) {\n setHistoryOpen(false);\n return;\n }\n onCancel();\n } else if (e.key === \"Enter\") {\n onCapture(selectedMode);\n }\n };\n\n document.addEventListener(\"keydown\", onKey);\n return () => document.removeEventListener(\"keydown\", onKey);\n }, [expanded, onCancel, onCapture, selectedMode, historyOpen]);\n\n // Drag handlers\n const handleMouseDown = useCallback(\n (e: React.MouseEvent) => {\n e.preventDefault();\n const el = toolbarRef.current;\n if (!el) return;\n const rect = el.getBoundingClientRect();\n setDragging(true);\n setDragPos({ x: rect.left, y: rect.top });\n dragState.current = {\n dragging: true,\n startX: e.clientX,\n startY: e.clientY,\n origX: rect.left,\n origY: rect.top,\n distance: 0,\n };\n },\n [],\n );\n\n useEffect(() => {\n const handleMouseMove = (e: MouseEvent) => {\n const ds = dragState.current;\n if (!ds || !ds.dragging) return;\n\n const dx = e.clientX - ds.startX;\n const dy = e.clientY - ds.startY;\n ds.distance = Math.sqrt(dx * dx + dy * dy);\n\n setDragPos({\n x: ds.origX + dx,\n y: ds.origY + dy,\n });\n };\n\n const handleMouseUp = (e: MouseEvent) => {\n const ds = dragState.current;\n if (!ds) return;\n\n if (ds.distance < 5) {\n onToggle();\n setDragging(false);\n setDragPos(null);\n dragState.current = null;\n } else {\n // Snap to nearest corner based on toolbar center\n const el = toolbarRef.current;\n const w = el?.offsetWidth ?? CONTAINER_SIZE;\n const h = el?.offsetHeight ?? CONTAINER_SIZE;\n const currentX = ds.origX + (e.clientX - ds.startX);\n const currentY = ds.origY + (e.clientY - ds.startY);\n const centerX = currentX + w / 2;\n const centerY = currentY + h / 2;\n const newCorner = snapToCorner(centerX, centerY);\n setCorner(newCorner);\n try {\n localStorage.setItem(\"ab-toolbar-corner\", newCorner);\n } catch {}\n\n // Animate snap: first render at current position, then transition to target\n const targetPos = getCornerPosition(newCorner, w, h);\n setDragging(false);\n setDragPos(null);\n setSnapAnim({ x: currentX, y: currentY, animate: false });\n dragState.current = null;\n\n requestAnimationFrame(() => {\n requestAnimationFrame(() => {\n setSnapAnim({ ...targetPos, animate: true });\n setTimeout(() => setSnapAnim(null), 300);\n });\n });\n }\n };\n\n window.addEventListener(\"mousemove\", handleMouseMove);\n window.addEventListener(\"mouseup\", handleMouseUp);\n return () => {\n window.removeEventListener(\"mousemove\", handleMouseMove);\n window.removeEventListener(\"mouseup\", handleMouseUp);\n };\n }, [onToggle]);\n\n const panelSide: \"left\" | \"right\" = isRightCorner(corner) ? \"left\" : \"right\";\n const tooltipSide: \"left\" | \"right\" = panelSide;\n const bottom = isBottomCorner(corner);\n\n // Build position style\n const positionStyle: React.CSSProperties = dragging && dragPos\n ? { left: dragPos.x, top: dragPos.y }\n : snapAnim\n ? {\n left: snapAnim.x,\n top: snapAnim.y,\n ...(snapAnim.animate && {\n transition: \"left 0.3s cubic-bezier(0.23, 1, 0.32, 1), top 0.3s cubic-bezier(0.23, 1, 0.32, 1)\",\n }),\n }\n : getCornerStyle(corner);\n\n const cameraTooltipLabel = expanded ? \"Close\" : undefined;\n const cameraTooltipStyle: React.CSSProperties | undefined = cameraTooltipLabel\n ? tooltipSide === \"left\"\n ? { right: \"calc(100% + 10px)\", top: \"50%\", transform: \"translateY(-50%)\" }\n : { left: \"calc(100% + 10px)\", top: \"50%\", transform: \"translateY(-50%)\" }\n : undefined;\n\n const cameraButton = (\n <div style={{ position: \"relative\" }}>\n {cameraTooltipLabel && cameraTooltipVisible && !dragging && (\n <div\n style={{\n position: \"absolute\",\n ...cameraTooltipStyle,\n background: bg.base,\n border: `1px solid ${stroke.default}`,\n borderRadius: 6,\n padding: \"0 8px\",\n height: 24,\n display: \"flex\",\n alignItems: \"center\",\n color: fg.strong,\n ...text.label.xs,\n whiteSpace: \"nowrap\",\n boxShadow: shadow.tooltip,\n pointerEvents: \"none\",\n }}\n >\n {cameraTooltipLabel}\n </div>\n )}\n <div\n onMouseDown={handleMouseDown}\n onMouseEnter={() => setCameraHovered(true)}\n onMouseLeave={() => setCameraHovered(false)}\n style={{\n width: 32,\n height: 32,\n padding: 0,\n borderRadius: \"50%\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n cursor: dragging ? \"grabbing\" : \"pointer\",\n background: expanded && cameraHovered ? state.hoverStrong : \"transparent\",\n transition: \"background 0.12s ease\",\n }}\n >\n <style\n dangerouslySetInnerHTML={{\n __html: `\n@keyframes ab-spin {\n 0% { transform: rotate(0deg); }\n 100% { transform: rotate(360deg); }\n}\n@keyframes ab-panel-in {\n from { opacity: 0; transform: translateY(4px); }\n to { opacity: 1; transform: translateY(0); }\n}\n`,\n }}\n />\n {loading ? (\n <LoaderCircle\n size={16}\n strokeWidth={2}\n style={{ animation: \"ab-spin 0.8s linear infinite\", color: \"white\" }}\n />\n ) : phase === \"ready\" ? (\n <Check size={18} strokeWidth={1.7} color={fg.default} />\n ) : expanded ? (\n <X\n size={18}\n strokeWidth={1.7}\n color={cameraHovered ? fg.strong : fg.default}\n />\n ) : (\n <Camera\n size={18}\n strokeWidth={1.7}\n color={cameraHovered ? fg.strong : fg.default}\n />\n )}\n </div>\n </div>\n );\n\n const toolbarButtons = buttonsVisible ? (\n <div\n style={{\n overflow: animDone ? \"visible\" : \"hidden\",\n maxHeight: animIn ? 195 : 0,\n transition: animIn\n ? \"max-height 250ms cubic-bezier(0.23, 1, 0.32, 1)\"\n : \"max-height 150ms cubic-bezier(0.23, 1, 0.32, 1)\",\n }}\n >\n <div\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n opacity: animIn ? 1 : 0,\n transform: animIn ? \"translateY(0)\" : `translateY(${bottom ? 6 : -6}px)`,\n transition: animIn\n ? \"opacity 200ms cubic-bezier(0.23, 1, 0.32, 1), transform 200ms cubic-bezier(0.23, 1, 0.32, 1)\"\n : \"opacity 150ms cubic-bezier(0.23, 1, 0.32, 1), transform 150ms cubic-bezier(0.23, 1, 0.32, 1)\",\n willChange: \"transform, opacity\",\n }}\n >\n <div style={{ paddingBottom: 2 }}>\n <IconButton\n active={selectedMode === \"component\" && !historyOpen}\n tooltipSide={tooltipSide}\n tooltip=\"Component\"\n onClick={() => {\n\n setHistoryOpen(false);\n onModeChange(\"component\");\n }}\n >\n <Camera size={18} strokeWidth={1.7} />\n </IconButton>\n </div>\n\n <ScreenshotsPanel\n open={historyOpen}\n onClick={() => {\n setHistoryOpen((prev) => !prev);\n }}\n selectedMode={selectedMode}\n frameSettings={frameSettings}\n onFrameSettingsChange={onFrameSettingsChange}\n tooltipSide={tooltipSide}\n />\n </div>\n </div>\n ) : null;\n\n return (\n <div\n ref={toolbarRef}\n data-afterbefore=\"true\"\n style={{\n position: \"fixed\",\n ...positionStyle,\n zIndex: 2147483647,\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n background: bg.base,\n borderRadius: 999,\n padding: 6,\n boxShadow: shadow.toolbar,\n ...fontBase,\n userSelect: \"none\",\n }}\n >\n {bottom ? (\n <>\n {toolbarButtons}\n {cameraButton}\n </>\n ) : (\n <>\n {cameraButton}\n {toolbarButtons}\n </>\n )}\n </div>\n );\n}\n\nexport function IconButton({\n children,\n active,\n tooltip,\n tooltipSide = \"left\",\n onClick,\n}: {\n children: React.ReactNode;\n active?: boolean;\n tooltip?: string;\n tooltipSide?: \"left\" | \"right\";\n onClick: () => void;\n}) {\n const [hovered, setHovered] = useState(false);\n const tooltipVisible = useTooltipDelay(hovered && !!tooltip);\n\n const tooltipStyle: React.CSSProperties = tooltipSide === \"left\"\n ? {\n right: \"calc(100% + 10px)\",\n top: \"50%\",\n transform: \"translateY(-50%)\",\n }\n : {\n left: \"calc(100% + 10px)\",\n top: \"50%\",\n transform: \"translateY(-50%)\",\n };\n\n return (\n <div style={{ position: \"relative\" }}>\n {tooltip && tooltipVisible && (\n <div\n style={{\n position: \"absolute\",\n ...tooltipStyle,\n background: bg.base,\n border: `1px solid ${stroke.default}`,\n borderRadius: 6,\n padding: \"0 8px\",\n height: 24,\n display: \"flex\",\n alignItems: \"center\",\n color: fg.strong,\n ...text.label.xs,\n whiteSpace: \"nowrap\",\n boxShadow: shadow.tooltip,\n pointerEvents: \"none\",\n }}\n >\n {tooltip}\n </div>\n )}\n\n <button\n onClick={onClick}\n onMouseEnter={() => setHovered(true)}\n onMouseLeave={() => setHovered(false)}\n style={{\n width: 32,\n height: 32,\n borderRadius: \"50%\",\n border: \"none\",\n background: active || hovered\n ? state.hoverStrong\n : \"transparent\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n cursor: \"pointer\",\n padding: 0,\n color: active || hovered\n ? fg.strong\n : fg.default,\n transition: \"background 0.12s ease, color 0.12s ease\",\n }}\n >\n {children}\n </button>\n </div>\n );\n}\n\n\n\n\n\nexport function DropItem({\n children,\n onClick,\n active,\n accent,\n}: {\n children: React.ReactNode;\n onClick: () => void;\n active?: boolean;\n accent?: boolean;\n}) {\n return (\n <button\n onClick={onClick}\n style={{\n display: \"block\",\n width: \"100%\",\n padding: \"7px 12px\",\n background: active ? state.active : \"transparent\",\n border: \"none\",\n color: accent\n ? accentToken.highlight\n : fg.strong,\n textAlign: \"left\",\n cursor: \"pointer\",\n ...text.paragraph.sm,\n fontFamily: \"inherit\",\n }}\n >\n {children}\n </button>\n );\n}\n\nexport function Separator({\n vertical = true,\n onClick,\n}: {\n vertical?: boolean;\n onClick?: () => void;\n}) {\n return (\n <div\n onClick={onClick}\n style={{\n position: \"relative\",\n width: vertical ? 1 : 24,\n height: vertical ? 18 : 1,\n background: stroke.strong,\n flexShrink: 0,\n margin: vertical ? \"0 6px\" : \"6px 0\",\n cursor: onClick ? \"pointer\" : undefined,\n }}\n >\n {onClick && (\n <div style={{ position: \"absolute\", inset: vertical ? \"0 -8px\" : \"-8px 0\" }} />\n )}\n </div>\n );\n}\n\n\n\nexport function FilterDropdown({\n label,\n value,\n options,\n isOpen,\n onToggle,\n onSelect,\n}: {\n label: string;\n value: string | null;\n options: string[];\n isOpen: boolean;\n onToggle: () => void;\n onSelect: (value: string) => void;\n}) {\n return (\n <div>\n <div\n style={{\n ...text.label.xs,\n color: fg.sub,\n marginBottom: 3,\n }}\n >\n {label}\n </div>\n <div style={{ position: \"relative\" }}>\n <button\n onClick={onToggle}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n gap: 6,\n width: \"100%\",\n height: 30,\n padding: \"0 8px\",\n borderRadius: 7,\n border: `1px solid ${stroke.default}`,\n background: state.input,\n color: fg.strong,\n cursor: \"pointer\",\n ...text.label.xs,\n fontFamily: \"inherit\",\n }}\n >\n <span\n style={{\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n }}\n >\n {value || \"\\u2014\"}\n </span>\n <ChevronDown size={12} strokeWidth={2} />\n </button>\n\n {isOpen && options.length > 0 && (\n <div\n style={{\n position: \"absolute\",\n top: \"calc(100% + 4px)\",\n left: 0,\n right: 0,\n maxHeight: 160,\n overflowY: \"auto\",\n background: bg.base,\n border: `1px solid ${stroke.default}`,\n borderRadius: 8,\n padding: \"4px 0\",\n boxShadow: shadow.dropdown,\n zIndex: 1,\n }}\n >\n {options.map((opt) => (\n <DropItem\n key={opt}\n active={opt === value}\n onClick={() => onSelect(opt)}\n >\n {opt}\n </DropItem>\n ))}\n </div>\n )}\n </div>\n </div>\n );\n}\n\nexport function ActionButton({\n children,\n onClick,\n disabled,\n}: {\n children: React.ReactNode;\n onClick: () => void;\n disabled?: boolean;\n}) {\n const [hovered, setHovered] = useState(false);\n\n return (\n <button\n onClick={onClick}\n disabled={disabled}\n onMouseEnter={() => setHovered(true)}\n onMouseLeave={() => setHovered(false)}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 6,\n width: \"100%\",\n padding: \"6px 8px\",\n border: \"none\",\n background: hovered ? state.active : \"transparent\",\n color: fg.default,\n ...text.label.xs,\n borderRadius: 6,\n cursor: disabled ? \"wait\" : \"pointer\",\n textAlign: \"left\" as const,\n fontFamily: \"inherit\",\n transition: \"background 0.1s ease\",\n }}\n >\n {children}\n </button>\n );\n}\n\n","// ---------------------------------------------------------------------------\n// Align UI — Neutral Gray palette + dark-theme semantic tokens\n// ---------------------------------------------------------------------------\n\nexport const gray = {\n 950: \"oklch(0.162 0 0)\",\n 900: \"oklch(0.195 0 0)\",\n 800: \"oklch(0.254 0 0)\",\n 700: \"oklch(0.302 0 0)\",\n 600: \"oklch(0.348 0 0)\",\n 500: \"oklch(0.396 0 0)\",\n 400: \"oklch(0.459 0 0)\",\n 300: \"oklch(0.549 0 0)\",\n 200: \"oklch(0.649 0 0)\",\n 100: \"oklch(0.72 0 0)\",\n 50: \"oklch(0.863 0 0)\",\n 0: \"oklch(0.933 0 0)\",\n} as const;\n\n// --- Surfaces ---\n\nexport const bg = {\n base: gray[900],\n elevated: gray[950],\n dropdown: gray[900],\n} as const;\n\n// --- Foreground (text / icons) ---\n\nexport const fg = {\n strong: gray[200], // ~5.6:1 — headings, input values\n default: \"oklch(0.6 0 0)\", // ~4.6:1 — body text, interactive labels (AA)\n sub: gray[300], // ~3.8:1 — secondary labels, icons\n muted: \"oklch(0.5 0 0)\", // ~3:1 — inline labels, decorative\n faint: gray[500], // ~2:1 — non-essential hints only\n} as const;\n\n// --- Stroke / borders ---\n\nexport const stroke = {\n soft: \"rgba(255, 255, 255, 0.08)\",\n default: \"rgba(255, 255, 255, 0.1)\",\n strong: \"rgba(255, 255, 255, 0.12)\",\n interactive: \"rgba(255, 255, 255, 0.18)\",\n} as const;\n\n// --- Interactive state backgrounds ---\n\nexport const state = {\n subtle: \"rgba(255, 255, 255, 0.04)\",\n button: \"rgba(255, 255, 255, 0.06)\",\n input: \"rgba(255, 255, 255, 0.07)\",\n active: \"rgba(255, 255, 255, 0.08)\",\n hover: \"rgba(255, 255, 255, 0.1)\",\n hoverStrong: \"rgba(255, 255, 255, 0.12)\",\n pressed: \"rgba(255, 255, 255, 0.14)\",\n} as const;\n\n// --- Accent ---\n\nexport const accent = {\n primary: \"#335CFF\",\n toggle: \"#38bdf8\",\n check: \"#4ade80\",\n highlight: \"rgba(125, 211, 252, 0.96)\",\n} as const;\n\n// --- Feedback ---\n\nexport const feedback = {\n success: \"rgba(34, 197, 94, 0.9)\",\n error: \"rgba(239, 68, 68, 0.9)\",\n errorText: \"rgba(239, 68, 68, 0.9)\",\n errorBg: \"rgba(239, 68, 68, 0.1)\",\n} as const;\n\n// --- Shadows ---\n\nexport const shadow = {\n toolbar: \"0 8px 32px rgba(0, 0, 0, 0.4)\",\n panel: \"0 14px 36px rgba(0, 0, 0, 0.32)\",\n dropdown: \"0 10px 30px rgba(0, 0, 0, 0.3)\",\n tooltip: \"0 8px 28px rgba(0, 0, 0, 0.28)\",\n toast: \"0 2px 8px rgba(0, 0, 0, 0.3)\",\n status: \"0 4px 20px rgba(0, 0, 0, 0.4), 0 0 0 1px rgba(255, 255, 255, 0.08)\",\n} as const;\n","\"use client\";\n\nimport React, { useCallback, useEffect, useState } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport {\n Trash2,\n X,\n} from \"lucide-react\";\nimport { Image as ImageIcon } from \"lucide-react\";\nimport type { CaptureMode } from \"../state\";\nimport { renderFrame, renderAfterbeforeFrame, type FrameSettings } from \"../capture\";\nimport { fontBase, text } from \"../font\";\nimport { bg, fg, stroke, state, accent as accentToken, feedback, shadow } from \"../color\";\nimport { SettingsContent } from \"./settings-panel\";\nimport { IconButton, FilterDropdown } from \"./toolbar\";\n\ninterface ScreenshotMeta {\n filename: string;\n timestamp: string;\n}\n\nfunction BrowserChromeBar({ theme, url = \"localhost\", scale = 1 }: { theme: \"light\" | \"dark\"; url?: string; scale?: number }) {\n const s = scale;\n const colors =\n theme === \"dark\"\n ? { titleBar: \"#1C1C1C\", urlBar: \"#262626\", text: \"#7B7B7B\", border: \"#333333\" }\n : { titleBar: \"#F5F5F5\", urlBar: \"#FFFFFF\", text: \"#999999\", border: \"#EBEBEB\" };\n\n return (\n <div style={{ background: colors.titleBar, flexShrink: 0, padding: `${4 * s}px ${6 * s}px` }}>\n <div style={{ display: \"flex\", alignItems: \"center\", gap: 6 * s, height: 14 * s }}>\n <div style={{ display: \"flex\", gap: 5 * s, flexShrink: 0 }}>\n {[\"#FF5F57\", \"#FEBC2E\", \"#28C840\"].map((c) => (\n <div key={c} style={{ width: 6 * s, height: 6 * s, borderRadius: \"50%\", background: c }} />\n ))}\n </div>\n <div\n style={{\n flex: 1,\n height: 14 * s,\n background: colors.urlBar,\n borderRadius: 3 * s,\n display: \"flex\",\n alignItems: \"center\",\n paddingLeft: 6 * s,\n ...(theme === \"light\" ? { border: `1px solid ${colors.border}` } : {}),\n boxSizing: \"border-box\" as const,\n }}\n >\n <span\n style={{\n fontSize: 7 * s,\n lineHeight: 1,\n color: colors.text,\n fontFamily: '-apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif',\n }}\n >\n {url}\n </span>\n </div>\n </div>\n </div>\n );\n}\n\nfunction FramePreview({\n componentUrl,\n viewportUrl,\n frameSettings,\n loading,\n afterbeforeMode,\n beforeUrl,\n afterUrl,\n activeSlot: activeSlotProp,\n onSlotClick,\n}: {\n componentUrl: string | null;\n viewportUrl: string | null;\n frameSettings: FrameSettings;\n loading: boolean;\n afterbeforeMode?: boolean;\n beforeUrl?: string | null;\n afterUrl?: string | null;\n activeSlot?: \"before\" | \"after\";\n onSlotClick?: (slot: \"before\" | \"after\") => void;\n}) {\n const { enabled: frameEnabled, browserChrome, browserTheme, browserUrl, browserShadow = 50, browserRadius = 8, size, bgType, bgColor, bgGradient, bgImage, padding } = frameSettings;\n const [viewportAvailable, setViewportAvailable] = useState(true);\n\n // Reset viewport availability when file changes\n useEffect(() => { setViewportAvailable(true); }, [componentUrl]);\n\n const previewUrl = browserChrome && viewportUrl && viewportAvailable\n ? viewportUrl\n : componentUrl;\n\n const aspectRatio = frameEnabled ? `${size.w} / ${size.h}` : \"16 / 10\";\n\n const outerBg: React.CSSProperties = frameEnabled\n ? bgType === \"image\" && bgImage\n ? { backgroundImage: `url(${bgImage})`, backgroundSize: \"cover\", backgroundPosition: \"center\" }\n : bgType === \"gradient\"\n ? { background: bgGradient }\n : { background: bgColor }\n : { background: bg.elevated };\n\n const emptyState = (\n <span style={{ ...text.paragraph.xs, color: fg.sub }}>\n {loading ? \"Loading...\" : \"No screenshots yet\"}\n </span>\n );\n\n const imageStyle: React.CSSProperties = { maxWidth: \"100%\", maxHeight: \"100%\", objectFit: \"contain\" as const, display: \"block\" };\n\n const imageEl = previewUrl ? (\n <img\n src={previewUrl}\n alt=\"\"\n onError={() => {\n if (browserChrome && viewportUrl && viewportAvailable) {\n setViewportAvailable(false);\n }\n }}\n style={imageStyle}\n />\n ) : null;\n\n // Padding for non-chrome mode (applied to outer container)\n const padStyle = frameEnabled && !browserChrome ? `${(padding / size.h) * 100}%` : undefined;\n\n // For chrome mode: scale factor so the browser window + chrome bar shrink together with padding\n const chromeScale = frameEnabled ? Math.max(0.3, (size.w - padding * 2) / size.w) : 1;\n const chromeWidthPct = frameEnabled ? `${chromeScale * 100}%` : \"100%\";\n const chromePadY = frameEnabled ? `${(padding / size.w) * 100}%` : undefined;\n\n // Shadow for browser window\n const shadowAlpha = (browserShadow / 100) * 0.6;\n const shadowBlur = (browserShadow / 100) * 40;\n const shadowY = (browserShadow / 100) * 8;\n const browserBoxShadow = browserChrome && browserShadow > 0\n ? `0 ${shadowY}px ${shadowBlur}px rgba(0, 0, 0, ${shadowAlpha})`\n : \"none\";\n\n if (afterbeforeMode) {\n return (\n <div\n style={{\n width: \"100%\",\n aspectRatio: \"1920 / 1080\",\n borderRadius: 10,\n overflow: \"hidden\",\n border: `1px solid ${stroke.soft}`,\n marginBottom: 10,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n gap: \"2%\",\n padding: \"5%\",\n ...outerBg,\n }}\n >\n {([\"before\", \"after\"] as const).map((slot) => {\n const url = slot === \"before\" ? beforeUrl : afterUrl;\n const isActive = activeSlotProp === slot;\n return (\n <div\n key={slot}\n onClick={() => onSlotClick?.(slot)}\n style={{\n flex: 1,\n display: \"flex\",\n flexDirection: \"column\" as const,\n alignItems: \"center\",\n gap: 8,\n cursor: \"pointer\",\n }}\n >\n <div\n style={{\n width: \"100%\",\n aspectRatio: \"16 / 10\",\n borderRadius: 6,\n border: isActive\n ? `2px solid ${accentToken.highlight}`\n : url\n ? `1px solid ${stroke.soft}`\n : `2px dashed ${stroke.interactive}`,\n overflow: \"hidden\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n background: \"rgba(0, 0, 0, 0.1)\",\n transition: \"border-color 0.12s ease\",\n }}\n >\n {url ? (\n <img src={url} alt=\"\" style={{ width: \"100%\", height: \"100%\", objectFit: \"cover\", display: \"block\" }} />\n ) : (\n <span style={{ ...text.paragraph.xs, color: fg.muted }}>\n Click to assign\n </span>\n )}\n </div>\n <span style={{ ...text.label.xs, color: fg.sub }}>\n {slot === \"before\" ? \"Before\" : \"After\"}\n </span>\n </div>\n );\n })}\n </div>\n );\n }\n\n return (\n <div\n style={{\n width: \"100%\",\n aspectRatio,\n borderRadius: 10,\n overflow: \"hidden\",\n border: `1px solid ${stroke.soft}`,\n marginBottom: 10,\n display: \"flex\",\n flexDirection: \"column\" as const,\n ...outerBg,\n ...(padStyle ? { padding: padStyle } : {}),\n }}\n >\n {browserChrome ? (\n <div\n style={{\n display: \"flex\",\n flexDirection: \"column\" as const,\n alignItems: \"center\",\n justifyContent: \"center\",\n flex: 1,\n minHeight: 0,\n }}\n >\n <div style={{ width: chromeWidthPct, display: \"flex\", flexDirection: \"column\" as const, borderRadius: browserRadius * chromeScale, overflow: \"hidden\", boxShadow: browserBoxShadow }}>\n <BrowserChromeBar theme={browserTheme} url={browserUrl} scale={chromeScale} />\n <div style={{ display: \"flex\", alignItems: \"center\", justifyContent: \"center\" }}>\n {imageEl || emptyState}\n </div>\n </div>\n </div>\n ) : (\n <div\n style={{\n flex: 1,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n minHeight: 0,\n }}\n >\n {imageEl || emptyState}\n </div>\n )}\n </div>\n );\n}\n\nfunction formatTimestamp(filename: string): string {\n const iso = filename\n .replace(/\\.png$/, \"\")\n .replace(/T(\\d{2})-(\\d{2})-(\\d{2})-(\\d+)Z$/, \"T$1:$2:$3.$4Z\");\n const date = new Date(iso);\n if (Number.isNaN(date.getTime())) return filename.replace(/\\.png$/, \"\");\n\n const now = new Date();\n const diffMs = now.getTime() - date.getTime();\n const diffMin = Math.floor(diffMs / 60000);\n\n if (diffMin < 1) return \"Just now\";\n if (diffMin < 60) return `${diffMin}m ago`;\n const diffHr = Math.floor(diffMin / 60);\n if (diffHr < 24) return `${diffHr}h ago`;\n\n return date.toLocaleDateString(undefined, { month: \"short\", day: \"numeric\", hour: \"2-digit\", minute: \"2-digit\" });\n}\n\nexport function ScreenshotsPanel({\n open,\n onClick,\n selectedMode,\n frameSettings,\n onFrameSettingsChange,\n tooltipSide,\n}: {\n open: boolean;\n onClick: () => void;\n selectedMode: CaptureMode;\n frameSettings: FrameSettings;\n onFrameSettingsChange: (settings: FrameSettings) => void;\n tooltipSide: \"left\" | \"right\";\n}) {\n const [toast, setToast] = useState<{ message: string; type: \"success\" | \"error\" } | null>(null);\n const [saveDir, setSaveDir] = useState<string | null>(null);\n const [picking, setPicking] = useState(false);\n\n const [repos, setRepos] = useState<string[]>([]);\n const [branches, setBranches] = useState<string[]>([]);\n const [screenshots, setScreenshots] = useState<ScreenshotMeta[]>([]);\n const [selectedRepo, setSelectedRepo] = useState<string | null>(null);\n const [selectedBranch, setSelectedBranch] = useState<string | null>(null);\n const [loading, setLoading] = useState(false);\n const [repoDropOpen, setRepoDropOpen] = useState(false);\n const [branchDropOpen, setBranchDropOpen] = useState(false);\n const [editingFile, setEditingFile] = useState<string | null>(null);\n const [editValue, setEditValue] = useState(\"\");\n const [selectedFile, setSelectedFile] = useState<string | null>(null);\n\n // Afterbefore comparison state\n const [beforeFile, setBeforeFile] = useState<string | null>(null);\n const [afterFile, setAfterFile] = useState<string | null>(null);\n const [activeSlot, setActiveSlot] = useState<\"before\" | \"after\">(\"before\");\n\n // Reset comparison state when mode is toggled off\n useEffect(() => {\n if (!frameSettings.afterbefore) {\n setBeforeFile(null);\n setAfterFile(null);\n setActiveSlot(\"before\");\n }\n }, [frameSettings.afterbefore]);\n\n useEffect(() => {\n if (!open) return;\n fetch(\"/__afterbefore/config\")\n .then((r) => r.json())\n .then((data) => setSaveDir(data.saveDir))\n .catch(() => {});\n }, [open]);\n\n const handlePickFolder = async () => {\n setPicking(true);\n try {\n const res = await fetch(\"/__afterbefore/pick-folder\", { method: \"POST\" });\n const data = await res.json();\n if (data.folder) {\n await fetch(\"/__afterbefore/config\", {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ saveDir: data.folder }),\n });\n setSaveDir(data.folder);\n }\n } catch {\n // noop\n } finally {\n setPicking(false);\n }\n };\n\n const shortDir = saveDir\n ? saveDir.replace(/^\\/Users\\/[^/]+\\//, \"\")\n : \"Desktop\";\n\n useEffect(() => {\n if (!open) {\n setRepoDropOpen(false);\n setBranchDropOpen(false);\n return;\n }\n setLoading(true);\n const params = new URLSearchParams();\n if (selectedRepo) params.set(\"repo\", selectedRepo);\n if (selectedBranch) params.set(\"branch\", selectedBranch);\n fetch(`/__afterbefore/history?${params}`)\n .then((r) => r.json())\n .then((data) => {\n setRepos(data.repos || []);\n setBranches(data.branches || []);\n const shots: ScreenshotMeta[] = data.screenshots || [];\n setScreenshots(shots);\n if (shots.length > 0) {\n setSelectedFile((prev) =>\n prev && shots.some((s) => s.filename === prev) ? prev : shots[0].filename,\n );\n } else {\n setSelectedFile(null);\n }\n if (!selectedRepo && data.currentRepo) setSelectedRepo(data.currentRepo);\n if (!selectedBranch && data.currentBranch) setSelectedBranch(data.currentBranch);\n })\n .catch(() => {})\n .finally(() => setLoading(false));\n }, [open, selectedRepo, selectedBranch]);\n\n const showToast = useCallback((message: string, type: \"success\" | \"error\") => {\n setToast({ message, type });\n setTimeout(() => setToast(null), 3000);\n }, []);\n\n const handleRename = async (oldName: string, newName: string) => {\n if (!newName.trim() || newName.trim() === oldName.replace(/\\.png$/, \"\")) {\n setEditingFile(null);\n return;\n }\n try {\n const res = await fetch(\"/__afterbefore/history/rename\", {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n repo: selectedRepo,\n branch: selectedBranch,\n oldName,\n newName: newName.trim(),\n }),\n });\n if (!res.ok) throw new Error();\n const data = await res.json();\n setScreenshots((prev) =>\n prev.map((s) =>\n s.filename === oldName\n ? { ...s, filename: data.filename, timestamp: data.filename.replace(/\\.png$/, \"\") }\n : s,\n ),\n );\n if (selectedFile === oldName) setSelectedFile(data.filename);\n showToast(\"Renamed\", \"success\");\n } catch {\n showToast(\"Rename failed\", \"error\");\n }\n setEditingFile(null);\n };\n\n const handleDelete = async (filename: string) => {\n try {\n const res = await fetch(\"/__afterbefore/history/delete\", {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n repo: selectedRepo,\n branch: selectedBranch,\n file: filename,\n }),\n });\n if (!res.ok) throw new Error();\n setScreenshots((prev) => prev.filter((s) => s.filename !== filename));\n if (selectedFile === filename) {\n const remaining = screenshots.filter((s) => s.filename !== filename);\n setSelectedFile(remaining.length > 0 ? remaining[0].filename : null);\n }\n showToast(\"Deleted\", \"success\");\n } catch {\n showToast(\"Delete failed\", \"error\");\n }\n };\n\n\n const [saving, setSaving] = useState(false);\n\n const toDataUrl = async (url: string): Promise<string> => {\n const r = await fetch(url);\n if (!r.ok) throw new Error(\"Failed to load image\");\n const b = await r.blob();\n return new Promise<string>((resolve) => {\n const reader = new FileReader();\n reader.onloadend = () => resolve(reader.result as string);\n reader.readAsDataURL(b);\n });\n };\n\n const makeImageUrl = (file: string) =>\n `/__afterbefore/history/image?repo=${encodeURIComponent(selectedRepo || \"\")}&branch=${encodeURIComponent(selectedBranch || \"\")}&file=${encodeURIComponent(file)}`;\n\n const handleSave = async () => {\n if (saving) return;\n\n // Afterbefore comparison mode\n if (frameSettings.afterbefore) {\n if (!beforeFile || !afterFile) return;\n setSaving(true);\n try {\n const beforeDataUrl = await toDataUrl(makeImageUrl(beforeFile));\n const afterDataUrl = await toDataUrl(makeImageUrl(afterFile));\n const renderedDataUrl = await renderAfterbeforeFrame(beforeDataUrl, afterDataUrl, frameSettings);\n const saveRes = await fetch(\"/__afterbefore/save\", {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ mode: \"resave\", image: renderedDataUrl, rawImage: beforeDataUrl }),\n });\n if (!saveRes.ok) throw new Error(\"Save failed\");\n showToast(\"Saved to desktop\", \"success\");\n } catch {\n showToast(\"Save failed\", \"error\");\n } finally {\n setSaving(false);\n }\n return;\n }\n\n // Single image mode\n if (!selectedFile) return;\n setSaving(true);\n try {\n const baseUrl = makeImageUrl(selectedFile);\n const rawDataUrl = await toDataUrl(baseUrl);\n let primaryDataUrl = rawDataUrl;\n if (frameSettings.browserChrome) {\n try {\n primaryDataUrl = await toDataUrl(`${baseUrl}&variant=viewport`);\n } catch {\n // viewport variant may not exist, fall back to base\n }\n }\n const renderedDataUrl = await renderFrame(primaryDataUrl, frameSettings);\n const saveRes = await fetch(\"/__afterbefore/save\", {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ mode: \"resave\", image: renderedDataUrl, rawImage: rawDataUrl }),\n });\n if (!saveRes.ok) throw new Error(\"Save failed\");\n showToast(\"Saved to desktop\", \"success\");\n } catch {\n showToast(\"Save failed\", \"error\");\n } finally {\n setSaving(false);\n }\n };\n\n const baseImageUrl = selectedFile\n ? `/__afterbefore/history/image?repo=${encodeURIComponent(selectedRepo || \"\")}&branch=${encodeURIComponent(selectedBranch || \"\")}&file=${encodeURIComponent(selectedFile)}`\n : null;\n const viewportUrl = baseImageUrl ? `${baseImageUrl}&variant=viewport` : null;\n\n return (\n <>\n <IconButton active={open} tooltipSide={tooltipSide} tooltip={!open ? \"Screenshots\" : undefined} onClick={onClick}>\n <ImageIcon size={18} strokeWidth={1.7} />\n </IconButton>\n\n {open && createPortal(\n <div\n data-afterbefore=\"true\"\n onClick={onClick}\n style={{\n position: \"fixed\",\n inset: 0,\n zIndex: 2147483647,\n background: \"rgba(0, 0, 0, 0.45)\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n ...fontBase,\n }}\n >\n <style\n dangerouslySetInnerHTML={{\n __html: `\n@keyframes ab-panel-in {\n from { opacity: 0; transform: translateY(4px); }\n to { opacity: 1; transform: translateY(0); }\n}\n`,\n }}\n />\n <div\n onClick={(e) => e.stopPropagation()}\n style={{\n width: 900,\n height: \"60vh\",\n borderRadius: 14,\n background: bg.base,\n border: `1px solid ${stroke.default}`,\n boxShadow: shadow.panel,\n display: \"flex\",\n flexDirection: \"column\",\n overflow: \"hidden\",\n animation: \"ab-panel-in 150ms cubic-bezier(0.23, 1, 0.32, 1)\",\n }}\n >\n {/* Header */}\n <div style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n padding: \"16px 20px\",\n borderBottom: `1px solid ${stroke.soft}`,\n }}>\n <div>\n <div style={{ ...text.label.sm, color: fg.strong }}>Screenshots</div>\n <div style={{ ...text.paragraph.xs, color: fg.sub, marginTop: 2 }}>\n Capture history & settings\n </div>\n </div>\n <button\n onClick={onClick}\n style={{\n width: 28,\n height: 28,\n borderRadius: 7,\n border: \"none\",\n background: \"transparent\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n cursor: \"pointer\",\n color: fg.sub,\n padding: 0,\n transition: \"background 0.12s ease, color 0.12s ease\",\n }}\n onMouseEnter={(e) => {\n (e.currentTarget as HTMLButtonElement).style.background = state.hover;\n (e.currentTarget as HTMLButtonElement).style.color = fg.strong;\n }}\n onMouseLeave={(e) => {\n (e.currentTarget as HTMLButtonElement).style.background = \"transparent\";\n (e.currentTarget as HTMLButtonElement).style.color = fg.sub;\n }}\n >\n <X size={14} strokeWidth={2} />\n </button>\n </div>\n\n {/* Two-column body */}\n <div style={{ display: \"flex\", flex: 1, overflow: \"hidden\", minHeight: 0, position: \"relative\" }}>\n {/* Left column — preview & file management */}\n <div style={{ flex: 1, overflowY: \"auto\", padding: \"16px 20px 20px\", minHeight: 0, marginRight: 301 }}>\n <FramePreview\n componentUrl={baseImageUrl}\n viewportUrl={viewportUrl}\n frameSettings={frameSettings}\n loading={loading}\n afterbeforeMode={frameSettings.afterbefore}\n beforeUrl={beforeFile ? `/__afterbefore/history/image?repo=${encodeURIComponent(selectedRepo || \"\")}&branch=${encodeURIComponent(selectedBranch || \"\")}&file=${encodeURIComponent(beforeFile)}` : null}\n afterUrl={afterFile ? `/__afterbefore/history/image?repo=${encodeURIComponent(selectedRepo || \"\")}&branch=${encodeURIComponent(selectedBranch || \"\")}&file=${encodeURIComponent(afterFile)}` : null}\n activeSlot={activeSlot}\n onSlotClick={setActiveSlot}\n />\n\n {!frameSettings.afterbefore && selectedFile && !loading && (\n <div style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 8,\n marginBottom: 12,\n }}>\n <div style={{ flex: 1, minWidth: 0 }}>\n {editingFile === selectedFile ? (\n <input\n autoFocus\n value={editValue}\n onChange={(e) => setEditValue(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") handleRename(selectedFile, editValue);\n if (e.key === \"Escape\") setEditingFile(null);\n }}\n onBlur={() => handleRename(selectedFile, editValue)}\n style={{\n width: \"100%\",\n ...text.label.xs,\n color: fg.strong,\n background: state.hover,\n border: `1px solid ${stroke.interactive}`,\n borderRadius: 4,\n padding: \"2px 6px\",\n outline: \"none\",\n fontFamily: \"inherit\",\n }}\n />\n ) : (\n <div\n onClick={() => {\n setEditingFile(selectedFile);\n setEditValue(selectedFile.replace(/\\.png$/, \"\"));\n }}\n style={{\n ...text.label.xs,\n color: fg.strong,\n cursor: \"pointer\",\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n }}\n title=\"Click to rename\"\n >\n {formatTimestamp(selectedFile)}\n </div>\n )}\n </div>\n <button\n onClick={() => handleDelete(selectedFile)}\n title=\"Delete screenshot\"\n style={{\n flexShrink: 0,\n width: 28,\n height: 28,\n borderRadius: 6,\n border: \"none\",\n background: \"transparent\",\n color: fg.muted,\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n padding: 0,\n }}\n onMouseEnter={(e) => {\n (e.currentTarget as HTMLButtonElement).style.color = feedback.error;\n (e.currentTarget as HTMLButtonElement).style.background = feedback.errorBg;\n }}\n onMouseLeave={(e) => {\n (e.currentTarget as HTMLButtonElement).style.color = fg.muted;\n (e.currentTarget as HTMLButtonElement).style.background = \"transparent\";\n }}\n >\n <Trash2 size={14} strokeWidth={1.8} />\n </button>\n </div>\n )}\n\n {/* Filters */}\n <div style={{ display: \"flex\", gap: 10, marginBottom: 10 }}>\n <div style={{ flex: 1, position: \"relative\" }}>\n <FilterDropdown\n label=\"Project\"\n value={selectedRepo}\n options={repos}\n isOpen={repoDropOpen}\n onToggle={() => {\n setRepoDropOpen((p) => !p);\n setBranchDropOpen(false);\n }}\n onSelect={(repo) => {\n setSelectedRepo(repo);\n setSelectedBranch(null);\n setRepoDropOpen(false);\n }}\n />\n </div>\n <div style={{ flex: 1, position: \"relative\" }}>\n <FilterDropdown\n label=\"Branch\"\n value={selectedBranch}\n options={branches}\n isOpen={branchDropOpen}\n onToggle={() => {\n setBranchDropOpen((p) => !p);\n setRepoDropOpen(false);\n }}\n onSelect={(branch) => {\n setSelectedBranch(branch);\n setBranchDropOpen(false);\n }}\n />\n </div>\n </div>\n\n {/* Thumbnail strip */}\n {screenshots.length > 0 && (\n <div\n style={{\n display: \"flex\",\n gap: 6,\n overflowX: \"auto\",\n paddingBottom: 4,\n marginBottom: 10,\n }}\n >\n {screenshots.map((shot) => {\n const thumbUrl = `/__afterbefore/history/image?repo=${encodeURIComponent(selectedRepo || \"\")}&branch=${encodeURIComponent(selectedBranch || \"\")}&file=${encodeURIComponent(shot.filename)}`;\n const isSelected = frameSettings.afterbefore\n ? shot.filename === beforeFile || shot.filename === afterFile\n : selectedFile === shot.filename;\n const slotBadge = frameSettings.afterbefore\n ? shot.filename === beforeFile ? \"B\" : shot.filename === afterFile ? \"A\" : null\n : null;\n return (\n <div\n key={shot.filename}\n onClick={() => {\n if (frameSettings.afterbefore) {\n if (activeSlot === \"before\") {\n setBeforeFile(shot.filename);\n setActiveSlot(\"after\");\n } else {\n setAfterFile(shot.filename);\n }\n } else {\n setSelectedFile(shot.filename);\n }\n }}\n style={{\n position: \"relative\" as const,\n width: 64,\n height: 44,\n flexShrink: 0,\n borderRadius: 6,\n overflow: \"hidden\",\n cursor: \"pointer\",\n border: isSelected\n ? `2px solid ${accentToken.highlight}`\n : `1px solid ${stroke.soft}`,\n opacity: isSelected ? 1 : 0.7,\n transition: \"opacity 0.12s ease, border-color 0.12s ease\",\n }}\n >\n <img\n src={thumbUrl}\n alt=\"\"\n style={{\n width: \"100%\",\n height: \"100%\",\n objectFit: \"cover\",\n display: \"block\",\n }}\n />\n {slotBadge && (\n <div style={{\n position: \"absolute\",\n top: 2,\n left: 2,\n width: 16,\n height: 16,\n borderRadius: 4,\n background: accentToken.highlight,\n color: \"#fff\",\n fontSize: 9,\n fontWeight: 600,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n }}>\n {slotBadge}\n </div>\n )}\n </div>\n );\n })}\n </div>\n )}\n\n </div>\n\n {/* Vertical divider + Right column — absolutely positioned so content doesn't grow parent */}\n <div style={{ position: \"absolute\", top: 0, right: 0, bottom: 0, width: 301, display: \"flex\", overflow: \"hidden\" }}>\n <div style={{ width: 1, flexShrink: 0, background: stroke.soft }} />\n <div style={{ flex: 1, display: \"flex\", flexDirection: \"column\" as const, overflow: \"hidden\" }}>\n <div style={{ flex: 1, overflowY: \"auto\", padding: \"16px 16px 12px\", minHeight: 0 }}>\n <SettingsContent\n frameSettings={frameSettings}\n onFrameSettingsChange={onFrameSettingsChange}\n saveDir={shortDir}\n picking={picking}\n onPickFolder={handlePickFolder}\n />\n </div>\n {(frameSettings.afterbefore ? (beforeFile && afterFile) : selectedFile) && (\n <div style={{ flexShrink: 0, padding: \"12px 16px\", borderTop: `1px solid ${stroke.soft}` }}>\n <button\n onClick={handleSave}\n disabled={saving}\n style={{\n width: \"100%\",\n padding: \"8px 0\",\n borderRadius: 8,\n border: \"none\",\n background: accentToken.toggle,\n color: \"#fff\",\n ...text.label.xs,\n cursor: saving ? \"default\" : \"pointer\",\n opacity: saving ? 0.6 : 1,\n transition: \"opacity 0.12s ease\",\n }}\n >\n {saving ? \"Saving...\" : \"Save\"}\n </button>\n </div>\n )}\n </div>\n </div>\n </div>\n </div>\n\n {toast && (\n <div\n onClick={(e) => e.stopPropagation()}\n style={{\n position: \"fixed\",\n bottom: 32,\n left: \"50%\",\n transform: \"translateX(-50%)\",\n padding: \"6px 14px\",\n borderRadius: 8,\n ...text.label.xs,\n whiteSpace: \"nowrap\",\n color: \"white\",\n background:\n toast.type === \"success\"\n ? feedback.success\n : feedback.error,\n boxShadow: shadow.toast,\n }}\n >\n {toast.message}\n </div>\n )}\n </div>,\n document.body,\n )}\n\n </>\n );\n}\n","\"use client\";\n\nimport React, { useEffect, useRef, useState } from \"react\";\nimport {\n Check,\n ChevronDown,\n Pipette,\n Trash2,\n Upload,\n} from \"lucide-react\";\nimport { FRAME_SIZE_PRESETS, GRADIENT_PRESETS, COLOR_PRESETS, type FrameSettings } from \"../capture\";\nimport { text as T } from \"../font\";\nimport { bg, fg, stroke, state, accent, shadow } from \"../color\";\n\n/** Settings rows — for embedding in the screenshots panel */\nexport function SettingsContent({\n frameSettings,\n onFrameSettingsChange,\n saveDir,\n picking,\n onPickFolder,\n}: {\n frameSettings: FrameSettings;\n onFrameSettingsChange: (settings: FrameSettings) => void;\n saveDir?: string;\n picking?: boolean;\n onPickFolder?: () => void;\n}) {\n const [autoOpenPanel, setAutoOpenPanel] = useState(() => {\n try { return localStorage.getItem(\"ab-auto-open-panel\") !== \"false\"; }\n catch { return true; }\n });\n\n return (\n <>\n <BackgroundSetting\n frameSettings={frameSettings}\n onFrameSettingsChange={onFrameSettingsChange}\n />\n\n <SettingsDivider />\n\n <BrowserFrameSetting\n enabled={frameSettings.browserChrome}\n theme={frameSettings.browserTheme}\n shadow={frameSettings.browserShadow ?? 50}\n radius={frameSettings.browserRadius ?? 8}\n url={frameSettings.browserUrl ?? \"localhost\"}\n onToggle={() =>\n onFrameSettingsChange({ ...frameSettings, browserChrome: !frameSettings.browserChrome })\n }\n onSelect={(theme) =>\n onFrameSettingsChange({ ...frameSettings, browserChrome: true, browserTheme: theme })\n }\n onShadowChange={(v) =>\n onFrameSettingsChange({ ...frameSettings, browserShadow: v })\n }\n onRadiusChange={(v) =>\n onFrameSettingsChange({ ...frameSettings, browserRadius: v })\n }\n onUrlChange={(v) =>\n onFrameSettingsChange({ ...frameSettings, browserUrl: v })\n }\n />\n\n <SettingsDivider />\n\n <SettingsRow\n title=\"Comparison\"\n description=\"Side-by-side before & after\"\n control={\n <ToggleSwitch\n enabled={frameSettings.afterbefore}\n onChange={() =>\n onFrameSettingsChange({\n ...frameSettings,\n afterbefore: !frameSettings.afterbefore,\n ...(!frameSettings.afterbefore ? { size: { w: 1920, h: 1080 } } : {}),\n })\n }\n />\n }\n />\n\n <SettingsDivider />\n\n <SettingsRow\n title=\"Open after capture\"\n description=\"Show screenshots panel after taking a screenshot\"\n control={\n <ToggleSwitch\n enabled={autoOpenPanel}\n onChange={() => {\n const next = !autoOpenPanel;\n setAutoOpenPanel(next);\n try { localStorage.setItem(\"ab-auto-open-panel\", String(next)); }\n catch {}\n }}\n />\n }\n />\n\n <SettingsDivider />\n\n {saveDir !== undefined && onPickFolder && (\n <SettingsRow\n title=\"Save location\"\n description={\n <span\n style={{\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n display: \"block\",\n }}\n title={saveDir}\n >\n {saveDir}\n </span>\n }\n control={\n <SmallButton onClick={onPickFolder}>\n {picking ? \"...\" : \"Change\"}\n </SmallButton>\n }\n />\n )}\n\n </>\n );\n}\n\nexport function SettingsRow({\n title,\n description,\n control,\n}: {\n title: string;\n description?: string | React.ReactNode;\n control: React.ReactNode;\n}) {\n return (\n <div style={{ display: \"flex\", alignItems: \"center\", justifyContent: \"space-between\", gap: 16, padding: \"14px 0\" }}>\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 2, flex: 1, minWidth: 0 }}>\n <span style={{ ...T.label.xs, color: fg.strong }}>\n {title}\n </span>\n {description && (\n <span style={{ ...T.paragraph.xs, color: fg.sub }}>\n {description}\n </span>\n )}\n </div>\n <div style={{ flexShrink: 0 }}>\n {control}\n </div>\n </div>\n );\n}\n\nexport function SettingsDivider() {\n return (\n <div\n style={{\n borderBottom: `1px solid ${stroke.soft}`,\n margin: \"0 -16px\",\n }}\n />\n );\n}\n\nexport function ToggleSwitch({\n enabled,\n onChange,\n}: {\n enabled: boolean;\n onChange: () => void;\n}) {\n return (\n <button\n type=\"button\"\n onClick={onChange}\n style={{\n width: 38,\n height: 22,\n borderRadius: 999,\n border: \"none\",\n background: enabled ? accent.toggle : stroke.interactive,\n position: \"relative\",\n cursor: \"pointer\",\n padding: 0,\n flexShrink: 0,\n transition: \"background 0.12s ease\",\n }}\n >\n <span\n style={{\n position: \"absolute\",\n top: 2,\n left: enabled ? 18 : 2,\n width: 18,\n height: 18,\n borderRadius: \"50%\",\n background: \"#fff\",\n transition: \"left 0.12s ease\",\n }}\n />\n </button>\n );\n}\n\nexport function FrameSizeControl({\n size,\n onChange,\n}: {\n size: { w: number; h: number };\n onChange: (size: { w: number; h: number }) => void;\n}) {\n const [sizeOpen, setSizeOpen] = useState(false);\n const [editing, setEditing] = useState<\"w\" | \"h\" | null>(null);\n const [text, setText] = useState(\"\");\n\n const currentPreset = FRAME_SIZE_PRESETS.find((p) => p.w === size.w && p.h === size.h);\n const isCustom = !currentPreset;\n\n const commitValue = (field: \"w\" | \"h\", raw: string) => {\n const n = parseInt(raw, 10);\n if (!Number.isNaN(n) && n > 0) onChange({ ...size, [field]: n });\n };\n\n const inputStyle: React.CSSProperties = {\n flex: 1,\n minWidth: 0,\n border: \"none\",\n background: \"transparent\",\n color: fg.strong,\n ...T.label.xs,\n fontFamily: \"inherit\",\n textAlign: \"left\",\n outline: \"none\",\n padding: \"0 2px 0 6px\",\n };\n\n return (\n <div style={{ marginTop: 16, paddingBottom: 14 }}>\n {/* Size heading + W/H inputs */}\n <span style={{ ...T.label.xs, color: fg.strong }}>Size</span>\n <div style={{ display: \"flex\", gap: 6, marginTop: 8 }}>\n {([\"w\", \"h\"] as const).map((field) => (\n <div\n key={field}\n style={{\n flex: 1,\n minWidth: 0,\n display: \"flex\",\n alignItems: \"center\",\n height: 30,\n padding: \"0 8px\",\n background: state.input,\n borderRadius: 7,\n }}\n >\n <span style={{ ...T.label.xs, color: fg.sub, flexShrink: 0, userSelect: \"none\" }}>\n {field.toUpperCase()}\n </span>\n <input\n type=\"text\"\n value={editing === field ? text : String(size[field])}\n onFocus={() => { setEditing(field); setText(String(size[field])); }}\n onBlur={() => { setEditing(null); commitValue(field, text); }}\n onChange={(e) => setText(e.target.value)}\n onKeyDown={(e) => { if (e.key === \"Enter\") (e.target as HTMLElement).blur(); }}\n style={inputStyle}\n />\n </div>\n ))}\n </div>\n\n {/* Presets */}\n <div style={{ marginTop: 16 }}>\n <span style={{ ...T.label.xs, color: fg.strong, display: \"block\", marginBottom: 8 }}>Presets</span>\n <div style={{ position: \"relative\" }}>\n <button\n onClick={() => setSizeOpen((prev) => !prev)}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n width: \"100%\",\n gap: 6,\n height: 28,\n padding: \"0 8px\",\n borderRadius: 7,\n border: `1px solid ${stroke.default}`,\n background: state.input,\n color: fg.sub,\n cursor: \"pointer\",\n ...T.label.xs,\n fontFamily: \"inherit\",\n whiteSpace: \"nowrap\",\n }}\n >\n {currentPreset ? currentPreset.label : \"Custom\"}\n <ChevronDown size={12} strokeWidth={2} />\n </button>\n\n {sizeOpen && (\n <div\n style={{\n position: \"absolute\",\n bottom: \"calc(100% + 4px)\",\n right: 0,\n minWidth: 180,\n background: bg.base,\n border: `1px solid ${stroke.default}`,\n borderRadius: 8,\n padding: \"4px 0\",\n boxShadow: shadow.dropdown,\n zIndex: 1,\n }}\n >\n {FRAME_SIZE_PRESETS.map((preset) => (\n <DropItem\n key={preset.label}\n active={!isCustom && preset.w === size.w && preset.h === size.h}\n onClick={() => {\n onChange({ w: preset.w, h: preset.h });\n setSizeOpen(false);\n }}\n >\n <span>{preset.label}</span>\n <span style={{ marginLeft: 6, fontSize: 10, color: fg.muted }}>\n {preset.hint}\n </span>\n </DropItem>\n ))}\n </div>\n )}\n </div>\n </div>\n </div>\n );\n}\n\ntype BgTab = \"gradient\" | \"solid\" | \"image\";\n\nfunction BackgroundSetting({\n frameSettings,\n onFrameSettingsChange,\n}: {\n frameSettings: FrameSettings;\n onFrameSettingsChange: (settings: FrameSettings) => void;\n}) {\n const [tab, setTab] = useState<BgTab>(\n frameSettings.bgType === \"image\" ? \"image\" : frameSettings.bgType === \"gradient\" ? \"gradient\" : \"solid\",\n );\n const [moreOpen, setMoreOpen] = useState(false);\n const fileInputRef = useRef<HTMLInputElement>(null);\n\n const handleFileSelect = (e: React.ChangeEvent<HTMLInputElement>) => {\n const file = e.target.files?.[0];\n if (!file) return;\n const reader = new FileReader();\n reader.onload = () => {\n const dataUrl = reader.result as string;\n if (dataUrl.length > 2 * 1024 * 1024) {\n downscaleImage(dataUrl, frameSettings.size.w, frameSettings.size.h).then((scaled) => {\n onFrameSettingsChange({ ...frameSettings, bgType: \"image\", bgImage: scaled });\n });\n } else {\n onFrameSettingsChange({ ...frameSettings, bgType: \"image\", bgImage: dataUrl });\n }\n };\n reader.readAsDataURL(file);\n e.target.value = \"\";\n };\n\n const selectGradient = (g: string) => {\n onFrameSettingsChange({ ...frameSettings, bgType: \"gradient\", bgGradient: g });\n };\n\n const selectColor = (c: string) => {\n onFrameSettingsChange({ ...frameSettings, bgType: \"color\", bgColor: c });\n };\n\n const currentBg = frameSettings.bgType === \"gradient\" ? frameSettings.bgGradient : frameSettings.bgColor;\n\n return (\n <div>\n {/* Header */}\n <div style={{ display: \"flex\", alignItems: \"center\", justifyContent: \"space-between\", gap: 16 }}>\n <span style={{ ...T.label.xs, color: fg.strong }}>Background</span>\n <ToggleSwitch\n enabled={frameSettings.enabled}\n onChange={() => onFrameSettingsChange({ ...frameSettings, enabled: !frameSettings.enabled })}\n />\n </div>\n\n {/* Tab bar */}\n <div style={{ display: \"flex\", gap: 2, marginTop: 12, background: state.subtle, borderRadius: 8, padding: 2 }}>\n {([\"solid\", \"gradient\", \"image\"] as BgTab[]).map((t) => (\n <button\n key={t}\n onClick={() => setTab(t)}\n style={{\n flex: 1,\n padding: \"6px 0\",\n border: \"none\",\n borderRadius: 6,\n background: tab === t ? state.button : \"transparent\",\n color: tab === t ? fg.strong : fg.default,\n ...T.label.xs,\n fontFamily: \"inherit\",\n cursor: \"pointer\",\n transition: \"background 0.12s ease, color 0.12s ease\",\n textTransform: \"capitalize\" as const,\n }}\n >\n {t}\n </button>\n ))}\n </div>\n\n {/* Gradient presets */}\n {tab === \"gradient\" && (\n <div style={{ display: \"flex\", gap: 8, marginTop: 12, padding: \"4px 4px 14px\", flexWrap: \"wrap\" }}>\n {GRADIENT_PRESETS.map((g) => {\n const selected = frameSettings.bgType === \"gradient\" && frameSettings.bgGradient === g;\n return (\n <PresetSwatch\n key={g}\n background={g}\n selected={selected}\n onClick={() => selectGradient(g)}\n />\n );\n })}\n </div>\n )}\n\n {/* Solid color presets */}\n {tab === \"solid\" && (\n <>\n <div style={{ display: \"flex\", gap: 8, marginTop: 12, padding: \"4px 4px 14px\", flexWrap: \"wrap\" }}>\n {COLOR_PRESETS.map((c) => {\n const selected = frameSettings.bgType === \"color\" && frameSettings.bgColor === c;\n return (\n <PresetSwatch\n key={c}\n background={c}\n selected={selected}\n onClick={() => selectColor(c)}\n />\n );\n })}\n {(() => {\n const customColor = frameSettings.bgColor;\n const isCustom = !COLOR_PRESETS.includes(customColor.toUpperCase());\n const bg = isCustom ? customColor : \"transparent\";\n // Determine if icon should be light or dark based on background luminance\n const iconColor = isCustom ? (hexLuminance(customColor) > 0.4 ? \"rgba(0,0,0,0.5)\" : \"rgba(255,255,255,0.7)\") : fg.sub;\n return (\n <button\n onClick={async () => {\n if (!(\"EyeDropper\" in window)) return;\n try {\n // @ts-expect-error EyeDropper API not yet in all TS libs\n const result = await new window.EyeDropper().open();\n selectColor(result.sRGBHex);\n } catch { /* user cancelled */ }\n }}\n style={{\n width: 32,\n height: 32,\n borderRadius: \"50%\",\n border: isCustom ? `1px solid ${stroke.soft}` : `1px dashed ${stroke.default}`,\n outline: isCustom ? `2px solid ${accent.toggle}` : \"none\",\n outlineOffset: 1,\n background: bg,\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n color: iconColor,\n }}\n >\n <Pipette size={14} strokeWidth={2} />\n </button>\n );\n })()}\n </div>\n <div style={{ paddingBottom: 4 }}>\n <ColorHexInput value={frameSettings.bgColor} onChange={selectColor} />\n </div>\n </>\n )}\n\n {/* Image upload */}\n {tab === \"image\" && (\n <div style={{ marginTop: 12 }}>\n <input\n ref={fileInputRef}\n type=\"file\"\n accept=\"image/*\"\n onChange={handleFileSelect}\n style={{ display: \"none\" }}\n />\n {frameSettings.bgImage ? (\n <div style={{ display: \"flex\", alignItems: \"center\", gap: 8 }}>\n <img\n src={frameSettings.bgImage}\n alt=\"\"\n style={{\n width: 48,\n height: 28,\n borderRadius: 4,\n objectFit: \"cover\",\n border: `1px solid ${stroke.strong}`,\n }}\n />\n <SmallButton onClick={() => fileInputRef.current?.click()}>\n <Upload size={11} strokeWidth={2} />\n Replace\n </SmallButton>\n <SmallButton onClick={() => onFrameSettingsChange({ ...frameSettings, bgImage: null })}>\n <Trash2 size={11} strokeWidth={2} />\n </SmallButton>\n </div>\n ) : (\n <SmallButton onClick={() => fileInputRef.current?.click()}>\n <Upload size={11} strokeWidth={2} />\n Upload image\n </SmallButton>\n )}\n </div>\n )}\n\n {/* More options toggle */}\n <button\n onClick={() => setMoreOpen(!moreOpen)}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 4,\n marginTop: 12,\n marginBottom: moreOpen ? 0 : 14,\n background: \"none\",\n border: \"none\",\n cursor: \"pointer\",\n color: fg.sub,\n ...T.label.xs,\n fontFamily: \"inherit\",\n padding: 0,\n }}\n >\n <ChevronDown\n size={12}\n strokeWidth={2}\n style={{\n transform: moreOpen ? \"rotate(180deg)\" : \"rotate(0deg)\",\n transition: \"transform 0.15s ease\",\n }}\n />\n More options\n </button>\n\n {moreOpen && (\n <div style={{ marginTop: 8 }}>\n {/* Size (percentage) */}\n <div>\n <span style={{ ...T.label.xs, color: fg.strong }}>Size</span>\n <div style={{ display: \"flex\", alignItems: \"center\", gap: 8, marginTop: 8, paddingLeft: 4 }}>\n <SlimSlider\n min={30}\n max={100}\n step={1}\n value={Math.round(((frameSettings.size.w - frameSettings.padding * 2) / frameSettings.size.w) * 100)}\n onChange={(v: number) => {\n const pad = Math.round((frameSettings.size.w * (1 - v / 100)) / 2);\n onFrameSettingsChange({ ...frameSettings, padding: pad });\n }}\n />\n <SliderInput\n min={30}\n max={100}\n suffix=\"%\"\n value={Math.round(((frameSettings.size.w - frameSettings.padding * 2) / frameSettings.size.w) * 100)}\n onChange={(n: number) => {\n const pad = Math.round((frameSettings.size.w * (1 - n / 100)) / 2);\n onFrameSettingsChange({ ...frameSettings, padding: pad });\n }}\n />\n </div>\n </div>\n\n {/* Frame dimensions */}\n <FrameSizeControl\n size={frameSettings.size}\n onChange={(size) => onFrameSettingsChange({ ...frameSettings, size })}\n />\n </div>\n )}\n </div>\n );\n}\n\nexport function SlimSlider({\n min,\n max,\n step,\n value,\n onChange,\n}: {\n min: number;\n max: number;\n step: number;\n value: number;\n onChange: (value: number) => void;\n}) {\n const trackRef = useRef<HTMLDivElement>(null);\n const pct = ((value - min) / (max - min)) * 100;\n\n const update = (clientX: number) => {\n const rect = trackRef.current!.getBoundingClientRect();\n const ratio = Math.max(0, Math.min(1, (clientX - rect.left) / rect.width));\n const raw = min + ratio * (max - min);\n const snapped = Math.round(raw / step) * step;\n onChange(Math.max(min, Math.min(max, snapped)));\n };\n\n const onPointerDown = (e: React.PointerEvent) => {\n e.preventDefault();\n (e.target as HTMLElement).setPointerCapture(e.pointerId);\n update(e.clientX);\n };\n\n const onPointerMove = (e: React.PointerEvent) => {\n if (e.buttons === 0) return;\n update(e.clientX);\n };\n\n return (\n <div\n ref={trackRef}\n onPointerDown={onPointerDown}\n onPointerMove={onPointerMove}\n style={{\n flex: 1,\n minWidth: 0,\n height: 20,\n display: \"flex\",\n alignItems: \"center\",\n cursor: \"pointer\",\n touchAction: \"none\",\n }}\n >\n <div style={{ position: \"relative\", width: \"100%\", height: 3, borderRadius: 2, background: stroke.default }}>\n <div style={{ position: \"absolute\", left: 0, top: 0, height: \"100%\", width: `${pct}%`, borderRadius: 2, background: fg.sub }} />\n <div\n style={{\n position: \"absolute\",\n top: \"50%\",\n left: `${pct}%`,\n width: 10,\n height: 10,\n borderRadius: \"50%\",\n background: fg.strong,\n transform: \"translate(-50%, -50%)\",\n }}\n />\n </div>\n </div>\n );\n}\n\nfunction PresetSwatch({\n background,\n selected,\n onClick,\n}: {\n background: string;\n selected: boolean;\n onClick: () => void;\n}) {\n return (\n <div\n onClick={onClick}\n style={{\n width: 32,\n height: 32,\n borderRadius: \"50%\",\n background,\n cursor: \"pointer\",\n border: `1px solid ${stroke.soft}`,\n outline: selected ? `2px solid ${accent.toggle}` : \"none\",\n outlineOffset: 1,\n position: \"relative\",\n transition: \"outline-color 0.12s ease\",\n flexShrink: 0,\n }}\n >\n {selected && (\n <div\n style={{\n position: \"absolute\",\n inset: 0,\n borderRadius: \"50%\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n background: \"rgba(0,0,0,0.2)\",\n }}\n >\n <Check size={16} strokeWidth={3} color=\"#fff\" />\n </div>\n )}\n </div>\n );\n}\n\n/** Approximate relative luminance from a hex color (0 = black, 1 = white) */\nfunction hexLuminance(hex: string): number {\n const n = parseInt(hex.replace(\"#\", \"\"), 16);\n const r = ((n >> 16) & 0xff) / 255;\n const g = ((n >> 8) & 0xff) / 255;\n const b = (n & 0xff) / 255;\n return 0.2126 * r + 0.7152 * g + 0.0722 * b;\n}\n\n/** Darken/lighten a hex color by an amount (-255 to 255) */\nfunction adjustColor(hex: string, amount: number): string {\n const num = parseInt(hex.replace(\"#\", \"\"), 16);\n const r = Math.min(255, Math.max(0, ((num >> 16) & 0xff) + amount));\n const g = Math.min(255, Math.max(0, ((num >> 8) & 0xff) + amount));\n const b = Math.min(255, Math.max(0, (num & 0xff) + amount));\n return `#${((r << 16) | (g << 8) | b).toString(16).padStart(6, \"0\")}`;\n}\n\nfunction BrowserFrameSetting({\n enabled,\n theme,\n shadow,\n radius,\n url,\n onToggle,\n onSelect,\n onShadowChange,\n onRadiusChange,\n onUrlChange,\n}: {\n enabled: boolean;\n theme: \"light\" | \"dark\";\n shadow: number;\n radius: number;\n url: string;\n onToggle: () => void;\n onSelect: (theme: \"light\" | \"dark\") => void;\n onShadowChange: (value: number) => void;\n onRadiusChange: (value: number) => void;\n onUrlChange: (value: string) => void;\n}) {\n const [moreOpen, setMoreOpen] = useState(false);\n\n const trafficLights = (\n <div style={{ display: \"flex\", gap: 4 }}>\n {[\"#FF5F57\", \"#FEBC2E\", \"#28C840\"].map((c) => (\n <div key={c} style={{ width: 5, height: 5, borderRadius: \"50%\", background: c }} />\n ))}\n </div>\n );\n\n const themes: { value: \"dark\" | \"light\"; label: string; titleBar: string; urlBar: string; border: string }[] = [\n { value: \"dark\", label: \"macOS Dark\", titleBar: \"#1C1C1C\", urlBar: \"#262626\", border: \"#333333\" },\n { value: \"light\", label: \"macOS Light\", titleBar: \"#F5F5F5\", urlBar: \"#FFFFFF\", border: \"#EBEBEB\" },\n ];\n\n return (\n <div style={{ padding: \"14px 0\" }}>\n <div style={{ display: \"flex\", alignItems: \"center\", justifyContent: \"space-between\", gap: 16 }}>\n <span style={{ ...T.label.xs, color: fg.strong }}>Browser frame</span>\n <ToggleSwitch enabled={enabled} onChange={onToggle} />\n </div>\n\n <div style={{ display: \"flex\", gap: 10, marginTop: 12 }}>\n {themes.map((t) => {\n const selected = enabled && theme === t.value;\n return (\n <div\n key={t.value}\n onClick={() => onSelect(t.value)}\n style={{\n flex: 1,\n cursor: \"pointer\",\n borderRadius: 10,\n border: selected ? `2px solid ${accent.toggle}` : `1px solid ${stroke.soft}`,\n padding: selected ? 7 : 8,\n position: \"relative\",\n background: state.subtle,\n transition: \"border-color 0.12s ease\",\n }}\n >\n {/* Mini browser chrome preview */}\n <div\n style={{\n background: t.titleBar,\n borderRadius: 6,\n overflow: \"hidden\",\n border: t.value === \"light\" ? `1px solid ${t.border}` : \"none\",\n display: \"flex\",\n alignItems: \"center\",\n gap: 6,\n padding: \"6px 8px\",\n }}\n >\n {trafficLights}\n <div\n style={{\n flex: 1,\n height: 8,\n background: t.urlBar,\n borderRadius: 2,\n ...(t.value === \"light\" ? { border: `1px solid ${t.border}` } : {}),\n }}\n />\n </div>\n\n <div style={{ textAlign: \"center\" as const, marginTop: 8, ...T.label.xs, color: fg.default }}>\n {t.label}\n </div>\n\n {/* Selection checkmark */}\n {selected && (\n <div\n style={{\n position: \"absolute\",\n top: -5,\n right: -5,\n width: 18,\n height: 18,\n borderRadius: \"50%\",\n background: accent.toggle,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n }}\n >\n <Check size={10} strokeWidth={3} color=\"#fff\" />\n </div>\n )}\n </div>\n );\n })}\n </div>\n\n {/* More options toggle */}\n <button\n onClick={() => setMoreOpen(!moreOpen)}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 4,\n marginTop: 12,\n background: \"none\",\n border: \"none\",\n cursor: \"pointer\",\n color: fg.sub,\n ...T.label.xs,\n fontFamily: \"inherit\",\n padding: 0,\n }}\n >\n <ChevronDown\n size={12}\n strokeWidth={2}\n style={{\n transform: moreOpen ? \"rotate(180deg)\" : \"rotate(0deg)\",\n transition: \"transform 0.15s ease\",\n }}\n />\n More options\n </button>\n\n {moreOpen && (\n <div style={{ marginTop: 8 }}>\n {/* URL */}\n <div>\n <span style={{ ...T.label.xs, color: fg.strong }}>URL</span>\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n height: 30,\n padding: \"0 8px\",\n background: state.input,\n borderRadius: 7,\n marginTop: 8,\n }}\n >\n <input\n type=\"text\"\n value={url}\n onChange={(e) => onUrlChange(e.target.value)}\n placeholder=\"localhost\"\n style={{\n flex: 1,\n minWidth: 0,\n border: \"none\",\n background: \"transparent\",\n color: fg.strong,\n ...T.label.xs,\n fontFamily: \"inherit\",\n outline: \"none\",\n padding: 0,\n }}\n />\n </div>\n </div>\n\n {/* Shadow */}\n <div style={{ marginTop: 12 }}>\n <span style={{ ...T.label.xs, color: fg.strong }}>Shadow</span>\n <div style={{ display: \"flex\", alignItems: \"center\", gap: 8, marginTop: 8, paddingLeft: 4 }}>\n <SlimSlider\n min={0}\n max={100}\n step={5}\n value={shadow}\n onChange={onShadowChange}\n />\n <SliderInput\n value={shadow}\n onChange={onShadowChange}\n min={0}\n max={100}\n suffix=\"\"\n />\n </div>\n </div>\n\n {/* Rounding */}\n <div style={{ marginTop: 12 }}>\n <span style={{ ...T.label.xs, color: fg.strong }}>Rounding</span>\n <div style={{ display: \"flex\", alignItems: \"center\", gap: 8, marginTop: 8, paddingLeft: 4 }}>\n <SlimSlider\n min={0}\n max={8}\n step={1}\n value={radius}\n onChange={onRadiusChange}\n />\n <SliderInput\n value={radius}\n onChange={onRadiusChange}\n min={0}\n max={8}\n suffix=\"px\"\n />\n </div>\n </div>\n </div>\n )}\n </div>\n );\n}\n\nexport function SegmentButton({\n children,\n active,\n onClick,\n style,\n}: {\n children: React.ReactNode;\n active: boolean;\n onClick: () => void;\n style?: React.CSSProperties;\n}) {\n return (\n <button\n onClick={onClick}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 4,\n height: 28,\n padding: \"0 10px\",\n border: `1px solid ${stroke.default}`,\n background: active ? state.pressed : state.subtle,\n color: active ? fg.strong : fg.default,\n cursor: \"pointer\",\n ...T.label.xs,\n fontFamily: \"inherit\",\n transition: \"background 0.12s ease, color 0.12s ease\",\n ...style,\n }}\n >\n {children}\n </button>\n );\n}\n\nexport function ColorSwatch({\n color,\n onChange,\n}: {\n color: string;\n onChange: (color: string) => void;\n}) {\n const inputRef = useRef<HTMLInputElement>(null);\n\n return (\n <div style={{ position: \"relative\" }}>\n <button\n onClick={() => inputRef.current?.click()}\n style={{\n width: 24,\n height: 24,\n borderRadius: 6,\n border: `1px solid ${stroke.interactive}`,\n background: color,\n cursor: \"pointer\",\n padding: 0,\n }}\n />\n <input\n ref={inputRef}\n type=\"color\"\n value={color}\n onChange={(e) => onChange(e.target.value)}\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n width: 0,\n height: 0,\n opacity: 0,\n pointerEvents: \"none\",\n }}\n />\n </div>\n );\n}\n\nexport function SmallButton({\n children,\n onClick,\n}: {\n children: React.ReactNode;\n onClick: () => void;\n}) {\n const [hovered, setHovered] = useState(false);\n\n return (\n <button\n onClick={onClick}\n onMouseEnter={() => setHovered(true)}\n onMouseLeave={() => setHovered(false)}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 4,\n padding: \"4px 10px\",\n borderRadius: 6,\n border: `1px solid ${stroke.strong}`,\n background: hovered ? state.hoverStrong : state.button,\n color: fg.default,\n ...T.label.xs,\n cursor: \"pointer\",\n fontFamily: \"inherit\",\n transition: \"background 0.12s ease\",\n }}\n >\n {children}\n </button>\n );\n}\n\nexport function NumInput({\n value,\n onChange,\n}: {\n value: number;\n onChange: (value: string) => void;\n}) {\n const [editing, setEditing] = useState(false);\n const [text, setText] = useState(String(value));\n\n useEffect(() => {\n if (!editing) {\n setText(String(value));\n }\n }, [editing, value]);\n\n return (\n <input\n type=\"text\"\n value={editing ? text : String(value)}\n onFocus={() => {\n setEditing(true);\n setText(String(value));\n }}\n onBlur={() => {\n setEditing(false);\n onChange(text);\n }}\n onChange={(e) => setText(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") {\n (e.target as HTMLElement).blur();\n }\n }}\n style={{\n width: 54,\n padding: \"4px 6px\",\n background: state.input,\n border: `1px solid ${stroke.default}`,\n borderRadius: 7,\n color: fg.strong,\n ...T.label.xs,\n fontFamily: \"inherit\",\n textAlign: \"center\",\n outline: \"none\",\n }}\n />\n );\n}\n\nfunction SliderInput({\n value,\n onChange,\n min = 0,\n max = 200,\n suffix = \"px\",\n}: {\n value: number;\n onChange: (value: number) => void;\n min?: number;\n max?: number;\n suffix?: string;\n}) {\n const [editing, setEditing] = useState(false);\n const [text, setText] = useState(String(value));\n\n useEffect(() => {\n if (!editing) setText(String(value));\n }, [editing, value]);\n\n return (\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n height: 30,\n padding: \"0 8px\",\n background: state.input,\n borderRadius: 7,\n flexShrink: 0,\n width: 68,\n }}\n >\n <input\n type=\"text\"\n value={editing ? text : String(value)}\n onFocus={() => { setEditing(true); setText(String(value)); }}\n onBlur={() => {\n setEditing(false);\n const n = parseInt(text, 10);\n if (!Number.isNaN(n) && n >= min && n <= max) onChange(n);\n }}\n onChange={(e) => setText(e.target.value)}\n onKeyDown={(e) => { if (e.key === \"Enter\") (e.target as HTMLElement).blur(); }}\n style={{\n flex: 1,\n minWidth: 0,\n border: \"none\",\n background: \"transparent\",\n color: fg.strong,\n ...T.label.xs,\n fontFamily: \"inherit\",\n textAlign: \"left\",\n outline: \"none\",\n padding: 0,\n }}\n />\n {suffix && <span style={{ ...T.label.xs, color: fg.sub, flexShrink: 0, userSelect: \"none\", marginLeft: 4 }}>{suffix}</span>}\n </div>\n );\n}\n\nfunction ColorHexInput({\n value,\n onChange,\n}: {\n value: string;\n onChange: (color: string) => void;\n}) {\n const [editing, setEditing] = useState(false);\n const [text, setText] = useState(value.replace(\"#\", \"\"));\n\n useEffect(() => {\n if (!editing) setText(value.replace(\"#\", \"\"));\n }, [editing, value]);\n\n const commit = (raw: string) => {\n const hex = raw.startsWith(\"#\") ? raw : `#${raw}`;\n if (/^#[0-9a-fA-F]{6}$/.test(hex)) onChange(hex);\n };\n\n return (\n <div\n style={{\n flex: 1,\n minWidth: 0,\n display: \"flex\",\n alignItems: \"center\",\n height: 30,\n padding: \"0 8px\",\n background: state.input,\n borderRadius: 7,\n gap: 6,\n }}\n >\n <span style={{ ...T.label.xs, color: fg.sub, flexShrink: 0, userSelect: \"none\" }}>#</span>\n <input\n type=\"text\"\n value={editing ? text : value.replace(\"#\", \"\")}\n onFocus={() => { setEditing(true); setText(value.replace(\"#\", \"\")); }}\n onBlur={() => { setEditing(false); commit(text); }}\n onChange={(e) => setText(e.target.value)}\n onKeyDown={(e) => { if (e.key === \"Enter\") (e.target as HTMLElement).blur(); }}\n style={{\n flex: 1,\n minWidth: 0,\n border: \"none\",\n background: \"transparent\",\n color: fg.strong,\n ...T.label.xs,\n fontFamily: \"inherit\",\n textAlign: \"left\",\n outline: \"none\",\n padding: 0,\n }}\n />\n </div>\n );\n}\n\nexport function HexInput({\n value,\n onChange,\n}: {\n value: string;\n onChange: (color: string) => void;\n}) {\n const [editing, setEditing] = useState(false);\n const [text, setText] = useState(value);\n\n useEffect(() => {\n if (!editing) {\n setText(value);\n }\n }, [editing, value]);\n\n const commit = (raw: string) => {\n const hex = raw.startsWith(\"#\") ? raw : `#${raw}`;\n if (/^#[0-9a-fA-F]{6}$/.test(hex)) {\n onChange(hex);\n }\n };\n\n return (\n <input\n type=\"text\"\n value={editing ? text : value}\n onFocus={() => {\n setEditing(true);\n setText(value);\n }}\n onBlur={() => {\n setEditing(false);\n commit(text);\n }}\n onChange={(e) => setText(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") {\n (e.target as HTMLElement).blur();\n }\n }}\n style={{\n width: 72,\n padding: \"4px 6px\",\n background: state.input,\n border: `1px solid ${stroke.default}`,\n borderRadius: 7,\n color: fg.strong,\n ...T.label.xs,\n fontFamily: \"inherit\",\n textAlign: \"left\",\n outline: \"none\",\n }}\n />\n );\n}\n\nexport function StaticText({ children }: { children: React.ReactNode }) {\n return (\n <span\n style={{\n fontSize: 11,\n color: fg.muted,\n minWidth: 8,\n textAlign: \"center\",\n }}\n >\n {children}\n </span>\n );\n}\n\nexport function DropItem({\n children,\n onClick,\n active,\n}: {\n children: React.ReactNode;\n onClick: () => void;\n active?: boolean;\n}) {\n return (\n <button\n onClick={onClick}\n style={{\n display: \"block\",\n width: \"100%\",\n padding: \"7px 12px\",\n background: active ? state.active : \"transparent\",\n border: \"none\",\n color: fg.strong,\n textAlign: \"left\",\n cursor: \"pointer\",\n ...T.paragraph.sm,\n fontFamily: \"inherit\",\n }}\n >\n {children}\n </button>\n );\n}\n\nasync function downscaleImage(dataUrl: string, maxW: number, maxH: number): Promise<string> {\n return new Promise((resolve) => {\n const img = new Image();\n img.onload = () => {\n const canvas = document.createElement(\"canvas\");\n const scale = Math.min(maxW / img.width, maxH / img.height, 1);\n canvas.width = img.width * scale;\n canvas.height = img.height * scale;\n const ctx = canvas.getContext(\"2d\")!;\n ctx.drawImage(img, 0, 0, canvas.width, canvas.height);\n resolve(canvas.toDataURL(\"image/jpeg\", 0.85));\n };\n img.onerror = () => resolve(dataUrl);\n img.src = dataUrl;\n });\n}\n","\"use client\";\n\nimport React, { useEffect, useRef, useCallback, useState } from \"react\";\n\ninterface InspectorProps {\n onSelect: (element: HTMLElement) => void;\n onCancel: () => void;\n}\n\nexport function Inspector({ onSelect, onCancel }: InspectorProps) {\n const [highlight, setHighlight] = useState<{\n x: number;\n y: number;\n width: number;\n height: number;\n } | null>(null);\n const hoveredEl = useRef<HTMLElement | null>(null);\n const styleEl = useRef<HTMLStyleElement | null>(null);\n\n // Inject global crosshair cursor style\n useEffect(() => {\n const style = document.createElement(\"style\");\n style.setAttribute(\"data-afterbefore\", \"true\");\n style.textContent = [\n \"* { cursor: crosshair !important; }\",\n \"[data-afterbefore], [data-afterbefore] * { cursor: auto !important; }\",\n \"[data-afterbefore] button, [data-afterbefore] label, [data-afterbefore] a { cursor: pointer !important; }\",\n \"[data-afterbefore] input, [data-afterbefore] textarea { cursor: text !important; }\",\n ].join(\"\\n\");\n document.head.appendChild(style);\n styleEl.current = style;\n return () => {\n style.remove();\n };\n }, []);\n\n const isOverlayElement = useCallback((el: Element | null): boolean => {\n let node = el;\n while (node) {\n if (node instanceof HTMLElement && node.dataset.afterbefore) return true;\n node = node.parentElement;\n }\n return false;\n }, []);\n\n const handleMouseMove = useCallback(\n (e: MouseEvent) => {\n const el = document.elementFromPoint(e.clientX, e.clientY);\n if (!el || !(el instanceof HTMLElement) || isOverlayElement(el)) {\n setHighlight(null);\n hoveredEl.current = null;\n return;\n }\n hoveredEl.current = el;\n const rect = el.getBoundingClientRect();\n setHighlight({\n x: rect.x,\n y: rect.y,\n width: rect.width,\n height: rect.height,\n });\n },\n [isOverlayElement],\n );\n\n const handleClick = useCallback(\n (e: MouseEvent) => {\n if (isOverlayElement(e.target as Element)) return;\n e.preventDefault();\n e.stopPropagation();\n e.stopImmediatePropagation();\n if (hoveredEl.current) {\n onSelect(hoveredEl.current);\n }\n },\n [onSelect, isOverlayElement],\n );\n\n const handleKeyDown = useCallback(\n (e: KeyboardEvent) => {\n if (e.key === \"Escape\") {\n onCancel();\n }\n },\n [onCancel],\n );\n\n useEffect(() => {\n document.addEventListener(\"mousemove\", handleMouseMove, true);\n document.addEventListener(\"click\", handleClick, true);\n document.addEventListener(\"keydown\", handleKeyDown);\n return () => {\n document.removeEventListener(\"mousemove\", handleMouseMove, true);\n document.removeEventListener(\"click\", handleClick, true);\n document.removeEventListener(\"keydown\", handleKeyDown);\n };\n }, [handleMouseMove, handleClick, handleKeyDown]);\n\n return (\n <div data-afterbefore=\"true\" style={{ position: \"fixed\", inset: 0, zIndex: 2147483646, pointerEvents: \"none\" }}>\n {highlight && (\n <div\n style={{\n position: \"fixed\",\n left: highlight.x,\n top: highlight.y,\n width: highlight.width,\n height: highlight.height,\n background: \"transparent\",\n border: \"1px solid #fff\",\n borderRadius: 2,\n boxShadow: \"0 0 0 9999px rgba(0, 0, 0, 0.5)\",\n pointerEvents: \"none\",\n }}\n />\n )}\n\n </div>\n );\n}\n"],"mappings":"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","names":["useState","useCallback","useEffect","state","useCallback","useEffect","useRef","useState","ChevronDown","Check","X","useCallback","useEffect","useState","Trash2","useState","useState","text","bg","shadow","useState","useState","useState","text","Fragment","jsx","jsxs","useState","useEffect","useCallback","Trash2","Fragment","jsx","jsxs","useState","useRef","useEffect","useState","useEffect","useRef","useCallback","jsxs","jsx","Check","X","Fragment","DropItem","accent","jsxs","jsx","ChevronDown","DropItem","useEffect","useRef","useCallback","useState","jsx","style","jsx","jsxs","state","useState","useEffect","useCallback"]}
|