/* WildTrack — Section 4 — Component Library */

function ComponentsPage() {
  const [theme, setTheme] = React.useState('light');
  const isDark = theme === 'dark';
  const bg = isDark ? '#0F1F18' : '#FAFAFA';
  const fg = isDark ? '#F6F1E7' : '#1B1B1B';
  const muted = isDark ? '#8BAF96' : '#6C757D';
  const surface = isDark ? '#1A2F22' : 'white';
  const border = isDark ? '#2A4A38' : '#E0E0E0';

  return (
    <div style={{ background: bg, color: fg, minHeight: '100vh' }}>
      <PageHeader active="Components" dark={isDark}/>

      <main style={{ maxWidth: 1280, margin: '0 auto', padding: '64px 48px 96px' }}>
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', marginBottom: 64, gap: 48 }}>
          <div>
            <div className="font-mono" style={{ fontSize: 11, letterSpacing: '0.22em', textTransform: 'uppercase', color: '#52B788', fontWeight: 500, marginBottom: 24 }}>
              Section 04 · Components
            </div>
            <h2 className="font-display" style={{ fontSize: 56, fontWeight: 700, margin: 0, lineHeight: 1.0, letterSpacing: '-0.025em', color: fg }}>
              Every atom in<br/>the system.
            </h2>
            <p style={{ fontSize: 17, color: muted, marginTop: 24, maxWidth: 560, lineHeight: 1.55 }}>
              Buttons, badges, inputs, cards, nav patterns, map overlays, empty and loading states — at rest and in motion, in both modes.
            </p>
          </div>
          <ThemeToggle theme={theme} setTheme={setTheme}/>
        </div>

        <CompSection label="01" title="Buttons" sub="Primary fills the platform action. Secondary frames. Danger is reserved for emergency operations. No drop shadows; pressed state moves on the border, not depth." dark={isDark}>
          <CompButtons dark={isDark}/>
        </CompSection>

        <CompSection label="02" title="Status pills" sub="Five states across the lifecycle. Pills use 20px radius — the only place we exceed 12px corners — and 12px horizontal padding." dark={isDark}>
          <CompBadges dark={isDark}/>
        </CompSection>

        <CompSection label="03" title="Inputs" sub="42px tall, 8px corners, 1px borders. Focus is a 2px accent ring — never replaces the border, so layout doesn't shift. Error swaps the border, never the ring." dark={isDark}>
          <CompInputs dark={isDark}/>
        </CompSection>

        <CompSection label="04" title="Cards" sub="Four card archetypes cover every data surface: tag summary, session, alert, and KPI. All share 12px corners and the same border-as-elevation system." dark={isDark}>
          <CompCards dark={isDark}/>
        </CompSection>

        <CompSection label="05" title="Navigation" sub="A vertical sidebar for the desk view, a five-tab bottom bar on mobile, and a sticky top bar carrying breadcrumb plus user state. Active state always reads as a strong colour shift, never animation alone." dark={isDark}>
          <CompNav dark={isDark}/>
        </CompSection>

        <CompSection label="06" title="Map overlays" sub="The map carries its own visual language. Polygons, pins, GPS dots, and exclusion areas all share one stroke weight, one corner radius, and a fixed colour grammar." dark={isDark}>
          <CompMapOverlays dark={isDark}/>
        </CompSection>

        <CompSection label="07" title="Empty states" sub="Zero is a moment — make it useful. Every empty has an icon, a one-liner, a sentence, and a call to action." dark={isDark}>
          <CompEmpty dark={isDark}/>
        </CompSection>

        <CompSection label="08" title="Loading states" sub="Skeletons match the shape and rhythm of the component they replace. Never spinners alone for content load; spinners only for foreground actions." dark={isDark}>
          <CompLoading dark={isDark}/>
        </CompSection>
      </main>
    </div>
  );
}

function ThemeToggle({ theme, setTheme }) {
  return (
    <div style={{
      display: 'flex', padding: 4, borderRadius: 999,
      background: theme === 'dark' ? '#1A2F22' : '#F5F5F5',
      border: '1px solid ' + (theme === 'dark' ? '#2A4A38' : '#E0E0E0'),
      gap: 2,
    }}>
      {[
        { v: 'light', l: 'Light' },
        { v: 'dark', l: 'Dark' },
      ].map(o => (
        <button key={o.v} onClick={() => setTheme(o.v)} style={{
          padding: '8px 18px', borderRadius: 999, border: 'none',
          background: theme === o.v ? '#2D6A4F' : 'transparent',
          color: theme === o.v ? 'white' : (theme === 'dark' ? '#8BAF96' : '#6C757D'),
          fontFamily: 'DM Sans, sans-serif', fontWeight: 500, fontSize: 13,
          cursor: 'pointer',
        }}>{o.l}</button>
      ))}
    </div>
  );
}

