// lib.jsx — Renegade shared primitives, icons, nav/footer, domain data
const { useState, useEffect, useRef, Fragment } = React;

/* ----------------------------- Icons (Lucide 1.5px) ----------------------------- */
const ICONS = {
  zap: '<path d="M4 14a1 1 0 0 1-.78-1.63l9.9-10.2a.5.5 0 0 1 .86.46l-1.92 6.02A1 1 0 0 0 13 10h7a1 1 0 0 1 .78 1.63l-9.9 10.2a.5.5 0 0 1-.86-.46l1.92-6.02A1 1 0 0 0 11 14z"/>',
  home: '<path d="m3 9 9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/><polyline points="9 22 9 12 15 12 15 22"/>',
  search: '<circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/>',
  hash: '<line x1="4" x2="20" y1="9" y2="9"/><line x1="4" x2="20" y1="15" y2="15"/><line x1="10" x2="8" y1="3" y2="21"/><line x1="16" x2="14" y1="3" y2="21"/>',
  check: '<path d="M20 6 9 17l-5-5"/>',
  checkCircle: '<circle cx="12" cy="12" r="10"/><path d="m9 12 2 2 4-4"/>',
  chevronDown: '<path d="m6 9 6 6 6-6"/>',
  chevronRight: '<path d="m9 18 6-6-6-6"/>',
  chevronLeft: '<path d="m15 18-6-6 6-6"/>',
  arrowRight: '<path d="M5 12h14"/><path d="m12 5 7 7-7 7"/>',
  arrowLeft: '<path d="m12 19-7-7 7-7"/><path d="M19 12H5"/>',
  sun: '<circle cx="12" cy="12" r="4"/><path d="M12 2v2"/><path d="M12 20v2"/><path d="m4.93 4.93 1.41 1.41"/><path d="m17.66 17.66 1.41 1.41"/><path d="M2 12h2"/><path d="M20 12h2"/><path d="m6.34 17.66-1.41 1.41"/><path d="m19.07 4.93-1.41 1.41"/>',
  info: '<circle cx="12" cy="12" r="10"/><path d="M12 16v-4"/><path d="M12 8h.01"/>',
  fileText: '<path d="M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z"/><path d="M14 2v4a2 2 0 0 0 2 2h4"/><path d="M16 13H8"/><path d="M16 17H8"/><path d="M10 9H8"/>',
  download: '<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" x2="12" y1="15" y2="3"/>',
  creditCard: '<rect width="20" height="14" x="2" y="5" rx="2"/><line x1="2" x2="22" y1="10" y2="10"/>',
  activity: '<path d="M22 12h-2.48a2 2 0 0 0-1.93 1.46l-2.35 8.36a.25.25 0 0 1-.48 0L9.24 2.18a.25.25 0 0 0-.48 0l-2.35 8.36A2 2 0 0 1 4.49 12H2"/>',
  gauge: '<path d="m12 14 4-4"/><path d="M3.34 19a10 10 0 1 1 17.32 0"/>',
  sliders: '<line x1="21" x2="14" y1="4" y2="4"/><line x1="10" x2="3" y1="4" y2="4"/><line x1="21" x2="12" y1="12" y2="12"/><line x1="8" x2="3" y1="12" y2="12"/><line x1="21" x2="16" y1="20" y2="20"/><line x1="12" x2="3" y1="20" y2="20"/><line x1="14" x2="14" y1="2" y2="6"/><line x1="8" x2="8" y1="10" y2="14"/><line x1="16" x2="16" y1="18" y2="22"/>',
  user: '<path d="M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/>',
  logOut: '<path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"/><polyline points="16 17 21 12 16 7"/><line x1="21" x2="9" y1="12" y2="12"/>',
  menu: '<line x1="4" x2="20" y1="12" y2="12"/><line x1="4" x2="20" y1="6" y2="6"/><line x1="4" x2="20" y1="18" y2="18"/>',
  x: '<path d="M18 6 6 18"/><path d="m6 6 12 12"/>',
  plus: '<path d="M5 12h14"/><path d="M12 5v14"/>',
  lock: '<rect width="18" height="11" x="3" y="11" rx="2" ry="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/>',
  alert: '<circle cx="12" cy="12" r="10"/><line x1="12" x2="12" y1="8" y2="12"/><line x1="12" x2="12.01" y1="16" y2="16"/>',
  mapPin: '<path d="M20 10c0 6-8 12-8 12s-8-6-8-12a8 8 0 0 1 16 0Z"/><circle cx="12" cy="10" r="3"/>',
  leaf: '<path d="M11 20A7 7 0 0 1 9.8 6.1C15.5 5 17 4.48 19 2c1 2 2 4.18 2 8 0 5.5-4.78 10-10 10Z"/><path d="M2 21c0-3 1.85-5.36 5.08-6C9.5 14.52 12 13 13 12"/>',
  shield: '<path d="M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z"/>',
  clock: '<circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/>',
  calendar: '<path d="M8 2v4"/><path d="M16 2v4"/><rect width="18" height="18" x="3" y="4" rx="2"/><path d="M3 10h18"/>',
  phone: '<path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z"/>',
  mail: '<rect width="20" height="16" x="2" y="4" rx="2"/><path d="m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7"/>',
  building: '<rect width="16" height="20" x="4" y="2" rx="2"/><path d="M9 22v-4h6v4"/><path d="M8 6h.01"/><path d="M16 6h.01"/><path d="M12 6h.01"/><path d="M12 10h.01"/><path d="M12 14h.01"/><path d="M16 10h.01"/><path d="M16 14h.01"/><path d="M8 10h.01"/><path d="M8 14h.01"/>',
  grid: '<rect width="7" height="7" x="3" y="3" rx="1"/><rect width="7" height="7" x="14" y="3" rx="1"/><rect width="7" height="7" x="14" y="14" rx="1"/><rect width="7" height="7" x="3" y="14" rx="1"/>',
  trendDown: '<polyline points="22 17 13.5 8.5 8.5 13.5 2 7"/><polyline points="16 17 22 17 22 11"/>',
  trendUp: '<polyline points="22 7 13.5 15.5 8.5 10.5 2 17"/><polyline points="16 7 22 7 22 13"/>',
  wallet: '<path d="M19 7V4a1 1 0 0 0-1-1H5a2 2 0 0 0 0 4h15a1 1 0 0 1 1 1v4h-3a2 2 0 0 0 0 4h3a1 1 0 0 0 1-1v-2a1 1 0 0 0-1-1"/><path d="M3 5v14a2 2 0 0 0 2 2h15a1 1 0 0 0 1-1v-4"/>',
  plug: '<path d="M12 22v-5"/><path d="M9 8V2"/><path d="M15 8V2"/><path d="M18 8v5a4 4 0 0 1-4 4h-4a4 4 0 0 1-4-4V8Z"/>',
  meter: '<circle cx="12" cy="12" r="9"/><path d="M12 12 8.5 8.5"/><path d="M12 7v1"/><path d="M17 12h-1"/><path d="M8 12H7"/>',
  receipt: '<path d="M4 2v20l2-1 2 1 2-1 2 1 2-1 2 1 2-1 2 1V2l-2 1-2-1-2 1-2-1-2 1-2-1-2 1Z"/><path d="M16 8h-6a2 2 0 1 0 0 4h4a2 2 0 1 1 0 4H8"/><path d="M12 17.5v-11"/>',
  bolt: '<path d="M13 2 3 14h9l-1 8 10-12h-9l1-8z"/>',
  facebook: '<path d="M18 2h-3a5 5 0 0 0-5 5v3H7v4h3v8h4v-8h3l1-4h-4V7a1 1 0 0 1 1-1h3z"/>',
  instagram: '<rect width="20" height="20" x="2" y="2" rx="5" ry="5"/><path d="M16 11.37A4 4 0 1 1 12.63 8 4 4 0 0 1 16 11.37z"/><line x1="17.5" x2="17.51" y1="6.5" y2="6.5"/>',
  twitter: '<path d="M22 4s-.7 2.1-2 3.4c1.6 10-9.4 17.3-18 11.6 2.2.1 4.4-.6 6-2C3 15.5.5 9.6 3 5c2.2 2.6 5.6 4.1 9 4-.9-4.2 4-6.6 7-3.8 1.1 0 3-1.2 3-1.2z"/>',
};
const Icon = ({ n, size = 20, sw = 1.5, style, className }) => (
  <svg className={'ic' + (className ? ' ' + className : '')} width={size} height={size} viewBox="0 0 24 24"
    fill="none" stroke="currentColor" strokeWidth={sw} strokeLinecap="round" strokeLinejoin="round"
    style={style} dangerouslySetInnerHTML={{ __html: ICONS[n] || '' }} aria-hidden="true" />
);
window.Icon = Icon;

