// Subcategory page components.
// Expects window.LANE ("personal"|"business") and window.SUBCAT (e.g. "foundations","systems")

const SUBCAT_META = {
  foundations: {
    lane: "personal",
    name: "Foundations",
    label: "FOUNDATIONS",
    sub: "The money basics that compound over time.",
    desc: "The quiet work — budgets, accounts, the mental model for where your money is going and why. Do this first, and every other lane starts working for you.",
    count: 142,
    related: [
      { name: "Savings", path: "/personal/savings/", count: 198 },
      { name: "Credit", path: "/personal/credit/", count: 164 },
      { name: "Income", path: "/personal/income/", count: 127 },
    ],
    featured: {
      title: "How to Build a 3-Month Emergency Fund",
      read: "6 MIN",
      desc: "The dollar-by-dollar plan that actually works when the car breaks down in March. No motivational language — just the ledger, the automation, and the number you're aiming at.",
      fig: { k: "TARGET", v: "$12,400", d: "3 months of essential spend" },
      fig2: { k: "TIMELINE", v: "18 MO", d: "at $689/mo, automated" },
      fig3: { k: "RATE", v: "4.35%", d: "HYSA, 26-wk avg" },
      author: "Johnnie",
    },
    guides: [
      { t: "How to Build a Budget You'll Actually Follow", read: "9 MIN", diff: "BEGINNER", desc: "Why the envelope method fails in a world of auto-pay, and the two-account system that replaces it." },
      { t: "How to Calculate Your Real Net Worth (Assets, Not Vibes)", read: "7 MIN", diff: "BEGINNER", desc: "The one-page spreadsheet, the three line items most people miss, and what the number should do." },
      { t: "How to Read a Bank Statement Like It's a Map", read: "5 MIN", diff: "BEGINNER", desc: "The four categories that decide whether the month is quiet or loud — and the one you stop fighting." },
      { t: "How to Choose a Checking Account in 2026", read: "6 MIN", diff: "BEGINNER", desc: "Why the big bank is probably fine, when a credit union wins, and the fee structure to read first." },
      { t: "How to Pair a HYSA With Your Main Bank", read: "4 MIN", diff: "BEGINNER", desc: "Two accounts, one button. The boring move that earns you four figures a year." },
      { t: "How to Track Monthly Cash Flow Without an App", read: "8 MIN", diff: "INTERMEDIATE", desc: "The 12-cell table that replaces Mint, YNAB, or whatever just shut down this month." },
      { t: "How to Run a 15-Minute Quarterly Money Review", read: "10 MIN", diff: "INTERMEDIATE", desc: "Four questions, four numbers, done in one sitting. The ritual that makes everything else optional." },
      { t: "How to Set Financial Goals in Dollar Figures (Not Feelings)", read: "6 MIN", diff: "BEGINNER", desc: "Why 'save more' fails, how to turn a wish into a number, and the 90-day check." },
    ],
    popular: [
      "How to Build a 3-Month Emergency Fund",
      "How to Build a Budget You'll Actually Follow",
      "How to Run a 15-Minute Quarterly Money Review",
      "How to Pair a HYSA With Your Main Bank",
    ],
  },
  systems: {
    lane: "business",
    name: "Systems",
    label: "SYSTEMS",
    sub: "The infrastructure that keeps your business running.",
    desc: "The books, the bank stack, the receipts, the rhythm. Built once so the boring parts run themselves and the taxman has nothing to say.",
    count: 118,
    related: [
      { name: "Capital", path: "/business/capital/", count: 94 },
      { name: "Operations", path: "/business/operations/", count: 156 },
      { name: "Compliance", path: "/business/compliance/", count: 121 },
    ],
    featured: {
      title: "How to Set Up Accounting for Your Solo Business",
      read: "8 MIN",
      desc: "The minimum viable bookkeeping stack for a one-person shop: accounts, categories, and the weekly ritual that makes tax season take an afternoon instead of a weekend.",
      fig: { k: "BENCHMARK", v: "P&L", d: "Industry-standard format" },
      fig2: { k: "WEEKLY", v: "45 MIN", d: "total bookkeeping time" },
      fig3: { k: "STACK", v: "3 TOOLS", d: "bank · books · receipts" },
    },
    guides: [
      { t: "How to Build a Chart of Accounts That Scales", read: "9 MIN", diff: "INTERMEDIATE", desc: "The 28-line chart that grows with you from $50k to $5M — and the four categories most solo shops forget." },
      { t: "How to Read Financial Statements Like a Founder", read: "9 MIN", diff: "INTERMEDIATE", desc: "Balance sheet, P&L, cash flow — what to look at, in what order, every month. With real numbers." },
      { t: "How to Reconcile Your Bank Feed in 15 Minutes a Week", read: "6 MIN", diff: "BEGINNER", desc: "The Monday-morning ritual that makes every other system downstream work." },
      { t: "How to Choose Bookkeeping Software in 2026", read: "7 MIN", diff: "BEGINNER", desc: "QuickBooks vs. Xero vs. Wave vs. a spreadsheet — what each breaks at, and where to pick." },
      { t: "How to Build a 13-Week Cash-Flow Forecast", read: "10 MIN", diff: "INTERMEDIATE", desc: "The one sheet your bank wants to see, your accountant will sign off, and you'll actually update." },
      { t: "How to Digitize and File Every Receipt Automatically", read: "5 MIN", diff: "BEGINNER", desc: "Two apps, one rule, zero shoeboxes. The setup that survives an audit." },
      { t: "How to Set Up a Separate Business Bank Account (Correctly)", read: "6 MIN", diff: "BEGINNER", desc: "EIN, signatories, and the sub-account pattern that replaces a dozen tools." },
      { t: "How to Close Your Books at Month-End in One Afternoon", read: "8 MIN", diff: "INTERMEDIATE", desc: "The checklist that moves month-end from dread to 2 hours, done." },
    ],
    popular: [
      "How to Set Up Accounting for Your Solo Business",
      "How to Read Financial Statements Like a Founder",
      "How to Build a 13-Week Cash-Flow Forecast",
      "How to Reconcile Your Bank Feed in 15 Minutes a Week",
    ],
  },
  savings: {
    lane: "personal",
    name: "Savings",
    label: "SAVINGS",
    sub: "How to put money aside without it feeling like punishment.",
    desc: "Emergency funds, sinking funds, HYSAs — the quiet, boring wins that compound into real cushion. Automation does the heavy lifting; you just pick the number and the account.",
    count: 198,
    related: [
      { name: "Foundations", path: "/personal/foundations/", count: 142 },
      { name: "Credit", path: "/personal/credit/", count: 164 },
      { name: "Income", path: "/personal/income/", count: 127 },
    ],
    featured: {
      title: "How to Build a 3-Month Emergency Fund",
      read: "6 MIN",
      desc: "The dollar-by-dollar plan that actually works when the car breaks down in March. Start with the target number, automate from payday, and stop watching the balance.",
      fig: { k: "TARGET", v: "$12,400", d: "3 months of essential spend" },
      fig2: { k: "TIMELINE", v: "18 MO", d: "at $689/mo, automated" },
      fig3: { k: "RATE", v: "4.35%", d: "HYSA, 26-wk avg" },
    },
    guides: [
      { t: "How to Pick a High-Yield Savings Account in 2026", read: "5 MIN", diff: "BEGINNER", desc: "The two things that actually move your money — rate and ease of transfer. The four things banks want you to focus on instead." },
      { t: "How to Automate Your Savings (Set It and Forget It)", read: "4 MIN", diff: "BEGINNER", desc: "The standing-order setup that puts your savings rate on autopilot, reviewed once a quarter, not every payday." },
      { t: "How to Build a Sinking Fund for Predictable Expenses", read: "6 MIN", diff: "BEGINNER", desc: "Holiday spending, car tires, the August property tax — one sub-account per category, funded monthly." },
      { t: "How to Save When You're Paid Irregularly", read: "8 MIN", diff: "INTERMEDIATE", desc: "The percentage-of-deposit rule that works for freelancers, commission earners, and anyone with lumpy income." },
      { t: "How to Decide Between a 6-Month or 12-Month Emergency Fund", read: "5 MIN", diff: "BEGINNER", desc: "The two job-security questions that decide your target, and why 12 months is only right for a specific kind of risk." },
      { t: "How to Use Your HYSA Without Killing Your Rate", read: "4 MIN", diff: "BEGINNER", desc: "How often you can withdraw before the rate tier drops, and the pairing that lets you spend without moving money twice." },
      { t: "How to Replenish Your Emergency Fund After Using It", read: "5 MIN", diff: "BEGINNER", desc: "The 90-day rebuild plan that doesn't wreck the rest of your budget, and the sequence that matters." },
      { t: "How to Store Savings Without Inflation Eating Them", read: "7 MIN", diff: "INTERMEDIATE", desc: "The three tiers — HYSA, T-bills, short-duration bond funds — and when to shift between them." },
    ],
    popular: [
      "How to Build a 3-Month Emergency Fund",
      "How to Automate Your Savings (Set It and Forget It)",
      "How to Pick a High-Yield Savings Account in 2026",
      "How to Build a Sinking Fund for Predictable Expenses",
    ],
  },
  income: {
    lane: "personal",
    name: "Income",
    label: "INCOME",
    sub: "Earning more, on purpose.",
    desc: "Salary negotiation with real numbers, side income that actually clears your tax bill, offers and equity decoded. The quiet work of making the line go up.",
    count: 127,
    related: [
      { name: "Foundations", path: "/personal/foundations/", count: 142 },
      { name: "Savings", path: "/personal/savings/", count: 198 },
      { name: "Investing", path: "/personal/investing/", count: 286 },
    ],
    featured: {
      title: "How to Negotiate a Salary Increase (With Real Numbers)",
      read: "7 MIN",
      desc: "The three-pager you bring to the meeting: market band, delta from current, and one sentence about what you've shipped since your last raise.",
      fig: { k: "MEDIAN LIFT", v: "+14.2%", d: "prepared asks, 2026 Q1" },
      fig2: { k: "PREP TIME", v: "3 HRS", d: "research + rehearsal" },
      fig3: { k: "TIMING", v: "Q1 / Q3", d: "budget cycle windows" },
    },
    guides: [
      { t: "How to Research Your Real Market Rate", read: "6 MIN", diff: "BEGINNER", desc: "The three data sources most people skip, and the one that underprices you." },
      { t: "How to Evaluate a Job Offer Beyond the Salary", read: "8 MIN", diff: "INTERMEDIATE", desc: "The six line items that change the offer's real value — and how to back-solve to the true number." },
      { t: "How to Negotiate Equity Without Looking Inexperienced", read: "9 MIN", diff: "INTERMEDIATE", desc: "The questions that make HR take your ask seriously, and the numbers you need before the call." },
      { t: "How to Start a Side Income That Clears $1,000/Mo", read: "10 MIN", diff: "BEGINNER", desc: "The four low-overhead paths that work in 2026, and what they actually pay after hours worked." },
      { t: "How to Price Freelance Work So You Actually Get Paid", read: "7 MIN", diff: "INTERMEDIATE", desc: "The effective hourly rule — what a $100 hour really nets after chasing, revisions, and unbilled calls." },
      { t: "How to Ask for a Title Change (Not Just a Raise)", read: "5 MIN", diff: "BEGINNER", desc: "The lateral move that compounds more than the percent raise in the same meeting." },
      { t: "How to Convert a Bonus Into Real Income", read: "4 MIN", diff: "BEGINNER", desc: "Why taking it in cash is rarely the play, and the two alternatives that keep more of it." },
      { t: "How to Build an Income Floor With a Second Skill", read: "8 MIN", diff: "ADVANCED", desc: "The 12-month plan to add a specific earning capability to your day job — no career pivot required." },
    ],
    popular: [
      "How to Negotiate a Salary Increase (With Real Numbers)",
      "How to Evaluate a Job Offer Beyond the Salary",
      "How to Start a Side Income That Clears $1,000/Mo",
      "How to Research Your Real Market Rate",
    ],
  },
  investing: {
    lane: "personal",
    name: "Investing",
    label: "INVESTING",
    sub: "From the first $500 to a real portfolio.",
    desc: "Index funds, tax-advantaged accounts, rebalance rules, and what not to buy. The approach that works for people who don't want a second job watching charts.",
    count: 286,
    related: [
      { name: "Savings", path: "/personal/savings/", count: 198 },
      { name: "Income", path: "/personal/income/", count: 127 },
      { name: "Credit", path: "/personal/credit/", count: 164 },
    ],
    featured: {
      title: "How to Start Investing With $500",
      read: "5 MIN",
      desc: "The two-fund portfolio that outperforms most advisors, the account to open first, and the automation rule that keeps you from tinkering.",
      fig: { k: "ENTRY", v: "$500", d: "minimum for most brokers" },
      fig2: { k: "FEES", v: "0.03%", d: "target expense ratio" },
      fig3: { k: "HORIZON", v: "10+ YR", d: "minimum for equities" },
    },
    guides: [
      { t: "How to Pick a Brokerage in 2026", read: "6 MIN", diff: "BEGINNER", desc: "Fidelity vs. Schwab vs. Vanguard vs. the new ones — what breaks where, and where to pick." },
      { t: "How to Build a Three-Fund Portfolio", read: "7 MIN", diff: "BEGINNER", desc: "The three funds, the ratios, and the 15-minute setup that beats 80% of actively managed accounts." },
      { t: "How to Maximize Your 401(k) Without Cashflow Pain", read: "8 MIN", diff: "INTERMEDIATE", desc: "The contribution ladder that hits match, Roth, and catch-up — sequenced so your paycheck doesn't break." },
      { t: "How to Decide Between a Roth and a Traditional IRA", read: "6 MIN", diff: "INTERMEDIATE", desc: "The break-even tax rate, the expected-rate-in-retirement question, and why the answer isn't what most blogs tell you." },
      { t: "How to Rebalance Your Portfolio Once a Year", read: "5 MIN", diff: "INTERMEDIATE", desc: "The 5% drift rule, the calendar option, and why most people do this wrong (or not at all)." },
      { t: "How to Invest a Windfall (Lump Sum vs. DCA)", read: "7 MIN", diff: "INTERMEDIATE", desc: "The math says lump sum wins ~66% of the time. The psychology says DCA. How to pick for your actual situation." },
      { t: "How to Read a Fund's Expense Ratio and Prospectus", read: "6 MIN", diff: "BEGINNER", desc: "The three numbers that matter, the fine print that costs you, and how a 0.5% fee eats 12% over 30 years." },
      { t: "How to Stop Picking Individual Stocks", read: "9 MIN", diff: "ADVANCED", desc: "The behavioral case against stock-picking, the exit plan if you're already holding a portfolio, and what to do with the capital gains." },
    ],
    popular: [
      "How to Start Investing With $500",
      "How to Build a Three-Fund Portfolio",
      "How to Maximize Your 401(k) Without Cashflow Pain",
      "How to Decide Between a Roth and a Traditional IRA",
    ],
  },
  debt: {
    lane: "personal",
    name: "Debt",
    label: "DEBT",
    sub: "Paying it off without losing the rest of your life.",
    desc: "Avalanche, snowball, balance transfers, the order that saves you the most dollars or the most morale. The math and the psychology, side by side.",
    count: 173,
    related: [
      { name: "Credit", path: "/personal/credit/", count: 164 },
      { name: "Foundations", path: "/personal/foundations/", count: 142 },
      { name: "Savings", path: "/personal/savings/", count: 198 },
    ],
    featured: {
      title: "How to Eliminate Credit Card Debt in 12 Months",
      read: "11 MIN",
      desc: "The three-step plan: stop the bleed, rank the debts, fund the extra payment. No motivation required — just a calculator and a calendar.",
      fig: { k: "AVG APR", v: "24.3%", d: "US CC, 2026 Q1" },
      fig2: { k: "EXTRA/MO", v: "$340", d: "median needed, $10k debt" },
      fig3: { k: "SAVINGS", v: "$4.2k", d: "interest avoided, avalanche" },
    },
    guides: [
      { t: "How to Choose Between Avalanche and Snowball", read: "6 MIN", diff: "BEGINNER", desc: "The spreadsheet case for avalanche, the behavioral case for snowball, and when each actually wins." },
      { t: "How to Use a Balance Transfer Without Getting Burned", read: "7 MIN", diff: "INTERMEDIATE", desc: "The 3% fee math, the 18-month window, and the thing most people forget that resets their APR." },
      { t: "How to Pay Off Student Loans in the Current Environment", read: "10 MIN", diff: "INTERMEDIATE", desc: "PSLF, SAVE, IBR — what's still live in 2026, what's expiring, and the order of operations for each scenario." },
      { t: "How to Negotiate a Credit Card Settlement", read: "8 MIN", diff: "ADVANCED", desc: "When it's right, when it destroys your score, and the script that gets a 40% reduction in one call." },
      { t: "How to Consolidate Debt (And When Not To)", read: "9 MIN", diff: "INTERMEDIATE", desc: "Personal loan vs. 401(k) loan vs. HELOC — the real cost of each, and when consolidation is just repackaging." },
      { t: "How to Rank Your Debts in the Right Order", read: "5 MIN", diff: "BEGINNER", desc: "The four attributes — APR, balance, tax-deductibility, liquidity — and the scoring that picks the first dollar target." },
      { t: "How to Stop Using Credit Cards Without Closing Them", read: "4 MIN", diff: "BEGINNER", desc: "Why closing tanks your score, and the soft-lock method that ends the behavior without the penalty." },
      { t: "How to Build a Debt Payoff Calendar You'll Actually Keep", read: "6 MIN", diff: "BEGINNER", desc: "The monthly check-in, the single number that matters, and the two-column layout that replaces a dozen apps." },
    ],
    popular: [
      "How to Eliminate Credit Card Debt in 12 Months",
      "How to Choose Between Avalanche and Snowball",
      "How to Use a Balance Transfer Without Getting Burned",
      "How to Pay Off Student Loans in the Current Environment",
    ],
  },
  credit: {
    lane: "personal",
    name: "Credit",
    label: "CREDIT",
    sub: "What your score means, and the handful of moves that move it fastest.",
    desc: "Utilization, length, mix, new inquiries, disputes — the five factors, weighted correctly, and the quiet habits that push your number up. No credit-repair hype.",
    count: 164,
    related: [
      { name: "Debt", path: "/personal/debt/", count: 173 },
      { name: "Foundations", path: "/personal/foundations/", count: 142 },
      { name: "Savings", path: "/personal/savings/", count: 198 },
    ],
    featured: {
      title: "How to Raise Your Credit Score 50 Points in 90 Days",
      read: "8 MIN",
      desc: "The three levers that move the number fastest — pay-down, statement-date timing, and a single dispute — with the expected lift from each.",
      fig: { k: "TARGET LIFT", v: "+50 pts", d: "realistic in 90 days" },
      fig2: { k: "UTILIZATION", v: "< 10%", d: "ideal for max score" },
      fig3: { k: "INQUIRY", v: "24 MO", d: "hard-pull fade time" },
    },
    guides: [
      { t: "How to Read Your Credit Report in 10 Minutes", read: "6 MIN", diff: "BEGINNER", desc: "The three bureaus, the four sections, and the items that deserve a second look before you dispute." },
      { t: "How to Dispute an Error With the Credit Bureaus", read: "7 MIN", diff: "INTERMEDIATE", desc: "The letter, the attachments, and the 30-day clock — what actually forces a correction." },
      { t: "How to Time a Credit Card Payment for Maximum Score", read: "4 MIN", diff: "BEGINNER", desc: "The statement-date rule that drops reported utilization to near-zero, even if you use the card daily." },
      { t: "How to Build Credit From Zero", read: "8 MIN", diff: "BEGINNER", desc: "The three-product sequence — secured card, authorized user, credit-builder loan — that gets you to 720 in 18 months." },
      { t: "How to Recover From a Late Payment", read: "6 MIN", diff: "INTERMEDIATE", desc: "The goodwill-letter script that works, the situations where it doesn't, and what else to do in the meantime." },
      { t: "How to Avoid the Common Credit-Killer Mistakes", read: "5 MIN", diff: "BEGINNER", desc: "Closing old cards, co-signing, maxing a new card — the five moves that can drop you 80+ points overnight." },
      { t: "How to Use a Credit Freeze (And When to Lift It)", read: "4 MIN", diff: "BEGINNER", desc: "The free freeze, the per-bureau process, and the 5-minute lift protocol for when you apply for credit." },
      { t: "How to Prep Your Credit for a Mortgage Application", read: "10 MIN", diff: "ADVANCED", desc: "The six-month runway: what to do, what not to touch, and the single mistake that cancels a pre-approval." },
    ],
    popular: [
      "How to Raise Your Credit Score 50 Points in 90 Days",
      "How to Read Your Credit Report in 10 Minutes",
      "How to Time a Credit Card Payment for Maximum Score",
      "How to Build Credit From Zero",
    ],
  },
  capital: {
    lane: "business",
    name: "Capital",
    label: "CAPITAL",
    sub: "When to borrow, when to wait, what the numbers need to say.",
    desc: "Lines of credit, SBA loans, revenue-based financing, equity. The decision tree for each, what the lender wants to see, and the cost of capital you actually pay once fees clear.",
    count: 94,
    related: [
      { name: "Systems", path: "/business/systems/", count: 118 },
      { name: "Operations", path: "/business/operations/", count: 156 },
      { name: "Compliance", path: "/business/compliance/", count: 121 },
    ],
    featured: {
      title: "How to Get Approved for a Business Line of Credit",
      read: "10 MIN",
      desc: "The three-sheet model that moves a lender from no to yes — and the quiet work you do in the 90 days before you apply.",
      fig: { k: "APPROVAL", v: "73%", d: "prepared applicants, 2026" },
      fig2: { k: "MIN TIME", v: "24 MO", d: "in business, most banks" },
      fig3: { k: "DSCR", v: "1.25x", d: "lender target, minimum" },
    },
    guides: [
      { t: "How to Decide Between an SBA Loan and a Line of Credit", read: "8 MIN", diff: "INTERMEDIATE", desc: "The use-case split: one-time vs. ongoing, collateralized vs. unsecured, and the real 5-year cost comparison." },
      { t: "How to Prep Your Books for a Lender Review", read: "9 MIN", diff: "INTERMEDIATE", desc: "The 12 months of P&L, the tax return reconciliation, and the two red flags you can fix in 30 days." },
      { t: "How to Apply for Revenue-Based Financing", read: "7 MIN", diff: "INTERMEDIATE", desc: "The real cost (usually 25-40% APR equivalent), when it makes sense, and when it quietly kills cashflow." },
      { t: "How to Structure a Friends-and-Family Round", read: "10 MIN", diff: "ADVANCED", desc: "The doc stack, the equity vs. debt question, and the conversation that keeps Thanksgiving intact." },
      { t: "How to Use a Business Credit Card as Working Capital", read: "5 MIN", diff: "BEGINNER", desc: "The 0% intro window, the utilization rule that protects your personal score, and the exit plan." },
      { t: "How to Pitch a Local Bank (Not a Chain)", read: "8 MIN", diff: "INTERMEDIATE", desc: "Why community banks approve faster, what relationship banking actually requires, and the two pages that matter." },
      { t: "How to Calculate the True Cost of Capital", read: "6 MIN", diff: "INTERMEDIATE", desc: "APR vs. APY vs. factor rate — the conversion table, and why most lender quotes understate the real number." },
      { t: "How to Get Approved for Your First SBA Loan", read: "11 MIN", diff: "ADVANCED", desc: "The 7(a) vs. microloan question, the documentation stack, and the common disqualifiers." },
    ],
    popular: [
      "How to Get Approved for a Business Line of Credit",
      "How to Decide Between an SBA Loan and a Line of Credit",
      "How to Prep Your Books for a Lender Review",
      "How to Calculate the True Cost of Capital",
    ],
  },
  operations: {
    lane: "business",
    name: "Operations",
    label: "OPERATIONS",
    sub: "The mechanics that turn a business into a business.",
    desc: "Pricing, margin math, payroll, the weekly rhythm. The unglamorous operations work that decides whether you've got a job or a company.",
    count: 156,
    related: [
      { name: "Systems", path: "/business/systems/", count: 118 },
      { name: "Capital", path: "/business/capital/", count: 94 },
      { name: "Growth", path: "/business/growth/", count: 188 },
    ],
    featured: {
      title: "How to Calculate Your Real Profit Margin",
      read: "9 MIN",
      desc: "Gross, contribution, operating, net — what each tells you, the COGS adjustments most owners miss, and the number that actually predicts whether next month is fine.",
      fig: { k: "GROSS", v: "58%", d: "services, median 2026" },
      fig2: { k: "CONTRIBUTION", v: "44%", d: "after variable costs" },
      fig3: { k: "NET", v: "12%", d: "after full overhead" },
      author: "Isabella",
    },
    guides: [
      { t: "How to Price Your Services (Not the Race-to-Bottom)", read: "8 MIN", diff: "INTERMEDIATE", desc: "The target-margin method, the value-based alternative, and the pricing sheet that makes the conversation short." },
      { t: "How to Run Payroll for a 3-Person Company", read: "7 MIN", diff: "INTERMEDIATE", desc: "The tool, the filings, the cadence — what to set up once so you don't think about it again." },
      { t: "How to Forecast Cashflow 13 Weeks Out", read: "10 MIN", diff: "ADVANCED", desc: "The weekly template, the inputs that matter, and the one cell that tells you when to pull the brake." },
      { t: "How to Set Up Net 30 Terms Without Getting Burned", read: "6 MIN", diff: "INTERMEDIATE", desc: "The deposit rule, the credit check, and the late-payment escalation that works." },
      { t: "How to Track Cost Per Unit in a Service Business", read: "8 MIN", diff: "INTERMEDIATE", desc: "The hours-to-deliverable math that turns hand-wavy services into priced products." },
      { t: "How to Decide What to Stop Doing", read: "6 MIN", diff: "INTERMEDIATE", desc: "The 4-quadrant revenue-effort chart that reveals what's secretly subsidizing everything else." },
      { t: "How to Raise Prices Without Losing Clients", read: "7 MIN", diff: "INTERMEDIATE", desc: "The 10% rule, the grandfathering clause, and the email that actually gets a yes." },
      { t: "How to Build a Weekly Operating Rhythm", read: "5 MIN", diff: "BEGINNER", desc: "The Monday number review, Wednesday delivery check, Friday cash call — 90 minutes a week, everything stays on." },
    ],
    popular: [
      "How to Calculate Your Real Profit Margin",
      "How to Price Your Services (Not the Race-to-Bottom)",
      "How to Forecast Cashflow 13 Weeks Out",
      "How to Raise Prices Without Losing Clients",
    ],
  },
  compliance: {
    lane: "business",
    name: "Compliance",
    label: "COMPLIANCE",
    sub: "The filings that move from annoying to existential if you ignore them.",
    desc: "Entity structure, sales tax, 1099s, the quarterly and annual filings. The unglamorous work that keeps the government quiet and your business actually yours.",
    count: 121,
    related: [
      { name: "Systems", path: "/business/systems/", count: 118 },
      { name: "Capital", path: "/business/capital/", count: 94 },
      { name: "Operations", path: "/business/operations/", count: 156 },
    ],
    featured: {
      title: "How to Choose Between an LLC and an S-Corp in 2026",
      read: "9 MIN",
      desc: "The income threshold that flips the decision, the payroll requirement, and the three questions that settle it before you meet with a CPA.",
      fig: { k: "BREAK-EVEN", v: "$80k", d: "SE income, S-corp math" },
      fig2: { k: "SAVINGS", v: "~$6k/yr", d: "above break-even" },
      fig3: { k: "PAYROLL", v: "REQUIRED", d: "reasonable comp, S-corp" },
    },
    guides: [
      { t: "How to File Your First Quarterly Estimated Tax Payment", read: "6 MIN", diff: "BEGINNER", desc: "The safe-harbor rule, the four dates, and the two-line worksheet that beats the IRS penalty." },
      { t: "How to Issue 1099s Without Tripping the Payer Rules", read: "5 MIN", diff: "BEGINNER", desc: "Who gets one, the $600 threshold, and the W-9 collection flow that starts before the first invoice." },
      { t: "How to Register for Sales Tax in Multiple States", read: "10 MIN", diff: "ADVANCED", desc: "The nexus rules (including Wayfair thresholds), the filing cadence per state, and the tool that replaces a bookkeeper." },
      { t: "How to Handle Payroll Taxes for a New Hire", read: "8 MIN", diff: "INTERMEDIATE", desc: "The W-4, I-9, state withholding — what's due when, and the payroll service that handles 90% of it." },
      { t: "How to Prep Your Business for an Annual Report Filing", read: "4 MIN", diff: "BEGINNER", desc: "The 10-minute state filing most owners miss until they get a dissolution letter." },
      { t: "How to Keep a Clean Ledger for Tax Season", read: "7 MIN", diff: "INTERMEDIATE", desc: "The monthly reconciliation that makes your April CPA appointment an hour instead of three days." },
      { t: "How to Structure Contractor Agreements That Hold Up", read: "9 MIN", diff: "INTERMEDIATE", desc: "The five clauses that matter, the IRS contractor-vs-employee test, and the template to start from." },
      { t: "How to Set Up Your Business for Audit Survival", read: "8 MIN", diff: "ADVANCED", desc: "The documentation stack, the 7-year rule, and what to hand the auditor in the first 30 minutes." },
    ],
    popular: [
      "How to Choose Between an LLC and an S-Corp in 2026",
      "How to File Your First Quarterly Estimated Tax Payment",
      "How to Issue 1099s Without Tripping the Payer Rules",
      "How to Prep Your Business for an Annual Report Filing",
    ],
  },
  growth: {
    lane: "business",
    name: "Growth",
    label: "GROWTH",
    sub: "Decisions in the right order — hiring, firing, adding a second line.",
    desc: "When to make the first hire, when to fire, when to add a service, when to slow down. The operator decisions that decide whether the business compounds or stalls.",
    count: 188,
    related: [
      { name: "Operations", path: "/business/operations/", count: 156 },
      { name: "Capital", path: "/business/capital/", count: 94 },
      { name: "Benchmarks", path: "/business/benchmarks/", count: 187 },
    ],
    featured: {
      title: "How to Hire Your First Employee",
      read: "11 MIN",
      desc: "The revenue threshold that signals you're ready, the role shape that actually unlocks your time, and the 90-day plan that makes the hire stick.",
      fig: { k: "REVENUE", v: "$180k", d: "threshold for first hire" },
      fig2: { k: "RAMP", v: "90 DAYS", d: "to productive output" },
      fig3: { k: "RETENTION", v: "> 12 MO", d: "target for first hire" },
    },
    guides: [
      { t: "How to Decide When to Hire (Not When You Can't Sleep)", read: "7 MIN", diff: "INTERMEDIATE", desc: "The bottleneck test, the margin math, and the three roles that usually come before 'assistant.'" },
      { t: "How to Price Up Without Losing Clients", read: "6 MIN", diff: "INTERMEDIATE", desc: "The 10% rule, the email to send 60 days out, and the grandfathering window that keeps retention." },
      { t: "How to Add a Second Service Line", read: "9 MIN", diff: "ADVANCED", desc: "The adjacent-capability test, the pilot structure, and the revenue threshold that says 'expand vs. stop.'" },
      { t: "How to Fire an Employee the Right Way", read: "8 MIN", diff: "ADVANCED", desc: "The legal checklist, the conversation structure, and the documentation that protects both sides." },
      { t: "How to Expand to a Second Geography", read: "10 MIN", diff: "ADVANCED", desc: "The entity structure, the sales-tax nexus implications, and the two metrics that say 'ready.'" },
      { t: "How to Write a Job Description That Actually Filters", read: "6 MIN", diff: "BEGINNER", desc: "The three bullet points that self-screen candidates, and the one you should never put in a JD." },
      { t: "How to Build a Hiring Pipeline Before You Need It", read: "7 MIN", diff: "INTERMEDIATE", desc: "The 12-month relationship-building play that makes your next hire already know you." },
      { t: "How to Know When to Stop Growing", read: "5 MIN", diff: "INTERMEDIATE", desc: "The two-quadrant chart — revenue vs. quality of life — and the signals that growth is costing you both." },
    ],
    popular: [
      "How to Hire Your First Employee",
      "How to Decide When to Hire (Not When You Can't Sleep)",
      "How to Price Up Without Losing Clients",
      "How to Fire an Employee the Right Way",
    ],
  },
  benchmarks: {
    lane: "business",
    name: "Benchmarks",
    label: "BENCHMARKS",
    sub: "What good looks like, by industry and by stage.",
    desc: "Margins, overhead ratios, LTV/CAC, utilization rates. The numbers that tell you whether you're shooting at the right target, or at an imaginary one.",
    count: 187,
    related: [
      { name: "Operations", path: "/business/operations/", count: 156 },
      { name: "Growth", path: "/business/growth/", count: 188 },
      { name: "Systems", path: "/business/systems/", count: 118 },
    ],
    featured: {
      title: "How to Know If Your Margins Are Actually Healthy",
      read: "8 MIN",
      desc: "The five industry reference tables, the adjustments to make before you compare, and the thing that matters more than the margin itself — its direction.",
      fig: { k: "SERVICES", v: "50-65%", d: "gross margin range" },
      fig2: { k: "PRODUCT", v: "30-45%", d: "gross margin range" },
      fig3: { k: "ECOM", v: "15-30%", d: "gross margin range" },
    },
    guides: [
      { t: "How to Benchmark Your Operating Expense Ratio", read: "7 MIN", diff: "INTERMEDIATE", desc: "The four categories that matter, the industry reference points, and the one that usually hides the problem." },
      { t: "How to Calculate LTV and CAC for a Services Business", read: "9 MIN", diff: "ADVANCED", desc: "The retention curve, the acquisition stack, and the 3:1 ratio that actually means healthy." },
      { t: "How to Measure Utilization Without Killing Morale", read: "6 MIN", diff: "INTERMEDIATE", desc: "The 65-75% target for billable roles, the definition that matters, and what to look at BEFORE utilization." },
      { t: "How to Compare Yourself to a Public Competitor's Filings", read: "10 MIN", diff: "ADVANCED", desc: "Reading a 10-K for operational cues, the ratios that map down to your size, and the ones that don't." },
      { t: "How to Know If Your Overhead Is Too High", read: "5 MIN", diff: "BEGINNER", desc: "The rent-plus-payroll-plus-software rule of thumb, by industry, and when the number is actually a feature." },
      { t: "How to Set Internal Benchmarks When Public Data Is Thin", read: "7 MIN", diff: "INTERMEDIATE", desc: "The 3-year internal trend method, the adjacent-industry stand-in, and the hypothesis-and-test loop." },
      { t: "How to Interpret Industry Reports (Skeptically)", read: "6 MIN", diff: "INTERMEDIATE", desc: "Who publishes them, what they don't publish, and the two adjustments that make them usable." },
      { t: "How to Know When a Good Number Hides a Bad Trend", read: "8 MIN", diff: "ADVANCED", desc: "The trailing-vs-leading indicator trap, and the ratio pairs that catch it before the quarter ends." },
    ],
    popular: [
      "How to Know If Your Margins Are Actually Healthy",
      "How to Benchmark Your Operating Expense Ratio",
      "How to Calculate LTV and CAC for a Services Business",
      "How to Measure Utilization Without Killing Morale",
    ],
  },
};

