// screens.jsx — Onboarding, Today, Discover, Detail, Routine, Progress

// ── Top bar / chrome ─────────────────────────────────────────
function TopBar({ title, eyebrow, dark, right, sticky = true, big = false }) {
  const fg = dark ? '#f4efe6' : '#1c1a15';
  const muted = dark ? 'rgba(244,239,230,0.55)' : 'rgba(28,26,21,0.55)';
  return (
    <div style={{
      position: sticky ? 'sticky' : 'relative', top: 0,
      zIndex: 5,
      background: dark
        ? 'linear-gradient(to bottom, rgba(20,18,14,0.92) 70%, rgba(20,18,14,0))'
        : 'linear-gradient(to bottom, rgba(248,244,236,0.92) 70%, rgba(248,244,236,0))',
      backdropFilter: 'blur(10px)',
      padding: '62px 20px 14px',
    }}>
      <div style={{ display: 'flex', alignItems: 'flex-end', justifyContent: 'space-between', gap: 12 }}>
        <div>
          {eyebrow && (
            <div style={{
              fontFamily: 'var(--cb-mono)',
              fontSize: 10, letterSpacing: 1.5, textTransform: 'uppercase',
              color: muted, marginBottom: 4,
            }}>{eyebrow}</div>
          )}
          <h1 style={{
            margin: 0,
            fontFamily: big ? 'var(--cb-display)' : 'inherit',
            fontWeight: big ? 400 : 600,
            fontSize: big ? 34 : 22, lineHeight: big ? 1.08 : 1.2, letterSpacing: big ? -0.6 : -0.2,
            color: fg, textWrap: 'pretty',
          }}>{title}</h1>
        </div>
        {right}
      </div>
    </div>
  );
}

function BottomNav({ tab, setTab, dark }) {
  const items = [
    { id: 'today',    label: 'Today',    icon: <NavIconToday/> },
    { id: 'discover', label: 'Discover', icon: <NavIconDiscover/> },
    { id: 'routine',  label: 'Routine',  icon: <NavIconRoutine/> },
    { id: 'progress', label: 'Progress', icon: <NavIconChart/> },
  ];
  const fg = dark ? '#f4efe6' : '#1c1a15';
  const muted = dark ? 'rgba(244,239,230,0.45)' : 'rgba(28,26,21,0.45)';
  return (
    <div style={{
      position: 'absolute', left: 0, right: 0, bottom: 0,
      paddingBottom: 28, paddingTop: 8,
      background: dark
        ? 'linear-gradient(to top, rgba(20,18,14,0.97) 60%, rgba(20,18,14,0))'
        : 'linear-gradient(to top, rgba(248,244,236,0.97) 60%, rgba(248,244,236,0))',
      backdropFilter: 'blur(12px)',
      zIndex: 30,
    }}>
      <div style={{
        display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 4,
        padding: '0 18px',
      }}>
        {items.map((it) => {
          const on = it.id === tab;
          return (
            <button key={it.id} onClick={() => setTab(it.id)}
              style={{
                all: 'unset', cursor: 'pointer',
                display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 4,
                padding: '8px 4px', borderRadius: 12,
                color: on ? fg : muted,
              }}>
              <div style={{ width: 22, height: 22 }}>{it.icon}</div>
              <span style={{ fontSize: 10.5, letterSpacing: 0.2, fontWeight: on ? 600 : 500 }}>{it.label}</span>
            </button>
          );
        })}
      </div>
    </div>
  );
}

