---
version: alpha
name: Redeye Passport
description: "Dark-first travel planning UI: deep teal-tinted night surfaces, a luminous aqua accent and cinematic display type for trips after dark."
colors:
  background: "#f0f6f7"
  foreground: "#0b1418"
  card: "#ffffff"
  card-foreground: "#0b1418"
  popover: "#ffffff"
  popover-foreground: "#0b1418"
  primary: "#09766a"
  primary-foreground: "#ffffff"
  secondary: "#e1eaec"
  secondary-foreground: "#151f25"
  muted: "#e1eaec"
  muted-foreground: "#455760"
  accent: "#d1faf1"
  accent-foreground: "#0a4742"
  destructive: "#c02d56"
  destructive-foreground: "#ffffff"
  success: "#2f6b1e"
  success-foreground: "#ffffff"
  warning: "#fdd58c"
  warning-foreground: "#402a07"
  border: "#c3d2d6"
  input: "#9db0b6"
  ring: "#0a9482"
  dark-background: "#0b1418"
  dark-foreground: "#f0f6f7"
  dark-card: "#151f25"
  dark-card-foreground: "#f0f6f7"
  dark-popover: "#151f25"
  dark-popover-foreground: "#f0f6f7"
  dark-primary: "#36d2b8"
  dark-primary-foreground: "#042b28"
  dark-secondary: "#212d33"
  dark-secondary-foreground: "#e1eaec"
  dark-muted: "#212d33"
  dark-muted-foreground: "#9db0b6"
  dark-accent: "#0a4742"
  dark-accent-foreground: "#d1faf1"
  dark-destructive: "#f66e89"
  dark-destructive-foreground: "#390011"
  dark-success: "#7ccf5a"
  dark-success-foreground: "#0b2108"
  dark-warning: "#e3a12a"
  dark-warning-foreground: "#261802"
  dark-border: "#212d33"
  dark-input: "#34434b"
  dark-ring: "#36d2b8"
typography:
  display-lg:
    fontFamily: Familjen Grotesk
    fontSize: 56px
    fontWeight: 700
    lineHeight: 1.05
    letterSpacing: -0.03em
  display-md:
    fontFamily: Familjen Grotesk
    fontSize: 42px
    fontWeight: 600
    lineHeight: 1.1
    letterSpacing: -0.022em
  heading-lg:
    fontFamily: Familjen Grotesk
    fontSize: 32px
    fontWeight: 600
    lineHeight: 1.18
    letterSpacing: -0.015em
  heading-md:
    fontFamily: Familjen Grotesk
    fontSize: 24px
    fontWeight: 500
    lineHeight: 1.28
    letterSpacing: -0.008em
  heading-sm:
    fontFamily: Rubik
    fontSize: 20px
    fontWeight: 600
    lineHeight: 1.35
    letterSpacing: -0.003em
  body-lg:
    fontFamily: Rubik
    fontSize: 18px
    fontWeight: 400
    lineHeight: 1.6
  body-md:
    fontFamily: Rubik
    fontSize: 16px
    fontWeight: 400
    lineHeight: 1.55
  body-sm:
    fontFamily: Rubik
    fontSize: 14px
    fontWeight: 400
    lineHeight: 1.5
  label:
    fontFamily: Rubik
    fontSize: 14px
    fontWeight: 500
    lineHeight: 1.3
    letterSpacing: 0.005em
  caption:
    fontFamily: Rubik
    fontSize: 12px
    fontWeight: 500
    lineHeight: 1.4
    letterSpacing: 0.02em
  code:
    fontFamily: JetBrains Mono
    fontSize: 14px
    fontWeight: 400
    lineHeight: 1.5
rounded:
  sm: 6px
  md: 12px
  lg: 18px
  xl: 24px
  full: 9999px
spacing:
  xs: 4px
  sm: 8px
  md: 16px
  lg: 24px
  xl: 32px
  2xl: 48px
  3xl: 64px
