:root light tokens — single source of truth
/* LIGHT CONSUMER APP — DESIGN TOKENS */
:root {
  /* Backgrounds */
  --bg-page:        #f7f8fa;   /* page/screen */
  --bg-card:        #ffffff;   /* card surface */
  --bg-elevated:    #ffffff;   /* nav bars */
  --bg-divider:     #e8eaed;   /* hairline */

  /* Text */
  --text-primary:   #1a1d24;   /* headings + body */
  --text-secondary: #5f636e;   /* meta, labels */
  --text-tertiary:  #9ea3ae;   /* placeholder */

  /* Brand */
  --brand-blue:     #2a93c1;   /* links, accents */
  --brand-orange:   #f1420b;   /* CTAs, add-to-cart */

  /* Status chips */
  --status-open:    #16a34a;
  --status-open-bg: #dcfce7;
  --status-closing: #d97706;
  --status-closing-bg: #fef3c7;
  --status-arriving: #2a93c1;
  --status-arriving-bg: #dbeafe;

  /* Radius */
  --r-card: 16px;  --r-btn: 50px;  --r-chip: 100px;

  /* Shadows */
  --shadow-card: 0 2px 12px rgba(26,29,36,0.08), 0 1px 3px rgba(26,29,36,0.06);
  --shadow-float: 0 8px 32px rgba(26,29,36,0.14), 0 2px 8px rgba(26,29,36,0.08);
  --shadow-nav: 0 -1px 0 rgba(26,29,36,0.08), 0 -4px 12px rgba(26,29,36,0.06);

  /* Fonts */
  --font-display: 'Oswald', sans-serif;  /* headings — brand thread */
  --font-body:    'Inter', sans-serif;    /* body */
}
01 · App Bar + Brand Logotype
📍 Midtown, NYC
342 W 42nd St — delivery zone
PureBrain.AI
JR

<div class="app-bar">
  <div class="app-bar__location">
    <div class="app-bar__city">📍 Midtown, NYC <span class="arrow">⌄</span></div>
    <div class="app-bar__street">342 W 42nd St</div>
  </div>
  <!-- Logotype: blue=PureBr+n, orange=ai, dark=.AI (light bg) -->
  <span class="app-logotype">
    <span class="p-br">PureBr</span><span class="p-ai">ai</span>
    <span class="p-n">n</span><span class="p-dot">.AI</span>
  </span>
  <div class="app-bar__avatar">JR</div>
</div>
02 · Search Bar
<div class="search-bar">
  <span class="search-bar__icon">🔍</span>
  <input class="search-bar__input" type="text"
         placeholder="Search trucks, cuisines, dishes…" />
  <button class="search-bar__filter">Filter</button>
</div>
03 · Live Status Chips — 3 states · JS: pulsing dot
Open Now Closing Soon Arriving at 11:30

Green dot pulses (CSS keyframes). Blue dot pulses on arrival. Amber is static.

<!-- Open Now: green, pulsing dot -->
<span class="chip chip--open">
  <span class="chip-dot"></span>Open Now
</span>

<!-- Closing Soon: amber, static -->
<span class="chip chip--closing">
  <span class="chip-dot"></span>Closing Soon
</span>

<!-- Arriving: blue (= brand-blue), pulsing dot -->
<span class="chip chip--arriving">
  <span class="chip-dot"></span>Arriving at 11:30
</span>

/* CSS for pulsing dots:
@keyframes pulse-green {
  0%, 100% { opacity: 1; transform: scale(1); }
  50%       { opacity: 0.5; transform: scale(1.4); }
} */
04 · Cuisine Category Scroll Row · JS: active toggle
🍽️
All
🌮
Tacos
🍔
Burgers
🥗
Bowls
🍜
Ramen
🍖
BBQ
🍦
Dessert
🍣
Sushi
🌱
Vegan
<!-- Horizontal scroll — JS toggles .active class -->
<div class="cuisine-scroll" id="cuisineScroll">
  <div class="cuisine-chip active" data-cuisine="all">
    <div class="cuisine-chip__icon">🍽️</div>
    <div class="cuisine-chip__label">All</div>
  </div>
  <div class="cuisine-chip" data-cuisine="tacos">
    <div class="cuisine-chip__icon">🌮</div>
    <div class="cuisine-chip__label">Tacos</div>
  </div>
  <!-- ...more chips -->