function NavIconToday() {
  return (<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round"><circle cx="12" cy="12" r="4"/><path d="M12 2v2M12 20v2M2 12h2M20 12h2M5 5l1.5 1.5M17.5 17.5L19 19M5 19l1.5-1.5M17.5 6.5L19 5"/></svg>);
}
function NavIconDiscover() {
  return (<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round"><circle cx="11" cy="11" r="7"/><path d="M16 16l5 5"/></svg>);
}
function NavIconRoutine() {
  return (<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round"><rect x="3" y="4" width="18" height="17" rx="2"/><path d="M3 9h18M8 2v4M16 2v4"/><path d="M8 14l2 2 4-4" /></svg>);
}
function NavIconChart() {
  return (<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round"><path d="M4 20V10M10 20V4M16 20v-7M22 20H2"/></svg>);
}

function OnboardScreen({ dark, onDone, defaultSelected = [] }) {
  const [selected, setSelected] = React.useState(defaultSelected);
  const fg = dark ? '#f4efe6' : '#1c1a15';
  const muted = dark ? 'rgba(244,239,230,0.6)' : 'rgba(28,26,21,0.55)';
  const stroke = dark ? 'rgba(255,255,255,0.07)' : 'rgba(28,26,21,0.08)';
  const accent = dark ? 'oklch(0.78 0.10 var(--cb-accent-hue))' : 'oklch(0.45 0.10 var(--cb-accent-hue))';

  const toggle = (id) => setSelected((s) =>
    s.includes(id) ? s.filter(x => x !== id) : (s.length >= 3 ? s : [...s, id])
  );

  return (
    <div style={{
      display: 'flex', flexDirection: 'column',
      padding: '72px 22px 32px', minHeight: '100%', boxSizing: 'border-box',
      gap: 28, color: fg,
    }}>
      <div>
        <div style={{ marginBottom: 18 }}>
          <ActovaLockup size={20} dark={dark}/>
        </div>
        <h1 style={{
          fontFamily: 'var(--cb-display)',
          fontWeight: 400, fontSize: 38, lineHeight: 1.1, margin: 0,
          letterSpacing: -0.6, textWrap: 'pretty',
        }}>What would you like to <em style={{ color: accent, fontStyle: 'italic' }}>act on</em> first?</h1>
        <p style={{
          margin: '14px 0 0', fontSize: 15, lineHeight: 1.5, color: muted, maxWidth: 320,
        }}>Pick up to three goals. We'll build a starter routine and surface the right tips for you. Change this any time.</p>
      </div>

      <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 10 }}>
        {GOALS.map((g) => {
          const on = selected.includes(g.id);
          return (
            <button key={g.id} onClick={() => toggle(g.id)}
              style={{
                all: 'unset', cursor: 'pointer',
                padding: '18px 16px',
                borderRadius: 16,
                border: `1px solid ${on ? accent : stroke}`,
                background: on
                  ? (dark ? 'oklch(0.25 0.04 var(--cb-accent-hue))' : 'oklch(0.96 0.04 var(--cb-accent-hue))')
                  : (dark ? 'rgba(255,255,255,0.025)' : '#fff'),
                display: 'flex', flexDirection: 'column', gap: 12,
                transition: 'all 0.15s',
              }}>
              <span style={{
                fontFamily: 'var(--cb-display)',
                fontSize: 26, lineHeight: 1, color: accent,
              }}>{g.emoji}</span>
              <span style={{
                fontSize: 14, fontWeight: 500, color: fg,
                lineHeight: 1.2, textWrap: 'pretty',
              }}>{g.label}</span>
            </button>
          );
        })}
      </div>

      <div style={{ flex: 1 }}/>
      <button
        onClick={() => selected.length && onDone(selected)}
        disabled={!selected.length}
        style={{
          all: 'unset', cursor: selected.length ? 'pointer' : 'not-allowed',
          background: selected.length
            ? (dark ? '#f4efe6' : '#1c1a15')
            : (dark ? 'rgba(255,255,255,0.08)' : 'rgba(28,26,21,0.08)'),
          color: selected.length
            ? (dark ? '#1c1a15' : '#fafaf7')
            : muted,
          textAlign: 'center', padding: '16px',
          borderRadius: 14, fontSize: 15, fontWeight: 600,
          letterSpacing: 0.1,
        }}>
        {selected.length
          ? 'Build my starter routine →'
          : 'Pick at least one goal'}
      </button>
    </div>
  );
}

function TodayScreen({ dark, routine, today, toggleToday, openTip, openRoutine, featuredTip, trackingVariant, cardVariant, streak }) {
  const fg = dark ? '#f4efe6' : '#1c1a15';
  const muted = dark ? 'rgba(244,239,230,0.55)' : 'rgba(28,26,21,0.55)';
  const stroke = dark ? 'rgba(255,255,255,0.07)' : 'rgba(28,26,21,0.08)';
  const accent = dark ? 'oklch(0.78 0.12 var(--cb-accent-hue))' : 'oklch(0.50 0.12 var(--cb-accent-hue))';
  const date = new Date();
  const dateStr = date.toLocaleDateString(undefined, { weekday: 'long', month: 'long', day: 'numeric' });

  const completedCount = routine.filter((t) => today[t.id]).length;
  const total = routine.length;
  const pct = total ? completedCount / total : 0;

  return (
    <div style={{ paddingBottom: 100 }}>
      <TopBar
        eyebrow={dateStr}
        title="Today"
        dark={dark}
        big
        right={<StreakBadge n={streak} dark={dark}/>}
      />

      <div style={{ padding: '0 20px 22px' }}>
        <div style={{
          background: dark ? 'rgba(255,255,255,0.04)' : '#fff',
          border: `0.5px solid ${stroke}`,
          borderRadius: 22, padding: '18px 18px',
          display: 'flex', alignItems: 'center', gap: 16,
        }}>
          <ProgressRing pct={pct} size={64} color={accent} track={dark ? 'rgba(255,255,255,0.08)' : 'rgba(28,26,21,0.06)'}/>
          <div style={{ flex: 1, minWidth: 0 }}>
            <div style={{ fontSize: 22, fontWeight: 600, color: fg, lineHeight: 1.1 }}>
              {completedCount}<span style={{ color: muted, fontWeight: 500 }}>/{total}</span>
              <span style={{ fontSize: 13, fontWeight: 500, color: muted, marginLeft: 8 }}>
                {pct === 1 ? '· Day complete' : pct === 0 ? '· Let\'s start' : '· In progress'}
              </span>
            </div>
            <div style={{ fontSize: 12.5, color: muted, marginTop: 4 }}>
              {routine.filter((t) => !today[t.id]).slice(0, 2).map(t => t.title).join(' · ') || 'Everything checked off.'}
            </div>
          </div>
        </div>
      </div>

      <div style={{ padding: '0 20px 22px' }}>
        <SectionHeader title="Your routine" dark={dark} right={
          <button onClick={openRoutine} style={{
            all: 'unset', cursor: 'pointer', fontSize: 12, color: muted,
          }}>Edit ›</button>
        }/>
        <TrackingWidget
          variant={trackingVariant}
          items={routine}
          state={today}
          onToggle={toggleToday}
          dark={dark}
          accent={accent}
        />
      </div>

      <div style={{ padding: '0 20px' }}>
        <SectionHeader title="Try something new" dark={dark}/>
        <div onClick={() => openTip(featuredTip.id)} style={{ cursor: 'pointer' }}>
          <TipCard variant={cardVariant} tip={featuredTip} dark={dark}
                   saved={false} onSave={() => {}}/>
        </div>
      </div>
    </div>
  );
}

function StreakBadge({ n, dark }) {
  const fg = dark ? '#f4efe6' : '#1c1a15';
  return (
    <span style={{
      display: 'inline-flex', alignItems: 'center', gap: 6,
      padding: '6px 12px', borderRadius: 999,
      background: dark ? 'rgba(255,255,255,0.06)' : 'rgba(28,26,21,0.05)',
      color: fg, fontSize: 13, fontWeight: 600,
    }}>
      <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round">
        <path d="M12 2c-1 3-4 5-4 9a4 4 0 008 0c0-2-1-3-2-4 0 2-1 3-2 3 0-3 2-5 0-8z"/>
      </svg>
      {n}d
    </span>
  );
}

function ProgressRing({ pct, size, color, track, stroke = 6 }) {
  const r = (size - stroke) / 2;
  const C = 2 * Math.PI * r;
  return (
    <svg width={size} height={size} style={{ flexShrink: 0 }}>
      <g transform={`rotate(-90 ${size/2} ${size/2})`}>
        <circle cx={size/2} cy={size/2} r={r} fill="none" stroke={track} strokeWidth={stroke}/>
        <circle cx={size/2} cy={size/2} r={r} fill="none" stroke={color} strokeWidth={stroke}
                strokeLinecap="round" strokeDasharray={C}
                strokeDashoffset={C * (1 - pct)}
                style={{ transition: 'stroke-dashoffset 0.6s cubic-bezier(.3,.7,.4,1)' }}/>
      </g>
    </svg>
  );
}

function SectionHeader({ title, right, dark }) {
  const fg = dark ? '#f4efe6' : '#1c1a15';
  return (
    <div style={{
      display: 'flex', alignItems: 'baseline', justifyContent: 'space-between',
      marginBottom: 12,
    }}>
      <h2 style={{
        margin: 0, fontSize: 13, fontWeight: 600, color: fg,
        letterSpacing: 0.8, textTransform: 'uppercase', whiteSpace: 'nowrap',
      }}>{title}</h2>
      {right}
    </div>
  );
}

function DiscoverScreen({ dark, openTip, saved, toggleSave, cardVariant }) {
  const [filter, setFilter] = React.useState('all');
  const [kindFilter, setKindFilter] = React.useState('all');
  const fg = dark ? '#f4efe6' : '#1c1a15';
  const muted = dark ? 'rgba(244,239,230,0.55)' : 'rgba(28,26,21,0.55)';

  const filtered = TIPS.filter(t =>
    (filter === 'all' || t.categories.includes(filter)) &&
    (kindFilter === 'all' || t.kind === kindFilter)
  );

  return (
    <div style={{ paddingBottom: 100 }}>
      <TopBar
        title="Discover"
        eyebrow={`${TIPS.length} tips · ${CATEGORIES.length} areas`}
        dark={dark} big
      />
      <div style={{
        display: 'flex', gap: 8, overflowX: 'auto', padding: '0 20px 14px',
        scrollbarWidth: 'none',
      }}>
        <Chip on={filter === 'all'} onClick={() => setFilter('all')} dark={dark}>All</Chip>
        {CATEGORIES.map(c => (
          <Chip key={c.id} on={filter === c.id} onClick={() => setFilter(c.id)} dark={dark}>
            <CategoryDot catId={c.id} size={6}/>
            <span style={{ marginLeft: 6 }}>{c.short}</span>
          </Chip>
        ))}
      </div>
      <div style={{
        display: 'flex', gap: 6, overflowX: 'auto', padding: '0 20px 18px',
        scrollbarWidth: 'none', fontSize: 11,
      }}>
        <SubChip on={kindFilter === 'all'} onClick={() => setKindFilter('all')} dark={dark}>Any kind</SubChip>
        {Object.entries(KIND_META).map(([k, m]) => (
          <SubChip key={k} on={kindFilter === k} onClick={() => setKindFilter(k)} dark={dark}>
            <KindGlyph kind={k} size={10}/> <span style={{ marginLeft: 4 }}>{m.label}</span>
          </SubChip>
        ))}
      </div>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 14, padding: '0 20px' }}>
        {filtered.length === 0 && (
          <div style={{ color: muted, fontSize: 13, padding: 24, textAlign: 'center' }}>
            No tips match those filters.
          </div>
        )}
        {filtered.map((tip) => (
          <TipCard
            key={tip.id}
            variant={cardVariant}
            tip={tip}
            dark={dark}
            saved={saved[tip.id]}
            onOpen={() => openTip(tip.id)}
            onSave={() => toggleSave(tip.id)}
          />
        ))}
      </div>
    </div>
  );
}

