// shared.jsx — Reverb shared design language: tokens, icons, brand mark,
// tab bar, mini player, cover art, common chips.

// ─────────────────────────────────────────────────────────────
// Brand mark — two nested arcs (sound echoing back)
// ─────────────────────────────────────────────────────────────
function RvMark({ size = 22, color = 'var(--accent)' }) {
  return (
    <svg width={size} height={size} viewBox="0 0 22 22" fill="none" style={{ flexShrink: 0 }}>
      <circle cx="11" cy="11" r="3.2" fill={color} />
      <path d="M11 4 a7 7 0 0 1 7 7" stroke={color} strokeWidth="1.6" strokeLinecap="round" />
      <path d="M11 1.2 a9.8 9.8 0 0 1 9.8 9.8" stroke={color} strokeOpacity="0.55" strokeWidth="1.4" strokeLinecap="round" />
    </svg>
  );
}

function RvWordmark({ size = 18, color = 'var(--text)' }) {
  return (
    <span style={{
      display: 'inline-flex', alignItems: 'center', gap: 7,
      fontFamily: 'var(--display)', fontWeight: 800,
      fontSize: size + 2, color, letterSpacing: '-0.045em',
    }}>
      <RvMark size={size + 4} />
      <span>Reverb</span>
    </span>
  );
}

