diff --git a/apps/blocks/README.md b/apps/blocks/README.md index 72dfd69..06a1a35 100644 --- a/apps/blocks/README.md +++ b/apps/blocks/README.md @@ -35,7 +35,7 @@ Run `pnpm gen` after changing any authored input. Never edit the generated files | `check:selections` | Reject empty mutation selections in `src/blocks` | | `lint:types` | `tsc --noEmit` | | `test` | `vitest run` | -| `test:visual` | Compare the static Pages site with the Playwright screenshot baselines | +| `test:visual` | Compare the static Pages site with platform-specific Playwright screenshot baselines | | `build:pages` | `BLOCKS_PAGES=1 next build` — static export for GitHub Pages | ## Layout diff --git a/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/auth-sign-in-dark.png b/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/auth-sign-in-dark.png deleted file mode 100644 index 3cb879b..0000000 Binary files a/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/auth-sign-in-dark.png and /dev/null differ diff --git a/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/auth-sign-in-light.png b/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/auth-sign-in-light.png deleted file mode 100644 index 8a66129..0000000 Binary files a/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/auth-sign-in-light.png and /dev/null differ diff --git a/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/catalog-dark.png b/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/catalog-dark.png deleted file mode 100644 index 44f1286..0000000 Binary files a/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/catalog-dark.png and /dev/null differ diff --git a/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/catalog-light.png b/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/catalog-light.png deleted file mode 100644 index 85b5fa5..0000000 Binary files a/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/catalog-light.png and /dev/null differ diff --git a/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/chat-dark.png b/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/chat-dark.png deleted file mode 100644 index 80b761c..0000000 Binary files a/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/chat-dark.png and /dev/null differ diff --git a/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/chat-light.png b/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/chat-light.png deleted file mode 100644 index 4e8f1b0..0000000 Binary files a/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/chat-light.png and /dev/null differ diff --git a/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/darwin/auth-sign-in-dark.png b/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/darwin/auth-sign-in-dark.png new file mode 100644 index 0000000..6fc9dd8 Binary files /dev/null and b/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/darwin/auth-sign-in-dark.png differ diff --git a/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/darwin/auth-sign-in-light.png b/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/darwin/auth-sign-in-light.png new file mode 100644 index 0000000..96e9f67 Binary files /dev/null and b/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/darwin/auth-sign-in-light.png differ diff --git a/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/darwin/catalog-dark.png b/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/darwin/catalog-dark.png new file mode 100644 index 0000000..fcb593d Binary files /dev/null and b/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/darwin/catalog-dark.png differ diff --git a/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/darwin/catalog-light.png b/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/darwin/catalog-light.png new file mode 100644 index 0000000..bc6b112 Binary files /dev/null and b/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/darwin/catalog-light.png differ diff --git a/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/darwin/chat-dark.png b/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/darwin/chat-dark.png new file mode 100644 index 0000000..ae67b8e Binary files /dev/null and b/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/darwin/chat-dark.png differ diff --git a/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/darwin/chat-light.png b/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/darwin/chat-light.png new file mode 100644 index 0000000..2dbb05d Binary files /dev/null and b/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/darwin/chat-light.png differ diff --git a/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/darwin/home-dark.png b/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/darwin/home-dark.png new file mode 100644 index 0000000..a8bdf92 Binary files /dev/null and b/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/darwin/home-dark.png differ diff --git a/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/darwin/home-light.png b/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/darwin/home-light.png new file mode 100644 index 0000000..c099ead Binary files /dev/null and b/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/darwin/home-light.png differ diff --git a/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/darwin/schema-builder-dark.png b/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/darwin/schema-builder-dark.png new file mode 100644 index 0000000..3b678e2 Binary files /dev/null and b/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/darwin/schema-builder-dark.png differ diff --git a/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/darwin/schema-builder-light.png b/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/darwin/schema-builder-light.png new file mode 100644 index 0000000..d441160 Binary files /dev/null and b/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/darwin/schema-builder-light.png differ diff --git a/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/darwin/ui-button-dark.png b/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/darwin/ui-button-dark.png new file mode 100644 index 0000000..945a8c3 Binary files /dev/null and b/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/darwin/ui-button-dark.png differ diff --git a/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/darwin/ui-button-light.png b/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/darwin/ui-button-light.png new file mode 100644 index 0000000..a83d0b6 Binary files /dev/null and b/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/darwin/ui-button-light.png differ diff --git a/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/home-dark.png b/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/home-dark.png deleted file mode 100644 index 341340d..0000000 Binary files a/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/home-dark.png and /dev/null differ diff --git a/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/home-light.png b/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/home-light.png deleted file mode 100644 index abec510..0000000 Binary files a/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/home-light.png and /dev/null differ diff --git a/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/linux/auth-sign-in-dark.png b/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/linux/auth-sign-in-dark.png new file mode 100644 index 0000000..6fc9dd8 Binary files /dev/null and b/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/linux/auth-sign-in-dark.png differ diff --git a/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/linux/auth-sign-in-light.png b/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/linux/auth-sign-in-light.png new file mode 100644 index 0000000..96e9f67 Binary files /dev/null and b/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/linux/auth-sign-in-light.png differ diff --git a/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/linux/catalog-dark.png b/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/linux/catalog-dark.png new file mode 100644 index 0000000..d5814e1 Binary files /dev/null and b/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/linux/catalog-dark.png differ diff --git a/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/linux/catalog-light.png b/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/linux/catalog-light.png new file mode 100644 index 0000000..0cacabc Binary files /dev/null and b/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/linux/catalog-light.png differ diff --git a/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/linux/chat-dark.png b/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/linux/chat-dark.png new file mode 100644 index 0000000..bacc86e Binary files /dev/null and b/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/linux/chat-dark.png differ diff --git a/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/linux/chat-light.png b/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/linux/chat-light.png new file mode 100644 index 0000000..c9e344f Binary files /dev/null and b/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/linux/chat-light.png differ diff --git a/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/linux/home-dark.png b/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/linux/home-dark.png new file mode 100644 index 0000000..61a9cb2 Binary files /dev/null and b/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/linux/home-dark.png differ diff --git a/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/linux/home-light.png b/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/linux/home-light.png new file mode 100644 index 0000000..ce816b0 Binary files /dev/null and b/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/linux/home-light.png differ diff --git a/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/linux/schema-builder-dark.png b/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/linux/schema-builder-dark.png new file mode 100644 index 0000000..3b678e2 Binary files /dev/null and b/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/linux/schema-builder-dark.png differ diff --git a/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/linux/schema-builder-light.png b/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/linux/schema-builder-light.png new file mode 100644 index 0000000..909bf71 Binary files /dev/null and b/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/linux/schema-builder-light.png differ diff --git a/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/linux/ui-button-dark.png b/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/linux/ui-button-dark.png new file mode 100644 index 0000000..b4de617 Binary files /dev/null and b/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/linux/ui-button-dark.png differ diff --git a/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/linux/ui-button-light.png b/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/linux/ui-button-light.png new file mode 100644 index 0000000..5326f01 Binary files /dev/null and b/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/linux/ui-button-light.png differ diff --git a/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/schema-builder-dark.png b/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/schema-builder-dark.png deleted file mode 100644 index b8bae81..0000000 Binary files a/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/schema-builder-dark.png and /dev/null differ diff --git a/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/schema-builder-light.png b/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/schema-builder-light.png deleted file mode 100644 index c73e827..0000000 Binary files a/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/schema-builder-light.png and /dev/null differ diff --git a/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/ui-button-dark.png b/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/ui-button-dark.png deleted file mode 100644 index 3a03d12..0000000 Binary files a/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/ui-button-dark.png and /dev/null differ diff --git a/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/ui-button-light.png b/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/ui-button-light.png deleted file mode 100644 index cba4a9e..0000000 Binary files a/apps/blocks/e2e/__screenshots__/desktop.visual.spec.ts/ui-button-light.png and /dev/null differ diff --git a/apps/blocks/e2e/__screenshots__/mobile.visual.spec.ts/auth-sign-in-mobile-light.png b/apps/blocks/e2e/__screenshots__/mobile.visual.spec.ts/auth-sign-in-mobile-light.png deleted file mode 100644 index 37baf17..0000000 Binary files a/apps/blocks/e2e/__screenshots__/mobile.visual.spec.ts/auth-sign-in-mobile-light.png and /dev/null differ diff --git a/apps/blocks/e2e/__screenshots__/mobile.visual.spec.ts/darwin/auth-sign-in-mobile-light.png b/apps/blocks/e2e/__screenshots__/mobile.visual.spec.ts/darwin/auth-sign-in-mobile-light.png new file mode 100644 index 0000000..e415e53 Binary files /dev/null and b/apps/blocks/e2e/__screenshots__/mobile.visual.spec.ts/darwin/auth-sign-in-mobile-light.png differ diff --git a/apps/blocks/e2e/__screenshots__/mobile.visual.spec.ts/darwin/home-mobile-light.png b/apps/blocks/e2e/__screenshots__/mobile.visual.spec.ts/darwin/home-mobile-light.png new file mode 100644 index 0000000..7b337b2 Binary files /dev/null and b/apps/blocks/e2e/__screenshots__/mobile.visual.spec.ts/darwin/home-mobile-light.png differ diff --git a/apps/blocks/e2e/__screenshots__/mobile.visual.spec.ts/darwin/schema-builder-mobile-light.png b/apps/blocks/e2e/__screenshots__/mobile.visual.spec.ts/darwin/schema-builder-mobile-light.png new file mode 100644 index 0000000..9eac4cf Binary files /dev/null and b/apps/blocks/e2e/__screenshots__/mobile.visual.spec.ts/darwin/schema-builder-mobile-light.png differ diff --git a/apps/blocks/e2e/__screenshots__/mobile.visual.spec.ts/home-mobile-light.png b/apps/blocks/e2e/__screenshots__/mobile.visual.spec.ts/home-mobile-light.png deleted file mode 100644 index bcee5ea..0000000 Binary files a/apps/blocks/e2e/__screenshots__/mobile.visual.spec.ts/home-mobile-light.png and /dev/null differ diff --git a/apps/blocks/e2e/__screenshots__/mobile.visual.spec.ts/linux/auth-sign-in-mobile-light.png b/apps/blocks/e2e/__screenshots__/mobile.visual.spec.ts/linux/auth-sign-in-mobile-light.png new file mode 100644 index 0000000..9d97bb5 Binary files /dev/null and b/apps/blocks/e2e/__screenshots__/mobile.visual.spec.ts/linux/auth-sign-in-mobile-light.png differ diff --git a/apps/blocks/e2e/__screenshots__/mobile.visual.spec.ts/linux/home-mobile-light.png b/apps/blocks/e2e/__screenshots__/mobile.visual.spec.ts/linux/home-mobile-light.png new file mode 100644 index 0000000..7b2b0f0 Binary files /dev/null and b/apps/blocks/e2e/__screenshots__/mobile.visual.spec.ts/linux/home-mobile-light.png differ diff --git a/apps/blocks/e2e/__screenshots__/mobile.visual.spec.ts/linux/schema-builder-mobile-light.png b/apps/blocks/e2e/__screenshots__/mobile.visual.spec.ts/linux/schema-builder-mobile-light.png new file mode 100644 index 0000000..e82f601 Binary files /dev/null and b/apps/blocks/e2e/__screenshots__/mobile.visual.spec.ts/linux/schema-builder-mobile-light.png differ diff --git a/apps/blocks/e2e/__screenshots__/mobile.visual.spec.ts/schema-builder-mobile-light.png b/apps/blocks/e2e/__screenshots__/mobile.visual.spec.ts/schema-builder-mobile-light.png deleted file mode 100644 index 25637ab..0000000 Binary files a/apps/blocks/e2e/__screenshots__/mobile.visual.spec.ts/schema-builder-mobile-light.png and /dev/null differ diff --git a/apps/blocks/playwright.config.ts b/apps/blocks/playwright.config.ts index fd7d68f..d70e8a4 100644 --- a/apps/blocks/playwright.config.ts +++ b/apps/blocks/playwright.config.ts @@ -2,7 +2,7 @@ import { defineConfig, devices } from '@playwright/test'; export default defineConfig({ testDir: './e2e', - snapshotPathTemplate: '{testDir}/__screenshots__/{testFilePath}/{arg}{ext}', + snapshotPathTemplate: '{testDir}/__screenshots__/{testFilePath}/{platform}/{arg}{ext}', fullyParallel: true, forbidOnly: Boolean(process.env.CI), retries: process.env.CI ? 2 : 0, diff --git a/apps/blocks/src/app/blocks/(guides)/concepts/design-and-motion/page.tsx b/apps/blocks/src/app/blocks/(guides)/concepts/design-and-motion/page.tsx index bbfedab..570df62 100644 --- a/apps/blocks/src/app/blocks/(guides)/concepts/design-and-motion/page.tsx +++ b/apps/blocks/src/app/blocks/(guides)/concepts/design-and-motion/page.tsx @@ -120,11 +120,11 @@ export default function DesignAndMotionPage() { /* "Bigger thing moves, slower spring" — three tiers, nothing in between. */ --dur-fast: 120ms; /* hover, focus, taps */ --dur: 160ms; /* dropdowns, tabs, accordion */ ---dur-slow: 240ms; /* dialogs, drawers, stepped flows */`} +--dur-slow: 200ms; /* dialogs, drawers, stepped flows */`} /> -

