/* global React, window */
// ============================================================
// Section 1 — 快速生图 Quick generator
// 重写（Sprint 2.K，2026-05-10）：
//   - 删配饰（用户：太丑）+ 删 bg picker（用户：跟 shell 关系做不好，永远白底）
//   - 删收藏 F 快捷键（用户要求）
//   - 文本随机 button 在 input 左侧 + 大随机 button 移到右上角（不再悬浮 dice）
//   - dice icon 换 wand（"魔法"语义比骰子更对题）
//   - flip-h IconButton selected 不要矩形框，只让 icon 颜色变
//   - 随机生图同时随机：shell + face + text + font (+rotation reset)
// ============================================================

const {
	useState: qUseState, useEffect: qUseEffect, useRef: qUseRef,
	useCallback: qUseCallback, useDeferredValue: qUseDeferredValue,
} = React

function QuickSection({ favs, setFavs, pushToCollection, hideHeader = false }) {
	const { t, lang } = useI18n()
	const toast = useToast()

	const def = window.DEFAULT_TRAITS || {}
	const [shells, setShells] = qUseState(window.SHELLS || [])
	const [faces, setFaces] = qUseState(window.FACES || [])
	const [shellId, setShellId] = qUseState(def.shellId || null)
	const [faceId, setFaceId] = qUseState(def.faceId || null)
	const [text, setText] = qUseState(def.text || '')
	const [font, setFont] = qUseState(def.font || 'sans')
	const [faceRotation, setFaceRotation] = qUseState(0)
	const [faceFlipX, setFaceFlipX] = qUseState(false)
	const [nameOpen, setNameOpen] = qUseState(false)
	const [copied, setCopied] = qUseState(false)
	// 文本语言选择：both（默认双语池）/ zh / en
	const [textLang, setTextLang] = qUseState(() => {
		try { return localStorage.getItem('pk-text-lang') || 'both' } catch { return 'both' }
	})
	qUseEffect(() => { try { localStorage.setItem('pk-text-lang', textLang) } catch {} }, [textLang])
	const exportRef = qUseRef(null)
	const previewWrapRef = qUseRef(null)

	qUseEffect(() => {
		loadManifests().then(({ shells: s, faces: f }) => {
			setShells(s); setFaces(f)
			// 如果 default shell/face 不在 manifest 中，回退到第一个
			if (s.length && !s.find((x) => x.id === shellId)) setShellId(s[0].id)
			if (f.length && !f.find((x) => x.id === faceId)) setFaceId(f[0].id)
		})
	}, [])

	const dShellId = qUseDeferredValue(shellId)
	const dFaceId = qUseDeferredValue(faceId)
	const dRotation = qUseDeferredValue(faceRotation)
	const dText = qUseDeferredValue(text)

	const shell = shells.find((x) => x.id === dShellId)
	const face = faces.find((x) => x.id === dFaceId)

	const previewKey = `${shellId}|${faceId}|${text}|${faceRotation}|${faceFlipX}|${font}`
	const isFav = !!favs[previewKey]
	const traits = { shellId, faceId, text, bg: '#FFFFFF', faceRotation, faceFlipX, faceFlipY: false, font }

	qUseEffect(() => {
		const el = previewWrapRef.current
		if (!el) return
		// rAF 节流：连续滚轮 delta 累积到下一帧一次性 setState，
		// 避免每个 wheel event 都触发 canvas 重画（导致频闪）
		let pendingDelta = 0
		let rafId = 0
		const onWheel = (e) => {
			e.preventDefault()
			pendingDelta += e.deltaY > 0 ? 5 : -5
			if (rafId) return
			rafId = requestAnimationFrame(() => {
				const d = pendingDelta
				pendingDelta = 0
				rafId = 0
				setFaceRotation((r) => {
					let v = r + d
					while (v > 180) v -= 360
					while (v < -180) v += 360
					return v
				})
			})
		}
		el.addEventListener('wheel', onWheel, { passive: false })
		return () => {
			el.removeEventListener('wheel', onWheel)
			if (rafId) cancelAnimationFrame(rafId)
		}
	}, [])

	const pickRandom = (arr) => arr[Math.floor(Math.random() * arr.length)]

	// 按 textLang 选文本池（用户：可选只看中 / 只看英 / 双语）
	const getTextPool = () => {
		if (textLang === 'zh') return window.RANDOM_TEXTS_ZH || []
		if (textLang === 'en') return window.RANDOM_TEXTS_EN || []
		return [...(window.RANDOM_TEXTS_ZH || []), ...(window.RANDOM_TEXTS_EN || [])]
	}

	// 强制下一个文本不等于当前文本（用户：每次随机文字一定要不一样的）
	const pickDifferent = (pool, current) => {
		if (pool.length === 0) return current
		if (pool.length === 1) return pool[0]
		const filtered = pool.filter((x) => x !== current)
		return pickRandom(filtered)
	}

	const randomText = qUseCallback(() => {
		const pool = getTextPool()
		if (!pool.length) return
		setText(pickDifferent(pool, text))
		// 字体也随机切（不等于当前 font）
		const fonts = FONT_OPTIONS.filter((f) => f.id !== font)
		if (fonts.length) setFont(pickRandom(fonts).id)
	}, [text, font, textLang])

	const randomize = qUseCallback(() => {
		if (!shells.length || !faces.length) return
		// shell / face 也保证不等于当前
		const otherShells = shells.filter((s) => s.id !== shellId)
		const otherFaces = faces.filter((f) => f.id !== faceId)
		setShellId(pickRandom(otherShells.length ? otherShells : shells).id)
		setFaceId(pickRandom(otherFaces.length ? otherFaces : faces).id)
		setFaceRotation(0); setFaceFlipX(false)
		// 文字必带（用户："每次随机生图的文字一定要不一样"）
		const pool = getTextPool()
		if (pool.length) setText(pickDifferent(pool, text))
		const fonts = FONT_OPTIONS.filter((f) => f.id !== font)
		if (fonts.length) setFont(pickRandom(fonts).id)
	}, [shells, faces, shellId, faceId, text, font, textLang])

	const onCopy = qUseCallback(() => {
		if (!exportRef.current) return
		exportRef.current.toBlob(async (blob) => {
			if (!blob) return
			try {
				await navigator.clipboard.write([new ClipboardItem({ 'image/png': blob })])
				setCopied(true)
				toast.push(t('quick.copied'), 'success')
				setTimeout(() => setCopied(false), 1100)
			} catch (e) {
				toast.push(lang === 'zh' ? '复制失败（浏览器限制）' : 'Copy failed', 'error')
			}
		}, 'image/png')
	}, [t, toast, lang])

	const onDownload = qUseCallback(() => {
		if (!exportRef.current) {
			toast.push(lang === 'zh' ? '画布未就绪' : 'Canvas not ready', 'error')
			return
		}
		try {
			exportRef.current.toBlob((blob) => {
				if (!blob) {
					toast.push(lang === 'zh' ? '导出失败' : 'Export failed', 'error')
					return
				}
				const url = URL.createObjectURL(blob)
				const a = document.createElement('a')
				a.href = url
				a.download = `pandakit-${shellId}-${faceId}-${Date.now()}.png`
				a.style.display = 'none'
				document.body.appendChild(a)
				a.click()
				setTimeout(() => {
					document.body.removeChild(a)
					URL.revokeObjectURL(url)
				}, 100)
				toast.push(lang === 'zh' ? '已下载 PNG' : 'Downloaded', 'success')
			}, 'image/png')
		} catch (e) {
			console.error('[download]', e)
			toast.push(lang === 'zh' ? '下载失败：' + e.message : 'Download failed: ' + e.message, 'error')
		}
	}, [shellId, faceId, toast, lang])

	const onFav = (next) => {
		setFavs((m) => {
			const nm = { ...m }
			if (next) {
				nm[previewKey] = { traits, ts: Date.now(), id: previewKey, caption: '' }
				pushToCollection?.({ traits, id: previewKey, caption: '' })
				// mobile：跳过命名弹窗，直接 toast；user 之后到 saved 里 rename
				const isMobile = typeof window !== 'undefined'
					&& window.matchMedia
					&& window.matchMedia('(max-width: 720px)').matches
				if (isMobile) {
					toast.push(t('quick.saved'), 'success')
				} else {
					setNameOpen(true)
				}
			} else {
				delete nm[previewKey]
				toast.push(t('quick.unsaved'))
			}
			return nm
		})
	}

	const onSaveName = (name) => {
		setNameOpen(false)
		setFavs((m) => ({ ...m, [previewKey]: { ...(m[previewKey] || {}), caption: name } }))
		if (typeof window.__pkRenameCollection === 'function') {
			window.__pkRenameCollection(previewKey, name)
		}
		toast.push(t('quick.saved'), 'success')
	}

	const flipH = () => setFaceFlipX((f) => !f)
	const resetFace = () => { setFaceRotation(0); setFaceFlipX(false) }

	qUseEffect(() => {
		const onKey = (e) => {
			if (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA') return
			if (e.key === 'r' || e.key === 'R') randomize()
			if (e.key === 'c' || e.key === 'C') onCopy()
			if (e.key === 'd' || e.key === 'D') onDownload()
			// F 快捷键已删（用户要求）
		}
		window.addEventListener('keydown', onKey)
		return () => window.removeEventListener('keydown', onKey)
	}, [randomize, onCopy, onDownload])

	return (
		<div style={{ position: 'relative' }}>
			{!hideHeader && (
				<div style={{ display: 'flex', alignItems: 'flex-start', justifyContent: 'space-between', marginBottom: 24 }}>
					<SectionHeader title={t('quick.title')} subtitle={t('quick.subtitle')} />
					{/* 用 wrapper 把 hover lift 限制在 button 内（删 transform 防 Tooltip 漂移）*/}
					<Tooltip content={(lang === 'zh' ? '随机生图' : 'Randomize') + ' · R'}>
						<button onClick={randomize}
							className="pk-focus-ring"
							style={{
								display: 'inline-flex', alignItems: 'center', gap: 8,
								padding: '10px 18px', borderRadius: 999,
								background: 'var(--primary)', border: '1px solid var(--primary-deep)',
								color: '#231C0E', fontSize: 13, fontWeight: 600,
								cursor: 'pointer',
								boxShadow: '0 4px 14px rgba(245,197,106,0.32)',
								transition: 'box-shadow 200ms var(--ease), background 200ms var(--ease)',
							}}
							onMouseEnter={(e) => (e.currentTarget.style.boxShadow = '0 6px 18px rgba(245,197,106,0.5)')}
							onMouseLeave={(e) => (e.currentTarget.style.boxShadow = '0 4px 14px rgba(245,197,106,0.32)')}
						>
							<Icon name="wand" size={16} />
							<span>{lang === 'zh' ? '随机生图' : 'Randomize'}</span>
						</button>
					</Tooltip>
				</div>
			)}

			<div style={{ display: 'grid', gridTemplateColumns: 'minmax(0, 1fr)', gap: 28 }}>
				{/* Preview block — 固定 360×360 */}
				<div className="pk-card" style={{ padding: 28, display: 'flex', flexDirection: 'column', alignItems: 'center' }}>
					<div ref={previewWrapRef} style={{
						position: 'relative',
						width: 360, height: 360,
						display: 'flex', alignItems: 'center', justifyContent: 'center',
					}}>
						{shell && face ? (
							<PandaCanvas
								shell={shell}
								face={face}
								text={dText}
								font={font}
								bg="#FFFFFF"
								faceRotation={dRotation}
								faceFlipX={faceFlipX}
								exportSize={1024}
								onCanvasReady={(c) => { exportRef.current = c }}
							/>
						) : (
							<div style={{ color: 'var(--text-soft)' }}>
								{lang === 'zh' ? '资源加载中…' : 'Loading…'}
							</div>
						)}
						<div style={{
							position: 'absolute', top: 0, right: 0,
							padding: '4px 10px', background: 'var(--card)',
							border: '1px solid var(--border)', borderRadius: 999,
							fontSize: 11, color: 'var(--text)', fontWeight: 600,
							boxShadow: 'var(--shadow-sm)',
						}}>
							<Icon name="sparkle" size={11} style={{ verticalAlign: '-2px' }} />{' '}
							<span style={{ marginLeft: 4 }}>{lang === 'zh' ? '实时预览' : 'Live'}</span>
						</div>
					</div>

					{/* Action buttons */}
					<div style={{ display: 'flex', gap: 10, marginTop: 22, alignItems: 'center' }}>
						<Tooltip content={t('quick.copy') + ' · C'}>
							<Button leftIcon={<Icon name={copied ? 'check' : 'copy'} size={16} />} onClick={onCopy}
								style={copied ? { background: 'var(--accent)', borderColor: '#5F8278', color: '#fff' } : undefined}>
								{t('quick.copy')}
							</Button>
						</Tooltip>
						<Tooltip content={t('quick.download') + ' · D'}>
							<Button variant="secondary" leftIcon={<Icon name="download" size={16} />} onClick={onDownload}>
								{t('quick.download')}
							</Button>
						</Tooltip>
						<div style={{ width: 1, height: 24, background: 'var(--border)' }} />
						<div style={{ position: 'relative' }}>
							<Tooltip content={t('quick.fav')}>
								<HeartButton active={isFav} onChange={onFav} label={t('quick.fav')} />
							</Tooltip>
							<NamePopover
								open={nameOpen}
								onClose={() => setNameOpen(false)}
								onSave={onSaveName}
								anchor="bottom"
								title={t('quick.name.save')}
								placeholder={t('quick.name.placeholder')}
								initial=""
							/>
						</div>
					</div>

					{/* Face transform: dot slider + flip + reset（IconButton 不要矩形框） */}
					<div style={{ marginTop: 22, display: 'flex', alignItems: 'center', gap: 14, flexWrap: 'wrap', justifyContent: 'center' }}>
						<RotationDot value={faceRotation} onChange={setFaceRotation} />
						<Tooltip content={lang === 'zh' ? '水平翻转' : 'Flip horizontal'}>
							<button onClick={flipH} aria-label="flip" className="pk-focus-ring"
								style={{
									width: 32, height: 32, padding: 0,
									border: 'none', background: 'transparent', cursor: 'pointer',
									borderRadius: 6,
									color: faceFlipX ? 'var(--primary-deep)' : 'var(--text-soft)',
									display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
									transition: 'color 160ms var(--ease)',
								}}
								onMouseEnter={(e) => { if (!faceFlipX) e.currentTarget.style.color = 'var(--text)' }}
								onMouseLeave={(e) => { if (!faceFlipX) e.currentTarget.style.color = 'var(--text-soft)' }}
							>
								<Icon name="flip-h" size={18} />
							</button>
						</Tooltip>
						<Tooltip content={lang === 'zh' ? '重置' : 'Reset'}>
							<button onClick={resetFace} aria-label="reset" className="pk-focus-ring"
								style={{
									width: 32, height: 32, padding: 0,
									border: 'none', background: 'transparent', cursor: 'pointer',
									borderRadius: 6, color: 'var(--text-soft)',
									display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
									transition: 'color 160ms var(--ease)',
								}}
								onMouseEnter={(e) => (e.currentTarget.style.color = 'var(--text)')}
								onMouseLeave={(e) => (e.currentTarget.style.color = 'var(--text-soft)')}
							>
								<Icon name="reset" size={16} />
							</button>
						</Tooltip>
						<span style={{
							fontSize: 12, color: 'var(--text)', minWidth: 44, fontWeight: 600,
							fontVariantNumeric: 'tabular-nums', textAlign: 'right',
						}}>
							{faceRotation > 0 ? '+' : ''}{faceRotation}°
							{faceFlipX && ' ⇋'}
						</span>
					</div>
					<div style={{ marginTop: 8, fontSize: 11, color: 'var(--text-soft)', textAlign: 'center' }}>
						{lang === 'zh' ? '拖动圆点 · 在预览图上滚轮微调' : 'drag dot · scroll wheel over preview'}
					</div>
				</div>

				{/* Selector rails */}
				<div className="pk-card" style={{ padding: '20px 4px 24px' }}>
					<TraitRail
						label={lang === 'zh' ? '姿势' : 'Pose'}
						options={shells}
						value={shellId}
						onChange={setShellId}
						getLabel={(s) => lang === 'en' ? s.label_en : s.label_zh}
						renderPreview={(s) => (
							<img src={'shells/' + s.file} alt={s.id} draggable={false}
								style={{ width: '100%', height: '100%', objectFit: 'contain', userSelect: 'none' }} />
						)}
					/>
					<TraitRail
						label={lang === 'zh' ? '表情' : 'Face'}
						options={faces}
						value={faceId}
						onChange={setFaceId}
						getLabel={(f) => lang === 'en' ? f.label_en : f.label_zh}
						renderPreview={(f) => (
							<img src={'faces/' + f.file} alt={f.id} draggable={false}
								style={{ width: '100%', height: '100%', objectFit: 'cover', borderRadius: '50%', userSelect: 'none' }} />
						)}
					/>

					{/* Text + 文本随机 button + 文本语言选择 + font dropdown */}
					<div style={{ padding: '16px 24px 4px', display: 'flex', gap: 10, alignItems: 'center', flexWrap: 'wrap' }}>
						<div style={{ fontSize: 13, fontWeight: 600, color: 'var(--text)', minWidth: 36 }}>{t('quick.text')}</div>
						<Tooltip content={t('quick.random.text')}>
							<button onClick={randomText} aria-label="random-text" className="pk-focus-ring"
								style={{
									width: 36, height: 36, padding: 0,
									border: '1px solid var(--border)', background: 'var(--card)',
									cursor: 'pointer', borderRadius: 8,
									color: 'var(--text-soft)',
									display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
									transition: 'all 160ms var(--ease)',
								}}
								onMouseEnter={(e) => { e.currentTarget.style.color = 'var(--text)'; e.currentTarget.style.background = 'var(--bg-soft)' }}
								onMouseLeave={(e) => { e.currentTarget.style.color = 'var(--text-soft)'; e.currentTarget.style.background = 'var(--card)' }}
							>
								<Icon name="wand" size={16} />
							</button>
						</Tooltip>
						{/* 文本语言选择（用短标签：双 / 中 / EN） */}
						<Tooltip content={lang === 'zh' ? '随机文本语言' : 'Random text language'}>
							<div style={{ display: 'inline-flex', border: '1px solid var(--border)', borderRadius: 8, overflow: 'hidden', background: 'var(--card)', flexShrink: 0 }}>
								{[
									{ id: 'both', label: '双' },
									{ id: 'zh',   label: '中' },
									{ id: 'en',   label: 'EN' },
								].map((opt) => {
									const on = textLang === opt.id
									return (
										<button key={opt.id} onClick={() => setTextLang(opt.id)}
											className="pk-focus-ring"
											style={{
												padding: '6px 8px', minWidth: 28,
												border: 'none', cursor: 'pointer',
												background: on ? 'var(--primary)' : 'transparent',
												color: on ? '#231C0E' : 'var(--text-soft)',
												fontSize: 11, fontWeight: on ? 700 : 500,
												transition: 'all 160ms var(--ease)',
											}}
										>
											{opt.label}
										</button>
									)
								})}
							</div>
						</Tooltip>
						<div style={{ flex: 1, minWidth: 200 }}>
							<Input
								value={text}
								onChange={(e) => setText(e.target.value)}
								placeholder={t('quick.text.placeholder')}
								prefixIcon={<Icon name="type" size={14} />}
								clearable
							/>
						</div>
						<div style={{ minWidth: 130 }}>
							<Dropdown
								value={font}
								onChange={setFont}
								options={FONT_OPTIONS.map((o) => ({
									value: o.id,
									label: fontLabel(lang, o.id),
									render: (
										<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 12, width: '100%' }}>
											<span>{fontLabel(lang, o.id)}</span>
											<span style={{ fontFamily: window.PANDA_FONTS[o.id], color: 'var(--text-soft)', fontSize: 16 }}>Aa 熊</span>
										</div>
									),
								}))}
							/>
						</div>
					</div>
				</div>
			</div>
		</div>
	)
}