function Chip({ on, children, onClick, dark }) {
  const fg = dark ? '#f4efe6' : '#1c1a15';
  return (
    <button onClick={onClick} style={{
      all: 'unset', cursor: 'pointer', flexShrink: 0,
      padding: '7px 13px', borderRadius: 999,
      background: on
        ? (dark ? '#f4efe6' : '#1c1a15')
        : (dark ? 'rgba(255,255,255,0.06)' : 'rgba(28,26,21,0.05)'),
      color: on
        ? (dark ? '#1c1a15' : '#fafaf7')
        : fg,
      fontSize: 13, fontWeight: 500, whiteSpace: 'nowrap',
      display: 'inline-flex', alignItems: 'center',
    }}>{children}</button>
  );
}

function SubChip({ on, children, onClick, dark }) {
  const fg = dark ? '#f4efe6' : '#1c1a15';
  const muted = dark ? 'rgba(244,239,230,0.55)' : 'rgba(28,26,21,0.55)';
  return (
    <button onClick={onClick} style={{
      all: 'unset', cursor: 'pointer', flexShrink: 0,
      padding: '5px 10px', borderRadius: 8,
      background: 'transparent',
      color: on ? fg : muted,
      fontSize: 12, fontWeight: on ? 600 : 500, whiteSpace: 'nowrap',
      border: `1px solid ${on ? fg : (dark ? 'rgba(255,255,255,0.08)' : 'rgba(28,26,21,0.08)')}`,
      display: 'inline-flex', alignItems: 'center',
    }}>{children}</button>
  );
}

