Adopt the shared design token contract

Replace the stock shadcn OKLCH neutral palette (whose teal --primary had no
relation to the brand) with the fluksio token block duplicated verbatim from
the root DESIGN-GUIDELINES.md, add the self-hosted Inter variable face, the
shared lib/motion.ts presets, a DESIGN.md pointer stub and the
no-arbitrary-font-size hook.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Melvin Strobl
2026-08-09 15:24:50 +02:00
co-authored by Claude Opus 5
parent 529b5f9ed5
commit bd2155603e
5 changed files with 216 additions and 73 deletions
+70
View File
@@ -0,0 +1,70 @@
/**
* Shared motion presets (Fluksio design system).
*
* Pure data: variants and transitions consumed by `motion/react` components
* across the app. Mirrors the `--ease-*` / `--duration-*` timing tokens defined
* in `index.css`, so CSS transitions and JS animations stay in sync.
*
* This file is duplicated verbatim in `fluksio` and `website` (the shadcn model,
* see ../../DESIGN.md / the root DESIGN-GUIDELINES.md). Keep the two copies
* identical; `make design-check` at the workspace root verifies it.
*
* Reduced motion: wrap each app root in `<MotionConfig reducedMotion="user">` so
* transform/layout animations are disabled automatically when the OS requests it.
*/
import type { Transition, Variants } from "motion/react"
/** Easing curves, mirroring the `--ease-*` tokens. */
export const easeEmphasized: [number, number, number, number] = [0.2, 0, 0, 1]
export const easeStandard: [number, number, number, number] = [0.4, 0, 0.2, 1]
/** Durations in seconds, mirroring the `--duration-*` tokens (ms). */
export const duration = { fast: 0.15, base: 0.2, slow: 0.3 } as const
export const transitions = {
/** Enter / expressive moves (decelerate). */
emphasized: { duration: duration.base, ease: easeEmphasized },
/** Neutral state changes. */
standard: { duration: duration.base, ease: easeStandard },
/** Springy, for hover tilt / direct-manipulation feedback. */
spring: { type: "spring", stiffness: 250, damping: 20, mass: 0.5 },
} satisfies Record<string, Transition>
const exitFast: Transition = { duration: duration.fast, ease: easeStandard }
/** Opacity fade. */
export const fadeIn: Variants = {
hidden: { opacity: 0 },
visible: { opacity: 1, transition: transitions.standard },
exit: { opacity: 0, transition: exitFast },
}
/** Fade + subtle scale: popovers, dialogs, floating panels. */
export const scaleIn: Variants = {
hidden: { opacity: 0, scale: 0.96 },
visible: { opacity: 1, scale: 1, transition: transitions.emphasized },
exit: { opacity: 0, scale: 0.96, transition: exitFast },
}
/** Fade + rise: list/grid items, toolbars, content blocks. */
export const slideUp: Variants = {
hidden: { opacity: 0, y: 8 },
visible: { opacity: 1, y: 0, transition: transitions.emphasized },
exit: { opacity: 0, y: 8, transition: exitFast },
}
/** Dialog / drawer scrim. */
export const overlayFade: Variants = {
hidden: { opacity: 0 },
visible: { opacity: 1, transition: exitFast },
exit: { opacity: 0, transition: exitFast },
}
/**
* Stagger container for lists/grids. Children animate with `slideUp` / `fadeIn`
* via `variants` inheritance (set the same `initial`/`animate` state names).
*/
export const listStagger: Variants = {
hidden: {},
visible: { transition: { staggerChildren: 0.05, delayChildren: 0.02 } },
}