diff --git a/.docs/TSK-3-fold-2048x1000.png b/.docs/TSK-3-fold-2048x1000.png new file mode 100644 index 0000000..ae36dd7 Binary files /dev/null and b/.docs/TSK-3-fold-2048x1000.png differ diff --git a/.docs/TSK-3-redesign-200-percent.png b/.docs/TSK-3-redesign-200-percent.png new file mode 100644 index 0000000..a830a70 Binary files /dev/null and b/.docs/TSK-3-redesign-200-percent.png differ diff --git a/.docs/TSK-3-redesign-desktop.png b/.docs/TSK-3-redesign-desktop.png new file mode 100644 index 0000000..223fd80 Binary files /dev/null and b/.docs/TSK-3-redesign-desktop.png differ diff --git a/.docs/TSK-3-redesign-mobile.png b/.docs/TSK-3-redesign-mobile.png new file mode 100644 index 0000000..27b9676 Binary files /dev/null and b/.docs/TSK-3-redesign-mobile.png differ diff --git a/.docs/design-reference-synthesis.md b/.docs/design-reference-synthesis.md new file mode 100644 index 0000000..2bd6d90 --- /dev/null +++ b/.docs/design-reference-synthesis.md @@ -0,0 +1,36 @@ +# Design Reference Synthesis + +## Purpose + +Use `VoltAgent/awesome-design-md` as an unofficial comparative research corpus, never as a drop-in identity. OpenAPI Studio must remain recognizable as itself and must not reproduce proprietary trade dress. + +The source documents are community analyses rather than official brand standards; several are explicitly inspired interpretations. Treat every extracted value as fallible and potentially stale. + +## Reference Set + +- **IBM / HashiCorp:** enterprise grid discipline, explicit surface hierarchy, restrained accents, dense proof. +- **ClickHouse / Replicate:** memorable single-color identity paired with real technical artifacts. +- **Vercel / Apple:** controlled typography, clear interaction hierarchy, deliberate whitespace. +- **Linear / Raycast:** product imagery carries the claim; marketing chrome stays subordinate. +- **Sanity / Sentry:** strong brand color is balanced by readable dark evidence surfaces. +- **Stripe:** narrative sequencing and high information clarity without uniform section templates. +- **Supabase:** code and product proof remain legible, contextual, and close to conversion actions. + +## OpenAPI Studio Translation + +1. Keep redline as the single identity color; reserve coral, green, and dark tones for semantic contract states. +2. Make the contract review artifact the visual proof, not decoration. +3. Use one neutral canvas hierarchy: canvas, dark evidence, hairlines, and one inverse offer. +4. Keep display type below 76px desktop and 64px mobile. Later-section headings stay below 68px. +5. At 1440×900 and 2048×1000, the first viewport must show the value proposition, primary CTA, price condition, and complete product artifact. +6. Body and consequential microcopy never fall below 12px; normal marketing body defaults to 16–20px. +7. Avoid repeated cards, repeated eyebrow scaffolding, gradients, glass, generic screenshots, and borrowed brand motifs. +8. Validate the fold separately from full-page rhythm. A full-page screenshot cannot approve conversion visibility. +9. Resolve IBM density versus Apple spaciousness deliberately: compact above the fold, then add air after the product proof. + +## Rejected Imports + +- IBM blue, Linear lavender, ClickHouse yellow, Stripe gradients, and Vercel monochrome are brand signatures, not reusable tokens. +- Apple-scale whitespace without Apple-scale imagery and recognition becomes empty space. +- Massive editorial display type is inappropriate when it displaces the conversion action. +- Dark developer-tool styling must remain confined to authentic contract evidence, not become category cosplay. diff --git a/.impeccable/live/config.json b/.impeccable/live/config.json new file mode 100644 index 0000000..0229c47 --- /dev/null +++ b/.impeccable/live/config.json @@ -0,0 +1,6 @@ +{ + "files": ["src/routes/__root.tsx"], + "insertBefore": "", + "commentSyntax": "jsx", + "cspChecked": true +} diff --git a/.tasks/2026-07-18-TSK-3-landing-redesign-TASKS.md b/.tasks/2026-07-18-TSK-3-landing-redesign-TASKS.md new file mode 100644 index 0000000..6358f84 --- /dev/null +++ b/.tasks/2026-07-18-TSK-3-landing-redesign-TASKS.md @@ -0,0 +1,30 @@ +# TSK-3 — Landing Redesign + +**Overall status:** DONE + +## TG-001 — Product and Design Context + +- **Owner:** Main agent +- **Status:** DONE +- **Acceptance:** `PRODUCT.md`, `DESIGN.md`, official benchmark, and critique define a truthful non-generic direction. +- **Evidence:** Official Apple, Google, GitHub, Stripe, Cloudflare, and Linear surfaces were reviewed for hierarchy, proof, CTA, trust, and responsive patterns without copying trade dress. Impeccable v3.9.1 context, brand register, palette, and independent critique informed `PRODUCT.md` and `DESIGN.md`. Live mode is configured for the TanStack root document; no CSP was detected. + +## TG-002 — Product-Led Landing Surface + +- **Owner:** Main agent +- **Dependencies:** TG-001 +- **Status:** DONE +- **Acceptance:** Responsive page implements REQ-001 through REQ-007 without new UI dependencies. +- **Evidence:** The product owner rejected the true-white/cobalt pass as generic. The replacement uses a distinctive redline identity, a custom contract-path mark, locally hosted Martian Grotesk, an immediate breaking-change painkiller, and a clearly labelled review prototype. Desktop and 390px mobile full-page screenshots have been inspected. No UI dependency was added. + +## TG-003 — Release Validation + +- **Owner:** Main agent +- **Dependencies:** TG-002 +- **Status:** DONE +- **Acceptance:** REQ-008 and REQ-009 validation, independent review, preview acceptance, and CI pass. +- **Evidence:** The third visual direction is implemented. After product-owner review exposed an oversized desktop fold, the type scale, hero spacing, and downstream display sizes were tightened. The hero now uses the requested literal 7:5 copy-to-artifact grid with deliberate copy grouping and a stable single-column mobile fallback. Exact fold evidence at `.docs/TSK-3-fold-2048x1000.png` keeps the CTA and prototype visible without scrolling; full-page desktop and mobile evidence is also current. Accessibility, truthfulness, no-JavaScript, and narrow-screen checks pass. The product owner approved the updated preview on 2026-07-18; CI passes. + +## Ready Rule + +TG-003 and product-owner approval are complete. Merge is authorized by the approval; production remains separately gated. diff --git a/DESIGN.md b/DESIGN.md new file mode 100644 index 0000000..dde4e15 --- /dev/null +++ b/DESIGN.md @@ -0,0 +1,66 @@ +--- +name: OpenAPI Studio +description: A decisive review surface for API contract changes. +colors: + redline: '#cf2f1b' + ink: '#171310' + black: '#000000' + paper: '#f5f5f3' + white: '#ffffff' + muted: '#5e5853' + muted-light: '#aaa39d' + artifact-ink: '#e8e4dd' + artifact-muted: '#98918b' + artifact-rule: '#38332f' + rule: '#bcb7b0' + rule-light: '#cbc7c1' + impact: '#ff654b' + removed: '#ff8d7a' + removed-bg: '#39201d' + added: '#a4e1bc' + added-bg: '#173126' +typography: + family: 'Martian Grotesk' + displayWeight: 680 + displayStretch: '90%' + displayTracking: '-0.04em' + bodyLineHeight: 1.65 +rounded: + default: '0' +--- + +## Overview + +OpenAPI Studio is “precision under pressure”: an exacting contract-review instrument with the confidence of an editorial technology brand. Vermilion redline, black, white, and disciplined scale create recognition; the contract artifact supplies the substance. Never borrow another company’s trade dress. + +Physical scene: an API lead reviews a consequential contract diff on a bright office display, under time pressure, and needs the interface to feel exact rather than theatrical. + +## Color and Typography + +Redline is a committed brand field, not a small accent. Use ink and paper for long reading areas and impact coral only inside true breaking-change states. All pairings meet WCAG 2.2 AA. Martian Grotesk is locally hosted under OFL 1.1; use its width axis to make display type compact and assertive. Monospace belongs only inside contract artifacts. + +## Shape and Layout + +Stay structurally flat: square controls, hard rules, no ornamental radius, gradients, glass, or soft shadows. A single offset white plane may communicate the product artifact’s physical priority. Use a 90rem shell and asymmetric editorial grids. Each section gets a distinct narrative rhythm rather than repeated cards. + +### Composition Gates + +- Desktop H1 ceiling: `4.75rem`; mobile H1 ceiling: `4rem`; later display headings: `4.4rem` maximum. +- The desktop hero uses a literal `7:5` copy-to-artifact grid and collapses to one column at `64rem`. +- The 1440×900 and 2048×1000 folds must include the primary CTA, price condition, and complete review artifact without scrolling. +- Header plus hero may not exceed the initial viewport height at supported desktop sizes. +- Consequential copy—prototype status, pricing terms, privacy guidance, and artifact captions—never renders below `0.75rem`. +- Full-page screenshots validate rhythm; viewport-only screenshots validate conversion. Both are required. + +## Components + +Navigation shares the hero field and has one dark pilot action. Product artifacts must show plausible OpenAPI paths, diffs, and review consequences and must be labelled when illustrative. Buttons are at least 44px high with visible focus. Numbering is reserved for the genuine three-step workflow. + +## Guardrails + +- Lead with the painkiller: catch a breaking change before users do. +- Pair commercial claims with public source, delivery checks, or explicit boundaries. +- Never fabricate customers, screenshots, certifications, metrics, or availability. +- Avoid anonymous system-font minimalism, generic SaaS cards, decorative code, and fashionable effects. +- Validate desktop, mobile, keyboard, reduced motion, no-JavaScript rendering, and 200% zoom. +- Treat `.docs/design-reference-synthesis.md` as comparative guidance, not permission to copy another brand. diff --git a/PRODUCT.md b/PRODUCT.md new file mode 100644 index 0000000..d1260ea --- /dev/null +++ b/PRODUCT.md @@ -0,0 +1,49 @@ +# Product + +## Register + +brand + +## Platform + +web + +## Users + +The primary audience is founders, backend leads, platform engineers, API designers, and developer-experience leads on software teams of roughly 2–30 engineers. They actively maintain OpenAPI 3.0 or 3.1 contracts and need to move a real change from editing through review and publishing without breaking meaning or losing trust. + +## Product Purpose + +OpenAPI Studio is being built as a dependable workspace for maintaining an API contract as shared product infrastructure rather than fragile YAML. The commercial objective is to move from $0 to the first $1,000 MRR by earning five design partners and validating repeated use, willingness to pay, and retention before expanding the feature surface. + +## Positioning + +OpenAPI Studio gives small API teams one clear, reviewable path from contract change to published truth without requiring a heavyweight API platform. + +## Conversion & proof + +- Primary CTA: review one costly contract change through a qualified founding-pilot conversation. +- Secondary CTA: inspect the public source and delivery evidence on GitHub. +- The line to remember: catch the breaking change before your users do. +- Belief ladder: this is built for my team; it understands the real contract workflow; it is honest about what exists; its technical foundation is credible; the pilot is low-risk; $29 per workspace per month would be reasonable if it solves the repeated problem. +- Proof on hand: a public repository, passing CI, a live Cloudflare preview, explicit OpenAPI 3.0/3.1 scope, privacy-bounded conversion telemetry, and transparent pilot terms. There are no customers, testimonials, production editor screenshots, or usage claims yet; none may be implied. + +## Brand Personality + +Exacting, assured, and accountable. The emotional goal is controlled urgency: a carefully engineered instrument for consequential work, not a timid enterprise template or a loud startup pitch. + +## Anti-references + +Do not resemble generic AI-generated SaaS, anonymous white/cobalt enterprise minimalism, warm editorial templates, terminal cosplay, abstract gradients, repeated card grids, glassmorphism, or unearned Apple imitation. Do not fabricate product UI or claim a workflow is available when it is only planned. Urgency must name a real contract consequence, never manufacture fear. + +## Design Principles + +1. Evidence before persuasion: every claim sits beside a truthful artifact, boundary, or verifiable delivery fact. +2. One decision per fold: establish fit, show the workflow, resolve trust, then present the offer. +3. Enterprise restraint, startup honesty: use disciplined hierarchy and finish without pretending to have customers, scale, or capabilities that do not exist. +4. The contract is the visual subject: OpenAPI structure, changes, validation, and publishing provide the imagery—not generic decoration. +5. Conversion without pressure: make the five-team pilot, response expectation, and $29 post-pilot price explicit. + +## Accessibility & Inclusion + +Meet WCAG 2.2 AA for the complete landing-page journey. Preserve semantic landmarks and heading order, keyboard operation, visible focus, 44px touch targets, 200% zoom usability, sufficient text and control contrast, readable line lengths, reduced-motion behavior, JavaScript-independent content and CTAs, and layouts without horizontal overflow. diff --git a/public/fonts/MartianGrotesk-LICENSE.txt b/public/fonts/MartianGrotesk-LICENSE.txt new file mode 100644 index 0000000..68afb73 --- /dev/null +++ b/public/fonts/MartianGrotesk-LICENSE.txt @@ -0,0 +1,93 @@ +Copyright 2021 The Martian Grotesk Project Authors (https://github.com/evilmartians/grotesk) + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/public/fonts/MartianGrotesk.woff2 b/public/fonts/MartianGrotesk.woff2 new file mode 100644 index 0000000..97aad72 Binary files /dev/null and b/public/fonts/MartianGrotesk.woff2 differ diff --git a/specs/features/2026-07-18-landing-redesign/spec.md b/specs/features/2026-07-18-landing-redesign/spec.md new file mode 100644 index 0000000..9564ebf --- /dev/null +++ b/specs/features/2026-07-18-landing-redesign/spec.md @@ -0,0 +1,43 @@ +# Landing Redesign + +| Field | Value | +| --------------- | ------------------------------- | +| Feature ID | TSK-3 | +| Roadmap outcome | Phase 1 — Demand and Conversion | +| Status | SPEC_APPROVED | +| Owner | Product owner | +| Updated | 2026-07-18 | + +## Problem and Outcome + +The current landing page is technically sound but visually generic, commercially unconvincing, and unsupported by product evidence. It must be replaced before outreach. The redesign must establish enterprise-grade trust without copying another company or implying that the unfinished editor already exists. + +## Requirements + +- **REQ-001:** Replace the rejected cream, moss, terracotta, mono-kicker, oversized compressed headline, numbered-card, and decorative-gradient system. +- **REQ-002:** Lead with a precise OpenAPI contract outcome, intended team, honest pilot status, and one primary design-partner action. +- **REQ-003:** Show a high-fidelity, clearly labelled sample contract-review artifact above the fold; it must not be presented as a currently available application screenshot. +- **REQ-004:** Explain the proposed edit, review, and publish workflow using concrete OpenAPI structure rather than generic feature cards. +- **REQ-005:** State current proof and boundaries: public source, passing delivery checks, OpenAPI 3.0/3.1 focus, no checkout, no fabricated customers, and no production editor access. +- **REQ-006:** Present the founding offer as five design-partner places, a free pilot, and a transparent $29/workspace/month post-pilot hypothesis. +- **REQ-007:** Preserve the qualified mailto flow, first-party identifier-free conversion events, JavaScript-independent CTA, and existing privacy constraints. +- **REQ-008:** Meet WCAG 2.2 AA, keyboard, 200% zoom, reduced-motion, mobile, no-overflow, performance, and truthful-copy acceptance. +- **REQ-009:** Use existing Solid, Tailwind, and platform capabilities; add no UI or animation dependency. + +## Non-Goals + +- Building the editor, authentication, checkout, scheduling, CRM storage, testimonials, customer logos, or production deployment. +- Copying Apple, Google, GitHub, Stripe, Linear, or any other company’s trade dress. +- Adding sections merely to make the page appear complete. + +## Validation + +- Content and evidence review confirms every availability, security, and workflow claim is true. +- Desktop, 390px mobile, and 200% zoom screenshots receive explicit product-owner visual approval. +- Playwright verifies CTA destinations, $29 copy, semantic structure, JavaScript-disabled usability, accessibility, and no horizontal overflow. +- Impeccable critique and detector report no release-blocking design or technical findings. +- `bun run check`, preview smoke testing, and GitHub CI pass before merge. + +## Approval Gate + +The product owner rejected the existing visual direction and authorized an autonomous Impeccable-led replacement benchmarked against enterprise product-marketing standards. Preview deployment, merge, outreach resumption, and production/custom-domain operations remain separately gated. diff --git a/src/features/marketing/marketing-home.tsx b/src/features/marketing/marketing-home.tsx index 10bf498..4014296 100644 --- a/src/features/marketing/marketing-home.tsx +++ b/src/features/marketing/marketing-home.tsx @@ -6,199 +6,237 @@ const applicationBody = `Hi OpenAPI Studio, Team and product: Current OpenAPI workflow: -The recurring problem costing us time: -Typical specification size: +The recurring contract problem costing us time: Would we pay $29/workspace/month if this worked? Why or why not? Best, `.replaceAll('\n', '\r\n') -const applicationHref = `mailto:pitechae@gmail.com?subject=${encodeURIComponent('OpenAPI Studio design partner')}&body=${encodeURIComponent(applicationBody)}` +const applicationHref = `mailto:pitechae@gmail.com?subject=${encodeURIComponent('OpenAPI Studio founding pilot')}&body=${encodeURIComponent(applicationBody)}` +const repositoryHref = 'https://github.com/bymilon/openapi-studio-tanstack' + +function Mark() { + return ( + + ) +} export function MarketingHome() { onMount(() => recordConversion('page_viewed')) return (
-
- - OPENAPI/STUDIO - - - Design-partner pilot - -
- -
-
-