/* ----------------------------- Logo ----------------------------- */
const Logo = ({ dark = false, height = 30 }) => (
  <img className="logo-img" src={dark ? 'assets/logo-white.png' : 'assets/logo.png'}
    alt="Renegade Energy" style={{ height }} />
);
window.Logo = Logo;

/* ----------------------------- Button ----------------------------- */
const Button = ({ variant = 'primary', size = 'md', children, onClick, onDark, disabled, type = 'button', className = '', ...rest }) => {
  const cls = ['btn', `btn-${variant}`, size === 'sm' ? 'btn-sm' : size === 'lg' ? 'btn-lg' : '', onDark ? 'on-dark' : '', className].filter(Boolean).join(' ');
  return <button type={type} className={cls} onClick={onClick} disabled={disabled} data-on-dark={onDark ? '' : undefined} {...rest}>{children}</button>;
};
window.Button = Button;

/* ----------------------------- Field ----------------------------- */
const Field = ({ label, hint, error, optional, icon, valid, children, id, ...rest }) => {
  const fid = id || (label ? 'f-' + label.replace(/\W+/g, '-').toLowerCase() : undefined);
  const groupCls = ['field-group', error ? 'has-error' : '', valid ? 'is-valid' : ''].filter(Boolean).join(' ');
  return (
    <div className={groupCls}>
      {label && <label className="field-label" htmlFor={fid}>{label}{optional && <span className="opt">Optional</span>}</label>}
      {children ? children : (
        icon ? (
          <div className="field-icon">
            <Icon n={icon} size={18} />
            <input id={fid} className="field" {...rest} />
          </div>
        ) : <input id={fid} className="field" {...rest} />
      )}
      {error ? <div className="field-hint"><Icon n="alert" size={14} />{error}</div> : (hint && <div className="field-hint">{hint}</div>)}
    </div>
  );
};
window.Field = Field;

