{"slug":"relay","name":"Relay — AI Agent Product Landing","version":"2.7.2","category":"saas landing","priceCents":2900,"description":"An AI SaaS landing page template for support-agent products. Relay ships seven frontend routes, four bounded billing workflow fixtures, a five-turn sample transcript, an ordered sample run log, explicit tool and policy boundaries, researched human handoff states, two canonical Wire Diagram graphs, a local price calculator and a living component styleguide. The templates route distinguishes automated success, policy denial, tool failure, approval timeout and voluntary escalation without implying a ticket backend or policy engine. Self-hosted Public Sans and JetBrains Mono, a 1.200 type scale, semantic Tailwind v4 tokens, one amber human-action mark, and complete light and dark modes verified against WCAG AA by computation. A framework-free HTML template edition ships the same seven routes as compiled documents with local fonts and vanilla JavaScript, plus the Nunjucks source that produced them.","summary":"For support-agent products that must show their work: an AI SaaS landing page template with four bounded billing workflows and a sample run. 7 routes.","tags":["ai saas landing page template","ai agent website template","ai agent landing page","tailwind-v4"],"palette":{"bg":"#dfe7f2","surface":"#f5f9ff","accent":"#b17000","text":"#121820","line":"#becada"},"accent_mode":"monochrome-plus-spot","darkMode":true,"pages":[{"path":"/","title":"Relay — the billing agent that hands off","sections":["site-header","agent-hero","outcome-band","how-it-works","boundary-grid","integrations","cta","site-footer"]},{"path":"/product","title":"Product — inside one agent run","sections":["site-header","conversation-thread","tool-timeline","agent-flow","handoff-panel","guardrails","cta","site-footer"]},{"path":"/security","title":"Security — every scope, every record","sections":["site-header","scope-ledger","guardrails","audit-record","cta","site-footer"]},{"path":"/pricing","title":"Pricing — billed on tickets it closes","sections":["site-header","price-estimator","pricing-table","faq","cta","site-footer"]},{"path":"/contact","title":"Contact — who answers, and when","sections":["site-header","support-desk","cta","site-footer"]},{"path":"/templates","title":"Templates for bounded billing workflows","sections":["site-header","template-index","cta","site-footer"]},{"path":"/components","title":"The parts — living styleguide","sections":["site-header","ui/page-hero","agent-hero","outcome-band","how-it-works","boundary-grid","integrations","conversation-thread","tool-timeline","agent-flow","handoff-panel","guardrails","scope-ledger","audit-record","pricing-table","price-estimator","support-desk","template-index","faq","cta","site-footer"]}],"components":[{"name":"site-header","file":"src/components/site-header.tsx","renders":"Sticky nav: wordmark, four destinations, sign-in and trial CTA, plus a JS-free <details> mobile menu"},{"name":"agent-hero","file":"src/components/agent-hero.tsx","renders":"Headline, lede, two CTAs and three risk-reversal notes offset into columns 2-7 of a twelve-column grid, beside a sample ticket card that overhangs the container and shows a Stripe tool call fixture, over a routing-trace field masked out of a colourless PNG so the token inks it"},{"name":"outcome-band","file":"src/components/outcome-band.tsx","renders":"Headline percentage at the page's one oversized step with the named customer quote that explains it, plus the run on this page reported as its own numbers"},{"name":"how-it-works","file":"src/components/how-it-works.tsx","renders":"Three numbered steps — reads the account, drafts with a citation, stops at your line — in a hairline-split row"},{"name":"boundary-grid","file":"src/components/boundary-grid.tsx","renders":"Two honest columns weighted 7/5 like the claim they carry: eight ticket types the agent closes, six it always escalates, with the dollar thresholds stated"},{"name":"integrations","file":"src/components/integrations.tsx","renders":"Six sample systems on the wide rail, each with a lucide glyph and its access level as a badge - read only, read plus write, write only"},{"name":"conversation-thread","file":"src/components/conversation-thread.tsx","renders":"The full transcript of one ticket: five turns across customer, agent and human, three tool calls with arithmetic that reconciles, a linked policy citation and the escalation that ends it - and in lead mode it opens /product with the page title set into the card's own header rail and the run's five-row ledger sticky beside it"},{"name":"tool-timeline","file":"src/components/tool-timeline.tsx","renders":"The same run as a timed log, broken out of the container so the offsets sit in the page margin - eight nodes on a hairline rail with offset, differentiated glyph, tool name, result, duration and what a person would have seen, ending on the amber handoff node"},{"name":"agent-flow","file":"src/components/agent-flow.tsx","renders":"The agent's decision flow as a Wire Diagram figure rendered from src/assets/agent-loop.wire.json - eight nodes including the loop back to the start, down to one policy check that forks 2:1 into a cool resolve branch and an amber human branch, with a text alternative in a disclosure"},{"name":"handoff-panel","file":"src/components/handoff-panel.tsx","renders":"The escalation as the human sees it in an 8/4 split: who owns it, the four facts gathered, the drafted reply with approve and edit actions, the rule that stopped it, and a queue rail with a designed empty state"},{"name":"guardrails","file":"src/components/guardrails.tsx","renders":"Four named rules — refund ceiling, policy threshold, read-only credential, audit retention — stated as configuration rather than promises"},{"name":"scope-ledger","file":"src/components/scope-ledger.tsx","renders":"The write-path Wire figure, then eight named access scopes on the wide rail, each with the system it reaches, a read or write badge, the kind of credential it is held under and the objects it touches, closing on the note that no scope reaches the primary database - it opens /security, so the figure is the first thing a reviewer sees"},{"name":"audit-record","file":"src/components/audit-record.tsx","renders":"The retention period at the page's one oversized step beside one sample row of the audit log, the blocked call from the shipped run, printed field by field with a link to the other seven"},{"name":"pricing-table","file":"src/components/pricing-table.tsx","renders":"Three plans priced per closed ticket with included volume and overage, one featured card emphasised by a filled neutral header rather than colour, and a full-bleed band giving the zero-cost escalation model a whole register"},{"name":"price-estimator","file":"src/components/price-estimator.tsx","renders":"A range slider over monthly closed tickets that prices both metered plans from the rates on the plan cards, names the cheaper one with its effective per-ticket cost, and hands off to sales past ten thousand - it opens /pricing with the title folded into its control column, and it is one of the theme's three client islands"},{"name":"support-desk","file":"src/components/support-desk.tsx","renders":"Four addressed support desks on the wide rail, each with a named owner and a stated answer window, over a 5/7 block carrying the median first reply at the page's oversized step beside the registered entity, office, data region and controller - it opens /contact and carries its heading"},{"name":"request-form","file":"src/components/request-form.tsx","renders":"A 4/8 request block whose submit is validated in the browser's own constraint gate, refuses with one sentence per field and a linked summary, and receipts the chosen desk's address, named owner and stated window while saying in words that nothing was transmitted"},{"name":"template-index","file":"src/components/template-index.tsx","renders":"Local workflow library with labelled search, risk filters, polite result count, removable filters, selected evidence, an explicit no-result recovery and one justified client-state boundary"},{"name":"faq","file":"src/components/faq.tsx","renders":"Six JS-free <details> questions with an animation-free plus/minus swap"},{"name":"cta","file":"src/components/cta.tsx","renders":"Closing panel: one headline, one primary action and the trial terms"},{"name":"site-footer","file":"src/components/site-footer.tsx","renders":"Brand blurb, four link columns and a non-interactive status line"},{"name":"ui/button","file":"src/components/ui/button.tsx","renders":"Anchor or button in primary/secondary/ghost at three sizes, driven by the primary-hover and primary-active state ramp, with a motion-safe press, disabled and pending states — pending swaps the variant colour for the info surface, keeps its label, sets aria-busy and refuses a second press — and a visible focus outline"},{"name":"ui/badge","file":"src/components/ui/badge.tsx","renders":"Monospace pill in neutral, accent, outline, info, positive, warning or critical tone for access and status labels"},{"name":"ui/container","file":"src/components/ui/container.tsx","renders":"The single content column: max-w-6xl with the shared gutter rhythm"},{"name":"ui/logo","file":"src/components/ui/logo.tsx","renders":"The relay mark plus wordmark, and a mark-only export used as the agent's avatar — the only hand-drawn SVG in the theme"},{"name":"ui/section-heading","file":"src/components/ui/section-heading.tsx","renders":"Eyebrow, heading and lede at the one shared type scale, left or centred, as an h2 or as the page's h1 one step up when the section opens a page"},{"name":"ui/page-hero","file":"src/components/ui/page-hero.tsx","renders":"Masthead primitive: eyebrow, title and lede in columns 1-7 with the facts as a labelled column on the right - it opens the /components styleguide, and it is there for pages a buyer adds rather than a lid every marketing page wears"},{"name":"ui/mode-toggle","file":"src/components/ui/mode-toggle.tsx","renders":"Light and dark toggle: a sun or moon stating the current mode with aria-pressed beside it, writing the mode class onto the nearest .tt-relay wrapper or onto the document when the theme runs standalone"},{"name":"ui/chat-turn","file":"src/components/ui/chat-turn.tsx","renders":"One transcript row — role avatar, author, timestamp, optional status chip, body — in customer, agent or human role, with the theme's single ambient streaming indicator and its visible label"},{"name":"ui/tool-call","file":"src/components/ui/tool-call.tsx","renders":"One tool invocation: name, arguments, returned line and duration, in a scrollable monospace block one radius step inside its parent"},{"name":"ui/wire-figure","file":"src/components/ui/wire-figure.tsx","renders":"The Wire Diagram renderer: a top-down figure with weighted or equal forks, native multi-parent back edges, branch badges carrying their published share, amber on every human node, and a generated text alternative in a disclosure"},{"name":"ui/template-summary","file":"src/components/ui/template-summary.tsx","renders":"Selected workflow identity, automated or human outcome, sample ticket, risk, amount, approver and terminal close condition"},{"name":"ui/boundary-matrix","file":"src/components/ui/boundary-matrix.tsx","renders":"Focusable semantic table of allowed, conditional and denied sample tools with exact rules and contained narrow-screen scrolling"},{"name":"ui/example-run","file":"src/components/ui/example-run.tsx","renders":"Ordered UTC sample events that distinguish success, policy denial, tool failure, approval timeout, voluntary escalation and handoff"},{"name":"ui/handoff-contract","file":"src/components/ui/handoff-contract.tsx","renders":"Ready, complete, missing-context or retry handoff payload with named owner, destination, attached evidence and recovery"},{"name":"ui/field","file":"src/components/ui/field.tsx","renders":"The field shell on tt-ui: a mono label, an optional marker in words, the read-only sentence, and one message line whose id never changes as it carries the hint, the error or the receipt - around a native input, textarea or select the theme still styles itself, in rest, invalid, valid, read-only and disabled surfaces"},{"name":"ui/template-checklist","file":"src/components/ui/template-checklist.tsx","renders":"Sample, configured and frontend-only buyer setup states with the missing implementation boundary in text"},{"name":"ui/accordion-disclosure","file":"src/components/ui/accordion-disclosure.tsx","renders":"A ruled FAQ row, a bordered card under a diagram and the header's mobile sheet, all closing on Escape with focus back on the summary"},{"name":"ui/toggle-group","file":"src/components/ui/toggle-group.tsx","renders":"The risk filter as a real radio group — one tab stop, arrow keys, selection following focus, and a selected surface rather than a tint"},{"name":"ui/unavailable-action","file":"src/components/ui/unavailable-action.tsx","renders":"A depicted action the demo does not perform, drawn as a dashed aria-disabled non-control with the boundary named beneath it"},{"name":"ui/form-error-summary","file":"src/components/ui/form-error-summary.tsx","renders":"The critical panel a refused submit lands on: one ordered row per failed field reading as that field's own sentence, each a real link to the control it names, inserted into the document rather than revealed so it is announced once and on the submit that matters"},{"name":"ui/form","file":"src/components/ui/form.tsx","renders":"The submit flow: constraint validation left to the browser and re-worded by the theme, one failure sent to its control and several to the summary, a fieldset that carries disabled and aria-busy together, and a receipt that exists before focus is moved to it"}],"tokens":{"--background":"#dfe7f2","--foreground":"#121820","--card":"#f5f9ff","--card-foreground":"#121820","--primary":"#b17000","--primary-foreground":"#050301","--primary-hover":"#c58220","--primary-active":"#d99439","--secondary":"#cdd8e7","--secondary-foreground":"#2a323d","--muted":"#d6dfeb","--muted-foreground":"#505c6b","--accent":"#f4e2c5","--accent-foreground":"#8c5800","--border":"#becada","--ring":"#805000","--field":"#f5f9ff","--field-border":"#68788c","--control-border":"#718196","--control-hover":"#d7e1ee","--control-active":"#c6d2e2","--selection":"#c8d9ec","--selection-foreground":"#172536","--selection-border":"#526f8e","--info":"#295b74","--info-soft":"#dcecf3","--info-border":"#5b8294","--positive":"#245c3e","--positive-soft":"#dcefe4","--positive-border":"#56816a","--warning":"#68448b","--warning-soft":"#ece2f5","--warning-border":"#8c70a8","--critical":"#8a2b3e","--critical-soft":"#f6dde3","--critical-border":"#ad6170","--shadow-color":"#0d1623","--surface-tint":"#d8dfe8","--radius":"0.625rem","--display-weight":"600","--text-d1":"1.5rem","--leading-d1":"1.25","--tracking-d1":"-0.01em","--text-d2":"clamp(1.5rem, 1.376rem + 0.53vw, 1.8rem)","--leading-d2":"1.2","--tracking-d2":"-0.01em","--text-d3":"clamp(1.8rem, 1.651rem + 0.637vw, 2.16rem)","--leading-d3":"1.15","--tracking-d3":"-0.02em","--text-d4":"clamp(2.16rem, 1.981rem + 0.764vw, 2.592rem)","--leading-d4":"1.1","--tracking-d4":"-0.025em","--text-lead":"1.125rem","--leading-lead":"1.6","--text-body":"1rem","--leading-body":"1.55","--text-small":"0.875rem","--leading-small":"1.45","--text-caption":"0.75rem","--leading-caption":"1.4","--tracking-label":"0.1em","--font-text":"var(--font-public-sans), ui-sans-serif, system-ui, -apple-system, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif","--font-sans":"var(--font-text)","--font-mono":"var(--font-jetbrains-mono), ui-monospace, \"SFMono-Regular\", \"SF Mono\", Menlo, Consolas, \"Liberation Mono\", monospace"},"tokensDark":{"--background":"#0d1117","--foreground":"#e2eaf5","--card":"#1b212a","--card-foreground":"#e2eaf5","--primary":"#eba54c","--primary-foreground":"#1a1103","--primary-hover":"#ffb862","--primary-active":"#ffd3a2","--secondary":"#232b36","--secondary-foreground":"#c4cfdd","--muted":"#0f141b","--muted-foreground":"#94a0b0","--accent":"#3c2b1a","--accent-foreground":"#f0b56f","--border":"#2d3643","--ring":"#eba54c","--field":"#111820","--field-border":"#73839a","--control-border":"#66778d","--control-hover":"#26303d","--control-active":"#303c4b","--selection":"#23364a","--selection-foreground":"#dbe9f7","--selection-border":"#7699bd","--info":"#9bcfe4","--info-soft":"#1b2d35","--info-border":"#5a91a8","--positive":"#9fd9b7","--positive-soft":"#1c3026","--positive-border":"#5c9a78","--warning":"#d9b9f2","--warning-soft":"#2f2239","--warning-border":"#9670b2","--critical":"#ff9cae","--critical-soft":"#38191f","--critical-border":"#b75569","--shadow-color":"#010611","--surface-tint":"#22272e","--radius":"0.625rem","--display-weight":"500","--text-d1":"1.5rem","--leading-d1":"1.25","--tracking-d1":"-0.01em","--text-d2":"clamp(1.5rem, 1.376rem + 0.53vw, 1.8rem)","--leading-d2":"1.2","--tracking-d2":"-0.01em","--text-d3":"clamp(1.8rem, 1.651rem + 0.637vw, 2.16rem)","--leading-d3":"1.15","--tracking-d3":"-0.02em","--text-d4":"clamp(2.16rem, 1.981rem + 0.764vw, 2.592rem)","--leading-d4":"1.1","--tracking-d4":"-0.025em","--text-lead":"1.125rem","--leading-lead":"1.6","--text-body":"1rem","--leading-body":"1.55","--text-small":"0.875rem","--leading-small":"1.45","--text-caption":"0.75rem","--leading-caption":"1.4","--tracking-label":"0.1em","--font-text":"var(--font-public-sans), ui-sans-serif, system-ui, -apple-system, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif","--font-sans":"var(--font-text)","--font-mono":"var(--font-jetbrains-mono), ui-monospace, \"SFMono-Regular\", \"SF Mono\", Menlo, Consolas, \"Liberation Mono\", monospace"},"compatibility":{"next":">=15","react":">=19","tailwind":">=4"},"dependencies":["lucide-react"],"editions":{"react":{"source":"src","runtime":"react"},"html":{"source":"html/src","output":"html/dist","engine":"nunjucks","runtime":"vanilla","buildRequired":false}},"ui_library":{"version":"1.5.2","files":["html/src/js/_tt/accordion-disclosure.js","html/src/js/_tt/field-ids.js","html/src/js/_tt/field.js","html/src/js/_tt/form-error-summary.js","html/src/js/_tt/form.js","html/src/js/_tt/mode.js","html/src/js/_tt/pending.js","src/components/ui/_tt/accordion-disclosure.axes.ts","src/components/ui/_tt/accordion-disclosure.fixtures.ts","src/components/ui/_tt/accordion-disclosure.tsx","src/components/ui/_tt/capture.ts","src/components/ui/_tt/field-ids.ts","src/components/ui/_tt/field.axes.ts","src/components/ui/_tt/field.capture.ts","src/components/ui/_tt/field.fixtures.ts","src/components/ui/_tt/field.tsx","src/components/ui/_tt/form-error-summary.axes.ts","src/components/ui/_tt/form-error-summary.fixtures.ts","src/components/ui/_tt/form-error-summary.tsx","src/components/ui/_tt/form.axes.ts","src/components/ui/_tt/form.fixtures.ts","src/components/ui/_tt/form.part.tsx","src/components/ui/_tt/form.ts","src/components/ui/_tt/ids.ts","src/components/ui/_tt/recipe.ts","src/components/ui/_tt/roving.ts","src/components/ui/_tt/toggle-group.axes.ts","src/components/ui/_tt/toggle-group.fixtures.ts","src/components/ui/_tt/toggle-group.tsx"]},"license":"standard","design":{"typefaces":{"text":"Public Sans","mono":"JetBrains Mono"},"typeRatio":1.2,"surface_kind":"marketing","built_against":"2026-08-24","levers":{"theme":"light","density":"comfortable","accent_mode":"monochrome-plus-spot","motion":"tactile","borders":"hairline","radius":"medium","texture":"none","shadow":"none"},"icons":{"set":"lucide","stroke":2,"ladder":["size-3.5","size-4","size-5"],"contexts":{"nav":"glyph","panel_header":"mark","fact_row":"none","feature_grid":"none"}},"disclosure":{"helper_line":"one-clause","sentence":"hint","paragraph":"details","parallel_views":"tabs","secondary_object":"drawer"},"cta":{"header":"quiet","hero":"filled","repeats":["fold","end"],"mobile":"inline"},"colour_budget":{"brand_max_pct":null,"concentration_pct":70,"regions":[]}}}