+

Calm isn’t the absence of design — it’s the discipline of it. The same restraint shapes the blocks you install: they inherit these tokens, so a surface dropped into your app reads the way the rest of it does. Retune those tokens for your brand and every block follows — that recipe is{' '} diff --git a/apps/blocks/src/app/blocks/(guides)/concepts/runtime-contract/page.tsx b/apps/blocks/src/app/blocks/(guides)/concepts/runtime-contract/page.tsx index 842bc87..50b04bb 100644 --- a/apps/blocks/src/app/blocks/(guides)/concepts/runtime-contract/page.tsx +++ b/apps/blocks/src/app/blocks/(guides)/concepts/runtime-contract/page.tsx @@ -76,7 +76,7 @@ export default function RuntimeContractPage() { /> -

+

This page is about why the contract is shaped this way, not how to install it — the{' '} getting-started tutorial covers the actual setup, including the environment variables and the auth pieces a block can’t ship for you. diff --git a/apps/blocks/src/app/blocks/(guides)/concepts/why-blocks/page.tsx b/apps/blocks/src/app/blocks/(guides)/concepts/why-blocks/page.tsx index 9b31b2e..e6bb6a9 100644 --- a/apps/blocks/src/app/blocks/(guides)/concepts/why-blocks/page.tsx +++ b/apps/blocks/src/app/blocks/(guides)/concepts/why-blocks/page.tsx @@ -69,7 +69,7 @@ const data = await signIn.mutateAsync({ input: { email, password } }); /> -

+

The result is a leaf that already does the full job. The{' '} sign-in card validates input, maps the server’s error codes to copy you can override, branches on unverified and MFA-required states, and renders the loading and diff --git a/apps/blocks/src/app/blocks/(guides)/getting-started/page.tsx b/apps/blocks/src/app/blocks/(guides)/getting-started/page.tsx index e5fcf5c..80c50c5 100644 --- a/apps/blocks/src/app/blocks/(guides)/getting-started/page.tsx +++ b/apps/blocks/src/app/blocks/(guides)/getting-started/page.tsx @@ -179,7 +179,7 @@ export default function GettingStartedPage() { namespaces, step-up, passkeys — see{' '} the runtime contract.

-

+

You can skip this explicit install — the runtime ships automatically with your first block in the next step.

diff --git a/apps/blocks/src/app/blocks/(guides)/guides/adapter/page.tsx b/apps/blocks/src/app/blocks/(guides)/guides/adapter/page.tsx index e5b6bf6..b9870d0 100644 --- a/apps/blocks/src/app/blocks/(guides)/guides/adapter/page.tsx +++ b/apps/blocks/src/app/blocks/(guides)/guides/adapter/page.tsx @@ -54,7 +54,7 @@ export default function AdapterGuidePage() { } }`} /> -

+

Full host checklist: Getting started.

diff --git a/apps/blocks/src/app/blocks/(guides)/guides/auth/page.tsx b/apps/blocks/src/app/blocks/(guides)/guides/auth/page.tsx index 22f64c3..34d58bb 100644 --- a/apps/blocks/src/app/blocks/(guides)/guides/auth/page.tsx +++ b/apps/blocks/src/app/blocks/(guides)/guides/auth/page.tsx @@ -45,7 +45,7 @@ export default function AuthGuidePage() { intro="Add the sign-in card, and make sure BlocksRuntime is mounted so the block can reach your endpoint. Here we only wire the host seams on top of it." > -

+

Runtime not mounted yet? See Wire a GraphQL adapter. Full prop reference: sign-in-card.

@@ -77,7 +77,7 @@ export default function SignInPage() { ); }`} /> -

