Skip to content

2026 rebrand: redesigned site, docs and blog branding, Prisma 8 - #8142

Open
nurul3101 wants to merge 70 commits into
mainfrom
shane/launch
Open

2026 rebrand: redesigned site, docs and blog branding, Prisma 8#8142
nurul3101 wants to merge 70 commits into
mainfrom
shane/launch

Conversation

@nurul3101

@nurul3101 nurul3101 commented Aug 11, 2026

Copy link
Copy Markdown
Member

[DO NOT MERGE YET]

The 2026 rebrand across the marketing site, docs, and blog, shipped as one PR.

Marketing site (apps/site-redesign)

A self-contained app carrying the CF redesign. It replaces apps/site at cutover.

  • CF-built pages: homepage, pricing (V2 copy), product template, and the /orm, /postgres, /compute pages from the approved V4 copy with the interactive platform stack (cf/feature/6-product-pages merged).
  • Real pages ported from the old site and rebuilt in the new design system: /customers, /company, /company/careers, /changelog (all 55 entries), /legal/{privacy,terms,sla,security-and-compliance}, /support, /community, /stack (interim), /programs with startups/partners/oss-friends subpages, and /enterprise.
  • Legacy paths (/about, /careers, /case-studies, /privacy, /terms, /sla, /startups, /partners, /oss-friends) 308-redirect to their new homes.
  • Footer links Trust Center, Status, and Data Guide to their real external homes; sitemap lists real routes only; CF's dead-end demo form removed.

Docs (apps/docs)

  • Chrome rebranded onto eclipse tokens: Sora display and Inter body (the Mona Sans override that suppressed the brand is gone), light and dark shells remapped (paper sidebar, ink dark mode replacing the old navy), new logo lockup, new favicons.

Blog (apps/blog)

  • Docs design pulled in: cyan accent hovers, the docs TOC treatment, dark-mode surface lifts, paper footer. Also flushed a stale pre-rebrand CSS compile that dev servers were serving.
  • New favicons, and the seven most recent 2026 covers regenerated in the new brand (paper surfaces, prism accents, Sora), each keeping its post's real data.
  • The content-create-hero-image skill rewritten for the new brand (tokens, design system, template, fonts, logos), version 2026.8.11.

Also included

  • Merge of origin/main (through "Drop default UTM params", including the Aug 7 privacy-policy DPF update, re-synced into the ported legal page).
  • Merge of origin/prisma-8-rebrand (Prisma Next renamed to Prisma 8, docs moved /next to /v8 with permanent redirects, RC status). That branch's PR can be closed unmerged; content main added after its freeze was renamed to match.

Deploy notes

  • The careers page's open roles need NEXT_PUBLIC_BOARD_ID in the site-redesign environment (same var apps/site uses).
  • site-redesign changelog entry images intentionally load from www.prisma.io (78MB not duplicated); assets move at cutover.
  • No Vercel project builds apps/site-redesign yet, so it gets no preview deployments until one is created (root directory apps/site-redesign).

andrefiori-cf and others added 30 commits July 24, 2026 09:28
…approved homepage