function PageHeader({ active, dark }) {
  const sections = ['Overview', 'Brand', 'Mobile', 'Portal', 'Components', 'Modes'];
  const links = { Overview: 'system.html', Brand: 'Brand.html', Mobile: 'Mobile.html', Portal: 'Portal.html', Components: 'Components.html', Modes: 'Modes.html' };
  return (
    <header className="rh-page-header" style={{ background: dark ? '#000' : '#1B1B1B' }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 14 }}>
        <svg width="32" height="32" viewBox="0 0 200 200">
          <circle cx="100" cy="100" r="78" fill="none" stroke="#52B788" strokeWidth="6" strokeDasharray="38 22" transform="rotate(-20 100 100)"/>
          <circle cx="100" cy="100" r="58" fill="none" stroke="#52B788" strokeWidth="3"/>
          <path d="M100 70 C82 70 78 86 88 100 L100 124 L112 100 C122 86 118 70 100 70 Z" fill="#52B788"/>
        </svg>
        <div>
          <div className="rh-eyebrow">Section 04</div>
          <h1>Component Library</h1>
        </div>
      </div>
      <nav className="rh-nav">
        {sections.map(s => <a key={s} href={links[s]} className={s === active ? 'active' : ''}>{s}</a>)}
      </nav>
    </header>
  );
}

function CompSection({ label, title, sub, dark, children }) {
  const muted = dark ? '#8BAF96' : '#6C757D';
  const fg = dark ? '#F6F1E7' : '#1B1B1B';
  const border = dark ? '#2A4A38' : '#EAEAEA';
  return (
    <section style={{ paddingTop: 64, paddingBottom: 64, borderTop: '1px solid ' + border }}>
      <div style={{ display: 'grid', gridTemplateColumns: '1fr 2fr', gap: 64, marginBottom: 40 }}>
        <div>
          <span className="font-mono" style={{ fontSize: 11, letterSpacing: '0.22em', color: '#52B788', textTransform: 'uppercase', fontWeight: 500 }}>
            04.{label}
          </span>
          <h3 className="font-display" style={{ fontSize: 32, fontWeight: 700, margin: '8px 0 0', color: fg, letterSpacing: '-0.015em' }}>
            {title}
          </h3>
        </div>
        <p style={{ fontSize: 15, color: muted, lineHeight: 1.55, margin: 0, alignSelf: 'flex-end' }}>{sub}</p>
      </div>
      {children}
    </section>
  );
}

function Frame({ dark, label, children, span = 1, padded = true }) {
  const bg = dark ? '#1A2F22' : 'white';
  const border = dark ? '#2A4A38' : '#E0E0E0';
  const muted = dark ? '#8BAF96' : '#6C757D';
  return (
    <div style={{
      gridColumn: `span ${span}`,
      border: '1px solid ' + border,
      borderRadius: 12,
      background: bg,
      overflow: 'hidden',
    }}>
      <div style={{
        padding: '12px 16px', borderBottom: '1px solid ' + border,
        fontFamily: 'JetBrains Mono, monospace', fontSize: 10, letterSpacing: '0.2em',
        color: muted, textTransform: 'uppercase',
        display: 'flex', justifyContent: 'space-between', alignItems: 'center',
      }}>
        <span>{label}</span>
      </div>
      <div style={{ padding: padded ? 24 : 0 }}>{children}</div>
    </div>
  );
}

