3 Commits

27 changed files with 156 additions and 69 deletions

View File

@ -4,9 +4,10 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<title>dangrubb.net</title> <title>dangrubb.net</title>
<link rel="icon" href="/src/img/favicon.ico" type="image/x-icon">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" href="/src/img/favicon.ico" type="image/x-icon"> <link rel="icon" href="/favicon.ico" sizes="48x48">
<link rel="icon" href="/favicon.svg" type="image/svg+xml">
<link rel="apple-touch-icon" href="/apple-touch-icon.png">
<link rel="stylesheet" href="./style.css"> <link rel="stylesheet" href="./style.css">
</head> </head>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.4 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

@ -1,7 +1,9 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<link rel="icon" href="assets/img/favicon.ico" type="image/x-icon"> <link rel="icon" href="/favicon.ico" sizes="48x48">
<link rel="icon" href="/favicon.svg" type="image/svg+xml">
<link rel="apple-touch-icon" href="/apple-touch-icon.png">
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />

View File

@ -1,7 +1,9 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<link rel="icon" href="assets/img/favicon.ico" type="image/x-icon"> <link rel="icon" href="/favicon.ico" sizes="48x48">
<link rel="icon" href="/favicon.svg" type="image/svg+xml">
<link rel="apple-touch-icon" href="/apple-touch-icon.png">
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />

View File

@ -4,9 +4,10 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<title>dangrubb.net</title> <title>dangrubb.net</title>
<link rel="icon" href="/src/img/favicon.ico" type="image/x-icon">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" href="/src/img/favicon.ico" type="image/x-icon"> <link rel="icon" href="/favicon.ico" sizes="48x48">
<link rel="icon" href="/favicon.svg" type="image/svg+xml">
<link rel="apple-touch-icon" href="/apple-touch-icon.png">
<link rel="stylesheet" href="./style.css"> <link rel="stylesheet" href="./style.css">
</head> </head>

BIN
public/apple-touch-icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.4 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

@ -1,7 +1,9 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<link rel="icon" href="assets/img/favicon.ico" type="image/x-icon"> <link rel="icon" href="/favicon.ico" sizes="48x48">
<link rel="icon" href="/favicon.svg" type="image/svg+xml">
<link rel="apple-touch-icon" href="/apple-touch-icon.png">
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />

View File

@ -1,7 +1,9 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<link rel="icon" href="assets/img/favicon.ico" type="image/x-icon"> <link rel="icon" href="/favicon.ico" sizes="48x48">
<link rel="icon" href="/favicon.svg" type="image/svg+xml">
<link rel="apple-touch-icon" href="/apple-touch-icon.png">
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />

Binary file not shown.

Before

Width:  |  Height:  |  Size: 655 B

After

Width:  |  Height:  |  Size: 15 KiB

View File

