﻿// BillyHub generated split file. Keep script order in Bills Manager.html.
function BudgetTab({ bills, showCents, payPeriod, budget, onBudgetChange, paymentLog, fundingLog, expenses, onLogBillPayment, onUndoBillPayment, onAddExpense, onAddMoney, onEditActivity, onDeleteActivity, onOpenAnalytics }) {
  const [billDrafts, setBillDrafts] = useState({});
  const [expenseDraft, setExpenseDraft] = useState({ category:'Gas', amount:'', note:'' });
  const savingsStart = parseFloat(budget.savingsStart) || 0;
  const savingsContribution = parseFloat(budget.savingsContribution) || 0;
  const savingsYears = Math.max(0, parseFloat(budget.savingsYears) || 0);
  const savingsMonths = Math.max(0, parseFloat(budget.savingsMonths) || 0);
  const savingsApr = Math.max(0, parseFloat(budget.savingsApr) || 0);
  const savingsFrequency = budget.savingsFrequency || 'monthly';
  const savingsPeriods = { weekly: 52, biweekly: 26, monthly: 12, quarterly: 4, annually: 1 };
  const periodsPerYear = savingsPeriods[savingsFrequency] || 12;
  const totalPeriods = Math.round((savingsYears + (savingsMonths / 12)) * periodsPerYear);
  const periodicRate = savingsApr / 100 / periodsPerYear;
  const futureSavings = periodicRate > 0
    ? savingsStart * Math.pow(1 + periodicRate, totalPeriods) + savingsContribution * ((Math.pow(1 + periodicRate, totalPeriods) - 1) / periodicRate)
    : savingsStart + (savingsContribution * totalPeriods);
  const savingsDeposits = savingsContribution * totalPeriods;
  const savingsInterest = Math.max(0, futureSavings - savingsStart - savingsDeposits);
  const period = getCurrentPayPeriod(payPeriod.date1, payPeriod.date2);
  const periodEntries = period ? bills
    .map(b => ({ b, d: getNextDue(b, period.start) }))
    .filter(({ d }) => d && d >= period.start && d <= period.end)
    .sort((a,b) => a.d - b.d) : [];
  const inPeriod = item => {
    if (!period || !item.date) return false;
    const d = parseLocalDate(item.dueDate || item.date);
    if (!d) return false;
    return d >= period.start && d <= period.end;
  };
  const periodLogs = paymentLog.filter(inPeriod);
  const periodFunding = fundingLog.filter(inPeriod);
  const periodExpenses = expenses.filter(inPeriod);
  const baseAccount = parseFloat(budget.amount) || 0;
  const fundingTotal = periodFunding.reduce((sum, item) => sum + (parseFloat(item.amount) || 0), 0);
  const paycheck = baseAccount + fundingTotal;
  const paidTotal = periodLogs.reduce((sum, item) => sum + (parseFloat(item.amount) || 0), 0);
  const expenseTotal = periodExpenses.reduce((sum, item) => sum + (parseFloat(item.amount) || 0), 0);
  const billTotal = periodEntries.reduce((sum, { b }) => sum + (parseFloat(b.amount) || 0), 0);
  const cashLeft = paycheck - paidTotal - expenseTotal;
  const scheduledPaidCount = periodEntries.filter(({ b, d }) => isOccurrencePaid(b, d)).length;
  const scheduledPrepaidCount = periodEntries.filter(({ b, d }) => isOccurrencePrepaid(b, d)).length;
  const scheduledDoneCount = scheduledPaidCount + scheduledPrepaidCount;
  const scheduledProgress = periodEntries.length ? Math.round((scheduledDoneCount / periodEntries.length) * 100) : 0;
  const categoryRows = Object.entries(periodExpenses.reduce((map, item) => {
    const category = item.category || 'Other';
    map[category] = (map[category] || 0) + (parseFloat(item.amount) || 0);
    return map;
  }, {})).sort((a,b) => b[1] - a[1]);
  const topCategoryTotal = Math.max(...categoryRows.map(([, total]) => total), 1);
  const paycheckLogEntries = Object.values(budget.paycheckLog || {});
  const monthTrend = Array.from({ length: 6 }, (_, index) => {
    const monthDate = new Date(new Date().getFullYear(), new Date().getMonth() - 5 + index, 1);
    const sameMonth = value => {
      const date = parseLocalDate(value);
      return date && date.getFullYear() === monthDate.getFullYear() && date.getMonth() === monthDate.getMonth();
    };
    const billsPaid = paymentLog
      .filter(item => sameMonth(item.date || item.dueDate))
      .reduce((sum, item) => sum + (parseFloat(item.amount) || 0), 0);
    const spent = expenses
      .filter(item => sameMonth(item.date))
      .reduce((sum, item) => sum + (parseFloat(item.amount) || 0), 0);
    const added = fundingLog
      .filter(item => sameMonth(item.date))
      .reduce((sum, item) => sum + (parseFloat(item.amount) || 0), 0);
    const paychecks = paycheckLogEntries
      .filter(item => sameMonth(item.startDate || item.loggedAt))
      .reduce((sum, item) => sum + (parseFloat(item.actualAmount || item.defaultAmount) || 0), 0);
    return {
      key: `${monthDate.getFullYear()}-${monthDate.getMonth()}`,
      label: monthDate.toLocaleDateString('en-US', { month:'short' }),
      billsPaid,
      spent,
      inflow: added + paychecks,
      outflow: billsPaid + spent,
    };
  });
  const trendMax = Math.max(...monthTrend.map(item => Math.max(item.inflow, item.outflow)), 1);
  const activity = [
    ...periodLogs.map(item => ({ ...item, activityType:'payment', kind:'Bill paid', title:item.billName })),
    ...periodFunding.map(item => ({ ...item, activityType:'funding', kind:'Money added', title:item.note || 'Money added' })),
    ...periodExpenses.map(item => ({ ...item, activityType:'expense', kind:item.category, title:item.note || 'Expense' })),
  ].sort((a,b) => (b.createdAt || '').localeCompare(a.createdAt || '')).slice(0, 8);
  const billAmount = (bill, dueDate) => billDrafts[`${bill.id}-${occurrenceKey(dueDate)}`] ?? String(bill.amount || '');
  const setBillAmount = (bill, dueDate, amount) => setBillDrafts(drafts => ({ ...drafts, [`${bill.id}-${occurrenceKey(dueDate)}`]: amount }));
  const saveExpense = () => {
    const amount = parseFloat(expenseDraft.amount) || 0;
    if (!amount) return;
    onAddExpense({
      id: uid(),
      date: todayISO(),
      createdAt: new Date().toISOString(),
      category: expenseDraft.category,
      note: expenseDraft.note.trim(),
      amount,
    });
    setExpenseDraft({ category:'Gas', amount:'', note:'' });
  };

  return (
    <div className="budget-workspace">
      <div className="budget-planner-grid">
        <div className="budget-module-shell">
          <div className="section-heading-row analytics-module-heading">
            <div>
              <p className="section-kicker" style={{ margin:'0 0 4px', color:'var(--muted)' }}>Budget</p>
              <h3 style={{ margin:0, fontFamily:'"Space Grotesk",sans-serif', fontSize:'1.2rem' }}>Account planner</h3>
            </div>
            <button type="button" className="ghost-button budget-analytics-button" onClick={onOpenAnalytics}>Analytics</button>
          </div>
        <div className="card budget-hero-card">
          <p style={{ margin:'0 0 18px', color:'var(--muted)', maxWidth:'68ch' }}>Add what is currently in your bank account, then log bill payments and quick expenses.</p>
          <div className="budget-heading-row">
            <label className="field budget-paycheck-field">
              <span>Bank account balance ($)</span>
              <input type="number" min="0" step="0.01" value={budget.amount || ''} onChange={e => onBudgetChange('amount', e.target.value)} />
            </label>
          </div>
          <div className="budget-stat-grid">
            <div className="budget-stat"><span>Bank balance</span><strong>{paycheck ? fmt(paycheck,showCents) : '-'}</strong></div>
            <div className="budget-stat"><span>Bills logged</span><strong>{fmt(paidTotal,showCents)}</strong><small>{periodLogs.length} payment{periodLogs.length!==1?'s':''}</small></div>
            <div className="budget-stat"><span>Expenses</span><strong>{fmt(expenseTotal,showCents)}</strong><small>{periodExpenses.length} expense{periodExpenses.length!==1?'s':''}{periodFunding.length ? ` · ${periodFunding.length} money add${periodFunding.length!==1?'s':''}` : ''}</small></div>
            <div className={`budget-stat${cashLeft < 0 ? ' is-negative' : ''}`}><span>Account left</span><strong>{paycheck ? fmt(cashLeft,showCents) : '-'}</strong></div>
          </div>
        </div>
        </div>

        <div className="card savings-calculator-card">
          <div>
              <p className="section-kicker" style={{ margin:'0 0 4px', color:'var(--muted)' }}>Savings</p>
              <h3 style={{ margin:0, fontFamily:'"Space Grotesk",sans-serif', fontSize:'1.2rem' }}>Savings Calculator</h3>
          </div>
          <div className="savings-calculator-grid">
            <label className="field">
              <span>Starting savings ($)</span>
              <input type="number" min="0" step="0.01" value={budget.savingsStart || ''} onChange={e => onBudgetChange('savingsStart', e.target.value)} />
            </label>
            <label className="field">
              <span>Add amount ($)</span>
              <input type="number" min="0" step="0.01" value={budget.savingsContribution || ''} onChange={e => onBudgetChange('savingsContribution', e.target.value)} />
            </label>
            <label className="field">
              <span>Add frequency</span>
              <select value={savingsFrequency} onChange={e => onBudgetChange('savingsFrequency', e.target.value)}>
                <option value="weekly">Weekly</option>
                <option value="biweekly">Bi-weekly</option>
                <option value="monthly">Monthly</option>
                <option value="quarterly">Quarterly</option>
                <option value="annually">Annually</option>
              </select>
            </label>
            <div className="savings-duration-fields">
              <label className="field">
                <span>Years</span>
                <input type="number" min="0" step="1" value={budget.savingsYears || ''} onChange={e => onBudgetChange('savingsYears', e.target.value)} />
              </label>
              <label className="field">
                <span>Months</span>
                <input type="number" min="0" max="11" step="1" value={budget.savingsMonths || ''} onChange={e => onBudgetChange('savingsMonths', e.target.value)} />
              </label>
            </div>
            <label className="field">
              <span>Interest rate (%)</span>
              <input type="number" min="0" step="0.01" value={budget.savingsApr || ''} onChange={e => onBudgetChange('savingsApr', e.target.value)} />
            </label>
          </div>
          <div className="savings-result-grid">
            <div className="budget-stat"><span>Total saved</span><strong>{fmt(futureSavings, showCents)}</strong></div>
            <div className="budget-stat"><span>Your deposits</span><strong>{fmt(savingsStart + savingsDeposits, showCents)}</strong></div>
            <div className="budget-stat"><span>Interest earned</span><strong>{fmt(savingsInterest, showCents)}</strong></div>
          </div>
        </div>
      </div>

      <div className="budget-grid">
        <div className="card budget-bills-card">
          <div className="section-heading-row">
            <div>
              <p className="section-kicker" style={{ margin:'0 0 4px', color:'var(--muted)' }}>{period ? `${shortDate(period.start)} - ${shortDate(period.end)}` : 'Pay period'}</p>
              <h3 style={{ margin:0, fontFamily:'"Space Grotesk",sans-serif', fontSize:'1.2rem' }}>Bills to pay</h3>
            </div>
            {period && <strong>{fmt(billTotal,showCents)} scheduled</strong>}
          </div>
          <div className="budget-bill-list">
            {!period && <div className="empty-state">Set your pay dates on the Dashboard to start this list.</div>}
            {period && periodEntries.length === 0 && <div className="empty-state">No bills found for this pay period.</div>}
            {periodEntries.map(({ b, d }) => {
              const paid = isOccurrencePaid(b, d);
              return (
                <div className={`budget-bill-row${paid ? ' is-paid' : ''}`} key={`${b.id}-${occurrenceKey(d)}`}>
                  <div>
                    <strong>{b.name}</strong>
                    <span>{shortDate(d)} {paid ? 'paid' : 'due'} - {fmt(b.amount,showCents)}</span>
                  </div>
                  <input type="number" min="0" step="0.01" value={billAmount(b, d)} onChange={e => setBillAmount(b, d, e.target.value)} aria-label={`${b.name} amount paid`} />
                  <button
                    type="button"
                    className={`paid-toggle${paid ? ' is-paid' : ''}`}
                    onClick={() => paid ? onUndoBillPayment(b, d) : onLogBillPayment(b, d, parseFloat(billAmount(b, d)) || 0)}
                  >
                    {paid ? 'Undo Log' : 'Log Paid'}
                  </button>
                </div>
              );
            })}
          </div>
        </div>

        <div className="card budget-expense-card">
          <p className="section-kicker" style={{ margin:'0 0 4px', color:'var(--muted)' }}>Expenses</p>
          <h3 style={{ margin:'0 0 14px', fontFamily:'"Space Grotesk",sans-serif', fontSize:'1.2rem' }}>Quick add</h3>
          <div className="budget-expense-form">
            <label className="field">
              <span>Category</span>
              <select value={expenseDraft.category} onChange={e => setExpenseDraft(x => ({ ...x, category:e.target.value }))}>
                {['Gas','Groceries','Food','Entertainment','Household','Other'].map(x => <option key={x}>{x}</option>)}
              </select>
            </label>
            <label className="field">
              <span>Amount ($)</span>
              <input type="number" min="0" step="0.01" value={expenseDraft.amount} onChange={e => setExpenseDraft(x => ({ ...x, amount:e.target.value }))} />
            </label>
            <label className="field full">
              <span>Note</span>
              <input type="text" placeholder="Optional" value={expenseDraft.note} onChange={e => setExpenseDraft(x => ({ ...x, note:e.target.value }))} />
            </label>
            <div className="budget-expense-actions">
              <button type="button" className="ghost-button budget-money-button" onClick={onAddMoney}>+ Add Money</button>
              <button type="button" className="primary-button" onClick={saveExpense}>Quick Add Expense</button>
            </div>
          </div>
        </div>

        <div className="card budget-log-card">
          <p className="section-kicker" style={{ margin:'0 0 4px', color:'var(--muted)' }}>Log</p>
          <h3 style={{ margin:'0 0 14px', fontFamily:'"Space Grotesk",sans-serif', fontSize:'1.2rem' }}>Recent activity</h3>
          <div className="budget-activity-list">
            {activity.length === 0 && <div className="empty-state">Payments and expenses you add will show up here.</div>}
            {activity.map(item => (
              <div className="budget-activity-item" key={item.id}>
                <div><strong>{item.title}</strong><span>{item.kind} - {shortDate(parseLocalDate(item.date))}</span></div>
                <div className="budget-activity-actions">
                  <strong className={item.activityType === 'funding' ? 'money-positive' : 'money-negative'}>{fmt(item.amount,showCents)}</strong>
                  <div className="mini-action-group">
                    <button type="button" className="ghost-button mini-action mini-action-edit" onClick={() => onEditActivity(item)}>Edit</button>
                  </div>
                </div>
              </div>
            ))}
          </div>
        </div>
      </div>

    </div>
  );
}

