A bunch of stuff
This commit is contained in:
@@ -620,6 +620,13 @@ export default {
|
||||
url: "https://thefoggiest.dev",
|
||||
description: "The personal blog of Diederick de Vries of Amsterdam.",
|
||||
},
|
||||
{
|
||||
title: "ThinksTooMuch",
|
||||
feedUrl: "https://thinkstoomuch.net/index.xml",
|
||||
url: "https://thinkstoomuch.net/",
|
||||
description:
|
||||
"Thoughts on atheism, leftism, firearms, work, and life.",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
export default {
|
||||
title: "Nathan Upchurch",
|
||||
logo: "/img/logo.svg",
|
||||
holidayLogo: "",
|
||||
url: "https://nathanupchurch.com/",
|
||||
language: "en",
|
||||
description:
|
||||
@@ -166,6 +167,7 @@ export default {
|
||||
iconURL: "/img/wafrn.svg",
|
||||
},
|
||||
],
|
||||
weatherSymbol: "🍁",
|
||||
webrings: [
|
||||
{
|
||||
name: "Fediring",
|
||||
|
||||
@@ -1,8 +1,4 @@
|
||||
<footer>
|
||||
<a href="https://notbyai.fyi/">
|
||||
<img src="/img/written-by-human-not-by-ai-white.svg" alt="Written by humans, not by AI.">
|
||||
</a>
|
||||
|
||||
<p>{% if metadata.copyrightNotice %}<span class="copyright-notice">{{ metadata.copyrightNotice }}</span>{% endif %}
|
||||
|
||||
{% if metadata.webrings %}<br>
|
||||
@@ -15,6 +11,11 @@
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
<a href="/sitemap/">Sitemap</a>
|
||||
<a href="/special/flying-toasters" style="color: var(--background-color); text-decoration: none;">Fly</a>
|
||||
</p>
|
||||
<div id="buttonsAndStuffContainer">
|
||||
<a href="https://notbyai.fyi/">
|
||||
<img src="/img/written-by-human-not-by-ai-white.svg" alt="Written by humans, not by AI.">
|
||||
</a>
|
||||
{% include "siteSettings.njk" %}
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
class="home-link">
|
||||
<img
|
||||
class="logo"
|
||||
src="{{ metadata.logo }}"
|
||||
src="{% if metadata.holidayLogo %}{{ metadata.holidayLogo }}{% else %}{{ metadata.logo }}{% endif %}"
|
||||
alt="{{ metadata.title }}">
|
||||
</a>
|
||||
{% if not hideNav %}{% include "nav.njk" %}{% endif %}
|
||||
|
||||
@@ -16,5 +16,6 @@
|
||||
</section>
|
||||
</main>
|
||||
{% include "footer.njk" %}
|
||||
{% include "weather.njk" %}
|
||||
</body>
|
||||
</html>
|
||||
|
||||
20
_includes/siteSettings.njk
Normal file
20
_includes/siteSettings.njk
Normal file
@@ -0,0 +1,20 @@
|
||||
<style>
|
||||
#siteSettingsContainer {
|
||||
& button:not(#settingsDone) {
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
const settingsModal = document.getElementById("siteSettings");
|
||||
</script>
|
||||
|
||||
<div id="siteSettingsContainer">
|
||||
<button onclick="siteSettings.showModal();">Site Settings</button>
|
||||
<dialog id="siteSettings">
|
||||
<h2>Site Settings</h2>
|
||||
{% include "weatherController.njk" %}
|
||||
<button id="settingsDone" onclick="siteSettings.close();">Done</button>
|
||||
</dialog>
|
||||
</div>
|
||||
172
_includes/weather.njk
Normal file
172
_includes/weather.njk
Normal file
@@ -0,0 +1,172 @@
|
||||
<!-- weather -->
|
||||
<!-- 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. #}
|
||||
|
||||
<style>
|
||||
.fallingObject {
|
||||
color: #fff;
|
||||
font-size: 1em;
|
||||
font-family: Arial;
|
||||
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="fallingObject">
|
||||
<div>{{ metadata.weatherSymbol }}</div>
|
||||
</div>
|
||||
<div class="fallingObject">
|
||||
<div>{{ metadata.weatherSymbol }}</div>
|
||||
</div>
|
||||
<div class="fallingObject">
|
||||
<div>{{ metadata.weatherSymbol }}</div>
|
||||
</div>
|
||||
<div class="fallingObject">
|
||||
<div>{{ metadata.weatherSymbol }}</div>
|
||||
</div>
|
||||
<div class="fallingObject">
|
||||
<div>{{ metadata.weatherSymbol }}</div>
|
||||
</div>
|
||||
<div class="fallingObject">
|
||||
<div>{{ metadata.weatherSymbol }}</div>
|
||||
</div>
|
||||
<div class="fallingObject">
|
||||
<div>{{ metadata.weatherSymbol }}</div>
|
||||
</div>
|
||||
<div class="fallingObject">
|
||||
<div>{{ metadata.weatherSymbol }}</div>
|
||||
</div>
|
||||
<div class="fallingObject">
|
||||
<div>{{ metadata.weatherSymbol }}</div>
|
||||
</div>
|
||||
<div class="fallingObject">
|
||||
<div>{{ metadata.weatherSymbol }}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const weather = document.getElementById("weather");
|
||||
const weatherToggle = document.getElementById("weatherToggle");
|
||||
const weatherPreference = localStorage.getItem("weather");
|
||||
|
||||
// Initial weather preference check on page load
|
||||
if (weatherPreference == 0) {
|
||||
weather.classList.add("hidden");
|
||||
weatherToggle.checked = false;
|
||||
} else {
|
||||
weather.classList.remove("hidden");
|
||||
weatherToggle.checked = true;
|
||||
};
|
||||
|
||||
// Handle weather setting toggle
|
||||
weatherToggle.addEventListener('change', function() {
|
||||
if (this.checked) {
|
||||
localStorage.setItem("weather", 1);
|
||||
weather.classList.remove("hidden");
|
||||
} else {
|
||||
localStorage.setItem("weather", 0);
|
||||
weather.classList.add("hidden");
|
||||
};
|
||||
});
|
||||
</script>
|
||||
<!-- /weather -->
|
||||
30
_includes/weatherController.njk
Normal file
30
_includes/weatherController.njk
Normal file
@@ -0,0 +1,30 @@
|
||||
<style>
|
||||
#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" checked />
|
||||
<label for="weatherToggle">Show weather?</label>
|
||||
</form>
|
||||
@@ -4,6 +4,10 @@ title: Nathan Upchurch | Changelog
|
||||
structuredData: none
|
||||
---
|
||||
# Changelog
|
||||
* 2025-11-9
|
||||
* Added [ThinksTooMuch](https://thinkstoomuch.net) to the [blogroll](/blogroll).
|
||||
* Updated [/incense](/incense).
|
||||
* Added snow / weather, and site settings button and dialog.
|
||||
* 2025-10-20
|
||||
* Added [Moist Poetry Journal](https://moistpoetryjournal.com) to the [blogroll](/blogroll).
|
||||
* Removed some less active and/or abandoned blogs from the [blogroll](/blogroll).
|
||||
|
||||
@@ -55,6 +55,7 @@ Incense making is hard. While parts of the world with strong incense cultures en
|
||||
### Other
|
||||
* [A list of archived URLs](https://web.archive.org/web/*/https://talesofincense.com/*) from a now-defunct site with some good information on Chinese incense.
|
||||
* [All of my writing on incense](/tags/incense/)
|
||||
* [Aromasublime Learning Center](https://www.aromasublime.com/news/category/key+articles++-+learning+center)—Articles on agarwood and agarwood oil.
|
||||
* [incensemakers.org](https://incensemakers.org/) is an invitation-only forum for relatively experienced incense makers. It is not incredibly active, but it does have a number of useful threads visible to non-members. If you are interested in joining, your best bet is to have an existing member you know personally get in touch with [me](/me) to provide a recommendation on your behalf.
|
||||
* See the [incense, fragrance, and perfumery section of my blogroll](/blogroll/#incense-fragrance-and-perfumery) for a list of blogs with writing on incense and related topics.
|
||||
|
||||
@@ -78,6 +79,7 @@ Incense making is hard. While parts of the world with strong incense cultures en
|
||||
* [Shoyeido Factory Works (YouTube)](https://www.youtube.com/watch?v=EQRxB4Gz-JM)
|
||||
* [The Frankincense Trail](https://www.imdb.com/title/tt2056414/)—Kate Humble follows the ancient frankincense trade route from Oman to Palestine. I have linked to the IMDB page, but this documentary series is well worth sailing the high seas for.
|
||||
* [*The Scent of Heaven: Inside Vietnam’s Incense Village* (YouTube)](https://www.youtube.com/watch?v=Wy8pDpIH31g)
|
||||
* [*'The Scent of Sakai' 堺の香り - Handmade incense stick craftsman* (YouTube)](https://www.youtube.com/watch?v=-4vOPSJYvX4)
|
||||
* [*Turf Peat Incense* (YouTube)](https://www.youtube.com/watch?v=4F7Xvdpq-GE)
|
||||
|
||||
## Reputable Suppliers of Aromatics
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
---
|
||||
title: Butterfly Spring Incense
|
||||
manufacturer: Lijiali
|
||||
date: 2025-10-28 12:07:00
|
||||
time: 12:07 PM
|
||||
---
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
---
|
||||
title: Green Kinam, AAA
|
||||
manufacturer: Yuzhi Oud
|
||||
date: 2025-11-03 11:41:00
|
||||
time: 11:41 AM
|
||||
---
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
---
|
||||
title: Palo Santo
|
||||
manufacturer: Some random shop
|
||||
date: 2025-11-05 14:37:00
|
||||
time: 2:37 PM
|
||||
---
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
---
|
||||
title: Some weird cedar, lavender, and orris composition I've been working on
|
||||
manufacturer: Myself
|
||||
date: 2025-11-03 9:33:00
|
||||
time: 9:33 AM
|
||||
---
|
||||
|
||||
@@ -193,10 +193,14 @@ export default async function (eleventyConfig) {
|
||||
);
|
||||
|
||||
// Passthrough
|
||||
|
||||
eleventyConfig
|
||||
.addPassthroughCopy({ "./public/": "/" })
|
||||
.addPassthroughCopy("./content/special/");
|
||||
.addPassthroughCopy("./content/special/")
|
||||
.addPassthroughCopy("./node_modules/@magenta/music/es6/core.js")
|
||||
.addPassthroughCopy(
|
||||
"./node_modules/html-midi-player/dist/midi-player.min.js",
|
||||
)
|
||||
.addPassthroughCopy("./node_modules/tone/build/Tone.js");
|
||||
|
||||
// Get the first `n` elements of a collection.
|
||||
eleventyConfig.addFilter("head", (array, n) => {
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
"mdfigcaption": "^0.1.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"html-midi-player": "^1.6.0",
|
||||
"markdown-it-container": "^4.0.0",
|
||||
"markdown-it-footnote": "^3.0.3",
|
||||
"markdown-it-image-figures": "^2.1.1",
|
||||
|
||||
@@ -183,7 +183,7 @@ html {
|
||||
input.answer {
|
||||
display: inline;
|
||||
}
|
||||
input:not(.answer),
|
||||
input:not(.answer):not(#weatherToggle),
|
||||
textarea {
|
||||
background-color: var(--background-color);
|
||||
border: var(--border-details);
|
||||
@@ -334,15 +334,17 @@ a {
|
||||
}
|
||||
footer {
|
||||
padding: var(--space-xl) 0 var(--space-m) 0;
|
||||
& p {
|
||||
font-size: var(--step-0);
|
||||
grid-column: var(--span-grid);
|
||||
margin-bottom: 0;
|
||||
}
|
||||
& .webring {
|
||||
display: inline;
|
||||
padding-right: var(--space-xs);
|
||||
}
|
||||
}
|
||||
footer .webring {
|
||||
display: inline;
|
||||
padding-right: var(--space-xs);
|
||||
}
|
||||
footer p {
|
||||
font-size: var(--step-0);
|
||||
grid-column: var(--span-grid);
|
||||
}
|
||||
|
||||
h1,
|
||||
h2,
|
||||
h3 {
|
||||
@@ -1051,6 +1053,18 @@ article.post {
|
||||
margin: var(--space-2xs) auto;
|
||||
}
|
||||
}
|
||||
#buttonsAndStuffContainer {
|
||||
display: flex;
|
||||
grid-column: var(--span-grid);
|
||||
width: 100%;
|
||||
& a,
|
||||
img,
|
||||
div {
|
||||
display: inline-block;
|
||||
height: var(--space-m-l);
|
||||
margin-right: var(--space-3xs);
|
||||
}
|
||||
}
|
||||
.gallery-images {
|
||||
display: flex;
|
||||
flex-flow: row wrap;
|
||||
@@ -1188,3 +1202,6 @@ dialog {
|
||||
gap: var(--grid-gutter);
|
||||
grid-template-columns: repeat(var(--grid-columns), 1fr);
|
||||
}
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
41
public/img/icons/breeze/story-editor.svg
Normal file
41
public/img/icons/breeze/story-editor.svg
Normal file
@@ -0,0 +1,41 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
viewBox="0 0 16 16"
|
||||
version="1.1"
|
||||
id="svg1"
|
||||
sodipodi:docname="story-editor.svg"
|
||||
inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<sodipodi:namedview
|
||||
id="namedview1"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#000000"
|
||||
borderopacity="0.25"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:zoom="57.0625"
|
||||
inkscape:cx="8"
|
||||
inkscape:cy="8"
|
||||
inkscape:window-width="2048"
|
||||
inkscape:window-height="1080"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg1" />
|
||||
<defs
|
||||
id="defs3051">
|
||||
<style
|
||||
type="text/css"
|
||||
id="current-color-scheme">.ColorScheme-Text { color: #fcfcfc; } </style>
|
||||
</defs>
|
||||
<path
|
||||
style="fill:#faf5f5;fill-opacity:1;stroke:none"
|
||||
d="M 3 2 L 3 14 L 7 14 L 7 13 L 4 13 L 4 5 L 12 5 L 12 7 L 13 7 L 13 2 L 12 2 L 12 4 L 11 4 L 11 2 L 5 2 L 5 4 L 4 4 L 4 2 L 3 2 z M 5 6 L 5 7 L 11 7 L 11 6 L 5 6 z M 5 8 L 5 9 L 8 9 L 8 8 L 5 8 z M 12 8 L 8 12 L 8 14 L 10 14 L 14 10 L 12 8 z M 11.689453 9.6894531 L 12.28125 10.28125 L 10.59375 11.96875 L 10.59375 11.984375 L 9.3125 13.28125 L 8.71875 12.6875 L 11.689453 9.6894531 z M 5 10 L 5 11 L 7 11 L 7 10 L 5 10 z "
|
||||
class="ColorScheme-Text"
|
||||
id="path1" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.6 KiB |
Reference in New Issue
Block a user