M
@mastors/core v1.x

@mastors/core

The design system foundation

@mastors/core is a utility-first SCSS library providing design tokens, utility classes, mixins, functions, and a responsive engine. It is the foundation for every package in the Mastors design system — and can be consumed standalone.

18
Utility Modules
10
Token Types
6
Breakpoints
2
Themes
All token-generated classes are driven by SCSS maps. The library uses CSS custom properties so themes update at runtime without a rebuild.

Installation

Add the package via your package manager of choice.

npm

npm install @mastors/core

yarn

yarn add @mastors/core

pnpm

pnpm add @mastors/core

Import & Usage

The main entry point compiles the full library in this order: config → abstracts → variables → tokens → functions → mixins → base → themes → semantic → responsive → helpers → utilities → accessibility.

Full import (outputs all CSS)

@use "@mastors/core";

Selective import (tokens + mixins only, no utility output)

@use "@mastors/core/scss/tokens/color"   as ct;
@use "@mastors/core/scss/tokens/spacing" as sp;
@use "@mastors/core/scss/mixins/breakpoint" as *;

.card {
  padding: sp.spacing(4);
  background: ct.color("primary", 50);

  @include bp(md) {
    padding: sp.spacing(8);
  }
}

Using the vars() function

@use "@mastors/core/scss/functions/vars" as *;

.btn {
  background: vars(accent);
  color: vars(accent-text);
  padding: vars(spacing-2) vars(spacing-4);
  border-radius: vars(radius-md);
  box-shadow: vars(shadow-sm, none);
}

Design Tokens

Colors

Token

6 palettes × 11 shades (50–950) plus white, black, and transparent. Each color is also emitted as a CSS custom property: --mastors-color-{palette}-{shade}.

@use "@mastors/core/scss/tokens/color" as ct;

// Accessor
$blue: ct.color("primary", 500); // → #3b82f6
$green-50: ct.color("success", 50); // → #f0fdf4
$white: ct.color("white");          // → #fff

primary

success

warning

error

info

neutral

Spacing

Token

A complete scale from 0 to 96 (0 → 24rem). Emitted as --mastors-spacing-{key}.

@use "@mastors/core/scss/tokens/spacing" as sp;

.btn { padding: sp.spacing(2) sp.spacing(4); }
// → padding: 0.5rem 1rem;
KeyValuepx
00px0
px1px1px
0.50.125rem2px
10.25rem4px
20.5rem8px
30.75rem12px
41rem16px
61.5rem24px
82rem32px
123rem48px
164rem64px
246rem96px
328rem128px
6416rem256px
9624rem384px

Sizing

Token

Width/height scale including fractional percentages, viewport units and keyword values. Emitted as --mastors-sizing-{key}.

@use "@mastors/core/scss/tokens/sizing" as sz;

.hero { width: sz.sizing("full"); height: sz.sizing("screen"); }
.card { width: sz.sizing("1/3"); max-width: sz.sizing(64); }
KeyValue
00
1/250%
1/333.3333%
2/366.6667%
1/425%
3/475%
full100%
screen100vw
svw100svw
dvw100dvw
autoauto
minmin-content
maxmax-content
fitfit-content

Typography

Token

Font sizes (xs–9xl), weights (thin–black), families (sans/serif/mono), line heights, and letter spacing. Emitted as CSS custom properties.

@use "@mastors/core/scss/tokens/typography" as ty;

h1 {
  font-size:   ty.font-size("4xl");   // 2.25rem
  font-weight: ty.font-weight("bold"); // 700
  line-height: ty.line-height("tight"); // 1.25
  letter-spacing: ty.letter-spacing("tight"); // -0.025em
}

code {
  font-family: ty.font-family("mono");
}
9xl — 8rem
4xl — 2.25rem
2xl — 1.5rem
lg — 1.125rem
base — 1rem
sm — 0.875rem
xs — 0.75rem

Shadows

Token

8 elevation steps: xs, sm, md, lg, xl, 2xl, inner, none. Emitted as --mastors-shadow-{key}.

@use "@mastors/core/scss/tokens/shadows" as sh;

.card  { box-shadow: sh.shadow("md"); }
.modal { box-shadow: sh.shadow("2xl"); }
.input { box-shadow: sh.shadow("inner"); }

xs

sm

md

lg

xl

2xl

inner

Radii

Token

Border-radius scale from none (0) to full (9999px). Emitted as --mastors-radius-{key}.

@use "@mastors/core/scss/tokens/radii" as ra;

.btn   { border-radius: ra.radius("md"); }   // 0.375rem
.badge { border-radius: ra.radius("full"); } // 9999px
.card  { border-radius: ra.radius("xl"); }   // 0.75rem
none
sm
base
md
lg
xl
2xl
3xl
full