// ─────────────────────────────────────────────────────────────
// Icons — minimal stroke set
// ─────────────────────────────────────────────────────────────
function Ic({ d, s = 22, w = 1.6, fill = 'none', stroke = 'currentColor', children, vb = '0 0 24 24' }) {
  return (
    <svg width={s} height={s} viewBox={vb} fill={fill} stroke={stroke} strokeWidth={w} strokeLinecap="round" strokeLinejoin="round">
      {d ? <path d={d} /> : children}
    </svg>
  );
}
const IcHome     = (p) => <Ic {...p} d="M3 11 L12 4 L21 11 V20 a1 1 0 0 1 -1 1 H4 a1 1 0 0 1 -1 -1 Z" />;
const IcLibrary  = (p) => <Ic {...p}><path d="M4 5h4v15H4z M10 5h4v15h-4z"/><path d="M16.5 6.2 L20 5.5 L20 20 L16.5 20.7 Z"/></Ic>;
const IcInterest = (p) => <Ic {...p} d="M12 3 a4.5 4.5 0 0 1 4.5 4.5 c0 2 -1.5 3.4 -3 5 c-1 1 -1.5 2 -1.5 3 c0 -1 -0.5 -2 -1.5 -3 c-1.5 -1.6 -3 -3 -3 -5 A4.5 4.5 0 0 1 12 3 Z M9 21 h6" />;
const IcUser     = (p) => <Ic {...p}><circle cx="12" cy="8.5" r="3.7"/><path d="M5 20 c1 -3.5 4 -5.5 7 -5.5 s6 2 7 5.5"/></Ic>;
const IcPlus     = (p) => <Ic {...p} d="M12 5 V19 M5 12 H19" />;
const IcPlay     = (p) => <Ic {...p} fill="currentColor" stroke="none"><path d="M7 4.5 V19.5 a0.8 0.8 0 0 0 1.2 0.7 l12 -7.5 a0.8 0.8 0 0 0 0 -1.4 l-12 -7.5 A0.8 0.8 0 0 0 7 4.5 Z" /></Ic>;
const IcPause    = (p) => <Ic {...p} fill="currentColor" stroke="none"><rect x="6" y="4.5" width="4" height="15" rx="1.2"/><rect x="14" y="4.5" width="4" height="15" rx="1.2"/></Ic>;
const IcChevR    = (p) => <Ic {...p} d="M9 5 l7 7 l-7 7" />;
const IcChevL    = (p) => <Ic {...p} d="M15 5 l-7 7 l7 7" />;
const IcChevD    = (p) => <Ic {...p} d="M5 9 l7 7 l7 -7" />;
const IcSegPrev  = (p) => <Ic {...p}><path d="M18 5 l-8 7 l8 7" /><path d="M5 5 V19" /></Ic>;
const IcSegNext  = (p) => <Ic {...p}><path d="M6 5 l8 7 l-8 7" /><path d="M19 5 V19" /></Ic>;
const IcMore     = (p) => <Ic {...p}><circle cx="5" cy="12" r="1.4" fill="currentColor" stroke="none"/><circle cx="12" cy="12" r="1.4" fill="currentColor" stroke="none"/><circle cx="19" cy="12" r="1.4" fill="currentColor" stroke="none"/></Ic>;
const IcSearch   = (p) => <Ic {...p}><circle cx="11" cy="11" r="6.5"/><path d="M16 16 l4 4"/></Ic>;
const IcUp       = (p) => <Ic {...p} d="M7 14 l5 -7 l5 7" />;
const IcDown     = (p) => <Ic {...p} d="M7 10 l5 7 l5 -7" />;
const IcThumbUp  = (p) => <Ic {...p} d="M7 11 V20 H4 V11 Z M7 11 L11 4 a2 2 0 0 1 2.5 2 L13 10 H19 a2 2 0 0 1 2 2.3 L19.5 18.7 a2 2 0 0 1 -2 1.3 H7" />;
const IcThumbDn  = (p) => <Ic {...p} d="M17 13 V4 H20 V13 Z M17 13 L13 20 a2 2 0 0 1 -2.5 -2 L11 14 H5 a2 2 0 0 1 -2 -2.3 L4.5 5.3 a2 2 0 0 1 2 -1.3 H17" />;
const IcPin      = (p) => <Ic {...p} d="M14 3 L21 10 L17 11 L18 17 L7 17 L12 12 L7 7 L14 6 Z M7 17 L3 21" />;
const IcCheck    = (p) => <Ic {...p} d="M5 12 l4 4 l10 -10" />;
const IcClose    = (p) => <Ic {...p} d="M6 6 l12 12 M18 6 l-12 12" />;
const IcLink     = (p) => <Ic {...p} d="M10 14 a4 4 0 0 1 0 -5.7 l3 -3 a4 4 0 1 1 5.7 5.7 l-1.5 1.5 M14 10 a4 4 0 0 1 0 5.7 l-3 3 a4 4 0 1 1 -5.7 -5.7 l1.5 -1.5" />;
const IcSpark    = (p) => <Ic {...p} d="M12 3 L13.6 9.4 L20 11 L13.6 12.6 L12 19 L10.4 12.6 L4 11 L10.4 9.4 Z" />;
const IcWave     = (p) => <Ic {...p}><path d="M3 12 H5 M7 8 V16 M10 5 V19 M13 9 V15 M16 6 V18 M19 10 V14 M21 12 H22"/></Ic>;
const IcFeed     = (p) => <Ic {...p}><rect x="4" y="4" width="16" height="6" rx="2"/><rect x="4" y="13" width="16" height="3" rx="1.2"/><rect x="4" y="18" width="10" height="2.4" rx="1"/></Ic>;
const IcBookmark = (p) => <Ic {...p} d="M6 4 H18 V21 L12 17 L6 21 Z"/>;
const IcShare    = (p) => <Ic {...p}><circle cx="6" cy="12" r="2.4"/><circle cx="18" cy="6" r="2.4"/><circle cx="18" cy="18" r="2.4"/><line x1="8" y1="11" x2="16" y2="7"/><line x1="8" y1="13" x2="16" y2="17"/></Ic>;
const IcSkip     = (p) => <Ic {...p} d="M5 7 l7 5 l-7 5 V7 Z M14 7 l7 5 l-7 5 V7 Z" fill="currentColor" stroke="none"/>;

