// Pachi components — gold/red/black/purple ギラギラ vocabulary.
// All components share global window scope; component-local style objects use unique names.

const PACHI_TOKENS = {
  bg:        '#0a0606',
  bgPanel:   '#15090a',
  bgPanel2:  '#1c0d0f',
  gold:      '#f5c542',
  goldDeep:  '#d4a017',
  goldDim:   '#8a6914',
  red:       '#e0252b',
  redDeep:   '#9a0f15',
  redGlow:   'rgba(224,37,43,0.55)',
  purple:    '#6b2fb3',
  purpleDeep:'#3a1466',
  textHi:    '#fff8e6',
  textMid:   '#d9c79c',
  textDim:   '#a8926a',
  hairline:  'rgba(245,197,66,0.35)',
};

// ─── SVG icon set (no emoji) ───
function Icon({ name, size = 16, color = 'currentColor', fill = false, style = {} }) {
  const P = {
    search: <><circle cx="11" cy="11" r="6.5" /><line x1="15.8" y1="15.8" x2="21" y2="21" /></>,
    menu: <><line x1="4" y1="7" x2="20" y2="7" /><line x1="4" y1="12" x2="20" y2="12" /><line x1="4" y1="17" x2="20" y2="17" /></>,
    back: <polyline points="14.5,5 7.5,12 14.5,19" />,
    close: <><line x1="6" y1="6" x2="18" y2="18" /><line x1="18" y1="6" x2="6" y2="18" /></>,
    home: <path d="M4 11.5 L12 4.5 L20 11.5 V19.5 H14.5 V14 H9.5 V19.5 H4 Z" />,
    grid: <><rect x="4" y="4" width="7" height="7" /><rect x="13" y="4" width="7" height="7" /><rect x="4" y="13" width="7" height="7" /><rect x="13" y="13" width="7" height="7" /></>,
    chart: <><line x1="4.5" y1="20" x2="19.5" y2="20" /><line x1="7.5" y1="16.5" x2="7.5" y2="10" /><line x1="12" y1="16.5" x2="12" y2="4.5" /><line x1="16.5" y1="16.5" x2="16.5" y2="12" /></>,
    user: <><circle cx="12" cy="8" r="3.5" /><path d="M5 20 C5 15.5 19 15.5 19 20" /></>,
    star: <path d="M12 3.5 L14.4 9 L20.5 9.6 L15.9 13.6 L17.3 19.5 L12 16.4 L6.7 19.5 L8.1 13.6 L3.5 9.6 L9.6 9 Z" />,
    pin: <><path d="M12 21 C12 21 5.5 14.8 5.5 10 A6.5 6.5 0 0 1 18.5 10 C18.5 14.8 12 21 12 21 Z" /><circle cx="12" cy="10" r="2.3" /></>,
    train: <><rect x="6" y="4" width="12" height="12" rx="2" /><line x1="6" y1="10" x2="18" y2="10" /><circle cx="9.5" cy="13" r="0.7" /><circle cx="14.5" cy="13" r="0.7" /><line x1="9" y1="16" x2="7" y2="20" /><line x1="15" y1="16" x2="17" y2="20" /></>,
    slot: <><rect x="4" y="6" width="16" height="12" rx="1.5" /><line x1="9.3" y1="6" x2="9.3" y2="18" /><line x1="14.6" y1="6" x2="14.6" y2="18" /></>,
    clock: <><circle cx="12" cy="12" r="8" /><polyline points="12,7.5 12,12 15.5,14" /></>,
    phone: <path d="M6 4 H9.5 L11 8.5 L8.8 10.2 A11 11 0 0 0 13.8 15.2 L15.5 13 L20 14.5 V18 A2 2 0 0 1 18 20 A16 16 0 0 1 4 6 A2 2 0 0 1 6 4 Z" />,
    bell: <><path d="M6 17 V11 A6 6 0 0 1 18 11 V17 L19.5 19 H4.5 Z" /><path d="M10.5 21 A1.8 1.8 0 0 0 13.5 21" /></>,
    doc: <><path d="M7 3.5 H14 L18.5 8 V20.5 H7 Z" /><polyline points="14,3.5 14,8 18.5,8" /></>,
    lock: <><rect x="6" y="11" width="12" height="9" rx="1.5" /><path d="M8.5 11 V8 A3.5 3.5 0 0 1 15.5 8 V11" /></>,
    mail: <><rect x="4" y="6" width="16" height="13" rx="1.5" /><polyline points="4.5,7 12,13 19.5,7" /></>,
    power: <><path d="M7.5 7 A7 7 0 1 0 16.5 7" /><line x1="12" y1="3.5" x2="12" y2="11" /></>,
    settings: <><circle cx="12" cy="12" r="3" /><path d="M12 4 V6.5 M12 17.5 V20 M4 12 H6.5 M17.5 12 H20 M6.4 6.4 L8.2 8.2 M15.8 15.8 L17.6 17.6 M6.4 17.6 L8.2 15.8 M15.8 8.2 L17.6 6.4" /></>,
    play: <path d="M8.5 5.5 L18 12 L8.5 18.5 Z" />,
    check: <polyline points="5,12.5 10,17.5 19,7" />,
  };
  return (
    <svg width={size} height={size} viewBox="0 0 24 24"
      fill={fill ? color : 'none'} stroke={fill ? 'none' : color} strokeWidth="2"
      strokeLinecap="round" strokeLinejoin="round"
      style={{ display: 'block', flexShrink: 0, ...style }}>
      {P[name] || null}
    </svg>
  );
}