/* ========== LIVE LEAF URLS ==========
   Same map as LaneHub.jsx — only Emergency Fund + Profit Margin are built.
   Exposed on window so SubcatApp.jsx (separate <script type="text/babel">)
   can reuse the same map without duplicating it. */
const LEAF_URLS = {
  "How to Build a 3-Month Emergency Fund": "/personal/foundations/emergency-fund/",
  "How to Calculate Your Real Profit Margin (Most People Get This Wrong)": "/business/operations/profit-margin/",
  "How to Calculate Your Real Profit Margin (Most Get This Wrong)": "/business/operations/profit-margin/",
  "How to Calculate Your Real Profit Margin": "/business/operations/profit-margin/",
};
const leafUrl = (title) => LEAF_URLS[title] || null;
window.leafUrl = leafUrl;

function SubcatBreadcrumbs({ data }) {
  const laneLabel = data.lane === "personal" ? "PERSONAL" : "BUSINESS";
  const homeHref = data.lane === "personal" ? "/personal/" : "/business/";
  return (
    <div className="crumbs">
      <div className="crumbs__inner">
        <a href="/" className="crumbs__item">HOME</a>
        <span className="crumbs__sep">/</span>
        <a href={homeHref} className="crumbs__item">{laneLabel}</a>
        <span className="crumbs__sep">/</span>
        <a className="crumbs__item" style={{color: "var(--forest-ink)"}}>{data.label}</a>
        <span className="crumbs__spacer" />
        <span className="crumbs__stats">
          <span>PATH</span>
          <span className="crumbs__val">/{data.lane}/{data.name.toLowerCase()}</span>
          <span>·</span>
          <span>COUNT</span>
          <span className="crumbs__val">{data.count}</span>
          <span>·</span>
          <span>SORT</span>
          <span className="crumbs__val">POPULAR</span>
        </span>
      </div>
    </div>
  );
}

