UI Style Guide
This is the guide that defines the visual standards for this website’s user interface (UI).
This UI style guide defines a shared visual language and sets the visual and functional standards for this website. It ensures the UI is consistent, responsive, accessible, and enjoyable to use, whether in light or dark mode.
Grid system #
This site uses a simple, flexible, and responsive 12-column grid system.
On screens up to 767px wide, columns stack vertically unless stated otherwise. At
768px and above, columns align horizontally according to the grid.
The main layout breakpoints are 1100 px, 992 px, 768 px, and 576 px, with custom values
as needed.
@media (max-width: 768px) {
[class^="grid__col"] {
flex-basis: 100%;
}
}
Spacing System #
The spacing system uses a consistent scale based on rem units. Spacing utilities are available for margins and padding, with directional variants for top, bottom, left, and right.
.m0 0
.m1 var(--space-100)
.m1-5 var(--space-150)
.m2 var(--space-200)
.m3 var(--space-300)
.m4 var(--space-400)
.m5 var(--space-500)
.m6 var(--space-600)
.p0 0
.p1 var(--space-100)
.p1-5 var(--space-150)
.p2 var(--space-200)
.p3 var(--space-300)
.p4 var(--space-400)
.p5 var(--space-500)
.p6 var(--space-600)
Colors #
Color Tokens
Semantic tokens provide meaning and ensure consistent color usage across the site. These tokens automatically adapt to light and dark mode themes.
--c-brand-base
--c-brand-light
--c-body-bg
--c-body-text
--c-warning
--c-alert
--c-focus-visible
Color Palettes
The color palettes are the foundational color scales defined in OKLCH units. These raw
color values are used to build semantic tokens. For example, --c-brand-base
references var(--orange-650) from the orange scale below.
Text elements #
All text elements should be responsive across browsers and viewport sizes. Avoid
horizontal
scrollbars whenever possible.
Some elements, such as headings, may adjust their size
based on the viewport width.
Headings
These are standard headings. Heading 1 Heading 2 Heading 3 Heading 4 Heading 5 Heading 6 These are custom headings. .headline .title-second .title-third .Title-DisplayInline text elements
The a element example
A muted a element example
The abbr element and abbr element with
title examples
The b element example
The cite element example
The code element example
The del element example
The dfn element and dfn element with
title examples
The em element example
The i element example
The img element
example
The mark element example
The ins element example
The kbd element example
The q element
exampleinside
a q element
The s element example
The samp element example
The small element example
The span element example
The strong element example
The sub element example
The sup element example
The u element example
The var element example
Paragraphs
This a sans-serif font paragraph (default).Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et m. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor.
This a serif font paragraph.Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et m. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor.
This a monospaced font paragraph.Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et m. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor.
This a leading font paragraph.The European languages are members of the same family. Their separate existence is a myth. For science, music, sport, etc, Europe uses the same vocabulary. The languages only differ in their grammar, their pronunciation and their most common words. Everyone realizes why a new common language would be desirable.
pre
SUN
SHINES
THROUGH THE
CLOUDS AND LIGHTS UP THE EARTH BELOW WITH WARMTH,
BRINGING HOPE AND JOY TO ALL WHO FEEL ITS RAYS,
SOFT BREEZES CARRY SONGS OF HAPPINESS AND PEACE,
WHILE FLOWERS BLOOM AND BIRDS SING LOUD AND CLEAR,
SPREADING SMILES FAR AND WIDE, LIKE GOLD THAT GLIMMERS,
ILLUMINATING HEARTS WITH KINDNESS EVERY DAY,
A BEAUTIFUL REMINDER THAT LIFE IS BRIGHT,
AND MOMENTS LIKE THIS MAKE ALL FEEL RIGHT,
BASK IN THE LIGHT,
FEEL THE LOVE,
CHERISH NOW.
pre & code
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width="device-width", initial-scale="1">
<title>...</title>
<link rel="stylesheet" href="main.css">
</head>
<body>
<header>...</header>
<main>...</main>
<footer>...</footer>
<script src="app.js"></script>
</body>
</html>
blockquotes
Blockquote-styled variant.Some sort of famous witty quote marked up with a
Tom Whatever<blockquote>and a child<p>element.
This is a styled blockquote variant used for testimonials and contact pages.
Author Name
Summary & details
The <details> and <summary> elements create
collapsible content sections.
What is this?
This is a <details> element with a <summary>.
Lists
Ordered list
- list item
- list item
-
- list item
- list item
- list item
- list item
- list item
- list item
Unordered list
- list item
- list item
-
- list item
- list item
- list item
- list item
- list item
- list item
Styled ordered list
- list item
- list item
-
- list item
- list item
- list item
- list item
- list item
- list item
Styled unordered list
- list item
- list item
-
- list item
- list item
- list item
- list item
- list item
- list item
Unstyled ordered list
- list item
- list item
-
- list item
- list item
- list item
- list item
- list item
- list item
Unstyled unordered list
- list item
- list item
-
- list item
- list item
- list item
- list item
- list item
- list item
Emoji #
This is the official UNICODE Emoji list
of 3,790 emojis (v16.0).
Emojis can be copied and pasted directly into the code, or their codepoints can be used
by replacing U+ with &#x. This is a hamburger emoji:
& # x 1 F 3 5 4 (spaces added for clarity) → 🍔.
| 🔥 | 😁 | 🤣 | 😍 | 😝 | 😴 | 😵 | 😎 |
| 🙉 | 💘 | 💯 | 💥 | 👋 | 👌 | ... | ... |
Embedded content #
All elements must be fully responsive, although the UI may appear inconsistent across browsers and platforms.
HTML Video & Audio Embeds
YouTube embed
Forms #
By default, <input>, <select>, and
<textarea> elements are set to 100% width. To avoid cross-browser
inconsistencies and accessibility issues, it is recommended to wrap these elements in a
container.
The appearance of some elements (such as <select> and checkboxes) may
vary between browsers.
Inputs
Buttons
Buttons can be created using a <button> (preferred),
<input type="button">, or
<a>s styled as buttons. In all cases, the UI should remain consistent.
Buttons support multiple states. Disabled buttons should use the disabled
attribute (for <button> and <input>) or
aria-disabled="true" (for links styled as buttons).
Tables #
Tables should be responsive to ensure they display correctly on all screen sizes without breaking the layout.
| Header 1 | Header 2 | Header 3 | Header 4 | Header 5 | Header 6 | Header 7 | Header 8 |
|---|---|---|---|---|---|---|---|
| row1_cell1 | row1_cell2 | row1_cell3 | row1_cell4 | row1_cell5 | row1_cell6 | row1_cell7 | row1_cell8 |
| row2_cell1 | row2_cell2 | row2_cell3 | row2_cell4 | row2_cell5 | row2_cell6 | row2_cell7 | row2_cell8 |
| row3_cell1 | row3_cell2 | row3_cell3 | row3_cell4 | row3_cell5 | row3_cell6 | row3_cell7 | row3_cell8 |
| row4_cell1 | row4_cell2 | row4_cell3 | row4_cell4 | row4_cell5 | row4_cell6 | row4_cell7 | row4_cell8 |
| row5_cell1 | row5_cell2 | row5_cell3 | row5_cell4 | row5_cell5 | row5_cell6 | row5_cell7 | row5_cell8 |
| Header 1 | Header 2 | Header 3 | Header 4 | Header 5 | Header 6 | Header 7 | Header 8 |
Components #
Reusable UI components that can be combined to build consistent interfaces across the site. Each component is designed to be responsive and accessible.
Carousel
A responsive image carousel. Supports lazy loading and navigation controls.
<div class="container-embla">
<div class="embla">
<div class="embla__viewport">
<div class="embla__container">
<div class="embla__slide">
<figure class="project-single__image-container">
<img loading="lazy" src="image-1.jpg" alt="Slide 1">
<figcaption>Slide 1 caption</figcaption>
</figure>
</div>
<div class="embla__slide">
<figure class="project-single__image-container">
<img loading="lazy" data-src="image-2.jpg" alt="Slide 2">
<figcaption>Slide 2 caption</figcaption>
</figure>
</div>
</div>
</div>
<div class="embla__controls">
<div class="embla__dots"></div>
</div>
</div>
</div>
Media Object (Bio)
A media object pattern with an avatar image and text content. The avatar floats left on larger screens. On mobile devices, the avatar stops floating and stacks above the text in two rows.
This is an example of the bio component. The avatar image floats to the left on larger screens, creating a media object layout. On mobile devices, the avatar stops floating and stacks above the text.
<div class="bio clearfix">
<div class="container-avatar">
<img class="avatar" src="image.jpg" alt="Person name" width="200" height="200">
</div>
<p class="lead">
Bio text content goes here. The avatar will float left on larger screens. On mobile, it stacks above the text.
</p>
</div>
Testimonial
A styled blockquote with decorative quotation marks. Attribution via
render_testimonial_cite(): name · role (optional context), then a LinkedIn
or Upwork source link.
“This is an example testimonial. The component uses a styled blockquote with decorative quotation marks that scale on larger screens. It's perfect for showcasing client feedback and quotes.”
Author N. · Role Title (LinkedIn recommendation ↗)
<blockquote class="blockquote-styled">
<p>
<i>"</i>Testimonial text goes here.<i>"</i>
</p>
<small class="testimonial-cite">
<span class="testimonial-cite__name">Author N.</span> · Role Title
<span class="testimonial-cite__source">(LinkedIn recommendation ↗)</span>
</small>
</blockquote>
Stats Bar
A short metrics list for project case studies. Up to four figures with brief labels.
<ul class="stats-bar" aria-label="Example project figures">
<li class="stats-bar__item">
<span class="stats-bar__value">
<span class="js-stats-bar-value"
data-stats-value="100"
data-stats-prefix=""
data-stats-suffix="+"
data-stats-decimals="0">100+</span>
</span>
<span class="stats-bar__label">
<span class="stats-bar__label-word">Websites</span>
<span class="stats-bar__label-word">delivered</span>
</span>
</li>
<!-- up to 3 more .stats-bar__item -->
</ul>
Project Details
A sidebar component used on project pages to display metadata. Features a sticky position on larger screens and a styled background with border.
<div class="project-single__details">
<aside>
<h2 class="sr-only">Project Details</h2>
<div class="mb3">
<span>Project</span>
Project Name
</div>
<div class="mb3">
<span>Company</span>
Company Name
</div>
<div class="mb3">
<span>Year</span>
2024
</div>
<div>
<span>Technologies</span>
Technology list
</div>
</aside>
</div>
Table of Contents
A navigation component for displaying page sections. Links wrap responsively.
<nav class="table-of-contents" aria-label="Table of contents">
<span>On This Page</span>
<ul class="list-unstyled">
<li><a class="btn btn--outline" href="#section-1">Section 1</a></li>
<li><a class="btn btn--outline" href="#section-2">Section 2</a></li>
<li><a class="btn btn--outline" href="#section-3">Section 3</a></li>
<li><a class="btn btn--outline" href="#section-4">Section 4</a></li>
<li><a class="btn btn--outline" href="#section-5">Section 5</a></li>
</ul>
</nav>
Project Card
A card component for displaying work/project previews. Features hover effects and a link.
<div class="card-work">
<a href="#">
<span>Category</span>
<h3 class="title-display">Project Title</h3>
<p>Project description text.</p>
</a>
<a href="#">
View project details
</a>
</div>