// ─── Gold frame: outer 1px gold + inner 1px dim gold + corner ticks ───
function GoldFrame({ children, padding = 0, style = {}, accent = 'gold', tight = false }) {
  const c = accent === 'red' ? PACHI_TOKENS.red : PACHI_TOKENS.gold;
  return (
    <div style={{
      position: 'relative',
      background: 'linear-gradient(180deg, #15090a 0%, #0c0506 100%)',
      border: `1px solid ${c}`,
      boxShadow: `0 0 0 1px rgba(0,0,0,0.6), inset 0 0 0 1px rgba(245,197,66,0.18), 0 4px 14px rgba(0,0,0,0.6)`,
      padding,
      ...style,
    }}>
      {!tight && <CornerTicks color={c} />}
      {children}
    </div>
  );
}

function CornerTicks({ color = PACHI_TOKENS.gold, size = 8 }) {
  const t = { position: 'absolute', width: size, height: size, borderColor: color, borderStyle: 'solid' };
  return (
    <>
      <span style={{ ...t, top: -1, left: -1, borderWidth: '2px 0 0 2px' }} />
      <span style={{ ...t, top: -1, right: -1, borderWidth: '2px 2px 0 0' }} />
      <span style={{ ...t, bottom: -1, left: -1, borderWidth: '0 0 2px 2px' }} />
      <span style={{ ...t, bottom: -1, right: -1, borderWidth: '0 2px 2px 0' }} />
    </>
  );
}

// ─── Red gradient pill section header ───
function SectionHeader({ kicker, title, action, onAction, accent = 'red' }) {
  const grad = accent === 'red'
    ? 'linear-gradient(90deg, #c40d13 0%, #e0252b 45%, #5a0509 100%)'
    : 'linear-gradient(90deg, #6b2fb3 0%, #b250ff 45%, #2a0e54 100%)';
  return (
    <div style={{ display: 'flex', alignItems: 'stretch', margin: '18px 12px 10px', gap: 0 }}>
      <div style={{
        position: 'relative',
        background: grad,
        padding: '7px 14px 7px 16px',
        clipPath: 'polygon(0 0, 100% 0, calc(100% - 12px) 100%, 0 100%)',
        boxShadow: `0 0 12px ${PACHI_TOKENS.redGlow}`,
        borderTop: `1px solid ${PACHI_TOKENS.gold}`,
        borderBottom: `1px solid ${PACHI_TOKENS.gold}`,
        flex: 1, minWidth: 0,
      }}>
        {kicker && (
          <div style={{
            fontSize: 9, letterSpacing: 2, fontWeight: 700,
            color: PACHI_TOKENS.gold, textTransform: 'uppercase',
            textShadow: '0 1px 0 #000',
          }}>{kicker}</div>
        )}
        <div style={{
          fontSize: 17, fontWeight: 900, color: '#fff8e6',
          letterSpacing: 0.5, lineHeight: 1.15,
          textShadow: '0 1px 0 #4a0408, 0 0 8px rgba(0,0,0,0.6)',
          fontFamily: '"Noto Sans JP", system-ui',
        }}>{title}</div>
      </div>
      {action && (
        <button onClick={onAction} style={{
          background: 'linear-gradient(180deg, #1a0d0f 0%, #0a0303 100%)',
          color: PACHI_TOKENS.gold,
          border: `1px solid ${PACHI_TOKENS.gold}`,
          fontSize: 12, fontWeight: 700, padding: '0 14px',
          cursor: 'pointer', fontFamily: '"Noto Sans JP", system-ui',
          marginLeft: -8, paddingLeft: 18,
          clipPath: 'polygon(12px 0, 100% 0, 100% 100%, 0 100%)',
        }}>{action} ›</button>
      )}
    </div>
  );
}

