// Pote — core visual atoms: PoteOrb, Poti, Wordmark, buttons, chips, etc.
// All globals registered on window at the bottom so other JSX files can use them.

const POTE_COLORS = {
  lime: '#DFFF00',
  limeDark: '#CBE800',
  limeSoft: '#F3FFC1',
  black: '#050505',
  white: '#FAFAF5',
  paper: '#F6F6F1',
  textMuted: '#6F6F69',
  lavender: '#CDB4FF',
  lavenderSoft: '#EFE7FF',
  cyan: '#BEEFF0',
  cyanSoft: '#E8FAFA',
  pink: '#FFB7D6',
  pinkSoft: '#FFE5EF',
  orange: '#FF9B21',
  orangeSoft: '#FFE7C7',
  mint: '#7DE0C0',
  mintSoft: '#DCF7EE',
};

// Per-color palette for the orb: [topAir, midLiquid, deepLiquid, stroke]
const ORB_PALETTES = {
  lime:     { air: '#F3FFC1', mid: '#DFFF00', deep: '#B6D300', stroke: '#7C9300' },
  lavender: { air: '#EFE7FF', mid: '#CDB4FF', deep: '#9C7CE2', stroke: '#5A3FA0' },
  cyan:     { air: '#E8FAFA', mid: '#BEEFF0', deep: '#7FBDBE', stroke: '#3C7F80' },
  pink:     { air: '#FFE5EF', mid: '#FFB7D6', deep: '#C98FAE', stroke: '#7A3F60' },
  orange:   { air: '#FFE7C7', mid: '#FF9B21', deep: '#C97A19', stroke: '#7A3F00' },
};

