🍅 Tomato CSS

The human-friendly CSS preprocessor. Write styles like you think.

Installation

Global Install (Recommended)

$ npm install -g @srivtx/tomato-css
$ tomato app.tom -o styles.css

Project Install

$ npm install @srivtx/tomato-css
$ npx tomato app.tom

Or add to package.json:

{
  "scripts": {
    "build": "tomato src/app.tom -o dist/styles.css",
    "watch": "tomato --watch src/app.tom -o dist/styles.css"
  }
}

No Install (npx)

$ npx @srivtx/tomato-css app.tom

Your First .tom File

Create a file called styles.tom:

button:
  bg blue-500
  color white
  pad 2 4
  round lg
  pointer
  smooth

Compile it:

$ tomato styles.tom -o styles.css

CLI Usage

$ tomato <input.tom> [-o output.css]
$ tomato --watch <input.tom> [-o output.css]
tomato app.tom Compile to app.css
tomato app.tom -o styles.css Custom output file
tomato --watch app.tom Watch mode

Selectors

HTML Elements

button:
  bg blue-500

nav:
  row spread

input:
  pad 2 4

Classes

.btn-primary:
  bg blue-500
  color white

.card:
  bg white
  round xl
  shadow lg

.hero-title:
  size 4xl
  bold

IDs

#header:
  bg slate-900
  pad 4 6

#main-content:
  pad 8

Auto-Class Conversion

Names that aren't HTML elements become classes automatically:

// These are equivalent:
card:           // → .card { }
.card:          // → .card { }

// But these stay as elements:
button:         // → button { }
nav:            // → nav { }
HTML elements like button, nav, div, header, footer, etc. stay as element selectors. Everything else becomes a class.

Components

Define reusable style groups with component name: and use them with use name.

Basic Components

component btn:
  pad 2 4
  round lg
  bold
  pointer
  smooth
  no border

button:
  use btn
  bg blue-500
  color white

.btn-secondary:
  use btn
  bg violet-500
  color white

.btn-outline:
  use btn
  bg transparent
  color blue-500
  border 2px solid blue-500

Nested Components

component base-input:
  pad 3 4
  round md
  border 1px solid slate-300
  smooth

component focus-ring:
  use base-input
  
  focus:
    ring 2px solid blue-400
    border-color blue-500

input:
  use focus-ring
  w-full
When you use a component, all its properties are expanded inline. This means you can override them by adding your own after!

Card Components

component card:
  bg white
  round xl
  shadow md
  pad 6
  smooth
  
  hover:
    shadow lg
    transform translateY(-2px)

.product-card:
  use card
  column
  gap 4

.profile-card:
  use card
  center all
  pad 8

Form Input Components

component input-base:
  w-full
  pad 3 4
  round lg
  border 1px solid slate-200
  bg white
  smooth
  
  focus:
    border-color blue-500
    ring 2px solid blue-100
    no outline

input:
  use input-base

textarea:
  use input-base
  min-height 120px
  resize vertical

select:
  use input-base
  pointer

Layout Components

component container:
  max-width 1200px
  margin 0 auto
  pad 4 6

component stack:
  column
  gap 4

component row-layout:
  row
  gap 4
  align-items center

.page:
  use container
  use stack
  gap 8

.toolbar:
  use row-layout
  row spread
  pad 4
  bg slate-50
You can use multiple components with multiple use statements! Properties are applied in order, so later ones override earlier ones.

Pseudo States

button:
  bg blue-500
  color white
  smooth
  
  hover:
    bg blue-600
    shadow lg
  
  focus:
    ring 2px solid blue-400
    no outline
  
  active:
    bg blue-700
  
  disabled:
    opacity 0.5
    cursor not-allowed

Responsive Design

hero:
  pad 16
  grid 3
  gap 6
  
  @mobile:
    pad 4
    grid 1
  
  @tablet:
    grid 2
Query Breakpoint
@mobile: max-width: 640px
@tablet: max-width: 768px
@laptop: max-width: 1024px
@desktop: max-width: 1280px

Custom Tokens

colors:
  primary blue-500
  secondary violet-500
  dark slate-900
  light slate-50
  muted slate-400
  danger red-500
  success green-500

button:
  bg primary
  color light

.alert-danger:
  bg danger
  color white

Color Reference

// 22 color scales built-in (Tailwind):
slate, gray, zinc, neutral, stone
red, orange, amber, yellow, lime
green, emerald, teal, cyan, sky
blue, indigo, violet, purple
fuchsia, pink, rose

// Usage:
bg rose-500
color slate-900
border 1px solid blue-300

All Properties

Tomato CSS Output
bg blue-500 background: #3b82f6
color white color: #ffffff
pad 2 4 padding: 0.5rem 1rem
margin 4 margin: 1rem
round lg border-radius: 0.5rem
round full border-radius: 9999px
shadow md box-shadow: ...
bold font-weight: bold
semibold font-weight: 600
italic font-style: italic
uppercase text-transform: uppercase
underline text-decoration: underline
pointer cursor: pointer
smooth transition: all 0.2s ease
no border border: none
no outline outline: none
row display: flex; flex-direction: row
row spread ...justify-content: space-between
row center ...justify-content: center
column display: flex; flex-direction: column
center all ...justify-content: center; align-items: center
grid 3 display: grid; grid-template-columns: repeat(3, 1fr)
gap 4 gap: 1rem
w-full width: 100%
h-screen height: 100vh
relative position: relative
absolute position: absolute
fixed position: fixed
hidden display: none
overflow hidden overflow: hidden