// ─────────────────────────────────────────────────────────────
// Status bar (light glyphs on dark)
// ─────────────────────────────────────────────────────────────
function StatusBar({ time = '7:24', dark = true }) {
  const c = dark ? '#29211C' : '#fff';
  const stroke = dark ? 'rgba(41,33,28,0.4)' : 'rgba(255,255,255,0.4)';
  return (
    <div style={{
      position: 'absolute', top: 0, left: 0, right: 0, height: 54, zIndex: 12,
      display: 'flex', justifyContent: 'space-between', alignItems: 'center',
      padding: '18px 28px 0', pointerEvents: 'none',
    }}>
      <span style={{ fontSize: 16, fontWeight: 600, color: c, letterSpacing: '-0.01em' }}>{time}</span>
      <span style={{ display: 'inline-flex', alignItems: 'center', gap: 6 }}>
        <svg width="17" height="11" viewBox="0 0 17 11"><rect x="0" y="7" width="3" height="4" rx="0.6" fill={c}/><rect x="4.5" y="5" width="3" height="6" rx="0.6" fill={c}/><rect x="9" y="2.5" width="3" height="8.5" rx="0.6" fill={c}/><rect x="13.5" y="0" width="3" height="11" rx="0.6" fill={c}/></svg>
        <svg width="16" height="11" viewBox="0 0 17 12"><path d="M8.5 3.2C10.8 3.2 12.9 4.1 14.4 5.6L15.5 4.5C13.7 2.7 11.2 1.5 8.5 1.5C5.8 1.5 3.3 2.7 1.5 4.5L2.6 5.6C4.1 4.1 6.2 3.2 8.5 3.2Z" fill={c}/><path d="M8.5 6.8C9.9 6.8 11.1 7.3 12 8.2L13.1 7.1C11.8 5.9 10.2 5.1 8.5 5.1C6.8 5.1 5.2 5.9 3.9 7.1L5 8.2C5.9 7.3 7.1 6.8 8.5 6.8Z" fill={c}/><circle cx="8.5" cy="10.5" r="1.5" fill={c}/></svg>
        <svg width="25" height="12" viewBox="0 0 25 12"><rect x="0.5" y="0.5" width="22" height="11" rx="3.2" stroke={stroke} fill="none"/><rect x="2" y="2" width="17" height="8" rx="1.6" fill={c}/><path d="M24 4 V8 c0.8 -0.3 1.2 -1.1 1.2 -2 s-0.4 -1.7 -1.2 -2 Z" fill={c} fillOpacity="0.5"/></svg>
      </span>
    </div>
  );
}