function RotationDot({ value, onChange }) {
	const trackRef = qUseRef(null)
	const [dragging, setDragging] = qUseState(false)

	const updateFromX = qUseCallback((clientX) => {
		if (!trackRef.current) return
		const rect = trackRef.current.getBoundingClientRect()
		const x = clientX - rect.left
		const ratio = Math.max(0, Math.min(1, x / rect.width))
		onChange(Math.round((ratio - 0.5) * 360))
	}, [onChange])

	const onMouseDown = (e) => {
		e.preventDefault()
		setDragging(true)
		updateFromX(e.clientX)
	}

	// touch — 触摸端拖动（用户：要做成可触摸拖动而不是点按式）
	const onTouchStart = (e) => {
		if (!e.touches || !e.touches[0]) return
		setDragging(true)
		updateFromX(e.touches[0].clientX)
	}

	qUseEffect(() => {
		if (!dragging) return
		const onMouseMove = (e) => updateFromX(e.clientX)
		const onMouseUp = () => setDragging(false)
		const onTouchMove = (e) => {
			if (!e.touches || !e.touches[0]) return
			e.preventDefault()  // 防 page scroll
			updateFromX(e.touches[0].clientX)
		}
		const onTouchEnd = () => setDragging(false)
		document.addEventListener('mousemove', onMouseMove)
		document.addEventListener('mouseup', onMouseUp)
		document.addEventListener('touchmove', onTouchMove, { passive: false })
		document.addEventListener('touchend', onTouchEnd)
		document.addEventListener('touchcancel', onTouchEnd)
		return () => {
			document.removeEventListener('mousemove', onMouseMove)
			document.removeEventListener('mouseup', onMouseUp)
			document.removeEventListener('touchmove', onTouchMove)
			document.removeEventListener('touchend', onTouchEnd)
			document.removeEventListener('touchcancel', onTouchEnd)
		}
	}, [dragging, updateFromX])

	const dotPercent = 50 + (value / 360) * 100

	return (
		<div ref={trackRef} onMouseDown={onMouseDown} onTouchStart={onTouchStart}
			className="pk-rotation-track"
			style={{
				position: 'relative', width: 220, height: 36,  // mobile 加高更易触摸
				cursor: dragging ? 'grabbing' : 'pointer',
				userSelect: 'none', touchAction: 'none',
			}}>
			<div style={{
				position: 'absolute', top: '50%', left: 0, right: 0, height: 4,
				background: 'var(--border-strong)', borderRadius: 2,
				transform: 'translateY(-50%)',
			}} />
			<div style={{
				position: 'absolute', top: '50%', left: '50%', width: 2, height: 14,
				background: 'var(--text-soft)', transform: 'translate(-50%, -50%)',
			}} />
			<div style={{
				position: 'absolute', top: '50%', left: dotPercent + '%',
				width: 28, height: 28, borderRadius: '50%',  // mobile 圆点也加大
				background: 'var(--primary)', border: '2px solid var(--primary-deep)',
				transform: 'translate(-50%, -50%)',
				cursor: dragging ? 'grabbing' : 'grab',
				display: 'flex', alignItems: 'center', justifyContent: 'center',
				boxShadow: 'var(--shadow-sm)',
				transition: dragging ? 'none' : 'left 60ms ease-out',
			}}>
				<div style={{
					width: 2, height: 14,
					background: 'var(--primary-deep)',
					transform: 'rotate(' + value + 'deg)',
					transformOrigin: 'center',
					borderRadius: 1,
				}} />
			</div>
		</div>
	)
}

