// Main Dashboard component. Wires timer, habits, tags, heatmaps, sessions.

function Dashboard() {
  const [state, setState] = useState(loadState);
  const [elapsedSec, setElapsedSec] = useState(0);
  const [editingGoal, setEditingGoal] = useState(false);
  const [goalDraft, setGoalDraft] = useState('');
  const [editingMission, setEditingMission] = useState(false);
  const [missionDraft, setMissionDraft] = useState('');
  const [sessionTitle, setSessionTitle] = useState('');
  const [sessionTag, setSessionTag] = useState(null);
  const [sessionHabits, setSessionHabits] = useState([]);
  const [addingTag, setAddingTag] = useState(false);
  const [newTagName, setNewTagName] = useState('');
  const [newTagShips, setNewTagShips] = useState(true);
  const [editingHabits, setEditingHabits] = useState(false);
  const [editingTags, setEditingTags] = useState(false);
  const [showData, setShowData] = useState(false);
  const [copiedLabel, setCopiedLabel] = useState(null);
  const [burstFor, setBurstFor] = useState(null);
  const [inputBurst, setInputBurst] = useState(0);
  const timerRef = useRef(null);

  useEffect(() => { saveState(state); }, [state]);

  useEffect(() => {
    if (state.activeSession && !state.activeSession.paused) {
      const tick = () => {
        const start = new Date(state.activeSession.startTime).getTime();
        setElapsedSec(Math.floor((Date.now() - start) / 1000));
      };
      tick();
      timerRef.current = setInterval(tick, 1000);
      return () => clearInterval(timerRef.current);
    } else if (state.activeSession?.paused) {
      setElapsedSec(state.activeSession.frozenElapsedSec || 0);
    } else {
      setElapsedSec(0);
    }
  }, [state.activeSession]);

  useEffect(() => {
    if (!sessionTag && state.tags.length > 0) {
      setSessionTag(state.tags[0].id);
    }
  }, [state.tags.length, sessionTag]);

  const toggleHabit = (habitId) => {
    const today = todayStr();
    const currentlyDone = state.habitLog[habitId]?.[today];
    setState(s => ({
      ...s,
      habitLog: {
        ...s.habitLog,
        [habitId]: { ...(s.habitLog[habitId] || {}), [today]: !currentlyDone },
      },
    }));
    if (!currentlyDone) {
      setBurstFor(habitId + ':' + Date.now());
      setTimeout(() => setBurstFor(null), 900);
    }
  };

  const startSession = () => {
    if (!sessionTitle.trim()) return;
    setState(s => ({
      ...s,
      activeSession: {
        title: sessionTitle.trim(), tagId: sessionTag, habitIds: sessionHabits,
        startTime: new Date().toISOString(), paused: false,
      },
    }));
  };

  const pauseSession = () => {
    if (!state.activeSession || state.activeSession.paused) return;
    setState(s => ({ ...s, activeSession: { ...s.activeSession, paused: true, frozenElapsedSec: elapsedSec } }));
  };

  const resumeSession = () => {
    if (!state.activeSession || !state.activeSession.paused) return;
    const frozen = state.activeSession.frozenElapsedSec || 0;
    const newStartTime = new Date(Date.now() - frozen * 1000).toISOString();
    setState(s => ({
      ...s,
      activeSession: { ...s.activeSession, paused: false, startTime: newStartTime, frozenElapsedSec: undefined },
    }));
  };

  const stopSession = () => {
    const sess = state.activeSession;
    if (!sess) return;
    const now = new Date();
    let dur;
    if (sess.paused) dur = sess.frozenElapsedSec || 0;
    else dur = Math.floor((now - new Date(sess.startTime)) / 1000);
    const today = todayStr();

    if (dur < 10) {
      setState(s => ({ ...s, activeSession: null }));
      setSessionTitle(''); setSessionHabits([]); return;
    }

    setState(s => {
      const newHabitLog = { ...s.habitLog };
      (sess.habitIds || []).forEach(hid => {
        newHabitLog[hid] = { ...(newHabitLog[hid] || {}), [today]: true };
      });
      return {
        ...s,
        habitLog: newHabitLog,
        sessions: [
          {
            id: `s${Date.now()}`,
            title: sess.title, tagId: sess.tagId, habitIds: sess.habitIds,
            startTime: sess.startTime, endTime: now.toISOString(),
            duration: dur, date: today,
          },
          ...s.sessions,
        ],
        activeSession: null,
      };
    });
    setSessionTitle(''); setSessionHabits([]);
  };

  const logInput = (tagId) => {
    setState(s => ({
      ...s,
      inputs: [...s.inputs, { id: `i${Date.now()}`, tagId, date: todayStr(), timestamp: new Date().toISOString() }],
    }));
    setInputBurst(Date.now());
    setTimeout(() => setInputBurst(0), 900);
  };
  const undoLastInput = () => setState(s => ({ ...s, inputs: s.inputs.slice(0, -1) }));

  const addTag = () => {
    if (!newTagName.trim()) return;
    const usedColors = new Set(state.tags.map(t => t.color));
    const nextColor = TAG_PALETTE.find(c => !usedColors.has(c)) || TAG_PALETTE[state.tags.length % TAG_PALETTE.length];
    setState(s => ({
      ...s,
      tags: [...s.tags, { id: `t${Date.now()}`, name: newTagName.trim(), color: nextColor, ships: newTagShips }],
    }));
    setNewTagName(''); setNewTagShips(true); setAddingTag(false);
  };
  const removeTag = (id) => {
    setState(s => ({ ...s, tags: s.tags.filter(t => t.id !== id) }));
    if (sessionTag === id) setSessionTag(null);
  };
  const toggleTagShips = (id) => {
    setState(s => ({ ...s, tags: s.tags.map(t => t.id === id ? { ...t, ships: !t.ships } : t) }));
  };

  const updateHabitName = (id, name) => {
    setState(s => ({ ...s, habits: s.habits.map(h => h.id === id ? { ...h, name } : h) }));
  };
  const addHabit = () => {
    setState(s => ({ ...s, habits: [...s.habits, { id: `h${Date.now()}`, name: 'new habit', frequency: 'daily' }] }));
  };
  const removeHabit = (id) => setState(s => ({ ...s, habits: s.habits.filter(h => h.id !== id) }));

  const habitDone = (hid, date = todayStr()) => state.habitLog[hid]?.[date] || false;

  const getStreak = (hid) => {
    let streak = 0;
    const d = new Date();
    while (streak < 365) {
      const ds = todayStr(d);
      if (habitDone(hid, ds)) { streak++; d.setDate(d.getDate() - 1); }
      else {
        if (streak === 0 && ds === todayStr()) { d.setDate(d.getDate() - 1); continue; }
        break;
      }
    }
    return streak;
  };

  const getLast30Count = (hid) => {
    let count = 0;
    const d = new Date();
    for (let i = 0; i < 30; i++) {
      if (habitDone(hid, todayStr(d))) count++;
      d.setDate(d.getDate() - 1);
    }
    return count;
  };

  const buildHeatmap = (getVal) => {
    const days = 30;
    const today = new Date();
    today.setHours(0, 0, 0, 0);
    const cells = [];
    for (let i = days - 1; i >= 0; i--) {
      const d = new Date(today);
      d.setDate(d.getDate() - i);
      cells.push({ date: todayStr(d), value: getVal(todayStr(d)), dayOfWeek: d.getDay() });
    }
    return cells;
  };

  const weekKey = getWeekKey();
  const weeklyInputs = state.inputs.filter(i => getWeekKey(new Date(i.timestamp)) === weekKey);
  const weeklyCount = weeklyInputs.length;
  const weekProgress = Math.min(100, (weeklyCount / state.weeklyGoal) * 100);
  const weeklySessions = state.sessions.filter(s => getWeekKey(new Date(s.startTime)) === weekKey);
  const weeklyHours = weeklySessions.reduce((sum, s) => sum + s.duration, 0) / 3600;

  const getHabitHoursThisWeek = (hid) => {
    const secs = weeklySessions.filter(s => (s.habitIds || []).includes(hid)).reduce((sum, s) => sum + s.duration, 0);
    return secs / 3600;
  };

  const inputCountByDay = state.inputs.reduce((acc, inp) => { acc[inp.date] = (acc[inp.date] || 0) + 1; return acc; }, {});
  const sessionHoursByDay = state.sessions.reduce((acc, sess) => {
    const date = sess.date || todayStr(new Date(sess.startTime));
    acc[date] = (acc[date] || 0) + sess.duration / 3600;
    return acc;
  }, {});

  const totalAllTimeHours = state.sessions.reduce((sum, s) => sum + s.duration, 0) / 3600;

  const getCellColor = makeCellColor(document.body.dataset.theme || 'luminous');

  const copyData = () => {
    const text = JSON.stringify(state, null, 2);
    const ta = document.createElement('textarea');
    ta.value = text; ta.style.position = 'fixed'; ta.style.opacity = '0';
    document.body.appendChild(ta); ta.select();
    try {
      document.execCommand('copy');
      setCopiedLabel('copied ✓');
      setTimeout(() => setCopiedLabel(null), 1500);
    } catch (e) {
      setCopiedLabel('select + ⌘C manually');
      setTimeout(() => setCopiedLabel(null), 2500);
    }
    document.body.removeChild(ta);
  };

  const recentIndexes = [27, 28, 29]; // last 3 days of 30-day window

  return (
    <div className="min-h-screen relative" style={{ color: 'var(--text-0)' }}>
      <div className="max-w-[1200px] mx-auto px-8 py-10 relative z-10 stagger">

        {/* Mission */}
        <div className="mb-10">
          {editingMission ? (
            <input
              value={missionDraft}
              onChange={(e) => setMissionDraft(e.target.value)}
              onBlur={() => { setState(s => ({ ...s, mission: missionDraft })); setEditingMission(false); }}
              onKeyDown={(e) => e.key === 'Enter' && e.target.blur()}
              autoFocus
              className="display w-full bg-transparent outline-none text-lg font-light border-b border-dashed pb-1"
              style={{ color: 'var(--text-0)', borderColor: 'var(--line-2)' }}
            />
          ) : (
            <div
              onClick={() => { setMissionDraft(state.mission); setEditingMission(true); }}
              className="display text-xl font-light cursor-text transition-colors"
              style={{ color: 'var(--text-1)' }}
            >
              {state.mission || <span style={{ color: 'var(--text-3)' }}>click to set your why</span>}
            </div>
          )}
        </div>

        <TimerPanel
          state={state} setState={setState}
          elapsedSec={elapsedSec}
          sessionTitle={sessionTitle} setSessionTitle={setSessionTitle}
          sessionTag={sessionTag} setSessionTag={setSessionTag}
          sessionHabits={sessionHabits} setSessionHabits={setSessionHabits}
          startSession={startSession} pauseSession={pauseSession}
          resumeSession={resumeSession} stopSession={stopSession}
        />

        {/* Habits */}
        <div className="mb-8">
          <div className="flex items-center justify-between mb-4">
            <div className="text-[11px] tracking-[0.25em] uppercase font-medium bracket-label" style={{ color: 'var(--text-2)' }}>habits</div>
            <button onClick={() => setEditingHabits(!editingHabits)} className="text-[11px] tracking-wide transition-colors" style={{ color: 'var(--text-2)' }}>
              {editingHabits ? 'done' : 'edit'}
            </button>
          </div>
          <div className={`grid gap-3 ${(state.habits.length + (editingHabits ? 1 : 0)) <= 3 ? 'grid-cols-3' : 'grid-cols-4'}`}>
            {state.habits.map(h => {
              const done = habitDone(h.id);
              const streak = getStreak(h.id);
              const hoursWk = getHabitHoursThisWeek(h.id);
              return (
                <div
                  key={h.id}
                  onClick={() => !editingHabits && toggleHabit(h.id)}
                  role="button"
                  tabIndex={editingHabits ? -1 : 0}
                  onKeyDown={(e) => { if (!editingHabits && (e.key === 'Enter' || e.key === ' ')) { e.preventDefault(); toggleHabit(h.id); } }}
                  data-done={done}
                  className={`habit-card surface relative text-left p-5 ${editingHabits ? 'cursor-default' : 'cursor-pointer'}`}
                  style={done ? {
                    background: 'var(--accent)',
                    borderColor: 'var(--accent)',
                    color: 'var(--bg-0)',
                  } : {}}
                >
                  <Burst active={burstFor && burstFor.startsWith(h.id + ':') ? burstFor : null} />
                  {editingHabits && (
                    <button
                      type="button"
                      onClick={(e) => { e.stopPropagation(); removeHabit(h.id); }}
                      className="absolute top-2 right-2 w-6 h-6 flex items-center justify-center rounded-full transition-colors"
                      style={{ color: done ? 'color-mix(in oklch, var(--bg-0) 70%, transparent)' : 'var(--text-2)' }}
                      aria-label="delete habit"
                    >
                      <XIcon size={14} />
                    </button>
                  )}
                  {editingHabits ? (
                    <input
                      value={h.name}
                      onChange={(e) => updateHabitName(h.id, e.target.value)}
                      onClick={(e) => e.stopPropagation()}
                      className="bg-transparent outline-none w-full font-medium mb-4 pr-8"
                      style={{ color: done ? 'var(--bg-0)' : 'var(--text-0)' }}
                    />
                  ) : (
                    <div className="font-medium mb-4 leading-tight min-h-[40px]" style={{ color: done ? 'var(--bg-0)' : 'var(--text-0)' }}>
                      {h.name}
                    </div>
                  )}
                  <div className="flex items-end justify-between relative">
                    <div
                      className={`w-10 h-10 flex items-center justify-center rounded-full transition-all ${done ? 'ring-pop' : ''}`}
                      style={done ? {
                        background: 'var(--bg-0)',
                        color: 'var(--accent)',
                      } : {
                        border: '2px solid var(--line-2)',
                      }}
                    >
                      {done && <CheckIcon size={18} strokeWidth={2.5} />}
                    </div>
                    <div className="text-right">
                      <div className="flex items-baseline gap-1 justify-end">
                        <FlameIcon size={12} strokeWidth={2} />
                        <span className="display text-2xl font-semibold tabular leading-none">
                          <CountUp value={streak} duration={600} />
                        </span>
                      </div>
                      <div className="text-[10px] tracking-wide mt-1" style={{ color: done ? 'color-mix(in oklch, var(--bg-0) 60%, transparent)' : 'var(--text-2)' }}>
                        {hoursWk > 0 ? `${hoursWk.toFixed(1)}h this week` : `${getLast30Count(h.id)} of 30`}
                      </div>
                    </div>
                  </div>
                </div>
              );
            })}
            {editingHabits && (
              <button onClick={addHabit} className="surface flex items-center justify-center text-xs p-5 min-h-[140px] transition-colors"
                style={{ border: '1px dashed var(--line-2)', background: 'transparent', color: 'var(--text-2)' }}>
                <PlusIcon size={14} /> <span className="ml-1">add</span>
              </button>
            )}
          </div>
        </div>

        {/* Week stats + Tags */}
        <div className="grid grid-cols-2 gap-3 mb-8">
          <div className="surface p-6">
            <div className="text-[11px] tracking-[0.25em] uppercase font-medium mb-4 bracket-label" style={{ color: 'var(--text-2)' }}>this week</div>
            <div className="flex items-baseline gap-2 mb-2">
              <span className="display text-6xl font-semibold tabular leading-none" style={{ color: 'var(--accent)' }}>
                <RollingNumber value={weeklyCount} />
              </span>
              <span className="display text-2xl tabular" style={{ color: 'var(--text-3)' }}>/</span>
              {editingGoal ? (
                <input
                  type="number"
                  value={goalDraft}
                  onChange={(e) => setGoalDraft(e.target.value)}
                  onBlur={() => {
                    const n = parseInt(goalDraft);
                    if (!isNaN(n) && n > 0) setState(s => ({ ...s, weeklyGoal: n }));
                    setEditingGoal(false);
                  }}
                  onKeyDown={(e) => e.key === 'Enter' && e.target.blur()}
                  autoFocus
                  className="display text-3xl font-medium bg-transparent outline-none w-16 tabular leading-none"
                  style={{ color: 'var(--text-2)' }}
                />
              ) : (
                <span
                  onClick={() => { setGoalDraft(String(state.weeklyGoal)); setEditingGoal(true); }}
                  className="display text-3xl font-medium cursor-text leading-none tabular"
                  style={{ color: 'var(--text-2)' }}
                >
                  {state.weeklyGoal}
                </span>
              )}
            </div>
            <div className="text-xs mb-4" style={{ color: 'var(--text-2)' }}>videos shipped</div>
            <div className="w-full h-1.5 rounded-full overflow-hidden mb-3" style={{ background: 'var(--line)' }}>
              <div
                className="progress-fill h-full rounded-full"
                style={{ width: `${weekProgress}%`, background: 'var(--accent)' }}
              />
            </div>
            <div className="flex items-center justify-between">
              <span className="text-[11px] tracking-wide tabular" style={{ color: 'var(--text-2)' }}>
                <CountUp value={weekProgress} duration={900} />% done
              </span>
              <span className="text-[11px] tracking-wide" style={{ color: 'var(--text-2)' }}>
                {state.weeklyGoal - weeklyCount > 0 ? `${state.weeklyGoal - weeklyCount} to go` : '✓ goal hit'}
              </span>
            </div>
            <div className="mt-5 pt-5 grid grid-cols-2 gap-4" style={{ borderTop: '1px solid var(--line)' }}>
              <div>
                <div className="flex items-baseline gap-1.5">
                  <span className="display text-3xl font-semibold tabular leading-none" style={{ color: 'var(--text-0)' }}>
                    <CountUp value={weeklyHours} decimals={1} duration={900} />
                  </span>
                  <span className="text-sm" style={{ color: 'var(--text-2)' }}>h</span>
                </div>
                <div className="text-[11px] tracking-wide mt-1" style={{ color: 'var(--text-2)' }}>deep work</div>
              </div>
              <div>
                <div className="flex items-baseline gap-1.5">
                  <span className="display text-3xl font-semibold tabular leading-none" style={{ color: 'var(--text-0)' }}>
                    <CountUp value={weeklySessions.length} duration={900} />
                  </span>
                </div>
                <div className="text-[11px] tracking-wide mt-1" style={{ color: 'var(--text-2)' }}>sessions</div>
              </div>
            </div>
          </div>

          <div className="surface p-6">
            <div className="flex items-center justify-between mb-4">
              <div className="text-[11px] tracking-[0.25em] uppercase font-medium bracket-label" style={{ color: 'var(--text-2)' }}>tags</div>
              <div className="flex items-center gap-3">
                {state.inputs.length > 0 && !editingTags && (
                  <button onClick={undoLastInput} className="text-[10px] tracking-wide transition-colors" style={{ color: 'var(--text-2)' }}>
                    ↶ undo
                  </button>
                )}
                <button onClick={() => setEditingTags(!editingTags)} className="text-[11px] tracking-wide transition-colors" style={{ color: 'var(--text-2)' }}>
                  {editingTags ? 'done' : 'edit'}
                </button>
              </div>
            </div>
            <div className="space-y-2">
              {state.tags.map(t => {
                const count = state.inputs.filter(i => i.tagId === t.id && getWeekKey(new Date(i.timestamp)) === weekKey).length;
                return (
                  <div key={t.id} className="flex items-center gap-3 group">
                    <div className="w-2 h-2 rounded-full flex-shrink-0" style={{ background: t.color }} />
                    <div className="flex-1 min-w-0 truncate text-sm" style={{ color: 'var(--text-0)' }}>{t.name}</div>
                    {editingTags ? (
                      <>
                        <button
                          onClick={() => toggleTagShips(t.id)}
                          className="text-[10px] tracking-wide px-2 py-0.5 rounded-full border transition-colors"
                          style={t.ships
                            ? { borderColor: 'color-mix(in oklch, var(--accent) 40%, transparent)', color: 'var(--accent)', background: 'color-mix(in oklch, var(--accent) 6%, transparent)' }
                            : { borderColor: 'var(--line-2)', color: 'var(--text-2)' }}
                        >
                          {t.ships ? '✓ ships' : 'no ships'}
                        </button>
                        {state.tags.length > 1 && (
                          <button onClick={() => removeTag(t.id)} style={{ color: 'var(--text-2)' }}>
                            <XIcon size={14} />
                          </button>
                        )}
                      </>
                    ) : t.ships ? (
                      <>
                        <div className="text-xs tabular" style={{ color: 'var(--text-2)' }}>
                          <CountUp value={count} duration={500} />
                        </div>
                        <button onClick={() => logInput(t.id)} className="w-8 h-8 rounded-full border flex items-center justify-center transition-all hover:scale-110 relative"
                          style={{ borderColor: 'var(--line-2)', color: 'var(--text-2)' }}>
                          <PlusIcon size={12} />
                          {inputBurst > 0 && <Burst active={inputBurst + t.id} />}
                        </button>
                      </>
                    ) : (
                      <div className="text-[10px] tracking-wide" style={{ color: 'var(--text-3)' }}>tag only</div>
                    )}
                  </div>
                );
              })}
            </div>
            {addingTag ? (
              <div className="mt-3 pt-3 space-y-2" style={{ borderTop: '1px solid var(--line)' }}>
                <input
                  value={newTagName}
                  onChange={(e) => setNewTagName(e.target.value)}
                  onKeyDown={(e) => e.key === 'Enter' && addTag()}
                  placeholder="tag name"
                  autoFocus
                  className="w-full bg-transparent outline-none text-sm"
                  style={{ color: 'var(--text-0)' }}
                />
                <div className="flex items-center justify-between">
                  <label className="flex items-center gap-2 cursor-pointer text-[11px]" style={{ color: 'var(--text-1)' }}>
                    <input type="checkbox" checked={newTagShips} onChange={(e) => setNewTagShips(e.target.checked)} />
                    tracks ships
                  </label>
                  <div className="flex items-center gap-2">
                    <button onClick={() => { setAddingTag(false); setNewTagName(''); }} className="text-xs" style={{ color: 'var(--text-2)' }}>cancel</button>
                    <button onClick={addTag} className="text-xs font-medium" style={{ color: 'var(--accent)' }}>add</button>
                  </div>
                </div>
              </div>
            ) : (
              <button onClick={() => setAddingTag(true)} className="text-[11px] tracking-wide flex items-center gap-1 mt-3 pt-3 w-full transition-colors"
                style={{ color: 'var(--text-2)', borderTop: '1px solid var(--line)' }}>
                <PlusIcon size={10} /> <span>add tag</span>
              </button>
            )}
          </div>
        </div>

        {/* Heatmaps */}
        <div className="surface p-6 mb-8">
          <div className="text-[11px] tracking-[0.25em] uppercase font-medium mb-5 bracket-label" style={{ color: 'var(--text-2)' }}>last 30 days</div>
          <div className="space-y-5">
            {state.habits.map(h => {
              const cells = buildHeatmap(d => habitDone(h.id, d) ? 1 : 0);
              const pad = cells[0].dayOfWeek;
              return (
                <HeatmapRow key={h.id} label={h.name} cells={cells} pad={pad} getColor={(v) => getCellColor(v, 1)} streak={getStreak(h.id)} recentIndexes={recentIndexes} />
              );
            })}
            <div className="pt-5 space-y-5" style={{ borderTop: '1px solid var(--line)' }}>
              {(() => {
                const cells = buildHeatmap(d => inputCountByDay[d] || 0);
                const max = Math.max(1, ...cells.map(c => c.value));
                const pad = cells[0].dayOfWeek;
                return <HeatmapRow label="videos shipped" cells={cells} pad={pad} getColor={(v) => getCellColor(v, max)} total={state.inputs.length} totalLabel="all-time" highlight recentIndexes={recentIndexes} />;
              })()}
              {(() => {
                const cells = buildHeatmap(d => sessionHoursByDay[d] || 0);
                const max = Math.max(1, ...cells.map(c => c.value));
                const pad = cells[0].dayOfWeek;
                return <HeatmapRow label="deep work" cells={cells} pad={pad} getColor={(v) => getCellColor(v, max)} total={`${totalAllTimeHours.toFixed(0)}h`} totalLabel="all-time" highlight recentIndexes={recentIndexes} />;
              })()}
            </div>
          </div>
        </div>

        {/* Recent sessions */}
        {state.sessions.length > 0 && (
          <div className="surface p-6 mb-8">
            <div className="text-[11px] tracking-[0.25em] uppercase font-medium mb-4 bracket-label" style={{ color: 'var(--text-2)' }}>recent sessions</div>
            <div>
              {state.sessions.slice(0, 10).map((sess, idx) => {
                const tg = state.tags.find(t => t.id === sess.tagId);
                return (
                  <div key={sess.id} className="flex items-center gap-4 py-2.5" style={{ borderTop: idx > 0 ? '1px solid var(--line)' : 'none' }}>
                    <div className="text-[11px] tabular w-20" style={{ color: 'var(--text-2)' }}>
                      {new Date(sess.startTime).toLocaleDateString('en-US', { month: 'short', day: 'numeric' }).toLowerCase()}
                    </div>
                    {tg && <div className="w-1.5 h-1.5 rounded-full flex-shrink-0" style={{ background: tg.color }} />}
                    <div className="flex-1 text-sm truncate" style={{ color: 'var(--text-0)' }}>{sess.title}</div>
                    <div className="flex items-center gap-1.5">
                      {sess.habitIds?.map(hid => {
                        const h = state.habits.find(x => x.id === hid);
                        return h ? <div key={hid} className="w-1 h-1 rounded-full" style={{ background: 'var(--accent)' }} title={h.name} /> : null;
                      })}
                    </div>
                    <div className="text-xs tabular w-14 text-right" style={{ color: 'var(--text-1)' }}>{formatDuration(sess.duration)}</div>
                  </div>
                );
              })}
            </div>
          </div>
        )}

        <div className="pt-4 flex items-center justify-between text-[10px] tracking-[0.25em] uppercase" style={{ color: 'var(--text-3)' }}>
          <span>measure inputs</span>
          <div className="flex items-center gap-4">
            <button onClick={() => setShowData(!showData)} className="cursor-pointer transition-colors">
              {showData ? 'hide data' : 'view data'}
            </button>
            <span>v0.6</span>
          </div>
        </div>

        {showData && (
          <div className="mt-6 surface p-6">
            <div className="flex items-center justify-between mb-4">
              <div className="text-[11px] tracking-[0.25em] uppercase font-medium" style={{ color: 'var(--text-2)' }}>
                stored data · {state.sessions.length} sessions · {state.inputs.length} inputs
              </div>
              <button onClick={copyData} className="text-[11px] tracking-wide transition-colors normal-case" style={{ color: 'var(--text-2)' }}>
                {copiedLabel || 'copy all'}
              </button>
            </div>
            <textarea
              readOnly
              value={JSON.stringify(state, null, 2)}
              className="code-view w-full h-96 text-xs p-4 rounded-lg resize-y outline-none"
              style={{ background: 'var(--bg-0)', color: 'var(--text-1)', border: '1px solid var(--line)' }}
            />
          </div>
        )}

      </div>
    </div>
  );
}

window.Dashboard = Dashboard;
