---
import { getCollection } from 'astro:content';
import BaseLayout from '../layouts/BaseLayout.astro';
import NavBar from '../components/NavBar.astro';
import { getReadingTime } from '../utils/reading-time';

const posts = await getCollection('posts');
const sortedPosts = posts.sort((a, b) => b.data.date.getTime() - a.data.date.getTime());
const base = import.meta.env.BASE_URL.replace(/\/?$/, '/');

// Match rage series titles to actual published posts by slug
const ragePosts: Record<string, string> = {
  'Your Build Cache Is Lying to You': 'your-build-cache-is-lying-to-you',
  'Two-Phase Fingerprinting: BuildXL\u2019s Deep Magic': 'two-phase-fingerprinting-buildxls-deep-magic',
  'Hooking Syscalls Without a Kernel Driver': 'hooking-syscalls-without-a-kernel-driver',
  'TypeScript 7 Makes the Build Harness More Important': 'typescript-7-makes-the-build-harness-more-important',
};

const rageDescriptions = [
  'The silent stale cache problem. Every JS monorepo build cache shares this flaw.',
  'Weak fingerprints find candidates. Strong fingerprints verify them. The pathset is the bridge.',
  'Three operating systems. Three interception mechanisms. macOS interpose, Linux eBPF, Windows Detours.',
  'Counter-intuitive: tsgo\u2019s 10x speedup makes distributed coordination more important, not less.',
  'Per-package content-addressed storage. The unsexy problem that kills CI build times.',
  'Personal narrative. From lage maintainer to Rust rewrite. The architecture\u2019s original sin.',
];

const rageSeries = [
  'Your Build Cache Is Lying to You',
  'Two-Phase Fingerprinting: BuildXL\u2019s Deep Magic',
  'Hooking Syscalls Without a Kernel Driver',
  'TypeScript 7 Makes the Build Harness More Important',
  'node_modules in a Content-Addressed Store',
  'What I Learned Maintaining Lage and Why I Rewrote It',
].map((title, i) => {
  const slug = ragePosts[title];
  const post = slug ? posts.find(p => p.id === slug) : null;
  return {
    title,
    slug: slug || null,
    published: !!post,
    readingTime: post?.body ? getReadingTime(post.body) : null,
    number: i + 1,
    description: rageDescriptions[i],
  };
});
---

