(function () { 'use strict'; const root = window.PixelIslandModules ||= {}; const clamp = (value, min, max) => Math.max(min, Math.min(max, value)); const lerp = (a, b, t) => a + (b - a) * t; const mod = (n, m) => ((n % m) + m) % m; function getCelestialLightForMinute(minute) { const isNight = minute >= 6; const local = isNight ? (minute - 6) / 4 : minute / 6; const t = clamp(local, 0, 1); const eased = t * t * (3 - 2 * t); const elevation = Math.max(.08, Math.sin(t * Math.PI)); const sourceX = isNight ? lerp(-1.05, 1.05, eased) : lerp(1.18, -1.18, eased); const sourceY = isNight ? -.46 - elevation * .24 : -.58 - elevation * .34; return { x: sourceX, y: sourceY, elevation, isNight, shadeAlpha: isNight ? .18 : lerp(.20, .08, elevation) }; } function getShadowForMinute(minute) { const light = getCelestialLightForMinute(minute); const length = lerp(light.isNight ? 1.35 : 1.9, light.isNight ? .85 : .52, light.elevation); return { x: -light.x * 6.5 * length, y: Math.min(-1.8, light.y * 4.2 * length), length, alpha: light.isNight ? .085 : lerp(.27, .12, light.elevation) }; } function getPhase(dayMs, now = Date.now()) { const t = mod(now, dayMs); const minute = t / 60000; const stops = [ { at: 0, key: 'morning', label: 'Morning', darkness: 0.18, tint: [255, 208, 144, 0.12] }, { at: 1, key: 'day', label: 'Day', darkness: 0.00, tint: [255, 255, 255, 0.00] }, { at: 5, key: 'day', label: 'Day', darkness: 0.00, tint: [255, 255, 255, 0.00] }, { at: 6, key: 'evening', label: 'Evening', darkness: 0.18, tint: [255, 146, 114, 0.14] }, { at: 10, key: 'night', label: 'Night', darkness: 0.48, tint: [36, 47, 96, 0.18] } ]; let a = stops[0], b = stops[1]; for (let i = 0; i < stops.length - 1; i++) { if (minute >= stops[i].at && minute < stops[i + 1].at) { a = stops[i]; b = stops[i + 1]; break; } if (minute >= 6) { a = stops[3]; b = stops[4]; } } const localT = clamp((minute - a.at) / Math.max(0.0001, b.at - a.at), 0, 1); const eased = localT * localT * (3 - 2 * localT); const tint = a.tint.map((v, i) => lerp(v, b.tint[i], eased)); const label = minute < 1 ? 'Morning' : minute < 5 ? 'Day' : minute < 6 ? 'Evening' : 'Night'; return { key: label.toLowerCase(), label, progress: t / dayMs, darkness: lerp(a.darkness, b.darkness, eased), tint: `rgba(${Math.round(tint[0])}, ${Math.round(tint[1])}, ${Math.round(tint[2])}, ${tint[3].toFixed(3)})`, light: getCelestialLightForMinute(minute), shadow: getShadowForMinute(minute) }; } root.Lighting = { getPhase, getShadowForMinute, getCelestialLightForMinute }; })();