---
/**
 * TemplatingShowcase - the personalization section. One artifact proves the
 * pitch (one template renders into a different email per recipient), then a
 * feature grid covers the whole engine. Everything shown mirrors the real
 * renderer (internal/tasks/template.go, internal/pkg/tmplfuncs, spintax.go):
 *
 *   - merge fields {{.FirstName}} + custom CSV fields, spaces allowed
 *   - fallbacks:   {{.FirstName | default "there"}}
 *   - conditionals if / else / end, eq, and / or, coercing numeric compares
 *   - helpers:     title, lower, contains, add / sub / mul / div
 *   - spintax:     {Hi|Hey|Hello}, nested, subject and body
 *   - A/B variants per step, same editor and preview
 *   - preview runs the real send engine; a broken {{if}} blocks launch;
 *     a failed render falls back to plain substitution, never a dead send
 */
import SectionHead from './SectionHead.astro';
import Icon from './Icon.astro';

// Three recipients through the same template: the Engineer branch, the else
// branch, and the default fallback for a contact with no first name. Each
// carries chips naming the features that fired.
const results = [
  {
    who: 'Alex Rivera',
    meta: 'alex@acme.com · role: Engineer',
    grad: 'from-sky-400 to-indigo-400',
    parts: [
      { t: 'Hey', c: 'spin' }, { t: ' ' }, { t: 'Alex', c: 'field' }, { t: ', we built this for teams like yours.' },
    ],
    chips: ['spintax picked Hey', 'if branch: Engineer'],
  },
  {
    who: 'Jenna Carter',
    meta: 'jenna@northwind.dev · role: Founder',
    grad: 'from-rose-400 to-amber-400',
    parts: [
      { t: 'Hi', c: 'spin' }, { t: ' ' }, { t: 'Jenna', c: 'field' }, { t: ', thought this might be useful for ' }, { t: 'Northwind', c: 'field' }, { t: '.' },
    ],
    chips: ['else branch', '{{.Company}}'],
  },
  {
    who: 'No first name',
    meta: 'mail@brightco.io · role: empty',
    grad: 'from-slate-300 to-slate-400',
    parts: [
      { t: 'Hello', c: 'spin' }, { t: ' ' }, { t: 'there', c: 'fall' }, { t: ', thought this might be useful for ' }, { t: 'Brightco', c: 'field' }, { t: '.' },
    ],
    chips: ['default "there"', 'blank never breaks'],
  },
];

const features = [
  {
    icon: 'database',
    title: 'Every field, including yours',
    body: 'Standard fields plus every column from your CSV import. Keys with spaces or dashes work everywhere, even inside conditions.',
    code: '{{.job title}}',
  },
  {
    icon: 'cog',
    title: 'Helper functions',
    body: 'Case and string helpers, arithmetic, and numeric compares that coerce strings, so number-like fields just work.',
    code: '{{if gtf .employees 50}}',
  },
  {
    icon: 'shuffle',
    title: 'Spintax, nested',
    body: 'Alternation groups resolve innermost first and nest freely. Subjects spin too, so no two sends read identical.',
    code: '{Hi|Hey {there|again}}',
  },
  {
    icon: 'flask',
    title: 'A/B variants per step',
    body: 'Test variants of any step. The original and every variant share the same editor, preview and content score.',
    code: 'Variant B · 50%',
  },
  {
    icon: 'search',
    title: 'Previewed with the real engine',
    body: 'The composer renders your template with the actual send engine against sample data. Conditionals, functions and spintax all run.',
    code: 'Hey Alex,',
  },
  {
    icon: 'shield',
    title: 'Validated before launch',
    body: 'A broken {{if}} blocks the campaign and unresolved tokens get flagged. A failing render falls back to plain substitution, never a lost send.',
    code: 'if: missing {{end}}',
  },
];
---
<section class="tpl py-20 md:py-28">
  <div class="container-page">
    <SectionHead
      eyebrow="Personalization"
      title="One template. A different email for every recipient."
      description="Every step is a template rendered at send time. Merge fields, conditionals, helpers and spintax resolve per recipient, and the composer shows the exact result before you launch."
    />

    <!-- ── Artifact: template -> three rendered emails ───────────── -->
    <div class="tpl-stage relative overflow-hidden mt-12 md:mt-14 rounded-[18px] p-5 sm:p-7 lg:p-9"
         style="background: linear-gradient(175deg, #fbfcfe 0%, var(--surface-2) 100%); box-shadow: inset 0 0 0 1px var(--border);">
      <span class="tpl-texture absolute inset-0 pointer-events-none"></span>

      <div class="relative grid lg:grid-cols-2 gap-5 lg:gap-8 items-center">
        <!-- The template, written once. -->
        <div class="tpl-code rounded-[12px] overflow-hidden bg-[#0c1224] ring-1 ring-white/10 shadow-[0_26px_60px_-20px_rgb(8_25_45_/_0.55)]">
          <div class="h-9 px-4 border-b border-white/[0.06] bg-white/[0.03] flex items-center gap-2">
            <span class="text-[9.5px] uppercase tracking-[0.14em] font-mono text-white/40">Step 1 · template</span>
            <span class="ml-auto text-[10px] font-mono text-white/30">written once</span>
          </div>
          <pre class="p-4 sm:p-5 font-mono text-[12px] sm:text-[12.5px] leading-[1.85] text-white/85 overflow-x-auto"><code><span style="color:#6ee7b7">{`{Hi|Hey|Hello}`}</span> <span style="color:#7dd3fc">{`{{.FirstName`}</span> <span style="color:#c4b5fd">| default</span> <span style="color:#fde68a">"there"</span><span style="color:#7dd3fc">{`}}`}</span>,