const Badge = ({ kind = 'navy', icon, children }) => (
  <span className={`badge badge-${kind}`}>{icon && <Icon n={icon} size={13} />}{children}</span>
);
window.Badge = Badge;

const Tag = ({ kind, icon, children }) => (
  <span className={'tag' + (kind ? ' tag-' + kind : '')}>{icon && <Icon n={icon} size={15} />}{children}</span>
);
window.Tag = Tag;

/* ----------------------------- Formatters ----------------------------- */
const fmt$ = (n, dp = 2) => '$' + Number(n).toLocaleString('en-AU', { minimumFractionDigits: dp, maximumFractionDigits: dp });
const fmt$0 = (n) => '$' + Math.round(n).toLocaleString('en-AU');
window.fmt$ = fmt$; window.fmt$0 = fmt$0;

/* ----------------------------- Domain data ----------------------------- */
// Distributors by region (NSW + QLD focus)
const DISTRIBUTORS = {
  'Ausgrid': { region: 'NSW', ref: 1828 },
  'Endeavour Energy': { region: 'NSW', ref: 1936 },
  'Essential Energy': { region: 'NSW', ref: 2104 },
  'Energex': { region: 'QLD', ref: 1742 },
  'Ergon Energy': { region: 'QLD', ref: 1889 },
};
window.DISTRIBUTORS = DISTRIBUTORS;

