diff --git a/CHANGELOG.md b/CHANGELOG.md
index c70513d..4876811 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,6 +8,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
Routine `stats.json` refreshes take a PATCH version bump but are grouped rather than
listed individually.
+## [0.28.0] - 2026-09-22
+
+### Changed
+- Manufacturing leads with *Last night, on the fleet*: four live counters (machines watched, flagged abnormal, work orders raised, weeks of data) from `agent-demo.json`, and one chart — six weeks of cycle deviation per machine, flagged machines in the line colour with direct labels, the rest muted, an "approved" reference, hover for the verdict, a table view. Replaces the four static marketing tiles. Counters animate unless the reader prefers reduced motion.
+
## [0.27.0] - 2026-09-22
### Added
diff --git a/VERSION b/VERSION
index 1b58cc1..697f087 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-0.27.0
+0.28.0
diff --git a/public/design/components.css b/public/design/components.css
index 0276429..ce8dd76 100644
--- a/public/design/components.css
+++ b/public/design/components.css
@@ -200,6 +200,9 @@
.viz-median { fill: var(--line, var(--brand)); stroke: var(--surface-1); stroke-width: 2; }
.viz-bar { fill: var(--line, var(--brand)); }
.viz-bar:hover, .viz-range:hover { opacity: 0.85; }
+.viz-line { stroke: var(--ink-muted); opacity: 0.45; stroke-linejoin: round; stroke-linecap: round; }
+.viz-line--flag { stroke: var(--line, var(--brand)); opacity: 1; }
+.viz-line:hover { opacity: 1; }
/* ── v0.20.1: contact panel — one form, one quiet address line ─────────── */
.contact-panel { display: grid; gap: var(--s-4); max-width: 520px; }
diff --git a/src/components/AgentPulse.astro b/src/components/AgentPulse.astro
new file mode 100644
index 0000000..8e2c4e0
--- /dev/null
+++ b/src/components/AgentPulse.astro
@@ -0,0 +1,105 @@
+---
+// Last night's agent cycle as numbers and one chart, drawn client-side from
+// agent-demo.json (the same file AgentDemo reads). Replaces the four static
+// marketing tiles: what the reader sees moved last night, and says when.
+// One axis, one hue; abnormal machines carry the line colour and a direct
+// label, the rest are muted; hover any line for the machine and its verdict.
+interface Props {
+ heading: string; lead: string;
+ tiles: { machines: string; abnormal: string; workOrders: string; weeks: string };
+ chart: { title: string; yLabel: string; refLabel: string; tableCaption: string; colMachine: string; colDeviation: string; colVerdict: string };
+ updated: string;
+}
+const { heading, lead, tiles, chart, updated } = Astro.props;
+---
+
+
{heading}
+
{lead}
+
+
—
{tiles.machines}
+
—
{tiles.abnormal}
+
—
{tiles.workOrders}
+
—
{tiles.weeks}
+
+
+
+
{chart.title}
+
+ {chart.tableCaption}
+
{chart.colMachine}
{chart.colDeviation}
{chart.colVerdict}
+
+
+
+
+
diff --git a/src/components/Manufacturing.astro b/src/components/Manufacturing.astro
index 4018186..da67e15 100644
--- a/src/components/Manufacturing.astro
+++ b/src/components/Manufacturing.astro
@@ -3,6 +3,7 @@ import ContactPanel from './ContactPanel.astro';
import AgentDemo from './AgentDemo.astro';
import HeroBand from './HeroBand.astro';
import ArtManufacturing from './ArtManufacturing.astro';
+import AgentPulse from './AgentPulse.astro';
import type { ManufacturingCopy, MfgLocale } from '../i18n/manufacturing';
interface Props { copy: ManufacturingCopy; locale: MfgLocale }
const { copy, locale } = Astro.props;
@@ -12,16 +13,7 @@ const { copy, locale } = Astro.props;
-
-
- {copy.tiles.map((t) => (
-
-
{t.value}
-
{t.label}
-
- ))}
-
-
+
{copy.insights.heading}
diff --git a/src/i18n/manufacturing.ts b/src/i18n/manufacturing.ts
index cbbe226..6c35464 100644
--- a/src/i18n/manufacturing.ts
+++ b/src/i18n/manufacturing.ts
@@ -31,6 +31,7 @@ export interface ManufacturingCopy {
title: string;
description: string;
hero: { eyebrow: string; title: string; lead: string; primary: string };
+ pulse: { heading: string; lead: string; tiles: { machines: string; abnormal: string; workOrders: string; weeks: string }; chart: { title: string; yLabel: string; refLabel: string; tableCaption: string; colMachine: string; colDeviation: string; colVerdict: string }; updated: string };
tiles: { value: string; label: string }[];
insights: { heading: string; lead: string; blocks: Block[] };
industries: { heading: string; lead: string; blocks: Block[] };
@@ -87,6 +88,13 @@ export const manufacturing: Record = {
lead: 'Built from data you already export. No IT project. Each finding tells you the cause, the cost, and what to do on Monday.',
primary: 'Send one Excel file',
},
+ pulse: {
+ heading: 'Last night, on the fleet',
+ lead: 'One agent cycle a night: sense every machine, reason over six weeks of cycle data, act with a root cause and a work order, record the trail.',
+ tiles: { machines: 'Machines watched', abnormal: 'Flagged abnormal', workOrders: 'Work orders raised', weeks: 'Weeks of cycle data' },
+ chart: { title: 'Cycle deviation from the approved cycle, by machine', yLabel: 'deviation vs approved cycle', refLabel: 'approved', tableCaption: 'Table view', colMachine: 'Machine', colDeviation: 'Last week', colVerdict: 'Verdict' },
+ updated: 'cycle of',
+ },
tiles: [
{ value: '48 hrs', label: 'First insights delivered' },
{ value: 'Zero', label: 'IT setup required' },
@@ -150,6 +158,13 @@ export const manufacturing: Record = {
lead: '이미 내보내고 있는 데이터로 만듭니다. IT 프로젝트가 필요 없습니다. 모든 발견은 원인, 비용, 그리고 월요일에 할 일을 말해줍니다.',
primary: '엑셀 파일 하나 보내기',
},
+ pulse: {
+ heading: '지난밤, 설비 전체에서',
+ lead: '하룻밤 한 사이클: 모든 설비를 감지하고, 6주치 사이클 데이터를 추론하고, 근본 원인과 작업지시로 실행하고, 이력을 기록합니다.',
+ tiles: { machines: '감시 설비', abnormal: '이상 판정', workOrders: '발행된 작업지시', weeks: '사이클 데이터 주수' },
+ chart: { title: '설비별 승인 사이클 대비 편차', yLabel: '승인 사이클 대비 편차', refLabel: '승인', tableCaption: '표로 보기', colMachine: '설비', colDeviation: '최근 주', colVerdict: '판정' },
+ updated: '사이클 일자',
+ },
tiles: [
{ value: '48시간', label: '첫 인사이트 전달' },
{ value: '없음', label: '필요한 IT 설정' },