// ─────────────────────────────────────────────────────────────────────────
// PoteOrb — circle + opaque liquid + simple wave + optional idle slosh.
// Strictly 2D, no glass/reflections. Renders as inline SVG so it scales.
// ─────────────────────────────────────────────────────────────────────────
function PoteOrb({
  color = 'lime',
  progress = 0.5,        // 0..1
  size = 120,
  showPercent = true,
  withFace = false,      // turns the orb into Poti
  animate = true,        // idle slosh
  seed = 0,              // de-sync timing per orb
  shadow = true,
}) {
  const pal = ORB_PALETTES[color] || ORB_PALETTES.lime;
  const cx = 100, cy = 100, r = 96;
  // map progress to wave baseline y (in 200x200 viewBox)
  // progress=0 -> wave near bottom (y~196), progress=1 -> wave near top (y~6)
  const baselineY = 196 - (190 * Math.max(0.04, Math.min(0.96, progress)));
  const pct = Math.round(progress * 100);
  const id = React.useId();
  const clipId = `clip-${id}`;
  const animId = `anim-${id}`;
  const animDelay = (seed * 0.37) % 6;

  // Two wave paths for slight parallax between mid & top layer
  const wavePathA = (y, amp = 8) =>
    `M -10 ${y} C 40 ${y - amp}, 80 ${y + amp}, 120 ${y - amp * 0.6} S 220 ${y + amp}, 240 ${y - amp * 0.4} L 240 220 L -10 220 Z`;
  const wavePathB = (y, amp = 6) =>
    `M -10 ${y + 4} C 50 ${y - amp + 4}, 90 ${y + amp + 4}, 140 ${y - amp * 0.5 + 4} S 230 ${y + amp + 4}, 240 ${y - amp * 0.3 + 4} L 240 220 L -10 220 Z`;

  return (
    <div style={{
      position: 'relative',
      width: size,
      height: size + (shadow ? 8 : 0),
      display: 'inline-block',
      lineHeight: 0,
    }}>
      {shadow && (
        <div style={{
          position: 'absolute',
          left: '8%', right: '8%', bottom: 0,
          height: size * 0.06,
          borderRadius: '50%',
          background: 'rgba(5,5,5,0.18)',
          filter: 'blur(6px)',
          zIndex: 0,
        }} />
      )}
      <svg
        viewBox="0 0 200 200"
        width={size}
        height={size}
        style={{ position: 'relative', display: 'block', overflow: 'visible' }}
      >
        <defs>
          <clipPath id={clipId}>
            <circle cx={cx} cy={cy} r={r} />
          </clipPath>
          {animate && (
            <style>{`
              @keyframes ${animId}-a {
                0%, 100% { transform: translate(-12px, 0) }
                50%      { transform: translate(0px, -2px) }
              }
              @keyframes ${animId}-b {
                0%, 100% { transform: translate(0px, 0px) }
                50%      { transform: translate(-14px, 1.5px) }
              }
              .${animId}-a { animation: ${animId}-a 7.5s ease-in-out ${animDelay}s infinite; transform-origin: 50% 50%; }
              .${animId}-b { animation: ${animId}-b 9.5s ease-in-out ${animDelay + 0.6}s infinite; transform-origin: 50% 50%; }
            `}</style>
          )}
        </defs>
        {/* base air (top color) */}
        <circle cx={cx} cy={cy} r={r} fill={pal.air} />
        {/* liquid clipped to orb */}
        <g clipPath={`url(#${clipId})`}>
          {/* mid liquid wave */}
          <g className={animate ? `${animId}-a` : ''}>
            <path d={wavePathA(baselineY, 10)} fill={pal.mid} />
          </g>
          {/* deep liquid wave (lower / darker) */}
          <g className={animate ? `${animId}-b` : ''}>
            <path d={wavePathB(baselineY + 18, 7)} fill={pal.deep} />
          </g>
        </g>
        {/* hairline border */}
        <circle cx={cx} cy={cy} r={r} fill="none" stroke={POTE_COLORS.black} strokeOpacity="0.55" strokeWidth="1.2" />

        {withFace && (
          <g>
            {/* eyes */}
            <ellipse cx={cx - 22} cy={cy - 8} rx="6" ry="9" fill={POTE_COLORS.black} />
            <ellipse cx={cx + 22} cy={cy - 8} rx="6" ry="9" fill={POTE_COLORS.black} />
            {/* mouth */}
            <path d={`M ${cx - 8} ${cy + 12} Q ${cx} ${cy + 22} ${cx + 8} ${cy + 12}`}
              fill="none" stroke={POTE_COLORS.black} strokeWidth="3" strokeLinecap="round" />
          </g>
        )}

        {showPercent && !withFace && size >= 64 && (
          <text
            x={cx}
            y={cy + (size > 96 ? 9 : 7)}
            textAnchor="middle"
            fontFamily='"Inter", "SF Pro", system-ui, sans-serif'
            fontSize={size > 130 ? 36 : size > 96 ? 30 : 24}
            fontWeight="800"
            letterSpacing="-1"
            fill={POTE_COLORS.black}
          >
            {pct}%
          </text>
        )}
      </svg>
    </div>
  );
}

