Skip to content

Commit 7751f6c

Browse files
authored
Merge pull request #7 from Astro-Craft-Theme/chore/template-debt-cleanup
Template-debt cleanup + pixel icons (batches 1-7, buyer data, icon pixelation)
2 parents 51c08cf + bf8a8c7 commit 7751f6c

98 files changed

Lines changed: 1585 additions & 592 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.claude/rules/seo.md

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -70,12 +70,13 @@ brackets and cost a normalizing ternary on every render; it was removed.
7070
none.
7171
- **`getBreadcrumbSchema` requires a _visible_ breadcrumb nav — it is not a free win.** Emitting a
7272
`BreadcrumbList` on a page with no on-screen breadcrumb is markup and schema disagreeing, which is
73-
the one thing structured data must never do. The builder ships unused **on purpose**: it is the
74-
schema counterpart to the `src/components/ui/breadcrumb/` primitive, the same way the other 43
75-
primitives ship unused. Build the nav first, then pass the node — don't reach for the builder
76-
because it happens to exist. (A dead export with no counterpart is a different matter: an unused
77-
helper that sits long enough starts getting cited in other files' docs as though it were part of
78-
the pattern, and then it is load-bearing fiction. Delete those.)
73+
the one thing structured data must never do. It is **now used**: blog posts pair a `BlogPosting`
74+
with a visible breadcrumb nav (built on the `src/components/ui/breadcrumb/` primitive — one of the
75+
39 primitives this template ships), so the schema and the on-screen trail agree. That is the bar
76+
for any new page — build the nav first, then pass the node; don't reach for the builder because it
77+
happens to exist. (A dead export with no counterpart is a different matter: an unused helper that
78+
sits long enough starts getting cited in other files' docs as though it were part of the pattern,
79+
and then it is load-bearing fiction. Delete those.)
7980
- Validate output in Google's Rich Results Test before shipping a new schema type.
8081

8182
## Crawlability & indexation
@@ -94,20 +95,20 @@ brackets and cost a normalizing ternary on every render; it was removed.
9495
hreflang is only meaningful with 2+ locales. Re-adding i18n means re-adding per-locale alternates +
9596
`x-default` in `BaseHead` (git history has the old block).
9697

97-
## Content pages (blog) — wire these when the blog route lands
98+
## Content pages (blog) — shipped with the live blog route
9899

99-
The `blog` + `authors` collections and `@astrojs/mdx` are wired, but **no `/blog/` route ships**
100-
a stated decision, not an oversight, and the README says so in the same words so the two can't
101-
drift. Every project wants its blog shaped differently; the collections are the starting point.
102-
When the route lands, these three come with it (**deliberately not built** until then — YAGNI):
100+
The `/blog/` route is **live** (`src/pages/blog/index.astro` + `[slug].astro`) over the `blog` +
101+
`authors` collections and `@astrojs/mdx`. The three pieces that ride with a content route are built:
103102

104-
- **RSS**: add a dependency-free endpoint (`src/pages/rss.xml.ts`) that maps the `blog` collection
105-
to escaped RSS 2.0 — hand-rolled, like everything else in `head`. Link it from `BaseHead`,
106-
`llms.txt`, and the footer.
107-
- **Article schema + `article` prop** on the post page (pattern above).
108-
- **`heroImage`** is optional in the schema today; make it **required** for a real blog so every post
109-
has an OG image, and add `og:image:width/height` from the bundled `ImageMetadata` (BaseHead already
110-
emits real dims when you pass an `image`).
103+
- **RSS**: a dependency-free endpoint (`src/pages/rss.xml.ts`) maps the `blog` collection to escaped
104+
RSS 2.0 via the `@js/rss` renderer — hand-rolled like everything else in `head` (no `@astrojs/rss`),
105+
self-checked by `src/js/rss.test.ts`. Linked from `BaseHead`, `llms.txt`, and the footer.
106+
- **Article schema + `article` prop** on the post page (`[slug].astro`): `getArticleSchema` emits a
107+
`BlogPosting` with a stable `@id` (`${url}#article`), a `publisher` reference to the site
108+
Organization, and `author.url` (from the author's `authorLink`). `dateModified` is emitted **only**
109+
when the post has an `updatedDate` — never invented from `datePublished`.
110+
- **`heroImage` is required** on blog posts (`content.config.ts``image()`, not `.optional()`), so
111+
every post has an OG image; `BaseHead` emits `og:image:width/height` from the bundled `ImageMetadata`.
111112

112113
## Images & Core Web Vitals
113114

.claude/rules/tailwind.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ export const button = tv({
9292
## `@apply` is allowed here — for shared, cross-cutting classes
9393

9494
This template uses `@apply` inside `@layer components`/`utilities` for reusable semantic classes, and that's
95-
correct usage: `.h1`, `.description`, `.site-container`, `.form__input`, `.primary-focus`,
95+
correct usage: `.h1`, `.description`, `.site-container`, `.primary-focus`,
9696
`.main-text-gradient`. Use `@apply` for a pattern repeated across many unrelated elements; reach for a
9797
**component** (or `tv`) when the thing has structure/variants. Don't `@apply` to "tidy" a one-off class list.
9898

@@ -101,7 +101,7 @@ correct usage: `.h1`, `.description`, `.site-container`, `.form__input`, `.prima
101101
- `@import "tailwindcss";` (one line). Load plugins with `@plugin "@tailwindcss/forms";`.
102102
- Declare layer order explicitly: `@layer theme, base, components, utilities;` and import into a layer when
103103
needed: `@import "./buttons.css" layer(components);`.
104-
- Native CSS nesting is available (`.form__input { &::placeholder { @apply text-base-400; } }`).
104+
- Native CSS nesting is available (`.blog-prose { & a { @apply text-info; } }`, as in global.css).
105105
- Keep the `@theme` token file separate (`tailwind-theme.css`) so it can also be imported into a `.astro`
106106
`<style>` block.
107107

.env.example

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,17 @@ SITE_URL=https://example.com
1111
# reads. Set this to "production" in your production build environment — and nowhere else, or
1212
# preview deploys will start failing on the placeholder too.
1313
# DEPLOY_ENV=production
14+
15+
# --- Contact form -----------------------------------------------------------------------------
16+
# The /contact/ route is server-rendered and sends through Resend (https://resend.com). Both keys
17+
# below are read at REQUEST time, so leaving them unset never breaks the build — the form simply
18+
# reports "not configured yet" until they are present. Create an API key in the Resend dashboard.
19+
RESEND_API_KEY=re_xxxxxxxxxxxxxxxxxxxxxxxxxxxx
20+
21+
# Where contact submissions are delivered — your own inbox.
22+
CONTACT_TO_EMAIL=you@example.com
23+
24+
# Optional. The From address on the sent mail. Defaults to Resend's shared onboarding@resend.dev,
25+
# which ONLY delivers to the Resend account owner's own address (fine for a first smoke test). To
26+
# send to anyone else, verify your own domain in Resend and set a From address on that domain here.
27+
# CONTACT_FROM_EMAIL=hello@yourdomain.com

0 commit comments

Comments
 (0)