FIKO kitchen

Tokens

omg/1vars.css

color tokens

--brand
--brand_lighter
--brand_darker
--brandT25
--brandT50
--surface
--text
--border_color
--cta
--dark
--darkT25
--light
--lightT25

spacing tokens

--spaceV
--spaceH
--space
--breath
--tap_size

--spaceH · --spaceV — axis-aware spacing

Each token tracks its own axis. Override one — only that axis changes. The tinted area is the padding; the white box is content.

--spaceH varies  ·  --spaceV fixed
content
--spaceH: 0.25svw
content
--spaceH: 1.75svw ← default
content
--spaceH: 5svw
--spaceV varies  ·  --spaceH fixed
content
--spaceV: 0.25svh
content
--spaceV: 1.5svh ← default
content
--spaceV: 5svh
padding: var(--spaceV) var(--spaceH) gap: var(--spaceH) margin-block: calc(var(--spaceV) * 2) padding-inline: calc(var(--spaceH) * 0.5)
source
--spaceH: 1.75svw;   /* scales with viewport width  */
--spaceV: 1.5svh;    /* scales with viewport height */

/* axis-aligned usage */
padding-inline: var(--spaceH);
padding-block:  var(--spaceV);
gap:            var(--spaceH);

/* multiples for rhythm */
margin-block: calc(var(--spaceV) * 2);
padding:      calc(var(--spaceV) * 0.5) calc(var(--spaceH) * 0.5);

typography tokens

--font_size · The quick brown fox

--font_serif · The quick brown fox

100 200 300 400 / thin* 500 / light* 600 / regular* 700 / medium* 800 / bold*

* semantic alias — use framework .weight_* classes in production

Base

omg/3base.css

h1 – h6 element defaults

h1 — The quick brown fox

h2 — The quick brown fox

h3 — The quick brown fox

h4 — The quick brown fox

h5 — The quick brown fox
h6 — The quick brown fox
source
<h1>Heading one</h1>
<h2>Heading two</h2>
<h3>Heading three</h3>

.h1.h6 heading classes (decoupled from element) omg/utils/text.css

h1 class on a p

h2 class on a p

h3 class on a p

h4 class on a p

h5 class on a p

h6 class on a p

source
<p class="h1">Display heading</p>
<p class="h2">Section heading</p>
<span class="h3">Any element</span>

p · strong

A paragraph with strong text inside. Line height is set by --line_height. Padding-block comes from --spaceV.

Second paragraph. The base layer resets lists and sets body font from --font_family.

source
<p>A paragraph with <strong>strong text</strong> inside.</p>

blockquote · cite

Design is not just what it looks like and feels like. Design is how it works. — Steve Jobs
source
<blockquote>
    Quote text here.
    <cite>— Author Name</cite>
</blockquote>

hr

Above the rule


Below the rule

source
<hr />

button naked element

source
<button>Default button</button>

:focus-visible

Tab to the button below to see focus ring (2px solid --focus_color, offset 2px)

Layout

omg/4layout.css — nav element rules  ·  omg/utils/layout.css — class-based layout (.container, .grid, .bento)

.container omg/utils/layout.css

full width
.container — centered, max var(--container_xl)
source
<div class="container">…</div>

.grid — responsive 1 → 4 cols via container query omg/utils/layout.css

1
2
3
4
5
6
source
<div class="grid">
    <div>…</div>
    <div>…</div>
    <div>…</div>
</div>

.bento — default 3×3, first child 2×2 omg/utils/layout.css

1 (2×2)
2
3
4
5
6
7
source
<div class="bento">
    <div>featured (auto 2×2)</div>
    <div>…</div>
</div>

.bento_col_2 .bento_col_3 .bento_full .bento_row_2 .bento_row_3 omg/utils/layout.css

1 (2×2)
.bento_col_2
.bento_row_2
4
5
.bento_full
source
<div class="bento" style="--bento_cols: 4; --bento_rows: 3;">
    <div class="bento_col_2">…</div>
    <div class="bento_row_2">…</div>
    <div class="bento_full">…</div>
