import { defineCollection } from "astro:content"; import { z } from "astro:schema"; import { glob } from "astro/loaders"; // Case studies. Adding a project = one .md file in src/content/projects/. const projects = defineCollection({ loader: glob({ pattern: "**/*.md", base: "./src/content/projects" }), schema: z.object({ title: z.string(), // The one-line "so what" — shown on cards and the case-study header. outcome: z.string(), summary: z.string(), role: z.string(), period: z.string(), stack: z.array(z.string()), featured: z.boolean().default(false), // Lower sorts first on the index + homepage. order: z.number().default(50), // Optional diagram key → rendered by the Diagram component (M3). diagram: z.string().optional(), // Optional cover art → /covers/.webp, rendered above the case header. // Sells the story at a glance; the diagram still carries the architecture. cover: z.string().optional(), links: z .array(z.object({ label: z.string(), href: z.string().url() })) .optional(), }), }); // Blog — write-only, schema-validated, pipeline-publishable. const blog = defineCollection({ loader: glob({ pattern: "**/*.md", base: "./src/content/blog" }), schema: z.object({ title: z.string(), date: z.coerce.date(), summary: z.string(), tags: z.array(z.string()).default([]), draft: z.boolean().default(false), // Optional hero image — a /blog/.webp in public/. Rendered on the post + as the card thumbnail. hero: z.string().optional(), heroAlt: z.string().optional(), }), }); export const collections = { projects, blog };