function BudgetAnalyticsTab({ bills, showCents, payPeriod, budget, paymentLog, fundingLog, expenses, onBack }) {
  const period = getCurrentPayPeriod(payPeriod.date1, payPeriod.date2);
  const periodEntries = period ? bills
    .map(b => ({ b, d: getNextDue(b, period.start) }))
    .filter(({ d }) => d && d >= period.start && d <= period.end)
    .sort((a,b) => a.d - b.d) : [];
  const inPeriod = item => {
    if (!period || !item.date) return false;
    const d = parseLocalDate(item.dueDate || item.date);
    if (!d) return false;
    return d >= period.start && d <= period.end;
  };
  const periodLogs = paymentLog.filter(inPeriod);
  const periodFunding = fundingLog.filter(inPeriod);
  const periodExpenses = expenses.filter(inPeriod);
  const baseAccount = parseFloat(budget.amount) || 0;
  const fundingTotal = periodFunding.reduce((sum, item) => sum + (parseFloat(item.amount) || 0), 0);
  const paycheck = baseAccount + fundingTotal;
  const paidTotal = periodLogs.reduce((sum, item) => sum + (parseFloat(item.amount) || 0), 0);
  const expenseTotal = periodExpenses.reduce((sum, item) => sum + (parseFloat(item.amount) || 0), 0);
  const billTotal = periodEntries.reduce((sum, { b }) => sum + (parseFloat(b.amount) || 0), 0);
  const cashLeft = paycheck - paidTotal - expenseTotal;
  const scheduledPaidCount = periodEntries.filter(({ b, d }) => isOccurrencePaid(b, d)).length;
  const scheduledPrepaidCount = periodEntries.filter(({ b, d }) => isOccurrencePrepaid(b, d)).length;
  const scheduledDoneCount = scheduledPaidCount + scheduledPrepaidCount;
  const scheduledProgress = periodEntries.length ? Math.round((scheduledDoneCount / periodEntries.length) * 100) : 0;
  const categoryRows = Object.entries(periodExpenses.reduce((map, item) => {
    const category = item.category || 'Other';
    map[category] = (map[category] || 0) + (parseFloat(item.amount) || 0);
    return map;
  }, {})).sort((a,b) => b[1] - a[1]);
  const topCategoryTotal = Math.max(...categoryRows.map(([, total]) => total), 1);
  const paycheckLogEntries = Object.values(budget.paycheckLog || {});
  const monthTrend = Array.from({ length: 6 }, (_, index) => {
    const monthDate = new Date(new Date().getFullYear(), new Date().getMonth() - 5 + index, 1);
    const sameMonth = value => {
      const date = parseLocalDate(value);
      return date && date.getFullYear() === monthDate.getFullYear() && date.getMonth() === monthDate.getMonth();
    };
    const billsPaid = paymentLog
      .filter(item => sameMonth(item.date || item.dueDate))
      .reduce((sum, item) => sum + (parseFloat(item.amount) || 0), 0);
    const spent = expenses
      .filter(item => sameMonth(item.date))
      .reduce((sum, item) => sum + (parseFloat(item.amount) || 0), 0);
    const added = fundingLog
      .filter(item => sameMonth(item.date))
      .reduce((sum, item) => sum + (parseFloat(item.amount) || 0), 0);
    const paychecks = paycheckLogEntries
      .filter(item => sameMonth(item.startDate || item.loggedAt))
      .reduce((sum, item) => sum + (parseFloat(item.actualAmount || item.defaultAmount) || 0), 0);
    return {
      key: `${monthDate.getFullYear()}-${monthDate.getMonth()}`,
      label: monthDate.toLocaleDateString('en-US', { month:'short' }),
      billsPaid,
      spent,
      inflow: added + paychecks,
      outflow: billsPaid + spent,
    };
  });
  const trendMax = Math.max(...monthTrend.map(item => Math.max(item.inflow, item.outflow)), 1);

  return (
    <div className="settings-page analytics-page">
      <div className="section-heading-row analytics-page-heading">
        <div>
          <p className="section-kicker" style={{ margin:'0 0 4px', color:'var(--muted)' }}>Budget</p>
          <h3 style={{ margin:0, fontFamily:'"Space Grotesk",sans-serif', fontSize:'1.35rem' }}>Budget analytics</h3>
        </div>
        <button type="button" className="ghost-button" onClick={onBack}>Back to Budget</button>
      </div>
      <div className="card budget-analytics-card budget-analytics-page-card">
        <div className="section-heading-row">
          <div>
            <p className="section-kicker" style={{ margin:'0 0 4px', color:'var(--muted)' }}>Analytics</p>
            <h3 style={{ margin:0, fontFamily:'"Space Grotesk",sans-serif', fontSize:'1.2rem' }}>Budget health</h3>
          </div>
          <span className={`analytics-saved-pill${cashLeft < 0 ? ' is-negative' : ''}`}>
            {period ? `${cashLeft >= 0 ? 'Saved' : 'Over'} ${fmt(Math.abs(cashLeft), showCents)}` : 'Set a pay period'}
          </span>
        </div>
        <div className="analytics-grid">
          <section className="analytics-panel">
            <div className="analytics-panel-heading">
              <span>Spending by category</span>
              <strong>{fmt(expenseTotal, showCents)}</strong>
            </div>
            <div className="category-analytics-list">
              {categoryRows.length === 0 && <div className="empty-state">Log expenses to see category trends.</div>}
              {categoryRows.map(([category, total]) => (
                <div className="category-analytics-row" key={category}>
                  <div>
                    <span>{category}</span>
                    <strong>{fmt(total, showCents)}</strong>
                  </div>
                  <div className="analytics-bar"><span style={{ width:`${Math.max(4, Math.round((total / topCategoryTotal) * 100))}%` }} /></div>
                </div>
              ))}
            </div>
          </section>
          <section className="analytics-panel">
            <div className="analytics-panel-heading">
              <span>Bills paid vs scheduled</span>
              <strong>{scheduledProgress}%</strong>
            </div>
            <div className="bill-progress-ring" style={{ '--progress': `${scheduledProgress}%` }}>
              <strong>{scheduledDoneCount}/{periodEntries.length}</strong>
              <span>done</span>
            </div>
            <div className="analytics-mini-grid">
              <div><span>Scheduled</span><strong>{fmt(billTotal, showCents)}</strong></div>
              <div><span>Logged</span><strong>{fmt(paidTotal, showCents)}</strong></div>
              <div><span>Pre-paid</span><strong>{scheduledPrepaidCount}</strong></div>
            </div>
          </section>
          <section className="analytics-panel analytics-trend-panel">
            <div className="analytics-panel-heading">
              <span>Monthly trends</span>
              <strong>6 months</strong>
            </div>
            <div className="monthly-trend-chart">
              {monthTrend.map(item => (
                <div className="monthly-trend-column" key={item.key}>
                  <div className="monthly-trend-bars">
                    <span className="is-inflow" style={{ height:`${Math.max(4, Math.round((item.inflow / trendMax) * 100))}%` }} title={`Inflow ${fmt(item.inflow, showCents)}`} />
                    <span className="is-outflow" style={{ height:`${Math.max(4, Math.round((item.outflow / trendMax) * 100))}%` }} title={`Outflow ${fmt(item.outflow, showCents)}`} />
                  </div>
                  <strong>{item.label}</strong>
                  <small className={item.inflow - item.outflow < 0 ? 'money-negative' : 'money-positive'}>
                    {fmt(item.inflow - item.outflow, false)}
                  </small>
                </div>
              ))}
            </div>
            <div className="trend-legend"><span className="is-inflow">Money in</span><span className="is-outflow">Bills + expenses</span></div>
          </section>
        </div>
      </div>
    </div>
  );
}