// ─────────────────────────────────────────────────────────────────────────
// Wordmark — custom SVG paths for "pote" (lowercase, thick, rounded)
// Hand-built; no font dependency.
// ─────────────────────────────────────────────────────────────────────────
function PoteWordmark({ height = 64, color = '#050505', font = 'svg' }) {
  // Three render modes:
  //   font='svg'       — user-supplied vectorized wordmark (default, brand-accurate)
  //   font='geo'       — geometric hand-tuned fallback (no external dependency)
  //   font='bricolage' — Bricolage Grotesque 900 (requires the GF import)
  if (font === 'bricolage') {
    return (
      <div style={{
        fontFamily: '"Bricolage Grotesque", system-ui, sans-serif',
        fontWeight: 900,
        fontSize: height * 1.45,
        lineHeight: 1,
        letterSpacing: '-0.07em',
        color,
        fontVariationSettings: '"wdth" 70, "opsz" 96',
        textRendering: 'geometricPrecision',
      }}>pote</div>
    );
  }
  if (font === 'svg') {
    // User-vectorized "pote" wordmark — viewBox 150 × 69.4
    return (
      <svg viewBox="0 0 150 69.4" height={height} style={{ display: 'block', color }}>
        <g fill="currentColor">
          <path d="m22.8 13.6c-9.7 0-18.6 7.4-18.7 18.5v32.4h9.6v-16.4c2.3 1.5 5.2 2.9 9.6 2.9 10.3 0 18.7-7.1 18.7-17.8 0-10.5-8.1-19.6-19.2-19.6zm-0.3 28c-4.6 0-8.7-3.4-8.7-8.9 0-4.3 3.2-9 8.7-9 4.8 0 9 3.5 9 9 0 4.7-3.7 8.9-9 8.9z" />
          <path d="m63.6 13.6c-9.7 0-19.5 6.9-19.5 19.1 0 10.1 7.2 18.3 19.4 18.3 10.2 0 18.7-7.1 18.7-18.1 0.1-11.3-8.8-19.3-18.6-19.3zm-0.1 28c-4.6 0-8.9-3-8.9-9 0-4.3 3.3-8.9 8.9-8.9 4.5 0 8.5 3.4 8.5 8.9 0.1 5.4-4.1 9-8.5 9z" />
          <path d="m98.1 3.8-10.3 0.4v10.1h-5.2v9.7h5.2v13.4c0 9.2 5.5 13.3 13.6 13.3 1.9 0 4.5-0.1 6.6-0.4v-9.1h-5.2c-2.9 0-4.6-1.7-4.6-5v-12.2h9.8v-9.7h-9.9v-10.5z" />
          <path d="m128.1 13.6c-10.2-0.3-18.9 7.7-18.9 18.7 0 11.1 7.8 18.7 19 18.7 6.9 0 13-3.2 16.3-9.8l-8.6-2.7c-1.1 1.7-3.6 3.8-7.4 3.8-4.1 0.1-8.1-2.2-8.8-6.4h25.9c0-1 0.1-1.7 0.1-3.6 0.1-10-7.2-18.4-17.6-18.7zm-8.3 15.2c1.2-3.9 4.5-5.9 8.1-5.9 4.6 0 7.5 2.7 8.2 5.9h-16.3z" />
        </g>
      </svg>
    );
  }
  // 'geo' — geometric hand-tuned fallback (the prior SVG)
  // Each glyph drawn at its own (0,0) and placed with a known translate.
  //   p (w 110) at  x=0    → 0..110
  //   o (w  96) at  x=114  → 114..210
  //   t (w  60) at  x=216  → 216..276
  //   e (w 104) at  x=270  → 270..374   (slight optical kerning into t)
  // viewBox 380 × 150. Counters via evenodd subpaths so it works on any bg.
  return (
    <svg viewBox="0 0 380 150" height={height} style={{ display: 'block' }}>
      <g fill={color} fillRule="evenodd">
        {/* p */}
        <g transform="translate(0,0)">
          <path d="
            M 0 32 h 28 v 6
            c 9 -10 21 -16 34 -16
            c 27 0 48 23 48 52
            c 0 29 -21 52 -48 52
            c -13 0 -25 -5 -34 -14
            v 30 h -28 z
            M 28 74
            c 0 16 12 28 26 28
            c 16 0 28 -12 28 -28
            c 0 -16 -12 -28 -28 -28
            c -14 0 -26 12 -26 28 z
          " />
        </g>
        {/* o */}
        <g transform="translate(114,0)">
          <path d="
            M 48 22
            c 27 0 48 24 48 52
            c 0 28 -21 52 -48 52
            c -27 0 -48 -24 -48 -52
            c 0 -28 21 -52 48 -52 z
            M 48 48
            c -14 0 -23 11 -23 24
            c 0 13 9 24 23 24
            c 14 0 23 -11 23 -24
            c 0 -13 -9 -24 -23 -24 z
          " />
        </g>
        {/* t */}
        <g transform="translate(216,0)">
          <path d="
            M 16 0 h 28 v 28 h 16 v 22 h -16 v 36
            c 0 9 3 14 12 14 h 4 v 24
            h -14 c -24 0 -30 -12 -30 -36
            v -38 h -16 v -22 h 16 z
          " />
        </g>
        {/* e */}
        <g transform="translate(270,0)">
          <path d="
            M 104 78
            h -76
            c 2 14 14 22 26 22
            c 8 0 16 -2 22 -8
            l 22 14
            c -10 14 -26 22 -44 22
            c -30 0 -54 -22 -54 -52
            c 0 -30 24 -52 52 -52
            c 32 0 52 22 52 50 z
            M 76 60
            c -2 -10 -12 -16 -22 -16
            c -14 0 -22 6 -24 16 z
          " />
        </g>
      </g>
    </svg>
  );
}

