TaiGraphics · Versie 3.0 · 2026
Design System
De visuele bouwstenen van taigraphics.nl. Tokens, typografie, componenten en codevoorbeelden op basis van de bestaande Astro + Tailwind codebase.
1. Kleuren
Altijd via CSS custom properties. Nooit hardcoded hex in componenten of Tailwind arbitrary colour values buiten deze tokens.
Brand
Primary
--color-primary
#0000ff
Secondary
--color-secondary
#6600cc
Accent Dark
--color-accent-dark
#100b7e
Accent Hover
--color-accent-hover
#2b7fff
Achtergronden
Page BG
--color-page-bg
#f5f5f5
Section Alt
--color-section-alt
#cedbef
Card BG
--color-card-bg
#ffffff
Card Border
--color-card-border
#f5f5f5
Category tags
Tag Tooling
--color-tag-tooling
#00adee
Tag AI
--color-tag-ai
#aa33bb
Tag Training
--color-tag-training
#ff9933
Tag Design System
--color-tag-design-system
#339999
2. Typografie
Twee fonts. Aeonik voor display en headings, DM Sans voor alles wat gelezen wordt. Nooit font-weight 700 — maximaal 600.
h1 · Aeonik · 36px
Heading niveau 1
h2 · Aeonik · 24px
Heading niveau 2
h3 · Aeonik · 20px
Heading niveau 3
body · DM Sans · 17px · leading-8
Body copy op 1.0625rem met ruime regelafstand voor leesbaarheid op alle schermen.
strong · DM Sans · 600
Vetgedrukte nadruk voor sleuteltermen in een zin.
kicker · DM Sans · 11px · uppercase · tracking-[0.15em]
Kicker label voorbeeld
CSS tokens
--font-aeonik: "Aeonik", system-ui, sans-serif;
--font-dmsans: "DM Sans", system-ui, sans-serif;
h1, h2, h3 {
font-family: var(--font-aeonik);
font-weight: 500;
}
body {
font-family: var(--font-dmsans);
font-size: 1.0625rem;
}
.card-kicker {
font-size: 0.6875rem;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.15em;
} 3. Spacing & layout
Drie containerbreedtes houden marges en regelbreedte consistent. Eén spacing-token regelt het verticale ritme tussen blokken.
Containerbreedtes
.page-container-800
800px · Blogtekst, prose content
.page-container-992
992px · Listings, brede secties, galerijen
Code
/* Containersysteem */
.page-container-800 { max-width: 800px; }
.page-container-992 { max-width: 992px; }
/* Block spacing token */
--space-block-y: 2rem;
.card-stack {
margin-block: var(--space-block-y);
}
/* section-alt alleen in case studies */
.section-alt {
background: var(--color-section-alt);
}
/* Blogart ikelen: altijd wit */
<ContentSection size="800">
...
</ContentSection> 4. Atoms
De kleinste herbruikbare elementen. Knoppen, tags, links en border accenten.
btn-primary
<a href="/blog" class="btn-primary">
Artikelen openen
</a>
/* Eigenschappen */
border-radius: 9999px;
padding: 0.5rem 1.5rem;
font-weight: 600;
font-size: 0.875rem;
transition: background/color 150ms ease-in-out; blog-tag
<span class="blog-tag blog-tag--tooling">
Tooling
</span>
<span class="blog-tag blog-tag--ai">AI</span>
<span class="blog-tag blog-tag--training">
Training
</span>
<span class="blog-tag blog-tag--design-system">
Design System
</span>
/* Variant = categoryVariant in frontmatter */ Border accenten
border-bottom-gradient
2px · subheadings in content
border-bottom-gradient-8
8px · visueel accent op hoofdtitels
border-top-gradient-3
3px top · kicker labels in case headers
<!-- 2px blauwe onderrand -->
<h3 class="border-bottom-gradient">Titel</h3>
<!-- 8px visueel accent -->
<h2 class="border-bottom-gradient-8">Titel</h2>
<!-- 3px bovenrand op kicker -->
<p class="border-top-gradient-3 card-kicker">
UX / UI / Design System
</p>
/* Nooit de border logica inline herhalen */ 5. Cards
Alle kaartpatronen zijn gebouwd op .card-base als fundament.
Wit, 12px radius, subtiele schaduw.
card-base
Kicker label
Kaart titel
Omschrijving die op de listingpagina verschijnt als samenvatting van het artikel of project.
/* card-base */
background: var(--color-card-bg);
border-radius: 0.75rem;
box-shadow: 0 1px 3px rgba(15,23,42,0.08);
/* card-interactive voegt toe: */
.card-interactive:hover {
transform: translateY(-0.125rem);
box-shadow: 0 6px 16px rgba(15,23,42,0.1);
transition: transform/box-shadow 200ms ease-out;
} QuoteCard
"
"Kevin is een hele fijne collega. Een echte teamplayer. Als UX/UI designer heeft hij een volledig design system opgetuigd."
Rene Lourens
Astron — The Netherlands Institute for Radio Astronomy
import QuoteCard from
'../../components/content/QuoteCard.astro'
<QuoteCard
quote='"Tekst van het citaat."'
author="Naam Achternaam"
subtitle="Functie, Organisatie"
/> CaseIntroCard
UX / Design System / Front-end
Korte omschrijving van het project en de aanpak.
Opdrachtgever: Bedrijfsnaam
Rol: UX Designer
Tools: Figma / Storybook
import CaseIntroCard from
'../../components/content/CaseIntroCard.astro'
<CaseIntroCard
imageSrc="/thumb003.png"
imageAlt="Alt tekst"
meta="UX / Design System"
summary="Projectomschrijving..."
details={[
{ label: "Opdrachtgever", value: "Naam" },
{ label: "Rol", value: "UX Designer" },
]}
/> 6. Blog componenten
Componenten die direct in MDX blogart ikelen worden geïmporteerd.
Blogsecties zijn altijd wit, zonder sectionClass.
ContentSection
ContentSection size="800"
Section heading (h2)
Paragraaftekst. Elke ContentSection heeft één h2 en 2–5 alinea's. Altijd wit in blogart ikelen.
import ContentSection from
'../../components/content/ContentSection.astro'
<ContentSection size="800">
## Section heading
Paragraaftekst...
</ContentSection>
/* Props */
size: "800" | "992"
sectionClass: nooit gebruiken in blog
containerClass: optioneel, bv. "pb-10" Tip van Tai card
Tip van Tai:
Concrete actie, altijd gericht op wat de lezer direct kan toepassen.
- Eerste actiepunt
- Tweede actiepunt
- Derde actiepunt
<div class="grid grid-cols-[100%]
gap-2 card-base card-stack">
<div class="p-6">
<h3 class="text-xl pt-1 pb-2
inline-block border-bottom-gradient">
Tip van Tai:
</h3>
<p class="leading-8">Tekst...</p>
<ul class="list-disc pl-6 mt-2
text-[color:var(--color-text-label)]">
<li class="pb-1">Punt</li>
</ul>
</div>
</div> BackLink & FigureGrid
BackLink
← Terug naar blogFigureGrid columns={3}
import BackLink from
'../../components/content/BackLink.astro'
import FigureGrid from
'../../components/content/FigureGrid.astro'
<!-- Altijd laatste element in artikel -->
<BackLink />
<!-- Responsive afbeeldingsgrid -->
<FigureGrid columns={2}>
<div class="overflow-hidden rounded-lg">
<img src="/img.png" alt="Beschrijving" />
</div>
</FigureGrid>
/* columns: 1 | 2 | 3 */ 7. Animaties & motion
Alle transities zijn 150–200ms met ease-out of ease-in-out.
Nooit transition: all — altijd specifieke properties benoemen.
.fade-in
Scroll-triggered entry
- blur(6px) → 0
- scale(0.98) → 1
- translateY(50px) → 0
- opacity 0 → 1
- 600ms ease-out
.card-interactive:hover
Kaartlift bij hover
- translateY(-0.125rem)
- shadow increase
- heading underline groeit
- 200ms ease-out
.btn-primary:hover
Knop inversie
- bg: white
- text: primary blue
- border: 1px solid blue
- 150ms ease-in-out
.nav-shrink
Nav krimpt bij scrollen
- trigger: scrollY > 30px
- class op nav element
- padding reduceert
page loader
Progress bar navigatie
- fixed top · 3px hoogte
- easing animatie
- MIN_VISIBLE: 850ms
hero typing
Roterende zinnen
- type: 62ms/char
- delete: 40ms/char
- pause: 2600ms
- blinking cursor
Code
<!-- Scroll fade-in -->
<div class="fade-in">
<!-- JS voegt .is-visible toe via IntersectionObserver -->
</div>
<!-- Interactieve kaart -->
<a class="card-base card-interactive group" href="...">
<h3 class="card-title">...</h3>
</a>
/* Altijd specifieke properties in transition */
transition: transform 200ms ease-out,
box-shadow 200ms ease-out;
/* Nooit: transition: all */