+

saveSession is your own token store — the same one{' '} BlocksRuntime’s getToken reads, so every later block request is authenticated. diff --git a/apps/blocks/src/app/blocks/(guides)/guides/customize-a-flow/page.tsx b/apps/blocks/src/app/blocks/(guides)/guides/customize-a-flow/page.tsx index 8417b7f..3cf1e8f 100644 --- a/apps/blocks/src/app/blocks/(guides)/guides/customize-a-flow/page.tsx +++ b/apps/blocks/src/app/blocks/(guides)/guides/customize-a-flow/page.tsx @@ -101,7 +101,7 @@ export default function SignInPage() { ); }`} /> -

+

Need a related capability — social sign-in, password reset? Each is its own flow with its own backend; browse the others in the sidebar.

diff --git a/apps/blocks/src/app/blocks/(guides)/guides/single-component/page.tsx b/apps/blocks/src/app/blocks/(guides)/guides/single-component/page.tsx index 92a24c6..09f2915 100644 --- a/apps/blocks/src/app/blocks/(guides)/guides/single-component/page.tsx +++ b/apps/blocks/src/app/blocks/(guides)/guides/single-component/page.tsx @@ -50,7 +50,7 @@ export default function SingleComponentGuidePage() { } }`} /> -

+

Already done the host setup? Then this is already in place — see{' '} Getting started.

@@ -76,7 +76,7 @@ export default function Page() { return ; }`} /> -

+

Blocks keep importing the package form (@constructive-io/ui/button); the two ways to consume coexist.

diff --git a/apps/blocks/src/app/blocks/(guides)/guides/theming/page.tsx b/apps/blocks/src/app/blocks/(guides)/guides/theming/page.tsx index 7dd4d42..d537b18 100644 --- a/apps/blocks/src/app/blocks/(guides)/guides/theming/page.tsx +++ b/apps/blocks/src/app/blocks/(guides)/guides/theming/page.tsx @@ -56,7 +56,7 @@ export default function ThemingGuidePage() { /* dark-mode overrides */ }`} /> -

+

New to the host setup? Start with Getting started.

@@ -79,7 +79,7 @@ export default function ThemingGuidePage() { --ring: oklch(0.70 0.18 17); }`} /> -

+

Constructive’s own accent is oklch(0.688 0.175 245.6) — swap in yours.

@@ -101,7 +101,7 @@ export default function ThemingGuidePage() { --accent: oklch(0.27 0.01 264); }`} /> -

+

These are the standard shadcn token names; the same set exists under :root for light mode.

