Skip to content

Variables & Utilities

The NETWRIX project uses a two-tier variable system that provides both foundation-level tokens and component-specific configurations. Understanding this system is crucial for maintaining consistency and enabling the Global Components library.


The primary variables file contains all foundation-level design tokens that define the core visual language of the system.

Location: src/scss/framework/_var/_vars.scss

_vars.scss serves as the single source of truth for all foundational design decisions:

  • ✅ Color palette definitions
  • ✅ Typography settings (font families)
  • ✅ Base spacing unit ($measure)
  • ✅ Grid configuration
  • ✅ Breakpoints
  • ✅ Animation timing
  • ✅ Border radius values
  • ✅ Container widths
  • ✅ And more…

Colors:

$color-a: #1A1536; // Navy
$color-b: #FCFAF5; // Cream
$color-c: #5851DB; // Purple
// ... (14 colors total: a through n)

Base Measure:

$measure: 0.5rem; // 0.5rem = 8px - Foundation for all spacing

Typography:

$type-a: "Hubot Sans", "HubotSans-fallback", "Courier New", monospace;
$type-b: "Syne", "Syne-fallback", "Trebuchet MS", "Verdana", sans-serif;

Grid System:

$viewport-type: max-width;
$columns: 12;
$gutter-width: 32px;
$half-gutter-width: $gutter-width * 0.5;
$gutter-compensation: -1 * $half-gutter-width;

Breakpoints:

$all: 0;
$desktop: 1700px;
$laptop: 1570px;
$tabletl: 1300px;
$tabletm: 1024px;
$tablets: 810px;
$mobile: 580px;

Border Radius:

$border-radius-a: $measure; // 8px
$border-radius-b: $measure*4; // 32px

Animation Timing:

$time-a: 0.1s; // Micro-interactions (buttons, toggles)
$time-b: 0.3s; // Expansion, system communication, toast
$time-c: 0.6s; // Background dimming

Easing Functions:

// Standard easing
$ease-standard-a: cubic-bezier(0.2, 0, 0.38, 0.9); // productive
$ease-standard-b: cubic-bezier(0, 0, 0.3, 1); // expressive
// Entrance easing
$ease-entrance-a: cubic-bezier(0, 0, 0.38, 0.9); // productive
$ease-entrance-b: cubic-bezier(0.4, 0.14, 0.3, 1); // expressive
// Exit easing
$ease-exit-a: cubic-bezier(0.2, 0, 1, 0.9); // productive
$ease-exit-b: cubic-bezier(0.4, 0.14, 1, 1); // expressive

These variables are imported throughout the project and form the foundation for all styling:

// In any component SCSS file
@use "sass:map";
@use "@scss/framework/_var/_vars.scss" as *;
.my-component {
color: map.get($color-options, a); // Use color tokens
padding: $measure * 4; // Use spacing scale
font-family: $type-b; // Use typography
border-radius: $border-radius-a; // Use border radius
transition: all $time-b $ease-standard-b; // Use timing & easing
@media all and ($viewport-type: $tablets) {
padding: $measure * 3; // Responsive with breakpoints
}
}

Global Components Variables (_global-vars.scss)

Section titled “Global Components Variables (_global-vars.scss)”

This file extends and configures the foundation variables specifically for the Global Components library. It’s where the magic happens to customize the pre-built components to match NETWRIX’s design system.

Location: src/scss/global-components/_global-vars.scss

As mentioned in Chapter 1, Global Components is a pre-built HTML and SCSS framework developed by Terra that provides ready-to-use UI components. These components use the g-- prefix (e.g., g--card-03, g--button-02).

The Global Components library is extremely flexible but needs to be configured to match your project’s design system. This is where _global-vars.scss comes in.

_global-vars.scss serves two critical functions:

  1. Passes foundation variables to the Global Components library
  2. Configures component-specific spacing, padding, and layout values that alter how Global Components render

The Flow:

  1. Foundation defined in _vars.scss:

    $measure: 0.5rem; // 8px
  2. Passed to Global Components in _global-vars.scss:

    $btn-padding: $measure*1.5 $measure * 3, // 12px 24px
  3. Applied to components by Global Components library:

    // Inside Global Components library
    .g--button-01 {
    padding: $btn-padding; // Results in: padding: 12px 24px;
    }
  4. Used in HTML:

    <button class="g--button-01">Click Me</button>
    <!-- Button now has 12px vertical and 24px horizontal padding -->

Beyond colors, typography, spacing, and grid, the NETWRIX foundations include several other essential design tokens.

Border radius tokens provide consistent corner rounding across all components.

Variables:

$border-radius-a: $measure; // 8px - Small radius (subtle rounding)
$border-radius-b: $measure*4; // 32px - Large radius (pronounced rounding)