// â”€â”€ Dashboard Tab â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€
function SettingsTab({ theme, themeName, themes, onToggle, onThemeSelect, onExportData, onImportClick, tweaks, onTweakChange, payday, onPaydayChange }) {
  const payPeriod = getAutomaticPayPeriod(payday);
  const currentPayFrequency = PAY_FREQUENCIES.some(option => option.value === payday.frequency) ? payday.frequency : 'biweekly';
  return (
    <div className="settings-page">
      <div className="card settings-page-card">
        <div className="section-heading-row">
          <div>
            <p className="section-kicker" style={{ margin:'0 0 4px', color:'var(--muted)' }}>Settings</p>
            <h3 style={{ margin:0, fontFamily:'"Space Grotesk",sans-serif', fontSize:'1.35rem' }}>BillyHub controls</h3>
          </div>
        </div>
        <div className="settings-section-grid">
          <section className="settings-block">
            <span className="settings-subtitle">Backup</span>
            <div className="settings-action-row">
              <button type="button" className="primary-button" onClick={onExportData}>Export backup</button>
              <button type="button" className="ghost-button" onClick={onImportClick}>Import backup</button>
            </div>
          </section>
          <section className="settings-block">
            <span className="settings-subtitle">Mode</span>
            <div className="settings-option-grid settings-mode-grid">
              <button type="button" className={`settings-chip${theme === 'light' ? ' is-active' : ''}`} onClick={() => theme !== 'light' && onToggle()}>Light</button>
              <button type="button" className={`settings-chip${theme === 'dark' ? ' is-active' : ''}`} onClick={() => theme !== 'dark' && onToggle()}>Dark</button>
            </div>
          </section>
          <section className="settings-block settings-pay-block full">
            <span className="settings-subtitle">Pay Setup</span>
            <label className="toggle settings-toggle">
              <input type="checkbox" checked={!!payday.autoEnabled} onChange={e => onPaydayChange('autoEnabled', e.target.checked)} />
              <span className="toggle-track"></span>
              <span className="toggle-label">Automatically calculate pay periods</span>
            </label>
            <div className="settings-pay-grid">
              <label className="field">
                <span>Pay frequency</span>
                <select value={currentPayFrequency} onChange={e => onPaydayChange('frequency', e.target.value)}>
                  {PAY_FREQUENCIES.map(option => <option key={option.value} value={option.value}>{option.label}</option>)}
                </select>
              </label>
              <label className="field">
                <span>{payday.frequency === 'semimonthly' ? 'First pay date' : 'Known payday'}</span>
                <input type="date" value={payday.firstDate || ''} onChange={e => onPaydayChange('firstDate', e.target.value)} />
              </label>
              {payday.frequency === 'semimonthly' && (
                <label className="field">
                  <span>Second pay date</span>
                  <input type="date" value={payday.secondDate || ''} onChange={e => onPaydayChange('secondDate', e.target.value)} />
                </label>
              )}
              <label className="field">
                <span>Minimum Paycheck ($)</span>
                <input type="number" min="0" step="0.01" value={payday.paycheckAmount || ''} onChange={e => onPaydayChange('paycheckAmount', e.target.value)} />
              </label>
            </div>
            <div className="settings-pay-summary">
              <span>{payday.firstDate ? payFrequencyLabel(payday.frequency || 'biweekly') : 'Add a payday to start'}</span>
              <strong>{payPeriod ? `${shortDate(payPeriod.start)} - ${shortDate(payPeriod.end)}` : 'No active period yet'}</strong>
            </div>
          </section>
          <section className="settings-block settings-theme-block full">
            <span className="settings-subtitle">Theme</span>
            <div className="settings-option-grid settings-theme-grid settings-page-theme-grid">
              {themes.map(option => (
                <button key={option.id} type="button" className={`settings-chip${themeName === option.id ? ' is-active' : ''}`} onClick={() => onThemeSelect(option.id)}>
                  {option.label}
                </button>
              ))}
            </div>
          </section>
          <section className="settings-block full">
            <span className="settings-subtitle">Display</span>
            <label className="toggle settings-toggle">
              <input type="checkbox" checked={!!tweaks.showCents} onChange={e => onTweakChange('showCents', e.target.checked)} />
              <span className="toggle-track"></span>
              <span className="toggle-label">Show cents in totals</span>
            </label>
            <label className="toggle settings-toggle">
              <input type="checkbox" checked={!!tweaks.sampleData} onChange={e => onTweakChange('sampleData', e.target.checked)} />
              <span className="toggle-track"></span>
              <span className="toggle-label">Use sample data when empty</span>
            </label>
          </section>
        </div>
      </div>
    </div>
  );
}

