// ─────────────────────────────────────────────────────────────
// Shared visual primitives — used across every section.
// Things that aren't quite icons (FLIcons) and aren't quite data:
//   • ForestGlyph     — concentric-rings mark beside every forest
//   • KindChip        — public / invite / private label
//   • JoinChip        — open / moderated / referral mode label
//   • SignalDot       — small left-side pulse for "rising/quiet"
//   • Avatar          — first-letter avatar for handles
//   • Btn             — calm primary / secondary button
// ─────────────────────────────────────────────────────────────


function ForestGlyph({ size = 30, hot = false, color = '#4F8E51', alive = true, intensity = 'quiet' }) {
  // When `alive` is set, the rings counter-rotate at a slow, calm pace and a
  // tracer dot orbits the outer ring. Hot forests get a faster orbit + a sun
  // center; quiet forests still rotate but glacially, so the row never reads
  // as static. Falls back to the static glyph when alive=false (used for the
  // brainstorm's premise screen to mimic the v1 look).
  const outerDur  = intensity === 'hot' ? '38s' : intensity === 'warm' ? '60s' : '90s';
  const middleDur = intensity === 'hot' ? '52s' : intensity === 'warm' ? '78s' : '110s';
  const innerDur  = intensity === 'hot' ? '24s' : intensity === 'warm' ? '40s' : '70s';
  const orbitDur  = intensity === 'hot' ? '6s'  : intensity === 'warm' ? '12s' : '22s';
  return (
    <svg width={size} height={size} viewBox="0 0 52 52" fill="none"
         style={{ flexShrink: 0, overflow: 'visible' }}>
      {/* Outer ring */}
      <g data-fl-anim={alive ? '' : undefined}
         style={alive ? { transformBox: 'view-box', transformOrigin: '50% 50%',
                          animation: `flRingSpin ${outerDur} linear infinite` } : undefined}>
        <circle cx="26" cy="26" r="23" stroke={color}
                strokeOpacity={hot ? 0.55 : 0.32} strokeWidth="1.2"/>
        {alive && (
          // Tracer dot — a small sun bead riding the outer ring.
          <circle cx="49" cy="26" r={hot ? 1.7 : 1.2}
                  fill={hot ? '#D4960C' : '#76AB78'}
                  opacity={hot ? 1 : 0.7}/>
        )}
      </g>
      {/* Middle ring — counter-rotates */}
      <g data-fl-anim={alive ? '' : undefined}
         style={alive ? { transformBox: 'view-box', transformOrigin: '50% 50%',
                          animation: `flRingSpinReverse ${middleDur} linear infinite` } : undefined}>
        <circle cx="26" cy="26" r="16" stroke={color}
                strokeOpacity={hot ? 0.75 : 0.5} strokeWidth="1.3"/>
        {alive && hot && (
          <circle cx="42" cy="26" r="1" fill="#A8C5A0" opacity="0.85"/>
        )}
      </g>
      {/* Inner ring */}
      <g data-fl-anim={alive ? '' : undefined}
         style={alive ? { transformBox: 'view-box', transformOrigin: '50% 50%',
                          animation: `flRingSpin ${innerDur} linear infinite` } : undefined}>
        <circle cx="26" cy="26" r="9" stroke={color}
                strokeOpacity={hot ? 1 : 0.75} strokeWidth="1.5"/>
      </g>
      {/* Center — pulses gently */}
      <circle cx="26" cy="26" r="3.2"
              fill={hot ? '#D4960C' : color}
              data-fl-anim={alive ? '' : undefined}
              style={alive && hot ? {
                transformBox: 'view-box', transformOrigin: '50% 50%',
                animation: `flGlyphBreathe ${orbitDur} var(--ease-organic) infinite`,
              } : undefined}/>
    </svg>
  );
}


function KindChip({ kind }) {
  const cfg = {
    public:  { fg: '#A8C5A0', bg: 'rgba(168,197,160,0.06)', bd: 'rgba(168,197,160,0.16)', label: 'public' },
    invite:  { fg: '#F4DCA0', bg: 'rgba(212,150,12,0.08)',  bd: 'rgba(212,150,12,0.32)',  label: 'invite' },
    private: { fg: '#D6BFA8', bg: '#2A1F12',                bd: '#5F3D22',                label: 'private' },
  }[kind];
  return (
    <span style={{
      font: '500 10px var(--font-sans)', color: cfg.fg,
      padding: '1px 7px', background: cfg.bg,
      border: `0.5px solid ${cfg.bd}`, borderRadius: 999,
      letterSpacing: '0.02em',
    }}>{cfg.label}</span>
  );
}


