mirror of
https://github.com/supabase/supabase.git
synced 2026-10-05 09:25:06 +03:00
fix(ui): make brand text readable across themes (#49871)
## What kind of change does this PR introduce? Bug fix and design-system update. Resolves DEPR-316. Follow-up rename (`text-brand` → `text-primary`) is in a dedicated PR (https://github.com/supabase/supabase/pull/50564) stacked on this one. ## What is the current behavior? `text-brand` resolves to the canonical bright brand green in places that need readable text, which fails WCAG AA on light surfaces. A separate `text-brand-display` token adds another green for large type. ## What is the new behavior? - `text-brand` maps to accessible `--primary` (light mode darkened to meet ~4.5:1 AA) - `--hue` / `--primary-hue` aligned to 157.5 - `text-brand-display` removed; former display callsites use `text-brand` - Bright fills/borders stay on `brand-default` - Design-system colour and typography docs updated | Before | After | | --- | --- | | <img width="514" height="112" alt="CleanShot 2026-09-02 at 11 13 09@2x" src="https://github.com/user-attachments/assets/4e0138a9-a32d-4e4c-a426-90736706e1e7" /> | <img width="512" height="138" alt="CleanShot 2026-09-21 at 11 42 05@2x" src="https://github.com/user-attachments/assets/164cc5b1-a0c5-4e93-95f1-80016641a114" /> | | <img width="864" height="266" alt="CleanShot 2026-09-02 at 11 13 53@2x" src="https://github.com/user-attachments/assets/3c1ca53f-bf9e-431e-bc15-816b4a275b8e" /> | <img width="882" height="248" alt="CleanShot 2026-09-21 at 11 41 37@2x" src="https://github.com/user-attachments/assets/24828e7b-ed6b-44cb-b9dc-becc3398bdfc" /> | | <img width="782" height="692" alt="CleanShot 2026-09-02 at 11 16 30@2x" src="https://github.com/user-attachments/assets/fc871977-77bc-47fb-9e0e-9284e0ecd5cc" /> | <img width="730" height="690" alt="CleanShot 2026-09-21 at 11 42 52@2x" src="https://github.com/user-attachments/assets/bf479515-d5f9-471e-b82d-f097c0f4b56c" /> | | <img width="480" height="306" alt="CleanShot 2026-09-02 at 11 18 53@2x" src="https://github.com/user-attachments/assets/03f341f4-f02e-44f8-a2b2-8c31670d0427" /> | <img width="470" height="300" alt="CleanShot 2026-09-21 at 11 43 19@2x" src="https://github.com/user-attachments/assets/9df18217-d5e6-48b8-ba0b-579d2664b94b" /> | | <img width="960" height="300" alt="CleanShot 2026-09-02 at 11 32 04@2x" src="https://github.com/user-attachments/assets/6b1d9373-7a71-4247-81ff-26441604b09d" /> | <img width="980" height="306" alt="CleanShot 2026-09-21 at 11 44 13@2x" src="https://github.com/user-attachments/assets/41ad4784-02ec-4b29-b860-32af9fa79aa8" /> | | <img width="924" height="214" alt="CleanShot 2026-09-02 at 11 34 44@2x" src="https://github.com/user-attachments/assets/1de661fe-c7b6-499b-a94f-e4737436ec79" /> | <img width="752" height="162" alt="CleanShot 2026-09-21 at 11 44 56@2x" src="https://github.com/user-attachments/assets/1811890f-0660-4445-84e9-447720954fa1" /> | ## To test Test each callsite **in light mode** (dark mode is largely unchanged). ### WWW - [Homepage](https://zone-www-dot-com-git-dnywh-depr-316-brand-text-tokens-supabase.vercel.app/): “Scale to millions” uses readable brand text (display token is gone) - [Careers](https://zone-www-dot-com-git-dnywh-depr-316-brand-text-tokens-supabase.vercel.app/careers): small “Careers” eyebrow readable; green dividers stay bright `brand-default` - [Contact](https://zone-www-dot-com-git-dnywh-depr-316-brand-text-tokens-supabase.vercel.app/contact-us): email / policy links use readable brand text - [Regions](https://zone-www-dot-com-git-dnywh-depr-316-brand-text-tokens-supabase.vercel.app/regions): “Ask about early access to BYOC” readable ### Docs - [Docs homepage](https://docs-git-dnywh-depr-316-brand-text-tokens-supabase.vercel.app/docs): “DOCS” wordmark and resource links readable - [Database overview](https://docs-git-dnywh-depr-316-brand-text-tokens-supabase.vercel.app/docs/guides/database/overview): nav / footer brand links readable - [JavaScript reference](https://docs-git-dnywh-depr-316-brand-text-tokens-supabase.vercel.app/docs/reference/javascript/introduction): active sidebar treatment readable ### Design system - [Typography](https://design-system-git-dnywh-depr-316-brand-text-tokens-supabase.vercel.app/docs/typography): documents `text-brand` only (no display) - [Colour usage](https://design-system-git-dnywh-depr-316-brand-text-tokens-supabase.vercel.app/docs/color-usage): `text-brand` vs `bg-brand-default` - [Design-system homepage](https://design-system-git-dnywh-depr-316-brand-text-tokens-supabase.vercel.app/): brand text examples across themes ### Studio - [Auth providers](https://studio-staging-git-dnywh-depr-316-brand-text-tokens-supabase.vercel.app/dashboard/project/_/auth/providers): enabled provider badge text readable; status dot stays bright - [Database policies](https://studio-staging-git-dnywh-depr-316-brand-text-tokens-supabase.vercel.app/dashboard/project/_/database/policies?new=true): template hover text more legible - [Database connections](https://studio-staging-git-dnywh-depr-316-brand-text-tokens-supabase.vercel.app/dashboard/project/_/observability/connections): “Live” status readable; animated dot stays bright green --------- Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
This commit is contained in:
1 parent
e1bdcc99db
commit
a31ca2bad0
166 files changed
+305
-279
No files matched your search
@@ -125,6 +125,10 @@ reviews:
|
||||
"read more", or "learn more" when it does not describe the
|
||||
destination. Skip if aria-label or wrapping context already names
|
||||
where the link goes.
|
||||
- Color contrast: flag non-large informative text below 4.5:1 and large informative
|
||||
text (at least 24px regular or 18.5px bold) below 3:1. Skip logotypes and
|
||||
decorative text. Treat expressive text at 40px or larger as advisory rather
|
||||
than blocking.
|
||||
|
||||
# Applies our internal engineering skills (.agents/skills/) as CodeRabbit review
|
||||
# guidelines. The skills are the single source of truth — they are consumed
|
||||
|
||||
@@ -9,10 +9,18 @@ The shorthand utility classes below simplify our full color palette by providing
|
||||
|
||||
Use accent text colors (e.g. text-destructive, text-warning) sparingly to avoid visual overload.
|
||||
|
||||
Use `text-brand` for readable branded text such as links, labels, and statuses. On light-theme
|
||||
surfaces it meets the 4.5:1 WCAG AA requirement for normal text. Use `bg-brand-default` /
|
||||
`border-brand-default` when you need the canonical bright Supabase green as a fill or border.
|
||||
|
||||
<Colors definition={'text'} />
|
||||
|
||||
## Background
|
||||
|
||||
Use `bg-brand-default` when the canonical Supabase green is required as a fill. The same
|
||||
`brand-default` suffix applies to borders and other non-text utilities, such as
|
||||
`border-brand-default`.
|
||||
|
||||
<Colors definition={'background'} />
|
||||
|
||||
### App backgrounds
|
||||
|
||||
@@ -9,7 +9,9 @@ The shorthands below are composed of core [Tailwind utility classes](../docs/tai
|
||||
|
||||
## Shorthands
|
||||
|
||||
| Value | Usage |
|
||||
| ------------------ | ---------------------------------------------------------------------------- |
|
||||
| `text-code-inline` | Apply to a `code` element for inline code or similar custom inline content |
|
||||
| `text-brand-link` | Supabase green text that meets contrast requirements in light and dark modes |
|
||||
| Value | Usage |
|
||||
| ------------------ | -------------------------------------------------------------------------- |
|
||||
| `text-code-inline` | Apply to a `code` element for inline code or similar custom inline content |
|
||||
| `text-brand` | Accessible Supabase green for readable branded text |
|
||||
|
||||
`text-brand` is independent from `bg-brand-default`, `border-brand-default`, and other non-text brand utilities. Its light-mode value has at least 4.5:1 contrast against the light surfaces used by the apps, meeting WCAG AA for normal text.
|
||||
@@ -23,7 +23,7 @@ export default function SuccessCheckSelected() {
|
||||
className={cn(
|
||||
'relative flex w-full items-center rounded-md border px-4 py-3 text-left text-sm transition-colors',
|
||||
isSelected
|
||||
? 'border-brand bg-brand-200/20 pr-10 dark:bg-brand-300'
|
||||
? 'border-brand-default bg-brand-200/20 pr-10 dark:bg-brand-300'
|
||||
: 'hover:border-default hover:bg-surface-200'
|
||||
)}
|
||||
>
|
||||
|
||||
@@ -108,7 +108,7 @@ Use the [Write the docs](../../.agents/skills/pm-the-docs/reference/write-the-do
|
||||
|
||||
### Edit existing pages
|
||||
|
||||
Use [`edit-the-docs`](../../.agents/skills/edit-the-docs/SKILL.md) for style, structure, or brevity on an existing page when you are not changing the product story.
|
||||
Use [`edit-the-docs`](../../.agents/skills/edit-the-docs/SKILL.md) for style, structure, or brevity on an existing page when you are not changing the product story.
|
||||
|
||||
## Document types
|
||||
|
||||
|
||||
@@ -330,7 +330,7 @@ const HomePage = () => (
|
||||
<TextLink
|
||||
label="Explore more resources"
|
||||
url="/guides/resources"
|
||||
className="no-underline text-brand-link text-sm"
|
||||
className="no-underline text-brand text-sm"
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -388,7 +388,7 @@ const HomePage = () => (
|
||||
<TextLink
|
||||
label="More on self-hosting"
|
||||
url="/guides/self-hosting"
|
||||
className="no-underline text-brand-link text-sm"
|
||||
className="no-underline text-brand text-sm"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -179,7 +179,7 @@ function Feedback({ className }: { className?: string }) {
|
||||
'[transition-timing-function:cubic-bezier(.76,0,.23,1)]',
|
||||
!isYes && 'hover:text-brand-600 hover:border-brand-500',
|
||||
isYes &&
|
||||
'bg-brand text-brand-200 border-brand! disabled:opacity-100 -translate-x-[calc(100%+var(--container-inline-flex-gap,0.5rem))]',
|
||||
'bg-brand-default text-brand-200 border-brand-default! disabled:opacity-100 -translate-x-[calc(100%+var(--container-inline-flex-gap,0.5rem))]',
|
||||
!showYes && 'opacity-0 invisible'
|
||||
)}
|
||||
onClick={() => handleVote('yes')}
|
||||
|
||||
@@ -94,7 +94,7 @@ function FeedbackModal({ visible, page, onCancel, onSubmit }: FeedbackModalProps
|
||||
href="https://supabase.com/dashboard/support/new"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-brand-link hover:underline"
|
||||
className="text-brand hover:underline"
|
||||
>
|
||||
support request
|
||||
</a>
|
||||
|
||||
@@ -14,7 +14,7 @@ const Footer = ({ className }: { className?: string }) => (
|
||||
<p>{text}</p>
|
||||
<Link
|
||||
href={url}
|
||||
className="text-brand-link hover:underline"
|
||||
className="text-brand hover:underline"
|
||||
target="_blank"
|
||||
rel="noreferrer noopener"
|
||||
>
|
||||
|
||||
@@ -137,7 +137,7 @@ const GlobalMobileMenu = ({ open, setOpen }: Props) => {
|
||||
height={24}
|
||||
alt="Supabase Logo"
|
||||
/>
|
||||
<span className="font-mono text-sm font-medium text-brand-link mb-px">DOCS</span>
|
||||
<span className="font-mono text-sm font-medium text-brand mb-px">DOCS</span>
|
||||
</Link>
|
||||
<div className="flex gap-4 items-center">
|
||||
<ThemeToggle contentClassName="bg-surface-200" />
|
||||
|
||||
@@ -22,7 +22,7 @@ const NavigationMenuCliList = ({ currentLevel, setLevel, id }) => {
|
||||
<li key={id} className="function-link-item text-foreground-lighter leading-3">
|
||||
<Link
|
||||
href={`#${id}`}
|
||||
className="cursor-pointer transition text-foreground-lighter text-sm hover:text-brand-link flex gap-3"
|
||||
className="cursor-pointer transition text-foreground-lighter text-sm hover:text-brand flex gap-3"
|
||||
>
|
||||
{icon && <img className="w-3" src={`${BASE_PATH}${icon}`} />}
|
||||
{title}
|
||||
@@ -99,7 +99,7 @@ const NavigationMenuCliList = ({ currentLevel, setLevel, id }) => {
|
||||
href={`${menu.parent ?? '/'}`}
|
||||
className={[
|
||||
'flex items-center gap-1 text-xs group mb-3',
|
||||
'text-base transition-all duration-200 text-brand-link hover:text-brand-600 hover:cursor-pointer ',
|
||||
'text-base transition-all duration-200 text-brand hover:text-brand-600 hover:cursor-pointer ',
|
||||
].join(' ')}
|
||||
>
|
||||
<div className="relative w-2">
|
||||
|
||||
@@ -43,7 +43,7 @@ const HeaderLink = React.memo(function HeaderLink(props: {
|
||||
className={[
|
||||
' ',
|
||||
!props.title && 'capitalize',
|
||||
props.url === pathname ? 'text-brand-link' : 'hover:text-brand-link text-foreground',
|
||||
props.url === pathname ? 'text-brand' : 'hover:text-brand text-foreground',
|
||||
].join(' ')}
|
||||
>
|
||||
{props.title ?? props.id}
|
||||
@@ -111,7 +111,7 @@ const ContentAccordionLink = React.memo(function ContentAccordionLink(props: any
|
||||
'cursor-pointer transition text-sm',
|
||||
'focus-inset rounded-md',
|
||||
activeItem
|
||||
? 'text-brand-link font-medium'
|
||||
? 'text-brand font-medium'
|
||||
: 'hover:text-foreground text-foreground-lighter',
|
||||
].join(' ')}
|
||||
>
|
||||
@@ -146,8 +146,8 @@ const ContentAccordionLink = React.memo(function ContentAccordionLink(props: any
|
||||
'relative block py-1.25 pl-1 -ml-1 cursor-pointer transition text-sm',
|
||||
'focus-inset rounded-md',
|
||||
child.url === pathname
|
||||
? 'text-brand-link'
|
||||
: 'hover:text-brand-link text-foreground-lighter',
|
||||
? 'text-brand'
|
||||
: 'hover:text-brand text-foreground-lighter',
|
||||
].join(' ')}
|
||||
>
|
||||
{child.url === pathname && (
|
||||
@@ -173,9 +173,7 @@ const ContentAccordionLink = React.memo(function ContentAccordionLink(props: any
|
||||
'flex items-center gap-2',
|
||||
'cursor-pointer transition text-sm',
|
||||
'focus-inset rounded-md',
|
||||
activeItem
|
||||
? 'text-brand-link font-medium'
|
||||
: 'hover:text-foreground text-foreground-lighter',
|
||||
activeItem ? 'text-brand font-medium' : 'hover:text-foreground text-foreground-lighter',
|
||||
].join(' ')}
|
||||
parent={props.subItem.parent}
|
||||
>
|
||||
@@ -206,9 +204,7 @@ const ContentLink = React.memo(function ContentLink(props: any) {
|
||||
className={[
|
||||
'cursor-pointer transition text-sm',
|
||||
'focus-inset rounded-md',
|
||||
props.url === pathname
|
||||
? 'text-brand-link'
|
||||
: 'hover:text-foreground text-foreground-lighter',
|
||||
props.url === pathname ? 'text-brand' : 'hover:text-foreground text-foreground-lighter',
|
||||
].join(' ')}
|
||||
>
|
||||
{props.icon && (
|
||||
@@ -230,7 +226,7 @@ const Content = (props) => {
|
||||
return (
|
||||
<div className="relative w-full flex flex-col gap-0 pb-5">
|
||||
<Link href={menu.url ?? ''}>
|
||||
<div className="flex items-center gap-3 my-3 text-brand-link">
|
||||
<div className="flex items-center gap-3 my-3 text-brand">
|
||||
<MenuIconPicker icon={menu.icon} />
|
||||
<HeaderLink title={menu.title} url={menu.url} id={id} />
|
||||
</div>
|
||||
|
||||
@@ -132,7 +132,7 @@ const HeaderLogo = memo(() => {
|
||||
height={navigationLogo?.height ?? 18}
|
||||
alt="Supabase wordmark"
|
||||
/>
|
||||
<span className="font-mono text-sm font-medium text-brand-link mb-px">DOCS</span>
|
||||
<span className="font-mono text-sm font-medium text-brand mb-px">DOCS</span>
|
||||
</Link>
|
||||
)
|
||||
})
|
||||
|
||||
@@ -80,7 +80,7 @@ const SideBar = ({ menuItems = [] }: { menuItems: any }) => {
|
||||
'py-1.5 px-5 rounded-sm text-sm transition',
|
||||
`${
|
||||
item.url === pathname
|
||||
? 'bg-background text-brand-link'
|
||||
? 'bg-background text-brand'
|
||||
: 'text-foreground-light hover:text-foreground'
|
||||
}`,
|
||||
].join(' ')}
|
||||
@@ -105,7 +105,7 @@ const SideBar = ({ menuItems = [] }: { menuItems: any }) => {
|
||||
size={14}
|
||||
strokeWidth={2}
|
||||
/>
|
||||
<span className="text-foreground text-sm group-hover:text-brand-link transition">
|
||||
<span className="text-foreground text-sm group-hover:text-brand transition">
|
||||
{group.label}
|
||||
</span>
|
||||
</Accordion.Trigger>
|
||||
@@ -119,7 +119,7 @@ const SideBar = ({ menuItems = [] }: { menuItems: any }) => {
|
||||
'py-1.5 px-5 rounded-sm text-sm transition',
|
||||
`${
|
||||
section.url === pathname
|
||||
? 'bg-background text-brand-link'
|
||||
? 'bg-background text-brand'
|
||||
: 'text-foreground-light hover:text-foreground'
|
||||
}`,
|
||||
].join(' ')}
|
||||
@@ -144,7 +144,7 @@ const SideBar = ({ menuItems = [] }: { menuItems: any }) => {
|
||||
size={14}
|
||||
strokeWidth={2}
|
||||
/>
|
||||
<span className="text-foreground text-sm group-hover:text-brand-link transition">
|
||||
<span className="text-foreground text-sm group-hover:text-brand transition">
|
||||
{section.name}
|
||||
</span>
|
||||
</Accordion.Trigger>
|
||||
@@ -157,7 +157,7 @@ const SideBar = ({ menuItems = [] }: { menuItems: any }) => {
|
||||
'py-1.5 ml-4 px-5 rounded-sm text-sm transition',
|
||||
`${
|
||||
item.url === pathname
|
||||
? 'bg-background text-brand-link'
|
||||
? 'bg-background text-brand'
|
||||
: 'text-foreground-light hover:text-foreground'
|
||||
}`,
|
||||
].join(' ')}
|
||||
|
||||
@@ -40,7 +40,7 @@ function ClientLibHeader({ menuData, className }: ClientLibHeaderProps) {
|
||||
href={menuData.pkg.repo}
|
||||
target="_blank"
|
||||
rel="noreferrer noopener"
|
||||
className="hover:text-brand-link focus-visible:text-brand-link transition-colors"
|
||||
className="hover:text-brand focus-visible:text-brand transition-colors"
|
||||
>
|
||||
<span className="sr-only">View on GitHub</span>
|
||||
<Github size={18} />
|
||||
|
||||
@@ -18,7 +18,7 @@ function PluginInstructions({ client }: { client: PluginClient }) {
|
||||
href="https://claude.com/plugins/supabase"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-brand-link hover:underline"
|
||||
className="text-brand hover:underline"
|
||||
>
|
||||
official Anthropic marketplace
|
||||
</a>
|
||||
@@ -53,7 +53,7 @@ function PluginInstructions({ client }: { client: PluginClient }) {
|
||||
href="https://developers.openai.com/codex/plugins#plugin-directory-in-the-codex-app"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-brand-link hover:underline"
|
||||
className="text-brand hover:underline"
|
||||
>
|
||||
Codex desktop app plugin directory
|
||||
</a>
|
||||
@@ -83,7 +83,7 @@ function PluginInstructions({ client }: { client: PluginClient }) {
|
||||
href="https://cursor.com/marketplace/supabase"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-brand-link hover:underline"
|
||||
className="text-brand hover:underline"
|
||||
>
|
||||
Supabase
|
||||
</a>{' '}
|
||||
@@ -118,7 +118,7 @@ function PluginInstructions({ client }: { client: PluginClient }) {
|
||||
href="https://geminicli.com/extensions/?name=supabase-communitysupabase-plugin"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-brand-link hover:underline"
|
||||
className="text-brand hover:underline"
|
||||
>
|
||||
Gemini CLI extensions directory
|
||||
</a>
|
||||
@@ -222,7 +222,7 @@ function PluginInstructions({ client }: { client: PluginClient }) {
|
||||
href="https://github.com/vercel-labs/open-plugin-spec"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-brand-link hover:underline"
|
||||
className="text-brand hover:underline"
|
||||
>
|
||||
Open Plugin
|
||||
</a>{' '}
|
||||
@@ -243,7 +243,7 @@ function PluginInstructions({ client }: { client: PluginClient }) {
|
||||
href="https://github.com/supabase-community/supabase-plugin"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-brand-link hover:underline"
|
||||
className="text-brand hover:underline"
|
||||
>
|
||||
GitHub repository
|
||||
</a>
|
||||
@@ -290,7 +290,7 @@ export function AgentPluginsPanel() {
|
||||
href={selectedClient.docsUrl}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-brand-link hover:underline inline-flex items-center"
|
||||
className="text-brand hover:underline inline-flex items-center"
|
||||
>
|
||||
{selectedClient.docsLinkText ?? `View ${selectedClient.label} extensions docs`}
|
||||
<ExternalLink className="h-3 w-3 ml-1" />
|
||||
@@ -302,7 +302,7 @@ export function AgentPluginsPanel() {
|
||||
href={selectedClient.repoUrl}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-brand-link hover:underline inline-flex items-center"
|
||||
className="text-brand hover:underline inline-flex items-center"
|
||||
>
|
||||
Give feedback
|
||||
<ExternalLink className="h-3 w-3 ml-1" />
|
||||
|
||||
@@ -23,7 +23,7 @@ function Logo() {
|
||||
height={18}
|
||||
alt="Supabase logo"
|
||||
/>
|
||||
<span className="font-mono text-sm font-medium text-brand-link mb-px">KB</span>
|
||||
<span className="font-mono text-sm font-medium text-brand mb-px">KB</span>
|
||||
</a>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -309,7 +309,9 @@ export const Grid = memo(
|
||||
<div
|
||||
className={cn(
|
||||
'flex flex-col items-center justify-center w-full h-full mt-9 transition',
|
||||
isTableEmpty && isDraggedOver && 'border-2 border-dashed border-brand'
|
||||
isTableEmpty &&
|
||||
isDraggedOver &&
|
||||
'border-2 border-dashed border-brand-default'
|
||||
)}
|
||||
>
|
||||
<p className="text-sm text-light pointer-events-auto">This table is empty</p>
|
||||
|
||||
@@ -190,7 +190,7 @@ export const ProviderForm = ({ config, provider, isActive }: ProviderFormProps)
|
||||
meta={
|
||||
isActive ? (
|
||||
<div className="flex items-center gap-1 rounded-full border border-brand-400 bg-brand-200 py-1 px-1 text-xs text-brand">
|
||||
<span className="rounded-full bg-brand p-0.5 text-xs text-brand-200">
|
||||
<span className="rounded-full bg-brand-default p-0.5 text-xs text-brand-200">
|
||||
<Check strokeWidth={2} size={12} />
|
||||
</span>
|
||||
<span className="px-1">Enabled</span>
|
||||
|
||||
@@ -117,7 +117,7 @@ export const HookCard = ({ hook, onSelectEdit, onSelectDelete }: HookCardProps)
|
||||
<div className="flex items-center gap-x-2">
|
||||
{hook.enabled ? (
|
||||
<Badge className="space-x-1" variant="success">
|
||||
<div className="h-3.5 w-3.5 bg-brand rounded-full flex justify-center items-center">
|
||||
<div className="h-3.5 w-3.5 bg-brand-default rounded-full flex justify-center items-center">
|
||||
<Check className="h-2 w-2 text-background-overlay " strokeWidth={6} />
|
||||
</div>
|
||||
<span>Enabled</span>
|
||||
|
||||
@@ -209,7 +209,7 @@ export const IntegrationCard = ({
|
||||
<div className="shrink-0">
|
||||
{true ? (
|
||||
<Badge className="space-x-1" variant="success">
|
||||
<div className="h-3.5 w-3.5 bg-brand rounded-full flex justify-center items-center">
|
||||
<div className="h-3.5 w-3.5 bg-brand-default rounded-full flex justify-center items-center">
|
||||
<Check className="h-2 w-2 text-background-overlay" strokeWidth={6} />
|
||||
</div>
|
||||
<span>Enabled</span>
|
||||
|
||||
@@ -274,7 +274,7 @@ export const UserOverview = ({ user, onDeleteSuccess }: UserOverviewProps) => {
|
||||
</div>
|
||||
{isActive ? (
|
||||
<div className="flex items-center gap-1 rounded-full border border-brand-400 bg-brand-200 py-1 px-1 text-xs text-brand">
|
||||
<span className="rounded-full bg-brand p-0.5 text-xs text-brand-200">
|
||||
<span className="rounded-full bg-brand-default p-0.5 text-xs text-brand-200">
|
||||
<Check strokeWidth={2} size={12} />
|
||||
</span>
|
||||
<span className="px-1">Enabled</span>
|
||||
|
||||
@@ -128,7 +128,11 @@ const BUILD_STATE_META: Record<ComputeInstanceBuildState, ComputeInstanceStateMe
|
||||
dotClassName: 'bg-warning',
|
||||
textClassName: 'text-foreground-light',
|
||||
},
|
||||
active: { label: 'Active', dotClassName: 'bg-brand', textClassName: 'text-foreground-light' },
|
||||
active: {
|
||||
label: 'Active',
|
||||
dotClassName: 'bg-brand-default',
|
||||
textClassName: 'text-foreground-light',
|
||||
},
|
||||
failed: {
|
||||
label: 'Failed',
|
||||
dotClassName: 'bg-destructive',
|
||||
|
||||
@@ -210,7 +210,7 @@ const ConnectOrganizationButton = ({
|
||||
'pointer-events-none shadow-none transition-colors',
|
||||
!disabled && !selected && 'group-hover:border-default group-hover:bg-surface-200',
|
||||
selected &&
|
||||
'border-brand bg-brand-200/20 dark:bg-brand-300 pr-10 group-hover:border-brand group-hover:bg-brand-200/20'
|
||||
'border-brand-default bg-brand-200/20 dark:bg-brand-300 pr-10 group-hover:border-brand-default group-hover:bg-brand-200/20'
|
||||
)}
|
||||
/>
|
||||
{selected && (
|
||||
|
||||
+1
-1
@@ -183,7 +183,7 @@ export const BigQueryFields = ({
|
||||
{isDraggingFile ? (
|
||||
<div
|
||||
aria-hidden="true"
|
||||
className="pointer-events-none absolute inset-0 rounded-md ring-2 ring-brand ring-offset-2 ring-offset-background"
|
||||
className="pointer-events-none absolute inset-0 rounded-md ring-2 ring-brand-default ring-offset-2 ring-offset-background"
|
||||
/>
|
||||
) : null}
|
||||
</div>
|
||||
|
||||
@@ -85,7 +85,7 @@ export const ReplicationNode = ({ id }: { id: string }) => {
|
||||
<div
|
||||
className={cn(
|
||||
'w-2 h-2 rounded-full',
|
||||
statusName === 'started' ? 'bg-brand' : 'bg-destructive'
|
||||
statusName === 'started' ? 'bg-brand-default' : 'bg-destructive'
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -166,7 +166,7 @@ export const RowMenu = ({
|
||||
/>
|
||||
{hasUpdate && (
|
||||
<span
|
||||
className="absolute -top-0.5 -right-0.5 h-2 w-2 bg-brand rounded-full"
|
||||
className="absolute -top-0.5 -right-0.5 h-2 w-2 bg-brand-default rounded-full"
|
||||
aria-hidden
|
||||
/>
|
||||
)}
|
||||
|
||||
@@ -140,8 +140,8 @@ export const RoleRow = ({ role, disabled = false, onSelectDelete }: RoleRowProps
|
||||
{role.activeConnections > 0 && (
|
||||
<div className="relative h-2 w-2">
|
||||
<span className="flex h-2 w-2">
|
||||
<span className="absolute inline-flex h-full w-full animate-ping rounded-full bg-brand opacity-75"></span>
|
||||
<span className="relative inline-flex h-2 w-2 rounded-full bg-brand opacity-75"></span>
|
||||
<span className="absolute inline-flex h-full w-full animate-ping rounded-full bg-brand-default opacity-75"></span>
|
||||
<span className="relative inline-flex h-2 w-2 rounded-full bg-brand-default opacity-75"></span>
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -52,7 +52,9 @@ const DefaultEdgeComponent = ({
|
||||
<BaseEdge
|
||||
id={id}
|
||||
path={edgePath}
|
||||
className={cn(selected ? 'stroke-brand!' : isDownloading ? 'stroke-black!' : undefined)}
|
||||
className={cn(
|
||||
selected ? 'stroke-brand-default!' : isDownloading ? 'stroke-black!' : undefined
|
||||
)}
|
||||
stroke="#000000"
|
||||
{...props}
|
||||
/>
|
||||
@@ -141,7 +143,7 @@ const EdgeRelationInfo = ({
|
||||
<Badge
|
||||
ref={checkIfShouldBeDisplayed}
|
||||
className={cn(
|
||||
'absolute pointer-events-auto z-50 p-1 rounded-[4px] gap-1 outline outline-1 outline-brand',
|
||||
'absolute pointer-events-auto z-50 p-1 rounded-[4px] gap-1 outline outline-1 outline-brand-default',
|
||||
show ? 'opacity-100' : 'opacity-0'
|
||||
)}
|
||||
style={{
|
||||
|
||||
@@ -72,7 +72,7 @@ const TableNodeComponent = ({
|
||||
<header
|
||||
className={cn(
|
||||
'text-[0.55rem] px-2 py-1 border-[0.5px] rounded-[4px] bg-alternative flex gap-1 items-center',
|
||||
hasEdgesSelected ? 'outline outline-1 outline-brand' : undefined
|
||||
hasEdgesSelected ? 'outline outline-1 outline-brand-default' : undefined
|
||||
)}
|
||||
>
|
||||
{data.name}
|
||||
@@ -89,7 +89,7 @@ const TableNodeComponent = ({
|
||||
<div
|
||||
className={cn(
|
||||
'border-[0.5px] overflow-hidden rounded-[4px] shadow-xs',
|
||||
hasEdgesSelected ? 'outline outline-1 outline-brand' : undefined
|
||||
hasEdgesSelected ? 'outline outline-1 outline-brand-default' : undefined
|
||||
)}
|
||||
style={{ width: TABLE_NODE_WIDTH / 2 }}
|
||||
>
|
||||
|
||||
@@ -16,7 +16,7 @@ const constraintTokenClassName = cn(
|
||||
export const ConstraintToken = ({ icon, label, variant = 'default' }: ConstraintTokenProps) => {
|
||||
const tokenToneClassName =
|
||||
variant === 'primary'
|
||||
? 'bg-brand/10 text-brand-600 border-brand-500'
|
||||
? 'bg-brand-default/10 text-brand-600 border-brand-500'
|
||||
: variant === 'default'
|
||||
? 'bg-surface-75 text-foreground-light border-strong'
|
||||
: 'bg-surface-75/50 text-foreground-light border-strong'
|
||||
|
||||
@@ -498,7 +498,7 @@ export const TableList = ({
|
||||
(table) => table.id === x.id
|
||||
) ? (
|
||||
<div className="flex items-center gap-x-2">
|
||||
<Check size={16} strokeWidth={2} className="text-brand-link" />
|
||||
<Check size={16} strokeWidth={2} className="text-brand" />
|
||||
<p className="text-foreground-light">Enabled</p>
|
||||
</div>
|
||||
) : (
|
||||
|
||||
+2
-2
@@ -139,8 +139,8 @@ export const DiskManagementReviewAndSubmitDialog = ({
|
||||
</div>
|
||||
|
||||
<div className="animate-badge-pulse absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 w-9 h-9 rounded-full bg-dash-sidebar border border-brand-500 flex items-center justify-center z-10 overflow-hidden">
|
||||
<span className="absolute inset-0 bg-brand/10 rounded-full" />
|
||||
<span className="animate-badge-shimmer pointer-events-none absolute inset-0 bg-linear-to-br from-transparent via-brand/20 to-transparent blur-md" />
|
||||
<span className="absolute inset-0 bg-brand-default/10 rounded-full" />
|
||||
<span className="animate-badge-shimmer pointer-events-none absolute inset-0 bg-linear-to-br from-transparent via-brand-default/20 to-transparent blur-md" />
|
||||
<ArrowRight size={16} className="text-brand-600 relative z-10" strokeWidth={2.5} />
|
||||
</div>
|
||||
|
||||
|
||||
@@ -101,7 +101,7 @@ export const DiskSpaceBar = ({ form }: DiskSpaceBarProps) => {
|
||||
<div
|
||||
className={cn(
|
||||
'h-[35px] relative border rounded-xs w-full transition overflow-visible',
|
||||
showNewSize ? 'bg-selection border border-brand' : 'bg-surface-300'
|
||||
showNewSize ? 'bg-selection border border-brand-default' : 'bg-surface-300'
|
||||
)}
|
||||
>
|
||||
<AnimatePresence>
|
||||
|
||||
@@ -98,7 +98,7 @@ export function ExplainHeader({ mode, onToggleMode, summary, id, rows }: Explain
|
||||
<span>Seq Scan (slow)</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-1.5">
|
||||
<span className="inline-block w-1.5 h-1.5 rounded-full bg-brand" />
|
||||
<span className="inline-block w-1.5 h-1.5 rounded-full bg-brand-default" />
|
||||
<span>Index Scan (fast)</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -154,7 +154,7 @@ export function getScanBarColor(operation: string): string {
|
||||
op.includes('index only scan') ||
|
||||
op.includes('bitmap index scan')
|
||||
) {
|
||||
return 'bg-brand/20'
|
||||
return 'bg-brand-default/20'
|
||||
}
|
||||
|
||||
// Sequential scans are yellow
|
||||
|
||||
@@ -90,7 +90,7 @@ export const EdgeFunctionRecentInvocations = ({
|
||||
<div
|
||||
className={cn(
|
||||
'flex items-center justify-center border px-1.5 py-0.5 rounded-sm text-xs font-mono',
|
||||
is2xx && 'text-brand border-brand bg-brand-300',
|
||||
is2xx && 'text-brand border-brand-default bg-brand-300',
|
||||
is4xx && 'text-warning border-warning bg-warning-300',
|
||||
is5xx && 'text-destructive border-destructive bg-destructive-300',
|
||||
!is2xx &&
|
||||
|
||||
+1
-1
@@ -26,7 +26,7 @@ export const ResourceGroupSection = ({
|
||||
) : (
|
||||
group.badge && (
|
||||
<Badge variant="success" className="gap-x-1.5">
|
||||
<span className="h-1.5 w-1.5 rounded-full bg-brand" />
|
||||
<span className="h-1.5 w-1.5 rounded-full bg-brand-default" />
|
||||
{group.badge}
|
||||
</Badge>
|
||||
)
|
||||
|
||||
@@ -92,8 +92,8 @@ export const IntegrationCard = ({
|
||||
</div>
|
||||
{isInstalled && (
|
||||
<div className="flex items-center gap-x-1">
|
||||
<BadgeCheck size={14} className="text-brand-link" />
|
||||
<span className="text-brand-link text-xs">Installed</span>
|
||||
<BadgeCheck size={14} className="text-brand" />
|
||||
<span className="text-brand text-xs">Installed</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -210,7 +210,7 @@ export const ActivityRow = ({
|
||||
>
|
||||
<TableCell className="relative w-[70px]">
|
||||
{selectedPid === activity.pid && (
|
||||
<div className="absolute h-full bg-brand top-0 left-0 w-1 bg-foreground-lighter" />
|
||||
<div className="absolute h-full bg-brand-default top-0 left-0 w-1" />
|
||||
)}
|
||||
|
||||
{/* Absolute (not inline in the flex row) so top-0/bottom-0 ignore the cell's padding and touch the adjacent row */}
|
||||
|
||||
@@ -47,7 +47,7 @@ const colorClassMap: Record<string, string> = {
|
||||
muted: 'bg-gray-500',
|
||||
destructive: 'bg-destructive',
|
||||
warning: 'bg-warning',
|
||||
brand: 'bg-brand',
|
||||
brand: 'bg-brand-default',
|
||||
}
|
||||
|
||||
const LEVEL_CHART_CONFIG: ChartConfig = {
|
||||
|
||||
+3
-3
@@ -169,12 +169,12 @@ function ControlCard({
|
||||
'px-4 py-4 flex flex-col items-start justify-between',
|
||||
'border rounded-md col-span-12 md:col-span-4 bg-surface-200',
|
||||
shouldHighlight &&
|
||||
'ring-4 ring-brand animate-[pulse_1.5s_ease-in-out_1] motion-reduce:animate-none shadow-md shadow-brand/40'
|
||||
'ring-4 ring-brand-default animate-[pulse_1.5s_ease-in-out_1] motion-reduce:animate-none shadow-md shadow-brand-default/40'
|
||||
)}
|
||||
>
|
||||
<div className="w-full">
|
||||
<div className="flex items-center space-x-2">
|
||||
<p className="text-brand-link text-sm uppercase">{plan.name}</p>
|
||||
<p className="text-brand text-sm uppercase">{plan.name}</p>
|
||||
{isCurrentPlan ? (
|
||||
<div className="text-xs bg-surface-300 text-foreground-light rounded-sm px-2 py-0.5">
|
||||
Current plan
|
||||
@@ -264,7 +264,7 @@ function ParityCard({
|
||||
'flex flex-col items-start justify-between',
|
||||
'border rounded-md col-span-12 md:col-span-4 bg-surface-200',
|
||||
shouldHighlight &&
|
||||
'ring-4 ring-brand animate-[pulse_1.5s_ease-in-out_1] motion-reduce:animate-none shadow-md shadow-brand/40'
|
||||
'ring-4 ring-brand-default animate-[pulse_1.5s_ease-in-out_1] motion-reduce:animate-none shadow-md shadow-brand-default/40'
|
||||
)}
|
||||
>
|
||||
<div className="w-full px-4 pt-4">
|
||||
|
||||
@@ -396,7 +396,7 @@ export function CustomReportSection() {
|
||||
</div>
|
||||
<div className="relative">
|
||||
{isDraggingOver && (
|
||||
<div className="absolute inset-0 rounded-sm bg-brand/10 pointer-events-none z-10" />
|
||||
<div className="absolute inset-0 rounded-sm bg-brand-default/10 pointer-events-none z-10" />
|
||||
)}
|
||||
{layout.length === 0 ? (
|
||||
<div
|
||||
|
||||
@@ -332,7 +332,7 @@ export const ServiceStatus = () => {
|
||||
(isProjectNew && service.status !== 'ACTIVE_HEALTHY')
|
||||
? 'bg-foreground-lighter animate-pulse'
|
||||
: service.status === 'ACTIVE_HEALTHY'
|
||||
? 'bg-brand'
|
||||
? 'bg-brand-default'
|
||||
: 'bg-selection'
|
||||
)}
|
||||
/>
|
||||
|
||||
@@ -139,7 +139,9 @@ export const UtilityActions = ({
|
||||
size={14}
|
||||
strokeWidth={2}
|
||||
className={
|
||||
isFavorite ? 'fill-brand stroke-none' : 'fill-none stroke-foreground-light'
|
||||
isFavorite
|
||||
? 'fill-brand-default stroke-none'
|
||||
: 'fill-none stroke-foreground-light'
|
||||
}
|
||||
/>
|
||||
{isFavorite ? 'Remove from' : 'Add to'} favorites
|
||||
@@ -198,7 +200,7 @@ export const UtilityActions = ({
|
||||
size="tiny"
|
||||
onClick={() => saveFavorite(id, false)}
|
||||
className="px-1"
|
||||
icon={<Heart className="fill-brand stroke-none" />}
|
||||
icon={<Heart className="fill-brand-default stroke-none" />}
|
||||
aria-label="Remove from favorites"
|
||||
/>
|
||||
) : (
|
||||
|
||||
+1
-1
@@ -46,7 +46,7 @@ export const CustomDomainDelete = ({ projectRef, customDomain }: CustomDomainDel
|
||||
<p className="text-xs text-foreground-light">Active custom domain:</p>
|
||||
<div className="flex items-center space-x-2">
|
||||
<code className="text-lg mx-0 flex items-center space-x-2">
|
||||
<div className="h-2 w-2 rounded-full bg-brand" />
|
||||
<div className="h-2 w-2 rounded-full bg-brand-default" />
|
||||
<span>
|
||||
<code className="text-code-inline">{customDomain.hostname}</code>
|
||||
</span>
|
||||
|
||||
+1
-1
@@ -311,7 +311,7 @@ export const ReplicaNode = ({ data }: NodeProps<Node<ReplicaNodeData>>) => {
|
||||
type="horizontal"
|
||||
value={stagePercent * 100}
|
||||
max={100}
|
||||
barClass="bg-brand"
|
||||
barClass="bg-brand-default"
|
||||
/>
|
||||
</div>
|
||||
</TooltipTrigger>
|
||||
|
||||
+2
-2
@@ -178,7 +178,7 @@ const MapView = () => {
|
||||
<circle
|
||||
r={4}
|
||||
className={`animate-ping ${
|
||||
hasNoDatabases ? 'fill-border-stronger' : 'fill-brand'
|
||||
hasNoDatabases ? 'fill-border-stronger' : 'fill-brand-default'
|
||||
}`}
|
||||
/>
|
||||
)}
|
||||
@@ -188,7 +188,7 @@ const MapView = () => {
|
||||
hasNoDatabases
|
||||
? 'fill-background-surface-300 stroke-border-stronger'
|
||||
: hasPrimary
|
||||
? 'fill-brand stroke-brand-500'
|
||||
? 'fill-brand-default stroke-brand-500'
|
||||
: 'fill-brand-500 stroke-brand-400'
|
||||
}`}
|
||||
/>
|
||||
|
||||
@@ -418,7 +418,7 @@ export const LogsDatePicker = ({
|
||||
size="tiny"
|
||||
onClick={handleCopy}
|
||||
className={cn({
|
||||
'text-brand-link': copied || pasted,
|
||||
'text-brand': copied || pasted,
|
||||
})}
|
||||
>
|
||||
{copied ? 'Copied!' : pasted ? 'Pasted!' : 'Copy range'}
|
||||
|
||||
@@ -196,7 +196,7 @@ export const PreviewFilterPanel = ({
|
||||
<div className="relative">
|
||||
{newCount > 0 && (
|
||||
<div className="absolute -top-3 -right-3 flex items-center justify-center">
|
||||
<div className="absolute h-4 w-4 animate-ping rounded-full bg-brand opacity-60"></div>
|
||||
<div className="absolute h-4 w-4 animate-ping rounded-full bg-brand-default opacity-60"></div>
|
||||
<div className="relative z-10 flex h-4 min-w-4 items-center justify-center rounded-full bg-brand-500 px-1 text-[10px] font-medium leading-none text-white">
|
||||
{newCount > 1000 ? `${Math.floor(newCount / 100) / 10}K` : newCount}
|
||||
</div>
|
||||
|
||||
@@ -122,7 +122,7 @@ const PolicyAllowedOperations = ({ allowedOperations = [], onToggleOperation = (
|
||||
className={cn(
|
||||
'text-xs font-mono leading-[1.1] px-2 py-1 rounded-full border font-normal whitespace-nowrap transition-colors duration-200',
|
||||
allowedClientLibraryMethods.includes(method)
|
||||
? 'bg-brand/10 text-brand-600 border-brand-500'
|
||||
? 'bg-brand-default/10 text-brand-600 border-brand-500'
|
||||
: 'bg-surface-75 text-foreground-lighter border-muted'
|
||||
)}
|
||||
>
|
||||
|
||||
@@ -59,7 +59,7 @@ function LinkSupportTicketSuccess() {
|
||||
<div className="flex flex-col items-center gap-y-4 py-8">
|
||||
<div className="relative">
|
||||
<Mail strokeWidth={1.5} size={60} className="text-brand" />
|
||||
<div className="h-6 w-6 rounded-full bg-brand absolute bottom-1 -right-1.5 flex items-center justify-center">
|
||||
<div className="h-6 w-6 rounded-full bg-brand-default absolute bottom-1 -right-1.5 flex items-center justify-center">
|
||||
<Check strokeWidth={4} size={16} className="text-contrast" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -157,7 +157,10 @@ function SupportFormHeader() {
|
||||
<Loader2 className="animate-spin" />
|
||||
) : (
|
||||
<div
|
||||
className={cn('h-2 w-2 rounded-full', isIncident ? 'bg-warning' : 'bg-brand')}
|
||||
className={cn(
|
||||
'h-2 w-2 rounded-full',
|
||||
isIncident ? 'bg-warning' : 'bg-brand-default'
|
||||
)}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -137,7 +137,12 @@ export function SupportFormStatusButton() {
|
||||
isLoading ? (
|
||||
<Loader2 className="animate-spin" />
|
||||
) : (
|
||||
<div className={cn('h-2 w-2 rounded-full', isIncident ? 'bg-warning' : 'bg-brand')} />
|
||||
<div
|
||||
className={cn(
|
||||
'h-2 w-2 rounded-full',
|
||||
isIncident ? 'bg-warning' : 'bg-brand-default'
|
||||
)}
|
||||
/>
|
||||
)
|
||||
}
|
||||
>
|
||||
|
||||
@@ -76,7 +76,7 @@ export const InsertButton = () => {
|
||||
<div
|
||||
className={cn([
|
||||
'border border-foreground-light w-[15px] h-[4px] translate-x-0.5',
|
||||
'transition duration-200 group-data-highlighted:border-brand group-data-highlighted:translate-x-0',
|
||||
'transition duration-200 group-data-highlighted:border-brand-default group-data-highlighted:translate-x-0',
|
||||
])}
|
||||
/>
|
||||
</div>
|
||||
@@ -97,7 +97,7 @@ export const InsertButton = () => {
|
||||
<div
|
||||
className={cn([
|
||||
'border border-foreground-light w-[4px] h-[15px] -translate-y-0.5',
|
||||
'transition duration-200 group-data-highlighted:border-brand group-data-highlighted:translate-y-0',
|
||||
'transition duration-200 group-data-highlighted:border-brand-default group-data-highlighted:translate-y-0',
|
||||
])}
|
||||
/>
|
||||
</div>
|
||||
|
||||
+3
-3
@@ -76,7 +76,7 @@ export const AddRowOperationItem = ({
|
||||
/>
|
||||
</CardHeader>
|
||||
|
||||
<CardContent className="py-2 px-3 font-mono text-xs text-brand-link">
|
||||
<CardContent className="py-2 px-3 font-mono text-xs text-brand">
|
||||
{previewColumns.length === 0 && (
|
||||
<span className="text-foreground-light">
|
||||
No data provided, default values will be used
|
||||
@@ -84,7 +84,7 @@ export const AddRowOperationItem = ({
|
||||
)}
|
||||
{previewColumns.map(([key, value]) => (
|
||||
<div key={key} className="flex gap-2 py-0.5">
|
||||
<span className="text-brand-link select-none font-medium">+</span>
|
||||
<span className="text-brand select-none font-medium">+</span>
|
||||
<span className="shrink-0">{key}:</span>
|
||||
<span className="truncate min-w-0" title={formatOperationItemValue(value)}>
|
||||
{formatOperationItemValue(value)}
|
||||
@@ -93,7 +93,7 @@ export const AddRowOperationItem = ({
|
||||
))}
|
||||
{remainingCount > 0 && (
|
||||
<div className="flex gap-2 py-0.5">
|
||||
<span className="text-brand-link select-none font-medium">+</span>
|
||||
<span className="text-brand select-none font-medium">+</span>
|
||||
<span>+{remainingCount} more column(s)</span>
|
||||
</div>
|
||||
)}
|
||||
|
||||
+2
-2
@@ -82,8 +82,8 @@ export const OperationItem = ({ operationId, tableId, content }: OperationItemPr
|
||||
</div>
|
||||
|
||||
<div className="flex gap-2 py-0.5">
|
||||
<span className="text-brand-link select-none font-medium">+</span>
|
||||
<span className="text-brand-link truncate max-w-full" title={formattedNewValue}>
|
||||
<span className="text-brand select-none font-medium">+</span>
|
||||
<span className="text-brand truncate max-w-full" title={formattedNewValue}>
|
||||
{formattedNewValue}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
+2
-2
@@ -592,7 +592,7 @@ export const createTable = async ({
|
||||
value={progress}
|
||||
max={100}
|
||||
type="horizontal"
|
||||
barClass="bg-brand"
|
||||
barClass="bg-brand-default"
|
||||
labelBottom={`Adding ${importContent.rowCount.toLocaleString()} rows to ${table.name}`}
|
||||
labelBottomClass=""
|
||||
labelTop={`${progress.toFixed(2)}%`}
|
||||
@@ -629,7 +629,7 @@ export const createTable = async ({
|
||||
value={progress}
|
||||
max={100}
|
||||
type="horizontal"
|
||||
barClass="bg-brand"
|
||||
barClass="bg-brand-default"
|
||||
labelBottom={`Adding ${importContent.rows.length.toLocaleString()} rows to ${table.name}`}
|
||||
labelTop={`${progress.toFixed(2)}%`}
|
||||
labelTopClass="tabular-nums"
|
||||
|
||||
@@ -84,7 +84,7 @@ describe('AdvisorButton', () => {
|
||||
|
||||
expect(container.querySelector('.bg-warning')).toBeInTheDocument()
|
||||
expect(container.querySelector('.bg-destructive')).not.toBeInTheDocument()
|
||||
expect(container.querySelector('.bg-brand')).not.toBeInTheDocument()
|
||||
expect(container.querySelector('.bg-brand-default')).not.toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('keeps the destructive dot when a critical issue is present', () => {
|
||||
@@ -151,7 +151,7 @@ describe('AdvisorButton', () => {
|
||||
|
||||
const { container } = render(<AdvisorButton projectRef="project-ref" />)
|
||||
|
||||
expect(container.querySelector('.bg-brand')).toBeInTheDocument()
|
||||
expect(container.querySelector('.bg-brand-default')).toBeInTheDocument()
|
||||
expect(container.querySelector('.bg-warning')).not.toBeInTheDocument()
|
||||
expect(container.querySelector('.bg-destructive')).not.toBeInTheDocument()
|
||||
expect(screen.getByRole('button')).toBeInTheDocument()
|
||||
|
||||
@@ -86,7 +86,7 @@ export const AdvisorButton = ({ projectRef }: { projectRef?: string }) => {
|
||||
) : hasWarningIssues ? (
|
||||
<span className="absolute top-1.5 right-1.5 w-1.5 h-1.5 rounded-full bg-warning" />
|
||||
) : hasUnreadNotifications ? (
|
||||
<span className="absolute top-1.5 right-1.5 w-1.5 h-1.5 rounded-full bg-brand" />
|
||||
<span className="absolute top-1.5 right-1.5 w-1.5 h-1.5 rounded-full bg-brand-default" />
|
||||
) : null}
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -73,7 +73,7 @@ export const MergeRequestButton = () => {
|
||||
icon={
|
||||
<div className="relative">
|
||||
{hasReviewRequested && (
|
||||
<span className="w-1 h-1 absolute top-0 right-0 rounded-full bg-brand" />
|
||||
<span className="w-1 h-1 absolute top-0 right-0 rounded-full bg-brand-default" />
|
||||
)}
|
||||
<GitMerge size={16} strokeWidth={1.5} />
|
||||
</div>
|
||||
|
||||
+3
-1
@@ -428,7 +428,9 @@ export const SQLEditorTreeViewItem = ({
|
||||
<Heart
|
||||
size={14}
|
||||
className={cn(
|
||||
isFavorite ? 'fill-brand stroke-none' : 'fill-none stroke-foreground-light'
|
||||
isFavorite
|
||||
? 'fill-brand-default stroke-none'
|
||||
: 'fill-none stroke-foreground-light'
|
||||
)}
|
||||
/>
|
||||
{isFavorite ? 'Remove from' : 'Add to'} favorites
|
||||
|
||||
@@ -35,9 +35,9 @@ export const BannerFreeMicroUpgrade = () => {
|
||||
<ComputeBadge
|
||||
infraComputeSize="nano"
|
||||
icon={<ChevronsUpAnimated />}
|
||||
className="text-brand-600 border-brand-500 bg-brand/10 gap-1"
|
||||
className="text-brand-600 border-brand-500 bg-brand-default/10 gap-1"
|
||||
/>
|
||||
<span className="animate-badge-shimmer pointer-events-none absolute inset-0 bg-linear-to-br from-transparent via-brand/20 to-transparent blur-md" />
|
||||
<span className="animate-badge-shimmer pointer-events-none absolute inset-0 bg-linear-to-br from-transparent via-brand-default/20 to-transparent blur-md" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -49,8 +49,8 @@ export const BannerTableEditorQueueOperations = () => {
|
||||
</div>
|
||||
|
||||
<div className="flex gap-2 py-0.5">
|
||||
<span className="text-brand-link select-none font-medium">+</span>
|
||||
<span className="text-brand-link truncate max-w-full">Blue</span>
|
||||
<span className="text-brand select-none font-medium">+</span>
|
||||
<span className="text-brand truncate max-w-full">Blue</span>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
@@ -115,12 +115,12 @@ export const ComputeBadgeWrapper = ({
|
||||
infraComputeSize={computeSize}
|
||||
icon={showUpgradeGlow && <ChevronsUpAnimated />}
|
||||
className={cn(
|
||||
showUpgradeGlow && 'text-brand-600 border-brand-500 bg-brand/10 gap-1',
|
||||
showUpgradeGlow && 'text-brand-600 border-brand-500 bg-brand-default/10 gap-1',
|
||||
badgeClassName
|
||||
)}
|
||||
/>
|
||||
{showUpgradeGlow && (
|
||||
<span className="animate-badge-shimmer pointer-events-none absolute inset-0 bg-linear-to-br from-transparent via-brand/20 to-transparent blur-md" />
|
||||
<span className="animate-badge-shimmer pointer-events-none absolute inset-0 bg-linear-to-br from-transparent via-brand-default/20 to-transparent blur-md" />
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -12,7 +12,7 @@ export const DotPing = ({ animate = true, variant = 'primary' }: DotPingProps) =
|
||||
className={cn(
|
||||
'absolute inset-0 rounded-full',
|
||||
animate && 'animate-ping',
|
||||
variant === 'primary' && 'bg-brand/20',
|
||||
variant === 'primary' && 'bg-brand-default/20',
|
||||
variant === 'default' && 'bg-selection/20',
|
||||
variant === 'warning' && 'bg-warning/20'
|
||||
)}
|
||||
@@ -24,7 +24,7 @@ export const DotPing = ({ animate = true, variant = 'primary' }: DotPingProps) =
|
||||
<span
|
||||
className={cn(
|
||||
'absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 inline-block w-2 h-2 rounded-full',
|
||||
variant === 'primary' && 'bg-brand',
|
||||
variant === 'primary' && 'bg-brand-default',
|
||||
variant === 'default' && 'bg-selection',
|
||||
variant === 'warning' && 'bg-warning'
|
||||
)}
|
||||
|
||||
@@ -95,7 +95,7 @@ export const DatabaseConnections: NextPageWithLayout = () => {
|
||||
<Tooltip>
|
||||
<TooltipTrigger className="flex items-center">
|
||||
<Badge variant="success">
|
||||
<span className="h-1.5 w-1.5 bg-brand rounded-full animate-pulse" />
|
||||
<span className="h-1.5 w-1.5 bg-brand-default rounded-full animate-pulse" />
|
||||
<span>Live</span>
|
||||
</Badge>
|
||||
</TooltipTrigger>
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
|
||||
.rdg-cell {
|
||||
border-left-color: hsl(var(--brand-default));
|
||||
color: hsl(var(--brand-link));
|
||||
color: var(--primary);
|
||||
}
|
||||
|
||||
/* First cell gets a stronger left border to indicate new row */
|
||||
@@ -329,7 +329,7 @@
|
||||
}
|
||||
|
||||
.sb-grid-column-header__inner svg {
|
||||
@apply border-brand text-brand;
|
||||
@apply border-brand-default text-brand;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
|
||||
.rdg-row {
|
||||
&.rdg-row--focused {
|
||||
@apply border-r border-brand;
|
||||
@apply border-r border-brand-default;
|
||||
border-right-width: 4px;
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@
|
||||
|
||||
.rdg-row {
|
||||
&.rdg-row--focused {
|
||||
@apply border-r border-brand;
|
||||
@apply border-r border-brand-default;
|
||||
border-right-width: 4px;
|
||||
}
|
||||
|
||||
|
||||
@@ -303,7 +303,7 @@
|
||||
|
||||
::-moz-selection {
|
||||
/* Code for Firefox */
|
||||
@apply bg-brand;
|
||||
@apply bg-brand-default;
|
||||
color: #333 !important;
|
||||
}
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ const page: GoPageInput = {
|
||||
<div className="flex flex-wrap gap-4 justify-center mt-6">
|
||||
<a
|
||||
href="https://supabase.com/dashboard"
|
||||
className="inline-flex items-center justify-center rounded-md bg-brand text-white px-5 py-2.5 text-sm font-medium hover:bg-brand/90 transition-colors"
|
||||
className="inline-flex items-center justify-center rounded-md bg-brand-default text-white px-5 py-2.5 text-sm font-medium hover:bg-brand-default/90 transition-colors"
|
||||
>
|
||||
Start building with Supabase
|
||||
</a>
|
||||
|
||||
@@ -138,7 +138,7 @@ const page: GoPageInput = {
|
||||
className="group flex h-full flex-col gap-3 rounded-lg border border-muted bg-surface-100 p-5 text-left transition-colors hover:border-brand-600 hover:bg-surface-200"
|
||||
>
|
||||
<span className="text-sm text-foreground-lighter">Blog</span>
|
||||
<span className="text-lg font-medium text-foreground group-hover:text-brand-link">
|
||||
<span className="text-lg font-medium text-foreground group-hover:text-brand">
|
||||
Introducing Supabase Pipelines
|
||||
</span>
|
||||
<span className="text-sm leading-relaxed text-foreground-light">
|
||||
@@ -151,7 +151,7 @@ const page: GoPageInput = {
|
||||
className="group flex h-full flex-col gap-3 rounded-lg border border-muted bg-surface-100 p-5 text-left transition-colors hover:border-brand-600 hover:bg-surface-200"
|
||||
>
|
||||
<span className="text-sm text-foreground-lighter">Docs</span>
|
||||
<span className="text-lg font-medium text-foreground group-hover:text-brand-link">
|
||||
<span className="text-lg font-medium text-foreground group-hover:text-brand">
|
||||
Set up Pipelines
|
||||
</span>
|
||||
<span className="text-sm leading-relaxed text-foreground-light">
|
||||
@@ -164,7 +164,7 @@ const page: GoPageInput = {
|
||||
className="group flex h-full flex-col gap-3 rounded-lg border border-muted bg-surface-100 p-5 text-left transition-colors hover:border-brand-600 hover:bg-surface-200"
|
||||
>
|
||||
<span className="text-sm text-foreground-lighter">Guide</span>
|
||||
<span className="text-lg font-medium text-foreground group-hover:text-brand-link">
|
||||
<span className="text-lg font-medium text-foreground group-hover:text-brand">
|
||||
Realtime or Pipelines?
|
||||
</span>
|
||||
<span className="text-sm leading-relaxed text-foreground-light">
|
||||
|
||||
@@ -24,7 +24,7 @@ export function QuoteSection({ quote, highlight, author }: QuoteSectionProps) {
|
||||
{highlight && (
|
||||
<>
|
||||
{' '}
|
||||
<span className="text-brand-link">{highlight}</span>
|
||||
<span className="text-brand">{highlight}</span>
|
||||
</>
|
||||
)}
|
||||
</p>
|
||||
|
||||
@@ -193,7 +193,7 @@ function IntegratedSkeleton() {
|
||||
<div className="rounded-xl border border-border bg-surface-100 p-4">
|
||||
<div className="flex flex-col gap-3">
|
||||
<div className="flex items-center gap-2.5">
|
||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-brand/15 text-[10px] font-medium text-brand">
|
||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-brand-default/15 text-[10px] font-medium text-brand">
|
||||
CW
|
||||
</div>
|
||||
<div className="flex flex-col">
|
||||
@@ -244,7 +244,7 @@ function IntegratedSkeleton() {
|
||||
{/* Verify email card */}
|
||||
<div className="rounded-xl border border-border bg-surface-100 p-4">
|
||||
<div className="flex flex-col items-center gap-2.5">
|
||||
<div className="flex h-8 w-8 items-center justify-center rounded-full bg-brand/10">
|
||||
<div className="flex h-8 w-8 items-center justify-center rounded-full bg-brand-default/10">
|
||||
<svg
|
||||
width="14"
|
||||
height="14"
|
||||
@@ -395,7 +395,7 @@ function IntegratedSkeleton() {
|
||||
<span className="text-[10px] text-foreground">Authenticator app</span>
|
||||
<span className="text-[9px] text-foreground-muted">TOTP via auth app</span>
|
||||
</div>
|
||||
<div className="rounded bg-brand/15 px-1.5 py-0.5 text-[8px] font-medium text-brand">
|
||||
<div className="rounded bg-brand-default/15 px-1.5 py-0.5 text-[8px] font-medium text-brand">
|
||||
On
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -478,7 +478,9 @@ function RealtimeSkeleton() {
|
||||
key={msg.id}
|
||||
className={cn(
|
||||
'transition-colors duration-500',
|
||||
tableFlashId === msg.id ? 'bg-brand/15 dark:bg-brand/5' : 'bg-surface-75'
|
||||
tableFlashId === msg.id
|
||||
? 'bg-brand-default/15 dark:bg-brand-default/5'
|
||||
: 'bg-surface-75'
|
||||
)}
|
||||
>
|
||||
<td className="border-b border-r border-default px-3 py-1.5 text-foreground-muted text-xs truncate max-w-0">
|
||||
@@ -546,9 +548,9 @@ function RealtimeSkeleton() {
|
||||
className={cn(
|
||||
'max-w-[75%] px-3 py-1.5 rounded-xl text-xs leading-snug transition-colors duration-500',
|
||||
isAlice
|
||||
? 'bg-brand/15 text-foreground rounded-br-sm'
|
||||
? 'bg-brand-default/15 text-foreground rounded-br-sm'
|
||||
: 'bg-surface-300 text-foreground rounded-bl-sm',
|
||||
chatFlashId === msg.id && 'ring-1 ring-brand/30'
|
||||
chatFlashId === msg.id && 'ring-1 ring-brand-default/30'
|
||||
)}
|
||||
>
|
||||
{msg.text}
|
||||
|
||||
+1
-1
@@ -140,7 +140,7 @@ export function SpreadsheetIllustration() {
|
||||
<td
|
||||
key={col.name}
|
||||
className={`border-b border-r last:border-r-0 border-secondary px-3 py-1.5 max-w-[200px] ${
|
||||
isEdited ? 'bg-brand/10' : ''
|
||||
isEdited ? 'bg-brand-default/10' : ''
|
||||
}`}
|
||||
>
|
||||
<span
|
||||
|
||||
@@ -177,7 +177,9 @@ function DatabaseChangesSkeleton() {
|
||||
key={msg.id}
|
||||
className={cn(
|
||||
'transition-colors duration-500',
|
||||
tableFlashId === msg.id ? 'bg-brand/15 dark:bg-brand/5' : 'bg-surface-75'
|
||||
tableFlashId === msg.id
|
||||
? 'bg-brand-default/15 dark:bg-brand-default/5'
|
||||
: 'bg-surface-75'
|
||||
)}
|
||||
>
|
||||
<td className="border-b border-r border-default px-3 py-1.5 text-foreground-muted text-xs truncate max-w-0">
|
||||
@@ -245,9 +247,9 @@ function DatabaseChangesSkeleton() {
|
||||
className={cn(
|
||||
'max-w-[75%] px-3 py-1.5 rounded-xl text-xs leading-snug transition-colors duration-500',
|
||||
isAlice
|
||||
? 'bg-brand/15 text-foreground rounded-br-sm'
|
||||
? 'bg-brand-default/15 text-foreground rounded-br-sm'
|
||||
: 'bg-surface-300 text-foreground rounded-bl-sm',
|
||||
chatFlashId === msg.id && 'ring-1 ring-brand/30'
|
||||
chatFlashId === msg.id && 'ring-1 ring-brand-default/30'
|
||||
)}
|
||||
>
|
||||
{msg.text}
|
||||
@@ -626,7 +628,7 @@ function BroadcastSkeleton() {
|
||||
key={i}
|
||||
className={cn(
|
||||
'absolute bottom-6 z-10 flex h-10 w-10 -translate-x-1/2 items-center justify-center rounded-xl border bg-surface-100 shadow-xs dark:shadow-sm transition-all duration-300',
|
||||
isFlashing ? 'border-brand text-brand' : 'border-border text-foreground-muted'
|
||||
isFlashing ? 'border-brand-default text-brand' : 'border-border text-foreground-muted'
|
||||
)}
|
||||
style={{ left: `${xPercent}%` }}
|
||||
>
|
||||
|
||||
@@ -38,7 +38,7 @@ function InteroperableSkeleton() {
|
||||
{[0, 1].map((i) => (
|
||||
<div
|
||||
key={`left-conn-${i}`}
|
||||
className="relative h-[1.5px] w-full overflow-hidden bg-brand/18 [mask-image:linear-gradient(to_right,transparent,black_20%,black_80%,transparent)] [webkit-mask-image:linear-gradient(to_right,transparent,black_20%,black_80%,transparent)]"
|
||||
className="relative h-[1.5px] w-full overflow-hidden bg-brand-default/18 [mask-image:linear-gradient(to_right,transparent,black_20%,black_80%,transparent)] [webkit-mask-image:linear-gradient(to_right,transparent,black_20%,black_80%,transparent)]"
|
||||
>
|
||||
<div
|
||||
className="absolute inset-y-0 left-0 w-24 [animation:interopLineSweep_1.05s_linear_infinite]"
|
||||
@@ -55,7 +55,7 @@ function InteroperableSkeleton() {
|
||||
{[0, 1].map((i) => (
|
||||
<div
|
||||
key={`right-conn-${i}`}
|
||||
className="relative h-[1.5px] w-full overflow-hidden bg-brand/18 [mask-image:linear-gradient(to_right,transparent,black_20%,black_80%,transparent)] [webkit-mask-image:linear-gradient(to_right,transparent,black_20%,black_80%,transparent)]"
|
||||
className="relative h-[1.5px] w-full overflow-hidden bg-brand-default/18 [mask-image:linear-gradient(to_right,transparent,black_20%,black_80%,transparent)] [webkit-mask-image:linear-gradient(to_right,transparent,black_20%,black_80%,transparent)]"
|
||||
>
|
||||
<div
|
||||
className="absolute inset-y-0 left-0 w-24 [animation:interopLineSweep_1.05s_linear_infinite]"
|
||||
@@ -153,7 +153,7 @@ function CDNSkeleton() {
|
||||
{[-20, -10, 0, 10, 20].map((offset, i) => (
|
||||
<div
|
||||
key={`flash-${offset}`}
|
||||
className="relative h-px w-full overflow-hidden bg-brand/15 [mask-image:linear-gradient(to_right,transparent,black_20%,black_80%,transparent)] [webkit-mask-image:linear-gradient(to_right,transparent,black_20%,black_80%,transparent)]"
|
||||
className="relative h-px w-full overflow-hidden bg-brand-default/15 [mask-image:linear-gradient(to_right,transparent,black_20%,black_80%,transparent)] [webkit-mask-image:linear-gradient(to_right,transparent,black_20%,black_80%,transparent)]"
|
||||
style={{ transform: `translateY(${offset}px)` }}
|
||||
>
|
||||
<div
|
||||
@@ -177,7 +177,7 @@ function CDNSkeleton() {
|
||||
|
||||
<div className="relative flex h-[116px] w-[116px] items-center justify-center rounded-[24px] border border-foreground/15 bg-surface-200/95 shadow-[0_8px_28px_hsl(var(--background-default)/0.24)]">
|
||||
<div className="absolute inset-0 rounded-[24px] shadow-[inset_0_1px_0_hsl(var(--foreground-default)/0.06)]" />
|
||||
<div className="absolute size-10 rounded-full bg-brand/15 blur-xl" />
|
||||
<div className="absolute size-10 rounded-full bg-brand-default/15 blur-xl" />
|
||||
<svg
|
||||
width="48"
|
||||
height="48"
|
||||
|
||||
@@ -361,7 +361,7 @@ function PartnerDetails({
|
||||
<span className="text-lighter">Category</span>
|
||||
<Link
|
||||
href={`/partners/catalog?cat=${encodeURIComponent(category.slug)}`}
|
||||
className="text-brand-link hover:underline transition-colors"
|
||||
className="text-brand hover:underline transition-colors"
|
||||
>
|
||||
{category.name}
|
||||
</Link>
|
||||
@@ -379,7 +379,7 @@ function PartnerDetails({
|
||||
}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
className="text-brand-link hover:underline transition-colors"
|
||||
className="text-brand hover:underline transition-colors"
|
||||
>
|
||||
{(() => {
|
||||
try {
|
||||
@@ -402,7 +402,7 @@ function PartnerDetails({
|
||||
href={activeListing.docsUrl}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
className="text-brand-link hover:underline transition-colors"
|
||||
className="text-brand hover:underline transition-colors"
|
||||
>
|
||||
<span className="flex items-center space-x-1">
|
||||
<span>Learn</span>
|
||||
|
||||
@@ -97,9 +97,8 @@ function FloatingTableOfContents({
|
||||
href={`#chapter-${chapterIndex + 1}`}
|
||||
onClick={() => setIsTocOpen(false)}
|
||||
className={cn(
|
||||
'block px-6 py-2 text-xs transition-colors font-mono uppercase tracking-wider text-center text-foreground-light hover:text-brand-link hover:bg-brand-300/25',
|
||||
chapterIndex + 1 === activeChapter &&
|
||||
'bg-brand-300/40 text-brand-link dark:text-brand'
|
||||
'block px-6 py-2 text-xs transition-colors font-mono uppercase tracking-wider text-center text-foreground-light hover:text-brand hover:bg-brand-300/25',
|
||||
chapterIndex + 1 === activeChapter && 'bg-brand-300/40 text-brand'
|
||||
)}
|
||||
>
|
||||
{chapter.shortTitle}
|
||||
@@ -227,7 +226,7 @@ export default function StateOfStartups2026Content() {
|
||||
<li key={chapterIndex + 1}>
|
||||
<Link
|
||||
href={`#chapter-${chapterIndex + 1}`}
|
||||
className="group flex flex-row gap-5 py-3 pl-7 pr-8 font-mono uppercase tracking-wide text-sm transition-all text-foreground-light hover:text-brand-link hover:bg-brand-300/25"
|
||||
className="group flex flex-row gap-5 py-3 pl-7 pr-8 font-mono uppercase tracking-wide text-sm transition-all text-foreground-light hover:text-brand hover:bg-brand-300/25"
|
||||
>
|
||||
<span className="text-xs rounded-full bg-surface-75 border border-surface-200 group-hover:border-brand-500/40 w-5 h-5 flex items-center justify-center group-hover:bg-brand-600/5">
|
||||
{chapterIndex + 1}
|
||||
|
||||
@@ -29,7 +29,7 @@ export function CohortToggle({ eyebrow, options, value, onValueChange }: CohortT
|
||||
onClick={() => onValueChange(option.label)}
|
||||
className={`px-3 py-1 text-xs font-mono uppercase tracking-wider border rounded-full transition-colors ${
|
||||
isActive
|
||||
? 'border-brand-500/40 bg-brand-300/40 text-brand-link dark:text-brand'
|
||||
? 'border-brand-500/40 bg-brand-300/40 text-brand'
|
||||
: 'border-overlay text-foreground-light hover:text-foreground hover:bg-surface-100'
|
||||
}`}
|
||||
>
|
||||
|
||||
@@ -11,7 +11,7 @@ interface ProgressBarProps {
|
||||
export function ProgressBar({
|
||||
className = 'h-4',
|
||||
backgroundClassName = 'bg-foreground-muted/80',
|
||||
foregroundClassName = 'bg-brand',
|
||||
foregroundClassName = 'bg-brand-default',
|
||||
animationDelay,
|
||||
reverse = false,
|
||||
}: ProgressBarProps) {
|
||||
@@ -62,7 +62,7 @@ const PROGRESS_BARS = [
|
||||
{
|
||||
height: 'h-8',
|
||||
bgColor: 'bg-foreground-muted/50',
|
||||
fgColor: 'bg-brand',
|
||||
fgColor: 'bg-brand-default',
|
||||
animationDelay: '0.3s',
|
||||
},
|
||||
{
|
||||
|
||||
@@ -68,7 +68,7 @@ export function ParticipantsCarousel({ participants }: { participants: Participa
|
||||
href={participant.url}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-xs md:text-sm font-mono tracking-widest uppercase text-foreground-lighter hover:text-brand-link transition-colors whitespace-nowrap"
|
||||
className="text-xs md:text-sm font-mono tracking-widest uppercase text-foreground-lighter hover:text-brand transition-colors whitespace-nowrap"
|
||||
>
|
||||
{participant.company}
|
||||
</Link>
|
||||
|
||||
@@ -13,15 +13,13 @@ export function SectionCallout({ eyebrow, body, href, cta, external }: SectionCa
|
||||
return (
|
||||
<div className="border-t border-muted px-8 py-8">
|
||||
<div className="bg-surface-100/60 border border-muted rounded-lg p-6 flex flex-col gap-3">
|
||||
<span className="text-brand-link dark:text-brand text-xs font-mono uppercase tracking-widest">
|
||||
{eyebrow}
|
||||
</span>
|
||||
<span className="text-brand text-xs font-mono uppercase tracking-widest">{eyebrow}</span>
|
||||
<p className="text-foreground-light text-balance">{body}</p>
|
||||
<Link
|
||||
href={href}
|
||||
target={external ? '_blank' : undefined}
|
||||
rel={external ? 'noopener noreferrer' : undefined}
|
||||
className="inline-flex items-center gap-1 text-brand-link dark:text-brand text-sm font-medium hover:underline w-fit"
|
||||
className="inline-flex items-center gap-1 text-brand text-sm font-medium hover:underline w-fit"
|
||||
>
|
||||
{cta}
|
||||
<ArrowUpRight size={14} strokeWidth={2} />
|
||||
|
||||
@@ -74,7 +74,7 @@ export function SurveyChannelMixChart({
|
||||
}}
|
||||
/>
|
||||
<div
|
||||
className={`h-full relative ${cohorts[ci].tone === 'accent' ? 'bg-brand' : 'bg-foreground-light'}`}
|
||||
className={`h-full relative ${cohorts[ci].tone === 'accent' ? 'bg-brand-default' : 'bg-foreground-light'}`}
|
||||
style={{ width: `${v ?? 0}%` }}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -56,9 +56,7 @@ export function SurveyChapter({
|
||||
{/* Text content */}
|
||||
<div className="max-w-240 mx-auto grid gap-y-4 sm:gap-y-8 grid-cols-1 md:grid-cols-3 text-balance pb-12">
|
||||
<div className="md:col-span-2 flex flex-col gap-4 px-8">
|
||||
<p
|
||||
className={`text-sm uppercase font-mono text-balance tracking-wider text-brand-link`}
|
||||
>
|
||||
<p className={`text-sm uppercase font-mono text-balance tracking-wider text-brand`}>
|
||||
{shortTitle}
|
||||
</p>
|
||||
<h2 className="text-4xl md:text-5xl xl:text-6xl text-balance leading-tight tracking-tight">
|
||||
|
||||
@@ -49,7 +49,7 @@ export function SurveyChapterSection({ section }: { section: SurveySection }) {
|
||||
return { [cohortToggle.key]: option.filter }
|
||||
}, [cohortToggle, cohortLabel])
|
||||
|
||||
const eyebrowColor = 'text-brand-link dark:text-brand'
|
||||
const eyebrowColor = 'text-brand'
|
||||
|
||||
// A section can be compared across years only if it has any 2025 data. New-in-
|
||||
// 2026 questions (share of codebase, auth, agents, MCP, the AI-codebase
|
||||
|
||||
@@ -25,8 +25,8 @@ interface SurveyChartProps {
|
||||
maxBars?: number
|
||||
}
|
||||
|
||||
const accentBarFg = 'bg-brand'
|
||||
const accentBarText = 'text-brand-link dark:text-brand'
|
||||
const accentBarFg = 'bg-brand-default'
|
||||
const accentBarText = 'text-brand'
|
||||
|
||||
export function SurveyChart({
|
||||
title,
|
||||
|
||||
@@ -63,7 +63,7 @@ export function ChartLegend({
|
||||
<div key={item.label} className="flex items-center gap-2">
|
||||
<span
|
||||
className={`inline-block ${item.variant === 'line' ? 'w-4 h-[3px]' : 'w-3 h-3'} ${
|
||||
item.tone === 'accent' ? 'bg-brand' : 'bg-foreground-light'
|
||||
item.tone === 'accent' ? 'bg-brand-default' : 'bg-foreground-light'
|
||||
}`}
|
||||
/>
|
||||
<span className="text-foreground-light text-xs font-mono uppercase tracking-widest">
|
||||
|
||||
@@ -120,7 +120,7 @@ export function SurveyPullQuoteCarousel({ quotes }: { quotes: CarouselPullQuote[
|
||||
}}
|
||||
>
|
||||
<div
|
||||
className="absolute inset-0 pointer-events-none bg-brand"
|
||||
className="absolute inset-0 pointer-events-none bg-brand-default"
|
||||
style={{
|
||||
maskImage: 'url("/images/state-of-startups/pattern-checker.svg")',
|
||||
maskSize: '4px',
|
||||
|
||||
@@ -24,7 +24,7 @@ export function SurveyPullQuoteGrid({ quotes }: { quotes: PullQuoteGridItem[] })
|
||||
{quotes.map((q, i) => (
|
||||
<div key={i} className="flex flex-col gap-4 px-8 py-12">
|
||||
{q.theme && (
|
||||
<span className="text-brand-link dark:text-brand text-xs font-mono uppercase tracking-widest">
|
||||
<span className="text-brand text-xs font-mono uppercase tracking-widest">
|
||||
{q.theme}
|
||||
</span>
|
||||
)}
|
||||
|
||||
@@ -9,7 +9,7 @@ export function SurveyRankedAnswersPair({
|
||||
}) {
|
||||
const accent = useAccent()
|
||||
|
||||
const accentBlocks = ['bg-brand', 'bg-brand-500', 'bg-brand-300']
|
||||
const accentBlocks = ['bg-brand-default', 'bg-brand-500', 'bg-brand-300']
|
||||
|
||||
const accentRankText = 'text-brand'
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ export function SurveyStatCard({ label, query, value, cohortFilter }: SurveyStat
|
||||
const cardRef = useRef<HTMLDivElement>(null)
|
||||
const { year } = useYear()
|
||||
|
||||
const accentBg = 'bg-brand'
|
||||
const accentBg = 'bg-brand-default'
|
||||
const accentText = 'text-brand'
|
||||
|
||||
// A static `value` wins; otherwise resolve from the embedded dataset for the
|
||||
|
||||
@@ -14,7 +14,7 @@ export function SurveySummarizedAnswer({ label, answers }: { label: string; answ
|
||||
const [isBlinking, setIsBlinking] = useState(false)
|
||||
const accent = useAccent()
|
||||
|
||||
const accentBg = 'bg-brand'
|
||||
const accentBg = 'bg-brand-default'
|
||||
|
||||
useEffect(() => {
|
||||
if (answers.length <= 1) return
|
||||
|
||||
@@ -18,7 +18,7 @@ export function SurveyWordCloud({
|
||||
const [scramblingTexts, setScramblingTexts] = useState<string[]>([])
|
||||
const accent = useAccent()
|
||||
|
||||
const accentBg = 'bg-brand'
|
||||
const accentBg = 'bg-brand-default'
|
||||
|
||||
// Calculate the range within the current context
|
||||
const counts = answers.map((answer) => answer.count)
|
||||
|
||||
@@ -198,7 +198,7 @@ function PreviousResultsCta() {
|
||||
<div className="w-fit bg-brand-300 px-5 py-3 text-[1.75rem] leading-8 tracking-tight text-brand md:text-[2.25rem] md:leading-10">
|
||||
of
|
||||
</div>
|
||||
<div className="w-fit bg-brand px-5 py-3 text-[1.75rem] leading-8 tracking-tight text-background dark:text-brand-200 md:text-[2.25rem] md:leading-10">
|
||||
<div className="w-fit bg-brand-default px-5 py-3 text-[1.75rem] leading-8 tracking-tight text-background dark:text-brand-200 md:text-[2.25rem] md:leading-10">
|
||||
Startups
|
||||
</div>
|
||||
<div className="w-fit bg-brand-500 px-5 py-3 text-[1.75rem] leading-8 tracking-tight text-brand-300 md:text-[2.25rem] md:leading-10">
|
||||
|
||||
@@ -4,7 +4,7 @@ import { Button } from 'ui'
|
||||
export function Hero() {
|
||||
return (
|
||||
<header className="container relative mx-auto px-6 pt-12 pb-8 lg:pt-24 lg:px-16 xl:px-20 text-center space-y-4">
|
||||
<h1 className="text-sm text-brand-link md:text-base">
|
||||
<h1 className="text-sm text-brand md:text-base">
|
||||
<span className="sr-only">Supabase </span>Contribute
|
||||
</h1>
|
||||
<h2 className="text-3xl md:text-4xl xl:text-5xl lg:max-w-2xl xl:max-w-6xl lg:mx-auto tracking-[-1px]">
|
||||
|
||||
@@ -19,7 +19,7 @@ export const markdownComponents: Components = {
|
||||
a: ({ node, ...props }) => (
|
||||
<a
|
||||
{...props}
|
||||
className="text-brand-link hover:underline break-all"
|
||||
className="text-brand hover:underline break-all"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
/>
|
||||
|
||||
@@ -104,7 +104,7 @@ const EnterpriseFormQuotes = ({
|
||||
<div className="relative w-full h-px bg-border-strong opacity-80 group-hover:opacity-100 rounded-full overflow-hidden">
|
||||
<motion.div
|
||||
className={cn(
|
||||
'absolute motion-reduce:hidden inset-0 w-full right-full bg-brand h-full transition-all',
|
||||
'absolute motion-reduce:hidden inset-0 w-full right-full bg-brand-default h-full transition-all',
|
||||
progress! > 99.7 ? 'opacity-0' : 'opacity-100'
|
||||
)}
|
||||
style={{ x: `${progress! - 100}%` }}
|
||||
|
||||
@@ -63,7 +63,7 @@ export function EventList() {
|
||||
<div
|
||||
className={cn(
|
||||
'absolute top-2 left-[-59px] rounded-full size-1.5',
|
||||
index === 0 ? 'bg-brand size-2 left-[-60px]' : 'bg-foreground-muted'
|
||||
index === 0 ? 'bg-brand-default size-2 left-[-60px]' : 'bg-foreground-muted'
|
||||
)}
|
||||
/>
|
||||
|
||||
|
||||
Loaded 100 of 166 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user