Refactor styles for consistency and clarity across components

- Updated theme.scss to use rgb() for background colors and added stylelint rules.
- Modified _mixins.scss to reorder properties for better readability and consistency.
- Enhanced button styles in _buttons.scss for improved layout and hover effects.
- Improved card styles in _cards.scss for better hover effects and layout consistency.
- Refined dialog styles in _dialogs.scss to enhance animations and layout.
- Updated form styles in _forms.scss for better accessibility and consistency.
- Enhanced header styles in _header.scss for improved layout and visual hierarchy.
- Refined typography styles in _typography.scss for better readability and consistency.
- Improved utility classes in _utilities.scss for better opacity handling and layout.
This commit is contained in:
2026-01-20 00:14:36 +00:00
parent 9ae6776f37
commit 93d707c79d
13 changed files with 443 additions and 388 deletions

View File

@@ -1,4 +1,22 @@
{
"extends": ["stylelint-config-standard-scss"],
"rules": {}
"plugins": ["stylelint-order"],
"rules": {
"color-no-hex": true,
"color-named": "never",
"value-keyword-case": "lower",
"no-duplicate-at-import-rules": true,
"declaration-block-no-redundant-longhand-properties": true,
"property-no-vendor-prefix": true,
"selector-no-vendor-prefix": true,
"media-feature-name-no-vendor-prefix": true,
"selector-class-pattern": "^[a-z0-9\\-]+$",
"selector-max-id": 0,
"selector-max-universal": 0,
"max-nesting-depth": 4,
"order/properties-alphabetical-order": true,
"color-function-notation": "modern",
"alpha-value-notation": "percentage",
"color-hex-length": "short"
}
}

28
package-lock.json generated
View File

@@ -73,6 +73,7 @@
"globals": "^16.0.0",
"stylelint": "^17.0.0",
"stylelint-config-standard-scss": "^17.0.0",
"stylelint-order": "^7.0.1",
"stylelint-scss": "^7.0.0",
"typescript": "~5.9.3",
"typescript-eslint": "^8.53.1"
@@ -8166,6 +8167,16 @@
"node": ">=4"
}
},
"node_modules/postcss-sorting": {
"version": "9.1.0",
"resolved": "https://registry.npmjs.org/postcss-sorting/-/postcss-sorting-9.1.0.tgz",
"integrity": "sha512-Mn8KJ45HNNG6JBpBizXcyf6LqY/qyqetGcou/nprDnFwBFBLGj0j/sNKV2lj2KMOVOwdXu14aEzqJv8CIV6e8g==",
"dev": true,
"license": "MIT",
"peerDependencies": {
"postcss": "^8.4.20"
}
},
"node_modules/postcss-value-parser": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
@@ -9368,6 +9379,23 @@
}
}
},
"node_modules/stylelint-order": {
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/stylelint-order/-/stylelint-order-7.0.1.tgz",
"integrity": "sha512-GWPei1zBVDDjxM+/BmcSCiOcHNd8rSqW6FUZtqQGlTRpD0Z5nSzspzWD8rtKif5KPdzUG68DApKEV/y/I9VbTw==",
"dev": true,
"license": "MIT",
"dependencies": {
"postcss": "^8.5.6",
"postcss-sorting": "^9.1.0"
},
"engines": {
"node": ">=20.19.0"
},
"peerDependencies": {
"stylelint": "^16.18.0 || ^17.0.0"
}
},
"node_modules/stylelint-scss": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/stylelint-scss/-/stylelint-scss-7.0.0.tgz",

View File

@@ -77,6 +77,7 @@
"globals": "^16.0.0",
"stylelint": "^17.0.0",
"stylelint-config-standard-scss": "^17.0.0",
"stylelint-order": "^7.0.1",
"stylelint-scss": "^7.0.0",
"typescript": "~5.9.3",
"typescript-eslint": "^8.53.1"

View File