</div>

nav element default

source
<nav>
    <a href="#">Logo</a>
    <ul>
        <li><a href="#">Link</a></li>
    </ul>
</nav>

Components

omg/5components.css

.button · .button_cta

source
<a class="button" href="#">
    <button>Default</button>
</a>

<a class="button button_cta" href="#">
    <button>CTA button</button>
</a>

.controls · .controls.sticky

.controls — height: var(--sticky_header_height) = 88px
source
<header class="controls sticky">
    <div class="container">…</div>
</header>

details.accordion

First item
Content inside. Padding comes from --spaceV and --spaceH.
Second item
Each item is independent — open/close state is not shared.
Third item — starts open
The chevron rotates 180° when open. No JS required.
source
<details class="accordion" open>
    <summary>Title</summary>
    <div>Content</div>
</details>

details.accordion.dotted

First dotted item
Dot leader fills the gap between label and chevron.
Second dotted item
Works with any summary text length — the leader stretches automatically.
Third dotted item — starts open
No bottom border on summary — the dot leader is the separator.
source
<details class="accordion dotted">
    <summary>Title</summary>
    <div>Content</div>
</details>

details.accordion.accordion_pm

First item
Plus/minus toggle — no rotation, clean symbol swap.
Second item
Composable — stack with .dotted for dot-leader + plus/minus.
Third item — starts open
Uses CSS content swap: "+" closed, "−" open. No SVG, no JS.
source
<details class="accordion accordion_pm">
    <summary>Title</summary>
    <div>Content</div>
</details>

States

omg/6states.css

data-state="loading"

source
<div data-state="loading">…</div>

data-state="disabled"

source
<div data-state="disabled">…</div>

data-state="empty" — display: none

Element below has data-state="empty" → hidden:

You should not see this

(hidden as expected)

source
<div data-state="empty">Hidden</div>

Spacing utilities

omg/utils/spacing.css

.gap_sm · .gap_md · .gap_lg

.gap_sm

A
B
C

.gap_md

A
B
C

.gap_lg

A
B
C
source
<div class="flex gap_sm">…</div>
<div class="flex gap_md">…</div>
<div class="flex gap_lg">…</div>

.pad_block_sm .pad_block_md .pad_block_lg .pad_block_xl .pad_block_xxl

sm
pad_block_sm
md
pad_block_md
lg
pad_block_lg
xl
pad_block_xl
source
<section class="pad_block_xl">…</section>

.spacer_block_xs.spacer_block_xxl

xs
sm
md
lg
xl
source
<div class="spacer_block_md"></div>

Text utilities

omg/utils/text.css

.center .uppercase .capitalize .strikethrough .pretty .mono

center — text-align: center

uppercase — text-transform: uppercase

capitalize text — text-transform: capitalize

strikethrough text — text-decoration: line-through

pretty — text-wrap: pretty (better line breaks for long text)

mono — ui-monospace, Cascadia Code, SF Mono, Menlo…

source
<p class="center">Centered</p>
<p class="uppercase">Uppercase</p>
<p class="capitalize">capitalized</p>
<p class="strikethrough">Struck through</p>
<p class="mono">Monospace</p>

.prose

This paragraph is constrained to 66ch and centered. Good for long-form reading. The .prose class sets max-width: 66ch and margin-inline: auto.

source
<div class="prose">
    <p>Long-form content…</p>
</div>

.dim

Normal text for reference

Dim text — slightly smaller, inherits color

source
<p class="dim">Secondary text</p>

.underline

source
<a href="#" class="underline">Underlined link</a>

.typewriter

Typewriter font — uses --font_serif (monospace stack)

source
<p class="typewriter">Monospace text</p>

.cat capitalize

category label — text-transform: capitalize

source
<span class="cat">category</span>

.dots dot leader

Chapter One 12
The Long Chapter Title 47
source
<div class="flex align_baseline">
    <span>Label</span>
    <span class="dots"></span>
    <span>Value</span>
