Skip to content

Nitip Design System

Reusable tokens and components for every page of the Nitip template. The published Framer template is the reference for look and behavior; component names follow the Figma file so designers and developers talk about the same thing.

See it live at /style-guide (not linked from the site, not indexed).

src/
design-system/ ← this folder: page-agnostic building blocks
theme.css ← color, breakpoint, easing and animation tokens (Tailwind v4 @theme)
tokens/text.ts ← text styles (h01 … menu)
tokens/motion.ts ← transitions and variant presets
utils/ ← cn(), link helpers
components/ ← actions, brand, navigation, layout, cards, media, data, patterns, forms, cursor
index.ts ← import everything from "@/design-system"
components/
site/ ← Header, Footer (design system + site content)
sections/ ← page sections, reusable across pages, content passed in as props
content/
types.ts ← content model (plain data)
routes.ts ← every URL
site.ts ← brand, navigation, contact, footer
collections/ ← projects, services, posts, testimonials, careers, team
pages/ ← page copy (home.ts, about.ts, …)
lib/to-ui.ts ← maps content items to component props
  1. Design-system components never import from @/content. Data comes in through props, so the same component works on any page and in any template.
  2. Pages pass content to sections; sections compose design-system components. Keep copy out of components.
  3. Links come from routes (routes.project(slug)), never hard-coded strings.
  4. Use tokens, not raw values: text.h02, bg-ink, border-line, springButton. If a new value repeats, add a token.
  5. Match Framer first. Any deliberate refinement is documented in the component’s comment.
  6. New component? Put it in the right components/ group, export it from index.ts, add it to /style-guide and the table below.
Token Values
Breakpoints Phone < 810 · md Tablet 810–1199 · lg Desktop ≥ 1200
Colors ink #101010 · canvas #F6F6F6 · line #D9D9D9 · muted #818181 · accent #FC5000 · star #FDCA49 · danger #FF2244
Font Inter (font-sans)
Text styles text.h01 46/58/72 · h02 44/52/64 · h2 32/36/42 · h3 28/32/36 · h4 24/26/28 · h5 20/22/24 · h6 18/19/20 · hugeParagraph 24/28/32 · largeParagraph 18 · paragraph 16 · smallParagraph 14 · button 14 uppercase · menu 13 uppercase
Section spacing <Section>: sectionGutters 20/30/40, sectionPadding 60/80/100 · sectionGap 60/80/100 between header and content · pageTitlePadding 50 top for page titles
Motion springButton (spring 0.4s, bounce 0.2) · springSoft (0.4s, no bounce) · springSlide (200/40) · springCursor (500/60) · reveal (height reveal) · ease-framer CSS tween for image zooms
Component Figma name Notes
PrimaryButton Primary Button (Default / No Icon) icon={false} for No Icon. Hover: shadow + arrow 45°
SecondaryButton Secondary Button Hover: underline + arrow -45°
BigButton Big Button Footer menu link
SocialMediaLink Social Media Hover: black row, white text
MenuButton Menu (Default / Hover / Active) Active has no hover
TextLink — (Framer link preset) 80% ink + underline on hover; external links handled
ArrowButton — (Framer slideshow arrow)
SwitchButton, Switch Switch Button (Default / Active), Switch Square toggle, #222 outline; Default hover 50% opacity
LoadMoreButton Load More Square ink button, 150 × 40, no hover; the parent places it (centered under the blog grid, left under careers)
Logo Logo (Black / White) tone="light" for dark backgrounds
Icon Phosphor icon set name, tone, size via className
Navigation Navigation (Default / Home / …) Active item from pathname; layout="stack" for mobile
Hamburger Hamburger (Default / Close)
Breadcrumbs — (Framer “Breadcrumbs”) Last item is the current page
Section, SectionHeader, SectionLabel, Divider Section / Title Section SectionHeader size="small" for Heading 6 titles; leadClassName sets the lead width
PageTitle Page Title Breadcrumbs (optional), h1, divider, description (max 600, descriptionWidth="wide" 850). Use with padding={pageTitlePadding}
ProjectCard Project With Details (Default) “View Project” cursor on the image
ProjectSimpleCard Project Simple Card (Open / Close) Used by ProjectRecentList
ProjectListItem Project With Details (Desktop / Tablet / Phone List) Row with divider; View Details and image zoom on desktop
PostCard Post Card “Read” cursor
TestimonialCard Testimonial (Desktop / Tablet / Mobile)
TextPoint Text Point List row with dot
HighlightList — (Framer rich text) Bulleted list with a bold lead phrase
FactCard Fact Number tone="dark" for the ink card; ring cursor
TeamCard Team Portrait, name, role, email. No hover
CoverImage — (Framer Image + Cover) Bottom gradient with content; ring cursor
ParallaxImage — (Framer Parallax) speed/phoneSpeed/offset/scale; image sized so no gap ever shows; clip={false} to clip in the parent
ScrollTransform — (Framer Scroll Transform, In View) from/phoneFrom (x, y, scale, opacity) → rest while the frame scrolls into view
Chart Chart (Desktop / Desktop Start / Mobile) Grows on scroll; ring cursor
PricingCard Pricing Plan switch (hidden with one plan), included list, price, CTA
Rating, AvatarGroup Hero “User Rating”
AccordionItem Service / Careers row Shared accordion row; layout="service" | "career" sets columns. Closed rows hide the divider up to the title column (tablet/desktop)
ServiceList Service (Open / Close)
CareerList Careers (Open / Close) Dot marker, About the Role + Requirement; pageSize adds a left-aligned Load More
ValueList Value (Desktop / Tablet / Phone) Numbered rows. No hover
ProjectRecentList Project Recent List
ProjectGallery Projects page Grid / List Switch + ProjectCard grid or ProjectListItem list
PostGrid Blog archive grid 1 / 2 / 3 columns, Load More, 4 or 6 posts per page
RichText — (Framer rich text) Post body: headings 40 above, paragraphs and lists 20; numbered and nested lists, bold leads
Slideshow, TestimonialSlideshow Testimonial Slide Show Autoplay 5s, drag, keyboard
Ticker — (Framer Ticker) 30 px/s
BigFooter Big Footer “More Details” cursor
Form — (Framer form) Posts to a server action; shows pending / success / error on the Submit button; resets on success only; honeypot field honeypotField. Delivery: src/lib/forms
CheckboxGroup — (Framer checkboxes) Label + wrapping 16 px square checkboxes; every checked option is sent under one name
FormField — (Framer input / textarea) Label + 40 px input or 200 px message box; ink 3% fill, focus turns white
SubmitButton Form (Default / Loading / Success / Error) Full width; status prop
Cursor Cursor (Dot / Active / View Project / Read / More Details) Render once in the layout; use data-cursor="…"
MotionProvider Honors reduced motion
CurrentYear Always-current copyright year

<Cursor /> is rendered once in app/layout.tsx. Mark elements with data-cursor:

<Link href={href} data-cursor="view-project"></Link> // also: "read", "more-details", "ring"

Planned (add when the page that uses them is built, from the Framer page)

Section titled “Planned (add when the page that uses them is built, from the Framer page)”
Component Figma name Page
SubmitButton Submit Button Contact
Play cursor Cursor / Play Video blocks