<BaseLayout title='Crash Test Dev'>
  <NavBar slot="nav" />

  <!-- Hero: full-width, two-column -->
  <section class="hero" aria-label="Introduction">
    <div class="hero-text">
      <h1 class="site-title">Crash Test Dev</h1>
      <p class="tagline">Engineering judgment, tested against reality.</p>
      <p class="byline">By Ken Chau</p>
    </div>
    <div class="hero-illustration" aria-hidden="true">
      <img src={`${base}images/hero-concept.png`} alt="Crash Test Dev concept illustration: layered system architecture in warm editorial style" width="1536" height="1024" loading="eager" />
    </div>
  </section>

  <!-- Featured excerpt: full-width with visual -->
  <section class="featured" aria-label="Featured excerpt">
    <div class="featured-inner">
      <div class="featured-content">
        <p class="featured-label">From the series</p>
        <blockquote class="excerpt">
          Your CI passed. Your tests passed. The build cache said nothing changed. It was wrong. You shipped a broken build to production because a cache returned stale output from three weeks ago. The bug took two days to find. The fix was one line. The root cause was not your code. It was your build system's trust model.
        </blockquote>
        <a class="featured-link" href={`${base}posts/your-build-cache-is-lying-to-you/`}>
          Read "Your Build Cache Is Lying to You" &rarr;
        </a>
      </div>
      <div class="featured-diagram" aria-hidden="true">
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 420 200" role="img" aria-label="The Silent Lie: how an undeclared input causes a stale cache hit">
          <rect width="420" height="200" fill="#F5F0E8" rx="4"/>
          <text x="210" y="24" text-anchor="middle" font-family="Georgia, serif" font-size="12" font-weight="bold" fill="#2B2421">The Silent Lie</text>
          <rect x="14" y="40" width="100" height="44" rx="3" fill="none" stroke="#2B2421" stroke-width="1.2"/>
          <text x="64" y="58" text-anchor="middle" font-family="monospace" font-size="8" fill="#2B2421">Developer changes</text>
          <text x="64" y="72" text-anchor="middle" font-family="monospace" font-size="8" font-weight="bold" fill="#A0522D">feature-flags.json</text>
          <line x1="114" y1="62" x2="136" y2="62" stroke="#2B2421" stroke-width="1.2"/>
          <polygon points="134,58 142,62 134,66" fill="#2B2421"/>
          <rect x="144" y="40" width="100" height="44" rx="3" fill="none" stroke="#2B2421" stroke-width="1.2"/>
          <text x="194" y="56" text-anchor="middle" font-family="monospace" font-size="7.5" fill="#2B2421">Cache check:</text>
          <text x="194" y="68" text-anchor="middle" font-family="monospace" font-size="7.5" fill="#2B2421">hash(src/**/*.ts)</text>
          <text x="194" y="78" text-anchor="middle" font-family="monospace" font-size="7.5" fill="#2B2421">Nothing changed</text>
          <line x1="244" y1="62" x2="266" y2="62" stroke="#2B2421" stroke-width="1.2"/>
          <polygon points="264,58 272,62 264,66" fill="#2B2421"/>
          <rect x="274" y="40" width="60" height="44" rx="3" fill="#A0522D"/>
          <text x="304" y="60" text-anchor="middle" font-family="Georgia, serif" font-size="11" font-weight="bold" fill="#F5F0E8">MATCH</text>
          <text x="304" y="74" text-anchor="middle" font-family="monospace" font-size="7" fill="#F5F0E8">(stale!)</text>
          <line x1="334" y1="62" x2="356" y2="62" stroke="#2B2421" stroke-width="1.2"/>
          <polygon points="354,58 362,62 354,66" fill="#2B2421"/>
          <rect x="364" y="44" width="44" height="36" rx="3" fill="#A0522D"/>
          <text x="386" y="62" text-anchor="middle" font-family="Georgia, serif" font-size="8" font-weight="bold" fill="#F5F0E8">Bug ships</text>
          <text x="386" y="72" text-anchor="middle" font-family="Georgia, serif" font-size="8" font-weight="bold" fill="#F5F0E8">to prod</text>
          <rect x="120" y="110" width="200" height="36" rx="3" fill="none" stroke="#A0522D" stroke-width="1" stroke-dasharray="4,2"/>
          <text x="220" y="128" text-anchor="middle" font-family="Georgia, serif" font-size="9" fill="#A0522D">feature-flags.json was never declared.</text>
          <text x="220" y="140" text-anchor="middle" font-family="Georgia, serif" font-size="9" fill="#A0522D">The cache didn't know it existed.</text>
        </svg>
      </div>
    </div>
  </section>

  <!-- Rage Series: 2-column grid at container width -->
  <section class="series" aria-label="Rage series">
    <h2 class="section-heading">Rage: Rebuilding the Build System</h2>
    <p class="series-description">A six-part investigation into rage, a Rust monorepo build system that fuses BuildXL's provable correctness with lage's ergonomics. From syscall sandboxing to content-addressed storage.</p>
    <div class="series-grid">
      {rageSeries.map((item) => (
        <div class={`series-card ${item.published ? 'published' : ''}`}>
          <span class="card-number">{String(item.number).padStart(2, '0')}</span>
          <div class="card-body">
            <span class="card-title">{item.title}</span>
            <span class="card-description">{item.description}</span>
            {item.published ? (
              <a href={`${base}posts/${item.slug}/`} class="card-link">
                Read &middot; {item.readingTime} min
              </a>
            ) : (
              <span class="card-status">Coming soon</span>
            )}
          </div>
        </div>
      ))}
    </div>
  </section>

  <!-- All Posts: compact 2-column grid at reading width -->
  <section class="all-posts" aria-label="All posts">
    <h2 class="section-heading">All Posts</h2>
    <div class="posts-grid">
      {sortedPosts.map((post) => (
        <article class="post-entry">
          <a href={`${base}posts/${post.id}/`} class="post-entry-link">
            <span class="post-entry-badge">{post.data.type}</span>
            <span class="post-entry-title">{post.data.title}</span>
            {post.body && (
              <span class="post-entry-meta">{getReadingTime(post.body)} min</span>
            )}
          </a>
        </article>
      ))}
    </div>
  </section>
