Cover mining diagnostics JSON blockers, AV-Safe preset fields, defender_off error paths, and Calibrate exclusion .ps1 generation with Go + Vitest; honest AV limits already documented in settingHelp.
253 lines
6.5 KiB
TypeScript
253 lines
6.5 KiB
TypeScript
/** Route → ambient 3D weather (particle glow, drift, palette). Mirrors ambientMusic page map. */
|
||
|
||
export type WeatherVibe =
|
||
| 'forge-glow'
|
||
| 'crucible-embers'
|
||
| 'emberwake-pulse'
|
||
| 'starfield-dim'
|
||
| 'medium-drift';
|
||
|
||
export type WeatherPalette = 'default' | 'crucible' | 'campaign' | 'dim';
|
||
|
||
export interface PageWeatherConfig {
|
||
vibe: WeatherVibe;
|
||
/** 0–1 overall particle glow strength */
|
||
intensity: number;
|
||
/** Velocity multiplier */
|
||
speed: number;
|
||
/** Pulse / twinkle rate multiplier */
|
||
pulse: number;
|
||
/** Particle density multiplier */
|
||
density: number;
|
||
/** Constellation link strength 0–1 */
|
||
linkStrength: number;
|
||
/** CSS grid / sacred-geo layer opacity */
|
||
layerOpacity: number;
|
||
/** Orb float animation duration (seconds; higher = slower) */
|
||
orbDrift: number;
|
||
/** Grid drift animation duration (seconds) */
|
||
gridDrift: number;
|
||
palette: WeatherPalette;
|
||
/** Campaign-energy sine pulse on emberwake routes */
|
||
energyPulse?: boolean;
|
||
}
|
||
|
||
export const DEFAULT_PAGE_WEATHER: PageWeatherConfig = {
|
||
vibe: 'medium-drift',
|
||
intensity: 0.65,
|
||
speed: 0.5,
|
||
pulse: 0.65,
|
||
density: 0.72,
|
||
linkStrength: 0.7,
|
||
layerOpacity: 0.55,
|
||
orbDrift: 14,
|
||
gridDrift: 48,
|
||
palette: 'default',
|
||
};
|
||
|
||
/** Route → weather profile. Prefix match for nested paths. */
|
||
export const PAGE_WEATHER: Record<string, PageWeatherConfig> = {
|
||
'/forge': {
|
||
vibe: 'forge-glow',
|
||
intensity: 1,
|
||
speed: 1,
|
||
pulse: 1,
|
||
density: 1,
|
||
linkStrength: 1,
|
||
layerOpacity: 0.6,
|
||
orbDrift: 12,
|
||
gridDrift: 40,
|
||
palette: 'default',
|
||
},
|
||
'/builder': {
|
||
vibe: 'forge-glow',
|
||
intensity: 1,
|
||
speed: 1,
|
||
pulse: 1,
|
||
density: 1,
|
||
linkStrength: 1,
|
||
layerOpacity: 0.6,
|
||
orbDrift: 12,
|
||
gridDrift: 40,
|
||
palette: 'default',
|
||
},
|
||
'/mission-deck': {
|
||
vibe: 'forge-glow',
|
||
intensity: 1,
|
||
speed: 1,
|
||
pulse: 1.05,
|
||
density: 1,
|
||
linkStrength: 1,
|
||
layerOpacity: 0.62,
|
||
orbDrift: 11,
|
||
gridDrift: 38,
|
||
palette: 'default',
|
||
},
|
||
'/lotl-timeline': {
|
||
vibe: 'crucible-embers',
|
||
intensity: 0.82,
|
||
speed: 0.38,
|
||
pulse: 0.72,
|
||
density: 0.88,
|
||
linkStrength: 0.5,
|
||
layerOpacity: 0.52,
|
||
orbDrift: 18,
|
||
gridDrift: 64,
|
||
palette: 'crucible',
|
||
},
|
||
'/onion': {
|
||
vibe: 'crucible-embers',
|
||
intensity: 0.82,
|
||
speed: 0.38,
|
||
pulse: 0.72,
|
||
density: 0.88,
|
||
linkStrength: 0.5,
|
||
layerOpacity: 0.52,
|
||
orbDrift: 18,
|
||
gridDrift: 64,
|
||
palette: 'crucible',
|
||
},
|
||
'/crucible': {
|
||
vibe: 'crucible-embers',
|
||
intensity: 0.75,
|
||
speed: 0.32,
|
||
pulse: 0.45,
|
||
density: 0.85,
|
||
linkStrength: 0.45,
|
||
layerOpacity: 0.5,
|
||
orbDrift: 22,
|
||
gridDrift: 72,
|
||
palette: 'crucible',
|
||
},
|
||
'/emberwake': {
|
||
vibe: 'emberwake-pulse',
|
||
intensity: 0.85,
|
||
speed: 0.55,
|
||
pulse: 1.6,
|
||
density: 0.9,
|
||
linkStrength: 0.75,
|
||
layerOpacity: 0.58,
|
||
orbDrift: 9,
|
||
gridDrift: 36,
|
||
palette: 'campaign',
|
||
energyPulse: true,
|
||
},
|
||
'/spread': {
|
||
vibe: 'emberwake-pulse',
|
||
intensity: 0.85,
|
||
speed: 0.55,
|
||
pulse: 1.6,
|
||
density: 0.9,
|
||
linkStrength: 0.75,
|
||
layerOpacity: 0.58,
|
||
orbDrift: 9,
|
||
gridDrift: 36,
|
||
palette: 'campaign',
|
||
energyPulse: true,
|
||
},
|
||
'/settings': {
|
||
vibe: 'starfield-dim',
|
||
intensity: 0.22,
|
||
speed: 0.15,
|
||
pulse: 0.35,
|
||
density: 0.45,
|
||
linkStrength: 0.12,
|
||
layerOpacity: 0.28,
|
||
orbDrift: 36,
|
||
gridDrift: 120,
|
||
palette: 'dim',
|
||
},
|
||
'/agents': {
|
||
vibe: 'medium-drift',
|
||
intensity: 0.68,
|
||
speed: 0.55,
|
||
pulse: 0.7,
|
||
density: 0.75,
|
||
linkStrength: 0.72,
|
||
layerOpacity: 0.52,
|
||
orbDrift: 15,
|
||
gridDrift: 50,
|
||
palette: 'default',
|
||
},
|
||
'/dashboard': {
|
||
vibe: 'medium-drift',
|
||
intensity: 0.65,
|
||
speed: 0.5,
|
||
pulse: 0.65,
|
||
density: 0.72,
|
||
linkStrength: 0.7,
|
||
layerOpacity: 0.55,
|
||
orbDrift: 14,
|
||
gridDrift: 48,
|
||
palette: 'default',
|
||
},
|
||
'/builds': {
|
||
vibe: 'medium-drift',
|
||
intensity: 0.55,
|
||
speed: 0.45,
|
||
pulse: 0.6,
|
||
density: 0.65,
|
||
linkStrength: 0.6,
|
||
layerOpacity: 0.48,
|
||
orbDrift: 16,
|
||
gridDrift: 54,
|
||
palette: 'default',
|
||
},
|
||
'/pathtracer': {
|
||
vibe: 'starfield-dim',
|
||
intensity: 0.35,
|
||
speed: 0.25,
|
||
pulse: 0.4,
|
||
density: 0.5,
|
||
linkStrength: 0.2,
|
||
layerOpacity: 0.32,
|
||
orbDrift: 28,
|
||
gridDrift: 90,
|
||
palette: 'dim',
|
||
},
|
||
};
|
||
|
||
export function resolvePageWeather(pathname: string): PageWeatherConfig {
|
||
const path = pathname.split('?')[0].replace(/\/$/, '') || '/';
|
||
if (PAGE_WEATHER[path] !== undefined) {
|
||
return PAGE_WEATHER[path];
|
||
}
|
||
for (const [prefix, weather] of Object.entries(PAGE_WEATHER)) {
|
||
if (prefix !== '/' && path.startsWith(prefix)) return weather;
|
||
}
|
||
return DEFAULT_PAGE_WEATHER;
|
||
}
|
||
|
||
export type GlowColor = {
|
||
core: string;
|
||
mid: string;
|
||
line: string;
|
||
};
|
||
|
||
export const WEATHER_PALETTES: Record<WeatherPalette, readonly GlowColor[]> = {
|
||
default: [
|
||
{ core: 'rgba(201, 162, 39, 0.85)', mid: 'rgba(201, 162, 39, 0.25)', line: 'rgba(201, 162, 39, 0.12)' },
|
||
{ core: 'rgba(0, 232, 245, 0.75)', mid: 'rgba(0, 232, 245, 0.22)', line: 'rgba(0, 232, 245, 0.1)' },
|
||
{ core: 'rgba(255, 45, 166, 0.7)', mid: 'rgba(255, 45, 166, 0.2)', line: 'rgba(255, 45, 166, 0.09)' },
|
||
{ core: 'rgba(255, 176, 32, 0.8)', mid: 'rgba(255, 176, 32, 0.22)', line: 'rgba(255, 176, 32, 0.1)' },
|
||
],
|
||
crucible: [
|
||
{ core: 'rgba(212, 175, 55, 0.9)', mid: 'rgba(212, 175, 55, 0.28)', line: 'rgba(212, 175, 55, 0.14)' },
|
||
{ core: 'rgba(232, 93, 74, 0.78)', mid: 'rgba(232, 93, 74, 0.22)', line: 'rgba(232, 93, 74, 0.1)' },
|
||
{ core: 'rgba(255, 140, 58, 0.82)', mid: 'rgba(255, 140, 58, 0.24)', line: 'rgba(255, 140, 58, 0.11)' },
|
||
{ core: 'rgba(180, 90, 40, 0.72)', mid: 'rgba(180, 90, 40, 0.2)', line: 'rgba(180, 90, 40, 0.09)' },
|
||
],
|
||
campaign: [
|
||
{ core: 'rgba(255, 95, 25, 0.92)', mid: 'rgba(255, 95, 25, 0.3)', line: 'rgba(255, 95, 25, 0.14)' },
|
||
{ core: 'rgba(255, 176, 32, 0.85)', mid: 'rgba(255, 176, 32, 0.26)', line: 'rgba(255, 176, 32, 0.12)' },
|
||
{ core: 'rgba(255, 55, 90, 0.7)', mid: 'rgba(255, 55, 90, 0.2)', line: 'rgba(255, 55, 90, 0.09)' },
|
||
{ core: 'rgba(0, 220, 255, 0.55)', mid: 'rgba(0, 220, 255, 0.16)', line: 'rgba(0, 220, 255, 0.08)' },
|
||
],
|
||
dim: [
|
||
{ core: 'rgba(190, 200, 230, 0.42)', mid: 'rgba(190, 200, 230, 0.12)', line: 'rgba(190, 200, 230, 0.05)' },
|
||
{ core: 'rgba(130, 150, 190, 0.32)', mid: 'rgba(130, 150, 190, 0.1)', line: 'rgba(130, 150, 190, 0.04)' },
|
||
{ core: 'rgba(201, 162, 39, 0.22)', mid: 'rgba(201, 162, 39, 0.08)', line: 'rgba(201, 162, 39, 0.03)' },
|
||
{ core: 'rgba(0, 232, 245, 0.18)', mid: 'rgba(0, 232, 245, 0.06)', line: 'rgba(0, 232, 245, 0.03)' },
|
||
],
|
||
};
|