ChefDash follows a single-source-of-truth architecture: oneDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/ImLukzy/ChefDash/llms.txt
Use this file to discover all available pages before exploring further.
ObservableObject class called GameState owns every piece of mutable data in the application — the active tab, the player’s coin balance, the level list, the shop inventory, and the live burger stack mid-round. ChefDashApp creates this object once, injects it at the root via .environmentObject(), and every view in the tree reads and writes it through @EnvironmentObject var gameState: GameState with no prop-drilling required.
Top-Level View Hierarchy
ContentView sits between the app entry point and all screen-level views. It is the single place in the codebase where screen routing happens — it reads gameState.activeTab and uses a switch statement to decide which view to render. No NavigationStack or NavigationLink is used for primary navigation; the entire routing model is driven by mutating one @Published string property.
Tab Routing via gameState.activeTab
activeTab is declared in GameState as:
ContentView switches on this value to render the correct screen:
gameState.activeTab to one of the valid string values. The full set of recognised values is:
| Value | Destination | Tab bar visible? |
|---|---|---|
"house.fill" | HomeView | ✅ Yes |
"map.fill" | MainMapView | ✅ Yes |
"cart.fill" | ShopView | ✅ Yes |
"profile" | ProfileView | ✅ Yes |
"settings" | SettingsView | ✅ Yes |
"kitchen_round" | RecipesView | ❌ Hidden |
"level_complete" | VictoryView | ❌ Hidden |
The CustomTabBar
CustomTabBar is a floating, arcade-styled navigation bar rendered inside a ZStack in ContentView, overlaid above all screen content. It is explicitly hidden during kitchen_round and level_complete states so that the gameplay and victory screens are unobstructed:
["house.fill", "map.fill", "cart.fill"] — rendered as SF Symbol icon buttons. Tapping a tab animates the transition with a spring:
Color(red: 0.96, green: 0.44, blue: 0.13)) and a subtle circular background at 12% opacity. Inactive tabs use white at 40% opacity, ensuring readability against the dark arcade background. A 4 pt filled dot beneath the icon serves as a minimal active-state indicator.
ChefDashApp sets .preferredColorScheme(.light) on ContentView, but ContentView itself immediately overrides this by calling .preferredColorScheme(.dark) on its root ZStack. The dark override takes precedence in the SwiftUI view tree, so the entire app renders in dark mode regardless of the user’s system appearance setting. This is intentional — the deep-dark arcade background (Color(red: 0.08, green: 0.08, blue: 0.10)) and the floating tab bar are designed exclusively for the dark environment.GameState as the Single Source of Truth
GameState is an ObservableObject class holding every category of app-wide data as @Published properties. The full surface area is:
Navigation
activeTab: String— drives the ContentView screen router.
coins: Int— current coin balance (starts at 150).isHapticsEnabled: Bool— haptic feedback toggle.playerName: String— display name (default:"Chef Novato").playerAvatar: String— emoji avatar (default:"👨🍳").
shopInventory: [ShopItem]— the three consumable power-ups; each item tracksquantityOwned.selectedUpgradesForRound: Set<String>— IDs of consumables the player has queued for the next round; cleared and consumed whenstartNewRound()is called.
levels: [Level]— the full array of 20Levelstructs, built bysetupLevels()atinit().selectedLevelIndex: Int— index intolevelspointing at the level currently being played or previewed.
currentBurgerStack: [String]— emojis the player has tapped so far in the current order.targetRecipeEmojis: [String]— the recipe the player must match.currentRecipeName: String— human-readable name derived from the recipe contents.ordersCompletedInSession: Int— how many orders have been successfully served this round.comboMultiplier: Int— current score multiplier (1–5); increments on success, resets to 1 on error.showPerfectMessage: Bool/showErrorMessage: Bool— transient flags for visual feedback, auto-cleared after 0.8 seconds.
The Two Model Types
Level
A value-type struct conforming to Identifiable. Each Level is immutable except for isUnlocked and starsEarned, which are var properties updated by GameState.finishRound(starsEarned:).
ShopItem
A value-type struct conforming to Identifiable, paired with an UpgradeType enum. The quantityOwned var is mutated when the player buys or consumes a power-up.
Color System — GameColors.swift
All shared UI colours are defined as static properties on a Color extension, forming the “Culinary Pop” design system:
| Property | RGB | Usage |
|---|---|---|
Color.gameBackground | (0.98, 0.97, 0.95) | Cream background for light-mode views |
Color.gameOrange | (0.96, 0.37, 0.05) | Primary action buttons (burnt orange) |
Color.gameYellow | (0.94, 0.69, 0.13) | Mustard-yellow grid accents on HomeView |
Color.gameCardBackground | Color.white | Card surfaces and modal backgrounds |
Color.gameTextDark | (0.22, 0.12, 0.05) | Primary body text (organic dark brown) |
Color.gameDarkBrown | (0.38, 0.20, 0.11) | Price-tag label backgrounds |
Color.gameLightGray | (0.95, 0.94, 0.92) | Ingredient button backgrounds |