heartwood every commit a ring

the page becomes a quiet readout

520a6419 by Isaac Bythewood · 1 month ago

the page becomes a quiet readout

replace grid layout with a single flowing column. curate one item
per category with day-seeded randomness instead of showing everything.
weave fragments into narrative paragraphs joined by floral separators.
bold key phrases for scanning. unify typography to two sizes. merge
weather mood into the sky section. center the haiku. mute the navigation.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
modified site/almanac.js
@@ -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';
modified site/index.html
@@ -37,58 +37,36 @@  <div id="time-layer"></div>  <main>    <article class="hero">    <article class="readout">      <p class="date-line"></p>      <header class="hero-header">      <header class="readout-header">        <h1>dark furrow</h1>        <p class="subtitle">old knowledge preserved</p>      </header>      <div class="hero-grid">        <div class="hero-cell hero-date">          <p class="season-name"></p>          <p class="season-note"></p>        </div>      <section class="flow flow-season">        <p class="season-name"></p>        <p class="season-note"></p>      </section>        <div class="hero-cell hero-moon">          <span class="moon-glyph"></span>          <p class="moon-garden-tip"></p>        </div>      <section class="flow flow-sky">        <p class="weather-mood-text"></p>        <p class="sky-data"></p>        <p class="moon-garden-tip"></p>      </section>        <div class="hero-cell hero-haiku">          <blockquote></blockquote>          <cite></cite>        </div>      </div>      <div class="hero-lower">        <div class="hero-cell hero-sky">          <h2>what the sky is doing</h2>          <p class="sky-data"></p>        </div>        <div class="hero-cell hero-mood">          <h2>the air today</h2>          <p class="weather-mood-text"></p>        </div>      </div>      <section class="flow flow-haiku">        <blockquote></blockquote>      </section>      <section class="wisdom"></section>      <nav class="seasons-nav"></nav>      <div class="scroll-cue" aria-hidden="true"></div>    </article>      <section class="flow flow-entries"></section>    <section class="glossary">      <header class="glossary-header">        <p class="glossary-note"></p>      </header>      <nav class="times-nav"></nav>      <div class="glossary-entries almanac"></div>    </section>      <nav class="nav-strip seasons-nav"></nav>      <nav class="nav-strip times-nav"></nav>    </article>    <footer>      <p>zone 7a &middot; north carolina &middot; tended by hand</p>
modified site/style.css
@@ -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 {