function DashboardTab({ bills, showCents, payPeriod, onPayPeriodChange, budget, onBudgetChange, payday, paymentLog, onMarkBillPaid, onToggleBillPrepaid }) {
  const now = startOfLocalDay(new Date());
  const [payPeriodView, setPayPeriodView] = useState('');
  const payPeriodOptions = payday?.autoEnabled ? getPayPeriodOptions(payday, now, 1, 8) : [];
  const currentPayPeriodOption = payPeriodOptions.find(option => option.isCurrent) || payPeriodOptions[0];
  const selectedPayPeriodOption = payPeriodOptions.find(option => option.key === payPeriodView) || currentPayPeriodOption;
  const selectedPayPeriodKey = selectedPayPeriodOption?.key || '';
  const paycheckOverrides = budget.paycheckOverrides || {};
  const paycheckLog = budget.paycheckLog || {};
  const actualCheckValue = selectedPayPeriodKey ? (paycheckOverrides[selectedPayPeriodKey] || '') : '';
  const defaultCheckAmount = parseFloat(payday?.paycheckAmount || budget.amount) || 0;
  const activePayPeriod = payPeriod.source === 'auto' && selectedPayPeriodOption
    ? { date1: toLocalISO(selectedPayPeriodOption.start), date2: toLocalISO(selectedPayPeriodOption.end), source: 'auto' }
    : payPeriod;
  const period = getCurrentPayPeriod(activePayPeriod.date1, activePayPeriod.date2);
  const periodEntries = period ? bills
    .map(b => ({ b, d: getNextDue(b, period.start) }))
    .filter(({ d }) => d && d >= period.start && d <= period.end)
    .sort((a,b) => a.d - b.d) : [];
  const paymentAmountFor = (bill, dueDate) => {
    const key = occurrenceKey(dueDate);
    const log = (paymentLog || []).find(item => item.billId === bill.id && item.dueDate === key);
    const value = log ? parseFloat(log.amount) : parseFloat(bill.amount);
    return Number.isFinite(value) ? value : 0;
  };
  const isSettled = (bill, dueDate) => isOccurrencePaid(bill, dueDate) || isOccurrencePrepaid(bill, dueDate);
  const unpaidPeriodEntries = periodEntries.filter(({ b, d }) => !isSettled(b, d));
  const originalPeriodTotal = periodEntries.reduce((s, { b }) => s + (parseFloat(b.amount) || 0), 0);
  const paidPeriodTotal = periodEntries
    .filter(({ b, d }) => isSettled(b, d))
    .reduce((s, { b, d }) => s + (isOccurrencePaid(b, d) ? paymentAmountFor(b, d) : (parseFloat(b.amount) || 0)), 0);
  const prepaidPeriodTotal = periodEntries
    .filter(({ b, d }) => isOccurrencePrepaid(b, d))
    .reduce((s, { b }) => s + (parseFloat(b.amount) || 0), 0);
  const periodTotal = Math.max(0, originalPeriodTotal - paidPeriodTotal);
  const paycheckAmt = actualCheckValue !== '' && Number.isFinite(parseFloat(actualCheckValue))
    ? parseFloat(actualCheckValue)
    : defaultCheckAmount;
  const paycheckInputValue = actualCheckValue !== ''
    ? actualCheckValue
    : (defaultCheckAmount ? String(defaultCheckAmount) : '');
  const remaining = paycheckAmt - Math.max(0, originalPeriodTotal - prepaidPeriodTotal);

  const thisMonthEntries = bills
    .map(b => ({ b, d: getNextDue(b, now) }))
    .filter(({ d }) => d && d >= now && d.getFullYear()===now.getFullYear() && d.getMonth()===now.getMonth())
    .sort((a,b) => a.d - b.d);
  const unpaidMonthEntries = thisMonthEntries.filter(({ b, d }) => !isSettled(b, d));
  const monthTotal = unpaidMonthEntries.reduce((s, { b }) => s + (parseFloat(b.amount) || 0), 0);
  const nextPayment = unpaidPeriodEntries[0] || null;
  const nextPaymentGroup = nextPayment
    ? unpaidPeriodEntries.filter(({ d }) => occurrenceKey(d) === occurrenceKey(nextPayment.d))
    : [];
  const nextPaymentTotal = nextPaymentGroup.reduce((sum, { b }) => sum + (parseFloat(b.amount) || 0), 0);
  const nextPaymentDetail = nextPaymentGroup.length > 1
    ? `${nextPaymentGroup.map(({ b }) => b.name).join(' + ')} - ${shortDate(nextPayment.d)}`
    : nextPayment ? `${nextPayment.b.name} - ${shortDate(nextPayment.d)}` : 'No upcoming payments';

  const daysLabel = d => {
    const diff = Math.ceil((d-now)/86400000);
    if (diff < 0) return 'Overdue';
    if (diff === 0) return 'Today';
    if (diff === 1) return 'Tomorrow';
    return `In ${diff}d`;
  };
  const updateActualCheck = value => {
    if (!selectedPayPeriodKey) return;
    onBudgetChange('paycheckOverrides', { ...paycheckOverrides, [selectedPayPeriodKey]: value });
    onBudgetChange('paycheckLog', {
      ...paycheckLog,
      [selectedPayPeriodKey]: {
        periodKey: selectedPayPeriodKey,
        startDate: selectedPayPeriodOption ? toLocalISO(selectedPayPeriodOption.start) : '',
        endDate: selectedPayPeriodOption ? toLocalISO(selectedPayPeriodOption.end) : '',
        defaultAmount: defaultCheckAmount,
        actualAmount: value,
        loggedAt: new Date().toISOString(),
      },
    });
  };

  return (
    <div className="layout overview-layout">
      <div className="look-ahead-card" style={{ display:'grid', gap:22 }}>

        {/* Month summary */}
        <div className="card">
          <h3 style={{ margin:0, fontFamily:'"Space Grotesk",sans-serif', fontSize:'1.2rem' }}>Summary</h3>
          <div className="summary-grid">
            <div className="summary-card due"><span>Due Rest of Month</span><strong>{fmt(monthTotal,showCents)}</strong></div>
            <div className="summary-card remaining">
              <span>Next Payment</span>
              <strong>{nextPaymentGroup.length ? fmt(nextPaymentTotal,showCents) : 'None'}</strong>
              <div className="summary-detail">
                {nextPaymentDetail}
              </div>
            </div>
            <div className="summary-card count"><span>Bills Left - this month</span><strong>{unpaidMonthEntries.length}</strong></div>
          </div>
        </div>

        {/* Pay Period Tracker */}
        <div className="card">
          <p className="section-kicker" style={{ margin:'0 0 4px', color:'var(--muted)' }}>Pay Period Tracker</p>
          <h3 style={{ margin:'0 0 16px', fontFamily:'"Space Grotesk",sans-serif', fontSize:'1.2rem' }}>Budget vs. Bills</h3>
          {activePayPeriod.source === 'auto' ? (
            <div className="pay-setup-summary-card">
              <label className="pay-period-view-field">
                <span>View period</span>
                <select value={selectedPayPeriodOption?.key || ''} onChange={e => setPayPeriodView(e.target.value)}>
                  {payPeriodOptions.map(option => (
                    <option key={option.key} value={option.key}>
                      {option.isCurrent ? 'Current: ' : ''}{shortDate(option.start)} - {shortDate(option.end)}
                    </option>
                  ))}
                </select>
              </label>
              <label className="pay-period-view-field paycheck-amount-field">
                <span>Paycheck Amount</span>
                <input type="number" min="0" step="0.01" placeholder="0.00" value={paycheckInputValue} onChange={e => updateActualCheck(e.target.value)} />
                <small>
                  {period ? `${shortDate(period.start)} - ${shortDate(period.end)}. ` : ''}
                  {defaultCheckAmount ? `Defaults to ${fmt(defaultCheckAmount, showCents)} from Settings.` : ''}
                  {' '}Saved to paycheck history when edited.
                </small>
              </label>
            </div>
          ) : (
            <div className="modal-grid" style={{ gap:12 }}>
              <div className="field">
                <span>First Pay Date</span>
                <input type="date" value={payPeriod.date1 || ''} onChange={e => onPayPeriodChange('date1', e.target.value)} />
              </div>
              <div className="field">
                <span>Second Pay Date</span>
                <input type="date" value={payPeriod.date2 || ''} onChange={e => onPayPeriodChange('date2', e.target.value)} />
              </div>
              <div className="field full">
                <span>Paycheck Amount ($)</span>
                <input type="number" step="0.01" min="0" placeholder="e.g. 2500.00"
                  value={budget.amount} onChange={e => onBudgetChange('amount', e.target.value)} className="money-input" />
              </div>
            </div>
          )}
          {period ? (
            <div className="pay-period-clean">
              <div className="pay-period-clean-header">
                <span>Period: {shortDate(period.start)} - {shortDate(period.end)}</span>
                <strong>{unpaidPeriodEntries.length} bill{unpaidPeriodEntries.length!==1?'s':''} still due</strong>
              </div>
              <div className="pay-period-clean-grid">
                <div className="pay-period-clean-card">
                  <p>Pay-period due</p>
                  <strong>{fmt(originalPeriodTotal,showCents)}</strong>
                  <span>{periodEntries.length} bill{periodEntries.length!==1?'s':''} scheduled</span>
                </div>
                <div className="pay-period-clean-card is-paid">
                  <p>Paid so far</p>
                  <strong>{fmt(paidPeriodTotal,showCents)}</strong>
                  <span>{periodEntries.length - unpaidPeriodEntries.length} marked paid or pre-paid</span>
                </div>
                <div className={`pay-period-clean-card is-still-due${periodTotal <= 0 ? ' is-clear' : ''}`}>
                  <p>Still due</p>
                  <strong>{fmt(periodTotal,showCents)}</strong>
                  <span>{periodTotal > 0 ? 'Updates when bills are paid or pre-paid' : 'All caught up'}</span>
                </div>
              </div>
              <div className={`pay-period-clean-footer${remaining < 0 ? ' is-negative' : ''}`}>
                <span>Account left after pre-paid bills</span>
                <strong>{paycheckAmt > 0 ? fmt(remaining,showCents) : '-'}</strong>
              </div>
            </div>
          ) : (
            <p style={{ margin:'14px 0 0', color:'var(--muted)', fontSize:'0.9rem' }}>Enter pay dates above to see your pay period budget.</p>
          )}
        </div>
      </div>

      {/* Pay period upcoming bills (Brandon) */}
      <div className="due-card">
        <div className="card">
          <p className="section-kicker" style={{ margin:'0 0 4px', color:'var(--muted)' }}>
            {period ? `${shortDate(period.start)} - ${shortDate(period.end)}` : 'Pay Period'}
          </p>
          <div style={{ display:'flex', justifyContent:'space-between', alignItems:'center', gap:12 }}>
            <h3 style={{ margin:0, fontFamily:'"Space Grotesk",sans-serif', fontSize:'1.2rem' }}>Upcoming Bills</h3>
            {period && <span className="count-pill">{unpaidPeriodEntries.length} bill{unpaidPeriodEntries.length!==1?'s':''} due</span>}
          </div>
          <div className="due-list">
            {!period && <div className="empty-state">Set your pay dates in the tracker to see bills here.</div>}
            {period && periodEntries.length === 0 && <div className="empty-state">No bills due this pay period.</div>}
            {periodEntries.map(({ b, d }) => {
              const paid = isOccurrencePaid(b, d);
              const prepaid = isOccurrencePrepaid(b, d);
              const settled = paid || prepaid;
              return (
                <div key={`${b.id}-${occurrenceKey(d)}`} className={`due-item${settled ? ' is-paid' : ''}${prepaid ? ' is-prepaid' : ''}`}>
                  <div>
                    <h3>
                      {b.name}
                      {b.autoPay && <span className="auto-pill">Auto</span>}
                      {paid && <span className="paid-pill">Paid</span>}
                      {prepaid && <span className="paid-pill prepaid-pill">Pre-paid</span>}
                      <span className="freq-pill">{freqLabel(b.frequency)}</span>
                    </h3>
                    <p style={{ margin:'4px 0 0', fontSize:'0.86rem', color:'var(--muted)' }}>
                      {paid ? `Paid for ${shortDate(d)}` : prepaid ? `Pre-paid for ${shortDate(d)}` : daysLabel(d)}
                    </p>
                  </div>
                  <div className="due-item-actions">
                    <strong className={`expense-amount${settled ? ' is-paid' : ''}`}>{fmt(b.amount,showCents)}</strong>
                    <div className="due-button-stack">
                      <button type="button" className={`paid-toggle${paid ? ' is-paid' : ''}`} onMouseDown={e => e.stopPropagation()} onClick={e => { e.stopPropagation(); onMarkBillPaid(b, d); }}>
                        {paid ? 'Unmark' : 'Mark Paid'}
                      </button>
                      <button type="button" className={`paid-toggle prepaid-toggle${prepaid ? ' is-paid' : ''}`} onMouseDown={e => e.stopPropagation()} onClick={e => { e.stopPropagation(); onToggleBillPrepaid(b, d); }}>
                        {prepaid ? 'Undo Pre-Paid' : 'Pre-Paid'}
                      </button>
                    </div>
                  </div>
                </div>
              );
            })}
          </div>
        </div>
      </div>
    </div>
  );
}

