function PageHead({ kicker, title, subtitle, actions }) {
  return (
    <div className="page-head">
      <div className="stack">
        {kicker && <div className="kicker">{kicker}</div>}
        <h1>{title}</h1>
        {subtitle && <p className="copy">{subtitle}</p>}
      </div>
      {actions && <div className="row">{actions}</div>}
    </div>
  );
}

function Stat({ value, label, tone }) {
  return (
    <div className="stat">
      <div className="stat-value" style={{ color: tone ? `var(--${tone})` : undefined }}>{value}</div>
      <div className="stat-label">{label}</div>
    </div>
  );
}

function Pill({ children, tone = '' }) {
  return <span className={`pill ${tone}`}>{children}</span>;
}

function ProgressBar({ value }) {
  const width = Math.max(0, Math.min(100, Number(value || 0)));
  return <div className="progress" aria-label={`${Math.round(width)}%`}><span style={{ width: `${width}%` }} /></div>;
}

function EmptyState({ title, body }) {
  return (
    <div className="empty">
      <div className="stack">
        <h3>{title}</h3>
        {body && <p>{body}</p>}
      </div>
    </div>
  );
}

function TaskBlocks({ blocks }) {
  return (
    <div className="panel">
      {(blocks || []).map((block, index) => (
        <div className="task-block" key={`${block.label}-${index}`}>
          <div>
            <div className="task-min">{block.minutes}m</div>
            <div className="muted mono" style={{ fontSize: 11 }}>{block.label}</div>
          </div>
          <p className="copy">{block.task}</p>
        </div>
      ))}
    </div>
  );
}

function categoryTone(category) {
  return category || 'weak';
}

function categoryLabel(category) {
  return window.CATEGORY_LABELS?.[category] || category || 'Weak';
}

function formatShortDate(dateText) {
  if (!dateText) return '-';
  const dt = parseDate(dateText);
  return dt.toLocaleDateString('en-US', { month: 'short', day: '2-digit' });
}

function formatLongDate(dateText) {
  const dt = parseDate(dateText);
  return dt.toLocaleDateString('en-US', { weekday: 'long', month: 'short', day: '2-digit' });
}

function clampText(value, fallback = '') {
  return String(value || fallback || '').trim();
}

function TypePill({ type }) {
  return <span className={`type-pill type-${String(type || 'study').toLowerCase()}`}>{type || 'STUDY'}</span>;
}

function PhasePill({ phase }) {
  return <span className="phase-pill">{phase || 'Phase'}</span>;
}

function Check({ on, onClick, size = 22 }) {
  return (
    <button
      className={`check ${on ? 'on' : ''}`}
      style={{ width: size, height: size }}
      onClick={onClick}
      aria-pressed={!!on}
    >
      {on ? 'x' : ''}
    </button>
  );
}

function Rating({ value = 0, onChange, color = 'var(--accent)' }) {
  return (
    <div className="rating">
      {[1, 2, 3, 4, 5].map(n => (
        <button
          key={n}
          className={`rating-dot ${Number(value || 0) >= n ? 'on' : ''}`}
          style={Number(value || 0) >= n ? { background: color, borderColor: color } : null}
          onClick={() => onChange(n)}
          aria-label={`${n}`}
        />
      ))}
    </div>
  );
}

Object.assign(window, {
  PageHead,
  Stat,
  Pill,
  ProgressBar,
  EmptyState,
  TaskBlocks,
  TypePill,
  PhasePill,
  Check,
  Rating,
  categoryTone,
  categoryLabel,
  formatShortDate,
  formatLongDate,
  clampText,
});