@@ -4,11 +4,12 @@
@use './theme';
// Global resets
/* stylelint-disable selector-max-universal */
* {
border-color: $border;
box-sizing: border-box;
margin: 0;
padding: 0;
box-sizing: border-box;
border-color: $border;
}
*,
@@ -18,6 +19,7 @@
::file-selector-button {
border-color: var(--md3-outline-variant);
}
/* stylelint-enable selector-max-universal */
// Body and base styles - Android Material You feel
body {
@@ -25,13 +27,13 @@ body {
color: $foreground;
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;
transition: background-color $duration-medium-2 $easing-standard,
color $duration-medium-2 $easing-standard;
overflow-x: hidden;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
letter-spacing: $letter-spacing-body;
line-height: $line-height-body-medium;
overflow-x: hidden;
transition: background-color $duration-medium-2 $easing-standard,
color $duration-medium-2 $easing-standard;
}
// ============================================
@@ -41,111 +43,111 @@ body {
// Display styles
.md3-display-large {
font-size: $font-display-large;
line-height: $line-height-display-large;
letter-spacing: $letter-spacing-display;
font-weight: 400;
letter-spacing: $letter-spacing-display;
line-height: $line-height-display-large;
}
.md3-display-medium {
font-size: $font-display-medium;
line-height: $line-height-display-medium;
letter-spacing: $letter-spacing-display;
font-weight: 400;
letter-spacing: $letter-spacing-display;
line-height: $line-height-display-medium;
}
.md3-display-small {
font-size: $font-display-small;
line-height: $line-height-display-small;
letter-spacing: $letter-spacing-display;
font-weight: 400;
letter-spacing: $letter-spacing-display;
line-height: $line-height-display-small;
}
// Headline styles
.md3-headline-large {
font-size: $font-headline-large;
line-height: $line-height-headline-large;
letter-spacing: $letter-spacing-headline;
font-weight: 400;
letter-spacing: $letter-spacing-headline;
line-height: $line-height-headline-large;
}
.md3-headline-medium {
font-size: $font-headline-medium;
line-height: $line-height-headline-medium;
letter-spacing: $letter-spacing-headline;
font-weight: 400;
letter-spacing: $letter-spacing-headline;
line-height: $line-height-headline-medium;
}
.md3-headline-small {
font-size: $font-headline-small;
line-height: $line-height-headline-small;
letter-spacing: $letter-spacing-headline;
font-weight: 400;
letter-spacing: $letter-spacing-headline;
line-height: $line-height-headline-small;
}
// Title styles
.md3-title-large {
font-size: $font-title-large;
line-height: $line-height-title-large;
letter-spacing: $letter-spacing-title;
font-weight: 400;
letter-spacing: $letter-spacing-title;
line-height: $line-height-title-large;
}
.md3-title-medium {
font-size: $font-title-medium;
line-height: $line-height-title-medium;
letter-spacing: $letter-spacing-title;
font-weight: 500;
letter-spacing: $letter-spacing-title;
line-height: $line-height-title-medium;
}
.md3-title-small {
font-size: $font-title-small;
line-height: $line-height-title-small;
letter-spacing: $letter-spacing-title;
font-weight: 500;
letter-spacing: $letter-spacing-title;
line-height: $line-height-title-small;
}
// Body styles
.md3-body-large {
font-size: $font-body-large;
line-height: $line-height-body-large;
letter-spacing: $letter-spacing-body;
font-weight: 400;
letter-spacing: $letter-spacing-body;
line-height: $line-height-body-large;
}
.md3-body-medium {
font-size: $font-body-medium;
line-height: $line-height-body-medium;
letter-spacing: $letter-spacing-body;
font-weight: 400;
letter-spacing: $letter-spacing-body;
line-height: $line-height-body-medium;
}
.md3-body-small {
font-size: $font-body-small;
line-height: $line-height-body-small;
letter-spacing: $letter-spacing-body;
font-weight: 400;
letter-spacing: $letter-spacing-body;
line-height: $line-height-body-small;
}
// Label styles
.md3-label-large {
font-size: $font-label-large;
line-height: $line-height-label-large;
letter-spacing: $letter-spacing-label;
font-weight: 500;
letter-spacing: $letter-spacing-label;
line-height: $line-height-label-large;
}
.md3-label-medium {
font-size: $font-label-medium;
line-height: $line-height-label-medium;
letter-spacing: $letter-spacing-label;
font-weight: 500;
letter-spacing: $letter-spacing-label;
line-height: $line-height-label-medium;
}
.md3-label-small {
font-size: $font-label-small;
line-height: $line-height-label-small;
letter-spacing: $letter-spacing-label;
font-weight: 500;
letter-spacing: $letter-spacing-label;
line-height: $line-height-label-small;
}
// Typography base for headings
@@ -177,14 +179,14 @@ h4 {
h5 {
font-size: $font-title-medium;
line-height: $line-height-title-medium;
font-weight: 500;
line-height: $line-height-title-medium;
}
h6 {
font-size: $font-title-small;
line-height: $line-height-title-small;
font-weight: 500;
line-height: $line-height-title-small;
}
code, pre {
@@ -402,18 +404,18 @@ code, pre {
// ============================================
.md3-state-layer {
position: relative;
overflow: hidden;
position: relative;
&::before {
content: '';
position: absolute;
inset: 0;
background-color: currentcolor;
opacity: 0;
transition: opacity $duration-short-4 $easing-standard;
pointer-events: none;
border-radius: inherit;
content: '';
inset: 0;
opacity: 0%;
pointer-events: none;
position: absolute;
transition: opacity $duration-short-4 $easing-standard;
}
&:hover::before {
@@ -435,32 +437,32 @@ code, pre {
@keyframes md3-ripple {
from {
opacity: 12%;
transform: scale(0);
opacity: 0.12;
}
to {
opacity: 0%;
transform: scale(4);
opacity: 0;
}
}
.md3-ripple {
position: relative;
overflow: hidden;
position: relative;
&::after {
content: '';
position: absolute;
width: 100%;
height: 100%;
top: 50%;
left: 50%;
transform: translate(-50%, -50%) scale(0);
background: radial-gradient(circle, currentcolor 10%, transparent 10.01%);
opacity: 0;
pointer-events: none;
border-radius: 50%;
content: '';
height: 100%;
left: 50%;
opacity: 0%;
pointer-events: none;
position: absolute;
top: 50%;
transform: translate(-50%, -50%) scale(0);
width: 100%;
}
&:active::after {
@@ -475,79 +477,79 @@ code, pre {
@keyframes accordion-down {
from {
height: 0;
opacity: 0;
opacity: 0%;
}
to {
height: var(--radix-accordion-content-height);
opacity: 1;
opacity: 100%;
}
}
@keyframes accordion-up {
from {
height: var(--radix-accordion-content-height);
opacity: 1;
opacity: 100%;
}
to {
height: 0;
opacity: 0;
opacity: 0%;
}
}
@keyframes md3-fade-in {
from {
opacity: 0;
opacity: 0%;
}
to {
opacity: 1;
opacity: 100%;
}
}
@keyframes md3-fade-out {
from {
opacity: 1;
opacity: 100%;
}
to {
opacity: 0;
opacity: 0%;
}
}
@keyframes md3-scale-in {
from {
opacity: 0;
opacity: 0%;
transform: scale(0.8);
}
to {
opacity: 1;
opacity: 100%;
transform: scale(1);
}
}
@keyframes md3-slide-in-bottom {
from {
opacity: 0;
opacity: 0%;
transform: translateY(100%);
}
to {
opacity: 1;
opacity: 100%;
transform: translateY(0);
}
}
@keyframes md3-slide-in-right {
from {
opacity: 0;
opacity: 0%;
transform: translateX(100%);
}
to {
opacity: 1;
opacity: 100%;
transform: translateX(0);
}
}
@@ -558,32 +560,32 @@ code, pre {
// Status bar simulation (optional)
.android-status-bar {
height: 24px;
background: var(--md3-surface-container-lowest);
display: flex;
align-items: center;
background: var(--md3-surface-container-lowest);
color: var(--md3-on-surface);
display: flex;
font-size: $font-label-small;
height: 24px;
justify-content: flex-end;
padding: 0 $size-4;
font-size: $font-label-small;
color: var(--md3-on-surface);
}
// Navigation bar simulation (bottom gesture bar)
.android-nav-bar {
height: 20px;
align-items: center;
background: transparent;
display: flex;
align-items: center;
height: 20px;
justify-content: center;
padding-bottom: $size-2;
&::after {
content: '';
width: 134px;
height: 5px;
background: var(--md3-on-surface-variant);
border-radius: $radius-full;
opacity: 0.4;
content: '';
height: 5px;
opacity: 40%;
width: 134px;
}
}
@@ -595,8 +597,8 @@ code, pre {
// Scrollbar styling (Android-like thin scrollbar)
::-webkit-scrollbar {
width: 4px;
height: 4px;
width: 4px;
}
::-webkit-scrollbar-track {

View File

@@ -4,6 +4,7 @@
@import '@radix-ui/colors/violet-dark.css';
// App-level CSS variables
/* stylelint-disable selector-max-id */
#spark-app {
--size-scale: 1;
--radius-factor: 1;
@@ -25,9 +26,9 @@
--color-fg-secondary: var(--color-neutral-11);
// Background colors
--color-bg: #fff;
--color-bg: rgb(255 255 255);
--color-bg-inset: var(--color-neutral-2);
--color-bg-overlay: #fff;
--color-bg-overlay: rgb(255 255 255);
// Focus ring
--color-focus-ring: var(--color-accent-9);
@@ -41,6 +42,7 @@
#spark-app.dark-theme {
--color-bg: var(--color-neutral-1);
--color-bg-inset: #000;
--color-bg-inset: rgb(0 0 0);
--color-bg-overlay: var(--color-neutral-3);
}
/* stylelint-enable selector-max-id */

View File

@@ -3,10 +3,10 @@
// Flexbox mixins
@mixin flex($direction: row, $justify: flex-start, $align: stretch, $wrap: nowrap) {
align-items: $align;
display: flex;
flex-flow: $direction $wrap;
justify-content: $justify;
align-items: $align;
}
@mixin flex-center {
@@ -24,8 +24,8 @@
// Grid mixin
@mixin grid($columns: 1, $gap: fn.spacing(4)) {
display: grid;
grid-template-columns: repeat($columns, 1fr);
gap: $gap;
grid-template-columns: repeat($columns, 1fr);
}
// Spacing mixins
@@ -39,8 +39,8 @@
}
@mixin py($value) {
padding-top: fn.spacing($value);
padding-bottom: fn.spacing($value);
padding-top: fn.spacing($value);
}
@mixin pt($value) {
@@ -69,8 +69,8 @@
}
@mixin my($value) {
margin-top: fn.spacing($value);
margin-bottom: fn.spacing($value);
margin-top: fn.spacing($value);
}
@mixin mt($value) {
@@ -125,26 +125,26 @@
@include font(medium);
@include text(sm);
display: inline-flex;
align-items: center;
justify-content: center;
gap: fn.spacing(2);
cursor: pointer;
transition: all 0.2s ease;
border: none;
cursor: pointer;
display: inline-flex;
gap: fn.spacing(2);
justify-content: center;
outline: none;
transition: all 0.2s ease;
&:disabled {
opacity: 0.5;
cursor: not-allowed;
opacity: 50%;
}
}
// Card mixin
@mixin card {
background: vars.$card;
color: vars.$card-foreground;
border: 1px solid vars.$border;
color: vars.$card-foreground;
@include rounded(lg);
@include p(6);
@@ -181,28 +181,28 @@
// Visually hidden (for accessibility)
@mixin sr-only {
position: absolute;
width: 1px;
border-width: 0;
clip-path: inset(50%);
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip-path: inset(50%);
padding: 0;
position: absolute;
white-space: nowrap;
border-width: 0;
width: 1px;
}
// Absolute positioning shortcuts
@mixin absolute-center {
left: 50%;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
@mixin absolute-fill {
position: absolute;
inset: 0;
position: absolute;
}
// Focus ring

View File

@@ -6,41 +6,41 @@
// Base button styles (MD3)
.btn {
display: inline-flex;
align-items: center;
justify-content: center;
gap: $size-2;
padding: $size-2-5 $size-6;
min-width: 64px;
min-height: 40px;
border: none;
border-radius: $radius-full;
font-family: inherit;
font-weight: 500;
font-size: $font-label-large;
line-height: $line-height-label-large;
letter-spacing: $letter-spacing-label;
cursor: pointer;
user-select: none;
text-decoration: none;
position: relative;
display: inline-flex;
font-family: inherit;
font-size: $font-label-large;
font-weight: 500;
gap: $size-2;
justify-content: center;
letter-spacing: $letter-spacing-label;
line-height: $line-height-label-large;
min-height: 40px;
min-width: 64px;
outline: none;
overflow: hidden;
padding: $size-2-5 $size-6;
position: relative;
text-decoration: none;
transition:
background-color $duration-short-4 $easing-standard,
box-shadow $duration-short-4 $easing-standard,
color $duration-short-4 $easing-standard;
outline: none;
user-select: none;
// State layer
&::before {
content: '';
position: absolute;
inset: 0;
border-radius: inherit;
background-color: currentcolor;
opacity: 0;
transition: opacity $duration-short-4 $easing-standard;
border-radius: inherit;
content: '';
inset: 0;
opacity: 0%;
pointer-events: none;
position: absolute;
transition: opacity $duration-short-4 $easing-standard;
}
&:hover::before {
@@ -61,15 +61,15 @@
}
&:disabled {
opacity: $state-disabled-opacity;
cursor: not-allowed;
opacity: $state-disabled-opacity;
pointer-events: none;
}
svg {
width: 18px;
height: 18px;
flex-shrink: 0;
height: 18px;
width: 18px;
}
// ============================================
@@ -78,8 +78,8 @@
&-primary,
&-filled {
background-color: $primary;
color: $on-primary;
box-shadow: $elevation-1;
color: $on-primary;
&:hover:not(:disabled) {
box-shadow: $elevation-2;
@@ -107,8 +107,8 @@
// ============================================
&-elevated {
background-color: $surface-container-low;
color: $primary;
box-shadow: $elevation-1;
color: $primary;
&:hover:not(:disabled) {
box-shadow: $elevation-2;
@@ -125,8 +125,8 @@
&-outline,
&-outlined {
background-color: transparent;
color: $primary;
border: 1px solid $outline;
color: $primary;
&:hover:not(:disabled) {
background-color: rgba($primary, $state-hover-opacity);
@@ -154,8 +154,8 @@
&-destructive,
&-error {
background-color: $destructive;
color: $on-error;
box-shadow: $elevation-1;
color: $on-error;
&:hover:not(:disabled) {
box-shadow: $elevation-2;
@@ -182,25 +182,25 @@
// Size Variants
// ============================================
&-sm {
padding: $size-1-5 $size-4;
min-height: 32px;
font-size: $font-label-medium;
gap: $size-1-5;
min-height: 32px;
padding: $size-1-5 $size-4;
svg {
width: 16px;
height: 16px;
width: 16px;
}
}
&-lg {
padding: $size-3 $size-8;
min-height: 48px;
font-size: $font-label-large;
min-height: 48px;
padding: $size-3 $size-8;
svg {
width: 20px;
height: 20px;
width: 20px;
}
}
@@ -208,22 +208,22 @@
// Icon Button
// ============================================
&-icon {
padding: 0;
min-width: 40px;
width: 40px;
height: 40px;
border-radius: $radius-full;
height: 40px;
min-width: 40px;
padding: 0;
width: 40px;
&.btn-sm {
height: 32px;
min-width: 32px;
width: 32px;
height: 32px;
}
&.btn-lg {
height: 48px;
min-width: 48px;
width: 48px;
height: 48px;
}
}
}
@@ -232,31 +232,31 @@
// MD3 Icon Button (standalone)
// ============================================
.icon-btn {
display: inline-flex;
align-items: center;
justify-content: center;
width: 40px;
height: 40px;
padding: 0;
background-color: transparent;
border: none;
border-radius: $radius-full;
background-color: transparent;
color: $on-surface-variant;
cursor: pointer;
position: relative;
overflow: hidden;
transition: color $duration-short-4 $easing-standard;
display: inline-flex;
height: 40px;
justify-content: center;
outline: none;
overflow: hidden;
padding: 0;
position: relative;
transition: color $duration-short-4 $easing-standard;
width: 40px;
&::before {
content: '';
position: absolute;
inset: 0;
border-radius: inherit;
background-color: currentcolor;
opacity: 0;
transition: opacity $duration-short-4 $easing-standard;
border-radius: inherit;
content: '';
inset: 0;
opacity: 0%;
pointer-events: none;
position: absolute;
transition: opacity $duration-short-4 $easing-standard;
}
&:hover::before {
@@ -277,13 +277,13 @@
}
&:disabled {
opacity: $state-disabled-opacity;
cursor: not-allowed;
opacity: $state-disabled-opacity;
}
svg {
width: 24px;
height: 24px;
width: 24px;
}
// Filled variant
@@ -309,31 +309,31 @@
// Navigation Button (burger menu)
// ============================================
.nav-burger-btn {
display: inline-flex;
align-items: center;
justify-content: center;
width: 48px;
height: 48px;
padding: 0;
background-color: transparent;
border: none;
border-radius: $radius-full;
background-color: transparent;
color: $on-surface;
cursor: pointer;
position: relative;
overflow: hidden;
transition: color $duration-short-4 $easing-standard;
display: inline-flex;
height: 48px;
justify-content: center;
outline: none;
overflow: hidden;
padding: 0;
position: relative;
transition: color $duration-short-4 $easing-standard;
width: 48px;
&::before {
content: '';
position: absolute;
inset: 0;
border-radius: inherit;
background-color: currentcolor;
opacity: 0;
transition: opacity $duration-short-4 $easing-standard;
border-radius: inherit;
content: '';
inset: 0;
opacity: 0%;
pointer-events: none;
position: absolute;
transition: opacity $duration-short-4 $easing-standard;
}
&:hover::before {
@@ -354,7 +354,7 @@
}
svg {
width: 24px;
height: 24px;
width: 24px;
}
}

View File

@@ -5,9 +5,9 @@
background-color: $card;
border: 1px solid $border;
border-radius: $radius-lg;
color: $card-foreground;
padding: $size-6;
transition: all 0.2s ease;
color: $card-foreground;
&:hover {
border-color: $accent;
@@ -15,24 +15,24 @@
}
&__header {
border-bottom: 1px solid $border;
margin-bottom: $size-4;
padding-bottom: $size-4;
border-bottom: 1px solid $border;
}
&__title {
margin: 0;
color: $foreground;
font-size: 1.25rem;
font-weight: 600;
color: $foreground;
line-height: 1.2;
margin: 0;
}
&__description {
margin-top: $size-2;
font-size: 0.875rem;
color: $muted-foreground;
font-size: 0.875rem;
line-height: 1.5;
margin-top: $size-2;
}
&__body {
@@ -42,19 +42,19 @@
}
&__footer {
border-top: 1px solid $border;
display: flex;
justify-content: flex-end;
gap: $size-2;
justify-content: flex-end;
margin-top: $size-4;
padding-top: $size-4;
border-top: 1px solid $border;
}
// Card variants
&--hover-lift {
&:hover {
transform: translateY(-4px);
box-shadow: 0 12px 24px $shadow-accent-md;
transform: translateY(-4px);
}
}

View File

@@ -7,31 +7,31 @@
// Scrim/Overlay
[data-slot="dialog-overlay"],
.dialog-overlay {
position: fixed;
inset: 0;
z-index: 50;
background-color: rgba($scrim, 0.32); // MD3 scrim opacity
animation: md3-fade-in $duration-medium-2 $easing-emphasized-decelerate;
background-color: rgba($scrim, 0.32); // MD3 scrim opacity
inset: 0;
position: fixed;
z-index: 50;
}
// Dialog Content (MD3 Basic Dialog)
[data-slot="dialog"],
.dialog-content {
position: fixed;
left: 50%;
top: 50%;
z-index: 50;
transform: translate(-50%, -50%);
width: calc(100% - 48px);
max-width: 560px;
max-height: calc(100vh - 96px);
overflow-y: auto;
animation: md3-dialog-enter $duration-medium-2 $easing-emphasized-decelerate;
background: $surface-container-high;
border: none;
border-radius: $radius-extra-large;
box-shadow: $elevation-3;
left: 50%;
max-height: calc(100vh - 96px);
max-width: 560px;
overflow-y: auto;
padding: $size-6;
animation: md3-dialog-enter $duration-medium-2 $easing-emphasized-decelerate;
position: fixed;
top: 50%;
transform: translate(-50%, -50%);
width: calc(100% - 48px);
z-index: 50;
&:focus {
outline: none;
@@ -50,19 +50,19 @@
// Dialog Title (MD3 Headline Small)
[data-slot="dialog-title"],
.dialog-title {
font-size: $font-headline-small;
line-height: $line-height-headline-small;
font-weight: 400;
color: $on-surface;
font-size: $font-headline-small;
font-weight: 400;
line-height: $line-height-headline-small;
margin: 0;
}
// Dialog Description (MD3 Body Medium)
[data-slot="dialog-description"],
.dialog-description {
color: $on-surface-variant;
font-size: $font-body-medium;
line-height: $line-height-body-medium;
color: $on-surface-variant;
margin: 0;
}
@@ -70,28 +70,28 @@
[data-slot="dialog-footer"],
.dialog-footer {
display: flex;
justify-content: flex-end;
gap: $size-2;
justify-content: flex-end;
margin-top: $size-6;
}
// Dialog Close Button
[data-slot="dialog-close"],
.dialog-close {
position: absolute;
top: $size-4;
right: $size-4;
width: 40px;
height: 40px;
display: flex;
align-items: center;
justify-content: center;
border-radius: $radius-full;
border: none;
background: transparent;
border: none;
border-radius: $radius-full;
color: $on-surface-variant;
cursor: pointer;
display: flex;
height: 40px;
justify-content: center;
position: absolute;
right: $size-4;
top: $size-4;
transition: background-color $duration-short-4 $easing-standard;
width: 40px;
&:hover {
background-color: rgba($on-surface, $state-hover-opacity);
@@ -108,16 +108,16 @@
// ============================================
[data-slot="dropdown-menu-content"],
.dropdown-content {
z-index: 50;
min-width: 112px;
max-width: 280px;
overflow: hidden;
border-radius: $radius-extra-small;
border: none;
background: $surface-container;
box-shadow: $elevation-2;
padding: $size-2 0;
animation: md3-menu-enter $duration-short-4 $easing-emphasized-decelerate;
background: $surface-container;
border: none;
border-radius: $radius-extra-small;
box-shadow: $elevation-2;
max-width: 280px;
min-width: 112px;
overflow: hidden;
padding: $size-2 0;
z-index: 50;
&:focus {
outline: none;
@@ -127,19 +127,19 @@
// Dropdown Menu Item
[data-slot="dropdown-menu-item"],
.dropdown-item {
position: relative;
display: flex;
align-items: center;
gap: $size-3;
min-height: 48px;
padding: 0 $size-3;
font-size: $font-body-large;
line-height: $line-height-body-large;
color: $on-surface;
cursor: pointer;
display: flex;
font-size: $font-body-large;
gap: $size-3;
line-height: $line-height-body-large;
min-height: 48px;
outline: none;
padding: 0 $size-3;
position: relative;
transition: background-color $duration-short-4 $easing-standard;
user-select: none;
outline: none;
&:hover {
background-color: rgba($on-surface, $state-hover-opacity);
@@ -154,32 +154,32 @@
}
&[data-disabled] {
pointer-events: none;
opacity: $state-disabled-opacity;
pointer-events: none;
}
svg {
width: 24px;
height: 24px;
color: $on-surface-variant;
height: 24px;
width: 24px;
}
}
// Dropdown Menu Separator
[data-slot="dropdown-menu-separator"],
.dropdown-separator {
height: 1px;
background: $outline-variant;
height: 1px;
margin: $size-2 0;
}
// Dropdown Menu Label
[data-slot="dropdown-menu-label"],
.dropdown-label {
padding: $size-2 $size-3;
color: $on-surface-variant;
font-size: $font-label-large;
font-weight: 500;
color: $on-surface-variant;
padding: $size-2 $size-3;
}
// ============================================
@@ -187,15 +187,15 @@
// ============================================
[data-slot="popover-content"],
.popover-content {
z-index: 50;
width: auto;
min-width: 112px;
border-radius: $radius-medium;
border: none;
background: $surface-container;
box-shadow: $elevation-2;
padding: $size-4;
animation: md3-menu-enter $duration-short-4 $easing-emphasized-decelerate;
background: $surface-container;
border: none;
border-radius: $radius-medium;
box-shadow: $elevation-2;
min-width: 112px;
padding: $size-4;
width: auto;
z-index: 50;
&:focus {
outline: none;
@@ -207,68 +207,68 @@
// ============================================
[data-slot="select-trigger"],
.select-trigger {
display: flex;
align-items: center;
justify-content: space-between;
width: 100%;
min-height: 56px;
padding: $size-4;
font-size: $font-body-large;
border-radius: $radius-extra-small;
border: 1px solid $outline;
background: transparent;
border: 1px solid $outline;
border-radius: $radius-extra-small;
color: $on-surface;
cursor: pointer;
display: flex;
font-size: $font-body-large;
justify-content: space-between;
min-height: 56px;
padding: $size-4;
transition: border-color $duration-short-4 $easing-standard;
width: 100%;
&:hover {
border-color: $on-surface;
}
&:focus {
outline: none;
border-color: $primary;
border-width: 2px;
outline: none;
padding: calc(#{$size-4} - 1px);
}
&[data-disabled] {
pointer-events: none;
opacity: $state-disabled-opacity;
pointer-events: none;
}
svg {
width: 24px;
height: 24px;
color: $on-surface-variant;
height: 24px;
width: 24px;
}
}
[data-slot="select-content"],
.select-content {
z-index: 50;
animation: md3-menu-enter $duration-short-4 $easing-emphasized-decelerate;
background: $surface-container;
border: none;
border-radius: $radius-extra-small;
box-shadow: $elevation-2;
min-width: 112px;
overflow: hidden;
border-radius: $radius-extra-small;
border: none;
background: $surface-container;
box-shadow: $elevation-2;
padding: $size-2 0;
animation: md3-menu-enter $duration-short-4 $easing-emphasized-decelerate;
z-index: 50;
}
[data-slot="select-item"],
.select-item {
position: relative;
display: flex;
align-items: center;
min-height: 48px;
padding: 0 $size-3;
font-size: $font-body-large;
color: $on-surface;
cursor: pointer;
transition: background-color $duration-short-4 $easing-standard;
display: flex;
font-size: $font-body-large;
min-height: 48px;
outline: none;
padding: 0 $size-3;
position: relative;
transition: background-color $duration-short-4 $easing-standard;
user-select: none;
&:hover {
@@ -283,19 +283,19 @@
background-color: rgba($primary, 0.12);
&::before {
content: '';
position: absolute;
left: 0;
top: 0;
bottom: 0;
width: 3px;
background: $primary;
bottom: 0;
content: '';
left: 0;
position: absolute;
top: 0;
width: 3px;
}
}
&[data-disabled] {
pointer-events: none;
opacity: $state-disabled-opacity;
pointer-events: none;
}
}
@@ -304,19 +304,19 @@
// ============================================
[data-slot="alert-dialog-content"],
.alert-dialog-content {
position: fixed;
left: 50%;
top: 50%;
z-index: 50;
transform: translate(-50%, -50%);
width: calc(100% - 48px);
max-width: 560px;
animation: md3-dialog-enter $duration-medium-2 $easing-emphasized-decelerate;
background: $surface-container-high;
border: none;
border-radius: $radius-extra-large;
box-shadow: $elevation-3;
left: 50%;
max-width: 560px;
padding: $size-6;
animation: md3-dialog-enter $duration-medium-2 $easing-emphasized-decelerate;
position: fixed;
top: 50%;
transform: translate(-50%, -50%);
width: calc(100% - 48px);
z-index: 50;
&:focus {
outline: none;
@@ -330,9 +330,9 @@
margin-bottom: $size-4;
svg {
width: 24px;
height: 24px;
color: $on-surface-variant;
height: 24px;
width: 24px;
}
&--error svg {
@@ -345,32 +345,32 @@
// ============================================
.snackbar,
[data-slot="toast"] {
display: flex;
align-items: center;
animation: md3-snackbar-enter $duration-medium-1 $easing-emphasized-decelerate;
background: $inverse-surface;
border-radius: $radius-extra-small;
box-shadow: $elevation-3;
color: $inverse-on-surface;
display: flex;
font-size: $font-body-medium;
gap: $size-2;
min-height: 48px;
padding: $size-3-5 $size-4;
background: $inverse-surface;
color: $inverse-on-surface;
border-radius: $radius-extra-small;
box-shadow: $elevation-3;
font-size: $font-body-medium;
animation: md3-snackbar-enter $duration-medium-1 $easing-emphasized-decelerate;
}
.snackbar-action {
margin-left: auto;
padding: 0 $size-2;
font-size: $font-label-large;
font-weight: 500;
color: $inverse-primary;
background: transparent;
border: none;
color: $inverse-primary;
cursor: pointer;
font-size: $font-label-large;
font-weight: 500;
margin-left: auto;
padding: 0 $size-2;
transition: opacity $duration-short-4 $easing-standard;
&:hover {
opacity: 0.8;
opacity: 80%;
}
}
@@ -378,24 +378,24 @@
// Namespace Selector (MD3 styled)
// ============================================
.namespace-select {
display: inline-flex;
align-items: center;
gap: $size-2;
padding: $size-2 $size-4;
font-size: $font-label-large;
font-weight: 500;
border-radius: $radius-small;
border: 1px solid $outline-variant;
background: $surface-container;
border: 1px solid $outline-variant;
border-radius: $radius-small;
color: $on-surface;
cursor: pointer;
display: inline-flex;
font-size: $font-label-large;
font-weight: 500;
gap: $size-2;
padding: $size-2 $size-4;
transition: all $duration-short-4 $easing-standard;
svg {
width: 18px;
height: 18px;
color: $on-surface-variant;
height: 18px;
transition: color $duration-short-4 $easing-standard;
width: 18px;
}
&:hover {
@@ -408,9 +408,9 @@
}
&:focus {
outline: none;
border-color: $primary;
box-shadow: 0 0 0 2px rgba($primary, 0.2);
outline: none;
}
}
@@ -419,46 +419,46 @@
// ============================================
@keyframes md3-fade-in {
from {
opacity: 0;
opacity: 0%;
}
to {
opacity: 1;
opacity: 100%;
}
}
@keyframes md3-dialog-enter {
from {
opacity: 0;
opacity: 0%;
transform: translate(-50%, -48%) scale(0.95);
}
to {
opacity: 1;
opacity: 100%;
transform: translate(-50%, -50%) scale(1);
}
}
@keyframes md3-menu-enter {
from {
opacity: 0;
opacity: 0%;
transform: scale(0.95);
}
to {
opacity: 1;
opacity: 100%;
transform: scale(1);
}
}
@keyframes md3-snackbar-enter {
from {
opacity: 0;
opacity: 0%;
transform: translateY(100%);
}
to {
opacity: 1;
opacity: 100%;
transform: translateY(0);
}
}

View File

@@ -13,72 +13,72 @@
}
&__label {
color: $foreground;
font-size: 0.875rem;
font-weight: 500;
color: $foreground;
}
&__input,
&__select,
&__textarea {
padding: $size-2 $size-3;
background-color: $input;
color: $foreground;
border: 1px solid $border;
border-radius: $radius-md;
color: $foreground;
font-size: 0.875rem;
padding: $size-2 $size-3;
transition: all 0.2s ease;
&:focus {
outline: none;
border-color: $ring;
box-shadow: 0 0 0 3px $shadow-focus;
outline: none;
}
&::placeholder {
color: $muted-foreground;
opacity: 0.6;
opacity: 60%;
}
&:disabled {
opacity: 0.5;
cursor: not-allowed;
background-color: $muted;
cursor: not-allowed;
opacity: 50%;
}
}
&__textarea {
resize: vertical;
min-height: 120px;
font-family: var(--font-jetbrains-mono), 'JetBrains Mono', monospace;
min-height: 120px;
resize: vertical;
}
&__select {
cursor: pointer;
appearance: none;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%23cbd5e1' d='M6 9L1 4h10z'/%3E%3C/svg%3E");
background-repeat: no-repeat;
background-position: right $size-3 center;
background-repeat: no-repeat;
cursor: pointer;
padding-right: $size-8;
}
&__helper {
font-size: 0.75rem;
color: $muted-foreground;
font-size: 0.75rem;
margin-top: -$size-1;
}
&__error {
font-size: 0.75rem;
color: $destructive;
font-size: 0.75rem;
margin-top: -$size-1;
}
// Checkbox and radio styles
&__checkbox,
&__radio {
width: 1rem;
height: 1rem;
accent-color: $primary;
height: 1rem;
width: 1rem;
}
}

View File

@@ -1,14 +1,15 @@
@use "sass:color";
@use '../abstracts' as *;
// Header and navigation - Material Design 3 style
header {
border-bottom: 1px solid rgba($border, 0.4);
background-color: rgba($card, 0.85); // MD3 surface
backdrop-filter: blur(12px) saturate(120%); // Less intense
background-color: rgba($card, 0.85); // MD3 surface
border-bottom: 1px solid rgba($border, 0.4);
box-shadow: 0 1px 2px rgb(0 0 0 / 8%); // MD3 elevation-1
position: sticky;
top: 0;
z-index: 20;
box-shadow: 0 1px 2px rgb(0 0 0 / 8%); // MD3 elevation-1
.container {
padding: 1rem 1.5rem;
@@ -17,24 +18,24 @@ header {
// Burger menu - Material Design 3 icon button style
.nav-burger-btn {
display: inline-flex;
align-items: center;
justify-content: center;
width: 2.5rem;
height: 2.5rem;
padding: 0.5rem;
border-radius: $radius-lg; // MD3 uses larger radius
background-color: transparent;
border: 1px solid transparent;
transition: all 0.2s cubic-bezier(0.2, 0, 0, 1); // MD3 standard easing
border-radius: $radius-lg; // MD3 uses larger radius
cursor: pointer;
display: inline-flex;
height: 2.5rem;
justify-content: center;
padding: 0.5rem;
position: relative;
transition: all 0.2s cubic-bezier(0.2, 0, 0, 1); // MD3 standard easing
width: 2.5rem;
svg {
width: 1.25rem;
height: 1.25rem;
color: $foreground;
height: 1.25rem;
transition: all 0.2s ease;
width: 1.25rem;
}
&:hover {
@@ -57,28 +58,28 @@ header {
// Logo styling - Material Design 3 inspired
.logo-container {
display: flex;
align-items: center;
display: flex;
gap: 0.75rem;
}
.logo-icon-box {
width: 2.5rem;
height: 2.5rem;
border-radius: $radius-xl; // MD3 large shape
background: linear-gradient(135deg, $primary 0%, hsl(260deg 45% 50%) 100%);
display: flex;
align-items: center;
justify-content: center;
background: linear-gradient(135deg, $primary 0%, hsl(260deg 45% 50%) 100%);
border-radius: $radius-xl; // MD3 large shape
box-shadow:
0 1px 2px rgb(0 0 0 / 12%), // MD3 elevation-1
0 1px 3px rgb(0 0 0 / 8%);
display: flex;
height: 2.5rem;
justify-content: center;
transition: all 0.3s cubic-bezier(0.2, 0, 0, 1); // MD3 emphasized easing
width: 2.5rem;
svg {
width: 1.25rem;
height: 1.25rem;
color: $primary-foreground;
height: 1.25rem;
width: 1.25rem;
}
&:hover {
@@ -90,23 +91,21 @@ header {
}
.logo-text {
// Subtle gradient instead of animated
background: linear-gradient(
135deg,
$foreground 0%,
color.scale($accent, $alpha: -20%) 100%
);
background-clip: text;
color: transparent;
font-size: 1.25rem;
font-weight: 600; // MD3 label-large weight
letter-spacing: 0.01em; // MD3 tracking
// Subtle gradient instead of animated
background: linear-gradient(135deg, $foreground 0%, rgb($accent / 80%) 100%);
background-clip: text;
color: transparent;
}
// Grid pattern - MD3 style (much more subtle)
.grid-pattern {
position: fixed;
inset: 0;
opacity: 0.008; // Even more subtle for MD3
pointer-events: none;
z-index: 0; // Ensure it's behind everything
background-image:
repeating-linear-gradient(
0deg,
@@ -123,17 +122,22 @@ header {
rgba($accent, 0.08) 65px
);
background-size: 64px 64px;
inset: 0;
opacity: 0.8%; // Even more subtle for MD3
pointer-events: none;
position: fixed;
z-index: 0; // Ensure it's behind everything
}
// Header animations - MD3 style (subtle)
@keyframes fade-in-down {
from {
opacity: 0;
opacity: 0%;
transform: translateY(-4px); // Less dramatic
}
to {
opacity: 1;
opacity: 100%;
transform: translateY(0);
}
}

View File

@@ -2,10 +2,10 @@
// Typography styles
h1, h2, h3, h4, h5, h6 {
color: $foreground;
font-family: var(--font-inter), Inter, sans-serif;
font-weight: 600;
line-height: 1.2;
color: $foreground;
}
h1 {
@@ -39,9 +39,9 @@ h6 {
}
p {
color: $foreground;
line-height: 1.6;
margin-bottom: $size-4;
color: $foreground;
&.text-muted {
color: $muted-foreground;
@@ -50,28 +50,28 @@ p {
// Code blocks
code {
font-family: var(--font-jetbrains-mono), 'JetBrains Mono', monospace;
background-color: $muted;
padding: 0.125rem 0.375rem;
border-radius: $radius-sm;
font-size: 0.875em;
color: $accent;
font-family: var(--font-jetbrains-mono), 'JetBrains Mono', monospace;
font-size: 0.875em;
padding: 0.125rem 0.375rem;
}
pre {
font-family: var(--font-jetbrains-mono), 'JetBrains Mono', monospace;
background-color: $muted;
padding: $size-4;
border-radius: $radius-md;
overflow-x: auto;
margin-bottom: $size-4;
border: 1px solid $border;
border-radius: $radius-md;
font-family: var(--font-jetbrains-mono), 'JetBrains Mono', monospace;
margin-bottom: $size-4;
overflow-x: auto;
padding: $size-4;
code {
background-color: transparent;
padding: 0;
border-radius: 0;
color: $foreground;
padding: 0;
}
}
@@ -87,9 +87,9 @@ a {
}
&:focus-visible {
border-radius: $radius-sm;
outline: 2px solid $ring;
outline-offset: 2px;
border-radius: $radius-sm;
}
}

View File

@@ -14,8 +14,8 @@
}
.py-#{$name} {
padding-top: $value !important;
padding-bottom: $value !important;
padding-top: $value !important;
}
.pt-#{$name} {
@@ -44,8 +44,8 @@
}
.my-#{$name} {
margin-top: $value !important;
margin-bottom: $value !important;
margin-top: $value !important;
}
.mt-#{$name} {
@@ -275,9 +275,9 @@
.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; }
.opacity-50 { opacity: 50% !important; }
.opacity-75 { opacity: 75% !important; }
.opacity-100 { opacity: 100% !important; }
// Transitions
.transition { transition: all 0.2s ease !important; }
@@ -309,11 +309,11 @@ $space-values: (2, 3, 4, 6, 8);
// Container
.container {
width: 100%;
margin-left: auto;
margin-right: auto;
padding-left: 1rem;
padding-right: 1rem;
width: 100%;
@media (width >= 640px) {
max-width: 640px;
@@ -429,8 +429,8 @@ svg.w-5 { width: 1.25rem !important; }
// Button-specific utilities using nesting
button {
&:disabled {
opacity: 50%;
pointer-events: none;
opacity: 0.5;
}
&:focus-visible {
@@ -439,7 +439,7 @@ button {
}
svg {
pointer-events: none;
flex-shrink: 0;
pointer-events: none;
}
}