// app.jsx — main Tendlet app (with onboarding + user folk replacement)

const NATIVE_SETTINGS_DEFAULTS = {
  "appearance": "light",
  "palette": "cream",
  "density": "regular",
  "homeOrder": "pets",
  "country": "Belgium",
  "language": "System",
  "showFamily": true,
  "showOnboarding": true,
  "spotlightHidden": false,
  "spotlightSource": "library",
  "spotlightCategories": { "fun": true, "care": false, "safety": false }
};

const STORAGE = {
  settings: 'tendlet.demo.settings',
  folks: 'tendlet.demo.folks',
  userName: 'tendlet.demo.userName',
  isDemo: 'tendlet.demo.isDemo',
  photos: 'tendlet.demo.photos',
  careLogs: 'tendlet.demo.careLogs',
  health: 'tendlet.demo.health',
  shop: 'tendlet.demo.shop',
  tasks: 'tendlet.demo.tasks',
  mealWeek: 'tendlet.demo.mealWeek',
  fedMeals: 'tendlet.demo.fedMeals',
};

const DEMO_PALETTES = [
  { id: 'cream', label: 'Cream', colors: ['#315831', '#9E4429', '#F0E7D5'] },
  { id: 'terracotta', label: 'Terracotta', colors: ['#8E2E1B', '#9B3218', '#E2C7B3'] },
  { id: 'pine', label: 'Pine', colors: ['#064F3A', '#704726', '#C7DACB'] },
  { id: 'tide', label: 'Tide', colors: ['#2D5B78', '#276B7D', '#D7E3EB'] },
];

const DEMO_MODES = [
  { id: 'system', label: 'System' },
  { id: 'light', label: 'Light' },
  { id: 'dark', label: 'Dark' },
];

function readDemoJson(keys, fallback) {
  const list = Array.isArray(keys) ? keys : [keys];
  for (const key of list) {
    try {
      const raw = localStorage.getItem(key);
      if (raw) return JSON.parse(raw);
    } catch (e) {}
  }
  return fallback;
}

function writeDemoJson(key, value) {
  try { localStorage.setItem(key, JSON.stringify(value)); } catch (e) {}
  return value;
}

function removeDemoJson(key) {
  try { localStorage.removeItem(key); } catch (e) {}
}

function useNativeSettings(defaults) {
  const [values, setValues] = React.useState(() => ({
    ...defaults,
    ...(readDemoJson(STORAGE.settings, {}) || {}),
  }));
  const setSetting = React.useCallback((keyOrEdits, val) => {
    setValues((prev) => {
      const edits = typeof keyOrEdits === 'string' ? { [keyOrEdits]: val } : (keyOrEdits || {});
      return writeDemoJson(STORAGE.settings, { ...prev, ...edits });
    });
  }, []);
  return [values, setSetting];
}

function DemoThemeControls({ theme, setTheme }) {
  const t = theme || {};
  const set = (key, value) => setTheme && setTheme(key, value);
  return (
    <aside className="demo-controls" aria-label="Demo display options">
      <div className="demo-controls-head">
        <div className="demo-kicker">Demo controls</div>
        <h2>Theme</h2>
      </div>

      <div className="demo-control-group">
        <div className="demo-control-label">Mode</div>
        <div className="demo-mode-row">
          {DEMO_MODES.map((mode) => (
            <button
              key={mode.id}
              type="button"
              className={((t.appearance || 'light') === mode.id ? 'on' : '')}
              onClick={() => set('appearance', mode.id)}
            >
              {mode.label}
            </button>
          ))}
        </div>
      </div>

      <div className="demo-control-group">
        <div className="demo-control-label">Palette</div>
        <div className="demo-palette-grid">
          {DEMO_PALETTES.map((palette) => (
            <button
              key={palette.id}
              type="button"
              className={((t.palette || 'cream') === palette.id ? 'on' : '')}
              onClick={() => set('palette', palette.id)}
            >
              <span className="swatch-strip">{palette.colors.map((c) => <i key={c} style={{ background: c }}></i>)}</span>
              <span>{palette.label}</span>
            </button>
          ))}
        </div>
      </div>
    </aside>
  );
}