</div>

<script>
// Active toggle: swap .active on click
document.querySelectorAll('.cuisine-chip').forEach(chip => {
  chip.addEventListener('click', () => {
    document.querySelectorAll('.cuisine-chip').forEach(c => c.classList.remove('active'));
    chip.classList.add('active');
    // Emit custom event for filtering: document.dispatchEvent(new CustomEvent('cuisineChange', {detail: chip.dataset.cuisine}))
  });
});
</script>
05 · Truck Card — hero component, full anatomy · JS: add button
[swap for real truck photo]
Open Now
0.3 mi
El Fuego Tacos
4.8 (142)
~12 min wait Mexican
[swap for real truck photo]
Closing Soon
0.6 mi
Prime Smash Co.
4.6 (89)
~8 min wait Burgers
[swap for real truck photo]
Arriving at 11:30
1.1 mi
Green Garden Bowls
4.9 (207)
Order ahead Vegan
<!-- Truck Card anatomy: photo(16:9) → name → rating+distance → wait → cuisine → add -->
<div class="truck-card">
  <div class="truck-card__photo">
    <!-- [swap for real truck photo] — use CSS bg-image or <img> -->
    <div class="truck-card__status">
      <span class="chip chip--open"><span class="chip-dot"></span>Open Now</span>
    </div>
    <div class="truck-card__distance">0.3 mi</div>
  </div>
  <div class="truck-card__body">
    <div class="truck-card__row1">
      <div class="truck-card__name">El Fuego Tacos</div>
      <div class="truck-card__rating"><span class="star">★</span>4.8 (142)</div>
    </div>
    <div class="truck-card__row2">
      <div class="truck-card__meta">
        <span class="truck-card__wait">~12 min wait</span>  <!-- WAIT not delivery -->
        <span class="truck-card__cuisine">Mexican</span>
      </div>
      <button class="btn-add" data-card="1">+</button>
    </div>
  </div>
</div>

<script>
document.querySelectorAll('.btn-add').forEach(btn => {
  btn.addEventListener('click', e => {
    e.stopPropagation();
    btn.textContent = '✓';
    btn.style.background = 'var(--status-open)';
    setTimeout(() => { btn.textContent = '+'; btn.style.background = ''; }, 1400);
  });
});
</script>
06 · Map View — first-class, live truck markers, "trucks near you"
🚚 El Fuego
🚚 Prime Smash
🚚 Green Garden
7 trucks near you
Trucks near you
El Fuego Tacos
0.3 mi · ~12 min wait
Prime Smash Co.
0.6 mi · ~8 min wait
Green Garden
Arriving 11:30
<!-- Map view: CSS grid + road lines + truck markers + user dot + drawer
     In production: replace map-view__grid with Mapbox/Google Maps iframe or canvas.
     Marker positions come from truck lat/lng → CSS left/top via JS coordinate transform. -->
<div class="map-view">
  <div class="map-view__grid"></div>

  <!-- Truck marker -->
  <div class="map-marker" style="left:135px;top:70px">
    <div class="map-marker__bubble open">🚚 El Fuego</div>
    <div class="map-marker__pin open"></div>
  </div>

  <div class="map-marker" style="left:80px;top:185px">
    <div class="map-marker__bubble arriving">🚚 Green Garden</div>
    <div class="map-marker__pin arriving"></div>
  </div>

  <!-- User blue dot -->
  <div class="map-user" style="left:190px;top:160px"></div>

  <div class="map-overlay-pill"><span class="dot">●</span> 7 trucks near you</div>

  <!-- Horizontal mini-card drawer -->
  <div class="map-drawer">
    <div class="map-drawer__handle"></div>
    <div class="map-drawer__title">Trucks near you</div>
    <div class="map-drawer__scroll">
      <div class="map-mini-card"> ... </div>
    </div>
  </div>
</div>
07 · Truck Profile Header + Sticky Menu Tabs · JS: active tab switch
[swap for real truck/food photo]
🤍
El Fuego Tacos
Open Now
★ 4.8 (142 reviews) · 0.3 mi · ~12 min wait
Authentic street tacos made fresh. Al pastor, carnitas, veggie. Best fish tacos in the borough.
<!-- Profile hero + sticky tabs — tabs are sticky:top:0 in real app -->
<div class="profile-hero">
  <!-- [swap for real truck/food photo: background-image on .profile-hero] -->
  <div class="profile-hero__back">←</div>
  <div class="profile-hero__favorite" id="favoriteBtn">🤍</div>