function DetailScreen({ tip, dark, onBack, saved, toggleSave }) {
  const fg = dark ? '#f4efe6' : '#1c1a15';
  const muted = dark ? 'rgba(244,239,230,0.55)' : 'rgba(28,26,21,0.55)';
  const stroke = dark ? 'rgba(255,255,255,0.07)' : 'rgba(28,26,21,0.08)';
  const card = dark ? 'rgba(255,255,255,0.04)' : '#fff';
  const accent = dark ? 'oklch(0.78 0.12 var(--cb-accent-hue))' : 'oklch(0.42 0.10 var(--cb-accent-hue))';
  const hue = CatHue(tip.primary);

  return (
    <div style={{ paddingBottom: 120, background: dark ? '#14120e' : 'oklch(0.97 0.008 80)' }}>
      <div style={{
        padding: '64px 22px 28px 22px',
        background: `linear-gradient(160deg,
          oklch(${dark ? '0.22' : '0.93'} 0.04 ${hue}) 0%,
          oklch(${dark ? '0.16' : '0.97'} 0.02 ${hue}) 100%)`,
        position: 'relative',
      }}>
        <div style={{
          display: 'flex', alignItems: 'center', justifyContent: 'space-between',
          marginBottom: 18,
        }}>
          <button onClick={onBack} style={{
            all: 'unset', cursor: 'pointer',
            width: 36, height: 36, borderRadius: 999,
            background: dark ? 'rgba(255,255,255,0.08)' : 'rgba(255,255,255,0.7)',
            display: 'flex', alignItems: 'center', justifyContent: 'center',
            color: fg, backdropFilter: 'blur(10px)',
          }}>
            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
              <path d="M15 18l-6-6 6-6"/>
            </svg>
          </button>
          <button onClick={() => toggleSave(tip.id)} style={{
            all: 'unset', cursor: 'pointer',
            display: 'inline-flex', alignItems: 'center', gap: 6,
            padding: '8px 14px', borderRadius: 999,
            background: saved
              ? (dark ? '#f4efe6' : '#1c1a15')
              : (dark ? 'rgba(255,255,255,0.08)' : 'rgba(255,255,255,0.7)'),
            color: saved
              ? (dark ? '#1c1a15' : '#fafaf7')
              : fg,
            fontSize: 12, fontWeight: 600,
            backdropFilter: 'blur(10px)',
          }}>
            <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round">
              {saved
                ? <path d="M5 12l4 4 10-10"/>
                : <path d="M12 5v14M5 12h14"/>}
            </svg>
            {saved ? 'In your routine' : 'Add to routine'}
          </button>
        </div>
        <span style={{
          fontFamily: 'var(--cb-mono)',
          fontSize: 10.5, letterSpacing: 1.5, textTransform: 'uppercase',
          color: dark ? `oklch(0.7 0.10 ${hue})` : `oklch(0.36 0.10 ${hue})`,
        }}>
          {CatLabel(tip.primary)} · {KIND_META[tip.kind].label}
        </span>
        <h1 style={{
          margin: '10px 0 0',
          fontFamily: 'var(--cb-display)', fontWeight: 400,
          fontSize: 38, lineHeight: 1.1, letterSpacing: -0.4,
          color: fg, textWrap: 'pretty',
        }}>{tip.title}</h1>
        <p style={{
          margin: '14px 0 0', fontSize: 15.5, lineHeight: 1.5, color: muted, textWrap: 'pretty',
        }}>{tip.summary}</p>
      </div>

      <div style={{ padding: '24px 22px 12px' }}>
        <div style={{
          padding: '18px 18px',
          borderRadius: 18,
          background: dark ? 'rgba(212,200,170,0.07)' : 'oklch(0.96 0.03 95)',
          border: `0.5px solid ${stroke}`,
          display: 'flex', gap: 14,
        }}>
          <div style={{
            width: 30, height: 30, borderRadius: 8,
            background: accent, color: dark ? '#1c1a15' : '#fafaf7',
            display: 'flex', alignItems: 'center', justifyContent: 'center',
            flexShrink: 0, marginTop: 1,
          }}>
            <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
              <path d="M5 12l4 4 10-10"/>
            </svg>
          </div>
          <div style={{ flex: 1 }}>
            <div style={{
              fontFamily: 'var(--cb-mono)',
              fontSize: 10, letterSpacing: 1.2, color: muted, textTransform: 'uppercase',
              marginBottom: 4,
            }}>Try this today</div>
            <div style={{ fontSize: 15, lineHeight: 1.45, color: fg }}>{tip.tryThis}</div>
          </div>
        </div>
      </div>

      <div style={{
        padding: '6px 22px 24px',
        display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 8,
      }}>
        <MetaCard label="Cadence" value={tip.cadence} dark={dark}/>
        <MetaCard label="Effort"  value={<EffortDots value={tip.effort} color={fg}/>} dark={dark}/>
        <MetaCard label="Cost"    value={<CostMarks value={tip.cost} color={fg}/>} dark={dark}/>
      </div>

      <Section title="Key takeaways" dark={dark}>
        <ul style={{
          margin: 0, padding: 0, listStyle: 'none',
          display: 'flex', flexDirection: 'column', gap: 10,
        }}>
          {tip.keyTakeaways.map((k, i) => (
            <li key={i} style={{
              display: 'grid', gridTemplateColumns: '22px 1fr', gap: 12,
              fontSize: 14.5, lineHeight: 1.4, color: fg,
            }}>
              <span style={{
                fontFamily: 'var(--cb-mono)', fontSize: 11,
                color: muted, paddingTop: 2,
              }}>{String(i + 1).padStart(2, '0')}</span>
              <span style={{ textWrap: 'pretty' }}>{k}</span>
            </li>
          ))}
        </ul>
      </Section>

      <Section title="What it does to your body" dark={dark}>
        <BodyDiagram effects={tip.positive} negative={tip.negative} dark={dark}/>
        <div style={{ marginTop: 16 }}>
          <SubLabel dark={dark}>Affects these systems</SubLabel>
          <BodySystemChips effects={tip.positive} dark={dark} max={20}/>
        </div>
        <div style={{ marginTop: 18 }}>
          <SubLabel dark={dark}>Effect intensity</SubLabel>
          <EffectBars positive={tip.positive} negative={tip.negative} dark={dark}/>
        </div>
      </Section>

      {tip.actions && tip.actions.length > 0 && (
        <Section title="Action steps" dark={dark}>
          <ol style={{
            margin: 0, padding: 0, listStyle: 'none',
            display: 'flex', flexDirection: 'column', gap: 8,
          }}>
            {tip.actions.map((a, i) => (
              <li key={i} style={{
                padding: '12px 14px',
                background: card, borderRadius: 12,
                border: `0.5px solid ${stroke}`,
                display: 'flex', alignItems: 'center', gap: 12,
                fontSize: 14, color: fg,
              }}>
                <span style={{
                  width: 22, height: 22, borderRadius: 999,
                  background: dark ? 'rgba(255,255,255,0.08)' : 'rgba(28,26,21,0.06)',
                  color: muted, display: 'flex', alignItems: 'center', justifyContent: 'center',
                  fontSize: 11, fontWeight: 600, flexShrink: 0,
                }}>{i + 1}</span>
                <span style={{ textWrap: 'pretty' }}>{a}</span>
              </li>
            ))}
          </ol>
        </Section>
      )}

      {tip.related && tip.related.length > 0 && (
        <Section title="Stacks well with" dark={dark}>
          <div style={{ display: 'flex', flexWrap: 'wrap', gap: 8 }}>
            {tip.related.map((r) => (
              <span key={r} style={{
                padding: '8px 14px', borderRadius: 999,
                background: card, border: `0.5px solid ${stroke}`,
                fontSize: 13, color: fg,
              }}>{r}</span>
            ))}
          </div>
        </Section>
      )}
    </div>
  );
}