Opacity

Token

17-step opacity scale 0–100. Emitted as --mastors-opacity-{key}.

@use "@mastors/core/scss/tokens/opacity" as op;

.overlay { opacity: op.opacity(50); } // → 0.5
.disabled { opacity: op.opacity(30); } // → 0.3
0
10
25
50
75
90
100

Z-Index

Token

Named stacking layers for predictable layering. Emitted as --mastors-z-{key}.

@use "@mastors/core/scss/tokens/z-index" as zi;

.dropdown { z-index: zi.z("dropdown"); } // 100
.modal    { z-index: zi.z("modal"); }    // 400
.toast    { z-index: zi.z("toast"); }    // 500
.tooltip  { z-index: zi.z("tooltip"); } // 600
KeyValueUse case
base0Default document flow
raised10Slightly elevated elements
dropdown100Dropdown menus
sticky200Sticky headers/sidebars
overlay300Overlay backdrops
modal400Modal dialogs
toast500Toast notifications
tooltip600Tooltips
max9999Escape hatch

Transitions

Token

Duration tokens (75ms–1000ms) and easing curves (linear, in, out, in-out, bounce). Emitted as --mastors-duration-{key} and --mastors-easing-{key}.

@use "@mastors/core/scss/tokens/transitions" as tr;

.btn {
  transition: background-color tr.duration("150") tr.easing("in-out");
}

// Values:
// tr.duration("75")   → 75ms
// tr.duration("300")  → 300ms
// tr.easing("out")    → cubic-bezier(0, 0, 0.2, 1)
// tr.easing("bounce") → cubic-bezier(0.34, 1.56, 0.64, 1)

Theming

Light & Dark Themes

Theme

Themes are toggled via .dark / [data-theme="dark"] on any ancestor element (strategy: class, default) or via prefers-color-scheme (strategy: media). Themes redefine semantic custom properties — no class changes needed on individual components.

<!-- Class strategy (default) -->
<html class="dark">
<!-- or -->
<html data-theme="dark">

<!-- Toggle with JS -->
<script>
  document.documentElement.classList.toggle('dark');
</script>
// Override dark strategy to media query:
// In your entry scss BEFORE @use "@mastors/core"
// (or via custom theme overrides)
$dark-mode-strategy: "media"; // default: "class"
@use "@mastors/core";

Light theme

--mastors-bg: #fff
--mastors-bg-subtle: #f9fafb
--mastors-text: #111827
--mastors-accent: #2563eb
--mastors-border: #e5e7eb

Dark theme

--mastors-bg: #030712
--mastors-bg-subtle: #111827
--mastors-text: #f9fafb
--mastors-accent: #60a5fa
--mastors-border: #374151

Semantic Layer

Theme

Role-based SCSS variables that map to CSS custom properties. Use these in your components instead of raw token references — they update automatically when the theme changes.

@use "@mastors/core/scss/semantic/colors"    as sc;
@use "@mastors/core/scss/semantic/spacing"   as ss;
@use "@mastors/core/scss/semantic/typography" as st;

.card {
  background: sc.$color-surface;
  color:       sc.$color-text;
  border:      1px solid sc.$color-border;
  padding:     ss.$space-component;
  font-family: st.$font-body;
}

// All $color-* variables resolve to var(--mastors-*) 
// so they inherit the active theme at runtime.
VariableCustom PropertyRole
$color-bg--mastors-bgPage background
$color-surface--mastors-surfaceCard / panel surface
$color-surface-raised--mastors-surface-raisedDropdowns, tooltips
$color-text--mastors-textPrimary text
$color-text-muted--mastors-text-mutedSecondary text
$color-text-subtle--mastors-text-subtlePlaceholder / tertiary
$color-border--mastors-borderDefault border
$color-accent--mastors-accentBrand / primary action
$color-accent-hover--mastors-accent-hoverAccent hover state
$space-inline0.25rem (spacing(1))Tight inline gap
$space-component1rem (spacing(4))Component padding
$space-section4rem (spacing(16))Between sections

Utilities

Spacing Utilities

Utility

Margin, padding, and gap utilities generated from spacing tokens. Supports all directional variants, logical properties, and auto for margins.

<!-- Margin -->
<div class="m-4">margin: 1rem</div>
<div class="mx-auto">margin-inline: auto</div>
<div class="my-8">margin-block: 2rem</div>
<div class="mt-2 mb-6">margin-top + margin-bottom</div>
<div class="ms-4 me-4">margin-inline-start/end (logical)</div>

<!-- Padding -->
<div class="p-6">padding: 1.5rem</div>
<div class="px-4 py-2">padding-x + padding-y</div>
<div class="ps-4 pe-4">padding-inline-start/end</div>