/* ─── BUTTONS ─── */
function CompButtons({ dark }) {
  return (
    <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 16 }}>
      <Frame dark={dark} label="Primary · all states">
        <Row>
          <button className="rh-btn rh-btn-primary">Register Tag</button>
          <button className="rh-btn rh-btn-primary" style={{ background: '#1B4332' }}>Hovered</button>
          <button className="rh-btn rh-btn-primary" style={{ background: '#0F2E22', transform: 'translateY(1px)' }}>Pressed</button>
          <button className="rh-btn rh-btn-disabled" disabled>Disabled</button>
        </Row>
        <Row style={{ marginTop: 12 }}>
          <button className="rh-btn rh-btn-primary">
            <Icon.Loader size={14} stroke="white" sw={2}/> Loading…
          </button>
        </Row>
      </Frame>

      <Frame dark={dark} label="Secondary · outline">
        <Row>
          <button className="rh-btn rh-btn-secondary">View Map</button>
          <button className="rh-btn rh-btn-secondary" style={{ background: '#D8F3DC' }}>Hovered</button>
          <button className="rh-btn rh-btn-secondary" style={{ background: '#B8E5C2' }}>Pressed</button>
          <button className="rh-btn rh-btn-disabled" disabled>Disabled</button>
        </Row>
      </Frame>

      <Frame dark={dark} label="Danger · emergency only">
        <Row>
          <button className="rh-btn rh-btn-danger">
            <Icon.Alert size={16} stroke="white"/> Emergency Alert
          </button>
          <button className="rh-btn rh-btn-danger" style={{ background: '#A03224' }}>
            <Icon.Alert size={16} stroke="white"/> Hovered
          </button>
          <button className="rh-btn rh-btn-danger" style={{ background: '#7C271C' }}>
            <Icon.Alert size={16} stroke="white"/> Pressed
          </button>
        </Row>
        <div style={{ marginTop: 12, fontSize: 11, color: '#C0392B', fontFamily: 'JetBrains Mono, monospace', letterSpacing: '0.12em' }}>
          ⚠ Never use for non-emergency confirmations or destructive UI.
        </div>
      </Frame>

      <Frame dark={dark} label="Icon button">
        <Row>
          {[<Icon.Plus size={18}/>, <Icon.Edit size={18}/>, <Icon.Eye size={18}/>, <Icon.Share size={18}/>, <Icon.Download size={18}/>].map((ico, i) => (
            <button key={i} style={{
              width: 38, height: 38, borderRadius: 8,
              background: dark ? 'rgba(255,255,255,0.05)' : '#F5F5F5',
              border: '1px solid ' + (dark ? '#2A4A38' : '#E0E0E0'),
              color: dark ? '#F6F1E7' : '#1B1B1B',
              display: 'flex', alignItems: 'center', justifyContent: 'center', cursor: 'pointer',
            }}>{React.cloneElement(ico, { stroke: 'currentColor' })}</button>
          ))}
        </Row>
        <Row style={{ marginTop: 12 }}>
          <button className="rh-btn rh-btn-secondary" style={{ padding: '8px 14px' }}>
            <Icon.Plus size={14} stroke="#2D6A4F"/> New Zone
          </button>
          <button className="rh-btn rh-btn-primary" style={{ padding: '8px 14px' }}>
            <Icon.Download size={14} stroke="white"/> Export
          </button>
        </Row>
      </Frame>
    </div>
  );
}

function Row({ children, style }) {
  return <div style={{ display: 'flex', flexWrap: 'wrap', gap: 10, alignItems: 'center', ...style }}>{children}</div>;
}

/* ─── BADGES ─── */
function CompBadges({ dark }) {
  const badges = [
    { cls: 'rh-badge-active', l: 'Active' },
    { cls: 'rh-badge-pending', l: 'Pending' },
    { cls: 'rh-badge-processing', l: 'Processing' },
    { cls: 'rh-badge-emergency', l: 'Emergency' },
    { cls: 'rh-badge-archived', l: 'Archived' },
  ];
  return (
    <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 16 }}>
      <Frame dark={dark} label="Default size · 13px">
        <Row>{badges.map(b => <span key={b.l} className={'rh-badge ' + b.cls}>{b.l}</span>)}</Row>
      </Frame>
      <Frame dark={dark} label="Small · 11px · table use">
        <Row>{badges.map(b => <span key={b.l} className={'rh-badge ' + b.cls} style={{ fontSize: 11, padding: '2px 9px' }}>{b.l}</span>)}</Row>
      </Frame>
    </div>
  );
}

/* ─── INPUTS ─── */
function CompInputs({ dark }) {
  return (
    <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 16 }}>
      <Frame dark={dark} label="Text input · states">
        <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
          <Input label="Tag ID" value="" state="default" dark={dark} placeholder="WT-2026-00000"/>
          <Input label="Operative" value="J. MacAllister" state="focus" dark={dark}/>
          <Input label="GPS accuracy" value="± 22m — outside zone radius" state="error" dark={dark} error="GPS accuracy below 10m required."/>
          <Input label="Organisation" value="Highland Estate Mgmt" state="disabled" dark={dark}/>
        </div>
      </Frame>

      <Frame dark={dark} label="Select · search · textarea">
        <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
          <div>
            <SmallLabel dark={dark}>Species</SmallLabel>
            <div style={{
              height: 42, padding: '0 14px', display: 'flex', alignItems: 'center', justifyContent: 'space-between',
              borderRadius: 8, border: '1px solid ' + (dark ? '#2A4A38' : '#D0D0D0'),
              fontSize: 14, color: dark ? '#F6F1E7' : '#1B1B1B', background: dark ? '#0F1F18' : 'white',
            }}>
              <span>Red Deer (Cervus elaphus)</span>
              <Icon.ChevronDown size={16} stroke={dark ? '#8BAF96' : '#6C757D'}/>
            </div>
          </div>
          <div>
            <SmallLabel dark={dark}>Search</SmallLabel>
            <div style={{
              height: 42, padding: '0 14px', display: 'flex', alignItems: 'center', gap: 10,
              borderRadius: 8, border: '1px solid ' + (dark ? '#2A4A38' : '#D0D0D0'),
              background: dark ? '#0F1F18' : 'white',
            }}>
              <Icon.Search size={16} stroke={dark ? '#8BAF96' : '#6C757D'}/>
              <span style={{ fontSize: 14, color: dark ? '#8BAF96' : '#6C757D' }}>Search tags, members, zones…</span>
              <span style={{ marginLeft: 'auto', fontFamily: 'JetBrains Mono, monospace', fontSize: 10, color: dark ? '#8BAF96' : '#B0B0B0' }}>⌘K</span>
            </div>
          </div>
          <div>
            <SmallLabel dark={dark}>Field notes</SmallLabel>
            <div style={{
              padding: '12px 14px', borderRadius: 8,
              border: '1px solid ' + (dark ? '#2A4A38' : '#D0D0D0'),
              background: dark ? '#0F1F18' : 'white',
              fontSize: 14, color: dark ? '#8BAF96' : '#B0B0B0',
              minHeight: 70,
            }}>
              Add field notes (optional)…
            </div>
          </div>
        </div>
      </Frame>
    </div>
  );
}