</BaseLayout>

<style>
  /* ── Hero: full-width two-column ────────────────────────────── */
  .hero {
    max-width: 100%;
    display: grid;
    grid-template-columns: 1fr 1fr;
    align-items: center;
    gap: var(--space-6);
    padding: var(--space-10) var(--space-8);
    border-bottom: 1px solid var(--border-subtle);
  }

  .hero-text {
    max-width: 540px;
    justify-self: end;
  }

  .site-title {
    font-family: var(--font-structure);
    font-size: var(--type-3xl);
    font-weight: 700;
    color: var(--text-primary);
    line-height: var(--leading-tight);
    letter-spacing: -0.02em;
    margin-bottom: var(--space-2);
  }

  .tagline {
    font-family: var(--font-prose);
    font-size: var(--type-lg);
    color: var(--text-secondary);
    line-height: var(--leading-prose);
    font-style: italic;
    margin-bottom: var(--space-1-5);
  }

  .byline {
    font-family: var(--font-structure);
    font-size: var(--type-sm);
    color: var(--text-tertiary);
    letter-spacing: 0.03em;
    text-transform: uppercase;
  }

  .hero-illustration {
    max-width: 400px;
    justify-self: start;
  }

  .hero-illustration img {
    width: 100%;
    height: auto;
    border-radius: var(--rounded-lg);
    box-shadow: var(--shadow-md);
  }

  /* ── Featured excerpt: full-width with terracotta border ────── */
  .featured {
    max-width: var(--width-container);
    margin-left: auto;
    margin-right: auto;
    padding: var(--space-8) 0;
    border-left: 4px solid var(--accent-primary);
    margin-top: var(--space-6);
    margin-bottom: var(--space-6);
  }

  .featured-inner {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--space-6);
    align-items: center;
    padding-left: var(--space-4);
  }

  .featured-label {
    font-family: var(--font-structure);
    font-size: var(--type-xs);
    font-weight: 600;
    color: var(--accent-primary);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    margin-bottom: var(--space-2);
  }

  .excerpt {
    font-family: var(--font-prose);
    font-size: var(--type-lg);
    color: var(--text-primary);
    line-height: var(--leading-prose);
    margin-bottom: var(--space-3);
    font-style: italic;
  }

  .featured-link {
    font-family: var(--font-structure);
    font-size: var(--type-sm);
    font-weight: 500;
  }

  .featured-diagram svg {
    width: 100%;
    height: auto;
    border-radius: var(--rounded-md);
    box-shadow: var(--shadow-sm);
  }

  /* ── Series: container-width 2-column grid ─────────────────── */
  .series {
    max-width: var(--width-container);
    margin-left: auto;
    margin-right: auto;
    margin-bottom: var(--space-8);
    padding: var(--space-6) 0;
  }

  .section-heading {
    font-family: var(--font-structure);
    font-size: var(--type-xl);
    font-weight: 600;
    color: var(--text-primary);
    line-height: var(--leading-snug);
    margin-bottom: var(--space-1-5);
  }

  .series-description {
    font-family: var(--font-prose);
    font-size: var(--type-base);
    color: var(--text-secondary);
    line-height: var(--leading-prose);
    margin-bottom: var(--space-4);
    max-width: var(--width-prose);
  }

  .series-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--space-3);
  }

  .series-card {
    background: var(--surface-card);
    border: 1px solid var(--border-subtle);
    border-radius: var(--rounded-lg);
    padding: var(--space-3);
    box-shadow: var(--shadow-sm);
    display: flex;
    gap: var(--space-2);
    align-items: flex-start;
    transition: box-shadow var(--duration-normal) var(--ease-default);
  }

  .series-card:hover {
    box-shadow: var(--shadow-md);
  }

  .series-card.published {
    border-color: var(--border-default);
  }

  .card-number {
    font-family: var(--font-evidence);
    font-size: var(--type-xl);
    font-weight: 700;
    color: var(--accent-primary);
    line-height: 1;
    flex-shrink: 0;
  }

  .card-body {
    display: flex;
    flex-direction: column;
    gap: var(--space-0-5);
  }

  .card-title {
    font-family: var(--font-structure);
    font-size: var(--type-base);
    font-weight: 600;
    color: var(--text-primary);
    line-height: var(--leading-snug);
  }

  .card-description {
    font-family: var(--font-prose);
    font-size: var(--type-sm);
    color: var(--text-secondary);
    line-height: var(--leading-normal);
  }

  .card-link {
    font-family: var(--font-structure);
    font-size: var(--type-sm);
    font-weight: 500;
    margin-top: var(--space-0-5);
    transition: color var(--duration-fast) var(--ease-default);
  }

  .card-status {
    font-family: var(--font-evidence);
    font-size: var(--type-xs);
    color: var(--text-tertiary);
    margin-top: var(--space-0-5);
    background: var(--surface-inset);
    padding: var(--space-0-5) var(--space-1);
    border-radius: var(--rounded-full);
    display: inline-block;
    width: fit-content;
  }

  /* ── All posts: reading-width 2-column grid ────────────────── */
  .all-posts {
    max-width: var(--width-prose);
    margin-left: auto;
    margin-right: auto;
    margin-bottom: var(--space-12);
    padding: var(--space-6) 0;
  }

  .all-posts .section-heading {
    margin-bottom: var(--space-3);
  }

  .posts-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0 var(--space-4);
  }

  .post-entry {
    border-bottom: 1px solid var(--border-subtle);
  }

  .post-entry-link {
    display: flex;
    align-items: baseline;
    gap: var(--space-1-5);
    padding: var(--space-1-5) 0;
    text-decoration: none;
    color: inherit;
    transition: color var(--duration-fast) var(--ease-default);
  }

  .post-entry-link:hover {
    text-decoration: none;
  }

  .post-entry-link:hover .post-entry-title {
    color: var(--accent-primary);
  }

  .post-entry-badge {
    font-family: var(--font-structure);
    font-size: var(--type-xs);
    font-weight: 600;
    color: var(--accent-primary);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    flex-shrink: 0;
  }

  .post-entry-title {
    font-family: var(--font-structure);
    font-size: var(--type-base);
    font-weight: 500;
    color: var(--text-primary);
    flex: 1;
    transition: color var(--duration-fast) var(--ease-default);
  }

  .post-entry-meta {
    font-family: var(--font-evidence);
    font-size: var(--type-xs);
    color: var(--text-tertiary);
    flex-shrink: 0;
  }

  /* ── Responsive: tablet ────────────────────────────────────── */
  @media (max-width: 1023px) {
    .hero {
      padding: var(--space-8) var(--space-4);
      gap: var(--space-4);
    }

    .hero-text {
      max-width: none;
    }

    .hero-illustration {
      max-width: 320px;
    }

    .featured-inner {
      grid-template-columns: 1fr 1fr;
    }

    .posts-grid {
      grid-template-columns: 1fr;
    }
  }

  /* ── Responsive: mobile ────────────────────────────────────── */
  @media (max-width: 768px) {
    .hero {
      grid-template-columns: 1fr;
      text-align: center;
      padding: var(--space-6) var(--space-3);
      gap: var(--space-4);
    }

    .hero-text {
      justify-self: center;
    }

    .hero-illustration {
      justify-self: center;
      max-width: 280px;
    }

    .featured {
      border-left: none;
      border-top: 4px solid var(--accent-primary);
      padding: var(--space-4) 0;
    }

    .featured-inner {
      grid-template-columns: 1fr;
      padding-left: 0;
    }

    .series-grid {
      grid-template-columns: 1fr;
    }

    .posts-grid {
      grid-template-columns: 1fr;
    }
  }
</style>