<!-- Gap -->
<div class="flex gap-4">gap: 1rem</div>
<div class="grid gap-x-6 gap-y-3">column + row gap</div>
p-4 (1rem)
py-2 px-6
gap-4 child
gap-4 child
gap-4 child
All spacing keys: 0, px, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64, 72, 80, 96
Plus auto for margin only.

Display

UtilityResponsive

Generates display classes including responsive variants (e.g. md:flex, lg:hidden).

<div class="block"></div>
<div class="inline-block"></div>
<div class="inline"></div>
<div class="flex"></div>
<div class="inline-flex"></div>
<div class="grid"></div>
<div class="inline-grid"></div>
<div class="table"></div>
<div class="contents"></div>
<div class="hidden"></div>         <!-- display: none -->

<!-- Responsive -->
<div class="hidden md:block">Shows from md up</div>
<div class="flex lg:hidden">Hidden from lg up</div>

Position

UtilityResponsive

Positioning classes + inset utilities for top/right/bottom/left values.

<div class="relative">
  <div class="absolute top-0 right-0">top-right corner</div>
  <div class="absolute inset-0">full overlay</div>
  <div class="absolute inset-x-0 bottom-0">bottom bar</div>
</div>

<div class="sticky top-0">Sticky header</div>
<div class="fixed bottom-0 right-0">Floating btn</div>

Inset keys: 0, auto, full (100%), 1/2 (50%)

Sizing

Utility

Width and height utilities generated from sizing tokens. Includes min-width, max-width, min-height, max-height shortcuts.

<div class="w-full h-screen">Full width, screen height</div>
<div class="w-1/2 h-32">50% width, 8rem height</div>
<div class="w-fit">Width: fit-content</div>

<!-- Min / Max -->
<div class="min-w-0 max-w-prose">Prose width (65ch)</div>
<div class="min-h-screen">Min 100vh height</div>
<div class="min-h-svh">Min 100svh (small viewport)</div>
<div class="min-h-dvh">Min 100dvh (dynamic viewport)</div>

Typography Utilities

UtilityResponsive

Text size, weight, family, alignment, leading, tracking, decoration, transform, whitespace, word-break, and more.

<!-- Size -->
<p class="text-xs"> <p class="text-sm"> <p class="text-base">
<p class="text-lg"> <p class="text-xl"> <p class="text-2xl">
<p class="text-3xl"> ... <p class="text-9xl">

<!-- Weight -->
<p class="font-thin"> <p class="font-light"> <p class="font-normal">
<p class="font-medium"> <p class="font-semibold"> <p class="font-bold">
<p class="font-extrabold"> <p class="font-black">

<!-- Family -->
<p class="font-sans"> <p class="font-serif"> <p class="font-mono">

<!-- Align (responsive) -->
<p class="text-left"> <p class="text-center"> <p class="text-right">
<p class="md:text-center">

<!-- Line height -->
<p class="leading-none"> <p class="leading-tight"> <p class="leading-normal">
<p class="leading-relaxed"> <p class="leading-loose">

<!-- Letter spacing -->
<p class="tracking-tight"> <p class="tracking-normal"> <p class="tracking-wide">
<p class="tracking-widest">

<!-- Decoration -->
<p class="underline"> <p class="line-through"> <p class="no-underline">
<p class="decoration-wavy decoration-2">

<!-- Transform -->
<p class="uppercase"> <p class="lowercase"> <p class="capitalize">

<!-- Style -->
<p class="italic"> <p class="not-italic">

<!-- Misc -->
<p class="antialiased"> <p class="text-ellipsis">
<p class="whitespace-nowrap"> <p class="break-words">

<!-- List -->
<ul class="list-disc list-inside"> <ol class="list-decimal">

Size scale →

text-xs — The quick brown fox

text-sm — The quick brown fox

text-base — The quick brown fox

text-xl font-semibold

text-4xl font-bold

decoration-wavy text-blue

TRACKING-WIDEST UPPERCASE

Color Utilities

Utility

Text color, background color, and border color classes for both semantic and primitive palettes.

<!-- Semantic text colors -->
<p class="text-default">Default text</p>
<p class="text-muted">Muted text</p>
<p class="text-subtle">Subtle text</p>
<p class="text-accent">Accent text</p>
<p class="text-inverse">Inverse text</p>

<!-- Primitive text colors -->
<p class="text-primary-600">Primary 600</p>
<p class="text-success-500">Success 500</p>
<p class="text-error-500">Error 500</p>
<p class="text-white"> <p class="text-black">
<p class="text-current"> <p class="text-transparent">

