Navid Moazzez brand & design system
The complete design language for navid.me: logos, photos, bios, colors, gradients, type, spacing, surfaces, icons and motion.
Use them for press, podcasts, partner materials, or for building anything that should feel like this site. Also published as design.md for agents and LLMs.

The design system behind navid.me
navid.me is where Navid Moazzez teaches creators and founders to master AI and build their own AI Operating System (AI OS). Every page on the site, from the home page to the articles and this one, is built from the one design system documented here.
Principles
4 rulesThe avatar is the one motif, and it always means Navid.
Navid's avatar sits in the mark and on every official account and site, so people see the same face wherever they meet him. It stands for Navid and is never used as decoration.
The site is built dark first, and light mode is designed rather than inverted.
Light mode has its own card backgrounds, borders and shadows instead of the dark values flipped, so a page reads as intended in whichever theme a visitor chooses.
Surfaces are glass on black, separated by light instead of color.
A card is a translucent panel with a hairline border and a soft shadow. Color is never used to fake elevation, so the accents stay free to mean something.
Every word is written to be understood on the first read.
Copy uses full sentences, digits instead of spelled-out numbers and American English, and it never uses em dashes. A number or a name always beats an adjective.
Surfaces
Where the system appliesOne set of tokens in src/app/globals.css styles every page on navid.me. Words come from the CMS in HQ and images from R2 on cdn.navid.me, so the layout changes with the page type while the vocabulary stays the same.
Core pages
Core pages are standalone pages, each built around one topic, such as the home page, the About page and the Speaking page.
Hubs
Hubs have a left rail of sections, a search bar with filters and an FAQ at the end, so a long list stays easy to scan.
Articles
Articles use a reading column with 18px body text, 16px on phones, and set quotes in the site's highlight card, because they are written to be read from top to bottom.
The navid.me mark
The navid.me mark is the full logo, the round avatar with the navid m wordmark and its blue dot over the i, in light, dark and monochrome versions, plus the favicon. Use the supplied files as they are, without retyping the name, swapping the avatar or adding effects.
Primary marks
5 files
Monochrome logo, light
Grayscale version for dark backgrounds. Use for co-branding, watermarks, or anywhere the full-color logo would compete with surrounding content.
Monochrome logo, dark
Grayscale version for light backgrounds. For print, documents, and light-colored surfaces.
Use the official logo
Source and downloadsThe avatar and the navid m wordmark are one fixed logo file. Never rebuild it by retyping the name next to a photo, and never change the gap between them. Use the light file on dark backgrounds and the dark file on light backgrounds.
Clear space and sizing
ConstructionKeep clear space on every side of the logo, and scale it as one piece. Below 20px, use the favicon on its own.

