Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changelog

## [0.6.6] - 2026-10-14

### Changed

- **Theming guidance for the Svelte pages.** `bridge guide` now explains how Bridge's sign-in and subscription pages match an app. They inherit its font, text size and text colour. A few `--bridge-*` variables, now including heading, button and label weights and a button shadow, cover the rest. Any plain CSS the app writes wins over Bridge's styles. The variable list in `bridge guide mechanisms` is brought up to date.

## [0.6.5] - 2026-10-14

### Added
Expand Down
2 changes: 1 addition & 1 deletion bridge-cli/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@nebulr-group/bridge-cli",
"version": "0.6.5",
"version": "0.6.6",
"description": "The Bridge CLI: set up and manage sign-in, roles, plans, feature flags and API tokens from your terminal or AI coding agent.",
"author": "Nebulr Group",
"license": "MIT",
Expand Down
2 changes: 1 addition & 1 deletion bridge-cli/prompts/decisions/look-and-feel.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ Product questions. Ask, wait, never guess.
Match the app's design without asking, and say which level you stopped at.

- **Level 0, layout:** the pages already sit inside the app's layout, so its header and navigation surround them. Never the stopping point on its own: the form inside still wears Bridge's colours.
- **Level 1, tokens — always:** map the app's design onto the `--bridge-*` tokens in the app's own stylesheet: its primary colour and hover to `--bridge-primary` / `--bridge-primary-hover` / `--bridge-primary-fg`, its border colour to `--bridge-border`, its corner radius to `--bridge-border-radius`, its focus ring to `--bridge-input-focus`, its text and muted text to `--bridge-foreground` / `--bridge-muted`, its surfaces to `--bridge-bg` / `--bridge-muted-bg`, its error and success colours to the alert tokens. Reference the app's own variables (`--bridge-primary: var(--primary)`) rather than copying values, so a later theme change carries over, dark mode included. The components inherit the page font, so set nothing for it unless the app sets its font on something other than `body`. Reason: tokens are the supported contract; ordinary CSS already wins over Bridge's defaults, so there is never a need for `!important`.
- **Level 1, tokens — always:** map the app's design onto the `--bridge-*` tokens in the app's own stylesheet: its primary colour and hover to `--bridge-primary` / `--bridge-primary-hover` / `--bridge-primary-fg`, its border colour to `--bridge-border`, its corner radius to `--bridge-border-radius`, its focus ring to `--bridge-input-focus`, its text and muted text to `--bridge-foreground` / `--bridge-muted`, its surfaces to `--bridge-bg` / `--bridge-muted-bg`, its error and success colours to the alert tokens, and, when the app has a type style of its own, its heading, button and label weights to `--bridge-font-weight-heading` / `-button` / `-label` and its button and card shadows to `--bridge-button-shadow` / `--bridge-card-shadow`. Reference the app's own variables (`--bridge-primary: var(--primary)`) rather than copying values, so a later theme change carries over, dark mode included. Don't set what the app already gives: the components inherit its font and text colour, and every Bridge text size follows the app's `<body>` text size; set a font only if the app puts it on something other than `body`. For anything the tokens don't cover, write plain CSS against Bridge's classes and `[data-bridge-*]` attributes, outside any `@layer`. Reason: tokens are the supported contract, and Bridge's styles sit in a cascade layer named `bridge`, so plain app CSS always wins without `!important`. Tailwind utility classes on Bridge's elements lose where Bridge sets the same property; use plain CSS there.
- **Level 2, frame and heading — when the app has a page shell:** if the app's own pages sit in a card, a panel or a two-column layout, pass the `frame` snippet so sign-in sits in the same one, using the app's own classes or components. Reason: it changes every page at once and keeps each page's own sub-steps.
- **Level 3, take over one page:** create that page's own route file (e.g. `src/routes/auth/login/+page.svelte`); every other page keeps working.
- **Level 4, headless:** build everything on `getBridgeAuth()`. Only when the developer asks for it.
Expand Down
52 changes: 29 additions & 23 deletions bridge-cli/prompts/mechanisms.md
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ The same ladder holds for the sign-in pages (`<BridgeAuthRoutes>`) and the subsc
| Rung | What you do | What you own |
|---|---|---|
| **0 — nothing** | Bridge's pages render inside your own `+layout.svelte` | Your navigation, header and shell already surround them |
| **1 — tokens** | Set `--bridge-*` CSS variables in your CSS | Colours, radius, spacing |
| **1 — tokens** | Set `--bridge-*` CSS variables in your CSS, and plain CSS for anything else | Colours, radius, spacing, weights, shadows |
| **2 — frame and heading** | Pass the `frame(page, children)` and `heading(page)` snippets | Everything around the form on every page, and each page's heading |
| **3 — take over one page** | Create that page's own route file, e.g. `src/routes/auth/login/+page.svelte` | That one page; SvelteKit prefers it over `[...bridge]`, every other page keeps working |
| **4 — headless** | Build your own UI on `getBridgeAuth()` | Everything |
Expand All @@ -243,36 +243,42 @@ The same ladder holds for the sign-in pages (`<BridgeAuthRoutes>`) and the subsc

