// Guide leaf page — both lanes, structural twins

/* ========== LIVE LEAF URLS ==========
   Only these two guides are live. Everything else renders as text, no href. */
const LEAF_URLS = {
  "How to Build a 3-Month Emergency Fund": "/personal/foundations/emergency-savings/build-a-3-month-emergency-fund/",
  "How to Calculate Your Real Profit Margin (Most People Get This Wrong)": "/business/benchmarks/margins-profitability/calculate-your-real-profit-margin/",
  "How to Calculate Your Real Profit Margin": "/business/benchmarks/margins-profitability/calculate-your-real-profit-margin/",
  "How to Run a 15-Minute Quarterly Money Review": "/personal/foundations/net-worth-tracking/run-a-15-minute-quarterly-money-review/",
  "How to Pick Your First HYSA Without Going Down a Rabbit Hole": "/personal/banking/account-types/pick-your-first-hysa-without-going-down-a-rabbit-hole/",
  "How to Set Your S-Corp Reasonable Salary": "/business/entity/s-corp-c-corp/set-your-s-corp-reasonable-salary/",
  "How to Read Your Own P&L Without an Accountant": "/business/accounting/reading-the-books/read-your-own-p-l-without-an-accountant/",
  "How a Rental Property Actually Fits Into a Personal Financial Plan": "/personal/investing/advanced-investing/how-a-rental-property-actually-fits-into-a-personal-financial-plan/",
  "What an Expired Certificate Actually Costs You": "/business/compliance/reporting/what-an-expired-certificate-actually-costs-you/",
};
const leafUrl = (title) => LEAF_URLS[title] || null;