function SmallLabel({ children, dark }) {
  return (
    <div style={{ fontSize: 13, fontWeight: 500, color: dark ? '#F6F1E7' : '#4A4A4A', marginBottom: 4 }}>{children}</div>
  );
}

function Input({ label, value, state, dark, placeholder, error }) {
  const isFocus = state === 'focus';
  const isErr = state === 'error';
  const isDis = state === 'disabled';
  const border = isFocus ? '2px solid #52B788' : isErr ? '1px solid #C0392B' : '1px solid ' + (dark ? '#2A4A38' : '#D0D0D0');
  const bg = isDis ? (dark ? '#0F1F18' : '#F5F5F5') : (dark ? '#0F1F18' : 'white');
  return (
    <div>
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 4 }}>
        <SmallLabel dark={dark}>{label}</SmallLabel>
        <span className="font-mono" style={{ fontSize: 10, color: dark ? '#8BAF96' : '#B0B0B0', letterSpacing: '0.1em', textTransform: 'uppercase' }}>{state}</span>
      </div>
      <div style={{
        height: 42, padding: '0 14px', display: 'flex', alignItems: 'center',
        borderRadius: 8, border, background: bg,
        fontSize: 14, color: isErr ? '#C0392B' : (dark ? '#F6F1E7' : '#1B1B1B'),
        boxShadow: isFocus ? '0 0 0 3px rgba(82,183,136,0.18)' : 'none',
        fontFamily: label.toLowerCase().includes('id') ? 'JetBrains Mono, monospace' : 'DM Sans, sans-serif',
        opacity: isDis ? 0.6 : 1,
      }}>
        {value || <span style={{ color: dark ? '#8BAF96' : '#B0B0B0' }}>{placeholder}</span>}
      </div>
      {error && <div style={{ fontSize: 12, color: '#C0392B', marginTop: 4 }}>{error}</div>}
    </div>
  );
}

