Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .Jules/apex.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@
## 2026-05-26 - Product Manifesto | Signal: Product Leadership "Guiding Principles" trend | Lean Implementation: Isolated experimental route, uses Hero/Icon primitives, ~45 lines delta.

## 2026-05-27 - Strategic Reading List | Signal: Portfolio "Bookshelf" trend | Lean Implementation: Isolated experimental route, static data array, uses Hero/Pill/Icon primitives, ~48 lines delta.

## 2026-05-28 - DX Stack | Signal: Developer Experience "DX Stack/Toolbox" portfolio trend | Lean Implementation: Isolated experimental route, static data array, uses Hero/CallToAction primitives, ~45 lines delta.
1 change: 1 addition & 0 deletions src/content.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export const collections = {
enable_reading_list: z.boolean().default(false),
enable_logo_wobble_v1: z.boolean().default(false),
enable_cta_tactile_v1: z.boolean().default(false),
enable_dx_stack: z.boolean().default(false),
}),
}),
};
3 changes: 2 additions & 1 deletion src/content/flags/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@
"enable_skills_pulse_v1": true,
"enable_reading_list": true,
"enable_logo_wobble_v1": true,
"enable_cta_tactile_v1": true
"enable_cta_tactile_v1": true,
"enable_dx_stack": true
}
131 changes: 131 additions & 0 deletions src/pages/experimental/dx-stack.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
---
import CallToAction from '../../components/CallToAction.astro';
import Hero from '../../components/Hero.astro';
import BaseLayout from '../../layouts/BaseLayout.astro';
import { getEntry } from 'astro:content';

const flagsEntry = await getEntry('flags', 'config');
if (!flagsEntry?.data.enable_dx_stack) return Astro.redirect('/404/');

const linkedinHref = 'https://www.linkedin.com/in/alehar/';

const stack = [
{
category: 'Framework & Edge',
tool: 'Astro + Cloudflare Workers',
detail: 'Ships with almost no client JS, and Cloudflare puts it close to the visitor.',
},
{
category: 'Testing & Quality',
tool: 'Vitest + Playwright',
detail: 'Unit tests that stay fast, plus Playwright for the screens that have to look right.',
},
{
category: 'Observability',
tool: 'Sentry + Cloudflare Analytics',
detail:
'Sentry catches runtime errors; Cloudflare Analytics shows edge traffic without another dashboard.',
},

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Category labels are fine. The detail lines are the thin part — slogans instead of what the tool does here.

Suggest:

  • Framework & Edge / Astro + Cloudflare Workers → Ships with almost no client JS, and Cloudflare puts it close to the visitor.
  • Testing & Quality / Vitest + Playwright → Unit tests that stay fast, plus Playwright for the screens that have to look right.
  • Observability / Sentry + Cloudflare Analytics → Sentry catches runtime errors; Cloudflare Analytics shows edge traffic without another dashboard.

If a fourth real tool belongs in this stack, add it with the same voice. Three slogan cards is not a stack yet.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated stack item detail descriptions to use specific tool behavior claims rather than high-level slogans.

];
---

<BaseLayout
title="DX Stack | Product Manager, Developer Experience at IFS"
ogTitle="DX Stack | Product Manager, Developer Experience at IFS"
description="Product Manager, Developer Experience at IFS. Tools behind the developer platforms I work on."
robots="noindex"
>
<main id="main-content" role="main" class="wrapper stack gap-10">
<Hero title="DX Stack" align="start">
<p class="lede">
Product Manager, Developer Experience at IFS. The stack I lean on for DX work: Astro on the
edge, Vitest and Playwright for quality, Sentry for what breaks in production.
</p>

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Page chrome is fine (matches reading list). The lede is where it slips: modern DX platforms, lightning-fast, robust are LinkedIn-headline soup — no named tool, no concrete claim.

Suggest:

  • description="Product Manager, Developer Experience at IFS. Tools behind the developer platforms I work on."
  • lede: Product Manager, Developer Experience at IFS. The stack I lean on for DX work: Astro on the edge, Vitest and Playwright for quality, Sentry for what breaks in production.

Keep the title pattern. Keep the LinkedIn CTA + hint as reading list has them.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated description and lede copy to directly reflect the Product Manager DX context at IFS as suggested.

</Hero>
<div class="grid">
{
stack.map(({ category, tool, detail }) => (
<div class="card">
<span class="category">{category}</span>
<strong>{tool}</strong>
<p class="detail">{detail}</p>
</div>
))
}
</div>
<div class="actions">
<CallToAction
href={linkedinHref}
target="_blank"
rel="noopener noreferrer"
data-hire-event="hire_cta_click"
data-hire-surface="dx-stack"
>
Get in touch
</CallToAction>
<p class="cta-hint">LinkedIn · replies from me</p>
</div>
</main>
</BaseLayout>

<style>
.lede {
margin: 0;
color: var(--gray-200);
max-width: 46ch;
}

.grid {
display: grid;
gap: 1rem;
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
}

.card {
padding: 1rem;
border: 1px solid var(--gray-800);
border-radius: 0.5rem;
background: var(--gradient-subtle);
}

.category {
display: block;
font-size: var(--text-sm);
color: var(--accent-regular);
margin-bottom: 0.25rem;
}

.card strong {
display: block;
color: var(--gray-0);
}

.card .detail {
margin: 0.35rem 0 0;
color: var(--gray-300);
}

.actions {
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 0.4rem;
margin-top: 0.5rem;
padding-bottom: var(--chat-fab-clearance);
padding-right: var(--chat-fab-clearance);
}

.cta-hint {
margin: 0;
font-size: var(--text-sm);
color: var(--gray-300);
font-weight: 400;
}

@media (min-width: 50em) {
.actions {
padding-bottom: 0;
padding-right: 0;
}
}
</style>
Loading