mirror of
https://github.com/johndoe6345789/snippet-pastebin.git
synced 2026-04-24 13:34:55 +00:00
Replace Tailwind with modular Sass system using mixins and utilities
Co-authored-by: johndoe6345789 <224850594+johndoe6345789@users.noreply.github.com>
This commit is contained in:
1085
package-lock.json
generated
1085
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -45,7 +45,6 @@
|
||||
"@radix-ui/react-toggle-group": "^1.1.2",
|
||||
"@radix-ui/react-tooltip": "^1.1.8",
|
||||
"@reduxjs/toolkit": "^2.11.2",
|
||||
"@tailwindcss/container-queries": "^0.1.1",
|
||||
"@tanstack/react-query": "^5.83.1",
|
||||
"@types/sql.js": "^1.4.9",
|
||||
"class-variance-authority": "^0.7.1",
|
||||
@@ -71,25 +70,21 @@
|
||||
"react-resizable-panels": "^2.1.7",
|
||||
"react-router-dom": "^7.12.0",
|
||||
"recharts": "^2.15.1",
|
||||
"sass": "^1.97.2",
|
||||
"sonner": "^2.0.1",
|
||||
"tailwind-merge": "^3.0.2",
|
||||
"three": "^0.175.0",
|
||||
"tw-animate-css": "^1.2.4",
|
||||
"uuid": "^11.1.0",
|
||||
"vaul": "^1.1.2",
|
||||
"zod": "^3.25.76"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^9.21.0",
|
||||
"@tailwindcss/postcss": "^4.1.18",
|
||||
"@types/react": "^19.0.10",
|
||||
"@types/react-dom": "^19.0.4",
|
||||
"autoprefixer": "^10.4.23",
|
||||
"eslint": "^9.28.0",
|
||||
"eslint-config-next": "^16.1.3",
|
||||
"eslint-plugin-react-hooks": "^5.2.0",
|
||||
"globals": "^16.0.0",
|
||||
"tailwindcss": "^4.1.11",
|
||||
"typescript": "~5.7.2",
|
||||
"typescript-eslint": "^8.38.0"
|
||||
},
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
export default {
|
||||
plugins: {
|
||||
'@tailwindcss/postcss': {},
|
||||
},
|
||||
}
|
||||
@@ -1,67 +0,0 @@
|
||||
@import 'tailwindcss';
|
||||
|
||||
:root {
|
||||
--background: 222.2 84% 4.9%;
|
||||
--foreground: 210 40% 98%;
|
||||
--card: 222.2 84% 4.9%;
|
||||
--card-foreground: 210 40% 98%;
|
||||
--popover: 222.2 84% 4.9%;
|
||||
--popover-foreground: 210 40% 98%;
|
||||
--primary: 263 70% 50%;
|
||||
--primary-foreground: 210 40% 98%;
|
||||
--secondary: 217.2 32.6% 17.5%;
|
||||
--secondary-foreground: 210 40% 98%;
|
||||
--muted: 217.2 32.6% 17.5%;
|
||||
--muted-foreground: 215 20.2% 65.1%;
|
||||
--accent: 195 100% 70%;
|
||||
--accent-foreground: 222.2 84% 4.9%;
|
||||
--destructive: 0 62.8% 30.6%;
|
||||
--destructive-foreground: 210 40% 98%;
|
||||
--border: 217.2 32.6% 17.5%;
|
||||
--input: 217.2 32.6% 17.5%;
|
||||
--ring: 195 100% 70%;
|
||||
--radius: 0.5rem;
|
||||
}
|
||||
|
||||
@theme {
|
||||
--color-background: hsl(var(--background));
|
||||
--color-foreground: hsl(var(--foreground));
|
||||
--color-card: hsl(var(--card));
|
||||
--color-card-foreground: hsl(var(--card-foreground));
|
||||
--color-popover: hsl(var(--popover));
|
||||
--color-popover-foreground: hsl(var(--popover-foreground));
|
||||
--color-primary: hsl(var(--primary));
|
||||
--color-primary-foreground: hsl(var(--primary-foreground));
|
||||
--color-secondary: hsl(var(--secondary));
|
||||
--color-secondary-foreground: hsl(var(--secondary-foreground));
|
||||
--color-muted: hsl(var(--muted));
|
||||
--color-muted-foreground: hsl(var(--muted-foreground));
|
||||
--color-accent: hsl(var(--accent));
|
||||
--color-accent-foreground: hsl(var(--accent-foreground));
|
||||
--color-destructive: hsl(var(--destructive));
|
||||
--color-destructive-foreground: hsl(var(--destructive-foreground));
|
||||
--color-border: hsl(var(--border));
|
||||
--color-input: hsl(var(--input));
|
||||
--color-ring: hsl(var(--ring));
|
||||
}
|
||||
|
||||
* {
|
||||
border-color: hsl(var(--border));
|
||||
}
|
||||
|
||||
body {
|
||||
background: hsl(var(--background));
|
||||
color: hsl(var(--foreground));
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
font-family: var(--font-inter), 'Inter', sans-serif;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: var(--font-inter), 'Inter', sans-serif;
|
||||
}
|
||||
|
||||
code, pre {
|
||||
font-family: var(--font-jetbrains-mono), 'JetBrains Mono', monospace;
|
||||
}
|
||||
49
src/app/globals.scss
Normal file
49
src/app/globals.scss
Normal file
@@ -0,0 +1,49 @@
|
||||
@import '../styles/abstracts';
|
||||
@import '../styles/utilities/utilities';
|
||||
@import './theme.scss';
|
||||
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
border-color: $border;
|
||||
}
|
||||
|
||||
body {
|
||||
background: $background;
|
||||
color: $foreground;
|
||||
font-family: var(--font-inter), 'Inter', sans-serif;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
font-family: var(--font-inter), 'Inter', sans-serif;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
code, pre {
|
||||
font-family: var(--font-jetbrains-mono), 'JetBrains Mono', monospace;
|
||||
}
|
||||
|
||||
:root {
|
||||
--background: 222.2 84% 4.9%;
|
||||
--foreground: 210 40% 98%;
|
||||
--card: 222.2 84% 4.9%;
|
||||
--card-foreground: 210 40% 98%;
|
||||
--popover: 222.2 84% 4.9%;
|
||||
--popover-foreground: 210 40% 98%;
|
||||
--primary: 263 70% 50%;
|
||||
--primary-foreground: 210 40% 98%;
|
||||
--secondary: 217.2 32.6% 17.5%;
|
||||
--secondary-foreground: 210 40% 98%;
|
||||
--muted: 217.2 32.6% 17.5%;
|
||||
--muted-foreground: 215 20.2% 65.1%;
|
||||
--accent: 195 100% 70%;
|
||||
--accent-foreground: 222.2 84% 4.9%;
|
||||
--destructive: 0 62.8% 30.6%;
|
||||
--destructive-foreground: 210 40% 98%;
|
||||
--border: 217.2 32.6% 17.5%;
|
||||
--input: 217.2 32.6% 17.5%;
|
||||
--ring: 195 100% 70%;
|
||||
--radius: 0.5rem;
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { Metadata } from 'next';
|
||||
import './globals.css';
|
||||
import './globals.scss';
|
||||
import { Providers } from './providers';
|
||||
|
||||
export const metadata: Metadata = {
|
||||
|
||||
@@ -1,262 +0,0 @@
|
||||
@import "tailwindcss";
|
||||
|
||||
@import '@radix-ui/colors/sage-dark.css' layer(base);
|
||||
@import '@radix-ui/colors/olive.css' layer(base);
|
||||
@import '@radix-ui/colors/olive-dark.css' layer(base);
|
||||
@import '@radix-ui/colors/sand.css' layer(base);
|
||||
@import '@radix-ui/colors/sand-dark.css' layer(base);
|
||||
@import '@radix-ui/colors/red.css' layer(base);
|
||||
@import '@radix-ui/colors/red-dark.css' layer(base);
|
||||
@import '@radix-ui/colors/ruby.css' layer(base);
|
||||
@import '@radix-ui/colors/ruby-dark.css' layer(base);
|
||||
@import '@radix-ui/colors/crimson.css' layer(base);
|
||||
@import '@radix-ui/colors/crimson-dark.css' layer(base);
|
||||
@import '@radix-ui/colors/pink.css' layer(base);
|
||||
@import '@radix-ui/colors/pink-dark.css' layer(base);
|
||||
@import '@radix-ui/colors/plum.css' layer(base);
|
||||
@import '@radix-ui/colors/plum-dark.css' layer(base);
|
||||
@import '@radix-ui/colors/purple.css' layer(base);
|
||||
@import '@radix-ui/colors/purple-dark.css' layer(base);
|
||||
@import '@radix-ui/colors/violet.css' layer(base);
|
||||
@import '@radix-ui/colors/violet-dark.css' layer(base);
|
||||
@import '@radix-ui/colors/iris.css' layer(base);
|
||||
@import '@radix-ui/colors/iris-dark.css' layer(base);
|
||||
@import '@radix-ui/colors/indigo.css' layer(base);
|
||||
@import '@radix-ui/colors/indigo-dark.css' layer(base);
|
||||
@import '@radix-ui/colors/blue.css' layer(base);
|
||||
@import '@radix-ui/colors/blue-dark.css' layer(base);
|
||||
@import '@radix-ui/colors/cyan.css' layer(base);
|
||||
@import '@radix-ui/colors/cyan-dark.css' layer(base);
|
||||
@import '@radix-ui/colors/teal.css' layer(base);
|
||||
@import '@radix-ui/colors/teal-dark.css' layer(base);
|
||||
@import '@radix-ui/colors/jade.css' layer(base);
|
||||
@import '@radix-ui/colors/jade-dark.css' layer(base);
|
||||
@import '@radix-ui/colors/green.css' layer(base);
|
||||
@import '@radix-ui/colors/green-dark.css' layer(base);
|
||||
@import '@radix-ui/colors/grass.css' layer(base);
|
||||
@import '@radix-ui/colors/grass-dark.css' layer(base);
|
||||
@import '@radix-ui/colors/bronze.css' layer(base);
|
||||
@import '@radix-ui/colors/bronze-dark.css' layer(base);
|
||||
@import '@radix-ui/colors/gold.css' layer(base);
|
||||
@import '@radix-ui/colors/gold-dark.css' layer(base);
|
||||
@import '@radix-ui/colors/brown.css' layer(base);
|
||||
@import '@radix-ui/colors/brown-dark.css' layer(base);
|
||||
@import '@radix-ui/colors/orange.css' layer(base);
|
||||
@import '@radix-ui/colors/orange-dark.css' layer(base);
|
||||
@import '@radix-ui/colors/amber.css' layer(base);
|
||||
@import '@radix-ui/colors/amber-dark.css' layer(base);
|
||||
@import '@radix-ui/colors/yellow.css' layer(base);
|
||||
@import '@radix-ui/colors/yellow-dark.css' layer(base);
|
||||
@import '@radix-ui/colors/lime.css' layer(base);
|
||||
@import '@radix-ui/colors/lime-dark.css' layer(base);
|
||||
@import '@radix-ui/colors/mint.css' layer(base);
|
||||
@import '@radix-ui/colors/mint-dark.css' layer(base);
|
||||
@import '@radix-ui/colors/sky.css' layer(base);
|
||||
@import '@radix-ui/colors/sky-dark.css' layer(base);
|
||||
@import '@radix-ui/colors/tomato.css' layer(base);
|
||||
@import '@radix-ui/colors/tomato-dark.css' layer(base);
|
||||
@import '@radix-ui/colors/gray.css' layer(base);
|
||||
@import '@radix-ui/colors/gray-dark.css' layer(base);
|
||||
@import '@radix-ui/colors/mauve.css' layer(base);
|
||||
@import '@radix-ui/colors/mauve-dark.css' layer(base);
|
||||
@import '@radix-ui/colors/slate.css' layer(base);
|
||||
@import '@radix-ui/colors/slate-dark.css' layer(base);
|
||||
@import '@radix-ui/colors/slate-alpha.css' layer(base);
|
||||
@import '@radix-ui/colors/slate-dark-alpha.css' layer(base);
|
||||
|
||||
@import 'tailwindcss/theme' layer(theme);
|
||||
|
||||
@import 'tailwindcss/preflight' layer(base);
|
||||
|
||||
/*
|
||||
The default border color has changed to `currentColor` in Tailwind CSS v4,
|
||||
so we've added these compatibility styles to make sure everything still
|
||||
looks the same as it did with Tailwind CSS v3.
|
||||
|
||||
If we ever want to remove these styles, we need to add an explicit border
|
||||
color utility to any element that depends on these defaults.
|
||||
*/
|
||||
@layer base {
|
||||
*,
|
||||
::after,
|
||||
::before,
|
||||
::backdrop,
|
||||
::file-selector-button {
|
||||
border-color: var(--color-gray-200, currentColor);
|
||||
}
|
||||
}
|
||||
|
||||
@layer base {
|
||||
#spark-app {
|
||||
--tomato-contrast: #fff;
|
||||
--red-contrast: #fff;
|
||||
--ruby-contrast: #fff;
|
||||
--crimson-contrast: #fff;
|
||||
--pink-contrast: #fff;
|
||||
--plum-contrast: #fff;
|
||||
--purple-contrast: #fff;
|
||||
--violet-contrast: #fff;
|
||||
--iris-contrast: #fff;
|
||||
--indigo-contrast: #fff;
|
||||
--blue-contrast: #fff;
|
||||
--cyan-contrast: #fff;
|
||||
--teal-contrast: #fff;
|
||||
--jade-contrast: #fff;
|
||||
--green-contrast: #fff;
|
||||
--grass-contrast: #fff;
|
||||
--bronze-contrast: #fff;
|
||||
--gold-contrast: #fff;
|
||||
--brown-contrast: #fff;
|
||||
--orange-contrast: #fff;
|
||||
--amber-contrast: #000;
|
||||
--yellow-contrast: #000;
|
||||
--lime-contrast: #000;
|
||||
--mint-contrast: #000;
|
||||
--sky-contrast: #000;
|
||||
--gray-contrast: #fff;
|
||||
--mauve-contrast: #fff;
|
||||
--slate-contrast: #fff;
|
||||
--sage-contrast: #fff;
|
||||
--olive-contrast: #fff;
|
||||
--sand-contrast: #fff;
|
||||
|
||||
/**
|
||||
* Spacing scale
|
||||
*
|
||||
* These variables define a spacing scale based on Tailwind's default.
|
||||
* We've introduced a --size-scale variable as a multiplier.
|
||||
* By adjusting this single value, we can proportionally
|
||||
* scale all spacing throughout the entire application.
|
||||
*
|
||||
* https://tailwindcss.com/docs/customizing-spacing#default-spacing-scale
|
||||
*/
|
||||
--size-scale: 1;
|
||||
--size-0: 0px;
|
||||
--size-px: 1px;
|
||||
--size-0-5: calc(0.125rem * var(--size-scale));
|
||||
--size-1: calc(0.25rem * var(--size-scale));
|
||||
--size-1-5: calc(0.375rem * var(--size-scale));
|
||||
--size-2: calc(0.5rem * var(--size-scale));
|
||||
--size-2-5: calc(0.625rem * var(--size-scale));
|
||||
--size-3: calc(0.75rem * var(--size-scale));
|
||||
--size-3-5: calc(0.875rem * var(--size-scale));
|
||||
--size-4: calc(1rem * var(--size-scale));
|
||||
--size-5: calc(1.25rem * var(--size-scale));
|
||||
--size-6: calc(1.5rem * var(--size-scale));
|
||||
--size-7: calc(1.75rem * var(--size-scale));
|
||||
--size-8: calc(2rem * var(--size-scale));
|
||||
--size-9: calc(2.25rem * var(--size-scale));
|
||||
--size-10: calc(2.5rem * var(--size-scale));
|
||||
--size-11: calc(2.75rem * var(--size-scale));
|
||||
--size-12: calc(3rem * var(--size-scale));
|
||||
--size-14: calc(3.5rem * var(--size-scale));
|
||||
--size-16: calc(4rem * var(--size-scale));
|
||||
--size-20: calc(5rem * var(--size-scale));
|
||||
--size-24: calc(6rem * var(--size-scale));
|
||||
--size-28: calc(7rem * var(--size-scale));
|
||||
--size-32: calc(8rem * var(--size-scale));
|
||||
--size-36: calc(9rem * var(--size-scale));
|
||||
--size-40: calc(10rem * var(--size-scale));
|
||||
--size-44: calc(11rem * var(--size-scale));
|
||||
--size-48: calc(12rem * var(--size-scale));
|
||||
--size-52: calc(13rem * var(--size-scale));
|
||||
--size-56: calc(14rem * var(--size-scale));
|
||||
--size-60: calc(15rem * var(--size-scale));
|
||||
--size-64: calc(16rem * var(--size-scale));
|
||||
--size-72: calc(18rem * var(--size-scale));
|
||||
--size-80: calc(20rem * var(--size-scale));
|
||||
--size-96: calc(24rem * var(--size-scale));
|
||||
|
||||
/* Border radii */
|
||||
--radius-factor: 1;
|
||||
--radius-sm: calc(2px * var(--radius-factor) * var(--size-scale));
|
||||
--radius-md: calc(6px * var(--radius-factor) * var(--size-scale));
|
||||
--radius-lg: calc(8px * var(--radius-factor) * var(--size-scale));
|
||||
--radius-xl: calc(12px * var(--radius-factor) * var(--size-scale));
|
||||
--radius-2xl: calc(16px * var(--radius-factor) * var(--size-scale));
|
||||
--radius-full: 9999px;
|
||||
|
||||
/* Neutral colors */
|
||||
--color-neutral-1: var(--slate-1);
|
||||
--color-neutral-2: var(--slate-2);
|
||||
--color-neutral-3: var(--slate-3);
|
||||
--color-neutral-4: var(--slate-4);
|
||||
--color-neutral-5: var(--slate-5);
|
||||
--color-neutral-6: var(--slate-6);
|
||||
--color-neutral-7: var(--slate-7);
|
||||
--color-neutral-8: var(--slate-8);
|
||||
--color-neutral-9: var(--slate-9);
|
||||
--color-neutral-10: var(--slate-10);
|
||||
--color-neutral-11: var(--slate-11);
|
||||
--color-neutral-12: var(--slate-12);
|
||||
--color-neutral-a1: var(--slate-a1);
|
||||
--color-neutral-a2: var(--slate-a2);
|
||||
--color-neutral-a3: var(--slate-a3);
|
||||
--color-neutral-a4: var(--slate-a4);
|
||||
--color-neutral-a5: var(--slate-a5);
|
||||
--color-neutral-a6: var(--slate-a6);
|
||||
--color-neutral-a7: var(--slate-a7);
|
||||
--color-neutral-a8: var(--slate-a8);
|
||||
--color-neutral-a9: var(--slate-a9);
|
||||
--color-neutral-a10: var(--slate-a10);
|
||||
--color-neutral-a11: var(--slate-a11);
|
||||
--color-neutral-a12: var(--slate-a12);
|
||||
--color-neutral-contrast: var(--slate-contrast);
|
||||
|
||||
/* Accent colors */
|
||||
--color-accent-1: var(--blue-1);
|
||||
--color-accent-2: var(--blue-2);
|
||||
--color-accent-3: var(--blue-3);
|
||||
--color-accent-4: var(--blue-4);
|
||||
--color-accent-5: var(--blue-5);
|
||||
--color-accent-6: var(--blue-6);
|
||||
--color-accent-7: var(--blue-7);
|
||||
--color-accent-8: var(--blue-8);
|
||||
--color-accent-9: var(--blue-9);
|
||||
--color-accent-10: var(--blue-10);
|
||||
--color-accent-11: var(--blue-11);
|
||||
--color-accent-12: var(--blue-12);
|
||||
--color-accent-contrast: var(--blue-contrast);
|
||||
|
||||
/* Secondary accent colors */
|
||||
--color-accent-secondary-1: var(--violet-1);
|
||||
--color-accent-secondary-2: var(--violet-2);
|
||||
--color-accent-secondary-3: var(--violet-3);
|
||||
--color-accent-secondary-4: var(--violet-4);
|
||||
--color-accent-secondary-5: var(--violet-5);
|
||||
--color-accent-secondary-6: var(--violet-6);
|
||||
--color-accent-secondary-7: var(--violet-7);
|
||||
--color-accent-secondary-8: var(--violet-8);
|
||||
--color-accent-secondary-9: var(--violet-9);
|
||||
--color-accent-secondary-10: var(--violet-10);
|
||||
--color-accent-secondary-11: var(--violet-11);
|
||||
--color-accent-secondary-12: var(--violet-12);
|
||||
--color-accent-secondary-contrast: var(--violet-contrast);
|
||||
|
||||
/* Foreground colors */
|
||||
--color-fg: var(--color-neutral-12);
|
||||
--color-fg-secondary: var(--color-neutral-a11);
|
||||
|
||||
/* Background colors */
|
||||
--color-bg: #ffffff;
|
||||
--color-bg-inset: var(--color-neutral-2);
|
||||
--color-bg-overlay: #ffffff;
|
||||
|
||||
/* Focus ring */
|
||||
--color-focus-ring: var(--color-accent-9);
|
||||
|
||||
/* Fonts */
|
||||
--font-sans-serif: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji",
|
||||
"Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
||||
--font-serif: ui-serif, Georgia, Cambria, "Times New Roman", Times, serif;
|
||||
--font-monospace: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas,
|
||||
"Liberation Mono", "Courier New", monospace;
|
||||
--font-family: var(--font-sans-serif);
|
||||
}
|
||||
|
||||
#spark-app.dark-theme {
|
||||
--color-bg: var(--color-neutral-1);
|
||||
--color-bg-inset: #000000;
|
||||
--color-bg-overlay: var(--color-neutral-3);
|
||||
}
|
||||
}
|
||||
75
src/app/theme.scss
Normal file
75
src/app/theme.scss
Normal file
@@ -0,0 +1,75 @@
|
||||
// Radix UI Colors imports (keeping the color system)
|
||||
@import '@radix-ui/colors/sage-dark.css';
|
||||
@import '@radix-ui/colors/slate.css';
|
||||
@import '@radix-ui/colors/slate-dark.css';
|
||||
@import '@radix-ui/colors/blue.css';
|
||||
@import '@radix-ui/colors/blue-dark.css';
|
||||
@import '@radix-ui/colors/violet.css';
|
||||
@import '@radix-ui/colors/violet-dark.css';
|
||||
|
||||
// Spacing scale variables
|
||||
$size-scale: 1;
|
||||
$size-0: 0px;
|
||||
$size-px: 1px;
|
||||
$size-0-5: calc(0.125rem * $size-scale);
|
||||
$size-1: calc(0.25rem * $size-scale);
|
||||
$size-2: calc(0.5rem * $size-scale);
|
||||
$size-3: calc(0.75rem * $size-scale);
|
||||
$size-4: calc(1rem * $size-scale);
|
||||
$size-5: calc(1.25rem * $size-scale);
|
||||
$size-6: calc(1.5rem * $size-scale);
|
||||
$size-8: calc(2rem * $size-scale);
|
||||
$size-10: calc(2.5rem * $size-scale);
|
||||
$size-12: calc(3rem * $size-scale);
|
||||
$size-16: calc(4rem * $size-scale);
|
||||
$size-20: calc(5rem * $size-scale);
|
||||
$size-24: calc(6rem * $size-scale);
|
||||
|
||||
// Border radii
|
||||
$radius-factor: 1;
|
||||
$radius-sm: calc(2px * $radius-factor * $size-scale);
|
||||
$radius-md: calc(6px * $radius-factor * $size-scale);
|
||||
$radius-lg: calc(8px * $radius-factor * $size-scale);
|
||||
$radius-xl: calc(12px * $radius-factor * $size-scale);
|
||||
$radius-full: 9999px;
|
||||
|
||||
// App-level CSS variables
|
||||
#spark-app {
|
||||
--size-scale: #{$size-scale};
|
||||
--radius-factor: #{$radius-factor};
|
||||
|
||||
// Neutral colors (using slate from Radix)
|
||||
--color-neutral-1: var(--slate-1);
|
||||
--color-neutral-2: var(--slate-2);
|
||||
--color-neutral-3: var(--slate-3);
|
||||
--color-neutral-11: var(--slate-11);
|
||||
--color-neutral-12: var(--slate-12);
|
||||
|
||||
// Accent colors (using blue from Radix)
|
||||
--color-accent-9: var(--blue-9);
|
||||
--color-accent-11: var(--blue-11);
|
||||
|
||||
// Foreground colors
|
||||
--color-fg: var(--color-neutral-12);
|
||||
--color-fg-secondary: var(--color-neutral-11);
|
||||
|
||||
// Background colors
|
||||
--color-bg: #ffffff;
|
||||
--color-bg-inset: var(--color-neutral-2);
|
||||
--color-bg-overlay: #ffffff;
|
||||
|
||||
// Focus ring
|
||||
--color-focus-ring: var(--color-accent-9);
|
||||
|
||||
// Fonts
|
||||
--font-sans-serif: ui-sans-serif, system-ui, sans-serif;
|
||||
--font-serif: ui-serif, Georgia, serif;
|
||||
--font-monospace: ui-monospace, 'SF Mono', Monaco, Consolas, monospace;
|
||||
--font-family: var(--font-sans-serif);
|
||||
}
|
||||
|
||||
#spark-app.dark-theme {
|
||||
--color-bg: var(--color-neutral-1);
|
||||
--color-bg-inset: #000000;
|
||||
--color-bg-overlay: var(--color-neutral-3);
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
import { clsx, type ClassValue } from "clsx"
|
||||
import { twMerge } from "tailwind-merge"
|
||||
|
||||
export function cn(...inputs: ClassValue[]) {
|
||||
return twMerge(clsx(inputs))
|
||||
return clsx(inputs)
|
||||
}
|
||||
|
||||
24
src/styles/abstracts/_functions.scss
Normal file
24
src/styles/abstracts/_functions.scss
Normal file
@@ -0,0 +1,24 @@
|
||||
// Spacing function
|
||||
@function spacing($key) {
|
||||
@return map-get($spacing, $key);
|
||||
}
|
||||
|
||||
// Border radius function
|
||||
@function radius($key) {
|
||||
@return map-get($radius, $key);
|
||||
}
|
||||
|
||||
// Font size function
|
||||
@function font-size($key) {
|
||||
@return map-get($font-sizes, $key);
|
||||
}
|
||||
|
||||
// Font weight function
|
||||
@function font-weight($key) {
|
||||
@return map-get($font-weights, $key);
|
||||
}
|
||||
|
||||
// Breakpoint function
|
||||
@function breakpoint($key) {
|
||||
@return map-get($breakpoints, $key);
|
||||
}
|
||||
3
src/styles/abstracts/_index.scss
Normal file
3
src/styles/abstracts/_index.scss
Normal file
@@ -0,0 +1,3 @@
|
||||
@import './variables';
|
||||
@import './functions';
|
||||
@import './mixins';
|
||||
212
src/styles/abstracts/_mixins.scss
Normal file
212
src/styles/abstracts/_mixins.scss
Normal file
@@ -0,0 +1,212 @@
|
||||
// Flexbox mixins
|
||||
@mixin flex($direction: row, $justify: flex-start, $align: stretch, $wrap: nowrap) {
|
||||
display: flex;
|
||||
flex-direction: $direction;
|
||||
justify-content: $justify;
|
||||
align-items: $align;
|
||||
flex-wrap: $wrap;
|
||||
}
|
||||
|
||||
@mixin flex-center {
|
||||
@include flex(row, center, center);
|
||||
}
|
||||
|
||||
@mixin flex-between {
|
||||
@include flex(row, space-between, center);
|
||||
}
|
||||
|
||||
@mixin flex-col {
|
||||
@include flex(column, flex-start, stretch);
|
||||
}
|
||||
|
||||
// Grid mixin
|
||||
@mixin grid($columns: 1, $gap: spacing(4)) {
|
||||
display: grid;
|
||||
grid-template-columns: repeat($columns, 1fr);
|
||||
gap: $gap;
|
||||
}
|
||||
|
||||
// Spacing mixins
|
||||
@mixin p($value) {
|
||||
padding: spacing($value);
|
||||
}
|
||||
|
||||
@mixin px($value) {
|
||||
padding-left: spacing($value);
|
||||
padding-right: spacing($value);
|
||||
}
|
||||
|
||||
@mixin py($value) {
|
||||
padding-top: spacing($value);
|
||||
padding-bottom: spacing($value);
|
||||
}
|
||||
|
||||
@mixin pt($value) {
|
||||
padding-top: spacing($value);
|
||||
}
|
||||
|
||||
@mixin pr($value) {
|
||||
padding-right: spacing($value);
|
||||
}
|
||||
|
||||
@mixin pb($value) {
|
||||
padding-bottom: spacing($value);
|
||||
}
|
||||
|
||||
@mixin pl($value) {
|
||||
padding-left: spacing($value);
|
||||
}
|
||||
|
||||
@mixin m($value) {
|
||||
margin: spacing($value);
|
||||
}
|
||||
|
||||
@mixin mx($value) {
|
||||
margin-left: spacing($value);
|
||||
margin-right: spacing($value);
|
||||
}
|
||||
|
||||
@mixin my($value) {
|
||||
margin-top: spacing($value);
|
||||
margin-bottom: spacing($value);
|
||||
}
|
||||
|
||||
@mixin mt($value) {
|
||||
margin-top: spacing($value);
|
||||
}
|
||||
|
||||
@mixin mr($value) {
|
||||
margin-right: spacing($value);
|
||||
}
|
||||
|
||||
@mixin mb($value) {
|
||||
margin-bottom: spacing($value);
|
||||
}
|
||||
|
||||
@mixin ml($value) {
|
||||
margin-left: spacing($value);
|
||||
}
|
||||
|
||||
// Gap mixin
|
||||
@mixin gap($value) {
|
||||
gap: spacing($value);
|
||||
}
|
||||
|
||||
// Border radius mixin
|
||||
@mixin rounded($value: base) {
|
||||
border-radius: radius($value);
|
||||
}
|
||||
|
||||
// Typography mixins
|
||||
@mixin text($size) {
|
||||
font-size: font-size($size);
|
||||
}
|
||||
|
||||
@mixin font($weight) {
|
||||
font-weight: font-weight($weight);
|
||||
}
|
||||
|
||||
// Responsive breakpoint mixin
|
||||
@mixin respond-to($breakpoint) {
|
||||
$size: breakpoint($breakpoint);
|
||||
@media (min-width: $size) {
|
||||
@content;
|
||||
}
|
||||
}
|
||||
|
||||
// Button base styles mixin
|
||||
@mixin button-base {
|
||||
@include px(4);
|
||||
@include py(2);
|
||||
@include rounded(md);
|
||||
@include font(medium);
|
||||
@include text(sm);
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: spacing(2);
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
border: none;
|
||||
outline: none;
|
||||
|
||||
&:disabled {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
|
||||
// Card mixin
|
||||
@mixin card {
|
||||
background: $card;
|
||||
color: $card-foreground;
|
||||
border: 1px solid $border;
|
||||
@include rounded(lg);
|
||||
@include p(6);
|
||||
}
|
||||
|
||||
// Shadow mixins
|
||||
@mixin shadow-sm {
|
||||
box-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);
|
||||
}
|
||||
|
||||
@mixin shadow {
|
||||
box-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);
|
||||
}
|
||||
|
||||
@mixin shadow-md {
|
||||
box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
|
||||
}
|
||||
|
||||
@mixin shadow-lg {
|
||||
box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
|
||||
}
|
||||
|
||||
// Transition mixin
|
||||
@mixin transition($properties: all, $duration: 0.2s, $timing: ease) {
|
||||
transition: $properties $duration $timing;
|
||||
}
|
||||
|
||||
// Truncate text
|
||||
@mixin truncate {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
// Visually hidden (for accessibility)
|
||||
@mixin sr-only {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
padding: 0;
|
||||
margin: -1px;
|
||||
overflow: hidden;
|
||||
clip: rect(0, 0, 0, 0);
|
||||
white-space: nowrap;
|
||||
border-width: 0;
|
||||
}
|
||||
|
||||
// Absolute positioning shortcuts
|
||||
@mixin absolute-center {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
@mixin absolute-fill {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
// Focus ring
|
||||
@mixin focus-ring {
|
||||
&:focus-visible {
|
||||
outline: 2px solid $ring;
|
||||
outline-offset: 2px;
|
||||
}
|
||||
}
|
||||
119
src/styles/abstracts/_variables.scss
Normal file
119
src/styles/abstracts/_variables.scss
Normal file
@@ -0,0 +1,119 @@
|
||||
// Color Variables
|
||||
$background: hsl(222.2, 84%, 4.9%);
|
||||
$foreground: hsl(210, 40%, 98%);
|
||||
$card: hsl(222.2, 84%, 4.9%);
|
||||
$card-foreground: hsl(210, 40%, 98%);
|
||||
$popover: hsl(222.2, 84%, 4.9%);
|
||||
$popover-foreground: hsl(210, 40%, 98%);
|
||||
$primary: hsl(263, 70%, 50%);
|
||||
$primary-foreground: hsl(210, 40%, 98%);
|
||||
$secondary: hsl(217.2, 32.6%, 17.5%);
|
||||
$secondary-foreground: hsl(210, 40%, 98%);
|
||||
$muted: hsl(217.2, 32.6%, 17.5%);
|
||||
$muted-foreground: hsl(215, 20.2%, 65.1%);
|
||||
$accent: hsl(195, 100%, 70%);
|
||||
$accent-foreground: hsl(222.2, 84%, 4.9%);
|
||||
$destructive: hsl(0, 62.8%, 30.6%);
|
||||
$destructive-foreground: hsl(210, 40%, 98%);
|
||||
$border: hsl(217.2, 32.6%, 17.5%);
|
||||
$input: hsl(217.2, 32.6%, 17.5%);
|
||||
$ring: hsl(195, 100%, 70%);
|
||||
|
||||
// Spacing Scale
|
||||
$spacing: (
|
||||
0: 0,
|
||||
px: 1px,
|
||||
0-5: 0.125rem,
|
||||
1: 0.25rem,
|
||||
1-5: 0.375rem,
|
||||
2: 0.5rem,
|
||||
2-5: 0.625rem,
|
||||
3: 0.75rem,
|
||||
3-5: 0.875rem,
|
||||
4: 1rem,
|
||||
5: 1.25rem,
|
||||
6: 1.5rem,
|
||||
7: 1.75rem,
|
||||
8: 2rem,
|
||||
9: 2.25rem,
|
||||
10: 2.5rem,
|
||||
11: 2.75rem,
|
||||
12: 3rem,
|
||||
14: 3.5rem,
|
||||
16: 4rem,
|
||||
20: 5rem,
|
||||
24: 6rem,
|
||||
28: 7rem,
|
||||
32: 8rem,
|
||||
36: 9rem,
|
||||
40: 10rem,
|
||||
48: 12rem,
|
||||
56: 14rem,
|
||||
64: 16rem,
|
||||
72: 18rem,
|
||||
80: 20rem,
|
||||
96: 24rem,
|
||||
);
|
||||
|
||||
// Border Radius
|
||||
$radius: (
|
||||
none: 0,
|
||||
sm: 0.125rem,
|
||||
base: 0.25rem,
|
||||
md: 0.375rem,
|
||||
lg: 0.5rem,
|
||||
xl: 0.75rem,
|
||||
2xl: 1rem,
|
||||
3xl: 1.5rem,
|
||||
full: 9999px,
|
||||
);
|
||||
|
||||
// Font Sizes
|
||||
$font-sizes: (
|
||||
xs: 0.75rem,
|
||||
sm: 0.875rem,
|
||||
base: 1rem,
|
||||
lg: 1.125rem,
|
||||
xl: 1.25rem,
|
||||
2xl: 1.5rem,
|
||||
3xl: 1.875rem,
|
||||
4xl: 2.25rem,
|
||||
5xl: 3rem,
|
||||
6xl: 3.75rem,
|
||||
7xl: 4.5rem,
|
||||
8xl: 6rem,
|
||||
9xl: 8rem,
|
||||
);
|
||||
|
||||
// Font Weights
|
||||
$font-weights: (
|
||||
thin: 100,
|
||||
extralight: 200,
|
||||
light: 300,
|
||||
normal: 400,
|
||||
medium: 500,
|
||||
semibold: 600,
|
||||
bold: 700,
|
||||
extrabold: 800,
|
||||
black: 900,
|
||||
);
|
||||
|
||||
// Breakpoints
|
||||
$breakpoints: (
|
||||
sm: 640px,
|
||||
md: 768px,
|
||||
lg: 1024px,
|
||||
xl: 1280px,
|
||||
2xl: 1536px,
|
||||
);
|
||||
|
||||
// Z-index scale
|
||||
$z-index: (
|
||||
0: 0,
|
||||
10: 10,
|
||||
20: 20,
|
||||
30: 30,
|
||||
40: 40,
|
||||
50: 50,
|
||||
auto: auto,
|
||||
);
|
||||
146
src/styles/utilities/_utilities.scss
Normal file
146
src/styles/utilities/_utilities.scss
Normal file
@@ -0,0 +1,146 @@
|
||||
@import '../abstracts';
|
||||
|
||||
// Utility classes generator
|
||||
@each $name, $value in $spacing {
|
||||
.p-#{$name} { padding: $value !important; }
|
||||
.px-#{$name} { padding-left: $value !important; padding-right: $value !important; }
|
||||
.py-#{$name} { padding-top: $value !important; padding-bottom: $value !important; }
|
||||
.pt-#{$name} { padding-top: $value !important; }
|
||||
.pr-#{$name} { padding-right: $value !important; }
|
||||
.pb-#{$name} { padding-bottom: $value !important; }
|
||||
.pl-#{$name} { padding-left: $value !important; }
|
||||
|
||||
.m-#{$name} { margin: $value !important; }
|
||||
.mx-#{$name} { margin-left: $value !important; margin-right: $value !important; }
|
||||
.my-#{$name} { margin-top: $value !important; margin-bottom: $value !important; }
|
||||
.mt-#{$name} { margin-top: $value !important; }
|
||||
.mr-#{$name} { margin-right: $value !important; }
|
||||
.mb-#{$name} { margin-bottom: $value !important; }
|
||||
.ml-#{$name} { margin-left: $value !important; }
|
||||
|
||||
.gap-#{$name} { gap: $value !important; }
|
||||
}
|
||||
|
||||
// Flexbox utilities
|
||||
.flex { display: flex !important; }
|
||||
.inline-flex { display: inline-flex !important; }
|
||||
.flex-row { flex-direction: row !important; }
|
||||
.flex-col { flex-direction: column !important; }
|
||||
.flex-wrap { flex-wrap: wrap !important; }
|
||||
.flex-nowrap { flex-wrap: nowrap !important; }
|
||||
.flex-1 { flex: 1 1 0% !important; }
|
||||
|
||||
// Justify content
|
||||
.justify-start { justify-content: flex-start !important; }
|
||||
.justify-end { justify-content: flex-end !important; }
|
||||
.justify-center { justify-content: center !important; }
|
||||
.justify-between { justify-content: space-between !important; }
|
||||
.justify-around { justify-content: space-around !important; }
|
||||
|
||||
// Align items
|
||||
.items-start { align-items: flex-start !important; }
|
||||
.items-end { align-items: flex-end !important; }
|
||||
.items-center { align-items: center !important; }
|
||||
.items-stretch { align-items: stretch !important; }
|
||||
|
||||
// Grid
|
||||
.grid { display: grid !important; }
|
||||
.grid-cols-1 { grid-template-columns: repeat(1, minmax(0, 1fr)) !important; }
|
||||
.grid-cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)) !important; }
|
||||
.grid-cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)) !important; }
|
||||
.grid-cols-4 { grid-template-columns: repeat(4, minmax(0, 1fr)) !important; }
|
||||
|
||||
// Border radius
|
||||
@each $name, $value in $radius {
|
||||
.rounded-#{$name} { border-radius: $value !important; }
|
||||
}
|
||||
|
||||
// Text sizes
|
||||
@each $name, $value in $font-sizes {
|
||||
.text-#{$name} { font-size: $value !important; }
|
||||
}
|
||||
|
||||
// Font weights
|
||||
@each $name, $value in $font-weights {
|
||||
.font-#{$name} { font-weight: $value !important; }
|
||||
}
|
||||
|
||||
// Text align
|
||||
.text-left { text-align: left !important; }
|
||||
.text-center { text-align: center !important; }
|
||||
.text-right { text-align: right !important; }
|
||||
|
||||
// Colors
|
||||
.text-foreground { color: $foreground !important; }
|
||||
.text-muted-foreground { color: $muted-foreground !important; }
|
||||
.text-primary { color: $primary !important; }
|
||||
.text-destructive { color: $destructive !important; }
|
||||
.text-accent { color: $accent !important; }
|
||||
|
||||
.bg-background { background-color: $background !important; }
|
||||
.bg-card { background-color: $card !important; }
|
||||
.bg-primary { background-color: $primary !important; }
|
||||
.bg-secondary { background-color: $secondary !important; }
|
||||
.bg-muted { background-color: $muted !important; }
|
||||
.bg-accent { background-color: $accent !important; }
|
||||
.bg-destructive { background-color: $destructive !important; }
|
||||
|
||||
// Border
|
||||
.border { border: 1px solid $border !important; }
|
||||
.border-b { border-bottom: 1px solid $border !important; }
|
||||
.border-t { border-top: 1px solid $border !important; }
|
||||
.border-l { border-left: 1px solid $border !important; }
|
||||
.border-r { border-right: 1px solid $border !important; }
|
||||
|
||||
// Width & Height
|
||||
.w-full { width: 100% !important; }
|
||||
.h-full { height: 100% !important; }
|
||||
.min-h-screen { min-height: 100vh !important; }
|
||||
.max-w-3xl { max-width: 48rem !important; }
|
||||
.max-w-7xl { max-width: 80rem !important; }
|
||||
|
||||
// Position
|
||||
.relative { position: relative !important; }
|
||||
.absolute { position: absolute !important; }
|
||||
.fixed { position: fixed !important; }
|
||||
.sticky { position: sticky !important; }
|
||||
|
||||
// Display
|
||||
.hidden { display: none !important; }
|
||||
.block { display: block !important; }
|
||||
.inline-block { display: inline-block !important; }
|
||||
|
||||
// Overflow
|
||||
.overflow-hidden { overflow: hidden !important; }
|
||||
.overflow-auto { overflow: auto !important; }
|
||||
.overflow-scroll { overflow: scroll !important; }
|
||||
|
||||
// Cursor
|
||||
.cursor-pointer { cursor: pointer !important; }
|
||||
.cursor-not-allowed { cursor: not-allowed !important; }
|
||||
|
||||
// Opacity
|
||||
.opacity-50 { opacity: 0.5 !important; }
|
||||
.opacity-75 { opacity: 0.75 !important; }
|
||||
.opacity-100 { opacity: 1 !important; }
|
||||
|
||||
// Transitions
|
||||
.transition { transition: all 0.2s ease !important; }
|
||||
.transition-colors { transition: color 0.2s ease, background-color 0.2s ease, border-color 0.2s ease !important; }
|
||||
|
||||
// Shadow
|
||||
.shadow-sm { @include shadow-sm; }
|
||||
.shadow { @include shadow; }
|
||||
.shadow-md { @include shadow-md; }
|
||||
.shadow-lg { @include shadow-lg; }
|
||||
|
||||
// Space between children
|
||||
.space-y-2 > * + * { margin-top: spacing(2) !important; }
|
||||
.space-y-3 > * + * { margin-top: spacing(3) !important; }
|
||||
.space-y-4 > * + * { margin-top: spacing(4) !important; }
|
||||
.space-y-6 > * + * { margin-top: spacing(6) !important; }
|
||||
.space-y-8 > * + * { margin-top: spacing(8) !important; }
|
||||
|
||||
.space-x-2 > * + * { margin-left: spacing(2) !important; }
|
||||
.space-x-3 > * + * { margin-left: spacing(3) !important; }
|
||||
.space-x-4 > * + * { margin-left: spacing(4) !important; }
|
||||
@@ -1,62 +0,0 @@
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
export default {
|
||||
darkMode: ["class"],
|
||||
content: [
|
||||
'./src/pages/**/*.{ts,tsx}',
|
||||
'./src/components/**/*.{ts,tsx}',
|
||||
'./src/app/**/*.{ts,tsx}',
|
||||
'./src/**/*.{ts,tsx}',
|
||||
],
|
||||
theme: {
|
||||
container: {
|
||||
center: true,
|
||||
padding: "2rem",
|
||||
screens: {
|
||||
"2xl": "1400px",
|
||||
},
|
||||
},
|
||||
extend: {
|
||||
colors: {
|
||||
border: "hsl(var(--border))",
|
||||
input: "hsl(var(--input))",
|
||||
ring: "hsl(var(--ring))",
|
||||
background: "hsl(var(--background))",
|
||||
foreground: "hsl(var(--foreground))",
|
||||
primary: {
|
||||
DEFAULT: "hsl(var(--primary))",
|
||||
foreground: "hsl(var(--primary-foreground))",
|
||||
},
|
||||
secondary: {
|
||||
DEFAULT: "hsl(var(--secondary))",
|
||||
foreground: "hsl(var(--secondary-foreground))",
|
||||
},
|
||||
destructive: {
|
||||
DEFAULT: "hsl(var(--destructive))",
|
||||
foreground: "hsl(var(--destructive-foreground))",
|
||||
},
|
||||
muted: {
|
||||
DEFAULT: "hsl(var(--muted))",
|
||||
foreground: "hsl(var(--muted-foreground))",
|
||||
},
|
||||
accent: {
|
||||
DEFAULT: "hsl(var(--accent))",
|
||||
foreground: "hsl(var(--accent-foreground))",
|
||||
},
|
||||
popover: {
|
||||
DEFAULT: "hsl(var(--popover))",
|
||||
foreground: "hsl(var(--popover-foreground))",
|
||||
},
|
||||
card: {
|
||||
DEFAULT: "hsl(var(--card))",
|
||||
foreground: "hsl(var(--card-foreground))",
|
||||
},
|
||||
},
|
||||
borderRadius: {
|
||||
lg: "var(--radius)",
|
||||
md: "calc(var(--radius) - 2px)",
|
||||
sm: "calc(var(--radius) - 4px)",
|
||||
},
|
||||
},
|
||||
},
|
||||
plugins: [],
|
||||
}
|
||||
Reference in New Issue
Block a user