/* ─── CARDS ─── */
function CompCards({ dark }) {
  const surface = dark ? '#1A2F22' : 'white';
  const border = dark ? '#2A4A38' : '#E0E0E0';
  const fg = dark ? '#F6F1E7' : '#1B1B1B';
  const muted = dark ? '#8BAF96' : '#6C757D';
  return (
    <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 16 }}>
      {/* Tag summary */}
      <Frame dark={dark} label="Tag summary card">
        <div style={{ background: surface, border: '1px solid ' + border, borderRadius: 12, padding: 16, display: 'grid', gridTemplateColumns: '40px 1fr auto', gap: 14, alignItems: 'center' }}>
          <div style={{ width: 40, height: 40, borderRadius: 10, background: dark ? '#1B4332' : '#D8F3DC', display: 'flex', alignItems: 'center', justifyContent: 'center', color: dark ? '#52B788' : '#2D6A4F' }}>
            <Icon.Deer size={22} stroke="currentColor"/>
          </div>
          <div>
            <div style={{ display: 'flex', alignItems: 'baseline', gap: 8, marginBottom: 4 }}>
              <span className="font-mono" style={{ fontSize: 13, fontWeight: 500, color: fg }}>WT-2026-00042</span>
              <span className="rh-badge rh-badge-active" style={{ fontSize: 10, padding: '2px 8px' }}>Tagged</span>
            </div>
            <div style={{ fontSize: 14, color: fg, fontWeight: 500 }}>Red Deer · Harvest</div>
            <div style={{ fontSize: 12, color: muted, marginTop: 2 }}>J. MacAllister · 14:22 · Lake District A</div>
          </div>
          <Icon.ChevronRight size={20} stroke={muted}/>
        </div>
      </Frame>

      {/* Session card */}
      <Frame dark={dark} label="Session card">
        <div style={{ background: surface, border: '1px solid ' + border, borderRadius: 12, padding: 16 }}>
          <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', marginBottom: 12 }}>
            <div>
              <div className="font-mono" style={{ fontSize: 10, color: muted, letterSpacing: '0.18em', textTransform: 'uppercase', marginBottom: 6 }}>
                Session · 14 May 2026
              </div>
              <div className="font-display" style={{ fontSize: 18, fontWeight: 600, color: fg }}>Lake District Zone A</div>
            </div>
            <span className="rh-badge rh-badge-active" style={{ fontSize: 11 }}>Complete</span>
          </div>
          <div style={{ height: 60, borderRadius: 8, overflow: 'hidden', marginBottom: 12, position: 'relative', background: '#1A2332' }}>
            <svg width="100%" height="60" viewBox="0 0 320 60" preserveAspectRatio="none">
              <path d="M10,40 C60,20 100,30 160,25 S260,50 310,30" stroke="#52B788" strokeWidth="2.5" fill="none" strokeLinecap="round"/>
              <circle cx="10" cy="40" r="4" fill="#52B788"/>
              <circle cx="310" cy="30" r="4" fill="#E9C46A"/>
            </svg>
          </div>
          <div style={{ display: 'flex', justifyContent: 'space-between', fontSize: 12, color: muted }}>
            <span><span style={{ fontFamily: 'JetBrains Mono, monospace', color: fg, fontWeight: 500 }}>3h 14m</span> · duration</span>
            <span><span style={{ fontFamily: 'JetBrains Mono, monospace', color: fg, fontWeight: 500 }}>8.2km</span> · distance</span>
            <span><span style={{ fontFamily: 'JetBrains Mono, monospace', color: fg, fontWeight: 500 }}>4</span> · tags</span>
          </div>
        </div>
      </Frame>

      {/* Alert card */}
      <Frame dark={dark} label="Alert card · emergency">
        <div style={{ border: '1px solid #C0392B', borderRadius: 12, padding: 16, position: 'relative', overflow: 'hidden', background: dark ? 'rgba(192,57,43,0.08)' : '#FDF5F4' }}>
          <div style={{ position: 'absolute', top: 0, left: 0, bottom: 0, width: 4, background: '#C0392B' }}/>
          <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: 8 }}>
            <div className="font-mono" style={{ fontSize: 10, letterSpacing: '0.22em', color: '#C0392B', textTransform: 'uppercase', fontWeight: 600 }}>
              ● Active Alert
            </div>
            <span style={{ fontFamily: 'JetBrains Mono, monospace', fontSize: 11, color: '#C0392B', fontWeight: 600 }}>2 min ago</span>
          </div>
          <div className="font-display" style={{ fontSize: 18, fontWeight: 700, color: fg, marginBottom: 4 }}>J. MacAllister</div>
          <div style={{ fontSize: 13, color: muted, marginBottom: 12 }}>Lake District Zone A · Active session</div>
          <div style={{ fontFamily: 'JetBrains Mono, monospace', fontSize: 12, color: muted }}>54.4621°N · 2.3010°W · ± 4m</div>
        </div>
      </Frame>

      {/* KPI */}
      <Frame dark={dark} label="KPI metric card">
        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12 }}>
          {[
            { l: 'Tags today', v: '12', t: '+4 in last hour', color: muted },
            { l: 'Members online', v: '7', sx: '/14', t: '50% of roster', color: muted },
          ].map(k => (
            <div key={k.l} style={{ border: '1px solid ' + border, background: surface, borderRadius: 12, padding: 16 }}>
              <div className="font-mono" style={{ fontSize: 10, letterSpacing: '0.2em', color: muted, textTransform: 'uppercase', marginBottom: 12 }}>
                {k.l}
              </div>
              <div style={{ display: 'flex', alignItems: 'baseline', gap: 6, marginBottom: 6 }}>
                <span className="font-display" style={{ fontSize: 32, fontWeight: 700, color: fg, letterSpacing: '-0.02em', lineHeight: 1 }}>{k.v}</span>
                {k.sx && <span style={{ fontSize: 13, color: muted }}>{k.sx}</span>}
              </div>
              <div style={{ fontSize: 12, color: k.color }}>{k.t}</div>
            </div>
          ))}
        </div>
      </Frame>
    </div>
  );
}

