Documentation · UI

Design System

Tokens, typography, grid, components, and longgrid blocks

Switch between themes, accents, and fonts using the floating panel on the right. When making global style changes (tokens, components, longgrid blocks), be sure to update this page as well—it’s the project’s live UI catalog.

Colors

The accent and “cool/warm” tones of the entire UI are defined by three numbers in the HSL model (Hue, Saturation, Lightness) at <html>. From these, --accent and derived tokens; neutral backgrounds are slightly tinted with the same hue (--neutral-accent-tint). Light/dark theme — data-theme, mesh — data-mesh-bg. Can be changed via the FAB on the right.

What is --theme-h, --theme-s, --theme-l

In CSS, it looks like this: --accent: hsl(var(--theme-h) calc(var(--theme-s) * 1%) calc(var(--theme-l) * 1%)). Values are written in localStorage (siteThemeV1) and are inserted by an inline script into headto prevent a “foreign” color from flashing during loading.

--bg
--bg-elevated
--surface
--text
--text-muted
--line
--accent
--accent-text
--accent-soft

Additionally: quadratic mesh shades — --accent-square-2 … 4; they depend on hue.

Fonts

A pair of fonts — data-font on <html> (FAB “Typography”): sets --font-accent (headings) and --font (body text). Scale in tables: class, example, purpose.

Font families

data-font Stack Where
merriweather Merriweather + Alice Default pair; Alice—body text, Merriweather—emphasized headings
mono Source Code Pro + PT Mono Monospace pair
geologica Geologica + PT Sans Sans-serif + neutral body text

Typographic scale

Class Example Purpose
.hero__eyebrow

Section caption

Hero, case input
.hero__title

Display main heading

H1 for the main page; reduced on DS for the column
.section__title

Section

“Skills,” “Portfolio,” contacts; main font, no caps
.case-page__h1

Page title

H1 for case studies / Design System
.case-page__sub

Lead text under the heading

Subheading below H1
.section__prose

Main paragraph text.

Prose, lists, and links in the article
h2 in .case-article

H2 subsection

Long-form sections (such as “Colors”)
h3 in .case-article

H3 subsection

Subsections within H2; margins in main.css: 3.25rem top, 1.5rem bottom, after figure 4rem, h3+h3 3.5rem

Rhythm and Code

Rhythm example:

  1. numbered item;

Inline code and block:

--font: "Alice", system-ui, serif;
--font-accent: "Merriweather", var(--font);

Headings use clamp() — scale relative to the viewport; see the “Grid” section for more details.

Grid and Responsive

There is no separate 12-column grid: a full-bleed layout with side margins --space and local CSS Grid within sections. The content column for DS and case studies — .case-article (max-width 48rem).

Basic framework

Breakpoints

From What Changes
860px .hero__grid → 2 columns 1.15fr 0.85fr
760px / 1180px .projects-carousel: --projects-visible 1 → 2 → 3 cards
720px .skills-category__grid → 2 columns
1024px Skills: 6-column mosaic (grid-column: span …)
560px / 1024px .contact-grid → 2 → 4 columns
48rem / 28rem Case gallery: ≤2 col → 1 col
640px case-media-gallery--wide collapses to the width of a column

Hero: one → two columns

Layout .hero__grid (compressed to 860px):

Contacts: 1 → 2 → 4

Demo .contact-grid (placeholders, no transitions):

Skills: mosaic layout on wide screens—see the homepage, #skills. Portfolio: carousel on 100vw with --projects-card-width and JS scrolling — on the homepage #projects.

Wide in case studies

.case-media--wide, .case-media-gallery--wide and .case-callout wider article columns: min(100vw − 2×padding, content + 8rem), with margins --space. On a narrow screen (up to 640px), "wide" collapses to the width of the column. Images with data-image-viewer — the outline and hover effects are the same as .case-video-shell (live examples — case study element demo). The caption below the video is figcaption centered in the column.

Typography and Motion

Fluid type: clamp() on .hero__title, .section__title, .case-page__h1. Rounded corners (data-radius) do not change the grid. For long screenshots and animations, the prefers-reduced-motion: reduce.

Components

Live examples; the shell (header, FAB, footer, cookie) is already integrated on this page.

Buttons

.btn .btn--primary | secondary | ghost · .btn--flat | raised · .btn__icon

FAB buttons

Floating buttons in the lower-right corner (.fab-stack). Icon-only and with a text label.

.fab .fab--primary | secondary · .fab--label (with text) · .fab-primary__ico · .fab__label

Tags

.hero__tags / .hero__tag

.mp-card__tags / .mp-card__tag

Portfolio Card

.mp-card .mp-card--stack-bottom — text on top, cover at the bottom

.mp-card--stack-bottom — glass layer (tokens from .glass-neutral) on the bottom third of the card

Placeholder while images are loading

While img hasn't loaded yet, initImageLoadPlaceholder it .is-img-loading on the image and .has-img-loading the wrapper. The background layer is ::before, a single glow from left to right— ::after (img-ph-shine-sweep). Icons, SVGs, and small images up to 40px are skipped; disable selectively: data-no-img-placeholder. Below is a fixed demo (on the website, the classes are removed after load).

.has-img-loading · .is-img-loading · .img-ph-demo (placeholder demo)

TUI Braille spinner

Loading large images in the viewer (.case-image-viewer) is indicated by a monospaced Braille spinner—just like in TUI. Pure CSS, no JS: 10 frames cycle through an animation. Reusable class: steps()an animation. Reusable class .tui-spinner (color — --accent, font—system mono).

⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏ ⠋ ⠙ ⠹ ⠸ ⠼ ⠴ ⠦ ⠧ ⠇ ⠏

.tui-spinner · frames: ⠋ ⠙ ⠹ ⠸ ⠼ ⠴ ⠦ ⠧ ⠇ ⠏ · prefers-reduced-motion displays ⠋

Skill card

skill-task-card__task — the task description provided by the business.

skill-task-card__solution — the first approach to the solution.

The second item in the solutions section.

.skill-task-card__task · __solutions · __solution

Callout

Longread accent block: wider than the column (like wide media), text .case-callout__content slightly larger than the main paragraph.

.case-callout · .case-callout__emoji · .case-callout__emoji--pulse · .case-callout__content

Contact Cards

On the home page, there are four cards in a grid (1→2→4 columns). Here are two examples—the grid is forced into two columns.

.contact-card--link · --action · --brand-*

Section with a background

On the homepage, the strip .section--surface is visually presented using mesh; in other cases, the page background is solid—see the compact demo below with background: var(--surface).

section__title

Snippet: .section.section--surface + .section__inner

.section · .section--surface · .section--tight · .section__inner

Separators

Horizontal separators: a line or simply white space (indentation). Modifiers --line, --air, --air-lg.




.sep · .sep--line · .sep--air · .sep--air-lg

Blocks

Longgrid case layout: media and galleries, link cards, videos, callouts, wide blocks, and other partials. A live example with all variations is available on a separate page; use it to copy sections when building a new case.

Case element demo

Activity

On the homepage in the section #mini-projects card mp-card section on the homepage in a masonry grid. Types, cells, and the live layout are on a separate page.

Activity Card Catalog