





What is inside
Brass Studio is built for a brand and digital studio that sells strategy, identity and web under one roof. A video hero and a short loading intro set the tone, while services, projects and posts live in typed Markdown collections and every sentence on the site sits in one labels file, ready to rebrand.
A video hero that waits for itself
The loading screen spells the studio name and lifts only when the hero video can play, capped at six seconds. It shows once per visit, not on every page change.
Pages that wipe in, not reload
The View Transitions router keeps the navbar alive between pages, and the new page wipes in from the bottom. Nothing flashes white.
Projects that filter themselves
Every distinct category in the project files becomes a filter on the projects page. The home hero shows three of them, picked at random on every visit.
Services that are their own pages
A service file becomes a route with summary, duration, tags and gallery, a row on the home page and an entry in the other-services list. Nothing to register.
Animations you add with an attribute
Reveals, word-by-word titles and scroll-scrubbed text come from data-anim attributes read by one shared library. Without JavaScript every line stays visible.
A navbar that reads the page
It turns light over any dark section on its own, a pill glides to the hovered link, and a live clock shows the visitor's local time.
A contact form that holds up
Seven fields validated on the server against the same lists the dropdowns use, honeypot, Upstash rate limiting and Resend delivery. With JS off the errors still come back rendered.
Images that never leave the repo
Every picture is a local asset cut to size by sharp at build time. No remote sources, so the build runs offline and no third party can change a photo after you ship.
SEO wired end to end
Titles and descriptions per page, 1200×630 social cards from each cover, JSON-LD for the studio, services, projects and posts, RSS, sitemap and robots.txt.
Typed content collections. You write a file, and the listing, the detail page, the feed and the sitemap pick it up on the next build.
src/content/services/*.mdSummary, duration, tags, cover and gallery. The home page and the other-services list read the whole collection.src/content/projects/*.mdCase studies with location, year, industry, timeline and deliverables. The category builds the filter on its own.src/content/blog/*.mdPosts with a category and a cover. Reading time is counted, the h2 headings build the index and the feed picks them up.src/content/legals/*.mdThe filename becomes the route.src/config/*.data.tsStats, team, process, testimonials, FAQ, the contact form dropdowns and every image and video outside the collections, all typed.---
title: New Client
description: One line for cards, search results and social previews.
summary: The sentence that sells the project.
category: Branding
order: 5
location: Lisbon, Portugal
year: 2026
industry: Fintech
timeline: 6 weeks
deliverables:
- Brand identity
- Website
cover:
src: ./images/new-client/cover.webp
alt: …
---The name
src/config/site.tsThe only place the studio is named. Page titles, the wordmark, the loading screen, the footer and the JSON-LD are all built from it, along with the email, phone and time zone.
The typefaces
astro.config.mjsThree self-hosted families declared in one block, from Fontsource and Fontshare. Nothing is fetched from a font CDN at runtime.
The palette
src/styles/global.cssTen colour tokens in the theme block. The accent fills the buttons, the logo and the focus ring, so changing one value rebrands the site.
The copy
src/config/labels.tsEvery user-facing string, alt text and SEO title, read through a typed helper. An unknown key fails the build instead of shipping empty.
Both have a free tier, and the contact form needs them: the ZIP ships an .env.template with the variables to fill in.
A README written for this template, not copied between them, inside the ZIP. It covers:
Try any demo before you decide
The demos are the real templates, deployed. No signup, no email in the way.