function Section({ title, children, dark }) {
  const fg = dark ? '#f4efe6' : '#1c1a15';
  return (
    <div style={{ padding: '12px 22px 16px' }}>
      <h2 style={{
        margin: '0 0 14px', fontSize: 12, letterSpacing: 1, textTransform: 'uppercase',
        fontWeight: 600, color: fg,
      }}>{title}</h2>
      {children}
    </div>
  );
}

function SubLabel({ children, dark }) {
  const muted = dark ? 'rgba(244,239,230,0.55)' : 'rgba(28,26,21,0.55)';
  return (
    <div style={{
      fontFamily: 'var(--cb-mono)', fontSize: 10, letterSpacing: 1.2,
      textTransform: 'uppercase', color: muted, marginBottom: 10,
    }}>{children}</div>
  );
}

function MetaCard({ label, value, dark }) {
  const fg = dark ? '#f4efe6' : '#1c1a15';
  const muted = dark ? 'rgba(244,239,230,0.55)' : 'rgba(28,26,21,0.55)';
  const card = dark ? 'rgba(255,255,255,0.04)' : '#fff';
  const stroke = dark ? 'rgba(255,255,255,0.07)' : 'rgba(28,26,21,0.06)';
  return (
    <div style={{
      background: card, border: `0.5px solid ${stroke}`,
      padding: '12px 12px', borderRadius: 12,
      display: 'flex', flexDirection: 'column', gap: 4,
    }}>
      <span style={{ fontSize: 10, letterSpacing: 0.5, color: muted, textTransform: 'uppercase' }}>{label}</span>
      <span style={{ fontSize: 14, color: fg, fontWeight: 500, display: 'inline-flex', alignItems: 'center' }}>{value}</span>
    </div>
  );
}