function HomeIndicator({ light = false }) {
  return (
    <div style={{
      position: 'absolute', left: 0, right: 0, bottom: 0, height: 30,
      display: 'flex', justifyContent: 'center', alignItems: 'flex-end',
      paddingBottom: 8, zIndex: 60, pointerEvents: 'none',
    }}>
      <div style={{
        width: 134, height: 5, borderRadius: 100,
        background: light ? 'rgba(255,255,255,0.75)' : 'rgba(40,30,20,0.32)',
      }}/>
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// Cover art — flat color block + bold icon glyph + accent shape.
// FA-style flat illustration. Italic serif title preserved (editorial).
// ─────────────────────────────────────────────────────────────
function CoverArt({
  title = 'Wednesday Morning Brief',
  kicker = 'Mar 14 · Morning',
  variant = 'sky',
  size = 320,
  radius = 22,
  showTitle = true,
  style = {},
}) {
  // Each variant: flat bg + glyph icon + accent shape color
  const variants = {
    sky:      { bg: '#3D8FE0', glyph: 'mic',        fg: '#fff', accent: '#F9C557', accentPos: 'tl' },
    amber:    { bg: '#E8754A', glyph: 'headphones', fg: '#fff', accent: '#15243D', accentPos: 'br' },
    plum:     { bg: '#B91F58', glyph: 'chat',       fg: '#fff', accent: '#F9C557', accentPos: 'bl' },
    teal:     { bg: '#2E9968', glyph: 'bolt',       fg: '#fff', accent: '#F9C557', accentPos: 'tr' },
    midnight: { bg: '#15243D', glyph: 'wave',       fg: '#fff', accent: '#3D8FE0', accentPos: 'br' },
    sand:     { bg: '#F9C557', glyph: 'sparks',     fg: '#15243D', accent: '#E63B7A', accentPos: 'tl' },
    rose:     { bg: '#E63B7A', glyph: 'globe',      fg: '#fff', accent: '#15243D', accentPos: 'br' },
    magenta:  { bg: '#E63B7A', glyph: 'sparks',     fg: '#fff', accent: '#F9C557', accentPos: 'tl' },
  };
  const v = variants[variant] || variants.sky;

  // Accent shape position
  const accentPositions = {
    tl: { top: '-18%', left: '-12%' },
    tr: { top: '-18%', right: '-12%' },
    bl: { bottom: '-18%', left: '-12%' },
    br: { bottom: '-18%', right: '-12%' },
  };
  const accentSize = size * 0.55;

  return (
    <div style={{
      width: size, height: size, borderRadius: radius, overflow: 'hidden',
      position: 'relative', flexShrink: 0,
      background: v.bg,
      boxShadow: '0 1px 0 rgba(24,30,50,0.06), 0 16px 36px rgba(24,30,50,0.18)',
      ...style,
    }}>
      {/* Accent circle/disc — flat color block in corner */}
      <div style={{
        position: 'absolute',
        ...accentPositions[v.accentPos],
        width: accentSize, height: accentSize, borderRadius: '50%',
        background: v.accent,
      }}/>

      {/* Bold glyph — centered/offset */}
      <svg
        width={size * 0.5} height={size * 0.5}
        viewBox="0 0 100 100" fill="none"
        style={{
          position: 'absolute',
          top: '22%', left: '50%', transform: 'translateX(-50%)',
        }}
      >
        <BigGlyphInner kind={v.glyph} fg={v.fg} bg={v.bg}/>
      </svg>

      {showTitle && (
        <>
          {/* Kicker chip top-left */}
          <div style={{
            position: 'absolute', top: size * 0.06, left: size * 0.06,
            padding: '4px 8px', borderRadius: 6,
            background: v.fg === '#fff' ? 'rgba(0,0,0,0.20)' : 'rgba(255,255,255,0.32)',
            color: v.fg,
            fontFamily: 'var(--display)', fontWeight: 800,
            fontSize: Math.max(9, size * 0.034),
            letterSpacing: '0.10em', textTransform: 'uppercase',
            whiteSpace: 'nowrap',
          }}>{kicker}</div>

          {/* Mark top-right */}
          <div style={{ position: 'absolute', top: size * 0.06, right: size * 0.06, opacity: 0.85 }}>
            <RvMark size={Math.max(14, size * 0.075)} color={v.fg}/>
          </div>

          {/* Title — italic serif at bottom, editorial */}
          <div style={{
            position: 'absolute', left: size * 0.07, right: size * 0.07, bottom: size * 0.07,
            fontFamily: 'var(--serif)', fontStyle: 'italic',
            fontSize: Math.max(18, size * 0.115),
            lineHeight: 1.02, color: v.fg,
            letterSpacing: '-0.02em', textWrap: 'balance',
          }}>{title}</div>
        </>
      )}
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// Source chip / favicon dot
// ─────────────────────────────────────────────────────────────
const SOURCE_LIB = {
  bloomberg: { bg: '#000', fg: '#fff', label: 'B', host: 'bloomberg.com' },
  ft:        { bg: '#FFF1E5', fg: '#33302E', label: 'FT', host: 'ft.com' },
  reuters:   { bg: '#FF8000', fg: '#fff', label: 'R', host: 'reuters.com' },
  stratechery:{ bg: '#1E2A4A', fg: '#fff', label: 'S', host: 'stratechery.com' },
  nyt:       { bg: '#fff', fg: '#000', label: 'T', host: 'nytimes.com' },
  semianalysis:{ bg: '#0D1F2D', fg: '#3FA9F5', label: 'SA', host: 'semianalysis.com' },
  theverge:  { bg: '#5200FF', fg: '#fff', label: 'V', host: 'theverge.com' },
  arxiv:     { bg: '#B31B1B', fg: '#fff', label: 'aX', host: 'arxiv.org' },
  nba:       { bg: '#1D428A', fg: '#C9082A', label: 'N', host: 'nba.com' },
  espn:      { bg: '#CC0000', fg: '#fff', label: 'E', host: 'espn.com' },
  livemint:  { bg: '#F99D1C', fg: '#000', label: 'M', host: 'livemint.com' },
  economist: { bg: '#E3120B', fg: '#fff', label: 'E', host: 'economist.com' },
  axios:     { bg: '#1860EA', fg: '#fff', label: 'A', host: 'axios.com' },
  carbonb:   { bg: '#0A6E4D', fg: '#fff', label: 'C', host: 'carbonbrief.org' },
  anthropic: { bg: '#D97757', fg: '#fff', label: 'A', host: 'anthropic.com' },
  github:    { bg: '#0D1117', fg: '#fff', label: 'gh', host: 'github.com' },
  hbr:       { bg: '#A4243B', fg: '#fff', label: 'H', host: 'hbr.org' },
};
function Favicon({ src = 'bloomberg', size = 16, radius = 4 }) {
  const s = SOURCE_LIB[src] || { bg: '#666', fg: '#fff', label: '?' };
  return (
    <span className="favicon" style={{
      width: size, height: size, borderRadius: radius,
      background: s.bg, color: s.fg, fontSize: Math.max(7, size * 0.55),
      fontWeight: 700, display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
      flexShrink: 0,
    }}>{s.label}</span>
  );
}
function SourceChip({ src, label, size = 'md' }) {
  const s = SOURCE_LIB[src] || {};
  const small = size === 'sm';
  return (
    <span className="rv-chip" style={{
      padding: small ? '3px 8px 3px 4px' : '5px 10px 5px 6px',
      fontSize: small ? 11 : 12,
    }}>
      <Favicon src={src} size={small ? 13 : 16} />
      <span>{label || s.host}</span>
    </span>
  );
}
function SourceDotRow({ srcs = [], size = 14 }) {
  return (
    <span style={{ display: 'inline-flex' }}>
      {srcs.map((s, i) => (
        <span key={i} style={{ marginLeft: i ? -5 : 0, border: '1.5px solid var(--bg)', borderRadius: 4, lineHeight: 0 }}>
          <Favicon src={s} size={size} radius={3} />
        </span>
      ))}
    </span>
  );
}

// ─────────────────────────────────────────────────────────────
// Status pill
// ─────────────────────────────────────────────────────────────
function StatusPill({ kind = 'new' }) {
  const map = {
    new:      { label: 'NEW',         bg: 'var(--magenta)', fg: '#fff' },
    progress: { label: 'IN PROGRESS', bg: 'var(--yellow)', fg: 'var(--text)' },
    done:     { label: 'DONE',        bg: 'var(--bg-3)', fg: 'var(--text-3)' },
    generating: { label: 'GENERATING…', bg: 'var(--accent-tint)', fg: 'var(--accent-deep)' },
  };
  const m = map[kind] || map.new;
  return <span className="rv-pill" style={{ background: m.bg, color: m.fg }}>{m.label}</span>;
}

// ─────────────────────────────────────────────────────────────
// Tab bar
// ─────────────────────────────────────────────────────────────
function TabBar({ active = 'today', onDark = false }) {
  const tabs = [
    { id: 'today',    icon: IcHome,     label: 'Today' },
    { id: 'feed',     icon: IcFeed,     label: 'Feed' },
    { id: 'catchup',  icon: IcPlus,     label: 'Catch-up', center: true },
    { id: 'library',  icon: IcLibrary,  label: 'Library' },
    { id: 'you',      icon: IcUser,     label: 'You' },
  ];
  return (
    <div className="rv-tabbar" style={onDark ? {
      background: 'linear-gradient(180deg, rgba(21,36,61,0) 0%, rgba(21,36,61,0.88) 30%, var(--text) 80%)',
    } : undefined}>
      {tabs.map(t => {
        const Icon = t.icon;
        const isActive = active === t.id;
        if (t.center) {
          return (
            <div key={t.id} className="rv-tab" style={{ position: 'relative' }}>
              <div style={{
                width: 48, height: 48, borderRadius: 14,
                background: 'var(--accent)',
                display: 'flex', alignItems: 'center', justifyContent: 'center',
                boxShadow: '0 6px 18px rgba(61,143,224,0.40), 0 2px 0 rgba(24,30,50,0.18)',
                marginTop: -10, marginBottom: 1,
                color: '#fff',
                border: '2px solid ' + (onDark ? 'var(--text)' : 'var(--bg)'),
              }}>
                <Icon s={22} w={2.6} />
              </div>
              <span style={{ fontSize: 10, color: onDark ? 'rgba(255,255,255,0.5)' : 'var(--text-3)', fontWeight: 600 }}>Catch-up</span>
            </div>
          );
        }
        return (
          <div key={t.id} className={'rv-tab' + (isActive ? ' active' : '')} style={onDark && !isActive ? { color: 'rgba(255,255,255,0.55)' } : undefined}>
            <Icon s={22} w={1.7} stroke={isActive ? 'var(--accent)' : (onDark ? 'rgba(255,255,255,0.55)' : 'var(--text-3)')} />
            <span>{t.label}</span>
          </div>
        );
      })}
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// Mini player
// ─────────────────────────────────────────────────────────────
function MiniPlayer({
  title = 'Wednesday Morning Brief',
  variant = 'sky',
  progress = 0.32,
  playing = true,
}) {
  return (
    <div className="rv-mini">
      <CoverArt size={42} radius={10} variant={variant} showTitle={false}/>
      <div style={{ flex: 1, minWidth: 0 }}>
        <div style={{ fontSize: 13, fontWeight: 600, color: 'var(--text)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{title}</div>
        <div style={{ marginTop: 5, height: 2, background: 'rgba(60,40,20,0.12)', borderRadius: 2, overflow: 'hidden' }}>
          <div style={{ width: `${progress*100}%`, height: '100%', background: 'var(--accent)' }}/>
        </div>
      </div>
      <button style={{
        width: 32, height: 32, borderRadius: 999, border: 0,
        background: 'rgba(60,40,20,0.07)', color: 'var(--text)',
        display: 'flex', alignItems: 'center', justifyContent: 'center',
        flexShrink: 0,
      }}>
        {playing ? <IcPause s={15}/> : <IcPlay s={15}/>}
      </button>
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// Waveform (static art) — used in player scrubber & mini
// ─────────────────────────────────────────────────────────────
function Waveform({ bars = 64, height = 36, progress = 0.32, active = true }) {
  // pseudo-random but deterministic
  const seed = (i) => {
    const x = Math.sin(i * 12.9898) * 43758.5453;
    return Math.abs(x - Math.floor(x));
  };
  return (
    <div style={{ display: 'flex', alignItems: 'center', gap: 2, height, width: '100%' }}>
      {Array.from({ length: bars }).map((_, i) => {
        const v = 0.18 + seed(i+1) * 0.82;
        const h = Math.round(v * height);
        const past = i / bars < progress;
        return (
          <div key={i} style={{
            flex: 1, height: h, borderRadius: 1.5,
            background: past ? 'var(--accent)' : 'rgba(60,40,20,0.14)',
            transformOrigin: 'center',
            animation: active && Math.abs(i/bars - progress) < 0.03
              ? 'rv-breathe 1.1s ease-in-out infinite' : 'none',
          }}/>
        );
      })}
    </div>
  );
}

Object.assign(window, {
  RvMark, RvWordmark,
  Ic, IcHome, IcLibrary, IcInterest, IcUser, IcPlus, IcPlay, IcPause,
  IcChevR, IcChevL, IcChevD, IcSegPrev, IcSegNext, IcMore, IcSearch,
  IcUp, IcDown, IcThumbUp, IcThumbDn, IcPin, IcCheck, IcClose, IcLink,
  IcSpark, IcWave, IcFeed, IcBookmark, IcShare, IcSkip,
  StatusBar, HomeIndicator,
  CoverArt, Favicon, SourceChip, SourceDotRow, StatusPill,
  TabBar, MiniPlayer, Waveform,
  SOURCE_LIB,
});