- For small teams maintaining OpenAPI 3.0 and 3.1 -

-

- Your API contract should not feel like a live grenade. -

-
-
-

- Edit, review, and publish OpenAPI contracts without YAML mistakes, silent breakage, or - documentation drift. -

-
+
+ + +
+ + +
+
+
+

+ Illustrative founding-pilot prototype · not a live editor +

+

+ billing-api.yaml PR #184 +

+
+ Impact detected +
+
+ GET + /invoices/{'{invoiceId}'} +
+
+ 42 + required: + 43 − + - dueDate + 43 + + - paymentDueAt +
+
+ ! +
+

Breaking change

+ Required response field removed +
+
+
+ + 1 breaking change - + + 2 review notes + + Needs a decision +
+
+ Illustrative prototype—not a screenshot of a currently available editor. +
+
+
+
+ +
+
+ +
+

Raw YAML tells you what moved. It rarely tells you what it costs.

+

The painkiller is a reviewable decision—not another text editor.

-

- No checkout. No fake instant access. We start with a direct conversation. -

-
-
-
-

- The contract is critical. The workflow around it is brittle. -

-

- OpenAPI is supposed to align engineering, product, customers, and tooling. In - practice, teams review raw diffs, repair indentation, and discover stale documentation - after the API has already moved. -