The logos are published as SVG, PNG, WebP and JPG on cdn.navid.me, and the monochrome logos as SVG. The icon and the favicon are 512px squares, and the favicon is also published at 180px and 32px.
Usage
Do and don'tUse the file as supplied, on the background it was made for.
Do not stretch or squash the mark. Scale both sides together.
Do not add a shadow, glow, gradient or outline.
Do not rotate, skew or tilt the mark.
Do not recolor the mark or place it on a background that hides it.
Do not crop the logo or use part of it on its own.
Do not set the name in type and call it the mark.
One typeface, and a mono stack for values
Inter sets every heading, paragraph, label, button and quote on navid.me, so hierarchy comes from size and weight rather than a second typeface. The system mono stack shows tokens, hex values and class names.
Families
3 stacksEvery heading on navid.me, from the home page headline to the card titles, is Inter at 700 with tight tracking. There is no separate display font, so size and weight carry the hierarchy.
font-family: 'Inter', sans-serifweight: 700 · line-height: 1.08–1.2 · letter-spacing: -0.025emInter at 400 carries paragraphs and card copy, and 500 and 600 carry labels, navigation and buttons.
font-family: 'Inter', sans-serifThe system mono stack, with no web font loaded, shows tokens, hex values and class names, so a value someone might copy reads as a value.
--glass-border rgba(255, 255, 255, 0.08)
font-family: ui-monospace, 'SF Mono', Menlo, monospaceDisplay and body are the same Inter. Headings are set larger, bolder and tighter, and nothing on the site uses a second typeface.
Type ramp
9 rolesUse the role, not the size. Every size below was measured on the live navid.me pages at desktop width.
| Role | Sample | Spec |
|---|---|---|
| display-1 | Headline | clamp(34, 20px + 3.5vw, 56) · 700 · -0.025em |
| display-2 | Section heading | 42 · 700 |
| hub-title | Hub section title | 32 · 700 |
| card-title | Card title | 20 · 700 |
| card-title-sm | Hub card title | 16 · 700 |
| body | Body text runs at 18px on every page. | 18 / 29 · 400 |
| label | Buttons and filters | 14 · 500 |
| mono | --text-primary · #E8E8EC | 13 · ui-monospace |
| mono-sm | --glass-border · rgba(255,255,255,0.08) | 11 · ui-monospace |
Text size
phones read smallerText steps up once there is room for longer lines. Both sizes are set in the site's global styles.
| Where | Size |
|---|---|
| Body | 16px on phones, 18px from 768px |
| Articles | 18px, and 16px at 640px and below |
Pairing in practice
Light and darkType do & don't
RulesSet headings in sentence case at 700 with tight tracking, so the size and weight carry the hierarchy.
Never set a heading, pill or button in capitals. Uppercase is not part of the navid.me brand.
Use mono for tokens, hex values and class names, so a value someone might copy reads as a value.
Never use em dashes in copy. Split the thought into two sentences or use a comma instead.
A dark-first palette with color only where it means something
navid.me is near-black with light gray text, and color appears only where it carries meaning. Blue and purple carry the brand, green marks a real success state, and red marks a Don't. Components reference the token rather than the hex value, so both themes follow automatically. Click any swatch to copy its value.
Core
4 tokensGlass
4 tokensAccents
4 tokensApp chrome
4 tokensLight and dark
10 tokensEvery core token has a dark value and a light value in src/app/globals.css. Light mode uses its own values rather than inverting the dark ones.
| Token | Dark | Light | Used for |
|---|---|---|---|
| --bg-primary | #000000 | #F4F5F7 | Page background |
| --bg-section | #051823 | #EBEDF0 | Banded sections |
| --text-primary | #E8E8EC | #1A1A2E | Headings and body text |
| --text-secondary | #B0B0BC | #5A5A72 | Intros, captions and muted labels |
| --glass-bg | rgba(255,255,255,0.06) | rgba(255,255,255,0.65) | Card and panel surface |
| --glass-bg-hover | rgba(255,255,255,0.10) | rgba(255,255,255,0.80) | Surface on hover |
| --glass-border | rgba(255,255,255,0.08) | rgba(0,0,0,0.06) | Hairline borders |
| --glass-border-hover | rgba(255,255,255,0.15) | rgba(0,0,0,0.12) | Borders on hover |
| --input-border | rgba(255,255,255,0.15) | rgba(0,0,0,0.12) | Input borders |
| --nav-bg-scrolled | rgba(0,0,0,0.85) | rgba(255,255,255,0.85) | Nav background once the page scrolls |
Do
- Reference the token, so the color follows the theme.
- Use green only for a real state, such as live, verified or done.
Don't
- Do not hard-code a hex value in a component.
- Do not use an accent color as a large flat fill.
A 4px scale, set in steps
Every space on navid.me is a step on Tailwind's 4px scale, written as a class. Spacing changes at breakpoints instead of growing with the screen, because the only fluid values on the site are font sizes. Every class and count below was measured in the site's code on Sept 21, 2026.
The scale
4px base · 17 stepsTailwind's steps from 2px to 80px, each drawn at its real size. Uses counts every padding, margin and gap class on that step across the site. Steps used fewer than 40 times are left out, and the largest of those set the top padding of page heroes. Click a class to copy it.
| Class | Size | Drawn | Uses | Used for |
|---|---|---|---|---|
| 2px | 119 | A small caption or hint line under a title | ||
| 4px | 229 | An icon beside a text link, or inside a small badge | ||
| 6px | 321 | An icon beside its label, the most common inline gap | ||
| 8px | 605 | Items in a row, like buttons, icons and chips | ||
| 10px | 282 | Menu and filter rows, where py-2.5 pads each row | ||
| 12px | 613 | The most used step, for rows of cards, buttons and list items | ||
| 14px | 80 | Side padding in dropdown menu and filter items | ||
| 16px | 528 | Side padding in buttons, pills and table cells | ||
| 20px | 324 | Padding in callout boxes, lists and panels | ||
| 24px | 610 | The page gutter, and the padding inside glass cards | ||
| 28px | 87 | Padding inside drawers from 640px | ||
| 32px | 348 | The page gutter on tablets, and the space under section headings | ||
| 40px | 126 | The space between a section heading and its content | ||
| 48px | 87 | The bottom of a section | ||
| 56px | 43 | The bottom of a page hero | ||
| 64px | 49 | The top and bottom of a shorter section | ||
| 80px | 59 | The top and bottom of a standard section |
Vertical rhythm
2 patternsThe 2 ways a section opens on navid.me, drawn at real size. Each tinted band is a gap, labeled with the class that sets it.
Landing sections
Home and AboutA section heading
One or two sentences introduce what the section covers.
Long-form sections
AI, Now and How I use AIA section heading
One or two sentences introduce what the section covers.
Widths
11 widths in useEvery width a section is centered in, widest first and drawn to scale. The count is how many centered containers in the code use it. Most sections sit in 1100px, and text is kept narrower so lines stay easy to read.
Breakpoints
5 widthsThe widths where navid.me's layout changes, with how often each Tailwind prefix appears in the code. Pages are built phones first, and the full layout arrives at 1024px.
| Width | What changes |
|---|---|
640px · sm · 683 uses | The page gutter widens from 24 to 32px, page heroes get more top padding, and the floating nav grows from 52 to 58px. |
768px · md · 88 uses | Body text goes from 16 to 18px, the footer links open from a collapsed list into 2 columns, and the newsletter bar sits side by side. |
1024px · lg · 362 uses | The floating nav shows its full menu, the page gutter goes back to 24px, and articles with a table of contents gain a 260px side column. |
1100px · hub pages | The hub sidebar appears, and its collapse button replaces the drawer button in the top bar. |
1280px · xl · 18 uses | Hub article pages add the table of contents column, some card grids reach 4 columns, and the footer links spread into 1 row. |
Drag to change the screen width. Spacing on navid.me does not grow smoothly with the screen. The gutter and the hero padding switch at the 640px and 1024px breakpoints, and the content column stops growing at 1100px.
| What | Classes | At this width |
|---|---|---|
| Page gutter | px-6 sm:px-8 lg:px-6 | 24px |
| Page hero, top | pt-24 sm:pt-32 | 128px |
| Page hero, bottom | pb-14 | 56px |
| Standard section, top and bottom | py-20 | 80px |
Grids and cards
gaps by column countThe gap each card grid uses at its widest, counted in the code, and the padding inside the glass card. There is no single rule yet: 3-column grids use 4 different gaps, and gap-6 is the most common.
| Grid | Gap | Uses |
|---|---|---|
| 3 columns | gap-6 · 24px | 12 |
| 3 columns | gap-5 · 20px | 5 |
| 3 columns | gap-3 · 12px | 5 |
| 3 columns | gap-4 · 16px | 4 |
| 2 columns | gap-3 · 12px | 5 |
| 4 columns | gap-5 · 20px | 3 |
| Custom column layouts, like text beside an image | gap-8 to gap-12 · 32 to 48px | 31 |
| Glass card padding | p-5 or p-6 · 20 or 24px | 6 each |
Usage
rulesDo
- Pick a step from the scale and write it as a Tailwind class, like gap-3 or py-20.
- Give a standard section py-20 and the page gutter px-6 sm:px-8 lg:px-6.
- Center page sections in max-w-[1100px], the width most of the site uses.
- Space a 3-column card grid with gap-6, and pad each glass card with p-6.
Don't
- Don't write an arbitrary value like mt-[11px]. Use the nearest step instead.
- Don't set padding or margins in an inline style when a class can do it.
- Don't add a new container width. Use one from the Widths block.
- Don't give sections on the same page different paddings, like py-16 beside py-20.
Known gaps
measured Sept 21, 2026Where the code does not follow the scale yet. These are the numbers to bring down.
| Gap | Measured | What it means |
|---|---|---|
| No spacing tokens | 0 --space-* variables | Spacing lives only in Tailwind classes, so no single value can be changed across the site. |
| Inline style spacing | 1,066 values | Padding, margin and gap are set in style objects instead of classes. The most common are 0, 6, 8 and 2px. |
| Arbitrary values | 48 classes | Values between steps, like mt-[11px] and py-[7px]. |
| Half steps | 802 uses | The 2, 6, 10 and 14px steps sit off the 4px grid. gap-1.5 alone appears 164 times. |
| Near-identical widths | 1100, 1150 and 1152px | 3 section widths within 52px of each other do the same job on different pages. |
| Section padding | py-20 on 29, py-16 on 10 | There are 2 standard paddings, and 22 of the 172 sections set none on the section itself. |
| Grid gaps | 4 gaps on 3 columns | gap-3, gap-4, gap-5 and gap-6 all space 3-column grids. |
Five corners, and each one tells you what you are looking at
The corner tells you what kind of element you are looking at. Every value below was measured on the live navid.me pages.
Medium
Medium is 6px, used for the avatars inside testimonial cards, the icon buttons in the nav and menu items.
Large
Large is 8px, the corner of every testimonial card, product card, input and button.
Extra large
Extra large is 12px, used for the photo tiles on the home page and for forms.
2x large
2x large is 16px, used for the stat cards on the home page, such as 12+ years of experience.
Full
Full is fully round, used for pill badges, tags, filter buttons and avatars.
A few components still use one-off values such as rounded-[10px]. New work should pick a step from the ladder above.
Do
- Pick the radius by what the element is, such as rounded-lg for a card and rounded-full for a pill.
Don't
- Do not invent a new radius for a single component.
- Do not use square corners on a button or an input.
Depth is light, not color
Surfaces separate by blur and shadow, never by a brighter color, so the accents stay free to mean something. Every layer below is in use today, from the lowest to the highest.
Shadows
lowest to highestIn dark mode most cards rest with no shadow at all and lift on hover. Light mode adds a faint resting shadow so white cards do not melt into the page.
| Layer | Shadow | Used by |
|---|---|---|
| Resting card, light | 0 1px 3px rgba(16,24,40,.05) | Testimonial, FAQ and thank-you cards |
| Card on hover | 0 6px 20px rgba(16,24,40,.08) light, 0 10px 30px rgba(0,0,0,.45) dark | Testimonial, FAQ and quote cards |
| Glass stat card | 0 8px 32px rgba(0,0,0,.2) with 20px blur | Stat cards |
| Liquid glass card | Inset highlights and 0 8px 26px rgba(0,0,0,.3), 18px blur | Liquid glass cards |
| Popup | 0 8px 24px rgba(0,0,0,.25), nav menus 0 10px 30px rgba(0,0,0,.45) | Filters, menus and dropdowns |
| Drawer | 0 0 80px rgba(0,0,0,.3) with 40px blur | Tool, book and skill drawers |
| Search window | 0 32px 120px rgba(0,0,0,.6) | Hub search |
Blur
glass over the pageBlur is what makes a surface read as glass. These are the values that repeat.
| Blur | Where |
|---|---|
12px | Glass cards and the newsletter bar |
15px | The floating nav and hub top bar at rest |
40px | Drawers |
72px | The floating nav once you scroll |
Layers
what sits on top of whatThe stacking order, from the page up. A new layer takes its place in this list rather than a number of its own.
| Layer | z-index |
|---|---|
| Page sections and footer | 1 |
| Menus and dropdowns | 50 |
| Hub top bar | 60 |
| Modals | 400 to 700 |
| Mobile menu | 9997 to 9998 |
| Floating nav | 9999 |
| Drawers | 10000 to 10001 |
| Tooltips | 10100 |
| Quick search | 10200 |
Functional, not decorative
Icons come from lucide-react 1.x, one library, stroked the same way everywhere. They label an action, a section or a state, and they answer a hover with the same small pop the sidebar uses. The one exception is a platform, which gets its real logo.
Icon grid
Lucide · 24px · 2px strokeSizing
4 stepsEvery size keeps Lucide's 2px stroke on the 24 viewBox, so the line scales with the icon: 1px at 12px, 1.33px at 16px, 1.67px at 20px. One path, never redrawn per size.
Hover
6 stylesIcons move on hover in 6 ways, one per surface. Hover the icon in each row. In the sidebar the icon stays grey in every state, inactive, hovered and active; only the row around it changes, and on hover the icon pops.
Hover anywhere on this card
| Surface | Hover it | Spec |
|---|---|---|
| Sidebar, prompt cards, favorites | cs-rail-icon · 1 → 1.16 → 1.1 · lift 1.5px · 260ms | |
| Top nav menu rows | scale 1.1 · 200ms ease-out | |
| Stat cards | scale 1.1 · rotate 6° · 300ms ease-out | |
| Landing page features | spring · scale 1.1 · rotate -3° · 500 / 15 | |
| Arrows in links and buttons | 2px right · 200ms | |
| Outbound links | 2px right, 2px up · 200ms |
Do & don't
RulesStroke only, in currentColor, with rounded caps and joins. One icon then works in both themes.
No filled glyphs in the interface. A solid shape outweighs the label beside it and breaks the outline set.
A platform gets its real logo through PlatformIcon. It is the one filled mark allowed, because it is a logo, not an icon.
No emoji as an interface icon. Emoji is a different visual language, and here it only opens a pill.
Let the icon pop when its row or card is hovered. Hover this card to see it.
No looping or spinning icons. The only icon that turns is LoaderCircle, while something loads.
A hovered row gets the grey plate from cs-hover-surface. The text and the icon keep their color.
Never turn an icon or its row blue on hover. Blue is for links in body copy, not for navigation.
How a photo is handled
Every image on the site is cropped, cornered and hovered the same way, so a photo never arrives looking like it came from somewhere else.
Treatment
6| Treatment | Value | How it is used |
|---|---|---|
| Crop | object-cover | Photos fill their box. A portrait in a square box anchors to the top so the head is never cut. |
| Corner | rounded-lg | The same radius as every card. |
| Ratio | 4 / 5 · 1 / 1 | 4:5 in a photo grid, 1:1 for a cover or an avatar. |
| Hover | scale 1.10 over 700ms | The image zooms inside its box; the box itself does not move. |
| Bloom | inset 0 0 90px -20px | A brand-blue glow fades in over the image on hover. |
| Shine | 900ms sweep | A soft white diagonal crosses the image once on hover. |
Graphic generator
15 real backgroundsThe graphic generator puts together on-brand artwork from the backgrounds the sites really use. Every option below is one of them, copied from its source, never drawn fresh. Pick one, pick a size, and download the PNG.
Each background is named by its source under the preview. The PNG is painted from the same values as the preview.
Bio and social accounts
Copy the bio as written for an introduction, a speaker listing or a guest post, and link to the official accounts below.
Bio
Navid Moazzez is a leading AI business strategist, the founder of AI OS Lab, and the host of the AI Creator Summit, watched by 100,000+ creators. He helps creators and founders master AI and build their own AI Operating System (AI OS) to automate their business and life.
Press photos
19Crop them to fit your layout. Please do not add filters or change the colour grading.
How Navid writes
Navid writes in first person, with real numbers, and warmly, the way he would explain something to a friend who runs a business. The examples below come from his 2026 emails and videos.
Four pillars
First person · Real numbers · Warm · ClearFirst person
Posts and videos are written in Navid's own voice, as I and me, and he speaks to the reader directly.
“In this session, I will give you a complete overview of the best AI tools for creators.”
Real numbers
He writes the exact figure, such as 500+ tools or 20 hours a week, never a vague claim.
“I tested 500+ AI tools, these are the 30+ best AI tools for creators.”
Warm and personal
Emails switch to you, open with Hey and a first name, and end with a P.S. Exclamation marks and a friendly ellipsis are part of how he sounds.
“P.S. While you're emailing me back, feel free to let me know what your #1 question or challenge is when it comes to using AI in your creator business.”
Clear structure
Paragraphs are 1 or 2 sentences long. Hub pages follow the same plain structure Brian Dean uses on Backlinko: what it is, why it matters, then best practices.
What to avoid
RulesEm dashes. Navid does not use them.
Opening with "Most people...", which is a drafting-tool hook and not how he writes.
The "X isn't Y, it's Z" construction.
AI filler words such as align, effortless, optimize, breakthrough, delve and leverage.
Spelled-out numbers. Write 30 seconds, never thirty seconds.
British spellings, because navid.me is written in American English.
In practice
Rewrites“A revolutionary AI-powered writing workflow that dramatically boosts your productivity.”
“The AI writing system that saves me 20 hours every week.”
“I hope this email finds you well. Please confirm receipt of your order at your earliest convenience.”
“Can you do me a small favor: Will you hit 'reply' to this email and just let me know if you got it?”
“I reviewed a large number of AI tools and picked the very best ones for you.”
“I tested 500+ AI tools, these are the 30+ best AI tools for creators.”
Purposeful, never for show
Motion says something is live, or that something responded. Sections and cards fade up once as they arrive, one after another. Live things pulse. Rows and buttons answer in 150 to 200ms, card surfaces in 300ms. Nothing bounces, tilts or lifts.
Easings and durations
website · 3 easings · 5 durationsThe website's motion values, measured from every globals.css and the Tailwind classes the sites use, and kept in section 5 of tokens.css, synced into every site as src/styles/core-tokens.css. The sites still type most values where they're used; these tokens record them. The apps ship no --ease or --dur tokens: their motion lives in App Kit's named @keyframes instead (see below).
| Token | Value | Where |
|---|---|---|
| --ease-standard | ease | Card light, FAQ rows, theme swap |
| --ease-tailwind | cubic-bezier(0.4, 0, 0.2, 1) | Every Tailwind transition-* class |
| --ease-out | cubic-bezier(0, 0, 0.2, 1) | Tailwind ease-out |
| --dur-micro | 150ms | Tailwind's default: color shifts, button hover |
| --dur-hover | 200ms | duration-200: rows, links, icons |
| --dur-short | 250ms | FAQ rows |
| --dur-surface | 300ms | Card light, theme swap, image zoom |
| --dur-panel | 400ms | Card shadow, status bar fill |
| --rise | 20px | How far an entrance travels |
| --stagger | 60ms | The gap between items in a grid |
Website motion = keyframe classes. .cs-vbadge-sweep (3.4s, verified badges), .btn-sparkle (1.6s, sparkle buttons), .animate-marquee (60s) and .animate-marquee-slow (100s, 60s on phones, pauses on hover), lightbulbPulse (2.5s, thank-you pages), gradientShift (12s and 15s, hero glow), drift (stardust), terminalBorderSpin (4s, terminal cards), .cs-rail-icon-pop (260ms, rail icons), .animate-fade-in-up (400ms). All honor prefers-reduced-motion. Page-wide: the top bar creeps toward 90% while a page loads and finishes when it arrives (180ms ease-out), a second bar follows the scroll, and the scrollbar shows only while you scroll.
Product motion = App Kit keyframes, kept for states that need attention: ak-ai-dot-pulse (1.05s, AI thinking), ak-ai-typing-dots (1.4s, AI typing), ak-ai-skeleton-shimmer (1.4s, loading), ak-ai-progress-slide (1.1s, progress), connectors-activity-ring (1.8s) and connectors-activity-dot (0.9s, a connector running), usage-card-blink (1.8s) and usage-card-spin (12s, the usage card), token-burn-scan (2.8s, the token meter). All honor prefers-reduced-motion.
:root {
--ease-standard: ease; /* card light, FAQ rows, theme swap */
--ease-tailwind: cubic-bezier(0.4, 0, 0.2, 1); /* every Tailwind transition-* class */
--ease-out: cubic-bezier(0, 0, 0.2, 1); /* Tailwind ease-out */
--dur-micro: 150ms; /* Tailwind's default: color shifts, button hover */
--dur-hover: 200ms; /* duration-200: rows, links, icons */
--dur-short: 250ms; /* .faq-item */
--dur-surface: 300ms; /* card light, theme swap, image zoom */
--dur-panel: 400ms; /* card shadow, status bar fill */
--rise: 20px; /* how far an entrance travels */
--stagger: 60ms; /* the gap between items in a grid */
}Reusable patterns
22 · every one the real thing1.8s cubic-bezier(0.4, 0, 0.2, 1) · infinite · 2 rings, 0.9s apart · live indicators
1.6s ease-in-out · fades to 40% and shrinks to 0.6 · loops
3.4s ease-in-out · a glint sweeps the verified badge, then rests · loops
1.6s linear · a line runs around the button's edge · loops
12s and 15s ease-in-out · the hero's 2 glows drift and swell · loops
30 specks rise and fade behind the page heroes · loops
Trusted by creators & founders from ambitious brands

























































