globals.css 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513
  1. @import 'config/tailwind.config.css';
  2. @import './../../../packages/studio/ui/build/css/themes/classic-dark.css';
  3. @import 'config/typography.css';
  4. @source '../pages/**/*.{js,ts,jsx,tsx}';
  5. @source '../components/**/*.{js,ts,jsx,tsx}';
  6. @source './../../../packages/studio/ui/src/**/*.{tsx,ts,js}';
  7. @source './../../../packages/studio/ui-patterns/src/**/*.{tsx,ts,js}';
  8. @theme {
  9. --text-grid: 13px;
  10. --color-typography-body-light: hsl(var(--foreground-light));
  11. --color-typography-body-dark: hsl(var(--foreground-light));
  12. --color-typography-body-secondary-light: hsl(var(--foreground-lighter));
  13. --color-typography-body-secondary-dark: hsl(var(--foreground-lighter));
  14. --color-typography-body-strong-light: hsl(var(--foreground-default));
  15. --color-typography-body-strong-dark: hsl(var(--foreground-default));
  16. --color-typography-body-faded-light: hsl(var(--foreground-muted));
  17. --color-typography-body-faded-dark: hsl(var(--foreground-muted));
  18. --color-table-body-light: hsl(var(--background-default));
  19. --color-table-body-dark: hsl(var(--background-default));
  20. --color-table-header-light: hsl(var(--background-surface-100));
  21. --color-table-header-dark: hsl(var(--background-surface-100));
  22. --color-table-footer-light: hsl(var(--background-surface-100));
  23. --color-table-footer-dark: hsl(var(--background-surface-100));
  24. --color-table-border-light: hsl(var(--border-default));
  25. --color-table-border-dark: hsl(var(--border-default));
  26. --color-panel-body-light: hsl(var(--background-surface-100));
  27. --color-panel-body-dark: hsl(var(--background-surface-100));
  28. --color-panel-header-light: hsl(var(--background-surface-100));
  29. --color-panel-header-dark: hsl(var(--background-surface-100));
  30. --color-panel-footer-light: hsl(var(--background-surface-100));
  31. --color-panel-footer-dark: hsl(var(--background-surface-100));
  32. --color-panel-border-light: hsl(var(--border-default));
  33. --color-panel-border-dark: hsl(var(--border-default));
  34. --color-panel-border-interior-light: hsl(var(--border-muted));
  35. --color-panel-border-interior-dark: hsl(var(--border-muted));
  36. --color-panel-border-hover-light: hsl(var(--border-muted));
  37. --color-panel-border-hover-dark: hsl(var(--border-muted));
  38. --animate-shimmer: shimmer 2s infinite linear;
  39. --animate-badge-shimmer: badge-shimmer 3s ease-in-out infinite;
  40. --animate-badge-pulse: badge-pulse 3s ease-in-out infinite;
  41. --animate-chevron-up: chevron-up 2s ease-in-out infinite;
  42. --animate-sway: sway 3s cubic-bezier(0.4, 0, 0.6, 1) infinite;
  43. --animate-marketplace-featured-progress: marketplace-featured-progress linear forwards;
  44. }
  45. @keyframes shimmer {
  46. 0% {
  47. background-position: -1000px 0;
  48. }
  49. 100% {
  50. background-position: 1000px 0;
  51. }
  52. }
  53. @keyframes badge-shimmer {
  54. 0% {
  55. transform: rotate(-45deg) translateX(-100%);
  56. opacity: 0;
  57. }
  58. 10% {
  59. opacity: 1;
  60. }
  61. 40% {
  62. opacity: 1;
  63. }
  64. 50% {
  65. transform: rotate(-45deg) translateX(100%);
  66. opacity: 0;
  67. }
  68. 100% {
  69. transform: rotate(-45deg) translateX(100%);
  70. opacity: 0;
  71. }
  72. }
  73. @keyframes badge-pulse {
  74. 0%,
  75. 100% {
  76. opacity: 1;
  77. }
  78. 50% {
  79. opacity: 0.8;
  80. }
  81. }
  82. @keyframes chevron-up {
  83. 0%,
  84. 100% {
  85. opacity: 0.2;
  86. }
  87. 50% {
  88. opacity: 1;
  89. }
  90. }
  91. @keyframes sway {
  92. 0%,
  93. 100% {
  94. transform: rotate(-10deg) scale(1.5) translateY(4rem);
  95. }
  96. 50% {
  97. transform: rotate(10deg) scale(1.5) translateY(2rem);
  98. }
  99. }
  100. @keyframes marketplace-featured-progress {
  101. from {
  102. transform: scaleX(0);
  103. }
  104. to {
  105. transform: scaleX(1);
  106. }
  107. }
  108. :root {
  109. --chart-1: var(--brand-default);
  110. --chart-2: 173 58% 39%;
  111. --chart-3: 197 37% 24%;
  112. --chart-4: 43 74% 66%;
  113. --chart-5: 27 87% 67%;
  114. --chart-blue: 217 91% 60%;
  115. --chart-warning: hsl(var(--warning-default));
  116. --chart-destructive: hsl(var(--destructive-default));
  117. --sidebar-background: var(--background-dash-sidebar);
  118. --sidebar-foreground: var(--foreground-default);
  119. --sidebar-primary: var(--foreground-default);
  120. --sidebar-primary-foreground: var(--warning-default);
  121. --sidebar-accent: var(--background-selection);
  122. --sidebar-accent-foreground: var(--foreground-default);
  123. --sidebar-border: var(--border-default);
  124. --sidebar-ring: 217.2 91.2% 59.8%;
  125. --header-height: 3rem;
  126. }
  127. [data-theme='dark'],
  128. .dark {
  129. --chart-1: var(--brand-default);
  130. --chart-2: 160 60% 45%;
  131. --chart-3: 30 80% 55%;
  132. --chart-4: 280 65% 60%;
  133. --chart-5: 340 75% 55%;
  134. --chart-blue: 217 91% 65%;
  135. --chart-warning: hsl(var(--warning-default));
  136. --chart-destructive: hsl(var(--destructive-default));
  137. --sidebar-background: var(--background-dash-sidebar);
  138. --sidebar-foreground: var(--foreground-default);
  139. --sidebar-primary: var(--foreground-default);
  140. --sidebar-primary-foreground: var(--warning-default);
  141. --sidebar-accent: var(--background-selection);
  142. --sidebar-accent-foreground: var(--foreground-default);
  143. --sidebar-border: var(--border-default);
  144. --sidebar-ring: 217.2 91.2% 59.8%;
  145. }
  146. @layer base {
  147. *,
  148. ::after,
  149. ::before,
  150. ::backdrop,
  151. ::file-selector-button {
  152. border-color: hsl(var(--border-default, currentColor));
  153. }
  154. /* Global affordance: every interactive element shows pointer on hover.
  155. Tailwind v4 no longer ships default cursor: pointer on buttons. */
  156. button:not(:disabled),
  157. a[href],
  158. [role='button']:not([aria-disabled='true']),
  159. summary,
  160. label[for],
  161. select:not(:disabled),
  162. input[type='submit']:not(:disabled),
  163. input[type='button']:not(:disabled),
  164. input[type='reset']:not(:disabled),
  165. input[type='checkbox']:not(:disabled),
  166. input[type='radio']:not(:disabled) {
  167. cursor: pointer;
  168. }
  169. button:disabled,
  170. [role='button'][aria-disabled='true'] {
  171. cursor: not-allowed;
  172. }
  173. }
  174. html,
  175. body,
  176. #__next,
  177. .main {
  178. @apply bg-dash-sidebar relative;
  179. @apply text-foreground;
  180. @apply overflow-x-clip;
  181. -moz-osx-font-smoothing: grayscale;
  182. -webkit-font-smoothing: antialiased;
  183. overscroll-behavior: none;
  184. }
  185. * {
  186. box-sizing: border-box;
  187. }
  188. .form-group .form-text,
  189. .Form .form-text {
  190. @apply text-foreground-lighter;
  191. }
  192. .form-group input,
  193. .form-group input[type='text'],
  194. .form-group input[type='email'],
  195. .form-group input[type='url'],
  196. .form-group input[type='password'],
  197. .form-group input[type='number'],
  198. .form-group input[type='date'],
  199. .form-group input[type='datetime-local'],
  200. .form-group input[type='month'],
  201. .form-group input[type='search'],
  202. .form-group input[type='tel'],
  203. .form-group input[type='time'],
  204. .form-group input[type='week'],
  205. .form-group input[multiple],
  206. .form-group textarea,
  207. .form-group select,
  208. input.form-control,
  209. .form-control input,
  210. .form-control textarea {
  211. @apply block;
  212. @apply box-border;
  213. /* @apply w-full ; */
  214. @apply rounded-md;
  215. @apply shadow-xs;
  216. @apply transition-all;
  217. @apply text-foreground;
  218. @apply border;
  219. @apply focus:shadow-md;
  220. @apply focus:border-stronger;
  221. @apply focus:ring-border-overlay;
  222. @apply bg-studio;
  223. @apply border-strong border;
  224. @apply outline-hidden;
  225. @apply focus:ring-2 focus:ring-current;
  226. }
  227. .form-group input,
  228. .form-group select,
  229. .form-group textarea {
  230. @apply px-4 py-2;
  231. }
  232. .form-group input:focus,
  233. .form-group input[type='text']:focus,
  234. .form-group input[type='email']:focus,
  235. .form-group input[type='url']:focus,
  236. .form-group input[type='password']:focus,
  237. .form-group input[type='number']:focus,
  238. .form-group input[type='date']:focus,
  239. .form-group input[type='datetime-local']:focus,
  240. .form-group input[type='month']:focus,
  241. .form-group input[type='search']:focus,
  242. .form-group input[type='tel']:focus,
  243. .form-group input[type='time']:focus,
  244. .form-group input[type='week']:focus,
  245. .form-group input[multiple]:focus,
  246. .form-group textarea:focus,
  247. .form-group select:focus,
  248. .form-group input:focus .form-control:focus {
  249. box-shadow: 0 0 0 2px rgba(62, 207, 142, 0.1);
  250. }
  251. /* icons in date / time inputs */
  252. .dark input[type='date']::-webkit-calendar-picker-indicator,
  253. .dark input[type='datetime-local']::-webkit-calendar-picker-indicator,
  254. .dark input[type='time']::-webkit-calendar-picker-indicator {
  255. filter: invert(0.8);
  256. }
  257. input.is-invalid {
  258. @apply bg-red-100;
  259. @apply border border-red-700;
  260. @apply focus:ring-red-500;
  261. @apply placeholder:text-red-600;
  262. }
  263. input::placeholder {
  264. @apply text-foreground-lighter;
  265. }
  266. .form-group input::placeholder {
  267. @apply text-foreground-lighter;
  268. }
  269. .billing-input-fixed {
  270. @apply w-full appearance-none rounded-sm border bg-gray-700 py-2 px-3 leading-tight text-gray-300 shadow-sm;
  271. }
  272. .input-mono {
  273. input,
  274. textarea {
  275. @apply font-mono;
  276. }
  277. }
  278. .input-sm {
  279. input,
  280. textarea {
  281. @apply text-sm;
  282. }
  283. }
  284. .input-xs {
  285. input,
  286. textarea {
  287. @apply text-xs;
  288. }
  289. }
  290. input[type='radio'] {
  291. @apply p-0;
  292. }
  293. input[type='number'] {
  294. -moz-appearance: textfield; /* Firefox, Not included in tailwind styles reset */
  295. }
  296. /* TODO: It doesnt' work, need to check */
  297. .hide-scrollbar {
  298. scrollbar-width: none; /* Firefox */
  299. -ms-overflow-style: none; /* Internet Explorer 10+ */
  300. }
  301. .hide-scrollbar::-webkit-scrollbar {
  302. width: 0;
  303. height: 0;
  304. display: none;
  305. }
  306. div[data-radix-portal]:not(.portal--toast) {
  307. z-index: 2147483646 !important;
  308. }
  309. .billing-compute-radio {
  310. label {
  311. @apply items-center justify-between;
  312. &:last-child {
  313. opacity: 100 !important;
  314. }
  315. }
  316. }
  317. .recharts-tooltip-cursor {
  318. @apply fill-transparent;
  319. }
  320. .expandable-tr {
  321. display: grid;
  322. grid-template-columns: repeat(5, 1fr);
  323. }
  324. .expanded-row-content {
  325. display: grid;
  326. grid-column: 1/-1;
  327. justify-content: flex-start;
  328. }
  329. .multi-select {
  330. button {
  331. display: block;
  332. width: 100%;
  333. }
  334. }
  335. @media (prefers-color-scheme: dark) {
  336. html {
  337. color-scheme: dark;
  338. }
  339. }
  340. .text-area-resize-none {
  341. textarea {
  342. @apply resize-none;
  343. }
  344. }
  345. .capitalize-sentence:first-letter {
  346. text-transform: capitalize;
  347. }
  348. .input-clear {
  349. input {
  350. @apply pr-7;
  351. }
  352. }
  353. /* to do: remove this CSS and do the same thing in a reusable tooltip component */
  354. [data-radix-popper-content-wrapper] {
  355. @apply z-50!;
  356. }
  357. .settings-container {
  358. @apply mx-auto max-w-4xl xl:max-w-6xl;
  359. }
  360. .react-grid-item.react-grid-placeholder {
  361. @apply bg-brand-500!;
  362. }
  363. .react-grid-item > .react-resizable-handle::after {
  364. content: '';
  365. position: absolute;
  366. right: 3px !important;
  367. bottom: 3px !important;
  368. width: 6px !important;
  369. height: 6px !important;
  370. @apply border-strong! dark:border-r-2! dark:border-b-2! dark:border-overlay!;
  371. }
  372. @keyframes typewriter {
  373. from {
  374. width: 0;
  375. }
  376. }
  377. @keyframes blink-caret {
  378. 50% {
  379. border-color: transparent;
  380. }
  381. }
  382. /*
  383. * Briven brand override — Phase 4 of BACKEND_FORK_BRIEF.md
  384. * Replaces Supabase's green (--brand-default 153 60 53) with briven's
  385. * brand green (#00e87a = 151.7 100 46). Source of truth lives in
  386. * packages/config/tailwind/theme.css (--color-primary). HSL form is
  387. * used here to integrate with Studio's existing theme variable shape.
  388. */
  389. [data-theme='classic-dark'],
  390. .classic-dark,
  391. [data-theme='dark'],
  392. .dark,
  393. :root {
  394. --brand-default: 151.7deg 100% 45.5%;
  395. --brand-link: 151.7deg 100% 45.5%;
  396. --brand-600: 151.7deg 90% 60%;
  397. --brand-500: 151.7deg 80% 35%;
  398. --brand-400: 151.7deg 70% 22%;
  399. --brand-300: 151.7deg 60% 13%;
  400. --brand-200: 151.7deg 50% 8%;
  401. /* Phase 5 screen 3 — extend brand override to absolute scale tokens
  402. * (--color-brand-700..1000) so Tailwind utilities like bg-brand-900
  403. * resolve to briven green rather than upstream's supabase HSL. */
  404. --color-brand-700: hsla(151.7, 70%, 38%, 1);
  405. --color-brand-800: hsla(151.7, 85%, 42%, 1);
  406. --color-brand-900: hsla(151.7, 100%, 45.5%, 1);
  407. --color-brand-1000: hsla(151.7, 90%, 50%, 1);
  408. }
  409. /*
  410. * Briven typography override — Phase 5 (screen 2: project home, applies
  411. * chrome-wide because the layout components are shared). Force mono
  412. * across the app to match the terminal aesthetic of the control plane
  413. * (apps/web). Headings render lowercase per BRAND.md §3.
  414. *
  415. * `var(--font-mono)` resolves to Studio's existing fallback stack
  416. * (Source Code Pro -> Office Code Pro -> Menlo -> monospace). When the
  417. * Geist Mono webfont lands in Phase 6+, it slots into --font-custom-mono
  418. * and propagates through this override.
  419. */
  420. :root {
  421. --font-sans: var(
  422. --font-geist-mono,
  423. 'Geist Mono',
  424. 'JetBrains Mono',
  425. 'Source Code Pro',
  426. Menlo,
  427. monospace
  428. );
  429. --font-mono: var(
  430. --font-geist-mono,
  431. 'Geist Mono',
  432. 'JetBrains Mono',
  433. 'Source Code Pro',
  434. Menlo,
  435. monospace
  436. );
  437. }
  438. body,
  439. button,
  440. input,
  441. select,
  442. textarea {
  443. font-family: var(--font-mono);
  444. }
  445. /* Lowercase all chrome headings — matches lowercase brand voice. Decorative
  446. * <h*> inside marketing strings can opt out with .normal-case if needed. */
  447. h1:not(.normal-case),
  448. h2:not(.normal-case),
  449. h3:not(.normal-case),
  450. h4:not(.normal-case),
  451. h5:not(.normal-case),
  452. h6:not(.normal-case) {
  453. text-transform: lowercase;
  454. }