function RoutineScreen({ dark, savedIds, toggleSave, openTip }) {
  const fg = dark ? '#f4efe6' : '#1c1a15';
  const muted = dark ? 'rgba(244,239,230,0.55)' : 'rgba(28,26,21,0.55)';
  const stroke = dark ? 'rgba(255,255,255,0.07)' : 'rgba(28,26,21,0.08)';
  const card = dark ? 'rgba(255,255,255,0.04)' : '#fff';
  const routineTips = TIPS.filter(t => savedIds[t.id]);
  const groups = {};
  routineTips.forEach(t => {
    (groups[t.cadence] = groups[t.cadence] || []).push(t);
  });
  const cadences = ['Daily', 'Weekly', 'One-time'];
  return (
    <div style={{ paddingBottom: 100 }}>
      <TopBar
        title="My Routine"
        eyebrow={`${routineTips.length} active`}
        dark={dark} big
      />
      <div style={{ padding: '0 20px' }}>
        {routineTips.length === 0 ? (
          <div style={{
            padding: '40px 20px', textAlign: 'center', color: muted,
            border: `0.5px dashed ${stroke}`, borderRadius: 18,
          }}>
            <div style={{
              fontFamily: 'var(--cb-display)',
              fontSize: 22, color: fg, marginBottom: 6,
            }}>Your routine is empty.</div>
            <div style={{ fontSize: 13, lineHeight: 1.5 }}>Discover a few tips and tap "Add to routine" to start.</div>
          </div>
        ) : (
          cadences.map((c) => groups[c] && (
            <div key={c} style={{ marginBottom: 22 }}>
              <SectionHeader title={c} dark={dark} right={
                <span style={{ fontSize: 12, color: muted }}>{groups[c].length}</span>
              }/>
              <div style={{
                background: card, borderRadius: 18,
                border: `0.5px solid ${stroke}`, overflow: 'hidden',
              }}>
                {groups[c].map((tip, i) => (
                  <div key={tip.id}
                    onClick={() => openTip(tip.id)}
                    style={{
                      display: 'flex', alignItems: 'center', gap: 12,
                      padding: '14px 16px', cursor: 'pointer',
                      borderTop: i === 0 ? 0 : `0.5px solid ${stroke}`,
                    }}>
                    <span style={{
                      width: 32, height: 32, borderRadius: 9,
                      background: `oklch(0.93 0.04 ${CatHue(tip.primary)})`,
                      color: `oklch(0.32 0.10 ${CatHue(tip.primary)})`,
                      display: 'flex', alignItems: 'center', justifyContent: 'center',
                      flexShrink: 0,
                    }}>
                      <KindGlyph kind={tip.kind} size={16} color="currentColor"/>
                    </span>
                    <div style={{ flex: 1, minWidth: 0 }}>
                      <div style={{ fontSize: 15, color: fg, fontWeight: 500, lineHeight: 1.2 }}>{tip.title}</div>
                      <div style={{ fontSize: 11.5, color: muted, marginTop: 3 }}>
                        {CatLabel(tip.primary)} · Effort{' '}
                        <EffortDots value={tip.effort} color={muted}/>
                      </div>
                    </div>
                    <button onClick={(e) => { e.stopPropagation(); toggleSave(tip.id); }}
                      style={{
                        all: 'unset', cursor: 'pointer',
                        padding: '5px 10px', borderRadius: 8,
                        fontSize: 11, color: muted,
                        background: dark ? 'rgba(255,255,255,0.05)' : 'rgba(28,26,21,0.04)',
                      }}>Remove</button>
                  </div>
                ))}
              </div>
            </div>
          ))
        )}
      </div>
    </div>
  );
}