100s linear, 60s on phones · pauses on hover · loops
drifts 0.35px a frame · drag it to scroll · loops
the top row drifts left, the bottom right · drag either · loops
the speaker grid from the summit call to action

Claude Code Starter Kit
Learn how to use Claude Code to build and grow your online business. From first setup to advanced workflows.

AI Tools Guide
Access a curated list of the best AI tools for creators and solopreneurs, organized by category.

Video Gear Guide
The ultimate video gear guide for creators. 60+ products across cameras, lenses, audio, lighting, and more — honestly reviewed.
each card rises 16px and fades in over 0.4s ease-out, 60ms after the one before · once · the resources page
Headlines fade in.
opacity over 0.8s · rise 20 → 0 on a spring · once, the first time it scrolls into view
rows arrive 90ms apart over 380ms · each check pops in over 260ms · once
150ms · scale 1.02 and brighter · no bounce
300ms ease · background, border and shadow · no lift

300ms · the image grows to 1.05 inside its frame
260ms ease · the icon lifts 1.5px and grows to 1.16, then settles at 1.1
slides in from the right on a spring · damping 30, stiffness 300
1s linear · the one loop reduced motion keeps
300ms ease · background and text crossfade across the page
2s ease-out · counts up once, the first time it scrolls into view
You can download every version of the logo from the Logo section of this page, including SVG and monochrome files. The logos are published as SVG, PNG, WebP and JPG on cdn.navid.me.
Use the light version on dark backgrounds and the dark version on light backgrounds. The Logo section shows each one on the background it was made for.
No, please use the logo exactly as supplied. Do not recolor, stretch, rotate or crop it, and do not add a shadow, glow or outline.
a row opens and closes over 250ms ease
Reduced motion
always respectedSome people get dizzy or sick from movement on screen, so their device asks for less. When it does, every animation on every site finishes at once and a hover becomes a quick fade. A spinner keeps turning, because it says the page is still working.
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 100ms !important;
scroll-behavior: auto !important;
}
.animate-spin, [data-motion="essential"] {
animation-duration: 1s !important;
animation-iteration-count: infinite !important;
}
}<MotionConfig reducedMotion="user">{children}</MotionConfig>| Line | What it does |
|---|---|
| @media (prefers-reduced-motion: reduce) | Applies only when the visitor turned on Reduce motion in their device settings. |
| animation-duration: 0.01ms | Every animation finishes at once, so things appear already in place. |
| animation-iteration-count: 1 | Loops stop after that one instant run: marquees, pulses, shimmer and sweeps. |
| transition-duration: 100ms | A hover still answers, as a quick color fade instead of a slide or a grow. |
| scroll-behavior: auto | Rail links jump straight to their section instead of gliding. |
| .animate-spin, [data-motion="essential"] | The exception. A spinner keeps turning, and anything marked essential keeps its motion. |
| <MotionConfig reducedMotion="user"> | framer-motion animates with inline styles the CSS can't reach. This makes it read the same setting: fades still play, nothing travels or scales. |
Reusable UI elements
The site is assembled from a fixed set. A new page composes them; it does not write its own card.
There are 5 button treatments, and all of them use rounded-lg. Solid is the one main action on a screen, and outline is for everything beside it. Gradient is for an offer, sparkle adds a line of light that travels the border on hover, and the avatar button carries Navid's face, with the mail badge sliding out on hover. No button moves on hover, because the fill brightens and the shadow deepens instead.
Touch targets
today's sizesThe tap areas the site's small controls have today. The common guideline is 44px, and none of these reach it yet.
| Control | Size |
|---|---|
| Mobile menu button | 32px |
| Search button | 36px |
| Hub top bar buttons | 30 to 32px |
Links
9| Class | Example | Where the site uses it |
|---|---|---|
| Body link | free valuable resources | components/home-page.tsx:557 |
| Nav link | components/shared.tsx:168 | |
| Dropdown item | components/shared.tsx:128 | |
| Nav button | components/hub-site/hub-actions.tsx:102 | |
| Gradient link | Learn more about Navid | components/site-footer.tsx:269 |
| Footer link | Now | components/site-footer.tsx:114 |
| Breadcrumb | components/article-detail-page.tsx:108 | |
| Article card pill | AI | components/articles-page.tsx:198 |
| Article page pill | AI | components/article-detail-page.tsx:89 |
Cards
7

