From 66414d8cd6f628f818b80009a7c5416b8c1bc4fc Mon Sep 17 00:00:00 2001 From: svemagie <869694+svemagie@users.noreply.github.com> Date: Thu, 19 Mar 2026 14:33:58 +0100 Subject: [PATCH] style: adopt Gruvbox-inspired palette and serif typography MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Inspired by brennan.day — warm cream backgrounds (#fbf1c7), Iowan Old Style/Palatino serif font, Gruvbox blue accent (#076678), and matching code syntax theme in both light and dark modes. Co-Authored-By: Claude Opus 4.6 --- _includes/components/sections/ai-usage.njk | 2 +- _includes/components/widgets/ai-usage.njk | 2 +- _includes/layouts/page.njk | 2 +- css/critical.css | 52 ++++++----- css/prism-theme.css | 60 ++++++------ css/tailwind.css | 104 ++++++++++----------- eleventy.config.js | 12 +-- tailwind.config.js | 57 ++++++----- 8 files changed, 151 insertions(+), 140 deletions(-) diff --git a/_includes/components/sections/ai-usage.njk b/_includes/components/sections/ai-usage.njk index 6b0ab26..7410a82 100644 --- a/_includes/components/sections/ai-usage.njk +++ b/_includes/components/sections/ai-usage.njk @@ -52,7 +52,7 @@

AI-Involved Posts Over Time

Highlighted days had posts with AI involvement (level 1+). Empty boxes represent days with no AI-involved posts.

{% set graphLimit = sectionConfig.limit or 1 %} - {% postGraph aiPostsList, { prefix: "ai-section", limit: graphLimit, boxColorDark: "#44403c", highlightColorLight: "#d97706", highlightColorDark: "#fbbf24" } %} + {% postGraph aiPostsList, { prefix: "ai-section", limit: graphLimit, boxColorDark: "#504945", highlightColorLight: "#076678", highlightColorDark: "#83a598" } %} {% endif %} diff --git a/_includes/components/widgets/ai-usage.njk b/_includes/components/widgets/ai-usage.njk index 004ef36..5063562 100644 --- a/_includes/components/widgets/ai-usage.njk +++ b/_includes/components/widgets/ai-usage.njk @@ -50,7 +50,7 @@ {# Compact post-graph — current year only, AI posts highlighted #} {% if aiPostsList and aiPostsList.length %}
AI-involved posts this year
- {% postGraph aiPostsList, { prefix: "ai-widget", limit: 1, noLabels: true, boxColorDark: "#44403c", highlightColorLight: "#d97706", highlightColorDark: "#fbbf24" } %} + {% postGraph aiPostsList, { prefix: "ai-widget", limit: 1, noLabels: true, boxColorDark: "#504945", highlightColorLight: "#076678", highlightColorDark: "#83a598" } %} {% endif %} diff --git a/_includes/layouts/page.njk b/_includes/layouts/page.njk index 63d1249..5451bbe 100644 --- a/_includes/layouts/page.njk +++ b/_includes/layouts/page.njk @@ -79,7 +79,7 @@ withSidebar: true {# Post graph showing AI posts (highlighted) on the full year grid #}

AI-Involved Posts Over Time

Highlighted days had posts with AI involvement (level 1+). Empty boxes represent days with no AI-involved posts.

- {% postGraph aiPostsList, { prefix: "ai", highlightColorLight: "#d97706", highlightColorDark: "#fbbf24" } %} + {% postGraph aiPostsList, { prefix: "ai", highlightColorLight: "#076678", highlightColorDark: "#83a598" } %} {% endif %} diff --git a/css/critical.css b/css/critical.css index 8966165..9451b34 100644 --- a/css/critical.css +++ b/css/critical.css @@ -2,30 +2,30 @@ /* Covers: layout shell, header, dark mode toggle, font display, basic typography */ *,*::before,*::after{box-sizing:border-box} -body{margin:0;font-family:"Inter",system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;line-height:1.5;-webkit-font-smoothing:antialiased} +body{margin:0;font-family:"Iowan Old Style","Palatino Linotype","URW Palladio L",P052,serif;line-height:1.5;-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility} -/* Dark mode base — warm stone palette */ -body{background-color:#faf8f5;color:#1c1b19} -.dark body{background-color:#0f0e0d;color:#faf8f5} +/* Dark mode base — Gruvbox-inspired warm palette */ +body{background-color:#fbf1c7;color:#282828} +.dark body{background-color:#1d2021;color:#fbf1c7} /* Container */ .container{max-width:64rem;margin-left:auto;margin-right:auto;padding-left:1rem;padding-right:1rem} /* Header — sticky, visible immediately */ -.site-header{background-color:#faf8f5;border-bottom:1px solid #e8e5df;padding-top:1rem;padding-bottom:1rem;position:sticky;top:0;z-index:50} -.dark .site-header{background-color:#1c1b19;border-bottom-color:#3f3b35} +.site-header{background-color:#fbf1c7;border-bottom:1px solid #d5c4a1;padding-top:1rem;padding-bottom:1rem;position:sticky;top:0;z-index:50} +.dark .site-header{background-color:#282828;border-bottom-color:#504945} .header-container{display:flex;align-items:center;justify-content:space-between} -.site-title{font-size:1.25rem;font-weight:700;color:#1c1b19;text-decoration:none} -.dark .site-title{color:#faf8f5} +.site-title{font-size:1.25rem;font-weight:700;color:#282828;text-decoration:none} +.dark .site-title{color:#fbf1c7} /* Header actions — hidden on mobile */ .header-actions{display:none} @media(min-width:768px){.header-actions{display:flex;align-items:center;gap:1rem}} /* Mobile menu toggle */ -.menu-toggle{display:block;padding:0.5rem;border-radius:0.5rem;background:none;border:none;color:#5c5750;cursor:pointer} +.menu-toggle{display:block;padding:0.5rem;border-radius:0.5rem;background:none;border:none;color:#665c54;cursor:pointer} @media(min-width:768px){.menu-toggle{display:none}} -.dark .menu-toggle{color:#a09a90} +.dark .menu-toggle{color:#a89984} /* Hidden utility */ .hidden{display:none!important} @@ -48,42 +48,46 @@ main.container{padding-top:1.5rem;padding-bottom:1.5rem} /* Reserve sidebar space on desktop to prevent CLS when Alpine.js hydrates collapsible widgets */ @media(min-width:1024px){.sidebar{min-height:600px}} -/* Font faces — in critical CSS so fonts begin downloading immediately. +/* Font faces — keep Inter available for UI elements that use font-sans. font-display:optional prevents FOUT/CLS: font either loads in time or fallback is kept. */ @font-face{font-family:'Inter';font-style:normal;font-display:optional;font-weight:400;src:url(/fonts/inter-latin-400-normal.woff2) format('woff2')} @font-face{font-family:'Inter';font-style:normal;font-display:optional;font-weight:600;src:url(/fonts/inter-latin-600-normal.woff2) format('woff2')} @font-face{font-family:'Inter';font-style:normal;font-display:optional;font-weight:700;src:url(/fonts/inter-latin-700-normal.woff2) format('woff2')} -/* Basic typography — prevent FOUT */ -h1,h2,h3,h4{margin:0;line-height:1.25} -a{color:#b45309} -.dark a{color:#fbbf24} +/* Basic typography */ +h1,h2,h3,h4{margin:0;line-height:1.25;font-weight:900} +a{color:#076678} +.dark a{color:#83a598} /* Prevent flash of unstyled content for nav */ .site-nav{display:flex;align-items:center;gap:1rem} -.site-nav>a,.site-nav .nav-dropdown-trigger{color:#5c5750;text-decoration:none;padding-top:0.5rem;padding-bottom:0.5rem} -.dark .site-nav>a,.dark .site-nav .nav-dropdown-trigger{color:#a09a90} +.site-nav>a,.site-nav .nav-dropdown-trigger{color:#665c54;text-decoration:none;padding-top:0.5rem;padding-bottom:0.5rem} +.dark .site-nav>a,.dark .site-nav .nav-dropdown-trigger{color:#a89984} /* Prevent FOUC — constrain images and SVG icons before Tailwind loads */ img{max-width:100%;height:auto} svg:not(:root):not([width]){width:1.25rem;height:1.25rem} /* Focus indicators — visible in critical CSS before Tailwind loads */ -a:focus-visible{outline:2px solid #b45309;outline-offset:2px;border-radius:2px} -.dark a:focus-visible{outline-color:#fbbf24} -button:focus-visible,[type="button"]:focus-visible{outline:2px solid #b45309;outline-offset:2px;border-radius:4px} -.dark button:focus-visible,.dark [type="button"]:focus-visible{outline-color:#fbbf24} +a:focus-visible{outline:2px solid #076678;outline-offset:2px;border-radius:2px} +.dark a:focus-visible{outline-color:#83a598} +button:focus-visible,[type="button"]:focus-visible{outline:2px solid #076678;outline-offset:2px;border-radius:4px} +.dark button:focus-visible,.dark [type="button"]:focus-visible{outline-color:#83a598} /* Skip link */ -.skip-link{position:absolute;top:-100%;left:0;z-index:100;background:#b45309;color:#fff;padding:0.5rem 1rem;font-weight:600;text-decoration:none} +.skip-link{position:absolute;top:-100%;left:0;z-index:100;background:#076678;color:#fbf1c7;padding:0.5rem 1rem;font-weight:600;text-decoration:none} .skip-link:focus{top:0;outline:none} +/* Selection colors — Gruvbox orange highlight */ +::selection{background:#d65d0e;color:#fbf1c7} +.dark ::selection{background:#fe8019;color:#1d2021} + /* Skeleton loader — visible until Tailwind stylesheet loads */ html.loading main.container>.page-content{display:none} html:not(.loading) .page-skeleton{display:none} @keyframes skel-pulse{0%,100%{opacity:1}50%{opacity:.4}} -.skel-bone{background:#e8e5df;border-radius:.5rem;animation:skel-pulse 1.5s ease-in-out infinite} -.dark .skel-bone{background:#3f3b35} +.skel-bone{background:#d5c4a1;border-radius:.5rem;animation:skel-pulse 1.5s ease-in-out infinite} +.dark .skel-bone{background:#504945} .skel-circle{border-radius:50%} /* Reduced motion — disable animations for users who prefer it */ diff --git a/css/prism-theme.css b/css/prism-theme.css index 86e7393..b34b543 100644 --- a/css/prism-theme.css +++ b/css/prism-theme.css @@ -1,5 +1,5 @@ -/* Syntax Highlighting — PrismJS theme for indiekit-eleventy-theme - Light mode: clean, high-contrast colors +/* Syntax Highlighting — PrismJS Gruvbox-inspired theme + Light mode: warm, muted colors on cream Dark mode: scoped under .dark (Tailwind darkMode: "class") */ /* ── Base code block styling ── */ @@ -30,30 +30,30 @@ pre[class*="language-"] { white-space: normal; } -/* ── Light Mode ── */ +/* ── Light Mode — Gruvbox Light ── */ code[class*="language-"], pre[class*="language-"] { - color: #24292e; + color: #3c3836; } pre[class*="language-"] { - background: #f4f2ee; - border: 1px solid #e1e4e8; + background: #f2e5bc; + border: 1px solid #d5c4a1; } :not(pre) > code[class*="language-"] { - background: #f4f2ee; + background: #f2e5bc; } .token.comment, .token.prolog, .token.doctype, .token.cdata { - color: #586069; + color: #928374; } .token.punctuation { - color: #24292e; + color: #3c3836; } .token.namespace { @@ -67,7 +67,7 @@ pre[class*="language-"] { .token.constant, .token.symbol, .token.deleted { - color: #005cc5; + color: #9d0006; } .token.selector, @@ -76,7 +76,7 @@ pre[class*="language-"] { .token.char, .token.builtin, .token.inserted { - color: #032f62; + color: #79740e; } .token.operator, @@ -84,24 +84,24 @@ pre[class*="language-"] { .token.url, .language-css .token.string, .style .token.string { - color: #d73a49; + color: #af3a03; } .token.atrule, .token.attr-value, .token.keyword { - color: #d73a49; + color: #076678; } .token.function, .token.class-name { - color: #6f42c1; + color: #8f3f71; } .token.regex, .token.important, .token.variable { - color: #e36209; + color: #b57614; } .token.important, @@ -119,37 +119,37 @@ pre[class*="language-"] { /* Line highlighting */ .highlight-line-active { - background-color: #fffbdd; + background-color: #d5c4a1; display: inline-block; width: calc(100% + 2.5em); margin-left: -1.25em; padding-left: 1.25em; } -/* ── Dark Mode ── */ +/* ── Dark Mode — Gruvbox Dark ── */ .dark code[class*="language-"], .dark pre[class*="language-"] { - color: #e1e4e8; + color: #ebdbb2; } .dark pre[class*="language-"] { - background: #161b22; - border-color: #30363d; + background: #1d2021; + border-color: #504945; } .dark :not(pre) > code[class*="language-"] { - background: #161b22; + background: #1d2021; } .dark .token.comment, .dark .token.prolog, .dark .token.doctype, .dark .token.cdata { - color: #8b949e; + color: #928374; } .dark .token.punctuation { - color: #e1e4e8; + color: #ebdbb2; } .dark .token.property, @@ -159,7 +159,7 @@ pre[class*="language-"] { .dark .token.constant, .dark .token.symbol, .dark .token.deleted { - color: #79c0ff; + color: #fb4934; } .dark .token.selector, @@ -168,7 +168,7 @@ pre[class*="language-"] { .dark .token.char, .dark .token.builtin, .dark .token.inserted { - color: #a5d6ff; + color: #b8bb26; } .dark .token.operator, @@ -176,26 +176,26 @@ pre[class*="language-"] { .dark .token.url, .dark .language-css .token.string, .dark .style .token.string { - color: #ff7b72; + color: #fe8019; } .dark .token.atrule, .dark .token.attr-value, .dark .token.keyword { - color: #ff7b72; + color: #83a598; } .dark .token.function, .dark .token.class-name { - color: #d2a8ff; + color: #d3869b; } .dark .token.regex, .dark .token.important, .dark .token.variable { - color: #ffa657; + color: #fabd2f; } .dark .highlight-line-active { - background-color: rgba(56, 139, 253, 0.15); + background-color: rgba(131, 165, 152, 0.15); } diff --git a/css/tailwind.css b/css/tailwind.css index c8d3eb9..3d79016 100644 --- a/css/tailwind.css +++ b/css/tailwind.css @@ -103,10 +103,10 @@ } } -/* Body background — warm stone canvas */ +/* Body — Gruvbox-inspired warm cream canvas with serif typography */ @layer base { body { - @apply bg-surface-50 dark:bg-surface-950 text-surface-900 dark:text-surface-100; + @apply bg-surface-50 dark:bg-surface-950 text-surface-900 dark:text-surface-100 font-serif; } /* P1: Date typography — all