+
+
+
+ +

From changed line to team decision.

-
    - {[ - [ - '01', - 'Editing is fragile', - 'One malformed change can invalidate the document or quietly alter its meaning.', - ], - [ - '02', - 'Reviews lack context', - 'Text diffs hide the endpoint, schema, and compatibility consequences reviewers actually need.', - ], - [ - '03', - 'Published docs drift', - 'When editing and publishing are separate chores, consumers stop trusting the contract.', - ], - ].map(([number, title, description]) => ( -
  1. - {number} -

    {title}

    -

    {description}

    -
  2. - ))} +
      +
    1. + 01 +
      +

      See the removed field

      +

      Keep dueDate beside its response path, operation, and schema context.

      +
      +
    2. +
    3. + 02 +
      +

      Assess the consequence

      +

      Decide whether consumers can absorb the rename to paymentDueAt.

      +
      +
    4. +
    5. + 03 +
      +

      Approve the new truth

      +

      Publish only after the team resolves the breaking change.

      +
      +
-
-

- What we are building with design partners -

-

- One dependable path from contract change to published truth. -

-
- {[ - [ - 'Import', - 'Bring a real JSON or YAML contract in without flattening its OpenAPI semantics.', - ], - [ - 'Review', - 'Understand validation issues and meaningful changes before they reach consumers.', - ], - [ - 'Publish', - 'Generate documentation from the same canonical contract the team approved.', - ], - ].map(([title, description], index) => ( -
- 0{index + 1} -

{title}

-

{description}

-
- ))} +
+
+
+ +

