feat: add stylelint for SCSS and CSS, update theme and global styles

- Added stylelint scripts to package.json for linting SCSS and CSS files.
- Updated global styles to remove quotes from font-family declarations and changed `currentColor` to `currentcolor`.
- Refactored theme.scss to use shorthand hex color codes and updated font-family declarations.
- Modified carousel component to remove unnecessary onSelect call.
- Enhanced useSnippetForm hook with comments and ESLint disable/enable for clarity.
- Improved mixins in _mixins.scss for flexbox and responsive breakpoints.
- Updated color definitions in _variables.scss to use the `hsl()` format with degrees.
- Changed button and dialog styles to use `currentcolor` for background.
- Adjusted header styles for box-shadow and gradient backgrounds.
- Refined typography styles to ensure consistent font-family usage.
- Enhanced utility classes in _utilities.scss for better readability and maintainability.
This commit is contained in:
2026-01-20 00:06:44 +00:00
parent f25e5e0597
commit 9ae6776f37
16 changed files with 1738 additions and 216 deletions

5
.stylelintignore Normal file
View File

@@ -0,0 +1,5 @@
.next
node_modules
dist
coverage
**/generated/**

4
.stylelintrc.json Normal file
View File

@@ -0,0 +1,4 @@
{
"extends": ["stylelint-config-standard-scss"],
"rules": {}
}

View File

@@ -18,8 +18,6 @@ export default [
},
rules: {
...reactHooks.configs.recommended.rules,
'react-hooks/set-state-in-effect': 'off',
'react-hooks/purity': 'off',
},
},
{

1341
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -8,6 +8,7 @@
"build": "next build",
"start": "next start",
"lint": "eslint .",
"stylelint": "stylelint \"src/**/*.{scss,css}\"",
"kill": "fuser -k 5000/tcp"
},
"dependencies": {
@@ -74,6 +75,9 @@
"eslint-config-next": "^16.1.3",
"eslint-plugin-react-hooks": "^7.0.1",
"globals": "^16.0.0",
"stylelint": "^17.0.0",
"stylelint-config-standard-scss": "^17.0.0",
"stylelint-scss": "^7.0.0",
"typescript": "~5.9.3",
"typescript-eslint": "^8.53.1"
},

View File