components:
  button-primary:
    backgroundColor: "{colors.primary}"
    textColor: "{colors.primary-foreground}"
    typography: "{typography.label}"
    rounded: "{rounded.md}"
    padding: 0 16px
    height: 40px
  button-secondary:
    backgroundColor: "{colors.secondary}"
    textColor: "{colors.secondary-foreground}"
    typography: "{typography.label}"
    rounded: "{rounded.md}"
    padding: 0 16px
    height: 40px
  button-destructive:
    backgroundColor: "{colors.destructive}"
    textColor: "{colors.destructive-foreground}"
    typography: "{typography.label}"
    rounded: "{rounded.md}"
    padding: 0 16px
    height: 40px
  input:
    backgroundColor: "{colors.background}"
    textColor: "{colors.foreground}"
    typography: "{typography.body-sm}"
    rounded: "{rounded.md}"
    padding: 0 12px
    height: 40px
  card:
    backgroundColor: "{colors.card}"
    textColor: "{colors.card-foreground}"
    rounded: "{rounded.lg}"
    padding: 24px
  popover:
    backgroundColor: "{colors.popover}"
    textColor: "{colors.popover-foreground}"
    rounded: "{rounded.lg}"
    padding: 12px
  helper-text:
    backgroundColor: "{colors.background}"
    textColor: "{colors.muted-foreground}"
    typography: "{typography.body-sm}"
  table-row-alt:
    backgroundColor: "{colors.muted}"
    textColor: "{colors.muted-foreground}"
    typography: "{typography.body-sm}"
    height: 44px
  badge:
    backgroundColor: "{colors.accent}"
    textColor: "{colors.accent-foreground}"
    typography: "{typography.caption}"
    rounded: "{rounded.full}"
    padding: 0 8px
    height: 22px
  badge-success:
    backgroundColor: "{colors.success}"
    textColor: "{colors.success-foreground}"
    typography: "{typography.caption}"
    rounded: "{rounded.full}"
    padding: 0 8px
    height: 22px
  badge-warning:
    backgroundColor: "{colors.warning}"
    textColor: "{colors.warning-foreground}"
    typography: "{typography.caption}"
    rounded: "{rounded.full}"
    padding: 0 8px
    height: 22px
  badge-destructive:
    backgroundColor: "{colors.destructive}"
    textColor: "{colors.destructive-foreground}"
    typography: "{typography.caption}"
    rounded: "{rounded.full}"
    padding: 0 8px
    height: 22px
  button-primary-dark:
    backgroundColor: "{colors.dark-primary}"
    textColor: "{colors.dark-primary-foreground}"
    typography: "{typography.label}"
    rounded: "{rounded.md}"
    padding: 0 16px
    height: 40px
  button-secondary-dark:
    backgroundColor: "{colors.dark-secondary}"
    textColor: "{colors.dark-secondary-foreground}"
    typography: "{typography.label}"
    rounded: "{rounded.md}"
    padding: 0 16px
    height: 40px
  button-destructive-dark:
    backgroundColor: "{colors.dark-destructive}"
    textColor: "{colors.dark-destructive-foreground}"
    typography: "{typography.label}"
    rounded: "{rounded.md}"
    padding: 0 16px
    height: 40px
  input-dark:
    backgroundColor: "{colors.dark-background}"
    textColor: "{colors.dark-foreground}"
    typography: "{typography.body-sm}"
    rounded: "{rounded.md}"
    padding: 0 12px
    height: 40px
  card-dark:
    backgroundColor: "{colors.dark-card}"
    textColor: "{colors.dark-card-foreground}"
    rounded: "{rounded.lg}"
    padding: 24px
  popover-dark:
    backgroundColor: "{colors.dark-popover}"
    textColor: "{colors.dark-popover-foreground}"
    rounded: "{rounded.lg}"
    padding: 12px
  helper-text-dark:
    backgroundColor: "{colors.dark-background}"
    textColor: "{colors.dark-muted-foreground}"
    typography: "{typography.body-sm}"
  table-row-alt-dark:
    backgroundColor: "{colors.dark-muted}"
    textColor: "{colors.dark-muted-foreground}"
    typography: "{typography.body-sm}"
    height: 44px
  badge-dark:
    backgroundColor: "{colors.dark-accent}"
    textColor: "{colors.dark-accent-foreground}"
    typography: "{typography.caption}"
    rounded: "{rounded.full}"
    padding: 0 8px
    height: 22px
  badge-success-dark:
    backgroundColor: "{colors.dark-success}"
    textColor: "{colors.dark-success-foreground}"
    typography: "{typography.caption}"
    rounded: "{rounded.full}"
    padding: 0 8px
    height: 22px
  badge-warning-dark:
    backgroundColor: "{colors.dark-warning}"
    textColor: "{colors.dark-warning-foreground}"
    typography: "{typography.caption}"
    rounded: "{rounded.full}"
    padding: 0 8px
    height: 22px
  badge-destructive-dark:
    backgroundColor: "{colors.dark-destructive}"
    textColor: "{colors.dark-destructive-foreground}"
    typography: "{typography.caption}"
    rounded: "{rounded.full}"
    padding: 0 8px
    height: 22px
