<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>{{.SiteTitle}} — template lab</title>
  <link rel="preconnect" href="https://fonts.googleapis.com" />
  <link href="https://fonts.googleapis.com/css2?family=Playfair+Display:ital,wght@0,400;0,700;1,400&family=JetBrains+Mono:wght@400;500&family=DM+Sans:wght@300;400;500&display=swap" rel="stylesheet" />
  <style>
    *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

    :root {
      --bg:        #0d0d0f;
      --surface:   #141416;
      --border:    #222226;
      --muted:     #3a3a40;
      --subtle:    #6b6b75;
      --body:      #c8c8d0;
      --heading:   #f0f0f4;
      --accent:    #e8c547;
      --accent2:   #5b8cff;
      --danger:    #ff6b6b;
      --mono:      'JetBrains Mono', monospace;
      --serif:     'Playfair Display', Georgia, serif;
      --sans:      'DM Sans', sans-serif;
    }

    html { background: var(--bg); color: var(--body); font-family: var(--sans); font-size: 16px; line-height: 1.6; }

    body { max-width: 1100px; margin: 0 auto; padding: 0 2rem 6rem; }

    /* ── Header ── */
    header {
      border-bottom: 1px solid var(--border);
      padding: 3rem 0 2rem;
      display: flex;
      justify-content: space-between;
      align-items: flex-end;
      gap: 1rem;
    }
    .site-title {
      font-family: var(--mono);
      font-size: .75rem;
      letter-spacing: .2em;
      text-transform: uppercase;
      color: var(--accent);
    }
    .site-headline {
      font-family: var(--serif);
      font-size: clamp(2rem, 5vw, 3.5rem);
      color: var(--heading);
      line-height: 1.1;
      margin-top: .4rem;
    }
    .site-headline em { color: var(--accent); font-style: italic; }
    .helper-count {
      font-family: var(--mono);
      font-size: .7rem;
      color: var(--subtle);
      text-align: right;
      white-space: nowrap;
    }

    /* ── Section label ── */
    .section-label {
      display: flex;
      align-items: center;
      gap: 1rem;
      margin: 4rem 0 1.5rem;
    }
    .section-label span {
      font-family: var(--mono);
      font-size: .65rem;
      letter-spacing: .15em;
      text-transform: uppercase;
      color: var(--accent);
      white-space: nowrap;
    }
    .section-label::after {
      content: '';
      flex: 1;
      height: 1px;
      background: var(--border);
    }

    /* ── Helper badge ── */
    .badge {
      display: inline-block;
      font-family: var(--mono);
      font-size: .6rem;
      letter-spacing: .08em;
      padding: .15em .5em;
      border-radius: 3px;
      border: 1px solid var(--muted);
      color: var(--subtle);
      vertical-align: middle;
      margin-left: .4rem;
    }
    .badge-accent { border-color: var(--accent); color: var(--accent); }
    .badge-blue   { border-color: var(--accent2); color: var(--accent2); }

    /* ── Demo block ── */
    .demo-grid {
      display: grid;
      grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
      gap: 1px;
      background: var(--border);
      border: 1px solid var(--border);
      border-radius: 8px;
      overflow: hidden;
    }
    .demo-cell {
      background: var(--surface);
      padding: 1.5rem;
    }
    .demo-cell h3 {
      font-family: var(--mono);
      font-size: .7rem;
      letter-spacing: .1em;
      text-transform: uppercase;
      color: var(--accent);
      margin-bottom: .75rem;
    }
    .demo-cell .result {
      font-size: 1rem;
      color: var(--heading);
    }
    .demo-cell .note {
      margin-top: .5rem;
      font-size: .75rem;
      color: var(--subtle);
      font-family: var(--mono);
    }

    /* ── Article cards ── */
    .article-list { display: flex; flex-direction: column; gap: 1px; background: var(--border); border: 1px solid var(--border); border-radius: 8px; overflow: hidden; }

    .article-card { background: var(--surface); padding: 2rem; display: grid; grid-template-columns: 1fr auto; gap: 1rem; align-items: start; transition: background .15s; }
    .article-card:hover { background: #18181c; }

    .card-meta { display: flex; align-items: center; gap: .75rem; flex-wrap: wrap; margin-bottom: .75rem; }
    .tag {
      font-family: var(--mono);
      font-size: .6rem;
      letter-spacing: .08em;
      text-transform: uppercase;
      padding: .2em .55em;
      background: var(--muted);
      border-radius: 3px;
      color: var(--body);
    }
    .tag-featured { background: color-mix(in srgb, var(--accent) 15%, transparent); color: var(--accent); }

    .card-title { font-family: var(--serif); font-size: 1.35rem; color: var(--heading); line-height: 1.25; margin-bottom: .5rem; }
    .card-subtitle { font-size: .85rem; color: var(--accent2); margin-bottom: .6rem; font-style: italic; }
    .card-excerpt { font-size: .875rem; color: var(--body); line-height: 1.65; }

    .card-author { display: flex; align-items: center; gap: .6rem; margin-top: 1.25rem; }
    .avatar {
      width: 32px; height: 32px; border-radius: 50%;
      background: var(--muted);
      display: flex; align-items: center; justify-content: center;
      font-family: var(--mono); font-size: .55rem; color: var(--accent);
      flex-shrink: 0;
    }
    .author-name { font-size: .8rem; color: var(--heading); }
    .author-date { font-size: .72rem; color: var(--subtle); font-family: var(--mono); }

    .card-aside { text-align: right; }
    .views { font-family: var(--mono); font-size: .75rem; color: var(--subtle); white-space: nowrap; }
    .views strong { color: var(--body); display: block; font-size: 1rem; }
    .price-badge {
      display: inline-block; margin-top: .75rem;
      font-family: var(--mono); font-size: .7rem;
      padding: .3em .7em; border-radius: 4px;
      background: color-mix(in srgb, var(--accent2) 15%, transparent);
      color: var(--accent2); border: 1px solid var(--accent2);
    }
    .price-free {
      background: color-mix(in srgb, #4caf50 12%, transparent);
      color: #6fcf97; border-color: #4caf50;
    }

    /* ── Logic demo table ── */
    .logic-table { width: 100%; border-collapse: collapse; font-size: .85rem; }
    .logic-table th {
      font-family: var(--mono); font-size: .65rem; letter-spacing: .1em; text-transform: uppercase;
      color: var(--subtle); text-align: left; padding: .6rem 1rem;
      border-bottom: 1px solid var(--border);
    }
    .logic-table td { padding: .75rem 1rem; border-bottom: 1px solid var(--border); color: var(--body); }
    .logic-table tr:last-child td { border-bottom: none; }
    .logic-table tr:hover td { background: var(--surface); }
    .val { font-family: var(--mono); font-size: .8rem; color: var(--accent); }

    /* ── Footer ── */
    footer {
      margin-top: 5rem; padding-top: 2rem; border-top: 1px solid var(--border);
      font-family: var(--mono); font-size: .65rem; color: var(--muted);
      display: flex; justify-content: space-between; flex-wrap: wrap; gap: .5rem;
    }
  </style>
</head>
<body>

<!-- ════════════════════════════════════════════
     HEADER
     ════════════════════════════════════════════ -->
<header>
  <div>
    <p class="site-title">{{.SiteTitle}}</p>
    <h1 class="site-headline">Template <em>helpers</em><br>in action</h1>
  </div>
  <p class="helper-count">22 helpers registered<br>across 6 groups</p>
</header>


<!-- ════════════════════════════════════════════
     STRING HELPERS
     ════════════════════════════════════════════ -->
<div class="section-label"><span>String helpers</span></div>

{{$first := first .Articles}}

<div class="demo-grid">

  <div class="demo-cell">
    <h3>capitalize <span class="badge">capitalize</span></h3>
    <p class="result">{{capitalize $first.Title}}</p>
    <p class="note">input: "{{$first.Title}}"</p>
  </div>

  <div class="demo-cell">
    <h3>truncate <span class="badge">truncate</span></h3>
    <p class="result">{{$first.Excerpt | truncate 80}}</p>
    <p class="note">capped at 80 chars</p>
  </div>

  <div class="demo-cell">
    <h3>prepend <span class="badge">prepend</span></h3>
    <p class="result">{{prepend $first.Slug "/articles/"}}</p>
    <p class="note">prepended "/articles/" to slug</p>
  </div>

  <div class="demo-cell">
    <h3>strAppend <span class="badge">strAppend</span></h3>
    <p class="result">{{strAppend $first.Slug ".html"}}</p>
    <p class="note">appended ".html" to slug</p>
  </div>

  <div class="demo-cell">
    <h3>split → join <span class="badge">split</span> <span class="badge">join</span></h3>
    {{$parts := split "go,templates,funcmap" ","}}
    <p class="result">{{join $parts " · "}}</p>
    <p class="note">split on "," then joined with " · "</p>
  </div>

</div>


<!-- ════════════════════════════════════════════
     NUMBER & DATE HELPERS
     ════════════════════════════════════════════ -->
<div class="section-label"><span>Number &amp; Date helpers</span></div>

<div class="demo-grid">

  <div class="demo-cell">
    <h3>fmtNumber — int <span class="badge">fmtNumber</span></h3>
    <p class="result">{{fmtNumber $first.Views}}</p>
    <p class="note">raw value: {{$first.Views}}</p>
  </div>

  {{$paid := index .Articles 2}}
  <div class="demo-cell">
    <h3>fmtNumber — float <span class="badge">fmtNumber</span></h3>
    <p class="result">$ {{fmtNumber $paid.Price}}</p>
    <p class="note">raw value: {{$paid.Price}}</p>
  </div>

  <div class="demo-cell">
    <h3>fmtDate "short" <span class="badge">fmtDate</span></h3>
    <p class="result">{{fmtDate $first.PublishedAt "short"}}</p>
    <p class="note">layout: "02 Jan 2006"</p>
  </div>

  <div class="demo-cell">
    <h3>fmtDate "long" <span class="badge">fmtDate</span></h3>
    <p class="result">{{fmtDate $first.PublishedAt "long"}}</p>
    <p class="note">layout: "02 January 2006"</p>
  </div>

  <div class="demo-cell">
    <h3>fmtDate "iso" <span class="badge">fmtDate</span></h3>
    <p class="result">{{fmtDate $first.PublishedAt "iso"}}</p>
    <p class="note">layout: "2006-01-02"</p>
  </div>

  <div class="demo-cell">
    <h3>timeAgo <span class="badge">timeAgo</span></h3>
    {{range .Articles}}
    <p class="result" style="margin-bottom:.3rem">{{timeAgo .PublishedAt}} <span class="note" style="display:inline">— {{fmtDate .PublishedAt "short"}}</span></p>
    {{end}}
  </div>

</div>


<!-- ════════════════════════════════════════════
     COLLECTION HELPERS
     ════════════════════════════════════════════ -->
<div class="section-label"><span>Collection helpers</span></div>

<div class="demo-grid">

  <div class="demo-cell">
    <h3>first <span class="badge">first</span></h3>
    {{with first .Articles}}
    <p class="result">{{capitalize .Title}}</p>
    <p class="note">first article in the list</p>
    {{end}}
  </div>

  <div class="demo-cell">
    <h3>last <span class="badge">last</span></h3>
    {{with last .Articles}}
    <p class="result">{{capitalize .Title}}</p>
    <p class="note">last article in the list</p>
    {{end}}
  </div>

  <div class="demo-cell">
    <h3>sliceOf 0–2 <span class="badge">sliceOf</span></h3>
    {{range sliceOf .Articles 0 2}}
    <p class="result" style="margin-bottom:.25rem">— {{capitalize .Title}}</p>
    {{end}}
    <p class="note">only first 2 of {{len .Articles}} articles</p>
  </div>

  <div class="demo-cell">
    <h3>contains — slice <span class="badge">contains</span></h3>
    {{if contains $first.Tags "go"}}
    <p class="result" style="color:var(--accent)">✓ has tag "go"</p>
    {{else}}
    <p class="result" style="color:var(--danger)">✗ missing tag "go"</p>
    {{end}}
    <p class="note">tags: {{join $first.Tags ", "}}</p>
  </div>

  <div class="demo-cell">
    <h3>contains — string <span class="badge">contains</span></h3>
    {{if contains $first.Excerpt "FuncMap"}}
    <p class="result" style="color:var(--accent)">✓ excerpt mentions "FuncMap"</p>
    {{else}}
    <p class="result" style="color:var(--danger)">✗ not found</p>
    {{end}}
    <p class="note">substring search on .Excerpt</p>
  </div>

  <div class="demo-cell">
    <h3>join <span class="badge">join</span></h3>
    <p class="result">{{join $first.Tags " / "}}</p>
    <p class="note">tags joined with " / "</p>
  </div>

</div>


<!-- ════════════════════════════════════════════
     LOGIC HELPERS
     ════════════════════════════════════════════ -->
<div class="section-label"><span>Logic helpers</span></div>

<table class="logic-table">
  <thead>
    <tr>
      <th>Helper</th>
      <th>Article</th>
      <th>Input</th>
      <th>Output</th>
    </tr>
  </thead>
  <tbody>
    {{range .Articles}}
    <tr>
      <td><span class="badge badge-accent">defaultVal</span></td>
      <td>{{.Title | capitalize | truncate 30}}</td>
      <td class="val">.Subtitle ({{if .Subtitle}}"{{.Subtitle}}"{{else}}empty{{end}})</td>
      <td class="val">{{defaultVal "No subtitle" .Subtitle}}</td>
    </tr>
    <tr>
      <td><span class="badge badge-blue">ternary</span></td>
      <td>{{capitalize .Title | truncate 30}}</td>
      <td class="val">.Featured = {{.Featured}}</td>
      <td class="val">{{ternary "⭐ featured" "regular" .Featured}}</td>
    </tr>
    <tr>
      <td><span class="badge badge-accent">coalesce</span></td>
      <td>{{capitalize .Title | truncate 30}}</td>
      <td class="val">.Subtitle → .Title</td>
      <td class="val">{{coalesce .Subtitle .Title}}</td>
    </tr>
    {{end}}
  </tbody>
</table>


<!-- ════════════════════════════════════════════
     FULL ARTICLE CARDS  (all helpers combined)
     ════════════════════════════════════════════ -->
<div class="section-label"><span>Full article cards — all helpers combined</span></div>

<div class="article-list">
  {{range .Articles}}
  <div class="article-card">
    <div>
      <div class="card-meta">
        {{if .Featured}}<span class="tag tag-featured">featured</span>{{end}}
        {{range .Tags}}<span class="tag">{{.}}</span>{{end}}
      </div>

      <h2 class="card-title">{{capitalize .Title}}</h2>

      {{with coalesce .Subtitle ""}}
        <p class="card-subtitle">{{.}}</p>
      {{end}}

      <p class="card-excerpt">{{.Excerpt | truncate 160}}</p>

      <a style="font-family:var(--mono);font-size:.7rem;color:var(--accent2);text-decoration:none;margin-top:.75rem;display:inline-block;"
         href="{{prepend .Slug "/articles/"}}">
        {{prepend .Slug "/articles/"}} →
      </a>

      <div class="card-author">
        <div class="avatar">{{.Author.Avatar}}</div>
        <div>
          <div class="author-name">{{capitalize .Author.Name}}</div>
          <div class="author-date">
            {{fmtDate .PublishedAt "short"}} · {{timeAgo .PublishedAt}}
          </div>
        </div>
      </div>
    </div>

    <div class="card-aside">
      <div class="views">
        <strong>{{fmtNumber .Views}}</strong>
        views
      </div>
      {{if gt .Price 0.0}}
        <span class="price-badge">$ {{fmtNumber .Price}}</span>
      {{else}}
        <span class="price-badge price-free">free</span>
      {{end}}
    </div>
  </div>
  {{end}}
</div>


<!-- ════════════════════════════════════════════
     FOOTER
     ════════════════════════════════════════════ -->
<footer>
  <span>{{.SiteTitle}} / template sandbox</span>
  <span>{{len .Articles}} articles · {{fmtDate (first .Articles).PublishedAt "iso"}} → {{fmtDate (last .Articles).PublishedAt "iso"}}</span>
</footer>

</body>
</html>