function ProgressScreen({ dark, routine, history }) {
  const fg = dark ? '#f4efe6' : '#1c1a15';
  const muted = dark ? 'rgba(244,239,230,0.55)' : 'rgba(28,26,21,0.55)';
  const stroke = dark ? 'rgba(255,255,255,0.07)' : 'rgba(28,26,21,0.08)';
  const card = dark ? 'rgba(255,255,255,0.04)' : '#fff';

  const days = 28;
  const today = new Date(); today.setHours(0,0,0,0);
  const cells = Array.from({ length: days }).map((_, i) => {
    const d = new Date(today); d.setDate(d.getDate() - (days - 1 - i));
    const key = d.toISOString().slice(0, 10);
    const completed = history[key] || 0;
    return { date: d, key, completed };
  });

  const streakDays = (() => {
    let s = 0;
    for (let i = cells.length - 1; i >= 0; i--) {
      if (cells[i].completed > 0.5) s++; else break;
    }
    return s;
  })();
  const avg = cells.reduce((a, c) => a + c.completed, 0) / cells.length;

  return (
    <div style={{ paddingBottom: 100 }}>
      <TopBar title="Progress" eyebrow="Last 28 days" dark={dark} big/>

      <div style={{ padding: '0 20px 18px' }}>
        <div style={{
          background: card, borderRadius: 22, padding: 20,
          border: `0.5px solid ${stroke}`,
          display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 14,
        }}>
          <BigStat n={streakDays} label="Day streak" suffix="d" dark={dark}/>
          <BigStat n={Math.round(avg * 100)} label="Completion" suffix="%" dark={dark}/>
        </div>
      </div>

      <Section title="Activity" dark={dark}>
        <div style={{
          background: card, borderRadius: 18, padding: 16,
          border: `0.5px solid ${stroke}`,
        }}>
          <div style={{
            display: 'grid',
            gridTemplateColumns: 'repeat(7, 1fr)',
            gap: 6,
          }}>
            {cells.map((c, i) => {
              const pct = c.completed;
              const isToday = i === cells.length - 1;
              const color = pct === 0
                ? (dark ? 'rgba(255,255,255,0.06)' : 'rgba(28,26,21,0.05)')
                : `oklch(${dark ? 0.4 + pct * 0.35 : 0.92 - pct * 0.3} 0.12 var(--cb-accent-hue))`;
              return (
                <div key={c.key} style={{
                  aspectRatio: '1/1', borderRadius: 6,
                  background: color,
                  border: isToday ? `1.5px solid ${dark ? '#f4efe6' : '#1c1a15'}` : 'none',
                }}/>
              );
            })}
          </div>
          <div style={{
            display: 'flex', justifyContent: 'space-between',
            marginTop: 12, fontSize: 10, color: muted,
            letterSpacing: 0.4, textTransform: 'uppercase',
          }}>
            <span>28d ago</span>
            <span>Today</span>
          </div>
        </div>
      </Section>

      <Section title="Per habit" dark={dark}>
        <div style={{
          background: card, borderRadius: 18,
          border: `0.5px solid ${stroke}`, overflow: 'hidden',
        }}>
          {routine.map((t, i) => {
            const score = 0.4 + (((t.id.charCodeAt(0) || 1) % 7) / 12);
            return (
              <div key={t.id} style={{
                display: 'flex', alignItems: 'center', gap: 12,
                padding: '12px 16px',
                borderTop: i === 0 ? 0 : `0.5px solid ${stroke}`,
              }}>
                <span style={{
                  width: 26, height: 26, borderRadius: 7,
                  background: `oklch(0.93 0.04 ${CatHue(t.primary)})`,
                  color: `oklch(0.32 0.10 ${CatHue(t.primary)})`,
                  display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0,
                }}>
                  <KindGlyph kind={t.kind} size={13} color="currentColor"/>
                </span>
                <span style={{ flex: 1, fontSize: 13.5, color: fg }}>{t.title}</span>
                <div style={{
                  width: 80, height: 6, borderRadius: 999,
                  background: dark ? 'rgba(255,255,255,0.06)' : 'rgba(28,26,21,0.06)',
                  position: 'relative',
                }}>
                  <div style={{
                    position: 'absolute', left: 0, top: 0, bottom: 0,
                    width: `${score * 100}%`, borderRadius: 999,
                    background: 'oklch(0.62 0.13 var(--cb-accent-hue))',
                  }}/>
                </div>
                <span style={{ fontSize: 12, color: muted, width: 32, textAlign: 'right' }}>{Math.round(score * 100)}%</span>
              </div>
            );
          })}
        </div>
      </Section>
    </div>
  );
}

function BigStat({ n, suffix, label, dark }) {
  const fg = dark ? '#f4efe6' : '#1c1a15';
  const muted = dark ? 'rgba(244,239,230,0.55)' : 'rgba(28,26,21,0.55)';
  return (
    <div>
      <div style={{
        fontFamily: 'var(--cb-display)', fontWeight: 400,
        fontSize: 42, lineHeight: 1, letterSpacing: -1, color: fg,
      }}>
        {n}<span style={{ fontSize: 22, color: muted }}>{suffix}</span>
      </div>
      <div style={{ fontSize: 11.5, color: muted, letterSpacing: 0.5, textTransform: 'uppercase', marginTop: 6 }}>
        {label}
      </div>
    </div>
  );
}

Object.assign(window, {
  TopBar, BottomNav, OnboardScreen, TodayScreen, DiscoverScreen,
  DetailScreen, RoutineScreen, ProgressScreen,
  ProgressRing, SectionHeader,
});