<!-- Semantic backgrounds -->
<div class="bg-default"> <div class="bg-subtle">
<div class="bg-surface"> <div class="bg-accent">

<!-- Primitive backgrounds -->
<div class="bg-primary-50"> <div class="bg-neutral-100">
<div class="bg-warning-200"> <div class="bg-white">
<div class="bg-transparent">
bg-primary-100 text-primary-700 bg-success-100 text-success-700 bg-warning-100 text-warning-700 bg-error-100 text-error-700 bg-info-100 text-info-700

Borders

Utility

Border width, style, color, and radius classes.

<!-- Border width -->
<div class="border">1px solid</div>
<div class="border-0">no border</div>
<div class="border-2">2px solid</div>
<div class="border-4">4px solid</div>
<div class="border-t">top only</div>
<div class="border-b">bottom only</div>

<!-- Border style -->
<div class="border border-dashed">dashed</div>
<div class="border border-dotted">dotted</div>

<!-- Border color -->
<div class="border border-default">semantic border</div>
<div class="border border-strong">strong border</div>
<div class="border border-transparent">transparent</div>

<!-- Border radius -->
<div class="rounded-none">   <div class="rounded-sm">
<div class="rounded">       <div class="rounded-md">
<div class="rounded-lg">    <div class="rounded-xl">
<div class="rounded-2xl">   <div class="rounded-3xl">
<div class="rounded-full">

<!-- Directional radius -->
<div class="rounded-t-lg">  <!-- top corners -->
<div class="rounded-b-xl">  <!-- bottom corners -->
<div class="rounded-l-full"> <!-- left corners -->
dashed
dotted

Shadow Utilities

Utility
<div class="shadow-xs">Extra small shadow</div>
<div class="shadow-sm">Small shadow</div>
<div class="shadow">Default (md) shadow</div>
<div class="shadow-md">Medium shadow</div>
<div class="shadow-lg">Large shadow</div>
<div class="shadow-xl">XL shadow</div>
<div class="shadow-2xl">2XL shadow</div>
<div class="shadow-inner">Inset shadow</div>
<div class="shadow-none">No shadow</div>

Opacity Utilities

Utility
<div class="opacity-0">   <!-- 0 -->
<div class="opacity-5">   <!-- 0.05 -->
<div class="opacity-10">  <!-- 0.1 -->
<div class="opacity-25">  <!-- 0.25 -->
<div class="opacity-50">  <!-- 0.5 -->
<div class="opacity-75">  <!-- 0.75 -->
<div class="opacity-90">  <!-- 0.9 -->
<div class="opacity-100"> <!-- 1 -->

Transform

Utility

Translate, rotate, scale, and transform-origin classes. Use .transform-gpu to promote to a composite layer.

<!-- Translate -->
<div class="translate-x-4">  <!-- translateX(1rem) -->
<div class="translate-y-2">  <!-- translateY(0.5rem) -->
<div class="-translate-y-1"> <!-- translateY(-0.25rem) -->
<div class="translate-x-full"> <!-- translateX(100%) -->

<!-- Rotate -->
<div class="rotate-45">   <!-- 45deg -->
<div class="rotate-90">   <!-- 90deg -->
<div class="rotate-180">  <!-- 180deg -->
<div class="-rotate-45">  <!-- -45deg -->

<!-- Scale -->
<div class="scale-0">    <!-- 0 -->
<div class="scale-50">   <!-- 0.5 -->
<div class="scale-100">  <!-- 1 (normal) -->
<div class="scale-105">  <!-- 1.05 -->
<div class="scale-110">  <!-- 1.1 -->
<div class="scale-150">  <!-- 1.5 -->
<div class="scale-x-75"> <!-- scaleX only -->

<!-- Origin -->
<div class="origin-center"> <div class="origin-top">
<div class="origin-bottom-right">

<!-- GPU acceleration -->
<div class="transform-gpu">  <!-- translateZ(0) -->
<div class="transform-none"> <!-- removes transform -->
45°
1.25
+1rem

Animation & Transitions

Utility

Built-in keyframe animations (spin, ping, pulse, bounce, fade-in, fade-out, slide-up, slide-down, scale-in) plus transition property, duration, easing, and delay utilities.

<!-- Animations -->
<div class="animate-spin">Spinner</div>
<div class="animate-ping">Ping dot</div>
<div class="animate-pulse">Pulsing skeleton</div>
<div class="animate-bounce">Bouncing indicator</div>
<div class="animate-fade-in">Fade in on mount</div>
<div class="animate-fade-out">Fade out</div>
<div class="animate-slide-up">Slide up</div>
<div class="animate-slide-down">Slide down</div>
<div class="animate-scale-in">Scale in</div>
<div class="animate-none">No animation</div>