const GUIDE_META = {
  "emergency-fund": {
    lane: "personal",
    breadcrumb: ["PERSONAL", "FOUNDATIONS", "EMERGENCY SAVINGS"],
    breadcrumbHrefs: ["/personal/", "/personal/foundations/", "/personal/foundations/emergency-savings/"],
    subcatPath: "/personal/foundations/emergency-savings/",
    subcatName: "Emergency Savings",
    read: "6 MIN",
    title: "How to Build a 3-Month Emergency Fund",
    sub: "The exact steps to get there, with numbers.",
    lead: "Three months of essential spend, parked in a high-yield account, contributed to automatically — that's the whole thing. Everything below is how to actually do it.",
    steps: [
      ["Step 01", "Frame the goal in a dollar figure, not a feeling.", "Add up one month of essential spend — rent, utilities, groceries, insurance, minimum debt payments. Multiply by three. That's your target."],
      ["Step 02", "Pull the three statements that show where you are today.", "Current savings, monthly take-home, monthly essential spend. Write them on one line. If the gap is less than 6 months of automation, skip to Step 04."],
      ["Step 03", "Open a separate high-yield savings account (HYSA).", "Not the same bank as checking. The separation is the point — friction is a feature. Aim for ≥ 4% APY in 2026."],
      ["Step 04", "Automate the boring 80%. Review the other 20% monthly.", "Schedule the transfer the day after payday. Check the balance at the end of the month, not the end of the week."],
      ["Step 05", "Re-check against your plan every 90 days.", "Life changes. Rent goes up, jobs change, the target moves. Recalculate once a quarter and adjust the automation."],
    ],
    figures: [
      { k: "TARGET", v: "$12,400", d: "3 months essential spend" },
      { k: "TIMELINE", v: "18 MO", d: "at $689/mo, automated" },
      { k: "RATE", v: "4.35%", d: "HYSA, 26-wk avg" },
    ],
    author: "Johnnie",
    authorRole: "Personal finance — formerly retail trading desk, Chicago",
    authorBio: "Johnnie spent a decade on a retail trading desk before walking away to write for people who were never meant to read a 10-K. He answers the money questions you're a little embarrassed to ask.",
    more: [
      { t: "How to Pick Your First HYSA Without Going Down a Rabbit Hole", read: "5 MIN" },
      { t: "How to Run a 15-Minute Quarterly Money Review", read: "6 MIN" },
      { t: "How to Pair a HYSA With Your Main Bank", read: "4 MIN" },
    ],
    prev: { t: "How to Build a Budget You'll Actually Follow", href: "#" },
    next: { t: "How to Pick Your First HYSA Without Going Down a Rabbit Hole", href: "#" },
  },
  "profit-margin": {
    lane: "business",
    breadcrumb: ["BUSINESS", "BENCHMARKS", "MARGINS & PROFITABILITY"],
    breadcrumbHrefs: ["/business/", "/business/benchmarks/", "/business/benchmarks/margins-profitability/"],
    subcatPath: "/business/benchmarks/margins-profitability/",
    subcatName: "Margins & Profitability",
    read: "8 MIN",
    title: "How to Calculate Your Real Profit Margin (Most People Get This Wrong)",
    sub: "The formula that changes your pricing strategy.",
    lead: "Most operators confuse markup with margin and set prices that leak cash every month. The fix is one formula, applied honestly to real numbers from your books — not the numbers you wish were in your books.",
    steps: [
      ["Step 01", "Gross Profit = Revenue minus Cost of Goods Sold (COGS).", "Revenue is what landed in the bank, net of refunds. COGS is every direct cost to produce what you sold — materials, direct labor, freight in. Nothing else."],
      ["Step 02", "Pull your quarterly revenue and actual COGS from your books.", "Not your best guess. Not last year's number × 1.1. Run the P&L for the quarter and use those exact figures."],
      ["Step 03", "Divide Gross Profit by Revenue. Multiply by 100 for percentage.", "That's your gross margin. Write it down. This is the only margin you should quote in pricing conversations."],
      ["Step 04", "Benchmark against your industry — not your gut.", "A healthy product business runs 35–50%. A healthy services business runs 50–70%. If you're below, the problem is pricing or COGS, not sales volume."],
      ["Step 05", "Track this monthly. Watch for seasonal swings and cost creep.", "Margins drift. A supplier raises prices 3%, a shipping lane adds a fee, a new hire is coded to COGS. Monthly tracking catches this before it compounds."],
    ],
    figures: [
      { k: "BENCHMARK", v: "22–35%", d: "healthy range, product biz" },
      { k: "FORMULA", v: "(R − C) / R", d: "Revenue, COGS" },
      { k: "WATCH", v: "±3%", d: "seasonal variance tolerance" },
    ],
    author: "Isabella",
    authorRole: "Small business — operator, three founded, two still running",
    authorBio: "Isabella has opened three businesses, closed one, and wrote the financial operating manuals for the other two. She's the person founders text at 11pm when the books don't tie.",
    more: [
      { t: "How to Read Your Own P&L Without an Accountant", read: "8 MIN" },
      { t: "How to Set Your S-Corp Reasonable Salary", read: "9 MIN" },
      { t: "How to Price Your Services Without Leaving Money on the Table", read: "8 MIN" },
    ],
    prev: { t: "How to Price Your Services Without Leaving Money on the Table", href: "#" },
    next: { t: "How to Read Your Own P&L Without an Accountant", href: "#" },
  },

  "quarterly-review": {
    lane: "personal",
    breadcrumb: ["PERSONAL", "FOUNDATIONS", "NET WORTH & TRACKING"],
    breadcrumbHrefs: ["/personal/", "/personal/foundations/", "/personal/foundations/net-worth-tracking/"],
    subcatPath: "/personal/foundations/net-worth-tracking/",
    subcatName: "Net Worth & Tracking",
    read: "6 MIN",
    title: "How to Run a 15-Minute Quarterly Money Review",
    sub: "You don't need a finance degree to catch what matters. You need a calendar reminder and a laptop.",
    lead: "Four things you look at, four times a year, on purpose. Monthly reviews get skipped. Quarterly is infrequent enough to stay on the calendar and frequent enough to catch the subscription you forgot, the balance that drifted, the rate that quietly doubled.",
    steps: [
      ["Step 01", "Put the review on the calendar before you close this tab.", "First Saturday after each quarter ends — January, April, July, October. Coffee, laptop, fifteen minutes, done before brunch. Schedule the next one before you close the session."],
      ["Step 02", "Checking — scroll back to the start of the quarter.", "Two things only. Recurring charges you do not recognize or do not want — cancel them from your phone before closing the tab. And the shape of your average balance — trending up, flat, or leaking down. Four minutes."],
      ["Step 03", "Credit cards — every card you use.", "Total owed across all cards, start of quarter to end. Growing on purpose is fine. Growing by accident is not. Look at the interest line, not just the minimum payment — it is what the card is actually costing you. Three minutes."],
      ["Step 04", "Savings and investments — everything that is supposed to go up.", "Did each account move in the direction you meant? If you contribute monthly and the balance dropped, is that the market or did your contribution stop? The math on an automated contribution is predictable. If the number is off, something is off. Four minutes."],
      ["Step 05", "Write down one number you are tracking.", "Total savings, debt-to-income, months of expenses, net worth — pick one and log it every quarter. Trends are more useful than snapshots and you can only see them if you write the number down. Ninety seconds. Do not skip it."],
    ],
    figures: [
      { k: "CADENCE", v: "4× / YR", d: "Jan · Apr · Jul · Oct" },
      { k: "TIME", v: "15 MIN", d: "per review, one sitting" },
      { k: "LEAK EX.", v: "$89 / MO", d: "forgotten subscription, 3 yrs" },
    ],
    author: "Johnnie",
    authorRole: "Personal finance — formerly retail trading desk, Chicago",
    authorBio: "Johnnie spent a decade on a retail trading desk before walking away to write for people who were never meant to read a 10-K. He answers the money questions you're a little embarrassed to ask.",
    more: [
      { t: "How to Build a 3-Month Emergency Fund", read: "6 MIN" },
      { t: "How to Pick Your First HYSA Without Going Down a Rabbit Hole", read: "5 MIN" },
      { t: "How to Track Net Worth Over Time Without Spreadsheet Hell", read: "5 MIN" },
    ],
    prev: { t: "How to Calculate Your Real Net Worth (Assets, Not Vibes)", href: "#" },
    next: { t: "How to Read a Bank Statement Like It's a Map", href: "#" },
  },

  "hysa": {
    lane: "personal",
    breadcrumb: ["PERSONAL", "BANKING", "ACCOUNT TYPES"],
    breadcrumbHrefs: ["/personal/", "/personal/banking/", "/personal/banking/account-types/"],
    subcatPath: "/personal/banking/account-types/",
    subcatName: "Account Types",
    read: "5 MIN",
    title: "How to Pick Your First HYSA Without Going Down a Rabbit Hole",
    sub: "The difference between the best rate and the tenth-best rate is smaller than you think. The difference between having one and not having one is the whole story.",
    lead: "A high-yield savings account pays you a real rate — 3% to 5% depending on the year — on money that would otherwise sit in a checking account earning nothing. FDIC-insured, liquid, boring. The research rabbit hole is a trap. Here is the ten-minute version.",
    steps: [
      ["Step 01", "Search \"best high yield savings account 2026\" and open three or four from one reputable source.", "NerdWallet, Bankrate, Investopedia — pick one. Do not open twelve tabs across six sources. The list from one good source is the list."],
      ["Step 02", "Eliminate anything more than 0.5% below the top rate.", "Within half a percent of the leader, you are fine. Chasing the last ten basis points on a $20,000 balance is optimizing for ten dollars a month. Do chase the first two hundred basis points."],
      ["Step 03", "Check the app-store rating. Eliminate anything below 4 stars.", "You are going to move money in and out of this account. A one-star app with a thousand reviews about crashes matters more than the rate. Read the reviews before you open the account."],
      ["Step 04", "Pick the one that is easiest to link to your existing checking.", "Same bank as checking means instant, free transfers. Different bank means one-to-two-day ACH. Neither is wrong — you just want to know which you are doing before the emergency, not during."],
      ["Step 05", "Open it. Transfer a test amount. Close the tabs.", "The real mistake is not which one you picked. It is not opening one at all. Best HYSA is the one you open today; second-best is the one you open tomorrow. There is no twelfth-best."],
    ],
    figures: [
      { k: "YIELD EX.", v: "$400", d: "$10,000 at 4% APY, 1 year" },
      { k: "RATE GAP", v: "≤ 0.5%", d: "acceptable spread from top" },
      { k: "DECISION", v: "10 MIN", d: "from tab to funded account" },
    ],
    author: "Johnnie",
    authorRole: "Personal finance — formerly retail trading desk, Chicago",
    authorBio: "Johnnie spent a decade on a retail trading desk before walking away to write for people who were never meant to read a 10-K. He answers the money questions you're a little embarrassed to ask.",
    more: [
      { t: "How to Build a 3-Month Emergency Fund", read: "6 MIN" },
      { t: "How to Run a 15-Minute Quarterly Money Review", read: "6 MIN" },
      { t: "How to Pair a HYSA With Your Main Bank", read: "4 MIN" },
    ],
    prev: { t: "How to Choose a Checking Account in 2026", href: "#" },
    next: { t: "How to Pair a HYSA With Your Main Bank", href: "#" },
  },

  "scorp-salary": {
    lane: "business",
    breadcrumb: ["BUSINESS", "ENTITY", "S-CORP & C-CORP"],
    breadcrumbHrefs: ["/business/", "/business/entity/", "/business/entity/s-corp-c-corp/"],
    subcatPath: "/business/entity/s-corp-c-corp/",
    subcatName: "S-Corp & C-Corp",
    read: "9 MIN",
    title: "How to Set Your S-Corp Reasonable Salary",
    sub: "The IRS has a position. Your accountant has a position. You need to know both.",
    lead: "The S-corp reasonable salary is the single most-audited question in small-business tax — not because the rule is complicated, but because it is fuzzy and the incentive to break it is large. The IRS does not publish a formula; they publish a framework. Here is how to set a number that is defensible.",
    steps: [
      ["Step 01", "Identify the primary work you actually do, not your title.", "Are you the electrician who owns the electrical company, or the operator who manages crews? Most owners are a mix. Estimate the percentage of your time on the trade versus on running the business. This split is the backbone of the whole calculation."],
      ["Step 02", "Pull market salary data for that work in your area.", "Bureau of Labor Statistics Occupational Employment Statistics (oews.bls.gov) is the standard source. Salary.com and Glassdoor are secondary. Get three data points for the trade rate and three for the management rate."],
      ["Step 03", "Adjust for your experience, then blend the two rates.", "Fifteen years in the trade moves you toward the top of the range; two years stays near the bottom. Calculate: (percent of time on trade × trade rate) + (percent of time on management × management rate). That blended number is your anchor."],
      ["Step 04", "Sanity-check against the business and the IRS factor list.", "The salary should be a meaningful portion of what the business produced, not a token. The IRS looks at nine factors including training, duties, dividend history, comparable pay, and whether you have a written compensation agreement. Your number should be defensible on every one."],
      ["Step 05", "Document the methodology in a one-page memo to your file.", "Date it. Keep it. \"That is what my accountant told me to pay\" is not a defense. \"BLS OES data for a licensed electrician in my metro, blended 70/30 trade/management, adjusted for fifteen years of experience\" is a defense. Revisit the number every year."],
    ],
    figures: [
      { k: "RANGE", v: "$60–85K", d: "typical 1-owner, $200K–$500K rev" },
      { k: "PAYROLL TAX", v: "15.3%", d: "up to SS wage base; +2.9% Medicare" },
      { k: "IRS FACTORS", v: "9", d: "reasonable-comp evaluation framework" },
    ],
    author: "Isabella",
    authorRole: "Small business — operator, three founded, two still running",
    authorBio: "Isabella has opened three businesses, closed one, and wrote the financial operating manuals for the other two. She's the person founders text at 11pm when the books don't tie.",
    more: [
      { t: "How to Read Your Own P&L Without an Accountant", read: "8 MIN" },
      { t: "How to Calculate Your Real Profit Margin", read: "8 MIN" },
      { t: "How to Elect S-Corp Status for Your LLC", read: "6 MIN" },
    ],
    prev: { t: "How to Elect S-Corp Status for Your LLC", href: "#" },
    next: { t: "How to Run Payroll for a Single-Owner S-Corp", href: "#" },
  },

  "read-pl": {
    lane: "business",
    breadcrumb: ["BUSINESS", "ACCOUNTING", "READING THE BOOKS"],
    breadcrumbHrefs: ["/business/", "/business/accounting/", "/business/accounting/reading-the-books/"],
    subcatPath: "/business/accounting/reading-the-books/",
    subcatName: "Reading the Books",
    read: "8 MIN",
    title: "How to Read Your Own P&L Without an Accountant",
    sub: "Your accountant builds the statement. You have to know what it says.",
    lead: "Every P&L has three sections — Revenue, Cost of Goods Sold, Operating Expenses — and seven numbers that actually matter. Read those seven in order and ask one question at each line. You do not need a finance degree. You need the discipline to look.",
    steps: [
      ["Step 01", "Revenue — is this what I expected?", "The easy number. It is what you sold, net of refunds. Compare it to last quarter, last year, and the quarter you thought you were going to have. Revenue is a fact; the rest of the statement tells you what the fact cost."],
      ["Step 02", "COGS — is this line growing faster than revenue?", "Cost of Goods Sold is only what it cost to deliver the specific work you sold — materials, direct labor, freight in. Software, rent, your salary — not COGS. If COGS is creeping up relative to revenue, either costs are rising or pricing is falling behind."],
      ["Step 03", "Gross Profit Margin — am I making enough on each job to run the business?", "Gross Profit ÷ Revenue × 100. This is the single best indicator of whether you are pricing correctly. A contracting business at 35% is in a very different position than one at 18%. If your P&L does not show this line, calculate it yourself."],
      ["Step 04", "Operating Expenses — have these grown without the business growing?", "Rent, insurance, software, marketing, your salary, utilities. This is where the leaks live. Software subscriptions you forgot, insurance that renewed high, payroll that grew when you hired. Individually fine, collectively the reason revenue rises and profit does not."],
      ["Step 05", "Net Income — given what I just saw, is this number explainable?", "Look at the bottom number last. Net Profit Margin = Net Income ÷ Revenue. Below 3% for two quarters in a row is not a cushion — it is a warning. No bad month, lawsuit, or insurance claim survives 3%."],
    ],
    figures: [
      { k: "LINES", v: "7", d: "numbers that matter on every P&L" },
      { k: "TIME", v: "15 MIN / MO", d: "full read, top to bottom" },
      { k: "MARGIN FLOOR", v: "3%", d: "below this, fragile for two quarters" },
    ],
    author: "Isabella",
    authorRole: "Small business — operator, three founded, two still running",
    authorBio: "Isabella has opened three businesses, closed one, and wrote the financial operating manuals for the other two. She's the person founders text at 11pm when the books don't tie.",
    more: [
      { t: "How to Calculate Your Real Profit Margin", read: "8 MIN" },
      { t: "How to Set Your S-Corp Reasonable Salary", read: "9 MIN" },
      { t: "How to Reconcile Your Books Every Month Without Losing a Weekend", read: "7 MIN" },
    ],
    prev: { t: "How to Reconcile Your Books Every Month Without Losing a Weekend", href: "#" },
    next: { t: "How to Read a Balance Sheet in 10 Minutes", href: "#" },
  },
};