// ─────────────────────────────────────────────────────────────────────────
// Buttons, chips, pills, highlight, bottom nav
// ─────────────────────────────────────────────────────────────────────────
function PrimaryButton({ children, full = true, onClick, style = {} }) {
  return (
    <button
      onClick={onClick}
      style={{
        height: 56,
        borderRadius: 28,
        background: POTE_COLORS.black,
        color: POTE_COLORS.white,
        border: 'none',
        fontSize: 17,
        fontWeight: 600,
        letterSpacing: '-0.2px',
        padding: '0 28px',
        cursor: 'pointer',
        width: full ? '100%' : 'auto',
        fontFamily: 'inherit',
        ...style,
      }}>
      {children}
    </button>
  );
}

function SecondaryButton({ children, full = true, onClick, style = {} }) {
  return (
    <button
      onClick={onClick}
      style={{
        height: 56,
        borderRadius: 28,
        background: POTE_COLORS.white,
        color: POTE_COLORS.black,
        border: `1.5px solid rgba(5,5,5,0.12)`,
        fontSize: 17,
        fontWeight: 600,
        letterSpacing: '-0.2px',
        padding: '0 28px',
        cursor: 'pointer',
        width: full ? '100%' : 'auto',
        fontFamily: 'inherit',
        ...style,
      }}>
      {children}
    </button>
  );
}

function StepPill({ step = 1, total = 3, lang = 'es' }) {
  const sep = lang === 'es' ? 'de' : 'of';
  return (
    <div style={{
      display: 'inline-flex',
      alignItems: 'center',
      height: 30,
      padding: '0 14px',
      borderRadius: 15,
      background: POTE_COLORS.black,
      color: POTE_COLORS.white,
      fontSize: 13,
      fontWeight: 600,
      letterSpacing: '0.2px',
    }}>{step} {sep} {total}</div>
  );
}

// Highlight a word with lime block behind it (inline). Forces black text
// so it stays readable when the surrounding text color is white/light.
function Hl({ children }) {
  return (
    <span style={{
      background: POTE_COLORS.lime,
      color: POTE_COLORS.black,
      padding: '0 6px',
      borderRadius: 6,
      boxDecorationBreak: 'clone',
      WebkitBoxDecorationBreak: 'clone',
    }}>{children}</span>
  );
}

// Chip — small black pill with white text, used for pote labels
function NameChip({ children, dark = true, style = {} }) {
  return (
    <span style={{
      display: 'inline-block',
      padding: '6px 12px',
      borderRadius: 999,
      background: dark ? POTE_COLORS.black : POTE_COLORS.white,
      color: dark ? POTE_COLORS.white : POTE_COLORS.black,
      fontSize: 13,
      fontWeight: 700,
      letterSpacing: '-0.1px',
      boxShadow: dark ? 'none' : '0 1px 0 rgba(5,5,5,0.06), 0 0 0 1px rgba(5,5,5,0.06)',
      ...style,
    }}>{children}</span>
  );
}

// Outside label "Cena · 85%" for small potes — paper card
function ExternalLabel({ name, pct, style = {} }) {
  return (
    <span style={{
      display: 'inline-flex',
      alignItems: 'baseline',
      gap: 6,
      padding: '6px 11px',
      borderRadius: 999,
      background: POTE_COLORS.white,
      boxShadow: '0 1px 0 rgba(5,5,5,0.04), 0 0 0 1px rgba(5,5,5,0.06)',
      fontSize: 12,
      fontWeight: 600,
      color: POTE_COLORS.black,
      letterSpacing: '-0.1px',
      ...style,
    }}>
      <span>{name}</span>
      <span style={{ color: POTE_COLORS.textMuted, fontWeight: 600 }}>·</span>
      <span style={{ fontVariantNumeric: 'tabular-nums' }}>{pct}%</span>
    </span>
  );
}

