Skip to content

The Integration Strategy

1. Your Current Setup Maps Well

Your ITCSS-like structure already aligns with design token architecture:

  • 02-tokens (your current layer) → Option Tokens (color palettes, spacing scales)
  • 03-layout → Uses Decision Tokens (semantic decisions like "surface color", "primary spacing")
  • 04-utils → Helper classes that might use Decision or Component Tokens
  • 05-componentsComponent Tokens (button-primary-background, card-padding, etc.)

2. Quasar Integration Strategy

Quasar provides extensive SCSS variables (as you've shown). Here's how to approach it:

Option A: Override Quasar Variables with Your Tokens

// 02-tokens/_quasar-overrides.scss
@use "design-tokens" as tokens;

// Map your design tokens to Quasar variables
$primary: tokens.$color-brand-primary;
$secondary: tokens.$color-brand-secondary;
$space-base: tokens.$spacing-base;
$breakpoint-xs: tokens.$breakpoint-mobile;

// Import Quasar with your overrides
@import "quasar/src/css/variables.sass";

Option B: Create a Token Mapping Layer

// 02-tokens/_design-tokens.scss
// Your source of truth
$color-brand-primary: #1976d2;
$color-brand-secondary: #26a69a;
$spacing-base: 16px;

// 02-tokens/_quasar-bridge.scss
// Bridge layer that maps tokens to Quasar
@use "design-tokens" as tokens;

$primary: tokens.$color-brand-primary;
$secondary: tokens.$color-brand-secondary;
$space-base: tokens.$spacing-base;

3. Atomic Design + BEM Integration

Since your designer uses Atomic Design, organize your components layer:

05-components/
├── _atoms/           # Basic elements (buttons, inputs)
│   ├── _button.scss
│   └── _input.scss
├── _molecules/       # Simple combinations (search bar, card header)
│   ├── _search-bar.scss
│   └── _card-header.scss
├── _organisms/       # Complex sections (navigation, footer)
│   ├── _navigation.scss
│   └── _footer.scss
└── _templates/       # Page-level layouts
    └── _dashboard.scss

BEM with Component Tokens:

// 05-components/_atoms/_button.scss
@use "../../02-tokens/decisions" as decisions;

.button {
  // Base button using decision tokens
  padding: decisions.$button-padding;
  border-radius: decisions.$button-border-radius;
  font-size: decisions.$button-font-size;

  &--primary {
    // Component token: button-primary
    background: decisions.$button-primary-background;
    color: decisions.$button-primary-text;
  }

  &--secondary {
    background: decisions.$button-secondary-background;
    color: decisions.$button-secondary-text;
  }

  &__icon {
    // Element within button
    margin-right: decisions.$button-icon-spacing;
  }
}

4. Three-Layer Token Architecture

Layer 1: Options (Primitives)

// 02-tokens/_options.scss
// What's available (the palette)
$color-blue-900: #0265dc;
$color-grey-100: #f8f8f8;
$spacing-4: 4px;
$spacing-8: 8px;
$spacing-16: 16px;

Layer 2: Decisions (Semantic)

// 02-tokens/_decisions.scss
@use "options" as opt;

// How they're applied
$color-primary: opt.$color-blue-900;
$color-surface: opt.$color-grey-100;
$spacing-small: opt.$spacing-8;
$spacing-medium: opt.$spacing-16;

$button-padding: $spacing-small $spacing-medium;
$button-border-radius: 4px;

Layer 3: Component Tokens

// 02-tokens/_components.scss
@use "decisions" as dec;

// Where they're applied
$button-primary-background: dec.$color-primary;
$button-primary-text: dec.$color-text-on-primary;
$button-secondary-background: dec.$color-surface;
$button-secondary-text: dec.$color-text;

5. File Structure Example

styles/
├── 01-reset/
│   └── _normalize.scss
├── 02-tokens/
│   ├── _options.scss          # Primitives (private)
│   ├── _decisions.scss        # Semantic tokens
│   ├── _components.scss       # Component-specific
│   ├── _quasar-bridge.scss    # Maps to Quasar vars
│   └── _index.scss            # Public API
├── 03-layout/
│   ├── _grid.scss
│   └── _container.scss
├── 04-utils/
│   ├── _spacing.scss
│   └── _text.scss
├── 05-components/
│   ├── _atoms/
│   ├── _molecules/
│   └── _organisms/
└── main.scss

6. CSS Layers Implementation

// main.scss
@layer reset, tokens, layout, utils, components;

@layer reset {
  @import "01-reset/normalize";
}

@layer tokens {
  // Tokens generate CSS custom properties
  @import "02-tokens/index";
}

@layer layout {
  @import "03-layout/grid";
  @import "03-layout/container";
}

@layer utils {
  @import "04-utils/spacing";
  @import "04-utils/text";
}

@layer components {
  @import "05-components/atoms/button";
  @import "05-components/molecules/search-bar";
}

7. Practical Workflow

  1. Designer creates in Figma (Atomic Design structure)
  2. Extract design tokens → Goes into 02-tokens/_options.scss and _decisions.scss
  3. Map to Quasar → Override Quasar variables via _quasar-bridge.scss
  4. Build components → Use BEM methodology with token references
  5. Non-Quasar components → Build using your tokens in the components layer

8. Example: Building a Custom Button

// 02-tokens/_decisions.scss
$button-padding-y: 8px;
$button-padding-x: 16px;
$button-radius: 4px;

// 05-components/_atoms/_button.scss
.btn {
  // Use decision tokens
  padding: $button-padding-y $button-padding-x;
  border-radius: $button-radius;

  &--primary {
    background: $color-primary;
    color: $color-text-on-primary;
  }

  &--outline {
    border: 2px solid $color-primary;
    color: $color-primary;
  }

  &__icon {
    margin-right: $spacing-small;
  }
}

Key Recommendations

  1. Start with 2 layers (Options + Decisions) - add Component tokens later if needed
  2. Make Option tokens private - only expose Decision/Component tokens to developers
  3. Keep Quasar as-is for standard components, override where needed
  4. Use your token layer as the bridge between design and Quasar
  5. BEM for custom components - leverage tokens for values
  6. Document which tokens are public in your 02-tokens/_index.scss

This approach gives you:

  • ✅ Design token architecture (flexibility + automation potential)
  • ✅ ITCSS organization (scalability)
  • ✅ Atomic Design (designer alignment)
  • ✅ BEM (component clarity)
  • ✅ Quasar integration (framework leverage)

Complete break down

// ============================================================================
// 02-TOKENS LAYER - DESIGN TOKEN ARCHITECTURE
// ============================================================================
//
// WHAT ARE THESE THREE LAYERS?
// -----------------------------
// This is NOT SCSS-specific - it's a design token architecture pattern
// from the "Design Token-Based UI Architecture" methodology.
//
// Think of it as THREE LEVELS OF DECISION-MAKING:
//
// ┌─────────────────────────────────────────────────────────────────┐
// │ LEVEL 1: OPTIONS (What CAN we use?)                            │
// │ ├─ Question: "What colors/sizes are available in our palette?" │
// │ └─ Example: blue-500, blue-600, spacing-4, spacing-8           │
// └─────────────────────────────────────────────────────────────────┘
//          ↓ (select from options)
// ┌─────────────────────────────────────────────────────────────────┐
// │ LEVEL 2: DECISIONS (How SHOULD we use them?)                   │
// │ ├─ Question: "What does primary color mean? What's our base    │
// │ │             spacing unit?"                                    │
// │ └─ Example: primary = blue-600, spacing-md = spacing-4         │
// └─────────────────────────────────────────────────────────────────┘
//          ↓ (apply decisions to components)
// ┌─────────────────────────────────────────────────────────────────┐
// │ LEVEL 3: COMPONENTS (Where DO we apply them?)                  │
// │ ├─ Question: "What's the button's color? Card's padding?"      │
// │ └─ Example: button-bg = primary, card-padding = spacing-md     │
// └─────────────────────────────────────────────────────────────────┘
//
// WHY THREE LAYERS?
// -----------------
// 1. FLEXIBILITY: Change "primary" from blue to green without touching
//    every component
// 2. CONSISTENCY: All "primary" colors update together
// 3. SCALABILITY: Add new components easily by referencing decisions
// 4. MAINTAINABILITY: Changes flow naturally down the hierarchy
//
// REAL-WORLD ANALOGY:
// -------------------
// OPTIONS    = Paint store (all available paint colors)
// DECISIONS  = Interior designer's palette (colors chosen for the house)
// COMPONENTS = Room assignments (living room = warm-beige, bedroom = cool-blue)
//
// If you change your mind about "warm-beige", you only update the DECISION,
// not every room individually.
//
// HOW DOES THIS WORK IN SCSS?
// ----------------------------
// We use SCSS modules (@use, @forward) to create this hierarchy:
// - _options.scss defines primitives
// - _decisions.scss imports options and creates semantic names
// - _components.scss imports decisions and creates component-specific tokens
// - _index.scss forwards only decisions & components (keeps options private)
//
// RESULT: Developers only see "primary" and "button-bg", not "blue-600"
//

// ----------------------------------------------------------------------------
// 02-tokens/_options.scss (PRIVATE - Primitives/Foundation)
// ----------------------------------------------------------------------------
// LAYER 1: OPTIONS (What's Available)
//
// PURPOSE: Define the raw palette - all possible values we COULD use
// ANALOGY: This is like the paint store's full color chart
// WHO USES: Only other token files (decisions.scss), NOT developers directly
// VISIBILITY: PRIVATE - not exposed to developers (see _index.scss)
//
// WHY KEEP THIS PRIVATE?
// 1. Prevents developers from using random values like $spacing-3 everywhere
// 2. Smaller bundle size (unused options don't bloat CSS)
// 3. Can change without breaking things (no one depends on it directly)
// 4. Forces use of semantic tokens (decisions/components) instead
//
// EXAMPLE SCENARIO:
// Bad:  .my-component { padding: $spacing-3 }  ← What does "3" mean?
// Good: .my-component { padding: $spacing-sm } ← Clear semantic meaning

// Spacing scale (based on 4px grid)
$spacing-1: 4px !default;
$spacing-2: 8px !default;
$spacing-3: 12px !default;
$spacing-4: 16px !default;
$spacing-6: 24px !default;
$spacing-8: 32px !default;

// Border radius options
$radius-sm: 2px !default;
$radius-md: 4px !default;
$radius-lg: 8px !default;
$radius-xl: 16px !default;
$radius-full: 9999px !default;

// Font sizes
$font-size-xs: 12px !default;
$font-size-sm: 14px !default;
$font-size-md: 16px !default;
$font-size-lg: 18px !default;

// Font weights
$font-weight-normal: 400 !default;
$font-weight-medium: 500 !default;
$font-weight-bold: 700 !default;

// Line heights
$line-height-tight: 1.25 !default;
$line-height-normal: 1.5 !default;
$line-height-relaxed: 1.715 !default;

// Color primitives
$color-blue-500: #2196f3 !default;
$color-blue-600: #1976d2 !default;
$color-blue-700: #1565c0 !default;
$color-grey-100: #f5f5f5 !default;
$color-grey-200: #eeeeee !default;
$color-grey-700: #616161 !default;
$color-white: #ffffff !default;

// Shadow primitives (from Quasar's system)
$shadow-1:
  0 1px 3px rgba(0, 0, 0, 0.2),
  0 1px 1px rgba(0, 0, 0, 0.14),
  0 2px 1px -1px rgba(0, 0, 0, 0.12) !default;
$shadow-2:
  0 1px 5px rgba(0, 0, 0, 0.2),
  0 2px 2px rgba(0, 0, 0, 0.14),
  0 3px 1px -2px rgba(0, 0, 0, 0.12) !default;
$shadow-5:
  0 3px 5px -1px rgba(0, 0, 0, 0.2),
  0 5px 8px rgba(0, 0, 0, 0.14),
  0 1px 14px rgba(0, 0, 0, 0.12) !default;

// Transition options
$transition-fast: 0.15s !default;
$transition-normal: 0.3s !default;
$transition-easing: cubic-bezier(0.25, 0.8, 0.5, 1) !default;

// ----------------------------------------------------------------------------
// 02-tokens/_decisions.scss (PUBLIC - Semantic/Contextual)
// ----------------------------------------------------------------------------
// LAYER 2: DECISIONS (How to Use Options)
//
// PURPOSE: Give semantic meaning to raw values - answer "what does it mean?"
// ANALOGY: Interior designer's color palette for the house
// WHO USES: Component files AND developers (this is PUBLIC)
// VISIBILITY: PUBLIC - exposed via _index.scss
//
// KEY CONCEPT: "SEMANTIC NAMING"
// Instead of: $color-blue-600    ← What is this used for?
// We have:    $color-primary     ← Aha! It's our brand color
//
// WHY THIS LAYER EXISTS?
// 1. Context: "primary" has meaning, "blue-600" is just a value
// 2. Changeability: Rebrand from blue to green? Change ONE line here
// 3. Consistency: All "primary" uses update together automatically
// 4. Developer Experience: No guessing which shade to use
//
// REAL EXAMPLE OF VALUE:
// Without decisions: Designer says "change brand color"
//   → You search codebase for all "blue-600" (200+ files)
//   → Miss some, inconsistent results
// With decisions:
//   → Change $color-primary: blue-600 to $color-primary: green-600
//   → Done! Everything updates
//
// REFERENCE PATTERN:
// Notice how we reference options using: opt.$option-name
// This is SCSS modules syntax - it imports from _options.scss
@use "options" as opt;

// Brand colors (semantic naming)
$color-primary: opt.$color-blue-600 !default;
$color-primary-dark: opt.$color-blue-700 !default;
$color-secondary: #26a69a !default;

// Surface colors
$color-surface: opt.$color-white !default;
$color-surface-variant: opt.$color-grey-100 !default;
$color-on-surface: opt.$color-grey-700 !default;
$color-on-primary: opt.$color-white !default;

// Spacing decisions (semantic naming)
$spacing-xs: opt.$spacing-1 !default;
$spacing-sm: opt.$spacing-2 !default;
$spacing-md: opt.$spacing-4 !default;
$spacing-lg: opt.$spacing-6 !default;
$spacing-xl: opt.$spacing-8 !default;

// Interactive element decisions
$interactive-radius: opt.$radius-md !default;
$interactive-radius-round: opt.$radius-full !default;
$interactive-shadow: opt.$shadow-2 !default;
$interactive-shadow-active: opt.$shadow-5 !default;
$interactive-transition: opt.$transition-normal opt.$transition-easing !default;

// Typography decisions
$text-body-size: opt.$font-size-sm !default;
$text-body-line-height: opt.$line-height-relaxed !default;
$text-weight-emphasis: opt.$font-weight-medium !default;

// ----------------------------------------------------------------------------
// 02-tokens/_components.scss (PUBLIC - Component-specific)
// ----------------------------------------------------------------------------
// LAYER 3: COMPONENTS (Where to Apply Decisions)
//
// PURPOSE: Map decisions to specific components - answer "where does it go?"
// ANALOGY: Room-by-room color assignments (living room = warm-beige)
// WHO USES: Component SCSS files (05-components/)
// VISIBILITY: PUBLIC - exposed via _index.scss
//
// KEY CONCEPT: "COMPONENT-SPECIFIC CONTEXT"
// Instead of: .button { background: $color-primary }
// We have:    .button { background: $button-primary-bg }
//             where $button-primary-bg = $color-primary
//
// WHY THIS LAYER EXISTS?
// 1. Clarity: "$button-primary-bg" is more specific than "$color-primary"
// 2. Flexibility: Buttons might need different shades in the future
// 3. Documentation: Self-documenting what each token is for
// 4. Component Isolation: Change button styles without affecting cards
//
// WHEN TO USE COMPONENT TOKENS VS DECISIONS?
//
// Use DECISIONS directly when:
//   → Simple, one-off usage
//   → No component-specific variations needed
//   Example: .error-message { color: $color-error }
//
// Use COMPONENT TOKENS when:
//   → Multiple related properties for same component
//   → Might need component-specific variations later
//   → Building a reusable component library
//   Example: All button-related tokens grouped together
//
// REAL EXAMPLE SCENARIO:
// Imagine: "Make buttons slightly darker than the primary color"
// Without component tokens:
//   → Change $color-primary → breaks cards, badges, etc.
// With component tokens:
//   → Change $button-primary-bg = $color-primary-dark
//   → Only buttons affected!
//
@use "decisions" as dec;

// Button component tokens
// Notice: We're creating a "namespace" for all button-related tokens
$button-padding-y: dec.$spacing-sm !default;
$button-padding-x: dec.$spacing-md !default;
$button-padding: $button-padding-y $button-padding-x !default;
$button-padding-dense: 0.285em !default;

$button-radius: dec.$interactive-radius !default;
$button-radius-rounded: dec.$interactive-radius-round !default;
$button-radius-push: 7px !default; // Kept from Quasar for compatibility

$button-font-size: dec.$text-body-size !default;
$button-line-height: dec.$text-body-line-height !default;
$button-font-weight: dec.$text-weight-emphasis !default;

$button-transition: dec.$interactive-transition !default;

$button-shadow: dec.$interactive-shadow !default;
$button-shadow-active: dec.$interactive-shadow-active !default;

// Button variant tokens (primary)
$button-primary-bg: dec.$color-primary !default;
$button-primary-text: dec.$color-on-primary !default;
$button-primary-bg-hover: dec.$color-primary-dark !default;

// Button variant tokens (secondary)
$button-secondary-bg: dec.$color-secondary !default;
$button-secondary-text: dec.$color-on-primary !default;

// Button variant tokens (outline)
$button-outline-border: dec.$color-primary !default;
$button-outline-text: dec.$color-primary !default;
$button-outline-bg-hover: dec.$color-surface-variant !default;

// FAB specific
$button-fab-icon-size: 24px !default;

// Card component tokens
$card-padding: dec.$spacing-lg !default;
$card-radius: dec.$interactive-radius !default;
$card-bg: dec.$color-surface !default;
$card-shadow: dec.$interactive-shadow !default;

$card-header-padding: dec.$spacing-md dec.$spacing-lg !default;
$card-body-padding: dec.$spacing-lg !default;
$card-footer-padding: dec.$spacing-md dec.$spacing-lg !default;

// ----------------------------------------------------------------------------
// 02-tokens/_quasar-bridge.scss
// ----------------------------------------------------------------------------
// THE BRIDGE: Connects Your Token System to Quasar Framework
//
// PURPOSE: Map your design tokens to Quasar's variable names
// WHY NEEDED: Quasar expects specific variable names like $button-padding
//
// HOW IT WORKS:
// 1. You define tokens: $button-padding: 8px 16px
// 2. Quasar expects: $button-padding variable
// 3. Bridge maps: $button-padding (Quasar) = $button-padding (yours)
//
// IMPORT ORDER IS CRITICAL:
// ┌─────────────────────────────────────────┐
// │ 1. Import this bridge file              │ ← Sets variables
// │ 2. Import Quasar                        │ ← Uses those variables
// │ 3. Import your custom components        │ ← Uses both
// └─────────────────────────────────────────┘
//
// If you import Quasar BEFORE the bridge:
//   → Quasar uses its defaults (your tokens ignored!)
//   → Your customizations don't apply
//
// WHAT !default MEANS:
// $variable: value !default;
//   → "Use this value IF the variable isn't already defined"
//   → Allows easy overriding later
//   → Quasar uses !default everywhere for customizability
//
// TWO APPROACHES:
//
// Approach A - Direct mapping (simple):
//   $button-padding: 8px 16px;
//   (Define directly in bridge)
//
// Approach B - Reference tokens (recommended):
//   @use 'components' as comp;
//   $button-padding: comp.$button-padding;
//   (Map from your component tokens)
//
// We use Approach B because:
//   → Single source of truth (component tokens)
//   → Change tokens, Quasar updates automatically
//   → Consistency between custom components and Quasar components
//
// Bridge layer: Maps your tokens to Quasar's variable names
// This file overrides Quasar defaults with your design tokens
@use "components" as comp;
@use "decisions" as dec;

// Override Quasar's button variables with your component tokens
// Pattern: $quasar-var-name: comp.$your-token-name
$button-border-radius: comp.$button-radius !default;
$button-padding: comp.$button-padding !default;
$button-dense-padding: comp.$button-padding-dense !default;
$button-fab-icon-font-size: comp.$button-fab-icon-size !default;
$button-transition: comp.$button-transition !default;
$button-font-size: comp.$button-font-size !default;
$button-line-height: comp.$button-line-height !default;
$button-font-weight: comp.$button-font-weight !default;
$button-shadow: comp.$button-shadow !default;
$button-shadow-active: comp.$button-shadow-active !default;
$button-rounded-border-radius: comp.$button-radius-rounded !default;
$button-push-border-radius: comp.$button-radius-push !default;

// Override Quasar's color variables
$primary: dec.$color-primary !default;
$secondary: dec.$color-secondary !default;

// Override spacing (if Quasar uses $space-base)
$space-base: dec.$spacing-md !default;

//
// WHAT GETS OVERRIDDEN?
// ---------------------
// When Quasar sees: $button-padding !default;
// It checks: "Is $button-padding already defined?"
//   → YES (we defined it above) → Use our value ✓
//   → NO → Use Quasar's default
//
// RESULT: All Quasar buttons automatically use your design tokens!

// ----------------------------------------------------------------------------
// 02-tokens/_index.scss (Public API)
// ----------------------------------------------------------------------------
// THE GATEKEEPER: Controls What Developers Can Access
//
// PURPOSE: Define the PUBLIC API of your token system
// THINK OF IT AS: The "exports" of your token module
//
// HOW IT WORKS:
// @forward 'decisions';  ← Makes everything from decisions.scss available
// @forward 'components'; ← Makes everything from components.scss available
// (no @forward for 'options') ← Options stay PRIVATE/hidden
//
// WHY THIS PATTERN?
// 1. ENCAPSULATION: Hide implementation details (options)
// 2. BETTER DX: Developers only see what they should use
// 3. SMALLER BUNDLES: Unused options don't get compiled
// 4. NON-BREAKING CHANGES: Change options without breaking developer code
//
// WHAT DOES @forward DO?
// When you @use '02-tokens', you get access to everything @forwarded here
// It's like saying "here's what's public, everything else is private"
//
// ANALOGY:
// Think of a restaurant:
// - Kitchen (options) = Private, customers don't see it
// - Menu (decisions/components) = Public, this is what customers use
// - _index.scss = The menu board that lists what's available
//
// SCSS MODULES PRIMER:
// @use 'file' as name;   → Import for use in THIS file only
// @forward 'file';       → Re-export for others who import THIS file
// @import 'file';        → Old way (global namespace, avoid in new code)

@forward "decisions";
@forward "components";
// Note: 'options' is NOT forwarded - it's private/internal only

// ============================================================================
// 05-COMPONENTS LAYER (Atomic Design Structure)
// ============================================================================

// ----------------------------------------------------------------------------
// 05-components/_atoms/_button.scss
// ----------------------------------------------------------------------------
// Custom button using BEM + Design Tokens
// This demonstrates building components alongside Quasar
@use "../../02-tokens" as tokens;

.btn {
  // Base button styles using component tokens
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: tokens.$button-padding;
  border-radius: tokens.$button-radius;
  font-size: tokens.$button-font-size;
  line-height: tokens.$button-line-height;
  font-weight: tokens.$button-font-weight;
  transition: tokens.$button-transition;
  cursor: pointer;
  border: none;
  text-decoration: none;
  user-select: none;

  // Variants (BEM modifiers)
  &--primary {
    background-color: tokens.$button-primary-bg;
    color: tokens.$button-primary-text;
    box-shadow: tokens.$button-shadow;

    &:hover {
      background-color: tokens.$button-primary-bg-hover;
      box-shadow: tokens.$button-shadow-active;
    }

    &:active {
      box-shadow: tokens.$button-shadow;
    }
  }

  &--secondary {
    background-color: tokens.$button-secondary-bg;
    color: tokens.$button-secondary-text;
    box-shadow: tokens.$button-shadow;

    &:hover {
      opacity: 0.9;
      box-shadow: tokens.$button-shadow-active;
    }
  }

  &--outline {
    background-color: transparent;
    color: tokens.$button-outline-text;
    border: 2px solid tokens.$button-outline-border;
    box-shadow: none;

    &:hover {
      background-color: tokens.$button-outline-bg-hover;
    }
  }

  &--rounded {
    border-radius: tokens.$button-radius-rounded;
  }

  &--dense {
    padding: tokens.$button-padding-dense;
  }

  &--block {
    display: flex;
    width: 100%;
  }

  // States
  &:disabled,
  &--disabled {
    opacity: 0.6;
    cursor: not-allowed;
    pointer-events: none;
  }

  // Elements (BEM elements)
  &__icon {
    &--left {
      margin-right: tokens.$spacing-sm;
    }

    &--right {
      margin-left: tokens.$spacing-sm;
    }
  }

  &__label {
    flex: 1;
  }
}

// ----------------------------------------------------------------------------
// 05-components/_molecules/_card.scss
// ----------------------------------------------------------------------------
// Custom card component using BEM + Design Tokens
@use "../../02-tokens" as tokens;

.card {
  background-color: tokens.$card-bg;
  border-radius: tokens.$card-radius;
  box-shadow: tokens.$card-shadow;
  overflow: hidden;

  // Elements
  &__header {
    padding: tokens.$card-header-padding;
    border-bottom: 1px solid tokens.$color-surface-variant;
  }

  &__title {
    margin: 0;
    font-size: tokens.$text-body-size;
    font-weight: tokens.$text-weight-emphasis;
    color: tokens.$color-on-surface;
  }

  &__body {
    padding: tokens.$card-body-padding;
  }

  &__footer {
    padding: tokens.$card-footer-padding;
    border-top: 1px solid tokens.$color-surface-variant;
    display: flex;
    justify-content: flex-end;
    gap: tokens.$spacing-sm;
  }

  // Modifiers
  &--flat {
    box-shadow: none;
    border: 1px solid tokens.$color-surface-variant;
  }

  &--bordered {
    border: 1px solid tokens.$color-surface-variant;
  }
}

// ----------------------------------------------------------------------------
// 05-components/_quasar-overrides/_q-btn-custom.scss
// ----------------------------------------------------------------------------
// Additional customization for Quasar's q-btn component
// This goes beyond variable overrides for specific use cases
@use "../../02-tokens" as tokens;

.q-btn {
  // Add custom variant that Quasar doesn't have
  &.q-btn--gradient-primary {
    background: linear-gradient(
      135deg,
      tokens.$button-primary-bg 0%,
      tokens.$button-primary-bg-hover 100%
    );
    color: tokens.$button-primary-text;
  }

  // Custom size variant
  &.q-btn--xs {
    font-size: 12px;
    padding: tokens.$spacing-xs tokens.$spacing-sm;
  }

  // Industry-specific variant (e.g., for your domain)
  &.q-btn--action {
    text-transform: none;
    letter-spacing: 0.5px;
    font-weight: tokens.$font-weight-bold;
  }
}

// ============================================================================
// MAIN.SCSS - Putting it all together
// ============================================================================
//
// THE COMPLETE IMPORT STRATEGY
// =============================
//
// CRITICAL SECTION: Understanding Import Order & CSS Layers
//
// PART 1: SCSS IMPORT ORDER (for variable overrides)
// ---------------------------------------------------
// This happens at COMPILE TIME (before CSS is generated)
//
// Step 1: Import Quasar bridge BEFORE Quasar itself
// ↓
@use "02-tokens/quasar-bridge";
//    This defines variables like $button-padding
//
// Step 2: Import Quasar (it will use your overridden variables)
// 
@import "quasar/src/css/index.sass";
//    Quasar reads $button-padding and uses YOUR value
//    Why @import here? Quasar uses old syntax, we must too
//
// 💡 KEY INSIGHT:
// The ORDER matters because SCSS processes files sequentially
// If you import Quasar BEFORE bridge, it uses defaults (bridge is too late!)
//
//
// PART 2: CSS LAYERS (for cascade control)
// -----------------------------------------
// This happens at RUNTIME (in the browser)
//
// Step 3: Define CSS layers for proper cascade control
// 
@layer reset, tokens, layout, quasar-overrides, components, utilities;
//
// WHAT ARE CSS LAYERS? (CSS feature, not SCSS)
// CSS Layers control specificity without using !important
// Think of them as "priority buckets" for your styles
//
// WHY USE LAYERS?
// Without layers:
//   .button { color: blue; }       Specificity: 0,1,0
//   .btn { color: red; }           Specificity: 0,1,0
//    Last one wins (source order matters, fragile!)
//
// With layers:
//   @layer base { .button { color: blue; } }
//   @layer components { .btn { color: red; } }
//   → "components" layer wins (explicit priority, predictable!)
//
// LAYER ORDER = PRIORITY (Lower → Higher)
// ┌─────────────────────────────────────────────────────────────┐
// │ 1. reset          ← Lowest priority (normalize.css, etc.)  │
// │ 2. tokens         ← CSS custom properties (if needed)      │
// │ 3. layout         ← Grid, containers, structure            │
// │ 4. quasar-overrides ← Modify Quasar components             │
// │ 5. components     ← Your custom components (BEM)           │
// │ 6. utilities      ← Highest priority (spacing, text utils) │
// └─────────────────────────────────────────────────────────────┘
//
// EXAMPLE IN ACTION:
// Quasar button has: .q-btn { padding: 8px }
// Your layer has:    @layer components { .q-btn { padding: 12px } }
// → Your padding wins because "components" layer is higher priority!
//
// HOW IT RELATES TO YOUR ITCSS:
// Your structure:       CSS Layer:
// 01-reset        →     @layer reset
// 02-tokens       →     @layer tokens
// 03-layout       →     @layer layout
// 04-utils        →     @layer utilities
// 05-components   →     @layer components
//
// WHY quasar-overrides LAYER?
// → Sometimes you need to modify Quasar components beyond variables
// → This layer sits between layout and your components
// → Gives you surgical control over Quasar without !important

@layer reset {
  @import "01-reset/normalize";
}

@layer tokens {
  // Generate CSS custom properties from tokens if needed
  // Example: :root { --color-primary: #1976d2; }
  // This is optional - useful for runtime theme switching
  @import "02-tokens/css-properties"; // Optional
}

@layer layout {
  @import "03-layout/grid";
  @import "03-layout/container";
}

@layer quasar-overrides {
  // Additional Quasar customizations beyond variable overrides
  @import "05-components/quasar-overrides/q-btn-custom";
}

@layer components {
  // Your custom components (Atomic Design structure)
  @import "05-components/atoms/button";
  @import "05-components/molecules/card";
  // ... more components
}

@layer utilities {
  @import "04-utils/spacing";
  @import "04-utils/text";
}

//
// COMPLETE MENTAL MODEL:
// =====================
//
// COMPILE TIME (SCSS):
// 1. Bridge defines variables
// 2. Quasar reads those variables
// 3. Everything compiles to CSS
//
// RUNTIME (Browser):
// 1. Reset styles apply (lowest priority)
// 2. Tokens/layout provide structure
// 3. Quasar components render
// 4. Your overrides apply (if needed)
// 5. Your custom components work alongside Quasar
// 6. Utilities can override anything (highest priority)
//
// RESULT:
// ✓ Quasar uses your design tokens automatically
// ✓ You can override Quasar when needed
// ✓ Your custom components stay consistent
// ✓ Predictable cascade (no specificity wars!)
//

// ============================================================================
// USAGE EXAMPLES
// ============================================================================

/*
<!-- Using Quasar button (automatically uses your tokens) -->
<q-btn 
  color="primary" 
  label="Click Me"
/>

<!-- Using Quasar button with custom override -->
<q-btn 
  class="q-btn--gradient-primary"
  label="Gradient Button"
/>

<!-- Using your custom BEM button -->
<button class="btn btn--primary">
  <span class="btn__icon btn__icon--left">🚀</span>
  <span class="btn__label">Launch</span>
</button>

<!-- Using your custom card -->
<div class="card">
  <div class="card__header">
    <h3 class="card__title">Card Title</h3>
  </div>
  <div class="card__body">
    Card content goes here
  </div>
  <div class="card__footer">
    <button class="btn btn--outline">Cancel</button>
    <button class="btn btn--primary">Save</button>
  </div>
</div>

<!-- Mixing Quasar and custom components -->
<div class="card">
  <div class="card__body">
    <q-input label="Name" />
  </div>
  <div class="card__footer">
    <q-btn flat label="Cancel" />
    <q-btn color="primary" label="Submit" />
  </div>
</div>
*/