For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (
- [ ]) syntax for tracking.
Goal: Port the Website 3.0 design from ~/Downloads/Website 3.0/ into www/v3/de/ as static HTML with vanilla JS animations, isolated from production via noindex + robots.txt. German first; English follows in a separate plan.
Architecture: New www/v3/ subfolder on master. Single global CSS file (v3.css) extracted from the design's <style> block. Per-section JS files for animations (orchestration cycling, swimlane packets, nav dropdown) following the existing www/js/orb.js IIFE pattern. JSX components are converted to their rendered HTML and inlined into de/index.html in the composition order from app.jsx (Nav → Hero → ModulesGrid → Workflow → Orchestration → OrchestrationB → CaseStudy → RoiCalculator → Integrations → Security → Pricing → CtaFooter). Mode toggle, tweaks panel, and edit-mode protocol are dropped.
Tech Stack: HTML, CSS, vanilla JS. Geist + Geist Mono via Google Fonts. No bundler, no build step. Local preview via python -m http.server from www/.
Verification model: Static HTML doesn't have a unit test framework. Each task verifies via:
curl -sI for HTTP 200grep for required markers (e.g., noindex, data-section="hero")Files:
Create: www/v3/robots.txt
Create: www/v3/de/index.html (shell only)
Create: www/v3/de/produkt/ (empty directory placeholder via .gitkeep)
Create: www/v3/css/v3.css (empty for now)
Create: www/v3/js/.gitkeep (empty)
Step 1: Create the directory structure
mkdir -p www/v3/de/produkt www/v3/css www/v3/js
touch www/v3/de/produkt/.gitkeep www/v3/js/.gitkeep
www/v3/robots.txtUser-agent: *
Disallow: /
www/v3/de/index.html shell<!doctype html>
<html lang="de">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="robots" content="noindex, nofollow" />
<title>Orcha — Autonome Finanzoperationen</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Geist:wght@300;400;500;600;700&family=Geist+Mono:wght@400;500;600&display=swap">
<link rel="stylesheet" href="../css/v3.css">
</head>
<body data-mode="editorial">
<!-- Sections inserted in subsequent tasks -->
</body>
</html>
www/v3/css/v3.css/* Website 3.0 draft styles — populated in Task 2 */
cd /Users/maximilianbrandstaetter/Orcha/www && python3 -m http.server 8765 &
(Keep running for the whole plan. Stop with lsof -ti:8765 | xargs kill at the end.)
curl -s http://localhost:8765/v3/de/index.html | grep -c 'noindex'
Expected: 1
curl -s http://localhost:8765/v3/robots.txt
Expected: contains Disallow: /
git add www/v3
git commit -m "feat(v3): scaffold www/v3/ draft with noindex + robots block"
v3.cssFiles:
www/v3/css/v3.cssThe original design has a single large <style> block in index.html (lines 10–625 of ~/Downloads/Website 3.0/index.html). Move it into v3.css verbatim. Keep the :root tokens, mode override (body[data-mode="systems"]), and prefers-reduced-motion block. Drop the tweaks panel CSS (.tweaks, .tweak-row, .tweak-btns, .swatches) since the panel is dropped.
<style> blocksed -n '10,625p' "/Users/maximilianbrandstaetter/Downloads/Website 3.0/index.html"
<style> block (without <style> tags) into www/v3/css/v3.cssUse the Read tool on the original file then Write to www/v3/css/v3.css. Drop only these blocks:
.tweaks { ... } through .swatches button.on { outline: ... } (the in-design controls panel)Keep everything else — including the editorial/systems mode tokens, even though we default to editorial. Future translation pass may want the systems variant available.
curl -sI http://localhost:8765/v3/css/v3.css | grep -i 'content-type'
Expected: text/css
curl -s http://localhost:8765/v3/css/v3.css | grep -c '^:root'
Expected: 1 (or 2 if the body[data-mode="systems"] block also matches the regex anchor — either way > 0)
Step 4: Visual check — open http://localhost:8765/v3/de/index.html in the browser. Page should render in Geist with paper background #f5f3ee, but be empty (no sections yet).
Step 5: Commit
git add www/v3/css/v3.css
git commit -m "feat(v3): port design tokens and global styles to v3.css"
Files:
www/v3/de/index.htmlwww/v3/js/nav-dropdown.jsSource: ~/Downloads/Website 3.0/components/app.jsx lines 11–76 (the Nav component). The dropdown uses useState + mouseenter/leave timers; we replicate with vanilla JS. Copy is left in English in this task; German translation happens in Task 14.
www/v3/de/index.html bodyAfter <body data-mode="editorial">, insert:
<div class="nav">
<div class="wrap nav-inner">
<a class="logo" href="#">
<span class="logo-mark"></span>
Orcha
</a>
<nav class="nav-links">
<div class="nav-dropdown" data-nav-dropdown>
<button class="nav-dropdown-trigger" data-nav-trigger aria-expanded="false">
Product
<svg width="10" height="10" viewBox="0 0 10 10" data-nav-chevron style="margin-left: 4px; transition: transform .18s ease;">
<path d="M2 3.5 L5 6.5 L8 3.5" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" />
</svg>
</button>
<div class="nav-dropdown-panel" data-nav-panel hidden>
<div class="nav-dropdown-header">
<span class="mono" style="font-size: 10px; letter-spacing: 0.16em; text-transform: uppercase; color: var(--muted);">Modules</span>
<span style="font-size: 12px; color: var(--ink-2);">Choose independently · or run the full suite</span>
</div>
<div class="nav-dropdown-grid">
<a href="produkt/kreditoren.html" class="nav-dropdown-item">
<span class="nav-dropdown-item-title">Accounts Payable</span>
<span class="nav-dropdown-item-hint">AP automation · 95% straight-through</span>
</a>
<a href="produkt/debitoren.html" class="nav-dropdown-item">
<span class="nav-dropdown-item-title">Accounts Receivable</span>
<span class="nav-dropdown-item-hint">Billing, dunning, bank match</span>
</a>
<a href="produkt/dokumente.html" class="nav-dropdown-item">
<span class="nav-dropdown-item-title">Document Management</span>
<span class="nav-dropdown-item-hint">Classify, extract, archive</span>
</a>
<a href="produkt/freigaben.html" class="nav-dropdown-item">
<span class="nav-dropdown-item-title">Approval Workflows</span>
<span class="nav-dropdown-item-hint">Multi-channel, budget-aware</span>
</a>
<a href="produkt/fpa.html" class="nav-dropdown-item">
<span class="nav-dropdown-item-title">Real-Time FP&A</span>
<span class="nav-dropdown-item-hint">Excel, Power BI, AI assistants</span>
</a>
</div>
<a href="produkt/index.html" class="nav-dropdown-footer">
Platform overview
<span aria-hidden="true">→</span>
</a>
</div>
</div>
<a href="#agents">Agents</a>
<a href="#workflow">How it works</a>
<a href="#orchestration">Stack</a>
<a href="#roi">ROI</a>
<a href="#integrations">Integrations</a>
<a href="#security">Security</a>
<a href="#pricing">Pricing</a>
</nav>
<div class="nav-cta">
<a class="btn btn-ghost" href="#">Sign in</a>
<a class="btn btn-primary" href="#pricing">Start trial <span aria-hidden="true">→</span></a>
</div>
</div>
</div>
<script src="../js/nav-dropdown.js" defer></script>
www/v3/js/nav-dropdown.js(function () {
document.addEventListener('DOMContentLoaded', function () {
var root = document.querySelector('[data-nav-dropdown]');
if (!root) return;
var trigger = root.querySelector('[data-nav-trigger]');
var panel = root.querySelector('[data-nav-panel]');
var chevron = root.querySelector('[data-nav-chevron]');
var closeTimer = null;
function open() {
clearTimeout(closeTimer);
panel.hidden = false;
trigger.setAttribute('aria-expanded', 'true');
trigger.classList.add('open');
chevron.style.transform = 'rotate(180deg)';
}
function close() {
panel.hidden = true;
trigger.setAttribute('aria-expanded', 'false');
trigger.classList.remove('open');
chevron.style.transform = 'none';
}
root.addEventListener('mouseenter', open);
root.addEventListener('mouseleave', function () {
closeTimer = setTimeout(close, 120);
});
trigger.addEventListener('click', function () {
panel.hidden ? open() : close();
});
});
})();
curl -s http://localhost:8765/v3/de/index.html | grep -c 'nav-dropdown-trigger'
Expected: 1
Step 4: Visual check — reload the page, hover "Product", panel should slide in. Click outside, it closes after ~120ms.
Step 5: Commit
git add www/v3/de/index.html www/v3/js/nav-dropdown.js
git commit -m "feat(v3): add nav with product dropdown menu"
Files:
www/v3/de/index.htmlSource: ~/Downloads/Website 3.0/components/hero.jsx. Default to variant A (heroVariant: "A" in the original TWEAKS block). Read the file fully before porting — useState for any dynamic chips/badges should be flattened to their initial rendered state.
Use the Read tool on /Users/maximilianbrandstaetter/Downloads/Website 3.0/components/hero.jsx. Identify the variant-A render path. Note any dynamic state (chip rotation, etc.) — replicate the initial rendered output only; if there's a JS-driven cycle, capture timing for a later JS file.
www/v3/de/index.html after the </div> of .nav and before the next section. Inline the variant-A output verbatim, preserving class names.(Engineer: copy the rendered output here — content depends on what the JSX produces. For a typical hero this is <section class="hero"> with eyebrow, h1 with .italic-swap, lede, CTA buttons.)
Step 3: If the hero has any JS-driven animation (e.g., chip rotator), create www/v3/js/hero.js with the equivalent vanilla loop and add <script src="../js/hero.js" defer></script> before </body>. Skip if hero is fully static.
Step 4: Verify
curl -s http://localhost:8765/v3/de/index.html | grep -c 'h-display'
Expected: >= 1
Step 5: Visual check — reload. Hero should look identical to the design's variant-A hero.
Step 6: Commit
git add www/v3/de/index.html www/v3/js/hero.js 2>/dev/null
git commit -m "feat(v3): add hero section (variant A)"
Files:
www/v3/de/index.htmlSource: ~/Downloads/Website 3.0/components/agents.jsx (the component is exported as ModulesGrid per app.jsx line 235).
Use the Read tool on /Users/maximilianbrandstaetter/Downloads/Website 3.0/components/agents.jsx. Note any JS interactivity.
Step 2: Insert agents HTML after the hero section. Keep the id="agents" so the nav anchor works.
Step 3: If interactive (hover state, count up animation, etc.), create www/v3/js/agents.js. Skip if static.
Step 4: Verify
curl -s http://localhost:8765/v3/de/index.html | grep -c 'id="agents"'
Expected: 1
Step 5: Visual check — reload, scroll to agents section, compare side-by-side with the design original (file:///Users/maximilianbrandstaetter/Downloads/Website%203.0/index.html rendered in browser).
Step 6: Commit
git add www/v3/de/index.html www/v3/js/agents.js 2>/dev/null
git commit -m "feat(v3): add agents/modules grid section"
Files:
www/v3/de/index.htmlSource: ~/Downloads/Website 3.0/components/workflow.jsx. Component is Workflow per app.jsx line 236.
Use the Read tool. Identify any animation (step progression, line drawing).
Step 2: Insert workflow HTML after agents. Keep id="workflow" for nav anchor.
Step 3: If animated, create www/v3/js/workflow.js.
Step 4: Verify
curl -s http://localhost:8765/v3/de/index.html | grep -c 'id="workflow"'
Expected: 1
Step 5: Visual check — compare against design.
Step 6: Commit
git add www/v3/de/index.html www/v3/js/workflow.js 2>/dev/null
git commit -m "feat(v3): add workflow section"
Files:
www/v3/de/index.htmlwww/v3/js/orchestration.jsSource: ~/Downloads/Website 3.0/components/orchestration.jsx. The CSS for this section is already in v3.css (.orch-grid, .orch-node, .orch-line, etc.). The animation cycles through nodes by toggling .active classes on .orch-node elements and .orch-line-active on SVG lines.
Use the Read tool on /Users/maximilianbrandstaetter/Downloads/Website 3.0/components/orchestration.jsx. Capture: (a) static structure of the three-column grid + central hub + SVG lines, (b) the timeline events list, (c) the useEffect interval that drives .active cycling — record interval ms, sequence order.
id="orchestration".Structure (fill in the actual node names, labels, timeline events from the JSX):
<section id="orchestration">
<div class="wrap">
<!-- Section header (eyebrow + h-section + lede) -->
<!-- .orch-grid with three .orch-col + .orch-center containing .orch-hub + SVG lines -->
<!-- .orch-timeline with .orch-event rows -->
</div>
</section>
Use the actual content from the JSX render output.
www/v3/js/orchestration.jsPattern:
(function () {
document.addEventListener('DOMContentLoaded', function () {
var section = document.getElementById('orchestration');
if (!section) return;
var inNodes = section.querySelectorAll('.orch-col-in .orch-node');
var outNodes = section.querySelectorAll('.orch-col-out .orch-node');
var lines = section.querySelectorAll('.orch-line');
if (!inNodes.length) return;
var step = 0;
function tick() {
inNodes.forEach(function (n) { n.classList.remove('active'); });
outNodes.forEach(function (n) { n.classList.remove('active'); });
lines.forEach(function (l) { l.classList.remove('orch-line-active'); });
// Activate current step's input + output + line
var inN = inNodes[step % inNodes.length];
var outN = outNodes[step % outNodes.length];
if (inN) inN.classList.add('active');
if (outN) outN.classList.add('active');
// Match line indexing to nodes (verify in source — lines may need a different mapping)
var line = lines[step % lines.length];
if (line) line.classList.add('orch-line-active');
step++;
}
if (window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches) return;
tick();
setInterval(tick, 1800); // Adjust to match source timing
});
})();
Add <script src="../js/orchestration.js" defer></script> before </body> (alongside nav-dropdown.js).
Important: the exact tick interval and node→line mapping must come from the source useEffect. If the source uses a more complex mapping, port that exactly.
curl -s http://localhost:8765/v3/de/index.html | grep -c 'orch-grid'
Expected: >= 1
Step 5: Visual check — reload. Watch for at least 3 cycles. Active state should highlight nodes + the connecting line in brand blue. No console errors. With prefers-reduced-motion: reduce set in the OS, the animation should not run.
Step 6: Commit
git add www/v3/de/index.html www/v3/js/orchestration.js
git commit -m "feat(v3): add orchestration A section with node cycling"
Files:
www/v3/de/index.htmlwww/v3/js/swimlanes.jsSource: ~/Downloads/Website 3.0/components/orchestration-b.jsx. CSS is already in v3.css (.swim-board, .swim-lane, .swim-packet, etc.). Packets animate left-to-right along tracks; some land in the warn-coloured human-escalation row.
Use the Read tool on /Users/maximilianbrandstaetter/Downloads/Website 3.0/components/orchestration-b.jsx. Capture: (a) the lane structure (human row + N agent rows), (b) packet definitions (origin lane, target lane, status, content), (c) animation timing (spawn cadence, transit duration).
Step 2: Insert swimlanes HTML after the orchestration A section. Use a separate id like id="orchestration-b" (or fold into #orchestration if the JSX renders both under one section — verify).
Step 3: Write www/v3/js/swimlanes.js
Pattern (timing/sequence comes from source):
(function () {
document.addEventListener('DOMContentLoaded', function () {
var board = document.querySelector('.swim-board');
if (!board) return;
if (window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches) return;
var lanes = board.querySelectorAll('.swim-lane');
var packetTpl = /* source-defined templates */;
function spawnPacket(targetLane, kind, content) {
var track = targetLane.querySelector('.swim-track');
var packet = document.createElement('div');
packet.className = 'swim-packet swim-packet-' + kind;
packet.innerHTML = content;
packet.style.position = 'absolute';
packet.style.left = '0';
packet.style.top = '50%';
packet.style.transform = 'translate(-100%, -50%)';
track.appendChild(packet);
// Animate via requestAnimationFrame or CSS transition
requestAnimationFrame(function () {
packet.style.transition = 'transform 2.4s linear';
packet.style.transform = 'translate(calc(' + track.offsetWidth + 'px), -50%)';
});
setTimeout(function () { packet.remove(); }, 2600);
}
// Schedule packet sequence using the data from the source
var queue = [/* packet sequence from JSX */];
var i = 0;
setInterval(function () {
var p = queue[i % queue.length];
var lane = lanes[p.laneIndex];
if (lane) spawnPacket(lane, p.kind, p.content);
i++;
}, 1400); // Adjust to match source
});
})();
Add <script src="../js/swimlanes.js" defer></script> before </body>.
curl -s http://localhost:8765/v3/de/index.html | grep -c 'swim-board'
Expected: >= 1
Step 5: Visual check — packets should spawn at the left of agent lanes, slide right, occasionally land in the human-escalation row with a warn-coloured highlight.
Step 6: Commit
git add www/v3/de/index.html www/v3/js/swimlanes.js
git commit -m "feat(v3): add orchestration B (swimlanes) with packet animation"
Files:
www/v3/de/index.htmlSource: ~/Downloads/Website 3.0/components/rest.jsx and ~/Downloads/Website 3.0/components/roi.jsx. Per app.jsx lines 239–244, the order is: CaseStudy, RoiCalculator, Integrations, Security, Pricing, CtaFooter.
Use the Read tool on rest.jsx and roi.jsx. Identify the boundaries between sections. The RoiCalculator may have interactivity (sliders that update KPI numbers).
Step 2: Insert each section's HTML in order after the swimlanes section. Use these IDs (matching nav anchors): id="case-study" (no nav anchor — fine), id="roi", id="integrations", id="security", id="pricing", then the CTA footer (no id).
Step 3: If RoiCalculator has slider interactivity, create www/v3/js/roi.js. Pattern:
(function () {
document.addEventListener('DOMContentLoaded', function () {
var section = document.getElementById('roi');
if (!section) return;
var inputs = section.querySelectorAll('input[type="range"], input[type="number"]');
var outputs = section.querySelectorAll('[data-roi-output]');
function recalc() {
// Read inputs, apply formula from source, write to outputs
}
inputs.forEach(function (i) { i.addEventListener('input', recalc); });
recalc();
});
})();
Use the exact formula from the source.
for id in roi integrations security pricing; do
curl -s http://localhost:8765/v3/de/index.html | grep -c "id=\"$id\"" || echo "missing: $id"
done
Expected: each prints 1.
Step 5: Visual check — full home page scrolled top to bottom, side-by-side with the design original.
Step 6: Commit
git add www/v3/de/index.html www/v3/js/roi.js 2>/dev/null
git commit -m "feat(v3): add case study, ROI, integrations, security, pricing, CTA"
Files: none
Open http://localhost:8765/v3/de/index.html and the design original side-by-side. Walk through every section. Check:
Typography matches (Geist 500 headlines, Geist Mono 11px eyebrows, brand blue accent)
Spacing matches (section padding 120px, card padding 32px)
Animations run: orchestration node cycling, swimlane packets, nav dropdown
No console errors
Nav anchors scroll to the right section
Responsive: shrink window to 900px, layouts collapse cleanly
Step 2: Note any visual deltas
If any section is visibly off, fix in place and amend the relevant task's commit. If a fix is large, create a new follow-up commit fix(v3): [section] visual delta.
Tell the user the home is ready for visual review. Wait for sign-off (or fix list) before proceeding to product pages.
Files:
www/v3/de/produkt/index.htmlwww/v3/css/product.csswww/v3/js/chrome.jsSources: ~/Downloads/Website 3.0/product/overview.html, ~/Downloads/Website 3.0/product/product.css, ~/Downloads/Website 3.0/product/chrome.js.
Step 1: Copy product.css into www/v3/css/product.css (verbatim or with import-path adjustments if any).
Step 2: Copy chrome.js into www/v3/js/chrome.js (verbatim).
Step 3: Copy overview.html content into www/v3/de/produkt/index.html with these adjustments:
Add <meta name="robots" content="noindex, nofollow"> in <head>
Update CSS link to <link rel="stylesheet" href="../../css/v3.css"> and add <link rel="stylesheet" href="../../css/product.css">
Update JS link to <script src="../../js/chrome.js" defer></script>
Update font links (preconnect + Google Fonts) — same as home
Update nav links to point to sibling product pages (kreditoren.html etc.) and back to home (../index.html)
Set <html lang="de">
Keep English copy in place — German pass is Task 14
Step 4: Verify
curl -sI http://localhost:8765/v3/de/produkt/index.html | head -1
curl -s http://localhost:8765/v3/de/produkt/index.html | grep -c 'noindex'
Expected: HTTP/1.0 200 OK and 1.
Step 5: Visual check — open in browser, compare to design's product/overview.html.
Step 6: Commit
git add www/v3/de/produkt/index.html www/v3/css/product.css www/v3/js/chrome.js
git commit -m "feat(v3): port product overview page"
Files:
www/v3/de/produkt/kreditoren.html (from accounts-payable.html)www/v3/de/produkt/debitoren.html (from accounts-receivable.html)www/v3/de/produkt/freigaben.html (from approvals.html)www/v3/de/produkt/dokumente.html (from document-management.html)www/v3/de/produkt/fpa.html (from fpa.html)Each subpage gets the same head adjustments as Task 11. URL slugs match existing www/de/produkt/ conventions (Kreditoren / Debitoren / Freigaben / Dokumente / FP&A).
Read ~/Downloads/Website 3.0/product/accounts-payable.html. Write to www/v3/de/produkt/kreditoren.html with:
<html lang="de">, noindex meta../../css/v3.css, ../../css/product.css../../js/chrome.jsVerify:
curl -sI http://localhost:8765/v3/de/produkt/kreditoren.html | head -1
Expected: 200.
Step 2: Port debitoren.html (same procedure, source accounts-receivable.html).
Step 3: Port freigaben.html (source approvals.html).
Step 4: Port dokumente.html (source document-management.html).
Step 5: Port fpa.html (source fpa.html).
Step 6: Verify all five pages return 200 and have noindex
for p in kreditoren debitoren freigaben dokumente fpa; do
status=$(curl -sI http://localhost:8765/v3/de/produkt/$p.html | head -1)
noindex=$(curl -s http://localhost:8765/v3/de/produkt/$p.html | grep -c 'noindex')
echo "$p: $status — noindex=$noindex"
done
Expected: each line shows 200 OK and noindex=1.
Step 7: Visual check — browse each page, compare to corresponding design original.
Step 8: Commit
git add www/v3/de/produkt/
git commit -m "feat(v3): port 5 product subpages (Kreditoren/Debitoren/Freigaben/Dokumente/FPA)"
Files: none
# All 7 pages return 200
for p in /v3/de/index.html /v3/de/produkt/index.html /v3/de/produkt/kreditoren.html /v3/de/produkt/debitoren.html /v3/de/produkt/freigaben.html /v3/de/produkt/dokumente.html /v3/de/produkt/fpa.html; do
status=$(curl -sI "http://localhost:8765$p" | head -1)
echo "$p — $status"
done
# All pages have noindex
for p in /v3/de/index.html /v3/de/produkt/index.html /v3/de/produkt/kreditoren.html /v3/de/produkt/debitoren.html /v3/de/produkt/freigaben.html /v3/de/produkt/dokumente.html /v3/de/produkt/fpa.html; do
count=$(curl -s "http://localhost:8765$p" | grep -c 'noindex')
echo "$p — noindex=$count"
done
# robots.txt blocks
curl -s http://localhost:8765/v3/robots.txt
# No links from current site point to /v3/
grep -r '/v3/' www/de/ www/en/ www/sitemap.xml 2>&1 | grep -v 'Binary' || echo "✓ no links from current site to /v3/"
# Production unchanged
git diff master -- www/de www/en www/sitemap.xml
Expected:
All 7 pages return 200 OK
All have noindex=1
robots.txt contains Disallow: /
No grep hits from current site to /v3/
git diff is empty for www/de, www/en, www/sitemap.xml
Step 2: Pause for user visual review of English version
Tell the user the English version is feature-complete and ask for visual sign-off before starting German translation. If fixes needed, address inline before proceeding.
Files:
www/v3/de/index.htmlReference the existing www/de/index.html for tone (Sie-form, no Anglicisms where a clean German term exists, Swiss German spelling per user preference).
Step 1: Build a translation pass list — read through every English string in www/v3/de/index.html and draft German equivalents. For headline/marketing phrases, draft 2 options and flag for user review.
Step 2: Apply translations in-place using the Edit tool, one section at a time:
Nav links: Product → Produkt, How it works → So funktioniert es, Stack → Stack, ROI → ROI, Integrations → Integrationen, Security → Sicherheit, Pricing → Preise, Sign in → Anmelden, Start trial → Trial starten
Dropdown: Modules → Module, Choose independently · or run the full suite → Einzeln nutzen · oder als komplette Suite, Platform overview → Plattform-Überblick, AP automation · 95% straight-through → AP-Automatisierung · 95% vollautomatisch, etc.
Hero, agents, workflow, orchestration, case study, ROI, integrations, security, pricing, CTA — section by section
Mono-font technical labels (e.g., INV-20411, agent codes) stay as-is
Title tag: Orcha — Autonome Finanzoperationen (already set in Task 1)
Step 3: Verify no untranslated English strings remain
Spot-check by opening in browser. Run a quick grep for common English-only words:
for word in "How it works" "Sign in" "Start trial" "Approve" "Choose"; do
count=$(grep -c "$word" www/v3/de/index.html)
echo "$word: $count"
done
Expected: most show 0. Any non-zero hit needs review (could be intentional like a brand term).
Step 4: Visual check — reload, scroll top to bottom, confirm copy reads naturally.
Step 5: Commit
git add www/v3/de/index.html
git commit -m "feat(v3): translate home page to German"
Files:
Modify: www/v3/de/produkt/index.html
Modify: www/v3/de/produkt/kreditoren.html
Modify: www/v3/de/produkt/debitoren.html
Modify: www/v3/de/produkt/freigaben.html
Modify: www/v3/de/produkt/dokumente.html
Modify: www/v3/de/produkt/fpa.html
Step 1: Translate produkt/index.html (overview page) using the same tone as the home page. Reference www/de/produkt/index.html for terminology consistency.
Verify:
grep -c 'How it works\|Sign in' www/v3/de/produkt/index.html
Expected: 0.
Step 2: Translate kreditoren.html
Step 3: Translate debitoren.html
Step 4: Translate freigaben.html
Step 5: Translate dokumente.html
Step 6: Translate fpa.html
Step 7: Verify across all six pages
for f in www/v3/de/produkt/index.html www/v3/de/produkt/kreditoren.html www/v3/de/produkt/debitoren.html www/v3/de/produkt/freigaben.html www/v3/de/produkt/dokumente.html www/v3/de/produkt/fpa.html; do
hits=$(grep -E "How it works|Sign in|Start trial|Approve workflow" "$f" | wc -l | tr -d ' ')
echo "$f: $hits English hits"
done
Expected: each file shows 0.
Step 8: Visual check — browse each page.
Step 9: Commit
git add www/v3/de/produkt/
git commit -m "feat(v3): translate 6 product pages to German"
Files: none
Run all six acceptance criteria from the spec.
for p in /v3/de/index.html /v3/de/produkt/index.html /v3/de/produkt/kreditoren.html /v3/de/produkt/debitoren.html /v3/de/produkt/freigaben.html /v3/de/produkt/dokumente.html /v3/de/produkt/fpa.html; do
curl -sI "http://localhost:8765$p" | head -1
done
Expected: 7 × 200 OK.
User opens browser DevTools console on /v3/de/index.html, watches for 60 seconds. Expected: no errors, orchestration cycles through nodes, swimlane packets spawn and traverse.
for p in /v3/de/index.html /v3/de/produkt/index.html /v3/de/produkt/kreditoren.html /v3/de/produkt/debitoren.html /v3/de/produkt/freigaben.html /v3/de/produkt/dokumente.html /v3/de/produkt/fpa.html; do
count=$(curl -s "http://localhost:8765$p" | grep -c 'noindex')
echo "$p: noindex=$count"
done
Expected: each shows 1.
curl -s http://localhost:8765/v3/robots.txt
Expected:
User-agent: *
Disallow: /
grep -r '/v3/' www/de/ www/en/ www/index.html www/sitemap.xml 2>/dev/null || echo "✓ no leakage"
Expected: ✓ no leakage.
grep -r 'tracker.js' www/v3/ 2>/dev/null && echo "WARN: tracker referenced" || echo "✓ no tracker in v3"
Expected: ✓ no tracker in v3.
git diff master~$(git rev-list master..HEAD --count) -- www/de www/en www/sitemap.xml www/css/globals.css www/js/main.js www/js/orb.js www/js/tracker.js www/js/community-forms.js
Expected: empty diff.
lsof -ti:8765 | xargs kill 2>/dev/null
Report: "Website 3.0 draft is on master at www/v3/de/. Local preview at http://localhost:8765/v3/de/ (run cd www && python3 -m http.server 8765 to restart). All 6 acceptance criteria pass. Ready for your review. Next step is the EN translation, which is a separate plan."