</div>

.weight_thin .weight_light .weight_regular .weight_medium .weight_bold · numeric .weight_100.weight_800

weight_thin — thinnest available

weight_light — light

weight_regular — regular body weight

weight_medium — medium emphasis

weight_bold — bold

100 200 300 400 500 600 700 800
source
<p class="weight_thin">Thin</p>
<p class="weight_bold">Bold</p>
<span class="weight_700">Numeric 700</span>

Visibility utilities

omg/utils/visibility.css

.hide .hidden .maybe_hide .visually_hidden .sr_only

Visible text hidden (display: none) ← .hide removes it
Visible text maybe_hide (hidden below 480px)
The next element is .visually_hidden — accessible to screen readers but invisible: Screen reader only content ← (not in flow)
source
<span class="hide">Hidden</span>
<span class="maybe_hide">Hidden below 480px</span>
<span class="visually_hidden">SR only</span>

.skip_to_content

Place a .skip_to_content link as the first child of <body>. It is visually_hidden until focused — Tab once to reveal it. Lets keyboard users skip the nav directly to the main content.

Skip to content

Tab to the link above to see it appear.

source
<!-- first child of body -->
<a class="skip_to_content" href="#main">Skip to content</a>

Gradient utilities

omg/utils/gradients.css

.gradient_o .gradient_h .gradient_v .gradient_warm

.gradient_o
.gradient_h
.gradient_v
.gradient_warm
source
<div class="gradient_o">…</div>
<div class="gradient_h">…</div>
<div class="gradient_v">…</div>
<div class="gradient_warm">…</div>

Aspect utilities

omg/utils/aspect.css

ratio classes

1:1
4:3
16:9
21:9
9:16
1:2
source
<div class="ratio_16x9">…</div>
<div class="ratio_1x1">…</div>
<div class="ratio_4x3">…</div>
<div class="ratio_21x9">…</div>

.aspect_container · .focus_* · .clip_*

.focus_center
.clip_letterbox
.clip_pillarbox
source
<div class="aspect_container ratio_16x9 focus_center">
    <img src="…" alt="…" />
    <div class="caption">Caption</div>
</div>

Layout utilities

omg/utils/layout.css

.flex · .flex_col

.flex (row)

A
B
C

.flex.flex_col (column)

A
B
C
source
<div class="flex gap_sm">…</div>
<div class="flex flex_col gap_sm">…</div>

.vertical

Vertical text

writing-mode: vertical-rl, rotate(180deg), uppercase

source
<span class="vertical">Label</span>

.flex_wrap .flex_1 .fill .w_full

.flex_wrap — wraps children

A
B
C
D
E

.flex_1 / .fill — grow to fill remaining space

fixed
fill — flex: 1
fixed

.w_full — width: 100%

w_full
source
<div class="flex flex_wrap gap_sm">…</div>
<div class="flex gap_sm">
    <div>fixed</div>
    <div class="fill">fills space</div>
</div>
<div class="w_full">full width</div>

.align_start .align_center .align_end .align_baseline .align_stretch

.align_start

A
B

.align_center

A
B

.align_end

A
B

.align_baseline

small large

.align_stretch

A stretch
B stretch
source
<div class="flex align_center">…</div>
<div class="flex align_baseline">…</div>
<div class="flex align_stretch">…</div>

.justify_start .justify_center .justify_end .justify_between

.justify_start

A
B

.justify_center

A
B

.justify_end

A
B

.justify_between

A
B
C
source
<div class="flex justify_center">…</div>
<div class="flex justify_between">…</div>

.clipped_circle

circle
source
<div class="clipped_circle">…</div>

.maximise — negative margin bleed

inside container padding

.maximise — bleeds past parent padding
source
<div class="maximise">Full-bleed element</div>

Form utilities

omg/5components.css

.field — label + input wrapper

source
<div class="field">
    <label for="name">Name</label>
    <input type="text" id="name" placeholder="…" />
</div>

input types