/* ─── NAV ─── */
function CompNav({ dark }) {
  const border = dark ? '#2A4A38' : '#E0E0E0';
  const fg = dark ? '#F6F1E7' : '#1B1B1B';
  const muted = dark ? '#8BAF96' : '#6C757D';
  return (
    <div style={{ display: 'grid', gridTemplateColumns: '260px 1fr', gap: 16 }}>
      <Frame dark={dark} label="Sidebar · web portal" padded={false}>
        <div style={{
          background: '#1B1B1B', color: 'white', padding: 12, minHeight: 380,
          display: 'flex', flexDirection: 'column', gap: 2,
        }}>
          <div className="font-mono" style={{ fontSize: 10, letterSpacing: '0.22em', color: '#8BAF96', padding: '8px 12px 12px', textTransform: 'uppercase' }}>
            Navigation
          </div>
          {[
            ['Dashboard', Icon.Chart, true],
            ['Zones', Icon.Map],
            ['Sessions', Icon.Briefcase],
            ['Tags', Icon.Tag],
            ['Users', Icon.Users],
            ['Alerts', Icon.Alert, false, 1],
            ['Reports', Icon.File],
            ['Settings', Icon.Settings],
          ].map(([l, Ico, active, badge]) => (
            <div key={l} style={{
              display: 'flex', alignItems: 'center', gap: 12,
              padding: '9px 12px',
              borderLeft: '3px solid ' + (active ? '#52B788' : 'transparent'),
              background: active ? 'rgba(82,183,136,0.08)' : 'transparent',
              color: active ? 'white' : 'rgba(255,255,255,0.6)',
              borderRadius: '0 8px 8px 0',
              fontSize: 13, fontWeight: 500,
            }}>
              <Ico size={16} stroke="currentColor"/>
              <span style={{ flex: 1 }}>{l}</span>
              {badge && <span style={{ fontSize: 10, padding: '1px 6px', borderRadius: 999, background: '#C0392B', fontWeight: 600 }}>{badge}</span>}
            </div>
          ))}
        </div>
      </Frame>

      <div style={{ display: 'grid', gridTemplateRows: 'auto auto', gap: 16 }}>
        <Frame dark={dark} label="Top bar · web" padded={false}>
          <div style={{
            padding: '14px 20px',
            background: dark ? '#1A2F22' : 'white',
            display: 'flex', justifyContent: 'space-between', alignItems: 'center',
          }}>
            <div>
              <div className="font-mono" style={{ fontSize: 10, letterSpacing: '0.18em', color: muted, textTransform: 'uppercase' }}>
                Zones · Lake District A
              </div>
              <div className="font-display" style={{ fontSize: 20, fontWeight: 700, color: fg, marginTop: 2 }}>
                Members
              </div>
            </div>
            <div style={{ display: 'flex', gap: 12, alignItems: 'center' }}>
              <Icon.Bell size={18} stroke={muted}/>
              <div style={{ width: 32, height: 32, borderRadius: 16, background: '#2D6A4F', color: 'white', display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 12, fontWeight: 600 }}>JM</div>
            </div>
          </div>
        </Frame>
        <Frame dark={dark} label="Bottom tab bar · mobile" padded={false}>
          <div style={{
            background: dark ? '#0F1F18' : 'white',
            padding: '8px 12px',
            display: 'flex', justifyContent: 'space-between', alignItems: 'center',
          }}>
            {[
              ['Home', Icon.Home, true],
              ['Map', Icon.Map],
              ['Tag', Icon.Tag, false, true],
              ['Sessions', Icon.Briefcase],
              ['Alerts', Icon.Alert, false, false, 1],
            ].map(([l, Ico, active, action, badge]) => (
              <div key={l} style={{ flex: 1, display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 4, padding: '6px 0' }}>
                {action ? (
                  <div style={{ width: 38, height: 38, borderRadius: 12, background: '#2D6A4F', display: 'flex', alignItems: 'center', justifyContent: 'center', marginTop: -6, boxShadow: '0 4px 10px rgba(45,106,79,0.3)' }}>
                    <Ico size={18} stroke="white"/>
                  </div>
                ) : (
                  <div style={{ position: 'relative' }}>
                    <Ico size={20} stroke={active ? '#2D6A4F' : muted}/>
                    {badge && <div style={{ position: 'absolute', top: -2, right: -4, width: 6, height: 6, borderRadius: 3, background: '#C0392B' }}/>}
                  </div>
                )}
                <span style={{ fontSize: 10, fontWeight: 500, color: active ? '#2D6A4F' : muted }}>{l}</span>
              </div>
            ))}
          </div>
        </Frame>
      </div>
    </div>
  );
}

