Design System

Work in progress. I'm adding components as I go, following patterns from what's already documented. Nothing here is set in stone yet.

Animations

anime.js timelines triggered by IntersectionObserver or the event bus. Elastic easing, staggered entrances.

RevealText

Atom

Composable text reveal that self-animates when its trigger event fires.

Wave (default)

Expériences
<RevealText text="Expériences" trigger="my-event" />

Slide

Mes projets

<RevealText text="Mes projets" as="h2" animation="slide" trigger="my-event" />

Props

PropTypeDefaultDescription
text string required Text content to reveal
as string "span" HTML tag to render
animation "wave" | "slide" "wave" Animation variant
trigger string - Event name that starts the animation
class string - CSS class forwarded to the root element

Header Animation

Foundation

Staggered entrance for header elements. Title, nav items, and menu slide up with elastic easing.

Preview

kinoo.dev Expériences Formations Réalisations Discutons ensemble

Timeline

TargetPropertyValueTiming
.title-wrapper translateY -1.2em → 0 delay: 0
.navbar li translateY -1.2em → 0 stagger: 30ms
.header-menu opacity 0 → 1 with translateY

Easing: outElastic(1, .5) · Duration: 800ms · Triggered after hero or immediately on non-hero pages.

Usage

import { animateHeader } from "@/lib/animations/headerAnime";

animateHeader();
animateHeader({ delay: 300 });

Section Reveal

Foundation

IntersectionObserver-based fade-in for page sections. Fires a reveal event per section so child components can react.

Preview

Section content

Behavior

PropertyValue
Trigger IntersectionObserver (10% threshold)
translateY 20px → 0
opacity 0 → 1
Duration 600ms
Root margin (mobile) 0px 0px 50px 0px
Root margin (desktop) 0px 0px -100px 0px

Each revealed section emits reveal:section:{id} via the event bus, letting child components (RevealText, tags) animate in response.

Usage

import { revealSections } from "@/lib/animations/revealSection";

const cleanup = revealSections();

// Mark sections in markup:
<section id="experiences" data-animate-section>...</section>

Card Reveal

Foundation

IntersectionObserver-based card entrance with scale and staggered children. Adapts to mobile.

Preview

Title Description Tags

Desktop Timeline

StepTargetPropertiesTiming
1 Card opacity 0→1, translateY 50→0, scale 0.8→1 600ms elastic
2 [data-animate-elem] opacity 0→1, translateX -20→0 800ms stagger 200ms

Mobile Timeline

StepTargetPropertiesTiming
1 Card opacity 0→1, translateY 20→0 500ms cubic
2 [data-animate-elem] opacity 0→1, translateY 10→0 400ms stagger 80ms

Mobile breakpoint: 900px. Cards in viewport on load are triggered immediately to handle tall elements that don't meet the 10% threshold.

Usage

import { revealCards } from "@/lib/animations/revealCard";

const cleanup = revealCards();

// Mark cards and their animated children:
<div data-animate-card>
  <h3 data-animate-elem>Title</h3>
  <p data-animate-elem>Content</p>
</div>

kinoo.dev · Design System