function SubcatHero({ data }) {
  const [filter, setFilter] = React.useState("ALL");
  const filters = ["ALL", "BEGINNER", "INTERMEDIATE", "ADVANCED", "< 5 MIN", "5-10 MIN", "10+ MIN"];
  return (
    <section className={`subhero subhero--${data.lane}`}>
      <div className="subhero__bg" aria-hidden="true" />
      <div className="subhero__inner">
        <div className="subhero__meta">
          <span className="subhero__num">{data.lane === "personal" ? "01" : "02"}</span>
          <span className="subhero__bar" />
          <span className="subhero__label">
            {data.lane === "personal" ? "PERSONAL" : "BUSINESS"} · {data.label}
          </span>
          <span className="subhero__dot">·</span>
          <span className="subhero__counter">{data.count} GUIDES</span>
          <span className="subhero__dot">·</span>
          <span className="subhero__counter">UPDATED WEEKLY</span>
        </div>
        <h1 className="subhero__h1">{data.name}</h1>
        <p className="subhero__sub">{data.sub}</p>
        <p className="subhero__desc">{data.desc}</p>

        <form className="subhero__search" onSubmit={(e) => e.preventDefault()}>
          <span className="subhero__search-label">SEARCH &gt;</span>
          <input placeholder={`search ${data.name.toLowerCase()} guides…`} />
          <span className="subhero__search-kbd">⌘ K</span>
          <button type="submit" className="subhero__search-btn">EXECUTE</button>
        </form>

        <div className="subhero__filters">
          <span className="subhero__filter-k">FILTER —</span>
          {filters.map(f => (
            <button
              key={f}
              className={`subhero__filter ${filter === f ? "is-on" : ""}`}
              onClick={() => setFilter(f)}
            >{f}</button>
          ))}
        </div>
      </div>
    </section>
  );
}