/* ─── MAP OVERLAYS ─── */
function CompMapOverlays({ dark }) {
  return (
    <div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 16 }}>
      {[
        { lbl: 'Zone polygon', desc: '#52B788 stroke 1.5px · 13% fill', svg: (
          <svg width="100" height="100" viewBox="0 0 100 100">
            <path d="M20,30 L60,20 L82,40 L78,72 L40,82 L18,60 Z" fill="#52B788" fillOpacity="0.15" stroke="#52B788" strokeWidth="1.5"/>
          </svg>
        )},
        { lbl: 'Exclusion zone', desc: '#C0392B stroke dashed', svg: (
          <svg width="100" height="100" viewBox="0 0 100 100">
            <path d="M20,30 L60,20 L82,40 L78,72 L40,82 L18,60 Z" fill="#C0392B" fillOpacity="0.12" stroke="#C0392B" strokeWidth="1.5" strokeDasharray="5 3"/>
          </svg>
        )},
        { lbl: 'User GPS · pulse', desc: '#52B788 dot · white border · pulsing', svg: (
          <svg width="100" height="100" viewBox="0 0 100 100">
            <circle cx="50" cy="50" r="22" fill="#52B788" fillOpacity="0.18">
              <animate attributeName="r" values="14;26;14" dur="2s" repeatCount="indefinite"/>
              <animate attributeName="fill-opacity" values="0.35;0;0.35" dur="2s" repeatCount="indefinite"/>
            </circle>
            <circle cx="50" cy="50" r="10" fill="#52B788" stroke="white" strokeWidth="2.5"/>
          </svg>
        )},
        { lbl: 'Other member', desc: '#E9C46A · initials inside', svg: (
          <svg width="100" height="100" viewBox="0 0 100 100">
            <circle cx="50" cy="50" r="14" fill="#E9C46A" stroke="white" strokeWidth="2"/>
            <text x="50" y="55" textAnchor="middle" fontSize="11" fontWeight="700" fill="#1B1B1B" fontFamily="DM Sans, sans-serif">TH</text>
          </svg>
        )},
        { lbl: 'Tag marker', desc: '#2D6A4F · white icon inside', svg: (
          <svg width="100" height="100" viewBox="0 0 100 100">
            <circle cx="50" cy="50" r="14" fill="white"/>
            <circle cx="50" cy="50" r="12" fill="#2D6A4F"/>
            <path d="M50 44 a4 4 0 1 0 0 8 a4 4 0 1 0 0 -8" fill="none" stroke="white" strokeWidth="1.5"/>
          </svg>
        )},
        { lbl: 'Tag · tapped', desc: 'White ring on tap', svg: (
          <svg width="100" height="100" viewBox="0 0 100 100">
            <circle cx="50" cy="50" r="20" fill="none" stroke="#52B788" strokeWidth="2" strokeDasharray="3 3"/>
            <circle cx="50" cy="50" r="14" fill="white"/>
            <circle cx="50" cy="50" r="12" fill="#2D6A4F"/>
            <path d="M50 44 a4 4 0 1 0 0 8 a4 4 0 1 0 0 -8" fill="none" stroke="white" strokeWidth="1.5"/>
          </svg>
        )},
        { lbl: 'Session trail', desc: '#52B788 polyline 3px round', svg: (
          <svg width="100" height="100" viewBox="0 0 100 100">
            <path d="M15,70 C30,50 50,55 60,40 S82,30 85,20" stroke="#52B788" strokeWidth="3" fill="none" strokeLinecap="round" strokeLinejoin="round"/>
            <circle cx="15" cy="70" r="4" fill="#52B788"/>
            <circle cx="85" cy="20" r="4" fill="#E9C46A"/>
          </svg>
        )},
        { lbl: 'GPS accuracy ring', desc: '13% green fill · adapts to accuracy', svg: (
          <svg width="100" height="100" viewBox="0 0 100 100">
            <circle cx="50" cy="50" r="34" fill="#52B788" fillOpacity="0.12" stroke="#52B788" strokeWidth="1"/>
            <circle cx="50" cy="50" r="8" fill="#52B788" stroke="white" strokeWidth="2"/>
          </svg>
        )},
      ].map(o => (
        <Frame key={o.lbl} dark={dark} label={o.lbl}>
          <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 12, padding: '12px 0' }}>
            <div style={{ width: 100, height: 100, background: '#1A2332', borderRadius: 8, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
              {o.svg}
            </div>
            <div style={{ fontSize: 11, color: dark ? '#8BAF96' : '#6C757D', textAlign: 'center', lineHeight: 1.4 }}>
              {o.desc}
            </div>
          </div>
        </Frame>
      ))}
    </div>
  );
}

