Kaniworks Design Guide
The system this site runs on.
Every color, size, component and rule below is the live one: the samples are rendered with the same code as the pages. This is what a design-systems engagement from the studio leaves behind, in your product instead of ours.
Generated when the site was built, 2026-10-05, from src/app/globals.css, src/components/demo-kit.tsx, src/components/ProductLogo.tsx: 8 tokens, 12 animations, 6 status tones, 13 product tiles. If the CSS changes, this page changes with it.
01
Four principles.
They decide every choice below. When two options look equally good, the principle picks.
Built for people standing up
Gloves on, in a hurry, often with no internet. Big targets, few words, nothing that needs a second look.
One accent
Blue is the only color that means something. Red is reserved for alarms and blocks, so it is never decoration.
Honest states
Every number has a label, every product has its stage, every pill says what is true right now.
Motion explains
Animation is used to show how something works, never to decorate. If it stops, the meaning must survive.
02
Color.
8 tokens, read from the :root block of globals.css and exposed to Tailwind through @theme. Contrast is measured against white; AA needs 4.5:1 for text and 3:1 for large text.
--bg
#ffffff
Page background.
--bg-soft
#f5f5f7
Cards, alternating sections, quiet panels.
1.1:1 on white · decorative only
--ink
#1d1d1f
Headings, body text, dark panels.
16.8:1 on white · AA text
--gray
#6e6e73
Secondary text and descriptions.
5.1:1 on white · AA text
--gray-light
#86868b
Captions and labels at 12 to 13 px. Never body text.
3.6:1 on white · AA large only
--blue
#1450f5
The one accent: links, buttons, eyebrows, live state.
6:1 on white · AA text
--blue-dark
#0f3fcc
Button hover.
8.1:1 on white · AA text
--ok
#30b45c
Healthy, live, done.
2.7:1 on white · decorative only
Status tones
03
Type.
One family, Geist, loaded from next/font with a system fallback. From globals.css: .headline is letter-spacing: -0.025em · font-weight: 600 · line-height: 1.05; .eyebrow is font-size: 14px · font-weight: 600 · letter-spacing: 0.01em. Sizes are pixels, never rems you have to convert.
Display
clamp(2.6rem, 6vw, 4.4rem) · 600 · -0.025em · 1.05
A senior designer on your team within a week.
Section heading
clamp(2rem, 4.5vw, 3.4rem) · 600
Pick the shape. Prices are up front.
Card title
19 px · 600
Industrial integration
Lead
19 to 21 px · 400 · 1.625
Cover an open UX role while you hire, or hand us a defined piece of design work.
Body
15 px · 400 · 1.625
Every price is a starting point in US dollars, confirmed in a written scope before anything starts.
Small
14 px · 400 · 1.625
The work is in your Figma every day, the designer is in your standups.
Caption
12 to 13 px · 500
In production · one client site
Eyebrow
14 px · 600 · 0.01em
Kaniworks Design Studio
04
Layout and shape.
A 1152 px container for pages, 1024 px for reading. Sections breathe at 96 to 128 px. Corners are generous and consistent, shadows are soft and only on floating things.
Containers and rhythm
- Page container
max-w-6xl(1152 px) · reading columnmax-w-5xlormax-w-3xl. - Section padding
py-24 md:py-32· tight sectionspy-16. - Card grid gap
gap-4(16 px) · card paddingp-7(28 px). - Side gutter
px-6(24 px) on every screen; nothing touches the edge. - Sticky nav 48 px; anchored sections use
scroll-mt-12.
Radius
28 px
24 px
16 px
12 px
full
rounded-[28px]Large panels and gallery cardsrounded-[24px]Standard cardsrounded-2xlDemo shells, FAQ rowsrounded-xlInner tiles inside a demorounded-fullButtons, pills, chips
Shadows: 0 28px 60px -24px rgba(0,0,0,.35) on demo shells and floating cards only. Flat cards have no shadow.
05
Components.
Rendered with the real classes. Copy the markup, not a screenshot.
Buttons and links
One primary per view. Secondary is white with a hairline border. Text links end with a chevron.
Status pills
Uppercase, 10 px, 600. The pill says the state in one word and changes color with it.
Chips
For lists of audiences or situations. White on soft, never clickable-looking unless they are.
Card
Serial-linked inventory
Each device is tracked by serial number from purchase to installation.
Icon, title, one or two sentences. On a soft section the card is white; on a white section it is soft.
Disclosure
Does it work on phones?
Yes. It runs in the browser and is designed for field use.
Can we set our own approval limits?
Yes. Approval rules are configured per company.
Native details and summary, so it works without JavaScript and reads to screen readers.
Steps
Understand
One sentence on what happens here.
Start small
One sentence on what happens here.
Go live
One sentence on what happens here.
Run it
One sentence on what happens here.
Product tiles
13 products, each a 100-unit tile with a 24-unit corner, one flat color and one white glyph, drawn as SVG so it is sharp at 26 px and at 560 px. Read from ProductLogo.tsx.
Demo shell
Design Studio · one engagement
RESEARCHResearch: eight interviews, one wall of notes
300 px wide, white, 16 px corners. Title and state pill on top, a caption bar with act dots at the bottom. Four acts, then it loops.
06
Motion.
One easing for entrances, one cadence for demos, and a rule for people who turn motion off.
Reveal
opacity 0→1, y 24→0, 0.8 s, ease [0.16, 1, 0.3, 1], once, when 60 px into view
Demo act
2.6 to 3.4 s per act, four acts, captions swap in 0.3 s
Count-up
numbers tick, never jump; 6 to 600 ms per step
Cursor
a drawn pointer moves to the control it clicks, 0.7 s
Reduced motion
every demo shows a chosen static act; ambient loops stop
Off screen
a demo pauses when less than 30% of it is visible
Named animations in globals.css
| Class | Keyframes | Duration | Timing | Repeats | Reduced motion |
|---|---|---|---|---|---|
| .pulse-dot | pulseDot | 2.4s | ease-in-out | infinite | stops |
| .alarm-pulse | alarmPulse | 1.3s | ease-in-out | infinite | stops |
| .scan-ring | scanSweep | 3.5s | linear | infinite | stops |
| .float-soft | floatSoft | 7s | ease-in-out | infinite | stops |
| .scan-beam | scanBeam | 2.6s | ease-in-out | infinite | stops |
| .ring-pulse | ringPulse | 2.2s | ease-out | infinite | stops |
| .elevator-dot | elevatorY | 4.5s | ease-in-out | infinite | stops |
| .smoke-puff | smokeRise | 3.2s | ease-out | infinite | stops |
| .walk-a | walkA | 6s | ease-in-out | infinite | stops |
| .walk-b | walkB | 4.6s | ease-in-out | infinite | stops |
| .dash-flow | dashFlow | 1.4s | linear | infinite | stops |
| .caret-blink | caretBlink | 1s | step-end | infinite | stops |
All 12 stop under prefers-reduced-motion.
07
Logo.
A blue tile with a white K, and the wordmark in Geist Bold converted to outlines. The pack holds every version as SVG and transparent PNG.
Rules
- Clear space of half the mark’s width on every side.
- Smallest size 120 px wide on screen, 30 mm in print; below that, the mark alone.
- On dark or busy backgrounds use the white version; the tile stays blue only on light.
- Never stretch, recolor, outline, rotate or add a shadow. Never retype the wordmark.
Files
Horizontal, stacked and mark only; color, white and one-color black; SVG and PNG at 256 to 2048 px.
Download the logo pack08
Voice.
Warm, plain, confident about facts. Written to be read on a phone by someone busy.
Headings are short statements with a full stop.
DoWe build yours, too.
NotOur Services & Solutions
No em dashes. Use a colon, a comma or a full stop.
DoRead-only by architecture: it can watch a panel but never change it.
NotRead-only — by architecture — it can never change a panel
No defensive words. Say the fact, not the fear.
DoSoftware in production at a client gate.
NotReal software for real businesses
One plain sentence per list item.
DoMonth to month, 30 days' notice.
NotFlexible, risk-free, month-to-month engagement models tailored to your needs
Honest stage on everything.
DoInteractive prototype · pilot schools welcome
NotTrusted by schools everywhere
US spelling, numerals for numbers, no hollow words.
DoColor, organize, 0.8 seconds.
NotSeamless, world-class, cutting-edge
09
For engineers.
Where each piece lives. The token block, the animation table, the status tones and the product tiles on this page are read from the source files when the site is built, so they cannot drift.
Tokens
:root {
--bg: #ffffff;
--bg-soft: #f5f5f7;
--ink: #1d1d1f;
--gray: #6e6e73;
--gray-light: #86868b;
--blue: #1450f5;
--blue-dark: #0f3fcc;
--ok: #30b45c;
}
@theme inline {
--color-bg: var(--bg);
--color-bg-soft: var(--bg-soft);
--color-ink: var(--ink);
--color-gray: var(--gray);
--color-gray-light: var(--gray-light);
--color-blue: var(--blue);
--color-ok: var(--ok);
--font-sans: var(--font-geist);
}Verbatim from globals.css. Utilities each token gives you:
- --color-bg → bg-bg, text-bg, border-bg
- --color-bg-soft → bg-bg-soft, text-bg-soft, border-bg-soft
- --color-ink → bg-ink, text-ink, border-ink
- --color-gray → bg-gray, text-gray, border-gray
- --color-gray-light → bg-gray-light, text-gray-light, border-gray-light
- --color-blue → bg-blue, text-blue, border-blue
- --color-ok → bg-ok, text-ok, border-ok
- --font-sans → font-sans
Files
src/app/globals.csstokens, type helpers, named animations, reduced-motion rules.src/components/demo-kit.tsxDemoShell, usePhases, Swap, Cursor, PlayWhenVisible.src/components/Reveal.tsxthe one entrance animation.src/components/ProductLogo.tsxevery product tile as SVG.src/components/Logo.tsxandbrand/the mark, the wordmark outlines and the pack.src/lib/*.tsall copy as data; pages render it and never hard-code words.
Stack: Next.js App Router, Tailwind v4 with the tokens above, Framer Motion for reveals and demos, lucide icons at 1.5 px stroke.
Want one of these for your product?
A design system engagement leaves your team with tokens, components and a guide like this one, in your codebase.