<!-- Transitions -->
<div class="transition">All common properties</div>
<div class="transition-colors">Colors only</div>
<div class="transition-opacity">Opacity only</div>
<div class="transition-transform">Transform only</div>
<div class="transition-shadow">Shadow only</div>
<div class="transition-none">Disable</div>

<!-- Duration -->
<div class="duration-75">  75ms
<div class="duration-150"> 150ms
<div class="duration-300"> 300ms
<div class="duration-700"> 700ms
<div class="duration-1000"> 1s

<!-- Easing -->
<div class="ease-linear">  <div class="ease-in">
<div class="ease-out">     <div class="ease-in-out">
<div class="ease-bounce">

<!-- Delay -->
<div class="delay-150"> <div class="delay-300"> <div class="delay-700">

<!-- Fill mode / Play state -->
<div class="fill-forwards">  <div class="fill-both">
<div class="animation-paused"> <div class="animation-running">

<!-- Repeat -->
<div class="animate-repeat-infinite"> <div class="animate-repeat-1">

spin

pulse

bounce

fade-in

Overflow

Utility
<div class="overflow-auto">    <!-- scroll when needed -->
<div class="overflow-hidden">  <!-- clip content -->
<div class="overflow-scroll">  <!-- always show scrollbar -->
<div class="overflow-visible"> <!-- default -->
<div class="overflow-clip">    <!-- clip without scrollbar -->

<!-- Axis-specific -->
<div class="overflow-x-auto overflow-y-hidden">Horizontal scroll</div>

Cursor

Utility
<div class="cursor-auto">        auto
<div class="cursor-default">     default arrow
<div class="cursor-pointer">     hand pointer
<div class="cursor-wait">        wait spinner
<div class="cursor-text">        I-beam
<div class="cursor-move">        move
<div class="cursor-not-allowed"> blocked
<div class="cursor-grab">        grab hand
<div class="cursor-grabbing">    grabbing hand
<div class="cursor-zoom-in">     zoom in
<div class="cursor-crosshair">   crosshair
<div class="cursor-none">        hidden cursor
pointer not-allowed grab crosshair zoom-in

Interaction

Utility

User-select, resize, scroll behavior, scroll snap, touch action, and state-variant pseudo-class utilities (hover:, focus:, disabled:).

<!-- User select -->
<div class="select-none">Cannot select</div>
<div class="select-text">Can select text</div>
<div class="select-all">Select all on click</div>

<!-- Resize -->
<textarea class="resize-none">No resize</textarea>
<textarea class="resize-y">Vertical resize</textarea>
<textarea class="resize">Both directions</textarea>

<!-- Scroll -->
<div class="scroll-smooth">Smooth scrolling</div>

<!-- Scroll snap -->
<div class="snap-x snap-mandatory overflow-x-auto">
  <div class="snap-start">Snap item 1</div>
  <div class="snap-center">Snap item 2</div>
</div>

<!-- Touch -->
<div class="touch-pan-x">Horizontal pan only</div>
<div class="touch-manipulation">Fast tap, no zoom</div>
<div class="touch-none">Disable touch</div>

<!-- Pointer events -->
<div class="pointer-events-none">Click-through</div>
<div class="pointer-events-auto">Default</div>

<!-- State variants -->
<button class="hover:bg-accent hover:scale-105">Hover effects</button>
<button class="focus:ring focus:ring-2">Focus ring</button>
<button class="disabled:opacity-50 disabled:cursor-not-allowed">Disabled</button>
<a class="hover:underline hover:text-accent">Hover link</a>

Layout

UtilityResponsive

Aspect ratio, object-fit, object-position, float, clear, isolation, mix-blend-mode, background blend, appearance, and will-change.

<!-- Aspect ratio -->
<div class="aspect-auto">   <div class="aspect-square">
<div class="aspect-video">  <!-- 16/9 -->
<div class="aspect-4-3">    <div class="aspect-3-2">
<div class="aspect-21-9">   <div class="aspect-9-16">
<div class="aspect-golden"> <!-- 1.618 -->

<!-- Object fit -->
<img class="object-cover">    <img class="object-contain">
<img class="object-fill">     <img class="object-scale-down">

<!-- Object position -->
<img class="object-center">   <img class="object-top">
<img class="object-bottom">   <img class="object-left">

<!-- Float (responsive) -->
<div class="float-left"> <div class="float-right"> <div class="float-none">
<div class="lg:float-right">

<!-- Isolation -->
<div class="isolate">New stacking context</div>

<!-- Mix blend mode -->
<div class="mix-blend-multiply">
<div class="mix-blend-screen">
<div class="mix-blend-overlay">

