Compare commits
8 Commits
dedc1394cf
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 6621b20829 | |||
| 72c0fddf02 | |||
| 6d6302bf5a | |||
| 4fd2e413f1 | |||
| aafed45d0d | |||
| beb45844cc | |||
| 5c4c547a45 | |||
| 95106a8899 |
@@ -206,4 +206,5 @@ export default {
|
|||||||
nextURL: "http://geekring.net/site/350/next",
|
nextURL: "http://geekring.net/site/350/next",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
wooModeOnByDefault: false,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -12,3 +12,9 @@
|
|||||||
async
|
async
|
||||||
src="//gc.zgo.at/count.js"
|
src="//gc.zgo.at/count.js"
|
||||||
></script>
|
></script>
|
||||||
|
|
||||||
|
<!-- Mochi -->
|
||||||
|
<script
|
||||||
|
src="https://mochi.meadow.cafe/reaper/mochi@upchur.ch/embed/1.js"
|
||||||
|
async
|
||||||
|
></script>
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
<style>
|
<style>
|
||||||
h4.isso-thread-heading {
|
h4.isso-thread-heading {
|
||||||
|
color: var(--text-color) !important;
|
||||||
font-size: var(--step-2) !important;
|
font-size: var(--step-2) !important;
|
||||||
font-variation-settings: "opsz" 50, "wght" 350, "SOFT" 20, "WONK" 1 !important;
|
font-variation-settings: "opsz" 50, "wght" 350, "SOFT" 20, "WONK" 1 !important;
|
||||||
line-height: calc(var(--step-2) * 0.25 + var(--step-2)) !important;
|
line-height: calc(var(--step-2) * 0.25 + var(--step-2)) !important;
|
||||||
@@ -59,4 +60,19 @@
|
|||||||
content: "" !important;
|
content: "" !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
textarea.isso-textarea {
|
||||||
|
background-color: var(--background-color) !important;
|
||||||
|
border: var(--border-details) !important;
|
||||||
|
border-color: var(--contrast-color) !important;
|
||||||
|
border-radius: var(--border-radius) !important;
|
||||||
|
color: var(--text-color) !important;
|
||||||
|
font-family: var(--font-family) !important;
|
||||||
|
font-size: var(--step-0) !important;
|
||||||
|
font-variation-settings: var(--font-variation-default) !important;
|
||||||
|
margin-block: 0 1lh !important;
|
||||||
|
min-height: var(--space-l) !important;
|
||||||
|
padding: 0 var(--space-3xs) !important;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -5,11 +5,15 @@
|
|||||||
<link rel="stylesheet" type="text/css" href="/css/index.css" />
|
<link rel="stylesheet" type="text/css" href="/css/index.css" />
|
||||||
<link rel="stylesheet" type="text/css" href="/css/webfonts/webfonts.css" />
|
<link rel="stylesheet" type="text/css" href="/css/webfonts/webfonts.css" />
|
||||||
<link rel="stylesheet" type="text/css" href="/css/code.css" />
|
<link rel="stylesheet" type="text/css" href="/css/code.css" />
|
||||||
|
<!-- Mochi webmentions -->
|
||||||
|
<link rel="webmention" href="https://mochi-webmentions.meadow.cafe/webmention/mochi@upchur.ch/1/receive" />
|
||||||
<!-- Indieweb profile links -->
|
<!-- Indieweb profile links -->
|
||||||
{% if not excludeProfilesFromHead %}{% for link in metadata.socialLinks %}{% if not link.excludeFromHead %}<link {% if link.customAttribute %} {{ link.customAttribute | safe }} {% endif %} href="{{ link.linkURL }}" />{% endif %}{% endfor %}{% endif %}
|
{% if not excludeProfilesFromHead %}{% for link in metadata.socialLinks %}{% if not link.excludeFromHead %}<link {% if link.customAttribute %} {{ link.customAttribute | safe }} {% endif %} href="{{ link.linkURL }}" />{% endif %}{% endfor %}{% endif %}
|
||||||
<!-- /Indieweb profile links -->
|
<!-- /Indieweb profile links -->
|
||||||
{% include "structuredData.njk" %}
|
{% include "structuredData.njk" %}
|
||||||
{% include "analytics.html" %}
|
{% include "analytics.html" %}
|
||||||
|
{% include "weatherStyle.njk" %}
|
||||||
|
{% include "wooModeStyle.njk" %}
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
{% include "header.njk" %}
|
{% include "header.njk" %}
|
||||||
@@ -20,5 +24,6 @@
|
|||||||
</main>
|
</main>
|
||||||
{% include "footer.njk" %}
|
{% include "footer.njk" %}
|
||||||
{% include "weather.njk" %}
|
{% include "weather.njk" %}
|
||||||
|
{% include "wooMode.njk" %}
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -1,16 +1,9 @@
|
|||||||
<style>
|
|
||||||
#siteSettingsContainer {
|
|
||||||
& button:not(#settingsDone) {
|
|
||||||
margin-top: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<div id="siteSettingsContainer">
|
<div id="siteSettingsContainer">
|
||||||
<button onclick="siteSettings.showModal();">Site Settings</button>
|
<button onclick="siteSettings.showModal();">Site Settings</button>
|
||||||
<dialog id="siteSettings">
|
<dialog id="siteSettings">
|
||||||
<h2>Site Settings</h2>
|
<h2>Site Settings</h2>
|
||||||
{% include "weatherController.njk" %}
|
{% include "weatherController.njk" %}
|
||||||
|
{% include "wooModeController.njk" %}
|
||||||
<button id="settingsDone" onclick="siteSettings.close();">Done</button>
|
<button id="settingsDone" onclick="siteSettings.close();">Done</button>
|
||||||
</dialog>
|
</dialog>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,117 +1,6 @@
|
|||||||
<!-- weather -->
|
<!-- weather -->
|
||||||
<!-- Based on https://codepen.io/codeconvey/pen/xRzQay -->
|
<!-- Based on https://codepen.io/codeconvey/pen/xRzQay -->
|
||||||
{# This include causes a symbol (text, emoji, et cetera; from metadata.weatherSymbol) to fall from the top of the viewport like snow. #}
|
{# This include causes a symbol (text, emoji, et cetera; from metadata.weatherSymbol) to fall from the top of the viewport like snow. #}
|
||||||
|
|
||||||
<style>
|
|
||||||
.fallingObject {
|
|
||||||
color: #fff;
|
|
||||||
font-size: 1em;
|
|
||||||
font-family: Arial;
|
|
||||||
pointer-events: none;
|
|
||||||
text-shadow: 0 0 1px #000;
|
|
||||||
}
|
|
||||||
@keyframes fallingObjects-fall {
|
|
||||||
0% {
|
|
||||||
top: -10%;
|
|
||||||
}
|
|
||||||
100% {
|
|
||||||
top: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@keyframes fallingObjects-shake {
|
|
||||||
0% {
|
|
||||||
transform: translateX(0px);
|
|
||||||
}
|
|
||||||
50% {
|
|
||||||
transform: translateX(80px);
|
|
||||||
}
|
|
||||||
100% {
|
|
||||||
transform: translateX(0px);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.fallingObject {
|
|
||||||
position: fixed;
|
|
||||||
top: -10%;
|
|
||||||
z-index: 9999;
|
|
||||||
user-select: none;
|
|
||||||
cursor: default;
|
|
||||||
animation-name: fallingObjects-fall, fallingObjects-shake;
|
|
||||||
animation-duration: 10s, 3s;
|
|
||||||
animation-timing-function: linear, ease-in-out;
|
|
||||||
animation-iteration-count: infinite, infinite;
|
|
||||||
animation-play-state: running, running;
|
|
||||||
}
|
|
||||||
.fallingObject:nth-of-type(0) {
|
|
||||||
left: 1%;
|
|
||||||
animation-delay: 0s, 0s;
|
|
||||||
& > div {
|
|
||||||
transform: rotate(45deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.fallingObject:nth-of-type(1) {
|
|
||||||
left: 10%;
|
|
||||||
animation-delay: 1s, 1s;
|
|
||||||
& > div {
|
|
||||||
transform: rotate(10deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.fallingObject:nth-of-type(2) {
|
|
||||||
left: 20%;
|
|
||||||
animation-delay: 6s, 0.5s;
|
|
||||||
& > div {
|
|
||||||
transform: rotate(60deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.fallingObject:nth-of-type(3) {
|
|
||||||
left: 30%;
|
|
||||||
animation-delay: 4s, 2s;
|
|
||||||
& > div {
|
|
||||||
transform: rotate(84deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.fallingObject:nth-of-type(4) {
|
|
||||||
left: 40%;
|
|
||||||
animation-delay: 2s, 2s;
|
|
||||||
& > div {
|
|
||||||
transform: rotate(267deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.fallingObject:nth-of-type(5) {
|
|
||||||
left: 50%;
|
|
||||||
animation-delay: 8s, 3s;
|
|
||||||
& > div {
|
|
||||||
transform: rotate(200deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.fallingObject:nth-of-type(6) {
|
|
||||||
left: 60%;
|
|
||||||
animation-delay: 6s, 2s;
|
|
||||||
& > div {
|
|
||||||
transform: rotate(20deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.fallingObject:nth-of-type(7) {
|
|
||||||
left: 70%;
|
|
||||||
animation-delay: 2.5s, 1s;
|
|
||||||
& > div {
|
|
||||||
transform: rotate(78deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.fallingObject:nth-of-type(8) {
|
|
||||||
left: 80%;
|
|
||||||
animation-delay: 1s, 0s;
|
|
||||||
& > div {
|
|
||||||
transform: rotate(3120deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.fallingObject:nth-of-type(9) {
|
|
||||||
left: 90%;
|
|
||||||
animation-delay: 3s, 1.5s;
|
|
||||||
& > div {
|
|
||||||
transform: rotate(123deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<div class="fallingObjects" id="weather" aria-hidden="true">
|
<div class="fallingObjects" id="weather" aria-hidden="true">
|
||||||
<div class="fallingObject">
|
<div class="fallingObject">
|
||||||
<div>{{ metadata.weatherSymbol }}</div>
|
<div>{{ metadata.weatherSymbol }}</div>
|
||||||
|
|||||||
@@ -1,30 +1,4 @@
|
|||||||
<style>
|
<form class="siteSettingsToggle" id="weatherController">
|
||||||
#weatherController {
|
|
||||||
color: var(--text-color);
|
|
||||||
font-size: var(--step--2);
|
|
||||||
font-variation-settings: var(--font-variation-ui);
|
|
||||||
text-transform: uppercase;
|
|
||||||
letter-spacing: var(--ui-letter-spacing);
|
|
||||||
font-family: var(--font-family-ui);
|
|
||||||
& label {
|
|
||||||
display: inline;
|
|
||||||
}
|
|
||||||
& input {
|
|
||||||
accent-color: var(--contrast-color);
|
|
||||||
background-color: var(--background-color);
|
|
||||||
border: var(--border-details);
|
|
||||||
border-color: var(--contrast-color);
|
|
||||||
border-radius: var(--border-radius);
|
|
||||||
color: var(--text-color);
|
|
||||||
&:focus {
|
|
||||||
box-shadow: 0 0 0 2px var(--contrast-color);
|
|
||||||
outline: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<form id="weatherController">
|
|
||||||
<input type="checkbox" id="weatherToggle" {% if metadata.weatherOnByDefault %}checked{% endif %} />
|
<input type="checkbox" id="weatherToggle" {% if metadata.weatherOnByDefault %}checked{% endif %} />
|
||||||
<label for="weatherToggle">Show weather?</label>
|
<label for="weatherToggle">Show weather?</label>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
112
_includes/weatherStyle.njk
Normal file
112
_includes/weatherStyle.njk
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
<!-- Weather style -->
|
||||||
|
<style>
|
||||||
|
.fallingObject {
|
||||||
|
color: #fff;
|
||||||
|
font-size: 1em;
|
||||||
|
font-family: Arial;
|
||||||
|
pointer-events: none;
|
||||||
|
text-shadow: 0 0 1px #000;
|
||||||
|
}
|
||||||
|
@keyframes fallingObjects-fall {
|
||||||
|
0% {
|
||||||
|
top: -10%;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
top: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@keyframes fallingObjects-shake {
|
||||||
|
0% {
|
||||||
|
transform: translateX(0px);
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
transform: translateX(80px);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: translateX(0px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.fallingObject {
|
||||||
|
position: fixed;
|
||||||
|
top: -10%;
|
||||||
|
z-index: 9999;
|
||||||
|
user-select: none;
|
||||||
|
cursor: default;
|
||||||
|
animation-name: fallingObjects-fall, fallingObjects-shake;
|
||||||
|
animation-duration: 10s, 3s;
|
||||||
|
animation-timing-function: linear, ease-in-out;
|
||||||
|
animation-iteration-count: infinite, infinite;
|
||||||
|
animation-play-state: running, running;
|
||||||
|
}
|
||||||
|
.fallingObject:nth-of-type(0) {
|
||||||
|
left: 1%;
|
||||||
|
animation-delay: 0s, 0s;
|
||||||
|
& > div {
|
||||||
|
transform: rotate(45deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.fallingObject:nth-of-type(1) {
|
||||||
|
left: 10%;
|
||||||
|
animation-delay: 1s, 1s;
|
||||||
|
& > div {
|
||||||
|
transform: rotate(10deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.fallingObject:nth-of-type(2) {
|
||||||
|
left: 20%;
|
||||||
|
animation-delay: 6s, 0.5s;
|
||||||
|
& > div {
|
||||||
|
transform: rotate(60deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.fallingObject:nth-of-type(3) {
|
||||||
|
left: 30%;
|
||||||
|
animation-delay: 4s, 2s;
|
||||||
|
& > div {
|
||||||
|
transform: rotate(84deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.fallingObject:nth-of-type(4) {
|
||||||
|
left: 40%;
|
||||||
|
animation-delay: 2s, 2s;
|
||||||
|
& > div {
|
||||||
|
transform: rotate(267deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.fallingObject:nth-of-type(5) {
|
||||||
|
left: 50%;
|
||||||
|
animation-delay: 8s, 3s;
|
||||||
|
& > div {
|
||||||
|
transform: rotate(200deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.fallingObject:nth-of-type(6) {
|
||||||
|
left: 60%;
|
||||||
|
animation-delay: 6s, 2s;
|
||||||
|
& > div {
|
||||||
|
transform: rotate(20deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.fallingObject:nth-of-type(7) {
|
||||||
|
left: 70%;
|
||||||
|
animation-delay: 2.5s, 1s;
|
||||||
|
& > div {
|
||||||
|
transform: rotate(78deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.fallingObject:nth-of-type(8) {
|
||||||
|
left: 80%;
|
||||||
|
animation-delay: 1s, 0s;
|
||||||
|
& > div {
|
||||||
|
transform: rotate(3120deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.fallingObject:nth-of-type(9) {
|
||||||
|
left: 90%;
|
||||||
|
animation-delay: 3s, 1.5s;
|
||||||
|
& > div {
|
||||||
|
transform: rotate(123deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<!-- / Weather style -->
|
||||||
222
_includes/wooMode.njk
Normal file
222
_includes/wooMode.njk
Normal file
@@ -0,0 +1,222 @@
|
|||||||
|
<!-- Woo Mode -->
|
||||||
|
<!-- Based on https://codepen.io/tommyho/pen/JjgoZLK -->
|
||||||
|
{# This include replaces the page background with a crazy rainbow animated shader #}
|
||||||
|
|
||||||
|
<canvas id="shaderCanvas"></canvas>
|
||||||
|
<script src="/js/three.min.js"></script>
|
||||||
|
<script>
|
||||||
|
let scene, camera, renderer, uniforms, material, mesh;
|
||||||
|
|
||||||
|
function initWoo() {
|
||||||
|
scene = new THREE.Scene();
|
||||||
|
camera = new THREE.OrthographicCamera(-1, 1, 1, -1, 0, 1);
|
||||||
|
|
||||||
|
renderer = new THREE.WebGLRenderer({ canvas: document.getElementById('shaderCanvas'), antialias: true });
|
||||||
|
renderer.setSize(window.innerWidth, window.innerHeight);
|
||||||
|
|
||||||
|
const vertexShader = `
|
||||||
|
varying vec2 vUv;
|
||||||
|
void main() {
|
||||||
|
vUv = uv;
|
||||||
|
gl_Position = vec4(position, 1.0);
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const fragmentShader = `
|
||||||
|
uniform float time;
|
||||||
|
uniform vec2 resolution;
|
||||||
|
varying vec2 vUv;
|
||||||
|
|
||||||
|
#define PI 3.14159265358979323846
|
||||||
|
|
||||||
|
vec2 rotate(vec2 v, float a) {
|
||||||
|
float s = sin(a);
|
||||||
|
float c = cos(a);
|
||||||
|
mat2 m = mat2(c, -s, s, c);
|
||||||
|
return m * v;
|
||||||
|
}
|
||||||
|
|
||||||
|
float random(vec2 st) {
|
||||||
|
return fract(sin(dot(st.xy, vec2(12.9898, 78.233))) * 43758.5453123);
|
||||||
|
}
|
||||||
|
|
||||||
|
float noise(vec2 st) {
|
||||||
|
vec2 i = floor(st);
|
||||||
|
vec2 f = fract(st);
|
||||||
|
|
||||||
|
float a = random(i);
|
||||||
|
float b = random(i + vec2(1.0, 0.0));
|
||||||
|
float c = random(i + vec2(0.0, 1.0));
|
||||||
|
float d = random(i + vec2(1.0, 1.0));
|
||||||
|
|
||||||
|
vec2 u = f * f * (3.0 - 2.0 * f);
|
||||||
|
|
||||||
|
return mix(a, b, u.x) + (c - a) * u.y * (1.0 - u.x) + (d - b) * u.x * u.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
float fbm(vec2 st) {
|
||||||
|
float value = 0.0;
|
||||||
|
float amplitude = 0.5;
|
||||||
|
float frequency = 0.0;
|
||||||
|
for (int i = 0; i < 6; i++) {
|
||||||
|
value += amplitude * noise(st);
|
||||||
|
st *= 2.0;
|
||||||
|
amplitude *= 0.5;
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 palette(float t, vec3 a, vec3 b, vec3 c, vec3 d) {
|
||||||
|
return a + b * cos(6.28318 * (c * t + d));
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 vibrancePalette(float t) {
|
||||||
|
vec3 a = vec3(0.5, 0.5, 0.5);
|
||||||
|
vec3 b = vec3(0.5, 0.5, 0.5);
|
||||||
|
vec3 c = vec3(1.0, 1.0, 1.0);
|
||||||
|
vec3 d = vec3(0.0, 0.33, 0.67);
|
||||||
|
return palette(t, a, b, c, d);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 warmPalette(float t) {
|
||||||
|
vec3 a = vec3(0.5, 0.5, 0.5);
|
||||||
|
vec3 b = vec3(0.5, 0.5, 0.5);
|
||||||
|
vec3 c = vec3(1.0, 1.0, 1.0);
|
||||||
|
vec3 d = vec3(0.0, 0.10, 0.20);
|
||||||
|
return palette(t, a, b, c, d);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 coolPalette(float t) {
|
||||||
|
vec3 a = vec3(0.5, 0.5, 0.5);
|
||||||
|
vec3 b = vec3(0.5, 0.5, 0.5);
|
||||||
|
vec3 c = vec3(1.0, 1.0, 1.0);
|
||||||
|
vec3 d = vec3(0.3, 0.20, 0.20);
|
||||||
|
return palette(t, a, b, c, d);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 rainbowPalette(float t) {
|
||||||
|
vec3 a = vec3(0.5, 0.5, 0.5);
|
||||||
|
vec3 b = vec3(0.5, 0.5, 0.5);
|
||||||
|
vec3 c = vec3(1.0, 1.0, 1.0);
|
||||||
|
vec3 d = vec3(0.0, 0.33, 0.67);
|
||||||
|
return palette(t, a, b, c, d);
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec2 st = gl_FragCoord.xy / resolution.xy;
|
||||||
|
st.x *= resolution.x / resolution.y;
|
||||||
|
|
||||||
|
vec2 q = vec2(0.);
|
||||||
|
q.x = fbm(st + 0.1 * time);
|
||||||
|
q.y = fbm(st + vec2(1.0));
|
||||||
|
|
||||||
|
vec2 r = vec2(0.);
|
||||||
|
r.x = fbm(st + 1.0 * q + vec2(1.7, 9.2) + 0.15 * time);
|
||||||
|
r.y = fbm(st + 1.0 * q + vec2(8.3, 2.8) + 0.126 * time);
|
||||||
|
|
||||||
|
float f = fbm(st + r);
|
||||||
|
|
||||||
|
vec2 p = st * 2.0 - 1.0;
|
||||||
|
float a = atan(p.y, p.x);
|
||||||
|
float r2 = length(p);
|
||||||
|
|
||||||
|
vec2 uv = vec2(a / PI, r2);
|
||||||
|
uv = rotate(uv, time * 0.1);
|
||||||
|
|
||||||
|
vec3 color1 = vibrancePalette(f + time * 0.1);
|
||||||
|
vec3 color2 = warmPalette(length(q));
|
||||||
|
vec3 color3 = coolPalette(length(r.x));
|
||||||
|
vec3 color4 = rainbowPalette(f * 2.0 + time * 0.2);
|
||||||
|
|
||||||
|
vec3 color = mix(color1, color2, 0.5);
|
||||||
|
color = mix(color, color3, 0.3);
|
||||||
|
color = mix(color, color4, sin(time * 0.1) * 0.5 + 0.5);
|
||||||
|
|
||||||
|
color += 0.05 * vec3(1.0) * smoothstep(0.1, 0.2, fbm(10.0 * uv + time * 0.5));
|
||||||
|
|
||||||
|
// Add some extra vibrancy
|
||||||
|
color = pow(color, vec3(0.8));
|
||||||
|
color *= 1.1;
|
||||||
|
|
||||||
|
gl_FragColor = vec4(color, 1.0);
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
uniforms = {
|
||||||
|
time: { value: 1.0 },
|
||||||
|
resolution: { value: new THREE.Vector2() }
|
||||||
|
};
|
||||||
|
|
||||||
|
material = new THREE.ShaderMaterial({
|
||||||
|
uniforms: uniforms,
|
||||||
|
vertexShader: vertexShader,
|
||||||
|
fragmentShader: fragmentShader
|
||||||
|
});
|
||||||
|
|
||||||
|
mesh = new THREE.Mesh(new THREE.PlaneGeometry(2, 2), material);
|
||||||
|
scene.add(mesh);
|
||||||
|
|
||||||
|
onWindowResize();
|
||||||
|
window.addEventListener('resize', onWindowResize, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onWindowResize() {
|
||||||
|
renderer.setSize(window.innerWidth, window.innerHeight);
|
||||||
|
uniforms.resolution.value.x = renderer.domElement.width;
|
||||||
|
uniforms.resolution.value.y = renderer.domElement.height;
|
||||||
|
}
|
||||||
|
|
||||||
|
function animate(timestamp) {
|
||||||
|
requestAnimationFrame(animate);
|
||||||
|
uniforms.time.value = timestamp * 0.001;
|
||||||
|
renderer.render(scene, camera);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
const wooCanvas = document.getElementById("shaderCanvas");
|
||||||
|
const wooToggle = document.getElementById("wooToggle");
|
||||||
|
const wooPreference = localStorage.getItem("wooMode");
|
||||||
|
let forcedWoo = false;
|
||||||
|
|
||||||
|
// Initial preference check on page load
|
||||||
|
if ({% if metadata.wooModeOnByDefault == false %}!wooPreference || {% endif %}wooPreference == 0) {
|
||||||
|
forcedWoo ? null : wooCanvas.classList.add("hidden");
|
||||||
|
wooToggle.checked = false;
|
||||||
|
} else {
|
||||||
|
wooCanvas.classList.remove("hidden");
|
||||||
|
wooToggle.checked = true;
|
||||||
|
initWoo();
|
||||||
|
animate(0);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Handle setting toggle
|
||||||
|
wooToggle.addEventListener('change', function() {
|
||||||
|
if (this.checked) {
|
||||||
|
localStorage.setItem("wooMode", 1);
|
||||||
|
|
||||||
|
let wooAudio = new Audio("/audio/30995__unclesigmund__woo-2.mp3");
|
||||||
|
wooAudio.volume = 0.4;
|
||||||
|
wooAudio.play();
|
||||||
|
|
||||||
|
wooCanvas.classList.remove("hidden");
|
||||||
|
initWoo();
|
||||||
|
animate(0);
|
||||||
|
} else {
|
||||||
|
localStorage.setItem("wooMode", 0);
|
||||||
|
forcedWoo ? null : wooCanvas.classList.add("hidden");
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
{% if forcedWoo %}
|
||||||
|
// Handle forced woo
|
||||||
|
forcedWoo = true;
|
||||||
|
console.log("Forcing woo mode: woo!");
|
||||||
|
wooCanvas.classList.remove("hidden");
|
||||||
|
initWoo();
|
||||||
|
animate(0);
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
|
||||||
|
</script>
|
||||||
|
<!-- /weather -->
|
||||||
4
_includes/wooModeController.njk
Normal file
4
_includes/wooModeController.njk
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<form class="siteSettingsToggle" id="wooModeController">
|
||||||
|
<input type="checkbox" id="wooToggle" {% if metadata.wooModeOnByDefault %}checked{% endif %} />
|
||||||
|
<label for="wooToggle">Woo mode?</label>
|
||||||
|
</form>
|
||||||
16
_includes/wooModeStyle.njk
Normal file
16
_includes/wooModeStyle.njk
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<!-- Woo mode style -->
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
background: none;
|
||||||
|
}
|
||||||
|
canvas {
|
||||||
|
display: block;
|
||||||
|
opacity: .35;
|
||||||
|
pointer-events: none;
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
z-index: -1;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<!-- / Woo mode style -->
|
||||||
@@ -7,4 +7,4 @@ structuredData: none
|
|||||||
# Privacy Statement
|
# Privacy Statement
|
||||||
|
|
||||||
## Data collection and use
|
## Data collection and use
|
||||||
I don’t collect any of your personal information, full-stop. All webfonts, icons, and images are hosted locally (these things can sometimes be used to [track people across the internet](https://www.firstpost.com/world/how-google-uses-fonts-to-track-what-users-do-online-and-sell-data-to-advertisers-12496552.html) otherwise). I use [umami](https://umami.is), a free and open source, privacy-respecting analytics tool, to see how many people visit this website. As of 2025-12-16 I also use [Goat Counter](https://goatcounter.com) (also FLOSS and privacy-respecting) as a backup to umami, as my self-hosted umami instance shat the bed the other day and I lost a bunch of data.
|
I don’t collect any of your personal information, full-stop. All webfonts, icons, and images are hosted locally (these things can sometimes be used to [track people across the internet](https://www.firstpost.com/world/how-google-uses-fonts-to-track-what-users-do-online-and-sell-data-to-advertisers-12496552.html) otherwise). I use [umami](https://umami.is), a free and open source, privacy-respecting analytics tool, to see how many people visit this website. As of 2025-12-16 I also use [Goat Counter](https://goatcounter.com) and [Mochi](https://mochi.meadow.cafe/) (also FLOSS and privacy-respecting) as backups to umami, as my self-hosted umami instance shat the bed the other day and I lost a bunch of data.
|
||||||
|
|||||||
410
content/blog/100-webmaster-questions.md
Normal file
410
content/blog/100-webmaster-questions.md
Normal file
@@ -0,0 +1,410 @@
|
|||||||
|
---
|
||||||
|
title: "100 Webmaster Questions"
|
||||||
|
description: "Answering a lot of questions."
|
||||||
|
date: 2026-02-05
|
||||||
|
tags:
|
||||||
|
- Questionnaire
|
||||||
|
synopsis: "Answering a lot of questions."
|
||||||
|
mastodon_id: "116021932929019975"
|
||||||
|
---
|
||||||
|
I found this questionnaire on the website of my [Geekring](https://geekring.net/) neighbor [Corvidae](https://corvidae.digital/100). [Original questions sheet on mousling.net](https://mouseling.net/100webmaster.txt).
|
||||||
|
|
||||||
|
## Please introduce yourself.
|
||||||
|
|
||||||
|
I'm Nathan. I live in Chicago, U.S.A., and have far too many interests. I play classical trombone for fun, make incense sticks, write things, cook vegan food, and more.
|
||||||
|
|
||||||
|
## How long have you been making websites?
|
||||||
|
|
||||||
|
Beside tinkering with HTML and CSS to customize my MySpace profile, I first started back in, oh, 2004 or 2005.
|
||||||
|
|
||||||
|
## And what got you into the hobby?
|
||||||
|
|
||||||
|
I just became so exhausted with both mainstream social media and the idea of a “personal brand” that I decided I needed a space on the internet where I could just sort of exist as a human honestly, and on my own terms.
|
||||||
|
|
||||||
|
## What kind of website are you most interested in?
|
||||||
|
|
||||||
|
Personal sites, featuring real people earnestly documenting their existence creatively. I'd like everyone to have one.
|
||||||
|
|
||||||
|
## What's your workflow? do you plan your websites out thoroughly or do you come up with the design as you go along?
|
||||||
|
|
||||||
|
If I'm making a site for a client, the whole thing is absolutely planned out first in order to nail down the scope. Then the design has to be done, from concepts to revisions and final approval, before any code can be written. If I'm making something for myself, I often just start with code and see where it goes.
|
||||||
|
|
||||||
|
## Please link to your biggest inspirations.
|
||||||
|
|
||||||
|
This might sound a bit conceited, but I don't know that I have any. I find that a lot of competition-winning design work is actually just ghastly to use and totally ignores accessibility, so I kind of have beef with many of my contemporaries. Really, the goal for my website was to try to make an excellent reading experience. It's not the most cutting-edge design, or the most interesting, but I think I've at least done that.
|
||||||
|
|
||||||
|
## What's your favourite part about making websites?
|
||||||
|
|
||||||
|
I love getting to that stage where you have systems in place and updates become really simple. I get a lot of satisfaction in refactoring, and trying to make things modular and reusable.
|
||||||
|
|
||||||
|
## And the thing you struggle with the most?
|
||||||
|
|
||||||
|
Getting over the blank page. Starting from nothing is always stressful.
|
||||||
|
|
||||||
|
## Do you keep the same layout on all of your pages? or do you use different ones?
|
||||||
|
|
||||||
|
Pretty much, yea. I use fluid spacing and type-sizing so the whole site is responsive and usable at any screen size without a single media query. I don't have much interest in tackling all of those problems again for a different layout haha.
|
||||||
|
|
||||||
|
## How confident are you with css?
|
||||||
|
|
||||||
|
I think I'm pretty solid. CSS is becoming more and more capable and easy to use. Christ, we have variables (custom properties) and nested selectors these days. It's not often I find myself banging my head against the wall anymore at any rate. Now if only I could keep my CSS a little more tidy…
|
||||||
|
|
||||||
|
## Do you know how to correctly use `<dl>`?
|
||||||
|
|
||||||
|
I've never needed it, but I'm glad to have learned about it here.
|
||||||
|
|
||||||
|
## What is your favorite html element?
|
||||||
|
|
||||||
|
The dialog element is really neat. It does so much for you too.
|
||||||
|
|
||||||
|
## If you're making a new web page from scratch, what is the first thing you do?
|
||||||
|
|
||||||
|
I like to use [Eleventy](https://www.11ty.dev/), so I'm not likely to be starting from scratch. If I had to though, I'd probably go remind myself what HTML boilerplate I'm supposed to be using these days.
|
||||||
|
|
||||||
|
## Do you know javascript?
|
||||||
|
|
||||||
|
Yes. I use it for desktop automation too, with Node.
|
||||||
|
|
||||||
|
## How about php?
|
||||||
|
|
||||||
|
I fear PHP.
|
||||||
|
|
||||||
|
## Does your website have a theme that you stick to?
|
||||||
|
|
||||||
|
For sure.
|
||||||
|
|
||||||
|
## Are you more focused on content or design?
|
||||||
|
|
||||||
|
Content. The reading experience is pretty good, so while I sometimes feel that my site is a little dull compared to some other personal sites, I'm happy with that.
|
||||||
|
|
||||||
|
## Do you own a domain name? if not, would you ever want to?
|
||||||
|
|
||||||
|
Absolutely. A few, actually.
|
||||||
|
|
||||||
|
## What do you think of nostalgia-focused or "retro" websites?
|
||||||
|
|
||||||
|
I think they're fun and I like to see them.
|
||||||
|
|
||||||
|
## Is your html valid? do you even check?
|
||||||
|
|
||||||
|
Lord, I haven't thought about that in a minute. I may have to fix a few things…
|
||||||
|
|
||||||
|
## What are your opinion on buttons and banners?
|
||||||
|
|
||||||
|
They're fun. I'd like to make a dedicated page for them at some point.
|
||||||
|
|
||||||
|
## What do you think of button walls in particular?
|
||||||
|
|
||||||
|
I think they're fun.
|
||||||
|
|
||||||
|
## If you started over again, would you make something similar or completely different?
|
||||||
|
|
||||||
|
I think it would be pretty similar, to be honest.
|
||||||
|
|
||||||
|
## Are you envious of other people's websites?
|
||||||
|
|
||||||
|
All the time! I love the cool stuff people build onto their sites: music players, et cetera. I just have to remind myself that my site has different goals.
|
||||||
|
|
||||||
|
## What text editor do you use?
|
||||||
|
|
||||||
|
I use the woefully underrated [Kate](https://kate-editor.org/). For quick edits I use [KWrite](https://apps.kde.org/kwrite/). In the terminal, I use Nano.
|
||||||
|
|
||||||
|
## Why do you use that one?
|
||||||
|
|
||||||
|
Kate is a lightweight native application with no electron bloat, and it has so may features. KWrite is also native, but it's really pared down, which is what you want sometimes. And as for Nano, well I just don't want to have to memorize esoteric commands to edit text.
|
||||||
|
|
||||||
|
## Do you host your image files on your web server, or on another host?
|
||||||
|
|
||||||
|
All images and typefaces are served locally. I'm careful to optimize images, and I don't want my visitors to be tracked by Google via Google Fonts. I do use a PeerTube instance for video.
|
||||||
|
|
||||||
|
## This might not be relevant to you, but what's your opinion on the neocities vs. nekoweb debate?
|
||||||
|
|
||||||
|
No idea. I host my own stuff.
|
||||||
|
|
||||||
|
## How much server space would you estimate your main website takes up?
|
||||||
|
|
||||||
|
At the time of writing, it's 90.2 MiB, with 564 files and 247 directories. Nuts!
|
||||||
|
|
||||||
|
## Do you keep local backups of your files?
|
||||||
|
|
||||||
|
I develop my site locally, so there's that. I also have a copy on my Gitea instance.
|
||||||
|
|
||||||
|
## Do you prefer simple or highly visual websites?
|
||||||
|
|
||||||
|
It really depends on the goals of the site! If it's designed to be a visually engaging website that encourages exploration, it makes sense to have some visual complexity going on. On the other hand, if I'm there to read an article, I don't want that to be hindered by the design.
|
||||||
|
|
||||||
|
## Do you stick to certain colours? do you do that on purpose, or is it your subconscious?
|
||||||
|
|
||||||
|
It varies from project to project.
|
||||||
|
|
||||||
|
## Have you ever thought about quitting? why?
|
||||||
|
|
||||||
|
No, at least where it concerns my personal projects. Client work isn't as fun, so I think I'm going to be pretty choosy about what I work on for the foreseeable future (outside of my day-job) because I really have come to value my free time very highly.
|
||||||
|
|
||||||
|
## Do you have many webmaster friends, or is it a solitary hobby?
|
||||||
|
|
||||||
|
Not many, but one or two.
|
||||||
|
|
||||||
|
## Do people in your real life know about your website?
|
||||||
|
|
||||||
|
Yes. It's got my name on it haha.
|
||||||
|
|
||||||
|
## Do you update your website very often? how often is "very often"?
|
||||||
|
|
||||||
|
I do; I have "status" and "now burning" sections on my site for micro-blogging and listing what incense sticks I'm burning. I wrote [a wee utility](https://nathanupchurch.com/blog/Solving-SSG-Microblogging-Ergonomics-with-KDialog-for-Incense-Posting/) to make it quick and easy to post these during the work-day, so updates usually happen from at least every other day to multiple times a day.
|
||||||
|
|
||||||
|
## And the overall design, do you change that much? why or why not?
|
||||||
|
|
||||||
|
No. I feel that I've met my design goals for my site, and getting the fluid type / spacing system and variable typefaces right took so. much. time. I have zero interest in doing all of that work again.
|
||||||
|
|
||||||
|
## Is your website more you-focused, hobby-focused, or outside world-focused?
|
||||||
|
|
||||||
|
It's a little of everything. I really want my website to represent me as a whole human, so I try to make sure that there's a good mix of creativity, life stuff, writing on hobbies and interests, et cetera.
|
||||||
|
|
||||||
|
## Do you do web design professionally?
|
||||||
|
|
||||||
|
Yes. I have a design firm that I operate with my business partner [Davey](https://daveydynamite.neocities.org/), although we don't do a lot with it at the minute. I also sometimes do web projects as a part of my role at my day job.
|
||||||
|
|
||||||
|
## If not, would you like to? and if you're comfortable answering, what do you do for work?
|
||||||
|
|
||||||
|
My title doesn't elucidate much, but my day job is a director-level role at a Chicago non-profit. It's a small organization, so we all have a hand in operations, but I also do design work, process work, and a little automation. I do everything from design collateral for events, to leading digital infrastructure integration projects, and building processes and tools for our team. I know a lot of people would complain about doing so many things, but I really value variety and enjoy project work so it fits me pretty well.
|
||||||
|
|
||||||
|
## Do you communicate with people by email very much?
|
||||||
|
|
||||||
|
Yea, I often email with other incense-heads and I get occasional emails from people who read my blog. I enjoy it when people get in touch with questions and comments.
|
||||||
|
|
||||||
|
## Some people reject social media and use websites as a replacement. do you keep social media outside of your website?
|
||||||
|
|
||||||
|
I try to avoid mainstream social media, but I am [all over the fediverse](https://nathan.contact).
|
||||||
|
|
||||||
|
## How about instant messengers? do you use a mainstream one like discord or telegram? or something like matrix? do you avoid them?
|
||||||
|
|
||||||
|
With great resentment I still have a Discord account that I rarely use. I use [Matrix and Signal](https://nathan.contact) often, and I also have an [XMPP](https://nathan.contact) account through the FSF that I have never once used haha. I stay signed in though, so if you have XMPP and want to get in touch, it would be a novelty to use it for once.
|
||||||
|
|
||||||
|
## Do you listen to music while you work on websites? if so, what kinds of artists?
|
||||||
|
|
||||||
|
Often! It depends on my mood, and my taste in music is hugely varied and slightly insane. It could be anything from Hindustani classical to deathcore, drum and bass, Russian ecclesiastical music, classical trombone concertos, black metal, or trip-hop. To throw some artists at the wall: Christian Lindberg, Ladytron, Mora Prokaza, Enei, Pandit Jasraj, Marie Keyrouz.
|
||||||
|
|
||||||
|
## Do you keep everything you make on one website, or do you have more than one?
|
||||||
|
|
||||||
|
Just the one right now. I eventually plan to make a "professional" website for all the corpo-speak that employers like to see when hiring.
|
||||||
|
|
||||||
|
## On a similar note, do you keep to one topic on your site, or many?
|
||||||
|
|
||||||
|
I write about many things, but I do try to keep incense at the fore, because it's something that very few people write about—especially when it comes to making incense. It's so hard to find information on incense-making and I want to do my part to keep the tradition alive.
|
||||||
|
|
||||||
|
## Do you present your real self, or at least try? or do you construct a persona on purpose?
|
||||||
|
|
||||||
|
Yes, with some caveats. I swear much more in the flesh. My philosophy is that I treat speech on my website as though I'm at a casual gathering with mixed company.
|
||||||
|
|
||||||
|
## Have you ever made a good friend thanks to your website?
|
||||||
|
|
||||||
|
Not really. Outside of the incense scene, I don't really make many online friends.
|
||||||
|
|
||||||
|
## Are you happy with the way html and css currently work?
|
||||||
|
|
||||||
|
Mostly. I do wish I could get a bit more programmatic with CSS. They're working on it, though.
|
||||||
|
|
||||||
|
## What are practices that you think people should avoid?
|
||||||
|
|
||||||
|
Ignoring accessibility: alt text, contrast ratios, et cetera. It's so much easier now with semantic HTML, too, and the WCAG is published online for anyone to read.
|
||||||
|
|
||||||
|
## What about under-utilised practices, or things you think people should do more?
|
||||||
|
|
||||||
|
Beside accessibility, using containers to encapsulate elements so that they can be more easily positioned with CSS grids and flexbox. Also using the proper elements. For example my comment form, which I *did not* write, has a bunch of `<p>` tags as containers and doesn't separate the buttons from the input fields in separate containers, making styling a nightmare.
|
||||||
|
|
||||||
|
## Do you use a lot of semantic html? or are you guilty of generic structure?
|
||||||
|
|
||||||
|
Absolutely. Why wouldn't you?
|
||||||
|
|
||||||
|
## Do you consider different browsers?
|
||||||
|
|
||||||
|
For pro work, you have to. I once had a subcontractor complaining that a site I built wasn't working only to find out that she was using a browser that hadn't been updated in seven years. (We found out that this was Apple's fault. After a point, they stop letting you upgrade your OS, and that means Safari too. What a nightmare.) You've got to decide where the cutoff is in order to know what features you can use. For personal stuff, I just target the most current version of Firefox. Usually, it's Chrome playing fast and loose with web standards, so if you target Chrome it seems like there's no guarantee that your site will work in Firefox, whereas the opposite usually isn't true.
|
||||||
|
|
||||||
|
## Speaking of, what's your preferred browser? convince your readers why they should use it.
|
||||||
|
|
||||||
|
Anything not using the Chromium engine, so basically Firefox and derivatives. Google uses their superior Chrome user numbers to justify making features outside of open web standards. This causes sites to break on non-Chromium browsers. This behavior is part of an ongoing pattern of [EEE](https://en.wikipedia.org/wiki/Embrace,_extend,_and_extinguish) on Google's part, and if it is allowed to continue, it risks making the web worse for everyone. I would encourage people to avoid Chrome, and any browser that uses its engine. If we don't, Google will use the leverage to kill competition and screw us all over like it has done time and time again (XMPP and RSS are some examples).
|
||||||
|
|
||||||
|
## And what os are you on?
|
||||||
|
|
||||||
|
EndeavourOS, an Arch GNU/Linux derivative.
|
||||||
|
|
||||||
|
## Do you have a strong opinion on that, or do you just happen to use it?
|
||||||
|
|
||||||
|
Well, I strongly feel that GNU/Linux is better than proprietary options. EndeavourOS just fits my needs really well with its up-to-date packages, frequent updates, and flexibility.
|
||||||
|
|
||||||
|
## Are your websites mobile-friendly?
|
||||||
|
|
||||||
|
Of course!
|
||||||
|
|
||||||
|
## What are your thoughts on autoplay?
|
||||||
|
|
||||||
|
It's for the best that it's blocked by default, but I still wish I could get away with using it on one or two special pages.
|
||||||
|
|
||||||
|
## What are your thoughts on webrings? are you in any?
|
||||||
|
|
||||||
|
Big fan. I'm in two at the moment: [Fediring](https://fediring.net/), and [Geekring](https://geekring.net/).
|
||||||
|
|
||||||
|
## Do you have any web shrines? what do you like to see in that sort of page?
|
||||||
|
|
||||||
|
No, nothing like that. I like discovering them though.
|
||||||
|
|
||||||
|
## Are your websites "cliche," in your opinion?
|
||||||
|
|
||||||
|
I hope not!
|
||||||
|
|
||||||
|
## What is your ideal website? are you striving for that, or for something else?
|
||||||
|
|
||||||
|
Real, fun, and ever-changing.
|
||||||
|
|
||||||
|
## Are you an artist? do you draw or design your own assets?
|
||||||
|
|
||||||
|
While I do graphic design, I'm not really an illustrator or anything like that—beyond the odd project for fun. So designer yes, artist no.
|
||||||
|
|
||||||
|
## What are your favourite resource sites?
|
||||||
|
|
||||||
|
I have an absolute ton of them on my [/links](https://nathanupchurch.com/links/) page.
|
||||||
|
|
||||||
|
## Is there a habit you just can't get away from no matter how hard you try?
|
||||||
|
|
||||||
|
Sloppy CSS. The cascade is tricky, but I think I'm improving.
|
||||||
|
|
||||||
|
## What's your biggest advice for a new webmaster?
|
||||||
|
|
||||||
|
Take your time, and learn git and *make a new branch* for any significant and complicated work so that it's easy to revert it if you make a mistake or get stuck.
|
||||||
|
|
||||||
|
## Do you keep all your styling in css? or do you hard-code some?
|
||||||
|
|
||||||
|
I use inline styles only as a last resort, usually for styling widgets that I have little control over such as the comment form.
|
||||||
|
|
||||||
|
## What do you think of frameset layouts?
|
||||||
|
|
||||||
|
It's not the 90s any more.
|
||||||
|
|
||||||
|
## How about table-based layouts?
|
||||||
|
|
||||||
|
Again, we're in 2026. There is no excuse for this haha.
|
||||||
|
|
||||||
|
## Do you subscribe to the ideas of "one-column", "two-column" and "three-column" layouts? do you use any of these?
|
||||||
|
|
||||||
|
I mean, when you look at eye-tracking studies, you see that the way people engage with websites is always changing. I think that, so long as you're applying gestalt principles in your design, you're probably doing an okay job no matter the layout.
|
||||||
|
|
||||||
|
## Do you spend longer on the html or the css?
|
||||||
|
|
||||||
|
The CSS, without question.
|
||||||
|
|
||||||
|
## Have you ever made a page with no css? it's useful for your thoughts.
|
||||||
|
|
||||||
|
No, never!
|
||||||
|
|
||||||
|
## Do you ever find yourself making layouts with nothing to put on them? or do you only make layouts when the need arises?
|
||||||
|
|
||||||
|
Only when necessary.
|
||||||
|
|
||||||
|
## Would you consider yourself a beginner? or advanced? somewhere in the middle?
|
||||||
|
|
||||||
|
I wouldn't go so far as to say advanced, but I think I know what I'm doing.
|
||||||
|
|
||||||
|
## Do you have a habit of looking at the source code of websites you visit?
|
||||||
|
|
||||||
|
Not often, as many sites have crazy obfuscated code these days. It's not often that you find well formatted, human-readable source anymore. More often I find myself reading documentation or Stack Overflow.
|
||||||
|
|
||||||
|
## How did you learn how to make websites?
|
||||||
|
|
||||||
|
I began in what was either a digital graphics or multimedia class in school where we learned to make websites using Adobe Dreamweaver. In adulthood I wound up tripping and falling into a career that eventually led to me making a number of websites professionally. I started with Adobe Muse, actually winning Adobe's Muse Site of the Day at one point. Once Adobe canned Muse, I realized I was going to have to get serious about learning HTML, CSS, and JavaScript, so I did.
|
||||||
|
|
||||||
|
## Do you ever force elements to do things they're not supposed to?
|
||||||
|
|
||||||
|
I do my best to avoid hacks.
|
||||||
|
|
||||||
|
## Thoughts on floating elements?
|
||||||
|
|
||||||
|
Again I say: it's not the 90s anymore.
|
||||||
|
|
||||||
|
## When you're sizing stuff, what do you use first? do you use px, em, %, or something else?
|
||||||
|
|
||||||
|
I'm using my responsive spacing system, so it's something like `var(--space-l)`, which will resolve to something like `clamp(2.5rem, 2.2183rem + 1.4085vw, 3rem)`. It makes things very easy and keeps everything nice and consistent.
|
||||||
|
|
||||||
|
## Do you have a favourite font?
|
||||||
|
|
||||||
|
I wouldn't know how to begin to choose!
|
||||||
|
|
||||||
|
## Would you run a website with another person? how would that work?
|
||||||
|
|
||||||
|
Why not? If it was interesting.
|
||||||
|
|
||||||
|
## Do you surf the web to find new personal websites very often?
|
||||||
|
|
||||||
|
Yes, I really enjoy clicking through web-rings and buttons.
|
||||||
|
|
||||||
|
## Do you bookmark other people's websites? how would you feel knowing someone else bookmarked yours?
|
||||||
|
|
||||||
|
Not often, no.
|
||||||
|
|
||||||
|
## What do you want people to be most impressed with when they see your website?
|
||||||
|
|
||||||
|
The fact that the layout uses no media queries.
|
||||||
|
|
||||||
|
## Are you interested in technology outside of websites? do you collect?
|
||||||
|
|
||||||
|
Yea, I love computers and FLOSS software. I do try to make good purchases that will last a long time, so I don't have a *ton* of tech, but I'm certainly not short on gadgets.
|
||||||
|
|
||||||
|
## How often and for how long are you online?
|
||||||
|
|
||||||
|
I work on a computer, so most of the day.
|
||||||
|
|
||||||
|
## When it comes to your website, who is your target audience?
|
||||||
|
|
||||||
|
Mostly incense nerds and people who want to keep up with my life. It's super easy to get an audience if you're on the fediverse and write about tech, but there are already plenty of blogs like that out there.
|
||||||
|
|
||||||
|
## Have you ever been interested in xhtml?
|
||||||
|
|
||||||
|
Not especially. It seems like one of those things that just never really took off.
|
||||||
|
|
||||||
|
## Do you program in general? have you ever written a program for use with or on your website, not counting simple javascript?
|
||||||
|
|
||||||
|
Yea, I wrote [Poaster](https://nathanupchurch.com/blog/Solving-SSG-Microblogging-Ergonomics-with-KDialog-for-Incense-Posting/) in Ruby for some reason. I have also done desktop automation stuff with Node.
|
||||||
|
|
||||||
|
## Speaking of programs that help you make websites, what do you think of static site generators (ssgs)? have you ever used one?
|
||||||
|
|
||||||
|
Big fan of Eleventy. I love being able to just get straight to the content when I want to, and I love that my site is modular and simple to update.
|
||||||
|
|
||||||
|
## Do you keep a hitcounter? why or why not?
|
||||||
|
|
||||||
|
No, but I do use some privacy respecting FLOSS analytics tools. I like to see how many people are reading my posts and where they are from.
|
||||||
|
|
||||||
|
## Do you frequent forums? which ones?
|
||||||
|
|
||||||
|
I wouldn't use the term frequent, but I do have a presence on some FLOSS forums, as well as [Dogs on Acid](https://www.dogsonacid.com/), and [Ouddict](https://www.ouddict.com/).
|
||||||
|
|
||||||
|
## Do you write your page content directly into the editor, or do you prepare it elsewhere, like a text document or a word document?
|
||||||
|
|
||||||
|
I often use [Marknote](https://apps.kde.org/marknote/). It's new and a little rough around the edges, but the potential is huge and I already enjoy using it despite its sometimes very annoying bugs.
|
||||||
|
|
||||||
|
## Do you think you appear cool to others? a more accurate answer now: do other people ever say you're cool?
|
||||||
|
|
||||||
|
I've been told that I write like a 50 year old academic, so, no haha. I also don't know that adults call each other cool very often. Certainly not the cool ones anyway!
|
||||||
|
|
||||||
|
## Are you embarrassed of your old work? have you ever deleted everything out of shame?
|
||||||
|
|
||||||
|
Always and forever.
|
||||||
|
|
||||||
|
## Would you close down your website if you couldn't update it, or would you leave an archive?
|
||||||
|
|
||||||
|
I think I'd like to leave it.
|
||||||
|
|
||||||
|
## So you reveal a lot about yourself on your website? or are you more secretive?
|
||||||
|
|
||||||
|
I try not to overshare too much, but I do keep it real, I think.
|
||||||
|
|
||||||
|
## Are you willing to reveal who your best online friend is, and/or if they have a website?
|
||||||
|
|
||||||
|
I will never tell.
|
||||||
|
|
||||||
|
## And do you optimise the images on your website?
|
||||||
|
|
||||||
|
Yes, with the utterly incredible [Converseen](https://converseen.fasterland.net/).
|
||||||
|
|
||||||
|
## We're out of time! how do you feel after answering 100 questions? ... other than exhausted.
|
||||||
|
|
||||||
|
Ready for bed!
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
---
|
||||||
|
title: "Woo-Woo Incense Description Generator and Other Site Updates"
|
||||||
|
description: "New on this website: a handy tool to generate woo, comments, and weather."
|
||||||
|
date: 2026-02-05
|
||||||
|
tags:
|
||||||
|
- Site Updates
|
||||||
|
imageURL: /img/woo-woo-incense-description-generator-and-other-updates/woo-woo-incense-description-generator_copy.webp
|
||||||
|
imageAlt: "A screenshot of the woo generator page. Swirling rainbow colors form the background."
|
||||||
|
synopsis: "New on this website: a handy tool to generate woo, comments, and weather."
|
||||||
|
mastodon_id: "116021705122518903"
|
||||||
|
---
|
||||||
|
## Woo-woo incense description generator
|
||||||
|
Whether they are spiritually inclined or mere earth-bound fragrance-heads, all sorts of people are attracted to the fragrant world of incense. It's no surprise, then, that the language people use to describe the incense they make can get pretty colorful. If you've ever wished you could write so… *interestingly* about incense, my brand new [Woo-woo incense description generator](/special/woo-woo-incense-description-generator/) is just the ticket! Occupying the "special" section of [my sitemap](/sitemap/) along-side the flying toasters, with but one click of a button it spits out a fresh serving of woo, complete with ingredients and "medicinal effects."[^1] Why not [give it a try?](/special/woo-woo-incense-description-generator/)
|
||||||
|
|
||||||
|
[](/img/woo-woo-incense-description-generator-and-other-updates/woo-woo-incense-description-generator_copy.webp)
|
||||||
|
|
||||||
|
## Woo mode
|
||||||
|
You may have noticed a "site settings" button at the bottom of the page. I set this up after the holidays with a "show weather" toggle to allow visitors who miss the snowflakes to enable them once again. In addition to this, there is now a "woo mode" toggle that allows you to have the psychedelic woo-woo incense description generator background on every page of the site! Both settings save to your browser's local storage, handily retaining the setting between visits for you with no cookies.
|
||||||
|
|
||||||
|
[](/img/woo-woo-incense-description-generator-and-other-updates/site-settings.webp)
|
||||||
|
|
||||||
|
## Guestbook back up
|
||||||
|
For a while, the service that powers my [guestbook](/guestbook/) went down due to [some drama with Azure](https://meadow.cafe/blog/0008-azure-disabled-my-account-trip-to-the-cabin/) and lost some data. Therefore, if you notice that your message is missing, know that I didn't delete it on purpose and feel free to leave another.
|
||||||
|
|
||||||
|
## Comments now available
|
||||||
|
I have, at long last, set up commenting via [Isso](https://isso-comments.de/) on blog posts and, as an unintended side effect, [quizzes](/quizzes), which I kind of like so I left it (there's only one quiz at the minute anyway). I wanted to do this ages ago, but I couldn't get Isso working on my [YunoHost](https://yunohost.org/index.en.html) server until recently. YunoHost is fantastic, but support can be scarce as hen's teeth, so we'll see how things go. Hopefully, it'll be rock solid and serve me well for years to come. Hopefully people will leave polite, thoughtful comments. Hopefully, spam is thin on the ground. Time will tell all!
|
||||||
|
|
||||||
|
[^1]: For the love of all that is good in this world do not take these seriously.
|
||||||
@@ -4,8 +4,12 @@ title: Nathan Upchurch | Changelog
|
|||||||
structuredData: none
|
structuredData: none
|
||||||
---
|
---
|
||||||
# Changelog
|
# Changelog
|
||||||
|
* 2026-02-07
|
||||||
|
* Updated [/wish](/wish).
|
||||||
* 2026-02-04
|
* 2026-02-04
|
||||||
* Added post comments via [Isso](https://isso-comments.de/). Please don't make me regret this.
|
* Added post comments via [Isso](https://isso-comments.de/). Please don't make me regret this.
|
||||||
|
* Add [Mochi](https://mochi.meadow.cafe/) privacy respecting analytics.
|
||||||
|
* Implement togglable site-wide Woo-Mode™ in site settings.
|
||||||
* 2026-02-01
|
* 2026-02-01
|
||||||
* Added [Woo-Woo Incense Description Generator](/special/woo-woo-incense-description-generator).
|
* Added [Woo-Woo Incense Description Generator](/special/woo-woo-incense-description-generator).
|
||||||
* 2026-01-21
|
* 2026-01-21
|
||||||
|
|||||||
7
content/now-burning/Now Burning_2026-02-04_15:27.md
Normal file
7
content/now-burning/Now Burning_2026-02-04_15:27.md
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
title: Morikage
|
||||||
|
manufacturer: Hikali Koh
|
||||||
|
date: 2026-02-04 15:27:00
|
||||||
|
time: 3:27 PM
|
||||||
|
---
|
||||||
|
|
||||||
7
content/now-burning/Now Burning_2026-02-05_10:13.md
Normal file
7
content/now-burning/Now Burning_2026-02-05_10:13.md
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
title: Musk
|
||||||
|
manufacturer: "The Mother’s Fragrances"
|
||||||
|
date: 2026-02-05 10:12:00
|
||||||
|
time: 10:12 AM
|
||||||
|
---
|
||||||
|
|
||||||
7
content/now-burning/Now Burning_2026-02-05_10:38.md
Normal file
7
content/now-burning/Now Burning_2026-02-05_10:38.md
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
title: Agarwood
|
||||||
|
manufacturer: Ganesha
|
||||||
|
date: 2026-02-05 10:38:00
|
||||||
|
time: 10:38 AM
|
||||||
|
---
|
||||||
|
|
||||||
7
content/now-burning/Now Burning_2026-02-09_13:28.md
Normal file
7
content/now-burning/Now Burning_2026-02-09_13:28.md
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
title: Agarwood
|
||||||
|
manufacturer: Ganesha
|
||||||
|
date: 2026-02-09 13:20:00
|
||||||
|
time: 1:20 PM
|
||||||
|
---
|
||||||
|
|
||||||
7
content/now-burning/Now Burning_2026-02-09_22:56.md
Normal file
7
content/now-burning/Now Burning_2026-02-09_22:56.md
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
title: Musk
|
||||||
|
manufacturer: "The Mother’s Fragrances"
|
||||||
|
date: 2026-02-09 22:56:00
|
||||||
|
time: 10:56 PM
|
||||||
|
---
|
||||||
|
|
||||||
7
content/now-burning/Now Burning_2026-02-10_10:06.md
Normal file
7
content/now-burning/Now Burning_2026-02-10_10:06.md
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
title: Patchouli
|
||||||
|
manufacturer: "The Mother’s Fragrances"
|
||||||
|
date: 2026-02-10 10:06:00
|
||||||
|
time: 10:06 AM
|
||||||
|
---
|
||||||
|
|
||||||
7
content/now-burning/Now Burning_2026-02-10_12:42.md
Normal file
7
content/now-burning/Now Burning_2026-02-10_12:42.md
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
title: Oud
|
||||||
|
manufacturer: Flora Botanical Incense
|
||||||
|
date: 2026-02-10 12:42:00
|
||||||
|
time: 12:42 PM
|
||||||
|
---
|
||||||
|
|
||||||
7
content/now-burning/Now Burning_2026-02-11_10:17.md
Normal file
7
content/now-burning/Now Burning_2026-02-11_10:17.md
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
title: Hawaiian Summer
|
||||||
|
manufacturer: Incense Apprentice
|
||||||
|
date: 2026-02-11 10:16:00
|
||||||
|
time: 10:16 AM
|
||||||
|
---
|
||||||
|
I think a little age has done this stick good. It's got a pleasant coolness.
|
||||||
7
content/now-burning/Now Burning_2026-02-13_10:03.md
Normal file
7
content/now-burning/Now Burning_2026-02-13_10:03.md
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
title: "Frankincense & Myrrh with Sacred Sage"
|
||||||
|
manufacturer: Fred Soll
|
||||||
|
date: 2026-02-13 10:02:00
|
||||||
|
time: 10:02 AM
|
||||||
|
---
|
||||||
|
An incredibly strong stick. Ventilation is key!
|
||||||
@@ -2,15 +2,20 @@
|
|||||||
layout: layouts/base.njk
|
layout: layouts/base.njk
|
||||||
title: "Woo-Woo Incense Description Generator"
|
title: "Woo-Woo Incense Description Generator"
|
||||||
structuredData: none
|
structuredData: none
|
||||||
|
forcedWoo: true
|
||||||
---
|
---
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<h1>Woo-Woo Incense Description Generator</h1>
|
<h1>Woo-Woo Incense Description Generator</h1>
|
||||||
<p>Ever wonder how people come up with those confusing esoteric descriptions of their incense complete with “medicinal effects?” Want some ideas to spice up your Instagram profile, website, or Etsy listings? Well you’re in luck! Click the button below to generate an incense description so mystical you’ll swear your chakras are aligned! Music by <a href="https://pixabay.com/users/saavane-32312792/">saavane on Pixabay</a>. Woo sound effect by <a href="https://freesound.org/s/30995/">UncleSigmund on freesound</a>. Background effect from <a href="https://codepen.io/tommyho/pen/JjgoZLK">Tommy Ho on Codepen</a>. No <a href="/ai">AI</a> used—I can write slop on my own!</p>
|
<p>Ever wonder how incense makers come up with those confusing esoteric descriptions of their incense complete with “medicinal effects?” Want some ideas to spice up your Instagram profile, website, or Etsy listings? Well you’re in luck! Click the button below to generate an incense description so mystical you’ll swear your chakras are aligned! Music by <a href="https://pixabay.com/users/saavane-32312792/">saavane on Pixabay</a>. Woo sound effect by <a href="https://freesound.org/s/30995/">UncleSigmund on freesound</a>. Background effect from <a href="https://codepen.io/tommyho/pen/JjgoZLK">Tommy Ho on Codepen</a>. No <a href="/ai">AI</a> used—I can write slop on my own!</p>
|
||||||
|
|
||||||
<script src="/js/incense-description-generator.js"></script>
|
<script src="/js/incense-description-generator.js"></script>
|
||||||
<script>
|
<script>
|
||||||
const audioOnClick = new Audio("/audio/30995__unclesigmund__woo-2.mp3");
|
let audioOnClick = new Audio("/audio/30995__unclesigmund__woo-2.mp3");
|
||||||
const bgMusic = new Audio("/audio/new-sun-428916.mp3");
|
let bgMusic = new Audio("/audio/new-sun-428916.mp3");
|
||||||
|
|
||||||
|
audioOnClick.volume = 0.4;
|
||||||
|
bgMusic.volume = 0.4;
|
||||||
|
bgMusic.loop = true;
|
||||||
|
|
||||||
window.addEventListener("pointermove", (e) => {
|
window.addEventListener("pointermove", (e) => {
|
||||||
bgMusic.play();
|
bgMusic.play();
|
||||||
@@ -38,193 +43,3 @@ structuredData: none
|
|||||||
<button onclick="generateWoo('wooContainer', 'wooButton')" id="wooButton">Generate Some Woo!</button>
|
<button onclick="generateWoo('wooContainer', 'wooButton')" id="wooButton">Generate Some Woo!</button>
|
||||||
<div class="card" id="wooContainer" style="padding: var(--space-s); margin-top: var(--space-l);">Click the button to generate woo…</div>
|
<div class="card" id="wooContainer" style="padding: var(--space-s); margin-top: var(--space-l);">Click the button to generate woo…</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Background effect from https://codepen.io/tommyho/pen/JjgoZLK -->
|
|
||||||
<canvas id="shaderCanvas"></canvas>
|
|
||||||
<script src="/js/three.min.js"></script>
|
|
||||||
<script>
|
|
||||||
let scene, camera, renderer, uniforms, material, mesh;
|
|
||||||
|
|
||||||
function init() {
|
|
||||||
scene = new THREE.Scene();
|
|
||||||
camera = new THREE.OrthographicCamera(-1, 1, 1, -1, 0, 1);
|
|
||||||
|
|
||||||
renderer = new THREE.WebGLRenderer({ canvas: document.getElementById('shaderCanvas'), antialias: true });
|
|
||||||
renderer.setSize(window.innerWidth, window.innerHeight);
|
|
||||||
|
|
||||||
const vertexShader = `
|
|
||||||
varying vec2 vUv;
|
|
||||||
void main() {
|
|
||||||
vUv = uv;
|
|
||||||
gl_Position = vec4(position, 1.0);
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
const fragmentShader = `
|
|
||||||
uniform float time;
|
|
||||||
uniform vec2 resolution;
|
|
||||||
varying vec2 vUv;
|
|
||||||
|
|
||||||
#define PI 3.14159265358979323846
|
|
||||||
|
|
||||||
vec2 rotate(vec2 v, float a) {
|
|
||||||
float s = sin(a);
|
|
||||||
float c = cos(a);
|
|
||||||
mat2 m = mat2(c, -s, s, c);
|
|
||||||
return m * v;
|
|
||||||
}
|
|
||||||
|
|
||||||
float random(vec2 st) {
|
|
||||||
return fract(sin(dot(st.xy, vec2(12.9898, 78.233))) * 43758.5453123);
|
|
||||||
}
|
|
||||||
|
|
||||||
float noise(vec2 st) {
|
|
||||||
vec2 i = floor(st);
|
|
||||||
vec2 f = fract(st);
|
|
||||||
|
|
||||||
float a = random(i);
|
|
||||||
float b = random(i + vec2(1.0, 0.0));
|
|
||||||
float c = random(i + vec2(0.0, 1.0));
|
|
||||||
float d = random(i + vec2(1.0, 1.0));
|
|
||||||
|
|
||||||
vec2 u = f * f * (3.0 - 2.0 * f);
|
|
||||||
|
|
||||||
return mix(a, b, u.x) + (c - a) * u.y * (1.0 - u.x) + (d - b) * u.x * u.y;
|
|
||||||
}
|
|
||||||
|
|
||||||
float fbm(vec2 st) {
|
|
||||||
float value = 0.0;
|
|
||||||
float amplitude = 0.5;
|
|
||||||
float frequency = 0.0;
|
|
||||||
for (int i = 0; i < 6; i++) {
|
|
||||||
value += amplitude * noise(st);
|
|
||||||
st *= 2.0;
|
|
||||||
amplitude *= 0.5;
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3 palette(float t, vec3 a, vec3 b, vec3 c, vec3 d) {
|
|
||||||
return a + b * cos(6.28318 * (c * t + d));
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3 vibrancePalette(float t) {
|
|
||||||
vec3 a = vec3(0.5, 0.5, 0.5);
|
|
||||||
vec3 b = vec3(0.5, 0.5, 0.5);
|
|
||||||
vec3 c = vec3(1.0, 1.0, 1.0);
|
|
||||||
vec3 d = vec3(0.0, 0.33, 0.67);
|
|
||||||
return palette(t, a, b, c, d);
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3 warmPalette(float t) {
|
|
||||||
vec3 a = vec3(0.5, 0.5, 0.5);
|
|
||||||
vec3 b = vec3(0.5, 0.5, 0.5);
|
|
||||||
vec3 c = vec3(1.0, 1.0, 1.0);
|
|
||||||
vec3 d = vec3(0.0, 0.10, 0.20);
|
|
||||||
return palette(t, a, b, c, d);
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3 coolPalette(float t) {
|
|
||||||
vec3 a = vec3(0.5, 0.5, 0.5);
|
|
||||||
vec3 b = vec3(0.5, 0.5, 0.5);
|
|
||||||
vec3 c = vec3(1.0, 1.0, 1.0);
|
|
||||||
vec3 d = vec3(0.3, 0.20, 0.20);
|
|
||||||
return palette(t, a, b, c, d);
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3 rainbowPalette(float t) {
|
|
||||||
vec3 a = vec3(0.5, 0.5, 0.5);
|
|
||||||
vec3 b = vec3(0.5, 0.5, 0.5);
|
|
||||||
vec3 c = vec3(1.0, 1.0, 1.0);
|
|
||||||
vec3 d = vec3(0.0, 0.33, 0.67);
|
|
||||||
return palette(t, a, b, c, d);
|
|
||||||
}
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
vec2 st = gl_FragCoord.xy / resolution.xy;
|
|
||||||
st.x *= resolution.x / resolution.y;
|
|
||||||
|
|
||||||
vec2 q = vec2(0.);
|
|
||||||
q.x = fbm(st + 0.1 * time);
|
|
||||||
q.y = fbm(st + vec2(1.0));
|
|
||||||
|
|
||||||
vec2 r = vec2(0.);
|
|
||||||
r.x = fbm(st + 1.0 * q + vec2(1.7, 9.2) + 0.15 * time);
|
|
||||||
r.y = fbm(st + 1.0 * q + vec2(8.3, 2.8) + 0.126 * time);
|
|
||||||
|
|
||||||
float f = fbm(st + r);
|
|
||||||
|
|
||||||
vec2 p = st * 2.0 - 1.0;
|
|
||||||
float a = atan(p.y, p.x);
|
|
||||||
float r2 = length(p);
|
|
||||||
|
|
||||||
vec2 uv = vec2(a / PI, r2);
|
|
||||||
uv = rotate(uv, time * 0.1);
|
|
||||||
|
|
||||||
vec3 color1 = vibrancePalette(f + time * 0.1);
|
|
||||||
vec3 color2 = warmPalette(length(q));
|
|
||||||
vec3 color3 = coolPalette(length(r.x));
|
|
||||||
vec3 color4 = rainbowPalette(f * 2.0 + time * 0.2);
|
|
||||||
|
|
||||||
vec3 color = mix(color1, color2, 0.5);
|
|
||||||
color = mix(color, color3, 0.3);
|
|
||||||
color = mix(color, color4, sin(time * 0.1) * 0.5 + 0.5);
|
|
||||||
|
|
||||||
color += 0.05 * vec3(1.0) * smoothstep(0.1, 0.2, fbm(10.0 * uv + time * 0.5));
|
|
||||||
|
|
||||||
// Add some extra vibrancy
|
|
||||||
color = pow(color, vec3(0.8));
|
|
||||||
color *= 1.1;
|
|
||||||
|
|
||||||
gl_FragColor = vec4(color, 1.0);
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
uniforms = {
|
|
||||||
time: { value: 1.0 },
|
|
||||||
resolution: { value: new THREE.Vector2() }
|
|
||||||
};
|
|
||||||
|
|
||||||
material = new THREE.ShaderMaterial({
|
|
||||||
uniforms: uniforms,
|
|
||||||
vertexShader: vertexShader,
|
|
||||||
fragmentShader: fragmentShader
|
|
||||||
});
|
|
||||||
|
|
||||||
mesh = new THREE.Mesh(new THREE.PlaneGeometry(2, 2), material);
|
|
||||||
scene.add(mesh);
|
|
||||||
|
|
||||||
onWindowResize();
|
|
||||||
window.addEventListener('resize', onWindowResize, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
function onWindowResize() {
|
|
||||||
renderer.setSize(window.innerWidth, window.innerHeight);
|
|
||||||
uniforms.resolution.value.x = renderer.domElement.width;
|
|
||||||
uniforms.resolution.value.y = renderer.domElement.height;
|
|
||||||
}
|
|
||||||
|
|
||||||
function animate(timestamp) {
|
|
||||||
requestAnimationFrame(animate);
|
|
||||||
uniforms.time.value = timestamp * 0.001;
|
|
||||||
renderer.render(scene, camera);
|
|
||||||
}
|
|
||||||
|
|
||||||
init();
|
|
||||||
animate(0);
|
|
||||||
</script>
|
|
||||||
<style>
|
|
||||||
body {
|
|
||||||
background: none;
|
|
||||||
}
|
|
||||||
canvas {
|
|
||||||
display: block;
|
|
||||||
opacity: .35;
|
|
||||||
pointer-events: none;
|
|
||||||
position: fixed;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
z-index: -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|||||||
@@ -41,18 +41,26 @@ However if abstention seems unconscionable, I would be delighted if you were to
|
|||||||
* [Kida Jinseido Ranjatai Incense](https://kikohincense.com/collections/kida-jinseido-incense-since-1937/products/kida-jinseido-ranjatai-incense)
|
* [Kida Jinseido Ranjatai Incense](https://kikohincense.com/collections/kida-jinseido-incense-since-1937/products/kida-jinseido-ranjatai-incense)
|
||||||
* [Kunmeido Shin Tokusen Reiryokoh Incense](https://kikohincense.com/collections/kunmeido-incense-kikoh/products/kunmeido-shin-tokusen-reiryokoh-incense)
|
* [Kunmeido Shin Tokusen Reiryokoh Incense](https://kikohincense.com/collections/kunmeido-incense-kikoh/products/kunmeido-shin-tokusen-reiryokoh-incense)
|
||||||
* [Minorien Kyara Fu-In](https://kikohincense.com/collections/minorien-incense-kikoh/products/minorien-kyara-fu-in-incense)
|
* [Minorien Kyara Fu-In](https://kikohincense.com/collections/minorien-incense-kikoh/products/minorien-kyara-fu-in-incense)
|
||||||
|
* [Nippon Kodo Kayuragi - Rose](https://kikohincense.com/collections/roses-and-chocolates-incense-collection/products/nippon-kodo-kayuragi-incense-rose)
|
||||||
|
* [Nippon Kodo Hana no Hana - Rose](https://kikohincense.com/collections/roses-and-chocolates-incense-collection/products/nippon-kodo-hana-no-hana-incense-rose)
|
||||||
* [Kin Objects Red Soil Aloeswood](https://kinobjects.com/products/red-soil-aloeswood-agarwood-incense-sticks?variant=40432647929879)
|
* [Kin Objects Red Soil Aloeswood](https://kinobjects.com/products/red-soil-aloeswood-agarwood-incense-sticks?variant=40432647929879)
|
||||||
|
* [Kokando Kaori no Kioku Chocolate](https://kikohincense.com/collections/roses-and-chocolates-incense-collection/products/kokando-kaori-no-kioku-chocolate-incense)
|
||||||
* [Kokando Kunpūshi Aloeswood](https://kikohincense.com/products/kokando-kunpushi-aloeswood)
|
* [Kokando Kunpūshi Aloeswood](https://kikohincense.com/products/kokando-kunpushi-aloeswood)
|
||||||
* [Kunmeido Shin Tokusen Reiryokoh](https://kikohincense.com/collections/kunmeido-incense-kikoh/products/kunmeido-shin-tokusen-reiryokoh-incense)
|
* [Kunmeido Shin Tokusen Reiryokoh](https://kikohincense.com/collections/kunmeido-incense-kikoh/products/kunmeido-shin-tokusen-reiryokoh-incense)
|
||||||
|
* [Les Encens du Monde - Moonlit Night | Karin](https://lotuszenincense.com/products/moonlit-night-karin-by-les-encens-du-monde?shpxid=fa2eb8b9-373c-44b6-b675-585881e5540b)
|
||||||
|
* [Mysore](https://www.aliexpress.us/item/3256808362085525.html)
|
||||||
* [Shoyeido Horin Assortment](https://shoyeido.com/products/horin-incense-assortment-sampler)
|
* [Shoyeido Horin Assortment](https://shoyeido.com/products/horin-incense-assortment-sampler)
|
||||||
* [Shoyeido Kohbai Pressed Incense](https://shoyeido.com/products/kohbai-red-plum-blossoms?variant=41714738921590)
|
* [Shoyeido Kohbai Pressed Incense](https://shoyeido.com/products/kohbai-red-plum-blossoms?variant=41714738921590)
|
||||||
* [Shoyeido Kunro Incense Assortment](https://shoyeido.com/products/kunro-incense-assortment)
|
* [Shoyeido Kunro Incense Assortment](https://shoyeido.com/products/kunro-incense-assortment)
|
||||||
|
* [Shoyeido Overtones Patchouli](https://shoyeido.com/products/overtones-patchouli-incense)
|
||||||
* [Shoyeido Premium Incense Sampler](https://shoyeido.com/products/premium-incense-assortment-sampler)
|
* [Shoyeido Premium Incense Sampler](https://shoyeido.com/products/premium-incense-assortment-sampler)
|
||||||
* [Tennendo Hagi Rose Incense](https://kikohincense.com/collections/tennendo-incense-kikoh/products/tennendo-hagi-rose-incense)
|
* [Tennendo Hagi Rose Incense](https://kikohincense.com/collections/tennendo-incense-kikoh/products/tennendo-hagi-rose-incense)
|
||||||
* [Tennendo Hanano Byakudan](https://www.japanincense.com/tn-0051.html)
|
* [Tennendo Hanano Byakudan](https://www.japanincense.com/tn-0051.html)
|
||||||
* [Tennendo Kyara Incense](https://kikohincense.com/products/tennendo-kyara-incense)
|
* [Tennendo Kyara Incense](https://kikohincense.com/products/tennendo-kyara-incense)
|
||||||
* [Tennendo Sumire Violet Incense](https://kikohincense.com/products/tennendo-ysumire-violet-incense)
|
* [Tennendo Sumire Violet Incense](https://kikohincense.com/products/tennendo-ysumire-violet-incense)
|
||||||
* [Yamadamatsu Hyofu](https://kikohincense.com/collections/yamadamatsu-incense-kikoh/products/yamadamatsu-hyofu-incense)
|
* [Yamadamatsu Hyofu](https://kikohincense.com/collections/yamadamatsu-incense-kikoh/products/yamadamatsu-hyofu-incense)
|
||||||
|
* [Yamadamatsu Kumoi](https://kikohincense.com/products/yamadamatsu-kumoyi-incense)
|
||||||
|
* [Yamadamatsu Shoyo](https://www.japanincense.com/ym-0037.html)
|
||||||
|
|
||||||
### Tea
|
### Tea
|
||||||
* A malty black tea from either [Spirit Tea](https://spirittea.co/) or [Yunnan Sourcing](https://yunnansourcing.com/).
|
* A malty black tea from either [Spirit Tea](https://spirittea.co/) or [Yunnan Sourcing](https://yunnansourcing.com/).
|
||||||
|
|||||||
@@ -156,7 +156,7 @@ html {
|
|||||||
input.answer {
|
input.answer {
|
||||||
display: inline;
|
display: inline;
|
||||||
}
|
}
|
||||||
input:not(.answer):not(#weatherToggle),
|
input:not(.answer, .siteSettingsToggle input),
|
||||||
textarea {
|
textarea {
|
||||||
background-color: var(--background-color);
|
background-color: var(--background-color);
|
||||||
border: var(--border-details);
|
border: var(--border-details);
|
||||||
@@ -866,6 +866,36 @@ sup {
|
|||||||
line-height: 0;
|
line-height: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Site Settings */
|
||||||
|
#siteSettingsContainer {
|
||||||
|
& button:not(#settingsDone) {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.siteSettingsToggle {
|
||||||
|
color: var(--text-color);
|
||||||
|
font-size: var(--step--2);
|
||||||
|
font-variation-settings: var(--font-variation-ui);
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: var(--ui-letter-spacing);
|
||||||
|
font-family: var(--font-family-ui);
|
||||||
|
& label {
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
& input {
|
||||||
|
accent-color: var(--contrast-color);
|
||||||
|
background-color: var(--background-color);
|
||||||
|
border: var(--border-details);
|
||||||
|
border-color: var(--contrast-color);
|
||||||
|
border-radius: var(--border-radius);
|
||||||
|
color: var(--text-color);
|
||||||
|
&:focus {
|
||||||
|
box-shadow: 0 0 0 2px var(--contrast-color);
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Tags */
|
/* Tags */
|
||||||
a.post-tag {
|
a.post-tag {
|
||||||
background-color: var(--color-gray-20);
|
background-color: var(--color-gray-20);
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 11 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 62 KiB |
Reference in New Issue
Block a user