// â”€â”€ Bills Tab â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€
function BillsTab({ bills, onEdit, onDelete, showCents }) {
  const now = new Date();
  const [search, setSearch] = useState('');
  const filtered = bills.filter(b => b.name.toLowerCase().includes(search.toLowerCase()));

  return (
    <div className="card">
      <div className="section-heading-row">
        <div>
          <p className="section-kicker" style={{ margin:'0 0 4px', color:'var(--muted)' }}>All Bills</p>
          <h3 style={{ margin:0, fontFamily:'"Space Grotesk",sans-serif', fontSize:'1.2rem' }}>{bills.length} bill{bills.length!==1?'s':''} tracked</h3>
        </div>
        <div className="action-button-row">
          <input className="search-input" type="text" placeholder="Search..." value={search} onChange={e=>setSearch(e.target.value)} />
          <button className="primary-button" onClick={() => onEdit({})}>+ Add Bill</button>
        </div>
      </div>
      <div className="table-wrap">
        {filtered.length === 0
          ? <div className="inline-empty-state">{bills.length===0?'No bills yet - click "+ Add Bill" to get started.':'No bills match your search.'}</div>
          : (
            <table className="bills-table">
              <thead><tr><th>Name</th><th>Amount</th><th>Frequency</th><th>Due Date</th><th>Auto-pay</th><th>Notes</th><th>Actions</th></tr></thead>
              <tbody>
                {filtered.map(bill => {
                  const nd = getNextDue(bill, now);
                  const diff = nd ? Math.ceil((nd-now)/86400000) : null;
                  return (
                    <tr key={bill.id}>
                      <td data-label="Name"><div className="cell-view">{bill.name}</div></td>
                      <td data-label="Amount"><div className="cell-view money-input">{fmt(bill.amount,showCents)}</div></td>
                      <td data-label="Frequency"><span className="freq-tag">{freqLabel(bill.frequency)}</span></td>
                      <td data-label="Due Date">
                        <div className={`cell-view${diff!==null&&diff<=3?' money-negative':''}`} style={{ fontSize:'0.88rem' }}>
                          {dayOnly(nd)}
                          {diff!==null&&diff<=7&&<span style={{ marginLeft:6,fontSize:'0.76rem',opacity:0.7 }}>({diff===0?'Today':diff<0?'Overdue':`${diff}d`})</span>}
                        </div>
                      </td>
                      <td data-label="Auto-pay"><span className={`auto-pay-pill ${bill.autoPay?'is-on':'is-off'}`}>{bill.autoPay?'On':'Off'}</span></td>
                      <td data-label="Notes"><div className={`cell-view ${!bill.notes?'is-empty':''}`} style={{ fontSize:'0.86rem' }}><span className="cell-view-note">{bill.notes||'-'}</span></div></td>
                      <td data-label="Actions"><button className="ghost-button" style={{ padding:'8px 14px',fontSize:'0.84rem' }} onClick={() => onEdit(bill)}>Edit</button></td>
                    </tr>
                  );
                })}
              </tbody>
            </table>
          )}
      </div>
    </div>
  );
}

