diff --git a/hugo.toml b/hugo.toml
index 846b595..4d5b81f 100644
--- a/hugo.toml
+++ b/hugo.toml
@@ -1,4 +1,5 @@
baseURL = 'https://swe-iss.rth1.xyz/'
+relativeURLs = true
locale = 'zh-CN'
title = 'SNOWARE'
copyright = '© 2026 S.A. | SNOWARE'
@@ -10,13 +11,13 @@ copyright = '© 2026 S.A. | SNOWARE'
navLinks = [
{ name = '资源下载', url = '/res/' },
{ name = '我的作品', url = '/softwares/' },
- { name = 'B站空间', url = 'https://bilibili.com/1875249243', external = true },
- { name = 'XAGuarder', url = '/xaguarder/' }
+ { name = 'B站空间', url = 'https://bilibili.com/1875249243', external = true }
]
services = [
{ name = 'Gitea', url = 'http://103.217.186.98:3000/', icon = 'git', desc = '代码仓库' },
{ name = 'Cloudreve', url = 'http://103.217.186.98:5212/home', icon = 'cloud', desc = '云存储' },
- { name = 'Minecraft Server', url = '', icon = 'game', desc = 'QQ 758522192 注明来意' }
+ { name = 'Minecraft Server', url = '', icon = 'game', desc = 'QQ 758522192 注明来意' },
+ { name = '学习与开发团队', url = '', icon = 'team', desc = '加入我们 QQ 758522192' }
]
[markup.goldmark.renderer]
diff --git a/layouts/_default/baseof.html b/layouts/_default/baseof.html
index fa921f3..9c8590c 100644
--- a/layouts/_default/baseof.html
+++ b/layouts/_default/baseof.html
@@ -11,6 +11,7 @@
{{ block "extra_head" . }}{{ end }}
+
{{ partial "nav.html" . }}
{{ block "body" . }}{{ end }}
diff --git a/layouts/index.html b/layouts/index.html
index 2c888e9..52bbf09 100644
--- a/layouts/index.html
+++ b/layouts/index.html
@@ -4,7 +4,13 @@
SNOWARE
- 冷静而温馨,简约而不简单。
+
+
群星璀璨而流星划过天际,曳尾长明而星空黯淡无光,我们如何在瞬间探寻永恒的答案?
+
苦旅漫漫,雾霭蒙蒙,文牒拭作灰烬,家书遥遥无期。
+
雾开雾散,云卷云舒,潮起潮息,光阴流转而你我不凡之辈,即亡没砂石亦必熠熠生辉
+
曲折的进步似为唯一的答案,我心永恒,流光跃过风雨,终会与你同行。
+
S.A. 2026 7.5 @EDT
+
+
diff --git a/static/css/style.css b/static/css/style.css
index c4dfbd8..c2910f4 100644
--- a/static/css/style.css
+++ b/static/css/style.css
@@ -1,9 +1,9 @@
-/* ===== SNOWARE — Minimal Warm Theme ===== */
+/* ===== SNOWARE — Dual Theme ===== */
:root {
- --bg: #1c1b19;
- --bg-soft: #262422;
- --bg-card: #2e2c2a;
+ --bg: #1a1710;
+ --bg-soft: #242016;
+ --bg-card: #2c2818;
--accent: #c8a87a;
--accent-warm: #e8c9a0;
--accent-cool: #8a9a7e;
@@ -16,6 +16,49 @@
--font: 'Segoe UI', system-ui, -apple-system, sans-serif;
--mono: 'Cascadia Code', 'Fira Code', monospace;
--transition: 0.25s ease;
+ --nav-bg: rgba(26,23,16,0.92);
+ --logo-border: rgba(200,168,122,0.3);
+ --logo-bg: rgba(44,40,24,0.5);
+ --btn-hover-bg: rgba(200,168,122,0.08);
+ --service-hover-bg: rgba(200,168,122,0.06);
+ --code-bg: rgba(255,255,255,0.05);
+ --code-inline-bg: rgba(255,255,255,0.06);
+ --warning-bg: rgba(180,60,50,0.06);
+ --warning-border: rgba(180,60,50,0.25);
+ --warning-h: #b84040;
+ --noise-svg: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.03'/%3E%3C/svg%3E");
+ --btn-accent-bg: rgba(200,168,122,0.1);
+ --btn-accent-hover-bg: rgba(200,168,122,0.18);
+ --subject-inline-bg: rgba(255,255,255,0.06);
+}
+
+/* Macaron Cyan theme (dark) */
+[data-theme="cyan"] {
+ --bg: #101820;
+ --bg-soft: #161e2c;
+ --bg-card: #1c2636;
+ --accent: #5cb8e4;
+ --accent-warm: #81d4fa;
+ --accent-cool: #7ec8e3;
+ --text: #c8dce8;
+ --text-muted: #8aa4b8;
+ --text-dim: #5a7a90;
+ --border: rgba(92,184,228,0.12);
+ --border-hover: rgba(92,184,228,0.28);
+ --nav-bg: rgba(16,24,32,0.92);
+ --logo-border: rgba(92,184,228,0.35);
+ --logo-bg: rgba(28,38,54,0.5);
+ --btn-hover-bg: rgba(92,184,228,0.08);
+ --service-hover-bg: rgba(92,184,228,0.06);
+ --code-bg: rgba(255,255,255,0.04);
+ --code-inline-bg: rgba(255,255,255,0.06);
+ --warning-bg: rgba(180,60,50,0.06);
+ --warning-border: rgba(180,60,50,0.25);
+ --warning-h: #c04040;
+ --noise-svg: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.75' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.03'/%3E%3C/svg%3E");
+ --btn-accent-bg: rgba(92,184,228,0.1);
+ --btn-accent-hover-bg: rgba(92,184,228,0.18);
+ --subject-inline-bg: rgba(255,255,255,0.06);
}
*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }
@@ -23,36 +66,56 @@ html { scroll-behavior: smooth; }
body {
font-family: var(--font);
- background: var(--bg);
+ background: transparent;
color: var(--text);
min-height: 100vh;
display: flex;
flex-direction: column;
line-height: 1.7;
- /* Warm linen texture via subtle noise */
- background-image:
- url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.03'/%3E%3C/svg%3E");
- background-repeat: repeat;
- background-size: 256px 256px;
+ transition: color var(--transition);
}
.container { max-width: 920px; margin: 0 auto; padding: 0 24px; }
+/* ===== Theme Toggle ===== */
+.theme-toggle {
+ background: none; border: none; cursor: pointer;
+ padding: 4px; color: var(--text-muted);
+ transition: color var(--transition);
+ display: flex; align-items: center; justify-content: center;
+}
+.theme-toggle:hover { color: var(--accent); }
+[data-theme="warm"] .theme-icon-warm,
+[data-theme="cyan"] .theme-icon-cyan { display: block; }
+[data-theme="warm"] .theme-icon-cyan,
+[data-theme="cyan"] .theme-icon-warm { display: none; }
+
+/* Logo color shift for cyan theme — sepia+hue-rotate for precise warm→cool conversion */
+[data-theme="cyan"] .nav-logo,
+[data-theme="cyan"] .home-logo,
+[data-theme="cyan"] .xag-logo,
+[data-theme="cyan"] .warning-logo,
+[data-theme="cyan"] .error-logo {
+ filter: sepia(0.6) hue-rotate(190deg) saturate(1.5) brightness(1.08);
+}
+
/* ===== Navigation ===== */
.site-nav {
position: sticky; top: 0; z-index: 100;
- background: rgba(28,27,25,0.92);
+ background: var(--nav-bg);
backdrop-filter: blur(14px);
border-bottom: 1px solid var(--border);
padding: 10px 0;
+ transition: background-color var(--transition), border-color var(--transition);
}
.nav-inner { display: flex; align-items: center; justify-content: space-between; }
.nav-brand {
display: flex; align-items: center; gap: 10px;
color: var(--text); font-weight: 700; font-size: 17px; text-decoration: none;
+ transition: color var(--transition);
}
.nav-brand img { border-radius: 50%; }
-.nav-links { display: flex; gap: 22px; }
+.nav-links { display: flex; gap: 22px; align-items: center; }
.nav-links a {
color: var(--text-muted); text-decoration: none; font-size: 13.5px;
transition: color var(--transition); position: relative;
@@ -77,17 +140,68 @@ body {
.home-hero .home-logo {
width: 160px; height: 160px;
border-radius: 50%;
- border: 2px solid rgba(200,168,122,0.3);
- background: rgba(46,44,42,0.5);
+ border: 2px solid var(--logo-border);
+ background: var(--logo-bg);
backdrop-filter: blur(8px);
+ transition: border-color var(--transition), background-color var(--transition);
}
.home-title {
font-size: 44px; font-weight: 700; letter-spacing: 6px;
color: var(--accent-warm);
margin: 0;
+ transition: color var(--transition);
}
-.home-subtitle {
- color: var(--text-muted); font-size: 15px; text-align: center; max-width: 420px;
+/* Poem section */
+.home-poem {
+ text-align: center;
+ max-width: 560px;
+ margin: 0 auto;
+ position: relative;
+}
+.poem-line {
+ color: var(--text-muted);
+ font-size: 14.5px;
+ line-height: 2;
+ opacity: 0;
+ animation: poemFadeIn 1.2s ease forwards;
+ transition: color var(--transition);
+}
+.poem-line.fade-1 { animation-delay: 0.3s; color: var(--accent-warm); font-size: 15px; }
+.poem-line.fade-2 { animation-delay: 0.9s; }
+.poem-line.fade-3 { animation-delay: 1.5s; color: var(--accent-warm); font-size: 15px; }
+.poem-line.fade-4 { animation-delay: 2.1s; }
+.poem-sig {
+ color: var(--text-dim);
+ font-size: 12px;
+ margin-top: 14px;
+ opacity: 0;
+ animation: poemFadeIn 1s ease 2.7s forwards;
+ font-family: var(--mono);
+ letter-spacing: 1px;
+}
+@keyframes poemFadeIn {
+ from { opacity: 0; transform: translateY(10px); }
+ to { opacity: 1; transform: translateY(0); }
+}
+.home-poem::before {
+ content: '';
+ display: block;
+ width: 60px;
+ height: 1px;
+ background: linear-gradient(to right, transparent, var(--accent), transparent);
+ margin: 0 auto 20px auto;
+ opacity: 0;
+ animation: poemFadeIn 0.8s ease 0.1s forwards;
+}
+.home-poem::after {
+ content: '';
+ display: block;
+ width: 60px;
+ height: 1px;
+ background: linear-gradient(to right, transparent, var(--accent), transparent);
+ margin: 20px auto 0 auto;
+ opacity: 0;
+ animation: poemFadeIn 0.8s ease 3.2s forwards;
}
/* Homepage nav buttons */
@@ -100,7 +214,7 @@ body {
}
.home-btn:hover {
border-color: var(--border-hover);
- background: rgba(200,168,122,0.08);
+ background: var(--btn-hover-bg);
transform: translateY(-1px);
}
@@ -112,10 +226,11 @@ body {
.home-services h2 {
font-size: 15px; color: var(--text-dim); font-weight: 500;
letter-spacing: 2px; text-transform: uppercase; margin-bottom: 20px;
+ transition: color var(--transition);
}
.services-grid {
- display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px;
- max-width: 600px; margin: 0 auto;
+ display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px;
+ max-width: 720px; margin: 0 auto;
}
.service-card {
padding: 20px 16px; border-radius: var(--radius);
@@ -126,7 +241,7 @@ body {
}
.service-card:hover {
border-color: var(--border-hover);
- background: rgba(200,168,122,0.06);
+ background: var(--service-hover-bg);
}
.service-icon {
display: flex; justify-content: center; margin-bottom: 10px;
@@ -144,6 +259,7 @@ body {
.page-hero h1 {
font-size: 36px; font-weight: 700;
color: var(--accent-warm); margin-bottom: 6px;
+ transition: color var(--transition);
}
.page-hero .subtitle { color: var(--text-muted); font-size: 16px; }
@@ -160,10 +276,10 @@ body {
.btn-primary { background: var(--accent); color: var(--bg); border-color: var(--accent); }
.btn-primary:hover { background: var(--accent-warm); }
.btn-accent {
- background: rgba(200,168,122,0.1); color: var(--accent);
+ background: var(--btn-accent-bg); color: var(--accent);
border-color: var(--border-hover);
}
-.btn-accent:hover { background: rgba(200,168,122,0.18); }
+.btn-accent:hover { background: var(--btn-accent-hover-bg); }
.btn-outline { background: transparent; color: var(--text-muted); border-color: var(--border); }
.btn-outline:hover { border-color: var(--text-muted); color: var(--text); }
.btn-lg { padding: 13px 30px; font-size: 16px; }
@@ -218,7 +334,7 @@ body {
.subject-card h3 { font-size: 17px; }
.subject-pw { font-size: 12.5px; color: var(--text-muted); }
.subject-pw code {
- background: rgba(255,255,255,0.06); padding: 2px 7px; border-radius: 4px;
+ background: var(--subject-inline-bg); padding: 2px 7px; border-radius: 4px;
color: var(--color); font-family: var(--mono);
}
@@ -263,13 +379,13 @@ body {
}
.sw-section h2 { color: var(--accent-warm); margin-bottom: 10px; font-size: 20px; }
.sw-code {
- background: rgba(255,255,255,0.05); padding: 10px 16px; border-radius: 6px;
+ background: var(--code-bg); padding: 10px 16px; border-radius: 6px;
font-family: var(--mono); font-size: 13px; overflow-x: auto; color: var(--text);
}
.usage-list { display: flex; flex-direction: column; gap: 10px; }
.usage-item { display: flex; gap: 10px; align-items: center; }
.usage-item code {
- background: rgba(255,255,255,0.05); padding: 5px 10px; border-radius: 5px;
+ background: var(--code-inline-bg); padding: 5px 10px; border-radius: 5px;
font-family: var(--mono); font-size: 12.5px; white-space: nowrap;
}
.usage-item span { color: var(--text-muted); font-size: 13px; }
@@ -297,11 +413,12 @@ body {
}
.warning-content {
text-align: center; padding: 50px;
- background: rgba(180,60,50,0.06); border: 2px solid rgba(180,60,50,0.25);
+ background: var(--warning-bg); border: 2px solid var(--warning-border);
border-radius: var(--radius); max-width: 480px;
+ transition: background-color var(--transition), border-color var(--transition);
}
.warning-logo { border-radius: 50%; margin-bottom: 18px; }
-.warning-content h1 { color: #b84040; font-size: 26px; margin-bottom: 14px; }
+.warning-content h1 { color: var(--warning-h); font-size: 26px; margin-bottom: 14px; }
.warning-text { font-size: 16px; color: var(--text); margin-bottom: 6px; }
.warning-sub { color: var(--text-muted); font-size: 13px; margin-bottom: 22px; }
@@ -318,6 +435,7 @@ body {
text-align: center; padding: 22px;
border-top: 1px solid var(--border);
color: var(--text-dim); font-size: 12.5px; margin-top: auto;
+ transition: border-color var(--transition), color var(--transition);
}
/* ===== Responsive ===== */
@@ -326,13 +444,14 @@ body {
.nav-links { gap: 14px; }
.home-title { font-size: 30px; letter-spacing: 4px; }
.home-hero .home-logo { width: 120px; height: 120px; }
- .services-grid { grid-template-columns: 1fr; max-width: 320px; }
+ .services-grid { grid-template-columns: 1fr 1fr; max-width: 360px; }
.page-hero h1 { font-size: 26px; }
.project-grid { grid-template-columns: 1fr; }
.filelist-grid { grid-template-columns: repeat(2, 1fr); }
.res-features, .sw-features { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 480px) {
+ .services-grid { grid-template-columns: 1fr; max-width: 280px; }
.filelist-grid { grid-template-columns: 1fr; }
.res-features, .sw-features { grid-template-columns: 1fr; }
.sw-links { flex-direction: column; align-items: center; }
diff --git a/static/js/nature-bg.js b/static/js/nature-bg.js
new file mode 100644
index 0000000..60a0182
--- /dev/null
+++ b/static/js/nature-bg.js
@@ -0,0 +1,216 @@
+// SNOWARE — Dynamic Nature Background (Stars + Mountains + Meteors)
+(function(){
+ var canvas = document.createElement('canvas');
+ canvas.id = 'nature-bg';
+ canvas.style.cssText = 'position:fixed;top:0;left:0;width:100%;height:100%;z-index:-1;pointer-events:none;';
+ document.body.prepend(canvas);
+ var ctx = canvas.getContext('2d');
+ var stars = [], shootingStars = [];
+ var W, H;
+ var lastShooting = 0;
+
+ function resize(){
+ W = canvas.width = window.innerWidth;
+ H = canvas.height = window.innerHeight;
+ initStars();
+ }
+
+ function initStars(){
+ stars = [];
+ var count = Math.floor(W * H / 2800);
+ for(var i = 0; i < count; i++){
+ stars.push({
+ x: Math.random() * W,
+ y: Math.random() * H * 0.55,
+ r: Math.random() * 1.5 + 0.3,
+ a: Math.random() * 0.6 + 0.2,
+ speed: Math.random() * 0.008 + 0.002,
+ phase: Math.random() * Math.PI * 2
+ });
+ }
+ }
+
+ function addShootingStar(){
+ shootingStars.push({
+ x: Math.random() * W * 0.6 + W * 0.1,
+ y: Math.random() * H * 0.25,
+ len: Math.random() * 120 + 60,
+ speed: Math.random() * 6 + 4,
+ angle: Math.random() * 0.25 + 0.15,
+ a: 1,
+ life: 0,
+ sparks: []
+ });
+ }
+
+ function getTheme(){
+ return document.documentElement.getAttribute('data-theme') || 'warm';
+ }
+
+ function getColors(){
+ var t = getTheme();
+ if(t === 'cyan'){
+ return {
+ sky1: '#0a1525', sky2: '#101828', sky3: '#182436',
+ star: '#c8dff0', starBright: '#81d4fa',
+ mtn1: '#0e1826', mtn2: '#162230', mtn3: '#1e2e40',
+ mtnLine: 'rgba(92,184,228,0.12)', mtnSnow: 'rgba(200,220,240,0.08)',
+ shoot: '#81d4fa', shootGlow: 'rgba(129,212,250,0.2)'
+ };
+ }
+ return {
+ sky1: '#0a0c08', sky2: '#141210', sky3: '#1a1710',
+ star: '#d4c0a0', starBright: '#e8c9a0',
+ mtn1: '#0e0c08', mtn2: '#181610', mtn3: '#242014',
+ mtnLine: 'rgba(200,168,122,0.08)', mtnSnow: 'rgba(232,201,160,0.06)',
+ shoot: '#e8c9a0', shootGlow: 'rgba(232,201,160,0.15)'
+ };
+ }
+
+ function drawSky(c){
+ var g = ctx.createLinearGradient(0, 0, 0, H);
+ g.addColorStop(0, c.sky1);
+ g.addColorStop(0.35, c.sky2);
+ g.addColorStop(1, c.sky3);
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, W, H);
+ }
+
+ function drawStars(c, t){
+ for(var i = 0; i < stars.length; i++){
+ var s = stars[i];
+ var twinkle = Math.sin(t * s.speed + s.phase) * 0.3 + 0.7;
+ var alpha = s.a * twinkle;
+ ctx.beginPath();
+ ctx.arc(s.x, s.y, s.r, 0, Math.PI * 2);
+ ctx.fillStyle = s.r > 1.2 ? c.starBright : c.star;
+ ctx.globalAlpha = alpha;
+ ctx.fill();
+ }
+ ctx.globalAlpha = 1;
+ }
+
+ function drawShootingStars(c, t){
+ // More frequent meteors: every 3-7 seconds
+ if(t - lastShooting > 3000 + Math.random() * 4000){
+ addShootingStar();
+ lastShooting = t;
+ }
+ for(var i = shootingStars.length - 1; i >= 0; i--){
+ var s = shootingStars[i];
+ s.life += 1;
+ s.x += s.speed;
+ s.y += s.speed * s.angle;
+ s.a -= 0.008;
+ if(s.a <= 0){ shootingStars.splice(i, 1); continue; }
+
+ // Head glow
+ ctx.save();
+ ctx.globalAlpha = s.a * 0.6;
+ var headGlow = ctx.createRadialGradient(s.x, s.y, 0, s.x, s.y, 8);
+ headGlow.addColorStop(0, c.shoot);
+ headGlow.addColorStop(1, 'transparent');
+ ctx.fillStyle = headGlow;
+ ctx.beginPath();
+ ctx.arc(s.x, s.y, 8, 0, Math.PI * 2);
+ ctx.fill();
+
+ // Main trail
+ ctx.globalAlpha = s.a;
+ ctx.strokeStyle = c.shoot;
+ ctx.lineWidth = 1.8;
+ ctx.lineCap = 'round';
+ ctx.beginPath();
+ ctx.moveTo(s.x, s.y);
+ var tailX = s.x - s.len * Math.cos(s.angle);
+ var tailY = s.y - s.len * Math.sin(s.angle);
+ ctx.lineTo(tailX, tailY);
+ ctx.stroke();
+
+ // Wide glow trail
+ ctx.globalAlpha = s.a * 0.25;
+ ctx.lineWidth = 6;
+ ctx.strokeStyle = c.shoot;
+ ctx.beginPath();
+ ctx.moveTo(s.x, s.y);
+ ctx.lineTo(s.x - s.len * 0.5 * Math.cos(s.angle), s.y - s.len * 0.5 * Math.sin(s.angle));
+ ctx.stroke();
+
+ // Secondary thin glow trail
+ ctx.globalAlpha = s.a * 0.12;
+ ctx.lineWidth = 12;
+ ctx.strokeStyle = c.shootGlow;
+ ctx.beginPath();
+ ctx.moveTo(s.x, s.y);
+ ctx.lineTo(s.x - s.len * 0.3 * Math.cos(s.angle), s.y - s.len * 0.3 * Math.sin(s.angle));
+ ctx.stroke();
+
+ ctx.restore();
+ }
+ }
+
+ function drawMountainLayer(yBase, height, color, lineColor, snowPatches, seed){
+ ctx.beginPath();
+ ctx.moveTo(0, yBase);
+ var step = 3;
+ for(var x = 0; x <= W; x += step){
+ var h = 0;
+ h += Math.sin(x * 0.003 + seed) * height * 0.5;
+ h += Math.sin(x * 0.007 + seed * 2) * height * 0.3;
+ h += Math.sin(x * 0.015 + seed * 3) * height * 0.15;
+ ctx.lineTo(x, yBase - Math.abs(h));
+ }
+ ctx.lineTo(W, H);
+ ctx.lineTo(0, H);
+ ctx.closePath();
+ ctx.fillStyle = color;
+ ctx.fill();
+ // subtle outline
+ ctx.strokeStyle = lineColor;
+ ctx.lineWidth = 1;
+ ctx.stroke();
+ // snow patches on peaks
+ if(snowPatches > 0){
+ ctx.globalAlpha = snowPatches;
+ ctx.fillStyle = lineColor;
+ for(var x = 0; x <= W; x += step){
+ var h = 0;
+ h += Math.sin(x * 0.003 + seed) * height * 0.5;
+ h += Math.sin(x * 0.007 + seed * 2) * height * 0.3;
+ h += Math.sin(x * 0.015 + seed * 3) * height * 0.15;
+ var peakY = yBase - Math.abs(h);
+ if(Math.abs(h) > height * 0.6){
+ ctx.beginPath();
+ ctx.arc(x, peakY + 2, 2 + Math.random(), 0, Math.PI * 2);
+ ctx.fill();
+ }
+ }
+ ctx.globalAlpha = 1;
+ }
+ }
+
+ function drawMountains(c){
+ // far layer
+ drawMountainLayer(H * 0.65, H * 0.18, c.mtn1, c.mtnLine, c.mtnSnow, 1.2);
+ // mid layer
+ drawMountainLayer(H * 0.72, H * 0.14, c.mtn2, c.mtnLine, 0, 3.7);
+ // near layer
+ drawMountainLayer(H * 0.82, H * 0.10, c.mtn3, c.mtnLine, 0, 7.1);
+ }
+
+ var startTime = performance.now();
+ function render(){
+ var t = (performance.now() - startTime) / 1000;
+ var c = getColors();
+ ctx.clearRect(0, 0, W, H);
+ drawSky(c);
+ drawStars(c, t);
+ drawShootingStars(c, performance.now());
+ drawMountains(c);
+ requestAnimationFrame(render);
+ }
+
+ resize();
+ window.addEventListener('resize', resize);
+ render();
+})();
diff --git a/static/logo.svg b/static/logo.svg
index 356bef0..4b675aa 100644
--- a/static/logo.svg
+++ b/static/logo.svg
@@ -1,35 +1,78 @@
-