Inspect the work before you trust the promise.

+
+
+

+ OpenAPI Studio is an early founding pilot, not a finished self-serve product. The + public build targets OpenAPI 3.0/3.1, deploys to a Cloudflare preview, and records + identifier-free conversion events. No invented customers. No fake screenshots. No + checkout. +

+ recordConversion('repository_clicked')}> + Inspect public source + + recordConversion('repository_clicked')} + > + Inspect delivery checks + +
-
-
+
+
-

- The design-partner offer -

-

- Help shape the workflow before we scale the feature list. -

-

- Bring a real contract and the recurring problem around it. We will work directly with - a small group of teams, prioritize repeated pain, and be explicit about what is not - built yet. -

+ +

Bring the contract change your team keeps paying for.

-
-

- Price hypothesis after pilot +

+ $ + 29 +

+ per workspace / month +
+ after a free pilot

-

$29

-

per workspace / month

-

- Pilot scope and terms are confirmed in conversation. There is no charge today. +

+
+

+ Built and run by{' '} + Milon Biswas, independent founder. Email only + the problem and workflow first—no contract upload or confidential material. Personal + reply within two business days.

recordConversion('design_partner_clicked')} > - Start the conversation - + Apply by email
-
) diff --git a/src/routes/index.tsx b/src/routes/index.tsx index 4983201..e12fdcd 100644 --- a/src/routes/index.tsx +++ b/src/routes/index.tsx @@ -10,7 +10,7 @@ export const Route = createFileRoute('/')({ { name: 'description', content: - 'Edit, review, and publish OpenAPI contracts without YAML mistakes or documentation drift.', + 'A design-partner pilot for small teams building a dependable OpenAPI contract workflow.', }, ], }), diff --git a/src/styles.css b/src/styles.css index aa244cd..bb0cb06 100644 --- a/src/styles.css +++ b/src/styles.css @@ -1,48 +1,617 @@ @import 'tailwindcss'; +@font-face { + font-family: 'Martian Grotesk'; + src: url('/fonts/MartianGrotesk.woff2') format('woff2-variations'); + font-weight: 100 1000; + font-stretch: 75% 200%; + font-display: swap; +} + @theme { - --color-ink: #17211b; - --color-paper: #f4f0e6; - --color-accent: #b9422c; - --color-moss: #244d3b; - --font-sans: 'Avenir Next', Avenir, 'Segoe UI', sans-serif; - --font-mono: 'IBM Plex Mono', 'SFMono-Regular', Consolas, monospace; + --font-sans: 'Martian Grotesk', Arial, sans-serif; + --font-mono: ui-monospace, 'SFMono-Regular', Consolas, monospace; } :root { - color: var(--color-ink); - background: var(--color-paper); - font-family: 'Avenir Next', Avenir, 'Segoe UI', sans-serif; + color: #12100f; + background: #f5f5f3; + font-family: var(--font-sans); font-synthesis: none; text-rendering: optimizeLegibility; } - * { box-sizing: border-box; } - +html { + scroll-behavior: smooth; +} body { margin: 0; min-width: 20rem; - background: - radial-gradient(circle at 10% 5%, rgb(232 93 63 / 12%), transparent 28rem), var(--color-paper); } - a { - text-underline-offset: 0.2em; + color: inherit; +} +p, +h1, +h2, +h3, +figure { + margin: 0; +} +h1, +h2, +h3 { + text-wrap: balance; } - ::selection { - color: var(--color-paper); - background: var(--color-moss); + color: #fff; + background: #171310; +} +.shell { + width: min(100% - 2.5rem, 90rem); + margin-inline: auto; } -@media (prefers-reduced-motion: no-preference) { - .cta-arrow { - transition: transform 160ms ease; - } +.brand-hero { + color: #171310; + background: #f5f5f3; +} +.site-header { + display: flex; + min-height: 5rem; + align-items: center; + justify-content: space-between; +} +.wordmark, +.footer-brand { + display: inline-flex; + align-items: center; + gap: 0.75rem; + font-size: 0.78rem; + font-weight: 760; + letter-spacing: -0.02em; + text-decoration: none; +} +.brand-mark { + width: 2rem; + height: 2rem; + fill: none; + stroke: currentColor; + stroke-width: 2.3; + color: #cf2f1b; +} +nav { + display: flex; + align-items: center; + gap: 2rem; +} +.nav-link, +.text-link { + font-size: 0.76rem; + font-weight: 650; + text-decoration: none; +} +.nav-link:hover, +.text-link:hover { + text-decoration: underline; + text-underline-offset: 0.3em; +} +.button { + display: inline-flex; + min-height: 3.25rem; + align-items: center; + justify-content: center; + gap: 1rem; + padding: 0.9rem 1.25rem; + border: 1px solid transparent; + font-size: 0.75rem; + font-weight: 760; + line-height: 1.2; + text-decoration: none; + transition: + transform 150ms ease, + background 150ms ease; +} +.button:hover { + transform: translateY(-2px); +} +.button-dark { + color: #fff; + background: #171310; +} +.button-dark:hover { + background: #000; +} +.button-light { + color: #171310; + background: #fff; +} +.button-compact { + min-height: 2.75rem; + padding: 0.7rem 1rem; +} +a:focus-visible { + outline: 3px solid #fff; + outline-offset: 4px; +} +.brand-hero a:focus-visible { + outline-color: #cf2f1b; +} +.brand-hero .button-dark:focus-visible { + outline-color: #171310; +} +.evidence-section a:focus-visible, +.site-footer a:focus-visible { + outline-color: #cf2f1b; +} + +.hero { + display: grid; + grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); + gap: clamp(2.5rem, 4vw, 4.5rem); + align-items: center; + padding-block: clamp(2.5rem, 5vw, 4.5rem) clamp(4rem, 7vw, 6rem); +} +.hero-copy { + display: flex; + flex-direction: column; + align-items: flex-start; + gap: 0; +} +.eyebrow, +.section-label { + font-size: 0.75rem; + font-weight: 720; + letter-spacing: 0.09em; + text-transform: uppercase; +} +.eyebrow { + display: flex; + align-items: center; + gap: 0.85rem; +} +.eyebrow span { + padding: 0.4rem 0.5rem; + color: #fff; + background: #cf2f1b; +} +h1 { + max-width: 11.5ch; + font-size: clamp(3.25rem, 5vw, 4.75rem); + font-stretch: 92%; + font-weight: 720; + letter-spacing: -0.04em; + line-height: 0.94; + color: #cf2f1b; +} +.hero-copy h1 { + margin-top: 1rem; +} +.hero-lead { + max-width: 42rem; + margin-top: 0.75rem; + font-size: clamp(1rem, 1.35vw, 1.22rem); + font-stretch: 96%; + line-height: 1.65; +} +.hero-actions { + display: flex; + flex-wrap: wrap; + align-items: center; + gap: 1rem 1.5rem; + margin-top: 1.5rem; +} +.availability { + margin-top: 0.75rem; + font-size: 0.78rem; + line-height: 1.5; +} - a:hover .cta-arrow { - transform: translateX(0.2rem); +.contract-artifact { + color: #e8e4dd; + background: #171310; + box-shadow: 0 0 0 1px #38332f; +} +.artifact-top { + display: flex; + flex-wrap: wrap; + justify-content: space-between; + gap: 1rem; + padding: 1.4rem 1.5rem; + border-bottom: 1px solid #38332f; +} +.artifact-kicker, +figcaption { + color: #98918b; + font-size: 0.75rem; + line-height: 1.5; +} +.artifact-title { + margin-top: 0.3rem; + font-size: 0.76rem; + font-weight: 700; +} +.artifact-title span { + margin-left: 0.4rem; + color: #98918b; + font-weight: 450; +} +.impact-state { + align-self: center; + padding: 0.4rem 0.55rem; + color: #171310; + background: #ff654b; + font-size: 0.75rem; + font-weight: 780; + text-transform: uppercase; +} +.operation-row { + display: flex; + align-items: center; + gap: 0.8rem; + padding: 1.3rem 1.5rem; + border-bottom: 1px solid #38332f; +} +.operation-row code, +.diff { + font-family: var(--font-mono); + font-size: 0.73rem; +} +.method { + padding: 0.3rem 0.42rem; + color: #171310; + background: #fff; + font-size: 0.75rem; + font-weight: 850; +} +.diff { + display: grid; + grid-template-columns: 3.5rem minmax(0, 1fr); + padding-block: 1rem; +} +.diff span, +.diff code { + min-height: 2.15rem; + padding-block: 0.4rem; +} +.diff span { + padding-inline: 0.8rem; + color: #98918b; + text-align: right; +} +.diff code { + padding-inline: 0.8rem; + white-space: pre-wrap; +} +.diff .removed { + color: #ff8d7a; + background: #39201d; +} +.diff .added { + color: #a4e1bc; + background: #173126; +} +.impact-callout { + display: flex; + align-items: center; + gap: 1rem; + margin: 0.4rem 1.5rem 1.5rem; + padding: 1rem; + color: #171310; + background: #ff654b; +} +.impact-icon { + display: grid; + width: 2rem; + height: 2rem; + place-items: center; + border: 2px solid #171310; + border-radius: 50%; + font-weight: 900; +} +.impact-callout p { + font-size: 0.75rem; + font-weight: 800; + letter-spacing: 0.08em; + text-transform: uppercase; +} +.impact-callout strong { + font-size: 0.82rem; +} +.review-summary { + display: flex; + flex-wrap: wrap; + align-items: center; + gap: 1rem 1.5rem; + padding: 1rem 1.5rem; + border-top: 1px solid #38332f; + font-size: 0.75rem; +} +.review-summary b { + color: #fff; + font-size: 0.85rem; +} +.review-summary strong { + margin-left: auto; + color: #ff654b; +} +figcaption { + padding: 0 1.5rem 1.25rem; +} + +.pain-section { + padding-block: clamp(4rem, 8vw, 7rem); + color: #fff; + background: #171310; +} +.pain-grid { + display: grid; + grid-template-columns: 0.35fr 1.65fr; + gap: 3rem; +} +.pain-section .section-label { + color: #ff654b; +} +.pain-section h2 { + max-width: 21ch; + font-size: clamp(2.4rem, 4vw, 4.4rem); + font-stretch: 90%; + font-weight: 650; + letter-spacing: -0.035em; + line-height: 1; +} +.pain-section h2 + p { + max-width: 38rem; + margin-top: 2.25rem; + color: #aaa39d; + font-size: 1.1rem; + line-height: 1.6; +} + +.workflow-section { + padding-block: clamp(4rem, 8vw, 7rem); + background: #f5f5f3; +} +.section-intro { + display: grid; + grid-template-columns: 0.35fr 1.65fr; + gap: 3rem; + margin-bottom: 4rem; +} +.section-intro h2, +.evidence-grid h2 { + max-width: 15ch; + font-size: clamp(2.4rem, 4vw, 4.25rem); + font-stretch: 90%; + font-weight: 680; + letter-spacing: -0.04em; + line-height: 1; +} +.workflow-list { + margin: 0; + padding: 0; + border-top: 1px solid #bcb7b0; + list-style: none; +} +.workflow-list li { + display: grid; + grid-template-columns: 0.35fr 1.65fr; + gap: 3rem; + padding-block: 2.5rem; + border-bottom: 1px solid #bcb7b0; +} +.step-number { + color: #cf2f1b; + font-size: 0.7rem; + font-weight: 800; +} +.workflow-list h3 { + font-size: clamp(1.4rem, 2.4vw, 2.2rem); + font-stretch: 92%; + font-weight: 700; + letter-spacing: -0.03em; +} +.workflow-list p { + max-width: 44rem; + margin-top: 0.75rem; + color: #5e5853; + font-size: 0.9rem; + line-height: 1.65; +} + +.evidence-section { + padding-block: clamp(4rem, 8vw, 7rem); + background: #fff; +} +.evidence-grid { + display: grid; + grid-template-columns: 1.15fr 0.85fr; + gap: clamp(3rem, 9vw, 9rem); +} +.evidence-grid .section-label { + margin-bottom: 2rem; + color: #cf2f1b; +} +.evidence-copy { + align-self: end; +} +.evidence-copy p { + max-width: 33rem; + color: #5e5853; + font-size: 1rem; + line-height: 1.75; +} +.evidence-copy a { + display: flex; + justify-content: space-between; + padding-block: 1.2rem; + border-bottom: 1px solid #cbc7c1; + font-size: 0.75rem; + font-weight: 720; + text-decoration: none; +} +.evidence-copy p + a { + margin-top: 2.5rem; + border-top: 1px solid #cbc7c1; +} +.evidence-copy a:hover { + color: #cf2f1b; +} + +.offer-section { + padding-block: clamp(4rem, 8vw, 7rem); + color: #fff; + background: #171310; + border-top: 0.75rem solid #cf2f1b; +} +.offer-grid { + display: grid; + grid-template-columns: 1.2fr 0.45fr 0.65fr; + gap: clamp(2rem, 6vw, 6rem); + align-items: end; +} +.offer-section h2 { + max-width: 17ch; + margin-top: 1.5rem; + font-size: clamp(2.4rem, 3.7vw, 4rem); + font-stretch: 91%; + font-weight: 680; + letter-spacing: -0.04em; + line-height: 1; +} +.price { + display: grid; + grid-template-columns: auto auto; + align-items: start; +} +.price > span { + margin-top: 0.8rem; + font-size: 1rem; +} +.price strong { + font-size: clamp(4.5rem, 8vw, 7.5rem); + font-stretch: 80%; + font-weight: 680; + letter-spacing: -0.07em; + line-height: 0.8; +} +.price p { + grid-column: 1 / -1; + margin-top: 1rem; + font-size: 0.75rem; + line-height: 1.6; +} +.offer-action { + display: flex; + flex-direction: column; + gap: 1rem; +} +.offer-trust { + max-width: 28rem; + font-size: 0.78rem; + line-height: 1.6; +} +.offer-trust a { + font-weight: 720; + text-underline-offset: 0.2em; +} +.site-footer { + display: flex; + min-height: 7rem; + align-items: center; + justify-content: space-between; + gap: 2rem; + font-size: 0.75rem; +} +.site-footer > div:last-child { + display: flex; + gap: 1.5rem; +} + +@media (max-width: 64rem) { + .hero { + grid-template-columns: 1fr; + } + .contract-artifact { + width: min(100% - 1.25rem, 48rem); + } + .offer-grid { + grid-template-columns: 1fr 1fr; + } + .offer-action { + grid-column: 1 / -1; + } +} +@media (max-width: 44rem) { + .shell { + width: min(100% - 2rem, 90rem); + } + .site-header { + min-height: 5rem; + } + nav { + gap: 0.75rem; + } + .nav-link { + display: none; + } + .hero { + padding-top: 2.5rem; + } + h1 { + font-size: clamp(2.8rem, 13vw, 4rem); + } + .hero-actions, + .hero-actions .button { + width: 100%; + } + .contract-artifact { + box-shadow: 0 0 0 1px #38332f; + } + .artifact-top { + align-items: flex-start; + flex-direction: column; + } + .review-summary strong { + width: 100%; + margin-left: 0; + } + .pain-grid, + .section-intro, + .workflow-list li, + .evidence-grid, + .offer-grid { + grid-template-columns: 1fr; + gap: 1.5rem; + } + .section-intro { + margin-bottom: 3rem; + } + .workflow-list li { + gap: 0.75rem; + } + .evidence-grid { + gap: 4rem; + } + .offer-action { + grid-column: auto; + } + .site-footer { + align-items: flex-start; + flex-direction: column; + justify-content: center; + padding-block: 2rem; + } +} +@media (prefers-reduced-motion: reduce) { + html { + scroll-behavior: auto; + } + *, + *::before, + *::after { + transition-duration: 0.01ms !important; } } diff --git a/tests/browser/marketing.test.ts b/tests/browser/marketing.test.ts index 6d8dcd9..418522d 100644 --- a/tests/browser/marketing.test.ts +++ b/tests/browser/marketing.test.ts @@ -14,26 +14,29 @@ test('presents a truthful design-partner conversion path', async ({ page }) => { await expect( page.getByRole('heading', { level: 1, - name: 'Your API contract should not feel like a live grenade.', + name: 'Catch the breaking change before your users do.', }), ).toBeVisible() - const application = page.getByRole('link', { name: 'Apply to become a design partner' }) + const application = page.getByRole('link', { name: 'Email the founder about the pilot' }) const applicationUrl = new URL((await application.getAttribute('href')) ?? '') expect(applicationUrl.protocol).toBe('mailto:') expect(applicationUrl.pathname).toBe('pitechae@gmail.com') - expect(applicationUrl.searchParams.get('subject')).toBe('OpenAPI Studio design partner') + expect(applicationUrl.searchParams.get('subject')).toBe('OpenAPI Studio founding pilot') expect(applicationUrl.searchParams.get('body')).toContain('Team and product:') expect(applicationUrl.searchParams.get('body')).toContain('Current OpenAPI workflow:') expect(applicationUrl.searchParams.get('body')).toContain( - 'The recurring problem costing us time:', + 'The recurring contract problem costing us time:', ) - expect(applicationUrl.searchParams.get('body')).toContain('Typical specification size:') expect(applicationUrl.searchParams.get('body')).toContain( 'Would we pay $29/workspace/month if this worked? Why or why not?', ) - await expect(page.getByText('No checkout. No fake instant access.')).toBeVisible() - await expect(page.getByRole('link', { name: 'View source on GitHub' })).toHaveAttribute( + await expect( + page.getByText('No invented customers. No fake screenshots. No checkout.'), + ).toBeVisible() + await expect(page.getByText('Illustrative prototype—not a screenshot')).toBeVisible() + await expect(page.getByText('no contract upload or confidential material')).toBeVisible() + await expect(page.getByRole('link', { name: 'Inspect public source' })).toHaveAttribute( 'href', 'https://github.com/bymilon/openapi-studio-tanstack', ) @@ -47,7 +50,11 @@ test('has no detectable accessibility violations and a usable tab order', async await page.keyboard.press('Tab') await expect(page.getByRole('link', { name: 'OpenAPI Studio home' })).toBeFocused() await page.keyboard.press('Tab') - await expect(page.getByRole('link', { name: 'Apply to become a design partner' })).toBeFocused() + await expect(page.getByRole('link', { name: 'Workflow', exact: true })).toBeFocused() + await page.keyboard.press('Tab') + await expect(page.getByRole('link', { name: 'Evidence' })).toBeFocused() + await page.keyboard.press('Tab') + await expect(page.getByRole('link', { name: 'Join pilot' })).toBeFocused() }) test('keeps the offer usable on a narrow screen without JavaScript', async ({ browser }) => { @@ -60,8 +67,8 @@ test('keeps the offer usable on a narrow screen without JavaScript', async ({ br await page.goto('/') await expect(page.getByRole('main')).toBeVisible() - await expect(page.getByRole('link', { name: 'Apply to become a design partner' })).toBeVisible() - await expect(page.getByText('$29')).toBeVisible() + await expect(page.getByRole('link', { name: 'Email the founder about the pilot' })).toBeVisible() + await expect(page.getByText('per workspace / month')).toBeVisible() expect((await page.locator('body').evaluate((body) => body.scrollWidth)) <= 360).toBe(true) await context.close()