function GuideBreadcrumbs({ g }) {
  const hrefs = g.breadcrumbHrefs || [];
  return (
    <div className="crumbs">
      <div className="crumbs__inner">
        <a href="/" className="crumbs__item">HOME</a>
        {g.breadcrumb.map((label, i) => (
          <React.Fragment key={label}>
            <span className="crumbs__sep">/</span>
            <a href={hrefs[i] || "/"} className="crumbs__item">{label}</a>
          </React.Fragment>
        ))}
        <span className="crumbs__sep">/</span>
        <a className="crumbs__item" style={{color: "var(--forest-ink)"}}>{g.read}</a>
        <span className="crumbs__spacer" />
        <span className="crumbs__stats">
          <span>ISSUE</span><span className="crumbs__val">038</span>
          <span>·</span>
          <span>FILED</span><span className="crumbs__val">04.18.26</span>
          <span>·</span>
          <span>BY</span><span className="crumbs__val">{g.author.toUpperCase()}</span>
        </span>
      </div>
    </div>
  );
}

function GuideHero({ g }) {
  return (
    <section className="ghero">
      <div className="ghero__bg" aria-hidden="true" />
      <div className="ghero__inner">
        <div className="ghero__meta">
          <span className="ghero__num">{g.lane === "personal" ? "01" : "02"}</span>
          <span className="ghero__bar" />
          <span className="ghero__label">{g.breadcrumb.join(" · ")}</span>
          <span className="ghero__dot">·</span>
          <span>{g.read}</span>
          <span className="ghero__dot">·</span>
          <span>FILED BY {g.author.toUpperCase()}</span>
        </div>
        <h1 className="ghero__h1">{g.title}</h1>
        <p className="ghero__sub">{g.sub}</p>
      </div>
    </section>
  );
}