Self-contained workspace app carrying its own toolkit (Next.js 16,
Tailwind v4, React 19) so the redesign can evolve without touching
apps/site or the shared packages. Snapshot of the client-approved
homepage from the CF prototype repo (its PR #7). Refs #1

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Generic product page template (hero, problem, features, platform
cross-sell, CTA) from the prototype repo's approved outline, plus the
new brand components it introduced (GlassGlide, IconTile, LearnMore)
and the /postgres page built on it. Copy slots are placeholders until
each product's copy is approved. Refs #2

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
From the V2 copy doc; sections past these are blocked on the client's
answers to the open copy questions. Refs #5

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Completes /pricing against the V2 copy doc: plan cards, calculator,
comparison, testimonials, CTA and FAQs, plus the fixes needed to make the
app build in production for the first time.

Pricing data — every figure confirmed by Gregory and cross-checked against
the live prisma.io/pricing page and its calculator:
  - Business gains an operations overage rate ($0.0010 per 1,000), which V2
    listed for Starter and Pro only
  - Business storage overage is $1.00/GB, taken from the live page. The
    calculator previously carried $1.50/GB copied from Pro, which
    overcharged every Business storage estimate
  - "No connection limits" removed — pooled limits do exist (10/100/500/1000)

Calculator rebuilt to match the live one: quick-start presets, an
operations slider that also reports estimated SQL queries (5x), monthly and
annual billing (-25%), and all three paid plans priced with the cheapest
recommended. Verified figure-for-figure against prisma.io/pricing.

Design system:
  - RoleKicker promoted out of stack-bento into a shared brand component and
    documented in /brand as the standard tagline. Four uppercase, letter-
    spaced eyebrows that never matched the homepage are now kickers
  - --paper added as an opt-in resting surface. --card is unchanged, so no
    other surface on the site moves

Build fixes, all pre-existing:
  - react-icons was never installed, so the relume-library scaffold failed
    with 983 module-not-found errors and no production build could succeed
  - button.tsx failed type-checking on a Slot/button handler union
  - badge.tsx needed "use client" — its radix-ui Slot import calls
    createContext, which 500'd every server page importing Badge (/brand)

Mobile: hero grid children were 25px wider than their track and clipped by
the panel; slider hit areas were 24px against a 44px touch minimum.

allowedDevOrigins set so the dev server can be opened over the LAN.

Co-Authored-By: Claude <noreply@anthropic.com>
The how-it-works, plans and calculator sections carried their horizontal
padding inside the max-w-6xl container, so the 1152px box was 1088px of
content plus 32px of padding — content sat 32px in from where it should and
ran 64px narrow.

Padding now sits on the <section> and max-w-6xl is the content box, matching
how-it-works.tsx on the homepage ("Ship a production TypeScript app in three
steps"), which is the standard for unwrapped sections. All three now measure
1152px starting at x=224, identical to the reference.

Co-Authored-By: Claude <noreply@anthropic.com>
The early-access major version keeps its working-name identifiers but is
now called Prisma 8 everywhere users read it:

- All prose, frontmatter, changelog entries, and UI labels (docs version
  dropdown now "v8 (Early Access)"; sidebar matchers keep URL fallbacks).
- Reworded ~35 now-redundant "becomes Prisma 8 at GA" sentences and the
  announcement post's naming section; added a one-line editor's note to
  the nine posts that were about Prisma Next under its working name.
- Replaced 14 images carrying the old wordmark: outlined badge/headline
  text in the teal covers swapped for live Mona Sans text, the indigo
  announcement family (incl. roadmap, TS-migrations, EA meta and the
  docs sidebar banner) rebuilt from the announcement SVG, and metas
  re-rendered from their heroes. Hero-image skill logos renamed to
  prisma-8-*.
- Fixed 27 links pointing at renamed heading anchors.

Deliberately unchanged (product-owned identifiers and live URLs):
create prisma@next npm dist-tags, the prisma-next CLI and config file,
the @prisma-next/* npm scope, /docs/orm/next URL segments (GA cutover
plan in next.config.mjs), published blog slugs, pris.ly/pn-* links,
Discord #prisma-next channels, and the EA banner CSS selectors that
PostHog CTA actions target.

Verified: types:check (docs, blog), lint:links, lint:agent-ready,
test:llm-markdown, lint:spellcheck, pnpm check, plus rendered-page and
image review on dev servers. Pre-commit hook skipped (pnpm is not
callable in this non-interactive shell); its check command was run
manually and passed.
Everywhere the site describes Prisma 8's current stage now says the
Release Candidate is available instead of Early Access:

- Docs: the EA banner, the version dropdown ("v8 (RC)"), section
  meta.json titles, llms.txt topics, the standard "Prisma 8 is in Early
  Access" callout on nine pages, and status prose across the next tree.
- New "release-candidate" badge type (badge-types.ts drives the zod
  enum, label, and color maps); the 41 Prisma 8 pages switched to it.
  Other products keep the early-access badge (e.g. the Postgres
  serverless driver) and the generic maturity-tier docs are untouched.
- Blog: the "Looking ahead" footers, per-post status notes, and
  pris.ly/pn-ea link text; site stack page descriptions.

Kept as historical artifacts: the Early Access announcement post
(title, slug, cover, body), launch-story references to it, dated
changelog entries, the April roadmap metaDescription, and every other
product's Early Access mentions.

Verified: docs types:check, lint:links, lint:agent-ready,
test:llm-markdown, lint:spellcheck, pnpm check, and rendered-page
checks on dev servers (banner, dropdown, callouts, footers, ltree
heading). Pre-commit hook skipped; its check command was run manually
and passed.
Shane Neubauer's feedback (2026-07-29), which also corrected several things
their own live pricing page currently gets wrong.

Corrections applied:
  - No annual billing. The monthly/yearly toggle and the 25% discount are
    removed — their live page offers annual, and Shane confirms they don't.
  - The "5x SQL queries per operation" readout is a stale technical detail
    that is no longer true. Removed; the caption now reads 1 query =
    1 operation.
  - "Most popular" moves from Pro to Starter, to anchor on the lower price
    rather than making Prisma read as more expensive than Vercel. This
    overrides the approved V2 copy, which puts it on Pro.
  - Free states that it is free forever.

Calculator recommendations were broken: with the presets copied from the live
calculator (12M / 36M / 84M ops) every preset recommended Pro or Business, so
Starter was never recommended and Free never appeared at all. Presets are now
100K/0.5GB, 1M/8GB and 20M/40GB, which recommend Free, Starter and Pro
respectively, and Free is priced alongside the paid plans instead of being
excluded — it goes "Not available" above its caps.

New detailed spec table (Shane: "these tend to be quite important for our
users"; also the full limits table Ankur asked for). Rows and values come from
their live "Compare plans" table so the structure matches what their users
already know.

Anything not confirmed is a visible TBC placeholder rather than a guess:
  - Supabase comparison column — Shane asked for it, no figures supplied
  - Free-tier backup retention — absent from their own table
  - Support tiers — live page says Standard/Premium, Gregory's notes said
    24h/2h response times
  - Global cache rows — published as a Postgres feature, but Gregory said
    Accelerate is being deprecated
Placeholders render as a dashed TBC badge, deliberately distinct from an em
dash, which means "not included on that plan".

Still outstanding: the plan cards are not above the fold, and the $385-450 vs
$70-90 comparison figures and "up to 5x" claim remain unverified.

Co-Authored-By: Claude <noreply@anthropic.com>
Plan cards move directly under the hero so the prices are reachable without
hunting for them (Shane's ask). This does not fully satisfy "visible without
scrolling" — measured, the cards still start 182px below the fold at 1440x800,
and reordering alone cannot close that: below the 100px fixed header there is
700px of room and the card block is 605px, leaving 95px for the whole hero.
Finishing it needs the hero compacted, which costs approved V2 copy and so
needs a copy decision.

Comparison section: the price gap is the argument, so it is now drawn — cost
bars scaled from the figures, with the Supabase column's unknown rendered as a
dashed empty track rather than zero. Bars and the savings multiple are derived
from the cost strings so the figures keep one source of truth and the multiple
cannot drift from the copy. Note this makes the section lean harder on the
still-unverified $385-450 / $70-90 numbers.

Also fixes the Supabase column reading as a claim about Supabase: it used an em
dash, which this page states in print means "not included on that plan". It now
uses the dashed TBC badge, matching the spec table.

Badges: rounded-full belongs to prism-button, whose two variants are a dark
filled pill and a white outlined pill — so a pill badge reads as a CTA whichever
way it is filled. Adds brand/marker.tsx, a squared chip with colour in a dot per
the role-kicker rule, and moves all four badge sites onto it.

Spec table: the group headers were uppercase and letter-spaced, which the brand
rule forbids; they are now sentence case with a coloured glyph per group. Adds
the hero's conic halo at a third of its opacity. Below lg the table is pivoted
feature-first — it was 832px wide against a 356px viewport, so two plans sat
outside a scroller with nothing to signal them. Rows identical across all four
plans (12 of 23) collapse to one line, which keeps the pivot short and makes the
rows that actually differ the prominent ones.

Co-Authored-By: Claude <noreply@anthropic.com>
Builds the ORM product page on the existing template, plus the two
top-level sections V4 adds that the template had no slot for: the
migrations argument and the fast-feedback blocks.

Copy is verbatim from the Notion card "Product Page Batch One (3-5) -
Copy", toggle V4. The code previously pointed at V1, which is the oldest
draft — different headlines, different CTAs, fewer sections. Comments now
name V4 so the next page doesn't repeat the mistake.

Three template changes were needed to fit real copy:

- The closer is per-page content now. Review feedback flagged all three
  product pages ending on an identical paragraph as reading templated,
  so nothing in it is defaulted or appended.
- Features pick their column count from the item count. V4 ships 3 (ORM),
  4 (Compute) and 5 (Postgres), and a row of three beats two-plus-an-orphan.
- "Learn more" links only render where the copy names a destination,
  rather than pointing at a guessed /docs.

Five hand-built abstractions follow the homepage idiom (real labels and
commands over skeleton lines): the schema file, the migration history as
a git-style graph, and one per feature. Space for the 3D renders is
reserved and sized where the cards have room for it, and the agent
character from the homepage's agent-loop section stands in as the runner
of the feedback loop.

Refs #2
Second product page on the /orm layout. Copy is verbatim from the Notion
card "Product Page Batch One (3-5) - Copy", toggle V4.

V4 shapes this page differently from /orm in two ways that matter:

- No testimonial section. /orm and /postgres carry one and Compute does
  not, so this composes the sections directly rather than going through
  ProductPage, which always renders them.
- No "in public beta" callout. V3 had one and V4 dropped it. The homepage
  still labels Compute as beta, so this is easy to reintroduce by
  accident — noted in the content file.

Four features, so the grid resolves to two rows of two on its own.

Five new abstractions in the established idiom: a deployments panel
pairing each environment's app with its branched database, and one per
feature. The co-located one shows the round trip disappearing without
inventing a latency figure — the only unit on it is the microseconds the
copy itself claims.

Refs #2
Third and last product page, replacing the placeholder instance. Copy is
verbatim from the Notion card "Product Page Batch One (3-5) - Copy",
toggle V4.

This is the one page whose approved copy matches the template's standard
shape exactly, so it goes through ProductPage rather than composing its
own sections — which is what that wrapper is for.

Five features is the count with no tidy answer: three-then-two hangs left,
two-two-one leaves an orphan. Six tracks with every card spanning two gives
three per row, and starting the fourth at track two centres the remaining
pair beneath them. Card widths stay identical and both rows centre on the
same axis.

Two accuracy calls in the illustrations:

- The certifications are Business-tier in the copy, so the compliance card
  labels the tier rather than leaving it to imply they apply everywhere.
- "no cold starts" stays in the body copy where V4 put it, but is kept out
  of the artwork: a standing guardrail says not to promote it to a claim.

The pricing card carries no figures either — the claim is the shape of the
bill, not a price, so the meter and its cap are unnumbered.

Refs #2
The product hero eyebrow rendered as uppercase, letter-spaced, grey text
— the exact three things /brand documents the tagline must never be.
The homepage uses RoleKicker: sentence case, ink at 70%, colour carried by
a dot. The heroes now use it too, so the tagline reads the same everywhere.

The eyebrow predates RoleKicker, which arrived with the pricing branch, so
these pages inherited a treatment the style guide had since replaced.

Adds PLATFORM_PRODUCT_ACCENTS beside PLATFORM_PRODUCT_ICONS: one canonical
dot colour per product — ORM cyan, Postgres yellow, Compute red — matching
the homepage stack and the /brand examples, so pages can't drift from it.
Content names its product by key rather than repeating a class string.

Verified by computed style: text-transform, letter-spacing, size, weight,
colour and dot colour are now identical to the homepage's taglines.
Fills the reserved hero slots with the render the homepage already pairs
with each product: cards-3d on /orm, cpu-3d on /compute, database-3d on
/postgres, matching orm/compute/postgres-illustration.tsx. ThreeDSlot now
draws with object-contain so a render keeps its aspect inside whatever
footprint the placeholder held, and the slots grew slightly now that real
art sits in them.

Also fixes the /postgres headline, which ran into the illustration. Two
separate causes:

- The headline box could exceed its own grid column, because 16ch at the
  top of the clamp is wider than the column. The column is the hard limit
  now.
- The real overflow was the emphasis. GlassGlide is whitespace-nowrap from
  md up, deliberately, so the light travels an unbroken phrase — and the
  emphasis here was seven words, one unbreakable ~790px token in a 544px
  column, which pushed "stack" out of sight. Shortened to one word.

All three headlines now set in three lines and clear the illustration by
65px or more. "Production-ready Postgres," cannot share a line at any
sensible size (790px at 56px, still 649px at 46px), so "already" leads the
second line instead. headlineEmphasis now documents the length constraint.
…ng room

Client feedback 2026-07-30, in two parts.

Fold: Shane asked to land on the plans rather than read introductory copy first,
citing Vercel's pricing page. The hero is now a title band — testimonial, subhead,
checks and CTAs all removed (each is represented elsewhere; only the per-plan
blurbs have nowhere else to live, so they stay in the data unrendered). Headline
and cards then moved into one wrapper, and the wrapper came off entirely when the
page still read tighter than the reference.

Width turned out to matter more than spacing: four cards of dense feature text at
max-w-6xl were 270px wide and wrapped an overage line onto three lines. At 84rem
they are 318px and 482px tall instead of 528px — wider AND shorter, which is the
only reason the added padding still leaves every CTA above the fold at 1440x800.

Unwrapping needed the wash and grain to dissolve themselves: anchored to the
section edge they cut off and drew a visible seam across the page.

Supabase: figures supplied by the client ("Recommended website comparison", fair
50K MAU model) and used verbatim, including the "database compute excluded" caveat
on their spend cap. Their doc also puts Prisma Pro at $72-90 where V2 said $70-90;
taking theirs, since the old number was never verified.

The savings marker now names its basis. Unqualified "Up to 5x less" sat directly
beside a Supabase column only ~1.5x more expensive, so it read as a claim about
Supabase and was wrong by 3x. NOTE: the 5x still derives from the unverified
$385-450 Neon + Vercel figure, which now looks like an outlier next to the
client's own numbers — flagged, needs their answer.

Co-Authored-By: Claude <noreply@anthropic.com>
The band existed to have light pass through the 3D element beside it, so
with the render gone it had no subject and read as decoration. The card is
just the migration history now, on its ray photo frame like the feature
cards.

Also removes what only existed to support the band: the `relative` on the
row list and the command strip, and on CardChrome, which no illustration
needs any longer.

The hero abstractions keep their renders, and the ray crossing behind them
is a separate treatment from the template and is untouched.
The site had no container width defined anywhere — no token in globals.css, no
Tailwind config, and /brand documents prisms and rays but nothing about layout.
Every section picked its own, so four values had drifted in:

  1152px  max-w-6xl              the brand-redesign sections
  1280px  max-w-7xl              the older/generic sections
  1280px  Tailwind's `container`  the secondary pages (blog, solutions, versus…)
  1536px  max-w-[96rem]           the wrapped-panel shells

The panels made it read worse rather than better: the shell was 1536px but its
contents were 1152px, so the widest thing on a page was decorative while the
content sat in the middle third. That is the "not using the horizontal space"
against Vercel.

Adds --container-site (87.5rem / 1400px) and --container-panel to @theme,
generating a `max-w-site` utility, and applies it to every live layout
container: 25 section/product components, 12 page files, and the two auth
wrappers. 1400px matches Vercel's pricing page, measured in headless Chromium as
a hard cap at both 1440 and 1920. Tuned for the 1440 viewport this project
designs against: with the usual px-4 sm:px-8 gutter the content renders 1376px
there, reaching the full 1400 past 1464.

Prose containers are deliberately untouched — max-w-2xl/3xl/[62ch] are text
measure and matter more at this width, not less. Unused scaffolding
(relume-library, the six root *-section components, gallery and demo routes) is
left alone.

Two things the audit turned up that a grep for `mx-auto max-w-*` missed: six
pages write the classes in reverse order (`max-w-6xl mx-auto`), and ten more use
Tailwind's built-in `container`, which silently caps at 1280px at this viewport.

Evidence that width beats padding here: the pricing cards went 270px -> 326px
wide and 528px -> 482px TALL, because two feature lines stopped wrapping. Wider
and shorter at once, and every plan CTA is still above the fold at 1440x800.

Verified 24 routes x {1440, 390}: all 200, zero horizontal overflow, no page
errors, no 1152/1280 container left on any live page. Formatting deliberately
excluded — running oxfmt over src/ rewrites ~485 untouched files to add
semicolons, which belongs in its own commit.

Co-Authored-By: Claude <noreply@anthropic.com>
…rand fixes

Brings in the max-w-site token (1400px), brand/marker.tsx, and the pricing
work landed alongside them, so the product pages build on the same widths
and shared primitives as the rest of the site.
…t reach

The site-wide width commit landed on the pricing branch and converted the
four product components that existed there. The two this branch added
afterwards — the migrations narrative and the feedback blocks, both on
/orm — were invisible to it and stayed at max-w-6xl, so those sections
would have rendered 1152px inside an otherwise 1400px page.

A token cannot retroactively rewrite hardcoded classes in files that did
not exist when the sweep ran, and the merge was clean, so nothing flagged
it. Measured after: every page now shows exactly two container widths,
1400 for content and 1536 for the wrapped-panel shells, matching the
homepage and pricing.
URL rename: the /next version segment (a working-name artifact) becomes
/v8 across all four trees: /orm/next -> /orm/v8, /cli/next -> /cli/v8,
/guides/next -> /guides/v8, and the getting-started tree /next -> /v8.
Content directories moved with git mv; every internal link, url:
frontmatter field, meta.json entry, llms.txt prefix and section slug
(/docs/llms/v8.txt), sidebar matcher, badge-visibility path, and the
version key ("next" -> "v8" in version.ts, the switcher, and the
sidebar tree) updated to match. Permanent redirects cover the old URLs,
including /llms/next.txt; the commented GA cutover map now speaks v8.

Package rename (ADR 242, prisma/prisma#29864): app-facing installs and
imports move from the @prisma-next scope to the consolidated @prisma
facades. Mappings verified against the merged monorepo's converted
example apps and facade export maps, e.g.:
- @prisma-next/postgres -> @prisma/orm-postgres (one dependency)
- @prisma-next/sql-runtime -> @prisma/orm-postgres/family-runtime
- @prisma-next/sql-orm-client -> @prisma/orm-postgres/orm-client
- @prisma-next/mongo-query-builder -> @prisma/orm-mongo/query-builder
- @prisma-next/target-postgres/migration -> @prisma/orm-postgres/target/migration
- @prisma-next/middleware-cache -> @prisma/orm-extension-middleware-cache
- extensions -> @prisma/orm-extension-{pgvector,postgis,paradedb,supabase,arktype-json}
Extension source links now point at prisma/prisma's
packages/3-extensions (verified to exist there).

Unchanged on purpose: the prisma-next bin and prisma-next.config.ts
(the Slack announcement defers that rename to a pre-RC roadmap task),
npm create prisma@next, blog slugs, pris.ly short links, and
prisma/prisma-next repo links whose targets have no equivalent in the
monorepo (retail-store example, planning docs).

Verified: docs types:check, lint:links (0 errors across the moved
trees), lint:agent-ready, test:llm-markdown, lint:spellcheck, pnpm
check; rendered /orm/v8 page with v8 (RC) dropdown and collapsed
sidebar; 308 redirects confirmed for all old-URL forms. Pre-commit hook
skipped; its check command was run manually and passed.
Main's #8125 added the generated error reference under the old
/orm/next path with working-name branding. Resolution:

- Accepted git's relocation of error-reference.mdx into orm/v8/reference
  (the meta.json entry merged into the renamed path automatically).
- Taught generate-error-reference.mjs the naming standard so every
  future sync stays compliant: v8 output path and frontmatter
  (Prisma 8, release-candidate badge, /orm/v8 url), "Prisma Next" ->
  "Prisma 8" in canonical body text, and published facade names for
  app-facing imports (@internal/utils/structured-error -> the facade
  utils/structured-error subpath; @internal/{postgres,sqlite,mongo} ->
  @prisma/orm-*). Internal-only testkit names are deliberately kept.
- Regenerated the page from the live canonical source (256 codes) and
  added its new vocabulary to cspell.json.
- Updated both error-reference workflows and the anchors spec to the
  /orm/v8 path, and the sync workflow's commit message.
- Reframed the 2026-08-02 changelog note from Early Access to Release
  Candidate.

Old /orm/next docsUrls emitted by existing builds still land correctly:
the 308 redirects preserve URL fragments.

Verified: docs types:check, lint:links, lint:agent-ready,
test:llm-markdown, lint:spellcheck (783 files, 0 issues), pnpm check.
Pre-commit hook skipped; its check command was run manually and passed.
Client review of /postgres, /orm and /compute: the pages explain the
product where the live site demonstrates it, the primary CTA gets lost,
and the platform diagram reads as "you must adopt all of Prisma".

Hero CTA. It sat under the subheadline AND three benefit lines, landing
at 675-757px — below the fold on /orm at 1440x800 — as the same black
pill as the navbar's, so it read as a repeat rather than the page's
action. It now follows a one-sentence subheadline directly, at a new lg
size, with the benefits demoted underneath and a reassurance microline.
Measured: 507-568px, 193x58 against the navbar's 109x36.

Hero visual. Each hero now runs a product tour (product-tour.tsx): a tab
strip over one panel, auto-advancing until a visitor drives it, stopping
for good when they do. Stops share a single grid cell so the frame takes
its tallest stop and nothing reflows or clips. /postgres tours the three
things a bare managed Postgres doesn't give you (branching, Studio,
Query Insights); /orm walks schema -> typed client -> a destructive
migration being refused -> the same client over any database; /compute
walks Connect -> Deploy -> Live -> Templates.

Nine new hero-scale abstractions back those stops. No screenshots — the
existing stylised idiom, carrying far more real detail.

Platform section. Four layers instead of three, each showing what it
swaps out for, always legible rather than hidden behind the interaction,
under a line that states the point in words. The node canvas generalised
from three hardcoded positions to N.

Copy. /orm's hero led with the agent; it now leads with the schema and
the typed client, and Features moves ahead of the migrations argument so
the page says what the ORM is before it argues agent safety. Feature and
problem prose trimmed where a panel now carries the explaining.

Co-Authored-By: Claude <noreply@anthropic.com>
Clicking a node already drove the section, but the card's response was a
border going from 6% to 14% black — indistinguishable in practice, so
the interaction read as nothing happening. The active card now lifts on
a shadow, its "Swaps for" label goes to ink, and its alternatives get
borders and a white fill while every other card's sit flat and grey.

Co-Authored-By: Claude <noreply@anthropic.com>
The card grid said the right thing and nobody felt it — feedback was that
it read as a table and nothing looked clickable. The information design
was the problem: every alternative sat at the same weight as everything
else, so there was no "current" to change and no reason to touch it.

Rebuilt around one mechanic. Each layer has a single slot, and you swap
what's in it: click an alternative and it flies up into the slot on a
shared-layout tween while the current occupant drops into its place. The
motion is the affordance — things move where you clicked, so the control
looks like a control. Hierarchy does the rest: one big lit slot per
layer, alternatives small beneath it.

The argument rides on the mechanic rather than sitting beside it. A slot
holding its Prisma option glows in that product's hue and the pipe out of
it flows; swap it and that stretch goes grey and still. The path dims, it
never breaks. A "Golden path" badge is the scoreboard, so a swap costs
something, and the footer says what each one actually costs — what still
works, and what you now own yourself.

The agent row sits outside the pipeline deliberately: no Prisma option to
pick, every agent equal, highlight cycling on its own.

platform.integrations is gone from the content contract — the layers and
their trade-offs are page-independent, so they live in the component and
only the section's body copy stays per page.

Co-Authored-By: Claude <noreply@anthropic.com>
Clicking an alternative appeared to freeze the control. Measured: no
main-thread block at all (11-18ms per click, zero long tasks) — the
element was going to opacity 0, parking at the OLD bench position for
~1s, then snapping into the slot at ~1500ms.

Cause was the shared `layoutId` between the bench chip and the slot chip.
The two nodes sit in very different parents, and framer treats that
pairing as a crossfade rather than a flight: it drove the incoming
element toward the position it came from and held it invisible until the
tween finished.

Replaced with directional slides, which read the same and are
deterministic — the bench is below the slot, so an incoming pick rises
from below while the outgoing one drops toward the bench it is joining.
The displaced item now animates into the bench from above, and the rest
of the bench reflows with a position-only layout animation.

Measured after: settled at ~200ms, no dead zone, still no long tasks.

The agent row keeps its layoutId — that one is siblings in a single row,
the case shared-layout handles correctly.

Co-Authored-By: Claude <noreply@anthropic.com>
A stack of Supabase + Drizzle + Vercel is an advert for other people, so
the builder now has a floor. Swapping out the last Prisma layer pulls one
back instead — specifically the longest-ago swap, never the layer just
clicked, since overriding the input someone just gave reads as the
control refusing them.

The restored slot pops so the change never happens where the eye isn't
looking, and the footer owns it in plain words rather than dressing it up
as a technical constraint: "<X> slid back in — we'll swap out any layer,
just not all of them at once."

Verified with a 25-click fuzz over the bench: minimum Prisma layers 1,
zero breaches, and the restored layer was the oldest swap every time.

Co-Authored-By: Claude <noreply@anthropic.com>
Drag was the first reflex reached for, so it should work. Bench items are
now draggable onto their layer's slot; the slot advertises itself with a
dashed outline the moment a drag starts, and anything dropped elsewhere
snaps back. Click stays the primary path — it is the keyboard-reachable
one, and the only one on touch.

Three things this needed, each found by driving it rather than reading it:

- Drag is enabled only for a fine pointer. On touch, framer captures the
  gesture and the page stops scrolling wherever the bench sits under your
  thumb. Subscribed via useSyncExternalStore rather than set from an
  effect, so the server snapshot is a plain false and hydration matches.

- Framer does not swallow the click a drag release fires, and the element
  has travelled under the cursor, so releasing anywhere lands a click on
  it: dropping on empty space swapped the layer anyway. Guarded — but the
  flag has to go up on drag START, because onDragEnd runs after the click.

- That guard is cleared on the next pointerdown, not on a timer. A first
  attempt cleared it inside onClick, which never ran after a successful
  drop (the button unmounts), so the flag survived and swallowed the next
  click on a different option.

Verified: drag swaps, cross-layer drops do nothing, drops on empty space
do nothing, click still works after a drag, the no-zero-Prisma floor
holds through drags as well as clicks, and touch renders no drag handles.

Co-Authored-By: Claude <noreply@anthropic.com>
coderabbitai[bot]
coderabbitai Bot previously approved these changes Aug 12, 2026
@nurul3101

Copy link
Copy Markdown
Member Author

Merge conflicts resolved (merged origin/main; the only overlap was the Prisma 8 error-reference sync, auto-merged cleanly). PR now reports MERGEABLE.

Bot findings triaged, 17 CodeQL alerts:

Implemented (1) — alert 39, js/incomplete-url-substring-sanitization in PrismButton. Valid, and it was my code. href.includes("console.prisma.io") also matches https://evil.com/?next=console.prisma.io and https://console.prisma.io.evil.com, so the cta_click conversion event could fire on a non-console link and pollute the GA4/Ads series that tracking exists to preserve. Now parses the href and compares the hostname exactly. This also fixes a latent throw: the old label-fallback path called new URL(href) unguarded, which raised on a relative href containing the substring. Verified against 13 cases including all the bypass forms.

Dismissed as false positive (2) — alerts 37 and 38, js/stored-xss in apps/site/src/app/changelog/page.tsx. The flagged value is a .mdx filename read from this repo's own content directory via getContentSlugs, not user input, and it is interpolated after a literal /changelog/ prefix. The resulting href is therefore always a same-origin relative path, so a javascript: or data: scheme cannot be formed. No dangerouslySetInnerHTML is involved anywhere in those pages. Dismissal reasons recorded on the alerts.

Left to auto-close (14) — alerts 23 to 36, all under apps/site-redesign/. That app is deleted in this PR (merged into apps/site), so every flagged file is gone and the alerts resolve on merge. Deliberately not dismissed: auto-close is the correct lifecycle here, whereas a manual dismissal would suppress the rule if similar code ever reappeared.

The Prisma 8 rebrand moved the generated error reference from
orm/next/reference/ to orm/v8/reference/, but cspell's ignorePaths still
named the old location. The file was silently pulled into the spellcheck
set for the first time and failed on four technical identifiers it has
always contained: the CONTRACT.CHECK_OPTOUT_INVALID error code, the SQL
keyword in WITH ORDINALITY, and the bigintnumber / unboundedint codec ids.

Repointing the ignore is the right fix rather than adding those words to
the dictionary: the file is generated and synced from the engine repo, so
every future sync would otherwise introduce new codec ids and error codes
that fail the same way. Spellcheck is green locally, 783 files checked.
prisma/prisma main gained CONTRACT.CHECK_NAME_RESERVED and
CONTRACT.CHECK_ON_STI_VARIANT with the @@check feature commit, one minute
after this branch's last green run of the completeness check. That check
re-clones prisma/prisma on every run, so the page drifted out of date
without anything in this PR changing.

Regenerated with the same generator the sync bot runs
(apps/docs/scripts/generate-error-reference.mjs), which also picks up the
two upstream description edits that now mention CHECK constraints. 279
codes, matching the verifier's count.
Ports the template directory from codex/dr-8815-template-directory,
keeping its data layer (prisma-examples manifest fetch, zod validation,
5-min revalidate, graceful empty state) and rebuilding the UI in the
2026 brand: framed Texture hero with a compute-red wash, RoleKicker,
PrismButtonOutline card CTAs with console cta_click tracking, and a
Templates link in the footer Resources column.
… the unified CLI

Adds a top-level Composer docs section (15 pages, Early Access): quickstart,
concepts (apps/modules, contracts, service input, databases, object storage,
building blocks), workflows (local dev, testing, deploying, porting), and
reference. Registered in the root meta.json, the navbar, and llmsSections.

Rewrites the cli/v8 tree from the standalone prisma-next binary to the
unified Prisma CLI (npx @prisma/cli@next until the prisma@next tag lands),
with command surfaces verified against 8.0.0-rc.2: init becomes orm init,
migration apply becomes migrate, migration ref becomes ref.

Composer commands were tested end to end locally (dev, log, watch-restart,
service-key 401s); deploy wording follows the composer repo guides.
…ied CLI

Replaces prisma-next invocations with npx @prisma/cli@next across the
Prisma 8 getting-started funnel, add-to-existing-project and import
guides, the ORM v8 concept/migrations/contract-authoring trees, the
Studio Prisma 8 page, the Deno guide, and the agent prompt blocks,
applying the verified command renames (init -> orm init).

Left untouched on purpose: quoted CLI output (the bundled toolchain
still prints prisma-next in hints), skill names, repo and blog URLs,
prisma-next.config.ts / prisma-next.md file names, and listings of
scaffold-generated files, which orm init still emits in that form. The
generated error reference is owned by the upstream sync.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants