@circadian/sol 0.2.8 → 0.2.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["WMO_MAP: Record<number, WeatherCategory>","fetchWeather","WMO_MAP","useWeatherData","finalPalette: WidgetPalette","opts: Intl.DateTimeFormatOptions","liveWeatherCategory: WeatherCategory | null","liveTemperatureC: number | null","WMO_MAP: Record<number, WeatherCategory>","palette: WidgetPalette","liveWeatherCategory: WeatherCategory | null","liveTemperatureC: number | null","props: CompactSkinProps","opts: Intl.DateTimeFormatOptions"],"sources":["../src/widgets/solar-widget.shell.tsx","../src/widgets/compact-widget.shell.tsx"],"sourcesContent":["'use client';\n\n/**\n * widgets/solar-widget.shell.tsx (skin-aware shell)\n *\n * Weather fetch is now centralised here alongside the compact shell:\n * - Fetches temperature + weather_code from open-meteo once per mount\n * - Resolves liveWeatherCategory: weatherCategoryOverride ?? live category\n * - Passes liveWeatherCategory + liveTemperatureC down to skin components\n * - Skins should prefer these props over running their own fetch\n *\n * simulatedDate prop wins over ctx.simulatedDate (set by SolarDevTools),\n * which wins over undefined (live time). This means the devtools timeline\n * scrubber moves the orb in every widget without requiring any prop wiring.\n */\n\nimport { useEffect, useLayoutEffect, useMemo, useState } from 'react';\nimport type { SolarPhase } from '../hooks/useSolarPosition';\nimport { lerpHex } from '../lib/solar-lerp';\nimport { useSolarTheme } from '../provider/solar-theme-provider';\nimport type { DesignMode, WidgetPalette } from '../skins/types/widget-skin.types';\n\n// ─── Re-exported types ────────────────────────────────────────────────────────\n\nexport type ExpandDirection =\n | 'top-left'\n | 'top-center'\n | 'top-right'\n | 'center-left'\n | 'center'\n | 'center-right'\n | 'bottom-left'\n | 'bottom-center'\n | 'bottom-right';\n\nexport type WidgetSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl';\n\nexport type WeatherCategory =\n | 'clear'\n | 'partly-cloudy'\n | 'overcast'\n | 'fog'\n | 'drizzle'\n | 'rain'\n | 'heavy-rain'\n | 'snow'\n | 'heavy-snow'\n | 'thunder';\n\nexport type CustomPalettes = Partial<Record<SolarPhase, { bg: [string, string, string] }>>;\n\nimport { SKINS } from '../skins/index';\nexport const PALETTES = SKINS.foundry.widgetPalettes;\n\n// ─── WMO weather code map ─────────────────────────────────────────────────────\n\nconst WMO_MAP: Record<number, WeatherCategory> = {\n 0: 'clear',\n 1: 'clear',\n 2: 'partly-cloudy',\n 3: 'overcast',\n 45: 'fog',\n 48: 'fog',\n 51: 'drizzle',\n 53: 'drizzle',\n 55: 'drizzle',\n 61: 'rain',\n 63: 'rain',\n 65: 'heavy-rain',\n 71: 'snow',\n 73: 'snow',\n 75: 'heavy-snow',\n 80: 'rain',\n 82: 'heavy-rain',\n 85: 'snow',\n 86: 'heavy-snow',\n 95: 'thunder',\n 96: 'thunder',\n 99: 'thunder',\n};\n\ninterface LiveWeather {\n temperatureC: number;\n category: WeatherCategory;\n}\n\nasync function fetchWeather(lat: number, lon: number): Promise<LiveWeather> {\n const url = new URL('https://api.open-meteo.com/v1/forecast');\n url.searchParams.set('latitude', String(lat));\n url.searchParams.set('longitude', String(lon));\n url.searchParams.set('current', 'temperature_2m,weather_code');\n url.searchParams.set('forecast_days', '1');\n const data = (await fetch(url.toString()).then((r) => r.json())) as {\n current: { temperature_2m: number; weather_code: number };\n };\n return {\n temperatureC: Math.round(data.current.temperature_2m),\n category: WMO_MAP[data.current.weather_code] ?? 'clear',\n };\n}\n\nfunction useWeatherData(lat: number | null, lon: number | null) {\n const [weather, setWeather] = useState<LiveWeather | null>(null);\n useEffect(() => {\n if (!lat || !lon) return;\n let dead = false;\n fetchWeather(lat, lon)\n .then((w) => {\n if (!dead) setWeather(w);\n })\n .catch(() => {});\n const id = setInterval(\n () =>\n fetchWeather(lat, lon)\n .then((w) => {\n if (!dead) setWeather(w);\n })\n .catch(() => {}),\n 30 * 60 * 1000,\n );\n return () => {\n dead = true;\n clearInterval(id);\n };\n }, [lat, lon]);\n return weather;\n}\n\n// ─── Widget props ─────────────────────────────────────────────────────────────\n\nexport interface SolarWidgetProps {\n expandDirection?: ExpandDirection;\n size?: WidgetSize;\n showFlag?: boolean;\n showWeather?: boolean;\n hoverEffect?: boolean;\n customPalettes?: CustomPalettes;\n phaseOverride?: SolarPhase;\n weatherCategoryOverride?: WeatherCategory | null;\n /** Explicit simulated date. Falls back to ctx.simulatedDate (from SolarDevTools)\n * then to real current time. */\n simulatedDate?: Date;\n /** Lock the widget state: `true` = always expanded, `false` = always collapsed.\n * Omit or pass `undefined` for default localStorage-driven behaviour. */\n forceExpanded?: boolean;\n}\n\n// ─── Palette blending helper ──────────────────────────────────────────────────\n\nfunction blendWidgetPalette(from: WidgetPalette, to: WidgetPalette, t: number): WidgetPalette {\n return {\n bg: [\n lerpHex(from.bg[0], to.bg[0], t),\n lerpHex(from.bg[1], to.bg[1], t),\n lerpHex(from.bg[2], to.bg[2], t),\n ],\n textColor: lerpHex(from.textColor, to.textColor, t),\n accentColor: lerpHex(from.accentColor, to.accentColor, t),\n orb: lerpHex(from.orb, to.orb, t),\n outerGlow: from.outerGlow,\n mode: t < 0.5 ? from.mode : to.mode,\n };\n}\n\n// ─── Shell component ──────────────────────────────────────────────────────────\n\nexport function SolarWidget({\n expandDirection = 'bottom-right',\n size = 'lg',\n showFlag = false,\n showWeather = false,\n hoverEffect = false,\n customPalettes,\n phaseOverride,\n weatherCategoryOverride,\n simulatedDate: simulatedDateProp,\n forceExpanded,\n}: SolarWidgetProps) {\n const [mounted, setMounted] = useState(false);\n useLayoutEffect(() => setMounted(true), []);\n\n const {\n phase,\n blend,\n activeSkin,\n timezone,\n latitude,\n longitude,\n simulatedDate: ctxSimulatedDate,\n setCustomPalettes,\n } = useSolarTheme();\n\n // Register customPalettes into context so DevTools can read them\n useEffect(() => {\n setCustomPalettes(customPalettes);\n return () => setCustomPalettes(undefined);\n }, [customPalettes, setCustomPalettes]);\n\n // prop wins → context (devtools) → undefined (live)\n const simulatedDate = simulatedDateProp ?? ctxSimulatedDate;\n\n const [expanded, setExpanded] = useState(false);\n\n const activePhase = phaseOverride ?? phase;\n const activeBlend = phaseOverride\n ? { phase: phaseOverride, nextPhase: phaseOverride, t: 0 }\n : blend;\n\n const fromPalette = activeSkin.widgetPalettes[activeBlend.phase];\n const toPalette = activeSkin.widgetPalettes[activeBlend.nextPhase];\n\n const blendedPalette = useMemo(\n () => blendWidgetPalette(fromPalette, toPalette, activeBlend.t),\n [fromPalette, toPalette, activeBlend.t],\n );\n\n const finalPalette: WidgetPalette = useMemo(() => {\n if (!customPalettes?.[activePhase]) return blendedPalette;\n return { ...blendedPalette, bg: customPalettes[activePhase]?.bg };\n }, [blendedPalette, customPalettes, activePhase]);\n\n const time = useMemo(() => {\n const d = simulatedDate ?? new Date();\n const opts: Intl.DateTimeFormatOptions = {\n hour: '2-digit',\n minute: '2-digit',\n hourCycle: 'h23',\n };\n if (timezone) opts.timeZone = timezone;\n const parts = new Intl.DateTimeFormat('en-GB', opts).formatToParts(d);\n const hh = parts.find((p) => p.type === 'hour')?.value ?? '00';\n const mm = parts.find((p) => p.type === 'minute')?.value ?? '00';\n return `${hh}:${mm}`;\n }, [simulatedDate, timezone]);\n\n // ── Centralised weather fetch ────────────────────────────────────────────\n const liveWeather = useWeatherData(latitude ?? null, longitude ?? null);\n\n const liveWeatherCategory: WeatherCategory | null = showWeather\n ? (weatherCategoryOverride ?? liveWeather?.category ?? null)\n : null;\n\n const liveTemperatureC: number | null = liveWeather?.temperatureC ?? null;\n\n const SkinComponent = activeSkin.Component;\n\n return (\n <div style={{ visibility: mounted ? 'visible' : 'hidden' }}>\n <SkinComponent\n phase={activePhase}\n blend={activeBlend}\n expanded={expanded}\n onToggle={() => setExpanded((v) => !v)}\n expandDirection={expandDirection}\n size={size}\n time={time}\n location=\"\"\n showFlag={showFlag}\n showWeather={showWeather}\n hoverEffect={hoverEffect}\n weather={weatherCategoryOverride}\n liveWeatherCategory={liveWeatherCategory}\n liveTemperatureC={liveTemperatureC}\n palette={finalPalette}\n latitude={latitude}\n longitude={longitude}\n timezone={timezone}\n simulatedDate={simulatedDate}\n forceExpanded={forceExpanded}\n />\n </div>\n );\n}\n","'use client';\n\n/**\n * widgets/compact-widget.shell.tsx\n *\n * Shell for the compact solar widget — a slim pill/bar format.\n *\n * simulatedDate prop wins over ctx.simulatedDate (set by SolarDevTools),\n * which wins over undefined (live time). This means the devtools timeline\n * scrubber moves the orb in compact widgets without requiring any prop wiring.\n */\n\nimport { useEffect, useLayoutEffect, useMemo, useState } from 'react';\nimport type { SolarBlend, SolarPhase } from '../hooks/useSolarPosition';\nimport { lerpHex } from '../lib/solar-lerp';\nimport { useSolarTheme } from '../provider/solar-theme-provider';\nimport type { DesignMode, SkinDefinition, WidgetPalette } from '../skins/types/widget-skin.types';\nimport type { CustomPalettes } from './solar-widget.shell';\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n\nexport type WeatherCategory =\n | 'clear'\n | 'partly-cloudy'\n | 'overcast'\n | 'fog'\n | 'drizzle'\n | 'rain'\n | 'heavy-rain'\n | 'snow'\n | 'heavy-snow'\n | 'thunder';\n\nexport type CompactSize = 'sm' | 'md' | 'lg';\n\n// ─── WMO weather code map ─────────────────────────────────────────────────────\n\nconst WMO_MAP: Record<number, WeatherCategory> = {\n 0: 'clear',\n 1: 'clear',\n 2: 'partly-cloudy',\n 3: 'overcast',\n 45: 'fog',\n 48: 'fog',\n 51: 'drizzle',\n 53: 'drizzle',\n 55: 'drizzle',\n 61: 'rain',\n 63: 'rain',\n 65: 'heavy-rain',\n 71: 'snow',\n 73: 'snow',\n 75: 'heavy-snow',\n 80: 'rain',\n 82: 'heavy-rain',\n 85: 'snow',\n 86: 'heavy-snow',\n 95: 'thunder',\n 96: 'thunder',\n 99: 'thunder',\n};\n\n// ─── Centralised weather fetch ────────────────────────────────────────────────\n\ninterface LiveWeather {\n temperatureC: number;\n category: WeatherCategory;\n}\n\nasync function fetchWeather(lat: number, lon: number): Promise<LiveWeather> {\n const url = new URL('https://api.open-meteo.com/v1/forecast');\n url.searchParams.set('latitude', String(lat));\n url.searchParams.set('longitude', String(lon));\n url.searchParams.set('current', 'temperature_2m,weather_code');\n url.searchParams.set('forecast_days', '1');\n const data = (await fetch(url.toString()).then((r) => r.json())) as {\n current: { temperature_2m: number; weather_code: number };\n };\n return {\n temperatureC: Math.round(data.current.temperature_2m),\n category: WMO_MAP[data.current.weather_code] ?? 'clear',\n };\n}\n\nfunction useWeatherData(lat: number | null, lon: number | null) {\n const [weather, setWeather] = useState<LiveWeather | null>(null);\n useEffect(() => {\n if (!lat || !lon) return;\n let dead = false;\n fetchWeather(lat, lon)\n .then((w) => {\n if (!dead) setWeather(w);\n })\n .catch(() => {});\n const id = setInterval(\n () =>\n fetchWeather(lat, lon)\n .then((w) => {\n if (!dead) setWeather(w);\n })\n .catch(() => {}),\n 30 * 60 * 1000,\n );\n return () => {\n dead = true;\n clearInterval(id);\n };\n }, [lat, lon]);\n return weather;\n}\n\n// ─── Props passed to every compact skin component ─────────────────────────────\n\nexport interface CompactSkinProps {\n phase: SolarPhase;\n blend: SolarBlend;\n time: string;\n location: string;\n flag?: string;\n temperature?: string;\n weather?: WeatherCategory | null;\n liveWeatherCategory: WeatherCategory | null;\n liveTemperatureC: number | null;\n latitude?: number | null;\n longitude?: number | null;\n timezone?: string | null;\n simulatedDate?: Date;\n showFlag: boolean;\n showWeather: boolean;\n showTemperature: boolean;\n size: CompactSize;\n palette: WidgetPalette;\n}\n\n// ─── Public props for the shell ───────────────────────────────────────────────\n\nexport interface CompactWidgetProps {\n design?: DesignMode;\n overridePhase?: SolarPhase | null;\n time?: string;\n location?: string;\n flag?: string;\n temperature?: string;\n weather?: WeatherCategory | null;\n weatherCategoryOverride?: WeatherCategory | null;\n showFlag?: boolean;\n showWeather?: boolean;\n showTemperature?: boolean;\n size?: CompactSize;\n latitude?: number | null;\n longitude?: number | null;\n timezone?: string | null;\n /** Override background colors per phase */\n customPalettes?: CustomPalettes;\n /** Explicit simulated date. Falls back to ctx.simulatedDate (from SolarDevTools)\n * then to real current time. */\n simulatedDate?: Date;\n className?: string;\n}\n\n// ─── Palette blending ─────────────────────────────────────────────────────────\n\nfunction blendPalette(skin: SkinDefinition, blend: SolarBlend): WidgetPalette {\n const from = skin.widgetPalettes[blend.phase];\n const to = skin.widgetPalettes[blend.nextPhase];\n const t = blend.t;\n if (t === 0) return from;\n const lerp = (a: string, b: string) => lerpHex(a, b, t);\n return {\n bg: [lerp(from.bg[0], to.bg[0]), lerp(from.bg[1], to.bg[1]), lerp(from.bg[2], to.bg[2])] as [\n string,\n string,\n string,\n ],\n textColor: lerp(from.textColor, to.textColor),\n accentColor: lerp(from.accentColor, to.accentColor),\n orb: lerp(from.orb, to.orb),\n outerGlow: lerp(from.outerGlow, to.outerGlow),\n mode: from.mode,\n };\n}\n\n// ─── Shell ────────────────────────────────────────────────────────────────────\n\nexport function CompactWidget({\n design: designOverride,\n overridePhase,\n time,\n location = '',\n flag,\n temperature,\n weather = null,\n weatherCategoryOverride,\n showFlag = false,\n showWeather = false,\n showTemperature = true,\n size = 'md',\n latitude,\n longitude,\n timezone,\n customPalettes,\n simulatedDate: simulatedDateProp,\n className = '',\n}: CompactWidgetProps) {\n const [mounted, setMounted] = useState(false);\n useLayoutEffect(() => setMounted(true), []);\n\n const ctx = useSolarTheme();\n\n // Register customPalettes into context so DevTools can read them\n useEffect(() => {\n ctx.setCustomPalettes(customPalettes);\n return () => ctx.setCustomPalettes(undefined);\n }, [customPalettes, ctx.setCustomPalettes]);\n\n // prop wins → context (devtools) → undefined (live)\n const simulatedDate = simulatedDateProp ?? ctx.simulatedDate;\n\n const skin = useMemo(() => {\n if (!designOverride || designOverride === ctx.design) return ctx.activeSkin;\n return ctx.activeSkin;\n }, [designOverride, ctx.design, ctx.activeSkin]);\n\n const phase = overridePhase ?? ctx.phase;\n const blend = overridePhase\n ? { phase: overridePhase, nextPhase: overridePhase, t: 0 }\n : ctx.blend;\n\n const blendedPalette = useMemo(() => blendPalette(skin, blend), [skin, blend]);\n\n const palette: WidgetPalette = useMemo(() => {\n if (!customPalettes?.[phase]) return blendedPalette;\n return { ...blendedPalette, bg: customPalettes[phase]?.bg };\n }, [blendedPalette, customPalettes, phase]);\n\n const resolvedLat = latitude ?? ctx.latitude;\n const resolvedLon = longitude ?? ctx.longitude;\n const resolvedTz = timezone ?? ctx.timezone;\n\n // ── Centralised weather fetch ────────────────────────────────────────────\n const liveWeather = useWeatherData(resolvedLat ?? null, resolvedLon ?? null);\n\n const liveWeatherCategory: WeatherCategory | null = showWeather\n ? (weatherCategoryOverride ?? weather ?? liveWeather?.category ?? null)\n : null;\n\n const liveTemperatureC: number | null = liveWeather?.temperatureC ?? null;\n\n // ── Resolve time string ──────────────────────────────────────────────────\n // If caller passes an explicit time string, use it. Otherwise derive from\n // simulatedDate (or real time) so the clock display matches the orb.\n const resolvedTime = useMemo(() => {\n if (time) return time;\n const d = simulatedDate ?? new Date();\n const opts: Intl.DateTimeFormatOptions = {\n hour: '2-digit',\n minute: '2-digit',\n hourCycle: 'h23',\n };\n if (resolvedTz) opts.timeZone = resolvedTz;\n const parts = new Intl.DateTimeFormat('en-GB', opts).formatToParts(d);\n const hh = parts.find((p) => p.type === 'hour')?.value ?? '00';\n const mm = parts.find((p) => p.type === 'minute')?.value ?? '00';\n return `${hh}:${mm}`;\n }, [time, simulatedDate, resolvedTz]);\n\n const props: CompactSkinProps = {\n phase,\n blend,\n time: resolvedTime,\n location,\n flag,\n temperature,\n weather,\n liveWeatherCategory,\n liveTemperatureC,\n latitude: resolvedLat,\n longitude: resolvedLon,\n timezone: resolvedTz,\n simulatedDate,\n showFlag,\n showWeather,\n showTemperature,\n size,\n palette,\n };\n\n const CompactComponent = (\n skin as SkinDefinition & {\n CompactComponent?: React.ComponentType<CompactSkinProps>;\n }\n ).CompactComponent;\n\n if (!CompactComponent) {\n return (\n <div className={className} style={{ opacity: 0.4, fontSize: 11, color: '#888' }}>\n Compact not implemented for {skin.id}\n </div>\n );\n }\n\n return (\n <div\n className={className}\n style={{ visibility: mounted ? 'visible' : 'hidden', isolation: 'isolate' }}\n >\n <CompactComponent {...props} />\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["WMO_MAP: Record<number, WeatherCategory>","fetchWeather","WMO_MAP","useWeatherData","finalPalette: WidgetPalette","opts: Intl.DateTimeFormatOptions","liveWeatherCategory: WeatherCategory | null","liveTemperatureC: number | null","WMO_MAP: Record<number, WeatherCategory>","palette: WidgetPalette","liveWeatherCategory: WeatherCategory | null","liveTemperatureC: number | null","props: CompactSkinProps","opts: Intl.DateTimeFormatOptions","UNIVERSAL_PHASE_MOTION: MotionProfile","VOID_MOTION: MotionProfile","PARCHMENT_MOTION: MotionProfile","SIGNAL_MOTION: MotionProfile","MERIDIAN_MOTION: MotionProfile","SUNDIAL_MOTION: MotionProfile","PAPER_MOTION: MotionProfile","FOUNDRY_MOTION: MotionProfile","MINERAL_MOTION: MotionProfile","TIDE_MOTION: MotionProfile","AURORA_MOTION: MotionProfile","SKIN_MOTION_PROFILES: Record<DesignMode, MotionProfile>"],"sources":["../src/widgets/solar-widget.shell.tsx","../src/widgets/compact-widget.shell.tsx","../src/shared/shader-motion-profiles.tsx","../src/shared/solar-shader-bg.tsx"],"sourcesContent":["'use client';\n\n/**\n * widgets/solar-widget.shell.tsx (skin-aware shell)\n *\n * Weather fetch is now centralised here alongside the compact shell:\n * - Fetches temperature + weather_code from open-meteo once per mount\n * - Resolves liveWeatherCategory: weatherCategoryOverride ?? live category\n * - Passes liveWeatherCategory + liveTemperatureC down to skin components\n * - Skins should prefer these props over running their own fetch\n *\n * simulatedDate prop wins over ctx.simulatedDate (set by SolarDevTools),\n * which wins over undefined (live time). This means the devtools timeline\n * scrubber moves the orb in every widget without requiring any prop wiring.\n */\n\nimport { useEffect, useLayoutEffect, useMemo, useState } from 'react';\nimport type { SolarPhase } from '../hooks/useSolarPosition';\nimport { lerpHex } from '../lib/solar-lerp';\nimport { useSolarTheme } from '../provider/solar-theme-provider';\nimport type { DesignMode, WidgetPalette } from '../skins/types/widget-skin.types';\n\n// ─── Re-exported types ────────────────────────────────────────────────────────\n\nexport type ExpandDirection =\n | 'top-left'\n | 'top-center'\n | 'top-right'\n | 'center-left'\n | 'center'\n | 'center-right'\n | 'bottom-left'\n | 'bottom-center'\n | 'bottom-right';\n\nexport type WidgetSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl';\n\nexport type WeatherCategory =\n | 'clear'\n | 'partly-cloudy'\n | 'overcast'\n | 'fog'\n | 'drizzle'\n | 'rain'\n | 'heavy-rain'\n | 'snow'\n | 'heavy-snow'\n | 'thunder';\n\nexport type CustomPalettes = Partial<Record<SolarPhase, { bg: [string, string, string] }>>;\n\nimport { SKINS } from '../skins/index';\nexport const PALETTES = SKINS.foundry.widgetPalettes;\n\n// ─── WMO weather code map ─────────────────────────────────────────────────────\n\nconst WMO_MAP: Record<number, WeatherCategory> = {\n 0: 'clear',\n 1: 'clear',\n 2: 'partly-cloudy',\n 3: 'overcast',\n 45: 'fog',\n 48: 'fog',\n 51: 'drizzle',\n 53: 'drizzle',\n 55: 'drizzle',\n 61: 'rain',\n 63: 'rain',\n 65: 'heavy-rain',\n 71: 'snow',\n 73: 'snow',\n 75: 'heavy-snow',\n 80: 'rain',\n 82: 'heavy-rain',\n 85: 'snow',\n 86: 'heavy-snow',\n 95: 'thunder',\n 96: 'thunder',\n 99: 'thunder',\n};\n\ninterface LiveWeather {\n temperatureC: number;\n category: WeatherCategory;\n}\n\nasync function fetchWeather(lat: number, lon: number): Promise<LiveWeather> {\n const url = new URL('https://api.open-meteo.com/v1/forecast');\n url.searchParams.set('latitude', String(lat));\n url.searchParams.set('longitude', String(lon));\n url.searchParams.set('current', 'temperature_2m,weather_code');\n url.searchParams.set('forecast_days', '1');\n const data = (await fetch(url.toString()).then((r) => r.json())) as {\n current: { temperature_2m: number; weather_code: number };\n };\n return {\n temperatureC: Math.round(data.current.temperature_2m),\n category: WMO_MAP[data.current.weather_code] ?? 'clear',\n };\n}\n\nfunction useWeatherData(lat: number | null, lon: number | null) {\n const [weather, setWeather] = useState<LiveWeather | null>(null);\n useEffect(() => {\n if (!lat || !lon) return;\n let dead = false;\n fetchWeather(lat, lon)\n .then((w) => {\n if (!dead) setWeather(w);\n })\n .catch(() => {});\n const id = setInterval(\n () =>\n fetchWeather(lat, lon)\n .then((w) => {\n if (!dead) setWeather(w);\n })\n .catch(() => {}),\n 30 * 60 * 1000,\n );\n return () => {\n dead = true;\n clearInterval(id);\n };\n }, [lat, lon]);\n return weather;\n}\n\n// ─── Widget props ─────────────────────────────────────────────────────────────\n\nexport interface SolarWidgetProps {\n expandDirection?: ExpandDirection;\n size?: WidgetSize;\n showFlag?: boolean;\n showWeather?: boolean;\n hoverEffect?: boolean;\n customPalettes?: CustomPalettes;\n phaseOverride?: SolarPhase;\n weatherCategoryOverride?: WeatherCategory | null;\n /** Explicit simulated date. Falls back to ctx.simulatedDate (from SolarDevTools)\n * then to real current time. */\n simulatedDate?: Date;\n /** Lock the widget state: `true` = always expanded, `false` = always collapsed.\n * Omit or pass `undefined` for default localStorage-driven behaviour. */\n forceExpanded?: boolean;\n}\n\n// ─── Palette blending helper ──────────────────────────────────────────────────\n\nfunction blendWidgetPalette(from: WidgetPalette, to: WidgetPalette, t: number): WidgetPalette {\n return {\n bg: [\n lerpHex(from.bg[0], to.bg[0], t),\n lerpHex(from.bg[1], to.bg[1], t),\n lerpHex(from.bg[2], to.bg[2], t),\n ],\n textColor: lerpHex(from.textColor, to.textColor, t),\n accentColor: lerpHex(from.accentColor, to.accentColor, t),\n orb: lerpHex(from.orb, to.orb, t),\n outerGlow: from.outerGlow,\n mode: t < 0.5 ? from.mode : to.mode,\n };\n}\n\n// ─── Shell component ──────────────────────────────────────────────────────────\n\nexport function SolarWidget({\n expandDirection = 'bottom-right',\n size = 'lg',\n showFlag = false,\n showWeather = false,\n hoverEffect = false,\n customPalettes,\n phaseOverride,\n weatherCategoryOverride,\n simulatedDate: simulatedDateProp,\n forceExpanded,\n}: SolarWidgetProps) {\n const [mounted, setMounted] = useState(false);\n useLayoutEffect(() => setMounted(true), []);\n\n const {\n phase,\n blend,\n activeSkin,\n timezone,\n latitude,\n longitude,\n simulatedDate: ctxSimulatedDate,\n setCustomPalettes,\n } = useSolarTheme();\n\n // Register customPalettes into context so DevTools can read them\n useEffect(() => {\n setCustomPalettes(customPalettes);\n return () => setCustomPalettes(undefined);\n }, [customPalettes, setCustomPalettes]);\n\n // prop wins → context (devtools) → undefined (live)\n const simulatedDate = simulatedDateProp ?? ctxSimulatedDate;\n\n const [expanded, setExpanded] = useState(false);\n\n const activePhase = phaseOverride ?? phase;\n const activeBlend = phaseOverride\n ? { phase: phaseOverride, nextPhase: phaseOverride, t: 0 }\n : blend;\n\n const fromPalette = activeSkin.widgetPalettes[activeBlend.phase];\n const toPalette = activeSkin.widgetPalettes[activeBlend.nextPhase];\n\n const blendedPalette = useMemo(\n () => blendWidgetPalette(fromPalette, toPalette, activeBlend.t),\n [fromPalette, toPalette, activeBlend.t],\n );\n\n const finalPalette: WidgetPalette = useMemo(() => {\n if (!customPalettes?.[activePhase]) return blendedPalette;\n return { ...blendedPalette, bg: customPalettes[activePhase]?.bg };\n }, [blendedPalette, customPalettes, activePhase]);\n\n const time = useMemo(() => {\n const d = simulatedDate ?? new Date();\n const opts: Intl.DateTimeFormatOptions = {\n hour: '2-digit',\n minute: '2-digit',\n hourCycle: 'h23',\n };\n if (timezone) opts.timeZone = timezone;\n const parts = new Intl.DateTimeFormat('en-GB', opts).formatToParts(d);\n const hh = parts.find((p) => p.type === 'hour')?.value ?? '00';\n const mm = parts.find((p) => p.type === 'minute')?.value ?? '00';\n return `${hh}:${mm}`;\n }, [simulatedDate, timezone]);\n\n // ── Centralised weather fetch ────────────────────────────────────────────\n const liveWeather = useWeatherData(latitude ?? null, longitude ?? null);\n\n const liveWeatherCategory: WeatherCategory | null = showWeather\n ? (weatherCategoryOverride ?? liveWeather?.category ?? null)\n : null;\n\n const liveTemperatureC: number | null = liveWeather?.temperatureC ?? null;\n\n const SkinComponent = activeSkin.Component;\n\n return (\n <div style={{ visibility: mounted ? 'visible' : 'hidden' }}>\n <SkinComponent\n phase={activePhase}\n blend={activeBlend}\n expanded={expanded}\n onToggle={() => setExpanded((v) => !v)}\n expandDirection={expandDirection}\n size={size}\n time={time}\n location=\"\"\n showFlag={showFlag}\n showWeather={showWeather}\n hoverEffect={hoverEffect}\n weather={weatherCategoryOverride}\n liveWeatherCategory={liveWeatherCategory}\n liveTemperatureC={liveTemperatureC}\n palette={finalPalette}\n latitude={latitude}\n longitude={longitude}\n timezone={timezone}\n simulatedDate={simulatedDate}\n forceExpanded={forceExpanded}\n />\n </div>\n );\n}\n","'use client';\n\n/**\n * widgets/compact-widget.shell.tsx\n *\n * Shell for the compact solar widget — a slim pill/bar format.\n *\n * simulatedDate prop wins over ctx.simulatedDate (set by SolarDevTools),\n * which wins over undefined (live time). This means the devtools timeline\n * scrubber moves the orb in compact widgets without requiring any prop wiring.\n */\n\nimport { useEffect, useLayoutEffect, useMemo, useState } from 'react';\nimport type { SolarBlend, SolarPhase } from '../hooks/useSolarPosition';\nimport { lerpHex } from '../lib/solar-lerp';\nimport { useSolarTheme } from '../provider/solar-theme-provider';\nimport type { DesignMode, SkinDefinition, WidgetPalette } from '../skins/types/widget-skin.types';\nimport type { CustomPalettes } from './solar-widget.shell';\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n\nexport type WeatherCategory =\n | 'clear'\n | 'partly-cloudy'\n | 'overcast'\n | 'fog'\n | 'drizzle'\n | 'rain'\n | 'heavy-rain'\n | 'snow'\n | 'heavy-snow'\n | 'thunder';\n\nexport type CompactSize = 'sm' | 'md' | 'lg';\n\n// ─── WMO weather code map ─────────────────────────────────────────────────────\n\nconst WMO_MAP: Record<number, WeatherCategory> = {\n 0: 'clear',\n 1: 'clear',\n 2: 'partly-cloudy',\n 3: 'overcast',\n 45: 'fog',\n 48: 'fog',\n 51: 'drizzle',\n 53: 'drizzle',\n 55: 'drizzle',\n 61: 'rain',\n 63: 'rain',\n 65: 'heavy-rain',\n 71: 'snow',\n 73: 'snow',\n 75: 'heavy-snow',\n 80: 'rain',\n 82: 'heavy-rain',\n 85: 'snow',\n 86: 'heavy-snow',\n 95: 'thunder',\n 96: 'thunder',\n 99: 'thunder',\n};\n\n// ─── Centralised weather fetch ────────────────────────────────────────────────\n\ninterface LiveWeather {\n temperatureC: number;\n category: WeatherCategory;\n}\n\nasync function fetchWeather(lat: number, lon: number): Promise<LiveWeather> {\n const url = new URL('https://api.open-meteo.com/v1/forecast');\n url.searchParams.set('latitude', String(lat));\n url.searchParams.set('longitude', String(lon));\n url.searchParams.set('current', 'temperature_2m,weather_code');\n url.searchParams.set('forecast_days', '1');\n const data = (await fetch(url.toString()).then((r) => r.json())) as {\n current: { temperature_2m: number; weather_code: number };\n };\n return {\n temperatureC: Math.round(data.current.temperature_2m),\n category: WMO_MAP[data.current.weather_code] ?? 'clear',\n };\n}\n\nfunction useWeatherData(lat: number | null, lon: number | null) {\n const [weather, setWeather] = useState<LiveWeather | null>(null);\n useEffect(() => {\n if (!lat || !lon) return;\n let dead = false;\n fetchWeather(lat, lon)\n .then((w) => {\n if (!dead) setWeather(w);\n })\n .catch(() => {});\n const id = setInterval(\n () =>\n fetchWeather(lat, lon)\n .then((w) => {\n if (!dead) setWeather(w);\n })\n .catch(() => {}),\n 30 * 60 * 1000,\n );\n return () => {\n dead = true;\n clearInterval(id);\n };\n }, [lat, lon]);\n return weather;\n}\n\n// ─── Props passed to every compact skin component ─────────────────────────────\n\nexport interface CompactSkinProps {\n phase: SolarPhase;\n blend: SolarBlend;\n time: string;\n location: string;\n flag?: string;\n temperature?: string;\n weather?: WeatherCategory | null;\n liveWeatherCategory: WeatherCategory | null;\n liveTemperatureC: number | null;\n latitude?: number | null;\n longitude?: number | null;\n timezone?: string | null;\n simulatedDate?: Date;\n showFlag: boolean;\n showWeather: boolean;\n showTemperature: boolean;\n size: CompactSize;\n palette: WidgetPalette;\n}\n\n// ─── Public props for the shell ───────────────────────────────────────────────\n\nexport interface CompactWidgetProps {\n design?: DesignMode;\n overridePhase?: SolarPhase | null;\n time?: string;\n location?: string;\n flag?: string;\n temperature?: string;\n weather?: WeatherCategory | null;\n weatherCategoryOverride?: WeatherCategory | null;\n showFlag?: boolean;\n showWeather?: boolean;\n showTemperature?: boolean;\n size?: CompactSize;\n latitude?: number | null;\n longitude?: number | null;\n timezone?: string | null;\n /** Override background colors per phase */\n customPalettes?: CustomPalettes;\n /** Explicit simulated date. Falls back to ctx.simulatedDate (from SolarDevTools)\n * then to real current time. */\n simulatedDate?: Date;\n className?: string;\n}\n\n// ─── Palette blending ─────────────────────────────────────────────────────────\n\nfunction blendPalette(skin: SkinDefinition, blend: SolarBlend): WidgetPalette {\n const from = skin.widgetPalettes[blend.phase];\n const to = skin.widgetPalettes[blend.nextPhase];\n const t = blend.t;\n if (t === 0) return from;\n const lerp = (a: string, b: string) => lerpHex(a, b, t);\n return {\n bg: [lerp(from.bg[0], to.bg[0]), lerp(from.bg[1], to.bg[1]), lerp(from.bg[2], to.bg[2])] as [\n string,\n string,\n string,\n ],\n textColor: lerp(from.textColor, to.textColor),\n accentColor: lerp(from.accentColor, to.accentColor),\n orb: lerp(from.orb, to.orb),\n outerGlow: lerp(from.outerGlow, to.outerGlow),\n mode: from.mode,\n };\n}\n\n// ─── Shell ────────────────────────────────────────────────────────────────────\n\nexport function CompactWidget({\n design: designOverride,\n overridePhase,\n time,\n location = '',\n flag,\n temperature,\n weather = null,\n weatherCategoryOverride,\n showFlag = false,\n showWeather = false,\n showTemperature = true,\n size = 'md',\n latitude,\n longitude,\n timezone,\n customPalettes,\n simulatedDate: simulatedDateProp,\n className = '',\n}: CompactWidgetProps) {\n const [mounted, setMounted] = useState(false);\n useLayoutEffect(() => setMounted(true), []);\n\n const ctx = useSolarTheme();\n\n // Register customPalettes into context so DevTools can read them\n useEffect(() => {\n ctx.setCustomPalettes(customPalettes);\n return () => ctx.setCustomPalettes(undefined);\n }, [customPalettes, ctx.setCustomPalettes]);\n\n // prop wins → context (devtools) → undefined (live)\n const simulatedDate = simulatedDateProp ?? ctx.simulatedDate;\n\n const skin = useMemo(() => {\n if (!designOverride || designOverride === ctx.design) return ctx.activeSkin;\n return ctx.activeSkin;\n }, [designOverride, ctx.design, ctx.activeSkin]);\n\n const phase = overridePhase ?? ctx.phase;\n const blend = overridePhase\n ? { phase: overridePhase, nextPhase: overridePhase, t: 0 }\n : ctx.blend;\n\n const blendedPalette = useMemo(() => blendPalette(skin, blend), [skin, blend]);\n\n const palette: WidgetPalette = useMemo(() => {\n if (!customPalettes?.[phase]) return blendedPalette;\n return { ...blendedPalette, bg: customPalettes[phase]?.bg };\n }, [blendedPalette, customPalettes, phase]);\n\n const resolvedLat = latitude ?? ctx.latitude;\n const resolvedLon = longitude ?? ctx.longitude;\n const resolvedTz = timezone ?? ctx.timezone;\n\n // ── Centralised weather fetch ────────────────────────────────────────────\n const liveWeather = useWeatherData(resolvedLat ?? null, resolvedLon ?? null);\n\n const liveWeatherCategory: WeatherCategory | null = showWeather\n ? (weatherCategoryOverride ?? weather ?? liveWeather?.category ?? null)\n : null;\n\n const liveTemperatureC: number | null = liveWeather?.temperatureC ?? null;\n\n // ── Resolve time string ──────────────────────────────────────────────────\n // If caller passes an explicit time string, use it. Otherwise derive from\n // simulatedDate (or real time) so the clock display matches the orb.\n const resolvedTime = useMemo(() => {\n if (time) return time;\n const d = simulatedDate ?? new Date();\n const opts: Intl.DateTimeFormatOptions = {\n hour: '2-digit',\n minute: '2-digit',\n hourCycle: 'h23',\n };\n if (resolvedTz) opts.timeZone = resolvedTz;\n const parts = new Intl.DateTimeFormat('en-GB', opts).formatToParts(d);\n const hh = parts.find((p) => p.type === 'hour')?.value ?? '00';\n const mm = parts.find((p) => p.type === 'minute')?.value ?? '00';\n return `${hh}:${mm}`;\n }, [time, simulatedDate, resolvedTz]);\n\n const props: CompactSkinProps = {\n phase,\n blend,\n time: resolvedTime,\n location,\n flag,\n temperature,\n weather,\n liveWeatherCategory,\n liveTemperatureC,\n latitude: resolvedLat,\n longitude: resolvedLon,\n timezone: resolvedTz,\n simulatedDate,\n showFlag,\n showWeather,\n showTemperature,\n size,\n palette,\n };\n\n const CompactComponent = (\n skin as SkinDefinition & {\n CompactComponent?: React.ComponentType<CompactSkinProps>;\n }\n ).CompactComponent;\n\n if (!CompactComponent) {\n return (\n <div className={className} style={{ opacity: 0.4, fontSize: 11, color: '#888' }}>\n Compact not implemented for {skin.id}\n </div>\n );\n }\n\n return (\n <div\n className={className}\n style={{ visibility: mounted ? 'visible' : 'hidden', isolation: 'isolate' }}\n >\n <CompactComponent {...props} />\n </div>\n );\n}\n","/**\n * shader-motion-profiles.ts\n *\n * Per-skin motion personalities for SolarShaderBg.\n *\n * This is the creative core of the background shader system. Colors come from\n * each skin's shaderPalettes — motion comes from here. Together they define\n * a complete atmospheric identity per skin per phase.\n *\n * Motion axes:\n * distortion — organic mesh noise. High = liquid, flowing. Low = crystalline, still.\n * swirl — vortex pull. High = spiral drama. Low = gentle drift.\n * speed — animation rate. 0 = frozen. 1 = reference. >1 = fast.\n * grainOverlay — film grain. High in dark/still skins, low in bright/active ones.\n *\n * ─── Design intent per skin ───────────────────────────────────────────────────\n *\n * VOID The anti-skin. Barely alive. Night = almost nothing moves.\n * Noon nudges up slightly — but \"slightly\" for Void is still near-zero.\n * Grain is highest at midnight because darkness has texture.\n *\n * PARCHMENT A document. Documents don't move. speed=0 everywhere.\n * The only \"motion\" is the CSS transition on color as the phase shifts.\n *\n * SIGNAL Brutalist terminal. No organic drift — that would feel wrong.\n * Instead: very low distortion, almost-zero swirl, high grain.\n * The background is raw, not smooth.\n *\n * MERIDIAN Airy and clean. Moves gently but constantly — like a well-ventilated\n * room. Half the universal values throughout.\n *\n * SUNDIAL Ancient, measured. The dial shadow moves once per hour.\n * Low speed, low swirl. Grain is stone-textured.\n *\n * PAPER Uncoated stock breathes. Organic, unhurried. Medium everything —\n * never dramatic, never static.\n *\n * FOUNDRY The reference skin. Uses the universal phase-energy curve:\n * low at night, high at noon, dramatic at sunrise/sunset.\n * Closest to the default PHASE_MOTION values.\n *\n * MINERAL Gemstones don't flow — they refract. Low distortion (facets, not\n * liquid), moderate swirl (internal light scattering), medium speed.\n * Grain is low — stones are smooth.\n *\n * TIDE The sea rolls. High distortion at all phases (waves never stop),\n * moderate swirl, speed follows tidal rhythm. Low grain — water is clear.\n *\n * AURORA The most variable. At midnight/night: maximum everything —\n * the lights are dancing. During day: gentle and warm, the aurora\n * is invisible. At dusk/sunset: the bands return.\n */\n\nimport type { SolarPhase } from '../hooks/useSolarPosition';\nimport type { DesignMode, ShaderMotion } from '../skins/types/widget-skin.types';\n\n// ─── Type ─────────────────────────────────────────────────────────────────────\n\nexport type MotionProfile = Record<SolarPhase, ShaderMotion>;\n\n// ─── Universal fallback — used when a skin has no shaderMotion ────────────────\n// The energy arc of the sun: slow at night, rising through dawn,\n// peaking near noon/sunset, unwinding through dusk.\n\nexport const UNIVERSAL_PHASE_MOTION: MotionProfile = {\n midnight: { distortion: 0.2, swirl: 0.04, speed: 0.1, grainOverlay: 0.18 },\n night: { distortion: 0.28, swirl: 0.06, speed: 0.15, grainOverlay: 0.15 },\n dawn: { distortion: 0.52, swirl: 0.14, speed: 0.26, grainOverlay: 0.1 },\n sunrise: { distortion: 0.68, swirl: 0.22, speed: 0.38, grainOverlay: 0.07 },\n morning: { distortion: 0.54, swirl: 0.13, speed: 0.5, grainOverlay: 0.05 },\n 'solar-noon': { distortion: 0.36, swirl: 0.07, speed: 0.64, grainOverlay: 0.04 },\n afternoon: { distortion: 0.44, swirl: 0.1, speed: 0.5, grainOverlay: 0.05 },\n sunset: { distortion: 0.72, swirl: 0.3, speed: 0.34, grainOverlay: 0.08 },\n dusk: { distortion: 0.44, swirl: 0.18, speed: 0.2, grainOverlay: 0.14 },\n};\n\n// ─── Per-skin motion profiles ─────────────────────────────────────────────────\n\n// VOID — barely alive. The orb is the only presence; the background should\n// not compete. Maximum grain at midnight because pure black has texture.\nconst VOID_MOTION: MotionProfile = {\n midnight: { distortion: 0.08, swirl: 0.01, speed: 0.04, grainOverlay: 0.28 },\n night: { distortion: 0.1, swirl: 0.02, speed: 0.05, grainOverlay: 0.22 },\n dawn: { distortion: 0.14, swirl: 0.03, speed: 0.07, grainOverlay: 0.16 },\n sunrise: { distortion: 0.16, swirl: 0.04, speed: 0.09, grainOverlay: 0.12 },\n morning: { distortion: 0.14, swirl: 0.03, speed: 0.1, grainOverlay: 0.1 },\n 'solar-noon': { distortion: 0.1, swirl: 0.02, speed: 0.12, grainOverlay: 0.08 },\n afternoon: { distortion: 0.12, swirl: 0.03, speed: 0.1, grainOverlay: 0.1 },\n sunset: { distortion: 0.18, swirl: 0.05, speed: 0.08, grainOverlay: 0.14 },\n dusk: { distortion: 0.12, swirl: 0.03, speed: 0.06, grainOverlay: 0.2 },\n};\n\n// PARCHMENT — a document doesn't move. speed=0 everywhere.\n// The phase shift is expressed only through the CSS color transition.\nconst PARCHMENT_MOTION: MotionProfile = {\n midnight: { distortion: 0.0, swirl: 0.0, speed: 0.0, grainOverlay: 0.06 },\n night: { distortion: 0.0, swirl: 0.0, speed: 0.0, grainOverlay: 0.05 },\n dawn: { distortion: 0.0, swirl: 0.0, speed: 0.0, grainOverlay: 0.04 },\n sunrise: { distortion: 0.0, swirl: 0.0, speed: 0.0, grainOverlay: 0.03 },\n morning: { distortion: 0.0, swirl: 0.0, speed: 0.0, grainOverlay: 0.02 },\n 'solar-noon': { distortion: 0.0, swirl: 0.0, speed: 0.0, grainOverlay: 0.02 },\n afternoon: { distortion: 0.0, swirl: 0.0, speed: 0.0, grainOverlay: 0.02 },\n sunset: { distortion: 0.0, swirl: 0.0, speed: 0.0, grainOverlay: 0.03 },\n dusk: { distortion: 0.0, swirl: 0.0, speed: 0.0, grainOverlay: 0.05 },\n};\n\n// SIGNAL — brutalist terminal. No organic drift. Raw grain, mechanical.\n// Distortion is very low (pixels don't flow in a terminal).\n// Grain is high — CRT texture, not smoothness.\nconst SIGNAL_MOTION: MotionProfile = {\n midnight: { distortion: 0.06, swirl: 0.0, speed: 0.06, grainOverlay: 0.32 },\n night: { distortion: 0.06, swirl: 0.0, speed: 0.06, grainOverlay: 0.3 },\n dawn: { distortion: 0.08, swirl: 0.01, speed: 0.08, grainOverlay: 0.26 },\n sunrise: { distortion: 0.08, swirl: 0.01, speed: 0.08, grainOverlay: 0.24 },\n morning: { distortion: 0.1, swirl: 0.01, speed: 0.1, grainOverlay: 0.22 },\n 'solar-noon': { distortion: 0.1, swirl: 0.01, speed: 0.1, grainOverlay: 0.2 },\n afternoon: { distortion: 0.1, swirl: 0.01, speed: 0.1, grainOverlay: 0.22 },\n sunset: { distortion: 0.08, swirl: 0.01, speed: 0.08, grainOverlay: 0.26 },\n dusk: { distortion: 0.06, swirl: 0.0, speed: 0.06, grainOverlay: 0.3 },\n};\n\n// MERIDIAN — clean and airy. Constant gentle drift. Never dramatic.\n// Half the universal values across all phases.\nconst MERIDIAN_MOTION: MotionProfile = {\n midnight: { distortion: 0.12, swirl: 0.02, speed: 0.08, grainOverlay: 0.08 },\n night: { distortion: 0.14, swirl: 0.03, speed: 0.1, grainOverlay: 0.07 },\n dawn: { distortion: 0.24, swirl: 0.06, speed: 0.14, grainOverlay: 0.05 },\n sunrise: { distortion: 0.3, swirl: 0.09, speed: 0.2, grainOverlay: 0.04 },\n morning: { distortion: 0.26, swirl: 0.06, speed: 0.26, grainOverlay: 0.03 },\n 'solar-noon': { distortion: 0.18, swirl: 0.04, speed: 0.32, grainOverlay: 0.02 },\n afternoon: { distortion: 0.22, swirl: 0.05, speed: 0.26, grainOverlay: 0.03 },\n sunset: { distortion: 0.32, swirl: 0.12, speed: 0.18, grainOverlay: 0.04 },\n dusk: { distortion: 0.22, swirl: 0.08, speed: 0.12, grainOverlay: 0.06 },\n};\n\n// SUNDIAL — ancient, measured. The gnomon shadow moves once per hour.\n// Low speed, low swirl. Stone grain.\nconst SUNDIAL_MOTION: MotionProfile = {\n midnight: { distortion: 0.18, swirl: 0.03, speed: 0.07, grainOverlay: 0.2 },\n night: { distortion: 0.2, swirl: 0.04, speed: 0.08, grainOverlay: 0.18 },\n dawn: { distortion: 0.28, swirl: 0.07, speed: 0.14, grainOverlay: 0.12 },\n sunrise: { distortion: 0.34, swirl: 0.1, speed: 0.18, grainOverlay: 0.09 },\n morning: { distortion: 0.28, swirl: 0.06, speed: 0.22, grainOverlay: 0.08 },\n 'solar-noon': { distortion: 0.2, swirl: 0.04, speed: 0.28, grainOverlay: 0.06 },\n afternoon: { distortion: 0.24, swirl: 0.05, speed: 0.22, grainOverlay: 0.07 },\n sunset: { distortion: 0.36, swirl: 0.14, speed: 0.16, grainOverlay: 0.1 },\n dusk: { distortion: 0.24, swirl: 0.08, speed: 0.1, grainOverlay: 0.14 },\n};\n\n// PAPER — uncoated stock breathes. Organic, unhurried. Medium everything.\n// Never dramatic, never static. Grain increases slightly at night.\nconst PAPER_MOTION: MotionProfile = {\n midnight: { distortion: 0.22, swirl: 0.04, speed: 0.1, grainOverlay: 0.22 },\n night: { distortion: 0.26, swirl: 0.06, speed: 0.14, grainOverlay: 0.18 },\n dawn: { distortion: 0.38, swirl: 0.1, speed: 0.22, grainOverlay: 0.12 },\n sunrise: { distortion: 0.46, swirl: 0.14, speed: 0.3, grainOverlay: 0.09 },\n morning: { distortion: 0.38, swirl: 0.09, speed: 0.38, grainOverlay: 0.07 },\n 'solar-noon': { distortion: 0.28, swirl: 0.05, speed: 0.46, grainOverlay: 0.05 },\n afternoon: { distortion: 0.34, swirl: 0.07, speed: 0.38, grainOverlay: 0.06 },\n sunset: { distortion: 0.5, swirl: 0.2, speed: 0.26, grainOverlay: 0.1 },\n dusk: { distortion: 0.34, swirl: 0.12, speed: 0.16, grainOverlay: 0.14 },\n};\n\n// FOUNDRY — the reference skin. Full universal energy arc.\n// Rich, heavy, machined. Slightly more swirl than the bare universal.\nconst FOUNDRY_MOTION: MotionProfile = {\n midnight: { distortion: 0.22, swirl: 0.04, speed: 0.1, grainOverlay: 0.16 },\n night: { distortion: 0.3, swirl: 0.07, speed: 0.16, grainOverlay: 0.13 },\n dawn: { distortion: 0.55, swirl: 0.16, speed: 0.28, grainOverlay: 0.09 },\n sunrise: { distortion: 0.7, swirl: 0.26, speed: 0.4, grainOverlay: 0.06 },\n morning: { distortion: 0.56, swirl: 0.15, speed: 0.52, grainOverlay: 0.04 },\n 'solar-noon': { distortion: 0.38, swirl: 0.08, speed: 0.66, grainOverlay: 0.03 },\n afternoon: { distortion: 0.46, swirl: 0.12, speed: 0.52, grainOverlay: 0.04 },\n sunset: { distortion: 0.74, swirl: 0.34, speed: 0.36, grainOverlay: 0.07 },\n dusk: { distortion: 0.46, swirl: 0.2, speed: 0.22, grainOverlay: 0.12 },\n};\n\n// MINERAL — gemstones refract, they don't flow. Low distortion, moderate swirl\n// (internal scattering), medium speed. Grain is very low — facets are sharp.\nconst MINERAL_MOTION: MotionProfile = {\n midnight: { distortion: 0.14, swirl: 0.1, speed: 0.12, grainOverlay: 0.06 },\n night: { distortion: 0.16, swirl: 0.12, speed: 0.14, grainOverlay: 0.05 },\n dawn: { distortion: 0.22, swirl: 0.18, speed: 0.22, grainOverlay: 0.04 },\n sunrise: { distortion: 0.28, swirl: 0.24, speed: 0.32, grainOverlay: 0.03 },\n morning: { distortion: 0.22, swirl: 0.18, speed: 0.4, grainOverlay: 0.02 },\n 'solar-noon': { distortion: 0.16, swirl: 0.14, speed: 0.5, grainOverlay: 0.02 },\n afternoon: { distortion: 0.2, swirl: 0.16, speed: 0.4, grainOverlay: 0.02 },\n sunset: { distortion: 0.3, swirl: 0.28, speed: 0.28, grainOverlay: 0.03 },\n dusk: { distortion: 0.2, swirl: 0.2, speed: 0.18, grainOverlay: 0.04 },\n};\n\n// TIDE — the sea rolls. High distortion at all phases (waves never stop).\n// Speed follows a tidal rhythm: slower at dead of night, building through dawn.\n// Grain is very low — water is clear, not grainy.\nconst TIDE_MOTION: MotionProfile = {\n midnight: { distortion: 0.5, swirl: 0.08, speed: 0.18, grainOverlay: 0.03 },\n night: { distortion: 0.54, swirl: 0.1, speed: 0.22, grainOverlay: 0.03 },\n dawn: { distortion: 0.64, swirl: 0.16, speed: 0.34, grainOverlay: 0.02 },\n sunrise: { distortion: 0.72, swirl: 0.2, speed: 0.44, grainOverlay: 0.02 },\n morning: { distortion: 0.68, swirl: 0.16, speed: 0.54, grainOverlay: 0.01 },\n 'solar-noon': { distortion: 0.6, swirl: 0.12, speed: 0.62, grainOverlay: 0.01 },\n afternoon: { distortion: 0.64, swirl: 0.14, speed: 0.54, grainOverlay: 0.01 },\n sunset: { distortion: 0.74, swirl: 0.24, speed: 0.4, grainOverlay: 0.02 },\n dusk: { distortion: 0.6, swirl: 0.18, speed: 0.28, grainOverlay: 0.03 },\n};\n\n// AURORA — the most variable. At midnight/night the lights dance at full\n// intensity. During the day the aurora is invisible — calm, warm sky.\n// At dusk/sunset the bands return. Grain is very low — aurora is luminous.\nconst AURORA_MOTION: MotionProfile = {\n midnight: { distortion: 0.8, swirl: 0.44, speed: 0.7, grainOverlay: 0.02 },\n night: { distortion: 0.86, swirl: 0.5, speed: 0.8, grainOverlay: 0.02 },\n dawn: { distortion: 0.62, swirl: 0.32, speed: 0.52, grainOverlay: 0.03 },\n sunrise: { distortion: 0.38, swirl: 0.16, speed: 0.3, grainOverlay: 0.04 },\n morning: { distortion: 0.18, swirl: 0.05, speed: 0.18, grainOverlay: 0.04 },\n 'solar-noon': { distortion: 0.14, swirl: 0.03, speed: 0.14, grainOverlay: 0.03 },\n afternoon: { distortion: 0.18, swirl: 0.05, speed: 0.18, grainOverlay: 0.04 },\n sunset: { distortion: 0.46, swirl: 0.24, speed: 0.42, grainOverlay: 0.03 },\n dusk: { distortion: 0.68, swirl: 0.38, speed: 0.6, grainOverlay: 0.02 },\n};\n\n// ─── Skin → profile map ───────────────────────────────────────────────────────\n\nexport const SKIN_MOTION_PROFILES: Record<DesignMode, MotionProfile> = {\n void: VOID_MOTION,\n parchment: PARCHMENT_MOTION,\n signal: SIGNAL_MOTION,\n meridian: MERIDIAN_MOTION,\n sundial: SUNDIAL_MOTION,\n paper: PAPER_MOTION,\n foundry: FOUNDRY_MOTION,\n mineral: MINERAL_MOTION,\n tide: TIDE_MOTION,\n aurora: AURORA_MOTION,\n};\n","'use client';\n// ════════════════════════════════════════════════════════════════════════════\n// FILE: components/solar-shader-bg.client.tsx\n// ════════════════════════════════════════════════════════════════════════════\n\nimport {\n createContext,\n useContext,\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport type { SolarBlend, SolarPhase } from '../hooks/useSolarPosition';\nimport { lerpColor } from '../lib/solar-lerp';\nimport { useSolarTheme } from '../provider/solar-theme-provider';\nimport type {\n ShaderImage,\n ShaderMotion,\n ShaderPalette,\n SkinDefinition,\n} from '../skins/types/widget-skin.types';\nimport { SKIN_MOTION_PROFILES, UNIVERSAL_PHASE_MOTION } from './shader-motion-profiles';\n\n// ─── Variant context ──────────────────────────────────────────────────────────\n\nexport type ShaderVariant = 'showcase' | 'dashboard' | 'editorial';\n\nconst ShaderVariantCtx = createContext<ShaderVariant>('showcase');\n\nexport function ShaderVariantProvider({\n variant,\n children,\n}: {\n variant: ShaderVariant;\n children: React.ReactNode;\n}) {\n return <ShaderVariantCtx.Provider value={variant}>{children}</ShaderVariantCtx.Provider>;\n}\n\nexport function useShaderVariant(): ShaderVariant {\n return useContext(ShaderVariantCtx);\n}\n\n// ─── Dashboard motion modifier ────────────────────────────────────────────────\n\nconst DASHBOARD_MOTION_SCALE = {\n speed: 0.45,\n distortion: 0.5,\n swirl: 0.4,\n grainOverlay: 1.3,\n} as const;\n\nconst DASHBOARD_OPACITY_SCALE = 0.65;\n\nfunction applyDashboardMotion(m: ShaderMotion): ShaderMotion {\n return {\n speed: m.speed * DASHBOARD_MOTION_SCALE.speed,\n distortion: m.distortion * DASHBOARD_MOTION_SCALE.distortion,\n swirl: m.swirl * DASHBOARD_MOTION_SCALE.swirl,\n grainOverlay: Math.min(1, m.grainOverlay * DASHBOARD_MOTION_SCALE.grainOverlay),\n };\n}\n\n// ─── Editorial motion modifier ────────────────────────────────────────────────\n\nconst EDITORIAL_MOTION_SCALE = {\n speed: 0.3,\n distortion: 0.35,\n swirl: 0.25,\n grainOverlay: 1.4,\n} as const;\n\nconst EDITORIAL_OPACITY_SCALE = 0.35;\n\nfunction applyEditorialMotion(m: ShaderMotion): ShaderMotion {\n return {\n speed: m.speed * EDITORIAL_MOTION_SCALE.speed,\n distortion: m.distortion * EDITORIAL_MOTION_SCALE.distortion,\n swirl: m.swirl * EDITORIAL_MOTION_SCALE.swirl,\n grainOverlay: Math.min(1, m.grainOverlay * EDITORIAL_MOTION_SCALE.grainOverlay),\n };\n}\n\nfunction mixToward(hex: string, target: string, mix: number): string {\n return lerpColor(hex, target, mix);\n}\n\nfunction applyEditorialPalette(p: ShaderPalette): ShaderPalette {\n const darkBase = '#08080c';\n const darkVignette = '#030306';\n return {\n ...p,\n colors: p.colors.map((c) => mixToward(c, darkBase, 0.92)) as [string, string, string, string],\n colorBack: mixToward(p.colorBack, darkBase, 0.95),\n vignette: mixToward(p.vignette, darkVignette, 0.9),\n cssFallback: `linear-gradient(135deg, ${darkBase} 0%, #0c0c14 100%)`,\n };\n}\n\n// ─── Interpolation helpers ────────────────────────────────────────────────────\n\nfunction lerpNum(a: number, b: number, t: number): number {\n return a + (b - a) * t;\n}\n\nfunction lerpMotion(a: ShaderMotion, b: ShaderMotion, t: number): ShaderMotion {\n return {\n distortion: lerpNum(a.distortion, b.distortion, t),\n swirl: lerpNum(a.swirl, b.swirl, t),\n speed: lerpNum(a.speed, b.speed, t),\n grainOverlay: lerpNum(a.grainOverlay, b.grainOverlay, t),\n };\n}\n\nfunction lerpPalette(a: ShaderPalette, b: ShaderPalette, t: number): ShaderPalette {\n return {\n colors: a.colors.map((ca, i) => lerpColor(ca, b.colors[i] ?? ca, t)) as [\n string,\n string,\n string,\n string,\n ],\n colorBack: lerpColor(a.colorBack, b.colorBack, t),\n opacity: lerpNum(a.opacity, b.opacity, t),\n vignette: lerpColor(a.vignette, b.vignette, t),\n cssFallback: a.cssFallback,\n image: a.image,\n };\n}\n\n// ─── Motion profile resolution ────────────────────────────────────────────────\n\nfunction resolveMotionProfile(skin: SkinDefinition): Record<SolarPhase, ShaderMotion> {\n if (skin.shaderMotion) return skin.shaderMotion;\n return SKIN_MOTION_PROFILES[skin.id] ?? UNIVERSAL_PHASE_MOTION;\n}\n\n// ─── Image config resolution ──────────────────────────────────────────────────\n\nfunction resolveImage(skin: SkinDefinition, palette: ShaderPalette): ShaderImage | undefined {\n return palette.image ?? skin.defaultImage;\n}\n\n// ─── Core config computation ──────────────────────────────────────────────────\n\nfunction computeConfig(skin: SkinDefinition, blend: SolarBlend) {\n const motionProfile = resolveMotionProfile(skin);\n const { phase, nextPhase, t } = blend;\n return {\n palette: lerpPalette(skin.shaderPalettes[phase], skin.shaderPalettes[nextPhase], t),\n motion: lerpMotion(motionProfile[phase], motionProfile[nextPhase], t),\n };\n}\n\n// ─── Hex → RGB helper ─────────────────────────────────────────────────────────\n\nfunction hexToRgb(hex: string): [number, number, number] {\n const result = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i.exec(hex);\n return result\n ? [\n Number.parseInt(result[1], 16) / 255,\n Number.parseInt(result[2], 16) / 255,\n Number.parseInt(result[3], 16) / 255,\n ]\n : [0, 0, 0];\n}\n\n// ─── WebGL SolarFlare shader ──────────────────────────────────────────────────\n// Inspired by a radiant solar flare effect. Uses the skin's 4 shader palette\n// colors as a blended flare color against the colorBack background.\n// Motion profile drives speed, intensity, spread and pulse.\n\nconst VS_SOURCE = `#version 300 es\n in vec2 a_position;\n void main() {\n gl_Position = vec4(a_position, 0.0, 1.0);\n }\n`;\n\nconst FS_SOURCE = `#version 300 es\n precision highp float;\n\n uniform vec2 r; // resolution\n uniform float t; // time\n uniform vec3 u_bg; // background color (colorBack)\n uniform vec3 u_c0; // palette color 0\n uniform vec3 u_c1; // palette color 1\n uniform vec3 u_c2; // palette color 2\n uniform vec3 u_c3; // palette color 3\n uniform float u_intensity;\n uniform float u_spread;\n uniform float u_pulseRate;\n uniform float u_speed;\n uniform float u_grain;\n\n out vec4 o;\n\n // Hash for grain\n float hash(vec2 p) {\n return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453);\n }\n\n void main() {\n vec4 FC = gl_FragCoord;\n vec2 p = (FC.xy * 2. - r) / r.y;\n\n // Average all 4 palette colors\n vec3 avgColor = (u_c0 + u_c1 + u_c2 + u_c3) * 0.25;\n\n // Normalize to a fixed luminance so the flare shape is identical\n // across all skins regardless of how bright/dark the palette is.\n // Dark palettes (Void midnight ≈ 0.01) and bright palettes\n // (Paper morning ≈ 0.95) both produce the same-sized sun.\n float lum = dot(avgColor, vec3(0.299, 0.587, 0.114));\n vec3 flareColor = lum > 0.001\n ? avgColor * (0.30 / lum) // rescale to target luminance 0.30\n : vec3(0.30); // neutral grey fallback\n\n // Solar flare radiance — matches the reference SolarFlare shader.\n // length(p) creates a circular distance field from center.\n // The exp(mod(dot(...))) creates alive, pulsing texture inside the sun.\n float l = u_intensity - length(p);\n\n o = tanh(\n vec4(flareColor, 0.0)\n / max(l, -l * u_spread)\n / exp(\n mod(dot(FC, sin(FC.yxyx)) + t * u_speed, 2.0)\n + sin(t * u_speed + sin(t * u_speed / u_pulseRate + p.y))\n )\n );\n\n // Film grain\n float grain = (hash(FC.xy + fract(t)) - 0.5) * u_grain;\n\n // Composite: background + flare glow + grain\n o = vec4(u_bg + o.rgb + grain, 1.0);\n }\n`;\n\ninterface SolarFlareCanvasProps {\n backgroundColor: string;\n colors: [string, string, string, string];\n speed: number;\n intensity: number;\n spread: number;\n pulseRate: number;\n grain: number;\n}\n\nfunction SolarFlareCanvas({\n backgroundColor,\n colors,\n speed,\n intensity,\n spread,\n pulseRate,\n grain,\n}: SolarFlareCanvasProps) {\n const canvasRef = useRef<HTMLCanvasElement>(null);\n const animationRef = useRef<number | null>(null);\n\n const configRef = useRef({\n backgroundColor,\n colors,\n speed,\n intensity,\n spread,\n pulseRate,\n grain,\n });\n\n useEffect(() => {\n configRef.current = {\n backgroundColor,\n colors,\n speed,\n intensity,\n spread,\n pulseRate,\n grain,\n };\n }, [backgroundColor, colors, speed, intensity, spread, pulseRate, grain]);\n\n // useLayoutEffect ensures WebGL context is created and the first frame is\n // drawn *before* the browser paints, preventing a blank-canvas flash on\n // client-side navigation remounts.\n useLayoutEffect(() => {\n const canvas = canvasRef.current;\n if (!canvas) return;\n\n const gl = canvas.getContext('webgl2');\n if (!gl) return;\n\n const createShader = (type: number, source: string) => {\n const shader = gl.createShader(type);\n if (!shader) return null;\n gl.shaderSource(shader, source);\n gl.compileShader(shader);\n if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {\n gl.deleteShader(shader);\n return null;\n }\n return shader;\n };\n\n const vs = createShader(gl.VERTEX_SHADER, VS_SOURCE);\n const fs = createShader(gl.FRAGMENT_SHADER, FS_SOURCE);\n if (!vs || !fs) return;\n\n const program = gl.createProgram();\n if (!program) return;\n\n gl.attachShader(program, vs);\n gl.attachShader(program, fs);\n gl.linkProgram(program);\n if (!gl.getProgramParameter(program, gl.LINK_STATUS)) return;\n\n const positionBuffer = gl.createBuffer();\n gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);\n gl.bufferData(\n gl.ARRAY_BUFFER,\n new Float32Array([-1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1]),\n gl.STATIC_DRAW,\n );\n\n const posLoc = gl.getAttribLocation(program, 'a_position');\n gl.enableVertexAttribArray(posLoc);\n gl.vertexAttribPointer(posLoc, 2, gl.FLOAT, false, 0, 0);\n\n const loc = {\n r: gl.getUniformLocation(program, 'r'),\n t: gl.getUniformLocation(program, 't'),\n bg: gl.getUniformLocation(program, 'u_bg'),\n c0: gl.getUniformLocation(program, 'u_c0'),\n c1: gl.getUniformLocation(program, 'u_c1'),\n c2: gl.getUniformLocation(program, 'u_c2'),\n c3: gl.getUniformLocation(program, 'u_c3'),\n intensity: gl.getUniformLocation(program, 'u_intensity'),\n spread: gl.getUniformLocation(program, 'u_spread'),\n pulseRate: gl.getUniformLocation(program, 'u_pulseRate'),\n speed: gl.getUniformLocation(program, 'u_speed'),\n grain: gl.getUniformLocation(program, 'u_grain'),\n };\n\n const resizeCanvas = () => {\n const dpr = window.devicePixelRatio || 1;\n canvas.width = Math.round(canvas.offsetWidth * dpr);\n canvas.height = Math.round(canvas.offsetHeight * dpr);\n gl.viewport(0, 0, canvas.width, canvas.height);\n };\n\n window.addEventListener('resize', resizeCanvas);\n resizeCanvas();\n\n const startTime = performance.now();\n\n const render = () => {\n const cfg = configRef.current;\n gl.useProgram(program);\n\n gl.uniform2f(loc.r, canvas.width, canvas.height);\n gl.uniform1f(loc.t, (performance.now() - startTime) / 1000);\n\n const bg = hexToRgb(cfg.backgroundColor);\n gl.uniform3f(loc.bg, bg[0], bg[1], bg[2]);\n\n const c0 = hexToRgb(cfg.colors[0]);\n const c1 = hexToRgb(cfg.colors[1]);\n const c2 = hexToRgb(cfg.colors[2]);\n const c3 = hexToRgb(cfg.colors[3]);\n gl.uniform3f(loc.c0, c0[0], c0[1], c0[2]);\n gl.uniform3f(loc.c1, c1[0], c1[1], c1[2]);\n gl.uniform3f(loc.c2, c2[0], c2[1], c2[2]);\n gl.uniform3f(loc.c3, c3[0], c3[1], c3[2]);\n\n gl.uniform1f(loc.intensity, cfg.intensity);\n gl.uniform1f(loc.spread, cfg.spread);\n gl.uniform1f(loc.pulseRate, cfg.pulseRate);\n gl.uniform1f(loc.speed, cfg.speed);\n gl.uniform1f(loc.grain, cfg.grain);\n\n gl.drawArrays(gl.TRIANGLES, 0, 6);\n animationRef.current = requestAnimationFrame(render);\n };\n\n render();\n\n return () => {\n window.removeEventListener('resize', resizeCanvas);\n if (animationRef.current) cancelAnimationFrame(animationRef.current);\n gl.deleteProgram(program);\n gl.deleteShader(vs);\n gl.deleteShader(fs);\n gl.deleteBuffer(positionBuffer);\n };\n }, []);\n\n return (\n <canvas\n ref={canvasRef}\n style={{\n position: 'absolute',\n top: 0,\n left: 0,\n width: '100%',\n height: '100%',\n }}\n />\n );\n}\n\n// ─── Client-side mount tracking ───────────────────────────────────────────────\n// After the very first hydration, any subsequent mount is a client-side navigation\n// remount — no SSR/hydration mismatch is possible, so the canvas can render\n// immediately without the `mounted` gate (which would cause a one-frame blink).\nlet _hasHydrated = false;\n\n// ─── Props ────────────────────────────────────────────────────────────────────\n\nexport interface SolarShaderBgProps {\n skinOverride?: SkinDefinition;\n blendOverride?: SolarBlend;\n opacityOverride?: number;\n variant?: ShaderVariant;\n className?: string;\n style?: React.CSSProperties;\n}\n\n// ─── SolarShaderBg ────────────────────────────────────────────────────────────\n\nexport function SolarShaderBg({\n skinOverride,\n blendOverride,\n opacityOverride,\n variant: variantProp,\n className,\n style,\n}: SolarShaderBgProps = {}) {\n const { activeSkin, blend: contextBlend } = useSolarTheme();\n const contextVariant = useShaderVariant();\n\n const skin = skinOverride ?? activeSkin;\n const blend = blendOverride ?? contextBlend;\n const variant = variantProp ?? contextVariant;\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: intentional fine-grained deps — blend object reference changes every render; subscribing to specific fields avoids thrashing computeConfig\n const { palette, motion: rawMotion } = useMemo(\n () => computeConfig(skin, blend),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [blend.phase, blend.nextPhase, blend.t, skin],\n );\n\n const variantPalette = variant === 'editorial' ? applyEditorialPalette(palette) : palette;\n\n const shaderMotion =\n variant === 'dashboard'\n ? applyDashboardMotion(rawMotion)\n : variant === 'editorial'\n ? applyEditorialMotion(rawMotion)\n : rawMotion;\n\n const resolvedOpacity =\n opacityOverride ??\n (variant === 'dashboard'\n ? variantPalette.opacity * DASHBOARD_OPACITY_SCALE\n : variant === 'editorial'\n ? variantPalette.opacity * EDITORIAL_OPACITY_SCALE\n : variantPalette.opacity);\n\n const imageConfig = resolveImage(skin, variantPalette);\n\n // Gate dynamic layers behind a client-only flag to avoid hydration mismatches.\n // On the very first mount (SSR hydration), start as false and flip via effect.\n // On subsequent mounts (client-side navigation), start as true immediately\n // so the WebGL canvas renders without a one-frame blink.\n const [mounted, setMounted] = useState(_hasHydrated);\n useLayoutEffect(() => {\n _hasHydrated = true;\n setMounted(true);\n }, []);\n\n useEffect(() => {\n document.documentElement.style.setProperty('--solar-shader-bg', variantPalette.colorBack);\n return () => {\n document.documentElement.style.removeProperty('--solar-shader-bg');\n };\n }, [variantPalette.colorBack]);\n\n // Map shader motion → SolarFlare parameters\n // intensity ≥ 3.5 ensures the radial edge is always off-screen (max corner\n // distance in normalised coords is ~1.15), so the glow fills the entire\n // viewport as an atmospheric wash — no visible \"sun\" circle.\n const flareSpeed = 0.6 + shaderMotion.speed * 0.8;\n const flareIntensity = 3.5 + shaderMotion.distortion * 0.5;\n const flareSpread = 8.0 + shaderMotion.swirl * 8.0;\n const flarePulseRate = 0.4 + (1.0 - shaderMotion.swirl) * 0.5;\n const flareGrain = shaderMotion.grainOverlay * 0.12;\n\n return (\n <div\n className={className}\n suppressHydrationWarning\n style={{\n position: 'absolute',\n inset: 0,\n overflow: 'hidden',\n background: variantPalette.cssFallback || variantPalette.colorBack,\n ...style,\n }}\n >\n {mounted && (\n <>\n {/* ── Layer 1: WebGL SolarFlare (renders instantly — no flash) ── */}\n <div className=\"absolute inset-0\" style={{ opacity: resolvedOpacity }}>\n <SolarFlareCanvas\n backgroundColor={variantPalette.colorBack}\n colors={variantPalette.colors}\n speed={flareSpeed}\n intensity={flareIntensity}\n spread={flareSpread}\n pulseRate={flarePulseRate}\n grain={flareGrain}\n />\n </div>\n\n {/* ── Layer 2: Atmospheric image ──────────────────────────────── */}\n {imageConfig && (\n <div\n className=\"absolute inset-0\"\n aria-hidden\n style={{\n opacity: imageConfig.opacity ?? 0.18,\n pointerEvents: 'none',\n background: 'var(--solar-accent)',\n WebkitMaskImage: `url(${imageConfig.src})`,\n maskImage: `url(${imageConfig.src})`,\n WebkitMaskSize: 'cover',\n maskSize: 'cover',\n WebkitMaskPosition: imageConfig.objectPosition ?? 'center center',\n maskPosition: imageConfig.objectPosition ?? 'center center',\n WebkitMaskRepeat: 'no-repeat',\n maskRepeat: 'no-repeat',\n }}\n />\n )}\n\n {/* ── Layer 3: Vignette ───────────────────────────────────────── */}\n <div\n className=\"absolute inset-0\"\n aria-hidden\n style={{\n pointerEvents: 'none',\n background: `radial-gradient(ellipse 85% 70% at 50% 50%, transparent 0%, ${variantPalette.vignette} 100%)`,\n }}\n />\n </>\n )}\n </div>\n );\n}\n\n// ─── SolarShaderBgFull ────────────────────────────────────────────────────────\n\nexport function SolarShaderBgFull(props: SolarShaderBgProps = {}) {\n return <SolarShaderBg {...props} style={{ zIndex: 0, ...props.style }} />;\n}\n\n// ─── useSolarShaderConfig ─────────────────────────────────────────────────────\n\nexport function useSolarShaderConfig(\n opts: {\n skinOverride?: SkinDefinition;\n blendOverride?: SolarBlend;\n } = {},\n) {\n const { activeSkin, blend: contextBlend } = useSolarTheme();\n const skin = opts.skinOverride ?? activeSkin;\n const blend = opts.blendOverride ?? contextBlend;\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: intentional fine-grained deps — blend object reference changes every render; subscribing to specific fields avoids thrashing computeConfig\n return useMemo(\n () => computeConfig(skin, blend),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [blend.phase, blend.nextPhase, blend.t, skin],\n );\n}\n"],"mappings":";;;;;AAoDA,MAAa,WAAW,MAAM,QAAQ;AAItC,MAAMA,YAA2C;CAC/C,GAAG;CACH,GAAG;CACH,GAAG;CACH,GAAG;CACH,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACL;AAOD,eAAeC,eAAa,KAAa,KAAmC;CAC1E,MAAM,MAAM,IAAI,IAAI,yCAAyC;AAC7D,KAAI,aAAa,IAAI,YAAY,OAAO,IAAI,CAAC;AAC7C,KAAI,aAAa,IAAI,aAAa,OAAO,IAAI,CAAC;AAC9C,KAAI,aAAa,IAAI,WAAW,8BAA8B;AAC9D,KAAI,aAAa,IAAI,iBAAiB,IAAI;CAC1C,MAAM,OAAQ,MAAM,MAAM,IAAI,UAAU,CAAC,CAAC,MAAM,MAAM,EAAE,MAAM,CAAC;AAG/D,QAAO;EACL,cAAc,KAAK,MAAM,KAAK,QAAQ,eAAe;EACrD,UAAUC,UAAQ,KAAK,QAAQ,iBAAiB;EACjD;;AAGH,SAASC,iBAAe,KAAoB,KAAoB;CAC9D,MAAM,CAAC,SAAS,cAAc,SAA6B,KAAK;AAChE,iBAAgB;AACd,MAAI,CAAC,OAAO,CAAC,IAAK;EAClB,IAAI,OAAO;AACX,iBAAa,KAAK,IAAI,CACnB,MAAM,MAAM;AACX,OAAI,CAAC,KAAM,YAAW,EAAE;IACxB,CACD,YAAY,GAAG;EAClB,MAAM,KAAK,kBAEPF,eAAa,KAAK,IAAI,CACnB,MAAM,MAAM;AACX,OAAI,CAAC,KAAM,YAAW,EAAE;IACxB,CACD,YAAY,GAAG,EACpB,OAAU,IACX;AACD,eAAa;AACX,UAAO;AACP,iBAAc,GAAG;;IAElB,CAAC,KAAK,IAAI,CAAC;AACd,QAAO;;AAwBT,SAAS,mBAAmB,MAAqB,IAAmB,GAA0B;AAC5F,QAAO;EACL,IAAI;GACF,QAAQ,KAAK,GAAG,IAAI,GAAG,GAAG,IAAI,EAAE;GAChC,QAAQ,KAAK,GAAG,IAAI,GAAG,GAAG,IAAI,EAAE;GAChC,QAAQ,KAAK,GAAG,IAAI,GAAG,GAAG,IAAI,EAAE;GACjC;EACD,WAAW,QAAQ,KAAK,WAAW,GAAG,WAAW,EAAE;EACnD,aAAa,QAAQ,KAAK,aAAa,GAAG,aAAa,EAAE;EACzD,KAAK,QAAQ,KAAK,KAAK,GAAG,KAAK,EAAE;EACjC,WAAW,KAAK;EAChB,MAAM,IAAI,KAAM,KAAK,OAAO,GAAG;EAChC;;AAKH,SAAgB,YAAY,EAC1B,kBAAkB,gBAClB,OAAO,MACP,WAAW,OACX,cAAc,OACd,cAAc,OACd,gBACA,eACA,yBACA,eAAe,mBACf,iBACmB;CACnB,MAAM,CAAC,SAAS,cAAc,SAAS,MAAM;AAC7C,uBAAsB,WAAW,KAAK,EAAE,EAAE,CAAC;CAE3C,MAAM,EACJ,OACA,OACA,YACA,UACA,UACA,WACA,eAAe,kBACf,sBACE,eAAe;AAGnB,iBAAgB;AACd,oBAAkB,eAAe;AACjC,eAAa,kBAAkB,OAAU;IACxC,CAAC,gBAAgB,kBAAkB,CAAC;CAGvC,MAAM,gBAAgB,qBAAqB;CAE3C,MAAM,CAAC,UAAU,eAAe,SAAS,MAAM;CAE/C,MAAM,cAAc,iBAAiB;CACrC,MAAM,cAAc,gBAChB;EAAE,OAAO;EAAe,WAAW;EAAe,GAAG;EAAG,GACxD;CAEJ,MAAM,cAAc,WAAW,eAAe,YAAY;CAC1D,MAAM,YAAY,WAAW,eAAe,YAAY;CAExD,MAAM,iBAAiB,cACf,mBAAmB,aAAa,WAAW,YAAY,EAAE,EAC/D;EAAC;EAAa;EAAW,YAAY;EAAE,CACxC;CAED,MAAMG,eAA8B,cAAc;AAChD,MAAI,CAAC,iBAAiB,aAAc,QAAO;AAC3C,SAAO;GAAE,GAAG;GAAgB,IAAI,eAAe,cAAc;GAAI;IAChE;EAAC;EAAgB;EAAgB;EAAY,CAAC;CAEjD,MAAM,OAAO,cAAc;EACzB,MAAM,IAAI,iCAAiB,IAAI,MAAM;EACrC,MAAMC,OAAmC;GACvC,MAAM;GACN,QAAQ;GACR,WAAW;GACZ;AACD,MAAI,SAAU,MAAK,WAAW;EAC9B,MAAM,QAAQ,IAAI,KAAK,eAAe,SAAS,KAAK,CAAC,cAAc,EAAE;AAGrE,SAAO,GAFI,MAAM,MAAM,MAAM,EAAE,SAAS,OAAO,EAAE,SAAS,KAE7C,GADF,MAAM,MAAM,MAAM,EAAE,SAAS,SAAS,EAAE,SAAS;IAE3D,CAAC,eAAe,SAAS,CAAC;CAG7B,MAAM,cAAcF,iBAAe,YAAY,MAAM,aAAa,KAAK;CAEvE,MAAMG,sBAA8C,cAC/C,2BAA2B,aAAa,YAAY,OACrD;CAEJ,MAAMC,mBAAkC,aAAa,gBAAgB;CAErE,MAAM,gBAAgB,WAAW;AAEjC,QACE,oBAAC;EAAI,OAAO,EAAE,YAAY,UAAU,YAAY,UAAU;YACxD,oBAAC;GACC,OAAO;GACP,OAAO;GACG;GACV,gBAAgB,aAAa,MAAM,CAAC,EAAE;GACrB;GACX;GACA;GACN,UAAS;GACC;GACG;GACA;GACb,SAAS;GACY;GACH;GAClB,SAAS;GACC;GACC;GACD;GACK;GACA;IACf;GACE;;;;;ACzOV,MAAMC,UAA2C;CAC/C,GAAG;CACH,GAAG;CACH,GAAG;CACH,GAAG;CACH,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACL;AASD,eAAe,aAAa,KAAa,KAAmC;CAC1E,MAAM,MAAM,IAAI,IAAI,yCAAyC;AAC7D,KAAI,aAAa,IAAI,YAAY,OAAO,IAAI,CAAC;AAC7C,KAAI,aAAa,IAAI,aAAa,OAAO,IAAI,CAAC;AAC9C,KAAI,aAAa,IAAI,WAAW,8BAA8B;AAC9D,KAAI,aAAa,IAAI,iBAAiB,IAAI;CAC1C,MAAM,OAAQ,MAAM,MAAM,IAAI,UAAU,CAAC,CAAC,MAAM,MAAM,EAAE,MAAM,CAAC;AAG/D,QAAO;EACL,cAAc,KAAK,MAAM,KAAK,QAAQ,eAAe;EACrD,UAAU,QAAQ,KAAK,QAAQ,iBAAiB;EACjD;;AAGH,SAAS,eAAe,KAAoB,KAAoB;CAC9D,MAAM,CAAC,SAAS,cAAc,SAA6B,KAAK;AAChE,iBAAgB;AACd,MAAI,CAAC,OAAO,CAAC,IAAK;EAClB,IAAI,OAAO;AACX,eAAa,KAAK,IAAI,CACnB,MAAM,MAAM;AACX,OAAI,CAAC,KAAM,YAAW,EAAE;IACxB,CACD,YAAY,GAAG;EAClB,MAAM,KAAK,kBAEP,aAAa,KAAK,IAAI,CACnB,MAAM,MAAM;AACX,OAAI,CAAC,KAAM,YAAW,EAAE;IACxB,CACD,YAAY,GAAG,EACpB,OAAU,IACX;AACD,eAAa;AACX,UAAO;AACP,iBAAc,GAAG;;IAElB,CAAC,KAAK,IAAI,CAAC;AACd,QAAO;;AAsDT,SAAS,aAAa,MAAsB,OAAkC;CAC5E,MAAM,OAAO,KAAK,eAAe,MAAM;CACvC,MAAM,KAAK,KAAK,eAAe,MAAM;CACrC,MAAM,IAAI,MAAM;AAChB,KAAI,MAAM,EAAG,QAAO;CACpB,MAAM,QAAQ,GAAW,MAAc,QAAQ,GAAG,GAAG,EAAE;AACvD,QAAO;EACL,IAAI;GAAC,KAAK,KAAK,GAAG,IAAI,GAAG,GAAG,GAAG;GAAE,KAAK,KAAK,GAAG,IAAI,GAAG,GAAG,GAAG;GAAE,KAAK,KAAK,GAAG,IAAI,GAAG,GAAG,GAAG;GAAC;EAKxF,WAAW,KAAK,KAAK,WAAW,GAAG,UAAU;EAC7C,aAAa,KAAK,KAAK,aAAa,GAAG,YAAY;EACnD,KAAK,KAAK,KAAK,KAAK,GAAG,IAAI;EAC3B,WAAW,KAAK,KAAK,WAAW,GAAG,UAAU;EAC7C,MAAM,KAAK;EACZ;;AAKH,SAAgB,cAAc,EAC5B,QAAQ,gBACR,eACA,MACA,WAAW,IACX,MACA,aACA,UAAU,MACV,yBACA,WAAW,OACX,cAAc,OACd,kBAAkB,MAClB,OAAO,MACP,UACA,WACA,UACA,gBACA,eAAe,mBACf,YAAY,MACS;CACrB,MAAM,CAAC,SAAS,cAAc,SAAS,MAAM;AAC7C,uBAAsB,WAAW,KAAK,EAAE,EAAE,CAAC;CAE3C,MAAM,MAAM,eAAe;AAG3B,iBAAgB;AACd,MAAI,kBAAkB,eAAe;AACrC,eAAa,IAAI,kBAAkB,OAAU;IAC5C,CAAC,gBAAgB,IAAI,kBAAkB,CAAC;CAG3C,MAAM,gBAAgB,qBAAqB,IAAI;CAE/C,MAAM,OAAO,cAAc;AACzB,MAAI,CAAC,kBAAkB,mBAAmB,IAAI,OAAQ,QAAO,IAAI;AACjE,SAAO,IAAI;IACV;EAAC;EAAgB,IAAI;EAAQ,IAAI;EAAW,CAAC;CAEhD,MAAM,QAAQ,iBAAiB,IAAI;CACnC,MAAM,QAAQ,gBACV;EAAE,OAAO;EAAe,WAAW;EAAe,GAAG;EAAG,GACxD,IAAI;CAER,MAAM,iBAAiB,cAAc,aAAa,MAAM,MAAM,EAAE,CAAC,MAAM,MAAM,CAAC;CAE9E,MAAMC,UAAyB,cAAc;AAC3C,MAAI,CAAC,iBAAiB,OAAQ,QAAO;AACrC,SAAO;GAAE,GAAG;GAAgB,IAAI,eAAe,QAAQ;GAAI;IAC1D;EAAC;EAAgB;EAAgB;EAAM,CAAC;CAE3C,MAAM,cAAc,YAAY,IAAI;CACpC,MAAM,cAAc,aAAa,IAAI;CACrC,MAAM,aAAa,YAAY,IAAI;CAGnC,MAAM,cAAc,eAAe,eAAe,MAAM,eAAe,KAAK;CAE5E,MAAMC,sBAA8C,cAC/C,2BAA2B,WAAW,aAAa,YAAY,OAChE;CAEJ,MAAMC,mBAAkC,aAAa,gBAAgB;CAoBrE,MAAMC,QAA0B;EAC9B;EACA;EACA,MAlBmB,cAAc;AACjC,OAAI,KAAM,QAAO;GACjB,MAAM,IAAI,iCAAiB,IAAI,MAAM;GACrC,MAAMC,OAAmC;IACvC,MAAM;IACN,QAAQ;IACR,WAAW;IACZ;AACD,OAAI,WAAY,MAAK,WAAW;GAChC,MAAM,QAAQ,IAAI,KAAK,eAAe,SAAS,KAAK,CAAC,cAAc,EAAE;AAGrE,UAAO,GAFI,MAAM,MAAM,MAAM,EAAE,SAAS,OAAO,EAAE,SAAS,KAE7C,GADF,MAAM,MAAM,MAAM,EAAE,SAAS,SAAS,EAAE,SAAS;KAE3D;GAAC;GAAM;GAAe;GAAW,CAAC;EAMnC;EACA;EACA;EACA;EACA;EACA;EACA,UAAU;EACV,WAAW;EACX,UAAU;EACV;EACA;EACA;EACA;EACA;EACA;EACD;CAED,MAAM,mBACJ,KAGA;AAEF,KAAI,CAAC,iBACH,QACE,qBAAC;EAAe;EAAW,OAAO;GAAE,SAAS;GAAK,UAAU;GAAI,OAAO;GAAQ;aAAE,gCAClD,KAAK;GAC9B;AAIV,QACE,oBAAC;EACY;EACX,OAAO;GAAE,YAAY,UAAU,YAAY;GAAU,WAAW;GAAW;YAE3E,oBAAC,oBAAiB,GAAI,QAAS;GAC3B;;;;;ACnPV,MAAaC,yBAAwC;CACnD,UAAU;EAAE,YAAY;EAAK,OAAO;EAAM,OAAO;EAAK,cAAc;EAAM;CAC1E,OAAO;EAAE,YAAY;EAAM,OAAO;EAAM,OAAO;EAAM,cAAc;EAAM;CACzE,MAAM;EAAE,YAAY;EAAM,OAAO;EAAM,OAAO;EAAM,cAAc;EAAK;CACvE,SAAS;EAAE,YAAY;EAAM,OAAO;EAAM,OAAO;EAAM,cAAc;EAAM;CAC3E,SAAS;EAAE,YAAY;EAAM,OAAO;EAAM,OAAO;EAAK,cAAc;EAAM;CAC1E,cAAc;EAAE,YAAY;EAAM,OAAO;EAAM,OAAO;EAAM,cAAc;EAAM;CAChF,WAAW;EAAE,YAAY;EAAM,OAAO;EAAK,OAAO;EAAK,cAAc;EAAM;CAC3E,QAAQ;EAAE,YAAY;EAAM,OAAO;EAAK,OAAO;EAAM,cAAc;EAAM;CACzE,MAAM;EAAE,YAAY;EAAM,OAAO;EAAM,OAAO;EAAK,cAAc;EAAM;CACxE;AAMD,MAAMC,cAA6B;CACjC,UAAU;EAAE,YAAY;EAAM,OAAO;EAAM,OAAO;EAAM,cAAc;EAAM;CAC5E,OAAO;EAAE,YAAY;EAAK,OAAO;EAAM,OAAO;EAAM,cAAc;EAAM;CACxE,MAAM;EAAE,YAAY;EAAM,OAAO;EAAM,OAAO;EAAM,cAAc;EAAM;CACxE,SAAS;EAAE,YAAY;EAAM,OAAO;EAAM,OAAO;EAAM,cAAc;EAAM;CAC3E,SAAS;EAAE,YAAY;EAAM,OAAO;EAAM,OAAO;EAAK,cAAc;EAAK;CACzE,cAAc;EAAE,YAAY;EAAK,OAAO;EAAM,OAAO;EAAM,cAAc;EAAM;CAC/E,WAAW;EAAE,YAAY;EAAM,OAAO;EAAM,OAAO;EAAK,cAAc;EAAK;CAC3E,QAAQ;EAAE,YAAY;EAAM,OAAO;EAAM,OAAO;EAAM,cAAc;EAAM;CAC1E,MAAM;EAAE,YAAY;EAAM,OAAO;EAAM,OAAO;EAAM,cAAc;EAAK;CACxE;AAID,MAAMC,mBAAkC;CACtC,UAAU;EAAE,YAAY;EAAK,OAAO;EAAK,OAAO;EAAK,cAAc;EAAM;CACzE,OAAO;EAAE,YAAY;EAAK,OAAO;EAAK,OAAO;EAAK,cAAc;EAAM;CACtE,MAAM;EAAE,YAAY;EAAK,OAAO;EAAK,OAAO;EAAK,cAAc;EAAM;CACrE,SAAS;EAAE,YAAY;EAAK,OAAO;EAAK,OAAO;EAAK,cAAc;EAAM;CACxE,SAAS;EAAE,YAAY;EAAK,OAAO;EAAK,OAAO;EAAK,cAAc;EAAM;CACxE,cAAc;EAAE,YAAY;EAAK,OAAO;EAAK,OAAO;EAAK,cAAc;EAAM;CAC7E,WAAW;EAAE,YAAY;EAAK,OAAO;EAAK,OAAO;EAAK,cAAc;EAAM;CAC1E,QAAQ;EAAE,YAAY;EAAK,OAAO;EAAK,OAAO;EAAK,cAAc;EAAM;CACvE,MAAM;EAAE,YAAY;EAAK,OAAO;EAAK,OAAO;EAAK,cAAc;EAAM;CACtE;AAKD,MAAMC,gBAA+B;CACnC,UAAU;EAAE,YAAY;EAAM,OAAO;EAAK,OAAO;EAAM,cAAc;EAAM;CAC3E,OAAO;EAAE,YAAY;EAAM,OAAO;EAAK,OAAO;EAAM,cAAc;EAAK;CACvE,MAAM;EAAE,YAAY;EAAM,OAAO;EAAM,OAAO;EAAM,cAAc;EAAM;CACxE,SAAS;EAAE,YAAY;EAAM,OAAO;EAAM,OAAO;EAAM,cAAc;EAAM;CAC3E,SAAS;EAAE,YAAY;EAAK,OAAO;EAAM,OAAO;EAAK,cAAc;EAAM;CACzE,cAAc;EAAE,YAAY;EAAK,OAAO;EAAM,OAAO;EAAK,cAAc;EAAK;CAC7E,WAAW;EAAE,YAAY;EAAK,OAAO;EAAM,OAAO;EAAK,cAAc;EAAM;CAC3E,QAAQ;EAAE,YAAY;EAAM,OAAO;EAAM,OAAO;EAAM,cAAc;EAAM;CAC1E,MAAM;EAAE,YAAY;EAAM,OAAO;EAAK,OAAO;EAAM,cAAc;EAAK;CACvE;AAID,MAAMC,kBAAiC;CACrC,UAAU;EAAE,YAAY;EAAM,OAAO;EAAM,OAAO;EAAM,cAAc;EAAM;CAC5E,OAAO;EAAE,YAAY;EAAM,OAAO;EAAM,OAAO;EAAK,cAAc;EAAM;CACxE,MAAM;EAAE,YAAY;EAAM,OAAO;EAAM,OAAO;EAAM,cAAc;EAAM;CACxE,SAAS;EAAE,YAAY;EAAK,OAAO;EAAM,OAAO;EAAK,cAAc;EAAM;CACzE,SAAS;EAAE,YAAY;EAAM,OAAO;EAAM,OAAO;EAAM,cAAc;EAAM;CAC3E,cAAc;EAAE,YAAY;EAAM,OAAO;EAAM,OAAO;EAAM,cAAc;EAAM;CAChF,WAAW;EAAE,YAAY;EAAM,OAAO;EAAM,OAAO;EAAM,cAAc;EAAM;CAC7E,QAAQ;EAAE,YAAY;EAAM,OAAO;EAAM,OAAO;EAAM,cAAc;EAAM;CAC1E,MAAM;EAAE,YAAY;EAAM,OAAO;EAAM,OAAO;EAAM,cAAc;EAAM;CACzE;AAID,MAAMC,iBAAgC;CACpC,UAAU;EAAE,YAAY;EAAM,OAAO;EAAM,OAAO;EAAM,cAAc;EAAK;CAC3E,OAAO;EAAE,YAAY;EAAK,OAAO;EAAM,OAAO;EAAM,cAAc;EAAM;CACxE,MAAM;EAAE,YAAY;EAAM,OAAO;EAAM,OAAO;EAAM,cAAc;EAAM;CACxE,SAAS;EAAE,YAAY;EAAM,OAAO;EAAK,OAAO;EAAM,cAAc;EAAM;CAC1E,SAAS;EAAE,YAAY;EAAM,OAAO;EAAM,OAAO;EAAM,cAAc;EAAM;CAC3E,cAAc;EAAE,YAAY;EAAK,OAAO;EAAM,OAAO;EAAM,cAAc;EAAM;CAC/E,WAAW;EAAE,YAAY;EAAM,OAAO;EAAM,OAAO;EAAM,cAAc;EAAM;CAC7E,QAAQ;EAAE,YAAY;EAAM,OAAO;EAAM,OAAO;EAAM,cAAc;EAAK;CACzE,MAAM;EAAE,YAAY;EAAM,OAAO;EAAM,OAAO;EAAK,cAAc;EAAM;CACxE;AAID,MAAMC,eAA8B;CAClC,UAAU;EAAE,YAAY;EAAM,OAAO;EAAM,OAAO;EAAK,cAAc;EAAM;CAC3E,OAAO;EAAE,YAAY;EAAM,OAAO;EAAM,OAAO;EAAM,cAAc;EAAM;CACzE,MAAM;EAAE,YAAY;EAAM,OAAO;EAAK,OAAO;EAAM,cAAc;EAAM;CACvE,SAAS;EAAE,YAAY;EAAM,OAAO;EAAM,OAAO;EAAK,cAAc;EAAM;CAC1E,SAAS;EAAE,YAAY;EAAM,OAAO;EAAM,OAAO;EAAM,cAAc;EAAM;CAC3E,cAAc;EAAE,YAAY;EAAM,OAAO;EAAM,OAAO;EAAM,cAAc;EAAM;CAChF,WAAW;EAAE,YAAY;EAAM,OAAO;EAAM,OAAO;EAAM,cAAc;EAAM;CAC7E,QAAQ;EAAE,YAAY;EAAK,OAAO;EAAK,OAAO;EAAM,cAAc;EAAK;CACvE,MAAM;EAAE,YAAY;EAAM,OAAO;EAAM,OAAO;EAAM,cAAc;EAAM;CACzE;AAID,MAAMC,iBAAgC;CACpC,UAAU;EAAE,YAAY;EAAM,OAAO;EAAM,OAAO;EAAK,cAAc;EAAM;CAC3E,OAAO;EAAE,YAAY;EAAK,OAAO;EAAM,OAAO;EAAM,cAAc;EAAM;CACxE,MAAM;EAAE,YAAY;EAAM,OAAO;EAAM,OAAO;EAAM,cAAc;EAAM;CACxE,SAAS;EAAE,YAAY;EAAK,OAAO;EAAM,OAAO;EAAK,cAAc;EAAM;CACzE,SAAS;EAAE,YAAY;EAAM,OAAO;EAAM,OAAO;EAAM,cAAc;EAAM;CAC3E,cAAc;EAAE,YAAY;EAAM,OAAO;EAAM,OAAO;EAAM,cAAc;EAAM;CAChF,WAAW;EAAE,YAAY;EAAM,OAAO;EAAM,OAAO;EAAM,cAAc;EAAM;CAC7E,QAAQ;EAAE,YAAY;EAAM,OAAO;EAAM,OAAO;EAAM,cAAc;EAAM;CAC1E,MAAM;EAAE,YAAY;EAAM,OAAO;EAAK,OAAO;EAAM,cAAc;EAAM;CACxE;AAID,MAAMC,iBAAgC;CACpC,UAAU;EAAE,YAAY;EAAM,OAAO;EAAK,OAAO;EAAM,cAAc;EAAM;CAC3E,OAAO;EAAE,YAAY;EAAM,OAAO;EAAM,OAAO;EAAM,cAAc;EAAM;CACzE,MAAM;EAAE,YAAY;EAAM,OAAO;EAAM,OAAO;EAAM,cAAc;EAAM;CACxE,SAAS;EAAE,YAAY;EAAM,OAAO;EAAM,OAAO;EAAM,cAAc;EAAM;CAC3E,SAAS;EAAE,YAAY;EAAM,OAAO;EAAM,OAAO;EAAK,cAAc;EAAM;CAC1E,cAAc;EAAE,YAAY;EAAM,OAAO;EAAM,OAAO;EAAK,cAAc;EAAM;CAC/E,WAAW;EAAE,YAAY;EAAK,OAAO;EAAM,OAAO;EAAK,cAAc;EAAM;CAC3E,QAAQ;EAAE,YAAY;EAAK,OAAO;EAAM,OAAO;EAAM,cAAc;EAAM;CACzE,MAAM;EAAE,YAAY;EAAK,OAAO;EAAK,OAAO;EAAM,cAAc;EAAM;CACvE;AAKD,MAAMC,cAA6B;CACjC,UAAU;EAAE,YAAY;EAAK,OAAO;EAAM,OAAO;EAAM,cAAc;EAAM;CAC3E,OAAO;EAAE,YAAY;EAAM,OAAO;EAAK,OAAO;EAAM,cAAc;EAAM;CACxE,MAAM;EAAE,YAAY;EAAM,OAAO;EAAM,OAAO;EAAM,cAAc;EAAM;CACxE,SAAS;EAAE,YAAY;EAAM,OAAO;EAAK,OAAO;EAAM,cAAc;EAAM;CAC1E,SAAS;EAAE,YAAY;EAAM,OAAO;EAAM,OAAO;EAAM,cAAc;EAAM;CAC3E,cAAc;EAAE,YAAY;EAAK,OAAO;EAAM,OAAO;EAAM,cAAc;EAAM;CAC/E,WAAW;EAAE,YAAY;EAAM,OAAO;EAAM,OAAO;EAAM,cAAc;EAAM;CAC7E,QAAQ;EAAE,YAAY;EAAM,OAAO;EAAM,OAAO;EAAK,cAAc;EAAM;CACzE,MAAM;EAAE,YAAY;EAAK,OAAO;EAAM,OAAO;EAAM,cAAc;EAAM;CACxE;AAKD,MAAMC,gBAA+B;CACnC,UAAU;EAAE,YAAY;EAAK,OAAO;EAAM,OAAO;EAAK,cAAc;EAAM;CAC1E,OAAO;EAAE,YAAY;EAAM,OAAO;EAAK,OAAO;EAAK,cAAc;EAAM;CACvE,MAAM;EAAE,YAAY;EAAM,OAAO;EAAM,OAAO;EAAM,cAAc;EAAM;CACxE,SAAS;EAAE,YAAY;EAAM,OAAO;EAAM,OAAO;EAAK,cAAc;EAAM;CAC1E,SAAS;EAAE,YAAY;EAAM,OAAO;EAAM,OAAO;EAAM,cAAc;EAAM;CAC3E,cAAc;EAAE,YAAY;EAAM,OAAO;EAAM,OAAO;EAAM,cAAc;EAAM;CAChF,WAAW;EAAE,YAAY;EAAM,OAAO;EAAM,OAAO;EAAM,cAAc;EAAM;CAC7E,QAAQ;EAAE,YAAY;EAAM,OAAO;EAAM,OAAO;EAAM,cAAc;EAAM;CAC1E,MAAM;EAAE,YAAY;EAAM,OAAO;EAAM,OAAO;EAAK,cAAc;EAAM;CACxE;AAID,MAAaC,uBAA0D;CACrE,MAAM;CACN,WAAW;CACX,QAAQ;CACR,UAAU;CACV,SAAS;CACT,OAAO;CACP,SAAS;CACT,SAAS;CACT,MAAM;CACN,QAAQ;CACT;;;;AC7MD,MAAM,mBAAmB,cAA6B,WAAW;AAYjE,SAAgB,mBAAkC;AAChD,QAAO,WAAW,iBAAiB;;AAKrC,MAAM,yBAAyB;CAC7B,OAAO;CACP,YAAY;CACZ,OAAO;CACP,cAAc;CACf;AAED,MAAM,0BAA0B;AAEhC,SAAS,qBAAqB,GAA+B;AAC3D,QAAO;EACL,OAAO,EAAE,QAAQ,uBAAuB;EACxC,YAAY,EAAE,aAAa,uBAAuB;EAClD,OAAO,EAAE,QAAQ,uBAAuB;EACxC,cAAc,KAAK,IAAI,GAAG,EAAE,eAAe,uBAAuB,aAAa;EAChF;;AAKH,MAAM,yBAAyB;CAC7B,OAAO;CACP,YAAY;CACZ,OAAO;CACP,cAAc;CACf;AAED,MAAM,0BAA0B;AAEhC,SAAS,qBAAqB,GAA+B;AAC3D,QAAO;EACL,OAAO,EAAE,QAAQ,uBAAuB;EACxC,YAAY,EAAE,aAAa,uBAAuB;EAClD,OAAO,EAAE,QAAQ,uBAAuB;EACxC,cAAc,KAAK,IAAI,GAAG,EAAE,eAAe,uBAAuB,aAAa;EAChF;;AAGH,SAAS,UAAU,KAAa,QAAgB,KAAqB;AACnE,QAAO,UAAU,KAAK,QAAQ,IAAI;;AAGpC,SAAS,sBAAsB,GAAiC;CAC9D,MAAM,WAAW;CACjB,MAAM,eAAe;AACrB,QAAO;EACL,GAAG;EACH,QAAQ,EAAE,OAAO,KAAK,MAAM,UAAU,GAAG,UAAU,IAAK,CAAC;EACzD,WAAW,UAAU,EAAE,WAAW,UAAU,IAAK;EACjD,UAAU,UAAU,EAAE,UAAU,cAAc,GAAI;EAClD,aAAa,2BAA2B,SAAS;EAClD;;AAKH,SAAS,QAAQ,GAAW,GAAW,GAAmB;AACxD,QAAO,KAAK,IAAI,KAAK;;AAGvB,SAAS,WAAW,GAAiB,GAAiB,GAAyB;AAC7E,QAAO;EACL,YAAY,QAAQ,EAAE,YAAY,EAAE,YAAY,EAAE;EAClD,OAAO,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE;EACnC,OAAO,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE;EACnC,cAAc,QAAQ,EAAE,cAAc,EAAE,cAAc,EAAE;EACzD;;AAGH,SAAS,YAAY,GAAkB,GAAkB,GAA0B;AACjF,QAAO;EACL,QAAQ,EAAE,OAAO,KAAK,IAAI,MAAM,UAAU,IAAI,EAAE,OAAO,MAAM,IAAI,EAAE,CAAC;EAMpE,WAAW,UAAU,EAAE,WAAW,EAAE,WAAW,EAAE;EACjD,SAAS,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAE;EACzC,UAAU,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE;EAC9C,aAAa,EAAE;EACf,OAAO,EAAE;EACV;;AAKH,SAAS,qBAAqB,MAAwD;AACpF,KAAI,KAAK,aAAc,QAAO,KAAK;AACnC,QAAO,qBAAqB,KAAK,OAAO;;AAK1C,SAAS,aAAa,MAAsB,SAAiD;AAC3F,QAAO,QAAQ,SAAS,KAAK;;AAK/B,SAAS,cAAc,MAAsB,OAAmB;CAC9D,MAAM,gBAAgB,qBAAqB,KAAK;CAChD,MAAM,EAAE,OAAO,WAAW,MAAM;AAChC,QAAO;EACL,SAAS,YAAY,KAAK,eAAe,QAAQ,KAAK,eAAe,YAAY,EAAE;EACnF,QAAQ,WAAW,cAAc,QAAQ,cAAc,YAAY,EAAE;EACtE;;AAKH,SAAS,SAAS,KAAuC;CACvD,MAAM,SAAS,4CAA4C,KAAK,IAAI;AACpE,QAAO,SACH;EACE,OAAO,SAAS,OAAO,IAAI,GAAG,GAAG;EACjC,OAAO,SAAS,OAAO,IAAI,GAAG,GAAG;EACjC,OAAO,SAAS,OAAO,IAAI,GAAG,GAAG;EAClC,GACD;EAAC;EAAG;EAAG;EAAE;;AAQf,MAAM,YAAY;;;;;;AAOlB,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAuElB,SAAS,iBAAiB,EACxB,iBACA,QACA,OACA,WACA,QACA,WACA,SACwB;CACxB,MAAM,YAAY,OAA0B,KAAK;CACjD,MAAM,eAAe,OAAsB,KAAK;CAEhD,MAAM,YAAY,OAAO;EACvB;EACA;EACA;EACA;EACA;EACA;EACA;EACD,CAAC;AAEF,iBAAgB;AACd,YAAU,UAAU;GAClB;GACA;GACA;GACA;GACA;GACA;GACA;GACD;IACA;EAAC;EAAiB;EAAQ;EAAO;EAAW;EAAQ;EAAW;EAAM,CAAC;AAKzE,uBAAsB;EACpB,MAAM,SAAS,UAAU;AACzB,MAAI,CAAC,OAAQ;EAEb,MAAM,KAAK,OAAO,WAAW,SAAS;AACtC,MAAI,CAAC,GAAI;EAET,MAAM,gBAAgB,MAAc,WAAmB;GACrD,MAAM,SAAS,GAAG,aAAa,KAAK;AACpC,OAAI,CAAC,OAAQ,QAAO;AACpB,MAAG,aAAa,QAAQ,OAAO;AAC/B,MAAG,cAAc,OAAO;AACxB,OAAI,CAAC,GAAG,mBAAmB,QAAQ,GAAG,eAAe,EAAE;AACrD,OAAG,aAAa,OAAO;AACvB,WAAO;;AAET,UAAO;;EAGT,MAAM,KAAK,aAAa,GAAG,eAAe,UAAU;EACpD,MAAM,KAAK,aAAa,GAAG,iBAAiB,UAAU;AACtD,MAAI,CAAC,MAAM,CAAC,GAAI;EAEhB,MAAM,UAAU,GAAG,eAAe;AAClC,MAAI,CAAC,QAAS;AAEd,KAAG,aAAa,SAAS,GAAG;AAC5B,KAAG,aAAa,SAAS,GAAG;AAC5B,KAAG,YAAY,QAAQ;AACvB,MAAI,CAAC,GAAG,oBAAoB,SAAS,GAAG,YAAY,CAAE;EAEtD,MAAM,iBAAiB,GAAG,cAAc;AACxC,KAAG,WAAW,GAAG,cAAc,eAAe;AAC9C,KAAG,WACD,GAAG,cACH,IAAI,aAAa;GAAC;GAAI;GAAI;GAAG;GAAI;GAAI;GAAG;GAAI;GAAG;GAAG;GAAI;GAAG;GAAE,CAAC,EAC5D,GAAG,YACJ;EAED,MAAM,SAAS,GAAG,kBAAkB,SAAS,aAAa;AAC1D,KAAG,wBAAwB,OAAO;AAClC,KAAG,oBAAoB,QAAQ,GAAG,GAAG,OAAO,OAAO,GAAG,EAAE;EAExD,MAAM,MAAM;GACV,GAAG,GAAG,mBAAmB,SAAS,IAAI;GACtC,GAAG,GAAG,mBAAmB,SAAS,IAAI;GACtC,IAAI,GAAG,mBAAmB,SAAS,OAAO;GAC1C,IAAI,GAAG,mBAAmB,SAAS,OAAO;GAC1C,IAAI,GAAG,mBAAmB,SAAS,OAAO;GAC1C,IAAI,GAAG,mBAAmB,SAAS,OAAO;GAC1C,IAAI,GAAG,mBAAmB,SAAS,OAAO;GAC1C,WAAW,GAAG,mBAAmB,SAAS,cAAc;GACxD,QAAQ,GAAG,mBAAmB,SAAS,WAAW;GAClD,WAAW,GAAG,mBAAmB,SAAS,cAAc;GACxD,OAAO,GAAG,mBAAmB,SAAS,UAAU;GAChD,OAAO,GAAG,mBAAmB,SAAS,UAAU;GACjD;EAED,MAAM,qBAAqB;GACzB,MAAM,MAAM,OAAO,oBAAoB;AACvC,UAAO,QAAQ,KAAK,MAAM,OAAO,cAAc,IAAI;AACnD,UAAO,SAAS,KAAK,MAAM,OAAO,eAAe,IAAI;AACrD,MAAG,SAAS,GAAG,GAAG,OAAO,OAAO,OAAO,OAAO;;AAGhD,SAAO,iBAAiB,UAAU,aAAa;AAC/C,gBAAc;EAEd,MAAM,YAAY,YAAY,KAAK;EAEnC,MAAM,eAAe;GACnB,MAAM,MAAM,UAAU;AACtB,MAAG,WAAW,QAAQ;AAEtB,MAAG,UAAU,IAAI,GAAG,OAAO,OAAO,OAAO,OAAO;AAChD,MAAG,UAAU,IAAI,IAAI,YAAY,KAAK,GAAG,aAAa,IAAK;GAE3D,MAAM,KAAK,SAAS,IAAI,gBAAgB;AACxC,MAAG,UAAU,IAAI,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,GAAG;GAEzC,MAAM,KAAK,SAAS,IAAI,OAAO,GAAG;GAClC,MAAM,KAAK,SAAS,IAAI,OAAO,GAAG;GAClC,MAAM,KAAK,SAAS,IAAI,OAAO,GAAG;GAClC,MAAM,KAAK,SAAS,IAAI,OAAO,GAAG;AAClC,MAAG,UAAU,IAAI,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,GAAG;AACzC,MAAG,UAAU,IAAI,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,GAAG;AACzC,MAAG,UAAU,IAAI,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,GAAG;AACzC,MAAG,UAAU,IAAI,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,GAAG;AAEzC,MAAG,UAAU,IAAI,WAAW,IAAI,UAAU;AAC1C,MAAG,UAAU,IAAI,QAAQ,IAAI,OAAO;AACpC,MAAG,UAAU,IAAI,WAAW,IAAI,UAAU;AAC1C,MAAG,UAAU,IAAI,OAAO,IAAI,MAAM;AAClC,MAAG,UAAU,IAAI,OAAO,IAAI,MAAM;AAElC,MAAG,WAAW,GAAG,WAAW,GAAG,EAAE;AACjC,gBAAa,UAAU,sBAAsB,OAAO;;AAGtD,UAAQ;AAER,eAAa;AACX,UAAO,oBAAoB,UAAU,aAAa;AAClD,OAAI,aAAa,QAAS,sBAAqB,aAAa,QAAQ;AACpE,MAAG,cAAc,QAAQ;AACzB,MAAG,aAAa,GAAG;AACnB,MAAG,aAAa,GAAG;AACnB,MAAG,aAAa,eAAe;;IAEhC,EAAE,CAAC;AAEN,QACE,oBAAC;EACC,KAAK;EACL,OAAO;GACL,UAAU;GACV,KAAK;GACL,MAAM;GACN,OAAO;GACP,QAAQ;GACT;GACD;;AAQN,IAAI,eAAe;AAenB,SAAgB,cAAc,EAC5B,cACA,eACA,iBACA,SAAS,aACT,WACA,UACsB,EAAE,EAAE;CAC1B,MAAM,EAAE,YAAY,OAAO,iBAAiB,eAAe;CAC3D,MAAM,iBAAiB,kBAAkB;CAEzC,MAAM,OAAO,gBAAgB;CAC7B,MAAM,QAAQ,iBAAiB;CAC/B,MAAM,UAAU,eAAe;CAG/B,MAAM,EAAE,SAAS,QAAQ,cAAc,cAC/B,cAAc,MAAM,MAAM,EAEhC;EAAC,MAAM;EAAO,MAAM;EAAW,MAAM;EAAG;EAAK,CAC9C;CAED,MAAM,iBAAiB,YAAY,cAAc,sBAAsB,QAAQ,GAAG;CAElF,MAAM,eACJ,YAAY,cACR,qBAAqB,UAAU,GAC/B,YAAY,cACV,qBAAqB,UAAU,GAC/B;CAER,MAAM,kBACJ,oBACC,YAAY,cACT,eAAe,UAAU,0BACzB,YAAY,cACV,eAAe,UAAU,0BACzB,eAAe;CAEvB,MAAM,cAAc,aAAa,MAAM,eAAe;CAMtD,MAAM,CAAC,SAAS,cAAc,SAAS,aAAa;AACpD,uBAAsB;AACpB,iBAAe;AACf,aAAW,KAAK;IACf,EAAE,CAAC;AAEN,iBAAgB;AACd,WAAS,gBAAgB,MAAM,YAAY,qBAAqB,eAAe,UAAU;AACzF,eAAa;AACX,YAAS,gBAAgB,MAAM,eAAe,oBAAoB;;IAEnE,CAAC,eAAe,UAAU,CAAC;CAM9B,MAAM,aAAa,KAAM,aAAa,QAAQ;CAC9C,MAAM,iBAAiB,MAAM,aAAa,aAAa;CACvD,MAAM,cAAc,IAAM,aAAa,QAAQ;CAC/C,MAAM,iBAAiB,MAAO,IAAM,aAAa,SAAS;CAC1D,MAAM,aAAa,aAAa,eAAe;AAE/C,QACE,oBAAC;EACY;EACX;EACA,OAAO;GACL,UAAU;GACV,OAAO;GACP,UAAU;GACV,YAAY,eAAe,eAAe,eAAe;GACzD,GAAG;GACJ;YAEA,WACC;GAEE,oBAAC;IAAI,WAAU;IAAmB,OAAO,EAAE,SAAS,iBAAiB;cACnE,oBAAC;KACC,iBAAiB,eAAe;KAChC,QAAQ,eAAe;KACvB,OAAO;KACP,WAAW;KACX,QAAQ;KACR,WAAW;KACX,OAAO;MACP;KACE;GAGL,eACC,oBAAC;IACC,WAAU;IACV;IACA,OAAO;KACL,SAAS,YAAY,WAAW;KAChC,eAAe;KACf,YAAY;KACZ,iBAAiB,OAAO,YAAY,IAAI;KACxC,WAAW,OAAO,YAAY,IAAI;KAClC,gBAAgB;KAChB,UAAU;KACV,oBAAoB,YAAY,kBAAkB;KAClD,cAAc,YAAY,kBAAkB;KAC5C,kBAAkB;KAClB,YAAY;KACb;KACD;GAIJ,oBAAC;IACC,WAAU;IACV;IACA,OAAO;KACL,eAAe;KACf,YAAY,+DAA+D,eAAe,SAAS;KACpG;KACD;MACD;GAED;;AAMV,SAAgB,kBAAkB,QAA4B,EAAE,EAAE;AAChE,QAAO,oBAAC;EAAc,GAAI;EAAO,OAAO;GAAE,QAAQ;GAAG,GAAG,MAAM;GAAO;GAAI"}
@@ -54747,5 +54747,5 @@ function SolarThemeProvider({ children, initialDesign = "foundry", isolated = fa
54747
54747
  }
54748
54748
 
54749
54749
  //#endregion
54750
- export { getSessionIsLive as a, setSessionTimeMinutes as c, clearSessionTimeMinutes as i, lerpHex as l, useSolarTheme as n, getSessionTimeMinutes as o, SKINS as r, setSessionLive as s, SolarThemeProvider as t };
54751
- //# sourceMappingURL=solar-theme-provider-6-EJ4jGB.js.map
54750
+ export { getSessionIsLive as a, setSessionTimeMinutes as c, clearSessionTimeMinutes as i, lerpColor as l, useSolarTheme as n, getSessionTimeMinutes as o, SKINS as r, setSessionLive as s, SolarThemeProvider as t, lerpHex as u };
54751
+ //# sourceMappingURL=solar-theme-provider-CSustvmw.js.map