<!doctype html>
<!--
  AVA-SPOTTER REPORT TEMPLATE. How to fill it in:

  1. Copy this whole file exactly. Change ONE thing only: the JSON between
     the two lines "REPORT DATA STARTS" and "REPORT DATA ENDS" further down.
     Do not change the HTML, the CSS or the script. They draw the report.
  2. Replace the example JSON with your findings. Keep the same keys:
     - "title": the piece's own headline, if it has one, or a few words
       saying what it is. A headline goes here and not in "paragraphs".
     - "about": one short line on what kind of writing it is, e.g. "LinkedIn post".
     - "date": today's date, written out, e.g. "14 October 2026".
     - "verdict": "label" is exactly one of "Reads naturally",
       "A few AI habits", "Lots of AI habits". "summary" is one sentence.
     - "paragraphs": the writer's text, one string per paragraph, copied
       exactly (its headline goes in "title" instead). Do not tidy, correct
       or shorten it (except as step 5 allows).
     - "marks": the sentences or phrases you mark, in the order they appear.
       "kind" is exactly "ai", "suspicious" or "human". "phrase" is copied
       character for character from "paragraphs" (same apostrophes, dashes
       and capitals), or the report cannot find it. "name" is the tell's
       name. "why" is one or two sentences about this piece. "couldTry" is
       one line starting "You could", for "ai" marks; leave it "" otherwise.
     - "themes": the bigger patterns from your passes, each with a short
       "heading" and a "body" paragraph. Content first, then structure,
       then tone.
     - "newerTells": tells you found by searching the web, each with its
       "name" and the "sources" (web addresses) you found it in. Use [] if
       you did not search.
     - "skipped": "" normally. For a long piece where you left paragraphs
       out, one sentence saying so.
  3. Inside the JSON, put a backslash before any double quote in your text:
     \"like this\". Use straight quotes for the JSON itself. Don't add
     comments or trailing commas. Never write "</script" inside the JSON.
  4. Give it to the person the best way you can: in a Claude HTML artifact
     if you are Claude; otherwise as a file ending in .html (for example
     ava-spotter-report.html); otherwise in one code block, with these
     three lines BEFORE it:
       1. Wait for me to finish writing the code (the box below stops growing).
       2. Press the download button on the code box (the arrow).
       3. Open the file you downloaded. It opens in your web browser.
     Never use an editing canvas (Gemini's Canvas): it stops being a web page.
  5. For a piece over about 600 words, put only the paragraphs with marks
     in "paragraphs", and say what you left out in "skipped".
-->
<html lang="en-GB">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Ava-spotter report</title>
<link rel="preconnect" href="https://fonts.bunny.net">
<link rel="stylesheet" href="https://fonts.bunny.net/css?family=hanken-grotesk:400,500,700,900&display=swap">
<style>
  :root {
    --ground: #F4F3EE; --card: #FFFFFF; --ink: #111110; --muted: #4C483E; --line: #DAD8CF;
    --hazard: #E8FF00; --olive: #4D5300; --blue: #1D67A8; --green: #1B7A43;
    --blue-wash: #D6E3EF; --green-wash: #D3E7DA;
    --font: "Hanken Grotesk", system-ui, -apple-system, "Segoe UI", sans-serif;
  }
  * { box-sizing: border-box; }
  body { margin: 0; background: var(--ground); color: var(--ink); font: 400 17px/1.6 var(--font);
    background-image: linear-gradient(#fff 1px, transparent 1px), linear-gradient(90deg, #fff 1px, transparent 1px);
    background-size: 96px 96px; -webkit-font-smoothing: antialiased; }
  .page { max-width: 1180px; margin: 0 auto; padding: 40px 24px 56px; }
  .brand { display: flex; align-items: center; gap: 18px; }
  .logo { display: inline-flex; flex-direction: column; align-items: center; gap: 2px; color: var(--ink); text-decoration: none; font-weight: 800; font-size: 15px; letter-spacing: -0.01em; line-height: 1; }
  .logo svg { width: 44px; height: 44px; margin: -4px; }
  .logo:hover span { text-decoration: underline; }
  .tool { padding-left: 18px; border-left: 1px solid var(--line); font-weight: 700; }
  .brand small { margin-left: auto; color: var(--muted); font-weight: 400; font-size: 14px; }
  h1 { font-size: clamp(34px, 6vw, 60px); line-height: 1; font-weight: 900; letter-spacing: -0.02em; margin: 40px 0 8px; }
  .about { color: var(--muted); margin: 0 0 28px; }
  .verdict { display: flex; flex-wrap: wrap; align-items: center; gap: 16px 20px; margin-bottom: 28px; }
  .stamp { display: inline-block; border: 2.5px solid var(--ink); border-radius: 6px; padding: 6px 14px; font-weight: 900; font-size: 18px; transform: rotate(-3deg); background: var(--card); }
  .verdict p { margin: 0; font-size: 20px; font-weight: 500; max-width: 46ch; }
  .counts { display: flex; flex-wrap: wrap; gap: 8px 18px; margin: 0 0 24px; padding: 0; list-style: none; font-size: 15px; }
  .counts li { display: inline-flex; align-items: center; gap: 8px; }
  .swatch { width: 26px; height: 12px; border-radius: 3px; display: inline-block; }
  .swatch--ai { background: var(--hazard); box-shadow: inset 0 0 0 1px var(--ink); }
  .swatch--suspicious { background: var(--blue); }
  .swatch--human { background: var(--green); }
  .markup { position: relative; display: grid; grid-template-columns: minmax(0, 1fr); gap: 24px; }
  .piece { align-self: start; background: var(--card); border: 1px solid var(--line); border-radius: 14px; padding: 32px 36px; font-size: 18px; line-height: 1.95; }
  .piece p { margin: 0 0 1em; } .piece p:last-child { margin: 0; }
  .tell { color: inherit; background: none; padding: 0 1px; border-radius: 3px; }
  .tell--ai { background: var(--hazard); box-decoration-break: clone; -webkit-box-decoration-break: clone; }
  .tell--suspicious { text-decoration: underline 2px var(--blue); text-underline-offset: 0.3em; color: var(--blue); }
  .tell--human { text-decoration: underline 2px var(--green); text-underline-offset: 0.3em; color: var(--green); }
  .tell sup { font-size: 11px; font-weight: 700; margin-left: 2px; }
  .notes { list-style: none; margin: 0; padding: 0; display: grid; gap: 14px; }
  .note { background: var(--card); border: 1px solid var(--line); border-radius: 12px; padding: 14px 16px; font-size: 15px; line-height: 1.5; }
  .note h3 { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin: 0 0 6px; font-size: 16px; }
  .num { display: inline-grid; place-items: center; width: 22px; height: 22px; border-radius: 50%; font-size: 12px; font-weight: 700; }
  .note--ai .num { background: var(--hazard); box-shadow: inset 0 0 0 1px var(--ink); }
  .note--suspicious .num { background: var(--blue); color: #fff; } .note--human .num { background: var(--green); color: #fff; }
  .chip { font-size: 12px; font-weight: 500; border: 1px solid currentColor; border-radius: 4px; padding: 0 7px; }
  .note--ai .chip { color: var(--olive); } .note--suspicious .chip { color: var(--blue); } .note--human .chip { color: var(--green); }
  .note q { display: block; font-style: italic; margin: 0 0 6px; }
  .note p { margin: 0; color: var(--muted); }
  .note .could { margin-top: 8px; color: var(--ink); }
  .note .lost { color: #B3261E; font-size: 13px; margin-top: 6px; }
  .leaders { position: absolute; inset: 0; pointer-events: none; overflow: visible; }
  .leaders path { fill: none; stroke-width: 1.5; }
  h2 { font-size: 30px; font-weight: 900; letter-spacing: -0.01em; margin: 56px 0 18px; }
  .themes { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 16px; }
  .theme { background: var(--card); border: 1px solid var(--line); border-top: 4px solid var(--ink); border-radius: 12px; padding: 18px 20px; }
  .theme h3 { margin: 0 0 8px; font-size: 19px; line-height: 1.3; }
  .theme p { margin: 0; color: var(--muted); }
  .newer { font-size: 14px; color: var(--muted); margin-top: 32px; }
  .cta { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 16px 32px; margin-top: 56px; padding: 24px 28px; border: 1px solid var(--line); border-radius: 14px; background: var(--card); }
  .cta p { margin: 0; font-size: 19px; line-height: 1.4; }
  .cta p span { color: var(--muted); }
  .cta-actions { display: flex; flex-wrap: wrap; gap: 10px; }
  .button { display: inline-flex; align-items: center; padding: 11px 18px; border-radius: 8px; font-weight: 700; font-size: 15px; text-decoration: none; color: var(--ink); }
  .button--main { background: var(--hazard); box-shadow: inset 0 0 0 1px var(--ink); }
  .button--quiet { box-shadow: inset 0 0 0 1px var(--line); }
  .button:hover { filter: brightness(0.96); }
  .newer a { color: var(--olive); }
  .skipped { color: var(--muted); font-size: 15px; margin: 12px 0 0; }
  footer a { color: inherit; }
  .print-notes, .print-only { display: none; }
  footer { margin-top: 48px; padding-top: 16px; border-top: 1px solid var(--line); font-size: 13px; color: var(--muted); display: flex; flex-wrap: wrap; gap: 6px 24px; }
  @media (min-width: 960px) {
    .markup.is-placed { grid-template-columns: minmax(0, 1fr) 340px; column-gap: 72px; }
    .markup.is-placed .notes { display: block; position: relative; }
    .markup.is-placed .note { position: absolute; left: 0; right: 0; }
  }
  /* Printed: A4, a page number and the maker in the margin. */
  @page { size: A4; margin: 15mm 15mm 17mm;
    @bottom-left { content: "Ava-spotter, by Avapond \00B7  avapond.com"; font: 8pt "Hanken Grotesk", sans-serif; color: #4C483E; }
    @bottom-right { content: counter(page) " / " counter(pages); font: 8pt "Hanken Grotesk", sans-serif; color: #4C483E; } }
  @media print {
    body { background: #fff; font-size: 10.5pt; line-height: 1.55; } .page { padding: 0; max-width: none; }
    h1 { font-size: 26pt; margin: 14pt 0 4pt; text-wrap: balance; } .about { margin-bottom: 14pt; }
    .verdict { margin-bottom: 12pt; break-inside: avoid; } .verdict p { font-size: 12.5pt; } .counts { margin-bottom: 12pt; }
    /* On paper each note follows its paragraph, so nobody turns pages to find what a number means. */
    .markup, .markup.is-placed { display: block; } .notes, .leaders { display: none; } .notes.has-lost { display: grid; gap: 8pt; margin-top: 10pt; }
    .note[data-printed] { display: none; }
    /* The writing's card may run over a page; each page's part gets its own edges. */
    .piece { padding: 16pt 18pt; font-size: 11pt; line-height: 1.8; border-radius: 10pt; box-decoration-break: clone; -webkit-box-decoration-break: clone; }
    .piece p { break-inside: avoid; orphans: 3; widows: 3; }
    .print-notes { display: grid; gap: 6pt; list-style: none; margin: -2pt 0 16pt; padding: 0 0 0 12pt; border-left: 1px solid var(--line); }
    .print-notes .note { padding: 7pt 10pt; font-size: 9pt; line-height: 1.45; break-inside: avoid; }
    .print-notes .note h3 { font-size: 10pt; margin-bottom: 3pt; } .print-notes .note q { margin-bottom: 3pt; }
    /* A heading always lands with what it introduces. */
    h2 { font-size: 18pt; margin: 22pt 0 10pt; break-after: avoid; }
    .themes { grid-template-columns: 1fr 1fr; gap: 10pt; } .theme { padding: 10pt 12pt; break-inside: avoid; } .theme h3 { font-size: 11.5pt; }
    .cta { margin-top: 22pt; padding: 14pt 16pt; break-inside: avoid; } .cta p { font-size: 12pt; }
    footer { margin-top: 18pt; font-size: 8.5pt; } .screen-only { display: none; }
    .tell--ai, .swatch, .num, .stamp, .logo svg, .button--main { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
  }
</style>
</head>
<body>
<div class="page">
  <header class="brand">
    <a class="logo" href="https://avapond.com/?utm_source=ava-spotter&amp;utm_medium=report" target="_blank" rel="noopener" aria-label="Avapond, avapond.com"><svg viewBox="-8 -9.13 85.27 85.27" aria-hidden="true"><g fill="#707070"><rect x="0" y="0" width="18" height="18" rx="2.5"/><rect x="24.5" y="0" width="18" height="18" rx="2.5"/><rect x="49" y="0" width="18" height="18" rx="2.5"/><rect x="0" y="24.5" width="18" height="18" rx="2.5"/><rect x="49" y="24.5" width="18" height="18" rx="2.5"/><rect x="0" y="49" width="18" height="18" rx="2.5"/><rect x="24.5" y="49" width="18" height="18" rx="2.5"/><rect x="49" y="49" width="18" height="18" rx="2.5"/></g><rect x="-9" y="-9" width="18" height="18" rx="2.5" transform="translate(56.6 21.6) rotate(30)" fill="#E8FF00" stroke="#111110" stroke-width="0.75"/></svg><span>avapond</span></a>
    <span class="tool">Ava-spotter</span>
    <small id="date"></small>
  </header>
  <h1 id="title"></h1>
  <p class="about" id="about"></p>
  <div class="verdict"><span class="stamp" id="stamp"></span><p id="summary"></p></div>
  <ul class="counts" id="counts"></ul>
  <section class="markup" id="markup">
    <article class="piece" id="piece"></article>
    <ol class="notes" id="notes"></ol>
    <svg class="leaders" id="leaders" aria-hidden="true"></svg>
  </section>
  <p class="skipped" id="skipped"></p>
  <h2 id="themes-heading">The bigger picture</h2>
  <div class="themes" id="themes"></div>
  <div class="newer" id="newer"></div>
  <aside class="cta">
    <p>Need help solving your business problems? <span>That's what we do.</span></p>
    <div class="cta-actions">
      <a class="button button--main" href="https://avapond.com/?utm_source=ava-spotter&amp;utm_medium=report" target="_blank" rel="noopener">Learn about us</a>
      <a class="button button--quiet" href="https://avapond.com/contact?utm_source=ava-spotter&amp;utm_medium=report" target="_blank" rel="noopener">Get in touch</a>
    </div>
  </aside>
  <footer><span>Ava-spotter, by Avapond · <a href="https://avapond.com/?utm_source=ava-spotter&amp;utm_medium=report" target="_blank" rel="noopener">avapond.com</a></span><span>A tell is a habit, not proof. This reads the writing, never the writer.</span><span class="screen-only">To keep a PDF: print this page and choose Save as PDF.</span></footer>
</div>
<noscript><p style="padding:24px">This report needs JavaScript to draw. Open it in a web browser such as Chrome, Safari, Edge or Firefox.</p></noscript>

<!-- REPORT DATA STARTS -->
<script type="application/json" id="report-data">
{
  "title": "Acme Brewery: October newsletter",
  "about": "Brewery newsletter",
  "date": "14 October 2026",
  "verdict": { "label": "A few AI habits", "summary": "Mostly a person with real news, with a few warm, empty phrases an AI likes to add." },
  "paragraphs": [
    "October was a big month at Acme Brewery. We finally replaced the bottling machine, which had been held together with cable ties since March. The new one has quietly transformed how we work."
  ],
  "marks": [
    { "kind": "human", "phrase": "held together with cable ties", "name": "Too specific to invent", "why": "A concrete, unglamorous detail that only someone at the brewery would know.", "couldTry": "" },
    { "kind": "ai", "phrase": "quietly transformed", "name": "Quietly", "why": "AI's favourite new word. There's nothing quiet about a new bottling machine.", "couldTry": "You could say what changed: \"The new one bottles three times as fast.\"" }
  ],
  "themes": [
    { "heading": "Real detail, padded with warm words", "body": "The facts are specific and believable. The AI-sounding lines are the ones that tell you how to feel instead of what happened." }
  ],
  "newerTells": [],
  "skipped": ""
}
</script>
<!-- REPORT DATA ENDS -->

<script>
(function () {
  var data = JSON.parse(document.getElementById('report-data').textContent);
  var LABEL = { ai: 'AI tell', suspicious: 'Suspicious', human: 'Probably human' };
  var COLOUR = { ai: '#4D5300', suspicious: '#1D67A8', human: '#1B7A43' };
  var kindOf = function (mark) { return LABEL[mark.kind] ? mark.kind : 'ai'; };
  var make = function (tag, className, text) { var el = document.createElement(tag); if (className) el.className = className; if (text) el.textContent = text; return el; };
  var set = function (id, text) { document.getElementById(id).textContent = text || ''; };

  set('title', (data.title || '').trim() || 'Ava-spotter report');
  set('about', data.about); set('date', data.date);
  set('stamp', data.verdict && data.verdict.label); set('summary', data.verdict && data.verdict.summary);
  set('skipped', data.skipped);

  var marks = (data.marks || []).map(function (mark, at) { return { mark: mark, number: at + 1, kind: kindOf(mark), found: false }; });

  // The counts, as a key: one line per kind that appears.
  var counts = document.getElementById('counts');
  ['ai', 'suspicious', 'human'].forEach(function (kind) {
    var n = marks.filter(function (each) { return each.kind === kind; }).length;
    if (!n) return;
    var li = make('li'); li.appendChild(make('span', 'swatch swatch--' + kind));
    li.appendChild(document.createTextNode(n + ' ' + (kind === 'ai' ? (n === 1 ? 'AI tell' : 'AI tells') : kind === 'suspicious' ? 'suspicious' : 'probably human')));
    counts.appendChild(li);
  });

  // The piece: each paragraph, with each mark's phrase found in reading order and wrapped.
  var piece = document.getElementById('piece');
  var queue = marks.slice();
  var placed = [];
  (data.paragraphs || []).forEach(function (text) {
    var p = make('p'); var rest = String(text); var here = [];
    while (rest) {
      var best = null, bestAt = -1;
      queue.forEach(function (each) { var at = rest.indexOf(each.mark.phrase); if (each.mark.phrase && at >= 0 && (bestAt < 0 || at < bestAt)) { best = each; bestAt = at; } });
      if (!best) { p.appendChild(document.createTextNode(rest)); break; }
      p.appendChild(document.createTextNode(rest.slice(0, bestAt)));
      var mark = make('mark', 'tell tell--' + best.kind, best.mark.phrase);
      mark.setAttribute('data-n', best.number); mark.appendChild(make('sup', '', String(best.number)));
      p.appendChild(mark); best.found = true; here.push(best.number); queue.splice(queue.indexOf(best), 1);
      rest = rest.slice(bestAt + best.mark.phrase.length);
    }
    piece.appendChild(p); placed.push({ p: p, numbers: here });
  });

  // The notes: one pull-out per mark.
  var notes = document.getElementById('notes');
  marks.forEach(function (each) {
    var li = make('li', 'note note--' + each.kind); li.setAttribute('data-n', each.number);
    var h3 = make('h3'); h3.appendChild(make('span', 'num', String(each.number)));
    h3.appendChild(document.createTextNode(each.mark.name || LABEL[each.kind])); h3.appendChild(make('span', 'chip', LABEL[each.kind]));
    li.appendChild(h3); li.appendChild(make('q', '', each.mark.phrase)); li.appendChild(make('p', '', each.mark.why));
    if (each.kind === 'ai' && each.mark.couldTry) li.appendChild(make('p', 'could', each.mark.couldTry));
    if (!each.found) li.appendChild(make('p', 'lost', 'This phrase isn\'t word for word in the text, so it isn\'t marked above.'));
    notes.appendChild(li);
  });

  // For print: each paragraph followed by its own notes (hidden on screen, where the leader lines do this).
  placed.forEach(function (entry) {
    if (!entry.numbers.length) return;
    var list = make('ol', 'print-notes'); list.setAttribute('aria-hidden', 'true');
    entry.numbers.forEach(function (n) { var original = notes.querySelector('.note[data-n="' + n + '"]'); if (!original) return; list.appendChild(original.cloneNode(true)); original.setAttribute('data-printed', ''); });
    entry.p.parentNode.insertBefore(list, entry.p.nextSibling);
  });
  if (notes.querySelector('.note:not([data-printed])')) notes.classList.add('has-lost');

  // The themes: one box each, heading and paragraph.
  var themes = document.getElementById('themes');
  (data.themes || []).forEach(function (theme) { var box = make('section', 'theme'); box.appendChild(make('h3', '', theme.heading)); box.appendChild(make('p', '', theme.body)); themes.appendChild(box); });
  if (!(data.themes || []).length) document.getElementById('themes-heading').hidden = true;

  // Newer tells found on the web, with where they were found.
  var newer = document.getElementById('newer');
  if ((data.newerTells || []).length) {
    newer.appendChild(make('p', '', 'Newer tells checked for, from the web:'));
    var list = make('ul');
    data.newerTells.forEach(function (tell) {
      var li = make('li', '', (tell.name || '') + ' ');
      (tell.sources || []).forEach(function (url, at) { var a = make('a', '', '[' + (at + 1) + ']'); a.href = url; a.target = '_blank'; a.rel = 'noopener'; li.appendChild(a); li.appendChild(document.createTextNode(' ')); });
      list.appendChild(li);
    });
    newer.appendChild(list);
  }

  // On a wide screen: each note beside its mark, joined by a line. Narrow screens and print list them after the piece.
  var markup = document.getElementById('markup'), svg = document.getElementById('leaders');
  var wide = window.matchMedia('(min-width: 960px)');
  function place() {
    svg.innerHTML = '';
    var items = Array.prototype.slice.call(notes.children);
    items.forEach(function (li) { li.style.top = ''; });
    if (!wide.matches) { markup.classList.remove('is-placed'); notes.style.height = ''; return; }
    markup.classList.add('is-placed');
    var box = markup.getBoundingClientRect(), notesBox = notes.getBoundingClientRect(), floor = 0;
    items.forEach(function (li) {
      var mark = piece.querySelector('mark[data-n="' + li.getAttribute('data-n') + '"]');
      var want = mark ? mark.getBoundingClientRect().top - notesBox.top - 8 : floor;
      var top = Math.max(want, floor); li.style.top = top + 'px'; floor = top + li.offsetHeight + 14;
      if (!mark) return;
      // From the card's edge, level with the mark's last line (never through the writing), to the note.
      var rects = mark.getClientRects(), last = rects[rects.length - 1], colour = COLOUR[li.className.split('note--')[1]] || '#111110';
      var x1 = piece.getBoundingClientRect().right - box.left, y1 = (last.top + last.bottom) / 2 - box.top;
      var x2 = notesBox.left - box.left, y2 = notesBox.top - box.top + top + 20, bend = x1 + (x2 - x1) / 2;
      var path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
      path.setAttribute('d', 'M' + x1 + ' ' + y1 + ' H' + bend + ' V' + y2 + ' H' + x2);
      path.setAttribute('stroke', colour);
      var dot = document.createElementNS('http://www.w3.org/2000/svg', 'circle');
      dot.setAttribute('cx', x1); dot.setAttribute('cy', y1); dot.setAttribute('r', 3.5); dot.setAttribute('fill', colour);
      svg.appendChild(path); svg.appendChild(dot);
    });
    notes.style.height = floor + 'px';
    svg.setAttribute('width', box.width); svg.setAttribute('height', Math.max(box.height, floor));
  }
  place();
  window.addEventListener('resize', place);
  if (document.fonts && document.fonts.ready) document.fonts.ready.then(place);
  window.addEventListener('beforeprint', function () { markup.classList.remove('is-placed'); svg.innerHTML = ''; notes.style.height = ''; Array.prototype.forEach.call(notes.children, function (li) { li.style.top = ''; }); });
  window.addEventListener('afterprint', place);
})();
</script>
</body>
</html>
