Building formray.dev
This is the build log for the site you're reading. A 16-page, dark-mode, i18n-ready marketing site built with Next.js 15, Tailwind v4, and a deliberate aesthetic borrowed from 1970s lab equipment.
The aesthetic
The visual language of Formray is amber phosphor on dark stone. CRT warmth. Oscilloscope traces. Grain textures. Scan lines. The feeling of a well-maintained analog lab — precise, warm, intentional.
Not cold. Not neon. Not cyberpunk. Vintage instrumentation.
This wasn't arbitrary. The reference companies — Anthropic, Vercel, Linear, Stripe — share a quality: restraint. Clean layouts, generous whitespace, typography that breathes. We wanted that discipline, but with warmth. The amber palette gives the site a physicality that pure monochrome lacks.
Every effect component serves this direction:
| Component | Purpose |
|---|---|
| Oscilloscope | Canvas waveform — hero background, 404 flatline |
| Grain texture | SVG noise overlay at 4% opacity — film grain |
| Scan lines | CRT horizontal lines on hero sections |
| Cursor glow | Mouse-following amber gradient — ambient light |
| CRT glow | Hover amber box-shadow on cards |
| Typewriter | Character-by-character text reveal |
| VU meter | SVG analog gauge with animated needle |
Stack decisions
| Choice | Why |
|---|---|
| Next.js 15 App Router | Server Components by default, RSC streaming |
| Tailwind v4 (CSS-first) | Design tokens as CSS custom properties in @theme |
| Motion (framer-motion) | Scroll animations, page transitions, hover effects |
| next-intl | Type-safe i18n, EN primary, IT secondary |
| MDX for blog | Rich components inside blog posts |
| Self-hosted fonts | No external CDN, no Google Fonts |
The guiding principle: Server Components by default. Only add "use client" for components that need browser APIs — canvas, mouse events, motion, forms. Everything else stays on the server.
Design system
The entire color palette, typography scale, spacing, and transitions live as CSS custom properties in globals.css via Tailwind v4's @theme block. No tailwind.config.ts. No JavaScript token files. Just CSS.
- Background: Stone 950 (
#0C0A09) — near black with warmth - Surface: Stone 900 (
#1C1917) — cards, elevated elements - Accent: Amber 500 (
#F59E0B) — links, CTAs, the signature glow - Text: Stone 50 (
#FAFAF9) — primary, high contrast - Text secondary: Stone 400 (
#A8A29E) — body, descriptions
Amber on Stone 950 hits 8.2:1 contrast ratio — AAA. Accessibility isn't an afterthought.
Typography is Inter for body and headings, JetBrains Mono for code. Both variable, both self-hosted, both loaded with font-display: swap.
Blog system
Blog posts are MDX files in content/blog/. Frontmatter parsed by gray-matter. Content evaluated at build time with @mdx-js/mdx and rendered with custom components.
The custom components — InfoBox, ComparisonTable, StepHeader, Quote, StatCard, and others — are injected via the MDX component map. No imports needed in the MDX files themselves.
Authors write MDX with components like <InfoBox>, <ComparisonTable>, <StepHeader> — and they just work. The rendering pipeline handles component resolution, syntax highlighting via rehype-highlight, and GitHub-flavored markdown via remark-gfm.
i18n
English is the default locale with no URL prefix. Italian gets /it/ prefix. The as-needed strategy from next-intl means English URLs are clean — /products/darc, not /en/products/darc.
Translation keys cover navigation, headings, CTAs, UI copy, and meta descriptions. Product names (DARC, AEGIS, PRISM) are never translated. Brand terms stay as-is.
Performance
- Lighthouse Performance: 95+
- Lighthouse Accessibility: 100
- LCP: under 2.5s
- CLS: under 0.1
- Initial JS bundle: under 100KB
Canvas animations use requestAnimationFrame. All motion respects prefers-reduced-motion. Images use next/image with AVIF/WebP. Fonts are self-hosted and variable.
The site ships as a standalone Docker container for deployment flexibility, though primary hosting is Vercel.
What I learned
Building a marketing site for your own company is a different exercise than client work. There's no brief to hide behind. Every decision — the amber instead of blue, the oscilloscope instead of a gradient, the grain texture at exactly 4% — is a statement about what the company is.
The site is the first product. If the craft isn't visible here, why would anyone trust the software?
Technology, thoughtfully. That's not just copy. It's the build process.