function GuideBody({ g }) {
  return (
    <section className="gbody">
      <div className="gbody__grid">
        <article className="gbody__main">
          <div className="gbody__kicker">
            <span className="bar"/> ARTICLE PREVIEW · PROCEDURE
          </div>
          <p className="gbody__lead">{g.lead}</p>

          <ol className="gbody__steps">
            {g.steps.map((s, i) => (
              <li key={i} className="gstep">
                <div className="gstep__num">{s[0]}</div>
                <div className="gstep__body">
                  <h3 className="gstep__h">{s[1]}</h3>
                  <p className="gstep__p">{s[2]}</p>
                </div>
              </li>
            ))}
          </ol>

          <div className="gbody__pull">
            <div className="gbody__pull-k">THE ONE-SENTENCE ANSWER</div>
            <p>{g.lead}</p>
          </div>

          <div className="gbody__actions">
            <button className="btn btn--primary">READ FULL GUIDE →</button>
            <button className="btn btn--ghost">SAVE TO LIBRARY</button>
            <span className="gbody__sharekey">SHARE · ⌘ S</span>
          </div>

          <div className="gbody__strip">
            <div className="gbody__strip-l">
              <span className="gbody__strip-k">ALSO IN THIS PROCEDURE</span>
              <span className="gbody__strip-v">05 STEPS · {g.figures.length} KEY FIGURES · {g.read}</span>
            </div>
            <div className="gbody__strip-r">
              <span className="gbody__strip-k">WRITER</span>
              <span className="gbody__strip-v">{g.author.toUpperCase()}</span>
            </div>
          </div>

          <nav className="gbody__nav">
            {leafUrl(g.prev.t) ? (
              <a href={leafUrl(g.prev.t)} className="gbody__nav-l">
                <span className="gbody__nav-k">← PREVIOUS</span>
                <span className="gbody__nav-t">{g.prev.t}</span>
              </a>
            ) : (
              <div className="gbody__nav-l">
                <span className="gbody__nav-k">← PREVIOUS</span>
                <span className="gbody__nav-t">{g.prev.t}</span>
              </div>
            )}
            {leafUrl(g.next.t) ? (
              <a href={leafUrl(g.next.t)} className="gbody__nav-r">
                <span className="gbody__nav-k">NEXT GUIDE →</span>
                <span className="gbody__nav-t">{g.next.t}</span>
              </a>
            ) : (
              <div className="gbody__nav-r">
                <span className="gbody__nav-k">NEXT GUIDE →</span>
                <span className="gbody__nav-t">{g.next.t}</span>
              </div>
            )}
          </nav>
        </article>

        <aside className="gbody__side">
          <div className="gfigs">
            <div className="gfigs__k">KEY FIGURES</div>
            <div className="gfigs__sub">04.18.26 · {g.breadcrumb[1]}</div>
            {g.figures.map((f, i) => (
              <div key={i} className="gfig">
                <div className="gfig__k">{f.k}</div>
                <div className="gfig__v">{f.v}</div>
                <div className="gfig__d">{f.d}</div>
              </div>
            ))}
            <div className="gfigs__foot">
              <span>SOURCED FROM</span>
              <span className="gfigs__foot-v">HOWTO · LIVE INDEX</span>
            </div>
          </div>

          <div className="gside-block">
            <div className="gside-block__k">MORE FROM {g.author.toUpperCase()} THIS WEEK</div>
            <ul>
              {g.more.map((m, i) => {
                const url = leafUrl(m.t);
                const Inner = url ? "a" : "div";
                const innerProps = url ? { href: url } : {};
                return (
                  <li key={m.t}>
                    <Inner {...innerProps}>
                      <span className="gside-block__idx">{String(i + 1).padStart(2, "0")}</span>
                      <div>
                        <div className="gside-block__t">{m.t}</div>
                        <div className="gside-block__r">{m.read}</div>
                      </div>
                    </Inner>
                  </li>
                );
              })}
            </ul>
          </div>

          <div className="gside-block gside-block--mint">
            <div className="gside-block__k" style={{color: "var(--forest-ink)"}}>NEXT STEP</div>
            <p>Think you've got it? Run the procedure once, then hit the next guide.</p>
            {leafUrl(g.next.t) ? (
              <a href={leafUrl(g.next.t)} className="gside-block__cta">{g.next.t} →</a>
            ) : (
              <span className="gside-block__cta">{g.next.t} →</span>
            )}
          </div>
        </aside>
      </div>
    </section>
  );
}

