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.
Documentation · UI
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.
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.
--theme-h, --theme-s, --theme-l--theme-h — hue (Hue), position on the color wheel 0–360°. A hue shift
recolors buttons, links, the mesh gradient, and square accents (--accent-square-2 …
4), without having to manually adjust each hex value.
--theme-s — Saturation: how “pure” the color is, rather than gray.
--theme-l — Accent lightness: darker or lighter than the primary brand color
(usually limited by the panel’s range to ensure buttons remain readable).
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.
Additionally: quadratic mesh shades — --accent-square-2 … 4; they depend on hue.
A pair of fonts — data-font on <html> (FAB “Typography”): sets
--font-accent (headings) and --font (body text). Scale in tables: class, example, purpose.
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 |
| 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 example:
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.
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).
--space: clamp(1rem, 4vw, 2.75rem) — horizontal margins + safe-area-inset.--max: none — no fixed 1200px “box”; width = viewport minus padding..section — vertical spacing via clamp(); .section__inner centers the block..section--tight — More compact vertically (case studies, this page).| 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 |
Layout .hero__grid (compressed to 860px):
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.
.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.
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.
Live examples; the shell (header, FAB, footer, cookie) is already integrated on this page.
.btn .btn--primary | secondary | ghost · .btn--flat | raised · .btn__icon
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
.hero__tags / .hero__tag
.mp-card__tags / .mp-card__tag
.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
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)
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-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
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
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-*
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).
Snippet: .section.section--surface + .section__inner
.section · .section--surface · .section--tight · .section__inner
Horizontal separators: a line or simply white space (indentation). Modifiers --line, --air, --air-lg.
.sep · .sep--line · .sep--air · .sep--air-lg
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.
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.