// Plans. Estimates assume ~3,900 kWh/yr typical household.
const PLANS = {
  home: {
    id: 'home', name: 'Renegade Home', code: 'RNG-HOME-FLAT-FY26',
    desc: 'A single flat rate, locked for 12 months. The simplest fair deal for a non-solar home.',
    meterType: 'Any meter', yearly: 1574, refPct: 14,
    tariffs: [
      { name: 'Usage', rateExGst: 26.95, rateIncGst: 29.65, unit: 'c/kWh', tod: 'All day' },
      { name: 'Supply charge', rateExGst: 89.00, rateIncGst: 97.90, unit: 'c/day', tod: 'Daily' },
    ],
    forSolar: false,
  },
  tou: {
    id: 'tou', name: 'Time-of-Use Saver', code: 'RNG-TOU-SMART-FY26',
    desc: 'Reward for shifting load off the evening peak. Needs a smart meter — most homes already have one.',
    meterType: 'Smart meter', yearly: 1438, refPct: 21,
    tariffs: [
      { name: 'Off-peak', rateExGst: 16.80, rateIncGst: 18.48, unit: 'c/kWh', tod: '22:00 – 07:00' },
      { name: 'Shoulder', rateExGst: 22.40, rateIncGst: 24.64, unit: 'c/kWh', tod: '07:00 – 15:00' },
      { name: 'Peak', rateExGst: 44.10, rateIncGst: 48.51, unit: 'c/kWh', tod: '15:00 – 22:00' },
      { name: 'Supply charge', rateExGst: 86.00, rateIncGst: 94.60, unit: 'c/day', tod: 'Daily' },
    ],
    forSolar: false,
  },
  solar: {
    id: 'solar', name: 'Responsible Solar Citizen', code: 'RNG-SOLAR-COSTREFLECT-FY26',
    desc: 'For homes with rooftop solar. Cost-reflective rates and a zero-to-negative midday feed-in — so you stop being subsidised by your neighbours, and stop subsidising the grid at midday.',
    meterType: 'Smart meter', yearly: 1712, refPct: 6,
    tariffs: [
      { name: 'Usage', rateExGst: 27.95, rateIncGst: 30.75, unit: 'c/kWh', tod: 'All day' },
      { name: 'Feed-in (10:00–14:00)', rateExGst: -2.00, rateIncGst: -2.00, unit: 'c/kWh', tod: '10:00 – 14:00' },
      { name: 'Feed-in (other)', rateExGst: 1.50, rateIncGst: 1.50, unit: 'c/kWh', tod: 'Outside midday' },
      { name: 'Supply charge', rateExGst: 92.00, rateIncGst: 101.20, unit: 'c/day', tod: 'Daily' },
    ],
    forSolar: true,
  },
};
window.PLANS = PLANS;

// The signed-in customer's account (post-signup demo state)
const ACCOUNT = {
  name: 'Maya Brennan', first: 'Maya',
  email: 'maya.brennan@example.com',
  account: 'RNG-00482-1175',
  nmi: '4103857291',
  address: '14 Carrington Rd, Marrickville NSW 2204',
  distributor: 'Ausgrid', region: 'NSW',
  planId: 'tou',
  billingCycle: 'Monthly',
  startDate: '4 Feb 2026',
  balance: 0,
  nextDebit: '28 Jun 2026',
};
window.ACCOUNT = ACCOUNT;