source
<input type="text" />
<input type="email" />
<input type="password" />
<input type="search" />
<input type="number" />
<input type="date" />

textarea

source
<div class="field">
    <label for="msg">Message</label>
    <textarea id="msg" rows="4"></textarea>
</div>

.select_wrap — select with chevron

source
<div class="field">
    <label for="sel">Country</label>
    <div class="select_wrap">
        <select id="sel">
            <option>Choose…</option>
        </select>
    </div>
</div>

disabled · invalid states

Submit the form to trigger :invalid styles.

source
<input type="text" disabled value="Cannot edit" />
<input type="email" required value="bad-value" />

Animation utilities

omg/utils/animation.css

.fade_in

Open the details below to trigger @starting-style — the element animates in on first render.

open to animate
.fade_in — fades from opacity 0
source
<div class="fade_in">Fades in on first render</div>

.slide_up .slide_down

Open each details to see the animation trigger.

open .slide_up
.slide_up — slides from below
open .slide_down
.slide_down — slides from above
source
<div class="slide_up">Slides in from below</div>
<div class="slide_down">Slides in from above</div>

.scale_in

Open the details to trigger the animation.

open .scale_in
.scale_in — scales from 0.85 to 1
source
<div class="scale_in">Scales in on first render</div>

Transition utilities

omg/utils/transitions.css

.vt_* — View Transitions API

The View Transitions API animates between page states or navigations. Assign a unique view-transition-name to elements you want animated across navigations. FIKO provides utility classes for common named transition slots.

.vt_hero .vt_title .vt_image .vt_card .vt_nav

Browser support: Chrome 111+, Edge 111+. Not yet in Firefox or Safari stable. Use @supports (view-transition-name: foo) to gate enhanced behaviour.

source
<!-- same element across two pages -->
<img class="vt_hero" src="hero.jpg" alt="…" />

<h1 class="vt_title">Page title</h1>

<!-- gate with @supports -->
@supports (view-transition-name: foo) {
    /* enhanced cross-page animation styles */
}

.fiko_glow + .fiko_orbital

omg/utils/fiko.css

.fiko_glow — ambient drift glow

FIKO glow

Blurred orbs drift slowly — ambient, not busy

Override: --fiko_orb_a / --fiko_orb_b

custom orb colors: fresh green

source
<section class="fiko_glow" style="min-height: 20rem;">
    <div>Content — children are z-index: 1 above orbs</div>
</section>

<!-- Custom orb colors -->
<section class="fiko_glow" style="--fiko_orb_a: oklch(0.72 0.22 145);">…</section>

.fiko_orbital — true elliptical orbit (CSS Motion Path)

FIKO orbital

Two orbs on separate ellipses, opposite directions

38s + 54s — super slow, reads as ambient

custom orb colors: fresh green

source
<section class="fiko_orbital" style="min-height: 20rem;">
    <div>Content — children are z-index: 1 above orbs</div>
</section>

<!-- Custom orb colors -->
<section class="fiko_orbital" style="--fiko_orb_a: oklch(0.72 0.22 145);">…</section>

.fiko shake

omg/utils/fiko.css

.fiko — one-shot on load (no JS)

FIKO

LOOK GOOD OR DIE

Plays once on page load. Reload to replay.

source
<h2 class="h2 fiko">FIKO</h2>
<h3 class="h3 fiko">LOOK GOOD OR DIE</h3>

.fiko_hover — shake on :hover

FIKO

LOOK GOOD OR DIE

source
<h2 class="h2 fiko_hover">FIKO</h2>
<h3 class="h3 fiko_hover">LOOK GOOD OR DIE</h3>

token overrides — --shake_distance --shake_duration

Makoko Chihuahua? FIKO!

LOOK DRAMATIC OR DIE

source
<h2 class="h2 fiko_hover" style="--shake_distance: 8px; --shake_duration: 0.35s">FIKO subtle</h2>
<h2 class="h2 fiko_hover" style="--shake_distance: 30px; --shake_duration: 0.9s">LOOK GOOD OR DIE dramatic</h2>