function JoinChip({ mode }) {
  const cfg = {
    open:      { label: 'open',       fg: '#A8C5A0', bd: 'rgba(168,197,160,0.30)' },
    moderated: { label: 'moderated',  fg: '#F4DCA0', bd: 'rgba(212,150,12,0.36)' },
    referral:  { label: 'referral',   fg: '#D6BFA8', bd: '#5F3D22' },
  }[mode];
  return (
    <span style={{
      font: '500 10px var(--font-sans)', color: cfg.fg,
      padding: '1px 7px', background: 'transparent',
      border: `0.5px solid ${cfg.bd}`, borderRadius: 999,
      letterSpacing: '0.02em',
    }}>{cfg.label}</span>
  );
}


function SignalDot({ signal = 'steady', size = 6 }) {
  // rising = sunlight, steady = canopy, quiet = muted
  const c = signal === 'rising' ? '#D4960C' :
            signal === 'quiet'  ? '#445239' : '#5E8048';
  return (
    <span style={{
      width: size, height: size, borderRadius: '50%', background: c,
      display: 'inline-block', flexShrink: 0,
      boxShadow: signal === 'rising' ? '0 0 0 3px rgba(212,150,12,0.18)' : 'none',
    }}/>
  );
}


function Avatar({ handle = 'x', size = 32, online = false, accent = '#5E8048' }) {
  const letter = (handle || '?').slice(0, 1).toUpperCase();
  return (
    <span style={{
      width: size, height: size, borderRadius: '50%',
      background: 'linear-gradient(135deg, #1B3A1D 0%, #111D0A 100%)',
      border: `0.5px solid ${accent}`,
      display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
      font: `500 ${Math.round(size * 0.42)}px var(--font-mono)`,
      color: accent, position: 'relative', flexShrink: 0,
    }}>
      {letter}
      {online && (
        <span style={{
          position: 'absolute', right: -1, bottom: -1,
          width: 9, height: 9, borderRadius: '50%',
          background: '#4F8E51', border: '1.5px solid #0B1306',
        }}/>
      )}
    </span>
  );
}


function Btn({ kind = 'primary', children, onClick, full = false, size = 'md', style = {} }) {
  const base = {
    border: 'none', cursor: 'pointer',
    font: '500 13px var(--font-sans)',
    borderRadius: 10,
    padding: size === 'sm' ? '6px 12px' : '10px 16px',
    transition: 'background 140ms var(--ease-organic), transform 140ms var(--ease-organic)',
    width: full ? '100%' : 'auto',
    display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: 6,
    ...style,
  };
  const skins = {
    primary:   { background: '#2C5F2E', color: '#F2EDE4' },
    secondary: { background: 'transparent', color: '#C9D2BB', border: '0.5px solid #2D3A22' },
    ghost:     { background: 'transparent', color: '#8A9678' },
    danger:    { background: '#3A1F18', color: '#E0A39A', border: '0.5px solid #5F2D24' },
    sun:       { background: 'rgba(212,150,12,0.10)', color: '#F4DCA0',
                 border: '0.5px solid rgba(212,150,12,0.40)' },
  };
  return (
    <button onClick={onClick} style={{ ...base, ...skins[kind] }}
      onMouseDown={e => e.currentTarget.style.transform = 'scale(0.97)'}
      onMouseUp={e => e.currentTarget.style.transform = 'scale(1)'}
      onMouseLeave={e => e.currentTarget.style.transform = 'scale(1)'}>
      {children}
    </button>
  );
}


// Phone scroll helper — used inside every phone screen so the bottom nav
// has consistent height and the body scrolls under it without bleeding.
function PhoneBody({ children, style = {} }) {
  return (
    <div className="phone-scroll" style={{
      flex: 1, overflowY: 'auto', overflowX: 'hidden', minHeight: 0,
      ...style,
    }}>{children}</div>
  );
}


Object.assign(window, {
  ForestGlyph, KindChip, JoinChip, SignalDot, Avatar, Btn, PhoneBody,
});
