Stylus

CSS architecture guide — breakpoints, variables, fonts, base styles, and file structure.

Breakpoints

Defined in src/css/core/breakpoints.styl. Eight viewport ranges from xsmall (0–359px) to xxxlarge (1820px+). Each generates three media query variables: $name-up, $name-only, and $name-max.

Viewport ranges

xsmall     0 – 359px
small      360 – 539px
smallWide  540 – 767px
medium     768 – 1023px
large      1024 – 1199px
xlarge     1200 – 1499px
xxlarge    1500 – 1819px
xxxlarge   1820px+

Usage in Stylus

.MyComponent
  padding 16px

  @media $medium-up
    padding 24px

  @media $large-up
    padding 32px

  @media $xlarge-max
    font-size 1.4rem

Special queries

$retina      // (min-resolution: 1.3dppx)
$landscape   // screen and (orientation: landscape)
$portrait    // screen and (orientation: portrait)
$short-up    // screen and (min-height: 48em)  — 768px
$high-up     // screen and (min-height: 67.5em) — 1080px

Container widths

$container-width-slim     750px
$container-width-medium  1080px
$container-width         1530px
$container-width-wide    1760px
$container-width-full    1820px

Variables

CSS custom properties defined in src/css/core/variables.styl on the :root selector. Available globally in all stylesheets.

Typography

--font-size           1.6rem
--font-geist          Geist, sans-serif
--font-family-code    monaco, 'Consolas', 'Lucida Console', monospace

Colors

--bg-color        wheat
--color-border    #eaecf0
--color-white     white
--color-black     #101828
--color-text      #344054
--color-grey      #667085

Layout & decoration

--container-width   1216px
--radius-sm         4px
--radius-base       8px
--radius-lg         12px
--radius-xl         16px
--layer-modal       100

Usage

.Card
  background var(--color-white)
  border-radius var(--radius-lg)
  color var(--color-text)
  font-family var(--font-geist)

Fonts

Font faces declared in src/css/core/fonts.styl. Font files live in src/fonts/. Currently using Geist in three weights.

Available weights

Geist Light     font-weight 300
Geist Regular   font-weight 400
Geist Medium    font-weight 500

Adding a new font

  1. Place .woff2 and .woff files in src/fonts/
  2. Add a @font-face block in fonts.styl with font-display: swap
  3. Create a CSS variable in variables.styl for the font family
@font-face {
  font-family: MyFont;
  src:
    url('/fonts/MyFont-Regular.woff2') format('woff2'),
    url('/fonts/MyFont-Regular.woff') format('woff');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

Base styles

Global resets and defaults in src/css/core/base.styl. Sets up box-sizing, typography, scrollbar hiding, and Swup/Lenis integration.

Key defaults

html
  box-sizing border-box
  font-size 62.5%          // 1rem = 10px

body
  font-size var(--font-size) // 1.6rem = 16px
  font-family var(--font-geist)
  line-height calc(24 / 16)
  background-color var(--bg-color)

Heading scale

h1   4rem      (40px)
h2   3.5rem    (35px)
h3   3rem      (30px)
h4   2.5rem    (25px)
h5   2rem      (20px)
h6   1.7rem    (17px)

Stylus syntax conventions

  1. No colons, no semicolons — pythonic syntax
  2. Indentation-based nesting (tabs, not spaces)
  3. Use & for parent selectors
  4. @font-face blocks use standard CSS braces
.Button
  display inline-flex
  padding 8px 16px
  border-radius var(--radius-base)

  &:hover
    opacity 0.8

  @media $medium-up
    padding 12px 24px

File structure

Stylus entry point is src/css/main.styl which uses glob imports to pull in everything automatically.

src/css/
  main.styl              // Entry — glob imports below
  core/
    breakpoints.styl     // Viewport variables & media queries
    variables.styl       // CSS custom properties
    fonts.styl           // @font-face declarations
    base.styl            // Global resets & defaults
  components/
    Container.styl       // Layout container
    Section.styl         // Page sections
    Title.styl           // Heading styles
    Button.styl          // Button styles
    ...
  utils/                 // Helper classes
  plugins/               // Third-party overrides

main.styl

@import 'core/**'
@import 'utils/**/*'
@import 'components/**'
@import 'plugins/**'

New .styl files in these folders are picked up automatically — no manual import needed.