// Bottom nav — 4 icons, active gets lime circle
function BottomNav({ active = 'home', lang = 'es' }) {
  const labels = lang === 'es'
    ? { home: 'Inicio', potes: 'Potes', moves: 'Movs', me: 'Perfil' }
    : { home: 'Home', potes: 'Potes', moves: 'Activity', me: 'Me' };
  const items = [
    { id: 'home',  label: labels.home,  icon: <NavIcon name="home" /> },
    { id: 'potes', label: labels.potes, icon: <NavIcon name="potes" /> },
    { id: 'moves', label: labels.moves, icon: <NavIcon name="moves" /> },
    { id: 'me',    label: labels.me,    icon: <NavIcon name="me" /> },
  ];
  return (
    <div style={{
      position: 'absolute',
      bottom: 34, left: 16, right: 16,
      height: 64,
      borderRadius: 32,
      background: POTE_COLORS.black,
      color: POTE_COLORS.white,
      display: 'flex',
      alignItems: 'center',
      justifyContent: 'space-around',
      padding: '0 14px',
      boxShadow: '0 10px 30px rgba(5,5,5,0.18)',
      zIndex: 5,
    }}>
      {items.map(it => {
        const isActive = active === it.id;
        return (
          <div key={it.id} style={{
            display: 'flex',
            flexDirection: 'column',
            alignItems: 'center',
            gap: 2,
            minWidth: 56,
          }}>
            <div style={{
              width: 40, height: 40,
              borderRadius: 20,
              background: isActive ? POTE_COLORS.lime : 'transparent',
              display: 'flex', alignItems: 'center', justifyContent: 'center',
              color: isActive ? POTE_COLORS.black : POTE_COLORS.white,
            }}>
              {it.icon}
            </div>
            <div style={{
              fontSize: 10,
              fontWeight: 600,
              opacity: isActive ? 1 : 0.7,
              letterSpacing: '0.1px',
            }}>{it.label}</div>
          </div>
        );
      })}
    </div>
  );
}

function NavIcon({ name }) {
  const s = { width: 22, height: 22, fill: 'none', stroke: 'currentColor', strokeWidth: 2, strokeLinecap: 'round', strokeLinejoin: 'round' };
  if (name === 'home')
    return <svg viewBox="0 0 24 24" {...s}><path d="M3 11l9-7 9 7v9a2 2 0 0 1-2 2h-4v-7h-6v7H5a2 2 0 0 1-2-2z"/></svg>;
  if (name === 'potes')
    return <svg viewBox="0 0 24 24" {...s}>
      <circle cx="8" cy="8" r="4"/><circle cx="17" cy="14" r="5"/><circle cx="7" cy="17" r="3"/>
    </svg>;
  if (name === 'moves')
    return <svg viewBox="0 0 24 24" {...s}><path d="M4 12h12M12 6l6 6-6 6"/><path d="M20 6v12" /></svg>;
  if (name === 'me')
    return <svg viewBox="0 0 24 24" {...s}><circle cx="12" cy="8" r="4"/><path d="M4 21c1.5-4 5-6 8-6s6.5 2 8 6"/></svg>;
  return null;
}