</div>
<div class="profile-info"> ... </div>

<!-- Sticky menu category tabs -->
<div class="menu-tabs" id="menuTabs">
  <div class="menu-tab active" data-tab="popular">Popular</div>
  <div class="menu-tab" data-tab="tacos">Tacos</div>
  <div class="menu-tab" data-tab="sides">Sides</div>
  <div class="menu-tab" data-tab="drinks">Drinks</div>
</div>

<script>
// Sticky tab active switching
document.querySelectorAll('#menuTabs .menu-tab').forEach(tab => {
  tab.addEventListener('click', () => {
    document.querySelectorAll('#menuTabs .menu-tab').forEach(t => t.classList.remove('active'));
    tab.classList.add('active');
    // Scroll to section: document.getElementById('section-' + tab.dataset.tab)?.scrollIntoView({behavior:'smooth'});
  });
});
// Favorite toggle
document.getElementById('favoriteBtn')?.addEventListener('click', function() {
  this.textContent = this.textContent === '🤍' ? '❤️' : '🤍';
});
</script>
08 · Menu Item Row (photo + name + description + price + add)
Popular Items
<div class="menu-item">
  <!-- 72x72 food photo — swap CSS gradient for background-image: url('truck-photo.jpg') -->
  <div class="menu-item__photo"></div>
  <div class="menu-item__body">
    <div class="menu-item__name">Al Pastor Taco (3-pack)</div>
    <div class="menu-item__desc">Marinated pork, pineapple, onion, cilantro, salsa verde.</div>
    <div class="menu-item__price">$11.50</div>
  </div>
  <div class="menu-item__action"><button class="btn-add">+</button></div>
</div>
09 · Bottom Tab Nav (Home, Map, Search, Orders, Profile) · JS: tab switch

Page content area

🏠 Home
🗺️ Map
🔍 Search
📦 Orders 2
👤 Profile
<!-- Bottom Tab Nav: position:fixed in real app (bottom:0) -->
<div class="bottom-nav" id="bottomNav">
  <div class="bottom-nav__tab active" data-tab="home">
    <span class="bottom-nav__icon">🏠</span>
    <span class="bottom-nav__label">Home</span>
  </div>
  <div class="bottom-nav__tab" data-tab="map">
    <span class="bottom-nav__icon">🗺️</span>
    <span class="bottom-nav__label">Map</span>
  </div>
  <div class="bottom-nav__tab" data-tab="search">
    <span class="bottom-nav__icon">🔍</span>
    <span class="bottom-nav__label">Search</span>
  </div>
  <div class="bottom-nav__tab" data-tab="orders" style="position:relative">
    <span class="bottom-nav__icon">📦</span>
    <span class="bottom-nav__label">Orders</span>
    <span class="bottom-nav__badge">2</span>  <!-- orange badge count -->
  </div>
  <div class="bottom-nav__tab" data-tab="profile">
    <span class="bottom-nav__icon">👤</span>
    <span class="bottom-nav__label">Profile</span>
  </div>
</div>

<script>
document.querySelectorAll('#bottomNav .bottom-nav__tab').forEach(tab => {
  tab.addEventListener('click', () => {
    document.querySelectorAll('#bottomNav .bottom-nav__tab').forEach(t => t.classList.remove('active'));
    tab.classList.add('active');
    // Route: window.location.hash = tab.dataset.tab;
  });
});
</script>
10 · Cart / Order Summary · JS: qty increment/decrement
Your Order Edit
2
Al Pastor Taco (3-pack)
$23.00
1
Chips & Guac
$5.50
Subtotal$28.50
Service fee$1.50
Total$30.00
3
View Order
$30.00
<!-- Cart summary with qty buttons -->
<div class="cart-summary">
  <div class="cart-summary__header">Your Order <span class="cart-summary__edit">Edit</span></div>
  <div class="cart-item">
    <div class="cart-item__qty">
      <button class="qty-btn" data-action="dec" data-item="1">−</button>
      <span class="qty-num" id="qty1">2</span>
      <button class="qty-btn" data-action="inc" data-item="1">+</button>
    </div>
    <div class="cart-item__name">Al Pastor Taco (3-pack)</div>
    <div class="cart-item__price" id="price1">$23.00</div>
  </div>
  <div class="cart-totals">
    <div class="cart-totals__total"><span>Total</span><span>$30.00</span></div>
  </div>