diff --git a/apps/blocks/src/app/blocks/(guides)/page.tsx b/apps/blocks/src/app/blocks/(guides)/page.tsx index 76ec997..bd5c4ef 100644 --- a/apps/blocks/src/app/blocks/(guides)/page.tsx +++ b/apps/blocks/src/app/blocks/(guides)/page.tsx @@ -33,7 +33,7 @@ export default function IntroductionPage() {
-

Copy-in, data path wired

+

Copy-in, data path wired

Constructive Blocks are copy-in React components with their data path already wired. Every data block calls a generated React-Query hook from your application’s @/generated/<namespace> SDK @@ -43,7 +43,7 @@ export default function IntroductionPage() {

-

One runtime, one wiring point

+

One runtime, one wiring point

One small runtime — BlocksRuntime — is the single wiring point: it configures each namespace’s SDK and shares one QueryClient, so blocks never mount providers or read @@ -52,7 +52,7 @@ export default function IntroductionPage() {

-

Built on the UI foundation

+

Built on the UI foundation

Every block is built from the same UI foundation,{' '} @constructive-io/ui, which ships in this registry too — use it as a package or copy @@ -61,7 +61,7 @@ export default function IntroductionPage() {

-

Honest about what’s live

+

Honest about what’s live

Each block states its backend availability, from Ready to{' '} Planned, so you always know what is live. @@ -87,7 +87,7 @@ export default function IntroductionPage() {

-

+

Its whole graph — the runtime, the UI foundation, shared utilities — resolves automatically. Want the reasoning first? Read Why blocks. Building a whole capability? Start from a flow — the diff --git a/apps/blocks/src/app/blocks/[...slug]/page.tsx b/apps/blocks/src/app/blocks/[...slug]/page.tsx index 40d4038..06795f9 100644 --- a/apps/blocks/src/app/blocks/[...slug]/page.tsx +++ b/apps/blocks/src/app/blocks/[...slug]/page.tsx @@ -87,7 +87,7 @@ export default async function Page({ params }: PageProps) { ))} {page.builtWith?.length ? ( -

+

Built with {page.builtWith.join(', ')}.

) : null} diff --git a/apps/blocks/src/app/blocks/layout.tsx b/apps/blocks/src/app/blocks/layout.tsx index 78518a9..b3eddcf 100644 --- a/apps/blocks/src/app/blocks/layout.tsx +++ b/apps/blocks/src/app/blocks/layout.tsx @@ -8,5 +8,5 @@ import type { ReactNode } from 'react'; * hamburger; the shell owns the skip-link and `#main` target. */ export default function BlocksLayout({ children }: { children: ReactNode }) { - return
{children}
; + return
{children}
; } diff --git a/apps/blocks/src/app/globals.css b/apps/blocks/src/app/globals.css index 0de17cb..e26600c 100644 --- a/apps/blocks/src/app/globals.css +++ b/apps/blocks/src/app/globals.css @@ -171,7 +171,7 @@ --ease-drawer: cubic-bezier(0.32, 0.72, 0, 1); /* drawers / sheets */ --dur-fast: 80ms; /* hover, color, weight, focus */ --dur: 160ms; /* indicators, small travel */ - --dur-slow: 240ms; /* panels, dialogs */ + --dur-slow: 200ms; /* panels, dialogs */ /* ── Surfaces (8-level ladder) — LIGHT (DESIGN.md §1.1) ── Canvas #FAFAFA; the ladder compresses to flat white; shadow does the work. @@ -435,7 +435,7 @@ html { snapping via `display`, these classes fade them: `display` is animated with `allow-discrete` so the element stays visible across the none↔shown flip, while opacity tweens. Durations mirror the `spring.slow` motion token — - appear in 0.24s, disappear in 0.16s. The `@starting-style` gives the appear + appear in 0.2s, disappear in 0.16s. The `@starting-style` gives the appear transition a starting opacity — required for an element to animate out of `display:none`. Because the panel's space is already reserved at that width, the appear is a pure opacity fade with no layout shift. Browsers without @@ -460,8 +460,8 @@ html { .xl-fade-block { opacity: 1; transition: - opacity 0.24s ease-out, - display 0.24s allow-discrete; + opacity 0.2s ease-out, + display 0.2s allow-discrete; } @starting-style { .xl-fade-flex, diff --git a/apps/blocks/src/app/layout.tsx b/apps/blocks/src/app/layout.tsx index e9fe260..ada5bb1 100644 --- a/apps/blocks/src/app/layout.tsx +++ b/apps/blocks/src/app/layout.tsx @@ -56,7 +56,7 @@ export default function RootLayout({ children }: { children: React.ReactNode }) className={`${geistSans.variable} ${geistMono.variable}`} suppressHydrationWarning > - + {/* Theme + package-manager context, then the global 3-column shell that every route (including the landing) renders inside. */} diff --git a/apps/blocks/src/app/not-found.tsx b/apps/blocks/src/app/not-found.tsx index 3cf6351..a7bc205 100644 --- a/apps/blocks/src/app/not-found.tsx +++ b/apps/blocks/src/app/not-found.tsx @@ -31,7 +31,7 @@ export default function NotFound() { -

+

HTTP 404 · Not Found

diff --git a/apps/blocks/src/app/page.tsx b/apps/blocks/src/app/page.tsx index b0a2ccb..7edee8a 100644 --- a/apps/blocks/src/app/page.tsx +++ b/apps/blocks/src/app/page.tsx @@ -20,18 +20,18 @@ import { publishedBlockCount, uiCount } from '@/lib/blocks'; // SSR and hydration passes. The skeleton holds the section's size meanwhile. const GridMotionWall = dynamic(() => import('@/components/landing/grid-motion').then((m) => m.GridMotionWall), { ssr: false, - loading: () =>
, + loading: () =>
, }); export default function HomePage() { return (
- {/* Intro block. `mt-12 xl:mt-0` clears the floating mobile hamburger. */} -
+ {/* Intro block. The shell's mobile header owns its top inset. */} +

Constructive Blocks

-

+

Full-stack auth, org and admin blocks for the Constructive platform — install with shadcn.

@@ -68,7 +68,7 @@ export default function HomePage() { {/* Quiet footer — one line. */}
-

+

v0.1.0 · {publishedBlockCount} blocks · {uiCount} ui components ·{' '}

{isMaxReached && ( -

+

{merged.maxKeysReached}

)} @@ -256,7 +256,7 @@ export function AccountApiKeysList({ {keys.length === 0 ? ( -

{merged.noKeysDescription}

+

{merged.noKeysDescription}

) : (
    {keys.map((key, idx) => { diff --git a/apps/blocks/src/blocks/auth/account-connected-accounts/account-connected-accounts.tsx b/apps/blocks/src/blocks/auth/account-connected-accounts/account-connected-accounts.tsx index ac79109..0bcaf31 100644 --- a/apps/blocks/src/blocks/auth/account-connected-accounts/account-connected-accounts.tsx +++ b/apps/blocks/src/blocks/auth/account-connected-accounts/account-connected-accounts.tsx @@ -305,7 +305,7 @@ export function AccountConnectedAccounts({ )} {isEmpty ? ( -

    +

    {merged.noProvidersMessage}

    ) : ( diff --git a/apps/blocks/src/blocks/auth/account-danger-card/account-danger-card.tsx b/apps/blocks/src/blocks/auth/account-danger-card/account-danger-card.tsx index cca26fa..0cb70f0 100644 --- a/apps/blocks/src/blocks/auth/account-danger-card/account-danger-card.tsx +++ b/apps/blocks/src/blocks/auth/account-danger-card/account-danger-card.tsx @@ -170,8 +170,8 @@ export function AccountDangerCard({ {emailSent ? (
    -

    {merged.emailSentTitle}

    -

    {merged.emailSentDescription}

    +

    {merged.emailSentTitle}

    +

    {merged.emailSentDescription}

    ) : (
-

{merged.profilePictureHint}

+

{merged.profilePictureHint}

)} diff --git a/apps/blocks/src/blocks/auth/api-key-created-modal/api-key-created-modal.tsx b/apps/blocks/src/blocks/auth/api-key-created-modal/api-key-created-modal.tsx index 559f5d9..95bfbb5 100644 --- a/apps/blocks/src/blocks/auth/api-key-created-modal/api-key-created-modal.tsx +++ b/apps/blocks/src/blocks/auth/api-key-created-modal/api-key-created-modal.tsx @@ -203,7 +203,7 @@ export function ApiKeyCreatedModal({ aria-hidden="true" />
-

+

{merged.warningHeading}

@@ -214,7 +214,7 @@ export function ApiKeyCreatedModal({ {/* Key display area */}

-

{merged.keyLabel}

+

{merged.keyLabel}

{copyError && ( -

+

{copyError}

)} diff --git a/apps/blocks/src/blocks/auth/change-password-form/change-password-form.tsx b/apps/blocks/src/blocks/auth/change-password-form/change-password-form.tsx index b36ef6a..358c58a 100644 --- a/apps/blocks/src/blocks/auth/change-password-form/change-password-form.tsx +++ b/apps/blocks/src/blocks/auth/change-password-form/change-password-form.tsx @@ -216,7 +216,7 @@ export function ChangePasswordForm({ data-slot="change-password-form" className={cn('w-full max-w-sm mx-auto', className)} > -

{merged.title}

+

{merged.title}

@@ -279,7 +279,7 @@ export function ChangePasswordForm({ value={strengthPct} className={cn('h-1.5', strengthColorClass(strength.label))} /> -

{strengthLabel(merged, strength.label)}

+

{strengthLabel(merged, strength.label)}

)}
diff --git a/apps/blocks/src/blocks/auth/domain-verification-step/domain-verification-step.tsx b/apps/blocks/src/blocks/auth/domain-verification-step/domain-verification-step.tsx index b9d9dc5..5599ebe 100644 --- a/apps/blocks/src/blocks/auth/domain-verification-step/domain-verification-step.tsx +++ b/apps/blocks/src/blocks/auth/domain-verification-step/domain-verification-step.tsx @@ -147,7 +147,7 @@ export function AuthDomainVerificationStep({ /> {/* Propagation note */} -

{merged.propagationNote}

+

{merged.propagationNote}

{/* Manual check trigger */} @@ -363,7 +363,7 @@ export function EmailOtpRequestCard({ diff --git a/apps/blocks/src/blocks/auth/forgot-password-card/forgot-password-card.tsx b/apps/blocks/src/blocks/auth/forgot-password-card/forgot-password-card.tsx index 8b20382..af705bb 100644 --- a/apps/blocks/src/blocks/auth/forgot-password-card/forgot-password-card.tsx +++ b/apps/blocks/src/blocks/auth/forgot-password-card/forgot-password-card.tsx @@ -202,7 +202,7 @@ export function ForgotPasswordCard({ @@ -271,7 +271,7 @@ export function ForgotPasswordCard({ diff --git a/apps/blocks/src/blocks/auth/forgot-password-page/forgot-password-page.tsx b/apps/blocks/src/blocks/auth/forgot-password-page/forgot-password-page.tsx index d83d798..8e97418 100644 --- a/apps/blocks/src/blocks/auth/forgot-password-page/forgot-password-page.tsx +++ b/apps/blocks/src/blocks/auth/forgot-password-page/forgot-password-page.tsx @@ -35,7 +35,7 @@ export default function ForgotPasswordPage() { const email = searchParams.get('email') ?? undefined; return ( -
+
{kind === 'org' && ( -

{merged.orgSuccessSwitchHint}

+

{merged.orgSuccessSwitchHint}

)} @@ -295,9 +295,9 @@ export function InvitationAcceptanceCard({
-

{org.displayName}

+

{org.displayName}

{org.username && ( -

@{org.username}

+

@{org.username}

)}
@@ -308,7 +308,7 @@ export function InvitationAcceptanceCard({ {inviter && (
-

+

{merged.orgInviteFrom}:{' '} {inviter.displayName}

@@ -317,7 +317,7 @@ export function InvitationAcceptanceCard({ {role && (
-

{merged.orgInviteRole}:

+

{merged.orgInviteRole}:

{role}
)} diff --git a/apps/blocks/src/blocks/auth/invitation-acceptance-page/invitation-acceptance-page.tsx b/apps/blocks/src/blocks/auth/invitation-acceptance-page/invitation-acceptance-page.tsx index 2253f9b..dcd0dee 100644 --- a/apps/blocks/src/blocks/auth/invitation-acceptance-page/invitation-acceptance-page.tsx +++ b/apps/blocks/src/blocks/auth/invitation-acceptance-page/invitation-acceptance-page.tsx @@ -135,7 +135,11 @@ export default function InvitationAcceptancePage({ messages: messageOverrides, c {BRAND_LOGO_SRC && (
{/* eslint-disable-next-line @next/next/no-img-element */} - Brand logo + Brand logo
)} @@ -158,8 +162,8 @@ export default function InvitationAcceptancePage({ messages: messageOverrides, c <> {!token ? (
-

{merged.missingTokenTitle}

-

{merged.missingTokenDescription}

+

{merged.missingTokenTitle}

+

{merged.missingTokenDescription}

Go to sign in diff --git a/apps/blocks/src/blocks/auth/magic-link-callback-page/magic-link-callback-page.tsx b/apps/blocks/src/blocks/auth/magic-link-callback-page/magic-link-callback-page.tsx index 2f4c689..90cee3a 100644 --- a/apps/blocks/src/blocks/auth/magic-link-callback-page/magic-link-callback-page.tsx +++ b/apps/blocks/src/blocks/auth/magic-link-callback-page/magic-link-callback-page.tsx @@ -249,7 +249,7 @@ function MagicLinkCallbackInner({ return (
{pageState === 'loading' && ( @@ -376,7 +376,7 @@ export default function MagicLinkCallbackPage({ fallback={
diff --git a/apps/blocks/src/blocks/auth/magic-link-request-card/magic-link-request-card.tsx b/apps/blocks/src/blocks/auth/magic-link-request-card/magic-link-request-card.tsx index bb6853f..205b76b 100644 --- a/apps/blocks/src/blocks/auth/magic-link-request-card/magic-link-request-card.tsx +++ b/apps/blocks/src/blocks/auth/magic-link-request-card/magic-link-request-card.tsx @@ -251,7 +251,7 @@ export function MagicLinkRequestCard({ @@ -324,7 +324,7 @@ export function MagicLinkRequestCard({ diff --git a/apps/blocks/src/blocks/auth/magic-link-sent-page/magic-link-sent-page.tsx b/apps/blocks/src/blocks/auth/magic-link-sent-page/magic-link-sent-page.tsx index d789a14..df216e9 100644 --- a/apps/blocks/src/blocks/auth/magic-link-sent-page/magic-link-sent-page.tsx +++ b/apps/blocks/src/blocks/auth/magic-link-sent-page/magic-link-sent-page.tsx @@ -241,7 +241,7 @@ export default function MagicLinkSentPage({ {resendSuccess && ( -

+

{merged.resendSuccess}

)} @@ -263,7 +263,7 @@ export default function MagicLinkSentPage({
{/* Code grid — 2 columns, 1 on mobile */} diff --git a/apps/blocks/src/blocks/auth/mfa-backup-codes-regenerate/mfa-backup-codes-regenerate.tsx b/apps/blocks/src/blocks/auth/mfa-backup-codes-regenerate/mfa-backup-codes-regenerate.tsx index 5db033a..8a371b9 100644 --- a/apps/blocks/src/blocks/auth/mfa-backup-codes-regenerate/mfa-backup-codes-regenerate.tsx +++ b/apps/blocks/src/blocks/auth/mfa-backup-codes-regenerate/mfa-backup-codes-regenerate.tsx @@ -213,7 +213,7 @@ export function MfaBackupCodesRegenerate({
{/* Prominent warning — old codes invalidated immediately */}
-

{merged.warningText}

+

{merged.warningText}

{/* Async error alert (aria-live="polite" is inside AuthErrorAlert) */} diff --git a/apps/blocks/src/blocks/auth/mfa-totp-challenge-page/mfa-totp-challenge-page.tsx b/apps/blocks/src/blocks/auth/mfa-totp-challenge-page/mfa-totp-challenge-page.tsx index d3c3866..b993bf4 100644 --- a/apps/blocks/src/blocks/auth/mfa-totp-challenge-page/mfa-totp-challenge-page.tsx +++ b/apps/blocks/src/blocks/auth/mfa-totp-challenge-page/mfa-totp-challenge-page.tsx @@ -133,7 +133,7 @@ export default function MfaTotpChallengePage({ > -

{merged.missingTokenTitle}

+

{merged.missingTokenTitle}

{merged.missingTokenDescription}
@@ -154,7 +154,7 @@ export default function MfaTotpChallengePage({ > -

{merged.expiredTokenTitle}

+

{merged.expiredTokenTitle}

{merged.expiredTokenDescription}
diff --git a/apps/blocks/src/blocks/auth/mfa-totp-challenge/mfa-totp-challenge.tsx b/apps/blocks/src/blocks/auth/mfa-totp-challenge/mfa-totp-challenge.tsx index 19a6cad..3a5bc0d 100644 --- a/apps/blocks/src/blocks/auth/mfa-totp-challenge/mfa-totp-challenge.tsx +++ b/apps/blocks/src/blocks/auth/mfa-totp-challenge/mfa-totp-challenge.tsx @@ -279,7 +279,7 @@ export function MfaTotpChallenge({ {merged.trustDeviceLabel}
-

{merged.trustDeviceHint}

+

{merged.trustDeviceHint}

)} @@ -302,7 +302,10 @@ export function MfaTotpChallenge({ message key is in the catalog now to avoid a breaking change later. */} {false && ( - diff --git a/apps/blocks/src/blocks/auth/mfa-totp-disable-confirm/mfa-totp-disable-confirm.tsx b/apps/blocks/src/blocks/auth/mfa-totp-disable-confirm/mfa-totp-disable-confirm.tsx index 5cd4c3f..62771fa 100644 --- a/apps/blocks/src/blocks/auth/mfa-totp-disable-confirm/mfa-totp-disable-confirm.tsx +++ b/apps/blocks/src/blocks/auth/mfa-totp-disable-confirm/mfa-totp-disable-confirm.tsx @@ -153,8 +153,8 @@ export function MfaTotpDisableConfirm({
{/* Prominent security warning — both texts visible simultaneously per spec */}
-

{merged.warningText}

-

{merged.backupCodesWarning}

+

{merged.warningText}

+

{merged.backupCodesWarning}

{/* Async error alert (aria-live="polite" is inside AuthErrorAlert) */} diff --git a/apps/blocks/src/blocks/auth/mfa-totp-enroll/mfa-totp-enroll.tsx b/apps/blocks/src/blocks/auth/mfa-totp-enroll/mfa-totp-enroll.tsx index 7e8e608..294967b 100644 --- a/apps/blocks/src/blocks/auth/mfa-totp-enroll/mfa-totp-enroll.tsx +++ b/apps/blocks/src/blocks/auth/mfa-totp-enroll/mfa-totp-enroll.tsx @@ -309,15 +309,15 @@ export function MfaTotpEnroll({ QR code for authenticator app setup
{manualKey && (
-

{merged.qrInstructions}

+

{merged.qrInstructions}

-

{merged.manualEntryLabel}

+

{merged.manualEntryLabel}

{formatManualKey(manualKey)} diff --git a/apps/blocks/src/blocks/auth/passkey-enroll/passkey-enroll.tsx b/apps/blocks/src/blocks/auth/passkey-enroll/passkey-enroll.tsx index 7b747ad..129b13a 100644 --- a/apps/blocks/src/blocks/auth/passkey-enroll/passkey-enroll.tsx +++ b/apps/blocks/src/blocks/auth/passkey-enroll/passkey-enroll.tsx @@ -179,7 +179,7 @@ export function PasskeyEnroll({

{merged.unsupportedBrowser}

@@ -229,10 +229,10 @@ export function PasskeyEnroll({ {!isPending && ( -

{merged.credentialNameHint}

+

{merged.credentialNameHint}

)} {isPending && ( -

+

{merged.browserPromptHint}

)} diff --git a/apps/blocks/src/blocks/auth/passkey-management-list/passkey-management-list.tsx b/apps/blocks/src/blocks/auth/passkey-management-list/passkey-management-list.tsx index 9f186bb..7cf6b4d 100644 --- a/apps/blocks/src/blocks/auth/passkey-management-list/passkey-management-list.tsx +++ b/apps/blocks/src/blocks/auth/passkey-management-list/passkey-management-list.tsx @@ -139,15 +139,15 @@ function CredentialRow({ credential, merged, onRenameStart, onDeleteRequest }: C
{credential.transports.length > 0 && ( -

+

{merged.transportsLabel}: {credential.transports.map(transportLabel).join(', ')}

)} -

+

{merged.createdAtLabel}: {created ?? '—'}

-

+

{lastUsed ? `${merged.lastUsedLabel}: ${lastUsed}` : merged.lastUsedNever}

@@ -339,14 +339,14 @@ export function PasskeyManagementList({ {isLoading && ( -

+

Loading…

)} {!isLoading && credentials.length === 0 && (
-

{merged.emptyState}

+

{merged.emptyState}

diff --git a/apps/blocks/src/blocks/auth/passkey-sign-in/passkey-sign-in.tsx b/apps/blocks/src/blocks/auth/passkey-sign-in/passkey-sign-in.tsx index fa5e383..59bf355 100644 --- a/apps/blocks/src/blocks/auth/passkey-sign-in/passkey-sign-in.tsx +++ b/apps/blocks/src/blocks/auth/passkey-sign-in/passkey-sign-in.tsx @@ -231,7 +231,7 @@ export function PasskeySignIn({ @@ -241,7 +241,7 @@ export function ResetPasswordCard({ {merged.expiredTokenDescription} - @@ -259,7 +259,7 @@ export function ResetPasswordCard({ {signInPath && ( - @@ -321,7 +321,7 @@ export function ResetPasswordCard({ className="h-1.5" data-testid="password-strength-bar" /> -

+

{strengthLabelText}

diff --git a/apps/blocks/src/blocks/auth/reset-password-page/reset-password-page.tsx b/apps/blocks/src/blocks/auth/reset-password-page/reset-password-page.tsx index b1ed3bf..c543506 100644 --- a/apps/blocks/src/blocks/auth/reset-password-page/reset-password-page.tsx +++ b/apps/blocks/src/blocks/auth/reset-password-page/reset-password-page.tsx @@ -62,7 +62,7 @@ export default function ResetPasswordPage({ className }: ResetPasswordPageProps) return (
diff --git a/apps/blocks/src/blocks/auth/sign-in-card/sign-in-card.tsx b/apps/blocks/src/blocks/auth/sign-in-card/sign-in-card.tsx index fa44aff..754d1cf 100644 --- a/apps/blocks/src/blocks/auth/sign-in-card/sign-in-card.tsx +++ b/apps/blocks/src/blocks/auth/sign-in-card/sign-in-card.tsx @@ -302,7 +302,7 @@ export function SignInCard({ @@ -314,9 +314,9 @@ export function SignInCard({ {signUpHref && ( -

+

{merged.signUpPrompt}{' '} -

diff --git a/apps/blocks/src/blocks/auth/sign-in-page/sign-in-page.tsx b/apps/blocks/src/blocks/auth/sign-in-page/sign-in-page.tsx index 711857d..4148c78 100644 --- a/apps/blocks/src/blocks/auth/sign-in-page/sign-in-page.tsx +++ b/apps/blocks/src/blocks/auth/sign-in-page/sign-in-page.tsx @@ -94,7 +94,11 @@ export default function SignInPage({ className }: { className?: string }) { {BRAND_LOGO_SRC && (
{/* eslint-disable-next-line @next/next/no-img-element */} - Brand logo + Brand logo
)} diff --git a/apps/blocks/src/blocks/auth/sign-up-card/sign-up-card.tsx b/apps/blocks/src/blocks/auth/sign-up-card/sign-up-card.tsx index 92c49ea..66fbf11 100644 --- a/apps/blocks/src/blocks/auth/sign-up-card/sign-up-card.tsx +++ b/apps/blocks/src/blocks/auth/sign-up-card/sign-up-card.tsx @@ -287,7 +287,7 @@ export function SignUpCard({ aria-label="Password strength" data-testid="password-strength-bar" /> -

+

{strengthLabel}

@@ -353,9 +353,9 @@ export function SignUpCard({ {signInHref && ( -

+

{merged.signInPrompt}{' '} -

diff --git a/apps/blocks/src/blocks/auth/social-buttons/social-buttons.tsx b/apps/blocks/src/blocks/auth/social-buttons/social-buttons.tsx index 5114bb2..99a19cd 100644 --- a/apps/blocks/src/blocks/auth/social-buttons/social-buttons.tsx +++ b/apps/blocks/src/blocks/auth/social-buttons/social-buttons.tsx @@ -350,7 +350,7 @@ export function AuthSocialButtons({ ))}
) : providerList.length === 0 && !isLoading ? ( -

{merged.noProvidersMessage}

+

{merged.noProvidersMessage}

) : (
-

+

{merged.protocolsSectionLabel}

    diff --git a/apps/blocks/src/blocks/auth/sso-sign-in-card/sso-sign-in-card.tsx b/apps/blocks/src/blocks/auth/sso-sign-in-card/sso-sign-in-card.tsx index 7843aad..2e98a7a 100644 --- a/apps/blocks/src/blocks/auth/sso-sign-in-card/sso-sign-in-card.tsx +++ b/apps/blocks/src/blocks/auth/sso-sign-in-card/sso-sign-in-card.tsx @@ -240,7 +240,7 @@ export function AuthSsoSignInCard({ diff --git a/apps/blocks/src/blocks/auth/verify-email-banner/verify-email-banner.tsx b/apps/blocks/src/blocks/auth/verify-email-banner/verify-email-banner.tsx index b195015..5fe76b7 100644 --- a/apps/blocks/src/blocks/auth/verify-email-banner/verify-email-banner.tsx +++ b/apps/blocks/src/blocks/auth/verify-email-banner/verify-email-banner.tsx @@ -150,7 +150,7 @@ export function VerifyEmailBanner({
) : !isLoading ? ( -

{merged.emptyState}

+

{merged.emptyState}

) : null} diff --git a/apps/blocks/src/blocks/org/create-card/create-card.tsx b/apps/blocks/src/blocks/org/create-card/create-card.tsx index 3b16994..72e0e57 100644 --- a/apps/blocks/src/blocks/org/create-card/create-card.tsx +++ b/apps/blocks/src/blocks/org/create-card/create-card.tsx @@ -328,7 +328,7 @@ export function OrgCreateCard({ step1Form.handleSubmit(); }} > -

{merged.step1Title}

+

{merged.step1Title}

-

{merged.slugHint}

+

{merged.slugHint}

{step1Values.username.length >= 2 && (
{slugCheck.isLoading && ( @@ -422,7 +422,7 @@ export function OrgCreateCard({ function renderStep2() { return (
-

{merged.step2Title}

+

{merged.step2Title}

@@ -446,9 +446,9 @@ export function OrgCreateCard({ onChange={(e) => handleLogoChange(e.target.files?.[0] ?? null)} data-testid="org-logo-input" /> -

{merged.logoHint}

+

{merged.logoHint}

{logoError && ( -

+

{logoError}

)} @@ -490,7 +490,7 @@ export function OrgCreateCard({ const prevStep = showLogoStep ? (2 as 1 | 2 | 3) : (1 as 1 | 2 | 3); return (
-

{merged.step3Title}

+

{merged.step3Title}

@@ -503,8 +503,8 @@ export function OrgCreateCard({
-

{step1Values.displayName}

-

@{step1Values.username}

+

{step1Values.displayName}

+

@{step1Values.username}

@@ -554,7 +554,7 @@ export function OrgCreateCard({ -

+

Step {displayStep} of {totalSteps}

diff --git a/apps/blocks/src/blocks/org/invite-dialog/invite-dialog.tsx b/apps/blocks/src/blocks/org/invite-dialog/invite-dialog.tsx index 2d70cc6..4aeaf75 100644 --- a/apps/blocks/src/blocks/org/invite-dialog/invite-dialog.tsx +++ b/apps/blocks/src/blocks/org/invite-dialog/invite-dialog.tsx @@ -373,9 +373,9 @@ export function InviteDialog({ {/* Pending invites list */} {!pendingInvites.isLoading && (
-

{merged.pendingInvitesTitle}

+

{merged.pendingInvitesTitle}

{nodes.length === 0 ? ( -

{merged.pendingInvitesEmpty}

+

{merged.pendingInvitesEmpty}

) : (
    {nodes.map((invite) => { @@ -394,7 +394,7 @@ export function InviteDialog({ >

    {invite.email}

    -

    +

    {interpolate(merged.expiresIn, { days: daysLeft })}

    @@ -408,7 +408,7 @@ export function InviteDialog({ onClick={() => handleResendInvite(invite)} disabled={updateInvite.isPending || createInvite.isPending} aria-label={`Resend invitation to ${invite.email}`} - className="h-7 px-2 text-xs" + className="min-h-11 px-2 text-xs sm:min-h-10" > {merged.resendButton} @@ -418,7 +418,7 @@ export function InviteDialog({ onClick={() => setConfirmCancelId(invite.id)} disabled={updateInvite.isPending} aria-label={`Cancel invitation to ${invite.email}`} - className="text-destructive hover:text-destructive h-7 px-2 text-xs" + className="text-destructive hover:text-destructive min-h-11 px-2 text-xs sm:min-h-10" > {merged.cancelInviteButton} diff --git a/apps/blocks/src/blocks/org/members-list/members-list.tsx b/apps/blocks/src/blocks/org/members-list/members-list.tsx index 5b03ff5..38110a4 100644 --- a/apps/blocks/src/blocks/org/members-list/members-list.tsx +++ b/apps/blocks/src/blocks/org/members-list/members-list.tsx @@ -375,7 +375,7 @@ export function MembersList({ )} {!queryResult.isLoading && queryResult.members.length === 0 && ( -

    {merged.emptyState}

    +

    {merged.emptyState}

    )} {!queryResult.isLoading && queryResult.members.length > 0 && ( @@ -414,7 +414,7 @@ export function MembersList({ onValueChange={(val) => doRoleChange(member, val === '' ? null : val)} disabled={actionPending || defaultUpdateMutation.isPending} > - + diff --git a/apps/blocks/src/blocks/org/roles-editor/roles-editor.tsx b/apps/blocks/src/blocks/org/roles-editor/roles-editor.tsx index d9abddb..16af9c2 100644 --- a/apps/blocks/src/blocks/org/roles-editor/roles-editor.tsx +++ b/apps/blocks/src/blocks/org/roles-editor/roles-editor.tsx @@ -362,7 +362,7 @@ export function OrgRolesEditor({ {editing === null && ( <> {profiles.length === 0 ? ( -

    +

    {merged.emptyState}

    ) : ( @@ -512,10 +512,10 @@ export function OrgRolesEditor({ className="rounded-md border bg-background p-4 shadow-sm space-y-3" data-testid="delete-confirm-dialog" > -

    +

    {merged.deleteConfirmTitle}

    -

    {merged.deleteConfirmDescription}

    +

    {merged.deleteConfirmDescription}

    diff --git a/apps/blocks/src/blocks/org/scim-connections-list/scim-connections-list.tsx b/apps/blocks/src/blocks/org/scim-connections-list/scim-connections-list.tsx index e4e2a11..e0c1e51 100644 --- a/apps/blocks/src/blocks/org/scim-connections-list/scim-connections-list.tsx +++ b/apps/blocks/src/blocks/org/scim-connections-list/scim-connections-list.tsx @@ -95,8 +95,8 @@ export function OrgScimConnectionsList({ {merged.backendPendingLabel} -

    {merged.emptyTitle}

    -

    {merged.emptyDescription}

    +

    {merged.emptyTitle}

    +

    {merged.emptyDescription}

diff --git a/apps/blocks/src/blocks/org/scim-setup-guide/scim-setup-guide.tsx b/apps/blocks/src/blocks/org/scim-setup-guide/scim-setup-guide.tsx index 9a94889..1bc4246 100644 --- a/apps/blocks/src/blocks/org/scim-setup-guide/scim-setup-guide.tsx +++ b/apps/blocks/src/blocks/org/scim-setup-guide/scim-setup-guide.tsx @@ -151,7 +151,7 @@ function CopyableCode({ type="button" variant="outline" size="sm" - className="h-7 shrink-0 text-xs" + className="min-h-11 shrink-0 text-xs sm:min-h-10" onClick={handleCopy} data-testid="copy-button" > @@ -207,7 +207,7 @@ export function OrgScimSetupGuide({ {/* Provider selector */}
-

+

{merged.providerLabel}

@@ -217,7 +217,7 @@ export function OrgScimSetupGuide({ type="button" variant={activeProvider === p.value ? 'default' : 'outline'} size="sm" - className="h-7 text-xs" + className="min-h-11 text-xs sm:min-h-10" onClick={() => setActiveProvider(p.value)} data-testid={`provider-${p.value}`} > @@ -229,8 +229,8 @@ export function OrgScimSetupGuide({ {/* SCIM Endpoint */}
-

{merged.sectionEndpointTitle}

-

{merged.sectionEndpointDescription}

+

{merged.sectionEndpointTitle}

+

{merged.sectionEndpointDescription}

-

{merged.sectionTokenTitle}

-

{merged.sectionTokenDescription}

+

{merged.sectionTokenTitle}

+

{merged.sectionTokenDescription}

{/* Attribute mappings */}
-

{merged.sectionAttributesTitle}

-

{merged.sectionAttributesDescription}

+

{merged.sectionAttributesTitle}

+

{merged.sectionAttributesDescription}

@@ -270,7 +270,7 @@ export function OrgScimSetupGuide({ {/* External docs link */} -

+

For step-by-step instructions, see the{' '} -

{merged.slugHint}

+

{merged.slugHint}

{/* Warn when slug has been changed from its original value */} {originalSlug && field.state.value && field.state.value !== originalSlug && (

{merged.slugChangeWarning}

@@ -421,7 +421,7 @@ export function OrgSettingsForm({
-

{merged.dangerZoneTitle}

+

{merged.dangerZoneTitle}

{/* Action buttons — shown on hover / for unread items */} @@ -286,7 +286,7 @@ function NotificationItem({ item, messages, onMarkRead, onDismiss }: Notificatio {lastResult ? ( -

{lastResult}

+

{lastResult}

) : null} - {status ?

{status}

: null} + {status ?

{status}

: null} ); } diff --git a/apps/blocks/src/components/docs/demos/auth-mfa-backup-codes-regenerate.demo.tsx b/apps/blocks/src/components/docs/demos/auth-mfa-backup-codes-regenerate.demo.tsx index 651a714..41c4c6c 100644 --- a/apps/blocks/src/components/docs/demos/auth-mfa-backup-codes-regenerate.demo.tsx +++ b/apps/blocks/src/components/docs/demos/auth-mfa-backup-codes-regenerate.demo.tsx @@ -20,7 +20,7 @@ export function BlockDemo() { Regenerate backup codes {lastResult ? ( -

{lastResult}

+

{lastResult}

) : null} -

Session expired

+

Session expired

Your sign-in session has expired. Please sign in again to get a new verification link. @@ -79,7 +79,7 @@ export function BlockDemo() { {state === 'missing-token' && ( -

Invalid link

+

Invalid link

This sign-in link is missing required parameters. Please sign in again. diff --git a/apps/blocks/src/components/docs/demos/auth-mfa-totp-disable-confirm.demo.tsx b/apps/blocks/src/components/docs/demos/auth-mfa-totp-disable-confirm.demo.tsx index 71cdc36..f70cf26 100644 --- a/apps/blocks/src/components/docs/demos/auth-mfa-totp-disable-confirm.demo.tsx +++ b/apps/blocks/src/components/docs/demos/auth-mfa-totp-disable-confirm.demo.tsx @@ -20,7 +20,7 @@ export function BlockDemo() { - {status ?

{status}

: null} + {status ?

{status}

: null} setStatus('Signed out — query cache cleared')} onError={() => setStatus('Sign-out failed')} /> - {status ?

{status}

: null} + {status ?

{status}

: null} ); } diff --git a/apps/blocks/src/components/docs/demos/auth-step-up-dialog.demo.tsx b/apps/blocks/src/components/docs/demos/auth-step-up-dialog.demo.tsx index 2a65a4e..af6c216 100644 --- a/apps/blocks/src/components/docs/demos/auth-step-up-dialog.demo.tsx +++ b/apps/blocks/src/components/docs/demos/auth-step-up-dialog.demo.tsx @@ -17,7 +17,7 @@ export function BlockDemo() { - {last ?

Last result: {last}

: null} + {last ?

Last result: {last}

: null} setDismissed(false)} > Restore banner diff --git a/apps/blocks/src/components/docs/demos/org-invite-dialog.demo.tsx b/apps/blocks/src/components/docs/demos/org-invite-dialog.demo.tsx index 94e012b..5e606a3 100644 --- a/apps/blocks/src/components/docs/demos/org-invite-dialog.demo.tsx +++ b/apps/blocks/src/components/docs/demos/org-invite-dialog.demo.tsx @@ -19,7 +19,7 @@ export function BlockDemo() { Invite member {lastResult ? ( -

{lastResult}

+

{lastResult}

) : null} -

+

Signed out — reset the preview to reload.

diff --git a/apps/blocks/src/components/docs/demos/shell-command-palette.demo.tsx b/apps/blocks/src/components/docs/demos/shell-command-palette.demo.tsx index fa22947..e2b80f1 100644 --- a/apps/blocks/src/components/docs/demos/shell-command-palette.demo.tsx +++ b/apps/blocks/src/components/docs/demos/shell-command-palette.demo.tsx @@ -66,7 +66,7 @@ export function BlockDemo() { {lastAction ? ( -

+

Selected: {lastAction}

) : null} diff --git a/apps/blocks/src/components/docs/demos/shell-header.demo.tsx b/apps/blocks/src/components/docs/demos/shell-header.demo.tsx index 39f4c80..d9f50da 100644 --- a/apps/blocks/src/components/docs/demos/shell-header.demo.tsx +++ b/apps/blocks/src/components/docs/demos/shell-header.demo.tsx @@ -39,7 +39,7 @@ function DemoAvatar() { return ( - {last ?

stepUp(): {last}

: null} + {last ?

stepUp(): {last}

: null} ); } diff --git a/apps/blocks/src/components/docs/doc-page.tsx b/apps/blocks/src/components/docs/doc-page.tsx index 5fd4c22..98ece98 100644 --- a/apps/blocks/src/components/docs/doc-page.tsx +++ b/apps/blocks/src/components/docs/doc-page.tsx @@ -43,7 +43,7 @@ export interface DocPageProps { export function DocPage({ title, description, installUrl, prev, next, children }: DocPageProps) { return ( -
+

{title}

@@ -55,7 +55,7 @@ export function DocPage({ title, description, installUrl, prev, next, children } {installUrl ? ( -

+

First install? Complete the one-time{' '} diff --git a/apps/blocks/src/components/docs/messages-table.tsx b/apps/blocks/src/components/docs/messages-table.tsx index 520ff1e..6306536 100644 --- a/apps/blocks/src/components/docs/messages-table.tsx +++ b/apps/blocks/src/components/docs/messages-table.tsx @@ -19,7 +19,7 @@ type MessagesObject = Record; function KeyValueTable({ caption, keyHeader, rows }: { caption: string; keyHeader: string; rows: [string, string][] }) { return (

-

{caption}

+

{caption}

diff --git a/apps/blocks/src/components/docs/mobile-drawer.tsx b/apps/blocks/src/components/docs/mobile-drawer.tsx index f57bd76..830f092 100644 --- a/apps/blocks/src/components/docs/mobile-drawer.tsx +++ b/apps/blocks/src/components/docs/mobile-drawer.tsx @@ -22,9 +22,9 @@ export function MobileDrawer({ open, onOpenChange }: MobileDrawerProps) { return ( - + Registry navigation @@ -34,7 +34,7 @@ export function MobileDrawer({ open, onOpenChange }: MobileDrawerProps) {
-

Make it yours

+

Make it yours

diff --git a/apps/blocks/src/components/docs/nav-item.tsx b/apps/blocks/src/components/docs/nav-item.tsx index 6935965..80b0b95 100644 --- a/apps/blocks/src/components/docs/nav-item.tsx +++ b/apps/blocks/src/components/docs/nav-item.tsx @@ -33,9 +33,9 @@ export function NavItem({ href, title, active, isNew, isUpdated, indent, onNavig aria-current={active ? 'page' : undefined} onClick={onNavigate} className={cn( - 'flex h-8 items-center rounded-lg text-[13px] text-muted-foreground outline-none', + 'flex h-11 items-center rounded-lg text-[13px] text-muted-foreground outline-none sm:h-10', indent ? 'pl-6 pr-3' : 'px-3', - 'transition-colors duration-[var(--dur-fast)]', + 'transition-[color,background-color,scale] duration-150 ease-out motion-safe:active:scale-[0.96] motion-reduce:transition-none', 'hover:bg-hover hover:text-foreground active:bg-active active:text-foreground focus-visible:ring-1 focus-visible:ring-ring', active && 'bg-active text-foreground', )} diff --git a/apps/blocks/src/components/docs/nav-menu.tsx b/apps/blocks/src/components/docs/nav-menu.tsx index 3771529..d70b682 100644 --- a/apps/blocks/src/components/docs/nav-menu.tsx +++ b/apps/blocks/src/components/docs/nav-menu.tsx @@ -149,7 +149,7 @@ const NavMenu = forwardRef(({ children, activeSlug, c {...props} > {/* Active route background */} - + {activeRouteRect && ( (({ children, activeSlug, c {/* Hover background */} - + {activeRect && ( (({ children, activeSlug, c {/* Focus ring */} - + {focusRect && ( ( data-nav-index={index} tabIndex={tabIdx} aria-current={isActiveRoute ? 'page' : undefined} - className={cn('relative z-10 flex h-8 cursor-pointer items-center rounded-lg px-3 outline-none', className)} + className={cn( + 'relative z-10 flex h-11 cursor-pointer items-center rounded-lg px-3 outline-none transition-transform duration-150 ease-out motion-safe:active:scale-[0.96] motion-reduce:transition-none sm:h-10', + className, + )} {...props} > {Icon && ( diff --git a/apps/blocks/src/components/docs/preview-frame.tsx b/apps/blocks/src/components/docs/preview-frame.tsx index f3b1b91..f129795 100644 --- a/apps/blocks/src/components/docs/preview-frame.tsx +++ b/apps/blocks/src/components/docs/preview-frame.tsx @@ -45,8 +45,8 @@ function PreviewErrorFallback() { role="alert" className="flex min-h-40 w-full flex-col items-center justify-center rounded-lg border border-border/60 bg-card p-6 text-center" > -

Preview unavailable

-

+

Preview unavailable

+

This live preview could not be displayed. Use Reset to try again.

diff --git a/apps/blocks/src/components/docs/requires-panel.tsx b/apps/blocks/src/components/docs/requires-panel.tsx index a3516de..a0eacd1 100644 --- a/apps/blocks/src/components/docs/requires-panel.tsx +++ b/apps/blocks/src/components/docs/requires-panel.tsx @@ -34,7 +34,7 @@ const chipClass = 'rounded-lg bg-muted px-1.5 py-0.5 font-mono text-[12px] text- function OpGroup({ label, items }: { label: string; items: string[] }) { return (
-

{label}

+

{label}

    {items.map((it) => (
  • diff --git a/apps/blocks/src/components/docs/right-panel.tsx b/apps/blocks/src/components/docs/right-panel.tsx index 136e1e5..aa9e25a 100644 --- a/apps/blocks/src/components/docs/right-panel.tsx +++ b/apps/blocks/src/components/docs/right-panel.tsx @@ -90,7 +90,7 @@ function PmControl() { aria-label="Package manager" value={pm} onChange={(e) => setPm(e.target.value as PackageManager)} - className="h-7 cursor-pointer rounded-lg bg-transparent px-2 text-[13px] text-foreground outline-none transition-colors duration-[var(--dur-fast)] hover:bg-hover active:bg-active focus-visible:ring-1 focus-visible:ring-ring" + className="h-11 cursor-pointer rounded-lg bg-transparent px-2 text-[13px] text-foreground outline-none transition-[color,background-color,scale] duration-150 ease-out hover:bg-hover active:bg-active motion-safe:active:scale-[0.96] motion-reduce:transition-none focus-visible:ring-1 focus-visible:ring-ring sm:h-10" > {PACKAGE_MANAGERS.map((p) => (