function GuideAuthor({ g }) {
  const isP = g.lane === "personal";
  return (
    <section className={`gauthor gauthor--${g.lane}`}>
      <div className="gauthor__inner">
        <div className={`gauthor__pic gauthor__pic--${g.lane}`} style={{position: "relative", overflow: "hidden"}}>
          <img src={`/contributors/${g.author.toLowerCase()}.png`} alt={g.author} style={{position: "absolute", inset: 0, width: "100%", height: "100%", objectFit: "cover"}} />
        </div>
        <div className="gauthor__body">
          <div className="gauthor__kicker">
            <span className="bar"/> ABOUT THE WRITER · {g.lane.toUpperCase()} LANE
          </div>
          <h3 className="gauthor__name">{g.author}</h3>
          <div className="gauthor__role">{g.authorRole}</div>
          <p className="gauthor__bio">{g.authorBio}</p>
          <dl className="gauthor__creds">
            <div><dt>GUIDES</dt><dd>{isP ? "312" : "218"}</dd></div>
            <div><dt>YEARS</dt><dd>{isP ? "12" : "9"}</dd></div>
            <div><dt>REVIEWED</dt><dd>{isP ? "1,284" : "864"}</dd></div>
            <div><dt>LANE</dt><dd>{g.lane.toUpperCase()}</dd></div>
          </dl>
          <div className="gauthor__actions">
            <button className="btn btn--primary">
              VIEW ALL GUIDES BY {g.author.toUpperCase()} →
            </button>
            <button className="btn btn--ghost">{g.author.toUpperCase()}'S PROFILE</button>
          </div>
        </div>
      </div>
    </section>
  );
}

