Files
supabase/apps/studio/styles/globals.css
Saxon FletcherandDanny White cd77bebafd chore(ui): refresh shared button styles (#50197)
## What kind of change does this PR introduce?

UI polish / design system: refreshed button styles, related token
tweaks, and a shared floating-button plate.

Resolves DEPR-652.

## What is the current behavior?

Default, primary, and secondary buttons use older fills, borders, and
hover treatments. Primary still leans on brand scale utilities. Default
fills don’t always read as raised chrome across surfaces, and floating
copy / expand / scroll controls can let busy content show through
translucent fills. Call sites hand-roll `rounded-* bg-background`
wrappers for that.

## What is the new behavior?

Refreshes primary, default, and secondary buttons with medium-weight
labels, subtle shadows and inset edges, and smoother transitions.
Light-mode default buttons use a raised fill with an accent hover state,
primary text is brighter, and inline keyboard shortcuts inherit the
button’s colour.

Adds `FloatingPlate`: an opaque `bg-popover` shell for floating default
buttons (and small clusters). Migrates Studio, Docs-related patterns,
www, and `ui-patterns` floaters onto it so busy content no longer shows
through translucent fills. Positioning, z-index, and hover/focus reveal
stay on the plate’s `className`. Use `rounded="full"` for pills.

Also:

- Moves primary onto semantic `--primary` / `--primary-hover` (with a
light-theme override) instead of brand utility fills
- Tokenises button shadows as `--button-shadow-drop` /
`--button-shadow-raised` / `--button-shadow-default` on the Button base
- Aligns hover direction: darken on light mode, lighten on dark mode for
both default and primary
- Default fill stays opaque `bg-card` in light (occlusion) and
translucent `bg-muted` in dark (adapts to the local surface)
- Documents fills and `FloatingPlate` on the design-system Button page
(with a live example)
- Scales shared radius tokens in Studio and www; medium+ Button sizes
use a proportionally softer radius
- Fixes www nav CTA centering (`lg:inline-flex` instead of `lg:block`)
- Query detail Expand/Collapse wires `aria-expanded` / `aria-controls`

| Before | After |
| --- | --- |
| <img width="1074" height="438" alt="CleanShot 2026-09-18 at 15 52
51@2x"
src="https://github.com/user-attachments/assets/ef43da21-b053-4b7e-9ac4-ab8b428228ab"
/> | <img width="1090" height="464" alt="CleanShot 2026-09-18 at 15 50
59@2x"
src="https://github.com/user-attachments/assets/2ddc55fc-4c8d-499c-a280-f3db3d99023c"
/> |
| <img width="1082" height="446" alt="CleanShot 2026-09-18 at 15 52
35@2x"
src="https://github.com/user-attachments/assets/3dd5452d-325a-4e4a-a79d-26c6c6950a31"
/> | <img width="1078" height="446" alt="CleanShot 2026-09-18 at 15 51
13@2x"
src="https://github.com/user-attachments/assets/93666385-3e6e-42e0-9891-9cd6bb935b67"
/> |

## To test

### Design system

- [Button
page](https://design-system-git-chore-button-styles-supabase.vercel.app/design-system/docs/components/button):
default / primary in light and dark; hover should darken on light,
lighten on dark
- Same page: [Floating over
content](https://design-system-git-chore-button-styles-supabase.vercel.app/design-system/docs/components/button#floating-over-content)
/ [Floating
plate](https://design-system-git-chore-button-styles-supabase.vercel.app/design-system/docs/components/button#floating-plate)
example; Copy over SQL should stay opaque
- Spot-check hover on a code preview Copy control

### Docs

[Docs deploy
preview](https://docs-git-chore-button-styles-supabase.vercel.app/docs):

- [Docs
homepage](https://docs-git-chore-button-styles-supabase.vercel.app/docs):
top-right **Sign up** / **Dashboard** primary; menu icon beside it
(default icon button)
- Shrink below `lg` and open the hamburger drawer: bottom **Sign in**
(default) + **Start your project** (primary) medium block buttons
- Tab once for **Skip to content** (FloatingPlate)
- [MCP
guide](https://docs-git-chore-button-styles-supabase.vercel.app/docs/guides/ai-tools/mcp):
project picker
- [Apple
login](https://docs-git-chore-button-styles-supabase.vercel.app/docs/guides/auth/social-login/auth-apple):
**Generate Secret Key** button in the Apple Secret Generator
- Optional opacity check: any guide code block Copy control (e.g. at the
bottom of [Import data into
Supabase](https://docs-git-chore-button-styles-supabase.vercel.app/docs/guides/database/import-data))

### Studio

[Studio deploy
preview](https://studio-staging-git-chore-button-styles-supabase.vercel.app/):

- **Observability → Query Performance**: open a query detail →
Expand/Collapse pill + SQL Copy chip (dark: no bleed-through)
- **Observability → Query Insights**: select a query → Clear query pill
- **Table Editor → any table → Definition** → floating **Open in SQL
Editor**
- **Connect → Framework → Add files**: Copy on the code tabs
(FloatingPlate; light hover follow-up is DEPR-694)
- Tab once for **Skip to content**

### WWW

- [www deploy
preview](https://zone-www-dot-com-git-chore-button-styles-supabase.vercel.app/):
nav Sign in / Start your project vertical centering; hero medium CTAs
radius

---------

Co-authored-by: Danny White <3104761+dnywh@users.noreply.github.com>
2026-09-23 03:43:00 +00:00

457 lines
9.6 KiB
CSS

@import 'config/tailwind.config.css';
@import 'config/typography.css';
@source '../pages/**/*.{js,ts,jsx,tsx}';
@source '../components/**/*.{js,ts,jsx,tsx}';
@source './../../../packages/ui/src/**/*.{tsx,ts,js}';
@source './../../../packages/ui-patterns/src/**/*.{tsx,ts,js}';
@theme inline {
--font-heading: var(--font-heading, var(--font-sans));
}
@theme {
/* Scale Tailwind's default radius tokens by 4/3 to match the Studio curve. */
--radius: 0.333333rem;
--radius-xs: 0.166667rem;
--radius-sm: 0.333333rem;
--radius-md: 0.5rem;
--radius-lg: 0.666667rem;
--radius-xl: 1rem;
--radius-2xl: 1.333333rem;
--radius-3xl: 2rem;
--radius-4xl: 2.666667rem;
--text-grid: 13px;
--color-typography-body-light: var(--foreground-light);
--color-typography-body-dark: var(--foreground-light);
--color-typography-body-secondary-light: var(--foreground-lighter);
--color-typography-body-secondary-dark: var(--foreground-lighter);
--color-typography-body-strong-light: var(--foreground-default);
--color-typography-body-strong-dark: var(--foreground-default);
--color-typography-body-faded-light: var(--foreground-muted);
--color-typography-body-faded-dark: var(--foreground-muted);
--color-table-body-light: var(--background-default);
--color-table-body-dark: var(--background-default);
--color-table-header-light: var(--background-surface-100);
--color-table-header-dark: var(--background-surface-100);
--color-table-footer-light: var(--background-surface-100);
--color-table-footer-dark: var(--background-surface-100);
--color-table-border-light: var(--border-default);
--color-table-border-dark: var(--border-default);
--color-panel-body-light: var(--background-surface-100);
--color-panel-body-dark: var(--background-surface-100);
--color-panel-header-light: var(--background-surface-100);
--color-panel-header-dark: var(--background-surface-100);
--color-panel-footer-light: var(--background-surface-100);
--color-panel-footer-dark: var(--background-surface-100);
--color-panel-border-light: var(--border-default);
--color-panel-border-dark: var(--border-default);
--color-panel-border-interior-light: var(--border-muted);
--color-panel-border-interior-dark: var(--border-muted);
--color-panel-border-hover-light: var(--border-muted);
--color-panel-border-hover-dark: var(--border-muted);
--animate-shimmer: shimmer 2s infinite linear;
--animate-badge-shimmer: badge-shimmer 3s ease-in-out infinite;
--animate-badge-pulse: badge-pulse 3s ease-in-out infinite;
--animate-chevron-up: chevron-up 2s ease-in-out infinite;
--animate-sway: sway 3s cubic-bezier(0.4, 0, 0.6, 1) infinite;
--animate-marketplace-featured-progress: marketplace-featured-progress linear forwards;
/* font sizing and weights optimized for Inter */
--text-sm: 0.8125rem;
--text-base: 0.9375rem;
--text-lg: 1rem;
--text-xl: 1.125rem;
--text-2xl: 1.375rem;
--text-3xl: 1.75rem;
--text-4xl: 2.125rem;
--text-5xl: 2.875rem;
--text-6xl: 3.625rem;
--text-7xl: 4.375rem;
--text-8xl: 5.875rem;
--text-9xl: 7.875rem;
--font-weight-normal: 450;
}
@keyframes shimmer {
0% {
background-position: -1000px 0;
}
100% {
background-position: 1000px 0;
}
}
@keyframes badge-shimmer {
0% {
transform: rotate(-45deg) translateX(-100%);
opacity: 0;
}
10% {
opacity: 1;
}
40% {
opacity: 1;
}
50% {
transform: rotate(-45deg) translateX(100%);
opacity: 0;
}
100% {
transform: rotate(-45deg) translateX(100%);
opacity: 0;
}
}
@keyframes badge-pulse {
0%,
100% {
opacity: 1;
}
50% {
opacity: 0.8;
}
}
@keyframes chevron-up {
0%,
100% {
opacity: 0.2;
}
50% {
opacity: 1;
}
}
@keyframes sway {
0%,
100% {
transform: rotate(-10deg) scale(1.5) translateY(4rem);
}
50% {
transform: rotate(10deg) scale(1.5) translateY(2rem);
}
}
@keyframes marketplace-featured-progress {
from {
transform: scaleX(0);
}
to {
transform: scaleX(1);
}
}
:root {
--sidebar-background: var(--background-dash-sidebar);
--sidebar-foreground: var(--foreground-default);
--sidebar-primary: var(--foreground-default);
--sidebar-primary-foreground: var(--warning);
--sidebar-accent: var(--background-selection);
--sidebar-accent-foreground: var(--foreground-default);
--sidebar-border: var(--border-default);
--sidebar-ring: var(--ring);
--header-height: 3rem;
}
[data-theme='dark'],
.dark {
--sidebar-background: var(--background-dash-sidebar);
--sidebar-foreground: var(--foreground-default);
--sidebar-primary: var(--foreground-default);
--sidebar-primary-foreground: var(--warning);
--sidebar-accent: var(--background-selection);
--sidebar-accent-foreground: var(--foreground-default);
--sidebar-border: var(--border-default);
--sidebar-ring: var(--ring);
}
@layer base {
*,
::after,
::before,
::backdrop,
::file-selector-button {
border-color: var(--border-default, currentColor);
}
}
html,
body,
#__next,
.main {
@apply bg-dash-sidebar relative;
@apply text-foreground;
@apply overflow-x-clip;
-moz-osx-font-smoothing: grayscale;
-webkit-font-smoothing: antialiased;
overscroll-behavior: none;
font-weight: 450;
}
* {
box-sizing: border-box;
}
@layer base {
h1,
h2,
h3,
h4,
h5,
h6 {
@apply font-heading;
}
}
h1,
h2,
h3,
h4,
h5,
h6 {
@apply font-semibold;
}
.form-group .form-text,
.Form .form-text {
@apply text-foreground-lighter;
}
.form-group input,
.form-group input[type='text'],
.form-group input[type='email'],
.form-group input[type='url'],
.form-group input[type='password'],
.form-group input[type='number'],
.form-group input[type='date'],
.form-group input[type='datetime-local'],
.form-group input[type='month'],
.form-group input[type='search'],
.form-group input[type='tel'],
.form-group input[type='time'],
.form-group input[type='week'],
.form-group input[multiple],
.form-group textarea,
.form-group select,
input.form-control,
.form-control input,
.form-control textarea {
@apply block;
@apply box-border;
/* @apply w-full ; */
@apply rounded-md;
@apply shadow-xs;
@apply text-foreground;
@apply border;
@apply bg-studio;
@apply border-strong border;
/* Prefer shared focus-ring over legacy green box-shadow / ring-current stacks */
@apply focus-ring;
}
.form-group input,
.form-group select,
.form-group textarea {
@apply px-4 py-2;
}
/* icons in date / time inputs */
.dark input[type='date']::-webkit-calendar-picker-indicator,
.dark input[type='datetime-local']::-webkit-calendar-picker-indicator,
.dark input[type='time']::-webkit-calendar-picker-indicator {
filter: invert(0.8);
}
input.is-invalid {
@apply bg-red-100;
@apply border border-red-700;
@apply focus-ring focus-visible:ring-destructive;
@apply placeholder:text-red-600;
}
input::placeholder {
@apply text-foreground-lighter;
}
.form-group input::placeholder {
@apply text-foreground-lighter;
}
.billing-input-fixed {
@apply w-full appearance-none rounded-sm border bg-gray-700 py-2 px-3 leading-tight text-gray-300 shadow-sm;
}
.input-mono {
input,
textarea {
@apply font-mono;
}
}
.input-sm {
input,
textarea {
@apply text-sm;
}
}
.input-xs {
input,
textarea {
@apply text-xs;
}
}
input[type='radio'] {
@apply p-0;
}
input[type='number'] {
-moz-appearance: textfield; /* Firefox, Not included in tailwind styles reset */
}
/* TODO: It doesnt' work, need to check */
.hide-scrollbar {
scrollbar-width: none; /* Firefox */
-ms-overflow-style: none; /* Internet Explorer 10+ */
}
.hide-scrollbar::-webkit-scrollbar {
width: 0;
height: 0;
display: none;
}
div[data-radix-portal]:not(.portal--toast) {
z-index: 2147483646 !important;
}
.billing-compute-radio {
label {
@apply items-center justify-between;
&:last-child {
opacity: 100 !important;
}
}
}
.recharts-tooltip-cursor {
@apply fill-transparent;
}
.expandable-tr {
display: grid;
grid-template-columns: repeat(5, 1fr);
}
.expanded-row-content {
display: grid;
grid-column: 1/-1;
justify-content: flex-start;
}
.multi-select {
button {
display: block;
width: 100%;
}
}
@media (prefers-color-scheme: dark) {
html {
color-scheme: dark;
}
}
.text-area-resize-none {
textarea {
@apply resize-none;
}
}
.capitalize-sentence:first-letter {
text-transform: capitalize;
}
.input-clear {
input {
@apply pr-7;
}
}
/* to do: remove this CSS and do the same thing in a reusable tooltip component */
[data-radix-popper-content-wrapper] {
@apply z-50!;
}
.settings-container {
@apply mx-auto max-w-4xl xl:max-w-6xl;
}
.react-grid-item.react-grid-placeholder {
@apply bg-brand-500!;
}
.react-grid-item > .react-resizable-handle::after {
content: '';
position: absolute;
right: 3px !important;
bottom: 3px !important;
width: 6px !important;
height: 6px !important;
@apply border-strong! dark:border-r-2! dark:border-b-2! dark:border-overlay!;
}
@keyframes typewriter {
from {
width: 0;
}
}
@keyframes blink-caret {
50% {
border-color: transparent;
}
}
/* Zoomable image (react-medium-image-zoom) */
[data-rmiz-modal]:focus,
[data-rmiz-modal-overlay]:focus {
outline: none !important;
}
[data-rmiz-modal-overlay],
[data-rmiz-modal-img] {
transition-timing-function: cubic-bezier(0.24, 0.25, 0.05, 1) !important;
}
[data-rmiz-modal-overlay='visible'] {
@apply bg-background!;
opacity: 0.8;
}
[data-rmiz-modal-img] {
image-rendering: high-quality;
}
.prose.text-sm ol > li::before {
top: 0.05rem;
}
.prose.text-sm ul > li::before {
top: 0.65rem;
}
.prose :where(strong, b):not(:where([class~='not-prose'], [class~='not-prose'] *)),
strong,
b {
@apply font-bold;
}