/* ─── EMPTY STATES ─── */
function CompEmpty({ dark }) {
  const fg = dark ? '#F6F1E7' : '#1B1B1B';
  const muted = dark ? '#8BAF96' : '#6C757D';
  const items = [
    { ico: Icon.Tag, ttl: 'No tags yet', sub: 'Register your first tag from the field to start a trace.', cta: 'Register Tag', icoSize: 28 },
    { ico: Icon.Briefcase, ttl: 'No active sessions', sub: 'Start a session from the map view when you head out.', cta: 'Start Session', icoSize: 28 },
    { ico: Icon.Check, ttl: 'All clear', sub: 'No active alerts in any of your zones right now.', cta: null, icoSize: 28 },
  ];
  return (
    <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 16 }}>
      {items.map(it => (
        <Frame key={it.ttl} dark={dark} label={'Empty · ' + it.ttl.toLowerCase()}>
          <div style={{ padding: '32px 16px', textAlign: 'center' }}>
            <div style={{
              width: 56, height: 56, margin: '0 auto 16px', borderRadius: 999,
              background: dark ? 'rgba(82,183,136,0.1)' : '#F4FBF7',
              display: 'flex', alignItems: 'center', justifyContent: 'center',
              color: '#2D6A4F',
            }}>
              <it.ico size={it.icoSize} stroke="currentColor"/>
            </div>
            <div className="font-display" style={{ fontSize: 18, fontWeight: 600, color: fg, marginBottom: 6, letterSpacing: '-0.01em' }}>
              {it.ttl}
            </div>
            <div style={{ fontSize: 13, color: muted, marginBottom: 16, lineHeight: 1.5, maxWidth: 240, margin: '0 auto 16px' }}>
              {it.sub}
            </div>
            {it.cta && <button className="rh-btn rh-btn-secondary" style={{ padding: '8px 16px', fontSize: 13 }}>{it.cta}</button>}
          </div>
        </Frame>
      ))}
    </div>
  );
}

/* ─── LOADING ─── */
function CompLoading({ dark }) {
  return (
    <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr', gap: 16 }}>
      <Frame dark={dark} label="Skeleton · card">
        <Skel dark={dark} h={56} w="100%" mb={12}/>
        <Skel dark={dark} h={14} w="60%" mb={8}/>
        <Skel dark={dark} h={14} w="40%"/>
      </Frame>
      <Frame dark={dark} label="Skeleton · table rows">
        {[1, 2, 3].map(i => (
          <div key={i} style={{ display: 'flex', alignItems: 'center', gap: 12, padding: '10px 0', borderBottom: i < 3 ? '1px solid ' + (dark ? '#2A4A38' : '#EAEAEA') : 'none' }}>
            <Skel dark={dark} h={28} w={28} r={14}/>
            <div style={{ flex: 1 }}>
              <Skel dark={dark} h={12} w="50%" mb={6}/>
              <Skel dark={dark} h={10} w="30%"/>
            </div>
            <Skel dark={dark} h={20} w={70} r={10}/>
          </div>
        ))}
      </Frame>
      <Frame dark={dark} label="Map loading · full">
        <div style={{ background: '#1A2332', borderRadius: 8, padding: 32, height: 180, display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', gap: 16 }}>
          <div style={{ color: '#52B788', animation: 'rh-blink 1.4s ease-in-out infinite' }}>
            <Icon.MapPin size={32} stroke="#52B788"/>
          </div>
          <div style={{ fontFamily: 'JetBrains Mono, monospace', fontSize: 11, letterSpacing: '0.2em', color: '#8BAF96', textTransform: 'uppercase' }}>
            Loading tiles…
          </div>
          <div style={{ width: 120, height: 2, background: 'rgba(82,183,136,0.2)', borderRadius: 1, overflow: 'hidden' }}>
            <div style={{ width: '40%', height: '100%', background: '#52B788', animation: 'rh-blink 1.4s ease-in-out infinite' }}/>
          </div>
        </div>
      </Frame>
    </div>
  );
}

function Skel({ dark, h = 14, w = '100%', r = 4, mb }) {
  return (
    <div style={{
      height: h, width: w, borderRadius: r, marginBottom: mb,
      background: dark
        ? 'linear-gradient(90deg, #1A2F22 0%, #2A4A38 50%, #1A2F22 100%)'
        : 'linear-gradient(90deg, #F5F5F5 0%, #EAEAEA 50%, #F5F5F5 100%)',
      backgroundSize: '200% 100%',
      animation: 'rh-shimmer 1.8s ease-in-out infinite',
    }}/>
  );
}

/* Inject shimmer keyframes once */
if (!document.getElementById('rh-shimmer-style')) {
  const s = document.createElement('style');
  s.id = 'rh-shimmer-style';
  s.textContent = '@keyframes rh-shimmer { 0%, 100% { background-position: -100% 0; } 50% { background-position: 100% 0; } }';
  document.head.appendChild(s);
}

ReactDOM.createRoot(document.getElementById('root')).render(<ComponentsPage/>);
