style: candlelit glow background replaces star field
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -41,10 +41,15 @@ a { color: var(--accent); text-decoration: none; }
|
||||
a:hover { color: var(--accent-hover); }
|
||||
code { font-family: ui-monospace, monospace; font-size: 0.875em; background: var(--bg-elevated); padding: 0.1em 0.35em; border-radius: 3px; }
|
||||
|
||||
/* Star field */
|
||||
#star-field { position: fixed; inset: 0; pointer-events: none; z-index: 0; overflow: hidden; }
|
||||
@keyframes star-orbit { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }
|
||||
@keyframes star-spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }
|
||||
#candle-glow {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
pointer-events: none;
|
||||
z-index: 0;
|
||||
background:
|
||||
radial-gradient(ellipse 80% 60% at 50% 40%, rgba(200, 168, 64, 0.045) 0%, transparent 70%),
|
||||
radial-gradient(ellipse 50% 40% at 20% 80%, rgba(200, 168, 64, 0.025) 0%, transparent 65%);
|
||||
}
|
||||
|
||||
/* Nav */
|
||||
nav {
|
||||
@@ -177,8 +182,7 @@ textarea { resize: vertical; }
|
||||
</head>
|
||||
<body>
|
||||
|
||||
{# Star field — orbits around top-left corner, populated by JS below #}
|
||||
<div id="star-field"></div>
|
||||
<div id="candle-glow"></div>
|
||||
|
||||
{% if session.user_id is defined %}
|
||||
<nav>
|
||||
@@ -243,111 +247,6 @@ function setTimeRange(val) {
|
||||
{% block content %}{% endblock %}
|
||||
</main>
|
||||
|
||||
<script>
|
||||
(function () {
|
||||
var field = document.getElementById('star-field');
|
||||
if (!field) return;
|
||||
|
||||
var W = window.innerWidth;
|
||||
var H = window.innerHeight;
|
||||
var maxR = Math.sqrt(W * W + H * H);
|
||||
|
||||
// Subtle purple glow anchoring the field to the top-left corner
|
||||
var glow = document.createElement('div');
|
||||
glow.style.cssText = 'position:absolute;width:500px;height:500px;left:-250px;top:-250px;border-radius:50%;background:radial-gradient(circle,rgba(124,94,244,0.06) 0%,transparent 65%);pointer-events:none;';
|
||||
field.appendChild(glow);
|
||||
|
||||
// Compute polygon points for a 5-pointed star inside a size×size box
|
||||
function starPoints(size) {
|
||||
var cx = size / 2, cy = size / 2;
|
||||
var R = size / 2 * 0.95; // outer radius
|
||||
var r = R * 0.382; // inner radius (golden ratio)
|
||||
var pts = [];
|
||||
for (var i = 0; i < 5; i++) {
|
||||
var oa = (i * 72 - 90) * Math.PI / 180;
|
||||
var ia = (i * 72 - 90 + 36) * Math.PI / 180;
|
||||
pts.push((cx + R * Math.cos(oa)).toFixed(2) + ',' + (cy + R * Math.sin(oa)).toFixed(2));
|
||||
pts.push((cx + r * Math.cos(ia)).toFixed(2) + ',' + (cy + r * Math.sin(ia)).toFixed(2));
|
||||
}
|
||||
return pts.join(' ');
|
||||
}
|
||||
|
||||
// 22 wizard-hat stars: [size(px), opacity, isGold, orbitDuration(s), spinDuration(s)]
|
||||
var defs = [
|
||||
[230, 0.09, true, 200, 28],
|
||||
[144, 0.08, true, 260, 40],
|
||||
[ 92, 0.10, false, 150, 22],
|
||||
[190, 0.07, true, 310, 35],
|
||||
[116, 0.09, false, 175, 18],
|
||||
[260, 0.07, true, 280, 45],
|
||||
[ 80, 0.11, false, 135, 20],
|
||||
[164, 0.08, true, 230, 32],
|
||||
[104, 0.09, false, 165, 24],
|
||||
[200, 0.07, true, 295, 38],
|
||||
[ 70, 0.10, false, 120, 16],
|
||||
[150, 0.08, true, 245, 30],
|
||||
[ 88, 0.09, false, 140, 21],
|
||||
[210, 0.07, true, 320, 42],
|
||||
[128, 0.08, false, 180, 26],
|
||||
[ 76, 0.10, true, 160, 19],
|
||||
[175, 0.07, true, 290, 36],
|
||||
[ 96, 0.09, false, 155, 23],
|
||||
[220, 0.07, true, 305, 44],
|
||||
[110, 0.08, false, 170, 25],
|
||||
[ 84, 0.09, true, 235, 31],
|
||||
[140, 0.08, false, 185, 27],
|
||||
];
|
||||
|
||||
var n = defs.length;
|
||||
defs.forEach(function (def, i) {
|
||||
var size = def[0], opacity = def[1], isGold = def[2], orbitDur = def[3], spinDur = def[4];
|
||||
|
||||
// Spread evenly across a ~110° fan from top-left, small random jitter
|
||||
var angleDeg = 4 + (i / (n - 1)) * 108 + (Math.random() * 8 - 4);
|
||||
var angle = angleDeg * Math.PI / 180;
|
||||
var radius = (0.15 + (i / n) * 0.7 + Math.random() * 0.15) * maxR * 0.88 + 60;
|
||||
|
||||
// Star center position in parent coords
|
||||
var cx = Math.cos(angle) * radius;
|
||||
var cy = Math.sin(angle) * radius;
|
||||
var left = cx - size / 2;
|
||||
var top = cy - size / 2;
|
||||
|
||||
var orbitDelay = -(Math.random() * orbitDur);
|
||||
var spinDelay = -(Math.random() * spinDur);
|
||||
var color = isGold ? '#c9a84c' : '#c8b4f8';
|
||||
|
||||
// Outer wrapper handles orbit — transform-origin points back to (0,0) corner
|
||||
var wrapper = document.createElement('div');
|
||||
wrapper.style.cssText = [
|
||||
'position:absolute',
|
||||
'left:' + left + 'px',
|
||||
'top:' + top + 'px',
|
||||
'width:' + size + 'px',
|
||||
'height:'+ size + 'px',
|
||||
'opacity:' + opacity,
|
||||
'transform-origin:' + (-left) + 'px ' + (-top) + 'px',
|
||||
'animation:star-orbit ' + orbitDur + 's ' + orbitDelay + 's linear infinite',
|
||||
'pointer-events:none'
|
||||
].join(';');
|
||||
|
||||
// Inner SVG handles spin — transform-origin defaults to 50% 50% (star center)
|
||||
var svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
|
||||
svg.setAttribute('width', size);
|
||||
svg.setAttribute('height', size);
|
||||
svg.setAttribute('viewBox', '0 0 ' + size + ' ' + size);
|
||||
svg.style.cssText = 'display:block;animation:star-spin ' + spinDur + 's ' + spinDelay + 's linear infinite;';
|
||||
|
||||
var poly = document.createElementNS('http://www.w3.org/2000/svg', 'polygon');
|
||||
poly.setAttribute('points', starPoints(size));
|
||||
poly.setAttribute('fill', color);
|
||||
svg.appendChild(poly);
|
||||
wrapper.appendChild(svg);
|
||||
field.appendChild(wrapper);
|
||||
});
|
||||
}());
|
||||
</script>
|
||||
|
||||
{% block extra_scripts %}{% endblock %}
|
||||
|
||||
</body>
|
||||
|
||||
Reference in New Issue
Block a user