Usage:

.my-card {
border-radius: $border-radius-a; // 8px - Standard cards, buttons
}
.my-pill {
border-radius: $border-radius-b; // 32px - Pills, badges, rounded elements
}

When to use:

  • $border-radius-a (8px): Standard UI elements - cards, buttons, inputs, containers
  • $border-radius-b (32px): Pills, badges, fully-rounded buttons, special decorative elements

Animation timing tokens ensure consistent motion design throughout the application.

Duration Tokens:

TokenDurationUse Case
$time-a0.1sMicro-interactions, button states, toggles
$time-b0.3sStandard transitions, dropdowns, modals
$time-c0.6sSlow transitions, backgrounds, page transitions

Easing Functions:

When to Use Each Type:

  • Standard Easing: General transitions, state changes, hover effects
  • Entrance Easing: Modals opening, dropdowns appearing, content sliding in
  • Exit Easing: Modals closing, dropdowns disappearing, content sliding out

Productive vs Expressive:

  • Productive (a): Fast, efficient, business-like - use for utility UI
  • Expressive (b): Smooth, dramatic, attention-getting - use for important interactions

Example Usage:

// Button with micro-interaction
.button {
transition:
background-color $time-a $ease-standard-a,
transform $time-a $ease-standard-a;
&:hover {
transform: translateY(-2px);
}
}
// Modal with entrance/exit animations
.modal {
opacity: 0;
transform: scale(0.95);
transition:
opacity $time-b $ease-entrance-b,
transform $time-b $ease-entrance-b;
&--active {
opacity: 1;
transform: scale(1);
}
}

Utilities are single-purpose CSS classes that apply specific styles. They’re essential for rapid development and maintaining consistency.

Location: src/scss/framework/utilities/_utilities.scss

The system already includes these utility categories:

@forward './align-items.scss'; // Flexbox alignment
@forward './aspect-ratio.scss'; // Aspect ratio utilities
@forward './display.scss'; // Display properties
@forward './flex-direction.scss'; // Flex direction
@forward './font-style.scss'; // Font styles (italic, etc.)
@forward './font-weight.scss'; // Font weights
@forward './height.scss'; // Height utilities
@forward './justify-content.scss'; // Flexbox justify
@forward './opacity.scss'; // Opacity values
@forward './overflow.scss'; // Overflow properties
@forward './position.scss'; // Position (absolute, relative, etc.)
@forward './spacing.scss'; // Margin and padding
@forward './text-align.scss'; // Text alignment
@forward './text-transform.scss'; // Text transform
@forward './width.scss'; // Width utilities

Here’s the step-by-step process for creating new utility classes:

Create a new SCSS file in src/scss/framework/utilities/ with a descriptive name.

Example: Let’s create cursor utilities. Create file: src/scss/framework/utilities/_cursor.scss.

Use the established pattern with mixins and loops to generate responsive utility classes:

src/scss/framework/utilities/_cursor.scss
@use "@scss/framework/_var/_vars.scss" as *;
// Define cursor values
$cursor-values: (
pointer: pointer,
default: default,
not-allowed: not-allowed,
grab: grab,
grabbing: grabbing,
move: move,
text: text,
wait: wait,
help: help,
) !default;
// Define breakpoints (if you need responsive cursors)
$cursor-breakpoints: (
all: $all,
tablets: $tablets,
mobile: $mobile,
);
// Create mixin to generate utilities
@mixin cursor-utility($cursor-prop, $breakpoints) {
@each $breakpoint-name, $breakpoint-value in $breakpoints {
@if ($breakpoint-value == 0) {
// Non-responsive utilities
@each $name, $property in $cursor-prop {
.u--cursor-#{$name} {
cursor: $property;
}
}
} @else {
// Responsive utilities
@media screen and ($viewport-type: $breakpoint-value) {
@each $name, $property in $cursor-prop {
.u--cursor-#{$breakpoint-name}-#{$name} {
cursor: $property;
}
}
}
}
}
}
// Generate utilities
@include cursor-utility($cursor-values, $cursor-breakpoints);

This generates classes like:

.u--cursor-pointer { cursor: pointer; }
.u--cursor-grab { cursor: grab; }
.u--cursor-tablets-pointer { cursor: pointer; } /* at tablets breakpoint */

Add your new utility to the main utilities index file:

src/scss/framework/utilities/_utilities.scss
@forward './align-items.scss';
@forward './aspect-ratio.scss';
@forward './display.scss';
// ... existing utilities ...
@forward './cursor.scss'; // ← Add your new utility here

Now you can use your new utilities:

