Now, with services!
Some checks failed
ci/woodpecker/pr/ci Pipeline failed

This commit is contained in:
2026-03-09 18:09:12 -03:00
parent 164ba69010
commit 1e0afb103c
64 changed files with 2365 additions and 2562 deletions

View File

@@ -1,307 +1,44 @@
<script lang="ts">
import Navigation from '$lib/components/Navigation.svelte';
import ExternalLinkIcon from '$lib/components/Icon/ExternalLink.svelte';
import Hero from '$lib/components/Hero.svelte';
import ScheduleSection from '$lib/components/ScheduleSection.svelte';
const discoveryCallUrl =
'https://cal.mifi.ventures/the-mifi/30min?utm_source=website&utm_medium=cta&utm_campaign=schedule_call&utm_content=services_landing';
const navItems = [
{ label: 'Home', href: '/', umamiEventLabel: 'home' },
{ label: 'Services', href: '#services-grid', umamiEventLabel: 'services' },
{ label: 'How engagements work', href: '#how-engagements-work', umamiEventLabel: 'engagements' },
{
label: 'Book a call',
href: `${discoveryCallUrl}-navigation`,
umamiEventLabel: 'book-call',
},
];
const services = [
{
title: 'Hands-On SaaS Architecture',
description:
'Build the foundations that allow SaaS products to evolve without accumulating structural debt. I work directly inside your codebase to improve frontend systems, establish reusable components, and create architecture that supports long-term iteration.',
href: '/services/hands-on-saas-architecture-consultant',
},
{
title: 'MVP Architecture & Launch',
description:
'Ship your product quickly without creating a fragile system you\'ll have to rewrite six months later. I help teams design and build MVPs that are simple, scalable, and structured for rapid iteration.',
href: '/services/mvp-architecture-and-launch',
},
{
title: 'Fractional CTO / Technical Partner',
description:
'Technical leadership for teams that need architectural direction but aren\'t ready for a full-time CTO. I work alongside founders and engineers to guide system design, evaluate technical decisions, and maintain long-term architectural clarity.',
href: '/services/fractional-cto-for-early-stage-saas',
},
{
title: 'Stage-Aligned Infrastructure',
description:
'Infrastructure decisions should match your company\'s stage. I help teams avoid unnecessary SaaS sprawl and cloud complexity while building infrastructure that can grow with the product.',
href: '/services/stage-aligned-infrastructure',
},
];
import ServicesCardGrid from '$lib/components/ServicesCardGrid.svelte';
import EngagementsDl from '$lib/components/EngagementsDl.svelte';
import { pageContent } from '$lib/data/services/landing/content';
</script>
<Navigation items={navItems} page="services" />
<Navigation items={pageContent.navItems} page="services" />
<header id="header" class="services-hero">
<div class="container">
<h1 class="services-hero__title">Consulting Services</h1>
<p class="services-hero__subhead">
I work with early-stage SaaS teams to build products that ship quickly and evolve cleanly.
Engagements range from hands-on architecture work inside your codebase to technical
leadership for growing teams.
</p>
<div class="cta-group">
<a
href={discoveryCallUrl}
class="btn btn-primary icon-button"
target="_blank"
rel="noopener noreferrer"
aria-label="Schedule a discovery call (opens in new tab)"
data-umami-event="schedule discovery call"
data-umami-event-location="services hero"
>
Schedule a discovery call
<ExternalLinkIcon aria-label="Opens in new tab" size={17} />
</a>
<a
href="/#process"
class="btn btn-secondary"
data-umami-event="see how i work"
data-umami-event-location="services hero"
>
See how I work
</a>
</div>
</div>
</header>
<Hero {...pageContent.hero} />
<main id="main">
<section class="section services-intro" aria-labelledby="intro-heading">
<div class="container container--narrow">
<h2 id="intro-heading" class="sr-only">How we work together</h2>
<p>
Early-stage SaaS companies face different technical challenges as they grow. Some
need help building their MVP correctly. Others need architectural guidance as
complexity increases. Some teams simply need a senior engineer who can step in and
stabilize a chaotic codebase.
</p>
<p>
The services below represent the most common ways I work with founders and
engineering teams.
</p>
{#each pageContent.introParagraphs as p}
<p>{p}</p>
{/each}
</div>
</section>
<section id="services-grid" class="section services-grid-section" aria-labelledby="services-heading">
<div class="container">
<h2 id="services-heading" class="section-title">Services</h2>
<ul class="services-card-list">
{#each services as service (service.href)}
<li class="services-card">
<h3 class="services-card__title">{service.title}</h3>
<p class="services-card__desc">{service.description}</p>
<a
href={service.href}
class="services-card__link"
data-umami-event="service link"
data-umami-event-label={service.href}
>
Learn more
<span aria-hidden="true"></span>
</a>
</li>
{/each}
</ul>
</div>
</section>
<ServicesCardGrid services={pageContent.services} />
<section id="how-engagements-work" class="section" aria-labelledby="engagements-heading">
<div class="container container--narrow">
<h2 id="engagements-heading">How engagements work</h2>
<p>Most engagements fall into one of three patterns:</p>
<dl class="engagements-list">
<dt>Architecture engagements</dt>
<dd>
Focused, fixed-scope projects designed to diagnose and correct structural issues
in a codebase.
</dd>
<dt>Implementation work</dt>
<dd>
Hands-on engineering to build or refactor core product systems.
</dd>
<dt>Advisory retainers</dt>
<dd>
Ongoing architectural guidance for teams that need senior technical oversight.
</dd>
</dl>
<p>Engagements are typically consulting-led and scoped to deliver meaningful progress quickly.</p>
</div>
</section>
<EngagementsDl
items={pageContent.engagements}
intro={pageContent.engagementsIntro}
outro={pageContent.engagementsOutro}
/>
<section class="section services-ideal" aria-labelledby="ideal-heading">
<div class="container container--narrow">
<h2 id="ideal-heading">Ideal clients</h2>
<ul class="content-list">
<li>Founder-led SaaS startups</li>
<li>Engineering teams with 115 developers</li>
<li>Products that are actively shipping and evolving</li>
<li>Teams that value thoughtful engineering decisions</li>
{#each pageContent.idealClients as item}
<li>{item}</li>
{/each}
</ul>
</div>
</section>
<ScheduleSection
title="Not sure which service fits?"
subtitle="Many engagements start with a short conversation about your product and technical challenges. From there we can determine whether architecture work, MVP support, or ongoing technical leadership makes the most sense."
bookingLinkTitle="Schedule a discovery call"
bookingLinkUrl={`${discoveryCallUrl}-schedule-section`}
showEmailLink
/>
<ScheduleSection {...pageContent.scheduleCta} />
</main>
<style>
.services-hero {
padding: var(--space-xxxl) 0 var(--space-xxl) 0;
text-align: center;
background-color: var(--color-bg);
border-bottom: 1px solid var(--color-border);
}
.services-hero__title {
margin-bottom: var(--space-lg);
font-family: var(--font-family-heading);
font-size: var(--font-size-xxl);
font-weight: var(--font-weight-bold);
letter-spacing: -0.03em;
}
.services-hero__subhead {
max-width: var(--max-narrow-width);
margin: 0 auto var(--space-xl) auto;
font-size: var(--font-size-large);
font-weight: var(--font-weight-normal);
color: var(--color-text-secondary);
line-height: var(--line-height-relaxed);
}
.cta-group {
display: flex;
flex-wrap: wrap;
gap: var(--space-md);
justify-content: center;
align-items: center;
margin-top: var(--space-lg);
}
@media (max-width: 768px) {
.cta-group {
flex-direction: column;
width: 100%;
}
}
.container--narrow {
max-width: var(--max-narrow-width);
}
.services-intro {
background-color: var(--color-bg-alt);
}
.services-grid-section {
background-color: var(--color-bg);
}
.services-card-list {
list-style: none;
margin: 0;
padding: 0;
display: grid;
gap: var(--space-xl);
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
}
.services-card {
padding: var(--space-xl);
background-color: var(--color-bg-alt);
border: 1px solid var(--color-border);
border-radius: var(--border-radius-medium);
display: flex;
flex-direction: column;
}
.services-card__title {
margin-bottom: var(--space-md);
font-size: var(--font-size-large);
font-weight: var(--font-weight-semibold);
}
.services-card__desc {
flex: 1;
margin-bottom: var(--space-lg);
font-size: var(--font-size-base);
color: var(--color-text-secondary);
line-height: var(--line-height-relaxed);
}
.services-card__link {
display: inline-flex;
align-items: center;
gap: var(--space-xs);
font-weight: var(--font-weight-semibold);
}
.services-card__link span {
margin-left: var(--space-xs);
}
.engagements-list {
margin: var(--space-lg) 0;
}
.engagements-list dt {
font-weight: var(--font-weight-semibold);
color: var(--color-text);
margin-top: var(--space-lg);
margin-bottom: var(--space-xs);
}
.engagements-list dt:first-child {
margin-top: 0;
}
.engagements-list dd {
margin: 0 0 0 var(--space-md);
color: var(--color-text-secondary);
line-height: var(--line-height-relaxed);
}
.services-ideal {
background-color: var(--color-bg-alt);
}
.schedule-section {
text-align: center;
background-color: var(--color-bg-subtle);
}
.schedule-text {
margin-bottom: var(--space-lg);
font-size: var(--font-size-large);
font-weight: var(--font-weight-normal);
color: var(--color-text-secondary);
line-height: var(--line-height-relaxed);
max-width: var(--max-text-width);
margin-left: auto;
margin-right: auto;
}
[id] {
scroll-margin-top: 6rem;
}
</style>