1of10
PaidFinds viral YouTube video ideas by tracking high-performing videos in your niche.


1of10
PaidFinds viral YouTube video ideas by tracking high-performing videos in your niche.
Discipline beats motivation. Show up daily, do the work, and the results will follow.
Discipline beats motivation. Show up daily, do the work, and the results will follow.
Pills and badges
8 shapesHubRail search
components/hub-rail/HubRail.tsx:240ThemeToggle
components/shared.tsx:39Testimonials
83Lists and callouts
2 boxesTables
1 table| Token | Value | Where it is used |
|---|---|---|
| --bg-primary | #000000 | The page background |
| --text-primary | #E8E8EC | Headings and body text |
| --glass-border | rgba(255,255,255,0.08) | Every hairline border |
Connectors feed
app-kit · data/connectors-activityHQ's connectors feed. Each tool's action streams in, runs, and checks off.
Usage card
app-kit · data/usage-cardThe Claude Code usage card from aios.guide. The counts run up and the heatmap floods in, row by row, when it scrolls into view.
Accordion
3 of this page's questionsAlso in the system
6Shell
The railed hub, mounted once in a segment layout so the rail survives navigation.
Surface
One card, on every page.
Search
The search row with the filter built in, choices shown back as dismissible chips.
Overlays
One drawer family. A card opens the drawer for its own type.
FAQ
The accordion, in a 700px column.
Close
The newsletter block every page ends on.
Every navigation the sites and apps use, one row per design. Below the table are the 2 that live in navid.me, as the real components in this page's theme: the floating nav, with its at rest and scrolled states, and the hub top bar. The hub sidebar is live to the left of this page.
| Navigation | Where | Layout | On phones |
|---|---|---|---|
| Floating top nav | navid.me, navid.bio, the now page and the design studio site | A fixed pill 10px from the top, 1240px wide and 52 to 58px tall. Narrows to 880px after 50px of scroll. About and Resources menus, search, theme and a call to action. | Below 1024px, a full-screen menu slides in from the left |
| Network nav | aios.guide, HQ, navid.media, the AI OS sites, the summits and the collection sites | The same floating pill, aware of who is signed in: a Products menu, bookmarks and an account menu. The collection sites drop the menus because their sidebar is the navigation. | Below 1024px, a slide-in menu and a profile sheet |
| Site nav, from the shared UI package | medialibrary.to and the media library | The floating pill built from props: logo, links and a slot on the right | Below 1024px, the same slide-in menu |
| Sales page nav | Sales pages of the AI OS sites, navid.consulting, navid.media and HQ | The floating pill with the page's own links and one call to action. It can stay hidden until the reader scrolls past the hero. | Below 768px, the menu opens under the bar |
| Summit nav | The summit pages | The floating pill, with a call to action set per summit | Below 1024px, the menu opens under the bar |
| Hub top bar | /brand and /favorites, the 19 collection sites and the media library docs | A sticky 56px bar across the page: the brand block matches the sidebar, links in the middle, Share, theme and account on the right | Below 1100px, the sidebar opens as a drawer from the bar |
| Hub sidebar | The same hub pages, and the navid.me help center | 248px, sticky under the top bar, with a search box and groups that open and close | Below 1100px, a drawer |
| AI OS guide sidebar and top bar | aios.guide, legacy.navid.me and the AI Token Tracker site | A fixed sidebar, 264px or 60px collapsed, with a sticky 56px top bar of tools on the right. Legacy keeps only search and theme. | Below 1024px, a 56px bar that opens a drawer |
| App shell | HQ, Creator Store, CreatorCRM, the link tracker and the other apps | A 60px app rail, a sidebar of 264px, 60px or open on hover, and a sticky 56px top bar | Below 1024px, a 56px bar and a drawer |
| Member app shell | The member learning app | A 264px or 60px sidebar and a sticky 56px header | A floating pill at the bottom, a bottom sheet and a 280px drawer |
| AI Token Tracker app rail | The AI Token Tracker app | A 264px or 60px rail | A 48px bar |
| Onboarding header | Sign-up and onboarding | A centered wordmark with no links | The same, centered |
The hub top bar, the same one above /favorites and this page.
Every footer the sites and apps use, grouped by kind. Below the table are the 2 that live in navid.me, as the real components in this page's theme. Narrow the window to see the phone accordion.
| Footer | Where | Layout | On phones |
|---|---|---|---|
| Mega footer | navid.me, navid.bio, navid.media, the AI OS sites, the summits, HQ and 20 more sites | Logo, bio and social icons, then 4 link columns, the copyright with language and theme, a legal row and the affiliate note | One accordion, with Legal added as a section |
| Simple footer | Sales, summit, lead magnet, upsell and checkout pages, in 122 places | Logo and tagline, legal links, a hairline, then the copyright with language and theme | Stacks into one column below 640px |
| Hub footer | The 19 collection sites and the media library | Logo, blurb and a row of social icons, link columns, then an Our projects strip listing every property | One accordion, with Our projects as a section |
| Footer bar | Sign-in, onboarding, account and email pages of HQ and the member app | The mark and theme, legal links, then the copyright. A compact version keeps only the last 2 rows. | Stacks |
| Onboarding footer | The bio-link store and the agent gate | The footer bar, with its brand, links and tagline chosen by the domain it is served on | Stacks |
| AI OS guide footer | aios.guide and the AI Token Tracker site | Wordmark, footer line and Built by Navid, 4 columns, then the legal row and 2 disclaimers | One accordion, with Help added |
| App footer | Sign-in pages of Creator Store and CreatorCRM | Logo, legal links and the copyright | Stacks |
| Small footers | The Creator Store storefront, CreatorCRM public pages and embedded agents | One centered line: the store or brand, and Powered by or Runs on Creator Store | The same line |
The mega footer, as navid.me renders it.
The simple footer.
Tool wall
@navid/ui · ToolWallColumns of real tool logos drifting at their own pace. Each column's speed is jittered so they never line up into rows.
Testimonial coverflow
@navid/ui · TestimonialCoverflowI don't think there's a better place right now to learn from AI creators than the AI for Creators Summit. So go there, sign up, and make sure you spend time on these sessions. They're worth it!
Linus EkenstamProduct/experience designer & entrepreneurOne quote at a time, its neighbors pushed back in 3D. Drag or flick it: the throw follows the spring iOS uses for a drawer.
Pricing tiers
@navid/ui · TierCardSelf-hosted
The whole thing, on your own machine or your own server.
- Every feature, no limits
- SQLite, or your own Postgres
- Local disk, or any S3-compatible bucket
- Your own AI key, or no AI at all
- Your own OAuth client per connector
Hosted
We run the platform and keep it updated. Nothing to install.
- We run and update the platform
- Your own bucket, connected
- AI captioning included
- Connectors already registered
- Export everything, any time
Done for you
We stand it up on your infrastructure and move your files in.
- Installed on your own server or cloud
- Your existing library migrated in
- Connectors configured and tested
- Your team walked through it
Media Library's real tiers. Each accent breathes at its own rate, so a row reads as a family rather than a template.
FAQ widget
cs-faq-widget · AI OS Consulting checkoutThe categorized FAQ exactly as the AI OS Consulting checkout renders it: compact, no header, inside its bordered box, with the real checkout questions.
Drawer
@navid/ui · ToolDrawerThe house drawer: hero, specs, rating and the outbound button. Creator, book, gear, template and prompt drawers are all built on this shell.
Floating table of contents
@navid/ui · FloatingTOCTick marks for each section that open into the list, Substack style. Here it is inline; on long posts it sits in the left rail.
Every number, drawn by the same components
These are the components HQ, the CRM, the link tracker, Health OS, the habit tracker, the AI Token Tracker and the other apps use to show numbers, shown exactly as they appear there. The country and link lists are real clicks. Every other number is a sample.
Token burn
app-kit · data/token-burnThe meter on HQ's AI OS dashboard. Usage against the window's cap, counting up on load, with a projection to the end of the window.
Activity feed
app-kit · data/activity-feedActivity
5 recent runsDrafting outlines for the next 3 videos from this week's trending topics.
Brief written: 4 meetings, 12 emails triaged, 3 tasks due today.
14 locales updated for 3 pages. All strings within their character budgets.
Pulled 4 of 4 sources: YouTube, newsletter, link clicks and sales.
Permission denied on 2 archived files. Check their owner and run it again.
HQ's AI OS activity feed. One row per skill run. Hover a row for its log.
Background queue
app-kit · data/background-queueBackground queue
2 active, 4 total—
—
inbox/reports/morning/2026-09-21.md
Permission denied on 2 files
HQ's AI OS queue. Skill runs in the background, each with its state and what it produced.
KPI board
app-kit · data/sales-kpi-boardSales dashboard
Click a card to chart it. Drag a card to reorder the row.
Gross volume
$6,840
The board on the Sales and CRM dashboards. The chart under it is data/revenue-chart.
Stat cards
app-kit · data/hq-stat-cardsThe stat row on HQ's list screens. It lifts and glows on hover.
Funnel
app-kit · data/funnelFunnel
HQ's product funnel. The biggest drop is marked as the top leak.
Health scores
app-kit · data/score-ringRecovery
usual 55 ms
usual 57 bpm
Room to push
Your resting HRV is 58 ms, above your usual 55 ms. That is what is carrying the number today.
Sleep
usual 1.4
usual 1.7
Last night
7.6 hours against your usual 7.1. Deep and REM together came to 3.5 hours.
Strain
usual 11.2
usual 7,960
Capacity left
10.9 against your usual 11.2. There is room in the tank today.
Health OS's home: Recovery, Sleep and Strain side by side. Only Recovery carries the traffic light; Sleep and Strain stay one color, so three rings never read as an alarm panel.
Achievement rings
app-kit · data/achievement-ringsEvery token across every session.
Days in a row with at least one session.
Share of input read from cache.
Every Claude Code session started.
AI Token Tracker's tier rings: bronze to diamond, each ring filling toward the next tier.
Breakdown lists
app-kit · data/breakdown-listReal: Navid's tracked links and 26,655 human clicks, counted on September 21, 2026. The icon tile is SquareIcon from data/link-ui. Link Tracker's analytics page shows the same lists.
Ranked bars
app-kit · data/report-graphsRankBars, from the product sales report, where it ranks top sellers and traffic sources.
Columns
app-kit · data/report-graphsColumns, from the product sales report, for a count over time.
Habit charts
app-kit · data/habit-chartsBarChart and HourChart, from the habit tracker's dashboard.
Year heatmap
app-kit · year-heatmapThe trailing year, one cell a day. Columns stretch to fill the card. Bucketed by quantile, as the testimonials app does.
Month grid
app-kit · data/month-gridSeptember 2026
The habit tracker's month calendar. Each day fills with the share of habits kept.
Burn calendar
app-kit · data/burn-calendarAI Token Tracker's spend calendar: the total on top, then one row per provider in its own color, all on one shared scale.
Hour of week
app-kit · data/hour-heatmapAI Token Tracker's 7 by 24 grid. Shading steps by quintile.
World map
app-kit · data/world-mapHQ's territory map. Revenue by country, shaded on a square-root scale. Hover a country for its orders.
Status pills
app-kit · data/billing-piecesStatusPill, from the billing tab about 18 apps carry, colored with the shared status tokens: each status has a text color and a matching background.
Chart color
7 roles| Role | Use | Value |
|---|---|---|
| Series 1 | The first series, and any chart with only one | #0B81F7 |
| Series 2 | The second series, and the end of every blue gradient | #6361EA |
| Series 3 | The third series | #02CFFF |
| Better | A change for the better, a finished state, the heatmap ramp | #22BAA0 |
| Worse | A change for the worse, a failed state | #C75050 |
| Flat | No change, axis labels, empty data | --text-secondary |
| Grid | Gridlines and the baseline | --glass-border |
Color is meaning
6 meanings, one muted color each, the same in every app: a task, a job, an order, a translation. Pick the meaning and the color follows. Brand blue is never a status, because blue is links and actions. Every chip and bar on this page is the real .status-chip and .status-bar every site ships, so what you see is the spec.
The 6 meanings
one color each · both themesA muted tint with text in the same hue, never a saturated fill, so a list reads at a glance and nothing shouts. Every text color clears 4.5:1 on its tint in both themes. The icon is fixed per meaning, so a status still reads without color.
| Meaning | Chip | Dark · text / tint | Light · text / tint |
|---|---|---|---|
| LiveRunning right now | Live | #6EA8DC / #143A4E | #2A6099 / #E3EEF7 |
| DoneFinished or healthy | Done | #6DB58E / #22402F | #2C7049 / #E4F0E8 |
| WaitingQueued, scheduled or paused | Waiting | #D9985F / #4E3524 | #A4501C / #FAEBDD |
| Needs reviewWaiting on a human look | Needs review | #9D9AE8 / #2F2C4E | #4F4AB8 / #ECEBFA |
| BrokenFailed, and needs you | Broken | #E38678 / #4E2C29 | #B03A2C / #FBE8E5 |
| At restDraft, cancelled or archived | At rest | --text-secondary / #16181D | --text-secondary / #FFFFFF |
Tasks
a piece of work, start to finishThe states a task moves through, each on its meaning. Only In progress moves: its icon breathes, and it stops for anyone who turns on reduced motion. Cancelled is struck through, so an ended task never reads as one that has not started.
Icons
one per meaning · LucideEach meaning has one fixed Lucide icon, drawn in the meaning's hue. Every hue clears 5:1 on the plain page in both themes, so an icon can stand next to text without a chip, and one color per meaning covers chip text, icons, bars and the heartbeat.
| Meaning | Icon | Dark | Light |
|---|---|---|---|
| Live | RotateCw | #6EA8DC | #2A6099 |
| Done | CircleCheck | #6DB58E | #2C7049 |
| Waiting | Clock | #D9985F | #A4501C |
| Needs review | CircleDot | #9D9AE8 | #4F4AB8 |
| Broken | CircleAlert | #E38678 | #B03A2C |
| At rest | CircleDashed | --text-secondary | --text-secondary |
Heartbeat
anything that runs · 8×16A capsule, 8 by 16 with a 4px radius, solid in the meaning's hue, for anything that runs: an agent, a job, a connector. Only a running one moves, sending out a soft ring every 1.6 seconds, and the ring stops for anyone who turns on reduced motion. An error stays still, because red already says it and a blink would shout. The rows below are examples.
Fixes itself or needs you
the question every amber and red row raisesAmber and red both ask for attention, but only some of them need a person. This is the answer, so a list can be read for what needs you and nothing else.
| State | Chip | Fixes itself? |
|---|---|---|
| QueuedBehind a job that is running | Queued | Yes. It starts when the job ahead finishes. |
| ScheduledSet to run later | Scheduled | Yes. It runs at its time. |
| Needs reviewWaiting on a human look | Needs review | No. Someone has to read it and approve it. |
| FailedStopped with an error | Failed | No. Someone has to fix the cause and run it again. |
Progress
one bar · the meaning's hueA job's bar takes the color of its state. A running upload, import or translation fills in the live hue with a slow sheen. A paused one turns amber, a finished one green, and a failed one red where it stopped.
Across the apps
every status we ship, by meaningThe statuses HQ, Creator Store and CreatorCRM already use, sorted by what they mean. A new screen never needs a new color: find the meaning here and use its chip.
| Meaning | Work | Content | Money |
|---|---|---|---|
| Live | AI run running, broadcast sending, video encoding | Translation in progress | Charge processing, trial running |
| Done | Run finished, broadcast sent, automation active | Published, reviewed translation, connected | Paid, subscription active, payout completed |
| Waiting | Queued, scheduled, paused | Stale translation, coming soon | Pending, past due, awaiting payment |
| Needs review | Awaiting approval | Machine translation | Affiliate awaiting approval |
| Broken | Run failed, broadcast failed | Import failed | Payment failed, disputed, unpaid |
| At rest | Draft, archived, disabled | Draft, archived | Cancelled, refunded, expired |
The code
tokens.css · section 4The status layer of the shared tokens file, as every site imports it. Use the chip with the meaning as its data-status, never a hex: <span class="status-chip" data-status="done">.
/* ── 4. Status ─────────────────────────────────────────────────────────── */
/* Color is meaning. 6 meanings, one muted color each, the same in every
* app: a task, a job, an order, a translation. Pick the meaning, never the
* color.
*
* live running right now in progress, sending, processing
* done finished or healthy published, paid, sent, connected
* waiting queued or paused scheduled, pending, stale
* review needs a human look machine translation, awaiting approval
* broken failed, needs you failed, disputed, error
* rest inert draft, cancelled, archived
*
* A muted tint with same-hue text, never a saturated fill, so a list reads
* at a glance without any chip shouting. Brand blue is not a status: it is
* links and actions. Every text color clears 4.5:1 on its tint, both themes,
* and 5:1 alone on the page, so one hue serves chip text, icons, bars and the
* heartbeat. Only live moves.
*/
:root {
/* each meaning: the hue (text, dots, bars), then the chip's tint */
--status-live: #6EA8DC;
--status-live-bg: #143A4E;
--status-done: #6DB58E;
--status-done-bg: #22402F;
--status-waiting: #D9985F;
--status-waiting-bg: #4E3524;
--status-review: #9D9AE8;
--status-review-bg: #2F2C4E;
--status-broken: #E38678;
--status-broken-bg: #4E2C29;
--status-rest: var(--text-secondary);
--status-rest-bg: #16181D;
}
[data-theme="light"] {
--status-live: #2A6099;
--status-live-bg: #E3EEF7;
--status-done: #2C7049;
--status-done-bg: #E4F0E8;
--status-waiting: #A4501C;
--status-waiting-bg: #FAEBDD;
--status-review: #4F4AB8;
--status-review-bg: #ECEBFA;
--status-broken: #B03A2C;
--status-broken-bg: #FBE8E5;
--status-rest-bg: #FFFFFF;
}
@media (prefers-color-scheme: light) {
[data-theme="system"] {
--status-live: #2A6099;
--status-live-bg: #E3EEF7;
--status-done: #2C7049;
--status-done-bg: #E4F0E8;
--status-waiting: #A4501C;
--status-waiting-bg: #FAEBDD;
--status-review: #4F4AB8;
--status-review-bg: #ECEBFA;
--status-broken: #B03A2C;
--status-broken-bg: #FBE8E5;
--status-rest-bg: #FFFFFF;
}
}
/* The chip: <span class="status-chip" data-status="done"><svg/>Done</span>.
A pill, a 1px border in its own hue at 25%, an optional 12px icon. */
.status-chip {
--_hue: var(--status-rest);
--_tint: var(--status-rest-bg);
display: inline-flex;
align-items: center;
gap: 6px;
height: 24px;
padding: 0 10px;
border-radius: 999px;
border: 1px solid color-mix(in srgb, var(--_hue) 25%, transparent);
background: var(--_tint);
color: var(--_hue);
font-size: 12px;
font-weight: 500;
line-height: 1;
white-space: nowrap;
}
.status-chip > svg { width: 12px; height: 12px; flex: none; }
/* Ended, not waiting: cancelled, refunded, expired. Still at rest, struck
through so it never reads as a draft. <span class="status-chip" data-status="rest" data-ended> */
.status-chip[data-ended] { text-decoration: line-through; text-decoration-thickness: 1px; }
:is(.status-chip, .status-bar, .status-beat)[data-status="live"] { --_hue: var(--status-live); --_tint: var(--status-live-bg); }
:is(.status-chip, .status-bar, .status-beat)[data-status="done"] { --_hue: var(--status-done); --_tint: var(--status-done-bg); }
:is(.status-chip, .status-bar, .status-beat)[data-status="waiting"] { --_hue: var(--status-waiting); --_tint: var(--status-waiting-bg); }
:is(.status-chip, .status-bar, .status-beat)[data-status="review"] { --_hue: var(--status-review); --_tint: var(--status-review-bg); }
:is(.status-chip, .status-bar, .status-beat)[data-status="broken"] { --_hue: var(--status-broken); --_tint: var(--status-broken-bg); }
:is(.status-chip, .status-bar, .status-beat)[data-status="rest"] { --_hue: var(--status-rest); --_tint: var(--status-rest-bg); }
/* The bar: <div class="status-bar" data-status="live"><span style="width:62%"></span></div>.
A 6px track in glass, filled with the meaning's hue. */
.status-bar {
--_hue: var(--status-rest);
height: 6px;
border-radius: 999px;
background: var(--glass-bg-hover);
overflow: hidden;
}
.status-bar > span {
display: block;
height: 100%;
border-radius: inherit;
background: var(--_hue);
transition: width 400ms ease;
}
/* The heartbeat: <span class="status-beat" data-status="live"></span>.
An 8×16 capsule, 4px radius, solid in the meaning's hue, for anything that
runs: an agent, a job, a connector. Still unless it is live. */
.status-beat {
--_hue: var(--status-rest);
display: inline-block;
flex: none;
width: 8px;
height: 16px;
border-radius: 4px;
background: var(--_hue);
}
/* Motion is reserved for live: the chip's icon breathes, the heartbeat sends
out a soft ring and the bar's fill carries a slow sheen. Broken stays still
on purpose: red already says it, and a blink would shout. */
.status-chip[data-status="live"] > svg { animation: status-breathe 1.6s ease-in-out infinite; }
.status-beat[data-status="live"] { animation: status-beat 1.6s ease-out infinite; }
.status-bar[data-status="live"] > span {
background-image: linear-gradient(90deg, transparent 0%, rgba(255, 255, 255, 0.28) 50%, transparent 100%);
background-size: 200% 100%;
background-color: var(--_hue);
animation: status-sheen 1.8s linear infinite;
}
@keyframes status-breathe { 0%, 100% { opacity: 1; } 50% { opacity: 0.4; } }
@keyframes status-beat {
0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--_hue) 55%, transparent); }
70% { box-shadow: 0 0 0 5px color-mix(in srgb, var(--_hue) 0%, transparent); }
100% { box-shadow: 0 0 0 0 transparent; }
}
@keyframes status-sheen { from { background-position: 150% 0; } to { background-position: -50% 0; } }
@media (prefers-reduced-motion: reduce) {
.status-chip[data-status="live"] > svg,
.status-beat[data-status="live"],
.status-bar[data-status="live"] > span { animation: none; }
}One file, and every site reads it
packages/nm-tokens/tokens.css is the single source for every Navid Media site. Every value is a CSS custom property, and Tailwind v4 reads the same file through @theme, so no site has a tailwind.config. Each site imports a generated copy, kept in line by npm run tokens:sync. One file, the same values on all 35 sites, and no hex typed by hand.
CSS variables
canonical · every siteDefined once in packages/nm-tokens/tokens.css. The brand hues are literal and look the same in both themes. Background, text and glass swap under [data-theme="light"], and under [data-theme="system"] when the device asks for light. Every color below carries a swatch drawn from the live value.
/* Navid Media design tokens. CANONICAL.
*
* The only file where a brand value is typed. Every site gets a generated
* copy at src/styles/core-tokens.css and imports it at the top of
* src/app/globals.css. Edit here, then run `npm run tokens:sync` in this
* folder. Never edit a copy: the next sync overwrites it and the check flags it.
*
* 1. Brand hues literal, the same in both themes
* 2. Tailwind @theme turns them into utilities; no tailwind.config
* 3. Theme dark by default, then light, then system asking for light
* 4. Status 6 meanings, one muted color each, and the chip and bar
* 5. Motion 3 easings, 5 durations, the rise, and reduced motion
*/
/* ── 1. Brand hues ─────────────────────────────────────────────────────── */
:root {
/* the brand gradient runs blue → indigo */
--brand-blue: #0B81F7; /* links, hover, focus */
--brand-indigo: #6361EA;
/* accents */
--brand-cyan: #02CFFF;
--brand-teal: #00C6C9;
--brand-orange: #FF583C;
--brand-amber: #F59E0B;
--brand-gold: #F9F871;
--brand-red: #F90B2C;
--brand-dim: #C0BFC7;
}
/* ── 2. Tailwind v4 ────────────────────────────────────────────────────── */
@theme {
--font-sans: "Inter", sans-serif;
/* each utility reads the hue above → bg-brand-blue, text-brand-cyan … */
--color-brand-blue: var(--brand-blue);
--color-brand-indigo: var(--brand-indigo);
--color-brand-cyan: var(--brand-cyan);
--color-brand-teal: var(--brand-teal);
--color-brand-orange: var(--brand-orange);
--color-brand-amber: var(--brand-amber);
--color-brand-gold: var(--brand-gold);
--color-brand-red: var(--brand-red);
--color-brand-dim: var(--brand-dim);
/* status hues as utilities → text-status-done, bg-status-live … */
--color-status-live: var(--status-live);
--color-status-done: var(--status-done);
--color-status-waiting: var(--status-waiting);
--color-status-review: var(--status-review);
--color-status-broken: var(--status-broken);
--color-status-rest: var(--status-rest);
}
/* ── 3. Theme ──────────────────────────────────────────────────────────── */
/* Dark is the default. */
:root {
/* ground */
--bg-primary: #000000;
--bg-section: #051823;
/* text */
--text-primary: #E8E8EC;
--text-secondary: #B0B0BC;
/* glass: every surface is white at low opacity over the ground */
--glass-bg: rgba(255, 255, 255, 0.06);
--glass-bg-hover: rgba(255, 255, 255, 0.1);
--glass-border: rgba(255, 255, 255, 0.08);
--glass-border-hover: rgba(255, 255, 255, 0.15);
--input-border: rgba(255, 255, 255, 0.15);
/* chrome */
--logo-display-light: none;
--logo-display-dark: block;
--nav-bg-scrolled: rgba(0, 0, 0, 0.85);
}
/* Light, chosen in the theme picker. */
[data-theme="light"] {
--bg-primary: #F4F5F7;
--bg-section: #EBEDF0;
--text-primary: #1A1A2E;
--text-secondary: #5A5A72;
--glass-bg: rgba(255, 255, 255, 0.65);
--glass-bg-hover: rgba(255, 255, 255, 0.8);
--glass-border: rgba(0, 0, 0, 0.06);
--glass-border-hover: rgba(0, 0, 0, 0.12);
--input-border: rgba(0, 0, 0, 0.12);
--nav-bg-scrolled: rgba(255, 255, 255, 0.85);
}
/* System, when the device asks for light. The same values as light. */
@media (prefers-color-scheme: light) {
[data-theme="system"] {
--bg-primary: #F4F5F7;
--bg-section: #EBEDF0;
--text-primary: #1A1A2E;
--text-secondary: #5A5A72;
--glass-bg: rgba(255, 255, 255, 0.65);
--glass-bg-hover: rgba(255, 255, 255, 0.8);
--glass-border: rgba(0, 0, 0, 0.06);
--glass-border-hover: rgba(0, 0, 0, 0.12);
--input-border: rgba(0, 0, 0, 0.12);
--nav-bg-scrolled: rgba(255, 255, 255, 0.85);
}
}
/* ── 4. Status ─────────────────────────────────────────────────────────── */
/* Color is meaning. 6 meanings, one muted color each, the same in every
* app: a task, a job, an order, a translation. Pick the meaning, never the
* color.
*
* live running right now in progress, sending, processing
* done finished or healthy published, paid, sent, connected
* waiting queued or paused scheduled, pending, stale
* review needs a human look machine translation, awaiting approval
* broken failed, needs you failed, disputed, error
* rest inert draft, cancelled, archived
*
* A muted tint with same-hue text, never a saturated fill, so a list reads
* at a glance without any chip shouting. Brand blue is not a status: it is
* links and actions. Every text color clears 4.5:1 on its tint, both themes,
* and 5:1 alone on the page, so one hue serves chip text, icons, bars and the
* heartbeat. Only live moves.
*/
:root {
/* each meaning: the hue (text, dots, bars), then the chip's tint */
--status-live: #6EA8DC;
--status-live-bg: #143A4E;
--status-done: #6DB58E;
--status-done-bg: #22402F;
--status-waiting: #D9985F;
--status-waiting-bg: #4E3524;
--status-review: #9D9AE8;
--status-review-bg: #2F2C4E;
--status-broken: #E38678;
--status-broken-bg: #4E2C29;
--status-rest: var(--text-secondary);
--status-rest-bg: #16181D;
}
[data-theme="light"] {
--status-live: #2A6099;
--status-live-bg: #E3EEF7;
--status-done: #2C7049;
--status-done-bg: #E4F0E8;
--status-waiting: #A4501C;
--status-waiting-bg: #FAEBDD;
--status-review: #4F4AB8;
--status-review-bg: #ECEBFA;
--status-broken: #B03A2C;
--status-broken-bg: #FBE8E5;
--status-rest-bg: #FFFFFF;
}
@media (prefers-color-scheme: light) {
[data-theme="system"] {
--status-live: #2A6099;
--status-live-bg: #E3EEF7;
--status-done: #2C7049;
--status-done-bg: #E4F0E8;
--status-waiting: #A4501C;
--status-waiting-bg: #FAEBDD;
--status-review: #4F4AB8;
--status-review-bg: #ECEBFA;
--status-broken: #B03A2C;
--status-broken-bg: #FBE8E5;
--status-rest-bg: #FFFFFF;
}
}
/* The chip: <span class="status-chip" data-status="done"><svg/>Done</span>.
A pill, a 1px border in its own hue at 25%, an optional 12px icon. */
.status-chip {
--_hue: var(--status-rest);
--_tint: var(--status-rest-bg);
display: inline-flex;
align-items: center;
gap: 6px;
height: 24px;
padding: 0 10px;
border-radius: 999px;
border: 1px solid color-mix(in srgb, var(--_hue) 25%, transparent);
background: var(--_tint);
color: var(--_hue);
font-size: 12px;
font-weight: 500;
line-height: 1;
white-space: nowrap;
}
.status-chip > svg { width: 12px; height: 12px; flex: none; }
/* Ended, not waiting: cancelled, refunded, expired. Still at rest, struck
through so it never reads as a draft. <span class="status-chip" data-status="rest" data-ended> */
.status-chip[data-ended] { text-decoration: line-through; text-decoration-thickness: 1px; }
:is(.status-chip, .status-bar, .status-beat)[data-status="live"] { --_hue: var(--status-live); --_tint: var(--status-live-bg); }
:is(.status-chip, .status-bar, .status-beat)[data-status="done"] { --_hue: var(--status-done); --_tint: var(--status-done-bg); }
:is(.status-chip, .status-bar, .status-beat)[data-status="waiting"] { --_hue: var(--status-waiting); --_tint: var(--status-waiting-bg); }
:is(.status-chip, .status-bar, .status-beat)[data-status="review"] { --_hue: var(--status-review); --_tint: var(--status-review-bg); }
:is(.status-chip, .status-bar, .status-beat)[data-status="broken"] { --_hue: var(--status-broken); --_tint: var(--status-broken-bg); }
:is(.status-chip, .status-bar, .status-beat)[data-status="rest"] { --_hue: var(--status-rest); --_tint: var(--status-rest-bg); }
/* The bar: <div class="status-bar" data-status="live"><span style="width:62%"></span></div>.
A 6px track in glass, filled with the meaning's hue. */
.status-bar {
--_hue: var(--status-rest);
height: 6px;
border-radius: 999px;
background: var(--glass-bg-hover);
overflow: hidden;
}
.status-bar > span {
display: block;
height: 100%;
border-radius: inherit;
background: var(--_hue);
transition: width 400ms ease;
}
/* The heartbeat: <span class="status-beat" data-status="live"></span>.
An 8×16 capsule, 4px radius, solid in the meaning's hue, for anything that
runs: an agent, a job, a connector. Still unless it is live. */
.status-beat {
--_hue: var(--status-rest);
display: inline-block;
flex: none;
width: 8px;
height: 16px;
border-radius: 4px;
background: var(--_hue);
}
/* Motion is reserved for live: the chip's icon breathes, the heartbeat sends
out a soft ring and the bar's fill carries a slow sheen. Broken stays still
on purpose: red already says it, and a blink would shout. */
.status-chip[data-status="live"] > svg { animation: status-breathe 1.6s ease-in-out infinite; }
.status-beat[data-status="live"] { animation: status-beat 1.6s ease-out infinite; }
.status-bar[data-status="live"] > span {
background-image: linear-gradient(90deg, transparent 0%, rgba(255, 255, 255, 0.28) 50%, transparent 100%);
background-size: 200% 100%;
background-color: var(--_hue);
animation: status-sheen 1.8s linear infinite;
}
@keyframes status-breathe { 0%, 100% { opacity: 1; } 50% { opacity: 0.4; } }
@keyframes status-beat {
0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--_hue) 55%, transparent); }
70% { box-shadow: 0 0 0 5px color-mix(in srgb, var(--_hue) 0%, transparent); }
100% { box-shadow: 0 0 0 0 transparent; }
}
@keyframes status-sheen { from { background-position: 150% 0; } to { background-position: -50% 0; } }
@media (prefers-reduced-motion: reduce) {
.status-chip[data-status="live"] > svg,
.status-beat[data-status="live"],
.status-bar[data-status="live"] > span { animation: none; }
}
/* ── 5. Motion ─────────────────────────────────────────────────────────── */
/* The values the sites already use, measured from the code: typed in
* globals.css, or Tailwind's own defaults. framer-motion cannot read CSS
* variables, so a site that animates with it mirrors these in
* src/lib/motion.ts. Change a value in both. */
:root {
--ease-standard: ease; /* card light, FAQ rows, theme swap */
--ease-tailwind: cubic-bezier(0.4, 0, 0.2, 1); /* every Tailwind transition-* class */
--ease-out: cubic-bezier(0, 0, 0.2, 1); /* Tailwind ease-out */
--dur-micro: 150ms; /* Tailwind's default: color shifts, button hover */
--dur-hover: 200ms; /* duration-200: rows, links, icons */
--dur-short: 250ms; /* .faq-item */
--dur-surface: 300ms; /* card light, theme swap, image zoom */
--dur-panel: 400ms; /* card shadow, status bar fill */
--rise: 20px; /* how far an entrance travels */
--stagger: 60ms; /* the gap between items in a grid */
}
/* Reduced motion. When the device asks for less, nothing travels:
* animations finish at once and stop looping, a hover becomes a quick fade,
* anchors jump instead of glide. A spinner keeps turning, because it says
* "still working", and <span data-motion="essential"> opts anything else in. */
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 100ms !important;
scroll-behavior: auto !important;
}
.animate-spin, [data-motion="essential"] {
animation-duration: 1s !important;
animation-iteration-count: infinite !important;
}
}
Tailwind v4 theme
@theme · no configNo site has a tailwind.config. The @theme block in the same file turns the brand hues into utilities, so bg-brand-blue, text-brand-cyan and font-sans work on every site and read the variables above instead of their own hex.
@theme {
--font-sans: "Inter", sans-serif;
/* each utility reads the hue above → bg-brand-blue, text-brand-cyan … */
--color-brand-blue: var(--brand-blue);
--color-brand-indigo: var(--brand-indigo);
--color-brand-cyan: var(--brand-cyan);
--color-brand-teal: var(--brand-teal);
--color-brand-orange: var(--brand-orange);
--color-brand-amber: var(--brand-amber);
--color-brand-gold: var(--brand-gold);
--color-brand-red: var(--brand-red);
--color-brand-dim: var(--brand-dim);
/* status hues as utilities → text-status-done, bg-status-live … */
--color-status-live: var(--status-live);
--color-status-done: var(--status-done);
--color-status-waiting: var(--status-waiting);
--color-status-review: var(--status-review);
--color-status-broken: var(--status-broken);
--color-status-rest: var(--status-rest);
}How a site takes it
every site · generatedEach site is its own repo and builds on its own, so it cannot reach the package at build time. npm run tokens:sync writes a copy to src/styles/core-tokens.css, stamped with the hash of its source, and globals.css imports it before any rule of its own.
@import "tailwindcss";
@import "../../node_modules/@creatorschool/ui/src/styles.css";
@import "../styles/core-tokens.css";Changing a value
sync · checkEdit tokens.css, sync, then check. The check fails when a site's copy has drifted, when a globals.css stops importing it, or when a brand hex is typed into a globals.css again.
packages/nm-tokens/tokens.css canonical, the only place a value is typed
│
│ npm run tokens:sync writes every site, stamps the hash
▼
<site>/src/styles/core-tokens.css generated in all 35 sites, never edited
│ the brand hues, @theme, and the dark, light and
│ system values, copied byte for byte
│
│ @import on the first lines
▼
<site>/src/app/globals.css the site's own rules
color: var(--brand-blue) border: var(--glass-border)
background: var(--bg-primary) class="bg-brand-blue"
anything only this site needs sits below the import
# check: npm run tokens:check → 35 sites, exits 1 on any driftIteration guide
for agents and developersHow to build with this system without breaking it. An agent reading design.md gets these same rules.
| Rule | Why |
|---|---|
| Start from the meaning, then use its token. Never type a hex. | The value lives in one file, so a change reaches every site. |
Change a value in tokens.css only, then run npm run tokens:sync. | Each site's copy is generated, and the check fails on drift. |
| Build from the components on this page. | A new page composes them. It never writes its own card, button, nav or footer. |
| Design dark first, then check light. | Light is designed rather than inverted, so it needs its own look. |
| Words come from the CMS. | A component never carries its own copy, so every word can be edited and translated. |
| In status, only live moves. | Motion means something is running right now. |
Known gaps
what is not settled yetAn honest list, so nobody builds on something that is not decided.
| Gap | Where it shows |
|---|---|
| Form fields have no focus ring, except the hub search bar. | Contact, testimonial and newsletter forms |
| Touch targets are 30 to 36px. There is no 44px rule yet. | Mobile menu, search and hub buttons |
| Resting cards use 4 slightly different shadows, not one scale. | Light mode cards |
| Article text drops to 16px at 640px, while body text changes at 768px. | Articles on screens between 641px and 767px |
| Form fields use a 12px radius on contact and 8px on testimonials. | Contact and testimonial forms |
| About 29,000 brand colors are still typed by hand outside the global stylesheets. | TypeScript and page stylesheets |
| Navs switch to phone layouts at 3 widths: 768px, 1024px and 1100px. | Sales navs, top navs and hub pages |
| Sidebars come in 5 widths: 248, 260, 264, 280 and 60px collapsed. | Hub, admin, app and drawer sidebars |
| Footer copies have drifted: 9 versions of the hub footer, 2 copyright styles and 2 platform disclaimer wordings. | Footers across the sites |
For agents and developers
The system is published as a single markdown file. Point an agent, an LLM or a teammate at it to build anything that should feel like this site.
/design.mdFrequently asked questions
Answers about using Navid Moazzez's logo, photos, bio and design system in press, podcasts and partner materials.
The most actionable AI newsletter for founders
Every week, get proven AI strategies, curated tools, and step-by-step systems to grow your audience, create better content, and build a profitable creator business.
No fluff, no filler, no BS. Just five minutes each week that might level up your online business and life.
P.S. Sign up now to get free access to my ultimate AI tools guide for creators.

























Social accounts
26