Source of truth

Style guide

Every specimen below is rendered from the live design tokens, so this page cannot drift from the system. Each one is labelled with the exact token or variant name to type when reusing it.

Colour

Swatches read their value straight from the CSS variable, in whichever theme is active. Use the semantic name, never the raw value — that is what makes light and dark work for free.

Surface

The layers a page is built from. Pick the flattest one that still separates content — page, then card, then a raised popover.

--backgroundbg-background
—

The page itself. Every screen starts here.

--cardbg-card
—

Panels sitting on the page: cards, speaker tiles, schedule rows.

--popoverbg-popover
—

Floating layers above the page: menus, tooltips, dialogs.

--mutedbg-muted
—

Quiet bands and fills that separate a section without a border.

--secondarybg-secondary
—

Neutral chips and secondary fills that must not read as brand.

--surface-glassbg-surface-glass
—

The frosted sticky header and glass cards.

Aa — sample text
--dark-sectionbg-dark-section
—

Full-bleed alternate bands that stay dark in both themes: CTA, sponsors, footer.

Content

Text and icons. Each surface has a matching foreground — never pair a foreground with a surface it was not made for.

Aa — sample text
--foregroundtext-foreground
—

Default body and heading text on the page.

Aa — sample text
--card-foregroundtext-card-foreground
—

Text inside cards and panels.

Aa — sample text
--popover-foregroundtext-popover-foreground
—

Text inside floating layers.

Aa — sample text
--muted-foregroundtext-muted-foreground
—

Supporting text: captions, labels, metadata, placeholders.

Aa — sample text
--primary-foregroundtext-primary-foreground
—

Text and icons on a primary or gradient fill.

Aa — sample text
--accent-foregroundtext-accent-foreground
—

Text and icons on the pink accent fill.

Aa — sample text
--accent-on-darkbg-accent-on-dark
—

Headings and emphasized text on a dark-section band. Never on light backgrounds.

Interactive

Anything a person can act on. The pink-to-blue gradient is the brand's primary action; the flat primary is its calm sibling for dense UI.

--primarybg-primary
—

The main action, active nav state and key numbers.

--primary-hoverbg-primary-hover
—

Hover and pressed state of a primary control.

--primary-subtlebg-primary-subtle
—

Tinted background behind a brand badge or selected row.

--accentbg-accent
—

The pink half of the brand. Highlights, never a second button style.

--accent-subtlebg-accent-subtle
—

Tinted background for accent chips.

--borderbg-border
—

Dividers and the outline of outline buttons and cards.

--inputbg-input
—

Field borders in their resting state.

--ringbg-ring
—

The focus ring on every keyboard-focusable control.

Feedback

Status only — never decoration. Each has a solid fill for badges and a subtle tint for message backgrounds.

--successbg-success
—

Confirmed, free, available, registration complete.

--success-subtlebg-success-subtle
—

Background of a success message.

--warningbg-warning
—

Few seats left, deadline approaching, needs attention.

--warning-subtlebg-warning-subtle
—

Background of a warning message.

--destructivebg-destructive
—

Errors, sold out, cancel and delete actions.

--destructive-subtlebg-destructive-subtle
—

Background of an error message or invalid field.

--infobg-info
—

Neutral information: venue notes, track labels.

--info-subtlebg-info-subtle
—

Background of an informational note.

Gradient

The pink-to-purple gradient is the brand's primary. It belongs on the one leading action of a screen and on hero headlines — nowhere else.

Primary action fillbg-gradient-primary
Build in the open
Headline filltext-gradient-primary

Typography

Geist for everything, Geist Mono for anything technical: times, ticket codes, token names. Sizes come from named steps, never from ad-hoc classes.

One day of building in the open

text-display— · — weight · — line-height

The single hero headline of a page. Never twice on one screen.

Talks, workshops and a lot of coffee

text-h1— · — weight · — line-height

Page titles below the hero.

Meet this year's speakers

text-h2— · — weight · — line-height

Section headings.

Designing with tokens, not pixels

text-h3— · — weight · — line-height

Card and list-item titles.

Doors open at nine in Zurich. Bring a laptop, a project you care about, and expect to leave with something that runs.

text-body— · — weight · — line-height

Paragraphs and default reading text.

Tickets are free, but seats are limited to six hundred.

text-small— · — weight · — line-height

Supporting text, helper copy and dense lists.

Main stage · 10:00

text-caption— · — weight · — line-height

Labels, chips, metadata and eyebrows.

Vibe Code Fest 2026
Sans — headings and bodyfont-sans
09:00 · VCF-2026
Mono — times, codes, labelsfont-mono

Spacing

The standard 4px scale — no parallel system. Gaps inside a component step by 2 and 3; gaps between blocks step by 6, 8 and 12.

p-1 / gap-1
4px
p-2 / gap-2
8px
p-3 / gap-3
12px
p-4 / gap-4
16px
p-6 / gap-6
24px
p-8 / gap-8
32px
p-12 / gap-12
48px
p-16 / gap-16
64px

Radius & elevation