// Top-right bell + avatar cluster (home) with optional Live Activity pill
function HomeTopBar({ name = 'Samu', lang = 'es', achievement = null }) {
  const isES = lang === 'es';
  return (
    <div style={{
      position: 'absolute',
      top: 56, left: 16, right: 16,
      display: 'flex',
      alignItems: 'center',
      gap: 10,
      zIndex: 4,
    }}>
      {/* Profile with greeting (matches codebase ChromeHomeGreetingButton) */}
      <div style={{
        display: 'flex', alignItems: 'center', gap: 8,
        height: 42, padding: '0 12px 0 6px',
        borderRadius: 21,
        background: POTE_COLORS.white,
        boxShadow: '0 1px 0 rgba(5,5,5,0.05), 0 0 0 1.5px rgba(5,5,5,0.06)',
        flexShrink: 0,
      }}>
        <div style={{
          width: 30, height: 30, borderRadius: 15,
          background: POTE_COLORS.lime,
          display: 'flex', alignItems: 'center', justifyContent: 'center',
          fontWeight: 800, color: POTE_COLORS.black, fontSize: 13,
        }}>S</div>
        <div style={{
          fontSize: 13, fontWeight: 700, color: POTE_COLORS.black, letterSpacing: '-0.1px',
        }}>Hola, {name} 👋</div>
      </div>

      {/* Live Activity pill — "Poti cuida X primero" */}
      {achievement ? (
        <div style={{
          flex: 1, minWidth: 0,
          height: 42, borderRadius: 21,
          background: POTE_COLORS.black,
          color: POTE_COLORS.white,
          display: 'flex', alignItems: 'center', gap: 8,
          padding: '0 14px 0 6px',
          boxShadow: '0 8px 20px rgba(5,5,5,0.25), 0 0 0 2.5px ' + POTE_COLORS.paper,
          cursor: 'pointer',
        }}>
          <span style={{
            width: 30, height: 30, borderRadius: 15,
            background: POTE_COLORS.lime,
            display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
            flexShrink: 0,
          }}>
            <svg viewBox="0 0 100 100" width="20" height="20">
              <ellipse cx="38" cy="44" rx="4.5" ry="7" fill="#050505" />
              <ellipse cx="62" cy="44" rx="4.5" ry="7" fill="#050505" />
              <path d="M 42 58 Q 50 66 58 58" fill="none" stroke="#050505" strokeWidth="2.6" strokeLinecap="round" />
            </svg>
          </span>
          <div style={{ flex: 1, minWidth: 0, lineHeight: '14px' }}>
            <div style={{ fontSize: 10, fontWeight: 700, opacity: 0.55, letterSpacing: '0.3px', textTransform: 'uppercase' }}>
              {isES ? 'Estado de Poti' : 'Poti status'}
            </div>
            <div style={{
              fontSize: 12, fontWeight: 800, letterSpacing: '-0.1px',
              overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap',
            }}>{isES ? 'Poti cuida Japón primero' : 'Poti tends Japón first'}</div>
          </div>
          <svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round" style={{ opacity: 0.6, flexShrink: 0 }}>
            <path d="M9 6l6 6-6 6"/>
          </svg>
        </div>
      ) : (
        <div style={{ flex: 1 }} />
      )}

      {/* Bell */}
      <button style={{
        width: 42, height: 42, borderRadius: 21,
        background: POTE_COLORS.white,
        border: '1.5px solid rgba(5,5,5,0.08)',
        display: 'flex', alignItems: 'center', justifyContent: 'center',
        cursor: 'pointer', position: 'relative', flexShrink: 0,
      }}>
        <svg width="18" height="18" viewBox="0 0 24 24" fill="none"
          stroke={POTE_COLORS.black} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
          <path d="M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9"/>
          <path d="M10 21a2 2 0 0 0 4 0"/>
        </svg>
        <span style={{
          position: 'absolute', top: 8, right: 9,
          width: 8, height: 8, borderRadius: 4,
          background: POTE_COLORS.orange,
          border: `1.5px solid ${POTE_COLORS.white}`,
        }} />
      </button>
    </div>
  );
}

// Floating + FAB
function FAB() {
  return (
    <button style={{
      position: 'absolute',
      right: 24, bottom: 116,
      width: 60, height: 60,
      borderRadius: 30,
      background: POTE_COLORS.lime,
      border: 'none',
      boxShadow: '0 10px 24px rgba(203,232,0,0.45), 0 0 0 1.5px rgba(5,5,5,0.06)',
      cursor: 'pointer',
      zIndex: 6,
      display: 'flex', alignItems: 'center', justifyContent: 'center',
    }}>
      <svg width="22" height="22" viewBox="0 0 24 24" fill="none"
        stroke={POTE_COLORS.black} strokeWidth="3" strokeLinecap="round">
        <path d="M12 5v14M5 12h14"/>
      </svg>
    </button>
  );
}