function FeaturedGuide({ data }) {
  const f = data.featured;
  const author = (f.author || "IRIS").toUpperCase();
  return (
    <section className="fguide">
      <div className="fguide__inner">
        <div className="fguide__stamp">
          <span className="fguide__stamp-k">EDITOR'S FEATURE</span>
          <span className="fguide__stamp-v">TOP-RANKED IN {data.label}</span>
        </div>
        <div className="fguide__card">
          <div className="fguide__l">
            <div className="fguide__meta">
              <span className="fguide__tag">{data.label}</span>
              <span className="fguide__sep">·</span>
              <span>{f.read}</span>
              <span className="fguide__sep">·</span>
              <span>FILED BY {author}</span>
            </div>
            <h2 className="fguide__title">{f.title}</h2>
            <p className="fguide__desc">{f.desc}</p>
            <div className="fguide__figs">
              {[f.fig, f.fig2, f.fig3].map((x, i) => (
                <div key={i} className="fguide__fig">
                  <div className="fguide__fig-k">{x.k}</div>
                  <div className="fguide__fig-v">{x.v}</div>
                  <div className="fguide__fig-d">{x.d}</div>
                </div>
              ))}
            </div>
            <div className="fguide__actions">
              {leafUrl(f.title) ? (
                <a href={leafUrl(f.title)} className="btn btn--mint" style={{ textDecoration: "none" }}>READ GUIDE →</a>
              ) : (
                <button className="btn btn--mint">READ GUIDE →</button>
              )}
              <button className="btn btn--ghost" style={{color: "#fff", borderColor: "var(--mint)"}}>SAVE TO LIBRARY</button>
            </div>
          </div>
          <aside className="fguide__r" aria-hidden="true">
            <div className="fguide__r-k">WEEK OF 04.18.26</div>
            <div className="fguide__r-issue">ISSUE 038</div>
            <div className="fguide__r-grid">
              {Array.from({length: 40}, (_, i) => (
                <span key={i} />
              ))}
            </div>
            <svg viewBox="0 0 240 120" preserveAspectRatio="none" className="fguide__r-chart">
              <path d="M0,110 L30,100 L60,95 L90,80 L120,70 L150,55 L180,40 L210,25 L240,10"
                fill="none" stroke="#99edc3" strokeWidth="1.5"/>
              <path d="M0,110 L30,100 L60,95 L90,80 L120,70 L150,55 L180,40 L210,25 L240,10 L240,120 L0,120 Z"
                fill="#99edc3" fillOpacity="0.12"/>
            </svg>
            <div className="fguide__r-author">
              <div className="fguide__r-pic" />
              <div>
                <div className="fguide__r-name">{author}</div>
                <div className="fguide__r-role">LEAD · {data.lane.toUpperCase()}</div>
              </div>
            </div>
          </aside>
        </div>
      </div>
    </section>
  );
}