Every radius derives from one token, so changing --radius rescales the whole system. Elevation is one ladder of four steps plus a brand accent — every shadow in the system is one of these variables, never a hand-written box-shadow.

Inputs, small and medium buttons · rounded-field
Cards, panels, schedule rows · rounded-card
Large feature surfaces · rounded-lg
Badges and large buttons · rounded-pill
Level 0shadow-flat--shadow-flat

Flush with the page. Separation comes from border-border alone: outline cards, table rows, section blocks.

—
Level 1shadow-raised--shadow-raised

Resting lift: raised cards, the gradient button, sticky headers, feature medallions.

—
Level 2shadow-lifted--shadow-lifted

Something is being acted on: hover or drag of a level-1 surface, elevated cards.

—
Level 3shadow-overlay--shadow-overlay

Floats above the page and closes: popovers, dropdowns, dialogs, toasts.

—
Accentshadow-glow--shadow-glow

Not a depth step. Brand emphasis behind gradient surfaces such as the hero CTA panel.

—
Frosted header and glass cardssurface-glass
Hover lift · hover-lift

Motion

Motion confirms an action — a press, a toggle, an expand. Nothing fades in on load, and nothing moves that the person did not touch. Hover each bar to see its timing.

--duration-fast—

Colour changes on buttons and links

--duration-base—

Lifts, expands, toggles

--duration-slow—

Large surfaces entering

--ease-standard—

Default easing for state changes

--ease-emphasized—

Motion that should feel confident

Icons

Lucide is the base icon set, plus curated brand/social glyphs, always rendered through the Icon component so size and colour stay on-system.

size="xs"
size="sm"
size="md"
size="lg"
size="xl"
arrowRight
arrowUpRight
calendar
check
chevronDown
chevronRight
clock
code
externalLink
globe
heart
link
spinner
info
instagram
linkedin
mail
moon
mapPin
menu
mic
minus
pencil
plus
search
send
sparkles
share
star
sun
ticket
warning
users
video
whatsapp
close
Code
<Icon name="ticket" size="md" tone="brand" />

Components

Every variant and every state that applies, side by side. States that a component does not own are marked so — they are handled by the field or the surrounding form.

Tabs

Teach something amazing at Vibe Code Fest.

bg-muteddata-[state=active]:bg-backgroundshadow-raisedring-ring

Talk proposals are open.

Disabled triggerdisabled:opacity-50
Code
<Tabs defaultValue="talk">
  <TabsList aria-label="Ways to contribute">
    <TabsTrigger value="talk">Talk/Session</TabsTrigger>
    <TabsTrigger value="volunteer">Volunteer</TabsTrigger>
  </TabsList>
  <TabsContent value="talk">Talk content</TabsContent>
  <TabsContent value="volunteer">Volunteer content</TabsContent>
</Tabs>

Button

VariantDefaultHover (point at it)FocusDisabledLoadingvariant="gradient"variant="solid"variant="secondary"variant="ghost"variant="link"variant="destructive"
variant="muted" · gradient backgrounds only

Hover and focus are live — point at or tab to any button above. The focus column shows the ring statically so both can be compared.

Which variant where: inside cards use gradient, solid or secondary. Inside a call-to-action panel use secondary. ghost and link stay for tertiary and inline actions only.

Code
<Button variant="gradient" size="lg" loading={isSaving}>
  Get tickets
</Button>

In context

Registration form

We only email you the ticket.

Feature card & CTA panel

Feature card

Icon medallion, heading and short supporting text — for non-interactive content.

Clickable feature card

Pass href and the whole card becomes a link, with hover lift and a focus ring.

Vibe Code Fest speaker

Feature card with picture

Pass imageSrc and a circular photo replaces the icon medallion.

Vibe Code Fest speaker

Call-to-action panel

Full-bleed gradient panel for the closing action on a page.

Get your ticket
Code
<FeatureCard
  icon="sparkles"
  title="Feature card"
  description="Short supporting text."
/>

<FeatureCard
  href="/programme"
  icon="ticket"
  title="Clickable feature card"
  description="Whole card is a link."
/>

<FeatureCard
  imageSrc={speakerPhoto}
  imageAlt="Speaker"
  title="Feature card with picture"
  description="Circular photo instead of the icon medallion."
/>

<CtaPanel
  title="Call-to-action panel"
  description="Full-bleed gradient panel."
  actionLabel="Get your ticket"
  actionHref="/tickets"
  image={{ src: speakerPhoto, alt: "Speaker" }}
/>

Input

That email address looks incomplete.
Code
<Input
  label="Email"
  error={errors.email}
  hint="We only email you the ticket."
/>

Badge

VariantSubtleSolidvariant="neutral"WorkshopWorkshopvariant="brand"WorkshopWorkshopvariant="info"WorkshopWorkshopvariant="success"WorkshopWorkshopvariant="warning"WorkshopWorkshopvariant="destructive"WorkshopWorkshop

Badges are static labels: no hover, focus, disabled or loading state.

Code
<Badge variant="success" tone="solid">Free</Badge>

Card

Workshop pass

Twelve seats, hands on

Build a small app end to end with a mentor at your table.

variant="plain"