---

# Redeye Passport

## Overview

Redeye Passport is for planning and tracking journeys on phones and laptops late at night, when the screen is the brightest thing in the room. Dark mode is the primary mode. Surfaces use the neutral ramp, a slate tinted toward the brand teal, and a single aqua accent (brand.400) marks the one main action per view. Light mode is supported and is built from the same ramps: background neutral.50, cards #ffffff, primary brand.700.

Moods: nocturnal, cinematic, luminous, calm. Built for: travel, hospitality, navigation. Density: comfortable.

Every color has a light value and a dark value. Tokens named `dark-*` are the dark-mode counterparts of the token with the same role name.

## Colors

Brand is an aqua-teal ramp (OKLCH hue about 170–178). Chroma peaks at brand.400–500 and tapers evenly toward 50 and 950. Neutrals sit at hue about 205 with low chroma (about 0.01–0.02), shifted toward the brand so dark surfaces carry a faint teal cast. Destructive (danger, hue about 5) is a magenta-crimson far from the teal primary (ΔE2000 > 40 in both modes). Success is a leafy green at hue about 135 and warning a clean amber at hue about 75. Warning steps 300–500 were re-saturated to remove the muddy olive mid-tones. Checked pairs: primary-foreground on primary is 5.5:1 in light and 8.0:1 in dark. muted-foreground (neutral.600 light, neutral.300 dark) is ≥ 6:1 on both background and muted. ring is 3.5:1 in light and 9.8:1 in dark against the background.

- **Primary** `#09766a` / dark `#36d2b8`: the single action color. Primary buttons, links, focus ring.
- **Background / Foreground** `#f0f6f7` / dark `#0b1418` on `#0b1418` / dark `#f0f6f7`: page surface and body text.
- **Card** `#ffffff` / dark `#151f25`: raised surfaces.
- **Secondary** `#e1eaec` / dark `#212d33`: secondary buttons and quiet controls.
- **Muted** `#e1eaec` / dark `#212d33` with **muted-foreground** `#455760` / dark `#9db0b6`: helper text, table stripes, disabled-looking surfaces.
- **Accent** `#d1faf1` / dark `#0a4742`: highlights, selected rows, badges.
- **Destructive** `#c02d56` / dark `#f66e89`, **Success** `#2f6b1e` / dark `#7ccf5a`, **Warning** `#fdd58c` / dark `#e3a12a`: status only, always paired with an icon or label.
- **Border** `#c3d2d6` / dark `#212d33`, **Input** `#9db0b6` / dark `#34434b`, **Ring** `#0a9482` / dark `#36d2b8`.

All text/background pairs above pass WCAG AA (4.5:1) in both modes; this is checked automatically at build time.

## Typography

The scale is a major third (1.25) from 16px up to 24px, then a perfect fourth (1.333): 12, 14, 16, 18, 20, 24, 32, 42, 56. Familjen Grotesk sets heading-md (24px, 500) through display-lg (56px, 700). Tracking tightens with size: −0.008em at 24px, −0.015em at 32px, −0.022em at 42px, −0.03em at 56px. Rubik (400/500/600) sets heading-sm and all functional text: forms, tables, buttons, itinerary rows. Body line height is 1.5–1.6. JetBrains Mono (400/500) at code size 14px is reserved for booking references, flight numbers, coordinates and timestamps.

- Display: **Familjen Grotesk** (fallback system-ui, sans-serif)
- Interface: **Rubik** (fallback system-ui, sans-serif)
- Mono: **JetBrains Mono** (fallback ui-monospace, monospace)

