Kelas Sekejap — Design System
Say it with confidence · v7 — the brand & UI system for an AI-native spoken-English app for Malaysian students.
Bold, editorial, zine-like — student posters and sticker cut-outs, not generic edtech. Confident enough for SPM exams, expressive enough for teenagers. We lead with type, keep learning calm, and save the loudest treatments for marketing and reward moments.
Using this with Claude Design
This repo is structured for the "Create using Claude Code" flow (best fidelity). Point Claude Code at this folder and it will read:
tokens.json/src/styles/tokens.css— the token source of truth (colour, type, spacing, radii, shadows, states).src/components/*.tsx— real React components that show how tokens compose into brand-correct UI.- This README — brand personality and the do/don't rules.
Everything visual derives from the tokens — there are no hardcoded hex values inside components.
Run the living gallery
npm install
npm run dev
src/App.tsx renders a preview of every component (cover, colour, buttons, tags, progress, inputs, feedback ladder, record button, phone frame).
Foundations
The full designer-facing guidance — type scale, spacing & breakpoints, shape & elevation, component-states matrix, accessibility / WCAG contrast, motion, iconography, and voice & tone — is documented in FOUNDATIONS.md. The essentials:
Colour
Named colour blocks are a confident set — each colour has a role, never a random accent.
Primary — recognition & behaviour
| Token | Hex | Text | Role |
|---|---|---|---|
| Haze | #EFEBE1 |
Ink | Warm neutral base / default background — keeps learning calm |
| Electric blue | #2557FF |
White | Loud brand anchor / hero / SPM recognition |
| Flame | #E64C09 |
Ink | The action colour — one primary CTA per view. Ink text (A1); white icons ok |
Secondary — content, rewards, states
| Token | Hex | Text | Role |
|---|---|---|---|
| Sunflower | #F0C84B |
Ink | Highlights & reward moments |
| Pulse | #F49EAF |
Ink | Social, warmth, campaign emphasis |
| Moss | #2FA36B |
Ink | Progress, growth, support. Ink text; white icons ok |
| Spark | #F68868 |
Ink | Celebrations, friendly alerts |
| Paper | #FFFFFF |
Ink | Cards, modals, content surfaces |
| Ink | #101014 |
White | Text, outlines, icons, contrast |
Typography — three families, three jobs
- Archivo Black — display / headlines. Uppercase, stacked, very tight. Tracking −0.065 to −0.085em · leading 0.8–0.86 · 56–96px.
- Plus Jakarta Sans — body & UI. Runs heavy — weights 700 / 800 / 900.
- JetBrains Mono — eyebrow labels, sticker tags, tokens. Uppercase, tracking 0.06–0.1em, weight 800.
Spacing — 4px base scale
space-1…10 = 4 · 8 · 12 · 16 · 20 · 24 · 32 · 40 · 48 · 64 px. Use tokens, not arbitrary values.
Radii, borders & elevation
Generous radii + a firm 2px Ink outline + a hard offset shadow (never blur) = the sticker cut-out feel.
- Radii:
md 20(chips) ·lg 28(cards) ·xl 36(hero) ·pill 999(buttons/tags). - Shadows:
8px 8px 0 Ink(cards) ·5px 5px 0 Ink(buttons/pills/tags). - Soft blur (
0 22px 60px) is marketing/hero only — never inside learning UI.
States (apply to buttons, inputs, interactive cards)
- Pressed —
translate(5px,5px), shadow removed (a physical push into the shadow). - Hover (web) —
translate(-2px,-2px), shadow grows to7px 7px 0. - Focus — visible Blue ring offset by Haze.
- Disabled — fill
#DEDBD3, text 45%, border 18%, no shadow. - Error —
rgba(230,76,9,.1)surface, 2px Flame border, Ink text.
Iconography
Lucide React only — never emoji, never mascots. Stroke-based, stroke-width 2 to match the Ink outline, rounded linecaps. Sizes 16 / 20 / 24. Ink by default; white on dark fills.
Components
Grouped under src/components/<group>/ to mirror the Claude Design project.
- core —
Button·Card+Eyebrow·StickerTag·SectionHeader·Badge·Toggle·DoodleAccent - forms —
Input - feedback —
ProgressBar·StepDots·Alert·Skeleton·FeedbackPanel·Toast·EmptyState - overlay —
Modal·Drawer - learning —
LessonTile·PhraseCard·CompletionCard·ListeningPlayer - spm —
Paper3TaskCard·BandBadge(+BANDS) ·RubricSummary - rewards —
StreakPill·QuestCard·RewardCard - app —
PhoneFrame·RecordButton·TabBar - marketing —
PosterCard - expression —
Expression(+EXPRESSIONS) — the eight branded faces
import { Card, StickerTag, Button } from 'ks-design-system';
<Card tone="blue" hero>
<StickerTag tone="flame">Say it with confidence · v7</StickerTag>
<Button variant="flame" block>Start speaking</Button>
</Card>
The emoji-rule exception
The no-emoji / no-mascot rule still holds. The one sanctioned exception is the branded Expression set (components/expression/) — eight simple faces for supportive moments only (feedback, empty states, rewards, completion). Use them sparingly: at most one per view, always secondary to the action, never a functional icon and never a mascot. No third-party emoji anywhere.
Usage rules
Do
- Use named colour blocks as a confident set — each colour has a role.
- Build type-first: stacked Archivo Black headline → mono label → then illustration.
- Keep the product calm — loud treatments only for marketing and hero moments.
- Use fluid, organic shapes — blobs, ovals, sticker cut-outs.
- One Flame primary CTA per view; everything else Paper or Haze.
- Lucide icons, 2px stroke, matching the Ink outline weight.
Don't
- Scatter colours as random accents with no role.
- Lead with illustration or decoration before the type does its job.
- Make learning UI shout — save the volume for covers and rewards.
- Use emoji or mascots — Lucide icons only, no characters (the branded
Expressionset is the one sanctioned exception; see above). - Stack multiple loud CTAs competing in one view.
- Use soft blur shadows inside the product, or rigid geometric shapes.
Kelas Sekejap · Say it with confidence v7 · design system guide