<button class="u--cursor-pointer">Clickable Button</button>
<div class="u--cursor-grab">Draggable Element</div>
<button class="u--cursor-not-allowed" disabled>Disabled Button</button>

  • ✅ Use utilities for common, repeatable styles
  • ✅ Follow the established naming convention (u--{property}-{value})
  • ✅ Generate responsive variants when appropriate
  • ✅ Use $measure for spacing-related utilities
  • ✅ Document new utilities in code comments
  • ✅ Keep utilities simple and single-purpose
  • ❌ Don’t create utilities for complex, component-specific styles
  • ❌ Don’t use arbitrary values (always use design tokens)
  • ❌ Don’t create too many rare-use utilities (adds to CSS bloat)
  • ❌ Don’t override existing utilities unnecessarily
  • ❌ Don’t forget to forward new utilities in _utilities.scss

  • ✅ Use color variables ($color-a, $color-b, etc.) in SCSS
  • ✅ Use .f--color-* utility classes in HTML for text colors
  • ✅ Ensure sufficient contrast for accessibility
  • ❌ Don’t use hardcoded hex values
  • ❌ Don’t create colors not in the design system
  • ✅ Use .f--font-* utility classes (a through g)
  • ✅ Use Hubot Sans for headings, Syne for body text
  • ✅ Let responsive scaling work automatically
  • ❌ Don’t use arbitrary font sizes
  • ❌ Don’t override line-heights without reason
  • ✅ Use spacing utilities (.u--pt-*, .u--pb-*, etc.)
  • ✅ Use $measure multiples in SCSS
  • ✅ Apply responsive spacing for mobile
  • ❌ Don’t use arbitrary pixel values
  • ❌ Don’t forget responsive spacing adjustments
  • ✅ Use container → row → column hierarchy
  • ✅ Plan responsive columns for all breakpoints
  • ✅ Use gaps for vertical spacing
  • ❌ Don’t skip the row wrapper
  • ❌ Don’t nest containers
  • ✅ Use _vars.scss for foundation-level tokens
  • ✅ Use _global-vars.scss to configure Global Components
  • ✅ Understand the cascade from measure → global vars → components
  • ❌ Don’t duplicate variable definitions
  • ❌ Don’t override global component vars locally

❌ Wrong:

.my-component {
padding: 23px;
color: #1a1a1a;
margin-bottom: 37px;
}

✅ Correct:

@use "sass:map";
@use "@scss/framework/_var/_vars.scss" as *;
.my-component {
padding: $measure * 3; // 24px using measure scale
color: map.get($color-options, a); // Navy using color token
margin-bottom: $measure * 5; // 40px using measure scale
}

❌ Wrong:

<div class="f--col-4">
<div class="card">Card content</div>
</div>

✅ Correct:

<div class="f--col-4 f--col-tabletm-6 f--col-tablets-12">
<div class="card">Card content</div>
</div>

❌ Wrong:

<div class="f--container">
<div class="f--col-6">Content</div>
</div>

✅ Correct:

<div class="f--container">
<div class="f--row">
<div class="f--col-6">Content</div>
</div>
</div>

ScenarioUse _vars.scssUse _global-vars.scss
Define new color✅ Yes❌ No
Change base spacing✅ Yes❌ No
Configure button padding❌ No✅ Yes
Add breakpoint✅ Yes❌ No
Adjust card spacing❌ No✅ Yes
Change font family✅ Yes❌ No

Create a utility when:

  • ✅ The style is used across multiple components
  • ✅ It’s a single, atomic CSS property
  • ✅ It needs responsive variants
  • ✅ It implements a design token

Don’t create a utility when:

  • ❌ It’s component-specific styling
  • ❌ It requires multiple CSS properties working together
  • ❌ It’s only used once in the entire project

You’ve now completed the Foundations chapter! 🎉

Next Chapter: Components & Modules

In the next chapter, you’ll learn:

  • 🧩 Component Architecture - How components are structured in NETWRIX
  • 🔧 Building Custom Components - Creating new components from Figma designs
  • 📦 Using Global Components - Leveraging the g-- prefixed component library
  • 🎨 Component Variants - Implementing different component variations
  • 📱 Responsive Components - Making components work across all devices
  • Component States - Hover, active, focus, disabled states
  • 🔄 Component Composition - Combining components to build complex modules

Foundations are the DNA of the NETWRIX design system. By mastering these core tokens and patterns, you ensure:

Visual Consistency - Every element aligns with the design system ✅ Maintainability - Changes propagate automatically through token updates ✅ Efficiency - Predefined patterns accelerate development ✅ Quality - Pixel-perfect implementation of Figma designs ✅ Scalability - Easy to extend and adapt as the system grows

Key Takeaway: Always start with foundations. Before writing any custom CSS, ask yourself: “Is there a foundation token, utility class, or grid pattern that can accomplish this?”