@@ -1,7 +1,7 @@
@use '../styles/abstracts' as *;
@use '../styles/utilities/utilities';
@use '../styles/components';
@use './theme.scss';
@use './theme';
// Global resets
* {
@@ -23,7 +23,7 @@
body {
background: $background;
color: $foreground;
font-family: var(--font-inter), 'Inter', 'Roboto', system-ui, sans-serif;
font-family: var(--font-inter), Inter, Roboto, system-ui, sans-serif;
font-size: $font-body-medium;
line-height: $line-height-body-medium;
letter-spacing: $letter-spacing-body;
@@ -150,7 +150,7 @@ body {
// Typography base for headings
h1, h2, h3, h4, h5, h6 {
font-family: var(--font-inter), 'Inter', 'Roboto', system-ui, sans-serif;
font-family: var(--font-inter), Inter, Roboto, system-ui, sans-serif;
font-weight: 400;
letter-spacing: $letter-spacing-headline;
}
@@ -409,7 +409,7 @@ code, pre {
content: '';
position: absolute;
inset: 0;
background-color: currentColor;
background-color: currentcolor;
opacity: 0;
transition: opacity $duration-short-4 $easing-standard;
pointer-events: none;
@@ -438,6 +438,7 @@ code, pre {
transform: scale(0);
opacity: 0.12;
}
to {
transform: scale(4);
opacity: 0;
@@ -456,7 +457,7 @@ code, pre {
top: 50%;
left: 50%;
transform: translate(-50%, -50%) scale(0);
background: radial-gradient(circle, currentColor 10%, transparent 10.01%);
background: radial-gradient(circle, currentcolor 10%, transparent 10.01%);
opacity: 0;
pointer-events: none;
border-radius: 50%;
@@ -476,6 +477,7 @@ code, pre {
height: 0;
opacity: 0;
}
to {
height: var(--radix-accordion-content-height);
opacity: 1;
@@ -487,6 +489,7 @@ code, pre {
height: var(--radix-accordion-content-height);
opacity: 1;
}
to {
height: 0;
opacity: 0;
@@ -497,6 +500,7 @@ code, pre {
from {
opacity: 0;
}
to {
opacity: 1;
}
@@ -506,6 +510,7 @@ code, pre {
from {
opacity: 1;
}
to {
opacity: 0;
}
@@ -516,6 +521,7 @@ code, pre {
opacity: 0;
transform: scale(0.8);
}
to {
opacity: 1;
transform: scale(1);
@@ -527,6 +533,7 @@ code, pre {
opacity: 0;
transform: translateY(100%);
}
to {
opacity: 1;
transform: translateY(0);
@@ -538,6 +545,7 @@ code, pre {
opacity: 0;
transform: translateX(100%);
}
to {
opacity: 1;
transform: translateX(0);

View File

@@ -25,22 +25,22 @@
--color-fg-secondary: var(--color-neutral-11);
// Background colors
--color-bg: #ffffff;
--color-bg: #fff;
--color-bg-inset: var(--color-neutral-2);
--color-bg-overlay: #ffffff;
--color-bg-overlay: #fff;
// 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-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-inset: #000;
--color-bg-overlay: var(--color-neutral-3);
}

View File

@@ -96,7 +96,6 @@ function Carousel({
useEffect(() => {
if (!api) return
onSelect(api)
api.on("reInit", onSelect)
api.on("select", onSelect)

View File

@@ -12,6 +12,9 @@ export function useSnippetForm(editingSnippet?: Snippet | null, open?: boolean)
const [inputParameters, setInputParameters] = useState<InputParameter[]>([])
const [errors, setErrors] = useState<{ title?: string; code?: string }>({})
/* eslint-disable react-hooks/set-state-in-effect */
// This effect hydrates the form when the dialog opens or when a different snippet is selected for editing.
// The state reset is intentional user-facing behavior.
useEffect(() => {
if (editingSnippet) {
setTitle(editingSnippet.title)
@@ -32,6 +35,7 @@ export function useSnippetForm(editingSnippet?: Snippet | null, open?: boolean)
}
setErrors({})
}, [editingSnippet, open])
/* eslint-enable react-hooks/set-state-in-effect */
const handleAddParameter = () => {
setInputParameters((prev) => [

View File

@@ -4,10 +4,9 @@
// Flexbox mixins
@mixin flex($direction: row, $justify: flex-start, $align: stretch, $wrap: nowrap) {
display: flex;
flex-direction: $direction;
flex-flow: $direction $wrap;
justify-content: $justify;
align-items: $align;
flex-wrap: $wrap;
}
@mixin flex-center {
@@ -112,6 +111,7 @@
// Responsive breakpoint mixin
@mixin respond-to($breakpoint) {
$size: fn.breakpoint($breakpoint);
@media (min-width: $size) {
@content;
}
@@ -124,6 +124,7 @@
@include rounded(md);
@include font(medium);
@include text(sm);
display: inline-flex;
align-items: center;
justify-content: center;
@@ -144,25 +145,26 @@
background: vars.$card;
color: vars.$card-foreground;
border: 1px solid vars.$border;
@include rounded(lg);
@include p(6);
}
// Shadow mixins
@mixin shadow-sm {
box-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);
box-shadow: 0 1px 2px 0 rgb(0 0 0 / 5%);
}
@mixin shadow {
box-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);
box-shadow: 0 1px 3px 0 rgb(0 0 0 / 10%), 0 1px 2px -1px rgb(0 0 0 / 10%);
}
@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);
box-shadow: 0 4px 6px -1px rgb(0 0 0 / 10%), 0 2px 4px -2px rgb(0 0 0 / 10%);
}
@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);
box-shadow: 0 10px 15px -3px rgb(0 0 0 / 10%), 0 4px 6px -4px rgb(0 0 0 / 10%);
}
// Transition mixin
@@ -185,7 +187,7 @@
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
clip-path: inset(50%);
white-space: nowrap;
border-width: 0;
}
@@ -200,10 +202,7 @@
@mixin absolute-fill {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
inset: 0;
}
// Focus ring

View File

@@ -5,129 +5,129 @@
// === MD3 Primary Tonal Palette ===
// Purple/Violet primary color with full tonal range
$md3-primary-0: hsl(260, 50%, 0%);
$md3-primary-10: hsl(260, 50%, 10%);
$md3-primary-20: hsl(260, 50%, 20%);
$md3-primary-25: hsl(260, 50%, 25%);
$md3-primary-30: hsl(260, 50%, 30%);
$md3-primary-35: hsl(260, 50%, 35%);
$md3-primary-40: hsl(260, 50%, 40%);
$md3-primary-50: hsl(260, 50%, 50%);
$md3-primary-60: hsl(260, 50%, 60%);
$md3-primary-70: hsl(260, 50%, 70%);
$md3-primary-80: hsl(260, 50%, 80%);
$md3-primary-90: hsl(260, 50%, 90%);
$md3-primary-95: hsl(260, 50%, 95%);
$md3-primary-99: hsl(260, 50%, 99%);
$md3-primary-100: hsl(260, 50%, 100%);
$md3-primary-0: hsl(260deg 50% 0%);
$md3-primary-10: hsl(260deg 50% 10%);
$md3-primary-20: hsl(260deg 50% 20%);
$md3-primary-25: hsl(260deg 50% 25%);
$md3-primary-30: hsl(260deg 50% 30%);
$md3-primary-35: hsl(260deg 50% 35%);
$md3-primary-40: hsl(260deg 50% 40%);
$md3-primary-50: hsl(260deg 50% 50%);
$md3-primary-60: hsl(260deg 50% 60%);
$md3-primary-70: hsl(260deg 50% 70%);
$md3-primary-80: hsl(260deg 50% 80%);
$md3-primary-90: hsl(260deg 50% 90%);
$md3-primary-95: hsl(260deg 50% 95%);
$md3-primary-99: hsl(260deg 50% 99%);
$md3-primary-100: hsl(260deg 50% 100%);
// === MD3 Secondary Tonal Palette ===
// Desaturated purple for secondary elements
$md3-secondary-0: hsl(260, 15%, 0%);
$md3-secondary-10: hsl(260, 15%, 10%);
$md3-secondary-20: hsl(260, 15%, 20%);
$md3-secondary-25: hsl(260, 15%, 25%);
$md3-secondary-30: hsl(260, 15%, 30%);
$md3-secondary-35: hsl(260, 15%, 35%);
$md3-secondary-40: hsl(260, 15%, 40%);
$md3-secondary-50: hsl(260, 15%, 50%);
$md3-secondary-60: hsl(260, 15%, 60%);
$md3-secondary-70: hsl(260, 15%, 70%);
$md3-secondary-80: hsl(260, 15%, 80%);
$md3-secondary-90: hsl(260, 15%, 90%);
$md3-secondary-95: hsl(260, 15%, 95%);
$md3-secondary-99: hsl(260, 15%, 99%);
$md3-secondary-100: hsl(260, 15%, 100%);
$md3-secondary-0: hsl(260deg 15% 0%);
$md3-secondary-10: hsl(260deg 15% 10%);
$md3-secondary-20: hsl(260deg 15% 20%);
$md3-secondary-25: hsl(260deg 15% 25%);
$md3-secondary-30: hsl(260deg 15% 30%);
$md3-secondary-35: hsl(260deg 15% 35%);
$md3-secondary-40: hsl(260deg 15% 40%);
$md3-secondary-50: hsl(260deg 15% 50%);
$md3-secondary-60: hsl(260deg 15% 60%);
$md3-secondary-70: hsl(260deg 15% 70%);
$md3-secondary-80: hsl(260deg 15% 80%);
$md3-secondary-90: hsl(260deg 15% 90%);
$md3-secondary-95: hsl(260deg 15% 95%);
$md3-secondary-99: hsl(260deg 15% 99%);
$md3-secondary-100: hsl(260deg 15% 100%);
// === MD3 Tertiary Tonal Palette ===
// Cyan/Teal for tertiary accents
$md3-tertiary-0: hsl(180, 50%, 0%);
$md3-tertiary-10: hsl(180, 50%, 10%);
$md3-tertiary-20: hsl(180, 50%, 20%);
$md3-tertiary-25: hsl(180, 50%, 25%);
$md3-tertiary-30: hsl(180, 50%, 30%);
$md3-tertiary-35: hsl(180, 50%, 35%);
$md3-tertiary-40: hsl(180, 50%, 40%);
$md3-tertiary-50: hsl(180, 50%, 50%);
$md3-tertiary-60: hsl(180, 50%, 60%);
$md3-tertiary-70: hsl(180, 50%, 70%);
$md3-tertiary-80: hsl(180, 50%, 80%);
$md3-tertiary-90: hsl(180, 50%, 90%);
$md3-tertiary-95: hsl(180, 50%, 95%);
$md3-tertiary-99: hsl(180, 50%, 99%);
$md3-tertiary-100: hsl(180, 50%, 100%);
$md3-tertiary-0: hsl(180deg 50% 0%);
$md3-tertiary-10: hsl(180deg 50% 10%);
$md3-tertiary-20: hsl(180deg 50% 20%);
$md3-tertiary-25: hsl(180deg 50% 25%);
$md3-tertiary-30: hsl(180deg 50% 30%);
$md3-tertiary-35: hsl(180deg 50% 35%);
$md3-tertiary-40: hsl(180deg 50% 40%);
$md3-tertiary-50: hsl(180deg 50% 50%);
$md3-tertiary-60: hsl(180deg 50% 60%);
$md3-tertiary-70: hsl(180deg 50% 70%);
$md3-tertiary-80: hsl(180deg 50% 80%);
$md3-tertiary-90: hsl(180deg 50% 90%);
$md3-tertiary-95: hsl(180deg 50% 95%);
$md3-tertiary-99: hsl(180deg 50% 99%);
$md3-tertiary-100: hsl(180deg 50% 100%);
// === MD3 Error Tonal Palette ===
$md3-error-0: hsl(0, 75%, 0%);
$md3-error-10: hsl(0, 75%, 10%);
$md3-error-20: hsl(0, 75%, 20%);
$md3-error-30: hsl(0, 75%, 30%);
$md3-error-40: hsl(0, 75%, 40%);
$md3-error-50: hsl(0, 75%, 50%);
$md3-error-60: hsl(0, 75%, 60%);
$md3-error-70: hsl(0, 75%, 70%);
$md3-error-80: hsl(0, 75%, 80%);
$md3-error-90: hsl(0, 75%, 90%);
$md3-error-95: hsl(0, 75%, 95%);
$md3-error-100: hsl(0, 75%, 100%);
$md3-error-0: hsl(0deg 75% 0%);
$md3-error-10: hsl(0deg 75% 10%);
$md3-error-20: hsl(0deg 75% 20%);
$md3-error-30: hsl(0deg 75% 30%);
$md3-error-40: hsl(0deg 75% 40%);
$md3-error-50: hsl(0deg 75% 50%);
$md3-error-60: hsl(0deg 75% 60%);
$md3-error-70: hsl(0deg 75% 70%);
$md3-error-80: hsl(0deg 75% 80%);
$md3-error-90: hsl(0deg 75% 90%);
$md3-error-95: hsl(0deg 75% 95%);
$md3-error-100: hsl(0deg 75% 100%);
// === MD3 Neutral Tonal Palette ===
// For surfaces and backgrounds
$md3-neutral-0: hsl(260, 10%, 0%);
$md3-neutral-4: hsl(260, 10%, 4%);
$md3-neutral-6: hsl(260, 10%, 6%);
$md3-neutral-10: hsl(260, 10%, 10%);
$md3-neutral-12: hsl(260, 10%, 12%);
$md3-neutral-17: hsl(260, 10%, 17%);
$md3-neutral-20: hsl(260, 10%, 20%);
$md3-neutral-22: hsl(260, 10%, 22%);
$md3-neutral-24: hsl(260, 10%, 24%);
$md3-neutral-25: hsl(260, 10%, 25%);
$md3-neutral-30: hsl(260, 10%, 30%);
$md3-neutral-35: hsl(260, 10%, 35%);
$md3-neutral-40: hsl(260, 10%, 40%);
$md3-neutral-50: hsl(260, 10%, 50%);
$md3-neutral-60: hsl(260, 10%, 60%);
$md3-neutral-70: hsl(260, 10%, 70%);
$md3-neutral-80: hsl(260, 10%, 80%);
$md3-neutral-87: hsl(260, 10%, 87%);
$md3-neutral-90: hsl(260, 10%, 90%);
$md3-neutral-92: hsl(260, 10%, 92%);
$md3-neutral-94: hsl(260, 10%, 94%);
$md3-neutral-95: hsl(260, 10%, 95%);
$md3-neutral-96: hsl(260, 10%, 96%);
$md3-neutral-98: hsl(260, 10%, 98%);
$md3-neutral-99: hsl(260, 10%, 99%);
$md3-neutral-100: hsl(260, 10%, 100%);
$md3-neutral-0: hsl(260deg 10% 0%);
$md3-neutral-4: hsl(260deg 10% 4%);
$md3-neutral-6: hsl(260deg 10% 6%);
$md3-neutral-10: hsl(260deg 10% 10%);
$md3-neutral-12: hsl(260deg 10% 12%);
$md3-neutral-17: hsl(260deg 10% 17%);
$md3-neutral-20: hsl(260deg 10% 20%);
$md3-neutral-22: hsl(260deg 10% 22%);
$md3-neutral-24: hsl(260deg 10% 24%);
$md3-neutral-25: hsl(260deg 10% 25%);
$md3-neutral-30: hsl(260deg 10% 30%);
$md3-neutral-35: hsl(260deg 10% 35%);
$md3-neutral-40: hsl(260deg 10% 40%);
$md3-neutral-50: hsl(260deg 10% 50%);
$md3-neutral-60: hsl(260deg 10% 60%);
$md3-neutral-70: hsl(260deg 10% 70%);
$md3-neutral-80: hsl(260deg 10% 80%);
$md3-neutral-87: hsl(260deg 10% 87%);
$md3-neutral-90: hsl(260deg 10% 90%);
$md3-neutral-92: hsl(260deg 10% 92%);
$md3-neutral-94: hsl(260deg 10% 94%);
$md3-neutral-95: hsl(260deg 10% 95%);
$md3-neutral-96: hsl(260deg 10% 96%);
$md3-neutral-98: hsl(260deg 10% 98%);
$md3-neutral-99: hsl(260deg 10% 99%);
$md3-neutral-100: hsl(260deg 10% 100%);
// === MD3 Neutral Variant Tonal Palette ===
// For outline and surface variants
$md3-neutral-variant-0: hsl(260, 15%, 0%);
$md3-neutral-variant-10: hsl(260, 15%, 10%);
$md3-neutral-variant-20: hsl(260, 15%, 20%);
$md3-neutral-variant-25: hsl(260, 15%, 25%);
$md3-neutral-variant-30: hsl(260, 15%, 30%);
$md3-neutral-variant-35: hsl(260, 15%, 35%);
$md3-neutral-variant-40: hsl(260, 15%, 40%);
$md3-neutral-variant-50: hsl(260, 15%, 50%);
$md3-neutral-variant-60: hsl(260, 15%, 60%);
$md3-neutral-variant-70: hsl(260, 15%, 70%);
$md3-neutral-variant-80: hsl(260, 15%, 80%);
$md3-neutral-variant-90: hsl(260, 15%, 90%);
$md3-neutral-variant-95: hsl(260, 15%, 95%);
$md3-neutral-variant-99: hsl(260, 15%, 99%);
$md3-neutral-variant-100: hsl(260, 15%, 100%);
$md3-neutral-variant-0: hsl(260deg 15% 0%);
$md3-neutral-variant-10: hsl(260deg 15% 10%);
$md3-neutral-variant-20: hsl(260deg 15% 20%);
$md3-neutral-variant-25: hsl(260deg 15% 25%);
$md3-neutral-variant-30: hsl(260deg 15% 30%);
$md3-neutral-variant-35: hsl(260deg 15% 35%);
$md3-neutral-variant-40: hsl(260deg 15% 40%);
$md3-neutral-variant-50: hsl(260deg 15% 50%);
$md3-neutral-variant-60: hsl(260deg 15% 60%);
$md3-neutral-variant-70: hsl(260deg 15% 70%);
$md3-neutral-variant-80: hsl(260deg 15% 80%);
$md3-neutral-variant-90: hsl(260deg 15% 90%);
$md3-neutral-variant-95: hsl(260deg 15% 95%);
$md3-neutral-variant-99: hsl(260deg 15% 99%);
$md3-neutral-variant-100: hsl(260deg 15% 100%);
// === MD3 Semantic Colors (Success, Warning, Info) ===
$md3-success-40: hsl(145, 60%, 35%);
$md3-success-80: hsl(145, 60%, 75%);
$md3-success-90: hsl(145, 60%, 90%);
$md3-warning-40: hsl(40, 80%, 45%);
$md3-warning-80: hsl(40, 80%, 75%);
$md3-warning-90: hsl(40, 80%, 90%);
$md3-info-40: hsl(210, 70%, 45%);
$md3-info-80: hsl(210, 70%, 75%);
$md3-info-90: hsl(210, 70%, 90%);
$md3-success-40: hsl(145deg 60% 35%);
$md3-success-80: hsl(145deg 60% 75%);
$md3-success-90: hsl(145deg 60% 90%);
$md3-warning-40: hsl(40deg 80% 45%);
$md3-warning-80: hsl(40deg 80% 75%);
$md3-warning-90: hsl(40deg 80% 90%);
$md3-info-40: hsl(210deg 70% 45%);
$md3-info-80: hsl(210deg 70% 75%);
$md3-info-90: hsl(210deg 70% 90%);
// ============================================
// MD3 Dark Theme Color Scheme
@@ -165,7 +165,6 @@ $on-error-container: $md3-error-90;
$background: $md3-neutral-6;
$foreground: $md3-neutral-90;
$on-background: $md3-neutral-90;
$surface: $md3-neutral-6;
$on-surface: $md3-neutral-90;
$surface-dim: $md3-neutral-6;
@@ -272,7 +271,6 @@ $letter-spacing-label: 0.1px;
// ============================================
$radius-factor: 1;
$size-scale: 1;
$radius-none: 0;
$radius-extra-small: calc(4px * $radius-factor); // MD3 extra-small
$radius-small: calc(8px * $radius-factor); // MD3 small
@@ -348,9 +346,12 @@ $easing-legacy: cubic-bezier(0.4, 0, 0.2, 1);
$size-0: 0px;
$size-px: 1px;
$size-0-5: calc(0.125rem * $size-scale); // 2px
$size-1-5: calc(0.375rem * $size-scale); // 6px
$size-1: calc(0.25rem * $size-scale); // 4px
$size-2: calc(0.5rem * $size-scale); // 8px
$size-2-5: calc(0.625rem * $size-scale); // 10px
$size-3: calc(0.75rem * $size-scale); // 12px
$size-3-5: calc(0.875rem * $size-scale); // 14px
$size-4: calc(1rem * $size-scale); // 16px
$size-5: calc(1.25rem * $size-scale); // 20px
$size-6: calc(1.5rem * $size-scale); // 24px

View File

@@ -37,7 +37,7 @@
position: absolute;
inset: 0;
border-radius: inherit;
background-color: currentColor;
background-color: currentcolor;
opacity: 0;
transition: opacity $duration-short-4 $easing-standard;
pointer-events: none;
@@ -253,7 +253,7 @@
position: absolute;
inset: 0;
border-radius: inherit;
background-color: currentColor;
background-color: currentcolor;
opacity: 0;
transition: opacity $duration-short-4 $easing-standard;
pointer-events: none;
@@ -330,7 +330,7 @@
position: absolute;
inset: 0;
border-radius: inherit;
background-color: currentColor;
background-color: currentcolor;
opacity: 0;
transition: opacity $duration-short-4 $easing-standard;
pointer-events: none;

View File

@@ -421,6 +421,7 @@
from {
opacity: 0;
}
to {
opacity: 1;
}
@@ -431,6 +432,7 @@
opacity: 0;
transform: translate(-50%, -48%) scale(0.95);
}
to {
opacity: 1;
transform: translate(-50%, -50%) scale(1);
@@ -442,6 +444,7 @@
opacity: 0;
transform: scale(0.95);
}
to {
opacity: 1;
transform: scale(1);
@@ -453,6 +456,7 @@
opacity: 0;
transform: translateY(100%);
}
to {
opacity: 1;
transform: translateY(0);

View File

@@ -8,7 +8,7 @@ header {
position: sticky;
top: 0;
z-index: 20;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.08); // MD3 elevation-1
box-shadow: 0 1px 2px rgb(0 0 0 / 8%); // MD3 elevation-1
.container {
padding: 1rem 1.5rem;
@@ -54,6 +54,7 @@ header {
outline-offset: 2px;
}
}
// Logo styling - Material Design 3 inspired
.logo-container {
display: flex;
@@ -65,13 +66,13 @@ header {
width: 2.5rem;
height: 2.5rem;
border-radius: $radius-xl; // MD3 large shape
background: linear-gradient(135deg, $primary 0%, hsl(260, 45%, 50%) 100%);
background: linear-gradient(135deg, $primary 0%, hsl(260deg 45% 50%) 100%);
display: flex;
align-items: center;
justify-content: center;
box-shadow:
0 1px 2px rgba(0, 0, 0, 0.12), // MD3 elevation-1
0 1px 3px rgba(0, 0, 0, 0.08);
0 1px 2px rgb(0 0 0 / 12%), // MD3 elevation-1
0 1px 3px rgb(0 0 0 / 8%);
transition: all 0.3s cubic-bezier(0.2, 0, 0, 1); // MD3 emphasized easing
svg {
@@ -82,8 +83,8 @@ header {
&:hover {
box-shadow:
0 2px 4px rgba(0, 0, 0, 0.14), // MD3 elevation-2
0 3px 6px rgba(0, 0, 0, 0.10);
0 2px 4px rgb(0 0 0 / 14%), // MD3 elevation-2
0 3px 6px rgb(0 0 0 / 10%);
transform: scale(1.02); // Subtle scale instead of translateY
}
}
@@ -92,11 +93,9 @@ header {
font-size: 1.25rem;
font-weight: 600; // MD3 label-large weight
letter-spacing: 0.01em; // MD3 tracking
color: $foreground;
// Subtle gradient instead of animated
background: linear-gradient(135deg, $foreground 0%, rgba($accent, 0.8) 100%);
-webkit-background-clip: text;
background: linear-gradient(135deg, $foreground 0%, rgb($accent / 80%) 100%);
background-clip: text;
color: transparent;
}
@@ -127,11 +126,12 @@ header {
}
// Header animations - MD3 style (subtle)
@keyframes fadeInDown {
@keyframes fade-in-down {
from {
opacity: 0;
transform: translateY(-4px); // Less dramatic
}
to {
opacity: 1;
transform: translateY(0);
@@ -139,5 +139,5 @@ header {
}
header {
animation: fadeInDown 0.3s cubic-bezier(0.2, 0, 0, 1); // MD3 easing
animation: fade-in-down 0.3s cubic-bezier(0.2, 0, 0, 1); // MD3 easing
}

View File

@@ -2,7 +2,7 @@
// Typography styles
h1, h2, h3, h4, h5, h6 {
font-family: var(--font-inter), 'Inter', sans-serif;
font-family: var(--font-inter), Inter, sans-serif;
font-weight: 600;
line-height: 1.2;
color: $foreground;

View File

@@ -4,88 +4,241 @@
// Utility classes generator
@each $name, $value in vars.$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; }
.p-#{$name} {
padding: $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; }
.px-#{$name} {
padding-left: $value !important;
padding-right: $value !important;
}
.gap-#{$name} { gap: $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; }
.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; }
.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; }
.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; }
.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 vars.$radius {
.rounded-#{$name} { border-radius: $value !important; }
.rounded-#{$name} {
border-radius: $value !important;
}
}
// Text sizes
@each $name, $value in vars.$font-sizes {
.text-#{$name} { font-size: $value !important; }
.text-#{$name} {
font-size: $value !important;
}
}
// Font weights
@each $name, $value in vars.$font-weights {
.font-#{$name} { font-weight: $value !important; }
.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; }
.text-left {
text-align: left !important;
}
.text-center {
text-align: center !important;
}
.text-right {
text-align: right !important;
}
// Colors
.text-foreground { color: vars.$foreground !important; }
.text-muted-foreground { color: vars.$muted-foreground !important; }
.text-primary { color: vars.$primary !important; }
.text-destructive { color: vars.$destructive !important; }
.text-accent { color: vars.$accent !important; }
.text-foreground {
color: vars.$foreground !important;
}
.bg-background { background-color: vars.$background !important; }
.bg-card { background-color: vars.$card !important; }
.bg-primary { background-color: vars.$primary !important; }
.bg-secondary { background-color: vars.$secondary !important; }
.bg-muted { background-color: vars.$muted !important; }
.bg-accent { background-color: vars.$accent !important; }
.bg-destructive { background-color: vars.$destructive !important; }
.text-muted-foreground {
color: vars.$muted-foreground !important;
}
.text-primary {
color: vars.$primary !important;
}
.text-destructive {
color: vars.$destructive !important;
}
.text-accent {
color: vars.$accent !important;
}
.bg-background {
background-color: vars.$background !important;
}
.bg-card {
background-color: vars.$card !important;
}
.bg-primary {
background-color: vars.$primary !important;
}
.bg-secondary {
background-color: vars.$secondary !important;
}
.bg-muted {
background-color: vars.$muted !important;
}
.bg-accent {
background-color: vars.$accent !important;
}
.bg-destructive {
background-color: vars.$destructive !important;
}
// Border
.border { border: 1px solid vars.$border !important; }
@@ -138,6 +291,7 @@
// Space between children - DRY loop
$space-values: (2, 3, 4, 6, 8);
@each $value in $space-values {
.space-y-#{$value} > * + * { margin-top: fn.spacing($value) !important; }
.space-x-#{$value} > * + * { margin-left: fn.spacing($value) !important; }
@@ -161,26 +315,26 @@ $space-values: (2, 3, 4, 6, 8);
padding-left: 1rem;
padding-right: 1rem;
@media (min-width: 640px) {
@media (width >= 640px) {
max-width: 640px;
}
@media (min-width: 768px) {
@media (width >= 768px) {
max-width: 768px;
}
@media (min-width: 1024px) {
@media (width >= 1024px) {
max-width: 1024px;
}
@media (min-width: 1280px) {
@media (width >= 1280px) {
max-width: 1280px;
}
}
// Additional positioning
.inset-0 {
top: 0 !important;
right: 0 !important;
bottom: 0 !important;
left: 0 !important;
inset: 0 !important;
}
.top-0 { top: 0 !important; }
@@ -240,7 +394,6 @@ $space-values: (2, 3, 4, 6, 8);
// Background clip
.bg-clip-text {
-webkit-background-clip: text !important;
background-clip: text !important;
}
@@ -252,7 +405,7 @@ $space-values: (2, 3, 4, 6, 8);
// Shadow variants
.shadow-xs {
box-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05) !important;
box-shadow: 0 1px 2px 0 rgb(0 0 0 / 5%) !important;
}
// Underline offset
@@ -261,7 +414,9 @@ $space-values: (2, 3, 4, 6, 8);
}
// Gap variations - only adding those NOT in spacing map
.gap-1\.5 { gap: 0.375rem !important; } // 1.5 spacing not in map
.gap-1-5 {
gap: 0.375rem !important;
} // 1.5 spacing not in map
// Rounded variations (additional)
.rounded-xs { border-radius: 0.125rem !important; }