Workshop pass

Twelve seats, hands on

Build a small app end to end with a mentor at your table.

variant="outline"

Workshop pass

Twelve seats, hands on

Build a small app end to end with a mentor at your table.

variant="elevated"

Workshop pass

Twelve seats, hands on

Build a small app end to end with a mentor at your table.

variant="glass"

Workshop pass

Twelve seats, hands on

Pass an optional action and an icon-only Button lands in the top-right corner of the card.

Code
<Card variant="glass">
  <CardHeader><CardTitle>Workshop pass</CardTitle></CardHeader>
</Card>

<Card
  variant="elevated"
  action={
    <Button variant="ghost" size="icon" aria-label="Edit">
      <Icon name="pencil" />
    </Button>
  }
>
  …
</Card>

Photo frame

Vibe Code Fest organizers togetherOrganizers celebrating with raised handsVibe Code Fest winners on stageSpeaker presenting at Vibe Code FestAudience applauding during the eventIce bath experience at Vibe Code Fest
View Full Photo Gallery

Photos by Silvan Mühlelemann (mühlelemann+popp AG)

bg-gradient-primarybg-cardrounded-cardrounded-lg

Six photographs share one gradient frame with rounded tiles, a gallery button and an optional credit line inside. The grid uses two columns on mobile and three columns from tablet size onward.

Code
<PhotoFrame
  photos={eventPhotos}
  href="https://example.com/full-gallery"
  credit="Photos by Silvan Mühlelemann"
  creditLabel="mühlelemann+popp AG"
  creditHref="https://example.com"
/>

Ticket card

Early bird
89 CHF
regular price129 CHF
Limited
199 CHF
regular price129 CHF
Student
49 CHF
regular price129 CHF

The tear line and side notches are rendered with a CSS mask, so the ticket works on gradient or image backgrounds too. The top area shows the tier price; the bottom area shows the regular-pass comparison.

Code
<TicketCard
  pill={<Badge variant="brand" tone="solid">Early bird</Badge>}
>
  <TicketPrice>
    <span className="text-body font-semibold">89 CHF</span>
  </TicketPrice>
  <TicketRegular label="regular price" price="129 CHF" />
</TicketCard>

Heading & Text

Speakers

Heading tone="default"

Speakers

Heading tone="muted"

Speakers

Heading tone="gradient"

Doors open at nine.

Text tone="default"

Doors open at nine.

Text tone="muted"

Doors open at nine.

Text tone="primary"

Doors open at nine.

Text tone="destructive"

Avatar

size="sm"
size="md"
size="lg"
size="xl"
Nora Keller
ring="gradient"

Speaker card

Ada Mwangi

Ada Mwangi

Staff Engineer · Northwind

PerformanceDX
variant="plain"
Ada Mwangi

Ada Mwangi

Staff Engineer · Northwind

PerformanceDX
variant="elevated"
Ada Mwangi

Ada Mwangi

Staff Engineer · Northwind

PerformanceDX
variant="glass"

LinkedIn bubble

placement="inline" · placement="avatar"
Code
<LinkedInBubble href="https://linkedin.com/in/nora-keller" name="Nora Keller" placement="inline" />

Sponsor card

ATOLL by EUTIMA logovariant="default"
ATOLL by EUTIMA logovariant="highlight"
ATOLL by EUTIMA logovariant="default" size="sm"
ATOLL by EUTIMA logovariant="highlight" size="sm"
Code
<SponsorCard logoSrc={atollLogo} name="ATOLL by EUTIMA" variant="highlight" size="sm" href="https://atoll-by-eutima.example.com" />

Schedule timeline

SPARK

An inspiring opening to ignite creativity.

10:00

Arrival & coffee

10:30–11:00

Keynote & fireside chat

Nora Keller & Marco Frei

SHARE

Interactive sessions led by the community.

11:00–11:25

Community talk

Luca Bianchi

12:30

Lunch

BUILD

Turn ideas into working products.

15:00–18:15

Hackathon

Ada Mwangi

18:15

Pizza break

CELEBRATE

Recognise the winners and close the day together.

19:30

Top five app pitches

Community voting and winner selection

20:00–22:00

Awards and celebration

Code
<Schedule>
  <ScheduleCategory markerTone="info" headerTransition="accentInfo">
    <ScheduleHeader icon="share" title="SHARE" subtext="Community sessions." />
    <ScheduleItem
      time="11:00"
      title="Community talk"
      speaker="Luca Bianchi"
      linkedinHref="https://linkedin.com/in/luca-bianchi"
      description="A short talk about building together."
      avatar={{ src: "https://example.com/luca.jpg", name: "Luca Bianchi" }}
    />
    <ScheduleItem time="12:30" title="Lunch" />
  </ScheduleCategory>
</Schedule>

Stat

600+Attendees
24Talks
12Workshops
1Day in Zurich
tone="default" · tone="brand"

FAQ

Open, closed, hover and keyboard focus are all live — tab into the questions above.

Navbar & Footer

Footer layout: brand on the left, centred tagline and newsletter action on the right; below the divider, centred legal links with social actions on the right edge.