// â”€â”€ Debt Tab â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€
function calcStrategyPayoff(debts, strategy, getExtra) {
  const items = debts.map((debt, index) => ({
    id: debt.id,
    name: debt.name,
    index,
    balance: Math.max(0, parseFloat(debt.balance) || 0),
    originalBalance: Math.max(0, parseFloat(debt.balance) || 0),
    apr: Math.max(0, parseFloat(debt.apr) || 0),
    minPayment: Math.max(0, parseFloat(debt.minPayment) || 0),
    extra: Math.max(0, parseFloat(getExtra(debt)) || 0),
    paidOffMonth: null,
    totalPaid: 0,
    interestPaid: 0,
  }));
  const initialBalance = items.reduce((sum, item) => sum + item.balance, 0);
  const monthlyBudget = items
    .filter(item => item.balance > 0.01)
    .reduce((sum, item) => sum + item.minPayment + item.extra, 0);
  const perDebt = {};
  if (items.length === 0 || initialBalance <= 0 || monthlyBudget <= 0) {
    items.forEach(item => { perDebt[item.id] = { months: 0, totalPaid: 0, interestPaid: 0, completed: item.balance <= 0 }; });
    return { months: 0, totalPaid: 0, interestPaid: 0, completed: initialBalance <= 0, order: items, perDebt };
  }

  const sortedTargets = list => [...list].sort((a,b) => {
    if (strategy === 'snowball') return a.balance - b.balance || b.apr - a.apr || a.index - b.index;
    return b.apr - a.apr || a.balance - b.balance || a.index - b.index;
  });
  const initialOrder = sortedTargets(items.filter(item => item.originalBalance > 0.01)).map(item => item.id);

  let months = 0;
  let totalPaid = 0;
  while (items.some(item => item.balance > 0.01) && months < 600) {
    months += 1;
    items.forEach(item => {
      if (item.balance <= 0.01) return;
      const interest = item.balance * (item.apr / 100 / 12);
      item.balance += interest;
      item.interestPaid += interest;
    });

    let budget = monthlyBudget;
    items.forEach(item => {
      if (item.balance <= 0.01 || budget <= 0) return;
      const payment = Math.min(item.minPayment, item.balance, budget);
      item.balance -= payment;
      item.totalPaid += payment;
      totalPaid += payment;
      budget -= payment;
    });

    sortedTargets(items.filter(item => item.balance > 0.01)).forEach(item => {
      if (budget <= 0 || item.balance <= 0.01) return;
      const payment = Math.min(item.balance, budget);
      item.balance -= payment;
      item.totalPaid += payment;
      totalPaid += payment;
      budget -= payment;
    });

    items.forEach(item => {
      if (!item.paidOffMonth && item.balance <= 0.01) item.paidOffMonth = months;
    });
  }

  items.forEach(item => {
    perDebt[item.id] = {
      months: item.paidOffMonth || months,
      totalPaid: item.totalPaid,
      interestPaid: Math.max(0, item.interestPaid),
      completed: !!item.paidOffMonth,
    };
  });

  return {
    months,
    totalPaid,
    interestPaid: Math.max(0, totalPaid - initialBalance),
    completed: !items.some(item => item.balance > 0.01),
    order: initialOrder.map(id => items.find(item => item.id === id)).filter(Boolean),
    perDebt,
  };
}