// ─── Page header — slim, non-sticky (the responsive TopBar is the app chrome) ───
function Header({ title = 'PACHI', onBack, onSearch, onMenu }) {
  return (
    <div style={{ display: 'flex', alignItems: 'center', gap: 10, margin: '8px 12px 0' }}>
      {onBack && (
        <button onClick={onBack} style={{
          display: 'inline-flex', alignItems: 'center', gap: 6,
          background: 'transparent', border: `1px solid ${PACHI_TOKENS.goldDim}`,
          color: PACHI_TOKENS.gold, padding: '8px 12px', fontSize: 12, fontWeight: 700,
          cursor: 'pointer', fontFamily: '"Noto Sans JP", system-ui', flexShrink: 0,
          whiteSpace: 'nowrap',
        }}><Icon name="back" size={14} />戻る</button>
      )}
      <div style={{
        fontSize: 16, fontWeight: 900, letterSpacing: 1,
        color: PACHI_TOKENS.gold,
        textShadow: '0 0 6px rgba(245,197,66,0.4)',
        fontFamily: '"Noto Sans JP", system-ui', flex: 1, minWidth: 0,
        overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap',
      }}>{title}</div>
      {onSearch && <button onClick={onSearch} style={iconBtn} aria-label="検索"><Icon name="search" size={18} /></button>}
      {onMenu && <button onClick={onMenu} style={iconBtn} aria-label="メニュー"><Icon name="menu" size={18} /></button>}
    </div>
  );
}
const iconBtn = {
  background: 'transparent', border: `1px solid ${PACHI_TOKENS.goldDim}`,
  color: PACHI_TOKENS.gold, width: 38, height: 38, padding: 0,
  cursor: 'pointer', display: 'grid', placeItems: 'center',
};

// ─── Hero banner with red glow + gold border ───
function HeroBanner({ src, label, onClick }) {
  return (
    <div onClick={onClick} style={{
      margin: '12px 12px 0', position: 'relative',
      border: `2px solid ${PACHI_TOKENS.gold}`,
      boxShadow: `0 0 24px rgba(224,37,43,0.45), 0 6px 18px rgba(0,0,0,0.6), inset 0 0 0 1px rgba(0,0,0,0.6)`,
      cursor: 'pointer',
    }}>
      <img src={src} alt="" style={{ display: 'block', width: '100%', height: 'auto' }} />
      {label && (
        <div style={{
          position: 'absolute', top: 8, left: 8,
          background: 'linear-gradient(90deg, #e0252b, #9a0f15)',
          color: '#fff', fontSize: 10, fontWeight: 900,
          padding: '3px 8px', letterSpacing: 1.5,
          border: `1px solid ${PACHI_TOKENS.gold}`,
          textShadow: '0 1px 0 #000',
        }}>{label}</div>
      )}
      <CornerTicks />
    </div>
  );
}

// ─── Event banner list (vertical) ───
function EventBannerList({ events, onSelect }) {
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 8, padding: '0 12px' }}>
      {events.map(e => (
        <div key={e.id} onClick={() => onSelect && onSelect(e)} style={{
          position: 'relative', cursor: 'pointer',
          border: `1px solid ${PACHI_TOKENS.gold}`,
          boxShadow: '0 0 10px rgba(224,37,43,0.25), 0 4px 10px rgba(0,0,0,0.6)',
        }}>
          <img src={e.banner} alt="" style={{ display: 'block', width: '100%', height: 'auto' }} />
        </div>
      ))}
    </div>
  );
}

// ─── Area button grid (6) ───
function AreaButtonGrid({ areas, onSelect }) {
  return (
    <div style={{
      display: 'grid', gridTemplateColumns: 'repeat(2, 1fr)', gap: 8,
      padding: '0 12px',
    }}>
      {areas.map(a => (
        <button key={a.id} onClick={() => onSelect && onSelect(a)} style={{
          background: a.primary
            ? 'linear-gradient(180deg, #2a0e0f 0%, #0c0303 100%)'
            : 'linear-gradient(180deg, #1a0708 0%, #060202 100%)',
          border: `1px solid ${a.primary ? PACHI_TOKENS.gold : PACHI_TOKENS.goldDim}`,
          boxShadow: a.primary ? '0 0 10px rgba(224,37,43,0.35)' : 'none',
          padding: '14px 12px', display: 'flex', alignItems: 'center',
          justifyContent: 'space-between', cursor: 'pointer',
          fontFamily: '"Noto Sans JP", system-ui',
        }}>
          <div style={{ textAlign: 'left' }}>
            <div style={{ color: PACHI_TOKENS.gold, fontWeight: 900, fontSize: 15, lineHeight: 1.1 }}>{a.label}</div>
            <div style={{ color: PACHI_TOKENS.textDim, fontSize: 11, marginTop: 2 }}>{a.halls.toLocaleString()} ホール</div>
          </div>
          <span style={{ color: PACHI_TOKENS.gold, fontSize: 18, fontWeight: 900 }}>›</span>
        </button>
      ))}
    </div>
  );
}

