This commit is contained in:
@@ -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 1–15 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>
|
||||
|
||||
Reference in New Issue
Block a user