commit b39dcda4a167ca4471e86897a157fe8a80737781 Author: Will Estes Date: Thu Jul 16 12:02:47 2026 -0400 Initial scaffold: submissions page + reader-magnet stub Mirrors twosquirrelspress-site's submissions form and michaelferrara-site's gift/course-enroll pattern. Gift page content, cover art, and the download file are stubs until the real reader-magnet is ready. Co-Authored-By: Claude Sonnet 5 diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml new file mode 100644 index 0000000..e66bc42 --- /dev/null +++ b/.gitea/workflows/deploy.yml @@ -0,0 +1,16 @@ +name: deploy +on: + push: + branches: [master] +jobs: + deploy: + runs-on: ubuntu-latest + container: + image: hugomods/hugo:exts + volumes: + - /var/www/thistleandmoth.org:/var/www/thistleandmoth.org + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + - run: hugo --minify -d /var/www/thistleandmoth.org diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1c3fa73 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +public/ +resources/ +.hugo_build.lock diff --git a/.tool-versions b/.tool-versions new file mode 100644 index 0000000..fb31987 --- /dev/null +++ b/.tool-versions @@ -0,0 +1 @@ +hugo 0.124.1 diff --git a/assets/css/main.css b/assets/css/main.css new file mode 100644 index 0000000..da39a35 --- /dev/null +++ b/assets/css/main.css @@ -0,0 +1,494 @@ +/* ========================================================================== + Thistle & Moth — 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 */ + --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; + + /* 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; + + --font-size-base: 19px; + --line-height-base: 1.65; + --measure: 70ch; /* max line length for body text */ + + /* Spacing scale */ + --space-1: 0.5rem; + --space-2: 1rem; + --space-3: 1.75rem; + --space-4: 3rem; + --space-5: 5rem; +} + +/* -------------------------------------------------------------------------- + 3. Base + -------------------------------------------------------------------------- */ + +*, +*::before, +*::after { + box-sizing: border-box; +} + +html { + font-size: 100%; +} + +body { + background-color: var(--color-bg); + color: var(--color-ink); + font-family: var(--font-body); + font-size: var(--font-size-base); + line-height: var(--line-height-base); + margin: 0; + -webkit-font-smoothing: antialiased; +} + +/* 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-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; +} + +/* -------------------------------------------------------------------------- + 10. Buttons, form fields, and the reader-magnet enrollment funnel + (layouts/partials/course-enroll-form.html, layouts/courses/single.html) + -------------------------------------------------------------------------- */ + +.btn { + display: inline-block; + 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; + border-radius: 4px; + padding: 0.75rem 1.5rem; + cursor: pointer; +} + +.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; + margin-bottom: 0.35rem; +} + +input[type="email"], +input[type="text"], +textarea { + width: 100%; + font-family: var(--font-ui); + font-size: 1rem; + 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; + width: 1px; + height: 1px; + overflow: hidden; +} + +.course-hero { + text-align: center; +} + +.course-cover { + max-width: 14rem; + width: 100%; + height: auto; + border-radius: 4px; + box-shadow: 0 4px 16px rgba(0, 0, 0, 0.2); + margin: 0 auto var(--space-3); +} + +.course-subhead { + font-style: italic; + color: var(--color-brass); + margin-top: 0; +} + +.course-social-proof { + font-style: italic; + font-size: 0.9rem; + color: var(--color-brass); +} + +.enroll-form { + max-width: 24rem; + 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: var(--space-2); +} + +.course-repeat-cta { + text-align: center; + margin-top: var(--space-5); +} + +/* -------------------------------------------------------------------------- + 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; + line-height: 0.8; + padding-right: 0.08em; + padding-top: 0.05em; + color: var(--color-accent); +} + +/* -------------------------------------------------------------------------- + 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/content/_index.md b/content/_index.md new file mode 100644 index 0000000..fe31299 --- /dev/null +++ b/content/_index.md @@ -0,0 +1,9 @@ +--- +title: "Thistle & Moth" +description: "TODO: one-line description of Thistle & Moth" +--- + +TODO: Thistle & Moth homepage copy goes here. + +Get a free story: [download the reader magnet](/gift). Writers: see our +[submission guidelines](/submissions). diff --git a/content/contact.md b/content/contact.md new file mode 100644 index 0000000..78aa55b --- /dev/null +++ b/content/contact.md @@ -0,0 +1,5 @@ +--- +title: "Contact" +layout: "contact" +description: "Get in touch with Thistle & Moth." +--- diff --git a/content/gift-thanks/index.md b/content/gift-thanks/index.md new file mode 100644 index 0000000..3c9091b --- /dev/null +++ b/content/gift-thanks/index.md @@ -0,0 +1,14 @@ +--- +title: "Thanks! Here's your story." +description: "TODO: one-line description once the real reader-magnet file is ready." +--- + +TODO: this is a stub. Once the real file is uploaded to the +`thistleandmoth-downloads` bucket, link it here the same way +`content/gift/index.md`'s `download_url` does. + +[Download the story](https://downloads.thistleandmoth.org/reader-magnet/story.epub) + +Talk soon, + +Thistle & Moth diff --git a/content/gift/index.md b/content/gift/index.md new file mode 100644 index 0000000..44b649b --- /dev/null +++ b/content/gift/index.md @@ -0,0 +1,38 @@ +--- +title: "TODO: Reader Magnet Title" +description: "TODO: one- to two-sentence hook for the free story/piece being given away." +type: "courses" +eec_slug: "reader-magnet" + +# Optional italic line under the title, for handling an objection up front. +hero_subhead: "TODO: this story, occasional emails when something new comes out, and other things you want in your inbox." + +# Label on the signup form's submit button. +cta_text: "Send it to me" + +# Cover image, hosted in the public downloads bucket alongside the real +# file. STUB — thistleandmoth-downloads is currently empty; these paths +# won't resolve until the real cover/file are uploaded (see the tofu +# linode_object_storage_bucket.thistleandmoth_downloads resource). +cover_image: "https://downloads.thistleandmoth.org/reader-magnet/cover.jpg" + +# Optional: a landscape (1200x630) variant of the cover for social-share +# previews (og:image/Twitter card). Falls back to cover_image if unset -- +# see layouts/_default/baseof.html. +social_image: "https://downloads.thistleandmoth.org/reader-magnet/cover_social.jpg" + +# Direct link to the file in the public downloads bucket — shown as an +# on-page button immediately after a successful signup, independent of the +# welcome email (see layouts/partials/course-enroll-form.html). STUB — no +# file uploaded yet. +download_url: "https://downloads.thistleandmoth.org/reader-magnet/story.epub" +download_text: "Download now" + +# Optional heading above the repeated signup form at the bottom of the page. +repeat_cta_heading: "Want it?" +--- +TODO: reader-magnet page copy goes here. + +This page is a stub — the cover image and download link above won't +resolve until real cover art and a real download file are uploaded to the +`thistleandmoth-downloads` bucket, and this copy is replaced. diff --git a/content/privacy.md b/content/privacy.md new file mode 100644 index 0000000..084a652 --- /dev/null +++ b/content/privacy.md @@ -0,0 +1,65 @@ +--- +title: "Privacy Policy" +description: "How thistleandmoth.org collects, uses, and protects your information." +--- + +_Last updated: July 2026_ + +This policy explains what information this site collects through use of +thistleandmoth.org, and what happens to it. + +## What this site collects + +Depending on how you use the site, that may include: + +- Your name, email address, and message, when you submit the contact form. +- Your email address, if you sign up for the free story. +- Your email address and name, if given, if you opt in to ongoing updates. +- Your name, email, manuscript, bio, and (optionally) a headshot, if you + submit work through the [submissions page](/submissions/). + +This site doesn't use third-party analytics, ad trackers, or tracking +pixels. Everything above runs on infrastructure operated directly — +nothing is handed to a third-party marketing platform. + +## Why this site collects it + +- To respond to messages sent through the contact form. +- To deliver the free story you signed up for. +- To review manuscripts submitted for consideration. +- To send periodic updates to people who've explicitly opted in — never + as a side effect of simply using the site. + +## What this site doesn't do + +- This site doesn't sell or rent your information to anyone. +- This site doesn't share it with third parties except the infrastructure + providers necessary to run the site and send email (e.g. the hosting + provider and its network) — none of whom get to use it for their own + purposes. + +## Your control over it + +- **Unsubscribe**: every ongoing-update email includes an unsubscribe + link. Clicking it removes you from that list immediately. +- **The free story**: this is a one-off signup with no ongoing + subscription — once you've received it, there's nothing further to opt + out of unless you also joined the ongoing updates list. +- **Deletion**: reach out through [the contact form](/contact/) and + your information will be deleted from these systems. + +## Security + +Your information is stored on infrastructure controlled directly, not +handed off to third-party SaaS platforms. That doesn't make it +invulnerable — no system is — but it does mean there's exactly one place +your data lives, and one party accountable for it. + +## Changes + +If this policy changes in a way that matters, the date at the top of this +page will be updated. + +## Questions + +[Get in touch](/contact/). diff --git a/content/submissions/_index.md b/content/submissions/_index.md new file mode 100644 index 0000000..d669cc8 --- /dev/null +++ b/content/submissions/_index.md @@ -0,0 +1,8 @@ +--- +title: "Submissions" +description: "How to submit work to Thistle & Moth." +--- + +TODO: describe what Thistle & Moth is looking for (genre, form, length, open calls). + +Send us your manuscript along with a short bio, a brief description of the piece, and a headshot if you have one — the form below covers all of it. diff --git a/content/terms.md b/content/terms.md new file mode 100644 index 0000000..0d40be6 --- /dev/null +++ b/content/terms.md @@ -0,0 +1,46 @@ +--- +title: "Terms of Use" +description: "Terms for using thistleandmoth.org, its free story, and its submissions." +--- + +_Last updated: July 2026_ + +These terms cover using thistleandmoth.org, its free story, and +submitting the contact or submissions forms. + +## Using this site + +This site and its free story are provided as-is, for entertainment +purposes. + +## The free story + +The story belongs to Thistle & Moth. You're welcome to read and enjoy it; +you're not entitled to redistribute, resell, or republish it without +asking first. + +## Submissions + +Submitting a manuscript through [the submissions page](/submissions/) +doesn't transfer any rights in it — you retain ownership of your work +unless a separate agreement says otherwise. Submitting doesn't guarantee +a response or acceptance. + +## No warranty + +This site and its content are provided without warranties of any kind, +express or implied. + +## Liability + +To the extent the law allows, Thistle & Moth isn't liable for damages +arising from your use of this site or its content. + +## Changes + +These terms may be updated as the site changes. Material changes will +update the date at the top of this page. + +## Questions + +[Get in touch](/contact/). diff --git a/hugo.toml b/hugo.toml new file mode 100644 index 0000000..cb78958 --- /dev/null +++ b/hugo.toml @@ -0,0 +1,35 @@ +baseURL = "https://thistleandmoth.org/" +locale = "en-US" +title = "Thistle & Moth" + +enableRobotsTXT = true +buildDrafts = false +buildFuture = false +buildExpired = false +disableKinds = ["taxonomy", "term"] + +[params] + env = "production" + description = "TODO: one-line description of Thistle & Moth" + author = "Thistle & Moth" + eec_base_url = "https://eec.thistleandmoth.org" + +[[menu.main]] + name = "Submissions" + url = "/submissions/" + weight = 10 + +[[menu.footer]] + name = "Contact" + url = "/contact/" + weight = 10 + +[[menu.footer]] + name = "Privacy" + url = "/privacy/" + weight = 20 + +[[menu.footer]] + name = "Terms" + url = "/terms/" + weight = 30 diff --git a/layouts/_default/baseof.html b/layouts/_default/baseof.html new file mode 100644 index 0000000..7a29dae --- /dev/null +++ b/layouts/_default/baseof.html @@ -0,0 +1,47 @@ + + + + + + {{ if .IsHome }}{{ .Site.Title }}{{ else }}{{ .Title }} · {{ .Site.Title }}{{ end }} + + {{ with .Params.social_image | default .Params.cover_image }} + + + + + {{ end }} + {{ $css := resources.Get "css/main.css" }} + {{ if hugo.IsProduction }} + {{ $css = $css | minify | fingerprint }} + + {{ else }} + + {{ end }} + + + + + + +
+ {{ block "main" . }}{{ end }} +
+ +
+ © {{ now.Year }} {{ .Site.Title }} + +
+ + diff --git a/layouts/_default/contact.html b/layouts/_default/contact.html new file mode 100644 index 0000000..8b3453c --- /dev/null +++ b/layouts/_default/contact.html @@ -0,0 +1,60 @@ +{{ define "main" }} +

Get in touch

+

Tell me a bit about what you're working on — I read every message myself.

+ +
+ + + + + + + + + + + + +
+

+ + +{{ end }} diff --git a/layouts/_default/list.html b/layouts/_default/list.html new file mode 100644 index 0000000..426e8db --- /dev/null +++ b/layouts/_default/list.html @@ -0,0 +1,9 @@ +{{ define "main" }} +

{{ .Title }}

+{{ .Content }} + +{{ end }} diff --git a/layouts/_default/single.html b/layouts/_default/single.html new file mode 100644 index 0000000..17b274b --- /dev/null +++ b/layouts/_default/single.html @@ -0,0 +1,4 @@ +{{ define "main" }} +

{{ .Title }}

+{{ .Content }} +{{ end }} diff --git a/layouts/courses/single.html b/layouts/courses/single.html new file mode 100644 index 0000000..812a0bb --- /dev/null +++ b/layouts/courses/single.html @@ -0,0 +1,43 @@ +{{ define "main" }} +
+

{{ .Title }}

+ {{ with .Params.cover_image }}{{ $.Title }} cover{{ end }} + {{ with .Params.hero_subhead }}

{{ . }}

{{ end }} + + {{ partial "course-enroll-form.html" (dict "id" "top" "page" .) }} + + {{ with .Params.social_proof }}

{{ . }}

{{ end }} +
+ +{{ if or .Params.credibility_heading .Params.credibility_bullets }} +
+ {{ with .Params.credibility_heading }}

{{ . }}

{{ end }} + {{ with .Params.credibility_bullets }} +
    + {{ range . }}
  • {{ . | markdownify }}
  • {{ end }} +
+ {{ end }} +
+{{ end }} + +{{ if or .Params.curriculum_heading .Params.curriculum_items }} +
+ {{ with .Params.curriculum_heading }}

{{ . }}

{{ end }} + {{ with .Params.curriculum_intro }}

{{ . }}

{{ end }} + {{ with .Params.curriculum_items }} +
    + {{ range . }} +
  1. {{ with .label }}{{ . }} {{ end }}{{ .text | markdownify }}
  2. + {{ end }} +
+ {{ end }} +
+{{ end }} + +{{ .Content }} + +
+ {{ with .Params.repeat_cta_heading }}

{{ . }}

{{ end }} + {{ partial "course-enroll-form.html" (dict "id" "bottom" "page" .) }} +
+{{ end }} diff --git a/layouts/index.html b/layouts/index.html new file mode 100644 index 0000000..17b274b --- /dev/null +++ b/layouts/index.html @@ -0,0 +1,4 @@ +{{ define "main" }} +

{{ .Title }}

+{{ .Content }} +{{ end }} diff --git a/layouts/partials/course-enroll-form.html b/layouts/partials/course-enroll-form.html new file mode 100644 index 0000000..e0dcd76 --- /dev/null +++ b/layouts/partials/course-enroll-form.html @@ -0,0 +1,55 @@ +{{ $id := .id }} +{{ $page := .page }} +
+ + + + + + +
+

+{{ with $page.Params.download_url }} + +{{ end }} + + diff --git a/layouts/submissions/list.html b/layouts/submissions/list.html new file mode 100644 index 0000000..3339b84 --- /dev/null +++ b/layouts/submissions/list.html @@ -0,0 +1,68 @@ +{{ define "main" }} +

{{ .Title }}

+{{ .Content }} + +
+ + + + + + + + + + + + + + + + + +

Markdown preferred. Under ~15MB.

+ + + +

Under ~5MB.

+ + + + +
+

+ + +{{ end }} diff --git a/static/fonts/EBGaramond-Medium.woff2 b/static/fonts/EBGaramond-Medium.woff2 new file mode 100644 index 0000000..6dcab99 Binary files /dev/null and b/static/fonts/EBGaramond-Medium.woff2 differ diff --git a/static/fonts/EBGaramond-Regular.woff2 b/static/fonts/EBGaramond-Regular.woff2 new file mode 100644 index 0000000..6567c0f Binary files /dev/null and b/static/fonts/EBGaramond-Regular.woff2 differ diff --git a/static/fonts/Inter-Regular.woff2 b/static/fonts/Inter-Regular.woff2 new file mode 100644 index 0000000..41f6888 Binary files /dev/null and b/static/fonts/Inter-Regular.woff2 differ diff --git a/static/fonts/SourceSerif4-Italic.woff2 b/static/fonts/SourceSerif4-Italic.woff2 new file mode 100644 index 0000000..f1d4ac7 Binary files /dev/null and b/static/fonts/SourceSerif4-Italic.woff2 differ diff --git a/static/fonts/SourceSerif4-Regular.woff2 b/static/fonts/SourceSerif4-Regular.woff2 new file mode 100644 index 0000000..12f5b10 Binary files /dev/null and b/static/fonts/SourceSerif4-Regular.woff2 differ