Relay
Relay is for a studio that sells design, and for a product team that wants to look like it hired one. It opens on a full-screen photograph drifting slowly behind two lines of very large type, under a floating glass navigation bar. Below it a browser window tilts into view and scrolls through a featured project, the studio statement fills in word by word, three project stages slide over each other and the process section rolls its step number as you read.
The homepage continues with two client marquees, a comparison table, six service rows, proof numbers, four reasons on glass cards, a testimonial slider, an integrations grid, pricing with a monthly and yearly switch, the latest journal posts and an FAQ. Relay is dark by default, with a light mode and four accent colours in the appearance panel.
| Property | Value |
|---|---|
| Tier | Pro ($69) |
| Category | Digital Agency / Creative Studio |
| Fonts | Rethink Sans for everything, bundled locally |
| Palette | Dark: black (#000000), graphite surface (#151515), white text (#f5f5f5), silver muted text (#b3b3b8). Light: warm white (#f5f4f1), white surface, near-black text (#1c1c20). One accent: Silver by default, with Ice, Sage and Rose presets, or any hex |
| Motion | GSAP and Lenis: hero drift, line-by-line headings, tilting browser preview, word-fill statement, stacking projects, rolling process number, counters, tilting glass cards, testimonial slider, FAQ disclosures |
| Styles | Plain CSS in src/styles/global.css, no CSS framework |
| Content | Every string, project, service, plan, article and form field in src/config/site.ts |
| Languages | English, one language per site |
Included routes
Section titled “Included routes”/- hero, browser preview, client marquees, studio statement, selected work, comparison table, services, process, proof, reasons, testimonials, integrations, pricing, journal preview and FAQ/work/and/work/[slug]/- all projects with filters by category, and a case study per project/services/and/services/[slug]/- the six services and a page for each/industries/- one row per project industry, generated from your projects/about/- the studio story, values and process/blog/and/blog/[slug]/- the journal and three articles/contact/- the contact form beside a direct email address/privacy/
The production build generates 21 static pages, including the 404 page, plus sitemap.xml and robots.txt.
What makes Relay different
Section titled “What makes Relay different”- Motion that sells the work - a browser window that scrolls through a project, a statement that fills in as you read, project stages that stack and a step number that rolls, with pause buttons and reduced-motion fallbacks.
- Case studies without mockup files - every project preview is built in HTML from a logo, three navigation labels, a headline, a button and one photograph.
- A studio site or a product site - pricing and integrations sit on the homepage, each behind one
enabledflag. - Dark, light and four accents - visitors switch in the appearance panel, and the choice is restored before the page paints.
Relay-specific setup
Section titled “Relay-specific setup”Set the site address
Section titled “Set the site address”Set seo.url in src/config/site.ts to your public address, for example https://yourstudio.com, or set PUBLIC_SITE_URL when you build. It must start with https:// and have no path after the domain; the build stops with a clear error otherwise. Canonical URLs, social images, the sitemap, the robots file and the structured data use it.
Name and branding
Section titled “Name and branding”brand holds the studio name, the ® suffix, the description, the email, the location line, the availability note and the copyright line. brand.markPath is the SVG path of the small mark in the navigation bar, brand.favicon is the favicon file and seo.logo is the logo file search engines read. Replace all three when you rebrand.
Dark and light mode
Section titled “Dark and light mode”appearance: { defaultMode: "dark", // or "light" accent: "#f5f5f5", background: "#000000", surface: "#151515", text: "#f5f5f5", muted: "#b3b3b8", light: { accent: "#252529", background: "#f5f4f1", surface: "#ffffff", text: "#1c1c20", muted: "#5c5c63" },},The top-level colours are the dark palette and light is the light one. defaultMode is what a first-time visitor sees. There is no automatic mode that follows the system setting: the site opens in your default and the visitor switches in the appearance panel.
Accent colours and the appearance panel
Section titled “Accent colours and the appearance panel”The round button in the corner opens the appearance panel: Light and Dark buttons, four accent swatches and a reset. Both choices are remembered in the browser and restored before the page paints. The presets are in accentSwitcher.presets, each with a value for dark mode and a deeper lightValue for light mode:
presets: [ { name: "Silver", value: "#f5f5f5", lightValue: "#252529" }, { name: "Ice", value: "#b3d5ff", lightValue: "#245b9c" }, // ...],Change the colours and labels, or set accentSwitcher.enabled to false to hide the panel and keep one look. The project photographs and the colours inside the project previews do not follow the accent.
The hero
Section titled “The hero”hero.lines holds the two headline lines, hero.image the photograph and hero.proof the three short points under the buttons. hero.motion controls the slow drift: enabled, duration in seconds, and videoSrc for a local MP4 or WebM file that plays in place of the drift. The photograph stays as the fallback if the video cannot play. The motion pauses off screen and is off for visitors who prefer reduced motion.
Add a project
Section titled “Add a project”Add an entry to projects. Its slug creates /work/<slug>/. Each project has a name, a category (used by the work page filters, so keep it in work.filters), an industry (used by the industries page), a year, a summary, a description, an image with alt text, the services, and the case study text: challenge, approach, outcome, a quote with its author and role.
The preview object builds the website composition shown over the photograph: logo, three navigation labels, an eyebrow, a headline, a cta, a caption, a sectionTitle, a sectionText and a footer. It is HTML, so no mockup image is needed.
featured.projectSlug chooses the project inside the browser window near the top of the homepage, and featured.browserAddress is the address shown in its bar.
Services
Section titled “Services”services holds the six services. Each slug creates /services/<slug>/, with a name, a short name, a tag, a description, a body paragraph, four deliverables and a symbol (window, orbit, bag or spark). The Services menu in the navigation bar lists them automatically.
Comparison table, process and proof
Section titled “Comparison table, process and proof”comparison.columns holds the two ways of working, each with four features that line up with comparison.rowLabels, and a timing. process.steps holds the five steps. proof.metrics holds the three counted numbers and proof.backgroundNumber the large outlined number behind the heading. Replace the demo numbers with real ones.
Pricing and integrations
Section titled “Pricing and integrations”Both sections are optional: set pricing.enabled or integrations.enabled to false to remove one, and remove its link from footer.groups.
Each plan in pricing.plans has a name, a description, an optional badge, a featured flag, a monthly and a yearly block (price, period and a note), a feature list and a button. Yearly billing shows the monthly equivalent, and the note states the yearly charge. The plans are display only: there is no checkout, so point each button at your own signup or contact page.
Each item in integrations.items has a name, a category, a description, a link and an image path to its logo. The six demo logos come from Simple Icons and are self-hosted in public/images/integrations/. mark is a one-letter fallback shown when an item has no image.
Testimonials
Section titled “Testimonials”testimonials.items holds the quotes with a name, a role and initials. The demo people and companies are fictional; replace them with real, approved quotes.
Connect the contact form
Section titled “Connect the contact form”The contact form starts in demo mode: it checks what is typed and says plainly that nothing was sent. Choose a provider in contact.delivery:
delivery: defineDelivery({ provider: "formspree", formId: "YOUR_FORM_ID" }),// or { provider: "formsubmit", recipient: "you@example.com" }// or { provider: "netlify", formName: "contact" }// or { provider: "custom", endpoint: "/api/contact", encoding: "json" }Custom endpoints accept json, multipart or urlencoded, and extraFields adds fixed public values to every submission. Everything in this config is sent to the browser, so never put a secret key in it. Update the privacy page for your provider. Netlify detects forms when it builds the site, so deploy again after switching to it.
Change the form fields
Section titled “Change the form fields”contact.fields lists the fields in the order they appear. Each has a name, a label, a type (text, email, tel, url, select or textarea), and optional required, placeholder, autocomplete, maxLength, rows, fullWidth, hideLabel and options settings. The name is what your provider receives. The consent line and every status message are in contact too.
Add an article
Section titled “Add an article”Add an entry to blog.posts. Its slug creates /blog/<slug>/. Each article has a title, a category, a date and an optional modified date in YYYY-MM-DD, a reading time, a cover image with alt text, an excerpt and sections, each with a heading and paragraphs. The headings feed the table of contents. blog.pageSize sets how many articles a journal page shows before it paginates, and blog.author sets the author in the structured data.
Search settings
Section titled “Search settings”seo.title and seo.description are the homepage title and description, and seo.titleTemplate formats every other page title. seo.indexable: false marks every page noindex and empties the sitemap, which is useful for a preview address. pageSeo takes an optional title, description, image or noindex per route, with keys such as work, services/web-design or blog/before-you-redesign.
Every indexable page carries JSON-LD built from the same config: Organization and WebSite everywhere, Service on service pages, CreativeWork on case studies, BlogPosting on articles, FAQPage on the homepage, and breadcrumbs. Add your real profile links to seo.sameAs. docs/seo.md and docs/schema.md in the theme list every setting.
Tune the motion
Section titled “Tune the motion”The animation lives in src/scripts/main.ts. The browser preview and the client marquees have pause buttons. Reduced-motion settings turn off the scroll animation, the smooth scrolling and the marquees, touch screens skip the tilt effects, and the content stays readable without JavaScript.
The footer credit
Section titled “The footer credit”brand.credit in site.ts holds the “Created by aerolaunch.app” line in the footer. Edit it, or remove it from src/components/Footer.astro.
Coding assistants
Section titled “Coding assistants”AGENTS.md describes where content lives, the design details to keep, the screen widths and modes to check and the commands to run: npm run check, npm test, npm run build and npm run verify:site.
HTML edition
Section titled “HTML edition”Relay is also available as a plain HTML template: the same design as ready-made HTML, CSS and JavaScript files that open straight from disk, with no build step. The light and dark switch, the accent panel, the navigation menus, the pricing switch, the work filters, the FAQ and the contact form still work, and the README explains where the two palettes live and how to connect the form. How the HTML editions are organised: HTML edition.