function DebtTab({ debts, onEdit, onDelete, income, onIncomeChange, extraPayment, onExtraPaymentChange }) {
  const [categoryFilter, setCategoryFilter] = useState('all');
  const [payoffStrategy, setPayoffStrategy] = useState('avalanche');
  const visibleDebts = categoryFilter === 'all' ? debts : debts.filter(d => debtCategory(d) === categoryFilter);
  const totalBalance = visibleDebts.reduce((s,d) => s+d.balance, 0);
  const activeVisibleDebts = visibleDebts.filter(d => (parseFloat(d.balance) || 0) > 0.01);
  const totalMin = activeVisibleDebts.reduce((s,d) => s+d.minPayment, 0);
  const allDebtMin = debts.filter(d => (parseFloat(d.balance) || 0) > 0.01).reduce((s,d) => s+d.minPayment, 0);
  const avgApr = visibleDebts.length ? visibleDebts.reduce((s,d) => s+d.apr, 0)/visibleDebts.length : 0;
  const getExtra = debt => Math.max(parseFloat(extraPayment[debt.id]) || 0, 0);
  const totalExtra = activeVisibleDebts.reduce((s,d) => s + getExtra(d), 0);
  const strategyDetails = {
    avalanche: {
      label: 'Avalanche',
      description: 'Pays the highest APR debt first so less money goes to interest over time.',
      note: 'Use Avalanche when saving the most interest matters more than quick wins.',
    },
    snowball: {
      label: 'Snowball',
      description: 'Pays the smallest balance first so accounts disappear faster and momentum builds.',
      note: 'Use Snowball when seeing debts close quickly will help you stick with it.',
    },
  };
  const payoffPlans = {
    avalanche: calcStrategyPayoff(visibleDebts, 'avalanche', getExtra),
    snowball: calcStrategyPayoff(visibleDebts, 'snowball', getExtra),
  };
  const selectedPlan = payoffPlans[payoffStrategy] || payoffPlans.avalanche;
  const selectedStrategy = strategyDetails[payoffStrategy] || strategyDetails.avalanche;
  const payoffs = selectedPlan.order
    .map(item => {
      const debt = visibleDebts.find(entry => entry.id === item.id);
      if (!debt) return null;
      return { debt, extraApplied:getExtra(debt), ...(selectedPlan.perDebt[item.id] || {}) };
    })
    .filter(Boolean);
  const incomeMode = income.mode || 'hourly';
  const incomeAmount = parseFloat(income.amount) || 0;
  const monthlyIncome = incomeMode === 'salary' ? incomeAmount / 12 : incomeAmount * 40 * 52 / 12;
  const dti = monthlyIncome > 0 ? (allDebtMin / monthlyIncome) * 100 : 0;
  const planTime = plan => {
    if (!plan || !plan.months) return '-';
    const yrs = Math.floor(plan.months / 12);
    const mos = plan.months % 12;
    const label = yrs > 0 ? `${yrs}y ${mos}m` : `${mos}m`;
    return plan.completed ? label : `${label}+`;
  };

  return (
    <div className="layout debt-layout">
      {/* Debt table */}
      <div>
        <div className="card">
          <div className="section-heading-row">
            <div>
              <p className="section-kicker" style={{ margin:'0 0 4px', color:'var(--muted)' }}>All Debts</p>
              <h3 style={{ margin:0, fontFamily:'"Space Grotesk",sans-serif', fontSize:'1.2rem' }}>
                {categoryFilter === 'all'
                  ? `${debts.length} debt${debts.length!==1?'s':''} tracked`
                  : `${fmt(totalBalance,false)} ${categoryFilter.toLowerCase()} debt`}
              </h3>
            </div>
            <button className="primary-button add-debt-button" onClick={() => onEdit({})}>+ Add Debt</button>
          </div>
          <div className="category-filter debt-category-filter" aria-label="Debt category filter">
            {[['all','All'], ...DEBT_CATEGORIES.map(category => [category, category])].map(([value, label]) => (
              <button type="button" key={value}
                className={`category-filter-button${categoryFilter===value?' is-active':''}`}
                onClick={() => setCategoryFilter(value)}>
                {label}
              </button>
            ))}
          </div>
          <div className="table-wrap">
            {visibleDebts.length === 0
              ? <div className="inline-empty-state">No debts yet - click "+ Add Debt" to get started.</div>
              : (
                <table className="bills-table debt-table">
                  <thead><tr><th>Name</th><th>Balance</th><th>APR</th><th>Category</th><th>Min. Payment</th><th>Actions</th></tr></thead>
                  <tbody>
                    {visibleDebts.map(d => (
                      <tr key={d.id}>
                        <td data-label="Name"><div className="cell-view">{d.name}</div></td>
                        <td data-label="Balance"><div className="cell-view money-negative money-input">{fmt(d.balance)}</div></td>
                        <td data-label="APR"><span className="freq-tag">{d.apr}%</span></td>
                        <td data-label="Category"><span className="freq-tag">{debtCategory(d)}</span></td>
                        <td data-label="Min. Payment"><div className="cell-view money-input">{fmt(d.minPayment)}</div></td>
                        <td data-label="Actions"><button className="ghost-button" style={{ padding:'8px 14px',fontSize:'0.84rem' }} onClick={() => onEdit(d)}>Edit</button></td>
                      </tr>
                    ))}
                  </tbody>
                </table>
              )}
          </div>
        </div>
        <div className="card dti-card">
          <div className="section-heading-row">
            <div>
              <p className="section-kicker" style={{ margin:'0 0 4px', color:'var(--muted)' }}>Debt To Income</p>
              <h3 style={{ margin:0, fontFamily:'"Space Grotesk",sans-serif', fontSize:'1.2rem' }}>
                {monthlyIncome > 0 ? `${dti.toFixed(1)}%` : 'Add income'}
              </h3>
            </div>
            <div className={`dti-pill ${monthlyIncome > 0 ? (dti <= 36 ? 'is-good' : dti <= 43 ? 'is-watch' : 'is-high') : ''}`}>
              {monthlyIncome > 0 ? (dti <= 36 ? 'Healthy' : dti <= 43 ? 'Watch' : 'High') : 'Waiting'}
            </div>
          </div>
          <div className="dti-grid">
            <label className="field">
              <span>Income Type</span>
              <div className="select-shell">
                <select value={incomeMode} onChange={e => onIncomeChange('mode', e.target.value)}>
                  <option value="hourly">Hourly</option>
                  <option value="salary">Salary</option>
                </select>
              </div>
            </label>
            <label className="field">
              <span>{incomeMode === 'salary' ? 'Annual Salary ($)' : 'Hourly Rate ($)'}</span>
              <input type="number" step="0.01" min="0" placeholder={incomeMode === 'salary' ? 'e.g. 65000' : 'e.g. 25.00'}
                value={income.amount || ''} onChange={e => onIncomeChange('amount', e.target.value)} className="money-input" />
            </label>
          </div>
          <div className="dti-summary">
            <div><span>Monthly income</span><strong>{fmt(monthlyIncome,false)}</strong></div>
            <div><span>Debt payments</span><strong>{fmt(allDebtMin,false)}</strong></div>
          </div>
          <p className="dti-note">Hourly assumes 40 hours per week.</p>
        </div>
      </div>

      {/* Payoff summary - redesigned cleaner */}
      <div>
        <div className="card">
          <p className="section-kicker" style={{ margin:'0 0 4px', color:'var(--muted)' }}>Payoff Summary</p>
          <h3 style={{ margin:'0 0 4px', fontFamily:'"Space Grotesk",sans-serif', fontSize:'1.2rem' }}>{selectedStrategy.label} Method</h3>
          <p style={{ margin:'0 0 16px', fontSize:'0.84rem', color:'var(--muted)' }}>
            Choose the payoff style that best matches how you want to make progress.
          </p>

          <div className="payoff-method-grid" aria-label="Debt payoff strategy">
            {Object.entries(strategyDetails).map(([id, method]) => {
              const plan = payoffPlans[id];
              return (
                <button
                  key={id}
                  type="button"
                  className={`payoff-method-card${payoffStrategy === id ? ' is-active' : ''}`}
                  onClick={() => setPayoffStrategy(id)}>
                  <span>{method.label}</span>
                  <p>{method.description}</p>
                  <strong>{planTime(plan)}</strong>
                  <small>{fmt(plan.interestPaid, false)} estimated interest</small>
                </button>
              );
            })}
          </div>
          <div className="payoff-method-note">{selectedStrategy.note}</div>

          {/* Totals row */}
          <div style={{ display:'grid', gridTemplateColumns:'repeat(3,1fr)', gap:8, marginBottom:16 }}>
            {[
              { label:'Total Balance', value:fmt(totalBalance,false), danger:true },
              { label:'Min. / Month', value:fmt(totalMin + totalExtra,false) },
              { label:'Avg APR', value:`${avgApr.toFixed(1)}%` },
            ].map(({ label, value, danger }) => (
              <div key={label} style={{ padding:'12px', borderRadius:12, background:'var(--surface-strong)', border:'1px solid var(--line)', textAlign:'center' }}>
                <div style={{ fontSize:'0.75rem', fontWeight:700, color:'var(--muted)', textTransform:'uppercase', letterSpacing:'0.06em', marginBottom:6 }}>{label}</div>
                <div style={{ fontFamily:'"Space Grotesk",sans-serif', fontWeight:700, fontSize:'1rem', color: danger ? 'var(--danger)' : 'var(--text)' }}>{value}</div>
              </div>
            ))}
          </div>
          {visibleDebts.length === 0
            ? <p style={{ color:'var(--muted)', margin:0 }}>No debts match this category.</p>
            : (
              <div style={{ display:'grid', gap:16 }}>
                {payoffs.map(({ debt, months, totalPaid, interestPaid, extraApplied, completed }) => {
                  const timeStr = planTime({ months, completed });
                  const pct = totalPaid > 0 ? Math.min(100, Math.round((interestPaid/totalPaid)*100)) : 0;
                  const interestBarClass = pct >= 25 ? 'is-alert' : 'is-ok';
                  return (
                    <div key={debt.id} className="payoff-card">
                      {/* Header row */}
                      <div style={{ display:'flex', justifyContent:'space-between', alignItems:'center', marginBottom:10 }}>
                        <div>
                          <span style={{ fontWeight:700 }}>{debt.name}</span>
                          <span className="freq-tag" style={{ marginLeft:8, fontSize:'0.78rem' }}>{debt.apr}% APR</span>
                          {extraApplied > 0 && <span className="extra-pill">+{fmt(extraApplied,false)}/mo extra</span>}
                        </div>
                        <span style={{ fontFamily:'"Space Grotesk",sans-serif', fontWeight:700, color:'var(--danger)', fontSize:'1.05rem', fontVariantNumeric:'tabular-nums' }}>{fmt(debt.balance,false)}</span>
                      </div>
                      <label className="extra-payment-row">
                        <span>
                          <small className="min-payment-note">Min {fmt(debt.minPayment)}</small>
                          Extra monthly payment
                        </span>
                        <input type="number" step="0.01" min="0" placeholder="0.00"
                          value={extraPayment[debt.id] || ''} onChange={e => onExtraPaymentChange(debt.id, e.target.value)} className="money-input" />
                      </label>
                      {/* Stats row */}
                      <div style={{ display:'grid', gridTemplateColumns:'repeat(3,1fr)', gap:10 }}>
                        {[
                          { label:'Payoff', value:timeStr },
                          { label:'Interest', value:fmt(interestPaid,false), danger:true },
                          { label:'Total Paid', value:fmt(totalPaid,false) },
                        ].map(({ label, value, danger }) => (
                          <div key={label} style={{ padding:'8px 10px', borderRadius:10, background:'var(--surface)', border:'1px solid var(--line)', textAlign:'center' }}>
                            <div style={{ fontSize:'0.72rem', fontWeight:700, color:'var(--muted)', textTransform:'uppercase', letterSpacing:'0.05em', marginBottom:4 }}>{label}</div>
                            <div style={{ fontFamily:'"Space Grotesk",sans-serif', fontWeight:700, fontSize:'0.92rem', color: danger ? 'var(--danger)' : 'var(--text)' }}>{value}</div>
                          </div>
                        ))}
                      </div>
                      {/* Interest bar */}
                      <div style={{ marginTop:10 }}>
                        <div style={{ display:'flex', justifyContent:'space-between', fontSize:'0.75rem', fontWeight:700, color:'var(--muted)', marginBottom:4 }}>
                          <span>Principal</span><span>{pct}% interest of total</span>
                        </div>
                          <div className={`interest-bar ${interestBarClass}`}>
                            <div style={{ width:`${pct}%` }} />
                          </div>
                      </div>
                    </div>
                  );
                })}
              </div>
            )}
        </div>
      </div>
    </div>
  );
}