// ─── Quick menu icon grid (8) ───
function MenuIconGrid({ items, onSelect }) {
  return (
    <div style={{
      display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 8,
      padding: '0 12px',
    }}>
      {items.map(it => (
        <button key={it.id} onClick={() => onSelect && onSelect(it)} style={{
          background: 'radial-gradient(120% 100% at 50% 0%, #2a0e0f 0%, #0a0304 70%)',
          border: `1px solid ${PACHI_TOKENS.goldDim}`,
          padding: '10px 4px 8px', display: 'flex', flexDirection: 'column',
          alignItems: 'center', gap: 4, cursor: 'pointer', position: 'relative',
          boxShadow: 'inset 0 0 12px rgba(245,197,66,0.08)',
        }}>
          {it.icon ? (
            <img src={it.icon} alt="" style={{
              width: 44, height: 44, objectFit: 'contain',
              filter: 'drop-shadow(0 0 6px rgba(245,197,66,0.5))',
            }} />
          ) : (
            <div style={{
              width: 36, height: 36, display: 'grid', placeItems: 'center',
              background: 'linear-gradient(135deg, #f5c542 0%, #d4a017 50%, #8a6914 100%)',
              color: '#1a0606', fontSize: 18, fontWeight: 900,
              boxShadow: 'inset 0 -2px 4px rgba(0,0,0,0.4), 0 0 8px rgba(245,197,66,0.4)',
              borderRadius: '50%',
            }}>{it.glyph}</div>
          )}
          <div style={{
            fontSize: 11, fontWeight: 700, color: PACHI_TOKENS.textHi,
            fontFamily: '"Noto Sans JP", system-ui', textAlign: 'center',
          }}>{it.label}</div>
        </button>
      ))}
    </div>
  );
}