// Soft section card (white-ish rounded card)
function Card({ children, style = {} }) {
  return (
    <div style={{
      background: POTE_COLORS.white,
      borderRadius: 24,
      padding: 18,
      boxShadow: '0 1px 0 rgba(5,5,5,0.03), 0 0 0 1px rgba(5,5,5,0.06)',
      ...style,
    }}>{children}</div>
  );
}

// ─────────────────────────────────────────────────────────────────────────
// Screen frame — wrapper that draws an iPhone-style bezel without iOS chrome.
// Pote owns its own look; we just provide rounded screen + status bar time +
// home indicator, so it reads as a real phone.
// ─────────────────────────────────────────────────────────────────────────
function PhoneFrame({ children, bg = POTE_COLORS.paper, width = 402, height = 874, label }) {
  return (
    <div style={{
      width, height,
      borderRadius: 56,
      background: '#1a1916',
      padding: 10,
      position: 'relative',
      boxShadow: '0 30px 70px rgba(5,5,5,0.18), 0 0 0 1px rgba(5,5,5,0.18)',
      fontFamily: '"Inter", "SF Pro Display", "SF Pro", system-ui, sans-serif',
    }}
    data-screen-label={label}
    >
      <div style={{
        width: '100%', height: '100%',
        borderRadius: 48,
        background: bg,
        overflow: 'hidden',
        position: 'relative',
      }}>
        {/* dynamic island */}
        <div style={{
          position: 'absolute',
          top: 10, left: '50%',
          transform: 'translateX(-50%)',
          width: 120, height: 34,
          borderRadius: 18,
          background: '#0c0b09',
          zIndex: 50,
        }} />
        {/* status time */}
        <div style={{
          position: 'absolute', top: 18, left: 28,
          fontSize: 15, fontWeight: 600,
          color: POTE_COLORS.black, zIndex: 40,
        }}>9:41</div>
        {/* status icons */}
        <div style={{
          position: 'absolute', top: 20, right: 28,
          display: 'flex', alignItems: 'center', gap: 5, zIndex: 40,
        }}>
          <svg width="16" height="11" viewBox="0 0 16 11"><g fill={POTE_COLORS.black}>
            <rect x="0" y="7" width="2.5" height="4" rx="0.5"/>
            <rect x="4" y="5" width="2.5" height="6" rx="0.5"/>
            <rect x="8" y="2.5" width="2.5" height="8.5" rx="0.5"/>
            <rect x="12" y="0" width="2.5" height="11" rx="0.5"/>
          </g></svg>
          <svg width="22" height="11" viewBox="0 0 22 11">
            <rect x="0.5" y="0.5" width="19" height="10" rx="3" fill="none" stroke={POTE_COLORS.black} strokeOpacity="0.4"/>
            <rect x="2" y="2" width="14" height="7" rx="1.5" fill={POTE_COLORS.black}/>
            <path d="M20.5 4v3c.6-.2 1-.7 1-1.5s-.4-1.3-1-1.5z" fill={POTE_COLORS.black} fillOpacity="0.55"/>
          </svg>
        </div>
        {/* home indicator */}
        <div style={{
          position: 'absolute', bottom: 8, left: '50%',
          transform: 'translateX(-50%)',
          width: 130, height: 5, borderRadius: 3,
          background: 'rgba(5,5,5,0.28)', zIndex: 60,
          pointerEvents: 'none',
        }} />
        {children}
      </div>
    </div>
  );
}

