From ef45866bb005336d075336f46f063c3b41acbd1a Mon Sep 17 00:00:00 2001 From: DragonSlayer_14 Date: Thu, 11 Jun 2026 18:26:33 +0200 Subject: [PATCH] =?UTF-8?q?Feat:=20Aktualisiert=20SCSS-Variablen=20f=C3=BC?= =?UTF-8?q?r=20Dark-Mode-Unterst=C3=BCtzung=20und=20Light-Mode-Optimierung?= =?UTF-8?q?en?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/watcherTasks.xml | 4 + assets/styles/app.scss | 472 ++++++++++++++++++++++++++++------------- 2 files changed, 324 insertions(+), 152 deletions(-) create mode 100644 .idea/watcherTasks.xml diff --git a/.idea/watcherTasks.xml b/.idea/watcherTasks.xml new file mode 100644 index 0000000..fb0d65a --- /dev/null +++ b/.idea/watcherTasks.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/assets/styles/app.scss b/assets/styles/app.scss index 9f508aa..4e66aa8 100644 --- a/assets/styles/app.scss +++ b/assets/styles/app.scss @@ -1,60 +1,99 @@ // ============================================================================= -// Design Tokens — SCSS Variables +// Design Tokens — Light Palette // ============================================================================= -// Surface palette -$color-surface: #0b1326; -$color-surface-dim: #0b1326; -$color-surface-bright: #31394d; -$color-surface-container-lowest: #060e20; -$color-surface-container-low: #131b2e; -$color-surface-container: #171f33; -$color-surface-container-high: #222a3d; -$color-surface-container-highest: #2d3449; -$color-on-surface: #dae2fd; -$color-on-surface-variant: #c0c7d3; -$color-inverse-surface: #dae2fd; -$color-inverse-on-surface: #283044; -$color-outline: #8a919d; -$color-outline-variant: #404751; -$color-surface-tint: #9dcaff; -$color-surface-variant: #2d3449; +$lt-surface: #f7f9fb; +$lt-surface-dim: #d8dadc; +$lt-surface-bright: #f7f9fb; +$lt-surface-container-lowest: #ffffff; +$lt-surface-container-low: #f2f4f6; +$lt-surface-container: #eceef0; +$lt-surface-container-high: #e6e8ea; +$lt-surface-container-highest: #e0e3e5; +$lt-on-surface: #191c1e; +$lt-on-surface-variant: #404751; +$lt-outline: #707883; +$lt-outline-variant: #c0c7d3; +$lt-surface-tint: #0061a2; +$lt-surface-variant: #e0e3e5; -// Primary — Electric Azure -$color-primary: #9dcaff; -$color-on-primary: #003257; -$color-primary-container: #50a7fa; -$color-on-primary-container: #003b65; -$color-inverse-primary: #0061a2; +$lt-primary: #0061a2; +$lt-on-primary: #ffffff; +$lt-primary-container: #50a7fa; +$lt-on-primary-container: #003b65; +$lt-inverse-primary: #9dcaff; -// Secondary -$color-secondary: #89ceff; -$color-on-secondary: #00344d; -$color-secondary-container: #00a2e6; -$color-on-secondary-container: #00344e; +$lt-secondary: #565e74; +$lt-on-secondary: #ffffff; +$lt-secondary-container: #dae2fd; +$lt-on-secondary-container: #5c647a; -// Tertiary (indigo accent) -$color-tertiary: #c0c1ff; -$color-on-tertiary: #1000a9; -$color-tertiary-container: #9598ff; -$color-on-tertiary-container: #1c16b1; +$lt-tertiary: #505f76; +$lt-on-tertiary: #ffffff; +$lt-tertiary-container: #94a4bc; +$lt-on-tertiary-container: #2a3a4f; -// Error -$color-error: #ffb4ab; -$color-on-error: #690005; -$color-error-container: #93000a; -$color-on-error-container: #ffdad6; +$lt-error: #ba1a1a; +$lt-on-error: #ffffff; +$lt-error-container: #ffdad6; +$lt-on-error-container: #93000a; -// Background -$color-background: #0b1326; -$color-on-background: #dae2fd; +$lt-background: #f7f9fb; +$lt-on-background: #191c1e; + +// ============================================================================= +// Design Tokens — Dark Palette +// ============================================================================= + +$dk-surface: #0b1326; +$dk-surface-dim: #0b1326; +$dk-surface-bright: #31394d; +$dk-surface-container-lowest: #060e20; +$dk-surface-container-low: #131b2e; +$dk-surface-container: #171f33; +$dk-surface-container-high: #222a3d; +$dk-surface-container-highest: #2d3449; +$dk-on-surface: #dae2fd; +$dk-on-surface-variant: #c0c7d3; +$dk-inverse-surface: #dae2fd; +$dk-inverse-on-surface: #283044; +$dk-outline: #8a919d; +$dk-outline-variant: #404751; +$dk-surface-tint: #9dcaff; +$dk-surface-variant: #2d3449; + +$dk-primary: #9dcaff; +$dk-on-primary: #003257; +$dk-primary-container: #50a7fa; +$dk-on-primary-container: #003b65; +$dk-inverse-primary: #0061a2; + +$dk-secondary: #89ceff; +$dk-on-secondary: #00344d; +$dk-secondary-container: #00a2e6; +$dk-on-secondary-container: #00344e; + +$dk-tertiary: #c0c1ff; +$dk-on-tertiary: #1000a9; +$dk-tertiary-container: #9598ff; +$dk-on-tertiary-container: #1c16b1; + +$dk-error: #ffb4ab; +$dk-on-error: #690005; +$dk-error-container: #93000a; +$dk-on-error-container: #ffdad6; + +$dk-background: #0b1326; +$dk-on-background: #dae2fd; + +// ============================================================================= +// Shared Tokens — Typography & Radius +// ============================================================================= -// Typography stacks $font-display: 'Space Grotesk', system-ui, sans-serif; $font-body: 'Geist', system-ui, -apple-system, sans-serif; $font-mono: 'JetBrains Mono', 'Courier New', monospace; -// Border radius scale $radius-sm: 0.25rem; $radius-default: 0.5rem; $radius-md: 0.75rem; @@ -64,51 +103,55 @@ $radius-full: 9999px; // ============================================================================= // Bootstrap Variable Overrides -// Must be declared before @import for !default overrides to take effect. -// Bootstrap 5.x uses @import internally — @use with() is not supported. +// Light mode values are the compiled baseline. +// $color-mode-type: media-query makes Bootstrap emit its own dark-mode block +// inside @media (prefers-color-scheme: dark) automatically. // ============================================================================= -// Semantic color map -$primary: $color-primary-container; // #50a7fa — Electric Azure -$secondary: $color-secondary; // #89ceff -$success: #4ade80; -$info: $color-primary; // #9dcaff -$warning: #fbbf24; -$danger: $color-error; // #ffb4ab -$light: $color-surface-bright; // #31394d -$dark: $color-surface-container-lowest; // #060e20 +$enable-dark-mode: true; +$color-mode-type: media-query; // use prefers-color-scheme instead of data-bs-theme -// Body -$body-bg: $color-background; // #0b1326 -$body-color: $color-on-surface; // #dae2fd -$body-secondary-color: $color-on-surface-variant; // #c0c7d3 +// Semantic colors — light baseline +$primary: $lt-primary-container; // #50a7fa — Electric Azure anchor +$secondary: $lt-secondary; // #565e74 +$success: #16a34a; +$info: $lt-primary; // #0061a2 +$warning: #d97706; +$danger: $lt-error; // #ba1a1a +$light: $lt-surface-container-low; // #f2f4f6 +$dark: $lt-on-surface; // #191c1e + +// Body — light defaults +$body-bg: $lt-background; // #f7f9fb +$body-color: $lt-on-surface; // #191c1e +$body-secondary-color: $lt-on-surface-variant; // #404751 // Links -$link-color: $color-primary; // #9dcaff -$link-hover-color: $color-primary-container; // #50a7fa +$link-color: $lt-primary; // #0061a2 +$link-hover-color: $lt-primary-container; // #50a7fa // Borders -$border-color: $color-outline-variant; // #404751 +$border-color: $lt-outline-variant; // #c0c7d3 // Border radius -$border-radius: $radius-default; // 0.5rem -$border-radius-sm: $radius-sm; // 0.25rem -$border-radius-lg: $radius-md; // 0.75rem -$border-radius-xl: $radius-lg; // 1rem -$border-radius-xxl: $radius-xl; // 1.5rem -$border-radius-pill: $radius-full; // 9999px +$border-radius: $radius-default; +$border-radius-sm: $radius-sm; +$border-radius-lg: $radius-md; +$border-radius-xl: $radius-lg; +$border-radius-xxl: $radius-xl; +$border-radius-pill: $radius-full; // Typography $font-family-sans-serif: $font-body; $font-family-monospace: $font-mono; -$font-size-base: 1rem; // 16px +$font-size-base: 1rem; $line-height-base: 1.5; -// Headings +// Headings — Bootstrap uses var(--bs-heading-color), dark mode auto-switches $headings-font-family: $font-display; $headings-font-weight: 600; $headings-line-height: 1.3; -$headings-color: $color-on-surface; +$headings-color: $lt-on-surface; // #191c1e // Grid $grid-gutter-width: 1.5rem; // 24px @@ -117,99 +160,93 @@ $container-max-widths: ( md: 720px, lg: 960px, xl: 1140px, - xxl: 1280px, + xxl: 1200px, ); -// Cards -$card-bg: $color-surface-container; -$card-border-color: $color-outline-variant; -$card-cap-bg: transparent; - -// Form inputs -$input-bg: $color-surface-container-low; -$input-border-color: $color-outline-variant; -$input-color: $color-on-surface; -$input-focus-border-color: $color-primary-container; -$input-placeholder-color: $color-on-surface-variant; - // Code -$code-color: $color-tertiary; -$pre-color: $color-on-surface; +$code-color: $lt-tertiary; // #505f76 -// Navbar -$navbar-dark-color: rgba($color-on-surface, 0.85); -$navbar-dark-hover-color: $color-primary; -$navbar-dark-active-color: $color-primary; +// Bootstrap dark mode variables — used inside Bootstrap's generated media query +$body-color-dark: $dk-on-surface; // #dae2fd +$body-bg-dark: $dk-background; // #0b1326 +$body-secondary-color-dark: $dk-on-surface-variant; // #c0c7d3 +$border-color-dark: $dk-outline-variant; // #404751 +$link-color-dark: $dk-primary; // #9dcaff +$headings-color-dark: $dk-on-surface; // #dae2fd +$code-color-dark: $dk-tertiary; // #c0c1ff // ============================================================================= // Bootstrap Import +// Bootstrap 5.x uses @import internally — @use with() is not supported. // ============================================================================= @import '~bootstrap/scss/bootstrap'; // ============================================================================= -// CSS Custom Properties — Full Design Token Set +// CSS Custom Properties — Light Mode (default) // ============================================================================= :root { // Surface - --color-surface: #{$color-surface}; - --color-surface-dim: #{$color-surface-dim}; - --color-surface-bright: #{$color-surface-bright}; - --color-surface-container-lowest: #{$color-surface-container-lowest}; - --color-surface-container-low: #{$color-surface-container-low}; - --color-surface-container: #{$color-surface-container}; - --color-surface-container-high: #{$color-surface-container-high}; - --color-surface-container-highest: #{$color-surface-container-highest}; - --color-on-surface: #{$color-on-surface}; - --color-on-surface-variant: #{$color-on-surface-variant}; - --color-inverse-surface: #{$color-inverse-surface}; - --color-inverse-on-surface: #{$color-inverse-on-surface}; - --color-outline: #{$color-outline}; - --color-outline-variant: #{$color-outline-variant}; - --color-surface-tint: #{$color-surface-tint}; - --color-surface-variant: #{$color-surface-variant}; + --color-surface: #{$lt-surface}; + --color-surface-dim: #{$lt-surface-dim}; + --color-surface-bright: #{$lt-surface-bright}; + --color-surface-container-lowest: #{$lt-surface-container-lowest}; + --color-surface-container-low: #{$lt-surface-container-low}; + --color-surface-container: #{$lt-surface-container}; + --color-surface-container-high: #{$lt-surface-container-high}; + --color-surface-container-highest: #{$lt-surface-container-highest}; + --color-on-surface: #{$lt-on-surface}; + --color-on-surface-variant: #{$lt-on-surface-variant}; + --color-outline: #{$lt-outline}; + --color-outline-variant: #{$lt-outline-variant}; + --color-surface-tint: #{$lt-surface-tint}; + --color-surface-variant: #{$lt-surface-variant}; + // RGB channels for rgba() composition (navbar glass, overlays) + --color-surface-container-lowest-rgb: 255, 255, 255; // Primary - --color-primary: #{$color-primary}; - --color-on-primary: #{$color-on-primary}; - --color-primary-container: #{$color-primary-container}; - --color-on-primary-container: #{$color-on-primary-container}; - --color-inverse-primary: #{$color-inverse-primary}; + --color-primary: #{$lt-primary}; + --color-on-primary: #{$lt-on-primary}; + --color-primary-container: #{$lt-primary-container}; + --color-on-primary-container: #{$lt-on-primary-container}; + --color-inverse-primary: #{$lt-inverse-primary}; // Secondary - --color-secondary: #{$color-secondary}; - --color-on-secondary: #{$color-on-secondary}; - --color-secondary-container: #{$color-secondary-container}; - --color-on-secondary-container: #{$color-on-secondary-container}; + --color-secondary: #{$lt-secondary}; + --color-on-secondary: #{$lt-on-secondary}; + --color-secondary-container: #{$lt-secondary-container}; + --color-on-secondary-container: #{$lt-on-secondary-container}; // Tertiary - --color-tertiary: #{$color-tertiary}; - --color-on-tertiary: #{$color-on-tertiary}; - --color-tertiary-container: #{$color-tertiary-container}; - --color-on-tertiary-container: #{$color-on-tertiary-container}; + --color-tertiary: #{$lt-tertiary}; + --color-on-tertiary: #{$lt-on-tertiary}; + --color-tertiary-container: #{$lt-tertiary-container}; + --color-on-tertiary-container: #{$lt-on-tertiary-container}; // Error - --color-error: #{$color-error}; - --color-on-error: #{$color-on-error}; - --color-error-container: #{$color-error-container}; - --color-on-error-container: #{$color-on-error-container}; + --color-error: #{$lt-error}; + --color-on-error: #{$lt-on-error}; + --color-error-container: #{$lt-error-container}; + --color-on-error-container: #{$lt-on-error-container}; // Background - --color-background: #{$color-background}; - --color-on-background: #{$color-on-background}; + --color-background: #{$lt-background}; + --color-on-background: #{$lt-on-background}; // Font stacks --font-display: #{$font-display}; --font-body: #{$font-body}; --font-mono: #{$font-mono}; - // Spacing scale (4px baseline) - --spacing-xs: 4px; - --spacing-sm: 8px; - --spacing-md: 16px; - --spacing-lg: 24px; - --spacing-xl: 32px; + // Spacing (8px base from light design doc) + --spacing-xs: 4px; + --spacing-sm: 8px; + --spacing-md: 16px; + --spacing-lg: 24px; + --spacing-xl: 32px; + --spacing-section: 120px; + --spacing-section-mobile: 64px; // Border radius --radius-sm: #{$radius-sm}; @@ -219,8 +256,66 @@ $navbar-dark-active-color: $color-primary; --radius-xl: #{$radius-xl}; --radius-full: #{$radius-full}; - // Elevation: glow-only focus/hover effect - --glow-primary: 0 0 0 3px rgba(80, 167, 250, 0.2); + // Elevation + --shadow-card-hover: 0px 4px 20px rgba(15, 23, 42, 0.05); + --glow-primary: 0 0 0 3px rgba(80, 167, 250, 0.2); +} + +// ============================================================================= +// CSS Custom Properties — Dark Mode Overrides +// ============================================================================= + +@media (prefers-color-scheme: dark) { + :root { + // Surface + --color-surface: #{$dk-surface}; + --color-surface-dim: #{$dk-surface-dim}; + --color-surface-bright: #{$dk-surface-bright}; + --color-surface-container-lowest: #{$dk-surface-container-lowest}; + --color-surface-container-low: #{$dk-surface-container-low}; + --color-surface-container: #{$dk-surface-container}; + --color-surface-container-high: #{$dk-surface-container-high}; + --color-surface-container-highest: #{$dk-surface-container-highest}; + --color-on-surface: #{$dk-on-surface}; + --color-on-surface-variant: #{$dk-on-surface-variant}; + --color-outline: #{$dk-outline}; + --color-outline-variant: #{$dk-outline-variant}; + --color-surface-tint: #{$dk-surface-tint}; + --color-surface-variant: #{$dk-surface-variant}; + --color-surface-container-lowest-rgb: 6, 14, 32; + + // Primary + --color-primary: #{$dk-primary}; + --color-on-primary: #{$dk-on-primary}; + --color-primary-container: #{$dk-primary-container}; + --color-on-primary-container: #{$dk-on-primary-container}; + --color-inverse-primary: #{$dk-inverse-primary}; + + // Secondary + --color-secondary: #{$dk-secondary}; + --color-on-secondary: #{$dk-on-secondary}; + --color-secondary-container: #{$dk-secondary-container}; + --color-on-secondary-container: #{$dk-on-secondary-container}; + + // Tertiary + --color-tertiary: #{$dk-tertiary}; + --color-on-tertiary: #{$dk-on-tertiary}; + --color-tertiary-container: #{$dk-tertiary-container}; + --color-on-tertiary-container: #{$dk-on-tertiary-container}; + + // Error + --color-error: #{$dk-error}; + --color-on-error: #{$dk-on-error}; + --color-error-container: #{$dk-error-container}; + --color-on-error-container: #{$dk-on-error-container}; + + // Background + --color-background: #{$dk-background}; + --color-on-background: #{$dk-on-background}; + + // Elevation adjustments for dark backgrounds + --shadow-card-hover: 0px 4px 20px rgba(0, 0, 0, 0.4); + } } // ============================================================================= @@ -247,20 +342,20 @@ code, kbd, pre, samp { .text-display-lg { font-family: var(--font-display); - font-size: 48px; + font-size: 64px; font-weight: 700; line-height: 1.1; letter-spacing: -0.02em; @media (max-width: 768px) { - font-size: 32px; + font-size: 40px; line-height: 1.2; } } .text-headline-md { font-family: var(--font-display); - font-size: 24px; + font-size: 32px; font-weight: 600; line-height: 1.3; } @@ -277,12 +372,16 @@ code, kbd, pre, samp { line-height: 1.5; } -.text-code-sm { +// Primary label style (light design doc) +.text-label-sm { font-family: var(--font-mono); - font-size: 14px; - line-height: 1.5; + font-size: 13px; + font-weight: 500; + line-height: 1; + letter-spacing: 0.05em; } +// Variant with uppercase transform (dark design doc) .text-label-caps { font-family: var(--font-mono); font-size: 12px; @@ -294,14 +393,18 @@ code, kbd, pre, samp { // ============================================================================= // Component Overrides +// All colors use var(--color-*) to auto-switch between modes. // ============================================================================= -// Buttons — glow on interactive states +// --- Buttons --- + .btn-primary { - color: $color-on-primary-container; + // #50a7fa is the shared anchor; light text gives better contrast + color: $lt-on-primary; // #ffffff &:hover, &:focus-visible { + color: $lt-on-primary; box-shadow: var(--glow-primary); } } @@ -313,46 +416,110 @@ code, kbd, pre, samp { } } -// Cards — tonal layering, no shadows +// --- Cards --- +// Project cards: border shifts to azure on hover, subtle shadow appears + .card { + background-color: var(--color-surface-container); + border: 1px solid var(--color-outline-variant); + border-radius: var(--radius-lg); // 1rem — large containers per design doc box-shadow: none; + transition: border-color 0.2s ease, box-shadow 0.2s ease; + + &:hover { + border-color: #50a7fa; + box-shadow: var(--shadow-card-hover); + } .card-title { font-family: var(--font-display); + color: var(--color-on-surface); } } -// Inputs — glow on focus (already wired via $input-focus-border-color) +// --- Form Inputs --- + .form-control, .form-select { + background-color: var(--color-surface-container-low); + border-color: var(--color-outline-variant); + color: var(--color-on-surface); + + &::placeholder { + color: var(--color-on-surface-variant); + opacity: 1; + } + &:focus { + background-color: var(--color-surface-container-low); + border-color: #50a7fa; + color: var(--color-on-surface); box-shadow: var(--glow-primary); } } -// Tech chips — JetBrains Mono, muted azure fill +// JetBrains Mono for all form labels +label, +.form-label { + font-family: var(--font-mono); + font-size: 13px; + font-weight: 500; + letter-spacing: 0.05em; + color: var(--color-on-surface-variant); +} + +// --- Navbar --- +// Sticky glassmorphism; links use JetBrains Mono (label-sm style) + +.navbar { + backdrop-filter: blur(12px); + -webkit-backdrop-filter: blur(12px); + // rgba() with RGB channel variable — correct way to compose transparency on a CSS var color + background-color: rgba(var(--color-surface-container-lowest-rgb), 0.85); + border-bottom: 1px solid var(--color-outline-variant); + + .nav-link { + font-family: var(--font-mono); + font-size: 13px; + font-weight: 500; + letter-spacing: 0.05em; + color: var(--color-on-surface); + transition: color 0.15s ease; + + &:hover, + &.active { + color: #50a7fa; + } + } +} + +// --- Tech Chips / Badges --- + .badge-tech { font-family: var(--font-mono); font-size: 12px; - font-weight: 600; + font-weight: 500; letter-spacing: 0.05em; - text-transform: uppercase; border-radius: var(--radius); padding: 4px 8px; background-color: rgba(80, 167, 250, 0.1); - color: var(--color-primary-container); - border: 1px solid rgba(80, 167, 250, 0.2); + // --color-primary is #0061a2 (light) / #9dcaff (dark) — both readable on their backgrounds + color: var(--color-primary); + border: 1px solid rgba(80, 167, 250, 0.25); } -// Code blocks — darkest surface, language label top-right +// --- Code Blocks --- + pre { position: relative; background-color: var(--color-surface-container-lowest); border: 1px solid var(--color-outline-variant); + border-radius: var(--radius); code { font-family: var(--font-mono); font-size: 14px; + color: var(--color-on-surface); } .code-lang { @@ -361,14 +528,15 @@ pre { right: var(--spacing-md); font-family: var(--font-mono); font-size: 12px; - font-weight: 600; + font-weight: 500; letter-spacing: 0.05em; text-transform: uppercase; color: var(--color-on-surface-variant); } } -// Interactive glow helper +// --- Interactive Glow Helper --- + .interactive-glow { transition: box-shadow 0.2s ease;