@@ -14,6 +14,97 @@ var ANIM_NAV_DELAY = 80; // --- seeded randomness --- // same picks all day, different tomorrow function dayHash(date) { var doy = Math.floor((date - new Date(date.getFullYear(), 0, 0)) / 86400000); return date.getFullYear() * 1000 + doy; } function seededRandom(seed) { var s = seed | 0; return function () { s = (s + 0x6D2B79F5) | 0; var t = Math.imul(s ^ (s >>> 15), 1 | s); t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t; return ((t ^ (t >>> 14)) >>> 0) / 4294967296; }; } function pickItems(list, count, rng) { if (list.length <= count) return list.slice(); var copy = list.slice(); var result = []; for (var i = 0; i < count; i++) { var idx = Math.floor(rng() * copy.length); result.push(copy[idx]); copy.splice(idx, 1); } return result; } function parseListItems(body) { var lines = body.split('\n'); var bullets = []; var prose = []; var inProse = false; var currentProse = ''; for (var i = 0; i < lines.length; i++) { var trimmed = lines[i].trim(); if (trimmed.match(/^- /)) { if (inProse && currentProse) { prose.push(currentProse.trim()); currentProse = ''; inProse = false; } bullets.push(trimmed.slice(2)); } else if (trimmed === '') { if (inProse && currentProse) { prose.push(currentProse.trim()); currentProse = ''; inProse = false; } } else { inProse = true; currentProse += (currentProse ? ' ' : '') + trimmed; } } if (inProse && currentProse) { prose.push(currentProse.trim()); } return { bullets: bullets, prose: prose }; } function highlightText(text) { // split into sentence fragments on ". " boundaries var fragments = text.split(/(?<=\.)\s+/); return fragments.map(function (frag) { var trimmed = frag.trim(); if (!trimmed) return ''; var words = trimmed.split(/\s+/); // short fragments (4 words or fewer): bold the whole thing if (words.length <= 4) { return '<strong>' + trimmed + '</strong>'; } // if there's an early comma, bold up to it var comma = trimmed.indexOf(','); if (comma > 0 && comma < 30) { return '<strong>' + trimmed.slice(0, comma) + '</strong>' + trimmed.slice(comma); } // otherwise bold the first 2-3 words (3 if first word is an article/conjunction) var count = /^(the|a|an|if|when|it|and|or|but|do|in)$/i.test(words[0]) ? 3 : 2; count = Math.min(count, words.length); return '<strong>' + words.slice(0, count).join(' ') + '</strong> ' + words.slice(count).join(' '); }).join(' '); } // --- time and season --- var SEASONS = [
@@ -73,39 +164,39 @@ var HAIKU = { 'winter': [ { lines: ['the winter stillness\na woodpecker searching through\nthe hollow silence'], author: 'dark furrow' }, { lines: ['bare frozen furrows\nhold the memory of seed\nbeneath the long dark'], author: 'dark furrow' }, { lines: ['woodsmoke ascending\nthrough the grey unmoving sky\nthe kettle whistles'], author: 'dark furrow' } { lines: ['the winter stillness\na woodpecker searching through\nthe hollow silence'] }, { lines: ['bare frozen furrows\nhold the memory of seed\nbeneath the long dark'] }, { lines: ['woodsmoke ascending\nthrough the grey unmoving sky\nthe kettle whistles'] } ], 'early-spring': [ { lines: ['the old dark furrow\nfills with rain and waits for warmth\nsomething stirs below'], author: 'dark furrow' }, { lines: ['cold mud on my hands\nthe first row planted before\nthe sparrows arrive'], author: 'dark furrow' }, { lines: ['fog lifts from the creek\nrevealing green where there was\nnothing just last week'], author: 'dark furrow' } { lines: ['the old dark furrow\nfills with rain and waits for warmth\nsomething stirs below'] }, { lines: ['cold mud on my hands\nthe first row planted before\nthe sparrows arrive'] }, { lines: ['fog lifts from the creek\nrevealing green where there was\nnothing just last week'] } ], 'late-spring': [ { lines: ['petals on the path\nthe bees have already found\nwhat i just planted'], author: 'dark furrow' }, { lines: ['warm rain after dawn\nthe lettuce grows so quickly\ni cannot keep up'], author: 'dark furrow' }, { lines: ['the frogs resume their\nevening argument like\nold familiar friends'], author: 'dark furrow' } { lines: ['petals on the path\nthe bees have already found\nwhat i just planted'] }, { lines: ['warm rain after dawn\nthe lettuce grows so quickly\ni cannot keep up'] }, { lines: ['the frogs resume their\nevening argument like\nold familiar friends'] } ], 'early-summer': [ { lines: ['cicadas tuning\ntheir one long note in the oaks\nthe heat has arrived'], author: 'dark furrow' }, { lines: ['the tomato vine\nclimbs past the stake i gave it\nreaching for the sun'], author: 'dark furrow' }, { lines: ['lightning bugs at dusk\neach one a small question asked\nthen answered in dark'], author: 'dark furrow' } { lines: ['cicadas tuning\ntheir one long note in the oaks\nthe heat has arrived'] }, { lines: ['the tomato vine\nclimbs past the stake i gave it\nreaching for the sun'] }, { lines: ['lightning bugs at dusk\neach one a small question asked\nthen answered in dark'] } ], 'midsummer': [ { lines: ['the garden gives more\nthan i can carry inside\nthe table overflows'], author: 'dark furrow' }, { lines: ['shade beneath the oak\nthe only cool place to sit\nthe dog already knows'], author: 'dark furrow' }, { lines: ['thunder in the west\nthe corn stands perfectly still\nwaiting for the rain'], author: 'dark furrow' } { lines: ['the garden gives more\nthan i can carry inside\nthe table overflows'] }, { lines: ['shade beneath the oak\nthe only cool place to sit\nthe dog already knows'] }, { lines: ['thunder in the west\nthe corn stands perfectly still\nwaiting for the rain'] } ], 'early-fall': [ { lines: ['the first cool morning\ni can see my breath again\nthe garden exhales'], author: 'dark furrow' }, { lines: ['one red leaf falling\nthrough the still september air\nlanding in my palm'], author: 'dark furrow' }, { lines: ['the garlic goes in\nan act of faith in the dark\nsee you in the spring'], author: 'dark furrow' } { lines: ['the first cool morning\ni can see my breath again\nthe garden exhales'] }, { lines: ['one red leaf falling\nthrough the still september air\nlanding in my palm'] }, { lines: ['the garlic goes in\nan act of faith in the dark\nsee you in the spring'] } ], 'late-fall': [ { lines: ['bare branch on bare branch\nthe crow arrives without sound\nthe sky turns away'], author: 'dark furrow' }, { lines: ['the last harvest done\ni clean the blade and hang it\non its proper nail'], author: 'dark furrow' }, { lines: ['wind through empty stalks\nplaying the garden like some\nforgotten instrument'], author: 'dark furrow' } { lines: ['bare branch on bare branch\nthe crow arrives without sound\nthe sky turns away'] }, { lines: ['the last harvest done\ni clean the blade and hang it\non its proper nail'] }, { lines: ['wind through empty stalks\nplaying the garden like some\nforgotten instrument'] } ] };
@@ -263,7 +354,7 @@ document.body.setAttribute('data-time', time); document.body.setAttribute('data-season', season.name); // sky layer: season color wash, stronger for the hero // sky layer: season color wash var sky = document.getElementById('sky-layer'); if (sky) { sky.style.background =
@@ -272,14 +363,13 @@ 'radial-gradient(ellipse at 50% 50%, rgba(' + s.tint + ',0.08) 0%, transparent 70%)'; } // time layer: light source shining down, covering the hero viewport // time layer: light source var timeEl = document.getElementById('time-layer'); if (timeEl) { timeEl.style.background = TIME_LIGHTS[time] || TIME_LIGHTS.morning; } } // the light source — stronger now, covering the hero var TIME_LIGHTS = { night: 'linear-gradient(to bottom, rgba(100,120,180,0.15) 0%, rgba(100,120,180,0.05) 30%, transparent 70%)',
@@ -334,10 +424,13 @@ return h + 'h ' + m + 'm'; } function moonGlyph(phase) { var name = moonName(phase); var illum = Math.round(moonIllumination(phase) * 100); return name + ', ' + illum + '%'; function formatClock(hours) { var h = Math.floor(hours); var m = Math.round((hours - h) * 60); if (m === 60) { h += 1; m = 0; } var suffix = h >= 12 ? 'pm' : 'am'; var display = h > 12 ? h - 12 : (h === 0 ? 12 : h); return display + ':' + (m < 10 ? '0' : '') + m + ' ' + suffix; } var MONTHS = ['january','february','march','april','may','june',
@@ -389,27 +482,28 @@ var sunrise = 12 - hours / 2; var sunset = 12 + hours / 2; var boldName = '<strong>' + name + '</strong>'; var lines = []; if (time === 'night') { lines.push('the moon is ' + name + ', ' + illum + '% lit.'); lines.push('the moon is ' + boldName + ', ' + illum + '% lit.'); lines.push('the world is turned away from the sun.'); lines.push(formatHM(hours) + ' of daylight today. ' + sign + gained + ' minutes from yesterday.'); lines.push('<strong>' + formatHM(hours) + '</strong> of daylight today. ' + sign + gained + ' minutes from yesterday.'); } else if (time === 'dawn') { lines.push('the sun rises around ' + formatHM(sunrise) + '.'); lines.push('the moon is ' + name + ', ' + illum + '% lit.'); lines.push(formatHM(hours) + ' of daylight ahead. it sets around ' + formatHM(sunset) + '.'); lines.push('the sun rises around <strong>' + formatClock(sunrise) + '</strong>.'); lines.push('the moon is ' + boldName + ', ' + illum + '% lit.'); lines.push('<strong>' + formatHM(hours) + '</strong> of daylight ahead. it sets around ' + formatClock(sunset) + '.'); } else if (time === 'evening') { lines.push('the sun set around ' + formatHM(sunset) + '.'); lines.push('the moon is ' + name + ', ' + illum + '% lit.'); lines.push('there were ' + formatHM(hours) + ' of daylight today. ' + sign + gained + ' minutes from yesterday.'); lines.push('the sun set around <strong>' + formatClock(sunset) + '</strong>.'); lines.push('the moon is ' + boldName + ', ' + illum + '% lit.'); lines.push('there were <strong>' + formatHM(hours) + '</strong> of daylight today. ' + sign + gained + ' minutes from yesterday.'); } else { lines.push('the moon is ' + name + ', ' + illum + '% lit.'); lines.push('the sun rose around ' + formatHM(sunrise) + ' and sets around ' + formatHM(sunset) + '.'); lines.push(formatHM(hours) + ' of daylight today. ' + sign + gained + ' minutes from yesterday.'); lines.push('the moon is ' + boldName + ', ' + illum + '% lit.'); lines.push('the sun rose around <strong>' + formatClock(sunrise) + '</strong> and sets around <strong>' + formatClock(sunset) + '</strong>.'); lines.push('<strong>' + formatHM(hours) + '</strong> of daylight today. ' + sign + gained + ' minutes from yesterday.'); } return lines.join('\n'); return lines.join('<br>'); }
@@ -417,20 +511,20 @@ function moonGardenTip(phase) { if (phase < 3.7) return 'the moon is dark. this is a time for rest and planning. prepare beds, amend soil, but do not plant. the old farmers said nothing wants to start in the dark.'; return 'the moon is dark. this is a time for <strong>rest and planning</strong>. prepare beds, amend soil, but do not plant. the old farmers said nothing wants to start in the dark.'; if (phase < 7.4) return 'the moon is waxing. plant leafy things: lettuce, spinach, cabbage, herbs that grow above ground. the light is growing and pulls the energy upward.'; return 'the moon is waxing. <strong>plant leafy things</strong>: lettuce, spinach, cabbage, herbs that grow above ground. the light is growing and pulls the energy upward.'; if (phase < 11.1) return 'the moon is in its first quarter. plant things that fruit: tomatoes, peppers, beans, squash. the increasing light favors strong stems and heavy fruit.'; return 'the moon is in its first quarter. <strong>plant things that fruit</strong>: tomatoes, peppers, beans, squash. the increasing light favors strong stems and heavy fruit.'; if (phase < 14.8) return 'the moon is nearly full. transplant, fertilize, graft. the light is strongest and the sap is rising. a good time to move plants and feed the soil.'; return 'the moon is nearly full. <strong>transplant, fertilize, graft</strong>. the light is strongest and the sap is rising. a good time to move plants and feed the soil.'; if (phase < 18.5) return 'the moon is full. plant root crops: carrots, potatoes, beets, onions, garlic. the energy is pulling downward now. bulbs and perennials go in well under a full moon.'; return 'the moon is full. <strong>plant root crops</strong>: carrots, potatoes, beets, onions, garlic. the energy is pulling downward now. bulbs and perennials go in well under a full moon.'; if (phase < 22.1) return 'the moon is waning. harvest what is ready, cut herbs for drying, prune what needs shaping. the energy is drawing inward. what you cut now heals faster.'; return 'the moon is waning. <strong>harvest what is ready</strong>, cut herbs for drying, prune what needs shaping. the energy is drawing inward. what you cut now heals faster.'; if (phase < 25.8) return 'the moon is in its last quarter. pull weeds, turn compost, cultivate the soil. this is a killing time, good for destroying what you do not want. the weeds will not come back as fast.'; return 'the moon is a thin crescent, almost gone. do not plant. rest, clean tools, plan the next cycle. the old almanacs left these days blank on purpose.'; return 'the moon is in its last quarter. <strong>pull weeds, turn compost</strong>, cultivate the soil. this is a killing time, good for destroying what you do not want. the weeds will not come back as fast.'; return 'the moon is a thin crescent, almost gone. <strong>do not plant</strong>. rest, clean tools, plan the next cycle. the old almanacs left these days blank on purpose.'; }
@@ -479,11 +573,11 @@ function revealWords(root) { if (!root) return; var elements = root.querySelectorAll('h2, p, li, blockquote, cite, .moon-glyph'); var elements = root.querySelectorAll('h2, p, li, blockquote'); var allItems = []; elements.forEach(function (el) { if (el.tagName === 'LI' || el.tagName === 'BLOCKQUOTE' || el.tagName === 'CITE' || el.classList.contains('moon-glyph')) { if (el.tagName === 'LI' || el.tagName === 'BLOCKQUOTE') { allItems.push(el); return; }
@@ -502,8 +596,26 @@ allItems.push(span); } }); } else { nodes.push(node.cloneNode(true)); } else if (node.nodeType === 1) { // for child elements like <strong>, split their text into word spans too var wrapper = document.createElement(node.tagName.toLowerCase()); // copy attributes for (var a = 0; a < node.attributes.length; a++) { wrapper.setAttribute(node.attributes[a].name, node.attributes[a].value); } var innerText = node.textContent || ''; innerText.split(/(\s+)/).forEach(function (w) { if (/^\s*$/.test(w)) { wrapper.appendChild(document.createTextNode(w)); } else { var span = document.createElement('span'); span.className = 'word'; span.textContent = w; wrapper.appendChild(span); allItems.push(span); } }); nodes.push(wrapper); } }); el.textContent = '';
@@ -532,18 +644,14 @@ dom.dateLine = document.querySelector('.date-line'); dom.seasonName = document.querySelector('.season-name'); dom.seasonNote = document.querySelector('.season-note'); dom.haikuBlock = document.querySelector('.hero-haiku blockquote'); dom.haikuCite = document.querySelector('.hero-haiku cite'); dom.moonGlyph = document.querySelector('.moon-glyph'); dom.haikuBlock = document.querySelector('.flow-haiku blockquote'); dom.moonGardenTip = document.querySelector('.moon-garden-tip'); dom.weatherMoodText = document.querySelector('.weather-mood-text'); dom.skyData = document.querySelector('.sky-data'); dom.glossaryNote = document.querySelector('.glossary-note'); dom.footerP = document.querySelector('footer p'); dom.wisdom = document.querySelector('.wisdom'); dom.almanac = document.querySelector('.glossary-entries'); dom.hero = document.querySelector('.hero'); dom.glossary = document.querySelector('.glossary'); dom.flowEntries = document.querySelector('.flow-entries'); dom.readout = document.querySelector('.readout'); dom.footer = document.querySelector('footer'); dom.seasonsNav = document.querySelector('.seasons-nav'); dom.timesNav = document.querySelector('.times-nav');
@@ -579,36 +687,32 @@ dom.haikuBlock.innerHTML = haikuLines.map(function (l) { return '<span class="haiku-line">' + l + '</span>'; }).join(''); dom.haikuCite.textContent = '— ' + haiku.author; } // moon glyph — large, standalone // moon gardening tip (now with bold highlights) var phase = moonPhase(now); dom.moonGlyph.textContent = moonGlyph(phase); // moon gardening tip dom.moonGardenTip.textContent = moonGardenTip(phase); dom.moonGardenTip.innerHTML = moonGardenTip(phase); // weather mood dom.weatherMoodText.textContent = getWeatherMood(season, contentTime); // sky data dom.skyData.innerHTML = skyText(now, contentTime).replace(/\n/g, '<br>'); // glossary note dom.glossaryNote.textContent = 'what the ' + contentTime + ' brings'; // sky data (now with bold highlights) dom.skyData.innerHTML = skyText(now, contentTime); // footer countdown dom.footerP.textContent = next.days + ' days until ' + next.label + ' \u00b7 zone 7a \u00b7 north carolina'; // crossfade: fade out content areas, then rebuild var fadeTargets = ['.hero-grid', '.hero-lower', '.wisdom', '.glossary-entries', 'footer']; // fade out content areas, then rebuild var fadeTargets = ['.flow-season', '.flow-sky', '.flow-haiku', '.wisdom', '.flow-entries', 'footer']; fadeTargets.forEach(function (sel) { var el = document.querySelector(sel); if (el) el.style.opacity = '0'; }); // seed the random number generator for today var rng = seededRandom(dayHash(now)); // fetch or use cached manifest var p = cachedManifest ? Promise.resolve(cachedManifest)
@@ -641,45 +745,63 @@ }) .then(function (entries) { dom.wisdom.innerHTML = ''; dom.almanac.innerHTML = ''; dom.flowEntries.innerHTML = ''; // collect all fragments into one flowing narrative var fragments = []; // wisdom lines entries.forEach(function (entry) { var div = document.createElement('div'); div.className = 'entry'; var h2 = document.createElement('h2'); h2.textContent = entry.meta.section || ''; div.appendChild(h2); var content = document.createElement('div'); content.innerHTML = renderMarkdown(entry.body); div.appendChild(content); var hasLists = content.querySelector('ul'); var hasParagraphs = content.querySelector('p'); if (hasLists && hasParagraphs) { div.setAttribute('data-content-type', 'mixed'); } else if (hasParagraphs && !hasLists) { div.setAttribute('data-content-type', 'prose'); } else { div.setAttribute('data-content-type', 'list'); if (!entry.meta.time) return; var lines = entry.body.split('\n').map(function (l) { return l.trim(); }).filter(function (l) { return l.length > 0; }); if (lines.length === 0) return; var picks = pickItems(lines, Math.min(2, lines.length), rng); picks.forEach(function (line) { fragments.push(line); }); }); // seasonal entries: pick 1 item from each category entries.forEach(function (entry) { if (entry.meta.time) return; var parsed = parseListItems(entry.body); if (parsed.bullets.length > 0) { var picks = pickItems(parsed.bullets, 1, rng); picks.forEach(function (item) { fragments.push(item); }); } if (entry.meta.time) { dom.wisdom.appendChild(div); } else { dom.almanac.appendChild(div); if (parsed.prose.length > 0) { var prosePick = pickItems(parsed.prose, 1, rng); fragments.push(prosePick[0]); } }); // shuffle all fragments together for a natural mixed read for (var i = fragments.length - 1; i > 0; i--) { var j = Math.floor(rng() * (i + 1)); var tmp = fragments[i]; fragments[i] = fragments[j]; fragments[j] = tmp; } // compose into flowing paragraphs, ~3-4 fragments each var SEP = ' <span class="sep">\u2767</span> '; var chunkSize = Math.min(4, Math.ceil(fragments.length / 2)); for (var c = 0; c < fragments.length; c += chunkSize) { var chunk = fragments.slice(c, c + chunkSize); var html = chunk.map(function (f) { return highlightText(f); }).join(SEP); var p = document.createElement('p'); p.className = 'narrative'; p.innerHTML = html; dom.flowEntries.appendChild(p); } // fade in and reveal fadeTargets.forEach(function (sel) { var el = document.querySelector(sel); if (el) el.style.opacity = '1'; }); revealWords(dom.hero); revealWords(dom.glossary); revealWords(dom.readout); revealWords(dom.footer); // update navs
@@ -687,7 +809,7 @@ updateTimeNav(contentTime); }) .catch(function () { dom.almanac.innerHTML = '<p style="color:var(--ash);font-style:italic;text-align:center;">the pages could not be found. try again in a moment.</p>'; dom.flowEntries.innerHTML = '<p style="color:var(--ash);font-style:italic;">the pages could not be found. try again in a moment.</p>'; fadeTargets.forEach(function (sel) { var el = document.querySelector(sel); if (el) el.style.opacity = '1';
@@ -12,10 +12,9 @@ --under2: rgba(42,36,32,0.5); --under3: rgba(26,23,20,0.4); --type-hero-title: clamp(3.2rem, 5vw + 1rem, 5rem); --type-hero-season: clamp(2.2rem, 3vw + 0.8rem, 3.2rem); --type-hero-body: clamp(0.95rem, 0.8vw + 0.6rem, 1.05rem); --type-hero-label: 0.85rem; --type-title: clamp(2.8rem, 4vw + 1rem, 4.2rem); --type-season: clamp(1.6rem, 2vw + 0.6rem, 2rem); --type-body: clamp(0.95rem, 0.8vw + 0.6rem, 1.05rem);}* {
@@ -32,7 +31,7 @@ body { background-color: var(--earth); color: var(--bone); font-family: Georgia, 'Times New Roman', serif; line-height: 1.7; line-height: 1.8; -webkit-font-smoothing: antialiased; transition: background-color 2s ease, color 2s ease;}
@@ -42,490 +41,267 @@ main {}/* ===== HERO ===== *//* ===== READOUT ===== */.hero { min-height: 100vh; min-height: 100dvh; display: flex; flex-direction: column; justify-content: center; padding: 4rem 3rem 3rem; position: relative; max-width: 72rem;.readout { max-width: 34rem; margin: 0 auto; padding: 4rem 1.5rem 2rem;}.hero-header { margin-bottom: 2.5rem;/* --- header --- */.readout-header { margin-bottom: 3rem;}.hero-header::after {.readout-header::after { content: ''; display: block; width: 4rem; width: 3rem; height: 1px; background: var(--bark); margin-top: 2rem; opacity: 0.6; margin-top: 1.5rem; opacity: 0.5;}.hero-header h1 { font-size: var(--type-hero-title);.readout-header h1 { font-size: var(--type-title); font-weight: 400; letter-spacing: 0.03em; color: var(--parchment); line-height: 1.1; text-shadow: 0 -2px 40px var(--glow);}.subtitle { font-style: italic; color: var(--ash); font-size: 1rem; margin-top: 0.4rem; font-style: italic; font-size: var(--type-body); margin-top: 0.3rem; animation: breathe 8s ease-in-out infinite;}/* --- hero grid --- *//* --- date line --- */.hero-grid { display: grid; grid-template-columns: 1.2fr 1fr 1fr; gap: 2rem 3rem; align-items: start; margin-top: 2rem;.date-line { color: var(--ash); font-size: var(--type-body); font-style: italic; letter-spacing: 0.02em; margin-bottom: 1.5rem;}.hero-lower { display: grid; grid-template-columns: 1fr 1fr; gap: 2rem 4rem; align-items: start; margin-top: 2.5rem;}.hero-cell {/* ===== FLOW SECTIONS ===== *//* consistent spacing and typography throughout */.flow { margin-bottom: 2.5rem; transition: opacity 0.4s ease;}/* --- hero elements --- */.date-line { color: var(--ash); font-size: 0.88rem; font-style: italic; letter-spacing: 0.03em; margin-bottom: 1.5rem; opacity: 0.8;}/* --- season --- */.season-name { font-size: var(--type-hero-season); font-size: var(--type-season); font-weight: 400; color: var(--sprout); letter-spacing: 0.02em; line-height: 1.2; animation: sway 6s ease-in-out infinite; transform-origin: left center; line-height: 1.3; transition: color 2s ease;}.moon-glyph { display: block; font-size: 1.1rem; font-style: italic; line-height: 1.4; margin-bottom: 1rem; color: var(--bone);}.moon-garden-tip {.season-note { color: var(--ash); font-style: italic; font-size: 0.9rem; font-size: var(--type-body); line-height: 1.8; margin-top: 0.6rem;}.hero-sky h2,.hero-mood h2 { font-size: var(--type-hero-label); font-weight: 400; color: var(--ember); letter-spacing: 0.02em; margin-bottom: 0.6rem; transition: color 2s ease;}.sky-data { color: var(--bone); font-size: var(--type-hero-body);/* --- sky (weather + celestial + moon tip) --- */.flow-sky p { font-size: var(--type-body); line-height: 1.9;}.weather-mood-text { color: var(--ash); color: var(--bone); font-style: italic; font-size: var(--type-hero-body); line-height: 1.9; margin-bottom: 1rem;}.season-note {.sky-data { color: var(--bone);}.moon-garden-tip { color: var(--ash); font-style: italic; font-size: 0.92rem; line-height: 1.8; margin-top: 0.8rem; margin-top: 1rem;}/* --- haiku --- */.hero-haiku { display: flex; flex-direction: column; justify-content: center; padding-top: 1rem;.flow-haiku { text-align: center;}.hero-haiku blockquote {.flow-haiku blockquote { display: inline-block; text-align: left; color: var(--ash); font-style: italic; font-size: 1.1rem; line-height: 2; font-size: var(--type-body); line-height: 2.2; letter-spacing: 0.02em; opacity: 0; animation: word-in 0.3s ease-out forwards;}.hero-haiku .haiku-line {.flow-haiku .haiku-line { display: block; white-space: nowrap;}.hero-haiku .haiku-line:nth-child(2) {.flow-haiku .haiku-line:nth-child(2) { padding-left: 1.2rem;}.hero-haiku .haiku-line:nth-child(3) {.flow-haiku .haiku-line:nth-child(3) { padding-left: 2.4rem;}.hero-haiku cite { display: block; margin-top: 0.5rem; color: var(--bark); font-size: 0.72rem; font-style: normal; letter-spacing: 0.04em;}/* --- wisdom (time-based, in hero) --- *//* --- wisdom (merged into narrative) --- */.wisdom { margin-top: 2.5rem; transition: opacity 0.4s ease; display: none;}.wisdom .entry h2 { font-size: var(--type-hero-label); font-weight: 400; color: var(--ember); letter-spacing: 0.02em; margin-bottom: 0.6rem; transition: color 2s ease;}.wisdom .entry p,.wisdom .entry div { color: var(--bone); font-size: var(--type-hero-body); line-height: 1.9;}/* --- seasons nav --- */.seasons-nav { display: flex; flex-wrap: wrap; gap: 0.2rem 0.5rem; margin-top: 2.5rem;}/* ===== NARRATIVE (curated items) ===== */.seasons-nav a { color: var(--ash); text-decoration: none; font-size: 0.8rem; font-style: italic; letter-spacing: 0.02em; padding: 0.15rem 0; transition: color 0.6s ease; cursor: pointer; opacity: 0; animation: word-in 0.4s ease-out forwards;.flow-entries { transition: opacity 0.4s ease;}.seasons-nav a:hover {.narrative { color: var(--bone); font-size: var(--type-body); line-height: 2; margin-bottom: 1.5rem;}.seasons-nav a.active { color: var(--sprout); text-decoration: underline; text-underline-offset: 3px;}.seasons-nav a:focus-visible,.times-nav a:focus-visible { outline: 1px solid var(--ember); outline-offset: 2px;.narrative:last-child { margin-bottom: 0;}.seasons-nav a.return-now {.sep { color: var(--ember); flex-basis: 100%;}.seasons-nav a::after { content: '\00b7'; color: var(--ash); margin-left: 0.4rem; opacity: 0.5;}.seasons-nav a:last-child::after { content: '';}/* --- scroll cue --- */.scroll-cue { position: absolute; bottom: 2rem; left: 50%; transform: translateX(-50%); width: 1px; height: 2.5rem; background: linear-gradient(to bottom, var(--ash), transparent); animation: drift 3s ease-in-out infinite; opacity: 0.4; margin: 0 0.2em; font-style: normal;}/* ===== GLOSSARY ===== *//* --- bold highlights for scanning --- */.glossary { position: relative; z-index: 10000; background: var(--earth); margin: 0 auto; padding: 8rem 2rem 6rem; transition: background-color 2s ease;}.glossary-header { max-width: 56rem; margin: 0 auto 2rem; text-align: center; padding-bottom: 2rem; border-bottom: 1px solid var(--bark);}.glossary-note { color: var(--ash); font-style: italic; font-size: 1.1rem; letter-spacing: 0.02em;.readout strong { color: var(--parchment); font-weight: 600;}/* --- time-of-day nav --- *//* ===== NAV STRIPS ===== */.times-nav { max-width: 40rem; margin: 0 auto 4rem;.nav-strip { display: flex; flex-wrap: wrap; justify-content: center; gap: 0.2rem 0.5rem; margin-top: 1.5rem; opacity: 0.3; transition: opacity 0.6s ease;}.nav-strip:hover,.nav-strip:focus-within { opacity: 0.7;}.times-nav a {.nav-strip a { color: var(--ash); text-decoration: none; font-size: 0.85rem; font-size: 0.75rem; font-style: italic; letter-spacing: 0.02em; padding: 0.15rem 0.3rem; padding: 0.15rem 0; transition: color 0.6s ease; cursor: pointer; opacity: 0; animation: word-in 0.4s ease-out forwards;}.times-nav a:hover {.nav-strip a:hover { color: var(--bone);}.times-nav a.active {.nav-strip a.active { color: var(--sprout); text-decoration: underline; text-underline-offset: 3px; text-decoration-skip-ink: auto;}.times-nav a.return-now { color: var(--ember); flex-basis: 100%; text-align: center; margin-top: 0.3rem;}.times-nav a::after { content: '\00b7'; color: var(--ash); margin-left: 0.4rem; opacity: 0.5;}.times-nav a:last-child::after,.times-nav a.return-now::after { content: '';}/* --- glossary entries --- */.glossary-entries { max-width: 40rem; margin: 0 auto; transition: opacity 0.4s ease;.nav-strip a.active::after { text-decoration: none; display: inline-block;}.glossary-entries .entry { margin-bottom: 4rem;.nav-strip a:focus-visible { outline: 1px solid var(--ember); outline-offset: 2px;}.glossary-entries .entry h2 { font-size: 1.15rem; font-weight: 400;.nav-strip a.return-now { color: var(--ember); letter-spacing: 0.02em; margin-bottom: 1.5rem; transition: color 2s ease;}.glossary-entries .entry p,.glossary-entries .entry > div { color: var(--bone); font-size: 0.95rem; line-height: 1.9;}.glossary-entries .entry ul { list-style: none; padding: 0;}.glossary-entries .entry ul li { color: var(--bone); font-size: 0.95rem; line-height: 1.85; padding-left: 1.2rem; position: relative; opacity: 0; animation: word-in 0.3s ease-out forwards;}.glossary-entries .entry ul li + li { margin-top: 0.4rem; flex-basis: 100%;}.glossary-entries .entry ul li::before {.nav-strip a::after { content: '\00b7'; position: absolute; left: 0; color: var(--sprout); font-weight: 500; animation: rustle 4s ease-in-out infinite; transition: color 2s ease;}.glossary-entries .entry ul li:nth-child(2n)::before { animation-delay: -1.3s; }.glossary-entries .entry ul li:nth-child(3n)::before { animation-delay: -2.7s; }.glossary-entries .entry ul li:nth-child(5n)::before { animation-delay: -0.6s; }.glossary-entries .entry p + p { margin-top: 0.6rem;}/* --- prose entries --- */.glossary-entries .entry[data-content-type="prose"] { text-align: center; padding: 2rem 0;}.glossary-entries .entry[data-content-type="prose"] p { font-style: italic; font-size: 1rem; line-height: 2.1; color: var(--ash); margin-left: 0.4rem; opacity: 0.4;}/* --- mixed entries (list + closing prose) --- */.glossary-entries .entry[data-content-type="mixed"] > div > p { margin-top: 1.2rem; padding-top: 1rem; border-top: 1px solid rgba(42,36,32,0.3); font-style: italic; color: var(--ash); font-size: 0.92rem; line-height: 2;}/* --- wisdom entry list items (in hero) --- */.wisdom .entry ul { list-style: none; padding: 0;.nav-strip a:last-child::after,.nav-strip a.return-now::after { content: '';}.wisdom .entry ul li { color: var(--bone); font-size: var(--type-hero-body); line-height: 1.9; padding-left: 1.2rem; position: relative; opacity: 0; animation: word-in 0.3s ease-out forwards;.times-nav { justify-content: flex-start;}.wisdom .entry ul li::before { content: '\00b7'; position: absolute; left: 0; color: var(--sprout); font-weight: 500; animation: rustle 4s ease-in-out infinite; transition: color 2s ease;.times-nav a.return-now { text-align: left; margin-top: 0.3rem;}/* ===== FOOTER ===== */footer { position: relative; z-index: 10000; background: var(--earth); padding: 3rem 2rem 4rem; max-width: 34rem; margin: 0 auto; padding: 2.5rem 1.5rem 3rem; text-align: center; border-top: 1px solid var(--bark); transition: opacity 0.4s ease, background-color 2s ease;
@@ -533,9 +309,9 @@ footer {footer p { color: var(--ash); font-size: 0.82rem; font-size: 0.8rem; font-style: italic; letter-spacing: 0.04em; letter-spacing: 0.03em;}
@@ -603,18 +379,6 @@ footer p { 70% { transform: translateX(-1px); }}@keyframes rustle { 0%, 100% { transform: translateX(0) scale(1); opacity: 0.8; } 25% { transform: translateX(2px) scale(1.3); opacity: 1; } 50% { transform: translateX(-1px) scale(0.9); opacity: 0.6; } 75% { transform: translateX(1px) scale(1.1); opacity: 0.9; }}@keyframes drift { 0%, 100% { opacity: 0.3; transform: translateX(-50%) translateY(0); } 50% { opacity: 0.6; transform: translateX(-50%) translateY(6px); }}@media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation-duration: 0.01ms !important;
@@ -625,47 +389,13 @@ footer p {/* ===== RESPONSIVE ===== */@media (max-width: 768px) { .hero { min-height: 110vh; min-height: 110dvh; padding: 3rem 1.5rem 3rem; } .hero-grid { grid-template-columns: 1fr; gap: 2rem 0; } .hero-haiku { padding-top: 0; } .hero-lower { grid-template-columns: 1fr; gap: 2rem 0; } .glossary-entries { max-width: 100%; }}@media (max-width: 480px) { html { font-size: 16px; } .hero { padding: 2.5rem 1.2rem 3rem; } .hero-header h1 { font-size: 3rem; } .glossary { padding: 5rem 1rem 5rem; .readout { padding: 2.5rem 1.2rem 2rem; } footer {