/* ----------------------------- Marketing Nav ----------------------------- */
const NAV_ITEMS = [
  { id: 'why', label: 'Why Renegade' },
  { id: 'how', label: 'How it works' },
  { id: 'plans', label: 'Plans & pricing' },
  { id: 'thesis', label: 'The thesis' },
];
const MarketingNav = ({ onNav, mode = 'transparent', onLogin }) => {
  const [open, setOpen] = useState(false);
  const dark = mode !== 'light';
  const cls = mode === 'light' ? 'mnav on-light' : mode === 'solid' ? 'mnav scrolled on-dark-nav' : 'mnav on-dark-nav';
  return (
    <div style={{ display: 'contents' }}>
      <header className={cls}>
        <div className="container">
          <a onClick={() => onNav('home')} style={{ borderBottom: 0, cursor: 'pointer', display: 'flex' }} aria-label="Renegade Energy home">
            <Logo dark={dark} height={28} />
          </a>
          <div className="mnav-spacer" />
          <div className="mnav-cta">
            <a className="desk-cta" onClick={onLogin} style={{ fontSize: 14, fontWeight: 600, cursor: 'pointer', color: dark ? '#fff' : 'var(--fg-1)' }}>Log in</a>
            <Button variant="primary" size="sm" className="desk-cta" onClick={() => onNav('signup')}>Get started</Button>
            <button className="mnav-burger" aria-label="Menu" onClick={() => setOpen(o => !o)} style={{ color: dark ? '#fff' : 'var(--fg-1)' }}>
              <Icon n={open ? 'x' : 'menu'} size={24} />
            </button>
          </div>
        </div>
      </header>
      {open && (
        <div className="msheet">
          <a onClick={() => { setOpen(false); onLogin(); }}>Log in</a>
          <div style={{ marginTop: 16 }}><Button variant="primary" size="lg" className="btn-block" onClick={() => { setOpen(false); onNav('signup'); }}>Get started</Button></div>
        </div>
      )}
    </div>
  );
};
window.MarketingNav = MarketingNav;

/* ----------------------------- Footer ----------------------------- */
const FOOT_COLS = [
  { h: 'Residential', links: ['Plans & pricing', 'How it works', 'Moving home', 'Concession & hardship', 'Refer a friend'] },
  { h: 'Business', links: ['Small business', 'Multi-site', 'Embedded networks', 'Developers'] },
  { h: 'Company', links: ['The thesis', 'About us', 'Careers', 'Media', 'Contact'] },
];
const Footer = ({ onNav }) => (
  <footer className="foot">
    <div className="container">
      <div className="foot-grid">
        <div>
          <Logo dark height={34} />
          <p style={{ fontSize: 14, marginTop: 20, maxWidth: 320, lineHeight: 1.55 }}>
            An Australian electricity retailer for households and small businesses without rooftop solar. We pass the saving back.
          </p>
          <div className="foot-social">
            <a aria-label="Facebook"><Icon n="facebook" size={18} /></a>
            <a aria-label="Instagram"><Icon n="instagram" size={18} /></a>
            <a aria-label="X"><Icon n="twitter" size={18} /></a>
          </div>
        </div>
        {FOOT_COLS.map(col => (
          <div className="foot-col" key={col.h}>
            <h4>{col.h}</h4>
            {col.links.map(l => <a key={l} onClick={() => col.h === 'Residential' && l === 'Plans & pricing' ? onNav('signup') : null}>{l}</a>)}
          </div>
        ))}
      </div>
      <div className="foot-base">
        <span>© 2026 Renegade Energy Pty Ltd · ABN 64 219 447 102 · AER retailer authorisation REN0042.</span>
        <span style={{ display: 'flex', gap: 20 }}>
          <a>Terms</a><a>Privacy</a><a>Basic Plan Information</a><a>Help &amp; support</a>
        </span>
      </div>
    </div>
  </footer>
);
window.Footer = Footer;

Object.assign(window, { useState, useEffect, useRef, Fragment });