// â”€â”€ Calendar Tab â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€
const MONTH_NAMES = ['January','February','March','April','May','June','July','August','September','October','November','December'];
const DAY_NAMES = ['Sun','Mon','Tue','Wed','Thu','Fri','Sat'];

function CalendarTab({ bills, payday, onPaydayChange }) {
  const now = new Date();
  const [yr, setYr] = useState(now.getFullYear());
  const [mo, setMo] = useState(now.getMonth());

  const firstDay = new Date(yr, mo, 1).getDay();
  const daysInMonth = new Date(yr, mo+1, 0).getDate();
  const daysInPrev = new Date(yr, mo, 0).getDate();

  // Frequency-based payday highlighting (Brandon)
  const paydayDays = getPaydaysInMonth(payday, null, yr, mo);

  const billMap = {};
  bills.forEach(b => getDatesInMonth(b,yr,mo).forEach(d => {
    const k = d.getDate(); if (!billMap[k]) billMap[k]=[]; billMap[k].push(b);
  }));

  const cells = [];
  for (let i=firstDay-1; i>=0; i--) cells.push({ day:daysInPrev-i, cur:false });
  for (let d=1; d<=daysInMonth; d++) cells.push({ day:d, cur:true });
  const rem = 42 - cells.length;
  for (let d=1; d<=rem; d++) cells.push({ day:d, cur:false });

  const isToday = (day, cur) => cur && day===now.getDate() && mo===now.getMonth() && yr===now.getFullYear();
  const curYear = now.getFullYear();
  const years = Array.from({ length:11 }, (_,i) => curYear-5+i);

  return (
    <div className="card look-ahead" style={{ gridColumn:'1/-1' }}>
      <div style={{ padding:'24px 24px 0', display:'flex', flexWrap:'wrap', alignItems:'end', justifyContent:'space-between', gap:16 }}>
        <div>
          <p className="section-kicker" style={{ margin:'0 0 4px', color:'var(--muted)' }}>Look-Ahead</p>
          <h3 style={{ margin:0, fontFamily:'"Space Grotesk",sans-serif', fontSize:'1.25rem' }}>
            {MONTH_NAMES[mo]} {yr}
          </h3>
        </div>
        <div style={{ display:'flex', flexWrap:'wrap', gap:10, alignItems:'end' }}>
          {/* Month/year dropdowns (Brandon) */}
          <div className="select-shell" style={{ minWidth:130 }}>
            <select value={mo} onChange={e => setMo(Number(e.target.value))}
              style={{ padding:'10px 36px 10px 14px', borderRadius:14, border:'1px solid var(--line)', background:'var(--surface-strong)', color:'var(--text)', fontFamily:'inherit', fontWeight:700, fontSize:'0.9rem', appearance:'none' }}>
              {MONTH_NAMES.map((m,i) => <option key={i} value={i}>{m}</option>)}
            </select>
          </div>
          <div className="select-shell" style={{ minWidth:90 }}>
            <select value={yr} onChange={e => setYr(Number(e.target.value))}
              style={{ padding:'10px 36px 10px 14px', borderRadius:14, border:'1px solid var(--line)', background:'var(--surface-strong)', color:'var(--text)', fontFamily:'inherit', fontWeight:700, fontSize:'0.9rem', appearance:'none' }}>
              {years.map(y => <option key={y} value={y}>{y}</option>)}
            </select>
          </div>
          <div className="calendar-pay-setup-pill">
            <span>{payday.firstDate ? payFrequencyLabel(payday.frequency || 'biweekly') : 'Pay setup not set'}</span>
            <strong>{payday.autoEnabled ? 'Auto from settings' : 'Calendar payday marks'}</strong>
          </div>
        </div>
      </div>

      {payday.firstDate && (
        <div style={{ padding:'10px 24px 0', display:'flex', alignItems:'center', gap:8 }}>
          <div style={{ width:14, height:14, borderRadius:4, background:'var(--lime)', opacity:0.9 }} />
          <span style={{ fontSize:'0.82rem', color:'var(--muted)', fontWeight:600 }}>Payday</span>
        </div>
      )}

      <div style={{ padding:'14px 24px 24px' }}>
        <div className="calendar-weekdays">{DAY_NAMES.map(d => <div key={d} className="calendar-weekday">{d}</div>)}</div>
        <div className="calendar-grid">
          {cells.map((cell, i) => {
            const bills4 = cell.cur ? (billMap[cell.day] || []) : [];
            const isPayday = cell.cur && paydayDays.has(cell.day);
            const billInfo = bills4.map(b => `${b.name}: ${fmt(b.amount,false)}${b.autoPay ? ' Auto' : ''}`).join('\n');
            return (
              <div key={i} className={['calendar-day', !cell.cur?'is-outside':'', isToday(cell.day,cell.cur)?'is-today':'', isPayday?'is-payday':''].filter(Boolean).join(' ')} title={billInfo}>
                  <div style={{ display:'flex', justifyContent:'space-between', alignItems:'center' }}>
                    <div className="calendar-day-number">{cell.day}</div>
                    {isToday(cell.day,cell.cur) && <span className="calendar-today-badge">Today</span>}
                    {isPayday && <span className="calendar-payday-badge">Pay</span>}
                  </div>
                {bills4.length > 0 && (
                  <div className="calendar-day-bills calendar-day-count-wrap">
                    <div className="calendar-bill-count">
                      {bills4.length} bill{bills4.length!==1?'s':''}
                    </div>
                    <div className="calendar-bill-tooltip" role="tooltip">
                      {bills4.map(b => (
                        <div key={b.id} className="calendar-bill-tooltip-row">
                          <span>{b.name}</span>
                          <strong>{fmt(b.amount,false)}</strong>
                        </div>
                      ))}
                    </div>
                  </div>
                )}
              </div>
            );
          })}
        </div>
      </div>
    </div>
  );
}

// â”€â”€ Tweaks Panel (edit mode only â€” Brandon) â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€
function TweaksPanel({ tweaks, onChange }) {
  return (
    <div className="tweaks-panel">
      <div className="tweaks-header">Tweaks</div>
      <div className="tweaks-body">
        <div className="tweaks-row">
          <span>Show cents</span>
          <label className="toggle" style={{ padding:0,border:'none',background:'none',width:'auto' }}>
            <input type="checkbox" checked={tweaks.showCents} onChange={e=>onChange('showCents',e.target.checked)} />
            <span className="toggle-track"></span>
          </label>
        </div>
        <div className="tweaks-row">
          <span>Sample data</span>
          <label className="toggle" style={{ padding:0,border:'none',background:'none',width:'auto' }}>
            <input type="checkbox" checked={tweaks.sampleData} onChange={e=>onChange('sampleData',e.target.checked)} />
            <span className="toggle-track"></span>
          </label>
        </div>
        <div className="tweaks-row">
          <span>Accent</span>
            <div style={{ display:'flex',gap:6 }}>
              {[['#b8e64b','null'],['#c2f25a','bright'],['#7f9b3f','deep']].map(([c,k])=>(
              <button key={k} onClick={()=>onChange('accent',c)}
                style={{ width:22,height:22,borderRadius:6,background:c,border:tweaks.accent===c?'2px solid var(--text)':'2px solid transparent',cursor:'pointer' }} />
            ))}
          </div>
        </div>
      </div>
    </div>
  );
}