@ -1,9 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 128 128"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="-8 -8 460 460">
<path d="M50.4 78.5a75.1 75.1 0 0 0-28.5 6.9l24.2-65.7c.7-2 1.9-3.2 3.4-3.2h29c1.5 0 2.7 1.2 3.4 3.2l24.2 65.7s-11.6-7-28.5-7L67 45.5c-.4-1.7-1.6-2.8-2.9-2.8-1.3 0-2.5 1.1-2.9 2.7L50.4 78.5Zm-1.1 28.2Zm-4.2-20.2c-2 6.6-.6 15.8 4.2 20.2a17.5 17.5 0 0 1 .2-.7 5.5 5.5 0 0 1 5.7-4.5c2.8.1 4.3 1.5 4.7 4.7.2 1.1.2 2.3.2 3.5v.4c0 2.7.7 5.2 2.2 7.4a13 13 0 0 0 5.7 4.9v-.3l-.2-.3c-1.8-5.6-.5-9.5 4.4-12.8l1.5-1a73 73 0 0 0 3.2-2.2 16 16 0 0 0 6.8-11.4c.3-2 .1-4-.6-6l-.8.6-1.6 1a37 37 0 0 1-22.4 2.7c-5-.7-9.7-2-13.2-6.2Z" /> <path fill="#EC9770" stroke="#EC9770" stroke-width="14" stroke-linejoin="miter" stroke-miterlimit="6" d="M5.59 376.00 L72.55 277.00 L105.59 277.00 L53.36 349.85 L70.87 349.85 C92.57 349.85 115.47 349.34 134.74 340.19 C154.00 331.04 169.62 313.53 180.23 294.15 C190.84 274.77 196.44 253.52 196.03 231.92 C195.62 210.31 189.19 188.34 178.01 169.66 C166.83 150.99 150.90 135.61 132.45 123.77 C113.99 111.93 93.02 105.30 70.92 105.30 L25.89 105.30 L6.10 80.00 L70.57 80.00 C96.81 80.00 122.87 86.78 145.14 100.38 C167.40 113.98 185.87 132.97 198.54 155.81 C211.21 178.64 218.08 205.34 218.28 231.30 C218.49 257.27 212.03 282.51 199.70 305.82 C187.36 329.13 169.17 350.52 146.44 362.36 C123.71 374.20 96.46 376.00 70.41 376.00 L5.59 376.00 Z M438.41 376.00 L371.45 277.00 L338.41 277.00 L390.64 349.85 L373.13 349.85 C351.43 349.85 328.53 349.34 309.26 340.19 C290.00 331.04 274.38 313.53 263.77 294.15 C253.16 274.77 247.56 253.52 247.97 231.92 C248.38 210.31 254.81 188.34 265.99 169.66 C277.17 150.99 293.10 135.61 311.55 123.77 C330.01 111.93 350.98 105.30 373.08 105.30 L418.11 105.30 L437.90 80.00 L373.43 80.00 C347.19 80.00 321.13 86.78 298.86 100.38 C276.60 113.98 258.13 132.97 245.46 155.81 C232.79 178.64 225.92 205.34 225.72 231.30 C225.51 257.27 231.97 282.51 244.30 305.82 C256.64 329.13 274.83 350.52 297.56 362.36 C320.29 374.20 347.54 376.00 373.59 376.00 L438.41 376.00 Z"/>
<style>
path { fill: #000; }
@media (prefers-color-scheme: dark) {
path { fill: #FFF; }
}
</style>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 749 B

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -4,7 +4,9 @@
<meta charset="UTF-8"> <meta charset="UTF-8">
<title>DGDN - Darnea | dangrubb.net</title> <title>DGDN - Darnea | dangrubb.net</title>
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" href="/src/img/favicon.ico" type="image/x-icon"> <link rel="icon" href="/favicon.ico" sizes="48x48">
<link rel="icon" href="/favicon.svg" type="image/svg+xml">
<link rel="apple-touch-icon" href="/apple-touch-icon.png">
<link rel="stylesheet" href="../../music.css"> <link rel="stylesheet" href="../../music.css">
<link rel="stylesheet" href="./player.css"> <link rel="stylesheet" href="./player.css">
</head> </head>

View File

@ -9,7 +9,7 @@
gap: 30px; gap: 30px;
margin-bottom: 40px; margin-bottom: 40px;
padding: 30px; padding: 30px;
background: rgba(107, 225, 233, 0.05); background: rgb(var(--accent-rgb) / 0.05);
border-radius: 8px; border-radius: 8px;
align-items: center; align-items: center;
} }
@ -23,18 +23,18 @@
.album-info h2 { .album-info h2 {
margin: 0 0 5px 0; margin: 0 0 5px 0;
font-size: 2rem; font-size: 2rem;
color: #9d9aa4; color: var(--text);
} }
.album-info .artist-name { .album-info .artist-name {
margin: 0 0 5px 0; margin: 0 0 5px 0;
color: #6be1e9; color: var(--accent);
font-size: 1.1rem; font-size: 1.1rem;
} }
.album-info .album-desc { .album-info .album-desc {
margin: 0; margin: 0;
color: #6be1e9; color: var(--accent);
font-size: 0.9rem; font-size: 0.9rem;
font-style: italic; font-style: italic;
} }
@ -43,8 +43,8 @@
.now-playing { .now-playing {
text-align: center; text-align: center;
padding: 20px; padding: 20px;
background: rgba(107, 225, 233, 0.1); background: rgb(var(--accent-rgb) / 0.1);
border: 1px solid rgba(107, 225, 233, 0.3); border: 1px solid rgb(var(--accent-rgb) / 0.3);
border-radius: 6px; border-radius: 6px;
margin-bottom: 20px; margin-bottom: 20px;
min-height: 60px; min-height: 60px;
@ -55,11 +55,11 @@
.now-playing p { .now-playing p {
margin: 0; margin: 0;
color: #9d9aa4; color: var(--text);
} }
.now-playing.playing p { .now-playing.playing p {
color: #6be1e9; color: var(--accent);
font-weight: bold; font-weight: bold;
} }
@ -67,7 +67,7 @@
#audio-player { #audio-player {
width: 100%; width: 100%;
margin-bottom: 30px; margin-bottom: 30px;
accent-color: #6be1e9; accent-color: var(--accent);
} }
/* Tracklist */ /* Tracklist */
@ -78,7 +78,7 @@
.tracklist h3 { .tracklist h3 {
margin: 0 0 20px 0; margin: 0 0 20px 0;
font-size: 1.3rem; font-size: 1.3rem;
color: #9d9aa4; color: var(--text);
} }
.tracklist ol { .tracklist ol {
@ -90,29 +90,29 @@
.tracklist li { .tracklist li {
padding: 12px; padding: 12px;
margin-bottom: 8px; margin-bottom: 8px;
background: rgba(157, 154, 164, 0.05); background: rgb(var(--text-rgb) / 0.05);
border: 1px solid rgba(107, 225, 233, 0.2); border: 1px solid rgb(var(--accent-rgb) / 0.2);
border-radius: 4px; border-radius: 4px;
cursor: pointer; cursor: pointer;
transition: all 0.2s ease; transition: all 0.2s ease;
color: #9d9aa4; color: var(--text);
} }
.tracklist li:hover { .tracklist li:hover {
background: rgba(107, 225, 233, 0.1); background: rgb(var(--accent-rgb) / 0.1);
border-color: rgba(107, 225, 233, 0.5); border-color: rgb(var(--accent-rgb) / 0.5);
} }
.tracklist li.active { .tracklist li.active {
background: rgba(107, 225, 233, 0.2); background: rgb(var(--accent-rgb) / 0.2);
border-color: #6be1e9; border-color: var(--accent);
color: #6be1e9; color: var(--accent);
font-weight: bold; font-weight: bold;
} }
.track-duration { .track-duration {
float: right; float: right;
color: #6be1e9; color: var(--accent);
font-size: 0.9rem; font-size: 0.9rem;
} }

View File

@ -4,7 +4,9 @@
<meta charset="UTF-8"> <meta charset="UTF-8">
<title>Darnea - dangrubb.net</title> <title>Darnea - dangrubb.net</title>
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" href="/src/img/favicon.ico" type="image/x-icon"> <link rel="icon" href="/favicon.ico" sizes="48x48">
<link rel="icon" href="/favicon.svg" type="image/svg+xml">
<link rel="apple-touch-icon" href="/apple-touch-icon.png">
<link rel="stylesheet" href="../music.css"> <link rel="stylesheet" href="../music.css">
</head> </head>
<body> <body>

View File

@ -4,7 +4,9 @@
<meta charset="UTF-8"> <meta charset="UTF-8">
<title>dangrubb.net Music</title> <title>dangrubb.net Music</title>
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" href="/src/img/favicon.ico" type="image/x-icon"> <link rel="icon" href="/favicon.ico" sizes="48x48">
<link rel="icon" href="/favicon.svg" type="image/svg+xml">
<link rel="apple-touch-icon" href="/apple-touch-icon.png">
<link rel="stylesheet" href="./music.css"> <link rel="stylesheet" href="./music.css">
</head> </head>
<body> <body>

View File

@ -1,9 +1,38 @@
/* --- THEME ---
Dark is the default; a light palette switches on automatically with the visitor's system setting. */
:root {
color-scheme: dark light;
--bg: #0d0a14;
--text: #9d9aa4;
--accent: #6be1e9;
--text-rgb: 157 154 164;
--accent-rgb: 107 225 233;
--warn: #ffff00;
--panel-a: rgb(13 10 20 / 0.6);
--panel-b: rgb(50 30 80 / 0.3);
--shadow: rgb(0 0 0 / 0.4);
}
@media (prefers-color-scheme: light) {
:root {
--bg: #faf6f2;
--text: #4a4553;
--accent: #0a727c;
--text-rgb: 74 69 83;
--accent-rgb: 10 114 124;
--warn: #8a5a00;
--panel-a: rgb(255 255 255 / 0.7);
--panel-b: rgb(250 214 190 / 0.35);
--shadow: rgb(74 69 83 / 0.18);
}
}
/* --- BASE STYLES (Merged from style.css) --- */ /* --- BASE STYLES (Merged from style.css) --- */
body { body {
background: #0d0a14; background: var(--bg);
padding: 40px 20px; padding: 40px 20px;
font-family: ui-monospace, "Cascadia Code", "Source Code Pro", Menlo, Consolas, "DejaVu Sans Mono", monospace; font-family: ui-monospace, "Cascadia Code", "Source Code Pro", Menlo, Consolas, "DejaVu Sans Mono", monospace;
color: #9d9aa4; color: var(--text);
/* Fixed the no-scroll issue here: */ /* Fixed the no-scroll issue here: */
min-height: 100vh; min-height: 100vh;
margin: 0; margin: 0;
@ -14,7 +43,7 @@ body {
} }
a { a {
color: #6be1e9; color: var(--accent);
text-decoration: none; text-decoration: none;
} }
@ -35,19 +64,19 @@ a:visited {
.music-header { .music-header {
text-align: center; text-align: center;
margin-bottom: 50px; margin-bottom: 50px;
border-bottom: 2px solid rgba(107, 225, 233, 0.3); border-bottom: 2px solid rgb(var(--accent-rgb) / 0.3);
padding-bottom: 20px; padding-bottom: 20px;
} }
.music-header h1 { .music-header h1 {
margin: 0; margin: 0;
font-size: 2rem; font-size: 2rem;
color: #9d9aa4; color: var(--text);
font-weight: bold; font-weight: bold;
} }
.music-header h1 a { .music-header h1 a {
color: #6be1e9; color: var(--accent);
} }
/* Artists/Albums Grid */ /* Artists/Albums Grid */
@ -63,16 +92,16 @@ a:visited {
.album-card { .album-card {
text-align: center; text-align: center;
padding: 20px; padding: 20px;
background: rgba(157, 154, 164, 0.05); background: rgb(var(--text-rgb) / 0.05);
border: 1px solid rgba(107, 225, 233, 0.2); border: 1px solid rgb(var(--accent-rgb) / 0.2);
border-radius: 8px; border-radius: 8px;
transition: all 0.3s ease; transition: all 0.3s ease;
} }
.artist-card:hover, .artist-card:hover,
.album-card:hover { .album-card:hover {
background: rgba(107, 225, 233, 0.1); background: rgb(var(--accent-rgb) / 0.1);
border-color: rgba(107, 225, 233, 0.5); border-color: rgb(var(--accent-rgb) / 0.5);
transform: translateY(-4px); transform: translateY(-4px);
} }
@ -86,12 +115,12 @@ a:visited {
.album-card h3 { .album-card h3 {
margin: 10px 0; margin: 10px 0;
font-size: 1.3rem; font-size: 1.3rem;
color: #9d9aa4; color: var(--text);
} }
.artist-meta, .artist-meta,
.album-meta { .album-meta {
color: #6be1e9; color: var(--accent);
font-size: 0.9rem; font-size: 0.9rem;
margin: 0; margin: 0;
} }
@ -101,7 +130,7 @@ a:visited {
text-align: center; text-align: center;
margin: 40px 0; margin: 40px 0;
padding: 40px 20px; padding: 40px 20px;
background: rgba(107, 225, 233, 0.05); background: rgb(var(--accent-rgb) / 0.05);
border-radius: 8px; border-radius: 8px;
} }
@ -113,7 +142,7 @@ a:visited {
.artist-detail h2 { .artist-detail h2 {
margin: 0; margin: 0;
font-size: 2.5rem; font-size: 2.5rem;
color: #9d9aa4; color: var(--text);
} }
/* Footer / Bottom Nav */ /* Footer / Bottom Nav */
@ -121,7 +150,7 @@ a:visited {
text-align: center; text-align: center;
margin-top: 60px; margin-top: 60px;
padding: 20px 0; padding: 20px 0;
border-top: 2px solid rgba(107, 225, 233, 0.3); border-top: 2px solid rgb(var(--accent-rgb) / 0.3);
} }
.bottom-nav { .bottom-nav {
@ -160,7 +189,7 @@ a:visited {
.announcement { .announcement {
margin: 20px auto; margin: 20px auto;
display: block; display: block;
border: 1px solid #ffff00; border: 1px solid var(--warn);
padding: 10px 15px; padding: 10px 15px;
border-radius: 3px; border-radius: 3px;
text-align: center; text-align: center;
@ -168,7 +197,7 @@ a:visited {
} }
.announcement a { .announcement a {
color: #ffff00; color: var(--warn);
font-weight: bold; font-weight: bold;
} }
@ -181,11 +210,11 @@ a:visited {
} }
.blog-preview { .blog-preview {
border: 1px solid rgba(155, 169, 180, 0.3); border: 1px solid rgb(var(--text-rgb) / 0.3);
border-radius: 4px; border-radius: 4px;
padding: 15px; padding: 15px;
background: linear-gradient(135deg, rgba(13, 10, 20, 0.6), rgba(50, 30, 80, 0.3)); background: linear-gradient(135deg, var(--panel-a), var(--panel-b));
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4); box-shadow: 0 4px 12px var(--shadow);
} }
/* --- RESPONSIVE MEDIA QUERIES --- */ /* --- RESPONSIVE MEDIA QUERIES --- */

View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 444 444">
<path fill="#090B11" d="M5.59 376.00 L72.55 277.00 L105.59 277.00 L53.36 349.85 L70.87 349.85 C92.57 349.85 115.47 349.34 134.74 340.19 C154.00 331.04 169.62 313.53 180.23 294.15 C190.84 274.77 196.44 253.52 196.03 231.92 C195.62 210.31 189.19 188.34 178.01 169.66 C166.83 150.99 150.90 135.61 132.45 123.77 C113.99 111.93 93.02 105.30 70.92 105.30 L25.89 105.30 L6.10 80.00 L70.57 80.00 C96.81 80.00 122.87 86.78 145.14 100.38 C167.40 113.98 185.87 132.97 198.54 155.81 C211.21 178.64 218.08 205.34 218.28 231.30 C218.49 257.27 212.03 282.51 199.70 305.82 C187.36 329.13 169.17 350.52 146.44 362.36 C123.71 374.20 96.46 376.00 70.41 376.00 L5.59 376.00 Z M438.41 376.00 L371.45 277.00 L338.41 277.00 L390.64 349.85 L373.13 349.85 C351.43 349.85 328.53 349.34 309.26 340.19 C290.00 331.04 274.38 313.53 263.77 294.15 C253.16 274.77 247.56 253.52 247.97 231.92 C248.38 210.31 254.81 188.34 265.99 169.66 C277.17 150.99 293.10 135.61 311.55 123.77 C330.01 111.93 350.98 105.30 373.08 105.30 L418.11 105.30 L437.90 80.00 L373.43 80.00 C347.19 80.00 321.13 86.78 298.86 100.38 C276.60 113.98 258.13 132.97 245.46 155.81 C232.79 178.64 225.92 205.34 225.72 231.30 C225.51 257.27 231.97 282.51 244.30 305.82 C256.64 329.13 274.83 350.52 297.56 362.36 C320.29 374.20 347.54 376.00 373.59 376.00 L438.41 376.00 Z"/>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 444 444">
<path fill="#FFFFFF" d="M5.59 376.00 L72.55 277.00 L105.59 277.00 L53.36 349.85 L70.87 349.85 C92.57 349.85 115.47 349.34 134.74 340.19 C154.00 331.04 169.62 313.53 180.23 294.15 C190.84 274.77 196.44 253.52 196.03 231.92 C195.62 210.31 189.19 188.34 178.01 169.66 C166.83 150.99 150.90 135.61 132.45 123.77 C113.99 111.93 93.02 105.30 70.92 105.30 L25.89 105.30 L6.10 80.00 L70.57 80.00 C96.81 80.00 122.87 86.78 145.14 100.38 C167.40 113.98 185.87 132.97 198.54 155.81 C211.21 178.64 218.08 205.34 218.28 231.30 C218.49 257.27 212.03 282.51 199.70 305.82 C187.36 329.13 169.17 350.52 146.44 362.36 C123.71 374.20 96.46 376.00 70.41 376.00 L5.59 376.00 Z M438.41 376.00 L371.45 277.00 L338.41 277.00 L390.64 349.85 L373.13 349.85 C351.43 349.85 328.53 349.34 309.26 340.19 C290.00 331.04 274.38 313.53 263.77 294.15 C253.16 274.77 247.56 253.52 247.97 231.92 C248.38 210.31 254.81 188.34 265.99 169.66 C277.17 150.99 293.10 135.61 311.55 123.77 C330.01 111.93 350.98 105.30 373.08 105.30 L418.11 105.30 L437.90 80.00 L373.43 80.00 C347.19 80.00 321.13 86.78 298.86 100.38 C276.60 113.98 258.13 132.97 245.46 155.81 C232.79 178.64 225.92 205.34 225.72 231.30 C225.51 257.27 231.97 282.51 244.30 305.82 C256.64 329.13 274.83 350.52 297.56 362.36 C320.29 374.20 347.54 376.00 373.59 376.00 L438.41 376.00 Z"/>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.4 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.4 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

@ -8,7 +8,9 @@ const { title } = Astro.props;
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>{title}</title> <title>{title}</title>
<link rel="icon" href="/src/img/favicon.ico" type="image/x-icon" /> <link rel="icon" href="/favicon.ico" sizes="48x48">
<link rel="icon" href="/favicon.svg" type="image/svg+xml">
<link rel="apple-touch-icon" href="/apple-touch-icon.png">
</head> </head>
<body> <body>
<slot /> <slot />

View File

@ -8,7 +8,9 @@ const { title } = Astro.props;
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>{title}</title> <title>{title}</title>
<link rel="icon" href="/src/img/favicon.ico" type="image/x-icon" /> <link rel="icon" href="/favicon.ico" sizes="48x48">
<link rel="icon" href="/favicon.svg" type="image/svg+xml">
<link rel="apple-touch-icon" href="/apple-touch-icon.png">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/boxicons@latest/css/boxicons.min.css" /> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/boxicons@latest/css/boxicons.min.css" />
</head> </head>
<body> <body>

View File

@ -8,7 +8,9 @@ const { title } = Astro.props;
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>{title}</title> <title>{title}</title>
<link rel="icon" href="/src/img/favicon.ico" type="image/x-icon" /> <link rel="icon" href="/favicon.ico" sizes="48x48">
<link rel="icon" href="/favicon.svg" type="image/svg+xml">
<link rel="apple-touch-icon" href="/apple-touch-icon.png">
<link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Alfa+Slab+One&family=Barlow:wght@400;600;700&display=swap" rel="stylesheet"> <link href="https://fonts.googleapis.com/css2?family=Alfa+Slab+One&family=Barlow:wght@400;600;700&display=swap" rel="stylesheet">

View File

@ -13,7 +13,9 @@ const { title } = Astro.props;
<meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="viewport" content="width=device-width, initial-scale=1" />
<title>{title}</title> <title>{title}</title>
<meta name="theme-color" content="#fff6f4" /> <meta name="theme-color" content="#fff6f4" />
<link rel="icon" href="/src/img/favicon.ico" type="image/x-icon" /> <link rel="icon" href="/favicon.ico" sizes="48x48">
<link rel="icon" href="/favicon.svg" type="image/svg+xml">
<link rel="apple-touch-icon" href="/apple-touch-icon.png">
</head> </head>
<body> <body>
<slot /> <slot />

View File

@ -8,7 +8,7 @@ import posts from '../../data/posts.json';
<header class="blog-header"> <header class="blog-header">
<a class="header-logo" href="/"> <a class="header-logo" href="/">
<span class="sr-only">dangrubb.net home</span> <span class="sr-only">dangrubb.net home</span>
<img src="/src/img/DanGrubbLogoDark.png" alt="" width="64" height="64" /> <img src="/src/img/DanGrubbLogoDark.svg" alt="" width="64" height="64" />
</a> </a>
<h1 class="page-title">Blog</h1> <h1 class="page-title">Blog</h1>
<p class="back-link"><a href="/">← Home</a></p> <p class="back-link"><a href="/">← Home</a></p>

View File

@ -26,16 +26,18 @@ const links = [
<title>dangrubb.net</title> <title>dangrubb.net</title>
<meta name="description" content="Welcome to dangrubb.net" /> <meta name="description" content="Welcome to dangrubb.net" />
<meta name="theme-color" content="#fff6f4" /> <meta name="theme-color" content="#fff6f4" />
<link rel="icon" href="/src/img/favicon.ico" type="image/x-icon" /> <link rel="icon" href="/favicon.ico" sizes="48x48">
<link rel="preload" as="image" href="/src/img/DanGrubbLogoWhite.png" /> <link rel="icon" href="/favicon.svg" type="image/svg+xml">
<link rel="apple-touch-icon" href="/apple-touch-icon.png">
<link rel="preload" as="image" href="/src/img/DanGrubbLogoWhite.svg" type="image/svg+xml" />
</head> </head>
<body class="is-loading"> <body class="is-loading">
<div class="loader" id="loader" aria-hidden="true"> <div class="loader" id="loader" aria-hidden="true">
<div class="loader__stage"> <div class="loader__stage">
<div class="scene"> <div class="scene">
<div class="cube"> <div class="cube">
<div class="cube__face cube__face--front"><img src="/src/img/DanGrubbLogoWhite.png" alt="" width="140" height="140" /></div> <div class="cube__face cube__face--front"><img src="/src/img/DanGrubbLogoWhite.svg" alt="" width="140" height="140" /></div>
<div class="cube__face cube__face--back"><img src="/src/img/DanGrubbLogoWhite.png" alt="" width="140" height="140" /></div> <div class="cube__face cube__face--back"><img src="/src/img/DanGrubbLogoWhite.svg" alt="" width="140" height="140" /></div>
<div class="cube__face cube__face--right"></div> <div class="cube__face cube__face--right"></div>
<div class="cube__face cube__face--left"></div> <div class="cube__face cube__face--left"></div>
<div class="cube__face cube__face--top"></div> <div class="cube__face cube__face--top"></div>
@ -49,7 +51,7 @@ const links = [
<header class="bar"> <header class="bar">
<a class="bar__logo" href="/"> <a class="bar__logo" href="/">
<span class="sr-only">dangrubb.net home</span> <span class="sr-only">dangrubb.net home</span>
<img src="/src/img/DanGrubbLogoDark.png" alt="" width="48" height="48" /> <img src="/src/img/DanGrubbLogoDark.svg" alt="" width="48" height="48" />
</a> </a>
<nav class="menu" id="menu" aria-label="Site"> <nav class="menu" id="menu" aria-label="Site">

View File

@ -724,7 +724,8 @@ export function startOrb(canvas, { onReady } = {}) {
if (!gl) return false; if (!gl) return false;
const hasF32 = !!gl.getExtension('EXT_color_buffer_float'); const hasF32 = !!gl.getExtension('EXT_color_buffer_float');
const interactive = hasF32 || !!gl.getExtension('EXT_color_buffer_half_float'); // let: dropped to false if the simulation turns out not to work on this GPU/driver (see the checks below)
let interactive = hasF32 || !!gl.getExtension('EXT_color_buffer_half_float');
const stateFmt = hasF32 const stateFmt = hasF32
? { internal: gl.RGBA32F, type: gl.FLOAT } ? { internal: gl.RGBA32F, type: gl.FLOAT }
: { internal: gl.RGBA16F, type: gl.HALF_FLOAT }; : { internal: gl.RGBA16F, type: gl.HALF_FLOAT };
@ -770,6 +771,19 @@ export function startOrb(canvas, { onReady } = {}) {
// and the spawn point of the current life, so the costly spawn maths runs once per life // and the spawn point of the current life, so the costly spawn maths runs once per life
const state = interactive ? pingPong(gl, T, T, stateFmt.internal, stateFmt.type, gl.NEAREST, 3) : null; const state = interactive ? pingPong(gl, T, T, stateFmt.internal, stateFmt.type, gl.NEAREST, 3) : null;
let needInit = true; let needInit = true;
const fallBack = (why) => {
if (!interactive) return;
interactive = false;
console.warn('orb: particle simulation unavailable on this GPU/driver, using the static layout.', why);
};
// some drivers accept float render targets but cannot complete a three-attachment framebuffer
if (state) {
const incomplete = [state.read, state.write].some((t) => {
gl.bindFramebuffer(gl.FRAMEBUFFER, t.fbo);
return gl.checkFramebufferStatus(gl.FRAMEBUFFER) !== gl.FRAMEBUFFER_COMPLETE;
});
if (incomplete) fallBack('particle framebuffer incomplete');
}
// fluid fields; rebuilt when the viewport shape changes so the grid stays square-celled // fluid fields; rebuilt when the viewport shape changes so the grid stays square-celled
let velocity, dye, pressure, divergence, curl, simW = 1, simH = 1; let velocity, dye, pressure, divergence, curl, simW = 1, simH = 1;
@ -924,6 +938,23 @@ export function startOrb(canvas, { onReady } = {}) {
let simT = reduced ? 8 : 0; let simT = reduced ? 8 : 0;
let last = performance.now(); let last = performance.now();
let ready = false; let ready = false;
let frameCount = 0;
// A few frames in, read one particle back: if the simulation produced nothing sane (all zeros, NaN),
// draw the static layout instead of an orb with no particles.
function verifySimulation() {
if (!hasF32) return; // reading half-float targets back as float is not guaranteed
try {
const px = new Float32Array(4);
gl.bindFramebuffer(gl.FRAMEBUFFER, state.read.fbo);
gl.readBuffer(gl.COLOR_ATTACHMENT0);
gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.FLOAT, px); // particle 0: an inner particle, always inside the ball
const r = Math.hypot(px[0], px[1], px[2]);
if (!(Number.isFinite(r) && r > 0.2 && r < 1.0)) fallBack(`particle 0 read back as (${Array.from(px).join(', ')})`);
} catch (e) {
fallBack(String(e));
}
}
function commonUniforms(prog, t) { function commonUniforms(prog, t) {
gl.uniform1f(prog.u.uTime, t); gl.uniform1f(prog.u.uTime, t);
@ -1004,6 +1035,7 @@ export function startOrb(canvas, { onReady } = {}) {
gl.uniform1f(s.u.uDt, dt); gl.uniform1f(s.u.uDt, dt);
gl.uniform1f(s.u.uGain, 0.5); gl.uniform1f(s.u.uGain, 0.5);
stepState(); stepState();
if (++frameCount === 5) verifySimulation();
} }
gl.bindFramebuffer(gl.FRAMEBUFFER, null); gl.bindFramebuffer(gl.FRAMEBUFFER, null);