refactor: website facelift (#10823)

This commit is contained in:
Noel
2025-04-10 22:02:37 +02:00
committed by GitHub
parent 1fe53c7ca2
commit 2e3bc69602
80 changed files with 6136 additions and 2529 deletions

View File

@@ -0,0 +1,228 @@
@import 'tailwindcss';
@plugin 'tailwindcss-react-aria-components';
@import 'tw-animate-css';
@plugin '@tailwindcss/typography';
@custom-variant dark (&:where(.dark, .dark *));
@theme {
--font-sans: var(--font-geist-sans);
--font-mono: var(--font-geist-mono);
--color-base-neutral-0: #ffffff;
--color-base-neutral-40: #fcfcfc;
--color-base-neutral-60: #fafafa;
--color-base-neutral-80: #f0f0f0;
--color-base-neutral-100: #e6e6e6;
--color-base-neutral-200: #cccccc;
--color-base-neutral-300: #b3b3b3;
--color-base-neutral-400: #999999;
--color-base-neutral-500: #808080;
--color-base-neutral-600: #666666;
--color-base-neutral-700: #4c4c4c;
--color-base-neutral-800: #333333;
--color-base-neutral-900: #191919;
--color-base-blurple-50: #e0e3ff;
--color-base-blurple-100: #cdd2ff;
--color-base-blurple-200: #9ea7ff;
--color-base-blurple-300: #7782fa;
--color-base-blurple-400: #5865f2;
--color-base-blurple-500: #3d48c3;
--color-base-blurple-600: #293294;
--color-base-blurple-700: #1a2165;
--color-base-blurple-800: #0e1137;
--color-base-blurple-900: #020208;
--color-base-sunset-100: #ffe1df;
--color-base-sunset-200: #ffc3bf;
--color-base-sunset-300: #ffa69e;
--color-base-sunset-400: #ff887e;
--color-base-sunset-500: #ff6a5e;
--color-base-sunset-600: #cc554b;
--color-base-sunset-700: #994038;
--color-base-sunset-800: #662a26;
--color-base-sunset-900: #331513;
--color-base-tangerine-100: #fdefd2;
--color-base-tangerine-200: #fce0a5;
--color-base-tangerine-300: #fad078;
--color-base-tangerine-400: #f9c14b;
--color-base-tangerine-500: #f7b11e;
--color-base-tangerine-600: #c68e18;
--color-base-tangerine-700: #946a12;
--color-base-tangerine-800: #63470c;
--color-base-tangerine-900: #312306;
--color-base-green-lime-100: #ecefcc;
--color-base-green-lime-200: #d9df99;
--color-base-green-lime-300: #c6cf66;
--color-base-green-lime-400: #b3bf33;
--color-base-green-lime-500: #a0af00;
--color-base-green-lime-600: #808c00;
--color-base-green-lime-700: #606900;
--color-base-green-lime-800: #404600;
--color-base-green-lime-900: #202300;
--color-base-crystal-100: #dfedff;
--color-base-crystal-200: #bfdbff;
--color-base-crystal-300: #9ec8ff;
--color-base-crystal-400: #7eb6ff;
--color-base-crystal-500: #5ea4ff;
--color-base-crystal-600: #4b83cc;
--color-base-crystal-700: #386299;
--color-base-crystal-800: #264266;
--color-base-crystal-900: #132133;
--text-base-heading-xl: 2.813rem;
--text-base-heading-xl--line-height: 3.25rem;
--text-base-heading-xl--letter-spacing: 0;
--text-base-heading-xl--font-weight: 400;
--text-base-heading-lg: 2.25rem;
--text-base-heading-lg--line-height: 2.75rem;
--text-base-heading-lg--letter-spacing: 0;
--text-base-heading-lg--font-weight: 400;
--text-base-heading-md: 2rem;
--text-base-heading-md--line-height: 2.5rem;
--text-base-heading-md--letter-spacing: 0;
--text-base-heading-md--font-weight: 400;
--text-base-heading-sm: 1.75rem;
--text-base-heading-sm--line-height: 2.25rem;
--text-base-heading-sm--letter-spacing: 0;
--text-base-heading-sm--font-weight: 400;
--text-base-heading-xs: 1.5rem;
--text-base-heading-xs--line-height: 2rem;
--text-base-heading-xs--letter-spacing: 0;
--text-base-heading-xs--font-weight: 400;
--text-base-label-xl: 1.125rem;
--text-base-label-xl--line-height: 1.75rem;
--text-base-label-xl--letter-spacing: 0.5px;
--text-base-label-xl--font-weight: 500;
--text-base-label-lg: 1rem;
--text-base-label-lg--line-height: 1.5rem;
--text-base-label-lg--letter-spacing: 0.5px;
--text-base-label-lg--font-weight: 500;
--text-base-label-md: 1rem;
--text-base-label-md--line-height: 1.5rem;
--text-base-label-md--letter-spacing: 0.5px;
--text-base-label-md--font-weight: 500;
/* --text-base-label-md: 0.875rem;
--text-base-label-md--line-height: 1.25rem;
--text-base-label-md--letter-spacing: 0.1px;
--text-base-label-md--font-weight: 500; */
--text-base-label-sm: 0.75rem;
--text-base-label-sm--line-height: 1rem;
--text-base-label-sm--letter-spacing: 0.5px;
--text-base-label-sm--font-weight: 500;
--text-base-label-xs: 0.688rem;
--text-base-label-xs--line-height: 1rem;
--text-base-label-xs--letter-spacing: 0.5px;
--text-base-label-xs--font-weight: 500;
--text-base-xl: 1.125rem;
--text-base-xl--line-height: 1.75rem;
--text-base-xl--letter-spacing: 0.5px;
--text-base-xl--font-weight: 400;
--text-base-lg: 1rem;
--text-base-lg--line-height: 1.5rem;
--text-base-lg--letter-spacing: 0.5px;
--text-base-lg--font-weight: 400;
--text-base-md: 1rem;
--text-base-md--line-height: 1.5rem;
--text-base-md--letter-spacing: 0.5px;
--text-base-md--font-weight: 400;
/* --text-base-md: 0.875rem;
--text-base-md--line-height: 1.25rem;
--text-base-md--letter-spacing: 0.25px;
--text-base-md--font-weight: 400; */
--text-base-sm: 0.75rem;
--text-base-sm--line-height: 1rem;
--text-base-sm--letter-spacing: 0.4px;
--text-base-sm--font-weight: 400;
--text-base-xs: 0.688rem;
--text-base-xs--line-height: 1rem;
--text-base-xs--letter-spacing: 0.5px;
--text-base-xs--font-weight: 400;
--shadow-base-sm: 0 1px 4px 0 #19191929;
--shadow-base-md: 0 3px 3px 0 #19191929;
--shadow-base-lg: 0 3px 6px 0 #1919193d;
--shadow-base-xl: 0 6px 6px 0 #1919193d;
--shadow-base-2xl: 0 8px 8px 0 #19191952;
}
@layer base {
* {
font-family: var(--font-roboto);
text-rendering: optimizeLegibility;
scrollbar-width: thin;
}
html.dark .os-scrollbar-handle {
--os-handle-bg: rgba(255, 255, 255, 0.5);
--os-handle-bg-hover: rgba(255, 255, 255, 0.7);
--os-handle-bg-active: rgba(255, 255, 255, 0.7);
}
.os-scrollbar-handle {
--os-handle-bg: rgba(0, 0, 0, 0.5);
--os-handle-bg-hover: rgba(0, 0, 0, 0.7);
--os-handle-bg-active: rgba(0, 0, 0, 0.7);
}
html.dark .shiki,
html.dark .shiki span {
color: var(--shiki-dark) !important;
font-style: var(--shiki-dark-font-style) !important;
font-weight: var(--shiki-dark-font-weight) !important;
text-decoration: var(--shiki-dark-text-decoration) !important;
}
pre {
@apply bg-[#f3f3f4]! dark:bg-[#121214]!;
}
code {
font-family: var(--font-geist-mono);
}
code > .line {
padding: 0 1rem;
}
}
@utility scrollbar-hidden {
scrollbar-width: none;
}
[cmdk-overlay] {
position: fixed;
inset: 0;
height: 100dvh;
width: 100vw;
@apply bg-base-neutral-900/72 z-30;
}
[cmdk-dialog] {
position: fixed;
left: 50%;
top: 0;
z-index: 50;
transform: translate(-50%, 0);
width: 100%;
max-width: 536px;
height: 100dvh;
@apply h-auto outline-0 md:top-16 md:p-4;
}
[cmdk-list-sizer] {
display: flex;
flex-direction: column;
gap: 0.5rem;
width: 100%;
}
[cmdk-group-heading] {
@apply text-base-label-sm text-base-neutral-600 dark:text-base-neutral-300 h-8 px-3 py-2;
}

View File

@@ -0,0 +1,34 @@
import { defineConfig } from 'cva';
import { extendTailwindMerge } from 'tailwind-merge';
const twMergeConfig = {
classGroups: {
'font-size': [
'text-base-xs',
'text-base-sm',
'text-base-md',
'text-base-lg',
'text-base-xl',
'text-base-label-xs',
'text-base-label-sm',
'text-base-label-md',
'text-base-label-lg',
'text-base-label-xl',
'text-base-heading-xs',
'text-base-heading-sm',
'text-base-heading-md',
'text-base-heading-lg',
'text-base-heading-xl',
],
},
};
const twMerge = extendTailwindMerge({
extend: twMergeConfig,
});
export const { cva, cx, compose } = defineConfig({
hooks: {
onComplete: (className) => twMerge(className),
},
});

View File

@@ -1,76 +0,0 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
* {
min-width: 0;
}
body {
font-family: var(--font-geist-sans);
min-height: 100dvh;
}
html.dark .os-scrollbar-handle {
--os-handle-bg: rgba(255, 255, 255, 0.5);
}
html.dark .os-scrollbar-handle:hover {
--os-handle-bg-hover: rgba(255, 255, 255, 0.7);
}
.os-scrollbar-handle {
--os-handle-bg: rgba(0, 0, 0, 0.5);
}
.os-scrollbar-handle:hover {
--os-handle-bg-hover: rgba(0, 0, 0, 0.7);
}
html.dark .shiki,
html.dark .shiki span {
color: var(--shiki-dark) !important;
/* background-color: var(--shiki-dark-bg) !important; */
background-color: transparent !important;
font-style: var(--shiki-dark-font-style) !important;
font-weight: var(--shiki-dark-font-weight) !important;
text-decoration: var(--shiki-dark-text-decoration) !important;
}
pre {
background-color: transparent !important;
}
code {
font-family: var(--font-geist-mono);
}
code > .line {
padding: 0 1rem;
}
[cmdk-overlay] {
position: fixed;
inset: 0;
height: 100dvh;
width: 100vw;
background-color: rgb(0 0 0 / 80%);
}
[cmdk-dialog] {
position: fixed;
left: 50%;
top: 20%;
z-index: 50;
transform: translate(-50%, 0);
width: 100%;
max-width: 640px;
padding: 1rem;
}
[cmdk-list-sizer] {
display: flex;
flex-direction: column;
gap: 0.5rem;
width: 100%;
}

View File

@@ -0,0 +1,193 @@
import { compose, cva } from '@/styles/cva';
import { focusRing } from '@/styles/ui/focusRing';
export const buttonStyles = compose(
focusRing,
cva({
base: [
'text-base-label-md relative inline-flex place-content-center place-items-center gap-2 border border-transparent',
'*:data-[slot=icon]:size-4.5 *:data-[slot=icon]:shrink-0 print:hidden',
],
variants: {
variant: {
unset: null,
outline: [
'h-10 rounded-sm px-4 py-2.5',
'border-base-neutral-300 text-base-neutral-800 bg-base-neutral-0 dark:bg-base-neutral-800 dark:border-base-neutral-500 dark:text-base-neutral-100',
'hover:bg-base-neutral-700 hover:text-base-neutral-40 dark:hover:bg-base-neutral-100 dark:hover:text-base-neutral-900 hover:border-transparent',
'focus-visible:bg-base-neutral-700 focus-visible:text-base-neutral-40 dark:focus-visible:bg-base-neutral-100 dark:focus-visible:text-base-neutral-900 focus-visible:border-transparent',
'pressed:bg-base-neutral-800 pressed:text-base-neutral-40 pressed:border-transparent dark:pressed:bg-base-neutral-60 dark:pressed:text-base-neutral-900',
'disabled:bg-base-neutral-40 disabled:text-base-neutral-900 disabled:border-base-neutral-300 dark:disabled:bg-base-neutral-800 dark:disabled:text-base-neutral-40',
],
discreet: [
'h-10 rounded-sm px-4 py-2.5',
'text-base-neutral-800 dark:text-base-neutral-100 bg-transparent',
'hover:bg-base-neutral-100 dark:hover:bg-base-neutral-700',
'focus-visible:bg-base-neutral-100 dark:focus-visible:bg-base-neutral-700',
'pressed:bg-base-neutral-200 dark:pressed:bg-base-neutral-600',
'disabled:text-base-neutral-900 dark:disabled:text-base-neutral-40',
],
filled: [
'h-10 rounded-sm px-4 py-2.5',
'bg-base-neutral-700 text-base-neutral-40 dark:bg-base-neutral-100 dark:text-base-neutral-900',
'hover:bg-base-neutral-500 dark:hover:bg-base-neutral-300',
'focus-visible:bg-base-neutral-500 dark:focus-visible:bg-base-neutral-300',
'pressed:bg-base-neutral-400 pressed:text-base-neutral-800 dark:pressed:bg-base-neutral-400',
'disabled:bg-base-neutral-200 disabled:text-base-neutral-900 dark:disabled:bg-base-neutral-400 dark:disabled:text-base-neutral-40',
],
tonal: [
'h-10 rounded-sm px-4 py-2.5',
'bg-base-neutral-500 text-base-neutral-40 dark:bg-base-neutral-400 dark:text-base-neutral-900',
'hover:bg-base-neutral-700 dark:hover:bg-base-neutral-200',
'focus-visible:bg-base-neutral-700 dark:focus-visible:bg-base-neutral-200',
'pressed:bg-base-neutral-800 dark:pressed:bg-base-neutral-100',
'disabled:bg-base-neutral-200 disabled:text-base-neutral-900 dark:disabled:bg-base-neutral-700 dark:disabled:text-base-neutral-40',
],
'secondary-outline': [
'h-10 rounded-sm px-4 py-2.5',
'border-base-blurple-200 text-base-neutral-800 bg-base-neutral-0 dark:bg-base-neutral-800 dark:border-base-blurple-500 dark:text-base-neutral-40',
'hover:bg-base-blurple-400 hover:text-base-neutral-900 hover:border-transparent',
'focus-visible:bg-base-blurple-400 focus-visible:text-base-neutral-900 focus-visible:border-transparent',
'pressed:bg-base-blurple-500 pressed:text-base-neutral-40 pressed:border-transparent dark:pressed:bg-base-blurple-300 dark:pressed:text-base-neutral-900',
'disabled:bg-base-neutral-0 disabled:text-base-neutral-900 disabled:border-base-neutral-200 dark:text-base-neutral-40 dark:disabled:bg-base-neutral-800 dark:disabled:border-base-neutral-700',
],
'secondary-discreet': [
'h-10 rounded-sm px-4 py-2.5',
'text-base-blurple-500 dark:text-base-blurple-300 bg-transparent',
'hover:bg-base-blurple-50 hover:text-base-blurple-600 dark:hover:bg-base-blurple-700 dark:hover:text-base-blurple-200',
'focus-visible:bg-base-blurple-50 focus-visible:text-base-blurple-600 dark:focus-visible:bg-base-blurple-700 dark:focus-visible:text-base-blurple-200',
'pressed:bg-base-blurple-100 pressed:text-base-blurple-700 dark:pressed:bg-base-blurple-600 dark:pressed:text-base-blurple-50',
'disabled:text-base-neutral-900 dark:disabled:text-base-neutral-40',
],
'secondary-filled': [
'h-10 rounded-sm px-4 py-2.5',
'bg-base-blurple-400 text-base-neutral-900',
'hover:bg-base-blurple-200 dark:hover:bg-base-blurple-600 dark:hover:text-base-neutral-200',
'focus-visible:bg-base-blurple-200 dark:focus-visible:bg-base-blurple-600 dark:focus-visible:text-base-neutral-200',
'pressed:bg-base-blurple-100 dark:pressed:bg-base-blurple-700 dark:pressed:text-base-neutral-100',
'disabled:bg-base-neutral-200 disabled:text-base-neutral-900 dark:disabled:bg-base-neutral-700 dark:disabled:text-base-neutral-40',
],
'secondary-tonal': [
'h-10 rounded-sm px-4 py-2.5',
'bg-base-blurple-200 text-base-neutral-900 dark:bg-base-blurple-600 dark:text-base-neutral-40',
'hover:bg-base-blurple-400 dark:hover:text-base-neutral-900',
'focus-visible:bg-base-blurple-400 dark:focus-visible:text-base-neutral-900',
'pressed:bg-base-blurple-500 pressed:text-base-neutral-40 dark:pressed:bg-base-blurple-300 dark:pressed:text-base-neutral-900',
'disabled:bg-base-neutral-200 disabled:text-base-neutral-900 dark:disabled:bg-base-neutral-700 dark:disabled:text-base-neutral-40',
],
'crystal-tonal': [
'h-10 rounded-sm px-4 py-2.5',
'bg-base-crystal-300 text-base-neutral-900 dark:bg-base-crystal-700 dark:text-base-neutral-40',
'hover:bg-base-crystal-500 dark:hover:text-base-neutral-900',
'focus-visible:bg-base-crystal-500 dark:focus-visible:text-base-neutral-900',
'pressed:bg-base-crystal-600 pressed:text-base-neutral-40 dark:pressed:bg-base-crystal-400 dark:pressed:text-base-neutral-900',
'disabled:bg-base-neutral-200 disabled:text-base-neutral-900 dark:disabled:bg-base-neutral-700 dark:disabled:text-base-neutral-40',
],
tooltip: [
'size-6 shrink-0 rounded-full p-0.5',
'text-base-neutral-800 dark:text-base-neutral-100',
'hover:text-base-crystal-500 dark:hover:text-base-crystal-300',
'focus-visible:text-base-crystal-500 dark:focus-visible:text-base-crystal-300',
'disabled:text-base-neutral-900 dark:disabled:text-base-neutral-40',
],
},
size: {
default: null,
icon: null,
sm: null,
xs: null,
'icon-sm': null,
'icon-xs': null,
},
isDestructive: {
true: null,
},
isDark: {
true: null,
},
isDisabled: {
true: 'cursor-default opacity-38 forced-colors:text-[GrayText] forced-colors:group-disabled:text-[GrayText] forced-colors:disabled:text-[GrayText]',
false: 'cursor-pointer',
},
isPending: {
true: 'cursor-default',
},
},
compoundVariants: [
{
variant: 'discreet',
isDestructive: true,
className: [
'text-base-sunset-600 dark:text-base-sunset-400',
'hover:bg-base-sunset-100 hover:text-base-sunset-700 dark:hover:bg-base-sunset-800 dark:hover:text-base-sunset-300',
'focus-visible:bg-base-sunset-100 focus-visible:text-base-sunset-700 dark:focus-visible:bg-base-sunset-700 dark:focus-visible:text-base-sunset-300',
'pressed:bg-base-sunset-200 pressed:text-base-sunset-800 dark:pressed:bg-base-sunset-700 dark:pressed:text-base-sunset-100',
],
},
{
variant: [
'filled',
'outline',
'discreet',
'tonal',
'secondary-filled',
'secondary-outline',
'secondary-discreet',
'secondary-tonal',
'crystal-tonal',
'unset',
],
size: 'icon',
className: 'size-10 shrink-0 rounded-full p-2.5',
},
{
variant: ['filled', 'outline'],
size: 'sm',
className: 'h-8 px-3 py-1.5',
},
{
variant: 'filled',
size: 'sm',
isDark: true,
className: [
'h-8 px-3 py-1.5',
'bg-base-neutral-900 dark:bg-base-neutral-40',
'hover:bg-base-neutral-700 dark:hover:bg-base-neutral-200',
'focus-visible:bg-base-neutral-700 dark:focus-visible:bg-base-neutral-200',
'pressed:bg-base-neutral-600 pressed:text-base-neutral-40 dark:pressed:bg-base-neutral-300 dark:pressed:text-base-neutral-900',
],
},
{
variant: 'filled',
size: 'xs',
isDark: true,
className: [
'h-6 gap-1 px-2 py-1',
'bg-base-neutral-900 dark:bg-base-neutral-40',
'hover:bg-base-neutral-700 dark:hover:bg-base-neutral-200',
'focus-visible:bg-base-neutral-700 dark:focus-visible:bg-base-neutral-200',
'pressed:bg-base-neutral-600 pressed:text-base-neutral-40 dark:pressed:bg-base-neutral-300 dark:pressed:text-base-neutral-900',
],
},
{
variant: ['filled', 'discreet', 'secondary-tonal', 'crystal-tonal', 'unset'],
size: 'icon-sm',
className: 'size-8 shrink-0 rounded-full p-1.5',
},
{
variant: 'outline',
size: 'icon-sm',
className: 'size-8 shrink-0 rounded-sm p-1.5',
},
{
variant: ['discreet', 'unset'],
size: 'icon-xs',
className: 'size-6 shrink-0 rounded-full p-0.5',
},
],
defaultVariants: {
variant: 'outline',
size: 'default',
},
}),
);

View File

@@ -0,0 +1,11 @@
import { cva } from 'cva';
export const focusRing = cva({
base: 'outline-base-blurple-400 dark:outline-base-blurple-400 outline-offset-2 forced-colors:outline-[Highlight]',
variants: {
isFocusVisible: {
true: 'outline-2',
false: 'outline-0',
},
},
});

View File

@@ -0,0 +1,9 @@
import { composeRenderProps } from 'react-aria-components';
import { cx } from '@/styles/cva';
export function composeTailwindRenderProps<Type>(
className: string | ((v: Type) => string) | undefined,
tw: string,
): string | ((v: Type) => string) {
return composeRenderProps(className, (className) => cx(tw, className));
}