@use "sass:list"; .font-thin { font-weight: 100; } .font-extralight { font-weight: 200; } .font-light { font-weight: 300; } .font-normal { font-weight: 400; } .font-medium { font-weight: 500; } .font-semibold { font-weight: 600; } .font-bold { font-weight: 700; } .font-extrabold { font-weight: 800; } .font-black { font-weight: 900; } .rounded-xs { border-radius: 0.125rem; } .rounded-sm { border-radius: 0.25rem; } .rounded-md { border-radius: 0.375rem; } .rounded-lg { border-radius: 0.5rem; } .rounded-xl { border-radius: 0.75rem; } .rounded-2xl { border-radius: 1rem; } .rounded-3xl { border-radius: 1.5rem; } .rounded-4xl { border-radius: 2rem; } .rounded-none { border-radius: 0; } .rounded-full { border-radius: calc(infinity * 1px); } $base: 0.25rem; @function spacing($step) { @return $step * $base; } $spacing-types: ( "p": "padding", "m": "margin", ); $spacing-variants: ( "": (""), "x": ("-left", "-right"), "y": ("-top", "-bottom"), "t": ("-top"), "b": ("-bottom"), "l": ("-left"), "r": ("-right"), ); @each $type-prefix, $type in $spacing-types { @each $dir-suffix, $sides in $spacing-variants { @for $i from 0 through 48 { // Whole step: p-0, p-1, p-2 ... .#{$type-prefix}#{$dir-suffix}-#{$i} { @each $side in $sides { #{$type}#{$side}: spacing($i); } } // Half step: p-0\.5, p-1\.5, p-2\.5 ... // Stop at 47.5 — 48.5 would exceed the scale @if $i < 48 { .#{$type-prefix}#{$dir-suffix}-#{$i}\.5 { @each $side in $sides { #{$type}#{$side}: spacing($i + 0.5); } } } } } } // ─── CSS custom properties ───────────────────────────────────────────────── :root { --spacing: 0.25rem; --container-3xs: 16rem; --container-2xs: 18rem; --container-xs: 20rem; --container-sm: 24rem; --container-md: 28rem; --container-lg: 32rem; --container-xl: 36rem; --container-2xl: 42rem; --container-3xl: 48rem; --container-4xl: 56rem; --container-5xl: 64rem; --container-6xl: 72rem; --container-7xl: 80rem; } // ─── Shared mixin ────────────────────────────────────────────────────────── @mixin set-props($props, $value) { @each $prop in $props { #{$prop}: $value; } } // ─── Class types ─────────────────────────────────────────────────────────── $class-types: ( "w": (width), "h": (height), "size": (width, height), ); // ─── Numeric: w-0 → w-48, h-0 → h-48, size-0 → size-48 ─────────────────── @each $prefix, $props in $class-types { @for $i from 0 through 48 { .#{$prefix}-#{$i} { @include set-props($props, calc(var(--spacing) * #{$i})); } } } // ─── Fractions ───────────────────────────────────────────────────────────── $fractions: ( "1\\/2": (1, 2), "1\\/3": (1, 3), "2\\/3": (2, 3), "1\\/4": (1, 4), "2\\/4": (2, 4), "3\\/4": (3, 4), "1\\/5": (1, 5), "2\\/5": (2, 5), "3\\/5": (3, 5), "4\\/5": (4, 5), "1\\/6": (1, 6), "2\\/6": (2, 6), "3\\/6": (3, 6), "4\\/6": (4, 6), "5\\/6": (5, 6), "1\\/12": (1, 12), "2\\/12": (2, 12), "3\\/12": (3, 12), "4\\/12": (4, 12), "5\\/12": (5, 12), "6\\/12": (6, 12), "7\\/12": (7, 12), "8\\/12": (8, 12), "9\\/12": (9, 12), "10\\/12": (10, 12), "11\\/12": (11, 12), ); @each $prefix, $props in $class-types { @each $name, $pair in $fractions { $num: list.nth($pair, 1); $den: list.nth($pair, 2); .#{$prefix}-#{$name} { @include set-props($props, calc(#{$num} / #{$den} * 100%)); } } } // ─── Container sizes (w- only) ───────────────────────────────────────────── $containers: ( "3xs", "2xs", "xs", "sm", "md", "lg", "xl", "2xl", "3xl", "4xl", "5xl", "6xl", "7xl" ); @each $name in $containers { .w-#{$name} { width: var(--container-#{$name}); } } // ─── Shared keywords (auto, px, full, min, max, fit) ─────────────────────── // These are identical in value across w-, h-, and size- $shared-keywords: ( "auto": auto, "px": 1px, "full": 100%, "min": min-content, "max": max-content, "fit": fit-content, ); @each $prefix, $props in $class-types { @each $name, $value in $shared-keywords { .#{$prefix}-#{$name} { @include set-props($props, $value); } } } // ─── Viewport keywords ───────────────────────────────────────────────────── // dvw/dvh/lvw/lvh/svw/svh apply equally to w-, h-, and size- $viewport-keywords: ( "dvw": 100dvw, "dvh": 100dvh, "lvw": 100lvw, "lvh": 100lvh, "svw": 100svw, "svh": 100svh, ); @each $prefix, $props in $class-types { @each $name, $value in $viewport-keywords { .#{$prefix}-#{$name} { @include set-props($props, $value); } } } .w-screen { width: 100vw; } .h-screen { height: 100vh; }