// page-journal.jsx — journal index, data-driven from JOURNAL, rows link to post.html?slug= const JCSS = ` .page .jr-list{ padding:60px 56px 80px; position:relative; } .page .jr-list .row{ display:grid; grid-template-columns:120px 1.5fr 1fr 80px; gap:48px; padding:34px 0; border-top:1px solid var(--rule); align-items:baseline; text-decoration:none; color:inherit; transition:padding .2s, background .2s; position:relative; } .page .jr-list .row:last-child{ border-bottom:1px solid var(--rule); } .page .jr-list .row:hover{ padding-left:14px; padding-right:14px; background:var(--paper); } .page .jr-list .yr{ font-family:'JetBrains Mono',monospace; font-size:13px; color:var(--ink-soft); } .page .jr-list .ttl{ font-family:'Instrument Serif',serif; font-style:italic; font-size:34px; line-height:1.02; } .page .jr-list .ttl em{ color:var(--terra); } .page .jr-list .ttl .rd{ display:block; font-family:'JetBrains Mono',monospace; font-style:normal; font-size:11px; letter-spacing:.08em; color:var(--ink-soft); margin-top:8px; opacity:0; transform:translateY(-4px); transition:.2s; } .page .jr-list .row:hover .ttl .rd{ opacity:1; transform:translateY(0); } .page .jr-list .cat{ font-family:'JetBrains Mono',monospace; font-size:11px; letter-spacing:.12em; text-transform:uppercase; color:var(--ink-soft); } .page .jr-list .arr{ text-align:right; font-family:'Instrument Serif',serif; font-style:italic; font-size:26px; color:var(--terra); transition:transform .2s; } .page .jr-list .row:hover .arr{ transform:translate(4px,-4px); } .page .jr-feat{ background:var(--paper); padding:80px 56px; display:grid; grid-template-columns:1fr 1fr; gap:64px; align-items:center; position:relative; } .page .jr-feat .pic{ aspect-ratio:4/3; border-radius:8px; overflow:hidden; transform:rotate(-1.5deg); box-shadow:0 30px 70px -34px rgba(0,0,0,.4); } .page .jr-feat .pic img{ width:100%; height:100%; object-fit:cover; } .page .jr-feat h2{ font-family:'Instrument Serif',serif; font-style:italic; font-size:60px; line-height:1; margin:14px 0 18px; } .page .jr-feat h2 em{ color:var(--terra); } .page .jr-feat .read{ display:inline-flex; align-items:center; gap:8px; margin-top:24px; font-family:'JetBrains Mono',monospace; font-size:12px; letter-spacing:.1em; text-transform:uppercase; text-decoration:none; color:var(--ink); border-bottom:2px solid var(--terra); padding-bottom:4px; } .page .jr-tags{ padding:56px 56px 12px; display:flex; gap:10px; flex-wrap:wrap; align-items:center; } .page .jr-tags .k{ font-family:'JetBrains Mono',monospace; font-size:11px; letter-spacing:.14em; text-transform:uppercase; color:var(--ink-soft); margin-right:4px; } .page .jr-tags button{ font-family:'JetBrains Mono',monospace; font-size:12px; letter-spacing:.04em; padding:7px 14px; border:1px solid var(--rule); border-radius:999px; background:transparent; color:var(--ink); cursor:pointer; transition:.2s; } .page .jr-tags button.on, .page .jr-tags button:hover{ background:var(--ink); color:var(--bg); border-color:var(--ink); } @media (max-width:900px){ .page .jr-feat{ grid-template-columns:1fr; gap:32px; padding:56px 24px; } .page .jr-feat h2{ font-size:clamp(38px,11vw,60px); } .page .jr-tags{ padding:0 24px 12px; } .page .jr-list{ padding:40px 24px 60px; } .page .jr-list .row{ grid-template-columns:1fr; gap:8px; padding:28px 0; } .page .jr-list .ttl{ font-size:28px; } .page .jr-list .arr{ display:none; } } `; function JournalPage(){ const feat = JOURNAL[0]; const rest = JOURNAL.slice(1); const cats = ['All', ...Array.from(new Set(JOURNAL.map(p => p.cat)))]; const initCat = () => { const u = new URLSearchParams(location.search).get('cat'); return (u && cats.includes(u)) ? u : 'All'; }; const [cat, setCat] = React.useState(initCat); function pickCat(c){ setCat(c); const u = new URL(location.href); if (c === 'All') u.searchParams.delete('cat'); else u.searchParams.set('cat', c); history.replaceState(null, '', u.toString()); } const shown = rest.filter(p => cat === 'All' || p.cat === cat); React.useEffect(() => { applySEO({ title: 'Journal — Maia Hariton', description: 'Working notes, opinionated takes, and the occasional tutorial from an independent web studio of one.', image: feat.hero, }); applyJSONLD({ '@context':'https://schema.org', '@type':'Blog', name:'Maia Hariton — Journal', blogPost: JOURNAL.map(p => ({ '@type':'BlogPosting', headline:p.titlePlain, datePublished:p.dateISO, url:'post.html?slug='+p.slug, articleSection:p.cat, })), }); }, []); return (
Journal · Notes from the studio

Things I’ve been
thinking about.

Working notes, opinionated takes, the occasional tutorial. Updated when I have something to say — not on a content calendar.

written between
client projects
{feat.titlePlain}/
Latest · {feat.date}

(?!.*

{feat.sum}

Read the post · {feat.readMin} min ↗

new ✦ latest post ↘
Filter {cats.map(c => ( ))}
{shown.map(p => (
{p.date}
/g,' ') + 'Read · ' + p.readMin + ' min' }} />
{p.cat}
))} {shown.length === 0 &&

Nothing filed under “{cat}” yet.

}

Get the occasional letter.

Two or three notes a year, no marketing, no funnel. Just whatever I’ve been thinking about — like these.

no spam, promise
); } ReactDOM.createRoot(document.getElementById('root')).render();