function GuideCard({ g, i, author, lane, hover }) {
  const url = leafUrl(g.t);
  const Wrap = url ? "a" : "article";
  const wrapProps = url
    ? { href: url, className: `gcard ${hover ? "is-hover" : ""}`, style: { textDecoration: "none", color: "inherit", display: "block" } }
    : { className: `gcard ${hover ? "is-hover" : ""}` };
  const byline = (g.author || author || "IRIS").toUpperCase();
  return (
    <Wrap {...wrapProps}>
      <div className="gcard__top">
        <span className="gcard__idx">{String(i + 1).padStart(3, "0")}</span>
        <span className="gcard__diff">{g.diff}</span>
      </div>
      <h3 className="gcard__title">{g.t}</h3>
      <p className="gcard__desc">{g.desc}</p>
      <div className="gcard__foot">
        <span className="gcard__author">BY {byline}</span>
        <span className="gcard__read">{g.read}</span>
      </div>
    </Wrap>
  );
}

function SubcatBody({ data }) {
  const author = "IRIS";
  return (
    <section className="sbody">
      <div className="sbody__grid">
        <div className="sbody__main">
          <div className="sbody__head">
            <div className="section-head__kicker">
              <span className="bar"/> ALL GUIDES · {data.label} · {data.count - 1} MORE
            </div>
            <h2 className="sbody__h2">Everything else in {data.name.toLowerCase()}.</h2>
            <div className="sbody__sort">
              <span>SORTED BY</span>
              <button className="is-on">POPULAR</button>
              <button>NEWEST</button>
              <button>SHORTEST</button>
              <button>A–Z</button>
            </div>
          </div>

          <div className="sbody__cards">
            {data.guides.map((g, i) => (
              <GuideCard
                key={g.t}
                g={g} i={i}
                author={author}
                lane={data.lane}
                hover={i === 0}
              />
            ))}
          </div>

          <div className="sbody__loadmore">
            <button className="btn btn--primary">LOAD {data.count - data.guides.length - 1} MORE GUIDES →</button>
            <span className="sbody__loadmore-meta">
              Showing {data.guides.length + 1} of {data.count} · {data.label}
            </span>
          </div>
        </div>

        <aside className="sbody__side">
          <div className="side-block">
            <div className="side-block__k">POPULAR IN {data.label}</div>
            <ol className="side-block__list">
              {data.popular.map((p, i) => {
                const url = leafUrl(p);
                const Inner = url ? "a" : "span";
                const innerProps = url ? { href: url } : {};
                return (
                  <li key={p}>
                    <Inner {...innerProps}>
                      <span className="side-block__idx">{String(i + 1).padStart(2, "0")}</span>
                      <span className="side-block__title">{p}</span>
                    </Inner>
                  </li>
                );
              })}
            </ol>
          </div>

          <div className="side-block">
            <div className="side-block__k">RELATED SUBCATEGORIES</div>
            <ul className="side-block__related">
              {data.related.map(r => (
                <li key={r.name}>
                  <a>
                    <span className="side-block__rname">{r.name}</span>
                    <span className="side-block__rcount">{r.count}</span>
                    <span className="side-block__rarr">→</span>
                  </a>
                </li>
              ))}
            </ul>
          </div>

          <div className="side-block side-block--dark">
            <div className="side-block__k" style={{color: "var(--mint)"}}>BENCHMARKS · {data.label}</div>
            <div className="side-block__bench">
              <div>
                <span className="k">AVG READ</span>
                <span className="v">7.2 MIN</span>
              </div>
              <div>
                <span className="k">UPDATED</span>
                <span className="v">04.18.26</span>
              </div>
              <div>
                <span className="k">TOTAL</span>
                <span className="v">{data.count}</span>
              </div>
              <div>
                <span className="k">AUTHOR</span>
                <span className="v">{author}</span>
              </div>
            </div>
          </div>

          <div className="side-block">
            <div className="side-block__k">NOT FINDING IT?</div>
            <p className="side-block__p">
              Ask Iris directly. Every question gets read. Enough of you ask the same thing, Iris writes the guide.
            </p>
            <button className="btn btn--primary" style={{width: "100%", justifyContent: "center"}}>
              SUBMIT A QUESTION →
            </button>
          </div>
        </aside>
      </div>
    </section>
  );
}

Object.assign(window, { SUBCAT_META, SubcatBreadcrumbs, SubcatHero, FeaturedGuide, GuideCard, SubcatBody });
