From 8f0204b928db56b2b053ad65574ee921e2cd23a4 Mon Sep 17 00:00:00 2001 From: Will Estes Date: Wed, 15 Jul 2026 10:14:21 -0400 Subject: [PATCH] Wire up the new stylesheet: self-host fonts, fix markup/class mismatch MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Self-hosts the five EB Garamond/Source Serif 4/Inter woff2 files the new CSS's @font-face rules point at (static/fonts/ didn't exist before now, so those requests just 404'd). Removes the old Google Fonts link that was pulling Roboto/Open Sans/Source Code Pro — fonts the new stylesheet never references. Updates baseof.html's header/footer markup from the old scaffold's .site/.brand/.inner classes to .site-header/.site-title/.site-footer, matching what the new CSS actually targets — without this the header and footer rendered completely unstyled. Adds the component styles the new CSS didn't include at all: .btn, .enroll-form/.enroll-status/.enroll-download, .course-hero and friends, and .skip-link. Most importantly .field-honeypot — its absence meant the anti-spam honeypot field rendered visibly on the page instead of off-screen, which would silently break a real visitor's signup if they filled it in. Co-Authored-By: Claude Sonnet 5 --- assets/css/main.css | 635 +++++++++++++++--------- layouts/_default/baseof.html | 35 +- static/fonts/EBGaramond-Medium.woff2 | Bin 0 -> 25376 bytes static/fonts/EBGaramond-Regular.woff2 | Bin 0 -> 23848 bytes static/fonts/Inter-Regular.woff2 | Bin 0 -> 23804 bytes static/fonts/SourceSerif4-Italic.woff2 | Bin 0 -> 20132 bytes static/fonts/SourceSerif4-Regular.woff2 | Bin 0 -> 20112 bytes 7 files changed, 420 insertions(+), 250 deletions(-) create mode 100644 static/fonts/EBGaramond-Medium.woff2 create mode 100644 static/fonts/EBGaramond-Regular.woff2 create mode 100644 static/fonts/Inter-Regular.woff2 create mode 100644 static/fonts/SourceSerif4-Italic.woff2 create mode 100644 static/fonts/SourceSerif4-Regular.woff2 diff --git a/assets/css/main.css b/assets/css/main.css index 07bf6e7..dbbe04a 100644 --- a/assets/css/main.css +++ b/assets/css/main.css @@ -1,214 +1,378 @@ +/* ========================================================================== + Michael Ferrara — site stylesheet + Fonts: EB Garamond (headings), Source Serif 4 (body), Inter (UI chrome) + Palette: parchment / ink / oxblood / brass + ========================================================================== */ + +/* -------------------------------------------------------------------------- + 1. Font loading + Self-hosted is preferable to a Google Fonts CDN call for both + privacy and reliability. Drop the .woff2 files in /assets/fonts/ + and adjust paths below. If you'd rather use Google Fonts directly, + swap this block for @import statements or a in your head + partial instead — either works, just don't do both. + -------------------------------------------------------------------------- */ + +@font-face { + font-family: "EB Garamond"; + src: url("/fonts/EBGaramond-Regular.woff2") format("woff2"); + font-weight: 400; + font-style: normal; + font-display: swap; +} + +@font-face { + font-family: "EB Garamond"; + src: url("/fonts/EBGaramond-Medium.woff2") format("woff2"); + font-weight: 600; + font-style: normal; + font-display: swap; +} + +@font-face { + font-family: "Source Serif 4"; + src: url("/fonts/SourceSerif4-Regular.woff2") format("woff2"); + font-weight: 400; + font-style: normal; + font-display: swap; +} + +@font-face { + font-family: "Source Serif 4"; + src: url("/fonts/SourceSerif4-Italic.woff2") format("woff2"); + font-weight: 400; + font-style: italic; + font-display: swap; +} + +@font-face { + font-family: "Inter"; + src: url("/fonts/Inter-Regular.woff2") format("woff2"); + font-weight: 400; + font-style: normal; + font-display: swap; +} + +/* -------------------------------------------------------------------------- + 2. Design tokens + -------------------------------------------------------------------------- */ + :root { - color-scheme: light dark; + /* Color */ + --color-bg: #f7f3ea; + --color-bg-raised: #efe9db; /* cards, code blocks, pull-quote background */ + --color-ink: #2a2521; /* body text */ + --color-ink-heading: #1c1712; /* headings, strongest contrast */ + --color-accent: #7a2e2e; /* links, rules, emphasis — oxblood */ + --color-accent-hover: #5c2222; + --color-brass: #8c7a5b; /* metadata, dividers, secondary accent */ + --color-border: #ddd3bd; - /* TODO: placeholder palette copied from reground.org's site — restyle to - match Michael's own branding before launch. */ - --bg: #faf8f4; - --bg-raised: #f5f1e8; - --fg: #333333; - --fg-muted: #6b6560; - --border: #e5ddd0; + /* Type */ + --font-body: "Source Serif 4", Georgia, "Times New Roman", serif; + --font-heading: "EB Garamond", "Palatino Linotype", Georgia, serif; + --font-ui: "Inter", "IBM Plex Sans", -apple-system, sans-serif; - --slate: #4a6fa5; - --rose: #d9a9b0; - --teal: #009688; - --taupe: #b19a75; + --font-size-base: 19px; + --line-height-base: 1.65; + --measure: 70ch; /* max line length for body text */ - --heading: var(--slate); - --accent: var(--slate); - --accent-fg: #ffffff; - --cta: #007f73; - --cta-fg: #ffffff; - - --radius: 0.5rem; - --max-width: 42rem; - - --font-heading: "Roboto", -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif; - --font-body: "Open Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif; - --font-accent: "Source Code Pro", "Courier New", monospace; -} -@media (prefers-color-scheme: dark) { - :root { - --bg: #1c1917; - --bg-raised: #262220; - --fg: #f0ebe3; - --fg-muted: #a89e92; - --border: #3a352f; - - --slate: #8fa8d1; - --rose: #e6c3ca; - --teal: #2dd4c4; - --taupe: #cbb190; - - --heading: var(--slate); - --accent: var(--slate); - --accent-fg: #14161a; - --cta: var(--teal); - --cta-fg: #0f1115; - } + /* Spacing scale */ + --space-1: 0.5rem; + --space-2: 1rem; + --space-3: 1.75rem; + --space-4: 3rem; + --space-5: 5rem; } -* { box-sizing: border-box; } +/* -------------------------------------------------------------------------- + 3. Base + -------------------------------------------------------------------------- */ + +*, +*::before, +*::after { + box-sizing: border-box; +} + +html { + font-size: 100%; +} body { - margin: 0; + background-color: var(--color-bg); + color: var(--color-ink); font-family: var(--font-body); - line-height: 1.6; - background: var(--bg); - color: var(--fg); - display: flex; - flex-direction: column; - min-height: 100vh; + font-size: var(--font-size-base); + line-height: var(--line-height-base); + margin: 0; + -webkit-font-smoothing: antialiased; } -a { color: var(--accent); } +/* Main content column */ +main { + max-width: var(--measure); + margin: 0 auto; + padding: var(--space-4) var(--space-2); +} + +/* -------------------------------------------------------------------------- + 4. Headings + -------------------------------------------------------------------------- */ + +h1, h2, h3, h4, h5, h6 { + font-family: var(--font-heading); + color: var(--color-ink-heading); + font-weight: 600; + line-height: 1.25; + margin-top: var(--space-4); + margin-bottom: var(--space-2); +} + +h1 { + font-size: 2.6rem; + margin-top: 0; +} + +h2 { + font-size: 2rem; + border-bottom: 1px solid var(--color-border); + padding-bottom: var(--space-1); +} + +h3 { + font-size: 1.5rem; +} + +h4 { + font-size: 1.2rem; + font-style: italic; + font-weight: 400; +} + +/* -------------------------------------------------------------------------- + 5. Body text elements + -------------------------------------------------------------------------- */ + +p { + margin: 0 0 var(--space-2) 0; +} + +a { + color: var(--color-accent); + text-decoration: underline; + text-decoration-thickness: 1px; + text-underline-offset: 0.15em; +} + +a:hover, +a:focus { + color: var(--color-accent-hover); +} + +/* Visible focus state — important for keyboard/screen-reader navigation */ +a:focus-visible, +button:focus-visible, +input:focus-visible { + outline: 2px solid var(--color-accent); + outline-offset: 2px; +} + +strong { + color: var(--color-ink-heading); +} + +em, i { + font-style: italic; +} + +blockquote { + margin: var(--space-3) 0; + padding: var(--space-2) var(--space-3); + border-left: 3px solid var(--color-accent); + background-color: var(--color-bg-raised); + font-style: italic; +} + +blockquote p:last-child { + margin-bottom: 0; +} + +hr { + border: none; + border-top: 1px solid var(--color-brass); + width: 4rem; + margin: var(--space-4) auto; +} + +/* -------------------------------------------------------------------------- + 6. Lists + -------------------------------------------------------------------------- */ + +ul, ol { + padding-left: 1.4em; + margin: 0 0 var(--space-2) 0; +} + +li { + margin-bottom: 0.4em; +} + +/* -------------------------------------------------------------------------- + 7. Code / pre + Kept legible rather than decorative — likely to appear rarely on this + site, but essays quoting Latin, TSV data, or Canon law citations + sometimes want a monospace treatment. + -------------------------------------------------------------------------- */ + +code, pre { + font-family: "Courier New", monospace; + font-size: 0.9em; +} + +code { + background-color: var(--color-bg-raised); + padding: 0.1em 0.35em; + border-radius: 3px; +} + +pre { + background-color: var(--color-bg-raised); + padding: var(--space-2); + overflow-x: auto; + border-radius: 4px; + border: 1px solid var(--color-border); +} + +pre code { + background: none; + padding: 0; +} + +/* -------------------------------------------------------------------------- + 8. UI chrome — nav, metadata, tags + Sans-serif reserved for these elements only. Never used for body prose. + -------------------------------------------------------------------------- */ + +.site-header, +.site-footer, +nav, +.meta, +.tags { + font-family: var(--font-ui); +} + +.site-header { + padding: var(--space-3) var(--space-2); + border-bottom: 1px solid var(--color-border); +} + +.site-title { + font-family: var(--font-heading); + font-size: 1.6rem; + color: var(--color-ink-heading); + text-decoration: none; +} + +nav a { + text-decoration: none; + color: var(--color-ink); + margin-right: var(--space-2); + font-size: 0.95rem; + letter-spacing: 0.02em; +} + +nav a:hover { + color: var(--color-accent); +} + +.meta { + color: var(--color-brass); + font-size: 0.85rem; + letter-spacing: 0.02em; +} + +.site-footer { + border-top: 1px solid var(--color-border); + padding: var(--space-3) var(--space-2); + color: var(--color-brass); + font-size: 0.85rem; + text-align: center; +} + +/* -------------------------------------------------------------------------- + 9. Skip link + Off-screen until focused — the same pattern needed for any keyboard/ + screen-reader user to bypass the header nav straight to
. + -------------------------------------------------------------------------- */ .skip-link { position: absolute; left: -9999px; top: 0; z-index: 100; - background: var(--cta); - color: var(--cta-fg); - padding: 0.75rem 1.25rem; - border-radius: 0 0 var(--radius) 0; + background-color: var(--color-accent); + color: var(--color-bg); + font-family: var(--font-ui); + padding: var(--space-1) var(--space-2); + border-radius: 0 0 4px 0; } + .skip-link:focus { left: 0; } -h1, h2, h3 { - font-family: var(--font-heading); - color: var(--heading); - line-height: 1.25; -} - -code, kbd, .accent-text { - font-family: var(--font-accent); -} - -header.site { - background: var(--slate); -} -header.site .inner { - max-width: var(--max-width); - margin: 0 auto; - padding: 1.25rem 1.5rem; - display: flex; - align-items: center; - justify-content: space-between; - gap: 1rem; - flex-wrap: wrap; -} -header.site .brand { - font-family: var(--font-heading); - font-weight: 700; - font-size: 1.1rem; - color: var(--bg); - text-decoration: none; -} -header.site nav { - display: flex; - gap: 1.5rem; -} -header.site nav a { - color: var(--bg); - opacity: 0.85; - text-decoration: none; - font-size: 0.95rem; -} -header.site nav a:hover { - opacity: 1; - text-decoration: underline; - text-decoration-color: var(--rose); - text-decoration-thickness: 2px; - text-underline-offset: 3px; -} -header.site a:focus-visible { - outline-color: var(--bg); -} - -main { - flex: 1; - max-width: var(--max-width); - margin: 0 auto; - padding: 4rem 1.5rem; - width: 100%; -} - -footer.site { - background: var(--bg-raised); - border-top: 1px solid var(--taupe); - margin-top: 2rem; -} -footer.site .inner { - max-width: var(--max-width); - margin: 0 auto; - padding: 1.5rem; - display: flex; - align-items: center; - justify-content: space-between; - gap: 1rem; - flex-wrap: wrap; - font-size: 0.85rem; - color: var(--fg-muted); -} -footer.site nav { - display: flex; - gap: 1.25rem; -} -footer.site nav a { - color: var(--slate); - text-decoration: none; -} -footer.site nav a:hover { - text-decoration: underline; - text-decoration-color: var(--rose); - text-decoration-thickness: 2px; - text-underline-offset: 3px; -} +/* -------------------------------------------------------------------------- + 10. Buttons, form fields, and the reader-magnet enrollment funnel + (layouts/partials/course-enroll-form.html, layouts/courses/single.html) + -------------------------------------------------------------------------- */ .btn { display: inline-block; - padding: 0.75rem 1.5rem; - border-radius: var(--radius); - background: var(--cta); - color: var(--cta-fg); - text-decoration: none; + font-family: var(--font-ui); font-weight: 600; + font-size: 0.95rem; + letter-spacing: 0.02em; + text-decoration: none; + color: var(--color-bg); + background-color: var(--color-accent); border: none; - font-size: 1rem; + border-radius: 4px; + padding: 0.75rem 1.5rem; cursor: pointer; } -.btn:hover { opacity: 0.9; } -a:focus-visible, button:focus-visible { - outline: 2px solid var(--cta); - outline-offset: 2px; +.btn:hover { + background-color: var(--color-accent-hover); + color: var(--color-bg); } label { display: block; + font-family: var(--font-ui); + font-size: 0.85rem; font-weight: 600; - font-size: 0.9rem; margin-bottom: 0.35rem; } -input, textarea { + +input[type="email"], +input[type="text"], +textarea { width: 100%; - padding: 0.65rem 0.75rem; - border-radius: var(--radius); - border: 1px solid var(--border); - background: var(--bg-raised); - color: var(--fg); - font-family: inherit; + font-family: var(--font-ui); font-size: 1rem; - margin-bottom: 1.25rem; -} -input:focus, textarea:focus { - outline: 2px solid var(--cta); - outline-offset: 1px; + color: var(--color-ink); + background-color: var(--color-bg-raised); + border: 1px solid var(--color-border); + border-radius: 4px; + padding: 0.65rem 0.75rem; + margin-bottom: var(--space-2); } +/* Honeypot: must stay genuinely hidden from sighted users (not just + visually de-emphasized), or a real visitor filling it in silently kills + their own signup — see course-enroll-form.html's `if (form.website.value) + return;` check. */ .field-honeypot { position: absolute; left: -9999px; @@ -217,92 +381,105 @@ input:focus, textarea:focus { overflow: hidden; } -/* Course/freebie landing pages (layouts/courses/single.html) */ .course-hero { text-align: center; } + .course-subhead { font-style: italic; - color: var(--fg-muted); + color: var(--color-brass); margin-top: 0; } + .course-social-proof { font-style: italic; font-size: 0.9rem; - color: var(--fg-muted); + color: var(--color-brass); } + .enroll-form { max-width: 24rem; - margin: 1.5rem auto; + margin: var(--space-3) auto; text-align: left; } + .enroll-status { text-align: center; + font-family: var(--font-ui); + font-size: 0.9rem; } + .enroll-download { text-align: center; - margin-top: 1rem; + margin-top: var(--space-2); } -.course-credibility, -.course-curriculum { - background: var(--bg-raised); - border: 1px solid var(--border); - border-radius: var(--radius); - padding: 2rem; - margin: 3rem 0; -} -.course-bullets { - list-style: none; - padding: 0; - margin: 1.5rem 0 0; -} -.course-bullets li { - position: relative; - padding-left: 1.75rem; - margin-bottom: 0.75rem; -} -.course-bullets li::before { - content: "✓"; - position: absolute; - left: 0; - color: var(--cta); - font-weight: 700; -} -.course-curriculum-list { - list-style: none; - padding: 0; - margin: 1.5rem 0 0; -} -.course-curriculum-list li { - margin-bottom: 1rem; -} -.course-day-label { - font-family: var(--font-heading); - color: var(--cta); - font-weight: 700; -} .course-repeat-cta { text-align: center; - margin-top: 3rem; + margin-top: var(--space-5); } -main img { +/* -------------------------------------------------------------------------- + 11. Post/article-specific + -------------------------------------------------------------------------- */ + +.post-title { + margin-bottom: var(--space-1); +} + +.post-meta { + margin-bottom: var(--space-4); +} + +.post-content h2:first-of-type { + margin-top: var(--space-3); +} + +/* Drop cap for opening paragraph — optional, purely decorative flourish; + delete this rule if it doesn't earn its keep in practice */ +.post-content > p:first-of-type::first-letter { + font-family: var(--font-heading); + font-size: 3.2em; float: left; - width: 220px; - height: auto; - margin: 0 1.5rem 1rem 0; - border-radius: var(--radius); + line-height: 0.8; + padding-right: 0.08em; + padding-top: 0.05em; + color: var(--color-accent); } -main h2:nth-of-type(2) { - clear: left; -} -@media (max-width: 30rem) { - main img { - float: none; - width: 100%; - max-width: 220px; - margin: 0 auto 1.5rem; - display: block; + +/* -------------------------------------------------------------------------- + 12. Responsive + -------------------------------------------------------------------------- */ + +@media (max-width: 640px) { + :root { + --font-size-base: 17px; + } + + h1 { + font-size: 2.1rem; + } + + h2 { + font-size: 1.6rem; + } + + main { + padding: var(--space-3) var(--space-2); + } +} + +/* -------------------------------------------------------------------------- + 13. Print + -------------------------------------------------------------------------- */ + +@media print { + body { + background: #fff; + color: #000; + } + + nav, .site-footer { + display: none; } } diff --git a/layouts/_default/baseof.html b/layouts/_default/baseof.html index cf80d68..2a54d8c 100644 --- a/layouts/_default/baseof.html +++ b/layouts/_default/baseof.html @@ -5,9 +5,6 @@ {{ if .IsHome }}{{ .Site.Title }}{{ else }}{{ .Title }} · {{ .Site.Title }}{{ end }} - - - {{ $css := resources.Get "css/main.css" }} {{ if hugo.IsProduction }} {{ $css = $css | minify | fingerprint }} @@ -19,30 +16,26 @@ -
-
- {{ .Site.Title }} - -
+
{{ block "main" . }}{{ end }}
-