<!-- Background blend -->
<div class="bg-blend-multiply">

<!-- Appearance -->
<select class="appearance-none">Custom styled select</select>

<!-- Will change -->
<div class="will-change-transform"> <div class="will-change-scroll">

square

16/9

4/3

Z-Index Utilities

Utility
<div class="z-base">     z-index: 0</div>
<div class="z-raised">   z-index: 10</div>
<div class="z-dropdown"> z-index: 100</div>
<div class="z-sticky">   z-index: 200</div>
<div class="z-overlay">  z-index: 300</div>
<div class="z-modal">    z-index: 400</div>
<div class="z-toast">    z-index: 500</div>
<div class="z-tooltip">  z-index: 600</div>
<div class="z-max">      z-index: 9999</div>

Helpers

Pre-built helper classes for common patterns: text truncation, line clamping, aspect ratios, clearfix, and visually-hidden content.

Truncate & Line Clamp

<p class="truncate">Single line truncation with ellipsis...</p>

<p class="line-clamp-1">Clamp to 1 line</p>
<p class="line-clamp-2">Clamp to 2 lines</p>
<p class="line-clamp-3">Clamp to 3 lines — max 3 visible</p>
<p class="line-clamp-6">Clamp to 6 lines</p>

<p class="break-words">Break long overflow-wrap words</p>
<p class="break-all">Break at any character</p>
<p class="break-keep">Keep words together (CJK)</p>

This is a very long sentence that should be truncated with an ellipsis at the end when it overflows.

This paragraph is clamped to two lines using the line-clamp-2 class. It will be hidden after the second visible line no matter how much content there is below this point.

Ratio Helpers

<div class="ratio-square">1:1 ratio</div>
<div class="ratio-video">16:9 ratio</div>
<div class="ratio-portrait">3:4 ratio</div>
<div class="ratio-wide">21:9 ultra-wide</div>
<div class="ratio-golden">Golden ratio (1.618)</div>

Clearfix

<!-- Clears floated children with ::after -->
<div class="clearfix">
  <img class="float-left" src="..." />
  <p>Text alongside float</p>
</div>

Sass API — Functions

Pure Sass functions — zero CSS output when imported alone. Use via @use "@mastors/core/scss/functions/...".

rem() & em() Unit conversion

@use "@mastors/core/scss/functions/rem" as *;
@use "@mastors/core/scss/functions/em"  as *;

.heading { font-size: rem(32px); }       // → 2rem
.media   { max-width: em(768px, 16px); } // → 48em

Color Functions

@use "@mastors/core/scss/functions/color" as *;