// ─────────────────────────────────────────────────────────────────────────
// WeekAccent — el ACENTO «toca esta semana». Un halo lima que abraza el orbe
// ─────────────────────────────────────────────────────────────────────────
// ClusterViewTabs — selector de VISTA del cluster, a escala de cabecera.
// Reemplaza el viejo «Tus potes · N activos». El usuario elige activamente:
//   Prioridad (default) → todos los potes en su orden (1·2·3…).
//   Esta semana         → solo los que tienen aporte; el resto, en calma.
// Tabs de texto con subrayado tinta — no repite la pastilla de Día|Sem.
// ─────────────────────────────────────────────────────────────────────────
function ClusterViewTabs({ value = 'prioridad', onChange, options }) {
  const opts = options || [{ k: 'prioridad', t: 'Prioridad' }, { k: 'semana', t: 'Esta semana' }];
  return (
    <div style={{ display: 'flex', gap: 18, alignItems: 'flex-end' }}>
      {opts.map(o => {
        const a = value === o.k;
        return (
          <span key={o.k} role="tab" aria-selected={a} onClick={() => onChange && onChange(o.k)} style={{
            position: 'relative', fontSize: 17, fontWeight: a ? 800 : 700, letterSpacing: '-0.5px',
            color: a ? POTE_COLORS.black : 'rgba(5,5,5,0.32)', cursor: 'pointer', paddingBottom: 6,
            lineHeight: '20px', fontFamily: 'inherit', userSelect: 'none', whiteSpace: 'nowrap',
          }}>
            {o.t}
            {a && <span style={{ position: 'absolute', left: 0, right: 0, bottom: 0, height: 3, borderRadius: 2, background: POTE_COLORS.black }} />}
          </span>
        );
      })}
    </div>
  );
}

// ─────────────────────────────────────────────────────────────────────────
// Floating cluster — utility to lay out home potes with natural positions.
// ORDEN = el del usuario (06c · Orden = grid): fijados primero, luego posición
// 1·2·3… (el orden del array). El puesto 1 está SIEMPRE al frente. El acento
// «toca esta semana» NO vive en el orbe: es la vista «Esta semana» del selector.
// ─────────────────────────────────────────────────────────────────────────
function PoteCluster({ items, animate = true, lang = 'es' }) {
  // each item: { name, goal, progress, color, x, y, size, label? }
  return (
    <div style={{ position: 'relative', width: '100%', height: '100%' }}>
      {items.map((p, i) => (
        <FloatingPote key={p.name + i} item={p} animate={animate} index={i} lang={lang} />
      ))}
    </div>
  );
}

function FloatingPote({ item, animate, index, lang }) {
  const { name, progress, color, x, y, size, mode = 'inside' } = item;
  // mode: 'inside' = % inside, name chip above; 'outside' = no text inside, paper label below
  const pct = Math.round(progress * 100);
  const id = `float-${index}`;
  const dx = (index % 2 === 0 ? 1 : -1) * 6;
  const dy = (index % 3 === 0 ? -1 : 1) * 8;
  const dur = 6.5 + (index * 0.7) % 3;
  const delay = (index * 0.6) % 4;
  return (
    <div style={{
      position: 'absolute',
      left: x, top: y,
      animation: animate ? `${id}-float ${dur}s ease-in-out ${delay}s infinite` : 'none',
    }}>
      <style>{`
        @keyframes ${id}-float {
          0%, 100% { transform: translate(0,0) }
          50%      { transform: translate(${dx}px, ${dy}px) }
        }
      `}</style>
      <div style={{ position: 'relative' }}>
        {mode === 'inside' && (
          <div style={{
            position: 'absolute',
            left: '50%', top: -14,
            transform: 'translateX(-50%)',
            zIndex: 2,
          }}>
            <NameChip>{name}</NameChip>
          </div>
        )}
        <PoteOrb
          color={color}
          progress={progress}
          size={size}
          showPercent={mode === 'inside'}
          animate={animate}
          seed={index}
        />
        {mode === 'outside' && (
          <div style={{
            position: 'absolute',
            left: '50%', bottom: -14,
            transform: 'translateX(-50%)',
            whiteSpace: 'nowrap',
            zIndex: 2,
          }}>
            <ExternalLabel name={name} pct={pct} />
          </div>
        )}
      </div>
    </div>
  );
}

// Register globals
Object.assign(window, {
  POTE_COLORS, ORB_PALETTES,
  PoteOrb, PoteWordmark,
  PrimaryButton, SecondaryButton, StepPill, Hl,
  NameChip, ExternalLabel, BottomNav, HomeTopBar, FAB,
  Card, PhoneFrame, PoteCluster, FloatingPote, NavIcon,
  ClusterViewTabs,
});
