Build dylanmazzei.com redesign as a static multi-page site
Eight pages (home, about, portfolio, consulting, marketing, business setup, contact, press) with copy taken verbatim from the content documents, a shared layout, and a zero-dependency Node build ready for Vercel. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,4 @@
|
|||||||
|
node_modules/
|
||||||
|
dist/
|
||||||
|
.DS_Store
|
||||||
|
.vercel
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
# dylanmazzei.com
|
||||||
|
|
||||||
|
Sitio de Dylan Mazzei, Founder & Operator. HTML estático generado con un script de Node sin dependencias.
|
||||||
|
|
||||||
|
## Estructura
|
||||||
|
|
||||||
|
```
|
||||||
|
src/layout.mjs Layout compartido: <head>, nav, footer, iconos y helpers
|
||||||
|
src/pages/*.mjs Una página por archivo (texto literal del documento de contenido)
|
||||||
|
static/ Se copia tal cual a dist/ (CSS, JS, imágenes, favicon)
|
||||||
|
build.mjs Genera dist/ + sitemap.xml + robots.txt + 404.html
|
||||||
|
```
|
||||||
|
|
||||||
|
| Ruta | Archivo |
|
||||||
|
|------|---------|
|
||||||
|
| `/` | `src/pages/home.mjs` |
|
||||||
|
| `/about/` | `src/pages/about.mjs` |
|
||||||
|
| `/portfolio/` | `src/pages/portfolio.mjs` |
|
||||||
|
| `/consulting/` | `src/pages/consulting.mjs` |
|
||||||
|
| `/consulting/marketing/` | `src/pages/marketing.mjs` |
|
||||||
|
| `/consulting/business-setup/` | `src/pages/business-setup.mjs` |
|
||||||
|
| `/contact/` | `src/pages/contact.mjs` |
|
||||||
|
| `/press/` | `src/pages/press.mjs` |
|
||||||
|
|
||||||
|
## Desarrollo
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm run build # genera dist/
|
||||||
|
npm run dev # build + servidor local
|
||||||
|
```
|
||||||
|
|
||||||
|
## Deploy en Vercel
|
||||||
|
|
||||||
|
Importa el repo en Vercel. `vercel.json` ya define el build (`npm run build`), la salida (`dist`) y las URLs limpias con slash final. No hace falta configurar nada más.
|
||||||
|
|
||||||
|
## Pendientes de contenido
|
||||||
|
|
||||||
|
- **Press:** confirmar el titular exacto del artículo de Gulf Magazine y su URL (`FEATURE` en `src/pages/press.mjs`).
|
||||||
|
- **Páginas que aún no existen.** Mientras tanto sus botones llevan a `/contact/` (`SITE.pending` en `src/layout.mjs`): Playbook, Poetry, Fractional Roles, Business Optimization, Supply Chain, Cybersecurity y Education.
|
||||||
|
- **Calendario:** poner el link real de agenda en `SITE.calendar`.
|
||||||
|
- **Formulario de contacto:** hoy abre el cliente de correo con el mensaje prellenado. Para recibirlo directo hay que conectar un servicio (Formspree, Resend, etc.).
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
// Builds the static site into ./dist. No dependencies: `node build.mjs`.
|
||||||
|
import { mkdir, rm, writeFile, cp } from 'node:fs/promises';
|
||||||
|
import { join, dirname } from 'node:path';
|
||||||
|
import { fileURLToPath } from 'node:url';
|
||||||
|
import { page, eyebrow, btn } from './src/layout.mjs';
|
||||||
|
|
||||||
|
const root = dirname(fileURLToPath(import.meta.url));
|
||||||
|
const out = join(root, 'dist');
|
||||||
|
const pages = ['home', 'about', 'portfolio', 'consulting', 'marketing', 'business-setup', 'contact', 'press'];
|
||||||
|
|
||||||
|
await rm(out, { recursive: true, force: true });
|
||||||
|
await mkdir(out, { recursive: true });
|
||||||
|
await cp(join(root, 'static'), out, { recursive: true });
|
||||||
|
|
||||||
|
const urls = [];
|
||||||
|
for (const name of pages) {
|
||||||
|
const def = (await import(`./src/pages/${name}.mjs`)).default;
|
||||||
|
const file = join(out, def.path, 'index.html');
|
||||||
|
await mkdir(dirname(file), { recursive: true });
|
||||||
|
await writeFile(file, page(def));
|
||||||
|
urls.push(def.path);
|
||||||
|
console.log('built', def.path);
|
||||||
|
}
|
||||||
|
|
||||||
|
await writeFile(join(out, '404.html'), page({
|
||||||
|
path: '/404/',
|
||||||
|
title: 'Page Not Found | Dylan Mazzei',
|
||||||
|
description: 'This page could not be found.',
|
||||||
|
body: `<section class="page-hero"><div class="wrap-narrow stack center" style="align-items:center;text-align:center">${eyebrow('404')}<h1 class="h-display-lg">Page Not Found</h1><div class="btn-row">${btn('BACK TO HOME', '/')}</div></div></section>`,
|
||||||
|
}));
|
||||||
|
|
||||||
|
const today = new Date().toISOString().slice(0, 10);
|
||||||
|
await writeFile(join(out, 'sitemap.xml'), `<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
||||||
|
${urls.map((u) => ` <url><loc>https://dylanmazzei.com${u}</loc><lastmod>${today}</lastmod></url>`).join('\n')}
|
||||||
|
</urlset>
|
||||||
|
`);
|
||||||
|
await writeFile(join(out, 'robots.txt'), 'User-agent: *\nAllow: /\nSitemap: https://dylanmazzei.com/sitemap.xml\n');
|
||||||
|
console.log('done →', out);
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"name": "dylanmazzei-website",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"private": true,
|
||||||
|
"type": "module",
|
||||||
|
"description": "dylanmazzei.com — static site built with a zero-dependency Node script.",
|
||||||
|
"scripts": {
|
||||||
|
"build": "node build.mjs",
|
||||||
|
"dev": "node build.mjs && npx --yes serve dist"
|
||||||
|
},
|
||||||
|
"engines": { "node": ">=18" }
|
||||||
|
}
|
||||||
+234
@@ -0,0 +1,234 @@
|
|||||||
|
// Shared layout, icons and small HTML helpers for every page.
|
||||||
|
|
||||||
|
export const SITE = {
|
||||||
|
url: 'https://dylanmazzei.com',
|
||||||
|
email: 'dylan@dylanmazzei.com',
|
||||||
|
pressEmail: 'press@dylanmazzei.com',
|
||||||
|
linkedin: 'https://www.linkedin.com/in/dylanmazzei/',
|
||||||
|
instagram: 'https://www.instagram.com/caposins',
|
||||||
|
// Replace with the real scheduling link (Calendly, Cal.com, etc.).
|
||||||
|
calendar: 'mailto:dylan@dylanmazzei.com?subject=Scheduling%20a%20conversation',
|
||||||
|
// Pages that are not built yet. Their CTAs point here until they exist.
|
||||||
|
pending: '/contact/',
|
||||||
|
};
|
||||||
|
|
||||||
|
const ICONS = {
|
||||||
|
arrow: '<path d="M3 8h10M9 4l4 4-4 4" stroke-width="1.75"/>',
|
||||||
|
'arrow-ur': '<path d="M5 11 11 5M6 5h5v5" stroke-width="1.75"/>',
|
||||||
|
check: '<path d="m3.5 8.5 3 3 6-6.5" stroke-width="1.75"/>',
|
||||||
|
plus: '<path d="M8 3v10M3 8h10" stroke-width="1.75"/>',
|
||||||
|
chev: '<path d="m4 6 4 4 4-4" stroke-width="1.75"/>',
|
||||||
|
menu: '<path d="M2 5h14M2 9h14M2 13h14" stroke-width="1.75"/>',
|
||||||
|
close: '<path d="M4 4l10 10M14 4 4 14" stroke-width="1.75"/>',
|
||||||
|
brace: '<path d="M6 2.5H5a1.5 1.5 0 0 0-1.5 1.5v2.3c0 .8-.6 1.7-1.5 1.7.9 0 1.5.9 1.5 1.7V12A1.5 1.5 0 0 0 5 13.5h1M10 2.5h1A1.5 1.5 0 0 1 12.5 4v2.3c0 .8.6 1.7 1.5 1.7-.9 0-1.5.9-1.5 1.7V12a1.5 1.5 0 0 1-1.5 1.5h-1" stroke-width="1.5"/>',
|
||||||
|
search: '<circle cx="10.5" cy="10.5" r="6.5"/><path d="m20 20-4.8-4.8M10.5 7.5v6M7.5 10.5h6"/>',
|
||||||
|
chip: '<rect x="6" y="6" width="12" height="12" rx="2.5"/><path d="M9.5 9.5h5v5h-5zM9 3v3M15 3v3M9 18v3M15 18v3M3 9h3M3 15h3M18 9h3M18 15h3"/>',
|
||||||
|
bottle: '<path d="M10 2.5h4M10.5 2.5v4.2L8.6 9.4a3 3 0 0 0-.6 1.8V20a1.5 1.5 0 0 0 1.5 1.5h5A1.5 1.5 0 0 0 16 20v-8.8a3 3 0 0 0-.6-1.8l-1.9-2.7V2.5"/><path d="M8 13.5h8v4H8z"/>',
|
||||||
|
edu: '<path d="m2.5 9 9.5-4.5L21.5 9 12 13.5z"/><path d="M6.5 11v4.5c0 1.6 2.5 3 5.5 3s5.5-1.4 5.5-3V11M21.5 9v5"/>',
|
||||||
|
shield: '<path d="M12 2.8 19.5 6v5.4c0 4.6-3.1 8.2-7.5 9.8-4.4-1.6-7.5-5.2-7.5-9.8V6z"/><path d="m8.8 12 2.3 2.3 4.3-4.6"/>',
|
||||||
|
bag: '<path d="M4.5 8h15l-1.2 12.1a1.5 1.5 0 0 1-1.5 1.4H7.2a1.5 1.5 0 0 1-1.5-1.4z"/><path d="M8.5 10.5V7a3.5 3.5 0 0 1 7 0v3.5"/>',
|
||||||
|
umbrella: '<path d="M3 12a9 9 0 0 1 18 0z"/><path d="M12 12v6.5a2 2 0 0 1-4 0M12 3v-.5"/>',
|
||||||
|
megaphone: '<path d="M3.5 10v4a1 1 0 0 0 1 1H7l9 5V4L7 9H4.5a1 1 0 0 0-1 1z"/><path d="M7 15l1.5 5M19.5 9.5a3.5 3.5 0 0 1 0 5"/>',
|
||||||
|
heart: '<path d="M12 20.5s-8-4.6-8-10.7A4.3 4.3 0 0 1 12 7.4a4.3 4.3 0 0 1 8 2.4c0 6.1-8 10.7-8 10.7z"/><path d="M8.5 12h2l1-2 1.5 4 1-2h2"/>',
|
||||||
|
shirt: '<path d="M9 3.5 4 5.8 2.5 10.5l3.3 1.3V20.5h12.4v-8.7l3.3-1.3L20 5.8l-5-2.3c-.4 1.4-1.6 2.3-3 2.3s-2.6-.9-3-2.3z"/>',
|
||||||
|
building: '<path d="M4 21V5a1.5 1.5 0 0 1 1.5-1.5h8A1.5 1.5 0 0 1 15 5v16M15 9h3.5A1.5 1.5 0 0 1 20 10.5V21M2.5 21h19M7.5 7.5h4M7.5 11h4M7.5 14.5h4"/>',
|
||||||
|
gauge: '<path d="M4 17a8 8 0 1 1 16 0"/><path d="m12 17 4-5M4 17h2M18 17h2M12 9V7.5"/>',
|
||||||
|
truck: '<path d="M2.5 6.5h11v10h-11zM13.5 10h4l3 3.2v3.3h-7"/><circle cx="6.5" cy="17.5" r="1.8"/><circle cx="17" cy="17.5" r="1.8"/>',
|
||||||
|
compass: '<circle cx="12" cy="12" r="9"/><path d="m15.5 8.5-2 5-5 2 2-5z"/>',
|
||||||
|
target: '<circle cx="12" cy="12" r="9"/><circle cx="12" cy="12" r="5"/><circle cx="12" cy="12" r="1.2"/>',
|
||||||
|
users: '<circle cx="9" cy="8.5" r="3.5"/><path d="M2.5 20c.6-3.4 3.3-5.5 6.5-5.5s5.9 2.1 6.5 5.5"/><path d="M15.5 5.2a3.5 3.5 0 0 1 0 6.6M17.5 14.8c2.1.6 3.6 2.4 4 5.2"/>',
|
||||||
|
chart: '<path d="M3.5 20.5h17"/><path d="M6.5 16.5v-4M11 16.5V8M15.5 16.5v-6M20 16.5V5"/>',
|
||||||
|
layers: '<path d="m12 3 9 4.8-9 4.8-9-4.8z"/><path d="m3 12.2 9 4.8 9-4.8M3 16.4l9 4.8 9-4.8"/>',
|
||||||
|
mic: '<rect x="9" y="2.5" width="6" height="11" rx="3"/><path d="M5.5 11a6.5 6.5 0 0 0 13 0M12 17.5v4M8.5 21.5h7"/>',
|
||||||
|
rocket: '<path d="M12 15.5 8.5 12c1.5-4.6 4.6-8.3 11-8.5-.2 6.4-3.9 9.5-8.5 11z"/><path d="M8.5 12 5 11.5l2.5-3h4M12 15.5l.5 3.5 3-2.5v-4"/><path d="M6.5 16c-1.6.6-2.4 2.3-2.5 4 1.7-.1 3.4-.9 4-2.5"/>',
|
||||||
|
route: '<circle cx="6" cy="18" r="2.5"/><circle cx="18" cy="6" r="2.5"/><path d="M8.5 18H16a3 3 0 0 0 0-6H8a3 3 0 0 1 0-6h7.5"/>',
|
||||||
|
mail: '<rect x="3" y="5" width="18" height="14" rx="2.5"/><path d="m3.5 6.5 8.5 6.5 8.5-6.5"/>',
|
||||||
|
calendar: '<rect x="3.5" y="5" width="17" height="15.5" rx="2.5"/><path d="M3.5 10h17M8 3v4M16 3v4"/>',
|
||||||
|
pin: '<path d="M12 21s7-6.2 7-11.5a7 7 0 0 0-14 0C5 14.8 12 21 12 21z"/><circle cx="12" cy="9.5" r="2.5"/>',
|
||||||
|
book: '<path d="M4 4.5A1.5 1.5 0 0 1 5.5 3H19v15H5.5A1.5 1.5 0 0 0 4 19.5z"/><path d="M4 19.5A1.5 1.5 0 0 0 5.5 21H19v-3"/>',
|
||||||
|
pen: '<path d="M4 20l1-4.5L15.5 5a2.1 2.1 0 0 1 3 3L8 18.5z"/><path d="m13.5 7 3 3"/>',
|
||||||
|
spark: '<path d="M12 3v4M12 17v4M3 12h4M17 12h4M5.6 5.6l2.8 2.8M15.6 15.6l2.8 2.8M18.4 5.6l-2.8 2.8M8.4 15.6l-2.8 2.8"/>',
|
||||||
|
};
|
||||||
|
|
||||||
|
const SMALL = new Set(['arrow', 'arrow-ur', 'check', 'plus', 'chev', 'brace']);
|
||||||
|
|
||||||
|
export function icon(name, cls = '') {
|
||||||
|
const vb = SMALL.has(name) ? '0 0 16 16' : name === 'menu' || name === 'close' ? '0 0 18 18' : '0 0 24 24';
|
||||||
|
const sw = SMALL.has(name) || name === 'menu' || name === 'close' ? '' : ' stroke-width="1.75"';
|
||||||
|
return `<svg class="${cls}" viewBox="${vb}" fill="none" stroke="currentColor"${sw} stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">${ICONS[name]}</svg>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const mark = (cls = 'brand-mark') => `<svg class="${cls}" viewBox="0 0 34 34" aria-hidden="true"><rect width="34" height="34" rx="10" fill="#594ff4"/><path d="M8 9h7.2c4.4 0 7.3 3.1 7.3 7.6 0 1.5-.3 2.8-.9 4L16.9 25H8l1.8-3.2h5.6c2.6 0 4.1-2 4.1-4.9 0-2.6-1.5-4.6-4.3-4.6h-5.3z" fill="#fff"/><path d="M27 8.5 18.3 25.5h4.2L27 16.8z" fill="#fff" opacity=".55"/></svg>`;
|
||||||
|
|
||||||
|
export const eyebrow = (t) => `<span class="eyebrow">${t}</span>`;
|
||||||
|
|
||||||
|
export function btn(text, href, variant = 'primary', extra = '') {
|
||||||
|
const ext = /^https?:/.test(href) ? ' target="_blank" rel="noopener"' : '';
|
||||||
|
return `<a class="btn btn-${variant}${extra ? ' ' + extra : ''}" href="${href}"${ext}>${text} ${icon('arrow')}</a>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function textLink(text, href) {
|
||||||
|
const ext = /^https?:/.test(href) ? ' target="_blank" rel="noopener"' : '';
|
||||||
|
return `<a class="text-link" href="${href}"${ext}>${text} ${icon('arrow')}</a>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const paras = (arr, cls = '') => arr.map((t) => `<p${cls ? ` class="${cls}"` : ''}>${t}</p>`).join('');
|
||||||
|
|
||||||
|
export function faq(items) {
|
||||||
|
return `<div class="faq">${items
|
||||||
|
.map(
|
||||||
|
([q, a], i) => `<details${i === 0 ? ' open' : ''}><summary>${q}<span class="pm">${icon('plus')}</span></summary><div class="answer">${paras(a)}</div></details>`
|
||||||
|
)
|
||||||
|
.join('')}</div>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const NAV = [
|
||||||
|
{ label: 'Portfolio', href: '/portfolio/' },
|
||||||
|
{ label: 'About', href: '/about/' },
|
||||||
|
{
|
||||||
|
label: 'Consulting',
|
||||||
|
href: '/consulting/',
|
||||||
|
children: [
|
||||||
|
{ label: 'Consulting', desc: 'Find the Real Problem. Then Fix the Right One.', href: '/consulting/', icon: 'compass' },
|
||||||
|
{ label: 'Marketing & AI Search', desc: 'Get Found Where Attention Is Moving.', href: '/consulting/marketing/', icon: 'search' },
|
||||||
|
{ label: 'Business Setup', desc: 'Start With Fewer Expensive Mistakes.', href: '/consulting/business-setup/', icon: 'building' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{ label: 'Press', href: '/press/' },
|
||||||
|
];
|
||||||
|
|
||||||
|
function nav(path) {
|
||||||
|
const isActive = (href) => (href === '/' ? path === '/' : path.startsWith(href));
|
||||||
|
const desktop = NAV.map((item) => {
|
||||||
|
if (!item.children) {
|
||||||
|
return `<li><a href="${item.href}"${isActive(item.href) ? ' aria-current="page"' : ''}>${item.label}</a></li>`;
|
||||||
|
}
|
||||||
|
return `<li class="has-drop${isActive(item.href) ? ' is-active' : ''}">
|
||||||
|
<button type="button" aria-haspopup="true">${item.label} ${icon('chev', 'chev')}</button>
|
||||||
|
<div class="dropdown">${item.children
|
||||||
|
.map((c) => `<a href="${c.href}"><span class="di">${icon(c.icon)}</span><span><strong>${c.label}</strong><small>${c.desc}</small></span></a>`)
|
||||||
|
.join('')}</div>
|
||||||
|
</li>`;
|
||||||
|
}).join('');
|
||||||
|
const mobile = NAV.map((item) => {
|
||||||
|
const top = `<li><a href="${item.href}">${item.label} ${icon('arrow', 'check')}</a></li>`;
|
||||||
|
if (!item.children) return top;
|
||||||
|
return top + item.children.slice(1).map((c) => `<li class="sub"><a href="${c.href}">${c.label}</a></li>`).join('');
|
||||||
|
}).join('');
|
||||||
|
|
||||||
|
return `<a class="skip" href="#main">Skip to content</a>
|
||||||
|
<header class="nav" id="nav">
|
||||||
|
<div class="wrap nav-inner">
|
||||||
|
<a class="brand" href="/" aria-label="Dylan Mazzei, home">${mark()}<span class="brand-word">Dylan Mazzei</span></a>
|
||||||
|
<nav aria-label="Primary"><ul class="nav-links">${desktop}</ul></nav>
|
||||||
|
<div class="nav-cta">
|
||||||
|
<a class="btn btn-primary btn-sm" href="/contact/">START A CONVERSATION</a>
|
||||||
|
<button class="menu-btn" id="menu-btn" type="button" aria-expanded="false" aria-controls="mobile-menu" aria-label="Open menu">${icon('menu')}</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="wrap mobile-menu" id="mobile-menu" hidden>
|
||||||
|
<ul>${mobile}</ul>
|
||||||
|
<a class="btn btn-primary" href="/contact/">START A CONVERSATION ${icon('arrow')}</a>
|
||||||
|
</div>
|
||||||
|
</header>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function footer() {
|
||||||
|
return `<footer class="footer">
|
||||||
|
<div class="wrap">
|
||||||
|
<div class="foot-top">
|
||||||
|
<div class="foot-intro">
|
||||||
|
<a class="brand" href="/" aria-label="Dylan Mazzei, home">${mark()}<span class="brand-word">Dylan Mazzei</span></a>
|
||||||
|
<p>DYLAN MAZZEI | FOUNDER & OPERATOR</p>
|
||||||
|
</div>
|
||||||
|
<div class="foot-col">
|
||||||
|
<h4>Explore</h4>
|
||||||
|
<ul>
|
||||||
|
<li><a href="/portfolio/">Portfolio</a></li>
|
||||||
|
<li><a href="/about/">About</a></li>
|
||||||
|
<li><a href="/press/">Press & Media</a></li>
|
||||||
|
<li><a href="/contact/">Contact</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="foot-col">
|
||||||
|
<h4>Consulting</h4>
|
||||||
|
<ul>
|
||||||
|
<li><a href="/consulting/">Consulting</a></li>
|
||||||
|
<li><a href="/consulting/marketing/">Marketing & AI Search</a></li>
|
||||||
|
<li><a href="/consulting/business-setup/">Business Setup</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="foot-col">
|
||||||
|
<h4>Direct Email</h4>
|
||||||
|
<ul>
|
||||||
|
<li><a href="mailto:${SITE.email}">${SITE.email}</a></li>
|
||||||
|
<li><a href="mailto:${SITE.pressEmail}">${SITE.pressEmail}</a></li>
|
||||||
|
<li><a href="${SITE.linkedin}" target="_blank" rel="noopener">LinkedIn</a></li>
|
||||||
|
<li><a href="${SITE.instagram}" target="_blank" rel="noopener">Instagram</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="foot-big">
|
||||||
|
<div class="stack-xs">
|
||||||
|
<span class="eyebrow">WHERE I WORK</span>
|
||||||
|
<p class="places">Texas<i>•</i>Florida<i>•</i>New York<i>•</i>Dubai</p>
|
||||||
|
</div>
|
||||||
|
<small>© ${new Date().getFullYear()} Dylan Mazzei</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="foot-word" aria-hidden="true">DYLAN MAZZEI</div>
|
||||||
|
</footer>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function page({ path, title, description, body, schema = [] }) {
|
||||||
|
const canonical = SITE.url + path;
|
||||||
|
const person = {
|
||||||
|
'@context': 'https://schema.org',
|
||||||
|
'@type': 'Person',
|
||||||
|
'@id': SITE.url + '/#dylan',
|
||||||
|
name: 'Dylan Mazzei',
|
||||||
|
url: SITE.url,
|
||||||
|
email: SITE.email,
|
||||||
|
image: SITE.url + '/assets/dylan-portrait.jpg',
|
||||||
|
jobTitle: 'Founder & Operator',
|
||||||
|
sameAs: [SITE.linkedin, SITE.instagram],
|
||||||
|
};
|
||||||
|
const ld = [person, ...schema].map((s) => `<script type="application/ld+json">${JSON.stringify(s)}</script>`).join('\n');
|
||||||
|
return `<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
|
<title>${title}</title>
|
||||||
|
<meta name="description" content="${description}">
|
||||||
|
<link rel="canonical" href="${canonical}">
|
||||||
|
<meta name="theme-color" content="#ffffff">
|
||||||
|
<meta property="og:type" content="website">
|
||||||
|
<meta property="og:site_name" content="Dylan Mazzei">
|
||||||
|
<meta property="og:title" content="${title}">
|
||||||
|
<meta property="og:description" content="${description}">
|
||||||
|
<meta property="og:url" content="${canonical}">
|
||||||
|
<meta property="og:image" content="${SITE.url}/assets/og.jpg">
|
||||||
|
<meta name="twitter:card" content="summary_large_image">
|
||||||
|
<meta name="twitter:title" content="${title}">
|
||||||
|
<meta name="twitter:description" content="${description}">
|
||||||
|
<meta name="twitter:image" content="${SITE.url}/assets/og.jpg">
|
||||||
|
<link rel="icon" href="/favicon.svg" type="image/svg+xml">
|
||||||
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||||
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
|
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inter:wght@500;700&family=JetBrains+Mono:wght@500&display=swap">
|
||||||
|
<link rel="stylesheet" href="/assets/styles.css">
|
||||||
|
<script>document.documentElement.classList.add('js');setTimeout(function(){if(!window.__site)document.documentElement.classList.remove('js')},2500)</script>
|
||||||
|
${ld}
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
${nav(path)}
|
||||||
|
<main id="main">
|
||||||
|
${body}
|
||||||
|
</main>
|
||||||
|
${footer()}
|
||||||
|
<script src="/assets/site.js" defer></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
`;
|
||||||
|
}
|
||||||
@@ -0,0 +1,250 @@
|
|||||||
|
import { icon, eyebrow, btn, paras, SITE } from '../layout.mjs';
|
||||||
|
|
||||||
|
const lines = (arr) => `<div class="lines">${arr.map((t, i) => `<p${i === 0 ? ' class="ink"' : ''}>${t}</p>`).join('')}</div>`;
|
||||||
|
|
||||||
|
const firsts = [
|
||||||
|
['The First Yes', ['Before the team, the systems, and the growth plan, someone has to believe in what you’re selling.', 'That first customer teaches you something no projection can.']],
|
||||||
|
['The First Wrong Call', ['Eventually, you make one.', 'Mine taught me something useful: being wrong is expensive only if your ego keeps you there.']],
|
||||||
|
['The First Real Win', ['It changes your confidence.', 'Not because you suddenly know everything.', 'Because now you know you can figure something out.']],
|
||||||
|
];
|
||||||
|
|
||||||
|
const noStraight = [
|
||||||
|
['compass', 'New Industry. Blank Page.', ['Walking into a business you don’t completely understand is uncomfortable.', 'Good.', 'It makes you listen before speaking, find people smarter than you, and question things an insider might have stopped noticing.']],
|
||||||
|
['layers', 'Different Business. Familiar Problem.', ['The terminology changes.', 'The fundamentals have a strange habit of showing up again: attention, trust, people, economics, execution, and whether the customer actually cares.']],
|
||||||
|
['spark', 'Beginner Is a Useful Position.', ['I never want experience to make me too sophisticated to ask an obvious question.', 'Obvious questions have opened some very interesting doors.']],
|
||||||
|
];
|
||||||
|
|
||||||
|
const people = [
|
||||||
|
['mic', 'Speak Your Mind', ['I want people who bring their own judgment to the table. If there\'s a better approach, a concern I\'ve overlooked, or a decision worth questioning, I want to hear it.', 'A different perspective can change everything.']],
|
||||||
|
['users', 'Experience Isn\'t Everything', ['Good ideas don\'t always come from the most senior person in the room.', 'I pay attention to people who understand the work firsthand. Sometimes the clearest insight comes from someone who has just joined the team.']],
|
||||||
|
['target', 'Decide and Deliver', ['I believe in open discussions and honest disagreements. Every perspective deserves consideration, but eventually, a decision has to be made.', 'Once we agree on a direction, the focus shifts to execution. That\'s where a strong team proves itself.']],
|
||||||
|
];
|
||||||
|
|
||||||
|
const exitsLater = [
|
||||||
|
['Winning Doesn’t Make You Right Forever', ['Something worked.', 'Great.', 'The next company does not owe you the same answer.']],
|
||||||
|
['Pattern Recognition Has a Catch', ['Experience helps you see what you’ve seen before.', 'It can also convince you that something new is familiar.', 'I try to know the difference.']],
|
||||||
|
['I Still Want More', ['Not more for the sake of accumulation.', 'More problems worth thinking about. More people who raise my standard. More ideas that make ignoring them difficult.', 'My definition of ambition has become more selective, not smaller.']],
|
||||||
|
];
|
||||||
|
|
||||||
|
const knowNow = [
|
||||||
|
['I Know What I’m Good At.', ['And I’ve become much better at recognizing who is better than me at everything else.']],
|
||||||
|
['I Know When I Don’t Know.', ['That sentence gets easier with experience.', 'It also gets more valuable.']],
|
||||||
|
['I Know I’m Not Finished.', ['Not because I have a number of companies left to start or some finish line in mind.', 'I just haven’t stopped being interested yet.']],
|
||||||
|
];
|
||||||
|
|
||||||
|
export default {
|
||||||
|
path: '/about/',
|
||||||
|
title: 'About Dylan Mazzei | Founder, Operator & Entrepreneur',
|
||||||
|
description: 'Meet Dylan Mazzei, a founder and operator shaped by eight years of companies, four exits, hard decisions, changing industries, and what comes next.',
|
||||||
|
body: `
|
||||||
|
<section class="page-hero" aria-labelledby="about-hero">
|
||||||
|
<div class="wrap page-hero-grid">
|
||||||
|
<div class="stack anim">
|
||||||
|
${eyebrow('ABOUT DYLAN')}
|
||||||
|
<h1 id="about-hero" class="h-display-lg">Founder in Title. Operator in Practice.</h1>
|
||||||
|
<p class="statement">Anyone can have an opinion about a business.<br><em>I prefer being responsible for one.</em></p>
|
||||||
|
<div class="prose">
|
||||||
|
<p>For more than eight years, I’ve put ideas into the world, brought people around them, watched customers respond, made decisions with imperfect information, and learned what happens after the strategy meeting ends.</p>
|
||||||
|
<p>Four companies have been sold. Others are still growing, changing, and giving me new things to figure out.</p>
|
||||||
|
<p class="body-ink">That’s the part I like.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="visual portrait anim">
|
||||||
|
<img src="/assets/dylan-portrait.jpg" alt="Dylan Mazzei" width="900" height="900">
|
||||||
|
<div class="flow" aria-hidden="true">
|
||||||
|
<small>Four companies have been sold.</small>
|
||||||
|
<ol><li>Insurance</li><li>Marketing</li><li>Home Healthcare</li><li>Apparel</li></ol>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="section" aria-labelledby="beginning">
|
||||||
|
<div class="wrap">
|
||||||
|
<div class="sec-head reveal">
|
||||||
|
<div class="stack-sm">${eyebrow('THE BEGINNING')}<h2 id="beginning" class="h-display">Business Made More Sense Once It Was Mine to Figure Out.</h2></div>
|
||||||
|
<p class="body">I grew up in South Florida and studied business. Then I got close enough to the real thing to understand how much the classroom could never simulate.</p>
|
||||||
|
</div>
|
||||||
|
<div class="process reveal">
|
||||||
|
${firsts.map(([h, p], i) => `<article class="process-step"><span class="num">${i + 1}</span><h3 class="h-md">${h}</h3>${lines(p)}</article>`).join('')}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="section" aria-labelledby="straight">
|
||||||
|
<div class="wrap">
|
||||||
|
<div class="sec-head reveal">
|
||||||
|
<div class="stack-sm">${eyebrow('NO STRAIGHT LINES')}<h2 id="straight" class="h-display">My Career Would Be Easier to Explain If I Had Stayed in One Industry.</h2></div>
|
||||||
|
<p class="statement">I didn’t.<br><em>And I wouldn’t rewrite it.</em></p>
|
||||||
|
</div>
|
||||||
|
<div class="cards cards-3 reveal">
|
||||||
|
${noStraight.map(([ic, h, p]) => `<article class="card"><span class="ic">${icon(ic)}</span><h3 class="h-sm">${h}</h3>${lines(p)}</article>`).join('')}
|
||||||
|
</div>
|
||||||
|
<div class="sec-foot reveal" style="justify-content:flex-end">${btn('EXPLORE MY JOURNEY', '/portfolio/')}</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="section band" aria-labelledby="os">
|
||||||
|
<div class="wrap">
|
||||||
|
<div class="sec-head reveal">
|
||||||
|
<div class="stack-sm">${eyebrow('MY OPERATING SYSTEM')}<h2 id="os" class="h-display">I Don’t Have a Formula. I Have a Few Rules I Keep Coming Back To.</h2></div>
|
||||||
|
<div class="prose"><p>Eight years has been long enough to develop instincts.</p><p>And long enough to know when not to trust them.</p></div>
|
||||||
|
</div>
|
||||||
|
<div class="rules">
|
||||||
|
<article class="rule reveal"><span class="index">RULE_01</span><h3>Get Closer</h3><div class="prose">
|
||||||
|
<p class="ink">When something doesn’t make sense, I move toward it.</p>
|
||||||
|
<p>Talk to the customer. Sit with the team. Follow the process. Look at the numbers.</p>
|
||||||
|
<p>Distance makes problems look cleaner than they are.</p></div></article>
|
||||||
|
<article class="rule reveal"><span class="index">RULE_02</span><h3>Ask the Uncomfortable Question</h3><div class="prose">
|
||||||
|
<div class="qlist"><p>Why are we doing this?</p><p>What if we’re wrong?</p><p>Would I buy this?</p><p>What are we pretending isn’t a problem?</p></div>
|
||||||
|
<p>The question people least want to answer is occasionally the one worth asking first.</p></div></article>
|
||||||
|
<article class="rule reveal"><span class="index">RULE_03</span><h3>Make the Call</h3><div class="prose">
|
||||||
|
<p class="ink">Eventually, research becomes procrastination.</p>
|
||||||
|
<p>Get enough information. Understand the risk. Decide.</p>
|
||||||
|
<p>Then stay around for the consequences.</p></div></article>
|
||||||
|
<article class="rule reveal"><span class="index">RULE_04</span><h3>Let Reality Win</h3><div class="prose">
|
||||||
|
<p class="ink">I can love an idea.</p>
|
||||||
|
<p>The customer is still allowed to hate it.</p>
|
||||||
|
<p>Reality wins every argument eventually. I prefer finding out early.</p></div></article>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="section" aria-labelledby="people">
|
||||||
|
<div class="wrap">
|
||||||
|
<div class="sec-head reveal">
|
||||||
|
<div class="stack-sm">${eyebrow('THE PEOPLE BEHIND THE BUSINESS')}<h2 id="people" class="h-display">The Right People Make the Business Better.</h2></div>
|
||||||
|
<div class="prose">
|
||||||
|
<p>I've learned that the people around me influence far more than the work getting done. They shape the decisions we make, the problems we notice, and how far an idea can go.</p>
|
||||||
|
<p>I value people who think independently, take ownership, and care enough about the outcome to challenge my perspective.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="features reveal">
|
||||||
|
${people.map(([ic, h, p]) => `<article class="feature"><span class="ic">${icon(ic)}</span><h3>${h}</h3><div class="prose">${paras(p)}</div></article>`).join('')}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="section" aria-labelledby="exits-later">
|
||||||
|
<div class="wrap">
|
||||||
|
<div class="showcase reveal" style="align-items:start">
|
||||||
|
<div class="stack" style="position:sticky;top:calc(var(--nav-h) + 32px)">
|
||||||
|
${eyebrow('FOUR EXITS LATER')}
|
||||||
|
<h2 id="exits-later" class="h-display">Success Made Me More Confident. Experience Made Me Less Certain.</h2>
|
||||||
|
<div class="prose"><p>Four exits look neat when reduced to a number.</p><p class="body-ink">The years behind them were anything but.</p></div>
|
||||||
|
</div>
|
||||||
|
<div class="stack-sm">
|
||||||
|
${exitsLater.map(([h, p]) => `<article class="card card-white"><h3 class="h-sm">${h}</h3>${lines(p)}</article>`).join('')}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="section" aria-labelledby="notice">
|
||||||
|
<div class="wrap">
|
||||||
|
<div class="sec-head-center reveal">
|
||||||
|
${eyebrow('THINGS I NOTICE')}
|
||||||
|
<h2 id="notice" class="h-display">The Business Usually Whispers Before It Shouts.</h2>
|
||||||
|
</div>
|
||||||
|
<div class="whisper reveal">
|
||||||
|
<div class="stack">
|
||||||
|
<div class="signals">
|
||||||
|
<p class="signal"><span class="dot"></span>A customer asks the same question for the tenth time.</p>
|
||||||
|
<p class="signal"><span class="dot"></span>Someone creates a spreadsheet to work around the software.</p>
|
||||||
|
<p class="signal"><span class="dot"></span>A five-minute task somehow takes an afternoon.</p>
|
||||||
|
</div>
|
||||||
|
<div class="prose"><p>Nobody thinks any of it is urgent.</p><p class="statement">I notice those things.</p></div>
|
||||||
|
</div>
|
||||||
|
<div class="stack">
|
||||||
|
<div class="shouts">
|
||||||
|
<div class="shout"><q>“We’ve Always Done It This Way.”</q><span>Interesting.</span></div>
|
||||||
|
<div class="shout"><q>“Nobody Complains About It.”</q><span>Even more interesting.</span></div>
|
||||||
|
<div class="shout"><q>“It’s Not a Big Problem.”</q><span>Maybe.</span></div>
|
||||||
|
</div>
|
||||||
|
<div class="prose"><p>Or maybe everyone has simply become very good at living with it.</p><p class="body-ink">Small friction has introduced me to some very big questions.</p></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="section" aria-labelledby="linkedin">
|
||||||
|
<div class="wrap">
|
||||||
|
<div class="sec-head reveal">
|
||||||
|
<div class="stack-sm">${eyebrow('THE PART THAT DOESN’T FIT ON LINKEDIN')}<h2 id="linkedin" class="h-display">Not Everything I Make Is Meant to Become a Company.</h2></div>
|
||||||
|
<div class="prose">
|
||||||
|
<p class="body-ink">This might be one of the more important things I’ve learned.</p>
|
||||||
|
<p>Not every interest needs monetizing.<br>Not every thought needs optimizing.<br>Not everything meaningful needs a metric attached to it.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="duo reveal">
|
||||||
|
<article class="card card-lg">
|
||||||
|
<span class="ic">${icon('book')}</span>
|
||||||
|
<h3 class="h-lg">Some Ideas Need Structure</h3>
|
||||||
|
<div class="prose">
|
||||||
|
<p>That instinct became The Business Launch Playbook.</p>
|
||||||
|
<p>I wanted to put what I had learned about beginnings somewhere useful, especially that strange stretch where an idea has to become something real.</p>
|
||||||
|
</div>
|
||||||
|
<div class="spacer"></div>
|
||||||
|
<div>${btn('EXPLORE THE PLAYBOOK', SITE.pending)}</div>
|
||||||
|
</article>
|
||||||
|
<article class="card card-lg card-dark">
|
||||||
|
${eyebrow('A DIFFERENT OUTLET')}
|
||||||
|
<h3 class="h-lg">Some Thoughts Need Space.</h3>
|
||||||
|
<p class="poem"><span>That’s poetry for me.</span><span>No pitch deck. No growth plan. No conversion rate.</span></p>
|
||||||
|
<p class="body">Just something I wanted to say and the patience to find the right words for it.</p>
|
||||||
|
<div class="spacer"></div>
|
||||||
|
<div>${btn('READ MY POETRY', SITE.pending, 'ghost-light')}</div>
|
||||||
|
</article>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="section" aria-labelledby="know-now">
|
||||||
|
<div class="wrap">
|
||||||
|
<div class="sec-head reveal">
|
||||||
|
<div class="stack-sm">${eyebrow('WHAT I KNOW NOW')}<h2 id="know-now" class="h-display">Eight Years In, I Have Fewer Absolutes.</h2></div>
|
||||||
|
</div>
|
||||||
|
<div class="principles reveal">
|
||||||
|
${knowNow.map(([h, p]) => `<article class="principle"><h3 class="h-md">${h}</h3><div class="lines">${paras(p)}</div></article>`).join('')}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="section" aria-labelledby="founders-call">
|
||||||
|
<div class="wrap">
|
||||||
|
<div class="showcase reverse reveal">
|
||||||
|
<div class="visual stack-sm">
|
||||||
|
<article class="card card-white"><span class="index">01</span><h3 class="h-sm">Diagnose First</h3><div class="prose"><p>The obvious problem and the real problem are not always the same.</p><p>Get close enough to know the difference.</p></div></article>
|
||||||
|
<article class="card card-white"><span class="index">02</span><h3 class="h-sm">Make It Work in the Real Business</h3><div class="prose"><p>A strategy can look great on paper and fall apart on Monday morning.</p><p>I care about what can actually be executed, measured, and improved.</p><p class="body-ink">That is the same standard I use inside my own companies.</p></div></article>
|
||||||
|
</div>
|
||||||
|
<div class="stack">
|
||||||
|
${eyebrow('WHEN FOUNDERS CALL')}
|
||||||
|
<h2 id="founders-call" class="h-display">I Work With Founders the Way I Run My Own Companies.</h2>
|
||||||
|
<div class="prose">
|
||||||
|
<p>When I step into another founder’s business, I want to understand what is actually happening before deciding what needs to change.</p>
|
||||||
|
<p class="body-ink">No assumptions. No solution looking for a problem.</p>
|
||||||
|
</div>
|
||||||
|
<div class="btn-row">${btn('WORK WITH DYLAN', '/consulting/')}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="section" aria-labelledby="curious">
|
||||||
|
<div class="wrap">
|
||||||
|
<div class="closing closing-dark reveal">
|
||||||
|
<div class="closing-inner">
|
||||||
|
${eyebrow('STILL CURIOUS')}
|
||||||
|
<h2 id="curious" class="h-display-lg">I’m More Interested in What I Haven’t Seen Yet.</h2>
|
||||||
|
<div class="prose">
|
||||||
|
<p>Eight years ago, I couldn’t have mapped the route that brought me here. I’m glad I didn’t.</p>
|
||||||
|
<p>There are still people I haven’t met, problems I haven’t seen, and ideas that will probably ruin a perfectly good night’s sleep.</p>
|
||||||
|
<p style="color:var(--porcelain)">If the next eight years surprise me too, I’ll take it.</p>
|
||||||
|
</div>
|
||||||
|
<div class="btn-row">${btn('START A CONVERSATION', '/contact/')}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
`,
|
||||||
|
};
|
||||||
@@ -0,0 +1,160 @@
|
|||||||
|
import { icon, eyebrow, btn, paras, faq } from '../layout.mjs';
|
||||||
|
|
||||||
|
const covers = [
|
||||||
|
['users', 'Entity & Ownership', ['LLC, S-Corp, or C-Corp considerations based on the business model, funding plans, and long-term goals', 'Co-founder and early-partner ownership structure', 'Existing entity and structure review']],
|
||||||
|
['pin', 'State & Market', ['State selection based on industry, filing requirements, costs, licensing, and operating plans', 'Multi-state operations and foreign qualification considerations', 'US setup considerations for international founders', 'UAE free zone considerations for US founders']],
|
||||||
|
['layers', 'Setup & Infrastructure', ['Licensing and compliance mapping', 'Banking and payment infrastructure', 'Registered agent setup', 'Bookkeeping and payroll sequencing', 'Insurance considerations', 'First-90-days administrative roadmap']],
|
||||||
|
];
|
||||||
|
|
||||||
|
const who = [
|
||||||
|
['rocket', 'You’re Starting Your First Company.', ['You have the idea and a plan to move.', 'Now you need to make the structural decisions without relying on a collection of contradictory search results and founder opinions.']],
|
||||||
|
['building', 'The Business Already Exists, but the Setup Feels Wrong.', ['Maybe the company has outgrown its original structure.', 'Maybe you formed in a state because someone told you to.', 'Maybe revenue, hiring, ownership, or operations have changed enough to make another look worthwhile.', 'We examine what you have before deciding whether anything actually needs to change.']],
|
||||||
|
['route', 'You’re Crossing a Border.', ['International founders entering the US and US founders exploring the UAE face another layer of structural and operational decisions.', 'The setup needs to make sense for where you’re going, not simply where you started.']],
|
||||||
|
];
|
||||||
|
|
||||||
|
const steps = [
|
||||||
|
['Diagnose', ['We review the planned or existing business structure against the industry, ownership, operating markets, revenue model, and growth plans.', 'If the company already exists, we look at what is working before suggesting that anything change.']],
|
||||||
|
['Map the Setup', ['You receive a prioritized roadmap covering the relevant entity, state, licensing, banking, ownership, and administrative considerations in sequence.', 'You know what comes first and what can wait.']],
|
||||||
|
['Set It Up', ['If you want help moving through the roadmap, a setup sprint takes the business through the practical steps with the appropriate specialists involved where needed.']],
|
||||||
|
];
|
||||||
|
|
||||||
|
const faqs = [
|
||||||
|
['Is Delaware always the right answer?', ['No.', 'Delaware can make sense for certain companies, particularly depending on financing, ownership, and future plans, but it isn’t automatically the best choice for every founder.', 'Your operating location, business model, ownership, costs, compliance obligations, and plans should all be considered before deciding where to form.']],
|
||||||
|
['Can you help if my business is already formed?', ['Yes.', 'The diagnostic can review an existing structure as well as a planned one.', 'If something looks inefficient or no longer fits the business, we identify it. That doesn’t mean restructuring automatically makes sense.', 'Sometimes the right recommendation is to leave what already works alone.']],
|
||||||
|
['Do you handle the actual filings?', ['The setup sprint can help coordinate the formation and administrative process.', 'Where filings or decisions require licensed legal, tax, accounting, or other professional services, the appropriate qualified professional handles that portion.']],
|
||||||
|
['Are you a lawyer or accountant?', ['No.', 'This is business and operational consulting, not legal, tax, or accounting advice.', 'Where formal professional advice is required, we work alongside your existing counsel or accounting professionals or help connect the process with appropriate specialists.']],
|
||||||
|
];
|
||||||
|
|
||||||
|
const layers = ['Entity.', 'State.', 'Ownership.', 'Banking.', 'Licensing.'];
|
||||||
|
const growth = ['You open another account.', 'Hire someone.', 'Add a partner.', 'Enter another market.', 'Raise money.', 'Sell something.'];
|
||||||
|
|
||||||
|
export default {
|
||||||
|
path: '/consulting/business-setup/',
|
||||||
|
title: 'Business Setup Consulting for Founders | Dylan Mazzei',
|
||||||
|
description: 'Business setup consulting for founders covering entity and state selection, licensing, banking, ownership, US expansion, UAE formation, and more.',
|
||||||
|
schema: [
|
||||||
|
{ '@context': 'https://schema.org', '@type': 'FAQPage', mainEntity: faqs.map(([q, a]) => ({ '@type': 'Question', name: q, acceptedAnswer: { '@type': 'Answer', text: a.join(' ') } })) },
|
||||||
|
],
|
||||||
|
body: `
|
||||||
|
<section class="page-hero" aria-labelledby="b-hero">
|
||||||
|
<div class="wrap page-hero-grid">
|
||||||
|
<div class="stack anim">
|
||||||
|
<nav class="crumbs" aria-label="Breadcrumb"><a href="/consulting/">Consulting</a>${icon('chev')}<span>Business Setup</span></nav>
|
||||||
|
${eyebrow('BUSINESS SETUP CONSULTING')}
|
||||||
|
<h1 id="b-hero" class="h-display-lg">Make the First Decisions With the Future in Mind.</h1>
|
||||||
|
<p class="lead">The first decisions in a company can be surprisingly persistent.</p>
|
||||||
|
<div class="prose">
|
||||||
|
<p>Entity. State. Ownership. Banking. Licensing. The administrative pieces aren’t the exciting part of starting a business, but getting them wrong can create expensive problems once the company starts moving.</p>
|
||||||
|
<p class="body-ink">I’ve formed and operated companies across multiple US states and the UAE.</p>
|
||||||
|
<p>The goal is to think through the structure before growth makes changing it harder.</p>
|
||||||
|
</div>
|
||||||
|
<div class="btn-row">${btn('BOOK YOUR DIAGNOSTIC', '/contact/')}</div>
|
||||||
|
</div>
|
||||||
|
<div class="panel anim" aria-hidden="true">
|
||||||
|
<div class="panel-bar"><span class="lights"><i></i><i></i><i></i></span><strong>SETTING THE FIRST LAYER</strong></div>
|
||||||
|
<div style="padding:20px;display:grid;gap:8px">
|
||||||
|
${layers.map((l, i) => `<div class="row" style="border:1px solid var(--mist);border-radius:12px;padding:14px 16px;margin-left:${i * 14}px;${i === 0 ? 'background:var(--violet);color:var(--porcelain);border-color:var(--violet)' : ''}"><span class="index" style="${i === 0 ? 'color:var(--porcelain)' : ''}">0${i + 1}</span><span class="name" style="font-weight:700;font-size:16px">${l}</span></div>`).join('')}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="section" aria-labelledby="layer">
|
||||||
|
<div class="wrap">
|
||||||
|
<div class="sec-head reveal">
|
||||||
|
<div class="stack-sm">${eyebrow('SETTING THE FIRST LAYER')}<h2 id="layer" class="h-display">Get the Foundation Right Before You Build on It.</h2></div>
|
||||||
|
<div class="prose"><p class="body-ink">Business setup is more than filing an entity.</p><p>We look at how the decisions fit together and what the business may need next.</p></div>
|
||||||
|
</div>
|
||||||
|
<div class="covers reveal">
|
||||||
|
${covers.map(([ic, h, items]) => `<article class="cover"><div class="cover-head"><span class="ic">${icon(ic)}</span><h3>${h}</h3></div><ul>${items.map((it) => `<li>${icon('check')}${it}</li>`).join('')}</ul></article>`).join('')}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="section" aria-labelledby="who-b">
|
||||||
|
<div class="wrap">
|
||||||
|
<div class="sec-head reveal">
|
||||||
|
<div class="stack-sm">${eyebrow('WHO THIS IS FOR')}<h2 id="who-b" class="h-display">Before “We’ll Figure It Out Later” Gets Expensive.</h2></div>
|
||||||
|
</div>
|
||||||
|
<div class="cards cards-3 reveal">
|
||||||
|
${who.map(([ic, h, p]) => `<article class="card"><span class="ic">${icon(ic)}</span><h3 class="h-sm">${h}</h3><div class="prose">${paras(p)}</div></article>`).join('')}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="section band" aria-labelledby="order">
|
||||||
|
<div class="wrap">
|
||||||
|
<div class="sec-head reveal">
|
||||||
|
<div class="stack-sm">${eyebrow('HOW DELIVERY WORKS')}<h2 id="order" class="h-display">Make the Decisions in the Right Order.</h2></div>
|
||||||
|
<div class="prose">
|
||||||
|
<p>You don’t need eight disconnected recommendations.</p>
|
||||||
|
<p style="color:var(--porcelain)">You need to understand which decision affects the next one.</p>
|
||||||
|
<p>That’s why this service follows the same diagnostic-first approach as my broader consulting work.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="rules">
|
||||||
|
${steps.map(([h, p], i) => `<article class="rule reveal"><span class="index">STEP_0${i + 1}</span><h3>${i + 1}. ${h}</h3><div class="prose">${p.map((t, j) => `<p${j === 0 ? ' class="ink"' : ''}>${t}</p>`).join('')}</div></article>`).join('')}
|
||||||
|
</div>
|
||||||
|
<div class="sec-foot reveal" style="border-top:0;margin-top:48px">
|
||||||
|
<div class="card card-dark" style="background:rgba(255,255,255,.04);border:1px solid var(--dark-line);max-width:720px">
|
||||||
|
<p class="statement">I’m an operator, not your lawyer or accountant.</p>
|
||||||
|
<p>Where a decision requires formal legal, tax, or accounting advice, we coordinate with your existing professionals or help bring the right qualified advisor into the conversation.</p>
|
||||||
|
</div>
|
||||||
|
${btn('START WITH THE DIAGNOSTIC', '/contact/', 'light')}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="section" aria-labelledby="live">
|
||||||
|
<div class="wrap">
|
||||||
|
<div class="showcase reveal">
|
||||||
|
<div class="stack">
|
||||||
|
${eyebrow('WHY THIS IS DIFFERENT')}
|
||||||
|
<h2 id="live" class="h-display">I’ve Had to Live With These Decisions Too.</h2>
|
||||||
|
<div class="prose">
|
||||||
|
<p>I’ve started enough companies to know how tempting it is to treat formation like paperwork standing between you and the interesting part.</p>
|
||||||
|
<p class="body-ink">Then the company grows.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="stack">
|
||||||
|
<div class="panel" aria-hidden="true">
|
||||||
|
<div class="panel-bar"><span class="lights"><i></i><i></i><i></i></span></div>
|
||||||
|
<ol style="padding:8px 0">${growth.map((g, i) => `<li class="row" style="padding:12px 20px${i === 0 ? ';border-top:0' : ''}"><span class="index">${String(i + 1).padStart(2, '0')}</span><span class="name">${g}</span></li>`).join('')}</ol>
|
||||||
|
</div>
|
||||||
|
<div class="prose">
|
||||||
|
<p class="sr-only">You open another account. Hire someone. Add a partner. Enter another market. Raise money. Sell something.</p>
|
||||||
|
<p class="body-ink">Suddenly, a decision made in an afternoon is still sitting in the middle of the business years later.</p>
|
||||||
|
<p>My perspective comes from operating companies across different industries and markets, not simply helping someone complete a filing.</p>
|
||||||
|
<p>It’s also why I wrote The Business Launch Playbook.</p>
|
||||||
|
<p class="body-ink">The beginning deserves more thought than it usually gets.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="section" aria-labelledby="faq-b">
|
||||||
|
<div class="wrap faq-layout">
|
||||||
|
<div class="stack-sm sticky reveal">${eyebrow('FREQUENTLY ASKED QUESTIONS')}<h2 id="faq-b" class="h-display">Before You File Anything.</h2></div>
|
||||||
|
<div class="reveal">${faq(faqs)}</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="section" aria-labelledby="structure">
|
||||||
|
<div class="wrap">
|
||||||
|
<div class="closing reveal">
|
||||||
|
<div class="closing-inner">
|
||||||
|
${eyebrow('START WITH THE STRUCTURE')}
|
||||||
|
<h2 id="structure" class="h-display-lg">Make the Early Decisions Easier to Live With Later.</h2>
|
||||||
|
<div class="prose">
|
||||||
|
<p>You don’t need every detail of the next five years figured out before starting.</p>
|
||||||
|
<p>You do need a structure that makes sense for the business you’re actually planning to operate.</p>
|
||||||
|
<p class="body-ink">We’ll map the decisions in the right order before you commit more time, money, and paperwork to them.</p>
|
||||||
|
</div>
|
||||||
|
<div class="btn-row">${btn('BOOK YOUR DIAGNOSTIC', '/contact/')}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
`,
|
||||||
|
};
|
||||||
@@ -0,0 +1,224 @@
|
|||||||
|
import { icon, eyebrow, btn, textLink, paras, faq, SITE } from '../layout.mjs';
|
||||||
|
|
||||||
|
const steps = [
|
||||||
|
['Business Diagnostic', ['We go inside the business to examine operations, financials, technology, marketing, and the places where growth is creating friction.', 'The goal is simple: find what deserves attention first.']],
|
||||||
|
['Roadmap Delivery', ['You receive a documented, prioritised roadmap built around what we found.', 'What needs to change. What can wait. What your team can handle. And where outside execution may actually help.']],
|
||||||
|
['Execution Sprint or Advisory', ['If it makes sense to keep working together, we move into a focused 90-day sprint or an ongoing advisory engagement.', 'If your team can take it from there, they do.']],
|
||||||
|
];
|
||||||
|
|
||||||
|
const plans = [
|
||||||
|
{
|
||||||
|
name: 'Business Diagnostic', h: 'Know What You’re Solving.', p: 'The mandatory starting point for every engagement.', fee: 'Fixed fee, quoted at booking',
|
||||||
|
items: ['Comprehensive operational audit', 'Marketing and visibility analysis', 'Cost structure review', 'Prioritised strategic roadmap', '45-minute strategy debrief'],
|
||||||
|
cta: 'BOOK YOUR DIAGNOSTIC', featured: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '90-Day Sprint', h: 'Turn the Roadmap Into Movement.', p: 'Hands-on execution around a defined problem, with a clear scope and enough time to make meaningful progress.', fee: 'Fixed scope, fixed fee',
|
||||||
|
items: ['Everything in the Diagnostic', 'Execution by Dylan’s specialist teams', 'System setup and automation', 'Vendor and talent vetting', 'Weekly progress check-ins'],
|
||||||
|
cta: 'APPLY FOR A 90-DAY SPRINT',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Advisory Retainer', h: 'Keep an Operator in the Room.', p: 'Ongoing strategic involvement for founders and internal teams who need another experienced perspective as the business moves.', fee: 'Monthly engagement',
|
||||||
|
items: ['Monthly strategic roadmapping', 'Bi-weekly advisory calls', 'Direct access for urgent blocks', 'Quarterly P&L reviews', 'Priority access to Dylan’s operating teams'],
|
||||||
|
cta: 'REQUEST ADVISORY',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const services = [
|
||||||
|
{ id: 'marketing', icon: 'search', name: 'Marketing & AI Search', h: 'Get Found Where Attention Is Moving.', p: ['SEO, AI search visibility, paid media, and funnel strategy grounded in what people actually discover, click, and choose.', 'Marketing has been part of my operating world for years, and it remains one of the areas where technology keeps changing the answer.'], cta: 'EXPLORE MARKETING & AI SEARCH', href: '/consulting/marketing/' },
|
||||||
|
{ id: 'business-setup', icon: 'building', name: 'Business Setup', h: 'Start With Fewer Expensive Mistakes.', p: ['Entity and state selection, licensing, banking architecture, and the practical decisions that turn an idea into an operating business.', 'I’ve started enough companies to know that early decisions have a habit of following you. I unpack more of that thinking in The Business Launch Playbook.'], cta: 'EXPLORE BUSINESS SETUP', href: '/consulting/business-setup/' },
|
||||||
|
{ id: 'optimization', icon: 'gauge', name: 'Business Optimization', h: 'Find What Growth Made Messy.', p: ['Growth creates opportunity.', 'It also creates workarounds, extra steps, unnecessary costs, unclear ownership, and processes nobody remembers choosing.', 'The job is to find what the business has outgrown and make it work for where the company is going next.'], cta: 'EXPLORE BUSINESS OPTIMIZATION', href: SITE.pending },
|
||||||
|
{ id: 'supply-chain', icon: 'truck', name: 'Supply Chain', h: 'Know What Happens Before It Reaches the Customer.', p: ['Sourcing, supplier vetting, logistics planning, and landed-cost analysis for businesses where products have to move through the real world.', 'My work across consumer products and e-commerce has taught me that what happens before the sale can determine whether the sale makes sense.'], cta: 'EXPLORE SUPPLY CHAIN', href: SITE.pending },
|
||||||
|
{ id: 'cybersecurity', icon: 'shield', name: 'Cybersecurity', h: 'Find the Exposure Before Someone Else Does.', p: ['Security posture assessments, vulnerability reviews, and compliance readiness grounded in how the business actually operates.', 'The goal isn’t security theatre.', 'It’s understanding where the business is exposed and what deserves attention first.'], cta: 'EXPLORE CYBERSECURITY', href: SITE.pending },
|
||||||
|
{ id: 'education', icon: 'edu', name: 'Education', h: 'Make the Strategy Survive the Classroom.', p: ['EdTech product strategy, institutional technology adoption, and market-entry thinking shaped around the realities of schools, educators, and implementation.', 'A product can make perfect sense in a meeting and still fail the people expected to use it.', 'The classroom gets the final vote.'], cta: 'EXPLORE EDUCATION CONSULTING', href: SITE.pending },
|
||||||
|
];
|
||||||
|
|
||||||
|
const faqs = [
|
||||||
|
['What services does Dylan Mazzei offer?', ['My consulting work spans business diagnostics, 90-day execution sprints, ongoing advisory, fractional leadership, marketing and AI search, business setup and optimisation, supply chain, cybersecurity, and education strategy.', 'Every engagement starts by understanding the business before deciding which, if any, of those services make sense.']],
|
||||||
|
['How do I book a consultation?', ['Start by booking the Business Diagnostic.', 'We’ll review the business, identify the areas that deserve attention, and use those findings to determine the most useful next step.']],
|
||||||
|
['What is the pricing structure?', ['The Business Diagnostic is a fixed fee quoted at booking.', '90-day sprints are fixed-scope, fixed-fee engagements. Advisory and fractional leadership are structured around the level of ongoing involvement required.']],
|
||||||
|
['What happens after the diagnostic?', ['You receive a prioritised roadmap outlining what needs attention, what should happen first, and where execution may be needed.', 'You can take that roadmap to your own team or continue working with mine.']],
|
||||||
|
['Do you work with businesses outside the US?', ['Yes. I operate across the US and Dubai and can work with businesses in other markets when the engagement is a good fit.']],
|
||||||
|
['Do I have to continue after the diagnostic?', ['No. The diagnostic is designed to be useful on its own.', 'If your team can execute the roadmap internally, you leave with a clearer direction and a place to start.']],
|
||||||
|
];
|
||||||
|
|
||||||
|
export default {
|
||||||
|
path: '/consulting/',
|
||||||
|
title: 'Business Consulting for Founders | Dylan Mazzei',
|
||||||
|
description: 'Work with Dylan Mazzei through diagnostic-first business consulting, execution sprints, advisory, and fractional leadership built for founders.',
|
||||||
|
schema: [
|
||||||
|
{ '@context': 'https://schema.org', '@type': 'FAQPage', mainEntity: faqs.map(([q, a]) => ({ '@type': 'Question', name: q, acceptedAnswer: { '@type': 'Answer', text: a.join(' ') } })) },
|
||||||
|
],
|
||||||
|
body: `
|
||||||
|
<section class="page-hero" aria-labelledby="c-hero">
|
||||||
|
<div class="wrap page-hero-grid">
|
||||||
|
<div class="stack anim">
|
||||||
|
${eyebrow('OPERATOR-LED CONSULTING')}
|
||||||
|
<h1 id="c-hero" class="h-display-lg">Find the Real Problem. Then Fix the Right One.</h1>
|
||||||
|
<p class="lead">Most founders know when something in the business isn’t working. The harder part is knowing why.</p>
|
||||||
|
<div class="prose">
|
||||||
|
<p>I start there. Before recommending a strategy, service, or solution, I look inside the business, find what is actually creating friction, and put the priorities in order.</p>
|
||||||
|
<p>It’s the same approach I use across the companies I operate today. Understand what is happening first. Decide what deserves attention second.</p>
|
||||||
|
<p class="statement">Then move.</p>
|
||||||
|
</div>
|
||||||
|
<div class="btn-row">${btn('BOOK YOUR DIAGNOSTIC', '/contact/')}</div>
|
||||||
|
</div>
|
||||||
|
<div class="panel panel-dark anim" aria-hidden="true">
|
||||||
|
<div class="panel-bar"><span class="lights"><i></i><i></i><i></i></span><span class="file">${icon('brace')}diagnostic.log</span></div>
|
||||||
|
<pre class="code-pre"><span class="ln"><span class="p">$</span> <span class="k">look</span> inside the business</span><span class="ln"><span class="s">✓</span> operations</span><span class="ln"><span class="s">✓</span> financials</span><span class="ln"><span class="s">✓</span> technology</span><span class="ln"><span class="s">✓</span> marketing</span><span class="ln"><span class="p">$</span> <span class="k">find</span> friction</span><span class="ln"><span class="n">→</span> what deserves attention first</span><span class="ln"><span class="p">$</span> <span class="k">put</span> the priorities in order</span><span class="ln"><span class="p">$</span> <span class="k">move</span><span class="cursor"></span></span></pre>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="section" aria-labelledby="how">
|
||||||
|
<div class="wrap">
|
||||||
|
<div class="sec-head reveal">
|
||||||
|
<div class="stack-sm">${eyebrow('HOW IT WORKS')}<h2 id="how" class="h-display">Diagnosis Before Prescription.</h2></div>
|
||||||
|
<div class="prose"><p>The loudest problem isn’t always the one holding the business back.</p><p class="body-ink">So we find the cause before we start fixing the symptoms.</p></div>
|
||||||
|
</div>
|
||||||
|
<div class="process reveal">
|
||||||
|
${steps.map(([h, p], i) => `<article class="process-step"><span class="num">${i + 1}</span><h3 class="h-md">${h}</h3><div class="prose">${paras(p)}</div></article>`).join('')}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="section" id="engagements" aria-labelledby="eng">
|
||||||
|
<div class="wrap">
|
||||||
|
<div class="sec-head reveal">
|
||||||
|
<div class="stack-sm">${eyebrow('ENGAGEMENT OPTIONS')}<h2 id="eng" class="h-display">Different Problems Need Different Levels of Involvement.</h2></div>
|
||||||
|
<div class="prose"><p class="body-ink">Start with the diagnostic.</p><p>What comes after depends on what the business actually needs.</p></div>
|
||||||
|
</div>
|
||||||
|
<div class="plans reveal">
|
||||||
|
${plans
|
||||||
|
.map(
|
||||||
|
(pl) => `<article class="plan${pl.featured ? ' plan-featured' : ''}">
|
||||||
|
<div class="plan-name"><span>${pl.name}</span>${pl.featured ? `<span class="dot"></span>` : ''}</div>
|
||||||
|
<h3>${pl.h}</h3>
|
||||||
|
<p>${pl.p}</p>
|
||||||
|
<div class="fee">${pl.fee}</div>
|
||||||
|
<ul>${pl.items.map((it) => `<li>${icon('check')}${it}</li>`).join('')}</ul>
|
||||||
|
${btn(pl.cta, '/contact/', pl.featured ? 'primary' : 'ghost')}
|
||||||
|
</article>`
|
||||||
|
)
|
||||||
|
.join('')}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="section band" aria-labelledby="frac">
|
||||||
|
<div class="wrap">
|
||||||
|
<div class="showcase" style="background:transparent;padding:0">
|
||||||
|
<div class="stack reveal">
|
||||||
|
${eyebrow('FRACTIONAL LEADERSHIP')}
|
||||||
|
<h2 id="frac" class="h-display">When the Business Needs an Owner, Not Another Recommendation.</h2>
|
||||||
|
<div class="prose">
|
||||||
|
<p>Some problems don’t need another project.</p>
|
||||||
|
<p style="color:var(--porcelain)">They need someone accountable for the function.</p>
|
||||||
|
<p>I can step into the business as a fractional CMO, COO, CISO, or Chief AI Officer, bringing the same operator mindset that shapes my current ventures into a defined leadership role.</p>
|
||||||
|
</div>
|
||||||
|
<p class="statement">Strategy gets more useful when someone owns what happens next.</p>
|
||||||
|
<div class="btn-row">${btn('EXPLORE FRACTIONAL ROLES', SITE.pending, 'light')}</div>
|
||||||
|
</div>
|
||||||
|
<div class="roles reveal" aria-hidden="true">
|
||||||
|
<div class="role"><span class="index">FRACTIONAL</span><b>CMO</b></div>
|
||||||
|
<div class="role"><span class="index">FRACTIONAL</span><b>COO</b></div>
|
||||||
|
<div class="role"><span class="index">FRACTIONAL</span><b>CISO</b></div>
|
||||||
|
<div class="role"><span class="index">FRACTIONAL</span><b>Chief AI Officer</b></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="section" id="services" aria-labelledby="svc">
|
||||||
|
<div class="wrap">
|
||||||
|
<div class="sec-head reveal">
|
||||||
|
<div class="stack-sm">${eyebrow('SERVICE LINES')}<h2 id="svc" class="h-display">Where Operating Experience Becomes Useful.</h2></div>
|
||||||
|
<div class="prose"><p>I stay close to areas where my teams and I are already doing the work.</p><p>Not because every business needs the same solution, but because experience is more useful when it comes from solving real versions of the problem.</p></div>
|
||||||
|
</div>
|
||||||
|
<div class="tabs reveal" data-tabs>
|
||||||
|
<div class="tab-list" role="tablist" aria-label="Service lines">
|
||||||
|
${services.map((s, i) => `<button class="tab-btn" role="tab" id="tab-${s.id}" aria-controls="${s.id}" aria-selected="${i === 0}"${i ? ' tabindex="-1"' : ''} type="button"><span class="ic">${icon(s.icon)}</span><span>${s.name}</span>${icon('arrow', 'arr')}</button>`).join('')}
|
||||||
|
</div>
|
||||||
|
<div class="tab-panels">
|
||||||
|
${services
|
||||||
|
.map(
|
||||||
|
(s) => `<article class="tab-panel" role="tabpanel" id="${s.id}" aria-labelledby="tab-${s.id}">
|
||||||
|
<span class="tp-title">${s.name}</span>
|
||||||
|
<h3 class="h-display">${s.h}</h3>
|
||||||
|
<div class="prose">${paras(s.p)}</div>
|
||||||
|
<div class="btn-row">${btn(s.cta, s.href)}</div>
|
||||||
|
</article>`
|
||||||
|
)
|
||||||
|
.join('')}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="section" aria-labelledby="why">
|
||||||
|
<div class="wrap">
|
||||||
|
<div class="sec-head reveal">
|
||||||
|
<div class="stack-sm">${eyebrow('WHY DYLAN')}<h2 id="why" class="h-display">I’ve Been on the Other Side of the Invoice.</h2></div>
|
||||||
|
<div class="prose">
|
||||||
|
<p>I’ve spent more than eight years operating businesses across different industries.</p>
|
||||||
|
<p>Along the way, I’ve hired consultants, agencies, specialists, vendors, and teams. I’ve made investments that worked and others that looked considerably better in the proposal.</p>
|
||||||
|
<p class="body-ink">I’ve also taken four companies through successful exits.</p>
|
||||||
|
<p>That changes how I look at someone else’s time and money.</p>
|
||||||
|
<p>I know the difference between a recommendation that sounds impressive and one that survives contact with the actual business.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="principles reveal">
|
||||||
|
<article class="principle"><span class="index">01</span><h3 class="h-md">Understand Before Recommending</h3><div class="prose"><p>I don’t need to arrive with the answer.</p><p>I need to ask enough of the right questions to find it.</p></div></article>
|
||||||
|
<article class="principle"><span class="index">02</span><h3 class="h-md">Make the Tradeoffs Visible</h3><div class="prose"><p>Every meaningful decision costs something.</p><p class="ink">Money. Time. Focus. Speed. Flexibility.</p><p>A useful strategy tells you what you’re choosing and what you’re giving up.</p></div></article>
|
||||||
|
<article class="principle"><span class="index">03</span><h3 class="h-md">Stay for the Result</h3><div class="prose"><p>A strategy deck is not the finish line.</p><p>If we move into execution, I care about what changed because we did.</p></div></article>
|
||||||
|
</div>
|
||||||
|
<div class="sec-foot reveal" style="justify-content:flex-end;margin-top:40px">${textLink('GET TO KNOW DYLAN', '/about/')}</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="section" aria-labelledby="behind">
|
||||||
|
<div class="wrap">
|
||||||
|
<div class="showcase reveal">
|
||||||
|
<div class="stack">
|
||||||
|
${eyebrow('THE OPERATOR BEHIND THE WORK')}
|
||||||
|
<h2 id="behind" class="h-display">The Consulting Came After the Companies.</h2>
|
||||||
|
<div class="prose">
|
||||||
|
<p>I didn’t start in consulting and eventually decide to operate businesses.</p>
|
||||||
|
<p class="body-ink">It happened the other way around.</p>
|
||||||
|
<p>Consulting grew out of the decisions, mistakes, patterns, and results of running companies across different industries.</p>
|
||||||
|
<p>You can read the full story or explore the businesses and exits that shaped it.</p>
|
||||||
|
</div>
|
||||||
|
<div class="btn-row">${btn('EXPLORE DYLAN’S VENTURES', '/portfolio/')}</div>
|
||||||
|
</div>
|
||||||
|
<div class="visual portrait">
|
||||||
|
<img src="/assets/dylan-portrait.jpg" alt="Dylan Mazzei" width="900" height="900" loading="lazy">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="section" aria-labelledby="faq-h">
|
||||||
|
<div class="wrap faq-layout">
|
||||||
|
<div class="stack-sm sticky reveal">${eyebrow('FREQUENTLY ASKED QUESTIONS')}<h2 id="faq-h" class="h-display">Questions Founders Usually Ask Before We Start.</h2></div>
|
||||||
|
<div class="reveal">${faq(faqs)}</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="section" aria-labelledby="clarity">
|
||||||
|
<div class="wrap">
|
||||||
|
<div class="closing closing-dark reveal">
|
||||||
|
<div class="closing-inner">
|
||||||
|
${eyebrow('START WITH CLARITY')}
|
||||||
|
<h2 id="clarity" class="h-display-lg">Stop Spending Money on the Wrong Problem.</h2>
|
||||||
|
<div class="prose">
|
||||||
|
<p>You don’t need to know exactly what is wrong before we talk.</p>
|
||||||
|
<p>Bring me the bottleneck, the stalled growth, the messy operation, or simply the feeling that the business should be working better than it is.</p>
|
||||||
|
<p style="color:var(--porcelain)">We’ll figure out what deserves your attention before you spend more time or money trying to fix it.</p>
|
||||||
|
</div>
|
||||||
|
<div class="btn-row">${btn('BOOK YOUR DIAGNOSTIC', '/contact/')}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
`,
|
||||||
|
};
|
||||||
@@ -0,0 +1,86 @@
|
|||||||
|
import { icon, eyebrow, btn, SITE } from '../layout.mjs';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
path: '/contact/',
|
||||||
|
title: 'Contact Dylan Mazzei | Business & Partnerships',
|
||||||
|
description: 'Contact Dylan Mazzei about business opportunities, strategic partnerships, consulting, media inquiries, or other conversations worth having.',
|
||||||
|
body: `
|
||||||
|
<section class="page-hero" aria-labelledby="ct-hero">
|
||||||
|
<div class="wrap contact-grid">
|
||||||
|
<div class="stack anim">
|
||||||
|
${eyebrow('CONTACT')}
|
||||||
|
<h1 id="ct-hero" class="h-display-lg">Interesting Things Usually Start With Hello.</h1>
|
||||||
|
<p class="lead">A business at a crossroads. An idea taking shape. A partnership worth exploring. Or something I haven’t thought of yet.</p>
|
||||||
|
<div class="prose">
|
||||||
|
<p class="body-ink">You don’t need a polished pitch.</p>
|
||||||
|
<p>Tell me what you’re working on and why you think we should talk.</p>
|
||||||
|
</div>
|
||||||
|
<div class="direct">
|
||||||
|
<div class="direct-row">
|
||||||
|
<small>DIRECT EMAIL</small>
|
||||||
|
<span class="val"><a href="mailto:${SITE.email}">${SITE.email}</a><button class="copy-btn" type="button" data-copy="${SITE.email}">Copy</button></span>
|
||||||
|
</div>
|
||||||
|
<div class="direct-row">
|
||||||
|
<small>WHERE I WORK</small>
|
||||||
|
<span class="val">Texas • Florida • New York • Dubai</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="stack anim">
|
||||||
|
<form class="panel form-card" id="inquiry" data-to="${SITE.email}" novalidate>
|
||||||
|
<div class="panel-bar"><span class="lights" aria-hidden="true"><i></i><i></i><i></i></span><span class="panel-url">${SITE.email}</span></div>
|
||||||
|
<div class="stack-xs">
|
||||||
|
<h2 class="h-md">Send an Inquiry</h2>
|
||||||
|
<p class="body">Give me enough context to understand what you’re working on, where things stand, and what you’d like to discuss.</p>
|
||||||
|
</div>
|
||||||
|
<div class="form-grid">
|
||||||
|
<div class="field"><label for="f-name">Name</label><input id="f-name" name="name" type="text" autocomplete="name" required></div>
|
||||||
|
<div class="field"><label for="f-email">Email</label><input id="f-email" name="email" type="email" autocomplete="email" required></div>
|
||||||
|
<div class="field"><label for="f-company">Company</label><input id="f-company" name="company" type="text" autocomplete="organization"></div>
|
||||||
|
<div class="field"><label for="f-topic">Topic</label>
|
||||||
|
<select id="f-topic" name="topic">
|
||||||
|
<option value="">Select one</option>
|
||||||
|
<option>Business opportunity</option>
|
||||||
|
<option>Strategic partnership</option>
|
||||||
|
<option>Consulting</option>
|
||||||
|
<option>Media inquiry</option>
|
||||||
|
<option>Something else</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="field field-full"><label for="f-message">Message</label><textarea id="f-message" name="message" required></textarea></div>
|
||||||
|
</div>
|
||||||
|
<button class="btn btn-primary btn-block" type="submit">SEND AN INQUIRY ${icon('arrow')}</button>
|
||||||
|
<p class="form-status" id="form-status" role="status" aria-live="polite"></p>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<a class="cal-card" href="${SITE.calendar}">
|
||||||
|
<div><h3>Rather Put It on the Calendar?</h3><p>If you already know a conversation makes sense, skip the back-and-forth and find a time that works.</p></div>
|
||||||
|
<span class="go">${icon('calendar')}</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="section" aria-labelledby="where">
|
||||||
|
<div class="wrap">
|
||||||
|
<div class="showcase reveal">
|
||||||
|
<div class="stack">
|
||||||
|
${eyebrow('NOT SURE WHERE TO START?')}
|
||||||
|
<h2 id="where" class="h-display">See What I’m Working On First.</h2>
|
||||||
|
<div class="prose">
|
||||||
|
<p>If you want a little context before reaching out, explore the companies I operate today, see the businesses and exits that shaped my journey, or learn how I work with founders.</p>
|
||||||
|
<p class="body-ink">Then, if something clicks, come back and say hello.</p>
|
||||||
|
</div>
|
||||||
|
<div class="btn-row">${btn('EXPLORE MY VENTURES', '/portfolio/')}</div>
|
||||||
|
</div>
|
||||||
|
<div class="stack-sm">
|
||||||
|
<a class="card card-white" href="/portfolio/"><div class="card-top"><span class="ic">${icon('layers')}</span>${icon('arrow-ur', 'check')}</div><h3 class="h-sm">explore the companies I operate today</h3></a>
|
||||||
|
<a class="card card-white" href="/about/"><div class="card-top"><span class="ic">${icon('route')}</span>${icon('arrow-ur', 'check')}</div><h3 class="h-sm">see the businesses and exits that shaped my journey</h3></a>
|
||||||
|
<a class="card card-white" href="/consulting/"><div class="card-top"><span class="ic">${icon('compass')}</span>${icon('arrow-ur', 'check')}</div><h3 class="h-sm">learn how I work with founders</h3></a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
`,
|
||||||
|
};
|
||||||
@@ -0,0 +1,230 @@
|
|||||||
|
import { icon, eyebrow, btn, textLink, mark, SITE } from '../layout.mjs';
|
||||||
|
|
||||||
|
const ventures = [
|
||||||
|
['search', 'MARKETING & AI SEARCH', 'Leading teams through a constantly changing search landscape.'],
|
||||||
|
['chip', 'AI SOFTWARE', 'Building around new opportunities created by AI.'],
|
||||||
|
['bottle', 'SPIRITS', 'Taking a consumer brand from idea to market.'],
|
||||||
|
['edu', 'EDUCATION TECHNOLOGY', 'Creating technology designed for real classrooms.'],
|
||||||
|
['shield', 'CYBERSECURITY', 'Solving security challenges for growing businesses.'],
|
||||||
|
['bag', 'E-COMMERCE', 'Turning product ideas into businesses built around real customers.'],
|
||||||
|
];
|
||||||
|
|
||||||
|
const exits = [
|
||||||
|
['umbrella', 'Insurance', 'I grew an insurance business around strong client relationships, a clear understanding of the market, and service people could trust.'],
|
||||||
|
['megaphone', 'Marketing', 'Led an agency focused on helping businesses reach the right audiences, strengthen their presence, and turn attention into growth.'],
|
||||||
|
['heart', 'Home Healthcare', 'Grew a people-first business in an industry where trust, quality of care, and responsible leadership mattered every day.'],
|
||||||
|
['shirt', 'Apparel', 'Took a consumer concept into the market, shaping the product, brand, and customer experience from the ground up.'],
|
||||||
|
];
|
||||||
|
|
||||||
|
const ventureRows = ventures
|
||||||
|
.map(([ic, name]) => `<div class="row"><span class="ico">${icon(ic)}</span><span class="name">${name.replace('&', '&')}</span><span class="status"><span class="dot"></span>Active</span></div>`)
|
||||||
|
.join('');
|
||||||
|
const exitRows = exits
|
||||||
|
.map(([, name]) => `<div class="row">${icon('check', 'check')}<span class="name">${name}</span><span class="status">Exited</span></div>`)
|
||||||
|
.join('');
|
||||||
|
|
||||||
|
export default {
|
||||||
|
path: '/',
|
||||||
|
title: 'Dylan Mazzei | Founder, Operator & Entrepreneur',
|
||||||
|
description: 'Meet Dylan Mazzei, a founder and operator leading ventures across AI, software, spirits, education, cybersecurity, e-commerce, and more.',
|
||||||
|
body: `
|
||||||
|
<section class="hero" aria-labelledby="hero-title">
|
||||||
|
<div class="wrap">
|
||||||
|
<div class="hero-copy anim">
|
||||||
|
<span class="tag tag-upper tag-white" style="border:1px solid var(--mist)"><span class="dot"></span>DYLAN MAZZEI | FOUNDER & OPERATOR</span>
|
||||||
|
<h1 id="hero-title" class="h-display-lg">One Good Idea Has Never Been Enough for Me.</h1>
|
||||||
|
<p class="lead">I’ve spent the last eight years turning ideas into companies across marketing, AI, software, spirits, education, cybersecurity, e-commerce, and more. Four have been sold. Others are growing. And I’m nowhere near finished building.</p>
|
||||||
|
<div class="btn-row">${btn('MY STORY', '/about/')}</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="cluster" aria-hidden="true">
|
||||||
|
<div class="panel dash">
|
||||||
|
<div class="panel-bar"><span class="lights"><i></i><i></i><i></i></span><span>Portfolio</span><span class="panel-url">dylanmazzei.com/portfolio</span></div>
|
||||||
|
<div class="dash-body">
|
||||||
|
<div class="dash-head"><div><small>CURRENT VENTURES</small><strong>The Companies I’m Leading Today</strong></div></div>
|
||||||
|
<div class="kpis">
|
||||||
|
<div class="kpi"><span>EXITS</span><b>4</b></div>
|
||||||
|
<div class="kpi"><span>INDUSTRIES</span><b>6</b></div>
|
||||||
|
<div class="kpi"><span>YEARS OPERATING</span><b>8+</b></div>
|
||||||
|
<div class="kpi"><span>WHERE I WORK</span><b>4</b></div>
|
||||||
|
</div>
|
||||||
|
<div class="dash-cols">
|
||||||
|
<div class="list"><div class="list-head"><span>CURRENT VENTURES</span><span></span></div>${ventureRows}</div>
|
||||||
|
<div class="list"><div class="list-head"><span>4 EXITS</span><span></span></div>${exitRows}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="panel profile">
|
||||||
|
<img src="/assets/dylan-portrait.jpg" alt="" width="900" height="900">
|
||||||
|
<div class="profile-meta">
|
||||||
|
<strong>Dylan Mazzei</strong>
|
||||||
|
<span class="prole">FOUNDER & OPERATOR</span>
|
||||||
|
<div class="chips"><span class="tag">Texas</span><span class="tag">Florida</span><span class="tag">New York</span><span class="tag">Dubai</span></div>
|
||||||
|
<span class="btn btn-primary btn-sm btn-block">START A CONVERSATION</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="panel panel-dark code">
|
||||||
|
<div class="panel-bar"><span class="lights"><i></i><i></i><i></i></span><span class="file">${icon('brace')}dylan.json</span></div>
|
||||||
|
<pre class="code-pre"><span class="ln"><span class="p">{</span></span><span class="ln"> <span class="k">"role"</span><span class="p">:</span> <span class="s">"Founder & Operator"</span><span class="p">,</span></span><span class="ln"> <span class="k">"exits"</span><span class="p">:</span> <span class="n">4</span><span class="p">,</span></span><span class="ln"> <span class="k">"industries"</span><span class="p">:</span> <span class="n">6</span><span class="p">,</span></span><span class="ln"> <span class="k">"yearsOperating"</span><span class="p">:</span> <span class="s">"8+"</span><span class="p">,</span></span><span class="ln"> <span class="k">"whereIWork"</span><span class="p">: [</span></span><span class="ln"> <span class="s">"Texas"</span><span class="p">,</span> <span class="s">"Florida"</span><span class="p">,</span></span><span class="ln"> <span class="s">"New York"</span><span class="p">,</span> <span class="s">"Dubai"</span></span><span class="ln"> <span class="p">],</span></span><span class="ln"> <span class="k">"finishedBuilding"</span><span class="p">:</span> <span class="n">false</span><span class="cursor"></span></span><span class="ln"><span class="p">}</span></span></pre>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="section" id="ventures" aria-labelledby="ventures-title">
|
||||||
|
<div class="wrap">
|
||||||
|
<div class="sec-head reveal">
|
||||||
|
<div class="stack-sm">${eyebrow('CURRENT VENTURES')}<h2 id="ventures-title" class="h-display">The Companies I’m Leading Today</h2></div>
|
||||||
|
<div class="prose">
|
||||||
|
<p>I like being close to the decisions that shape a company, especially when there is something new to figure out.</p>
|
||||||
|
<p>Today, I lead businesses across AI, marketing, software, spirits, education technology, cybersecurity, and e-commerce. They operate in very different worlds, which keeps me curious.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="features reveal">
|
||||||
|
${ventures.map(([ic, h, p]) => `<article class="feature"><span class="ic">${icon(ic)}</span><h3>${h}</h3><p>${p}</p></article>`).join('')}
|
||||||
|
</div>
|
||||||
|
<div class="sec-foot reveal" style="justify-content:flex-end">${btn('EXPLORE MY VENTURES', '/portfolio/')}</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="section" id="journey" aria-labelledby="journey-title">
|
||||||
|
<div class="wrap">
|
||||||
|
<div class="sec-head reveal">
|
||||||
|
<div class="stack-sm">${eyebrow('THE JOURNEY SO FAR')}<h2 id="journey-title" class="h-display">Good Opportunities Rarely Look the Same.</h2></div>
|
||||||
|
<p class="body">I’ve never looked at opportunity through the lens of one industry. Over the years, that curiosity has taken me into very different businesses, including four that grew into successful exits.</p>
|
||||||
|
</div>
|
||||||
|
<div class="cards cards-4 exits reveal">
|
||||||
|
${exits
|
||||||
|
.map(
|
||||||
|
([ic, h, p]) => `<article class="card exit"><div class="card-top"><span class="ic">${icon(ic)}</span><span class="tag tag-white">${icon('check', 'check')}Exit</span></div><h3 class="h-md">${h}</h3><p>${p}</p></article>`
|
||||||
|
)
|
||||||
|
.join('')}
|
||||||
|
</div>
|
||||||
|
<div class="stats reveal">
|
||||||
|
<div class="stat"><span>EXITS</span><b data-count="4">4</b></div>
|
||||||
|
<div class="stat"><span>INDUSTRIES</span><b data-count="6">6</b></div>
|
||||||
|
<div class="stat"><span>YEARS OPERATING</span><b data-count="8" data-suffix="+">8+</b></div>
|
||||||
|
<div class="stat stat-note">
|
||||||
|
<p>Different businesses have called for different decisions, teams, and ways of thinking. That range still shapes how I approach every opportunity today.</p>
|
||||||
|
${textLink('FOLLOW THE JOURNEY', '/about/')}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="section" id="about" aria-labelledby="about-title">
|
||||||
|
<div class="wrap">
|
||||||
|
<div class="showcase reveal">
|
||||||
|
<div class="stack">
|
||||||
|
${eyebrow('ABOUT DYLAN')}
|
||||||
|
<h2 id="about-title" class="h-display">Curiosity Got Me Started. Ambition Kept Me Moving.</h2>
|
||||||
|
<p class="quote-line">I have always been more interested in what could be possible than what already exists.</p>
|
||||||
|
<div class="prose">
|
||||||
|
<p>That curiosity has taken me into industries I never expected to enter, across markets, teams, and ideas that looked nothing alike from the outside. What connects them is the part I enjoy most: seeing potential early, bringing the right people around it, and giving an idea the chance to become something real.</p>
|
||||||
|
<p>Business is a big part of my story, but it is not the whole story.</p>
|
||||||
|
</div>
|
||||||
|
<div class="btn-row">${btn('GET TO KNOW DYLAN', '/about/')}</div>
|
||||||
|
</div>
|
||||||
|
<div class="visual portrait">
|
||||||
|
<img src="/assets/dylan-portrait.jpg" alt="Dylan Mazzei" width="900" height="900" loading="lazy">
|
||||||
|
<div class="flow" aria-hidden="true">
|
||||||
|
<small>What connects them is the part I enjoy most:</small>
|
||||||
|
<ol><li>seeing potential early</li><li>bringing the right people around it</li><li>giving an idea the chance to become something real</li></ol>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="section" id="consulting" aria-labelledby="consult-title">
|
||||||
|
<div class="wrap">
|
||||||
|
<div class="showcase reverse reveal">
|
||||||
|
<div class="visual panel steps-panel" aria-hidden="true">
|
||||||
|
<div class="panel-bar"><span class="lights"><i></i><i></i><i></i></span><strong>Diagnosis Before Prescription.</strong></div>
|
||||||
|
<ol>
|
||||||
|
<li class="sp-step"><span class="num">1</span><h4>Business Diagnostic</h4></li>
|
||||||
|
<li class="sp-step"><span class="num">2</span><h4>Roadmap Delivery</h4></li>
|
||||||
|
<li class="sp-step"><span class="num">3</span><h4>Execution Sprint or Advisory</h4></li>
|
||||||
|
</ol>
|
||||||
|
</div>
|
||||||
|
<div class="stack">
|
||||||
|
${eyebrow('CONSULT DYLAN')}
|
||||||
|
<h2 id="consult-title" class="h-display">Sometimes You Need Another Founder in the Room.</h2>
|
||||||
|
<p class="quote-line">I know what it is like to make decisions when the answer isn't obvious, and the outcome belongs to you.</p>
|
||||||
|
<div class="prose">
|
||||||
|
<p>That is the perspective I bring when I work with founders. We look closely at the business, talk through what is getting in the way, and figure out where your attention can make the biggest difference.</p>
|
||||||
|
<p>Every engagement starts with a diagnostic. Not because I already know the answer, but because your business deserves one that actually fits.</p>
|
||||||
|
</div>
|
||||||
|
<div class="btn-row">${btn('WORK WITH DYLAN', '/consulting/')}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="section" id="playbook" aria-labelledby="playbook-title">
|
||||||
|
<div class="wrap">
|
||||||
|
<div class="showcase reveal">
|
||||||
|
<div class="stack">
|
||||||
|
${eyebrow('FROM THE NOTEBOOK')}
|
||||||
|
<h2 id="playbook-title" class="h-display">Different Businesses. Different Beginnings. One Playbook.</h2>
|
||||||
|
<p class="body">I’ve started enough businesses to know the beginning matters.</p>
|
||||||
|
<ul class="beats">
|
||||||
|
<li>${icon('arrow')}The early calls.</li>
|
||||||
|
<li>${icon('arrow')}The first customers.</li>
|
||||||
|
<li>${icon('arrow')}The moments when an idea has to become more than an idea.</li>
|
||||||
|
</ul>
|
||||||
|
<p class="body">The Business Launch Playbook puts my approach to those moments on the page, shaped by years of starting, operating, and growing businesses across very different industries.</p>
|
||||||
|
<div class="btn-row">${btn('GET THE PLAYBOOK', SITE.pending)}</div>
|
||||||
|
</div>
|
||||||
|
<div class="visual book-stage">
|
||||||
|
<div class="book" role="img" aria-label="The Business Launch Playbook by Dylan Mazzei">
|
||||||
|
${mark()}
|
||||||
|
<h3>The Business Launch Playbook</h3>
|
||||||
|
<div class="by">Dylan Mazzei</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="section" id="press" aria-label="Press and poetry">
|
||||||
|
<div class="wrap duo reveal">
|
||||||
|
<article class="card card-lg">
|
||||||
|
${eyebrow('PRESS & MEDIA')}
|
||||||
|
<h2 class="h-display">The Work Spoke. Then I Did.</h2>
|
||||||
|
<div class="prose">
|
||||||
|
<p>About the businesses. The exits. The ideas. What worked. What didn’t. And what I’m thinking about next.</p>
|
||||||
|
<p>Some of those conversations made it into interviews, profiles, podcasts, and features.</p>
|
||||||
|
</div>
|
||||||
|
<div class="spacer"></div>
|
||||||
|
<div>${btn('SEE THE FEATURES', '/press/')}</div>
|
||||||
|
</article>
|
||||||
|
<article class="card card-lg card-dark" id="poetry">
|
||||||
|
${eyebrow('A DIFFERENT SIDE')}
|
||||||
|
<h2 class="h-display">And Then There’s Poetry.</h2>
|
||||||
|
<p class="poem"><span>Not every idea of mine becomes a company.</span><span>Some become words.</span></p>
|
||||||
|
<p class="body">Poetry gives me somewhere to put thoughts that don't belong in a business plan, a strategy session, or a boardroom.</p>
|
||||||
|
<div class="spacer"></div>
|
||||||
|
<div>${btn('TURN THE PAGE', SITE.pending, 'ghost-light')}</div>
|
||||||
|
</article>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="section" id="connect" aria-labelledby="connect-title">
|
||||||
|
<div class="wrap">
|
||||||
|
<div class="closing reveal">
|
||||||
|
<div class="closing-inner">
|
||||||
|
${eyebrow('LET’S CONNECT')}
|
||||||
|
<h2 id="connect-title" class="h-display-lg">Interesting Things Usually Start With a Conversation.</h2>
|
||||||
|
<div class="prose">
|
||||||
|
<p>Maybe you have an idea taking shape. A business at an interesting crossroads. A partnership worth exploring. Or simply a question you think I might have a perspective on.</p>
|
||||||
|
<p>I’ve learned to pay attention when an interesting conversation begins. Some of the best opportunities in my life have started exactly that way.</p>
|
||||||
|
<p class="body-ink">If there’s something worth talking about, I’m listening.</p>
|
||||||
|
</div>
|
||||||
|
<div class="btn-row">${btn('START A CONVERSATION', '/contact/')}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
`,
|
||||||
|
};
|
||||||
@@ -0,0 +1,152 @@
|
|||||||
|
import { icon, eyebrow, btn, textLink, paras, faq } from '../layout.mjs';
|
||||||
|
|
||||||
|
const covers = [
|
||||||
|
['search', 'Search & AI Visibility', ['SEO strategy', 'AI search visibility, including LLMO, GEO, and AEO', 'Schema and entity strategy', 'Local and multi-location visibility']],
|
||||||
|
['route', 'Acquisition & Conversion', ['Paid media', 'Social media management', 'Funnel strategy', 'Conversion opportunities']],
|
||||||
|
['chart', 'Measurement & Marketing Operations', ['Analytics setup', 'Channel and attribution review', 'Marketing team evaluation', 'Agency and vendor evaluation']],
|
||||||
|
];
|
||||||
|
|
||||||
|
const who = [
|
||||||
|
['gauge', 'You’re Spending, but the ROI Is Blurry.', ['Budget is moving across channels, but nobody can clearly connect enough of that activity to revenue.', 'Before spending more, we figure out what the current spend is actually doing.']],
|
||||||
|
['search', 'Organic Growth Has Stopped Behaving Like It Used To.', ['Rankings may still matter, but traditional SEO now shares the discovery journey with AI Overviews, answer engines, LLMs, local results, and other surfaces.', 'If the strategy hasn’t changed, the market already has.']],
|
||||||
|
['rocket', 'Paid Media Works Until You Try to Scale It.', ['A channel can perform well and still have a ceiling.', 'When acquisition starts getting more expensive, we look beyond simply increasing the budget and examine the offer, funnel, search presence, channel mix, and what happens after the click.']],
|
||||||
|
];
|
||||||
|
|
||||||
|
const steps = [
|
||||||
|
['Diagnose', ['We audit analytics, search visibility, paid accounts, funnels, current marketing activity, and the teams or vendors responsible for it.', 'We find the leaks before prescribing the fix.']],
|
||||||
|
['Prioritise', ['You get a clear roadmap showing what deserves attention now, what can wait, and where the strongest opportunities sit.', 'Not twenty priorities.', 'The ones that matter.']],
|
||||||
|
['Execute', ['When execution makes sense, we move into a focused 90-day sprint with specialist support from the same operating ecosystem behind my current ventures.', 'Your existing team can stay involved. So can your existing vendors if they’re doing good work.']],
|
||||||
|
];
|
||||||
|
|
||||||
|
const faqs = [
|
||||||
|
['What is AI search visibility, LLMO, GEO, and AEO?', ['These terms describe different approaches to improving how a business, brand, or content appears across AI-generated answers and modern search experiences.', 'The terminology is still evolving. What matters is making your business understandable, credible, and discoverable across the systems people increasingly use to find answers.']],
|
||||||
|
['Do you execute or advise?', ['Both.', 'Some businesses need a roadmap their existing team can execute. Others need hands-on implementation through a 90-day sprint or ongoing support.', 'The diagnostic determines the right approach.']],
|
||||||
|
['Do you work with existing marketing teams?', ['Yes.', 'I’m not interested in replacing a capable team simply to create more work for mine.', 'If your internal team or existing agency is strong, we can design the strategy around making them more effective.']],
|
||||||
|
['What budget size is needed?', ['There isn’t one universal marketing budget that makes an engagement worthwhile.', 'The more important question is whether there is enough opportunity, complexity, or existing spend for the diagnostic to uncover meaningful improvements.']],
|
||||||
|
];
|
||||||
|
|
||||||
|
const surfaces = ['a search result', 'an AI answer', 'an ad', 'a social platform', 'a local listing'];
|
||||||
|
|
||||||
|
export default {
|
||||||
|
path: '/consulting/marketing/',
|
||||||
|
title: 'Marketing Consulting for Founders | Dylan Mazzei',
|
||||||
|
description: 'Marketing consulting for founders covering SEO, AI search, paid media, funnels, analytics, and digital visibility, starting with a diagnostic.',
|
||||||
|
schema: [
|
||||||
|
{ '@context': 'https://schema.org', '@type': 'FAQPage', mainEntity: faqs.map(([q, a]) => ({ '@type': 'Question', name: q, acceptedAnswer: { '@type': 'Answer', text: a.join(' ') } })) },
|
||||||
|
],
|
||||||
|
body: `
|
||||||
|
<section class="page-hero" aria-labelledby="m-hero">
|
||||||
|
<div class="wrap page-hero-grid">
|
||||||
|
<div class="stack anim">
|
||||||
|
<nav class="crumbs" aria-label="Breadcrumb"><a href="/consulting/">Consulting</a>${icon('chev')}<span>Marketing</span></nav>
|
||||||
|
${eyebrow('MARKETING CONSULTING')}
|
||||||
|
<h1 id="m-hero" class="h-display-lg">Marketing Consulting for a Search World That Won’t Sit Still.</h1>
|
||||||
|
<p class="lead">Search changed. Discovery changed. The customer journey changed with it.</p>
|
||||||
|
<div class="prose">
|
||||||
|
<p>I run marketing businesses, so I’m not watching those changes from the sidelines. My teams work inside SEO, AI search, paid media, content, and conversion every day.</p>
|
||||||
|
<p class="body-ink">The goal isn’t to add another marketing tactic.</p>
|
||||||
|
<p>It’s to figure out what is actually earning attention, what is wasting money, and where your next customer is increasingly likely to find you.</p>
|
||||||
|
</div>
|
||||||
|
<div class="btn-row">${btn('BOOK YOUR DIAGNOSTIC', '/contact/')}</div>
|
||||||
|
</div>
|
||||||
|
<div class="panel anim" aria-hidden="true">
|
||||||
|
<div class="panel-bar"><span class="lights"><i></i><i></i><i></i></span><strong>Visibility Is Bigger Than Google Rankings Now.</strong></div>
|
||||||
|
<div style="padding:20px;display:grid;gap:10px">
|
||||||
|
${surfaces.map((s, i) => `<div class="row" style="border:1px solid var(--mist);border-radius:12px;padding:12px 14px"><span class="ico">${icon(['search', 'spark', 'target', 'users', 'pin'][i])}</span><span class="name">${s}</span><span class="status"><span class="dot"></span></span></div>`).join('')}
|
||||||
|
<div class="row" style="border-radius:12px;padding:12px 14px;background:var(--violet);color:var(--porcelain);border:0"><span class="name">your website</span>${icon('arrow', 'check')}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="section" aria-labelledby="covers">
|
||||||
|
<div class="wrap">
|
||||||
|
<div class="sec-head reveal">
|
||||||
|
<div class="stack-sm">${eyebrow('WHAT THIS COVERS')}<h2 id="covers" class="h-display">Visibility Is Bigger Than Google Rankings Now.</h2></div>
|
||||||
|
<div class="prose">
|
||||||
|
<p>People can discover your business through a search result, an AI answer, an ad, a social platform, or a local listing before they ever reach your website.</p>
|
||||||
|
<p class="body-ink">The strategy has to connect those moments.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="covers reveal">
|
||||||
|
${covers.map(([ic, h, items]) => `<article class="cover"><div class="cover-head"><span class="ic">${icon(ic)}</span><h3>${h}</h3></div><ul>${items.map((it) => `<li>${icon('check')}${it}</li>`).join('')}</ul></article>`).join('')}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="section" aria-labelledby="who">
|
||||||
|
<div class="wrap">
|
||||||
|
<div class="sec-head reveal">
|
||||||
|
<div class="stack-sm">${eyebrow('WHO THIS IS FOR')}<h2 id="who" class="h-display">When More Marketing Isn’t Necessarily the Answer.</h2></div>
|
||||||
|
</div>
|
||||||
|
<div class="cards cards-3 reveal">
|
||||||
|
${who.map(([ic, h, p]) => `<article class="card"><span class="ic">${icon(ic)}</span><h3 class="h-sm">${h}</h3><div class="prose">${paras(p)}</div></article>`).join('')}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="section band" aria-labelledby="delivery">
|
||||||
|
<div class="wrap">
|
||||||
|
<div class="sec-head reveal">
|
||||||
|
<div class="stack-sm">${eyebrow('HOW DELIVERY WORKS')}<h2 id="delivery" class="h-display">We Don’t Start With a Channel. We Start With the Business.</h2></div>
|
||||||
|
<div class="prose">
|
||||||
|
<p style="color:var(--porcelain)">Marketing problems have a habit of disguising themselves.</p>
|
||||||
|
<p>Weak conversion can look like a traffic problem. Poor attribution can make a good channel look bad. A visibility problem can begin somewhere entirely different from SEO.</p>
|
||||||
|
<p>That’s why every engagement follows the same diagnostic-first approach behind my consulting work.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="rules">
|
||||||
|
${steps.map(([h, p], i) => `<article class="rule reveal"><span class="index">STEP_0${i + 1}</span><h3>${i + 1}. ${h}</h3><div class="prose">${p.map((t, j) => `<p${j === 0 ? ' class="ink"' : ''}>${t}</p>`).join('')}</div></article>`).join('')}
|
||||||
|
</div>
|
||||||
|
<div class="sec-foot reveal" style="border-color:var(--dark-line);margin-top:48px;border-top:0">
|
||||||
|
<div class="prose"><p>The objective is not to replace people unnecessarily.</p><p class="statement">It’s to make the marketing work better.</p></div>
|
||||||
|
${btn('START WITH THE DIAGNOSTIC', '/contact/', 'light')}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="section" aria-labelledby="why-op">
|
||||||
|
<div class="wrap">
|
||||||
|
<div class="showcase reveal">
|
||||||
|
<div class="stack">
|
||||||
|
${eyebrow('WHY OPERATOR-LED MARKETING')}
|
||||||
|
<h2 id="why-op" class="h-display">I Have to Live With These Strategies Too.</h2>
|
||||||
|
<div class="prose">
|
||||||
|
<p class="body-ink">Marketing advice looks different when your own businesses depend on it.</p>
|
||||||
|
<p>I’ve spent years operating in digital marketing while also being the person on the other side asking whether the leads are good, whether acquisition makes economic sense, and whether the strategy is producing anything the business can actually use.</p>
|
||||||
|
</div>
|
||||||
|
<p><a class="inline-link" href="/portfolio/">You can see the businesses behind that operating experience.</a></p>
|
||||||
|
</div>
|
||||||
|
<div class="stack-sm">
|
||||||
|
<p class="statement">That tension matters.</p>
|
||||||
|
<article class="card card-dark"><h3 class="h-lg">Marketing has to perform outside the marketing report.</h3></article>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="section" aria-labelledby="faq-m">
|
||||||
|
<div class="wrap faq-layout">
|
||||||
|
<div class="stack-sm sticky reveal">${eyebrow('FREQUENTLY ASKED QUESTIONS')}<h2 id="faq-m" class="h-display">Before We Talk Marketing.</h2></div>
|
||||||
|
<div class="reveal">${faq(faqs)}</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="section" aria-labelledby="numbers">
|
||||||
|
<div class="wrap">
|
||||||
|
<div class="closing reveal">
|
||||||
|
<div class="closing-inner">
|
||||||
|
${eyebrow('START WITH THE NUMBERS')}
|
||||||
|
<h2 id="numbers" class="h-display-lg">Before You Spend More, Find Out What’s Working.</h2>
|
||||||
|
<div class="prose">
|
||||||
|
<p>Every engagement begins with the Business Diagnostic because another campaign won’t solve a problem we haven’t identified yet.</p>
|
||||||
|
<p>We’ll look at where your visibility, traffic, leads, and marketing spend are going, then identify what deserves attention first.</p>
|
||||||
|
<p class="body-ink">If there’s a stronger way forward, you’ll know what it is before committing more budget to it.</p>
|
||||||
|
</div>
|
||||||
|
<div class="btn-row">${btn('BOOK YOUR DIAGNOSTIC', '/contact/')}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
`,
|
||||||
|
};
|
||||||
@@ -0,0 +1,127 @@
|
|||||||
|
import { icon, eyebrow, btn, textLink } from '../layout.mjs';
|
||||||
|
|
||||||
|
const ventures = [
|
||||||
|
['AI Growth Media Service', 'AG', 'CEO & Board Member', 'AI-focused marketing and growth company working at the intersection of digital visibility, strategy, and performance.', ['AI Search', 'Digital Visibility', 'Growth Strategy']],
|
||||||
|
['READTYCH', 'RT', 'Chief Marketing Officer, Co-Founder & Board Member', 'Education technology company developing a two-screen Digital Book and connected learning platform designed around how students and educators actually work.', ['EdTech', 'Product Strategy', 'Market Development']],
|
||||||
|
['Growth360Partners', 'G3', 'Chief Executive Officer & Founder', 'Full-service digital marketing agency bringing together search, websites, paid media, social, optimization, and growth strategy.', ['Marketing', 'Search', 'Digital Growth']],
|
||||||
|
['Infinitus Texas', 'IT', 'Partner & Strategic Advisor', 'Strategic partnership focused on brand positioning, marketing direction, and creating stronger foundations for scalable growth.', ['Strategy', 'Positioning', 'Growth']],
|
||||||
|
['Skinny Spiritz', 'SS', 'Chief Executive Officer & Board Member', 'Beverage brand where product, positioning, placement, partnerships, and customer attention all have to work together.', ['Spirits', 'Brand Growth', 'Partnerships']],
|
||||||
|
['Techie Marketing', 'TM', 'Chief Web3 Officer, Co-Founder & Advisor', 'Digital marketing and branding company created around the needs of technology and Web3-focused businesses.', ['Web3', 'Branding', 'Digital Strategy']],
|
||||||
|
['AiGrowth360', 'A3', 'Chief Executive Officer & Founder', 'Performance-driven digital marketing company using AI, analytics, and search strategy to find better ways to create measurable growth.', ['AI', 'Analytics', 'Performance Marketing']],
|
||||||
|
['Gangi Apparel', 'GA', 'Strategic Advisor & Partner', 'Apparel brand focused on fashion, identity, positioning, and creating a brand people can recognize beyond the product itself.', ['Apparel', 'Brand Positioning', 'Consumer']],
|
||||||
|
['meSEO', 'me', 'Founder & Strategic Growth Leader', 'Web application built around AI search, SEO, and the changing ways businesses are discovered online.', ['Software', 'AI Search', 'SEO']],
|
||||||
|
];
|
||||||
|
|
||||||
|
const capabilities = [
|
||||||
|
'SEO Strategy', 'LLMO / AI Search Visibility', 'GEO / Local Expansion', 'Website Development', 'Website Optimization',
|
||||||
|
'Social Media Management', 'Paid Media', 'Brand Development', 'Strategic Partnerships', 'Investor Relations',
|
||||||
|
'Venture Growth', 'Business Development', 'Product Development', 'Fashion Brand Building',
|
||||||
|
];
|
||||||
|
|
||||||
|
const industries = [
|
||||||
|
'Education', 'Technology', 'AI', 'Digital Marketing', 'Beverage', 'Fashion / Apparel', 'Consumer Brands',
|
||||||
|
'Web3', 'Healthcare', 'Business Development', 'Partnerships', 'Investor Relations', 'Software / Web Apps',
|
||||||
|
];
|
||||||
|
|
||||||
|
const half = Math.ceil(capabilities.length / 2);
|
||||||
|
const row = (items) => items.map((c) => `<span class="cap"><i></i>${c}</span>`).join('');
|
||||||
|
const marquee = (items, rev) => `<div class="marquee"><div class="marquee-track${rev ? ' rev' : ''}">${row(items)}<span aria-hidden="true" style="display:contents">${row(items)}</span></div></div>`;
|
||||||
|
|
||||||
|
export default {
|
||||||
|
path: '/portfolio/',
|
||||||
|
title: 'Venture Portfolio & Brands | Dylan Mazzei',
|
||||||
|
description: 'Explore Dylan Mazzei’s portfolio of companies, brands, partnerships, and operating roles across AI, marketing, technology, education, and more.',
|
||||||
|
body: `
|
||||||
|
<section class="page-hero" aria-labelledby="pf-hero">
|
||||||
|
<div class="wrap page-hero-grid">
|
||||||
|
<div class="stack anim">
|
||||||
|
${eyebrow('PORTFOLIO')}
|
||||||
|
<h1 id="pf-hero" class="h-display-lg">Different Companies. Different Roles. Same Responsibility.</h1>
|
||||||
|
<p class="lead">I’ve worked across companies at very different stages, sometimes as founder, sometimes as operator, partner, advisor, or board member.</p>
|
||||||
|
<div class="btn-row">${btn('EXPLORE MY CURRENT VENTURES', '#ventures')}${btn('WORK WITH DYLAN', '/consulting/', 'ghost')}</div>
|
||||||
|
</div>
|
||||||
|
<div class="panel anim" aria-hidden="true">
|
||||||
|
<div class="panel-bar"><span class="lights"><i></i><i></i><i></i></span><strong>The title changes. The expectation doesn’t.</strong></div>
|
||||||
|
<ol class="steps-panel" style="padding:8px 0">
|
||||||
|
<li class="sp-step"><span class="num">1</span><h4>Understand the business.</h4></li>
|
||||||
|
<li class="sp-step"><span class="num">2</span><h4>Know where I can make a difference.</h4></li>
|
||||||
|
<li class="sp-step"><span class="num">3</span><h4>Then be accountable for what happens next.</h4></li>
|
||||||
|
</ol>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p class="sr-only">The title changes. The expectation doesn’t. Understand the business. Know where I can make a difference. Then be accountable for what happens next.</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="section" id="ventures" aria-labelledby="vb">
|
||||||
|
<div class="wrap">
|
||||||
|
<div class="sec-head reveal">
|
||||||
|
<div class="stack-sm">${eyebrow('FOUNDER-LED. OPERATOR-DRIVEN. ALWAYS CLOSE TO THE WORK.')}<h2 id="vb" class="h-display">Ventures & Brands</h2></div>
|
||||||
|
<p class="body">Different industries have asked different things of me. That range is part of the point.</p>
|
||||||
|
</div>
|
||||||
|
<div class="ventures reveal">
|
||||||
|
${ventures
|
||||||
|
.map(
|
||||||
|
([name, mono, role, desc, focus]) => `<article class="venture">
|
||||||
|
<div class="venture-head"><span class="mono" aria-hidden="true">${mono}</span></div>
|
||||||
|
<div class="stack-xs"><h3>${name}</h3><p class="vrole">${role}</p></div>
|
||||||
|
<p>${desc}</p>
|
||||||
|
<div class="focus"><small>FOCUS:</small><div class="chips">${focus.map((f) => `<span class="tag">${f}</span>`).join('')}</div></div>
|
||||||
|
</article>`
|
||||||
|
)
|
||||||
|
.join('')}
|
||||||
|
</div>
|
||||||
|
<div class="sec-foot reveal" style="justify-content:flex-end">${textLink('SEE HOW I THINK AS AN OPERATOR', '/about/')}</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="section band" aria-labelledby="caps">
|
||||||
|
<div class="wrap">
|
||||||
|
<div class="sec-head reveal">
|
||||||
|
<div class="stack-sm">${eyebrow('CORE CAPABILITIES')}<h2 id="caps" class="h-display">What I Keep Getting Pulled Into.</h2></div>
|
||||||
|
<p class="body">Different companies. Different problems. Certain kinds of work keep finding their way back to my desk.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="stack-sm reveal">
|
||||||
|
${marquee(capabilities.slice(0, half))}
|
||||||
|
${marquee(capabilities.slice(half), true)}
|
||||||
|
</div>
|
||||||
|
<div class="wrap">
|
||||||
|
<div class="sec-foot reveal" style="border-color:var(--dark-line);margin-top:48px">
|
||||||
|
<p style="color:var(--ash)">The operating experience behind these capabilities also shapes my consulting work with founders.</p>
|
||||||
|
${btn('WORK WITH DYLAN', '/consulting/', 'light')}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="section" aria-labelledby="ind">
|
||||||
|
<div class="wrap">
|
||||||
|
<div class="sec-head reveal">
|
||||||
|
<div class="stack-sm">${eyebrow('INDUSTRIES & SECTORS')}<h2 id="ind" class="h-display">I Never Saw Much Value in Staying in One Lane.</h2></div>
|
||||||
|
<p class="body">Moving between industries keeps me from assuming the last answer will work on the next problem.</p>
|
||||||
|
</div>
|
||||||
|
<div class="industries reveal">
|
||||||
|
${industries.map((n, i) => `<div class="industry"><span class="index">${String(i + 1).padStart(2, '0')}</span><b>${n}</b></div>`).join('')}
|
||||||
|
<a class="industry industry-note" href="/about/"><p>That range has also included businesses that went through successful exits. You can read more about the journey behind the portfolio.</p>${icon('arrow', 'check')}</a>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="section" aria-labelledby="next">
|
||||||
|
<div class="wrap">
|
||||||
|
<div class="closing reveal">
|
||||||
|
<div class="closing-inner">
|
||||||
|
${eyebrow('WHAT’S NEXT')}
|
||||||
|
<h2 id="next" class="h-display-lg">The Portfolio Is Still Moving.</h2>
|
||||||
|
<div class="prose">
|
||||||
|
<p>Some of these businesses are growing. Others are changing. New ideas are already competing for attention.</p>
|
||||||
|
<p>If you want to see what I’m actively operating today, start with my current ventures.</p>
|
||||||
|
<p class="body-ink">If you have a business, partnership, or opportunity worth putting on the table, I’m open to the conversation.</p>
|
||||||
|
</div>
|
||||||
|
<div class="btn-row">${btn('EXPLORE MY VENTURES', '#ventures', 'ghost')}${btn('START A CONVERSATION', '/contact/')}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
`,
|
||||||
|
};
|
||||||
@@ -0,0 +1,94 @@
|
|||||||
|
import { icon, eyebrow, btn, textLink, SITE } from '../layout.mjs';
|
||||||
|
|
||||||
|
// TODO(content): the source document asks for the exact published Gulf Magazine
|
||||||
|
// headline. Replace FEATURE.headline (and add FEATURE.url) once it is confirmed.
|
||||||
|
const FEATURE = {
|
||||||
|
outlet: 'GULF MAGAZINE • FEATURE ARTICLE',
|
||||||
|
headline: 'Inside Dylan Mazzei’s High-Stakes',
|
||||||
|
url: null,
|
||||||
|
};
|
||||||
|
|
||||||
|
const topics = [
|
||||||
|
['rocket', 'ENTREPRENEURSHIP', 'Starting, operating, growing, and exiting companies.'],
|
||||||
|
['search', 'AI & SEARCH', 'How AI is changing visibility, marketing, software, and discovery.'],
|
||||||
|
['target', 'LEADERSHIP', 'Teams, decisions, accountability, and what happens after the strategy meeting.'],
|
||||||
|
['layers', 'BUILDING ACROSS INDUSTRIES', 'What changes between markets, and what surprisingly doesn’t.'],
|
||||||
|
];
|
||||||
|
|
||||||
|
export default {
|
||||||
|
path: '/press/',
|
||||||
|
title: 'Press, Media & Interviews | Dylan Mazzei',
|
||||||
|
description: 'Explore press and media featuring Dylan Mazzei on entrepreneurship, business growth, AI, leadership, and operating companies across industries.',
|
||||||
|
body: `
|
||||||
|
<section class="page-hero" aria-labelledby="pr-hero">
|
||||||
|
<div class="wrap page-hero-grid">
|
||||||
|
<div class="stack anim">
|
||||||
|
${eyebrow('PRESS & MEDIA')}
|
||||||
|
<h1 id="pr-hero" class="h-display-lg">Some Questions Are Better Answered From Experience.</h1>
|
||||||
|
<p class="lead">I spend most of my time inside businesses, not talking about them.</p>
|
||||||
|
<div class="prose"><p>But when there’s something useful to add, I’m happy to talk about the decisions, industries, ideas, and changes I’m seeing from the operator’s side of the table.</p></div>
|
||||||
|
<div class="btn-row">${btn('ABOUT DYLAN', '/about/', 'ghost')}</div>
|
||||||
|
</div>
|
||||||
|
<div class="panel profile anim" style="position:relative;top:auto;left:auto;max-width:360px;justify-self:end;width:100%">
|
||||||
|
<img src="/assets/dylan-portrait.jpg" alt="Dylan Mazzei" width="900" height="900">
|
||||||
|
<div class="profile-meta">
|
||||||
|
<strong>Dylan Mazzei</strong>
|
||||||
|
<span class="prole">FOUNDER & OPERATOR</span>
|
||||||
|
<a class="btn btn-primary btn-sm btn-block" href="mailto:${SITE.pressEmail}">${SITE.pressEmail}</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="section" aria-labelledby="featured">
|
||||||
|
<div class="wrap">
|
||||||
|
<div class="sec-head reveal">
|
||||||
|
<div class="stack-sm">${eyebrow('FEATURED PRESS')}<h2 id="featured" class="h-display">From the Other Side of the Interview.</h2></div>
|
||||||
|
</div>
|
||||||
|
<article class="feature-press reveal">
|
||||||
|
<div class="fp-visual" aria-hidden="true">
|
||||||
|
<div class="magazine">
|
||||||
|
<img src="/assets/dylan-portrait.jpg" alt="" width="900" height="900" loading="lazy">
|
||||||
|
<span class="mast">GULF</span>
|
||||||
|
<span class="cover-line">${FEATURE.headline}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="fp-copy">
|
||||||
|
<span class="meta">${FEATURE.outlet}</span>
|
||||||
|
<h3>${FEATURE.headline}</h3>
|
||||||
|
${FEATURE.url ? `<div>${btn('READ THE FEATURE', FEATURE.url, 'light')}</div>` : ''}
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="section" aria-labelledby="speak">
|
||||||
|
<div class="wrap">
|
||||||
|
<div class="sec-head reveal">
|
||||||
|
<div class="stack-sm">${eyebrow('WHAT I CAN SPEAK TO')}<h2 id="speak" class="h-display">Ask Me About Something I Actually Work On.</h2></div>
|
||||||
|
</div>
|
||||||
|
<div class="topics reveal">
|
||||||
|
${topics.map(([ic, h, p]) => `<article class="topic"><span class="ic">${icon(ic)}</span><h3>${h}</h3><p>${p}</p></article>`).join('')}
|
||||||
|
</div>
|
||||||
|
<div class="sec-foot reveal" style="justify-content:flex-end;border-top:0">${textLink('EXPLORE MY VENTURES', '/portfolio/')}</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="section" aria-labelledby="media">
|
||||||
|
<div class="wrap">
|
||||||
|
<div class="closing closing-dark reveal">
|
||||||
|
<div class="closing-inner">
|
||||||
|
${eyebrow('MEDIA INQUIRIES')}
|
||||||
|
<h2 id="media" class="h-display-lg">Have a Question Worth Asking?</h2>
|
||||||
|
<div class="prose">
|
||||||
|
<p>For interviews, speaking engagements, podcasts, expert commentary, or press materials, contact the PR team.</p>
|
||||||
|
<p>Share the topic, format, publication or platform, and deadline so we can get you what you need.</p>
|
||||||
|
</div>
|
||||||
|
<p class="statement" style="display:flex;gap:12px;align-items:center;flex-wrap:wrap;justify-content:center">${SITE.pressEmail}<button class="copy-btn" type="button" data-copy="${SITE.pressEmail}">Copy</button></p>
|
||||||
|
<div class="btn-row">${btn('CONTACT THE PR TEAM', 'mailto:' + SITE.pressEmail)}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
`,
|
||||||
|
};
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 252 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 429 KiB |
@@ -0,0 +1,123 @@
|
|||||||
|
(function () {
|
||||||
|
window.__site = true;
|
||||||
|
var root = document.documentElement;
|
||||||
|
var reduce = window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches;
|
||||||
|
|
||||||
|
// Nav border on scroll
|
||||||
|
var nav = document.getElementById('nav');
|
||||||
|
var onScroll = function () { nav && nav.classList.toggle('is-scrolled', window.scrollY > 8); };
|
||||||
|
onScroll();
|
||||||
|
window.addEventListener('scroll', onScroll, { passive: true });
|
||||||
|
|
||||||
|
// Mobile menu
|
||||||
|
var menuBtn = document.getElementById('menu-btn');
|
||||||
|
var menu = document.getElementById('mobile-menu');
|
||||||
|
if (menuBtn && menu) {
|
||||||
|
menuBtn.addEventListener('click', function () {
|
||||||
|
var open = menu.hidden;
|
||||||
|
menu.hidden = !open;
|
||||||
|
menuBtn.setAttribute('aria-expanded', String(open));
|
||||||
|
menuBtn.setAttribute('aria-label', open ? 'Close menu' : 'Open menu');
|
||||||
|
});
|
||||||
|
document.addEventListener('keydown', function (e) {
|
||||||
|
if (e.key === 'Escape' && !menu.hidden) { menu.hidden = true; menuBtn.setAttribute('aria-expanded', 'false'); menuBtn.focus(); }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reveal on scroll
|
||||||
|
var reveals = document.querySelectorAll('.reveal');
|
||||||
|
if ('IntersectionObserver' in window && !reduce) {
|
||||||
|
var io = new IntersectionObserver(function (entries) {
|
||||||
|
entries.forEach(function (en) {
|
||||||
|
if (en.isIntersecting) { en.target.classList.add('is-in'); io.unobserve(en.target); }
|
||||||
|
});
|
||||||
|
}, { rootMargin: '0px 0px -8% 0px', threshold: 0.05 });
|
||||||
|
reveals.forEach(function (el) { io.observe(el); });
|
||||||
|
} else {
|
||||||
|
reveals.forEach(function (el) { el.classList.add('is-in'); });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Count-up numbers: <b data-count="8" data-suffix="+">8+</b>
|
||||||
|
var counters = document.querySelectorAll('[data-count]');
|
||||||
|
var run = function (el) {
|
||||||
|
var end = parseInt(el.getAttribute('data-count'), 10);
|
||||||
|
var suffix = el.getAttribute('data-suffix') || '';
|
||||||
|
var start = null;
|
||||||
|
var dur = 1200;
|
||||||
|
var step = function (t) {
|
||||||
|
if (!start) start = t;
|
||||||
|
var p = Math.min((t - start) / dur, 1);
|
||||||
|
var eased = 1 - Math.pow(1 - p, 3);
|
||||||
|
el.textContent = Math.round(end * eased) + suffix;
|
||||||
|
if (p < 1) requestAnimationFrame(step);
|
||||||
|
};
|
||||||
|
requestAnimationFrame(step);
|
||||||
|
};
|
||||||
|
if ('IntersectionObserver' in window && !reduce) {
|
||||||
|
var co = new IntersectionObserver(function (entries) {
|
||||||
|
entries.forEach(function (en) { if (en.isIntersecting) { run(en.target); co.unobserve(en.target); } });
|
||||||
|
}, { threshold: 0.6 });
|
||||||
|
counters.forEach(function (el) { co.observe(el); });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tabs (service lines)
|
||||||
|
document.querySelectorAll('[data-tabs]').forEach(function (wrap) {
|
||||||
|
var btns = wrap.querySelectorAll('[role="tab"]');
|
||||||
|
var panels = wrap.querySelectorAll('[role="tabpanel"]');
|
||||||
|
var select = function (i, focus) {
|
||||||
|
btns.forEach(function (b, j) {
|
||||||
|
var on = i === j;
|
||||||
|
b.setAttribute('aria-selected', String(on));
|
||||||
|
b.tabIndex = on ? 0 : -1;
|
||||||
|
panels[j].hidden = !on;
|
||||||
|
});
|
||||||
|
if (focus) btns[i].focus();
|
||||||
|
};
|
||||||
|
btns.forEach(function (b, i) {
|
||||||
|
b.addEventListener('click', function () { select(i); });
|
||||||
|
b.addEventListener('keydown', function (e) {
|
||||||
|
var k = e.key;
|
||||||
|
if (k === 'ArrowDown' || k === 'ArrowRight') { e.preventDefault(); select((i + 1) % btns.length, true); }
|
||||||
|
if (k === 'ArrowUp' || k === 'ArrowLeft') { e.preventDefault(); select((i - 1 + btns.length) % btns.length, true); }
|
||||||
|
});
|
||||||
|
});
|
||||||
|
var hash = location.hash.replace('#', '');
|
||||||
|
var start = 0;
|
||||||
|
panels.forEach(function (p, j) { if (p.id === hash) start = j; });
|
||||||
|
select(start);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Copy buttons
|
||||||
|
document.querySelectorAll('[data-copy]').forEach(function (b) {
|
||||||
|
b.addEventListener('click', function () {
|
||||||
|
var text = b.getAttribute('data-copy');
|
||||||
|
var label = b.textContent;
|
||||||
|
var done = function () { b.textContent = 'Copied'; setTimeout(function () { b.textContent = label; }, 1600); };
|
||||||
|
try { navigator.clipboard.writeText(text).then(done, function () {}); } catch (e) {}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Inquiry form: opens the visitor's email client with the message prefilled.
|
||||||
|
var form = document.getElementById('inquiry');
|
||||||
|
if (form) {
|
||||||
|
form.addEventListener('submit', function (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
if (!form.reportValidity()) return;
|
||||||
|
var d = new FormData(form);
|
||||||
|
var body = [
|
||||||
|
'Name: ' + d.get('name'),
|
||||||
|
'Email: ' + d.get('email'),
|
||||||
|
d.get('company') ? 'Company: ' + d.get('company') : '',
|
||||||
|
d.get('topic') ? 'Topic: ' + d.get('topic') : '',
|
||||||
|
'',
|
||||||
|
d.get('message')
|
||||||
|
].filter(function (l, i) { return l !== '' || i === 4; }).join('\n');
|
||||||
|
var subject = 'Inquiry from ' + d.get('name') + (d.get('topic') ? ' — ' + d.get('topic') : '');
|
||||||
|
window.location.href = 'mailto:' + form.getAttribute('data-to') + '?subject=' + encodeURIComponent(subject) + '&body=' + encodeURIComponent(body);
|
||||||
|
var status = document.getElementById('form-status');
|
||||||
|
if (status) status.textContent = 'Your email app should open with the message ready to send.';
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
root.classList.add('ready');
|
||||||
|
})();
|
||||||
@@ -0,0 +1,796 @@
|
|||||||
|
/* Dylan Mazzei — "Ivory Terminal"
|
||||||
|
White canvas, charcoal type, one violet for every deliberate action.
|
||||||
|
Layered product-style mockups carry the visuals; dark Inkstone bands mark the
|
||||||
|
moments where Dylan talks about how he operates. */
|
||||||
|
:root {
|
||||||
|
--violet: #594ff4;
|
||||||
|
--violet-press: #4a40e6;
|
||||||
|
--violet-soft: #eeedfe;
|
||||||
|
--violet-glow: rgba(89, 79, 244, 0.35);
|
||||||
|
--ink: #1f1f1f;
|
||||||
|
--graphite: #333333;
|
||||||
|
--slate: #5d5d5d;
|
||||||
|
--smoke: #888888;
|
||||||
|
--ash: #b0b0b0;
|
||||||
|
--mist: #e7e7e7;
|
||||||
|
--cloud: #f6f6f6;
|
||||||
|
--porcelain: #ffffff;
|
||||||
|
--obsidian: #000000;
|
||||||
|
--signal-green: #1aab8b;
|
||||||
|
--dark-line: #2e2e2e;
|
||||||
|
--dark-muted: #9a9a9a;
|
||||||
|
--code-key: #c9c6ff;
|
||||||
|
--code-str: #6fd6bd;
|
||||||
|
--code-num: #ffb38a;
|
||||||
|
--code-dim: #8a8a8a;
|
||||||
|
|
||||||
|
--font-sans: "Inter", "DM Sans", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
|
||||||
|
--font-mono: "JetBrains Mono", ui-monospace, "SF Mono", Menlo, Consolas, monospace;
|
||||||
|
|
||||||
|
--text-caption: 14px;
|
||||||
|
--text-body: 16px;
|
||||||
|
--text-lead: 18px;
|
||||||
|
--text-heading-sm: 20px;
|
||||||
|
--text-heading: 26px;
|
||||||
|
--text-heading-lg: clamp(28px, 3.2vw, 36px);
|
||||||
|
--text-display: clamp(36px, 5.2vw, 56px);
|
||||||
|
--text-display-lg: clamp(42px, 7vw, 72px);
|
||||||
|
--tracking-eyebrow: 0.075em;
|
||||||
|
|
||||||
|
--radius-pill: 99px;
|
||||||
|
--radius-card: 36px;
|
||||||
|
--radius-panel: 16px;
|
||||||
|
--radius-img: 10px;
|
||||||
|
--shadow-float: rgba(0, 0, 0, 0.12) 0px 0px 60px -13px;
|
||||||
|
|
||||||
|
--page-max: 1200px;
|
||||||
|
--gutter: 24px;
|
||||||
|
--section-y: 112px;
|
||||||
|
--card-pad: 32px;
|
||||||
|
--gap: 24px;
|
||||||
|
--nav-h: 72px;
|
||||||
|
color-scheme: light;
|
||||||
|
}
|
||||||
|
|
||||||
|
*, *::before, *::after { box-sizing: border-box; }
|
||||||
|
html { scroll-behavior: smooth; scroll-padding-top: calc(var(--nav-h) + 24px); -webkit-text-size-adjust: 100%; }
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
background: var(--porcelain);
|
||||||
|
color: var(--ink);
|
||||||
|
font-family: var(--font-sans);
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: var(--text-body);
|
||||||
|
line-height: 1.55;
|
||||||
|
font-feature-settings: "ss01" on, "cv11" on;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
text-rendering: optimizeLegibility;
|
||||||
|
overflow-x: hidden;
|
||||||
|
}
|
||||||
|
img { max-width: 100%; height: auto; display: block; }
|
||||||
|
a { color: inherit; text-decoration: none; }
|
||||||
|
h1, h2, h3, h4, p, ul, ol, figure, blockquote { margin: 0; }
|
||||||
|
ul, ol { padding: 0; list-style: none; }
|
||||||
|
h1, h2, h3, h4 { font-weight: 700; text-wrap: balance; color: var(--ink); }
|
||||||
|
p { text-wrap: pretty; }
|
||||||
|
::selection { background: var(--violet); color: var(--porcelain); }
|
||||||
|
:focus-visible { outline: 2px solid var(--violet); outline-offset: 3px; border-radius: 6px; }
|
||||||
|
.skip { position: absolute; left: 16px; top: -60px; z-index: 100; background: var(--violet); color: var(--porcelain); padding: 10px 18px; border-radius: var(--radius-pill); }
|
||||||
|
.skip:focus { top: 12px; }
|
||||||
|
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
|
||||||
|
|
||||||
|
.wrap { max-width: var(--page-max); margin: 0 auto; padding-inline: var(--gutter); }
|
||||||
|
.wrap-narrow { max-width: 860px; margin: 0 auto; padding-inline: var(--gutter); }
|
||||||
|
.section { padding-block: var(--section-y); }
|
||||||
|
.section-tight { padding-block: calc(var(--section-y) * 0.6); }
|
||||||
|
.section + .section:not(.band) { padding-top: 0; }
|
||||||
|
|
||||||
|
/* ---------- Type ---------- */
|
||||||
|
.eyebrow {
|
||||||
|
display: inline-flex; align-items: center; gap: 10px;
|
||||||
|
font-size: 13px; font-weight: 500; letter-spacing: var(--tracking-eyebrow);
|
||||||
|
text-transform: uppercase; color: var(--smoke); line-height: 1.4;
|
||||||
|
}
|
||||||
|
.eyebrow::before { content: ""; width: 6px; height: 6px; border-radius: 2px; background: var(--violet); flex: none; }
|
||||||
|
.h-display-lg { font-size: var(--text-display-lg); line-height: 1.03; letter-spacing: -0.04em; }
|
||||||
|
.h-display { font-size: var(--text-display); line-height: 1.07; letter-spacing: -0.032em; }
|
||||||
|
.h-lg { font-size: var(--text-heading-lg); line-height: 1.15; letter-spacing: -0.022em; }
|
||||||
|
.h-md { font-size: var(--text-heading); line-height: 1.2; letter-spacing: -0.016em; }
|
||||||
|
.h-sm { font-size: var(--text-heading-sm); line-height: 1.33; letter-spacing: -0.01em; }
|
||||||
|
.lead { font-size: var(--text-lead); line-height: 1.6; color: var(--slate); }
|
||||||
|
.body { color: var(--slate); max-width: 62ch; }
|
||||||
|
.body-ink { color: var(--ink); }
|
||||||
|
.statement { font-size: clamp(22px, 2.6vw, 30px); line-height: 1.3; letter-spacing: -0.02em; color: var(--ink); font-weight: 500; }
|
||||||
|
.statement em { font-style: normal; color: var(--smoke); }
|
||||||
|
.prose { display: flex; flex-direction: column; gap: 16px; }
|
||||||
|
.prose p { color: var(--slate); max-width: 62ch; }
|
||||||
|
.stack { display: flex; flex-direction: column; gap: var(--gap); }
|
||||||
|
.stack-sm { display: flex; flex-direction: column; gap: 16px; }
|
||||||
|
.stack-xs { display: flex; flex-direction: column; gap: 8px; }
|
||||||
|
.center { text-align: center; align-items: center; }
|
||||||
|
.center .body, .center .prose p { margin-inline: auto; }
|
||||||
|
|
||||||
|
/* ---------- Buttons ---------- */
|
||||||
|
.btn {
|
||||||
|
display: inline-flex; align-items: center; justify-content: center; gap: 12px;
|
||||||
|
min-height: 50px; padding: 14px 28px; border-radius: var(--radius-pill);
|
||||||
|
font: 700 13px/1 var(--font-sans); letter-spacing: 0.08em; text-transform: uppercase; white-space: nowrap;
|
||||||
|
border: 1.5px solid transparent; cursor: pointer;
|
||||||
|
transition: background-color .18s ease, color .18s ease, border-color .18s ease, box-shadow .25s ease, transform .18s ease;
|
||||||
|
}
|
||||||
|
.btn svg { width: 16px; height: 16px; flex: none; transition: transform .18s ease; }
|
||||||
|
.btn:hover svg { transform: translateX(3px); }
|
||||||
|
.btn:active { transform: translateY(1px); }
|
||||||
|
.btn-primary { background: var(--violet); color: var(--porcelain); }
|
||||||
|
.btn-primary:hover { background: var(--violet-press); box-shadow: 0 10px 30px -10px var(--violet-glow); }
|
||||||
|
.btn-ghost { background: transparent; color: var(--violet); border-color: var(--violet); }
|
||||||
|
.btn-ghost:hover { background: var(--violet-soft); }
|
||||||
|
.btn-light { background: var(--porcelain); color: var(--ink); }
|
||||||
|
.btn-light:hover { background: var(--mist); }
|
||||||
|
.btn-ghost-light { background: transparent; color: var(--porcelain); border-color: rgba(255, 255, 255, .35); }
|
||||||
|
.btn-ghost-light:hover { background: rgba(255, 255, 255, .08); border-color: var(--porcelain); }
|
||||||
|
.btn-sm { min-height: 42px; padding: 11px 20px; font-size: 12px; }
|
||||||
|
.btn-block { width: 100%; }
|
||||||
|
.btn-row { display: flex; flex-wrap: wrap; gap: 12px; }
|
||||||
|
.center .btn-row { justify-content: center; }
|
||||||
|
|
||||||
|
.text-link { display: inline-flex; align-items: center; gap: 10px; color: var(--violet); font: 700 13px/1.2 var(--font-sans); letter-spacing: 0.08em; text-transform: uppercase; }
|
||||||
|
.text-link svg { width: 16px; height: 16px; transition: transform .18s ease; }
|
||||||
|
.text-link:hover svg { transform: translateX(3px); }
|
||||||
|
|
||||||
|
/* ---------- Tags ---------- */
|
||||||
|
.tag {
|
||||||
|
display: inline-flex; align-items: center; gap: 6px;
|
||||||
|
padding: 5px 12px; border-radius: var(--radius-pill);
|
||||||
|
font-size: 13px; font-weight: 500; line-height: 1.4;
|
||||||
|
background: var(--cloud); color: var(--ink); white-space: nowrap;
|
||||||
|
}
|
||||||
|
.tag-white { background: var(--porcelain); }
|
||||||
|
.tag-line { background: transparent; border: 1px solid var(--mist); }
|
||||||
|
.tag-violet { background: var(--violet); color: var(--porcelain); }
|
||||||
|
.tag-upper { text-transform: uppercase; letter-spacing: var(--tracking-eyebrow); font-size: 12px; }
|
||||||
|
.tag-dark { background: #2a2a2a; color: var(--porcelain); }
|
||||||
|
.chips { display: flex; flex-wrap: wrap; gap: 8px; }
|
||||||
|
.dot { width: 6px; height: 6px; border-radius: 50%; background: var(--signal-green); flex: none; box-shadow: 0 0 0 3px rgba(26, 171, 139, .15); }
|
||||||
|
|
||||||
|
/* ---------- Navigation ---------- */
|
||||||
|
.nav {
|
||||||
|
position: sticky; top: env(safe-area-inset-top, 0px); z-index: 50;
|
||||||
|
background: rgba(255, 255, 255, 0.86);
|
||||||
|
backdrop-filter: saturate(180%) blur(16px); -webkit-backdrop-filter: saturate(180%) blur(16px);
|
||||||
|
border-bottom: 1px solid transparent; transition: border-color .2s ease;
|
||||||
|
}
|
||||||
|
.nav.is-scrolled { border-bottom-color: var(--mist); }
|
||||||
|
.nav-inner { height: var(--nav-h); display: flex; align-items: center; justify-content: space-between; gap: 24px; }
|
||||||
|
.brand { display: inline-flex; align-items: center; gap: 12px; flex: none; }
|
||||||
|
.brand-mark { width: 34px; height: 34px; flex: none; }
|
||||||
|
.brand-word { font-size: 14px; font-weight: 700; letter-spacing: 0.12em; text-transform: uppercase; }
|
||||||
|
.nav-links { display: flex; align-items: center; gap: 2px; }
|
||||||
|
.nav-links > li { position: relative; }
|
||||||
|
.nav-links a, .nav-links button {
|
||||||
|
display: inline-flex; align-items: center; gap: 6px; padding: 9px 14px; border-radius: var(--radius-pill);
|
||||||
|
font: 500 15px/1.2 var(--font-sans); color: var(--graphite); background: none; border: 0; cursor: pointer;
|
||||||
|
transition: background-color .15s ease, color .15s ease;
|
||||||
|
}
|
||||||
|
.nav-links a:hover, .nav-links button:hover, .nav-links li:focus-within > button { background: var(--cloud); color: var(--ink); }
|
||||||
|
.nav-links a[aria-current="page"], .nav-links .is-active > button { color: var(--violet); }
|
||||||
|
.nav-links .chev { width: 12px; height: 12px; transition: transform .2s ease; }
|
||||||
|
.dropdown {
|
||||||
|
position: absolute; top: calc(100% + 10px); left: 50%; translate: -50% 0; min-width: 300px;
|
||||||
|
background: var(--porcelain); border: 1px solid var(--mist); border-radius: 20px; box-shadow: var(--shadow-float);
|
||||||
|
padding: 8px; display: grid; gap: 2px;
|
||||||
|
opacity: 0; visibility: hidden; transform: translateY(-6px); transition: opacity .18s ease, transform .18s ease, visibility .18s;
|
||||||
|
}
|
||||||
|
.dropdown::before { content: ""; position: absolute; inset: -12px 0 auto; height: 12px; }
|
||||||
|
.has-drop:hover .dropdown, .has-drop:focus-within .dropdown { opacity: 1; visibility: visible; transform: none; }
|
||||||
|
.has-drop:hover .chev, .has-drop:focus-within .chev { transform: rotate(180deg); }
|
||||||
|
.dropdown a { display: grid; grid-template-columns: 36px 1fr; gap: 12px; align-items: center; padding: 10px 12px; border-radius: 14px; }
|
||||||
|
.dropdown a:hover { background: var(--cloud); }
|
||||||
|
.dropdown .di { width: 36px; height: 36px; border-radius: 10px; background: var(--violet-soft); color: var(--violet); display: grid; place-items: center; }
|
||||||
|
.dropdown .di svg { width: 18px; height: 18px; }
|
||||||
|
.dropdown strong { display: block; font-size: 14px; color: var(--ink); }
|
||||||
|
.dropdown small { display: block; font-size: 12.5px; color: var(--smoke); line-height: 1.35; }
|
||||||
|
.nav-cta { display: flex; align-items: center; gap: 8px; }
|
||||||
|
.menu-btn {
|
||||||
|
display: none; width: 44px; height: 44px; border-radius: 50%; border: 1px solid var(--mist);
|
||||||
|
background: var(--porcelain); color: var(--ink); align-items: center; justify-content: center; cursor: pointer;
|
||||||
|
}
|
||||||
|
.menu-btn svg { width: 18px; height: 18px; }
|
||||||
|
.mobile-menu { border-top: 1px solid var(--mist); padding-block: 8px 24px; max-height: calc(100dvh - var(--nav-h)); overflow-y: auto; }
|
||||||
|
.mobile-menu a { display: flex; justify-content: space-between; align-items: center; padding: 14px 2px; font-size: 18px; border-bottom: 1px solid var(--cloud); }
|
||||||
|
.mobile-menu .sub a { padding-left: 18px; font-size: 16px; color: var(--slate); }
|
||||||
|
.mobile-menu .btn { margin-top: 20px; width: 100%; border-bottom: 0; font-size: 13px; justify-content: center; }
|
||||||
|
|
||||||
|
/* ---------- Page hero (inner pages) ---------- */
|
||||||
|
.page-hero { padding-block: 88px 96px; position: relative; overflow: hidden; }
|
||||||
|
.page-hero::before {
|
||||||
|
content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
|
||||||
|
background-image: linear-gradient(var(--mist) 1px, transparent 1px), linear-gradient(90deg, var(--mist) 1px, transparent 1px);
|
||||||
|
background-size: 56px 56px; background-position: center top;
|
||||||
|
mask-image: radial-gradient(ellipse 70% 60% at 70% 0%, #000 0%, transparent 70%);
|
||||||
|
-webkit-mask-image: radial-gradient(ellipse 70% 60% at 70% 0%, #000 0%, transparent 70%);
|
||||||
|
opacity: .7;
|
||||||
|
}
|
||||||
|
.page-hero-grid { display: grid; grid-template-columns: 1.15fr 0.85fr; gap: 64px; align-items: center; }
|
||||||
|
.page-hero-grid > * { min-width: 0; }
|
||||||
|
.page-hero .stack { gap: 28px; }
|
||||||
|
.crumbs { display: flex; gap: 8px; align-items: center; font-size: 13px; color: var(--smoke); }
|
||||||
|
.crumbs a:hover { color: var(--violet); }
|
||||||
|
.crumbs svg { width: 12px; height: 12px; }
|
||||||
|
|
||||||
|
/* ---------- Floating panels / mockups ---------- */
|
||||||
|
.panel {
|
||||||
|
background: var(--porcelain); border-radius: var(--radius-panel);
|
||||||
|
box-shadow: var(--shadow-float); border: 1px solid var(--mist); overflow: hidden;
|
||||||
|
}
|
||||||
|
.panel-bar {
|
||||||
|
display: flex; align-items: center; gap: 12px; height: 44px; padding: 0 16px;
|
||||||
|
border-bottom: 1px solid var(--mist); font-size: 13px; color: var(--slate);
|
||||||
|
}
|
||||||
|
.panel-bar strong { color: var(--ink); font-size: 13.5px; }
|
||||||
|
.lights { display: flex; gap: 6px; }
|
||||||
|
.lights i { width: 10px; height: 10px; border-radius: 50%; background: var(--mist); }
|
||||||
|
.panel-url { margin-left: auto; padding: 4px 12px; border-radius: var(--radius-pill); background: var(--cloud); font-size: 12px; color: var(--smoke); }
|
||||||
|
.panel-dark { background: var(--ink); border-color: var(--ink); color: var(--porcelain); }
|
||||||
|
.panel-dark .panel-bar { border-bottom-color: var(--dark-line); color: var(--ash); }
|
||||||
|
.panel-dark .lights i { background: #3a3a3a; }
|
||||||
|
.file { display: inline-flex; align-items: center; gap: 8px; font-family: var(--font-mono); font-size: 12px; color: var(--porcelain); }
|
||||||
|
.file svg { width: 14px; height: 14px; color: var(--code-key); }
|
||||||
|
.code-pre {
|
||||||
|
margin: 0; padding: 18px 20px 22px; font: 500 12.5px/1.75 var(--font-mono); color: var(--porcelain);
|
||||||
|
counter-reset: ln; white-space: pre; overflow-x: auto;
|
||||||
|
}
|
||||||
|
.code-pre .ln { display: block; }
|
||||||
|
.code-pre .ln::before { counter-increment: ln; content: counter(ln); display: inline-block; width: 24px; color: #4d4d4d; }
|
||||||
|
.k { color: var(--code-key); } .s { color: var(--code-str); } .n { color: var(--code-num); } .p { color: var(--code-dim); }
|
||||||
|
.cursor { display: inline-block; width: 7px; height: 15px; background: var(--violet); vertical-align: -3px; margin-left: 2px; animation: blink 1.1s steps(1) infinite; }
|
||||||
|
@keyframes blink { 50% { opacity: 0; } }
|
||||||
|
|
||||||
|
/* ---------- Home hero ---------- */
|
||||||
|
.hero { padding-block: 96px 0; text-align: center; position: relative; }
|
||||||
|
.hero::before {
|
||||||
|
content: ""; position: absolute; inset: 0 0 auto; height: 900px; z-index: -1; pointer-events: none;
|
||||||
|
background-image: linear-gradient(var(--mist) 1px, transparent 1px), linear-gradient(90deg, var(--mist) 1px, transparent 1px);
|
||||||
|
background-size: 64px 64px; background-position: center -1px;
|
||||||
|
mask-image: radial-gradient(ellipse 60% 55% at 50% 30%, #000 0%, transparent 75%);
|
||||||
|
-webkit-mask-image: radial-gradient(ellipse 60% 55% at 50% 30%, #000 0%, transparent 75%);
|
||||||
|
opacity: .65;
|
||||||
|
}
|
||||||
|
.hero-copy { display: flex; flex-direction: column; align-items: center; gap: 28px; }
|
||||||
|
.hero h1 { max-width: 15ch; }
|
||||||
|
.hero .lead { max-width: 660px; }
|
||||||
|
.cluster { position: relative; max-width: 1120px; height: 720px; margin: 80px auto 0; text-align: left; }
|
||||||
|
.cluster .panel { position: absolute; }
|
||||||
|
.dash { left: 228px; top: 0; width: 700px; z-index: 2; }
|
||||||
|
.dash-body { padding: 24px; display: grid; gap: 20px; }
|
||||||
|
.dash-head { display: flex; align-items: end; justify-content: space-between; gap: 12px 16px; flex-wrap: wrap; }
|
||||||
|
.dash-head small { display: block; font-size: 12px; color: var(--smoke); letter-spacing: var(--tracking-eyebrow); text-transform: uppercase; }
|
||||||
|
.dash-head strong { font-size: 20px; letter-spacing: -0.01em; }
|
||||||
|
.kpis { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; }
|
||||||
|
.kpi { background: var(--cloud); border-radius: 12px; padding: 14px 16px; }
|
||||||
|
.kpi span { display: block; font-size: 11.5px; color: var(--smoke); letter-spacing: var(--tracking-eyebrow); text-transform: uppercase; }
|
||||||
|
.kpi b { display: block; font-size: 28px; line-height: 1.15; letter-spacing: -0.02em; font-variant-numeric: tabular-nums; }
|
||||||
|
.dash-cols { display: grid; grid-template-columns: 1.35fr 1fr; gap: 16px; }
|
||||||
|
.list { border: 1px solid var(--mist); border-radius: 12px; overflow: hidden; }
|
||||||
|
.list-head { display: flex; justify-content: space-between; align-items: center; padding: 10px 14px; font-size: 11.5px; color: var(--smoke); background: var(--cloud); letter-spacing: var(--tracking-eyebrow); text-transform: uppercase; }
|
||||||
|
.row { display: flex; align-items: center; gap: 10px; padding: 9px 14px; font-size: 13.5px; border-top: 1px solid var(--mist); }
|
||||||
|
.list-head + .row { border-top: 0; }
|
||||||
|
.row .ico { width: 26px; height: 26px; border-radius: 8px; background: var(--violet-soft); color: var(--violet); display: grid; place-items: center; flex: none; }
|
||||||
|
.row .ico svg { width: 15px; height: 15px; }
|
||||||
|
.row .name { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
||||||
|
.status { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; color: var(--slate); }
|
||||||
|
.check { color: var(--violet); width: 16px; height: 16px; flex: none; }
|
||||||
|
.profile { left: 0; top: 170px; width: 252px; z-index: 3; padding: 14px; border-radius: 24px; }
|
||||||
|
.profile img { border-radius: var(--radius-img); aspect-ratio: 1; object-fit: cover; object-position: center 20%; width: 100%; }
|
||||||
|
.profile-meta { padding: 14px 4px 4px; display: grid; gap: 10px; }
|
||||||
|
.profile-meta strong { font-size: 17px; letter-spacing: -0.01em; }
|
||||||
|
.profile-meta .prole { font-size: 12px; color: var(--slate); margin-top: -8px; letter-spacing: var(--tracking-eyebrow); text-transform: uppercase; }
|
||||||
|
.profile .chips { gap: 6px; }
|
||||||
|
.profile .tag { font-size: 12px; padding: 3px 10px; }
|
||||||
|
.code { right: 0; top: 400px; width: 360px; z-index: 3; }
|
||||||
|
|
||||||
|
/* ---------- Section header ---------- */
|
||||||
|
.sec-head { display: grid; grid-template-columns: 1.1fr 1fr; gap: 48px; align-items: end; margin-bottom: 56px; }
|
||||||
|
.sec-head > * { min-width: 0; }
|
||||||
|
.sec-head .stack-sm { gap: 20px; }
|
||||||
|
.sec-head-center { max-width: 820px; margin: 0 auto 56px; display: flex; flex-direction: column; align-items: center; text-align: center; gap: 20px; }
|
||||||
|
.sec-head-center .body { margin-inline: auto; }
|
||||||
|
|
||||||
|
/* ---------- Feature grid ---------- */
|
||||||
|
.features { display: grid; grid-template-columns: repeat(3, 1fr); gap: 0 32px; }
|
||||||
|
.feature { display: flex; flex-direction: column; gap: 16px; padding-block: 32px 40px; border-top: 1px solid var(--mist); position: relative; }
|
||||||
|
.feature::before { content: ""; position: absolute; top: -1px; left: 0; width: 0; height: 1px; background: var(--violet); transition: width .5s ease; }
|
||||||
|
.feature:hover::before { width: 100%; }
|
||||||
|
.ic { width: 48px; height: 48px; border-radius: 14px; background: var(--cloud); color: var(--violet); display: grid; place-items: center; flex: none; }
|
||||||
|
.ic svg { width: 24px; height: 24px; }
|
||||||
|
.feature h3 { font-size: 14px; letter-spacing: var(--tracking-eyebrow); text-transform: uppercase; }
|
||||||
|
.feature p { font-size: var(--text-heading-sm); line-height: 1.4; letter-spacing: -0.01em; color: var(--graphite); }
|
||||||
|
.features-2 { grid-template-columns: repeat(2, 1fr); }
|
||||||
|
.features-4 { grid-template-columns: repeat(4, 1fr); }
|
||||||
|
.sec-foot { display: flex; justify-content: space-between; align-items: center; gap: 24px; flex-wrap: wrap; margin-top: 16px; padding-top: 32px; border-top: 1px solid var(--mist); }
|
||||||
|
.sec-foot p { color: var(--slate); max-width: 62ch; }
|
||||||
|
|
||||||
|
/* ---------- Cloud cards ---------- */
|
||||||
|
.cards { display: grid; gap: 16px; }
|
||||||
|
.cards-2 { grid-template-columns: repeat(2, 1fr); }
|
||||||
|
.cards-3 { grid-template-columns: repeat(3, 1fr); }
|
||||||
|
.cards-4 { grid-template-columns: repeat(4, 1fr); }
|
||||||
|
.card { background: var(--cloud); border-radius: var(--radius-card); padding: var(--card-pad); display: flex; flex-direction: column; gap: 18px; min-width: 0; position: relative; transition: background-color .2s ease; }
|
||||||
|
.card p { color: var(--slate); }
|
||||||
|
.card .card-top { display: flex; justify-content: space-between; align-items: center; gap: 12px; }
|
||||||
|
.card .ic { background: var(--porcelain); border-radius: 50%; }
|
||||||
|
.card-white { background: var(--porcelain); border: 1px solid var(--mist); }
|
||||||
|
.card-dark { background: var(--ink); color: var(--porcelain); }
|
||||||
|
.card-dark h2, .card-dark h3, .card-dark h4 { color: var(--porcelain); }
|
||||||
|
.card-dark p, .card-dark .body { color: var(--ash); }
|
||||||
|
.card-dark .eyebrow { color: var(--ash); }
|
||||||
|
.card-lg { padding: 48px; gap: 24px; }
|
||||||
|
.card .spacer { flex: 1; }
|
||||||
|
.card .push { margin-top: auto; }
|
||||||
|
.index { font: 500 12px/1 var(--font-mono); color: var(--smoke); letter-spacing: 0.04em; }
|
||||||
|
.card-dark .index { color: var(--dark-muted); }
|
||||||
|
.exit { min-height: 320px; }
|
||||||
|
.exit h3 { margin-top: auto; }
|
||||||
|
.exit p { font-size: 15px; }
|
||||||
|
|
||||||
|
/* ---------- Stats ---------- */
|
||||||
|
.stats { display: grid; grid-template-columns: repeat(3, 1fr) 1.3fr; margin-top: 56px; border-top: 1px solid var(--ink); }
|
||||||
|
.stat { padding: 28px 24px 0 0; display: grid; gap: 4px; align-content: start; }
|
||||||
|
.stat + .stat { padding-left: 24px; border-left: 1px solid var(--mist); }
|
||||||
|
.stat span { font-size: 13px; color: var(--smoke); letter-spacing: var(--tracking-eyebrow); text-transform: uppercase; }
|
||||||
|
.stat b { font-size: clamp(56px, 6.5vw, 88px); line-height: 1; letter-spacing: -0.05em; font-variant-numeric: tabular-nums; }
|
||||||
|
.stat b sup { font-size: .5em; vertical-align: .7em; color: var(--violet); margin-left: 2px; }
|
||||||
|
.stat-note { display: flex; flex-direction: column; justify-content: space-between; gap: 20px; }
|
||||||
|
.stat-note p { color: var(--slate); }
|
||||||
|
|
||||||
|
/* ---------- Showcase ---------- */
|
||||||
|
.showcase { background: var(--cloud); border-radius: var(--radius-card); padding: 64px; display: grid; grid-template-columns: 1fr 1fr; gap: 64px; align-items: center; }
|
||||||
|
.showcase > * { min-width: 0; }
|
||||||
|
.showcase .stack { max-width: 540px; }
|
||||||
|
.quote-line { font-size: var(--text-heading-sm); line-height: 1.45; letter-spacing: -0.01em; color: var(--ink); padding-left: 20px; border-left: 2px solid var(--violet); }
|
||||||
|
.portrait { position: relative; padding-bottom: 48px; }
|
||||||
|
.portrait img { width: 100%; aspect-ratio: 4 / 4.4; object-fit: cover; object-position: center 22%; border-radius: 24px; }
|
||||||
|
.flow {
|
||||||
|
position: absolute; left: -32px; bottom: 0; width: min(340px, 88%);
|
||||||
|
background: var(--porcelain); border-radius: var(--radius-panel); box-shadow: var(--shadow-float);
|
||||||
|
border: 1px solid var(--mist); padding: 18px 20px; display: grid; gap: 12px;
|
||||||
|
}
|
||||||
|
.flow small { font-size: 12px; color: var(--smoke); }
|
||||||
|
.flow ol { display: grid; gap: 10px; counter-reset: f; }
|
||||||
|
.flow li { display: flex; align-items: center; gap: 12px; font-size: 14.5px; counter-increment: f; }
|
||||||
|
.flow li::before { content: counter(f); width: 24px; height: 24px; border-radius: 50%; flex: none; display: grid; place-items: center; font-size: 12px; background: var(--violet-soft); color: var(--violet); }
|
||||||
|
|
||||||
|
/* Steps panel (process) */
|
||||||
|
.steps-panel { border-radius: 24px; }
|
||||||
|
.steps-panel ol { padding: 8px 0; }
|
||||||
|
.sp-step { display: grid; grid-template-columns: 44px 1fr; gap: 16px; align-items: start; padding: 20px 24px; }
|
||||||
|
.sp-step + .sp-step { border-top: 1px solid var(--mist); }
|
||||||
|
.sp-step .num { width: 44px; height: 44px; border-radius: 12px; background: var(--cloud); display: grid; place-items: center; font-weight: 700; font-variant-numeric: tabular-nums; color: var(--slate); }
|
||||||
|
.sp-step:first-child .num { background: var(--violet); color: var(--porcelain); }
|
||||||
|
.sp-step h4 { font-size: 16px; margin-top: 11px; }
|
||||||
|
|
||||||
|
/* Book */
|
||||||
|
.book-stage { display: grid; place-items: center; padding-block: 16px; perspective: 1200px; }
|
||||||
|
.book {
|
||||||
|
position: relative; width: min(300px, 80%); aspect-ratio: 3 / 4.1;
|
||||||
|
background: var(--ink); color: var(--porcelain); border-radius: 6px 16px 16px 6px;
|
||||||
|
box-shadow: var(--shadow-float), rgba(0, 0, 0, 0.22) 24px 30px 50px -24px;
|
||||||
|
padding: 32px 28px 28px 38px; display: flex; flex-direction: column;
|
||||||
|
transform: rotateY(-14deg) rotateX(4deg); transform-style: preserve-3d; transition: transform .6s cubic-bezier(.2, .7, .2, 1);
|
||||||
|
overflow: visible;
|
||||||
|
}
|
||||||
|
.book-stage:hover .book { transform: rotateY(-4deg) rotateX(2deg); }
|
||||||
|
.book::before { content: ""; position: absolute; left: 14px; top: 0; bottom: 0; width: 1px; background: rgba(255, 255, 255, .12); }
|
||||||
|
.book::after { content: ""; position: absolute; right: -10px; top: 10px; bottom: 10px; width: 10px; border-radius: 0 6px 6px 0; background: repeating-linear-gradient(180deg, var(--porcelain) 0 2px, var(--mist) 2px 3px); }
|
||||||
|
.book .brand-mark { width: 30px; height: 30px; }
|
||||||
|
.book h3 { color: var(--porcelain); font-size: clamp(26px, 3vw, 34px); line-height: 1.05; letter-spacing: -0.03em; margin-top: auto; }
|
||||||
|
.book .by { margin-top: 20px; padding-top: 14px; border-top: 1px solid rgba(255, 255, 255, .16); font-size: 12px; color: var(--ash); letter-spacing: var(--tracking-eyebrow); text-transform: uppercase; }
|
||||||
|
.beats { display: grid; }
|
||||||
|
.beats li { display: flex; gap: 14px; align-items: baseline; padding-block: 12px; border-top: 1px solid var(--mist); color: var(--ink); }
|
||||||
|
.beats li:last-child { border-bottom: 1px solid var(--mist); }
|
||||||
|
.beats li svg { width: 16px; height: 16px; color: var(--violet); flex: none; transform: translateY(2px); }
|
||||||
|
|
||||||
|
/* Duo (press + poetry) */
|
||||||
|
.duo { display: grid; grid-template-columns: 1.15fr 1fr; gap: 16px; }
|
||||||
|
.poem { font-size: var(--text-heading); line-height: 1.35; letter-spacing: -0.015em; display: grid; gap: 4px; color: var(--porcelain); }
|
||||||
|
.poem span:last-child { color: var(--ash); }
|
||||||
|
|
||||||
|
/* ---------- Dark band ---------- */
|
||||||
|
.band { background: var(--ink); color: var(--porcelain); position: relative; overflow: hidden; }
|
||||||
|
.band::before {
|
||||||
|
content: ""; position: absolute; inset: 0; pointer-events: none;
|
||||||
|
background-image: radial-gradient(rgba(255, 255, 255, .09) 1px, transparent 1px);
|
||||||
|
background-size: 22px 22px;
|
||||||
|
mask-image: radial-gradient(ellipse 80% 70% at 85% 10%, #000, transparent 70%);
|
||||||
|
-webkit-mask-image: radial-gradient(ellipse 80% 70% at 85% 10%, #000, transparent 70%);
|
||||||
|
}
|
||||||
|
.band > * { position: relative; }
|
||||||
|
.band h2, .band h3, .band h4 { color: var(--porcelain); }
|
||||||
|
.band .eyebrow { color: var(--ash); }
|
||||||
|
.band .body, .band .prose p, .band .lead { color: var(--ash); }
|
||||||
|
.band .statement, .band .prose p.statement { color: var(--porcelain); }
|
||||||
|
.inline-link { color: var(--violet); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 4px; }
|
||||||
|
.inline-link:hover { text-decoration-thickness: 2px; }
|
||||||
|
.band + .section:not(.band) { padding-top: var(--section-y); }
|
||||||
|
|
||||||
|
/* Rules (terminal list) */
|
||||||
|
.rules { border-top: 1px solid var(--dark-line); }
|
||||||
|
.rule { display: grid; grid-template-columns: 120px 1fr 1.2fr; gap: 32px; padding-block: 36px; border-bottom: 1px solid var(--dark-line); align-items: start; }
|
||||||
|
.rule > * { min-width: 0; }
|
||||||
|
.rule .index { color: var(--violet); font-size: 13px; padding-top: 8px; filter: brightness(1.35); }
|
||||||
|
.rule h3 { font-size: var(--text-heading-lg); line-height: 1.1; letter-spacing: -0.025em; }
|
||||||
|
.rule .prose p { color: var(--ash); }
|
||||||
|
.rule .prose p.ink { color: var(--porcelain); }
|
||||||
|
.qlist { display: grid; gap: 6px; }
|
||||||
|
.qlist p { font-family: var(--font-mono); font-size: 14.5px; color: var(--porcelain) !important; }
|
||||||
|
.qlist p::before { content: "> "; color: var(--violet); filter: brightness(1.35); }
|
||||||
|
|
||||||
|
/* Line list (short beats) */
|
||||||
|
.lines { display: grid; gap: 4px; }
|
||||||
|
.lines p { color: var(--slate); }
|
||||||
|
.lines p.ink { color: var(--ink); }
|
||||||
|
|
||||||
|
/* Whisper (things I notice) */
|
||||||
|
.whisper { display: grid; grid-template-columns: 1fr 1fr; gap: 64px; align-items: start; }
|
||||||
|
.whisper > * { min-width: 0; }
|
||||||
|
.signals { display: grid; gap: 12px; }
|
||||||
|
.signal { display: flex; gap: 14px; align-items: center; padding: 16px 20px; background: var(--cloud); border-radius: var(--radius-panel); color: var(--slate); }
|
||||||
|
.signal:nth-child(1) { font-size: 15px; opacity: .7; }
|
||||||
|
.signal:nth-child(2) { font-size: 16px; opacity: .85; }
|
||||||
|
.signal:nth-child(3) { font-size: 17px; }
|
||||||
|
.signal .dot { background: var(--ash); box-shadow: none; }
|
||||||
|
.signal:nth-child(3) .dot { background: var(--violet); box-shadow: 0 0 0 4px var(--violet-soft); }
|
||||||
|
.shouts { display: grid; gap: 0; }
|
||||||
|
.shout { padding-block: 22px; border-top: 1px solid var(--mist); display: grid; gap: 6px; }
|
||||||
|
.shout:last-child { border-bottom: 1px solid var(--mist); }
|
||||||
|
.shout q { quotes: none; font-weight: 700; letter-spacing: -0.02em; color: var(--ink); line-height: 1.15; }
|
||||||
|
.shout:nth-child(1) q { font-size: 24px; }
|
||||||
|
.shout:nth-child(2) q { font-size: 30px; }
|
||||||
|
.shout:nth-child(3) q { font-size: 38px; }
|
||||||
|
.shout span { color: var(--slate); }
|
||||||
|
|
||||||
|
/* ---------- Process (horizontal steps) ---------- */
|
||||||
|
.process { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; counter-reset: step; position: relative; }
|
||||||
|
.process-step { background: var(--cloud); border-radius: var(--radius-card); padding: var(--card-pad); display: flex; flex-direction: column; gap: 16px; position: relative; min-width: 0; }
|
||||||
|
.process-step .num {
|
||||||
|
width: 52px; height: 52px; border-radius: 16px; background: var(--porcelain); border: 1px solid var(--mist);
|
||||||
|
display: grid; place-items: center; font-weight: 700; font-size: 18px; font-variant-numeric: tabular-nums; color: var(--ink);
|
||||||
|
}
|
||||||
|
.process-step:first-child .num { background: var(--violet); border-color: var(--violet); color: var(--porcelain); }
|
||||||
|
.process-step:not(:last-child)::after {
|
||||||
|
content: ""; position: absolute; top: 58px; right: -16px; width: 16px; height: 1px; background: var(--ash);
|
||||||
|
}
|
||||||
|
.process-step p { color: var(--slate); }
|
||||||
|
.process-step p.ink { color: var(--ink); }
|
||||||
|
|
||||||
|
/* ---------- Pricing / engagement ---------- */
|
||||||
|
.plans { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; align-items: stretch; }
|
||||||
|
.plan { border-radius: var(--radius-card); padding: 36px 32px; display: flex; flex-direction: column; gap: 20px; background: var(--cloud); min-width: 0; }
|
||||||
|
.plan-featured { background: var(--ink); color: var(--porcelain); box-shadow: 0 30px 60px -30px rgba(31, 31, 31, .5); }
|
||||||
|
.plan-featured h3, .plan-featured h4 { color: var(--porcelain); }
|
||||||
|
.plan.plan-featured p { color: var(--ash); }
|
||||||
|
.plan .plan-name { font-size: 13px; letter-spacing: var(--tracking-eyebrow); text-transform: uppercase; color: var(--smoke); display: flex; justify-content: space-between; align-items: center; gap: 8px; }
|
||||||
|
.plan-featured .plan-name { color: var(--ash); }
|
||||||
|
.plan h3 { font-size: var(--text-heading); line-height: 1.15; letter-spacing: -0.02em; }
|
||||||
|
.plan p { color: var(--slate); }
|
||||||
|
.plan .fee { padding-block: 14px; border-block: 1px solid var(--mist); font-weight: 700; color: var(--ink); font-size: 15px; }
|
||||||
|
.plan-featured .fee { border-color: var(--dark-line); color: var(--porcelain); }
|
||||||
|
.plan ul { display: grid; gap: 12px; }
|
||||||
|
.plan li { display: flex; gap: 12px; align-items: flex-start; font-size: 15px; color: var(--graphite); }
|
||||||
|
.plan-featured li { color: var(--porcelain); }
|
||||||
|
.plan li svg { width: 16px; height: 16px; color: var(--violet); flex: none; margin-top: 3px; }
|
||||||
|
.plan-featured li svg { color: #8d86ff; }
|
||||||
|
.plan .btn { margin-top: auto; }
|
||||||
|
|
||||||
|
/* ---------- Role chips (fractional) ---------- */
|
||||||
|
.roles { display: grid; grid-template-columns: repeat(2, 1fr); gap: 12px; }
|
||||||
|
.role {
|
||||||
|
border: 1px solid var(--dark-line); border-radius: 24px; padding: 24px; display: grid; gap: 28px;
|
||||||
|
background: rgba(255, 255, 255, .02); transition: border-color .2s ease, background-color .2s ease;
|
||||||
|
}
|
||||||
|
.role:hover { border-color: var(--violet); background: rgba(89, 79, 244, .08); }
|
||||||
|
.role .index { color: var(--dark-muted); }
|
||||||
|
.role b { font-size: clamp(28px, 3.4vw, 40px); letter-spacing: -0.03em; line-height: 1; }
|
||||||
|
|
||||||
|
/* ---------- Tabs (service lines) ---------- */
|
||||||
|
.tabs { display: grid; grid-template-columns: 340px 1fr; gap: 24px; align-items: start; }
|
||||||
|
.tabs > * { min-width: 0; }
|
||||||
|
.tab-list { display: grid; gap: 4px; position: sticky; top: calc(var(--nav-h) + 24px); }
|
||||||
|
.tab-btn {
|
||||||
|
display: grid; grid-template-columns: 40px 1fr 16px; gap: 14px; align-items: center; text-align: left;
|
||||||
|
padding: 14px 16px; border-radius: 18px; border: 1px solid transparent; background: transparent; cursor: pointer;
|
||||||
|
font: 700 16px/1.25 var(--font-sans); color: var(--slate); transition: background-color .15s ease, color .15s ease, border-color .15s ease;
|
||||||
|
}
|
||||||
|
.tab-btn .ic { width: 40px; height: 40px; border-radius: 12px; }
|
||||||
|
.tab-btn .ic svg { width: 20px; height: 20px; }
|
||||||
|
.tab-btn .arr { width: 16px; height: 16px; opacity: 0; transition: opacity .15s ease, transform .15s ease; transform: translateX(-4px); color: var(--violet); }
|
||||||
|
.tab-btn:hover { background: var(--cloud); color: var(--ink); }
|
||||||
|
.tab-btn[aria-selected="true"] { background: var(--cloud); color: var(--ink); border-color: var(--mist); }
|
||||||
|
.tab-btn[aria-selected="true"] .ic { background: var(--violet); color: var(--porcelain); }
|
||||||
|
.tab-btn[aria-selected="true"] .arr { opacity: 1; transform: none; }
|
||||||
|
.tab-panels { display: grid; gap: 16px; }
|
||||||
|
.tab-panel { background: var(--cloud); border-radius: var(--radius-card); padding: 48px; display: flex; flex-direction: column; gap: 22px; min-height: 420px; }
|
||||||
|
.tab-panel .tp-title { font-size: 13px; letter-spacing: var(--tracking-eyebrow); text-transform: uppercase; color: var(--smoke); }
|
||||||
|
.tab-panel .btn-row { margin-top: auto; padding-top: 8px; }
|
||||||
|
.js .tabs .tab-panel[hidden] { display: none; }
|
||||||
|
html:not(.js) .tab-list { display: none; }
|
||||||
|
html:not(.js) .tabs { grid-template-columns: 1fr; }
|
||||||
|
|
||||||
|
/* ---------- Principles (why dylan) ---------- */
|
||||||
|
.principles { display: grid; grid-template-columns: repeat(3, 1fr); gap: 0; border-top: 1px solid var(--ink); }
|
||||||
|
.principle { padding: 32px 32px 8px 0; display: flex; flex-direction: column; gap: 14px; min-width: 0; }
|
||||||
|
.principle + .principle { padding-left: 32px; border-left: 1px solid var(--mist); }
|
||||||
|
.principle p { color: var(--slate); }
|
||||||
|
.principle p.ink { color: var(--ink); }
|
||||||
|
|
||||||
|
/* ---------- FAQ ---------- */
|
||||||
|
.faq { display: grid; gap: 10px; }
|
||||||
|
.faq details { background: var(--cloud); border-radius: var(--radius-panel); transition: background-color .2s ease; }
|
||||||
|
.faq details[open] { background: var(--porcelain); box-shadow: var(--shadow-float); outline: 1px solid var(--mist); }
|
||||||
|
.faq summary {
|
||||||
|
list-style: none; cursor: pointer; display: flex; justify-content: space-between; align-items: center; gap: 20px;
|
||||||
|
padding: 22px 26px; font-weight: 700; font-size: 17px; letter-spacing: -0.01em; color: var(--ink);
|
||||||
|
}
|
||||||
|
.faq summary::-webkit-details-marker { display: none; }
|
||||||
|
.faq summary .pm { width: 32px; height: 32px; border-radius: 50%; background: var(--porcelain); display: grid; place-items: center; flex: none; transition: transform .25s ease, background-color .2s ease, color .2s ease; color: var(--ink); }
|
||||||
|
.faq details[open] summary .pm { transform: rotate(45deg); background: var(--violet); color: var(--porcelain); }
|
||||||
|
.faq summary .pm svg { width: 14px; height: 14px; }
|
||||||
|
.faq .answer { padding: 0 26px 24px; display: grid; gap: 12px; color: var(--slate); max-width: 72ch; }
|
||||||
|
.faq-layout { display: grid; grid-template-columns: 0.8fr 1.2fr; gap: 64px; align-items: start; }
|
||||||
|
.faq-layout > * { min-width: 0; }
|
||||||
|
.faq-layout .sticky { position: sticky; top: calc(var(--nav-h) + 32px); }
|
||||||
|
|
||||||
|
/* ---------- Ventures directory (portfolio) ---------- */
|
||||||
|
.ventures { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; }
|
||||||
|
.venture { background: var(--cloud); border-radius: 28px; padding: 28px; display: flex; flex-direction: column; gap: 16px; min-width: 0; position: relative; overflow: hidden; transition: background-color .2s ease, transform .25s ease; }
|
||||||
|
.venture:hover { background: var(--porcelain); box-shadow: var(--shadow-float); outline: 1px solid var(--mist); transform: translateY(-3px); }
|
||||||
|
.venture-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 12px; }
|
||||||
|
.mono { width: 52px; height: 52px; border-radius: 16px; background: var(--ink); color: var(--porcelain); display: grid; place-items: center; font-weight: 700; font-size: 17px; letter-spacing: -0.02em; flex: none; }
|
||||||
|
.venture:nth-child(3n+2) .mono { background: var(--violet); }
|
||||||
|
.venture:nth-child(3n+3) .mono { background: var(--porcelain); color: var(--ink); border: 1px solid var(--mist); }
|
||||||
|
.venture h3 { font-size: 24px; letter-spacing: -0.02em; line-height: 1.15; }
|
||||||
|
.venture .vrole { font-size: 13px; color: var(--violet); letter-spacing: 0.02em; line-height: 1.4; }
|
||||||
|
.venture p { color: var(--slate); font-size: 15px; }
|
||||||
|
.venture .focus { margin-top: auto; padding-top: 16px; border-top: 1px solid var(--mist); display: grid; gap: 10px; }
|
||||||
|
.venture .focus small { font-size: 11.5px; color: var(--smoke); letter-spacing: var(--tracking-eyebrow); text-transform: uppercase; }
|
||||||
|
.venture .focus .chips { gap: 6px; }
|
||||||
|
.venture .tag { background: var(--porcelain); font-size: 12px; padding: 4px 10px; }
|
||||||
|
.venture:hover .tag { background: var(--cloud); }
|
||||||
|
|
||||||
|
/* Marquee */
|
||||||
|
.marquee { overflow: hidden; mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent); -webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent); }
|
||||||
|
.marquee-track { display: flex; gap: 12px; width: max-content; animation: marquee 50s linear infinite; padding-block: 6px; }
|
||||||
|
.marquee:hover .marquee-track { animation-play-state: paused; }
|
||||||
|
.marquee-track.rev { animation-direction: reverse; animation-duration: 58s; }
|
||||||
|
@keyframes marquee { to { transform: translateX(-50%); } }
|
||||||
|
.cap { display: inline-flex; align-items: center; gap: 12px; padding: 16px 24px; border-radius: var(--radius-pill); background: var(--porcelain); border: 1px solid var(--mist); font-size: 17px; font-weight: 700; letter-spacing: -0.01em; white-space: nowrap; }
|
||||||
|
.cap i { width: 8px; height: 8px; border-radius: 2px; background: var(--violet); }
|
||||||
|
.band .cap { background: rgba(255, 255, 255, .04); border-color: var(--dark-line); color: var(--porcelain); }
|
||||||
|
|
||||||
|
/* Industries grid */
|
||||||
|
.industries { display: grid; grid-template-columns: repeat(4, 1fr); border-top: 1px solid var(--mist); border-left: 1px solid var(--mist); }
|
||||||
|
.industry { padding: 22px 22px; border-right: 1px solid var(--mist); border-bottom: 1px solid var(--mist); display: flex; flex-direction: column; gap: 18px; min-height: 120px; justify-content: space-between; transition: background-color .2s ease; }
|
||||||
|
.industry:hover { background: var(--cloud); }
|
||||||
|
.industry .index { color: var(--ash); }
|
||||||
|
.industry b { font-size: 19px; letter-spacing: -0.015em; line-height: 1.2; }
|
||||||
|
.industry-note { background: var(--violet); color: var(--porcelain); grid-column: span 3; flex-direction: row; align-items: flex-end; }
|
||||||
|
.industry-note:hover { background: var(--violet-press); }
|
||||||
|
.filler { background: var(--cloud); }
|
||||||
|
.filler:hover { background: var(--cloud); }
|
||||||
|
.industry-note p { font-size: 15px; line-height: 1.45; }
|
||||||
|
|
||||||
|
/* ---------- Covers (what this covers) ---------- */
|
||||||
|
.covers { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; }
|
||||||
|
.cover { background: var(--porcelain); border: 1px solid var(--mist); border-radius: 28px; padding: 28px; display: flex; flex-direction: column; gap: 20px; min-width: 0; }
|
||||||
|
.cover .cover-head { display: flex; gap: 14px; align-items: center; }
|
||||||
|
.cover h3 { font-size: 19px; letter-spacing: -0.015em; line-height: 1.25; }
|
||||||
|
.cover ul { display: grid; gap: 0; }
|
||||||
|
.cover li { display: flex; gap: 12px; align-items: flex-start; padding-block: 11px; border-top: 1px solid var(--cloud); color: var(--graphite); font-size: 15px; }
|
||||||
|
.cover li svg { width: 16px; height: 16px; color: var(--violet); flex: none; margin-top: 3px; }
|
||||||
|
|
||||||
|
/* ---------- Closing CTA ---------- */
|
||||||
|
.closing { background: var(--cloud); border-radius: var(--radius-card); padding: 88px 48px; text-align: center; position: relative; overflow: hidden; }
|
||||||
|
.closing::before {
|
||||||
|
content: ""; position: absolute; inset: 0; pointer-events: none;
|
||||||
|
background-image: linear-gradient(var(--mist) 1px, transparent 1px), linear-gradient(90deg, var(--mist) 1px, transparent 1px);
|
||||||
|
background-size: 48px 48px; background-position: center;
|
||||||
|
mask-image: radial-gradient(ellipse 60% 70% at 50% 100%, #000, transparent 70%);
|
||||||
|
-webkit-mask-image: radial-gradient(ellipse 60% 70% at 50% 100%, #000, transparent 70%);
|
||||||
|
}
|
||||||
|
.closing > * { position: relative; }
|
||||||
|
.closing-inner { max-width: 780px; margin: 0 auto; display: flex; flex-direction: column; align-items: center; gap: 24px; }
|
||||||
|
.closing .prose p { margin-inline: auto; }
|
||||||
|
.closing-dark { background: var(--ink); color: var(--porcelain); }
|
||||||
|
.closing-dark::before { background-image: radial-gradient(rgba(255, 255, 255, .1) 1px, transparent 1px); background-size: 22px 22px; }
|
||||||
|
.closing-dark h2 { color: var(--porcelain); }
|
||||||
|
.closing-dark .prose p { color: var(--ash); }
|
||||||
|
.closing-dark .eyebrow { color: var(--ash); }
|
||||||
|
.closing-dark .statement { color: var(--porcelain); }
|
||||||
|
|
||||||
|
/* ---------- Contact ---------- */
|
||||||
|
.contact-grid { display: grid; grid-template-columns: 0.95fr 1.05fr; gap: 64px; align-items: start; }
|
||||||
|
.contact-grid > * { min-width: 0; }
|
||||||
|
.direct { display: grid; gap: 0; border-top: 1px solid var(--mist); }
|
||||||
|
.direct-row { display: grid; gap: 8px; padding-block: 22px; border-bottom: 1px solid var(--mist); }
|
||||||
|
.direct-row small { font-size: 12px; color: var(--smoke); letter-spacing: var(--tracking-eyebrow); text-transform: uppercase; }
|
||||||
|
.direct-row .val { font-size: clamp(20px, 2.2vw, 26px); font-weight: 700; letter-spacing: -0.02em; display: flex; flex-wrap: wrap; align-items: center; gap: 12px; }
|
||||||
|
.direct-row a.val:hover { color: var(--violet); }
|
||||||
|
.copy-btn { border: 1px solid var(--mist); background: var(--porcelain); border-radius: var(--radius-pill); padding: 6px 12px; font: 500 12px var(--font-sans); color: var(--graphite); cursor: pointer; }
|
||||||
|
.copy-btn:hover { border-color: var(--ash); }
|
||||||
|
.form-card { padding: 36px; border-radius: 28px; display: grid; gap: 24px; }
|
||||||
|
.form-card .panel-bar { margin: -36px -36px 0; }
|
||||||
|
.form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
|
||||||
|
.field { display: grid; gap: 8px; }
|
||||||
|
.field-full { grid-column: 1 / -1; }
|
||||||
|
.field label { font-size: 13px; color: var(--slate); }
|
||||||
|
.field input, .field textarea, .field select {
|
||||||
|
width: 100%; font: 500 16px/1.4 var(--font-sans); color: var(--ink);
|
||||||
|
background: var(--cloud); border: 1px solid transparent; border-radius: 16px; padding: 14px 16px;
|
||||||
|
transition: border-color .15s ease, background-color .15s ease, box-shadow .15s ease;
|
||||||
|
}
|
||||||
|
.field textarea { min-height: 150px; resize: vertical; }
|
||||||
|
.field input:focus, .field textarea:focus, .field select:focus { outline: none; background: var(--porcelain); border-color: var(--violet); box-shadow: 0 0 0 4px var(--violet-soft); }
|
||||||
|
.form-note { font-size: 13px; color: var(--smoke); }
|
||||||
|
.form-status { font-size: 14px; color: var(--signal-green); min-height: 1.4em; }
|
||||||
|
.cal-card { display: grid; grid-template-columns: 1fr auto; gap: 20px; align-items: center; padding: 28px 32px; border-radius: 28px; background: var(--ink); color: var(--porcelain); transition: transform .2s ease; }
|
||||||
|
.cal-card:hover { transform: translateY(-2px); }
|
||||||
|
.cal-card h3 { color: var(--porcelain); font-size: 22px; letter-spacing: -0.02em; }
|
||||||
|
.cal-card p { color: var(--ash); font-size: 15px; margin-top: 6px; }
|
||||||
|
.cal-card .go { width: 52px; height: 52px; border-radius: 50%; background: var(--violet); display: grid; place-items: center; transition: transform .2s ease; }
|
||||||
|
.cal-card:hover .go { transform: rotate(-45deg); }
|
||||||
|
.cal-card .go svg { width: 18px; height: 18px; }
|
||||||
|
|
||||||
|
/* ---------- Press ---------- */
|
||||||
|
.feature-press { display: grid; grid-template-columns: 1fr 1fr; border-radius: var(--radius-card); overflow: hidden; background: var(--ink); color: var(--porcelain); }
|
||||||
|
.feature-press > * { min-width: 0; }
|
||||||
|
.fp-visual { position: relative; min-height: 380px; background: #151515; display: grid; place-items: center; padding: 40px; overflow: hidden; }
|
||||||
|
.fp-visual::before { content: ""; position: absolute; inset: 0; background-image: radial-gradient(rgba(255, 255, 255, .08) 1px, transparent 1px); background-size: 18px 18px; }
|
||||||
|
.magazine { position: relative; width: min(260px, 70%); aspect-ratio: 3 / 4; border-radius: 8px; overflow: hidden; box-shadow: 0 40px 80px -30px rgba(0, 0, 0, .8); transform: rotate(-4deg); transition: transform .5s ease; }
|
||||||
|
.feature-press:hover .magazine { transform: rotate(-1deg) scale(1.02); }
|
||||||
|
.magazine img { width: 100%; height: 100%; object-fit: cover; object-position: center 20%; filter: grayscale(.2) contrast(1.05); }
|
||||||
|
.magazine::after { content: ""; position: absolute; inset: 0; background: linear-gradient(180deg, rgba(0, 0, 0, .55) 0%, transparent 30%, transparent 55%, rgba(0, 0, 0, .75) 100%); }
|
||||||
|
.magazine .mast { position: absolute; top: 14px; left: 16px; right: 16px; z-index: 1; font-weight: 700; font-size: 22px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--porcelain); }
|
||||||
|
.magazine .cover-line { position: absolute; bottom: 16px; left: 16px; right: 16px; z-index: 1; font-size: 13px; line-height: 1.3; color: var(--porcelain); font-weight: 700; }
|
||||||
|
.fp-copy { padding: 56px; display: flex; flex-direction: column; gap: 22px; justify-content: center; }
|
||||||
|
.fp-copy h3 { color: var(--porcelain); font-size: var(--text-heading-lg); letter-spacing: -0.025em; line-height: 1.12; }
|
||||||
|
.fp-copy .meta { font-size: 12px; letter-spacing: var(--tracking-eyebrow); text-transform: uppercase; color: var(--ash); }
|
||||||
|
.topics { display: grid; grid-template-columns: repeat(2, 1fr); gap: 16px; }
|
||||||
|
.topic { border: 1px solid var(--mist); border-radius: 28px; padding: 32px; display: grid; gap: 14px; grid-template-columns: 48px 1fr; align-items: start; transition: border-color .2s ease; }
|
||||||
|
.topic:hover { border-color: var(--violet); }
|
||||||
|
.topic h3 { font-size: 14px; letter-spacing: var(--tracking-eyebrow); text-transform: uppercase; margin-top: 4px; }
|
||||||
|
.topic p { color: var(--graphite); font-size: 18px; line-height: 1.45; letter-spacing: -0.01em; grid-column: 2; }
|
||||||
|
|
||||||
|
/* ---------- Footer ---------- */
|
||||||
|
.footer { background: var(--obsidian); color: var(--porcelain); padding-block: 80px clamp(110px, 17vw, 250px); margin-top: var(--section-y); position: relative; overflow: hidden; }
|
||||||
|
.foot-cta { display: flex; justify-content: space-between; align-items: end; gap: 32px; flex-wrap: wrap; padding-bottom: 64px; border-bottom: 1px solid #1f1f1f; }
|
||||||
|
.foot-cta h2 { color: var(--porcelain); max-width: 16ch; }
|
||||||
|
.foot-top { display: grid; grid-template-columns: 1.4fr repeat(3, 1fr); gap: 48px; }
|
||||||
|
.foot-top > * { min-width: 0; }
|
||||||
|
.foot-top .brand-word { color: var(--porcelain); }
|
||||||
|
.foot-intro { display: grid; gap: 20px; align-content: start; }
|
||||||
|
.foot-intro p { color: var(--ash); font-size: 13px; letter-spacing: var(--tracking-eyebrow); text-transform: uppercase; }
|
||||||
|
.foot-col h4 { font-size: 12px; font-weight: 500; letter-spacing: var(--tracking-eyebrow); text-transform: uppercase; color: var(--slate); margin-bottom: 18px; }
|
||||||
|
.foot-col ul { display: grid; gap: 12px; }
|
||||||
|
.foot-col a { color: var(--porcelain); transition: color .15s ease; overflow-wrap: anywhere; }
|
||||||
|
.foot-col a:hover { color: #8d86ff; }
|
||||||
|
.foot-col .muted { color: var(--ash); }
|
||||||
|
.foot-big { margin-top: 72px; padding-top: 32px; border-top: 1px solid #1f1f1f; display: flex; justify-content: space-between; align-items: end; gap: 24px; flex-wrap: wrap; }
|
||||||
|
.foot-big .places { font-size: clamp(22px, 3.4vw, 40px); font-weight: 700; letter-spacing: -0.025em; line-height: 1.15; }
|
||||||
|
.foot-big .places i { font-style: normal; color: var(--violet); padding-inline: 12px; }
|
||||||
|
.foot-big small { color: var(--slate); font-size: 13px; }
|
||||||
|
.foot-word { position: absolute; left: 50%; bottom: -0.22em; translate: -50% 0; font-size: clamp(80px, 17vw, 250px); font-weight: 700; letter-spacing: -0.06em; line-height: 1; color: #121212; white-space: nowrap; pointer-events: none; user-select: none; }
|
||||||
|
.footer .wrap { position: relative; z-index: 1; }
|
||||||
|
|
||||||
|
/* ---------- Motion ---------- */
|
||||||
|
@keyframes rise { from { opacity: 0; transform: translateY(18px); } to { opacity: 1; transform: none; } }
|
||||||
|
.anim > * { animation: rise .8s cubic-bezier(.2, .7, .2, 1) both; }
|
||||||
|
.anim > *:nth-child(2) { animation-delay: .08s; }
|
||||||
|
.anim > *:nth-child(3) { animation-delay: .16s; }
|
||||||
|
.anim > *:nth-child(4) { animation-delay: .24s; }
|
||||||
|
.anim > *:nth-child(5) { animation-delay: .32s; }
|
||||||
|
.anim > *:nth-child(6) { animation-delay: .4s; }
|
||||||
|
.cluster .panel { animation: rise 1s cubic-bezier(.2, .7, .2, 1) both; }
|
||||||
|
.cluster .dash { animation-delay: .35s; }
|
||||||
|
.cluster .profile { animation-delay: .55s; }
|
||||||
|
.cluster .code { animation-delay: .7s; }
|
||||||
|
.js .reveal { opacity: 0; transform: translateY(24px); transition: opacity .8s cubic-bezier(.2, .7, .2, 1), transform .8s cubic-bezier(.2, .7, .2, 1); }
|
||||||
|
.js .reveal.is-in { opacity: 1; transform: none; }
|
||||||
|
@media (prefers-reduced-motion: reduce) {
|
||||||
|
html { scroll-behavior: auto; }
|
||||||
|
*, *::before, *::after { animation: none !important; transition: none !important; }
|
||||||
|
.js .reveal { opacity: 1; transform: none; }
|
||||||
|
.book { transform: none; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------- Responsive ---------- */
|
||||||
|
@media (max-width: 1100px) {
|
||||||
|
.nav-links { display: none; }
|
||||||
|
.nav-cta .btn { display: none; }
|
||||||
|
.menu-btn { display: inline-flex; }
|
||||||
|
.cluster { height: auto; display: grid; grid-template-columns: 1fr 1fr; gap: 20px; max-width: 760px; }
|
||||||
|
.cluster > * { min-width: 0; }
|
||||||
|
.cluster .panel { position: relative; left: auto; right: auto; top: auto; width: auto; }
|
||||||
|
.dash { grid-column: 1 / -1; }
|
||||||
|
.cards-4, .exits { grid-template-columns: repeat(2, 1fr); }
|
||||||
|
.exit { min-height: 260px; }
|
||||||
|
.stats { grid-template-columns: repeat(3, 1fr); }
|
||||||
|
.stat-note { grid-column: 1 / -1; padding: 32px 0 0 !important; border-left: 0 !important; }
|
||||||
|
.foot-top { grid-template-columns: 1fr 1fr 1fr; }
|
||||||
|
.foot-intro { grid-column: 1 / -1; }
|
||||||
|
.ventures { grid-template-columns: repeat(2, 1fr); }
|
||||||
|
.industries { grid-template-columns: repeat(3, 1fr); }
|
||||||
|
.industry-note { grid-column: span 2; }
|
||||||
|
.tabs { grid-template-columns: 280px 1fr; }
|
||||||
|
.rule { grid-template-columns: 80px 1fr; }
|
||||||
|
.rule .prose { grid-column: 2; }
|
||||||
|
}
|
||||||
|
@media (max-width: 900px) {
|
||||||
|
:root { --section-y: 80px; }
|
||||||
|
.sec-head, .page-hero-grid, .whisper, .faq-layout, .contact-grid { grid-template-columns: 1fr; gap: 32px; }
|
||||||
|
.sec-head { margin-bottom: 40px; }
|
||||||
|
.faq-layout .sticky { position: static; }
|
||||||
|
.features { grid-template-columns: repeat(2, 1fr); }
|
||||||
|
.features-4 { grid-template-columns: repeat(2, 1fr); }
|
||||||
|
.showcase { grid-template-columns: 1fr; padding: 40px; gap: 48px; }
|
||||||
|
.showcase.reverse .visual { order: 2; }
|
||||||
|
.flow { left: 16px; }
|
||||||
|
.duo, .cards-2, .cards-3, .plans, .covers, .feature-press, .topics { grid-template-columns: 1fr; }
|
||||||
|
.process { grid-template-columns: 1fr; }
|
||||||
|
.process-step:not(:last-child)::after { top: auto; bottom: -16px; left: 58px; right: auto; width: 1px; height: 16px; }
|
||||||
|
.principles { grid-template-columns: 1fr; }
|
||||||
|
.principle { padding: 28px 0 !important; border-left: 0 !important; }
|
||||||
|
.principle + .principle { border-top: 1px solid var(--mist); }
|
||||||
|
.tabs { grid-template-columns: 1fr; }
|
||||||
|
.tab-list { position: static; grid-auto-flow: column; grid-auto-columns: max-content; overflow-x: auto; padding-bottom: 6px; scrollbar-width: none; }
|
||||||
|
.tab-list::-webkit-scrollbar { display: none; }
|
||||||
|
.tab-btn { grid-template-columns: 32px auto; padding: 10px 16px 10px 10px; font-size: 14px; }
|
||||||
|
.tab-btn .ic { width: 32px; height: 32px; }
|
||||||
|
.tab-btn .arr { display: none; }
|
||||||
|
.tab-panel { padding: 32px; min-height: 0; }
|
||||||
|
.fp-copy { padding: 36px; }
|
||||||
|
.fp-visual { min-height: 320px; }
|
||||||
|
}
|
||||||
|
@media (max-width: 640px) {
|
||||||
|
:root { --gutter: 16px; --section-y: 64px; --nav-h: 64px; }
|
||||||
|
.brand-word { font-size: 13px; }
|
||||||
|
.hero { padding-top: 56px; }
|
||||||
|
.page-hero { padding-block: 48px 56px; }
|
||||||
|
.cluster { grid-template-columns: 1fr; margin-top: 48px; }
|
||||||
|
.dash-body { padding: 16px; }
|
||||||
|
.kpis { grid-template-columns: repeat(2, 1fr); }
|
||||||
|
.dash-cols { grid-template-columns: 1fr; }
|
||||||
|
.panel-url { display: none; }
|
||||||
|
.profile { max-width: 340px; width: 100%; justify-self: center; }
|
||||||
|
.features, .features-4, .cards-4, .ventures, .roles { grid-template-columns: 1fr; }
|
||||||
|
.feature { padding-block: 28px; }
|
||||||
|
.exit { min-height: 0; }
|
||||||
|
.exit h3 { margin-top: 12px; }
|
||||||
|
.stats { grid-template-columns: 1fr; }
|
||||||
|
.stat { padding: 24px 0 !important; border-left: 0 !important; }
|
||||||
|
.stat + .stat { border-top: 1px solid var(--mist); }
|
||||||
|
.showcase { padding: 24px; border-radius: 28px; }
|
||||||
|
.card, .card-lg { padding: 28px; border-radius: 28px; }
|
||||||
|
.industries { grid-template-columns: repeat(2, 1fr); }
|
||||||
|
.industry-note { grid-column: 1 / -1; }
|
||||||
|
.industry { padding: 18px; min-height: 100px; }
|
||||||
|
.industry b { font-size: 16px; }
|
||||||
|
.rule { grid-template-columns: 1fr; gap: 14px; padding-block: 28px; }
|
||||||
|
.rule .prose { grid-column: auto; }
|
||||||
|
.rule .index { padding-top: 0; }
|
||||||
|
.shout:nth-child(1) q { font-size: 20px; }
|
||||||
|
.shout:nth-child(2) q { font-size: 24px; }
|
||||||
|
.shout:nth-child(3) q { font-size: 28px; }
|
||||||
|
.tab-panel { padding: 24px; border-radius: 28px; }
|
||||||
|
.plan { padding: 28px 24px; }
|
||||||
|
.form-card { padding: 24px; }
|
||||||
|
.form-card .panel-bar { margin: -24px -24px 0; }
|
||||||
|
.form-grid { grid-template-columns: 1fr; }
|
||||||
|
.closing { padding: 56px 20px; border-radius: 28px; }
|
||||||
|
.cal-card { padding: 24px; }
|
||||||
|
.fp-copy { padding: 28px; }
|
||||||
|
.topic { grid-template-columns: 1fr; padding: 24px; }
|
||||||
|
.topic p { grid-column: auto; }
|
||||||
|
.foot-top { grid-template-columns: 1fr 1fr; gap: 36px; }
|
||||||
|
.foot-col:last-child { grid-column: 1 / -1; }
|
||||||
|
.btn { white-space: normal; text-align: center; }
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 34 34"><rect width="34" height="34" rx="10" fill="#594ff4"/><path d="M8 9h7.2c4.4 0 7.3 3.1 7.3 7.6 0 1.5-.3 2.8-.9 4L16.9 25H8l1.8-3.2h5.6c2.6 0 4.1-2 4.1-4.9 0-2.6-1.5-4.6-4.3-4.6h-5.3z" fill="#fff"/><path d="M27 8.5 18.3 25.5h4.2L27 16.8z" fill="#fff" opacity=".55"/></svg>
|
||||||
|
After Width: | Height: | Size: 330 B |
+13
@@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https://openapi.vercel.sh/vercel.json",
|
||||||
|
"buildCommand": "npm run build",
|
||||||
|
"outputDirectory": "dist",
|
||||||
|
"cleanUrls": true,
|
||||||
|
"trailingSlash": true,
|
||||||
|
"headers": [
|
||||||
|
{
|
||||||
|
"source": "/assets/(.*)",
|
||||||
|
"headers": [{ "key": "Cache-Control", "value": "public, max-age=604800, stale-while-revalidate=86400" }]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user