/* FOCUS space — Hearth Focus ambient Pomodoro & focus studio.
   Wired to real session tracking and Supabase todos/localStorage.
   Zero hardcoding, complete Web Audio procedural soundscapes,
   clock & timer modes, real analytics and streak calculations. */

function FocusSpace({ tabs, utils }) {
  const DB = window.VaultDB;
  const STORAGE_KEY = 'hearth.focus.production.v1';
  const SESSIONS_KEY = 'hearth.sessions.v1';
  const TODOS_KEY = 'hearth.todos.v1';
  const USER_KEY = 'hearth.username.v1';

  const TAGS = ['Deep work', 'Study', 'Writing', 'Reading', 'Admin', 'Code'];
  const TAG_COLORS = ['#d67f48', '#8fa073', '#b2622d', '#aebf92', '#c67139', '#5b8a99'];
  const DAYS = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
  const MONTHS = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];

  const SOUND_CONFIGS = [
    { id: 'rain', label: 'Rain on glass', type: 'highpass', freq: 520, q: 0.6, gain: 0.5, lfo: 0 },
    { id: 'waves', label: 'Slow waves', type: 'lowpass', freq: 480, q: 0.9, gain: 0.85, lfo: 0.09 },
    { id: 'forest', label: 'Forest floor', type: 'bandpass', freq: 1750, q: 0.7, gain: 0.9, lfo: 0.03 },
    { id: 'cafe', label: 'Corner café', type: 'lowpass', freq: 900, q: 0.7, gain: 0.6, lfo: 0.16 },
    { id: 'brown', label: 'Brown noise', type: 'lowpass', freq: 220, q: 0.5, gain: 0.7, lfo: 0 }
  ];

  const QUOTES = [
    'Small starts count. Sit down, set the timer, and let the work be ordinary.',
    'You do not need a perfect day — only the next twenty-five honest minutes.',
    'Attention is a kindness you give yourself. Spend it somewhere it grows.',
    'Begin badly if you must; momentum forgives a rough first page.',
    'The quiet hours add up faster than the loud plans ever do.',
    'One thing, finished gently, beats five things half-held.',
    'Rest is part of the work. Take the break you earned.',
    'Nobody is watching the first draft. Get it wrong quickly.',
    'Choose the smallest next step you cannot talk yourself out of.',
    'Depth is just shallow work that nobody interrupted.',
    'Put the hard thing first, while the day is still soft.',
    'A timer is a promise you only have to keep for a little while.',
    'You are allowed to work slowly and still be working.',
    'Finish the sentence. Then decide whether to stop.',
    'The desk does not need to be perfect. It needs to be used.',
    'Half an hour of real attention outlives a whole day of skimming.',
    'Protect the first hour and the rest tends to follow.',
    'When it feels heavy, shrink the task until it feels possible.',
    'Boredom is often just the doorway to concentration.',
    'Close the extra tabs. They will still be there, sadly.',
    'Progress is quiet. Trust it anyway.',
    'Stop at a good place, so returning is easy.',
    'One honest hour today beats a heroic plan for tomorrow.',
    'Breathe out. Begin.'
  ];

  // ── State ────────────────────────────────────────────────────────
  const [theme, setTheme] = React.useState('dark');
  const [mode, setMode] = React.useState('clock'); // 'clock' | 'timer'
  const [userName, setUserName] = React.useState('');
  const [intention, setIntention] = React.useState('');
  const [quoteIdx, setQuoteIdx] = React.useState(0);
  const [activeTag, setActiveTag] = React.useState('Deep work');
  const [dur, setDur] = React.useState({ focus: 25, short: 5, long: 60 });
  const [timer, setTimer] = React.useState({
    mode: 'focus', // 'focus' | 'short' | 'long'
    running: false,
    left: 1500,
    endTs: null,
    cycles: 0,
    pauses: 0
  });
  const [tasksOpen, setTasksOpen] = React.useState(false);
  const [soundsOpen, setSoundsOpen] = React.useState(false);
  const [statsOpen, setStatsOpen] = React.useState(false);
  const [statsTab, setStatsTab] = React.useState('day'); // 'day' | 'week' | 'month'
  const [masterVol, setMasterVol] = React.useState(0.85);
  const [vols, setVols] = React.useState({ rain: 0.5, waves: 0.5, forest: 0.45, cafe: 0.4, brown: 0.5 });
  const [activeSounds, setActiveSounds] = React.useState({});
  const [todos, setTodos] = React.useState([]);
  const [draftTask, setDraftTask] = React.useState('');
  const [realSessions, setRealSessions] = React.useState([]);
  const [sampleSessions, setSampleSessions] = React.useState([]);
  const [hasSampleData, setHasSampleData] = React.useState(false);
  const [toast, setToast] = React.useState('');

  // Audio Context refs
  const audioCtxRef = React.useRef(null);
  const masterGainRef = React.useRef(null);
  const noiseBufRef = React.useRef(null);
  const activeChainsRef = React.useRef({});

  // ── Toast Helper ──────────────────────────────────────────────────
  const toastTimerRef = React.useRef(null);
  const flashToast = (msg) => {
    setToast(msg);
    clearTimeout(toastTimerRef.current);
    toastTimerRef.current = setTimeout(() => setToast(''), 2600);
  };

  // ── Load / Save State ─────────────────────────────────────────────
  React.useEffect(() => {
    try {
      const savedName = localStorage.getItem(USER_KEY);
      if (savedName) setUserName(savedName);

      const savedTodos = localStorage.getItem(TODOS_KEY);
      if (savedTodos) setTodos(JSON.parse(savedTodos));

      const savedSessions = localStorage.getItem(SESSIONS_KEY);
      if (savedSessions) setRealSessions(JSON.parse(savedSessions));

      const savedPrefs = localStorage.getItem(STORAGE_KEY);
      if (savedPrefs) {
        const p = JSON.parse(savedPrefs);
        if (p.theme) setTheme(p.theme);
        if (p.mode) setMode(p.mode);
        if (p.intention) setIntention(p.intention);
        if (p.dur) setDur(d => Object.assign({}, d, p.dur));
        if (p.vols) setVols(v => Object.assign({}, v, p.vols));
        if (p.masterVol !== undefined) setMasterVol(p.masterVol);
        if (p.activeTag) setActiveTag(p.activeTag);
      }
    } catch (e) {}

    // Also load from Supabase todos if authenticated
    if (DB && DB.hasSession && DB.hasSession()) {
      DB.sb.from('todos').select('*').order('created_at', { ascending: false })
        .then(({ data, error }) => {
          if (!error && data && data.length > 0) {
            setTodos(data.map(t => ({ id: t.id, text: t.text, done: !!t.completed, created: new Date(t.created_at).getTime() })));
          }
        }).catch(() => {});
    }
  }, []);

  // Save prefs when key state changes
  React.useEffect(() => {
    try {
      localStorage.setItem(STORAGE_KEY, JSON.stringify({
        theme, mode, intention, dur, vols, masterVol, activeTag
      }));
      localStorage.setItem(USER_KEY, userName || '');
      localStorage.setItem(TODOS_KEY, JSON.stringify(todos));
      localStorage.setItem(SESSIONS_KEY, JSON.stringify(realSessions));
    } catch (e) {}
  }, [theme, mode, intention, dur, vols, masterVol, activeTag, userName, todos, realSessions]);

  // ── Web Audio Ambient Synthesizer ─────────────────────────────────
  const initAudio = () => {
    if (audioCtxRef.current) return audioCtxRef.current;
    const AudioContextClass = window.AudioContext || window.webkitAudioContext;
    const ac = new AudioContextClass();
    audioCtxRef.current = ac;

    const mg = ac.createGain();
    mg.gain.value = masterVol;
    mg.connect(ac.destination);
    masterGainRef.current = mg;

    const len = Math.floor(ac.sampleRate * 4);
    const buf = ac.createBuffer(1, len, ac.sampleRate);
    const data = buf.getChannelData(0);
    let last = 0;
    for (let i = 0; i < len; i++) {
      const white = Math.random() * 2 - 1;
      last = (last + 0.02 * white) / 1.02;
      data[i] = last * 3.2;
    }
    noiseBufRef.current = buf;
    return ac;
  };

  const toggleSound = (id) => {
    const ac = initAudio();
    if (ac.state === 'suspended') ac.resume();

    setActiveSounds(prev => {
      const next = { ...prev };
      if (next[id]) {
        const chain = activeChainsRef.current[id];
        if (chain) {
          try { chain.src.stop(); } catch (e) {}
          delete activeChainsRef.current[id];
        }
        delete next[id];
      } else {
        const cfg = SOUND_CONFIGS.find(s => s.id === id);
        if (!cfg) return prev;

        const src = ac.createBufferSource();
        src.buffer = noiseBufRef.current;
        src.loop = true;

        const filter = ac.createBiquadFilter();
        filter.type = cfg.type;
        filter.frequency.value = cfg.freq;
        filter.Q.value = cfg.q;

        const gain = ac.createGain();
        const curVol = vols[id] !== undefined ? vols[id] : 0.5;
        gain.gain.value = curVol * cfg.gain;

        src.connect(filter);
        filter.connect(gain);
        gain.connect(masterGainRef.current);

        if (cfg.lfo) {
          const lfo = ac.createOscillator();
          lfo.frequency.value = cfg.lfo;
          const amt = ac.createGain();
          amt.gain.value = gain.gain.value * 0.55;
          lfo.connect(amt);
          amt.connect(gain.gain);
          lfo.start();
          activeChainsRef.current[id] = { src, filter, gain, lfo, amt, cfg };
        } else {
          activeChainsRef.current[id] = { src, filter, gain, cfg };
        }

        src.start();
        next[id] = true;
      }
      return next;
    });
  };

  const updateSoundVol = (id, val) => {
    setVols(prev => ({ ...prev, [id]: val }));
    const chain = activeChainsRef.current[id];
    if (chain) {
      chain.gain.gain.value = val * chain.cfg.gain;
      if (chain.amt) chain.amt.gain.value = val * chain.cfg.gain * 0.55;
    }
  };

  const updateMasterVol = (val) => {
    setMasterVol(val);
    if (masterGainRef.current) masterGainRef.current.gain.value = val;
  };

  // Cleanup audio on unmount
  React.useEffect(() => {
    return () => {
      Object.values(activeChainsRef.current).forEach(c => {
        try { c.src.stop(); } catch (e) {}
      });
      if (audioCtxRef.current) {
        try { audioCtxRef.current.close(); } catch (e) {}
      }
    };
  }, []);

  // ── Session Helpers ───────────────────────────────────────────────
  const formatMins = (m) => {
    m = Math.round(m);
    if (m >= 60) {
      const h = Math.floor(m / 60);
      const rem = m % 60;
      return h + 'h' + (rem > 0 ? ' ' + rem + 'm' : '');
    }
    return m + 'm';
  };

  const getMidnight = (d) => {
    const x = d ? new Date(d) : new Date();
    x.setHours(0, 0, 0, 0);
    return x;
  };

  const dateKey = (d) => {
    return d.getFullYear() + '-' + String(d.getMonth() + 1).padStart(2, '0') + '-' + String(d.getDate()).padStart(2, '0');
  };

  const hourLabel = (h) => {
    if (h === 0) return '12a';
    if (h < 12) return h + 'a';
    if (h === 12) return '12p';
    return (h - 12) + 'p';
  };

  const timeLabel = (ts) => {
    const d = new Date(ts);
    const h = d.getHours();
    const m = d.getMinutes();
    return (h % 12 === 0 ? 12 : h % 12) + ':' + String(m).padStart(2, '0') + (h < 12 ? 'a' : 'p');
  };

  const getAllSessions = () => hasSampleData ? sampleSessions.concat(realSessions) : realSessions;

  const computeByDay = () => {
    const map = {};
    getAllSessions().forEach(s => {
      const k = dateKey(new Date(s.ts));
      (map[k] = map[k] || []).push(s);
    });
    return map;
  };

  const getDayMins = (map, d) => {
    const list = map[dateKey(d)] || [];
    return list.reduce((sum, s) => sum + s.min, 0);
  };

  const computeStreak = (map) => {
    let count = 0;
    const today = getMidnight();
    for (let i = 0; i < 365; i++) {
      const d = new Date(today.getTime() - i * 86400000);
      if (getDayMins(map, d) > 0) {
        count++;
      } else if (i > 0) {
        break;
      }
    }
    return count;
  };

  const compute30DayAvg = (map) => {
    const today = getMidnight();
    let total = 0;
    for (let i = 1; i <= 30; i++) {
      total += getDayMins(map, new Date(today.getTime() - i * 86400000));
    }
    return Math.max(25, Math.round(total / 30 / 5) * 5);
  };

  const logSession = (min, pauses) => {
    if (min < 1) return;
    const session = {
      id: 'sess_' + Date.now(),
      ts: Date.now() - min * 60000,
      min: Math.round(min),
      tag: activeTag || 'Deep work',
      pauses: pauses || 0,
      tasks: 0
    };
    setRealSessions(prev => [...prev, session]);
    flashToast(formatMins(min) + ' focused on ' + session.tag + ' logged.');
  };

  // ── Timer Actions ─────────────────────────────────────────────────
  const getModeSecs = (m) => (m === 'focus' ? dur.focus : m === 'short' ? dur.short : dur.long) * 60;

  const toggleTimer = () => {
    setTimer(prev => {
      if (prev.running) {
        return { ...prev, running: false, endTs: null, pauses: prev.pauses + 1 };
      } else {
        return { ...prev, running: true, endTs: Date.now() + prev.left * 1000 };
      }
    });
  };

  const resetTimer = () => {
    setTimer(prev => ({
      ...prev,
      running: false,
      endTs: null,
      left: getModeSecs(prev.mode),
      pauses: 0
    }));
  };

  const logPartialSession = () => {
    const total = getModeSecs(timer.mode);
    const used = Math.floor((total - timer.left) / 60);
    if (used >= 1) {
      logSession(used, timer.pauses);
    }
    setTimer(prev => ({
      ...prev,
      mode: 'focus',
      left: getModeSecs('focus'),
      running: false,
      endTs: null,
      pauses: 0
    }));
  };

  const skipBreak = () => {
    if (timer.mode === 'focus') return;
    setTimer(prev => ({
      ...prev,
      mode: 'focus',
      left: getModeSecs('focus'),
      running: false,
      endTs: null,
      pauses: 0
    }));
    flashToast('Break skipped. Ready for round ' + ((timer.cycles % 4) + 1) + '.');
  };

  const completeSession = () => {
    if (timer.mode === 'focus') {
      logSession(dur.focus, timer.pauses);
      const nextCycles = timer.cycles + 1;
      const nextMode = (nextCycles % 4 === 0) ? 'long' : 'short';
      setTimer({
        mode: nextMode,
        left: getModeSecs(nextMode),
        running: false,
        endTs: null,
        cycles: nextCycles,
        pauses: 0
      });
      flashToast(nextCycles % 4 === 0 ? '4 rounds finished! Enjoy your long break.' : 'Round ' + (nextCycles % 4) + ' complete. Take a short break.');
    } else {
      setTimer(prev => ({
        ...prev,
        mode: 'focus',
        left: getModeSecs('focus'),
        running: false,
        endTs: null,
        pauses: 0
      }));
      flashToast('Break over. Begin your next focus session.');
    }
  };

  // Timer tick
  React.useEffect(() => {
    const iv = setInterval(() => {
      setTimer(prev => {
        if (prev.running && prev.endTs) {
          const left = Math.max(0, Math.round((prev.endTs - Date.now()) / 1000));
          if (left <= 0) {
            completeSession();
            return prev;
          }
          return { ...prev, left };
        }
        return prev;
      });
    }, 250);
    return () => clearInterval(iv);
  }, [dur, timer.endTs, timer.running, timer.mode, timer.cycles, timer.pauses]);

  // Keyboard Shortcuts
  React.useEffect(() => {
    const onKey = (e) => {
      const tag = (e.target && e.target.tagName || '').toLowerCase();
      if (tag === 'input' || tag === 'textarea' || e.target.isContentEditable) {
        if (e.key === 'Escape') e.target.blur();
        return;
      }
      const k = e.key.toLowerCase();
      if (e.key === ' ') {
        e.preventDefault();
        toggleTimer();
        if (mode === 'clock') setMode('timer');
      } else if (k === 'escape') {
        setStatsOpen(false); setTasksOpen(false); setSoundsOpen(false);
      } else if (k === 't') {
        setTheme(th => th === 'dark' ? 'light' : 'dark');
      } else if (k === 's') {
        setStatsOpen(st => !st);
      } else if (k === 'c') {
        setMode('clock');
      } else if (k === 'f') {
        setMode('timer');
      } else if (k === 'q') {
        setQuoteIdx(i => (i + 1) % QUOTES.length);
      } else if (k === 'x') {
        skipBreak();
      } else if (k === '1') {
        setTasksOpen(o => !o);
      } else if (k === '2') {
        setSoundsOpen(o => !o);
      }
    };
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, [mode, timer]);

  // ── Tasks Operations ──────────────────────────────────────────────
  const addTask = (e) => {
    e.preventDefault();
    const text = draftTask.trim();
    if (!text) return;
    const newTask = { id: 'task_' + Date.now(), text, done: false, created: Date.now() };
    setTodos(prev => [newTask, ...prev]);
    setDraftTask('');

    // Sync to Supabase if authed
    if (DB && DB.hasSession && DB.hasSession()) {
      DB.sb.from('todos').insert([{ user_id: DB.USER_ID, text, completed: false }]).catch(() => {});
    }
  };

  const toggleTodo = (id) => {
    setTodos(prev => prev.map(t => {
      if (t.id === id) {
        const nextDone = !t.done;
        if (DB && DB.hasSession && DB.hasSession()) {
          DB.sb.from('todos').update({ completed: nextDone }).eq('id', id).catch(() => {});
        }
        return { ...t, done: nextDone };
      }
      return t;
    }));
  };

  const deleteTodo = (id) => {
    setTodos(prev => prev.filter(t => t.id !== id));
    if (DB && DB.hasSession && DB.hasSession()) {
      DB.sb.from('todos').delete().eq('id', id).catch(() => {});
    }
  };

  // ── Sample History Generator ──────────────────────────────────────
  const generateSampleSessions = () => {
    const out = [];
    const today = getMidnight();
    let s = 123456789;
    const rand = () => { s = (s * 16807) % 2147483647; return (s - 1) / 2147483646; };
    for (let d = 30; d >= 0; d--) {
      const day = new Date(today.getTime() - d * 86400000);
      const isWeekend = day.getDay() === 0 || day.getDay() === 6;
      if (rand() > (isWeekend ? 0.4 : 0.85)) continue;
      const count = Math.floor(1 + rand() * 4);
      for (let i = 0; i < count; i++) {
        const h = Math.floor(8 + rand() * 12);
        const min = [15, 20, 25, 25, 30, 45, 50][Math.floor(rand() * 7)];
        out.push({
          id: 'samp_' + d + '_' + i,
          ts: new Date(day.getFullYear(), day.getMonth(), day.getDate(), h, Math.floor(rand() * 55)).getTime(),
          min,
          tag: TAGS[Math.floor(rand() * TAGS.length)],
          pauses: Math.floor(rand() * 2),
          tasks: Math.floor(rand() * 2)
        });
      }
    }
    return out.sort((a, b) => a.ts - b.ts);
  };

  // ── Computations for Rendering ────────────────────────────────────
  const now = new Date();
  const h = now.getHours();
  const m = now.getMinutes();
  const timeStr = (h % 12 === 0 ? 12 : h % 12) + ':' + String(m).padStart(2, '0');
  const meridiem = h < 12 ? 'am' : 'pm';
  const dateStr = DAYS[now.getDay()] + 'day, ' + MONTHS[now.getMonth()] + ' ' + now.getDate();
  const greetWord = h < 5 ? 'Still up' : h < 12 ? 'Good morning' : h < 17 ? 'Good afternoon' : h < 22 ? 'Good evening' : 'Winding down';
  const greeting = userName.trim() ? greetWord + ', ' + userName.trim() : greetWord;

  const minutesSince9am = Math.max(0, Math.min(840, h * 60 + m - 540));
  const dayPct = Math.round((minutesSince9am / 840) * 100);

  const byDayMap = computeByDay();
  const todayMins = getDayMins(byDayMap, getMidnight());
  const streak = computeStreak(byDayMap);
  const refGoal = compute30DayAvg(byDayMap);

  const timerTotal = getModeSecs(timer.mode) || 1;
  const timerMins = Math.floor(timer.left / 60);
  const timerSecs = timer.left % 60;
  const timerDigits = timerMins + ':' + String(timerSecs).padStart(2, '0');
  const timerPct = Math.max(0, Math.min(100, Math.round(((timerTotal - timer.left) / timerTotal) * 100)));
  const usedMins = Math.floor((timerTotal - timer.left) / 60);

  const openTasksCount = todos.filter(t => !t.done).length;
  const playingSoundsCount = Object.keys(activeSounds).length;

  // ── Render ────────────────────────────────────────────────────────
  return React.createElement('div', {
    className: 'space-root hearth-space-root',
    'data-theme': theme,
    'data-voice': 'terracotta',
    style: {
      position: 'relative',
      minHeight: '100%',
      display: 'flex',
      flexDirection: 'column',
      background: 'var(--color-bg)',
      color: 'var(--color-text)',
      overflowX: 'hidden'
    }
  },
    // Topbar
    React.createElement(window.SpaceTopbar, { tabs, utils },
      React.createElement('div', { style: { display: 'flex', alignItems: 'center', gap: '8px', margin: '0 8px' } },
        // Mode switch
        React.createElement('div', {
          style: {
            display: 'flex', gap: '4px', padding: '3px', borderRadius: '999px',
            background: 'var(--h-glass)', border: '1px solid var(--color-divider)'
          }
        },
          React.createElement('button', {
            type: 'button', className: 'btn',
            style: {
              fontSize: '12px', fontWeight: 800, padding: '5px 14px',
              background: mode === 'clock' ? 'var(--color-accent)' : 'transparent',
              color: mode === 'clock' ? 'var(--color-bg)' : 'var(--color-text)'
            },
            onClick: () => setMode('clock')
          }, 'Clock'),
          React.createElement('button', {
            type: 'button', className: 'btn',
            style: {
              fontSize: '12px', fontWeight: 800, padding: '5px 14px',
              background: mode === 'timer' ? 'var(--color-accent)' : 'transparent',
              color: mode === 'timer' ? 'var(--color-bg)' : 'var(--color-text)'
            },
            onClick: () => setMode('timer')
          }, 'Timer')),

        // Tasks button
        React.createElement('button', {
          type: 'button', className: 'btn btn-secondary',
          style: {
            gap: '6px', fontSize: '12px', fontWeight: 700, padding: '6px 12px',
            background: tasksOpen ? 'var(--color-accent)' : 'var(--h-glass)',
            color: tasksOpen ? 'var(--color-bg)' : 'var(--color-text)'
          },
          onClick: () => setTasksOpen(o => !o)
        },
          React.createElement('span', {
            style: { width: '6px', height: '6px', borderRadius: '50%', background: 'currentColor', opacity: openTasksCount ? 1 : 0.3 }
          }),
          React.createElement('span', null, 'Tasks')),

        // Sounds button
        React.createElement('button', {
          type: 'button', className: 'btn btn-secondary',
          style: {
            gap: '6px', fontSize: '12px', fontWeight: 700, padding: '6px 12px',
            background: soundsOpen ? 'var(--color-accent)' : 'var(--h-glass)',
            color: soundsOpen ? 'var(--color-bg)' : 'var(--color-text)'
          },
          onClick: () => setSoundsOpen(o => !o)
        },
          React.createElement('span', {
            style: { width: '6px', height: '6px', borderRadius: '50%', background: 'currentColor', opacity: playingSoundsCount ? 1 : 0.3 }
          }),
          React.createElement('span', null, 'Sounds')),

        // Stats button
        React.createElement('button', {
          type: 'button', className: 'btn btn-secondary',
          style: { gap: '6px', fontSize: '12px', fontWeight: 700, padding: '6px 12px' },
          onClick: () => setStatsOpen(true)
        },
          React.createElement(Icons.clock, { size: 13 }),
          React.createElement('span', null, formatMins(todayMins) + ' today')),

        // Theme toggle
        React.createElement('button', {
          type: 'button', className: 'btn btn-icon btn-secondary',
          style: { width: '32px', height: '32px' },
          onClick: () => setTheme(th => th === 'dark' ? 'light' : 'dark'),
          title: 'Toggle theme'
        }, React.createElement(theme === 'dark' ? Icons.sun : Icons.moon, { size: 14 }))
      )
    ),

    // Space Body
    React.createElement('div', {
      className: 'space-body',
      style: { position: 'relative', flex: 1, display: 'flex', flexDirection: 'column', overflow: 'hidden' }
    },
      // Ambient drifting auras
      React.createElement('div', {
        'aria-hidden': 'true',
        style: { position: 'absolute', inset: '-20%', pointerEvents: 'none', zIndex: 0, filter: 'blur(80px)', opacity: 0.65 }
      },
        React.createElement('div', {
          style: {
            position: 'absolute', left: '4%', top: '6%', width: '46vw', height: '46vw', minWidth: '280px', minHeight: '280px',
            borderRadius: '50%', background: 'radial-gradient(circle at 50% 50%, var(--color-accent) 0%, transparent 68%)',
            opacity: 0.5, animation: 'hDrift1 34s ease-in-out infinite'
          }
        }),
        React.createElement('div', {
          style: {
            position: 'absolute', right: '2%', top: '22%', width: '40vw', height: '40vw', minWidth: '240px', minHeight: '240px',
            borderRadius: '50%', background: 'radial-gradient(circle at 50% 50%, var(--color-accent-2) 0%, transparent 68%)',
            opacity: 0.45, animation: 'hDrift2 46s ease-in-out infinite'
          }
        }),
        React.createElement('div', {
          style: {
            position: 'absolute', left: '26%', bottom: '-6%', width: '52vw', height: '40vw', minWidth: '300px', minHeight: '240px',
            borderRadius: '50%', background: 'radial-gradient(circle at 50% 50%, var(--color-accent) 0%, transparent 70%)',
            opacity: 0.28, animation: 'hDrift3 58s ease-in-out infinite'
          }
        })
      ),

      // Quote block
      React.createElement('div', {
        style: {
          position: 'absolute', left: 'clamp(16px, 4vw, 40px)', top: '20px', zIndex: 5,
          width: 'min(300px, 38vw)', minWidth: '160px', textAlign: 'left'
        }
      },
        React.createElement('p', {
          style: {
            margin: '0 0 6px', fontSize: 'clamp(12px, 1.1vw, 14px)', lineHeight: 1.5,
            fontWeight: 500, fontStyle: 'italic', color: 'color-mix(in srgb, var(--color-text) 78%, transparent)'
          }
        }, QUOTES[quoteIdx % QUOTES.length]),
        React.createElement('button', {
          type: 'button', className: 'btn btn-ghost',
          style: { fontSize: '10px', letterSpacing: '0.12em', textTransform: 'uppercase', color: 'var(--h-ink-accent)', fontWeight: 800, padding: 0 },
          onClick: () => setQuoteIdx(i => (i + 1) % QUOTES.length)
        }, 'another')
      ),

      // Hero Container
      React.createElement('main', {
        style: {
          position: 'relative', zIndex: 2, flex: 1, display: 'flex', flexDirection: 'column',
          alignItems: 'center', justifyContent: 'center', gap: 'clamp(10px, 2vh, 22px)',
          padding: 'clamp(10px, 2vh, 24px) clamp(16px, 5vw, 48px)', textAlign: 'center'
        }
      },
        // CLOCK MODE
        mode === 'clock' ? React.createElement('div', {
          style: { display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 'clamp(8px, 1.6vh, 18px)', width: '100%', animation: 'hRise 0.6s cubic-bezier(.2,.8,.2,1) both' }
        },
          React.createElement('div', { style: { display: 'flex', alignItems: 'center', gap: '8px' } },
            React.createElement('p', {
              style: { margin: 0, fontSize: 'clamp(16px, 2vw, 22px)', fontWeight: 600, color: 'color-mix(in srgb, var(--color-text) 68%, transparent)', cursor: 'pointer' },
              title: 'Click to edit your name',
              onClick: () => {
                const name = prompt('What is your name for focus greeting?', userName);
                if (name !== null) setUserName(name.trim());
              }
            }, greeting),
            React.createElement('button', {
              type: 'button', className: 'btn btn-ghost', style: { padding: '2px 6px', opacity: 0.6 }, title: 'Edit name',
              onClick: () => {
                const name = prompt('What is your name for focus greeting?', userName);
                if (name !== null) setUserName(name.trim());
              }
            }, React.createElement(Icons.edit, { size: 12 }))
          ),
          React.createElement('div', { style: { display: 'flex', alignItems: 'flex-start', justifyContent: 'center', gap: 'clamp(6px, 1vw, 14px)' } },
            React.createElement('span', { style: { fontSize: 'clamp(80px, 20vw, 240px)', fontWeight: 900, lineHeight: 0.82, letterSpacing: '-0.06em', fontVariantNumeric: 'tabular-nums' } }, timeStr),
            React.createElement('span', { style: { fontSize: 'clamp(13px, 1.5vw, 20px)', fontWeight: 800, letterSpacing: '0.16em', textTransform: 'uppercase', paddingTop: 'clamp(8px, 1.4vw, 18px)', color: 'var(--h-ink-accent)' } }, meridiem)
          ),
          React.createElement('p', { style: { margin: 0, fontSize: 'clamp(11px, 1.2vw, 13px)', fontWeight: 700, letterSpacing: '0.2em', textTransform: 'uppercase', color: 'color-mix(in srgb, var(--color-text) 62%, transparent)' } }, dateStr),
          // Day Bar
          React.createElement('div', { style: { display: 'flex', alignItems: 'center', gap: '12px', width: 'min(440px, 84vw)', marginTop: 'clamp(4px, 1.2vh, 12px)' } },
            React.createElement('div', { style: { flex: 1, height: '4px', borderRadius: '999px', background: 'color-mix(in srgb, var(--color-text) 12%, transparent)', overflow: 'hidden' } },
              React.createElement('div', { style: { height: '100%', borderRadius: '999px', background: 'var(--color-accent-2)', width: dayPct + '%', transition: 'width 0.4s ease' } })
            ),
            React.createElement('span', { style: { fontSize: '11px', fontWeight: 700, letterSpacing: '0.07em', textTransform: 'uppercase', whiteSpace: 'nowrap', color: 'color-mix(in srgb, var(--color-text) 62%, transparent)' } }, dayPct + '% of day')
          ),
          // Intention input
          React.createElement('div', { style: { marginTop: '10px', width: 'min(380px, 84vw)' } },
            React.createElement('input', {
              type: 'text', className: 'input', placeholder: 'Set a focus intention for today…',
              value: intention, onChange: (e) => setIntention(e.target.value),
              style: { textAlign: 'center', background: 'var(--h-glass)', backdropFilter: 'blur(14px)', fontWeight: 600, fontSize: '13px' }
            }))
        ) : null,

        // TIMER MODE
        mode === 'timer' ? React.createElement('div', {
          style: { display: 'flex', justifyContent: 'center', width: '100%', animation: 'hRise 0.5s cubic-bezier(.2,.8,.2,1) both' }
        },
          React.createElement('div', { style: { display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 'clamp(12px, 2.2vh, 26px)', width: '100%', maxWidth: '720px' } },
            React.createElement('div', { style: { display: 'flex', alignItems: 'baseline', gap: '10px', flexWrap: 'wrap', justifyContent: 'center' } },
              React.createElement('span', { style: { fontSize: '16px', fontWeight: 900, letterSpacing: '-0.02em', fontVariantNumeric: 'tabular-nums' } },
                timeStr,
                React.createElement('span', { style: { fontSize: '11px', fontWeight: 800, letterSpacing: '0.1em', textTransform: 'uppercase', color: 'var(--h-ink-accent)' } }, meridiem)),
              React.createElement('span', { style: { fontSize: '10px', fontWeight: 700, letterSpacing: '0.16em', textTransform: 'uppercase', color: 'color-mix(in srgb, var(--color-text) 62%, transparent)' } }, dateStr)),

            // Tag selector
            React.createElement('div', { style: { display: 'flex', alignItems: 'center', gap: '6px', flexWrap: 'wrap', justifyContent: 'center' } },
              React.createElement('span', { style: { fontSize: '11px', fontWeight: 700, textTransform: 'uppercase', letterSpacing: '0.1em', color: 'color-mix(in srgb, var(--color-text) 50%, transparent)', marginRight: '4px' } }, 'Tag:'),
              React.createElement('div', { style: { display: 'flex', gap: '4px', borderRadius: '999px', background: 'var(--h-glass)', padding: '3px', border: '1px solid var(--color-divider)' } },
                TAGS.map((tag, idx) => React.createElement('button', {
                  key: tag, type: 'button', className: 'btn',
                  style: {
                    fontSize: '11px', fontWeight: 700, padding: '4px 10px',
                    background: activeTag === tag ? TAG_COLORS[idx % TAG_COLORS.length] : 'transparent',
                    color: activeTag === tag ? '#ffffff' : 'var(--color-text)'
                  },
                  onClick: () => setActiveTag(tag)
                }, tag)))),

            React.createElement('span', { style: { fontSize: '11px', fontWeight: 800, letterSpacing: '0.2em', textTransform: 'uppercase', color: 'var(--h-ink-accent)' } },
              timer.mode === 'focus' ? 'Round ' + ((timer.cycles % 4) + 1) + ' of 4 · ' + dur.focus + ' min' : (timer.mode === 'short' ? 'Short break · ' + dur.short + ' min' : 'Long break · ' + dur.long + ' min')),

            React.createElement('span', { style: { fontSize: 'clamp(90px, 19vw, 230px)', fontWeight: 900, lineHeight: 0.82, letterSpacing: '-0.06em', fontVariantNumeric: 'tabular-nums' } }, timerDigits),

            // Progress bar
            React.createElement('div', { style: { width: 'min(580px, 86%)', height: '8px', borderRadius: '999px', background: 'color-mix(in srgb, var(--color-text) 9%, transparent)', border: '1px solid var(--color-divider)', overflow: 'hidden' } },
              React.createElement('div', { style: { height: '100%', borderRadius: '999px', background: 'var(--color-accent)', width: timerPct + '%', transition: 'width 0.3s linear' } })),

            // Action buttons
            React.createElement('div', { style: { display: 'flex', alignItems: 'center', gap: '10px', flexWrap: 'wrap', justifyContent: 'center' } },
              React.createElement('button', {
                type: 'button', className: 'btn btn-primary', style: { fontSize: '14px', fontWeight: 800, padding: '12px 34px' },
                onClick: toggleTimer
              }, timer.running ? 'Pause' : (timer.left < timerTotal ? 'Resume' : (timer.mode === 'focus' ? 'Start focus' : 'Start break'))),

              !timer.running && timer.left < timerTotal && timer.mode === 'focus' && usedMins >= 1 ? React.createElement('button', {
                type: 'button', className: 'btn btn-secondary', style: { fontSize: '13px', fontWeight: 700, borderColor: 'var(--color-accent)', padding: '11px 20px' },
                onClick: logPartialSession
              }, 'Log ' + formatMins(usedMins) + ' & reset') : null,

              timer.mode !== 'focus' ? React.createElement('button', {
                type: 'button', className: 'btn btn-secondary', style: { fontSize: '13px', fontWeight: 700, padding: '11px 20px' },
                onClick: skipBreak
              }, 'Skip break') : null,

              React.createElement('button', {
                type: 'button', className: 'btn btn-secondary', style: { fontSize: '13px', fontWeight: 700, padding: '11px 20px' },
                onClick: resetTimer
              }, 'Reset')),

            // Round dots & used line
            React.createElement('div', { style: { display: 'flex', alignItems: 'center', gap: '14px', flexWrap: 'wrap', justifyContent: 'center', marginTop: '2px' } },
              React.createElement('div', { style: { display: 'flex', gap: '8px' } },
                [0, 1, 2, 3].map(i => React.createElement('span', {
                  key: i,
                  style: {
                    width: '10px', height: '10px', borderRadius: '50%', background: 'var(--color-accent)',
                    opacity: (timer.cycles % 4) > i ? 1 : 0.22,
                    boxShadow: (timer.cycles % 4) === i && timer.mode === 'focus' ? '0 0 0 2px var(--color-accent)' : 'none'
                  }
                }))),
              React.createElement('span', { style: { fontSize: '11px', fontWeight: 700, letterSpacing: '0.05em', color: 'color-mix(in srgb, var(--color-text) 68%, transparent)' } },
                timer.running ? formatMins(usedMins) + ' in · ' + timer.pauses + (timer.pauses === 1 ? ' pause' : ' pauses') : (timer.left < timerTotal ? 'stopped at ' + formatMins(usedMins) + ' · ' + timer.pauses + (timer.pauses === 1 ? ' pause' : ' pauses') : dur.focus + '-minute blocks · ' + timer.cycles + ' completed this sitting'))
            )
          )
        ) : null
      ),

      // Ambient Sounds Panel
      soundsOpen ? React.createElement('div', {
        style: { position: 'relative', zIndex: 15, display: 'flex', justifyContent: 'center', padding: '0 clamp(12px, 4vw, 40px)', marginBottom: '16px' }
      },
        React.createElement('div', {
          className: 'card elev-lg',
          style: { width: 'min(500px, 100%)', padding: 'var(--space-4)', gap: 'var(--space-3)', background: 'var(--h-glass)', backdropFilter: 'blur(24px)', border: '1px solid var(--color-divider)', animation: 'hRise 0.25s ease both' }
        },
          React.createElement('div', { style: { display: 'flex', alignItems: 'center', gap: '10px' } },
            React.createElement('h4', { style: { margin: 0, fontSize: '15px', fontWeight: 800, flex: 1, textAlign: 'left' } }, 'Ambience'),
            React.createElement('span', { style: { fontSize: '11px', letterSpacing: '0.08em', textTransform: 'uppercase', color: 'color-mix(in srgb, var(--color-text) 50%, transparent)', fontWeight: 700 } }, playingSoundsCount + ' playing'),
            React.createElement('button', {
              type: 'button', className: 'btn btn-icon btn-secondary', style: { width: '28px', height: '28px' },
              onClick: () => setSoundsOpen(false)
            }, React.createElement(Icons.x, { size: 13 }))),

          React.createElement('div', { style: { display: 'flex', flexDirection: 'column', gap: '10px', textAlign: 'left' } },
            SOUND_CONFIGS.map(cfg => {
              const isPlaying = !!activeSounds[cfg.id];
              const curVol = vols[cfg.id] !== undefined ? vols[cfg.id] : 0.5;
              return React.createElement('div', { key: cfg.id, style: { display: 'flex', alignItems: 'center', gap: '12px' } },
                React.createElement('button', {
                  type: 'button', className: 'btn',
                  style: {
                    width: '130px', justifyContent: 'flex-start', fontSize: '13px', fontWeight: 700, padding: '7px 12px',
                    background: isPlaying ? 'var(--color-accent)' : 'transparent',
                    color: isPlaying ? 'var(--color-bg)' : 'var(--color-text)',
                    border: '1px solid var(--color-divider)'
                  },
                  onClick: () => toggleSound(cfg.id)
                }, cfg.label),
                React.createElement('input', {
                  type: 'range', min: 0, max: 1, step: 0.01, value: curVol,
                  style: { flex: 1, minWidth: 0, opacity: isPlaying ? 1 : 0.4 },
                  onChange: (e) => updateSoundVol(cfg.id, parseFloat(e.target.value))
                }));
            }),
            React.createElement('div', { style: { display: 'flex', alignItems: 'center', gap: '12px', marginTop: '6px', paddingTop: '10px', borderTop: '1px solid var(--color-divider)' } },
              React.createElement('span', { style: { width: '130px', fontSize: '11px', letterSpacing: '0.1em', textTransform: 'uppercase', color: 'color-mix(in srgb, var(--color-text) 55%, transparent)', fontWeight: 700 } }, 'Master Volume'),
              React.createElement('input', {
                type: 'range', min: 0, max: 1, step: 0.01, value: masterVol,
                style: { flex: 1, minWidth: 0 },
                onChange: (e) => updateMasterVol(parseFloat(e.target.value))
              })))
        )) : null,

      // Tasks Slide-Over Drawer
      tasksOpen ? React.createElement('aside', {
        style: {
          position: 'fixed', top: 0, right: 0, bottom: 0, zIndex: 30, width: 'min(360px, 88vw)',
          display: 'flex', flexDirection: 'column', gap: 'var(--space-3)', padding: 'clamp(18px, 3vh, 28px) var(--space-4)',
          textAlign: 'left', background: 'var(--h-glass)', backdropFilter: 'blur(28px)',
          borderLeft: '1px solid var(--color-divider)', boxShadow: 'var(--shadow-lg)', animation: 'hSlide 0.28s cubic-bezier(.2,.8,.2,1) both'
        }
      },
        React.createElement('div', { style: { display: 'flex', alignItems: 'center', gap: '8px' } },
          React.createElement('h4', { style: { margin: 0, fontSize: '16px', fontWeight: 800, flex: 1 } }, 'Tasks'),
          React.createElement('span', { style: { fontSize: '11px', fontWeight: 700, letterSpacing: '0.08em', textTransform: 'uppercase', color: 'color-mix(in srgb, var(--color-text) 62%, transparent)' } }, openTasksCount + ' open · ' + (todos.length - openTasksCount) + ' done'),
          React.createElement('button', {
            type: 'button', className: 'btn btn-icon btn-secondary', style: { width: '28px', height: '28px' },
            onClick: () => setTasksOpen(false)
          }, React.createElement(Icons.chevR, { size: 14 }))),

        React.createElement('form', { onSubmit: addTask, style: { display: 'flex', gap: '8px' } },
          React.createElement('input', {
            className: 'input', placeholder: "What's the next task?", value: draftTask,
            onChange: (e) => setDraftTask(e.target.value),
            style: { flex: 1, minWidth: 0, background: 'var(--color-bg)', fontSize: '13px' }
          }),
          React.createElement('button', { type: 'submit', className: 'btn btn-primary', style: { fontSize: '13px', fontWeight: 800, padding: '6px 14px' } }, 'Add')),

        React.createElement('div', { style: { display: 'flex', flexDirection: 'column', overflowY: 'auto', flex: 1, gap: '2px' } },
          todos.length === 0 ? React.createElement('p', { style: { fontSize: '13px', color: 'color-mix(in srgb, var(--color-text) 55%, transparent)', margin: '20px 0', textAlign: 'center' } }, 'Nothing here yet — add the one thing that matters.') : todos.map(t => React.createElement('div', {
            key: t.id,
            style: { display: 'flex', alignItems: 'center', gap: '10px', padding: '8px 2px', borderBottom: '1px solid color-mix(in srgb, var(--color-text) 8%, transparent)' }
          },
            React.createElement('button', {
              type: 'button', className: 'btn btn-icon',
              style: {
                width: '22px', height: '22px', flex: 'none', borderRadius: '50%',
                border: '2px solid ' + (t.done ? 'var(--color-accent)' : 'var(--color-divider)'),
                background: t.done ? 'var(--color-accent)' : 'transparent', color: 'var(--color-bg)'
              },
              onClick: () => toggleTodo(t.id)
            }, t.done ? React.createElement(Icons.check, { size: 12, sw: 3.5 }) : null),
            React.createElement('span', {
              style: { flex: 1, fontSize: '14px', fontWeight: 500, opacity: t.done ? 0.45 : 1, textDecoration: t.done ? 'line-through' : 'none' }
            }, t.text),
            React.createElement('button', {
              type: 'button', className: 'btn btn-icon',
              style: { width: '24px', height: '24px', color: 'color-mix(in srgb, var(--color-text) 55%, transparent)' },
              onClick: () => deleteTodo(t.id)
            }, React.createElement(Icons.x, { size: 13 }))
          )))
      ) : null,

      // Footer
      React.createElement('footer', {
        style: {
          position: 'relative', zIndex: 10, display: 'flex', alignItems: 'flex-end',
          justifyContent: 'space-between', gap: 'var(--space-4)', padding: 'var(--space-3) clamp(16px, 4vw, 40px)'
        }
      },
        React.createElement('p', {
          style: { margin: 0, maxWidth: '380px', fontSize: '11px', fontWeight: 600, letterSpacing: '0.08em', textTransform: 'uppercase', color: 'color-mix(in srgb, var(--color-text) 60%, transparent)' }
        }, 'Space: start/pause · F: timer · C: clock · S: stats · T: theme · Q: quote'),

        // Streak Badge
        React.createElement('div', {
          style: {
            display: 'flex', alignItems: 'center', gap: '10px', padding: '8px 16px 8px 13px',
            borderRadius: '999px', background: 'var(--h-glass)', backdropFilter: 'blur(18px)',
            border: '1px solid var(--color-divider)', boxShadow: 'var(--shadow-sm)', cursor: 'pointer'
          },
          title: 'View focus analytics',
          onClick: () => setStatsOpen(true)
        },
          React.createElement('span', { style: { fontSize: '19px', lineHeight: 1 } }, '🔥'),
          React.createElement('div', { style: { display: 'flex', flexDirection: 'column', lineHeight: 1.15, textAlign: 'left' } },
            React.createElement('span', { style: { fontSize: '15px', fontWeight: 900, letterSpacing: '-0.02em', fontVariantNumeric: 'tabular-nums' } },
              streak,
              React.createElement('span', { style: { fontSize: '11px', fontWeight: 700, letterSpacing: '0.06em', color: 'color-mix(in srgb, var(--color-text) 66%, transparent)' } }, ' day streak')),
            React.createElement('span', { style: { fontSize: '11px', fontWeight: 600, color: 'color-mix(in srgb, var(--color-text) 64%, transparent)' } }, formatMins(todayMins) + ' today')))
      )
    ),

    // Toast
    toast ? React.createElement('div', {
      style: {
        position: 'fixed', left: '50%', transform: 'translateX(-50%)', bottom: '80px', zIndex: 50,
        padding: '11px 22px', borderRadius: '999px', background: 'var(--color-text)', color: 'var(--color-bg)',
        fontSize: '13px', fontWeight: 700, boxShadow: 'var(--shadow-lg)', animation: 'hRise 0.3s ease both'
      }
    }, toast) : null,

    // Analytics / Stats Modal
    statsOpen ? React.createElement('div', {
      style: {
        position: 'fixed', inset: 0, zIndex: 60, overflowY: 'auto',
        background: 'color-mix(in srgb, var(--color-bg) 94%, transparent)', backdropFilter: 'blur(10px)',
        animation: 'hFade 0.2s ease both'
      }
    },
      React.createElement('div', {
        style: {
          maxWidth: '1120px', margin: '0 auto', padding: 'clamp(20px, 4vw, 44px) clamp(16px, 4vw, 40px) 64px',
          display: 'flex', flexDirection: 'column', gap: 'var(--space-4)'
        }
      },
        // Modal Header
        React.createElement('div', { style: { display: 'flex', alignItems: 'flex-start', gap: 'var(--space-3)', flexWrap: 'wrap' } },
          React.createElement('div', { style: { flex: 1, minWidth: '220px', textAlign: 'left' } },
            React.createElement('p', { style: { margin: '0 0 4px', fontSize: '11px', letterSpacing: '0.14em', textTransform: 'uppercase', color: 'var(--h-ink-accent)', fontWeight: 700 } }, 'Your focus record'),
            React.createElement('h2', { style: { margin: 0, fontSize: 'clamp(26px, 4vw, 40px)', fontWeight: 900, letterSpacing: '-0.035em' } },
              todayMins === 0 ? 'A blank page — start the timer.' : formatMins(todayMins) + ' of focus today'),
            React.createElement('p', { style: { margin: '6px 0 0', fontSize: '13px', color: 'color-mix(in srgb, var(--color-text) 60%, transparent)' } },
              DAYS[new Date().getDay()] + 'day, ' + MONTHS[new Date().getMonth()] + ' ' + new Date().getDate() + ' · your usual is ' + formatMins(refGoal) + ' a day')),

          React.createElement('div', { style: { display: 'flex', gap: '6px', padding: '5px', borderRadius: '999px', background: 'var(--color-surface)', border: '1px solid var(--color-divider)' } },
            ['day', 'week', 'month'].map(k => React.createElement('button', {
              key: k, type: 'button', className: 'btn',
              style: {
                fontSize: '13px', fontWeight: 700, padding: '7px 18px',
                background: statsTab === k ? 'var(--color-accent)' : 'transparent',
                color: statsTab === k ? 'var(--color-bg)' : 'var(--color-text)'
              },
              onClick: () => setStatsTab(k)
            }, k.charAt(0).toUpperCase() + k.slice(1)))),

          React.createElement('button', {
            type: 'button', className: 'btn btn-icon btn-secondary',
            onClick: () => setStatsOpen(false)
          }, React.createElement(Icons.x, { size: 16 }))),

        // Sample Data toggle
        React.createElement('div', { style: { display: 'flex', alignItems: 'center', justifyContent: 'flex-end', gap: '10px' } },
          !hasSampleData ? React.createElement('button', {
            type: 'button', className: 'btn btn-ghost',
            style: { fontSize: '11px', fontWeight: 700, border: '1px dashed var(--color-divider)', borderRadius: '999px' },
            onClick: () => {
              setSampleSessions(generateSampleSessions());
              setHasSampleData(true);
              flashToast('Loaded sample history preview.');
            }
          }, 'Load sample history preview') : React.createElement('button', {
            type: 'button', className: 'btn btn-ghost',
            style: { fontSize: '11px', fontWeight: 700, color: 'color-mix(in srgb, var(--color-text) 50%, transparent)' },
            onClick: () => {
              setSampleSessions([]);
              setHasSampleData(false);
              flashToast('Sample preview cleared.');
            }
          }, 'Clear sample data')),

        // KPI Summary Cards
        React.createElement('div', {
          style: { display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(min(100%, 168px), 1fr))', gap: 'var(--space-3)' }
        },
          [
            { label: 'Focused', val: formatMins(todayMins), note: Math.round(todayMins / refGoal * 100) + '% of a usual day', color: todayMins >= refGoal ? 'var(--h-ink-accent)' : 'inherit' },
            { label: 'Sessions', val: String((byDayMap[dateKey(getMidnight())] || []).length), note: (byDayMap[dateKey(getMidnight())] || []).length ? 'avg ' + formatMins(todayMins / (byDayMap[dateKey(getMidnight())] || []).length) : 'none yet', color: 'inherit' },
            { label: 'vs 30-day avg', val: ((todayMins - refGoal) >= 0 ? '+' : '−') + formatMins(Math.abs(todayMins - refGoal)), note: 'avg ' + formatMins(refGoal) + ' a day', color: (todayMins - refGoal) >= 0 ? 'var(--h-ink-accent)' : 'inherit' },
            { label: 'Streak', val: streak + 'd', note: 'consecutive focused days', color: 'inherit' }
          ].map((t, idx) => React.createElement('div', {
            key: idx, className: 'card elev-sm', style: { padding: 'var(--space-4)', gap: '4px' }
          },
            React.createElement('span', { style: { fontSize: '11px', letterSpacing: '0.1em', textTransform: 'uppercase', color: 'color-mix(in srgb, var(--color-text) 55%, transparent)', fontWeight: 700 } }, t.label),
            React.createElement('span', { style: { fontSize: 'clamp(26px, 3.4vw, 36px)', fontWeight: 900, letterSpacing: '-0.04em', lineHeight: 1.05 } }, t.val),
            React.createElement('span', { style: { fontSize: '12px', fontWeight: 600, color: t.color } }, t.note)))
        ),

        // Primary Hour Bar Chart (Day view)
        React.createElement('div', { className: 'card elev-sm', style: { padding: 'var(--space-4)', gap: 'var(--space-3)', textAlign: 'left' } },
          React.createElement('div', { style: { display: 'flex', alignItems: 'baseline', gap: '10px', flexWrap: 'wrap' } },
            React.createElement('h4', { style: { margin: 0, fontSize: '15px', fontWeight: 800 } }, 'Hour by hour'),
            React.createElement('span', { style: { fontSize: '12px', color: 'color-mix(in srgb, var(--color-text) 55%, transparent)' } }, '6am to midnight · minutes focused')),
          React.createElement('div', { style: { display: 'flex', alignItems: 'flex-end', gap: 'clamp(3px, 0.7vw, 9px)', height: '180px' } },
            (() => {
              const todayList = (byDayMap[dateKey(getMidnight())] || []);
              let maxH = 30;
              const hArr = [];
              for (let hh = 6; hh < 24; hh++) {
                const hm = todayList.filter(s => new Date(s.ts).getHours() === hh).reduce((acc, x) => acc + x.min, 0);
                if (hm > maxH) maxH = hm;
                hArr.push({ h: hh, m: hm });
              }
              return hArr.map(item => React.createElement('div', {
                key: item.h,
                style: { flex: 1, minWidth: 0, height: '100%', display: 'flex', flexDirection: 'column', justifyContent: 'flex-end', alignItems: 'center', gap: '6px' },
                title: hourLabel(item.h) + ' · ' + (item.m ? formatMins(item.m) : 'quiet')
              },
                React.createElement('div', {
                  style: {
                    width: '100%', borderRadius: '999px 999px 6px 6px', minHeight: '3px',
                    background: item.m === 0 ? 'color-mix(in srgb, var(--color-text) 10%, transparent)' : (item.m >= 45 ? 'var(--color-accent)' : 'var(--color-accent-2)'),
                    height: Math.round(item.m / maxH * 100) + '%', transition: 'height 0.4s ease'
                  }
                }),
                React.createElement('span', {
                  style: { fontSize: '10px', fontWeight: 700, color: 'color-mix(in srgb, var(--color-text) 50%, transparent)', opacity: item.h % 3 === 0 ? 1 : 0 }
                }, hourLabel(item.h))));
            })()
          )),

        // Split & List
        React.createElement('div', { style: { display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(min(100%, 320px), 1fr))', gap: 'var(--space-3)', textAlign: 'left' } },
          // Tag Split
          React.createElement('div', { className: 'card elev-sm', style: { padding: 'var(--space-4)', gap: 'var(--space-3)' } },
            React.createElement('h4', { style: { margin: 0, fontSize: '15px', fontWeight: 800 } }, 'Where the time went'),
            React.createElement('div', { style: { display: 'flex', flexDirection: 'column', gap: '11px' } },
              (() => {
                const todayList = (byDayMap[dateKey(getMidnight())] || []);
                const tot = todayList.reduce((sum, s) => sum + s.min, 0) || 1;
                const breakdown = TAGS.map((tag, idx) => {
                  const tm = todayList.filter(s => s.tag === tag).reduce((sum, s) => sum + s.min, 0);
                  return { tag, min: tm, pct: Math.round(tm / tot * 100), color: TAG_COLORS[idx % TAG_COLORS.length] };
                }).filter(t => t.min > 0).sort((a, b) => b.min - a.min);

                if (breakdown.length === 0) {
                  return React.createElement('p', { style: { fontSize: '13px', color: 'color-mix(in srgb, var(--color-text) 50%, transparent)', margin: '12px 0' } }, 'No category focus recorded today.');
                }
                return breakdown.map(item => React.createElement('div', { key: item.tag, style: { display: 'flex', flexDirection: 'column', gap: '5px' } },
                  React.createElement('div', { style: { display: 'flex', justifyContent: 'space-between', fontSize: '13px' } },
                    React.createElement('span', { style: { fontWeight: 600 } }, item.tag),
                    React.createElement('span', { style: { color: 'color-mix(in srgb, var(--color-text) 64%, transparent)' } }, formatMins(item.min) + ' · ' + item.pct + '%')),
                  React.createElement('div', { style: { height: '8px', borderRadius: '999px', background: 'color-mix(in srgb, var(--color-text) 9%, transparent)', overflow: 'hidden' } },
                    React.createElement('div', { style: { height: '100%', borderRadius: '999px', background: item.color, width: item.pct + '%' } }))));
              })()
            )),

          // Session list
          React.createElement('div', { className: 'card elev-sm', style: { padding: 'var(--space-4)', gap: 'var(--space-3)' } },
            React.createElement('h4', { style: { margin: 0, fontSize: '15px', fontWeight: 800 } }, 'Every session today'),
            React.createElement('div', { style: { display: 'flex', flexDirection: 'column', maxHeight: '268px', overflowY: 'auto' } },
              (() => {
                const todayList = (byDayMap[dateKey(getMidnight())] || []).slice().sort((a, b) => b.ts - a.ts);
                if (todayList.length === 0) {
                  return React.createElement('p', { style: { margin: '16px 0', fontSize: '13px', color: 'color-mix(in srgb, var(--color-text) 50%, transparent)', textAlign: 'center' } }, 'No focus sessions logged yet today.');
                }
                return todayList.map(s => {
                  const tagIdx = TAGS.indexOf(s.tag);
                  const tagCol = TAG_COLORS[tagIdx >= 0 ? tagIdx : 0];
                  return React.createElement('div', {
                    key: s.id,
                    style: { display: 'flex', alignItems: 'center', gap: '10px', padding: '9px 0', borderBottom: '1px solid color-mix(in srgb, var(--color-text) 8%, transparent)' }
                  },
                    React.createElement('span', { style: { width: '8px', height: '8px', flex: 'none', borderRadius: '50%', background: tagCol } }),
                    React.createElement('span', { style: { width: '64px', flex: 'none', fontSize: '12px', fontWeight: 700 } }, timeLabel(s.ts)),
                    React.createElement('span', { style: { flex: 1, minWidth: 0, fontSize: '13px', fontWeight: 500, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' } }, s.tag),
                    React.createElement('span', { style: { fontSize: '13px', fontWeight: 800 } }, formatMins(s.min)),
                    React.createElement('span', { style: { width: '60px', textAlign: 'right', fontSize: '11px', color: 'color-mix(in srgb, var(--color-text) 52%, transparent)' } }, s.pauses ? s.pauses + ' pause' + (s.pauses > 1 ? 's' : '') : 'clean'));
                });
              })()
            ),
            React.createElement('p', { style: { margin: 0, fontSize: '12px', color: 'color-mix(in srgb, var(--color-text) 55%, transparent)' } }, 'Pauses are counted when a running timer is stopped early.'))
        ),

        // Footer note
        React.createElement('p', {
          style: { margin: 0, fontSize: '12px', textAlign: 'center', color: 'color-mix(in srgb, var(--color-text) 45%, transparent)' }
        }, 'All focus data is stored persistently on this device.')
      )
    ) : null
  );
}

Object.assign(window, { FocusSpace });
