heartwood every commit a ring

the page learns to breathe

f2aee786 by Isaac Bythewood · 1 month ago

the page learns to breathe

season-aware background, time-of-day light, haiku, bugs, weather
moods, moon phases, written dates, crossfade transitions, word
reveal for everything, entry dividers, metadata. borders removed.
the old moving shapes removed. what remains is quieter and true.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
modified site/almanac.js
@@ -53,28 +53,233 @@  }  // --- haiku ---  // real poems. the old masters wrote about exactly this.  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' }    ],    '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' }    ],    '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' }    ],    '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' }    ],    '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' }    ],    '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' }    ],    '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' }    ]  };  function getHaiku(season) {    var poems = HAIKU[season.name];    if (!poems) return null;    // pick one based on day of year so it changes daily but is stable within the day    var doy = Math.floor((new Date() - new Date(new Date().getFullYear(), 0, 0)) / 86400000);    return poems[doy % poems.length];  }  // --- weather moods ---  // not forecasts. the character of the air in this season, at this hour.  var WEATHER_MOODS = {    'winter': {      dawn: 'the cold is sharpest now. frost on everything. the air tastes like iron.',      morning: 'grey and still. the kind of cold that settles in the bones and stays.',      afternoon: 'thin winter light, already angling toward evening. the air is dry and quiet.',      evening: 'the dark comes early and completely. woodsmoke from somewhere.',      night: 'clear and bitter, or clouded and raw. either way, stay in.'    },    'early-spring': {      dawn: 'cold still, but softer than last month. fog in the low places.',      morning: 'cool and damp. the kind of morning that smells like turned earth.',      afternoon: 'mild with a chance of anything. spring weather changes its mind.',      evening: 'cooling fast once the sun drops. a jacket you almost left behind.',      night: 'still cold enough to frost. the season is not settled yet.'    },    'late-spring': {      dawn: 'warm already. dew on everything. the birds are unreasonably loud.',      morning: 'bright and easy. the kind of morning that makes you go outside.',      afternoon: 'warm, sometimes hot. thunderstorms build in the west by three.',      evening: 'long golden light. warm enough to sit outside and do nothing.',      night: 'mild, finally. windows open. the frogs are singing.'    },    'early-summer': {      dawn: 'warm and humid before the sun is even up. it will be a hot one.',      morning: 'hazy. the heat is already building. do what you need to do early.',      afternoon: 'the full weight of it. cicadas. shade is the only mercy.',      evening: 'still warm but the light softens. lightning bugs in the grass.',      night: 'heavy air. the kind of night that does not cool down.'    },    'midsummer': {      dawn: 'the air is thick before sunrise. everything is already sweating.',      morning: 'blazing. the garden wilts by ten. water it or lose it.',      afternoon: 'oppressive. thunderheads pile up. the storms when they come are violent and brief.',      evening: 'a little relief if the storms came through. if not, you wait.',      night: 'warm and loud with insects. sleep with the windows open or don\'t sleep.'    },    'early-fall': {      dawn: 'cool at last. real cool. the first morning you can see your breath.',      morning: 'crisp and blue. the clearest skies of the year.',      afternoon: 'warm but not punishing. the light has that golden slant to it.',      evening: 'cool enough for a fire. the smell of leaves starting.',      night: 'cold and clear. you can see more stars now that the haze is gone.'    },    'late-fall': {      dawn: 'raw and grey. the trees are bare. wind with nothing to stop it.',      morning: 'cold rain or cold sun, both are possible. dress for both.',      afternoon: 'short. the light is leaving by four. make use of what remains.',      evening: 'dark already. the wind sounds different through bare branches.',      night: 'the kind of cold that makes the house feel smaller and warmer.'    }  };  function getWeatherMood(season, time) {    var moods = WEATHER_MOODS[season.name];    if (!moods) return '';    return moods[time] || '';  }  // --- daylight cycle ---  // shifts the palette based on time of day  var CYCLES = {    night:     { bg: '#080706', text: '#9a8e80', accent: '#4a6340', heading: '#7a6a58', glow: 'rgba(60,50,35,0.08)' },    dawn:      { bg: '#0f0c09', text: '#c4b5a0', accent: '#7a9a62', heading: '#c0885a', glow: 'rgba(180,120,60,0.06)' },    morning:   { bg: '#0e0c0a', text: '#d4c8b8', accent: '#7a9a62', heading: '#b07a50', glow: 'rgba(140,100,50,0.04)' },    afternoon: { bg: '#0d0b09', text: '#d0c2b0', accent: '#6a8a55', heading: '#a87048', glow: 'rgba(160,100,40,0.05)' },    evening:   { bg: '#0b0908', text: '#c8b8a5', accent: '#5a7d4a', heading: '#b87840', glow: 'rgba(180,100,40,0.08)' }    night: {      bg: '#060504',      text: '#9a8e80',      accent: '#3a5030',      heading: '#7a6a58',      glow: 'rgba(30,25,20,0.08)',      under1: 'rgba(15,12,10,0.8)',      under2: 'rgba(20,18,15,0.6)',      under3: 'rgba(10,10,15,0.5)'    },    dawn: {      bg: '#0f0c09',      text: '#c4b5a0',      accent: '#7a9a62',      heading: '#c0885a',      glow: 'rgba(180,120,60,0.06)',      under1: 'rgba(40,25,15,0.6)',      under2: 'rgba(50,30,18,0.4)',      under3: 'rgba(30,20,12,0.5)'    },    morning: {      bg: '#0e0c0a',      text: '#d4c8b8',      accent: '#7a9a62',      heading: '#b07a50',      glow: 'rgba(140,100,50,0.04)',      under1: 'rgba(26,23,20,0.7)',      under2: 'rgba(42,36,32,0.5)',      under3: 'rgba(26,23,20,0.4)'    },    afternoon: {      bg: '#0d0b09',      text: '#d0c2b0',      accent: '#6a8a55',      heading: '#a87048',      glow: 'rgba(160,100,40,0.05)',      under1: 'rgba(35,28,20,0.6)',      under2: 'rgba(30,25,18,0.5)',      under3: 'rgba(40,30,20,0.4)'    },    evening: {      bg: '#0b0908',      text: '#c8b8a5',      accent: '#5a7d4a',      heading: '#b87840',      glow: 'rgba(180,100,40,0.08)',      under1: 'rgba(45,25,12,0.7)',      under2: 'rgba(35,18,10,0.6)',      under3: 'rgba(25,15,8,0.5)'    }  };  function applyDaylightCycle(time) {  // season palettes — the color of the earth shifts with the year  var SEASON_COLORS = {    'winter':       { bg: '#07080b', tint: '40,50,80' },     // cold blue    'early-spring': { bg: '#0a0c08', tint: '50,70,35' },     // dark moss    'late-spring':  { bg: '#0b0d07', tint: '55,80,30' },     // green rising    'early-summer': { bg: '#0d0b07', tint: '80,65,20' },     // golden heat    'midsummer':    { bg: '#0e0a06', tint: '90,60,15' },     // scorched amber    'early-fall':   { bg: '#0d0906', tint: '85,45,20' },     // rust and oak    'late-fall':    { bg: '#0b0908', tint: '65,40,30' }      // bare wood  };  function applyDaylightCycle(time, season) {    var c = CYCLES[time] || CYCLES.morning;    var s = SEASON_COLORS[season.name] || SEASON_COLORS['early-spring'];    var r = document.documentElement;    r.style.setProperty('--earth', c.bg);    // background color blends time + season    r.style.setProperty('--earth', s.bg);    r.style.setProperty('--bone', c.text);    r.style.setProperty('--sprout', c.accent);    r.style.setProperty('--ember', c.heading);    r.style.setProperty('--glow', c.glow);    r.style.setProperty('--under1', c.under1);    r.style.setProperty('--under2', c.under2);    r.style.setProperty('--under3', c.under3);    document.body.setAttribute('data-time', time);    document.body.setAttribute('data-season', season.name);    // sky layer: season color wash    var sky = document.getElementById('sky-layer');    if (sky) {      sky.style.background =        'radial-gradient(ellipse at 30% 20%, rgba(' + s.tint + ',0.12) 0%, transparent 50%), ' +        'radial-gradient(ellipse at 70% 80%, rgba(' + s.tint + ',0.08) 0%, transparent 50%), ' +        'radial-gradient(ellipse at 50% 50%, rgba(' + s.tint + ',0.05) 0%, transparent 70%)';    }    // time layer: light source shining down from above    var timeEl = document.getElementById('time-layer');    if (timeEl) {      timeEl.style.background = TIME_LIGHTS[time] || TIME_LIGHTS.morning;    }  }  // the light source — a thin band across the top, sun or moon  var TIME_LIGHTS = {    night:      'linear-gradient(to bottom, rgba(100,120,180,0.10) 0%, rgba(100,120,180,0.03) 40%, transparent 100%)',    dawn:      'linear-gradient(to bottom, rgba(220,150,70,0.14) 0%, rgba(200,120,50,0.04) 50%, transparent 100%)',    morning:      'linear-gradient(to bottom, rgba(240,210,140,0.10) 0%, rgba(240,210,140,0.02) 50%, transparent 100%)',    afternoon:      'linear-gradient(to bottom, rgba(240,200,110,0.12) 0%, rgba(240,200,110,0.03) 50%, transparent 100%)',    evening:      'linear-gradient(to bottom, rgba(200,90,30,0.16) 0%, rgba(180,70,20,0.04) 50%, transparent 100%)'  };  // --- sky calculations ---
@@ -115,9 +320,55 @@    return h + 'h ' + m + 'm';  }  function moonGlyph(phase) {    // 8 unicode moon glyphs mapped to the synodic cycle    var glyphs = ['\uD83C\uDF11','\uD83C\uDF12','\uD83C\uDF13','\uD83C\uDF14','\uD83C\uDF15','\uD83C\uDF16','\uD83C\uDF17','\uD83C\uDF18'];    var i = Math.floor((phase / 29.53058867) * 8) % 8;    return glyphs[i];  }  var MONTHS = ['january','february','march','april','may','june',    'july','august','september','october','november','december'];  var ORDINALS = ['','first','second','third','fourth','fifth','sixth',    'seventh','eighth','ninth','tenth','eleventh','twelfth','thirteenth',    'fourteenth','fifteenth','sixteenth','seventeenth','eighteenth',    'nineteenth','twentieth','twenty-first','twenty-second','twenty-third',    'twenty-fourth','twenty-fifth','twenty-sixth','twenty-seventh',    'twenty-eighth','twenty-ninth','thirtieth','thirty-first'];  var TIME_WORDS = {    night: 'night',    dawn: 'dawn',    morning: 'morning',    afternoon: 'afternoon',    evening: 'evening'  };  function writtenDate(date) {    var time = getTimeOfDay(date);    return TIME_WORDS[time] + ', the ' + ORDINALS[date.getDate()] + ' of ' + MONTHS[date.getMonth()];  }  function daysUntilNextSeason(date) {    var current = getSeason(date);    for (var i = 0; i < SEASONS.length; i++) {      var s = SEASONS[i];      var sDate = new Date(date.getFullYear(), s.start[0] - 1, s.start[1]);      if (sDate > date && s.name !== current.name) {        var diff = Math.ceil((sDate - date) / 86400000);        return { days: diff, label: s.label };      }    }    // wrap to next year    var first = SEASONS[0];    var next = new Date(date.getFullYear() + 1, first.start[0] - 1, first.start[1]);    return { days: Math.ceil((next - date) / 86400000), label: first.label };  }  function skyText(now, time) {    var phase = moonPhase(now);    var name = moonName(phase);    var glyph = moonGlyph(phase);    var illum = Math.round(moonIllumination(phase) * 100);    var hours = daylight(now, LAT);    var yesterday = new Date(now);
@@ -167,22 +418,26 @@    var lines = body.split('\n');    var html = '';    var inList = false;    var inPara = false;    lines.forEach(function (line) {      var trimmed = line.trim();      if (trimmed.match(/^- /)) {        if (inPara) { html += '</p>'; inPara = false; }        if (!inList) { html += '<ul>'; inList = true; }        html += '<li>' + trimmed.slice(2) + '</li>';      } else if (trimmed === '') {        if (inList) { html += '</ul>'; inList = false; }        if (inPara) { html += '</p>'; inPara = false; }      } else {        if (inList) { html += '</ul>'; inList = false; }        if (trimmed === '') {          html += '<br>';        } else {          html += trimmed + '<br>';        }        if (!inPara) { html += '<p>'; inPara = true; }        else { html += '<br>'; }        html += trimmed;      }    });    if (inList) html += '</ul>';    if (inPara) html += '</p>';    return html;  }
@@ -191,9 +446,15 @@  function revealWords(root) {    var elements = root.querySelectorAll('h2, p, li');    var allWords = [];    var allItems = []; // mixed: word spans and whole li elements    elements.forEach(function (el) {      if (el.tagName === 'LI') {        // list items fade in as a whole unit, bullet and all        allItems.push(el);        return;      }      var nodes = [];      el.childNodes.forEach(function (node) {        if (node.nodeType === 3) {
@@ -205,7 +466,7 @@              span.className = 'word';              span.textContent = w;              nodes.push(span);              allWords.push(span);              allItems.push(span);            }          });        } else {
@@ -217,36 +478,75 @@    });    var delay = 0;    allWords.forEach(function (span) {      span.style.animationDelay = delay + 'ms';      delay += 18;    allItems.forEach(function (item) {      item.style.animationDelay = delay + 'ms';      delay += item.tagName === 'LI' ? 60 : 18;    });  }  // --- main ---  function render() {  var currentSeason = null;  var cachedManifest = null;  var naturalSeason = null;  function loadContent(seasonOverride) {    var now = new Date();    var season = getSeason(now);    var season = seasonOverride || getSeason(now);    var time = getTimeOfDay(now);    currentSeason = season;    // daylight cycle follows the clock, tinted by season    applyDaylightCycle(time, season);    // daylight cycle    applyDaylightCycle(time);    // date line    document.querySelector('.date-line').textContent = writtenDate(now);    // season header    document.querySelector('.season-name').textContent = season.label;    document.querySelector('.season-note').innerHTML = season.note.replace(/\n/g, '<br>');    // sky    // haiku    var haiku = getHaiku(season);    var haikuBlock = document.querySelector('.haiku blockquote');    var haikuCite = document.querySelector('.haiku cite');    if (haiku) {      var haikuLines = haiku.lines[0].split('\n');      haikuBlock.innerHTML = haikuLines.map(function (l) {        return '<span class="haiku-line">' + l + '</span>';      }).join('');      haikuCite.textContent = '';    }    // weather mood    var moodP = document.querySelector('.weather-mood p');    moodP.textContent = getWeatherMood(season, time);    // sky always shows real data    var skyP = document.querySelector('.sky p');    skyP.innerHTML = skyText(now, time).replace(/\n/g, '<br>');    // fetch content    fetch('/data/manifest.json')      .then(function (r) { return r.json(); })      .then(function (manifest) {        // filter to current season and time of day    // footer countdown    var next = daysUntilNextSeason(now);    document.querySelector('footer p').textContent =      next.days + ' days until ' + next.label + ' \u00b7 zone 7a \u00b7 north carolina';    // crossfade: fade out content areas, then rebuild    var fadeTargets = ['.season', '.haiku', '.weather-mood', '.sky', '.almanac', 'footer'];    fadeTargets.forEach(function (sel) {      var el = document.querySelector(sel);      if (el) el.style.opacity = '0';    });    // fetch or use cached manifest    var p = cachedManifest      ? Promise.resolve(cachedManifest)      : fetch('/data/manifest.json').then(function (r) { return r.json(); });    p.then(function (manifest) {        cachedManifest = manifest;        var relevant = manifest.filter(function (entry) {          if (entry.season && entry.season !== season.name) return false;          if (entry.time && entry.time !== time) return false;
@@ -278,11 +578,71 @@          almanac.appendChild(div);        });        // reveal everything        revealWords(document.querySelector('main'));        // fade in and reveal        fadeTargets.forEach(function (sel) {          var el = document.querySelector(sel);          if (el) el.style.opacity = '1';        });        revealWords(document.querySelector('header'));        revealWords(document.querySelector('.season'));        revealWords(document.querySelector('.haiku'));        revealWords(document.querySelector('.weather-mood'));        revealWords(document.querySelector('.sky'));        revealWords(document.querySelector('.almanac'));        revealWords(document.querySelector('footer'));        // update nav        updateNav(season);      });  }  render();  // unique season names in order, for the nav  var seasonOrder = [];  var seasonMap = {};  SEASONS.forEach(function (s) {    if (!seasonMap[s.name]) {      seasonMap[s.name] = s;      seasonOrder.push(s);    }  });  function updateNav(activeSeason) {    var nav = document.querySelector('.seasons-nav');    nav.innerHTML = '';    var delay = 0;    seasonOrder.forEach(function (s) {      var a = document.createElement('a');      a.textContent = s.label;      if (s.name === activeSeason.name) {        a.className = 'active';      }      a.style.animationDelay = delay + 'ms';      delay += 80;      a.addEventListener('click', function () {        window.scrollTo({ top: 0, behavior: 'smooth' });        loadContent(s);      });      nav.appendChild(a);    });    if (activeSeason.name !== naturalSeason.name) {      var ret = document.createElement('a');      ret.textContent = 'return to now';      ret.className = 'return-now';      ret.style.animationDelay = delay + 'ms';      ret.addEventListener('click', function () {        window.scrollTo({ top: 0, behavior: 'smooth' });        loadContent(null);      });      nav.appendChild(ret);    }  }  // initial render  var now = new Date();  naturalSeason = getSeason(now);  loadContent(null);})();
added site/data/bugs/early-fall.md
@@ -0,0 +1,11 @@---season: early-fallsection: what is crawling---- the mosquitoes are finally easing. first frost will finish them.- stink bugs looking for ways into the house. seal what you can.- woolly bear caterpillars crossing the road. old wisdom says the wider the brown band, the milder the winter.- yellow jackets aggressive now, defending nests that are almost done. give them space.- monarch butterflies passing through on their way south. plant milkweed and they will stop.- crickets at night, slowing as it cools. count the chirps in fourteen seconds, add forty. that is the temperature.
added site/data/bugs/early-spring.md
@@ -0,0 +1,11 @@---season: early-springsection: what is crawling---- earthworms in the turned soil, the best sign there is- ladybugs waking up, finding their way out of the house. friends.- aphids arriving early on new growth. not friends. the ladybugs will handle it.- cabbage moths, white and innocent-looking. they are not innocent.- ground beetles under boards and stones, let them be, they eat slugs- slugs. the eternal problem. beer traps or copper tape or acceptance.
added site/data/bugs/early-summer.md
@@ -0,0 +1,11 @@---season: early-summersection: what is crawling---- mosquitoes at dawn and dusk. standing water is where they breed. dump it.- squash vine borers, the worst of them. wrap the stems in foil or lose the plant.- cucumber beetles, yellow and black, spreading wilt. pick them off early.- praying mantis hunting in the tall plants. do not touch. just watch.- honeybees heavy with pollen, slow and gentle. they will not bother you.- braconid wasps, tiny, laying eggs on hornworms. if you see white cocoons on a caterpillar, leave it. the wasps are winning.
added site/data/bugs/late-fall.md
@@ -0,0 +1,10 @@---season: late-fallsection: what is crawling---- ladybugs clustering on the south side of the house, looking for cracks. let them in if you can stand it.- stink bugs inside now. do not crush them, the name is earned.- the last moths at the porch light. fewer every night.- spiders moving indoors. most are harmless. the brown recluse is not. learn the difference.- everything else is burrowing, cocooning, or dying. the quiet is coming.
added site/data/bugs/late-spring.md
@@ -0,0 +1,11 @@---season: late-springsection: what is crawling---- bees everywhere now, doing the real work. do not spray anything while they are out.- japanese beetle grubs are becoming japanese beetles. pick them off by hand into soapy water.- tomato hornworms soon. huge, green, invisible until they are not. check the undersides.- fireflies in the grass at dusk. leave the lawn alone and they will stay.- spiders in the garden corners, building webs between the stakes. they earn their place.- ticks in the tall grass. check yourself after. tuck your pants in.
added site/data/bugs/midsummer.md
@@ -0,0 +1,11 @@---season: midsummersection: what is crawling---- cicadas, loud enough to drown out thought. they are harmless.- japanese beetles at their worst. the roses suffer most.- mosquitoes relentless. long sleeves at dusk or pay for it.- dragonflies over the garden, eating hundreds of mosquitoes a day. allies.- the yellow garden spider, huge and beautiful, writing zigzags in her web.- stink bugs arriving. they want your tomatoes. they will get some.
added site/data/bugs/winter.md
@@ -0,0 +1,10 @@---season: wintersection: what is crawling---- almost nothing. that is the gift of winter.- house spiders in the corners. they were there all year, you just notice them now.- cluster flies in the window on warm afternoons. they are slow and confused.- beneath the soil, grubs and larvae are waiting. the cycle does not stop, it just hides.- this is the time to clean up debris where pests overwinter. rake, burn, compost hot.
modified site/data/manifest.json
@@ -14,6 +14,13 @@  { "path": "kitchen/early-fall.md", "season": "early-fall" },  { "path": "kitchen/late-fall.md", "season": "late-fall" },  { "path": "kitchen/winter.md", "season": "winter" },  { "path": "bugs/early-spring.md", "season": "early-spring" },  { "path": "bugs/late-spring.md", "season": "late-spring" },  { "path": "bugs/early-summer.md", "season": "early-summer" },  { "path": "bugs/midsummer.md", "season": "midsummer" },  { "path": "bugs/early-fall.md", "season": "early-fall" },  { "path": "bugs/late-fall.md", "season": "late-fall" },  { "path": "bugs/winter.md", "season": "winter" },  { "path": "names/early-spring.md", "season": "early-spring" },  { "path": "names/late-spring.md", "season": "late-spring" },  { "path": "names/early-summer.md", "season": "early-summer" },
modified site/index.html
@@ -3,24 +3,62 @@<head>  <meta charset="utf-8">  <meta name="viewport" content="width=device-width, initial-scale=1">  <title>dark furrow</title>  <meta name="description" content="old knowledge preserved">  <title>dark furrow / old knowledge preserved</title>  <meta name="description" content="a seasonal almanac of planting, harvest, moon phases, and forgotten rhythms. what to grow, what to cook, what the sky is doing. tended by hand for zone 7a.">  <meta name="author" content="isaac bythewood">  <meta name="theme-color" content="#0e0c0a">  <meta name="color-scheme" content="dark">  <!-- open graph -->  <meta property="og:type" content="website">  <meta property="og:url" content="https://darkfurrow.com">  <meta property="og:title" content="dark furrow">  <meta property="og:description" content="old knowledge preserved. a seasonal almanac of planting, harvest, moon phases, and the quiet rhythms the modern world forgot.">  <meta property="og:site_name" content="dark furrow">  <meta property="og:locale" content="en_US">  <!-- twitter / x -->  <meta name="twitter:card" content="summary">  <meta name="twitter:title" content="dark furrow">  <meta name="twitter:description" content="old knowledge preserved. what to plant, what to cook, what the moon is doing. an almanac that breathes with the season and the hour.">  <!-- misc -->  <meta name="robots" content="index, follow">  <meta name="generator" content="hand and soil">  <link rel="canonical" href="https://darkfurrow.com">  <link rel="icon" href="/favicon.svg" type="image/svg+xml">  <link rel="stylesheet" href="/style.css"></head><body>  <div id="sky-layer"></div>  <div id="time-layer"></div>  <main>    <header>      <h1>dark furrow</h1>      <p class="subtitle">old knowledge preserved</p>      <div class="title-row">        <h1>dark furrow</h1>        <p class="subtitle">old knowledge preserved</p>      </div>      <p class="date-line"></p>      <nav class="seasons-nav"></nav>    </header>    <section class="haiku">      <blockquote></blockquote>      <cite></cite>    </section>    <section class="season">      <p class="season-name"></p>      <p class="season-note"></p>    </section>    <section class="weather-mood">      <h2>the air today</h2>      <p></p>    </section>    <section class="sky">      <h2>what the sky is doing</h2>      <p></p>
modified site/style.css
@@ -9,6 +9,9 @@  --moss: #5a7d4a;  --ember: #b07a50;  --glow: rgba(140,100,50,0.04);  --under1: rgba(26,23,20,0.7);  --under2: rgba(42,36,32,0.5);  --under3: rgba(26,23,20,0.4);}* {
@@ -38,29 +41,45 @@ main {header {  margin-bottom: 4rem;  border-bottom: 1px solid var(--bark);  border-bottom: none;  padding-bottom: 2rem;}.title-row {  display: flex;  align-items: baseline;  gap: 1rem;  flex-wrap: wrap;}h1 {  font-size: 2.4rem;  font-weight: 400;  letter-spacing: 0.04em;  color: var(--parchment);  margin-bottom: 0.3rem;}.subtitle {  font-style: italic;  color: var(--ash);  font-size: 1.05rem;  font-size: 0.9rem;  animation: breathe 8s ease-in-out infinite;}.date-line {  color: var(--ash);  font-size: 0.8rem;  font-style: italic;  letter-spacing: 0.03em;  margin-top: 0.6rem;  margin-bottom: 0.2rem;}.season {  margin-bottom: 3rem;  padding: 1.5rem 0;  border-bottom: 1px solid var(--bark);  border-bottom: none;  transition: opacity 0.4s ease;}.season-name {
@@ -81,10 +100,72 @@ h1 {  line-height: 1.8;}.haiku {  margin-bottom: 3rem;  padding: 0.8rem 0;  display: flex;  flex-direction: column;  align-items: center;  transition: opacity 0.4s ease;}.haiku blockquote {  color: var(--ash);  font-style: italic;  font-size: 0.82rem;  line-height: 1.8;  letter-spacing: 0.02em;}.haiku .haiku-line {  display: block;}.haiku .haiku-line:nth-child(2) {  padding-left: 1rem;}.haiku .haiku-line:nth-child(3) {  padding-left: 2rem;}.haiku cite {  display: block;  margin-top: 0.4rem;  color: var(--bark);  font-size: 0.72rem;  font-style: normal;  letter-spacing: 0.04em;}.weather-mood {  margin-bottom: 3rem;  padding: 1.2rem 0;  border-bottom: none;  transition: opacity 0.4s ease;}.weather-mood h2 {  font-size: 1.1rem;  font-weight: 500;  color: var(--ember);  margin-bottom: 0.8rem;  letter-spacing: 0.02em;  transition: color 2s ease;}.weather-mood p {  color: var(--ash);  font-style: italic;  font-size: 0.95rem;  line-height: 1.9;}.sky {  margin-bottom: 3rem;  padding-bottom: 1.5rem;  border-bottom: 1px solid var(--bark);  border-bottom: none;  transition: opacity 0.4s ease;}.sky h2 {
@@ -106,6 +187,19 @@ h1 {  display: flex;  flex-direction: column;  gap: 2.8rem;  transition: opacity 0.4s ease;}.almanac .entry + .entry::before {  content: '*';  display: block;  text-align: center;  color: var(--bark);  font-size: 0.9rem;  letter-spacing: 0.5em;  margin-bottom: 2.8rem;  opacity: 0;  animation: word-in 0.3s ease-out forwards;}.entry h2 {
@@ -135,6 +229,8 @@ h1 {  line-height: 1.9;  padding-left: 1.2rem;  position: relative;  opacity: 0;  animation: word-in 0.3s ease-out forwards;}.entry ul li::before {
@@ -151,10 +247,52 @@ h1 {.entry ul li:nth-child(3n)::before { animation-delay: -2.7s; }.entry ul li:nth-child(5n)::before { animation-delay: -0.6s; }.seasons-nav {  display: flex;  flex-wrap: wrap;  gap: 0.2rem 0.6rem;  margin-top: 1rem;}.seasons-nav a {  color: var(--bark);  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;}.seasons-nav a:hover {  color: var(--ash);}.seasons-nav a.active {  color: var(--sprout);}.seasons-nav a.return-now {  color: var(--ember);}.seasons-nav a::after {  content: ' \00b7';  color: var(--bark);}.seasons-nav a:last-child::after {  content: '';}footer {  margin-top: 4rem;  margin-top: 2rem;  padding-top: 2rem;  border-top: 1px solid var(--bark);  border-top: none;  transition: opacity 0.4s ease;}footer p {
@@ -170,57 +308,28 @@ footer p {  animation: word-in 0.3s ease-out forwards;}/* daylight glow *//* daylight layer */body::before {  content: '';#sky-layer {  position: fixed;  top: 0;  left: 0;  right: 0;  bottom: 0;  pointer-events: none;  background: radial-gradient(ellipse at 50% 0%, var(--glow) 0%, transparent 70%);  transition: background 3s ease;  z-index: 9999;}/* time-of-day ambient */body[data-time="dawn"]::after {  content: '';  position: fixed;  bottom: 0;  left: 0;  right: 0;  height: 30vh;  pointer-events: none;  background: linear-gradient(to top, rgba(180,120,60,0.03) 0%, transparent 100%);  z-index: 9999;}body[data-time="evening"]::after {  content: '';  position: fixed;  top: 0;  left: 0;  right: 0;  height: 40vh;  pointer-events: none;  background: linear-gradient(to bottom, rgba(160,80,30,0.04) 0%, transparent 100%);  z-index: 9999;  z-index: 9998;  transition: background 4s ease;}body[data-time="night"]::after {  content: '';#time-layer {  position: fixed;  top: 0;  left: 0;  right: 0;  bottom: 0;  height: 120px;  pointer-events: none;  background: radial-gradient(ellipse at 50% 50%, transparent 30%, rgba(0,0,0,0.15) 100%);  z-index: 9999;  transition: background 4s ease;}::selection {