function GuideNav({ g }) {
  const nextUrl = leafUrl(g.next.t);
  return (
    <section className="gnav">
      <div className="gnav__inner">
        <a href={g.subcatPath} className="gnav__back">
          <span className="gnav__arr">←</span> BACK TO {g.subcatName.toUpperCase()}
        </a>
        {nextUrl ? (
          <a href={nextUrl} className="gnav__next">
            NEXT GUIDE: {g.next.t} <span className="gnav__arr">→</span>
          </a>
        ) : (
          <span className="gnav__next">
            NEXT GUIDE: {g.next.t} <span className="gnav__arr">→</span>
          </span>
        )}
      </div>
    </section>
  );
}

function GuideApp() {
  const key = window.GUIDE || "emergency-fund";
  const g = GUIDE_META[key];
  const [tweaksOpen, setTweaksOpen] = React.useState(false);

  React.useEffect(() => {
    const handler = (e) => {
      if (!e.data) return;
      if (e.data.type === "__activate_edit_mode") setTweaksOpen(true);
      if (e.data.type === "__deactivate_edit_mode") setTweaksOpen(false);
    };
    window.addEventListener("message", handler);
    window.parent.postMessage({ type: "__edit_mode_available" }, "*");
    return () => window.removeEventListener("message", handler);
  }, []);

  React.useEffect(() => {
    const tick = () => {
      const now = new Date();
      const hh = String(now.getHours()).padStart(2, "0");
      const mm = String(now.getMinutes()).padStart(2, "0");
      const ss = String(now.getSeconds()).padStart(2, "0");
      const clock = document.getElementById("tickerClock");
      if (clock) clock.textContent = `NYC · ${hh}:${mm}:${ss}`;
      const fsess = document.getElementById("fsess");
      if (fsess) fsess.textContent = `${hh}${mm}.${ss}`;
    };
    tick();
    const id = setInterval(tick, 1000);
    return () => clearInterval(id);
  }, []);

  return (
    <div className="site" data-lane={g.lane}>
      <Ticker />
      <Nav lane={g.lane} setLane={() => {}} />
      <GuideBreadcrumbs g={g} />
      <GuideHero g={g} />
      <GuideBody g={g} />
      <GuideAuthor g={g} />
      <GuideNav g={g} />
      <NetworkBand />
      <Footer />

      <div className={`tweaks ${tweaksOpen ? "is-open" : ""}`}>
        <div className="tweaks__head">
          <span>GUIDE · {g.lane.toUpperCase()}</span>
          <button onClick={() => setTweaksOpen(false)} style={{color: "var(--pistachio)"}}>✕</button>
        </div>
        <div className="tweaks__body">
          <div>
            <span className="tweaks__k">THIS IS A LEAF PAGE</span>
            <p style={{fontSize: "10px", color: "var(--pistachio)", margin: 0, lineHeight: 1.5, letterSpacing: "0.08em"}}>
              SWITCH FILES TO VIEW THE OTHER LANE · PERSONAL = EMERGENCY FUND · BUSINESS = PROFIT MARGIN
            </p>
          </div>
        </div>
        <div className="tweaks__foot">FINANCE · GUIDE</div>
      </div>
    </div>
  );
}

Object.assign(window, { GUIDE_META, GuideBreadcrumbs, GuideHero, GuideBody, GuideAuthor, GuideNav });
ReactDOM.createRoot(document.getElementById("root")).render(<GuideApp />);