</div>

<!-- Floating cart FAB — position:fixed bottom:80px in real app -->
<div class="cart-fab">
  <div class="cart-fab__left">
    <div class="cart-fab__count">3</div>
    <span class="cart-fab__label">View Order</span>
  </div>
  <span class="cart-fab__price">$30.00</span>
</div>

<script>
const items = { 1: { qty: 2, unit: 11.50 }, 2: { qty: 1, unit: 5.50 } };
document.querySelectorAll('.qty-btn').forEach(btn => {
  btn.addEventListener('click', () => {
    const id = btn.dataset.item;
    if (btn.dataset.action === 'inc') items[id].qty++;
    else if (items[id].qty > 0) items[id].qty--;
    document.getElementById('qty'+id).textContent = items[id].qty;
    document.getElementById('price'+id).textContent = '$' + (items[id].qty * items[id].unit).toFixed(2);
    // recalc total + update cart-fab
  });
});
</script>
11 · Order Tracking Card — estimated wait time + step progress
Order in progress
El Fuego Tacos
8
min wait
Confirmed
🔥
Cooking
3
Ready
4
Pick up
<!-- Order tracking: progress bar + wait minutes + step tracker -->
<div class="tracking-card">
  <div class="tracking-card__bar">
    <div class="tracking-card__progress" style="width:55%"></div>  <!-- JS updates width -->
  </div>
  <div class="tracking-card__body">
    <div class="tracking-card__row1">
      <div>
        <div class="tracking-card__status-label">Order in progress</div>
        <div class="tracking-card__title">El Fuego Tacos</div>
      </div>
      <div class="tracking-card__wait">
        <div class="tracking-card__wait-num">8</div>  <!-- WAIT time, not delivery -->
        <div class="tracking-card__wait-label">min wait</div>
      </div>
    </div>
    <div class="tracking-card__steps">
      <div class="tracking-step done">
        <div class="tracking-step__dot">✓</div>
        <div class="tracking-step__label">Confirmed</div>
      </div>
      <div class="tracking-connector done"></div>
      <div class="tracking-step current">
        <div class="tracking-step__dot">🔥</div>
        <div class="tracking-step__label">Cooking</div>
      </div>
      <div class="tracking-connector"></div>
      <div class="tracking-step">...</div>
    </div>
  </div>
</div>
12 · Bottom-Anchored CTA Bar (thumb-zone, primary + secondary actions)

Content above

<!-- CTA Bar: position:fixed bottom:0 in real app. Adjust bottom for safe-area-inset. -->
<div class="cta-bar">
  <button class="btn-secondary">Save for Later</button>
  <button class="btn-primary">🛒 Order Now · $30.00</button>
</div>

/* For real app:
.cta-bar {
  position: fixed;
  bottom: 0; left: 0; right: 0;
  padding-bottom: calc(20px + env(safe-area-inset-bottom));
} */
Brand Thread — how PureBrain stays PureBrain on a light food app
How the brand thread is held on a light/white background

Logotype spans preserved exactly: PureBrain.AI — blue/orange/blue/dark-on-light. The .AI reads as near-black (#1a1d24) on white (vs white on dark). All other color segments identical to the operator app.

Oswald Bold everywhere it matters: truck names, section headers, prices, CTA buttons, tab labels, app bar. This is the brand's personality weight — same font as the dark operator app.

Orange #f1420b for all CTAs: "Add", "Order Now", "View Order" floating cart, active nav tab, active cuisine chip — the action color is the same brand orange throughout.

Blue #2a93c1 for trust signals: links, Edit, arriving status chip (= brand-blue), user location dot, progress accents. Keeps the brand dual-color system alive.

Light because food demands it: #ffffff cards + #f7f8fa page. Food photography reads on white, not dark. This is the design research finding from UberEats/DoorDash: dark = operator tool, light = consumer app. The brand stays PureBrain through typography and color, not background.