function App() {
  const [t, setTheme] = useNativeSettings(NATIVE_SETTINGS_DEFAULTS);
  const [phase, setPhase] = React.useState(t.showOnboarding ? 'onboarding' : 'main');
  const [tab, setTab] = React.useState('today');
  const [detailId, setDetailId] = React.useState(null);
  const [rootSheet, setRootSheet] = React.useState(null);
  const [shopOpen, setShopOpen] = React.useState(false);
  const [folks, setFolks] = React.useState(() => readDemoJson(STORAGE.folks, window.FOLK) || window.FOLK);
  const [tasks, setTasks] = React.useState(() => readDemoJson(STORAGE.tasks, window.TODAY_TASKS) || window.TODAY_TASKS);
  const [userName, setUserName] = React.useState(() => readDemoJson(STORAGE.userName, 'Quentin') || 'Quentin');
  const [isDemo, setIsDemo] = React.useState(() => readDemoJson(STORAGE.isDemo, true) !== false);
  const updateUserName = React.useCallback((name) => {
    setUserName(writeDemoJson(STORAGE.userName, name || 'Quentin'));
  }, []);

  // photos: { [folkId]: dataUrl } — persists across reloads
  const [photos, setPhotos] = React.useState(() => {
    return readDemoJson([STORAGE.photos, 'hearth.photos'], {});
  });
  const setFolkPhoto = React.useCallback((id, dataUrl) => {
    setPhotos((prev) => {
      const next = dataUrl == null ? (() => { const n = { ...prev }; delete n[id]; return n; })()
                                   : { ...prev, [id]: dataUrl };
      return writeDemoJson(STORAGE.photos, next);
    });
  }, []);

  // careLogs: { water: { [folkId]: [{date}] }, weight: { [folkId]: [{date, kg}] } }
  const SEED_LOGS = {
    water: {
      echo:  [{ date: window.daysAgoDate(3) }, { date: window.daysAgoDate(11) }],
      fern:  [{ date: window.daysAgoDate(1) }, { date: window.daysAgoDate(4) }, { date: window.daysAgoDate(8) }],
      ollie: [{ date: window.daysAgoDate(6) }, { date: window.daysAgoDate(14) }],
      sage:  [{ date: window.daysAgoDate(21) }],
    },
    weight: {
      luna: [
        { date: window.daysAgoDate(0),  kg: 1.04 },
        { date: window.daysAgoDate(7),  kg: 1.02 },
        { date: window.daysAgoDate(14), kg: 1.01 },
        { date: window.daysAgoDate(21), kg: 0.98 },
        { date: window.daysAgoDate(28), kg: 0.97 },
        { date: window.daysAgoDate(35), kg: 0.95 },
      ],
      mochi: [
        { date: window.daysAgoDate(2),  kg: 5.2 },
        { date: window.daysAgoDate(34), kg: 5.1 },
        { date: window.daysAgoDate(66), kg: 4.9 },
      ],
      koda:  [
        { date: window.daysAgoDate(5),  kg: 18.3 },
        { date: window.daysAgoDate(40), kg: 18.6 },
        { date: window.daysAgoDate(72), kg: 18.4 },
      ],
    },
  };
  const [careLogs, setCareLogs] = React.useState(() => {
    return readDemoJson([STORAGE.careLogs, 'hearth.careLogs'], SEED_LOGS) || SEED_LOGS;
  });
  const persistLogs = (next) => {
    return writeDemoJson(STORAGE.careLogs, next);
  };
  const logWater = (folkId, entry) => setCareLogs((p) => persistLogs({
    ...p, water: { ...p.water, [folkId]: [entry, ...(p.water[folkId] || [])] }
  }));
  const undoWater = (folkId) => setCareLogs((p) => persistLogs({
    ...p, water: { ...p.water, [folkId]: (p.water[folkId] || []).slice(1) }
  }));
  const logWeight = (folkId, entry) => setCareLogs((p) => persistLogs({
    ...p, weight: { ...p.weight, [folkId]: [entry, ...(p.weight[folkId] || [])] }
  }));

  // Medications: { [folkId]: [...] }; Documents: { [folkId]: [...] }
  // Journals:    { [folkId]: [{ id, date, photoUrl, note }] }
  // Symptoms:    { [folkId]: [{ id, date, symptom, severity, note }] }
  // Vets:        [{ id, type, name, phone, address, note }]
  // FamilyMembers: [{ id, name, email, role, status, lastSeen }]
  // Activity:    [{ id, who, verb, at }]
  // AwayMode:    { active, sitter, startDate, endDate, brief }
  const SEED_HEALTH = {
    meds: {
      mira:  [{ id: 'm1', name: 'API General Cure', dose: '1 packet', freq: 'every other day · 7 days', start: window.daysAgoDate(2), note: 'Treating fin nip + opportunistic infection.' }],
    },
    docs: {
      luna:  [
        { id: 'd1', title: 'Annual vet exam', type: 'vet',  date: window.daysAgoDate(45), note: 'Clean teeth, no scurvy signs.' },
        { id: 'd2', title: 'Adoption paperwork', type: 'legal', date: window.daysAgoDate(820), note: 'Rescue: Cavy Rescue PNW' },
      ],
      mochi: [
        { id: 'd3', title: 'Vaccination record', type: 'vet', date: window.daysAgoDate(120), note: 'FVRCP + rabies, due again next March.' },
        { id: 'd4', title: 'Pet insurance policy', type: 'insurance', date: window.daysAgoDate(380), note: 'Healthy Paws · Plan 250' },
        { id: 'd5', title: 'Microchip', type: 'id', date: window.daysAgoDate(1460), note: '985112004562103' },
      ],
      koda:  [
        { id: 'd6', title: 'Rabies certificate', type: 'vet', date: window.daysAgoDate(200), note: 'Valid 3 years.' },
      ],
    },
    journals: {
      // No seed photos — let users discover the feature via the empty state.
    },
    symptoms: {
      mira:  [
        { id: 's1', date: window.daysAgoDate(3), symptom: 'Fin nip on tail', severity: 'mild', note: 'Tank-mate? Possibly water-quality.' },
        { id: 's2', date: window.daysAgoDate(1), symptom: 'Less interested in food', severity: 'moderate', note: 'Refused pellet at 6pm feeding.' },
      ],
    },
    vets: [
      { id: 'v1', type: 'primary',   name: 'Maple Veterinary Clinic', phone: '+1 555 0103', address: '142 Maple Ave', note: 'Dr. Park — Mon–Sat 8–6.' },
      { id: 'v2', type: 'emergency', name: 'Westside Animal Emergency', phone: '+1 555 0911', address: '88 West Pike', note: '24 / 7, no appointment needed.' },
      { id: 'v3', type: 'poison',    name: 'ASPCA Poison Control', phone: '+1 888 426 4435', note: '$95 consultation fee. Always available.' },
    ],
    family: [
      { id: 'fy', name: 'You',  role: 'you',   status: 'active', lastSeen: window.daysAgoDate(0) },
      { id: 'fa', name: 'Alex', email: 'alex@tendlet.app', role: 'admin', status: 'active',  lastSeen: window.daysAgoDate(0) },
      { id: 'fj', name: 'Jess', email: 'jess@tendlet.app', role: 'carer', status: 'active',  lastSeen: window.daysAgoDate(1) },
    ],
    activity: [
      { id: 'a1', who: 'Alex', verb: 'watered Echo',  at: new Date(Date.now() - 9*3600*1000).toISOString() },
      { id: 'a2', who: 'Jess', verb: 'added a vet note for Luna', at: new Date(Date.now() - 21*3600*1000).toISOString() },
      { id: 'a3', who: 'You',  verb: 'walked Koda',   at: new Date(Date.now() - 2*3600*1000).toISOString() },
      { id: 'a4', who: 'Alex', verb: 'refilled hay',  at: new Date(Date.now() - 30*3600*1000).toISOString() },
    ],
    away: { active: false, sitter: '', startDate: '', endDate: '', brief: '' },
  };
  const [health, setHealth] = React.useState(() => {
    return readDemoJson([STORAGE.health, 'hearth.health'], SEED_HEALTH) || SEED_HEALTH;
  });
  const persistHealth = (next) => {
    return writeDemoJson(STORAGE.health, next);
  };
  const addMed = (folkId, med) => setHealth((p) => persistHealth({
    ...p, meds: { ...p.meds, [folkId]: [{ id: `m-${Date.now()}`, ...med }, ...(p.meds[folkId] || [])] }
  }));
  const removeMed = (folkId, id) => setHealth((p) => persistHealth({
    ...p, meds: { ...p.meds, [folkId]: (p.meds[folkId] || []).filter((m) => m.id !== id) }
  }));
  const addDoc = (folkId, doc) => setHealth((p) => persistHealth({
    ...p, docs: { ...p.docs, [folkId]: [{ id: `d-${Date.now()}`, ...doc }, ...(p.docs[folkId] || [])] }
  }));
  const removeDoc = (folkId, id) => setHealth((p) => persistHealth({
    ...p, docs: { ...p.docs, [folkId]: (p.docs[folkId] || []).filter((d) => d.id !== id) }
  }));
  const addJournal = (folkId, entry) => setHealth((p) => persistHealth({
    ...p, journals: { ...(p.journals || {}), [folkId]: [entry, ...((p.journals || {})[folkId] || [])] }
  }));
  const removeJournal = (folkId, id) => setHealth((p) => persistHealth({
    ...p, journals: { ...(p.journals || {}), [folkId]: ((p.journals || {})[folkId] || []).filter((j) => j.id !== id) }
  }));
  const addSymptom = (folkId, entry) => setHealth((p) => persistHealth({
    ...p, symptoms: { ...(p.symptoms || {}), [folkId]: [entry, ...((p.symptoms || {})[folkId] || [])] }
  }));
  const removeSymptom = (folkId, id) => setHealth((p) => persistHealth({
    ...p, symptoms: { ...(p.symptoms || {}), [folkId]: ((p.symptoms || {})[folkId] || []).filter((s) => s.id !== id) }
  }));
  const addVet = (c) => setHealth((p) => persistHealth({ ...p, vets: [c, ...(p.vets || [])] }));
  const removeVet = (id) => setHealth((p) => persistHealth({ ...p, vets: (p.vets || []).filter((v) => v.id !== id) }));
  const inviteFamily = (m) => setHealth((p) => persistHealth({ ...p, family: [...(p.family || []), m] }));
  const removeFamily = (id) => setHealth((p) => persistHealth({ ...p, family: (p.family || []).filter((f) => f.id !== id) }));
  const updateFamilyRole = (id, role) => setHealth((p) => persistHealth({
    ...p, family: (p.family || []).map((f) => f.id === id ? { ...f, role } : f)
  }));
  const updateAway = (a) => setHealth((p) => persistHealth({ ...p, away: a }));

  // Supplies / shop list
  const [shopItems, setShopItems] = React.useState(() => readDemoJson(STORAGE.shop, window.SHOP || []) || []);
  const persistShop = (next) => writeDemoJson(STORAGE.shop, next);
  const toggleShopLow = (id) => setShopItems((p) => persistShop(
    (p || []).map((it) => it.id === id ? { ...it, low: !it.low } : it)
  ));
  const addShopItem = (item) => setShopItems((p) => persistShop([
    { id: `s-${Date.now()}`, ...item },
    ...(p || []),
  ]));
  const updateShopItem = (id, edits) => setShopItems((p) => persistShop(
    (p || []).map((it) => it.id === id ? { ...it, ...edits } : it)
  ));
  const removeShopItem = (id) => setShopItems((p) => persistShop((p || []).filter((it) => it.id !== id)));

  // Meals demo state
  const [mealWeekStarted, setMealWeekStarted] = React.useState(() => {
    const stored = readDemoJson(STORAGE.mealWeek, { started: false });
    return !!stored.started;
  });
  const startMealWeek = () => {
    setMealWeekStarted(true);
    writeDemoJson(STORAGE.mealWeek, { started: true, startedAt: window.TOOLS_NOW.toISOString() });
  };
  const resetMealWeek = () => {
    setMealWeekStarted(false);
    setFedMeals({});
    writeDemoJson(STORAGE.mealWeek, { started: false });
    writeDemoJson(STORAGE.fedMeals, {});
  };
  const [fedMeals, setFedMeals] = React.useState(() => readDemoJson(STORAGE.fedMeals, {}) || {});
  const toggleFedMeal = (key) => setFedMeals((p) => {
    const next = { ...(p || {}), [key]: !p?.[key] };
    return writeDemoJson(STORAGE.fedMeals, next);
  });

  // Symptom log can pre-fill Ask Tendlet with a vet-summary prompt
  const askWithPrompt = (folk, prompt) => {
    openAsk(folk);
    // The AskTendlet component resets messages on open; we want the prompt to seed the first user message.
    // We use a small ref-based mechanism via a global var picked up next render.
    window.__askPrefill = prompt;
  };

  // Folks decorated with their photoUrl (if any)
  const folksWithPhotos = React.useMemo(
    () => folks.map((f) => ({ ...f, photoUrl: photos[f.id] || null })),
    [folks, photos]
  );

  // Ask Tendlet modal
  const [askOpen, setAskOpen] = React.useState(false);
  const [askFolk, setAskFolk] = React.useState(null);
  const openAsk = (folk) => { setAskFolk(folk); setAskOpen(true); };
  const closeAsk = () => setAskOpen(false);

  // Notification banner
  const [notifTask, setNotifTask] = React.useState(null);
  const triggerNotif = React.useCallback((task) => {
    const t = task || tasks.find((x) => !x.done && (x.id === 't5' || x.id === 't4')) || tasks.find((x) => !x.done);
    if (t) setNotifTask(t);
  }, [tasks]);
  const closeNotif = () => setNotifTask(null);
  const notifComplete = () => {
    if (notifTask) toggleTask(notifTask.id);
    setNotifTask(null);
  };
  const notifSnooze = () => {
    // demo: just close
    setNotifTask(null);
  };

  // task completion → fade out
  const [completing, setCompleting] = React.useState(new Set());
  const completionTimers = React.useRef({});

  const toggleTask = (id) => {
    const cur = tasks.find((x) => x.id === id);
    if (!cur) return;
    if (!cur.done) {
      // mark done + fade
      setTasks((ts) => writeDemoJson(STORAGE.tasks, ts.map((x) => x.id === id ? { ...x, done: true } : x)));
      setCompleting((s) => new Set([...s, id]));
      clearTimeout(completionTimers.current[id]);
      completionTimers.current[id] = setTimeout(() => {
        setCompleting((s) => {
          const n = new Set(s); n.delete(id); return n;
        });
      }, 650);
    } else {
      // undo (reachable from timeline-style views where done tasks still render)
      setTasks((ts) => writeDemoJson(STORAGE.tasks, ts.map((x) => x.id === id ? { ...x, done: false } : x)));
    }
  };

  const addTask = (task) => setTasks((ts) => writeDemoJson(STORAGE.tasks, [...ts, task]));
  const updateTask = (id, edits) => setTasks((ts) => writeDemoJson(STORAGE.tasks, ts.map((x) => x.id === id ? { ...x, ...edits } : x)));
  const removeTask = (id) => setTasks((ts) => writeDemoJson(STORAGE.tasks, ts.filter((x) => x.id !== id)));

  const openDetail = (id) => { setShopOpen(false); setRootSheet(null); setDetailId(id); };
  const closeDetail = () => setDetailId(null);
  const selectTab = (next) => {
    if (next === 'add') {
      setRootSheet('add');
      return;
    }
    setRootSheet(null);
    setShopOpen(false);
    setDetailId(null);
    setTab(next);
  };

  const saveNewFolk = (f) => {
    const stub = {
      id: `u-${Date.now()}`,
      kind: f.kind,
      name: f.name,
      em: f.species.em,
      tint: f.species.tint,
      custom: !!f.species.custom,
      species: f.species.lbl,
      iconKey: f.species.iconKey,
    };
    const hyd = window.hydrateOnboardingFolk([stub]);
    setFolks((arr) => writeDemoJson(STORAGE.folks, [...arr, ...hyd]));
    setTasks((arr) => writeDemoJson(STORAGE.tasks, [...arr, ...window.generateTasksFor(hyd)]));
    setIsDemo(writeDemoJson(STORAGE.isDemo, false));
    setTab('today');
    setShopOpen(false);
  };

  const plantFirst = t.homeOrder === 'plants';

  React.useEffect(() => {
    const preferredDark = typeof window.matchMedia === 'function' && window.matchMedia('(prefers-color-scheme: dark)').matches;
    const resolvedAppearance = t.appearance === 'system' ? (preferredDark ? 'dark' : 'light') : (t.appearance || 'light');
    document.documentElement.setAttribute('data-palette', t.palette || 'cream');
    document.documentElement.setAttribute('data-density', t.density || 'regular');
    document.documentElement.setAttribute('data-appearance', resolvedAppearance);
  }, [t.palette, t.density, t.appearance]);

  const completeOnboarding = ({ name, folks: userFolks }) => {
    if (name) setUserName(writeDemoJson(STORAGE.userName, name));
    if (userFolks && userFolks.length) {
      const hydrated = window.hydrateOnboardingFolk(userFolks);
      setFolks(writeDemoJson(STORAGE.folks, hydrated));
      setTasks(writeDemoJson(STORAGE.tasks, window.generateTasksFor(hydrated)));
      setIsDemo(writeDemoJson(STORAGE.isDemo, false));
    }
    setTheme('showOnboarding', false);
    setPhase('main');
    setTab('today');
    setDetailId(null);
  };

  const restartOnboarding = () => {
    setTheme('showOnboarding', true);
    setPhase('onboarding');
    setDetailId(null);
    setRootSheet(null);
    setShopOpen(false);
  };

  const resetToDemo = () => {
    const demoSettings = { ...NATIVE_SETTINGS_DEFAULTS, showOnboarding: false };
    setFolks(writeDemoJson(STORAGE.folks, window.FOLK));
    setTasks(writeDemoJson(STORAGE.tasks, window.TODAY_TASKS));
    setIsDemo(writeDemoJson(STORAGE.isDemo, true));
    setUserName(writeDemoJson(STORAGE.userName, 'Quentin'));
    setPhotos(writeDemoJson(STORAGE.photos, {}));
    setCareLogs(writeDemoJson(STORAGE.careLogs, SEED_LOGS));
    setHealth(writeDemoJson(STORAGE.health, SEED_HEALTH));
    setShopItems(writeDemoJson(STORAGE.shop, window.SHOP || []));
    setMealWeekStarted(false);
    setFedMeals(writeDemoJson(STORAGE.fedMeals, {}));
    writeDemoJson(STORAGE.mealWeek, { started: false });
    writeDemoJson(STORAGE.settings, demoSettings);
    removeDemoJson('hearth.photos');
    removeDemoJson('hearth.careLogs');
    removeDemoJson('hearth.health');
    setTheme(demoSettings);
    setPhase('main');
    setTab('today');
    setDetailId(null);
    setRootSheet(null);
    setShopOpen(false);
  };

  const clearAllPhotos = () => {
    setPhotos(writeDemoJson(STORAGE.photos, {}));
    removeDemoJson('hearth.photos');
  };

  // pick the active screen
  let screen;
  if (phase === 'onboarding') {
    screen = <window.OnboardingFlow onComplete={completeOnboarding} onDemo={resetToDemo} />;
  } else if (tab === 'today') {
    screen = <window.TodayScreen folks={folksWithPhotos} tasks={tasks} toggleTask={toggleTask} openDetail={openDetail}
                                 completing={completing} plantFirst={plantFirst} family={t.showFamily}
                                 userName={userName} isDemo={isDemo} onAsk={openAsk}
                                 spotlightHidden={t.spotlightHidden}
                                 spotlightSource={t.spotlightSource}
                                 spotlightCategories={t.spotlightCategories}
                                 awayMode={health.away}
                                 familyActivity={health.activity || []}
                                 shopItems={shopItems}
                                 onOpenShop={() => setShopOpen(true)} />;
  } else if (tab === 'folk') {
    screen = <window.FolkScreen folks={folksWithPhotos} openDetail={openDetail} plantFirst={plantFirst} onAdd={() => setRootSheet('folk-add')} />;
  } else if (tab === 'meals') {
    screen = <window.MealsScreen
      folks={folksWithPhotos}
      mealWeekStarted={mealWeekStarted}
      onStartMealWeek={startMealWeek}
      onResetMealWeek={resetMealWeek}
      fedMeals={fedMeals}
      onToggleFed={toggleFedMeal}
      shopItems={shopItems}
      onToggleShopLow={toggleShopLow}
      onOpenShop={() => setShopOpen(true)}
      openDetail={openDetail}
    />;
  } else if (tab === 'profile') {
    screen = <window.ProfileScreen userName={userName} folks={folksWithPhotos}
                                   theme={t} setTheme={setTheme}
                                   onSetUserName={updateUserName}
                                   onResetDemo={resetToDemo}
                                   onRestartOnboarding={restartOnboarding}
                                   onClearPhotos={clearAllPhotos}
                                   tasks={tasks}
                                   vets={health.vets || []}
                                   onAddVet={addVet} onRemoveVet={removeVet}
                                   family={health.family || []}
                                   activity={health.activity || []}
                                   onInviteFamily={inviteFamily}
                                   onRemoveFamily={removeFamily}
                                   onUpdateFamilyRole={updateFamilyRole}
                                   awayMode={health.away}
                                   onUpdateAway={updateAway}
                                   onUpdateTask={updateTask} />;
  }

  const detailSheet = detailId ? (
    <div className="native-sheet-overlay" onClick={closeDetail}>
      <div className="native-nav-sheet full" onClick={(e) => e.stopPropagation()}>
        <window.DetailScreen
          folks={folksWithPhotos}
          folkId={detailId}
          onBack={closeDetail}
          isDemo={isDemo}
          onAsk={openAsk}
          askWithPrompt={askWithPrompt}
          tasks={tasks}
          addTask={addTask}
          removeTask={removeTask}
          setFolkPhoto={setFolkPhoto}
          waterLog={(careLogs.water || {})[detailId] || []}
          weightLog={(careLogs.weight || {})[detailId] || []}
          onLogWater={(e) => logWater(detailId, e)}
          onUndoWater={() => undoWater(detailId)}
          onLogWeight={(e) => logWeight(detailId, e)}
          meds={(health.meds || {})[detailId] || []}
          docs={(health.docs || {})[detailId] || []}
          onAddMed={(m) => addMed(detailId, m)}
          onRemoveMed={(id) => removeMed(detailId, id)}
          onAddDoc={(d) => addDoc(detailId, d)}
          onRemoveDoc={(id) => removeDoc(detailId, id)}
          journal={(health.journals || {})[detailId] || []}
          onAddJournal={(e) => addJournal(detailId, e)}
          onRemoveJournal={(id) => removeJournal(detailId, id)}
          symptoms={(health.symptoms || {})[detailId] || []}
          onAddSymptom={(e) => addSymptom(detailId, e)}
          onRemoveSymptom={(id) => removeSymptom(detailId, id)}
        />
      </div>
    </div>
  ) : null;

  const addSheet = rootSheet === 'add' ? (
    <div className="native-sheet-overlay" onClick={() => setRootSheet(null)}>
      <div className="native-nav-sheet" onClick={(e) => e.stopPropagation()}>
        <window.QuickAddScreen
          folks={folksWithPhotos}
          onBack={() => setRootSheet(null)}
          onLogWater={(folkId, e) => logWater(folkId, e)}
          onLogWeight={(folkId, e) => logWeight(folkId, e)}
          onAddMed={(folkId, m) => addMed(folkId, m)}
          onAddDoc={(folkId, d) => addDoc(folkId, d)}
          onAddJournal={(folkId, e) => addJournal(folkId, e)}
          onAddSymptom={(folkId, e) => addSymptom(folkId, e)}
          onAddRoutine={(task) => addTask(task)}
          onComplete={() => setRootSheet(null)}
        />
      </div>
    </div>
  ) : rootSheet === 'folk-add' ? (
    <div className="native-sheet-overlay" onClick={() => setRootSheet(null)}>
      <div className="native-nav-sheet" onClick={(e) => e.stopPropagation()}>
        <window.AddScreen
          onBack={() => setRootSheet(null)}
          onSave={(f) => { saveNewFolk(f); setRootSheet(null); }}
        />
      </div>
    </div>
  ) : null;

  const shopSheet = shopOpen ? (
    <div className="native-sheet-overlay" onClick={() => setShopOpen(false)}>
      <div className="native-nav-sheet" onClick={(e) => e.stopPropagation()}>
        <window.ShopScreen
          folks={folksWithPhotos}
          items={shopItems}
          onBack={() => setShopOpen(false)}
          onToggleLow={toggleShopLow}
          onAddItem={addShopItem}
          onUpdateItem={updateShopItem}
          onRemoveItem={removeShopItem}
          openDetail={openDetail}
        />
      </div>
    </div>
  ) : null;

  const showChrome = phase === 'main' && !detailId && !rootSheet && !shopOpen;

  return (
    <div className="demo-page">
      <DemoThemeControls theme={t} setTheme={setTheme} />
      <div className="iphone-stage">
        <div className="iphone-device" aria-label="Tendlet iPhone demo">
          <div className="iphone-bezel">
            <div className="iphone-screen">
              <div className="ios-status-bar" aria-hidden="true">
                <span className="ios-time">9:24</span>
                <span className="ios-dynamic-island"></span>
                <span className="ios-status-icons"><span>5G</span><span className="ios-battery"></span></span>
              </div>
              <div className="app-viewport">
                <div className="screen-host" key={phase + '-' + tab} data-screen-label={phase === 'onboarding' ? 'Onboarding' : tab}>
                  {screen}
                </div>
                {showChrome && <window.TabBar tab={tab} setTab={selectTab} />}
                {detailSheet}
                {shopSheet}
                {addSheet}
                {askOpen && <window.AskTendlet open={askOpen} onClose={closeAsk} folks={folksWithPhotos} contextFolk={askFolk} />}
                {notifTask && (
                  <window.NotificationBanner
                    task={notifTask}
                    folk={folksWithPhotos.find((x) => x.id === notifTask.folkId)}
                    onComplete={notifComplete}
                    onSnooze={notifSnooze}
                    onDismiss={closeNotif}
                    onOpen={() => { const t = notifTask; setNotifTask(null); if (t) openDetail(t.folkId); }}
                  />
                )}
              </div>
              <div className="iphone-home-indicator" aria-hidden="true"></div>
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App />);