<span style="color:#c4b5fd">{`{{if eq`}</span> <span style="color:#7dd3fc">.role</span> <span style="color:#fde68a">"Engineer"</span><span style="color:#c4b5fd">{`}}`}</span>we built this for
teams like yours.<span style="color:#c4b5fd">{`{{else}}`}</span>thought this might
be useful for <span style="color:#7dd3fc">{`{{.Company}}`}</span>.<span style="color:#c4b5fd">{`{{end}}`}</span></code></pre>
        </div>

        <!-- What each recipient actually receives. -->
        <div class="space-y-3">
          {results.map((r, i) => (
            <div class="tpl-result rounded-[12px] bg-white ring-1 ring-slate-200 shadow-[0_10px_30px_-18px_rgb(15_23_42_/_0.25)] p-4" style={`--i:${i}`}>
              <div class="flex items-center gap-2.5">
                <span class={`w-6 h-6 rounded-full shrink-0 bg-gradient-to-br ${r.grad}`}></span>
                <span class="text-[12px] font-semibold text-slate-900">{r.who}</span>
                <span class="text-[10.5px] font-mono text-slate-400 truncate">{r.meta}</span>
              </div>
              <p class="mt-2.5 text-[12.5px] leading-relaxed text-slate-700">
                {r.parts.map((p) => (
                  p.c
                    ? <span class:list={[
                        'rounded px-[3px]',
                        p.c === 'spin' && 'bg-emerald-50 text-emerald-700',
                        p.c === 'field' && 'bg-sky-50 text-sky-700',
                        p.c === 'fall' && 'bg-amber-50 text-amber-700',
                      ]}>{p.t}</span>
                    : p.t
                ))}
              </p>
              <div class="mt-2.5 flex flex-wrap gap-1.5">
                {r.chips.map((c) => (
                  <span class="inline-flex items-center h-5 px-1.5 rounded text-[9.5px] font-mono text-slate-500 bg-slate-50 ring-1 ring-slate-200">{c}</span>
                ))}
              </div>
            </div>
          ))}
        </div>
      </div>

      <div class="relative mt-5 flex items-center justify-center gap-2 text-[11px] font-mono uppercase tracking-[0.14em] text-muted-foreground">
        <Icon name="zap" size={11} class="text-[color:var(--brand)]" />
        rendered per recipient, at send time
      </div>
    </div>

    <!-- ── The whole engine ──────────────────────────────────────── -->
    <div class="mt-5 grid sm:grid-cols-2 lg:grid-cols-3 gap-3">
      {features.map((f) => (
        <div class="rounded-[14px] bg-white ring-1 ring-[color:var(--border)] p-5" style="box-shadow: var(--shadow-sm);">
          <div class="flex items-center gap-2.5">
            <span class="grid place-items-center w-7 h-7 rounded-md bg-[color:var(--brand-soft)] text-[color:var(--brand)]">
              <Icon name={f.icon} size={14} />
            </span>
            <h3 class="text-[14px] font-semibold tracking-[-0.01em] text-heading">{f.title}</h3>
          </div>
          <p class="mt-2.5 text-[13px] leading-relaxed text-foreground/65">{f.body}</p>
          <code class="mt-3.5 inline-flex items-center h-6 px-2 rounded-md bg-[#0c1224] text-[11px] font-mono text-sky-300 ring-1 ring-white/10">{f.code}</code>
        </div>
      ))}
    </div>
  </div>
</section>

<style>
  .tpl-texture {
    background-image: radial-gradient(circle, rgb(15 23 42 / 0.07) 1px, transparent 1.2px);
    background-size: 14px 14px;
    -webkit-mask-image: radial-gradient(ellipse at 50% 45%, #000 30%, transparent 80%);
    mask-image: radial-gradient(ellipse at 50% 45%, #000 30%, transparent 80%);
  }

  /* Motion is gated on .is-live (observer below), so nothing runs off screen. */
  @media (prefers-reduced-motion: no-preference) {
    .tpl.js-ready .tpl-code,
    .tpl.js-ready .tpl-result { opacity: 0; }
    .tpl.is-live .tpl-code {
      animation: tpl-rise 620ms cubic-bezier(0.22, 1, 0.36, 1) both;
    }
    .tpl.is-live .tpl-result {
      animation: tpl-rise 520ms cubic-bezier(0.22, 1, 0.36, 1) both,
                 tpl-spot 9s ease-in-out infinite;
      animation-delay: calc(var(--i) * 140ms + 200ms), calc(var(--i) * 3s + 1.2s);
    }
  }

  @keyframes tpl-rise {
    from { opacity: 0; transform: translateY(12px); }
    to   { opacity: 1; transform: none; }
  }
  /* A soft spotlight visits each rendered email in turn: one template, three
     different emails, forever. */
  @keyframes tpl-spot {
    0%, 30%, 100% { box-shadow: 0 10px 30px -18px rgb(15 23 42 / 0.25); }
    8%, 22% {
      box-shadow: 0 18px 44px -18px rgb(2 132 199 / 0.35), 0 0 0 1.5px var(--brand);
      transform: translateY(-2px);
    }
  }
</style>

<script is:inline>
  // Arm hidden start states only when JS runs, so a script failure leaves
  // the section fully visible.
  document.querySelectorAll('.tpl').forEach((el) => el.classList.add('js-ready'));
</script>

<script>
  const tpl = document.querySelector('.tpl');
  if (tpl) {
    new IntersectionObserver(
      (entries) => entries.forEach((e) => tpl.classList.toggle('is-live', e.isIntersecting)),
      { threshold: 0.12 },
    ).observe(tpl);
  }
</script>