`heading` replaces only each page's main step (the login credentials step, the signup form, the set-password form); sub-steps such as "Reset your password" keep their own, so two headings never stack. There are no per-page snippets: to change more than frame and heading, take over the page (rung 3). A sign-in page you own navigates itself after sign-in: `<LoginForm onLogin={() => goto(readReturnTo($page.url) ?? '/')} />`.

**The token contract (rung 1).** These `--bridge-*` variables are the supported way to restyle the components; each has a built-in default. Set them on `:root` or on any wrapper.
**The token contract (rung 1).** These `--bridge-*` variables are the supported way to restyle the components; each has a built-in default. Set them on `:root` or on any wrapper. Set only what the app does not already give: Bridge inherits the app's font and text colour, and every Bridge text size follows the app's `<body>` text size.

| Token | Default | Styles |
|---|---|---|
| `--bridge-primary` | `#4f46e5` | Primary buttons, selected plan interval, active workspace border |
| `--bridge-primary-hover` | `#4338ca` | Primary button hover |
| `--bridge-primary-fg` | `#ffffff` | Text on primary buttons |
| `--bridge-primary-foreground` | `#ffffff` | Workspace avatar text; plan picker fallback when `--bridge-primary-fg` is unset |
| `--bridge-primary-light` | `#eff6ff` | Active workspace background |
| `--bridge-border` | `#d1d5db` | Input and secondary button borders |
| `--bridge-border-radius` | `6px` | Corners of inputs, buttons, alerts, cards |
| `--bridge-input-focus` | `#4f46e5` | Input focus ring |
| `--bridge-foreground` | `#374151` | Password-toggle hover, workspace names |
| `--bridge-primary` | `#4f46e5` | Primary buttons, the selected tab and plan interval, the active workspace |
| `--bridge-primary-hover` | primary, 15% darker | Primary button hover |
| `--bridge-primary-fg` | `#ffffff` | Text on primary surfaces |
| `--bridge-primary-light` | primary at 10% | Tint behind the active workspace |
| `--bridge-input-focus` | primary | Input focus ring |
| `--bridge-bg` | `#ffffff` | Dialogs, menus, panels |
| `--bridge-foreground` | `#111827` | Text on those surfaces, workspace names |
| `--bridge-muted` | `#6b7280` | Secondary text, hints, table headings |
| `--bridge-bg` | `#ffffff` | Plan-change confirmation panel |
| `--bridge-bg-muted` | `#f5f5f5` | MFA backup code |
| `--bridge-muted-bg` | `#f3f4f6` | Workspace list hover, plan interval tabs (which fall back to `--bridge-bg-muted`) |
| `--bridge-alert-error-bg` | `#fef2f2` | Error alert background |
| `--bridge-alert-error-fg` | `#991b1b` | Error alert text |
| `--bridge-alert-error-border` | `#fca5a5` | Error alert border |
| `--bridge-alert-success-bg` | `#f0fdf4` | Success alert background |
| `--bridge-alert-success-fg` | `#166534` | Success alert text |
| `--bridge-alert-success-border` | `#86efac` | Success alert border |
| `--bridge-muted-bg` | `#f3f4f6` | Subtle fills: tab tracks, hovers, the MFA backup code |
| `--bridge-border` | `#d1d5db` | Input, table, card and secondary button borders |
| `--bridge-border-radius` | `6px` | Corners of inputs, buttons, alerts, cards and dialogs |
| `--bridge-card-bg` | `--bridge-bg` | Plan cards and the current-plan panel on the subscription page |
| `--bridge-card-shadow` | a soft 1–3px shadow | Plan cards, the current-plan panel and the plan-change dialog. `none` for a flat look |
| `--bridge-button-shadow` | `none` | Every Bridge button's shadow, e.g. `4px 4px 0 #111` |
| `--bridge-font-size` | your `<body>` text size | The base every Bridge text size scales from |
| `--bridge-font-weight-heading` | `600` (`700` on a few titles) | Page, dialog and section titles, plan names, prices |
| `--bridge-font-weight-button` | `500` | Every Bridge button |
| `--bridge-font-weight-label` | `500` (`600` on a few) | Form labels, table headings, badges, names |
| `--bridge-overlay` | `rgba(15, 23, 42, 0.45)` | Backdrop behind dialogs |
| `--bridge-alert-error-{bg,fg,border}` | `#fef2f2` / `#991b1b` / `#fca5a5` | Errors, critical billing notices, cancelled plan badge |
| `--bridge-alert-success-{bg,fg,border}` | `#f0fdf4` / `#166534` / `#86efac` | Confirmations, active plan badge |
| `--bridge-alert-info-{bg,fg,border}` | `#eff6ff` / `#1e40af` / `#bfdbfe` | Info notices, trial badge |
| `--bridge-alert-warning-{bg,fg,border}` | `#fffbeb` / `#92400e` / `#fcd34d` | Warnings, a quota nearing its limit, past-due badge |
| `--bridge-auth-page-padding` | `3rem 1rem` | Padding of the default sign-in page container |
| `--bridge-billing-page-width` | `60rem` | Width of the subscription pages and `<BridgePaywallPage>` |
| `--bridge-billing-page-padding` | `3rem 1rem` | Padding of the subscription pages and `<BridgePaywallPage>` |
| `--bridge-paywall-bg` | `rgba(15, 23, 42, 0.72)` | Backdrop of the `<BridgePaywall>` overlay |
| `--bridge-paywall-panel-bg` | `#ffffff` | Panel of the `<BridgePaywall>` overlay |
| `--bridge-paywall-bg` | `rgba(15, 23, 42, 0.72)` | Backdrop of the `<BridgePaywall>` overlay and the billing lockscreen |
| `--bridge-paywall-panel-bg` | `--bridge-bg` | Panel of the `<BridgePaywall>` overlay |

All default rules use `:where()`, so any selector of yours wins without `!important`. Leaving out `import '@nebulr-group/bridge-svelte/styles'` makes the components headless: plain HTML for you to style.
The derived tokens (hover, light, focus) follow `--bridge-primary` wherever you set it, unless you set them too. Two older names still work as deprecated aliases: `--bridge-primary-foreground` for `--bridge-primary-fg`, and `--bridge-bg-muted` for `--bridge-muted-bg`.

All Bridge styles sit in a CSS cascade layer named `bridge`, so plain CSS the app writes outside a layer overrides them, whatever the load order and with no `!important`: for anything the tokens don't cover, target Bridge's classes and `[data-bridge-*]` attributes (`.bridge-btn-primary:hover { transform: translate(-2px, -2px); }`). Tailwind utility classes on Bridge's elements lose where Bridge sets the same property; use plain CSS there, or Tailwind's important modifier. Leaving out `import '@nebulr-group/bridge-svelte/styles'` makes the components headless: plain HTML for you to style.

## 7. Pages Bridge serves, and the one it only offers

Expand Down
Loading