dsh-any-background 0.3.4 → 0.3.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/client.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","names":["panelFragments","createAdapter","panelFragments","createAdapter","panelFragments","createAdapter","panelFragments","createAdapter","panelFragments","createAdapter","panelFragments","createAdapter","panelFragments","createAdapter","adapterFor015rc","adapterFor016alpha","adapterFor017alpha","adapterFor017rc","adapterFor020rc","adapterFor020rc2","adapterFor021alpha","adapterForUnknown","subs","randomSeed","Component","useState","createPortal","memo","useRef","useState","useCallback","SEG_W","useState","useRef","useRef","useState","useCallback","useState","useRef","PARTS","useRef","useState","useState","useRef","useCallback","useRef","useState","useRef","useState","useState","useRef","useCallback","useMemo","useRef","useCallback","useSyncExternalStore","useCallback","useSyncExternalStore","useMemo","createElement","createElement","subscribeBetterSidebar","rpcRemoveFont","rpcSetVideoFromUrl"],"sources":["../src/client/runtime.ts","../src/client/i18n.ts","../src/client/state.ts","../src/host-compat/channel.ts","../src/client/host-compat/versions/shared.ts","../src/client/host-compat/versions/v0-1-5-rc-2-3/adapter.ts","../src/client/host-compat/versions/v0-1-6-alpha-1-2/adapter.ts","../src/client/host-compat/versions/v0-1-7-alpha-1-2-rc-1/adapter.ts","../src/client/host-compat/versions/v0-1-7-rc-2/adapter.ts","../src/client/host-compat/versions/v0-2-0-rc-1/adapter.ts","../src/client/host-compat/versions/v0-2-0-rc-2/adapter.ts","../src/client/host-compat/versions/v0-2-1-alpha-1/adapter.ts","../src/client/host-compat/versions/unknown/adapter.ts","../src/client/host-compat/versions/registry.ts","../src/client/host-compat/release.ts","../src/client/rpc.ts","../src/client/host-compat/capabilities.ts","../src/client/header-tag.ts","../src/client/utils/image.ts","../src/client/utils/color.ts","../src/client/utils/bg-generators.ts","../src/client/wallpaper.ts","../src/client/host-compat/styles.ts","../src/client/utils/video.ts","../src/client/components/ui.css.ts","../src/client/components/icons.tsx","../src/client/components/ErrorBoundary.tsx","../src/client/components/Portal.tsx","../src/client/components/ColorWheel.tsx","../src/client/components/ColorInputs.tsx","../src/client/components/ColorPicker.tsx","../src/client/components/pages/ColorPage.tsx","../src/client/components/LiveSlider.tsx","../src/client/components/pages/InterfacePage.tsx","../src/client/components/pages/FontPage.tsx","../src/client/components/BgEditor.tsx","../src/client/components/pages/BackgroundPage.tsx","../src/client/utils/presets.ts","../src/client/components/pages/ProfilePage.tsx","../src/client/components/ThemeSection.tsx","../src/client/sidebar/store-hook.ts","../src/client/sidebar/tab.tsx","../src/client/env.ts","../src/client/sidebar/native-tab.tsx","../src/client/index.tsx"],"sourcesContent":["/**\n * Harness-version-agnostic access to the client runtime.\n *\n * Before dsh 0.1.2 the store primitive lived on the composite package\n * `@deepseek-ai/dsh-client-runtime` (the `/client` subpath). The new harness\n * split it into `@deepseek-ai/dsh-client-store`. Both specifiers are kept\n * external so they resolve against the host client-module table; a missing\n * table entry on one side throws (the \"missed the module table\" error) and is\n * caught, falling through to the other package. This lets one bundle load on\n * both the old npm release and the new source.\n *\n * The host's synchronous `require` is injected by the loader into the bundle\n * factory; tsdown keeps these two bare specifiers as external CJS requires so\n * they bind to that factory `require`.\n */\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\ninterface StoreModule {\n defineStore: any\n}\n\nfunction resolveStore(): StoreModule | null {\n try {\n // New harness (dsh >= 0.1.2): dedicated store package after the runtime\n // was split. Missing here means the loader table has no such row → throw.\n return require('@deepseek-ai/dsh-client-store') as StoreModule\n } catch {\n /* fall through to the legacy composite runtime below */\n }\n try {\n // Legacy harness (npm release): composite runtime, /client subpath.\n return require('@deepseek-ai/dsh-client-runtime/client') as StoreModule\n } catch {\n // Neither resolved (host variant with no store module at all). This MUST\n // not throw at import time: this module is evaluated while the client\n // bundle boots, so a throw here kills the whole plugin — no theme, no\n // wallpaper, nothing. Callers degrade to \"no settings panel\" instead.\n console.warn('dsh-any-background: no client store module resolved on this host; the settings panel will be disabled')\n return null\n }\n}\n\n/** null when neither store package resolves on this host (see resolveStore). */\nexport const defineStore: any = resolveStore()?.defineStore ?? null","export const NS = 'settings.anyBg'\r\n\r\nexport const zh: Record<string, string> = {\r\n nav: '主题', brandTag: '外观定制', close: '关闭',\r\n pageColor: '色彩', pageInterface: '界面', pageFont: '字体', pageBackground: '背景', pageProfile: '配置',\r\n descColor: '拖动色轮或输入精确数值,整个界面的配色将实时跟随变化',\r\n descInterface: '为主界面的各个区域单独调节透明度与模糊,营造空间层次感',\r\n descFont: '上传自定义字体为整套界面换字形,并按区域为文字添加描边,让内容在复杂的壁纸上依然清晰',\r\n descBackground: '上传一张图片或一段视频作为壁纸并自由摆放,或让算法为你实时生成动态背景',\r\n descProfile: '一键套用外观预设,保存多套配置随时切换,设置昼夜自动换装,或导出/导入完整主题',\r\n colorTitle: '主题色', colorHint: '在色轮外圈选择色相,在内部方形中调整饱和度和明度;双击滑块可恢复默认值',\r\n swatchTitle: '灵感色板',\r\n hexCaption: '当前主题色',\r\n uiTitle: '主界面',\r\n uiOpacity: '透明度', uiBlur: '模糊度',\r\n uiOpacityBg: '主背景', uiOpacitySide: '侧边栏', uiOpacityCard: '对话框中选项面板', uiOpacityInput: '输入框与控件',\r\n uiSop: '设置界面',\r\n uiChatRegion: '对话文本框',\r\n uiTrajectory: '轨迹页',\r\n uiPanelNative: '右方侧边栏',\r\n guideDesc: '管理主题色、壁纸与界面透明度',\r\n uiProduced: '产出物/高亮内容',\r\n uiHeader: '顶栏选项',\r\n fontPageTitle: '字体与描边',\r\n fontTitle: '自定义字体',\r\n fontHint: '支持 ttf/otf/woff/woff2 字体文件(上限 100MB),将应用到整个界面的文字;代码块的等宽字体保持不变。中文字体通常有几十 MB,首次上传与刷新加载需要片刻',\r\n fontUpload: '上传字体',\r\n fontUploading: '上传中…',\r\n fontRemove: '移除字体',\r\n fontEnabled: '启用字体',\r\n fontNone: '未设置,使用宿主默认字体',\r\n fontFail: '字体上传失败,请确认是有效的 ttf/otf/woff/woff2 文件',\r\n uploadTooLarge: '文件过大,上限 {limit}',\r\n bgUploadFail: '壁纸上传失败',\r\n videoUploadFail: '视频上传失败,本次播放不会被保存',\r\n strokeTitle: '文字描边',\r\n strokeHint: '按区域为文字添加描边:粗细为 0 表示关闭,「自动」会生成与文字颜色相反的颜色,「主题色」跟随当前主题色。代码块与图标已自动豁免,多色语法不会糊成一团',\r\n strokeWidth: '描边粗细',\r\n strokeColor: '描边颜色',\r\n strokeAuto: '自动反色',\r\n strokeGray: '灰色',\r\n strokeBlack: '黑色',\r\n strokeWhite: '白色',\r\n strokeTheme: '主题色',\r\n strokeCustom: '自定义',\r\n bgTitle: '背景', bgChoose: '选择图片或视频', bgRemove: '移除背景', bgFromUrl: '从网址', bgUrlPlaceholder: '粘贴图片或视频网址 https://…', bgUrlApply: '应用', bgUrlCancel: '取消', bgUrlApplying: '加载中…', bgUrlBadHttp: '仅支持 http/https 图片网址', bgUrlFail: '获取图片失败',\r\n bgEdit: '编辑位置', bgEditLocked: '仅「适应」模式可编辑位置', wpOpacity: '背景透明度', bgBlur: '背景模糊',\r\n bgModeTitle: '布局模式',\r\n bgModeFit: '适应', bgModeFill: '填充', bgModeStretch: '拉伸', bgModeTile: '平铺', bgModeCenter: '居中',\r\n bgVideoBadge: '视频',\r\n bgSourceImage: '图片 / 视频',\r\n bgSourceGenerated: '动态生成',\r\n dropHint: '点击选择图片或视频,或将文件拖到这里',\r\n liveBadge: '动态壁纸',\r\n bgHint: '「适应」布局模式下悬停预览可编辑图片/视频的位置与缩放(其余布局模式按模式自动排布);动态生成模式下可选择类型、预设与参数。绑定种子后刷新页面壁纸保持不变,取消绑定则每次刷新随机换新',\r\n editorTitle: '背景编辑器', editorHint: '拖动移动画面,滚轮或双指缩放大小',\r\n editorCommit: '确认', editorCancel: '取消', editorReset: '重置',\r\n extractColor: '从背景提取主题色', extracting: '取色中…',\r\n extractNoWp: '请先设置背景图片',\r\n extractDone: '已应用背景主色调',\r\n extractFail: '未在背景中找到鲜明的颜色,请换一张背景',\r\n crashTitle: '界面渲染出错',\r\n crashDesc: '主题设置面板遇到问题,点击下方按钮重置后重试',\r\n crashReset: '重置面板',\r\n exportTheme: '导出配置',\r\n importTheme: '导入配置',\r\n exportCardTitle: '导出配置',\r\n exportCardDesc: '将主题色、透明度、模糊与壁纸打包为 dsh-any-theme.json 文件',\r\n importCardTitle: '导入配置',\r\n importCardDesc: '从之前导出的 JSON 文件一键恢复完整主题',\r\n toastExportDone: '配置文件已开始下载',\r\n importDone: '已导入主题配置',\r\n importFail: '导入失败,文件格式不正确',\r\n footerTag: '外观插件',\r\n eyedropper: '从背景取色',\r\n pickerTitle: '从背景取色',\r\n pickerHint: '移动鼠标预览颜色,点击背景选取为主题色',\r\n pickerClose: '关闭',\r\n bgTypeImage: '图片',\r\n bgTypeMesh: '网格渐变',\r\n bgTypeShader: 'Shader',\r\n bgTypePattern: '几何图案',\r\n bgMeshDesc: '柔和的多点渐变色块',\r\n bgShaderDesc: '持续流动的光影动画',\r\n bgPatternDesc: '规律的几何纹理',\r\n bgRegenerate: '重新生成',\r\n bgSeedLocked: '已绑定 · 刷新不变',\r\n bgSeedUnlocked: '未绑定 · 刷新换新',\r\n seedLock: '锁定种子',\r\n bgMeshScale: '扩散范围',\r\n bgMeshIntensity: '色彩强度',\r\n bgShaderPreset: '预设',\r\n bgShaderSpeed: '流动速度',\r\n bgShaderScale: '纹理尺度',\r\n bgPatternPreset: '图案',\r\n bgPatternDensity: '密度',\r\n bgPatternScale: '尺度',\r\n presetAurora: '极光',\r\n presetNebula: '星云',\r\n presetNoise: '流动噪声',\r\n presetDots: '点阵',\r\n presetWaves: '波浪',\r\n presetPoly: '低多边形',\r\n presetStarfield: '星空',\r\n presetRain: '雨滴',\r\n presetContour: '等高线',\r\n presetMeta: '流体光斑',\r\n bgPause: '暂停',\r\n bgResume: '播放',\r\n bgUrlVideoFail: '获取视频失败,请确认链接可直接下载视频文件',\r\n schemeTitle: '界面明暗',\r\n schemeLight: '亮色',\r\n schemeDark: '暗色',\r\n schemeAuto: '自动',\r\n schemeHint: '「自动」优先跟随背景画面的实际明暗决定界面明暗(无背景时依据主题色明度);强制亮色/暗色后整套配色按所选方向生成,未选主题色时使用中性灰配色',\r\n presetGalleryTitle: '外观预设',\r\n presetName_default: '默认',\r\n presetDesc_default: '恢复插件的初始外观',\r\n presetName_glass: '毛玻璃',\r\n presetDesc_glass: '通透表面 + 磨砂玻璃层次',\r\n presetName_minimal: '极简白',\r\n presetDesc_minimal: '接近实色的表面,无模糊',\r\n presetName_midnight: '暗夜紫',\r\n presetDesc_midnight: '深色强调,重磨砂低透明度',\r\n presetName_cyber: '赛博',\r\n presetDesc_cyber: '艳丽洋红,界面近乎消失',\r\n presetName_warm: '暖阳',\r\n presetDesc_warm: '琥珀色调的明亮实色界面',\r\n presetApplied: '预设已应用',\r\n profilesTitle: '我的配置',\r\n profileSave: '保存当前配置',\r\n profileNamePlaceholder: '输入配置名称…',\r\n profileNameRequired: '请先输入配置名称',\r\n profileSaved: '配置已保存',\r\n profileApplied: '配置已应用',\r\n profileApply: '应用',\r\n profileDelete: '删除配置',\r\n profileDeleteConfirm: '确认删除',\r\n profileNone: '不切换',\r\n profilesEmpty: '还没有保存的配置。调整好外观后点击「保存当前配置」,即可随时一键切换。',\r\n scheduleTitle: '昼夜自动切换',\r\n scheduleHint: '按时间或系统深色模式,在两套已保存的配置之间自动切换(切换的是配色与表面参数,壁纸不变)',\r\n scheduleMode: '切换依据',\r\n scheduleModeTime: '固定时段',\r\n scheduleModeSystem: '跟随系统',\r\n scheduleTimes: '切换时间',\r\n scheduleDayStart: '日间开始',\r\n scheduleNightStart: '夜间开始',\r\n scheduleProfiles: '对应配置',\r\n scheduleDayProfile: '日间',\r\n scheduleNightProfile: '夜间',\r\n rotTitle: '壁纸轮换',\r\n rotHint: '把多张图片加入轮换池,按所选频率自动更换壁纸;启用后立即生效',\r\n rotAdd: '添加图片',\r\n rotRemove: '移除',\r\n rotShuffle: '随机',\r\n rotOrder: '顺序',\r\n rotReload: '每次刷新',\r\n rotDaily: '每天',\r\n rotWeekly: '每周',\r\n rotNow: '立即切换',\r\n}\r\n\r\nexport const en: Record<string, string> = {\r\n nav: 'Theme', brandTag: 'Appearance', close: 'Close',\r\n pageColor: 'Color', pageInterface: 'Interface', pageFont: 'Font', pageBackground: 'Background', pageProfile: 'Profile',\r\n descColor: 'Drag the wheel or type exact values — the whole UI follows live',\r\n descInterface: 'Tune opacity and blur per surface to build depth',\r\n descFont: 'Swap the interface typeface with your own font file, and outline text per region so it stays legible over busy wallpapers',\r\n descBackground: 'Upload an image or a video as wallpaper and place it freely, or let the algorithm paint a live background',\r\n descProfile: 'Apply a one-click preset, save multiple named profiles, schedule a day/night switch, or export/import the full theme',\r\n colorTitle: 'Theme color', colorHint: 'Pick hue on the outer ring, adjust saturation & lightness in the square; double-click a slider to reset',\r\n swatchTitle: 'Quick swatches',\r\n hexCaption: 'Current accent',\r\n uiTitle: 'Interface',\r\n uiOpacity: 'Opacity', uiBlur: 'Blur',\r\n uiOpacityBg: 'Main background', uiOpacitySide: 'Sidebar', uiOpacityCard: 'Cards & panels', uiOpacityInput: 'Input & controls',\r\n uiSop: 'Settings interface',\r\n uiChatRegion: 'Conversation text frame',\r\n uiTrajectory: 'Trajectory view',\r\n uiPanelNative: 'Right sidebar',\r\n guideDesc: 'Theme color, wallpaper and interface opacity in the right sidebar',\r\n uiProduced: 'Produced / highlights',\r\n uiHeader: 'Header popovers',\r\n fontPageTitle: 'Font & outline',\r\n fontTitle: 'Custom font',\r\n fontHint: 'Accepts ttf/otf/woff/woff2 files (up to 100MB) and applies them to the whole interface; code blocks keep their monospace stack. CJK fonts routinely span tens of MB, so the first upload and each reload take a moment',\r\n fontUpload: 'Upload font',\r\n fontUploading: 'Uploading…',\r\n fontRemove: 'Remove font',\r\n fontEnabled: 'Font enabled',\r\n fontNone: 'None — host default',\r\n fontFail: 'Upload failed — make sure it is a valid ttf/otf/woff/woff2 file',\r\n uploadTooLarge: 'File is too large (limit {limit})',\r\n bgUploadFail: 'Wallpaper upload failed',\r\n videoUploadFail: 'Video upload failed — this playback will not be saved',\r\n strokeTitle: 'Text outline',\r\n strokeHint: 'Outline text per region: width 0 turns it off, \"auto\" picks the inverse of the text color, and \"theme\" follows the current accent. Code blocks and icons are exempted automatically, so multi-color syntax never smears',\r\n strokeWidth: 'Outline width',\r\n strokeColor: 'Outline color',\r\n strokeAuto: 'Auto contrast',\r\n strokeGray: 'Gray',\r\n strokeBlack: 'Black',\r\n strokeWhite: 'White',\r\n strokeTheme: 'Accent',\r\n strokeCustom: 'Custom',\r\n bgTitle: 'Background', bgChoose: 'Choose image or video', bgRemove: 'Remove background', bgFromUrl: 'From URL', bgUrlPlaceholder: 'Paste an image or video URL https://…', bgUrlApply: 'Apply', bgUrlCancel: 'Cancel', bgUrlApplying: 'Loading…', bgUrlBadHttp: 'Only http/https image URLs are supported', bgUrlFail: 'Could not fetch the image',\r\n bgEdit: 'Edit position', bgEditLocked: 'Position editing is only available in Fit mode', wpOpacity: 'Background opacity', bgBlur: 'Background blur',\r\n bgModeTitle: 'Layout mode',\r\n bgModeFit: 'Fit', bgModeFill: 'Fill', bgModeStretch: 'Stretch', bgModeTile: 'Tile', bgModeCenter: 'Center',\r\n bgVideoBadge: 'Video',\r\n bgSourceImage: 'Image / Video',\r\n bgSourceGenerated: 'Generated',\r\n dropHint: 'Click to choose an image or video, or drop one here',\r\n liveBadge: 'Live wallpaper',\r\n bgHint: 'In Fit layout mode hover the preview to reposition and zoom the image/video (other modes arrange it automatically); in generated mode pick a type, preset and parameters. With the seed locked the wallpaper stays the same across refreshes; unlocked, every refresh randomizes it',\r\n editorTitle: 'Background editor', editorHint: 'Drag to move; scroll or pinch with two fingers to zoom',\r\n editorCommit: 'Confirm', editorCancel: 'Cancel', editorReset: 'Reset',\r\n extractColor: 'Extract from background', extracting: 'Extracting…',\r\n extractNoWp: 'Set a background first',\r\n extractDone: 'Background color applied',\r\n extractFail: 'No vivid color found in this background, try another',\r\n crashTitle: 'Section crashed',\r\n crashDesc: 'The theme panel hit an error. Reset below to recover.',\r\n crashReset: 'Reset panel',\r\n exportTheme: 'Export',\r\n importTheme: 'Import',\r\n exportCardTitle: 'Export profile',\r\n exportCardDesc: 'Bundle color, opacity, blur and wallpaper into dsh-any-theme.json',\r\n importCardTitle: 'Import profile',\r\n importCardDesc: 'Restore a full theme from a previously exported JSON file',\r\n toastExportDone: 'Export started',\r\n importDone: 'Theme imported',\r\n importFail: 'Import failed — invalid file',\r\n footerTag: 'Appearance plugin',\r\n eyedropper: 'Eyedropper',\r\n pickerTitle: 'Pick from background',\r\n pickerHint: 'Hover to preview, click to pick as theme color',\r\n pickerClose: 'Close',\r\n bgTypeImage: 'Image',\r\n bgTypeMesh: 'Mesh gradient',\r\n bgTypeShader: 'Shader',\r\n bgTypePattern: 'Pattern',\r\n bgMeshDesc: 'Soft multi-blob gradients',\r\n bgShaderDesc: 'Flowing light animation',\r\n bgPatternDesc: 'Regular geometric texture',\r\n bgRegenerate: 'Regenerate',\r\n bgSeedLocked: 'Seeded · stable on refresh',\r\n bgSeedUnlocked: 'Unseeded · new on refresh',\r\n seedLock: 'Lock seed',\r\n bgMeshScale: 'Spread',\r\n bgMeshIntensity: 'Intensity',\r\n bgShaderPreset: 'Preset',\r\n bgShaderSpeed: 'Flow speed',\r\n bgShaderScale: 'Texture scale',\r\n bgPatternPreset: 'Pattern',\r\n bgPatternDensity: 'Density',\r\n bgPatternScale: 'Scale',\r\n presetAurora: 'Aurora',\r\n presetNebula: 'Nebula',\r\n presetNoise: 'Flowing noise',\r\n presetDots: 'Dots',\r\n presetWaves: 'Waves',\r\n presetPoly: 'Low poly',\r\n presetStarfield: 'Starfield',\r\n presetRain: 'Rain',\r\n presetContour: 'Contours',\r\n presetMeta: 'Fluid orbs',\r\n bgPause: 'Pause',\r\n bgResume: 'Play',\r\n bgUrlVideoFail: 'Could not fetch the video — make sure the link downloads a video file directly',\r\n schemeTitle: 'Interface scheme',\r\n schemeLight: 'Light',\r\n schemeDark: 'Dark',\r\n schemeAuto: 'Auto',\r\n schemeHint: '\"Auto\" follows the background brightness first (accent lightness as fallback only); forcing light/dark regenerates the palette in that direction - with no accent picked, a neutral gray palette is used',\r\n presetGalleryTitle: 'Appearance presets',\r\n presetName_default: 'Default',\r\n presetDesc_default: 'Restore the plugin\\'s original look',\r\n presetName_glass: 'Frosted glass',\r\n presetDesc_glass: 'Translucent surfaces + frosted depth',\r\n presetName_minimal: 'Minimal',\r\n presetDesc_minimal: 'Near-solid surfaces, no frost',\r\n presetName_midnight: 'Midnight',\r\n presetDesc_midnight: 'Deep violet accent, heavy frost',\r\n presetName_cyber: 'Cyber',\r\n presetDesc_cyber: 'Vivid magenta, vanishing surfaces',\r\n presetName_warm: 'Warm daylight',\r\n presetDesc_warm: 'Amber accent on solid light surfaces',\r\n presetApplied: 'Preset applied',\r\n profilesTitle: 'Saved profiles',\r\n profileSave: 'Save current',\r\n profileNamePlaceholder: 'Profile name…',\r\n profileNameRequired: 'Enter a name first',\r\n profileSaved: 'Profile saved',\r\n profileApplied: 'Profile applied',\r\n profileApply: 'Apply',\r\n profileDelete: 'Delete profile',\r\n profileDeleteConfirm: 'Sure?',\r\n profileNone: 'None',\r\n profilesEmpty: 'No saved profiles yet. Tune the look, then hit \"Save current\" to switch back anytime.',\r\n scheduleTitle: 'Day/night auto switch',\r\n scheduleHint: 'Automatically swap between two saved profiles by clock time or the OS dark mode (colors and surfaces switch; the wallpaper stays)',\r\n scheduleMode: 'Trigger',\r\n scheduleModeTime: 'Fixed times',\r\n scheduleModeSystem: 'Follow system',\r\n scheduleTimes: 'Switch times',\r\n scheduleDayStart: 'Day starts',\r\n scheduleNightStart: 'Night starts',\r\n scheduleProfiles: 'Profiles',\r\n scheduleDayProfile: 'Day',\r\n scheduleNightProfile: 'Night',\r\n rotTitle: 'Wallpaper rotation',\r\n rotHint: 'Add images to a rotation pool and let the wallpaper change on your cadence; takes effect immediately when enabled',\r\n rotAdd: 'Add images',\r\n rotRemove: 'Remove',\r\n rotShuffle: 'Shuffle',\r\n rotOrder: 'In order',\r\n rotReload: 'Every refresh',\r\n rotDaily: 'Daily',\r\n rotWeekly: 'Weekly',\r\n rotNow: 'Switch now',\r\n}\r\n","import type { BgState, ThemeConfig, PartOpacities, PartBlurs, PartStrokes, StrokeConfig, BgMode, ProfileEntry, RotationConfig, RotationItem, ScheduleConfig, SchemeOverride, ProfileAppearance } from './types'\r\n\r\nexport const DEFAULT_CONFIG: ThemeConfig = {\r\n color: null,\r\n // Defaults sit at mid-scale rather than at \"no visible change\" (was 0.85 /\r\n // 0.93 / 1 / 1 with every blur at 0): a fresh install then shows right away\r\n // that the controls are live, instead of looking inert until each slider is\r\n // dragged once. Only affects installs with no persisted config.\r\n // The main background is the deliberate exception: with no persisted config it\r\n // now paints nothing over the wallpaper (opacity 0) and frosts nothing (blur 0),\r\n // so a first launch shows the picture as uploaded.\r\n opacities: { bg: 0, sidebar: 0.5, card: 0.5, input: 0.5 },\r\n // Blur sliders are px-based (0–60), so 50% of their range is 30px — except the\r\n // bg pair above and below, which start untouched.\r\n blurs: { bg: 0, sidebar: 30, card: 30, settings: 30, chat: 30, trajectory: 30, input: 30, panel: 30, produced: 30, header: 30 },\r\n strokes: {\r\n bg: { width: 0, color: 'auto', customColor: '#808080' },\r\n sidebar: { width: 0, color: 'auto', customColor: '#808080' },\r\n card: { width: 0, color: 'auto', customColor: '#808080' },\r\n settings: { width: 0, color: 'auto', customColor: '#808080' },\r\n chat: { width: 0, color: 'auto', customColor: '#808080' },\r\n trajectory: { width: 0, color: 'auto', customColor: '#808080' },\r\n input: { width: 0, color: 'auto', customColor: '#808080' },\r\n panel: { width: 0, color: 'auto', customColor: '#808080' },\r\n produced: { width: 0, color: 'auto', customColor: '#808080' },\r\n header: { width: 0, color: 'auto', customColor: '#808080' },\r\n },\r\n settingsOpacity: 0.5,\r\n // 100% = the background picture untouched. Deliberately NOT part of the\r\n // 50% default batch: halving the wallpaper's own alpha would wash out a\r\n // freshly uploaded picture — the other surface sliders above are mid-scale,\r\n // this one stays opaque.\r\n wallpaperOpacity: 1,\r\n // The 背景 page's own wallpaper blur, 0 for the same reason: a first install\r\n // shows the wallpaper exactly as uploaded.\r\n blur: 0,\r\n bgState: { zoom: 1, x: 0, y: 0, iw: 0, ih: 0 },\r\n videoBgState: { zoom: 1, x: 0, y: 0, iw: 0, ih: 0 },\r\n backgroundType: 'image',\r\n bgMode: 'fit',\r\n videoMime: null,\r\n fontMime: null,\r\n fontEnabled: true,\r\n generatedBg: null,\r\n regenerateOnReload: false,\r\n chatTextOpacity: 0.5,\r\n // 100% = untouched host surface; these all default to mid-scale too.\r\n trajectoryOpacity: 0.5,\r\n panelOpacity: 0.5,\r\n producedOpacity: 0.5,\r\n headerOpacity: 0.5,\r\n profiles: [],\r\n rotation: { enabled: false, mode: 'shuffle', interval: 'daily', current: 0, items: [], lastRotate: null },\r\n schedule: { enabled: false, mode: 'time', dayProfile: null, nightProfile: null, dayStart: '07:00', nightStart: '19:00' },\r\n schemeOverride: 'auto',\r\n activeProfile: null,\r\n}\r\n\r\nconst clamp01 = (n: unknown, def: number): number =>\r\n typeof n === 'number' ? Math.min(1, Math.max(0, n)) : def\r\n\r\n// In-memory mirror of the file-backed store; the UI reads and mutates this,\r\n// and it is synced to disk via the RPC layer.\r\nexport let cfg: ThemeConfig = { ...DEFAULT_CONFIG, opacities: { ...DEFAULT_CONFIG.opacities }, blurs: { ...DEFAULT_CONFIG.blurs }, strokes: structuredClone(DEFAULT_CONFIG.strokes), bgState: { ...DEFAULT_CONFIG.bgState }, videoBgState: { ...DEFAULT_CONFIG.videoBgState } }\r\nexport let wpImageUrl: string | null = null\r\n// Retained across background-type switches so coming back to image/video\r\n// restores the original upload.\r\nexport let wpUrl: string | null = null\r\nexport let wpVideoUrl: string | null = null\r\n/** Captured video frame standing in for previews/color extraction (still-image APIs). */\r\nexport let wpVideoSnapshot: string | null = null\r\n/** Local blob URL backing an in-session video; revoked when replaced or cleared. */\r\nlet wpVideoObjectUrl: string | null = null\r\n\r\nexport function setWpUrl(url: string | null): void { wpUrl = url }\r\n// The serve URL is stable across in-place replacements (upload / URL download /\r\n// rotation), so every swap needs a query-string cache-buster or the URL-keyed\r\n// caches — the layer re-set guard, loadImage decode cache, brightness verdict,\r\n// low-res drag copy, intrinsic-size lookup — all keep the old pixels.\r\nlet imageRev = 0\r\nexport function bumpImageRev(url: string | null): string | null {\r\n if (url === null) return url\r\n // The serve URL is a same-origin relative path (/dsh-any-background/…); the\r\n // rev query must reach those too, or an in-place replacement keeps the same\r\n // backgroundImage string and applyImageWp skips the swap. blob:/data: stay\r\n // intact (a query can break blob resolution).\r\n if (!/^https?:\\/\\//i.test(url) && !url.startsWith('/')) return url\r\n imageRev++\r\n return `${url}${url.includes('?') ? '&' : '?'}r=${imageRev}`\r\n}\r\nexport function setWpImageUrl(url: string | null): void { wpImageUrl = bumpImageRev(url) }\r\n// The serve URL is stable, so replacing the stored video needs a query-string\r\n// cache-buster or the player keeps the cached copy.\r\nlet videoRev = 0\r\nexport function setWpVideoUrl(url: string | null, mime: string | null): void {\r\n if (url === null) {\r\n wpVideoUrl = null\r\n wpVideoSnapshot = null\r\n } else {\r\n videoRev++\r\n // Blob URLs are unique per object; a query string can break their\r\n // resolution in some engines, so they skip the cache-buster.\r\n wpVideoUrl = url.startsWith('blob:') ? url : `${url}${url.includes('?') ? '&' : '?'}r=${videoRev}`\r\n }\r\n // Release the previous in-session object URL when replaced or cleared.\r\n if (wpVideoObjectUrl !== null && wpVideoObjectUrl !== url) {\r\n URL.revokeObjectURL(wpVideoObjectUrl)\r\n wpVideoObjectUrl = null\r\n }\r\n if (url !== null && url.startsWith('blob:')) wpVideoObjectUrl = url\r\n cfg.videoMime = url ? mime : null\r\n}\r\nexport function setWpVideoSnapshot(url: string | null): void { wpVideoSnapshot = url }\r\n\r\n/** Release the in-session video object URL (plugin teardown). */\r\nexport function disposeVideoObjectUrl(): void {\r\n if (wpVideoObjectUrl !== null) {\r\n URL.revokeObjectURL(wpVideoObjectUrl)\r\n wpVideoObjectUrl = null\r\n }\r\n}\r\nexport function setBgState(s: BgState): void { cfg.bgState = s }\r\n\r\n// Brightness verdict of the active generated background, analyzed once per\r\n// switch from a captured frame. null = fall back to the picked color's lightness.\r\nexport let bgDark: boolean | null = null\r\nexport function setBgDark(v: boolean | null): void { bgDark = v }\r\nexport function rBgDark(): boolean | null { return bgDark }\r\n\r\nexport function rHasColor(): boolean { return cfg.color !== null }\r\nexport function rColor(): [number, number, number] { return cfg.color ?? [220, 0.55, 0.25] }\r\nexport function rWpImage(): string | null { return wpImageUrl }\r\nexport function rWpVideo(): string | null { return wpVideoUrl }\r\nexport function rBgMode(): BgMode { return cfg.bgMode ?? DEFAULT_CONFIG.bgMode }\r\nexport function rChatTextOpacity(): number { return clamp01(cfg.chatTextOpacity, DEFAULT_CONFIG.chatTextOpacity) }\r\nexport function rTrajectoryOpacity(): number { return clamp01(cfg.trajectoryOpacity, DEFAULT_CONFIG.trajectoryOpacity) }\r\n/** Display URL: the uploaded image/video snapshot per active type, else the generated snapshot. */\r\nexport function rWp(): string | null {\r\n if (cfg.backgroundType === 'image') return wpImageUrl\r\n if (cfg.backgroundType === 'video') return wpVideoSnapshot\r\n return wpUrl\r\n}\r\nexport function rOps(): PartOpacities {\r\n const o = cfg.opacities ?? {}\r\n const out = {} as PartOpacities\r\n for (const k of ['bg', 'sidebar', 'card', 'input'] as const) {\r\n out[k] = clamp01(o[k], DEFAULT_CONFIG.opacities[k])\r\n }\r\n return out\r\n}\r\nexport function rBlurs(): PartBlurs {\r\n const b = cfg.blurs ?? {}\r\n const out = {} as PartBlurs\r\n for (const k of ['bg', 'sidebar', 'card', 'settings', 'chat', 'trajectory', 'input', 'panel', 'produced', 'header'] as const) {\r\n const v = b[k]\r\n out[k] = typeof v === 'number' ? Math.min(60, Math.max(0, v)) : DEFAULT_CONFIG.blurs[k]\r\n }\r\n return out\r\n}\r\n\r\nconst STROKE_GROUPS = ['bg', 'sidebar', 'card', 'settings', 'chat', 'trajectory', 'input', 'panel', 'produced', 'header'] as const\r\nconst STROKE_COLOR_KEYS = ['auto', 'gray', 'black', 'white', 'theme', 'custom'] as const\r\nconst HEX_RE = /^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/\r\nconst DEFAULT_STROKE: StrokeConfig = { width: 0, color: 'auto', customColor: '#808080' }\r\n\r\nfunction adoptStroke(raw: unknown): StrokeConfig {\r\n const s = (raw ?? {}) as Partial<StrokeConfig>\r\n return {\r\n width: typeof s.width === 'number' && isFinite(s.width) ? Math.min(4, Math.max(0, s.width)) : DEFAULT_STROKE.width,\r\n color: STROKE_COLOR_KEYS.includes(s.color as StrokeConfig['color']) ? s.color as StrokeConfig['color'] : DEFAULT_STROKE.color,\r\n customColor: typeof s.customColor === 'string' && HEX_RE.test(s.customColor) ? s.customColor : DEFAULT_STROKE.customColor,\r\n }\r\n}\r\n\r\n/** Move a possibly-partial strokes map into the full shape the UI reads. */\r\nfunction strokesFrom(raw: unknown): PartStrokes {\r\n const s = (raw ?? {}) as Partial<PartStrokes>\r\n const out = {} as PartStrokes\r\n for (const k of STROKE_GROUPS) out[k] = adoptStroke(s[k])\r\n return out\r\n}\r\n\r\nexport function rStrokes(): PartStrokes {\r\n return strokesFrom(cfg.strokes)\r\n}\r\nexport function rWop(): number { return clamp01(cfg.wallpaperOpacity, DEFAULT_CONFIG.wallpaperOpacity) }\r\nexport function rBl(): number {\r\n return typeof cfg.blur === 'number' ? Math.min(60, Math.max(0, cfg.blur)) : DEFAULT_CONFIG.blur\r\n}\r\nexport function rSop(): number { return clamp01(cfg.settingsOpacity, DEFAULT_CONFIG.settingsOpacity) }\r\nexport function rPanelOpacity(): number { return clamp01(cfg.panelOpacity, DEFAULT_CONFIG.panelOpacity) }\r\nexport function rProducedOpacity(): number { return clamp01(cfg.producedOpacity, DEFAULT_CONFIG.producedOpacity) }\r\nexport function rHeaderOpacity(): number { return clamp01(cfg.headerOpacity, DEFAULT_CONFIG.headerOpacity) }\r\nexport function rBgState(): BgState { return cfg.bgState }\r\nexport function rVideoBgState(): BgState { return cfg.videoBgState }\r\n\r\n// ── Profiles / rotation / schedule / scheme ──────────────────────────────────\r\nexport function rProfiles(): ProfileEntry[] { return Array.isArray(cfg.profiles) ? cfg.profiles : [] }\r\nexport function rRotation(): RotationConfig {\r\n const r = cfg.rotation\r\n return r && typeof r === 'object'\r\n ? { ...DEFAULT_CONFIG.rotation, ...r, items: Array.isArray(r.items) ? r.items : [] }\r\n : { ...DEFAULT_CONFIG.rotation, items: [] }\r\n}\r\nexport function rSchedule(): ScheduleConfig {\r\n return cfg.schedule && typeof cfg.schedule === 'object' ? { ...DEFAULT_CONFIG.schedule, ...cfg.schedule } : { ...DEFAULT_CONFIG.schedule }\r\n}\r\nexport function rSchemeOverride(): SchemeOverride {\r\n return cfg.schemeOverride === 'light' || cfg.schemeOverride === 'dark' ? cfg.schemeOverride : 'auto'\r\n}\r\nexport function rActiveProfile(): string | null { return cfg.activeProfile }\r\n\r\n/** Effective interface scheme (drives data-ds-dark-theme / color-scheme): a\r\n * forced override wins; in auto a picked color decides through its palette\r\n * direction (keeps native controls aligned with the drawn surfaces), and\r\n * without a pick the background's brightness verdict does. Stay light as the\r\n * last fallback. */\r\nexport function rScheme(): 'light' | 'dark' {\r\n const o = rSchemeOverride()\r\n if (o !== 'auto') return o\r\n if (rHasColor()) return rColorScheme()\r\n return rBgDark() ? 'dark' : 'light'\r\n}\r\n\r\n/** Direction the color palette itself is built in: a forced override wins; in\r\n * auto the theme color's own lightness decides (0.2.4 behavior) so surfaces\r\n * always contrast with the palette's label fonts — the wallpaper verdict must\r\n * not drag a dark color's surfaces into a light build (and vice versa) or\r\n * text and surfaces converge. */\r\nexport function rColorScheme(): 'light' | 'dark' {\r\n const o = rSchemeOverride()\r\n if (o !== 'auto') return o\r\n return rHasColor() && rColor()[2] < 0.55 ? 'dark' : 'light'\r\n}\r\n\r\n/** Snapshot of the appearance fields a profile/preset restores. */\r\nexport function currentAppearance(): ProfileAppearance {\r\n return {\r\n color: cfg.color,\r\n opacities: { ...rOps() },\r\n blurs: { ...rBlurs() },\r\n strokes: rStrokes(),\r\n settingsOpacity: rSop(),\r\n wallpaperOpacity: rWop(),\r\n blur: rBl(),\r\n chatTextOpacity: rChatTextOpacity(),\r\n trajectoryOpacity: rTrajectoryOpacity(),\r\n panelOpacity: rPanelOpacity(),\r\n producedOpacity: rProducedOpacity(),\r\n headerOpacity: rHeaderOpacity(),\r\n }\r\n}\r\n\r\n/** Apply an appearance snapshot onto cfg (meta fields untouched). */\r\nexport function applyAppearance(ap: ProfileAppearance): void {\r\n cfg.color = Array.isArray(ap.color) && ap.color.length === 3 ? [...ap.color] as [number, number, number] : null\r\n cfg.opacities = { ...DEFAULT_CONFIG.opacities, ...(ap.opacities ?? {}) }\r\n cfg.blurs = { ...DEFAULT_CONFIG.blurs, ...(ap.blurs ?? {}) }\r\n cfg.strokes = strokesFrom(ap.strokes)\r\n cfg.settingsOpacity = clamp01(ap.settingsOpacity, DEFAULT_CONFIG.settingsOpacity)\r\n cfg.wallpaperOpacity = clamp01(ap.wallpaperOpacity, DEFAULT_CONFIG.wallpaperOpacity)\r\n cfg.blur = typeof ap.blur === 'number' ? Math.min(60, Math.max(0, ap.blur)) : DEFAULT_CONFIG.blur\r\n cfg.chatTextOpacity = clamp01(ap.chatTextOpacity, DEFAULT_CONFIG.chatTextOpacity)\r\n cfg.trajectoryOpacity = clamp01(ap.trajectoryOpacity, DEFAULT_CONFIG.trajectoryOpacity)\r\n cfg.panelOpacity = clamp01(ap.panelOpacity, DEFAULT_CONFIG.panelOpacity)\r\n cfg.producedOpacity = clamp01(ap.producedOpacity, DEFAULT_CONFIG.producedOpacity)\r\n cfg.headerOpacity = clamp01(ap.headerOpacity, DEFAULT_CONFIG.headerOpacity)\r\n}\r\n\r\nconst num = (n: unknown, def: number): number => typeof n === 'number' ? n : def\r\nconst cl = (n: unknown, lo: number, hi: number, def: number): number =>\r\n typeof n === 'number' ? Math.min(hi, Math.max(lo, n)) : def\r\n\r\nconst HHMM_RE = /^([01]\\d|2[0-3]):[0-5]\\d$/\r\n\r\nfunction adoptProfiles(raw: unknown): ProfileEntry[] {\r\n if (!Array.isArray(raw)) return []\r\n const out: ProfileEntry[] = []\r\n for (const item of raw.slice(0, 20)) {\r\n const p = (item ?? {}) as Partial<ProfileEntry>\r\n if (typeof p.id !== 'string' || p.id.length === 0 || p.id.length > 64) continue\r\n if (out.some(e => e.id === p.id)) continue\r\n const ac = (p.config ?? {}) as Partial<ProfileAppearance>\r\n out.push({\r\n id: p.id,\r\n name: typeof p.name === 'string' && p.name.trim() ? p.name.slice(0, 60) : 'Profile',\r\n createdAt: typeof p.createdAt === 'string' ? p.createdAt : '',\r\n config: {\r\n color: Array.isArray(ac.color) && ac.color.length === 3 ? [...ac.color] as [number, number, number] : null,\r\n opacities: { ...DEFAULT_CONFIG.opacities, ...(ac.opacities ?? {}) },\r\n blurs: { ...DEFAULT_CONFIG.blurs, ...(ac.blurs ?? {}) },\r\n strokes: strokesFrom(ac.strokes),\r\n settingsOpacity: clamp01(ac.settingsOpacity, DEFAULT_CONFIG.settingsOpacity),\r\n wallpaperOpacity: clamp01(ac.wallpaperOpacity, DEFAULT_CONFIG.wallpaperOpacity),\r\n blur: num(ac.blur, DEFAULT_CONFIG.blur),\r\n chatTextOpacity: clamp01(ac.chatTextOpacity, DEFAULT_CONFIG.chatTextOpacity),\r\n trajectoryOpacity: clamp01(ac.trajectoryOpacity, DEFAULT_CONFIG.trajectoryOpacity),\r\n panelOpacity: clamp01(ac.panelOpacity, DEFAULT_CONFIG.panelOpacity),\r\n producedOpacity: clamp01(ac.producedOpacity, DEFAULT_CONFIG.producedOpacity),\r\n headerOpacity: clamp01(ac.headerOpacity, DEFAULT_CONFIG.headerOpacity),\r\n },\r\n })\r\n }\r\n return out\r\n}\r\n\r\nfunction adoptRotation(raw: unknown): RotationConfig {\r\n const r = (raw ?? {}) as Partial<RotationConfig>\r\n const items: RotationItem[] = Array.isArray(r.items)\r\n ? r.items\r\n .filter((it): it is RotationItem => {\r\n const i = (it ?? {}) as Partial<RotationItem>\r\n return typeof i?.file === 'string' && /^[\\w-]+\\.(jpg|jpeg|png|gif|webp)$/i.test(i.file)\r\n })\r\n .slice(0, 30)\r\n .map(it => ({ file: it.file, thumb: typeof it.thumb === 'string' && it.thumb.startsWith('data:image/') && it.thumb.length <= 65536 ? it.thumb : '' }))\r\n : []\r\n return {\r\n enabled: r.enabled === true,\r\n mode: r.mode === 'order' ? 'order' : 'shuffle',\r\n interval: r.interval === 'reload' || r.interval === 'weekly' ? r.interval : 'daily',\r\n current: num(r.current, 0),\r\n items,\r\n lastRotate: typeof r.lastRotate === 'string' ? r.lastRotate : null,\r\n }\r\n}\r\n\r\nfunction adoptSchedule(raw: unknown): ScheduleConfig {\r\n const r = (raw ?? {}) as Partial<ScheduleConfig>\r\n return {\r\n enabled: r.enabled === true,\r\n mode: r.mode === 'system' ? 'system' : 'time',\r\n dayProfile: typeof r.dayProfile === 'string' ? r.dayProfile : null,\r\n nightProfile: typeof r.nightProfile === 'string' ? r.nightProfile : null,\r\n dayStart: typeof r.dayStart === 'string' && HHMM_RE.test(r.dayStart) ? r.dayStart : DEFAULT_CONFIG.schedule.dayStart,\r\n nightStart: typeof r.nightStart === 'string' && HHMM_RE.test(r.nightStart) ? r.nightStart : DEFAULT_CONFIG.schedule.nightStart,\r\n }\r\n}\r\n\r\nfunction adoptBgState(s: Partial<BgState>): BgState {\r\n return {\r\n zoom: num(s.zoom, 1),\r\n x: num(s.x, 0),\r\n y: num(s.y, 0),\r\n iw: typeof s.iw === 'number' && s.iw > 0 ? s.iw : 0,\r\n ih: typeof s.ih === 'number' && s.ih > 0 ? s.ih : 0,\r\n }\r\n}\r\n\r\n/** Move a possibly-absent partial config into the shape the UI reads. */\r\nexport function adoptConfig(raw: unknown): void {\r\n const c = (raw ?? {}) as Partial<ThemeConfig> & { opacity?: unknown }\r\n const color = Array.isArray(c.color) && c.color.length === 3\r\n ? [c.color[0], c.color[1], c.color[2]] as [number, number, number]\r\n : null\r\n // Migration: the old single main-interface opacity becomes per-part, keeping\r\n // the sidebar's former +0.08 offset.\r\n const legacy = typeof c.opacity === 'number' ? c.opacity : null\r\n const ops = (c.opacities ?? {}) as Partial<PartOpacities>\r\n const bl = (c.blurs ?? {}) as Partial<PartBlurs>\r\n const blurs = {} as PartBlurs\r\n for (const k of ['bg', 'sidebar', 'card', 'settings', 'chat', 'trajectory', 'input', 'panel', 'produced', 'header'] as const) {\r\n blurs[k] = num(bl[k], DEFAULT_CONFIG.blurs[k])\r\n }\r\n const bgType = ['video', 'mesh', 'shader', 'pattern'].includes(c.backgroundType as string)\r\n ? (c.backgroundType as ThemeConfig['backgroundType'])\r\n : DEFAULT_CONFIG.backgroundType\r\n const bgMode = (['fit', 'fill', 'stretch', 'tile', 'center'] as BgMode[]).includes(c.bgMode as BgMode) ? (c.bgMode as BgMode) : DEFAULT_CONFIG.bgMode\r\n const gen = c.generatedBg && typeof c.generatedBg === 'object'\r\n ? (c.generatedBg as { type?: string })\r\n : null\r\n const generatedBg = gen && gen.type === bgType ? (c.generatedBg as ThemeConfig['generatedBg']) : null\r\n\r\n cfg = {\r\n color,\r\n opacities: {\r\n bg: num(ops.bg, legacy ?? DEFAULT_CONFIG.opacities.bg),\r\n sidebar: num(ops.sidebar, legacy !== null ? Math.min(1, legacy + 0.08) : DEFAULT_CONFIG.opacities.sidebar),\r\n card: num(ops.card, DEFAULT_CONFIG.opacities.card),\r\n input: num(ops.input, DEFAULT_CONFIG.opacities.input),\r\n },\r\n blurs,\r\n strokes: strokesFrom(c.strokes),\r\n settingsOpacity: num(c.settingsOpacity, DEFAULT_CONFIG.settingsOpacity),\r\n wallpaperOpacity: num(c.wallpaperOpacity, DEFAULT_CONFIG.wallpaperOpacity),\r\n blur: num(c.blur, DEFAULT_CONFIG.blur),\r\n bgState: adoptBgState((c.bgState ?? {}) as Partial<BgState>),\r\n videoBgState: adoptBgState((c.videoBgState ?? {}) as Partial<BgState>),\r\n backgroundType: bgType,\r\n bgMode,\r\n videoMime: typeof c.videoMime === 'string' ? c.videoMime : null,\r\n fontMime: typeof c.fontMime === 'string' ? c.fontMime : null,\r\n fontEnabled: typeof c.fontEnabled === 'boolean' ? c.fontEnabled : DEFAULT_CONFIG.fontEnabled,\r\n generatedBg: generatedBg ? normalizeGeneratedBg(generatedBg) : null,\r\n regenerateOnReload: typeof c.regenerateOnReload === 'boolean' ? c.regenerateOnReload : DEFAULT_CONFIG.regenerateOnReload,\r\n chatTextOpacity: clamp01(c.chatTextOpacity, DEFAULT_CONFIG.chatTextOpacity),\r\n trajectoryOpacity: clamp01(c.trajectoryOpacity, DEFAULT_CONFIG.trajectoryOpacity),\r\n panelOpacity: clamp01(c.panelOpacity, DEFAULT_CONFIG.panelOpacity),\r\n producedOpacity: clamp01(c.producedOpacity, DEFAULT_CONFIG.producedOpacity),\r\n headerOpacity: clamp01(c.headerOpacity, DEFAULT_CONFIG.headerOpacity),\r\n profiles: adoptProfiles(c.profiles),\r\n rotation: adoptRotation(c.rotation),\r\n schedule: adoptSchedule(c.schedule),\r\n schemeOverride: c.schemeOverride === 'light' || c.schemeOverride === 'dark' ? c.schemeOverride : 'auto',\r\n activeProfile: typeof c.activeProfile === 'string' ? c.activeProfile : null,\r\n }\r\n}\r\n\r\nfunction normalizeGeneratedBg(p: ThemeConfig['generatedBg']): ThemeConfig['generatedBg'] {\r\n if (!p) return null\r\n if (p.type === 'mesh') {\r\n return {\r\n type: 'mesh',\r\n seed: num(p.seed, 0),\r\n scale: cl(p.scale, 0.3, 3, 1),\r\n intensity: cl(p.intensity, 0, 1, 0.6),\r\n }\r\n }\r\n if (p.type === 'shader') {\r\n return {\r\n type: 'shader',\r\n preset: ['aurora', 'nebula', 'noise', 'starfield'].includes(p.preset) ? p.preset : 'aurora',\r\n speed: cl(p.speed, 0, 2, 0.3),\r\n scale: cl(p.scale, 0.3, 3, 1),\r\n seed: typeof p.seed === 'number' ? Math.floor(p.seed) : 0,\r\n }\r\n }\r\n return {\r\n type: 'pattern',\r\n preset: ['dots', 'waves', 'poly', 'rain', 'contour', 'meta'].includes(p.preset) ? p.preset : 'dots',\r\n density: cl(p.density, 0, 1, 0.5),\r\n scale: cl(p.scale, 0.3, 3, 1),\r\n seed: typeof p.seed === 'number' ? Math.floor(p.seed) : 0,\r\n }\r\n}\r\n","/**\n * Single source of truth for what a DSH release IS, and which adapter answers\n * for a release the plugin has never seen.\n *\n * Shared by both halves of the plugin: the node half resolves the release from\n * disk (see `detect.ts`) and ships the verdict to the client half, which uses it\n * to pick a per-version adapter (see `client/host-compat/versions/`). Keeping the\n * bucketing here means the two halves can never disagree about what `0.1.6-alpha`\n * means — a drifted matcher on one side would silently hand the client a channel\n * the client's registry has no adapter for.\n *\n * @module\n */\n\n/** Adapter channels the plugin ships an adapter for: a patch line plus its\n * prerelease channel, so `0.1.5-rc.2` and a hypothetical `0.1.5-beta.1` are NOT\n * the same answer. `unknown` is the \"could not determine the release\" bucket,\n * not a release.\n *\n * `0.1.7-alpha` and `0.1.7-rc` share a patch line but not an answer: the menu\n * paint moved to `MenuSurface`'s own layer at `0.1.7-rc.2`, which is a fact about\n * the host's CSS that no amount of \"same line\" reasoning carries over. A line is\n * only as unified as its verified facts.\n *\n * `0.2.0-rc.2` is keyed down to the BUILD because the line split against that\n * scheme: `0.2.0-rc.1` and `0.2.0-rc.2` are the same patch line AND the same\n * prerelease channel, yet rc.2 renamed the token a sticky menu group heading\n * paints from, so the rc.1 answer is no longer complete for it. When one channel\n * name cannot hold both halves of a line, the half that opened the new facts is\n * named for the build that opened them, and `classifyRelease`'s \"highest verified\n * row at or below the host\" hands every later `0.2.0-rc` (and `0.2.0` stable) to\n * it. */\nexport type HostChannel =\n | '0.1.5-rc'\n | '0.1.6-alpha'\n | '0.1.7-alpha'\n | '0.1.7-rc'\n | '0.2.0-rc'\n | '0.2.0-rc.2'\n | '0.2.1-alpha'\n | 'unknown'\n\n/** A known channel — one that has a real adapter. */\nexport type KnownChannel = Exclude<HostChannel, 'unknown'>\n\n/** A release the plugin verified an adapter against. Oldest first. */\nexport interface SupportedRelease {\n readonly channel: KnownChannel\n /** The build the folder's facts were checked against. It orders the table, so\n * bumping it is part of re-verifying an adapter against a newer build. */\n readonly release: string\n}\n\n/** What this plugin supports, in upgrade order. One row = one build whose facts\n * were checked; several rows may share a `channel` when a newer build was\n * verified as needing no change to that folder's adapter (as `0.1.7-rc.1` was) —\n * a row then reports `exact` instead of `line`, and no new folder appears.\n * Rows may ALSO share a patch line while carrying different channels, which is\n * how a line says \"the facts changed halfway through it\" (`0.1.7-alpha.2` and\n * `0.1.7-rc.1` speak for `0.1.7-alpha`, `0.1.7-rc.2` opens `0.1.7-rc`, and\n * `0.2.0-rc.2` opens a second answer on a line that had one — see the note on\n * `HostChannel` for why that row is keyed to the build).\n * Adding an ADAPTER means adding a channel plus a folder in\n * `client/host-compat/versions/`. */\nexport const SUPPORTED_RELEASES: readonly SupportedRelease[] = [\n { channel: '0.1.5-rc', release: '0.1.5-rc.2' },\n { channel: '0.1.6-alpha', release: '0.1.6-alpha.2' },\n { channel: '0.1.7-alpha', release: '0.1.7-alpha.2' },\n { channel: '0.1.7-alpha', release: '0.1.7-rc.1' },\n { channel: '0.1.7-rc', release: '0.1.7-rc.2' },\n { channel: '0.2.0-rc', release: '0.2.0-rc.1' },\n { channel: '0.2.0-rc.2', release: '0.2.0-rc.2' },\n { channel: '0.2.1-alpha', release: '0.2.1-alpha.1' },\n]\n\n/** How the chosen adapter relates to the release that was detected. Reported so a\n * guess never reads as a verified match:\n * · `exact` — the host is on a build this table was checked against.\n * · `line` — a different build of a VERIFIED patch line (`0.1.6-alpha.4`, or a\n * future `0.1.6` stable); same line, so the adapter normally holds.\n * · `nearest` — no verified line covers it, so the closest one is clamped to:\n * the newest above everything for a newer host, the oldest for an older one.\n * · `unresolved` — no release parsed at all; the DOM arbitrates. */\nexport type ChannelMatch = 'exact' | 'line' | 'nearest' | 'unresolved'\n\n/** The adapter to use, and how much trust that answer deserves. */\nexport interface HostVerdict {\n readonly channel: HostChannel\n readonly match: ChannelMatch\n}\n\n/** Resolved host facts, as they travel node → client over the `read` payload. */\nexport interface HostInfo {\n /** Full detected release string (`0.1.6-alpha.2`), or null when undetermined. */\n version: string | null\n /** Channel derived from `version`, used to pick an adapter. */\n channel: HostChannel\n}\n\nexport const UNKNOWN_HOST_INFO: HostInfo = { version: null, channel: 'unknown' }\n\n/** True when a string looks like a release version. A bare `~/.dsh` directory\n * basename does not, which is why the disk probe sanity-checks before trusting\n * a path segment. */\nconst VERSION_RE = /^\\d+\\.\\d+\\.\\d+(?:-[0-9A-Za-z.-]+)?$/\n\nexport function looksLikeVersion(value: string): boolean {\n return VERSION_RE.test(value)\n}\n\n/** A release broken into the parts that decide an adapter. `channel` is the FIRST\n * prerelease identifier (`rc` in `0.1.5-rc.3`, `alpha` in `0.1.7-alpha.1`) — that\n * is the half of the tag stating which development line the build belongs to;\n * `build` is only a counter within that line. */\ninterface Parsed {\n readonly core: readonly [number, number, number]\n readonly channel: string | null\n readonly build: number | null\n}\n\nconst PARSE_RE = /^(\\d+)\\.(\\d+)\\.(\\d+)(?:-([0-9A-Za-z.-]+))?$/\n\nfunction parse(version: string): Parsed | null {\n const m = PARSE_RE.exec(version)\n if (m === null) return null\n const parts = m[4] === undefined ? [] : m[4].split('.')\n const build = parts.length > 1 ? Number(parts[1]) : NaN\n return {\n core: [Number(m[1]), Number(m[2]), Number(m[3])],\n channel: parts.length > 0 ? parts[0]! : null,\n build: Number.isFinite(build) ? build : null,\n }\n}\n\n/** The table, parsed once: every row is a literal this file controls. */\nconst TABLE = SUPPORTED_RELEASES.map(row => ({ ...row, parsed: parse(row.release)! }))\n\nfunction cmpCore(a: readonly [number, number, number], b: readonly [number, number, number]): number {\n for (let i = 0; i < 3; i++) {\n if (a[i] !== b[i]) return a[i]! < b[i]! ? -1 : 1\n }\n return 0\n}\n\n/** Total order over releases, following the semver rule that a prerelease sorts\n * BELOW the release it precedes (`0.1.6-alpha.2 < 0.1.6`). */\nfunction cmp(a: Parsed, b: Parsed): number {\n const core = cmpCore(a.core, b.core)\n if (core !== 0) return core\n if (a.channel === null || b.channel === null) {\n if (a.channel === b.channel) return 0\n return a.channel === null ? 1 : -1\n }\n if (a.channel !== b.channel) return a.channel < b.channel ? -1 : 1\n const ab = a.build ?? 0\n const bb = b.build ?? 0\n return ab === bb ? 0 : ab < bb ? -1 : 1\n}\n\n/** Pick the adapter for a release, clamping to the nearest verified line when the\n * release is outside everything this plugin has seen.\n *\n * A release is matched by PATCH LINE before anything else: `0.1.6-alpha.4` and a\n * future `0.1.6` stable both belong to the line verified at `0.1.6-alpha.2`, and\n * handing them that adapter beats giving up — the DOM probes only cover panel\n * mechanics, not the surface decisions the line is known for.\n *\n * Outside every verified line the answer is a guess, so it is the closest one and\n * it says so (`nearest`): newer than the newest line → that newest adapter, older\n * than the oldest → the oldest, strictly between two → the LOWER one, because an\n * adapter may only claim what it was verified for. A release that will not parse\n * at all is `unknown`, and the DOM arbitrates there. */\nexport function classifyRelease(version: string | null): HostVerdict {\n const host = version === null ? null : parse(version)\n if (host === null) return { channel: 'unknown', match: 'unresolved' }\n\n const sameLine = TABLE.filter(row => cmpCore(row.parsed.core, host.core) === 0)\n if (sameLine.length > 0) {\n // `exact` names THE BUILD the row was checked against, not its channel: a\n // channel-only test would call `0.1.7-alpha.4` exact against a table verified\n // at `alpha.2`, and `line` exists precisely so an unverified build says so.\n const exact = sameLine.find(row => row.release === version)\n if (exact !== undefined) return { channel: exact.channel, match: 'exact' }\n // A patch line may carry several verified builds AND several channels, so take\n // the highest row at or below the host: an unverified newer build gets the\n // newest verification that precedes it, whichever folder that was\n // (`0.1.7-rc.3` → the `0.1.7-rc` facts checked at rc.2, not the alpha ones), and\n // one older than every row falls back to the line's first, since the folder's\n // facts were derived from that shape.\n const atOrBelow = sameLine.filter(row => cmp(row.parsed, host) <= 0)\n const chosen = atOrBelow.length > 0 ? atOrBelow[atOrBelow.length - 1]! : sameLine[0]!\n return { channel: chosen.channel, match: 'line' }\n }\n\n const older = TABLE.filter(row => cmp(row.parsed, host) < 0)\n if (older.length === 0) return { channel: TABLE[0]!.channel, match: 'nearest' }\n const newer = TABLE.filter(row => cmp(row.parsed, host) > 0)\n if (newer.length === 0) return { channel: TABLE[TABLE.length - 1]!.channel, match: 'nearest' }\n return { channel: older[older.length - 1]!.channel, match: 'nearest' }\n}\n\n/** The channel a release maps onto — the verdict's answer without the confidence. */\nexport function channelOf(version: string | null): HostChannel {\n return classifyRelease(version).channel\n}\n\n/** Prerelease tag of a release string (`alpha.2` in `0.1.6-alpha.2`), or null\n * when the version is bare/undetermined. Needed because a channel is coarser\n * than reality: `conversation.session.header.leading` ships in exactly one\n * build within the 0.1.6-alpha line. */\nexport function prereleaseOf(version: string | null): string | null {\n if (version === null) return null\n const m = /^\\d+\\.\\d+\\.\\d+-([0-9A-Za-z.-]+)$/.exec(version)\n return m?.[1] ?? null\n}\n","/**\n * Selector + declaration vocabulary shared by every per-version adapter.\n *\n * These are the ANCHORS, not the decisions. What varies between releases (which\n * element slides, whether the panel needs promoting, which header slot keys\n * exist) is answered in the version folders; what is stable across all of them\n * lives here so no adapter has to re-type a host selector and get it subtly wrong.\n *\n * Verified against the harness release tags (dsh-v0.1.5-rc.2 … dsh-v0.2.1-alpha.1),\n * not inferred:\n * · `[data-sidebar-right-panel]` — emitted by `ui-sidebar-right/shell/SidebarRight.tsx`\n * on every release in range, with values `push` | `fullscreen`.\n * · `[data-dockkit-host]` / `[data-dockkit-empty]` — emitted ONLY by\n * `ui-dockkit/components/TabLayout.tsx`, a file that first appears at\n * 0.1.7-alpha.1. Dockkit itself EXISTS earlier (its `TabMenu` carries\n * `[data-dockkit-tab-menu]` on every release), so only these two attributes\n * are the 0.1.7 marker — never test \"is dockkit installed\".\n * · `[data-dsh-bottom-panel]` — the optional dsh-better-sidebar workbench, not\n * a host element at all. It is a single element on every release, which is\n * why it needs no version arm.\n * · `[data-plugin-panel]` / `[data-plugin-scope] > ul` — emitted by\n * `ui-plugin-manager/src/client/PluginManagerPage.tsx`. That package is NEW AT\n * 0.1.6-alpha.2: `git ls-tree` shows it absent from 0.1.5-rc.2, 0.1.5-rc.3 and\n * 0.1.6-alpha.1, where the plugin list lived in `ui-settings-plugin-inventory`\n * under `[data-plugin-scope]` alone — no `[data-plugin-panel]`, and no card\n * `ul` in that group either. The three anchors this rule matches — `section\n * [data-plugin-panel]`, `section[data-plugin-scope] > ul.cards` and\n * `section[data-plugin-loading] > ul.cards` — are re-emitted unchanged at\n * `0.2.0-rc.2` and `0.2.1-alpha.1` (checked per tag in `PluginManagerPage.tsx`),\n * so the ONE rule below serves every tag that emits the page.\n *\n * @module\n */\n\nimport type { MenuSurfaceFacts } from './types'\n\n/** The host's own right Sidebar wrapper. */\nexport const PANEL_WRAPPER = '[data-sidebar-right-panel]'\n\n/** The same wrapper in its fullscreen state; the host raises its own z-index to 40. */\nexport const PANEL_FULLSCREEN = '[data-sidebar-right-panel=\"fullscreen\"]'\n\n/** The docked children a 0.1.7+ panel slides — the panel itself stays put. */\nexport const DOCKKIT_SLIDERS =\n '[data-sidebar-right-panel] [data-dockkit-host=\"dock\"],[data-sidebar-right-panel] [data-dockkit-empty]'\n\n/** The third-party workbench panel, one element on every release. Owned by the\n * PRODUCED slider (0.3.2): a conversation artifact that happens to open in a\n * panel, not a page column — so it fades and frosts with the produced surfaces. */\nexport const BETTER_SIDEBAR_PANEL = '[data-dsh-bottom-panel]'\n\n/** The cards that take the composer seat away from the input bar: approval\n * (`ui-approval`), plan review and the question composer (`ui-user-questions`).\n * They are siblings of `[data-composer-card]`, not its children — the seat\n * renders the elected takeover beside the fallback bar (verified per tag in\n * `ConversationContent.tsx` and both packages' `slots.inject('conversation.composer')`)\n * — and each paints the capsule's own `--dsw-specific-input-major`, from\n * `dsh-v0.1.5-rc.2` through `dsh-v0.2.1-alpha.1`.\n *\n * The marker sits on the wrapper, the fill on its child card:\n * `[data-approval-key] > div`, `[data-plan-review-key] > section`,\n * `[data-question-key] > section`. */\nexport const COMPOSER_TAKEOVER_CARD =\n '[data-approval-key]>div,[data-plan-review-key]>section,[data-question-key]>section'\n\n/** The takeover cards' free-text answer field — only the question composer has\n * one (approval and plan review are button rows). Form controls do not inherit\n * text properties, so the stroke group needs the editor spelled out; appending\n * a suffix to `COMPOSER_TAKEOVER_CARD` would bind to its LAST arm only. */\nexport const COMPOSER_TAKEOVER_EDITOR = '[data-question-key]>section textarea'\n\n/** Every surface the panel opacity slider owns — the host's own right Sidebar.\n * Layout-neutral token re-scope. (The dsh-better-sidebar workbench used to be\n * listed here; it moved to the produced group, see `PRODUCED_RULE`.) */\nexport const PANEL_SURFACES = PANEL_WRAPPER\n\n/** DOM-shape test for \"this is NOT a 0.1.7-style frame\". Used ONLY by the\n * unresolved adapter, where the DOM is the authority because the release is not. */\nexport const WITHOUT_DOCKKIT_FRAME = ':not(:has([data-dockkit-host],[data-dockkit-empty]))'\n\n/** The panel blur declaration pair. Both prefixes because Safari needs the\n * `-webkit-` one and the cascade must not let them disagree. */\nexport function panelBlurRule(selectors: string): string {\n return `${selectors}{` +\n '-webkit-backdrop-filter:var(--dsh-any-blur-panel,none);' +\n 'backdrop-filter:var(--dsh-any-blur-panel,none)}'\n}\n\n/**\n * The plugin-manager page's frosted card block, for the releases that ship it.\n *\n * `设置 → 插件` lists each group's plugins in a `ul` that has NO surface of its\n * own — measured live on 0.1.7-alpha.1: a transparent flex column, 2px gaps, each\n * `li` transparent with a 12px radius. With the settings surfaces faded, the whole\n * table floats straight on the wallpaper. This frames each group's list the way the\n * composer capsule is framed: a rounded block on an `::before` underlay.\n *\n * Which releases emit the page decides who gets this string — see `pluginPageRule`\n * in each version folder.\n *\n * The card `ul` is matched through TWO scopes. `0.2.0-rc.1` added a first-read\n * `ListSkeleton` that reuses `.cards` under `section[data-plugin-loading]`, so a\n * rule keyed on `[data-plugin-scope]` alone would show the real list frosted and\n * the loading list bare, then re-frost the block when the data lands. Hosts before\n * that never emit the attribute, so the extra selector is inert rather than a\n * version branch.\n *\n * BINDING, and why it is not just \"put it in the dialog\": the block paints from\n * `--dsh-any-bg-settings-surface` and frosts from `--dsh-any-blur-settings`, i.e.\n * the settings-opacity / settings-blur pair. On 0.1.7 the page is a child of\n * `centerCol`, NOT of the settings dialog (and from `0.1.7-rc.2` the dialog is a\n * `createPortal` beside `#root`, so it is further away still), therefore\n * `SETTINGS_STYLE_RULE`'s token\n * re-scope never reaches it and the list would otherwise follow the homepage card\n * alpha; reading the plugin-owned variables off `:root` puts them under the slider\n * that owns this page. The `var(--dsw-alias-bg-layer-2)` fallback covers the window\n * before the first `applySettingsOverrides` write.\n *\n * The frost rides an underlay because backdrop-filter must never sit directly on a\n * host part (containing block + backdrop root), and the `isolation` is what keeps\n * the underlay's `z-index:-1` inside the block instead of escaping behind the frame.\n * The `:has([role=\"dialog\"])` valve matters here more than anywhere else: every row\n * carries a `plugins.item` slot that third-party plugins fill with their own\n * controls, so a dialog can legitimately open inside the list.\n */\nexport const PLUGIN_PAGE_FROST_RULE =\n '[data-plugin-panel] [data-plugin-scope]>ul,[data-plugin-panel] [data-plugin-loading]>ul{' +\n 'position:relative;isolation:isolate;padding:8px;border-radius:14px}' +\n '[data-plugin-panel] [data-plugin-scope]>ul:has([role=\"dialog\"]),' +\n '[data-plugin-panel] [data-plugin-loading]>ul:has([role=\"dialog\"]){isolation:auto}' +\n '[data-plugin-panel] [data-plugin-scope]>ul::before,' +\n '[data-plugin-panel] [data-plugin-loading]>ul::before{' +\n 'content:\"\";position:absolute;inset:0;z-index:-1;pointer-events:none;border-radius:inherit;' +\n 'background:var(--dsh-any-bg-settings-surface,var(--dsw-alias-bg-layer-2));' +\n '-webkit-backdrop-filter:var(--dsh-any-blur-settings,none);' +\n 'backdrop-filter:var(--dsh-any-blur-settings,none)}'\n\n/** The host's own `ui-theme` name for \"dropdowns, popovers, suggestion lists\", and\n * the token the plugin has always remapped onto the card slider. Whether it still\n * reaches a menu's paint is the question `MenuSurfaceFacts` below answers — from\n * `0.1.7-rc.2` the host aliases it AWAY from the menu layer, so declaring it alone\n * fades the non-`MenuSurface` overlays and nothing else. */\nexport const MENU_FILL_TOKEN = '--dsw-specific-menu'\n\n/** Frost by filtering the element itself — the only option where the element is the\n * thing that paints, and the shape every release up to `0.1.7-rc.1` presents. Both\n * prefixes because Safari needs the `-webkit-` one and the cascade must not let\n * them disagree. */\nexport function elementFrostDecl(value: string): string {\n return `-webkit-backdrop-filter:${value};backdrop-filter:${value}`\n}\n\n/**\n * ── Where a menu's paint lives ────────────────────────────────────────────────\n * Verified by reading the emitting source at each tag, not inferred from a changelog.\n *\n * `dsh-v0.1.5-rc.2` … `dsh-v0.1.7-rc.1`: the menu ELEMENT paints itself. Its own\n * CSS module declares `background:var(--dsw-specific-menu)` — 11 files at\n * 0.1.5-rc.2/rc.3 and 0.1.6-alpha.1/alpha.2, 15 at 0.1.7-alpha.1/alpha.2, 16 at\n * rc.1 (`Menu`, `MenuView`, `PopupSelectView`, `ModelSelect`, `dockkit` TabMenu,\n * `stat-dialog`, `QueueDock`, `ContextMeter`, `TodoPanel`, `GoalBar`,\n * `JobListAction`, `HoverCard`, `ScheduleCatalogAction`, `SubagentHeaderLineage`,\n * `TeamAction`, `CordisPanel`). One token therefore paints every menu, and\n * filtering the element is the arm that reaches it.\n * Frost is a separate, later fact, and worth recording because it changes what\n * the plugin is doing on the older tags: `--dsw-menu-backdrop-filter` has ZERO\n * consumers before `0.1.7-alpha.1` (15 there, 16 at rc.1). On `0.1.5`/`0.1.6` the\n * host frosts no menu at all, so the card/header blur sliders are the only reason\n * a menu has a frost there — which is why the declaration goes on the element\n * rather than into a host token the host does not read.\n *\n * `dsh-v0.1.7-rc.2` (npm `latest`) and `dsh-v0.2.0-rc.1`: `TabMenu`, `MenuView`,\n * `PopupSelectView`, `ModelSelect` and `Menu` all render through the new\n * `ui-primitives/src/MenuSurface.tsx` (byte-identical between the two tags),\n * which leaves the element unpainted and draws on a `z-index:-1` child instead\n * (`MenuSurface.module.css` `.material`: `background:var(--dsw-menu-surface-fill)`\n * + `backdrop-filter:var(--dsw-menu-backdrop-filter)`). The four menu stylesheets\n * that used to paint the old token (Menu/MenuView/PopupSelectView/dockkit TabMenu)\n * drop it at rc.2, which is why the painter count goes 16 → 14.\n * Two consequences, both measured from those files:\n * · the host FLIPPED ITS ALIAS — `design-platform.css` now declares\n * `--dsw-specific-menu:var(--dsw-menu-surface-fill)` where every earlier\n * release declared the reverse. So a plugin that retints only the old token\n * writes a value nothing on a menu any longer reads, and the card / header\n * opacity sliders go inert on exactly the surfaces they were built for.\n * · that child layer exists on purpose: its comment says filtering only the\n * background \"keeps nested menus and fixed overlays free of an ancestor\n * backdrop root\", and the surface sets `isolation:isolate`. Filtering the\n * element anyway installs the backdrop root the layer was written to avoid.\n * The frost therefore rides `--dsw-menu-backdrop-filter`, whose consumer set is\n * the same 14 stylesheets at both tags (stat dialog, queue dock, context meter,\n * todo panel, goal bar, job list, `HoverCard`, `PickerPopover`/`TaskMenu`/\n * `ScheduleCatalogAction`, the subagent lineage, `TeamAction`, `CordisPanel`,\n * `MenuSurface` itself) — re-declaring the token reaches the frost whoever ends up\n * applying it, and does not depend on any element being the painting element.\n *\n * `dsh-v0.2.0-rc.2` (npm `latest`) and `dsh-v0.2.1-alpha.1`: the layer and the frost\n * are the same files — `MenuSurface.tsx` and `MenuSurface.module.css` are\n * byte-identical to rc.1, and every `--dsw-menu-backdrop-filter` consumer is too —\n * but the sticky GROUP HEADING inside those menus changed owner. Through rc.1 the\n * only grouped menu was `ModelSelect`, whose own stylesheet painted that heading\n * from the menu token (`ModelSelect.module.css` `.groupTitle{position:sticky;\n * background:var(--dsw-specific-menu)}`), so the card slider drove it and a picked\n * wallpaper color tinted it. At rc.2 the rule is deleted and both grouped popups\n * (`ModelSelect`, `PopupSelectView`) render the new `ui-primitives/MenuGroup.tsx`,\n * whose heading stays transparent until `data-stuck` and then paints\n * `--dsw-alias-menu-group-header-fill` (light `rgba(248,249,250,.94)`, dark\n * `rgba(48,49,54,.94)`, declared in the `body` blocks of `design-platform.css`).\n * The surface did not go away — its token was RENAMED, and `ModelSelect.module.css`\n * is the one `--dsw-specific-menu` consumer that disappears at rc.2. Left alone, it\n * is the single menu element the fade no longer reaches: an untinted, near-opaque\n * band sitting on top of every row in the list the moment that list scrolls.\n */\n/** The answer for the releases whose menus paint themselves: `0.1.5-rc`,\n * `0.1.6-alpha`, `0.1.7-alpha`. The unresolved bucket is its own variant below. */\nexport const LEGACY_MENU_SURFACE: MenuSurfaceFacts = {\n fillTokens: [MENU_FILL_TOKEN],\n frostDecl: elementFrostDecl,\n}\n\n/** The answer for `0.1.7-rc` (`0.1.7-rc.2` onward) and `0.2.0-rc`. The old token\n * stays in the list on purpose: 14 surfaces in the same claim set still paint their\n * fill from it — the lineage tree, `CordisPanel`, the stat dialog, `QueueDock`,\n * `TodoPanel`, `ContextMeter`, `GoalBar`, `JobListAction`, `HoverCard`, `TeamAction`,\n * `ModelSelect`'s own card and the schedule trio (`PickerPopover`, `TaskMenu`,\n * `ScheduleCatalogAction`) — while the shared menus moved to\n * `--dsw-menu-surface-fill`. Dropping either name fades one half of that set. */\nexport const LAYERED_MENU_SURFACE: MenuSurfaceFacts = {\n fillTokens: [MENU_FILL_TOKEN, '--dsw-menu-surface-fill'],\n frostDecl: value => `--dsw-menu-backdrop-filter:${value}`,\n}\n\n/** The fill the sticky group heading of a shared menu paints from — `MenuGroup`'s\n * own contribution to the menu's look, first emitted at `0.2.0-rc.2`. */\nexport const MENU_GROUP_HEADER_FILL_TOKEN = '--dsw-alias-menu-group-header-fill'\n\n/** The answer for `0.2.0-rc` from `0.2.0-rc.2` and for `0.2.1-alpha`: everything\n * `LAYERED_MENU_SURFACE` says, plus the heading `MenuGroup` renamed.\n *\n * Riding `fillTokens` rather than being left out is a decision with evidence on\n * both sides, so state it: the host's README calls this token \"independent of the\n * menu material\" and gives it a 94% fill while the surface layer sits at 58%/45%.\n * That is a choice about an OPAQUE menu. This plugin's whole product is a menu the\n * wallpaper shows through, and one release earlier the very same heading read the\n * very same token as the card it sits on — so following it keeps rc.1's contract\n * (\"the card slider owns every layer of a menu, in the picked color\") instead of\n * leaving an untinted stock band inside a tinted, faded card.\n * Compositing is on its side too: the heading stacks on the surface layer it sticks\n * to, so a heading and a card at the same alpha still read as a band roughly\n * twice-as-dense as the card (1-(1-a)²) — occluding, at the slider's level, exactly\n * as it did when both came from one token. */\nexport const LAYERED_MENU_SURFACE_WITH_GROUP_HEADER: MenuSurfaceFacts = {\n fillTokens: [...LAYERED_MENU_SURFACE.fillTokens, MENU_GROUP_HEADER_FILL_TOKEN],\n frostDecl: LAYERED_MENU_SURFACE.frostDecl,\n}\n\n/** The answer when the release could not be resolved, and neither of the two\n * verified shapes can be asserted. Each half is chosen so that being on the\n * wrong line costs an inert declaration rather than a wrong pixel:\n * · BOTH fill tokens. A custom property nothing reads costs nothing, so this\n * half always lands: the fade reaches a self-painting menu through the old\n * token and a `MenuSurface` layer through the new one.\n * · the ELEMENT's frost, and not the host's blur token, because on `0.1.5` and\n * `0.1.6` `--dsw-menu-backdrop-filter` has no consumer at all (verified: zero\n * files before 0.1.7-alpha.1) — the token arm would leave those hosts with no\n * menu frost whatsoever, while filtering the element frosts every release.\n * On a `MenuSurface` host it does not stack: the surface root IS the element\n * that carries `role=\"menu\"`, so our filter makes it a backdrop root, and the\n * `z-index:-1` layer inside it then has only the (unpainted) surface to sample\n * and its own default `blur(40px)` becomes inert. One frost — ours — plus a\n * `position:relative` element that hosts nested menus the way the layer was\n * written not to. Accepted for a bucket that by definition cannot know. */\nexport const UNRESOLVED_MENU_SURFACE: MenuSurfaceFacts = {\n fillTokens: LAYERED_MENU_SURFACE.fillTokens,\n frostDecl: elementFrostDecl,\n}\n\n/** Session-header slot anchors present on EVERY release in range. The slot\n * renderer stamps `data-slot=\"<key>\"` unconditionally (`ui-renderer/scoped-slots.tsx`),\n * and all five keys are registered from 0.1.5-rc.2 through 0.2.1-alpha.1 —\n * verified per tag. Adapters append the keys their own release adds. */\nexport const BASE_HEADER_SLOT_KEYS = [\n 'conversation.session.header',\n 'conversation.session.header.actions',\n 'conversation.session.header.utilities',\n 'conversation.session.header.corner',\n 'conversation.session.header.lineage',\n] as const\n","/**\n * Adapter for the DSH 0.1.5-rc channel (`0.1.5-rc.2`, `0.1.5-rc.3`).\n *\n * Nothing here is inferred from a neighbouring release — each fact below was\n * checked against the harness tags `dsh-v0.1.5-rc.2` / `dsh-v0.1.5-rc.3`.\n *\n * Host shape this line presents:\n * `ui-sidebar-right/shell/SidebarRight.module.css`\n * .panel { position:absolute; z-index:10; transform:translateX(100%); visibility:hidden }\n * .panel[data-sidebar-right-open] { transform:none }\n * .panel[data-sidebar-right-panel='fullscreen'] { position:fixed; inset:0; z-index:40 }\n * `ui-dockkit` ships WITHOUT `TabLayout.tsx`, so `[data-dockkit-host]` and\n * `[data-dockkit-empty]` are never rendered on this line.\n * `ui-plugin-manager` (the page behind `PLUGIN_PAGE_FROST_RULE`) is not a package\n * on this line at all, and neither tag emits `[data-plugin-panel]`.\n *\n * Consequence for the panel slider: the WRAPPER is what slides, so the\n * `backdrop-filter` belongs on the wrapper — and because the wrapper sits inside\n * an animated track with its own stacking context, it must be promoted out of it\n * or the filter has no wallpaper to sample.\n *\n * Menus paint themselves here: 11 stylesheets declare\n * `background:var(--dsw-specific-menu)` on the element (`Menu`, `MenuView`,\n * `PopupSelectView`, `stat-dialog`, `ModelSelect`, `JobListAction`, `ContextMeter`,\n * `ScheduleCatalogAction`, `SubagentHeaderLineage`, `TeamAction`, `CordisPanel`),\n * and `--dsw-menu-backdrop-filter`\n * has NO consumer on this line at all — the host frosts no menu, so the element is\n * both the paint and the only place a frost can go. Hence `LEGACY_MENU_SURFACE`.\n *\n * @module\n */\nimport {\n BASE_HEADER_SLOT_KEYS,\n LEGACY_MENU_SURFACE,\n PANEL_FULLSCREEN,\n PANEL_WRAPPER,\n panelBlurRule,\n} from '../shared'\nimport type { HostAdapter, HostInfo, PanelFragments } from '../types'\n\n/** The wrapper carries the slide transform on this line, so it carries the blur. */\nfunction panelFragments(): PanelFragments {\n return {\n // Lift the panel clear of the rightbar column's stacking context. Fullscreen\n // re-asserts the host's own z-index 40 (the modal dialog stack lives at 100+,\n // above both), so the promotion above cannot drag it under the frame chrome.\n promotion:\n `${PANEL_WRAPPER}{position:fixed!important;z-index:26!important}` +\n `${PANEL_FULLSCREEN}{z-index:40!important}`,\n blur: panelBlurRule(PANEL_WRAPPER),\n }\n}\n\nexport function createAdapter(host: HostInfo): HostAdapter {\n return {\n id: '0.1.5-rc.2/rc.3',\n channel: '0.1.5-rc',\n host,\n panelFragments,\n // No plugin-manager page to frost. Emitting the rule would be harmless — the\n // selector cannot match — but a resolved adapter's job is to say what THIS\n // release has, and this one does not.\n pluginPageRule: '',\n menus: LEGACY_MENU_SURFACE,\n surface: {\n // This line's own right Sidebar does NOT carry the appearance page, so the\n // plugin's dsh-better-sidebar page owns the guide surface and must register.\n ownsSidebarGuideSurface: false,\n // All five header slot anchors are registered on both 0.1.5 releases.\n headerSlotKeys: BASE_HEADER_SLOT_KEYS,\n },\n }\n}\n","/**\n * Adapter for the DSH 0.1.6-alpha channel (`0.1.6-alpha.1`, `0.1.6-alpha.2`).\n *\n * Facts checked per tag against `dsh-v0.1.6-alpha.1` / `dsh-v0.1.6-alpha.2` —\n * deliberately not copied over from the 0.1.5 folder, even where the two lines\n * turned out to agree. If a future 0.1.6 patch diverges, only this file moves.\n *\n * Host shape this line presents:\n * `SidebarRight.module.css` is unchanged from the 0.1.5 line for the parts that\n * matter: `.panel` still carries `position:absolute` + `transform:translateX(100%)`,\n * `data-sidebar-right-open` still clears it with `transform:none`, and the panel\n * width is still an inline `width` with no `--dsh-sidebar-width` variable.\n * alpha.2 appends fullscreen window chrome (`.63` windows / `.77` darwin), which\n * does not move the blur target, AND the `ui-plugin-manager` package — so the\n * plugin-page frost below is prerelease-gated rather than channel-wide.\n * `ui-dockkit` still has no `TabLayout.tsx`, so no `[data-dockkit-host]` /\n * `[data-dockkit-empty]` on this line either.\n *\n * So the panel mechanics match 0.1.5: the wrapper slides, the wrapper takes the\n * blur, and the wrapper needs promoting.\n *\n * Menus too — checked separately at both tags, because that is what this folder is\n * for: 11 stylesheets paint the menu element from `--dsw-specific-menu` on alpha.1\n * and alpha.2 alike, and `--dsw-menu-backdrop-filter` has no consumer on either, so\n * `LEGACY_MENU_SURFACE` serves the whole line. The element is both the paint and\n * the frost's only possible home.\n *\n * @module\n */\nimport {\n BASE_HEADER_SLOT_KEYS,\n LEGACY_MENU_SURFACE,\n PANEL_FULLSCREEN,\n PANEL_WRAPPER,\n PLUGIN_PAGE_FROST_RULE,\n panelBlurRule,\n} from '../shared'\nimport { prereleaseOf } from '../../../../host-compat/channel'\nimport type { HostAdapter, HostInfo, PanelFragments } from '../types'\n\n/** The extra session-header anchor this line introduces: the macOS titlebar work\n * added `conversation.session.header.leading`. It was deleted again at\n * 0.1.7-alpha.1 with no shim, so it is unique to this line — which is why the\n * channel alone is not enough to answer it and the prerelease is read.\n * `alpha.1` predates it.\n *\n * Erring toward \"included\": a slot key the host never emits simply matches\n * nothing, whereas a key we omit hides a header area from the plugin for the\n * whole session. */\nfunction hasLeadingHeaderSlot(version: string | null): boolean {\n const pre = prereleaseOf(version)\n if (pre === null) return true\n const m = /^alpha\\.(\\d+)$/.exec(pre)\n return m === null || Number(m[1]) >= 2\n}\n\n/** The other thing this line splits on: `ui-plugin-manager` — the package that\n * renders `设置 → 插件` and stamps `[data-plugin-panel]` — was CREATED at\n * alpha.2. Until then the plugin list was a settings tab in\n * `ui-settings-plugin-inventory`, which carries `[data-plugin-scope]` but no\n * card list to frame, so alpha.1 has nothing for the frost rule to apply to.\n *\n * Same erring-toward-included convention as `hasLeadingHeaderSlot`: the rule's\n * own `[data-plugin-panel]` prefix means an over-broad arm cannot paint, while\n * an over-narrow one leaves a page bare for the whole session. */\nfunction hasPluginManagerPage(version: string | null): boolean {\n const pre = prereleaseOf(version)\n if (pre === null) return true\n const m = /^alpha\\.(\\d+)$/.exec(pre)\n return m === null || Number(m[1]) >= 2\n}\n\nfunction panelFragments(): PanelFragments {\n return {\n // Same treatment as the 0.1.5 line: the wrapper is transformed inside an\n // animated track, so the frost needs it lifted out to have wallpaper to\n // sample. This is the arrangement the 0.1.6 report confirmed working.\n promotion:\n `${PANEL_WRAPPER}{position:fixed!important;z-index:26!important}` +\n `${PANEL_FULLSCREEN}{z-index:40!important}`,\n blur: panelBlurRule(PANEL_WRAPPER),\n }\n}\n\nexport function createAdapter(host: HostInfo): HostAdapter {\n return {\n id: '0.1.6-alpha.1/alpha.2',\n channel: '0.1.6-alpha',\n host,\n panelFragments,\n pluginPageRule: hasPluginManagerPage(host.version) ? PLUGIN_PAGE_FROST_RULE : '',\n menus: LEGACY_MENU_SURFACE,\n surface: {\n // From this line the host's own right Sidebar carries an appearance page,\n // so the plugin's dsh-better-sidebar page would double the guide surface\n // and stands down. NOT derived from the sidebar service existing — it\n // already ships on 0.1.5-rc.2 — this is the release's own behaviour.\n ownsSidebarGuideSurface: true,\n headerSlotKeys: hasLeadingHeaderSlot(host.version)\n ? [...BASE_HEADER_SLOT_KEYS, 'conversation.session.header.leading']\n : BASE_HEADER_SLOT_KEYS,\n },\n }\n}\n","/**\n * Adapter for the DSH 0.1.7-alpha channel (`0.1.7-alpha.1`, `0.1.7-alpha.2`),\n * re-verified unchanged at `0.1.7-rc.1`.\n *\n * This is the line the panel mechanics actually changed on — verified against\n * `dsh-v0.1.6-alpha.2` → `dsh-v0.1.7-alpha.1`, where `SidebarRight.module.css`\n * was rewritten (116 lines changed) and `ui-dockkit/src/components/TabLayout.tsx`\n * was ADDED. Both facts were checked, not assumed.\n *\n * `0.1.7-rc.1` was checked the same way, by diffing every package that emits an\n * anchor this plugin matches (the panel CSS, dockkit, the plugin-manager page, the\n * slot renderer, the theme tokens): no anchor line moved, and the two UI changes it\n * carries do not reach us —\n * · `ui-plugin-manager`: a new `InstallDialog` failure screen plus compatibility\n * wording. The card block (`section` → `div.groupHead` + `ul.cards`) is\n * untouched, and the dialog is a body-level `Modal`, so the `:has()` valve of\n * `PLUGIN_PAGE_FROST_RULE` never even has to fire for it.\n * · `ui-conversation`: `.titleRow` gains `container-type:inline-size`, which makes\n * it a stacking context and a containing block. Header slots sit inside that\n * row, but this plugin reaches them through background/blur tokens, and the\n * dropdowns they trigger portal to `document.body` (see `header-tag.ts`), so\n * nothing of ours lands inside the new containment.\n *\n * Host shape this line presents:\n * .panel { position:absolute; --dsh-dockkit-dock-layer:10; pointer-events:none }\n * — no transform, no visibility, and no z-index of its own any more.\n * .panel :global([data-dockkit-host='dock']),\n * .panel :global([data-dockkit-empty]),\n * .panel :global([data-dockkit-divider]) { transform:translateX(var(--dsh-sidebar-width)); visibility:hidden }\n * .panel[data-sidebar-right-open] :global(…) { transform:none }\n * — the DOCKED CHILDREN are what slide.\n * .panel[data-sidebar-right-panel='fullscreen'] { --dsh-dockkit-dock-layer:40 }\n * — fullscreen no longer flips the panel to `position:fixed`; it raises a\n * layer variable, and the width becomes `100vw` on the absolute panel.\n *\n * Consequences encoded below:\n * 1. The blur belongs on the children. On the wrapper it frosted a stationary\n * frame — \"the blur stays put while the sidebar moves\".\n * 2. The promotion must NOT be emitted. `position:fixed` detaches the panel from\n * the track the host animates, which is the whole reason 2 the blur stopped\n * travelling. The host's own sheet documents the content root as owning \"no\n * stacking context or transform\", so `backdrop-filter` resolves against the\n * page and samples the wallpaper unaided.\n * 3. `[data-dockkit-empty]` must be included alongside `[data-dockkit-host]`: a\n * pane with no tabs renders the empty host instead, and keying on `host`\n * alone mis-detects that (transient) shape.\n *\n * Also true of this line, recorded so the next reader does not re-derive it:\n * · `conversation.session.header.leading` was DELETED here with no shim, so this\n * folder deliberately does not list it (see the 0.1.6 folder).\n * · `--dsw-specific-menu` was severed from `--dsw-alias-bg-layer-3` and became a\n * literal translucent rgba, plus a `html[data-platform='darwin']` re-override.\n * The plugin already samples and writes that token directly, so the severance\n * needs no adapter of its own — but note the consequence: `toRgba()` REPLACES\n * alpha, so the header slider now overrides the host's own 0.58 rather than\n * fading an opaque layer. Intended (the slider means \"this opacity\"), worth\n * knowing if the 0.1.7 header ever looks too thin.\n * · `[data-chat-flow]` is stamped on a nested `ChatGroupSeat` content element\n * too. Checked against every use in this plugin: the stroke group is inherited\n * so a second match changes nothing, and the view-card discovery takes the\n * first match, which is still the real flow root. No arm needed.\n * · menus still paint THEMSELVES on this line — 15 stylesheets declare\n * `background:var(--dsw-specific-menu)` on the element at alpha.1/alpha.2 and 16\n * at rc.1, so `LEGACY_MENU_SURFACE` is the answer and the `MenuSurface` child\n * layer does not exist yet. Worth noting what DID arrive here:\n * `--dsw-menu-backdrop-filter` goes from zero consumers at 0.1.6-alpha.2 to 15 at\n * alpha.1 (16 at rc.1), i.e. this is the line where the host started frosting\n * menus on the element itself. The plugin's own filter sits on the same element\n * and wins the cascade by sheet order, so the element is still the only place a\n * frost can go — which is exactly why re-declaring the HOST's token instead\n * would be inert on this line and correct on the next one.\n *\n * @module\n */\nimport {\n BASE_HEADER_SLOT_KEYS,\n DOCKKIT_SLIDERS,\n LEGACY_MENU_SURFACE,\n PLUGIN_PAGE_FROST_RULE,\n panelBlurRule,\n} from '../shared'\nimport type { HostAdapter, HostInfo, PanelFragments } from '../types'\n\nfunction panelFragments(): PanelFragments {\n return {\n // Consequence 2: nothing to promote. The panel resolves against the page on\n // its own here, so the pre-0.1.7 lift is pure downside.\n promotion: '',\n blur: panelBlurRule(DOCKKIT_SLIDERS),\n }\n}\n\nexport function createAdapter(host: HostInfo): HostAdapter {\n return {\n id: '0.1.7-alpha.1/alpha.2/rc.1',\n channel: '0.1.7-alpha',\n host,\n panelFragments,\n // Every build this folder covers ships the plugin-manager page, and\n // `renderGroup` is byte-identical to 0.1.6-alpha.2's, so the same string\n // serves the whole line — rc.1 changed only the install dialog around it.\n pluginPageRule: PLUGIN_PAGE_FROST_RULE,\n menus: LEGACY_MENU_SURFACE,\n surface: {\n ownsSidebarGuideSurface: true,\n headerSlotKeys: BASE_HEADER_SLOT_KEYS,\n },\n }\n}\n","/**\n * Adapter for the DSH `0.1.7-rc` channel, verified at `0.1.7-rc.2` (npm `latest`).\n *\n * Same patch line as `v0-1-7-alpha-1-2-rc-1`, DIFFERENT ANSWERS — which is why this\n * folder exists at all rather than another row on that one. Everything the alpha\n * folder says about panel mechanics still holds here (checked by diffing the panel\n * CSS, dockkit, the slot renderer and the plugin-manager page tag to tag: no anchor\n * line moved, and `TabLayout.tsx` / `SidebarRight.module.css` are unchanged from\n * rc.1). What moved is where a MENU gets its paint.\n *\n * Two host changes reach this plugin:\n *\n * 1. `ui-primitives/src/MenuSurface.tsx` is NEW, and `TabMenu`, `MenuView`,\n * `PopupSelectView`, `ModelSelect` and `Menu` all render through it. The element\n * that carries `role=\"menu\"` no longer paints anything: a `z-index:-1` child\n * layer does, reading `--dsw-menu-surface-fill` for the fill and\n * `--dsw-menu-backdrop-filter` for the frost. And `design-platform.css` flipped\n * its alias — `--dsw-specific-menu:var(--dsw-menu-surface-fill)`, where every\n * earlier release declared it the other way round. Consequence, read off those\n * two files rather than guessed: retinting `--dsw-specific-menu` alone now fades\n * nothing on a shared menu, so the card and header opacity sliders go inert on\n * exactly the surfaces they were built for. `LAYERED_MENU_SURFACE` is the answer.\n * Filtering the menu element would also have kept working, sort of — but the\n * child layer's own comment says it exists so that no ANCESTOR becomes a\n * backdrop root, so that arm stops being offered here.\n *\n * 2. `ui-settings-general/src/client/SettingsRoot.tsx` now renders the dialog\n * through `createPortal`, beside `#root`, instead of inline in the column. It\n * costs this plugin nothing, recorded so nobody re-derives it:\n * `SETTINGS_PANEL_SEL` tests the dialog's own identity (its hashed `_panel`\n * class plus `role`/`aria-modal`/`aria-labelledby`, all unchanged), never an\n * ancestor, so the retint and the blur land the same way one level higher up.\n * The one rule that DID care — `PART_BLUR_RULE`'s\n * `:has([role=\"dialog\"]){isolation:auto}` valve, written because a modal mounted\n * inside a column kept its z-index local to that column — now never matches, and\n * that is fine: the modal it existed to release is no longer inside a column\n * either, so the trap and the valve left together.\n *\n * Still `0.1.7` facts, restated for the reader who only opens this folder:\n * · the panel is a stationary frame; the dockkit children slide, so the blur goes\n * on the children and nothing is promoted.\n * · `conversation.session.header.leading` is gone; `--dsw-specific-menu` is a\n * literal translucent rgba, not an alias of a layer token.\n * · the shimmer primitive is STILL `data-text-shimmer` (checked: `data-shimmer`\n * does not exist at this tag) — that rename belongs to 0.2.0.\n *\n * @module\n */\nimport {\n BASE_HEADER_SLOT_KEYS,\n DOCKKIT_SLIDERS,\n LAYERED_MENU_SURFACE,\n PLUGIN_PAGE_FROST_RULE,\n panelBlurRule,\n} from '../shared'\nimport type { HostAdapter, HostInfo, PanelFragments } from '../types'\n\nfunction panelFragments(): PanelFragments {\n return {\n // Re-verified against rc.2: the wrapper carries no transform and no z-index, so\n // `backdrop-filter` on it resolves against the page unaided and the lift the\n // pre-0.1.7 folders emit would only knock the panel off its animation track.\n promotion: '',\n blur: panelBlurRule(DOCKKIT_SLIDERS),\n }\n}\n\nexport function createAdapter(host: HostInfo): HostAdapter {\n return {\n id: '0.1.7-rc.2',\n channel: '0.1.7-rc',\n host,\n panelFragments,\n // `renderGroup` is byte-identical to the alpha folder's at this tag; what rc.2\n // added around it is the install dialog, which portals to body.\n pluginPageRule: PLUGIN_PAGE_FROST_RULE,\n menus: LAYERED_MENU_SURFACE,\n surface: {\n ownsSidebarGuideSurface: true,\n headerSlotKeys: BASE_HEADER_SLOT_KEYS,\n },\n }\n}\n","/**\n * Adapter for the DSH `0.2.0-rc` channel, verified at `0.2.0-rc.1`.\n *\n * A new MINOR line, and the panel is not what changed. Checked by reading the\n * emitting source at the tag rather than a changelog:\n * · `ui-sidebar-right/src/client/shell/SidebarRight.module.css` is BYTE-IDENTICAL\n * to `0.1.7-rc.2`, and `ui-primitives/src/MenuSurface.tsx` is byte-identical\n * too. So the slide owner, the layer variable and where a menu gets its paint\n * all answer the same as the `0.1.7-rc` folder — nothing below re-derives them.\n * · the five `conversation.session.header*` slot keys are the same five;\n * `conversation.session.header.leading` is still deleted.\n * · `ui-settings-general/SettingsRoot.tsx` is byte-identical, so the settings\n * dialog is still a body-level `createPortal` and `SETTINGS_PANEL_SEL`'s\n * identity test still reaches it.\n * · the boot peer gate (`app-boot/src/plugin-compatibility.ts`,\n * `compatibility-preflight.ts`) is byte-identical, which is what makes the\n * manifest change below a HARD requirement rather than metadata: an unlisted\n * peer version disables the plugin at profile composition and its modules are\n * never imported.\n *\n * What did move, and reaches this plugin:\n *\n * 1. `ui-dockkit/components/TabLayout.tsx` clamps a FLOATING pane's `top` with\n * `max(var(--dsh-dockkit-float-top, 0px), Ypx)`. Only floats: the attributes\n * this plugin matches, `data-dockkit-host=\"dock\"` and `data-dockkit-empty`,\n * are on unchanged lines (verified by grep at both tags), so the blur arm\n * stands as the rc.2 folder wrote it.\n *\n * 2. `ui-primitives/src/TextShimmer.tsx` is REWRITTEN. The old primitive set\n * `data-text-shimmer` and painted the element itself with a clipped gradient\n * (`background-clip:text` + `-webkit-text-fill-color:transparent`) sized by an\n * inline `--dsh-text-shimmer-spread`, which no longer exists anywhere in the\n * repo. The new one marks its root `data-shimmer` and moves the highlight onto\n * an absolutely-positioned overlay (`.decoration` / `.sweep` / `.highlight`)\n * tinted by `--dsw-alias-label-shimmer`, so the real glyphs keep their own\n * color. Consequence for the stroke sliders: the old failure mode — a stroke\n * repainting transparent-filled glyphs as one flat blob — is gone, but\n * `-webkit-text-stroke` is still inherited, so the chat stroke would now land\n * on BOTH the real text and the sweeping copy and double every glyph while it\n * animates. Progress chrome still is not conversation prose, so the exemption\n * stays and gains the new attribute (`STROKE_RULE`).\n * More rows use it now: `ReasoningRow` and `GenericCommandCard` join\n * `ChatGroupSeat` / `MessageItem` / `RunningStatus` / `DisclosureRow`.\n *\n * 3. `ui-plugin-manager` gains a first-read `ListSkeleton`. Its card `ul` carries\n * the same `.cards` class but sits under `section[data-plugin-loading]`\n * instead of `section[data-plugin-scope]`, so the shared frost rule had to\n * grow or the plugin page would show an unfrosted list for the length of the\n * first read and then re-frost it — see `PLUGIN_PAGE_FROST_RULE`.\n *\n * @module\n */\nimport {\n BASE_HEADER_SLOT_KEYS,\n DOCKKIT_SLIDERS,\n LAYERED_MENU_SURFACE,\n PLUGIN_PAGE_FROST_RULE,\n panelBlurRule,\n} from '../shared'\nimport type { HostAdapter, HostInfo, PanelFragments } from '../types'\n\nfunction panelFragments(): PanelFragments {\n return {\n // Re-verified: the wrapper CSS is byte-identical to rc.2, so the panel is\n // still a stationary frame, the dockkit children still slide, and promoting\n // the wrapper would still knock it off the host's animation track.\n promotion: '',\n blur: panelBlurRule(DOCKKIT_SLIDERS),\n }\n}\n\nexport function createAdapter(host: HostInfo): HostAdapter {\n return {\n id: '0.2.0-rc.1',\n channel: '0.2.0-rc',\n host,\n panelFragments,\n // The page markup that decides the frost target is unchanged apart from the\n // new loading skeleton, which the shared rule now covers for every line that\n // ships the page (older hosts never emit `[data-plugin-loading]`).\n pluginPageRule: PLUGIN_PAGE_FROST_RULE,\n menus: LAYERED_MENU_SURFACE,\n surface: {\n ownsSidebarGuideSurface: true,\n headerSlotKeys: BASE_HEADER_SLOT_KEYS,\n },\n }\n}\n","/**\n * Adapter for the DSH `0.2.0-rc` line from `0.2.0-rc.2` on, verified at `0.2.0-rc.2`.\n *\n * The first case where one patch line AND one prerelease channel carry two\n * answers, so this folder opens a second channel (see the note on `HostChannel`).\n * What it took was one renamed token, and it is a menu token, which is the class of\n * fact this table exists for:\n *\n * · `ui-primitives/src/MenuGroup.tsx` + `.module.css` are NEW at rc.2 and the\n * headings of both grouped popups (`ModelSelect`, `PopupSelectView`) now come\n * from them. `ModelSelect.module.css` loses `.groupTitle{background:var(\n * --dsw-specific-menu)}` in the same breath — the sticky heading's paint moved\n * to `--dsw-alias-menu-group-header-fill`, a token that does not exist before\n * this tag (`git grep` at `0.1.7-rc.2` and `0.2.0-rc.1`: absent). Hence\n * `LAYERED_MENU_SURFACE_WITH_GROUP_HEADER` rather than the rc.1 constant: the\n * old claim set stayed true, it just stopped covering one element.\n * · the rest of the menu layer is the same code — `MenuSurface.tsx` and\n * `MenuSurface.module.css` are byte-identical to `0.2.0-rc.1`, and so is every\n * consumer of `--dsw-menu-backdrop-filter`.\n *\n * Also verified at this tag, and NOT a reason for a folder of its own:\n * · `SidebarRight.module.css` and `ui-dockkit/src/components/TabLayout.tsx` are\n * unchanged, so the panel is still a stationary frame whose dockkit children\n * slide (`panelBlurRule(DOCKKIT_SLIDERS)`, no promotion).\n * · the five `conversation.session.header*` slot keys, and still no `…leading`.\n * · `PluginManagerPage.tsx` still emits `section[data-plugin-panel]` with the card\n * `ul` under `[data-plugin-scope]` and `[data-plugin-loading]`.\n * · `TextShimmer` keeps the rc.1 shape (`data-shimmer`), so the stroke exemption\n * stands as written.\n *\n * What moved that reached this plugin WITHOUT a version branch, because the host\n * wrote it as a chain with a fallback:\n * · `TurnTriggerNodeView.module.css` now fills from\n * `var(--dsw-alias-turn-trigger-bg, var(--dsw-alias-markdown-code-block))` and\n * hovers with `var(--dsw-alias-turn-trigger-bg-hover, var(--dsw-alias-interactive-bg-hover))`,\n * both aliases declared in `design-platform.css` at this tag. The produced\n * slider's arm reads the SAME chain (see `PRODUCED_RULE`), so older hosts take\n * the fallback and this one takes the new alias — without any release test. That\n * matters here rather than being pedantry: dark mode repoints the alias at\n * `--dsw-alias-interactive-bg-hover`, so an arm still mixing on the code-block\n * token would keep overriding the row with the OLD color and the row would stop\n * tracking its own hover.\n *\n * @module\n */\nimport {\n BASE_HEADER_SLOT_KEYS,\n DOCKKIT_SLIDERS,\n LAYERED_MENU_SURFACE_WITH_GROUP_HEADER,\n PLUGIN_PAGE_FROST_RULE,\n panelBlurRule,\n} from '../shared'\nimport type { HostAdapter, HostInfo, PanelFragments } from '../types'\n\nfunction panelFragments(): PanelFragments {\n return {\n // Re-verified at this tag: the wrapper CSS is byte-identical to rc.1.\n promotion: '',\n blur: panelBlurRule(DOCKKIT_SLIDERS),\n }\n}\n\nexport function createAdapter(host: HostInfo): HostAdapter {\n return {\n id: '0.2.0-rc.2',\n channel: '0.2.0-rc.2',\n host,\n panelFragments,\n pluginPageRule: PLUGIN_PAGE_FROST_RULE,\n menus: LAYERED_MENU_SURFACE_WITH_GROUP_HEADER,\n surface: {\n ownsSidebarGuideSurface: true,\n headerSlotKeys: BASE_HEADER_SLOT_KEYS,\n },\n }\n}\n","/**\n * Adapter for the DSH `0.2.1-alpha` line, verified at `0.2.1-alpha.1`.\n *\n * A new MINOR line opened with a prerelease, and the answer is the `0.2.0-rc.2`\n * folder's — which is a statement this file has to earn, because \"same as the\n * release before\" is exactly the reasoning that went wrong when `0.1.7-rc.2` moved\n * the menu paint. Read at the tag instead:\n * · `ui-theme/src/styles/design-platform.css` is BYTE-IDENTICAL to `0.2.0-rc.2`\n * (`git diff --numstat` empty), so every token this plugin writes — the menu\n * pair, the specific-menu alias, the turn-trigger chain — resolves to the same\n * values.\n * · `MenuGroup.tsx`, `MenuGroup.module.css`, `MenuSurface.tsx` and\n * `MenuSurface.module.css` are byte-identical too, and `MenuGroup` is still the\n * only consumer of `--dsw-alias-menu-group-header-fill`. That is why the menus\n * here answer with `LAYERED_MENU_SURFACE_WITH_GROUP_HEADER`, the same facts the\n * rc.2 folder checked, and not by re-typing them.\n * · `ui-sidebar-right/shell/SidebarRight.module.css` and\n * `ui-dockkit/src/components/TabLayout.tsx` unchanged (only `.tsx` service\n * wiring moved), so the panel stays a stationary frame with sliding dockkit\n * children and no promotion.\n * · the five `conversation.session.header*` slot keys, still no `…leading`.\n * · `PluginManagerPage.tsx` still emits the three anchors of the card list.\n * · `TextShimmer` still marks its root `data-shimmer`, so the stroke exemption\n * written for rc.1 stands.\n *\n * What did move, and why none of it needs a fact from this folder:\n *\n * 1. `ui-layout/AppFrame` gains a second grid row, `div.bottomRow[data-shell-bottom]`\n * holding the new `shell.bottom` slot, and it paints `--dsw-alias-bg-base` —\n * the main-background token, which `applyCustomTokensNow` already re-emits on\n * `body`, so the strip follows the main-bg slider with no new binding. The row\n * is `min-height:0` and empty unless a plugin fills the slot, so an untouched\n * install shows nothing. It also sits AFTER `RightbarColumn` in the frame's\n * children, which is the side `discoverParts()` does not count from: it anchors\n * on `data-rightbar-col` and reads `rightIdx-2` / `rightIdx-1`, so the sidebar\n * and center column are still the same two children.\n * 2. `ui-primitives/InlineEditor.module.css` is the new home of the inline editor's\n * `.editor{background:var(--dsw-alias-bg-base)}`. Same token, so the same slider\n * reaches it wherever the component moved to.\n * 3. `modules/system.ts` narrowed `claimStyles` to the tags a factory itself added\n * (see `ensureUiCss` for what that changed about our own sheet).\n * 4. `@deepseek-ai/dsh-invariants` is DELETED at this tag — `git ls-tree` shows no\n * `packages/runtime-diagnostics/invariants`, and the boot/app plugin loader never\n * looked for a plugin's `invariant` export. This plugin's no-op companion was\n * therefore already dead weight here, and it goes rather than claiming a peer\n * version for a package the host no longer ships.\n *\n * @module\n */\nimport {\n BASE_HEADER_SLOT_KEYS,\n DOCKKIT_SLIDERS,\n LAYERED_MENU_SURFACE_WITH_GROUP_HEADER,\n PLUGIN_PAGE_FROST_RULE,\n panelBlurRule,\n} from '../shared'\nimport type { HostAdapter, HostInfo, PanelFragments } from '../types'\n\nfunction panelFragments(): PanelFragments {\n return {\n promotion: '',\n blur: panelBlurRule(DOCKKIT_SLIDERS),\n }\n}\n\nexport function createAdapter(host: HostInfo): HostAdapter {\n return {\n id: '0.2.1-alpha.1',\n channel: '0.2.1-alpha',\n host,\n panelFragments,\n pluginPageRule: PLUGIN_PAGE_FROST_RULE,\n menus: LAYERED_MENU_SURFACE_WITH_GROUP_HEADER,\n surface: {\n ownsSidebarGuideSurface: true,\n headerSlotKeys: BASE_HEADER_SLOT_KEYS,\n },\n }\n}\n","/**\n * Stand-in for \"we could not resolve the release\".\n *\n * This is a REAL case, not a theoretical one: a plain `~/.dsh` install has no\n * launcher layout, so the front-door probe finds neither a manifest nor a\n * version-shaped directory name. It must not degrade into a guessed channel —\n * a wrong guess silently restyles the window.\n *\n * Instead, the DOM arbitrates. Both panel arms ship, each gated on the shape that\n * only one release family can present, which is exactly how this plugin behaved\n * before release detection existed. It is why an unresolved host still gets a\n * working panel blur.\n *\n * The one concession this costs: an engine without `:has()` cannot parse a gated\n * selector and drops that block, so such a host loses the promotion. A resolved\n * host does not have that problem — its arm is unconditional.\n *\n * @module\n */\nimport {\n BASE_HEADER_SLOT_KEYS,\n DOCKKIT_SLIDERS,\n PANEL_FULLSCREEN,\n PANEL_WRAPPER,\n PLUGIN_PAGE_FROST_RULE,\n UNRESOLVED_MENU_SURFACE,\n panelBlurRule,\n WITHOUT_DOCKKIT_FRAME,\n} from '../shared'\nimport type { HostAdapter, HostInfo, PanelFragments } from '../types'\n\nfunction panelFragments(): PanelFragments {\n const wrapper = `${PANEL_WRAPPER}${WITHOUT_DOCKKIT_FRAME}`\n return {\n // The promotion can only be claimed conditionally here: on a 0.1.7-style\n // frame it is actively wrong, and the frame's presence is all we can test.\n promotion:\n `${wrapper}{position:fixed!important;z-index:26!important}` +\n `${PANEL_FULLSCREEN}${WITHOUT_DOCKKIT_FRAME}{z-index:40!important}`,\n // Each owner in its OWN block — a selector list is not forgiving, so bundling\n // them would let one unparseable entry drop the other's frost too.\n blur:\n panelBlurRule(DOCKKIT_SLIDERS) +\n panelBlurRule(wrapper),\n }\n}\n\nexport function createAdapter(host: HostInfo): HostAdapter {\n return {\n id: 'unknown',\n channel: 'unknown',\n host,\n panelFragments,\n // Unlike the panel arms this needs no DOM gate: the page's own\n // `[data-plugin-panel]` prefix IS the test, so on a release with no plugin\n // manager the rule is simply inert. No `:has()` cost either.\n pluginPageRule: PLUGIN_PAGE_FROST_RULE,\n // The menu arms cannot be DOM-gated the way the panel ones are — a fill token\n // and a frost target are not testable on an element that is not open yet — so\n // this takes the variant built to cost nothing on whichever line it turns out\n // to be. See `UNRESOLVED_MENU_SURFACE`.\n menus: UNRESOLVED_MENU_SURFACE,\n surface: {\n // Asserting `true` here would withdraw the plugin's sidebar page on a host\n // that may not have an appearance page of its own — a missing page is worse\n // than a duplicate, and the duplicate is what the resolved adapters prevent.\n ownsSidebarGuideSurface: false,\n headerSlotKeys: BASE_HEADER_SLOT_KEYS,\n },\n }\n}\n","/**\n * The registry: release channel → the adapter folder that speaks for it.\n *\n * The ONLY place in the plugin that maps a release onto code. Adding a new DSH\n * line is a three-step change with no existing file to touch:\n * 1. `KnownChannel` (and `channelOf`) in `src/host-compat/channel.ts`,\n * 2. a folder here, mirroring the others, NAMED FOR THE EXACT TAGS ITS FACTS\n * WERE CHECKED AGAINST (`v0-1-6-alpha-1-2`, not `v0-1-6-alpha`) so the\n * precision of the table is readable from the tree, and the folder states\n * inside it which prerelease gates it carries,\n * 3. the row below.\n * A newer build that turns out to need NO change does not get its own folder: it\n * joins the name of the folder whose facts held (`v0-1-7-alpha-1-2-rc-1`, checked\n * at rc.1) and gains a `SUPPORTED_RELEASES` row, which is what moves that host's\n * verdict from `line` to `exact`.\n * Anything that reads an adapter then picks it up without a edit — which is the\n * point: version branching must not be reachable from the styling code.\n *\n * The folder is keyed by what its FACTS cover, not by the version number's shape:\n * `v0-1-7-rc-2` sits beside `v0-1-7-alpha-1-2-rc-1` even though both are \"0.1.7\",\n * because rc.2 moved where a menu gets its paint. Two folders on one patch line is\n * the cost of a table that is true; a row on a folder whose facts no longer hold is\n * the cost of one that is not.\n *\n * `v0-2-0-rc-2` sits beside `v0-2-0-rc-1` on a line that does not even differ in\n * prerelease name, because that rc renamed the token a sticky menu group heading\n * paints from. When the split is that fine-grained the channel key takes the build\n * that opened the new facts (`0.2.0-rc.2`), and `classifyRelease` routes everything\n * above it there — a folder named for a line is only honest while the line agrees.\n *\n * @module\n */\nimport type { HostAdapter, HostChannel, HostInfo } from './types'\nimport { createAdapter as adapterFor015rc } from './v0-1-5-rc-2-3/adapter'\nimport { createAdapter as adapterFor016alpha } from './v0-1-6-alpha-1-2/adapter'\nimport { createAdapter as adapterFor017alpha } from './v0-1-7-alpha-1-2-rc-1/adapter'\nimport { createAdapter as adapterFor017rc } from './v0-1-7-rc-2/adapter'\nimport { createAdapter as adapterFor020rc } from './v0-2-0-rc-1/adapter'\nimport { createAdapter as adapterFor020rc2 } from './v0-2-0-rc-2/adapter'\nimport { createAdapter as adapterFor021alpha } from './v0-2-1-alpha-1/adapter'\nimport { createAdapter as adapterForUnknown } from './unknown/adapter'\n\nconst ADAPTERS: Record<HostChannel, (host: HostInfo) => HostAdapter> = {\n '0.1.5-rc': adapterFor015rc,\n '0.1.6-alpha': adapterFor016alpha,\n '0.1.7-alpha': adapterFor017alpha,\n '0.1.7-rc': adapterFor017rc,\n '0.2.0-rc': adapterFor020rc,\n '0.2.0-rc.2': adapterFor020rc2,\n '0.2.1-alpha': adapterFor021alpha,\n unknown: adapterForUnknown,\n}\n\n/** Pick the adapter for a resolved host. `host.channel` is already narrowed to\n * the union by `adoptHostInfo`, so every channel here has a row by construction —\n * a new channel in `HostChannel` fails to compile until it is added. */\nexport function buildAdapter(host: HostInfo): HostAdapter {\n return ADAPTERS[host.channel](host)\n}\n","/**\n * The client-side half of the front door: where the release verdict lands.\n *\n * The browser cannot detect the host release — the client context exposes no\n * version field, and the app manifest that states it is only readable on the node\n * half. So `src/host-compat/detect.ts` resolves it there and the verdict travels\n * in the `read` RPC payload (see `client/rpc.ts`, which calls `adoptHostInfo`).\n *\n * This module only HOLDS the verdict and tells subscribers when it changes. It\n * deliberately answers no feature questions — that is `capabilities.ts`, so the\n * version → behaviour mapping stays in one place.\n *\n * @module\n */\nimport { useSyncExternalStore } from 'react'\nimport {\n channelOf,\n looksLikeVersion,\n UNKNOWN_HOST_INFO,\n type HostInfo,\n} from '../../host-compat/channel'\nimport { buildAdapter } from './versions/registry'\nimport type { HostAdapter } from './versions/types'\n\nlet current: HostInfo = UNKNOWN_HOST_INFO\n/** False until the server verdict lands. Feature gates must not read \"not asked\n * yet\" as \"an old host\" — see `adapterResolved()`. */\nlet resolved = false\n\nconst subs = new Set<() => void>()\n\n/** Cached adapter, keyed by the verdict it was built from. Held because React's\n * `useSyncExternalStore` requires a stable snapshot between notifications. */\nlet adapterCache: HostAdapter | null = null\n\n/** Adopt the verdict delivered by the server's `read` payload.\n *\n * The payload's `channel` is IGNORED and re-derived from `version` here: the\n * two halves are built together, so a disagreeing pair can only mean one of them\n * is stale, and re-deriving keeps `channelOf` the single definition of what a\n * channel means. */\nexport function adoptHostInfo(raw: unknown): void {\n if (raw === null || typeof raw !== 'object') return\n const h = raw as { version?: unknown }\n const version =\n typeof h.version === 'string' && looksLikeVersion(h.version.trim()) ? h.version.trim() : null\n const next: HostInfo = { version, channel: channelOf(version) }\n const changed = !resolved || current.version !== next.version || current.channel !== next.channel\n current = next\n resolved = true\n if (changed) {\n adapterCache = null\n subs.forEach(cb => cb())\n }\n}\n\n/** Subscribe to the verdict landing (or changing). */\nexport function subscribeHostInfo(cb: () => void): () => void {\n subs.add(cb)\n return () => { subs.delete(cb) }\n}\n\n/** Whether the server verdict has landed at all. */\nexport function adapterResolved(): boolean {\n return resolved\n}\n\n/** The detected host release + channel. */\nexport function rHostInfo(): HostInfo {\n return current\n}\n\n/** The adapter chosen for the current verdict — `unknown`'s stand-in until the\n * verdict lands, which is the safe answer: it asserts nothing and lets the DOM\n * arbitrate. */\nexport function rHostAdapter(): HostAdapter {\n adapterCache ??= buildAdapter(current)\n return adapterCache\n}\n\n/** React hook: re-renders when the host verdict lands or changes. */\nexport function useHostAdapter(): HostAdapter {\n return useSyncExternalStore(subscribeHostInfo, rHostAdapter)\n}\n","import type { RpcResultLike, UploadOutcome } from './types'\r\nimport { cfg, adoptConfig, setWpUrl, setWpImageUrl, setWpVideoUrl, rWpImage } from './state'\r\nimport { adoptHostInfo } from './host-compat/release'\r\n\r\nexport const RPC_CHANNEL = '/dsh-any-background'\r\n/** Same-origin serve URL of the persisted video (enough for <video src>/fetch). */\r\nexport const VIDEO_SERVE_URL = '/dsh-any-background/video'\r\n/** Same-origin serve URL of the persisted wallpaper (native <img> loading). */\r\nexport const WALLPAPER_SERVE_URL = '/dsh-any-background/wallpaper'\r\n/** Raw-bytes upload endpoint for the wallpaper slot (no base64 inflation). */\r\nconst WALLPAPER_UPLOAD_URL = '/dsh-any-background/wallpaper/upload'\r\n/** HTTP route new videos are POSTed to as raw bytes (see uploadVideo). */\r\nexport const VIDEO_UPLOAD_URL = '/dsh-any-background/video/upload'\r\n/** Same-origin serve URL of the persisted custom font (enough for @font-face). */\r\nexport const FONT_SERVE_URL = '/dsh-any-background/font'\r\n/** HTTP route custom fonts are POSTed to as raw bytes (see uploadFont). */\r\nexport const FONT_UPLOAD_URL = '/dsh-any-background/font/upload'\r\nconst RPC_NS = 'dshAnyBackground'\r\nconst rpcEndpoint = (method: string): string => `${RPC_NS}/${method}`\r\n\r\nlet rpcCallFn: ((endpoint: string, payload: unknown) => Promise<RpcResultLike | undefined>) | null = null\r\n\r\n/** Serve URL of the persisted custom font, filled by loadPersisted. */\r\nexport let fontServeUrl: string | null = null\r\n\r\nexport function initRpc(call: (endpoint: string, payload: unknown) => Promise<RpcResultLike | undefined>): void {\r\n rpcCallFn = call\r\n}\r\n\r\nasync function rpcCall(method: string, payload: unknown): Promise<unknown> {\r\n if (!rpcCallFn) return undefined\r\n try {\r\n const res = await rpcCallFn(rpcEndpoint(method), payload)\r\n if (res && res.ok === true) return res.value\r\n console.warn(`dsh-any-background: rpc \"${method}\" failed`, res?.error)\r\n return undefined\r\n } catch (e) {\r\n console.warn(`dsh-any-background: rpc \"${method}\" threw`, e)\r\n return undefined\r\n }\r\n}\r\n\r\n// Slider drags fire dozens of events per second; coalesce writes to a trailing\r\n// debounce and flush the last pending write on pagehide so a quick close never\r\n// loses it.\r\nconst SAVE_DEBOUNCE_MS = 250\r\nlet saveTimer: number | undefined\r\n\r\nexport function saveConfig(): void {\r\n if (saveTimer !== undefined) window.clearTimeout(saveTimer)\r\n saveTimer = window.setTimeout(() => {\r\n saveTimer = undefined\r\n void rpcCall('writeConfig', { config: cfg })\r\n }, SAVE_DEBOUNCE_MS)\r\n}\r\n\r\nexport function flushSave(): void {\r\n if (saveTimer === undefined) return\r\n window.clearTimeout(saveTimer)\r\n saveTimer = undefined\r\n void rpcCall('writeConfig', { config: cfg })\r\n}\r\n\r\n/** Persist the current config immediately (import path — no debounce). */\r\nexport function persistConfig(): void {\r\n void rpcCall('writeConfig', { config: cfg })\r\n}\r\n\r\n/** Load the persisted theme (config + wallpaper URL + video URL) from the node\r\n * half. Image and video both travel as serve URLs — never bytes — so this RPC\r\n * stays tiny. Resolves true when the server advanced a due wallpaper rotation\r\n * during the read — the restored wallpaper is then already the new pick.\r\n * `firstRun` means the server had no theme-config.json and just materialized\r\n * its defaults: the caller should persist the browser side's own defaults and\r\n * re-read once so every slider starts from a value that is really on disk. */\r\nexport async function loadPersisted(): Promise<{ rotated: boolean; firstRun: boolean }> {\r\n const data = await rpcCall('read', {})\r\n if (data && typeof data === 'object') {\r\n const d = data as { config?: unknown; wallpaperUrl?: unknown; videoUrl?: unknown; fontUrl?: unknown; rotated?: unknown; firstRun?: unknown; host?: unknown }\r\n // Host release verdict first: feature gates read it before any appearance\r\n // work runs, and it is the only source of the real version string.\r\n adoptHostInfo(d.host)\r\n if (d.config) adoptConfig(d.config)\r\n // Uploaded image and video keep their own slots so type switches never\r\n // discard them; in image mode the caller points wpUrl at it.\r\n if (typeof d.wallpaperUrl === 'string') setWpImageUrl(d.wallpaperUrl)\r\n else if (d.wallpaperUrl === null) setWpImageUrl(null)\r\n // The video travels as a serve URL; the frame snapshot is re-captured by\r\n // the boot restore in index.tsx when needed.\r\n if (typeof d.videoUrl === 'string') setWpVideoUrl(d.videoUrl, cfg.videoMime)\r\n else if (d.videoUrl === null) setWpVideoUrl(null, null)\r\n // The custom font travels as a serve URL too; the caller applies the\r\n // @font-face from it (config.fontEnabled decides whether it is active).\r\n if (typeof d.fontUrl === 'string') fontServeUrl = d.fontUrl\r\n else if (d.fontUrl === null) fontServeUrl = null\r\n // Mirror the same rev'd URL setWpImageUrl stored, so wpUrl never diverges.\r\n if (cfg.backgroundType === 'image') setWpUrl(rWpImage())\r\n return { rotated: d.rotated === true, firstRun: d.firstRun === true }\r\n }\r\n return { rotated: false, firstRun: false }\r\n}\r\n\r\n/** Persist a wallpaper (null removes it); one-shot, no debounce. */\r\nexport function persistWallpaper(dataUrl: string | null): void {\r\n void rpcCall('setWallpaper', { dataUrl })\r\n}\r\n\r\n/** Persist a background video (null removes it); resolves true once on disk,\r\n * so callers only switch playback to the serve URL after acceptance. */\r\nexport async function persistVideo(dataUrl: string | null): Promise<boolean> {\r\n const res = await rpcCall('setVideo', { dataUrl })\r\n return res === true\r\n}\r\n\r\n/** Download a wallpaper from a network URL and persist it into the local slot\r\n * (the host replaces wallpaper.jpg). Returns the freshly stored serve URL on\r\n * success, or the host's failure message. */\r\nexport async function setWallpaperFromUrl(url: string): Promise<{ ok: boolean; wallpaperUrl?: string | null; error?: string }> {\r\n if (!rpcCallFn) return { ok: false, error: 'rpc not ready' }\r\n let res: RpcResultLike | undefined\r\n try {\r\n res = await rpcCallFn(rpcEndpoint('setWallpaperUrl'), { url })\r\n } catch (e) {\r\n return { ok: false, error: e instanceof Error ? e.message : String(e) }\r\n }\r\n if (!res) return { ok: false, error: 'no response' }\r\n if (res.ok !== true) {\r\n const err = (res as { error?: { message?: string } }).error\r\n return { ok: false, error: err?.message ?? 'request failed' }\r\n }\r\n const v = res.value as { ok?: boolean; wallpaperUrl?: string | null; error?: string }\r\n return v?.ok === true\r\n ? { ok: true, wallpaperUrl: v.wallpaperUrl ?? null }\r\n : { ok: false, error: v?.error ?? 'failed' }\r\n}\r\n\r\n/** Download a background video from a network URL. The server streams it into\r\n * the video slot and returns the resolved MIME for playback via the serve URL. */\r\nexport async function setVideoFromUrl(url: string): Promise<{ ok: boolean; mime?: string; error?: string }> {\r\n if (!rpcCallFn) return { ok: false, error: 'rpc not ready' }\r\n let res: RpcResultLike | undefined\r\n try {\r\n res = await rpcCallFn(rpcEndpoint('setVideoUrl'), { url })\r\n } catch (e) {\r\n return { ok: false, error: e instanceof Error ? e.message : String(e) }\r\n }\r\n if (!res) return { ok: false, error: 'no response' }\r\n if (res.ok !== true) {\r\n const err = (res as { error?: { message?: string } }).error\r\n return { ok: false, error: err?.message ?? 'request failed' }\r\n }\r\n const v = res.value as { ok?: boolean; mime?: string; error?: string }\r\n return v?.ok === true\r\n ? { ok: true, mime: v.mime ?? 'video/mp4' }\r\n : { ok: false, error: v?.error ?? 'failed' }\r\n}\r\n\r\n/** Map a refused upload response onto an outcome. The body has to be read: the\r\n * node half names the reason there, and an oversized transfer answers\r\n * `413 { ok:false, error:'too large', limit:'100 MB' }`. Checking `res.ok`\r\n * alone threw that away, so an oversized upload surfaced as a bare failure —\r\n * or, on the wallpaper path, as nothing at all. */\r\nasync function refusedUpload(res: Response): Promise<UploadOutcome> {\r\n const body = await res.json().catch(() => null) as { error?: unknown; limit?: unknown } | null\r\n if (body?.error === 'too large') {\r\n return {\r\n ok: false,\r\n refusal: {\r\n kind: 'too-large',\r\n status: res.status,\r\n limit: typeof body.limit === 'string' ? body.limit : undefined,\r\n },\r\n }\r\n }\r\n return { ok: false, refusal: { kind: 'http', status: res.status } }\r\n}\r\n\r\n/** Localized description of a refusal for the panel's toast. `fallbackKey` is\r\n * the caller's own \"…upload failed\" string, used for anything that is not a\r\n * size refusal. */\r\nexport function uploadRefusalText(o: UploadOutcome, t: (key: string) => string, fallbackKey: string): string {\r\n if (o.refusal?.kind === 'too-large') {\r\n const limit = o.refusal.limit ?? ''\r\n return t('uploadTooLarge').split('{limit}').join(limit)\r\n }\r\n if (o.refusal !== undefined) return `${t(fallbackKey)} (http ${o.refusal.status})`\r\n return t(fallbackKey)\r\n}\r\n\r\n/** Upload a video's raw bytes over HTTP (MIME in Content-Type, body untouched\r\n * — no base64 inflation that would blow the RPC body limit on large clips). */\r\nexport async function uploadVideo(blob: Blob, mime: string): Promise<UploadOutcome> {\r\n try {\r\n const res = await fetch(VIDEO_UPLOAD_URL, {\r\n method: 'POST',\r\n headers: { 'Content-Type': mime || 'application/octet-stream' },\r\n body: blob,\r\n })\r\n return res.ok ? { ok: true } : await refusedUpload(res)\r\n } catch (e) {\r\n console.warn('dsh-any-background: video upload failed', e)\r\n return { ok: false }\r\n }\r\n}\r\n\r\n/** Upload a wallpaper's raw bytes over HTTP — same streaming model as videos,\r\n * original pixels preserved, zero base64 round-trips. */\r\nexport async function uploadWallpaper(blob: Blob): Promise<UploadOutcome> {\r\n try {\r\n const res = await fetch(WALLPAPER_UPLOAD_URL, {\r\n method: 'POST',\r\n headers: { 'Content-Type': blob.type || 'image/jpeg' },\r\n body: blob,\r\n })\r\n return res.ok ? { ok: true } : await refusedUpload(res)\r\n } catch (e) {\r\n console.warn('dsh-any-background: wallpaper upload failed', e)\r\n return { ok: false }\r\n }\r\n}\r\n\r\n/** Upload a custom font's raw bytes over HTTP; resolves the sniffed MIME on\r\n * success, or a refusal the caller can report (an oversized font used to be\r\n * indistinguishable from a corrupt one). */\r\nexport async function uploadFont(blob: Blob): Promise<UploadOutcome & { mime?: string }> {\r\n try {\r\n const res = await fetch(FONT_UPLOAD_URL, {\r\n method: 'POST',\r\n headers: { 'Content-Type': blob.type || 'application/octet-stream' },\r\n body: blob,\r\n })\r\n if (!res.ok) return await refusedUpload(res)\r\n const data = await res.json().catch(() => null) as { mime?: string } | null\r\n return { ok: true, mime: typeof data?.mime === 'string' ? data.mime : 'font/ttf' }\r\n } catch (e) {\r\n console.warn('dsh-any-background: font upload failed', e)\r\n return { ok: false }\r\n }\r\n}\r\n\r\n/** Remove the stored custom font (server deletes every variant + clears the\r\n * recorded MIME); resolves true once the slot is empty. */\r\nexport async function removeFont(): Promise<boolean> {\r\n const res = await rpcCall('removeFont', {})\r\n return res === true\r\n}\r\n\r\n// ── Wallpaper rotation RPCs ──────────────────────────────────────────────────\r\n\r\nexport interface RotationAddResult { ok: boolean; index?: number; items?: Array<{ file: string; thumb: string }>; error?: string }\r\n\r\n/** Add an image (data URL + small thumbnail) to the server-side rotation pool. */\r\nexport async function rotationAdd(dataUrl: string, thumb: string): Promise<RotationAddResult> {\r\n if (!rpcCallFn) return { ok: false, error: 'rpc not ready' }\r\n try {\r\n const res = await rpcCallFn(rpcEndpoint('rotationAdd'), { dataUrl, thumb })\r\n if (res && res.ok === true) return (res.value ?? { ok: false, error: 'no value' }) as RotationAddResult\r\n return { ok: false, error: (res as { error?: { message?: string } })?.error?.message ?? 'request failed' }\r\n } catch (e) {\r\n return { ok: false, error: e instanceof Error ? e.message : String(e) }\r\n }\r\n}\r\n\r\n/** Remove a rotation item by index. Returns the updated items list. */\r\nexport async function rotationRemove(index: number): Promise<{ ok: boolean; items?: Array<{ file: string; thumb: string }>; error?: string }> {\r\n if (!rpcCallFn) return { ok: false, error: 'rpc not ready' }\r\n try {\r\n const res = await rpcCallFn(rpcEndpoint('rotationRemove'), { index })\r\n if (res && res.ok === true) return (res.value ?? { ok: false, error: 'no value' }) as { ok: boolean; items?: Array<{ file: string; thumb: string }>; error?: string }\r\n return { ok: false, error: (res as { error?: { message?: string } })?.error?.message ?? 'request failed' }\r\n } catch (e) {\r\n return { ok: false, error: e instanceof Error ? e.message : String(e) }\r\n }\r\n}\r\n\r\n/** Activate a rotation item: the server copies its bytes into the wallpaper\r\n * slot and returns the serve URL for immediate display. */\r\nexport async function rotationActivate(index: number): Promise<{ ok: boolean; wallpaperUrl?: string; error?: string }> {\r\n if (!rpcCallFn) return { ok: false, error: 'rpc not ready' }\r\n try {\r\n const res = await rpcCallFn(rpcEndpoint('rotationSet'), { index })\r\n if (res && res.ok === true) return (res.value ?? { ok: false, error: 'no value' }) as { ok: boolean; wallpaperUrl?: string; error?: string }\r\n return { ok: false, error: (res as { error?: { message?: string } })?.error?.message ?? 'request failed' }\r\n } catch (e) {\r\n return { ok: false, error: e instanceof Error ? e.message : String(e) }\r\n }\r\n}\r\n","/**\n * The plugin's ONE vocabulary for host-dependent decisions.\n *\n * Everything downstream asks a QUESTION (\"who owns the guide surface?\", \"which CSS\n * arm applies?\") and gets an answer from the current adapter. No consumer names a\n * release. That is what keeps the per-version folders honest: when 0.1.8 needs a\n * new behaviour, a consumer changes by reading a new adapter field, not by growing\n * another version comparison.\n *\n * @module\n */\nimport { adapterResolved, rHostAdapter } from './release'\nimport type { HostAdapter } from './versions/types'\n\n/** Who should carry the plugin's appearance page on the host's guide surface.\n *\n * `host` — the host's own right Sidebar already presents an appearance page, so\n * the plugin's dsh-better-sidebar page stands down (a second identical\n * card on the same surface).\n * `plugin` — it does not, so the dsh-better-sidebar page registers and the native\n * tab yields to it.\n * `pending` — the verdict has not landed yet (it is a Node round-trip). Callers\n * must NOT treat this as `plugin`: register provisionally and arm a\n * withdrawal, because a brief duplicate is recoverable while a missing\n * page is invisible until someone looks. */\nexport type GuideOwner = 'host' | 'plugin' | 'pending'\n\nexport function sidebarGuideOwner(): GuideOwner {\n if (!adapterResolved()) return 'pending'\n return rHostAdapter().surface.ownsSidebarGuideSurface ? 'host' : 'plugin'\n}\n\n/** The `[data-slot=\"<key>\"]` selectors marking the session header's surfaces.\n * Built from the adapter so a release that adds or deletes an anchor needs no\n * change here — see the `headerSlotKeys` notes in each version folder. */\nexport function headerSlotSelectors(): string[] {\n return rHostAdapter().surface.headerSlotKeys.map(key => `[data-slot=\"${key}\"]`)\n}\n\n/** The current adapter, for callers that need more than one field from it (and to\n * keep the snapshot identity stable across a single render pass). */\nexport function hostAdapter(): HostAdapter {\n return rHostAdapter()\n}\n","/**\n * Header-surface tagging.\n *\n * WHY A RUNTIME TAG IS NEEDED\n * The session-header dropdowns (open-in-app, session-log, Agent Team, the job\n * list, the subagent lineage tree) render their popover through the Menu/tree\n * primitives, which PORTAL the list to `document.body`. A portaled list is not a\n * DOM descendant of the header — no ancestor selector can reach it — and the\n * primitive emits no `id`/`aria-controls` back-link to its anchor either. Pure\n * CSS class matching was the remaining option, but 0.1.7 broke the shapes this\n * plugin relied on: open-in-app moved from in-place to `portal` (so the old\n * `:not(_portal)` discriminator no longer selected it), and the session row menu\n * became a dynamic `sidebar.workspaces.session.menu.item` slot whose rows are no\n * longer guaranteed to include a destructive one.\n *\n * THE SIGNAL\n * The slot renderer stamps every registered slot with `data-slot=\"<key>\"`\n * (ui-renderer `scoped-slots.tsx`). Those anchors live in the header subtree, so\n * the plugin can detect when a header trigger is expanded — which keys identify\n * the header is a per-release fact and comes from the host adapter, not from a\n * hardcoded list here.\n *\n * WHY NOT GEOMETRY\n * A tempting link is the inline position the primitive writes on a portaled list\n * (`style=\"left: …; top: …\"`). It was tried and REJECTED: an `align=\"end\"` list\n * is flush to the trigger's right edge while the trigger itself sits at the far\n * right of the header, so the two boxes often do not overlap horizontally (in\n * the reported DOM the list is at `left:1012` with the trigger near x=1400). Any\n * purely geometric proximity test therefore misses real header menus.\n *\n * THE ACTUAL RULE (structural, no geometry, no timing)\n * A header dropdown can only be open while its trigger reports\n * `aria-expanded=\"true\"`, and opening one is what mounts the popover. So a\n * popover tag is maintained as: \"there is at least one expanded header trigger,\n * AND this popover is not owned by another group\". Popovers are only ever\n * tagged/released on a change of that combined state, which makes the tag\n * self-consistent and idempotent.\n *\n * The one hazard is a popover that is open for an unrelated reason (a composer\n * menu, a hover card) *while* a header trigger stays expanded. Such a popover\n * is not a candidate: it is excluded by `ownsForeignSurface`, which skips any\n * popover carrying markers of a different slider group. In practice header\n * dropdowns are transient (opening one closes the others), so this is a guard\n * rather than the common path.\n *\n * @module\n */\n\nimport { hostAdapter } from './host-compat/capabilities'\n\n/** Marker attribute the stylesheet keys on. */\nexport const HEADER_POPOVER_ATTR = 'data-dsh-any-header-popover'\n\n/** Portaled popovers a header trigger can own. */\nconst POPOVER_SELECTOR = '[role=\"menu\"], [role=\"tree\"], [role=\"dialog\"]'\n\n/** Which session-header slot anchors to watch — supplied by the host adapter,\n * because the set is not the same on every release: 0.1.6-alpha.2 registers a\n * sixth (`.leading`) that neither the line before nor the line after has.\n * Memoised on the array identity, which the adapter keeps stable until the\n * release verdict lands. */\nlet slotAnchorCache: { keys: readonly string[]; selector: string } | null = null\nfunction headerSlotAnchors(): string {\n const keys = hostAdapter().surface.headerSlotKeys\n if (slotAnchorCache === null || slotAnchorCache.keys !== keys) {\n slotAnchorCache = { keys, selector: keys.map(key => `[data-slot=\"${key}\"]`).join(',') }\n }\n return slotAnchorCache.selector\n}\n\n/** Whether any header slot anchor has an expanded trigger. */\nfunction headerTriggerOpen(): boolean {\n for (const anchor of document.querySelectorAll(headerSlotAnchors())) {\n if (anchor.querySelector('[aria-expanded=\"true\"]') !== null) return true\n }\n return false\n}\n\n/** Surfaces that belong to a different slider group and must never be claimed.\n * `_denseList` without `_portal` is the in-place card-side dense menu, an\n * `_ioCard`/`_menu`-classed body-level list belongs elsewhere, and a modal is\n * its own surface. */\nfunction ownsForeignSurface(el: Element): boolean {\n if (el.getAttribute('aria-modal') === 'true') return true\n // A list that is not directly under <body> is an in-place popover owned by\n // whatever subtree it lives in (composer menus), never the header.\n return el.parentElement !== document.body\n}\n\nlet observer: MutationObserver | null = null\nlet raf: number | null = null\n\n/** Recompute tags from the current open state. */\nfunction refreshHeaderPopovers(): void {\n const open = headerTriggerOpen()\n const candidates = [...document.querySelectorAll(POPOVER_SELECTOR)].filter(el => !ownsForeignSurface(el))\n if (!open) {\n for (const el of document.querySelectorAll(`[${HEADER_POPOVER_ATTR}]`)) {\n el.removeAttribute(HEADER_POPOVER_ATTR)\n }\n return\n }\n // A header dropdown is open: claim body-level popovers, releasing any that\n // stopped being candidates (detached, or re-classified as foreign).\n for (const el of candidates) el.setAttribute(HEADER_POPOVER_ATTR, '')\n for (const el of document.querySelectorAll(`[${HEADER_POPOVER_ATTR}]`)) {\n if (!candidates.includes(el)) el.removeAttribute(HEADER_POPOVER_ATTR)\n }\n}\n\nfunction schedule(): void {\n if (raf !== null) return\n raf = window.requestAnimationFrame(() => {\n raf = null\n refreshHeaderPopovers()\n })\n}\n\n/** Start tagging. Returns a teardown that stops observing and clears markings. */\nexport function startHeaderPopoverTagging(): () => void {\n if (typeof MutationObserver === 'undefined' || typeof document === 'undefined') return () => {}\n refreshHeaderPopovers()\n observer = new MutationObserver(schedule)\n // Attribute + childList across the body subtree: a popover mounting and an\n // `aria-expanded` flipping both land here. Character data is irrelevant.\n observer.observe(document.body, {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: ['aria-expanded'],\n })\n return () => {\n observer?.disconnect()\n observer = null\n if (raf !== null) { window.cancelAnimationFrame(raf); raf = null }\n for (const el of document.querySelectorAll(`[${HEADER_POPOVER_ATTR}]`)) {\n el.removeAttribute(HEADER_POPOVER_ATTR)\n }\n }\n}\n","/**\r\n * Read a chosen image file as a data URL WITHOUT re-encoding: the original\r\n * pixels are kept as-is (no canvas downscale / JPEG re-compression), so the\r\n * wallpaper is stored and displayed at full fidelity. The tradeoff is a larger\r\n * payload over the RPC channel and on disk for big images.\r\n */\r\nexport function readImg(file: File, cb: (url: string | null) => void): void {\r\n const r = new FileReader()\r\n r.onerror = () => cb(null)\r\n r.onload = () => cb(r.result as string)\r\n r.readAsDataURL(file)\r\n}\r\n\r\n/** Promised readImg variant for async flows. */\r\nexport function readImgAsync(file: File): Promise<string | null> {\r\n return new Promise(resolve => readImg(file, resolve))\r\n}\r\n\r\n/** Blob → data URL (used when a local asset must be embedded, e.g. theme export). */\r\nexport function blobToDataUrl(blob: Blob): Promise<string> {\r\n return new Promise<string>((resolve, reject) => {\r\n const fr = new FileReader()\r\n fr.onload = () => resolve(fr.result as string)\r\n fr.onerror = () => reject(fr.error)\r\n fr.readAsDataURL(blob)\r\n })\r\n}\r\n\r\n// Shared decoded-image cache. The boot path decodes the same wallpaper URL up\r\n// to four times (palette extract, brightness verdict, low-res capture,\r\n// intrinsic size); memoizing the decoded element turns those into one decode.\r\nconst IMG_CACHE_MAX = 6\r\nconst imgCache = new Map<string, Promise<HTMLImageElement | null>>()\r\n\r\n/** Decode an image URL once and share the element across callers (LRU-capped). */\r\nexport function loadImage(url: string): Promise<HTMLImageElement | null> {\r\n const hit = imgCache.get(url)\r\n if (hit) {\r\n imgCache.delete(url)\r\n imgCache.set(url, hit)\r\n return hit\r\n }\r\n const p = new Promise<HTMLImageElement | null>(resolve => {\r\n const img = new Image()\r\n img.onerror = () => resolve(null)\r\n img.onload = () => resolve(img)\r\n img.src = url\r\n })\r\n imgCache.set(url, p)\r\n while (imgCache.size > IMG_CACHE_MAX) {\r\n const oldest = imgCache.keys().next().value\r\n if (oldest !== undefined) imgCache.delete(oldest)\r\n }\r\n return p\r\n}\r\n\r\n/** Build a small JPEG thumbnail (rotation-pool picker preview). Resolves null\r\n * when the image cannot be decoded. */\r\nexport function makeThumb(dataUrl: string, maxSide = 96): Promise<string | null> {\r\n return new Promise(resolve => {\r\n const img = new Image()\r\n img.onerror = () => resolve(null)\r\n img.onload = () => {\r\n try {\r\n const iw = img.naturalWidth || img.width\r\n const ih = img.naturalHeight || img.height\r\n if (iw <= 0 || ih <= 0) { resolve(null); return }\r\n const k = Math.min(1, maxSide / Math.max(iw, ih))\r\n const c = document.createElement('canvas')\r\n c.width = Math.max(1, Math.round(iw * k))\r\n c.height = Math.max(1, Math.round(ih * k))\r\n const g = c.getContext('2d')\r\n if (!g) { resolve(null); return }\r\n g.drawImage(img, 0, 0, c.width, c.height)\r\n resolve(c.toDataURL('image/jpeg', 0.72))\r\n } catch {\r\n resolve(null)\r\n }\r\n }\r\n img.src = dataUrl\r\n })\r\n}\r\n","import type { BgState, ColorPalette } from '../types'\r\nimport { loadImage } from './image'\r\n\r\n// The wheel works in HSV end to end; storage and genTokens expect HSL, so\r\n// setColor converts HSV → HSL at the boundary and sectionInject converts the\r\n// stored HSL → HSV for the initial wheel props. Conversions never stack.\r\n\r\nexport function hsvToHsl(h: number, s: number, v: number): [number, number, number] {\r\n const l = v * (1 - s / 2)\r\n const sl = l === 0 || l === 1 ? 0 : (v - l) / Math.min(l, 1 - l)\r\n return [h, sl, l]\r\n}\r\n\r\nexport function hslToHsv(h: number, s: number, l: number): [number, number, number] {\r\n const v = l + s * Math.min(l, 1 - l)\r\n const sv = v === 0 ? 0 : 2 * (1 - l / v)\r\n return [h, sv, v]\r\n}\r\n\r\n/** Format an RGB triple as a lowercase hex string. Channels are rounded: some\r\n * callers feed float channels and a fractional byte would produce invalid\r\n * hex. */\r\nexport function rgbToHex(rgb: [number, number, number]): string {\r\n return '#' + rgb.map(v => Math.round(v).toString(16).padStart(2, '0')).join('')\r\n}\r\n\r\nlet tokensCacheKey = ''\r\nlet tokensCache: { colorScheme: 'light' | 'dark'; tokens: Record<string, string> } | null = null\r\n\r\n/**\r\n * Memoized token generation: the same (hue, sat, lit, scheme) input always\r\n * yields the same token set, and applyWp / applyCustomTokens /\r\n * applySettingsOverrides call this repeatedly (slider drags, viewport\r\n * re-applies), so cache the last result and skip the 30+ hsl() string builds\r\n * when nothing changed. The optional scheme forces the palette direction\r\n * (light/dark) independently of the color's own lightness.\r\n */\r\nexport function genTokens(hue: number, sat: number, lit: number, scheme?: 'light' | 'dark'): { colorScheme: 'light' | 'dark'; tokens: Record<string, string> } {\r\n const key = `${hue}|${sat}|${lit}|${scheme ?? 'auto'}`\r\n if (tokensCacheKey === key && tokensCache) return tokensCache\r\n tokensCacheKey = key\r\n tokensCache = buildTokens(hue, sat, lit, scheme)\r\n return tokensCache\r\n}\r\n\r\nfunction buildTokens(hue: number, sat: number, lit: number, scheme?: 'light' | 'dark'): { colorScheme: 'light' | 'dark'; tokens: Record<string, string> } {\r\n // `scheme ?? lit < 0.55` would hand back the STRING 'light' (truthy) and\r\n // route both forced directions into the dark branch — compare explicitly.\r\n const dark = scheme !== undefined ? scheme === 'dark' : lit < 0.55\r\n // Every token is an offset around the base lightness, so a scheme that\r\n // contradicts the pick's band (a forced dark over a light color) would\r\n // build \"dark\" surfaces that stay light. Mirror the lightness into the\r\n // target band instead — hue/saturation carry over, the stored pick itself\r\n // is untouched (this is a display-time remap, not a config change).\r\n if (scheme !== undefined && (lit < 0.55) !== dark) {\r\n lit = dark\r\n ? Math.min(0.44, Math.max(0.14, 1 - lit))\r\n : Math.max(0.6, Math.min(0.88, 1 - lit))\r\n }\r\n const h = (d: number) => ((hue + d) % 360 + 360) % 360\r\n const s = (d: number) => Math.max(0, Math.min(1, sat + d))\r\n const l = (d: number) => Math.max(0, Math.min(1, lit + d))\r\n const hsl = (hh: number, ss: number, ll: number) => `hsl(${Math.round(hh)},${Math.round(ss * 100)}%,${Math.round(ll * 100)}%)`\r\n const rgba = (hh: number, ss: number, ll: number, a: number) =>\r\n `hsla(${Math.round(hh)},${Math.round(ss * 100)}%,${Math.round(ll * 100)}%,${a})`\r\n\r\n if (dark) {\r\n return {\r\n colorScheme: 'dark',\r\n tokens: {\r\n '--dsw-alias-bg-base': hsl(h(0), s(0), l(-0.04)),\r\n '--dsw-alias-bg-layer-1': hsl(h(0), s(0), l(0.02)),\r\n '--dsw-alias-bg-layer-2': hsl(h(0), s(0), l(0.07)),\r\n '--dsw-alias-bg-layer-3': hsl(h(0), s(-0.05), l(0.12)),\r\n '--dsw-alias-bg-overlay': hsl(h(0), s(-0.05), l(0.12)),\r\n '--dsw-alias-bg-module-platform': hsl(h(0), s(0), l(0.05)),\r\n '--dsw-alias-bg-multi-select': hsl(h(0), s(0), l(0.1)),\r\n '--dsw-alias-bg-skeleton': 'rgba(255,255,255,0.08)',\r\n '--dsw-alias-border-l1': rgba(h(0), s(-0.1), l(0.18), 0.12),\r\n '--dsw-alias-border-l2': rgba(h(0), s(-0.1), l(0.22), 0.22),\r\n '--dsw-alias-border-l3': 'rgba(255,255,255,0.16)',\r\n '--dsw-alias-border-l4': 'rgba(255,255,255,0.2)',\r\n '--dsw-alias-border-inverted': 'rgba(255,255,255,0.06)',\r\n '--dsw-alias-label-primary': hsl(0, 0, 1),\r\n '--dsw-alias-label-secondary': 'rgba(255,255,255,0.85)',\r\n '--dsw-alias-label-tertiary': 'rgba(255,255,255,0.7)',\r\n // Placeholder/dim hint — deliberately weaker than the text tiers so a\r\n // placeholder reads as a hint, never as real input.\r\n '--dsw-alias-label-caption': 'rgba(255,255,255,0.5)',\r\n '--dsw-alias-label-dimmed': 'rgba(255,255,255,0.35)',\r\n '--dsw-alias-label-quaternary': 'rgba(255,255,255,0.25)',\r\n '--dsw-alias-label-primary-dimmed': 'rgba(255,255,255,0.92)',\r\n '--dsw-alias-label-primary-foreground': hsl(0, 0, 1),\r\n // Inverted label sits on a light brand/contrast/badge surface in dark\r\n // mode, so it must be dark ink, not white.\r\n '--dsw-alias-label-primary-inverted': hsl(h(0), s(0.08), Math.min(l(0.06), 0.16)),\r\n '--dsw-alias-label-primary-bluish': hsl(0, 0, 1),\r\n '--dsw-alias-brand-primary': hsl(h(0), s(0.1), Math.max(l(0.2), 0.5)),\r\n '--dsw-alias-brand-text': l(0.2) > 0.6 ? '#000' : '#fff',\r\n '--dsw-alias-button-primary-fill': hsl(h(0), s(0.1), Math.max(l(0.2), 0.5)),\r\n '--dsw-alias-button-primary-hover': hsl(h(0), s(0.1), Math.max(l(0.28), 0.58)),\r\n '--dsw-alias-button-primary-dimmed': hsl(h(0), s(0), l(0.07)),\r\n '--dsw-alias-button-elevated-fill': hsl(h(0), s(0), l(0.04)),\r\n '--dsw-alias-button-floating-fill': hsl(h(0), s(0), l(0.02)),\r\n '--dsw-alias-button-floating-hover': hsl(h(0), s(0), l(0.1)),\r\n '--dsw-alias-button-tool-bar-fill': 'rgba(255,255,255,0.08)',\r\n '--dsw-alias-button-tool-bar-hover': 'rgba(255,255,255,0.12)',\r\n '--dsw-alias-button-ghost-active-fill': hsl(h(0), s(0), l(0.06)),\r\n '--dsw-alias-button-ghost-active-border': 'rgba(255,255,255,0.16)',\r\n '--dsw-alias-button-ghost-active-hover': hsl(h(0), s(0), l(0.09)),\r\n '--dsw-alias-button-info-fill': '#679efe',\r\n '--dsw-alias-button-info-hover': '#4176e6',\r\n '--dsw-alias-button-contrast-fill': hsl(0, 0, 1),\r\n '--dsw-alias-interactive-bg-hover': rgba(h(0), s(0), Math.max(l(0.15), 0.4), 0.12),\r\n '--dsw-alias-interactive-bg-hover-solid': rgba(h(0), s(0), Math.max(l(0.15), 0.4), 0.16),\r\n '--dsw-alias-interactive-bg-hover-accent': 'rgba(255,255,255,0.24)',\r\n '--dsw-alias-interactive-bg-hover-danger': 'rgba(242,90,90,0.15)',\r\n '--dsw-alias-interactive-bg-active': rgba(h(0), s(0), Math.max(l(0.15), 0.4), 0.2),\r\n '--dsw-alias-markdown-code-block': hsl(h(0), s(0), l(-0.06)),\r\n '--dsw-alias-markdown-code-block-banner': hsl(h(0), s(0), l(-0.02)),\r\n '--dsw-alias-markdown-inline-code': hsl(h(0), s(0), l(0.04)),\r\n '--dsw-alias-markdown-placeholder': hsl(h(0), s(0), l(-0.02)),\r\n '--dsw-alias-markdown-tag': hsl(h(0), s(0), l(0.05)),\r\n '--dsw-alias-markdown-citation': hsl(h(0), s(0), l(0.06)),\r\n '--dsw-alias-markdown-code-segment-selected': hsl(h(0), s(0), l(0.05)),\r\n '--dsw-alias-markdown-code-segment-unselected': hsl(h(0), s(0), l(-0.05)),\r\n '--dsw-alias-state-error-primary': '#ff5c72',\r\n '--dsw-alias-state-error-secondary': '#ff8aa0',\r\n '--dsw-alias-state-success-primary': '#3ddc84',\r\n '--dsw-alias-state-success-secondary': '#69eea4',\r\n // Badge tertiary tokens are the static dark surfaces the UI draws\r\n // over (trajectory tool/context badges, connection pill, plan chip):\r\n // aligning them with the native dark 800/900 steps keeps light fix label\r\n // text readable instead of tint-same-as-background (issue #9).\r\n '--dsw-alias-state-success-tertiary': '#233c2c',\r\n '--dsw-alias-state-warn-primary': '#ffb347',\r\n '--dsw-alias-state-warn-secondary': '#ffc980',\r\n '--dsw-alias-state-warn-tertiary': '#27241f',\r\n '--dsw-alias-state-warn-label': '#dd8629',\r\n '--dsw-alias-state-business-primary': '#679efe',\r\n '--dsw-alias-state-business-tertiary': '#34415b',\r\n '--dsw-specific-sidebar-fill': hsl(h(0), s(0), l(-0.06)),\r\n '--dsw-specific-sidebar-nav-item-active': hsl(h(0), s(0), l(0.04)),\r\n '--dsw-specific-sidebar-nav-item-hover': hsl(h(0), s(0), l(0)),\r\n '--dsw-specific-input-major': hsl(h(0), s(0), l(0.02)),\r\n '--dsw-specific-menu': hsl(h(0), s(0), l(0.08)),\r\n '--dsw-specific-bubble': hsl(h(0), s(0), l(0.03)),\r\n '--dsw-specific-bubble-highlight': hsl(h(0), s(0), l(0.08)),\r\n '--dsw-specific-selector': hsl(h(0), s(0), l(0.05)),\r\n '--dsw-specific-login-input': hsl(h(0), s(0), l(0.03)),\r\n '--dsw-specific-tip': hsl(h(0), s(0), l(0.05)),\r\n '--dsw-alias-toast-bg': hsl(h(0), s(0), l(0.08)),\r\n '--dsw-alias-tooltip-bg': hsl(h(0), s(0), l(0.08)),\r\n '--dsw-alias-scrollbar-bg-l1': hsl(h(0), s(-0.05), l(0.12)),\r\n '--dsw-alias-scrollbar-bg-l2': hsl(h(0), s(-0.05), l(0.16)),\r\n '--dsw-alias-scrollbar-hover-l1': hsl(h(0), s(-0.05), l(0.22)),\r\n '--dsw-alias-scrollbar-hover-l2': hsl(h(0), s(-0.05), l(0.22)),\r\n },\r\n }\r\n }\r\n return {\r\n colorScheme: 'light',\r\n tokens: {\r\n '--dsw-alias-bg-base': hsl(h(0), s(-0.08), l(0.03)),\r\n '--dsw-alias-bg-layer-1': hsl(h(0), s(-0.12), l(0.07)),\r\n '--dsw-alias-bg-layer-2': hsl(h(0), s(-0.1), l(-0.03)),\r\n '--dsw-alias-bg-layer-3': hsl(h(0), s(-0.08), l(-0.09)),\r\n '--dsw-alias-bg-overlay': hsl(h(0), s(-0.12), l(0.08)),\r\n '--dsw-alias-border-l1': rgba(h(0), s(-0.15), l(-0.35), 0.18),\r\n '--dsw-alias-border-l2': rgba(h(0), s(-0.15), l(-0.35), 0.3),\r\n '--dsw-alias-label-primary': hsl(0, 0, 0),\r\n '--dsw-alias-label-secondary': 'rgba(0,0,0,0.85)',\r\n '--dsw-alias-label-tertiary': 'rgba(0,0,0,0.7)',\r\n // Placeholder/dim hint — deliberately weaker than the text tiers so a\r\n // placeholder reads as a hint, never as real input.\r\n '--dsw-alias-label-caption': 'rgba(0,0,0,0.5)',\r\n '--dsw-alias-label-dimmed': 'rgba(0,0,0,0.35)',\r\n '--dsw-alias-label-quaternary': 'rgba(0,0,0,0.25)',\r\n '--dsw-alias-brand-primary': hsl(h(0), s(0.05), Math.min(l(-0.18), 0.45)),\r\n '--dsw-alias-brand-text': '#fff',\r\n '--dsw-alias-button-primary-hover': hsl(h(0), s(0.05), Math.min(l(-0.12), 0.5)),\r\n '--dsw-alias-button-primary-dimmed': hsl(h(0), s(-0.1), l(-0.03)),\r\n '--dsw-alias-button-elevated-fill': hsl(h(0), s(-0.1), l(0.1)),\r\n '--dsw-alias-button-floating-hover': hsl(h(0), s(-0.1), l(0.16)),\r\n '--dsw-alias-interactive-bg-hover': rgba(h(0), s(0), l(-0.3), 0.08),\r\n '--dsw-alias-interactive-bg-active': rgba(h(0), s(0), l(-0.3), 0.14),\r\n '--dsw-alias-markdown-code-block': hsl(h(0), s(-0.1), l(-0.03)),\r\n '--dsw-alias-markdown-inline-code': hsl(h(0), s(-0.08), l(0.04)),\r\n '--dsw-specific-sidebar-fill': hsl(h(0), s(-0.1), l(-0.03)),\r\n '--dsw-specific-sidebar-nav-item-active': hsl(h(0), s(-0.08), l(0.05)),\r\n '--dsw-specific-sidebar-nav-item-hover': hsl(h(0), s(-0.12), l(0)),\r\n '--dsw-specific-input-major': hsl(h(0), s(-0.12), l(0.1)),\r\n '--dsw-specific-menu': hsl(h(0), s(-0.12), l(0.15)),\r\n '--dsw-alias-scrollbar-bg-l1': hsl(h(0), s(-0.1), l(-0.08)),\r\n '--dsw-alias-scrollbar-bg-l2': hsl(h(0), s(-0.08), l(-0.12)),\r\n '--dsw-alias-scrollbar-hover-l1': hsl(h(0), s(-0.08), l(-0.16)),\r\n '--dsw-alias-scrollbar-hover-l2': hsl(h(0), s(-0.08), l(-0.16)),\r\n },\r\n }\r\n}\r\n\r\nexport function toRgba(c: string, a: number): string {\r\n const hx = /^#([0-9a-f]{3}|[0-9a-f]{6})$/i.exec(c.trim())\r\n if (hx) { let d = hx[1]!; if (d.length === 3) d = d.split('').map(x => x + x).join(''); const n = parseInt(d, 16); return `rgba(${(n >> 16) & 255},${(n >> 8) & 255},${n & 255},${a})` }\r\n const rgb = /^rgba?\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)(?:\\s*,\\s*([\\d.]+))?\\s*\\)$/i.exec(c.trim())\r\n if (rgb) return `rgba(${rgb[1]},${rgb[2]},${rgb[3]},${a})`\r\n const hsl = /^hsla?\\(\\s*([\\d.]+)\\s*,\\s*([\\d.]+)%\\s*,\\s*([\\d.]+)%/i.exec(c.trim())\r\n if (hsl) return `hsla(${hsl[1]},${hsl[2]}%,${hsl[3]}%,${a})`\r\n return c.trim()\r\n}\r\n\r\nexport function rgbToHsl(r: number, g: number, b: number): [number, number, number] {\r\n const rn = r / 255, gn = g / 255, bn = b / 255\r\n const max = Math.max(rn, gn, bn), min = Math.min(rn, gn, bn)\r\n const l = (max + min) / 2\r\n if (max === min) return [0, 0, l]\r\n const d = max - min\r\n const s = l > 0.5 ? d / (2 - max - min) : d / (max + min)\r\n let h: number\r\n if (max === rn) h = ((gn - bn) / d) % 6\r\n else if (max === gn) h = (bn - rn) / d + 2\r\n else h = (rn - gn) / d + 4\r\n h *= 60\r\n if (h < 0) h += 360\r\n return [h, s, l]\r\n}\r\n\r\n// Wallpaper color extraction: decode the cached data URL → crop the visible\r\n// (framed) region → downsample to a 64×64 canvas → quantize pixels into 4-bit\r\n// RGB buckets → discard near-gray / near-black / near-white pixels → pick the\r\n// most populous vivid bucket (count × saturation bias) → average its members →\r\n// RGB→HSL → clamp lightness into a band that keeps the light/dark scheme\r\n// decision unambiguous. Purely client-side and memory-bounded.\r\n\r\nconst EXTRACT_SIDE = 64\r\n\r\ninterface Bucket { count: number; r: number; g: number; b: number; s: number }\r\n\r\nfunction bucketsToHsl(b: Bucket): [number, number, number] {\r\n return rgbToHsl(b.r / b.count, b.g / b.count, b.b / b.count)\r\n}\r\n\r\nfunction extractWallpaperPalette(dataUrl: string, bgState: BgState): Promise<ColorPalette | null> {\r\n return loadImage(dataUrl).then(img => {\r\n if (!img) return null\r\n try {\r\n const iw = img.naturalWidth || img.width\r\n const ih = img.naturalHeight || img.height\r\n const bg = bgState\r\n let sx = 0, sy = 0, sw = iw, sh = ih\r\n if (bg.iw === iw && bg.ih === ih && bg.iw > 0) {\r\n const fit = Math.min(window.innerWidth / iw, window.innerHeight / ih)\r\n const w = iw * fit * bg.zoom\r\n const h = ih * fit * bg.zoom\r\n // bg.x/bg.y are the image center's fractional viewport point, so the\r\n // image's top-left sits at (px, py) in viewport coordinates — the\r\n // same offset wallpaper.ts writes into background-position. The\r\n // visible source band is viewport [0, vw] mapped to source\r\n // [-px, vw - px], clipped to the image.\r\n const px = bg.x * window.innerWidth - w / 2\r\n const py = bg.y * window.innerHeight - h / 2\r\n sx = Math.max(0, -px)\r\n sy = Math.max(0, -py)\r\n sw = Math.min(iw - sx, window.innerWidth - px - sx)\r\n sh = Math.min(ih - sy, window.innerHeight - py - sy)\r\n if (sw <= 0 || sh <= 0) { sx = 0; sy = 0; sw = iw; sh = ih }\r\n }\r\n const c = document.createElement('canvas')\r\n c.width = EXTRACT_SIDE; c.height = EXTRACT_SIDE\r\n const g = c.getContext('2d', { willReadFrequently: true })!\r\n g.drawImage(img, sx, sy, sw, sh, 0, 0, EXTRACT_SIDE, EXTRACT_SIDE)\r\n const px = g.getImageData(0, 0, EXTRACT_SIDE, EXTRACT_SIDE).data\r\n const counts = new Uint32Array(4096)\r\n const sums = new Float64Array(4096 * 3)\r\n let totalLum = 0\r\n let sampled = 0\r\n for (let i = 0; i < px.length; i += 4) {\r\n const r = px[i], gg = px[i + 1], b = px[i + 2]\r\n const max = Math.max(r, gg, b), min = Math.min(r, gg, b)\r\n const v = max / 255\r\n const s = max === 0 ? 0 : (max - min) / max\r\n // Include all non-extreme pixels in luminance; only vivid pixels in\r\n // palette buckets so we don't theme around gray/black/white.\r\n // Rec.709 luma — the SAME measure analyzeFrameDark uses for the\r\n // brightness verdict, so the extracted lightness band and the\r\n // verdict can never disagree on a saturated frame.\r\n totalLum += (0.2126 * r + 0.7152 * gg + 0.0722 * b) / 255\r\n sampled++\r\n if (s < 0.08 || v < 0.12 || v > 0.97) continue\r\n const key = ((r >> 4) << 8) | ((gg >> 4) << 4) | (b >> 4)\r\n counts[key]++\r\n sums[key * 3] += r; sums[key * 3 + 1] += gg; sums[key * 3 + 2] += b\r\n }\r\n const buckets: Bucket[] = []\r\n for (let k = 0; k < 4096; k++) {\r\n if (counts[k] === 0) continue\r\n buckets.push({\r\n count: counts[k],\r\n r: sums[k * 3],\r\n g: sums[k * 3 + 1],\r\n b: sums[k * 3 + 2],\r\n s: (Math.max(sums[k * 3], sums[k * 3 + 1], sums[k * 3 + 2]) - Math.min(sums[k * 3], sums[k * 3 + 1], sums[k * 3 + 2])) / Math.max(sums[k * 3], sums[k * 3 + 1], sums[k * 3 + 2]) || 0,\r\n })\r\n }\r\n if (buckets.length === 0) { return null }\r\n // Sort by vivid-weighted count.\r\n buckets.sort((a, b) => b.count * (0.5 + b.s) - a.count * (0.5 + a.s))\r\n const primary = bucketsToHsl(buckets[0]!)\r\n const primaryHue = primary[0]\r\n // Secondary: next bucket that is reasonably separated from primary.\r\n let secondary = primary\r\n for (const b of buckets.slice(1)) {\r\n const [h] = bucketsToHsl(b)\r\n const sep = Math.abs(((h - primaryHue + 540) % 360) - 180)\r\n if (sep > 30) { secondary = bucketsToHsl(b); break }\r\n }\r\n // Tertiary: complementary-ish hue based on primary if no good secondary.\r\n let tertiary: [number, number, number] = [((primaryHue + 180) % 360), Math.min(0.7, primary[1]), Math.min(0.7, primary[2])]\r\n for (const b of buckets.slice(1)) {\r\n const [h] = bucketsToHsl(b)\r\n const sep = Math.abs(((h - primaryHue + 540) % 360) - 180)\r\n if (sep > 90 && sep < 150) { tertiary = bucketsToHsl(b); break }\r\n }\r\n // Surface: neutralized primary (very low saturation).\r\n const surface: [number, number, number] = [primaryHue, Math.min(0.06, primary[1] * 0.3), primary[2]]\r\n // Auto light/dark: use the average luminance of the whole image so a\r\n // bright wallpaper naturally drives a light scheme and vice-versa.\r\n const luminance = sampled > 0 ? totalLum / sampled : primary[2]\r\n // Snap primary lightness out of the ambiguous middle band.\r\n const autoDark = luminance < 0.5\r\n const lc = autoDark ? Math.min(0.44, Math.max(0.2, primary[2])) : Math.max(0.6, Math.min(0.82, primary[2]))\r\n primary[2] = lc\r\n return {\r\n primary: [primary[0], Math.min(0.9, Math.max(0.15, primary[1])), primary[2]],\r\n secondary: [secondary[0], Math.min(0.85, Math.max(0.2, secondary[1])), Math.min(0.75, Math.max(0.35, secondary[2]))],\r\n tertiary: [tertiary[0], Math.min(0.8, Math.max(0.2, tertiary[1])), Math.min(0.7, Math.max(0.35, tertiary[2]))],\r\n surface,\r\n luminance,\r\n }\r\n } catch {\r\n return null\r\n }\r\n })\r\n}\r\n\r\n/** Backward-compatible single-color extraction: returns the primary HSL. */\r\nexport async function extractWallpaperColor(dataUrl: string, bgState: BgState): Promise<[number, number, number] | null> {\r\n const palette = await extractWallpaperPalette(dataUrl, bgState)\r\n return palette ? palette.primary : null\r\n}\r\n\r\n// One-shot frame brightness analysis: called only when a generated background\r\n// is switched (from its captured snapshot), never from the animation loop.\r\n// Decode the frame, downsample to a 32×32 canvas, average Rec.709 luma.\r\n// Dark frame → light fonts, light frame → dark fonts.\r\n\r\nconst ANALYZE_SIDE = 32\r\n\r\n/** Analyze a captured frame's average luminance. Resolves true when the frame\r\n * reads dark (use white fonts), false when light (use black fonts), or null\r\n * when the frame cannot be decoded. */\r\nexport function analyzeFrameDark(dataUrl: string): Promise<boolean | null> {\r\n return loadImage(dataUrl).then(img => {\r\n if (!img) return null\r\n try {\r\n const c = document.createElement('canvas')\r\n c.width = ANALYZE_SIDE; c.height = ANALYZE_SIDE\r\n const g = c.getContext('2d', { willReadFrequently: true })!\r\n g.drawImage(img, 0, 0, ANALYZE_SIDE, ANALYZE_SIDE)\r\n const px = g.getImageData(0, 0, ANALYZE_SIDE, ANALYZE_SIDE).data\r\n let lum = 0\r\n const count = px.length / 4\r\n for (let i = 0; i < px.length; i += 4) {\r\n lum += 0.2126 * px[i]! + 0.7152 * px[i + 1]! + 0.0722 * px[i + 2]!\r\n }\r\n return lum / count / 255 < 0.5\r\n } catch {\r\n return null\r\n }\r\n })\r\n}\r\n\r\n/** HSL (h 0-360, s/l 0-1) → RGB (0-255 integers). */\r\nexport function hslToRgb(h: number, s: number, l: number): [number, number, number] {\r\n const c = (1 - Math.abs(2 * l - 1)) * s\r\n const hp = h / 60\r\n const x = c * (1 - Math.abs((hp % 2) - 1))\r\n let r = 0, g = 0, b = 0\r\n if (hp < 1) { r = c; g = x }\r\n else if (hp < 2) { r = x; g = c }\r\n else if (hp < 3) { g = c; b = x }\r\n else if (hp < 4) { g = x; b = c }\r\n else if (hp < 5) { r = x; b = c }\r\n else { r = c; b = x }\r\n const m = l - c / 2\r\n return [Math.round((r + m) * 255), Math.round((g + m) * 255), Math.round((b + m) * 255)]\r\n}\r\n","import type { GeneratedBgParams, MeshGradientParams, ShaderParams, PatternParams } from '../types'\r\n\r\n// The live full-screen canvas renders at a fraction of the CSS size — it sits\r\n// behind frosted/translucent UI anyway, so ~0.5–0.6px backing keeps it looking\r\n// sharp while drastically cutting fill/gradient cost per frame.\r\nconst RENDER_SCALE = 0.55\r\nconst FPS = 30\r\nconst FRAME_MS = 1000 / FPS\r\n\r\nexport interface LiveBgController {\r\n canvas: HTMLCanvasElement\r\n stop: () => void\r\n pause: () => void\r\n resume: () => void\r\n snapshot: () => string\r\n}\r\n\r\nfunction newRaf(canvas: HTMLCanvasElement, draw: () => void): { stop: () => void; pause: () => void; resume: () => void } {\r\n canvas.dataset.dshAnyCanvas = '1'\r\n let running = true\r\n let paused = false\r\n let rafId = 0\r\n let last = 0\r\n // Draw the very first frame synchronously so snapshot() right after creation\r\n // already yields a real frame (used by the preview, palette and export).\r\n draw()\r\n // Reduced-motion preference: keep the static first frame, never start the loop.\r\n if (typeof window.matchMedia === 'function' && window.matchMedia('(prefers-reduced-motion: reduce)').matches) {\r\n return { stop: () => { running = false }, pause: () => undefined, resume: () => undefined }\r\n }\r\n const loop = (ts: number) => {\r\n if (!running || paused) return\r\n if (ts - last >= FRAME_MS) { last = ts; draw() }\r\n rafId = requestAnimationFrame(loop)\r\n }\r\n rafId = requestAnimationFrame(loop)\r\n return {\r\n stop: () => { running = false; cancelAnimationFrame(rafId) },\r\n pause: () => { paused = true; cancelAnimationFrame(rafId) },\r\n resume: () => {\r\n if (!running || !paused) return\r\n paused = false\r\n last = 0\r\n rafId = requestAnimationFrame(loop)\r\n },\r\n }\r\n}\r\n\r\nfunction createCanvas(): HTMLCanvasElement {\r\n const c = document.createElement('canvas')\r\n c.style.cssText = 'position:absolute;inset:0;width:100%;height:100%;object-fit:cover;'\r\n return c\r\n}\r\n\r\nfunction liveSize(): { w: number; h: number } {\r\n const dpr = Math.min(window.devicePixelRatio || 1, 1.5)\r\n const w = Math.max(320, Math.ceil(window.innerWidth * dpr * RENDER_SCALE))\r\n const h = Math.max(180, Math.ceil(window.innerHeight * dpr * RENDER_SCALE))\r\n return { w, h }\r\n}\r\n\r\nfunction fitLiveCanvas(c: HTMLCanvasElement): void {\r\n const { w, h } = liveSize()\r\n if (c.width !== w || c.height !== h) { c.width = w; c.height = h }\r\n}\r\n\r\n// ── Deterministic seeded RNG ─────────────────────────────────────────────────\r\nfunction createRng(seed: number) {\r\n let s = seed > 0 ? seed : 1\r\n return () => {\r\n s ^= s << 13\r\n s ^= s >>> 17\r\n s ^= s << 5\r\n return (s >>> 0) / 0xffffffff\r\n }\r\n}\r\n\r\n// ── Seeded 2D noise (for canvas mesh / pattern motion) ──────────────────────\r\nfunction createNoise(seed: number) {\r\n const rng = createRng(seed)\r\n const perm: number[] = []\r\n for (let i = 0; i < 256; i++) perm[i] = i\r\n for (let i = 255; i > 0; i--) {\r\n const j = Math.floor(rng() * (i + 1))\r\n const t = perm[i]!; perm[i] = perm[j]!; perm[j] = t\r\n }\r\n for (let i = 0; i < 256; i++) perm[i + 256] = perm[i]!\r\n function fade(t: number) { return t * t * t * (t * (t * 6 - 15) + 10) }\r\n function lerp(a: number, b: number, t: number) { return a + (b - a) * t }\r\n function grad(hash: number, x: number, y: number) {\r\n const h = hash & 15\r\n const u = h < 8 ? x : y\r\n const v = h < 4 ? y : (h === 12 || h === 14) ? x : 0\r\n return ((h & 1) === 0 ? u : -u) + ((h & 2) === 0 ? v : -v)\r\n }\r\n return (x: number, y: number) => {\r\n const X = Math.floor(x) & 255\r\n const Y = Math.floor(y) & 255\r\n x -= Math.floor(x)\r\n y -= Math.floor(y)\r\n const u = fade(x)\r\n const v = fade(y)\r\n const A = perm[X]! + Y\r\n return lerp(\r\n lerp(grad(perm[A]!, x, y), grad(perm[A! + 1]!, x - 1, y), u),\r\n lerp(grad(perm[A! + 256]!, x, y - 1), grad(perm[A! + 257]!, x - 1, y - 1), u),\r\n v,\r\n )\r\n }\r\n}\r\n\r\n// ── Mesh gradient (animated) ──────────────────────────────────────────────────\r\nexport function createMeshGradient(params: MeshGradientParams, canvas?: HTMLCanvasElement): LiveBgController {\r\n const c = canvas ?? createCanvas()\r\n fitLiveCanvas(c)\r\n const g = c.getContext('2d', { alpha: false })!\r\n const rng = createRng(params.seed)\r\n const noise = createNoise(params.seed)\r\n const dark = rng() < 0.5\r\n const baseHue = Math.round(rng() * 360)\r\n const count = Math.round(7 + 9 * params.scale * params.intensity)\r\n const blobs: { x: number; y: number; r: number; hx: number; hy: number; speed: number; hue: number; sat: number; lit: number }[] = []\r\n for (let i = 0; i < count; i++) {\r\n blobs.push({\r\n x: rng(), y: rng(),\r\n r: (0.22 + rng() * 0.6) * params.scale,\r\n hx: rng() * 4 - 2, hy: rng() * 4 - 2,\r\n speed: 0.05 + rng() * 0.1,\r\n hue: (baseHue + (rng() < 0.5 ? 30 : 180) + rng() * 60) % 360,\r\n sat: Math.round(45 + rng() * 50 * params.intensity),\r\n lit: dark ? Math.round(18 + rng() * 35 * params.intensity) : Math.round(60 + rng() * 25 * params.intensity),\r\n })\r\n }\r\n let t = 0\r\n const alpha = (0.22 + 0.3 * params.intensity).toFixed(3)\r\n const innerAlpha = (+alpha * 0.35).toFixed(3)\r\n const draw = () => {\r\n fitLiveCanvas(c)\r\n const w = c.width, h = c.height\r\n g.fillStyle = dark ? '#0a0b0e' : '#f5f7fa'\r\n g.fillRect(0, 0, w, h)\r\n for (const b of blobs) {\r\n const phase = t * b.speed\r\n const cx = (((b.x + noise(b.hx + phase * 0.3, b.hy) * 0.25 + phase * 0.03) % 1 + 1) % 1) * w\r\n const cy = (((b.y + noise(b.hx, b.hy + phase * 0.3) * 0.25 + phase * 0.012) % 1 + 1) % 1) * h\r\n const r = b.r * Math.min(w, h) * (0.8 + 0.4 * Math.sin(phase + b.hx))\r\n const rad = g.createRadialGradient(cx, cy, 0, cx, cy, r)\r\n rad.addColorStop(0, `hsla(${b.hue},${b.sat}%,${b.lit}%,${alpha})`)\r\n rad.addColorStop(0.55, `hsla(${b.hue},${Math.round(b.sat * 0.6)}%,${b.lit}%,${innerAlpha})`)\r\n rad.addColorStop(1, 'hsla(0,0%,0%,0)')\r\n g.fillStyle = rad\r\n g.fillRect(0, 0, w, h)\r\n }\r\n t += 0.028\r\n }\r\n return { canvas: c, ...newRaf(c, draw), snapshot: () => c.toDataURL('image/jpeg', 0.92) }\r\n}\r\n\r\n// ── Shader backgrounds (animated WebGL) ───────────────────────────────────────\r\nexport function createShaderBg(params: ShaderParams, canvas?: HTMLCanvasElement): LiveBgController {\r\n const c = canvas ?? createCanvas()\r\n fitLiveCanvas(c)\r\n const gl = c.getContext('webgl', { alpha: false }) || c.getContext('experimental-webgl', { alpha: false }) as WebGLRenderingContext | null\r\n if (!gl) return createMeshGradient({ type: 'mesh', seed: params.speed * 1000, scale: params.scale, intensity: 0.6 }, c)\r\n\r\n const vs = `\r\n attribute vec2 a_position;\r\n void main() { gl_Position = vec4(a_position, 0.0, 1.0); }\r\n `\r\n const program = createProgram(gl, vs, shaderFragment(params.preset))\r\n if (!program) return createMeshGradient({ type: 'mesh', seed: params.speed * 1000, scale: params.scale, intensity: 0.6 }, c)\r\n\r\n const posLoc = gl.getAttribLocation(program, 'a_position')\r\n const buf = gl.createBuffer()\r\n gl.bindBuffer(gl.ARRAY_BUFFER, buf)\r\n gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([-1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1]), gl.STATIC_DRAW)\r\n gl.enableVertexAttribArray(posLoc)\r\n gl.vertexAttribPointer(posLoc, 2, gl.FLOAT, false, 0, 0)\r\n gl.useProgram(program)\r\n const uRes = gl.getUniformLocation(program, 'u_resolution')\r\n const uTime = gl.getUniformLocation(program, 'u_time')\r\n const uScale = gl.getUniformLocation(program, 'u_scale')\r\n const uSeed = gl.getUniformLocation(program, 'u_seed')\r\n const seed01 = (params.seed >>> 0) / 0xffffffff\r\n let t = 0\r\n const draw = () => {\r\n fitLiveCanvas(c)\r\n gl.viewport(0, 0, c.width, c.height)\r\n gl.uniform2f(uRes, c.width, c.height)\r\n gl.uniform1f(uTime, t)\r\n gl.uniform1f(uScale, params.scale)\r\n gl.uniform1f(uSeed, seed01)\r\n gl.drawArrays(gl.TRIANGLES, 0, 6)\r\n t += 0.32 * params.speed\r\n }\r\n return { canvas: c, ...newRaf(c, draw), snapshot: () => c.toDataURL('image/jpeg', 0.95) }\r\n}\r\n\r\nfunction createProgram(gl: WebGLRenderingContext, vs: string, fs: string): WebGLProgram | null {\r\n const v = gl.createShader(gl.VERTEX_SHADER)\r\n const f = gl.createShader(gl.FRAGMENT_SHADER)\r\n if (!v || !f) return null\r\n gl.shaderSource(v, vs); gl.compileShader(v)\r\n gl.shaderSource(f, fs); gl.compileShader(f)\r\n if (!gl.getShaderParameter(v, gl.COMPILE_STATUS) || !gl.getShaderParameter(f, gl.COMPILE_STATUS)) {\r\n gl.deleteShader(v); gl.deleteShader(f)\r\n return null\r\n }\r\n const p = gl.createProgram()\r\n if (!p) return null\r\n gl.attachShader(p, v); gl.attachShader(p, f); gl.linkProgram(p)\r\n if (!gl.getProgramParameter(p, gl.LINK_STATUS)) { gl.deleteProgram(p); return null }\r\n return p\r\n}\r\n\r\nfunction shaderFragment(preset: ShaderParams['preset']): string {\r\n const common = `\r\n precision mediump float;\r\n uniform vec2 u_resolution;\r\n uniform float u_time;\r\n uniform float u_scale;\r\n uniform float u_seed;\r\n\r\n vec3 mod289(vec3 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; }\r\n vec4 mod289(vec4 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; }\r\n vec4 permute(vec4 x) { return mod289(((x*34.0)+1.0)*x); }\r\n vec4 taylorInvSqrt(vec4 r) { return 1.79284291400159 - 0.85373472095314 * r; }\r\n vec3 hueRotate(vec3 rgb, float angle) {\r\n float c = cos(angle), s = sin(angle);\r\n mat3 m = mat3(\r\n 0.299 + 0.701*c + 0.168*s, 0.587 - 0.587*c + 0.330*s, 0.114 - 0.114*c - 0.497*s,\r\n 0.299 - 0.299*c - 0.328*s, 0.587 + 0.413*c + 0.035*s, 0.114 - 0.114*c + 0.292*s,\r\n 0.299 - 0.300*c + 1.250*s, 0.587 - 0.588*c - 1.050*s, 0.114 + 0.886*c - 0.203*s\r\n );\r\n return rgb * m;\r\n }\r\n float snoise(vec3 v) {\r\n const vec2 C = vec2(1.0/6.0, 1.0/3.0);\r\n const vec4 D = vec4(0.0, 0.5, 1.0, 2.0);\r\n vec3 i = floor(v + dot(v, C.yyy));\r\n vec3 x0 = v - i + dot(i, C.xxx);\r\n vec3 g = step(x0.yzx, x0.xyz);\r\n vec3 l = 1.0 - g;\r\n vec3 i1 = min(g.xyz, l.zxy);\r\n vec3 i2 = max(g.xyz, l.zxy);\r\n vec3 x1 = x0 - i1 + C.xxx;\r\n vec3 x2 = x0 - i2 + C.yyy;\r\n vec3 x3 = x0 - D.yyy;\r\n i = mod289(i);\r\n vec4 p = permute(permute(permute(\r\n i.z + vec4(0.0, i1.z, i2.z, 1.0))\r\n + i.y + vec4(0.0, i1.y, i2.y, 1.0))\r\n + i.x + vec4(0.0, i1.x, i2.x, 1.0));\r\n float n_ = 0.142857142857;\r\n vec3 ns = n_ * D.wyz - D.xzx;\r\n vec4 j = p - 49.0 * floor(p * ns.z * ns.z);\r\n vec4 x_ = floor(j * ns.z);\r\n vec4 y_ = floor(j - 7.0 * x_);\r\n vec4 x = x_ * ns.x + ns.yyyy;\r\n vec4 y = y_ * ns.x + ns.yyyy;\r\n vec4 h = 1.0 - abs(x) - abs(y);\r\n vec4 b0 = vec4(x.xy, y.xy);\r\n vec4 b1 = vec4(x.zw, y.zw);\r\n vec4 s0 = floor(b0)*2.0 + 1.0;\r\n vec4 s1 = floor(b1)*2.0 + 1.0;\r\n vec4 sh = -step(h, vec4(0.0));\r\n vec4 a0 = b0.xzyw + s0.xzyw*sh.xxyy;\r\n vec4 a1 = b1.xzyw + s1.xzyw*sh.zzww;\r\n vec3 p0 = vec3(a0.xy, h.x);\r\n vec3 p1 = vec3(a0.zw, h.y);\r\n vec3 p2 = vec3(a1.xy, h.z);\r\n vec3 p3 = vec3(a1.zw, h.w);\r\n vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2,p2), dot(p3,p3)));\r\n p0 *= norm.x; p1 *= norm.y; p2 *= norm.z; p3 *= norm.w;\r\n vec4 m = max(0.6 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0);\r\n m = m * m;\r\n return 42.0 * dot(m*m, vec4(dot(p0,x0), dot(p1,x1), dot(p2,x2), dot(p3,x3)));\r\n }\r\n float fbm(vec3 p) {\r\n float v = 0.0, a = 0.5;\r\n for (int i = 0; i < 5; i++) {\r\n v += a * snoise(p);\r\n p *= 2.0; a *= 0.5;\r\n }\r\n return v;\r\n }\r\n `\r\n if (preset === 'aurora') {\r\n return common + `\r\n void main() {\r\n vec2 uv = gl_FragCoord.xy / u_resolution;\r\n float t = u_time;\r\n float n1 = fbm(vec3(uv * 2.5 * u_scale, t));\r\n float n2 = fbm(vec3(uv * 4.0 * u_scale + 7.0, t * 1.4));\r\n float n3 = fbm(vec3(uv * 1.2 * u_scale - 3.0, t * 0.7));\r\n float bands = smoothstep(0.15, 0.85, 0.5 + 0.5 * sin((uv.y + n3 * 0.08) * 8.0 + n1 * 1.5));\r\n vec3 c1 = vec3(0.03, 0.08, 0.14);\r\n vec3 c2 = vec3(0.05, 0.28, 0.32);\r\n vec3 c3 = vec3(0.18, 0.62, 0.42);\r\n vec3 c4 = vec3(0.55, 0.22, 0.52);\r\n vec3 c5 = vec3(0.85, 0.35, 0.25);\r\n vec3 col = mix(c1, c2, bands);\r\n col = mix(col, c3, smoothstep(0.25, 0.75, n1));\r\n col = mix(col, c4, smoothstep(0.45, 0.85, n2) * 0.75);\r\n col = mix(col, c5, smoothstep(0.7, 0.95, n2 + n1 * 0.3) * 0.45);\r\n col = hueRotate(col, u_seed * 6.28318530718);\r\n gl_FragColor = vec4(col, 1.0);\r\n }\r\n `\r\n }\r\n if (preset === 'nebula') {\r\n return common + `\r\n void main() {\r\n vec2 uv = gl_FragCoord.xy / u_resolution;\r\n float t = u_time * 0.8;\r\n float n = fbm(vec3(uv * 2.2 * u_scale, t));\r\n float n2 = fbm(vec3(uv * 5.0 * u_scale - 4.0, t * 0.65));\r\n float n3 = fbm(vec3(uv * 0.9 * u_scale + 2.0, t * 0.4));\r\n vec3 c1 = vec3(0.02, 0.02, 0.08);\r\n vec3 c2 = vec3(0.12, 0.04, 0.22);\r\n vec3 c3 = vec3(0.32, 0.10, 0.35);\r\n vec3 c4 = vec3(0.10, 0.18, 0.42);\r\n vec3 c5 = vec3(0.55, 0.30, 0.55);\r\n vec3 col = mix(c1, c2, smoothstep(-0.5, 0.6, n));\r\n col = mix(col, c3, smoothstep(0.15, 0.8, n2) * 0.75);\r\n col = mix(col, c4, smoothstep(0.35, 0.85, n + n3 * 0.3) * 0.55);\r\n col = mix(col, c5, smoothstep(0.6, 0.95, n2) * 0.35);\r\n col = hueRotate(col, u_seed * 6.28318530718);\r\n gl_FragColor = vec4(col, 1.0);\r\n }\r\n `\r\n }\r\n if (preset === 'starfield') {\r\n return common + `\r\n float hash21(vec2 p) {\r\n p = fract(p * vec2(234.34, 435.345));\r\n p += dot(p, p + 34.23);\r\n return fract(p.x * p.y);\r\n }\r\n vec3 starLayer(vec2 uv, float t, float density) {\r\n vec3 col = vec3(0.0);\r\n vec2 grid = uv * density;\r\n vec2 cell = floor(grid);\r\n vec2 f = fract(grid) - 0.5;\r\n float h = hash21(cell);\r\n if (h > 0.8) {\r\n vec2 offs = (vec2(hash21(cell + 1.3), hash21(cell + 2.7)) - 0.5) * 0.7;\r\n float d = length(f - offs);\r\n float tw = 0.35 + 0.65 * sin(t * (1.0 + h * 2.5) + h * 40.0);\r\n col += vec3(0.85, 0.92, 1.0) * smoothstep(0.07, 0.0, d) * max(0.0, tw);\r\n }\r\n return col;\r\n }\r\n void main() {\r\n vec2 uv = gl_FragCoord.xy / u_resolution;\r\n vec2 p = (gl_FragCoord.xy - 0.5 * u_resolution) / u_resolution.y;\r\n float t = u_time * 0.5;\r\n vec3 col = mix(vec3(0.012, 0.014, 0.035), vec3(0.035, 0.035, 0.08), uv.y);\r\n // Faint drifting nebula veil behind the stars.\r\n float n = fbm(vec3(p * 2.2 * u_scale, t * 0.05));\r\n col += vec3(0.05, 0.045, 0.11) * smoothstep(0.05, 0.85, n);\r\n vec3 stars = vec3(0.0);\r\n stars += starLayer(p + vec2(t * 0.006, 0.0), t, 13.0 * u_scale);\r\n stars += starLayer(p * 1.8 + vec2(t * 0.013, 3.0), t * 1.25, 27.0 * u_scale);\r\n stars += starLayer(p * 3.1 + vec2(t * 0.021, 7.0), t * 0.85, 46.0 * u_scale);\r\n col += stars;\r\n col = hueRotate(col, u_seed * 6.28318530718);\r\n gl_FragColor = vec4(col, 1.0);\r\n }\r\n `\r\n }\r\n // noise\r\n return common + `\r\n void main() {\r\n vec2 uv = gl_FragCoord.xy / u_resolution;\r\n float t = u_time;\r\n float n = fbm(vec3(uv * 3.5 * u_scale, t));\r\n float n2 = fbm(vec3(uv * 9.0 * u_scale + 15.0, t * 1.6));\r\n float n3 = fbm(vec3(uv * 1.5 * u_scale - 5.0, t * 0.5));\r\n vec3 c1 = vec3(0.06, 0.06, 0.08);\r\n vec3 c2 = vec3(0.16, 0.18, 0.22);\r\n vec3 c3 = vec3(0.30, 0.32, 0.36);\r\n vec3 c4 = vec3(0.46, 0.48, 0.52);\r\n vec3 col = mix(c1, c2, 0.5 + 0.5 * n + n3 * 0.15);\r\n col = mix(col, c3, smoothstep(0.3, 0.8, n2) * 0.45);\r\n col = mix(col, c4, smoothstep(0.6, 0.95, n2) * 0.25);\r\n col = hueRotate(col, u_seed * 6.28318530718);\r\n gl_FragColor = vec4(col, 1.0);\r\n }\r\n `\r\n}\r\n\r\n// ── Geometric patterns (animated) ─────────────────────────────────────────────\r\nexport function createPatternBg(params: PatternParams, canvas?: HTMLCanvasElement): LiveBgController {\r\n if (params.preset === 'waves') return createWaves(params, canvas)\r\n if (params.preset === 'poly') return createLowPoly(params, canvas)\r\n if (params.preset === 'rain') return createRain(params, canvas)\r\n if (params.preset === 'contour') return createContour(params, canvas)\r\n if (params.preset === 'meta') return createMeta(params, canvas)\r\n return createDots(params, canvas)\r\n}\r\n\r\nfunction createRain(params: PatternParams, canvas?: HTMLCanvasElement): LiveBgController {\r\n const c = canvas ?? createCanvas()\r\n fitLiveCanvas(c)\r\n const g = c.getContext('2d', { alpha: false })!\r\n const rng = createRng(params.seed)\r\n const dark = rng() < 0.5\r\n const hue = Math.round(rng() * 360)\r\n const count = Math.round(30 + params.density * 150)\r\n const drops: { x: number; y: number; len: number; speed: number; sat: number; lit: number; alpha: number; width: number }[] = []\r\n for (let i = 0; i < count; i++) {\r\n drops.push({\r\n x: rng(),\r\n y: rng(),\r\n len: (0.035 + rng() * 0.075) * (0.7 + params.scale * 0.5),\r\n speed: (0.25 + rng() * 0.55) * (0.6 + params.scale * 0.5),\r\n sat: Math.round(30 + rng() * 40),\r\n lit: dark ? Math.round(55 + rng() * 25) : Math.round(40 + rng() * 25),\r\n alpha: 0.12 + rng() * 0.28,\r\n width: 0.8 + rng() * 1.4,\r\n })\r\n }\r\n let t = 0\r\n const draw = () => {\r\n fitLiveCanvas(c)\r\n const w = c.width, h = c.height\r\n g.fillStyle = dark ? '#07080c' : '#f4f6f9'\r\n g.fillRect(0, 0, w, h)\r\n for (const d of drops) {\r\n const yy = (((d.y + t * d.speed) % 1) + 1) % 1\r\n const x = d.x * w\r\n const y0 = yy * h\r\n const y1 = y0 - d.len * h\r\n const grad = g.createLinearGradient(x, y0, x, y1)\r\n grad.addColorStop(0, `hsla(${hue},${d.sat}%,${d.lit}%,${d.alpha.toFixed(2)})`)\r\n grad.addColorStop(1, 'hsla(0,0%,0%,0)')\r\n g.strokeStyle = grad\r\n g.lineWidth = d.width\r\n g.beginPath()\r\n g.moveTo(x, y0)\r\n g.lineTo(x, y1)\r\n g.stroke()\r\n }\r\n t += 0.016\r\n }\r\n return { canvas: c, ...newRaf(c, draw), snapshot: () => c.toDataURL('image/jpeg', 0.94) }\r\n}\r\n\r\nfunction createContour(params: PatternParams, canvas?: HTMLCanvasElement): LiveBgController {\r\n const c = canvas ?? createCanvas()\r\n fitLiveCanvas(c)\r\n const g = c.getContext('2d', { alpha: false })!\r\n const noise = createNoise(params.seed)\r\n const rng = createRng(params.seed + 1013)\r\n const dark = rng() < 0.5\r\n const hue = Math.round(rng() * 360)\r\n const layers = Math.round(16 + params.density * 46)\r\n const freq = 0.0016 / params.scale\r\n const amp = 0.055 * params.scale\r\n let t = 0\r\n const draw = () => {\r\n fitLiveCanvas(c)\r\n const w = c.width, h = c.height\r\n g.fillStyle = dark ? '#0a0b0e' : '#f6f7fa'\r\n g.fillRect(0, 0, w, h)\r\n const samples = Math.max(60, Math.floor(w / 8))\r\n for (let i = 0; i <= layers; i++) {\r\n const base = i / layers\r\n const shift = t * 0.05\r\n g.beginPath()\r\n for (let s = 0; s <= samples; s++) {\r\n const fx = s / samples\r\n const n = noise(fx * 60 * freq * 400, i * 0.22 + shift)\r\n const y = (base + (n - 0.5) * amp) * h\r\n if (s === 0) g.moveTo(0, y)\r\n else g.lineTo(fx * w, y)\r\n }\r\n const lit = dark ? 20 + (i / layers) * 22 : 62 - (i / layers) * 18\r\n g.strokeStyle = `hsla(${(hue + i * 2) % 360},30%,${lit}%,${(0.25 + 0.2 * (i / layers)).toFixed(2)})`\r\n g.lineWidth = 1\r\n g.stroke()\r\n }\r\n t += 0.032\r\n }\r\n return { canvas: c, ...newRaf(c, draw), snapshot: () => c.toDataURL('image/jpeg', 0.94) }\r\n}\r\n\r\nfunction createMeta(params: PatternParams, canvas?: HTMLCanvasElement): LiveBgController {\r\n const c = canvas ?? createCanvas()\r\n fitLiveCanvas(c)\r\n const g = c.getContext('2d', { alpha: false })!\r\n const rng = createRng(params.seed)\r\n const dark = rng() < 0.5\r\n const baseHue = Math.round(rng() * 360)\r\n const count = Math.round(5 + params.density * 11)\r\n const blobs: { x: number; y: number; r: number; ax: number; ay: number; speed: number; phase: number; hue: number }[] = []\r\n for (let i = 0; i < count; i++) {\r\n blobs.push({\r\n x: 0.15 + rng() * 0.7, y: 0.15 + rng() * 0.7,\r\n r: (0.09 + rng() * 0.14) * params.scale,\r\n ax: 0.08 + rng() * 0.22, ay: 0.08 + rng() * 0.22,\r\n speed: 0.15 + rng() * 0.3,\r\n phase: rng() * Math.PI * 2,\r\n hue: (baseHue + rng() * 70) % 360,\r\n })\r\n }\r\n let t = 0\r\n const draw = () => {\r\n fitLiveCanvas(c)\r\n const w = c.width, h = c.height\r\n g.fillStyle = dark ? '#08090d' : '#f5f6f9'\r\n g.fillRect(0, 0, w, h)\r\n g.globalCompositeOperation = dark ? 'lighter' : 'multiply'\r\n for (const b of blobs) {\r\n const cx = (b.x + Math.sin(t * b.speed + b.phase) * b.ax) * w\r\n const cy = (b.y + Math.cos(t * b.speed * 0.83 + b.phase * 1.7) * b.ay) * h\r\n const r = b.r * Math.min(w, h) * (0.9 + 0.2 * Math.sin(t * b.speed + b.phase))\r\n const rad = g.createRadialGradient(cx, cy, 0, cx, cy, r)\r\n if (dark) {\r\n rad.addColorStop(0, `hsla(${b.hue},65%,58%,0.55)`)\r\n rad.addColorStop(0.7, `hsla(${b.hue},60%,45%,0.18)`)\r\n rad.addColorStop(1, 'hsla(0,0%,0%,0)')\r\n } else {\r\n rad.addColorStop(0, `hsla(${b.hue},55%,70%,0.5)`)\r\n rad.addColorStop(0.7, `hsla(${b.hue},50%,80%,0.2)`)\r\n rad.addColorStop(1, 'hsla(0,0%,100%,0)')\r\n }\r\n g.fillStyle = rad\r\n g.beginPath()\r\n g.arc(cx, cy, r, 0, Math.PI * 2)\r\n g.fill()\r\n }\r\n g.globalCompositeOperation = 'source-over'\r\n t += 0.03\r\n }\r\n return { canvas: c, ...newRaf(c, draw), snapshot: () => c.toDataURL('image/jpeg', 0.94) }\r\n}\r\n\r\nfunction createDots(params: PatternParams, canvas?: HTMLCanvasElement): LiveBgController {\r\n const c = canvas ?? createCanvas()\r\n fitLiveCanvas(c)\r\n const g = c.getContext('2d', { alpha: false })!\r\n const rng = createRng(params.seed)\r\n const dark = rng() < 0.5\r\n const baseHue = Math.round(rng() * 360)\r\n const spacing = Math.max(26, 150 * params.scale / (0.25 + params.density))\r\n const dots: { cx: number; cy: number; r: number; hue: number; sat: number; lit: number; phase: number; speed: number }[] = []\r\n for (let y = 0; y < 8; y++) {\r\n for (let x = 0; x < 8; x++) {\r\n dots.push({\r\n cx: x / 7, cy: y / 7,\r\n r: spacing * 0.16 * params.scale * (0.6 + rng() * 0.7),\r\n hue: (baseHue + rng() * 80) % 360,\r\n sat: Math.round(35 + rng() * 55),\r\n lit: dark ? Math.round(30 + rng() * 35) : Math.round(55 + rng() * 30),\r\n phase: rng() * Math.PI * 2,\r\n speed: 0.5 + rng() * 1.2,\r\n })\r\n }\r\n }\r\n let t = 0\r\n const draw = () => {\r\n fitLiveCanvas(c)\r\n const w = c.width, h = c.height\r\n g.fillStyle = dark ? '#0a0b0d' : '#f6f7f9'\r\n g.fillRect(0, 0, w, h)\r\n for (const d of dots) {\r\n const pulse = 0.75 + 0.35 * Math.sin(t * d.speed + d.phase)\r\n const r = Math.max(1, d.r * pulse)\r\n const x = d.cx * w + (d.r * 0.3) * Math.sin(t * d.speed * 0.5 + d.phase)\r\n const y = d.cy * h + (d.r * 0.3) * Math.cos(t * d.speed * 0.7 + d.phase)\r\n g.beginPath()\r\n g.arc(x, y, r, 0, Math.PI * 2)\r\n g.fillStyle = `hsla(${d.hue},${d.sat}%,${d.lit}%,${(0.18 + 0.25 * pulse).toFixed(2)})`\r\n g.fill()\r\n }\r\n t += 0.032\r\n }\r\n return { canvas: c, ...newRaf(c, draw), snapshot: () => c.toDataURL('image/jpeg', 0.94) }\r\n}\r\n\r\nfunction createWaves(params: PatternParams, canvas?: HTMLCanvasElement): LiveBgController {\r\n const c = canvas ?? createCanvas()\r\n fitLiveCanvas(c)\r\n const g = c.getContext('2d', { alpha: false })!\r\n const rng = createRng(params.seed)\r\n const dark = rng() < 0.5\r\n const hue = Math.round(rng() * 360)\r\n const layers = Math.round(5 + params.density * 8)\r\n const waves: { yBase: number; amp: number; freq: number; phase: number; speed: number; hue: number; sat: number; lit: number; alpha: number }[] = []\r\n for (let i = 0; i < layers; i++) {\r\n waves.push({\r\n yBase: 0.25 + (i / layers) * 0.55,\r\n amp: (25 + rng() * 45) * params.scale,\r\n freq: (0.006 + rng() * 0.01) / params.scale,\r\n phase: rng() * Math.PI * 2,\r\n speed: (0.3 + rng() * 0.7) * (rng() < 0.5 ? 1 : -1),\r\n hue: (hue + i * 12) % 360,\r\n sat: Math.round(40 + rng() * 45),\r\n lit: dark ? Math.round(14 + (i / layers) * 32) : Math.round(72 - (i / layers) * 28),\r\n alpha: 0.22 + rng() * 0.32,\r\n })\r\n }\r\n let t = 0\r\n const draw = () => {\r\n fitLiveCanvas(c)\r\n const w = c.width, h = c.height\r\n g.fillStyle = dark ? '#07080a' : '#f8f9fb'\r\n g.fillRect(0, 0, w, h)\r\n for (const wave of waves) {\r\n g.beginPath()\r\n g.moveTo(0, h)\r\n for (let x = 0; x <= w; x += Math.max(6, Math.floor(w / 180))) {\r\n const y = h * wave.yBase\r\n + Math.sin(x * wave.freq + wave.phase + t * wave.speed) * wave.amp\r\n + Math.sin(x * wave.freq * 2.1 + wave.phase * 1.3 - t * wave.speed * 1.5) * wave.amp * 0.5\r\n g.lineTo(x, y)\r\n }\r\n g.lineTo(w, h)\r\n g.closePath()\r\n g.fillStyle = `hsla(${wave.hue},${wave.sat}%,${wave.lit}%,${wave.alpha.toFixed(2)})`\r\n g.fill()\r\n }\r\n t += 0.032\r\n }\r\n return { canvas: c, ...newRaf(c, draw), snapshot: () => c.toDataURL('image/jpeg', 0.94) }\r\n}\r\n\r\nfunction createLowPoly(params: PatternParams, canvas?: HTMLCanvasElement): LiveBgController {\r\n const c = canvas ?? createCanvas()\r\n fitLiveCanvas(c)\r\n const g = c.getContext('2d', { alpha: false })!\r\n const rng = createRng(params.seed)\r\n const dark = rng() < 0.5\r\n const hue = Math.round(rng() * 360)\r\n const cols = Math.round(10 + params.density * 20)\r\n const rows = Math.max(6, Math.round(cols * 0.65))\r\n const points: { x: number; y: number; dx: number; dy: number; speed: number }[][] = []\r\n for (let y = 0; y <= rows; y++) {\r\n const row: { x: number; y: number; dx: number; dy: number; speed: number }[] = []\r\n for (let x = 0; x <= cols; x++) {\r\n row.push({\r\n x: x / cols, y: y / rows,\r\n dx: (rng() - 0.5) * 0.02, dy: (rng() - 0.5) * 0.02,\r\n speed: 0.3 + rng() * 0.5,\r\n })\r\n }\r\n points.push(row)\r\n }\r\n const cells: { y: number; x: number; hue: number; sat: number; lit: number; phase: number }[] = []\r\n for (let y = 0; y < rows; y++) {\r\n for (let x = 0; x < cols; x++) {\r\n cells.push({ y, x, hue: (hue + rng() * 60) % 360, sat: Math.round(35 + rng() * 40), lit: dark ? Math.round(12 + rng() * 35) : Math.round(65 - rng() * 10), phase: rng() * Math.PI * 2 })\r\n }\r\n }\r\n let t = 0\r\n const px: { x: number; y: number }[][] = points.map(row => row.map(() => ({ x: 0, y: 0 })))\r\n const draw = () => {\r\n fitLiveCanvas(c)\r\n const w = c.width, h = c.height\r\n g.fillStyle = dark ? '#08090c' : '#f5f6f8'\r\n g.fillRect(0, 0, w, h)\r\n for (let y = 0; y <= rows; y++) {\r\n const row = points[y]!\r\n const out = px[y]!\r\n for (let x = 0; x <= cols; x++) {\r\n const p = row[x]!\r\n out[x]!.x = (p.x + Math.sin(t * p.speed + p.dx * 100) * p.dx) * w\r\n out[x]!.y = (p.y + Math.cos(t * p.speed + p.dy * 100) * p.dy) * h\r\n }\r\n }\r\n for (const cell of cells) {\r\n const p1 = px[cell.y]![cell.x]!, p2 = px[cell.y]![cell.x + 1]!, p3 = px[cell.y + 1]![cell.x]!, p4 = px[cell.y + 1]![cell.x + 1]!\r\n const cx = (p1.x + p2.x + p3.x) / 3 / w\r\n const lit = Math.max(0, Math.min(100, cell.lit + Math.sin(t * 0.6 + cell.phase) * 6))\r\n g.beginPath(); g.moveTo(p1.x, p1.y); g.lineTo(p2.x, p2.y); g.lineTo(p3.x, p3.y); g.closePath()\r\n g.fillStyle = `hsla(${cell.hue + cx * 40},${cell.sat}%,${lit}%,0.92)`\r\n g.fill()\r\n g.beginPath(); g.moveTo(p2.x, p2.y); g.lineTo(p4.x, p4.y); g.lineTo(p3.x, p3.y); g.closePath()\r\n g.fillStyle = `hsla(${(cell.hue + cx * 40 + 12) % 360},${cell.sat}%,${Math.max(0, lit - 4)}%,0.92)`\r\n g.fill()\r\n }\r\n t += 0.03\r\n }\r\n return { canvas: c, ...newRaf(c, draw), snapshot: () => c.toDataURL('image/jpeg', 0.94) }\r\n}\r\n\r\n// ── Dispatcher ────────────────────────────────────────────────────────────────\r\nexport function createDynamicBackground(params: GeneratedBgParams, canvas?: HTMLCanvasElement): LiveBgController {\r\n if (params.type === 'mesh') return createMeshGradient(params, canvas)\r\n if (params.type === 'shader') return createShaderBg(params, canvas)\r\n return createPatternBg(params, canvas)\r\n}\r\n\r\nfunction randomSeed(): number {\r\n return Math.floor(Math.random() * 0x7fffffff)\r\n}\r\n\r\n/** Build default params for a newly selected background type. */\r\nexport function defaultParamsFor(type: Exclude<GeneratedBgParams['type'], 'image'>): GeneratedBgParams {\r\n if (type === 'mesh') return { type: 'mesh', seed: randomSeed(), scale: 1.1, intensity: 0.65 }\r\n if (type === 'shader') return { type: 'shader', preset: 'aurora', speed: 0.35, scale: 1, seed: randomSeed() }\r\n return { type: 'pattern', preset: 'dots', density: 0.5, scale: 1, seed: randomSeed() }\r\n}\r\n","import { MENU_FILL_TOKEN, PANEL_SURFACES, BETTER_SIDEBAR_PANEL, COMPOSER_TAKEOVER_CARD, COMPOSER_TAKEOVER_EDITOR, elementFrostDecl } from './host-compat/versions/shared'\r\nimport { hostAdapter } from './host-compat/capabilities'\r\nimport { HEADER_POPOVER_ATTR } from './header-tag'\r\nimport { rWp, rWpImage, rWpVideo, rBgState, rVideoBgState, rBl, rWop, rOps, rSop, rStrokes, rColor, rHasColor, rBlurs, rBgMode, rChatTextOpacity, rTrajectoryOpacity, rPanelOpacity, rProducedOpacity, rHeaderOpacity, rScheme, rColorScheme, rSchemeOverride, cfg, setWpUrl, rBgDark, setBgDark, disposeVideoObjectUrl } from './state'\r\nimport type { BackgroundType, GeneratedBgParams, PartOpacities, PartBlurs, StrokeConfig } from './types'\r\nimport { genTokens, toRgba, extractWallpaperColor, analyzeFrameDark } from './utils/color'\r\nimport { loadImage } from './utils/image'\r\nimport { createDynamicBackground, defaultParamsFor } from './utils/bg-generators'\r\n\r\nlet wpEl: HTMLDivElement | null = null\r\nlet videoEl: HTMLVideoElement | null = null\r\nlet appliedTokenNames: string[] = []\r\nlet wpController: { canvas: HTMLCanvasElement; stop: () => void; pause?: () => void; resume?: () => void; snapshot: () => string } | null = null\r\nlet snapshotListener: (() => void) | null = null\r\nlet tokenStyleEl: HTMLStyleElement | null = null\r\n\r\n/** Pause the live generated background's animation loop (session-only). */\r\nexport function pauseGeneratedBg(): void { wpController?.pause?.() }\r\n\r\n/** Resume the live generated background's animation loop. */\r\nexport function resumeGeneratedBg(): void { wpController?.resume?.() }\r\n\r\nfunction clearDynamicBg(): void {\r\n wpController?.stop()\r\n wpController?.canvas.remove()\r\n wpController = null\r\n}\r\n\r\n/** Register a callback fired once a generated snapshot is ready (so the caller\r\n * can re-sync the settings preview / store). Returns an unsubscribe: HMR\r\n * re-runs apply and would otherwise leave the previous apply's closure as the\r\n * live listener (a stale this-session callback invoked by a lingering\r\n * controller). */\r\nexport function onGeneratedSnapshot(cb: () => void): () => void {\r\n snapshotListener = cb\r\n return () => { if (snapshotListener === cb) snapshotListener = null }\r\n}\r\n\r\nfunction ensureTokenStyle(): HTMLStyleElement {\r\n if (tokenStyleEl?.isConnected) return tokenStyleEl\r\n tokenStyleEl = document.createElement('style')\r\n tokenStyleEl.dataset.plugin = 'dsh-any-background-tokens'\r\n document.head.appendChild(tokenStyleEl)\r\n return tokenStyleEl\r\n}\r\n\r\nfunction clearCustomTokens(): void {\r\n if (tokenStyleEl) tokenStyleEl.textContent = ''\r\n for (const name of appliedTokenNames) document.body.style.removeProperty(name)\r\n appliedTokenNames = []\r\n}\r\n\r\n/** Drop every applied custom token and forget the token fingerprint, so a\r\n * later color-less profile (system theme) leaves no stale rule behind. */\r\nexport function clearThemeTokens(): void {\r\n clearCustomTokens()\r\n baseTokenKey = ''\r\n lastBgKey = ''\r\n document.body.removeAttribute('data-ds-dark-theme')\r\n document.body.style.removeProperty('color-scheme')\r\n}\r\n\r\n/** Label tokens flipped by the background brightness verdict. The faint tiers\r\n * (caption/dimmed) are deliberately NOT flipped: they back placeholder/hint\r\n * text, which must stay visibly weaker than real input even when the wallpaper\r\n * brightness flips the main label direction. Exported so the skin registration\r\n * (index) can flip fonts through the host theme service too. */\r\nexport const LABEL_TOKENS = [\r\n '--dsw-alias-label-primary',\r\n '--dsw-alias-label-secondary',\r\n '--dsw-alias-label-tertiary',\r\n]\r\n\r\n// Solid surface tokens grouped by which interface-opacity slider owns them.\r\n// Every member is re-emitted with per-part alpha so surfaces over the wallpaper\r\n// (composer input, elevated buttons, menu panels) can go translucent — not just\r\n// the layered bg/sidebar tokens. --dsw-specific-menu (dropdowns, slash-trigger\r\n// menu, model selector, popovers around the dialog) is owned by the card\r\n// slider; the Cordis panel shares that token but is re-scoped to the input\r\n// slider via inputBlurRule.\r\n//\r\n// `--dsw-alias-bg-base` IS the main-background surface: the AppFrame ground and\r\n// the conversation root that fills the center column both paint from it, which\r\n// is exactly what lets the wallpaper show through the main area. It must stay\r\n// remapped — un-remapping it makes those surfaces opaque and hides the wallpaper\r\n// entirely behind a solid theme color.\r\nconst OPACITY_TOKEN_GROUPS: Array<{ part: keyof PartOpacities; names: string[] }> = [\r\n { part: 'bg', names: ['--dsw-alias-bg-base'] },\r\n { part: 'sidebar', names: ['--dsw-specific-sidebar-fill'] },\r\n { part: 'card', names: ['--dsw-alias-bg-layer-1', '--dsw-alias-bg-layer-2', '--dsw-alias-bg-layer-3', '--dsw-specific-menu'] },\r\n { part: 'input', names: ['--dsw-specific-input-major'] },\r\n]\r\n\r\n// Plugin-owned variables the opacity-bearing tokens read from. They live as\r\n// inline custom props on <html>, so a slider drag rewrites only those few values\r\n// instead of re-parsing/re-matching the whole body token rule on every tick —\r\n// the difference is critical when a large wallpaper sits under the interface.\r\nconst OPACITY_VARS: Record<string, string> = {\r\n '--dsw-alias-bg-base': '--dsh-any-op-bg',\r\n '--dsw-specific-sidebar-fill': '--dsh-any-op-sidebar',\r\n '--dsw-alias-bg-layer-1': '--dsh-any-op-card-1',\r\n '--dsw-alias-bg-layer-2': '--dsh-any-op-card-2',\r\n '--dsw-alias-bg-layer-3': '--dsh-any-op-card-3',\r\n '--dsw-specific-input-major': '--dsh-any-op-input',\r\n '--dsw-specific-menu': '--dsh-any-op-menu',\r\n}\r\n\r\n// Fingerprint of the non-alpha token base (color pick + brightness verdict).\r\n// The static body rule is only rebuilt when it changes; a drag never touches it.\r\nlet baseTokenKey = ''\r\n\r\n// Coalesce slider-driven token updates to one rAF: a single drag fires several\r\n// input events per frame, and every full re-apply repaints expensive regions\r\n// over a large wallpaper. Batching keeps at most one update per frame. The\r\n// base-fingerprint gate above already makes a muted drag cheap; this prevents\r\n// repeated identical reapplies from stacking within the same frame.\r\nlet pendingOps: PartOpacities | null = null\r\nlet tokensRaf: number | null = null\r\n\r\nexport function applyCustomTokens(ops: PartOpacities): void {\r\n pendingOps = ops\r\n if (tokensRaf !== null) return\r\n tokensRaf = requestAnimationFrame(() => {\r\n tokensRaf = null\r\n if (pendingOps === null) return\r\n const o = pendingOps\r\n pendingOps = null\r\n applyCustomTokensNow(o)\r\n })\r\n}\r\n\r\n// Only the main-bg slider retints the center column; keys on\r\n// baseTokenKey + ops.bg so a sidebar/card/input drag never rewrites it.\r\nlet lastBgKey = ''\r\n\r\n/** Palette source for the token rule: the picked color; a forced scheme\r\n * without a picked color builds a neutral near-gray palette in that\r\n * direction; auto without a color keeps the host's own palette (null — only\r\n * the label direction gets asserted). The palette direction follows the\r\n * color's own lightness (rColorScheme), not the wallpaper verdict, so the\r\n * surfaces keep contrasting with the fonts. */\r\nfunction paletteTokens(): Record<string, string> | null {\r\n const scheme = rColorScheme()\r\n if (rHasColor()) {\r\n const [h, s, l] = rColor()\r\n return genTokens(h, s, l, scheme).tokens\r\n }\r\n if (rSchemeOverride() !== 'auto') {\r\n return genTokens(220, 0.04, scheme === 'dark' ? 0.14 : 0.92, scheme).tokens\r\n }\r\n return null\r\n}\r\n\r\n/** Surface colors the opacity sliders fade when the plugin has NO palette of\r\n * its own (no picked color, no forced scheme), read live from the host's\r\n * resolved tokens on `:root` — the same trick applyPanelOverrides uses for the\r\n * workbench panel. Without this source the per-part alpha is never emitted at\r\n * all and every opacity slider looks inert until the user drags it once.\r\n * The sliders only ever supply the alpha: the host still decides the colors,\r\n * so a custom host skin survives. Returns null when the host exposes none. */\r\nfunction readHostOpacityTokens(): Record<string, string> | null {\r\n if (typeof getComputedStyle === 'undefined') return null\r\n const cs = getComputedStyle(document.documentElement)\r\n const out: Record<string, string> = {}\r\n let found = false\r\n for (const g of OPACITY_TOKEN_GROUPS) {\r\n for (const name of g.names) {\r\n const v = cs.getPropertyValue(name).trim()\r\n if (v === '') continue\r\n out[name] = v\r\n found = true\r\n }\r\n }\r\n return found ? out : null\r\n}\r\n\r\nfunction applyCustomTokensNow(ops: PartOpacities): void {\r\n const hasColor = rHasColor()\r\n const override = rSchemeOverride()\r\n const [h, s, l] = rColor()\r\n const scheme = rScheme()\r\n const verdict = rBgDark()\r\n const palette = paletteTokens()\r\n // Surface source for the opacity re-emit: the plugin's own palette when it\r\n // has one, otherwise the host's resolved tokens — see readHostOpacityTokens.\r\n // This is what keeps all four interface-opacity sliders live in the default\r\n // state (fresh install: no picked color, no verdict, auto scheme).\r\n const surfaces = palette ?? readHostOpacityTokens()\r\n // Clone: the verdict below mutates, and genTokens' result is cached/shared.\r\n const tokens: Record<string, string> = { ...surfaces }\r\n // Font direction while the scheme is automatic: a picked color owns it —\r\n // its palette direction (rColorScheme) keeps the labels contrasted with the\r\n // surfaces they sit on, so a very dark pick flips to white fonts even over\r\n // a light wallpaper (and vice versa). Without a pick the wallpaper\r\n // brightness verdict decides: the text then sits directly on the wallpaper.\r\n if (override === 'auto') {\r\n const fontDark = hasColor ? rColorScheme() === 'dark' : verdict\r\n if (fontDark !== null && fontDark !== undefined) {\r\n const font = fontDark ? '#fff' : '#000'\r\n for (const name of LABEL_TOKENS) tokens[name] = font\r\n }\r\n }\r\n try {\r\n const forceDark = scheme === 'dark'\r\n const key = `${h}|${s}|${l}|${verdict}|${scheme}|${hasColor}|${hostAdapter().menus.fillTokens.join(',')}`\r\n if (key !== baseTokenKey) {\r\n baseTokenKey = key\r\n // Drive the base-palette switch with a plugin-specific value so the\r\n // gradient rule never matches a host dark-mode flag; color-scheme makes\r\n // native controls (select popups) follow the forced palette. Both ride the\r\n // stylesheet (not inline styles) so the host presenter clearing body\r\n // inline styles on boot can't drop them, and the !important rule survives\r\n // that clearing too.\r\n if (forceDark) document.body.setAttribute('data-ds-dark-theme', 'dsh-any-background')\r\n else document.body.removeAttribute('data-ds-dark-theme')\r\n const decls: string[] = [`color-scheme:${forceDark ? 'dark' : 'light'}`]\r\n for (const [name, value] of Object.entries(tokens)) {\r\n const opVar = OPACITY_VARS[name]\r\n decls.push(`${name}:${opVar !== undefined ? `var(${opVar})` : value}!important`)\r\n }\r\n // A release that paints menus from a second token needs that name re-scoped\r\n // too, or the menu would inherit the CARD alpha from `body` under one name and\r\n // the host's own opaque value under the other — which is precisely how the\r\n // opacity sliders went inert on 0.1.7-rc.2. Same variable, so one slider still\r\n // writes one value. Guarded on the sampled color existing, because a `var()`\r\n // naming an unset property is the guaranteed-invalid-value trap documented on\r\n // `applyHeaderPopovers`.\r\n if (tokens[MENU_FILL_TOKEN] !== undefined) {\r\n const menuVar = OPACITY_VARS[MENU_FILL_TOKEN]\r\n for (const name of hostAdapter().menus.fillTokens) {\r\n if (name === MENU_FILL_TOKEN || tokens[name] !== undefined) continue\r\n decls.push(`${name}:var(${menuVar})!important`)\r\n }\r\n }\r\n ensureTokenStyle().textContent = `body{${decls.join(';')}}`\r\n // Drop inline tokens left by earlier builds so the stylesheet is the single source of truth.\r\n for (const name of appliedTokenNames) document.body.style.removeProperty(name)\r\n appliedTokenNames = Object.keys(tokens)\r\n }\r\n // Without a palette there are no surface alphas to re-emit — the host\r\n // palette stays untouched and only the label direction was asserted. Now\r\n // that the host's own resolved tokens can back the alpha, this only bails\r\n // when even those are unavailable.\r\n if (surfaces === null) {\r\n // Preserve the previous \"nothing derived\" cleanup: a color-less auto\r\n // state with no verdict leaves no stale rule behind. A forced scheme or\r\n // a wallpaper verdict still has something to assert above.\r\n if (!hasColor && override === 'auto' && verdict === null) clearThemeTokens()\r\n return\r\n }\r\n // Cheap per-drag update: only the surface alpha vars move on <html>.\r\n const root = document.documentElement\r\n for (const g of OPACITY_TOKEN_GROUPS) {\r\n for (const name of g.names) {\r\n if (surfaces[name] === undefined) continue\r\n root.style.setProperty(OPACITY_VARS[name], toRgba(surfaces[name]!, ops[g.part]))\r\n }\r\n }\r\n // The Cordis panel keeps its own input-slider alpha (see inputBlurRule).\r\n const menu = surfaces['--dsw-specific-menu']\r\n if (menu !== undefined) root.style.setProperty('--dsh-any-op-menu-cordis', toRgba(menu, ops.input))\r\n const bgKey = `${baseTokenKey}|${ops.bg}`\r\n if (bgKey !== lastBgKey) { lastBgKey = bgKey; applyPartOpacities(ops) }\r\n // The exempt surfaces (exemptDefaultRule) point at the host's OWN token\r\n // values, sampled from :root here — so re-capture them whenever the palette\r\n // underneath changes. This is the one function every color/verdict/scheme\r\n // path funnels through.\r\n applyExemptDefaults()\r\n } catch {\r\n // ignore\r\n }\r\n}\r\n\r\n// ── Settings panel opacity ─────────────────────────────────────────────────────\r\n// Scoped by the settings dialog's own identity, not just its ARIA shape: every\r\n// aria-modal dialog that labels itself would otherwise be claimed here, and a\r\n// third-party confirm dialog does exactly that (an antd `Modal` carries\r\n// `role=\"dialog\"`, `aria-modal=\"true\"` AND `aria-labelledby` pointing at its\r\n// title). Claimed by mistake, it inherits the settings surface + blur + layer\r\n// re-scope + settings text stroke — which reads as a mis-adapted dialog with a\r\n// shifted button label rather than as the plugin's own look.\r\n// The discriminator is the hashed `_panel` class: SettingsRoot.tsx renders\r\n// `<div className={css.panel} role=\"dialog\" aria-modal=\"true\"\r\n// aria-labelledby={titleId}>` identically on 0.1.5-rc.2 / 0.1.6-alpha.2 /\r\n// 0.1.7-alpha.2 / 0.1.7-rc.1, while antd's classes are all `ant-*` (hyphens, so\r\n// `_panel` can never match one).\r\n// The surface (--dsw-alias-bg-layer-2) is re-emitted with an alpha through a\r\n// plugin-owned variable so the panel keeps its color while fading.\r\n\r\nexport const SETTINGS_PANEL_SEL = '[role=\"dialog\"][aria-modal=\"true\"][aria-labelledby][class*=\"_panel\"]'\r\nexport const SETTINGS_STYLE_RULE =\r\n `${SETTINGS_PANEL_SEL}{` +\r\n `background:var(--dsh-any-bg-settings-surface,var(--dsw-alias-bg-layer-2));` +\r\n `backdrop-filter:var(--dsh-any-blur-settings,none);` +\r\n // Re-scope the dialog's layer tokens to plugin-owned variables so every\r\n // surface inside the dialog follows the settings opacity slider only.\r\n `--dsw-alias-bg-layer-1:var(--dsh-any-bg-settings-layer-1);` +\r\n `--dsw-alias-bg-layer-2:var(--dsh-any-bg-settings-layer-2);` +\r\n `--dsw-alias-bg-layer-3:var(--dsh-any-bg-settings-layer-3)}` +\r\n // Option-panel blur inside the dialog, owned by the card blur slider.\r\n `${SETTINGS_PANEL_SEL} .dab-card{backdrop-filter:var(--dsh-any-blur-card-panels,none);-webkit-backdrop-filter:var(--dsh-any-blur-card-panels,none)}`\r\n\r\n// ── Popover / popover-style surface blur (the \"card\" slider's true target) ────\r\n// The \"card\" opacity slider does not bind to the settings dialog's .dab-card —\r\n// the comments at OPACITY_TOKEN_GROUPS note that --dsw-specific-menu (the\r\n// dropdown / popover / menu surface token) is owned by the card slider, and\r\n// the body-level re-scope in `applyCustomTokensNow` retints every consumer\r\n// of that token globally. The host uses --dsw-specific-menu for the \"popovers\r\n// around the dialog\" — the model selector (ModelSelect), the per-session\r\n// permission preset row (PermissionRow → Menu portal), the composer\r\n// permission seat (PermissionSelect → in-place Menu, `side=\"top\"`), the\r\n// stat dialog (TurnUsagePanel / StatsPills → useStatDialog), the schedule\r\n// catalog, the subagent lineage tree, the /model command panel, the\r\n// @-trigger suggestion list, the job list, etc.\r\n//\r\n// The card-blur slider has to land on the same surfaces for the visible\r\n// effect to follow the slider.\r\n//\r\n// The host uses three ARIA roles for these surfaces, and one stable\r\n// data-attribute to disqualify a non-target:\r\n//\r\n// [role=\"menu\"] · every Menu primitive surface (.list, .submenu),\r\n// ModelSelect's `.menu`. These are the picker-style\r\n// popovers, both portal-mode (rendered to body via\r\n// createPortal) and in-place (rendered where the React\r\n// subtree is — PermissionSelect keeps its `side=\"top\"`\r\n// list inside the composer card).\r\n// [role=\"listbox\"]· the /model command panel (PopupSelectView `.viewport`)\r\n// and the @-trigger suggestion list (MenuView `.viewport`)\r\n// — both the inner scroll box, not the card. From\r\n// 0.1.7-rc.2 the schedule ClockPicker adds one per column\r\n// (`ui-schedule/ClockPicker.tsx`), inside its own popover.\r\n// [role=\"tree\"] · the subagent lineage tree (portaled to body) and\r\n// the sidebar's workspace browser (ui-workspace). The\r\n// `body >` qualifier restricts this to the portaled\r\n// variant and keeps the sidebar tree out.\r\n// [role=\"dialog\"]:not([aria-modal=\"true\"])\r\n// · stat-dialog (TurnUsagePanel / StatsPills). The\r\n// settings modal is `role=\"dialog\"` with\r\n// `aria-modal=\"true\"` and is owned by\r\n// SETTINGS_STYLE_RULE; the `:not()` excludes it.\r\n//\r\n// The one element the rule must NOT touch is the dockkit per-tab\r\n// right-click menu (ui-dockkit TabMenu.tsx). It uses `role=\"menu\"` and\r\n// is portaled to body, and its background paints from\r\n// `--dsw-alias-bg-layer-3` (a layer token, not the menu token) — it is a\r\n// tab control, not a \"popover around the dialog\", and it carries a stable\r\n// `data-dockkit-tab-menu` attribute. `:not([data-dockkit-tab-menu])`\r\n// trims it out of the menu rule.\r\n//\r\n// Stacking-context caveat: the in-place menus (PermissionSelect's\r\n// `side=\"top\"` list, MenuView's listbox, PopupSelectView's listbox) live\r\n// inside .composerSeat, which is `position: sticky` and therefore a\r\n// stacking-context root. Their backdrop-filter cannot see the wallpaper\r\n// (z-index: -1 in body) because they are trapped in that context. The\r\n// effect they get is \"frost the composer card chrome\", which the card\r\n// slider drives just as visibly as a wallpaper-facing blur because the\r\n// card's own surface sits in the same context.\r\n//\r\n// The portaled menus (ModelSelect, Menu portal mode, stat-dialog,\r\n// SubagentHeaderLineage) are in body's stacking context and see the\r\n// wallpaper directly through the (transparent) AppFrame.\r\n//\r\n// THE MENU ARM IS NOT HOST-AGNOSTIC and asks the release adapter for its\r\n// declaration (`MenuSurfaceFacts`): up to 0.1.7-rc.1 the `[role=\"menu\"]` element\r\n// painted its own fill and frost (`Menu.module.css`, `ModelSelect.module.css` each\r\n// declared `background:var(--dsw-specific-menu)` plus\r\n// `backdrop-filter:var(--dsw-menu-backdrop-filter)` on that element), so filtering\r\n// it is the whole job. From 0.1.7-rc.2 that element carries no paint — a\r\n// `position:absolute;inset:0;z-index:-1` `.material` child of `MenuSurface` does,\r\n// and the host states why the root stays unfiltered (\"Filtering only the background\r\n// keeps nested menus and fixed overlays free of an ancestor backdrop root or a new\r\n// fixed-position containing block\"). So the plugin hands the value to the host's\r\n// blur token there instead of filtering an ancestor the host deliberately left clear.\r\n//\r\n// THE OTHER ARMS KEEP THE ELEMENT-LEVEL FROST, because the token cannot reach them:\r\n// custom properties travel downward, and on the layered releases the filtered layer\r\n// sits above or beside the matched element, never inside it — `[role=\"listbox\"]` is\r\n// the MenuSurface's *child* viewport (PopupSelectView.tsx:153, MenuView.tsx:132; the\r\n// surface root carries no role), and `[role=\"tree\"]` sits inside `.menu`, whose frost\r\n// lives on `.menu::before`. Setting the token on either is inert, so the element\r\n// filter is the only declaration that lands. Note these cards were never owned by the\r\n// card slider on either shape: the host frosts the card and our filter adds a frost\r\n// inside it, which is how the slider behaved at 0.1.7-rc.1 too.\r\nconst CARD_BLUR_VAR = '--dsh-any-blur-card-panels'\r\nconst POPOVER_MENU_SEL = `[role=\"menu\"]:not([data-dockkit-tab-menu])`\r\nconst POPOVER_OTHER_SEL =\r\n `[role=\"listbox\"],` +\r\n `body > [role=\"tree\"],` +\r\n `body > [role=\"dialog\"]:not([aria-modal=\"true\"])`\r\n\r\n/** The frost declaration this release's menus want, driven by the named plugin var.\r\n * Every menu-shaped surface group asks through here, so the card group, the header\r\n * group and the exemptions can never disagree about which layer to paint. */\r\nfunction menuFrost(blurVar: string): string {\r\n return hostAdapter().menus.frostDecl(`var(${blurVar},none)`)\r\n}\r\n\r\n/** Declare EVERY token this release's menus can paint their fill from with the same\r\n * value. One slider, one value, every layer reached — and a token the host does not\r\n * read is inert, so this is safe to emit on a line that only needs one.\r\n *\r\n * Used for values that are guaranteed to resolve. Where the value is a `var()` the\r\n * caller must first confirm the variable it names is actually set: an undefined\r\n * custom property inside `background:var(…)` computes to the guaranteed-invalid\r\n * value and the surface goes fully transparent (see the notes on\r\n * `applyHeaderPopovers` and `applyExemptDefaults`). */\r\nfunction menuFillDecls(value: string): string {\r\n return hostAdapter().menus.fillTokens.map(name => `${name}:${value}`).join(';')\r\n}\r\n\r\nexport function popoverBlurRule(): string {\r\n return `${POPOVER_MENU_SEL}{${menuFrost(CARD_BLUR_VAR)}}` +\r\n `${POPOVER_OTHER_SEL}{${elementFrostDecl(`var(${CARD_BLUR_VAR},none)`)}}`\r\n}\r\n\r\n// Input/control surface blur. The composer card and the Cordis panel expose\r\n// stable host data attributes ([data-composer-card], [data-cordis-panel]), so\r\n// the backdrop is attached via a stylesheet rule rather than element discovery.\r\n// The Cordis panel shares the --dsw-specific-menu token with the dialog's\r\n// option boxes, but it stays owned by the input slider — the re-scope below\r\n// keeps it there now that the menu token itself follows the card slider. Note\r\n// the input slider must NOT drive the button-elevated-fill /\r\n// button-floating-hover tokens: the settings panel's own controls (slider\r\n// thumbs, .dab-btn, segmented thumb) are painted from those same tokens, so\r\n// tinting them would bleach the panel's own UI.\r\n// Set on <html> while the input blur is non-zero, to gate `inputBlurRule`'s\r\n// composer-card rules below (see the paint-order note there).\r\nconst INPUT_FROST_CLASS = 'dab-input-frost'\r\n\r\nexport function inputBlurRule(): string {\r\n // The composer capsule must NOT carry backdrop-filter itself: it is an\r\n // ancestor of the in-place popovers (permission / command / model lists),\r\n // and a backdrop-filter on it would make it a backdrop root, trapping those\r\n // lists' own backdrop-filter to the capsule — which chained their visible\r\n // frost to the input slider. The frost instead rides an isolated ::before\r\n // underlay (position:absolute, z-index:-1), so it sits behind the capsule\r\n // content AND the popovers, leaving the popovers free to sample the\r\n // wallpaper and follow the card slider only. (Same rule the part-blurs\r\n // follow: backdrop-filter never goes directly on a host part.)\r\n //\r\n // The price of that underlay is `position:relative` + `isolation:isolate`, and\r\n // both are PAINT ORDER: a positioned element — or any element that establishes a\r\n // stacking context, which `isolation` does — is painted in the positioned layer,\r\n // above other plugins' in-flow or earlier-in-tree notices that overlap the same\r\n // spot. That is the \"输入框的 z 层级太高,挡住了通知\" report, and it cannot be\r\n // fixed away while a frost is requested: a frost needs an isolated containing\r\n // block, and no CSS construct provides one that paints *below* in-flow content.\r\n // What can be fixed is paying the cost for nothing, so both declarations are\r\n // gated on the blur being non-zero — at 0 the capsule keeps the host's own\r\n // layering and the plugin competes for nothing.\r\n return `.${INPUT_FROST_CLASS} [data-composer-card]{position:relative;isolation:isolate}` +\r\n `.${INPUT_FROST_CLASS} [data-composer-card]::before{` +\r\n 'content:\"\";position:absolute;inset:0;z-index:-1;pointer-events:none;border-radius:inherit;' +\r\n '-webkit-backdrop-filter:var(--dsh-any-input-blur,none);' +\r\n 'backdrop-filter:var(--dsh-any-input-blur,none)}' +\r\n // The takeover cards that sit in the composer seat (approval / plan review /\r\n // question) are the capsule's SIBLINGS, so the rule above never reaches them.\r\n // They fill from the same `--dsw-specific-input-major`, which this plugin\r\n // re-emits with the input alpha — so they faded while staying bare, and the\r\n // blur slider read as broken on exactly the surface the user is meant to read.\r\n // Same underlay recipe as the capsule: never a backdrop root of its own.\r\n `.${INPUT_FROST_CLASS} ${COMPOSER_TAKEOVER_CARD}{position:relative;isolation:isolate}` +\r\n `.${INPUT_FROST_CLASS} ${COMPOSER_TAKEOVER_CARD}::before{` +\r\n 'content:\"\";position:absolute;inset:0;z-index:-1;pointer-events:none;border-radius:inherit;' +\r\n '-webkit-backdrop-filter:var(--dsh-any-input-blur,none);' +\r\n 'backdrop-filter:var(--dsh-any-input-blur,none)}' +\r\n '[data-cordis-panel]{' +\r\n '-webkit-backdrop-filter:var(--dsh-any-input-blur,none);' +\r\n 'backdrop-filter:var(--dsh-any-input-blur,none)}' +\r\n // Every fill token, not just the one the Cordis panel's option boxes used to\r\n // read: on a release where a menu paints from a layer token, scoping only the\r\n // old name would let the box inherit the CARD alpha from `body` while the panel\r\n // itself follows the input slider. Inert where the host reads one token.\r\n `[data-cordis-panel]{${menuFillDecls('var(--dsh-any-op-menu-cordis)!important')}}`\r\n}\r\n\r\nfunction applyInputBlur(px: number): void {\r\n const root = document.documentElement\r\n // The frost gate: with the slider at 0 the plugin must not add any layering to\r\n // the composer at all (see inputBlurRule).\r\n if (px > 0) root.classList.add(INPUT_FROST_CLASS)\r\n else root.classList.remove(INPUT_FROST_CLASS)\r\n if (px > 0) root.style.setProperty('--dsh-any-input-blur', `blur(${px}px)`)\r\n else root.style.removeProperty('--dsh-any-input-blur')\r\n}\r\n\r\n// Narrow-viewport hosts render a fixed session-title bar (.dsh-mobile-app-header)\r\n// above the AppFrame columns, outside every column's subtree. The main-bg alpha\r\n// lives on the columns (applyPartOpacities), so that bar paints the raw\r\n// wallpaper and splits visually from the translucent center column. Both rules\r\n// below ride plugin-owned variables so the bar follows the sliders and falls\r\n// back to the host default when the plugin never set them.\r\nexport const MOBILE_HEADER_RULE =\r\n '.dsh-mobile-app-header{' +\r\n 'background:var(--dsh-any-op-bg,transparent)!important;' +\r\n 'backdrop-filter:var(--dsh-any-part-blur-global,none);' +\r\n '-webkit-backdrop-filter:var(--dsh-any-part-blur-global,none)}'\r\n\r\n/** Mirror of the bg-part blur on :root. --dsh-any-part-blur is element-scoped\r\n * to the columns, so surfaces outside their subtree (the mobile header, or\r\n * third-party styles) can never inherit it. */\r\nfunction applyBgBlurGlobal(px: number): void {\r\n if (px > 0) document.documentElement.style.setProperty('--dsh-any-part-blur-global', `blur(${px}px)`)\r\n else document.documentElement.style.removeProperty('--dsh-any-part-blur-global')\r\n}\r\n\r\n// ── Right sidebar / workbench panel (the \"panel\" slider pair) ────────────────\r\n// The `panelOpacity` / blurs.panel pair targets two surfaces by mode:\r\n// · native — the host's own right Sidebar (`[data-sidebar-right-panel]`),\r\n// a `--dsw-alias-bg-base`-painted column of the page;\r\n// · dsh-better-sidebar installed — its bottom workbench panel\r\n// (`[data-dsh-bottom-panel]`), which paints every surface from the same\r\n// layer/bg-base tokens.\r\n// Both hang where neither the column opacities nor the part-blur underlays\r\n// reach, so both need their own treatment: a token re-scope here, and a blur rule\r\n// from the adapters.\r\n//\r\n// Which element the blur rides, and whether the panel has to be lifted out of its\r\n// stacking context to have wallpaper to sample, CHANGED between host releases —\r\n// that history (and the measurement behind it) lives with the adapters that answer\r\n// it, in `host-compat/versions/*`. The token re-scope below is layout-neutral and\r\n// stays correct on every release.\r\nexport const PANEL_TOKEN_RULE =\r\n // Re-scope the layer tokens so every surface inside the panel follows the\r\n // panel opacity slider only. The re-scope lives in the always-emitted\r\n // stylesheet so it works even with no palette (pointing at unwritten vars\r\n // would invalidate the background and drop the surface entirely;\r\n // `applyPanelOverrides` writes the vars on every call).\r\n `${PANEL_SURFACES}{` +\r\n '--dsw-alias-bg-base:var(--dsh-any-panel-bg-base);' +\r\n '--dsw-alias-bg-layer-1:var(--dsh-any-panel-layer-1);' +\r\n '--dsw-alias-bg-layer-2:var(--dsh-any-panel-layer-2);' +\r\n '--dsw-alias-bg-layer-3:var(--dsh-any-panel-layer-3)}'\r\n\r\n// ── Header popovers (Agent Team panel + background-job list + open-in-app /\r\n// session-log menus + subagent lineage tree) ────────────────────────────────\r\n// Session-header dropdowns that paint from --dsw-specific-menu, the same token\r\n// the card slider owns — so they used to follow the card opacity, and the\r\n// non-Menu ones never got any blur (they are `position: absolute` under their\r\n// own trigger, not portaled to body, so popoverBlurRule's\r\n// `body > [role=\"dialog\"]` selector misses them). This rule gives them their\r\n// own part: the header opacity slider retints the menu token for these\r\n// surfaces only, and the header blur slider frosts them.\r\n//\r\n// This rule is appended AFTER popoverBlurRule in the static stylesheet, and\r\n// each selector carries equal-or-higher specificity — so listing a surface here\r\n// cleanly overrides the card group instead of fighting it. That matters for the\r\n// menu selectors below, which DO already match `[role=\"menu\"]`: they are moved\r\n// from the card group to the header group, not merely added.\r\n//\r\n// TWO MATCHING STRATEGIES, primary first:\r\n//\r\n// 1. [data-dsh-any-header-popover] — the runtime tag (see header-tag.ts). Every\r\n// header dropdown portals its popover to <body> through the Menu/tree\r\n// primitive, which severs the DOM link to the header and exposes no\r\n// id/aria-controls back-link, so no ancestor selector can reach it. The tag\r\n// module observes the stable `[data-slot=\"conversation.session.header*\"]`\r\n// anchors (emitted by the slot renderer on 0.1.5 → 0.1.7 alike) and marks the\r\n// open popover. This is the ONLY strategy that still works on 0.1.7, where\r\n// open-in-app moved to a portal and the session row menu became a dynamic\r\n// slot — see below.\r\n//\r\n// 2. Class-shape fallbacks — retained for hosts where the tag observer has not\r\n// run yet (first paint) or is unavailable, and they still cover 0.1.5/0.1.6:\r\n// · ul[class*=\"_menu\"] — the background-job list. It is one of exactly TWO\r\n// host <ul> elements styled by a `menu` CSS-module class; the other is the\r\n// schedule catalog (`ui-schedule` ScheduleCatalogAction.tsx), verified on\r\n// 0.1.7-alpha.1. Every remaining `_menu` consumer (ModelSelect, TabMenu,\r\n// MenuView, TerminalGuide, SubagentHeaderLineage) renders a <div>. The two\r\n// <ul>s are portal'd siblings with the same attributes (class, style,\r\n// aria-label) and no distinguishing marker, so this fallback cannot single\r\n// out the job list: the schedule catalog takes the header look too.\r\n// Strategy 1 never tags it, so that overlap comes from this rule alone.\r\n// ACCEPTED as-is: keeping the job list styled on first paint is worth more\r\n// than holding the catalog on the card group, so do not \"fix\" the match.\r\n// · div[role=\"dialog\"][class*=\"_panel\"]:not([aria-modal=\"true\"]) — the\r\n// Agent Team panel. The other `_panel` + role=\"dialog\" element is the\r\n// settings modal (aria-modal=\"true\"), which SETTINGS_STYLE_RULE owns.\r\n// · [role=\"tree\"][class*=\"_menu\"] — the subagent lineage tree. Portal'd, so\r\n// `body > [role=\"tree\"]` already matched it; the class is what separates\r\n// it from every other `role=\"tree\"` (workspace lists use `.list` /\r\n// `.flatList` / `.searchTree`).\r\n// · [role=\"menu\"][class*=\"_denseList\"]:not([class*=\"_portal\"]) — the two\r\n// in-place `dense` Menu primitives: open-in-app's picker and the\r\n// session-log download menu on 0.1.5/0.1.6. The `:not([_portal])` is\r\n// what keeps every PORTALED dense menu (WorkspaceBrowser view options,\r\n// TextPreview open-with, ReviewTab file selector) on the card slider.\r\n// NOTE: on 0.1.7 open-in-app became `portal`+`dense` (see\r\n// OpenTargetButton.tsx), so this fallback deliberately no longer matches\r\n// it — strategy 1's tag is what restores the header grouping there.\r\n// Keeping the exclusion matters: broadening it would drag the side-panel\r\n// dense menus into the header group.\r\n// SPECIFICITY IS LOAD-BEARING HERE. The card group's rule is\r\n// `[role=\"menu\"]:not([data-dockkit-tab-menu])` — specificity (0,2,0) — so a bare\r\n// `[data-dsh-any-header-popover]` (0,1,0) LOSES to it no matter how late it\r\n// appears in the sheet. That is exactly how the tagged open-in-app menu kept\r\n// taking the card blur. Every header selector below therefore carries an extra\r\n// attribute so it reaches (0,2,0)+ and genuinely overrides the card group:\r\n// · [data-dsh-any-header-popover][role] → (0,2,0)\r\n// · [role=\"menu\"][class*=\"_denseList\"]... → (0,2,0)+\r\n//\r\n// NO TOKEN DECLARATION LIVES HERE. The header group's surface color is written\r\n// as a LITERAL by `applyHeaderPopovers` into a dedicated sheet, for the same\r\n// reason `applyExemptDefaults` is: an earlier revision declared\r\n// `--dsw-specific-menu:var(--dsh-any-op-menu-header,var(--dsw-specific-menu))`,\r\n// which is a SELF-REFERENCE. With `--dsh-any-op-menu-header` unset (before the\r\n// first apply, or on a host the plugin cannot sample) the fallback names the\r\n// property being declared, the custom property computes to the\r\n// guaranteed-invalid value, and every menu background reading it goes fully\r\n// transparent. Literals cannot cycle; when no color resolves we emit nothing and\r\n// the surface keeps the re-scoped value instead.\r\n/** The header dropdown surfaces, spelled ONCE. Three rules consume this set (the\r\n * static blur rule, the dynamic token rule and the stroke group), and every one\r\n * of them drifting by a single attribute re-introduces the bug where a header\r\n * menu keeps the card slider's look instead of its own.\r\n *\r\n * Strategy 1 is the runtime tag (`header-tag.ts`); strategies 2 are class-shape\r\n * fallbacks for the first paint before the tag observer runs. */\r\nconst HEADER_TAG_SELECTOR = `[${HEADER_POPOVER_ATTR}]`\r\nconst HEADER_SURFACES = [\r\n HEADER_TAG_SELECTOR,\r\n 'ul[class*=\"_menu\"],div[role=\"dialog\"][class*=\"_panel\"]:not([aria-modal=\"true\"])',\r\n `[role=\"menu\"][class*=\"_denseList\"]:not([class*=\"_portal\"])`,\r\n '[role=\"tree\"][class*=\"_menu\"]',\r\n]\r\n\r\n/** SPECIFICITY IS LOAD-BEARING HERE. The card group's rule is\r\n * `[role=\"menu\"]:not([data-dockkit-tab-menu])` — specificity (0,2,0) — so a bare\r\n * `[data-dsh-any-header-popover]` (0,1,0) LOSES to it no matter how late it\r\n * appears in the sheet. That is exactly how the tagged open-in-app menu kept\r\n * taking the card blur. `[role]` is a no-op presence test that raises only the\r\n * tagged arm to (0,2,0); the other three already qualify at (0,2,0)+. */\r\nconst HEADER_SURFACES_PADDED = [`${HEADER_TAG_SELECTOR}[role]`, ...HEADER_SURFACES.slice(1)]\r\n\r\n/** The header blur variable, and the rule that frosts the header's dropdown set.\r\n * The declaration comes from the same adapter answer as the card group's menu arm:\r\n * every surface in this set paints its skin from the host's own menu-blur token\r\n * (`SubagentHeaderLineage.module.css:120` uses a pseudo-element, the stat dialog and\r\n * goal bar use their own layer), so handing over the token reaches all of them on\r\n * both paint shapes, while filtering the element would install the ancestor\r\n * backdrop root each of those files documents avoiding. */\r\nconst HEADER_BLUR_VAR = '--dsh-any-blur-header'\r\n\r\nexport function headerPopoverRule(): string {\r\n return `${HEADER_SURFACES_PADDED.join(',')}{${menuFrost(HEADER_BLUR_VAR)}}`\r\n}\r\n\r\n// ── Surfaces pinned against the sliders (theme color kept) ────────────────────\r\n// Two groups the user wants the sliders to leave alone, for two reasons:\r\n//\r\n// 1. Modal-native confirm dialogs — `role=\"dialog\"[aria-modal=\"true\"]` WITHOUT\r\n// `aria-labelledby` (which is what separates them from the settings panel\r\n// that SETTINGS_STYLE_RULE owns). These are the rename / delete / risk /\r\n// feedback confirmations: short-lived, destructive or decision-critical\r\n// prompts whose legibility must not depend on an appearance slider. They do\r\n// not match SETTINGS_STYLE_RULE, but they still inherit the body-level token\r\n// re-scope, so the card slider's alpha on --dsw-alias-bg-layer-2 bleeds into\r\n// them. `applyExemptDefaults` pins those tokens at alpha 1 — keeping whatever\r\n// color the theme dictates, dropping only the slider's translucency.\r\n//\r\n// 2. Session row menus — the portal'd `[role=\"menu\"]` listing rename / fork /\r\n// archive / delete. Structurally identical to every other Menu primitive\r\n// (model selector, @-suggestions, …) and portalled to body, so no attribute\r\n// or ancestor distinguishes it. `:has([class*=\"_danger\"])` approximates it:\r\n// `_danger` is the destructive-row class, and among host menus only the\r\n// session-row menu carries one (for its 删除会话 entry). Deliberately narrow,\r\n// and it no-ops on engines without :has() (the menu simply keeps the card\r\n// look rather than breaking).\r\n//\r\n// Both groups come AFTER popoverBlurRule / SETTINGS_STYLE_RULE so they win on\r\n// order.\r\n//\r\n// IMPORTANT — no self-referencing fallbacks. An earlier version wrote\r\n// `--dsw-alias-bg-layer-2:var(--dsh-any-host-layer-2,var(--dsw-alias-bg-layer-2))`.\r\n// When the host var is unset the fallback names the property being declared,\r\n// which is a CSS cycle: the custom property computes to the guaranteed-invalid\r\n// value and every `background:var(--dsw-alias-bg-layer-2)` consuming it becomes\r\n// invalid — i.e. fully transparent. That is why the pin is emitted DYNAMICALLY\r\n// with real literals (see applyExemptDefaults): when no color resolves we emit\r\n// NO declaration at all, so the element keeps the re-scoped value instead of\r\n// going transparent.\r\n//\r\n// Only the parts that cannot go invalid stay static: the blur/stroke resets.\r\nexport function exemptDefaultRule(): string {\r\n return '[role=\"dialog\"][aria-modal=\"true\"]:not([aria-labelledby]){' +\r\n 'backdrop-filter:none;-webkit-backdrop-filter:none}' +\r\n // Session row menus (approximated by their destructive row): no plugin blur,\r\n // no plugin stroke. Its surface color is restored dynamically too. The frost is\r\n // cleared through the release's own menu arm — on a MenuSurface host\r\n // `backdrop-filter:none` on the element would leave the child layer frosted.\r\n `[role=\"menu\"]:has([class*=\"_danger\"]){${hostAdapter().menus.frostDecl('none')};` +\r\n '-webkit-text-stroke-width:0}'\r\n}\r\n\r\n/** Selector the dynamic header token rule targets — the same set as the static\r\n * headerPopoverRule above, so the two can never drift apart. */\r\nconst HEADER_TOKEN_SELECTOR = HEADER_SURFACES_PADDED.join(',')\r\n\r\n/** Header-popover surfaces: retint the menu token and (re)write the blur.\r\n * Mirrors applyProduced: the static rule above never changes, so a drag only\r\n * rewrites the blur variable and this one dynamic rule. */\r\nexport function applyHeaderPopovers(): void {\r\n const root = document.documentElement\r\n const px = rBlurs().header\r\n if (px > 0) root.style.setProperty('--dsh-any-blur-header', `blur(${px}px)`)\r\n else root.style.removeProperty('--dsh-any-blur-header')\r\n // Alpha: re-emit the live menu token's own color with the header opacity so\r\n // the popover keeps the host palette (and follows a picked color) while fading\r\n // independently of the card slider. EVERY fill token the release paints menus\r\n // from gets that same literal (`menuFillDecls`), because one header opacity has\r\n // to mean one look whether the surface reads the old name or the layer's new one.\r\n //\r\n // LITERAL, not a CSS var indirection — see the note above on the header group.\r\n // The declaration goes into a dedicated sheet so the static rule stays\r\n // selector-only and a drag rewrites just this one text node.\r\n let opacity = rHeaderOpacity()\r\n if (opacity < 0) opacity = 0\r\n if (opacity > 1) opacity = 1\r\n const surfaces = paletteTokens() ?? readHostOpacityTokens()\r\n const menu = surfaces?.[MENU_FILL_TOKEN]\r\n const el = ensureHeaderStyle()\r\n // Nothing resolved: emit NO declaration rather than an invalid one, so the\r\n // surface keeps the re-scoped token value instead of going transparent.\r\n const css = menu === undefined\r\n ? ''\r\n : `${HEADER_TOKEN_SELECTOR}{${menuFillDecls(toRgba(menu, opacity))}}`\r\n if (el.textContent !== css) el.textContent = css\r\n}\r\n\r\nlet headerStyleEl: HTMLStyleElement | null = null\r\nfunction ensureHeaderStyle(): HTMLStyleElement {\r\n if (headerStyleEl?.isConnected) return headerStyleEl\r\n headerStyleEl = document.createElement('style')\r\n headerStyleEl.dataset.plugin = 'dsh-any-background-header'\r\n document.head.appendChild(headerStyleEl)\r\n return headerStyleEl\r\n}\r\n\r\n/** Pin the exempt groups (confirm dialogs and the session-row menu) so no\r\n * appearance slider moves them — while KEEPING the active theme color.\r\n *\r\n * \"Default\" here means \"not faded, not blurred\", NOT \"host-palette original\":\r\n * an earlier version restored the :root host colors, which also stripped the\r\n * picked theme color and made the menu look un-themed. The correct source is\r\n * the same one every other slider uses (the plugin palette when there is one,\r\n * else the host's resolved tokens) with alpha pinned to 1 — so the surface\r\n * keeps whatever color the theme currently dictates and only loses the slider's\r\n * translucency and blur.\r\n *\r\n * Emitted as REAL literals into a dedicated stylesheet, never as\r\n * `var(--x, var(--x))`: a self-referencing fallback is a CSS cycle that\r\n * computes to the guaranteed-invalid value and turns every consuming\r\n * `background:var(--dsw-alias-bg-layer-2)` fully transparent. Literals also\r\n * mean that when no color can be resolved we emit NO declaration at all, so\r\n * the surface keeps the re-scoped value rather than going transparent. */\r\nexport function applyExemptDefaults(): void {\r\n if (typeof document === 'undefined') return\r\n const source = paletteTokens() ?? readHostOpacityTokens()\r\n const el = ensureExemptStyle()\r\n const decls: string[] = []\r\n // Only declare a token we actually resolved a color for, and pin it opaque.\r\n const add = (token: string, value: string | undefined): void => {\r\n if (value === undefined || value === '') return\r\n // Literal with alpha 1 — no cycle possible, and no slider translucency.\r\n decls.push(`${token}:${toRgba(value, 1)}`)\r\n }\r\n add('--dsw-alias-bg-layer-1', source?.['--dsw-alias-bg-layer-1'])\r\n add('--dsw-alias-bg-layer-2', source?.['--dsw-alias-bg-layer-2'])\r\n add('--dsw-alias-bg-layer-3', source?.['--dsw-alias-bg-layer-3'])\r\n // One sampled color, declared under EVERY name this release paints a menu from:\r\n // a session-row menu on a `MenuSurface` host fades out of the layer token, and\r\n // pinning only the old name would leave it faded while everything else around it\r\n // went opaque. A name the host does not read is inert.\r\n const menuColor = source?.[MENU_FILL_TOKEN]\r\n for (const name of hostAdapter().menus.fillTokens) add(name, menuColor)\r\n if (decls.length === 0) {\r\n // Nothing resolved (pre-mount / host ships none): drop the pin rather than\r\n // emit an invalid one. The surfaces keep the re-scoped look.\r\n if (el.textContent !== '') el.textContent = ''\r\n return\r\n }\r\n const dialog = '[role=\"dialog\"][aria-modal=\"true\"]:not([aria-labelledby])'\r\n const body = decls.join(';')\r\n const css =\r\n `${dialog},${dialog} *{${body}}` +\r\n `[role=\"menu\"]:has([class*=\"_danger\"]){${body}}`\r\n if (el.textContent !== css) el.textContent = css\r\n}\r\n\r\nlet exemptStyleEl: HTMLStyleElement | null = null\r\nfunction ensureExemptStyle(): HTMLStyleElement {\r\n if (exemptStyleEl?.isConnected) return exemptStyleEl\r\n exemptStyleEl = document.createElement('style')\r\n exemptStyleEl.dataset.plugin = 'dsh-any-background-exempt'\r\n document.head.appendChild(exemptStyleEl)\r\n return exemptStyleEl\r\n}\r\n\r\n// ── Produced/artifact surfaces ─────────────────────────────────────────────\r\n// The surfaces owned by the \"产出物/高亮内容\" (produced/highlights) slider are\r\n// the code blocks inside conversation content (host CodeBlock → `.md-code-block`\r\n// wrapping `[data-code-block-content]` > `<pre class=\"shiki css-variables\">`),\r\n// their banner, the inline `code` chips in markdown (the small background box\r\n// around identifiers like `@supports`, rendered by the host's\r\n// `:not(pre) > code` rule) and the composer's reference chips\r\n// (`[data-composer-chip]`).\r\n//\r\n// Those sliders are an ALPHA control for the color a surface ALREADY uses — they\r\n// must never paint a color of their own. The host paints the block background\r\n// from its own tokens: `--dsl-code-block-background` (= `--dsw-alias-markdown-\r\n// code-block`) on the wrapper and again on the inner `pre`,\r\n// `--dsl-code-block-banner-background-color` on the banner, and\r\n// `--dsw-alias-markdown-inline-code` on an inline chip. The shiki `pre` also\r\n// carries an inline `background-color: var(--shiki-background)`, which the theme\r\n// package aliases to that same `--dsw-alias-markdown-code-block`. So every layer\r\n// is re-emitted through `color-mix(in srgb, <its own host color> <pct>,\r\n// transparent)`: 100% reproduces the host color exactly, and lowering it fades\r\n// THAT surface instead of stacking a second background on top of the original\r\n// one.\r\n//\r\n// The opaque wrapper layers (the `.md-code-block` fill and the sticky banner\r\n// wrapper's `--dsw-alias-bg-base` backdrop) are cleared so the wallpaper shows\r\n// through once, and `backdrop-filter` gets something to frost; only the `pre`,\r\n// the banner and the inline chips carry the modulated color. The\r\n// `--shiki-background` alias is re-pointed on the content container as well, so\r\n// the same control reaches code blocks that live outside `.md-code-block` (the\r\n// document preview) and take their background from that inline variable alone.\r\n// Values ride root CSS variables, so blocks and chips that stream in after a\r\n// reply pick them up without an observer.\r\nexport const PRODUCED_RULE =\r\n // ── Frosting (backdrop-filter) ─────────────────────────────────────────────\r\n // Kept outside the color-mix guard so it never depends on color-mix support.\r\n // TerminalBlock ([data-terminal]), ReadBlock ([data-read]) and\r\n // ContextInjectionRow body ([data-context-injection-body]) all share the\r\n // --dsw-alias-markdown-code-block surface as code blocks, so they receive\r\n // both blur and alpha modulation below.\r\n //\r\n // ChangedFiles ([data-changed-files]): from 0.1.7 the card ROOT carries its own\r\n // fill (--dsw-alias-bg-layer-1), so the frost belongs on the root — one frost\r\n // per card. The header button and its tile are faded by alpha alone (see the\r\n // --changes-fill arms below); frosting them too would blur the already frosted\r\n // root behind them.\r\n //\r\n // SearchBlock ([data-search]) and WebBlock ([data-web]) both paint from\r\n // --dsw-alias-markdown-code-block (their .block root), so they join the\r\n // same produced surface group.\r\n //\r\n // The expanded IN/OUT card (.ioCard, ToolRow + bash-sample) also paints from\r\n // --dsw-alias-markdown-code-block. It carries no data-* attribute, so it binds\r\n // by its CSS-Module class shape: the harness build hashes classes as\r\n // `<hash>_<localName>` (e.g. `o3BgMG_ioCard`), so `[class*=\"_ioCard\"]` is\r\n // stable across builds while a bare `.ioCard` would never match.\r\n //\r\n // The three surfaces 0.1.7 added to the produced family all filled from\r\n // --dsw-alias-markdown-code-block when they appeared: DiffBlock ([data-diff]), the\r\n // tool-result detail block (ToolDetails .root, marked [data-inspect] when it offers\r\n // the inspector) and the turn-event row ([data-turn-trigger]). They frost off the\r\n // same attribute either way; the turn row's own fill moved at `0.2.0-rc.2`, which\r\n // is the alpha arm's business, not this list's.\r\n //\r\n // Inline `code` chips (:not(pre)>code) ride the frost as well: they are the one\r\n // produced surface a reader sees mid-sentence, and leaving them opaque while the\r\n // block behind them faded made them look pinned to the wallpaper instead of part\r\n // of it. They are display:inline-flex, so the promotion risk is real — the\r\n // compact markdown variant ([data-markdown-variant=\"compact\"], used by the\r\n // reasoning rows) resets display to `inline`, where a frost would fragment\r\n // across line boxes, so that context opts back out.\r\n //\r\n // The hover preview window ([style*=\"--dsh-hover-preview-fade\"]) is the artifact\r\n // a produced surface opens: `ui-primitives/HoverCard` portals its card to\r\n // document.body, so no in-tree re-scope can reach it and it painted its own\r\n // literal `--dsw-hovercard-bg: #2C2C2E` (identical in both themes, deliberately a\r\n // component variable and not a theme token — see HoverCard.module.css) untouched\r\n // by any slider. That inline custom property is the only stable marker it has:\r\n // the class is hashed per build, and on 0.1.5-rc.2 / 0.1.6-alpha.2 the card\r\n // element carries no attribute at all, so those hosts simply never match it here\r\n // rather than being caught by a `[class$=\"_card\"]` that would also hit the\r\n // composer and the changed-files card.\r\n '[data-code-block-content] pre,[data-code-block-banner],[data-composer-chip],' +\r\n '[data-changed-files],' +\r\n '[data-terminal],[data-read],[data-diff],[data-context-injection-body],' +\r\n '[data-search],[data-web],[class*=\"_ioCard\"],' +\r\n '[data-inspect],[data-turn-trigger],' +\r\n '[style*=\"--dsh-hover-preview-fade\"],' +\r\n ':not(pre)>code{' +\r\n '-webkit-backdrop-filter:var(--dsh-any-blur-prod,none);' +\r\n 'backdrop-filter:var(--dsh-any-blur-prod,none)}' +\r\n '[data-markdown-variant=\"compact\"] :not(pre)>code{' +\r\n '-webkit-backdrop-filter:none;backdrop-filter:none}' +\r\n // ── dsh-better-sidebar workbench [data-dsh-bottom-panel] ──────────────────\r\n // The third-party bottom panel is a produced surface by nature — it opens the\r\n // artifact a conversation row points at — so since 0.3.2 the produced pair owns\r\n // it instead of the panel row, which is now just the host's own right Sidebar.\r\n // Unlike a code block it does not paint one token: every surface inside it\r\n // (pane chrome, tab bar, cards) reads a layer token, so its alpha cannot ride\r\n // `--dsh-any-prod-pct` and re-emit in place; the four tokens are re-scoped from\r\n // root variables `applyProduced` writes at the slider's alpha, exactly the way\r\n // PANEL_TOKEN_RULE does for the native panel. Kept in its own block, not merged\r\n // into the selector list above, because an engine that drops one of these\r\n // declarations must not take the code-block frost down with it.\r\n `${BETTER_SIDEBAR_PANEL}{` +\r\n '-webkit-backdrop-filter:var(--dsh-any-blur-prod,none);' +\r\n 'backdrop-filter:var(--dsh-any-blur-prod,none)}' +\r\n `${BETTER_SIDEBAR_PANEL}{` +\r\n '--dsw-alias-bg-base:var(--dsh-any-prod-panel-bg-base);' +\r\n '--dsw-alias-bg-layer-1:var(--dsh-any-prod-panel-layer-1);' +\r\n '--dsw-alias-bg-layer-2:var(--dsh-any-prod-panel-layer-2);' +\r\n '--dsw-alias-bg-layer-3:var(--dsh-any-prod-panel-layer-3)}' +\r\n // ── Alpha (color-mix) ──────────────────────────────────────────────────────\r\n // Guarded: without color-mix support the host look stays untouched instead\r\n // of resolving the surface color to an invalid value.\r\n '@supports (background:color-mix(in srgb,red 50%,transparent)){' +\r\n // ── Existing code-block surfaces ───────────────────────────────────────────\r\n '.md-code-block{background:transparent!important}' +\r\n '.md-code-block>div{background-color:transparent!important}' +\r\n // Every base falls back to the older token names (0.1.2-alpha.4 has no\r\n // `--dsl-code-block-*` yet), so the color-mix can never resolve to an\r\n // invalid value and blank a surface out.\r\n '.md-code-block [data-code-block-content] pre{' +\r\n 'background-color:color-mix(in srgb,var(--dsl-code-block-background,var(--dsw-alias-markdown-code-block,transparent)) var(--dsh-any-prod-pct,100%),transparent)!important}' +\r\n '.md-code-block [data-code-block-banner]{' +\r\n 'background-color:color-mix(in srgb,var(--dsl-code-block-banner-background-color,var(--dsw-alias-markdown-code-block-banner,transparent)) var(--dsh-any-prod-pct,100%),transparent)!important}' +\r\n // Banners outside the markdown block: 0.1.7 moved ReadBlock / DiffBlock /\r\n // CodeBlock onto one shared CodeCard, whose `.header` fills from\r\n // `--dsl-code-block-banner-background-color` when a markdown block is in scope\r\n // and otherwise from `--dsl-code-block-background` → `--dsw-alias-markdown-code-block`\r\n // (CodeCard.module.css:16). Re-emitting that same chain is what keeps the banner\r\n // themed: the older `--dsw-alias-markdown-code-block-banner` token below is a\r\n // near-white value 0.1.7 no longer paints here, so forcing it made every read /\r\n // diff header a pale slab that ignored the produced alpha.\r\n '[data-code-block-banner]{' +\r\n 'background-color:color-mix(in srgb,var(--dsl-code-block-banner-background-color,var(--dsl-code-block-background,var(--dsw-alias-markdown-code-block,transparent))) var(--dsh-any-prod-pct,100%),transparent)!important}' +\r\n '[data-code-block-content]{' +\r\n '--shiki-background:color-mix(in srgb,var(--dsw-alias-markdown-code-block,var(--dsl-code-block-background,transparent)) var(--dsh-any-prod-pct,100%),transparent)}' +\r\n // Inline markdown `code` chips: the host's own selector shape, so the chip\r\n // keeps its token color and only loses alpha (plus the shared frost).\r\n ':not(pre)>code{' +\r\n 'background-color:color-mix(in srgb,var(--dsw-alias-markdown-inline-code,transparent) var(--dsh-any-prod-pct,100%),transparent)!important}' +\r\n '[data-composer-chip]>*{' +\r\n 'background-color:color-mix(in srgb,var(--dsw-alias-interactive-bg-hover,transparent) var(--dsh-any-prod-pct,100%),transparent)!important}' +\r\n // ── TerminalBlock [data-terminal] ──────────────────────────────────────────\r\n // Root: background: var(--dsw-alias-markdown-code-block) (TerminalBlock.module.css).\r\n // The copy button inside re-asserts that same token as an opaque fill so it\r\n // stays readable over scrolling output. Clear it so the card fades uniformly.\r\n '[data-terminal]{' +\r\n 'background-color:color-mix(in srgb,var(--dsw-alias-markdown-code-block,transparent) var(--dsh-any-prod-pct,100%),transparent)!important}' +\r\n '[data-terminal] button{background-color:transparent!important}' +\r\n // ── ReadBlock [data-read] / DiffBlock [data-diff] ────────────────────────\r\n // Both are CodeCards from 0.1.7: the root fills from\r\n // --dsw-alias-markdown-code-block and the banner carries\r\n // [data-code-block-banner], handled by the shared banner arm above. The guarded\r\n // rule below only serves 0.1.6, where ReadBlock's first child WAS a banner\r\n // painted from --dsw-alias-markdown-code-block-banner and carried no marker.\r\n '[data-read],[data-diff]{' +\r\n 'background-color:color-mix(in srgb,var(--dsw-alias-markdown-code-block,transparent) var(--dsh-any-prod-pct,100%),transparent)!important}' +\r\n '[data-read]>div:first-child:not([data-code-block-banner]),' +\r\n '[data-diff]>div:first-child:not([data-code-block-banner]){' +\r\n 'background-color:color-mix(in srgb,var(--dsw-alias-markdown-code-block-banner,transparent) var(--dsh-any-prod-pct,100%),transparent)!important}' +\r\n // ── ContextInjectionRow body [data-context-injection-body] ────────────────\r\n // The .body element uses --dsw-alias-markdown-code-block (same as code blocks).\r\n '[data-context-injection-body]{' +\r\n 'background-color:color-mix(in srgb,var(--dsw-alias-markdown-code-block,transparent) var(--dsh-any-prod-pct,100%),transparent)!important}' +\r\n // ── ToolDetails [data-inspect] / turn-event row [data-turn-trigger] ───────\r\n // The two produced surfaces 0.1.7 added outside the code-block family. They read\r\n // the same token through `0.1.7` … `0.2.0-rc.1` (ToolDetails.module.css,\r\n // TurnTriggerNodeView.module.css), and `0.2.0-rc.2` gave the turn row its own\r\n // pair — but wrote it the way a host hands a surface to its theme:\r\n // background: var(--dsw-alias-turn-trigger-bg, var(--dsw-alias-markdown-code-block))\r\n // :hover var(--dsw-alias-turn-trigger-bg-hover, var(--dsw-alias-interactive-bg-hover))\r\n // with both aliases declared on `body`, so in DARK mode the row is\r\n // `--dsw-alias-interactive-bg-hover` (and its hover is `-bg-active`) while the\r\n // code block stays where it was. Reading the same chain is what keeps this arm\r\n // release-neutral — a `var()` fallback is the host's own \"if that property is not\r\n // set\" test, so an older host takes the code-block color and a newer one takes its\r\n // own, with no version check here. Sharing one rule with `[data-inspect]` instead\r\n // would be a visible bug: the `!important` mix would keep painting the row with\r\n // the pre-rc.2 color and the row would stop tracking its hover state.\r\n '[data-inspect]{' +\r\n 'background-color:color-mix(in srgb,var(--dsw-alias-markdown-code-block,transparent) var(--dsh-any-prod-pct,100%),transparent)!important}' +\r\n '[data-turn-trigger]{' +\r\n 'background-color:color-mix(in srgb,var(--dsw-alias-turn-trigger-bg,var(--dsw-alias-markdown-code-block,transparent)) var(--dsh-any-prod-pct,100%),transparent)!important}' +\r\n '[data-turn-trigger]:hover{' +\r\n 'background-color:color-mix(in srgb,var(--dsw-alias-turn-trigger-bg-hover,var(--dsw-alias-interactive-bg-hover,transparent)) var(--dsh-any-prod-pct,100%),transparent)!important}' +\r\n // ── ChangedFiles card [data-changed-files] ────────────────────────────────\r\n // 0.1.7 gave the card a root fill (--dsw-alias-bg-layer-1) plus a header and a\r\n // file-count tile that both paint from --changes-fill (neutral-50 light /\r\n // neutral-850 dark, redefined under body[data-ds-dark-theme]). All three follow\r\n // the produced slider now: with the root opaque and the file rows transparent,\r\n // the card read as a hard white plate no matter where the slider sat. The tile\r\n // is alpha-only because the root behind it already frosts.\r\n //\r\n // The root cannot fade with color-mix the way its siblings do: --dsw-alias-bg-layer-1\r\n // is the token the interface \"card\" (option-panel) slider re-emits globally on\r\n // `body`, so mixing on top of it multiplied two alphas and the artifact card\r\n // answered to both sliders. It reads the produced slider's own re-emit of the\r\n // RAW token instead — one surface, one slider.\r\n '[data-changed-files]{' +\r\n 'background-color:var(--dsh-any-prod-layer-1,var(--dsw-alias-bg-layer-1,transparent))!important}' +\r\n '[data-changed-files]>button:first-child{' +\r\n 'background-color:color-mix(in srgb,var(--changes-fill,transparent) var(--dsh-any-prod-pct,100%),transparent)!important}' +\r\n '[data-changed-files]>button:first-child:hover{' +\r\n 'background-color:color-mix(in srgb,var(--changes-hover,var(--changes-fill,transparent)) var(--dsh-any-prod-pct,100%),transparent)!important}' +\r\n '[data-changed-files]>button:first-child>span:first-child{' +\r\n 'background-color:color-mix(in srgb,var(--changes-fill,transparent) var(--dsh-any-prod-pct,100%),transparent)!important}' +\r\n // ── Hover preview window [style*=\"--dsh-hover-preview-fade\"] ───────────────\r\n // See the frost list above for why this is the marker. Two surfaces live under\r\n // that one attribute, and they do NOT paint from the same place:\r\n // · the plain card — `.card` in HoverCard.module.css — keeps its component\r\n // literal `--dsw-hovercard-bg: #2C2C2E` (dark in BOTH themes by the host's\r\n // own choice), so mixing on that token fades the color the host uses.\r\n // · the `preview` variant (`.preview`, what ChangedFiles opens) repaints from\r\n // --dsw-alias-bg-layer-1, i.e. the THEME surface, and never redefines the\r\n // literal. Mixing on --dsw-hovercard-bg there would replace a light themed\r\n // card with the dark one — measured: the preview came out\r\n // rgb(44,44,46) over a light theme. It reads the produced slider's raw\r\n // layer-1 instead, the same single-slider route the changed-files card uses.\r\n // The fallback keeps the host's own color if that variable has not been written\r\n // yet; it is the card-slider remapped token there, which is the pre-existing host\r\n // look, not a second alpha.\r\n '[style*=\"--dsh-hover-preview-fade\"]{' +\r\n 'background-color:color-mix(in srgb,var(--dsw-hovercard-bg,#2c2c2e) var(--dsh-any-prod-pct,100%),transparent)!important}' +\r\n '[style*=\"--dsh-hover-preview-fade\"][class*=\"_preview\"]{' +\r\n 'background-color:var(--dsh-any-prod-layer-1,var(--dsw-alias-bg-layer-1,transparent))!important}' +\r\n // ── SearchBlock [data-search] ─────────────────────────────────────────────\r\n // Root (.block): background: var(--dsw-alias-markdown-code-block).\r\n // Header (.header): background: var(--dsw-alias-markdown-code-block-banner).\r\n // Only the root body fades — the header banner keeps its opaque host color\r\n // so the white/grey title bar stays visually stable regardless of the slider.\r\n '[data-search]{' +\r\n 'background-color:color-mix(in srgb,var(--dsw-alias-markdown-code-block,transparent) var(--dsh-any-prod-pct,100%),transparent)!important}' +\r\n // ── WebBlock [data-web] ───────────────────────────────────────────────────\r\n // Root (.block): background: var(--dsw-alias-markdown-code-block).\r\n // No banner sub-surface; the single fill fades uniformly.\r\n '[data-web]{' +\r\n 'background-color:color-mix(in srgb,var(--dsw-alias-markdown-code-block,transparent) var(--dsh-any-prod-pct,100%),transparent)!important}' +\r\n // ── Expanded IN/OUT card [class*=\"_ioCard\"] ───────────────────────────────\r\n // ToolRow's and bash-sample's .ioCard: background: var(--dsw-alias-markdown-\r\n // code-block), the same surface as a code block. No banner sub-surface.\r\n '[class*=\"_ioCard\"]{' +\r\n 'background-color:color-mix(in srgb,var(--dsw-alias-markdown-code-block,transparent) var(--dsh-any-prod-pct,100%),transparent)!important}' +\r\n '}'\r\n\r\n// ── Per-part text stroke (-webkit-text-stroke) ────────────────────────────────\r\n// Same surface groups as the blur sliders (issue #16). Values ride two root\r\n// CSS variables per group — width and resolved color — so a slider drag only\r\n// rewrites variables while the (static) rules below never change. paint-order\r\n// MUST accompany every stroke declaration: without it the stroke paints over\r\n// the glyph and thins the characters.\r\n//\r\n// The two homepage columns (bg / sidebar groups) are discovered structurally\r\n// (see discoverParts) and carry the stroke INLINE from applyStrokes instead of\r\n// a static selector. Every other group binds to the same stable selectors the\r\n// blur rules already proved:\r\n// settings → the settings dialog (SETTINGS_PANEL_SEL)\r\n// card → the popover/menu surface set (popoverBlurRule's selectors)\r\n// input → composer card + cordis panel (inputBlurRule's markers), the\r\n// seat takeover cards beside the capsule, and the native editors\r\n// inside them (form controls do not inherit text properties from\r\n// their container)\r\n// chat → the conversation message column ([data-chat-flow])\r\n// trajectory → the trajectory view root\r\n// produced → code blocks / banners / inline code chips / composer chips.\r\n// Being a DIRECT rule it also shields those surfaces from the\r\n// inherited chat stroke — with produced width 0 the reset is\r\n// exactly the exemption shiki multi-color text needs.\r\n// panel → the host's own right Sidebar column (the dsh-better-sidebar\r\n// workbench sits in the produced group above, since 0.3.2)\r\n//\r\n// Global exemptions: SVG glyphs (host icons are paths, but paint-order is\r\n// inherited and would subtly alter stroked-and-filled icon rendering) and\r\n// ::placeholder text (italic hint text must stay unstroked).\r\n\r\nexport const STROKE_RULE = [\r\n // settings\r\n `${SETTINGS_PANEL_SEL}{-webkit-text-stroke:var(--dsh-any-stroke-settings-w,0px) var(--dsh-any-stroke-settings-c,transparent);paint-order:stroke fill}`,\r\n // card / popovers — selector set mirrors popoverBlurRule\r\n `[role=\"menu\"]:not([data-dockkit-tab-menu]),[role=\"listbox\"],body>[role=\"tree\"],body>[role=\"dialog\"]:not([aria-modal=\"true\"])` +\r\n `{-webkit-text-stroke:var(--dsh-any-stroke-card-w,0px) var(--dsh-any-stroke-card-c,transparent);paint-order:stroke fill}`,\r\n // input / controls — native editors need their own declaration\r\n `[data-composer-card],[data-cordis-panel],` +\r\n `[data-composer-card] textarea,[data-composer-card] input,[data-composer-card] [contenteditable],` +\r\n `[data-cordis-panel] input,[data-cordis-panel] textarea,` +\r\n // the seat takeover cards belong to this slider too (see inputBlurRule)\r\n `${COMPOSER_TAKEOVER_CARD},${COMPOSER_TAKEOVER_EDITOR}` +\r\n `{-webkit-text-stroke:var(--dsh-any-stroke-input-w,0px) var(--dsh-any-stroke-input-c,transparent);paint-order:stroke fill}`,\r\n // chat message column\r\n `[data-chat-flow]{-webkit-text-stroke:var(--dsh-any-stroke-chat-w,0px) var(--dsh-any-stroke-chat-c,transparent);paint-order:stroke fill}`,\r\n // trajectory view\r\n `[data-conversation-composer-overlay]{-webkit-text-stroke:var(--dsh-any-stroke-trajectory-w,0px) var(--dsh-any-stroke-trajectory-c,transparent);paint-order:stroke fill}`,\r\n // produced / artifact text — direct rule doubles as the chat-inheritance shield;\r\n // also covers changed-files card, tool-call terminal, file-read block and\r\n // context-injection notice (all \"produced/highlight\" surfaces).\r\n // SearchBlock [data-search] and WebBlock [data-web] join the same group:\r\n // they share the --dsw-alias-markdown-code-block surface and appear inline\r\n // in the conversation column, so they inherit the chat stroke without this\r\n // direct exemption, just like the other produced surfaces.\r\n // The expanded IN/OUT card joins by CSS-Module class shape ([class*=\"_ioCard\"],\r\n // see PRODUCED_RULE) — same surface, same exemption.\r\n // [data-diff] / [data-inspect] / [data-turn-trigger] join with the same PRODUCED_RULE\r\n // group: without a direct rule here their text would keep inheriting the chat\r\n // stroke while every other produced surface obeyed its own slider.\r\n `[data-code-block-content] pre,[data-code-block-content],[data-code-block-banner],[data-composer-chip],:not(pre)>code,` +\r\n `[data-changed-files],[data-terminal],[data-read],[data-diff],[data-inspect],[data-turn-trigger],[data-context-injection-body],[data-search],[data-web],[class*=\"_ioCard\"],[style*=\"--dsh-hover-preview-fade\"]` +\r\n // The workbench joined this group with 0.3.2 (PRODUCED_RULE), so its text does\r\n // too — otherwise the produced stroke would cover every artifact except the one\r\n // that opens them.\r\n `,${BETTER_SIDEBAR_PANEL}` +\r\n `{-webkit-text-stroke:var(--dsh-any-stroke-produced-w,0px) var(--dsh-any-stroke-produced-c,transparent);paint-order:stroke fill}`,\r\n // the host's own right Sidebar column\r\n `${PANEL_SURFACES}{-webkit-text-stroke:var(--dsh-any-stroke-panel-w,0px) var(--dsh-any-stroke-panel-c,transparent);paint-order:stroke fill}`,\r\n // header popovers — the same surfaces as headerPopoverRule, unpadded: a\r\n // stroke never competed with the card group's backdrop-filter, so raising\r\n // specificity here would change which group wins and is not ours to decide.\r\n `${HEADER_SURFACES.join(',')}` +\r\n `{-webkit-text-stroke:var(--dsh-any-stroke-header-w,0px) var(--dsh-any-stroke-header-c,transparent);paint-order:stroke fill}`,\r\n // exemptions\r\n // Turn status / progress chrome — never owned by the \"conversation text\r\n // frame\" (chat) stroke group, because `-webkit-text-stroke` is INHERITED: a rule\r\n // on [data-chat-flow] reaches straight into these rows, and on every host\r\n // generation that damage is not cosmetic.\r\n //\r\n // One selector per shape actually observed, so all generations are covered\r\n // without a version check — an attribute a release does not emit simply matches\r\n // nothing:\r\n // · [role=\"status\"] — 0.1.5/0.1.6 render the live line as a bare\r\n // `.turnStatus` div under [data-chat-flow] (ChatView.module.css: brand-blue\r\n // gradient + background-clip:text + -webkit-text-fill-color:transparent).\r\n // This is the reported 0.1.6 regression. It also covers the hidden live\r\n // announcement 0.1.7 emits for a11y, and the retry/error status rows.\r\n // · [data-turn-process] — the turn-process disclosure row (0.1.6 and 0.1.7\r\n // TurnProcessNodeView). Its label is elapsed-time / activity chrome\r\n // (\"深度求索中,用时40秒\", \"已搜索代码并协调子任务\"), not conversation prose.\r\n // · [style*=\"--dsh-text-shimmer-spread\"] / [data-text-shimmer] — the TextShimmer\r\n // primitive as 0.1.7 shipped it: it published that custom property INLINE on\r\n // the clipped element, so the substring match finds every instance whatever\r\n // the hashed class name is, and the semantic attribute marks exactly the\r\n // moments the gradient exists. Here the stroke is destructive: the glyphs are\r\n // painted by their own clipped gradient with a transparent fill, so a stroke\r\n // repaints them as one flat stroke-coloured blob and the shimmer disappears.\r\n // · [data-shimmer] — the SAME primitive, rewritten at 0.2.0-rc.1 (the old\r\n // attribute and the `--dsh-text-shimmer-spread` property are both gone from\r\n // that tag). Its paint moved off the text onto an absolutely-positioned\r\n // overlay (`.decoration` / `.sweep` / `.highlight`), so the failure mode\r\n // changed rather than disappeared: the real glyphs keep their own color, but\r\n // the inherited stroke lands on BOTH of the two stacked copies of the string,\r\n // outlining the sweeping one too. One rule on the root is enough here — the\r\n // attribute sits on the wrapper and the stroke reset inherits down into the\r\n // overlay subtree.\r\n //\r\n // `paint-order:normal` rides along for the same reason it does on `svg` below:\r\n // it is inherited too, and a stray `stroke fill` would reorder the fill.\r\n `[data-chat-flow] [role=\"status\"],` +\r\n `[data-chat-flow] [data-turn-process],` +\r\n `[data-chat-flow] [data-text-shimmer],` +\r\n `[data-chat-flow] [data-shimmer],` +\r\n `[data-chat-flow] [style*=\"--dsh-text-shimmer-spread\"]` +\r\n `{-webkit-text-stroke-width:0!important;paint-order:normal!important}`,\r\n `svg{-webkit-text-stroke-width:0!important;paint-order:normal!important}`,\r\n `::placeholder{-webkit-text-stroke-width:0!important}`,\r\n].join('')\r\n\r\n/** Groups whose stroke lands on the structurally-discovered columns (inline),\r\n * versus every group served by the static STROKE_RULE selectors. */\r\nconst STROKE_INLINE_GROUPS = ['bg', 'sidebar'] as const\r\ntype StrokeGroup = keyof PartBlurs\r\nconst STROKE_VAR_GROUPS: StrokeGroup[] = ['card', 'settings', 'chat', 'trajectory', 'input', 'panel', 'produced', 'header']\r\n\r\n/** Resolve one group's stroke color key into a concrete CSS color.\r\n * 'auto' contrasts the FONT direction (white fonts → black stroke and vice\r\n * versa — mirrors the label flip in applyCustomTokensNow); 'theme' follows\r\n * the live palette's brand primary (picked color → generated palette, else\r\n * the host's own resolved token). */\r\nfunction strokeColor(s: StrokeConfig): string {\r\n switch (s.color) {\r\n case 'gray': return '#808080'\r\n case 'black': return '#000'\r\n case 'white': return '#fff'\r\n case 'custom': return s.customColor\r\n case 'theme': {\r\n if (rHasColor() || rSchemeOverride() !== 'auto') {\r\n const [h, sa, l] = rColor()\r\n return genTokens(h, sa, l, rColorScheme()).tokens['--dsw-alias-brand-primary'] ?? '#808080'\r\n }\r\n if (typeof getComputedStyle !== 'undefined') {\r\n const v = getComputedStyle(document.documentElement).getPropertyValue('--dsw-alias-brand-primary').trim()\r\n if (v !== '') return v\r\n }\r\n return '#808080'\r\n }\r\n case 'auto':\r\n default: {\r\n // Font direction, same derivation order as applyCustomTokensNow: picked\r\n // color's palette direction, then a forced scheme, then the wallpaper\r\n // brightness verdict; light fonts (unknown) default to a white stroke.\r\n let fontDark: boolean\r\n if (rHasColor()) fontDark = rColorScheme() === 'dark'\r\n else if (rSchemeOverride() !== 'auto') fontDark = rScheme() === 'dark'\r\n else if (rBgDark() !== null) fontDark = rBgDark() === true\r\n else fontDark = false\r\n return fontDark ? '#000' : '#fff'\r\n }\r\n }\r\n}\r\n\r\n/** Write every group's stroke width/color variables + the two column strokes.\r\n * Called from applyWp so palette/verdict changes re-derive 'auto'/'theme'. */\r\n/** Write (or clear) one column's inline text stroke. The stroke rides inline\r\n * styles and is fully removed at width 0 so nothing lingers after the slider\r\n * resets. */\r\nfunction applyInlineStroke(el: HTMLElement, s: StrokeConfig): void {\r\n if (s.width > 0) {\r\n el.style.setProperty('-webkit-text-stroke', `${s.width}px ${strokeColor(s)}`)\r\n el.style.setProperty('paint-order', 'stroke fill')\r\n } else {\r\n el.style.removeProperty('-webkit-text-stroke')\r\n el.style.removeProperty('paint-order')\r\n }\r\n}\r\n\r\nexport function applyStrokes(): void {\r\n const strokes = rStrokes()\r\n const root = document.documentElement\r\n for (const g of STROKE_VAR_GROUPS) {\r\n const s = strokes[g]\r\n root.style.setProperty(`--dsh-any-stroke-${g}-w`, `${s.width}px`)\r\n root.style.setProperty(`--dsh-any-stroke-${g}-c`, strokeColor(s))\r\n }\r\n // Columns are dynamically discovered; the var groups above ride CSS\r\n // variables, the two column groups ride inline styles.\r\n discoverParts()\r\n for (const g of STROKE_INLINE_GROUPS) {\r\n const el = g === 'bg' ? centerEl : sidebarEl\r\n if (el !== null) applyInlineStroke(el, strokes[g])\r\n }\r\n}\r\n\r\n/** Live per-group stroke update during slider drag (no full re-apply). */\r\nexport function setPartStroke(part: StrokeGroup, s: StrokeConfig): void {\r\n if (STROKE_VAR_GROUPS.includes(part)) {\r\n document.documentElement.style.setProperty(`--dsh-any-stroke-${part}-w`, `${s.width}px`)\r\n document.documentElement.style.setProperty(`--dsh-any-stroke-${part}-c`, strokeColor(s))\r\n return\r\n }\r\n discoverParts()\r\n const el = part === 'bg' ? centerEl : sidebarEl\r\n if (el === null) return\r\n applyInlineStroke(el, s)\r\n}\r\n\r\n/** Teardown only: drop every stroke variable and column inline stroke. */\r\nfunction removeStrokes(): void {\r\n const root = document.documentElement\r\n for (const g of [...STROKE_VAR_GROUPS, ...STROKE_INLINE_GROUPS]) {\r\n root.style.removeProperty(`--dsh-any-stroke-${g}-w`)\r\n root.style.removeProperty(`--dsh-any-stroke-${g}-c`)\r\n }\r\n for (const el of [centerEl, sidebarEl]) {\r\n if (el === null) continue\r\n el.style.removeProperty('-webkit-text-stroke')\r\n el.style.removeProperty('paint-order')\r\n }\r\n}\r\n\r\n// ── Custom interface font ─────────────────────────────────────────────────────\r\n// One font file owns a server-side slot served from /dsh-any-background/font.\r\n// Applying it means: register an @font-face for the plugin-owned 'DAnyFont'\r\n// family and re-scope the host's interface font token (--dsw-font-family, the\r\n// base stack every text consumer reads) to `'DAnyFont', <original stack>` at\r\n// body level — the body-level custom property shadows :root's for all\r\n// descendants, so the swap survives host theme re-assertions (they rewrite\r\n// :root only). The host's code font (--ds-font-family-code) is deliberately\r\n// untouched: code blocks keep their mono stack.\r\n// The <style> element carries both the @font-face and the token override, so\r\n// disabling/removing the font is just removing the element.\r\n\r\nconst FONT_FAMILY = 'DAnyFont'\r\nlet fontStyleEl: HTMLStyleElement | null = null\r\n\r\nfunction fontFormatForMime(mime: string | null): string {\r\n switch (mime) {\r\n case 'font/woff2': return 'woff2'\r\n case 'font/woff': return 'woff'\r\n case 'font/otf': return 'opentype'\r\n default: return 'truetype'\r\n }\r\n}\r\n\r\n/** Apply or clear the custom interface font. `url` is the serve URL (null =\r\n * nothing stored); `enabled` gates the token override without deleting the\r\n * file. The original host stack is re-read on every apply so a host skin\r\n * change is picked up, and stays as the fallback after 'DAnyFont'. */\r\nexport function applyFontFace(url: string | null, enabled: boolean, mime: string | null): void {\r\n if (url === null || !enabled) {\r\n fontStyleEl?.remove()\r\n fontStyleEl = null\r\n return\r\n }\r\n if (fontStyleEl === null || !fontStyleEl.isConnected) {\r\n fontStyleEl = document.createElement('style')\r\n fontStyleEl.dataset.plugin = 'dsh-any-background-font'\r\n document.head.appendChild(fontStyleEl)\r\n }\r\n let stack = ''\r\n if (typeof getComputedStyle !== 'undefined') {\r\n stack = getComputedStyle(document.documentElement).getPropertyValue('--dsw-font-family').trim()\r\n }\r\n if (stack === '') stack = \"-apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', sans-serif\"\r\n const fmt = fontFormatForMime(mime)\r\n fontStyleEl.textContent =\r\n `@font-face{font-family:'${FONT_FAMILY}';src:url('${url}') format('${fmt}');font-display:swap}` +\r\n // Inheritable consumers only: form controls with UA default fonts keep\r\n // their own look unless the host already opted them into the token.\r\n `body{--dsw-font-family:'${FONT_FAMILY}',${stack}}` +\r\n `input,textarea,select,button{font-family:var(--dsw-font-family)}`\r\n}\r\n\r\n/** Teardown only: drop the @font-face + token override. */\r\nfunction removeFontFace(): void {\r\n fontStyleEl?.remove()\r\n fontStyleEl = null\r\n}\r\n\r\n/** The four layer slots a panel-wide token re-scope owns — both the variable\r\n * names to write and the shape the token source comes back in. */\r\ninterface LayerVarNames { base: string; layer1: string; layer2: string; layer3: string }\r\n\r\n/** The host's own defaults, read from the live `:root` so a custom host skin or\r\n * theme override wins. */\r\nfunction readHostLayerTokens(): LayerVarNames | null {\r\n if (typeof getComputedStyle === 'undefined') return null\r\n const root = document.documentElement\r\n const cs = getComputedStyle(root)\r\n const base = cs.getPropertyValue('--dsw-alias-bg-base').trim()\r\n const layer1 = cs.getPropertyValue('--dsw-alias-bg-layer-1').trim()\r\n const layer2 = cs.getPropertyValue('--dsw-alias-bg-layer-2').trim()\r\n const layer3 = cs.getPropertyValue('--dsw-alias-bg-layer-3').trim()\r\n if (!base && !layer1 && !layer2 && !layer3) return null\r\n return { base, layer1, layer2, layer3 }\r\n}\r\n\r\n/** The host's own right Sidebar (`PANEL_TOKEN_RULE`) reads this set. */\r\nconst PANEL_LAYER_VARS: LayerVarNames = {\r\n base: '--dsh-any-panel-bg-base',\r\n layer1: '--dsh-any-panel-layer-1',\r\n layer2: '--dsh-any-panel-layer-2',\r\n layer3: '--dsh-any-panel-layer-3',\r\n}\r\n\r\n/** The dsh-better-sidebar workbench (see `PRODUCED_RULE`) reads this set, so the\r\n * two panels can follow two different sliders. */\r\nconst PROD_PANEL_LAYER_VARS: LayerVarNames = {\r\n base: '--dsh-any-prod-panel-bg-base',\r\n layer1: '--dsh-any-prod-panel-layer-1',\r\n layer2: '--dsh-any-prod-panel-layer-2',\r\n layer3: '--dsh-any-prod-panel-layer-3',\r\n}\r\n/** The changed-files card root needs one token only — the RAW `--dsw-alias-bg-layer-1`\r\n * at the produced alpha. It cannot mix on the token itself the way the other\r\n * produced surfaces do, because that name is what the interface card slider\r\n * re-emits globally on `body` (OPACITY_TOKEN_GROUPS), so mixing on it would bind\r\n * one artifact card to two sliders. */\r\nconst PROD_LAYER_VARS: Partial<LayerVarNames> = { layer1: '--dsh-any-prod-layer-1' }\r\n\r\nconst LAYER_KEYS = ['base', 'layer1', 'layer2', 'layer3'] as const\r\n\r\n/** Re-emit the four layer colors at `op` alpha into `names`. The source is the\r\n * plugin palette when a picked color / forced scheme owns the theme, otherwise\r\n * the host's own resolved tokens — a slider only ever supplies the alpha, so the\r\n * colors keep following whichever theme or host skin is active.\r\n *\r\n * Every pass writes SOMETHING: the re-scope rules live in the always-emitted\r\n * stylesheet, and a `var()` naming an unwritten variable makes the surface\r\n * guaranteed-invalid, which drops its background entirely rather than leaving it\r\n * on the host default. */\r\nfunction writeLayerVars(names: Partial<LayerVarNames>, op: number): void {\r\n const palette = paletteTokens()\r\n const src: Partial<LayerVarNames> = palette !== null\r\n ? {\r\n base: palette['--dsw-alias-bg-base'],\r\n layer1: palette['--dsw-alias-bg-layer-1'],\r\n layer2: palette['--dsw-alias-bg-layer-2'],\r\n layer3: palette['--dsw-alias-bg-layer-3'],\r\n }\r\n : readHostLayerTokens() ?? {}\r\n const root = document.documentElement\r\n if (LAYER_KEYS.every(k => !src[k])) {\r\n // Pre-mount, or neither source has shipped the tokens yet: nothing to retint,\r\n // so park the surfaces on transparent until the next apply.\r\n for (const k of LAYER_KEYS) if (names[k]) root.style.setProperty(names[k]!, 'transparent')\r\n return\r\n }\r\n for (const k of LAYER_KEYS) {\r\n const name = names[k]\r\n const v = src[k]\r\n if (name && v) root.style.setProperty(name, toRgba(v, op))\r\n }\r\n}\r\n\r\nexport function applyPanelOverrides(op: number): void {\r\n writeLayerVars(PANEL_LAYER_VARS, op)\r\n}\r\n\r\nfunction applyPanelBlur(px: number): void {\r\n if (px > 0) document.documentElement.style.setProperty('--dsh-any-blur-panel', `blur(${px}px)`)\r\n else document.documentElement.style.removeProperty('--dsh-any-blur-panel')\r\n}\r\n\r\n// Placeholder/hint text inside the composer and the plugin's own input\r\n// surfaces: rendered with the weak caption token (distinct from real input)\r\n// plus italic, so an empty box is never mistaken for typed content. Written\r\n// as a rule so it also covers placeholder text colored by the host's text tier.\r\nexport const PLACEHOLDER_RULE =\r\n '[data-composer-card] textarea::placeholder,' +\r\n '[data-composer-card] input::placeholder,' +\r\n '[data-composer-card] [contenteditable]::placeholder,' +\r\n '[data-cordis-panel] input::placeholder,' +\r\n '[data-cordis-panel] textarea::placeholder,' +\r\n `${COMPOSER_TAKEOVER_EDITOR}::placeholder,` +\r\n '.dab-input::placeholder,' +\r\n '.dab-input textarea::placeholder,' +\r\n '.dab-input input::placeholder' +\r\n '{color:var(--dsh-any-placeholder,var(--dsw-alias-label-caption,#8a8f98))!important;font-style:italic;opacity:.85}'\r\n\r\ntype LayerPrefix = '--dsh-any-bg-settings' | '--dsh-any-traj'\r\n\r\n/** Re-scope one surface group's layer tokens onto plugin-owned variables so a\r\n * dedicated slider owns its alpha (the host has no per-surface opacity). The\r\n * settings group additionally retints its dialog surface variable. Always\r\n * written explicitly — including at 100% — so removing a slider's effect means\r\n * writing 1, not deleting the variable (the style rules below have no fallback\r\n * and would otherwise resolve the body tokens that applyCustomTokens rewrote\r\n * with the homepage card alpha). */\r\nfunction applyLayerOverrides(prefix: LayerPrefix, op: number, surface: boolean): void {\r\n const [h, s, l] = rColor()\r\n const tokens = genTokens(h, s, l, rColorScheme()).tokens\r\n if (surface) {\r\n const surfaceColor = tokens['--dsw-alias-bg-layer-2']\r\n if (surfaceColor !== undefined) {\r\n document.documentElement.style.setProperty(`${prefix}-surface`, toRgba(surfaceColor, op))\r\n }\r\n }\r\n for (const layer of [1, 2, 3] as const) {\r\n const c = tokens[`--dsw-alias-bg-layer-${layer}`]\r\n if (c !== undefined) {\r\n document.documentElement.style.setProperty(`${prefix}-layer-${layer}`, toRgba(c, op))\r\n }\r\n }\r\n}\r\n\r\nexport function applySettingsOverrides(op: number): void {\r\n applyLayerOverrides('--dsh-any-bg-settings', op, true)\r\n}\r\n\r\n// ── Trajectory view opacity ──────────────────────────────────────────────\r\n// The trajectory view's own panels fully cover the root, so retinting only the\r\n// root background is invisible. Re-scope the view root's layer tokens to\r\n// plugin-owned variables so every surface follows the trajectory slider.\r\nexport const TRAJECTORY_STYLE_RULE =\r\n '[data-conversation-composer-overlay]{' +\r\n // No fallback inside var(): a self-referential fallback would be a cycle.\r\n '--dsw-alias-bg-layer-1:var(--dsh-any-traj-layer-1);' +\r\n '--dsw-alias-bg-layer-2:var(--dsh-any-traj-layer-2);' +\r\n '--dsw-alias-bg-layer-3:var(--dsh-any-traj-layer-3)}'\r\n\r\nexport function applyTrajectoryOverrides(op: number): void {\r\n applyLayerOverrides('--dsh-any-traj', op, false)\r\n}\r\n\r\n/** Register a callback fired when a wallpaper-extracted theme color is\r\n * adopted by the auto-adaptation path, so the section can re-register the\r\n * host skin, sync the editor UI and persist the pick (wallpaper.ts cannot\r\n * do those itself — they live in the section). */\r\nlet colorAdoptedListener: ((hsl: [number, number, number]) => void) | null = null\r\nexport function onColorAdopted(cb: (hsl: [number, number, number]) => void): () => void {\r\n colorAdoptedListener = cb\r\n return () => { if (colorAdoptedListener === cb) colorAdoptedListener = null }\r\n}\r\n\r\n/** Apply the theme color: use the saved pick directly, or fall back to\r\n * extracting a dominant color from the current wallpaper. */\r\nexport function applyThemeColor(): void {\r\n if (rHasColor()) {\r\n applyWp()\r\n return\r\n }\r\n const url = rWp()\r\n if (url) {\r\n // Paint the wallpaper immediately — the palette extract decodes the full\r\n // image and would otherwise leave the host's blank background on screen\r\n // for the whole decode. The verdict/skin settle a beat later on re-apply.\r\n applyWp()\r\n // Video mode samples the frame snapshot through the video's own placement\r\n // state; the image slot's framing does not apply to the snapshot.\r\n const st = cfg.backgroundType === 'video' ? rVideoBgState() : rBgState()\r\n void extractWallpaperColor(url, st).then(hsl => {\r\n // A swap during the decode (upload / rotation) points every URL-keyed\r\n // cache at the new picture; only adopt the color when this wallpaper is\r\n // still the active one.\r\n if (hsl && rWp() === url) {\r\n cfg.color = hsl\r\n // The listener runs before applyWp so the freshly registered skin and\r\n // the token pass below describe the same color.\r\n colorAdoptedListener?.(hsl)\r\n // The color changed, so a re-apply is needed for the token pass. When\r\n // the decode yielded nothing (or the wallpaper was swapped out) the\r\n // first applyWp above still describes the screen and a second one\r\n // would only re-do the same work.\r\n applyWp()\r\n }\r\n })\r\n } else {\r\n applyWp()\r\n }\r\n}\r\n\r\n/** Switch the background source type. For generated types a new live canvas is\r\n * attached to the wallpaper layer and a snapshot is kept for the store/preview. */\r\nexport function setBackgroundType(type: BackgroundType): void {\r\n cfg.backgroundType = type\r\n if (type === 'image') {\r\n // Restore the retained image upload and drop the generated brightness verdict.\r\n clearDynamicBg()\r\n setBgDark(null)\r\n setWpUrl(rWpImage())\r\n applyThemeColor()\r\n return\r\n }\r\n if (type === 'video') {\r\n // Restore the retained video upload; the frame snapshot stays the preview URL.\r\n clearDynamicBg()\r\n setBgDark(null)\r\n setWpUrl(null)\r\n applyThemeColor()\r\n return\r\n }\r\n // Keep existing params for this generated type so sub-type switches preserve adjustments.\r\n if (!cfg.generatedBg || cfg.generatedBg.type !== type) {\r\n cfg.generatedBg = defaultParamsFor(type)\r\n }\r\n applyGeneratedBg(cfg.generatedBg)\r\n}\r\n\r\nfunction randomSeed(): number {\r\n return Math.floor(Math.random() * 0x7fffffff)\r\n}\r\n\r\n/** Regenerate the current generated background with a new visual seed while\r\n * preserving the user's scale/intensity/speed/density/preset choices. */\r\nexport function regenerateGeneratedBg(): void {\r\n const params = cfg.generatedBg\r\n // 'video' also carries a generatedBg-less slot: bailing here keeps this from\r\n // racing applyWp's video branch (it would clear the player's state while the\r\n // video branch is setting it up).\r\n if (!params || cfg.backgroundType === 'image' || cfg.backgroundType === 'video') return\r\n cfg.generatedBg = { ...params, seed: randomSeed() }\r\n applyGeneratedBg(cfg.generatedBg)\r\n}\r\n\r\n/** Update a generated background's parameters and re-render. */\r\nexport function updateGeneratedBg(params: GeneratedBgParams): void {\r\n cfg.backgroundType = params.type\r\n cfg.generatedBg = params\r\n applyGeneratedBg(params)\r\n}\r\n\r\nfunction applyGeneratedBg(params: GeneratedBgParams): void {\r\n clearDynamicBg()\r\n clearVideoEl()\r\n ensureWpContainer()\r\n wpController = createDynamicBackground(params)\r\n if (wpEl) {\r\n wpEl.style.backgroundImage = 'none'\r\n wpEl.appendChild(wpController.canvas)\r\n }\r\n // The canvas paints its first frame on the next animation tick; only then is\r\n // the snapshot meaningful. Do NOT refresh the palette here — generated\r\n // backgrounds must not overwrite the user's picked theme color.\r\n requestAnimationFrame(() => {\r\n // Two guards, because clearDynamicBg() stops the OLD controller without\r\n // cancelling its already-scheduled rAF: a rapid regenerate (or a type\r\n // switch) leaves a stale callback whose `wpController` read is the NEW one.\r\n // Snapshotting through the captured `controller` and re-checking identity\r\n // after keeps a dead background's frame from overwriting the live URL.\r\n const controller = wpController\r\n if (controller === null) return\r\n const frame = controller.snapshot()\r\n if (wpController !== controller) return\r\n setWpUrl(frame)\r\n applyWp()\r\n snapshotListener?.()\r\n // One-shot brightness verdict from the captured frame to flip font\r\n // direction; never runs in the animation loop.\r\n setBgDark(null)\r\n void analyzeFrameDark(frame).then(dark => {\r\n if (dark === null || wpController !== controller) return\r\n applyVerdict(dark)\r\n applyCustomTokens(rOps())\r\n })\r\n })\r\n}\r\n\r\n// ── Per-part interface blur ───────────────────────────────────────────────────\r\n// The AppFrame columns use hashed CSS-module classes, so parts are located\r\n// structurally: the shell overlay carries a stable data attribute and the\r\n// sidebar/center/rightbar columns are its preceding siblings.\r\n//\r\n// DSH 0.1.5-rc.1+ has only THREE columns in the frame: [sidebar, center,\r\n// rightbar]. The pre-rc.1 \"details\" column no longer exists — the frame\r\n// tree in 0.1.5-rc.1+ is:\r\n//\r\n// [data-app-frame]? → [sidebarCol] [CenterColumn (wraps main)] [RightbarColumn] [data-shell-overlay]\r\n//\r\n// The rightbar carries the stable `[data-rightbar-col]` marker, so we resolve\r\n// it directly and never let `discoverParts` collapse the right panel into a\r\n// \"details\" column — that mis-target painted the rightbar's surface with the\r\n// main-bg tint and backdrop-filter, making it disappear into the page.\r\n//\r\n// backdrop-filter must NEVER go directly on a host part: it turns the element\r\n// into a containing block for fixed-positioned descendants, which would trap\r\n// the host's settings dialog inside the column. Each blurred part carries an\r\n// isolated ::before underlay holding the backdrop-filter instead.\r\nlet frameEl: HTMLElement | null = null\r\nlet sidebarEl: HTMLElement | null = null\r\nlet centerEl: HTMLElement | null = null\r\nlet rightEl: HTMLElement | null = null\r\n\r\nconst PART_BLUR_CLASS = 'dab-part-blur'\r\nconst PART_UNDERLAY_CLASS = 'dab-part-underlay'\r\n\r\n/** The AppFrame's main-bg clear-out, as a class rather than an inline write.\r\n *\r\n * WHY NOT INLINE (measured on 0.1.7): the frame's own translucent\r\n * `--dsw-alias-bg-base` is what hides the wallpaper, so `applyPartOpacities` has\r\n * to clear it. Written as `frameEl.style.background = 'transparent'` the clear\r\n * survived a settings change but not a sidebar open/close — the host owns that\r\n * element's `style` too (it animates `grid-template-columns`), and while it\r\n * re-asserts its own background the frame snaps back to an opaque\r\n * `rgb(200,207,218)`: wallpaper gone, and every frost on top of it flattened,\r\n * because a backdrop-filter with nothing behind it has nothing to blur. A class\r\n * rule with `!important` sits outside the host's `style` writes entirely, so the\r\n * clear cannot be re-clobbered and there is nothing to re-apply. */\r\nexport const PART_FRAME_CLASS = 'dab-frame-clear'\r\nexport const FRAME_CLEAR_RULE = `.${PART_FRAME_CLASS}{background:transparent!important}`\r\n\r\nconst PART_BLUR_RULE =\r\n // The dot is load-bearing: without `isolation` the host does not create a\r\n // stacking context, so the underlay's `z-index:-1` escapes into the page's and\r\n // the frost paints over the wrong area instead of staying inside the surface.\r\n `.${PART_BLUR_CLASS}{isolation:isolate}` +\r\n // …but that same stacking context is a trap for the host's dialogs: a\r\n // `position:fixed` modal mounted inside a column keeps its z-index LOCAL to the\r\n // column, so a column that paints early (the sidebar) buries a modal that must\r\n // cover the whole page. Verified live against 0.1.7: the settings overlay's\r\n // center hit-tested to the composer card below it, and dropped back onto the\r\n // dialog the moment this exemption was added. Losing the frost for as long as a\r\n // modal is open is the cheaper half of the trade — a dialog you cannot see is a\r\n // dead end. The cost is bounded because the match is transient: with the\r\n // settings view closed the sidebar column holds no `[role=\"dialog\"]` at all,\r\n // which was counted live before this exemption was written.\r\n `.${PART_BLUR_CLASS}:has([role=\"dialog\"]){isolation:auto}` +\r\n `.${PART_UNDERLAY_CLASS}{position:absolute;inset:0;z-index:-1;pointer-events:none;border-radius:inherit;` +\r\n `backdrop-filter:var(--dsh-any-part-blur,none);-webkit-backdrop-filter:var(--dsh-any-part-blur,none)}`\r\n\r\nlet partBlurStyleEl: HTMLStyleElement | null = null\r\n\r\nfunction ensurePartBlurStyle(): void {\r\n if (partBlurStyleEl?.isConnected) return\r\n partBlurStyleEl = document.createElement('style')\r\n partBlurStyleEl.dataset.plugin = 'dsh-any-background-parts'\r\n partBlurStyleEl.textContent = PART_BLUR_RULE\r\n document.head.appendChild(partBlurStyleEl)\r\n}\r\n\r\nfunction discoverParts(): void {\r\n const overlay = document.querySelector<HTMLElement>('[data-shell-overlay]')\r\n if (overlay === null) return\r\n const frame = overlay.parentElement\r\n if (frame === null) return\r\n frameEl = frame\r\n // One pass over frame.children for both anchors: the rightbar is the only\r\n // column with its own stable host marker (its own grid track — never the\r\n // \"details\" twin of center, so it must never take the main-bg tint), and the\r\n // overlay's index anchors the column order behind it.\r\n let overlayIdx = -1\r\n let rightIdx = -1\r\n let right: HTMLElement | null = null\r\n const children = frame.children\r\n for (let i = 0; i < children.length; i++) {\r\n const child = children[i]\r\n if (child === overlay) {\r\n overlayIdx = i\r\n } else if (child instanceof HTMLElement && child.dataset.rightbarCol !== undefined) {\r\n right = child\r\n rightIdx = i\r\n }\r\n }\r\n rightEl = right\r\n // With the host's grid the rightbar sits between center and overlay; the\r\n // indexes are resolved from the children array directly instead of trusting\r\n // the layout to keep that invariant. The else branch covers a future build\r\n // that drops the rightbar entirely (legacy 3-column shape).\r\n if (right !== null) {\r\n sidebarEl = (children[rightIdx - 2] as HTMLElement | undefined) ?? null\r\n centerEl = (children[rightIdx - 1] as HTMLElement | undefined) ?? null\r\n } else {\r\n sidebarEl = (children[overlayIdx - 3] as HTMLElement | undefined) ?? null\r\n centerEl = (children[overlayIdx - 2] as HTMLElement | undefined) ?? null\r\n }\r\n}\r\n\r\nfunction setBlur(el: HTMLElement | null, px: number): void {\r\n if (el === null) return\r\n // Nothing to clear and nothing applied yet: skip the querySelector and the\r\n // style writes. This is the common steady state — every observer tick and\r\n // every applyWp calls setBlur(el, 0) on parts that never had a blur.\r\n if (px === 0 && !el.classList.contains(PART_BLUR_CLASS) && el.getAttribute('data-dab-pos-patched') !== '1') return\r\n const underlay = el.querySelector<HTMLDivElement>(`:scope > .${PART_UNDERLAY_CLASS}`)\r\n if (px > 0) {\r\n ensurePartBlurStyle()\r\n // The underlay is position:absolute and needs a positioned host: static\r\n // columns get relative (a layout no-op for flex items) that is restored on\r\n // clear; parts the host already positions keep their own scheme.\r\n if (!el.classList.contains(PART_BLUR_CLASS) && getComputedStyle(el).position === 'static') {\r\n el.style.position = 'relative'\r\n el.setAttribute('data-dab-pos-patched', '1')\r\n }\r\n el.classList.add(PART_BLUR_CLASS)\r\n if (underlay === null) {\r\n const node = document.createElement('div')\r\n node.className = PART_UNDERLAY_CLASS\r\n el.prepend(node)\r\n }\r\n el.style.setProperty('--dsh-any-part-blur', `blur(${px}px)`)\r\n } else {\r\n el.classList.remove(PART_BLUR_CLASS)\r\n el.style.removeProperty('--dsh-any-part-blur')\r\n underlay?.remove()\r\n if (el.getAttribute('data-dab-pos-patched') === '1') {\r\n el.style.removeProperty('position')\r\n el.removeAttribute('data-dab-pos-patched')\r\n }\r\n }\r\n}\r\n\r\nfunction applySettingsBlur(px: number): void {\r\n if (px > 0) document.documentElement.style.setProperty('--dsh-any-blur-settings', `blur(${px}px)`)\r\n else document.documentElement.style.removeProperty('--dsh-any-blur-settings')\r\n}\r\n\r\n/** Apply the main-background opacity to the center column instead of\r\n * the frame. The frame's translucent bg-base sits UNDER the sidebar, so\r\n * reducing the main-bg opacity stacked a second alpha onto the sidebar; moving\r\n * the alpha onto the column keeps the sidebar owned by its own slider. The\r\n * rightbar (DSH 0.1.5-rc.1+) is intentionally NOT tinted here — it sits on\r\n * its own grid track, paints its own surfaces from its own tokens, and\r\n * inheriting the main-bg tint would blend it into the page and make the\r\n * right panel disappear. */\r\nfunction applyPartOpacities(ops: PartOpacities): void {\r\n const tokens = paletteTokens()\r\n if (tokens === null) return\r\n discoverParts()\r\n if (frameEl === null) return\r\n const base = tokens['--dsw-alias-bg-base']\r\n frameEl.classList.add(PART_FRAME_CLASS)\r\n // An inline clear from an earlier build of this plugin would be a stale\r\n // duplicate of what the class now says; drop it so the class is the only owner.\r\n if (frameEl.style.background !== '') frameEl.style.removeProperty('background')\r\n if (centerEl !== null) centerEl.style.background = base !== undefined ? toRgba(base, ops.bg) : 'transparent'\r\n // Defensive: a previous build (pre-fix) may have left an inline `background`\r\n // on the rightbar — clear it so it stops carrying the main-bg tint.\r\n if (rightEl !== null) rightEl.style.background = ''\r\n}\r\n\r\n/** Blur of the option panels inside the settings dialog (.dab-card), owned by\r\n * the \"dialog option panel\" (card) blur slider. Written as a plugin-owned\r\n * variable consumed by SETTINGS_STYLE_RULE — deliberately NOT applied to the\r\n * homepage center column, which this slider must never touch. */\r\nfunction applyCardPanelsBlur(px: number): void {\r\n if (px > 0) document.documentElement.style.setProperty('--dsh-any-blur-card-panels', `blur(${px}px)`)\r\n else document.documentElement.style.removeProperty('--dsh-any-blur-card-panels')\r\n}\r\n\r\n/** Apply per-part interface blur to the AppFrame columns + settings panel. */\r\nexport function applyPartBlurs(blurs: PartBlurs): void {\r\n discoverParts()\r\n // The bg blur frosts the wallpaper behind the main content column; the\r\n // frame itself stays unblurred so the sidebar is never double-frosted by\r\n // both the bg and sidebar sliders. The rightbar (DSH 0.1.5-rc.1+) is\r\n // intentionally untouched: the host's own panel sits inside the rightbar\r\n // and paints from its own tokens, so a backdrop-filter there would bleed\r\n // the wallpaper into the panel surface and break the focused-tab chrome.\r\n setBlur(frameEl, 0)\r\n setBlur(sidebarEl, blurs.sidebar)\r\n setBlur(centerEl, blurs.bg)\r\n setBlur(rightEl, 0)\r\n applyBgBlurGlobal(blurs.bg)\r\n applyCardPanelsBlur(blurs.card)\r\n applySettingsBlur(blurs.settings)\r\n applyInputBlur(blurs.input)\r\n applyPanelBlur(blurs.panel)\r\n applyProduced()\r\n applyHeaderPopovers()\r\n applyViewCards()\r\n}\r\n\r\n/** Produced/artifact surfaces (conversation code blocks + their banner +\r\n * inline code chips + composer chips + the dsh-better-sidebar workbench):\r\n * re-write the root blur and the alpha percentage consumed by PRODUCED_RULE. The\r\n * percentage is an alpha for the surface's OWN host color — 1 (100%) reproduces\r\n * the untouched host look and lowering it fades exactly that color out — so no\r\n * palette sampling is involved and the surfaces keep following the active\r\n * theme/wallpaper color on their own. Two surfaces are the exception: the\r\n * workbench reads a whole set of layer tokens rather than one color, and the\r\n * changed-files card reads a token the card slider owns globally — both take their\r\n * alpha from `writeLayerVars` instead of mixing on the live token. */\r\nexport function applyProduced(): void {\r\n const px = rBlurs().produced\r\n const root = document.documentElement\r\n if (px > 0) root.style.setProperty('--dsh-any-blur-prod', `blur(${px}px)`)\r\n else root.style.removeProperty('--dsh-any-blur-prod')\r\n let opacity = rProducedOpacity()\r\n if (opacity < 0) opacity = 0\r\n if (opacity > 1) opacity = 1\r\n root.style.setProperty('--dsh-any-prod-pct', `${Math.round(opacity * 100)}%`)\r\n writeLayerVars(PROD_PANEL_LAYER_VARS, opacity)\r\n writeLayerVars(PROD_LAYER_VARS, opacity)\r\n}\r\n\r\n/** Live per-part blur update during slider drag (no full re-apply). */\r\nexport function setPartBlur(part: keyof PartBlurs, v: number): void {\r\n if (part === 'settings') { applySettingsBlur(v); return }\r\n if (part === 'card') { applyCardPanelsBlur(v); return }\r\n if (part === 'input') { applyInputBlur(v); return }\r\n if (part === 'panel') { applyPanelBlur(v); return }\r\n if (part === 'produced') { applyProduced(); return }\r\n if (part === 'header') { applyHeaderPopovers(); return }\r\n if (part === 'chat' || part === 'trajectory') { applyViewCards(); return }\r\n discoverParts()\r\n if (part === 'bg') { setBlur(centerEl, v); applyBgBlurGlobal(v) }\r\n else setBlur(sidebarEl, v)\r\n}\r\n\r\n// ── Conversation view treatments ────────────────────────────────────\r\n// The chat message column is styled as a real card (layer-1 surface + border +\r\n// 16px radius + 18px padding); the trajectory view gets NO card decoration —\r\n// its own panels fully cover the view root, so its opacity slider re-scopes the\r\n// layer tokens inside the view and its blur frosts the backdrop through the\r\n// standard root underlay.\r\n//\r\n// Host structure (deepseek-harness ui-conversation / ui-trajectory):\r\n// ConversationRoot\r\n// header — title + tabs, OUTSIDE the scrollport\r\n// [data-conversation-scroll] — the single scrollport\r\n// [data-chat-flow] ← chat column (flow content, NOT scrollable)\r\n// [data-conversation-composer-overlay] ← trajectory view root\r\n// [data-composer-seat] — sticky composer, a sibling\r\n// The input is sticky inside the same scrollport, so the stable host markers\r\n// are used; generic heuristics remain as a chat fallback for marker-less hosts.\r\n//\r\n// Cards are ALWAYS styled once their host exists — sliders at zero only turn\r\n// surface/border transparent, so the layout never reflows and the view cannot\r\n// jump when a slider leaves zero. Removal happens only at plugin teardown.\r\ninterface ViewCardSpec {\r\n sel: string\r\n mark: string\r\n /** Dataset key prefix holding the stashed pre-card inline values. */\r\n prev: string\r\n opacity: () => number\r\n blur: () => number\r\n /** Generic heuristic fallback (chat card only, hosts without the marker). */\r\n fallback?: boolean\r\n /** No card decoration — surfaces follow scoped layer tokens; only the blur\r\n * underlay is attached to the host element. */\r\n plain?: boolean\r\n}\r\n\r\nconst VIEW_CARDS: ViewCardSpec[] = [\r\n { sel: '[data-chat-flow]', mark: 'data-dab-chat-card', prev: 'dabChatPrev', opacity: rChatTextOpacity, blur: () => rBlurs().chat, fallback: true },\r\n { sel: '[data-conversation-composer-overlay]', mark: 'data-dab-traj-card', prev: 'dabTrajPrev', opacity: rTrajectoryOpacity, blur: () => rBlurs().trajectory, plain: true },\r\n]\r\n\r\nconst viewTargets: Array<HTMLElement | null> = VIEW_CARDS.map(() => null)\r\n\r\n/** View specs whose real host marker has been seen at least once. Until a\r\n * marker is seen, its absence is ambiguous — \"that view is not mounted\" or\r\n * \"this build has no such marker, keep running the generic fallback\" — and the\r\n * pass has to keep probing. Once seen, absence can only mean the former, so the\r\n * pass may be skipped.\r\n *\r\n * This matters because the two specs are two different MAIN VIEWS and only one\r\n * of them is mounted at a time (the host renders the main slot for the active\r\n * panel id, keyed by `entryKey` — see AppFrame's MainPanel). So \"every surface\r\n * present\" is never true during a normal session, and an all-or-nothing gate on\r\n * it silently never engages: that is exactly how the previous version of this\r\n * observer ended up running the full pass on every animation frame while\r\n * tokens streamed. */\r\nconst markerSeen = new Set<number>()\r\n\r\n/** Resolve just the stable host markers for the view specs — one querySelector\r\n * each, no fallback heuristics. Cheap enough to run on every coalesced burst,\r\n * and enough to notice a view mounting/unmounting. */\r\nfunction probeViewMarkers(): (HTMLElement | null)[] {\r\n const center = centerEl\r\n if (center === null || !document.body.contains(center)) return VIEW_CARDS.map(() => null)\r\n return VIEW_CARDS.map(spec => center.querySelector<HTMLElement>(spec.sel))\r\n}\r\n\r\n/** Whether the pass must run regardless of the value/identity signature. */\r\nfunction needsPartsPass(markers: (HTMLElement | null)[]): boolean {\r\n // Columns missing: the pass is what discovers them.\r\n if (!columnsPresent()) return true\r\n // A mounted view whose marker moved (appeared, or was replaced by a fresh\r\n // element) has to be re-styled — the identity gate below cannot see it,\r\n // because an undiscovered target is still null in viewTargets.\r\n if (markers.some((el, i) => el !== null && el !== viewTargets[i])) return true\r\n // A spec with a generic fallback whose marker has never been seen on this\r\n // host: the pass performs that resolution, so it cannot be skipped.\r\n return VIEW_CARDS.some((spec, i) => spec.fallback === true && markers[i] === null && !markerSeen.has(i))\r\n}\r\n\r\nfunction isScrollableY(el: HTMLElement): boolean {\r\n const oy = getComputedStyle(el).overflowY\r\n // 'overlay' covers Chromium's non-standard overflow value.\r\n return oy === 'auto' || oy === 'scroll' || oy === 'overlay'\r\n}\r\n\r\n/** Whether the subtree hosts the chat input (textarea / contenteditable /\r\n * textbox role) — used to keep the card off the input row. */\r\nfunction containsChatEditor(el: HTMLElement): boolean {\r\n return el.querySelector('textarea,[contenteditable=\"true\"],[contenteditable=\"\"],[contenteditable=\"plaintext-only\"],[role=\"textbox\"]') !== null\r\n}\r\n\r\n/** Walk down from a coarse candidate toward the actual message column: stop\r\n * at a scroll container (the card surface must stay pinned to the scroll\r\n * port); while the chat input lives inside, descend into the tallest child that\r\n * does NOT contain it (the header row is short, the input row holds the\r\n * editor); otherwise peel wrappers dominated (>= 85%) by a single child so\r\n * tab bars / titles stay outside the card. */\r\nfunction refineMessageColumn(start: HTMLElement): HTMLElement {\r\n let cur = start\r\n for (let depth = 0; depth < 10; depth++) {\r\n if (isScrollableY(cur)) break\r\n const kids = Array.from(cur.children).filter((k): k is HTMLElement => k instanceof HTMLElement)\r\n if (kids.length === 0) break\r\n const tallest = kids.reduce((a, b) => (b.clientHeight > a.clientHeight ? b : a))\r\n if (containsChatEditor(cur)) {\r\n const candidates = kids.filter(k => !containsChatEditor(k) && k.clientHeight >= cur.clientHeight * 0.4)\r\n if (candidates.length === 0) break\r\n cur = candidates.reduce((a, b) => (b.clientHeight > a.clientHeight ? b : a))\r\n continue\r\n }\r\n if (kids.length > 1 && tallest.clientHeight >= cur.clientHeight * 0.85) { cur = tallest; continue }\r\n break\r\n }\r\n return cur\r\n}\r\n\r\nfunction discoverViewTarget(idx: number, spec: ViewCardSpec): HTMLElement | null {\r\n if (centerEl === null || !document.body.contains(centerEl)) { viewTargets[idx] = null; return null }\r\n // The host marker always wins over a cached fallback (the view may not be\r\n // mounted yet when the plugin applies early).\r\n const marked = centerEl.querySelector<HTMLElement>(spec.sel)\r\n const cached = viewTargets[idx]\r\n if (marked !== null) {\r\n // This host does expose the marker, so from now on its absence means \"that\r\n // view is not the active one\" — see the note on markerSeen.\r\n markerSeen.add(idx)\r\n if (cached !== null && cached !== marked) { setBlur(cached, 0); restoreCardHost(cached, spec.mark, spec.prev, spec.plain === true) }\r\n viewTargets[idx] = marked\r\n return marked\r\n }\r\n if (cached !== null && centerEl.contains(cached)) return cached\r\n viewTargets[idx] = null\r\n if (spec.fallback !== true) return null\r\n // The fallback may only refine a conversation that is ALREADY there; it must\r\n // never invent one. With no conversation marker in the column the chat view is\r\n // simply not mounted — the settings view owns the column then, and its page is\r\n // routinely the column's only tall element, so the heuristic below would dress\r\n // that page up as a chat card and hang a 15px frost over the whole window.\r\n // Every release in the supported range emits at least one of these four.\r\n if (\r\n centerEl.querySelector(\r\n '[data-chat-flow],[data-conversation-scroll],[data-composer-seat],[data-conversation-composer-overlay]'\r\n ) === null\r\n ) return null\r\n // On the harness, an absent [data-chat-flow] just means the chat view is not\r\n // mounted (hero phase, trajectory tab) — settling on the whole scrollport\r\n // there would wrap the entire page in the card.\r\n if (centerEl.querySelector('[data-conversation-scroll]') !== null) return null\r\n // Marker-less hosts keep their layout until a slider moves.\r\n if (spec.opacity() <= 0 && spec.blur() <= 0) return null\r\n // Generic fallbacks: the largest vertically scrollable element inside the\r\n // column, or the tallest direct child when the host virtualises scrolling.\r\n let best: HTMLElement | null = null\r\n let bestArea = 0\r\n for (const el of Array.from(centerEl.querySelectorAll<HTMLElement>('*'))) {\r\n if (!isScrollableY(el)) continue\r\n if (el.clientHeight < centerEl.clientHeight * 0.35) continue\r\n const area = el.clientWidth * el.clientHeight\r\n if (area > bestArea) { bestArea = area; best = el }\r\n }\r\n if (best === null) {\r\n for (const el of Array.from(centerEl.children)) {\r\n if (!(el instanceof HTMLElement)) continue\r\n if (el.clientHeight < centerEl.clientHeight * 0.5) continue\r\n if (el.clientHeight > (best?.clientHeight ?? 0)) best = el\r\n }\r\n }\r\n // A settings-dialog surface is never the chat card: the dialog owns its own\r\n // look through SETTINGS_STYLE_RULE, and while it is open with no conversation\r\n // mounted its page IS the column's largest scroller, so the geometry above\r\n // would wrap, say, the 「插件」 page in card chrome and hang a frost underlay on\r\n // it. Tested on the picked element rather than on the column so it also holds\r\n // when the dialog is portal'd and only its content renders inside the column.\r\n if (best !== null && best.closest(SETTINGS_PANEL_SEL) !== null) best = null\r\n // Coarse candidates are narrowed to the message column itself.\r\n const refined = best !== null ? refineMessageColumn(best) : null\r\n viewTargets[idx] = refined\r\n return refined\r\n}\r\n\r\n/** Stash the host's own inline values so teardown restores them exactly.\r\n * Plain views only get a background override, so only that is stashed. */\r\nfunction stashCardPrev(el: HTMLElement, prev: string, plain: boolean): void {\r\n const ds = el.dataset as Record<string, string | undefined>\r\n ds[prev + 'Bg'] = el.style.getPropertyValue('background')\r\n if (plain) return\r\n ds[prev + 'BoxSizing'] = el.style.getPropertyValue('box-sizing')\r\n ds[prev + 'Border'] = el.style.getPropertyValue('border')\r\n ds[prev + 'Radius'] = el.style.getPropertyValue('border-radius')\r\n ds[prev + 'Padding'] = el.style.getPropertyValue('padding')\r\n}\r\n\r\n/** Undo the inline styling, restoring the host's previous inline values. */\r\nfunction restoreCardHost(el: HTMLElement, mark: string, prev: string, plain: boolean): void {\r\n if (!el.hasAttribute(mark)) return\r\n const ds = el.dataset as Record<string, string | undefined>\r\n const restore = (prop: string, v: string | undefined): void => {\r\n if (v !== undefined && v !== '') el.style.setProperty(prop, v)\r\n else el.style.removeProperty(prop)\r\n }\r\n restore('background', ds[prev + 'Bg'])\r\n if (!plain) {\r\n restore('box-sizing', ds[prev + 'BoxSizing'])\r\n restore('border', ds[prev + 'Border'])\r\n restore('border-radius', ds[prev + 'Radius'])\r\n restore('padding', ds[prev + 'Padding'])\r\n delete ds[prev + 'BoxSizing']; delete ds[prev + 'Border']; delete ds[prev + 'Radius']; delete ds[prev + 'Padding']\r\n }\r\n delete ds[prev + 'Bg']\r\n el.removeAttribute(mark)\r\n}\r\n\r\n/** Teardown only: strip every view treatment and hand the hosts back untouched. */\r\nfunction removeViewCards(): void {\r\n VIEW_CARDS.forEach((spec, i) => {\r\n const el = viewTargets[i]\r\n if (el !== null) { setBlur(el, 0); restoreCardHost(el, spec.mark, spec.prev, spec.plain === true) }\r\n viewTargets[i] = null\r\n })\r\n}\r\n\r\n// ── Wide markdown tables ──────────────────────────────────────────────────────\r\n// DSH intentionally lets `.md-table-wide` bleed outside the text column (a\r\n// negative --dsh-table-lead margin + max-width:none, set by a host rule like\r\n// `.Sxvs8a_body .md-table-wide`; the prefix is a build-time hash class). That\r\n// bleed only becomes visible once the chat surface gains a visible border, i.e.\r\n// when the chat region opacity or blur is non-zero (see borderAlpha in\r\n// applyViewCards). Under that same condition, pull the table back inside the\r\n// column and let it scroll horizontally. The stable `.md-table-wide` class is\r\n// targeted with !important so the fix survives DSH's changing hash prefixes.\r\n\r\nconst TABLE_FIX_RULE = [\r\n '.md-table-wide {',\r\n ' --dsh-table-spare: 0px !important;',\r\n ' --dsh-table-lead: 0px !important;',\r\n ' box-sizing: border-box !important;',\r\n ' width: 100% !important;',\r\n ' max-width: 100% !important;',\r\n ' margin-left: 0 !important;',\r\n ' padding-left: 0 !important;',\r\n ' padding-bottom: 0 !important;',\r\n ' overflow-x: auto !important;',\r\n '}',\r\n].join('\\n')\r\nlet tableFixStyleEl: HTMLStyleElement | null = null\r\n\r\n/** Toggle the wide-table clamp according to the chat region's opacity & blur. */\r\nfunction syncTableFix(): void {\r\n const needed = rChatTextOpacity() > 0 || rBlurs().chat > 0\r\n if (!needed) {\r\n if (tableFixStyleEl !== null) { tableFixStyleEl.remove(); tableFixStyleEl = null }\r\n return\r\n }\r\n if (tableFixStyleEl === null) {\r\n tableFixStyleEl = document.createElement('style')\r\n tableFixStyleEl.dataset.plugin = 'dsh-any-background-table-fix'\r\n tableFixStyleEl.textContent = TABLE_FIX_RULE\r\n }\r\n if (!tableFixStyleEl.isConnected) document.head.appendChild(tableFixStyleEl)\r\n}\r\n\r\n/** Re-derive the conversation view cards from the current config. Cheap\r\n * enough for live slider drags; the card structure is applied unconditionally\r\n * once the host exists so the layout never reflows when a slider leaves zero. */\r\nexport function applyViewCards(): void {\r\n discoverParts()\r\n if (centerEl === null) return\r\n const [h, s, l] = rColor()\r\n const surface = genTokens(h, s, l, rColorScheme()).tokens['--dsw-alias-bg-layer-1']\r\n VIEW_CARDS.forEach((spec, i) => {\r\n const target = discoverViewTarget(i, spec)\r\n if (target === null) return\r\n const plain = spec.plain === true\r\n const opacity = spec.opacity()\r\n const blurPx = spec.blur()\r\n if (!plain) {\r\n if (!target.hasAttribute(spec.mark)) stashCardPrev(target, spec.prev, false)\r\n // Mirrors .dab-card (layer-1 background, border, 16px radius, 18px\r\n // padding), written inline so it wins over host stylesheets; the opacity\r\n // slider drives surface alpha and fades the border with it.\r\n const borderAlpha = opacity > 0 ? Math.min(1, opacity * 1.5) : (blurPx > 0 ? 0.35 : 0)\r\n target.style.background = surface !== undefined ? toRgba(surface, opacity) : 'transparent'\r\n target.style.border = surface !== undefined ? `1px solid ${toRgba(surface, borderAlpha)}` : '1px solid transparent'\r\n target.style.borderRadius = '16px'\r\n target.style.padding = '18px'\r\n // DSH has no global box-sizing reset; under content-box the padding +\r\n // border above would push the card past its width:100% — overflowing\r\n // narrow screens and breaking margin:0 auto centering.\r\n target.style.boxSizing = 'border-box'\r\n }\r\n // Plain views write no inline styles — only the blur underlay is hosted here.\r\n target.setAttribute(spec.mark, '1')\r\n setBlur(target, blurPx)\r\n })\r\n syncTableFix()\r\n}\r\n\r\nlet partsObserver: MutationObserver | null = null\r\nlet partsApplyRaf = 0\r\n/** Signature of the last blur+opacity pass we actually wrote to the DOM. */\r\nlet appliedPartsKey = ''\r\n/** The surfaces the last pass styled, compared BY IDENTITY: the host can swap\r\n * a view element for a fresh one while the slider values stay identical, and\r\n * the value signature alone would then skip the pass and leave the new view\r\n * unstyled until a slider moves. */\r\nlet appliedTargets: (HTMLElement | null)[] = []\r\n\r\n/** The four frame columns are mounted and still attached. These are the frame's\r\n * own children (see the host's AppFrame: sidebar / center / rightbar carrying\r\n * `data-rightbar-col` / the overlay), so they exist as soon as the shell does —\r\n * unlike the per-view cards below, which come and go with the active view. */\r\nfunction columnsPresent(): boolean {\r\n return frameEl !== null && sidebarEl !== null && centerEl !== null && rightEl !== null\r\n && document.body.contains(frameEl) && document.body.contains(centerEl)\r\n}\r\n\r\n/** Snapshot of every surface the pass would style, for the identity check. */\r\nfunction targetsNow(): (HTMLElement | null)[] {\r\n return [frameEl, sidebarEl, centerEl, rightEl, ...viewTargets]\r\n}\r\n\r\n/** Watch for the AppFrame mounting so persisted blurs land even when the shell\r\n * renders after this plugin's apply. */\r\nexport function watchParts(): void {\r\n if (partsObserver !== null || typeof MutationObserver === 'undefined') return\r\n partsObserver = new MutationObserver(() => {\r\n // The observer cannot tell whether a mutation touched our surfaces, so\r\n // without a gate every childList change on body — streaming tokens,\r\n // keystrokes — re-runs the full blur+opacity pass. Coalesce a burst into one\r\n // animation frame, then skip it when it cannot change anything.\r\n if (partsApplyRaf !== 0) return\r\n partsApplyRaf = requestAnimationFrame(() => {\r\n partsApplyRaf = 0\r\n const blurs = rBlurs()\r\n const ops = rOps()\r\n const key = JSON.stringify([blurs, ops])\r\n const markers = probeViewMarkers()\r\n if (!needsPartsPass(markers) && key === appliedPartsKey\r\n && !targetsNow().some((el, i) => el !== appliedTargets[i])) return\r\n applyPartBlurs(blurs)\r\n applyPartOpacities(ops)\r\n // Snapshot AFTER the pass, not before: discovery happens inside it, and\r\n // comparing the next tick against a pre-discovery snapshot would make that\r\n // tick re-run the whole pass for nothing.\r\n appliedPartsKey = key\r\n appliedTargets = targetsNow()\r\n })\r\n })\r\n partsObserver.observe(document.body, { childList: true, subtree: true })\r\n}\r\n\r\nexport function stopWatchingParts(): void {\r\n partsObserver?.disconnect()\r\n partsObserver = null\r\n if (partsApplyRaf !== 0) { cancelAnimationFrame(partsApplyRaf); partsApplyRaf = 0 }\r\n appliedPartsKey = ''\r\n appliedTargets = []\r\n // Re-probe on the next enable: a marker seen before the teardown is no longer\r\n // evidence about the DOM at hand.\r\n markerSeen.clear()\r\n}\r\n\r\n// ── Theme-reset watchdog ──────────────────────────────────────────────────\r\n// The host re-asserts its own :root/body scheme rules on mount, on settings\r\n// adoption and after the plugin's startup assertion, toggling the\r\n// `data-ds-dark-theme` attribute off / to a host value — which would paint a\r\n// frame of light surfaces. Watch that flag and, whenever the plugin's own\r\n// value disappears, re-set it and re-emit the token stylesheet within the same\r\n// frame. The guard stops feedback: once our mark is present the handler\r\n// returns, so our own re-assertion cannot re-trigger.\r\nlet themeObserver: MutationObserver | null = null\r\nlet themeRaf = 0\r\n\r\nfunction reassertScheme(): void {\r\n const dark = rScheme() === 'dark'\r\n if (dark) document.body.setAttribute('data-ds-dark-theme', 'dsh-any-background')\r\n else document.body.removeAttribute('data-ds-dark-theme')\r\n applyCustomTokens(rOps())\r\n}\r\n\r\n/** Re-assert the plugin's forced scheme whenever the host strips it, so a\r\n * refresh / cold-load / set-change never flashes a light frame. Returns a\r\n * disposer for teardown. */\r\nexport function watchThemeResets(): () => void {\r\n if (themeObserver !== null || typeof MutationObserver === 'undefined') return () => undefined\r\n themeObserver = new MutationObserver(() => {\r\n if (document.body.getAttribute('data-ds-dark-theme') === 'dsh-any-background') return\r\n if (!(rHasColor() || rBgDark() !== null || rSchemeOverride() !== 'auto')) return\r\n if (themeRaf !== 0) return\r\n themeRaf = requestAnimationFrame(() => {\r\n themeRaf = 0\r\n if (document.body.getAttribute('data-ds-dark-theme') === 'dsh-any-background') return\r\n reassertScheme()\r\n })\r\n })\r\n themeObserver.observe(document.body, { attributes: true, attributeFilter: ['data-ds-dark-theme'] })\r\n themeObserver.observe(document.documentElement, { attributes: true, attributeFilter: ['data-ds-dark-theme'] })\r\n return () => {\r\n themeObserver?.disconnect()\r\n themeObserver = null\r\n }\r\n}\r\n\r\nfunction ensureWpContainer(): void {\r\n if (!wpEl || !document.body.contains(wpEl)) {\r\n wpEl = document.createElement('div')\r\n wpEl.style.cssText = 'position:fixed;inset:0;z-index:-1;pointer-events:none;overflow:hidden;'\r\n document.body.prepend(wpEl)\r\n }\r\n}\r\n\r\nfunction clearVideoEl(): void {\r\n if (videoEl === null) return\r\n videoEl.pause()\r\n videoEl.removeAttribute('src')\r\n videoEl.load()\r\n videoEl.remove()\r\n videoEl = null\r\n}\r\n\r\n/** Intrinsic-size cache for the center mode (native pixels of the current image). */\r\nlet imgNat: { url: string; w: number; h: number } | null = null\r\nfunction imageNatSize(url: string, cb: (w: number, h: number) => void): void {\r\n if (imgNat !== null && imgNat.url === url) { cb(imgNat.w, imgNat.h); return }\r\n void loadImage(url).then(img => {\r\n if (!img) { cb(0, 0); return }\r\n imgNat = { url, w: img.naturalWidth, h: img.naturalHeight }\r\n cb(img.naturalWidth, img.naturalHeight)\r\n })\r\n}\r\n\r\n// ── Drag-time wallpaper downscaling ──────────────────────────────────────────\r\n// Repainting translucent surfaces over a full-resolution wallpaper is expensive\r\n// (proportional to the image's pixel area, worse under backdrop blur). During a\r\n// slider drag we swap the layer's background-image to a bounded-size JPEG copy,\r\n// slashing that per-frame raster cost; the full-res image is restored on release\r\n// and stays browser-cached, so the swap is cheap. Precomputed after each image\r\n// apply so the first drag needs no decode hitch.\r\nconst DRAG_MAX_SIDE = 720\r\n\r\nlet lowResUrl: string | null = null\r\nlet lowResFor = ''\r\nlet dragLow = false\r\n\r\nfunction captureLowRes(url: string, cb: (low: string | null) => void): void {\r\n if (lowResFor === url) { cb(lowResUrl); return }\r\n void loadImage(url).then(img => {\r\n if (!img) { cb(null); return }\r\n const k = Math.min(1, DRAG_MAX_SIDE / Math.max(img.naturalWidth, img.naturalHeight))\r\n if (k >= 1) { lowResFor = url; lowResUrl = null; cb(null); return }\r\n const c = document.createElement('canvas')\r\n c.width = Math.max(1, Math.round(img.naturalWidth * k))\r\n c.height = Math.max(1, Math.round(img.naturalHeight * k))\r\n const g = c.getContext('2d')\r\n if (!g) { lowResFor = url; lowResUrl = null; cb(null); return }\r\n g.drawImage(img, 0, 0, c.width, c.height)\r\n const low = c.toDataURL('image/jpeg', 0.85)\r\n lowResFor = url; lowResUrl = low\r\n cb(low)\r\n })\r\n}\r\n\r\nfunction setDragLow(on: boolean): void {\r\n if (cfg.backgroundType !== 'image' || on === dragLow || !wpEl) return\r\n const full = rWpImage()\r\n if (!full) return\r\n if (on) {\r\n dragLow = true\r\n captureLowRes(full, low => {\r\n if (!dragLow || !wpEl || low === null) return\r\n if (wpEl.style.backgroundImage !== `url(\"${low}\")`) wpEl.style.backgroundImage = `url(\"${low}\")`\r\n })\r\n } else {\r\n dragLow = false\r\n if (wpEl.style.backgroundImage !== `url(\"${full}\")`) wpEl.style.backgroundImage = `url(\"${full}\")`\r\n }\r\n}\r\n\r\n/** While any range slider in the app is being dragged, run the wallpaper at\r\n * reduced resolution; restore on release. Returns a disposer for teardown. */\r\nexport function watchWallpaperDragQuality(): () => void {\r\n const isRange = (t: EventTarget | null): boolean =>\r\n t instanceof HTMLInputElement && t.type === 'range'\r\n const down = (e: PointerEvent): void => { if (isRange(e.target)) setDragLow(true) }\r\n const up = (): void => { if (dragLow) setDragLow(false) }\r\n window.addEventListener('pointerdown', down, true)\r\n window.addEventListener('pointerup', up, true)\r\n window.addEventListener('pointercancel', up, true)\r\n return () => {\r\n window.removeEventListener('pointerdown', down, true)\r\n window.removeEventListener('pointerup', up, true)\r\n window.removeEventListener('pointercancel', up, true)\r\n if (dragLow) setDragLow(false)\r\n }\r\n}\r\n\r\n// ── Wallpaper brightness verdict ─────────────────────────────────────────────\r\n// Image/video wallpapers get the same one-shot brightness verdict generated\r\n// backgrounds analyze from their captured frame: decoded once per URL (cached),\r\n// it drives the label direction and the auto scheme, so a light wallpaper gets\r\n// dark fonts even when no theme color is picked and the host preference is dark.\r\nlet wpVerdict: { url: string; dark: boolean } | null = null\r\nlet verdictListener: (() => void) | null = null\r\n// Monotonic guard for the async frame analysis: a stale result (the wallpaper\r\n// changed while the frame was decoding) must never overwrite the current\r\n// verdict. applyGeneratedBg guards with its own controller comparison; the\r\n// image/video path needs the same protection.\r\nlet verdictGen = 0\r\n\r\n/** Register a callback fired when the background brightness verdict CHANGES\r\n * (a new wallpaper was analyzed, a generated bg regenerated), so the skin can\r\n * be re-registered through the host theme service. */\r\nexport function onVerdictApplied(cb: () => void): () => void {\r\n verdictListener = cb\r\n return () => { if (verdictListener === cb) verdictListener = null }\r\n}\r\n\r\nfunction applyVerdict(dark: boolean | null): void {\r\n if (rBgDark() === dark) return\r\n setBgDark(dark)\r\n if (dark !== null) verdictListener?.()\r\n}\r\n\r\nfunction updateWpVerdict(url: string | null): void {\r\n const gen = ++verdictGen\r\n if (url === null) { applyVerdict(null); return }\r\n if (wpVerdict !== null && wpVerdict.url === url) { applyVerdict(wpVerdict.dark); return }\r\n void analyzeFrameDark(url).then(dark => {\r\n if (dark === null || gen !== verdictGen) return\r\n wpVerdict = { url, dark }\r\n applyVerdict(dark)\r\n applyCustomTokens(rOps())\r\n })\r\n}\r\n\r\nfunction applyImageWp(url: string): void {\r\n clearDynamicBg()\r\n clearVideoEl()\r\n ensureWpContainer()\r\n const bg = rBgState()\r\n const mode = rBgMode()\r\n const next = `url(\"${url}\")`\r\n // Skip re-setting the same data URL — re-decoding it flashes the wallpaper\r\n // blank for a frame on boot re-applies.\r\n if (wpEl!.style.backgroundImage !== next) {\r\n wpEl!.style.backgroundImage = next\r\n }\r\n if (mode === 'fit') {\r\n wpEl!.style.backgroundRepeat = 'no-repeat'\r\n if (bg.iw > 0) {\r\n // Contain-fit at zoom with the image center pinned to the committed\r\n // fractional viewport point, so the framed region survives viewport changes.\r\n const fit = Math.min(window.innerWidth / bg.iw, window.innerHeight / bg.ih)\r\n const w = bg.iw * fit * bg.zoom\r\n const h = bg.ih * fit * bg.zoom\r\n wpEl!.style.backgroundSize = `${w}px ${h}px`\r\n wpEl!.style.backgroundPosition = `${bg.x * window.innerWidth - w / 2}px ${bg.y * window.innerHeight - h / 2}px`\r\n } else {\r\n // Fresh image: match the editor's initial centered contain view.\r\n wpEl!.style.backgroundSize = 'contain'\r\n wpEl!.style.backgroundPosition = 'center'\r\n }\r\n } else if (mode === 'fill') {\r\n wpEl!.style.backgroundRepeat = 'no-repeat'\r\n wpEl!.style.backgroundSize = 'cover'\r\n wpEl!.style.backgroundPosition = 'center'\r\n } else if (mode === 'stretch') {\r\n wpEl!.style.backgroundRepeat = 'no-repeat'\r\n wpEl!.style.backgroundSize = '100% 100%'\r\n wpEl!.style.backgroundPosition = 'center'\r\n } else if (mode === 'tile') {\r\n wpEl!.style.backgroundRepeat = 'repeat'\r\n // background-size:auto resolves the intrinsic size per tile.\r\n wpEl!.style.backgroundSize = 'auto'\r\n wpEl!.style.backgroundPosition = '0px 0px'\r\n } else {\r\n // Center: native size, centered. The intrinsic size needs an async decode;\r\n // 'contain' keeps a sensible frame until it lands.\r\n wpEl!.style.backgroundRepeat = 'no-repeat'\r\n wpEl!.style.backgroundSize = 'contain'\r\n wpEl!.style.backgroundPosition = 'center'\r\n imageNatSize(url, (w, h) => {\r\n if (!wpEl || wpEl.style.backgroundImage !== next || rBgMode() !== 'center') return\r\n if (w > 0 && h > 0) {\r\n wpEl.style.backgroundSize = `${w}px ${h}px`\r\n wpEl.style.backgroundPosition = 'center'\r\n }\r\n })\r\n }\r\n // Precompute the drag-time downscaled copy now so the first drag swaps without\r\n // a decode hitch (the original is already loaded, so this hits the cache).\r\n captureLowRes(url, () => undefined)\r\n applyWpEffects()\r\n updateWpVerdict(url)\r\n}\r\n\r\n/** Video wallpaper: a muted looping <video> inside the wallpaper layer.\r\n * Placement modes map onto object-fit (tile has no video equivalent and\r\n * falls back to cover). */\r\nfunction applyVideoWp(url: string): void {\r\n clearDynamicBg()\r\n ensureWpContainer()\r\n if (wpEl!.style.backgroundImage !== 'none') wpEl!.style.backgroundImage = 'none'\r\n if (videoEl === null || !videoEl.isConnected) {\r\n videoEl = document.createElement('video')\r\n videoEl.muted = true\r\n videoEl.loop = true\r\n videoEl.autoplay = true\r\n videoEl.playsInline = true\r\n videoEl.preload = 'auto'\r\n videoEl.setAttribute('playsinline', '')\r\n videoEl.style.cssText = 'position:absolute;inset:0;width:100%;height:100%;object-position:center;'\r\n // Attach before loading so the element is in the document when play()\r\n // resolves; a detached video can defer its first rendered frame.\r\n wpEl!.appendChild(videoEl)\r\n videoEl.setAttribute('src', url)\r\n void videoEl.play().catch(() => undefined)\r\n } else if (videoEl.getAttribute('src') !== url) {\r\n // Compare the attribute, not videoEl.src: the property getter resolves to\r\n // an absolute URL that would never match the relative serve URL and would\r\n // restart playback on every re-apply.\r\n videoEl.setAttribute('src', url)\r\n void videoEl.play().catch(() => undefined)\r\n }\r\n const mode = rBgMode()\r\n const bg = rVideoBgState()\r\n if (mode === 'fit' && bg.iw > 0) {\r\n // Editor-committed box at contain-fit scale × zoom, centered on the\r\n // fractional point; object-fit:fill stretches the frame into the box\r\n // (same aspect ratio, so nothing distorts).\r\n const fit = Math.min(window.innerWidth / bg.iw, window.innerHeight / bg.ih)\r\n const w = bg.iw * fit * bg.zoom\r\n const h = bg.ih * fit * bg.zoom\r\n videoEl.style.cssText = `position:absolute;left:${bg.x * window.innerWidth - w / 2}px;top:${bg.y * window.innerHeight - h / 2}px;width:${w}px;height:${h}px;object-fit:fill;`\r\n } else {\r\n videoEl.style.cssText = 'position:absolute;inset:0;width:100%;height:100%;object-position:center;'\r\n videoEl.style.objectFit = mode === 'stretch' ? 'fill' : (mode === 'fill' || mode === 'tile') ? 'cover' : 'contain'\r\n }\r\n applyWpEffects()\r\n // Video mode has no still Image-decodable source; the captured frame\r\n // snapshot stands in for the brightness verdict (null until it lands, then\r\n // re-analyzed through the next apply).\r\n updateWpVerdict(rWp())\r\n}\r\n\r\nfunction applyWpEffects(): void {\r\n if (!wpEl) return\r\n const blur = rBl()\r\n wpEl.style.filter = blur > 0 ? `blur(${blur}px)` : 'none'\r\n wpEl.style.opacity = String(rWop())\r\n}\r\n\r\nexport function applyWp(): void {\r\n const url = rWp()\r\n if (cfg.backgroundType === 'video') {\r\n // The frame snapshot (rWp's video branch) is preview-only; the layer plays\r\n // the video from its own slot.\r\n const vurl = rWpVideo()\r\n if (vurl) {\r\n applyVideoWp(vurl)\r\n } else {\r\n clearDynamicBg()\r\n clearVideoEl()\r\n wpEl?.remove(); wpEl = null\r\n // An empty video slot must not keep the previous wallpaper's brightness\r\n // verdict alive: nothing is on screen to justify it, and a stale verdict\r\n // would flip the next background's font direction the wrong way. The\r\n // no-background branch below does the same.\r\n wpVerdict = null\r\n setBgDark(null)\r\n }\r\n } else if (cfg.backgroundType !== 'image' && cfg.generatedBg) {\r\n // Recreate the live canvas from saved params if one is not active yet\r\n // (boot or after import).\r\n clearVideoEl()\r\n if (!wpController) {\r\n applyGeneratedBg(cfg.generatedBg)\r\n return\r\n }\r\n ensureWpContainer()\r\n if (wpController.canvas.parentElement !== wpEl) wpEl!.appendChild(wpController.canvas)\r\n applyWpEffects()\r\n } else if (url) {\r\n applyImageWp(url)\r\n } else {\r\n // No background: tear down the layer but keep tokens/blur intact.\r\n clearDynamicBg()\r\n clearVideoEl()\r\n wpEl?.remove(); wpEl = null\r\n wpVerdict = null\r\n setBgDark(null)\r\n }\r\n // Write tokens only when there is something to derive them from (a saved\r\n // pick, a background brightness verdict, or a forced scheme) — on boot the\r\n // persisted state has not loaded yet, and rColor() would flash the default.\r\n // Interface opacity used to sit behind that same gate, which left all four\r\n // sliders dead until the user dragged one: they are applied unconditionally\r\n // now, falling back to the host's own resolved surface tokens when the\r\n // plugin has no palette (see readHostOpacityTokens). Nothing here keys off\r\n // rColor() unless a palette is actually in play, so there is no boot flash.\r\n applyCustomTokens(rOps())\r\n if (rHasColor()) {\r\n applySettingsOverrides(rSop())\r\n applyTrajectoryOverrides(rTrajectoryOpacity())\r\n }\r\n // Panel slider: always applied, no longer gated on a palette being active.\r\n // The token re-scope rule lives in the always-on static stylesheet, and\r\n // `applyPanelOverrides` falls back to the host's own resolved tokens when\r\n // no plugin palette is present so the panel follows the slider in every\r\n // state (picked color, wallpaper verdict, forced scheme, or none).\r\n applyPanelOverrides(rPanelOpacity())\r\n applyProduced()\r\n applyHeaderPopovers()\r\n applyExemptDefaults()\r\n applyPartBlurs(rBlurs())\r\n // Strokes re-derive here so 'auto'/'theme' colors follow palette and\r\n // wallpaper-verdict changes (applyWp runs on every theme/color re-apply).\r\n applyStrokes()\r\n}\r\n\r\nexport function teardownWp(): void {\r\n clearDynamicBg()\r\n clearVideoEl()\r\n disposeVideoObjectUrl()\r\n setBgDark(null)\r\n wpVerdict = null\r\n wpEl?.remove(); wpEl = null\r\n clearCustomTokens()\r\n tokenStyleEl?.remove(); tokenStyleEl = null\r\n removeViewCards()\r\n document.body.removeAttribute('data-ds-dark-theme')\r\n document.body.style.removeProperty('color-scheme')\r\n document.documentElement.style.removeProperty('--dsh-any-bg-settings-surface')\r\n document.documentElement.style.removeProperty('--dsh-any-bg-settings-layer-1')\r\n document.documentElement.style.removeProperty('--dsh-any-bg-settings-layer-2')\r\n document.documentElement.style.removeProperty('--dsh-any-bg-settings-layer-3')\r\n document.documentElement.style.removeProperty('--dsh-any-traj-layer-1')\r\n document.documentElement.style.removeProperty('--dsh-any-traj-layer-2')\r\n document.documentElement.style.removeProperty('--dsh-any-traj-layer-3')\r\n document.documentElement.style.removeProperty('--dsh-any-bg-settings-card-surface')\r\n document.documentElement.style.removeProperty('--dsh-any-blur-settings')\r\n document.documentElement.style.removeProperty('--dsh-any-blur-card-panels')\r\n document.documentElement.style.removeProperty('--dsh-any-input-blur')\r\n document.documentElement.style.removeProperty('--dsh-any-part-blur-global')\r\n for (const set of [PANEL_LAYER_VARS, PROD_PANEL_LAYER_VARS, PROD_LAYER_VARS]) {\r\n for (const k of LAYER_KEYS) {\r\n const name = set[k]\r\n if (name) document.documentElement.style.removeProperty(name)\r\n }\r\n }\r\n document.documentElement.classList.remove(INPUT_FROST_CLASS)\r\n document.documentElement.style.removeProperty('--dsh-any-blur-panel')\r\n document.documentElement.style.removeProperty('--dsh-any-blur-prod')\r\n document.documentElement.style.removeProperty('--dsh-any-prod-pct')\r\n document.documentElement.style.removeProperty('--dsh-any-blur-header')\r\n headerStyleEl?.remove(); headerStyleEl = null\r\n exemptStyleEl?.remove(); exemptStyleEl = null\r\n for (const v of Object.values(OPACITY_VARS)) document.documentElement.style.removeProperty(v)\r\n baseTokenKey = ''\r\n lastBgKey = ''\r\n if (tokensRaf !== null) { cancelAnimationFrame(tokensRaf); tokensRaf = null }\r\n pendingOps = null\r\n tableFixStyleEl?.remove(); tableFixStyleEl = null\r\n partBlurStyleEl?.remove(); partBlurStyleEl = null\r\n removeStrokes()\r\n removeFontFace()\r\n // Drop the low-res drag cache and the drag flag: a teardown mid-drag leaves\r\n // the disposer's reset path short-circuited (!wpEl), and dragLow stuck true\r\n // would make every later setDragLow(true) a no-op — the drag-quality\r\n // downgrade silently never engages again.\r\n imgNat = null\r\n lowResUrl = null\r\n lowResFor = ''\r\n dragLow = false\r\n setBlur(frameEl, 0); setBlur(sidebarEl, 0); setBlur(centerEl, 0); setBlur(rightEl, 0)\r\n if (frameEl !== null) frameEl.classList.remove(PART_FRAME_CLASS)\r\n if (centerEl !== null) centerEl.style.removeProperty('background')\r\n if (rightEl !== null) rightEl.style.removeProperty('background')\r\n stopWatchingParts()\r\n}\r\n\r\n/** Live wallpaper-opacity updates during slider drag (no full re-apply). */\r\nexport function setWpOpacity(v: number): void {\r\n if (wpEl) wpEl.style.opacity = String(v)\r\n}\r\n\r\n/** Live wallpaper-blur updates during slider drag (no full re-apply). */\r\nexport function setWpBlur(v: number): void {\r\n if (wpEl) wpEl.style.filter = v > 0 ? `blur(${v}px)` : 'none'\r\n}\r\n","/**\n * Assembly of the plugin's one static stylesheet.\n *\n * Until now the sheet was a single template literal in the client entry with\n * thirteen constants bolted together in whatever order they were added. That\n * order is load-bearing and was documented in three separate comment blocks in\n * `wallpaper.ts` — so it is encoded here instead, in one list, with the reason\n * next to each entry.\n *\n * What the release can change lives in the slots marked below: the panel group\n * (which element carries the frost), the plugin-manager page (whether this release\n * ships that page at all), and the menu groups (which token a menu's fill comes\n * from and whose job its frost is). Everything outside a slot is host-agnostic by\n * construction — it targets attributes every release in range emits.\n *\n * The sheet is rebuilt when the release verdict lands. It has to be: `apply` runs\n * synchronously while the verdict is a Node round-trip, so the FIRST sheet is\n * always the unresolved, DOM-arbitrated one. That is the correct interim state,\n * and swapping in the resolved arm a moment later is what removes the `:has()`\n * dependency from hosts we do know the answer for.\n *\n * @module\n */\nimport {\n FRAME_CLEAR_RULE,\n MOBILE_HEADER_RULE,\n PANEL_TOKEN_RULE,\n PLACEHOLDER_RULE,\n PRODUCED_RULE,\n SETTINGS_STYLE_RULE,\n STROKE_RULE,\n TRAJECTORY_STYLE_RULE,\n exemptDefaultRule,\n headerPopoverRule,\n inputBlurRule,\n popoverBlurRule,\n} from '../wallpaper'\nimport { rHostAdapter, subscribeHostInfo } from './release'\n\n/** The plugin's own dark-mode value on the body attribute the host sets. Scoping\n * the gradient to it avoids matching the host's own theme attribute. */\nconst DARK_GRADIENT =\n 'body[data-ds-dark-theme=\"dsh-any-background\"]::before{' +\n \"content:'';position:fixed;inset:0;z-index:-1;pointer-events:none;\" +\n 'background:radial-gradient(ellipse 80% 60% at 50% 0%,rgba(255,255,255,0.03) 0%,transparent 60%)}'\n\n/**\n * The order contract. Later entries override earlier ones at equal specificity,\n * which several groups rely on:\n * · headerPopoverRule() after popoverBlurRule() — a surface moving from the card\n * group to the header group must win, not merely be listed twice.\n * · PRODUCED_RULE / STROKE_RULE after the blur groups — they shield their\n * surfaces from an inherited slider.\n * · exemptDefaultRule() last of the token groups — an exemption has to land\n * after whatever it exempts.\n * · PLACEHOLDER_RULE genuinely last — `::placeholder` resets must survive every\n * group above.\n *\n * Three of these are FUNCTIONS, not constants, and they are version slots like\n * `panel.blur`: which declaration frosts a menu, and which token a menu's fill\n * comes from, is the current adapter's answer (`adapter.menus`). They stay in\n * place rather than moving next to the other slots because the contract above is\n * about position — a slot is only safe if it does not have to relocate.\n */\nexport function buildStaticStyles(): string {\n const adapter = rHostAdapter()\n const panel = adapter.panelFragments()\n // `← adapter` marks a version slot: the string it concatenates is chosen by the\n // resolved release. Everything else is host-agnostic by construction.\n return DARK_GRADIENT\n // First, not because anything competes with it, but because every surface\n // group below assumes the frame behind them is clear.\n + FRAME_CLEAR_RULE\n + SETTINGS_STYLE_RULE\n + popoverBlurRule() // ← adapter: a menu's frost + fill token\n + TRAJECTORY_STYLE_RULE\n + inputBlurRule() // ← adapter: the same fill tokens scoped to the input slider\n + MOBILE_HEADER_RULE\n + PANEL_TOKEN_RULE\n + panel.promotion // ← adapter: panel geometry, whose target element changed\n + panel.blur // ← adapter: ditto\n + adapter.pluginPageRule // ← adapter: the plugin-manager block, absent on old lines\n + PRODUCED_RULE\n + STROKE_RULE\n + headerPopoverRule() // ← adapter: same frost answer, header's own blur var\n + exemptDefaultRule() // ← adapter: the exemptions clear frost through it too\n + PLACEHOLDER_RULE\n}\n\n/** Append the plugin's stylesheet and keep it matched to the host.\n * Returns a teardown for the plugin's effect scope. */\nexport function mountStaticStyles(): () => void {\n const el = document.createElement('style')\n el.dataset.plugin = 'dsh-any-background'\n el.textContent = buildStaticStyles()\n document.head.appendChild(el)\n // Re-resolve only when the verdict actually changes; the write is a full sheet\n // swap, so it must not run on unrelated notifications.\n let last = el.textContent\n const unsubscribe = subscribeHostInfo(() => {\n const next = buildStaticStyles()\n if (next !== last) {\n last = next\n el.textContent = next\n }\n })\n return () => {\n unsubscribe()\n el.parentNode?.removeChild(el)\n }\n}\n","/**\r\n * Video-background helpers: capturing a single frame as a JPEG snapshot.\r\n * The snapshot stands in for everything that only understands still images:\r\n * the settings preview, theme-color extraction and the eyedropper. Uploads\r\n * stream the raw file over the binary upload route (see rpc.uploadVideo) —\r\n * a data-URL detour would inflate the bytes and trip the RPC body limit.\r\n */\r\n\r\nfunction grabFrame(v: HTMLVideoElement): string | null {\r\n const w = v.videoWidth, h = v.videoHeight\r\n if (w <= 0 || h <= 0) return null\r\n const canvas = document.createElement('canvas')\r\n canvas.width = w\r\n canvas.height = h\r\n const ctx = canvas.getContext('2d')\r\n if (!ctx) return null\r\n ctx.drawImage(v, 0, 0, w, h)\r\n try {\r\n return canvas.toDataURL('image/jpeg', 0.85)\r\n } catch {\r\n return null\r\n }\r\n}\r\n\r\n/**\r\n * Capture one representative frame from a video data URL as a JPEG data URL.\r\n * Seeks to ~10% of the duration (first frame is often black) and waits for\r\n * the seek to land; resolves null when the video cannot be decoded. A timeout\r\n * keeps a broken file from hanging the upload flow.\r\n */\r\nexport function captureVideoSnapshot(url: string): Promise<string | null> {\r\n return new Promise(resolve => {\r\n const v = document.createElement('video')\r\n let settled = false\r\n const done = (r: string | null): void => {\r\n if (settled) return\r\n settled = true\r\n window.clearTimeout(timer)\r\n v.removeAttribute('src')\r\n v.load()\r\n resolve(r)\r\n }\r\n const timer = window.setTimeout(() => done(grabFrame(v)), 6000)\r\n v.muted = true\r\n v.preload = 'auto'\r\n v.playsInline = true\r\n v.onerror = () => done(null)\r\n v.onloadeddata = () => {\r\n // Prefer a frame slightly into the clip; very short clips seek to half.\r\n const target = isFinite(v.duration) && v.duration > 0.6 ? Math.min(v.duration * 0.1, 2) : 0\r\n if (target <= 0) { done(grabFrame(v)); return }\r\n v.onseeked = () => done(grabFrame(v))\r\n try {\r\n v.currentTime = target\r\n } catch {\r\n done(grabFrame(v))\r\n }\r\n }\r\n v.src = url\r\n })\r\n}\r\n","/**\n * dsh-any-background — settings UI design system.\n *\n * The section is styled entirely through these scoped classes instead of the\n * host's inline-style approach: animations (page transitions, staggered\n * reveals, the rotating orb ring) and pseudo-element effects cannot be\n * expressed as React inline styles. Every color reads the host's\n * --dsw-alias-* tokens so the panel follows the user's custom theme color and\n * light/dark scheme automatically; `color-mix` tints carry a plain-token\n * fallback first for older engines.\n */\nexport const NAV_ITEM_H = 38\nexport const NAV_GAP = 4\n\nexport const UI_CSS = `\n/* The section is rendered INLINE inside the host settings dialog's content\n * column: the host provides the modal chrome (backdrop, centering, closing).\n * These classes style only the embedded shell; transient fixed layers (toast,\n * color picker, background editor) escape through Portals on <html>. */\n.dab-root{position:relative;box-sizing:border-box;color:var(--dsw-alias-label-primary);animation:dab-fade-in .35s ease both;container-type:inline-size;display:flex;flex-direction:column;align-items:center;width:100%;min-width:0;--dab-mono:ui-monospace,\"Cascadia Mono\",\"SF Mono\",Consolas,\"Courier New\",monospace}\n/* The root needs its OWN border-box, not just the descendants' below: the\n * sidebar surface puts 12px of padding on it, and with the default content-box\n * that padding landed OUTSIDE the width:100%, so the page came out 24px wider\n * than the pane and the host clipped both edges off. */\n.dab-root *,.dab-root *::before,.dab-root *::after{box-sizing:border-box}\n.dab-root button{font-family:inherit}\n\n/* ── shell: nav rail + page body ─────────────────────────────────────────── */\n.dab-shell{display:grid;grid-template-columns:158px minmax(0,1fr);gap:26px;align-items:start;padding-bottom:8px;width:100%;max-width:980px;margin:0 auto}\n.dab-nav{position:sticky;top:0;display:flex;flex-direction:column;gap:18px}\n.dab-brand{display:flex;align-items:center;gap:10px;padding:2px 6px}\n.dab-brand-tile{width:30px;height:30px;flex:none;border-radius:9px;display:grid;place-items:center;color:var(--dsw-alias-brand-text);background:var(--dsw-alias-brand-primary);box-shadow:0 4px 14px -4px var(--dsw-alias-brand-primary)}\n.dab-brand-name{font-size:13px;font-weight:650;letter-spacing:.01em;line-height:1.25}\n.dab-brand-tag{font-size:9px;letter-spacing:.16em;font-weight:600;color:var(--dsw-alias-label-quaternary,var(--dsw-alias-label-tertiary));text-transform:uppercase}\n.dab-nav-list{position:relative;display:flex;flex-direction:column;gap:${NAV_GAP}px}\n.dab-nav-ind{position:absolute;left:0;right:0;top:0;height:${NAV_ITEM_H}px;border-radius:11px;background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);background:color-mix(in srgb,var(--dsw-alias-brand-primary) 13%,transparent);border-color:color-mix(in srgb,var(--dsw-alias-brand-primary) 25%,transparent);transition:transform .38s cubic-bezier(.22,1,.36,1)}\n.dab-nav-item{position:relative;z-index:1;display:flex;align-items:center;gap:10px;height:${NAV_ITEM_H}px;padding:0 12px;border:0;background:none;border-radius:11px;color:var(--dsw-alias-label-tertiary);font-size:13px;cursor:pointer;text-align:left;transition:color .22s ease}\n.dab-nav-item:hover{color:var(--dsw-alias-label-primary)}\n.dab-nav-item.is-active{color:var(--dsw-alias-brand-primary);font-weight:600}\n.dab-nav-item svg{flex:none;transition:transform .3s cubic-bezier(.34,1.56,.64,1)}\n.dab-nav-item:hover svg{transform:scale(1.14) rotate(-5deg)}\n\n/* ── page chrome ─────────────────────────────────────────────────────────── */\n.dab-page{animation:dab-page-in .4s cubic-bezier(.22,1,.36,1) both;min-width:0;display:flex;flex-direction:column;gap:13px}\n.dab-head{margin:2px 0 5px}\n.dab-overline{font-size:10.5px;font-weight:700;letter-spacing:.18em;text-transform:uppercase;color:var(--dsw-alias-brand-primary);opacity:.9}\n.dab-h1{margin:4px 0 0;font-size:21px;font-weight:700;letter-spacing:-.01em}\n.dab-desc{margin:6px 0 0;font-size:12.5px;line-height:1.55;color:var(--dsw-alias-label-tertiary);max-width:56ch}\n.dab-card{background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l2);border-radius:16px;padding:18px}\n.dab-card-hover{transition:transform .28s ease,box-shadow .28s ease,border-color .28s ease}\n.dab-card-hover:hover{transform:translateY(-2px);box-shadow:0 10px 28px -12px rgba(0,0,0,.28)}\n.dab-rise{animation:dab-rise-in .55s cubic-bezier(.22,1,.36,1) both;animation-delay:calc(var(--d,0) * 62ms)}\n\n/* ── accent hero (color orb) ─────────────────────────────────────────────── */\n.dab-hero-accent{display:flex;align-items:center;gap:24px;flex-wrap:wrap}\n.dab-orb-wrap{position:relative;width:118px;height:118px;flex:none}\n.dab-orb{position:absolute;inset:11px;border-radius:50%;background:radial-gradient(circle at 32% 28%,rgba(255,255,255,.5),rgba(255,255,255,0) 44%),var(--c,#888);box-shadow:0 16px 36px -10px var(--c-soft,transparent),inset 0 -10px 20px rgba(0,0,0,.16);animation:dab-orb-in .7s cubic-bezier(.22,1,.36,1) both}\n.dab-orb-ring{position:absolute;inset:0;border-radius:50%;background:conic-gradient(from 0deg,transparent 0 30%,var(--c,#888) 46%,transparent 62%,transparent 76%,var(--c,#888) 90%,transparent 100%);-webkit-mask:radial-gradient(farthest-side,transparent calc(100% - 3.5px),#000 calc(100% - 2.5px));mask:radial-gradient(farthest-side,transparent calc(100% - 3.5px),#000 calc(100% - 2.5px));animation:dab-spin 7s linear infinite;opacity:.9}\n.dab-hex-caption{font-size:11px;color:var(--dsw-alias-label-tertiary);letter-spacing:.04em}\n.dab-hex{font-family:var(--dab-mono);font-size:24px;font-weight:600;letter-spacing:.02em;line-height:1.2;margin-top:2px}\n.dab-hsl-row{display:flex;gap:16px;margin-top:7px;font-family:var(--dab-mono);font-size:11px;color:var(--dsw-alias-label-tertiary)}\n.dab-hsl-row b{font-weight:600;color:var(--dsw-alias-label-secondary,var(--dsw-alias-label-tertiary))}\n\n/* ── swatches ────────────────────────────────────────────────────────────── */\n.dab-swatch-title{font-size:12px;font-weight:600;margin-bottom:10px;color:var(--dsw-alias-label-secondary,var(--dsw-alias-label-tertiary))}\n.dab-swatches{display:flex;flex-wrap:wrap;gap:9px}\n.dab-swatch{width:25px;height:25px;border-radius:50%;border:0;padding:0;cursor:pointer;box-shadow:inset 0 0 0 1px rgba(0,0,0,.1);transition:transform .22s cubic-bezier(.34,1.56,.64,1),box-shadow .22s ease}\n.dab-swatch:hover{transform:scale(1.2)}\n.dab-swatch.is-on{box-shadow:0 0 0 2px var(--dsw-alias-bg-layer-1),0 0 0 4px var(--dsw-alias-brand-primary)}\n\n/* ── wheel card ──────────────────────────────────────────────────────────── */\n.dab-wheel-card{position:relative;display:flex;align-items:center;justify-content:center;gap:28px;flex-wrap:wrap;padding:24px 18px}\n.dab-wheel-glow{position:absolute;width:230px;height:230px;border-radius:50%;filter:blur(48px);opacity:.2;background:var(--c,#888);pointer-events:none;transition:background .4s ease}\n/* flex:none is load bearing, not cosmetic: the pointer maths reads client\n * coordinates straight off this element's box, so any shrink below the 220px\n * drawing surface would desynchronise the ring from the cursor. */\n.dab-wheel{position:relative;flex:none;cursor:crosshair;border-radius:50%;box-shadow:0 12px 32px -14px rgba(0,0,0,.4)}\n.dab-hint{font-size:11.5px;line-height:1.55;color:var(--dsw-alias-label-tertiary);padding:0 4px}\n\n/* ── precise color inputs ────────────────────────────────────────────────── */\n.dab-inputs{display:flex;flex-direction:column;gap:10px;min-width:172px}\n.dab-field{display:flex;align-items:center;gap:8px}\n.dab-field-label{width:14px;text-align:center;font-family:var(--dab-mono);font-size:11px;font-weight:600;color:var(--dsw-alias-label-tertiary)}\n.dab-num{flex:1;min-width:0;height:30px;padding:0 10px;border-radius:9px;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-primary);font-family:var(--dab-mono);font-size:12px;outline:none;transition:border-color .2s,box-shadow .2s}\n.dab-num:focus{border-color:var(--dsw-alias-brand-primary);box-shadow:0 0 0 3px color-mix(in srgb,var(--dsw-alias-brand-primary) 18%,transparent)}\n.dab-num::-webkit-outer-spin-button,.dab-num::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}\n.dab-num{-moz-appearance:textfield;appearance:textfield}\n.dab-urlinput{flex:1;min-width:180px;height:34px;padding:0 12px;border-radius:10px;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-primary);font-size:12.5px;outline:none;transition:border-color .2s}\n.dab-urlinput::placeholder{color:var(--dsw-alias-label-quaternary)}\n.dab-urlinput:focus{border-color:var(--dsw-alias-brand-primary);box-shadow:0 0 0 3px color-mix(in srgb,var(--dsw-alias-brand-primary) 18%,transparent)}\n.dab-urlrow{display:flex;flex-wrap:wrap;gap:8px;align-items:center;margin-top:12px;animation:dab-list-in .3s cubic-bezier(.22,1,.36,1) both}\n.dab-swatch-lg{height:38px;border-radius:10px;border:1px solid var(--dsw-alias-border-l2);box-shadow:inset 0 0 14px rgba(0,0,0,.1);transition:transform .3s ease}\n.dab-swatch-lg:hover{transform:scale(1.02)}\n\n/* ── buttons & chips ─────────────────────────────────────────────────────── */\n.dab-btn{display:inline-flex;align-items:center;justify-content:center;gap:7px;height:34px;padding:0 14px;border-radius:10px;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-button-elevated-fill);color:var(--dsw-alias-label-primary);font-size:12.5px;font-weight:550;cursor:pointer;transition:transform .18s ease,box-shadow .18s ease,border-color .18s ease,opacity .18s ease,background .18s ease}\n.dab-btn:hover:not(:disabled){transform:translateY(-1px);box-shadow:0 5px 14px -6px rgba(0,0,0,.32)}\n.dab-btn:active:not(:disabled){transform:translateY(0) scale(.97);box-shadow:none}\n.dab-btn:disabled{opacity:.5;cursor:not-allowed}\n.dab-btn-primary{background:var(--dsw-alias-brand-primary);color:var(--dsw-alias-brand-text);border-color:transparent}\n.dab-btn-danger{color:var(--dsw-alias-state-error-primary)}\n.dab-btn-danger-solid{background:var(--dsw-alias-state-error-primary);color:#fff;border-color:transparent}\n.dab-btn-danger-solid:hover:not(:disabled){background:color-mix(in srgb,var(--dsw-alias-state-error-primary) 85%,#000)}\n.dab-btn-ghost{background:transparent;border-color:transparent;color:var(--dsw-alias-label-secondary,var(--dsw-alias-label-tertiary))}\n.dab-btn-ghost:hover:not(:disabled){background:var(--dsw-alias-bg-layer-2);box-shadow:none}\n/* Soft solid button: subtle layer background instead of transparent ghost. */\n.dab-btn-soft{background:var(--dsw-alias-bg-layer-2);border-color:var(--dsw-alias-border-l2);color:var(--dsw-alias-label-secondary,var(--dsw-alias-label-tertiary))}\n.dab-btn-soft:hover:not(:disabled){background:var(--dsw-alias-bg-layer-3,var(--dsw-alias-bg-layer-2));color:var(--dsw-alias-label-primary)}\n/* White background with error-red text (inverse of danger-solid). */\n.dab-btn-danger-inverted{background:#fff;color:var(--dsw-alias-state-error-primary);border-color:transparent}\n.dab-btn-danger-inverted:hover:not(:disabled){background:#f3f4f6}\n.dab-btn:focus-visible,.dab-nav-item:focus-visible,.dab-seg-item:focus-visible,.dab-swatch:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:2px}\n.dab-chip-row{display:flex;flex-wrap:wrap;gap:8px}\n.dab-chip{height:30px;padding:0 14px;border-radius:99px;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-secondary,var(--dsw-alias-label-tertiary));font-size:12px;cursor:pointer;display:inline-flex;align-items:center;gap:6px;transition:background-color .22s ease,border-color .22s ease,color .22s ease}\n.dab-chip:hover{border-color:var(--dsw-alias-brand-primary);color:var(--dsw-alias-label-primary)}\n.dab-chip.is-active{background:var(--dsw-alias-brand-primary);color:var(--dsw-alias-brand-text);border-color:transparent}\n\n/* ── sliders ─────────────────────────────────────────────────────────────── */\n.dab-slider-block{display:flex;flex-direction:column;gap:6px}\n.dab-slider-block + .dab-slider-block{margin-top:13px}\n.dab-slider-label{font-size:12px;font-weight:550;color:var(--dsw-alias-label-secondary,var(--dsw-alias-label-tertiary))}\n.dab-slider-val{font-family:var(--dab-mono);font-size:11px;color:var(--dsw-alias-label-tertiary);min-width:44px;text-align:right}\n.dab-slider{-webkit-appearance:none;appearance:none;flex:1;min-width:0;height:4px;border-radius:99px;outline:none;cursor:pointer;margin:5px 0;background:linear-gradient(to right,var(--dsw-alias-brand-primary) calc(var(--pct,50) * 1%),var(--dsw-alias-border-l2) calc(var(--pct,50) * 1%));transition:height .15s ease}\n.dab-slider:hover{height:5px}\n.dab-slider::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;width:15px;height:15px;border-radius:50%;background:var(--dsw-alias-button-elevated-fill,#fff);border:2px solid var(--dsw-alias-brand-primary);box-shadow:0 1px 5px rgba(0,0,0,.28);transition:transform .16s cubic-bezier(.34,1.56,.64,1)}\n.dab-slider:hover::-webkit-slider-thumb,.dab-slider:focus-visible::-webkit-slider-thumb{transform:scale(1.22)}\n.dab-slider:active::-webkit-slider-thumb{transform:scale(1.34)}\n.dab-slider::-moz-range-thumb{width:13px;height:13px;border-radius:50%;background:var(--dsw-alias-button-elevated-fill,#fff);border:2px solid var(--dsw-alias-brand-primary)}\n\n/* ── interface part cards ────────────────────────────────────────────────── */\n.dab-grid-parts{display:grid;grid-template-columns:repeat(auto-fill,minmax(min(240px,100%),1fr));gap:13px}\n.dab-part-head{display:flex;align-items:center;gap:11px;margin-bottom:14px}\n.dab-part-ico{width:32px;height:32px;flex:none;border-radius:10px;display:grid;place-items:center;color:var(--dsw-alias-brand-primary);background:var(--dsw-alias-bg-layer-2);background:color-mix(in srgb,var(--dsw-alias-brand-primary) 12%,transparent)}\n.dab-part-name{font-size:13.5px;font-weight:600}\n.dab-part-badge{margin-left:auto;font-family:var(--dab-mono);font-size:11px;color:var(--dsw-alias-label-tertiary);background:var(--dsw-alias-bg-layer-2);border-radius:99px;padding:3px 9px}\n\n/* ── segmented control ───────────────────────────────────────────────────── */\n.dab-seg{position:relative;display:inline-flex;padding:3px;background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);border-radius:11px}\n.dab-seg-thumb{position:absolute;top:3px;bottom:3px;left:3px;width:var(--w,96px);border-radius:8px;background:var(--dsw-alias-button-elevated-fill);box-shadow:0 2px 8px -2px rgba(0,0,0,.28);transition:transform .32s cubic-bezier(.22,1,.36,1)}\n.dab-seg-item{position:relative;z-index:1;display:inline-flex;align-items:center;justify-content:center;gap:6px;width:var(--w,96px);height:30px;border:0;background:none;border-radius:8px;color:var(--dsw-alias-label-tertiary);font-size:12.5px;cursor:pointer;transition:color .25s ease}\n.dab-seg-item.is-active{color:var(--dsw-alias-label-primary);font-weight:600}\n\n/* ── toggle switch ───────────────────────────────────────────────────────── */\n.dab-toggle{position:relative;width:42px;height:24px;flex:none;border-radius:99px;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);cursor:pointer;padding:0;transition:background .28s ease,border-color .28s ease}\n.dab-toggle-knob{position:absolute;top:2.5px;left:2.5px;width:17px;height:17px;border-radius:50%;background:var(--dsw-alias-label-secondary,#999);box-shadow:0 1px 3px rgba(0,0,0,.3);transition:transform .28s cubic-bezier(.22,1,.36,1),background .28s ease}\n.dab-toggle.is-on{background:var(--dsw-alias-brand-primary);border-color:var(--dsw-alias-brand-primary)}\n.dab-toggle.is-on .dab-toggle-knob{transform:translateX(18px);background:#fff}\n\n/* ── custom font card ────────────────────────────────────────────────────── */\n.dab-font-title{display:flex;align-items:center;gap:11px}\n.dab-font-row{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-top:14px}\n.dab-font-name{font-family:var(--dab-mono);font-size:13.5px;color:var(--dsw-alias-label-secondary,var(--dsw-alias-label-tertiary));background:var(--dsw-alias-bg-layer-2);border-radius:99px;padding:5px 11px;max-width:260px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n.dab-font-name.is-empty{color:var(--dsw-alias-label-tertiary)}\n.dab-font-actions{display:flex;align-items:center;gap:8px;margin-left:auto}\n/* The font card's labels read one step larger than the rest of the panel —\n they carry most of the explanation on this page. Scoped to the card so the\n same .dab-hint / .dab-btn elsewhere keep their size. */\n.dab-font-actions .dab-btn{font-size:14.5px}\n.dab-font-card .dab-hint{font-size:13.5px}\n\n/* ── text-stroke color dots ──────────────────────────────────────────────── */\n.dab-stroke-dots{display:flex;align-items:center;gap:9px;margin-top:14px}\n.dab-stroke-dot-wrap{position:relative;width:18px;height:18px;flex:none}\n.dab-stroke-dot{width:18px;height:18px;padding:0;border-radius:50%;border:1.5px solid var(--dsw-alias-border-l2);background-clip:padding-box;cursor:pointer;transition:transform .18s cubic-bezier(.34,1.56,.64,1),box-shadow .18s ease}\n.dab-stroke-dot:hover{transform:scale(1.16)}\n/* 'auto' has no fixed value — half light / half dark reads as \"derived\". */\n.dab-stroke-dot-auto{background:conic-gradient(from -90deg,#fff 0 50%,#000 50% 100%)}\n.dab-stroke-dot.is-active{box-shadow:0 0 0 2px var(--dsw-alias-bg-layer-1),0 0 0 3.5px var(--dsw-alias-brand-primary);border-color:transparent}\n/* The native color picker sits invisible on top of the custom swatch. */\n.dab-stroke-dot-input{position:absolute;inset:0;width:100%;height:100%;margin:0;padding:0;border:0;border-radius:50%;background:none;opacity:0;cursor:pointer}\n\n/* ── background preview hero ─────────────────────────────────────────────── */\n.dab-hero{position:relative;border-radius:16px;overflow:hidden;aspect-ratio:16/9;background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2)}\n.dab-hero-img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;transition:transform .5s cubic-bezier(.22,1,.36,1)}\n.dab-hero:hover .dab-hero-img{transform:scale(1.03)}\n.dab-hero-empty{position:absolute;inset:6px;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:10px;color:var(--dsw-alias-label-tertiary);font-size:12.5px;border:1.5px dashed var(--dsw-alias-border-l2);border-radius:12px;cursor:pointer;background:transparent;transition:border-color .25s,color .25s,background .25s;width:auto;height:auto}\n.dab-hero-empty:hover{border-color:var(--dsw-alias-brand-primary);color:var(--dsw-alias-brand-primary)}\n.dab-hero-empty.is-over{border-color:var(--dsw-alias-brand-primary);color:var(--dsw-alias-brand-primary);background:color-mix(in srgb,var(--dsw-alias-brand-primary) 8%,transparent)}\n.dab-hero-badge{position:absolute;top:10px;left:10px;display:inline-flex;align-items:center;gap:5px;height:24px;padding:0 11px;border-radius:99px;background:rgba(0,0,0,.45);color:#fff;font-size:11px;backdrop-filter:blur(6px);pointer-events:none}\n.dab-hero-veil{position:absolute;left:0;right:0;bottom:0;padding:34px 12px 12px;display:flex;align-items:flex-end;justify-content:flex-end;gap:8px;background:linear-gradient(to top,rgba(0,0,0,.55),rgba(0,0,0,0));opacity:0;transform:translateY(6px);transition:opacity .3s ease,transform .3s ease}\n.dab-hero:hover .dab-hero-veil{opacity:1;transform:none}\n.dab-hero-veil .dab-btn{background:rgba(255,255,255,.94);color:#14161a;border-color:transparent;height:30px;font-size:12px}\n.dab-hero-veil .dab-btn-danger{color:#dc2626}\n\n/* ── generated background type cards ─────────────────────────────────────── */\n.dab-types{display:grid;grid-template-columns:repeat(3,1fr);gap:12px}\n.dab-type{position:relative;border:1.5px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-1);border-radius:14px;padding:10px;cursor:pointer;text-align:left;font:inherit;transition:border-color .25s,transform .25s,box-shadow .25s;animation:dab-type-in .42s cubic-bezier(.22,1,.36,1) both;animation-delay:calc(var(--i,0) * 60ms)}\n.dab-type:hover{transform:translateY(-2px)}\n.dab-type.is-active{border-color:var(--dsw-alias-brand-primary);box-shadow:0 0 0 3px color-mix(in srgb,var(--dsw-alias-brand-primary) 18%,transparent)}\n.dab-type-thumb{height:62px;border-radius:9px;overflow:hidden;position:relative}\n.dab-type-name{margin-top:9px;font-size:12.5px;font-weight:600;color:var(--dsw-alias-label-primary)}\n.dab-type-desc{margin-top:2px;font-size:11px;color:var(--dsw-alias-label-tertiary);line-height:1.4}\n.dab-type-check{position:absolute;top:16px;right:16px;width:20px;height:20px;border-radius:50%;background:var(--dsw-alias-brand-primary);color:var(--dsw-alias-brand-text);display:grid;place-items:center;opacity:0;transform:scale(.4);transition:opacity .25s,transform .25s cubic-bezier(.34,1.56,.64,1)}\n.dab-type.is-active .dab-type-check{opacity:1;transform:none}\n.dab-thumb-mesh{background:radial-gradient(circle at 22% 30%,#f472b6,transparent 42%),radial-gradient(circle at 80% 22%,#38bdf8,transparent 46%),radial-gradient(circle at 52% 84%,#fbbf24,transparent 52%),#1e293b}\n.dab-thumb-shader{background:linear-gradient(120deg,#0ea5e9,#8b5cf6,#d946ef,#0ea5e9);background-size:300% 300%;animation:dab-flow 6s linear infinite}\n.dab-thumb-pattern{background-image:radial-gradient(circle,rgba(255,255,255,.92) 1.2px,transparent 1.4px);background-size:10px 10px;background-color:#334155}\n\n/* ── seed row ────────────────────────────────────────────────────────────── */\n.dab-seed{display:flex;align-items:center;gap:13px;padding:12px 14px;border-radius:12px;background:var(--dsw-alias-bg-layer-2);margin-top:14px}\n.dab-seed-ico{color:var(--dsw-alias-brand-primary);display:grid;place-items:center}\n.dab-seed-txt{flex:1;min-width:0}\n.dab-seed-title{font-size:12.5px;font-weight:600;display:flex;align-items:center;gap:6px}\n.dab-seed-desc{font-size:11px;color:var(--dsw-alias-label-tertiary);margin-top:2px}\n.dab-spin{animation:dab-rotate .7s cubic-bezier(.3,.7,.3,1) 1}\n\n/* ── profile page ────────────────────────────────────────────────────────── */\n.dab-profile-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(220px,100%),1fr));gap:13px}\n.dab-profile-ico{width:38px;height:38px;border-radius:11px;display:grid;place-items:center;margin-bottom:13px;color:var(--dsw-alias-brand-primary);background:var(--dsw-alias-bg-layer-2);background:color-mix(in srgb,var(--dsw-alias-brand-primary) 12%,transparent)}\n.dab-profile-title{font-size:14px;font-weight:650}\n.dab-profile-desc{font-size:12px;color:var(--dsw-alias-label-tertiary);line-height:1.55;margin:5px 0 15px}\n.dab-footer{margin-top:6px;padding:14px 4px 0;border-top:1px solid var(--dsw-alias-border-l2);display:flex;align-items:center;justify-content:space-between;font-size:11px;color:var(--dsw-alias-label-tertiary)}\n.dab-footer-mono{font-family:var(--dab-mono);letter-spacing:.02em}\n\n/* ── presets / profiles / schedule / rotation ────────────────────────────── */\n.dab-row-head{display:flex;align-items:center;justify-content:space-between;gap:12px}\n.dab-preset-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(min(150px,100%),1fr));gap:10px}\n.dab-preset{display:flex;flex-direction:column;align-items:flex-start;gap:3px;padding:12px;border:1.5px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-1);border-radius:13px;cursor:pointer;font:inherit;text-align:left;transition:border-color .25s,transform .25s,box-shadow .25s;animation:dab-row-in .34s cubic-bezier(.22,1,.36,1) both;animation-delay:calc(var(--i,0) * 45ms)}\n.dab-preset:hover{transform:translateY(-2px);border-color:var(--dsw-alias-brand-primary);box-shadow:0 8px 22px -12px rgba(0,0,0,.3)}\n.dab-preset-dot{width:22px;height:22px;border-radius:50%;margin-bottom:4px;box-shadow:inset 0 0 0 1px rgba(0,0,0,.12),0 4px 10px -4px rgba(0,0,0,.35);background:var(--dsw-alias-bg-layer-2);display:grid;place-items:center;color:var(--dsw-alias-label-tertiary)}\n.dab-preset-name{font-size:12.5px;font-weight:600;color:var(--dsw-alias-label-primary)}\n.dab-preset-desc{font-size:10.5px;line-height:1.45;color:var(--dsw-alias-label-tertiary)}\n.dab-profile-list{display:flex;flex-direction:column;gap:8px;margin-top:12px;animation:dab-list-in .38s cubic-bezier(.22,1,.36,1) both}\n.dab-profile-row{display:flex;align-items:center;gap:11px;padding:9px 12px;border:1px solid var(--dsw-alias-border-l2);border-radius:12px;background:var(--dsw-alias-bg-layer-2);animation:dab-row-in .34s cubic-bezier(.22,1,.36,1) both;animation-delay:calc(var(--i,0) * 45ms);transition:border-color .22s ease,background .22s ease}\n.dab-profile-row:hover{border-color:color-mix(in srgb,var(--dsw-alias-brand-primary) 28%,transparent);background:color-mix(in srgb,var(--dsw-alias-label-primary) 4%,var(--dsw-alias-bg-layer-2))}\n.dab-profile-row.is-active{border-color:color-mix(in srgb,var(--dsw-alias-brand-primary) 45%,transparent);background:color-mix(in srgb,var(--dsw-alias-brand-primary) 7%,var(--dsw-alias-bg-layer-2))}\n.dab-profile-dot{width:22px;height:22px;flex:none;border-radius:50%;background:var(--dsw-alias-bg-layer-1);box-shadow:inset 0 0 0 1px rgba(0,0,0,.12);display:grid;place-items:center;color:var(--dsw-alias-label-tertiary)}\n.dab-profile-meta{flex:1;min-width:0;display:flex;flex-direction:column;gap:1px}\n.dab-profile-name{font-size:12.5px;font-weight:600;color:var(--dsw-alias-label-primary);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n.dab-profile-sub{font-family:var(--dab-mono);font-size:10px;color:var(--dsw-alias-label-tertiary)}\n.dab-btn-confirm{background:var(--dsw-alias-state-error-primary)!important;color:#fff!important;border-color:transparent!important}\n.dab-select{height:32px;padding:0 10px;border-radius:9px;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-primary);font-size:12px;outline:none;cursor:pointer;max-width:180px}\n.dab-select:focus{border-color:var(--dsw-alias-brand-primary)}\n.dab-timeinput{height:32px;padding:0 8px;border-radius:9px;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-primary);font-family:var(--dab-mono);font-size:12px;outline:none}\n.dab-timeinput:focus{border-color:var(--dsw-alias-brand-primary)}\n/* Collapsible panel: animates grid-template-rows 0fr→1fr so the schedule\n block unfolds to its content height instead of popping in. visibility\n flips after the fold finishes (and instantly on open) so hidden inputs\n are never focusable. */\n.dab-schedule-wrap{display:grid;grid-template-rows:0fr;visibility:hidden;transition:grid-template-rows .42s cubic-bezier(.22,1,.36,1),visibility 0s linear .42s}\n.dab-schedule-wrap.is-open{grid-template-rows:1fr;visibility:visible;transition:grid-template-rows .42s cubic-bezier(.22,1,.36,1)}\n.dab-schedule-clip{overflow:hidden;min-height:0;opacity:0;transition:opacity .28s ease}\n.dab-schedule-wrap.is-open .dab-schedule-clip{opacity:1;transition:opacity .32s ease .1s}\n.dab-schedule-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(220px,100%),1fr));gap:16px;padding-top:12px}\n.dab-schedule-cell{min-width:0;animation:dab-row-in .34s cubic-bezier(.22,1,.36,1) both;animation-delay:calc(var(--i,0) * 60ms)}\n.dab-time-row{display:flex;flex-direction:column;gap:9px}\n.dab-time-label{display:flex;align-items:center;gap:7px;font-size:12px;color:var(--dsw-alias-label-secondary,var(--dsw-alias-label-tertiary))}\n.dab-time-label svg{color:var(--dsw-alias-brand-primary);flex:none}\n.dab-time-label .dab-select,.dab-time-label .dab-timeinput{flex:1;min-width:0}\n.dab-thumbstrip{display:flex;flex-wrap:wrap;gap:9px;margin-top:13px}\n.dab-thumb{position:relative;width:64px;height:44px;border-radius:9px;overflow:hidden;border:1.5px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);display:grid;place-items:center;color:var(--dsw-alias-label-tertiary);animation:dab-list-in .3s cubic-bezier(.22,1,.36,1) both}\n.dab-thumb.is-current{border-color:var(--dsw-alias-brand-primary);box-shadow:0 0 0 2px color-mix(in srgb,var(--dsw-alias-brand-primary) 25%,transparent)}\n.dab-thumb img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}\n.dab-thumb-x{position:absolute;top:2px;right:2px;width:16px;height:16px;border:0;border-radius:50%;background:rgba(0,0,0,.55);color:#fff;cursor:pointer;display:grid;place-items:center;opacity:0;transition:opacity .18s ease,background .18s ease;padding:0}\n.dab-thumb:hover .dab-thumb-x{opacity:1}\n.dab-thumb-x:hover{background:var(--dsw-alias-state-error-primary)}\n.dab-thumb-add{border-style:dashed;cursor:pointer;background:transparent;color:var(--dsw-alias-label-tertiary);font:inherit;transition:border-color .22s ease,color .22s ease}\n.dab-thumb-add:hover{border-color:var(--dsw-alias-brand-primary);color:var(--dsw-alias-brand-primary)}\n.dab-chip-sep{width:1px;height:18px;background:var(--dsw-alias-border-l2);margin:0 4px;flex:none}\n\n/* ── toast ───────────────────────────────────────────────────────────────── */\n.dab-toast{position:fixed;left:50%;bottom:30px;transform:translateX(-50%);display:flex;align-items:center;gap:8px;height:38px;padding:0 16px;border-radius:99px;background:var(--dsw-alias-bg-layer-3,var(--dsw-alias-bg-layer-2));border:1px solid var(--dsw-alias-border-l2);box-shadow:0 10px 30px -8px rgba(0,0,0,.38);font-size:12.5px;z-index:10001;animation:dab-toast-in .32s cubic-bezier(.22,1,.36,1) both}\n.dab-toast-ok{color:var(--dsw-alias-brand-primary);display:grid;place-items:center}\n.dab-toast-err{color:var(--dsw-alias-state-error-primary);display:grid;place-items:center}\n\n/* ── modals (editor / eyedropper / crash) ────────────────────────────────── */\n/* Pin to the viewport explicitly with vw/vh so ancestor padding/margins on\n * body cannot shift or clip the overlay; keep it above host sidebar chrome.\n * pointer-events:auto re-enables interaction: these overlays render inside a\n * Portal root that is pointer-events:none so it never blocks the page alone. */\n.dab-overlay{position:fixed;left:0;top:0;width:100vw;height:100vh;z-index:999999;background:rgba(8,10,14,.62);backdrop-filter:blur(8px);display:flex;flex-direction:column;align-items:center;justify-content:center;gap:14px;animation:dab-fade-in .25s ease both;pointer-events:auto}\n.dab-overlay-title{color:#fff;font-size:15px;font-weight:600}\n.dab-overlay-hint{color:rgba(255,255,255,.62);font-size:12px}\n.dab-modal-card{animation:dab-zoom-in .3s cubic-bezier(.22,1,.36,1) both;max-width:calc(100vw - 40px);max-height:calc(100vh - 120px);overflow:auto}\n.dab-overlay .dab-btn{background:rgba(255,255,255,.94);color:#14161a;border-color:transparent}\n.dab-overlay .dab-btn-primary{background:var(--dsw-alias-brand-primary);color:var(--dsw-alias-brand-text)}\n.dab-crash{display:flex;flex-direction:column;gap:10px;align-items:center;padding:28px 18px;border:1px solid var(--dsw-alias-border-l2);border-radius:16px}\n.dab-crash-title{font-size:15px;font-weight:650}\n.dab-crash-desc{font-size:12px;color:var(--dsw-alias-label-tertiary);text-align:center;line-height:1.5}\n/* The crash cause: readable, scrollable, and clipped to a few lines so a long\n * stack cannot push the reset button off the panel. */\n.dab-crash-detail{margin:0;max-width:min(520px,80vw);max-height:132px;overflow:auto;padding:8px 10px;border-radius:8px;background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);font-family:var(--dab-mono);font-size:10.5px;line-height:1.5;color:var(--dsw-alias-label-secondary,var(--dsw-alias-label-tertiary));text-align:left;white-space:pre-wrap;word-break:break-word}\n\n/* ── keyframes ───────────────────────────────────────────────────────────── */\n@keyframes dab-fade-in{from{opacity:0}to{opacity:1}}\n@keyframes dab-page-in{from{opacity:0;transform:translateY(12px)}to{opacity:1;transform:none}}\n@keyframes dab-rise-in{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}\n@keyframes dab-list-in{from{opacity:0;transform:translateY(-7px)}to{opacity:1;transform:none}}\n@keyframes dab-row-in{from{opacity:0;transform:translateY(6px) scale(.985)}to{opacity:1;transform:none}}\n@keyframes dab-type-in{from{opacity:0;transform:translateY(8px) scale(.97)}to{opacity:1;transform:none}}\n@keyframes dab-orb-in{from{opacity:0;transform:scale(.82)}to{opacity:1;transform:none}}\n@keyframes dab-spin{to{transform:rotate(360deg)}}\n@keyframes dab-rotate{to{transform:rotate(360deg)}}\n@keyframes dab-toast-in{from{opacity:0;transform:translate(-50%,10px)}to{opacity:1;transform:translate(-50%,0)}}\n@keyframes dab-zoom-in{from{opacity:0;transform:scale(.94) translateY(8px)}to{opacity:1;transform:none}}\n@keyframes dab-flow{to{background-position:300% 50%}}\n\n/* ── sidebar surface (a dsh-better-sidebar page) ─────────────────────────────\n * Same shell, hosted in a panel that is handed a full-height column (the host's\n * native tab body is height:100%) and whose width the user drags freely. So only\n * THREE things are fixed here, all of them structural:\n * 1. the shell fills the height and the page body owns the scroll\n * (flex:1 + min-height:0), so the panel stays one scrollable column instead\n * of pushing the whole tab into a scrollbar;\n * 2. the nav is a rail ABOVE the page rather than beside it — a side rail would\n * spend 150px of a panel that is narrow by nature, and this way the page\n * keeps the full width for its own grids;\n * 3. long tokens (paths, hex, URLs) may wrap instead of widening the panel.\n *\n * Everything else — grid columns, paddings, type scale, whether the cards lift on\n * hover — is width-driven through the container queries below, which measure this\n * shell (the .dab-root container, which declares container-type:inline-size) and\n * not the viewport. A narrow sidebar compacts; a wide one falls back to the\n * dialog's own spacing and multi-column grids, because at that point it *is* a\n * dialog-sized surface. */\n[data-dab-surface=\"sidebar\"].dab-root{height:100%;min-height:0;padding:12px 12px 0}\n[data-dab-surface=\"sidebar\"] .dab-shell{display:flex;flex-direction:column;align-items:stretch;gap:11px;height:100%;min-height:0;max-width:none;padding-bottom:0}\n[data-dab-surface=\"sidebar\"] .dab-nav{gap:0}\n[data-dab-surface=\"sidebar\"] .dab-nav-list{flex-direction:row;gap:2px;overflow-x:auto;overflow-y:hidden;padding-bottom:1px}\n[data-dab-surface=\"sidebar\"] .dab-nav-list::-webkit-scrollbar{display:none}\n[data-dab-surface=\"sidebar\"] .dab-nav-ind{display:none}\n[data-dab-surface=\"sidebar\"] .dab-nav-item{flex:none;height:32px;gap:7px;padding:0 10px;font-size:12px}\n[data-dab-surface=\"sidebar\"] .dab-nav-item.is-active{background:var(--dsw-alias-bg-layer-2)}\n[data-dab-surface=\"sidebar\"] .dab-page{flex:1;min-height:0;overflow-y:auto;overflow-x:hidden;padding-bottom:16px;scrollbar-width:thin}\n/* Last-resort safety for text that cannot wrap (paths, hex, URLs). */\n[data-dab-surface=\"sidebar\"] .dab-hint,[data-dab-surface=\"sidebar\"] .dab-part-name{overflow-wrap:anywhere}\n/* The panel's width is whatever the user dragged it to, so let the part cards\n * fill as many columns as actually fit instead of hard-coding one. 170px is the\n * narrowest a part card stays readable once its header can wrap (see the head\n * rules below), which puts the second column at roughly a 380px panel — the\n * default right-sidebar width. */\n[data-dab-surface=\"sidebar\"] .dab-grid-parts{grid-template-columns:repeat(auto-fill,minmax(min(170px,100%),1fr));gap:12px}\n[data-dab-surface=\"sidebar\"] .dab-types{grid-template-columns:repeat(auto-fit,minmax(min(150px,100%),1fr))}\n[data-dab-surface=\"sidebar\"] .dab-card{padding:12px}\n[data-dab-surface=\"sidebar\"] .dab-part-head{gap:8px;margin-bottom:10px}\n[data-dab-surface=\"sidebar\"] .dab-part-ico{width:26px;height:26px;border-radius:8px}\n[data-dab-surface=\"sidebar\"] .dab-part-name{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:12.5px}\n[data-dab-surface=\"sidebar\"] .dab-part-badge{padding:2px 7px;font-size:10px}\n\n/* Narrow panel: tighten the chrome so the content still has room. */\n@container (max-width:539px){\n [data-dab-surface=\"sidebar\"] .dab-page{gap:11px}\n [data-dab-surface=\"sidebar\"] .dab-h1{font-size:17px}\n [data-dab-surface=\"sidebar\"] .dab-desc{font-size:12px}\n [data-dab-surface=\"sidebar\"] .dab-orb-wrap{width:96px;height:96px}\n [data-dab-surface=\"sidebar\"] .dab-wheel-card{padding:14px 10px;gap:16px}\n [data-dab-surface=\"sidebar\"] .dab-wheel-glow{width:170px;height:170px}\n /* Lift-on-hover is a dialog affordance; in a cramped scrolling panel it only\n * adds jitter under the cursor. */\n [data-dab-surface=\"sidebar\"] .dab-card-hover:hover{transform:none;box-shadow:none}\n}\n/* Roomy panel: behave like the dialog again — its spacing, its type scale, and\n * multi-column grids (a smaller track minimum than the dialog, because the page\n * here is a few hundred px narrower than a dialog's content column). */\n@container (min-width:540px){\n [data-dab-surface=\"sidebar\"] .dab-shell{gap:16px}\n [data-dab-surface=\"sidebar\"] .dab-page{gap:13px}\n [data-dab-surface=\"sidebar\"] .dab-nav-item{height:34px;font-size:12.5px;padding:0 12px}\n /* The shared ≤620px rule flattens the type cards to one column, which is right\n * for a narrow phone-width dialog but wasteful in a roomy panel. */\n [data-dab-surface=\"sidebar\"] .dab-types{grid-template-columns:repeat(auto-fit,minmax(180px,1fr))}\n}\n\n/* ── responsive & motion preferences ─────────────────────────────────────── */\n@container (max-width:620px){\n .dab-shell{grid-template-columns:1fr;gap:14px}\n .dab-nav{position:static;flex-direction:row;align-items:center;justify-content:space-between;gap:10px}\n .dab-nav-list{flex-direction:row;overflow-x:auto;scrollbar-width:none}\n .dab-nav-list::-webkit-scrollbar{display:none}\n .dab-nav-ind{display:none}\n .dab-nav-item{flex:none;padding:0 10px}\n .dab-nav-item.is-active{background:var(--dsw-alias-bg-layer-2)}\n .dab-types{grid-template-columns:1fr}\n}\n@container (min-width:621px){\n .dab-shell{grid-template-columns:158px minmax(0,1fr);gap:26px}\n}\n/* Phone: on a handset the settings dialog's content column shrinks to roughly\n * the viewport, and the dialog-sized chrome (18px cards, 21px headings, a 118px\n * orb, 24px paddings) stops fitting — cards end up wider than the column or the\n * color row wraps into three cramped pieces. These are the same tightenings the\n * sidebar surface applies at its own narrow widths, so a phone settings dialog\n * and a narrow sidebar panel end up looking the same. */\n@container (max-width:480px){\n .dab-shell{gap:10px}\n .dab-page{gap:10px}\n .dab-head{margin:0 0 2px}\n .dab-h1{font-size:18px}\n .dab-desc{font-size:12px}\n .dab-card{padding:14px;border-radius:14px}\n .dab-hero-accent{gap:16px}\n .dab-orb-wrap{width:92px;height:92px}\n .dab-wheel-card{padding:14px 10px;gap:16px}\n .dab-wheel-glow{width:180px;height:180px}\n /* Three fixed type-card columns need ~400px; two adaptive ones fit 320px. */\n .dab-types{grid-template-columns:repeat(auto-fit,minmax(min(150px,100%),1fr))}\n .dab-grid-parts{gap:11px}\n .dab-part-head{margin-bottom:10px}\n .dab-slider-block + .dab-slider-block{margin-top:10px}\n .dab-footer{padding-top:10px}\n}\n@media (prefers-reduced-motion:reduce){\n .dab-root *,.dab-root *::before,.dab-root *::after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}\n}\n`\n\nconst CSS_ID = 'dab-ui-css'\n\n/** Inject the design-system stylesheet once per document (HMR-safe). */\nexport function ensureUiCss(): void {\n if (typeof document === 'undefined') return\n let el = document.getElementById(CSS_ID) as HTMLStyleElement | null\n if (!el) {\n el = document.createElement('style')\n el.id = CSS_ID\n // Self-claim it. Through `0.2.0-rc.2` the host's module system stamped\n // `data-plugin` on EVERY untagged `<style>` that existed when a plugin factory\n // materialized, so an untagged sheet injected later (this one is injected by the\n // settings page, not by the module factory) was handed to whichever plugin ran\n // next and deleted when that plugin errored or was disposed. `0.2.1-alpha.1`\n // narrowed the claim to tags the factory itself added; the attribute makes the\n // sheet safe on both.\n el.dataset.plugin = 'dsh-any-background-ui-css'\n document.head.appendChild(el)\n }\n if (el.textContent !== UI_CSS) el.textContent = UI_CSS\n}\n","import type { ReactNode } from 'react'\r\n\r\n/** Sun glyph, migrated from @deepseek-ai/dsh-client-ui-primitives IconLightOutline16. */\r\nexport const SUN_PATHS = '<path d=\"M11.3496 8C11.3496 6.14985 9.85015 4.65039 8 4.65039C6.14985 4.65039 4.65039 6.14985 4.65039 8C4.65039 9.85015 6.14985 11.3496 8 11.3496C9.85015 11.3496 11.3496 9.85015 11.3496 8ZM12.6504 8C12.6504 10.5681 10.5681 12.6504 8 12.6504C5.43188 12.6504 3.34961 10.5681 3.34961 8C3.34961 5.43188 5.43188 3.34961 8 3.34961C10.5681 3.34961 12.6504 5.43188 12.6504 8Z\" fill=\"currentColor\"/><path d=\"M8.65039 0.5V2.5H7.34961V0.5H8.65039Z\" fill=\"currentColor\"/><path d=\"M8.65039 13.5V15.5H7.34961V13.5H8.65039Z\" fill=\"currentColor\"/><path d=\"M3.15808 2.24035L4.57229 3.65456L3.6525 4.57435L2.23829 3.16014L3.15808 2.24035Z\" fill=\"currentColor\"/><path d=\"M12.3505 11.4327L13.7647 12.8469L12.8449 13.7667L11.4307 12.3525L12.3505 11.4327Z\" fill=\"currentColor\"/><path d=\"M2.24537 12.8469L3.65958 11.4327L4.57937 12.3525L3.16516 13.7667L2.24537 12.8469Z\" fill=\"currentColor\"/><path d=\"M11.4377 3.65455L12.852 2.24033L13.7718 3.16012L12.3575 4.57434L11.4377 3.65455Z\" fill=\"currentColor\"/><path d=\"M0.5 7.35461H2.5V8.6554H0.5L0.5 7.35461Z\" fill=\"currentColor\"/><path d=\"M13.5 7.35461H15.5V8.6554H13.5V8.6554Z\" fill=\"currentColor\"/>'\r\n\r\nexport function SunIcon({ size = 16, className }: { size?: number; className?: string }) {\r\n return (\r\n <svg width={size} height={size} className={className} viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" dangerouslySetInnerHTML={{ __html: SUN_PATHS }} />\r\n )\r\n}\r\n\r\nfunction Glyph({ children, size = 16, className }: { children: ReactNode; size?: number; className?: string }) {\r\n return (\r\n <svg width={size} height={size} className={className} viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\" strokeWidth={1.5} strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\">\r\n {children}\r\n </svg>\r\n )\r\n}\r\n\r\nexport const DropletIcon = ({ size, className }: { size?: number; className?: string }) => (\r\n <Glyph size={size} className={className}><path d=\"M8 1.9c2.4 2.8 4.3 5 4.3 7.1a4.3 4.3 0 1 1-8.6 0C3.7 6.9 5.6 4.7 8 1.9z\" /></Glyph>\r\n)\r\n\r\nexport const LayersIcon = ({ size, className }: { size?: number; className?: string }) => (\r\n <Glyph size={size} className={className}><path d=\"M8 2.2 13.2 5 8 7.8 2.8 5 8 2.2z\" /><path d=\"M2.8 8.2 8 11l5.2-2.8\" /><path d=\"M2.8 11.2 8 14l5.2-2.8\" /></Glyph>\r\n)\r\n\r\nexport const PhotoIcon = ({ size, className }: { size?: number; className?: string }) => (\r\n <Glyph size={size} className={className}><rect x=\"2\" y=\"3.2\" width=\"12\" height=\"9.6\" rx=\"2\" /><circle cx=\"5.7\" cy=\"6.3\" r=\"0.9\" /><path d=\"M14 10.4l-2.8-2.8-4.8 4.8\" /></Glyph>\r\n)\r\n\r\nexport const VideoIcon = ({ size, className }: { size?: number; className?: string }) => (\r\n <Glyph size={size} className={className}><rect x=\"1.5\" y=\"4.2\" width=\"8.8\" height=\"7.6\" rx=\"2\" /><path d=\"M10.3 6.9l4.2-2.4v7l-4.2-2.4\" /></Glyph>\r\n)\r\n\r\nexport const TextIcon = ({ size, className }: { size?: number; className?: string }) => (\r\n <Glyph size={size} className={className}><path d=\"M3 4.2h10M3 8h10M3 11.8h6.5\" /></Glyph>\r\n)\r\n\r\nexport const TrajectoryIcon = ({ size, className }: { size?: number; className?: string }) => (\r\n <Glyph size={size} className={className}><path d=\"M2.5 3.2h11M2.5 6.6h11M2.5 10h11\" /><circle cx=\"4.4\" cy=\"3.2\" r=\"1.1\" /><circle cx=\"8\" cy=\"6.6\" r=\"1.1\" /><circle cx=\"11.4\" cy=\"10\" r=\"1.1\" /></Glyph>\r\n)\r\n\r\n/** Bottom workbench panel (dsh-better-sidebar): a window with a docked strip. */\r\nexport const PanelIcon = ({ size, className }: { size?: number; className?: string }) => (\r\n <Glyph size={size} className={className}><path d=\"M2.4 2.7h11.2v10.6H2.4z\" /><path d=\"M2.4 10.1h11.2\" /></Glyph>\r\n)\r\n\r\nexport const SlidersIcon = ({ size, className }: { size?: number; className?: string }) => (\r\n <Glyph size={size} className={className}><path d=\"M2.5 4.5h4.9M11.6 4.5h1.9M2.5 11.5h1.9M8.6 11.5h4.9\" /><circle cx=\"9.5\" cy=\"4.5\" r=\"1.7\" /><circle cx=\"5.5\" cy=\"11.5\" r=\"1.7\" /></Glyph>\r\n)\r\n\r\nexport const SparkleIcon = ({ size, className }: { size?: number; className?: string }) => (\r\n <Glyph size={size} className={className}><path d=\"M7.2 1.8l1.2 3.1 3.1 1.2-3.1 1.2-1.2 3.1-1.2-3.1L2.9 6.1 6 4.9l1.2-3.1z\" /><path d=\"M12 10.5l.5 1.2 1.2.5-1.2.5-.5 1.2-.5-1.2-1.2-.5 1.2-.5.5-1.2z\" /></Glyph>\r\n)\r\n\r\nexport const RefreshIcon = ({ size, className }: { size?: number; className?: string }) => (\r\n <Glyph size={size} className={className}><path d=\"M13.2 8A5.2 5.2 0 1 1 11.5 4.2\" /><path d=\"M13.4 1.8v2.9h-2.9\" /></Glyph>\r\n)\r\n\r\nexport const DownloadIcon = ({ size, className }: { size?: number; className?: string }) => (\r\n <Glyph size={size} className={className}><path d=\"M8 2.2v8\" /><path d=\"M4.6 7l3.4 3.4L11.4 7\" /><path d=\"M2.8 13.8h10.4\" /></Glyph>\r\n)\r\n\r\nexport const UploadIcon = ({ size, className }: { size?: number; className?: string }) => (\r\n <Glyph size={size} className={className}><path d=\"M8 10.4V2.6\" /><path d=\"M4.6 5.8L8 2.4l3.4 3.4\" /><path d=\"M2.8 13.8h10.4\" /></Glyph>\r\n)\r\n\r\nexport const LinkIcon = ({ size, className }: { size?: number; className?: string }) => (\r\n <Glyph size={size} className={className}><path d=\"M6.6 9.4 9.4 6.6\" /><path d=\"M5.9 11.1l-1.4 1.4a2.6 2.6 0 0 1-3.7-3.7L3.5 6.8\" /><path d=\"M10.1 4.9l1.4-1.4a2.6 2.6 0 0 1 3.7 3.7l-2.1 2.1\" /></Glyph>\r\n)\r\n\r\nexport const LockIcon = ({ size, className }: { size?: number; className?: string }) => (\r\n <Glyph size={size} className={className}><rect x=\"3.6\" y=\"7.2\" width=\"8.8\" height=\"6\" rx=\"1.4\" /><path d=\"M5.6 7.2V5.4a2.4 2.4 0 0 1 4.8 0v1.8\" /></Glyph>\r\n)\r\n\r\nexport const TrashIcon = ({ size, className }: { size?: number; className?: string }) => (\r\n <Glyph size={size} className={className}><path d=\"M2.8 4.4h10.4\" /><path d=\"M6.4 4.4V2.9h3.2v1.5\" /><path d=\"M4.4 4.4l.5 8.6h6.2l.5-8.6\" /></Glyph>\r\n)\r\n\r\nexport const EditIcon = ({ size, className }: { size?: number; className?: string }) => (\r\n <Glyph size={size} className={className}><path d=\"M9.5 4l2.5 2.5\" /><path d=\"M3 13l.8-3L10 3.8 12.2 6 6 12.2 3 13z\" /></Glyph>\r\n)\r\n\r\nexport const PipetteIcon = ({ size, className }: { size?: number; className?: string }) => (\r\n <Glyph size={size} className={className}><circle cx=\"8\" cy=\"8\" r=\"4.2\" /><path d=\"M8 1.6v2.6M8 11.8v2.6M1.6 8h2.6M11.8 8h2.6\" /></Glyph>\r\n)\r\n\r\nexport const CheckIcon = ({ size, className }: { size?: number; className?: string }) => (\r\n <Glyph size={size} className={className}><path d=\"M3.2 8.6l3 3L12.8 5\" /></Glyph>\r\n)\r\n\r\nexport const AlertIcon = ({ size, className }: { size?: number; className?: string }) => (\r\n <Glyph size={size} className={className}><path d=\"M8 2.6l5.4 9.8H2.6L8 2.6z\" /><path d=\"M8 6.8v2.4M8 11.4v.01\" /></Glyph>\r\n)\r\n\r\nexport const CanvasIcon = ({ size, className }: { size?: number; className?: string }) => (\r\n <Glyph size={size} className={className}><rect x=\"2.2\" y=\"2.2\" width=\"11.6\" height=\"11.6\" rx=\"2\" /></Glyph>\r\n)\r\n\r\nexport const SidebarIcon = ({ size, className }: { size?: number; className?: string }) => (\r\n <Glyph size={size} className={className}><rect x=\"2.2\" y=\"2.2\" width=\"11.6\" height=\"11.6\" rx=\"2\" /><path d=\"M6.6 2.2v11.6\" /></Glyph>\r\n)\r\n\r\nexport const ChatIcon = ({ size, className }: { size?: number; className?: string }) => (\r\n <Glyph size={size} className={className}><path d=\"M13.4 4.4v4.4a2 2 0 0 1-2 2H6.2l-3.6 3V4.4a2 2 0 0 1 2-2h6.8a2 2 0 0 1 2 2z\" /></Glyph>\r\n)\r\n\r\nexport const GearIcon = ({ size, className }: { size?: number; className?: string }) => (\r\n <Glyph size={size} className={className}><circle cx=\"8\" cy=\"8\" r=\"2.1\" /><path d=\"M8 1.7v1.8M8 12.5v1.8M1.7 8h1.8M12.5 8h1.8M3.6 3.6l1.3 1.3M11.1 11.1l1.3 1.3M12.4 3.6l-1.3 1.3M4.9 11.1l-1.3 1.3\" /></Glyph>\r\n)\r\n\r\nexport const InputIcon = ({ size, className }: { size?: number; className?: string }) => (\r\n <Glyph size={size} className={className}><rect x=\"2.2\" y=\"4\" width=\"11.6\" height=\"8\" rx=\"2\" /><path d=\"M8 6.6v2M7 8h2\" /></Glyph>\r\n)\r\n\r\nexport const PlusIcon = ({ size, className }: { size?: number; className?: string }) => (\r\n <Glyph size={size} className={className}><path d=\"M8 3v10M3 8h10\" /></Glyph>\r\n)\r\n\r\nexport const MoonIcon = ({ size, className }: { size?: number; className?: string }) => (\r\n <Glyph size={size} className={className}><path d=\"M13.2 9.6A5.6 5.6 0 0 1 6.4 2.8a5.6 5.6 0 1 0 6.8 6.8z\" /></Glyph>\r\n)\r\n\r\nexport const ClockIcon = ({ size, className }: { size?: number; className?: string }) => (\r\n <Glyph size={size} className={className}><circle cx=\"8\" cy=\"8\" r=\"5.8\" /><path d=\"M8 4.8V8l2.2 1.6\" /></Glyph>\r\n)\r\n\r\nexport const XIcon = ({ size, className }: { size?: number; className?: string }) => (\r\n <Glyph size={size} className={className}><path d=\"M4 4l8 8M12 4l-8 8\" /></Glyph>\r\n)\r\n\r\n/** Letterform glyph: a stroked capital A (the font/type page + nav entry). */\r\nexport const FontIcon = ({ size, className }: { size?: number; className?: string }) => (\r\n <Glyph size={size} className={className}><path d=\"M4 12.2 8 3.8l4 8.4\" /><path d=\"M5.6 9.6h4.8\" /></Glyph>\r\n)\r\n\r\nexport const PlayIcon = ({ size, className }: { size?: number; className?: string }) => (\r\n <Glyph size={size} className={className}><path d=\"M5.2 3.4l7.4 4.6-7.4 4.6V3.4z\" /></Glyph>\r\n)\r\n\r\nexport const PauseIcon = ({ size, className }: { size?: number; className?: string }) => (\r\n <Glyph size={size} className={className}><path d=\"M5.4 3.4v9.2M10.6 3.4v9.2\" /></Glyph>\r\n)\r\n\r\n","import { Component, type ReactNode } from 'react'\n\ninterface Props {\n t: (key: string) => string\n onReset?: () => void\n children: ReactNode\n}\n\ninterface State {\n error: Error | null\n}\n\n/**\n * Catches render errors from the theme section subtree (wheel, sliders, editor)\n * so a single bad state can never take down the whole settings panel. Shows a\n * compact fallback with a reset button; the reset re-renders the section with\n * the current saved config, which is enough to recover from most transient\n * failures (corrupt transient UI state, stale image decode, etc.).\n */\nexport class ErrorBoundary extends Component<Props, State> {\n override state: State = { error: null }\n\n static getDerivedStateFromError(error: Error): State {\n return { error }\n }\n\n override componentDidCatch(error: Error, info: { componentStack?: string | null }): void {\n console.error('dsh-any-background: section render crashed', error, info.componentStack)\n }\n\n private reset = (): void => {\n this.setState({ error: null })\n this.props.onReset?.()\n }\n\n override render() {\n if (this.state.error) {\n // Show the cause, not just the apology. The host's own console holds the\n // full stack, but a plugin that repaints the settings panel has no other\n // way to tell the user why it went blank — and \"please open devtools\" is a\n // poor answer to \"it crashed\".\n const detail = this.state.error.stack ?? `${this.state.error.name}: ${this.state.error.message}`\n return (\n <div className=\"dab-crash\">\n <div className=\"dab-crash-title\">{this.props.t('crashTitle')}</div>\n <div className=\"dab-crash-desc\">{this.props.t('crashDesc')}</div>\n <pre className=\"dab-crash-detail\">{detail}</pre>\n <button type=\"button\" className=\"dab-btn\" onClick={this.reset}>{this.props.t('crashReset')}</button>\n </div>\n )\n }\n return this.props.children\n }\n}\n","import { useEffect, useState } from 'react'\nimport type { ReactNode } from 'react'\nimport { createPortal } from 'react-dom'\n\n/**\n * Render children into a fixed root attached to document.documentElement.\n *\n * The host's sidebar is often implemented by translating the body or a wrapper\n * (margin-left / transform). A fixed element portaled to body would still be\n * captured by that transformed ancestor and shift with the sidebar. Attaching\n * the portal root directly to <html> escapes body-level transforms so the\n * overlay is always painted relative to the viewport and centered correctly.\n */\nexport function Portal({ children }: { children: ReactNode }) {\n const [target, setTarget] = useState<HTMLElement | null>(null)\n useEffect(() => {\n const el = document.createElement('div')\n el.dataset.dabPortal = '1'\n el.style.cssText = 'position:fixed;inset:0;pointer-events:none;z-index:999999'\n document.documentElement.appendChild(el)\n setTarget(el)\n return () => { el.remove() }\n }, [])\n return target ? createPortal(children, target) : null\n}\n","import { useRef, useState, useEffect, useCallback, memo } from 'react'\n\nconst WHEEL_SIZE = 220\nconst CX = WHEEL_SIZE / 2\nconst RING_OUTER = 106\nconst RING_INNER = 82\n// Square inscribed in the ring's inner circle: half-side = RING_INNER / √2,\n// so the four corners sit exactly on the inner edge of the hue ring. The\n// exact (un-rounded) value keeps the corners tangent to the ring — a rounded\n// half-side would push the diagonals past the ring's inner boundary.\nconst SQ_HALF = RING_INNER / Math.SQRT2\n\n/** Static hue ring cached once across all wheels. */\nlet ringCache: HTMLCanvasElement | null = null\nfunction getRingCache(): HTMLCanvasElement {\n if (ringCache) return ringCache\n const cvs = document.createElement('canvas')\n cvs.width = WHEEL_SIZE; cvs.height = WHEEL_SIZE\n const c = cvs.getContext('2d')!\n // Instead of 360 separate arc paths, use a single conic gradient clipped to\n // the ring. This removes per-frame path overhead and anti-aliasing gaps.\n const g = c.createConicGradient(0, CX, CX)\n for (let i = 0; i <= 360; i++) g.addColorStop(i / 360, `hsl(${i},100%,50%)`)\n c.beginPath()\n c.arc(CX, CX, RING_OUTER, 0, Math.PI * 2)\n c.arc(CX, CX, RING_INNER, 0, Math.PI * 2, true)\n c.fillStyle = g\n c.fill()\n ringCache = cvs\n return ringCache\n}\n\nfunction drawMarkers(ctx: CanvasRenderingContext2D, hue: number, sat: number, lit: number): void {\n // Hue marker on ring. Canvas math angles (0 = +x / \"3 o'clock\", positive =\n // toward +y) directly match the conic-gradient hue distribution drawn in\n // getRingCache (colorStop i/360 → hsl(i)), so NO extra ±90° shift is applied.\n // A shift would rotate the picker's indication 90° away from the rendered\n // gradient (e.g. picking the top of the wheel would report red while the\n // pixels there are blue). hue 0 sits at the right edge, +90° at the bottom.\n const hRad = hue * Math.PI / 180\n const hR = (RING_OUTER + RING_INNER) / 2\n const hmx = CX + Math.cos(hRad) * hR\n const hmy = CX + Math.sin(hRad) * hR\n ctx.beginPath(); ctx.arc(hmx, hmy, 8, 0, Math.PI * 2)\n ctx.fillStyle = 'rgba(0,0,0,0.25)'; ctx.fill()\n ctx.beginPath(); ctx.arc(hmx, hmy, 6.5, 0, Math.PI * 2)\n ctx.strokeStyle = '#fff'; ctx.lineWidth = 2; ctx.stroke()\n\n // SL marker (HSV coordinates)\n const gx = CX - SQ_HALF, gy = CX - SQ_HALF, sz = SQ_HALF * 2\n const smx = gx + sat * sz\n const smy = gy + (1 - lit) * sz\n ctx.beginPath(); ctx.arc(smx, smy, 7, 0, Math.PI * 2)\n ctx.fillStyle = 'rgba(0,0,0,0.25)'; ctx.fill()\n ctx.beginPath(); ctx.arc(smx, smy, 5.5, 0, Math.PI * 2)\n ctx.strokeStyle = '#fff'; ctx.lineWidth = 2; ctx.stroke()\n ctx.beginPath(); ctx.arc(smx, smy, 3.5, 0, Math.PI * 2)\n ctx.strokeStyle = '#000'; ctx.lineWidth = 1; ctx.stroke()\n}\n\nfunction drawSquare(c: CanvasRenderingContext2D, hue: number): void {\n const gx = CX - SQ_HALF, gy = CX - SQ_HALF, sz = SQ_HALF * 2\n c.clearRect(gx - 1, gy - 1, sz + 2, sz + 2)\n c.fillStyle = '#fff'; c.fillRect(gx, gy, sz, sz)\n const gh = c.createLinearGradient(gx, 0, gx + sz, 0)\n gh.addColorStop(0, 'rgba(255,255,255,1)'); gh.addColorStop(1, `hsl(${hue},100%,50%)`)\n c.fillStyle = gh; c.fillRect(gx, gy, sz, sz)\n const gv = c.createLinearGradient(0, gy, 0, gy + sz)\n gv.addColorStop(0, 'rgba(0,0,0,0)'); gv.addColorStop(1, 'rgba(0,0,0,1)')\n c.fillStyle = gv; c.fillRect(gx, gy, sz, sz)\n}\n\nfunction hitTest(x: number, y: number): 'ring' | 'square' | null {\n if (Math.abs(x - CX) <= SQ_HALF && Math.abs(y - CX) <= SQ_HALF) return 'square'\n const dx = x - CX, dy = y - CX\n const dist = Math.sqrt(dx * dx + dy * dy)\n if (dist >= RING_INNER - 4 && dist <= RING_OUTER + 4) return 'ring'\n return null\n}\n\nfunction pickHue(x: number, y: number): number {\n // Inverse of drawMarkers: no ±90° shift, matching the conic gradient exactly.\n let angle = Math.atan2(y - CX, x - CX) * 180 / Math.PI\n if (angle < 0) angle += 360\n return angle\n}\n\nfunction pickSL(x: number, y: number): [number, number] {\n const gx = CX - SQ_HALF, gy = CX - SQ_HALF, sz = SQ_HALF * 2\n return [\n Math.max(0, Math.min(1, (x - gx) / sz)),\n Math.max(0.02, Math.min(0.98, 1 - (y - gy) / sz)),\n ]\n}\n\nexport const ColorWheel = memo(function ColorWheel({ hue, sat, lit, onChange }: {\n hue: number; sat: number; lit: number\n onChange: (h: number, s: number, l: number) => void\n}) {\n const cvsRef = useRef<HTMLCanvasElement>(null)\n const [col, setCol] = useState({ hue, sat, lit })\n const colRef = useRef(col)\n colRef.current = col\n\n // Adopt external changes (e.g. section remount after theme restore).\n useEffect(() => {\n setCol(c => (c.hue === hue && c.sat === sat && c.lit === lit ? c : { hue, sat, lit }))\n }, [hue, sat, lit])\n\n // Redraw only what changed. The static ring is copied from cache; the square\n // only redraws when hue changes; markers redraw on every value change.\n useEffect(() => {\n const cvs = cvsRef.current\n if (!cvs) return\n const ctx = cvs.getContext('2d')!\n ctx.clearRect(0, 0, WHEEL_SIZE, WHEEL_SIZE)\n // Draw the square first, then the ring on top: the ring's opaque pixels\n // cover the square's four corners (which are tangent to the ring's inner\n // edge), so the corners no longer visually overlap the hue ring.\n drawSquare(ctx, col.hue)\n ctx.drawImage(getRingCache(), 0, 0)\n drawMarkers(ctx, col.hue, col.sat, col.lit)\n }, [col])\n\n // Batch pointer updates in a single rAF so rapid mousemove events do not\n // trigger a React state flush + onChange on every pixel.\n const pendingRef = useRef<{ h: number; s: number; l: number } | null>(null)\n const rafRef = useRef<number | null>(null)\n /** Unmount-time cleanup for a drag that never saw its mouseup (panel closed\n * mid-drag): without it the document listeners stay attached forever and the\n * pending rAF keeps calling setState on a dead component. */\n const dragCleanupRef = useRef<(() => void) | null>(null)\n const flushPending = useCallback(() => {\n rafRef.current = null\n const p = pendingRef.current\n if (!p) return\n pendingRef.current = null\n setCol({ hue: p.h, sat: p.s, lit: p.l })\n onChange(p.h, p.s, p.l)\n }, [onChange])\n\n const schedule = useCallback((h: number, s: number, l: number) => {\n pendingRef.current = { h, s, l }\n if (rafRef.current === null) rafRef.current = requestAnimationFrame(flushPending)\n }, [flushPending])\n\n const onDown = useCallback((e: React.MouseEvent<HTMLCanvasElement>) => {\n const r = cvsRef.current!.getBoundingClientRect()\n const x = e.clientX - r.left, y = e.clientY - r.top\n const region = hitTest(x, y)\n if (!region) return\n if (region === 'ring') {\n schedule(pickHue(x, y), colRef.current.sat, colRef.current.lit)\n } else {\n const [s, l] = pickSL(x, y)\n schedule(colRef.current.hue, s, l)\n }\n const onMove = (ev: MouseEvent) => {\n const rr = cvsRef.current!.getBoundingClientRect()\n const mx = ev.clientX - rr.left, my = ev.clientY - rr.top\n if (region === 'ring') {\n const d = Math.sqrt((mx - CX) ** 2 + (my - CX) ** 2)\n if (d >= RING_INNER - 10 && d <= RING_OUTER + 10) schedule(pickHue(mx, my), colRef.current.sat, colRef.current.lit)\n } else {\n const [s, l] = pickSL(mx, my)\n schedule(colRef.current.hue, s, l)\n }\n }\n const stopDrag = () => {\n document.removeEventListener('mousemove', onMove)\n document.removeEventListener('mouseup', stopDrag)\n dragCleanupRef.current = null\n }\n dragCleanupRef.current = stopDrag\n document.addEventListener('mousemove', onMove); document.addEventListener('mouseup', stopDrag)\n }, [schedule])\n\n // Cancel the pending rAF and any live drag listeners on unmount (see\n // dragCleanupRef above): a drag ended by closing the panel never fires mouseup.\n useEffect(() => {\n return () => {\n if (rafRef.current !== null) { cancelAnimationFrame(rafRef.current); rafRef.current = null }\n pendingRef.current = null\n dragCleanupRef.current?.()\n }\n }, [])\n\n return <canvas ref={cvsRef} width={WHEEL_SIZE} height={WHEEL_SIZE} className=\"dab-wheel\" onMouseDown={onDown} />\n})\n","import { useState, useEffect, useRef } from 'react'\nimport type { CSSProperties } from 'react'\nimport { hsvToHsl, hslToRgb, rgbToHsl, hslToHsv } from '../utils/color'\n\ntype Mode = 'hsl' | 'rgb'\n\nconst SEG_W = 66\n\nfunction clamp(v: number, min: number, max: number): number {\n return Math.min(max, Math.max(min, v))\n}\n\n/**\n * A single numeric field that edits one color channel. Keeps its own text\n * while focused so typing never gets clobbered by the parent re-rendering the\n * canonical value; commits every valid keystroke live and re-normalizes on\n * blur. The value prop only pushes back in when the field is not focused\n * (wheel drags, wallpaper extraction, mode switches).\n */\nfunction NumField({ label, value, min, max, step, onChange }: {\n label: string; value: number; min: number; max: number; step: number\n onChange: (v: number) => void\n}) {\n const [text, setText] = useState(String(value))\n const focused = useRef(false)\n\n useEffect(() => {\n if (!focused.current) setText(String(value))\n }, [value])\n\n return (\n <label className=\"dab-field\">\n <span className=\"dab-field-label\">{label}</span>\n <input\n type=\"number\"\n min={min} max={max} step={step}\n value={text}\n className=\"dab-num\"\n onFocus={() => { focused.current = true }}\n onBlur={() => { focused.current = false; setText(String(value)) }}\n onChange={e => {\n setText(e.target.value)\n // An emptied field is Number('') === 0 — a finite value — so without\n // this guard clearing the box for a moment would commit the channel\n // to its minimum and yank the color under the user's fingers.\n if (e.target.value === '') return\n const v = Number(e.target.value)\n if (Number.isFinite(v)) onChange(clamp(v, min, max))\n }}\n />\n </label>\n )\n}\n\n/**\n * Precise color entry next to the wheel: a HSL/RGB segmented toggle plus three\n * numeric channel fields and a live swatch. The wheel is HSV end-to-end, so\n * this panel converts at the boundary — HSL fields map straight onto the\n * stored HSL, RGB fields round-trip through rgbToHsl — and both emit HSV via\n * the same onChange the wheel uses, keeping one canonical color.\n */\nexport function ColorInputs({ hue, sat, lit, onChange }: {\n hue: number; sat: number; lit: number\n onChange: (h: number, s: number, l: number) => void\n}) {\n const [mode, setMode] = useState<Mode>('hsl')\n const [h, s, l] = hsvToHsl(hue, sat, lit)\n const [r, g, b] = hslToRgb(h, s, l)\n\n const setHsl = (nh: number, ns: number, nl: number) => onChange(...hslToHsv(nh, ns, nl))\n const setRgb = (nr: number, ng: number, nb: number) => {\n const [nh, ns, nl] = rgbToHsl(nr, ng, nb)\n onChange(...hslToHsv(nh, ns, nl))\n }\n\n return (\n <div className=\"dab-inputs\">\n <div className=\"dab-seg\" style={{ '--w': `${SEG_W}px` } as CSSProperties}>\n <div className=\"dab-seg-thumb\" style={{ transform: `translateX(${mode === 'hsl' ? 0 : SEG_W}px)` }} />\n <button type=\"button\" className={`dab-seg-item${mode === 'hsl' ? ' is-active' : ''}`} onClick={() => setMode('hsl')}>HSL</button>\n <button type=\"button\" className={`dab-seg-item${mode === 'rgb' ? ' is-active' : ''}`} onClick={() => setMode('rgb')}>RGB</button>\n </div>\n <div style={{ display: 'flex', flexDirection: 'column', gap: 7 }}>\n {mode === 'hsl' ? (\n <>\n <NumField label=\"H\" value={Math.round(h)} min={0} max={360} step={1} onChange={v => setHsl(v, s, l)} />\n <NumField label=\"S\" value={Math.round(s * 100)} min={0} max={100} step={1} onChange={v => setHsl(h, v / 100, l)} />\n <NumField label=\"L\" value={Math.round(l * 100)} min={0} max={100} step={1} onChange={v => setHsl(h, s, v / 100)} />\n </>\n ) : (\n <>\n <NumField label=\"R\" value={r} min={0} max={255} step={1} onChange={v => setRgb(v, g, b)} />\n <NumField label=\"G\" value={g} min={0} max={255} step={1} onChange={v => setRgb(r, v, b)} />\n <NumField label=\"B\" value={b} min={0} max={255} step={1} onChange={v => setRgb(r, g, v)} />\n </>\n )}\n </div>\n <div className=\"dab-swatch-lg\" style={{ background: `hsl(${Math.round(h)} ${Math.round(s * 100)}% ${Math.round(l * 100)}%)` }} />\n </div>\n )\n}\n","import { useRef, useState, useEffect, useCallback } from 'react'\nimport { rgbToHsl, hslToHsv, rgbToHex } from '../utils/color'\nimport { Portal } from './Portal'\n\nconst MAG_SIZE = 96\nconst MAG_ZOOM = 8\n\n/**\n * Eyedropper modal: shows the wallpaper full-bleed (no drag/zoom) and lets the\n * user click any pixel to adopt it as the theme color. A magnifier circle\n * follows the cursor so small details can be picked precisely. The wallpaper\n * is a data URL, so sampling is CORS-free: draw it once to an offscreen-sized\n * canvas and read pixels via getImageData.\n */\nexport function ColorPicker({ url, t, onPick, onClose }: {\n url: string\n t: (key: string) => string\n onPick: (hsv: [number, number, number]) => void\n onClose: () => void\n}) {\n const canvasRef = useRef<HTMLCanvasElement>(null)\n const magRef = useRef<HTMLCanvasElement>(null)\n const imgRef = useRef<HTMLImageElement | null>(null)\n const [ready, setReady] = useState(false)\n const [hover, setHover] = useState<{ rgb: [number, number, number] } | null>(null)\n const [mag, setMag] = useState<{ x: number; y: number } | null>(null)\n\n useEffect(() => {\n const img = new Image()\n img.onload = () => { imgRef.current = img; setReady(true) }\n img.src = url\n }, [url])\n\n useEffect(() => {\n if (!ready || !canvasRef.current || !imgRef.current) return\n const canvas = canvasRef.current\n canvas.width = imgRef.current.naturalWidth\n canvas.height = imgRef.current.naturalHeight\n const ctx = canvas.getContext('2d')\n if (ctx) ctx.drawImage(imgRef.current, 0, 0)\n // Deps include url (not just ready): an upload completes by rewriting the\n // store URL while `ready` stays true, and without this dependency the\n // canvas keeps the old pixels while sampleAt maps coordinates onto them.\n }, [ready, url])\n\n const sampleAt = useCallback((clientX: number, clientY: number) => {\n const canvas = canvasRef.current\n if (!canvas) return null\n const rect = canvas.getBoundingClientRect()\n if (rect.width === 0 || rect.height === 0) return null\n const ctx = canvas.getContext('2d')\n if (!ctx) return null\n const sx = Math.round((clientX - rect.left) * (canvas.width / rect.width))\n const sy = Math.round((clientY - rect.top) * (canvas.height / rect.height))\n if (sx < 0 || sy < 0 || sx >= canvas.width || sy >= canvas.height) return null\n const d = ctx.getImageData(sx, sy, 1, 1).data\n return { sx, sy, rgb: [d[0], d[1], d[2]] as [number, number, number] }\n }, [])\n\n const drawMagnifier = useCallback((sx: number, sy: number) => {\n const mag = magRef.current\n const src = canvasRef.current\n if (!mag || !src) return\n const ctx = mag.getContext('2d')\n if (!ctx) return\n const half = MAG_SIZE / MAG_ZOOM / 2\n ctx.clearRect(0, 0, MAG_SIZE, MAG_SIZE)\n ctx.drawImage(src, sx - half, sy - half, half * 2, half * 2, 0, 0, MAG_SIZE, MAG_SIZE)\n ctx.strokeStyle = 'rgba(255,255,255,0.85)'\n ctx.lineWidth = 1\n ctx.beginPath()\n ctx.moveTo(MAG_SIZE / 2, 0); ctx.lineTo(MAG_SIZE / 2, MAG_SIZE)\n ctx.moveTo(0, MAG_SIZE / 2); ctx.lineTo(MAG_SIZE, MAG_SIZE / 2)\n ctx.stroke()\n }, [])\n\n const onMove = (e: React.MouseEvent) => {\n const s = sampleAt(e.clientX, e.clientY)\n if (!s) { setHover(null); setMag(null); return }\n setHover({ rgb: s.rgb })\n drawMagnifier(s.sx, s.sy)\n const off = 28\n let x = e.clientX + off\n let y = e.clientY + off\n if (x + MAG_SIZE > window.innerWidth) x = e.clientX - off - MAG_SIZE\n if (y + MAG_SIZE > window.innerHeight) y = e.clientY - off - MAG_SIZE\n setMag({ x, y })\n }\n\n const onClick = (e: React.MouseEvent) => {\n const s = sampleAt(e.clientX, e.clientY)\n if (!s) return\n const [h, sl, l] = rgbToHsl(s.rgb[0], s.rgb[1], s.rgb[2])\n onPick(hslToHsv(h, sl, l))\n }\n\n return (\n <Portal>\n <div className=\"dab-overlay\">\n <div className=\"dab-overlay-title\">{t('pickerTitle')}</div>\n <div className=\"dab-overlay-hint\">{t('pickerHint')}</div>\n <div className=\"dab-modal-card\" style={{\n maxWidth: 'min(90vw, 720px)', maxHeight: '60vh', overflow: 'hidden',\n borderRadius: 12, border: '2px solid rgba(255,255,255,0.3)', background: '#000', cursor: 'crosshair',\n }}>\n <canvas ref={canvasRef} style={{ display: 'block', maxWidth: '100%', maxHeight: '60vh', objectFit: 'contain' }}\n onMouseMove={onMove}\n onMouseLeave={() => { setHover(null); setMag(null) }}\n onClick={onClick} />\n </div>\n <div style={{ display: 'flex', alignItems: 'center', gap: 10, minWidth: 260 }}>\n <div style={{ width: 28, height: 28, borderRadius: 8, border: '1px solid rgba(255,255,255,0.4)', background: hover ? rgbToHex(hover.rgb) : 'transparent' }} />\n <div style={{ color: '#fff', fontSize: 13, fontFamily: 'var(--dab-mono, monospace)' }}>{hover ? `${rgbToHex(hover.rgb)} · rgb(${hover.rgb.join(', ')})` : '—'}</div>\n </div>\n <div style={{ display: 'flex', gap: 10 }}>\n <button type=\"button\" className=\"dab-btn\" onClick={onClose}>{t('pickerClose')}</button>\n </div>\n <canvas ref={magRef} width={MAG_SIZE} height={MAG_SIZE}\n style={{\n position: 'fixed', width: MAG_SIZE, height: MAG_SIZE, borderRadius: '50%',\n border: '2px solid rgba(255,255,255,0.7)', boxShadow: '0 4px 16px rgba(0,0,0,0.5)',\n zIndex: 10000, background: '#000', pointerEvents: 'none', transition: 'opacity 0.08s',\n left: mag?.x ?? 0, top: mag?.y ?? 0, opacity: mag ? 1 : 0,\n }} />\n </div>\n </Portal>\n )\n}\n","import { useState } from 'react'\r\nimport type { CSSProperties } from 'react'\r\nimport type { ThemeSectionProps, ThemeStoreState } from '../../types'\r\nimport { hsvToHsl, hslToRgb, hslToHsv, rgbToHex } from '../../utils/color'\r\nimport { ColorWheel } from '../ColorWheel'\r\nimport { ColorInputs } from '../ColorInputs'\r\nimport { ColorPicker } from '../ColorPicker'\r\nimport { PipetteIcon, SparkleIcon } from '../icons'\r\n\r\n/** Curated quick-pick hues (HSL, s .72 l .55). */\r\nconst SWATCHES: Array<[number, number, number]> = [\r\n [356, 0.72, 0.55], [24, 0.78, 0.55], [44, 0.8, 0.55], [152, 0.62, 0.5],\r\n [174, 0.68, 0.48], [208, 0.72, 0.55], [252, 0.68, 0.6], [300, 0.64, 0.58],\r\n]\r\n\r\nexport function ColorPage({ p, notify }: { p: ThemeSectionProps; notify: (msg: string, ok?: boolean) => void }) {\r\n const { t, hue, sat, lit, setColor, extractColor, setSchemeOverride, useStore } = p\r\n // Field-level subscriptions: only url (extract/eyedropper gating), the forced\r\n // scheme and the stored color change this page's output.\r\n const storeUrl = useStore((s: ThemeStoreState) => s.url)\r\n const schemeOverride = useStore((s: ThemeStoreState) => s.schemeOverride)\r\n const color = useStore((s: ThemeStoreState) => s.color)\r\n const [pickerOpen, setPickerOpen] = useState(false)\r\n const [extracting, setExtracting] = useState(false)\r\n\r\n const wheel = (color ?? [hue, sat, lit]) as [number, number, number]\r\n const [h, s, l] = hsvToHsl(wheel[0], wheel[1], wheel[2])\r\n const [r, g, b] = hslToRgb(h, s, l)\r\n const hex = rgbToHex([r, g, b])\r\n const soft = `rgba(${Math.round(r)},${Math.round(g)},${Math.round(b)},0.5)`\r\n const orbVars = { '--c': hex, '--c-soft': soft } as CSSProperties\r\n\r\n const onExtract = async () => {\r\n if (!storeUrl || extracting) return\r\n setExtracting(true)\r\n try {\r\n const ok = await extractColor()\r\n notify(ok ? t('extractDone') : t('extractFail'), ok)\r\n } catch {\r\n notify(t('extractFail'), false)\r\n } finally {\r\n setExtracting(false)\r\n }\r\n }\r\n\r\n return (\r\n <>\r\n <header className=\"dab-head dab-rise\" style={{ '--d': 0 } as CSSProperties}>\r\n <div className=\"dab-overline\">Accent</div>\r\n <h2 className=\"dab-h1\">{t('colorTitle')}</h2>\r\n <p className=\"dab-desc\">{t('descColor')}</p>\r\n </header>\r\n\r\n {/* Hero: living orb with a rotating conic halo + live HEX readout */}\r\n <section className=\"dab-card dab-card-hover dab-hero-accent dab-rise\" style={{ '--d': 1 } as CSSProperties}>\r\n <div className=\"dab-orb-wrap\" style={orbVars}>\r\n <div className=\"dab-orb-ring\" />\r\n <div className=\"dab-orb\" />\r\n </div>\r\n <div style={{ flex: 1, minWidth: 200 }}>\r\n <div className=\"dab-hex-caption\">{t('hexCaption')}</div>\r\n <div className=\"dab-hex\">{hex.toUpperCase()}</div>\r\n <div className=\"dab-hsl-row\">\r\n <span>H <b>{Math.round(h)}°</b></span>\r\n <span>S <b>{Math.round(s * 100)}%</b></span>\r\n <span>L <b>{Math.round(l * 100)}%</b></span>\r\n </div>\r\n <div className=\"dab-chip-row\" style={{ marginTop: 14 }}>\r\n <button type=\"button\" className=\"dab-btn\" disabled={!storeUrl || extracting} onClick={onExtract}>\r\n <SparkleIcon size={14} />{extracting ? t('extracting') : t('extractColor')}\r\n </button>\r\n <button type=\"button\" className=\"dab-btn\" disabled={!storeUrl} onClick={() => setPickerOpen(true)}>\r\n <PipetteIcon size={14} />{t('eyedropper')}\r\n </button>\r\n </div>\r\n </div>\r\n </section>\r\n\r\n {/* Wheel + precise entry */}\r\n <section className=\"dab-card dab-wheel-card dab-rise\" style={{ '--d': 2 } as CSSProperties}>\r\n <div className=\"dab-wheel-glow\" style={{ background: hex }} />\r\n <ColorWheel hue={wheel[0]} sat={wheel[1]} lit={wheel[2]} onChange={setColor} />\r\n <ColorInputs hue={wheel[0]} sat={wheel[1]} lit={wheel[2]} onChange={setColor} />\r\n </section>\r\n <p className=\"dab-hint dab-rise\" style={{ '--d': 3 } as CSSProperties}>{t('colorHint')}</p>\r\n\r\n {/* Quick swatches */}\r\n <section className=\"dab-card dab-card-hover dab-rise\" style={{ '--d': 3 } as CSSProperties}>\r\n <div className=\"dab-swatch-title\">{t('swatchTitle')}</div>\r\n <div className=\"dab-swatches\">\r\n {SWATCHES.map(([sh, ss, sl], i) => {\r\n // Circular hue distance via the (Δ+540)%360 trick. A swatch is \"on\"\r\n // only when the current color actually matches it (hue within 3°,\r\n // sat/lightness within 0.05). Picking a custom color in the wheel\r\n // clears the swatch selection instead of keeping it highlighted\r\n // based on hue proximity alone.\r\n const dist = Math.abs(((wheel[0] - sh + 540) % 360) - 180)\r\n const on = dist < 3 && Math.abs(s - ss) < 0.05 && Math.abs(l - sl) < 0.05\r\n return (\r\n <button\r\n key={i} type=\"button\"\r\n className={`dab-swatch${on ? ' is-on' : ''}`}\r\n style={{ background: `hsl(${sh} ${Math.round(ss * 100)}% ${Math.round(sl * 100)}%)` }}\r\n title={rgbToHex(hslToRgb(sh, ss, sl)).toUpperCase()}\r\n onClick={() => setColor(...hslToHsv(sh, ss, sl))} />\r\n )\r\n })}\r\n </div>\r\n </section>\r\n\r\n {/* Forced interface scheme */}\r\n <section className=\"dab-card dab-rise\" style={{ '--d': 4 } as CSSProperties}>\r\n <div className=\"dab-swatch-title\">{t('schemeTitle')}</div>\r\n <div className=\"dab-seg\" style={{ '--w': '86px' } as CSSProperties}>\r\n <div className=\"dab-seg-thumb\" style={{ transform: `translateX(${schemeOverride === 'light' ? 0 : schemeOverride === 'dark' ? 86 : 172}px)` }} />\r\n <button type=\"button\" className={`dab-seg-item${schemeOverride === 'light' ? ' is-active' : ''}`} onClick={() => setSchemeOverride('light')}>{t('schemeLight')}</button>\r\n <button type=\"button\" className={`dab-seg-item${schemeOverride === 'dark' ? ' is-active' : ''}`} onClick={() => setSchemeOverride('dark')}>{t('schemeDark')}</button>\r\n <button type=\"button\" className={`dab-seg-item${schemeOverride === 'auto' ? ' is-active' : ''}`} onClick={() => setSchemeOverride('auto')}>{t('schemeAuto')}</button>\r\n </div>\r\n <p className=\"dab-hint\" style={{ marginTop: 10 }}>{t('schemeHint')}</p>\r\n </section>\r\n\r\n {/* Eyedropper modal */}\r\n {pickerOpen && storeUrl ? (\r\n <ColorPicker url={storeUrl} t={t} onClose={() => setPickerOpen(false)}\r\n onPick={hsv => { setColor(hsv[0], hsv[1], hsv[2]); setPickerOpen(false) }} />\r\n ) : null}\r\n </>\r\n )\r\n}\r\n","import { useEffect, useRef } from 'react'\nimport type { CSSProperties } from 'react'\n\n/**\n * Zero-lag slider: the thumb and value label update through DOM refs while\n * dragging (onInput) so the caller can mutate the live UI directly without a\n * React re-render; onChange commits the settled value. Double-click resets to\n * the canonical default. The track fill is a gradient driven by the --pct\n * custom property, updated imperatively alongside the thumb.\n */\nexport function LiveSlider({ min, max, step, def, fmt, label, onInput, onChange }: {\n min: number; max: number; step: number; def: number\n fmt: (v: number) => string; label?: string; onInput?: (v: number) => void; onChange: (v: number) => void\n}) {\n const inputRef = useRef<HTMLInputElement>(null)\n const valRef = useRef<HTMLSpanElement>(null)\n\n const paint = (el: HTMLInputElement, v: number): void => {\n el.style.setProperty('--pct', String(((v - min) / (max - min)) * 100))\n }\n\n // Read the formatter through a ref: every caller passes an inline arrow\n // (`v => `${v}%``), whose identity changes per render. Listing `fmt` in the\n // effect deps would re-run this sync on EVERY parent render — and since the\n // sync writes inputRef.value from `def`, a mid-drag re-render (the 30s\n // schedule tick, a toast, a store sync) yanks the thumb back to the old\n // committed value. Only the numeric bounds may re-sync, never the closure.\n const fmtRef = useRef(fmt)\n fmtRef.current = fmt\n\n // Controlled sync: keep the knob and label aligned with the canonical prop\n // so external updates (presets, regeneration, imports) never leave it stale.\n useEffect(() => {\n if (inputRef.current) {\n inputRef.current.value = String(def)\n paint(inputRef.current, def)\n }\n if (valRef.current) valRef.current.textContent = fmtRef.current(def)\n }, [def, min, max])\n\n const apply = (v: number): void => {\n if (inputRef.current) {\n inputRef.current.value = String(v)\n paint(inputRef.current, v)\n }\n if (valRef.current) valRef.current.textContent = fmt(v)\n onInput?.(v)\n onChange(v)\n }\n\n return (\n <div className=\"dab-slider-block\">\n {label ? <span className=\"dab-slider-label\">{label}</span> : null}\n <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>\n <input\n ref={inputRef} type=\"range\" className=\"dab-slider\"\n style={{ '--pct': ((def - min) / (max - min)) * 100 } as CSSProperties}\n min={min} max={max} step={step} defaultValue={def}\n title={label ? `${label} · ${fmt(def)}` : fmt(def)}\n onDoubleClick={() => apply(def)}\n onInput={e => {\n const el = e.target as HTMLInputElement\n const v = Number(el.value)\n paint(el, v)\n onInput?.(v)\n if (valRef.current) valRef.current.textContent = fmt(v)\n }}\n onChange={e => onChange(Number((e.target as HTMLInputElement).value))} />\n <span ref={valRef} className=\"dab-slider-val\">{fmt(def)}</span>\n </div>\n </div>\n )\n}\n","import type { CSSProperties, ComponentType } from 'react'\nimport type { ThemeSectionProps, ThemeStoreState, PartOpacities, PartBlurs } from '../../types'\nimport { cfg, rOps, rSop, rBlurs, rChatTextOpacity, rTrajectoryOpacity, rPanelOpacity, rProducedOpacity, rHeaderOpacity } from '../../state'\nimport { saveConfig } from '../../rpc'\nimport { applyCustomTokens, applySettingsOverrides, setPartBlur, applyViewCards, applyTrajectoryOverrides, applyPanelOverrides, applyProduced, applyHeaderPopovers } from '../../wallpaper'\nimport { LiveSlider } from '../LiveSlider'\nimport { CanvasIcon, SidebarIcon, ChatIcon, GearIcon, TextIcon, TrajectoryIcon, InputIcon, PanelIcon } from '../icons'\n\ninterface PartDef {\n labelKey: string\n Icon: ComponentType<{ size?: number }>\n /** Homepage part key; absent for the settings-panel part. */\n opKey?: keyof PartOpacities\n isSettings?: boolean\n /** Conversation text region: tint opacity + blur over the message column. */\n isChat?: boolean\n /** Trajectory view: tint opacity + blur over the whole view surface. */\n isTrajectory?: boolean\n /** The host's own right Sidebar column: opacity + blur. */\n isPanel?: boolean\n /** Produced/highlight surfaces — code blocks, inline code, produced chips and\n * the dsh-better-sidebar workbench: opacity + blur. */\n isProduced?: boolean\n /** Header popovers (Agent Team panel + background-job list): opacity + blur. */\n isHeader?: boolean\n}\n\nconst PARTS: PartDef[] = [\n { opKey: 'bg', labelKey: 'uiOpacityBg', Icon: CanvasIcon },\n { opKey: 'sidebar', labelKey: 'uiOpacitySide', Icon: SidebarIcon },\n { opKey: 'card', labelKey: 'uiOpacityCard', Icon: ChatIcon },\n { opKey: 'input', labelKey: 'uiOpacityInput', Icon: InputIcon },\n { isSettings: true, labelKey: 'uiSop', Icon: GearIcon },\n { isChat: true, labelKey: 'uiChatRegion', Icon: TextIcon },\n { isTrajectory: true, labelKey: 'uiTrajectory', Icon: TrajectoryIcon },\n { isProduced: true, labelKey: 'uiProduced', Icon: TextIcon },\n { isHeader: true, labelKey: 'uiHeader', Icon: PanelIcon },\n { isPanel: true, labelKey: 'uiPanelNative', Icon: PanelIcon },\n]\n\nexport function InterfacePage({ p }: { p: ThemeSectionProps }) {\n const { t, setOps, setBlurs, setSop, setPanelOp, useStore } = p\n // Presets, theme imports and profile restores mutate cfg directly and only\n // bump the store's metaRev — this page renders straight off cfg, so without\n // this subscription it never re-renders and the sliders keep showing the\n // values from before the change (while the interface itself already moved).\n const metaRev = useStore((s: ThemeStoreState) => s.metaRev)\n void metaRev\n // The panel row owns the host's own right Sidebar only. The dsh-better-sidebar\n // workbench used to ride this row too, but it is an artifact viewer, not a page\n // column, so since 0.3.2 it belongs to the produced row below (PRODUCED_RULE).\n\n return (\n <>\n <header className=\"dab-head dab-rise\" style={{ '--d': 0 } as CSSProperties}>\n <div className=\"dab-overline\">Surfaces</div>\n <h2 className=\"dab-h1\">{t('uiTitle')}</h2>\n <p className=\"dab-desc\">{t('descInterface')}</p>\n </header>\n\n <div className=\"dab-grid-parts\">\n {PARTS.map((part, i) => {\n const { labelKey, Icon, isSettings, isChat, isTrajectory, isPanel, isProduced, isHeader } = part\n const opKey = part.opKey\n const label = t(labelKey)\n // Homepage parts (bg/sidebar/card/input) bind to their own part only;\n // the settings panel (isSettings) binds exclusively to the 'settings'\n // part (--dsh-any-blur-settings / --dsh-any-bg-settings-surface) and\n // must never fall back to a homepage part key — otherwise the dialog\n // panel would track the homepage center/card blur and the home-page\n // opacities. The chat region (isChat) and the trajectory view\n // (isTrajectory) own their own blur keys plus their own tint\n // opacities; the header row (isHeader) owns the 'header' blur key and\n // cfg.headerOpacity; the panel row (isPanel, the host's own right\n // Sidebar column) owns the 'panel' blur key and cfg.panelOpacity.\n // Every homepage opKey is also a PartBlurs\n // key (input included), so the shared blur slider dereferences it\n // directly.\n const blurKey: keyof PartBlurs = isChat ? 'chat' : isTrajectory ? 'trajectory' : isSettings ? 'settings' : isPanel ? 'panel' : isProduced ? 'produced' : isHeader ? 'header' : opKey!\n const opacity = isChat ? rChatTextOpacity() : isTrajectory ? rTrajectoryOpacity() : isSettings ? rSop() : isPanel ? rPanelOpacity() : isProduced ? rProducedOpacity() : isHeader ? rHeaderOpacity() : rOps()[opKey!]\n return (\n <section key={blurKey} className=\"dab-card dab-card-hover dab-rise\" style={{ '--d': i + 1 } as CSSProperties}>\n <div className=\"dab-part-head\">\n <div className=\"dab-part-ico\"><Icon size={16} /></div>\n <div className=\"dab-part-name\">{label}</div>\n <span className=\"dab-part-badge\">{Math.round(opacity * 100)}%</span>\n </div>\n\n <LiveSlider label={t('uiOpacity')} min={0} max={100} step={1} def={Math.round(opacity * 100)}\n fmt={v => `${v}%`}\n onInput={v => {\n const op = v / 100\n if (isChat) {\n cfg.chatTextOpacity = op\n applyViewCards()\n } else if (isTrajectory) {\n cfg.trajectoryOpacity = op\n applyTrajectoryOverrides(op)\n } else if (isSettings) {\n cfg.settingsOpacity = op\n applySettingsOverrides(op)\n } else if (isPanel) {\n cfg.panelOpacity = op\n applyPanelOverrides(op)\n } else if (isProduced) {\n cfg.producedOpacity = op\n applyProduced()\n } else if (isHeader) {\n cfg.headerOpacity = op\n applyHeaderPopovers()\n } else {\n const ops = { ...rOps() }\n ops[opKey!] = op\n cfg.opacities = ops\n applyCustomTokens(ops)\n }\n saveConfig()\n }}\n onChange={v => {\n const op = v / 100\n if (isChat) {\n cfg.chatTextOpacity = op\n applyViewCards()\n saveConfig()\n } else if (isTrajectory) {\n cfg.trajectoryOpacity = op\n applyTrajectoryOverrides(op)\n saveConfig()\n } else if (isSettings) {\n setSop(op)\n } else if (isPanel) {\n setPanelOp(op)\n } else if (isProduced) {\n cfg.producedOpacity = op\n applyProduced()\n saveConfig()\n } else if (isHeader) {\n cfg.headerOpacity = op\n applyHeaderPopovers()\n saveConfig()\n } else {\n const ops = { ...rOps() }\n ops[opKey!] = op\n setOps(ops)\n }\n }} />\n\n <LiveSlider label={t('uiBlur')} min={0} max={60} step={1} def={rBlurs()[blurKey]}\n fmt={v => `${v}px`}\n onInput={v => {\n const blurs = { ...rBlurs() }\n blurs[blurKey] = v\n cfg.blurs = blurs\n setPartBlur(blurKey, v)\n saveConfig()\n }}\n onChange={v => {\n const blurs = { ...rBlurs() }\n blurs[blurKey] = v\n setBlurs(blurs)\n }} />\n </section>\n )\n })}\n </div>\n </>\n )\n}\n","import { useEffect, useRef, useState } from 'react'\nimport type { CSSProperties, ComponentType } from 'react'\nimport type { PartBlurs, PartStrokes, StrokeConfig, ThemeStoreState, ThemeSectionProps } from '../../types'\nimport { cfg, rStrokes } from '../../state'\nimport { saveConfig, uploadRefusalText } from '../../rpc'\nimport { setPartStroke } from '../../wallpaper'\nimport { LiveSlider } from '../LiveSlider'\nimport {\n CanvasIcon, SidebarIcon, ChatIcon, GearIcon, TextIcon, TrajectoryIcon,\n InputIcon, PanelIcon, TrashIcon, UploadIcon,\n} from '../icons'\n\n/**\n * Font page: the custom interface font slot plus per-part text strokes.\n *\n * Stroke settings mirror the interface page's per-part blur groups one-to-one\n * (same nine surfaces) — see STROKE_RULE in wallpaper.ts for how each group\n * binds to the DOM. Colors are stored as PRESET KEYS, never resolved values,\n * so 'auto' (contrast the font) and 'theme' (follow the accent) keep tracking\n * the palette; only 'custom' carries a literal hex.\n */\ninterface PartDef {\n /** Surface group key — a PartBlurs key, and therefore a PartStrokes key. */\n key: keyof PartBlurs\n labelKey: string\n Icon: ComponentType<{ size?: number }>\n}\n\nconst PARTS: PartDef[] = [\n { key: 'bg', labelKey: 'uiOpacityBg', Icon: CanvasIcon },\n { key: 'sidebar', labelKey: 'uiOpacitySide', Icon: SidebarIcon },\n { key: 'card', labelKey: 'uiOpacityCard', Icon: ChatIcon },\n { key: 'input', labelKey: 'uiOpacityInput', Icon: InputIcon },\n { key: 'settings', labelKey: 'uiSop', Icon: GearIcon },\n { key: 'chat', labelKey: 'uiChatRegion', Icon: TextIcon },\n { key: 'trajectory', labelKey: 'uiTrajectory', Icon: TrajectoryIcon },\n { key: 'produced', labelKey: 'uiProduced', Icon: TextIcon },\n { key: 'header', labelKey: 'uiHeader', Icon: PanelIcon },\n { key: 'panel', labelKey: 'uiPanelNative', Icon: PanelIcon },\n]\n\nconst COLOR_KEYS: Array<StrokeConfig['color']> = ['auto', 'gray', 'black', 'white', 'theme', 'custom']\nconst COLOR_LABEL_KEYS: Record<StrokeConfig['color'], string> = {\n auto: 'strokeAuto', gray: 'strokeGray', black: 'strokeBlack',\n white: 'strokeWhite', theme: 'strokeTheme', custom: 'strokeCustom',\n}\n\n/** Swatch fill for one preset key. 'auto' gets its half-black/half-white\n * conic gradient from CSS, and 'custom' shows the stored hex. */\nfunction dotStyle(key: StrokeConfig['color'], s: StrokeConfig): CSSProperties {\n switch (key) {\n case 'gray': return { background: '#808080' }\n case 'black': return { background: '#000' }\n case 'white': return { background: '#fff' }\n case 'theme': return { background: 'var(--dsw-alias-brand-primary)' }\n case 'custom': return { background: s.customColor }\n default: return {}\n }\n}\n\nexport function FontPage({ p, notify }: { p: ThemeSectionProps; notify: (msg: string, ok?: boolean) => void }) {\n const { t, setFont, removeFont, setFontEnabled, setStrokes, useStore } = p\n const fileRef = useRef<HTMLInputElement>(null)\n\n // cfg is the source of truth; the local copies exist because nothing else\n // re-renders this page when the config changes (the store only carries the\n // wallpaper/color/meta snapshots), and async uploads settle after render.\n const [strokes, setStrokesState] = useState<PartStrokes>(() => rStrokes())\n const [fontInfo, setFontInfo] = useState<{ mime: string | null; enabled: boolean; name: string | null }>(() => ({\n mime: cfg.fontMime, enabled: cfg.fontEnabled, name: null,\n }))\n const [busy, setBusy] = useState(false)\n\n // Presets / imports / profile restores rewrite cfg.strokes and the font slot\n // directly and only bump the store's metaRev. Without this re-derivation the\n // local copies above keep rendering the values from before the change.\n const metaRev = useStore((s: ThemeStoreState) => s.metaRev)\n useEffect(() => {\n setStrokesState(rStrokes())\n setFontInfo(prev =>\n prev.mime === cfg.fontMime && prev.enabled === cfg.fontEnabled\n ? prev\n : { mime: cfg.fontMime, enabled: cfg.fontEnabled, name: null },\n )\n }, [metaRev])\n\n const hasFont = fontInfo.mime !== null\n // After a reload only the MIME survives (the original filename is not\n // persisted), so fall back to the container format — e.g. \"WOFF2\".\n const fontLabel = fontInfo.name ?? (fontInfo.mime !== null ? fontInfo.mime.replace('font/', '').toUpperCase() : t('fontNone'))\n\n /** Write one group's stroke: cfg + live DOM now, disk on commit. `live`\n * marks slider drags (debounced save, no full re-apply). */\n const patch = (key: keyof PartBlurs, next: Partial<StrokeConfig>, live: boolean): void => {\n const map: PartStrokes = { ...strokes, [key]: { ...strokes[key], ...next } }\n setStrokesState(map)\n cfg.strokes = map\n setPartStroke(key, map[key])\n if (live) saveConfig()\n else setStrokes(map)\n }\n\n const pickFont = async (file: File): Promise<void> => {\n setBusy(true)\n setFontInfo({ ...fontInfo, name: file.name })\n const outcome = await setFont(file)\n setBusy(false)\n if (outcome.ok) {\n setFontInfo({ mime: cfg.fontMime, enabled: cfg.fontEnabled, name: file.name })\n } else {\n // Roll the optimistic name back to whatever is actually stored.\n setFontInfo({ mime: cfg.fontMime, enabled: cfg.fontEnabled, name: null })\n notify(uploadRefusalText(outcome, t, 'fontFail'), false)\n }\n }\n\n return (\n <>\n <header className=\"dab-head dab-rise\" style={{ '--d': 0 } as CSSProperties}>\n <div className=\"dab-overline\">Typography</div>\n <h2 className=\"dab-h1\">{t('fontPageTitle')}</h2>\n <p className=\"dab-desc\">{t('descFont')}</p>\n </header>\n\n <section className=\"dab-card dab-rise dab-font-card\" style={{ '--d': 1 } as CSSProperties}>\n <div className=\"dab-row-head\">\n <div className=\"dab-font-title\">\n <div className=\"dab-part-ico\"><TextIcon size={16} /></div>\n <div className=\"dab-part-name\">{t('fontTitle')}</div>\n </div>\n {hasFont ? (\n <button type=\"button\" className={`dab-toggle${fontInfo.enabled ? ' is-on' : ''}`} role=\"switch\"\n aria-checked={fontInfo.enabled} aria-label={t('fontEnabled')}\n onClick={() => {\n const v = !fontInfo.enabled\n setFontEnabled(v)\n setFontInfo({ ...fontInfo, enabled: v })\n }}>\n <span className=\"dab-toggle-knob\" />\n </button>\n ) : null}\n </div>\n\n <div className=\"dab-font-row\">\n <span className={`dab-font-name${hasFont ? '' : ' is-empty'}`} title={fontLabel}>{fontLabel}</span>\n <div className=\"dab-font-actions\">\n <button type=\"button\" className=\"dab-btn dab-btn-primary\" disabled={busy}\n onClick={() => fileRef.current?.click()}>\n <UploadIcon size={14} />{busy ? t('fontUploading') : t('fontUpload')}\n </button>\n {hasFont ? (\n <button type=\"button\" className=\"dab-btn dab-btn-danger\"\n onClick={() => {\n removeFont()\n setFontInfo({ mime: null, enabled: cfg.fontEnabled, name: null })\n }}>\n <TrashIcon size={14} />{t('fontRemove')}\n </button>\n ) : null}\n </div>\n </div>\n\n <p className=\"dab-hint\" style={{ marginTop: 10 }}>{t('fontHint')}</p>\n <input ref={fileRef} type=\"file\" accept=\".ttf,.otf,.woff,.woff2,font/*\" style={{ display: 'none' }}\n onChange={e => {\n const f = e.target.files?.[0]\n e.target.value = ''\n if (f) void pickFont(f)\n }} />\n </section>\n\n <section className=\"dab-card dab-rise\" style={{ '--d': 2 } as CSSProperties}>\n <div className=\"dab-part-head\" style={{ marginBottom: 10 }}>\n <div className=\"dab-part-name\">{t('strokeTitle')}</div>\n </div>\n <p className=\"dab-hint\" style={{ marginBottom: 14 }}>{t('strokeHint')}</p>\n\n <div className=\"dab-grid-parts\">\n {PARTS.map((part, i) => {\n const s = strokes[part.key]\n return (\n <section key={part.key} className=\"dab-card dab-card-hover dab-rise\" style={{ '--d': i + 3 } as CSSProperties}>\n <div className=\"dab-part-head\">\n <div className=\"dab-part-ico\"><part.Icon size={16} /></div>\n <div className=\"dab-part-name\">{t(part.labelKey)}</div>\n <span className=\"dab-part-badge\">{s.width}px</span>\n </div>\n\n <LiveSlider label={t('strokeWidth')} min={0} max={4} step={0.5} def={s.width}\n fmt={v => `${v}px`}\n onInput={v => patch(part.key, { width: v }, true)}\n onChange={v => patch(part.key, { width: v }, false)} />\n\n <div className=\"dab-stroke-dots\">\n {COLOR_KEYS.map(key => {\n const active = s.color === key\n return (\n <div key={key} className=\"dab-stroke-dot-wrap\">\n <button type=\"button\"\n className={`dab-stroke-dot${key === 'auto' ? ' dab-stroke-dot-auto' : ''}${active ? ' is-active' : ''}`}\n style={dotStyle(key, s)}\n title={t(COLOR_LABEL_KEYS[key])} aria-label={t(COLOR_LABEL_KEYS[key])}\n aria-pressed={active}\n onClick={() => patch(part.key, { color: key }, false)} />\n {/* The native picker is invisible and stretched over the\n swatch, so one click both selects 'custom' and opens\n it — no in-house color popover needed. */}\n {key === 'custom' ? (\n <input type=\"color\" className=\"dab-stroke-dot-input\" value={s.customColor}\n aria-label={t('strokeCustom')}\n onChange={e => patch(part.key, { color: 'custom', customColor: e.target.value }, false)} />\n ) : null}\n </div>\n )\n })}\n </div>\n </section>\n )\n })}\n </div>\n </section>\n </>\n )\n}\n","import { useRef, useState, useEffect, useCallback } from 'react'\r\nimport { cfg } from '../state'\r\nimport { Portal } from './Portal'\r\n\r\n/** Placement slot for the active background type: video framing lives in its\r\n * own state so image and video edits never overwrite each other. */\r\nconst activeState = () => cfg.backgroundType === 'video' ? cfg.videoBgState : cfg.bgState\r\n\r\n/** Zoom is shared by every input path (wheel + pinch) so all pictures animate\r\n * between the same bounds. */\r\nconst clampZoom = (z: number): number => Math.max(0.1, Math.min(10, z))\r\n\r\nexport function BgEditor({ url, t, onClose, onCommit }: {\r\n url: string; t: (key: string) => string; onClose: () => void\r\n onCommit: (zoom: number, x: number, y: number, iw: number, ih: number) => void\r\n}) {\r\n const pw = Math.min(window.innerWidth * 0.75, 860)\r\n const ph = Math.round(pw * window.innerHeight / window.innerWidth)\r\n const saved = activeState()\r\n const [zoom, setZoom] = useState(saved.iw > 0 ? saved.zoom : 1)\r\n const [pos, setPos] = useState(saved.iw > 0 ? { x: saved.x * pw, y: saved.y * ph } : { x: 0, y: 0 })\r\n const [imgSize, setImgSize] = useState({ w: 0, h: 0 })\r\n const containerRef = useRef<HTMLDivElement>(null)\r\n const imgRef = useRef<HTMLImageElement>(null)\r\n /**\r\n * The overlay node is held in STATE rather than a plain ref, so the listener\r\n * effect below re-runs the moment it actually exists.\r\n *\r\n * This is not a style choice. Everything here renders through <Portal>, which\r\n * returns null on its first render — its own effect has to create the host\r\n * node under <html> first. A plain ref is therefore still null when a\r\n * mount-only effect runs, and an effect whose deps never change again attaches\r\n * nothing, ever. That is exactly how the touch handlers below ended up dead on\r\n * real phones: the wheel handler only survived because its deps churn on every\r\n * zoom/pan, so the wallpaper's img.onload re-ran it once and wired it up.\r\n */\r\n const [overlayEl, setOverlayEl] = useState<HTMLDivElement | null>(null)\r\n const dragRef = useRef({ active: false, sx: 0, sy: 0, spx: 0, spy: 0 })\r\n /** Unmount-time cleanup for a drag that never saw its mouseup (editor closed\r\n * mid-drag): without it the document listeners stay attached forever and\r\n * keep calling setPos on a dead component. */\r\n const dragStopRef = useRef<(() => void) | null>(null)\r\n /** Set once a gesture actually moved, so the click that follows a drag is not\r\n * mistaken for a tap on the backdrop (mousedown and mouseup in different\r\n * subtrees make the click land on the overlay, i.e. \"outside\"). Reset at the\r\n * start of every gesture — touchstart / mousedown / wheel — so it can only\r\n * ever describe the gesture that just ended, never an earlier one. */\r\n const movedRef = useRef(false)\r\n // Latest view for the natively-attached touch listeners below — they are\r\n // attached once (rather than re-bound every render) and read the current\r\n // zoom/offset from this mirror.\r\n const viewRef = useRef({ zoom, pos })\r\n viewRef.current = { zoom, pos }\r\n /** Pinch gesture baseline (two fingers down): finger spread + midpoint and\r\n * the transform that was live at that moment. */\r\n const pinchRef = useRef<{ dist: number; zoom: number; cx: number; cy: number; px: number; py: number } | null>(null)\r\n /** Single-finger pan baseline. */\r\n const touchDragRef = useRef<{ sx: number; sy: number; spx: number; spy: number } | null>(null)\r\n\r\n useEffect(() => {\r\n const img = new Image()\r\n img.onload = () => {\r\n const scale = Math.min(pw / img.width, ph / img.height)\r\n const w = img.width * scale, h = img.height * scale\r\n setImgSize({ w, h })\r\n const s = activeState()\r\n if (s.iw > 0 && s.iw === img.width && s.ih === img.height) {\r\n setZoom(s.zoom)\r\n // Saved x, y are CENTER fractions of the preview: the image center\r\n // lands at (x·pw, y·ph), so the top-left comes from subtracting half\r\n // the displayed (zoom-scaled) image size.\r\n setPos({ x: s.x * pw - w * s.zoom / 2, y: s.y * ph - h * s.zoom / 2 })\r\n } else {\r\n setZoom(1)\r\n setPos({ x: (pw - w) / 2, y: (ph - h) / 2 })\r\n }\r\n }\r\n img.src = url\r\n }, [url, pw, ph])\r\n\r\n const onDown = useCallback((e: React.MouseEvent) => {\r\n e.preventDefault()\r\n movedRef.current = false\r\n dragRef.current = { active: true, sx: e.clientX, sy: e.clientY, spx: pos.x, spy: pos.y }\r\n const onMove = (ev: MouseEvent) => {\r\n if (!dragRef.current.active) return\r\n if (Math.abs(ev.clientX - dragRef.current.sx) > 4 || Math.abs(ev.clientY - dragRef.current.sy) > 4) movedRef.current = true\r\n setPos({ x: dragRef.current.spx + ev.clientX - dragRef.current.sx, y: dragRef.current.spy + ev.clientY - dragRef.current.sy })\r\n }\r\n const stopDrag = () => {\r\n dragRef.current.active = false\r\n document.removeEventListener('mousemove', onMove)\r\n document.removeEventListener('mouseup', stopDrag)\r\n dragStopRef.current = null\r\n }\r\n dragStopRef.current = stopDrag\r\n document.addEventListener('mousemove', onMove); document.addEventListener('mouseup', stopDrag)\r\n }, [pos])\r\n\r\n // A drag ended by closing the editor never fires mouseup; drop the listeners\r\n // here so they cannot outlive this component.\r\n useEffect(() => () => { dragStopRef.current?.() }, [])\r\n\r\n const onWheelCb = useCallback((e: WheelEvent) => {\r\n e.preventDefault()\r\n movedRef.current = false\r\n const el = containerRef.current\r\n if (!el) return\r\n const rect = el.getBoundingClientRect()\r\n // Anchor the zoom at the preview center so the mouse position never\r\n // steers where the image grows/shrinks — the current view stays centered.\r\n const mx = rect.width / 2, my = rect.height / 2\r\n // 3% per wheel step (0.97 zoom-out / 1.03 zoom-in).\r\n const factor = e.deltaY > 0 ? 0.97 : 1.03\r\n // Read the live view from the mirror instead of closing over zoom/pos: that\r\n // keeps this handler identity-stable, so it is bound once rather than torn\r\n // down and re-bound on every zoom/pan frame.\r\n const { zoom: z, pos: p } = viewRef.current\r\n const nz = clampZoom(z * factor)\r\n const nx = mx - (mx - p.x) * (nz / z)\r\n const ny = my - (my - p.y) * (nz / z)\r\n setZoom(nz); setPos({ x: nx, y: ny })\r\n }, [])\r\n\r\n // ── Touch: one finger pans the preview, two fingers pinch-zoom (dragging them\r\n // together pans at the same time). Three things are deliberate here:\r\n //\r\n // 1. The listeners hang off the OVERLAY, not the preview card. The card is\r\n // only ~75% of a phone's width, so a pinch whose fingers land on the dimmed\r\n // backdrop — the common case on a phone — used to be handed straight to the\r\n // browser, which zoomed the page instead of the picture. Touch events\r\n // bubble, and `TouchEvent.touches` lists every finger on the surface rather\r\n // than only the target's own, so listening on the overlay also lets a pinch\r\n // with one finger on the card and one on the backdrop work.\r\n // 2. They are attached natively with passive:false: React registers touchmove\r\n // passively at the root, where preventDefault is a no-op — the page would\r\n // pan and browser-zoom behind the open editor. A jsx onTouchMove prop\r\n // cannot fix that, since it rides the same passive root listener.\r\n // 3. A one-finger pan only starts on the preview itself, so dragging the\r\n // backdrop still reads as a tap-outside-to-close rather than silently\r\n // shoving the wallpaper around.\r\n const onTouchStartCb = useCallback((e: TouchEvent) => {\r\n const card = containerRef.current\r\n if (!card) return\r\n movedRef.current = false\r\n if (e.touches.length >= 2) {\r\n // A second finger takes over from the pan and opens a pinch.\r\n touchDragRef.current = null\r\n const rect = card.getBoundingClientRect()\r\n const a = e.touches[0], b = e.touches[1]\r\n pinchRef.current = {\r\n dist: Math.hypot(a.clientX - b.clientX, a.clientY - b.clientY),\r\n zoom: viewRef.current.zoom,\r\n cx: (a.clientX + b.clientX) / 2 - rect.left,\r\n cy: (a.clientY + b.clientY) / 2 - rect.top,\r\n px: viewRef.current.pos.x, py: viewRef.current.pos.y,\r\n }\r\n return\r\n }\r\n if (e.touches.length === 1) {\r\n // Start (or restart) a one-finger pan from the live transform.\r\n pinchRef.current = null\r\n if (!card.contains(e.target as Node)) { touchDragRef.current = null; return }\r\n const tp = e.touches[0]\r\n touchDragRef.current = { sx: tp.clientX, sy: tp.clientY, spx: viewRef.current.pos.x, spy: viewRef.current.pos.y }\r\n }\r\n }, [])\r\n\r\n const onTouchMoveCb = useCallback((e: TouchEvent) => {\r\n const card = containerRef.current\r\n if (!card) return\r\n if (e.touches.length >= 2 && pinchRef.current !== null) {\r\n e.preventDefault()\r\n movedRef.current = true\r\n const p = pinchRef.current\r\n // A zero spread (two fingers detected at one point) has no scale to derive.\r\n if (p.dist <= 0) return\r\n const rect = card.getBoundingClientRect()\r\n const a = e.touches[0], b = e.touches[1]\r\n const dist = Math.hypot(a.clientX - b.clientX, a.clientY - b.clientY)\r\n const cx = (a.clientX + b.clientX) / 2 - rect.left\r\n const cy = (a.clientY + b.clientY) / 2 - rect.top\r\n const nz = clampZoom(p.zoom * (dist / p.dist))\r\n // Keep the image point that started under the fingers pinned to them:\r\n // at gesture start it sat at base coord (c0 - t0)/z0, and after zooming\r\n // to z1 the offset must place it back under the current midpoint. Both\r\n // the scale change AND a two-finger drag fall out of this one relation.\r\n setZoom(nz)\r\n setPos({ x: cx - ((p.cx - p.px) / p.zoom) * nz, y: cy - ((p.cy - p.py) / p.zoom) * nz })\r\n return\r\n }\r\n if (e.touches.length === 1 && touchDragRef.current !== null) {\r\n e.preventDefault()\r\n const d = touchDragRef.current\r\n const tp = e.touches[0]\r\n if (Math.abs(tp.clientX - d.sx) > 4 || Math.abs(tp.clientY - d.sy) > 4) movedRef.current = true\r\n setPos({ x: d.spx + tp.clientX - d.sx, y: d.spy + tp.clientY - d.sy })\r\n }\r\n }, [])\r\n\r\n const onTouchEndCb = useCallback((e: TouchEvent) => {\r\n if (e.touches.length === 1) {\r\n // Two fingers → one: re-baseline the pan against the finger left down,\r\n // or lifting one finger would snap the picture back by its offset.\r\n const tp = e.touches[0]\r\n touchDragRef.current = { sx: tp.clientX, sy: tp.clientY, spx: viewRef.current.pos.x, spy: viewRef.current.pos.y }\r\n pinchRef.current = null\r\n } else if (e.touches.length === 0) {\r\n touchDragRef.current = null\r\n pinchRef.current = null\r\n }\r\n }, [])\r\n\r\n // Bound once the overlay node exists — see the note on `overlayEl` above for\r\n // why keying this off a plain ref silently attached nothing.\r\n useEffect(() => {\r\n if (!overlayEl) return\r\n const noPageGesture = (e: Event): void => e.preventDefault()\r\n overlayEl.addEventListener('wheel', onWheelCb, { passive: false })\r\n overlayEl.addEventListener('touchstart', onTouchStartCb, { passive: false })\r\n overlayEl.addEventListener('touchmove', onTouchMoveCb, { passive: false })\r\n overlayEl.addEventListener('touchend', onTouchEndCb, { passive: false })\r\n overlayEl.addEventListener('touchcancel', onTouchEndCb, { passive: false })\r\n // WebKit's legacy page-zoom gestures (iOS). touch-action:none covers modern\r\n // iOS by itself; this is insurance for older in-app WebViews, where a\r\n // two-finger pinch would otherwise still scale the whole viewport.\r\n overlayEl.addEventListener('gesturestart', noPageGesture, { passive: false })\r\n overlayEl.addEventListener('gesturechange', noPageGesture, { passive: false })\r\n overlayEl.addEventListener('gestureend', noPageGesture, { passive: false })\r\n return () => {\r\n overlayEl.removeEventListener('wheel', onWheelCb)\r\n overlayEl.removeEventListener('touchstart', onTouchStartCb)\r\n overlayEl.removeEventListener('touchmove', onTouchMoveCb)\r\n overlayEl.removeEventListener('touchend', onTouchEndCb)\r\n overlayEl.removeEventListener('touchcancel', onTouchEndCb)\r\n overlayEl.removeEventListener('gesturestart', noPageGesture)\r\n overlayEl.removeEventListener('gesturechange', noPageGesture)\r\n overlayEl.removeEventListener('gestureend', noPageGesture)\r\n }\r\n }, [overlayEl, onWheelCb, onTouchStartCb, onTouchMoveCb, onTouchEndCb])\r\n\r\n const resetView = useCallback(() => {\r\n if (imgSize.w === 0) return\r\n setZoom(1); setPos({ x: (pw - imgSize.w) / 2, y: (ph - imgSize.h) / 2 })\r\n }, [pw, ph, imgSize])\r\n\r\n return (\r\n <Portal>\r\n <div\r\n ref={setOverlayEl}\r\n className=\"dab-overlay\"\r\n style={{\r\n // The modal owns every gesture inside it: without this, a pinch or a\r\n // drag started on the dimmed backdrop is claimed by the browser, which\r\n // pinches the viewport and rubber-bands the page behind the editor.\r\n // Scoped to this overlay rather than the shared .dab-overlay class —\r\n // the color picker shares that class and must stay scrollable.\r\n touchAction: 'none', overscrollBehavior: 'contain',\r\n }}\r\n onClick={e => {\r\n // A pan that ended on the backdrop would otherwise fire a click whose\r\n // target is the nearest common ancestor — the overlay — and close the\r\n // editor, throwing away the adjustment mid-drag.\r\n if (movedRef.current) { movedRef.current = false; return }\r\n if (e.target === e.currentTarget) onClose()\r\n }}\r\n onMouseDown={() => { movedRef.current = false }}\r\n >\r\n <div className=\"dab-overlay-title\">{t('editorTitle')}</div>\r\n <div ref={containerRef} className=\"dab-modal-card\" style={{\r\n position: 'relative', overflow: 'hidden', border: '2px solid rgba(255,255,255,0.3)',\r\n borderRadius: 12, background: '#000', cursor: 'grab', width: pw, height: ph,\r\n // Hand the area's default pan/pinch gestures to the touch handlers\r\n // above: without this the page scrolls and the browser pinch-zooms\r\n // the viewport instead of scaling the picture.\r\n touchAction: 'none', WebkitUserSelect: 'none', userSelect: 'none',\r\n }} onMouseDown={onDown}>\r\n <img ref={imgRef} src={url} alt=\"\" draggable={false} style={{\r\n position: 'absolute', transformOrigin: '0 0', pointerEvents: 'none',\r\n width: imgSize.w, height: imgSize.h,\r\n transform: `translate(${pos.x}px,${pos.y}px) scale(${zoom})`,\r\n }} />\r\n </div>\r\n <div className=\"dab-overlay-hint\">{t('editorHint')}</div>\r\n <div style={{ display: 'flex', gap: 10 }}>\r\n <button type=\"button\" className=\"dab-btn\" onClick={resetView}>{t('editorReset')}</button>\r\n <button type=\"button\" className=\"dab-btn\" onClick={onClose}>{t('editorCancel')}</button>\r\n <button type=\"button\" className=\"dab-btn\" onClick={() => onCommit(zoom, (pos.x + imgSize.w * zoom / 2) / pw, (pos.y + imgSize.h * zoom / 2) / ph, imgRef.current?.naturalWidth ?? 0, imgRef.current?.naturalHeight ?? 0)}>{t('editorCommit')}</button>\r\n </div>\r\n </div>\r\n </Portal>\r\n )\r\n}\r\n","import { useEffect, useRef, useState } from 'react'\r\nimport type { CSSProperties } from 'react'\r\nimport type { ThemeSectionProps, ThemeStoreState, BackgroundType, GeneratedBgParams, BgMode } from '../../types'\r\nimport { cfg, rWop, rBl, rBgMode } from '../../state'\r\nimport { saveConfig, setWallpaperFromUrl, uploadWallpaper, uploadRefusalText, WALLPAPER_SERVE_URL } from '../../rpc'\r\nimport { applyWp, setWpOpacity, setWpBlur, pauseGeneratedBg, resumeGeneratedBg } from '../../wallpaper'\r\nimport { defaultParamsFor } from '../../utils/bg-generators'\r\nimport { BgEditor } from '../BgEditor'\r\nimport { LiveSlider } from '../LiveSlider'\r\nimport { LockIcon, CheckIcon, PhotoIcon, RefreshIcon, SparkleIcon, TrashIcon, UploadIcon, EditIcon, VideoIcon, LinkIcon, PlusIcon, XIcon, PlayIcon, PauseIcon } from '../icons'\r\n\r\nconst SEG_W = 108\r\nconst BG_MODES: Array<{ mode: BgMode; labelKey: string }> = [\r\n { mode: 'fit', labelKey: 'bgModeFit' },\r\n { mode: 'fill', labelKey: 'bgModeFill' },\r\n { mode: 'stretch', labelKey: 'bgModeStretch' },\r\n { mode: 'tile', labelKey: 'bgModeTile' },\r\n { mode: 'center', labelKey: 'bgModeCenter' },\r\n]\r\n\r\nexport function BackgroundPage({ p, notify }: { p: ThemeSectionProps; notify: (msg: string, ok?: boolean) => void }) {\r\n const { t, setWpFromServer, setVideo, setWop, setBl, setBgType, setGeneratedBg, regenerateBg, setRegenerateOnReload, setRotation, addRotationItems, removeRotationItem, rotateNow, setVideoFromUrl, useStore } = p\r\n // Field-level store subscriptions: dragging sliders / picking colors changes\r\n // only the color fields, and the background page has no reason to re-render\r\n // for those — full-state subscription re-renders this whole page (hero img,\r\n // thumbnails, sliders) on every unrelated store write.\r\n const storeUrl = useStore((s: ThemeStoreState) => s.url)\r\n const backgroundType = useStore((s: ThemeStoreState) => s.backgroundType)\r\n const generatedBg = useStore((s: ThemeStoreState) => s.generatedBg)\r\n const regenerateOnReload = useStore((s: ThemeStoreState) => s.regenerateOnReload)\r\n const rotation = useStore((s: ThemeStoreState) => s.rotation)\r\n\r\n const fileRef = useRef<HTMLInputElement>(null)\r\n const rotFileRef = useRef<HTMLInputElement>(null)\r\n const [editorOpen, setEditorOpen] = useState(false)\r\n const [dragOver, setDragOver] = useState(false)\r\n const [spinTick, setSpinTick] = useState(0)\r\n const [rotBusy, setRotBusy] = useState(false)\r\n const [urlOpen, setUrlOpen] = useState(false)\r\n const [urlVal, setUrlVal] = useState('')\r\n const [urlBusy, setUrlBusy] = useState(false)\r\n const [urlErr, setUrlErr] = useState<string | null>(null)\r\n // Layout mode is owned by cfg (persisted on click); local mirror only so\r\n // the chip row re-renders on selection. It must re-derive from cfg whenever\r\n // the store's bgRev moves: importTheme rewrites cfg.bgMode through\r\n // adoptConfig without touching this local state, which would otherwise leave\r\n // the chips — and the `mode === 'fit'` editor gate below — showing the\r\n // abandoned layout mode.\r\n const bgRev = useStore((s: ThemeStoreState) => s.bgRev)\r\n const [mode, setModeState] = useState<BgMode>(rBgMode())\r\n useEffect(() => { setModeState(rBgMode()) }, [bgRev])\r\n\r\n const isVideo = backgroundType === 'video'\r\n const isStatic = backgroundType === 'image' || isVideo\r\n const isGenerated = !isStatic\r\n const activeGenType: Exclude<BackgroundType, 'image' | 'video'> = isGenerated && generatedBg ? generatedBg.type : 'mesh'\r\n\r\n // Session-only pause state; any controller swap (type switch, regenerate)\r\n // recreates the loop running, so reset the button to match.\r\n const [paused, setPaused] = useState(false)\r\n const genPreset = generatedBg !== null && generatedBg.type !== 'mesh' ? generatedBg.preset : undefined\r\n useEffect(() => { setPaused(false) }, [activeGenType, genPreset, generatedBg?.seed])\r\n\r\n const onFileSelect = async (f: File): Promise<void> => {\r\n if (f.type.startsWith('video/')) {\r\n // Hand the raw file over directly: it streams to disk over the\r\n // binary upload route. A data-URL detour would inflate the bytes by a\r\n // third (base64) and blow the RPC body limit on large clips. The clip\r\n // plays from a local object URL straight away, so only a refusal of the\r\n // background upload needs saying — silently it would just fail to persist\r\n // and be gone after a reload.\r\n const outcome = await setVideo(f, f.type)\r\n if (!outcome.ok) notify(uploadRefusalText(outcome, t, 'videoUploadFail'), false)\r\n return\r\n }\r\n // Stream the original bytes straight to disk (no base64 round-trip, no\r\n // re-encoding), then point the wallpaper at the serve URL. The browser\r\n // decodes it natively like any <img>.\r\n const outcome = await uploadWallpaper(f)\r\n if (outcome.ok) setWpFromServer(WALLPAPER_SERVE_URL)\r\n else notify(uploadRefusalText(outcome, t, 'bgUploadFail'), false)\r\n }\r\n\r\n const onDrop = (e: React.DragEvent) => {\r\n e.preventDefault()\r\n setDragOver(false)\r\n const f = e.dataTransfer.files?.[0]\r\n if (f && (f.type.startsWith('image/') || f.type.startsWith('video/'))) void onFileSelect(f)\r\n }\r\n\r\n const applyUrl = async () => {\r\n const u = urlVal.trim()\r\n if (!/^https?:\\/\\//i.test(u)) { setUrlErr(t('bgUrlBadHttp')); return }\r\n setUrlBusy(true)\r\n setUrlErr(null)\r\n const r = await setWallpaperFromUrl(u)\r\n if (r.ok) {\r\n // The host already replaced the local wallpaper file; just switch the\r\n // theme to image mode and point the display at the serve URL.\r\n setWpFromServer(r.wallpaperUrl ?? null)\r\n setUrlOpen(false)\r\n setUrlVal('')\r\n } else if (r.error === 'not an image') {\r\n // A video URL: stream it into the video slot through the server and\r\n // play from the serve route.\r\n const ok = await setVideoFromUrl(u)\r\n if (ok) {\r\n setUrlOpen(false)\r\n setUrlVal('')\r\n } else {\r\n setUrlErr(t('bgUrlVideoFail'))\r\n }\r\n } else {\r\n setUrlErr(r.error === 'invalid url' || r.error === 'unsupported scheme'\r\n ? t('bgUrlBadHttp')\r\n : (r.error ?? t('bgUrlFail')))\r\n }\r\n setUrlBusy(false)\r\n }\r\n\r\n const switchToStatic = () => {\r\n if (isStatic) return\r\n setBgType(isVideo || cfg.videoMime !== null ? 'video' : 'image')\r\n }\r\n\r\n const setMode = (m: BgMode) => {\r\n if (m === mode) return\r\n setModeState(m)\r\n cfg.bgMode = m\r\n applyWp()\r\n saveConfig()\r\n }\r\n\r\n const setGenType = (type: Exclude<BackgroundType, 'image' | 'video'>) => {\r\n if (type === activeGenType) return\r\n setPaused(false)\r\n setBgType(type)\r\n }\r\n\r\n const ensureGenParams = (): GeneratedBgParams => generatedBg ?? defaultParamsFor(activeGenType)\r\n\r\n const updateGenerated = (patch: Partial<GeneratedBgParams>) => {\r\n // Any parameter change rebuilds the live controller, which restarts the\r\n // animation loop — reset the paused state so the button stays truthful.\r\n setPaused(false)\r\n setGeneratedBg({ ...ensureGenParams(), ...patch } as GeneratedBgParams)\r\n }\r\n\r\n const typeMeta: Array<{ type: Exclude<BackgroundType, 'image' | 'video'>; labelKey: string; descKey: string; thumb: string }> = [\r\n { type: 'mesh', labelKey: 'bgTypeMesh', descKey: 'bgMeshDesc', thumb: 'dab-thumb-mesh' },\r\n { type: 'shader', labelKey: 'bgTypeShader', descKey: 'bgShaderDesc', thumb: 'dab-thumb-shader' },\r\n { type: 'pattern', labelKey: 'bgTypePattern', descKey: 'bgPatternDesc', thumb: 'dab-thumb-pattern' },\r\n ]\r\n\r\n const presetLabel = (key: string) => {\r\n switch (key) {\r\n case 'aurora': return t('presetAurora')\r\n case 'nebula': return t('presetNebula')\r\n case 'noise': return t('presetNoise')\r\n case 'starfield': return t('presetStarfield')\r\n case 'dots': return t('presetDots')\r\n case 'waves': return t('presetWaves')\r\n case 'poly': return t('presetPoly')\r\n case 'rain': return t('presetRain')\r\n case 'contour': return t('presetContour')\r\n case 'meta': return t('presetMeta')\r\n default: return key\r\n }\r\n }\r\n\r\n return (\r\n <>\r\n <header className=\"dab-head dab-rise\" style={{ '--d': 0 } as CSSProperties}>\r\n <div className=\"dab-overline\">Canvas</div>\r\n <h2 className=\"dab-h1\">{t('bgTitle')}</h2>\r\n <p className=\"dab-desc\">{t('descBackground')}</p>\r\n </header>\r\n\r\n {/* Preview hero with hover veil */}\r\n <section className=\"dab-rise\" style={{ '--d': 1 } as CSSProperties}>\r\n <div className=\"dab-hero\">\r\n {storeUrl ? (\r\n <>\r\n <img className=\"dab-hero-img\" src={storeUrl} alt=\"\" draggable={false} />\r\n {isGenerated ? (\r\n <span className=\"dab-hero-badge\"><SparkleIcon size={11} />{t('liveBadge')}</span>\r\n ) : isVideo ? (\r\n <span className=\"dab-hero-badge\"><VideoIcon size={11} />{t('bgVideoBadge')}</span>\r\n ) : null}\r\n <div className=\"dab-hero-veil\">\r\n {isStatic && storeUrl ? (\r\n <button type=\"button\" className=\"dab-btn\" disabled={mode !== 'fit'}\r\n title={mode !== 'fit' ? t('bgEditLocked') : undefined}\r\n onClick={() => setEditorOpen(true)}>\r\n <EditIcon size={13} />{t('bgEdit')}\r\n </button>\r\n ) : isGenerated ? (\r\n <button type=\"button\" className=\"dab-btn\" onClick={() => { setPaused(false); regenerateBg(); setSpinTick(x => x + 1) }}>\r\n <RefreshIcon size={13} />{t('bgRegenerate')}\r\n </button>\r\n ) : null}\r\n <button type=\"button\" className=\"dab-btn dab-btn-danger\" onClick={() => setWpFromServer(null)}>\r\n <TrashIcon size={13} />{t('bgRemove')}\r\n </button>\r\n </div>\r\n </>\r\n ) : (\r\n <button\r\n type=\"button\"\r\n className={`dab-hero-empty${dragOver ? ' is-over' : ''}`}\r\n onClick={() => fileRef.current?.click()}\r\n onDragOver={e => { e.preventDefault(); setDragOver(true) }}\r\n onDragLeave={() => setDragOver(false)}\r\n onDrop={onDrop}>\r\n <UploadIcon size={20} />\r\n <span>{t('dropHint')}</span>\r\n </button>\r\n )}\r\n </div>\r\n </section>\r\n\r\n {/* Source segmented control */}\r\n <section className=\"dab-rise\" style={{ '--d': 2 } as CSSProperties}>\r\n <div className=\"dab-seg\" style={{ '--w': `${SEG_W}px` } as CSSProperties}>\r\n <div className=\"dab-seg-thumb\" style={{ transform: `translateX(${isGenerated ? SEG_W : 0}px)` }} />\r\n <button type=\"button\" className={`dab-seg-item${!isGenerated ? ' is-active' : ''}`} onClick={switchToStatic}>\r\n <PhotoIcon size={14} />{t('bgSourceImage')}\r\n </button>\r\n <button type=\"button\" className={`dab-seg-item${isGenerated ? ' is-active' : ''}`}\r\n onClick={() => { if (!isGenerated) setBgType(generatedBg?.type ?? 'mesh') }}>\r\n <SparkleIcon size={14} />{t('bgSourceGenerated')}\r\n </button>\r\n </div>\r\n </section>\r\n\r\n {/* Mode content */}\r\n {!isGenerated ? (\r\n <>\r\n <section className=\"dab-card dab-card-hover dab-rise\" style={{ '--d': 3 } as CSSProperties}>\r\n <div className=\"dab-chip-row\">\r\n <button type=\"button\" className=\"dab-btn dab-btn-primary\" onClick={() => fileRef.current?.click()}>\r\n <UploadIcon size={14} />{t('bgChoose')}\r\n </button>\r\n <button type=\"button\" className=\"dab-btn dab-btn-soft\" onClick={() => setUrlOpen(o => !o)}>\r\n <LinkIcon size={14} />{t('bgFromUrl')}\r\n </button>\r\n {storeUrl || isVideo ? (\r\n <>\r\n {isStatic && storeUrl ? (\r\n <button type=\"button\" className=\"dab-btn\" disabled={mode !== 'fit'}\r\n title={mode !== 'fit' ? t('bgEditLocked') : undefined}\r\n onClick={() => setEditorOpen(true)}>\r\n <EditIcon size={14} />{t('bgEdit')}\r\n </button>\r\n ) : null}\r\n <button type=\"button\" className=\"dab-btn dab-btn-danger-inverted\" onClick={() => setWpFromServer(null)}>\r\n <TrashIcon size={14} />{t('bgRemove')}\r\n </button>\r\n </>\r\n ) : null}\r\n </div>\r\n {urlOpen ? (\r\n <div className=\"dab-urlrow\">\r\n <input type=\"text\" className=\"dab-urlinput\" value={urlVal} placeholder={t('bgUrlPlaceholder')}\r\n onChange={e => setUrlVal(e.target.value)}\r\n onKeyDown={e => { if (e.key === 'Enter') { e.preventDefault(); void applyUrl() } }}\r\n autoFocus />\r\n <button type=\"button\" className=\"dab-btn dab-btn-primary\" disabled={urlBusy} onClick={() => void applyUrl()}>\r\n {urlBusy ? t('bgUrlApplying') : t('bgUrlApply')}\r\n </button>\r\n <button type=\"button\" className=\"dab-btn\" onClick={() => { setUrlOpen(false); setUrlVal(''); setUrlErr(null) }}>\r\n {t('bgUrlCancel')}\r\n </button>\r\n </div>\r\n ) : null}\r\n {urlErr ? (\r\n <p className=\"dab-urlerr\" style={{ marginTop: 8, color: 'var(--dsw-alias-state-error-primary)', fontSize: 12 }}>{urlErr}</p>\r\n ) : null}\r\n {/* Adaptive placement for image/video backgrounds. \"fit\" keeps the\r\n editor-committed framing; the pan/zoom editor only applies there. */}\r\n <div style={{ marginTop: 16 }}>\r\n <div className=\"dab-swatch-title\">{t('bgModeTitle')}</div>\r\n <div className=\"dab-chip-row\">\r\n {BG_MODES.map(m => (\r\n <button key={m.mode} type=\"button\" className={`dab-chip${mode === m.mode ? ' is-active' : ''}`}\r\n onClick={() => setMode(m.mode)}>\r\n {t(m.labelKey)}\r\n </button>\r\n ))}\r\n </div>\r\n </div>\r\n </section>\r\n\r\n {/* Wallpaper rotation pool */}\r\n <section className=\"dab-card dab-rise\" style={{ '--d': 4 } as CSSProperties}>\r\n <div className=\"dab-row-head\">\r\n <div className=\"dab-swatch-title\" style={{ marginBottom: 0 }}>{t('rotTitle')}</div>\r\n <button type=\"button\" className={`dab-toggle${rotation.enabled ? ' is-on' : ''}`} role=\"switch\" aria-checked={rotation.enabled}\r\n onClick={() => setRotation({ enabled: !rotation.enabled })}>\r\n <span className=\"dab-toggle-knob\" />\r\n </button>\r\n </div>\r\n <p className=\"dab-hint\" style={{ marginTop: 8 }}>{t('rotHint')}</p>\r\n <div className=\"dab-thumbstrip\">\r\n {rotation.items.map((it, i) => (\r\n <div key={it.file} className={`dab-thumb${rotation.enabled && i === rotation.current ? ' is-current' : ''}`}>\r\n {it.thumb ? <img src={it.thumb} alt=\"\" draggable={false} /> : <PhotoIcon size={15} />}\r\n <button type=\"button\" className=\"dab-thumb-x\" title={t('rotRemove')}\r\n disabled={rotBusy} onClick={() => { setRotBusy(true); void removeRotationItem(i).finally(() => setRotBusy(false)) }}>\r\n <XIcon size={10} />\r\n </button>\r\n </div>\r\n ))}\r\n <button type=\"button\" className=\"dab-thumb dab-thumb-add\" title={t('rotAdd')} disabled={rotBusy}\r\n onClick={() => rotFileRef.current?.click()}>\r\n <PlusIcon size={16} />\r\n </button>\r\n </div>\r\n {rotation.items.length > 0 ? (\r\n <div className=\"dab-chip-row\" style={{ marginTop: 12 }}>\r\n <button type=\"button\" className={`dab-chip${rotation.mode === 'shuffle' ? ' is-active' : ''}`}\r\n onClick={() => setRotation({ mode: 'shuffle' })}>{t('rotShuffle')}</button>\r\n <button type=\"button\" className={`dab-chip${rotation.mode === 'order' ? ' is-active' : ''}`}\r\n onClick={() => setRotation({ mode: 'order' })}>{t('rotOrder')}</button>\r\n <span className=\"dab-chip-sep\" />\r\n <button type=\"button\" className={`dab-chip${rotation.interval === 'reload' ? ' is-active' : ''}`}\r\n onClick={() => setRotation({ interval: 'reload' })}>{t('rotReload')}</button>\r\n <button type=\"button\" className={`dab-chip${rotation.interval === 'daily' ? ' is-active' : ''}`}\r\n onClick={() => setRotation({ interval: 'daily' })}>{t('rotDaily')}</button>\r\n <button type=\"button\" className={`dab-chip${rotation.interval === 'weekly' ? ' is-active' : ''}`}\r\n onClick={() => setRotation({ interval: 'weekly' })}>{t('rotWeekly')}</button>\r\n <button type=\"button\" className=\"dab-btn\" disabled={rotBusy}\r\n onClick={() => { setRotBusy(true); void rotateNow().finally(() => setRotBusy(false)) }}>\r\n <RefreshIcon size={13} />{t('rotNow')}\r\n </button>\r\n </div>\r\n ) : null}\r\n <input ref={rotFileRef} type=\"file\" accept=\"image/*\" multiple style={{ display: 'none' }} onChange={e => {\r\n const files = Array.from(e.target.files ?? [])\r\n e.target.value = ''\r\n if (files.length === 0) return\r\n setRotBusy(true)\r\n void addRotationItems(files).finally(() => setRotBusy(false))\r\n }} />\r\n </section>\r\n </>\r\n ) : (\r\n <section className=\"dab-card dab-rise\" style={{ '--d': 3 } as CSSProperties}>\r\n {/* Type cards with animated thumbnails */}\r\n <div className=\"dab-types\">\r\n {typeMeta.map((m, i) => (\r\n <button key={m.type} type=\"button\" className={`dab-type${activeGenType === m.type ? ' is-active' : ''}`}\r\n style={{ '--i': i } as CSSProperties} onClick={() => setGenType(m.type)}>\r\n <div className={`dab-type-thumb ${m.thumb}`} />\r\n <div className=\"dab-type-name\">{t(m.labelKey)}</div>\r\n <div className=\"dab-type-desc\">{t(m.descKey)}</div>\r\n <span className=\"dab-type-check\"><CheckIcon size={11} /></span>\r\n </button>\r\n ))}\r\n </div>\r\n\r\n {/* Presets (shader / pattern) */}\r\n {activeGenType === 'shader' && generatedBg?.type === 'shader' ? (\r\n <div style={{ marginTop: 14 }}>\r\n <div className=\"dab-swatch-title\">{t('bgShaderPreset')}</div>\r\n <div className=\"dab-chip-row\">\r\n {(['aurora', 'nebula', 'noise', 'starfield'] as const).map(pr => (\r\n <button key={pr} type=\"button\" className={`dab-chip${generatedBg.preset === pr ? ' is-active' : ''}`}\r\n onClick={() => updateGenerated({ preset: pr })}>\r\n {presetLabel(pr)}\r\n </button>\r\n ))}\r\n </div>\r\n </div>\r\n ) : null}\r\n\r\n {activeGenType === 'pattern' && generatedBg?.type === 'pattern' ? (\r\n <div style={{ marginTop: 14 }}>\r\n <div className=\"dab-swatch-title\">{t('bgPatternPreset')}</div>\r\n <div className=\"dab-chip-row\">\r\n {(['dots', 'waves', 'poly', 'rain', 'contour', 'meta'] as const).map(pr => (\r\n <button key={pr} type=\"button\" className={`dab-chip${generatedBg.preset === pr ? ' is-active' : ''}`}\r\n onClick={() => updateGenerated({ preset: pr })}>\r\n {presetLabel(pr)}\r\n </button>\r\n ))}\r\n </div>\r\n </div>\r\n ) : null}\r\n\r\n {/* Parameter sliders */}\r\n <div style={{ marginTop: 16 }}>\r\n {activeGenType === 'mesh' && generatedBg?.type === 'mesh' ? (\r\n <>\r\n <LiveSlider label={t('bgMeshScale')} min={30} max={300} step={1} def={Math.round(generatedBg.scale * 100)}\r\n fmt={v => `${v}%`} onChange={v => updateGenerated({ scale: v / 100 })} />\r\n <LiveSlider label={t('bgMeshIntensity')} min={0} max={100} step={1} def={Math.round(generatedBg.intensity * 100)}\r\n fmt={v => `${v}%`} onChange={v => updateGenerated({ intensity: v / 100 })} />\r\n </>\r\n ) : null}\r\n {activeGenType === 'shader' && generatedBg?.type === 'shader' ? (\r\n <>\r\n <LiveSlider label={t('bgShaderSpeed')} min={0} max={200} step={1} def={Math.round(generatedBg.speed * 100)}\r\n fmt={v => `${v}%`} onChange={v => updateGenerated({ speed: v / 100 })} />\r\n <LiveSlider label={t('bgShaderScale')} min={30} max={300} step={1} def={Math.round(generatedBg.scale * 100)}\r\n fmt={v => `${v}%`} onChange={v => updateGenerated({ scale: v / 100 })} />\r\n </>\r\n ) : null}\r\n {activeGenType === 'pattern' && generatedBg?.type === 'pattern' ? (\r\n <>\r\n <LiveSlider label={t('bgPatternDensity')} min={0} max={100} step={1} def={Math.round(generatedBg.density * 100)}\r\n fmt={v => `${v}%`} onChange={v => updateGenerated({ density: v / 100 })} />\r\n <LiveSlider label={t('bgPatternScale')} min={30} max={300} step={1} def={Math.round(generatedBg.scale * 100)}\r\n fmt={v => `${v}%`} onChange={v => updateGenerated({ scale: v / 100 })} />\r\n </>\r\n ) : null}\r\n </div>\r\n\r\n {/* Seed lock + regenerate + pause */}\r\n <div className=\"dab-seed\">\r\n <span className=\"dab-seed-ico\"><LockIcon size={15} /></span>\r\n <div className=\"dab-seed-txt\">\r\n <div className=\"dab-seed-title\">{t('seedLock')}</div>\r\n <div className=\"dab-seed-desc\">{!regenerateOnReload ? t('bgSeedLocked') : t('bgSeedUnlocked')}</div>\r\n </div>\r\n <button type=\"button\" className={`dab-toggle${!regenerateOnReload ? ' is-on' : ''}`}\r\n role=\"switch\" aria-checked={!regenerateOnReload}\r\n onClick={() => setRegenerateOnReload(!regenerateOnReload)}>\r\n <span className=\"dab-toggle-knob\" />\r\n </button>\r\n <button type=\"button\" className=\"dab-btn\" onClick={() => {\r\n if (paused) { resumeGeneratedBg(); setPaused(false) }\r\n else { pauseGeneratedBg(); setPaused(true) }\r\n }}>\r\n {paused ? <PlayIcon size={13} /> : <PauseIcon size={13} />}{paused ? t('bgResume') : t('bgPause')}\r\n </button>\r\n <button type=\"button\" className=\"dab-btn dab-btn-primary\" onClick={() => { regenerateBg(); setPaused(false); setSpinTick(x => x + 1) }}>\r\n <span key={spinTick} className=\"dab-spin\" style={{ display: 'grid' }}><RefreshIcon size={13} /></span>\r\n {t('bgRegenerate')}\r\n </button>\r\n </div>\r\n </section>\r\n )}\r\n\r\n {/* Global wallpaper adjustments */}\r\n <section className=\"dab-card dab-card-hover dab-rise\" style={{ '--d': 5 } as CSSProperties}>\r\n <LiveSlider label={t('wpOpacity')} min={0} max={100} step={1} def={Math.round(rWop() * 100)}\r\n fmt={v => `${v}%`}\r\n onInput={v => { const op = v / 100; cfg.wallpaperOpacity = op; setWpOpacity(op); saveConfig() }}\r\n onChange={v => setWop(v / 100)} />\r\n <LiveSlider label={t('bgBlur')} min={0} max={60} step={1} def={rBl()}\r\n fmt={v => `${v}px`}\r\n onInput={v => { cfg.blur = v; setWpBlur(v); saveConfig() }}\r\n onChange={v => setBl(v)} />\r\n <p className=\"dab-hint\" style={{ marginTop: 12 }}>{t('bgHint')}</p>\r\n </section>\r\n\r\n <input ref={fileRef} type=\"file\" accept=\"image/*,video/*\" style={{ display: 'none' }} onChange={e => {\r\n const f = e.target.files?.[0]; if (!f) return\r\n void onFileSelect(f); e.target.value = ''\r\n }} />\r\n\r\n {/* Background editor modal (image/video + fit mode only). For videos\r\n the reference is the captured frame snapshot — same pixels as the\r\n playing video, so the committed framing maps 1:1 onto the layer. */}\r\n {editorOpen && storeUrl && isStatic && mode === 'fit' ? (\r\n <BgEditor url={storeUrl} t={t} onClose={() => setEditorOpen(false)}\r\n onCommit={(z, x, y, iw, ih) => {\r\n const st = { zoom: z, x, y, iw, ih }\r\n if (backgroundType === 'video') cfg.videoBgState = st\r\n else cfg.bgState = st\r\n applyWp(); saveConfig(); setEditorOpen(false)\r\n }} />\r\n ) : null}\r\n </>\r\n )\r\n}\r\n","import type { PartStrokes, ProfileAppearance, StrokeConfig } from '../types'\n\n/**\n * Built-in appearance presets. Each bundles the surface parameters a profile\n * stores (color, per-part opacities/blurs, tints) — never the wallpaper\n * itself, which stays machine-local. Applying a preset is identical to\n * applying a saved profile.\n */\nexport interface BuiltinPreset {\n key: string\n appearance: ProfileAppearance\n}\n\nconst zeroBlurs = { bg: 0, sidebar: 0, card: 0, settings: 0, chat: 0, trajectory: 0, input: 0, panel: 0, produced: 0, header: 0 }\n\n/** Presets ship with strokes off — text outlines are an opt-in look. Fresh\n * objects per call so a profile restore can never alias another preset's\n * stroke config (applyAppearance copies, but mutation-proofing is free). */\nconst zeroStrokes = (): PartStrokes => {\n const off = (): StrokeConfig => ({ width: 0, color: 'auto', customColor: '#808080' })\n return {\n bg: off(), sidebar: off(), card: off(), settings: off(), chat: off(),\n trajectory: off(), input: off(), panel: off(), produced: off(), header: off(),\n }\n}\n\nexport const BUILTIN_PRESETS: BuiltinPreset[] = [\n {\n key: 'default',\n appearance: {\n color: null,\n opacities: { bg: 0.85, sidebar: 0.93, card: 1, input: 1 },\n blurs: { ...zeroBlurs },\n strokes: zeroStrokes(),\n settingsOpacity: 1,\n wallpaperOpacity: 1,\n blur: 0,\n chatTextOpacity: 0,\n trajectoryOpacity: 1,\n panelOpacity: 1,\n producedOpacity: 1,\n headerOpacity: 1,\n },\n },\n {\n // Frosted glass: translucent surfaces over a sharp wallpaper, blurred shell.\n key: 'glass',\n appearance: {\n color: [212, 0.5, 0.38],\n opacities: { bg: 0.62, sidebar: 0.55, card: 0.62, input: 0.58 },\n blurs: { ...zeroBlurs, bg: 20, sidebar: 14, card: 12, settings: 20, trajectory: 8, input: 14, panel: 12 },\n strokes: zeroStrokes(),\n settingsOpacity: 0.88,\n wallpaperOpacity: 1,\n blur: 0,\n chatTextOpacity: 0,\n trajectoryOpacity: 0.85,\n panelOpacity: 0.85,\n producedOpacity: 1,\n headerOpacity: 1,\n },\n },\n {\n // Minimal: near-solid surfaces, no frost, system theme color.\n key: 'minimal',\n appearance: {\n color: null,\n opacities: { bg: 0.97, sidebar: 0.97, card: 1, input: 1 },\n blurs: { ...zeroBlurs },\n strokes: zeroStrokes(),\n settingsOpacity: 1,\n wallpaperOpacity: 1,\n blur: 0,\n chatTextOpacity: 0,\n trajectoryOpacity: 1,\n panelOpacity: 1,\n producedOpacity: 1,\n headerOpacity: 1,\n },\n },\n {\n // Midnight: deep violet accent, dark scheme, heavy frost.\n key: 'midnight',\n appearance: {\n color: [262, 0.45, 0.16],\n opacities: { bg: 0.5, sidebar: 0.45, card: 0.55, input: 0.6 },\n blurs: { ...zeroBlurs, bg: 24, sidebar: 18, card: 14, settings: 22, trajectory: 10, input: 16, panel: 16 },\n strokes: zeroStrokes(),\n settingsOpacity: 0.85,\n wallpaperOpacity: 0.92,\n blur: 2,\n chatTextOpacity: 0,\n trajectoryOpacity: 0.8,\n panelOpacity: 0.8,\n producedOpacity: 1,\n headerOpacity: 1,\n },\n },\n {\n // Cyber: vivid magenta accent over barely-there surfaces.\n key: 'cyber',\n appearance: {\n color: [315, 0.7, 0.22],\n opacities: { bg: 0.42, sidebar: 0.5, card: 0.45, input: 0.55 },\n blurs: { ...zeroBlurs, bg: 16, sidebar: 12, card: 10, settings: 18, trajectory: 6, input: 20, panel: 18 },\n strokes: zeroStrokes(),\n settingsOpacity: 0.8,\n wallpaperOpacity: 1,\n blur: 0,\n chatTextOpacity: 0,\n trajectoryOpacity: 0.78,\n panelOpacity: 0.75,\n producedOpacity: 1,\n headerOpacity: 1,\n },\n },\n {\n // Warm daylight: amber accent, solid light surfaces.\n key: 'warm',\n appearance: {\n color: [28, 0.6, 0.72],\n opacities: { bg: 0.92, sidebar: 0.95, card: 1, input: 1 },\n blurs: { ...zeroBlurs },\n strokes: zeroStrokes(),\n settingsOpacity: 1,\n wallpaperOpacity: 1,\n blur: 0,\n chatTextOpacity: 0,\n trajectoryOpacity: 1,\n panelOpacity: 1,\n producedOpacity: 1,\n headerOpacity: 1,\n },\n },\n]\n","import { useRef, useState } from 'react'\nimport type { CSSProperties } from 'react'\nimport type { ThemeSectionProps, ThemeStoreState, ProfileEntry, ScheduleConfig } from '../../types'\nimport { BUILTIN_PRESETS } from '../../utils/presets'\nimport { hslToRgb } from '../../utils/color'\nimport { DownloadIcon, UploadIcon, CheckIcon, PlusIcon, SunIcon, MoonIcon, ClockIcon } from '../icons'\n\nconst hexOf = (color: [number, number, number] | null): string =>\n color === null\n ? ''\n : '#' + hslToRgb(color[0], color[1], color[2]).map(v => Math.round(v).toString(16).padStart(2, '0')).join('')\n\nfunction ProfileDot({ entry }: { entry: ProfileEntry }) {\n const hex = hexOf(entry.config.color)\n return (\n <span className=\"dab-profile-dot\" style={hex ? { background: hex } : undefined} title={hex ? hex.toUpperCase() : undefined}>\n {hex ? null : <CheckIcon size={11} />}\n </span>\n )\n}\n\nexport function ProfilePage({ p, notify }: { p: ThemeSectionProps; notify: (msg: string, ok?: boolean) => void }) {\n const { t, exportTheme, importTheme, saveProfile, applyProfile, deleteProfile, applyPreset, setSchedule, useStore } = p\n // Field-level subscriptions: profile list, active id and schedule are the only\n // store fields this page renders — full-state subscription would re-render\n // the whole profile list on every unrelated store write (color, wallpaper…).\n const profiles = useStore((s: ThemeStoreState) => s.profiles)\n const schedule = useStore((s: ThemeStoreState) => s.schedule)\n const activeProfile = useStore((s: ThemeStoreState) => s.activeProfile)\n const importRef = useRef<HTMLInputElement>(null)\n const [nameOpen, setNameOpen] = useState(false)\n const [nameVal, setNameVal] = useState('')\n const [confirmId, setConfirmId] = useState<string | null>(null)\n\n const onImport = async (file: File) => {\n try {\n const ok = await importTheme(file)\n notify(ok ? t('importDone') : t('importFail'), ok)\n } catch {\n notify(t('importFail'), false)\n }\n }\n\n const onSave = (): void => {\n const name = nameVal.trim()\n if (!name) return\n if (saveProfile(name)) {\n notify(t('profileSaved'), true)\n setNameVal('')\n setNameOpen(false)\n } else {\n notify(t('profileNameRequired'), false)\n }\n }\n\n const onApply = (entry: ProfileEntry): void => {\n if (applyProfile(entry.id)) notify(t('profileApplied'), true)\n }\n\n const onDelete = (entry: ProfileEntry): void => {\n if (confirmId !== entry.id) { setConfirmId(entry.id); return }\n setConfirmId(null)\n deleteProfile(entry.id)\n }\n\n const profileOptions = (value: string | null, onChange: (id: string | null) => void) => (\n <select className=\"dab-select\" value={value ?? ''} onChange={e => onChange(e.target.value || null)}>\n <option value=\"\">{t('profileNone')}</option>\n {profiles.map(pr => <option key={pr.id} value={pr.id}>{pr.name}</option>)}\n </select>\n )\n\n const patchSchedule = (patch: Partial<ScheduleConfig>): void => setSchedule(patch)\n\n return (\n <>\n <header className=\"dab-head dab-rise\" style={{ '--d': 0 } as CSSProperties}>\n <div className=\"dab-overline\">Profile</div>\n <h2 className=\"dab-h1\">{t('pageProfile')}</h2>\n <p className=\"dab-desc\">{t('descProfile')}</p>\n </header>\n\n {/* Built-in presets */}\n <section className=\"dab-card dab-rise\" style={{ '--d': 1 } as CSSProperties}>\n <div className=\"dab-swatch-title\">{t('presetGalleryTitle')}</div>\n <div className=\"dab-preset-grid\">\n {BUILTIN_PRESETS.map((ps, i) => {\n const hex = hexOf(ps.appearance.color)\n return (\n <button key={ps.key} type=\"button\" className=\"dab-preset\" style={{ '--i': i } as CSSProperties} onClick={() => { applyPreset(ps.appearance); notify(t('presetApplied')) }}>\n <span className=\"dab-preset-dot\" style={hex ? { background: hex } : undefined}>\n {hex ? null : <CheckIcon size={12} />}\n </span>\n <span className=\"dab-preset-name\">{t(`presetName_${ps.key}`)}</span>\n <span className=\"dab-preset-desc\">{t(`presetDesc_${ps.key}`)}</span>\n </button>\n )\n })}\n </div>\n </section>\n\n {/* Saved profiles */}\n <section className=\"dab-card dab-rise\" style={{ '--d': 2 } as CSSProperties}>\n <div className=\"dab-row-head\">\n <div className=\"dab-swatch-title\" style={{ marginBottom: 0 }}>{t('profilesTitle')}</div>\n <button type=\"button\" className=\"dab-btn dab-btn-primary\" onClick={() => setNameOpen(o => !o)}>\n <PlusIcon size={14} />{t('profileSave')}\n </button>\n </div>\n {nameOpen ? (\n <div className=\"dab-urlrow\">\n <input type=\"text\" className=\"dab-urlinput\" value={nameVal} placeholder={t('profileNamePlaceholder')} maxLength={60}\n onChange={e => setNameVal(e.target.value)}\n onKeyDown={e => { if (e.key === 'Enter') { e.preventDefault(); onSave() } }}\n autoFocus />\n <button type=\"button\" className=\"dab-btn dab-btn-primary\" disabled={!nameVal.trim()} onClick={onSave}>{t('editorCommit')}</button>\n <button type=\"button\" className=\"dab-btn\" onClick={() => { setNameOpen(false); setNameVal('') }}>{t('bgUrlCancel')}</button>\n </div>\n ) : null}\n {profiles.length === 0 ? (\n <p className=\"dab-hint\" style={{ marginTop: 10 }}>{t('profilesEmpty')}</p>\n ) : (\n <div className=\"dab-profile-list\">\n {profiles.map((entry, i) => (\n <div key={entry.id} className={`dab-profile-row${activeProfile === entry.id ? ' is-active' : ''}`} style={{ '--i': i } as CSSProperties}>\n <ProfileDot entry={entry} />\n <div className=\"dab-profile-meta\">\n <span className=\"dab-profile-name\">{entry.name}</span>\n <span className=\"dab-profile-sub\">{new Date(entry.createdAt).toLocaleDateString()}</span>\n </div>\n <button type=\"button\" className=\"dab-btn\" onClick={() => onApply(entry)}>{t('profileApply')}</button>\n <button type=\"button\" className={`dab-btn dab-btn-danger-solid${confirmId === entry.id ? ' dab-btn-confirm' : ''}`}\n title={t('profileDelete')} onClick={() => onDelete(entry)}>\n {confirmId === entry.id ? (\n <><CheckIcon size={13} />{t('profileDeleteConfirm')}</>\n ) : (\n t('profileDelete')\n )}\n </button>\n </div>\n ))}\n </div>\n )}\n </section>\n\n {/* Day/night auto switch */}\n <section className=\"dab-card dab-rise\" style={{ '--d': 3 } as CSSProperties}>\n <div className=\"dab-row-head\">\n <div className=\"dab-swatch-title\" style={{ marginBottom: 0 }}>{t('scheduleTitle')}</div>\n <button type=\"button\" className={`dab-toggle${schedule.enabled ? ' is-on' : ''}`} role=\"switch\" aria-checked={schedule.enabled}\n onClick={() => patchSchedule({ enabled: !schedule.enabled })}>\n <span className=\"dab-toggle-knob\" />\n </button>\n </div>\n <p className=\"dab-hint\" style={{ marginTop: 8 }}>{t('scheduleHint')}</p>\n <div className={`dab-schedule-wrap${schedule.enabled ? ' is-open' : ''}`} aria-hidden={!schedule.enabled}>\n <div className=\"dab-schedule-clip\">\n <div className=\"dab-schedule-grid\">\n <div className=\"dab-schedule-cell\" style={{ '--i': 0 } as CSSProperties}>\n <div className=\"dab-swatch-title\">{t('scheduleMode')}</div>\n <div className=\"dab-chip-row\">\n <button type=\"button\" className={`dab-chip${schedule.mode === 'time' ? ' is-active' : ''}`}\n onClick={() => patchSchedule({ mode: 'time' })}><ClockIcon size={13} />{t('scheduleModeTime')}</button>\n <button type=\"button\" className={`dab-chip${schedule.mode === 'system' ? ' is-active' : ''}`}\n onClick={() => patchSchedule({ mode: 'system' })}>{t('scheduleModeSystem')}</button>\n </div>\n </div>\n {schedule.mode === 'time' ? (\n <div className=\"dab-schedule-cell\" style={{ '--i': 1 } as CSSProperties}>\n <div className=\"dab-swatch-title\">{t('scheduleTimes')}</div>\n <div className=\"dab-time-row\">\n <label className=\"dab-time-label\"><SunIcon size={13} />{t('scheduleDayStart')}\n <input type=\"time\" className=\"dab-timeinput\" value={schedule.dayStart}\n onChange={e => { if (/^([01]\\d|2[0-3]):[0-5]\\d$/.test(e.target.value)) patchSchedule({ dayStart: e.target.value }) }} />\n </label>\n <label className=\"dab-time-label\"><MoonIcon size={13} />{t('scheduleNightStart')}\n <input type=\"time\" className=\"dab-timeinput\" value={schedule.nightStart}\n onChange={e => { if (/^([01]\\d|2[0-3]):[0-5]\\d$/.test(e.target.value)) patchSchedule({ nightStart: e.target.value }) }} />\n </label>\n </div>\n </div>\n ) : null}\n <div className=\"dab-schedule-cell\" style={{ '--i': 2 } as CSSProperties}>\n <div className=\"dab-swatch-title\">{t('scheduleProfiles')}</div>\n <div className=\"dab-time-row\">\n <label className=\"dab-time-label\"><SunIcon size={13} />{t('scheduleDayProfile')}\n {profileOptions(schedule.dayProfile, id => patchSchedule({ dayProfile: id }))}\n </label>\n <label className=\"dab-time-label\"><MoonIcon size={13} />{t('scheduleNightProfile')}\n {profileOptions(schedule.nightProfile, id => patchSchedule({ nightProfile: id }))}\n </label>\n </div>\n </div>\n </div>\n </div>\n </div>\n </section>\n\n {/* Export / import */}\n <div className=\"dab-profile-grid\">\n <section className=\"dab-card dab-card-hover dab-rise\" style={{ '--d': 4 } as CSSProperties}>\n <div className=\"dab-profile-ico\"><DownloadIcon size={17} /></div>\n <div className=\"dab-profile-title\">{t('exportCardTitle')}</div>\n <div className=\"dab-profile-desc\">{t('exportCardDesc')}</div>\n <button type=\"button\" className=\"dab-btn dab-btn-primary\" onClick={() => { exportTheme(); notify(t('toastExportDone')) }}>\n <DownloadIcon size={14} />{t('exportTheme')}\n </button>\n </section>\n\n <section className=\"dab-card dab-card-hover dab-rise\" style={{ '--d': 5 } as CSSProperties}>\n <div className=\"dab-profile-ico\"><UploadIcon size={17} /></div>\n <div className=\"dab-profile-title\">{t('importCardTitle')}</div>\n <div className=\"dab-profile-desc\">{t('importCardDesc')}</div>\n <button type=\"button\" className=\"dab-btn\" onClick={() => importRef.current?.click()}>\n <UploadIcon size={14} />{t('importTheme')}\n </button>\n <input ref={importRef} type=\"file\" accept=\"application/json,.json\" style={{ display: 'none' }} onChange={e => {\n const f = e.target.files?.[0]; if (!f) return\n void onImport(f); e.target.value = ''\n }} />\n </section>\n </div>\n\n <footer className=\"dab-footer dab-rise\" style={{ '--d': 6 } as CSSProperties}>\n <span className=\"dab-footer-mono\">dsh-any-background</span>\n <span>{t('footerTag')}</span>\n </footer>\n </>\n )\n}\n","/**\n * dsh-any-background — appearance shell for the five pages.\n *\n * Two surfaces render this shell, and only the chrome differs:\n * · `settings` — injected into the host settings dialog's content column,\n * which supplies the modal frame (nav rail on the left, brand block, page\n * max-width, the dialog's own scrolling);\n * · `sidebar` — a page inside dsh-better-sidebar, where the panel is much\n * narrower, is handed a full-height column, and has to own its own scroll\n * region. The brand block is dropped (the sidebar's tab bar already names\n * the page) and the rail turns into a compact row.\n * The five pages themselves never branch on the surface: width-driven\n * adaptation lives in the stylesheet's container queries, which measure the\n * shell itself rather than assuming either surface's width.\n */\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react'\nimport type { ThemeSectionProps } from '../types'\nimport { ensureUiCss, NAV_ITEM_H, NAV_GAP } from './ui.css'\nimport { SunIcon, DropletIcon, LayersIcon, PhotoIcon, SlidersIcon, FontIcon, CheckIcon, AlertIcon } from './icons'\nimport { ErrorBoundary } from './ErrorBoundary'\nimport { Portal } from './Portal'\nimport { ColorPage } from './pages/ColorPage'\nimport { InterfacePage } from './pages/InterfacePage'\nimport { FontPage } from './pages/FontPage'\nimport { BackgroundPage } from './pages/BackgroundPage'\nimport { ProfilePage } from './pages/ProfilePage'\n\n/** Which chrome wraps the pages; see the module doc. */\nexport type ThemeSurface = 'settings' | 'sidebar'\n\nexport function ThemeSection(props: ThemeSectionProps & { surface?: ThemeSurface }) {\n ensureUiCss()\n const { t } = props\n const surface = props.surface ?? 'settings'\n const [page, setPage] = useState(0)\n const [toast, setToast] = useState<{ msg: string; ok: boolean } | null>(null)\n const toastTimer = useRef<number | undefined>(undefined)\n\n useEffect(() => () => window.clearTimeout(toastTimer.current), [])\n\n const notify = useCallback((msg: string, ok = true): void => {\n setToast({ msg, ok })\n window.clearTimeout(toastTimer.current)\n toastTimer.current = window.setTimeout(() => setToast(null), 2600)\n }, [])\n\n // Stable element identities: an inline notify + inline array rebuilds every\n // page element on each render, so a toast appearing (or any state tick)\n // re-renders all five pages at once. That churn is what makes LiveSlider's\n // sync effect fire mid-drag and yank the thumb back, so keep the elements\n // memoized on the few props that actually change them.\n const pages = useMemo(() => [\n { label: t('pageColor'), Icon: DropletIcon, node: <ColorPage p={props} notify={notify} /> },\n { label: t('pageInterface'), Icon: LayersIcon, node: <InterfacePage p={props} /> },\n { label: t('pageFont'), Icon: FontIcon, node: <FontPage p={props} notify={notify} /> },\n { label: t('pageBackground'), Icon: PhotoIcon, node: <BackgroundPage p={props} notify={notify} /> },\n { label: t('pageProfile'), Icon: SlidersIcon, node: <ProfilePage p={props} notify={notify} /> },\n ], [t, props, notify])\n\n return (\n <ErrorBoundary t={t}>\n <div className=\"dab-root\" data-dab-surface={surface}>\n <div className=\"dab-shell\">\n <nav className=\"dab-nav\">\n {surface === 'sidebar' ? null : (\n <div className=\"dab-brand\">\n <div className=\"dab-brand-tile\"><SunIcon size={15} /></div>\n <div>\n <div className=\"dab-brand-name\">{t('nav')}</div>\n <div className=\"dab-brand-tag\">{t('brandTag')}</div>\n </div>\n </div>\n )}\n <div className=\"dab-nav-list\">\n <div className=\"dab-nav-ind\" style={{ transform: `translateY(${page * (NAV_ITEM_H + NAV_GAP)}px)` }} />\n {pages.map((pg, i) => (\n <button\n key={pg.label} type=\"button\"\n className={`dab-nav-item${i === page ? ' is-active' : ''}`}\n onClick={() => setPage(i)}>\n <pg.Icon size={16} />\n <span>{pg.label}</span>\n </button>\n ))}\n </div>\n </nav>\n\n <div className=\"dab-page\" key={page}>\n {pages[page].node}\n </div>\n </div>\n </div>\n\n {toast ? (\n <Portal>\n <div className=\"dab-toast\" role=\"status\">\n <span className={toast.ok ? 'dab-toast-ok' : 'dab-toast-err'}>\n {toast.ok ? <CheckIcon size={14} /> : <AlertIcon size={14} />}\n </span>\n <span>{toast.msg}</span>\n </div>\n </Portal>\n ) : null}\n </ErrorBoundary>\n )\n}\n","/**\n * dsh-any-background — selector hook over a host store instance.\n *\n * The settings slot kit hands the pages a `useStore(selector)` hook that is\n * bound to this plugin's store instance by the host renderer. A better-sidebar\n * page gets no such kit — its tab props carry `ctx`/`store`/`scope` for\n * better-sidebar's own store — so the same contract is rebuilt here from the\n * store instance itself, which already IS an observable source\n * (`getSnapshot`/`subscribe`, see `defineStore` in the host's client store).\n *\n * Semantics match the host binding on purpose: reduce the published snapshot\n * through the selector and compare with `Object.is`, so a page subscribing to\n * one field does not re-render on unrelated writes.\n */\nimport { useCallback, useRef, useSyncExternalStore } from 'react'\n\n/** The observable slice of a store instance this module relies on. */\nexport interface ObservableStore<S> {\n getSnapshot: () => S\n subscribe: (onChange: () => void) => () => void\n}\n\n/**\n * Bind a store instance to a `useStore(selector)` hook. Call once per store and\n * share the result: the returned hook keeps one subscription identity for its\n * whole lifetime.\n * @param store - observable store instance (`defineStore` handle).\n * @returns a selector hook reading that instance.\n */\nexport function createStoreHook<S>(store: ObservableStore<S>): <T>(selector: (snapshot: S) => T) => T {\n // Bound once: `subscribe` must keep its identity across renders or React\n // re-subscribes on every one of them.\n const subscribe = (onChange: () => void): (() => void) => store.subscribe(onChange)\n const { getSnapshot } = store\n return function useStoreSelector<T>(selector: (snapshot: S) => T): T {\n // Cache the selected value per snapshot identity. Two reasons, both load\n // bearing: React demands a referentially stable result for an unchanged\n // snapshot (otherwise it re-renders forever), and callers pass inline\n // arrows whose identity changes every render, so the selector itself can\n // never provide that stability. Caching per snapshot also makes a selector\n // that derives a fresh object safe.\n const cache = useRef<{ snapshot: S; value: T } | null>(null)\n const read = useCallback(() => {\n const snapshot = getSnapshot()\n const hit = cache.current\n if (hit !== null && hit.snapshot === snapshot) return hit.value\n const value = selector(snapshot)\n cache.current = { snapshot, value }\n return value\n }, [selector])\n return useSyncExternalStore(subscribe, read, read)\n }\n}\n","/**\n * dsh-any-background — dsh-better-sidebar integration.\n *\n * Publishes the plugin's appearance controls as a sidebar page (\"主题\") in\n * better-sidebar's tab registry. The page renders the SAME five-page tree as\n * the settings section — `ThemeSection` takes a `surface` variant — so there is\n * one UI to maintain, not two forks of it.\n *\n * The dependency is optional at every level, which is why nothing here imports\n * the package:\n * · the service is read off the client context at runtime, so a DSH install\n * without better-sidebar silently registers nothing, and a better-sidebar\n * that mounts *after* this plugin still gets the page (`ctx.inject` fires\n * whenever the service shows up, never when it never does);\n * · the plugin's own types are restated in the minimal local contract below\n * instead of imported — a value import would be rejected by the host's\n * client-bundle purity gate, and even a type-only import would make the\n * package a build-time dependency for everyone who does not run it.\n */\nimport { createElement, useCallback, useMemo, useSyncExternalStore } from 'react'\nimport type { Ctx, LocaleService, ThemeSectionProps, ThemeStoreState } from '../types'\nimport { NS } from '../i18n'\nimport { ThemeSection } from '../components/ThemeSection'\nimport { SunIcon } from '../components/icons'\nimport { createStoreHook, type ObservableStore } from './store-hook'\nimport { subscribeHostInfo } from '../host-compat/release'\nimport { sidebarGuideOwner } from '../host-compat/capabilities'\n\n/** Minimal restatement of the slice of `ctx.betterSidebar` used here. */\ninterface BetterSidebarService {\n /** Register a page type; the returned disposer withdraws it. */\n registerTab(descriptor: {\n id: string\n title: string | (() => string)\n icon?: unknown\n order?: number\n /** Focus an already-open page instead of stacking duplicates. */\n single?: boolean\n component: () => unknown\n }): () => void\n}\n\n/** The client context, plus the optional service this module probes for. */\ntype CtxWithSidebar = Ctx & { betterSidebar?: BetterSidebarService }\n\n/**\n * The active locale id, used as a re-render signal: page labels are resolved by\n * calling `t(...)` at render time, so the props object (and with it the memoized\n * page tree) has to be rebuilt when the language flips — otherwise the page\n * would keep painting the previous language until some unrelated store write\n * happened to re-render it.\n * @param locale - host locale service.\n * @returns the active locale id (a stable string, safe for `Object.is`).\n */\nfunction useActiveLocale(locale: LocaleService): string {\n const subscribe = useCallback((onChange: () => void) => locale.subscribe(onChange), [locale])\n const read = useCallback(() => locale.getSnapshot().active, [locale])\n return useSyncExternalStore(subscribe, read, read)\n}\n\n/** Rendered inside a sidebar tab: the five pages, `surface: 'sidebar'` shell.\n * Shared by the better-sidebar page and the native right-Sidebar tab — both\n * hand a full-height column that owns its own scroll. */\nexport function ThemeTab({ face, useStore, locale }: {\n /** The plugin's business face, built once and shared with the settings section. */\n face: Omit<ThemeSectionProps, 'useStore'>\n useStore: ThemeSectionProps['useStore']\n locale: LocaleService\n}) {\n const active = useActiveLocale(locale)\n // Unlike the settings slot — whose kit rebuilds the props object on every\n // render — every input here is stable, so the pages keep stable element\n // identities and only re-render when the store tells them to (or the language\n // changes). That is exactly the property the settings path has to fake.\n const props = useMemo<ThemeSectionProps>(() => ({ ...face, useStore }), [face, useStore, active])\n return createElement(ThemeSection, { ...props, surface: 'sidebar' })\n}\n\n/**\n * Register the appearance page with better-sidebar, if it is installed.\n *\n * Call from the client `apply`. The registration is owned by the injected\n * scope's effect, so unloading the plugin (or HMR) withdraws it — without that,\n * the next activation would throw on the duplicate id.\n * @param ctx - client context.\n * @param opts.face - lazy accessor for the shared business face.\n * @param opts.store - the plugin's store instance, or null on a host where the\n * store module never resolved (in that case there is nothing to bind and no\n * page is registered).\n */\nexport function registerThemeSidebarTab(ctx: Ctx, opts: {\n face: () => Omit<ThemeSectionProps, 'useStore'>\n store: ObservableStore<ThemeStoreState> | null\n}): void {\n const { store } = opts\n // Fail soft on an unexpected store shape. `defineStore` has already shipped\n // two different return shapes (an instance on newer builds, a\n // `{ spec, create }` declaration on dsh-client-store 0.1.2-alpha.x), and\n // binding a hook to the wrong one throws on every render — which the section's\n // error boundary turns into a dead panel. Registering nothing leaves the\n // settings panel working, which is the right trade.\n if (store === null || typeof store.getSnapshot !== 'function' || typeof store.subscribe !== 'function') {\n console.warn('dsh-any-background: no observable store instance on this host; the sidebar page stays unregistered')\n return\n }\n const locale = ctx.locale\n const t = locale.bind(NS)\n const useStore = createStoreHook(store)\n // A fixed order slot past the built-ins (terminal 40 / browser 50) keeps the\n // page at the end of the + menu instead of displacing the tools above it.\n const ORDER = 55\n ctx.inject?.(['betterSidebar'], (scope: Ctx) => {\n const service = (scope as CtxWithSidebar).betterSidebar\n if (service === undefined) return\n // A host whose own right Sidebar already carries the appearance page would\n // show two identical entries on the same guide surface, so the better-sidebar\n // page stands down there. Driven by the host adapter, not by the native\n // sidebar service: that service also ships on 0.1.5-rc.2, where this page\n // must still register.\n const owner = sidebarGuideOwner()\n if (owner === 'host') return\n let disposeTab: (() => void) | null = null\n // Verdict not landed yet (Node round-trip): register now and withdraw if the\n // host turns out to own the surface — better a brief duplicate than a\n // missing page.\n const unsubscribeHost = owner === 'pending'\n ? subscribeHostInfo(() => {\n if (sidebarGuideOwner() === 'host') {\n disposeTab?.()\n disposeTab = null\n unsubscribeHost()\n }\n })\n : () => {}\n // The face is materialized HERE, once, before the host can render the page.\n // Its first build warms the store (syncBg/syncMetaNow), and a store write\n // issued from inside a render is exactly the kind of impurity that turns\n // into a \"setState while rendering\" warning later.\n const face = opts.face()\n scope.effect(() => {\n disposeTab = service.registerTab({\n id: 'dsh-any-background:theme',\n title: () => t('nav'),\n icon: (size: number) => createElement(SunIcon, { size }),\n order: ORDER,\n single: true,\n // The tab props carry better-sidebar's own store/scope/visible seats\n // and are not needed: this page polls nothing, and its only\n // subscription is the plugin store, shared with the settings section.\n component: () => createElement(ThemeTab, { face, useStore, locale }),\n }) ?? null\n return () => {\n unsubscribeHost()\n disposeTab?.()\n disposeTab = null\n }\n })\n })\n}\n","/**\n * Host capability detection — which third-party plugins are actually present.\n *\n * The host exposes no plugin registry on the client context, so presence is\n * inferred from the stable DOM markers those plugins mount. Detection runs\n * once (plugin boot) and is re-armed by a cheap body-level MutationObserver so\n * a plugin that mounts after this one still flips the cached verdict. The\n * verdict is sticky-true for the session: whether a detected plugin's surface\n * is currently collapsed must not hide the settings that govern it.\n */\n\n/** Persistent container + surfaces dsh-better-sidebar mounts when loaded.\n * `[data-dsh-better-sidebar]` is the plugin's host wrapper — always appended\n * to document.body on mount — so it is the authoritative \"plugin is loaded\"\n * signal and the body childList observer fires exactly when it appears. The\n * panel surfaces are listed only as reinforcement: they are conditionally\n * rendered (collapsed panels drop them), so they must never be the sole\n * signal.\n *\n * `[data-sidebar-right-panel]` is deliberately ABSENT: on every host generation\n * it marks the host's own right Sidebar (always present once a session opens),\n * so counting it would make the better-sidebar verdict permanently true on any\n * host and mis-drive everything gated on it. */\n\nexport const BETTER_SIDEBAR_MARKERS = [\n '[data-dsh-better-sidebar]',\n '[data-dsh-panel-host]',\n '[data-dsh-bottom-panel]',\n] as const\n\nlet betterSidebar = false\nconst subs = new Set<() => void>()\n\n/** Read snapshot of whether the better-sidebar plugin is present. */\nexport function rBetterSidebar(): boolean {\n return betterSidebar\n}\n\nfunction emit(): void {\n subs.forEach(cb => cb())\n}\n\nfunction sync(): void {\n const present = document.querySelector(BETTER_SIDEBAR_MARKERS.join(',')) !== null\n if (present && !betterSidebar) {\n betterSidebar = true\n emit()\n }\n // Sticky on purpose: a collapsed/detached panel must not untick the verdict.\n}\n\n/** Subscribe to verdict changes. */\nexport function subscribe(cb: () => void): () => void {\n subs.add(cb)\n return () => { subs.delete(cb) }\n}\n\n/** Start detection (probe once, then watch body mounts). Returns an\n * unsubscribe for plugin teardown. */\nexport function startBetterSidebarWatch(): () => void {\n sync()\n const observer = new MutationObserver(sync)\n observer.observe(document.body, { childList: true })\n return () => observer.disconnect()\n}\n\n// ── Native right-Sidebar capability ───────────────────────────────────────────\n// CORRECTION: the native right Sidebar is NOT a 0.1.6+ introduction. It ships and\n// is enabled on 0.1.5-rc.2 already — `@deepseek-ai/dsh-client-ui-sidebar-right`\n// is a `dsh-web-app` dependency and its `ui-sidebar-right` entry is in that\n// release's `cordis.patch.yml`, and `ctx.sidebarRightTabs` is provided there\n// too. An earlier revision of this module treated the service as a \"0.1.6+\"\n// probe, which wrongly suppressed the better-sidebar page on 0.1.5.\n//\n// The real release comes from `host-compat/` (resolved on the Node half, where the\n// launcher's on-disk layout is readable). This flag now only records whether the\n// native registry service was actually CONFIRMED on this host — a runtime\n// availability fact used to decide whether the native tab can be registered at\n// all — while the better-sidebar suppression is driven by the host adapter.\n\nlet nativeTabs = false\nconst nativeSubs = new Set<() => void>()\n\n/** Whether the native right-Sidebar tab registry service was confirmed present. */\nexport function rNativeSidebarTabs(): boolean {\n return nativeTabs\n}\n\n/** Mark the native right-Sidebar service as confirmed. Sticky — the service\n * never goes away within a session. */\nexport function markNativeSidebarTabs(): void {\n if (nativeTabs) return\n nativeTabs = true\n nativeSubs.forEach(cb => cb())\n}\n\n/** Subscribe to the native-Sidebar verdict. */\nexport function subscribeNativeTabs(cb: () => void): () => void {\n nativeSubs.add(cb)\n return () => { nativeSubs.delete(cb) }\n}","/**\n * dsh-any-background — native right-Sidebar integration.\n *\n * DSH ships an official right Sidebar (`dsh-client-ui-sidebar-right`) with a\n * public two-stage extension path: a static tab type into\n * `ctx.sidebarRightTabs` — whose `guide` entry draws a card on the Sidebar's\n * guide page — and a body under the keyed `sidebar.right.pane.tab` seat. This\n * module registers the plugin's appearance pages through that path, so the\n * official Sidebar gains a \"主题\" card that opens the very same five pages the\n * settings panel shows (one implementation, one state store; editing in either\n * place shows up in the other).\n *\n * NOTE: that registry is NOT a new-host feature. It is provided on 0.1.5-rc.2\n * already (verified against the release tag), so nothing here may treat \"the\n * service answered\" as \"this is a recent DSH\" — whether this tab or the\n * better-sidebar page owns the guide surface is the host adapter's call.\n *\n * The dependency is optional at every level, mirroring `sidebar/tab.tsx`:\n * · the registry is waited on with `ctx.inject`, so a host without the\n * right Sidebar (or an older DSH) silently registers nothing, and a\n * Sidebar that initializes after this plugin still gets the card;\n * · the service shape is restated as a minimal local contract instead of\n * imported — a value import would be rejected by the host's client-bundle\n * purity gate, and even a type-only import would make the package a\n * build-time dependency for everyone who does not run it.\n *\n * When dsh-better-sidebar is installed it brings its own \"主题\" page (registered\n * by `sidebar/tab.tsx`), which would duplicate this card on the same guide\n * page. The native card therefore yields: it is not registered while\n * better-sidebar is detected, and it withdraws itself if better-sidebar mounts\n * later (the presence verdict is sticky-true, so no re-registration path is\n * needed). The Interface page's panel slider follows the same split:\n * \"右方侧边栏\" natively, \"bettersidebar\" when that plugin is present.\n */\nimport { createElement } from 'react'\nimport type { Ctx, ThemeSectionProps, ThemeStoreState } from '../types'\nimport { NS } from '../i18n'\nimport { ThemeTab } from './tab'\nimport { SunIcon } from '../components/icons'\nimport { createStoreHook, type ObservableStore } from './store-hook'\nimport { rBetterSidebar, subscribe as subscribeBetterSidebar, markNativeSidebarTabs } from '../env'\nimport { subscribeHostInfo } from '../host-compat/release'\nimport { sidebarGuideOwner } from '../host-compat/capabilities'\n\n/** Minimal restatement of the slice of `ctx.sidebarRightTabs` used here. */\ninterface SidebarRightTabsService {\n /** Register one tab type for the caller's effect lifetime; returns an idempotent disposer. */\n register(definition: {\n /** Unique implementation identity; also the key the body registers under. */\n id: string\n /** Type discriminator — what `openTab` names. */\n kind: string\n /** The tab chip's text, captured when the tab opens. */\n title: (address: string) => string\n /** Entry boxes for the guide page; picking one opens this type as a page. */\n guide?: readonly {\n id: string\n order: number\n title: () => string\n description?: () => string\n /** A React component receiving `{ size?, className? }`. */\n icon?: unknown\n }[]\n }): () => void\n}\n\n/** The client context, plus the optional service this module waits for. */\ntype CtxWithTabs = Ctx & { sidebarRightTabs?: SidebarRightTabsService }\n\n/** The tab implementation's identity, and the key the body registers under. */\nexport const NATIVE_TAB_ID = 'dsh-any-background:theme'\n\n/** The page kind: what `openTab` names and the guide entry opens. */\nconst NATIVE_TAB_KIND = 'danybg-theme'\n\n/**\n * Register the appearance pages with the native right Sidebar, if one exists.\n *\n * Call from the client `apply`. Both registrations sit inside the injected\n * scope's effects, so unloading the plugin (or HMR) withdraws them — without\n * that, the next activation would throw on the duplicate id.\n * @param ctx - client context.\n * @param opts.face - lazy accessor for the shared business face.\n * @param opts.store - the plugin's store instance, or null on a host where the\n * store module never resolved (in that case there is nothing to bind and no\n * page is registered).\n */\nexport function registerNativeSidebarTab(ctx: Ctx, opts: {\n face: () => Omit<ThemeSectionProps, 'useStore'>\n store: ObservableStore<ThemeStoreState> | null\n}): void {\n const { store } = opts\n // Same guard as the better-sidebar path: `defineStore` has shipped two return\n // shapes across host builds, and binding a hook to the wrong one throws on\n // every render. Registering nothing leaves the settings panel working.\n if (store === null || typeof store.getSnapshot !== 'function' || typeof store.subscribe !== 'function') {\n console.warn('dsh-any-background: no observable store instance on this host; the native sidebar page stays unregistered')\n return\n }\n const locale = ctx.locale\n const t = locale.bind(NS)\n const useStore = createStoreHook(store)\n ctx.inject?.(['sidebarRightTabs'], (scope: Ctx) => {\n const tabs = (scope as CtxWithTabs).sidebarRightTabs\n if (tabs === undefined || typeof tabs.register !== 'function') return\n // This host has the native registry: record the capability so the\n // better-sidebar page knows the surface exists at all. Presence alone does NOT\n // decide who owns it — see markNativeSidebarTabs and the module note.\n markNativeSidebarTabs()\n // The face is materialized HERE, once, before the host can render the page:\n // its first build warms the store (syncBg/syncMetaNow), and a store write\n // issued from inside a render is exactly the impurity that turns into a\n // \"setState while rendering\" warning later.\n const face = opts.face()\n // The tab body needs no tab info of its own — the page polls nothing and\n // its only subscription is the plugin's shared store — so the slot\n // framework's props are ignored wholesale.\n const ThemeBody = () => createElement(ThemeTab, { face, useStore, locale })\n scope.effect(() => {\n // Which page owns the guide surface is decided by the SAME predicate the\n // better-sidebar module uses, so the two can never both stand down and\n // leave the Surface with no appearance card at all:\n // · the host owns it → better-sidebar page suppressed, native wins\n // · the plugin owns it → better-sidebar page registers, native yields\n // · pending verdict → the native card registers, and is withdrawn once\n // the adapter says better-sidebar owns the surface.\n const yieldTo = (): boolean =>\n sidebarGuideOwner() === 'plugin' && rBetterSidebar()\n if (yieldTo()) return\n let disposeTab: (() => void) | null = null\n const withdraw = (): void => {\n disposeTab?.()\n disposeTab = null\n }\n const unsubscribeBetter = subscribeBetterSidebar(() => { if (yieldTo()) withdraw() })\n const unsubscribeHost = subscribeHostInfo(() => { if (yieldTo()) withdraw() })\n disposeTab = tabs.register({\n id: NATIVE_TAB_ID,\n kind: NATIVE_TAB_KIND,\n title: () => t('nav'),\n guide: [{\n id: 'theme',\n // Past the shipped pages (files 10 / terminal 40 / browser 50): the\n // appearance card trails the tools instead of displacing them.\n order: 55,\n title: () => t('nav'),\n description: () => t('guideDesc'),\n icon: SunIcon,\n }],\n })\n return () => {\n unsubscribeBetter()\n unsubscribeHost()\n withdraw()\n }\n }, 'dsh-any-background: native sidebar theme tab')\n // Stage two: the body under the keyed seat, dispatched by the type's id.\n scope.effect(() => ctx.slots.inject('sidebar.right.pane.tab', () => ctx.slots.register(\n { name: 'sidebar.right.pane.tab', key: NATIVE_TAB_ID },\n ThemeBody,\n )), 'dsh-any-background: native sidebar theme body')\n })\n}\n","/**\n * dsh-any-background — browser half entry.\n *\n * Wires the plugin lifecycle: theme registration, wallpaper layer, viewport\n * watch, i18n, settings-section injection, boot restore, watchdog. The heavy\n * lifting lives in the sibling modules (state/rpc/wallpaper/utils/components).\n */\nimport { defineStore } from './runtime'\nimport type { Ctx, RpcResultLike, BoundActions, ThemeSectionProps, PartOpacities, PartBlurs, PartStrokes, BackgroundType, GeneratedBgParams, ProfileAppearance, ProfileEntry, RotationItem, ScheduleConfig, SchemeOverride, UploadOutcome, StoreInstance } from './types'\nimport { NS, zh, en } from './i18n'\nimport { cfg, rHasColor, rColor, rWp, rWpImage, rWpVideo, rBgState, rVideoBgState, setWpUrl, setWpImageUrl, setWpVideoUrl, setWpVideoSnapshot, setBgState, adoptConfig, DEFAULT_CONFIG, setBgDark, rBgDark, rProfiles, rRotation, rSchedule, rScheme, rColorScheme, rSchemeOverride, currentAppearance, applyAppearance } from './state'\nimport { RPC_CHANNEL, VIDEO_SERVE_URL, FONT_SERVE_URL, fontServeUrl, initRpc, saveConfig, flushSave, loadPersisted, persistWallpaper, persistVideo, persistConfig, uploadVideo, uploadFont, removeFont as rpcRemoveFont, rotationAdd, rotationRemove, rotationActivate, setVideoFromUrl as rpcSetVideoFromUrl } from './rpc'\nimport { applyWp, teardownWp, applySettingsOverrides, applyPanelOverrides, applyStrokes, applyFontFace, watchParts, watchThemeResets, regenerateGeneratedBg, setBackgroundType, updateGeneratedBg, applyThemeColor, onGeneratedSnapshot, watchWallpaperDragQuality, clearThemeTokens, onVerdictApplied, onColorAdopted, LABEL_TOKENS, SETTINGS_PANEL_SEL } from './wallpaper'\nimport { mountStaticStyles } from './host-compat/styles'\nimport { genTokens, hslToHsv, hsvToHsl, extractWallpaperColor } from './utils/color'\nimport { captureVideoSnapshot } from './utils/video'\nimport { readImgAsync, makeThumb, blobToDataUrl } from './utils/image'\nimport { ThemeSection } from './components/ThemeSection'\nimport { registerThemeSidebarTab } from './sidebar/tab'\nimport { registerNativeSidebarTab } from './sidebar/native-tab'\nimport { SUN_PATHS } from './components/icons'\nimport { startBetterSidebarWatch } from './env'\nimport { startHeaderPopoverTagging } from './header-tag'\n\nexport const name = 'dsh-any-background'\nexport const inject = ['slots', 'locale', 'theme', 'connection']\n\nconst CUSTOM_ID = 'custom-color'\n\nexport function apply(ctx: Ctx): void {\n // Bind the dedicated `/dsh-any-background` RPC caller so the persistence\n // module can reach the node half's file-backed store.\n initRpc((endpoint, payload) =>\n ctx.connection.rpc.call(RPC_CHANNEL, endpoint, payload).then((res: any) => res as RpcResultLike | undefined)\n )\n\n // 1. Restore custom color and register as a skin. The skin MUST go through\n // the host theme service — the host presenter paints fonts from the\n // registered theme, so a stylesheet-only override loses to it.\n // · picked color → genTokens in the effective scheme;\n // · forced scheme → neutral palette in the forced direction;\n // · auto, no color→ adopt the host's own palette in the background\n // brightness verdict's direction, fonts flipped to match\n // the wallpaper (perceptual luma, threshold 0.5).\n const [initH, initS, initL] = rColor()\n let customDispose: (() => void) | null = null\n // Records that the host theme service rejected our skin for a reason other\n // than the HMR duplicate below: logged once so the 1s watchdog's retries do\n // not spam the console (or, worse, fail in total silence while the user's\n // theme quietly never applies).\n let registerFailed = false\n // registerCustom takes HSL (the storage/wheel space and genTokens space).\n const registerCustom = (h?: number, s?: number, l?: number): boolean => {\n customDispose?.()\n try {\n let colorScheme: 'light' | 'dark'\n let tokens: Record<string, string>\n if (rHasColor()) {\n ;({ colorScheme, tokens } = genTokens(h ?? rColor()[0], s ?? rColor()[1], l ?? rColor()[2], rColorScheme()))\n } else if (rSchemeOverride() !== 'auto') {\n const dark = rScheme() === 'dark'\n ;({ colorScheme, tokens } = genTokens(220, 0.04, dark ? 0.14 : 0.92, dark ? 'dark' : 'light'))\n } else {\n const verdict = rBgDark()\n if (verdict === null) { customDispose = null; return false }\n const snap = ctx.theme.getTheme()\n const wantScheme = verdict ? 'dark' : 'light'\n const source = snap.themes.find(t => t.id !== CUSTOM_ID && t.colorScheme === wantScheme)\n ?? snap.themes.find(t => t.id !== CUSTOM_ID)\n if (source === undefined) { customDispose = null; return false }\n colorScheme = wantScheme\n tokens = { ...source.tokens }\n const font = verdict ? '#fff' : '#000'\n for (const name of LABEL_TOKENS) tokens[name] = font\n }\n customDispose = ctx.theme.register({ id: CUSTOM_ID, colorScheme, tokens })\n } catch (e) {\n // HMR tolerance: an earlier apply pass may still hold a live registration\n // for this id, and register throws on the duplicate — the registry then\n // already contains the skin, so fall through and activate it below.\n // Any OTHER failure (host API drift, version mismatch) must not be\n // swallowed here: the watchdog would retry it every second forever.\n const alreadyLive = (() => { try { return ctx.theme.getTheme().themes.some(t => t.id === CUSTOM_ID) } catch { return false } })()\n if (!alreadyLive) {\n if (!registerFailed) {\n registerFailed = true\n console.error('dsh-any-background: host theme register failed; the custom skin will stay inactive', e)\n }\n customDispose = null\n return false\n }\n customDispose = null\n }\n // Only activate the custom theme if it is actually registered.\n const present = (() => { try { return ctx.theme.getTheme().themes.some(t => t.id === CUSTOM_ID) } catch { return false } })()\n if (present) ctx.theme.setTheme(CUSTOM_ID)\n return present\n }\n // Restore saved color on boot.\n if (rHasColor()) registerCustom(initH, initS, initL)\n // A fresh background brightness verdict (wallpaper swapped in, generated bg\n // regenerated) re-registration trigger: without a picked color the adopted\n // skin must be rebuilt so its fonts follow the new wallpaper.\n const disposeVerdict = onVerdictApplied(() => {\n if (!rHasColor()) registerCustom()\n })\n // A wallpaper-extracted color adopted by the auto path (applyThemeColor's\n // no-saved-pick branch) must finish the full adaptation here: register the\n // skin in the color's direction, persist, and sync the editor wheel — the\n // bare cfg.color write in wallpaper.ts cannot reach any of those.\n const disposeColorAdopted = onColorAdopted(hsl => {\n registerCustom(hsl[0], hsl[1], hsl[2])\n saveConfig()\n colorRev++\n bound?.syncColor(hslToHsv(hsl[0], hsl[1], hsl[2]), colorRev)\n })\n // Drop this apply's listener closures on teardown: HMR re-runs apply and the\n // module-level slots would otherwise keep invoking the previous session's\n // callbacks (and the closures above hold dead `bound`/`customDispose` state).\n ctx.effect(() => () => { disposeVerdict(); disposeColorAdopted() }, 'dsh-any-background: verdict/color listeners')\n ctx.effect(() => () => {\n customDispose?.()\n if (colorTimerRef.current !== null) window.clearTimeout(colorTimerRef.current)\n }, 'dsh-any-background: skin dispose')\n\n // 2. The plugin's static stylesheet — the dark-mode gradient plus every\n // host-override rule. Assembled in `host-compat/styles`, which owns the rule\n // order and slots in the panel arm chosen by the host's release adapter (the\n // first sheet is the unresolved one; it is re-cut when the verdict lands).\n ctx.effect(() => mountStaticStyles(), 'dsh-any-background: stylesheet')\n\n // Wallpaper downscales to a low-res copy during slider drags, restored on release.\n const disposeDragQuality = watchWallpaperDragQuality()\n ctx.effect(() => () => disposeDragQuality(), 'dsh-any-background: drag quality')\n\n // 3. State store. defineStore is null on a host variant where neither store\n // package resolved (see runtime.ts): keep applying theme/wallpaper and skip\n // only the settings section rather than crashing the whole client half.\n //\n // `defineStore` returns two different things across host builds:\n // · newer builds hand back the STORE INSTANCE (getSnapshot/subscribe/\n // actions) directly;\n // · dsh-client-store 0.1.2-alpha.x hands back a DECLARATION\n // `{ spec, create(scopeKey) }` that the renderer instantiates per scope\n // — the object the plugin holds has neither getSnapshot nor actions.\n // The settings panel only ever worked because the renderer did the\n // instantiation; anything the plugin itself reads off that object has to\n // normalize first.\n let rev = 0\n let colorRev = 0\n let bgRev = 0\n const colorTimerRef: { current: number | null } = { current: null }\n const storeSpec = defineStore === null ? null : defineStore({\n init: () => ({\n url: null as string | null,\n rev: -1,\n colorRev: -1,\n color: null as [number, number, number] | null,\n backgroundType: cfg.backgroundType,\n generatedBg: cfg.generatedBg,\n bgRev: -1,\n regenerateOnReload: cfg.regenerateOnReload,\n profiles: [] as ProfileEntry[],\n rotation: { ...DEFAULT_CONFIG.rotation, items: [] },\n schedule: { ...DEFAULT_CONFIG.schedule },\n schemeOverride: 'auto' as SchemeOverride,\n activeProfile: null as string | null,\n metaRev: -1,\n }),\n actions: {\n syncBg: (d: any, url: string | null, r: number, bgType?: BackgroundType, genBg?: GeneratedBgParams | null, bgr?: number, reload?: boolean) => {\n if (r > d.rev) { d.url = url; d.rev = r }\n if (bgr !== undefined && bgr > d.bgRev) { d.backgroundType = bgType!; d.generatedBg = genBg ?? null; d.bgRev = bgr }\n if (reload !== undefined) { d.regenerateOnReload = reload }\n },\n syncColor: (d: any, hsv: [number, number, number], r: number) => { if (r > d.colorRev) { d.color = hsv; d.colorRev = r } },\n syncMeta: (d: any, profiles: ProfileEntry[], rotation: typeof cfg.rotation, schedule: typeof cfg.schedule, schemeOverride: SchemeOverride, activeProfile: string | null, r: number) => {\n if (r > d.metaRev) {\n d.profiles = profiles; d.rotation = rotation; d.schedule = schedule\n d.schemeOverride = schemeOverride; d.activeProfile = activeProfile; d.metaRev = r\n }\n },\n },\n })\n /** One shared instance, whatever the host build handed back.\n *\n * The plugin publishes a single appearance state that BOTH surfaces read —\n * the settings section (through the renderer's `useStore`) and the\n * better-sidebar page (through the hook in `sidebar/store-hook`). Handing the\n * host a declaration whose `create` always returns this very instance is what\n * keeps them from drifting: letting the renderer mint its own would give the\n * sidebar a second, permanently empty copy of the state. */\n const storeInstance = storeSpec === null\n ? null\n : (typeof (storeSpec as { getSnapshot?: unknown }).getSnapshot === 'function'\n ? storeSpec as StoreInstance\n : (storeSpec as { create: (scopeKey?: string) => StoreInstance }).create())\n /** What gets registered: the instance on newer builds, a single-instance\n * declaration on the ones that expect a declaration. */\n const store = storeSpec === null || storeInstance === storeSpec\n ? storeSpec\n : { spec: (storeSpec as { spec?: unknown }).spec ?? {}, create: () => storeInstance }\n // The instance's actions ARE the sync face the settings slot hands back\n // (`defineStore` bakes the draft into each action, so their signatures match\n // BoundActions exactly). Binding them here rather than waiting for the\n // settings section's first render keeps the store fed from boot: the\n // better-sidebar page can be opened without the settings panel ever having\n // been, and it must not render boot-time defaults for profiles/rotation.\n let bound: BoundActions | null = null\n if (storeInstance !== null) bound = storeInstance.actions as BoundActions\n const syncBg = () => {\n rev++; bgRev++\n bound?.syncBg(rWp(), rev, cfg.backgroundType, cfg.generatedBg, bgRev, cfg.regenerateOnReload)\n }\n // When a generated background finishes its first frame, its snapshot becomes\n // the display/preview URL — re-sync the store so the preview follows.\n const disposeSnapshot = onGeneratedSnapshot(syncBg)\n ctx.effect(() => () => disposeSnapshot(), 'dsh-any-background: snapshot listener')\n\n /** Capture the first frame of the video now applied and finish its\n * adaptation: the frame stands in for every still-image API (previews,\n * color extraction) and the brightness verdict follows it. The stale guard\n * skips a capture whose video was swapped out from under it (another\n * upload or a rotation switch landing mid-decode). */\n const captureAndApplyVideo = (url: string | null): void => {\n if (url === null) return\n void captureVideoSnapshot(url).then(snap => {\n if (rWpVideo() !== url) return\n setWpVideoSnapshot(snap)\n applyThemeColor()\n syncBg()\n })\n }\n\n // ── Profiles / presets / scheme / rotation / schedule ────────────────────────\n let metaRev = 0\n const syncMetaNow = (): void => {\n metaRev++\n bound?.syncMeta(rProfiles(), rRotation(), rSchedule(), rSchemeOverride(), cfg.activeProfile, metaRev)\n }\n\n /** Apply an appearance snapshot (profile or built-in preset) to the whole\n * interface: re-register the skin, re-emit tokens, persist. */\n const applyAppearanceLive = (ap: ProfileAppearance): void => {\n applyAppearance(ap)\n if (rHasColor()) {\n const [h, s, l] = rColor()\n registerCustom(h, s, l)\n } else if (!registerCustom()) {\n // Nothing to assert (no color, auto, no verdict): hand the palette back\n // to the host theme.\n customDispose?.()\n customDispose = null\n clearThemeTokens()\n const snap = ctx.theme.getTheme()\n const fallback = snap.themes.find(t => t.id !== CUSTOM_ID)\n if (fallback !== undefined && snap.preference === CUSTOM_ID) ctx.theme.setTheme(fallback.id)\n }\n applyWp()\n }\n\n const applyProfileById = (id: string): boolean => {\n const entry = rProfiles().find(p => p.id === id)\n if (entry === undefined) return false\n applyAppearanceLive(entry.config)\n cfg.activeProfile = id\n applyWp()\n persistConfig()\n syncMetaNow()\n return true\n }\n\n // ── Wallpaper rotation ───────────────────────────────────────────────────────\n /** Extract the theme color once from a freshly activated wallpaper and run\n * the full adaptation (host skin + editor wheel sync); the caller persists. */\n const adoptWallpaperColor = async (dataUrl: string): Promise<void> => {\n const hsl = await extractWallpaperColor(dataUrl, rBgState())\n // The wallpaper may have been swapped while the image was decoding; a stale\n // pick must not overwrite the new picture's color.\n if (!hsl || rWp() !== dataUrl) return\n cfg.color = hsl\n registerCustom(hsl[0], hsl[1], hsl[2])\n colorRev++\n bound?.syncColor(hslToHsv(hsl[0], hsl[1], hsl[2]), colorRev)\n }\n\n /** Activate a rotation item: the server copies its bytes into the wallpaper\n * slot; the client applies the returned serve URL through the normal image\n * path, then re-extracts the theme color from the new picture so the\n * palette follows the rotation. */\n const applyRotationIndex = async (idx: number, auto: boolean): Promise<boolean> => {\n const rot = rRotation()\n if (idx < 0 || idx >= rot.items.length) return false\n const r = await rotationActivate(idx)\n if (!r.ok || !r.wallpaperUrl) {\n console.warn('dsh-any-background: rotation activate failed', r.error)\n return false\n }\n // The server already persisted the bytes into the wallpaper slot; mirror\n // setWpFromServer's state switch (bound is not initialized yet here).\n cfg.backgroundType = 'image'\n setBgDark(null)\n setWpImageUrl(r.wallpaperUrl)\n setWpUrl(rWpImage())\n setBgState({ ...DEFAULT_CONFIG.bgState })\n cfg.rotation = { ...rot, current: idx, lastRotate: auto || rot.lastRotate === null ? new Date().toISOString() : rot.lastRotate }\n // The picture just switched, so any saved pick describes the old wallpaper:\n // extract once from the new one to re-adapt (placement state matches the\n // previous image, so a size mismatch makes the extractor fall back to the\n // whole picture — the desired behavior for a fresh wallpaper).\n if (cfg.backgroundType === 'image') await adoptWallpaperColor(rWp()!)\n applyThemeColor()\n syncBg()\n saveConfig()\n syncMetaNow()\n return true\n }\n\n const isoWeekKey = (d: Date): string => {\n const t = new Date(Date.UTC(d.getFullYear(), d.getMonth(), d.getDate()))\n const day = t.getUTCDay() || 7\n t.setUTCDate(t.getUTCDate() + 4 - day)\n const yearStart = new Date(Date.UTC(t.getUTCFullYear(), 0, 1))\n const week = Math.ceil(((t.getTime() - yearStart.getTime()) / 86400000 + 1) / 7)\n return `${t.getUTCFullYear()}-W${week}`\n }\n\n const rotationDue = (): boolean => {\n const rot = rRotation()\n if (!rot.enabled || rot.items.length === 0) return false\n if (rot.interval === 'reload') return true\n const last = rot.lastRotate !== null ? new Date(rot.lastRotate) : null\n if (last === null || isNaN(last.getTime())) return true\n const now = new Date()\n if (rot.interval === 'daily') return last.toDateString() !== now.toDateString()\n return isoWeekKey(last) !== isoWeekKey(now)\n }\n\n const pickNextRotationIndex = (): number => {\n const rot = rRotation()\n const n = rot.items.length\n if (n === 0) return -1\n if (rot.mode === 'shuffle' && n > 1) {\n let idx = rot.current\n while (idx === rot.current) idx = Math.floor(Math.random() * n)\n return idx\n }\n return (rot.current + 1) % n\n }\n\n const maybeRotate = async (): Promise<void> => {\n if (!rotationDue()) return\n await applyRotationIndex(pickNextRotationIndex(), true)\n }\n\n // ── Day/night profile schedule ───────────────────────────────────────────────\n const parseHHMM = (s: string): number => {\n const m = /^([01]\\d|2[0-3]):([0-5]\\d)$/.exec(s)\n return m === null ? -1 : Number(m[1]) * 60 + Number(m[2])\n }\n\n const isNightNow = (sc: ScheduleConfig): boolean => {\n const now = new Date()\n const cur = now.getHours() * 60 + now.getMinutes()\n const day = parseHHMM(sc.dayStart)\n const night = parseHHMM(sc.nightStart)\n if (day < 0 || night < 0) return false\n // Normal window (day 07:00 → night 19:00): night wraps midnight.\n if (day <= night) return cur >= night || cur < day\n // Overnight window (e.g. day 22:00 → night 06:00): night is the middle span.\n return cur >= night && cur < day\n }\n\n const scheduleTick = (): void => {\n const sc = rSchedule()\n if (!sc.enabled) return\n // Both steps are optional: `matchMedia?.(…)` alone still throws on the\n // `.matches` read, and this runs inside the boot restore chain and the 30 s\n // schedule timer — a throw here would abort the whole restore (font, skin,\n // wallpaper) and then repeat every tick.\n const night = sc.mode === 'system'\n ? (window.matchMedia?.('(prefers-color-scheme: dark)')?.matches ?? false)\n : isNightNow(sc)\n const want = night ? sc.nightProfile : sc.dayProfile\n if (!want || want === cfg.activeProfile) return\n applyProfileById(want)\n }\n\n // 4. Wallpaper.\n applyWp(); syncBg()\n // The AppFrame mounts after this apply; watch for it so persisted per-part\n // blurs land as soon as the shell renders.\n watchParts()\n // Load the file-backed theme and re-apply once it lands (defaults are already\n // applied above; the deferred restore below re-asserts too). The server\n // advances a due rotation inside the read itself, so the restored wallpaper\n // is already the new pick and paints from the first apply — no old→new flash.\n void loadPersisted().then(async ({ rotated: serverRotated, firstRun }) => {\n if (firstRun) {\n // Nothing was ever persisted on this machine (no theme-config.json).\n // Write the browser half's full default set straight away and re-read it\n // back once, so the restored appearance genuinely comes from disk rather\n // than from in-memory defaults that exist on no reboot.\n persistConfig()\n await loadPersisted()\n applyWp()\n }\n syncMetaNow()\n // The stored custom font (if any) applies immediately; fontEnabled gates\n // the token override without touching the file.\n applyFontFace(fontServeUrl, cfg.fontEnabled, cfg.fontMime)\n // Re-register the skin with the restored color so UI and theme never diverge.\n if (rHasColor()) {\n const [h, s, l] = rColor()\n registerCustom(h, s, l)\n }\n if (serverRotated) {\n // The wallpaper was swapped server-side while the theme color still\n // describes the previous picture: re-extract once so the palette\n // follows the rotation (same adaptation as a client-side advance).\n // Persist the extracted pick — the disk still holds the old color, and\n // without this every later reload would restore it over the new\n // wallpaper.\n if (cfg.backgroundType === 'image' && rWp()) {\n await adoptWallpaperColor(rWp()!)\n saveConfig()\n }\n } else {\n // Fallback client-side advance (server flag missing / older half), still\n // before the branch restore so the fresh wallpaper is what gets applied.\n await maybeRotate()\n }\n // Regenerate on reload if enabled, else reconstruct from saved params.\n if (cfg.backgroundType === 'video') {\n const v = rWpVideo()\n if (v) {\n // The frame snapshot is not persisted: re-capture it for previews.\n captureAndApplyVideo(v)\n applyWp()\n } else {\n // Stored video missing: fall back to the retained image slot.\n cfg.backgroundType = 'image'\n setWpUrl(rWpImage())\n applyThemeColor()\n }\n } else if (cfg.backgroundType !== 'image') {\n if (cfg.regenerateOnReload) {\n regenerateGeneratedBg()\n } else if (cfg.generatedBg) {\n updateGeneratedBg(cfg.generatedBg)\n }\n // Persist the normalized config so the seed and flag land on disk.\n persistConfig()\n } else {\n // Saved pick wins; otherwise extract from the uploaded wallpaper.\n applyThemeColor()\n }\n syncBg()\n scheduleTick()\n if (rHasColor()) { colorRev++; bound?.syncColor(hslToHsv(...rColor()), colorRev) }\n })\n // Schedule cadence: check every 30s (covers fixed-clock switches) and react\n // immediately when the OS scheme flips in 'system' mode.\n const schemeMq = window.matchMedia?.('(prefers-color-scheme: dark)')\n const scheduleTimer = window.setInterval(scheduleTick, 30_000)\n schemeMq?.addEventListener?.('change', scheduleTick)\n ctx.effect(() => () => {\n window.clearInterval(scheduleTimer)\n schemeMq?.removeEventListener?.('change', scheduleTick)\n }, 'dsh-any-background: schedule timer')\n ctx.effect(() => () => { teardownWp() }, 'dsh-any-background: wp cleanup')\n ctx.effect(() => startBetterSidebarWatch(), 'dsh-any-background: better-sidebar watch')\n ctx.effect(() => startHeaderPopoverTagging(), 'dsh-any-background: header popover tagging')\n ctx.effect(() => ctx.on('theme/change', () => {\n // The custom theme's preference lives in memory, so a host adoption can\n // silently reset it; re-assert it while the skin has anything to say (a\n // color, a brightness verdict, or a forced scheme). Guard on registry\n // presence — registerCustom disposes the old skin first, so during that\n // transient the registry lacks CUSTOM_ID.\n if (rHasColor() || rBgDark() !== null || rSchemeOverride() !== 'auto') {\n const snapshot = ctx.theme.getTheme()\n if (snapshot.preference !== CUSTOM_ID && snapshot.themes.some(t => t.id === CUSTOM_ID)) {\n ctx.theme.setTheme(CUSTOM_ID)\n }\n }\n applyWp()\n }), 'dsh-any-background: theme change')\n // Wallpaper placement is computed in absolute viewport pixels, so watch the\n // viewport itself: a fixed inset:0 sentinel's box always equals the viewport,\n // so a ResizeObserver on it catches any viewport change (window resize,\n // monitor moves, panel splitters, zoom); a resolution media query catches\n // DPI-only moves. Re-applies are coalesced to one per animation frame.\n let frame = 0\n const applySoon = (): void => {\n if (frame !== 0) return\n frame = requestAnimationFrame(() => { frame = 0; applyWp() })\n }\n const sentinel = document.createElement('div')\n sentinel.style.cssText = 'position:fixed;inset:0;pointer-events:none;visibility:hidden'\n document.body.append(sentinel)\n const viewportObserver = new ResizeObserver(applySoon)\n viewportObserver.observe(sentinel)\n // A DPI-only move changes no layout box, so the sentinel above misses it;\n // a resolution media query catches it. Optional-chained like the scheme\n // query above: an old WebView without matchMedia must not take down the\n // rest of apply (i18n, section injection, the watchdogs) with a TypeError.\n const dprQuery = window.matchMedia?.(`(resolution: ${window.devicePixelRatio}dppx)`)\n dprQuery?.addEventListener?.('change', applySoon)\n ctx.effect(() => () => {\n viewportObserver.disconnect()\n dprQuery?.removeEventListener?.('change', applySoon)\n sentinel.remove()\n }, 'dsh-any-background: viewport watch')\n\n // 5. Locale.\n ctx.effect(() => ctx.locale.register(NS, { zh, en }), 'dsh-any-background: i18n')\n\n // 6. Section injection.\n /** The business face, built once on first use and shared by both surfaces\n * (the settings section and the better-sidebar page). Memoizing is not just\n * about cost: the face closes over per-surface state — the font preview blob\n * URL behind releaseFontPreview — so a second build would give the sidebar\n * its own preview slot and leak whichever copy never gets released. */\n let themeFace: Omit<ThemeSectionProps, 'useStore'> | null = null\n const buildFace = (): Omit<ThemeSectionProps, 'useStore'> => {\n if (themeFace !== null) return themeFace\n // Both surfaces open long after boot: push the current snapshots so the\n // profiles / rotation / schedule controls render live state, not the\n // store's boot-time defaults.\n syncBg()\n syncMetaNow()\n // Play a picked/imported video instantly from a local object URL while its\n // raw bytes stream to disk in the background — no upload + first-buffer\n // wait after import. The serve URL takes over on the next reload. The\n // upload's outcome is returned so the panel can report a refusal: a video\n // that streams to disk but is refused (oversized) still plays locally and\n // would otherwise look saved.\n const playVideoFromBlob = (blob: Blob, mime: string | null): Promise<UploadOutcome> => {\n const localUrl = URL.createObjectURL(blob)\n cfg.backgroundType = 'video'\n setWpUrl(null)\n cfg.videoBgState = { ...DEFAULT_CONFIG.bgState }\n setWpVideoUrl(localUrl, mime ?? blob.type ?? 'video/mp4')\n applyWp()\n syncBg()\n captureAndApplyVideo(rWpVideo())\n return uploadVideo(blob, mime ?? blob.type ?? 'video/mp4').then(outcome => {\n if (outcome.ok) persistConfig()\n return outcome\n })\n }\n // ── Custom interface font ────────────────────────────────────────────────\n // The file itself lives in the server-side font slot (see uploadFont); the\n // UI only ever sees GTK's serve URL. A picked file is additionally rendered\n // from a local blob URL so the glyph swap is visible while the bytes are\n // still streaming to disk — that preview is released once the slot takes\n // over (a short delay lets any in-flight glyph load finish against it).\n const FONT_EXT_MIME: Record<string, string> = { woff2: 'font/woff2', woff: 'font/woff', otf: 'font/otf', ttf: 'font/ttf' }\n const fontMimeFromName = (name: string): string => {\n const ext = name.split('.').pop()?.toLowerCase() ?? ''\n return FONT_EXT_MIME[ext] ?? 'font/ttf'\n }\n let fontPreviewUrl: string | null = null\n const releaseFontPreview = (delay: number): void => {\n if (fontPreviewUrl === null) return\n const url = fontPreviewUrl\n fontPreviewUrl = null\n window.setTimeout(() => URL.revokeObjectURL(url), delay)\n }\n /** Point the @font-face at whatever is authoritative right now: the\n * persisted slot when one exists, otherwise nothing. */\n const applyStoredFont = (): void => {\n applyFontFace(cfg.fontMime !== null ? FONT_SERVE_URL : null, cfg.fontEnabled, cfg.fontMime)\n }\n\n const [wh, ws, wl] = rColor()\n const [dh, ds, dv] = hslToHsv(wh, ws, wl)\n const built: Omit<ThemeSectionProps, 'useStore'> = {\n t: ctx.locale.bind(NS),\n hue: dh, sat: ds, lit: dv,\n setColor: (nh: number, ns: number, nl: number) => {\n const [sh, ss, sl] = hsvToHsl(nh, ns, nl)\n cfg.color = [sh, ss, sl]\n // Preview UI stays synchronous for instant feedback; the expensive work\n // (theme registration + token writes + persist) is debounced by 80ms.\n if (colorTimerRef.current !== null) window.clearTimeout(colorTimerRef.current)\n colorTimerRef.current = window.setTimeout(() => {\n colorTimerRef.current = null\n registerCustom(sh, ss, sl)\n applyWp()\n saveConfig()\n }, 80)\n // Keep the canonical color in the store so programmatic changes and\n // remounts share one source.\n colorRev++\n bound?.syncColor([nh, ns, nl], colorRev)\n },\n // Server-side set: the wallpaper bytes are ALREADY persisted by the caller\n // (raw upload / URL download / rotation), so this only switches the theme\n // to image mode and points the display at the serve URL. null removes the\n // stored image and video.\n setWpFromServer: (u: string | null) => {\n cfg.backgroundType = 'image'\n // Retain the upload in its own slot so type switches never lose it.\n // The generated-background brightness verdict stops applying here.\n setBgDark(null)\n setWpImageUrl(u)\n // Mirror the same rev'd URL so wpUrl and the display never diverge.\n setWpUrl(rWpImage())\n setBgState({ ...DEFAULT_CONFIG.bgState })\n if (u === null) {\n // Removing the background clears the stored video as well.\n setWpVideoUrl(null, null)\n void persistVideo(null)\n persistWallpaper(null)\n }\n applyThemeColor()\n syncBg()\n },\n setVideo: async (u: Blob | string | null, mime: string | null): Promise<UploadOutcome> => {\n setBgDark(null)\n if (u === null) {\n // Removing: clear the stored video and return to the image slot.\n setWpVideoUrl(null, null)\n cfg.backgroundType = 'image'\n setWpUrl(rWpImage())\n void persistVideo(null)\n applyThemeColor()\n syncBg()\n saveConfig()\n return { ok: true }\n }\n if (typeof u !== 'string') {\n // A picked file plays instantly from a local object URL while its raw\n // bytes stream to disk in the background — no upload + buffer wait.\n return playVideoFromBlob(u, mime)\n }\n // Legacy data-URL string path: persist, then play from the serve URL.\n const ok = await persistVideo(u)\n const live = ok ? VIDEO_SERVE_URL : u\n cfg.backgroundType = 'video'\n setWpUrl(null)\n cfg.videoBgState = { ...DEFAULT_CONFIG.bgState }\n setWpVideoUrl(live, mime ?? null)\n applyWp()\n saveConfig()\n syncBg()\n captureAndApplyVideo(rWpVideo())\n return { ok }\n },\n setBgType: (type: BackgroundType) => {\n setBackgroundType(type)\n // Keep the uploaded wallpaper on disk so it can be restored when the\n // user returns to the image type; it is only removed via setWpFromServer(null).\n saveConfig()\n syncBg()\n },\n setGeneratedBg: (params) => {\n updateGeneratedBg(params)\n saveConfig()\n syncBg()\n },\n regenerateBg: () => {\n regenerateGeneratedBg()\n // Immediate (non-debounced) write so the new seed survives a refresh\n // fired right after the click.\n persistConfig()\n syncBg()\n },\n setRegenerateOnReload: (v: boolean) => {\n cfg.regenerateOnReload = v\n // Immediate (non-debounced) write: a debounced save can be cut off by\n // page unload, which would revert the toggle on the next refresh.\n persistConfig()\n syncBg()\n },\n setOps: (ops: PartOpacities) => { cfg.opacities = ops; applyWp(); syncBg(); saveConfig() },\n setBlurs: (blurs: PartBlurs) => { cfg.blurs = blurs; applyWp(); syncBg(); saveConfig() },\n setStrokes: (strokes: PartStrokes) => { cfg.strokes = strokes; applyStrokes(); saveConfig() },\n // Optimistic upload: render the picked file from a local blob URL at\n // once, stream the bytes to disk, then swap the @font-face to the\n // persisted slot. A rejected upload rolls the preview back to whatever\n // was stored before (nothing, on a first failure).\n setFont: async (file: File): Promise<UploadOutcome> => {\n releaseFontPreview(0)\n const localUrl = URL.createObjectURL(file)\n fontPreviewUrl = localUrl\n applyFontFace(localUrl, true, fontMimeFromName(file.name))\n const outcome = await uploadFont(file)\n if (!outcome.ok || outcome.mime === undefined) {\n applyStoredFont()\n releaseFontPreview(4000)\n return { ok: false, refusal: outcome.refusal }\n }\n cfg.fontMime = outcome.mime\n cfg.fontEnabled = true\n applyFontFace(FONT_SERVE_URL, true, outcome.mime)\n releaseFontPreview(4000)\n persistConfig()\n return { ok: true }\n },\n removeFont: () => {\n releaseFontPreview(0)\n cfg.fontMime = null\n applyFontFace(null, false, null)\n void rpcRemoveFont()\n persistConfig()\n },\n setFontEnabled: (v: boolean) => {\n cfg.fontEnabled = v\n applyStoredFont()\n persistConfig()\n },\n setWop: (v: number) => { cfg.wallpaperOpacity = v; applyWp(); syncBg(); saveConfig() },\n setBl: (v: number) => { cfg.blur = v; applyWp(); syncBg(); saveConfig() },\n setSop: (v: number) => { cfg.settingsOpacity = v; applySettingsOverrides(v); saveConfig() },\n setPanelOp: (v: number) => { cfg.panelOpacity = v; applyPanelOverrides(v); saveConfig() },\n // One-click: derive a theme color from the current wallpaper. Purely\n // client-side — no RPC traffic; the sample is a 64×64 canvas.\n extractColor: async (): Promise<boolean> => {\n const url = rWp()\n if (!url) return false\n // Video mode extracts from the frame snapshot through the video's\n // placement state (rWp already returns the snapshot there).\n const st = cfg.backgroundType === 'video' ? rVideoBgState() : rBgState()\n const hsl = await extractWallpaperColor(url, st)\n if (!hsl) return false\n cfg.color = hsl\n registerCustom(hsl[0], hsl[1], hsl[2])\n applyWp()\n saveConfig()\n const hsv = hslToHsv(hsl[0], hsl[1], hsl[2])\n colorRev++\n bound?.syncColor(hsv, colorRev)\n return true\n },\n // Download the whole theme as dsh-any-theme.json: the config plus the\n // wallpaper data URL only when it is an uploaded image, and the video\n // bytes copied in as a data URL when a video background is active.\n // Generated backgrounds are reconstructed from the saved params on\n // import, so their exports stay small.\n exportTheme: async () => {\n let videoPayload: string | null = null\n if (cfg.backgroundType === 'video') {\n const vurl = rWpVideo()\n if (vurl) {\n try {\n const blob = await fetch(vurl).then(r => r.blob())\n videoPayload = await blobToDataUrl(blob)\n // The serve route may report a generic Content-Type; pin the\n // recorded MIME so the import detector sees data:video/….\n if (videoPayload && !/^data:video\\//.test(videoPayload)) {\n videoPayload = videoPayload.replace(/^data:[^;,]*/, `data:${cfg.videoMime ?? 'video/mp4'}`)\n }\n } catch {\n videoPayload = null\n }\n }\n }\n // The wallpaper is displayed through the serve URL; exports embed the\n // bytes (fetched from that URL) so the file is portable.\n let wallpaperPayload: string | null = null\n if (cfg.backgroundType === 'image') {\n const wurl = rWp()\n if (wurl) {\n if (wurl.startsWith('data:')) {\n wallpaperPayload = wurl\n } else {\n try {\n const blob = await fetch(wurl).then(r => r.blob())\n wallpaperPayload = await blobToDataUrl(blob)\n } catch {\n wallpaperPayload = null\n }\n }\n }\n }\n const payload = {\n version: 2,\n exportedAt: new Date().toISOString(),\n config: cfg,\n wallpaper: wallpaperPayload,\n video: videoPayload,\n }\n const blob = new Blob([JSON.stringify(payload, null, 2)], { type: 'application/json' })\n const url = URL.createObjectURL(blob)\n const a = document.createElement('a')\n a.href = url\n a.download = 'dsh-any-theme.json'\n a.click()\n // Firefox and Safari start the download asynchronously; revoking in the\n // same tick can abort it. releaseFontPreview below already uses this\n // delayed-revoke pattern for the same reason.\n window.setTimeout(() => URL.revokeObjectURL(url), 4000)\n },\n // Import a theme JSON: apply the config to memory, then persist through\n // the same paths as manual edits — config → theme-config.json, wallpaper\n // base64 → wallpaper.jpg (decoded on the node half). For generated\n // backgrounds the image is reconstructed from params instead of persisted.\n importTheme: async (file: File): Promise<boolean> => {\n try {\n const data: unknown = JSON.parse(await file.text())\n if (!data || typeof data !== 'object') return false\n const d = data as { version?: number; config?: unknown; wallpaper?: unknown; video?: unknown }\n if (typeof d.config !== 'object' || d.config === null) return false\n adoptConfig(d.config)\n if (cfg.backgroundType === 'video') {\n const video = typeof d.video === 'string' && /^data:video\\//.test(d.video) ? d.video : null\n if (video !== null) {\n // Decode the embedded data URL to a blob and play it instantly\n // from a local object URL while the bytes stream to disk in the\n // background (the data-URL RPC path stays as the small fallback).\n let blob: Blob | null = null\n try { blob = await fetch(video).then(r => r.blob()) } catch { blob = null }\n if (blob !== null) {\n // Fire and forget: the import's own success/failure is already\n // reported, and the embedded video typically exceeds the upload\n // limit anyway (the same cap that made the fetch path win).\n void playVideoFromBlob(blob, cfg.videoMime)\n } else {\n const ok = await persistVideo(video)\n const live = ok ? VIDEO_SERVE_URL : video\n setWpVideoUrl(live, cfg.videoMime)\n applyWp()\n captureAndApplyVideo(rWpVideo())\n }\n } else {\n // Export lacked the video payload: fall back to no background.\n setWpVideoUrl(null, null)\n void persistVideo(null)\n cfg.backgroundType = 'image'\n setWpImageUrl(null)\n setWpUrl(null)\n persistWallpaper(null)\n applyThemeColor()\n }\n } else if (cfg.backgroundType === 'image') {\n const wallpaper = typeof d.wallpaper === 'string' && /^data:image\\//.test(d.wallpaper) ? d.wallpaper : null\n setWpImageUrl(wallpaper)\n setWpUrl(wallpaper)\n persistWallpaper(wallpaper)\n applyThemeColor()\n } else {\n setWpImageUrl(null)\n setWpUrl(null)\n persistWallpaper(null)\n // Reconstruct the imported dynamic background from its saved params.\n // Import means \"restore what I exported\", so the seed/params must be\n // preserved exactly; only regenerate a fresh look when the user has\n // that preference enabled — mirroring the boot-restore branch.\n if (cfg.regenerateOnReload) regenerateGeneratedBg()\n else if (cfg.generatedBg) updateGeneratedBg(cfg.generatedBg)\n }\n persistConfig()\n // The imported file carries profiles / rotation / schedule / scheme\n // too: push them into the meta store or the panels keep rendering the\n // previous lists until the next reload.\n syncMetaNow()\n if (rHasColor()) {\n const [h, s, l] = rColor()\n registerCustom(h, s, l)\n }\n syncBg()\n if (rHasColor()) {\n colorRev++\n bound?.syncColor(hslToHsv(...rColor()), colorRev)\n }\n return true\n } catch {\n return false\n }\n },\n // Save the current appearance as a named profile (oldest dropped at 20).\n saveProfile: (name: string): boolean => {\n const trimmed = name.trim()\n if (!trimmed) return false\n const profiles = [...rProfiles()]\n if (profiles.length >= 20) profiles.shift()\n const id = `p-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`\n profiles.push({ id, name: trimmed.slice(0, 60), createdAt: new Date().toISOString(), config: currentAppearance() })\n cfg.profiles = profiles\n cfg.activeProfile = id\n persistConfig()\n syncMetaNow()\n return true\n },\n applyProfile: (id: string): boolean => applyProfileById(id),\n deleteProfile: (id: string): boolean => {\n const before = rProfiles()\n if (!before.some(p => p.id === id)) return false\n cfg.profiles = before.filter(p => p.id !== id)\n if (cfg.activeProfile === id) cfg.activeProfile = null\n // Clear schedule references so the tick never targets a dead id.\n const sc = rSchedule()\n if (sc.dayProfile === id || sc.nightProfile === id) {\n cfg.schedule = {\n ...sc,\n dayProfile: sc.dayProfile === id ? null : sc.dayProfile,\n nightProfile: sc.nightProfile === id ? null : sc.nightProfile,\n }\n }\n persistConfig()\n syncMetaNow()\n return true\n },\n applyPreset: (appearance: ProfileAppearance): void => {\n applyAppearanceLive(appearance)\n cfg.activeProfile = null\n applyWp()\n persistConfig()\n syncMetaNow()\n },\n setSchemeOverride: (v: SchemeOverride): void => {\n cfg.schemeOverride = v\n // Re-register the skin in every case: with a color the palette follows\n // the forced direction; without one a neutral palette is registered so\n // the host presenter flips the fonts too.\n registerCustom()\n applyWp()\n saveConfig()\n syncMetaNow()\n },\n setSchedule: (patch: Partial<ScheduleConfig>): void => {\n cfg.schedule = { ...rSchedule(), ...patch }\n if (patch.enabled === true) scheduleTick()\n persistConfig()\n syncMetaNow()\n },\n setRotation: (patch: Partial<Pick<typeof cfg.rotation, 'enabled' | 'mode' | 'interval'>>): void => {\n cfg.rotation = { ...rRotation(), ...patch }\n if (patch.enabled === true) void maybeRotate()\n persistConfig()\n syncMetaNow()\n },\n addRotationItems: async (files: File[]): Promise<boolean> => {\n let added = false\n for (const f of files) {\n if (!f.type.startsWith('image/')) continue\n const dataUrl = await readImgAsync(f)\n if (!dataUrl) continue\n const thumb = await makeThumb(dataUrl)\n const r = await rotationAdd(dataUrl, thumb ?? '')\n if (r.ok && r.items !== undefined) {\n cfg.rotation = { ...rRotation(), items: r.items as RotationItem[] }\n added = true\n }\n }\n if (added) {\n // Server already wrote the items into its config copy; re-persist so\n // the client's full config (meta included) stays authoritative.\n persistConfig()\n syncMetaNow()\n syncBg()\n }\n return added\n },\n removeRotationItem: async (index: number): Promise<boolean> => {\n const r = await rotationRemove(index)\n if (!r.ok || r.items === undefined) return false\n const rot = rRotation()\n cfg.rotation = {\n ...rot,\n items: r.items as RotationItem[],\n current: Math.max(0, Math.min(rot.current >= index ? rot.current - 1 : rot.current, Math.max(0, r.items.length - 1))),\n }\n persistConfig()\n syncMetaNow()\n return true\n },\n rotateNow: async (): Promise<boolean> => {\n if (rRotation().items.length === 0) return false\n return applyRotationIndex(pickNextRotationIndex(), true)\n },\n // Network video URL: the server streams it into the video slot; the\n // client switches to video mode and plays from the serve URL, then\n // captures the preview frame through the same path as local uploads.\n setVideoFromUrl: async (url: string): Promise<boolean> => {\n const r = await rpcSetVideoFromUrl(url)\n if (!r.ok || !r.mime) {\n console.warn('dsh-any-background: video url fetch failed', r.error)\n return false\n }\n setBgDark(null)\n cfg.backgroundType = 'video'\n setWpUrl(null)\n cfg.videoBgState = { ...DEFAULT_CONFIG.bgState }\n setWpVideoUrl(VIDEO_SERVE_URL, r.mime)\n applyWp()\n saveConfig()\n syncBg()\n captureAndApplyVideo(rWpVideo())\n return true\n },\n }\n themeFace = built\n return built\n }\n // The settings slot's inject face: it still owns binding the actions the host\n // hands over (the very actions of the shared instance), then returns the shared\n // face so both surfaces read one instance of it.\n const sectionInject = (actions: BoundActions): Omit<ThemeSectionProps, 'useStore'> => {\n bound = actions\n return buildFace()\n }\n if (store === null) {\n // No host store module (see runtime.ts): the section needs one to bind its\n // props, so register nothing. The theme/wallpaper half above still works.\n console.error('dsh-any-background: settings panel disabled on this host (no store module)')\n } else {\n ctx.slots.inject('settings.section', () => ctx.slots.register({\n name: 'settings.section', id: 'dsh-any-background', order: 35,\n label: () => ctx.locale.bind(NS)('nav'),\n locale: NS, store, inject: sectionInject,\n }, ThemeSection as any))\n }\n\n // 6.1. Sidebar pages: the same five pages, registered twice by surface —\n // as a better-sidebar tab when that plugin is installed, and as a native\n // right-Sidebar tab (\"主题\" card on the official Sidebar's guide page) when\n // it is not. Both are runtime-optional — see the modules for how each\n // service is resolved without importing it. `storeInstance` (not the\n // declaration) is what either page's selector hook has to bind.\n registerThemeSidebarTab(ctx, { face: buildFace, store: storeInstance })\n registerNativeSidebarTab(ctx, { face: buildFace, store: storeInstance })\n\n // 6.5. Settings-nav icon: the harness derives the nav glyph from the section\n // id (unknown ids fall back to the settings gear) with no plugin hook, so\n // patch the mounted nav cell in place — find the cell whose label matches\n // this section's nav text and swap its svg for the sun glyph.\n const navLabel = (): string => ctx.locale.bind(NS)('nav')\n const applyNavIcon = (): void => {\n // SETTINGS_PANEL_SEL rather than the ARIA shape: a confirm dialog is an\n // aria-modal dialog with a labelledby too, and document order decides which one\n // a loose query returns — so the glyph would go missing whenever that dialog\n // happens to precede a re-mounted settings panel. Same anchor as the styles.\n const panel = document.querySelector<HTMLElement>(SETTINGS_PANEL_SEL)\n const nav = panel?.querySelector('nav')\n if (!nav) return\n const target = navLabel()\n for (const cell of Array.from(nav.querySelectorAll('button'))) {\n const label = cell.querySelector('span')\n if (label && label.textContent?.trim() === target) {\n const svg = cell.querySelector('svg')\n if (svg && svg.dataset.dshAnyIcon !== '1') {\n const sun = document.createElementNS('http://www.w3.org/2000/svg', 'svg')\n sun.setAttribute('width', '16')\n sun.setAttribute('height', '16')\n sun.setAttribute('viewBox', '0 0 16 16')\n sun.setAttribute('fill', 'none')\n sun.setAttribute('xmlns', 'http://www.w3.org/2000/svg')\n sun.dataset.dshAnyIcon = '1'\n sun.innerHTML = SUN_PATHS\n svg.replaceWith(sun)\n }\n return\n }\n }\n }\n let navIconObserver: MutationObserver | null = null\n const watchNavIcon = (): void => {\n if (navIconObserver !== null || typeof MutationObserver === 'undefined') return\n navIconObserver = new MutationObserver(records => {\n // React only when the settings panel (or its nav) is (re)created, so\n // chat-content mutations don't trigger a scan.\n const relevant = records.some(r => {\n for (const n of r.addedNodes) {\n if (n.nodeType !== 1) continue\n const el = n as Element\n if (el.matches?.(SETTINGS_PANEL_SEL) || el.querySelector?.(SETTINGS_PANEL_SEL)) return true\n }\n return false\n })\n if (relevant) applyNavIcon()\n })\n navIconObserver.observe(document.body, { childList: true, subtree: true })\n applyNavIcon()\n }\n watchNavIcon()\n ctx.effect(() => () => { navIconObserver?.disconnect(); navIconObserver = null }, 'dsh-any-background: nav icon watch')\n\n // 7. Deferred boot restore: the theme service and the host settings scope\n // settle asynchronously after this apply, so the synchronous restore can be\n // observed mid-flight — a late host adoption resets the preference, or the\n // presenter re-applies over our overrides. Re-running the saved-color and\n // wallpaper restore a few ticks later guarantees the saved records land.\n const restoreSaved = (): void => {\n if (rHasColor()) {\n const snapshot = ctx.theme.getTheme()\n if (!snapshot.themes.some(t => t.id === CUSTOM_ID)) {\n // Theme missing (host adoption dropped it): re-register + activate.\n const [h, s, l] = rColor()\n registerCustom(h, s, l)\n } else if (snapshot.preference !== CUSTOM_ID) {\n // Theme present but inactive: just re-assert the preference. Calling\n // registerCustom here would dispose + re-create the skin, flashing the\n // interface back to the system theme for a frame on every boot.\n ctx.theme.setTheme(CUSTOM_ID)\n }\n }\n applyWp()\n }\n const restoreTimers = [300, 1500].map(delay => window.setTimeout(restoreSaved, delay))\n ctx.effect(() => () => { restoreTimers.forEach(id => window.clearTimeout(id)) }, 'dsh-any-background: boot restore')\n\n // 8. Theme watchdog: the theme service keeps only built-in preferences in\n // memory, so ANY host-scope adoption can silently drop the custom theme —\n // reverting the label colors (white/black) and the inner surfaces to the\n // system palette. While the skin has anything to say (a color, a brightness\n // verdict, or a forced scheme), re-register and re-assert the custom theme\n // on a slow interval so the theme state always matches it, independent of\n // which event resets it.\n const watchdogId = window.setInterval(() => {\n if (!rHasColor() && rBgDark() === null && rSchemeOverride() === 'auto') return\n const snapshot = ctx.theme.getTheme()\n let changed = false\n if (!snapshot.themes.some(t => t.id === CUSTOM_ID)) {\n registerCustom()\n changed = true\n } else if (snapshot.preference !== CUSTOM_ID) {\n ctx.theme.setTheme(CUSTOM_ID)\n changed = true\n }\n if (changed) applyWp()\n }, 1000)\n ctx.effect(() => () => { window.clearInterval(watchdogId) }, 'dsh-any-background: theme watchdog')\n\n // 8.5. Theme-reset watchdog: counter the host re-asserting its own light\n // :root/body scheme after startup (refresh, cold load, settings adoption),\n // which would paint a frame of white surfaces.\n const disposeThemeResets = watchThemeResets()\n ctx.effect(() => () => { disposeThemeResets() }, 'dsh-any-background: theme resets watch')\n\n // 9. Flush any pending debounced config write when the page is hidden or\n // closed, so the last slider position is never lost to the debounce window.\n const onPageHide = (): void => flushSave()\n window.addEventListener('pagehide', onPageHide)\n ctx.effect(() => () => window.removeEventListener('pagehide', onPageHide), 'dsh-any-background: pagehide flush')\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"client.js","names":["panelFragments","createAdapter","panelFragments","createAdapter","panelFragments","createAdapter","panelFragments","createAdapter","panelFragments","createAdapter","panelFragments","createAdapter","panelFragments","createAdapter","adapterFor015rc","adapterFor016alpha","adapterFor017alpha","adapterFor017rc","adapterFor020rc","adapterFor020rc2","adapterFor021alpha","adapterForUnknown","subs","randomSeed","Component","useState","createPortal","memo","useRef","useState","useCallback","SEG_W","useState","useRef","useRef","useState","useCallback","useState","useRef","PARTS","useRef","useState","useState","useRef","useCallback","useRef","useState","useRef","useState","useState","useRef","useCallback","useMemo","useRef","useCallback","useSyncExternalStore","useCallback","useSyncExternalStore","useMemo","createElement","createElement","subscribeBetterSidebar","rpcRemoveFont","rpcSetVideoFromUrl"],"sources":["../src/client/runtime.ts","../src/client/i18n.ts","../src/client/state.ts","../src/host-compat/channel.ts","../src/client/host-compat/versions/shared.ts","../src/client/host-compat/versions/v0-1-5-rc-2-3/adapter.ts","../src/client/host-compat/versions/v0-1-6-alpha-1-2/adapter.ts","../src/client/host-compat/versions/v0-1-7-alpha-1-2-rc-1/adapter.ts","../src/client/host-compat/versions/v0-1-7-rc-2/adapter.ts","../src/client/host-compat/versions/v0-2-0-rc-1/adapter.ts","../src/client/host-compat/versions/v0-2-0-rc-2/adapter.ts","../src/client/host-compat/versions/v0-2-1-alpha-1/adapter.ts","../src/client/host-compat/versions/unknown/adapter.ts","../src/client/host-compat/versions/registry.ts","../src/client/host-compat/release.ts","../src/client/rpc.ts","../src/client/host-compat/capabilities.ts","../src/client/header-tag.ts","../src/client/utils/image.ts","../src/client/utils/color.ts","../src/client/utils/bg-generators.ts","../src/client/wallpaper.ts","../src/client/host-compat/styles.ts","../src/client/utils/video.ts","../src/client/components/ui.css.ts","../src/client/components/icons.tsx","../src/client/components/ErrorBoundary.tsx","../src/client/components/Portal.tsx","../src/client/components/ColorWheel.tsx","../src/client/components/ColorInputs.tsx","../src/client/components/ColorPicker.tsx","../src/client/components/pages/ColorPage.tsx","../src/client/components/LiveSlider.tsx","../src/client/components/pages/InterfacePage.tsx","../src/client/components/pages/FontPage.tsx","../src/client/components/BgEditor.tsx","../src/client/components/pages/BackgroundPage.tsx","../src/client/utils/presets.ts","../src/client/components/pages/ProfilePage.tsx","../src/client/components/ThemeSection.tsx","../src/client/sidebar/store-hook.ts","../src/client/sidebar/tab.tsx","../src/client/env.ts","../src/client/sidebar/native-tab.tsx","../src/client/index.tsx"],"sourcesContent":["/**\n * Harness-version-agnostic access to the client runtime.\n *\n * Before dsh 0.1.2 the store primitive lived on the composite package\n * `@deepseek-ai/dsh-client-runtime` (the `/client` subpath). The new harness\n * split it into `@deepseek-ai/dsh-client-store`. Both specifiers are kept\n * external so they resolve against the host client-module table; a missing\n * table entry on one side throws (the \"missed the module table\" error) and is\n * caught, falling through to the other package. This lets one bundle load on\n * both the old npm release and the new source.\n *\n * The host's synchronous `require` is injected by the loader into the bundle\n * factory; tsdown keeps these two bare specifiers as external CJS requires so\n * they bind to that factory `require`.\n */\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\ninterface StoreModule {\n defineStore: any\n}\n\nfunction resolveStore(): StoreModule | null {\n try {\n // New harness (dsh >= 0.1.2): dedicated store package after the runtime\n // was split. Missing here means the loader table has no such row → throw.\n return require('@deepseek-ai/dsh-client-store') as StoreModule\n } catch {\n /* fall through to the legacy composite runtime below */\n }\n try {\n // Legacy harness (npm release): composite runtime, /client subpath.\n return require('@deepseek-ai/dsh-client-runtime/client') as StoreModule\n } catch {\n // Neither resolved (host variant with no store module at all). This MUST\n // not throw at import time: this module is evaluated while the client\n // bundle boots, so a throw here kills the whole plugin — no theme, no\n // wallpaper, nothing. Callers degrade to \"no settings panel\" instead.\n console.warn('dsh-any-background: no client store module resolved on this host; the settings panel will be disabled')\n return null\n }\n}\n\n/** null when neither store package resolves on this host (see resolveStore). */\nexport const defineStore: any = resolveStore()?.defineStore ?? null","export const NS = 'settings.anyBg'\r\n\r\nexport const zh: Record<string, string> = {\r\n nav: '主题', brandTag: '外观定制', close: '关闭',\r\n pageColor: '色彩', pageInterface: '界面', pageFont: '字体', pageBackground: '背景', pageProfile: '配置',\r\n descColor: '拖动色轮或输入精确数值,整个界面的配色将实时跟随变化',\r\n descInterface: '为主界面的各个区域单独调节透明度与模糊,营造空间层次感',\r\n descFont: '上传自定义字体为整套界面换字形,并按区域为文字添加描边,让内容在复杂的壁纸上依然清晰',\r\n descBackground: '上传一张图片或一段视频作为壁纸并自由摆放,或让算法为你实时生成动态背景',\r\n descProfile: '一键套用外观预设,保存多套配置随时切换,设置昼夜自动换装,或导出/导入完整主题',\r\n colorTitle: '主题色', colorHint: '在色轮外圈选择色相,在内部方形中调整饱和度和明度;双击滑块可恢复默认值',\r\n swatchTitle: '灵感色板',\r\n hexCaption: '当前主题色',\r\n uiTitle: '主界面',\r\n uiOpacity: '透明度', uiBlur: '模糊度',\r\n uiOpacityBg: '主背景', uiOpacitySide: '侧边栏', uiOpacityCard: '对话框中选项面板', uiOpacityInput: '输入框与控件',\r\n uiSop: '设置界面',\r\n uiChatRegion: '对话文本框',\r\n uiTrajectory: '轨迹页',\r\n uiPanelNative: '右方侧边栏',\r\n guideDesc: '管理主题色、壁纸与界面透明度',\r\n uiProduced: '产出物/高亮内容',\r\n uiHeader: '顶栏选项',\r\n uiHeaderBar: '标题栏',\r\n fontPageTitle: '字体与描边',\r\n fontTitle: '自定义字体',\r\n fontHint: '支持 ttf/otf/woff/woff2 字体文件(上限 100MB),将应用到整个界面的文字;代码块的等宽字体保持不变。中文字体通常有几十 MB,首次上传与刷新加载需要片刻',\r\n fontUpload: '上传字体',\r\n fontUploading: '上传中…',\r\n fontRemove: '移除字体',\r\n fontEnabled: '启用字体',\r\n fontNone: '未设置,使用宿主默认字体',\r\n fontFail: '字体上传失败,请确认是有效的 ttf/otf/woff/woff2 文件',\r\n uploadTooLarge: '文件过大,上限 {limit}',\r\n bgUploadFail: '壁纸上传失败',\r\n videoUploadFail: '视频上传失败,本次播放不会被保存',\r\n strokeTitle: '文字描边',\r\n strokeHint: '按区域为文字添加描边:粗细为 0 表示关闭,「自动」会生成与文字颜色相反的颜色,「主题色」跟随当前主题色。代码块与图标已自动豁免,多色语法不会糊成一团',\r\n strokeWidth: '描边粗细',\r\n strokeColor: '描边颜色',\r\n strokeAuto: '自动反色',\r\n strokeGray: '灰色',\r\n strokeBlack: '黑色',\r\n strokeWhite: '白色',\r\n strokeTheme: '主题色',\r\n strokeCustom: '自定义',\r\n bgTitle: '背景', bgChoose: '选择图片或视频', bgRemove: '移除背景', bgFromUrl: '从网址', bgUrlPlaceholder: '粘贴图片或视频网址 https://…', bgUrlApply: '应用', bgUrlCancel: '取消', bgUrlApplying: '加载中…', bgUrlBadHttp: '仅支持 http/https 图片网址', bgUrlFail: '获取图片失败',\r\n bgEdit: '编辑位置', bgEditLocked: '仅「适应」模式可编辑位置', wpOpacity: '背景透明度', bgBlur: '背景模糊',\r\n bgModeTitle: '布局模式',\r\n bgModeFit: '适应', bgModeFill: '填充', bgModeStretch: '拉伸', bgModeTile: '平铺', bgModeCenter: '居中',\r\n bgVideoBadge: '视频',\r\n bgSourceImage: '图片 / 视频',\r\n bgSourceGenerated: '动态生成',\r\n dropHint: '点击选择图片或视频,或将文件拖到这里',\r\n liveBadge: '动态壁纸',\r\n bgHint: '「适应」布局模式下悬停预览可编辑图片/视频的位置与缩放(其余布局模式按模式自动排布);动态生成模式下可选择类型、预设与参数。绑定种子后刷新页面壁纸保持不变,取消绑定则每次刷新随机换新',\r\n editorTitle: '背景编辑器', editorHint: '拖动移动画面,滚轮或双指缩放大小',\r\n editorCommit: '确认', editorCancel: '取消', editorReset: '重置',\r\n extractColor: '从背景提取主题色', extracting: '取色中…',\r\n extractNoWp: '请先设置背景图片',\r\n extractDone: '已应用背景主色调',\r\n extractFail: '未在背景中找到鲜明的颜色,请换一张背景',\r\n crashTitle: '界面渲染出错',\r\n crashDesc: '主题设置面板遇到问题,点击下方按钮重置后重试',\r\n crashReset: '重置面板',\r\n exportTheme: '导出配置',\r\n importTheme: '导入配置',\r\n exportCardTitle: '导出配置',\r\n exportCardDesc: '将主题色、透明度、模糊与壁纸打包为 dsh-any-theme.json 文件',\r\n importCardTitle: '导入配置',\r\n importCardDesc: '从之前导出的 JSON 文件一键恢复完整主题',\r\n toastExportDone: '配置文件已开始下载',\r\n importDone: '已导入主题配置',\r\n importFail: '导入失败,文件格式不正确',\r\n footerTag: '外观插件',\r\n eyedropper: '从背景取色',\r\n pickerTitle: '从背景取色',\r\n pickerHint: '移动鼠标预览颜色,点击背景选取为主题色',\r\n pickerClose: '关闭',\r\n bgTypeImage: '图片',\r\n bgTypeMesh: '网格渐变',\r\n bgTypeShader: 'Shader',\r\n bgTypePattern: '几何图案',\r\n bgMeshDesc: '柔和的多点渐变色块',\r\n bgShaderDesc: '持续流动的光影动画',\r\n bgPatternDesc: '规律的几何纹理',\r\n bgRegenerate: '重新生成',\r\n bgSeedLocked: '已绑定 · 刷新不变',\r\n bgSeedUnlocked: '未绑定 · 刷新换新',\r\n seedLock: '锁定种子',\r\n bgMeshScale: '扩散范围',\r\n bgMeshIntensity: '色彩强度',\r\n bgShaderPreset: '预设',\r\n bgShaderSpeed: '流动速度',\r\n bgShaderScale: '纹理尺度',\r\n bgPatternPreset: '图案',\r\n bgPatternDensity: '密度',\r\n bgPatternScale: '尺度',\r\n presetAurora: '极光',\r\n presetNebula: '星云',\r\n presetNoise: '流动噪声',\r\n presetDots: '点阵',\r\n presetWaves: '波浪',\r\n presetPoly: '低多边形',\r\n presetStarfield: '星空',\r\n presetRain: '雨滴',\r\n presetContour: '等高线',\r\n presetMeta: '流体光斑',\r\n bgPause: '暂停',\r\n bgResume: '播放',\r\n bgUrlVideoFail: '获取视频失败,请确认链接可直接下载视频文件',\r\n schemeTitle: '界面明暗',\r\n schemeLight: '亮色',\r\n schemeDark: '暗色',\r\n schemeAuto: '自动',\r\n schemeHint: '「自动」优先跟随背景画面的实际明暗决定界面明暗(无背景时依据主题色明度);强制亮色/暗色后整套配色按所选方向生成,未选主题色时使用中性灰配色',\r\n presetGalleryTitle: '外观预设',\r\n presetName_default: '默认',\r\n presetDesc_default: '恢复插件的初始外观',\r\n presetName_glass: '毛玻璃',\r\n presetDesc_glass: '通透表面 + 磨砂玻璃层次',\r\n presetName_minimal: '极简白',\r\n presetDesc_minimal: '接近实色的表面,无模糊',\r\n presetName_midnight: '暗夜紫',\r\n presetDesc_midnight: '深色强调,重磨砂低透明度',\r\n presetName_cyber: '赛博',\r\n presetDesc_cyber: '艳丽洋红,界面近乎消失',\r\n presetName_warm: '暖阳',\r\n presetDesc_warm: '琥珀色调的明亮实色界面',\r\n presetApplied: '预设已应用',\r\n profilesTitle: '我的配置',\r\n profileSave: '保存当前配置',\r\n profileNamePlaceholder: '输入配置名称…',\r\n profileNameRequired: '请先输入配置名称',\r\n profileSaved: '配置已保存',\r\n profileApplied: '配置已应用',\r\n profileApply: '应用',\r\n profileDelete: '删除配置',\r\n profileDeleteConfirm: '确认删除',\r\n profileNone: '不切换',\r\n profilesEmpty: '还没有保存的配置。调整好外观后点击「保存当前配置」,即可随时一键切换。',\r\n scheduleTitle: '昼夜自动切换',\r\n scheduleHint: '按时间或系统深色模式,在两套已保存的配置之间自动切换(切换的是配色与表面参数,壁纸不变)',\r\n scheduleMode: '切换依据',\r\n scheduleModeTime: '固定时段',\r\n scheduleModeSystem: '跟随系统',\r\n scheduleTimes: '切换时间',\r\n scheduleDayStart: '日间开始',\r\n scheduleNightStart: '夜间开始',\r\n scheduleProfiles: '对应配置',\r\n scheduleDayProfile: '日间',\r\n scheduleNightProfile: '夜间',\r\n rotTitle: '壁纸轮换',\r\n rotHint: '把多张图片加入轮换池,按所选频率自动更换壁纸;启用后立即生效',\r\n rotAdd: '添加图片',\r\n rotRemove: '移除',\r\n rotShuffle: '随机',\r\n rotOrder: '顺序',\r\n rotReload: '每次刷新',\r\n rotDaily: '每天',\r\n rotWeekly: '每周',\r\n rotNow: '立即切换',\r\n}\r\n\r\nexport const en: Record<string, string> = {\r\n nav: 'Theme', brandTag: 'Appearance', close: 'Close',\r\n pageColor: 'Color', pageInterface: 'Interface', pageFont: 'Font', pageBackground: 'Background', pageProfile: 'Profile',\r\n descColor: 'Drag the wheel or type exact values — the whole UI follows live',\r\n descInterface: 'Tune opacity and blur per surface to build depth',\r\n descFont: 'Swap the interface typeface with your own font file, and outline text per region so it stays legible over busy wallpapers',\r\n descBackground: 'Upload an image or a video as wallpaper and place it freely, or let the algorithm paint a live background',\r\n descProfile: 'Apply a one-click preset, save multiple named profiles, schedule a day/night switch, or export/import the full theme',\r\n colorTitle: 'Theme color', colorHint: 'Pick hue on the outer ring, adjust saturation & lightness in the square; double-click a slider to reset',\r\n swatchTitle: 'Quick swatches',\r\n hexCaption: 'Current accent',\r\n uiTitle: 'Interface',\r\n uiOpacity: 'Opacity', uiBlur: 'Blur',\r\n uiOpacityBg: 'Main background', uiOpacitySide: 'Sidebar', uiOpacityCard: 'Cards & panels', uiOpacityInput: 'Input & controls',\r\n uiSop: 'Settings interface',\r\n uiChatRegion: 'Conversation text frame',\r\n uiTrajectory: 'Trajectory view',\r\n uiPanelNative: 'Right sidebar',\r\n guideDesc: 'Theme color, wallpaper and interface opacity in the right sidebar',\r\n uiProduced: 'Produced / highlights',\r\n uiHeader: 'Header popovers',\r\n uiHeaderBar: 'Header bar',\r\n fontPageTitle: 'Font & outline',\r\n fontTitle: 'Custom font',\r\n fontHint: 'Accepts ttf/otf/woff/woff2 files (up to 100MB) and applies them to the whole interface; code blocks keep their monospace stack. CJK fonts routinely span tens of MB, so the first upload and each reload take a moment',\r\n fontUpload: 'Upload font',\r\n fontUploading: 'Uploading…',\r\n fontRemove: 'Remove font',\r\n fontEnabled: 'Font enabled',\r\n fontNone: 'None — host default',\r\n fontFail: 'Upload failed — make sure it is a valid ttf/otf/woff/woff2 file',\r\n uploadTooLarge: 'File is too large (limit {limit})',\r\n bgUploadFail: 'Wallpaper upload failed',\r\n videoUploadFail: 'Video upload failed — this playback will not be saved',\r\n strokeTitle: 'Text outline',\r\n strokeHint: 'Outline text per region: width 0 turns it off, \"auto\" picks the inverse of the text color, and \"theme\" follows the current accent. Code blocks and icons are exempted automatically, so multi-color syntax never smears',\r\n strokeWidth: 'Outline width',\r\n strokeColor: 'Outline color',\r\n strokeAuto: 'Auto contrast',\r\n strokeGray: 'Gray',\r\n strokeBlack: 'Black',\r\n strokeWhite: 'White',\r\n strokeTheme: 'Accent',\r\n strokeCustom: 'Custom',\r\n bgTitle: 'Background', bgChoose: 'Choose image or video', bgRemove: 'Remove background', bgFromUrl: 'From URL', bgUrlPlaceholder: 'Paste an image or video URL https://…', bgUrlApply: 'Apply', bgUrlCancel: 'Cancel', bgUrlApplying: 'Loading…', bgUrlBadHttp: 'Only http/https image URLs are supported', bgUrlFail: 'Could not fetch the image',\r\n bgEdit: 'Edit position', bgEditLocked: 'Position editing is only available in Fit mode', wpOpacity: 'Background opacity', bgBlur: 'Background blur',\r\n bgModeTitle: 'Layout mode',\r\n bgModeFit: 'Fit', bgModeFill: 'Fill', bgModeStretch: 'Stretch', bgModeTile: 'Tile', bgModeCenter: 'Center',\r\n bgVideoBadge: 'Video',\r\n bgSourceImage: 'Image / Video',\r\n bgSourceGenerated: 'Generated',\r\n dropHint: 'Click to choose an image or video, or drop one here',\r\n liveBadge: 'Live wallpaper',\r\n bgHint: 'In Fit layout mode hover the preview to reposition and zoom the image/video (other modes arrange it automatically); in generated mode pick a type, preset and parameters. With the seed locked the wallpaper stays the same across refreshes; unlocked, every refresh randomizes it',\r\n editorTitle: 'Background editor', editorHint: 'Drag to move; scroll or pinch with two fingers to zoom',\r\n editorCommit: 'Confirm', editorCancel: 'Cancel', editorReset: 'Reset',\r\n extractColor: 'Extract from background', extracting: 'Extracting…',\r\n extractNoWp: 'Set a background first',\r\n extractDone: 'Background color applied',\r\n extractFail: 'No vivid color found in this background, try another',\r\n crashTitle: 'Section crashed',\r\n crashDesc: 'The theme panel hit an error. Reset below to recover.',\r\n crashReset: 'Reset panel',\r\n exportTheme: 'Export',\r\n importTheme: 'Import',\r\n exportCardTitle: 'Export profile',\r\n exportCardDesc: 'Bundle color, opacity, blur and wallpaper into dsh-any-theme.json',\r\n importCardTitle: 'Import profile',\r\n importCardDesc: 'Restore a full theme from a previously exported JSON file',\r\n toastExportDone: 'Export started',\r\n importDone: 'Theme imported',\r\n importFail: 'Import failed — invalid file',\r\n footerTag: 'Appearance plugin',\r\n eyedropper: 'Eyedropper',\r\n pickerTitle: 'Pick from background',\r\n pickerHint: 'Hover to preview, click to pick as theme color',\r\n pickerClose: 'Close',\r\n bgTypeImage: 'Image',\r\n bgTypeMesh: 'Mesh gradient',\r\n bgTypeShader: 'Shader',\r\n bgTypePattern: 'Pattern',\r\n bgMeshDesc: 'Soft multi-blob gradients',\r\n bgShaderDesc: 'Flowing light animation',\r\n bgPatternDesc: 'Regular geometric texture',\r\n bgRegenerate: 'Regenerate',\r\n bgSeedLocked: 'Seeded · stable on refresh',\r\n bgSeedUnlocked: 'Unseeded · new on refresh',\r\n seedLock: 'Lock seed',\r\n bgMeshScale: 'Spread',\r\n bgMeshIntensity: 'Intensity',\r\n bgShaderPreset: 'Preset',\r\n bgShaderSpeed: 'Flow speed',\r\n bgShaderScale: 'Texture scale',\r\n bgPatternPreset: 'Pattern',\r\n bgPatternDensity: 'Density',\r\n bgPatternScale: 'Scale',\r\n presetAurora: 'Aurora',\r\n presetNebula: 'Nebula',\r\n presetNoise: 'Flowing noise',\r\n presetDots: 'Dots',\r\n presetWaves: 'Waves',\r\n presetPoly: 'Low poly',\r\n presetStarfield: 'Starfield',\r\n presetRain: 'Rain',\r\n presetContour: 'Contours',\r\n presetMeta: 'Fluid orbs',\r\n bgPause: 'Pause',\r\n bgResume: 'Play',\r\n bgUrlVideoFail: 'Could not fetch the video — make sure the link downloads a video file directly',\r\n schemeTitle: 'Interface scheme',\r\n schemeLight: 'Light',\r\n schemeDark: 'Dark',\r\n schemeAuto: 'Auto',\r\n schemeHint: '\"Auto\" follows the background brightness first (accent lightness as fallback only); forcing light/dark regenerates the palette in that direction - with no accent picked, a neutral gray palette is used',\r\n presetGalleryTitle: 'Appearance presets',\r\n presetName_default: 'Default',\r\n presetDesc_default: 'Restore the plugin\\'s original look',\r\n presetName_glass: 'Frosted glass',\r\n presetDesc_glass: 'Translucent surfaces + frosted depth',\r\n presetName_minimal: 'Minimal',\r\n presetDesc_minimal: 'Near-solid surfaces, no frost',\r\n presetName_midnight: 'Midnight',\r\n presetDesc_midnight: 'Deep violet accent, heavy frost',\r\n presetName_cyber: 'Cyber',\r\n presetDesc_cyber: 'Vivid magenta, vanishing surfaces',\r\n presetName_warm: 'Warm daylight',\r\n presetDesc_warm: 'Amber accent on solid light surfaces',\r\n presetApplied: 'Preset applied',\r\n profilesTitle: 'Saved profiles',\r\n profileSave: 'Save current',\r\n profileNamePlaceholder: 'Profile name…',\r\n profileNameRequired: 'Enter a name first',\r\n profileSaved: 'Profile saved',\r\n profileApplied: 'Profile applied',\r\n profileApply: 'Apply',\r\n profileDelete: 'Delete profile',\r\n profileDeleteConfirm: 'Sure?',\r\n profileNone: 'None',\r\n profilesEmpty: 'No saved profiles yet. Tune the look, then hit \"Save current\" to switch back anytime.',\r\n scheduleTitle: 'Day/night auto switch',\r\n scheduleHint: 'Automatically swap between two saved profiles by clock time or the OS dark mode (colors and surfaces switch; the wallpaper stays)',\r\n scheduleMode: 'Trigger',\r\n scheduleModeTime: 'Fixed times',\r\n scheduleModeSystem: 'Follow system',\r\n scheduleTimes: 'Switch times',\r\n scheduleDayStart: 'Day starts',\r\n scheduleNightStart: 'Night starts',\r\n scheduleProfiles: 'Profiles',\r\n scheduleDayProfile: 'Day',\r\n scheduleNightProfile: 'Night',\r\n rotTitle: 'Wallpaper rotation',\r\n rotHint: 'Add images to a rotation pool and let the wallpaper change on your cadence; takes effect immediately when enabled',\r\n rotAdd: 'Add images',\r\n rotRemove: 'Remove',\r\n rotShuffle: 'Shuffle',\r\n rotOrder: 'In order',\r\n rotReload: 'Every refresh',\r\n rotDaily: 'Daily',\r\n rotWeekly: 'Weekly',\r\n rotNow: 'Switch now',\r\n}\r\n","import type { BgState, ThemeConfig, PartOpacities, PartBlurs, PartStrokes, StrokeConfig, BgMode, ProfileEntry, RotationConfig, RotationItem, ScheduleConfig, SchemeOverride, ProfileAppearance } from './types'\r\n\r\nexport const DEFAULT_CONFIG: ThemeConfig = {\r\n color: null,\r\n // Defaults sit at mid-scale rather than at \"no visible change\" (was 0.85 /\r\n // 0.93 / 1 / 1 with every blur at 0): a fresh install then shows right away\r\n // that the controls are live, instead of looking inert until each slider is\r\n // dragged once. Only affects installs with no persisted config.\r\n // The main background is the deliberate exception: with no persisted config it\r\n // now paints nothing over the wallpaper (opacity 0) and frosts nothing (blur 0),\r\n // so a first launch shows the picture as uploaded.\r\n opacities: { bg: 0, sidebar: 0.5, card: 0.5, input: 0.5 },\r\n // Blur sliders are px-based (0–60), so 50% of their range is 30px — except the\r\n // bg pair above and below, which start untouched.\r\n blurs: { bg: 0, sidebar: 30, card: 30, settings: 30, chat: 30, trajectory: 30, input: 30, panel: 30, produced: 30, header: 30, headerBar: 30 },\r\n strokes: {\r\n bg: { width: 0, color: 'auto', customColor: '#808080' },\r\n sidebar: { width: 0, color: 'auto', customColor: '#808080' },\r\n card: { width: 0, color: 'auto', customColor: '#808080' },\r\n settings: { width: 0, color: 'auto', customColor: '#808080' },\r\n chat: { width: 0, color: 'auto', customColor: '#808080' },\r\n trajectory: { width: 0, color: 'auto', customColor: '#808080' },\r\n input: { width: 0, color: 'auto', customColor: '#808080' },\r\n panel: { width: 0, color: 'auto', customColor: '#808080' },\r\n produced: { width: 0, color: 'auto', customColor: '#808080' },\r\n header: { width: 0, color: 'auto', customColor: '#808080' },\r\n headerBar: { width: 0, color: 'auto', customColor: '#808080' },\r\n },\r\n settingsOpacity: 0.5,\r\n // 100% = the background picture untouched. Deliberately NOT part of the\r\n // 50% default batch: halving the wallpaper's own alpha would wash out a\r\n // freshly uploaded picture — the other surface sliders above are mid-scale,\r\n // this one stays opaque.\r\n wallpaperOpacity: 1,\r\n // The 背景 page's own wallpaper blur, 0 for the same reason: a first install\r\n // shows the wallpaper exactly as uploaded.\r\n blur: 0,\r\n bgState: { zoom: 1, x: 0, y: 0, iw: 0, ih: 0 },\r\n videoBgState: { zoom: 1, x: 0, y: 0, iw: 0, ih: 0 },\r\n backgroundType: 'image',\r\n bgMode: 'fit',\r\n videoMime: null,\r\n fontMime: null,\r\n fontEnabled: true,\r\n generatedBg: null,\r\n regenerateOnReload: false,\r\n chatTextOpacity: 0.5,\r\n // 100% = untouched host surface; these all default to mid-scale too.\r\n trajectoryOpacity: 0.5,\r\n panelOpacity: 0.5,\r\n producedOpacity: 0.5,\r\n headerOpacity: 0.5,\r\n headerBarOpacity: 0.5,\r\n profiles: [],\r\n rotation: { enabled: false, mode: 'shuffle', interval: 'daily', current: 0, items: [], lastRotate: null },\r\n schedule: { enabled: false, mode: 'time', dayProfile: null, nightProfile: null, dayStart: '07:00', nightStart: '19:00' },\r\n schemeOverride: 'auto',\r\n activeProfile: null,\r\n}\r\n\r\nconst clamp01 = (n: unknown, def: number): number =>\r\n typeof n === 'number' ? Math.min(1, Math.max(0, n)) : def\r\n\r\n// In-memory mirror of the file-backed store; the UI reads and mutates this,\r\n// and it is synced to disk via the RPC layer.\r\nexport let cfg: ThemeConfig = { ...DEFAULT_CONFIG, opacities: { ...DEFAULT_CONFIG.opacities }, blurs: { ...DEFAULT_CONFIG.blurs }, strokes: structuredClone(DEFAULT_CONFIG.strokes), bgState: { ...DEFAULT_CONFIG.bgState }, videoBgState: { ...DEFAULT_CONFIG.videoBgState } }\r\nexport let wpImageUrl: string | null = null\r\n// Retained across background-type switches so coming back to image/video\r\n// restores the original upload.\r\nexport let wpUrl: string | null = null\r\nexport let wpVideoUrl: string | null = null\r\n/** Captured video frame standing in for previews/color extraction (still-image APIs). */\r\nexport let wpVideoSnapshot: string | null = null\r\n/** Local blob URL backing an in-session video; revoked when replaced or cleared. */\r\nlet wpVideoObjectUrl: string | null = null\r\n\r\nexport function setWpUrl(url: string | null): void { wpUrl = url }\r\n// The serve URL is stable across in-place replacements (upload / URL download /\r\n// rotation), so every swap needs a query-string cache-buster or the URL-keyed\r\n// caches — the layer re-set guard, loadImage decode cache, brightness verdict,\r\n// low-res drag copy, intrinsic-size lookup — all keep the old pixels.\r\nlet imageRev = 0\r\nexport function bumpImageRev(url: string | null): string | null {\r\n if (url === null) return url\r\n // The serve URL is a same-origin relative path (/dsh-any-background/…); the\r\n // rev query must reach those too, or an in-place replacement keeps the same\r\n // backgroundImage string and applyImageWp skips the swap. blob:/data: stay\r\n // intact (a query can break blob resolution).\r\n if (!/^https?:\\/\\//i.test(url) && !url.startsWith('/')) return url\r\n imageRev++\r\n return `${url}${url.includes('?') ? '&' : '?'}r=${imageRev}`\r\n}\r\nexport function setWpImageUrl(url: string | null): void { wpImageUrl = bumpImageRev(url) }\r\n// The serve URL is stable, so replacing the stored video needs a query-string\r\n// cache-buster or the player keeps the cached copy.\r\nlet videoRev = 0\r\nexport function setWpVideoUrl(url: string | null, mime: string | null): void {\r\n if (url === null) {\r\n wpVideoUrl = null\r\n wpVideoSnapshot = null\r\n } else {\r\n videoRev++\r\n // Blob URLs are unique per object; a query string can break their\r\n // resolution in some engines, so they skip the cache-buster.\r\n wpVideoUrl = url.startsWith('blob:') ? url : `${url}${url.includes('?') ? '&' : '?'}r=${videoRev}`\r\n }\r\n // Release the previous in-session object URL when replaced or cleared.\r\n if (wpVideoObjectUrl !== null && wpVideoObjectUrl !== url) {\r\n URL.revokeObjectURL(wpVideoObjectUrl)\r\n wpVideoObjectUrl = null\r\n }\r\n if (url !== null && url.startsWith('blob:')) wpVideoObjectUrl = url\r\n cfg.videoMime = url ? mime : null\r\n}\r\nexport function setWpVideoSnapshot(url: string | null): void { wpVideoSnapshot = url }\r\n\r\n/** Release the in-session video object URL (plugin teardown). */\r\nexport function disposeVideoObjectUrl(): void {\r\n if (wpVideoObjectUrl !== null) {\r\n URL.revokeObjectURL(wpVideoObjectUrl)\r\n wpVideoObjectUrl = null\r\n }\r\n}\r\nexport function setBgState(s: BgState): void { cfg.bgState = s }\r\n\r\n// Brightness verdict of the active generated background, analyzed once per\r\n// switch from a captured frame. null = fall back to the picked color's lightness.\r\nexport let bgDark: boolean | null = null\r\nexport function setBgDark(v: boolean | null): void { bgDark = v }\r\nexport function rBgDark(): boolean | null { return bgDark }\r\n\r\nexport function rHasColor(): boolean { return cfg.color !== null }\r\nexport function rColor(): [number, number, number] { return cfg.color ?? [220, 0.55, 0.25] }\r\nexport function rWpImage(): string | null { return wpImageUrl }\r\nexport function rWpVideo(): string | null { return wpVideoUrl }\r\nexport function rBgMode(): BgMode { return cfg.bgMode ?? DEFAULT_CONFIG.bgMode }\r\nexport function rChatTextOpacity(): number { return clamp01(cfg.chatTextOpacity, DEFAULT_CONFIG.chatTextOpacity) }\r\nexport function rTrajectoryOpacity(): number { return clamp01(cfg.trajectoryOpacity, DEFAULT_CONFIG.trajectoryOpacity) }\r\n/** Display URL: the uploaded image/video snapshot per active type, else the generated snapshot. */\r\nexport function rWp(): string | null {\r\n if (cfg.backgroundType === 'image') return wpImageUrl\r\n if (cfg.backgroundType === 'video') return wpVideoSnapshot\r\n return wpUrl\r\n}\r\nexport function rOps(): PartOpacities {\r\n const o = cfg.opacities ?? {}\r\n const out = {} as PartOpacities\r\n for (const k of ['bg', 'sidebar', 'card', 'input'] as const) {\r\n out[k] = clamp01(o[k], DEFAULT_CONFIG.opacities[k])\r\n }\r\n return out\r\n}\r\nexport function rBlurs(): PartBlurs {\r\n const b = cfg.blurs ?? {}\r\n const out = {} as PartBlurs\r\n for (const k of ['bg', 'sidebar', 'card', 'settings', 'chat', 'trajectory', 'input', 'panel', 'produced', 'header', 'headerBar'] as const) {\r\n const v = b[k]\r\n out[k] = typeof v === 'number' ? Math.min(60, Math.max(0, v)) : DEFAULT_CONFIG.blurs[k]\r\n }\r\n return out\r\n}\r\n\r\nconst STROKE_GROUPS = ['bg', 'sidebar', 'card', 'settings', 'chat', 'trajectory', 'input', 'panel', 'produced', 'header', 'headerBar'] as const\r\nconst STROKE_COLOR_KEYS = ['auto', 'gray', 'black', 'white', 'theme', 'custom'] as const\r\nconst HEX_RE = /^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/\r\nconst DEFAULT_STROKE: StrokeConfig = { width: 0, color: 'auto', customColor: '#808080' }\r\n\r\nfunction adoptStroke(raw: unknown): StrokeConfig {\r\n const s = (raw ?? {}) as Partial<StrokeConfig>\r\n return {\r\n width: typeof s.width === 'number' && isFinite(s.width) ? Math.min(4, Math.max(0, s.width)) : DEFAULT_STROKE.width,\r\n color: STROKE_COLOR_KEYS.includes(s.color as StrokeConfig['color']) ? s.color as StrokeConfig['color'] : DEFAULT_STROKE.color,\r\n customColor: typeof s.customColor === 'string' && HEX_RE.test(s.customColor) ? s.customColor : DEFAULT_STROKE.customColor,\r\n }\r\n}\r\n\r\n/** Move a possibly-partial strokes map into the full shape the UI reads. */\r\nfunction strokesFrom(raw: unknown): PartStrokes {\r\n const s = (raw ?? {}) as Partial<PartStrokes>\r\n const out = {} as PartStrokes\r\n for (const k of STROKE_GROUPS) out[k] = adoptStroke(s[k])\r\n return out\r\n}\r\n\r\nexport function rStrokes(): PartStrokes {\r\n return strokesFrom(cfg.strokes)\r\n}\r\nexport function rWop(): number { return clamp01(cfg.wallpaperOpacity, DEFAULT_CONFIG.wallpaperOpacity) }\r\nexport function rBl(): number {\r\n return typeof cfg.blur === 'number' ? Math.min(60, Math.max(0, cfg.blur)) : DEFAULT_CONFIG.blur\r\n}\r\nexport function rSop(): number { return clamp01(cfg.settingsOpacity, DEFAULT_CONFIG.settingsOpacity) }\r\nexport function rPanelOpacity(): number { return clamp01(cfg.panelOpacity, DEFAULT_CONFIG.panelOpacity) }\r\nexport function rProducedOpacity(): number { return clamp01(cfg.producedOpacity, DEFAULT_CONFIG.producedOpacity) }\r\nexport function rHeaderOpacity(): number { return clamp01(cfg.headerOpacity, DEFAULT_CONFIG.headerOpacity) }\r\nexport function rHeaderBarOpacity(): number { return clamp01(cfg.headerBarOpacity, DEFAULT_CONFIG.headerBarOpacity) }\r\nexport function rBgState(): BgState { return cfg.bgState }\r\nexport function rVideoBgState(): BgState { return cfg.videoBgState }\r\n\r\n// ── Profiles / rotation / schedule / scheme ──────────────────────────────────\r\nexport function rProfiles(): ProfileEntry[] { return Array.isArray(cfg.profiles) ? cfg.profiles : [] }\r\nexport function rRotation(): RotationConfig {\r\n const r = cfg.rotation\r\n return r && typeof r === 'object'\r\n ? { ...DEFAULT_CONFIG.rotation, ...r, items: Array.isArray(r.items) ? r.items : [] }\r\n : { ...DEFAULT_CONFIG.rotation, items: [] }\r\n}\r\nexport function rSchedule(): ScheduleConfig {\r\n return cfg.schedule && typeof cfg.schedule === 'object' ? { ...DEFAULT_CONFIG.schedule, ...cfg.schedule } : { ...DEFAULT_CONFIG.schedule }\r\n}\r\nexport function rSchemeOverride(): SchemeOverride {\r\n return cfg.schemeOverride === 'light' || cfg.schemeOverride === 'dark' ? cfg.schemeOverride : 'auto'\r\n}\r\nexport function rActiveProfile(): string | null { return cfg.activeProfile }\r\n\r\n/** Effective interface scheme (drives data-ds-dark-theme / color-scheme): a\r\n * forced override wins; in auto a picked color decides through its palette\r\n * direction (keeps native controls aligned with the drawn surfaces), and\r\n * without a pick the background's brightness verdict does. Stay light as the\r\n * last fallback. */\r\nexport function rScheme(): 'light' | 'dark' {\r\n const o = rSchemeOverride()\r\n if (o !== 'auto') return o\r\n if (rHasColor()) return rColorScheme()\r\n return rBgDark() ? 'dark' : 'light'\r\n}\r\n\r\n/** Direction the color palette itself is built in: a forced override wins; in\r\n * auto the theme color's own lightness decides (0.2.4 behavior) so surfaces\r\n * always contrast with the palette's label fonts — the wallpaper verdict must\r\n * not drag a dark color's surfaces into a light build (and vice versa) or\r\n * text and surfaces converge. */\r\nexport function rColorScheme(): 'light' | 'dark' {\r\n const o = rSchemeOverride()\r\n if (o !== 'auto') return o\r\n return rHasColor() && rColor()[2] < 0.55 ? 'dark' : 'light'\r\n}\r\n\r\n/** Snapshot of the appearance fields a profile/preset restores. */\r\nexport function currentAppearance(): ProfileAppearance {\r\n return {\r\n color: cfg.color,\r\n opacities: { ...rOps() },\r\n blurs: { ...rBlurs() },\r\n strokes: rStrokes(),\r\n settingsOpacity: rSop(),\r\n wallpaperOpacity: rWop(),\r\n blur: rBl(),\r\n chatTextOpacity: rChatTextOpacity(),\r\n trajectoryOpacity: rTrajectoryOpacity(),\r\n panelOpacity: rPanelOpacity(),\r\n producedOpacity: rProducedOpacity(),\r\n headerOpacity: rHeaderOpacity(),\r\n headerBarOpacity: rHeaderBarOpacity(),\r\n }\r\n}\r\n\r\n/** Apply an appearance snapshot onto cfg (meta fields untouched). */\r\nexport function applyAppearance(ap: ProfileAppearance): void {\r\n cfg.color = Array.isArray(ap.color) && ap.color.length === 3 ? [...ap.color] as [number, number, number] : null\r\n cfg.opacities = { ...DEFAULT_CONFIG.opacities, ...(ap.opacities ?? {}) }\r\n cfg.blurs = { ...DEFAULT_CONFIG.blurs, ...(ap.blurs ?? {}) }\r\n cfg.strokes = strokesFrom(ap.strokes)\r\n cfg.settingsOpacity = clamp01(ap.settingsOpacity, DEFAULT_CONFIG.settingsOpacity)\r\n cfg.wallpaperOpacity = clamp01(ap.wallpaperOpacity, DEFAULT_CONFIG.wallpaperOpacity)\r\n cfg.blur = typeof ap.blur === 'number' ? Math.min(60, Math.max(0, ap.blur)) : DEFAULT_CONFIG.blur\r\n cfg.chatTextOpacity = clamp01(ap.chatTextOpacity, DEFAULT_CONFIG.chatTextOpacity)\r\n cfg.trajectoryOpacity = clamp01(ap.trajectoryOpacity, DEFAULT_CONFIG.trajectoryOpacity)\r\n cfg.panelOpacity = clamp01(ap.panelOpacity, DEFAULT_CONFIG.panelOpacity)\r\n cfg.producedOpacity = clamp01(ap.producedOpacity, DEFAULT_CONFIG.producedOpacity)\r\n cfg.headerOpacity = clamp01(ap.headerOpacity, DEFAULT_CONFIG.headerOpacity)\r\n cfg.headerBarOpacity = clamp01(ap.headerBarOpacity, DEFAULT_CONFIG.headerBarOpacity)\r\n}\r\n\r\nconst num = (n: unknown, def: number): number => typeof n === 'number' ? n : def\r\nconst cl = (n: unknown, lo: number, hi: number, def: number): number =>\r\n typeof n === 'number' ? Math.min(hi, Math.max(lo, n)) : def\r\n\r\nconst HHMM_RE = /^([01]\\d|2[0-3]):[0-5]\\d$/\r\n\r\nfunction adoptProfiles(raw: unknown): ProfileEntry[] {\r\n if (!Array.isArray(raw)) return []\r\n const out: ProfileEntry[] = []\r\n for (const item of raw.slice(0, 20)) {\r\n const p = (item ?? {}) as Partial<ProfileEntry>\r\n if (typeof p.id !== 'string' || p.id.length === 0 || p.id.length > 64) continue\r\n if (out.some(e => e.id === p.id)) continue\r\n const ac = (p.config ?? {}) as Partial<ProfileAppearance>\r\n out.push({\r\n id: p.id,\r\n name: typeof p.name === 'string' && p.name.trim() ? p.name.slice(0, 60) : 'Profile',\r\n createdAt: typeof p.createdAt === 'string' ? p.createdAt : '',\r\n config: {\r\n color: Array.isArray(ac.color) && ac.color.length === 3 ? [...ac.color] as [number, number, number] : null,\r\n opacities: { ...DEFAULT_CONFIG.opacities, ...(ac.opacities ?? {}) },\r\n blurs: { ...DEFAULT_CONFIG.blurs, ...(ac.blurs ?? {}) },\r\n strokes: strokesFrom(ac.strokes),\r\n settingsOpacity: clamp01(ac.settingsOpacity, DEFAULT_CONFIG.settingsOpacity),\r\n wallpaperOpacity: clamp01(ac.wallpaperOpacity, DEFAULT_CONFIG.wallpaperOpacity),\r\n blur: num(ac.blur, DEFAULT_CONFIG.blur),\r\n chatTextOpacity: clamp01(ac.chatTextOpacity, DEFAULT_CONFIG.chatTextOpacity),\r\n trajectoryOpacity: clamp01(ac.trajectoryOpacity, DEFAULT_CONFIG.trajectoryOpacity),\r\n panelOpacity: clamp01(ac.panelOpacity, DEFAULT_CONFIG.panelOpacity),\r\n producedOpacity: clamp01(ac.producedOpacity, DEFAULT_CONFIG.producedOpacity),\r\n headerOpacity: clamp01(ac.headerOpacity, DEFAULT_CONFIG.headerOpacity),\r\n headerBarOpacity: clamp01(ac.headerBarOpacity, DEFAULT_CONFIG.headerBarOpacity),\r\n },\r\n })\r\n }\r\n return out\r\n}\r\n\r\nfunction adoptRotation(raw: unknown): RotationConfig {\r\n const r = (raw ?? {}) as Partial<RotationConfig>\r\n const items: RotationItem[] = Array.isArray(r.items)\r\n ? r.items\r\n .filter((it): it is RotationItem => {\r\n const i = (it ?? {}) as Partial<RotationItem>\r\n return typeof i?.file === 'string' && /^[\\w-]+\\.(jpg|jpeg|png|gif|webp)$/i.test(i.file)\r\n })\r\n .slice(0, 30)\r\n .map(it => ({ file: it.file, thumb: typeof it.thumb === 'string' && it.thumb.startsWith('data:image/') && it.thumb.length <= 65536 ? it.thumb : '' }))\r\n : []\r\n return {\r\n enabled: r.enabled === true,\r\n mode: r.mode === 'order' ? 'order' : 'shuffle',\r\n interval: r.interval === 'reload' || r.interval === 'weekly' ? r.interval : 'daily',\r\n current: num(r.current, 0),\r\n items,\r\n lastRotate: typeof r.lastRotate === 'string' ? r.lastRotate : null,\r\n }\r\n}\r\n\r\nfunction adoptSchedule(raw: unknown): ScheduleConfig {\r\n const r = (raw ?? {}) as Partial<ScheduleConfig>\r\n return {\r\n enabled: r.enabled === true,\r\n mode: r.mode === 'system' ? 'system' : 'time',\r\n dayProfile: typeof r.dayProfile === 'string' ? r.dayProfile : null,\r\n nightProfile: typeof r.nightProfile === 'string' ? r.nightProfile : null,\r\n dayStart: typeof r.dayStart === 'string' && HHMM_RE.test(r.dayStart) ? r.dayStart : DEFAULT_CONFIG.schedule.dayStart,\r\n nightStart: typeof r.nightStart === 'string' && HHMM_RE.test(r.nightStart) ? r.nightStart : DEFAULT_CONFIG.schedule.nightStart,\r\n }\r\n}\r\n\r\nfunction adoptBgState(s: Partial<BgState>): BgState {\r\n return {\r\n zoom: num(s.zoom, 1),\r\n x: num(s.x, 0),\r\n y: num(s.y, 0),\r\n iw: typeof s.iw === 'number' && s.iw > 0 ? s.iw : 0,\r\n ih: typeof s.ih === 'number' && s.ih > 0 ? s.ih : 0,\r\n }\r\n}\r\n\r\n/** Move a possibly-absent partial config into the shape the UI reads. */\r\nexport function adoptConfig(raw: unknown): void {\r\n const c = (raw ?? {}) as Partial<ThemeConfig> & { opacity?: unknown }\r\n const color = Array.isArray(c.color) && c.color.length === 3\r\n ? [c.color[0], c.color[1], c.color[2]] as [number, number, number]\r\n : null\r\n // Migration: the old single main-interface opacity becomes per-part, keeping\r\n // the sidebar's former +0.08 offset.\r\n const legacy = typeof c.opacity === 'number' ? c.opacity : null\r\n const ops = (c.opacities ?? {}) as Partial<PartOpacities>\r\n const bl = (c.blurs ?? {}) as Partial<PartBlurs>\r\n const blurs = {} as PartBlurs\r\n for (const k of ['bg', 'sidebar', 'card', 'settings', 'chat', 'trajectory', 'input', 'panel', 'produced', 'header', 'headerBar'] as const) {\r\n blurs[k] = num(bl[k], DEFAULT_CONFIG.blurs[k])\r\n }\r\n const bgType = ['video', 'mesh', 'shader', 'pattern'].includes(c.backgroundType as string)\r\n ? (c.backgroundType as ThemeConfig['backgroundType'])\r\n : DEFAULT_CONFIG.backgroundType\r\n const bgMode = (['fit', 'fill', 'stretch', 'tile', 'center'] as BgMode[]).includes(c.bgMode as BgMode) ? (c.bgMode as BgMode) : DEFAULT_CONFIG.bgMode\r\n const gen = c.generatedBg && typeof c.generatedBg === 'object'\r\n ? (c.generatedBg as { type?: string })\r\n : null\r\n const generatedBg = gen && gen.type === bgType ? (c.generatedBg as ThemeConfig['generatedBg']) : null\r\n\r\n cfg = {\r\n color,\r\n opacities: {\r\n bg: num(ops.bg, legacy ?? DEFAULT_CONFIG.opacities.bg),\r\n sidebar: num(ops.sidebar, legacy !== null ? Math.min(1, legacy + 0.08) : DEFAULT_CONFIG.opacities.sidebar),\r\n card: num(ops.card, DEFAULT_CONFIG.opacities.card),\r\n input: num(ops.input, DEFAULT_CONFIG.opacities.input),\r\n },\r\n blurs,\r\n strokes: strokesFrom(c.strokes),\r\n settingsOpacity: num(c.settingsOpacity, DEFAULT_CONFIG.settingsOpacity),\r\n wallpaperOpacity: num(c.wallpaperOpacity, DEFAULT_CONFIG.wallpaperOpacity),\r\n blur: num(c.blur, DEFAULT_CONFIG.blur),\r\n bgState: adoptBgState((c.bgState ?? {}) as Partial<BgState>),\r\n videoBgState: adoptBgState((c.videoBgState ?? {}) as Partial<BgState>),\r\n backgroundType: bgType,\r\n bgMode,\r\n videoMime: typeof c.videoMime === 'string' ? c.videoMime : null,\r\n fontMime: typeof c.fontMime === 'string' ? c.fontMime : null,\r\n fontEnabled: typeof c.fontEnabled === 'boolean' ? c.fontEnabled : DEFAULT_CONFIG.fontEnabled,\r\n generatedBg: generatedBg ? normalizeGeneratedBg(generatedBg) : null,\r\n regenerateOnReload: typeof c.regenerateOnReload === 'boolean' ? c.regenerateOnReload : DEFAULT_CONFIG.regenerateOnReload,\r\n chatTextOpacity: clamp01(c.chatTextOpacity, DEFAULT_CONFIG.chatTextOpacity),\r\n trajectoryOpacity: clamp01(c.trajectoryOpacity, DEFAULT_CONFIG.trajectoryOpacity),\r\n panelOpacity: clamp01(c.panelOpacity, DEFAULT_CONFIG.panelOpacity),\r\n producedOpacity: clamp01(c.producedOpacity, DEFAULT_CONFIG.producedOpacity),\r\n headerOpacity: clamp01(c.headerOpacity, DEFAULT_CONFIG.headerOpacity),\r\n headerBarOpacity: clamp01(c.headerBarOpacity, DEFAULT_CONFIG.headerBarOpacity),\r\n profiles: adoptProfiles(c.profiles),\r\n rotation: adoptRotation(c.rotation),\r\n schedule: adoptSchedule(c.schedule),\r\n schemeOverride: c.schemeOverride === 'light' || c.schemeOverride === 'dark' ? c.schemeOverride : 'auto',\r\n activeProfile: typeof c.activeProfile === 'string' ? c.activeProfile : null,\r\n }\r\n}\r\n\r\nfunction normalizeGeneratedBg(p: ThemeConfig['generatedBg']): ThemeConfig['generatedBg'] {\r\n if (!p) return null\r\n if (p.type === 'mesh') {\r\n return {\r\n type: 'mesh',\r\n seed: num(p.seed, 0),\r\n scale: cl(p.scale, 0.3, 3, 1),\r\n intensity: cl(p.intensity, 0, 1, 0.6),\r\n }\r\n }\r\n if (p.type === 'shader') {\r\n return {\r\n type: 'shader',\r\n preset: ['aurora', 'nebula', 'noise', 'starfield'].includes(p.preset) ? p.preset : 'aurora',\r\n speed: cl(p.speed, 0, 2, 0.3),\r\n scale: cl(p.scale, 0.3, 3, 1),\r\n seed: typeof p.seed === 'number' ? Math.floor(p.seed) : 0,\r\n }\r\n }\r\n return {\r\n type: 'pattern',\r\n preset: ['dots', 'waves', 'poly', 'rain', 'contour', 'meta'].includes(p.preset) ? p.preset : 'dots',\r\n density: cl(p.density, 0, 1, 0.5),\r\n scale: cl(p.scale, 0.3, 3, 1),\r\n seed: typeof p.seed === 'number' ? Math.floor(p.seed) : 0,\r\n }\r\n}\r\n","/**\n * Single source of truth for what a DSH release IS, and which adapter answers\n * for a release the plugin has never seen.\n *\n * Shared by both halves of the plugin: the node half resolves the release from\n * disk (see `detect.ts`) and ships the verdict to the client half, which uses it\n * to pick a per-version adapter (see `client/host-compat/versions/`). Keeping the\n * bucketing here means the two halves can never disagree about what `0.1.6-alpha`\n * means — a drifted matcher on one side would silently hand the client a channel\n * the client's registry has no adapter for.\n *\n * @module\n */\n\n/** Adapter channels the plugin ships an adapter for: a patch line plus its\n * prerelease channel, so `0.1.5-rc.2` and a hypothetical `0.1.5-beta.1` are NOT\n * the same answer. `unknown` is the \"could not determine the release\" bucket,\n * not a release.\n *\n * `0.1.7-alpha` and `0.1.7-rc` share a patch line but not an answer: the menu\n * paint moved to `MenuSurface`'s own layer at `0.1.7-rc.2`, which is a fact about\n * the host's CSS that no amount of \"same line\" reasoning carries over. A line is\n * only as unified as its verified facts.\n *\n * `0.2.0-rc.2` is keyed down to the BUILD because the line split against that\n * scheme: `0.2.0-rc.1` and `0.2.0-rc.2` are the same patch line AND the same\n * prerelease channel, yet rc.2 renamed the token a sticky menu group heading\n * paints from, so the rc.1 answer is no longer complete for it. When one channel\n * name cannot hold both halves of a line, the half that opened the new facts is\n * named for the build that opened them, and `classifyRelease`'s \"highest verified\n * row at or below the host\" hands every later `0.2.0-rc` (and `0.2.0` stable) to\n * it. */\nexport type HostChannel =\n | '0.1.5-rc'\n | '0.1.6-alpha'\n | '0.1.7-alpha'\n | '0.1.7-rc'\n | '0.2.0-rc'\n | '0.2.0-rc.2'\n | '0.2.1-alpha'\n | 'unknown'\n\n/** A known channel — one that has a real adapter. */\nexport type KnownChannel = Exclude<HostChannel, 'unknown'>\n\n/** A release the plugin verified an adapter against. Oldest first. */\nexport interface SupportedRelease {\n readonly channel: KnownChannel\n /** The build the folder's facts were checked against. It orders the table, so\n * bumping it is part of re-verifying an adapter against a newer build. */\n readonly release: string\n}\n\n/** What this plugin supports, in upgrade order. One row = one build whose facts\n * were checked; several rows may share a `channel` when a newer build was\n * verified as needing no change to that folder's adapter (as `0.1.7-rc.1` was) —\n * a row then reports `exact` instead of `line`, and no new folder appears.\n * Rows may ALSO share a patch line while carrying different channels, which is\n * how a line says \"the facts changed halfway through it\" (`0.1.7-alpha.2` and\n * `0.1.7-rc.1` speak for `0.1.7-alpha`, `0.1.7-rc.2` opens `0.1.7-rc`, and\n * `0.2.0-rc.2` opens a second answer on a line that had one — see the note on\n * `HostChannel` for why that row is keyed to the build).\n * Adding an ADAPTER means adding a channel plus a folder in\n * `client/host-compat/versions/`. */\nexport const SUPPORTED_RELEASES: readonly SupportedRelease[] = [\n { channel: '0.1.5-rc', release: '0.1.5-rc.2' },\n { channel: '0.1.6-alpha', release: '0.1.6-alpha.2' },\n { channel: '0.1.7-alpha', release: '0.1.7-alpha.2' },\n { channel: '0.1.7-alpha', release: '0.1.7-rc.1' },\n { channel: '0.1.7-rc', release: '0.1.7-rc.2' },\n { channel: '0.2.0-rc', release: '0.2.0-rc.1' },\n { channel: '0.2.0-rc.2', release: '0.2.0-rc.2' },\n { channel: '0.2.1-alpha', release: '0.2.1-alpha.1' },\n]\n\n/** How the chosen adapter relates to the release that was detected. Reported so a\n * guess never reads as a verified match:\n * · `exact` — the host is on a build this table was checked against.\n * · `line` — a different build of a VERIFIED patch line (`0.1.6-alpha.4`, or a\n * future `0.1.6` stable); same line, so the adapter normally holds.\n * · `nearest` — no verified line covers it, so the closest one is clamped to:\n * the newest above everything for a newer host, the oldest for an older one.\n * · `unresolved` — no release parsed at all; the DOM arbitrates. */\nexport type ChannelMatch = 'exact' | 'line' | 'nearest' | 'unresolved'\n\n/** The adapter to use, and how much trust that answer deserves. */\nexport interface HostVerdict {\n readonly channel: HostChannel\n readonly match: ChannelMatch\n}\n\n/** Resolved host facts, as they travel node → client over the `read` payload. */\nexport interface HostInfo {\n /** Full detected release string (`0.1.6-alpha.2`), or null when undetermined. */\n version: string | null\n /** Channel derived from `version`, used to pick an adapter. */\n channel: HostChannel\n}\n\nexport const UNKNOWN_HOST_INFO: HostInfo = { version: null, channel: 'unknown' }\n\n/** True when a string looks like a release version. A bare `~/.dsh` directory\n * basename does not, which is why the disk probe sanity-checks before trusting\n * a path segment. */\nconst VERSION_RE = /^\\d+\\.\\d+\\.\\d+(?:-[0-9A-Za-z.-]+)?$/\n\nexport function looksLikeVersion(value: string): boolean {\n return VERSION_RE.test(value)\n}\n\n/** A release broken into the parts that decide an adapter. `channel` is the FIRST\n * prerelease identifier (`rc` in `0.1.5-rc.3`, `alpha` in `0.1.7-alpha.1`) — that\n * is the half of the tag stating which development line the build belongs to;\n * `build` is only a counter within that line. */\ninterface Parsed {\n readonly core: readonly [number, number, number]\n readonly channel: string | null\n readonly build: number | null\n}\n\nconst PARSE_RE = /^(\\d+)\\.(\\d+)\\.(\\d+)(?:-([0-9A-Za-z.-]+))?$/\n\nfunction parse(version: string): Parsed | null {\n const m = PARSE_RE.exec(version)\n if (m === null) return null\n const parts = m[4] === undefined ? [] : m[4].split('.')\n const build = parts.length > 1 ? Number(parts[1]) : NaN\n return {\n core: [Number(m[1]), Number(m[2]), Number(m[3])],\n channel: parts.length > 0 ? parts[0]! : null,\n build: Number.isFinite(build) ? build : null,\n }\n}\n\n/** The table, parsed once: every row is a literal this file controls. */\nconst TABLE = SUPPORTED_RELEASES.map(row => ({ ...row, parsed: parse(row.release)! }))\n\nfunction cmpCore(a: readonly [number, number, number], b: readonly [number, number, number]): number {\n for (let i = 0; i < 3; i++) {\n if (a[i] !== b[i]) return a[i]! < b[i]! ? -1 : 1\n }\n return 0\n}\n\n/** Total order over releases, following the semver rule that a prerelease sorts\n * BELOW the release it precedes (`0.1.6-alpha.2 < 0.1.6`). */\nfunction cmp(a: Parsed, b: Parsed): number {\n const core = cmpCore(a.core, b.core)\n if (core !== 0) return core\n if (a.channel === null || b.channel === null) {\n if (a.channel === b.channel) return 0\n return a.channel === null ? 1 : -1\n }\n if (a.channel !== b.channel) return a.channel < b.channel ? -1 : 1\n const ab = a.build ?? 0\n const bb = b.build ?? 0\n return ab === bb ? 0 : ab < bb ? -1 : 1\n}\n\n/** Pick the adapter for a release, clamping to the nearest verified line when the\n * release is outside everything this plugin has seen.\n *\n * A release is matched by PATCH LINE before anything else: `0.1.6-alpha.4` and a\n * future `0.1.6` stable both belong to the line verified at `0.1.6-alpha.2`, and\n * handing them that adapter beats giving up — the DOM probes only cover panel\n * mechanics, not the surface decisions the line is known for.\n *\n * Outside every verified line the answer is a guess, so it is the closest one and\n * it says so (`nearest`): newer than the newest line → that newest adapter, older\n * than the oldest → the oldest, strictly between two → the LOWER one, because an\n * adapter may only claim what it was verified for. A release that will not parse\n * at all is `unknown`, and the DOM arbitrates there. */\nexport function classifyRelease(version: string | null): HostVerdict {\n const host = version === null ? null : parse(version)\n if (host === null) return { channel: 'unknown', match: 'unresolved' }\n\n const sameLine = TABLE.filter(row => cmpCore(row.parsed.core, host.core) === 0)\n if (sameLine.length > 0) {\n // `exact` names THE BUILD the row was checked against, not its channel: a\n // channel-only test would call `0.1.7-alpha.4` exact against a table verified\n // at `alpha.2`, and `line` exists precisely so an unverified build says so.\n const exact = sameLine.find(row => row.release === version)\n if (exact !== undefined) return { channel: exact.channel, match: 'exact' }\n // A patch line may carry several verified builds AND several channels, so take\n // the highest row at or below the host: an unverified newer build gets the\n // newest verification that precedes it, whichever folder that was\n // (`0.1.7-rc.3` → the `0.1.7-rc` facts checked at rc.2, not the alpha ones), and\n // one older than every row falls back to the line's first, since the folder's\n // facts were derived from that shape.\n const atOrBelow = sameLine.filter(row => cmp(row.parsed, host) <= 0)\n const chosen = atOrBelow.length > 0 ? atOrBelow[atOrBelow.length - 1]! : sameLine[0]!\n return { channel: chosen.channel, match: 'line' }\n }\n\n const older = TABLE.filter(row => cmp(row.parsed, host) < 0)\n if (older.length === 0) return { channel: TABLE[0]!.channel, match: 'nearest' }\n const newer = TABLE.filter(row => cmp(row.parsed, host) > 0)\n if (newer.length === 0) return { channel: TABLE[TABLE.length - 1]!.channel, match: 'nearest' }\n return { channel: older[older.length - 1]!.channel, match: 'nearest' }\n}\n\n/** The channel a release maps onto — the verdict's answer without the confidence. */\nexport function channelOf(version: string | null): HostChannel {\n return classifyRelease(version).channel\n}\n\n/** Prerelease tag of a release string (`alpha.2` in `0.1.6-alpha.2`), or null\n * when the version is bare/undetermined. Needed because a channel is coarser\n * than reality: `conversation.session.header.leading` ships in exactly one\n * build within the 0.1.6-alpha line. */\nexport function prereleaseOf(version: string | null): string | null {\n if (version === null) return null\n const m = /^\\d+\\.\\d+\\.\\d+-([0-9A-Za-z.-]+)$/.exec(version)\n return m?.[1] ?? null\n}\n","/**\n * Selector + declaration vocabulary shared by every per-version adapter.\n *\n * These are the ANCHORS, not the decisions. What varies between releases (which\n * element slides, whether the panel needs promoting, which header slot keys\n * exist) is answered in the version folders; what is stable across all of them\n * lives here so no adapter has to re-type a host selector and get it subtly wrong.\n *\n * Verified against the harness release tags (dsh-v0.1.5-rc.2 … dsh-v0.2.1-alpha.1),\n * not inferred:\n * · `[data-sidebar-right-panel]` — emitted by `ui-sidebar-right/shell/SidebarRight.tsx`\n * on every release in range, with values `push` | `fullscreen`.\n * · `[data-dockkit-host]` / `[data-dockkit-empty]` — emitted ONLY by\n * `ui-dockkit/components/TabLayout.tsx`, a file that first appears at\n * 0.1.7-alpha.1. Dockkit itself EXISTS earlier (its `TabMenu` carries\n * `[data-dockkit-tab-menu]` on every release), so only these two attributes\n * are the 0.1.7 marker — never test \"is dockkit installed\".\n * · `[data-dsh-bottom-panel]` — the optional dsh-better-sidebar workbench, not\n * a host element at all. It is a single element on every release, which is\n * why it needs no version arm.\n * · `[data-plugin-panel]` / `[data-plugin-scope] > ul` — emitted by\n * `ui-plugin-manager/src/client/PluginManagerPage.tsx`. That package is NEW AT\n * 0.1.6-alpha.2: `git ls-tree` shows it absent from 0.1.5-rc.2, 0.1.5-rc.3 and\n * 0.1.6-alpha.1, where the plugin list lived in `ui-settings-plugin-inventory`\n * under `[data-plugin-scope]` alone — no `[data-plugin-panel]`, and no card\n * `ul` in that group either. The three anchors this rule matches — `section\n * [data-plugin-panel]`, `section[data-plugin-scope] > ul.cards` and\n * `section[data-plugin-loading] > ul.cards` — are re-emitted unchanged at\n * `0.2.0-rc.2` and `0.2.1-alpha.1` (checked per tag in `PluginManagerPage.tsx`),\n * so the ONE rule below serves every tag that emits the page.\n *\n * @module\n */\n\nimport type { MenuSurfaceFacts } from './types'\n\n/** The host's own right Sidebar wrapper. */\nexport const PANEL_WRAPPER = '[data-sidebar-right-panel]'\n\n/** The same wrapper in its fullscreen state; the host raises its own z-index to 40. */\nexport const PANEL_FULLSCREEN = '[data-sidebar-right-panel=\"fullscreen\"]'\n\n/** The docked children a 0.1.7+ panel slides — the panel itself stays put. */\nexport const DOCKKIT_SLIDERS =\n '[data-sidebar-right-panel] [data-dockkit-host=\"dock\"],[data-sidebar-right-panel] [data-dockkit-empty]'\n\n/** The third-party workbench panel, one element on every release. Owned by the\n * PRODUCED slider (0.3.2): a conversation artifact that happens to open in a\n * panel, not a page column — so it fades and frosts with the produced surfaces. */\nexport const BETTER_SIDEBAR_PANEL = '[data-dsh-bottom-panel]'\n\n/** The cards that take the composer seat away from the input bar: approval\n * (`ui-approval`), plan review and the question composer (`ui-user-questions`).\n * They are siblings of `[data-composer-card]`, not its children — the seat\n * renders the elected takeover beside the fallback bar (verified per tag in\n * `ConversationContent.tsx` and both packages' `slots.inject('conversation.composer')`)\n * — and each paints the capsule's own `--dsw-specific-input-major`, from\n * `dsh-v0.1.5-rc.2` through `dsh-v0.2.1-alpha.1`.\n *\n * The marker sits on the wrapper, the fill on its child card:\n * `[data-approval-key] > div`, `[data-plan-review-key] > section`,\n * `[data-question-key] > section`.\n *\n * One more fact these three share, and it is the reason the input-frost\n * treatment for them lives in a runtime pass instead of a stylesheet rule:\n * NO release in range declares `position` on any of the three cards (checked\n * per tag — 0 hits for `position:` in `ApprovalPanel.module.css`,\n * `PlanReviewPanel.module.css` and `QuestionComposer.module.css`), so unlike\n * the fallback capsule — whose `.card` is `position:relative` on every tag —\n * the host does not hand the plugin a containing block to mount a\n * `z-index:-1` underlay on. Writing that `position` from the plugin's own\n * stylesheet turns the card's box into a cascade race with anything else that\n * positions it: a host build that caps the card with a percentage\n * `max-height` loses its absolute containing block the moment a plugin rule\n * wins that race, and the whole chain collapses — content outside the card,\n * buttons off the viewport (dsh-any-background issue #24). The consumer that\n * needs the containing block (`applyTakeoverFrost`) therefore probes each card\n * at runtime and only anchors a box whose computed position is `static`; see\n * `inputBlurRule`. */\nexport const COMPOSER_TAKEOVER_CARD =\n '[data-approval-key]>div,[data-plan-review-key]>section,[data-question-key]>section'\n\n/** The takeover cards' free-text answer field — only the question composer has\n * one (approval and plan review are button rows). Form controls do not inherit\n * text properties, so the stroke group needs the editor spelled out; appending\n * a suffix to `COMPOSER_TAKEOVER_CARD` would bind to its LAST arm only. */\nexport const COMPOSER_TAKEOVER_EDITOR = '[data-question-key]>section textarea'\n\n/** Every surface the panel opacity slider owns — the host's own right Sidebar.\n * Layout-neutral token re-scope. (The dsh-better-sidebar workbench used to be\n * listed here; it moved to the produced group, see `PRODUCED_RULE`.) */\nexport const PANEL_SURFACES = PANEL_WRAPPER\n\n/** DOM-shape test for \"this is NOT a 0.1.7-style frame\". Used ONLY by the\n * unresolved adapter, where the DOM is the authority because the release is not. */\nexport const WITHOUT_DOCKKIT_FRAME = ':not(:has([data-dockkit-host],[data-dockkit-empty]))'\n\n/** The panel blur declaration pair. Both prefixes because Safari needs the\n * `-webkit-` one and the cascade must not let them disagree. */\nexport function panelBlurRule(selectors: string): string {\n return `${selectors}{` +\n '-webkit-backdrop-filter:var(--dsh-any-blur-panel,none);' +\n 'backdrop-filter:var(--dsh-any-blur-panel,none)}'\n}\n\n/**\n * The plugin-manager page's frosted card block, for the releases that ship it.\n *\n * `设置 → 插件` lists each group's plugins in a `ul` that has NO surface of its\n * own — measured live on 0.1.7-alpha.1: a transparent flex column, 2px gaps, each\n * `li` transparent with a 12px radius. With the settings surfaces faded, the whole\n * table floats straight on the wallpaper. This frames each group's list the way the\n * composer capsule is framed: a rounded block on an `::before` underlay.\n *\n * Which releases emit the page decides who gets this string — see `pluginPageRule`\n * in each version folder.\n *\n * The card `ul` is matched through TWO scopes. `0.2.0-rc.1` added a first-read\n * `ListSkeleton` that reuses `.cards` under `section[data-plugin-loading]`, so a\n * rule keyed on `[data-plugin-scope]` alone would show the real list frosted and\n * the loading list bare, then re-frost the block when the data lands. Hosts before\n * that never emit the attribute, so the extra selector is inert rather than a\n * version branch.\n *\n * BINDING, and why it is not just \"put it in the dialog\": the block paints from\n * `--dsh-any-bg-settings-surface` and frosts from `--dsh-any-blur-settings`, i.e.\n * the settings-opacity / settings-blur pair. On 0.1.7 the page is a child of\n * `centerCol`, NOT of the settings dialog (and from `0.1.7-rc.2` the dialog is a\n * `createPortal` beside `#root`, so it is further away still), therefore\n * `SETTINGS_STYLE_RULE`'s token\n * re-scope never reaches it and the list would otherwise follow the homepage card\n * alpha; reading the plugin-owned variables off `:root` puts them under the slider\n * that owns this page. The `var(--dsw-alias-bg-layer-2)` fallback covers the window\n * before the first `applySettingsOverrides` write.\n *\n * The frost rides an underlay because backdrop-filter must never sit directly on a\n * host part (containing block + backdrop root), and the `isolation` is what keeps\n * the underlay's `z-index:-1` inside the block instead of escaping behind the frame.\n * The `:has([role=\"dialog\"])` valve matters here more than anywhere else: every row\n * carries a `plugins.item` slot that third-party plugins fill with their own\n * controls, so a dialog can legitimately open inside the list.\n */\nexport const PLUGIN_PAGE_FROST_RULE =\n '[data-plugin-panel] [data-plugin-scope]>ul,[data-plugin-panel] [data-plugin-loading]>ul{' +\n 'position:relative;isolation:isolate;padding:8px;border-radius:14px}' +\n '[data-plugin-panel] [data-plugin-scope]>ul:has([role=\"dialog\"]),' +\n '[data-plugin-panel] [data-plugin-loading]>ul:has([role=\"dialog\"]){isolation:auto}' +\n '[data-plugin-panel] [data-plugin-scope]>ul::before,' +\n '[data-plugin-panel] [data-plugin-loading]>ul::before{' +\n 'content:\"\";position:absolute;inset:0;z-index:-1;pointer-events:none;border-radius:inherit;' +\n 'background:var(--dsh-any-bg-settings-surface,var(--dsw-alias-bg-layer-2));' +\n '-webkit-backdrop-filter:var(--dsh-any-blur-settings,none);' +\n 'backdrop-filter:var(--dsh-any-blur-settings,none)}'\n\n/** The host's own `ui-theme` name for \"dropdowns, popovers, suggestion lists\", and\n * the token the plugin has always remapped onto the card slider. Whether it still\n * reaches a menu's paint is the question `MenuSurfaceFacts` below answers — from\n * `0.1.7-rc.2` the host aliases it AWAY from the menu layer, so declaring it alone\n * fades the non-`MenuSurface` overlays and nothing else. */\nexport const MENU_FILL_TOKEN = '--dsw-specific-menu'\n\n/** Frost by filtering the element itself — the only option where the element is the\n * thing that paints, and the shape every release up to `0.1.7-rc.1` presents. Both\n * prefixes because Safari needs the `-webkit-` one and the cascade must not let\n * them disagree. */\nexport function elementFrostDecl(value: string): string {\n return `-webkit-backdrop-filter:${value};backdrop-filter:${value}`\n}\n\n/**\n * ── Where a menu's paint lives ────────────────────────────────────────────────\n * Verified by reading the emitting source at each tag, not inferred from a changelog.\n *\n * `dsh-v0.1.5-rc.2` … `dsh-v0.1.7-rc.1`: the menu ELEMENT paints itself. Its own\n * CSS module declares `background:var(--dsw-specific-menu)` — 11 files at\n * 0.1.5-rc.2/rc.3 and 0.1.6-alpha.1/alpha.2, 15 at 0.1.7-alpha.1/alpha.2, 16 at\n * rc.1 (`Menu`, `MenuView`, `PopupSelectView`, `ModelSelect`, `dockkit` TabMenu,\n * `stat-dialog`, `QueueDock`, `ContextMeter`, `TodoPanel`, `GoalBar`,\n * `JobListAction`, `HoverCard`, `ScheduleCatalogAction`, `SubagentHeaderLineage`,\n * `TeamAction`, `CordisPanel`). One token therefore paints every menu, and\n * filtering the element is the arm that reaches it.\n * Frost is a separate, later fact, and worth recording because it changes what\n * the plugin is doing on the older tags: `--dsw-menu-backdrop-filter` has ZERO\n * consumers before `0.1.7-alpha.1` (15 there, 16 at rc.1). On `0.1.5`/`0.1.6` the\n * host frosts no menu at all, so the card/header blur sliders are the only reason\n * a menu has a frost there — which is why the declaration goes on the element\n * rather than into a host token the host does not read.\n *\n * `dsh-v0.1.7-rc.2` (npm `latest`) and `dsh-v0.2.0-rc.1`: `TabMenu`, `MenuView`,\n * `PopupSelectView`, `ModelSelect` and `Menu` all render through the new\n * `ui-primitives/src/MenuSurface.tsx` (byte-identical between the two tags),\n * which leaves the element unpainted and draws on a `z-index:-1` child instead\n * (`MenuSurface.module.css` `.material`: `background:var(--dsw-menu-surface-fill)`\n * + `backdrop-filter:var(--dsw-menu-backdrop-filter)`). The four menu stylesheets\n * that used to paint the old token (Menu/MenuView/PopupSelectView/dockkit TabMenu)\n * drop it at rc.2, which is why the painter count goes 16 → 14.\n * Two consequences, both measured from those files:\n * · the host FLIPPED ITS ALIAS — `design-platform.css` now declares\n * `--dsw-specific-menu:var(--dsw-menu-surface-fill)` where every earlier\n * release declared the reverse. So a plugin that retints only the old token\n * writes a value nothing on a menu any longer reads, and the card / header\n * opacity sliders go inert on exactly the surfaces they were built for.\n * · that child layer exists on purpose: its comment says filtering only the\n * background \"keeps nested menus and fixed overlays free of an ancestor\n * backdrop root\", and the surface sets `isolation:isolate`. Filtering the\n * element anyway installs the backdrop root the layer was written to avoid.\n * The frost therefore rides `--dsw-menu-backdrop-filter`, whose consumer set is\n * the same 14 stylesheets at both tags (stat dialog, queue dock, context meter,\n * todo panel, goal bar, job list, `HoverCard`, `PickerPopover`/`TaskMenu`/\n * `ScheduleCatalogAction`, the subagent lineage, `TeamAction`, `CordisPanel`,\n * `MenuSurface` itself) — re-declaring the token reaches the frost whoever ends up\n * applying it, and does not depend on any element being the painting element.\n *\n * `dsh-v0.2.0-rc.2` (npm `latest`) and `dsh-v0.2.1-alpha.1`: the layer and the frost\n * are the same files — `MenuSurface.tsx` and `MenuSurface.module.css` are\n * byte-identical to rc.1, and every `--dsw-menu-backdrop-filter` consumer is too —\n * but the sticky GROUP HEADING inside those menus changed owner. Through rc.1 the\n * only grouped menu was `ModelSelect`, whose own stylesheet painted that heading\n * from the menu token (`ModelSelect.module.css` `.groupTitle{position:sticky;\n * background:var(--dsw-specific-menu)}`), so the card slider drove it and a picked\n * wallpaper color tinted it. At rc.2 the rule is deleted and both grouped popups\n * (`ModelSelect`, `PopupSelectView`) render the new `ui-primitives/MenuGroup.tsx`,\n * whose heading stays transparent until `data-stuck` and then paints\n * `--dsw-alias-menu-group-header-fill` (light `rgba(248,249,250,.94)`, dark\n * `rgba(48,49,54,.94)`, declared in the `body` blocks of `design-platform.css`).\n * The surface did not go away — its token was RENAMED, and `ModelSelect.module.css`\n * is the one `--dsw-specific-menu` consumer that disappears at rc.2. Left alone, it\n * is the single menu element the fade no longer reaches: an untinted, near-opaque\n * band sitting on top of every row in the list the moment that list scrolls.\n */\n/** The answer for the releases whose menus paint themselves: `0.1.5-rc`,\n * `0.1.6-alpha`, `0.1.7-alpha`. The unresolved bucket is its own variant below. */\nexport const LEGACY_MENU_SURFACE: MenuSurfaceFacts = {\n fillTokens: [MENU_FILL_TOKEN],\n frostDecl: elementFrostDecl,\n}\n\n/** The answer for `0.1.7-rc` (`0.1.7-rc.2` onward) and `0.2.0-rc`. The old token\n * stays in the list on purpose: 14 surfaces in the same claim set still paint their\n * fill from it — the lineage tree, `CordisPanel`, the stat dialog, `QueueDock`,\n * `TodoPanel`, `ContextMeter`, `GoalBar`, `JobListAction`, `HoverCard`, `TeamAction`,\n * `ModelSelect`'s own card and the schedule trio (`PickerPopover`, `TaskMenu`,\n * `ScheduleCatalogAction`) — while the shared menus moved to\n * `--dsw-menu-surface-fill`. Dropping either name fades one half of that set. */\nexport const LAYERED_MENU_SURFACE: MenuSurfaceFacts = {\n fillTokens: [MENU_FILL_TOKEN, '--dsw-menu-surface-fill'],\n frostDecl: value => `--dsw-menu-backdrop-filter:${value}`,\n}\n\n/** The fill the sticky group heading of a shared menu paints from — `MenuGroup`'s\n * own contribution to the menu's look, first emitted at `0.2.0-rc.2`. */\nexport const MENU_GROUP_HEADER_FILL_TOKEN = '--dsw-alias-menu-group-header-fill'\n\n/** The answer for `0.2.0-rc` from `0.2.0-rc.2` and for `0.2.1-alpha`: everything\n * `LAYERED_MENU_SURFACE` says, plus the heading `MenuGroup` renamed.\n *\n * Riding `fillTokens` rather than being left out is a decision with evidence on\n * both sides, so state it: the host's README calls this token \"independent of the\n * menu material\" and gives it a 94% fill while the surface layer sits at 58%/45%.\n * That is a choice about an OPAQUE menu. This plugin's whole product is a menu the\n * wallpaper shows through, and one release earlier the very same heading read the\n * very same token as the card it sits on — so following it keeps rc.1's contract\n * (\"the card slider owns every layer of a menu, in the picked color\") instead of\n * leaving an untinted stock band inside a tinted, faded card.\n * Compositing is on its side too: the heading stacks on the surface layer it sticks\n * to, so a heading and a card at the same alpha still read as a band roughly\n * twice-as-dense as the card (1-(1-a)²) — occluding, at the slider's level, exactly\n * as it did when both came from one token. */\nexport const LAYERED_MENU_SURFACE_WITH_GROUP_HEADER: MenuSurfaceFacts = {\n fillTokens: [...LAYERED_MENU_SURFACE.fillTokens, MENU_GROUP_HEADER_FILL_TOKEN],\n frostDecl: LAYERED_MENU_SURFACE.frostDecl,\n}\n\n/** The answer when the release could not be resolved, and neither of the two\n * verified shapes can be asserted. Each half is chosen so that being on the\n * wrong line costs an inert declaration rather than a wrong pixel:\n * · BOTH fill tokens. A custom property nothing reads costs nothing, so this\n * half always lands: the fade reaches a self-painting menu through the old\n * token and a `MenuSurface` layer through the new one.\n * · the ELEMENT's frost, and not the host's blur token, because on `0.1.5` and\n * `0.1.6` `--dsw-menu-backdrop-filter` has no consumer at all (verified: zero\n * files before 0.1.7-alpha.1) — the token arm would leave those hosts with no\n * menu frost whatsoever, while filtering the element frosts every release.\n * On a `MenuSurface` host it does not stack: the surface root IS the element\n * that carries `role=\"menu\"`, so our filter makes it a backdrop root, and the\n * `z-index:-1` layer inside it then has only the (unpainted) surface to sample\n * and its own default `blur(40px)` becomes inert. One frost — ours — plus a\n * `position:relative` element that hosts nested menus the way the layer was\n * written not to. Accepted for a bucket that by definition cannot know. */\nexport const UNRESOLVED_MENU_SURFACE: MenuSurfaceFacts = {\n fillTokens: LAYERED_MENU_SURFACE.fillTokens,\n frostDecl: elementFrostDecl,\n}\n\n/** Session-header slot anchors present on EVERY release in range. The slot\n * renderer stamps `data-slot=\"<key>\"` unconditionally (`ui-renderer/scoped-slots.tsx`),\n * and all five keys are registered from 0.1.5-rc.2 through 0.2.1-alpha.1 —\n * verified per tag. Adapters append the keys their own release adds. */\nexport const BASE_HEADER_SLOT_KEYS = [\n 'conversation.session.header',\n 'conversation.session.header.actions',\n 'conversation.session.header.utilities',\n 'conversation.session.header.corner',\n 'conversation.session.header.lineage',\n] as const\n","/**\n * Adapter for the DSH 0.1.5-rc channel (`0.1.5-rc.2`, `0.1.5-rc.3`).\n *\n * Nothing here is inferred from a neighbouring release — each fact below was\n * checked against the harness tags `dsh-v0.1.5-rc.2` / `dsh-v0.1.5-rc.3`.\n *\n * Host shape this line presents:\n * `ui-sidebar-right/shell/SidebarRight.module.css`\n * .panel { position:absolute; z-index:10; transform:translateX(100%); visibility:hidden }\n * .panel[data-sidebar-right-open] { transform:none }\n * .panel[data-sidebar-right-panel='fullscreen'] { position:fixed; inset:0; z-index:40 }\n * `ui-dockkit` ships WITHOUT `TabLayout.tsx`, so `[data-dockkit-host]` and\n * `[data-dockkit-empty]` are never rendered on this line.\n * `ui-plugin-manager` (the page behind `PLUGIN_PAGE_FROST_RULE`) is not a package\n * on this line at all, and neither tag emits `[data-plugin-panel]`.\n *\n * Consequence for the panel slider: the WRAPPER is what slides, so the\n * `backdrop-filter` belongs on the wrapper — and because the wrapper sits inside\n * an animated track with its own stacking context, it must be promoted out of it\n * or the filter has no wallpaper to sample.\n *\n * Menus paint themselves here: 11 stylesheets declare\n * `background:var(--dsw-specific-menu)` on the element (`Menu`, `MenuView`,\n * `PopupSelectView`, `stat-dialog`, `ModelSelect`, `JobListAction`, `ContextMeter`,\n * `ScheduleCatalogAction`, `SubagentHeaderLineage`, `TeamAction`, `CordisPanel`),\n * and `--dsw-menu-backdrop-filter`\n * has NO consumer on this line at all — the host frosts no menu, so the element is\n * both the paint and the only place a frost can go. Hence `LEGACY_MENU_SURFACE`.\n *\n * @module\n */\nimport {\n BASE_HEADER_SLOT_KEYS,\n LEGACY_MENU_SURFACE,\n PANEL_FULLSCREEN,\n PANEL_WRAPPER,\n panelBlurRule,\n} from '../shared'\nimport type { HostAdapter, HostInfo, PanelFragments } from '../types'\n\n/** The wrapper carries the slide transform on this line, so it carries the blur. */\nfunction panelFragments(): PanelFragments {\n return {\n // Lift the panel clear of the rightbar column's stacking context. Fullscreen\n // re-asserts the host's own z-index 40 (the modal dialog stack lives at 100+,\n // above both), so the promotion above cannot drag it under the frame chrome.\n promotion:\n `${PANEL_WRAPPER}{position:fixed!important;z-index:26!important}` +\n `${PANEL_FULLSCREEN}{z-index:40!important}`,\n blur: panelBlurRule(PANEL_WRAPPER),\n }\n}\n\nexport function createAdapter(host: HostInfo): HostAdapter {\n return {\n id: '0.1.5-rc.2/rc.3',\n channel: '0.1.5-rc',\n host,\n panelFragments,\n // No plugin-manager page to frost. Emitting the rule would be harmless — the\n // selector cannot match — but a resolved adapter's job is to say what THIS\n // release has, and this one does not.\n pluginPageRule: '',\n menus: LEGACY_MENU_SURFACE,\n surface: {\n // This line's own right Sidebar does NOT carry the appearance page, so the\n // plugin's dsh-better-sidebar page owns the guide surface and must register.\n ownsSidebarGuideSurface: false,\n // All five header slot anchors are registered on both 0.1.5 releases.\n headerSlotKeys: BASE_HEADER_SLOT_KEYS,\n },\n }\n}\n","/**\n * Adapter for the DSH 0.1.6-alpha channel (`0.1.6-alpha.1`, `0.1.6-alpha.2`).\n *\n * Facts checked per tag against `dsh-v0.1.6-alpha.1` / `dsh-v0.1.6-alpha.2` —\n * deliberately not copied over from the 0.1.5 folder, even where the two lines\n * turned out to agree. If a future 0.1.6 patch diverges, only this file moves.\n *\n * Host shape this line presents:\n * `SidebarRight.module.css` is unchanged from the 0.1.5 line for the parts that\n * matter: `.panel` still carries `position:absolute` + `transform:translateX(100%)`,\n * `data-sidebar-right-open` still clears it with `transform:none`, and the panel\n * width is still an inline `width` with no `--dsh-sidebar-width` variable.\n * alpha.2 appends fullscreen window chrome (`.63` windows / `.77` darwin), which\n * does not move the blur target, AND the `ui-plugin-manager` package — so the\n * plugin-page frost below is prerelease-gated rather than channel-wide.\n * `ui-dockkit` still has no `TabLayout.tsx`, so no `[data-dockkit-host]` /\n * `[data-dockkit-empty]` on this line either.\n *\n * So the panel mechanics match 0.1.5: the wrapper slides, the wrapper takes the\n * blur, and the wrapper needs promoting.\n *\n * Menus too — checked separately at both tags, because that is what this folder is\n * for: 11 stylesheets paint the menu element from `--dsw-specific-menu` on alpha.1\n * and alpha.2 alike, and `--dsw-menu-backdrop-filter` has no consumer on either, so\n * `LEGACY_MENU_SURFACE` serves the whole line. The element is both the paint and\n * the frost's only possible home.\n *\n * @module\n */\nimport {\n BASE_HEADER_SLOT_KEYS,\n LEGACY_MENU_SURFACE,\n PANEL_FULLSCREEN,\n PANEL_WRAPPER,\n PLUGIN_PAGE_FROST_RULE,\n panelBlurRule,\n} from '../shared'\nimport { prereleaseOf } from '../../../../host-compat/channel'\nimport type { HostAdapter, HostInfo, PanelFragments } from '../types'\n\n/** The extra session-header anchor this line introduces: the macOS titlebar work\n * added `conversation.session.header.leading`. It was deleted again at\n * 0.1.7-alpha.1 with no shim, so it is unique to this line — which is why the\n * channel alone is not enough to answer it and the prerelease is read.\n * `alpha.1` predates it.\n *\n * Erring toward \"included\": a slot key the host never emits simply matches\n * nothing, whereas a key we omit hides a header area from the plugin for the\n * whole session. */\nfunction hasLeadingHeaderSlot(version: string | null): boolean {\n const pre = prereleaseOf(version)\n if (pre === null) return true\n const m = /^alpha\\.(\\d+)$/.exec(pre)\n return m === null || Number(m[1]) >= 2\n}\n\n/** The other thing this line splits on: `ui-plugin-manager` — the package that\n * renders `设置 → 插件` and stamps `[data-plugin-panel]` — was CREATED at\n * alpha.2. Until then the plugin list was a settings tab in\n * `ui-settings-plugin-inventory`, which carries `[data-plugin-scope]` but no\n * card list to frame, so alpha.1 has nothing for the frost rule to apply to.\n *\n * Same erring-toward-included convention as `hasLeadingHeaderSlot`: the rule's\n * own `[data-plugin-panel]` prefix means an over-broad arm cannot paint, while\n * an over-narrow one leaves a page bare for the whole session. */\nfunction hasPluginManagerPage(version: string | null): boolean {\n const pre = prereleaseOf(version)\n if (pre === null) return true\n const m = /^alpha\\.(\\d+)$/.exec(pre)\n return m === null || Number(m[1]) >= 2\n}\n\nfunction panelFragments(): PanelFragments {\n return {\n // Same treatment as the 0.1.5 line: the wrapper is transformed inside an\n // animated track, so the frost needs it lifted out to have wallpaper to\n // sample. This is the arrangement the 0.1.6 report confirmed working.\n promotion:\n `${PANEL_WRAPPER}{position:fixed!important;z-index:26!important}` +\n `${PANEL_FULLSCREEN}{z-index:40!important}`,\n blur: panelBlurRule(PANEL_WRAPPER),\n }\n}\n\nexport function createAdapter(host: HostInfo): HostAdapter {\n return {\n id: '0.1.6-alpha.1/alpha.2',\n channel: '0.1.6-alpha',\n host,\n panelFragments,\n pluginPageRule: hasPluginManagerPage(host.version) ? PLUGIN_PAGE_FROST_RULE : '',\n menus: LEGACY_MENU_SURFACE,\n surface: {\n // From this line the host's own right Sidebar carries an appearance page,\n // so the plugin's dsh-better-sidebar page would double the guide surface\n // and stands down. NOT derived from the sidebar service existing — it\n // already ships on 0.1.5-rc.2 — this is the release's own behaviour.\n ownsSidebarGuideSurface: true,\n headerSlotKeys: hasLeadingHeaderSlot(host.version)\n ? [...BASE_HEADER_SLOT_KEYS, 'conversation.session.header.leading']\n : BASE_HEADER_SLOT_KEYS,\n },\n }\n}\n","/**\n * Adapter for the DSH 0.1.7-alpha channel (`0.1.7-alpha.1`, `0.1.7-alpha.2`),\n * re-verified unchanged at `0.1.7-rc.1`.\n *\n * This is the line the panel mechanics actually changed on — verified against\n * `dsh-v0.1.6-alpha.2` → `dsh-v0.1.7-alpha.1`, where `SidebarRight.module.css`\n * was rewritten (116 lines changed) and `ui-dockkit/src/components/TabLayout.tsx`\n * was ADDED. Both facts were checked, not assumed.\n *\n * `0.1.7-rc.1` was checked the same way, by diffing every package that emits an\n * anchor this plugin matches (the panel CSS, dockkit, the plugin-manager page, the\n * slot renderer, the theme tokens): no anchor line moved, and the two UI changes it\n * carries do not reach us —\n * · `ui-plugin-manager`: a new `InstallDialog` failure screen plus compatibility\n * wording. The card block (`section` → `div.groupHead` + `ul.cards`) is\n * untouched, and the dialog is a body-level `Modal`, so the `:has()` valve of\n * `PLUGIN_PAGE_FROST_RULE` never even has to fire for it.\n * · `ui-conversation`: `.titleRow` gains `container-type:inline-size`, which makes\n * it a stacking context and a containing block. Header slots sit inside that\n * row, but this plugin reaches them through background/blur tokens, and the\n * dropdowns they trigger portal to `document.body` (see `header-tag.ts`), so\n * nothing of ours lands inside the new containment.\n *\n * Host shape this line presents:\n * .panel { position:absolute; --dsh-dockkit-dock-layer:10; pointer-events:none }\n * — no transform, no visibility, and no z-index of its own any more.\n * .panel :global([data-dockkit-host='dock']),\n * .panel :global([data-dockkit-empty]),\n * .panel :global([data-dockkit-divider]) { transform:translateX(var(--dsh-sidebar-width)); visibility:hidden }\n * .panel[data-sidebar-right-open] :global(…) { transform:none }\n * — the DOCKED CHILDREN are what slide.\n * .panel[data-sidebar-right-panel='fullscreen'] { --dsh-dockkit-dock-layer:40 }\n * — fullscreen no longer flips the panel to `position:fixed`; it raises a\n * layer variable, and the width becomes `100vw` on the absolute panel.\n *\n * Consequences encoded below:\n * 1. The blur belongs on the children. On the wrapper it frosted a stationary\n * frame — \"the blur stays put while the sidebar moves\".\n * 2. The promotion must NOT be emitted. `position:fixed` detaches the panel from\n * the track the host animates, which is the whole reason 2 the blur stopped\n * travelling. The host's own sheet documents the content root as owning \"no\n * stacking context or transform\", so `backdrop-filter` resolves against the\n * page and samples the wallpaper unaided.\n * 3. `[data-dockkit-empty]` must be included alongside `[data-dockkit-host]`: a\n * pane with no tabs renders the empty host instead, and keying on `host`\n * alone mis-detects that (transient) shape.\n *\n * Also true of this line, recorded so the next reader does not re-derive it:\n * · `conversation.session.header.leading` was DELETED here with no shim, so this\n * folder deliberately does not list it (see the 0.1.6 folder).\n * · `--dsw-specific-menu` was severed from `--dsw-alias-bg-layer-3` and became a\n * literal translucent rgba, plus a `html[data-platform='darwin']` re-override.\n * The plugin already samples and writes that token directly, so the severance\n * needs no adapter of its own — but note the consequence: `toRgba()` REPLACES\n * alpha, so the header slider now overrides the host's own 0.58 rather than\n * fading an opaque layer. Intended (the slider means \"this opacity\"), worth\n * knowing if the 0.1.7 header ever looks too thin.\n * · `[data-chat-flow]` is stamped on a nested `ChatGroupSeat` content element\n * too. Checked against every use in this plugin: the stroke group is inherited\n * so a second match changes nothing, and the view-card discovery takes the\n * first match, which is still the real flow root. No arm needed.\n * · menus still paint THEMSELVES on this line — 15 stylesheets declare\n * `background:var(--dsw-specific-menu)` on the element at alpha.1/alpha.2 and 16\n * at rc.1, so `LEGACY_MENU_SURFACE` is the answer and the `MenuSurface` child\n * layer does not exist yet. Worth noting what DID arrive here:\n * `--dsw-menu-backdrop-filter` goes from zero consumers at 0.1.6-alpha.2 to 15 at\n * alpha.1 (16 at rc.1), i.e. this is the line where the host started frosting\n * menus on the element itself. The plugin's own filter sits on the same element\n * and wins the cascade by sheet order, so the element is still the only place a\n * frost can go — which is exactly why re-declaring the HOST's token instead\n * would be inert on this line and correct on the next one.\n *\n * @module\n */\nimport {\n BASE_HEADER_SLOT_KEYS,\n DOCKKIT_SLIDERS,\n LEGACY_MENU_SURFACE,\n PLUGIN_PAGE_FROST_RULE,\n panelBlurRule,\n} from '../shared'\nimport type { HostAdapter, HostInfo, PanelFragments } from '../types'\n\nfunction panelFragments(): PanelFragments {\n return {\n // Consequence 2: nothing to promote. The panel resolves against the page on\n // its own here, so the pre-0.1.7 lift is pure downside.\n promotion: '',\n blur: panelBlurRule(DOCKKIT_SLIDERS),\n }\n}\n\nexport function createAdapter(host: HostInfo): HostAdapter {\n return {\n id: '0.1.7-alpha.1/alpha.2/rc.1',\n channel: '0.1.7-alpha',\n host,\n panelFragments,\n // Every build this folder covers ships the plugin-manager page, and\n // `renderGroup` is byte-identical to 0.1.6-alpha.2's, so the same string\n // serves the whole line — rc.1 changed only the install dialog around it.\n pluginPageRule: PLUGIN_PAGE_FROST_RULE,\n menus: LEGACY_MENU_SURFACE,\n surface: {\n ownsSidebarGuideSurface: true,\n headerSlotKeys: BASE_HEADER_SLOT_KEYS,\n },\n }\n}\n","/**\n * Adapter for the DSH `0.1.7-rc` channel, verified at `0.1.7-rc.2` (npm `latest`).\n *\n * Same patch line as `v0-1-7-alpha-1-2-rc-1`, DIFFERENT ANSWERS — which is why this\n * folder exists at all rather than another row on that one. Everything the alpha\n * folder says about panel mechanics still holds here (checked by diffing the panel\n * CSS, dockkit, the slot renderer and the plugin-manager page tag to tag: no anchor\n * line moved, and `TabLayout.tsx` / `SidebarRight.module.css` are unchanged from\n * rc.1). What moved is where a MENU gets its paint.\n *\n * Two host changes reach this plugin:\n *\n * 1. `ui-primitives/src/MenuSurface.tsx` is NEW, and `TabMenu`, `MenuView`,\n * `PopupSelectView`, `ModelSelect` and `Menu` all render through it. The element\n * that carries `role=\"menu\"` no longer paints anything: a `z-index:-1` child\n * layer does, reading `--dsw-menu-surface-fill` for the fill and\n * `--dsw-menu-backdrop-filter` for the frost. And `design-platform.css` flipped\n * its alias — `--dsw-specific-menu:var(--dsw-menu-surface-fill)`, where every\n * earlier release declared it the other way round. Consequence, read off those\n * two files rather than guessed: retinting `--dsw-specific-menu` alone now fades\n * nothing on a shared menu, so the card and header opacity sliders go inert on\n * exactly the surfaces they were built for. `LAYERED_MENU_SURFACE` is the answer.\n * Filtering the menu element would also have kept working, sort of — but the\n * child layer's own comment says it exists so that no ANCESTOR becomes a\n * backdrop root, so that arm stops being offered here.\n *\n * 2. `ui-settings-general/src/client/SettingsRoot.tsx` now renders the dialog\n * through `createPortal`, beside `#root`, instead of inline in the column. It\n * costs this plugin nothing, recorded so nobody re-derives it:\n * `SETTINGS_PANEL_SEL` tests the dialog's own identity (its hashed `_panel`\n * class plus `role`/`aria-modal`/`aria-labelledby`, all unchanged), never an\n * ancestor, so the retint and the blur land the same way one level higher up.\n * The one rule that DID care — `PART_BLUR_RULE`'s\n * `:has([role=\"dialog\"]){isolation:auto}` valve, written because a modal mounted\n * inside a column kept its z-index local to that column — now never matches, and\n * that is fine: the modal it existed to release is no longer inside a column\n * either, so the trap and the valve left together.\n *\n * Still `0.1.7` facts, restated for the reader who only opens this folder:\n * · the panel is a stationary frame; the dockkit children slide, so the blur goes\n * on the children and nothing is promoted.\n * · `conversation.session.header.leading` is gone; `--dsw-specific-menu` is a\n * literal translucent rgba, not an alias of a layer token.\n * · the shimmer primitive is STILL `data-text-shimmer` (checked: `data-shimmer`\n * does not exist at this tag) — that rename belongs to 0.2.0.\n *\n * @module\n */\nimport {\n BASE_HEADER_SLOT_KEYS,\n DOCKKIT_SLIDERS,\n LAYERED_MENU_SURFACE,\n PLUGIN_PAGE_FROST_RULE,\n panelBlurRule,\n} from '../shared'\nimport type { HostAdapter, HostInfo, PanelFragments } from '../types'\n\nfunction panelFragments(): PanelFragments {\n return {\n // Re-verified against rc.2: the wrapper carries no transform and no z-index, so\n // `backdrop-filter` on it resolves against the page unaided and the lift the\n // pre-0.1.7 folders emit would only knock the panel off its animation track.\n promotion: '',\n blur: panelBlurRule(DOCKKIT_SLIDERS),\n }\n}\n\nexport function createAdapter(host: HostInfo): HostAdapter {\n return {\n id: '0.1.7-rc.2',\n channel: '0.1.7-rc',\n host,\n panelFragments,\n // `renderGroup` is byte-identical to the alpha folder's at this tag; what rc.2\n // added around it is the install dialog, which portals to body.\n pluginPageRule: PLUGIN_PAGE_FROST_RULE,\n menus: LAYERED_MENU_SURFACE,\n surface: {\n ownsSidebarGuideSurface: true,\n headerSlotKeys: BASE_HEADER_SLOT_KEYS,\n },\n }\n}\n","/**\n * Adapter for the DSH `0.2.0-rc` channel, verified at `0.2.0-rc.1`.\n *\n * A new MINOR line, and the panel is not what changed. Checked by reading the\n * emitting source at the tag rather than a changelog:\n * · `ui-sidebar-right/src/client/shell/SidebarRight.module.css` is BYTE-IDENTICAL\n * to `0.1.7-rc.2`, and `ui-primitives/src/MenuSurface.tsx` is byte-identical\n * too. So the slide owner, the layer variable and where a menu gets its paint\n * all answer the same as the `0.1.7-rc` folder — nothing below re-derives them.\n * · the five `conversation.session.header*` slot keys are the same five;\n * `conversation.session.header.leading` is still deleted.\n * · `ui-settings-general/SettingsRoot.tsx` is byte-identical, so the settings\n * dialog is still a body-level `createPortal` and `SETTINGS_PANEL_SEL`'s\n * identity test still reaches it.\n * · the boot peer gate (`app-boot/src/plugin-compatibility.ts`,\n * `compatibility-preflight.ts`) is byte-identical, which is what makes the\n * manifest change below a HARD requirement rather than metadata: an unlisted\n * peer version disables the plugin at profile composition and its modules are\n * never imported.\n *\n * What did move, and reaches this plugin:\n *\n * 1. `ui-dockkit/components/TabLayout.tsx` clamps a FLOATING pane's `top` with\n * `max(var(--dsh-dockkit-float-top, 0px), Ypx)`. Only floats: the attributes\n * this plugin matches, `data-dockkit-host=\"dock\"` and `data-dockkit-empty`,\n * are on unchanged lines (verified by grep at both tags), so the blur arm\n * stands as the rc.2 folder wrote it.\n *\n * 2. `ui-primitives/src/TextShimmer.tsx` is REWRITTEN. The old primitive set\n * `data-text-shimmer` and painted the element itself with a clipped gradient\n * (`background-clip:text` + `-webkit-text-fill-color:transparent`) sized by an\n * inline `--dsh-text-shimmer-spread`, which no longer exists anywhere in the\n * repo. The new one marks its root `data-shimmer` and moves the highlight onto\n * an absolutely-positioned overlay (`.decoration` / `.sweep` / `.highlight`)\n * tinted by `--dsw-alias-label-shimmer`, so the real glyphs keep their own\n * color. Consequence for the stroke sliders: the old failure mode — a stroke\n * repainting transparent-filled glyphs as one flat blob — is gone, but\n * `-webkit-text-stroke` is still inherited, so the chat stroke would now land\n * on BOTH the real text and the sweeping copy and double every glyph while it\n * animates. Progress chrome still is not conversation prose, so the exemption\n * stays and gains the new attribute (`STROKE_RULE`).\n * More rows use it now: `ReasoningRow` and `GenericCommandCard` join\n * `ChatGroupSeat` / `MessageItem` / `RunningStatus` / `DisclosureRow`.\n *\n * 3. `ui-plugin-manager` gains a first-read `ListSkeleton`. Its card `ul` carries\n * the same `.cards` class but sits under `section[data-plugin-loading]`\n * instead of `section[data-plugin-scope]`, so the shared frost rule had to\n * grow or the plugin page would show an unfrosted list for the length of the\n * first read and then re-frost it — see `PLUGIN_PAGE_FROST_RULE`.\n *\n * @module\n */\nimport {\n BASE_HEADER_SLOT_KEYS,\n DOCKKIT_SLIDERS,\n LAYERED_MENU_SURFACE,\n PLUGIN_PAGE_FROST_RULE,\n panelBlurRule,\n} from '../shared'\nimport type { HostAdapter, HostInfo, PanelFragments } from '../types'\n\nfunction panelFragments(): PanelFragments {\n return {\n // Re-verified: the wrapper CSS is byte-identical to rc.2, so the panel is\n // still a stationary frame, the dockkit children still slide, and promoting\n // the wrapper would still knock it off the host's animation track.\n promotion: '',\n blur: panelBlurRule(DOCKKIT_SLIDERS),\n }\n}\n\nexport function createAdapter(host: HostInfo): HostAdapter {\n return {\n id: '0.2.0-rc.1',\n channel: '0.2.0-rc',\n host,\n panelFragments,\n // The page markup that decides the frost target is unchanged apart from the\n // new loading skeleton, which the shared rule now covers for every line that\n // ships the page (older hosts never emit `[data-plugin-loading]`).\n pluginPageRule: PLUGIN_PAGE_FROST_RULE,\n menus: LAYERED_MENU_SURFACE,\n surface: {\n ownsSidebarGuideSurface: true,\n headerSlotKeys: BASE_HEADER_SLOT_KEYS,\n },\n }\n}\n","/**\n * Adapter for the DSH `0.2.0-rc` line from `0.2.0-rc.2` on, verified at `0.2.0-rc.2`.\n *\n * The first case where one patch line AND one prerelease channel carry two\n * answers, so this folder opens a second channel (see the note on `HostChannel`).\n * What it took was one renamed token, and it is a menu token, which is the class of\n * fact this table exists for:\n *\n * · `ui-primitives/src/MenuGroup.tsx` + `.module.css` are NEW at rc.2 and the\n * headings of both grouped popups (`ModelSelect`, `PopupSelectView`) now come\n * from them. `ModelSelect.module.css` loses `.groupTitle{background:var(\n * --dsw-specific-menu)}` in the same breath — the sticky heading's paint moved\n * to `--dsw-alias-menu-group-header-fill`, a token that does not exist before\n * this tag (`git grep` at `0.1.7-rc.2` and `0.2.0-rc.1`: absent). Hence\n * `LAYERED_MENU_SURFACE_WITH_GROUP_HEADER` rather than the rc.1 constant: the\n * old claim set stayed true, it just stopped covering one element.\n * · the rest of the menu layer is the same code — `MenuSurface.tsx` and\n * `MenuSurface.module.css` are byte-identical to `0.2.0-rc.1`, and so is every\n * consumer of `--dsw-menu-backdrop-filter`.\n *\n * Also verified at this tag, and NOT a reason for a folder of its own:\n * · `SidebarRight.module.css` and `ui-dockkit/src/components/TabLayout.tsx` are\n * unchanged, so the panel is still a stationary frame whose dockkit children\n * slide (`panelBlurRule(DOCKKIT_SLIDERS)`, no promotion).\n * · the five `conversation.session.header*` slot keys, and still no `…leading`.\n * · `PluginManagerPage.tsx` still emits `section[data-plugin-panel]` with the card\n * `ul` under `[data-plugin-scope]` and `[data-plugin-loading]`.\n * · `TextShimmer` keeps the rc.1 shape (`data-shimmer`), so the stroke exemption\n * stands as written.\n *\n * What moved that reached this plugin WITHOUT a version branch, because the host\n * wrote it as a chain with a fallback:\n * · `TurnTriggerNodeView.module.css` now fills from\n * `var(--dsw-alias-turn-trigger-bg, var(--dsw-alias-markdown-code-block))` and\n * hovers with `var(--dsw-alias-turn-trigger-bg-hover, var(--dsw-alias-interactive-bg-hover))`,\n * both aliases declared in `design-platform.css` at this tag. The produced\n * slider's arm reads the SAME chain (see `PRODUCED_RULE`), so older hosts take\n * the fallback and this one takes the new alias — without any release test. That\n * matters here rather than being pedantry: dark mode repoints the alias at\n * `--dsw-alias-interactive-bg-hover`, so an arm still mixing on the code-block\n * token would keep overriding the row with the OLD color and the row would stop\n * tracking its own hover.\n *\n * @module\n */\nimport {\n BASE_HEADER_SLOT_KEYS,\n DOCKKIT_SLIDERS,\n LAYERED_MENU_SURFACE_WITH_GROUP_HEADER,\n PLUGIN_PAGE_FROST_RULE,\n panelBlurRule,\n} from '../shared'\nimport type { HostAdapter, HostInfo, PanelFragments } from '../types'\n\nfunction panelFragments(): PanelFragments {\n return {\n // Re-verified at this tag: the wrapper CSS is byte-identical to rc.1.\n promotion: '',\n blur: panelBlurRule(DOCKKIT_SLIDERS),\n }\n}\n\nexport function createAdapter(host: HostInfo): HostAdapter {\n return {\n id: '0.2.0-rc.2',\n channel: '0.2.0-rc.2',\n host,\n panelFragments,\n pluginPageRule: PLUGIN_PAGE_FROST_RULE,\n menus: LAYERED_MENU_SURFACE_WITH_GROUP_HEADER,\n surface: {\n ownsSidebarGuideSurface: true,\n headerSlotKeys: BASE_HEADER_SLOT_KEYS,\n },\n }\n}\n","/**\n * Adapter for the DSH `0.2.1-alpha` line, verified at `0.2.1-alpha.1`.\n *\n * A new MINOR line opened with a prerelease, and the answer is the `0.2.0-rc.2`\n * folder's — which is a statement this file has to earn, because \"same as the\n * release before\" is exactly the reasoning that went wrong when `0.1.7-rc.2` moved\n * the menu paint. Read at the tag instead:\n * · `ui-theme/src/styles/design-platform.css` is BYTE-IDENTICAL to `0.2.0-rc.2`\n * (`git diff --numstat` empty), so every token this plugin writes — the menu\n * pair, the specific-menu alias, the turn-trigger chain — resolves to the same\n * values.\n * · `MenuGroup.tsx`, `MenuGroup.module.css`, `MenuSurface.tsx` and\n * `MenuSurface.module.css` are byte-identical too, and `MenuGroup` is still the\n * only consumer of `--dsw-alias-menu-group-header-fill`. That is why the menus\n * here answer with `LAYERED_MENU_SURFACE_WITH_GROUP_HEADER`, the same facts the\n * rc.2 folder checked, and not by re-typing them.\n * · `ui-sidebar-right/shell/SidebarRight.module.css` and\n * `ui-dockkit/src/components/TabLayout.tsx` unchanged (only `.tsx` service\n * wiring moved), so the panel stays a stationary frame with sliding dockkit\n * children and no promotion.\n * · the five `conversation.session.header*` slot keys, still no `…leading`.\n * · `PluginManagerPage.tsx` still emits the three anchors of the card list.\n * · `TextShimmer` still marks its root `data-shimmer`, so the stroke exemption\n * written for rc.1 stands.\n *\n * What did move, and why none of it needs a fact from this folder:\n *\n * 1. `ui-layout/AppFrame` gains a second grid row, `div.bottomRow[data-shell-bottom]`\n * holding the new `shell.bottom` slot, and it paints `--dsw-alias-bg-base` —\n * the main-background token, which `applyCustomTokensNow` already re-emits on\n * `body`, so the strip follows the main-bg slider with no new binding. The row\n * is `min-height:0` and empty unless a plugin fills the slot, so an untouched\n * install shows nothing. It also sits AFTER `RightbarColumn` in the frame's\n * children, which is the side `discoverParts()` does not count from: it anchors\n * on `data-rightbar-col` and reads `rightIdx-2` / `rightIdx-1`, so the sidebar\n * and center column are still the same two children.\n * 2. `ui-primitives/InlineEditor.module.css` is the new home of the inline editor's\n * `.editor{background:var(--dsw-alias-bg-base)}`. Same token, so the same slider\n * reaches it wherever the component moved to.\n * 3. `modules/system.ts` narrowed `claimStyles` to the tags a factory itself added\n * (see `ensureUiCss` for what that changed about our own sheet).\n * 4. `@deepseek-ai/dsh-invariants` is DELETED at this tag — `git ls-tree` shows no\n * `packages/runtime-diagnostics/invariants`, and the boot/app plugin loader never\n * looked for a plugin's `invariant` export. This plugin's no-op companion was\n * therefore already dead weight here, and it goes rather than claiming a peer\n * version for a package the host no longer ships.\n *\n * @module\n */\nimport {\n BASE_HEADER_SLOT_KEYS,\n DOCKKIT_SLIDERS,\n LAYERED_MENU_SURFACE_WITH_GROUP_HEADER,\n PLUGIN_PAGE_FROST_RULE,\n panelBlurRule,\n} from '../shared'\nimport type { HostAdapter, HostInfo, PanelFragments } from '../types'\n\nfunction panelFragments(): PanelFragments {\n return {\n promotion: '',\n blur: panelBlurRule(DOCKKIT_SLIDERS),\n }\n}\n\nexport function createAdapter(host: HostInfo): HostAdapter {\n return {\n id: '0.2.1-alpha.1',\n channel: '0.2.1-alpha',\n host,\n panelFragments,\n pluginPageRule: PLUGIN_PAGE_FROST_RULE,\n menus: LAYERED_MENU_SURFACE_WITH_GROUP_HEADER,\n surface: {\n ownsSidebarGuideSurface: true,\n headerSlotKeys: BASE_HEADER_SLOT_KEYS,\n },\n }\n}\n","/**\n * Stand-in for \"we could not resolve the release\".\n *\n * This is a REAL case, not a theoretical one: a plain `~/.dsh` install has no\n * launcher layout, so the front-door probe finds neither a manifest nor a\n * version-shaped directory name. It must not degrade into a guessed channel —\n * a wrong guess silently restyles the window.\n *\n * Instead, the DOM arbitrates. Both panel arms ship, each gated on the shape that\n * only one release family can present, which is exactly how this plugin behaved\n * before release detection existed. It is why an unresolved host still gets a\n * working panel blur.\n *\n * The one concession this costs: an engine without `:has()` cannot parse a gated\n * selector and drops that block, so such a host loses the promotion. A resolved\n * host does not have that problem — its arm is unconditional.\n *\n * @module\n */\nimport {\n BASE_HEADER_SLOT_KEYS,\n DOCKKIT_SLIDERS,\n PANEL_FULLSCREEN,\n PANEL_WRAPPER,\n PLUGIN_PAGE_FROST_RULE,\n UNRESOLVED_MENU_SURFACE,\n panelBlurRule,\n WITHOUT_DOCKKIT_FRAME,\n} from '../shared'\nimport type { HostAdapter, HostInfo, PanelFragments } from '../types'\n\nfunction panelFragments(): PanelFragments {\n const wrapper = `${PANEL_WRAPPER}${WITHOUT_DOCKKIT_FRAME}`\n return {\n // The promotion can only be claimed conditionally here: on a 0.1.7-style\n // frame it is actively wrong, and the frame's presence is all we can test.\n promotion:\n `${wrapper}{position:fixed!important;z-index:26!important}` +\n `${PANEL_FULLSCREEN}${WITHOUT_DOCKKIT_FRAME}{z-index:40!important}`,\n // Each owner in its OWN block — a selector list is not forgiving, so bundling\n // them would let one unparseable entry drop the other's frost too.\n blur:\n panelBlurRule(DOCKKIT_SLIDERS) +\n panelBlurRule(wrapper),\n }\n}\n\nexport function createAdapter(host: HostInfo): HostAdapter {\n return {\n id: 'unknown',\n channel: 'unknown',\n host,\n panelFragments,\n // Unlike the panel arms this needs no DOM gate: the page's own\n // `[data-plugin-panel]` prefix IS the test, so on a release with no plugin\n // manager the rule is simply inert. No `:has()` cost either.\n pluginPageRule: PLUGIN_PAGE_FROST_RULE,\n // The menu arms cannot be DOM-gated the way the panel ones are — a fill token\n // and a frost target are not testable on an element that is not open yet — so\n // this takes the variant built to cost nothing on whichever line it turns out\n // to be. See `UNRESOLVED_MENU_SURFACE`.\n menus: UNRESOLVED_MENU_SURFACE,\n surface: {\n // Asserting `true` here would withdraw the plugin's sidebar page on a host\n // that may not have an appearance page of its own — a missing page is worse\n // than a duplicate, and the duplicate is what the resolved adapters prevent.\n ownsSidebarGuideSurface: false,\n headerSlotKeys: BASE_HEADER_SLOT_KEYS,\n },\n }\n}\n","/**\n * The registry: release channel → the adapter folder that speaks for it.\n *\n * The ONLY place in the plugin that maps a release onto code. Adding a new DSH\n * line is a three-step change with no existing file to touch:\n * 1. `KnownChannel` (and `channelOf`) in `src/host-compat/channel.ts`,\n * 2. a folder here, mirroring the others, NAMED FOR THE EXACT TAGS ITS FACTS\n * WERE CHECKED AGAINST (`v0-1-6-alpha-1-2`, not `v0-1-6-alpha`) so the\n * precision of the table is readable from the tree, and the folder states\n * inside it which prerelease gates it carries,\n * 3. the row below.\n * A newer build that turns out to need NO change does not get its own folder: it\n * joins the name of the folder whose facts held (`v0-1-7-alpha-1-2-rc-1`, checked\n * at rc.1) and gains a `SUPPORTED_RELEASES` row, which is what moves that host's\n * verdict from `line` to `exact`.\n * Anything that reads an adapter then picks it up without a edit — which is the\n * point: version branching must not be reachable from the styling code.\n *\n * The folder is keyed by what its FACTS cover, not by the version number's shape:\n * `v0-1-7-rc-2` sits beside `v0-1-7-alpha-1-2-rc-1` even though both are \"0.1.7\",\n * because rc.2 moved where a menu gets its paint. Two folders on one patch line is\n * the cost of a table that is true; a row on a folder whose facts no longer hold is\n * the cost of one that is not.\n *\n * `v0-2-0-rc-2` sits beside `v0-2-0-rc-1` on a line that does not even differ in\n * prerelease name, because that rc renamed the token a sticky menu group heading\n * paints from. When the split is that fine-grained the channel key takes the build\n * that opened the new facts (`0.2.0-rc.2`), and `classifyRelease` routes everything\n * above it there — a folder named for a line is only honest while the line agrees.\n *\n * @module\n */\nimport type { HostAdapter, HostChannel, HostInfo } from './types'\nimport { createAdapter as adapterFor015rc } from './v0-1-5-rc-2-3/adapter'\nimport { createAdapter as adapterFor016alpha } from './v0-1-6-alpha-1-2/adapter'\nimport { createAdapter as adapterFor017alpha } from './v0-1-7-alpha-1-2-rc-1/adapter'\nimport { createAdapter as adapterFor017rc } from './v0-1-7-rc-2/adapter'\nimport { createAdapter as adapterFor020rc } from './v0-2-0-rc-1/adapter'\nimport { createAdapter as adapterFor020rc2 } from './v0-2-0-rc-2/adapter'\nimport { createAdapter as adapterFor021alpha } from './v0-2-1-alpha-1/adapter'\nimport { createAdapter as adapterForUnknown } from './unknown/adapter'\n\nconst ADAPTERS: Record<HostChannel, (host: HostInfo) => HostAdapter> = {\n '0.1.5-rc': adapterFor015rc,\n '0.1.6-alpha': adapterFor016alpha,\n '0.1.7-alpha': adapterFor017alpha,\n '0.1.7-rc': adapterFor017rc,\n '0.2.0-rc': adapterFor020rc,\n '0.2.0-rc.2': adapterFor020rc2,\n '0.2.1-alpha': adapterFor021alpha,\n unknown: adapterForUnknown,\n}\n\n/** Pick the adapter for a resolved host. `host.channel` is already narrowed to\n * the union by `adoptHostInfo`, so every channel here has a row by construction —\n * a new channel in `HostChannel` fails to compile until it is added. */\nexport function buildAdapter(host: HostInfo): HostAdapter {\n return ADAPTERS[host.channel](host)\n}\n","/**\n * The client-side half of the front door: where the release verdict lands.\n *\n * The browser cannot detect the host release — the client context exposes no\n * version field, and the app manifest that states it is only readable on the node\n * half. So `src/host-compat/detect.ts` resolves it there and the verdict travels\n * in the `read` RPC payload (see `client/rpc.ts`, which calls `adoptHostInfo`).\n *\n * This module only HOLDS the verdict and tells subscribers when it changes. It\n * deliberately answers no feature questions — that is `capabilities.ts`, so the\n * version → behaviour mapping stays in one place.\n *\n * @module\n */\nimport { useSyncExternalStore } from 'react'\nimport {\n channelOf,\n looksLikeVersion,\n UNKNOWN_HOST_INFO,\n type HostInfo,\n} from '../../host-compat/channel'\nimport { buildAdapter } from './versions/registry'\nimport type { HostAdapter } from './versions/types'\n\nlet current: HostInfo = UNKNOWN_HOST_INFO\n/** False until the server verdict lands. Feature gates must not read \"not asked\n * yet\" as \"an old host\" — see `adapterResolved()`. */\nlet resolved = false\n\nconst subs = new Set<() => void>()\n\n/** Cached adapter, keyed by the verdict it was built from. Held because React's\n * `useSyncExternalStore` requires a stable snapshot between notifications. */\nlet adapterCache: HostAdapter | null = null\n\n/** Adopt the verdict delivered by the server's `read` payload.\n *\n * The payload's `channel` is IGNORED and re-derived from `version` here: the\n * two halves are built together, so a disagreeing pair can only mean one of them\n * is stale, and re-deriving keeps `channelOf` the single definition of what a\n * channel means. */\nexport function adoptHostInfo(raw: unknown): void {\n if (raw === null || typeof raw !== 'object') return\n const h = raw as { version?: unknown }\n const version =\n typeof h.version === 'string' && looksLikeVersion(h.version.trim()) ? h.version.trim() : null\n const next: HostInfo = { version, channel: channelOf(version) }\n const changed = !resolved || current.version !== next.version || current.channel !== next.channel\n current = next\n resolved = true\n if (changed) {\n adapterCache = null\n subs.forEach(cb => cb())\n }\n}\n\n/** Subscribe to the verdict landing (or changing). */\nexport function subscribeHostInfo(cb: () => void): () => void {\n subs.add(cb)\n return () => { subs.delete(cb) }\n}\n\n/** Whether the server verdict has landed at all. */\nexport function adapterResolved(): boolean {\n return resolved\n}\n\n/** The detected host release + channel. */\nexport function rHostInfo(): HostInfo {\n return current\n}\n\n/** The adapter chosen for the current verdict — `unknown`'s stand-in until the\n * verdict lands, which is the safe answer: it asserts nothing and lets the DOM\n * arbitrate. */\nexport function rHostAdapter(): HostAdapter {\n adapterCache ??= buildAdapter(current)\n return adapterCache\n}\n\n/** React hook: re-renders when the host verdict lands or changes. */\nexport function useHostAdapter(): HostAdapter {\n return useSyncExternalStore(subscribeHostInfo, rHostAdapter)\n}\n","import type { RpcResultLike, UploadOutcome } from './types'\r\nimport { cfg, adoptConfig, setWpUrl, setWpImageUrl, setWpVideoUrl, rWpImage } from './state'\r\nimport { adoptHostInfo } from './host-compat/release'\r\n\r\nexport const RPC_CHANNEL = '/dsh-any-background'\r\n/** Same-origin serve URL of the persisted video (enough for <video src>/fetch). */\r\nexport const VIDEO_SERVE_URL = '/dsh-any-background/video'\r\n/** Same-origin serve URL of the persisted wallpaper (native <img> loading). */\r\nexport const WALLPAPER_SERVE_URL = '/dsh-any-background/wallpaper'\r\n/** Raw-bytes upload endpoint for the wallpaper slot (no base64 inflation). */\r\nconst WALLPAPER_UPLOAD_URL = '/dsh-any-background/wallpaper/upload'\r\n/** HTTP route new videos are POSTed to as raw bytes (see uploadVideo). */\r\nexport const VIDEO_UPLOAD_URL = '/dsh-any-background/video/upload'\r\n/** Same-origin serve URL of the persisted custom font (enough for @font-face). */\r\nexport const FONT_SERVE_URL = '/dsh-any-background/font'\r\n/** HTTP route custom fonts are POSTed to as raw bytes (see uploadFont). */\r\nexport const FONT_UPLOAD_URL = '/dsh-any-background/font/upload'\r\nconst RPC_NS = 'dshAnyBackground'\r\nconst rpcEndpoint = (method: string): string => `${RPC_NS}/${method}`\r\n\r\nlet rpcCallFn: ((endpoint: string, payload: unknown) => Promise<RpcResultLike | undefined>) | null = null\r\n\r\n/** Serve URL of the persisted custom font, filled by loadPersisted. */\r\nexport let fontServeUrl: string | null = null\r\n\r\nexport function initRpc(call: (endpoint: string, payload: unknown) => Promise<RpcResultLike | undefined>): void {\r\n rpcCallFn = call\r\n}\r\n\r\nasync function rpcCall(method: string, payload: unknown): Promise<unknown> {\r\n if (!rpcCallFn) return undefined\r\n try {\r\n const res = await rpcCallFn(rpcEndpoint(method), payload)\r\n if (res && res.ok === true) return res.value\r\n console.warn(`dsh-any-background: rpc \"${method}\" failed`, res?.error)\r\n return undefined\r\n } catch (e) {\r\n console.warn(`dsh-any-background: rpc \"${method}\" threw`, e)\r\n return undefined\r\n }\r\n}\r\n\r\n// Slider drags fire dozens of events per second; coalesce writes to a trailing\r\n// debounce and flush the last pending write on pagehide so a quick close never\r\n// loses it.\r\nconst SAVE_DEBOUNCE_MS = 250\r\nlet saveTimer: number | undefined\r\n\r\nexport function saveConfig(): void {\r\n if (saveTimer !== undefined) window.clearTimeout(saveTimer)\r\n saveTimer = window.setTimeout(() => {\r\n saveTimer = undefined\r\n void rpcCall('writeConfig', { config: cfg })\r\n }, SAVE_DEBOUNCE_MS)\r\n}\r\n\r\nexport function flushSave(): void {\r\n if (saveTimer === undefined) return\r\n window.clearTimeout(saveTimer)\r\n saveTimer = undefined\r\n void rpcCall('writeConfig', { config: cfg })\r\n}\r\n\r\n/** Persist the current config immediately (import path — no debounce). */\r\nexport function persistConfig(): void {\r\n void rpcCall('writeConfig', { config: cfg })\r\n}\r\n\r\n/** Load the persisted theme (config + wallpaper URL + video URL) from the node\r\n * half. Image and video both travel as serve URLs — never bytes — so this RPC\r\n * stays tiny. Resolves true when the server advanced a due wallpaper rotation\r\n * during the read — the restored wallpaper is then already the new pick.\r\n * `firstRun` means the server had no theme-config.json and just materialized\r\n * its defaults: the caller should persist the browser side's own defaults and\r\n * re-read once so every slider starts from a value that is really on disk. */\r\nexport async function loadPersisted(): Promise<{ rotated: boolean; firstRun: boolean }> {\r\n const data = await rpcCall('read', {})\r\n if (data && typeof data === 'object') {\r\n const d = data as { config?: unknown; wallpaperUrl?: unknown; videoUrl?: unknown; fontUrl?: unknown; rotated?: unknown; firstRun?: unknown; host?: unknown }\r\n // Host release verdict first: feature gates read it before any appearance\r\n // work runs, and it is the only source of the real version string.\r\n adoptHostInfo(d.host)\r\n if (d.config) adoptConfig(d.config)\r\n // Uploaded image and video keep their own slots so type switches never\r\n // discard them; in image mode the caller points wpUrl at it.\r\n if (typeof d.wallpaperUrl === 'string') setWpImageUrl(d.wallpaperUrl)\r\n else if (d.wallpaperUrl === null) setWpImageUrl(null)\r\n // The video travels as a serve URL; the frame snapshot is re-captured by\r\n // the boot restore in index.tsx when needed.\r\n if (typeof d.videoUrl === 'string') setWpVideoUrl(d.videoUrl, cfg.videoMime)\r\n else if (d.videoUrl === null) setWpVideoUrl(null, null)\r\n // The custom font travels as a serve URL too; the caller applies the\r\n // @font-face from it (config.fontEnabled decides whether it is active).\r\n if (typeof d.fontUrl === 'string') fontServeUrl = d.fontUrl\r\n else if (d.fontUrl === null) fontServeUrl = null\r\n // Mirror the same rev'd URL setWpImageUrl stored, so wpUrl never diverges.\r\n if (cfg.backgroundType === 'image') setWpUrl(rWpImage())\r\n return { rotated: d.rotated === true, firstRun: d.firstRun === true }\r\n }\r\n return { rotated: false, firstRun: false }\r\n}\r\n\r\n/** Persist a wallpaper (null removes it); one-shot, no debounce. */\r\nexport function persistWallpaper(dataUrl: string | null): void {\r\n void rpcCall('setWallpaper', { dataUrl })\r\n}\r\n\r\n/** Persist a background video (null removes it); resolves true once on disk,\r\n * so callers only switch playback to the serve URL after acceptance. */\r\nexport async function persistVideo(dataUrl: string | null): Promise<boolean> {\r\n const res = await rpcCall('setVideo', { dataUrl })\r\n return res === true\r\n}\r\n\r\n/** Download a wallpaper from a network URL and persist it into the local slot\r\n * (the host replaces wallpaper.jpg). Returns the freshly stored serve URL on\r\n * success, or the host's failure message. */\r\nexport async function setWallpaperFromUrl(url: string): Promise<{ ok: boolean; wallpaperUrl?: string | null; error?: string }> {\r\n if (!rpcCallFn) return { ok: false, error: 'rpc not ready' }\r\n let res: RpcResultLike | undefined\r\n try {\r\n res = await rpcCallFn(rpcEndpoint('setWallpaperUrl'), { url })\r\n } catch (e) {\r\n return { ok: false, error: e instanceof Error ? e.message : String(e) }\r\n }\r\n if (!res) return { ok: false, error: 'no response' }\r\n if (res.ok !== true) {\r\n const err = (res as { error?: { message?: string } }).error\r\n return { ok: false, error: err?.message ?? 'request failed' }\r\n }\r\n const v = res.value as { ok?: boolean; wallpaperUrl?: string | null; error?: string }\r\n return v?.ok === true\r\n ? { ok: true, wallpaperUrl: v.wallpaperUrl ?? null }\r\n : { ok: false, error: v?.error ?? 'failed' }\r\n}\r\n\r\n/** Download a background video from a network URL. The server streams it into\r\n * the video slot and returns the resolved MIME for playback via the serve URL. */\r\nexport async function setVideoFromUrl(url: string): Promise<{ ok: boolean; mime?: string; error?: string }> {\r\n if (!rpcCallFn) return { ok: false, error: 'rpc not ready' }\r\n let res: RpcResultLike | undefined\r\n try {\r\n res = await rpcCallFn(rpcEndpoint('setVideoUrl'), { url })\r\n } catch (e) {\r\n return { ok: false, error: e instanceof Error ? e.message : String(e) }\r\n }\r\n if (!res) return { ok: false, error: 'no response' }\r\n if (res.ok !== true) {\r\n const err = (res as { error?: { message?: string } }).error\r\n return { ok: false, error: err?.message ?? 'request failed' }\r\n }\r\n const v = res.value as { ok?: boolean; mime?: string; error?: string }\r\n return v?.ok === true\r\n ? { ok: true, mime: v.mime ?? 'video/mp4' }\r\n : { ok: false, error: v?.error ?? 'failed' }\r\n}\r\n\r\n/** Map a refused upload response onto an outcome. The body has to be read: the\r\n * node half names the reason there, and an oversized transfer answers\r\n * `413 { ok:false, error:'too large', limit:'100 MB' }`. Checking `res.ok`\r\n * alone threw that away, so an oversized upload surfaced as a bare failure —\r\n * or, on the wallpaper path, as nothing at all. */\r\nasync function refusedUpload(res: Response): Promise<UploadOutcome> {\r\n const body = await res.json().catch(() => null) as { error?: unknown; limit?: unknown } | null\r\n if (body?.error === 'too large') {\r\n return {\r\n ok: false,\r\n refusal: {\r\n kind: 'too-large',\r\n status: res.status,\r\n limit: typeof body.limit === 'string' ? body.limit : undefined,\r\n },\r\n }\r\n }\r\n return { ok: false, refusal: { kind: 'http', status: res.status } }\r\n}\r\n\r\n/** Localized description of a refusal for the panel's toast. `fallbackKey` is\r\n * the caller's own \"…upload failed\" string, used for anything that is not a\r\n * size refusal. */\r\nexport function uploadRefusalText(o: UploadOutcome, t: (key: string) => string, fallbackKey: string): string {\r\n if (o.refusal?.kind === 'too-large') {\r\n const limit = o.refusal.limit ?? ''\r\n return t('uploadTooLarge').split('{limit}').join(limit)\r\n }\r\n if (o.refusal !== undefined) return `${t(fallbackKey)} (http ${o.refusal.status})`\r\n return t(fallbackKey)\r\n}\r\n\r\n/** Upload a video's raw bytes over HTTP (MIME in Content-Type, body untouched\r\n * — no base64 inflation that would blow the RPC body limit on large clips). */\r\nexport async function uploadVideo(blob: Blob, mime: string): Promise<UploadOutcome> {\r\n try {\r\n const res = await fetch(VIDEO_UPLOAD_URL, {\r\n method: 'POST',\r\n headers: { 'Content-Type': mime || 'application/octet-stream' },\r\n body: blob,\r\n })\r\n return res.ok ? { ok: true } : await refusedUpload(res)\r\n } catch (e) {\r\n console.warn('dsh-any-background: video upload failed', e)\r\n return { ok: false }\r\n }\r\n}\r\n\r\n/** Upload a wallpaper's raw bytes over HTTP — same streaming model as videos,\r\n * original pixels preserved, zero base64 round-trips. */\r\nexport async function uploadWallpaper(blob: Blob): Promise<UploadOutcome> {\r\n try {\r\n const res = await fetch(WALLPAPER_UPLOAD_URL, {\r\n method: 'POST',\r\n headers: { 'Content-Type': blob.type || 'image/jpeg' },\r\n body: blob,\r\n })\r\n return res.ok ? { ok: true } : await refusedUpload(res)\r\n } catch (e) {\r\n console.warn('dsh-any-background: wallpaper upload failed', e)\r\n return { ok: false }\r\n }\r\n}\r\n\r\n/** Upload a custom font's raw bytes over HTTP; resolves the sniffed MIME on\r\n * success, or a refusal the caller can report (an oversized font used to be\r\n * indistinguishable from a corrupt one). */\r\nexport async function uploadFont(blob: Blob): Promise<UploadOutcome & { mime?: string }> {\r\n try {\r\n const res = await fetch(FONT_UPLOAD_URL, {\r\n method: 'POST',\r\n headers: { 'Content-Type': blob.type || 'application/octet-stream' },\r\n body: blob,\r\n })\r\n if (!res.ok) return await refusedUpload(res)\r\n const data = await res.json().catch(() => null) as { mime?: string } | null\r\n return { ok: true, mime: typeof data?.mime === 'string' ? data.mime : 'font/ttf' }\r\n } catch (e) {\r\n console.warn('dsh-any-background: font upload failed', e)\r\n return { ok: false }\r\n }\r\n}\r\n\r\n/** Remove the stored custom font (server deletes every variant + clears the\r\n * recorded MIME); resolves true once the slot is empty. */\r\nexport async function removeFont(): Promise<boolean> {\r\n const res = await rpcCall('removeFont', {})\r\n return res === true\r\n}\r\n\r\n// ── Wallpaper rotation RPCs ──────────────────────────────────────────────────\r\n\r\nexport interface RotationAddResult { ok: boolean; index?: number; items?: Array<{ file: string; thumb: string }>; error?: string }\r\n\r\n/** Add an image (data URL + small thumbnail) to the server-side rotation pool. */\r\nexport async function rotationAdd(dataUrl: string, thumb: string): Promise<RotationAddResult> {\r\n if (!rpcCallFn) return { ok: false, error: 'rpc not ready' }\r\n try {\r\n const res = await rpcCallFn(rpcEndpoint('rotationAdd'), { dataUrl, thumb })\r\n if (res && res.ok === true) return (res.value ?? { ok: false, error: 'no value' }) as RotationAddResult\r\n return { ok: false, error: (res as { error?: { message?: string } })?.error?.message ?? 'request failed' }\r\n } catch (e) {\r\n return { ok: false, error: e instanceof Error ? e.message : String(e) }\r\n }\r\n}\r\n\r\n/** Remove a rotation item by index. Returns the updated items list. */\r\nexport async function rotationRemove(index: number): Promise<{ ok: boolean; items?: Array<{ file: string; thumb: string }>; error?: string }> {\r\n if (!rpcCallFn) return { ok: false, error: 'rpc not ready' }\r\n try {\r\n const res = await rpcCallFn(rpcEndpoint('rotationRemove'), { index })\r\n if (res && res.ok === true) return (res.value ?? { ok: false, error: 'no value' }) as { ok: boolean; items?: Array<{ file: string; thumb: string }>; error?: string }\r\n return { ok: false, error: (res as { error?: { message?: string } })?.error?.message ?? 'request failed' }\r\n } catch (e) {\r\n return { ok: false, error: e instanceof Error ? e.message : String(e) }\r\n }\r\n}\r\n\r\n/** Activate a rotation item: the server copies its bytes into the wallpaper\r\n * slot and returns the serve URL for immediate display. */\r\nexport async function rotationActivate(index: number): Promise<{ ok: boolean; wallpaperUrl?: string; error?: string }> {\r\n if (!rpcCallFn) return { ok: false, error: 'rpc not ready' }\r\n try {\r\n const res = await rpcCallFn(rpcEndpoint('rotationSet'), { index })\r\n if (res && res.ok === true) return (res.value ?? { ok: false, error: 'no value' }) as { ok: boolean; wallpaperUrl?: string; error?: string }\r\n return { ok: false, error: (res as { error?: { message?: string } })?.error?.message ?? 'request failed' }\r\n } catch (e) {\r\n return { ok: false, error: e instanceof Error ? e.message : String(e) }\r\n }\r\n}\r\n","/**\n * The plugin's ONE vocabulary for host-dependent decisions.\n *\n * Everything downstream asks a QUESTION (\"who owns the guide surface?\", \"which CSS\n * arm applies?\") and gets an answer from the current adapter. No consumer names a\n * release. That is what keeps the per-version folders honest: when 0.1.8 needs a\n * new behaviour, a consumer changes by reading a new adapter field, not by growing\n * another version comparison.\n *\n * @module\n */\nimport { adapterResolved, rHostAdapter } from './release'\nimport type { HostAdapter } from './versions/types'\n\n/** Who should carry the plugin's appearance page on the host's guide surface.\n *\n * `host` — the host's own right Sidebar already presents an appearance page, so\n * the plugin's dsh-better-sidebar page stands down (a second identical\n * card on the same surface).\n * `plugin` — it does not, so the dsh-better-sidebar page registers and the native\n * tab yields to it.\n * `pending` — the verdict has not landed yet (it is a Node round-trip). Callers\n * must NOT treat this as `plugin`: register provisionally and arm a\n * withdrawal, because a brief duplicate is recoverable while a missing\n * page is invisible until someone looks. */\nexport type GuideOwner = 'host' | 'plugin' | 'pending'\n\nexport function sidebarGuideOwner(): GuideOwner {\n if (!adapterResolved()) return 'pending'\n return rHostAdapter().surface.ownsSidebarGuideSurface ? 'host' : 'plugin'\n}\n\n/** The `[data-slot=\"<key>\"]` selectors marking the session header's surfaces.\n * Built from the adapter so a release that adds or deletes an anchor needs no\n * change here — see the `headerSlotKeys` notes in each version folder. */\nexport function headerSlotSelectors(): string[] {\n return rHostAdapter().surface.headerSlotKeys.map(key => `[data-slot=\"${key}\"]`)\n}\n\n/** The current adapter, for callers that need more than one field from it (and to\n * keep the snapshot identity stable across a single render pass). */\nexport function hostAdapter(): HostAdapter {\n return rHostAdapter()\n}\n","/**\n * Header-surface tagging.\n *\n * WHY A RUNTIME TAG IS NEEDED\n * The session-header dropdowns (open-in-app, session-log, Agent Team, the job\n * list, the subagent lineage tree) render their popover through the Menu/tree\n * primitives, which PORTAL the list to `document.body`. A portaled list is not a\n * DOM descendant of the header — no ancestor selector can reach it — and the\n * primitive emits no `id`/`aria-controls` back-link to its anchor either. Pure\n * CSS class matching was the remaining option, but 0.1.7 broke the shapes this\n * plugin relied on: open-in-app moved from in-place to `portal` (so the old\n * `:not(_portal)` discriminator no longer selected it), and the session row menu\n * became a dynamic `sidebar.workspaces.session.menu.item` slot whose rows are no\n * longer guaranteed to include a destructive one.\n *\n * THE SIGNAL\n * The slot renderer stamps every registered slot with `data-slot=\"<key>\"`\n * (ui-renderer `scoped-slots.tsx`). Those anchors live in the header subtree, so\n * the plugin can detect when a header trigger is expanded — which keys identify\n * the header is a per-release fact and comes from the host adapter, not from a\n * hardcoded list here.\n *\n * WHY NOT GEOMETRY\n * A tempting link is the inline position the primitive writes on a portaled list\n * (`style=\"left: …; top: …\"`). It was tried and REJECTED: an `align=\"end\"` list\n * is flush to the trigger's right edge while the trigger itself sits at the far\n * right of the header, so the two boxes often do not overlap horizontally (in\n * the reported DOM the list is at `left:1012` with the trigger near x=1400). Any\n * purely geometric proximity test therefore misses real header menus.\n *\n * THE ACTUAL RULE (structural, no geometry, no timing)\n * A header dropdown can only be open while its trigger reports\n * `aria-expanded=\"true\"`, and opening one is what mounts the popover. So a\n * popover tag is maintained as: \"there is at least one expanded header trigger,\n * AND this popover is not owned by another group\". Popovers are only ever\n * tagged/released on a change of that combined state, which makes the tag\n * self-consistent and idempotent.\n *\n * The one hazard is a popover that is open for an unrelated reason (a composer\n * menu, a hover card) *while* a header trigger stays expanded. Such a popover\n * is not a candidate: it is excluded by `ownsForeignSurface`, which skips any\n * popover carrying markers of a different slider group. In practice header\n * dropdowns are transient (opening one closes the others), so this is a guard\n * rather than the common path.\n *\n * @module\n */\n\nimport { hostAdapter } from './host-compat/capabilities'\n\n/** Marker attribute the stylesheet keys on. */\nexport const HEADER_POPOVER_ATTR = 'data-dsh-any-header-popover'\n\n/** Portaled popovers a header trigger can own. */\nconst POPOVER_SELECTOR = '[role=\"menu\"], [role=\"tree\"], [role=\"dialog\"]'\n\n/** Which session-header slot anchors to watch — supplied by the host adapter,\n * because the set is not the same on every release: 0.1.6-alpha.2 registers a\n * sixth (`.leading`) that neither the line before nor the line after has.\n * Memoised on the array identity, which the adapter keeps stable until the\n * release verdict lands. */\nlet slotAnchorCache: { keys: readonly string[]; selector: string } | null = null\nfunction headerSlotAnchors(): string {\n const keys = hostAdapter().surface.headerSlotKeys\n if (slotAnchorCache === null || slotAnchorCache.keys !== keys) {\n slotAnchorCache = { keys, selector: keys.map(key => `[data-slot=\"${key}\"]`).join(',') }\n }\n return slotAnchorCache.selector\n}\n\n/** Whether any header slot anchor has an expanded trigger. */\nfunction headerTriggerOpen(): boolean {\n for (const anchor of document.querySelectorAll(headerSlotAnchors())) {\n if (anchor.querySelector('[aria-expanded=\"true\"]') !== null) return true\n }\n return false\n}\n\n/** Surfaces that belong to a different slider group and must never be claimed.\n * `_denseList` without `_portal` is the in-place card-side dense menu, an\n * `_ioCard`/`_menu`-classed body-level list belongs elsewhere, and a modal is\n * its own surface. */\nfunction ownsForeignSurface(el: Element): boolean {\n if (el.getAttribute('aria-modal') === 'true') return true\n // A list that is not directly under <body> is an in-place popover owned by\n // whatever subtree it lives in (composer menus), never the header.\n return el.parentElement !== document.body\n}\n\nlet observer: MutationObserver | null = null\nlet raf: number | null = null\n\n/** Recompute tags from the current open state. */\nfunction refreshHeaderPopovers(): void {\n const open = headerTriggerOpen()\n const candidates = [...document.querySelectorAll(POPOVER_SELECTOR)].filter(el => !ownsForeignSurface(el))\n if (!open) {\n for (const el of document.querySelectorAll(`[${HEADER_POPOVER_ATTR}]`)) {\n el.removeAttribute(HEADER_POPOVER_ATTR)\n }\n return\n }\n // A header dropdown is open: claim body-level popovers, releasing any that\n // stopped being candidates (detached, or re-classified as foreign).\n for (const el of candidates) el.setAttribute(HEADER_POPOVER_ATTR, '')\n for (const el of document.querySelectorAll(`[${HEADER_POPOVER_ATTR}]`)) {\n if (!candidates.includes(el)) el.removeAttribute(HEADER_POPOVER_ATTR)\n }\n}\n\nfunction schedule(): void {\n if (raf !== null) return\n raf = window.requestAnimationFrame(() => {\n raf = null\n refreshHeaderPopovers()\n })\n}\n\n/** Start tagging. Returns a teardown that stops observing and clears markings. */\nexport function startHeaderPopoverTagging(): () => void {\n if (typeof MutationObserver === 'undefined' || typeof document === 'undefined') return () => {}\n refreshHeaderPopovers()\n observer = new MutationObserver(schedule)\n // Attribute + childList across the body subtree: a popover mounting and an\n // `aria-expanded` flipping both land here. Character data is irrelevant.\n observer.observe(document.body, {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: ['aria-expanded'],\n })\n return () => {\n observer?.disconnect()\n observer = null\n if (raf !== null) { window.cancelAnimationFrame(raf); raf = null }\n for (const el of document.querySelectorAll(`[${HEADER_POPOVER_ATTR}]`)) {\n el.removeAttribute(HEADER_POPOVER_ATTR)\n }\n }\n}\n","/**\r\n * Read a chosen image file as a data URL WITHOUT re-encoding: the original\r\n * pixels are kept as-is (no canvas downscale / JPEG re-compression), so the\r\n * wallpaper is stored and displayed at full fidelity. The tradeoff is a larger\r\n * payload over the RPC channel and on disk for big images.\r\n */\r\nexport function readImg(file: File, cb: (url: string | null) => void): void {\r\n const r = new FileReader()\r\n r.onerror = () => cb(null)\r\n r.onload = () => cb(r.result as string)\r\n r.readAsDataURL(file)\r\n}\r\n\r\n/** Promised readImg variant for async flows. */\r\nexport function readImgAsync(file: File): Promise<string | null> {\r\n return new Promise(resolve => readImg(file, resolve))\r\n}\r\n\r\n/** Blob → data URL (used when a local asset must be embedded, e.g. theme export). */\r\nexport function blobToDataUrl(blob: Blob): Promise<string> {\r\n return new Promise<string>((resolve, reject) => {\r\n const fr = new FileReader()\r\n fr.onload = () => resolve(fr.result as string)\r\n fr.onerror = () => reject(fr.error)\r\n fr.readAsDataURL(blob)\r\n })\r\n}\r\n\r\n// Shared decoded-image cache. The boot path decodes the same wallpaper URL up\r\n// to four times (palette extract, brightness verdict, low-res capture,\r\n// intrinsic size); memoizing the decoded element turns those into one decode.\r\nconst IMG_CACHE_MAX = 6\r\nconst imgCache = new Map<string, Promise<HTMLImageElement | null>>()\r\n\r\n/** Decode an image URL once and share the element across callers (LRU-capped). */\r\nexport function loadImage(url: string): Promise<HTMLImageElement | null> {\r\n const hit = imgCache.get(url)\r\n if (hit) {\r\n imgCache.delete(url)\r\n imgCache.set(url, hit)\r\n return hit\r\n }\r\n const p = new Promise<HTMLImageElement | null>(resolve => {\r\n const img = new Image()\r\n img.onerror = () => resolve(null)\r\n img.onload = () => resolve(img)\r\n img.src = url\r\n })\r\n imgCache.set(url, p)\r\n while (imgCache.size > IMG_CACHE_MAX) {\r\n const oldest = imgCache.keys().next().value\r\n if (oldest !== undefined) imgCache.delete(oldest)\r\n }\r\n return p\r\n}\r\n\r\n/** Build a small JPEG thumbnail (rotation-pool picker preview). Resolves null\r\n * when the image cannot be decoded. */\r\nexport function makeThumb(dataUrl: string, maxSide = 96): Promise<string | null> {\r\n return new Promise(resolve => {\r\n const img = new Image()\r\n img.onerror = () => resolve(null)\r\n img.onload = () => {\r\n try {\r\n const iw = img.naturalWidth || img.width\r\n const ih = img.naturalHeight || img.height\r\n if (iw <= 0 || ih <= 0) { resolve(null); return }\r\n const k = Math.min(1, maxSide / Math.max(iw, ih))\r\n const c = document.createElement('canvas')\r\n c.width = Math.max(1, Math.round(iw * k))\r\n c.height = Math.max(1, Math.round(ih * k))\r\n const g = c.getContext('2d')\r\n if (!g) { resolve(null); return }\r\n g.drawImage(img, 0, 0, c.width, c.height)\r\n resolve(c.toDataURL('image/jpeg', 0.72))\r\n } catch {\r\n resolve(null)\r\n }\r\n }\r\n img.src = dataUrl\r\n })\r\n}\r\n","import type { BgState, ColorPalette } from '../types'\r\nimport { loadImage } from './image'\r\n\r\n// The wheel works in HSV end to end; storage and genTokens expect HSL, so\r\n// setColor converts HSV → HSL at the boundary and sectionInject converts the\r\n// stored HSL → HSV for the initial wheel props. Conversions never stack.\r\n\r\nexport function hsvToHsl(h: number, s: number, v: number): [number, number, number] {\r\n const l = v * (1 - s / 2)\r\n const sl = l === 0 || l === 1 ? 0 : (v - l) / Math.min(l, 1 - l)\r\n return [h, sl, l]\r\n}\r\n\r\nexport function hslToHsv(h: number, s: number, l: number): [number, number, number] {\r\n const v = l + s * Math.min(l, 1 - l)\r\n const sv = v === 0 ? 0 : 2 * (1 - l / v)\r\n return [h, sv, v]\r\n}\r\n\r\n/** Format an RGB triple as a lowercase hex string. Channels are rounded: some\r\n * callers feed float channels and a fractional byte would produce invalid\r\n * hex. */\r\nexport function rgbToHex(rgb: [number, number, number]): string {\r\n return '#' + rgb.map(v => Math.round(v).toString(16).padStart(2, '0')).join('')\r\n}\r\n\r\nlet tokensCacheKey = ''\r\nlet tokensCache: { colorScheme: 'light' | 'dark'; tokens: Record<string, string> } | null = null\r\n\r\n/**\r\n * Memoized token generation: the same (hue, sat, lit, scheme) input always\r\n * yields the same token set, and applyWp / applyCustomTokens /\r\n * applySettingsOverrides call this repeatedly (slider drags, viewport\r\n * re-applies), so cache the last result and skip the 30+ hsl() string builds\r\n * when nothing changed. The optional scheme forces the palette direction\r\n * (light/dark) independently of the color's own lightness.\r\n */\r\nexport function genTokens(hue: number, sat: number, lit: number, scheme?: 'light' | 'dark'): { colorScheme: 'light' | 'dark'; tokens: Record<string, string> } {\r\n const key = `${hue}|${sat}|${lit}|${scheme ?? 'auto'}`\r\n if (tokensCacheKey === key && tokensCache) return tokensCache\r\n tokensCacheKey = key\r\n tokensCache = buildTokens(hue, sat, lit, scheme)\r\n return tokensCache\r\n}\r\n\r\nfunction buildTokens(hue: number, sat: number, lit: number, scheme?: 'light' | 'dark'): { colorScheme: 'light' | 'dark'; tokens: Record<string, string> } {\r\n // `scheme ?? lit < 0.55` would hand back the STRING 'light' (truthy) and\r\n // route both forced directions into the dark branch — compare explicitly.\r\n const dark = scheme !== undefined ? scheme === 'dark' : lit < 0.55\r\n // Every token is an offset around the base lightness, so a scheme that\r\n // contradicts the pick's band (a forced dark over a light color) would\r\n // build \"dark\" surfaces that stay light. Mirror the lightness into the\r\n // target band instead — hue/saturation carry over, the stored pick itself\r\n // is untouched (this is a display-time remap, not a config change).\r\n if (scheme !== undefined && (lit < 0.55) !== dark) {\r\n lit = dark\r\n ? Math.min(0.44, Math.max(0.14, 1 - lit))\r\n : Math.max(0.6, Math.min(0.88, 1 - lit))\r\n }\r\n const h = (d: number) => ((hue + d) % 360 + 360) % 360\r\n const s = (d: number) => Math.max(0, Math.min(1, sat + d))\r\n const l = (d: number) => Math.max(0, Math.min(1, lit + d))\r\n const hsl = (hh: number, ss: number, ll: number) => `hsl(${Math.round(hh)},${Math.round(ss * 100)}%,${Math.round(ll * 100)}%)`\r\n const rgba = (hh: number, ss: number, ll: number, a: number) =>\r\n `hsla(${Math.round(hh)},${Math.round(ss * 100)}%,${Math.round(ll * 100)}%,${a})`\r\n\r\n if (dark) {\r\n return {\r\n colorScheme: 'dark',\r\n tokens: {\r\n '--dsw-alias-bg-base': hsl(h(0), s(0), l(-0.04)),\r\n '--dsw-alias-bg-layer-1': hsl(h(0), s(0), l(0.02)),\r\n '--dsw-alias-bg-layer-2': hsl(h(0), s(0), l(0.07)),\r\n '--dsw-alias-bg-layer-3': hsl(h(0), s(-0.05), l(0.12)),\r\n '--dsw-alias-bg-overlay': hsl(h(0), s(-0.05), l(0.12)),\r\n '--dsw-alias-bg-module-platform': hsl(h(0), s(0), l(0.05)),\r\n '--dsw-alias-bg-multi-select': hsl(h(0), s(0), l(0.1)),\r\n '--dsw-alias-bg-skeleton': 'rgba(255,255,255,0.08)',\r\n '--dsw-alias-border-l1': rgba(h(0), s(-0.1), l(0.18), 0.12),\r\n '--dsw-alias-border-l2': rgba(h(0), s(-0.1), l(0.22), 0.22),\r\n '--dsw-alias-border-l3': 'rgba(255,255,255,0.16)',\r\n '--dsw-alias-border-l4': 'rgba(255,255,255,0.2)',\r\n '--dsw-alias-border-inverted': 'rgba(255,255,255,0.06)',\r\n '--dsw-alias-label-primary': hsl(0, 0, 1),\r\n '--dsw-alias-label-secondary': 'rgba(255,255,255,0.85)',\r\n '--dsw-alias-label-tertiary': 'rgba(255,255,255,0.7)',\r\n // Placeholder/dim hint — deliberately weaker than the text tiers so a\r\n // placeholder reads as a hint, never as real input.\r\n '--dsw-alias-label-caption': 'rgba(255,255,255,0.5)',\r\n '--dsw-alias-label-dimmed': 'rgba(255,255,255,0.35)',\r\n '--dsw-alias-label-quaternary': 'rgba(255,255,255,0.25)',\r\n '--dsw-alias-label-primary-dimmed': 'rgba(255,255,255,0.92)',\r\n '--dsw-alias-label-primary-foreground': hsl(0, 0, 1),\r\n // Inverted label sits on a light brand/contrast/badge surface in dark\r\n // mode, so it must be dark ink, not white.\r\n '--dsw-alias-label-primary-inverted': hsl(h(0), s(0.08), Math.min(l(0.06), 0.16)),\r\n '--dsw-alias-label-primary-bluish': hsl(0, 0, 1),\r\n '--dsw-alias-brand-primary': hsl(h(0), s(0.1), Math.max(l(0.2), 0.5)),\r\n '--dsw-alias-brand-text': l(0.2) > 0.6 ? '#000' : '#fff',\r\n '--dsw-alias-button-primary-fill': hsl(h(0), s(0.1), Math.max(l(0.2), 0.5)),\r\n '--dsw-alias-button-primary-hover': hsl(h(0), s(0.1), Math.max(l(0.28), 0.58)),\r\n '--dsw-alias-button-primary-dimmed': hsl(h(0), s(0), l(0.07)),\r\n '--dsw-alias-button-elevated-fill': hsl(h(0), s(0), l(0.04)),\r\n '--dsw-alias-button-floating-fill': hsl(h(0), s(0), l(0.02)),\r\n '--dsw-alias-button-floating-hover': hsl(h(0), s(0), l(0.1)),\r\n '--dsw-alias-button-tool-bar-fill': 'rgba(255,255,255,0.08)',\r\n '--dsw-alias-button-tool-bar-hover': 'rgba(255,255,255,0.12)',\r\n '--dsw-alias-button-ghost-active-fill': hsl(h(0), s(0), l(0.06)),\r\n '--dsw-alias-button-ghost-active-border': 'rgba(255,255,255,0.16)',\r\n '--dsw-alias-button-ghost-active-hover': hsl(h(0), s(0), l(0.09)),\r\n '--dsw-alias-button-info-fill': '#679efe',\r\n '--dsw-alias-button-info-hover': '#4176e6',\r\n '--dsw-alias-button-contrast-fill': hsl(0, 0, 1),\r\n '--dsw-alias-interactive-bg-hover': rgba(h(0), s(0), Math.max(l(0.15), 0.4), 0.12),\r\n '--dsw-alias-interactive-bg-hover-solid': rgba(h(0), s(0), Math.max(l(0.15), 0.4), 0.16),\r\n '--dsw-alias-interactive-bg-hover-accent': 'rgba(255,255,255,0.24)',\r\n '--dsw-alias-interactive-bg-hover-danger': 'rgba(242,90,90,0.15)',\r\n '--dsw-alias-interactive-bg-active': rgba(h(0), s(0), Math.max(l(0.15), 0.4), 0.2),\r\n '--dsw-alias-markdown-code-block': hsl(h(0), s(0), l(-0.06)),\r\n '--dsw-alias-markdown-code-block-banner': hsl(h(0), s(0), l(-0.02)),\r\n '--dsw-alias-markdown-inline-code': hsl(h(0), s(0), l(0.04)),\r\n '--dsw-alias-markdown-placeholder': hsl(h(0), s(0), l(-0.02)),\r\n '--dsw-alias-markdown-tag': hsl(h(0), s(0), l(0.05)),\r\n '--dsw-alias-markdown-citation': hsl(h(0), s(0), l(0.06)),\r\n '--dsw-alias-markdown-code-segment-selected': hsl(h(0), s(0), l(0.05)),\r\n '--dsw-alias-markdown-code-segment-unselected': hsl(h(0), s(0), l(-0.05)),\r\n '--dsw-alias-state-error-primary': '#ff5c72',\r\n '--dsw-alias-state-error-secondary': '#ff8aa0',\r\n '--dsw-alias-state-success-primary': '#3ddc84',\r\n '--dsw-alias-state-success-secondary': '#69eea4',\r\n // Badge tertiary tokens are the static dark surfaces the UI draws\r\n // over (trajectory tool/context badges, connection pill, plan chip):\r\n // aligning them with the native dark 800/900 steps keeps light fix label\r\n // text readable instead of tint-same-as-background (issue #9).\r\n '--dsw-alias-state-success-tertiary': '#233c2c',\r\n '--dsw-alias-state-warn-primary': '#ffb347',\r\n '--dsw-alias-state-warn-secondary': '#ffc980',\r\n '--dsw-alias-state-warn-tertiary': '#27241f',\r\n '--dsw-alias-state-warn-label': '#dd8629',\r\n '--dsw-alias-state-business-primary': '#679efe',\r\n '--dsw-alias-state-business-tertiary': '#34415b',\r\n '--dsw-specific-sidebar-fill': hsl(h(0), s(0), l(-0.06)),\r\n '--dsw-specific-sidebar-nav-item-active': hsl(h(0), s(0), l(0.04)),\r\n '--dsw-specific-sidebar-nav-item-hover': hsl(h(0), s(0), l(0)),\r\n '--dsw-specific-input-major': hsl(h(0), s(0), l(0.02)),\r\n '--dsw-specific-menu': hsl(h(0), s(0), l(0.08)),\r\n '--dsw-specific-bubble': hsl(h(0), s(0), l(0.03)),\r\n '--dsw-specific-bubble-highlight': hsl(h(0), s(0), l(0.08)),\r\n '--dsw-specific-selector': hsl(h(0), s(0), l(0.05)),\r\n '--dsw-specific-login-input': hsl(h(0), s(0), l(0.03)),\r\n '--dsw-specific-tip': hsl(h(0), s(0), l(0.05)),\r\n '--dsw-alias-toast-bg': hsl(h(0), s(0), l(0.08)),\r\n '--dsw-alias-tooltip-bg': hsl(h(0), s(0), l(0.08)),\r\n '--dsw-alias-scrollbar-bg-l1': hsl(h(0), s(-0.05), l(0.12)),\r\n '--dsw-alias-scrollbar-bg-l2': hsl(h(0), s(-0.05), l(0.16)),\r\n '--dsw-alias-scrollbar-hover-l1': hsl(h(0), s(-0.05), l(0.22)),\r\n '--dsw-alias-scrollbar-hover-l2': hsl(h(0), s(-0.05), l(0.22)),\r\n },\r\n }\r\n }\r\n return {\r\n colorScheme: 'light',\r\n tokens: {\r\n '--dsw-alias-bg-base': hsl(h(0), s(-0.08), l(0.03)),\r\n '--dsw-alias-bg-layer-1': hsl(h(0), s(-0.12), l(0.07)),\r\n '--dsw-alias-bg-layer-2': hsl(h(0), s(-0.1), l(-0.03)),\r\n '--dsw-alias-bg-layer-3': hsl(h(0), s(-0.08), l(-0.09)),\r\n '--dsw-alias-bg-overlay': hsl(h(0), s(-0.12), l(0.08)),\r\n '--dsw-alias-border-l1': rgba(h(0), s(-0.15), l(-0.35), 0.18),\r\n '--dsw-alias-border-l2': rgba(h(0), s(-0.15), l(-0.35), 0.3),\r\n '--dsw-alias-label-primary': hsl(0, 0, 0),\r\n '--dsw-alias-label-secondary': 'rgba(0,0,0,0.85)',\r\n '--dsw-alias-label-tertiary': 'rgba(0,0,0,0.7)',\r\n // Placeholder/dim hint — deliberately weaker than the text tiers so a\r\n // placeholder reads as a hint, never as real input.\r\n '--dsw-alias-label-caption': 'rgba(0,0,0,0.5)',\r\n '--dsw-alias-label-dimmed': 'rgba(0,0,0,0.35)',\r\n '--dsw-alias-label-quaternary': 'rgba(0,0,0,0.25)',\r\n '--dsw-alias-brand-primary': hsl(h(0), s(0.05), Math.min(l(-0.18), 0.45)),\r\n '--dsw-alias-brand-text': '#fff',\r\n '--dsw-alias-button-primary-hover': hsl(h(0), s(0.05), Math.min(l(-0.12), 0.5)),\r\n '--dsw-alias-button-primary-dimmed': hsl(h(0), s(-0.1), l(-0.03)),\r\n '--dsw-alias-button-elevated-fill': hsl(h(0), s(-0.1), l(0.1)),\r\n '--dsw-alias-button-floating-hover': hsl(h(0), s(-0.1), l(0.16)),\r\n '--dsw-alias-interactive-bg-hover': rgba(h(0), s(0), l(-0.3), 0.08),\r\n '--dsw-alias-interactive-bg-active': rgba(h(0), s(0), l(-0.3), 0.14),\r\n '--dsw-alias-markdown-code-block': hsl(h(0), s(-0.1), l(-0.03)),\r\n '--dsw-alias-markdown-inline-code': hsl(h(0), s(-0.08), l(0.04)),\r\n '--dsw-specific-sidebar-fill': hsl(h(0), s(-0.1), l(-0.03)),\r\n '--dsw-specific-sidebar-nav-item-active': hsl(h(0), s(-0.08), l(0.05)),\r\n '--dsw-specific-sidebar-nav-item-hover': hsl(h(0), s(-0.12), l(0)),\r\n '--dsw-specific-input-major': hsl(h(0), s(-0.12), l(0.1)),\r\n '--dsw-specific-menu': hsl(h(0), s(-0.12), l(0.15)),\r\n '--dsw-alias-scrollbar-bg-l1': hsl(h(0), s(-0.1), l(-0.08)),\r\n '--dsw-alias-scrollbar-bg-l2': hsl(h(0), s(-0.08), l(-0.12)),\r\n '--dsw-alias-scrollbar-hover-l1': hsl(h(0), s(-0.08), l(-0.16)),\r\n '--dsw-alias-scrollbar-hover-l2': hsl(h(0), s(-0.08), l(-0.16)),\r\n },\r\n }\r\n}\r\n\r\nexport function toRgba(c: string, a: number): string {\r\n const hx = /^#([0-9a-f]{3}|[0-9a-f]{6})$/i.exec(c.trim())\r\n if (hx) { let d = hx[1]!; if (d.length === 3) d = d.split('').map(x => x + x).join(''); const n = parseInt(d, 16); return `rgba(${(n >> 16) & 255},${(n >> 8) & 255},${n & 255},${a})` }\r\n const rgb = /^rgba?\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)(?:\\s*,\\s*([\\d.]+))?\\s*\\)$/i.exec(c.trim())\r\n if (rgb) return `rgba(${rgb[1]},${rgb[2]},${rgb[3]},${a})`\r\n const hsl = /^hsla?\\(\\s*([\\d.]+)\\s*,\\s*([\\d.]+)%\\s*,\\s*([\\d.]+)%/i.exec(c.trim())\r\n if (hsl) return `hsla(${hsl[1]},${hsl[2]}%,${hsl[3]}%,${a})`\r\n return c.trim()\r\n}\r\n\r\nexport function rgbToHsl(r: number, g: number, b: number): [number, number, number] {\r\n const rn = r / 255, gn = g / 255, bn = b / 255\r\n const max = Math.max(rn, gn, bn), min = Math.min(rn, gn, bn)\r\n const l = (max + min) / 2\r\n if (max === min) return [0, 0, l]\r\n const d = max - min\r\n const s = l > 0.5 ? d / (2 - max - min) : d / (max + min)\r\n let h: number\r\n if (max === rn) h = ((gn - bn) / d) % 6\r\n else if (max === gn) h = (bn - rn) / d + 2\r\n else h = (rn - gn) / d + 4\r\n h *= 60\r\n if (h < 0) h += 360\r\n return [h, s, l]\r\n}\r\n\r\n// Wallpaper color extraction: decode the cached data URL → crop the visible\r\n// (framed) region → downsample to a 64×64 canvas → quantize pixels into 4-bit\r\n// RGB buckets → discard near-gray / near-black / near-white pixels → pick the\r\n// most populous vivid bucket (count × saturation bias) → average its members →\r\n// RGB→HSL → clamp lightness into a band that keeps the light/dark scheme\r\n// decision unambiguous. Purely client-side and memory-bounded.\r\n\r\nconst EXTRACT_SIDE = 64\r\n\r\ninterface Bucket { count: number; r: number; g: number; b: number; s: number }\r\n\r\nfunction bucketsToHsl(b: Bucket): [number, number, number] {\r\n return rgbToHsl(b.r / b.count, b.g / b.count, b.b / b.count)\r\n}\r\n\r\nfunction extractWallpaperPalette(dataUrl: string, bgState: BgState): Promise<ColorPalette | null> {\r\n return loadImage(dataUrl).then(img => {\r\n if (!img) return null\r\n try {\r\n const iw = img.naturalWidth || img.width\r\n const ih = img.naturalHeight || img.height\r\n const bg = bgState\r\n let sx = 0, sy = 0, sw = iw, sh = ih\r\n if (bg.iw === iw && bg.ih === ih && bg.iw > 0) {\r\n const fit = Math.min(window.innerWidth / iw, window.innerHeight / ih)\r\n const w = iw * fit * bg.zoom\r\n const h = ih * fit * bg.zoom\r\n // bg.x/bg.y are the image center's fractional viewport point, so the\r\n // image's top-left sits at (px, py) in viewport coordinates — the\r\n // same offset wallpaper.ts writes into background-position. The\r\n // visible source band is viewport [0, vw] mapped to source\r\n // [-px, vw - px], clipped to the image.\r\n const px = bg.x * window.innerWidth - w / 2\r\n const py = bg.y * window.innerHeight - h / 2\r\n sx = Math.max(0, -px)\r\n sy = Math.max(0, -py)\r\n sw = Math.min(iw - sx, window.innerWidth - px - sx)\r\n sh = Math.min(ih - sy, window.innerHeight - py - sy)\r\n if (sw <= 0 || sh <= 0) { sx = 0; sy = 0; sw = iw; sh = ih }\r\n }\r\n const c = document.createElement('canvas')\r\n c.width = EXTRACT_SIDE; c.height = EXTRACT_SIDE\r\n const g = c.getContext('2d', { willReadFrequently: true })!\r\n g.drawImage(img, sx, sy, sw, sh, 0, 0, EXTRACT_SIDE, EXTRACT_SIDE)\r\n const px = g.getImageData(0, 0, EXTRACT_SIDE, EXTRACT_SIDE).data\r\n const counts = new Uint32Array(4096)\r\n const sums = new Float64Array(4096 * 3)\r\n let totalLum = 0\r\n let sampled = 0\r\n for (let i = 0; i < px.length; i += 4) {\r\n const r = px[i], gg = px[i + 1], b = px[i + 2]\r\n const max = Math.max(r, gg, b), min = Math.min(r, gg, b)\r\n const v = max / 255\r\n const s = max === 0 ? 0 : (max - min) / max\r\n // Include all non-extreme pixels in luminance; only vivid pixels in\r\n // palette buckets so we don't theme around gray/black/white.\r\n // Rec.709 luma — the SAME measure analyzeFrameDark uses for the\r\n // brightness verdict, so the extracted lightness band and the\r\n // verdict can never disagree on a saturated frame.\r\n totalLum += (0.2126 * r + 0.7152 * gg + 0.0722 * b) / 255\r\n sampled++\r\n if (s < 0.08 || v < 0.12 || v > 0.97) continue\r\n const key = ((r >> 4) << 8) | ((gg >> 4) << 4) | (b >> 4)\r\n counts[key]++\r\n sums[key * 3] += r; sums[key * 3 + 1] += gg; sums[key * 3 + 2] += b\r\n }\r\n const buckets: Bucket[] = []\r\n for (let k = 0; k < 4096; k++) {\r\n if (counts[k] === 0) continue\r\n buckets.push({\r\n count: counts[k],\r\n r: sums[k * 3],\r\n g: sums[k * 3 + 1],\r\n b: sums[k * 3 + 2],\r\n s: (Math.max(sums[k * 3], sums[k * 3 + 1], sums[k * 3 + 2]) - Math.min(sums[k * 3], sums[k * 3 + 1], sums[k * 3 + 2])) / Math.max(sums[k * 3], sums[k * 3 + 1], sums[k * 3 + 2]) || 0,\r\n })\r\n }\r\n if (buckets.length === 0) { return null }\r\n // Sort by vivid-weighted count.\r\n buckets.sort((a, b) => b.count * (0.5 + b.s) - a.count * (0.5 + a.s))\r\n const primary = bucketsToHsl(buckets[0]!)\r\n const primaryHue = primary[0]\r\n // Secondary: next bucket that is reasonably separated from primary.\r\n let secondary = primary\r\n for (const b of buckets.slice(1)) {\r\n const [h] = bucketsToHsl(b)\r\n const sep = Math.abs(((h - primaryHue + 540) % 360) - 180)\r\n if (sep > 30) { secondary = bucketsToHsl(b); break }\r\n }\r\n // Tertiary: complementary-ish hue based on primary if no good secondary.\r\n let tertiary: [number, number, number] = [((primaryHue + 180) % 360), Math.min(0.7, primary[1]), Math.min(0.7, primary[2])]\r\n for (const b of buckets.slice(1)) {\r\n const [h] = bucketsToHsl(b)\r\n const sep = Math.abs(((h - primaryHue + 540) % 360) - 180)\r\n if (sep > 90 && sep < 150) { tertiary = bucketsToHsl(b); break }\r\n }\r\n // Surface: neutralized primary (very low saturation).\r\n const surface: [number, number, number] = [primaryHue, Math.min(0.06, primary[1] * 0.3), primary[2]]\r\n // Auto light/dark: use the average luminance of the whole image so a\r\n // bright wallpaper naturally drives a light scheme and vice-versa.\r\n const luminance = sampled > 0 ? totalLum / sampled : primary[2]\r\n // Snap primary lightness out of the ambiguous middle band.\r\n const autoDark = luminance < 0.5\r\n const lc = autoDark ? Math.min(0.44, Math.max(0.2, primary[2])) : Math.max(0.6, Math.min(0.82, primary[2]))\r\n primary[2] = lc\r\n return {\r\n primary: [primary[0], Math.min(0.9, Math.max(0.15, primary[1])), primary[2]],\r\n secondary: [secondary[0], Math.min(0.85, Math.max(0.2, secondary[1])), Math.min(0.75, Math.max(0.35, secondary[2]))],\r\n tertiary: [tertiary[0], Math.min(0.8, Math.max(0.2, tertiary[1])), Math.min(0.7, Math.max(0.35, tertiary[2]))],\r\n surface,\r\n luminance,\r\n }\r\n } catch {\r\n return null\r\n }\r\n })\r\n}\r\n\r\n/** Backward-compatible single-color extraction: returns the primary HSL. */\r\nexport async function extractWallpaperColor(dataUrl: string, bgState: BgState): Promise<[number, number, number] | null> {\r\n const palette = await extractWallpaperPalette(dataUrl, bgState)\r\n return palette ? palette.primary : null\r\n}\r\n\r\n// One-shot frame brightness analysis: called only when a generated background\r\n// is switched (from its captured snapshot), never from the animation loop.\r\n// Decode the frame, downsample to a 32×32 canvas, average Rec.709 luma.\r\n// Dark frame → light fonts, light frame → dark fonts.\r\n\r\nconst ANALYZE_SIDE = 32\r\n\r\n/** Analyze a captured frame's average luminance. Resolves true when the frame\r\n * reads dark (use white fonts), false when light (use black fonts), or null\r\n * when the frame cannot be decoded. */\r\nexport function analyzeFrameDark(dataUrl: string): Promise<boolean | null> {\r\n return loadImage(dataUrl).then(img => {\r\n if (!img) return null\r\n try {\r\n const c = document.createElement('canvas')\r\n c.width = ANALYZE_SIDE; c.height = ANALYZE_SIDE\r\n const g = c.getContext('2d', { willReadFrequently: true })!\r\n g.drawImage(img, 0, 0, ANALYZE_SIDE, ANALYZE_SIDE)\r\n const px = g.getImageData(0, 0, ANALYZE_SIDE, ANALYZE_SIDE).data\r\n let lum = 0\r\n const count = px.length / 4\r\n for (let i = 0; i < px.length; i += 4) {\r\n lum += 0.2126 * px[i]! + 0.7152 * px[i + 1]! + 0.0722 * px[i + 2]!\r\n }\r\n return lum / count / 255 < 0.5\r\n } catch {\r\n return null\r\n }\r\n })\r\n}\r\n\r\n/** HSL (h 0-360, s/l 0-1) → RGB (0-255 integers). */\r\nexport function hslToRgb(h: number, s: number, l: number): [number, number, number] {\r\n const c = (1 - Math.abs(2 * l - 1)) * s\r\n const hp = h / 60\r\n const x = c * (1 - Math.abs((hp % 2) - 1))\r\n let r = 0, g = 0, b = 0\r\n if (hp < 1) { r = c; g = x }\r\n else if (hp < 2) { r = x; g = c }\r\n else if (hp < 3) { g = c; b = x }\r\n else if (hp < 4) { g = x; b = c }\r\n else if (hp < 5) { r = x; b = c }\r\n else { r = c; b = x }\r\n const m = l - c / 2\r\n return [Math.round((r + m) * 255), Math.round((g + m) * 255), Math.round((b + m) * 255)]\r\n}\r\n","import type { GeneratedBgParams, MeshGradientParams, ShaderParams, PatternParams } from '../types'\r\n\r\n// The live full-screen canvas renders at a fraction of the CSS size — it sits\r\n// behind frosted/translucent UI anyway, so ~0.5–0.6px backing keeps it looking\r\n// sharp while drastically cutting fill/gradient cost per frame.\r\nconst RENDER_SCALE = 0.55\r\nconst FPS = 30\r\nconst FRAME_MS = 1000 / FPS\r\n\r\nexport interface LiveBgController {\r\n canvas: HTMLCanvasElement\r\n stop: () => void\r\n pause: () => void\r\n resume: () => void\r\n snapshot: () => string\r\n}\r\n\r\nfunction newRaf(canvas: HTMLCanvasElement, draw: () => void): { stop: () => void; pause: () => void; resume: () => void } {\r\n canvas.dataset.dshAnyCanvas = '1'\r\n let running = true\r\n let paused = false\r\n let rafId = 0\r\n let last = 0\r\n // Draw the very first frame synchronously so snapshot() right after creation\r\n // already yields a real frame (used by the preview, palette and export).\r\n draw()\r\n // Reduced-motion preference: keep the static first frame, never start the loop.\r\n if (typeof window.matchMedia === 'function' && window.matchMedia('(prefers-reduced-motion: reduce)').matches) {\r\n return { stop: () => { running = false }, pause: () => undefined, resume: () => undefined }\r\n }\r\n const loop = (ts: number) => {\r\n if (!running || paused) return\r\n if (ts - last >= FRAME_MS) { last = ts; draw() }\r\n rafId = requestAnimationFrame(loop)\r\n }\r\n rafId = requestAnimationFrame(loop)\r\n return {\r\n stop: () => { running = false; cancelAnimationFrame(rafId) },\r\n pause: () => { paused = true; cancelAnimationFrame(rafId) },\r\n resume: () => {\r\n if (!running || !paused) return\r\n paused = false\r\n last = 0\r\n rafId = requestAnimationFrame(loop)\r\n },\r\n }\r\n}\r\n\r\nfunction createCanvas(): HTMLCanvasElement {\r\n const c = document.createElement('canvas')\r\n c.style.cssText = 'position:absolute;inset:0;width:100%;height:100%;object-fit:cover;'\r\n return c\r\n}\r\n\r\nfunction liveSize(): { w: number; h: number } {\r\n const dpr = Math.min(window.devicePixelRatio || 1, 1.5)\r\n const w = Math.max(320, Math.ceil(window.innerWidth * dpr * RENDER_SCALE))\r\n const h = Math.max(180, Math.ceil(window.innerHeight * dpr * RENDER_SCALE))\r\n return { w, h }\r\n}\r\n\r\nfunction fitLiveCanvas(c: HTMLCanvasElement): void {\r\n const { w, h } = liveSize()\r\n if (c.width !== w || c.height !== h) { c.width = w; c.height = h }\r\n}\r\n\r\n// ── Deterministic seeded RNG ─────────────────────────────────────────────────\r\nfunction createRng(seed: number) {\r\n let s = seed > 0 ? seed : 1\r\n return () => {\r\n s ^= s << 13\r\n s ^= s >>> 17\r\n s ^= s << 5\r\n return (s >>> 0) / 0xffffffff\r\n }\r\n}\r\n\r\n// ── Seeded 2D noise (for canvas mesh / pattern motion) ──────────────────────\r\nfunction createNoise(seed: number) {\r\n const rng = createRng(seed)\r\n const perm: number[] = []\r\n for (let i = 0; i < 256; i++) perm[i] = i\r\n for (let i = 255; i > 0; i--) {\r\n const j = Math.floor(rng() * (i + 1))\r\n const t = perm[i]!; perm[i] = perm[j]!; perm[j] = t\r\n }\r\n for (let i = 0; i < 256; i++) perm[i + 256] = perm[i]!\r\n function fade(t: number) { return t * t * t * (t * (t * 6 - 15) + 10) }\r\n function lerp(a: number, b: number, t: number) { return a + (b - a) * t }\r\n function grad(hash: number, x: number, y: number) {\r\n const h = hash & 15\r\n const u = h < 8 ? x : y\r\n const v = h < 4 ? y : (h === 12 || h === 14) ? x : 0\r\n return ((h & 1) === 0 ? u : -u) + ((h & 2) === 0 ? v : -v)\r\n }\r\n return (x: number, y: number) => {\r\n const X = Math.floor(x) & 255\r\n const Y = Math.floor(y) & 255\r\n x -= Math.floor(x)\r\n y -= Math.floor(y)\r\n const u = fade(x)\r\n const v = fade(y)\r\n const A = perm[X]! + Y\r\n return lerp(\r\n lerp(grad(perm[A]!, x, y), grad(perm[A! + 1]!, x - 1, y), u),\r\n lerp(grad(perm[A! + 256]!, x, y - 1), grad(perm[A! + 257]!, x - 1, y - 1), u),\r\n v,\r\n )\r\n }\r\n}\r\n\r\n// ── Mesh gradient (animated) ──────────────────────────────────────────────────\r\nexport function createMeshGradient(params: MeshGradientParams, canvas?: HTMLCanvasElement): LiveBgController {\r\n const c = canvas ?? createCanvas()\r\n fitLiveCanvas(c)\r\n const g = c.getContext('2d', { alpha: false })!\r\n const rng = createRng(params.seed)\r\n const noise = createNoise(params.seed)\r\n const dark = rng() < 0.5\r\n const baseHue = Math.round(rng() * 360)\r\n const count = Math.round(7 + 9 * params.scale * params.intensity)\r\n const blobs: { x: number; y: number; r: number; hx: number; hy: number; speed: number; hue: number; sat: number; lit: number }[] = []\r\n for (let i = 0; i < count; i++) {\r\n blobs.push({\r\n x: rng(), y: rng(),\r\n r: (0.22 + rng() * 0.6) * params.scale,\r\n hx: rng() * 4 - 2, hy: rng() * 4 - 2,\r\n speed: 0.05 + rng() * 0.1,\r\n hue: (baseHue + (rng() < 0.5 ? 30 : 180) + rng() * 60) % 360,\r\n sat: Math.round(45 + rng() * 50 * params.intensity),\r\n lit: dark ? Math.round(18 + rng() * 35 * params.intensity) : Math.round(60 + rng() * 25 * params.intensity),\r\n })\r\n }\r\n let t = 0\r\n const alpha = (0.22 + 0.3 * params.intensity).toFixed(3)\r\n const innerAlpha = (+alpha * 0.35).toFixed(3)\r\n const draw = () => {\r\n fitLiveCanvas(c)\r\n const w = c.width, h = c.height\r\n g.fillStyle = dark ? '#0a0b0e' : '#f5f7fa'\r\n g.fillRect(0, 0, w, h)\r\n for (const b of blobs) {\r\n const phase = t * b.speed\r\n const cx = (((b.x + noise(b.hx + phase * 0.3, b.hy) * 0.25 + phase * 0.03) % 1 + 1) % 1) * w\r\n const cy = (((b.y + noise(b.hx, b.hy + phase * 0.3) * 0.25 + phase * 0.012) % 1 + 1) % 1) * h\r\n const r = b.r * Math.min(w, h) * (0.8 + 0.4 * Math.sin(phase + b.hx))\r\n const rad = g.createRadialGradient(cx, cy, 0, cx, cy, r)\r\n rad.addColorStop(0, `hsla(${b.hue},${b.sat}%,${b.lit}%,${alpha})`)\r\n rad.addColorStop(0.55, `hsla(${b.hue},${Math.round(b.sat * 0.6)}%,${b.lit}%,${innerAlpha})`)\r\n rad.addColorStop(1, 'hsla(0,0%,0%,0)')\r\n g.fillStyle = rad\r\n g.fillRect(0, 0, w, h)\r\n }\r\n t += 0.028\r\n }\r\n return { canvas: c, ...newRaf(c, draw), snapshot: () => c.toDataURL('image/jpeg', 0.92) }\r\n}\r\n\r\n// ── Shader backgrounds (animated WebGL) ───────────────────────────────────────\r\nexport function createShaderBg(params: ShaderParams, canvas?: HTMLCanvasElement): LiveBgController {\r\n const c = canvas ?? createCanvas()\r\n fitLiveCanvas(c)\r\n const gl = c.getContext('webgl', { alpha: false }) || c.getContext('experimental-webgl', { alpha: false }) as WebGLRenderingContext | null\r\n if (!gl) return createMeshGradient({ type: 'mesh', seed: params.speed * 1000, scale: params.scale, intensity: 0.6 }, c)\r\n\r\n const vs = `\r\n attribute vec2 a_position;\r\n void main() { gl_Position = vec4(a_position, 0.0, 1.0); }\r\n `\r\n const program = createProgram(gl, vs, shaderFragment(params.preset))\r\n if (!program) return createMeshGradient({ type: 'mesh', seed: params.speed * 1000, scale: params.scale, intensity: 0.6 }, c)\r\n\r\n const posLoc = gl.getAttribLocation(program, 'a_position')\r\n const buf = gl.createBuffer()\r\n gl.bindBuffer(gl.ARRAY_BUFFER, buf)\r\n gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([-1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1]), gl.STATIC_DRAW)\r\n gl.enableVertexAttribArray(posLoc)\r\n gl.vertexAttribPointer(posLoc, 2, gl.FLOAT, false, 0, 0)\r\n gl.useProgram(program)\r\n const uRes = gl.getUniformLocation(program, 'u_resolution')\r\n const uTime = gl.getUniformLocation(program, 'u_time')\r\n const uScale = gl.getUniformLocation(program, 'u_scale')\r\n const uSeed = gl.getUniformLocation(program, 'u_seed')\r\n const seed01 = (params.seed >>> 0) / 0xffffffff\r\n let t = 0\r\n const draw = () => {\r\n fitLiveCanvas(c)\r\n gl.viewport(0, 0, c.width, c.height)\r\n gl.uniform2f(uRes, c.width, c.height)\r\n gl.uniform1f(uTime, t)\r\n gl.uniform1f(uScale, params.scale)\r\n gl.uniform1f(uSeed, seed01)\r\n gl.drawArrays(gl.TRIANGLES, 0, 6)\r\n t += 0.32 * params.speed\r\n }\r\n return { canvas: c, ...newRaf(c, draw), snapshot: () => c.toDataURL('image/jpeg', 0.95) }\r\n}\r\n\r\nfunction createProgram(gl: WebGLRenderingContext, vs: string, fs: string): WebGLProgram | null {\r\n const v = gl.createShader(gl.VERTEX_SHADER)\r\n const f = gl.createShader(gl.FRAGMENT_SHADER)\r\n if (!v || !f) return null\r\n gl.shaderSource(v, vs); gl.compileShader(v)\r\n gl.shaderSource(f, fs); gl.compileShader(f)\r\n if (!gl.getShaderParameter(v, gl.COMPILE_STATUS) || !gl.getShaderParameter(f, gl.COMPILE_STATUS)) {\r\n gl.deleteShader(v); gl.deleteShader(f)\r\n return null\r\n }\r\n const p = gl.createProgram()\r\n if (!p) return null\r\n gl.attachShader(p, v); gl.attachShader(p, f); gl.linkProgram(p)\r\n if (!gl.getProgramParameter(p, gl.LINK_STATUS)) { gl.deleteProgram(p); return null }\r\n return p\r\n}\r\n\r\nfunction shaderFragment(preset: ShaderParams['preset']): string {\r\n const common = `\r\n precision mediump float;\r\n uniform vec2 u_resolution;\r\n uniform float u_time;\r\n uniform float u_scale;\r\n uniform float u_seed;\r\n\r\n vec3 mod289(vec3 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; }\r\n vec4 mod289(vec4 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; }\r\n vec4 permute(vec4 x) { return mod289(((x*34.0)+1.0)*x); }\r\n vec4 taylorInvSqrt(vec4 r) { return 1.79284291400159 - 0.85373472095314 * r; }\r\n vec3 hueRotate(vec3 rgb, float angle) {\r\n float c = cos(angle), s = sin(angle);\r\n mat3 m = mat3(\r\n 0.299 + 0.701*c + 0.168*s, 0.587 - 0.587*c + 0.330*s, 0.114 - 0.114*c - 0.497*s,\r\n 0.299 - 0.299*c - 0.328*s, 0.587 + 0.413*c + 0.035*s, 0.114 - 0.114*c + 0.292*s,\r\n 0.299 - 0.300*c + 1.250*s, 0.587 - 0.588*c - 1.050*s, 0.114 + 0.886*c - 0.203*s\r\n );\r\n return rgb * m;\r\n }\r\n float snoise(vec3 v) {\r\n const vec2 C = vec2(1.0/6.0, 1.0/3.0);\r\n const vec4 D = vec4(0.0, 0.5, 1.0, 2.0);\r\n vec3 i = floor(v + dot(v, C.yyy));\r\n vec3 x0 = v - i + dot(i, C.xxx);\r\n vec3 g = step(x0.yzx, x0.xyz);\r\n vec3 l = 1.0 - g;\r\n vec3 i1 = min(g.xyz, l.zxy);\r\n vec3 i2 = max(g.xyz, l.zxy);\r\n vec3 x1 = x0 - i1 + C.xxx;\r\n vec3 x2 = x0 - i2 + C.yyy;\r\n vec3 x3 = x0 - D.yyy;\r\n i = mod289(i);\r\n vec4 p = permute(permute(permute(\r\n i.z + vec4(0.0, i1.z, i2.z, 1.0))\r\n + i.y + vec4(0.0, i1.y, i2.y, 1.0))\r\n + i.x + vec4(0.0, i1.x, i2.x, 1.0));\r\n float n_ = 0.142857142857;\r\n vec3 ns = n_ * D.wyz - D.xzx;\r\n vec4 j = p - 49.0 * floor(p * ns.z * ns.z);\r\n vec4 x_ = floor(j * ns.z);\r\n vec4 y_ = floor(j - 7.0 * x_);\r\n vec4 x = x_ * ns.x + ns.yyyy;\r\n vec4 y = y_ * ns.x + ns.yyyy;\r\n vec4 h = 1.0 - abs(x) - abs(y);\r\n vec4 b0 = vec4(x.xy, y.xy);\r\n vec4 b1 = vec4(x.zw, y.zw);\r\n vec4 s0 = floor(b0)*2.0 + 1.0;\r\n vec4 s1 = floor(b1)*2.0 + 1.0;\r\n vec4 sh = -step(h, vec4(0.0));\r\n vec4 a0 = b0.xzyw + s0.xzyw*sh.xxyy;\r\n vec4 a1 = b1.xzyw + s1.xzyw*sh.zzww;\r\n vec3 p0 = vec3(a0.xy, h.x);\r\n vec3 p1 = vec3(a0.zw, h.y);\r\n vec3 p2 = vec3(a1.xy, h.z);\r\n vec3 p3 = vec3(a1.zw, h.w);\r\n vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2,p2), dot(p3,p3)));\r\n p0 *= norm.x; p1 *= norm.y; p2 *= norm.z; p3 *= norm.w;\r\n vec4 m = max(0.6 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0);\r\n m = m * m;\r\n return 42.0 * dot(m*m, vec4(dot(p0,x0), dot(p1,x1), dot(p2,x2), dot(p3,x3)));\r\n }\r\n float fbm(vec3 p) {\r\n float v = 0.0, a = 0.5;\r\n for (int i = 0; i < 5; i++) {\r\n v += a * snoise(p);\r\n p *= 2.0; a *= 0.5;\r\n }\r\n return v;\r\n }\r\n `\r\n if (preset === 'aurora') {\r\n return common + `\r\n void main() {\r\n vec2 uv = gl_FragCoord.xy / u_resolution;\r\n float t = u_time;\r\n float n1 = fbm(vec3(uv * 2.5 * u_scale, t));\r\n float n2 = fbm(vec3(uv * 4.0 * u_scale + 7.0, t * 1.4));\r\n float n3 = fbm(vec3(uv * 1.2 * u_scale - 3.0, t * 0.7));\r\n float bands = smoothstep(0.15, 0.85, 0.5 + 0.5 * sin((uv.y + n3 * 0.08) * 8.0 + n1 * 1.5));\r\n vec3 c1 = vec3(0.03, 0.08, 0.14);\r\n vec3 c2 = vec3(0.05, 0.28, 0.32);\r\n vec3 c3 = vec3(0.18, 0.62, 0.42);\r\n vec3 c4 = vec3(0.55, 0.22, 0.52);\r\n vec3 c5 = vec3(0.85, 0.35, 0.25);\r\n vec3 col = mix(c1, c2, bands);\r\n col = mix(col, c3, smoothstep(0.25, 0.75, n1));\r\n col = mix(col, c4, smoothstep(0.45, 0.85, n2) * 0.75);\r\n col = mix(col, c5, smoothstep(0.7, 0.95, n2 + n1 * 0.3) * 0.45);\r\n col = hueRotate(col, u_seed * 6.28318530718);\r\n gl_FragColor = vec4(col, 1.0);\r\n }\r\n `\r\n }\r\n if (preset === 'nebula') {\r\n return common + `\r\n void main() {\r\n vec2 uv = gl_FragCoord.xy / u_resolution;\r\n float t = u_time * 0.8;\r\n float n = fbm(vec3(uv * 2.2 * u_scale, t));\r\n float n2 = fbm(vec3(uv * 5.0 * u_scale - 4.0, t * 0.65));\r\n float n3 = fbm(vec3(uv * 0.9 * u_scale + 2.0, t * 0.4));\r\n vec3 c1 = vec3(0.02, 0.02, 0.08);\r\n vec3 c2 = vec3(0.12, 0.04, 0.22);\r\n vec3 c3 = vec3(0.32, 0.10, 0.35);\r\n vec3 c4 = vec3(0.10, 0.18, 0.42);\r\n vec3 c5 = vec3(0.55, 0.30, 0.55);\r\n vec3 col = mix(c1, c2, smoothstep(-0.5, 0.6, n));\r\n col = mix(col, c3, smoothstep(0.15, 0.8, n2) * 0.75);\r\n col = mix(col, c4, smoothstep(0.35, 0.85, n + n3 * 0.3) * 0.55);\r\n col = mix(col, c5, smoothstep(0.6, 0.95, n2) * 0.35);\r\n col = hueRotate(col, u_seed * 6.28318530718);\r\n gl_FragColor = vec4(col, 1.0);\r\n }\r\n `\r\n }\r\n if (preset === 'starfield') {\r\n return common + `\r\n float hash21(vec2 p) {\r\n p = fract(p * vec2(234.34, 435.345));\r\n p += dot(p, p + 34.23);\r\n return fract(p.x * p.y);\r\n }\r\n vec3 starLayer(vec2 uv, float t, float density) {\r\n vec3 col = vec3(0.0);\r\n vec2 grid = uv * density;\r\n vec2 cell = floor(grid);\r\n vec2 f = fract(grid) - 0.5;\r\n float h = hash21(cell);\r\n if (h > 0.8) {\r\n vec2 offs = (vec2(hash21(cell + 1.3), hash21(cell + 2.7)) - 0.5) * 0.7;\r\n float d = length(f - offs);\r\n float tw = 0.35 + 0.65 * sin(t * (1.0 + h * 2.5) + h * 40.0);\r\n col += vec3(0.85, 0.92, 1.0) * smoothstep(0.07, 0.0, d) * max(0.0, tw);\r\n }\r\n return col;\r\n }\r\n void main() {\r\n vec2 uv = gl_FragCoord.xy / u_resolution;\r\n vec2 p = (gl_FragCoord.xy - 0.5 * u_resolution) / u_resolution.y;\r\n float t = u_time * 0.5;\r\n vec3 col = mix(vec3(0.012, 0.014, 0.035), vec3(0.035, 0.035, 0.08), uv.y);\r\n // Faint drifting nebula veil behind the stars.\r\n float n = fbm(vec3(p * 2.2 * u_scale, t * 0.05));\r\n col += vec3(0.05, 0.045, 0.11) * smoothstep(0.05, 0.85, n);\r\n vec3 stars = vec3(0.0);\r\n stars += starLayer(p + vec2(t * 0.006, 0.0), t, 13.0 * u_scale);\r\n stars += starLayer(p * 1.8 + vec2(t * 0.013, 3.0), t * 1.25, 27.0 * u_scale);\r\n stars += starLayer(p * 3.1 + vec2(t * 0.021, 7.0), t * 0.85, 46.0 * u_scale);\r\n col += stars;\r\n col = hueRotate(col, u_seed * 6.28318530718);\r\n gl_FragColor = vec4(col, 1.0);\r\n }\r\n `\r\n }\r\n // noise\r\n return common + `\r\n void main() {\r\n vec2 uv = gl_FragCoord.xy / u_resolution;\r\n float t = u_time;\r\n float n = fbm(vec3(uv * 3.5 * u_scale, t));\r\n float n2 = fbm(vec3(uv * 9.0 * u_scale + 15.0, t * 1.6));\r\n float n3 = fbm(vec3(uv * 1.5 * u_scale - 5.0, t * 0.5));\r\n vec3 c1 = vec3(0.06, 0.06, 0.08);\r\n vec3 c2 = vec3(0.16, 0.18, 0.22);\r\n vec3 c3 = vec3(0.30, 0.32, 0.36);\r\n vec3 c4 = vec3(0.46, 0.48, 0.52);\r\n vec3 col = mix(c1, c2, 0.5 + 0.5 * n + n3 * 0.15);\r\n col = mix(col, c3, smoothstep(0.3, 0.8, n2) * 0.45);\r\n col = mix(col, c4, smoothstep(0.6, 0.95, n2) * 0.25);\r\n col = hueRotate(col, u_seed * 6.28318530718);\r\n gl_FragColor = vec4(col, 1.0);\r\n }\r\n `\r\n}\r\n\r\n// ── Geometric patterns (animated) ─────────────────────────────────────────────\r\nexport function createPatternBg(params: PatternParams, canvas?: HTMLCanvasElement): LiveBgController {\r\n if (params.preset === 'waves') return createWaves(params, canvas)\r\n if (params.preset === 'poly') return createLowPoly(params, canvas)\r\n if (params.preset === 'rain') return createRain(params, canvas)\r\n if (params.preset === 'contour') return createContour(params, canvas)\r\n if (params.preset === 'meta') return createMeta(params, canvas)\r\n return createDots(params, canvas)\r\n}\r\n\r\nfunction createRain(params: PatternParams, canvas?: HTMLCanvasElement): LiveBgController {\r\n const c = canvas ?? createCanvas()\r\n fitLiveCanvas(c)\r\n const g = c.getContext('2d', { alpha: false })!\r\n const rng = createRng(params.seed)\r\n const dark = rng() < 0.5\r\n const hue = Math.round(rng() * 360)\r\n const count = Math.round(30 + params.density * 150)\r\n const drops: { x: number; y: number; len: number; speed: number; sat: number; lit: number; alpha: number; width: number }[] = []\r\n for (let i = 0; i < count; i++) {\r\n drops.push({\r\n x: rng(),\r\n y: rng(),\r\n len: (0.035 + rng() * 0.075) * (0.7 + params.scale * 0.5),\r\n speed: (0.25 + rng() * 0.55) * (0.6 + params.scale * 0.5),\r\n sat: Math.round(30 + rng() * 40),\r\n lit: dark ? Math.round(55 + rng() * 25) : Math.round(40 + rng() * 25),\r\n alpha: 0.12 + rng() * 0.28,\r\n width: 0.8 + rng() * 1.4,\r\n })\r\n }\r\n let t = 0\r\n const draw = () => {\r\n fitLiveCanvas(c)\r\n const w = c.width, h = c.height\r\n g.fillStyle = dark ? '#07080c' : '#f4f6f9'\r\n g.fillRect(0, 0, w, h)\r\n for (const d of drops) {\r\n const yy = (((d.y + t * d.speed) % 1) + 1) % 1\r\n const x = d.x * w\r\n const y0 = yy * h\r\n const y1 = y0 - d.len * h\r\n const grad = g.createLinearGradient(x, y0, x, y1)\r\n grad.addColorStop(0, `hsla(${hue},${d.sat}%,${d.lit}%,${d.alpha.toFixed(2)})`)\r\n grad.addColorStop(1, 'hsla(0,0%,0%,0)')\r\n g.strokeStyle = grad\r\n g.lineWidth = d.width\r\n g.beginPath()\r\n g.moveTo(x, y0)\r\n g.lineTo(x, y1)\r\n g.stroke()\r\n }\r\n t += 0.016\r\n }\r\n return { canvas: c, ...newRaf(c, draw), snapshot: () => c.toDataURL('image/jpeg', 0.94) }\r\n}\r\n\r\nfunction createContour(params: PatternParams, canvas?: HTMLCanvasElement): LiveBgController {\r\n const c = canvas ?? createCanvas()\r\n fitLiveCanvas(c)\r\n const g = c.getContext('2d', { alpha: false })!\r\n const noise = createNoise(params.seed)\r\n const rng = createRng(params.seed + 1013)\r\n const dark = rng() < 0.5\r\n const hue = Math.round(rng() * 360)\r\n const layers = Math.round(16 + params.density * 46)\r\n const freq = 0.0016 / params.scale\r\n const amp = 0.055 * params.scale\r\n let t = 0\r\n const draw = () => {\r\n fitLiveCanvas(c)\r\n const w = c.width, h = c.height\r\n g.fillStyle = dark ? '#0a0b0e' : '#f6f7fa'\r\n g.fillRect(0, 0, w, h)\r\n const samples = Math.max(60, Math.floor(w / 8))\r\n for (let i = 0; i <= layers; i++) {\r\n const base = i / layers\r\n const shift = t * 0.05\r\n g.beginPath()\r\n for (let s = 0; s <= samples; s++) {\r\n const fx = s / samples\r\n const n = noise(fx * 60 * freq * 400, i * 0.22 + shift)\r\n const y = (base + (n - 0.5) * amp) * h\r\n if (s === 0) g.moveTo(0, y)\r\n else g.lineTo(fx * w, y)\r\n }\r\n const lit = dark ? 20 + (i / layers) * 22 : 62 - (i / layers) * 18\r\n g.strokeStyle = `hsla(${(hue + i * 2) % 360},30%,${lit}%,${(0.25 + 0.2 * (i / layers)).toFixed(2)})`\r\n g.lineWidth = 1\r\n g.stroke()\r\n }\r\n t += 0.032\r\n }\r\n return { canvas: c, ...newRaf(c, draw), snapshot: () => c.toDataURL('image/jpeg', 0.94) }\r\n}\r\n\r\nfunction createMeta(params: PatternParams, canvas?: HTMLCanvasElement): LiveBgController {\r\n const c = canvas ?? createCanvas()\r\n fitLiveCanvas(c)\r\n const g = c.getContext('2d', { alpha: false })!\r\n const rng = createRng(params.seed)\r\n const dark = rng() < 0.5\r\n const baseHue = Math.round(rng() * 360)\r\n const count = Math.round(5 + params.density * 11)\r\n const blobs: { x: number; y: number; r: number; ax: number; ay: number; speed: number; phase: number; hue: number }[] = []\r\n for (let i = 0; i < count; i++) {\r\n blobs.push({\r\n x: 0.15 + rng() * 0.7, y: 0.15 + rng() * 0.7,\r\n r: (0.09 + rng() * 0.14) * params.scale,\r\n ax: 0.08 + rng() * 0.22, ay: 0.08 + rng() * 0.22,\r\n speed: 0.15 + rng() * 0.3,\r\n phase: rng() * Math.PI * 2,\r\n hue: (baseHue + rng() * 70) % 360,\r\n })\r\n }\r\n let t = 0\r\n const draw = () => {\r\n fitLiveCanvas(c)\r\n const w = c.width, h = c.height\r\n g.fillStyle = dark ? '#08090d' : '#f5f6f9'\r\n g.fillRect(0, 0, w, h)\r\n g.globalCompositeOperation = dark ? 'lighter' : 'multiply'\r\n for (const b of blobs) {\r\n const cx = (b.x + Math.sin(t * b.speed + b.phase) * b.ax) * w\r\n const cy = (b.y + Math.cos(t * b.speed * 0.83 + b.phase * 1.7) * b.ay) * h\r\n const r = b.r * Math.min(w, h) * (0.9 + 0.2 * Math.sin(t * b.speed + b.phase))\r\n const rad = g.createRadialGradient(cx, cy, 0, cx, cy, r)\r\n if (dark) {\r\n rad.addColorStop(0, `hsla(${b.hue},65%,58%,0.55)`)\r\n rad.addColorStop(0.7, `hsla(${b.hue},60%,45%,0.18)`)\r\n rad.addColorStop(1, 'hsla(0,0%,0%,0)')\r\n } else {\r\n rad.addColorStop(0, `hsla(${b.hue},55%,70%,0.5)`)\r\n rad.addColorStop(0.7, `hsla(${b.hue},50%,80%,0.2)`)\r\n rad.addColorStop(1, 'hsla(0,0%,100%,0)')\r\n }\r\n g.fillStyle = rad\r\n g.beginPath()\r\n g.arc(cx, cy, r, 0, Math.PI * 2)\r\n g.fill()\r\n }\r\n g.globalCompositeOperation = 'source-over'\r\n t += 0.03\r\n }\r\n return { canvas: c, ...newRaf(c, draw), snapshot: () => c.toDataURL('image/jpeg', 0.94) }\r\n}\r\n\r\nfunction createDots(params: PatternParams, canvas?: HTMLCanvasElement): LiveBgController {\r\n const c = canvas ?? createCanvas()\r\n fitLiveCanvas(c)\r\n const g = c.getContext('2d', { alpha: false })!\r\n const rng = createRng(params.seed)\r\n const dark = rng() < 0.5\r\n const baseHue = Math.round(rng() * 360)\r\n const spacing = Math.max(26, 150 * params.scale / (0.25 + params.density))\r\n const dots: { cx: number; cy: number; r: number; hue: number; sat: number; lit: number; phase: number; speed: number }[] = []\r\n for (let y = 0; y < 8; y++) {\r\n for (let x = 0; x < 8; x++) {\r\n dots.push({\r\n cx: x / 7, cy: y / 7,\r\n r: spacing * 0.16 * params.scale * (0.6 + rng() * 0.7),\r\n hue: (baseHue + rng() * 80) % 360,\r\n sat: Math.round(35 + rng() * 55),\r\n lit: dark ? Math.round(30 + rng() * 35) : Math.round(55 + rng() * 30),\r\n phase: rng() * Math.PI * 2,\r\n speed: 0.5 + rng() * 1.2,\r\n })\r\n }\r\n }\r\n let t = 0\r\n const draw = () => {\r\n fitLiveCanvas(c)\r\n const w = c.width, h = c.height\r\n g.fillStyle = dark ? '#0a0b0d' : '#f6f7f9'\r\n g.fillRect(0, 0, w, h)\r\n for (const d of dots) {\r\n const pulse = 0.75 + 0.35 * Math.sin(t * d.speed + d.phase)\r\n const r = Math.max(1, d.r * pulse)\r\n const x = d.cx * w + (d.r * 0.3) * Math.sin(t * d.speed * 0.5 + d.phase)\r\n const y = d.cy * h + (d.r * 0.3) * Math.cos(t * d.speed * 0.7 + d.phase)\r\n g.beginPath()\r\n g.arc(x, y, r, 0, Math.PI * 2)\r\n g.fillStyle = `hsla(${d.hue},${d.sat}%,${d.lit}%,${(0.18 + 0.25 * pulse).toFixed(2)})`\r\n g.fill()\r\n }\r\n t += 0.032\r\n }\r\n return { canvas: c, ...newRaf(c, draw), snapshot: () => c.toDataURL('image/jpeg', 0.94) }\r\n}\r\n\r\nfunction createWaves(params: PatternParams, canvas?: HTMLCanvasElement): LiveBgController {\r\n const c = canvas ?? createCanvas()\r\n fitLiveCanvas(c)\r\n const g = c.getContext('2d', { alpha: false })!\r\n const rng = createRng(params.seed)\r\n const dark = rng() < 0.5\r\n const hue = Math.round(rng() * 360)\r\n const layers = Math.round(5 + params.density * 8)\r\n const waves: { yBase: number; amp: number; freq: number; phase: number; speed: number; hue: number; sat: number; lit: number; alpha: number }[] = []\r\n for (let i = 0; i < layers; i++) {\r\n waves.push({\r\n yBase: 0.25 + (i / layers) * 0.55,\r\n amp: (25 + rng() * 45) * params.scale,\r\n freq: (0.006 + rng() * 0.01) / params.scale,\r\n phase: rng() * Math.PI * 2,\r\n speed: (0.3 + rng() * 0.7) * (rng() < 0.5 ? 1 : -1),\r\n hue: (hue + i * 12) % 360,\r\n sat: Math.round(40 + rng() * 45),\r\n lit: dark ? Math.round(14 + (i / layers) * 32) : Math.round(72 - (i / layers) * 28),\r\n alpha: 0.22 + rng() * 0.32,\r\n })\r\n }\r\n let t = 0\r\n const draw = () => {\r\n fitLiveCanvas(c)\r\n const w = c.width, h = c.height\r\n g.fillStyle = dark ? '#07080a' : '#f8f9fb'\r\n g.fillRect(0, 0, w, h)\r\n for (const wave of waves) {\r\n g.beginPath()\r\n g.moveTo(0, h)\r\n for (let x = 0; x <= w; x += Math.max(6, Math.floor(w / 180))) {\r\n const y = h * wave.yBase\r\n + Math.sin(x * wave.freq + wave.phase + t * wave.speed) * wave.amp\r\n + Math.sin(x * wave.freq * 2.1 + wave.phase * 1.3 - t * wave.speed * 1.5) * wave.amp * 0.5\r\n g.lineTo(x, y)\r\n }\r\n g.lineTo(w, h)\r\n g.closePath()\r\n g.fillStyle = `hsla(${wave.hue},${wave.sat}%,${wave.lit}%,${wave.alpha.toFixed(2)})`\r\n g.fill()\r\n }\r\n t += 0.032\r\n }\r\n return { canvas: c, ...newRaf(c, draw), snapshot: () => c.toDataURL('image/jpeg', 0.94) }\r\n}\r\n\r\nfunction createLowPoly(params: PatternParams, canvas?: HTMLCanvasElement): LiveBgController {\r\n const c = canvas ?? createCanvas()\r\n fitLiveCanvas(c)\r\n const g = c.getContext('2d', { alpha: false })!\r\n const rng = createRng(params.seed)\r\n const dark = rng() < 0.5\r\n const hue = Math.round(rng() * 360)\r\n const cols = Math.round(10 + params.density * 20)\r\n const rows = Math.max(6, Math.round(cols * 0.65))\r\n const points: { x: number; y: number; dx: number; dy: number; speed: number }[][] = []\r\n for (let y = 0; y <= rows; y++) {\r\n const row: { x: number; y: number; dx: number; dy: number; speed: number }[] = []\r\n for (let x = 0; x <= cols; x++) {\r\n row.push({\r\n x: x / cols, y: y / rows,\r\n dx: (rng() - 0.5) * 0.02, dy: (rng() - 0.5) * 0.02,\r\n speed: 0.3 + rng() * 0.5,\r\n })\r\n }\r\n points.push(row)\r\n }\r\n const cells: { y: number; x: number; hue: number; sat: number; lit: number; phase: number }[] = []\r\n for (let y = 0; y < rows; y++) {\r\n for (let x = 0; x < cols; x++) {\r\n cells.push({ y, x, hue: (hue + rng() * 60) % 360, sat: Math.round(35 + rng() * 40), lit: dark ? Math.round(12 + rng() * 35) : Math.round(65 - rng() * 10), phase: rng() * Math.PI * 2 })\r\n }\r\n }\r\n let t = 0\r\n const px: { x: number; y: number }[][] = points.map(row => row.map(() => ({ x: 0, y: 0 })))\r\n const draw = () => {\r\n fitLiveCanvas(c)\r\n const w = c.width, h = c.height\r\n g.fillStyle = dark ? '#08090c' : '#f5f6f8'\r\n g.fillRect(0, 0, w, h)\r\n for (let y = 0; y <= rows; y++) {\r\n const row = points[y]!\r\n const out = px[y]!\r\n for (let x = 0; x <= cols; x++) {\r\n const p = row[x]!\r\n out[x]!.x = (p.x + Math.sin(t * p.speed + p.dx * 100) * p.dx) * w\r\n out[x]!.y = (p.y + Math.cos(t * p.speed + p.dy * 100) * p.dy) * h\r\n }\r\n }\r\n for (const cell of cells) {\r\n const p1 = px[cell.y]![cell.x]!, p2 = px[cell.y]![cell.x + 1]!, p3 = px[cell.y + 1]![cell.x]!, p4 = px[cell.y + 1]![cell.x + 1]!\r\n const cx = (p1.x + p2.x + p3.x) / 3 / w\r\n const lit = Math.max(0, Math.min(100, cell.lit + Math.sin(t * 0.6 + cell.phase) * 6))\r\n g.beginPath(); g.moveTo(p1.x, p1.y); g.lineTo(p2.x, p2.y); g.lineTo(p3.x, p3.y); g.closePath()\r\n g.fillStyle = `hsla(${cell.hue + cx * 40},${cell.sat}%,${lit}%,0.92)`\r\n g.fill()\r\n g.beginPath(); g.moveTo(p2.x, p2.y); g.lineTo(p4.x, p4.y); g.lineTo(p3.x, p3.y); g.closePath()\r\n g.fillStyle = `hsla(${(cell.hue + cx * 40 + 12) % 360},${cell.sat}%,${Math.max(0, lit - 4)}%,0.92)`\r\n g.fill()\r\n }\r\n t += 0.03\r\n }\r\n return { canvas: c, ...newRaf(c, draw), snapshot: () => c.toDataURL('image/jpeg', 0.94) }\r\n}\r\n\r\n// ── Dispatcher ────────────────────────────────────────────────────────────────\r\nexport function createDynamicBackground(params: GeneratedBgParams, canvas?: HTMLCanvasElement): LiveBgController {\r\n if (params.type === 'mesh') return createMeshGradient(params, canvas)\r\n if (params.type === 'shader') return createShaderBg(params, canvas)\r\n return createPatternBg(params, canvas)\r\n}\r\n\r\nfunction randomSeed(): number {\r\n return Math.floor(Math.random() * 0x7fffffff)\r\n}\r\n\r\n/** Build default params for a newly selected background type. */\r\nexport function defaultParamsFor(type: Exclude<GeneratedBgParams['type'], 'image'>): GeneratedBgParams {\r\n if (type === 'mesh') return { type: 'mesh', seed: randomSeed(), scale: 1.1, intensity: 0.65 }\r\n if (type === 'shader') return { type: 'shader', preset: 'aurora', speed: 0.35, scale: 1, seed: randomSeed() }\r\n return { type: 'pattern', preset: 'dots', density: 0.5, scale: 1, seed: randomSeed() }\r\n}\r\n","import { MENU_FILL_TOKEN, PANEL_SURFACES, BETTER_SIDEBAR_PANEL, COMPOSER_TAKEOVER_CARD, COMPOSER_TAKEOVER_EDITOR, elementFrostDecl } from './host-compat/versions/shared'\r\nimport { hostAdapter } from './host-compat/capabilities'\r\nimport { HEADER_POPOVER_ATTR } from './header-tag'\r\nimport { rWp, rWpImage, rWpVideo, rBgState, rVideoBgState, rBl, rWop, rOps, rSop, rStrokes, rColor, rHasColor, rBlurs, rBgMode, rChatTextOpacity, rTrajectoryOpacity, rPanelOpacity, rProducedOpacity, rHeaderOpacity, rHeaderBarOpacity, rScheme, rColorScheme, rSchemeOverride, cfg, setWpUrl, rBgDark, setBgDark, disposeVideoObjectUrl } from './state'\r\nimport type { BackgroundType, GeneratedBgParams, PartOpacities, PartBlurs, StrokeConfig } from './types'\r\nimport { genTokens, toRgba, extractWallpaperColor, analyzeFrameDark } from './utils/color'\r\nimport { loadImage } from './utils/image'\r\nimport { createDynamicBackground, defaultParamsFor } from './utils/bg-generators'\r\n\r\nlet wpEl: HTMLDivElement | null = null\r\nlet videoEl: HTMLVideoElement | null = null\r\nlet appliedTokenNames: string[] = []\r\nlet wpController: { canvas: HTMLCanvasElement; stop: () => void; pause?: () => void; resume?: () => void; snapshot: () => string } | null = null\r\nlet snapshotListener: (() => void) | null = null\r\nlet tokenStyleEl: HTMLStyleElement | null = null\r\n\r\n/** Pause the live generated background's animation loop (session-only). */\r\nexport function pauseGeneratedBg(): void { wpController?.pause?.() }\r\n\r\n/** Resume the live generated background's animation loop. */\r\nexport function resumeGeneratedBg(): void { wpController?.resume?.() }\r\n\r\nfunction clearDynamicBg(): void {\r\n wpController?.stop()\r\n wpController?.canvas.remove()\r\n wpController = null\r\n}\r\n\r\n/** Register a callback fired once a generated snapshot is ready (so the caller\r\n * can re-sync the settings preview / store). Returns an unsubscribe: HMR\r\n * re-runs apply and would otherwise leave the previous apply's closure as the\r\n * live listener (a stale this-session callback invoked by a lingering\r\n * controller). */\r\nexport function onGeneratedSnapshot(cb: () => void): () => void {\r\n snapshotListener = cb\r\n return () => { if (snapshotListener === cb) snapshotListener = null }\r\n}\r\n\r\nfunction ensureTokenStyle(): HTMLStyleElement {\r\n if (tokenStyleEl?.isConnected) return tokenStyleEl\r\n tokenStyleEl = document.createElement('style')\r\n tokenStyleEl.dataset.plugin = 'dsh-any-background-tokens'\r\n document.head.appendChild(tokenStyleEl)\r\n return tokenStyleEl\r\n}\r\n\r\nfunction clearCustomTokens(): void {\r\n if (tokenStyleEl) tokenStyleEl.textContent = ''\r\n for (const name of appliedTokenNames) document.body.style.removeProperty(name)\r\n appliedTokenNames = []\r\n}\r\n\r\n/** Drop every applied custom token and forget the token fingerprint, so a\r\n * later color-less profile (system theme) leaves no stale rule behind. */\r\nexport function clearThemeTokens(): void {\r\n clearCustomTokens()\r\n baseTokenKey = ''\r\n lastBgKey = ''\r\n document.body.removeAttribute('data-ds-dark-theme')\r\n document.body.style.removeProperty('color-scheme')\r\n}\r\n\r\n/** Label tokens flipped by the background brightness verdict. The faint tiers\r\n * (caption/dimmed) are deliberately NOT flipped: they back placeholder/hint\r\n * text, which must stay visibly weaker than real input even when the wallpaper\r\n * brightness flips the main label direction. Exported so the skin registration\r\n * (index) can flip fonts through the host theme service too. */\r\nexport const LABEL_TOKENS = [\r\n '--dsw-alias-label-primary',\r\n '--dsw-alias-label-secondary',\r\n '--dsw-alias-label-tertiary',\r\n]\r\n\r\n// Solid surface tokens grouped by which interface-opacity slider owns them.\r\n// Every member is re-emitted with per-part alpha so surfaces over the wallpaper\r\n// (composer input, elevated buttons, menu panels) can go translucent — not just\r\n// the layered bg/sidebar tokens. --dsw-specific-menu (dropdowns, slash-trigger\r\n// menu, model selector, popovers around the dialog) is owned by the card\r\n// slider; the Cordis panel shares that token but is re-scoped to the input\r\n// slider via inputBlurRule.\r\n//\r\n// `--dsw-alias-bg-base` IS the main-background surface: the AppFrame ground and\r\n// the conversation root that fills the center column both paint from it, which\r\n// is exactly what lets the wallpaper show through the main area. It must stay\r\n// remapped — un-remapping it makes those surfaces opaque and hides the wallpaper\r\n// entirely behind a solid theme color.\r\nconst OPACITY_TOKEN_GROUPS: Array<{ part: keyof PartOpacities; names: string[] }> = [\r\n { part: 'bg', names: ['--dsw-alias-bg-base'] },\r\n { part: 'sidebar', names: ['--dsw-specific-sidebar-fill'] },\r\n { part: 'card', names: ['--dsw-alias-bg-layer-1', '--dsw-alias-bg-layer-2', '--dsw-alias-bg-layer-3', '--dsw-specific-menu'] },\r\n { part: 'input', names: ['--dsw-specific-input-major'] },\r\n]\r\n\r\n// Plugin-owned variables the opacity-bearing tokens read from. They live as\r\n// inline custom props on <html>, so a slider drag rewrites only those few values\r\n// instead of re-parsing/re-matching the whole body token rule on every tick —\r\n// the difference is critical when a large wallpaper sits under the interface.\r\nconst OPACITY_VARS: Record<string, string> = {\r\n '--dsw-alias-bg-base': '--dsh-any-op-bg',\r\n '--dsw-specific-sidebar-fill': '--dsh-any-op-sidebar',\r\n '--dsw-alias-bg-layer-1': '--dsh-any-op-card-1',\r\n '--dsw-alias-bg-layer-2': '--dsh-any-op-card-2',\r\n '--dsw-alias-bg-layer-3': '--dsh-any-op-card-3',\r\n '--dsw-specific-input-major': '--dsh-any-op-input',\r\n '--dsw-specific-menu': '--dsh-any-op-menu',\r\n}\r\n\r\n// Fingerprint of the non-alpha token base (color pick + brightness verdict).\r\n// The static body rule is only rebuilt when it changes; a drag never touches it.\r\nlet baseTokenKey = ''\r\n\r\n// Coalesce slider-driven token updates to one rAF: a single drag fires several\r\n// input events per frame, and every full re-apply repaints expensive regions\r\n// over a large wallpaper. Batching keeps at most one update per frame. The\r\n// base-fingerprint gate above already makes a muted drag cheap; this prevents\r\n// repeated identical reapplies from stacking within the same frame.\r\nlet pendingOps: PartOpacities | null = null\r\nlet tokensRaf: number | null = null\r\n\r\nexport function applyCustomTokens(ops: PartOpacities): void {\r\n pendingOps = ops\r\n if (tokensRaf !== null) return\r\n tokensRaf = requestAnimationFrame(() => {\r\n tokensRaf = null\r\n if (pendingOps === null) return\r\n const o = pendingOps\r\n pendingOps = null\r\n applyCustomTokensNow(o)\r\n })\r\n}\r\n\r\n// Only the main-bg slider retints the center column; keys on\r\n// baseTokenKey + ops.bg so a sidebar/card/input drag never rewrites it.\r\nlet lastBgKey = ''\r\n\r\n/** Palette source for the token rule: the picked color; a forced scheme\r\n * without a picked color builds a neutral near-gray palette in that\r\n * direction; auto without a color keeps the host's own palette (null — only\r\n * the label direction gets asserted). The palette direction follows the\r\n * color's own lightness (rColorScheme), not the wallpaper verdict, so the\r\n * surfaces keep contrasting with the fonts. */\r\nfunction paletteTokens(): Record<string, string> | null {\r\n const scheme = rColorScheme()\r\n if (rHasColor()) {\r\n const [h, s, l] = rColor()\r\n return genTokens(h, s, l, scheme).tokens\r\n }\r\n if (rSchemeOverride() !== 'auto') {\r\n return genTokens(220, 0.04, scheme === 'dark' ? 0.14 : 0.92, scheme).tokens\r\n }\r\n return null\r\n}\r\n\r\n/** Surface colors the opacity sliders fade when the plugin has NO palette of\r\n * its own (no picked color, no forced scheme), read live from the host's\r\n * resolved tokens on `:root` — the same trick applyPanelOverrides uses for the\r\n * workbench panel. Without this source the per-part alpha is never emitted at\r\n * all and every opacity slider looks inert until the user drags it once.\r\n * The sliders only ever supply the alpha: the host still decides the colors,\r\n * so a custom host skin survives. Returns null when the host exposes none. */\r\nfunction readHostOpacityTokens(): Record<string, string> | null {\r\n if (typeof getComputedStyle === 'undefined') return null\r\n const cs = getComputedStyle(document.documentElement)\r\n const out: Record<string, string> = {}\r\n let found = false\r\n for (const g of OPACITY_TOKEN_GROUPS) {\r\n for (const name of g.names) {\r\n const v = cs.getPropertyValue(name).trim()\r\n if (v === '') continue\r\n out[name] = v\r\n found = true\r\n }\r\n }\r\n return found ? out : null\r\n}\r\n\r\nfunction applyCustomTokensNow(ops: PartOpacities): void {\r\n const hasColor = rHasColor()\r\n const override = rSchemeOverride()\r\n const [h, s, l] = rColor()\r\n const scheme = rScheme()\r\n const verdict = rBgDark()\r\n const palette = paletteTokens()\r\n // Surface source for the opacity re-emit: the plugin's own palette when it\r\n // has one, otherwise the host's resolved tokens — see readHostOpacityTokens.\r\n // This is what keeps all four interface-opacity sliders live in the default\r\n // state (fresh install: no picked color, no verdict, auto scheme).\r\n const surfaces = palette ?? readHostOpacityTokens()\r\n // Clone: the verdict below mutates, and genTokens' result is cached/shared.\r\n const tokens: Record<string, string> = { ...surfaces }\r\n // Font direction while the scheme is automatic: a picked color owns it —\r\n // its palette direction (rColorScheme) keeps the labels contrasted with the\r\n // surfaces they sit on, so a very dark pick flips to white fonts even over\r\n // a light wallpaper (and vice versa). Without a pick the wallpaper\r\n // brightness verdict decides: the text then sits directly on the wallpaper.\r\n if (override === 'auto') {\r\n const fontDark = hasColor ? rColorScheme() === 'dark' : verdict\r\n if (fontDark !== null && fontDark !== undefined) {\r\n const font = fontDark ? '#fff' : '#000'\r\n for (const name of LABEL_TOKENS) tokens[name] = font\r\n }\r\n }\r\n try {\r\n const forceDark = scheme === 'dark'\r\n const key = `${h}|${s}|${l}|${verdict}|${scheme}|${hasColor}|${hostAdapter().menus.fillTokens.join(',')}`\r\n if (key !== baseTokenKey) {\r\n baseTokenKey = key\r\n // Drive the base-palette switch with a plugin-specific value so the\r\n // gradient rule never matches a host dark-mode flag; color-scheme makes\r\n // native controls (select popups) follow the forced palette. Both ride the\r\n // stylesheet (not inline styles) so the host presenter clearing body\r\n // inline styles on boot can't drop them, and the !important rule survives\r\n // that clearing too.\r\n if (forceDark) document.body.setAttribute('data-ds-dark-theme', 'dsh-any-background')\r\n else document.body.removeAttribute('data-ds-dark-theme')\r\n const decls: string[] = [`color-scheme:${forceDark ? 'dark' : 'light'}`]\r\n for (const [name, value] of Object.entries(tokens)) {\r\n const opVar = OPACITY_VARS[name]\r\n decls.push(`${name}:${opVar !== undefined ? `var(${opVar})` : value}!important`)\r\n }\r\n // A release that paints menus from a second token needs that name re-scoped\r\n // too, or the menu would inherit the CARD alpha from `body` under one name and\r\n // the host's own opaque value under the other — which is precisely how the\r\n // opacity sliders went inert on 0.1.7-rc.2. Same variable, so one slider still\r\n // writes one value. Guarded on the sampled color existing, because a `var()`\r\n // naming an unset property is the guaranteed-invalid-value trap documented on\r\n // `applyHeaderPopovers`.\r\n if (tokens[MENU_FILL_TOKEN] !== undefined) {\r\n const menuVar = OPACITY_VARS[MENU_FILL_TOKEN]\r\n for (const name of hostAdapter().menus.fillTokens) {\r\n if (name === MENU_FILL_TOKEN || tokens[name] !== undefined) continue\r\n decls.push(`${name}:var(${menuVar})!important`)\r\n }\r\n }\r\n ensureTokenStyle().textContent = `body{${decls.join(';')}}`\r\n // Drop inline tokens left by earlier builds so the stylesheet is the single source of truth.\r\n for (const name of appliedTokenNames) document.body.style.removeProperty(name)\r\n appliedTokenNames = Object.keys(tokens)\r\n }\r\n // The header bar is painted here, before the surface bail below: its own\r\n // opacity is a part value like any other, and its material is the\r\n // main-background surface this funnel already resolved. The Windows caption\r\n // band and the host's native-button probe are pinned here too — the same\r\n // resolved source, but at full strength rather than through a slider.\r\n applyHeaderBar(surfaces)\r\n applyNativeCaption(surfaces)\r\n // Without a palette there are no surface alphas to re-emit — the host\r\n // palette stays untouched and only the label direction was asserted. Now\r\n // that the host's own resolved tokens can back the alpha, this only bails\r\n // when even those are unavailable.\r\n if (surfaces === null) {\r\n // Preserve the previous \"nothing derived\" cleanup: a color-less auto\r\n // state with no verdict leaves no stale rule behind. A forced scheme or\r\n // a wallpaper verdict still has something to assert above.\r\n if (!hasColor && override === 'auto' && verdict === null) clearThemeTokens()\r\n return\r\n }\r\n // Cheap per-drag update: only the surface alpha vars move on <html>.\r\n const root = document.documentElement\r\n for (const g of OPACITY_TOKEN_GROUPS) {\r\n for (const name of g.names) {\r\n if (surfaces[name] === undefined) continue\r\n root.style.setProperty(OPACITY_VARS[name], toRgba(surfaces[name]!, ops[g.part]))\r\n }\r\n }\r\n // The Cordis panel keeps its own input-slider alpha (see inputBlurRule).\r\n const menu = surfaces['--dsw-specific-menu']\r\n if (menu !== undefined) root.style.setProperty('--dsh-any-op-menu-cordis', toRgba(menu, ops.input))\r\n const bgKey = `${baseTokenKey}|${ops.bg}`\r\n if (bgKey !== lastBgKey) { lastBgKey = bgKey; applyPartOpacities(ops) }\r\n // The exempt surfaces (exemptDefaultRule) point at the host's OWN token\r\n // values, sampled from :root here — so re-capture them whenever the palette\r\n // underneath changes. This is the one function every color/verdict/scheme\r\n // path funnels through.\r\n applyExemptDefaults()\r\n } catch {\r\n // ignore\r\n }\r\n}\r\n\r\n// ── Settings panel opacity ─────────────────────────────────────────────────────\r\n// Scoped by the settings dialog's own identity, not just its ARIA shape: every\r\n// aria-modal dialog that labels itself would otherwise be claimed here, and a\r\n// third-party confirm dialog does exactly that (an antd `Modal` carries\r\n// `role=\"dialog\"`, `aria-modal=\"true\"` AND `aria-labelledby` pointing at its\r\n// title). Claimed by mistake, it inherits the settings surface + blur + layer\r\n// re-scope + settings text stroke — which reads as a mis-adapted dialog with a\r\n// shifted button label rather than as the plugin's own look.\r\n// The discriminator is the hashed `_panel` class: SettingsRoot.tsx renders\r\n// `<div className={css.panel} role=\"dialog\" aria-modal=\"true\"\r\n// aria-labelledby={titleId}>` identically on 0.1.5-rc.2 / 0.1.6-alpha.2 /\r\n// 0.1.7-alpha.2 / 0.1.7-rc.1, while antd's classes are all `ant-*` (hyphens, so\r\n// `_panel` can never match one).\r\n// The surface (--dsw-alias-bg-layer-2) is re-emitted with an alpha through a\r\n// plugin-owned variable so the panel keeps its color while fading.\r\n\r\nexport const SETTINGS_PANEL_SEL = '[role=\"dialog\"][aria-modal=\"true\"][aria-labelledby][class*=\"_panel\"]'\r\nexport const SETTINGS_STYLE_RULE =\r\n `${SETTINGS_PANEL_SEL}{` +\r\n `background:var(--dsh-any-bg-settings-surface,var(--dsw-alias-bg-layer-2));` +\r\n `backdrop-filter:var(--dsh-any-blur-settings,none);` +\r\n // Re-scope the dialog's layer tokens to plugin-owned variables so every\r\n // surface inside the dialog follows the settings opacity slider only.\r\n `--dsw-alias-bg-layer-1:var(--dsh-any-bg-settings-layer-1);` +\r\n `--dsw-alias-bg-layer-2:var(--dsh-any-bg-settings-layer-2);` +\r\n `--dsw-alias-bg-layer-3:var(--dsh-any-bg-settings-layer-3)}` +\r\n // Option-panel blur inside the dialog, owned by the card blur slider.\r\n `${SETTINGS_PANEL_SEL} .dab-card{backdrop-filter:var(--dsh-any-blur-card-panels,none);-webkit-backdrop-filter:var(--dsh-any-blur-card-panels,none)}`\r\n\r\n// ── Popover / popover-style surface blur (the \"card\" slider's true target) ────\r\n// The \"card\" opacity slider does not bind to the settings dialog's .dab-card —\r\n// the comments at OPACITY_TOKEN_GROUPS note that --dsw-specific-menu (the\r\n// dropdown / popover / menu surface token) is owned by the card slider, and\r\n// the body-level re-scope in `applyCustomTokensNow` retints every consumer\r\n// of that token globally. The host uses --dsw-specific-menu for the \"popovers\r\n// around the dialog\" — the model selector (ModelSelect), the per-session\r\n// permission preset row (PermissionRow → Menu portal), the composer\r\n// permission seat (PermissionSelect → in-place Menu, `side=\"top\"`), the\r\n// stat dialog (TurnUsagePanel / StatsPills → useStatDialog), the schedule\r\n// catalog, the subagent lineage tree, the /model command panel, the\r\n// @-trigger suggestion list, the job list, etc.\r\n//\r\n// The card-blur slider has to land on the same surfaces for the visible\r\n// effect to follow the slider.\r\n//\r\n// The host uses three ARIA roles for these surfaces, and one stable\r\n// data-attribute to disqualify a non-target:\r\n//\r\n// [role=\"menu\"] · every Menu primitive surface (.list, .submenu),\r\n// ModelSelect's `.menu`. These are the picker-style\r\n// popovers, both portal-mode (rendered to body via\r\n// createPortal) and in-place (rendered where the React\r\n// subtree is — PermissionSelect keeps its `side=\"top\"`\r\n// list inside the composer card).\r\n// [role=\"listbox\"]· the /model command panel (PopupSelectView `.viewport`)\r\n// and the @-trigger suggestion list (MenuView `.viewport`)\r\n// — both the inner scroll box, not the card. From\r\n// 0.1.7-rc.2 the schedule ClockPicker adds one per column\r\n// (`ui-schedule/ClockPicker.tsx`), inside its own popover.\r\n// [role=\"tree\"] · the subagent lineage tree (portaled to body) and\r\n// the sidebar's workspace browser (ui-workspace). The\r\n// `body >` qualifier restricts this to the portaled\r\n// variant and keeps the sidebar tree out.\r\n// [role=\"dialog\"]:not([aria-modal=\"true\"])\r\n// · stat-dialog (TurnUsagePanel / StatsPills). The\r\n// settings modal is `role=\"dialog\"` with\r\n// `aria-modal=\"true\"` and is owned by\r\n// SETTINGS_STYLE_RULE; the `:not()` excludes it.\r\n//\r\n// The one element the rule must NOT touch is the dockkit per-tab\r\n// right-click menu (ui-dockkit TabMenu.tsx). It uses `role=\"menu\"` and\r\n// is portaled to body, and its background paints from\r\n// `--dsw-alias-bg-layer-3` (a layer token, not the menu token) — it is a\r\n// tab control, not a \"popover around the dialog\", and it carries a stable\r\n// `data-dockkit-tab-menu` attribute. `:not([data-dockkit-tab-menu])`\r\n// trims it out of the menu rule.\r\n//\r\n// Stacking-context caveat: the in-place menus (PermissionSelect's\r\n// `side=\"top\"` list, MenuView's listbox, PopupSelectView's listbox) live\r\n// inside .composerSeat, which is `position: sticky` and therefore a\r\n// stacking-context root. Their backdrop-filter cannot see the wallpaper\r\n// (z-index: -1 in body) because they are trapped in that context. The\r\n// effect they get is \"frost the composer card chrome\", which the card\r\n// slider drives just as visibly as a wallpaper-facing blur because the\r\n// card's own surface sits in the same context.\r\n//\r\n// The portaled menus (ModelSelect, Menu portal mode, stat-dialog,\r\n// SubagentHeaderLineage) are in body's stacking context and see the\r\n// wallpaper directly through the (transparent) AppFrame.\r\n//\r\n// THE MENU ARM IS NOT HOST-AGNOSTIC and asks the release adapter for its\r\n// declaration (`MenuSurfaceFacts`): up to 0.1.7-rc.1 the `[role=\"menu\"]` element\r\n// painted its own fill and frost (`Menu.module.css`, `ModelSelect.module.css` each\r\n// declared `background:var(--dsw-specific-menu)` plus\r\n// `backdrop-filter:var(--dsw-menu-backdrop-filter)` on that element), so filtering\r\n// it is the whole job. From 0.1.7-rc.2 that element carries no paint — a\r\n// `position:absolute;inset:0;z-index:-1` `.material` child of `MenuSurface` does,\r\n// and the host states why the root stays unfiltered (\"Filtering only the background\r\n// keeps nested menus and fixed overlays free of an ancestor backdrop root or a new\r\n// fixed-position containing block\"). So the plugin hands the value to the host's\r\n// blur token there instead of filtering an ancestor the host deliberately left clear.\r\n//\r\n// THE OTHER ARMS KEEP THE ELEMENT-LEVEL FROST, because the token cannot reach them:\r\n// custom properties travel downward, and on the layered releases the filtered layer\r\n// sits above or beside the matched element, never inside it — `[role=\"listbox\"]` is\r\n// the MenuSurface's *child* viewport (PopupSelectView.tsx:153, MenuView.tsx:132; the\r\n// surface root carries no role), and `[role=\"tree\"]` sits inside `.menu`, whose frost\r\n// lives on `.menu::before`. Setting the token on either is inert, so the element\r\n// filter is the only declaration that lands. Note these cards were never owned by the\r\n// card slider on either shape: the host frosts the card and our filter adds a frost\r\n// inside it, which is how the slider behaved at 0.1.7-rc.1 too.\r\nconst CARD_BLUR_VAR = '--dsh-any-blur-card-panels'\r\nconst POPOVER_MENU_SEL = `[role=\"menu\"]:not([data-dockkit-tab-menu])`\r\nconst POPOVER_OTHER_SEL =\r\n `[role=\"listbox\"],` +\r\n `body > [role=\"tree\"],` +\r\n `body > [role=\"dialog\"]:not([aria-modal=\"true\"])`\r\n\r\n/** The frost declaration this release's menus want, driven by the named plugin var.\r\n * Every menu-shaped surface group asks through here, so the card group, the header\r\n * group and the exemptions can never disagree about which layer to paint. */\r\nfunction menuFrost(blurVar: string): string {\r\n return hostAdapter().menus.frostDecl(`var(${blurVar},none)`)\r\n}\r\n\r\n/** Declare EVERY token this release's menus can paint their fill from with the same\r\n * value. One slider, one value, every layer reached — and a token the host does not\r\n * read is inert, so this is safe to emit on a line that only needs one.\r\n *\r\n * Used for values that are guaranteed to resolve. Where the value is a `var()` the\r\n * caller must first confirm the variable it names is actually set: an undefined\r\n * custom property inside `background:var(…)` computes to the guaranteed-invalid\r\n * value and the surface goes fully transparent (see the notes on\r\n * `applyHeaderPopovers` and `applyExemptDefaults`). */\r\nfunction menuFillDecls(value: string): string {\r\n return hostAdapter().menus.fillTokens.map(name => `${name}:${value}`).join(';')\r\n}\r\n\r\nexport function popoverBlurRule(): string {\r\n return `${POPOVER_MENU_SEL}{${menuFrost(CARD_BLUR_VAR)}}` +\r\n `${POPOVER_OTHER_SEL}{${elementFrostDecl(`var(${CARD_BLUR_VAR},none)`)}}`\r\n}\r\n\r\n// Input/control surface blur. The composer card and the Cordis panel expose\r\n// stable host data attributes ([data-composer-card], [data-cordis-panel]), so\r\n// the backdrop is attached via a stylesheet rule rather than element discovery.\r\n// The Cordis panel shares the --dsw-specific-menu token with the dialog's\r\n// option boxes, but it stays owned by the input slider — the re-scope below\r\n// keeps it there now that the menu token itself follows the card slider. Note\r\n// the input slider must NOT drive the button-elevated-fill /\r\n// button-floating-hover tokens: the settings panel's own controls (slider\r\n// thumbs, .dab-btn, segmented thumb) are painted from those same tokens, so\r\n// tinting them would bleach the panel's own UI.\r\n// Set on <html> while the input blur is non-zero, to gate `inputBlurRule`'s\r\n// composer-card rules below (see the paint-order note there).\r\nconst INPUT_FROST_CLASS = 'dab-input-frost'\r\n\r\n// Carried by each composer-seat takeover card (approval / plan review /\r\n// question) while the input frost is on. Unlike the capsule's arm above, this\r\n// class is attached PER CARD at runtime by `applyTakeoverFrost`, not by a\r\n// `[data-approval-key]>div` selector: see the note inside `inputBlurRule` for\r\n// why the anchor has to be probed rather than declared.\r\nconst TAKEOVER_FROST_CLASS = 'dab-takeover-frost'\r\n\r\n// Marks a card whose `position:relative` was written by the plugin because the\r\n// host left it static — the `setBlur` idiom, same attribute name and same\r\n// meaning: only the writer may clear it.\r\nconst TAKEOVER_POS_ATTR = 'data-dab-pos-patched'\r\n\r\nexport function inputBlurRule(): string {\r\n // The composer capsule must NOT carry backdrop-filter itself: it is an\r\n // ancestor of the in-place popovers (permission / command / model lists),\r\n // and a backdrop-filter on it would make it a backdrop root, trapping those\r\n // lists' own backdrop-filter to the capsule — which chained their visible\r\n // frost to the input slider. The frost instead rides an isolated ::before\r\n // underlay (position:absolute, z-index:-1), so it sits behind the capsule\r\n // content AND the popovers, leaving the popovers free to sample the\r\n // wallpaper and follow the card slider only. (Same rule the part-blurs\r\n // follow: backdrop-filter never goes directly on a host part.)\r\n //\r\n // The price of that underlay is `position:relative` + `isolation:isolate`, and\r\n // both are PAINT ORDER: a positioned element — or any element that establishes a\r\n // stacking context, which `isolation` does — is painted in the positioned layer,\r\n // above other plugins' in-flow or earlier-in-tree notices that overlap the same\r\n // spot. That is the \"输入框的 z 层级太高,挡住了通知\" report, and it cannot be\r\n // fixed away while a frost is requested: a frost needs an isolated containing\r\n // block, and no CSS construct provides one that paints *below* in-flow content.\r\n // What can be fixed is paying the cost for nothing, so both declarations are\r\n // gated on the blur being non-zero — at 0 the capsule keeps the host's own\r\n // layering and the plugin competes for nothing.\r\n return `.${INPUT_FROST_CLASS} [data-composer-card]{position:relative;isolation:isolate}` +\r\n `.${INPUT_FROST_CLASS} [data-composer-card]::before{` +\r\n 'content:\"\";position:absolute;inset:0;z-index:-1;pointer-events:none;border-radius:inherit;' +\r\n '-webkit-backdrop-filter:var(--dsh-any-input-blur,none);' +\r\n 'backdrop-filter:var(--dsh-any-input-blur,none)}' +\r\n // The takeover cards that sit in the composer seat (approval / plan review /\r\n // question) are the capsule's SIBLINGS, so the rule above never reaches them.\r\n // They fill from the same `--dsw-specific-input-major`, which this plugin\r\n // re-emits with the input alpha — so they faded while staying bare, and the\r\n // blur slider read as broken on exactly the surface the user is meant to read.\r\n // Same underlay recipe as the capsule: never a backdrop root of its own.\r\n //\r\n // WHY THIS ARM IS CLASS-ONLY (no `[data-approval-key]>div` selector, no\r\n // `position`, and why the class is attached at runtime): the underlay needs\r\n // the card to BE the containing block for its `inset:0` layer, and the host\r\n // never positions these cards — no release in range declares `position` on\r\n // any of the three (see `COMPOSER_TAKEOVER_CARD`). A stylesheet rule that\r\n // declares one therefore decides the card's position BY CASCADE against\r\n // whatever else is styling the page, and a host build that positions the card\r\n // itself (issue #24's desktop shell pins it with a percentage `max-height`,\r\n // so the card's absolute containing block is load-bearing) hands the plugin\r\n // that decision: the `relative` wins or loses on specificity, and whichever\r\n // way it lands the host's box is now the plugin's to move. Measured both ways\r\n // against a shell rule of the same weight — the plugin's rule wins by source\r\n // order and turns the host's absolute card into an in-flow one, seat height\r\n // and all — which is a host layout this plugin has no business deciding; that\r\n // report is where the card's box came apart. So: `applyTakeoverFrost` attaches\r\n // this class only while the blur is non-zero, and writes `position:relative`\r\n // INLINE only when the card's computed position is `static` — the `setBlur`\r\n // guard. A card the host positions keeps its own position (which is then the\r\n // containing block the underlay rides, so the frost still lands) and gets\r\n // nothing but the stacking context below.\r\n `.${TAKEOVER_FROST_CLASS}{isolation:isolate}` +\r\n `.${TAKEOVER_FROST_CLASS}::before{` +\r\n 'content:\"\";position:absolute;inset:0;z-index:-1;pointer-events:none;border-radius:inherit;' +\r\n '-webkit-backdrop-filter:var(--dsh-any-input-blur,none);' +\r\n 'backdrop-filter:var(--dsh-any-input-blur,none)}' +\r\n // …but that stacking context is the same trap PART_BLUR_RULE documents: a\r\n // dialog mounted inside the card keeps its z-index local and can be buried\r\n // under the seat. The cards are host-owned surfaces a Tool fills through the\r\n // `conversation.approval.detail` slot, so a dialog can legitimately open\r\n // inside one. Losing the frost while it is open is the cheaper half.\r\n `.${TAKEOVER_FROST_CLASS}:has([role=\"dialog\"]){isolation:auto}` +\r\n '[data-cordis-panel]{' +\r\n '-webkit-backdrop-filter:var(--dsh-any-input-blur,none);' +\r\n 'backdrop-filter:var(--dsh-any-input-blur,none)}' +\r\n // Every fill token, not just the one the Cordis panel's option boxes used to\r\n // read: on a release where a menu paints from a layer token, scoping only the\r\n // old name would let the box inherit the CARD alpha from `body` while the panel\r\n // itself follows the input slider. Inert where the host reads one token.\r\n `[data-cordis-panel]{${menuFillDecls('var(--dsh-any-op-menu-cordis)!important')}}`\r\n}\r\n\r\nfunction applyInputBlur(px: number): void {\r\n const root = document.documentElement\r\n // The frost gate: with the slider at 0 the plugin must not add any layering to\r\n // the composer at all (see inputBlurRule).\r\n if (px > 0) root.classList.add(INPUT_FROST_CLASS)\r\n else root.classList.remove(INPUT_FROST_CLASS)\r\n if (px > 0) root.style.setProperty('--dsh-any-input-blur', `blur(${px}px)`)\r\n else root.style.removeProperty('--dsh-any-input-blur')\r\n applyTakeoverFrost(px)\r\n}\r\n\r\n/** Carry the input frost on the seat's takeover cards (approval / plan review /\r\n * question), the capsule's siblings — see `inputBlurRule` for the recipe and\r\n * why it is attached here rather than by a stylesheet selector.\r\n *\r\n * The anchor probe is the `setBlur` guard: `position:relative` is written\r\n * inline ONLY where the host left the card `static`, and remembered with\r\n * `TAKEOVER_POS_ATTR` so clearing it is this function's job. A card a host or a\r\n * desktop shell positions itself is left exactly as it is — its own position\r\n * supplies the underlay's containing block — so no host box ever has its\r\n * position decided by this plugin's cascade (issue #24).\r\n *\r\n * Idempotent and cheap in the steady state: cards already carrying the class\r\n * (or already clear of it) are skipped without a style read. */\r\nfunction applyTakeoverFrost(px: number): void {\r\n const cards = document.querySelectorAll<HTMLElement>(COMPOSER_TAKEOVER_CARD)\r\n if (px > 0) {\r\n for (const card of cards) {\r\n if (card.classList.contains(TAKEOVER_FROST_CLASS)) continue\r\n if (getComputedStyle(card).position === 'static') {\r\n card.style.position = 'relative'\r\n card.setAttribute(TAKEOVER_POS_ATTR, '1')\r\n }\r\n card.classList.add(TAKEOVER_FROST_CLASS)\r\n }\r\n return\r\n }\r\n for (const card of cards) {\r\n if (!card.classList.contains(TAKEOVER_FROST_CLASS)) continue\r\n card.classList.remove(TAKEOVER_FROST_CLASS)\r\n if (card.getAttribute(TAKEOVER_POS_ATTR) === '1') {\r\n card.style.removeProperty('position')\r\n card.removeAttribute(TAKEOVER_POS_ATTR)\r\n }\r\n }\r\n}\r\n\r\n// Narrow-viewport hosts render a fixed session-title bar (.dsh-mobile-app-header)\r\n// above the AppFrame columns, outside every column's subtree. The main-bg alpha\r\n// lives on the columns (applyPartOpacities), so that bar paints the raw\r\n// wallpaper and splits visually from the translucent center column. Both rules\r\n// below ride plugin-owned variables so the bar follows the sliders and falls\r\n// back to the host default when the plugin never set them.\r\nexport const MOBILE_HEADER_RULE =\r\n '.dsh-mobile-app-header{' +\r\n 'background:var(--dsh-any-op-bg,transparent)!important;' +\r\n 'backdrop-filter:var(--dsh-any-part-blur-global,none);' +\r\n '-webkit-backdrop-filter:var(--dsh-any-part-blur-global,none)}'\r\n\r\n// ── Session header bar (the conversation's own 「标题栏」) ──────────────────────\r\n// The row that carries the session title, its actions and the view tabs — the\r\n// host's `ConversationHeader`, its own file from `0.1.7-alpha.1`:\r\n// `ui-conversation/skeleton/ConversationHeader.tsx` renders one `<header>` that\r\n// holds the header slots. Before that line (0.1.5-rc.2 / 0.1.6-alpha.2) the slots\r\n// mounted straight into the conversation root with no row of their own, so there\r\n// is nothing to tint there and this part never claims anything.\r\n//\r\n// The bar has no surface of its own — the centre column's background paints\r\n// straight through it — so once a wallpaper is up, the strip the title and the\r\n// tabs sit on shows the raw picture while every surface around it is masked. It\r\n// gets its own opacity + blur pair, painted as a REGION TINT the way the chat\r\n// column's card is (see `VIEW_CARDS`): the material is the plugin's\r\n// main-background surface at this part's own opacity, so the bar reads as one band\r\n// over the column instead of a second colour stacked on it, and the frost rides\r\n// the element's own `backdrop-filter` — the header hosts no in-place overlay of\r\n// its own (its dropdowns portal to `body`), so it may be the backdrop root here.\r\n//\r\n// The row is CLAIMED AT RUNTIME, not matched by a stylesheet selector: the\r\n// addressable seam every release in range emits is the slot wrapper\r\n// (`[data-slot^=\"conversation.session.header\"]`), so the plugin walks from that\r\n// anchor up to the nearest `<header>` and tags it with `dab-header-bar` — the same\r\n// idiom the view cards and the frame use, and the one that cannot be broken by a\r\n// host that re-wraps or renames the element around the slots.\r\nconst HEADER_BAR_CLASS = 'dab-header-bar'\r\nconst HEADER_BAR_ANCHOR = '[data-slot^=\"conversation.session.header\"]'\r\n\r\n/** The session header bar, or null where this host has no such element. */\r\nfunction discoverHeaderBar(): HTMLElement | null {\r\n if (centerEl === null || !document.body.contains(centerEl)) return null\r\n const bar = centerEl.querySelector(HEADER_BAR_ANCHOR)?.closest('header')\r\n return bar instanceof HTMLElement ? bar : null\r\n}\r\n\r\n/** The bar's paint. The variables are written by `applyHeaderBar`; the class is\r\n * only ever added when they are, so a host the plugin is not theming keeps its\r\n * own header untouched. */\r\nexport const HEADER_BAR_RULE =\r\n `.${HEADER_BAR_CLASS}{` +\r\n 'background:var(--dsh-any-op-header-bar,transparent)!important;' +\r\n 'backdrop-filter:var(--dsh-any-blur-header-bar,none);' +\r\n '-webkit-backdrop-filter:var(--dsh-any-blur-header-bar,none)}'\r\n\r\n/** Claim the bar and write its material + frost. `surfaces` arrives from the token\r\n * funnel, which already has the resolved source list; the settings sliders and the\r\n * parts pass call it without one and the sources are re-resolved here. */\r\nexport function applyHeaderBar(surfaces?: Record<string, string> | null): void {\r\n const src = surfaces === undefined ? (paletteTokens() ?? readHostOpacityTokens()) : surfaces\r\n const base = src?.['--dsw-alias-bg-base']\r\n const root = document.documentElement\r\n discoverParts()\r\n const bar = discoverHeaderBar()\r\n if (base === undefined) {\r\n // Not theming (no picked color, no wallpaper verdict): not our row.\r\n if (bar !== null) bar.classList.remove(HEADER_BAR_CLASS)\r\n root.style.removeProperty('--dsh-any-op-header-bar')\r\n root.style.removeProperty('--dsh-any-blur-header-bar')\r\n return\r\n }\r\n root.style.setProperty('--dsh-any-op-header-bar', toRgba(base, rHeaderBarOpacity()))\r\n const px = rBlurs().headerBar\r\n if (px > 0) root.style.setProperty('--dsh-any-blur-header-bar', `blur(${px}px)`)\r\n else root.style.removeProperty('--dsh-any-blur-header-bar')\r\n if (bar !== null) bar.classList.add(HEADER_BAR_CLASS)\r\n}\r\n\r\n// ── Windows desktop caption band + native window-controls block ───────────────\r\n// The caption row is CHROME, so it stops following the sidebar slider. The facts,\r\n// read off the desktop app rather than inferred:\r\n// · `preload-windows.ts` stamps `data-windows-titlebar` on <html> for the\r\n// primary window and paints nothing itself;\r\n// · the caption band is `AppFrame.module.css`'s `.frame::before`, and both it\r\n// and `.frame` fill from `--dsw-specific-sidebar-fill` — the token the\r\n// sidebar slider owns, which is why dialing that slider down leaves the\r\n// window's own caption clear and the wallpaper raw under the title and the\r\n// Application / Edit menubar (issue #23, symptom 1);\r\n// · the native window-controls overlay — the minimize/maximize/close block,\r\n// drawn by Windows and not by the page — is colored by that same preload,\r\n// which MEASURES `--dsw-specific-sidebar-fill` and `--dsw-alias-label-primary`\r\n// off a probe span it appends to <body> and ships them over\r\n// `dsh-desktop:windows-appearance`. There is no page-callable IPC and the\r\n// `dshDesktop` bridge exposes none, so those measured tokens ARE the plugin's\r\n// entire lever on that block. A caption is a window colour, not a page\r\n// surface: the platform draws it as ONE OPAQUE COLOR, so a translucent band\r\n// and the block can never agree (symptom 2).\r\n// The answer is to treat the band as material at FULL strength and to feed the\r\n// host's probe the same literal, which makes the block show the band's color\r\n// instead of the sidebar slider's alpha. The material is the palette's sidebar\r\n// fill when a color was picked and the neutral the plugin would build for the\r\n// effective scheme otherwise, so its direction always matches the label ink the\r\n// plugin is asserting (see the label flip in `applyCustomTokensNow`): the menubar\r\n// inherits that ink and the measured `--dsw-alias-label-primary` — the glyph color\r\n// of the native buttons — is the same ink, so both stay readable on the band in\r\n// either direction.\r\n// NOT a settings part: the band is window chrome with no slider of its own, so\r\n// nothing in the panel writes it — the 「标题栏」 opacity/blur pair owns the\r\n// conversation's own header row instead (see `applyHeaderBar`). Inert where the\r\n// preload did not mark the document, and no declaration at all where the plugin\r\n// is not theming (no picked color, no wallpaper verdict), so a stock install's\r\n// caption keeps the host's own look.\r\nconst CAPTION_FRAME_CLASS = 'dab-frame-caption'\r\nconst WCO_PROBE_SEL = 'body > span[style*=\"--dsw-specific-sidebar-fill\"]'\r\n\r\nlet wcoStyleEl: HTMLStyleElement | null = null\r\n\r\nfunction ensureWcoStyle(): HTMLStyleElement {\r\n if (wcoStyleEl?.isConnected) return wcoStyleEl\r\n wcoStyleEl = document.createElement('style')\r\n wcoStyleEl.dataset.plugin = 'dsh-any-background-wco'\r\n document.head.appendChild(wcoStyleEl)\r\n return wcoStyleEl\r\n}\r\n\r\n/** The band's opaque material, or '' when the plugin has no theme to assert. The\r\n * sampled sidebar fill is already opaque in both source paths (the plugin's\r\n * palette builds `hsl()`, the host's own token is a static colour) — it only\r\n * misses on a host that exposes neither, and then the neutral the plugin builds\r\n * for the effective scheme stands in so the band still tracks the label ink. */\r\nfunction captionFill(src: Record<string, string> | null): string {\r\n const sampled = src?.['--dsw-specific-sidebar-fill']\r\n if (sampled !== undefined) return sampled\r\n if (paletteTokens() === null && rBgDark() === null) return ''\r\n const dark = rScheme() === 'dark'\r\n return genTokens(220, 0.04, dark ? 0.14 : 0.92, dark ? 'dark' : 'light').tokens['--dsw-specific-sidebar-fill'] ?? ''\r\n}\r\n\r\n/** Write the caption rule and mark the frame it targets. The frame is the\r\n * plugin's own discovery (`discoverParts`), not a guessed hashed class name. The\r\n * probe selector is a verified shape: an inline style that mentions the sidebar\r\n * token on a body-level span is the desktop preload's caption probe and nothing\r\n * else, so no match means no desktop caption and the rule is inert. */\r\nfunction applyNativeCaption(surfaces?: Record<string, string> | null): void {\r\n if (!document.documentElement.hasAttribute('data-windows-titlebar')) return\r\n const src = surfaces === undefined ? (paletteTokens() ?? readHostOpacityTokens()) : surfaces\r\n const fill = captionFill(src)\r\n const css = fill === '' ? '' : `${WCO_PROBE_SEL}{--dsw-specific-sidebar-fill:${fill}}` +\r\n `[data-windows-titlebar] .${CAPTION_FRAME_CLASS}::before{background:${fill}!important}`\r\n const el = ensureWcoStyle()\r\n if (el.textContent !== css) el.textContent = css\r\n discoverParts()\r\n if (frameEl === null) return\r\n if (css === '') frameEl.classList.remove(CAPTION_FRAME_CLASS)\r\n else frameEl.classList.add(CAPTION_FRAME_CLASS)\r\n}\r\n\r\n/** Mirror of the bg-part blur on :root. --dsh-any-part-blur is element-scoped\r\n * to the columns, so surfaces outside their subtree (the mobile header, or\r\n * third-party styles) can never inherit it. */\r\nfunction applyBgBlurGlobal(px: number): void {\r\n if (px > 0) document.documentElement.style.setProperty('--dsh-any-part-blur-global', `blur(${px}px)`)\r\n else document.documentElement.style.removeProperty('--dsh-any-part-blur-global')\r\n}\r\n\r\n// ── Right sidebar / workbench panel (the \"panel\" slider pair) ────────────────\r\n// The `panelOpacity` / blurs.panel pair targets two surfaces by mode:\r\n// · native — the host's own right Sidebar (`[data-sidebar-right-panel]`),\r\n// a `--dsw-alias-bg-base`-painted column of the page;\r\n// · dsh-better-sidebar installed — its bottom workbench panel\r\n// (`[data-dsh-bottom-panel]`), which paints every surface from the same\r\n// layer/bg-base tokens.\r\n// Both hang where neither the column opacities nor the part-blur underlays\r\n// reach, so both need their own treatment: a token re-scope here, and a blur rule\r\n// from the adapters.\r\n//\r\n// Which element the blur rides, and whether the panel has to be lifted out of its\r\n// stacking context to have wallpaper to sample, CHANGED between host releases —\r\n// that history (and the measurement behind it) lives with the adapters that answer\r\n// it, in `host-compat/versions/*`. The token re-scope below is layout-neutral and\r\n// stays correct on every release.\r\nexport const PANEL_TOKEN_RULE =\r\n // Re-scope the layer tokens so every surface inside the panel follows the\r\n // panel opacity slider only. The re-scope lives in the always-emitted\r\n // stylesheet so it works even with no palette (pointing at unwritten vars\r\n // would invalidate the background and drop the surface entirely;\r\n // `applyPanelOverrides` writes the vars on every call).\r\n `${PANEL_SURFACES}{` +\r\n '--dsw-alias-bg-base:var(--dsh-any-panel-bg-base);' +\r\n '--dsw-alias-bg-layer-1:var(--dsh-any-panel-layer-1);' +\r\n '--dsw-alias-bg-layer-2:var(--dsh-any-panel-layer-2);' +\r\n '--dsw-alias-bg-layer-3:var(--dsh-any-panel-layer-3)}'\r\n\r\n// ── Header popovers (Agent Team panel + background-job list + open-in-app /\r\n// session-log menus + subagent lineage tree) ────────────────────────────────\r\n// Session-header dropdowns that paint from --dsw-specific-menu, the same token\r\n// the card slider owns — so they used to follow the card opacity, and the\r\n// non-Menu ones never got any blur (they are `position: absolute` under their\r\n// own trigger, not portaled to body, so popoverBlurRule's\r\n// `body > [role=\"dialog\"]` selector misses them). This rule gives them their\r\n// own part: the header opacity slider retints the menu token for these\r\n// surfaces only, and the header blur slider frosts them.\r\n//\r\n// This rule is appended AFTER popoverBlurRule in the static stylesheet, and\r\n// each selector carries equal-or-higher specificity — so listing a surface here\r\n// cleanly overrides the card group instead of fighting it. That matters for the\r\n// menu selectors below, which DO already match `[role=\"menu\"]`: they are moved\r\n// from the card group to the header group, not merely added.\r\n//\r\n// TWO MATCHING STRATEGIES, primary first:\r\n//\r\n// 1. [data-dsh-any-header-popover] — the runtime tag (see header-tag.ts). Every\r\n// header dropdown portals its popover to <body> through the Menu/tree\r\n// primitive, which severs the DOM link to the header and exposes no\r\n// id/aria-controls back-link, so no ancestor selector can reach it. The tag\r\n// module observes the stable `[data-slot=\"conversation.session.header*\"]`\r\n// anchors (emitted by the slot renderer on 0.1.5 → 0.1.7 alike) and marks the\r\n// open popover. This is the ONLY strategy that still works on 0.1.7, where\r\n// open-in-app moved to a portal and the session row menu became a dynamic\r\n// slot — see below.\r\n//\r\n// 2. Class-shape fallbacks — retained for hosts where the tag observer has not\r\n// run yet (first paint) or is unavailable, and they still cover 0.1.5/0.1.6:\r\n// · ul[class*=\"_menu\"] — the background-job list. It is one of exactly TWO\r\n// host <ul> elements styled by a `menu` CSS-module class; the other is the\r\n// schedule catalog (`ui-schedule` ScheduleCatalogAction.tsx), verified on\r\n// 0.1.7-alpha.1. Every remaining `_menu` consumer (ModelSelect, TabMenu,\r\n// MenuView, TerminalGuide, SubagentHeaderLineage) renders a <div>. The two\r\n// <ul>s are portal'd siblings with the same attributes (class, style,\r\n// aria-label) and no distinguishing marker, so this fallback cannot single\r\n// out the job list: the schedule catalog takes the header look too.\r\n// Strategy 1 never tags it, so that overlap comes from this rule alone.\r\n// ACCEPTED as-is: keeping the job list styled on first paint is worth more\r\n// than holding the catalog on the card group, so do not \"fix\" the match.\r\n// · div[role=\"dialog\"][class*=\"_panel\"]:not([aria-modal=\"true\"]) — the\r\n// Agent Team panel. The other `_panel` + role=\"dialog\" element is the\r\n// settings modal (aria-modal=\"true\"), which SETTINGS_STYLE_RULE owns.\r\n// · [role=\"tree\"][class*=\"_menu\"] — the subagent lineage tree. Portal'd, so\r\n// `body > [role=\"tree\"]` already matched it; the class is what separates\r\n// it from every other `role=\"tree\"` (workspace lists use `.list` /\r\n// `.flatList` / `.searchTree`).\r\n// · [role=\"menu\"][class*=\"_denseList\"]:not([class*=\"_portal\"]) — the two\r\n// in-place `dense` Menu primitives: open-in-app's picker and the\r\n// session-log download menu on 0.1.5/0.1.6. The `:not([_portal])` is\r\n// what keeps every PORTALED dense menu (WorkspaceBrowser view options,\r\n// TextPreview open-with, ReviewTab file selector) on the card slider.\r\n// NOTE: on 0.1.7 open-in-app became `portal`+`dense` (see\r\n// OpenTargetButton.tsx), so this fallback deliberately no longer matches\r\n// it — strategy 1's tag is what restores the header grouping there.\r\n// Keeping the exclusion matters: broadening it would drag the side-panel\r\n// dense menus into the header group.\r\n// SPECIFICITY IS LOAD-BEARING HERE. The card group's rule is\r\n// `[role=\"menu\"]:not([data-dockkit-tab-menu])` — specificity (0,2,0) — so a bare\r\n// `[data-dsh-any-header-popover]` (0,1,0) LOSES to it no matter how late it\r\n// appears in the sheet. That is exactly how the tagged open-in-app menu kept\r\n// taking the card blur. Every header selector below therefore carries an extra\r\n// attribute so it reaches (0,2,0)+ and genuinely overrides the card group:\r\n// · [data-dsh-any-header-popover][role] → (0,2,0)\r\n// · [role=\"menu\"][class*=\"_denseList\"]... → (0,2,0)+\r\n//\r\n// NO TOKEN DECLARATION LIVES HERE. The header group's surface color is written\r\n// as a LITERAL by `applyHeaderPopovers` into a dedicated sheet, for the same\r\n// reason `applyExemptDefaults` is: an earlier revision declared\r\n// `--dsw-specific-menu:var(--dsh-any-op-menu-header,var(--dsw-specific-menu))`,\r\n// which is a SELF-REFERENCE. With `--dsh-any-op-menu-header` unset (before the\r\n// first apply, or on a host the plugin cannot sample) the fallback names the\r\n// property being declared, the custom property computes to the\r\n// guaranteed-invalid value, and every menu background reading it goes fully\r\n// transparent. Literals cannot cycle; when no color resolves we emit nothing and\r\n// the surface keeps the re-scoped value instead.\r\n/** The header dropdown surfaces, spelled ONCE. Three rules consume this set (the\r\n * static blur rule, the dynamic token rule and the stroke group), and every one\r\n * of them drifting by a single attribute re-introduces the bug where a header\r\n * menu keeps the card slider's look instead of its own.\r\n *\r\n * Strategy 1 is the runtime tag (`header-tag.ts`); strategies 2 are class-shape\r\n * fallbacks for the first paint before the tag observer runs. */\r\nconst HEADER_TAG_SELECTOR = `[${HEADER_POPOVER_ATTR}]`\r\nconst HEADER_SURFACES = [\r\n HEADER_TAG_SELECTOR,\r\n 'ul[class*=\"_menu\"],div[role=\"dialog\"][class*=\"_panel\"]:not([aria-modal=\"true\"])',\r\n `[role=\"menu\"][class*=\"_denseList\"]:not([class*=\"_portal\"])`,\r\n '[role=\"tree\"][class*=\"_menu\"]',\r\n]\r\n\r\n/** SPECIFICITY IS LOAD-BEARING HERE. The card group's rule is\r\n * `[role=\"menu\"]:not([data-dockkit-tab-menu])` — specificity (0,2,0) — so a bare\r\n * `[data-dsh-any-header-popover]` (0,1,0) LOSES to it no matter how late it\r\n * appears in the sheet. That is exactly how the tagged open-in-app menu kept\r\n * taking the card blur. `[role]` is a no-op presence test that raises only the\r\n * tagged arm to (0,2,0); the other three already qualify at (0,2,0)+. */\r\nconst HEADER_SURFACES_PADDED = [`${HEADER_TAG_SELECTOR}[role]`, ...HEADER_SURFACES.slice(1)]\r\n\r\n/** The header blur variable, and the rule that frosts the header's dropdown set.\r\n * The declaration comes from the same adapter answer as the card group's menu arm:\r\n * every surface in this set paints its skin from the host's own menu-blur token\r\n * (`SubagentHeaderLineage.module.css:120` uses a pseudo-element, the stat dialog and\r\n * goal bar use their own layer), so handing over the token reaches all of them on\r\n * both paint shapes, while filtering the element would install the ancestor\r\n * backdrop root each of those files documents avoiding. */\r\nconst HEADER_BLUR_VAR = '--dsh-any-blur-header'\r\n\r\nexport function headerPopoverRule(): string {\r\n return `${HEADER_SURFACES_PADDED.join(',')}{${menuFrost(HEADER_BLUR_VAR)}}`\r\n}\r\n\r\n// ── Surfaces pinned against the sliders (theme color kept) ────────────────────\r\n// Two groups the user wants the sliders to leave alone, for two reasons:\r\n//\r\n// 1. Modal-native confirm dialogs — `role=\"dialog\"[aria-modal=\"true\"]` WITHOUT\r\n// `aria-labelledby` (which is what separates them from the settings panel\r\n// that SETTINGS_STYLE_RULE owns). These are the rename / delete / risk /\r\n// feedback confirmations: short-lived, destructive or decision-critical\r\n// prompts whose legibility must not depend on an appearance slider. They do\r\n// not match SETTINGS_STYLE_RULE, but they still inherit the body-level token\r\n// re-scope, so the card slider's alpha on --dsw-alias-bg-layer-2 bleeds into\r\n// them. `applyExemptDefaults` pins those tokens at alpha 1 — keeping whatever\r\n// color the theme dictates, dropping only the slider's translucency.\r\n//\r\n// 2. Session row menus — the portal'd `[role=\"menu\"]` listing rename / fork /\r\n// archive / delete. Structurally identical to every other Menu primitive\r\n// (model selector, @-suggestions, …) and portalled to body, so no attribute\r\n// or ancestor distinguishes it. `:has([class*=\"_danger\"])` approximates it:\r\n// `_danger` is the destructive-row class, and among host menus only the\r\n// session-row menu carries one (for its 删除会话 entry). Deliberately narrow,\r\n// and it no-ops on engines without :has() (the menu simply keeps the card\r\n// look rather than breaking).\r\n//\r\n// Both groups come AFTER popoverBlurRule / SETTINGS_STYLE_RULE so they win on\r\n// order.\r\n//\r\n// IMPORTANT — no self-referencing fallbacks. An earlier version wrote\r\n// `--dsw-alias-bg-layer-2:var(--dsh-any-host-layer-2,var(--dsw-alias-bg-layer-2))`.\r\n// When the host var is unset the fallback names the property being declared,\r\n// which is a CSS cycle: the custom property computes to the guaranteed-invalid\r\n// value and every `background:var(--dsw-alias-bg-layer-2)` consuming it becomes\r\n// invalid — i.e. fully transparent. That is why the pin is emitted DYNAMICALLY\r\n// with real literals (see applyExemptDefaults): when no color resolves we emit\r\n// NO declaration at all, so the element keeps the re-scoped value instead of\r\n// going transparent.\r\n//\r\n// Only the parts that cannot go invalid stay static: the blur/stroke resets.\r\nexport function exemptDefaultRule(): string {\r\n return '[role=\"dialog\"][aria-modal=\"true\"]:not([aria-labelledby]){' +\r\n 'backdrop-filter:none;-webkit-backdrop-filter:none}' +\r\n // Session row menus (approximated by their destructive row): no plugin blur,\r\n // no plugin stroke. Its surface color is restored dynamically too. The frost is\r\n // cleared through the release's own menu arm — on a MenuSurface host\r\n // `backdrop-filter:none` on the element would leave the child layer frosted.\r\n `[role=\"menu\"]:has([class*=\"_danger\"]){${hostAdapter().menus.frostDecl('none')};` +\r\n '-webkit-text-stroke-width:0}'\r\n}\r\n\r\n/** Selector the dynamic header token rule targets — the same set as the static\r\n * headerPopoverRule above, so the two can never drift apart. */\r\nconst HEADER_TOKEN_SELECTOR = HEADER_SURFACES_PADDED.join(',')\r\n\r\n/** Header-popover surfaces: retint the menu token and (re)write the blur.\r\n * Mirrors applyProduced: the static rule above never changes, so a drag only\r\n * rewrites the blur variable and this one dynamic rule. */\r\nexport function applyHeaderPopovers(): void {\r\n const root = document.documentElement\r\n const px = rBlurs().header\r\n if (px > 0) root.style.setProperty('--dsh-any-blur-header', `blur(${px}px)`)\r\n else root.style.removeProperty('--dsh-any-blur-header')\r\n // Alpha: re-emit the live menu token's own color with the header opacity so\r\n // the popover keeps the host palette (and follows a picked color) while fading\r\n // independently of the card slider. EVERY fill token the release paints menus\r\n // from gets that same literal (`menuFillDecls`), because one header opacity has\r\n // to mean one look whether the surface reads the old name or the layer's new one.\r\n //\r\n // LITERAL, not a CSS var indirection — see the note above on the header group.\r\n // The declaration goes into a dedicated sheet so the static rule stays\r\n // selector-only and a drag rewrites just this one text node.\r\n let opacity = rHeaderOpacity()\r\n if (opacity < 0) opacity = 0\r\n if (opacity > 1) opacity = 1\r\n const surfaces = paletteTokens() ?? readHostOpacityTokens()\r\n const menu = surfaces?.[MENU_FILL_TOKEN]\r\n const el = ensureHeaderStyle()\r\n // Nothing resolved: emit NO declaration rather than an invalid one, so the\r\n // surface keeps the re-scoped token value instead of going transparent.\r\n const css = menu === undefined\r\n ? ''\r\n : `${HEADER_TOKEN_SELECTOR}{${menuFillDecls(toRgba(menu, opacity))}}`\r\n if (el.textContent !== css) el.textContent = css\r\n}\r\n\r\nlet headerStyleEl: HTMLStyleElement | null = null\r\nfunction ensureHeaderStyle(): HTMLStyleElement {\r\n if (headerStyleEl?.isConnected) return headerStyleEl\r\n headerStyleEl = document.createElement('style')\r\n headerStyleEl.dataset.plugin = 'dsh-any-background-header'\r\n document.head.appendChild(headerStyleEl)\r\n return headerStyleEl\r\n}\r\n\r\n/** Pin the exempt groups (confirm dialogs and the session-row menu) so no\r\n * appearance slider moves them — while KEEPING the active theme color.\r\n *\r\n * \"Default\" here means \"not faded, not blurred\", NOT \"host-palette original\":\r\n * an earlier version restored the :root host colors, which also stripped the\r\n * picked theme color and made the menu look un-themed. The correct source is\r\n * the same one every other slider uses (the plugin palette when there is one,\r\n * else the host's resolved tokens) with alpha pinned to 1 — so the surface\r\n * keeps whatever color the theme currently dictates and only loses the slider's\r\n * translucency and blur.\r\n *\r\n * Emitted as REAL literals into a dedicated stylesheet, never as\r\n * `var(--x, var(--x))`: a self-referencing fallback is a CSS cycle that\r\n * computes to the guaranteed-invalid value and turns every consuming\r\n * `background:var(--dsw-alias-bg-layer-2)` fully transparent. Literals also\r\n * mean that when no color can be resolved we emit NO declaration at all, so\r\n * the surface keeps the re-scoped value rather than going transparent. */\r\nexport function applyExemptDefaults(): void {\r\n if (typeof document === 'undefined') return\r\n const source = paletteTokens() ?? readHostOpacityTokens()\r\n const el = ensureExemptStyle()\r\n const decls: string[] = []\r\n // Only declare a token we actually resolved a color for, and pin it opaque.\r\n const add = (token: string, value: string | undefined): void => {\r\n if (value === undefined || value === '') return\r\n // Literal with alpha 1 — no cycle possible, and no slider translucency.\r\n decls.push(`${token}:${toRgba(value, 1)}`)\r\n }\r\n add('--dsw-alias-bg-layer-1', source?.['--dsw-alias-bg-layer-1'])\r\n add('--dsw-alias-bg-layer-2', source?.['--dsw-alias-bg-layer-2'])\r\n add('--dsw-alias-bg-layer-3', source?.['--dsw-alias-bg-layer-3'])\r\n // One sampled color, declared under EVERY name this release paints a menu from:\r\n // a session-row menu on a `MenuSurface` host fades out of the layer token, and\r\n // pinning only the old name would leave it faded while everything else around it\r\n // went opaque. A name the host does not read is inert.\r\n const menuColor = source?.[MENU_FILL_TOKEN]\r\n for (const name of hostAdapter().menus.fillTokens) add(name, menuColor)\r\n if (decls.length === 0) {\r\n // Nothing resolved (pre-mount / host ships none): drop the pin rather than\r\n // emit an invalid one. The surfaces keep the re-scoped look.\r\n if (el.textContent !== '') el.textContent = ''\r\n return\r\n }\r\n const dialog = '[role=\"dialog\"][aria-modal=\"true\"]:not([aria-labelledby])'\r\n const body = decls.join(';')\r\n const css =\r\n `${dialog},${dialog} *{${body}}` +\r\n `[role=\"menu\"]:has([class*=\"_danger\"]){${body}}`\r\n if (el.textContent !== css) el.textContent = css\r\n}\r\n\r\nlet exemptStyleEl: HTMLStyleElement | null = null\r\nfunction ensureExemptStyle(): HTMLStyleElement {\r\n if (exemptStyleEl?.isConnected) return exemptStyleEl\r\n exemptStyleEl = document.createElement('style')\r\n exemptStyleEl.dataset.plugin = 'dsh-any-background-exempt'\r\n document.head.appendChild(exemptStyleEl)\r\n return exemptStyleEl\r\n}\r\n\r\n// ── Produced/artifact surfaces ─────────────────────────────────────────────\r\n// The surfaces owned by the \"产出物/高亮内容\" (produced/highlights) slider are\r\n// the code blocks inside conversation content (host CodeBlock → `.md-code-block`\r\n// wrapping `[data-code-block-content]` > `<pre class=\"shiki css-variables\">`),\r\n// their banner, the inline `code` chips in markdown (the small background box\r\n// around identifiers like `@supports`, rendered by the host's\r\n// `:not(pre) > code` rule) and the composer's reference chips\r\n// (`[data-composer-chip]`).\r\n//\r\n// Those sliders are an ALPHA control for the color a surface ALREADY uses — they\r\n// must never paint a color of their own. The host paints the block background\r\n// from its own tokens: `--dsl-code-block-background` (= `--dsw-alias-markdown-\r\n// code-block`) on the wrapper and again on the inner `pre`,\r\n// `--dsl-code-block-banner-background-color` on the banner, and\r\n// `--dsw-alias-markdown-inline-code` on an inline chip. The shiki `pre` also\r\n// carries an inline `background-color: var(--shiki-background)`, which the theme\r\n// package aliases to that same `--dsw-alias-markdown-code-block`. So every layer\r\n// is re-emitted through `color-mix(in srgb, <its own host color> <pct>,\r\n// transparent)`: 100% reproduces the host color exactly, and lowering it fades\r\n// THAT surface instead of stacking a second background on top of the original\r\n// one.\r\n//\r\n// The opaque wrapper layers (the `.md-code-block` fill and the sticky banner\r\n// wrapper's `--dsw-alias-bg-base` backdrop) are cleared so the wallpaper shows\r\n// through once, and `backdrop-filter` gets something to frost; only the `pre`,\r\n// the banner and the inline chips carry the modulated color. The\r\n// `--shiki-background` alias is re-pointed on the content container as well, so\r\n// the same control reaches code blocks that live outside `.md-code-block` (the\r\n// document preview) and take their background from that inline variable alone.\r\n// Values ride root CSS variables, so blocks and chips that stream in after a\r\n// reply pick them up without an observer.\r\nexport const PRODUCED_RULE =\r\n // ── Frosting (backdrop-filter) ─────────────────────────────────────────────\r\n // Kept outside the color-mix guard so it never depends on color-mix support.\r\n // TerminalBlock ([data-terminal]), ReadBlock ([data-read]) and\r\n // ContextInjectionRow body ([data-context-injection-body]) all share the\r\n // --dsw-alias-markdown-code-block surface as code blocks, so they receive\r\n // both blur and alpha modulation below.\r\n //\r\n // ChangedFiles ([data-changed-files]): from 0.1.7 the card ROOT carries its own\r\n // fill (--dsw-alias-bg-layer-1), so the frost belongs on the root — one frost\r\n // per card. The header button and its tile are faded by alpha alone (see the\r\n // --changes-fill arms below); frosting them too would blur the already frosted\r\n // root behind them.\r\n //\r\n // SearchBlock ([data-search]) and WebBlock ([data-web]) both paint from\r\n // --dsw-alias-markdown-code-block (their .block root), so they join the\r\n // same produced surface group.\r\n //\r\n // The expanded IN/OUT card (.ioCard, ToolRow + bash-sample) also paints from\r\n // --dsw-alias-markdown-code-block. It carries no data-* attribute, so it binds\r\n // by its CSS-Module class shape: the harness build hashes classes as\r\n // `<hash>_<localName>` (e.g. `o3BgMG_ioCard`), so `[class*=\"_ioCard\"]` is\r\n // stable across builds while a bare `.ioCard` would never match.\r\n //\r\n // The three surfaces 0.1.7 added to the produced family all filled from\r\n // --dsw-alias-markdown-code-block when they appeared: DiffBlock ([data-diff]), the\r\n // tool-result detail block (ToolDetails .root, marked [data-inspect] when it offers\r\n // the inspector) and the turn-event row ([data-turn-trigger]). They frost off the\r\n // same attribute either way; the turn row's own fill moved at `0.2.0-rc.2`, which\r\n // is the alpha arm's business, not this list's.\r\n //\r\n // Inline `code` chips (:not(pre)>code) ride the frost as well: they are the one\r\n // produced surface a reader sees mid-sentence, and leaving them opaque while the\r\n // block behind them faded made them look pinned to the wallpaper instead of part\r\n // of it. They are display:inline-flex, so the promotion risk is real — the\r\n // compact markdown variant ([data-markdown-variant=\"compact\"], used by the\r\n // reasoning rows) resets display to `inline`, where a frost would fragment\r\n // across line boxes, so that context opts back out.\r\n //\r\n // The hover preview window ([style*=\"--dsh-hover-preview-fade\"]) is the artifact\r\n // a produced surface opens: `ui-primitives/HoverCard` portals its card to\r\n // document.body, so no in-tree re-scope can reach it and it painted its own\r\n // literal `--dsw-hovercard-bg: #2C2C2E` (identical in both themes, deliberately a\r\n // component variable and not a theme token — see HoverCard.module.css) untouched\r\n // by any slider. That inline custom property is the only stable marker it has:\r\n // the class is hashed per build, and on 0.1.5-rc.2 / 0.1.6-alpha.2 the card\r\n // element carries no attribute at all, so those hosts simply never match it here\r\n // rather than being caught by a `[class$=\"_card\"]` that would also hit the\r\n // composer and the changed-files card.\r\n '[data-code-block-content] pre,[data-code-block-banner],[data-composer-chip],' +\r\n '[data-changed-files],' +\r\n '[data-terminal],[data-read],[data-diff],[data-context-injection-body],' +\r\n '[data-search],[data-web],[class*=\"_ioCard\"],' +\r\n '[data-inspect],[data-turn-trigger],' +\r\n '[style*=\"--dsh-hover-preview-fade\"],' +\r\n ':not(pre)>code{' +\r\n '-webkit-backdrop-filter:var(--dsh-any-blur-prod,none);' +\r\n 'backdrop-filter:var(--dsh-any-blur-prod,none)}' +\r\n '[data-markdown-variant=\"compact\"] :not(pre)>code{' +\r\n '-webkit-backdrop-filter:none;backdrop-filter:none}' +\r\n // ── dsh-better-sidebar workbench [data-dsh-bottom-panel] ──────────────────\r\n // The third-party bottom panel is a produced surface by nature — it opens the\r\n // artifact a conversation row points at — so since 0.3.2 the produced pair owns\r\n // it instead of the panel row, which is now just the host's own right Sidebar.\r\n // Unlike a code block it does not paint one token: every surface inside it\r\n // (pane chrome, tab bar, cards) reads a layer token, so its alpha cannot ride\r\n // `--dsh-any-prod-pct` and re-emit in place; the four tokens are re-scoped from\r\n // root variables `applyProduced` writes at the slider's alpha, exactly the way\r\n // PANEL_TOKEN_RULE does for the native panel. Kept in its own block, not merged\r\n // into the selector list above, because an engine that drops one of these\r\n // declarations must not take the code-block frost down with it.\r\n `${BETTER_SIDEBAR_PANEL}{` +\r\n '-webkit-backdrop-filter:var(--dsh-any-blur-prod,none);' +\r\n 'backdrop-filter:var(--dsh-any-blur-prod,none)}' +\r\n `${BETTER_SIDEBAR_PANEL}{` +\r\n '--dsw-alias-bg-base:var(--dsh-any-prod-panel-bg-base);' +\r\n '--dsw-alias-bg-layer-1:var(--dsh-any-prod-panel-layer-1);' +\r\n '--dsw-alias-bg-layer-2:var(--dsh-any-prod-panel-layer-2);' +\r\n '--dsw-alias-bg-layer-3:var(--dsh-any-prod-panel-layer-3)}' +\r\n // ── Alpha (color-mix) ──────────────────────────────────────────────────────\r\n // Guarded: without color-mix support the host look stays untouched instead\r\n // of resolving the surface color to an invalid value.\r\n '@supports (background:color-mix(in srgb,red 50%,transparent)){' +\r\n // ── Existing code-block surfaces ───────────────────────────────────────────\r\n '.md-code-block{background:transparent!important}' +\r\n '.md-code-block>div{background-color:transparent!important}' +\r\n // Every base falls back to the older token names (0.1.2-alpha.4 has no\r\n // `--dsl-code-block-*` yet), so the color-mix can never resolve to an\r\n // invalid value and blank a surface out.\r\n '.md-code-block [data-code-block-content] pre{' +\r\n 'background-color:color-mix(in srgb,var(--dsl-code-block-background,var(--dsw-alias-markdown-code-block,transparent)) var(--dsh-any-prod-pct,100%),transparent)!important}' +\r\n '.md-code-block [data-code-block-banner]{' +\r\n 'background-color:color-mix(in srgb,var(--dsl-code-block-banner-background-color,var(--dsw-alias-markdown-code-block-banner,transparent)) var(--dsh-any-prod-pct,100%),transparent)!important}' +\r\n // Banners outside the markdown block: 0.1.7 moved ReadBlock / DiffBlock /\r\n // CodeBlock onto one shared CodeCard, whose `.header` fills from\r\n // `--dsl-code-block-banner-background-color` when a markdown block is in scope\r\n // and otherwise from `--dsl-code-block-background` → `--dsw-alias-markdown-code-block`\r\n // (CodeCard.module.css:16). Re-emitting that same chain is what keeps the banner\r\n // themed: the older `--dsw-alias-markdown-code-block-banner` token below is a\r\n // near-white value 0.1.7 no longer paints here, so forcing it made every read /\r\n // diff header a pale slab that ignored the produced alpha.\r\n '[data-code-block-banner]{' +\r\n 'background-color:color-mix(in srgb,var(--dsl-code-block-banner-background-color,var(--dsl-code-block-background,var(--dsw-alias-markdown-code-block,transparent))) var(--dsh-any-prod-pct,100%),transparent)!important}' +\r\n '[data-code-block-content]{' +\r\n '--shiki-background:color-mix(in srgb,var(--dsw-alias-markdown-code-block,var(--dsl-code-block-background,transparent)) var(--dsh-any-prod-pct,100%),transparent)}' +\r\n // Inline markdown `code` chips: the host's own selector shape, so the chip\r\n // keeps its token color and only loses alpha (plus the shared frost).\r\n ':not(pre)>code{' +\r\n 'background-color:color-mix(in srgb,var(--dsw-alias-markdown-inline-code,transparent) var(--dsh-any-prod-pct,100%),transparent)!important}' +\r\n '[data-composer-chip]>*{' +\r\n 'background-color:color-mix(in srgb,var(--dsw-alias-interactive-bg-hover,transparent) var(--dsh-any-prod-pct,100%),transparent)!important}' +\r\n // ── TerminalBlock [data-terminal] ──────────────────────────────────────────\r\n // Root: background: var(--dsw-alias-markdown-code-block) (TerminalBlock.module.css).\r\n // The copy button inside re-asserts that same token as an opaque fill so it\r\n // stays readable over scrolling output. Clear it so the card fades uniformly.\r\n '[data-terminal]{' +\r\n 'background-color:color-mix(in srgb,var(--dsw-alias-markdown-code-block,transparent) var(--dsh-any-prod-pct,100%),transparent)!important}' +\r\n '[data-terminal] button{background-color:transparent!important}' +\r\n // ── ReadBlock [data-read] / DiffBlock [data-diff] ────────────────────────\r\n // Both are CodeCards from 0.1.7: the root fills from\r\n // --dsw-alias-markdown-code-block and the banner carries\r\n // [data-code-block-banner], handled by the shared banner arm above. The guarded\r\n // rule below only serves 0.1.6, where ReadBlock's first child WAS a banner\r\n // painted from --dsw-alias-markdown-code-block-banner and carried no marker.\r\n '[data-read],[data-diff]{' +\r\n 'background-color:color-mix(in srgb,var(--dsw-alias-markdown-code-block,transparent) var(--dsh-any-prod-pct,100%),transparent)!important}' +\r\n '[data-read]>div:first-child:not([data-code-block-banner]),' +\r\n '[data-diff]>div:first-child:not([data-code-block-banner]){' +\r\n 'background-color:color-mix(in srgb,var(--dsw-alias-markdown-code-block-banner,transparent) var(--dsh-any-prod-pct,100%),transparent)!important}' +\r\n // ── ContextInjectionRow body [data-context-injection-body] ────────────────\r\n // The .body element uses --dsw-alias-markdown-code-block (same as code blocks).\r\n '[data-context-injection-body]{' +\r\n 'background-color:color-mix(in srgb,var(--dsw-alias-markdown-code-block,transparent) var(--dsh-any-prod-pct,100%),transparent)!important}' +\r\n // ── ToolDetails [data-inspect] / turn-event row [data-turn-trigger] ───────\r\n // The two produced surfaces 0.1.7 added outside the code-block family. They read\r\n // the same token through `0.1.7` … `0.2.0-rc.1` (ToolDetails.module.css,\r\n // TurnTriggerNodeView.module.css), and `0.2.0-rc.2` gave the turn row its own\r\n // pair — but wrote it the way a host hands a surface to its theme:\r\n // background: var(--dsw-alias-turn-trigger-bg, var(--dsw-alias-markdown-code-block))\r\n // :hover var(--dsw-alias-turn-trigger-bg-hover, var(--dsw-alias-interactive-bg-hover))\r\n // with both aliases declared on `body`, so in DARK mode the row is\r\n // `--dsw-alias-interactive-bg-hover` (and its hover is `-bg-active`) while the\r\n // code block stays where it was. Reading the same chain is what keeps this arm\r\n // release-neutral — a `var()` fallback is the host's own \"if that property is not\r\n // set\" test, so an older host takes the code-block color and a newer one takes its\r\n // own, with no version check here. Sharing one rule with `[data-inspect]` instead\r\n // would be a visible bug: the `!important` mix would keep painting the row with\r\n // the pre-rc.2 color and the row would stop tracking its hover state.\r\n '[data-inspect]{' +\r\n 'background-color:color-mix(in srgb,var(--dsw-alias-markdown-code-block,transparent) var(--dsh-any-prod-pct,100%),transparent)!important}' +\r\n '[data-turn-trigger]{' +\r\n 'background-color:color-mix(in srgb,var(--dsw-alias-turn-trigger-bg,var(--dsw-alias-markdown-code-block,transparent)) var(--dsh-any-prod-pct,100%),transparent)!important}' +\r\n '[data-turn-trigger]:hover{' +\r\n 'background-color:color-mix(in srgb,var(--dsw-alias-turn-trigger-bg-hover,var(--dsw-alias-interactive-bg-hover,transparent)) var(--dsh-any-prod-pct,100%),transparent)!important}' +\r\n // ── ChangedFiles card [data-changed-files] ────────────────────────────────\r\n // 0.1.7 gave the card a root fill (--dsw-alias-bg-layer-1) plus a header and a\r\n // file-count tile that both paint from --changes-fill (neutral-50 light /\r\n // neutral-850 dark, redefined under body[data-ds-dark-theme]). All three follow\r\n // the produced slider now: with the root opaque and the file rows transparent,\r\n // the card read as a hard white plate no matter where the slider sat. The tile\r\n // is alpha-only because the root behind it already frosts.\r\n //\r\n // The root cannot fade with color-mix the way its siblings do: --dsw-alias-bg-layer-1\r\n // is the token the interface \"card\" (option-panel) slider re-emits globally on\r\n // `body`, so mixing on top of it multiplied two alphas and the artifact card\r\n // answered to both sliders. It reads the produced slider's own re-emit of the\r\n // RAW token instead — one surface, one slider.\r\n '[data-changed-files]{' +\r\n 'background-color:var(--dsh-any-prod-layer-1,var(--dsw-alias-bg-layer-1,transparent))!important}' +\r\n '[data-changed-files]>button:first-child{' +\r\n 'background-color:color-mix(in srgb,var(--changes-fill,transparent) var(--dsh-any-prod-pct,100%),transparent)!important}' +\r\n '[data-changed-files]>button:first-child:hover{' +\r\n 'background-color:color-mix(in srgb,var(--changes-hover,var(--changes-fill,transparent)) var(--dsh-any-prod-pct,100%),transparent)!important}' +\r\n '[data-changed-files]>button:first-child>span:first-child{' +\r\n 'background-color:color-mix(in srgb,var(--changes-fill,transparent) var(--dsh-any-prod-pct,100%),transparent)!important}' +\r\n // ── Hover preview window [style*=\"--dsh-hover-preview-fade\"] ───────────────\r\n // See the frost list above for why this is the marker. Two surfaces live under\r\n // that one attribute, and they do NOT paint from the same place:\r\n // · the plain card — `.card` in HoverCard.module.css — keeps its component\r\n // literal `--dsw-hovercard-bg: #2C2C2E` (dark in BOTH themes by the host's\r\n // own choice), so mixing on that token fades the color the host uses.\r\n // · the `preview` variant (`.preview`, what ChangedFiles opens) repaints from\r\n // --dsw-alias-bg-layer-1, i.e. the THEME surface, and never redefines the\r\n // literal. Mixing on --dsw-hovercard-bg there would replace a light themed\r\n // card with the dark one — measured: the preview came out\r\n // rgb(44,44,46) over a light theme. It reads the produced slider's raw\r\n // layer-1 instead, the same single-slider route the changed-files card uses.\r\n // The fallback keeps the host's own color if that variable has not been written\r\n // yet; it is the card-slider remapped token there, which is the pre-existing host\r\n // look, not a second alpha.\r\n '[style*=\"--dsh-hover-preview-fade\"]{' +\r\n 'background-color:color-mix(in srgb,var(--dsw-hovercard-bg,#2c2c2e) var(--dsh-any-prod-pct,100%),transparent)!important}' +\r\n '[style*=\"--dsh-hover-preview-fade\"][class*=\"_preview\"]{' +\r\n 'background-color:var(--dsh-any-prod-layer-1,var(--dsw-alias-bg-layer-1,transparent))!important}' +\r\n // ── SearchBlock [data-search] ─────────────────────────────────────────────\r\n // Root (.block): background: var(--dsw-alias-markdown-code-block).\r\n // Header (.header): background: var(--dsw-alias-markdown-code-block-banner).\r\n // Only the root body fades — the header banner keeps its opaque host color\r\n // so the white/grey title bar stays visually stable regardless of the slider.\r\n '[data-search]{' +\r\n 'background-color:color-mix(in srgb,var(--dsw-alias-markdown-code-block,transparent) var(--dsh-any-prod-pct,100%),transparent)!important}' +\r\n // ── WebBlock [data-web] ───────────────────────────────────────────────────\r\n // Root (.block): background: var(--dsw-alias-markdown-code-block).\r\n // No banner sub-surface; the single fill fades uniformly.\r\n '[data-web]{' +\r\n 'background-color:color-mix(in srgb,var(--dsw-alias-markdown-code-block,transparent) var(--dsh-any-prod-pct,100%),transparent)!important}' +\r\n // ── Expanded IN/OUT card [class*=\"_ioCard\"] ───────────────────────────────\r\n // ToolRow's and bash-sample's .ioCard: background: var(--dsw-alias-markdown-\r\n // code-block), the same surface as a code block. No banner sub-surface.\r\n '[class*=\"_ioCard\"]{' +\r\n 'background-color:color-mix(in srgb,var(--dsw-alias-markdown-code-block,transparent) var(--dsh-any-prod-pct,100%),transparent)!important}' +\r\n '}'\r\n\r\n// ── Per-part text stroke (-webkit-text-stroke) ────────────────────────────────\r\n// Same surface groups as the blur sliders (issue #16). Values ride two root\r\n// CSS variables per group — width and resolved color — so a slider drag only\r\n// rewrites variables while the (static) rules below never change. paint-order\r\n// MUST accompany every stroke declaration: without it the stroke paints over\r\n// the glyph and thins the characters.\r\n//\r\n// The two homepage columns (bg / sidebar groups) are discovered structurally\r\n// (see discoverParts) and carry the stroke INLINE from applyStrokes instead of\r\n// a static selector. Every other group binds to the same stable selectors the\r\n// blur rules already proved:\r\n// settings → the settings dialog (SETTINGS_PANEL_SEL)\r\n// card → the popover/menu surface set (popoverBlurRule's selectors)\r\n// input → composer card + cordis panel (inputBlurRule's markers), the\r\n// seat takeover cards beside the capsule, and the native editors\r\n// inside them (form controls do not inherit text properties from\r\n// their container)\r\n// chat → the conversation message column ([data-chat-flow])\r\n// trajectory → the trajectory view root\r\n// produced → code blocks / banners / inline code chips / composer chips.\r\n// Being a DIRECT rule it also shields those surfaces from the\r\n// inherited chat stroke — with produced width 0 the reset is\r\n// exactly the exemption shiki multi-color text needs.\r\n// panel → the host's own right Sidebar column (the dsh-better-sidebar\r\n// workbench sits in the produced group above, since 0.3.2)\r\n//\r\n// Global exemptions: SVG glyphs (host icons are paths, but paint-order is\r\n// inherited and would subtly alter stroked-and-filled icon rendering) and\r\n// ::placeholder text (italic hint text must stay unstroked).\r\n\r\nexport const STROKE_RULE = [\r\n // settings\r\n `${SETTINGS_PANEL_SEL}{-webkit-text-stroke:var(--dsh-any-stroke-settings-w,0px) var(--dsh-any-stroke-settings-c,transparent);paint-order:stroke fill}`,\r\n // card / popovers — selector set mirrors popoverBlurRule\r\n `[role=\"menu\"]:not([data-dockkit-tab-menu]),[role=\"listbox\"],body>[role=\"tree\"],body>[role=\"dialog\"]:not([aria-modal=\"true\"])` +\r\n `{-webkit-text-stroke:var(--dsh-any-stroke-card-w,0px) var(--dsh-any-stroke-card-c,transparent);paint-order:stroke fill}`,\r\n // input / controls — native editors need their own declaration\r\n `[data-composer-card],[data-cordis-panel],` +\r\n `[data-composer-card] textarea,[data-composer-card] input,[data-composer-card] [contenteditable],` +\r\n `[data-cordis-panel] input,[data-cordis-panel] textarea,` +\r\n // the seat takeover cards belong to this slider too (see inputBlurRule)\r\n `${COMPOSER_TAKEOVER_CARD},${COMPOSER_TAKEOVER_EDITOR}` +\r\n `{-webkit-text-stroke:var(--dsh-any-stroke-input-w,0px) var(--dsh-any-stroke-input-c,transparent);paint-order:stroke fill}`,\r\n // session header bar (its title, actions and view tabs inherit from the row)\r\n `.${HEADER_BAR_CLASS}{-webkit-text-stroke:var(--dsh-any-stroke-headerBar-w,0px) var(--dsh-any-stroke-headerBar-c,transparent);paint-order:stroke fill}`,\r\n // chat message column\r\n `[data-chat-flow]{-webkit-text-stroke:var(--dsh-any-stroke-chat-w,0px) var(--dsh-any-stroke-chat-c,transparent);paint-order:stroke fill}`,\r\n // trajectory view\r\n `[data-conversation-composer-overlay]{-webkit-text-stroke:var(--dsh-any-stroke-trajectory-w,0px) var(--dsh-any-stroke-trajectory-c,transparent);paint-order:stroke fill}`,\r\n // produced / artifact text — direct rule doubles as the chat-inheritance shield;\r\n // also covers changed-files card, tool-call terminal, file-read block and\r\n // context-injection notice (all \"produced/highlight\" surfaces).\r\n // SearchBlock [data-search] and WebBlock [data-web] join the same group:\r\n // they share the --dsw-alias-markdown-code-block surface and appear inline\r\n // in the conversation column, so they inherit the chat stroke without this\r\n // direct exemption, just like the other produced surfaces.\r\n // The expanded IN/OUT card joins by CSS-Module class shape ([class*=\"_ioCard\"],\r\n // see PRODUCED_RULE) — same surface, same exemption.\r\n // [data-diff] / [data-inspect] / [data-turn-trigger] join with the same PRODUCED_RULE\r\n // group: without a direct rule here their text would keep inheriting the chat\r\n // stroke while every other produced surface obeyed its own slider.\r\n `[data-code-block-content] pre,[data-code-block-content],[data-code-block-banner],[data-composer-chip],:not(pre)>code,` +\r\n `[data-changed-files],[data-terminal],[data-read],[data-diff],[data-inspect],[data-turn-trigger],[data-context-injection-body],[data-search],[data-web],[class*=\"_ioCard\"],[style*=\"--dsh-hover-preview-fade\"]` +\r\n // The workbench joined this group with 0.3.2 (PRODUCED_RULE), so its text does\r\n // too — otherwise the produced stroke would cover every artifact except the one\r\n // that opens them.\r\n `,${BETTER_SIDEBAR_PANEL}` +\r\n `{-webkit-text-stroke:var(--dsh-any-stroke-produced-w,0px) var(--dsh-any-stroke-produced-c,transparent);paint-order:stroke fill}`,\r\n // the host's own right Sidebar column\r\n `${PANEL_SURFACES}{-webkit-text-stroke:var(--dsh-any-stroke-panel-w,0px) var(--dsh-any-stroke-panel-c,transparent);paint-order:stroke fill}`,\r\n // header popovers — the same surfaces as headerPopoverRule, unpadded: a\r\n // stroke never competed with the card group's backdrop-filter, so raising\r\n // specificity here would change which group wins and is not ours to decide.\r\n `${HEADER_SURFACES.join(',')}` +\r\n `{-webkit-text-stroke:var(--dsh-any-stroke-header-w,0px) var(--dsh-any-stroke-header-c,transparent);paint-order:stroke fill}`,\r\n // exemptions\r\n // Turn status / progress chrome — never owned by the \"conversation text\r\n // frame\" (chat) stroke group, because `-webkit-text-stroke` is INHERITED: a rule\r\n // on [data-chat-flow] reaches straight into these rows, and on every host\r\n // generation that damage is not cosmetic.\r\n //\r\n // One selector per shape actually observed, so all generations are covered\r\n // without a version check — an attribute a release does not emit simply matches\r\n // nothing:\r\n // · [role=\"status\"] — 0.1.5/0.1.6 render the live line as a bare\r\n // `.turnStatus` div under [data-chat-flow] (ChatView.module.css: brand-blue\r\n // gradient + background-clip:text + -webkit-text-fill-color:transparent).\r\n // This is the reported 0.1.6 regression. It also covers the hidden live\r\n // announcement 0.1.7 emits for a11y, and the retry/error status rows.\r\n // · [data-turn-process] — the turn-process disclosure row (0.1.6 and 0.1.7\r\n // TurnProcessNodeView). Its label is elapsed-time / activity chrome\r\n // (\"深度求索中,用时40秒\", \"已搜索代码并协调子任务\"), not conversation prose.\r\n // · [style*=\"--dsh-text-shimmer-spread\"] / [data-text-shimmer] — the TextShimmer\r\n // primitive as 0.1.7 shipped it: it published that custom property INLINE on\r\n // the clipped element, so the substring match finds every instance whatever\r\n // the hashed class name is, and the semantic attribute marks exactly the\r\n // moments the gradient exists. Here the stroke is destructive: the glyphs are\r\n // painted by their own clipped gradient with a transparent fill, so a stroke\r\n // repaints them as one flat stroke-coloured blob and the shimmer disappears.\r\n // · [data-shimmer] — the SAME primitive, rewritten at 0.2.0-rc.1 (the old\r\n // attribute and the `--dsh-text-shimmer-spread` property are both gone from\r\n // that tag). Its paint moved off the text onto an absolutely-positioned\r\n // overlay (`.decoration` / `.sweep` / `.highlight`), so the failure mode\r\n // changed rather than disappeared: the real glyphs keep their own color, but\r\n // the inherited stroke lands on BOTH of the two stacked copies of the string,\r\n // outlining the sweeping one too. One rule on the root is enough here — the\r\n // attribute sits on the wrapper and the stroke reset inherits down into the\r\n // overlay subtree.\r\n //\r\n // `paint-order:normal` rides along for the same reason it does on `svg` below:\r\n // it is inherited too, and a stray `stroke fill` would reorder the fill.\r\n `[data-chat-flow] [role=\"status\"],` +\r\n `[data-chat-flow] [data-turn-process],` +\r\n `[data-chat-flow] [data-text-shimmer],` +\r\n `[data-chat-flow] [data-shimmer],` +\r\n `[data-chat-flow] [style*=\"--dsh-text-shimmer-spread\"]` +\r\n `{-webkit-text-stroke-width:0!important;paint-order:normal!important}`,\r\n `svg{-webkit-text-stroke-width:0!important;paint-order:normal!important}`,\r\n `::placeholder{-webkit-text-stroke-width:0!important}`,\r\n].join('')\r\n\r\n/** Groups whose stroke lands on the structurally-discovered columns (inline),\r\n * versus every group served by the static STROKE_RULE selectors. */\r\nconst STROKE_INLINE_GROUPS = ['bg', 'sidebar'] as const\r\ntype StrokeGroup = keyof PartBlurs\r\nconst STROKE_VAR_GROUPS: StrokeGroup[] = ['card', 'settings', 'chat', 'trajectory', 'input', 'panel', 'produced', 'header', 'headerBar']\r\n\r\n/** Resolve one group's stroke color key into a concrete CSS color.\r\n * 'auto' contrasts the FONT direction (white fonts → black stroke and vice\r\n * versa — mirrors the label flip in applyCustomTokensNow); 'theme' follows\r\n * the live palette's brand primary (picked color → generated palette, else\r\n * the host's own resolved token). */\r\nfunction strokeColor(s: StrokeConfig): string {\r\n switch (s.color) {\r\n case 'gray': return '#808080'\r\n case 'black': return '#000'\r\n case 'white': return '#fff'\r\n case 'custom': return s.customColor\r\n case 'theme': {\r\n if (rHasColor() || rSchemeOverride() !== 'auto') {\r\n const [h, sa, l] = rColor()\r\n return genTokens(h, sa, l, rColorScheme()).tokens['--dsw-alias-brand-primary'] ?? '#808080'\r\n }\r\n if (typeof getComputedStyle !== 'undefined') {\r\n const v = getComputedStyle(document.documentElement).getPropertyValue('--dsw-alias-brand-primary').trim()\r\n if (v !== '') return v\r\n }\r\n return '#808080'\r\n }\r\n case 'auto':\r\n default: {\r\n // Font direction, same derivation order as applyCustomTokensNow: picked\r\n // color's palette direction, then a forced scheme, then the wallpaper\r\n // brightness verdict; light fonts (unknown) default to a white stroke.\r\n let fontDark: boolean\r\n if (rHasColor()) fontDark = rColorScheme() === 'dark'\r\n else if (rSchemeOverride() !== 'auto') fontDark = rScheme() === 'dark'\r\n else if (rBgDark() !== null) fontDark = rBgDark() === true\r\n else fontDark = false\r\n return fontDark ? '#000' : '#fff'\r\n }\r\n }\r\n}\r\n\r\n/** Write every group's stroke width/color variables + the two column strokes.\r\n * Called from applyWp so palette/verdict changes re-derive 'auto'/'theme'. */\r\n/** Write (or clear) one column's inline text stroke. The stroke rides inline\r\n * styles and is fully removed at width 0 so nothing lingers after the slider\r\n * resets. */\r\nfunction applyInlineStroke(el: HTMLElement, s: StrokeConfig): void {\r\n if (s.width > 0) {\r\n el.style.setProperty('-webkit-text-stroke', `${s.width}px ${strokeColor(s)}`)\r\n el.style.setProperty('paint-order', 'stroke fill')\r\n } else {\r\n el.style.removeProperty('-webkit-text-stroke')\r\n el.style.removeProperty('paint-order')\r\n }\r\n}\r\n\r\nexport function applyStrokes(): void {\r\n const strokes = rStrokes()\r\n const root = document.documentElement\r\n for (const g of STROKE_VAR_GROUPS) {\r\n const s = strokes[g]\r\n root.style.setProperty(`--dsh-any-stroke-${g}-w`, `${s.width}px`)\r\n root.style.setProperty(`--dsh-any-stroke-${g}-c`, strokeColor(s))\r\n }\r\n // Columns are dynamically discovered; the var groups above ride CSS\r\n // variables, the two column groups ride inline styles.\r\n discoverParts()\r\n for (const g of STROKE_INLINE_GROUPS) {\r\n const el = g === 'bg' ? centerEl : sidebarEl\r\n if (el !== null) applyInlineStroke(el, strokes[g])\r\n }\r\n}\r\n\r\n/** Live per-group stroke update during slider drag (no full re-apply). */\r\nexport function setPartStroke(part: StrokeGroup, s: StrokeConfig): void {\r\n if (STROKE_VAR_GROUPS.includes(part)) {\r\n document.documentElement.style.setProperty(`--dsh-any-stroke-${part}-w`, `${s.width}px`)\r\n document.documentElement.style.setProperty(`--dsh-any-stroke-${part}-c`, strokeColor(s))\r\n return\r\n }\r\n discoverParts()\r\n const el = part === 'bg' ? centerEl : sidebarEl\r\n if (el === null) return\r\n applyInlineStroke(el, s)\r\n}\r\n\r\n/** Teardown only: drop every stroke variable and column inline stroke. */\r\nfunction removeStrokes(): void {\r\n const root = document.documentElement\r\n for (const g of [...STROKE_VAR_GROUPS, ...STROKE_INLINE_GROUPS]) {\r\n root.style.removeProperty(`--dsh-any-stroke-${g}-w`)\r\n root.style.removeProperty(`--dsh-any-stroke-${g}-c`)\r\n }\r\n for (const el of [centerEl, sidebarEl]) {\r\n if (el === null) continue\r\n el.style.removeProperty('-webkit-text-stroke')\r\n el.style.removeProperty('paint-order')\r\n }\r\n}\r\n\r\n// ── Custom interface font ─────────────────────────────────────────────────────\r\n// One font file owns a server-side slot served from /dsh-any-background/font.\r\n// Applying it means: register an @font-face for the plugin-owned 'DAnyFont'\r\n// family and re-scope the host's interface font token (--dsw-font-family, the\r\n// base stack every text consumer reads) to `'DAnyFont', <original stack>` at\r\n// body level — the body-level custom property shadows :root's for all\r\n// descendants, so the swap survives host theme re-assertions (they rewrite\r\n// :root only). The host's code font (--ds-font-family-code) is deliberately\r\n// untouched: code blocks keep their mono stack.\r\n// The <style> element carries both the @font-face and the token override, so\r\n// disabling/removing the font is just removing the element.\r\n\r\nconst FONT_FAMILY = 'DAnyFont'\r\nlet fontStyleEl: HTMLStyleElement | null = null\r\n\r\nfunction fontFormatForMime(mime: string | null): string {\r\n switch (mime) {\r\n case 'font/woff2': return 'woff2'\r\n case 'font/woff': return 'woff'\r\n case 'font/otf': return 'opentype'\r\n default: return 'truetype'\r\n }\r\n}\r\n\r\n/** Apply or clear the custom interface font. `url` is the serve URL (null =\r\n * nothing stored); `enabled` gates the token override without deleting the\r\n * file. The original host stack is re-read on every apply so a host skin\r\n * change is picked up, and stays as the fallback after 'DAnyFont'. */\r\nexport function applyFontFace(url: string | null, enabled: boolean, mime: string | null): void {\r\n if (url === null || !enabled) {\r\n fontStyleEl?.remove()\r\n fontStyleEl = null\r\n return\r\n }\r\n if (fontStyleEl === null || !fontStyleEl.isConnected) {\r\n fontStyleEl = document.createElement('style')\r\n fontStyleEl.dataset.plugin = 'dsh-any-background-font'\r\n document.head.appendChild(fontStyleEl)\r\n }\r\n let stack = ''\r\n if (typeof getComputedStyle !== 'undefined') {\r\n stack = getComputedStyle(document.documentElement).getPropertyValue('--dsw-font-family').trim()\r\n }\r\n if (stack === '') stack = \"-apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', sans-serif\"\r\n const fmt = fontFormatForMime(mime)\r\n fontStyleEl.textContent =\r\n `@font-face{font-family:'${FONT_FAMILY}';src:url('${url}') format('${fmt}');font-display:swap}` +\r\n // Inheritable consumers only: form controls with UA default fonts keep\r\n // their own look unless the host already opted them into the token.\r\n `body{--dsw-font-family:'${FONT_FAMILY}',${stack}}` +\r\n `input,textarea,select,button{font-family:var(--dsw-font-family)}`\r\n}\r\n\r\n/** Teardown only: drop the @font-face + token override. */\r\nfunction removeFontFace(): void {\r\n fontStyleEl?.remove()\r\n fontStyleEl = null\r\n}\r\n\r\n/** The four layer slots a panel-wide token re-scope owns — both the variable\r\n * names to write and the shape the token source comes back in. */\r\ninterface LayerVarNames { base: string; layer1: string; layer2: string; layer3: string }\r\n\r\n/** The host's own defaults, read from the live `:root` so a custom host skin or\r\n * theme override wins. */\r\nfunction readHostLayerTokens(): LayerVarNames | null {\r\n if (typeof getComputedStyle === 'undefined') return null\r\n const root = document.documentElement\r\n const cs = getComputedStyle(root)\r\n const base = cs.getPropertyValue('--dsw-alias-bg-base').trim()\r\n const layer1 = cs.getPropertyValue('--dsw-alias-bg-layer-1').trim()\r\n const layer2 = cs.getPropertyValue('--dsw-alias-bg-layer-2').trim()\r\n const layer3 = cs.getPropertyValue('--dsw-alias-bg-layer-3').trim()\r\n if (!base && !layer1 && !layer2 && !layer3) return null\r\n return { base, layer1, layer2, layer3 }\r\n}\r\n\r\n/** The host's own right Sidebar (`PANEL_TOKEN_RULE`) reads this set. */\r\nconst PANEL_LAYER_VARS: LayerVarNames = {\r\n base: '--dsh-any-panel-bg-base',\r\n layer1: '--dsh-any-panel-layer-1',\r\n layer2: '--dsh-any-panel-layer-2',\r\n layer3: '--dsh-any-panel-layer-3',\r\n}\r\n\r\n/** The dsh-better-sidebar workbench (see `PRODUCED_RULE`) reads this set, so the\r\n * two panels can follow two different sliders. */\r\nconst PROD_PANEL_LAYER_VARS: LayerVarNames = {\r\n base: '--dsh-any-prod-panel-bg-base',\r\n layer1: '--dsh-any-prod-panel-layer-1',\r\n layer2: '--dsh-any-prod-panel-layer-2',\r\n layer3: '--dsh-any-prod-panel-layer-3',\r\n}\r\n/** The changed-files card root needs one token only — the RAW `--dsw-alias-bg-layer-1`\r\n * at the produced alpha. It cannot mix on the token itself the way the other\r\n * produced surfaces do, because that name is what the interface card slider\r\n * re-emits globally on `body` (OPACITY_TOKEN_GROUPS), so mixing on it would bind\r\n * one artifact card to two sliders. */\r\nconst PROD_LAYER_VARS: Partial<LayerVarNames> = { layer1: '--dsh-any-prod-layer-1' }\r\n\r\nconst LAYER_KEYS = ['base', 'layer1', 'layer2', 'layer3'] as const\r\n\r\n/** Re-emit the four layer colors at `op` alpha into `names`. The source is the\r\n * plugin palette when a picked color / forced scheme owns the theme, otherwise\r\n * the host's own resolved tokens — a slider only ever supplies the alpha, so the\r\n * colors keep following whichever theme or host skin is active.\r\n *\r\n * Every pass writes SOMETHING: the re-scope rules live in the always-emitted\r\n * stylesheet, and a `var()` naming an unwritten variable makes the surface\r\n * guaranteed-invalid, which drops its background entirely rather than leaving it\r\n * on the host default. */\r\nfunction writeLayerVars(names: Partial<LayerVarNames>, op: number): void {\r\n const palette = paletteTokens()\r\n const src: Partial<LayerVarNames> = palette !== null\r\n ? {\r\n base: palette['--dsw-alias-bg-base'],\r\n layer1: palette['--dsw-alias-bg-layer-1'],\r\n layer2: palette['--dsw-alias-bg-layer-2'],\r\n layer3: palette['--dsw-alias-bg-layer-3'],\r\n }\r\n : readHostLayerTokens() ?? {}\r\n const root = document.documentElement\r\n if (LAYER_KEYS.every(k => !src[k])) {\r\n // Pre-mount, or neither source has shipped the tokens yet: nothing to retint,\r\n // so park the surfaces on transparent until the next apply.\r\n for (const k of LAYER_KEYS) if (names[k]) root.style.setProperty(names[k]!, 'transparent')\r\n return\r\n }\r\n for (const k of LAYER_KEYS) {\r\n const name = names[k]\r\n const v = src[k]\r\n if (name && v) root.style.setProperty(name, toRgba(v, op))\r\n }\r\n}\r\n\r\nexport function applyPanelOverrides(op: number): void {\r\n writeLayerVars(PANEL_LAYER_VARS, op)\r\n}\r\n\r\nfunction applyPanelBlur(px: number): void {\r\n if (px > 0) document.documentElement.style.setProperty('--dsh-any-blur-panel', `blur(${px}px)`)\r\n else document.documentElement.style.removeProperty('--dsh-any-blur-panel')\r\n}\r\n\r\n// Placeholder/hint text inside the composer and the plugin's own input\r\n// surfaces: rendered with the weak caption token (distinct from real input)\r\n// plus italic, so an empty box is never mistaken for typed content. Written\r\n// as a rule so it also covers placeholder text colored by the host's text tier.\r\nexport const PLACEHOLDER_RULE =\r\n '[data-composer-card] textarea::placeholder,' +\r\n '[data-composer-card] input::placeholder,' +\r\n '[data-composer-card] [contenteditable]::placeholder,' +\r\n '[data-cordis-panel] input::placeholder,' +\r\n '[data-cordis-panel] textarea::placeholder,' +\r\n `${COMPOSER_TAKEOVER_EDITOR}::placeholder,` +\r\n '.dab-input::placeholder,' +\r\n '.dab-input textarea::placeholder,' +\r\n '.dab-input input::placeholder' +\r\n '{color:var(--dsh-any-placeholder,var(--dsw-alias-label-caption,#8a8f98))!important;font-style:italic;opacity:.85}'\r\n\r\ntype LayerPrefix = '--dsh-any-bg-settings' | '--dsh-any-traj'\r\n\r\n/** Re-scope one surface group's layer tokens onto plugin-owned variables so a\r\n * dedicated slider owns its alpha (the host has no per-surface opacity). The\r\n * settings group additionally retints its dialog surface variable. Always\r\n * written explicitly — including at 100% — so removing a slider's effect means\r\n * writing 1, not deleting the variable (the style rules below have no fallback\r\n * and would otherwise resolve the body tokens that applyCustomTokens rewrote\r\n * with the homepage card alpha). */\r\nfunction applyLayerOverrides(prefix: LayerPrefix, op: number, surface: boolean): void {\r\n const [h, s, l] = rColor()\r\n const tokens = genTokens(h, s, l, rColorScheme()).tokens\r\n if (surface) {\r\n const surfaceColor = tokens['--dsw-alias-bg-layer-2']\r\n if (surfaceColor !== undefined) {\r\n document.documentElement.style.setProperty(`${prefix}-surface`, toRgba(surfaceColor, op))\r\n }\r\n }\r\n for (const layer of [1, 2, 3] as const) {\r\n const c = tokens[`--dsw-alias-bg-layer-${layer}`]\r\n if (c !== undefined) {\r\n document.documentElement.style.setProperty(`${prefix}-layer-${layer}`, toRgba(c, op))\r\n }\r\n }\r\n}\r\n\r\nexport function applySettingsOverrides(op: number): void {\r\n applyLayerOverrides('--dsh-any-bg-settings', op, true)\r\n}\r\n\r\n// ── Trajectory view opacity ──────────────────────────────────────────────\r\n// The trajectory view's own panels fully cover the root, so retinting only the\r\n// root background is invisible. Re-scope the view root's layer tokens to\r\n// plugin-owned variables so every surface follows the trajectory slider.\r\nexport const TRAJECTORY_STYLE_RULE =\r\n '[data-conversation-composer-overlay]{' +\r\n // No fallback inside var(): a self-referential fallback would be a cycle.\r\n '--dsw-alias-bg-layer-1:var(--dsh-any-traj-layer-1);' +\r\n '--dsw-alias-bg-layer-2:var(--dsh-any-traj-layer-2);' +\r\n '--dsw-alias-bg-layer-3:var(--dsh-any-traj-layer-3)}'\r\n\r\nexport function applyTrajectoryOverrides(op: number): void {\r\n applyLayerOverrides('--dsh-any-traj', op, false)\r\n}\r\n\r\n/** Register a callback fired when a wallpaper-extracted theme color is\r\n * adopted by the auto-adaptation path, so the section can re-register the\r\n * host skin, sync the editor UI and persist the pick (wallpaper.ts cannot\r\n * do those itself — they live in the section). */\r\nlet colorAdoptedListener: ((hsl: [number, number, number]) => void) | null = null\r\nexport function onColorAdopted(cb: (hsl: [number, number, number]) => void): () => void {\r\n colorAdoptedListener = cb\r\n return () => { if (colorAdoptedListener === cb) colorAdoptedListener = null }\r\n}\r\n\r\n/** Apply the theme color: use the saved pick directly, or fall back to\r\n * extracting a dominant color from the current wallpaper. */\r\nexport function applyThemeColor(): void {\r\n if (rHasColor()) {\r\n applyWp()\r\n return\r\n }\r\n const url = rWp()\r\n if (url) {\r\n // Paint the wallpaper immediately — the palette extract decodes the full\r\n // image and would otherwise leave the host's blank background on screen\r\n // for the whole decode. The verdict/skin settle a beat later on re-apply.\r\n applyWp()\r\n // Video mode samples the frame snapshot through the video's own placement\r\n // state; the image slot's framing does not apply to the snapshot.\r\n const st = cfg.backgroundType === 'video' ? rVideoBgState() : rBgState()\r\n void extractWallpaperColor(url, st).then(hsl => {\r\n // A swap during the decode (upload / rotation) points every URL-keyed\r\n // cache at the new picture; only adopt the color when this wallpaper is\r\n // still the active one.\r\n if (hsl && rWp() === url) {\r\n cfg.color = hsl\r\n // The listener runs before applyWp so the freshly registered skin and\r\n // the token pass below describe the same color.\r\n colorAdoptedListener?.(hsl)\r\n // The color changed, so a re-apply is needed for the token pass. When\r\n // the decode yielded nothing (or the wallpaper was swapped out) the\r\n // first applyWp above still describes the screen and a second one\r\n // would only re-do the same work.\r\n applyWp()\r\n }\r\n })\r\n } else {\r\n applyWp()\r\n }\r\n}\r\n\r\n/** Switch the background source type. For generated types a new live canvas is\r\n * attached to the wallpaper layer and a snapshot is kept for the store/preview. */\r\nexport function setBackgroundType(type: BackgroundType): void {\r\n cfg.backgroundType = type\r\n if (type === 'image') {\r\n // Restore the retained image upload and drop the generated brightness verdict.\r\n clearDynamicBg()\r\n setBgDark(null)\r\n setWpUrl(rWpImage())\r\n applyThemeColor()\r\n return\r\n }\r\n if (type === 'video') {\r\n // Restore the retained video upload; the frame snapshot stays the preview URL.\r\n clearDynamicBg()\r\n setBgDark(null)\r\n setWpUrl(null)\r\n applyThemeColor()\r\n return\r\n }\r\n // Keep existing params for this generated type so sub-type switches preserve adjustments.\r\n if (!cfg.generatedBg || cfg.generatedBg.type !== type) {\r\n cfg.generatedBg = defaultParamsFor(type)\r\n }\r\n applyGeneratedBg(cfg.generatedBg)\r\n}\r\n\r\nfunction randomSeed(): number {\r\n return Math.floor(Math.random() * 0x7fffffff)\r\n}\r\n\r\n/** Regenerate the current generated background with a new visual seed while\r\n * preserving the user's scale/intensity/speed/density/preset choices. */\r\nexport function regenerateGeneratedBg(): void {\r\n const params = cfg.generatedBg\r\n // 'video' also carries a generatedBg-less slot: bailing here keeps this from\r\n // racing applyWp's video branch (it would clear the player's state while the\r\n // video branch is setting it up).\r\n if (!params || cfg.backgroundType === 'image' || cfg.backgroundType === 'video') return\r\n cfg.generatedBg = { ...params, seed: randomSeed() }\r\n applyGeneratedBg(cfg.generatedBg)\r\n}\r\n\r\n/** Update a generated background's parameters and re-render. */\r\nexport function updateGeneratedBg(params: GeneratedBgParams): void {\r\n cfg.backgroundType = params.type\r\n cfg.generatedBg = params\r\n applyGeneratedBg(params)\r\n}\r\n\r\nfunction applyGeneratedBg(params: GeneratedBgParams): void {\r\n clearDynamicBg()\r\n clearVideoEl()\r\n ensureWpContainer()\r\n wpController = createDynamicBackground(params)\r\n if (wpEl) {\r\n wpEl.style.backgroundImage = 'none'\r\n wpEl.appendChild(wpController.canvas)\r\n }\r\n // The canvas paints its first frame on the next animation tick; only then is\r\n // the snapshot meaningful. Do NOT refresh the palette here — generated\r\n // backgrounds must not overwrite the user's picked theme color.\r\n requestAnimationFrame(() => {\r\n // Two guards, because clearDynamicBg() stops the OLD controller without\r\n // cancelling its already-scheduled rAF: a rapid regenerate (or a type\r\n // switch) leaves a stale callback whose `wpController` read is the NEW one.\r\n // Snapshotting through the captured `controller` and re-checking identity\r\n // after keeps a dead background's frame from overwriting the live URL.\r\n const controller = wpController\r\n if (controller === null) return\r\n const frame = controller.snapshot()\r\n if (wpController !== controller) return\r\n setWpUrl(frame)\r\n applyWp()\r\n snapshotListener?.()\r\n // One-shot brightness verdict from the captured frame to flip font\r\n // direction; never runs in the animation loop.\r\n setBgDark(null)\r\n void analyzeFrameDark(frame).then(dark => {\r\n if (dark === null || wpController !== controller) return\r\n applyVerdict(dark)\r\n applyCustomTokens(rOps())\r\n })\r\n })\r\n}\r\n\r\n// ── Per-part interface blur ───────────────────────────────────────────────────\r\n// The AppFrame columns use hashed CSS-module classes, so parts are located\r\n// structurally: the shell overlay carries a stable data attribute and the\r\n// sidebar/center/rightbar columns are its preceding siblings.\r\n//\r\n// DSH 0.1.5-rc.1+ has only THREE columns in the frame: [sidebar, center,\r\n// rightbar]. The pre-rc.1 \"details\" column no longer exists — the frame\r\n// tree in 0.1.5-rc.1+ is:\r\n//\r\n// [data-app-frame]? → [sidebarCol] [CenterColumn (wraps main)] [RightbarColumn] [data-shell-overlay]\r\n//\r\n// The rightbar carries the stable `[data-rightbar-col]` marker, so we resolve\r\n// it directly and never let `discoverParts` collapse the right panel into a\r\n// \"details\" column — that mis-target painted the rightbar's surface with the\r\n// main-bg tint and backdrop-filter, making it disappear into the page.\r\n//\r\n// backdrop-filter must NEVER go directly on a host part: it turns the element\r\n// into a containing block for fixed-positioned descendants, which would trap\r\n// the host's settings dialog inside the column. Each blurred part carries an\r\n// isolated ::before underlay holding the backdrop-filter instead.\r\nlet frameEl: HTMLElement | null = null\r\nlet sidebarEl: HTMLElement | null = null\r\nlet centerEl: HTMLElement | null = null\r\nlet rightEl: HTMLElement | null = null\r\n\r\nconst PART_BLUR_CLASS = 'dab-part-blur'\r\nconst PART_UNDERLAY_CLASS = 'dab-part-underlay'\r\n\r\n/** The AppFrame's main-bg clear-out, as a class rather than an inline write.\r\n *\r\n * WHY NOT INLINE (measured on 0.1.7): the frame's own translucent\r\n * `--dsw-alias-bg-base` is what hides the wallpaper, so `applyPartOpacities` has\r\n * to clear it. Written as `frameEl.style.background = 'transparent'` the clear\r\n * survived a settings change but not a sidebar open/close — the host owns that\r\n * element's `style` too (it animates `grid-template-columns`), and while it\r\n * re-asserts its own background the frame snaps back to an opaque\r\n * `rgb(200,207,218)`: wallpaper gone, and every frost on top of it flattened,\r\n * because a backdrop-filter with nothing behind it has nothing to blur. A class\r\n * rule with `!important` sits outside the host's `style` writes entirely, so the\r\n * clear cannot be re-clobbered and there is nothing to re-apply. */\r\nexport const PART_FRAME_CLASS = 'dab-frame-clear'\r\nexport const FRAME_CLEAR_RULE = `.${PART_FRAME_CLASS}{background:transparent!important}`\r\n\r\nconst PART_BLUR_RULE =\r\n // The dot is load-bearing: without `isolation` the host does not create a\r\n // stacking context, so the underlay's `z-index:-1` escapes into the page's and\r\n // the frost paints over the wrong area instead of staying inside the surface.\r\n `.${PART_BLUR_CLASS}{isolation:isolate}` +\r\n // …but that same stacking context is a trap for the host's dialogs: a\r\n // `position:fixed` modal mounted inside a column keeps its z-index LOCAL to the\r\n // column, so a column that paints early (the sidebar) buries a modal that must\r\n // cover the whole page. Verified live against 0.1.7: the settings overlay's\r\n // center hit-tested to the composer card below it, and dropped back onto the\r\n // dialog the moment this exemption was added. Losing the frost for as long as a\r\n // modal is open is the cheaper half of the trade — a dialog you cannot see is a\r\n // dead end. The cost is bounded because the match is transient: with the\r\n // settings view closed the sidebar column holds no `[role=\"dialog\"]` at all,\r\n // which was counted live before this exemption was written.\r\n `.${PART_BLUR_CLASS}:has([role=\"dialog\"]){isolation:auto}` +\r\n `.${PART_UNDERLAY_CLASS}{position:absolute;inset:0;z-index:-1;pointer-events:none;border-radius:inherit;` +\r\n `backdrop-filter:var(--dsh-any-part-blur,none);-webkit-backdrop-filter:var(--dsh-any-part-blur,none)}`\r\n\r\nlet partBlurStyleEl: HTMLStyleElement | null = null\r\n\r\nfunction ensurePartBlurStyle(): void {\r\n if (partBlurStyleEl?.isConnected) return\r\n partBlurStyleEl = document.createElement('style')\r\n partBlurStyleEl.dataset.plugin = 'dsh-any-background-parts'\r\n partBlurStyleEl.textContent = PART_BLUR_RULE\r\n document.head.appendChild(partBlurStyleEl)\r\n}\r\n\r\nfunction discoverParts(): void {\r\n const overlay = document.querySelector<HTMLElement>('[data-shell-overlay]')\r\n if (overlay === null) return\r\n const frame = overlay.parentElement\r\n if (frame === null) return\r\n frameEl = frame\r\n // One pass over frame.children for both anchors: the rightbar is the only\r\n // column with its own stable host marker (its own grid track — never the\r\n // \"details\" twin of center, so it must never take the main-bg tint), and the\r\n // overlay's index anchors the column order behind it.\r\n let overlayIdx = -1\r\n let rightIdx = -1\r\n let right: HTMLElement | null = null\r\n const children = frame.children\r\n for (let i = 0; i < children.length; i++) {\r\n const child = children[i]\r\n if (child === overlay) {\r\n overlayIdx = i\r\n } else if (child instanceof HTMLElement && child.dataset.rightbarCol !== undefined) {\r\n right = child\r\n rightIdx = i\r\n }\r\n }\r\n rightEl = right\r\n // With the host's grid the rightbar sits between center and overlay; the\r\n // indexes are resolved from the children array directly instead of trusting\r\n // the layout to keep that invariant. The else branch covers a future build\r\n // that drops the rightbar entirely (legacy 3-column shape).\r\n if (right !== null) {\r\n sidebarEl = (children[rightIdx - 2] as HTMLElement | undefined) ?? null\r\n centerEl = (children[rightIdx - 1] as HTMLElement | undefined) ?? null\r\n } else {\r\n sidebarEl = (children[overlayIdx - 3] as HTMLElement | undefined) ?? null\r\n centerEl = (children[overlayIdx - 2] as HTMLElement | undefined) ?? null\r\n }\r\n}\r\n\r\nfunction setBlur(el: HTMLElement | null, px: number): void {\r\n if (el === null) return\r\n // Nothing to clear and nothing applied yet: skip the querySelector and the\r\n // style writes. This is the common steady state — every observer tick and\r\n // every applyWp calls setBlur(el, 0) on parts that never had a blur.\r\n if (px === 0 && !el.classList.contains(PART_BLUR_CLASS) && el.getAttribute('data-dab-pos-patched') !== '1') return\r\n const underlay = el.querySelector<HTMLDivElement>(`:scope > .${PART_UNDERLAY_CLASS}`)\r\n if (px > 0) {\r\n ensurePartBlurStyle()\r\n // The underlay is position:absolute and needs a positioned host: static\r\n // columns get relative (a layout no-op for flex items) that is restored on\r\n // clear; parts the host already positions keep their own scheme.\r\n if (!el.classList.contains(PART_BLUR_CLASS) && getComputedStyle(el).position === 'static') {\r\n el.style.position = 'relative'\r\n el.setAttribute('data-dab-pos-patched', '1')\r\n }\r\n el.classList.add(PART_BLUR_CLASS)\r\n if (underlay === null) {\r\n const node = document.createElement('div')\r\n node.className = PART_UNDERLAY_CLASS\r\n el.prepend(node)\r\n }\r\n el.style.setProperty('--dsh-any-part-blur', `blur(${px}px)`)\r\n } else {\r\n el.classList.remove(PART_BLUR_CLASS)\r\n el.style.removeProperty('--dsh-any-part-blur')\r\n underlay?.remove()\r\n if (el.getAttribute('data-dab-pos-patched') === '1') {\r\n el.style.removeProperty('position')\r\n el.removeAttribute('data-dab-pos-patched')\r\n }\r\n }\r\n}\r\n\r\nfunction applySettingsBlur(px: number): void {\r\n if (px > 0) document.documentElement.style.setProperty('--dsh-any-blur-settings', `blur(${px}px)`)\r\n else document.documentElement.style.removeProperty('--dsh-any-blur-settings')\r\n}\r\n\r\n/** Apply the main-background opacity to the center column instead of\r\n * the frame. The frame's translucent bg-base sits UNDER the sidebar, so\r\n * reducing the main-bg opacity stacked a second alpha onto the sidebar; moving\r\n * the alpha onto the column keeps the sidebar owned by its own slider. The\r\n * rightbar (DSH 0.1.5-rc.1+) is intentionally NOT tinted here — it sits on\r\n * its own grid track, paints its own surfaces from its own tokens, and\r\n * inheriting the main-bg tint would blend it into the page and make the\r\n * right panel disappear. */\r\nfunction applyPartOpacities(ops: PartOpacities): void {\r\n const tokens = paletteTokens()\r\n if (tokens === null) return\r\n discoverParts()\r\n if (frameEl === null) return\r\n const base = tokens['--dsw-alias-bg-base']\r\n frameEl.classList.add(PART_FRAME_CLASS)\r\n // An inline clear from an earlier build of this plugin would be a stale\r\n // duplicate of what the class now says; drop it so the class is the only owner.\r\n if (frameEl.style.background !== '') frameEl.style.removeProperty('background')\r\n if (centerEl !== null) centerEl.style.background = base !== undefined ? toRgba(base, ops.bg) : 'transparent'\r\n // Defensive: a previous build (pre-fix) may have left an inline `background`\r\n // on the rightbar — clear it so it stops carrying the main-bg tint.\r\n if (rightEl !== null) rightEl.style.background = ''\r\n}\r\n\r\n/** Blur of the option panels inside the settings dialog (.dab-card), owned by\r\n * the \"dialog option panel\" (card) blur slider. Written as a plugin-owned\r\n * variable consumed by SETTINGS_STYLE_RULE — deliberately NOT applied to the\r\n * homepage center column, which this slider must never touch. */\r\nfunction applyCardPanelsBlur(px: number): void {\r\n if (px > 0) document.documentElement.style.setProperty('--dsh-any-blur-card-panels', `blur(${px}px)`)\r\n else document.documentElement.style.removeProperty('--dsh-any-blur-card-panels')\r\n}\r\n\r\n/** Apply per-part interface blur to the AppFrame columns + settings panel. */\r\nexport function applyPartBlurs(blurs: PartBlurs): void {\r\n discoverParts()\r\n // The bg blur frosts the wallpaper behind the main content column; the\r\n // frame itself stays unblurred so the sidebar is never double-frosted by\r\n // both the bg and sidebar sliders. The rightbar (DSH 0.1.5-rc.1+) is\r\n // intentionally untouched: the host's own panel sits inside the rightbar\r\n // and paints from its own tokens, so a backdrop-filter there would bleed\r\n // the wallpaper into the panel surface and break the focused-tab chrome.\r\n setBlur(frameEl, 0)\r\n setBlur(sidebarEl, blurs.sidebar)\r\n setBlur(centerEl, blurs.bg)\r\n setBlur(rightEl, 0)\r\n applyBgBlurGlobal(blurs.bg)\r\n applyCardPanelsBlur(blurs.card)\r\n applySettingsBlur(blurs.settings)\r\n applyInputBlur(blurs.input)\r\n applyPanelBlur(blurs.panel)\r\n applyProduced()\r\n applyHeaderPopovers()\r\n // Re-claims the session header bar: a conversation switch remounts the row, and\r\n // the class has to land on the element the host just created.\r\n applyHeaderBar()\r\n // Same for the Windows caption band: the frame can be rebuilt with the rest of\r\n // the shell, and the pin has to land on the element the host just created.\r\n applyNativeCaption()\r\n applyViewCards()\r\n}\r\n\r\n/** Produced/artifact surfaces (conversation code blocks + their banner +\r\n * inline code chips + composer chips + the dsh-better-sidebar workbench):\r\n * re-write the root blur and the alpha percentage consumed by PRODUCED_RULE. The\r\n * percentage is an alpha for the surface's OWN host color — 1 (100%) reproduces\r\n * the untouched host look and lowering it fades exactly that color out — so no\r\n * palette sampling is involved and the surfaces keep following the active\r\n * theme/wallpaper color on their own. Two surfaces are the exception: the\r\n * workbench reads a whole set of layer tokens rather than one color, and the\r\n * changed-files card reads a token the card slider owns globally — both take their\r\n * alpha from `writeLayerVars` instead of mixing on the live token. */\r\nexport function applyProduced(): void {\r\n const px = rBlurs().produced\r\n const root = document.documentElement\r\n if (px > 0) root.style.setProperty('--dsh-any-blur-prod', `blur(${px}px)`)\r\n else root.style.removeProperty('--dsh-any-blur-prod')\r\n let opacity = rProducedOpacity()\r\n if (opacity < 0) opacity = 0\r\n if (opacity > 1) opacity = 1\r\n root.style.setProperty('--dsh-any-prod-pct', `${Math.round(opacity * 100)}%`)\r\n writeLayerVars(PROD_PANEL_LAYER_VARS, opacity)\r\n writeLayerVars(PROD_LAYER_VARS, opacity)\r\n}\r\n\r\n/** Live per-part blur update during slider drag (no full re-apply). */\r\nexport function setPartBlur(part: keyof PartBlurs, v: number): void {\r\n if (part === 'settings') { applySettingsBlur(v); return }\r\n if (part === 'card') { applyCardPanelsBlur(v); return }\r\n if (part === 'input') { applyInputBlur(v); return }\r\n if (part === 'panel') { applyPanelBlur(v); return }\r\n if (part === 'produced') { applyProduced(); return }\r\n if (part === 'header') { applyHeaderPopovers(); return }\r\n if (part === 'headerBar') { applyHeaderBar(); return }\r\n if (part === 'chat' || part === 'trajectory') { applyViewCards(); return }\r\n discoverParts()\r\n if (part === 'bg') { setBlur(centerEl, v); applyBgBlurGlobal(v) }\r\n else setBlur(sidebarEl, v)\r\n}\r\n\r\n// ── Conversation view treatments ────────────────────────────────────\r\n// The chat message column is styled as a real card (layer-1 surface + border +\r\n// 16px radius + 18px padding); the trajectory view gets NO card decoration —\r\n// its own panels fully cover the view root, so its opacity slider re-scopes the\r\n// layer tokens inside the view and its blur frosts the backdrop through the\r\n// standard root underlay.\r\n//\r\n// Host structure (deepseek-harness ui-conversation / ui-trajectory):\r\n// ConversationRoot\r\n// header — title + tabs, OUTSIDE the scrollport\r\n// [data-conversation-scroll] — the single scrollport\r\n// [data-chat-flow] ← chat column (flow content, NOT scrollable)\r\n// [data-conversation-composer-overlay] ← trajectory view root\r\n// [data-composer-seat] — sticky composer, a sibling\r\n// The input is sticky inside the same scrollport, so the stable host markers\r\n// are used; generic heuristics remain as a chat fallback for marker-less hosts.\r\n//\r\n// Cards are ALWAYS styled once their host exists — sliders at zero only turn\r\n// surface/border transparent, so the layout never reflows and the view cannot\r\n// jump when a slider leaves zero. Removal happens only at plugin teardown.\r\ninterface ViewCardSpec {\r\n sel: string\r\n mark: string\r\n /** Dataset key prefix holding the stashed pre-card inline values. */\r\n prev: string\r\n opacity: () => number\r\n blur: () => number\r\n /** Generic heuristic fallback (chat card only, hosts without the marker). */\r\n fallback?: boolean\r\n /** No card decoration — surfaces follow scoped layer tokens; only the blur\r\n * underlay is attached to the host element. */\r\n plain?: boolean\r\n}\r\n\r\nconst VIEW_CARDS: ViewCardSpec[] = [\r\n { sel: '[data-chat-flow]', mark: 'data-dab-chat-card', prev: 'dabChatPrev', opacity: rChatTextOpacity, blur: () => rBlurs().chat, fallback: true },\r\n { sel: '[data-conversation-composer-overlay]', mark: 'data-dab-traj-card', prev: 'dabTrajPrev', opacity: rTrajectoryOpacity, blur: () => rBlurs().trajectory, plain: true },\r\n]\r\n\r\nconst viewTargets: Array<HTMLElement | null> = VIEW_CARDS.map(() => null)\r\n\r\n/** View specs whose real host marker has been seen at least once. Until a\r\n * marker is seen, its absence is ambiguous — \"that view is not mounted\" or\r\n * \"this build has no such marker, keep running the generic fallback\" — and the\r\n * pass has to keep probing. Once seen, absence can only mean the former, so the\r\n * pass may be skipped.\r\n *\r\n * This matters because the two specs are two different MAIN VIEWS and only one\r\n * of them is mounted at a time (the host renders the main slot for the active\r\n * panel id, keyed by `entryKey` — see AppFrame's MainPanel). So \"every surface\r\n * present\" is never true during a normal session, and an all-or-nothing gate on\r\n * it silently never engages: that is exactly how the previous version of this\r\n * observer ended up running the full pass on every animation frame while\r\n * tokens streamed. */\r\nconst markerSeen = new Set<number>()\r\n\r\n/** Resolve just the stable host markers for the view specs — one querySelector\r\n * each, no fallback heuristics. Cheap enough to run on every coalesced burst,\r\n * and enough to notice a view mounting/unmounting. */\r\nfunction probeViewMarkers(): (HTMLElement | null)[] {\r\n const center = centerEl\r\n if (center === null || !document.body.contains(center)) return VIEW_CARDS.map(() => null)\r\n return VIEW_CARDS.map(spec => center.querySelector<HTMLElement>(spec.sel))\r\n}\r\n\r\n/** Whether the pass must run regardless of the value/identity signature. */\r\nfunction needsPartsPass(markers: (HTMLElement | null)[]): boolean {\r\n // Columns missing: the pass is what discovers them.\r\n if (!columnsPresent()) return true\r\n // A mounted view whose marker moved (appeared, or was replaced by a fresh\r\n // element) has to be re-styled — the identity gate below cannot see it,\r\n // because an undiscovered target is still null in viewTargets.\r\n if (markers.some((el, i) => el !== null && el !== viewTargets[i])) return true\r\n // A spec with a generic fallback whose marker has never been seen on this\r\n // host: the pass performs that resolution, so it cannot be skipped.\r\n return VIEW_CARDS.some((spec, i) => spec.fallback === true && markers[i] === null && !markerSeen.has(i))\r\n}\r\n\r\nfunction isScrollableY(el: HTMLElement): boolean {\r\n const oy = getComputedStyle(el).overflowY\r\n // 'overlay' covers Chromium's non-standard overflow value.\r\n return oy === 'auto' || oy === 'scroll' || oy === 'overlay'\r\n}\r\n\r\n/** Whether the subtree hosts the chat input (textarea / contenteditable /\r\n * textbox role) — used to keep the card off the input row. */\r\nfunction containsChatEditor(el: HTMLElement): boolean {\r\n return el.querySelector('textarea,[contenteditable=\"true\"],[contenteditable=\"\"],[contenteditable=\"plaintext-only\"],[role=\"textbox\"]') !== null\r\n}\r\n\r\n/** Walk down from a coarse candidate toward the actual message column: stop\r\n * at a scroll container (the card surface must stay pinned to the scroll\r\n * port); while the chat input lives inside, descend into the tallest child that\r\n * does NOT contain it (the header row is short, the input row holds the\r\n * editor); otherwise peel wrappers dominated (>= 85%) by a single child so\r\n * tab bars / titles stay outside the card. */\r\nfunction refineMessageColumn(start: HTMLElement): HTMLElement {\r\n let cur = start\r\n for (let depth = 0; depth < 10; depth++) {\r\n if (isScrollableY(cur)) break\r\n const kids = Array.from(cur.children).filter((k): k is HTMLElement => k instanceof HTMLElement)\r\n if (kids.length === 0) break\r\n const tallest = kids.reduce((a, b) => (b.clientHeight > a.clientHeight ? b : a))\r\n if (containsChatEditor(cur)) {\r\n const candidates = kids.filter(k => !containsChatEditor(k) && k.clientHeight >= cur.clientHeight * 0.4)\r\n if (candidates.length === 0) break\r\n cur = candidates.reduce((a, b) => (b.clientHeight > a.clientHeight ? b : a))\r\n continue\r\n }\r\n if (kids.length > 1 && tallest.clientHeight >= cur.clientHeight * 0.85) { cur = tallest; continue }\r\n break\r\n }\r\n return cur\r\n}\r\n\r\nfunction discoverViewTarget(idx: number, spec: ViewCardSpec): HTMLElement | null {\r\n if (centerEl === null || !document.body.contains(centerEl)) { viewTargets[idx] = null; return null }\r\n // The host marker always wins over a cached fallback (the view may not be\r\n // mounted yet when the plugin applies early).\r\n const marked = centerEl.querySelector<HTMLElement>(spec.sel)\r\n const cached = viewTargets[idx]\r\n if (marked !== null) {\r\n // This host does expose the marker, so from now on its absence means \"that\r\n // view is not the active one\" — see the note on markerSeen.\r\n markerSeen.add(idx)\r\n if (cached !== null && cached !== marked) { setBlur(cached, 0); restoreCardHost(cached, spec.mark, spec.prev, spec.plain === true) }\r\n viewTargets[idx] = marked\r\n return marked\r\n }\r\n if (cached !== null && centerEl.contains(cached)) return cached\r\n viewTargets[idx] = null\r\n if (spec.fallback !== true) return null\r\n // The fallback may only refine a conversation that is ALREADY there; it must\r\n // never invent one. With no conversation marker in the column the chat view is\r\n // simply not mounted — the settings view owns the column then, and its page is\r\n // routinely the column's only tall element, so the heuristic below would dress\r\n // that page up as a chat card and hang a 15px frost over the whole window.\r\n // Every release in the supported range emits at least one of these four.\r\n if (\r\n centerEl.querySelector(\r\n '[data-chat-flow],[data-conversation-scroll],[data-composer-seat],[data-conversation-composer-overlay]'\r\n ) === null\r\n ) return null\r\n // On the harness, an absent [data-chat-flow] just means the chat view is not\r\n // mounted (hero phase, trajectory tab) — settling on the whole scrollport\r\n // there would wrap the entire page in the card.\r\n if (centerEl.querySelector('[data-conversation-scroll]') !== null) return null\r\n // Marker-less hosts keep their layout until a slider moves.\r\n if (spec.opacity() <= 0 && spec.blur() <= 0) return null\r\n // Generic fallbacks: the largest vertically scrollable element inside the\r\n // column, or the tallest direct child when the host virtualises scrolling.\r\n let best: HTMLElement | null = null\r\n let bestArea = 0\r\n for (const el of Array.from(centerEl.querySelectorAll<HTMLElement>('*'))) {\r\n if (!isScrollableY(el)) continue\r\n if (el.clientHeight < centerEl.clientHeight * 0.35) continue\r\n const area = el.clientWidth * el.clientHeight\r\n if (area > bestArea) { bestArea = area; best = el }\r\n }\r\n if (best === null) {\r\n for (const el of Array.from(centerEl.children)) {\r\n if (!(el instanceof HTMLElement)) continue\r\n if (el.clientHeight < centerEl.clientHeight * 0.5) continue\r\n if (el.clientHeight > (best?.clientHeight ?? 0)) best = el\r\n }\r\n }\r\n // A settings-dialog surface is never the chat card: the dialog owns its own\r\n // look through SETTINGS_STYLE_RULE, and while it is open with no conversation\r\n // mounted its page IS the column's largest scroller, so the geometry above\r\n // would wrap, say, the 「插件」 page in card chrome and hang a frost underlay on\r\n // it. Tested on the picked element rather than on the column so it also holds\r\n // when the dialog is portal'd and only its content renders inside the column.\r\n if (best !== null && best.closest(SETTINGS_PANEL_SEL) !== null) best = null\r\n // Coarse candidates are narrowed to the message column itself.\r\n const refined = best !== null ? refineMessageColumn(best) : null\r\n viewTargets[idx] = refined\r\n return refined\r\n}\r\n\r\n/** Stash the host's own inline values so teardown restores them exactly.\r\n * Plain views only get a background override, so only that is stashed. */\r\nfunction stashCardPrev(el: HTMLElement, prev: string, plain: boolean): void {\r\n const ds = el.dataset as Record<string, string | undefined>\r\n ds[prev + 'Bg'] = el.style.getPropertyValue('background')\r\n if (plain) return\r\n ds[prev + 'BoxSizing'] = el.style.getPropertyValue('box-sizing')\r\n ds[prev + 'Border'] = el.style.getPropertyValue('border')\r\n ds[prev + 'Radius'] = el.style.getPropertyValue('border-radius')\r\n ds[prev + 'Padding'] = el.style.getPropertyValue('padding')\r\n}\r\n\r\n/** Undo the inline styling, restoring the host's previous inline values. */\r\nfunction restoreCardHost(el: HTMLElement, mark: string, prev: string, plain: boolean): void {\r\n if (!el.hasAttribute(mark)) return\r\n const ds = el.dataset as Record<string, string | undefined>\r\n const restore = (prop: string, v: string | undefined): void => {\r\n if (v !== undefined && v !== '') el.style.setProperty(prop, v)\r\n else el.style.removeProperty(prop)\r\n }\r\n restore('background', ds[prev + 'Bg'])\r\n if (!plain) {\r\n restore('box-sizing', ds[prev + 'BoxSizing'])\r\n restore('border', ds[prev + 'Border'])\r\n restore('border-radius', ds[prev + 'Radius'])\r\n restore('padding', ds[prev + 'Padding'])\r\n delete ds[prev + 'BoxSizing']; delete ds[prev + 'Border']; delete ds[prev + 'Radius']; delete ds[prev + 'Padding']\r\n }\r\n delete ds[prev + 'Bg']\r\n el.removeAttribute(mark)\r\n}\r\n\r\n/** Teardown only: strip every view treatment and hand the hosts back untouched. */\r\nfunction removeViewCards(): void {\r\n VIEW_CARDS.forEach((spec, i) => {\r\n const el = viewTargets[i]\r\n if (el !== null) { setBlur(el, 0); restoreCardHost(el, spec.mark, spec.prev, spec.plain === true) }\r\n viewTargets[i] = null\r\n })\r\n}\r\n\r\n// ── Wide markdown tables ──────────────────────────────────────────────────────\r\n// DSH intentionally lets `.md-table-wide` bleed outside the text column (a\r\n// negative --dsh-table-lead margin + max-width:none, set by a host rule like\r\n// `.Sxvs8a_body .md-table-wide`; the prefix is a build-time hash class). That\r\n// bleed only becomes visible once the chat surface gains a visible border, i.e.\r\n// when the chat region opacity or blur is non-zero (see borderAlpha in\r\n// applyViewCards). Under that same condition, pull the table back inside the\r\n// column and let it scroll horizontally. The stable `.md-table-wide` class is\r\n// targeted with !important so the fix survives DSH's changing hash prefixes.\r\n\r\nconst TABLE_FIX_RULE = [\r\n '.md-table-wide {',\r\n ' --dsh-table-spare: 0px !important;',\r\n ' --dsh-table-lead: 0px !important;',\r\n ' box-sizing: border-box !important;',\r\n ' width: 100% !important;',\r\n ' max-width: 100% !important;',\r\n ' margin-left: 0 !important;',\r\n ' padding-left: 0 !important;',\r\n ' padding-bottom: 0 !important;',\r\n ' overflow-x: auto !important;',\r\n '}',\r\n].join('\\n')\r\nlet tableFixStyleEl: HTMLStyleElement | null = null\r\n\r\n/** Toggle the wide-table clamp according to the chat region's opacity & blur. */\r\nfunction syncTableFix(): void {\r\n const needed = rChatTextOpacity() > 0 || rBlurs().chat > 0\r\n if (!needed) {\r\n if (tableFixStyleEl !== null) { tableFixStyleEl.remove(); tableFixStyleEl = null }\r\n return\r\n }\r\n if (tableFixStyleEl === null) {\r\n tableFixStyleEl = document.createElement('style')\r\n tableFixStyleEl.dataset.plugin = 'dsh-any-background-table-fix'\r\n tableFixStyleEl.textContent = TABLE_FIX_RULE\r\n }\r\n if (!tableFixStyleEl.isConnected) document.head.appendChild(tableFixStyleEl)\r\n}\r\n\r\n/** Re-derive the conversation view cards from the current config. Cheap\r\n * enough for live slider drags; the card structure is applied unconditionally\r\n * once the host exists so the layout never reflows when a slider leaves zero. */\r\nexport function applyViewCards(): void {\r\n discoverParts()\r\n if (centerEl === null) return\r\n const [h, s, l] = rColor()\r\n const surface = genTokens(h, s, l, rColorScheme()).tokens['--dsw-alias-bg-layer-1']\r\n VIEW_CARDS.forEach((spec, i) => {\r\n const target = discoverViewTarget(i, spec)\r\n if (target === null) return\r\n const plain = spec.plain === true\r\n const opacity = spec.opacity()\r\n const blurPx = spec.blur()\r\n if (!plain) {\r\n if (!target.hasAttribute(spec.mark)) stashCardPrev(target, spec.prev, false)\r\n // Mirrors .dab-card (layer-1 background, border, 16px radius, 18px\r\n // padding), written inline so it wins over host stylesheets; the opacity\r\n // slider drives surface alpha and fades the border with it.\r\n const borderAlpha = opacity > 0 ? Math.min(1, opacity * 1.5) : (blurPx > 0 ? 0.35 : 0)\r\n target.style.background = surface !== undefined ? toRgba(surface, opacity) : 'transparent'\r\n target.style.border = surface !== undefined ? `1px solid ${toRgba(surface, borderAlpha)}` : '1px solid transparent'\r\n target.style.borderRadius = '16px'\r\n target.style.padding = '18px'\r\n // DSH has no global box-sizing reset; under content-box the padding +\r\n // border above would push the card past its width:100% — overflowing\r\n // narrow screens and breaking margin:0 auto centering.\r\n target.style.boxSizing = 'border-box'\r\n }\r\n // Plain views write no inline styles — only the blur underlay is hosted here.\r\n target.setAttribute(spec.mark, '1')\r\n setBlur(target, blurPx)\r\n })\r\n syncTableFix()\r\n}\r\n\r\nlet partsObserver: MutationObserver | null = null\r\nlet partsApplyRaf = 0\r\n/** Signature of the last blur+opacity pass we actually wrote to the DOM. */\r\nlet appliedPartsKey = ''\r\n/** The surfaces the last pass styled, compared BY IDENTITY: the host can swap\r\n * a view element for a fresh one while the slider values stay identical, and\r\n * the value signature alone would then skip the pass and leave the new view\r\n * unstyled until a slider moves. */\r\nlet appliedTargets: (HTMLElement | null)[] = []\r\n\r\n/** The four frame columns are mounted and still attached. These are the frame's\r\n * own children (see the host's AppFrame: sidebar / center / rightbar carrying\r\n * `data-rightbar-col` / the overlay), so they exist as soon as the shell does —\r\n * unlike the per-view cards below, which come and go with the active view. */\r\nfunction columnsPresent(): boolean {\r\n return frameEl !== null && sidebarEl !== null && centerEl !== null && rightEl !== null\r\n && document.body.contains(frameEl) && document.body.contains(centerEl)\r\n}\r\n\r\n/** The composer seat's elected takeover card (approval / plan review / question)\r\n * when one is mounted. It is not a view, but it shares the view cards' problem:\r\n * the host mounts a fresh element when a takeover is elected, and the pass\r\n * signature alone would skip that pass — `applyTakeoverFrost` rides\r\n * `applyInputBlur` — leaving the new card bare until a slider moves. Scoped to\r\n * the center column exactly like the view markers, because this query runs on\r\n * every coalesced mutation burst, including token streaming. */\r\nfunction probeTakeoverCard(): HTMLElement | null {\r\n if (centerEl === null || !document.body.contains(centerEl)) return null\r\n return centerEl.querySelector<HTMLElement>(COMPOSER_TAKEOVER_CARD)\r\n}\r\n\r\n/** Snapshot of every surface the pass would style, for the identity check. */\r\nfunction targetsNow(): (HTMLElement | null)[] {\r\n return [frameEl, sidebarEl, centerEl, rightEl, ...viewTargets, probeTakeoverCard()]\r\n}\r\n\r\n/** Watch for the AppFrame mounting so persisted blurs land even when the shell\r\n * renders after this plugin's apply. */\r\nexport function watchParts(): void {\r\n if (partsObserver !== null || typeof MutationObserver === 'undefined') return\r\n partsObserver = new MutationObserver(() => {\r\n // The observer cannot tell whether a mutation touched our surfaces, so\r\n // without a gate every childList change on body — streaming tokens,\r\n // keystrokes — re-runs the full blur+opacity pass. Coalesce a burst into one\r\n // animation frame, then skip it when it cannot change anything.\r\n if (partsApplyRaf !== 0) return\r\n partsApplyRaf = requestAnimationFrame(() => {\r\n partsApplyRaf = 0\r\n const blurs = rBlurs()\r\n const ops = rOps()\r\n const key = JSON.stringify([blurs, ops])\r\n const markers = probeViewMarkers()\r\n if (!needsPartsPass(markers) && key === appliedPartsKey\r\n && !targetsNow().some((el, i) => el !== appliedTargets[i])) return\r\n applyPartBlurs(blurs)\r\n applyPartOpacities(ops)\r\n // Snapshot AFTER the pass, not before: discovery happens inside it, and\r\n // comparing the next tick against a pre-discovery snapshot would make that\r\n // tick re-run the whole pass for nothing.\r\n appliedPartsKey = key\r\n appliedTargets = targetsNow()\r\n })\r\n })\r\n partsObserver.observe(document.body, { childList: true, subtree: true })\r\n}\r\n\r\nexport function stopWatchingParts(): void {\r\n partsObserver?.disconnect()\r\n partsObserver = null\r\n if (partsApplyRaf !== 0) { cancelAnimationFrame(partsApplyRaf); partsApplyRaf = 0 }\r\n appliedPartsKey = ''\r\n appliedTargets = []\r\n // Re-probe on the next enable: a marker seen before the teardown is no longer\r\n // evidence about the DOM at hand.\r\n markerSeen.clear()\r\n}\r\n\r\n// ── Theme-reset watchdog ──────────────────────────────────────────────────\r\n// The host re-asserts its own :root/body scheme rules on mount, on settings\r\n// adoption and after the plugin's startup assertion, toggling the\r\n// `data-ds-dark-theme` attribute off / to a host value — which would paint a\r\n// frame of light surfaces. Watch that flag and, whenever the plugin's own\r\n// value disappears, re-set it and re-emit the token stylesheet within the same\r\n// frame. The guard stops feedback: once our mark is present the handler\r\n// returns, so our own re-assertion cannot re-trigger.\r\nlet themeObserver: MutationObserver | null = null\r\nlet themeRaf = 0\r\n\r\nfunction reassertScheme(): void {\r\n const dark = rScheme() === 'dark'\r\n if (dark) document.body.setAttribute('data-ds-dark-theme', 'dsh-any-background')\r\n else document.body.removeAttribute('data-ds-dark-theme')\r\n applyCustomTokens(rOps())\r\n}\r\n\r\n/** Re-assert the plugin's forced scheme whenever the host strips it, so a\r\n * refresh / cold-load / set-change never flashes a light frame. Returns a\r\n * disposer for teardown. */\r\nexport function watchThemeResets(): () => void {\r\n if (themeObserver !== null || typeof MutationObserver === 'undefined') return () => undefined\r\n themeObserver = new MutationObserver(() => {\r\n if (document.body.getAttribute('data-ds-dark-theme') === 'dsh-any-background') return\r\n if (!(rHasColor() || rBgDark() !== null || rSchemeOverride() !== 'auto')) return\r\n if (themeRaf !== 0) return\r\n themeRaf = requestAnimationFrame(() => {\r\n themeRaf = 0\r\n if (document.body.getAttribute('data-ds-dark-theme') === 'dsh-any-background') return\r\n reassertScheme()\r\n })\r\n })\r\n themeObserver.observe(document.body, { attributes: true, attributeFilter: ['data-ds-dark-theme'] })\r\n themeObserver.observe(document.documentElement, { attributes: true, attributeFilter: ['data-ds-dark-theme'] })\r\n return () => {\r\n themeObserver?.disconnect()\r\n themeObserver = null\r\n }\r\n}\r\n\r\nfunction ensureWpContainer(): void {\r\n if (!wpEl || !document.body.contains(wpEl)) {\r\n wpEl = document.createElement('div')\r\n wpEl.style.cssText = 'position:fixed;inset:0;z-index:-1;pointer-events:none;overflow:hidden;'\r\n document.body.prepend(wpEl)\r\n }\r\n}\r\n\r\nfunction clearVideoEl(): void {\r\n if (videoEl === null) return\r\n videoEl.pause()\r\n videoEl.removeAttribute('src')\r\n videoEl.load()\r\n videoEl.remove()\r\n videoEl = null\r\n}\r\n\r\n/** Intrinsic-size cache for the center mode (native pixels of the current image). */\r\nlet imgNat: { url: string; w: number; h: number } | null = null\r\nfunction imageNatSize(url: string, cb: (w: number, h: number) => void): void {\r\n if (imgNat !== null && imgNat.url === url) { cb(imgNat.w, imgNat.h); return }\r\n void loadImage(url).then(img => {\r\n if (!img) { cb(0, 0); return }\r\n imgNat = { url, w: img.naturalWidth, h: img.naturalHeight }\r\n cb(img.naturalWidth, img.naturalHeight)\r\n })\r\n}\r\n\r\n// ── Drag-time wallpaper downscaling ──────────────────────────────────────────\r\n// Repainting translucent surfaces over a full-resolution wallpaper is expensive\r\n// (proportional to the image's pixel area, worse under backdrop blur). During a\r\n// slider drag we swap the layer's background-image to a bounded-size JPEG copy,\r\n// slashing that per-frame raster cost; the full-res image is restored on release\r\n// and stays browser-cached, so the swap is cheap. Precomputed after each image\r\n// apply so the first drag needs no decode hitch.\r\nconst DRAG_MAX_SIDE = 720\r\n\r\nlet lowResUrl: string | null = null\r\nlet lowResFor = ''\r\nlet dragLow = false\r\n\r\nfunction captureLowRes(url: string, cb: (low: string | null) => void): void {\r\n if (lowResFor === url) { cb(lowResUrl); return }\r\n void loadImage(url).then(img => {\r\n if (!img) { cb(null); return }\r\n const k = Math.min(1, DRAG_MAX_SIDE / Math.max(img.naturalWidth, img.naturalHeight))\r\n if (k >= 1) { lowResFor = url; lowResUrl = null; cb(null); return }\r\n const c = document.createElement('canvas')\r\n c.width = Math.max(1, Math.round(img.naturalWidth * k))\r\n c.height = Math.max(1, Math.round(img.naturalHeight * k))\r\n const g = c.getContext('2d')\r\n if (!g) { lowResFor = url; lowResUrl = null; cb(null); return }\r\n g.drawImage(img, 0, 0, c.width, c.height)\r\n const low = c.toDataURL('image/jpeg', 0.85)\r\n lowResFor = url; lowResUrl = low\r\n cb(low)\r\n })\r\n}\r\n\r\nfunction setDragLow(on: boolean): void {\r\n if (cfg.backgroundType !== 'image' || on === dragLow || !wpEl) return\r\n const full = rWpImage()\r\n if (!full) return\r\n if (on) {\r\n dragLow = true\r\n captureLowRes(full, low => {\r\n if (!dragLow || !wpEl || low === null) return\r\n if (wpEl.style.backgroundImage !== `url(\"${low}\")`) wpEl.style.backgroundImage = `url(\"${low}\")`\r\n })\r\n } else {\r\n dragLow = false\r\n if (wpEl.style.backgroundImage !== `url(\"${full}\")`) wpEl.style.backgroundImage = `url(\"${full}\")`\r\n }\r\n}\r\n\r\n/** While any range slider in the app is being dragged, run the wallpaper at\r\n * reduced resolution; restore on release. Returns a disposer for teardown. */\r\nexport function watchWallpaperDragQuality(): () => void {\r\n const isRange = (t: EventTarget | null): boolean =>\r\n t instanceof HTMLInputElement && t.type === 'range'\r\n const down = (e: PointerEvent): void => { if (isRange(e.target)) setDragLow(true) }\r\n const up = (): void => { if (dragLow) setDragLow(false) }\r\n window.addEventListener('pointerdown', down, true)\r\n window.addEventListener('pointerup', up, true)\r\n window.addEventListener('pointercancel', up, true)\r\n return () => {\r\n window.removeEventListener('pointerdown', down, true)\r\n window.removeEventListener('pointerup', up, true)\r\n window.removeEventListener('pointercancel', up, true)\r\n if (dragLow) setDragLow(false)\r\n }\r\n}\r\n\r\n// ── Wallpaper brightness verdict ─────────────────────────────────────────────\r\n// Image/video wallpapers get the same one-shot brightness verdict generated\r\n// backgrounds analyze from their captured frame: decoded once per URL (cached),\r\n// it drives the label direction and the auto scheme, so a light wallpaper gets\r\n// dark fonts even when no theme color is picked and the host preference is dark.\r\nlet wpVerdict: { url: string; dark: boolean } | null = null\r\nlet verdictListener: (() => void) | null = null\r\n// Monotonic guard for the async frame analysis: a stale result (the wallpaper\r\n// changed while the frame was decoding) must never overwrite the current\r\n// verdict. applyGeneratedBg guards with its own controller comparison; the\r\n// image/video path needs the same protection.\r\nlet verdictGen = 0\r\n\r\n/** Register a callback fired when the background brightness verdict CHANGES\r\n * (a new wallpaper was analyzed, a generated bg regenerated), so the skin can\r\n * be re-registered through the host theme service. */\r\nexport function onVerdictApplied(cb: () => void): () => void {\r\n verdictListener = cb\r\n return () => { if (verdictListener === cb) verdictListener = null }\r\n}\r\n\r\nfunction applyVerdict(dark: boolean | null): void {\r\n if (rBgDark() === dark) return\r\n setBgDark(dark)\r\n if (dark !== null) verdictListener?.()\r\n}\r\n\r\nfunction updateWpVerdict(url: string | null): void {\r\n const gen = ++verdictGen\r\n if (url === null) { applyVerdict(null); return }\r\n if (wpVerdict !== null && wpVerdict.url === url) { applyVerdict(wpVerdict.dark); return }\r\n void analyzeFrameDark(url).then(dark => {\r\n if (dark === null || gen !== verdictGen) return\r\n wpVerdict = { url, dark }\r\n applyVerdict(dark)\r\n applyCustomTokens(rOps())\r\n })\r\n}\r\n\r\nfunction applyImageWp(url: string): void {\r\n clearDynamicBg()\r\n clearVideoEl()\r\n ensureWpContainer()\r\n const bg = rBgState()\r\n const mode = rBgMode()\r\n const next = `url(\"${url}\")`\r\n // Skip re-setting the same data URL — re-decoding it flashes the wallpaper\r\n // blank for a frame on boot re-applies.\r\n if (wpEl!.style.backgroundImage !== next) {\r\n wpEl!.style.backgroundImage = next\r\n }\r\n if (mode === 'fit') {\r\n wpEl!.style.backgroundRepeat = 'no-repeat'\r\n if (bg.iw > 0) {\r\n // Contain-fit at zoom with the image center pinned to the committed\r\n // fractional viewport point, so the framed region survives viewport changes.\r\n const fit = Math.min(window.innerWidth / bg.iw, window.innerHeight / bg.ih)\r\n const w = bg.iw * fit * bg.zoom\r\n const h = bg.ih * fit * bg.zoom\r\n wpEl!.style.backgroundSize = `${w}px ${h}px`\r\n wpEl!.style.backgroundPosition = `${bg.x * window.innerWidth - w / 2}px ${bg.y * window.innerHeight - h / 2}px`\r\n } else {\r\n // Fresh image: match the editor's initial centered contain view.\r\n wpEl!.style.backgroundSize = 'contain'\r\n wpEl!.style.backgroundPosition = 'center'\r\n }\r\n } else if (mode === 'fill') {\r\n wpEl!.style.backgroundRepeat = 'no-repeat'\r\n wpEl!.style.backgroundSize = 'cover'\r\n wpEl!.style.backgroundPosition = 'center'\r\n } else if (mode === 'stretch') {\r\n wpEl!.style.backgroundRepeat = 'no-repeat'\r\n wpEl!.style.backgroundSize = '100% 100%'\r\n wpEl!.style.backgroundPosition = 'center'\r\n } else if (mode === 'tile') {\r\n wpEl!.style.backgroundRepeat = 'repeat'\r\n // background-size:auto resolves the intrinsic size per tile.\r\n wpEl!.style.backgroundSize = 'auto'\r\n wpEl!.style.backgroundPosition = '0px 0px'\r\n } else {\r\n // Center: native size, centered. The intrinsic size needs an async decode;\r\n // 'contain' keeps a sensible frame until it lands.\r\n wpEl!.style.backgroundRepeat = 'no-repeat'\r\n wpEl!.style.backgroundSize = 'contain'\r\n wpEl!.style.backgroundPosition = 'center'\r\n imageNatSize(url, (w, h) => {\r\n if (!wpEl || wpEl.style.backgroundImage !== next || rBgMode() !== 'center') return\r\n if (w > 0 && h > 0) {\r\n wpEl.style.backgroundSize = `${w}px ${h}px`\r\n wpEl.style.backgroundPosition = 'center'\r\n }\r\n })\r\n }\r\n // Precompute the drag-time downscaled copy now so the first drag swaps without\r\n // a decode hitch (the original is already loaded, so this hits the cache).\r\n captureLowRes(url, () => undefined)\r\n applyWpEffects()\r\n updateWpVerdict(url)\r\n}\r\n\r\n/** Video wallpaper: a muted looping <video> inside the wallpaper layer.\r\n * Placement modes map onto object-fit (tile has no video equivalent and\r\n * falls back to cover). */\r\nfunction applyVideoWp(url: string): void {\r\n clearDynamicBg()\r\n ensureWpContainer()\r\n if (wpEl!.style.backgroundImage !== 'none') wpEl!.style.backgroundImage = 'none'\r\n if (videoEl === null || !videoEl.isConnected) {\r\n videoEl = document.createElement('video')\r\n videoEl.muted = true\r\n videoEl.loop = true\r\n videoEl.autoplay = true\r\n videoEl.playsInline = true\r\n videoEl.preload = 'auto'\r\n videoEl.setAttribute('playsinline', '')\r\n videoEl.style.cssText = 'position:absolute;inset:0;width:100%;height:100%;object-position:center;'\r\n // Attach before loading so the element is in the document when play()\r\n // resolves; a detached video can defer its first rendered frame.\r\n wpEl!.appendChild(videoEl)\r\n videoEl.setAttribute('src', url)\r\n void videoEl.play().catch(() => undefined)\r\n } else if (videoEl.getAttribute('src') !== url) {\r\n // Compare the attribute, not videoEl.src: the property getter resolves to\r\n // an absolute URL that would never match the relative serve URL and would\r\n // restart playback on every re-apply.\r\n videoEl.setAttribute('src', url)\r\n void videoEl.play().catch(() => undefined)\r\n }\r\n const mode = rBgMode()\r\n const bg = rVideoBgState()\r\n if (mode === 'fit' && bg.iw > 0) {\r\n // Editor-committed box at contain-fit scale × zoom, centered on the\r\n // fractional point; object-fit:fill stretches the frame into the box\r\n // (same aspect ratio, so nothing distorts).\r\n const fit = Math.min(window.innerWidth / bg.iw, window.innerHeight / bg.ih)\r\n const w = bg.iw * fit * bg.zoom\r\n const h = bg.ih * fit * bg.zoom\r\n videoEl.style.cssText = `position:absolute;left:${bg.x * window.innerWidth - w / 2}px;top:${bg.y * window.innerHeight - h / 2}px;width:${w}px;height:${h}px;object-fit:fill;`\r\n } else {\r\n videoEl.style.cssText = 'position:absolute;inset:0;width:100%;height:100%;object-position:center;'\r\n videoEl.style.objectFit = mode === 'stretch' ? 'fill' : (mode === 'fill' || mode === 'tile') ? 'cover' : 'contain'\r\n }\r\n applyWpEffects()\r\n // Video mode has no still Image-decodable source; the captured frame\r\n // snapshot stands in for the brightness verdict (null until it lands, then\r\n // re-analyzed through the next apply).\r\n updateWpVerdict(rWp())\r\n}\r\n\r\nfunction applyWpEffects(): void {\r\n if (!wpEl) return\r\n const blur = rBl()\r\n wpEl.style.filter = blur > 0 ? `blur(${blur}px)` : 'none'\r\n wpEl.style.opacity = String(rWop())\r\n}\r\n\r\nexport function applyWp(): void {\r\n const url = rWp()\r\n if (cfg.backgroundType === 'video') {\r\n // The frame snapshot (rWp's video branch) is preview-only; the layer plays\r\n // the video from its own slot.\r\n const vurl = rWpVideo()\r\n if (vurl) {\r\n applyVideoWp(vurl)\r\n } else {\r\n clearDynamicBg()\r\n clearVideoEl()\r\n wpEl?.remove(); wpEl = null\r\n // An empty video slot must not keep the previous wallpaper's brightness\r\n // verdict alive: nothing is on screen to justify it, and a stale verdict\r\n // would flip the next background's font direction the wrong way. The\r\n // no-background branch below does the same.\r\n wpVerdict = null\r\n setBgDark(null)\r\n }\r\n } else if (cfg.backgroundType !== 'image' && cfg.generatedBg) {\r\n // Recreate the live canvas from saved params if one is not active yet\r\n // (boot or after import).\r\n clearVideoEl()\r\n if (!wpController) {\r\n applyGeneratedBg(cfg.generatedBg)\r\n return\r\n }\r\n ensureWpContainer()\r\n if (wpController.canvas.parentElement !== wpEl) wpEl!.appendChild(wpController.canvas)\r\n applyWpEffects()\r\n } else if (url) {\r\n applyImageWp(url)\r\n } else {\r\n // No background: tear down the layer but keep tokens/blur intact.\r\n clearDynamicBg()\r\n clearVideoEl()\r\n wpEl?.remove(); wpEl = null\r\n wpVerdict = null\r\n setBgDark(null)\r\n }\r\n // Write tokens only when there is something to derive them from (a saved\r\n // pick, a background brightness verdict, or a forced scheme) — on boot the\r\n // persisted state has not loaded yet, and rColor() would flash the default.\r\n // Interface opacity used to sit behind that same gate, which left all four\r\n // sliders dead until the user dragged one: they are applied unconditionally\r\n // now, falling back to the host's own resolved surface tokens when the\r\n // plugin has no palette (see readHostOpacityTokens). Nothing here keys off\r\n // rColor() unless a palette is actually in play, so there is no boot flash.\r\n applyCustomTokens(rOps())\r\n if (rHasColor()) {\r\n applySettingsOverrides(rSop())\r\n applyTrajectoryOverrides(rTrajectoryOpacity())\r\n }\r\n // Panel slider: always applied, no longer gated on a palette being active.\r\n // The token re-scope rule lives in the always-on static stylesheet, and\r\n // `applyPanelOverrides` falls back to the host's own resolved tokens when\r\n // no plugin palette is present so the panel follows the slider in every\r\n // state (picked color, wallpaper verdict, forced scheme, or none).\r\n applyPanelOverrides(rPanelOpacity())\r\n applyProduced()\r\n applyHeaderPopovers()\r\n applyExemptDefaults()\r\n applyPartBlurs(rBlurs())\r\n // Strokes re-derive here so 'auto'/'theme' colors follow palette and\r\n // wallpaper-verdict changes (applyWp runs on every theme/color re-apply).\r\n applyStrokes()\r\n}\r\n\r\nexport function teardownWp(): void {\r\n clearDynamicBg()\r\n clearVideoEl()\r\n disposeVideoObjectUrl()\r\n setBgDark(null)\r\n wpVerdict = null\r\n wpEl?.remove(); wpEl = null\r\n clearCustomTokens()\r\n tokenStyleEl?.remove(); tokenStyleEl = null\r\n removeViewCards()\r\n document.body.removeAttribute('data-ds-dark-theme')\r\n document.body.style.removeProperty('color-scheme')\r\n document.documentElement.style.removeProperty('--dsh-any-bg-settings-surface')\r\n document.documentElement.style.removeProperty('--dsh-any-bg-settings-layer-1')\r\n document.documentElement.style.removeProperty('--dsh-any-bg-settings-layer-2')\r\n document.documentElement.style.removeProperty('--dsh-any-bg-settings-layer-3')\r\n document.documentElement.style.removeProperty('--dsh-any-traj-layer-1')\r\n document.documentElement.style.removeProperty('--dsh-any-traj-layer-2')\r\n document.documentElement.style.removeProperty('--dsh-any-traj-layer-3')\r\n document.documentElement.style.removeProperty('--dsh-any-bg-settings-card-surface')\r\n document.documentElement.style.removeProperty('--dsh-any-blur-settings')\r\n document.documentElement.style.removeProperty('--dsh-any-blur-card-panels')\r\n document.documentElement.style.removeProperty('--dsh-any-input-blur')\r\n document.documentElement.style.removeProperty('--dsh-any-part-blur-global')\r\n for (const set of [PANEL_LAYER_VARS, PROD_PANEL_LAYER_VARS, PROD_LAYER_VARS]) {\r\n for (const k of LAYER_KEYS) {\r\n const name = set[k]\r\n if (name) document.documentElement.style.removeProperty(name)\r\n }\r\n }\r\n document.documentElement.classList.remove(INPUT_FROST_CLASS)\r\n // Hand the seat takeover cards back untouched — the inline `position` this\r\n // pass may have written included (typed teardown, so no observer will).\r\n applyTakeoverFrost(0)\r\n // The header bar, the Windows caption band and the pinned probe go back to the\r\n // host: the classes come off, the two part variables and the rules are dropped.\r\n document.documentElement.style.removeProperty('--dsh-any-op-header-bar')\r\n document.documentElement.style.removeProperty('--dsh-any-blur-header-bar')\r\n document.querySelectorAll(`.${HEADER_BAR_CLASS}`).forEach(el => el.classList.remove(HEADER_BAR_CLASS))\r\n frameEl?.classList.remove(CAPTION_FRAME_CLASS)\r\n wcoStyleEl?.remove(); wcoStyleEl = null\r\n document.documentElement.style.removeProperty('--dsh-any-blur-panel')\r\n document.documentElement.style.removeProperty('--dsh-any-blur-prod')\r\n document.documentElement.style.removeProperty('--dsh-any-prod-pct')\r\n document.documentElement.style.removeProperty('--dsh-any-blur-header')\r\n headerStyleEl?.remove(); headerStyleEl = null\r\n exemptStyleEl?.remove(); exemptStyleEl = null\r\n for (const v of Object.values(OPACITY_VARS)) document.documentElement.style.removeProperty(v)\r\n baseTokenKey = ''\r\n lastBgKey = ''\r\n if (tokensRaf !== null) { cancelAnimationFrame(tokensRaf); tokensRaf = null }\r\n pendingOps = null\r\n tableFixStyleEl?.remove(); tableFixStyleEl = null\r\n partBlurStyleEl?.remove(); partBlurStyleEl = null\r\n removeStrokes()\r\n removeFontFace()\r\n // Drop the low-res drag cache and the drag flag: a teardown mid-drag leaves\r\n // the disposer's reset path short-circuited (!wpEl), and dragLow stuck true\r\n // would make every later setDragLow(true) a no-op — the drag-quality\r\n // downgrade silently never engages again.\r\n imgNat = null\r\n lowResUrl = null\r\n lowResFor = ''\r\n dragLow = false\r\n setBlur(frameEl, 0); setBlur(sidebarEl, 0); setBlur(centerEl, 0); setBlur(rightEl, 0)\r\n if (frameEl !== null) frameEl.classList.remove(PART_FRAME_CLASS)\r\n if (centerEl !== null) centerEl.style.removeProperty('background')\r\n if (rightEl !== null) rightEl.style.removeProperty('background')\r\n stopWatchingParts()\r\n}\r\n\r\n/** Live wallpaper-opacity updates during slider drag (no full re-apply). */\r\nexport function setWpOpacity(v: number): void {\r\n if (wpEl) wpEl.style.opacity = String(v)\r\n}\r\n\r\n/** Live wallpaper-blur updates during slider drag (no full re-apply). */\r\nexport function setWpBlur(v: number): void {\r\n if (wpEl) wpEl.style.filter = v > 0 ? `blur(${v}px)` : 'none'\r\n}\r\n","/**\r\n * Assembly of the plugin's one static stylesheet.\r\n *\r\n * Until now the sheet was a single template literal in the client entry with\r\n * thirteen constants bolted together in whatever order they were added. That\r\n * order is load-bearing and was documented in three separate comment blocks in\r\n * `wallpaper.ts` — so it is encoded here instead, in one list, with the reason\r\n * next to each entry.\r\n *\r\n * What the release can change lives in the slots marked below: the panel group\r\n * (which element carries the frost), the plugin-manager page (whether this release\r\n * ships that page at all), and the menu groups (which token a menu's fill comes\r\n * from and whose job its frost is). Everything outside a slot is host-agnostic by\r\n * construction — it targets attributes every release in range emits.\r\n *\r\n * The sheet is rebuilt when the release verdict lands. It has to be: `apply` runs\r\n * synchronously while the verdict is a Node round-trip, so the FIRST sheet is\r\n * always the unresolved, DOM-arbitrated one. That is the correct interim state,\r\n * and swapping in the resolved arm a moment later is what removes the `:has()`\r\n * dependency from hosts we do know the answer for.\r\n *\r\n * @module\r\n */\r\nimport {\r\n FRAME_CLEAR_RULE,\r\n HEADER_BAR_RULE,\r\n MOBILE_HEADER_RULE,\r\n PANEL_TOKEN_RULE,\r\n PLACEHOLDER_RULE,\r\n PRODUCED_RULE,\r\n SETTINGS_STYLE_RULE,\r\n STROKE_RULE,\r\n TRAJECTORY_STYLE_RULE,\r\n exemptDefaultRule,\r\n headerPopoverRule,\r\n inputBlurRule,\r\n popoverBlurRule,\r\n} from '../wallpaper'\r\nimport { rHostAdapter, subscribeHostInfo } from './release'\r\n\r\n/** The plugin's own dark-mode value on the body attribute the host sets. Scoping\r\n * the gradient to it avoids matching the host's own theme attribute. */\r\nconst DARK_GRADIENT =\r\n 'body[data-ds-dark-theme=\"dsh-any-background\"]::before{' +\r\n \"content:'';position:fixed;inset:0;z-index:-1;pointer-events:none;\" +\r\n 'background:radial-gradient(ellipse 80% 60% at 50% 0%,rgba(255,255,255,0.03) 0%,transparent 60%)}'\r\n\r\n/**\r\n * The order contract. Later entries override earlier ones at equal specificity,\r\n * which several groups rely on:\r\n * · headerPopoverRule() after popoverBlurRule() — a surface moving from the card\r\n * group to the header group must win, not merely be listed twice.\r\n * · PRODUCED_RULE / STROKE_RULE after the blur groups — they shield their\r\n * surfaces from an inherited slider.\r\n * · exemptDefaultRule() last of the token groups — an exemption has to land\r\n * after whatever it exempts.\r\n * · PLACEHOLDER_RULE genuinely last — `::placeholder` resets must survive every\r\n * group above.\r\n *\r\n * Three of these are FUNCTIONS, not constants, and they are version slots like\r\n * `panel.blur`: which declaration frosts a menu, and which token a menu's fill\r\n * comes from, is the current adapter's answer (`adapter.menus`). They stay in\r\n * place rather than moving next to the other slots because the contract above is\r\n * about position — a slot is only safe if it does not have to relocate.\r\n */\r\nexport function buildStaticStyles(): string {\r\n const adapter = rHostAdapter()\r\n const panel = adapter.panelFragments()\r\n // `← adapter` marks a version slot: the string it concatenates is chosen by the\r\n // resolved release. Everything else is host-agnostic by construction.\r\n return DARK_GRADIENT\r\n // First, not because anything competes with it, but because every surface\r\n // group below assumes the frame behind them is clear.\r\n + FRAME_CLEAR_RULE\r\n + SETTINGS_STYLE_RULE\r\n + popoverBlurRule() // ← adapter: a menu's frost + fill token\r\n + TRAJECTORY_STYLE_RULE\r\n + inputBlurRule() // ← adapter: the same fill tokens scoped to the input slider\r\n + MOBILE_HEADER_RULE\r\n // The session header bar's paint: the class is claimed at runtime, the\r\n // variables by applyHeaderBar (see HEADER_BAR_RULE).\r\n + HEADER_BAR_RULE\r\n + PANEL_TOKEN_RULE\r\n + panel.promotion // ← adapter: panel geometry, whose target element changed\r\n + panel.blur // ← adapter: ditto\r\n + adapter.pluginPageRule // ← adapter: the plugin-manager block, absent on old lines\r\n + PRODUCED_RULE\r\n + STROKE_RULE\r\n + headerPopoverRule() // ← adapter: same frost answer, header's own blur var\r\n + exemptDefaultRule() // ← adapter: the exemptions clear frost through it too\r\n + PLACEHOLDER_RULE\r\n}\r\n\r\n/** Append the plugin's stylesheet and keep it matched to the host.\r\n * Returns a teardown for the plugin's effect scope. */\r\nexport function mountStaticStyles(): () => void {\r\n const el = document.createElement('style')\r\n el.dataset.plugin = 'dsh-any-background'\r\n el.textContent = buildStaticStyles()\r\n document.head.appendChild(el)\r\n // Re-resolve only when the verdict actually changes; the write is a full sheet\r\n // swap, so it must not run on unrelated notifications.\r\n let last = el.textContent\r\n const unsubscribe = subscribeHostInfo(() => {\r\n const next = buildStaticStyles()\r\n if (next !== last) {\r\n last = next\r\n el.textContent = next\r\n }\r\n })\r\n return () => {\r\n unsubscribe()\r\n el.parentNode?.removeChild(el)\r\n }\r\n}\r\n","/**\r\n * Video-background helpers: capturing a single frame as a JPEG snapshot.\r\n * The snapshot stands in for everything that only understands still images:\r\n * the settings preview, theme-color extraction and the eyedropper. Uploads\r\n * stream the raw file over the binary upload route (see rpc.uploadVideo) —\r\n * a data-URL detour would inflate the bytes and trip the RPC body limit.\r\n */\r\n\r\nfunction grabFrame(v: HTMLVideoElement): string | null {\r\n const w = v.videoWidth, h = v.videoHeight\r\n if (w <= 0 || h <= 0) return null\r\n const canvas = document.createElement('canvas')\r\n canvas.width = w\r\n canvas.height = h\r\n const ctx = canvas.getContext('2d')\r\n if (!ctx) return null\r\n ctx.drawImage(v, 0, 0, w, h)\r\n try {\r\n return canvas.toDataURL('image/jpeg', 0.85)\r\n } catch {\r\n return null\r\n }\r\n}\r\n\r\n/**\r\n * Capture one representative frame from a video data URL as a JPEG data URL.\r\n * Seeks to ~10% of the duration (first frame is often black) and waits for\r\n * the seek to land; resolves null when the video cannot be decoded. A timeout\r\n * keeps a broken file from hanging the upload flow.\r\n */\r\nexport function captureVideoSnapshot(url: string): Promise<string | null> {\r\n return new Promise(resolve => {\r\n const v = document.createElement('video')\r\n let settled = false\r\n const done = (r: string | null): void => {\r\n if (settled) return\r\n settled = true\r\n window.clearTimeout(timer)\r\n v.removeAttribute('src')\r\n v.load()\r\n resolve(r)\r\n }\r\n const timer = window.setTimeout(() => done(grabFrame(v)), 6000)\r\n v.muted = true\r\n v.preload = 'auto'\r\n v.playsInline = true\r\n v.onerror = () => done(null)\r\n v.onloadeddata = () => {\r\n // Prefer a frame slightly into the clip; very short clips seek to half.\r\n const target = isFinite(v.duration) && v.duration > 0.6 ? Math.min(v.duration * 0.1, 2) : 0\r\n if (target <= 0) { done(grabFrame(v)); return }\r\n v.onseeked = () => done(grabFrame(v))\r\n try {\r\n v.currentTime = target\r\n } catch {\r\n done(grabFrame(v))\r\n }\r\n }\r\n v.src = url\r\n })\r\n}\r\n","/**\n * dsh-any-background — settings UI design system.\n *\n * The section is styled entirely through these scoped classes instead of the\n * host's inline-style approach: animations (page transitions, staggered\n * reveals, the rotating orb ring) and pseudo-element effects cannot be\n * expressed as React inline styles. Every color reads the host's\n * --dsw-alias-* tokens so the panel follows the user's custom theme color and\n * light/dark scheme automatically; `color-mix` tints carry a plain-token\n * fallback first for older engines.\n */\nexport const NAV_ITEM_H = 38\nexport const NAV_GAP = 4\n\nexport const UI_CSS = `\n/* The section is rendered INLINE inside the host settings dialog's content\n * column: the host provides the modal chrome (backdrop, centering, closing).\n * These classes style only the embedded shell; transient fixed layers (toast,\n * color picker, background editor) escape through Portals on <html>. */\n.dab-root{position:relative;box-sizing:border-box;color:var(--dsw-alias-label-primary);animation:dab-fade-in .35s ease both;container-type:inline-size;display:flex;flex-direction:column;align-items:center;width:100%;min-width:0;--dab-mono:ui-monospace,\"Cascadia Mono\",\"SF Mono\",Consolas,\"Courier New\",monospace}\n/* The root needs its OWN border-box, not just the descendants' below: the\n * sidebar surface puts 12px of padding on it, and with the default content-box\n * that padding landed OUTSIDE the width:100%, so the page came out 24px wider\n * than the pane and the host clipped both edges off. */\n.dab-root *,.dab-root *::before,.dab-root *::after{box-sizing:border-box}\n.dab-root button{font-family:inherit}\n\n/* ── shell: nav rail + page body ─────────────────────────────────────────── */\n.dab-shell{display:grid;grid-template-columns:158px minmax(0,1fr);gap:26px;align-items:start;padding-bottom:8px;width:100%;max-width:980px;margin:0 auto}\n.dab-nav{position:sticky;top:0;display:flex;flex-direction:column;gap:18px}\n.dab-brand{display:flex;align-items:center;gap:10px;padding:2px 6px}\n.dab-brand-tile{width:30px;height:30px;flex:none;border-radius:9px;display:grid;place-items:center;color:var(--dsw-alias-brand-text);background:var(--dsw-alias-brand-primary);box-shadow:0 4px 14px -4px var(--dsw-alias-brand-primary)}\n.dab-brand-name{font-size:13px;font-weight:650;letter-spacing:.01em;line-height:1.25}\n.dab-brand-tag{font-size:9px;letter-spacing:.16em;font-weight:600;color:var(--dsw-alias-label-quaternary,var(--dsw-alias-label-tertiary));text-transform:uppercase}\n.dab-nav-list{position:relative;display:flex;flex-direction:column;gap:${NAV_GAP}px}\n.dab-nav-ind{position:absolute;left:0;right:0;top:0;height:${NAV_ITEM_H}px;border-radius:11px;background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);background:color-mix(in srgb,var(--dsw-alias-brand-primary) 13%,transparent);border-color:color-mix(in srgb,var(--dsw-alias-brand-primary) 25%,transparent);transition:transform .38s cubic-bezier(.22,1,.36,1)}\n.dab-nav-item{position:relative;z-index:1;display:flex;align-items:center;gap:10px;height:${NAV_ITEM_H}px;padding:0 12px;border:0;background:none;border-radius:11px;color:var(--dsw-alias-label-tertiary);font-size:13px;cursor:pointer;text-align:left;transition:color .22s ease}\n.dab-nav-item:hover{color:var(--dsw-alias-label-primary)}\n.dab-nav-item.is-active{color:var(--dsw-alias-brand-primary);font-weight:600}\n.dab-nav-item svg{flex:none;transition:transform .3s cubic-bezier(.34,1.56,.64,1)}\n.dab-nav-item:hover svg{transform:scale(1.14) rotate(-5deg)}\n\n/* ── page chrome ─────────────────────────────────────────────────────────── */\n.dab-page{animation:dab-page-in .4s cubic-bezier(.22,1,.36,1) both;min-width:0;display:flex;flex-direction:column;gap:13px}\n.dab-head{margin:2px 0 5px}\n.dab-overline{font-size:10.5px;font-weight:700;letter-spacing:.18em;text-transform:uppercase;color:var(--dsw-alias-brand-primary);opacity:.9}\n.dab-h1{margin:4px 0 0;font-size:21px;font-weight:700;letter-spacing:-.01em}\n.dab-desc{margin:6px 0 0;font-size:12.5px;line-height:1.55;color:var(--dsw-alias-label-tertiary);max-width:56ch}\n.dab-card{background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l2);border-radius:16px;padding:18px}\n.dab-card-hover{transition:transform .28s ease,box-shadow .28s ease,border-color .28s ease}\n.dab-card-hover:hover{transform:translateY(-2px);box-shadow:0 10px 28px -12px rgba(0,0,0,.28)}\n.dab-rise{animation:dab-rise-in .55s cubic-bezier(.22,1,.36,1) both;animation-delay:calc(var(--d,0) * 62ms)}\n\n/* ── accent hero (color orb) ─────────────────────────────────────────────── */\n.dab-hero-accent{display:flex;align-items:center;gap:24px;flex-wrap:wrap}\n.dab-orb-wrap{position:relative;width:118px;height:118px;flex:none}\n.dab-orb{position:absolute;inset:11px;border-radius:50%;background:radial-gradient(circle at 32% 28%,rgba(255,255,255,.5),rgba(255,255,255,0) 44%),var(--c,#888);box-shadow:0 16px 36px -10px var(--c-soft,transparent),inset 0 -10px 20px rgba(0,0,0,.16);animation:dab-orb-in .7s cubic-bezier(.22,1,.36,1) both}\n.dab-orb-ring{position:absolute;inset:0;border-radius:50%;background:conic-gradient(from 0deg,transparent 0 30%,var(--c,#888) 46%,transparent 62%,transparent 76%,var(--c,#888) 90%,transparent 100%);-webkit-mask:radial-gradient(farthest-side,transparent calc(100% - 3.5px),#000 calc(100% - 2.5px));mask:radial-gradient(farthest-side,transparent calc(100% - 3.5px),#000 calc(100% - 2.5px));animation:dab-spin 7s linear infinite;opacity:.9}\n.dab-hex-caption{font-size:11px;color:var(--dsw-alias-label-tertiary);letter-spacing:.04em}\n.dab-hex{font-family:var(--dab-mono);font-size:24px;font-weight:600;letter-spacing:.02em;line-height:1.2;margin-top:2px}\n.dab-hsl-row{display:flex;gap:16px;margin-top:7px;font-family:var(--dab-mono);font-size:11px;color:var(--dsw-alias-label-tertiary)}\n.dab-hsl-row b{font-weight:600;color:var(--dsw-alias-label-secondary,var(--dsw-alias-label-tertiary))}\n\n/* ── swatches ────────────────────────────────────────────────────────────── */\n.dab-swatch-title{font-size:12px;font-weight:600;margin-bottom:10px;color:var(--dsw-alias-label-secondary,var(--dsw-alias-label-tertiary))}\n.dab-swatches{display:flex;flex-wrap:wrap;gap:9px}\n.dab-swatch{width:25px;height:25px;border-radius:50%;border:0;padding:0;cursor:pointer;box-shadow:inset 0 0 0 1px rgba(0,0,0,.1);transition:transform .22s cubic-bezier(.34,1.56,.64,1),box-shadow .22s ease}\n.dab-swatch:hover{transform:scale(1.2)}\n.dab-swatch.is-on{box-shadow:0 0 0 2px var(--dsw-alias-bg-layer-1),0 0 0 4px var(--dsw-alias-brand-primary)}\n\n/* ── wheel card ──────────────────────────────────────────────────────────── */\n.dab-wheel-card{position:relative;display:flex;align-items:center;justify-content:center;gap:28px;flex-wrap:wrap;padding:24px 18px}\n.dab-wheel-glow{position:absolute;width:230px;height:230px;border-radius:50%;filter:blur(48px);opacity:.2;background:var(--c,#888);pointer-events:none;transition:background .4s ease}\n/* flex:none is load bearing, not cosmetic: the pointer maths reads client\n * coordinates straight off this element's box, so any shrink below the 220px\n * drawing surface would desynchronise the ring from the cursor. */\n.dab-wheel{position:relative;flex:none;cursor:crosshair;border-radius:50%;box-shadow:0 12px 32px -14px rgba(0,0,0,.4)}\n.dab-hint{font-size:11.5px;line-height:1.55;color:var(--dsw-alias-label-tertiary);padding:0 4px}\n\n/* ── precise color inputs ────────────────────────────────────────────────── */\n.dab-inputs{display:flex;flex-direction:column;gap:10px;min-width:172px}\n.dab-field{display:flex;align-items:center;gap:8px}\n.dab-field-label{width:14px;text-align:center;font-family:var(--dab-mono);font-size:11px;font-weight:600;color:var(--dsw-alias-label-tertiary)}\n.dab-num{flex:1;min-width:0;height:30px;padding:0 10px;border-radius:9px;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-primary);font-family:var(--dab-mono);font-size:12px;outline:none;transition:border-color .2s,box-shadow .2s}\n.dab-num:focus{border-color:var(--dsw-alias-brand-primary);box-shadow:0 0 0 3px color-mix(in srgb,var(--dsw-alias-brand-primary) 18%,transparent)}\n.dab-num::-webkit-outer-spin-button,.dab-num::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}\n.dab-num{-moz-appearance:textfield;appearance:textfield}\n.dab-urlinput{flex:1;min-width:180px;height:34px;padding:0 12px;border-radius:10px;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-primary);font-size:12.5px;outline:none;transition:border-color .2s}\n.dab-urlinput::placeholder{color:var(--dsw-alias-label-quaternary)}\n.dab-urlinput:focus{border-color:var(--dsw-alias-brand-primary);box-shadow:0 0 0 3px color-mix(in srgb,var(--dsw-alias-brand-primary) 18%,transparent)}\n.dab-urlrow{display:flex;flex-wrap:wrap;gap:8px;align-items:center;margin-top:12px;animation:dab-list-in .3s cubic-bezier(.22,1,.36,1) both}\n.dab-swatch-lg{height:38px;border-radius:10px;border:1px solid var(--dsw-alias-border-l2);box-shadow:inset 0 0 14px rgba(0,0,0,.1);transition:transform .3s ease}\n.dab-swatch-lg:hover{transform:scale(1.02)}\n\n/* ── buttons & chips ─────────────────────────────────────────────────────── */\n.dab-btn{display:inline-flex;align-items:center;justify-content:center;gap:7px;height:34px;padding:0 14px;border-radius:10px;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-button-elevated-fill);color:var(--dsw-alias-label-primary);font-size:12.5px;font-weight:550;cursor:pointer;transition:transform .18s ease,box-shadow .18s ease,border-color .18s ease,opacity .18s ease,background .18s ease}\n.dab-btn:hover:not(:disabled){transform:translateY(-1px);box-shadow:0 5px 14px -6px rgba(0,0,0,.32)}\n.dab-btn:active:not(:disabled){transform:translateY(0) scale(.97);box-shadow:none}\n.dab-btn:disabled{opacity:.5;cursor:not-allowed}\n.dab-btn-primary{background:var(--dsw-alias-brand-primary);color:var(--dsw-alias-brand-text);border-color:transparent}\n.dab-btn-danger{color:var(--dsw-alias-state-error-primary)}\n.dab-btn-danger-solid{background:var(--dsw-alias-state-error-primary);color:#fff;border-color:transparent}\n.dab-btn-danger-solid:hover:not(:disabled){background:color-mix(in srgb,var(--dsw-alias-state-error-primary) 85%,#000)}\n.dab-btn-ghost{background:transparent;border-color:transparent;color:var(--dsw-alias-label-secondary,var(--dsw-alias-label-tertiary))}\n.dab-btn-ghost:hover:not(:disabled){background:var(--dsw-alias-bg-layer-2);box-shadow:none}\n/* Soft solid button: subtle layer background instead of transparent ghost. */\n.dab-btn-soft{background:var(--dsw-alias-bg-layer-2);border-color:var(--dsw-alias-border-l2);color:var(--dsw-alias-label-secondary,var(--dsw-alias-label-tertiary))}\n.dab-btn-soft:hover:not(:disabled){background:var(--dsw-alias-bg-layer-3,var(--dsw-alias-bg-layer-2));color:var(--dsw-alias-label-primary)}\n/* White background with error-red text (inverse of danger-solid). */\n.dab-btn-danger-inverted{background:#fff;color:var(--dsw-alias-state-error-primary);border-color:transparent}\n.dab-btn-danger-inverted:hover:not(:disabled){background:#f3f4f6}\n.dab-btn:focus-visible,.dab-nav-item:focus-visible,.dab-seg-item:focus-visible,.dab-swatch:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:2px}\n.dab-chip-row{display:flex;flex-wrap:wrap;gap:8px}\n.dab-chip{height:30px;padding:0 14px;border-radius:99px;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-secondary,var(--dsw-alias-label-tertiary));font-size:12px;cursor:pointer;display:inline-flex;align-items:center;gap:6px;transition:background-color .22s ease,border-color .22s ease,color .22s ease}\n.dab-chip:hover{border-color:var(--dsw-alias-brand-primary);color:var(--dsw-alias-label-primary)}\n.dab-chip.is-active{background:var(--dsw-alias-brand-primary);color:var(--dsw-alias-brand-text);border-color:transparent}\n\n/* ── sliders ─────────────────────────────────────────────────────────────── */\n.dab-slider-block{display:flex;flex-direction:column;gap:6px}\n.dab-slider-block + .dab-slider-block{margin-top:13px}\n.dab-slider-label{font-size:12px;font-weight:550;color:var(--dsw-alias-label-secondary,var(--dsw-alias-label-tertiary))}\n.dab-slider-val{font-family:var(--dab-mono);font-size:11px;color:var(--dsw-alias-label-tertiary);min-width:44px;text-align:right}\n.dab-slider{-webkit-appearance:none;appearance:none;flex:1;min-width:0;height:4px;border-radius:99px;outline:none;cursor:pointer;margin:5px 0;background:linear-gradient(to right,var(--dsw-alias-brand-primary) calc(var(--pct,50) * 1%),var(--dsw-alias-border-l2) calc(var(--pct,50) * 1%));transition:height .15s ease}\n.dab-slider:hover{height:5px}\n.dab-slider::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;width:15px;height:15px;border-radius:50%;background:var(--dsw-alias-button-elevated-fill,#fff);border:2px solid var(--dsw-alias-brand-primary);box-shadow:0 1px 5px rgba(0,0,0,.28);transition:transform .16s cubic-bezier(.34,1.56,.64,1)}\n.dab-slider:hover::-webkit-slider-thumb,.dab-slider:focus-visible::-webkit-slider-thumb{transform:scale(1.22)}\n.dab-slider:active::-webkit-slider-thumb{transform:scale(1.34)}\n.dab-slider::-moz-range-thumb{width:13px;height:13px;border-radius:50%;background:var(--dsw-alias-button-elevated-fill,#fff);border:2px solid var(--dsw-alias-brand-primary)}\n\n/* ── interface part cards ────────────────────────────────────────────────── */\n.dab-grid-parts{display:grid;grid-template-columns:repeat(auto-fill,minmax(min(240px,100%),1fr));gap:13px}\n.dab-part-head{display:flex;align-items:center;gap:11px;margin-bottom:14px}\n.dab-part-ico{width:32px;height:32px;flex:none;border-radius:10px;display:grid;place-items:center;color:var(--dsw-alias-brand-primary);background:var(--dsw-alias-bg-layer-2);background:color-mix(in srgb,var(--dsw-alias-brand-primary) 12%,transparent)}\n.dab-part-name{font-size:13.5px;font-weight:600}\n.dab-part-badge{margin-left:auto;font-family:var(--dab-mono);font-size:11px;color:var(--dsw-alias-label-tertiary);background:var(--dsw-alias-bg-layer-2);border-radius:99px;padding:3px 9px}\n\n/* ── segmented control ───────────────────────────────────────────────────── */\n.dab-seg{position:relative;display:inline-flex;padding:3px;background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);border-radius:11px}\n.dab-seg-thumb{position:absolute;top:3px;bottom:3px;left:3px;width:var(--w,96px);border-radius:8px;background:var(--dsw-alias-button-elevated-fill);box-shadow:0 2px 8px -2px rgba(0,0,0,.28);transition:transform .32s cubic-bezier(.22,1,.36,1)}\n.dab-seg-item{position:relative;z-index:1;display:inline-flex;align-items:center;justify-content:center;gap:6px;width:var(--w,96px);height:30px;border:0;background:none;border-radius:8px;color:var(--dsw-alias-label-tertiary);font-size:12.5px;cursor:pointer;transition:color .25s ease}\n.dab-seg-item.is-active{color:var(--dsw-alias-label-primary);font-weight:600}\n\n/* ── toggle switch ───────────────────────────────────────────────────────── */\n.dab-toggle{position:relative;width:42px;height:24px;flex:none;border-radius:99px;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);cursor:pointer;padding:0;transition:background .28s ease,border-color .28s ease}\n.dab-toggle-knob{position:absolute;top:2.5px;left:2.5px;width:17px;height:17px;border-radius:50%;background:var(--dsw-alias-label-secondary,#999);box-shadow:0 1px 3px rgba(0,0,0,.3);transition:transform .28s cubic-bezier(.22,1,.36,1),background .28s ease}\n.dab-toggle.is-on{background:var(--dsw-alias-brand-primary);border-color:var(--dsw-alias-brand-primary)}\n.dab-toggle.is-on .dab-toggle-knob{transform:translateX(18px);background:#fff}\n\n/* ── custom font card ────────────────────────────────────────────────────── */\n.dab-font-title{display:flex;align-items:center;gap:11px}\n.dab-font-row{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-top:14px}\n.dab-font-name{font-family:var(--dab-mono);font-size:13.5px;color:var(--dsw-alias-label-secondary,var(--dsw-alias-label-tertiary));background:var(--dsw-alias-bg-layer-2);border-radius:99px;padding:5px 11px;max-width:260px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n.dab-font-name.is-empty{color:var(--dsw-alias-label-tertiary)}\n.dab-font-actions{display:flex;align-items:center;gap:8px;margin-left:auto}\n/* The font card's labels read one step larger than the rest of the panel —\n they carry most of the explanation on this page. Scoped to the card so the\n same .dab-hint / .dab-btn elsewhere keep their size. */\n.dab-font-actions .dab-btn{font-size:14.5px}\n.dab-font-card .dab-hint{font-size:13.5px}\n\n/* ── text-stroke color dots ──────────────────────────────────────────────── */\n.dab-stroke-dots{display:flex;align-items:center;gap:9px;margin-top:14px}\n.dab-stroke-dot-wrap{position:relative;width:18px;height:18px;flex:none}\n.dab-stroke-dot{width:18px;height:18px;padding:0;border-radius:50%;border:1.5px solid var(--dsw-alias-border-l2);background-clip:padding-box;cursor:pointer;transition:transform .18s cubic-bezier(.34,1.56,.64,1),box-shadow .18s ease}\n.dab-stroke-dot:hover{transform:scale(1.16)}\n/* 'auto' has no fixed value — half light / half dark reads as \"derived\". */\n.dab-stroke-dot-auto{background:conic-gradient(from -90deg,#fff 0 50%,#000 50% 100%)}\n.dab-stroke-dot.is-active{box-shadow:0 0 0 2px var(--dsw-alias-bg-layer-1),0 0 0 3.5px var(--dsw-alias-brand-primary);border-color:transparent}\n/* The native color picker sits invisible on top of the custom swatch. */\n.dab-stroke-dot-input{position:absolute;inset:0;width:100%;height:100%;margin:0;padding:0;border:0;border-radius:50%;background:none;opacity:0;cursor:pointer}\n\n/* ── background preview hero ─────────────────────────────────────────────── */\n.dab-hero{position:relative;border-radius:16px;overflow:hidden;aspect-ratio:16/9;background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2)}\n.dab-hero-img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;transition:transform .5s cubic-bezier(.22,1,.36,1)}\n.dab-hero:hover .dab-hero-img{transform:scale(1.03)}\n.dab-hero-empty{position:absolute;inset:6px;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:10px;color:var(--dsw-alias-label-tertiary);font-size:12.5px;border:1.5px dashed var(--dsw-alias-border-l2);border-radius:12px;cursor:pointer;background:transparent;transition:border-color .25s,color .25s,background .25s;width:auto;height:auto}\n.dab-hero-empty:hover{border-color:var(--dsw-alias-brand-primary);color:var(--dsw-alias-brand-primary)}\n.dab-hero-empty.is-over{border-color:var(--dsw-alias-brand-primary);color:var(--dsw-alias-brand-primary);background:color-mix(in srgb,var(--dsw-alias-brand-primary) 8%,transparent)}\n.dab-hero-badge{position:absolute;top:10px;left:10px;display:inline-flex;align-items:center;gap:5px;height:24px;padding:0 11px;border-radius:99px;background:rgba(0,0,0,.45);color:#fff;font-size:11px;backdrop-filter:blur(6px);pointer-events:none}\n.dab-hero-veil{position:absolute;left:0;right:0;bottom:0;padding:34px 12px 12px;display:flex;align-items:flex-end;justify-content:flex-end;gap:8px;background:linear-gradient(to top,rgba(0,0,0,.55),rgba(0,0,0,0));opacity:0;transform:translateY(6px);transition:opacity .3s ease,transform .3s ease}\n.dab-hero:hover .dab-hero-veil{opacity:1;transform:none}\n.dab-hero-veil .dab-btn{background:rgba(255,255,255,.94);color:#14161a;border-color:transparent;height:30px;font-size:12px}\n.dab-hero-veil .dab-btn-danger{color:#dc2626}\n\n/* ── generated background type cards ─────────────────────────────────────── */\n.dab-types{display:grid;grid-template-columns:repeat(3,1fr);gap:12px}\n.dab-type{position:relative;border:1.5px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-1);border-radius:14px;padding:10px;cursor:pointer;text-align:left;font:inherit;transition:border-color .25s,transform .25s,box-shadow .25s;animation:dab-type-in .42s cubic-bezier(.22,1,.36,1) both;animation-delay:calc(var(--i,0) * 60ms)}\n.dab-type:hover{transform:translateY(-2px)}\n.dab-type.is-active{border-color:var(--dsw-alias-brand-primary);box-shadow:0 0 0 3px color-mix(in srgb,var(--dsw-alias-brand-primary) 18%,transparent)}\n.dab-type-thumb{height:62px;border-radius:9px;overflow:hidden;position:relative}\n.dab-type-name{margin-top:9px;font-size:12.5px;font-weight:600;color:var(--dsw-alias-label-primary)}\n.dab-type-desc{margin-top:2px;font-size:11px;color:var(--dsw-alias-label-tertiary);line-height:1.4}\n.dab-type-check{position:absolute;top:16px;right:16px;width:20px;height:20px;border-radius:50%;background:var(--dsw-alias-brand-primary);color:var(--dsw-alias-brand-text);display:grid;place-items:center;opacity:0;transform:scale(.4);transition:opacity .25s,transform .25s cubic-bezier(.34,1.56,.64,1)}\n.dab-type.is-active .dab-type-check{opacity:1;transform:none}\n.dab-thumb-mesh{background:radial-gradient(circle at 22% 30%,#f472b6,transparent 42%),radial-gradient(circle at 80% 22%,#38bdf8,transparent 46%),radial-gradient(circle at 52% 84%,#fbbf24,transparent 52%),#1e293b}\n.dab-thumb-shader{background:linear-gradient(120deg,#0ea5e9,#8b5cf6,#d946ef,#0ea5e9);background-size:300% 300%;animation:dab-flow 6s linear infinite}\n.dab-thumb-pattern{background-image:radial-gradient(circle,rgba(255,255,255,.92) 1.2px,transparent 1.4px);background-size:10px 10px;background-color:#334155}\n\n/* ── seed row ────────────────────────────────────────────────────────────── */\n.dab-seed{display:flex;align-items:center;gap:13px;padding:12px 14px;border-radius:12px;background:var(--dsw-alias-bg-layer-2);margin-top:14px}\n.dab-seed-ico{color:var(--dsw-alias-brand-primary);display:grid;place-items:center}\n.dab-seed-txt{flex:1;min-width:0}\n.dab-seed-title{font-size:12.5px;font-weight:600;display:flex;align-items:center;gap:6px}\n.dab-seed-desc{font-size:11px;color:var(--dsw-alias-label-tertiary);margin-top:2px}\n.dab-spin{animation:dab-rotate .7s cubic-bezier(.3,.7,.3,1) 1}\n\n/* ── profile page ────────────────────────────────────────────────────────── */\n.dab-profile-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(220px,100%),1fr));gap:13px}\n.dab-profile-ico{width:38px;height:38px;border-radius:11px;display:grid;place-items:center;margin-bottom:13px;color:var(--dsw-alias-brand-primary);background:var(--dsw-alias-bg-layer-2);background:color-mix(in srgb,var(--dsw-alias-brand-primary) 12%,transparent)}\n.dab-profile-title{font-size:14px;font-weight:650}\n.dab-profile-desc{font-size:12px;color:var(--dsw-alias-label-tertiary);line-height:1.55;margin:5px 0 15px}\n.dab-footer{margin-top:6px;padding:14px 4px 0;border-top:1px solid var(--dsw-alias-border-l2);display:flex;align-items:center;justify-content:space-between;font-size:11px;color:var(--dsw-alias-label-tertiary)}\n.dab-footer-mono{font-family:var(--dab-mono);letter-spacing:.02em}\n\n/* ── presets / profiles / schedule / rotation ────────────────────────────── */\n.dab-row-head{display:flex;align-items:center;justify-content:space-between;gap:12px}\n.dab-preset-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(min(150px,100%),1fr));gap:10px}\n.dab-preset{display:flex;flex-direction:column;align-items:flex-start;gap:3px;padding:12px;border:1.5px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-1);border-radius:13px;cursor:pointer;font:inherit;text-align:left;transition:border-color .25s,transform .25s,box-shadow .25s;animation:dab-row-in .34s cubic-bezier(.22,1,.36,1) both;animation-delay:calc(var(--i,0) * 45ms)}\n.dab-preset:hover{transform:translateY(-2px);border-color:var(--dsw-alias-brand-primary);box-shadow:0 8px 22px -12px rgba(0,0,0,.3)}\n.dab-preset-dot{width:22px;height:22px;border-radius:50%;margin-bottom:4px;box-shadow:inset 0 0 0 1px rgba(0,0,0,.12),0 4px 10px -4px rgba(0,0,0,.35);background:var(--dsw-alias-bg-layer-2);display:grid;place-items:center;color:var(--dsw-alias-label-tertiary)}\n.dab-preset-name{font-size:12.5px;font-weight:600;color:var(--dsw-alias-label-primary)}\n.dab-preset-desc{font-size:10.5px;line-height:1.45;color:var(--dsw-alias-label-tertiary)}\n.dab-profile-list{display:flex;flex-direction:column;gap:8px;margin-top:12px;animation:dab-list-in .38s cubic-bezier(.22,1,.36,1) both}\n.dab-profile-row{display:flex;align-items:center;gap:11px;padding:9px 12px;border:1px solid var(--dsw-alias-border-l2);border-radius:12px;background:var(--dsw-alias-bg-layer-2);animation:dab-row-in .34s cubic-bezier(.22,1,.36,1) both;animation-delay:calc(var(--i,0) * 45ms);transition:border-color .22s ease,background .22s ease}\n.dab-profile-row:hover{border-color:color-mix(in srgb,var(--dsw-alias-brand-primary) 28%,transparent);background:color-mix(in srgb,var(--dsw-alias-label-primary) 4%,var(--dsw-alias-bg-layer-2))}\n.dab-profile-row.is-active{border-color:color-mix(in srgb,var(--dsw-alias-brand-primary) 45%,transparent);background:color-mix(in srgb,var(--dsw-alias-brand-primary) 7%,var(--dsw-alias-bg-layer-2))}\n.dab-profile-dot{width:22px;height:22px;flex:none;border-radius:50%;background:var(--dsw-alias-bg-layer-1);box-shadow:inset 0 0 0 1px rgba(0,0,0,.12);display:grid;place-items:center;color:var(--dsw-alias-label-tertiary)}\n.dab-profile-meta{flex:1;min-width:0;display:flex;flex-direction:column;gap:1px}\n.dab-profile-name{font-size:12.5px;font-weight:600;color:var(--dsw-alias-label-primary);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n.dab-profile-sub{font-family:var(--dab-mono);font-size:10px;color:var(--dsw-alias-label-tertiary)}\n.dab-btn-confirm{background:var(--dsw-alias-state-error-primary)!important;color:#fff!important;border-color:transparent!important}\n.dab-select{height:32px;padding:0 10px;border-radius:9px;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-primary);font-size:12px;outline:none;cursor:pointer;max-width:180px}\n.dab-select:focus{border-color:var(--dsw-alias-brand-primary)}\n.dab-timeinput{height:32px;padding:0 8px;border-radius:9px;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-primary);font-family:var(--dab-mono);font-size:12px;outline:none}\n.dab-timeinput:focus{border-color:var(--dsw-alias-brand-primary)}\n/* Collapsible panel: animates grid-template-rows 0fr→1fr so the schedule\n block unfolds to its content height instead of popping in. visibility\n flips after the fold finishes (and instantly on open) so hidden inputs\n are never focusable. */\n.dab-schedule-wrap{display:grid;grid-template-rows:0fr;visibility:hidden;transition:grid-template-rows .42s cubic-bezier(.22,1,.36,1),visibility 0s linear .42s}\n.dab-schedule-wrap.is-open{grid-template-rows:1fr;visibility:visible;transition:grid-template-rows .42s cubic-bezier(.22,1,.36,1)}\n.dab-schedule-clip{overflow:hidden;min-height:0;opacity:0;transition:opacity .28s ease}\n.dab-schedule-wrap.is-open .dab-schedule-clip{opacity:1;transition:opacity .32s ease .1s}\n.dab-schedule-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(220px,100%),1fr));gap:16px;padding-top:12px}\n.dab-schedule-cell{min-width:0;animation:dab-row-in .34s cubic-bezier(.22,1,.36,1) both;animation-delay:calc(var(--i,0) * 60ms)}\n.dab-time-row{display:flex;flex-direction:column;gap:9px}\n.dab-time-label{display:flex;align-items:center;gap:7px;font-size:12px;color:var(--dsw-alias-label-secondary,var(--dsw-alias-label-tertiary))}\n.dab-time-label svg{color:var(--dsw-alias-brand-primary);flex:none}\n.dab-time-label .dab-select,.dab-time-label .dab-timeinput{flex:1;min-width:0}\n.dab-thumbstrip{display:flex;flex-wrap:wrap;gap:9px;margin-top:13px}\n.dab-thumb{position:relative;width:64px;height:44px;border-radius:9px;overflow:hidden;border:1.5px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);display:grid;place-items:center;color:var(--dsw-alias-label-tertiary);animation:dab-list-in .3s cubic-bezier(.22,1,.36,1) both}\n.dab-thumb.is-current{border-color:var(--dsw-alias-brand-primary);box-shadow:0 0 0 2px color-mix(in srgb,var(--dsw-alias-brand-primary) 25%,transparent)}\n.dab-thumb img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}\n.dab-thumb-x{position:absolute;top:2px;right:2px;width:16px;height:16px;border:0;border-radius:50%;background:rgba(0,0,0,.55);color:#fff;cursor:pointer;display:grid;place-items:center;opacity:0;transition:opacity .18s ease,background .18s ease;padding:0}\n.dab-thumb:hover .dab-thumb-x{opacity:1}\n.dab-thumb-x:hover{background:var(--dsw-alias-state-error-primary)}\n.dab-thumb-add{border-style:dashed;cursor:pointer;background:transparent;color:var(--dsw-alias-label-tertiary);font:inherit;transition:border-color .22s ease,color .22s ease}\n.dab-thumb-add:hover{border-color:var(--dsw-alias-brand-primary);color:var(--dsw-alias-brand-primary)}\n.dab-chip-sep{width:1px;height:18px;background:var(--dsw-alias-border-l2);margin:0 4px;flex:none}\n\n/* ── toast ───────────────────────────────────────────────────────────────── */\n.dab-toast{position:fixed;left:50%;bottom:30px;transform:translateX(-50%);display:flex;align-items:center;gap:8px;height:38px;padding:0 16px;border-radius:99px;background:var(--dsw-alias-bg-layer-3,var(--dsw-alias-bg-layer-2));border:1px solid var(--dsw-alias-border-l2);box-shadow:0 10px 30px -8px rgba(0,0,0,.38);font-size:12.5px;z-index:10001;animation:dab-toast-in .32s cubic-bezier(.22,1,.36,1) both}\n.dab-toast-ok{color:var(--dsw-alias-brand-primary);display:grid;place-items:center}\n.dab-toast-err{color:var(--dsw-alias-state-error-primary);display:grid;place-items:center}\n\n/* ── modals (editor / eyedropper / crash) ────────────────────────────────── */\n/* Pin to the viewport explicitly with vw/vh so ancestor padding/margins on\n * body cannot shift or clip the overlay; keep it above host sidebar chrome.\n * pointer-events:auto re-enables interaction: these overlays render inside a\n * Portal root that is pointer-events:none so it never blocks the page alone. */\n.dab-overlay{position:fixed;left:0;top:0;width:100vw;height:100vh;z-index:999999;background:rgba(8,10,14,.62);backdrop-filter:blur(8px);display:flex;flex-direction:column;align-items:center;justify-content:center;gap:14px;animation:dab-fade-in .25s ease both;pointer-events:auto}\n.dab-overlay-title{color:#fff;font-size:15px;font-weight:600}\n.dab-overlay-hint{color:rgba(255,255,255,.62);font-size:12px}\n.dab-modal-card{animation:dab-zoom-in .3s cubic-bezier(.22,1,.36,1) both;max-width:calc(100vw - 40px);max-height:calc(100vh - 120px);overflow:auto}\n.dab-overlay .dab-btn{background:rgba(255,255,255,.94);color:#14161a;border-color:transparent}\n.dab-overlay .dab-btn-primary{background:var(--dsw-alias-brand-primary);color:var(--dsw-alias-brand-text)}\n.dab-crash{display:flex;flex-direction:column;gap:10px;align-items:center;padding:28px 18px;border:1px solid var(--dsw-alias-border-l2);border-radius:16px}\n.dab-crash-title{font-size:15px;font-weight:650}\n.dab-crash-desc{font-size:12px;color:var(--dsw-alias-label-tertiary);text-align:center;line-height:1.5}\n/* The crash cause: readable, scrollable, and clipped to a few lines so a long\n * stack cannot push the reset button off the panel. */\n.dab-crash-detail{margin:0;max-width:min(520px,80vw);max-height:132px;overflow:auto;padding:8px 10px;border-radius:8px;background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);font-family:var(--dab-mono);font-size:10.5px;line-height:1.5;color:var(--dsw-alias-label-secondary,var(--dsw-alias-label-tertiary));text-align:left;white-space:pre-wrap;word-break:break-word}\n\n/* ── keyframes ───────────────────────────────────────────────────────────── */\n@keyframes dab-fade-in{from{opacity:0}to{opacity:1}}\n@keyframes dab-page-in{from{opacity:0;transform:translateY(12px)}to{opacity:1;transform:none}}\n@keyframes dab-rise-in{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}\n@keyframes dab-list-in{from{opacity:0;transform:translateY(-7px)}to{opacity:1;transform:none}}\n@keyframes dab-row-in{from{opacity:0;transform:translateY(6px) scale(.985)}to{opacity:1;transform:none}}\n@keyframes dab-type-in{from{opacity:0;transform:translateY(8px) scale(.97)}to{opacity:1;transform:none}}\n@keyframes dab-orb-in{from{opacity:0;transform:scale(.82)}to{opacity:1;transform:none}}\n@keyframes dab-spin{to{transform:rotate(360deg)}}\n@keyframes dab-rotate{to{transform:rotate(360deg)}}\n@keyframes dab-toast-in{from{opacity:0;transform:translate(-50%,10px)}to{opacity:1;transform:translate(-50%,0)}}\n@keyframes dab-zoom-in{from{opacity:0;transform:scale(.94) translateY(8px)}to{opacity:1;transform:none}}\n@keyframes dab-flow{to{background-position:300% 50%}}\n\n/* ── sidebar surface (a dsh-better-sidebar page) ─────────────────────────────\n * Same shell, hosted in a panel that is handed a full-height column (the host's\n * native tab body is height:100%) and whose width the user drags freely. So only\n * THREE things are fixed here, all of them structural:\n * 1. the shell fills the height and the page body owns the scroll\n * (flex:1 + min-height:0), so the panel stays one scrollable column instead\n * of pushing the whole tab into a scrollbar;\n * 2. the nav is a rail ABOVE the page rather than beside it — a side rail would\n * spend 150px of a panel that is narrow by nature, and this way the page\n * keeps the full width for its own grids;\n * 3. long tokens (paths, hex, URLs) may wrap instead of widening the panel.\n *\n * Everything else — grid columns, paddings, type scale, whether the cards lift on\n * hover — is width-driven through the container queries below, which measure this\n * shell (the .dab-root container, which declares container-type:inline-size) and\n * not the viewport. A narrow sidebar compacts; a wide one falls back to the\n * dialog's own spacing and multi-column grids, because at that point it *is* a\n * dialog-sized surface. */\n[data-dab-surface=\"sidebar\"].dab-root{height:100%;min-height:0;padding:12px 12px 0}\n[data-dab-surface=\"sidebar\"] .dab-shell{display:flex;flex-direction:column;align-items:stretch;gap:11px;height:100%;min-height:0;max-width:none;padding-bottom:0}\n[data-dab-surface=\"sidebar\"] .dab-nav{gap:0}\n[data-dab-surface=\"sidebar\"] .dab-nav-list{flex-direction:row;gap:2px;overflow-x:auto;overflow-y:hidden;padding-bottom:1px}\n[data-dab-surface=\"sidebar\"] .dab-nav-list::-webkit-scrollbar{display:none}\n[data-dab-surface=\"sidebar\"] .dab-nav-ind{display:none}\n[data-dab-surface=\"sidebar\"] .dab-nav-item{flex:none;height:32px;gap:7px;padding:0 10px;font-size:12px}\n[data-dab-surface=\"sidebar\"] .dab-nav-item.is-active{background:var(--dsw-alias-bg-layer-2)}\n[data-dab-surface=\"sidebar\"] .dab-page{flex:1;min-height:0;overflow-y:auto;overflow-x:hidden;padding-bottom:16px;scrollbar-width:thin}\n/* Last-resort safety for text that cannot wrap (paths, hex, URLs). */\n[data-dab-surface=\"sidebar\"] .dab-hint,[data-dab-surface=\"sidebar\"] .dab-part-name{overflow-wrap:anywhere}\n/* The panel's width is whatever the user dragged it to, so let the part cards\n * fill as many columns as actually fit instead of hard-coding one. 170px is the\n * narrowest a part card stays readable once its header can wrap (see the head\n * rules below), which puts the second column at roughly a 380px panel — the\n * default right-sidebar width. */\n[data-dab-surface=\"sidebar\"] .dab-grid-parts{grid-template-columns:repeat(auto-fill,minmax(min(170px,100%),1fr));gap:12px}\n[data-dab-surface=\"sidebar\"] .dab-types{grid-template-columns:repeat(auto-fit,minmax(min(150px,100%),1fr))}\n[data-dab-surface=\"sidebar\"] .dab-card{padding:12px}\n[data-dab-surface=\"sidebar\"] .dab-part-head{gap:8px;margin-bottom:10px}\n[data-dab-surface=\"sidebar\"] .dab-part-ico{width:26px;height:26px;border-radius:8px}\n[data-dab-surface=\"sidebar\"] .dab-part-name{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:12.5px}\n[data-dab-surface=\"sidebar\"] .dab-part-badge{padding:2px 7px;font-size:10px}\n\n/* Narrow panel: tighten the chrome so the content still has room. */\n@container (max-width:539px){\n [data-dab-surface=\"sidebar\"] .dab-page{gap:11px}\n [data-dab-surface=\"sidebar\"] .dab-h1{font-size:17px}\n [data-dab-surface=\"sidebar\"] .dab-desc{font-size:12px}\n [data-dab-surface=\"sidebar\"] .dab-orb-wrap{width:96px;height:96px}\n [data-dab-surface=\"sidebar\"] .dab-wheel-card{padding:14px 10px;gap:16px}\n [data-dab-surface=\"sidebar\"] .dab-wheel-glow{width:170px;height:170px}\n /* Lift-on-hover is a dialog affordance; in a cramped scrolling panel it only\n * adds jitter under the cursor. */\n [data-dab-surface=\"sidebar\"] .dab-card-hover:hover{transform:none;box-shadow:none}\n}\n/* Roomy panel: behave like the dialog again — its spacing, its type scale, and\n * multi-column grids (a smaller track minimum than the dialog, because the page\n * here is a few hundred px narrower than a dialog's content column). */\n@container (min-width:540px){\n [data-dab-surface=\"sidebar\"] .dab-shell{gap:16px}\n [data-dab-surface=\"sidebar\"] .dab-page{gap:13px}\n [data-dab-surface=\"sidebar\"] .dab-nav-item{height:34px;font-size:12.5px;padding:0 12px}\n /* The shared ≤620px rule flattens the type cards to one column, which is right\n * for a narrow phone-width dialog but wasteful in a roomy panel. */\n [data-dab-surface=\"sidebar\"] .dab-types{grid-template-columns:repeat(auto-fit,minmax(180px,1fr))}\n}\n\n/* ── responsive & motion preferences ─────────────────────────────────────── */\n@container (max-width:620px){\n .dab-shell{grid-template-columns:1fr;gap:14px}\n .dab-nav{position:static;flex-direction:row;align-items:center;justify-content:space-between;gap:10px}\n .dab-nav-list{flex-direction:row;overflow-x:auto;scrollbar-width:none}\n .dab-nav-list::-webkit-scrollbar{display:none}\n .dab-nav-ind{display:none}\n .dab-nav-item{flex:none;padding:0 10px}\n .dab-nav-item.is-active{background:var(--dsw-alias-bg-layer-2)}\n .dab-types{grid-template-columns:1fr}\n}\n@container (min-width:621px){\n .dab-shell{grid-template-columns:158px minmax(0,1fr);gap:26px}\n}\n/* Phone: on a handset the settings dialog's content column shrinks to roughly\n * the viewport, and the dialog-sized chrome (18px cards, 21px headings, a 118px\n * orb, 24px paddings) stops fitting — cards end up wider than the column or the\n * color row wraps into three cramped pieces. These are the same tightenings the\n * sidebar surface applies at its own narrow widths, so a phone settings dialog\n * and a narrow sidebar panel end up looking the same. */\n@container (max-width:480px){\n .dab-shell{gap:10px}\n .dab-page{gap:10px}\n .dab-head{margin:0 0 2px}\n .dab-h1{font-size:18px}\n .dab-desc{font-size:12px}\n .dab-card{padding:14px;border-radius:14px}\n .dab-hero-accent{gap:16px}\n .dab-orb-wrap{width:92px;height:92px}\n .dab-wheel-card{padding:14px 10px;gap:16px}\n .dab-wheel-glow{width:180px;height:180px}\n /* Three fixed type-card columns need ~400px; two adaptive ones fit 320px. */\n .dab-types{grid-template-columns:repeat(auto-fit,minmax(min(150px,100%),1fr))}\n .dab-grid-parts{gap:11px}\n .dab-part-head{margin-bottom:10px}\n .dab-slider-block + .dab-slider-block{margin-top:10px}\n .dab-footer{padding-top:10px}\n}\n@media (prefers-reduced-motion:reduce){\n .dab-root *,.dab-root *::before,.dab-root *::after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}\n}\n`\n\nconst CSS_ID = 'dab-ui-css'\n\n/** Inject the design-system stylesheet once per document (HMR-safe). */\nexport function ensureUiCss(): void {\n if (typeof document === 'undefined') return\n let el = document.getElementById(CSS_ID) as HTMLStyleElement | null\n if (!el) {\n el = document.createElement('style')\n el.id = CSS_ID\n // Self-claim it. Through `0.2.0-rc.2` the host's module system stamped\n // `data-plugin` on EVERY untagged `<style>` that existed when a plugin factory\n // materialized, so an untagged sheet injected later (this one is injected by the\n // settings page, not by the module factory) was handed to whichever plugin ran\n // next and deleted when that plugin errored or was disposed. `0.2.1-alpha.1`\n // narrowed the claim to tags the factory itself added; the attribute makes the\n // sheet safe on both.\n el.dataset.plugin = 'dsh-any-background-ui-css'\n document.head.appendChild(el)\n }\n if (el.textContent !== UI_CSS) el.textContent = UI_CSS\n}\n","import type { ReactNode } from 'react'\r\n\r\n/** Sun glyph, migrated from @deepseek-ai/dsh-client-ui-primitives IconLightOutline16. */\r\nexport const SUN_PATHS = '<path d=\"M11.3496 8C11.3496 6.14985 9.85015 4.65039 8 4.65039C6.14985 4.65039 4.65039 6.14985 4.65039 8C4.65039 9.85015 6.14985 11.3496 8 11.3496C9.85015 11.3496 11.3496 9.85015 11.3496 8ZM12.6504 8C12.6504 10.5681 10.5681 12.6504 8 12.6504C5.43188 12.6504 3.34961 10.5681 3.34961 8C3.34961 5.43188 5.43188 3.34961 8 3.34961C10.5681 3.34961 12.6504 5.43188 12.6504 8Z\" fill=\"currentColor\"/><path d=\"M8.65039 0.5V2.5H7.34961V0.5H8.65039Z\" fill=\"currentColor\"/><path d=\"M8.65039 13.5V15.5H7.34961V13.5H8.65039Z\" fill=\"currentColor\"/><path d=\"M3.15808 2.24035L4.57229 3.65456L3.6525 4.57435L2.23829 3.16014L3.15808 2.24035Z\" fill=\"currentColor\"/><path d=\"M12.3505 11.4327L13.7647 12.8469L12.8449 13.7667L11.4307 12.3525L12.3505 11.4327Z\" fill=\"currentColor\"/><path d=\"M2.24537 12.8469L3.65958 11.4327L4.57937 12.3525L3.16516 13.7667L2.24537 12.8469Z\" fill=\"currentColor\"/><path d=\"M11.4377 3.65455L12.852 2.24033L13.7718 3.16012L12.3575 4.57434L11.4377 3.65455Z\" fill=\"currentColor\"/><path d=\"M0.5 7.35461H2.5V8.6554H0.5L0.5 7.35461Z\" fill=\"currentColor\"/><path d=\"M13.5 7.35461H15.5V8.6554H13.5V8.6554Z\" fill=\"currentColor\"/>'\r\n\r\nexport function SunIcon({ size = 16, className }: { size?: number; className?: string }) {\r\n return (\r\n <svg width={size} height={size} className={className} viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" dangerouslySetInnerHTML={{ __html: SUN_PATHS }} />\r\n )\r\n}\r\n\r\nfunction Glyph({ children, size = 16, className }: { children: ReactNode; size?: number; className?: string }) {\r\n return (\r\n <svg width={size} height={size} className={className} viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\" strokeWidth={1.5} strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\">\r\n {children}\r\n </svg>\r\n )\r\n}\r\n\r\nexport const DropletIcon = ({ size, className }: { size?: number; className?: string }) => (\r\n <Glyph size={size} className={className}><path d=\"M8 1.9c2.4 2.8 4.3 5 4.3 7.1a4.3 4.3 0 1 1-8.6 0C3.7 6.9 5.6 4.7 8 1.9z\" /></Glyph>\r\n)\r\n\r\nexport const LayersIcon = ({ size, className }: { size?: number; className?: string }) => (\r\n <Glyph size={size} className={className}><path d=\"M8 2.2 13.2 5 8 7.8 2.8 5 8 2.2z\" /><path d=\"M2.8 8.2 8 11l5.2-2.8\" /><path d=\"M2.8 11.2 8 14l5.2-2.8\" /></Glyph>\r\n)\r\n\r\nexport const PhotoIcon = ({ size, className }: { size?: number; className?: string }) => (\r\n <Glyph size={size} className={className}><rect x=\"2\" y=\"3.2\" width=\"12\" height=\"9.6\" rx=\"2\" /><circle cx=\"5.7\" cy=\"6.3\" r=\"0.9\" /><path d=\"M14 10.4l-2.8-2.8-4.8 4.8\" /></Glyph>\r\n)\r\n\r\nexport const VideoIcon = ({ size, className }: { size?: number; className?: string }) => (\r\n <Glyph size={size} className={className}><rect x=\"1.5\" y=\"4.2\" width=\"8.8\" height=\"7.6\" rx=\"2\" /><path d=\"M10.3 6.9l4.2-2.4v7l-4.2-2.4\" /></Glyph>\r\n)\r\n\r\nexport const TextIcon = ({ size, className }: { size?: number; className?: string }) => (\r\n <Glyph size={size} className={className}><path d=\"M3 4.2h10M3 8h10M3 11.8h6.5\" /></Glyph>\r\n)\r\n\r\nexport const TrajectoryIcon = ({ size, className }: { size?: number; className?: string }) => (\r\n <Glyph size={size} className={className}><path d=\"M2.5 3.2h11M2.5 6.6h11M2.5 10h11\" /><circle cx=\"4.4\" cy=\"3.2\" r=\"1.1\" /><circle cx=\"8\" cy=\"6.6\" r=\"1.1\" /><circle cx=\"11.4\" cy=\"10\" r=\"1.1\" /></Glyph>\r\n)\r\n\r\n/** Bottom workbench panel (dsh-better-sidebar): a window with a docked strip. */\r\nexport const PanelIcon = ({ size, className }: { size?: number; className?: string }) => (\r\n <Glyph size={size} className={className}><path d=\"M2.4 2.7h11.2v10.6H2.4z\" /><path d=\"M2.4 10.1h11.2\" /></Glyph>\r\n)\r\n\r\nexport const SlidersIcon = ({ size, className }: { size?: number; className?: string }) => (\r\n <Glyph size={size} className={className}><path d=\"M2.5 4.5h4.9M11.6 4.5h1.9M2.5 11.5h1.9M8.6 11.5h4.9\" /><circle cx=\"9.5\" cy=\"4.5\" r=\"1.7\" /><circle cx=\"5.5\" cy=\"11.5\" r=\"1.7\" /></Glyph>\r\n)\r\n\r\nexport const SparkleIcon = ({ size, className }: { size?: number; className?: string }) => (\r\n <Glyph size={size} className={className}><path d=\"M7.2 1.8l1.2 3.1 3.1 1.2-3.1 1.2-1.2 3.1-1.2-3.1L2.9 6.1 6 4.9l1.2-3.1z\" /><path d=\"M12 10.5l.5 1.2 1.2.5-1.2.5-.5 1.2-.5-1.2-1.2-.5 1.2-.5.5-1.2z\" /></Glyph>\r\n)\r\n\r\nexport const RefreshIcon = ({ size, className }: { size?: number; className?: string }) => (\r\n <Glyph size={size} className={className}><path d=\"M13.2 8A5.2 5.2 0 1 1 11.5 4.2\" /><path d=\"M13.4 1.8v2.9h-2.9\" /></Glyph>\r\n)\r\n\r\nexport const DownloadIcon = ({ size, className }: { size?: number; className?: string }) => (\r\n <Glyph size={size} className={className}><path d=\"M8 2.2v8\" /><path d=\"M4.6 7l3.4 3.4L11.4 7\" /><path d=\"M2.8 13.8h10.4\" /></Glyph>\r\n)\r\n\r\nexport const UploadIcon = ({ size, className }: { size?: number; className?: string }) => (\r\n <Glyph size={size} className={className}><path d=\"M8 10.4V2.6\" /><path d=\"M4.6 5.8L8 2.4l3.4 3.4\" /><path d=\"M2.8 13.8h10.4\" /></Glyph>\r\n)\r\n\r\nexport const LinkIcon = ({ size, className }: { size?: number; className?: string }) => (\r\n <Glyph size={size} className={className}><path d=\"M6.6 9.4 9.4 6.6\" /><path d=\"M5.9 11.1l-1.4 1.4a2.6 2.6 0 0 1-3.7-3.7L3.5 6.8\" /><path d=\"M10.1 4.9l1.4-1.4a2.6 2.6 0 0 1 3.7 3.7l-2.1 2.1\" /></Glyph>\r\n)\r\n\r\nexport const LockIcon = ({ size, className }: { size?: number; className?: string }) => (\r\n <Glyph size={size} className={className}><rect x=\"3.6\" y=\"7.2\" width=\"8.8\" height=\"6\" rx=\"1.4\" /><path d=\"M5.6 7.2V5.4a2.4 2.4 0 0 1 4.8 0v1.8\" /></Glyph>\r\n)\r\n\r\nexport const TrashIcon = ({ size, className }: { size?: number; className?: string }) => (\r\n <Glyph size={size} className={className}><path d=\"M2.8 4.4h10.4\" /><path d=\"M6.4 4.4V2.9h3.2v1.5\" /><path d=\"M4.4 4.4l.5 8.6h6.2l.5-8.6\" /></Glyph>\r\n)\r\n\r\nexport const EditIcon = ({ size, className }: { size?: number; className?: string }) => (\r\n <Glyph size={size} className={className}><path d=\"M9.5 4l2.5 2.5\" /><path d=\"M3 13l.8-3L10 3.8 12.2 6 6 12.2 3 13z\" /></Glyph>\r\n)\r\n\r\nexport const PipetteIcon = ({ size, className }: { size?: number; className?: string }) => (\r\n <Glyph size={size} className={className}><circle cx=\"8\" cy=\"8\" r=\"4.2\" /><path d=\"M8 1.6v2.6M8 11.8v2.6M1.6 8h2.6M11.8 8h2.6\" /></Glyph>\r\n)\r\n\r\nexport const CheckIcon = ({ size, className }: { size?: number; className?: string }) => (\r\n <Glyph size={size} className={className}><path d=\"M3.2 8.6l3 3L12.8 5\" /></Glyph>\r\n)\r\n\r\nexport const AlertIcon = ({ size, className }: { size?: number; className?: string }) => (\r\n <Glyph size={size} className={className}><path d=\"M8 2.6l5.4 9.8H2.6L8 2.6z\" /><path d=\"M8 6.8v2.4M8 11.4v.01\" /></Glyph>\r\n)\r\n\r\nexport const CanvasIcon = ({ size, className }: { size?: number; className?: string }) => (\r\n <Glyph size={size} className={className}><rect x=\"2.2\" y=\"2.2\" width=\"11.6\" height=\"11.6\" rx=\"2\" /></Glyph>\r\n)\r\n\r\nexport const SidebarIcon = ({ size, className }: { size?: number; className?: string }) => (\r\n <Glyph size={size} className={className}><rect x=\"2.2\" y=\"2.2\" width=\"11.6\" height=\"11.6\" rx=\"2\" /><path d=\"M6.6 2.2v11.6\" /></Glyph>\r\n)\r\n\r\nexport const ChatIcon = ({ size, className }: { size?: number; className?: string }) => (\r\n <Glyph size={size} className={className}><path d=\"M13.4 4.4v4.4a2 2 0 0 1-2 2H6.2l-3.6 3V4.4a2 2 0 0 1 2-2h6.8a2 2 0 0 1 2 2z\" /></Glyph>\r\n)\r\n\r\nexport const GearIcon = ({ size, className }: { size?: number; className?: string }) => (\r\n <Glyph size={size} className={className}><circle cx=\"8\" cy=\"8\" r=\"2.1\" /><path d=\"M8 1.7v1.8M8 12.5v1.8M1.7 8h1.8M12.5 8h1.8M3.6 3.6l1.3 1.3M11.1 11.1l1.3 1.3M12.4 3.6l-1.3 1.3M4.9 11.1l-1.3 1.3\" /></Glyph>\r\n)\r\n\r\nexport const InputIcon = ({ size, className }: { size?: number; className?: string }) => (\r\n <Glyph size={size} className={className}><rect x=\"2.2\" y=\"4\" width=\"11.6\" height=\"8\" rx=\"2\" /><path d=\"M8 6.6v2M7 8h2\" /></Glyph>\r\n)\r\n\r\n/** Session header bar: a window with its title band above the content. */\r\nexport const HeaderBarIcon = ({ size, className }: { size?: number; className?: string }) => (\r\n <Glyph size={size} className={className}><rect x=\"2.2\" y=\"2.2\" width=\"11.6\" height=\"11.6\" rx=\"2\" /><path d=\"M2.2 5.6h11.6\" /></Glyph>\r\n)\r\n\r\nexport const PlusIcon = ({ size, className }: { size?: number; className?: string }) => (\r\n <Glyph size={size} className={className}><path d=\"M8 3v10M3 8h10\" /></Glyph>\r\n)\r\n\r\nexport const MoonIcon = ({ size, className }: { size?: number; className?: string }) => (\r\n <Glyph size={size} className={className}><path d=\"M13.2 9.6A5.6 5.6 0 0 1 6.4 2.8a5.6 5.6 0 1 0 6.8 6.8z\" /></Glyph>\r\n)\r\n\r\nexport const ClockIcon = ({ size, className }: { size?: number; className?: string }) => (\r\n <Glyph size={size} className={className}><circle cx=\"8\" cy=\"8\" r=\"5.8\" /><path d=\"M8 4.8V8l2.2 1.6\" /></Glyph>\r\n)\r\n\r\nexport const XIcon = ({ size, className }: { size?: number; className?: string }) => (\r\n <Glyph size={size} className={className}><path d=\"M4 4l8 8M12 4l-8 8\" /></Glyph>\r\n)\r\n\r\n/** Letterform glyph: a stroked capital A (the font/type page + nav entry). */\r\nexport const FontIcon = ({ size, className }: { size?: number; className?: string }) => (\r\n <Glyph size={size} className={className}><path d=\"M4 12.2 8 3.8l4 8.4\" /><path d=\"M5.6 9.6h4.8\" /></Glyph>\r\n)\r\n\r\nexport const PlayIcon = ({ size, className }: { size?: number; className?: string }) => (\r\n <Glyph size={size} className={className}><path d=\"M5.2 3.4l7.4 4.6-7.4 4.6V3.4z\" /></Glyph>\r\n)\r\n\r\nexport const PauseIcon = ({ size, className }: { size?: number; className?: string }) => (\r\n <Glyph size={size} className={className}><path d=\"M5.4 3.4v9.2M10.6 3.4v9.2\" /></Glyph>\r\n)\r\n\r\n","import { Component, type ReactNode } from 'react'\n\ninterface Props {\n t: (key: string) => string\n onReset?: () => void\n children: ReactNode\n}\n\ninterface State {\n error: Error | null\n}\n\n/**\n * Catches render errors from the theme section subtree (wheel, sliders, editor)\n * so a single bad state can never take down the whole settings panel. Shows a\n * compact fallback with a reset button; the reset re-renders the section with\n * the current saved config, which is enough to recover from most transient\n * failures (corrupt transient UI state, stale image decode, etc.).\n */\nexport class ErrorBoundary extends Component<Props, State> {\n override state: State = { error: null }\n\n static getDerivedStateFromError(error: Error): State {\n return { error }\n }\n\n override componentDidCatch(error: Error, info: { componentStack?: string | null }): void {\n console.error('dsh-any-background: section render crashed', error, info.componentStack)\n }\n\n private reset = (): void => {\n this.setState({ error: null })\n this.props.onReset?.()\n }\n\n override render() {\n if (this.state.error) {\n // Show the cause, not just the apology. The host's own console holds the\n // full stack, but a plugin that repaints the settings panel has no other\n // way to tell the user why it went blank — and \"please open devtools\" is a\n // poor answer to \"it crashed\".\n const detail = this.state.error.stack ?? `${this.state.error.name}: ${this.state.error.message}`\n return (\n <div className=\"dab-crash\">\n <div className=\"dab-crash-title\">{this.props.t('crashTitle')}</div>\n <div className=\"dab-crash-desc\">{this.props.t('crashDesc')}</div>\n <pre className=\"dab-crash-detail\">{detail}</pre>\n <button type=\"button\" className=\"dab-btn\" onClick={this.reset}>{this.props.t('crashReset')}</button>\n </div>\n )\n }\n return this.props.children\n }\n}\n","import { useEffect, useState } from 'react'\nimport type { ReactNode } from 'react'\nimport { createPortal } from 'react-dom'\n\n/**\n * Render children into a fixed root attached to document.documentElement.\n *\n * The host's sidebar is often implemented by translating the body or a wrapper\n * (margin-left / transform). A fixed element portaled to body would still be\n * captured by that transformed ancestor and shift with the sidebar. Attaching\n * the portal root directly to <html> escapes body-level transforms so the\n * overlay is always painted relative to the viewport and centered correctly.\n */\nexport function Portal({ children }: { children: ReactNode }) {\n const [target, setTarget] = useState<HTMLElement | null>(null)\n useEffect(() => {\n const el = document.createElement('div')\n el.dataset.dabPortal = '1'\n el.style.cssText = 'position:fixed;inset:0;pointer-events:none;z-index:999999'\n document.documentElement.appendChild(el)\n setTarget(el)\n return () => { el.remove() }\n }, [])\n return target ? createPortal(children, target) : null\n}\n","import { useRef, useState, useEffect, useCallback, memo } from 'react'\n\nconst WHEEL_SIZE = 220\nconst CX = WHEEL_SIZE / 2\nconst RING_OUTER = 106\nconst RING_INNER = 82\n// Square inscribed in the ring's inner circle: half-side = RING_INNER / √2,\n// so the four corners sit exactly on the inner edge of the hue ring. The\n// exact (un-rounded) value keeps the corners tangent to the ring — a rounded\n// half-side would push the diagonals past the ring's inner boundary.\nconst SQ_HALF = RING_INNER / Math.SQRT2\n\n/** Static hue ring cached once across all wheels. */\nlet ringCache: HTMLCanvasElement | null = null\nfunction getRingCache(): HTMLCanvasElement {\n if (ringCache) return ringCache\n const cvs = document.createElement('canvas')\n cvs.width = WHEEL_SIZE; cvs.height = WHEEL_SIZE\n const c = cvs.getContext('2d')!\n // Instead of 360 separate arc paths, use a single conic gradient clipped to\n // the ring. This removes per-frame path overhead and anti-aliasing gaps.\n const g = c.createConicGradient(0, CX, CX)\n for (let i = 0; i <= 360; i++) g.addColorStop(i / 360, `hsl(${i},100%,50%)`)\n c.beginPath()\n c.arc(CX, CX, RING_OUTER, 0, Math.PI * 2)\n c.arc(CX, CX, RING_INNER, 0, Math.PI * 2, true)\n c.fillStyle = g\n c.fill()\n ringCache = cvs\n return ringCache\n}\n\nfunction drawMarkers(ctx: CanvasRenderingContext2D, hue: number, sat: number, lit: number): void {\n // Hue marker on ring. Canvas math angles (0 = +x / \"3 o'clock\", positive =\n // toward +y) directly match the conic-gradient hue distribution drawn in\n // getRingCache (colorStop i/360 → hsl(i)), so NO extra ±90° shift is applied.\n // A shift would rotate the picker's indication 90° away from the rendered\n // gradient (e.g. picking the top of the wheel would report red while the\n // pixels there are blue). hue 0 sits at the right edge, +90° at the bottom.\n const hRad = hue * Math.PI / 180\n const hR = (RING_OUTER + RING_INNER) / 2\n const hmx = CX + Math.cos(hRad) * hR\n const hmy = CX + Math.sin(hRad) * hR\n ctx.beginPath(); ctx.arc(hmx, hmy, 8, 0, Math.PI * 2)\n ctx.fillStyle = 'rgba(0,0,0,0.25)'; ctx.fill()\n ctx.beginPath(); ctx.arc(hmx, hmy, 6.5, 0, Math.PI * 2)\n ctx.strokeStyle = '#fff'; ctx.lineWidth = 2; ctx.stroke()\n\n // SL marker (HSV coordinates)\n const gx = CX - SQ_HALF, gy = CX - SQ_HALF, sz = SQ_HALF * 2\n const smx = gx + sat * sz\n const smy = gy + (1 - lit) * sz\n ctx.beginPath(); ctx.arc(smx, smy, 7, 0, Math.PI * 2)\n ctx.fillStyle = 'rgba(0,0,0,0.25)'; ctx.fill()\n ctx.beginPath(); ctx.arc(smx, smy, 5.5, 0, Math.PI * 2)\n ctx.strokeStyle = '#fff'; ctx.lineWidth = 2; ctx.stroke()\n ctx.beginPath(); ctx.arc(smx, smy, 3.5, 0, Math.PI * 2)\n ctx.strokeStyle = '#000'; ctx.lineWidth = 1; ctx.stroke()\n}\n\nfunction drawSquare(c: CanvasRenderingContext2D, hue: number): void {\n const gx = CX - SQ_HALF, gy = CX - SQ_HALF, sz = SQ_HALF * 2\n c.clearRect(gx - 1, gy - 1, sz + 2, sz + 2)\n c.fillStyle = '#fff'; c.fillRect(gx, gy, sz, sz)\n const gh = c.createLinearGradient(gx, 0, gx + sz, 0)\n gh.addColorStop(0, 'rgba(255,255,255,1)'); gh.addColorStop(1, `hsl(${hue},100%,50%)`)\n c.fillStyle = gh; c.fillRect(gx, gy, sz, sz)\n const gv = c.createLinearGradient(0, gy, 0, gy + sz)\n gv.addColorStop(0, 'rgba(0,0,0,0)'); gv.addColorStop(1, 'rgba(0,0,0,1)')\n c.fillStyle = gv; c.fillRect(gx, gy, sz, sz)\n}\n\nfunction hitTest(x: number, y: number): 'ring' | 'square' | null {\n if (Math.abs(x - CX) <= SQ_HALF && Math.abs(y - CX) <= SQ_HALF) return 'square'\n const dx = x - CX, dy = y - CX\n const dist = Math.sqrt(dx * dx + dy * dy)\n if (dist >= RING_INNER - 4 && dist <= RING_OUTER + 4) return 'ring'\n return null\n}\n\nfunction pickHue(x: number, y: number): number {\n // Inverse of drawMarkers: no ±90° shift, matching the conic gradient exactly.\n let angle = Math.atan2(y - CX, x - CX) * 180 / Math.PI\n if (angle < 0) angle += 360\n return angle\n}\n\nfunction pickSL(x: number, y: number): [number, number] {\n const gx = CX - SQ_HALF, gy = CX - SQ_HALF, sz = SQ_HALF * 2\n return [\n Math.max(0, Math.min(1, (x - gx) / sz)),\n Math.max(0.02, Math.min(0.98, 1 - (y - gy) / sz)),\n ]\n}\n\nexport const ColorWheel = memo(function ColorWheel({ hue, sat, lit, onChange }: {\n hue: number; sat: number; lit: number\n onChange: (h: number, s: number, l: number) => void\n}) {\n const cvsRef = useRef<HTMLCanvasElement>(null)\n const [col, setCol] = useState({ hue, sat, lit })\n const colRef = useRef(col)\n colRef.current = col\n\n // Adopt external changes (e.g. section remount after theme restore).\n useEffect(() => {\n setCol(c => (c.hue === hue && c.sat === sat && c.lit === lit ? c : { hue, sat, lit }))\n }, [hue, sat, lit])\n\n // Redraw only what changed. The static ring is copied from cache; the square\n // only redraws when hue changes; markers redraw on every value change.\n useEffect(() => {\n const cvs = cvsRef.current\n if (!cvs) return\n const ctx = cvs.getContext('2d')!\n ctx.clearRect(0, 0, WHEEL_SIZE, WHEEL_SIZE)\n // Draw the square first, then the ring on top: the ring's opaque pixels\n // cover the square's four corners (which are tangent to the ring's inner\n // edge), so the corners no longer visually overlap the hue ring.\n drawSquare(ctx, col.hue)\n ctx.drawImage(getRingCache(), 0, 0)\n drawMarkers(ctx, col.hue, col.sat, col.lit)\n }, [col])\n\n // Batch pointer updates in a single rAF so rapid mousemove events do not\n // trigger a React state flush + onChange on every pixel.\n const pendingRef = useRef<{ h: number; s: number; l: number } | null>(null)\n const rafRef = useRef<number | null>(null)\n /** Unmount-time cleanup for a drag that never saw its mouseup (panel closed\n * mid-drag): without it the document listeners stay attached forever and the\n * pending rAF keeps calling setState on a dead component. */\n const dragCleanupRef = useRef<(() => void) | null>(null)\n const flushPending = useCallback(() => {\n rafRef.current = null\n const p = pendingRef.current\n if (!p) return\n pendingRef.current = null\n setCol({ hue: p.h, sat: p.s, lit: p.l })\n onChange(p.h, p.s, p.l)\n }, [onChange])\n\n const schedule = useCallback((h: number, s: number, l: number) => {\n pendingRef.current = { h, s, l }\n if (rafRef.current === null) rafRef.current = requestAnimationFrame(flushPending)\n }, [flushPending])\n\n const onDown = useCallback((e: React.MouseEvent<HTMLCanvasElement>) => {\n const r = cvsRef.current!.getBoundingClientRect()\n const x = e.clientX - r.left, y = e.clientY - r.top\n const region = hitTest(x, y)\n if (!region) return\n if (region === 'ring') {\n schedule(pickHue(x, y), colRef.current.sat, colRef.current.lit)\n } else {\n const [s, l] = pickSL(x, y)\n schedule(colRef.current.hue, s, l)\n }\n const onMove = (ev: MouseEvent) => {\n const rr = cvsRef.current!.getBoundingClientRect()\n const mx = ev.clientX - rr.left, my = ev.clientY - rr.top\n if (region === 'ring') {\n const d = Math.sqrt((mx - CX) ** 2 + (my - CX) ** 2)\n if (d >= RING_INNER - 10 && d <= RING_OUTER + 10) schedule(pickHue(mx, my), colRef.current.sat, colRef.current.lit)\n } else {\n const [s, l] = pickSL(mx, my)\n schedule(colRef.current.hue, s, l)\n }\n }\n const stopDrag = () => {\n document.removeEventListener('mousemove', onMove)\n document.removeEventListener('mouseup', stopDrag)\n dragCleanupRef.current = null\n }\n dragCleanupRef.current = stopDrag\n document.addEventListener('mousemove', onMove); document.addEventListener('mouseup', stopDrag)\n }, [schedule])\n\n // Cancel the pending rAF and any live drag listeners on unmount (see\n // dragCleanupRef above): a drag ended by closing the panel never fires mouseup.\n useEffect(() => {\n return () => {\n if (rafRef.current !== null) { cancelAnimationFrame(rafRef.current); rafRef.current = null }\n pendingRef.current = null\n dragCleanupRef.current?.()\n }\n }, [])\n\n return <canvas ref={cvsRef} width={WHEEL_SIZE} height={WHEEL_SIZE} className=\"dab-wheel\" onMouseDown={onDown} />\n})\n","import { useState, useEffect, useRef } from 'react'\nimport type { CSSProperties } from 'react'\nimport { hsvToHsl, hslToRgb, rgbToHsl, hslToHsv } from '../utils/color'\n\ntype Mode = 'hsl' | 'rgb'\n\nconst SEG_W = 66\n\nfunction clamp(v: number, min: number, max: number): number {\n return Math.min(max, Math.max(min, v))\n}\n\n/**\n * A single numeric field that edits one color channel. Keeps its own text\n * while focused so typing never gets clobbered by the parent re-rendering the\n * canonical value; commits every valid keystroke live and re-normalizes on\n * blur. The value prop only pushes back in when the field is not focused\n * (wheel drags, wallpaper extraction, mode switches).\n */\nfunction NumField({ label, value, min, max, step, onChange }: {\n label: string; value: number; min: number; max: number; step: number\n onChange: (v: number) => void\n}) {\n const [text, setText] = useState(String(value))\n const focused = useRef(false)\n\n useEffect(() => {\n if (!focused.current) setText(String(value))\n }, [value])\n\n return (\n <label className=\"dab-field\">\n <span className=\"dab-field-label\">{label}</span>\n <input\n type=\"number\"\n min={min} max={max} step={step}\n value={text}\n className=\"dab-num\"\n onFocus={() => { focused.current = true }}\n onBlur={() => { focused.current = false; setText(String(value)) }}\n onChange={e => {\n setText(e.target.value)\n // An emptied field is Number('') === 0 — a finite value — so without\n // this guard clearing the box for a moment would commit the channel\n // to its minimum and yank the color under the user's fingers.\n if (e.target.value === '') return\n const v = Number(e.target.value)\n if (Number.isFinite(v)) onChange(clamp(v, min, max))\n }}\n />\n </label>\n )\n}\n\n/**\n * Precise color entry next to the wheel: a HSL/RGB segmented toggle plus three\n * numeric channel fields and a live swatch. The wheel is HSV end-to-end, so\n * this panel converts at the boundary — HSL fields map straight onto the\n * stored HSL, RGB fields round-trip through rgbToHsl — and both emit HSV via\n * the same onChange the wheel uses, keeping one canonical color.\n */\nexport function ColorInputs({ hue, sat, lit, onChange }: {\n hue: number; sat: number; lit: number\n onChange: (h: number, s: number, l: number) => void\n}) {\n const [mode, setMode] = useState<Mode>('hsl')\n const [h, s, l] = hsvToHsl(hue, sat, lit)\n const [r, g, b] = hslToRgb(h, s, l)\n\n const setHsl = (nh: number, ns: number, nl: number) => onChange(...hslToHsv(nh, ns, nl))\n const setRgb = (nr: number, ng: number, nb: number) => {\n const [nh, ns, nl] = rgbToHsl(nr, ng, nb)\n onChange(...hslToHsv(nh, ns, nl))\n }\n\n return (\n <div className=\"dab-inputs\">\n <div className=\"dab-seg\" style={{ '--w': `${SEG_W}px` } as CSSProperties}>\n <div className=\"dab-seg-thumb\" style={{ transform: `translateX(${mode === 'hsl' ? 0 : SEG_W}px)` }} />\n <button type=\"button\" className={`dab-seg-item${mode === 'hsl' ? ' is-active' : ''}`} onClick={() => setMode('hsl')}>HSL</button>\n <button type=\"button\" className={`dab-seg-item${mode === 'rgb' ? ' is-active' : ''}`} onClick={() => setMode('rgb')}>RGB</button>\n </div>\n <div style={{ display: 'flex', flexDirection: 'column', gap: 7 }}>\n {mode === 'hsl' ? (\n <>\n <NumField label=\"H\" value={Math.round(h)} min={0} max={360} step={1} onChange={v => setHsl(v, s, l)} />\n <NumField label=\"S\" value={Math.round(s * 100)} min={0} max={100} step={1} onChange={v => setHsl(h, v / 100, l)} />\n <NumField label=\"L\" value={Math.round(l * 100)} min={0} max={100} step={1} onChange={v => setHsl(h, s, v / 100)} />\n </>\n ) : (\n <>\n <NumField label=\"R\" value={r} min={0} max={255} step={1} onChange={v => setRgb(v, g, b)} />\n <NumField label=\"G\" value={g} min={0} max={255} step={1} onChange={v => setRgb(r, v, b)} />\n <NumField label=\"B\" value={b} min={0} max={255} step={1} onChange={v => setRgb(r, g, v)} />\n </>\n )}\n </div>\n <div className=\"dab-swatch-lg\" style={{ background: `hsl(${Math.round(h)} ${Math.round(s * 100)}% ${Math.round(l * 100)}%)` }} />\n </div>\n )\n}\n","import { useRef, useState, useEffect, useCallback } from 'react'\nimport { rgbToHsl, hslToHsv, rgbToHex } from '../utils/color'\nimport { Portal } from './Portal'\n\nconst MAG_SIZE = 96\nconst MAG_ZOOM = 8\n\n/**\n * Eyedropper modal: shows the wallpaper full-bleed (no drag/zoom) and lets the\n * user click any pixel to adopt it as the theme color. A magnifier circle\n * follows the cursor so small details can be picked precisely. The wallpaper\n * is a data URL, so sampling is CORS-free: draw it once to an offscreen-sized\n * canvas and read pixels via getImageData.\n */\nexport function ColorPicker({ url, t, onPick, onClose }: {\n url: string\n t: (key: string) => string\n onPick: (hsv: [number, number, number]) => void\n onClose: () => void\n}) {\n const canvasRef = useRef<HTMLCanvasElement>(null)\n const magRef = useRef<HTMLCanvasElement>(null)\n const imgRef = useRef<HTMLImageElement | null>(null)\n const [ready, setReady] = useState(false)\n const [hover, setHover] = useState<{ rgb: [number, number, number] } | null>(null)\n const [mag, setMag] = useState<{ x: number; y: number } | null>(null)\n\n useEffect(() => {\n const img = new Image()\n img.onload = () => { imgRef.current = img; setReady(true) }\n img.src = url\n }, [url])\n\n useEffect(() => {\n if (!ready || !canvasRef.current || !imgRef.current) return\n const canvas = canvasRef.current\n canvas.width = imgRef.current.naturalWidth\n canvas.height = imgRef.current.naturalHeight\n const ctx = canvas.getContext('2d')\n if (ctx) ctx.drawImage(imgRef.current, 0, 0)\n // Deps include url (not just ready): an upload completes by rewriting the\n // store URL while `ready` stays true, and without this dependency the\n // canvas keeps the old pixels while sampleAt maps coordinates onto them.\n }, [ready, url])\n\n const sampleAt = useCallback((clientX: number, clientY: number) => {\n const canvas = canvasRef.current\n if (!canvas) return null\n const rect = canvas.getBoundingClientRect()\n if (rect.width === 0 || rect.height === 0) return null\n const ctx = canvas.getContext('2d')\n if (!ctx) return null\n const sx = Math.round((clientX - rect.left) * (canvas.width / rect.width))\n const sy = Math.round((clientY - rect.top) * (canvas.height / rect.height))\n if (sx < 0 || sy < 0 || sx >= canvas.width || sy >= canvas.height) return null\n const d = ctx.getImageData(sx, sy, 1, 1).data\n return { sx, sy, rgb: [d[0], d[1], d[2]] as [number, number, number] }\n }, [])\n\n const drawMagnifier = useCallback((sx: number, sy: number) => {\n const mag = magRef.current\n const src = canvasRef.current\n if (!mag || !src) return\n const ctx = mag.getContext('2d')\n if (!ctx) return\n const half = MAG_SIZE / MAG_ZOOM / 2\n ctx.clearRect(0, 0, MAG_SIZE, MAG_SIZE)\n ctx.drawImage(src, sx - half, sy - half, half * 2, half * 2, 0, 0, MAG_SIZE, MAG_SIZE)\n ctx.strokeStyle = 'rgba(255,255,255,0.85)'\n ctx.lineWidth = 1\n ctx.beginPath()\n ctx.moveTo(MAG_SIZE / 2, 0); ctx.lineTo(MAG_SIZE / 2, MAG_SIZE)\n ctx.moveTo(0, MAG_SIZE / 2); ctx.lineTo(MAG_SIZE, MAG_SIZE / 2)\n ctx.stroke()\n }, [])\n\n const onMove = (e: React.MouseEvent) => {\n const s = sampleAt(e.clientX, e.clientY)\n if (!s) { setHover(null); setMag(null); return }\n setHover({ rgb: s.rgb })\n drawMagnifier(s.sx, s.sy)\n const off = 28\n let x = e.clientX + off\n let y = e.clientY + off\n if (x + MAG_SIZE > window.innerWidth) x = e.clientX - off - MAG_SIZE\n if (y + MAG_SIZE > window.innerHeight) y = e.clientY - off - MAG_SIZE\n setMag({ x, y })\n }\n\n const onClick = (e: React.MouseEvent) => {\n const s = sampleAt(e.clientX, e.clientY)\n if (!s) return\n const [h, sl, l] = rgbToHsl(s.rgb[0], s.rgb[1], s.rgb[2])\n onPick(hslToHsv(h, sl, l))\n }\n\n return (\n <Portal>\n <div className=\"dab-overlay\">\n <div className=\"dab-overlay-title\">{t('pickerTitle')}</div>\n <div className=\"dab-overlay-hint\">{t('pickerHint')}</div>\n <div className=\"dab-modal-card\" style={{\n maxWidth: 'min(90vw, 720px)', maxHeight: '60vh', overflow: 'hidden',\n borderRadius: 12, border: '2px solid rgba(255,255,255,0.3)', background: '#000', cursor: 'crosshair',\n }}>\n <canvas ref={canvasRef} style={{ display: 'block', maxWidth: '100%', maxHeight: '60vh', objectFit: 'contain' }}\n onMouseMove={onMove}\n onMouseLeave={() => { setHover(null); setMag(null) }}\n onClick={onClick} />\n </div>\n <div style={{ display: 'flex', alignItems: 'center', gap: 10, minWidth: 260 }}>\n <div style={{ width: 28, height: 28, borderRadius: 8, border: '1px solid rgba(255,255,255,0.4)', background: hover ? rgbToHex(hover.rgb) : 'transparent' }} />\n <div style={{ color: '#fff', fontSize: 13, fontFamily: 'var(--dab-mono, monospace)' }}>{hover ? `${rgbToHex(hover.rgb)} · rgb(${hover.rgb.join(', ')})` : '—'}</div>\n </div>\n <div style={{ display: 'flex', gap: 10 }}>\n <button type=\"button\" className=\"dab-btn\" onClick={onClose}>{t('pickerClose')}</button>\n </div>\n <canvas ref={magRef} width={MAG_SIZE} height={MAG_SIZE}\n style={{\n position: 'fixed', width: MAG_SIZE, height: MAG_SIZE, borderRadius: '50%',\n border: '2px solid rgba(255,255,255,0.7)', boxShadow: '0 4px 16px rgba(0,0,0,0.5)',\n zIndex: 10000, background: '#000', pointerEvents: 'none', transition: 'opacity 0.08s',\n left: mag?.x ?? 0, top: mag?.y ?? 0, opacity: mag ? 1 : 0,\n }} />\n </div>\n </Portal>\n )\n}\n","import { useState } from 'react'\r\nimport type { CSSProperties } from 'react'\r\nimport type { ThemeSectionProps, ThemeStoreState } from '../../types'\r\nimport { hsvToHsl, hslToRgb, hslToHsv, rgbToHex } from '../../utils/color'\r\nimport { ColorWheel } from '../ColorWheel'\r\nimport { ColorInputs } from '../ColorInputs'\r\nimport { ColorPicker } from '../ColorPicker'\r\nimport { PipetteIcon, SparkleIcon } from '../icons'\r\n\r\n/** Curated quick-pick hues (HSL, s .72 l .55). */\r\nconst SWATCHES: Array<[number, number, number]> = [\r\n [356, 0.72, 0.55], [24, 0.78, 0.55], [44, 0.8, 0.55], [152, 0.62, 0.5],\r\n [174, 0.68, 0.48], [208, 0.72, 0.55], [252, 0.68, 0.6], [300, 0.64, 0.58],\r\n]\r\n\r\nexport function ColorPage({ p, notify }: { p: ThemeSectionProps; notify: (msg: string, ok?: boolean) => void }) {\r\n const { t, hue, sat, lit, setColor, extractColor, setSchemeOverride, useStore } = p\r\n // Field-level subscriptions: only url (extract/eyedropper gating), the forced\r\n // scheme and the stored color change this page's output.\r\n const storeUrl = useStore((s: ThemeStoreState) => s.url)\r\n const schemeOverride = useStore((s: ThemeStoreState) => s.schemeOverride)\r\n const color = useStore((s: ThemeStoreState) => s.color)\r\n const [pickerOpen, setPickerOpen] = useState(false)\r\n const [extracting, setExtracting] = useState(false)\r\n\r\n const wheel = (color ?? [hue, sat, lit]) as [number, number, number]\r\n const [h, s, l] = hsvToHsl(wheel[0], wheel[1], wheel[2])\r\n const [r, g, b] = hslToRgb(h, s, l)\r\n const hex = rgbToHex([r, g, b])\r\n const soft = `rgba(${Math.round(r)},${Math.round(g)},${Math.round(b)},0.5)`\r\n const orbVars = { '--c': hex, '--c-soft': soft } as CSSProperties\r\n\r\n const onExtract = async () => {\r\n if (!storeUrl || extracting) return\r\n setExtracting(true)\r\n try {\r\n const ok = await extractColor()\r\n notify(ok ? t('extractDone') : t('extractFail'), ok)\r\n } catch {\r\n notify(t('extractFail'), false)\r\n } finally {\r\n setExtracting(false)\r\n }\r\n }\r\n\r\n return (\r\n <>\r\n <header className=\"dab-head dab-rise\" style={{ '--d': 0 } as CSSProperties}>\r\n <div className=\"dab-overline\">Accent</div>\r\n <h2 className=\"dab-h1\">{t('colorTitle')}</h2>\r\n <p className=\"dab-desc\">{t('descColor')}</p>\r\n </header>\r\n\r\n {/* Hero: living orb with a rotating conic halo + live HEX readout */}\r\n <section className=\"dab-card dab-card-hover dab-hero-accent dab-rise\" style={{ '--d': 1 } as CSSProperties}>\r\n <div className=\"dab-orb-wrap\" style={orbVars}>\r\n <div className=\"dab-orb-ring\" />\r\n <div className=\"dab-orb\" />\r\n </div>\r\n <div style={{ flex: 1, minWidth: 200 }}>\r\n <div className=\"dab-hex-caption\">{t('hexCaption')}</div>\r\n <div className=\"dab-hex\">{hex.toUpperCase()}</div>\r\n <div className=\"dab-hsl-row\">\r\n <span>H <b>{Math.round(h)}°</b></span>\r\n <span>S <b>{Math.round(s * 100)}%</b></span>\r\n <span>L <b>{Math.round(l * 100)}%</b></span>\r\n </div>\r\n <div className=\"dab-chip-row\" style={{ marginTop: 14 }}>\r\n <button type=\"button\" className=\"dab-btn\" disabled={!storeUrl || extracting} onClick={onExtract}>\r\n <SparkleIcon size={14} />{extracting ? t('extracting') : t('extractColor')}\r\n </button>\r\n <button type=\"button\" className=\"dab-btn\" disabled={!storeUrl} onClick={() => setPickerOpen(true)}>\r\n <PipetteIcon size={14} />{t('eyedropper')}\r\n </button>\r\n </div>\r\n </div>\r\n </section>\r\n\r\n {/* Wheel + precise entry */}\r\n <section className=\"dab-card dab-wheel-card dab-rise\" style={{ '--d': 2 } as CSSProperties}>\r\n <div className=\"dab-wheel-glow\" style={{ background: hex }} />\r\n <ColorWheel hue={wheel[0]} sat={wheel[1]} lit={wheel[2]} onChange={setColor} />\r\n <ColorInputs hue={wheel[0]} sat={wheel[1]} lit={wheel[2]} onChange={setColor} />\r\n </section>\r\n <p className=\"dab-hint dab-rise\" style={{ '--d': 3 } as CSSProperties}>{t('colorHint')}</p>\r\n\r\n {/* Quick swatches */}\r\n <section className=\"dab-card dab-card-hover dab-rise\" style={{ '--d': 3 } as CSSProperties}>\r\n <div className=\"dab-swatch-title\">{t('swatchTitle')}</div>\r\n <div className=\"dab-swatches\">\r\n {SWATCHES.map(([sh, ss, sl], i) => {\r\n // Circular hue distance via the (Δ+540)%360 trick. A swatch is \"on\"\r\n // only when the current color actually matches it (hue within 3°,\r\n // sat/lightness within 0.05). Picking a custom color in the wheel\r\n // clears the swatch selection instead of keeping it highlighted\r\n // based on hue proximity alone.\r\n const dist = Math.abs(((wheel[0] - sh + 540) % 360) - 180)\r\n const on = dist < 3 && Math.abs(s - ss) < 0.05 && Math.abs(l - sl) < 0.05\r\n return (\r\n <button\r\n key={i} type=\"button\"\r\n className={`dab-swatch${on ? ' is-on' : ''}`}\r\n style={{ background: `hsl(${sh} ${Math.round(ss * 100)}% ${Math.round(sl * 100)}%)` }}\r\n title={rgbToHex(hslToRgb(sh, ss, sl)).toUpperCase()}\r\n onClick={() => setColor(...hslToHsv(sh, ss, sl))} />\r\n )\r\n })}\r\n </div>\r\n </section>\r\n\r\n {/* Forced interface scheme */}\r\n <section className=\"dab-card dab-rise\" style={{ '--d': 4 } as CSSProperties}>\r\n <div className=\"dab-swatch-title\">{t('schemeTitle')}</div>\r\n <div className=\"dab-seg\" style={{ '--w': '86px' } as CSSProperties}>\r\n <div className=\"dab-seg-thumb\" style={{ transform: `translateX(${schemeOverride === 'light' ? 0 : schemeOverride === 'dark' ? 86 : 172}px)` }} />\r\n <button type=\"button\" className={`dab-seg-item${schemeOverride === 'light' ? ' is-active' : ''}`} onClick={() => setSchemeOverride('light')}>{t('schemeLight')}</button>\r\n <button type=\"button\" className={`dab-seg-item${schemeOverride === 'dark' ? ' is-active' : ''}`} onClick={() => setSchemeOverride('dark')}>{t('schemeDark')}</button>\r\n <button type=\"button\" className={`dab-seg-item${schemeOverride === 'auto' ? ' is-active' : ''}`} onClick={() => setSchemeOverride('auto')}>{t('schemeAuto')}</button>\r\n </div>\r\n <p className=\"dab-hint\" style={{ marginTop: 10 }}>{t('schemeHint')}</p>\r\n </section>\r\n\r\n {/* Eyedropper modal */}\r\n {pickerOpen && storeUrl ? (\r\n <ColorPicker url={storeUrl} t={t} onClose={() => setPickerOpen(false)}\r\n onPick={hsv => { setColor(hsv[0], hsv[1], hsv[2]); setPickerOpen(false) }} />\r\n ) : null}\r\n </>\r\n )\r\n}\r\n","import { useEffect, useRef } from 'react'\nimport type { CSSProperties } from 'react'\n\n/**\n * Zero-lag slider: the thumb and value label update through DOM refs while\n * dragging (onInput) so the caller can mutate the live UI directly without a\n * React re-render; onChange commits the settled value. Double-click resets to\n * the canonical default. The track fill is a gradient driven by the --pct\n * custom property, updated imperatively alongside the thumb.\n */\nexport function LiveSlider({ min, max, step, def, fmt, label, onInput, onChange }: {\n min: number; max: number; step: number; def: number\n fmt: (v: number) => string; label?: string; onInput?: (v: number) => void; onChange: (v: number) => void\n}) {\n const inputRef = useRef<HTMLInputElement>(null)\n const valRef = useRef<HTMLSpanElement>(null)\n\n const paint = (el: HTMLInputElement, v: number): void => {\n el.style.setProperty('--pct', String(((v - min) / (max - min)) * 100))\n }\n\n // Read the formatter through a ref: every caller passes an inline arrow\n // (`v => `${v}%``), whose identity changes per render. Listing `fmt` in the\n // effect deps would re-run this sync on EVERY parent render — and since the\n // sync writes inputRef.value from `def`, a mid-drag re-render (the 30s\n // schedule tick, a toast, a store sync) yanks the thumb back to the old\n // committed value. Only the numeric bounds may re-sync, never the closure.\n const fmtRef = useRef(fmt)\n fmtRef.current = fmt\n\n // Controlled sync: keep the knob and label aligned with the canonical prop\n // so external updates (presets, regeneration, imports) never leave it stale.\n useEffect(() => {\n if (inputRef.current) {\n inputRef.current.value = String(def)\n paint(inputRef.current, def)\n }\n if (valRef.current) valRef.current.textContent = fmtRef.current(def)\n }, [def, min, max])\n\n const apply = (v: number): void => {\n if (inputRef.current) {\n inputRef.current.value = String(v)\n paint(inputRef.current, v)\n }\n if (valRef.current) valRef.current.textContent = fmt(v)\n onInput?.(v)\n onChange(v)\n }\n\n return (\n <div className=\"dab-slider-block\">\n {label ? <span className=\"dab-slider-label\">{label}</span> : null}\n <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>\n <input\n ref={inputRef} type=\"range\" className=\"dab-slider\"\n style={{ '--pct': ((def - min) / (max - min)) * 100 } as CSSProperties}\n min={min} max={max} step={step} defaultValue={def}\n title={label ? `${label} · ${fmt(def)}` : fmt(def)}\n onDoubleClick={() => apply(def)}\n onInput={e => {\n const el = e.target as HTMLInputElement\n const v = Number(el.value)\n paint(el, v)\n onInput?.(v)\n if (valRef.current) valRef.current.textContent = fmt(v)\n }}\n onChange={e => onChange(Number((e.target as HTMLInputElement).value))} />\n <span ref={valRef} className=\"dab-slider-val\">{fmt(def)}</span>\n </div>\n </div>\n )\n}\n","import type { CSSProperties, ComponentType } from 'react'\r\nimport type { ThemeSectionProps, ThemeStoreState, PartOpacities, PartBlurs } from '../../types'\r\nimport { cfg, rOps, rSop, rBlurs, rChatTextOpacity, rTrajectoryOpacity, rPanelOpacity, rProducedOpacity, rHeaderOpacity, rHeaderBarOpacity } from '../../state'\r\nimport { saveConfig } from '../../rpc'\r\nimport { applyCustomTokens, applySettingsOverrides, setPartBlur, applyViewCards, applyTrajectoryOverrides, applyPanelOverrides, applyProduced, applyHeaderPopovers, applyHeaderBar } from '../../wallpaper'\r\nimport { LiveSlider } from '../LiveSlider'\r\nimport { CanvasIcon, SidebarIcon, ChatIcon, GearIcon, TextIcon, TrajectoryIcon, InputIcon, PanelIcon, HeaderBarIcon } from '../icons'\r\n\r\ninterface PartDef {\r\n labelKey: string\r\n Icon: ComponentType<{ size?: number }>\r\n /** Homepage part key; absent for the settings-panel part. */\r\n opKey?: keyof PartOpacities\r\n isSettings?: boolean\r\n /** Conversation text region: tint opacity + blur over the message column. */\r\n isChat?: boolean\r\n /** Trajectory view: tint opacity + blur over the whole view surface. */\r\n isTrajectory?: boolean\r\n /** The host's own right Sidebar column: opacity + blur. */\r\n isPanel?: boolean\r\n /** Produced/highlight surfaces — code blocks, inline code, produced chips and\r\n * the dsh-better-sidebar workbench: opacity + blur. */\r\n isProduced?: boolean\r\n /** Header popovers (Agent Team panel + background-job list): opacity + blur. */\r\n isHeader?: boolean\r\n /** Session header bar (the conversation's title / actions / view tabs):\r\n * opacity + blur. Inert where the host renders that slot bare. */\r\n isHeaderBar?: boolean\r\n}\r\n\r\nconst PARTS: PartDef[] = [\r\n { opKey: 'bg', labelKey: 'uiOpacityBg', Icon: CanvasIcon },\r\n { opKey: 'sidebar', labelKey: 'uiOpacitySide', Icon: SidebarIcon },\r\n { opKey: 'card', labelKey: 'uiOpacityCard', Icon: ChatIcon },\r\n { opKey: 'input', labelKey: 'uiOpacityInput', Icon: InputIcon },\r\n { isSettings: true, labelKey: 'uiSop', Icon: GearIcon },\r\n { isChat: true, labelKey: 'uiChatRegion', Icon: TextIcon },\r\n { isTrajectory: true, labelKey: 'uiTrajectory', Icon: TrajectoryIcon },\r\n { isProduced: true, labelKey: 'uiProduced', Icon: TextIcon },\r\n { isHeader: true, labelKey: 'uiHeader', Icon: PanelIcon },\r\n { isHeaderBar: true, labelKey: 'uiHeaderBar', Icon: HeaderBarIcon },\r\n { isPanel: true, labelKey: 'uiPanelNative', Icon: PanelIcon },\r\n]\r\n\r\nexport function InterfacePage({ p }: { p: ThemeSectionProps }) {\r\n const { t, setOps, setBlurs, setSop, setPanelOp, useStore } = p\r\n // Presets, theme imports and profile restores mutate cfg directly and only\r\n // bump the store's metaRev — this page renders straight off cfg, so without\r\n // this subscription it never re-renders and the sliders keep showing the\r\n // values from before the change (while the interface itself already moved).\r\n const metaRev = useStore((s: ThemeStoreState) => s.metaRev)\r\n void metaRev\r\n // The panel row owns the host's own right Sidebar only. The dsh-better-sidebar\r\n // workbench used to ride this row too, but it is an artifact viewer, not a page\r\n // column, so since 0.3.2 it belongs to the produced row below (PRODUCED_RULE).\r\n\r\n return (\r\n <>\r\n <header className=\"dab-head dab-rise\" style={{ '--d': 0 } as CSSProperties}>\r\n <div className=\"dab-overline\">Surfaces</div>\r\n <h2 className=\"dab-h1\">{t('uiTitle')}</h2>\r\n <p className=\"dab-desc\">{t('descInterface')}</p>\r\n </header>\r\n\r\n <div className=\"dab-grid-parts\">\r\n {PARTS.map((part, i) => {\r\n const { labelKey, Icon, isSettings, isChat, isTrajectory, isPanel, isProduced, isHeader, isHeaderBar } = part\r\n const opKey = part.opKey\r\n const label = t(labelKey)\r\n // Homepage parts (bg/sidebar/card/input) bind to their own part only;\r\n // the settings panel (isSettings) binds exclusively to the 'settings'\r\n // part (--dsh-any-blur-settings / --dsh-any-bg-settings-surface) and\r\n // must never fall back to a homepage part key — otherwise the dialog\r\n // panel would track the homepage center/card blur and the home-page\r\n // opacities. The chat region (isChat) and the trajectory view\r\n // (isTrajectory) own their own blur keys plus their own tint\r\n // opacities; the header row (isHeader) owns the 'header' blur key and\r\n // cfg.headerOpacity; the panel row (isPanel, the host's own right\r\n // Sidebar column) owns the 'panel' blur key and cfg.panelOpacity.\r\n // Every homepage opKey is also a PartBlurs\r\n // key (input included), so the shared blur slider dereferences it\r\n // directly.\r\n const blurKey: keyof PartBlurs = isChat ? 'chat' : isTrajectory ? 'trajectory' : isSettings ? 'settings' : isPanel ? 'panel' : isProduced ? 'produced' : isHeader ? 'header' : isHeaderBar ? 'headerBar' : opKey!\r\n const opacity = isChat ? rChatTextOpacity() : isTrajectory ? rTrajectoryOpacity() : isSettings ? rSop() : isPanel ? rPanelOpacity() : isProduced ? rProducedOpacity() : isHeader ? rHeaderOpacity() : isHeaderBar ? rHeaderBarOpacity() : rOps()[opKey!]\r\n return (\r\n <section key={blurKey} className=\"dab-card dab-card-hover dab-rise\" style={{ '--d': i + 1 } as CSSProperties}>\r\n <div className=\"dab-part-head\">\r\n <div className=\"dab-part-ico\"><Icon size={16} /></div>\r\n <div className=\"dab-part-name\">{label}</div>\r\n <span className=\"dab-part-badge\">{Math.round(opacity * 100)}%</span>\r\n </div>\r\n\r\n <LiveSlider label={t('uiOpacity')} min={0} max={100} step={1} def={Math.round(opacity * 100)}\r\n fmt={v => `${v}%`}\r\n onInput={v => {\r\n const op = v / 100\r\n if (isChat) {\r\n cfg.chatTextOpacity = op\r\n applyViewCards()\r\n } else if (isTrajectory) {\r\n cfg.trajectoryOpacity = op\r\n applyTrajectoryOverrides(op)\r\n } else if (isSettings) {\r\n cfg.settingsOpacity = op\r\n applySettingsOverrides(op)\r\n } else if (isPanel) {\r\n cfg.panelOpacity = op\r\n applyPanelOverrides(op)\r\n } else if (isProduced) {\r\n cfg.producedOpacity = op\r\n applyProduced()\r\n } else if (isHeader) {\r\n cfg.headerOpacity = op\r\n applyHeaderPopovers()\r\n } else if (isHeaderBar) {\r\n cfg.headerBarOpacity = op\r\n applyHeaderBar()\r\n } else {\r\n const ops = { ...rOps() }\r\n ops[opKey!] = op\r\n cfg.opacities = ops\r\n applyCustomTokens(ops)\r\n }\r\n saveConfig()\r\n }}\r\n onChange={v => {\r\n const op = v / 100\r\n if (isChat) {\r\n cfg.chatTextOpacity = op\r\n applyViewCards()\r\n saveConfig()\r\n } else if (isTrajectory) {\r\n cfg.trajectoryOpacity = op\r\n applyTrajectoryOverrides(op)\r\n saveConfig()\r\n } else if (isSettings) {\r\n setSop(op)\r\n } else if (isPanel) {\r\n setPanelOp(op)\r\n } else if (isProduced) {\r\n cfg.producedOpacity = op\r\n applyProduced()\r\n saveConfig()\r\n } else if (isHeader) {\r\n cfg.headerOpacity = op\r\n applyHeaderPopovers()\r\n saveConfig()\r\n } else if (isHeaderBar) {\r\n cfg.headerBarOpacity = op\r\n applyHeaderBar()\r\n saveConfig()\r\n } else {\r\n const ops = { ...rOps() }\r\n ops[opKey!] = op\r\n setOps(ops)\r\n }\r\n }} />\r\n\r\n <LiveSlider label={t('uiBlur')} min={0} max={60} step={1} def={rBlurs()[blurKey]}\r\n fmt={v => `${v}px`}\r\n onInput={v => {\r\n const blurs = { ...rBlurs() }\r\n blurs[blurKey] = v\r\n cfg.blurs = blurs\r\n setPartBlur(blurKey, v)\r\n saveConfig()\r\n }}\r\n onChange={v => {\r\n const blurs = { ...rBlurs() }\r\n blurs[blurKey] = v\r\n setBlurs(blurs)\r\n }} />\r\n </section>\r\n )\r\n })}\r\n </div>\r\n </>\r\n )\r\n}\r\n","import { useEffect, useRef, useState } from 'react'\r\nimport type { CSSProperties, ComponentType } from 'react'\r\nimport type { PartBlurs, PartStrokes, StrokeConfig, ThemeStoreState, ThemeSectionProps } from '../../types'\r\nimport { cfg, rStrokes } from '../../state'\r\nimport { saveConfig, uploadRefusalText } from '../../rpc'\r\nimport { setPartStroke } from '../../wallpaper'\r\nimport { LiveSlider } from '../LiveSlider'\r\nimport {\r\n CanvasIcon, SidebarIcon, ChatIcon, GearIcon, TextIcon, TrajectoryIcon,\r\n InputIcon, PanelIcon, HeaderBarIcon, TrashIcon, UploadIcon,\r\n} from '../icons'\r\n\r\n/**\r\n * Font page: the custom interface font slot plus per-part text strokes.\r\n *\r\n * Stroke settings mirror the interface page's per-part blur groups one-to-one\r\n * (same nine surfaces) — see STROKE_RULE in wallpaper.ts for how each group\r\n * binds to the DOM. Colors are stored as PRESET KEYS, never resolved values,\r\n * so 'auto' (contrast the font) and 'theme' (follow the accent) keep tracking\r\n * the palette; only 'custom' carries a literal hex.\r\n */\r\ninterface PartDef {\r\n /** Surface group key — a PartBlurs key, and therefore a PartStrokes key. */\r\n key: keyof PartBlurs\r\n labelKey: string\r\n Icon: ComponentType<{ size?: number }>\r\n}\r\n\r\nconst PARTS: PartDef[] = [\r\n { key: 'bg', labelKey: 'uiOpacityBg', Icon: CanvasIcon },\r\n { key: 'sidebar', labelKey: 'uiOpacitySide', Icon: SidebarIcon },\r\n { key: 'card', labelKey: 'uiOpacityCard', Icon: ChatIcon },\r\n { key: 'input', labelKey: 'uiOpacityInput', Icon: InputIcon },\r\n { key: 'settings', labelKey: 'uiSop', Icon: GearIcon },\r\n { key: 'chat', labelKey: 'uiChatRegion', Icon: TextIcon },\r\n { key: 'trajectory', labelKey: 'uiTrajectory', Icon: TrajectoryIcon },\r\n { key: 'produced', labelKey: 'uiProduced', Icon: TextIcon },\r\n { key: 'header', labelKey: 'uiHeader', Icon: PanelIcon },\r\n { key: 'headerBar', labelKey: 'uiHeaderBar', Icon: HeaderBarIcon },\r\n { key: 'panel', labelKey: 'uiPanelNative', Icon: PanelIcon },\r\n]\r\n\r\nconst COLOR_KEYS: Array<StrokeConfig['color']> = ['auto', 'gray', 'black', 'white', 'theme', 'custom']\r\nconst COLOR_LABEL_KEYS: Record<StrokeConfig['color'], string> = {\r\n auto: 'strokeAuto', gray: 'strokeGray', black: 'strokeBlack',\r\n white: 'strokeWhite', theme: 'strokeTheme', custom: 'strokeCustom',\r\n}\r\n\r\n/** Swatch fill for one preset key. 'auto' gets its half-black/half-white\r\n * conic gradient from CSS, and 'custom' shows the stored hex. */\r\nfunction dotStyle(key: StrokeConfig['color'], s: StrokeConfig): CSSProperties {\r\n switch (key) {\r\n case 'gray': return { background: '#808080' }\r\n case 'black': return { background: '#000' }\r\n case 'white': return { background: '#fff' }\r\n case 'theme': return { background: 'var(--dsw-alias-brand-primary)' }\r\n case 'custom': return { background: s.customColor }\r\n default: return {}\r\n }\r\n}\r\n\r\nexport function FontPage({ p, notify }: { p: ThemeSectionProps; notify: (msg: string, ok?: boolean) => void }) {\r\n const { t, setFont, removeFont, setFontEnabled, setStrokes, useStore } = p\r\n const fileRef = useRef<HTMLInputElement>(null)\r\n\r\n // cfg is the source of truth; the local copies exist because nothing else\r\n // re-renders this page when the config changes (the store only carries the\r\n // wallpaper/color/meta snapshots), and async uploads settle after render.\r\n const [strokes, setStrokesState] = useState<PartStrokes>(() => rStrokes())\r\n const [fontInfo, setFontInfo] = useState<{ mime: string | null; enabled: boolean; name: string | null }>(() => ({\r\n mime: cfg.fontMime, enabled: cfg.fontEnabled, name: null,\r\n }))\r\n const [busy, setBusy] = useState(false)\r\n\r\n // Presets / imports / profile restores rewrite cfg.strokes and the font slot\r\n // directly and only bump the store's metaRev. Without this re-derivation the\r\n // local copies above keep rendering the values from before the change.\r\n const metaRev = useStore((s: ThemeStoreState) => s.metaRev)\r\n useEffect(() => {\r\n setStrokesState(rStrokes())\r\n setFontInfo(prev =>\r\n prev.mime === cfg.fontMime && prev.enabled === cfg.fontEnabled\r\n ? prev\r\n : { mime: cfg.fontMime, enabled: cfg.fontEnabled, name: null },\r\n )\r\n }, [metaRev])\r\n\r\n const hasFont = fontInfo.mime !== null\r\n // After a reload only the MIME survives (the original filename is not\r\n // persisted), so fall back to the container format — e.g. \"WOFF2\".\r\n const fontLabel = fontInfo.name ?? (fontInfo.mime !== null ? fontInfo.mime.replace('font/', '').toUpperCase() : t('fontNone'))\r\n\r\n /** Write one group's stroke: cfg + live DOM now, disk on commit. `live`\r\n * marks slider drags (debounced save, no full re-apply). */\r\n const patch = (key: keyof PartBlurs, next: Partial<StrokeConfig>, live: boolean): void => {\r\n const map: PartStrokes = { ...strokes, [key]: { ...strokes[key], ...next } }\r\n setStrokesState(map)\r\n cfg.strokes = map\r\n setPartStroke(key, map[key])\r\n if (live) saveConfig()\r\n else setStrokes(map)\r\n }\r\n\r\n const pickFont = async (file: File): Promise<void> => {\r\n setBusy(true)\r\n setFontInfo({ ...fontInfo, name: file.name })\r\n const outcome = await setFont(file)\r\n setBusy(false)\r\n if (outcome.ok) {\r\n setFontInfo({ mime: cfg.fontMime, enabled: cfg.fontEnabled, name: file.name })\r\n } else {\r\n // Roll the optimistic name back to whatever is actually stored.\r\n setFontInfo({ mime: cfg.fontMime, enabled: cfg.fontEnabled, name: null })\r\n notify(uploadRefusalText(outcome, t, 'fontFail'), false)\r\n }\r\n }\r\n\r\n return (\r\n <>\r\n <header className=\"dab-head dab-rise\" style={{ '--d': 0 } as CSSProperties}>\r\n <div className=\"dab-overline\">Typography</div>\r\n <h2 className=\"dab-h1\">{t('fontPageTitle')}</h2>\r\n <p className=\"dab-desc\">{t('descFont')}</p>\r\n </header>\r\n\r\n <section className=\"dab-card dab-rise dab-font-card\" style={{ '--d': 1 } as CSSProperties}>\r\n <div className=\"dab-row-head\">\r\n <div className=\"dab-font-title\">\r\n <div className=\"dab-part-ico\"><TextIcon size={16} /></div>\r\n <div className=\"dab-part-name\">{t('fontTitle')}</div>\r\n </div>\r\n {hasFont ? (\r\n <button type=\"button\" className={`dab-toggle${fontInfo.enabled ? ' is-on' : ''}`} role=\"switch\"\r\n aria-checked={fontInfo.enabled} aria-label={t('fontEnabled')}\r\n onClick={() => {\r\n const v = !fontInfo.enabled\r\n setFontEnabled(v)\r\n setFontInfo({ ...fontInfo, enabled: v })\r\n }}>\r\n <span className=\"dab-toggle-knob\" />\r\n </button>\r\n ) : null}\r\n </div>\r\n\r\n <div className=\"dab-font-row\">\r\n <span className={`dab-font-name${hasFont ? '' : ' is-empty'}`} title={fontLabel}>{fontLabel}</span>\r\n <div className=\"dab-font-actions\">\r\n <button type=\"button\" className=\"dab-btn dab-btn-primary\" disabled={busy}\r\n onClick={() => fileRef.current?.click()}>\r\n <UploadIcon size={14} />{busy ? t('fontUploading') : t('fontUpload')}\r\n </button>\r\n {hasFont ? (\r\n <button type=\"button\" className=\"dab-btn dab-btn-danger\"\r\n onClick={() => {\r\n removeFont()\r\n setFontInfo({ mime: null, enabled: cfg.fontEnabled, name: null })\r\n }}>\r\n <TrashIcon size={14} />{t('fontRemove')}\r\n </button>\r\n ) : null}\r\n </div>\r\n </div>\r\n\r\n <p className=\"dab-hint\" style={{ marginTop: 10 }}>{t('fontHint')}</p>\r\n <input ref={fileRef} type=\"file\" accept=\".ttf,.otf,.woff,.woff2,font/*\" style={{ display: 'none' }}\r\n onChange={e => {\r\n const f = e.target.files?.[0]\r\n e.target.value = ''\r\n if (f) void pickFont(f)\r\n }} />\r\n </section>\r\n\r\n <section className=\"dab-card dab-rise\" style={{ '--d': 2 } as CSSProperties}>\r\n <div className=\"dab-part-head\" style={{ marginBottom: 10 }}>\r\n <div className=\"dab-part-name\">{t('strokeTitle')}</div>\r\n </div>\r\n <p className=\"dab-hint\" style={{ marginBottom: 14 }}>{t('strokeHint')}</p>\r\n\r\n <div className=\"dab-grid-parts\">\r\n {PARTS.map((part, i) => {\r\n const s = strokes[part.key]\r\n return (\r\n <section key={part.key} className=\"dab-card dab-card-hover dab-rise\" style={{ '--d': i + 3 } as CSSProperties}>\r\n <div className=\"dab-part-head\">\r\n <div className=\"dab-part-ico\"><part.Icon size={16} /></div>\r\n <div className=\"dab-part-name\">{t(part.labelKey)}</div>\r\n <span className=\"dab-part-badge\">{s.width}px</span>\r\n </div>\r\n\r\n <LiveSlider label={t('strokeWidth')} min={0} max={4} step={0.5} def={s.width}\r\n fmt={v => `${v}px`}\r\n onInput={v => patch(part.key, { width: v }, true)}\r\n onChange={v => patch(part.key, { width: v }, false)} />\r\n\r\n <div className=\"dab-stroke-dots\">\r\n {COLOR_KEYS.map(key => {\r\n const active = s.color === key\r\n return (\r\n <div key={key} className=\"dab-stroke-dot-wrap\">\r\n <button type=\"button\"\r\n className={`dab-stroke-dot${key === 'auto' ? ' dab-stroke-dot-auto' : ''}${active ? ' is-active' : ''}`}\r\n style={dotStyle(key, s)}\r\n title={t(COLOR_LABEL_KEYS[key])} aria-label={t(COLOR_LABEL_KEYS[key])}\r\n aria-pressed={active}\r\n onClick={() => patch(part.key, { color: key }, false)} />\r\n {/* The native picker is invisible and stretched over the\r\n swatch, so one click both selects 'custom' and opens\r\n it — no in-house color popover needed. */}\r\n {key === 'custom' ? (\r\n <input type=\"color\" className=\"dab-stroke-dot-input\" value={s.customColor}\r\n aria-label={t('strokeCustom')}\r\n onChange={e => patch(part.key, { color: 'custom', customColor: e.target.value }, false)} />\r\n ) : null}\r\n </div>\r\n )\r\n })}\r\n </div>\r\n </section>\r\n )\r\n })}\r\n </div>\r\n </section>\r\n </>\r\n )\r\n}\r\n","import { useRef, useState, useEffect, useCallback } from 'react'\r\nimport { cfg } from '../state'\r\nimport { Portal } from './Portal'\r\n\r\n/** Placement slot for the active background type: video framing lives in its\r\n * own state so image and video edits never overwrite each other. */\r\nconst activeState = () => cfg.backgroundType === 'video' ? cfg.videoBgState : cfg.bgState\r\n\r\n/** Zoom is shared by every input path (wheel + pinch) so all pictures animate\r\n * between the same bounds. */\r\nconst clampZoom = (z: number): number => Math.max(0.1, Math.min(10, z))\r\n\r\nexport function BgEditor({ url, t, onClose, onCommit }: {\r\n url: string; t: (key: string) => string; onClose: () => void\r\n onCommit: (zoom: number, x: number, y: number, iw: number, ih: number) => void\r\n}) {\r\n const pw = Math.min(window.innerWidth * 0.75, 860)\r\n const ph = Math.round(pw * window.innerHeight / window.innerWidth)\r\n const saved = activeState()\r\n const [zoom, setZoom] = useState(saved.iw > 0 ? saved.zoom : 1)\r\n const [pos, setPos] = useState(saved.iw > 0 ? { x: saved.x * pw, y: saved.y * ph } : { x: 0, y: 0 })\r\n const [imgSize, setImgSize] = useState({ w: 0, h: 0 })\r\n const containerRef = useRef<HTMLDivElement>(null)\r\n const imgRef = useRef<HTMLImageElement>(null)\r\n /**\r\n * The overlay node is held in STATE rather than a plain ref, so the listener\r\n * effect below re-runs the moment it actually exists.\r\n *\r\n * This is not a style choice. Everything here renders through <Portal>, which\r\n * returns null on its first render — its own effect has to create the host\r\n * node under <html> first. A plain ref is therefore still null when a\r\n * mount-only effect runs, and an effect whose deps never change again attaches\r\n * nothing, ever. That is exactly how the touch handlers below ended up dead on\r\n * real phones: the wheel handler only survived because its deps churn on every\r\n * zoom/pan, so the wallpaper's img.onload re-ran it once and wired it up.\r\n */\r\n const [overlayEl, setOverlayEl] = useState<HTMLDivElement | null>(null)\r\n const dragRef = useRef({ active: false, sx: 0, sy: 0, spx: 0, spy: 0 })\r\n /** Unmount-time cleanup for a drag that never saw its mouseup (editor closed\r\n * mid-drag): without it the document listeners stay attached forever and\r\n * keep calling setPos on a dead component. */\r\n const dragStopRef = useRef<(() => void) | null>(null)\r\n /** Set once a gesture actually moved, so the click that follows a drag is not\r\n * mistaken for a tap on the backdrop (mousedown and mouseup in different\r\n * subtrees make the click land on the overlay, i.e. \"outside\"). Reset at the\r\n * start of every gesture — touchstart / mousedown / wheel — so it can only\r\n * ever describe the gesture that just ended, never an earlier one. */\r\n const movedRef = useRef(false)\r\n // Latest view for the natively-attached touch listeners below — they are\r\n // attached once (rather than re-bound every render) and read the current\r\n // zoom/offset from this mirror.\r\n const viewRef = useRef({ zoom, pos })\r\n viewRef.current = { zoom, pos }\r\n /** Pinch gesture baseline (two fingers down): finger spread + midpoint and\r\n * the transform that was live at that moment. */\r\n const pinchRef = useRef<{ dist: number; zoom: number; cx: number; cy: number; px: number; py: number } | null>(null)\r\n /** Single-finger pan baseline. */\r\n const touchDragRef = useRef<{ sx: number; sy: number; spx: number; spy: number } | null>(null)\r\n\r\n useEffect(() => {\r\n const img = new Image()\r\n img.onload = () => {\r\n const scale = Math.min(pw / img.width, ph / img.height)\r\n const w = img.width * scale, h = img.height * scale\r\n setImgSize({ w, h })\r\n const s = activeState()\r\n if (s.iw > 0 && s.iw === img.width && s.ih === img.height) {\r\n setZoom(s.zoom)\r\n // Saved x, y are CENTER fractions of the preview: the image center\r\n // lands at (x·pw, y·ph), so the top-left comes from subtracting half\r\n // the displayed (zoom-scaled) image size.\r\n setPos({ x: s.x * pw - w * s.zoom / 2, y: s.y * ph - h * s.zoom / 2 })\r\n } else {\r\n setZoom(1)\r\n setPos({ x: (pw - w) / 2, y: (ph - h) / 2 })\r\n }\r\n }\r\n img.src = url\r\n }, [url, pw, ph])\r\n\r\n const onDown = useCallback((e: React.MouseEvent) => {\r\n e.preventDefault()\r\n movedRef.current = false\r\n dragRef.current = { active: true, sx: e.clientX, sy: e.clientY, spx: pos.x, spy: pos.y }\r\n const onMove = (ev: MouseEvent) => {\r\n if (!dragRef.current.active) return\r\n if (Math.abs(ev.clientX - dragRef.current.sx) > 4 || Math.abs(ev.clientY - dragRef.current.sy) > 4) movedRef.current = true\r\n setPos({ x: dragRef.current.spx + ev.clientX - dragRef.current.sx, y: dragRef.current.spy + ev.clientY - dragRef.current.sy })\r\n }\r\n const stopDrag = () => {\r\n dragRef.current.active = false\r\n document.removeEventListener('mousemove', onMove)\r\n document.removeEventListener('mouseup', stopDrag)\r\n dragStopRef.current = null\r\n }\r\n dragStopRef.current = stopDrag\r\n document.addEventListener('mousemove', onMove); document.addEventListener('mouseup', stopDrag)\r\n }, [pos])\r\n\r\n // A drag ended by closing the editor never fires mouseup; drop the listeners\r\n // here so they cannot outlive this component.\r\n useEffect(() => () => { dragStopRef.current?.() }, [])\r\n\r\n const onWheelCb = useCallback((e: WheelEvent) => {\r\n e.preventDefault()\r\n movedRef.current = false\r\n const el = containerRef.current\r\n if (!el) return\r\n const rect = el.getBoundingClientRect()\r\n // Anchor the zoom at the preview center so the mouse position never\r\n // steers where the image grows/shrinks — the current view stays centered.\r\n const mx = rect.width / 2, my = rect.height / 2\r\n // 3% per wheel step (0.97 zoom-out / 1.03 zoom-in).\r\n const factor = e.deltaY > 0 ? 0.97 : 1.03\r\n // Read the live view from the mirror instead of closing over zoom/pos: that\r\n // keeps this handler identity-stable, so it is bound once rather than torn\r\n // down and re-bound on every zoom/pan frame.\r\n const { zoom: z, pos: p } = viewRef.current\r\n const nz = clampZoom(z * factor)\r\n const nx = mx - (mx - p.x) * (nz / z)\r\n const ny = my - (my - p.y) * (nz / z)\r\n setZoom(nz); setPos({ x: nx, y: ny })\r\n }, [])\r\n\r\n // ── Touch: one finger pans the preview, two fingers pinch-zoom (dragging them\r\n // together pans at the same time). Three things are deliberate here:\r\n //\r\n // 1. The listeners hang off the OVERLAY, not the preview card. The card is\r\n // only ~75% of a phone's width, so a pinch whose fingers land on the dimmed\r\n // backdrop — the common case on a phone — used to be handed straight to the\r\n // browser, which zoomed the page instead of the picture. Touch events\r\n // bubble, and `TouchEvent.touches` lists every finger on the surface rather\r\n // than only the target's own, so listening on the overlay also lets a pinch\r\n // with one finger on the card and one on the backdrop work.\r\n // 2. They are attached natively with passive:false: React registers touchmove\r\n // passively at the root, where preventDefault is a no-op — the page would\r\n // pan and browser-zoom behind the open editor. A jsx onTouchMove prop\r\n // cannot fix that, since it rides the same passive root listener.\r\n // 3. A one-finger pan only starts on the preview itself, so dragging the\r\n // backdrop still reads as a tap-outside-to-close rather than silently\r\n // shoving the wallpaper around.\r\n const onTouchStartCb = useCallback((e: TouchEvent) => {\r\n const card = containerRef.current\r\n if (!card) return\r\n movedRef.current = false\r\n if (e.touches.length >= 2) {\r\n // A second finger takes over from the pan and opens a pinch.\r\n touchDragRef.current = null\r\n const rect = card.getBoundingClientRect()\r\n const a = e.touches[0], b = e.touches[1]\r\n pinchRef.current = {\r\n dist: Math.hypot(a.clientX - b.clientX, a.clientY - b.clientY),\r\n zoom: viewRef.current.zoom,\r\n cx: (a.clientX + b.clientX) / 2 - rect.left,\r\n cy: (a.clientY + b.clientY) / 2 - rect.top,\r\n px: viewRef.current.pos.x, py: viewRef.current.pos.y,\r\n }\r\n return\r\n }\r\n if (e.touches.length === 1) {\r\n // Start (or restart) a one-finger pan from the live transform.\r\n pinchRef.current = null\r\n if (!card.contains(e.target as Node)) { touchDragRef.current = null; return }\r\n const tp = e.touches[0]\r\n touchDragRef.current = { sx: tp.clientX, sy: tp.clientY, spx: viewRef.current.pos.x, spy: viewRef.current.pos.y }\r\n }\r\n }, [])\r\n\r\n const onTouchMoveCb = useCallback((e: TouchEvent) => {\r\n const card = containerRef.current\r\n if (!card) return\r\n if (e.touches.length >= 2 && pinchRef.current !== null) {\r\n e.preventDefault()\r\n movedRef.current = true\r\n const p = pinchRef.current\r\n // A zero spread (two fingers detected at one point) has no scale to derive.\r\n if (p.dist <= 0) return\r\n const rect = card.getBoundingClientRect()\r\n const a = e.touches[0], b = e.touches[1]\r\n const dist = Math.hypot(a.clientX - b.clientX, a.clientY - b.clientY)\r\n const cx = (a.clientX + b.clientX) / 2 - rect.left\r\n const cy = (a.clientY + b.clientY) / 2 - rect.top\r\n const nz = clampZoom(p.zoom * (dist / p.dist))\r\n // Keep the image point that started under the fingers pinned to them:\r\n // at gesture start it sat at base coord (c0 - t0)/z0, and after zooming\r\n // to z1 the offset must place it back under the current midpoint. Both\r\n // the scale change AND a two-finger drag fall out of this one relation.\r\n setZoom(nz)\r\n setPos({ x: cx - ((p.cx - p.px) / p.zoom) * nz, y: cy - ((p.cy - p.py) / p.zoom) * nz })\r\n return\r\n }\r\n if (e.touches.length === 1 && touchDragRef.current !== null) {\r\n e.preventDefault()\r\n const d = touchDragRef.current\r\n const tp = e.touches[0]\r\n if (Math.abs(tp.clientX - d.sx) > 4 || Math.abs(tp.clientY - d.sy) > 4) movedRef.current = true\r\n setPos({ x: d.spx + tp.clientX - d.sx, y: d.spy + tp.clientY - d.sy })\r\n }\r\n }, [])\r\n\r\n const onTouchEndCb = useCallback((e: TouchEvent) => {\r\n if (e.touches.length === 1) {\r\n // Two fingers → one: re-baseline the pan against the finger left down,\r\n // or lifting one finger would snap the picture back by its offset.\r\n const tp = e.touches[0]\r\n touchDragRef.current = { sx: tp.clientX, sy: tp.clientY, spx: viewRef.current.pos.x, spy: viewRef.current.pos.y }\r\n pinchRef.current = null\r\n } else if (e.touches.length === 0) {\r\n touchDragRef.current = null\r\n pinchRef.current = null\r\n }\r\n }, [])\r\n\r\n // Bound once the overlay node exists — see the note on `overlayEl` above for\r\n // why keying this off a plain ref silently attached nothing.\r\n useEffect(() => {\r\n if (!overlayEl) return\r\n const noPageGesture = (e: Event): void => e.preventDefault()\r\n overlayEl.addEventListener('wheel', onWheelCb, { passive: false })\r\n overlayEl.addEventListener('touchstart', onTouchStartCb, { passive: false })\r\n overlayEl.addEventListener('touchmove', onTouchMoveCb, { passive: false })\r\n overlayEl.addEventListener('touchend', onTouchEndCb, { passive: false })\r\n overlayEl.addEventListener('touchcancel', onTouchEndCb, { passive: false })\r\n // WebKit's legacy page-zoom gestures (iOS). touch-action:none covers modern\r\n // iOS by itself; this is insurance for older in-app WebViews, where a\r\n // two-finger pinch would otherwise still scale the whole viewport.\r\n overlayEl.addEventListener('gesturestart', noPageGesture, { passive: false })\r\n overlayEl.addEventListener('gesturechange', noPageGesture, { passive: false })\r\n overlayEl.addEventListener('gestureend', noPageGesture, { passive: false })\r\n return () => {\r\n overlayEl.removeEventListener('wheel', onWheelCb)\r\n overlayEl.removeEventListener('touchstart', onTouchStartCb)\r\n overlayEl.removeEventListener('touchmove', onTouchMoveCb)\r\n overlayEl.removeEventListener('touchend', onTouchEndCb)\r\n overlayEl.removeEventListener('touchcancel', onTouchEndCb)\r\n overlayEl.removeEventListener('gesturestart', noPageGesture)\r\n overlayEl.removeEventListener('gesturechange', noPageGesture)\r\n overlayEl.removeEventListener('gestureend', noPageGesture)\r\n }\r\n }, [overlayEl, onWheelCb, onTouchStartCb, onTouchMoveCb, onTouchEndCb])\r\n\r\n const resetView = useCallback(() => {\r\n if (imgSize.w === 0) return\r\n setZoom(1); setPos({ x: (pw - imgSize.w) / 2, y: (ph - imgSize.h) / 2 })\r\n }, [pw, ph, imgSize])\r\n\r\n return (\r\n <Portal>\r\n <div\r\n ref={setOverlayEl}\r\n className=\"dab-overlay\"\r\n style={{\r\n // The modal owns every gesture inside it: without this, a pinch or a\r\n // drag started on the dimmed backdrop is claimed by the browser, which\r\n // pinches the viewport and rubber-bands the page behind the editor.\r\n // Scoped to this overlay rather than the shared .dab-overlay class —\r\n // the color picker shares that class and must stay scrollable.\r\n touchAction: 'none', overscrollBehavior: 'contain',\r\n }}\r\n onClick={e => {\r\n // A pan that ended on the backdrop would otherwise fire a click whose\r\n // target is the nearest common ancestor — the overlay — and close the\r\n // editor, throwing away the adjustment mid-drag.\r\n if (movedRef.current) { movedRef.current = false; return }\r\n if (e.target === e.currentTarget) onClose()\r\n }}\r\n onMouseDown={() => { movedRef.current = false }}\r\n >\r\n <div className=\"dab-overlay-title\">{t('editorTitle')}</div>\r\n <div ref={containerRef} className=\"dab-modal-card\" style={{\r\n position: 'relative', overflow: 'hidden', border: '2px solid rgba(255,255,255,0.3)',\r\n borderRadius: 12, background: '#000', cursor: 'grab', width: pw, height: ph,\r\n // Hand the area's default pan/pinch gestures to the touch handlers\r\n // above: without this the page scrolls and the browser pinch-zooms\r\n // the viewport instead of scaling the picture.\r\n touchAction: 'none', WebkitUserSelect: 'none', userSelect: 'none',\r\n }} onMouseDown={onDown}>\r\n <img ref={imgRef} src={url} alt=\"\" draggable={false} style={{\r\n position: 'absolute', transformOrigin: '0 0', pointerEvents: 'none',\r\n width: imgSize.w, height: imgSize.h,\r\n transform: `translate(${pos.x}px,${pos.y}px) scale(${zoom})`,\r\n }} />\r\n </div>\r\n <div className=\"dab-overlay-hint\">{t('editorHint')}</div>\r\n <div style={{ display: 'flex', gap: 10 }}>\r\n <button type=\"button\" className=\"dab-btn\" onClick={resetView}>{t('editorReset')}</button>\r\n <button type=\"button\" className=\"dab-btn\" onClick={onClose}>{t('editorCancel')}</button>\r\n <button type=\"button\" className=\"dab-btn\" onClick={() => onCommit(zoom, (pos.x + imgSize.w * zoom / 2) / pw, (pos.y + imgSize.h * zoom / 2) / ph, imgRef.current?.naturalWidth ?? 0, imgRef.current?.naturalHeight ?? 0)}>{t('editorCommit')}</button>\r\n </div>\r\n </div>\r\n </Portal>\r\n )\r\n}\r\n","import { useEffect, useRef, useState } from 'react'\r\nimport type { CSSProperties } from 'react'\r\nimport type { ThemeSectionProps, ThemeStoreState, BackgroundType, GeneratedBgParams, BgMode } from '../../types'\r\nimport { cfg, rWop, rBl, rBgMode } from '../../state'\r\nimport { saveConfig, setWallpaperFromUrl, uploadWallpaper, uploadRefusalText, WALLPAPER_SERVE_URL } from '../../rpc'\r\nimport { applyWp, setWpOpacity, setWpBlur, pauseGeneratedBg, resumeGeneratedBg } from '../../wallpaper'\r\nimport { defaultParamsFor } from '../../utils/bg-generators'\r\nimport { BgEditor } from '../BgEditor'\r\nimport { LiveSlider } from '../LiveSlider'\r\nimport { LockIcon, CheckIcon, PhotoIcon, RefreshIcon, SparkleIcon, TrashIcon, UploadIcon, EditIcon, VideoIcon, LinkIcon, PlusIcon, XIcon, PlayIcon, PauseIcon } from '../icons'\r\n\r\nconst SEG_W = 108\r\nconst BG_MODES: Array<{ mode: BgMode; labelKey: string }> = [\r\n { mode: 'fit', labelKey: 'bgModeFit' },\r\n { mode: 'fill', labelKey: 'bgModeFill' },\r\n { mode: 'stretch', labelKey: 'bgModeStretch' },\r\n { mode: 'tile', labelKey: 'bgModeTile' },\r\n { mode: 'center', labelKey: 'bgModeCenter' },\r\n]\r\n\r\nexport function BackgroundPage({ p, notify }: { p: ThemeSectionProps; notify: (msg: string, ok?: boolean) => void }) {\r\n const { t, setWpFromServer, setVideo, setWop, setBl, setBgType, setGeneratedBg, regenerateBg, setRegenerateOnReload, setRotation, addRotationItems, removeRotationItem, rotateNow, setVideoFromUrl, useStore } = p\r\n // Field-level store subscriptions: dragging sliders / picking colors changes\r\n // only the color fields, and the background page has no reason to re-render\r\n // for those — full-state subscription re-renders this whole page (hero img,\r\n // thumbnails, sliders) on every unrelated store write.\r\n const storeUrl = useStore((s: ThemeStoreState) => s.url)\r\n const backgroundType = useStore((s: ThemeStoreState) => s.backgroundType)\r\n const generatedBg = useStore((s: ThemeStoreState) => s.generatedBg)\r\n const regenerateOnReload = useStore((s: ThemeStoreState) => s.regenerateOnReload)\r\n const rotation = useStore((s: ThemeStoreState) => s.rotation)\r\n\r\n const fileRef = useRef<HTMLInputElement>(null)\r\n const rotFileRef = useRef<HTMLInputElement>(null)\r\n const [editorOpen, setEditorOpen] = useState(false)\r\n const [dragOver, setDragOver] = useState(false)\r\n const [spinTick, setSpinTick] = useState(0)\r\n const [rotBusy, setRotBusy] = useState(false)\r\n const [urlOpen, setUrlOpen] = useState(false)\r\n const [urlVal, setUrlVal] = useState('')\r\n const [urlBusy, setUrlBusy] = useState(false)\r\n const [urlErr, setUrlErr] = useState<string | null>(null)\r\n // Layout mode is owned by cfg (persisted on click); local mirror only so\r\n // the chip row re-renders on selection. It must re-derive from cfg whenever\r\n // the store's bgRev moves: importTheme rewrites cfg.bgMode through\r\n // adoptConfig without touching this local state, which would otherwise leave\r\n // the chips — and the `mode === 'fit'` editor gate below — showing the\r\n // abandoned layout mode.\r\n const bgRev = useStore((s: ThemeStoreState) => s.bgRev)\r\n const [mode, setModeState] = useState<BgMode>(rBgMode())\r\n useEffect(() => { setModeState(rBgMode()) }, [bgRev])\r\n\r\n const isVideo = backgroundType === 'video'\r\n const isStatic = backgroundType === 'image' || isVideo\r\n const isGenerated = !isStatic\r\n const activeGenType: Exclude<BackgroundType, 'image' | 'video'> = isGenerated && generatedBg ? generatedBg.type : 'mesh'\r\n\r\n // Session-only pause state; any controller swap (type switch, regenerate)\r\n // recreates the loop running, so reset the button to match.\r\n const [paused, setPaused] = useState(false)\r\n const genPreset = generatedBg !== null && generatedBg.type !== 'mesh' ? generatedBg.preset : undefined\r\n useEffect(() => { setPaused(false) }, [activeGenType, genPreset, generatedBg?.seed])\r\n\r\n const onFileSelect = async (f: File): Promise<void> => {\r\n if (f.type.startsWith('video/')) {\r\n // Hand the raw file over directly: it streams to disk over the\r\n // binary upload route. A data-URL detour would inflate the bytes by a\r\n // third (base64) and blow the RPC body limit on large clips. The clip\r\n // plays from a local object URL straight away, so only a refusal of the\r\n // background upload needs saying — silently it would just fail to persist\r\n // and be gone after a reload.\r\n const outcome = await setVideo(f, f.type)\r\n if (!outcome.ok) notify(uploadRefusalText(outcome, t, 'videoUploadFail'), false)\r\n return\r\n }\r\n // Stream the original bytes straight to disk (no base64 round-trip, no\r\n // re-encoding), then point the wallpaper at the serve URL. The browser\r\n // decodes it natively like any <img>.\r\n const outcome = await uploadWallpaper(f)\r\n if (outcome.ok) setWpFromServer(WALLPAPER_SERVE_URL)\r\n else notify(uploadRefusalText(outcome, t, 'bgUploadFail'), false)\r\n }\r\n\r\n const onDrop = (e: React.DragEvent) => {\r\n e.preventDefault()\r\n setDragOver(false)\r\n const f = e.dataTransfer.files?.[0]\r\n if (f && (f.type.startsWith('image/') || f.type.startsWith('video/'))) void onFileSelect(f)\r\n }\r\n\r\n const applyUrl = async () => {\r\n const u = urlVal.trim()\r\n if (!/^https?:\\/\\//i.test(u)) { setUrlErr(t('bgUrlBadHttp')); return }\r\n setUrlBusy(true)\r\n setUrlErr(null)\r\n const r = await setWallpaperFromUrl(u)\r\n if (r.ok) {\r\n // The host already replaced the local wallpaper file; just switch the\r\n // theme to image mode and point the display at the serve URL.\r\n setWpFromServer(r.wallpaperUrl ?? null)\r\n setUrlOpen(false)\r\n setUrlVal('')\r\n } else if (r.error === 'not an image') {\r\n // A video URL: stream it into the video slot through the server and\r\n // play from the serve route.\r\n const ok = await setVideoFromUrl(u)\r\n if (ok) {\r\n setUrlOpen(false)\r\n setUrlVal('')\r\n } else {\r\n setUrlErr(t('bgUrlVideoFail'))\r\n }\r\n } else {\r\n setUrlErr(r.error === 'invalid url' || r.error === 'unsupported scheme'\r\n ? t('bgUrlBadHttp')\r\n : (r.error ?? t('bgUrlFail')))\r\n }\r\n setUrlBusy(false)\r\n }\r\n\r\n const switchToStatic = () => {\r\n if (isStatic) return\r\n setBgType(isVideo || cfg.videoMime !== null ? 'video' : 'image')\r\n }\r\n\r\n const setMode = (m: BgMode) => {\r\n if (m === mode) return\r\n setModeState(m)\r\n cfg.bgMode = m\r\n applyWp()\r\n saveConfig()\r\n }\r\n\r\n const setGenType = (type: Exclude<BackgroundType, 'image' | 'video'>) => {\r\n if (type === activeGenType) return\r\n setPaused(false)\r\n setBgType(type)\r\n }\r\n\r\n const ensureGenParams = (): GeneratedBgParams => generatedBg ?? defaultParamsFor(activeGenType)\r\n\r\n const updateGenerated = (patch: Partial<GeneratedBgParams>) => {\r\n // Any parameter change rebuilds the live controller, which restarts the\r\n // animation loop — reset the paused state so the button stays truthful.\r\n setPaused(false)\r\n setGeneratedBg({ ...ensureGenParams(), ...patch } as GeneratedBgParams)\r\n }\r\n\r\n const typeMeta: Array<{ type: Exclude<BackgroundType, 'image' | 'video'>; labelKey: string; descKey: string; thumb: string }> = [\r\n { type: 'mesh', labelKey: 'bgTypeMesh', descKey: 'bgMeshDesc', thumb: 'dab-thumb-mesh' },\r\n { type: 'shader', labelKey: 'bgTypeShader', descKey: 'bgShaderDesc', thumb: 'dab-thumb-shader' },\r\n { type: 'pattern', labelKey: 'bgTypePattern', descKey: 'bgPatternDesc', thumb: 'dab-thumb-pattern' },\r\n ]\r\n\r\n const presetLabel = (key: string) => {\r\n switch (key) {\r\n case 'aurora': return t('presetAurora')\r\n case 'nebula': return t('presetNebula')\r\n case 'noise': return t('presetNoise')\r\n case 'starfield': return t('presetStarfield')\r\n case 'dots': return t('presetDots')\r\n case 'waves': return t('presetWaves')\r\n case 'poly': return t('presetPoly')\r\n case 'rain': return t('presetRain')\r\n case 'contour': return t('presetContour')\r\n case 'meta': return t('presetMeta')\r\n default: return key\r\n }\r\n }\r\n\r\n return (\r\n <>\r\n <header className=\"dab-head dab-rise\" style={{ '--d': 0 } as CSSProperties}>\r\n <div className=\"dab-overline\">Canvas</div>\r\n <h2 className=\"dab-h1\">{t('bgTitle')}</h2>\r\n <p className=\"dab-desc\">{t('descBackground')}</p>\r\n </header>\r\n\r\n {/* Preview hero with hover veil */}\r\n <section className=\"dab-rise\" style={{ '--d': 1 } as CSSProperties}>\r\n <div className=\"dab-hero\">\r\n {storeUrl ? (\r\n <>\r\n <img className=\"dab-hero-img\" src={storeUrl} alt=\"\" draggable={false} />\r\n {isGenerated ? (\r\n <span className=\"dab-hero-badge\"><SparkleIcon size={11} />{t('liveBadge')}</span>\r\n ) : isVideo ? (\r\n <span className=\"dab-hero-badge\"><VideoIcon size={11} />{t('bgVideoBadge')}</span>\r\n ) : null}\r\n <div className=\"dab-hero-veil\">\r\n {isStatic && storeUrl ? (\r\n <button type=\"button\" className=\"dab-btn\" disabled={mode !== 'fit'}\r\n title={mode !== 'fit' ? t('bgEditLocked') : undefined}\r\n onClick={() => setEditorOpen(true)}>\r\n <EditIcon size={13} />{t('bgEdit')}\r\n </button>\r\n ) : isGenerated ? (\r\n <button type=\"button\" className=\"dab-btn\" onClick={() => { setPaused(false); regenerateBg(); setSpinTick(x => x + 1) }}>\r\n <RefreshIcon size={13} />{t('bgRegenerate')}\r\n </button>\r\n ) : null}\r\n <button type=\"button\" className=\"dab-btn dab-btn-danger\" onClick={() => setWpFromServer(null)}>\r\n <TrashIcon size={13} />{t('bgRemove')}\r\n </button>\r\n </div>\r\n </>\r\n ) : (\r\n <button\r\n type=\"button\"\r\n className={`dab-hero-empty${dragOver ? ' is-over' : ''}`}\r\n onClick={() => fileRef.current?.click()}\r\n onDragOver={e => { e.preventDefault(); setDragOver(true) }}\r\n onDragLeave={() => setDragOver(false)}\r\n onDrop={onDrop}>\r\n <UploadIcon size={20} />\r\n <span>{t('dropHint')}</span>\r\n </button>\r\n )}\r\n </div>\r\n </section>\r\n\r\n {/* Source segmented control */}\r\n <section className=\"dab-rise\" style={{ '--d': 2 } as CSSProperties}>\r\n <div className=\"dab-seg\" style={{ '--w': `${SEG_W}px` } as CSSProperties}>\r\n <div className=\"dab-seg-thumb\" style={{ transform: `translateX(${isGenerated ? SEG_W : 0}px)` }} />\r\n <button type=\"button\" className={`dab-seg-item${!isGenerated ? ' is-active' : ''}`} onClick={switchToStatic}>\r\n <PhotoIcon size={14} />{t('bgSourceImage')}\r\n </button>\r\n <button type=\"button\" className={`dab-seg-item${isGenerated ? ' is-active' : ''}`}\r\n onClick={() => { if (!isGenerated) setBgType(generatedBg?.type ?? 'mesh') }}>\r\n <SparkleIcon size={14} />{t('bgSourceGenerated')}\r\n </button>\r\n </div>\r\n </section>\r\n\r\n {/* Mode content */}\r\n {!isGenerated ? (\r\n <>\r\n <section className=\"dab-card dab-card-hover dab-rise\" style={{ '--d': 3 } as CSSProperties}>\r\n <div className=\"dab-chip-row\">\r\n <button type=\"button\" className=\"dab-btn dab-btn-primary\" onClick={() => fileRef.current?.click()}>\r\n <UploadIcon size={14} />{t('bgChoose')}\r\n </button>\r\n <button type=\"button\" className=\"dab-btn dab-btn-soft\" onClick={() => setUrlOpen(o => !o)}>\r\n <LinkIcon size={14} />{t('bgFromUrl')}\r\n </button>\r\n {storeUrl || isVideo ? (\r\n <>\r\n {isStatic && storeUrl ? (\r\n <button type=\"button\" className=\"dab-btn\" disabled={mode !== 'fit'}\r\n title={mode !== 'fit' ? t('bgEditLocked') : undefined}\r\n onClick={() => setEditorOpen(true)}>\r\n <EditIcon size={14} />{t('bgEdit')}\r\n </button>\r\n ) : null}\r\n <button type=\"button\" className=\"dab-btn dab-btn-danger-inverted\" onClick={() => setWpFromServer(null)}>\r\n <TrashIcon size={14} />{t('bgRemove')}\r\n </button>\r\n </>\r\n ) : null}\r\n </div>\r\n {urlOpen ? (\r\n <div className=\"dab-urlrow\">\r\n <input type=\"text\" className=\"dab-urlinput\" value={urlVal} placeholder={t('bgUrlPlaceholder')}\r\n onChange={e => setUrlVal(e.target.value)}\r\n onKeyDown={e => { if (e.key === 'Enter') { e.preventDefault(); void applyUrl() } }}\r\n autoFocus />\r\n <button type=\"button\" className=\"dab-btn dab-btn-primary\" disabled={urlBusy} onClick={() => void applyUrl()}>\r\n {urlBusy ? t('bgUrlApplying') : t('bgUrlApply')}\r\n </button>\r\n <button type=\"button\" className=\"dab-btn\" onClick={() => { setUrlOpen(false); setUrlVal(''); setUrlErr(null) }}>\r\n {t('bgUrlCancel')}\r\n </button>\r\n </div>\r\n ) : null}\r\n {urlErr ? (\r\n <p className=\"dab-urlerr\" style={{ marginTop: 8, color: 'var(--dsw-alias-state-error-primary)', fontSize: 12 }}>{urlErr}</p>\r\n ) : null}\r\n {/* Adaptive placement for image/video backgrounds. \"fit\" keeps the\r\n editor-committed framing; the pan/zoom editor only applies there. */}\r\n <div style={{ marginTop: 16 }}>\r\n <div className=\"dab-swatch-title\">{t('bgModeTitle')}</div>\r\n <div className=\"dab-chip-row\">\r\n {BG_MODES.map(m => (\r\n <button key={m.mode} type=\"button\" className={`dab-chip${mode === m.mode ? ' is-active' : ''}`}\r\n onClick={() => setMode(m.mode)}>\r\n {t(m.labelKey)}\r\n </button>\r\n ))}\r\n </div>\r\n </div>\r\n </section>\r\n\r\n {/* Wallpaper rotation pool */}\r\n <section className=\"dab-card dab-rise\" style={{ '--d': 4 } as CSSProperties}>\r\n <div className=\"dab-row-head\">\r\n <div className=\"dab-swatch-title\" style={{ marginBottom: 0 }}>{t('rotTitle')}</div>\r\n <button type=\"button\" className={`dab-toggle${rotation.enabled ? ' is-on' : ''}`} role=\"switch\" aria-checked={rotation.enabled}\r\n onClick={() => setRotation({ enabled: !rotation.enabled })}>\r\n <span className=\"dab-toggle-knob\" />\r\n </button>\r\n </div>\r\n <p className=\"dab-hint\" style={{ marginTop: 8 }}>{t('rotHint')}</p>\r\n <div className=\"dab-thumbstrip\">\r\n {rotation.items.map((it, i) => (\r\n <div key={it.file} className={`dab-thumb${rotation.enabled && i === rotation.current ? ' is-current' : ''}`}>\r\n {it.thumb ? <img src={it.thumb} alt=\"\" draggable={false} /> : <PhotoIcon size={15} />}\r\n <button type=\"button\" className=\"dab-thumb-x\" title={t('rotRemove')}\r\n disabled={rotBusy} onClick={() => { setRotBusy(true); void removeRotationItem(i).finally(() => setRotBusy(false)) }}>\r\n <XIcon size={10} />\r\n </button>\r\n </div>\r\n ))}\r\n <button type=\"button\" className=\"dab-thumb dab-thumb-add\" title={t('rotAdd')} disabled={rotBusy}\r\n onClick={() => rotFileRef.current?.click()}>\r\n <PlusIcon size={16} />\r\n </button>\r\n </div>\r\n {rotation.items.length > 0 ? (\r\n <div className=\"dab-chip-row\" style={{ marginTop: 12 }}>\r\n <button type=\"button\" className={`dab-chip${rotation.mode === 'shuffle' ? ' is-active' : ''}`}\r\n onClick={() => setRotation({ mode: 'shuffle' })}>{t('rotShuffle')}</button>\r\n <button type=\"button\" className={`dab-chip${rotation.mode === 'order' ? ' is-active' : ''}`}\r\n onClick={() => setRotation({ mode: 'order' })}>{t('rotOrder')}</button>\r\n <span className=\"dab-chip-sep\" />\r\n <button type=\"button\" className={`dab-chip${rotation.interval === 'reload' ? ' is-active' : ''}`}\r\n onClick={() => setRotation({ interval: 'reload' })}>{t('rotReload')}</button>\r\n <button type=\"button\" className={`dab-chip${rotation.interval === 'daily' ? ' is-active' : ''}`}\r\n onClick={() => setRotation({ interval: 'daily' })}>{t('rotDaily')}</button>\r\n <button type=\"button\" className={`dab-chip${rotation.interval === 'weekly' ? ' is-active' : ''}`}\r\n onClick={() => setRotation({ interval: 'weekly' })}>{t('rotWeekly')}</button>\r\n <button type=\"button\" className=\"dab-btn\" disabled={rotBusy}\r\n onClick={() => { setRotBusy(true); void rotateNow().finally(() => setRotBusy(false)) }}>\r\n <RefreshIcon size={13} />{t('rotNow')}\r\n </button>\r\n </div>\r\n ) : null}\r\n <input ref={rotFileRef} type=\"file\" accept=\"image/*\" multiple style={{ display: 'none' }} onChange={e => {\r\n const files = Array.from(e.target.files ?? [])\r\n e.target.value = ''\r\n if (files.length === 0) return\r\n setRotBusy(true)\r\n void addRotationItems(files).finally(() => setRotBusy(false))\r\n }} />\r\n </section>\r\n </>\r\n ) : (\r\n <section className=\"dab-card dab-rise\" style={{ '--d': 3 } as CSSProperties}>\r\n {/* Type cards with animated thumbnails */}\r\n <div className=\"dab-types\">\r\n {typeMeta.map((m, i) => (\r\n <button key={m.type} type=\"button\" className={`dab-type${activeGenType === m.type ? ' is-active' : ''}`}\r\n style={{ '--i': i } as CSSProperties} onClick={() => setGenType(m.type)}>\r\n <div className={`dab-type-thumb ${m.thumb}`} />\r\n <div className=\"dab-type-name\">{t(m.labelKey)}</div>\r\n <div className=\"dab-type-desc\">{t(m.descKey)}</div>\r\n <span className=\"dab-type-check\"><CheckIcon size={11} /></span>\r\n </button>\r\n ))}\r\n </div>\r\n\r\n {/* Presets (shader / pattern) */}\r\n {activeGenType === 'shader' && generatedBg?.type === 'shader' ? (\r\n <div style={{ marginTop: 14 }}>\r\n <div className=\"dab-swatch-title\">{t('bgShaderPreset')}</div>\r\n <div className=\"dab-chip-row\">\r\n {(['aurora', 'nebula', 'noise', 'starfield'] as const).map(pr => (\r\n <button key={pr} type=\"button\" className={`dab-chip${generatedBg.preset === pr ? ' is-active' : ''}`}\r\n onClick={() => updateGenerated({ preset: pr })}>\r\n {presetLabel(pr)}\r\n </button>\r\n ))}\r\n </div>\r\n </div>\r\n ) : null}\r\n\r\n {activeGenType === 'pattern' && generatedBg?.type === 'pattern' ? (\r\n <div style={{ marginTop: 14 }}>\r\n <div className=\"dab-swatch-title\">{t('bgPatternPreset')}</div>\r\n <div className=\"dab-chip-row\">\r\n {(['dots', 'waves', 'poly', 'rain', 'contour', 'meta'] as const).map(pr => (\r\n <button key={pr} type=\"button\" className={`dab-chip${generatedBg.preset === pr ? ' is-active' : ''}`}\r\n onClick={() => updateGenerated({ preset: pr })}>\r\n {presetLabel(pr)}\r\n </button>\r\n ))}\r\n </div>\r\n </div>\r\n ) : null}\r\n\r\n {/* Parameter sliders */}\r\n <div style={{ marginTop: 16 }}>\r\n {activeGenType === 'mesh' && generatedBg?.type === 'mesh' ? (\r\n <>\r\n <LiveSlider label={t('bgMeshScale')} min={30} max={300} step={1} def={Math.round(generatedBg.scale * 100)}\r\n fmt={v => `${v}%`} onChange={v => updateGenerated({ scale: v / 100 })} />\r\n <LiveSlider label={t('bgMeshIntensity')} min={0} max={100} step={1} def={Math.round(generatedBg.intensity * 100)}\r\n fmt={v => `${v}%`} onChange={v => updateGenerated({ intensity: v / 100 })} />\r\n </>\r\n ) : null}\r\n {activeGenType === 'shader' && generatedBg?.type === 'shader' ? (\r\n <>\r\n <LiveSlider label={t('bgShaderSpeed')} min={0} max={200} step={1} def={Math.round(generatedBg.speed * 100)}\r\n fmt={v => `${v}%`} onChange={v => updateGenerated({ speed: v / 100 })} />\r\n <LiveSlider label={t('bgShaderScale')} min={30} max={300} step={1} def={Math.round(generatedBg.scale * 100)}\r\n fmt={v => `${v}%`} onChange={v => updateGenerated({ scale: v / 100 })} />\r\n </>\r\n ) : null}\r\n {activeGenType === 'pattern' && generatedBg?.type === 'pattern' ? (\r\n <>\r\n <LiveSlider label={t('bgPatternDensity')} min={0} max={100} step={1} def={Math.round(generatedBg.density * 100)}\r\n fmt={v => `${v}%`} onChange={v => updateGenerated({ density: v / 100 })} />\r\n <LiveSlider label={t('bgPatternScale')} min={30} max={300} step={1} def={Math.round(generatedBg.scale * 100)}\r\n fmt={v => `${v}%`} onChange={v => updateGenerated({ scale: v / 100 })} />\r\n </>\r\n ) : null}\r\n </div>\r\n\r\n {/* Seed lock + regenerate + pause */}\r\n <div className=\"dab-seed\">\r\n <span className=\"dab-seed-ico\"><LockIcon size={15} /></span>\r\n <div className=\"dab-seed-txt\">\r\n <div className=\"dab-seed-title\">{t('seedLock')}</div>\r\n <div className=\"dab-seed-desc\">{!regenerateOnReload ? t('bgSeedLocked') : t('bgSeedUnlocked')}</div>\r\n </div>\r\n <button type=\"button\" className={`dab-toggle${!regenerateOnReload ? ' is-on' : ''}`}\r\n role=\"switch\" aria-checked={!regenerateOnReload}\r\n onClick={() => setRegenerateOnReload(!regenerateOnReload)}>\r\n <span className=\"dab-toggle-knob\" />\r\n </button>\r\n <button type=\"button\" className=\"dab-btn\" onClick={() => {\r\n if (paused) { resumeGeneratedBg(); setPaused(false) }\r\n else { pauseGeneratedBg(); setPaused(true) }\r\n }}>\r\n {paused ? <PlayIcon size={13} /> : <PauseIcon size={13} />}{paused ? t('bgResume') : t('bgPause')}\r\n </button>\r\n <button type=\"button\" className=\"dab-btn dab-btn-primary\" onClick={() => { regenerateBg(); setPaused(false); setSpinTick(x => x + 1) }}>\r\n <span key={spinTick} className=\"dab-spin\" style={{ display: 'grid' }}><RefreshIcon size={13} /></span>\r\n {t('bgRegenerate')}\r\n </button>\r\n </div>\r\n </section>\r\n )}\r\n\r\n {/* Global wallpaper adjustments */}\r\n <section className=\"dab-card dab-card-hover dab-rise\" style={{ '--d': 5 } as CSSProperties}>\r\n <LiveSlider label={t('wpOpacity')} min={0} max={100} step={1} def={Math.round(rWop() * 100)}\r\n fmt={v => `${v}%`}\r\n onInput={v => { const op = v / 100; cfg.wallpaperOpacity = op; setWpOpacity(op); saveConfig() }}\r\n onChange={v => setWop(v / 100)} />\r\n <LiveSlider label={t('bgBlur')} min={0} max={60} step={1} def={rBl()}\r\n fmt={v => `${v}px`}\r\n onInput={v => { cfg.blur = v; setWpBlur(v); saveConfig() }}\r\n onChange={v => setBl(v)} />\r\n <p className=\"dab-hint\" style={{ marginTop: 12 }}>{t('bgHint')}</p>\r\n </section>\r\n\r\n <input ref={fileRef} type=\"file\" accept=\"image/*,video/*\" style={{ display: 'none' }} onChange={e => {\r\n const f = e.target.files?.[0]; if (!f) return\r\n void onFileSelect(f); e.target.value = ''\r\n }} />\r\n\r\n {/* Background editor modal (image/video + fit mode only). For videos\r\n the reference is the captured frame snapshot — same pixels as the\r\n playing video, so the committed framing maps 1:1 onto the layer. */}\r\n {editorOpen && storeUrl && isStatic && mode === 'fit' ? (\r\n <BgEditor url={storeUrl} t={t} onClose={() => setEditorOpen(false)}\r\n onCommit={(z, x, y, iw, ih) => {\r\n const st = { zoom: z, x, y, iw, ih }\r\n if (backgroundType === 'video') cfg.videoBgState = st\r\n else cfg.bgState = st\r\n applyWp(); saveConfig(); setEditorOpen(false)\r\n }} />\r\n ) : null}\r\n </>\r\n )\r\n}\r\n","import type { PartStrokes, ProfileAppearance, StrokeConfig } from '../types'\r\n\r\n/**\r\n * Built-in appearance presets. Each bundles the surface parameters a profile\r\n * stores (color, per-part opacities/blurs, tints) — never the wallpaper\r\n * itself, which stays machine-local. Applying a preset is identical to\r\n * applying a saved profile.\r\n */\r\nexport interface BuiltinPreset {\r\n key: string\r\n appearance: ProfileAppearance\r\n}\r\n\r\nconst zeroBlurs = { bg: 0, sidebar: 0, card: 0, settings: 0, chat: 0, trajectory: 0, input: 0, panel: 0, produced: 0, header: 0, headerBar: 0 }\r\n\r\n/** Presets ship with strokes off — text outlines are an opt-in look. Fresh\r\n * objects per call so a profile restore can never alias another preset's\r\n * stroke config (applyAppearance copies, but mutation-proofing is free). */\r\nconst zeroStrokes = (): PartStrokes => {\r\n const off = (): StrokeConfig => ({ width: 0, color: 'auto', customColor: '#808080' })\r\n return {\r\n bg: off(), sidebar: off(), card: off(), settings: off(), chat: off(),\r\n trajectory: off(), input: off(), panel: off(), produced: off(), header: off(),\r\n headerBar: off(),\r\n }\r\n}\r\n\r\nexport const BUILTIN_PRESETS: BuiltinPreset[] = [\r\n {\r\n key: 'default',\r\n appearance: {\r\n color: null,\r\n opacities: { bg: 0.85, sidebar: 0.93, card: 1, input: 1 },\r\n blurs: { ...zeroBlurs },\r\n strokes: zeroStrokes(),\r\n settingsOpacity: 1,\r\n wallpaperOpacity: 1,\r\n blur: 0,\r\n chatTextOpacity: 0,\r\n trajectoryOpacity: 1,\r\n panelOpacity: 1,\r\n producedOpacity: 1,\r\n headerOpacity: 1,\r\n headerBarOpacity: 0.85,\r\n },\r\n },\r\n {\r\n // Frosted glass: translucent surfaces over a sharp wallpaper, blurred shell.\r\n key: 'glass',\r\n appearance: {\r\n color: [212, 0.5, 0.38],\r\n opacities: { bg: 0.62, sidebar: 0.55, card: 0.62, input: 0.58 },\r\n blurs: { ...zeroBlurs, bg: 20, sidebar: 14, card: 12, settings: 20, trajectory: 8, input: 14, panel: 12 },\r\n strokes: zeroStrokes(),\r\n settingsOpacity: 0.88,\r\n wallpaperOpacity: 1,\r\n blur: 0,\r\n chatTextOpacity: 0,\r\n trajectoryOpacity: 0.85,\r\n panelOpacity: 0.85,\r\n producedOpacity: 1,\r\n headerOpacity: 1,\r\n headerBarOpacity: 0.62,\r\n },\r\n },\r\n {\r\n // Minimal: near-solid surfaces, no frost, system theme color.\r\n key: 'minimal',\r\n appearance: {\r\n color: null,\r\n opacities: { bg: 0.97, sidebar: 0.97, card: 1, input: 1 },\r\n blurs: { ...zeroBlurs },\r\n strokes: zeroStrokes(),\r\n settingsOpacity: 1,\r\n wallpaperOpacity: 1,\r\n blur: 0,\r\n chatTextOpacity: 0,\r\n trajectoryOpacity: 1,\r\n panelOpacity: 1,\r\n producedOpacity: 1,\r\n headerOpacity: 1,\r\n headerBarOpacity: 0.97,\r\n },\r\n },\r\n {\r\n // Midnight: deep violet accent, dark scheme, heavy frost.\r\n key: 'midnight',\r\n appearance: {\r\n color: [262, 0.45, 0.16],\r\n opacities: { bg: 0.5, sidebar: 0.45, card: 0.55, input: 0.6 },\r\n blurs: { ...zeroBlurs, bg: 24, sidebar: 18, card: 14, settings: 22, trajectory: 10, input: 16, panel: 16 },\r\n strokes: zeroStrokes(),\r\n settingsOpacity: 0.85,\r\n wallpaperOpacity: 0.92,\r\n blur: 2,\r\n chatTextOpacity: 0,\r\n trajectoryOpacity: 0.8,\r\n panelOpacity: 0.8,\r\n producedOpacity: 1,\r\n headerOpacity: 1,\r\n headerBarOpacity: 0.5,\r\n },\r\n },\r\n {\r\n // Cyber: vivid magenta accent over barely-there surfaces.\r\n key: 'cyber',\r\n appearance: {\r\n color: [315, 0.7, 0.22],\r\n opacities: { bg: 0.42, sidebar: 0.5, card: 0.45, input: 0.55 },\r\n blurs: { ...zeroBlurs, bg: 16, sidebar: 12, card: 10, settings: 18, trajectory: 6, input: 20, panel: 18 },\r\n strokes: zeroStrokes(),\r\n settingsOpacity: 0.8,\r\n wallpaperOpacity: 1,\r\n blur: 0,\r\n chatTextOpacity: 0,\r\n trajectoryOpacity: 0.78,\r\n panelOpacity: 0.75,\r\n producedOpacity: 1,\r\n headerOpacity: 1,\r\n headerBarOpacity: 0.42,\r\n },\r\n },\r\n {\r\n // Warm daylight: amber accent, solid light surfaces.\r\n key: 'warm',\r\n appearance: {\r\n color: [28, 0.6, 0.72],\r\n opacities: { bg: 0.92, sidebar: 0.95, card: 1, input: 1 },\r\n blurs: { ...zeroBlurs },\r\n strokes: zeroStrokes(),\r\n settingsOpacity: 1,\r\n wallpaperOpacity: 1,\r\n blur: 0,\r\n chatTextOpacity: 0,\r\n trajectoryOpacity: 1,\r\n panelOpacity: 1,\r\n producedOpacity: 1,\r\n headerOpacity: 1,\r\n headerBarOpacity: 0.92,\r\n },\r\n },\r\n]\r\n","import { useRef, useState } from 'react'\nimport type { CSSProperties } from 'react'\nimport type { ThemeSectionProps, ThemeStoreState, ProfileEntry, ScheduleConfig } from '../../types'\nimport { BUILTIN_PRESETS } from '../../utils/presets'\nimport { hslToRgb } from '../../utils/color'\nimport { DownloadIcon, UploadIcon, CheckIcon, PlusIcon, SunIcon, MoonIcon, ClockIcon } from '../icons'\n\nconst hexOf = (color: [number, number, number] | null): string =>\n color === null\n ? ''\n : '#' + hslToRgb(color[0], color[1], color[2]).map(v => Math.round(v).toString(16).padStart(2, '0')).join('')\n\nfunction ProfileDot({ entry }: { entry: ProfileEntry }) {\n const hex = hexOf(entry.config.color)\n return (\n <span className=\"dab-profile-dot\" style={hex ? { background: hex } : undefined} title={hex ? hex.toUpperCase() : undefined}>\n {hex ? null : <CheckIcon size={11} />}\n </span>\n )\n}\n\nexport function ProfilePage({ p, notify }: { p: ThemeSectionProps; notify: (msg: string, ok?: boolean) => void }) {\n const { t, exportTheme, importTheme, saveProfile, applyProfile, deleteProfile, applyPreset, setSchedule, useStore } = p\n // Field-level subscriptions: profile list, active id and schedule are the only\n // store fields this page renders — full-state subscription would re-render\n // the whole profile list on every unrelated store write (color, wallpaper…).\n const profiles = useStore((s: ThemeStoreState) => s.profiles)\n const schedule = useStore((s: ThemeStoreState) => s.schedule)\n const activeProfile = useStore((s: ThemeStoreState) => s.activeProfile)\n const importRef = useRef<HTMLInputElement>(null)\n const [nameOpen, setNameOpen] = useState(false)\n const [nameVal, setNameVal] = useState('')\n const [confirmId, setConfirmId] = useState<string | null>(null)\n\n const onImport = async (file: File) => {\n try {\n const ok = await importTheme(file)\n notify(ok ? t('importDone') : t('importFail'), ok)\n } catch {\n notify(t('importFail'), false)\n }\n }\n\n const onSave = (): void => {\n const name = nameVal.trim()\n if (!name) return\n if (saveProfile(name)) {\n notify(t('profileSaved'), true)\n setNameVal('')\n setNameOpen(false)\n } else {\n notify(t('profileNameRequired'), false)\n }\n }\n\n const onApply = (entry: ProfileEntry): void => {\n if (applyProfile(entry.id)) notify(t('profileApplied'), true)\n }\n\n const onDelete = (entry: ProfileEntry): void => {\n if (confirmId !== entry.id) { setConfirmId(entry.id); return }\n setConfirmId(null)\n deleteProfile(entry.id)\n }\n\n const profileOptions = (value: string | null, onChange: (id: string | null) => void) => (\n <select className=\"dab-select\" value={value ?? ''} onChange={e => onChange(e.target.value || null)}>\n <option value=\"\">{t('profileNone')}</option>\n {profiles.map(pr => <option key={pr.id} value={pr.id}>{pr.name}</option>)}\n </select>\n )\n\n const patchSchedule = (patch: Partial<ScheduleConfig>): void => setSchedule(patch)\n\n return (\n <>\n <header className=\"dab-head dab-rise\" style={{ '--d': 0 } as CSSProperties}>\n <div className=\"dab-overline\">Profile</div>\n <h2 className=\"dab-h1\">{t('pageProfile')}</h2>\n <p className=\"dab-desc\">{t('descProfile')}</p>\n </header>\n\n {/* Built-in presets */}\n <section className=\"dab-card dab-rise\" style={{ '--d': 1 } as CSSProperties}>\n <div className=\"dab-swatch-title\">{t('presetGalleryTitle')}</div>\n <div className=\"dab-preset-grid\">\n {BUILTIN_PRESETS.map((ps, i) => {\n const hex = hexOf(ps.appearance.color)\n return (\n <button key={ps.key} type=\"button\" className=\"dab-preset\" style={{ '--i': i } as CSSProperties} onClick={() => { applyPreset(ps.appearance); notify(t('presetApplied')) }}>\n <span className=\"dab-preset-dot\" style={hex ? { background: hex } : undefined}>\n {hex ? null : <CheckIcon size={12} />}\n </span>\n <span className=\"dab-preset-name\">{t(`presetName_${ps.key}`)}</span>\n <span className=\"dab-preset-desc\">{t(`presetDesc_${ps.key}`)}</span>\n </button>\n )\n })}\n </div>\n </section>\n\n {/* Saved profiles */}\n <section className=\"dab-card dab-rise\" style={{ '--d': 2 } as CSSProperties}>\n <div className=\"dab-row-head\">\n <div className=\"dab-swatch-title\" style={{ marginBottom: 0 }}>{t('profilesTitle')}</div>\n <button type=\"button\" className=\"dab-btn dab-btn-primary\" onClick={() => setNameOpen(o => !o)}>\n <PlusIcon size={14} />{t('profileSave')}\n </button>\n </div>\n {nameOpen ? (\n <div className=\"dab-urlrow\">\n <input type=\"text\" className=\"dab-urlinput\" value={nameVal} placeholder={t('profileNamePlaceholder')} maxLength={60}\n onChange={e => setNameVal(e.target.value)}\n onKeyDown={e => { if (e.key === 'Enter') { e.preventDefault(); onSave() } }}\n autoFocus />\n <button type=\"button\" className=\"dab-btn dab-btn-primary\" disabled={!nameVal.trim()} onClick={onSave}>{t('editorCommit')}</button>\n <button type=\"button\" className=\"dab-btn\" onClick={() => { setNameOpen(false); setNameVal('') }}>{t('bgUrlCancel')}</button>\n </div>\n ) : null}\n {profiles.length === 0 ? (\n <p className=\"dab-hint\" style={{ marginTop: 10 }}>{t('profilesEmpty')}</p>\n ) : (\n <div className=\"dab-profile-list\">\n {profiles.map((entry, i) => (\n <div key={entry.id} className={`dab-profile-row${activeProfile === entry.id ? ' is-active' : ''}`} style={{ '--i': i } as CSSProperties}>\n <ProfileDot entry={entry} />\n <div className=\"dab-profile-meta\">\n <span className=\"dab-profile-name\">{entry.name}</span>\n <span className=\"dab-profile-sub\">{new Date(entry.createdAt).toLocaleDateString()}</span>\n </div>\n <button type=\"button\" className=\"dab-btn\" onClick={() => onApply(entry)}>{t('profileApply')}</button>\n <button type=\"button\" className={`dab-btn dab-btn-danger-solid${confirmId === entry.id ? ' dab-btn-confirm' : ''}`}\n title={t('profileDelete')} onClick={() => onDelete(entry)}>\n {confirmId === entry.id ? (\n <><CheckIcon size={13} />{t('profileDeleteConfirm')}</>\n ) : (\n t('profileDelete')\n )}\n </button>\n </div>\n ))}\n </div>\n )}\n </section>\n\n {/* Day/night auto switch */}\n <section className=\"dab-card dab-rise\" style={{ '--d': 3 } as CSSProperties}>\n <div className=\"dab-row-head\">\n <div className=\"dab-swatch-title\" style={{ marginBottom: 0 }}>{t('scheduleTitle')}</div>\n <button type=\"button\" className={`dab-toggle${schedule.enabled ? ' is-on' : ''}`} role=\"switch\" aria-checked={schedule.enabled}\n onClick={() => patchSchedule({ enabled: !schedule.enabled })}>\n <span className=\"dab-toggle-knob\" />\n </button>\n </div>\n <p className=\"dab-hint\" style={{ marginTop: 8 }}>{t('scheduleHint')}</p>\n <div className={`dab-schedule-wrap${schedule.enabled ? ' is-open' : ''}`} aria-hidden={!schedule.enabled}>\n <div className=\"dab-schedule-clip\">\n <div className=\"dab-schedule-grid\">\n <div className=\"dab-schedule-cell\" style={{ '--i': 0 } as CSSProperties}>\n <div className=\"dab-swatch-title\">{t('scheduleMode')}</div>\n <div className=\"dab-chip-row\">\n <button type=\"button\" className={`dab-chip${schedule.mode === 'time' ? ' is-active' : ''}`}\n onClick={() => patchSchedule({ mode: 'time' })}><ClockIcon size={13} />{t('scheduleModeTime')}</button>\n <button type=\"button\" className={`dab-chip${schedule.mode === 'system' ? ' is-active' : ''}`}\n onClick={() => patchSchedule({ mode: 'system' })}>{t('scheduleModeSystem')}</button>\n </div>\n </div>\n {schedule.mode === 'time' ? (\n <div className=\"dab-schedule-cell\" style={{ '--i': 1 } as CSSProperties}>\n <div className=\"dab-swatch-title\">{t('scheduleTimes')}</div>\n <div className=\"dab-time-row\">\n <label className=\"dab-time-label\"><SunIcon size={13} />{t('scheduleDayStart')}\n <input type=\"time\" className=\"dab-timeinput\" value={schedule.dayStart}\n onChange={e => { if (/^([01]\\d|2[0-3]):[0-5]\\d$/.test(e.target.value)) patchSchedule({ dayStart: e.target.value }) }} />\n </label>\n <label className=\"dab-time-label\"><MoonIcon size={13} />{t('scheduleNightStart')}\n <input type=\"time\" className=\"dab-timeinput\" value={schedule.nightStart}\n onChange={e => { if (/^([01]\\d|2[0-3]):[0-5]\\d$/.test(e.target.value)) patchSchedule({ nightStart: e.target.value }) }} />\n </label>\n </div>\n </div>\n ) : null}\n <div className=\"dab-schedule-cell\" style={{ '--i': 2 } as CSSProperties}>\n <div className=\"dab-swatch-title\">{t('scheduleProfiles')}</div>\n <div className=\"dab-time-row\">\n <label className=\"dab-time-label\"><SunIcon size={13} />{t('scheduleDayProfile')}\n {profileOptions(schedule.dayProfile, id => patchSchedule({ dayProfile: id }))}\n </label>\n <label className=\"dab-time-label\"><MoonIcon size={13} />{t('scheduleNightProfile')}\n {profileOptions(schedule.nightProfile, id => patchSchedule({ nightProfile: id }))}\n </label>\n </div>\n </div>\n </div>\n </div>\n </div>\n </section>\n\n {/* Export / import */}\n <div className=\"dab-profile-grid\">\n <section className=\"dab-card dab-card-hover dab-rise\" style={{ '--d': 4 } as CSSProperties}>\n <div className=\"dab-profile-ico\"><DownloadIcon size={17} /></div>\n <div className=\"dab-profile-title\">{t('exportCardTitle')}</div>\n <div className=\"dab-profile-desc\">{t('exportCardDesc')}</div>\n <button type=\"button\" className=\"dab-btn dab-btn-primary\" onClick={() => { exportTheme(); notify(t('toastExportDone')) }}>\n <DownloadIcon size={14} />{t('exportTheme')}\n </button>\n </section>\n\n <section className=\"dab-card dab-card-hover dab-rise\" style={{ '--d': 5 } as CSSProperties}>\n <div className=\"dab-profile-ico\"><UploadIcon size={17} /></div>\n <div className=\"dab-profile-title\">{t('importCardTitle')}</div>\n <div className=\"dab-profile-desc\">{t('importCardDesc')}</div>\n <button type=\"button\" className=\"dab-btn\" onClick={() => importRef.current?.click()}>\n <UploadIcon size={14} />{t('importTheme')}\n </button>\n <input ref={importRef} type=\"file\" accept=\"application/json,.json\" style={{ display: 'none' }} onChange={e => {\n const f = e.target.files?.[0]; if (!f) return\n void onImport(f); e.target.value = ''\n }} />\n </section>\n </div>\n\n <footer className=\"dab-footer dab-rise\" style={{ '--d': 6 } as CSSProperties}>\n <span className=\"dab-footer-mono\">dsh-any-background</span>\n <span>{t('footerTag')}</span>\n </footer>\n </>\n )\n}\n","/**\n * dsh-any-background — appearance shell for the five pages.\n *\n * Two surfaces render this shell, and only the chrome differs:\n * · `settings` — injected into the host settings dialog's content column,\n * which supplies the modal frame (nav rail on the left, brand block, page\n * max-width, the dialog's own scrolling);\n * · `sidebar` — a page inside dsh-better-sidebar, where the panel is much\n * narrower, is handed a full-height column, and has to own its own scroll\n * region. The brand block is dropped (the sidebar's tab bar already names\n * the page) and the rail turns into a compact row.\n * The five pages themselves never branch on the surface: width-driven\n * adaptation lives in the stylesheet's container queries, which measure the\n * shell itself rather than assuming either surface's width.\n */\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react'\nimport type { ThemeSectionProps } from '../types'\nimport { ensureUiCss, NAV_ITEM_H, NAV_GAP } from './ui.css'\nimport { SunIcon, DropletIcon, LayersIcon, PhotoIcon, SlidersIcon, FontIcon, CheckIcon, AlertIcon } from './icons'\nimport { ErrorBoundary } from './ErrorBoundary'\nimport { Portal } from './Portal'\nimport { ColorPage } from './pages/ColorPage'\nimport { InterfacePage } from './pages/InterfacePage'\nimport { FontPage } from './pages/FontPage'\nimport { BackgroundPage } from './pages/BackgroundPage'\nimport { ProfilePage } from './pages/ProfilePage'\n\n/** Which chrome wraps the pages; see the module doc. */\nexport type ThemeSurface = 'settings' | 'sidebar'\n\nexport function ThemeSection(props: ThemeSectionProps & { surface?: ThemeSurface }) {\n ensureUiCss()\n const { t } = props\n const surface = props.surface ?? 'settings'\n const [page, setPage] = useState(0)\n const [toast, setToast] = useState<{ msg: string; ok: boolean } | null>(null)\n const toastTimer = useRef<number | undefined>(undefined)\n\n useEffect(() => () => window.clearTimeout(toastTimer.current), [])\n\n const notify = useCallback((msg: string, ok = true): void => {\n setToast({ msg, ok })\n window.clearTimeout(toastTimer.current)\n toastTimer.current = window.setTimeout(() => setToast(null), 2600)\n }, [])\n\n // Stable element identities: an inline notify + inline array rebuilds every\n // page element on each render, so a toast appearing (or any state tick)\n // re-renders all five pages at once. That churn is what makes LiveSlider's\n // sync effect fire mid-drag and yank the thumb back, so keep the elements\n // memoized on the few props that actually change them.\n const pages = useMemo(() => [\n { label: t('pageColor'), Icon: DropletIcon, node: <ColorPage p={props} notify={notify} /> },\n { label: t('pageInterface'), Icon: LayersIcon, node: <InterfacePage p={props} /> },\n { label: t('pageFont'), Icon: FontIcon, node: <FontPage p={props} notify={notify} /> },\n { label: t('pageBackground'), Icon: PhotoIcon, node: <BackgroundPage p={props} notify={notify} /> },\n { label: t('pageProfile'), Icon: SlidersIcon, node: <ProfilePage p={props} notify={notify} /> },\n ], [t, props, notify])\n\n return (\n <ErrorBoundary t={t}>\n <div className=\"dab-root\" data-dab-surface={surface}>\n <div className=\"dab-shell\">\n <nav className=\"dab-nav\">\n {surface === 'sidebar' ? null : (\n <div className=\"dab-brand\">\n <div className=\"dab-brand-tile\"><SunIcon size={15} /></div>\n <div>\n <div className=\"dab-brand-name\">{t('nav')}</div>\n <div className=\"dab-brand-tag\">{t('brandTag')}</div>\n </div>\n </div>\n )}\n <div className=\"dab-nav-list\">\n <div className=\"dab-nav-ind\" style={{ transform: `translateY(${page * (NAV_ITEM_H + NAV_GAP)}px)` }} />\n {pages.map((pg, i) => (\n <button\n key={pg.label} type=\"button\"\n className={`dab-nav-item${i === page ? ' is-active' : ''}`}\n onClick={() => setPage(i)}>\n <pg.Icon size={16} />\n <span>{pg.label}</span>\n </button>\n ))}\n </div>\n </nav>\n\n <div className=\"dab-page\" key={page}>\n {pages[page].node}\n </div>\n </div>\n </div>\n\n {toast ? (\n <Portal>\n <div className=\"dab-toast\" role=\"status\">\n <span className={toast.ok ? 'dab-toast-ok' : 'dab-toast-err'}>\n {toast.ok ? <CheckIcon size={14} /> : <AlertIcon size={14} />}\n </span>\n <span>{toast.msg}</span>\n </div>\n </Portal>\n ) : null}\n </ErrorBoundary>\n )\n}\n","/**\n * dsh-any-background — selector hook over a host store instance.\n *\n * The settings slot kit hands the pages a `useStore(selector)` hook that is\n * bound to this plugin's store instance by the host renderer. A better-sidebar\n * page gets no such kit — its tab props carry `ctx`/`store`/`scope` for\n * better-sidebar's own store — so the same contract is rebuilt here from the\n * store instance itself, which already IS an observable source\n * (`getSnapshot`/`subscribe`, see `defineStore` in the host's client store).\n *\n * Semantics match the host binding on purpose: reduce the published snapshot\n * through the selector and compare with `Object.is`, so a page subscribing to\n * one field does not re-render on unrelated writes.\n */\nimport { useCallback, useRef, useSyncExternalStore } from 'react'\n\n/** The observable slice of a store instance this module relies on. */\nexport interface ObservableStore<S> {\n getSnapshot: () => S\n subscribe: (onChange: () => void) => () => void\n}\n\n/**\n * Bind a store instance to a `useStore(selector)` hook. Call once per store and\n * share the result: the returned hook keeps one subscription identity for its\n * whole lifetime.\n * @param store - observable store instance (`defineStore` handle).\n * @returns a selector hook reading that instance.\n */\nexport function createStoreHook<S>(store: ObservableStore<S>): <T>(selector: (snapshot: S) => T) => T {\n // Bound once: `subscribe` must keep its identity across renders or React\n // re-subscribes on every one of them.\n const subscribe = (onChange: () => void): (() => void) => store.subscribe(onChange)\n const { getSnapshot } = store\n return function useStoreSelector<T>(selector: (snapshot: S) => T): T {\n // Cache the selected value per snapshot identity. Two reasons, both load\n // bearing: React demands a referentially stable result for an unchanged\n // snapshot (otherwise it re-renders forever), and callers pass inline\n // arrows whose identity changes every render, so the selector itself can\n // never provide that stability. Caching per snapshot also makes a selector\n // that derives a fresh object safe.\n const cache = useRef<{ snapshot: S; value: T } | null>(null)\n const read = useCallback(() => {\n const snapshot = getSnapshot()\n const hit = cache.current\n if (hit !== null && hit.snapshot === snapshot) return hit.value\n const value = selector(snapshot)\n cache.current = { snapshot, value }\n return value\n }, [selector])\n return useSyncExternalStore(subscribe, read, read)\n }\n}\n","/**\n * dsh-any-background — dsh-better-sidebar integration.\n *\n * Publishes the plugin's appearance controls as a sidebar page (\"主题\") in\n * better-sidebar's tab registry. The page renders the SAME five-page tree as\n * the settings section — `ThemeSection` takes a `surface` variant — so there is\n * one UI to maintain, not two forks of it.\n *\n * The dependency is optional at every level, which is why nothing here imports\n * the package:\n * · the service is read off the client context at runtime, so a DSH install\n * without better-sidebar silently registers nothing, and a better-sidebar\n * that mounts *after* this plugin still gets the page (`ctx.inject` fires\n * whenever the service shows up, never when it never does);\n * · the plugin's own types are restated in the minimal local contract below\n * instead of imported — a value import would be rejected by the host's\n * client-bundle purity gate, and even a type-only import would make the\n * package a build-time dependency for everyone who does not run it.\n */\nimport { createElement, useCallback, useMemo, useSyncExternalStore } from 'react'\nimport type { Ctx, LocaleService, ThemeSectionProps, ThemeStoreState } from '../types'\nimport { NS } from '../i18n'\nimport { ThemeSection } from '../components/ThemeSection'\nimport { SunIcon } from '../components/icons'\nimport { createStoreHook, type ObservableStore } from './store-hook'\nimport { subscribeHostInfo } from '../host-compat/release'\nimport { sidebarGuideOwner } from '../host-compat/capabilities'\n\n/** Minimal restatement of the slice of `ctx.betterSidebar` used here. */\ninterface BetterSidebarService {\n /** Register a page type; the returned disposer withdraws it. */\n registerTab(descriptor: {\n id: string\n title: string | (() => string)\n icon?: unknown\n order?: number\n /** Focus an already-open page instead of stacking duplicates. */\n single?: boolean\n component: () => unknown\n }): () => void\n}\n\n/** The client context, plus the optional service this module probes for. */\ntype CtxWithSidebar = Ctx & { betterSidebar?: BetterSidebarService }\n\n/**\n * The active locale id, used as a re-render signal: page labels are resolved by\n * calling `t(...)` at render time, so the props object (and with it the memoized\n * page tree) has to be rebuilt when the language flips — otherwise the page\n * would keep painting the previous language until some unrelated store write\n * happened to re-render it.\n * @param locale - host locale service.\n * @returns the active locale id (a stable string, safe for `Object.is`).\n */\nfunction useActiveLocale(locale: LocaleService): string {\n const subscribe = useCallback((onChange: () => void) => locale.subscribe(onChange), [locale])\n const read = useCallback(() => locale.getSnapshot().active, [locale])\n return useSyncExternalStore(subscribe, read, read)\n}\n\n/** Rendered inside a sidebar tab: the five pages, `surface: 'sidebar'` shell.\n * Shared by the better-sidebar page and the native right-Sidebar tab — both\n * hand a full-height column that owns its own scroll. */\nexport function ThemeTab({ face, useStore, locale }: {\n /** The plugin's business face, built once and shared with the settings section. */\n face: Omit<ThemeSectionProps, 'useStore'>\n useStore: ThemeSectionProps['useStore']\n locale: LocaleService\n}) {\n const active = useActiveLocale(locale)\n // Unlike the settings slot — whose kit rebuilds the props object on every\n // render — every input here is stable, so the pages keep stable element\n // identities and only re-render when the store tells them to (or the language\n // changes). That is exactly the property the settings path has to fake.\n const props = useMemo<ThemeSectionProps>(() => ({ ...face, useStore }), [face, useStore, active])\n return createElement(ThemeSection, { ...props, surface: 'sidebar' })\n}\n\n/**\n * Register the appearance page with better-sidebar, if it is installed.\n *\n * Call from the client `apply`. The registration is owned by the injected\n * scope's effect, so unloading the plugin (or HMR) withdraws it — without that,\n * the next activation would throw on the duplicate id.\n * @param ctx - client context.\n * @param opts.face - lazy accessor for the shared business face.\n * @param opts.store - the plugin's store instance, or null on a host where the\n * store module never resolved (in that case there is nothing to bind and no\n * page is registered).\n */\nexport function registerThemeSidebarTab(ctx: Ctx, opts: {\n face: () => Omit<ThemeSectionProps, 'useStore'>\n store: ObservableStore<ThemeStoreState> | null\n}): void {\n const { store } = opts\n // Fail soft on an unexpected store shape. `defineStore` has already shipped\n // two different return shapes (an instance on newer builds, a\n // `{ spec, create }` declaration on dsh-client-store 0.1.2-alpha.x), and\n // binding a hook to the wrong one throws on every render — which the section's\n // error boundary turns into a dead panel. Registering nothing leaves the\n // settings panel working, which is the right trade.\n if (store === null || typeof store.getSnapshot !== 'function' || typeof store.subscribe !== 'function') {\n console.warn('dsh-any-background: no observable store instance on this host; the sidebar page stays unregistered')\n return\n }\n const locale = ctx.locale\n const t = locale.bind(NS)\n const useStore = createStoreHook(store)\n // A fixed order slot past the built-ins (terminal 40 / browser 50) keeps the\n // page at the end of the + menu instead of displacing the tools above it.\n const ORDER = 55\n ctx.inject?.(['betterSidebar'], (scope: Ctx) => {\n const service = (scope as CtxWithSidebar).betterSidebar\n if (service === undefined) return\n // A host whose own right Sidebar already carries the appearance page would\n // show two identical entries on the same guide surface, so the better-sidebar\n // page stands down there. Driven by the host adapter, not by the native\n // sidebar service: that service also ships on 0.1.5-rc.2, where this page\n // must still register.\n const owner = sidebarGuideOwner()\n if (owner === 'host') return\n let disposeTab: (() => void) | null = null\n // Verdict not landed yet (Node round-trip): register now and withdraw if the\n // host turns out to own the surface — better a brief duplicate than a\n // missing page.\n const unsubscribeHost = owner === 'pending'\n ? subscribeHostInfo(() => {\n if (sidebarGuideOwner() === 'host') {\n disposeTab?.()\n disposeTab = null\n unsubscribeHost()\n }\n })\n : () => {}\n // The face is materialized HERE, once, before the host can render the page.\n // Its first build warms the store (syncBg/syncMetaNow), and a store write\n // issued from inside a render is exactly the kind of impurity that turns\n // into a \"setState while rendering\" warning later.\n const face = opts.face()\n scope.effect(() => {\n disposeTab = service.registerTab({\n id: 'dsh-any-background:theme',\n title: () => t('nav'),\n icon: (size: number) => createElement(SunIcon, { size }),\n order: ORDER,\n single: true,\n // The tab props carry better-sidebar's own store/scope/visible seats\n // and are not needed: this page polls nothing, and its only\n // subscription is the plugin store, shared with the settings section.\n component: () => createElement(ThemeTab, { face, useStore, locale }),\n }) ?? null\n return () => {\n unsubscribeHost()\n disposeTab?.()\n disposeTab = null\n }\n })\n })\n}\n","/**\n * Host capability detection — which third-party plugins are actually present.\n *\n * The host exposes no plugin registry on the client context, so presence is\n * inferred from the stable DOM markers those plugins mount. Detection runs\n * once (plugin boot) and is re-armed by a cheap body-level MutationObserver so\n * a plugin that mounts after this one still flips the cached verdict. The\n * verdict is sticky-true for the session: whether a detected plugin's surface\n * is currently collapsed must not hide the settings that govern it.\n */\n\n/** Persistent container + surfaces dsh-better-sidebar mounts when loaded.\n * `[data-dsh-better-sidebar]` is the plugin's host wrapper — always appended\n * to document.body on mount — so it is the authoritative \"plugin is loaded\"\n * signal and the body childList observer fires exactly when it appears. The\n * panel surfaces are listed only as reinforcement: they are conditionally\n * rendered (collapsed panels drop them), so they must never be the sole\n * signal.\n *\n * `[data-sidebar-right-panel]` is deliberately ABSENT: on every host generation\n * it marks the host's own right Sidebar (always present once a session opens),\n * so counting it would make the better-sidebar verdict permanently true on any\n * host and mis-drive everything gated on it. */\n\nexport const BETTER_SIDEBAR_MARKERS = [\n '[data-dsh-better-sidebar]',\n '[data-dsh-panel-host]',\n '[data-dsh-bottom-panel]',\n] as const\n\nlet betterSidebar = false\nconst subs = new Set<() => void>()\n\n/** Read snapshot of whether the better-sidebar plugin is present. */\nexport function rBetterSidebar(): boolean {\n return betterSidebar\n}\n\nfunction emit(): void {\n subs.forEach(cb => cb())\n}\n\nfunction sync(): void {\n const present = document.querySelector(BETTER_SIDEBAR_MARKERS.join(',')) !== null\n if (present && !betterSidebar) {\n betterSidebar = true\n emit()\n }\n // Sticky on purpose: a collapsed/detached panel must not untick the verdict.\n}\n\n/** Subscribe to verdict changes. */\nexport function subscribe(cb: () => void): () => void {\n subs.add(cb)\n return () => { subs.delete(cb) }\n}\n\n/** Start detection (probe once, then watch body mounts). Returns an\n * unsubscribe for plugin teardown. */\nexport function startBetterSidebarWatch(): () => void {\n sync()\n const observer = new MutationObserver(sync)\n observer.observe(document.body, { childList: true })\n return () => observer.disconnect()\n}\n\n// ── Native right-Sidebar capability ───────────────────────────────────────────\n// CORRECTION: the native right Sidebar is NOT a 0.1.6+ introduction. It ships and\n// is enabled on 0.1.5-rc.2 already — `@deepseek-ai/dsh-client-ui-sidebar-right`\n// is a `dsh-web-app` dependency and its `ui-sidebar-right` entry is in that\n// release's `cordis.patch.yml`, and `ctx.sidebarRightTabs` is provided there\n// too. An earlier revision of this module treated the service as a \"0.1.6+\"\n// probe, which wrongly suppressed the better-sidebar page on 0.1.5.\n//\n// The real release comes from `host-compat/` (resolved on the Node half, where the\n// launcher's on-disk layout is readable). This flag now only records whether the\n// native registry service was actually CONFIRMED on this host — a runtime\n// availability fact used to decide whether the native tab can be registered at\n// all — while the better-sidebar suppression is driven by the host adapter.\n\nlet nativeTabs = false\nconst nativeSubs = new Set<() => void>()\n\n/** Whether the native right-Sidebar tab registry service was confirmed present. */\nexport function rNativeSidebarTabs(): boolean {\n return nativeTabs\n}\n\n/** Mark the native right-Sidebar service as confirmed. Sticky — the service\n * never goes away within a session. */\nexport function markNativeSidebarTabs(): void {\n if (nativeTabs) return\n nativeTabs = true\n nativeSubs.forEach(cb => cb())\n}\n\n/** Subscribe to the native-Sidebar verdict. */\nexport function subscribeNativeTabs(cb: () => void): () => void {\n nativeSubs.add(cb)\n return () => { nativeSubs.delete(cb) }\n}","/**\n * dsh-any-background — native right-Sidebar integration.\n *\n * DSH ships an official right Sidebar (`dsh-client-ui-sidebar-right`) with a\n * public two-stage extension path: a static tab type into\n * `ctx.sidebarRightTabs` — whose `guide` entry draws a card on the Sidebar's\n * guide page — and a body under the keyed `sidebar.right.pane.tab` seat. This\n * module registers the plugin's appearance pages through that path, so the\n * official Sidebar gains a \"主题\" card that opens the very same five pages the\n * settings panel shows (one implementation, one state store; editing in either\n * place shows up in the other).\n *\n * NOTE: that registry is NOT a new-host feature. It is provided on 0.1.5-rc.2\n * already (verified against the release tag), so nothing here may treat \"the\n * service answered\" as \"this is a recent DSH\" — whether this tab or the\n * better-sidebar page owns the guide surface is the host adapter's call.\n *\n * The dependency is optional at every level, mirroring `sidebar/tab.tsx`:\n * · the registry is waited on with `ctx.inject`, so a host without the\n * right Sidebar (or an older DSH) silently registers nothing, and a\n * Sidebar that initializes after this plugin still gets the card;\n * · the service shape is restated as a minimal local contract instead of\n * imported — a value import would be rejected by the host's client-bundle\n * purity gate, and even a type-only import would make the package a\n * build-time dependency for everyone who does not run it.\n *\n * When dsh-better-sidebar is installed it brings its own \"主题\" page (registered\n * by `sidebar/tab.tsx`), which would duplicate this card on the same guide\n * page. The native card therefore yields: it is not registered while\n * better-sidebar is detected, and it withdraws itself if better-sidebar mounts\n * later (the presence verdict is sticky-true, so no re-registration path is\n * needed). The Interface page's panel slider follows the same split:\n * \"右方侧边栏\" natively, \"bettersidebar\" when that plugin is present.\n */\nimport { createElement } from 'react'\nimport type { Ctx, ThemeSectionProps, ThemeStoreState } from '../types'\nimport { NS } from '../i18n'\nimport { ThemeTab } from './tab'\nimport { SunIcon } from '../components/icons'\nimport { createStoreHook, type ObservableStore } from './store-hook'\nimport { rBetterSidebar, subscribe as subscribeBetterSidebar, markNativeSidebarTabs } from '../env'\nimport { subscribeHostInfo } from '../host-compat/release'\nimport { sidebarGuideOwner } from '../host-compat/capabilities'\n\n/** Minimal restatement of the slice of `ctx.sidebarRightTabs` used here. */\ninterface SidebarRightTabsService {\n /** Register one tab type for the caller's effect lifetime; returns an idempotent disposer. */\n register(definition: {\n /** Unique implementation identity; also the key the body registers under. */\n id: string\n /** Type discriminator — what `openTab` names. */\n kind: string\n /** The tab chip's text, captured when the tab opens. */\n title: (address: string) => string\n /** Entry boxes for the guide page; picking one opens this type as a page. */\n guide?: readonly {\n id: string\n order: number\n title: () => string\n description?: () => string\n /** A React component receiving `{ size?, className? }`. */\n icon?: unknown\n }[]\n }): () => void\n}\n\n/** The client context, plus the optional service this module waits for. */\ntype CtxWithTabs = Ctx & { sidebarRightTabs?: SidebarRightTabsService }\n\n/** The tab implementation's identity, and the key the body registers under. */\nexport const NATIVE_TAB_ID = 'dsh-any-background:theme'\n\n/** The page kind: what `openTab` names and the guide entry opens. */\nconst NATIVE_TAB_KIND = 'danybg-theme'\n\n/**\n * Register the appearance pages with the native right Sidebar, if one exists.\n *\n * Call from the client `apply`. Both registrations sit inside the injected\n * scope's effects, so unloading the plugin (or HMR) withdraws them — without\n * that, the next activation would throw on the duplicate id.\n * @param ctx - client context.\n * @param opts.face - lazy accessor for the shared business face.\n * @param opts.store - the plugin's store instance, or null on a host where the\n * store module never resolved (in that case there is nothing to bind and no\n * page is registered).\n */\nexport function registerNativeSidebarTab(ctx: Ctx, opts: {\n face: () => Omit<ThemeSectionProps, 'useStore'>\n store: ObservableStore<ThemeStoreState> | null\n}): void {\n const { store } = opts\n // Same guard as the better-sidebar path: `defineStore` has shipped two return\n // shapes across host builds, and binding a hook to the wrong one throws on\n // every render. Registering nothing leaves the settings panel working.\n if (store === null || typeof store.getSnapshot !== 'function' || typeof store.subscribe !== 'function') {\n console.warn('dsh-any-background: no observable store instance on this host; the native sidebar page stays unregistered')\n return\n }\n const locale = ctx.locale\n const t = locale.bind(NS)\n const useStore = createStoreHook(store)\n ctx.inject?.(['sidebarRightTabs'], (scope: Ctx) => {\n const tabs = (scope as CtxWithTabs).sidebarRightTabs\n if (tabs === undefined || typeof tabs.register !== 'function') return\n // This host has the native registry: record the capability so the\n // better-sidebar page knows the surface exists at all. Presence alone does NOT\n // decide who owns it — see markNativeSidebarTabs and the module note.\n markNativeSidebarTabs()\n // The face is materialized HERE, once, before the host can render the page:\n // its first build warms the store (syncBg/syncMetaNow), and a store write\n // issued from inside a render is exactly the impurity that turns into a\n // \"setState while rendering\" warning later.\n const face = opts.face()\n // The tab body needs no tab info of its own — the page polls nothing and\n // its only subscription is the plugin's shared store — so the slot\n // framework's props are ignored wholesale.\n const ThemeBody = () => createElement(ThemeTab, { face, useStore, locale })\n scope.effect(() => {\n // Which page owns the guide surface is decided by the SAME predicate the\n // better-sidebar module uses, so the two can never both stand down and\n // leave the Surface with no appearance card at all:\n // · the host owns it → better-sidebar page suppressed, native wins\n // · the plugin owns it → better-sidebar page registers, native yields\n // · pending verdict → the native card registers, and is withdrawn once\n // the adapter says better-sidebar owns the surface.\n const yieldTo = (): boolean =>\n sidebarGuideOwner() === 'plugin' && rBetterSidebar()\n if (yieldTo()) return\n let disposeTab: (() => void) | null = null\n const withdraw = (): void => {\n disposeTab?.()\n disposeTab = null\n }\n const unsubscribeBetter = subscribeBetterSidebar(() => { if (yieldTo()) withdraw() })\n const unsubscribeHost = subscribeHostInfo(() => { if (yieldTo()) withdraw() })\n disposeTab = tabs.register({\n id: NATIVE_TAB_ID,\n kind: NATIVE_TAB_KIND,\n title: () => t('nav'),\n guide: [{\n id: 'theme',\n // Past the shipped pages (files 10 / terminal 40 / browser 50): the\n // appearance card trails the tools instead of displacing them.\n order: 55,\n title: () => t('nav'),\n description: () => t('guideDesc'),\n icon: SunIcon,\n }],\n })\n return () => {\n unsubscribeBetter()\n unsubscribeHost()\n withdraw()\n }\n }, 'dsh-any-background: native sidebar theme tab')\n // Stage two: the body under the keyed seat, dispatched by the type's id.\n scope.effect(() => ctx.slots.inject('sidebar.right.pane.tab', () => ctx.slots.register(\n { name: 'sidebar.right.pane.tab', key: NATIVE_TAB_ID },\n ThemeBody,\n )), 'dsh-any-background: native sidebar theme body')\n })\n}\n","/**\n * dsh-any-background — browser half entry.\n *\n * Wires the plugin lifecycle: theme registration, wallpaper layer, viewport\n * watch, i18n, settings-section injection, boot restore, watchdog. The heavy\n * lifting lives in the sibling modules (state/rpc/wallpaper/utils/components).\n */\nimport { defineStore } from './runtime'\nimport type { Ctx, RpcResultLike, BoundActions, ThemeSectionProps, PartOpacities, PartBlurs, PartStrokes, BackgroundType, GeneratedBgParams, ProfileAppearance, ProfileEntry, RotationItem, ScheduleConfig, SchemeOverride, UploadOutcome, StoreInstance } from './types'\nimport { NS, zh, en } from './i18n'\nimport { cfg, rHasColor, rColor, rWp, rWpImage, rWpVideo, rBgState, rVideoBgState, setWpUrl, setWpImageUrl, setWpVideoUrl, setWpVideoSnapshot, setBgState, adoptConfig, DEFAULT_CONFIG, setBgDark, rBgDark, rProfiles, rRotation, rSchedule, rScheme, rColorScheme, rSchemeOverride, currentAppearance, applyAppearance } from './state'\nimport { RPC_CHANNEL, VIDEO_SERVE_URL, FONT_SERVE_URL, fontServeUrl, initRpc, saveConfig, flushSave, loadPersisted, persistWallpaper, persistVideo, persistConfig, uploadVideo, uploadFont, removeFont as rpcRemoveFont, rotationAdd, rotationRemove, rotationActivate, setVideoFromUrl as rpcSetVideoFromUrl } from './rpc'\nimport { applyWp, teardownWp, applySettingsOverrides, applyPanelOverrides, applyStrokes, applyFontFace, watchParts, watchThemeResets, regenerateGeneratedBg, setBackgroundType, updateGeneratedBg, applyThemeColor, onGeneratedSnapshot, watchWallpaperDragQuality, clearThemeTokens, onVerdictApplied, onColorAdopted, LABEL_TOKENS, SETTINGS_PANEL_SEL } from './wallpaper'\nimport { mountStaticStyles } from './host-compat/styles'\nimport { genTokens, hslToHsv, hsvToHsl, extractWallpaperColor } from './utils/color'\nimport { captureVideoSnapshot } from './utils/video'\nimport { readImgAsync, makeThumb, blobToDataUrl } from './utils/image'\nimport { ThemeSection } from './components/ThemeSection'\nimport { registerThemeSidebarTab } from './sidebar/tab'\nimport { registerNativeSidebarTab } from './sidebar/native-tab'\nimport { SUN_PATHS } from './components/icons'\nimport { startBetterSidebarWatch } from './env'\nimport { startHeaderPopoverTagging } from './header-tag'\n\nexport const name = 'dsh-any-background'\nexport const inject = ['slots', 'locale', 'theme', 'connection']\n\nconst CUSTOM_ID = 'custom-color'\n\nexport function apply(ctx: Ctx): void {\n // Bind the dedicated `/dsh-any-background` RPC caller so the persistence\n // module can reach the node half's file-backed store.\n initRpc((endpoint, payload) =>\n ctx.connection.rpc.call(RPC_CHANNEL, endpoint, payload).then((res: any) => res as RpcResultLike | undefined)\n )\n\n // 1. Restore custom color and register as a skin. The skin MUST go through\n // the host theme service — the host presenter paints fonts from the\n // registered theme, so a stylesheet-only override loses to it.\n // · picked color → genTokens in the effective scheme;\n // · forced scheme → neutral palette in the forced direction;\n // · auto, no color→ adopt the host's own palette in the background\n // brightness verdict's direction, fonts flipped to match\n // the wallpaper (perceptual luma, threshold 0.5).\n const [initH, initS, initL] = rColor()\n let customDispose: (() => void) | null = null\n // Records that the host theme service rejected our skin for a reason other\n // than the HMR duplicate below: logged once so the 1s watchdog's retries do\n // not spam the console (or, worse, fail in total silence while the user's\n // theme quietly never applies).\n let registerFailed = false\n // registerCustom takes HSL (the storage/wheel space and genTokens space).\n const registerCustom = (h?: number, s?: number, l?: number): boolean => {\n customDispose?.()\n try {\n let colorScheme: 'light' | 'dark'\n let tokens: Record<string, string>\n if (rHasColor()) {\n ;({ colorScheme, tokens } = genTokens(h ?? rColor()[0], s ?? rColor()[1], l ?? rColor()[2], rColorScheme()))\n } else if (rSchemeOverride() !== 'auto') {\n const dark = rScheme() === 'dark'\n ;({ colorScheme, tokens } = genTokens(220, 0.04, dark ? 0.14 : 0.92, dark ? 'dark' : 'light'))\n } else {\n const verdict = rBgDark()\n if (verdict === null) { customDispose = null; return false }\n const snap = ctx.theme.getTheme()\n const wantScheme = verdict ? 'dark' : 'light'\n const source = snap.themes.find(t => t.id !== CUSTOM_ID && t.colorScheme === wantScheme)\n ?? snap.themes.find(t => t.id !== CUSTOM_ID)\n if (source === undefined) { customDispose = null; return false }\n colorScheme = wantScheme\n tokens = { ...source.tokens }\n const font = verdict ? '#fff' : '#000'\n for (const name of LABEL_TOKENS) tokens[name] = font\n }\n customDispose = ctx.theme.register({ id: CUSTOM_ID, colorScheme, tokens })\n } catch (e) {\n // HMR tolerance: an earlier apply pass may still hold a live registration\n // for this id, and register throws on the duplicate — the registry then\n // already contains the skin, so fall through and activate it below.\n // Any OTHER failure (host API drift, version mismatch) must not be\n // swallowed here: the watchdog would retry it every second forever.\n const alreadyLive = (() => { try { return ctx.theme.getTheme().themes.some(t => t.id === CUSTOM_ID) } catch { return false } })()\n if (!alreadyLive) {\n if (!registerFailed) {\n registerFailed = true\n console.error('dsh-any-background: host theme register failed; the custom skin will stay inactive', e)\n }\n customDispose = null\n return false\n }\n customDispose = null\n }\n // Only activate the custom theme if it is actually registered.\n const present = (() => { try { return ctx.theme.getTheme().themes.some(t => t.id === CUSTOM_ID) } catch { return false } })()\n if (present) ctx.theme.setTheme(CUSTOM_ID)\n return present\n }\n // Restore saved color on boot.\n if (rHasColor()) registerCustom(initH, initS, initL)\n // A fresh background brightness verdict (wallpaper swapped in, generated bg\n // regenerated) re-registration trigger: without a picked color the adopted\n // skin must be rebuilt so its fonts follow the new wallpaper.\n const disposeVerdict = onVerdictApplied(() => {\n if (!rHasColor()) registerCustom()\n })\n // A wallpaper-extracted color adopted by the auto path (applyThemeColor's\n // no-saved-pick branch) must finish the full adaptation here: register the\n // skin in the color's direction, persist, and sync the editor wheel — the\n // bare cfg.color write in wallpaper.ts cannot reach any of those.\n const disposeColorAdopted = onColorAdopted(hsl => {\n registerCustom(hsl[0], hsl[1], hsl[2])\n saveConfig()\n colorRev++\n bound?.syncColor(hslToHsv(hsl[0], hsl[1], hsl[2]), colorRev)\n })\n // Drop this apply's listener closures on teardown: HMR re-runs apply and the\n // module-level slots would otherwise keep invoking the previous session's\n // callbacks (and the closures above hold dead `bound`/`customDispose` state).\n ctx.effect(() => () => { disposeVerdict(); disposeColorAdopted() }, 'dsh-any-background: verdict/color listeners')\n ctx.effect(() => () => {\n customDispose?.()\n if (colorTimerRef.current !== null) window.clearTimeout(colorTimerRef.current)\n }, 'dsh-any-background: skin dispose')\n\n // 2. The plugin's static stylesheet — the dark-mode gradient plus every\n // host-override rule. Assembled in `host-compat/styles`, which owns the rule\n // order and slots in the panel arm chosen by the host's release adapter (the\n // first sheet is the unresolved one; it is re-cut when the verdict lands).\n ctx.effect(() => mountStaticStyles(), 'dsh-any-background: stylesheet')\n\n // Wallpaper downscales to a low-res copy during slider drags, restored on release.\n const disposeDragQuality = watchWallpaperDragQuality()\n ctx.effect(() => () => disposeDragQuality(), 'dsh-any-background: drag quality')\n\n // 3. State store. defineStore is null on a host variant where neither store\n // package resolved (see runtime.ts): keep applying theme/wallpaper and skip\n // only the settings section rather than crashing the whole client half.\n //\n // `defineStore` returns two different things across host builds:\n // · newer builds hand back the STORE INSTANCE (getSnapshot/subscribe/\n // actions) directly;\n // · dsh-client-store 0.1.2-alpha.x hands back a DECLARATION\n // `{ spec, create(scopeKey) }` that the renderer instantiates per scope\n // — the object the plugin holds has neither getSnapshot nor actions.\n // The settings panel only ever worked because the renderer did the\n // instantiation; anything the plugin itself reads off that object has to\n // normalize first.\n let rev = 0\n let colorRev = 0\n let bgRev = 0\n const colorTimerRef: { current: number | null } = { current: null }\n const storeSpec = defineStore === null ? null : defineStore({\n init: () => ({\n url: null as string | null,\n rev: -1,\n colorRev: -1,\n color: null as [number, number, number] | null,\n backgroundType: cfg.backgroundType,\n generatedBg: cfg.generatedBg,\n bgRev: -1,\n regenerateOnReload: cfg.regenerateOnReload,\n profiles: [] as ProfileEntry[],\n rotation: { ...DEFAULT_CONFIG.rotation, items: [] },\n schedule: { ...DEFAULT_CONFIG.schedule },\n schemeOverride: 'auto' as SchemeOverride,\n activeProfile: null as string | null,\n metaRev: -1,\n }),\n actions: {\n syncBg: (d: any, url: string | null, r: number, bgType?: BackgroundType, genBg?: GeneratedBgParams | null, bgr?: number, reload?: boolean) => {\n if (r > d.rev) { d.url = url; d.rev = r }\n if (bgr !== undefined && bgr > d.bgRev) { d.backgroundType = bgType!; d.generatedBg = genBg ?? null; d.bgRev = bgr }\n if (reload !== undefined) { d.regenerateOnReload = reload }\n },\n syncColor: (d: any, hsv: [number, number, number], r: number) => { if (r > d.colorRev) { d.color = hsv; d.colorRev = r } },\n syncMeta: (d: any, profiles: ProfileEntry[], rotation: typeof cfg.rotation, schedule: typeof cfg.schedule, schemeOverride: SchemeOverride, activeProfile: string | null, r: number) => {\n if (r > d.metaRev) {\n d.profiles = profiles; d.rotation = rotation; d.schedule = schedule\n d.schemeOverride = schemeOverride; d.activeProfile = activeProfile; d.metaRev = r\n }\n },\n },\n })\n /** One shared instance, whatever the host build handed back.\n *\n * The plugin publishes a single appearance state that BOTH surfaces read —\n * the settings section (through the renderer's `useStore`) and the\n * better-sidebar page (through the hook in `sidebar/store-hook`). Handing the\n * host a declaration whose `create` always returns this very instance is what\n * keeps them from drifting: letting the renderer mint its own would give the\n * sidebar a second, permanently empty copy of the state. */\n const storeInstance = storeSpec === null\n ? null\n : (typeof (storeSpec as { getSnapshot?: unknown }).getSnapshot === 'function'\n ? storeSpec as StoreInstance\n : (storeSpec as { create: (scopeKey?: string) => StoreInstance }).create())\n /** What gets registered: the instance on newer builds, a single-instance\n * declaration on the ones that expect a declaration. */\n const store = storeSpec === null || storeInstance === storeSpec\n ? storeSpec\n : { spec: (storeSpec as { spec?: unknown }).spec ?? {}, create: () => storeInstance }\n // The instance's actions ARE the sync face the settings slot hands back\n // (`defineStore` bakes the draft into each action, so their signatures match\n // BoundActions exactly). Binding them here rather than waiting for the\n // settings section's first render keeps the store fed from boot: the\n // better-sidebar page can be opened without the settings panel ever having\n // been, and it must not render boot-time defaults for profiles/rotation.\n let bound: BoundActions | null = null\n if (storeInstance !== null) bound = storeInstance.actions as BoundActions\n const syncBg = () => {\n rev++; bgRev++\n bound?.syncBg(rWp(), rev, cfg.backgroundType, cfg.generatedBg, bgRev, cfg.regenerateOnReload)\n }\n // When a generated background finishes its first frame, its snapshot becomes\n // the display/preview URL — re-sync the store so the preview follows.\n const disposeSnapshot = onGeneratedSnapshot(syncBg)\n ctx.effect(() => () => disposeSnapshot(), 'dsh-any-background: snapshot listener')\n\n /** Capture the first frame of the video now applied and finish its\n * adaptation: the frame stands in for every still-image API (previews,\n * color extraction) and the brightness verdict follows it. The stale guard\n * skips a capture whose video was swapped out from under it (another\n * upload or a rotation switch landing mid-decode). */\n const captureAndApplyVideo = (url: string | null): void => {\n if (url === null) return\n void captureVideoSnapshot(url).then(snap => {\n if (rWpVideo() !== url) return\n setWpVideoSnapshot(snap)\n applyThemeColor()\n syncBg()\n })\n }\n\n // ── Profiles / presets / scheme / rotation / schedule ────────────────────────\n let metaRev = 0\n const syncMetaNow = (): void => {\n metaRev++\n bound?.syncMeta(rProfiles(), rRotation(), rSchedule(), rSchemeOverride(), cfg.activeProfile, metaRev)\n }\n\n /** Apply an appearance snapshot (profile or built-in preset) to the whole\n * interface: re-register the skin, re-emit tokens, persist. */\n const applyAppearanceLive = (ap: ProfileAppearance): void => {\n applyAppearance(ap)\n if (rHasColor()) {\n const [h, s, l] = rColor()\n registerCustom(h, s, l)\n } else if (!registerCustom()) {\n // Nothing to assert (no color, auto, no verdict): hand the palette back\n // to the host theme.\n customDispose?.()\n customDispose = null\n clearThemeTokens()\n const snap = ctx.theme.getTheme()\n const fallback = snap.themes.find(t => t.id !== CUSTOM_ID)\n if (fallback !== undefined && snap.preference === CUSTOM_ID) ctx.theme.setTheme(fallback.id)\n }\n applyWp()\n }\n\n const applyProfileById = (id: string): boolean => {\n const entry = rProfiles().find(p => p.id === id)\n if (entry === undefined) return false\n applyAppearanceLive(entry.config)\n cfg.activeProfile = id\n applyWp()\n persistConfig()\n syncMetaNow()\n return true\n }\n\n // ── Wallpaper rotation ───────────────────────────────────────────────────────\n /** Extract the theme color once from a freshly activated wallpaper and run\n * the full adaptation (host skin + editor wheel sync); the caller persists. */\n const adoptWallpaperColor = async (dataUrl: string): Promise<void> => {\n const hsl = await extractWallpaperColor(dataUrl, rBgState())\n // The wallpaper may have been swapped while the image was decoding; a stale\n // pick must not overwrite the new picture's color.\n if (!hsl || rWp() !== dataUrl) return\n cfg.color = hsl\n registerCustom(hsl[0], hsl[1], hsl[2])\n colorRev++\n bound?.syncColor(hslToHsv(hsl[0], hsl[1], hsl[2]), colorRev)\n }\n\n /** Activate a rotation item: the server copies its bytes into the wallpaper\n * slot; the client applies the returned serve URL through the normal image\n * path, then re-extracts the theme color from the new picture so the\n * palette follows the rotation. */\n const applyRotationIndex = async (idx: number, auto: boolean): Promise<boolean> => {\n const rot = rRotation()\n if (idx < 0 || idx >= rot.items.length) return false\n const r = await rotationActivate(idx)\n if (!r.ok || !r.wallpaperUrl) {\n console.warn('dsh-any-background: rotation activate failed', r.error)\n return false\n }\n // The server already persisted the bytes into the wallpaper slot; mirror\n // setWpFromServer's state switch (bound is not initialized yet here).\n cfg.backgroundType = 'image'\n setBgDark(null)\n setWpImageUrl(r.wallpaperUrl)\n setWpUrl(rWpImage())\n setBgState({ ...DEFAULT_CONFIG.bgState })\n cfg.rotation = { ...rot, current: idx, lastRotate: auto || rot.lastRotate === null ? new Date().toISOString() : rot.lastRotate }\n // The picture just switched, so any saved pick describes the old wallpaper:\n // extract once from the new one to re-adapt (placement state matches the\n // previous image, so a size mismatch makes the extractor fall back to the\n // whole picture — the desired behavior for a fresh wallpaper).\n if (cfg.backgroundType === 'image') await adoptWallpaperColor(rWp()!)\n applyThemeColor()\n syncBg()\n saveConfig()\n syncMetaNow()\n return true\n }\n\n const isoWeekKey = (d: Date): string => {\n const t = new Date(Date.UTC(d.getFullYear(), d.getMonth(), d.getDate()))\n const day = t.getUTCDay() || 7\n t.setUTCDate(t.getUTCDate() + 4 - day)\n const yearStart = new Date(Date.UTC(t.getUTCFullYear(), 0, 1))\n const week = Math.ceil(((t.getTime() - yearStart.getTime()) / 86400000 + 1) / 7)\n return `${t.getUTCFullYear()}-W${week}`\n }\n\n const rotationDue = (): boolean => {\n const rot = rRotation()\n if (!rot.enabled || rot.items.length === 0) return false\n if (rot.interval === 'reload') return true\n const last = rot.lastRotate !== null ? new Date(rot.lastRotate) : null\n if (last === null || isNaN(last.getTime())) return true\n const now = new Date()\n if (rot.interval === 'daily') return last.toDateString() !== now.toDateString()\n return isoWeekKey(last) !== isoWeekKey(now)\n }\n\n const pickNextRotationIndex = (): number => {\n const rot = rRotation()\n const n = rot.items.length\n if (n === 0) return -1\n if (rot.mode === 'shuffle' && n > 1) {\n let idx = rot.current\n while (idx === rot.current) idx = Math.floor(Math.random() * n)\n return idx\n }\n return (rot.current + 1) % n\n }\n\n const maybeRotate = async (): Promise<void> => {\n if (!rotationDue()) return\n await applyRotationIndex(pickNextRotationIndex(), true)\n }\n\n // ── Day/night profile schedule ───────────────────────────────────────────────\n const parseHHMM = (s: string): number => {\n const m = /^([01]\\d|2[0-3]):([0-5]\\d)$/.exec(s)\n return m === null ? -1 : Number(m[1]) * 60 + Number(m[2])\n }\n\n const isNightNow = (sc: ScheduleConfig): boolean => {\n const now = new Date()\n const cur = now.getHours() * 60 + now.getMinutes()\n const day = parseHHMM(sc.dayStart)\n const night = parseHHMM(sc.nightStart)\n if (day < 0 || night < 0) return false\n // Normal window (day 07:00 → night 19:00): night wraps midnight.\n if (day <= night) return cur >= night || cur < day\n // Overnight window (e.g. day 22:00 → night 06:00): night is the middle span.\n return cur >= night && cur < day\n }\n\n const scheduleTick = (): void => {\n const sc = rSchedule()\n if (!sc.enabled) return\n // Both steps are optional: `matchMedia?.(…)` alone still throws on the\n // `.matches` read, and this runs inside the boot restore chain and the 30 s\n // schedule timer — a throw here would abort the whole restore (font, skin,\n // wallpaper) and then repeat every tick.\n const night = sc.mode === 'system'\n ? (window.matchMedia?.('(prefers-color-scheme: dark)')?.matches ?? false)\n : isNightNow(sc)\n const want = night ? sc.nightProfile : sc.dayProfile\n if (!want || want === cfg.activeProfile) return\n applyProfileById(want)\n }\n\n // 4. Wallpaper.\n applyWp(); syncBg()\n // The AppFrame mounts after this apply; watch for it so persisted per-part\n // blurs land as soon as the shell renders.\n watchParts()\n // Load the file-backed theme and re-apply once it lands (defaults are already\n // applied above; the deferred restore below re-asserts too). The server\n // advances a due rotation inside the read itself, so the restored wallpaper\n // is already the new pick and paints from the first apply — no old→new flash.\n void loadPersisted().then(async ({ rotated: serverRotated, firstRun }) => {\n if (firstRun) {\n // Nothing was ever persisted on this machine (no theme-config.json).\n // Write the browser half's full default set straight away and re-read it\n // back once, so the restored appearance genuinely comes from disk rather\n // than from in-memory defaults that exist on no reboot.\n persistConfig()\n await loadPersisted()\n applyWp()\n }\n syncMetaNow()\n // The stored custom font (if any) applies immediately; fontEnabled gates\n // the token override without touching the file.\n applyFontFace(fontServeUrl, cfg.fontEnabled, cfg.fontMime)\n // Re-register the skin with the restored color so UI and theme never diverge.\n if (rHasColor()) {\n const [h, s, l] = rColor()\n registerCustom(h, s, l)\n }\n if (serverRotated) {\n // The wallpaper was swapped server-side while the theme color still\n // describes the previous picture: re-extract once so the palette\n // follows the rotation (same adaptation as a client-side advance).\n // Persist the extracted pick — the disk still holds the old color, and\n // without this every later reload would restore it over the new\n // wallpaper.\n if (cfg.backgroundType === 'image' && rWp()) {\n await adoptWallpaperColor(rWp()!)\n saveConfig()\n }\n } else {\n // Fallback client-side advance (server flag missing / older half), still\n // before the branch restore so the fresh wallpaper is what gets applied.\n await maybeRotate()\n }\n // Regenerate on reload if enabled, else reconstruct from saved params.\n if (cfg.backgroundType === 'video') {\n const v = rWpVideo()\n if (v) {\n // The frame snapshot is not persisted: re-capture it for previews.\n captureAndApplyVideo(v)\n applyWp()\n } else {\n // Stored video missing: fall back to the retained image slot.\n cfg.backgroundType = 'image'\n setWpUrl(rWpImage())\n applyThemeColor()\n }\n } else if (cfg.backgroundType !== 'image') {\n if (cfg.regenerateOnReload) {\n regenerateGeneratedBg()\n } else if (cfg.generatedBg) {\n updateGeneratedBg(cfg.generatedBg)\n }\n // Persist the normalized config so the seed and flag land on disk.\n persistConfig()\n } else {\n // Saved pick wins; otherwise extract from the uploaded wallpaper.\n applyThemeColor()\n }\n syncBg()\n scheduleTick()\n if (rHasColor()) { colorRev++; bound?.syncColor(hslToHsv(...rColor()), colorRev) }\n })\n // Schedule cadence: check every 30s (covers fixed-clock switches) and react\n // immediately when the OS scheme flips in 'system' mode.\n const schemeMq = window.matchMedia?.('(prefers-color-scheme: dark)')\n const scheduleTimer = window.setInterval(scheduleTick, 30_000)\n schemeMq?.addEventListener?.('change', scheduleTick)\n ctx.effect(() => () => {\n window.clearInterval(scheduleTimer)\n schemeMq?.removeEventListener?.('change', scheduleTick)\n }, 'dsh-any-background: schedule timer')\n ctx.effect(() => () => { teardownWp() }, 'dsh-any-background: wp cleanup')\n ctx.effect(() => startBetterSidebarWatch(), 'dsh-any-background: better-sidebar watch')\n ctx.effect(() => startHeaderPopoverTagging(), 'dsh-any-background: header popover tagging')\n ctx.effect(() => ctx.on('theme/change', () => {\n // The custom theme's preference lives in memory, so a host adoption can\n // silently reset it; re-assert it while the skin has anything to say (a\n // color, a brightness verdict, or a forced scheme). Guard on registry\n // presence — registerCustom disposes the old skin first, so during that\n // transient the registry lacks CUSTOM_ID.\n if (rHasColor() || rBgDark() !== null || rSchemeOverride() !== 'auto') {\n const snapshot = ctx.theme.getTheme()\n if (snapshot.preference !== CUSTOM_ID && snapshot.themes.some(t => t.id === CUSTOM_ID)) {\n ctx.theme.setTheme(CUSTOM_ID)\n }\n }\n applyWp()\n }), 'dsh-any-background: theme change')\n // Wallpaper placement is computed in absolute viewport pixels, so watch the\n // viewport itself: a fixed inset:0 sentinel's box always equals the viewport,\n // so a ResizeObserver on it catches any viewport change (window resize,\n // monitor moves, panel splitters, zoom); a resolution media query catches\n // DPI-only moves. Re-applies are coalesced to one per animation frame.\n let frame = 0\n const applySoon = (): void => {\n if (frame !== 0) return\n frame = requestAnimationFrame(() => { frame = 0; applyWp() })\n }\n const sentinel = document.createElement('div')\n sentinel.style.cssText = 'position:fixed;inset:0;pointer-events:none;visibility:hidden'\n document.body.append(sentinel)\n const viewportObserver = new ResizeObserver(applySoon)\n viewportObserver.observe(sentinel)\n // A DPI-only move changes no layout box, so the sentinel above misses it;\n // a resolution media query catches it. Optional-chained like the scheme\n // query above: an old WebView without matchMedia must not take down the\n // rest of apply (i18n, section injection, the watchdogs) with a TypeError.\n const dprQuery = window.matchMedia?.(`(resolution: ${window.devicePixelRatio}dppx)`)\n dprQuery?.addEventListener?.('change', applySoon)\n ctx.effect(() => () => {\n viewportObserver.disconnect()\n dprQuery?.removeEventListener?.('change', applySoon)\n sentinel.remove()\n }, 'dsh-any-background: viewport watch')\n\n // 5. Locale.\n ctx.effect(() => ctx.locale.register(NS, { zh, en }), 'dsh-any-background: i18n')\n\n // 6. Section injection.\n /** The business face, built once on first use and shared by both surfaces\n * (the settings section and the better-sidebar page). Memoizing is not just\n * about cost: the face closes over per-surface state — the font preview blob\n * URL behind releaseFontPreview — so a second build would give the sidebar\n * its own preview slot and leak whichever copy never gets released. */\n let themeFace: Omit<ThemeSectionProps, 'useStore'> | null = null\n const buildFace = (): Omit<ThemeSectionProps, 'useStore'> => {\n if (themeFace !== null) return themeFace\n // Both surfaces open long after boot: push the current snapshots so the\n // profiles / rotation / schedule controls render live state, not the\n // store's boot-time defaults.\n syncBg()\n syncMetaNow()\n // Play a picked/imported video instantly from a local object URL while its\n // raw bytes stream to disk in the background — no upload + first-buffer\n // wait after import. The serve URL takes over on the next reload. The\n // upload's outcome is returned so the panel can report a refusal: a video\n // that streams to disk but is refused (oversized) still plays locally and\n // would otherwise look saved.\n const playVideoFromBlob = (blob: Blob, mime: string | null): Promise<UploadOutcome> => {\n const localUrl = URL.createObjectURL(blob)\n cfg.backgroundType = 'video'\n setWpUrl(null)\n cfg.videoBgState = { ...DEFAULT_CONFIG.bgState }\n setWpVideoUrl(localUrl, mime ?? blob.type ?? 'video/mp4')\n applyWp()\n syncBg()\n captureAndApplyVideo(rWpVideo())\n return uploadVideo(blob, mime ?? blob.type ?? 'video/mp4').then(outcome => {\n if (outcome.ok) persistConfig()\n return outcome\n })\n }\n // ── Custom interface font ────────────────────────────────────────────────\n // The file itself lives in the server-side font slot (see uploadFont); the\n // UI only ever sees GTK's serve URL. A picked file is additionally rendered\n // from a local blob URL so the glyph swap is visible while the bytes are\n // still streaming to disk — that preview is released once the slot takes\n // over (a short delay lets any in-flight glyph load finish against it).\n const FONT_EXT_MIME: Record<string, string> = { woff2: 'font/woff2', woff: 'font/woff', otf: 'font/otf', ttf: 'font/ttf' }\n const fontMimeFromName = (name: string): string => {\n const ext = name.split('.').pop()?.toLowerCase() ?? ''\n return FONT_EXT_MIME[ext] ?? 'font/ttf'\n }\n let fontPreviewUrl: string | null = null\n const releaseFontPreview = (delay: number): void => {\n if (fontPreviewUrl === null) return\n const url = fontPreviewUrl\n fontPreviewUrl = null\n window.setTimeout(() => URL.revokeObjectURL(url), delay)\n }\n /** Point the @font-face at whatever is authoritative right now: the\n * persisted slot when one exists, otherwise nothing. */\n const applyStoredFont = (): void => {\n applyFontFace(cfg.fontMime !== null ? FONT_SERVE_URL : null, cfg.fontEnabled, cfg.fontMime)\n }\n\n const [wh, ws, wl] = rColor()\n const [dh, ds, dv] = hslToHsv(wh, ws, wl)\n const built: Omit<ThemeSectionProps, 'useStore'> = {\n t: ctx.locale.bind(NS),\n hue: dh, sat: ds, lit: dv,\n setColor: (nh: number, ns: number, nl: number) => {\n const [sh, ss, sl] = hsvToHsl(nh, ns, nl)\n cfg.color = [sh, ss, sl]\n // Preview UI stays synchronous for instant feedback; the expensive work\n // (theme registration + token writes + persist) is debounced by 80ms.\n if (colorTimerRef.current !== null) window.clearTimeout(colorTimerRef.current)\n colorTimerRef.current = window.setTimeout(() => {\n colorTimerRef.current = null\n registerCustom(sh, ss, sl)\n applyWp()\n saveConfig()\n }, 80)\n // Keep the canonical color in the store so programmatic changes and\n // remounts share one source.\n colorRev++\n bound?.syncColor([nh, ns, nl], colorRev)\n },\n // Server-side set: the wallpaper bytes are ALREADY persisted by the caller\n // (raw upload / URL download / rotation), so this only switches the theme\n // to image mode and points the display at the serve URL. null removes the\n // stored image and video.\n setWpFromServer: (u: string | null) => {\n cfg.backgroundType = 'image'\n // Retain the upload in its own slot so type switches never lose it.\n // The generated-background brightness verdict stops applying here.\n setBgDark(null)\n setWpImageUrl(u)\n // Mirror the same rev'd URL so wpUrl and the display never diverge.\n setWpUrl(rWpImage())\n setBgState({ ...DEFAULT_CONFIG.bgState })\n if (u === null) {\n // Removing the background clears the stored video as well.\n setWpVideoUrl(null, null)\n void persistVideo(null)\n persistWallpaper(null)\n }\n applyThemeColor()\n syncBg()\n },\n setVideo: async (u: Blob | string | null, mime: string | null): Promise<UploadOutcome> => {\n setBgDark(null)\n if (u === null) {\n // Removing: clear the stored video and return to the image slot.\n setWpVideoUrl(null, null)\n cfg.backgroundType = 'image'\n setWpUrl(rWpImage())\n void persistVideo(null)\n applyThemeColor()\n syncBg()\n saveConfig()\n return { ok: true }\n }\n if (typeof u !== 'string') {\n // A picked file plays instantly from a local object URL while its raw\n // bytes stream to disk in the background — no upload + buffer wait.\n return playVideoFromBlob(u, mime)\n }\n // Legacy data-URL string path: persist, then play from the serve URL.\n const ok = await persistVideo(u)\n const live = ok ? VIDEO_SERVE_URL : u\n cfg.backgroundType = 'video'\n setWpUrl(null)\n cfg.videoBgState = { ...DEFAULT_CONFIG.bgState }\n setWpVideoUrl(live, mime ?? null)\n applyWp()\n saveConfig()\n syncBg()\n captureAndApplyVideo(rWpVideo())\n return { ok }\n },\n setBgType: (type: BackgroundType) => {\n setBackgroundType(type)\n // Keep the uploaded wallpaper on disk so it can be restored when the\n // user returns to the image type; it is only removed via setWpFromServer(null).\n saveConfig()\n syncBg()\n },\n setGeneratedBg: (params) => {\n updateGeneratedBg(params)\n saveConfig()\n syncBg()\n },\n regenerateBg: () => {\n regenerateGeneratedBg()\n // Immediate (non-debounced) write so the new seed survives a refresh\n // fired right after the click.\n persistConfig()\n syncBg()\n },\n setRegenerateOnReload: (v: boolean) => {\n cfg.regenerateOnReload = v\n // Immediate (non-debounced) write: a debounced save can be cut off by\n // page unload, which would revert the toggle on the next refresh.\n persistConfig()\n syncBg()\n },\n setOps: (ops: PartOpacities) => { cfg.opacities = ops; applyWp(); syncBg(); saveConfig() },\n setBlurs: (blurs: PartBlurs) => { cfg.blurs = blurs; applyWp(); syncBg(); saveConfig() },\n setStrokes: (strokes: PartStrokes) => { cfg.strokes = strokes; applyStrokes(); saveConfig() },\n // Optimistic upload: render the picked file from a local blob URL at\n // once, stream the bytes to disk, then swap the @font-face to the\n // persisted slot. A rejected upload rolls the preview back to whatever\n // was stored before (nothing, on a first failure).\n setFont: async (file: File): Promise<UploadOutcome> => {\n releaseFontPreview(0)\n const localUrl = URL.createObjectURL(file)\n fontPreviewUrl = localUrl\n applyFontFace(localUrl, true, fontMimeFromName(file.name))\n const outcome = await uploadFont(file)\n if (!outcome.ok || outcome.mime === undefined) {\n applyStoredFont()\n releaseFontPreview(4000)\n return { ok: false, refusal: outcome.refusal }\n }\n cfg.fontMime = outcome.mime\n cfg.fontEnabled = true\n applyFontFace(FONT_SERVE_URL, true, outcome.mime)\n releaseFontPreview(4000)\n persistConfig()\n return { ok: true }\n },\n removeFont: () => {\n releaseFontPreview(0)\n cfg.fontMime = null\n applyFontFace(null, false, null)\n void rpcRemoveFont()\n persistConfig()\n },\n setFontEnabled: (v: boolean) => {\n cfg.fontEnabled = v\n applyStoredFont()\n persistConfig()\n },\n setWop: (v: number) => { cfg.wallpaperOpacity = v; applyWp(); syncBg(); saveConfig() },\n setBl: (v: number) => { cfg.blur = v; applyWp(); syncBg(); saveConfig() },\n setSop: (v: number) => { cfg.settingsOpacity = v; applySettingsOverrides(v); saveConfig() },\n setPanelOp: (v: number) => { cfg.panelOpacity = v; applyPanelOverrides(v); saveConfig() },\n // One-click: derive a theme color from the current wallpaper. Purely\n // client-side — no RPC traffic; the sample is a 64×64 canvas.\n extractColor: async (): Promise<boolean> => {\n const url = rWp()\n if (!url) return false\n // Video mode extracts from the frame snapshot through the video's\n // placement state (rWp already returns the snapshot there).\n const st = cfg.backgroundType === 'video' ? rVideoBgState() : rBgState()\n const hsl = await extractWallpaperColor(url, st)\n if (!hsl) return false\n cfg.color = hsl\n registerCustom(hsl[0], hsl[1], hsl[2])\n applyWp()\n saveConfig()\n const hsv = hslToHsv(hsl[0], hsl[1], hsl[2])\n colorRev++\n bound?.syncColor(hsv, colorRev)\n return true\n },\n // Download the whole theme as dsh-any-theme.json: the config plus the\n // wallpaper data URL only when it is an uploaded image, and the video\n // bytes copied in as a data URL when a video background is active.\n // Generated backgrounds are reconstructed from the saved params on\n // import, so their exports stay small.\n exportTheme: async () => {\n let videoPayload: string | null = null\n if (cfg.backgroundType === 'video') {\n const vurl = rWpVideo()\n if (vurl) {\n try {\n const blob = await fetch(vurl).then(r => r.blob())\n videoPayload = await blobToDataUrl(blob)\n // The serve route may report a generic Content-Type; pin the\n // recorded MIME so the import detector sees data:video/….\n if (videoPayload && !/^data:video\\//.test(videoPayload)) {\n videoPayload = videoPayload.replace(/^data:[^;,]*/, `data:${cfg.videoMime ?? 'video/mp4'}`)\n }\n } catch {\n videoPayload = null\n }\n }\n }\n // The wallpaper is displayed through the serve URL; exports embed the\n // bytes (fetched from that URL) so the file is portable.\n let wallpaperPayload: string | null = null\n if (cfg.backgroundType === 'image') {\n const wurl = rWp()\n if (wurl) {\n if (wurl.startsWith('data:')) {\n wallpaperPayload = wurl\n } else {\n try {\n const blob = await fetch(wurl).then(r => r.blob())\n wallpaperPayload = await blobToDataUrl(blob)\n } catch {\n wallpaperPayload = null\n }\n }\n }\n }\n const payload = {\n version: 2,\n exportedAt: new Date().toISOString(),\n config: cfg,\n wallpaper: wallpaperPayload,\n video: videoPayload,\n }\n const blob = new Blob([JSON.stringify(payload, null, 2)], { type: 'application/json' })\n const url = URL.createObjectURL(blob)\n const a = document.createElement('a')\n a.href = url\n a.download = 'dsh-any-theme.json'\n a.click()\n // Firefox and Safari start the download asynchronously; revoking in the\n // same tick can abort it. releaseFontPreview below already uses this\n // delayed-revoke pattern for the same reason.\n window.setTimeout(() => URL.revokeObjectURL(url), 4000)\n },\n // Import a theme JSON: apply the config to memory, then persist through\n // the same paths as manual edits — config → theme-config.json, wallpaper\n // base64 → wallpaper.jpg (decoded on the node half). For generated\n // backgrounds the image is reconstructed from params instead of persisted.\n importTheme: async (file: File): Promise<boolean> => {\n try {\n const data: unknown = JSON.parse(await file.text())\n if (!data || typeof data !== 'object') return false\n const d = data as { version?: number; config?: unknown; wallpaper?: unknown; video?: unknown }\n if (typeof d.config !== 'object' || d.config === null) return false\n adoptConfig(d.config)\n if (cfg.backgroundType === 'video') {\n const video = typeof d.video === 'string' && /^data:video\\//.test(d.video) ? d.video : null\n if (video !== null) {\n // Decode the embedded data URL to a blob and play it instantly\n // from a local object URL while the bytes stream to disk in the\n // background (the data-URL RPC path stays as the small fallback).\n let blob: Blob | null = null\n try { blob = await fetch(video).then(r => r.blob()) } catch { blob = null }\n if (blob !== null) {\n // Fire and forget: the import's own success/failure is already\n // reported, and the embedded video typically exceeds the upload\n // limit anyway (the same cap that made the fetch path win).\n void playVideoFromBlob(blob, cfg.videoMime)\n } else {\n const ok = await persistVideo(video)\n const live = ok ? VIDEO_SERVE_URL : video\n setWpVideoUrl(live, cfg.videoMime)\n applyWp()\n captureAndApplyVideo(rWpVideo())\n }\n } else {\n // Export lacked the video payload: fall back to no background.\n setWpVideoUrl(null, null)\n void persistVideo(null)\n cfg.backgroundType = 'image'\n setWpImageUrl(null)\n setWpUrl(null)\n persistWallpaper(null)\n applyThemeColor()\n }\n } else if (cfg.backgroundType === 'image') {\n const wallpaper = typeof d.wallpaper === 'string' && /^data:image\\//.test(d.wallpaper) ? d.wallpaper : null\n setWpImageUrl(wallpaper)\n setWpUrl(wallpaper)\n persistWallpaper(wallpaper)\n applyThemeColor()\n } else {\n setWpImageUrl(null)\n setWpUrl(null)\n persistWallpaper(null)\n // Reconstruct the imported dynamic background from its saved params.\n // Import means \"restore what I exported\", so the seed/params must be\n // preserved exactly; only regenerate a fresh look when the user has\n // that preference enabled — mirroring the boot-restore branch.\n if (cfg.regenerateOnReload) regenerateGeneratedBg()\n else if (cfg.generatedBg) updateGeneratedBg(cfg.generatedBg)\n }\n persistConfig()\n // The imported file carries profiles / rotation / schedule / scheme\n // too: push them into the meta store or the panels keep rendering the\n // previous lists until the next reload.\n syncMetaNow()\n if (rHasColor()) {\n const [h, s, l] = rColor()\n registerCustom(h, s, l)\n }\n syncBg()\n if (rHasColor()) {\n colorRev++\n bound?.syncColor(hslToHsv(...rColor()), colorRev)\n }\n return true\n } catch {\n return false\n }\n },\n // Save the current appearance as a named profile (oldest dropped at 20).\n saveProfile: (name: string): boolean => {\n const trimmed = name.trim()\n if (!trimmed) return false\n const profiles = [...rProfiles()]\n if (profiles.length >= 20) profiles.shift()\n const id = `p-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`\n profiles.push({ id, name: trimmed.slice(0, 60), createdAt: new Date().toISOString(), config: currentAppearance() })\n cfg.profiles = profiles\n cfg.activeProfile = id\n persistConfig()\n syncMetaNow()\n return true\n },\n applyProfile: (id: string): boolean => applyProfileById(id),\n deleteProfile: (id: string): boolean => {\n const before = rProfiles()\n if (!before.some(p => p.id === id)) return false\n cfg.profiles = before.filter(p => p.id !== id)\n if (cfg.activeProfile === id) cfg.activeProfile = null\n // Clear schedule references so the tick never targets a dead id.\n const sc = rSchedule()\n if (sc.dayProfile === id || sc.nightProfile === id) {\n cfg.schedule = {\n ...sc,\n dayProfile: sc.dayProfile === id ? null : sc.dayProfile,\n nightProfile: sc.nightProfile === id ? null : sc.nightProfile,\n }\n }\n persistConfig()\n syncMetaNow()\n return true\n },\n applyPreset: (appearance: ProfileAppearance): void => {\n applyAppearanceLive(appearance)\n cfg.activeProfile = null\n applyWp()\n persistConfig()\n syncMetaNow()\n },\n setSchemeOverride: (v: SchemeOverride): void => {\n cfg.schemeOverride = v\n // Re-register the skin in every case: with a color the palette follows\n // the forced direction; without one a neutral palette is registered so\n // the host presenter flips the fonts too.\n registerCustom()\n applyWp()\n saveConfig()\n syncMetaNow()\n },\n setSchedule: (patch: Partial<ScheduleConfig>): void => {\n cfg.schedule = { ...rSchedule(), ...patch }\n if (patch.enabled === true) scheduleTick()\n persistConfig()\n syncMetaNow()\n },\n setRotation: (patch: Partial<Pick<typeof cfg.rotation, 'enabled' | 'mode' | 'interval'>>): void => {\n cfg.rotation = { ...rRotation(), ...patch }\n if (patch.enabled === true) void maybeRotate()\n persistConfig()\n syncMetaNow()\n },\n addRotationItems: async (files: File[]): Promise<boolean> => {\n let added = false\n for (const f of files) {\n if (!f.type.startsWith('image/')) continue\n const dataUrl = await readImgAsync(f)\n if (!dataUrl) continue\n const thumb = await makeThumb(dataUrl)\n const r = await rotationAdd(dataUrl, thumb ?? '')\n if (r.ok && r.items !== undefined) {\n cfg.rotation = { ...rRotation(), items: r.items as RotationItem[] }\n added = true\n }\n }\n if (added) {\n // Server already wrote the items into its config copy; re-persist so\n // the client's full config (meta included) stays authoritative.\n persistConfig()\n syncMetaNow()\n syncBg()\n }\n return added\n },\n removeRotationItem: async (index: number): Promise<boolean> => {\n const r = await rotationRemove(index)\n if (!r.ok || r.items === undefined) return false\n const rot = rRotation()\n cfg.rotation = {\n ...rot,\n items: r.items as RotationItem[],\n current: Math.max(0, Math.min(rot.current >= index ? rot.current - 1 : rot.current, Math.max(0, r.items.length - 1))),\n }\n persistConfig()\n syncMetaNow()\n return true\n },\n rotateNow: async (): Promise<boolean> => {\n if (rRotation().items.length === 0) return false\n return applyRotationIndex(pickNextRotationIndex(), true)\n },\n // Network video URL: the server streams it into the video slot; the\n // client switches to video mode and plays from the serve URL, then\n // captures the preview frame through the same path as local uploads.\n setVideoFromUrl: async (url: string): Promise<boolean> => {\n const r = await rpcSetVideoFromUrl(url)\n if (!r.ok || !r.mime) {\n console.warn('dsh-any-background: video url fetch failed', r.error)\n return false\n }\n setBgDark(null)\n cfg.backgroundType = 'video'\n setWpUrl(null)\n cfg.videoBgState = { ...DEFAULT_CONFIG.bgState }\n setWpVideoUrl(VIDEO_SERVE_URL, r.mime)\n applyWp()\n saveConfig()\n syncBg()\n captureAndApplyVideo(rWpVideo())\n return true\n },\n }\n themeFace = built\n return built\n }\n // The settings slot's inject face: it still owns binding the actions the host\n // hands over (the very actions of the shared instance), then returns the shared\n // face so both surfaces read one instance of it.\n const sectionInject = (actions: BoundActions): Omit<ThemeSectionProps, 'useStore'> => {\n bound = actions\n return buildFace()\n }\n if (store === null) {\n // No host store module (see runtime.ts): the section needs one to bind its\n // props, so register nothing. The theme/wallpaper half above still works.\n console.error('dsh-any-background: settings panel disabled on this host (no store module)')\n } else {\n ctx.slots.inject('settings.section', () => ctx.slots.register({\n name: 'settings.section', id: 'dsh-any-background', order: 35,\n label: () => ctx.locale.bind(NS)('nav'),\n locale: NS, store, inject: sectionInject,\n }, ThemeSection as any))\n }\n\n // 6.1. Sidebar pages: the same five pages, registered twice by surface —\n // as a better-sidebar tab when that plugin is installed, and as a native\n // right-Sidebar tab (\"主题\" card on the official Sidebar's guide page) when\n // it is not. Both are runtime-optional — see the modules for how each\n // service is resolved without importing it. `storeInstance` (not the\n // declaration) is what either page's selector hook has to bind.\n registerThemeSidebarTab(ctx, { face: buildFace, store: storeInstance })\n registerNativeSidebarTab(ctx, { face: buildFace, store: storeInstance })\n\n // 6.5. Settings-nav icon: the harness derives the nav glyph from the section\n // id (unknown ids fall back to the settings gear) with no plugin hook, so\n // patch the mounted nav cell in place — find the cell whose label matches\n // this section's nav text and swap its svg for the sun glyph.\n const navLabel = (): string => ctx.locale.bind(NS)('nav')\n const applyNavIcon = (): void => {\n // SETTINGS_PANEL_SEL rather than the ARIA shape: a confirm dialog is an\n // aria-modal dialog with a labelledby too, and document order decides which one\n // a loose query returns — so the glyph would go missing whenever that dialog\n // happens to precede a re-mounted settings panel. Same anchor as the styles.\n const panel = document.querySelector<HTMLElement>(SETTINGS_PANEL_SEL)\n const nav = panel?.querySelector('nav')\n if (!nav) return\n const target = navLabel()\n for (const cell of Array.from(nav.querySelectorAll('button'))) {\n const label = cell.querySelector('span')\n if (label && label.textContent?.trim() === target) {\n const svg = cell.querySelector('svg')\n if (svg && svg.dataset.dshAnyIcon !== '1') {\n const sun = document.createElementNS('http://www.w3.org/2000/svg', 'svg')\n sun.setAttribute('width', '16')\n sun.setAttribute('height', '16')\n sun.setAttribute('viewBox', '0 0 16 16')\n sun.setAttribute('fill', 'none')\n sun.setAttribute('xmlns', 'http://www.w3.org/2000/svg')\n sun.dataset.dshAnyIcon = '1'\n sun.innerHTML = SUN_PATHS\n svg.replaceWith(sun)\n }\n return\n }\n }\n }\n let navIconObserver: MutationObserver | null = null\n const watchNavIcon = (): void => {\n if (navIconObserver !== null || typeof MutationObserver === 'undefined') return\n navIconObserver = new MutationObserver(records => {\n // React only when the settings panel (or its nav) is (re)created, so\n // chat-content mutations don't trigger a scan.\n const relevant = records.some(r => {\n for (const n of r.addedNodes) {\n if (n.nodeType !== 1) continue\n const el = n as Element\n if (el.matches?.(SETTINGS_PANEL_SEL) || el.querySelector?.(SETTINGS_PANEL_SEL)) return true\n }\n return false\n })\n if (relevant) applyNavIcon()\n })\n navIconObserver.observe(document.body, { childList: true, subtree: true })\n applyNavIcon()\n }\n watchNavIcon()\n ctx.effect(() => () => { navIconObserver?.disconnect(); navIconObserver = null }, 'dsh-any-background: nav icon watch')\n\n // 7. Deferred boot restore: the theme service and the host settings scope\n // settle asynchronously after this apply, so the synchronous restore can be\n // observed mid-flight — a late host adoption resets the preference, or the\n // presenter re-applies over our overrides. Re-running the saved-color and\n // wallpaper restore a few ticks later guarantees the saved records land.\n const restoreSaved = (): void => {\n if (rHasColor()) {\n const snapshot = ctx.theme.getTheme()\n if (!snapshot.themes.some(t => t.id === CUSTOM_ID)) {\n // Theme missing (host adoption dropped it): re-register + activate.\n const [h, s, l] = rColor()\n registerCustom(h, s, l)\n } else if (snapshot.preference !== CUSTOM_ID) {\n // Theme present but inactive: just re-assert the preference. Calling\n // registerCustom here would dispose + re-create the skin, flashing the\n // interface back to the system theme for a frame on every boot.\n ctx.theme.setTheme(CUSTOM_ID)\n }\n }\n applyWp()\n }\n const restoreTimers = [300, 1500].map(delay => window.setTimeout(restoreSaved, delay))\n ctx.effect(() => () => { restoreTimers.forEach(id => window.clearTimeout(id)) }, 'dsh-any-background: boot restore')\n\n // 8. Theme watchdog: the theme service keeps only built-in preferences in\n // memory, so ANY host-scope adoption can silently drop the custom theme —\n // reverting the label colors (white/black) and the inner surfaces to the\n // system palette. While the skin has anything to say (a color, a brightness\n // verdict, or a forced scheme), re-register and re-assert the custom theme\n // on a slow interval so the theme state always matches it, independent of\n // which event resets it.\n const watchdogId = window.setInterval(() => {\n if (!rHasColor() && rBgDark() === null && rSchemeOverride() === 'auto') return\n const snapshot = ctx.theme.getTheme()\n let changed = false\n if (!snapshot.themes.some(t => t.id === CUSTOM_ID)) {\n registerCustom()\n changed = true\n } else if (snapshot.preference !== CUSTOM_ID) {\n ctx.theme.setTheme(CUSTOM_ID)\n changed = true\n }\n if (changed) applyWp()\n }, 1000)\n ctx.effect(() => () => { window.clearInterval(watchdogId) }, 'dsh-any-background: theme watchdog')\n\n // 8.5. Theme-reset watchdog: counter the host re-asserting its own light\n // :root/body scheme after startup (refresh, cold load, settings adoption),\n // which would paint a frame of white surfaces.\n const disposeThemeResets = watchThemeResets()\n ctx.effect(() => () => { disposeThemeResets() }, 'dsh-any-background: theme resets watch')\n\n // 9. Flush any pending debounced config write when the page is hidden or\n // closed, so the last slider position is never lost to the debounce window.\n const onPageHide = (): void => flushSave()\n window.addEventListener('pagehide', onPageHide)\n ctx.effect(() => () => window.removeEventListener('pagehide', onPageHide), 'dsh-any-background: pagehide flush')\n}\n"],"mappings":"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"}