function TraitRail({ label, options, value, onChange, renderPreview, getLabel }) {
	const railRef = qUseRef(null)

	qUseEffect(() => {
		const el = railRef.current
		if (!el) return
		// rail 是 wheel sink — deltaY 永远转横滚，不传给页面（用户：滚到底也不要滚页面）
		// 副作用：到边界后还转，但 scrollLeft 不动，相当于 noop（不会让页面意外跳动）
		const onWheel = (e) => {
			if (e.deltaY === 0) return
			e.preventDefault()
			el.scrollLeft += e.deltaY
		}
		el.addEventListener('wheel', onWheel, { passive: false })
		return () => el.removeEventListener('wheel', onWheel)
	}, [])

	return (
		<div style={{ padding: '10px 24px' }}>
			<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 10 }}>
				<div style={{ fontSize: 13, fontWeight: 600, color: 'var(--text)' }}>{label}</div>
				<div style={{ fontSize: 12, color: 'var(--text-soft)' }}>
					{Math.max(0, options.findIndex((o) => o.id === value)) + 1} / {options.length}
				</div>
			</div>
			<div ref={railRef} className="pk-rail" style={{
				display: 'flex', gap: 12,
				overflowX: 'auto', overflowY: 'hidden',
				padding: '6px 0 10px', scrollBehavior: 'smooth',
			}}>
				{options.map((o) => (
					<Tooltip key={o.id} content={getLabel(o)} side="bottom" variant="light">
						<ChoiceCard shape="round" size={68} selected={o.id === value} onClick={() => onChange(o.id)} label={getLabel(o)}>
							<div style={{ width: 56, height: 56, display: 'inline-flex', alignItems: 'center', justifyContent: 'center', background: 'var(--bg-soft)', borderRadius: '50%', overflow: 'hidden' }}>
								{renderPreview(o)}
							</div>
						</ChoiceCard>
					</Tooltip>
				))}
			</div>
		</div>
	)
}

window.QuickSection = QuickSection