// ─── Store card ───
function StoreCard({ shop, onClick }) {
  return (
    <div onClick={onClick} style={{
      margin: '0 12px', cursor: 'pointer', position: 'relative',
      border: `1px solid ${PACHI_TOKENS.gold}`,
      background: 'linear-gradient(180deg, #15090a 0%, #0a0405 100%)',
      boxShadow: '0 0 12px rgba(224,37,43,0.2), 0 4px 10px rgba(0,0,0,0.5)',
      padding: 10, display: 'flex', gap: 10, alignItems: 'flex-start',
    }}>
      <div style={{
        width: 96, height: 96, flexShrink: 0,
        backgroundImage: `url(${shop.image})`,
        backgroundSize: 'cover', backgroundPosition: 'center',
        backgroundColor: '#000',
        border: `1px solid ${PACHI_TOKENS.goldDim}`,
        boxShadow: 'inset 0 0 16px rgba(0,0,0,0.6)',
      }} />
      <div style={{ flex: 1, minWidth: 0 }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 6, marginBottom: 4 }}>
          <div style={{
            color: PACHI_TOKENS.gold, fontWeight: 900, fontSize: 15,
            fontFamily: '"Noto Sans JP", system-ui', flex: 1, minWidth: 0,
            overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap',
            textShadow: '0 0 4px rgba(245,197,66,0.4)',
          }}>{shop.name}</div>
          {shop.todayEvent && (
            <div style={{
              background: 'linear-gradient(180deg, #e0252b, #9a0f15)',
              color: '#fff', fontSize: 9, fontWeight: 900, padding: '2px 5px',
              border: `1px solid ${PACHI_TOKENS.gold}`, letterSpacing: 1,
              fontFamily: '"Noto Sans JP", system-ui', flexShrink: 0,
            }}>本日</div>
          )}
        </div>
        <div style={{ display: 'flex', alignItems: 'center', gap: 4, marginBottom: 4 }}>
          <Stars rating={shop.rating} />
          <span style={{ color: PACHI_TOKENS.gold, fontSize: 11, fontWeight: 700 }}>{shop.rating}</span>
          <span style={{ color: PACHI_TOKENS.textDim, fontSize: 11 }}>({shop.ratingCount}件)</span>
        </div>
        <Row icon="pin" text={shop.address} />
        <Row icon="train" text={shop.station} />
        <Row icon="slot" text={`パチスロ ${shop.slotCount}台`} />
        <Row icon="clock" text={shop.openHours} />
      </div>
    </div>
  );
}
function Row({ icon, text }) {
  return (
    <div style={{
      display: 'flex', alignItems: 'center', gap: 6, color: PACHI_TOKENS.textHi,
      fontSize: 12, fontFamily: '"Noto Sans JP", system-ui', lineHeight: 1.6,
    }}>
      <Icon name={icon} size={13} color={PACHI_TOKENS.gold} />
      <span style={{ flex: 1, minWidth: 0, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{text}</span>
    </div>
  );
}
function Stars({ rating }) {
  return (
    <div style={{ display: 'flex', gap: 1 }}>
      {[1,2,3,4,5].map(i => (
        <Icon key={i} name="star" size={12} fill
          color={i <= Math.round(rating) ? PACHI_TOKENS.gold : '#3a2a10'} />
      ))}
    </div>
  );
}

// ─── Machine thumbnail grid ───
function MachineThumbnailGrid({ machines, onSelect, columns = 3 }) {
  return (
    <div style={{
      display: 'grid', gridTemplateColumns: `repeat(${columns}, 1fr)`, gap: 8,
      padding: '0 12px',
    }}>
      {machines.map(m => (
        <button key={m.id} onClick={() => onSelect && onSelect(m)} style={{
          background: '#000', border: `1px solid ${PACHI_TOKENS.gold}`,
          padding: 0, cursor: 'pointer', position: 'relative',
          boxShadow: '0 0 8px rgba(224,37,43,0.2)',
        }}>
          <img src={m.thumbnail} alt={m.name} style={{ display: 'block', width: '100%', height: 'auto' }} />
          <div style={{
            position: 'absolute', bottom: 0, left: 0, right: 0,
            background: 'linear-gradient(180deg, transparent 0%, rgba(0,0,0,0.95) 60%)',
            padding: '14px 6px 6px', textAlign: 'center',
          }}>
            <div style={{
              color: PACHI_TOKENS.gold, fontSize: 11, fontWeight: 900,
              fontFamily: '"Noto Sans JP", system-ui', lineHeight: 1.15,
              textShadow: '0 1px 0 #000', overflow: 'hidden',
              textOverflow: 'ellipsis', whiteSpace: 'nowrap',
            }}>{m.name}</div>
          </div>
        </button>
      ))}
    </div>
  );
}

// ─── Bottom nav (5 tabs) ───
function BottomNav({ active, onChange }) {
  const tabs = [
    { id: 'home',    label: 'ホーム',     glyph: 'home' },
    { id: 'hall',    label: 'ホール',     glyph: 'search' },
    { id: 'data',    label: '台データ',   glyph: 'chart' },
    { id: 'machine', label: '機種一覧',   glyph: 'grid' },
    { id: 'mypage',  label: 'マイページ', glyph: 'user' },
  ];
  return (
    <div style={{
      position: 'sticky', bottom: 0, zIndex: 20,
      background: 'linear-gradient(180deg, #15090a 0%, #050202 100%)',
      borderTop: `2px solid ${PACHI_TOKENS.gold}`,
      boxShadow: '0 -4px 14px rgba(0,0,0,0.7), 0 -2px 16px rgba(224,37,43,0.18)',
      display: 'grid', gridTemplateColumns: 'repeat(5, 1fr)', height: 64,
      paddingBottom: 'env(safe-area-inset-bottom, 0)',
    }}>
      {tabs.map(t => {
        const on = t.id === active;
        return (
          <button key={t.id} onClick={() => onChange && onChange(t.id)} style={{
            background: on
              ? 'radial-gradient(80% 100% at 50% 100%, rgba(224,37,43,0.7) 0%, rgba(224,37,43,0) 70%)'
              : 'transparent',
            border: 'none', borderTop: on ? `2px solid ${PACHI_TOKENS.gold}` : '2px solid transparent',
            marginTop: -2, color: on ? PACHI_TOKENS.gold : PACHI_TOKENS.textDim,
            display: 'flex', flexDirection: 'column', alignItems: 'center',
            justifyContent: 'center', gap: 3, cursor: 'pointer', padding: 0,
            fontFamily: '"Noto Sans JP", system-ui',
          }}>
            <Icon name={t.glyph} size={21}
              style={{ filter: on ? 'drop-shadow(0 0 5px rgba(245,197,66,0.7))' : 'none' }} />
            <span style={{ fontSize: 10.5, fontWeight: 700 }}>{t.label}</span>
          </button>
        );
      })}
    </div>
  );
}

// ─── Stats panel (BB / RB / total games / rate / diff) ───
function StatsPanel({ data }) {
  const rows = [
    { label: '総回転数', value: data.totalGames.toLocaleString(), suffix: 'G' },
    { label: 'BB',      value: data.bb,                            color: PACHI_TOKENS.red },
    { label: 'RB',      value: data.rb,                            color: '#3070d8' },
    { label: '合成確率', value: data.combinedRate },
    { label: '差枚',    value: (data.payoutDiff > 0 ? '+' : '') + data.payoutDiff.toLocaleString(),
      color: data.payoutDiff >= 0 ? PACHI_TOKENS.red : '#3070d8', big: true },
  ];
  return (
    <GoldFrame style={{ margin: '0 12px' }}>
      <div style={{ display: 'flex', flexDirection: 'column' }}>
        {rows.map((r, i) => (
          <div key={r.label} style={{
            display: 'flex', justifyContent: 'space-between', alignItems: 'baseline',
            padding: '10px 14px',
            borderTop: i === 0 ? 'none' : `1px solid ${PACHI_TOKENS.hairline}`,
          }}>
            <span style={{
              color: PACHI_TOKENS.textMid, fontSize: 13, fontWeight: 700,
              fontFamily: '"Noto Sans JP", system-ui',
            }}>{r.label}</span>
            <span style={{
              color: r.color || PACHI_TOKENS.gold,
              fontSize: r.big ? 22 : 16, fontWeight: 900,
              fontFamily: '"Bebas Neue", "Noto Sans JP", system-ui',
              letterSpacing: 1,
              textShadow: r.color ? `0 0 8px ${r.color}88` : '0 0 6px rgba(245,197,66,0.4)',
            }}>{r.value}{r.suffix && <span style={{ fontSize: 11, marginLeft: 2, color: PACHI_TOKENS.textDim }}>{r.suffix}</span>}</span>
          </div>
        ))}
      </div>
    </GoldFrame>
  );
}

// ─── Slump graph (SVG, replaceable) ───
function GraphPanel({ data }) {
  const points = data.graph;
  const w = 350, h = 180, padL = 36, padR = 12, padT = 16, padB = 22;
  const min = Math.min(...points, 0) - 500;
  const max = Math.max(...points, 0) + 500;
  const range = max - min;
  const xs = (i) => padL + ((w - padL - padR) * i) / (points.length - 1);
  const ys = (v) => padT + (h - padT - padB) * (1 - (v - min) / range);
  const zeroY = ys(0);
  const path = points.map((p, i) => `${i === 0 ? 'M' : 'L'}${xs(i)},${ys(p)}`).join(' ');
  const fillPath = `${path} L${xs(points.length - 1)},${zeroY} L${xs(0)},${zeroY} Z`;
  const positive = data.payoutDiff >= 0;
  const lineColor = positive ? PACHI_TOKENS.red : '#3070d8';
  const yticks = [Math.ceil(max / 5000) * 5000, 5000, 0, -5000].filter(v => v >= min && v <= max);
  return (
    <GoldFrame style={{ margin: '0 12px', padding: 10 }}>
      <div style={{
        display: 'flex', justifyContent: 'space-between', alignItems: 'baseline',
        marginBottom: 6, padding: '0 4px',
      }}>
        <span style={{
          color: PACHI_TOKENS.textMid, fontSize: 11, fontWeight: 700,
          fontFamily: '"Noto Sans JP", system-ui',
        }}>スランプグラフ</span>
        <span style={{
          color: lineColor, fontSize: 22, fontWeight: 900,
          fontFamily: '"Bebas Neue", system-ui', letterSpacing: 1,
          textShadow: `0 0 10px ${lineColor}88`,
        }}>{positive ? '+' : ''}{data.payoutDiff.toLocaleString()}<span style={{ fontSize: 11, marginLeft: 2 }}>枚</span></span>
      </div>
      <svg viewBox={`0 0 ${w} ${h}`} width="100%" style={{ display: 'block' }}>
        <defs>
          <linearGradient id="grad-fill" x1="0" y1="0" x2="0" y2="1">
            <stop offset="0%" stopColor={lineColor} stopOpacity="0.5" />
            <stop offset="100%" stopColor={lineColor} stopOpacity="0" />
          </linearGradient>
        </defs>
        {/* gridlines */}
        {yticks.map(v => (
          <g key={v}>
            <line x1={padL} x2={w-padR} y1={ys(v)} y2={ys(v)}
                  stroke={v === 0 ? PACHI_TOKENS.gold : PACHI_TOKENS.hairline}
                  strokeWidth={v === 0 ? 1 : 0.5} strokeDasharray={v === 0 ? '0' : '2 2'} />
            <text x={padL - 4} y={ys(v) + 3} fontSize="9" fill={PACHI_TOKENS.textDim}
                  textAnchor="end" fontFamily="Bebas Neue, monospace">{v.toLocaleString()}</text>
          </g>
        ))}
        {/* x-axis labels (hours) */}
        {[0, 6, 12, 18, 24].map(i => (
          <text key={i} x={xs(i)} y={h - 6} fontSize="9" fill={PACHI_TOKENS.textDim}
                textAnchor="middle" fontFamily="Bebas Neue, monospace">
            {String(9 + Math.round(i / 2)).padStart(2,'0')}:00
          </text>
        ))}
        <path d={fillPath} fill="url(#grad-fill)" />
        <path d={path} fill="none" stroke={lineColor} strokeWidth="2"
              style={{ filter: `drop-shadow(0 0 4px ${lineColor})` }} />
      </svg>
    </GoldFrame>
  );
}

// ─── History panel ───
function HistoryPanel({ history }) {
  return (
    <GoldFrame style={{ margin: '0 12px' }}>
      <div style={{
        padding: '8px 12px',
        borderBottom: `1px solid ${PACHI_TOKENS.hairline}`,
        background: 'linear-gradient(180deg, #2a0d0e 0%, #150607 100%)',
      }}>
        <span style={{
          color: PACHI_TOKENS.gold, fontSize: 12, fontWeight: 900,
          fontFamily: '"Noto Sans JP", system-ui', letterSpacing: 1,
        }}>当り履歴</span>
      </div>
      <div>
        {history.map((h, i) => (
          <div key={i} style={{
            display: 'grid', gridTemplateColumns: '64px 56px 1fr auto',
            alignItems: 'center', padding: '9px 12px', gap: 10,
            borderTop: i === 0 ? 'none' : `1px solid ${PACHI_TOKENS.hairline}`,
            fontFamily: '"Bebas Neue", monospace',
          }}>
            <span style={{ color: PACHI_TOKENS.textHi, fontSize: 14, fontWeight: 700, letterSpacing: 0.5 }}>{h.time}</span>
            <span style={{
              padding: '2px 0', textAlign: 'center', fontSize: 11, fontWeight: 900,
              background: h.type === 'BB' ? 'linear-gradient(180deg, #e0252b, #9a0f15)' : 'linear-gradient(180deg, #3070d8, #1a3a82)',
              color: '#fff', border: `1px solid ${PACHI_TOKENS.gold}`, letterSpacing: 1,
            }}>{h.type}</span>
            <span style={{ color: PACHI_TOKENS.gold, fontSize: 14, fontWeight: 700 }}>{h.count}<span style={{ fontSize: 10, color: PACHI_TOKENS.textDim, marginLeft: 2 }}>回目</span></span>
            <span style={{ color: PACHI_TOKENS.textHi, fontSize: 14, fontWeight: 700, letterSpacing: 0.5 }}>{h.game}</span>
          </div>
        ))}
      </div>
    </GoldFrame>
  );
}

// ─── Day-tabs (今日 / 昨日 / 2日前 / 3日前) ───
function DayTabs({ active, onChange }) {
  const tabs = ['当日', '前日', '2日前', '3日前'];
  return (
    <div style={{
      display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 0,
      margin: '0 12px',
      border: `1px solid ${PACHI_TOKENS.gold}`,
    }}>
      {tabs.map((t, i) => {
        const on = i === active;
        return (
          <button key={t} onClick={() => onChange && onChange(i)} style={{
            background: on
              ? 'linear-gradient(180deg, #e0252b 0%, #6a0509 100%)'
              : 'linear-gradient(180deg, #1a0708 0%, #0a0303 100%)',
            color: on ? '#fff' : PACHI_TOKENS.textMid,
            border: 'none', borderRight: i < 3 ? `1px solid ${PACHI_TOKENS.goldDim}` : 'none',
            padding: '10px 0', fontSize: 12, fontWeight: 900, cursor: 'pointer',
            fontFamily: '"Noto Sans JP", system-ui',
            textShadow: on ? '0 1px 0 #000' : 'none',
            boxShadow: on ? 'inset 0 0 12px rgba(245,197,66,0.4)' : 'none',
          }}>{t}</button>
        );
      })}
    </div>
  );
}

// ─── Search bar (used in shop list) ───
function AreaStationToggle({ active, onChange }) {
  return (
    <div style={{
      display: 'grid', gridTemplateColumns: '1fr 1fr', margin: '0 12px',
      border: `1px solid ${PACHI_TOKENS.gold}`,
    }}>
      {['エリアから探す', '駅名から探す'].map((t, i) => {
        const on = i === active;
        return (
          <button key={t} onClick={() => onChange && onChange(i)} style={{
            background: on ? 'linear-gradient(180deg, #f5c542 0%, #8a6914 100%)' : 'transparent',
            color: on ? '#1a0606' : PACHI_TOKENS.gold,
            border: 'none', borderRight: i === 0 ? `1px solid ${PACHI_TOKENS.gold}` : 'none',
            padding: '10px 0', fontSize: 12, fontWeight: 900, cursor: 'pointer',
            fontFamily: '"Noto Sans JP", system-ui',
            textShadow: on ? 'none' : '0 0 4px rgba(245,197,66,0.4)',
          }}><span style={{ display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: 6 }}><Icon name={i === 0 ? 'pin' : 'train'} size={14} />{t}</span></button>
        );
      })}
    </div>
  );
}

// ─── Play button (random external casino link) ───
const PACHI_PLAY_LINKS = [
  { name: 'Konibet',     host: 'konibet.com', tone: 'gold' },
  { name: 'スロット天国', host: 'sloten.io',   tone: 'red'  },
  { name: 'ELDOAH',      host: 'eldoah.com',  tone: 'purple' },
];

function PlayButton({ machineName }) {
  const [hover, setHover] = React.useState(false);
  const [pick]  = React.useState(() => PACHI_PLAY_LINKS[Math.floor(Math.random() * PACHI_PLAY_LINKS.length)]);
  const handle = () => {
    const fresh = PACHI_PLAY_LINKS[Math.floor(Math.random() * PACHI_PLAY_LINKS.length)];
    window.open(`https://${fresh.host}/`, '_blank', 'noopener,noreferrer');
  };
  return (
    <div style={{ padding: '0 12px' }}>
      <button onClick={handle}
        onMouseEnter={() => setHover(true)} onMouseLeave={() => setHover(false)}
        style={{
        position: 'relative', overflow: 'hidden',
        width: '100%', padding: '14px 14px',
        background: 'linear-gradient(180deg, #ffe48a 0%, #f5c542 35%, #d4a017 65%, #8a6914 100%)',
        border: `2px solid ${PACHI_TOKENS.gold}`,
        color: '#1a0606', cursor: 'pointer',
        fontFamily: '"Noto Sans JP", system-ui',
        boxShadow: hover
          ? '0 0 28px rgba(245,197,66,0.85), 0 0 18px rgba(224,37,43,0.5), inset 0 -3px 0 rgba(0,0,0,0.3)'
          : '0 0 18px rgba(245,197,66,0.55), 0 0 12px rgba(224,37,43,0.35), inset 0 -3px 0 rgba(0,0,0,0.3)',
        transform: hover ? 'translateY(-1px)' : 'translateY(0)',
        transition: 'box-shadow 0.18s ease, transform 0.12s ease',
        display: 'flex', alignItems: 'center', justifyContent: 'space-between',
      }}>
        {/* shine sweep */}
        <span style={{
          position: 'absolute', top: 0, bottom: 0, left: hover ? '110%' : '-40%',
          width: '40%',
          background: 'linear-gradient(90deg, transparent, rgba(255,255,255,0.7), transparent)',
          transform: 'skewX(-20deg)', pointerEvents: 'none',
          transition: 'left 0.6s ease',
        }} />
        <span style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
          <span style={{
            display: 'inline-grid', placeItems: 'center',
            width: 28, height: 28, background: '#1a0606', borderRadius: '50%',
            color: PACHI_TOKENS.gold, display: 'grid', placeItems: 'center',
            boxShadow: 'inset 0 0 6px rgba(245,197,66,0.4)',
          }}><Icon name="play" size={13} fill color={PACHI_TOKENS.gold} /></span>
          <span style={{
            fontSize: 17, fontWeight: 900, letterSpacing: 4,
            textShadow: '0 1px 0 rgba(255,255,255,0.4)',
          }}>プレイする</span>
        </span>
        <span style={{
          fontSize: 9, fontWeight: 900, letterSpacing: 2,
          padding: '4px 8px', background: 'rgba(26,6,6,0.85)',
          color: PACHI_TOKENS.gold, border: `1px solid rgba(0,0,0,0.4)`,
          fontFamily: '"Bebas Neue", system-ui',
        }}>PLAY ONLINE</span>
      </button>
      <div style={{
        marginTop: 6,
        display: 'flex', alignItems: 'center', justifyContent: 'space-between',
        fontSize: 10, color: PACHI_TOKENS.textDim,
        fontFamily: '"Noto Sans JP", system-ui',
      }}>
        <span>提携カジノでオンラインプレイ</span>
        <span style={{ display: 'flex', gap: 6 }}>
          {PACHI_PLAY_LINKS.map(l => (
            <span key={l.host} style={{
              fontFamily: '"Bebas Neue", system-ui', letterSpacing: 1,
              color: l.tone === 'red' ? PACHI_TOKENS.red
                   : l.tone === 'purple' ? '#b18cff'
                   : PACHI_TOKENS.gold,
            }}>{l.host}</span>
          ))}
        </span>
      </div>
    </div>
  );
}

// expose globally
Object.assign(window, {
  PACHI_TOKENS, Icon, GoldFrame, CornerTicks, SectionHeader, Header, HeroBanner,
  EventBannerList, AreaButtonGrid, MenuIconGrid, StoreCard, MachineThumbnailGrid,
  BottomNav, StatsPanel, GraphPanel, HistoryPanel, DayTabs, AreaStationToggle,
  PlayButton,
});