// tint($color, $pct) — mix with white
$light-blue: tint(#3b82f6, 40%);

// shade($color, $pct) — mix with black
$dark-blue:  shade(#3b82f6, 30%);

// alpha($color, $alpha) — set alpha
$semi:       alpha(#3b82f6, 0.5);

// contrast($bg) — returns black or white for best contrast
$text-color: contrast(#3b82f6);  // → white

// palette($name, $shade) — shorthand accessor
$c: palette("primary", 500);

// rgb-color($name, $shade, $opacity) — with optional alpha
$c: rgb-color("primary", 500, 0.6);

// color-ramp($base, $steps, $dir) — tint/shade ramp
$ramp: color-ramp(#3b82f6, 5, "tint");

Math Functions

@use "@mastors/core/scss/functions/math" as *;

// fluid($min, $max, $min-vw, $max-vw) — clamp() expression
font-size: fluid(1rem, 2rem);
// → clamp(1rem, …vw + …, 2rem)

// clamp-value($min, $val, $max)
font-size: clamp-value(0.875rem, 4vw, 2rem);

// strip-unit(16px) → 16
$n: strip-unit(16px);

// round-to(3.14159, 2) → 3.14
$r: round-to(3.14159);

// lerp($a, $b, $t) — linear interpolation
$v: lerp(0, 100px, 0.5); // → 50px

vars() — Token Reference Function

@use "@mastors/core/scss/functions/vars" as *;

// Simple token reference (no fallback)
.card {
  background: vars(surface);            // var(--mastors-surface)
  color:       vars(text);              // var(--mastors-text)
  border:      1px solid vars(border);  // var(--mastors-border)
}

// With CSS fallback
.badge {
  background: vars(accent-subtle, #eff6ff); // var(--mastors-accent-subtle, #eff6ff)
}

// Path-based accessor (functions/_string.scss)
// vars($category, $keys...)
@use "@mastors/core/scss/functions/string" as sf;

color: sf.vars(color, primary, 500); // var(--mastors-color-primary-500)
gap:   sf.vars(spacing, 4);           // var(--mastors-spacing-4)

Map Helpers

@use "@mastors/core/scss/functions/map-helpers" as *;

$nested: ("colors": ("blue": #3b82f6));
$blue: map-deep-get($nested, "colors", "blue"); // → #3b82f6

$merged: map-collect($map-a, $map-b, $map-c); // shallow merge

Sass API — Mixins

Breakpoint Mixin Responsive

@use "@mastors/core/scss/mixins/breakpoint" as *;

.sidebar {
  display: none;

  // Mobile-first: apply at sm and above (min-width: 640px)
  @include bp(sm)  { display: block; }
  @include bp(md)  { width: 240px; }
  @include bp(lg)  { width: 300px; }
  @include bp(2xl) { width: 360px; }
}

// Aliases — all three are equivalent
@include respond-to(md) { ... }
@include breakpoint-up(md) { ... }

// Below a breakpoint (max-width)
@include breakpoint-down(lg) { ... }

// Available keys: xs(0) sm(640px) md(768px) lg(1024px) xl(1280px) 2xl(1536px)

Container Mixin

@use "@mastors/core/scss/mixins/container" as *;

.page-wrapper {
  @include container;
  // → width: 100%; margin-inline: auto; padding-inline: 1rem;
  //   max-width: 640px @sm, 768px @md, 1024px @lg,
  //              1280px @xl, 1400px @2xl
}

Elevation Mixin

@use "@mastors/core/scss/mixins/elevation" as *;

.card { @include elevation("md"); }   // box-shadow: md token
.nav  { @include elevation("lg"); }   // box-shadow: lg token
// Keys: xs sm md lg xl 2xl inner none

Transition Mixin

@use "@mastors/core/scss/mixins/transition" as *;

.btn {
  // transition($props, $duration, $easing)
  @include transition((background-color, color), "150", "in-out");
  // → transition: background-color 150ms cubic-bezier(0.4,0,0.2,1),
  //               color 150ms cubic-bezier(0.4,0,0.2,1);
}

.modal { @include transition((transform, opacity), "300", "out"); }

Pseudo Mixin

@use "@mastors/core/scss/mixins/pseudo" as *;

.badge::before {
  @include pseudo($display: inline-block, $pos: relative, $content: "");
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: currentColor;
}

Theme Mixin

@use "@mastors/core/scss/mixins/theme" as *;

.card {
  background: #fff;

  @include dark-mode {
    background: #1f2937;
    color: #f9fafb;
  }

  @include light-mode {
    box-shadow: 0 1px 3px rgb(0 0 0 / 10%);
  }

  // Named theme (data-theme="ocean")
  @include theme("ocean") {
    background: #083344;
    color: #ecfeff;
  }
}

Responsive

Breakpoints

Engine

Mobile-first breakpoints used by the responsive engine to generate prefixed utility variants. xs is the base (no prefix).

<!-- Pattern: {bp}:{utility} -->
<div class="hidden sm:block">      Shown sm+</div>
<div class="block md:hidden">      Hidden md+</div>
<div class="flex-col lg:flex-row"> Row from lg</div>
<div class="text-sm xl:text-base"> Bigger on xl</div>
Keymin-widthBreakpoint
xs0pxAll screens (no prefix)
sm640pxLarge phones +
md768pxTablets +
lg1024pxLaptops +
xl1280pxDesktops +
2xl1536pxWide screens +
Only utilities with responsive: true in their config generate breakpoint variants. Currently enabled: display, position, text-align, float, clear.

Fluid Typography

Responsive

Uses clamp() to scale font sizes smoothly between two viewport widths. No media queries needed.

@use "@mastors/core/scss/responsive/fluid-type" as ft;

// Mixin — apply fluid font-size to the element
.hero-title {
  @include ft.apply-fluid-type(2rem, 4rem);
  // → font-size: clamp(2rem, …vw + …, 4rem);
}

// Custom viewport range
.headline {
  @include ft.apply-fluid-type(1.5rem, 3rem, 480px, 1400px);
}

// Function — use inside any property value
.lead {
  font-size: ft.fluid-type(1rem, 1.5rem);
}

// Pre-built fluid heading scale (opt-in)
// Scales h1–h6 + p fluidly across 320px–1280px
@include ft.fluid-scale();
// h1: clamp(2rem, …, 3.75rem)
// h2: clamp(1.5rem, …, 3rem)
// h3: clamp(1.25rem, …, 2.25rem)
// h4: clamp(1.125rem, …, 1.875rem)
// h5: clamp(1rem, …, 1.5rem)
// h6: clamp(0.875rem, …, 1.25rem)
// p:  clamp(0.875rem, …, 1.125rem)

Container Queries

Responsive

CSS container query helpers. Supports inline-size and size containment types.

<!-- Step 1: Create containment context -->
<div class="cq-inline">  <!-- container-type: inline-size -->
  <div class="cq-size">  <!-- container-type: size -->

<!-- data attribute shorthand -->
<div data-container>     <!-- container-type: inline-size -->
@use "@mastors/core/scss/responsive/container-queries" as cq;

// Inside any component SCSS file:
.card {
  // When the container is at least 40rem wide
  @include cq.cq(40rem) {
    display: grid;
    grid-template-columns: 1fr 2fr;
  }

  // Named container query
  @include cq.cq(30rem, "sidebar") {
    font-size: 0.875rem;
  }
}

Accessibility

Built-in accessibility features: focus rings, reduced motion, screen-reader utilities, and print helpers.

Screen Reader Utilities

<!-- Visually hidden but accessible to screen readers -->
<span class="sr-only">Menu (screen reader label)</span>

<!-- Undo sr-only — make visible again -->
<span class="not-sr-only">Now visible</span>

<!-- Legacy aliases (all equivalent to sr-only) -->
<span class="visually-hidden">Hidden visually</span>
<span class="vh">Shorthand alias</span>

<!-- Shown when focused (skip links pattern) -->
<a class="visually-hidden-focusable" href="#main">
  Skip to main content
</a>

Focus Ring

Automatically applied to :focus-visible. Mouse users do not see the ring (:focus:not(:focus-visible) { outline: none }).

/* Auto-applied by accessibility/_focus.scss */
:focus-visible {
  outline: 2px solid var(--mastors-color-primary-500, #3b82f6);
  outline-offset: 2px;
  border-radius: 2px;
}

Reduced Motion

Respects the OS-level "reduce motion" preference. All animations and transitions are disabled to near-zero duration automatically.

/* Auto-applied — no class needed */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration:        0.01ms !important;
    animation-iteration-count: 1      !important;
    transition-duration:       0.01ms !important;
    scroll-behavior:           auto   !important;
  }
}

Print Utilities

<!-- Hide in print, show on screen -->
<nav class="print:hidden">Navigation</nav>

<!-- Show only in print -->
<div class="screen:hidden">Print-only watermark</div>

<!-- Page break control -->
<section class="print:break-inside-avoid">...</section>
<div class="print:break-before">New page before this</div>
<div class="print:break-after">New page after this</div>

<!-- Print-safe colors -->
<p class="print:text-black print:bg-white">Print-safe</p>
<div class="print:shadow-none print:border-none">Clean print</div>

Base

The base layer applies an opinionated modern CSS reset and emits all token-based CSS custom properties on :root.

Reset Highlights

/* box-sizing: border-box on everything */
*, *::before, *::after { box-sizing: border-box; }

/* Zero margin/padding everywhere */
* { margin: 0; padding: 0; }

/* Smooth scroll + tab-size */
html { text-size-adjust: 100%; tab-size: 4; scroll-behavior: smooth; }

/* Font smoothing */
body { -webkit-font-smoothing: antialiased; }

/* Block images, max 100% */
img, picture, video, canvas, svg { display: block; max-width: 100%; }

/* Form elements inherit font */
input, button, textarea, select { font: inherit; }

/* Break long words in headings/paragraphs */
p, h1, h2, h3, h4, h5, h6 { overflow-wrap: break-word; }

/* Removed list styles */
ol, ul { list-style: none; }

/* Links inherit color and text-decoration */
a { color: inherit; text-decoration: inherit; }

/* Collapsed table borders */
table { border-collapse: collapse; border-spacing: 0; }

/* Cursor on interactive elements */
button, [role="button"] { cursor: pointer; }

:root Custom Properties

Every token map is emitted as CSS custom properties on :root via the generator.

:root {
  /* Colors — nested: --mastors-color-primary-50 … -950 */
  --mastors-color-primary-500: #3b82f6;
  --mastors-color-success-500: #22c55e;
  /* … (6 palettes × 11 shades + white + black) … */

  /* Spacing */
  --mastors-spacing-4: 1rem;

  /* Typography */
  --mastors-font-size-xl: 1.25rem;
  --mastors-font-weight-bold: 700;

  /* Radii */
  --mastors-radius-md: 0.375rem;

  /* Shadows */
  --mastors-shadow-md: 0 4px 6px -1px rgb(0 0 0/10%),...;

  /* Transitions */
  --mastors-duration-300: 300ms;
  --mastors-easing-in-out: cubic-bezier(0.4, 0, 0.2, 1);

  /* Z-index */
  --mastors-z-modal: 400;

  /* Opacity */
  --mastors-opacity-50: 0.5;
}

@mastors/core Documentation — Generated from source SCSS

Packages path: packages/core/scss