Design System
A contextual atomic design system for kinoo.dev. Shared components live in a common library, while feature-specific components stay with their context.
Work in progress.
Foundations
Design tokens and base styles that form the building blocks of the system.
Colors
Color palette and CSS variables used throughout the website.
Background Colors
--background-color #181927 --background-frosted rgba(24, 25, 39, 0.05) Text Colors
--color #e0e0e0 --light-color #f6f5f7 Accent Colors
--accent-color #f8ba88 --secondary-accent-color #c9a88d --accent-bright #f6b17a Section Theme Colors
Each section uses a themed color palette. These override --accent-color and --secondary-accent-color at the section level.
Green (Realisations)
--green-lightest#9ae5b1--green-light#80d49a--green#66c384--green-dark#5ab376--green-darker#4a9c63--green-darkest#3d8552Pink (Experiences)
--pink-lightest#f8c8d9--pink-light#f8a4c0--pink#f68dab--pink-dark#f47799--pink-darker#f26088--pink-darkest#d55478Purple (Formations)
--purple-lightest#c9bce6--purple-light#b09ee0--purple#9c85d3--purple-dark#8870c7--purple-darker#745bba--purple-darkest#6048a0Card Colors
--card-first-background-color#2d2d3b--card-alt-background-color#1c2638--card-hover-background#313d50Border Colors
--border-colorrgba(255, 255, 255, 0.1)--border-hover-colorrgba(255, 255, 255, 0.2)Usage
Import variables from @/styles/variables.css or use CSS custom properties directly in your styles.
Typography
Font sizes and heading styles used throughout the website.
Headings
--h1-size Heading 1
--h2-size Heading 2
--h3-size Heading 3
--subtitle-size Subtitle text
--font-size Body text paragraph
--button-font-size Size Variables
| Variable | Default | 1368px | 900px | 600px |
|---|---|---|---|---|
--h1-size | 96px | 92px | 86px | 64px |
--h2-size | 38px | 48px | 44px | 36px |
--h3-size | 24px | 24px | 20px | 18px |
--subtitle-size | 22px | 24px | 20px | - |
--font-size | 18px | 18px | 16px | - |
--button-font-size | 15px | 15px | 15px | - |
Font Family
The website uses Outfit as the primary font family with weights from 100 to 800.
Spacing
Consistent spacing scale used throughout the application.
Scale
4px 8px 12px 16px 24px 32px 48px 64px Section Margin
| Variable | Default | 1368px | 900px | 600px |
|---|---|---|---|---|
--section-margin | 142px | 192px | 148px | 94px |
Shared / Atoms
Reusable atomic components shared across multiple features.
Tag
Atom
Default
title="TypeScript" With Icon
title="Terminal" icon={terminalSvg} Highlighted
title="Featured" highlight Props
| Prop | Type | Default | Description |
|---|---|---|---|
title | string | required | The text content of the tag |
icon | string | - | SVG icon as raw string |
highlight | boolean | false | Adds accent border |
hero | boolean | false | Hero animation variant |
TagLink
Atom
Props
| Prop | Type | Default | Description |
|---|---|---|---|
href | string | required | URL to link to |
text | string | required | Link text |
BurgerIcon
Atom
Animated hamburger menu icon that transforms to an X when the parent has .open class.
States
Usage
<BurgerIcon />
Designed to be used inside an IconButton. The animation triggers when the parent element has the .open class.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
class | string | - | Additional CSS classes |
Animation
The three lines transform using CSS transitions (0.3s ease):
- Top line rotates 45deg and moves down
- Middle line fades out
- Bottom line rotates -45deg and moves up
H3Tagged
Atom
Heading with an inline tag badge, used for card titles with categorization.
Default
Project Title
Reacttitle="Project Title" tag="React" Props
| Prop | Type | Default | Description |
|---|---|---|---|
title | string | required | The heading text |
tag | string | required | The tag/badge text |
Usage
Typically used within CardTitle to display job titles or project names with their category/type.
Shared / Molecules
Reusable compound components shared across multiple features.
Card
Molecule
Base container component with gradient border effect. Parent of the Card compound system.
Basic Card
Card content goes here. Cards use slots for flexible content.
<Card>...content...</Card> Card with Content
Project Title
This is a description of the project. Cards support complex layouts with titles, tags, and descriptions.
Card Family Overview
| Component | Purpose | Usage |
|---|---|---|
Card | Base container | Wrapper with gradient border |
CardContent | Layout helper | Structured content with slots |
CardTitle | Title block | Job/project title with metadata |
CardSplit | Two-column layout | Title + description + aside |
Animation Attributes
Add data-animate-elem to elements for reveal animations. Used with revealCards utility for staggered fade-in effects.
CardContent
Molecule
Layout wrapper with named slots for structured card content. Used inside Card.
Slots
slot="title" Header/title area slot="marge" Right-aligned content next to title slot="description" Main body text default slot Additional content (tags, links) Usage
<Card><CardContent>...</CardContent></Card> CardTitle
Molecule
Title block for cards with company/project metadata. Uses H3Tagged internally.
Props
| Prop | Type | Description |
|---|---|---|
title | string | Main title (uses H3Tagged) |
tag | string | Category badge |
href | string | Company/project URL |
label | string | Link text |
location | string | Location (with dot separators) |
date | string | Date range |
Usage
<CardTitle slot="title" title="Developer" tag="Freelance" ... /> CardSplit
Molecule
Two-column grid layout for cards with title, description, and aside areas.
Layout Preview
<CardSplit reverse> to flip layout Props
| Prop | Type | Default | Description |
|---|---|---|---|
reverse | boolean | false | Flips the layout (aside on left) |
Slots
| Slot | Grid Area | Description |
|---|---|---|
title | Top-left | Card header with H3Tagged |
description | Bottom-left | Main content area |
aside | Right column (spans 2 rows) | Image or supplementary content |
Spotlight
Molecule
Interactive spotlight effect that follows mouse movement on desktop. Creates a glowing halo that tracks the cursor.
Demo
Card 1
Hover over the container to see the spotlight effect
Card 2
Each card tracks the cursor independently
Card 3
Color is customizable via the color prop
Usage
<Spotlight color="var(--accent-bright)">...</Spotlight>
Wrap content with the Spotlight component. Add data-spotlight attribute to the parent container and initialize with spotlight() function.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
color | string | required | CSS color for the spotlight glow effect |
class | string | - | Additional CSS class for the wrapper |
Implementation
The parent container needs data-spotlight attribute and must be initialized with spotlight(container) from @/lib/dom/spotlight. The function tracks mouse movement and updates --mouse-x and --mouse-y CSS properties.
Shared / Organisms
Complex patterns shared across multiple features.
Section Pattern
Organism
Shared layout pattern used by Experiences, Realisations, and Formations sections. Combines section header, themed grid, and card-based content.
Pattern Overview
| Section | Color Theme | Card Type | Grid Layout |
|---|---|---|---|
Experiences | Pink (#f68dab) | CardContent | 2-column masonry |
Realisations | Green (#66c384) | CardSplit | 3-column |
Formations | Purple (#9c85d3) | CardContent | 3-column |
Section Header
Expériences
All sections use <span class="subtitle"> + <h2> pattern with section-specific accent colors.
Structure
<section> Container with data-animate-section <span.subtitle> Section label (e.g., "Mes") <h2> Section title <div.grid> Grid with data-spotlight <Spotlight> Hover effect wrapper <Card> Card container <CardContent> or CardSplit for realisations Section Theming
Each section overrides CSS custom properties for its color theme:
#experiences {
--accent-color: #f68dab;
--secondary-accent-color: #f8c8d9;
--card-title-font-size: 16px;
}| Variable | Purpose |
|---|---|
--accent-color | Primary section color (subtitle, links, tags) |
--secondary-accent-color | Lighter variant for hover states |
--card-title-font-size | Title size override |
Data Attributes
| Attribute | Element | Purpose |
|---|---|---|
data-animate-section | section | Triggers section reveal animation |
data-spotlight | .grid | Enables spotlight mouse tracking |
data-animate-elem | cards | Staggered card reveal |
Grid Layouts
Spotlight Integration
Each section initializes the spotlight effect via script:
import { spotlight } from "@/lib/dom/spotlight";
const container = document.getElementById("experiences-grid");
if (container) spotlight(container);Demo
Example Card
DemoCompany Location 2024
This demonstrates the card pattern used in section grids.
Hero
Components specific to the hero section.
HeroSubtitle
Atom
Animated subtitle that wraps each character in a span for letter-by-letter animation effects.
Preview
Props
| Prop | Type | Description |
|---|---|---|
subtitle | string | Text to display (each character wrapped in a span) |
Animation
Each character is wrapped in a <span class="letter"> element. The heroAnime.ts animation applies a staggered translateY effect to reveal letters sequentially.
Usage
<HeroSubtitle subtitle="Développeur Frontend Freelance" /> Styling
| Property | Value |
|---|---|
font-size | var(--hero-span-size) |
font-weight | 100 |
color | var(--accent-color) |
line-height | 38px |
Header
Site header and navigation components.
Header
Organism
Sticky site header with navigation and frosted glass effect.
Preview
Structure
header Sticky container with frosted glass .header Flex container (space-between) nav Left: logo + NavBar HeaderMenu Right: links + CTA Frosted Glass
backdrop-filter: blur(30px) + gradient mask Responsive
| Breakpoint | Height | Changes |
|---|---|---|
| Default | 120px | Full layout |
| <980px | 120px | NavBar hidden |
| <600px | 80px | CTA hidden |
Usage
<Header /> Included in Layout.astro. No props required.
HeaderLink
Atom
External Links
The external prop adds target="_blank" and rel="noreferrer nofollow noopener".
Props
| Prop | Type | Default | Description |
|---|---|---|---|
href | string | required | Link destination |
label | string | required | Accessible label (also displayed for badge variant) |
tooltip | string | label | Custom tooltip text (defaults to label) |
variant | "icon" | "badge" | "icon" | Visual style |
external | boolean | false | Opens in new tab with security attributes |
Tooltip
Icon variant displays a tooltip above on hover. Badge variant has no tooltip since it already shows text.
Hover States
Both variants transition to accent color on hover. Icon SVG paths and badge border/text all use the same accent color for consistency.
Contact
Contact section and related components.
Contact
Organism
Full contact section combining description text and an interactive form (SolidJS).
Structure
<section id="contact"> Main container with animation attribute <h2> Section title .contact-content Flexbox container .contact-description Left column with intro text <ContactForm /> SolidJS form component ContactForm (SolidJS)
| Prop | Type | Description |
|---|---|---|
accessToken | string | Web3Forms API access key |
Uses client:load directive for immediate hydration. Form validation handled by Modular Forms.
Layout
| Breakpoint | Layout |
|---|---|
| Desktop (>1200px) | Side-by-side: description (max 466px) + form |
| Tablet/Mobile | Stacked: description then form |
Form Fields
| Field | Type | Validation |
|---|---|---|
| Name | text input | Required |
| email input | Required, email format | |
| Message | textarea | Required |
Usage
<Contact />
No props required. Form uses environment variable VITE_WEB3FORMS_ACCESS_KEY for API authentication.
Integration
The #contact section is detected by FloatingContact and viewDetection utilities for scroll-based navigation highlighting.
FloatingContact
Organism
Mobile-only sticky contact button that appears at the bottom of the screen. Auto-hides when the contact section is visible.
Behavior
| Condition | State | CSS |
|---|---|---|
| Desktop (>600px) | Hidden | display: none |
| Mobile, #contact not visible | Visible | Default styles |
| Mobile, #contact in viewport | Hidden | .current class added |
Positioning
| Property | Value |
|---|---|
position | sticky |
bottom | 36px |
z-index | 300 |
width | 36px |
View Detection Integration
Uses viewDetection utility from @/lib/dom/viewDetection to detect when #contact section enters the viewport. The .current class is toggled to fade out the button.
Usage
<FloatingContact /> No props required. Component is self-contained with its own scroll detection logic.
Sidebar
Design system navigation component.
Templates
Common patterns showing how components combine in real usage.
Compositions
Template
Real-world examples showing how atoms, molecules, and organisms combine to create complete UI patterns.
Experience Card
The primary card pattern used in the Experiences section. Combines Spotlight, Card, CardContent, and CardTitle.
Lead Developer
FreelanceCompany Lille 2024
Description of the role and responsibilities. Includes highlighted technologies and achievements.
- Feature or responsibility one
- Feature or responsibility two
<Spotlight color="var(--pink)">
<Card>
<CardContent>
<CardTitle slot="title" ... />
<p slot="description">...</p>
<ul>...</ul>
<img slot="marge" ... />
</CardContent>
</Card>
</Spotlight>Hero Title Block
The hero section title pattern combining HeroSubtitle (animated) with the main h1.
Martin Kinoo
<div class="title">
<HeroSubtitle subtitle="Développeur Frontend Freelance" />
<h1><span>Martin</span> <span>Kinoo</span></h1>
</div>Tech Stack Tags
A collection of Tag components displaying technology stack. Used in Hero section.
<ul>
{techs.map(tech => (
<li>
<Tag
title={tech.title}
hero={true}
icon={tech.icon}
highlight={tech.highlight}
/>
</li>
))}
</ul>Section Header
Standard section header pattern with subtitle and main heading. Used across all main sections.
Expériences
<section id="experiences">
<span class="subtitle">Mes</span>
<h2>Expériences</h2>
...
</section>Component Hierarchy
| Pattern | Components Used | Location |
|---|---|---|
| Experience Card | Spotlight / Card / CardContent / CardTitle | Experiences section |
| Realisation Card | Spotlight / Card / CardSplit / H3Tagged + Slider | Realisations section |
| Formation Card | Card / CardContent / CardTitle | Formations section |
| Hero Block | HeroSubtitle + h1 + Tags list | Hero section |
| Page Layout | Header + main content + FloatingContact | All pages |
DS Components
Documentation components used to build this design system. Self-documenting meta-components.
DSBlock
Atom
Example
Demo Title
Content inside DSBlock
Props
| Prop | Type | Default | Description |
|---|---|---|---|
title | string | required | Section heading (h3) |
Usage
<DSBlock title="Section Title">
<DSPreview>
<!-- Component preview -->
</DSPreview>
<DSCode>code example</DSCode>
</DSBlock>DSBlock provides consistent 32px margin-top spacing between sections. Use it to wrap each documentation section.
DSPreview
Atom
Example
Props
| Prop | Type | Default | Description |
|---|---|---|---|
class | string | - | Additional CSS classes |
Usage
<DSPreview>
<Button>Click me</Button>
</DSPreview>
<DSPreview class="custom-class">
<!-- Custom styling via class -->
</DSPreview>DSPreview uses 32px padding and 16px gap. Pass custom classes to override flex direction or alignment.
DSCode
Atom
Inline Example
<Button variant="primary" /> Block Example
const greeting = "Hello";
console.log(greeting);Props
| Prop | Type | Default | Description |
|---|---|---|---|
inline | boolean | false | Renders as inline code snippet |
Usage
<!-- Inline code -->
<DSCode inline><Button /></DSCode>
<!-- Block code -->
<DSCode>
const foo = "bar";
console.log(foo);
</DSCode>DSPropsTable
Atom
Example
| Name | Value |
|---|---|
| Primary | Orange button |
| Secondary | Outline style |
With Code Cells
| Prop | Type | Description |
|---|---|---|
title | string | Main heading |
items | array | List of items |
Props
| Prop | Type | Default | Description |
|---|---|---|---|
headers | string[] | required | Table header labels |
rows | Cell[][] | required | Array of rows, each row is array of cells |
Cell can be a string or { code: string } for code formatting.
Usage
<DSPropsTable
headers={["Prop", "Type", "Default", "Description"]}
rows={[
[{ code: "title" }, "string", "required", "The title text"],
[{ code: "disabled" }, "boolean", "false", "Disables the component"],
]}
/>DSStructure
Atom
Hierarchy diagram for displaying component structure or DOM tree.
Example
<Card> Container component <CardTitle> Title section <CardContent> Main content <p> Text paragraph Props
| Prop | Type | Default | Description |
|---|---|---|---|
rows | StructureRow[] | required | Array of structure rows |
StructureRow: { code: string, description: string, indent?: number }
Usage
<DSStructure
rows={[
{ code: "<section>", description: "Container" },
{ code: "<header>", description: "Header area", indent: 1 },
{ code: "<main>", description: "Main content", indent: 1 },
]}
/>DSNote
Atom
Example
This is a note with inline code support. Use it for tips and additional context.
Props
| Prop | Type | Description |
|---|---|---|
| (slot) | any | Content to display as note |
Usage
<DSNote>Note text with <code>code</code></DSNote>
DSNote has 12px margin-top and 70% opacity. Supports inline <code> tags.