| Token | Font | Size | Line height | Weight |
|---|---|---|---|---|
| display-lg | Familjen Grotesk | 56px | 1.05 | 700 |
| display-md | Familjen Grotesk | 42px | 1.1 | 600 |
| heading-lg | Familjen Grotesk | 32px | 1.18 | 600 |
| heading-md | Familjen Grotesk | 24px | 1.28 | 500 |
| heading-sm | Rubik | 20px | 1.35 | 600 |
| body-lg | Rubik | 18px | 1.6 | 400 |
| body-md | Rubik | 16px | 1.55 | 400 |
| body-sm | Rubik | 14px | 1.5 | 400 |
| label | Rubik | 14px | 1.3 | 500 |
| caption | Rubik | 12px | 1.4 | 500 |
| code | JetBrains Mono | 14px | 1.5 | 400 |

## Layout

Comfortable density on a 4px base grid. Itinerary and map-side cards use 24px padding (space.6). Gaps between sections are 16–24px (space.4–space.6). Content columns cap at 1120px so long destination guides keep a readable measure on wide monitors. Buttons and inputs share a 40px height so they align in a row.

Spacing uses a 4px base: xs = 4px, sm = 8px, md = 16px, lg = 24px, xl = 32px, 2xl = 48px, 3xl = 64px.

## Elevation & Depth

Depth comes from tonal layering first. In dark mode, background is neutral.950, card and popover are neutral.900, and secondary and muted are neutral.800, each one step lighter. Borders are neutral.800, so they separate cards without adding glare. Shadows are dark and diffuse: sm for inputs, md for cards. Only shadow.lg adds a faint aqua glow, and it is limited to the hero destination card and the active map pin.

- sm: `0 1px 2px rgba(4, 12, 16, 0.32)`
- md: `0 8px 24px -6px rgba(4, 12, 16, 0.45)`
- lg: `0 24px 60px -12px rgba(4, 12, 16, 0.55), 0 0 32px rgba(54, 210, 184, 0.16)`

## Shapes

Rounding is soft and generous: 6px (radius.sm) on checkboxes and tags, 12px (radius.md) on buttons and inputs, 18px (radius.lg) on cards, 24px (radius.xl) on hero panels. radius.full is reserved for badges and map chips. No surface uses radius.none.

Radius scale: sm 6px, md 12px, lg 18px, xl 24px, full 9999px.

## Components

Components ending in `-dark` are the dark-mode versions. Button: 40px tall, 16px horizontal padding, label type. Input: 40px tall with a 1px input-colored border; focus shows a 2px ring in the ring color. Card: 24px padding, 1px border, sm shadow. Badge: pill, caption type.

## Do's and Don'ts

- **Do:** Design dark mode first: background {color.neutral.950}, card and popover {color.neutral.900}, secondary and muted {color.neutral.800}. Then check light mode.
- **Do:** Use primary ({color.brand.400} dark, {color.brand.700} light) for one main button per view, such as Book or Save trip. Style other actions as secondary or ghost.
- **Do:** Show focus as a 2px ring in the ring token, offset 2px, on every button, input, map chip and itinerary row.
- **Do:** Set Familjen Grotesk only at heading-md (24px) and above, using the weight and negative letterSpacing defined for each style (e.g. display-lg 56px/700/−0.03em).
- **Do:** Set flight numbers, booking references, coordinates and times in JetBrains Mono at code (14px, 400) with tabular figures, so columns align in itinerary tables.
- **Do:** Apply shadow.lg (with the aqua glow) only to the hero destination card and the active map pin.
- **Don't:** Don't use brand teal for errors, cancellations or delays. Use destructive for errors and cancellations, and warning for delays and schedule changes.
- **Don't:** Don't use pure black (#000000) surfaces or pure white (#ffffff) text in dark mode. Use neutral.950 and neutral.50.
- **Don't:** Don't set more than one line of body-md or smaller on accent surfaces (brand.100 light, brand.900 dark). Keep accent for selected itinerary items and short labels.
- **Don't:** Don't use Familjen Grotesk below 24px or in all caps. Use Rubik heading-sm (20px, 600) for smaller headings.
- **Don't:** Don't use muted-foreground for text smaller than caption (12px) or for disabled-looking primary actions. Use the disabled state at 50% opacity instead.
- **Don't:** Don't combine shadow.md and shadow.lg on one surface. In dark mode, separate layers with neutral.950 → neutral.900 → neutral.800 first.
