const { useState, useEffect, useRef, useMemo } = React;
/*
═══════════════════════════════════════════════════════════════
ECONOMIC BRIEFING v7 — maysoonsalah.co
ARCHITECTURE:
1. Gate (brand dark theme, request access + login)
2. Report header + date
3. Global Overview (always visible — narrative + key numbers)
4. Tabs (both public & private — jump to sections)
5. Section content
6. Disclaimer footer
═══════════════════════════════════════════════════════════════
*/
// ─── BRAND ───────────────────────────────────────
const B = {
  caviar: "#2c2f32", surface: "#353840", wasabi: "#e9f056",
  sage: "#d7e8bc", border: "rgba(215,232,188,0.10)",
  glow: "rgba(233,240,86,0.08)", aborder: "rgba(233,240,86,0.15)",
  sageMuted: "rgba(215,232,188,0.55)", sageDim: "rgba(215,232,188,0.3)",
};
// ─── USERS (hashed) ──────────────────────────────
const USERS = [
  { hash: "cf4ac2c66d7f78631357379dca0f4bf8122fa4c065e32956f38ddc76cd1adbe6", name: "Maysoon", role: "private" },
  { hash: "0523ba6453494f05859f9172b3bad9882ac8455f86bd22b554ae7c59cd2eacf4", name: "Erik", role: "public" },
  { hash: "0861d63e2958de42b81feeef4dc5197484e4514277343ea58b7ea63dab30f50e", name: "Cendejas", role: "public" },
  { hash: "952d57fa55abc0d97f16f85d9235aad2f0cbf0d7bd5438cb69b781a014f41c3a", name: "Lubna", role: "public" },
  { hash: "60198c69ad30ec36d590740bf4e588a3e52a1a392c3031fb695ed57b2e539496", name: "Angie", role: "public" },
  { hash: "3f9af3f52e5caa53a27c84710dad4d947e628fdc151ecfd40673d2d0926b3028", name: "Jojo", role: "public" },
];
async function hashPw(s) {
  const b = await crypto.subtle.digest("SHA-256", new TextEncoder().encode(s));
  return Array.from(new Uint8Array(b)).map(x => x.toString(16).padStart(2, "0")).join("");
}
async function auth(code) { const h = await hashPw(code); const u = USERS.find(x => x.hash === h); return u ? { name: u.name, role: u.role } : null; }
function track(user) { try { const k = "eb_log"; const l = JSON.parse(localStorage.getItem(k) || "[]"); l.push({ name: user.name, role: user.role, ts: new Date().toISOString() }); localStorage.setItem(k, JSON.stringify(l)); } catch {} }
function saveReq(d) { try { const k = "eb_req"; const l = JSON.parse(localStorage.getItem(k) || "[]"); l.push({ ...d, ts: new Date().toISOString() }); localStorage.setItem(k, JSON.stringify(l)); } catch {} }
function getLogs() { try { return JSON.parse(localStorage.getItem("eb_log") || "[]"); } catch { return []; } }
function getReqs() { try { return JSON.parse(localStorage.getItem("eb_req") || "[]"); } catch { return []; } }
// ─── DATA (Perplexity-verified March 20, 2026) ──
const D = {
  meta: {
    date: "March 20, 2026", updated: "2026-03-20T10:30:00-04:00",
    next: "After Iran ceasefire developments or employment update",
  },
  // ── GLOBAL OVERVIEW (always visible) ──
  overview: {
    headline: "Oil shock rewrites the playbook",
    narrative: [
      "Three weeks into the U.S.–Israel war with Iran, the global economy is navigating its most significant energy disruption since the 1970s Arab embargo. The Strait of Hormuz — through which 20% of the world's oil flows — remains effectively closed. Oil has surged from $70 to a volatile $96–$110 range, with some analysts now pricing in $150–$200 if the conflict extends through Q2.",
      "The ripple effects are everywhere. Gas prices are up nearly a dollar since February. The Fed held rates steady this week, trapped between rising inflation and a weakening job market — February payrolls fell 92,000. Goldman Sachs raised its recession probability to 25%. JPMorgan cut its S&P 500 year-end target to 7,200. The S&P has hit new 2026 closing lows. That said, the Sahm Rule recession indicator sits at 0.27 — well below the 0.50 trigger — suggesting an economy with elevated uncertainty rather than one already in a classic contraction.",
      "For risk assets, the damage is real but the contrarian signal is loud. Crypto's Fear & Greed Index has spent 46 consecutive days in extreme fear territory — the longest since FTX. Bitcoin is down 32% from its all-time high but has actually outperformed the S&P 500, Nasdaq, and gold since the war began. Institutional inflows of $2.7B over three weeks suggest smart money is accumulating while retail capitulates.",
      "In Florida real estate, the picture is nuanced. Mortgage rates remain stable near 6.1%, but higher gas, construction costs, and insurance premiums are squeezing affordability. The Treasure Coast at $214–$277 per square foot remains 30–55% cheaper than Palm Beach, Broward, and Miami-Dade — a gap that continues to drive northward migration from buyers priced out of South Florida. Port St. Lucie builders are offering up to $20,000 in concessions and 4.99% promotional financing. The likely near-term effect is not a collapse, but a wider gap between well-priced homes with incentives and overpriced listings that linger.",
    ],
    keyNumbers: [
      { label: "Recession Odds", value: "25–35%", delta: "↑ from 10–20% pre-war", color: "#b5706b" },
      { label: "Sahm Rule", value: "0.27", delta: "Below 0.50 trigger", color: "#7a9e7e" },
      { label: "Oil (WTI)", value: "$96", delta: "↑ from $70 pre-war", color: "#b5706b" },
      { label: "Bitcoin", value: "$69,513", delta: "−32% from ATH", color: "#b5706b" },
      { label: "30-Yr Mortgage", value: "6.11%", delta: "Stable", color: "#c4a35a" },
      { label: "Fear & Greed", value: "23", delta: "46 days extreme fear", color: "#b5706b" },
    ],
    warStatus: { day: 20, status: "Active — Escalating", items: [
      "U.S. & Israel struck Iran's South Pars gas field — world's largest natural gas reserve",
      "Iran threatening energy infrastructure across Saudi Arabia, UAE, and Qatar",
      "Strait of Hormuz effectively closed — shipping at a standstill",
      "IEA released 400M barrels from emergency reserves — largest coordinated action ever",
      "Gas prices up ~$0.90 nationally since February 28 — now averaging $3.89",
      "Analysts modeling $150–$200 oil if conflict extends through Q2",
    ]},
  },
  // ── TAB: MACRO ──
  macro: [
    { name: "GDP Growth", val: "2.4%", trend: "→", sig: "n", note: "Fed projection — solid but threatened by oil" },
    { name: "Unemployment", val: "4.4%", trend: "↑", sig: "n", note: "Feb payrolls fell 92K — sluggish but not collapsing" },
    { name: "Sahm Rule", val: "0.27", trend: "→", sig: "pos", note: "Well below 0.50 recession trigger" },
    { name: "Inflation (PCE)", val: "2.7%", trend: "↑", sig: "neg", note: "Fed revised up from 2.4% — oil driven" },
    { name: "Fed Rate", val: "3.50–3.75%", trend: "→", sig: "n", note: "Held steady — one cut projected for late 2026" },
    { name: "S&P 500", val: "6,594", trend: "↓", sig: "neg", note: "New 2026 lows — JPM target cut to 7,200" },
    { name: "VIX", val: "25.75", trend: "↑", sig: "n", note: "Elevated — not panic but rising" },
    { name: "10Y Treasury", val: "4.275%", trend: "↑", sig: "n", note: "Inflation expectations rising" },
  ],
  recProb: { pct: 28, label: "Elevated", sources: [{ n: "Goldman Sachs", v: 25, d: "Mar 12" }, { n: "J.P. Morgan", v: 35, d: "Q1 '26" }, { n: "Polymarket", v: 31, d: "Mar 19" }, { n: "Kalshi", v: 32, d: "Mar 19" }], body: "Oil shock is the primary driver — pre-war odds were 10–20%. However, the Sahm Rule at 0.27 (below the 0.50 trigger), stable initial claims, and low layoffs suggest elevated uncertainty rather than confirmed recession. The economy is cautious, not contracting." },
  // ── TAB: CRYPTO ──
  crypto: {
    fg: 23, fgLabel: "Extreme Fear", fgDays: 46,
    coins: [
      { name: "Bitcoin", price: 69513, chg: -2.7, ath: 103000, dd: -32.5, short: "Bearish short-term — oil shock pulling capital from risk assets across the board", long: "BTC has outperformed S&P 500, Nasdaq, and gold since the war began. Extreme fear windows have historically produced +38% median 90-day returns." },
      { name: "Ethereum", price: 2122, chg: -6.0, ath: 4946, dd: -57.1, short: "Selling intensifying — Buterin sales + supply growing at 0.23% annually weighed on sentiment", long: "Standard Chartered targets $10K–$40K long-term. Glamsterdam upgrade expected by May 2026." },
    ],
    events: [
      "Citi cut BTC target to $112K, ETH to $3,175 — slower ETF flows, stalled U.S. legislation",
      "46 consecutive days in extreme fear — longest since FTX collapse (Nov 2022)",
      "Institutional inflows of $2.7B over 3 weeks — smart money accumulating while retail sells",
      "BTC outperforming equities and gold since war began despite headline drawdown",
    ],
    moves: [
      "Do not add crypto positions without stable income — protect your 3-month runway first",
      "If holding BTC or ETH, hold — extreme fear is historically a buy signal, not a sell signal",
      "When income stabilizes, DCA weekly or biweekly over 8–12 weeks — staged buying beats lump-sum timing in fear periods",
      "Reserve a slightly larger final tranche for deeper drawdowns — the main risk is buying too early in a still-falling tape",
      "Never skip buys because sentiment is still fearful — the point of DCA is removing the need to guess the bottom",
      "Watch for Strait of Hormuz reopening — the primary risk-on catalyst for all markets",
    ],
  },
  // ── TAB: REAL ESTATE (Perplexity-verified) ──
  re: {
    nat: { r30: "6.11%", r15: "5.45%", med: "$405K", yoy: "−1.2%", inv: 5.2 },
    subs: [
      { county: "St. Lucie", area: "Fort Pierce / PSL", sqft: "$214", med: "$395K", yoy: "−2.5%", dom: "94", sig: "n", note: "Buyer-friendly — up to $20K builder concessions, 4.99% promo rates" },
      { county: "Indian River", area: "Vero Beach / Sebastian", sqft: "$221", med: "$394K", yoy: "−2.6%", dom: "54", sig: "n", note: "Cooling slightly — still tighter than St. Lucie" },
      { county: "Martin", area: "Stuart / Jensen Beach", sqft: "$277", med: "$434K", yoy: "−5.05%", dom: "71", sig: "neg", note: "Sharpest YoY decline in the region — luxury softening" },
      { county: "Palm Beach", area: "West Palm / Jupiter", sqft: "$299", med: "$595K", yoy: "−5.4%", dom: "48", sig: "neg", note: "Down most YoY — but $1M+ segment still strong" },
      { county: "Broward", area: "Fort Lauderdale", sqft: "$309", med: "$520K", yoy: "−3.88%", dom: "52", sig: "n", note: "Condo oversupplied — insurance $10K+ in coastal areas" },
      { county: "Miami-Dade", area: "Miami / Homestead", sqft: "$468", med: "$580K", yoy: "flat", dom: "44", sig: "n", note: "Cash buyers keeping prices sticky — $1M+ at all-time highs" },
    ],
    insurance: [
      { county: "Miami-Dade", avg: "$5,391", city: "Miami — varies widely" },
      { county: "Palm Beach", avg: "$5,247", city: "West Palm Beach $8,618" },
      { county: "Broward", avg: "$5,164", city: "Fort Lauderdale $10,917 · Hollywood $11,250" },
      { county: "Martin", avg: "$4,756", city: "Stuart — moderate" },
      { county: "St. Lucie", avg: "Lower", city: "Port St. Lucie — generally less extreme than south" },
    ],
    newConstruction: {
      tcMedianSqft: "$243",
      tcMedianPrice: "$478,708",
      fpMedianListing: "$299,000",
      fpDom: "94 days",
      pslConcessions: "Up to $20,000",
      pslPromoRate: "4.99%",
      trend: "1.8% month-over-month softening — buyer-friendly window",
    },
    local: { market: "Fort Pierce & Treasure Coast", range: "$365K–$415K", yoy: "−2.5%", dom: "62–94", lev: 7, trends: [
      "Buyer-friendly — elevated inventory, builders competing with $20K+ concessions and sub-5% promo rates",
      "Insurance costs less extreme than Broward/PBC but still climbing — factor into total housing cost",
      "Wylder actively selling across multiple neighborhoods ($250K–$1M+) — Glynlea Country Club opening with Perry Homes",
      "Mortgage rates stable near 6.1% — oil shock could push them either way depending on inflation vs recession",
      "Northward migration confirmed: affordability-seeking buyers from Miami-Dade and Broward driving middle-market demand",
      "Oil shock impact: not a collapse, but a wider gap between well-priced homes with incentives and overpriced listings that linger",
    ]},
    moves: [
      "Treasure Coast at $214–$277/sqft vs $299–$468 in PBC through Miami-Dade — 30–55% discount",
      "Migration north is real but concentrated in the middle market — luxury still supported by cash buyers in South Florida",
      "Builder incentives are the play right now: $20K concessions + 4.99% rates at PSL communities",
      "Insurance is the hidden killer: Broward coastal running $10K–$11K vs significantly less on the Treasure Coast",
      "Higher oil = higher construction input costs, which keeps new-build pricing sticky even as resale demand cools",
    ],
    home: { buy: 430000, now: 418000, delta: -12000, pct: -2.8, rec: "Mid-2027 at 3–5% annual appreciation" },
    privMoves: [
      "$12K dip is not cause for alarm — Treasure Coast fundamentals intact and migration trend supports recovery",
      "Perry Homes position is the highest-leverage move — Wylder buildout is multi-year with sustained demand",
      "Ask about employee purchase incentives if hired — many builders offer 2–5% discounts for staff",
      "Fort Pierce new construction at $299K median is well below your home's value — confirms your equity position in the market",
    ],
  },
  // ── TAB: INVESTMENT (Perplexity-verified) ──
  invest: {
    summary: "Bitcoin has outperformed equities and gold since the Iran war began, but its extreme drawdowns mean it should be sized as a speculative sleeve, not the whole plan. Gold offers crisis ballast. The S&P 500 is the most balanced growth engine at a discount. High-yield savings is the only option that prioritizes liquidity over upside — and with recession risk elevated, that liquidity matters.",
    tiers: [
      { name: "Foundation", alloc: "First priority — before any investing", items: [
        { a: "High-yield savings", t: "6 months expenses", w: "4.3–5% APY risk-free — acts as recession and oil-shock dry powder. This is not optional.", s: "pos" },
      ]},
      { name: "Core Growth", alloc: "~65% of investable capital", items: [
        { a: "S&P 500 Index (VOO/SPY)", t: "~40%", w: "Most balanced growth engine — currently at 2026 lows, which historically rewards patient buyers", s: "n" },
        { a: "Bitcoin (BTC)", t: "~25%", w: "Outperforming equities since war began. Extreme fear = historic entry window. DCA weekly over 8–12 weeks — do not lump sum.", s: "n" },
      ]},
      { name: "Hedges & Satellites", alloc: "~35% of investable capital", items: [
        { a: "Gold / GLD", t: "~20%", w: "Crisis ballast — despite the $322 single-day drop, gold has held value through the broader conflict and provides geopolitical hedge", s: "pos" },
        { a: "Ethereum (ETH)", t: "Small position", w: "Higher risk/reward — 57% off ATH, Glamsterdam upgrade coming. Only if BTC position is already established.", s: "n" },
        { a: "I-Bonds / TIPS", t: "Remainder", w: "Inflation protection at a time when PCE is rising on oil shock — real yield is positive at current rates", s: "pos" },
      ]},
    ],
    dcaNote: "For Bitcoin specifically: weekly or biweekly DCA over 8–12 weeks is the evidence-backed approach during extreme fear. Reserve a slightly larger final tranche for deeper drawdowns. Never skip scheduled buys because sentiment is still fearful — the entire point of DCA is removing the need to guess the bottom.",
    caveat: "This framework assumes income is stabilized and a six-month emergency fund is in place. Sequence matters — don't skip to satellite positions before the foundation is solid. With only three months of runway, the Foundation tier is the only appropriate current action.",
  },
  // ── TAB: COMMODITIES & ENERGY ──
  commodities: {
    narrative: "The Iran war has turned energy and commodities into the most important market story of 2026. Oil is the epicenter, but the shock ripples through natural gas, gold, silver, and agricultural commodities via shipping disruptions through the Strait of Hormuz. Understanding these prices is critical because they directly feed into inflation, Fed policy, consumer spending, construction costs, and ultimately your real estate and crypto positions.",
    assets: [
      { name: "Oil (WTI Crude)", price: "$96", pre: "$70", chg: "+37%", trend: "↑↑↑", sig: "neg", context: "Was $70 pre-war. Spiked to $120 on March 9. Brent hit $110 after South Pars strike. IEA released 400M barrels but it's buying days, not weeks.", why: "Directly drives gas prices, inflation expectations, Fed policy freeze, and consumer spending. A sustained $100+ oil price historically tips economies into recession." },
      { name: "Brent Crude", price: "$103", pre: "$73", chg: "+41%", trend: "↑↑↑", sig: "neg", context: "Global benchmark. Dubai crude hit $150+, Oman crude above $152. Unprecedented $50+ spread between WTI and Asian benchmarks.", why: "The WTI-Brent-Dubai spread tells you Asia is running out of physical barrels. If Hormuz stays closed, Brent could test $130+." },
      { name: "Natural Gas", price: "Elevated", pre: "Stable", chg: "Spiking", trend: "↑↑", sig: "neg", context: "South Pars strike targeted the world's largest gas field, shared with Qatar. Qatar condemned the attack. Europe scrambling for LNG.", why: "Gas prices feed directly into electricity costs, construction input prices, and Florida housing affordability." },
      { name: "Gasoline (US Avg)", price: "$3.89/gal", pre: "$2.98/gal", chg: "+$0.91", trend: "↑↑", sig: "neg", context: "Largest monthly spike since Katrina. 11 states up more than $1/gallon. Arizona +$1.17, Kentucky +$1.07.", why: "Hits consumers hardest and fastest. Already affecting driving patterns, discretionary spending, and buyer urgency in housing." },
    ],
    oilScenarios: [
      { scenario: "Ceasefire within weeks", oil: "$70–$80", impact: "Rapid normalization. Crypto and equities rally hard. Housing demand rebounds. Best case." },
      { scenario: "Conflict drags through Q2", oil: "$100–$130", impact: "Sustained inflation pressure. Fed stays frozen. Consumer spending weakens. Housing slows. Moderate recession risk." },
      { scenario: "Hormuz closed 3+ months", oil: "$150–$200", impact: "Global demand destruction. Recession near-certain. All risk assets suffer except gold. Emergency reserves depleted." },
    ],
    moves: [
      "Do not try to trade oil directly — volatility is extreme and the WTI-Asia spread is unprecedented",
      "Higher gas prices directly reduce your 3-month runway — factor $150–$200/month more into burn rate",
      "Higher oil = higher construction input costs = sticky new-build pricing even as demand cools",
      "The oil scenario is binary: Hormuz reopens and everything normalizes, or it doesn't and we're in a fundamentally different environment",
    ],
  },
  // ── TAB: PRECIOUS METALS ──
  metals: {
    narrative: "Gold and silver operate on a different thesis than oil — they're crisis hedges, not crisis victims. The single-day $322 gold drop was a margin-call forced liquidation, not a loss of safe-haven status. Central banks globally continue accumulating. In the investment framework, precious metals at 20% of investable capital is the hedge designed specifically for the scenario we're currently living through.",
    assets: [
      { name: "Gold", price: "$4,569", pre: "$4,891 (recent high)", chg: "−$322 today", trend: "↓ (short-term)", sig: "n", context: "Dropped $322 in a single session — margin-call liquidation across asset classes. Still up significantly YTD. Central banks continue buying aggressively — China, India, Turkey, Poland all adding reserves.", why: "Gold is the geopolitical hedge. The single-day drop is forced selling, not a signal change. Every prior oil shock and Middle East conflict has eventually been bullish for gold." },
      { name: "Silver", price: "~$33", pre: "~$30", chg: "+~10%", trend: "↑", sig: "n", context: "Following gold broadly but also has industrial demand component — solar panels, electronics, EVs. Less liquid, more volatile, wider spreads.", why: "Double-edged: industrial demand means it's exposed to both geopolitical risk (bullish) and recession risk (bearish). A pure crisis hedge should prioritize gold first." },
    ],
    centralBanks: "Central bank gold purchases hit multi-decade highs in 2024–2025 and show no signs of slowing. China, India, Turkey, and Poland are the largest buyers. This structural demand provides a floor under gold prices that didn't exist in previous decades.",
    moves: [
      "Gold at ~20% of investable capital is the hedge for exactly this scenario — hold or add on forced-liquidation dips like today",
      "The $322 single-day drop is a buying opportunity for those with cash, not a sell signal — margin calls create temporary dislocations",
      "Silver is a secondary position — only after gold allocation is established. More volatile, less proven as a pure crisis hedge",
      "Physical gold vs. GLD ETF vs. mining stocks: GLD is simplest for most investors. Mining stocks add equity risk. Physical adds storage/insurance cost.",
      "Central bank buying provides structural floor — this isn't 2013 when institutions were selling. The bid underneath gold is stronger than at any point in decades.",
    ],
  },
  // ── TAB: AI & TECH (public market analysis + private income models) ──
  aiTech: {
    narrative: "AI remains the most significant structural growth story in the economy, even as the oil shock creates short-term headwinds. The question isn't whether AI spending continues — it's whether the current pace of infrastructure buildout justifies the valuations baked into the market. For investors, the AI trade has split into two camps: infrastructure (chips, data centers, power) and applications (SaaS, automation, agents).",
    indicators: [
      { name: "AI Infrastructure CapEx", value: "Accelerating", sig: "pos", detail: "Microsoft, Google, Amazon, and Meta collectively committed $200B+ in AI CapEx for 2025–2026. Spending is front-loaded and shows no signs of deceleration despite broader market weakness." },
      { name: "Chip Demand", value: "Strong but shifting", sig: "n", detail: "Nvidia Blackwell and Rubin chips in high demand. Micron earnings beat massively — revenue up 196% YoY. However, export restrictions to China and the oil shock's impact on Asian manufacturing create supply-chain uncertainty." },
      { name: "AI Hiring Trends", value: "Mixed", sig: "n", detail: "Companies are using AI to scale productivity rather than adding headcount — creating a 'no-hire, no-fire' equilibrium. AI engineering roles remain in high demand. Non-technical roles facing displacement." },
      { name: "AI Application Revenue", value: "Growing", sig: "pos", detail: "Enterprise AI adoption accelerating across legal, healthcare, finance, and real estate. Anthropic, OpenAI, and Google all expanding enterprise offerings. Revenue is real but concentrated in a few players." },
      { name: "Data Center Power", value: "Constraint", sig: "neg", detail: "AI data centers require massive energy — the oil shock makes this more expensive. Utilities like NextEra being re-rated as 'AI utilities.' Nuclear and carbon capture gaining policy support over renewables." },
      { name: "Regulation", value: "Uncertain", sig: "n", detail: "U.S. crypto legislation stalled but AI regulation still evolving. EU AI Act implementation ongoing. No near-term regulatory risk to core AI infrastructure spending." },
    ],
    stocks: [
      { name: "Nvidia (NVDA)", signal: "Dominant", note: "Controls ~80% of AI training chip market. Blackwell ramp strong. But valuation assumes perfection — any demand miss hits hard." },
      { name: "Micron (MU)", signal: "Breakout", note: "EPS $12.20 beat by $3.54. Revenue up 196% YoY. AI memory demand driving historic growth. Stock still dropped 5.6% on broader market selloff — the market is punishing everything." },
      { name: "Microsoft (MSFT)", signal: "Steady", note: "Azure AI revenue growing 50%+. Copilot adoption broadening. Most diversified AI play among mega-caps." },
      { name: "Alphabet (GOOGL)", signal: "Undervalued", note: "Gemini improving rapidly. Cloud AI growing. Trading at a discount to peers on search disruption fears that may be overblown." },
      { name: "Palantir (PLTR)", signal: "Speculative", note: "Government + enterprise AI platform. Revenue growing but valuation is aggressive. High beta — will move sharply with market sentiment." },
    ],
    chipIndex: "The SOX (Philadelphia Semiconductor Index) is down ~15% from its 2025 highs but up 40%+ over two years. Chip stocks are the infrastructure backbone of AI — they move first in any AI sentiment shift. If you believe AI spending continues, chip dips are historically good entries.",
    moves: [
      "AI infrastructure spending is the most resilient part of the market right now — these budgets are committed multi-year",
      "Don't chase individual AI stocks without a broader equity position (S&P 500 index) first — concentration risk applies here too",
      "Micron's earnings show AI memory demand is real, not hype — but the stock still dropped on broader fear. Sentiment > fundamentals right now.",
      "The 'AI utilities' thesis (data center power demand) is a sleeper play — NextEra and similar names are being re-rated",
      "Watch for the oil shock to impact AI CapEx timelines — higher energy costs could slow data center buildouts in Asia and Europe",
    ],
    // Private only — passive income models
    passiveIncome: {
      reality: "A few hundred to a few thousand dollars per month is the realistic starting range — not passive riches — unless you already have distribution. Treat viral screenshots with skepticism.",
      models: [
        { name: "Productized micro-SaaS", desc: "Small recurring-revenue tools solving specific problems. Your design skillset makes the UI/UX a competitive advantage. Real estate niche has clearer demand and shorter sales cycles.", potential: "$500–$3,000/mo after launch", timeline: "2–4 months to MVP" },
        { name: "Automated lead-gen tools", desc: "AI-powered buyer/seller matching, market report generators, or community comparison tools — directly tied to your real estate expertise.", potential: "$1,000–$5,000/mo with agent partnerships", timeline: "1–3 months leveraging existing work" },
        { name: "Niche content systems", desc: "Automated newsletter, market update, or social content pipelines. This economic briefing is already a prototype of this model.", potential: "$300–$2,000/mo from sponsorships or subscriptions", timeline: "1–2 months to systematize" },
      ],
      bestFit: "Your strongest play is automated lead-gen for real estate — you already have the report templates, the market knowledge, and the design skills. This economic briefing is proof of concept. Productize it.",
    },
  },
  // ── PRIVATE ONLY ──
  priorities: [
    { r: 1, act: "Land the Perry Homes position", why: "Eliminates runway risk, transforms the financial picture, and puts you inside the Treasure Coast's biggest active development", urg: "Now" },
    { r: 2, act: "Build emergency fund to six months", why: "Three months is thin with recession odds at 25–35% and oil shock ongoing. High-yield savings at 4.3–5% APY while you build.", urg: "Once employed" },
    { r: 3, act: "Diversify beyond 99% crypto", why: "Even though BTC is outperforming since the war, concentration risk during geopolitical crisis is dangerous. Target 40/25/20/15 split.", urg: "When cash frees up" },
    { r: 4, act: "Systematize this briefing as a lead-gen product", why: "You've already built the prototype. Automated market reports for agents and buyers = recurring revenue from your existing skills.", urg: "Parallel track" },
    { r: 5, act: "DCA into BTC over 8–12 weeks when income is stable", why: "Fear index at 23 is historically one of the best entry windows. Weekly buys, never skip, reserve a larger final tranche.", urg: "After priorities 1–2" },
  ],
};
// ─── UTILS ───────────────────────────────────────
const $ = n => n.toLocaleString("en-US", { style: "currency", currency: "USD", maximumFractionDigits: 0 });
const dc = s => s === "pos" ? "#7a9e7e" : s === "neg" ? "#b5706b" : "#c4a35a";
const ago = iso => { const h = Math.floor((Date.now() - new Date(iso).getTime()) / 3600000); return h < 1 ? "Just now" : h < 24 ? `${h}h ago` : `${Math.floor(h / 24)}d ago`; };
// ─── REPORT TOKENS ───────────────────────────────
const sf = "'Cormorant Garamond','Georgia',serif";
const sn = "'DM Sans','Helvetica Neue',sans-serif";
const cream = "#faf8f5"; const ink = "#1e1e1e"; const mt = "#8a847a"; const wh = "#b0a99e"; const rl = "#d5cfc6"; const alt = "#f5f2ed";
const sage = "#7a9e7e"; const amber = "#c4a35a"; const rose = "#b5706b";
// ═══════════════════════════════════════════════════
// GATE
// ═══════════════════════════════════════════════════
function Gate({ onUnlock }) {
  const [mode, setMode] = useState("request");
  const [pw, setPw] = useState(""); const [err, setErr] = useState(false); const [shake, setShake] = useState(false);
  const [done, setDone] = useState(false);
  const [form, setForm] = useState({ first: "", last: "", email: "", phone: "" });
  const [hov, setHov] = useState(null); const ref = useRef(null);
  useEffect(() => { if (mode === "login") ref.current?.focus(); }, [mode]);
  const login = async () => { const u = await auth(pw); if (u) { track(u); onUnlock(u); } else { setErr(true); setShake(true); setPw(""); setTimeout(() => setShake(false), 500); } };
  const request = () => { if (!form.first || !form.last || !form.email) return; saveReq(form); setDone(true); };
  return (
    <div style={{ minHeight: "100vh", background: B.caviar, fontFamily: sn, display: "flex", flexDirection: "column", color: B.sage }}>
      <style>{`@import url('https://fonts.googleapis.com/css2?family=Cormorant+Garamond:ital,wght@0,400;0,500;0,600;0,700;1,400;1,500&family=DM+Sans:ital,wght@0,300;0,400;0,500;0,600;1,300;1,400&display=swap');*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}body{background:${B.caviar}}@keyframes fadeUp{from{opacity:0;transform:translateY(14px)}to{opacity:1;transform:translateY(0)}}@keyframes shake{0%,100%{transform:translateX(0)}25%{transform:translateX(-5px)}75%{transform:translateX(5px)}}::selection{background:rgba(233,240,86,0.2)}::placeholder{color:${B.sageDim}}`}</style>
      <nav style={{ display: "flex", justifyContent: "space-between", alignItems: "center", padding: "22px 36px", flexWrap: "wrap", gap: 12 }}>
        <a href="https://www.maysoonsalah.com" style={{ fontFamily: sf, fontSize: 18, fontWeight: 600, color: B.sage, textDecoration: "none" }}>Maysoon Salah.</a>
        <div style={{ display: "flex", gap: 28, alignItems: "center", flexWrap: "wrap" }}>
          {["Real Estate","Design","Ventures","Contact"].map(n => (<a key={n} href={`https://www.maysoonsalah.com/#${n.toLowerCase().replace(/ /g,"-")}`} style={{ fontSize: 13, color: B.sageMuted, textDecoration: "none", letterSpacing: .5, transition: "opacity .25s", opacity: hov === n ? .5 : 1 }} onMouseEnter={() => setHov(n)} onMouseLeave={() => setHov(null)}>{n}</a>))}
          <span style={{ fontSize: 13, color: B.wasabi, fontWeight: 500, letterSpacing: .5, borderBottom: `1px solid ${B.wasabi}`, paddingBottom: 2 }}>Economic Briefing</span>
        </div>
      </nav>
      <main style={{ flex: 1, display: "flex", alignItems: "center", justifyContent: "center", padding: "20px 36px 60px" }}>
        <div style={{ maxWidth: 520, width: "100%", animation: shake ? "shake .5s ease" : "fadeUp .8s cubic-bezier(.22,1,.36,1)" }}>
          <span style={{ fontSize: 11, letterSpacing: 4, textTransform: "uppercase", color: B.sageMuted, fontWeight: 500, display: "block", marginBottom: 20 }}>Private Report · {D.meta.date}</span>
          <h1 style={{ fontFamily: sf, fontSize: 56, fontWeight: 500, color: B.sage, lineHeight: 1.04, marginBottom: 8, letterSpacing: -1 }}>Economic<br /><em style={{ fontWeight: 400, color: B.wasabi }}>Briefing</em></h1>
          <p style={{ fontFamily: sf, fontSize: 17, color: B.sageMuted, fontStyle: "italic", marginBottom: 28 }}>Recession indicators · Crypto & digital assets · Oil & energy · Precious metals · AI & tech · SE Florida real estate · Investment positioning</p>
          <div style={{ width: 48, height: 1, background: B.aborder, marginBottom: 28 }} />
          <p style={{ fontSize: 14.5, color: B.sageMuted, lineHeight: 1.75, fontWeight: 300, marginBottom: 36, maxWidth: 440 }}>A curated intelligence report tracking the economic signals that matter — updated regularly with AI-assisted analysis.</p>
          {mode === "request" && !done && (<div>
            <label style={gi.label}>Request Access</label>
            <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 10, marginBottom: 10 }}>
              <input placeholder="First name *" value={form.first} onChange={e => setForm({...form, first: e.target.value})} style={gi.input} />
              <input placeholder="Last name *" value={form.last} onChange={e => setForm({...form, last: e.target.value})} style={gi.input} />
            </div>
            <input placeholder="Email address *" value={form.email} onChange={e => setForm({...form, email: e.target.value})} style={{...gi.input, marginBottom: 10, width: "100%"}} />
            <input placeholder="Phone (optional)" value={form.phone} onChange={e => setForm({...form, phone: e.target.value})} style={{...gi.input, marginBottom: 16, width: "100%"}} />
            <button onClick={request} style={gi.btn}>Request Access</button>
            <p style={gi.toggle} onClick={() => setMode("login")}>Already have an access code? <span style={{ color: B.wasabi, cursor: "pointer", borderBottom: `1px solid ${B.aborder}` }}>Log in</span></p>
          </div>)}
          {mode === "request" && done && (<div style={{ background: B.glow, border: `1px solid ${B.aborder}`, padding: 24, animation: "fadeUp .5s ease" }}>
            <p style={{ fontSize: 16, fontWeight: 500, color: B.sage, marginBottom: 8 }}>Request received.</p>
            <p style={{ fontSize: 14, color: B.sageMuted, lineHeight: 1.7, fontWeight: 300 }}>Your access code will be sent shortly.</p>
            <p style={{...gi.toggle, marginTop: 16}} onClick={() => setMode("login")}><span style={{ color: B.wasabi, cursor: "pointer", borderBottom: `1px solid ${B.aborder}` }}>Log in with access code →</span></p>
          </div>)}
          {mode === "login" && (<div>
            <label style={gi.label}>Access Code</label>
            <div style={{ display: "flex" }}>
              <input ref={ref} type="password" value={pw} onChange={e => { setPw(e.target.value); setErr(false); }} onKeyDown={e => e.key === "Enter" && login()} placeholder="Enter code" style={{...gi.input, flex: 1, borderRight: "none"}} />
              <button onClick={login} style={gi.btnInline}>Enter</button>
            </div>
            {err && <p style={{ color: "#b5706b", fontSize: 12, marginTop: 10 }}>Invalid access code</p>}
            <p style={gi.toggle} onClick={() => setMode("request")}>Need access? <span style={{ color: B.wasabi, cursor: "pointer", borderBottom: `1px solid ${B.aborder}` }}>Request it here</span></p>
          </div>)}
        </div>
      </main>
      <div style={{ display: "flex", justifyContent: "space-between", padding: "18px 36px", fontSize: 11, color: B.sageDim, borderTop: `1px solid ${B.border}` }}><span>© 2026 Maysoon Salah</span><span style={{ fontStyle: "italic" }}>Real Estate + Design + AI</span></div>
    </div>
  );
}
const gi = {
  label: { fontSize: 10, letterSpacing: 2.5, textTransform: "uppercase", color: B.sageMuted, fontWeight: 500, marginBottom: 10, display: "block" },
  input: { background: B.surface, border: `1px solid ${B.border}`, padding: "14px 18px", fontSize: 14, fontFamily: sn, fontWeight: 300, color: B.sage, letterSpacing: .5, outline: "none", width: "100%" },
  btn: { width: "100%", background: B.wasabi, border: "none", padding: "15px 32px", fontSize: 13, fontFamily: sn, fontWeight: 600, color: B.caviar, letterSpacing: 1.5, cursor: "pointer", textTransform: "uppercase" },
  btnInline: { background: B.wasabi, border: `1px solid ${B.wasabi}`, padding: "14px 28px", fontSize: 12, fontFamily: sn, fontWeight: 600, color: B.caviar, letterSpacing: 1.5, cursor: "pointer", textTransform: "uppercase" },
  toggle: { fontSize: 13, color: B.sageDim, fontWeight: 300, marginTop: 16 },
};
// ═══════════════════════════════════════════════════
// REPORT PRIMITIVES
// ═══════════════════════════════════════════════════
const SH = ({ ch, t, badge, bc }) => (<div style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline", marginBottom: 24, flexWrap: "wrap", gap: 10 }}><div style={{ display: "flex", alignItems: "baseline", gap: 14 }}>{ch && <span style={{ fontFamily: sf, fontSize: 14, color: wh, letterSpacing: 1 }}>{ch}</span>}<h2 style={{ fontFamily: sf, fontSize: 30, fontWeight: 400, color: ink, fontStyle: "italic" }}>{t}</h2></div>{badge && <span style={{ fontSize: 10.5, fontWeight: 500, padding: "5px 16px", letterSpacing: 1.5, textTransform: "uppercase", background: bc || amber, color: cream }}>{badge}</span>}</div>);
const Dot = ({ s }) => <span style={{ width: 8, height: 8, borderRadius: "50%", background: dc(s), display: "inline-block", flexShrink: 0 }} />;
const Fact = ({ children }) => <p style={{ fontSize: 14.5, lineHeight: 1.75, fontWeight: 300, display: "flex", gap: 10, alignItems: "flex-start", marginBottom: 4, color: ink }}><span style={{ color: wh }}>—</span><span>{children}</span></p>;
const Move = ({ children }) => <p style={{ fontSize: 14.5, lineHeight: 1.85, fontWeight: 300, color: ink }}>→ {children}</p>;
const Sub = ({ children }) => <h3 style={{ fontFamily: sf, fontSize: 19, fontWeight: 400, fontStyle: "italic", marginBottom: 14, color: ink }}>{children}</h3>;
const Bdy = ({ children, sx }) => <p style={{ fontSize: 14, color: mt, lineHeight: 1.75, fontWeight: 300, ...sx }}>{children}</p>;
const Sec = ({ children }) => <section style={{ marginBottom: 48, paddingBottom: 48, borderBottom: `1px solid ${rl}` }}>{children}</section>;
const TH = ({ children }) => <th style={{ textAlign: "left", padding: "11px 14px", borderBottom: `1px solid ${ink}`, color: mt, fontSize: 9.5, fontWeight: 500, letterSpacing: 2.5, textTransform: "uppercase", whiteSpace: "nowrap" }}>{children}</th>;
const TD = ({ children, sx }) => <td style={{ padding: "13px 14px", borderBottom: "1px solid #ebe7e1", fontSize: 13.5, fontWeight: 300, color: ink, ...sx }}>{children}</td>;
// ═══════════════════════════════════════════════════
// OVERVIEW — Always visible above tabs
// ═══════════════════════════════════════════════════
function Overview() {
  const o = D.overview;
  return (
    <div style={{ marginBottom: 40 }}>
      {/* Key numbers strip */}
      <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fit, minmax(120px, 1fr))", gap: 16, marginBottom: 32, padding: "24px 0", borderBottom: `1px solid ${rl}`, borderTop: `1px solid ${rl}` }}>
        {o.keyNumbers.map((k, i) => (
          <div key={i} style={{ display: "flex", flexDirection: "column", gap: 3 }}>
            <span style={{ fontSize: 10, color: mt, textTransform: "uppercase", letterSpacing: 2, fontWeight: 500 }}>{k.label}</span>
            <span style={{ fontSize: 22, fontFamily: sf, fontWeight: 500, color: ink }}>{k.value}</span>
            <span style={{ fontSize: 12, color: k.color, fontWeight: 500 }}>{k.delta}</span>
          </div>
        ))}
      </div>
      {/* Narrative essay */}
      <div style={{ marginBottom: 32 }}>
        <h2 style={{ fontFamily: sf, fontSize: 34, fontWeight: 400, color: ink, fontStyle: "italic", marginBottom: 20, lineHeight: 1.15 }}>{o.headline}</h2>
        {o.narrative.map((p, i) => (
          <p key={i} style={{ fontSize: 15, color: ink, lineHeight: 1.85, fontWeight: 300, marginBottom: 16, maxWidth: 720 }}>{p}</p>
        ))}
      </div>
      {/* War status */}
      <div style={{ background: alt, padding: 24, marginBottom: 0 }}>
        <div style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline", marginBottom: 16, flexWrap: "wrap", gap: 8 }}>
          <h3 style={{ fontFamily: sf, fontSize: 20, fontWeight: 400, fontStyle: "italic", color: ink }}>Iran Conflict — Day {o.warStatus.day}</h3>
          <span style={{ fontSize: 10.5, fontWeight: 500, padding: "5px 16px", letterSpacing: 1.5, textTransform: "uppercase", background: rose, color: cream }}>{o.warStatus.status}</span>
        </div>
        {o.warStatus.items.map((f, i) => <Fact key={i}>{f}</Fact>)}
      </div>
    </div>
  );
}
// ═══════════════════════════════════════════════════
// TAB SECTIONS
// ═══════════════════════════════════════════════════
function MacroTab() {
  const d = D.recProb; const c = d.pct < 20 ? sage : d.pct < 35 ? amber : rose;
  return (<Sec>
    <SH ch="01" t="Recession Probability" badge={d.label} bc={c} />
    <div style={{ display: "flex", alignItems: "center", gap: 24, marginBottom: 28 }}>
      <span style={{ fontSize: 56, fontFamily: sf, fontWeight: 400, color: c, minWidth: 86, letterSpacing: -2 }}>{d.pct}%</span>
      <div style={{ flex: 1, height: 3, background: "#e0dbd4", overflow: "hidden" }}><div style={{ height: "100%", width: `${d.pct}%`, background: c, transition: "width 1.4s ease-out" }} /></div>
    </div>
    <div style={{ display: "flex", gap: 28, flexWrap: "wrap", marginBottom: 20 }}>
      {d.sources.map((s, i) => (<div key={i} style={{ display: "flex", flexDirection: "column", gap: 3 }}><span style={{ fontSize: 24, fontFamily: sf, fontWeight: 500 }}>{s.v}%</span><span style={{ fontSize: 12, color: mt }}>{s.n}</span><span style={{ fontSize: 11, color: wh }}>{s.d}</span></div>))}
    </div>
    <Bdy>{d.body}</Bdy>
    <div style={{ marginTop: 32 }}><SH ch="02" t="Macro Dashboard" />
      <div style={{ overflowX: "auto", marginBottom: 18 }}><table style={{ width: "100%", borderCollapse: "collapse" }}>
        <thead><tr><TH>Indicator</TH><TH>Value</TH><TH>Trend</TH><TH /><TH>Note</TH></tr></thead>
        <tbody>{D.macro.map((r, i) => (<tr key={i} style={i%2===0?{background:alt}:{}}><TD>{r.name}</TD><TD sx={{fontWeight:500,whiteSpace:"nowrap"}}>{r.val}</TD><TD sx={{textAlign:"center",fontSize:16}}>{r.trend}</TD><TD sx={{textAlign:"center"}}><Dot s={r.sig}/></TD><TD sx={{color:mt}}>{r.note}</TD></tr>))}</tbody>
      </table></div>
      <div style={{display:"flex",gap:22}}>{[["pos","Favorable"],["n","Mixed"],["neg","Unfavorable"]].map(([s,l])=>(<span key={s} style={{fontSize:11,color:mt,display:"flex",alignItems:"center",gap:6}}><Dot s={s}/>{l}</span>))}</div>
    </div>
  </Sec>);
}
function CryptoTab() {
  const d = D.crypto;
  return (<Sec>
    <SH ch="03" t="Crypto & Digital Assets" badge={`Fear & Greed: ${d.fg} — ${d.fgLabel}`} bc={d.fg<25?rose:amber} />
    <Bdy sx={{marginBottom:28}}>{d.fgDays} consecutive days in extreme fear — the longest stretch since the FTX collapse in November 2022.</Bdy>
    <div style={{display:"grid",gridTemplateColumns:"repeat(auto-fit,minmax(270px,1fr))",gap:18,marginBottom:28}}>
      {d.coins.map((c,i)=>(<div key={i} style={{background:"#fff",border:`1px solid ${rl}`,padding:22}}>
        <div style={{display:"flex",justifyContent:"space-between",marginBottom:6}}><span style={{fontFamily:sf,fontSize:19,fontWeight:500}}>{c.name}</span><span style={{fontSize:13,fontWeight:500,color:c.chg<0?rose:sage}}>{c.chg>0?"+":""}{c.chg}%</span></div>
        <div style={{fontSize:34,fontFamily:sf,fontWeight:400,marginBottom:10,letterSpacing:-1}}>{$(c.price)}</div>
        <div style={{display:"flex",justifyContent:"space-between",fontSize:12,color:mt,marginBottom:14}}><span>ATH {$(c.ath)}</span><span style={{color:rose}}>{c.dd}%</span></div>
        <div style={{height:1,background:rl,marginBottom:14}}/>
        <div style={{fontSize:13.5,lineHeight:1.65,fontWeight:300}}><p><em style={{fontFamily:sf,fontWeight:500,fontStyle:"italic",color:mt,fontSize:14.5,marginRight:5}}>Near-term:</em>{c.short}</p><p style={{marginTop:8}}><em style={{fontFamily:sf,fontWeight:500,fontStyle:"italic",color:mt,fontSize:14.5,marginRight:5}}>Long-term:</em>{c.long}</p></div>
      </div>))}
    </div>
    <div style={{marginBottom:20}}><Sub>Key Events</Sub>{d.events.map((e,i)=><Fact key={i}>{e}</Fact>)}</div>
    <div style={{background:alt,padding:22}}><Sub>Recommended Moves</Sub>{d.moves.map((m,i)=><Move key={i}>{m}</Move>)}</div>
  </Sec>);
}
function OilEnergyTab() {
  const d = D.commodities;
  return (<Sec>
    <SH ch="04" t="Oil & Energy" badge="Iran War Impact" bc={rose} />
    <Bdy sx={{marginBottom:28}}>{d.narrative}</Bdy>
    {d.assets.map((a,i)=>(<div key={i} style={{background:i%2===0?"#fff":alt,border:`1px solid ${rl}`,padding:22,marginBottom:12}}>
      <div style={{display:"flex",justifyContent:"space-between",alignItems:"baseline",marginBottom:8,flexWrap:"wrap",gap:8}}>
        <span style={{fontFamily:sf,fontSize:19,fontWeight:500}}>{a.name}</span>
        <div style={{display:"flex",gap:16,alignItems:"baseline"}}>
          <span style={{fontSize:22,fontFamily:sf,fontWeight:500}}>{a.price}</span>
          <span style={{fontSize:13,fontWeight:500,color:a.chg.startsWith("+")?rose:a.chg.startsWith("−")?sage:mt}}>{a.chg}</span>
          <Dot s={a.sig}/>
        </div>
      </div>
      <Bdy sx={{marginBottom:8}}>{a.context}</Bdy>
      <p style={{fontSize:13,lineHeight:1.65,fontWeight:400,color:ink}}><em style={{fontFamily:sf,fontWeight:500,fontStyle:"italic",color:mt,fontSize:14.5,marginRight:5}}>Why it matters:</em>{a.why}</p>
    </div>))}
    <div style={{marginTop:28}}><Sub>Oil Price Scenarios</Sub>
      <div style={{display:"grid",gridTemplateColumns:"repeat(auto-fit,minmax(220px,1fr))",gap:16}}>
        {d.oilScenarios.map((s,i)=>{
          const c = i===0?sage:i===1?amber:rose;
          return (<div key={i} style={{background:"#fff",border:`1px solid ${rl}`,padding:20,borderTop:`3px solid ${c}`}}>
            <span style={{fontSize:10,textTransform:"uppercase",letterSpacing:2,color:c,fontWeight:500,display:"block",marginBottom:8}}>{s.scenario}</span>
            <span style={{fontSize:22,fontFamily:sf,fontWeight:500,display:"block",marginBottom:8}}>{s.oil}</span>
            <Bdy>{s.impact}</Bdy>
          </div>);
        })}
      </div>
    </div>
    <div style={{background:alt,padding:22,marginTop:28}}><Sub>Recommended Moves</Sub>{d.moves.map((m,i)=><Move key={i}>{m}</Move>)}</div>
  </Sec>);
}
function MetalsTab() {
  const d = D.metals;
  return (<Sec>
    <SH ch="05" t="Precious Metals" badge="Crisis Hedge" bc={amber} />
    <Bdy sx={{marginBottom:28}}>{d.narrative}</Bdy>
    {d.assets.map((a,i)=>(<div key={i} style={{background:"#fff",border:`1px solid ${rl}`,padding:22,marginBottom:12}}>
      <div style={{display:"flex",justifyContent:"space-between",alignItems:"baseline",marginBottom:8,flexWrap:"wrap",gap:8}}>
        <span style={{fontFamily:sf,fontSize:19,fontWeight:500}}>{a.name}</span>
        <div style={{display:"flex",gap:16,alignItems:"baseline"}}>
          <span style={{fontSize:22,fontFamily:sf,fontWeight:500}}>{a.price}</span>
          <span style={{fontSize:13,fontWeight:500,color:a.chg.startsWith("+")?sage:a.chg.startsWith("−")?rose:mt}}>{a.chg}</span>
          <Dot s={a.sig}/>
        </div>
      </div>
      <Bdy sx={{marginBottom:8}}>{a.context}</Bdy>
      <p style={{fontSize:13,lineHeight:1.65,fontWeight:400,color:ink}}><em style={{fontFamily:sf,fontWeight:500,fontStyle:"italic",color:mt,fontSize:14.5,marginRight:5}}>Why it matters:</em>{a.why}</p>
    </div>))}
    <div style={{background:alt,padding:22,marginTop:20,marginBottom:20}}>
      <Sub>Central Bank Buying</Sub>
      <Bdy>{d.centralBanks}</Bdy>
    </div>
    <div style={{background:alt,padding:22}}><Sub>Recommended Moves</Sub>{d.moves.map((m,i)=><Move key={i}>{m}</Move>)}</div>
  </Sec>);
}
function AITechTab({ isPriv }) {
  const d = D.aiTech;
  return (<Sec>
    <SH ch="06" t="AI & Tech" badge="Structural Growth" bc={sage} />
    <Bdy sx={{marginBottom:28}}>{d.narrative}</Bdy>
    <Sub>Growth Indicators</Sub>
    {d.indicators.map((ind,i)=>(<div key={i} style={{display:"flex",gap:14,padding:"14px 0",borderBottom:"1px solid #ebe7e1",alignItems:"flex-start"}}>
      <Dot s={ind.sig}/>
      <div style={{flex:1,marginTop:-1}}>
        <div style={{display:"flex",justifyContent:"space-between",flexWrap:"wrap",gap:8}}>
          <span style={{fontSize:14.5,fontWeight:500}}>{ind.name}</span>
          <span style={{fontSize:12,color:dc(ind.sig),fontWeight:500}}>{ind.value}</span>
        </div>
        <Bdy sx={{marginTop:3}}>{ind.detail}</Bdy>
      </div>
    </div>))}
    <div style={{marginTop:28}}><Sub>Key AI Stocks</Sub>
      <div style={{overflowX:"auto",marginBottom:18}}><table style={{width:"100%",borderCollapse:"collapse"}}>
        <thead><tr><TH>Company</TH><TH>Signal</TH><TH>Note</TH></tr></thead>
        <tbody>{d.stocks.map((s,i)=>(<tr key={i} style={i%2===0?{background:alt}:{}}>
          <TD sx={{fontWeight:500}}>{s.name}</TD>
          <TD sx={{fontWeight:500,color:s.signal==="Dominant"||s.signal==="Breakout"?sage:s.signal==="Speculative"?rose:mt}}>{s.signal}</TD>
          <TD sx={{color:mt,fontSize:12.5}}>{s.note}</TD>
        </tr>))}</tbody>
      </table></div></div>
    <div style={{background:alt,padding:22,marginBottom:20}}><Sub>Semiconductor Index</Sub><Bdy>{d.chipIndex}</Bdy></div>
    <div style={{background:alt,padding:22}}><Sub>Recommended Moves</Sub>{d.moves.map((m,i)=><Move key={i}>{m}</Move>)}</div>
    {isPriv && d.passiveIncome && (<div style={{marginTop:32,paddingTop:32,borderTop:`1px solid ${rl}`}}>
      <SH t="AI Passive Income Models" badge="Your Opportunity" bc={amber} />
      <Bdy sx={{marginBottom:24}}>{d.passiveIncome.reality}</Bdy>
      {d.passiveIncome.models.map((m,i)=>(<div key={i} style={{background:"#fff",border:`1px solid ${rl}`,padding:22,marginBottom:12}}>
        <div style={{display:"flex",justifyContent:"space-between",alignItems:"baseline",marginBottom:8,flexWrap:"wrap",gap:8}}>
          <span style={{fontFamily:sf,fontSize:19,fontWeight:500}}>{m.name}</span>
          <span style={{fontSize:12,color:sage,fontWeight:500}}>{m.potential}</span>
        </div>
        <Bdy sx={{marginBottom:8}}>{m.desc}</Bdy>
        <span style={{fontSize:12,color:wh,fontStyle:"italic"}}>Timeline: {m.timeline}</span>
      </div>))}
      <div style={{background:alt,padding:22}}><Sub>Best Fit for You</Sub><p style={{fontSize:15,color:ink,lineHeight:1.8,fontWeight:400}}>{d.passiveIncome.bestFit}</p></div>
    </div>)}
  </Sec>);
}
function RETab({ isPriv }) {
  const {nat:n,subs,local:l,moves,home,privMoves}=D.re;
  return (<Sec>
    <SH ch="07" t="Real Estate" badge={`Buyer Leverage: ${l.lev}/10`} bc={amber} />
    <Sub>National</Sub>
    <div style={{display:"flex",gap:28,flexWrap:"wrap",marginBottom:28}}>
      {[[n.r30,"30-Yr Fixed"],[n.med,"Median Price"],[n.yoy,"YoY"],[`${n.inv} mo`,"Inventory"]].map(([v,lb],i)=>(<div key={i} style={{display:"flex",flexDirection:"column",gap:3}}><span style={{fontSize:21,fontFamily:sf,fontWeight:500}}>{v}</span><span style={{fontSize:10,color:mt,textTransform:"uppercase",letterSpacing:2,fontWeight:500}}>{lb}</span></div>))}
    </div>
    <Sub>Southeast Florida — Price per Square Foot</Sub>
    <div style={{overflowX:"auto",marginBottom:18}}><table style={{width:"100%",borderCollapse:"collapse"}}>
      <thead><tr><TH>County</TH><TH>Area</TH><TH>$/SqFt</TH><TH>Median</TH><TH>YoY</TH><TH>DOM</TH><TH/><TH>Note</TH></tr></thead>
      <tbody>{subs.map((r,i)=>(<tr key={i} style={i%2===0?{background:alt}:{}}><TD sx={{fontWeight:500}}>{r.county}</TD><TD>{r.area}</TD><TD sx={{fontWeight:500}}>{r.sqft}</TD><TD>{r.med}</TD><TD sx={{color:r.yoy.startsWith("+")?sage:r.yoy.startsWith("−")?rose:ink}}>{r.yoy}</TD><TD>{r.dom}</TD><TD sx={{textAlign:"center"}}><Dot s={r.sig}/></TD><TD sx={{color:mt,fontSize:12}}>{r.note}</TD></tr>))}</tbody>
    </table></div>
    <Bdy sx={{fontStyle:"italic",marginBottom:28}}>The Treasure Coast at $214–$277/sqft remains 30–55% below Palm Beach through Miami-Dade — this gap drives northward migration and supports long-term equity growth.</Bdy>
    <Sub>Insurance Cost by County</Sub>
    <div style={{overflowX:"auto",marginBottom:28}}><table style={{width:"100%",borderCollapse:"collapse"}}>
      <thead><tr><TH>County</TH><TH>Avg Annual Premium</TH><TH>City-Level Premiums</TH></tr></thead>
      <tbody>{D.re.insurance.map((r,i)=>(<tr key={i} style={i%2===0?{background:alt}:{}}><TD sx={{fontWeight:500}}>{r.county}</TD><TD>{r.avg}</TD><TD sx={{color:mt,fontSize:12}}>{r.city}</TD></tr>))}</tbody>
    </table></div>
    <Bdy sx={{fontStyle:"italic",marginBottom:28}}>Coastal Broward insurance runs $10K–$11K annually in cities like Fort Lauderdale and Hollywood. The Treasure Coast is generally less extreme but still climbing — this is the biggest hidden cost in Florida real estate.</Bdy>
    <Sub>New Construction — Treasure Coast</Sub>
    <div style={{display:"flex",gap:28,flexWrap:"wrap",marginBottom:12}}>
      {[[D.re.newConstruction.tcMedianSqft,"Median $/SqFt"],[D.re.newConstruction.tcMedianPrice,"Median Price"],[D.re.newConstruction.fpMedianListing,"Fort Pierce Median"],[D.re.newConstruction.fpDom,"Fort Pierce DOM"]].map(([v,lb],i)=>(<div key={i} style={{display:"flex",flexDirection:"column",gap:3}}><span style={{fontSize:21,fontFamily:sf,fontWeight:500}}>{v}</span><span style={{fontSize:10,color:mt,textTransform:"uppercase",letterSpacing:2,fontWeight:500}}>{lb}</span></div>))}
    </div>
    <Fact>Port St. Lucie builders offering up to {D.re.newConstruction.pslConcessions} in concessions with {D.re.newConstruction.pslPromoRate} promotional financing</Fact>
    <Fact>{D.re.newConstruction.trend}</Fact>
    <div style={{marginTop:28}}><Sub>{l.market}</Sub>
      <div style={{display:"flex",gap:28,flexWrap:"wrap",marginBottom:12}}>
        {[[l.range,"Median Range"],[l.yoy,"YoY"],[l.dom,"Days on Market"]].map(([v,lb],i)=>(<div key={i} style={{display:"flex",flexDirection:"column",gap:3}}><span style={{fontSize:21,fontFamily:sf,fontWeight:500}}>{v}</span><span style={{fontSize:10,color:mt,textTransform:"uppercase",letterSpacing:2,fontWeight:500}}>{lb}</span></div>))}
      </div>
      {l.trends.map((t,i)=><Fact key={i}>{t}</Fact>)}
    </div>
    {isPriv&&(<div style={{marginTop:28}}><Sub>Your Home</Sub>
      <div style={{display:"flex",gap:28,flexWrap:"wrap",marginBottom:8}}>
        <div style={{display:"flex",flexDirection:"column",gap:3}}><span style={{fontSize:21,fontFamily:sf,fontWeight:500}}>{$(home.buy)}</span><span style={{fontSize:10,color:mt,textTransform:"uppercase",letterSpacing:2,fontWeight:500}}>Purchased</span></div>
        <div style={{display:"flex",flexDirection:"column",gap:3}}><span style={{fontSize:21,fontFamily:sf,fontWeight:500}}>{$(home.now)}</span><span style={{fontSize:10,color:mt,textTransform:"uppercase",letterSpacing:2,fontWeight:500}}>Current Est.</span></div>
        <div style={{display:"flex",flexDirection:"column",gap:3}}><span style={{fontSize:21,fontFamily:sf,fontWeight:500,color:home.delta<0?rose:sage}}>{home.delta<0?"−":"+"}{$(Math.abs(home.delta))} ({home.pct}%)</span><span style={{fontSize:10,color:mt,textTransform:"uppercase",letterSpacing:2,fontWeight:500}}>Delta</span></div>
      </div><Bdy>Recovery estimate: {home.rec}</Bdy>
    </div>)}
    <div style={{background:alt,padding:22,marginTop:28}}><Sub>Market Observations</Sub>{moves.map((m,i)=><Move key={i}>{m}</Move>)}{isPriv&&privMoves.map((m,i)=><Move key={i}>{m}</Move>)}</div>
  </Sec>);
}
function InvestTab() {
  return (<Sec>
    <SH ch="08" t="Investment Framework" badge="When Cash Frees Up" bc={sage} />
    <Bdy sx={{marginBottom:28}}>{D.invest.summary}</Bdy>
    {D.invest.tiers.map((t,ti)=>(<div key={ti} style={{marginBottom:28}}>
      <div style={{display:"flex",justifyContent:"space-between",alignItems:"baseline",marginBottom:14}}><Sub>{t.name}</Sub><span style={{fontSize:12,color:wh,fontStyle:"italic"}}>{t.alloc}</span></div>
      {t.items.map((it,ii)=>(<div key={ii} style={{display:"flex",gap:14,padding:"14px 0",borderBottom:"1px solid #ebe7e1",alignItems:"flex-start"}}>
        <Dot s={it.s}/><div style={{flex:1,marginTop:-1}}><div style={{display:"flex",justifyContent:"space-between",flexWrap:"wrap",gap:8}}><span style={{fontSize:14.5,fontWeight:500}}>{it.a}</span><span style={{fontSize:12,color:mt}}>{it.t}</span></div><Bdy sx={{marginTop:3}}>{it.w}</Bdy></div>
      </div>))}
    </div>))}
    <div style={{background:alt,padding:22,marginBottom:20}}><Sub>Bitcoin DCA Strategy</Sub><Bdy>{D.invest.dcaNote}</Bdy></div>
    <Bdy sx={{fontStyle:"italic",background:alt,padding:18}}>{D.invest.caveat}</Bdy>
  </Sec>);
}
function PrioTab() {
  const uc=u=>u==="Now"?rose:u==="Once employed"?amber:u==="When cash frees up"?sage:u==="Parallel track"?amber:u==="After priorities 1–2"?sage:mt;
  return (<Sec>
    <SH ch="09" t="Action Priorities" />
    {D.priorities.map((p,i)=>(<div key={i} style={{display:"flex",alignItems:"center",gap:18,padding:"18px 0",borderBottom:"1px solid #ebe7e1"}}>
      <span style={{fontFamily:sf,fontSize:26,color:wh,minWidth:38}}>{String(p.r).padStart(2,"0")}</span>
      <div style={{flex:1}}><span style={{fontSize:15,fontWeight:500,display:"block"}}>{p.act}</span><span style={{fontSize:13,color:mt,fontWeight:300}}>{p.why}</span></div>
      <span style={{fontSize:10.5,fontWeight:500,padding:"5px 14px",border:"1px solid",color:uc(p.urg),borderColor:uc(p.urg)+"55",letterSpacing:1.5,textTransform:"uppercase",whiteSpace:"nowrap"}}>{p.urg}</span>
    </div>))}
  </Sec>);
}
function TrackTab() {
  const logs=getLogs();const reqs=getReqs();
  const g=useMemo(()=>{const m={};logs.forEach(l=>{if(!m[l.name])m[l.name]={c:0,last:l.ts};m[l.name].c++;m[l.name].last=l.ts;});return Object.entries(m).sort((a,b)=>b[1].c-a[1].c);},[logs]);
  return (<section>
    <SH t="Tracking" badge={`${logs.length} logins · ${reqs.length} requests`} bc={mt}/>
    {g.length>0&&(<div style={{marginBottom:24}}><Sub>Login History</Sub><div style={{overflowX:"auto"}}><table style={{width:"100%",borderCollapse:"collapse"}}><thead><tr><TH>Person</TH><TH>Logins</TH><TH>Last Seen</TH></tr></thead><tbody>{g.map(([n,d],i)=>(<tr key={i} style={i%2===0?{background:alt}:{}}><TD sx={{fontWeight:500}}>{n}</TD><TD sx={{fontWeight:500}}>{d.c}</TD><TD sx={{color:mt}}>{ago(d.last)}</TD></tr>))}</tbody></table></div></div>)}
    {reqs.length>0&&(<div style={{marginBottom:24}}><Sub>Access Requests</Sub><div style={{overflowX:"auto"}}><table style={{width:"100%",borderCollapse:"collapse"}}><thead><tr><TH>Name</TH><TH>Email</TH><TH>Phone</TH><TH>Requested</TH></tr></thead><tbody>{reqs.map((r,i)=>(<tr key={i} style={i%2===0?{background:alt}:{}}><TD sx={{fontWeight:500}}>{r.first} {r.last}</TD><TD>{r.email}</TD><TD sx={{color:mt}}>{r.phone||"—"}</TD><TD sx={{color:mt}}>{ago(r.ts)}</TD></tr>))}</tbody></table></div></div>)}
    <Bdy sx={{fontStyle:"italic"}}>Stored in your browser. Upgrade to Supabase for persistence across devices.</Bdy>
  </section>);
}
// ═══════════════════════════════════════════════════
// MAIN APP
// ═══════════════════════════════════════════════════
function App() {
  const [user, setUser] = useState(null);
  const [tab, setTab] = useState("overview");
  const [vis, setVis] = useState(false);
  useEffect(() => { if (user) setTimeout(() => setVis(true), 60); }, [user]);
  if (!user) return <Gate onUnlock={setUser} />;
  const priv = user.role === "private";
  const tabs = [
    { id: "overview", l: "Overview" },
    { id: "macro", l: "Macro & Rates" },
    { id: "crypto", l: "Crypto" },
    { id: "energy", l: "Oil & Energy" },
    { id: "metals", l: "Precious Metals" },
    { id: "ai", l: "AI & Tech" },
    { id: "re", l: "Real Estate" },
    { id: "invest", l: "Investment" },
    ...(priv ? [{ id: "prio", l: "Priorities" }, { id: "track", l: "Tracking" }] : []),
  ];
  return (
    <div style={{ minHeight: "100vh", background: cream, color: ink, fontFamily: sn, padding: "0 28px 60px", maxWidth: 840, margin: "0 auto" }}>
      <style>{`@import url('https://fonts.googleapis.com/css2?family=Cormorant+Garamond:ital,wght@0,400;0,500;0,600;0,700;1,400;1,500&family=DM+Sans:ital,wght@0,300;0,400;0,500;0,600;1,300;1,400&display=swap');*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}body{background:${cream}}@keyframes fadeUp{from{opacity:0;transform:translateY(14px)}to{opacity:1;transform:translateY(0)}}::selection{background:${amber}33}::-webkit-scrollbar{width:5px;height:5px}::-webkit-scrollbar-track{background:transparent}::-webkit-scrollbar-thumb{background:${rl};border-radius:3px}`}</style>
      {/* HEADER */}
      <header style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-end", paddingTop: 44, paddingBottom: 18, flexWrap: "wrap", gap: 16 }}>
        <div>
          <p style={{ fontFamily: sf, fontSize: 13, letterSpacing: 3, color: wh, textTransform: "uppercase", marginBottom: 6 }}>Maysoon Salah</p>
          <h1 style={{ fontFamily: sf, fontSize: 40, fontWeight: 400, lineHeight: 1.08, letterSpacing: -.5 }}>Economic <em style={{ fontWeight: 400 }}>Briefing</em></h1>
          <p style={{ fontFamily: sf, fontSize: 14, color: mt, fontStyle: "italic", marginTop: 6 }}>Recession · Crypto · Oil & Energy · Precious Metals · AI & Tech · Real Estate · Investment</p>
        </div>
        <div style={{ display: "flex", flexDirection: "column", alignItems: "flex-end", gap: 3 }}>
          <span style={{ fontFamily: sf, fontSize: 19, fontWeight: 500 }}>{D.meta.date}</span>
          <span style={{ fontSize: 11, color: mt }}>Updated {ago(D.meta.updated)}</span>
          <span style={{ fontSize: 11, color: wh }}>Viewing as {user.name}</span>
        </div>
      </header>
      <div style={{ height: 1, background: ink, marginBottom: 12 }} />
      {/* TABS */}
      <nav style={{ display: "flex", gap: 0, borderBottom: `1px solid ${rl}`, marginBottom: 24, overflowX: "auto", position: "sticky", top: 0, background: cream, zIndex: 10, paddingTop: 4 }}>
        {tabs.map(t => (
          <button key={t.id} onClick={() => setTab(t.id)} style={{
            background: "none", border: "none",
            borderBottom: `2px solid ${tab === t.id ? ink : "transparent"}`,
            padding: "13px 18px", fontSize: 13, fontFamily: sn,
            fontWeight: tab === t.id ? 500 : 400,
            color: tab === t.id ? ink : mt,
            cursor: "pointer", transition: "all .2s", whiteSpace: "nowrap", letterSpacing: .3,
          }}>{t.l}</button>
        ))}
      </nav>
      {/* CONTENT */}
      <main style={{ animation: vis ? "fadeUp .5s ease .1s both" : "none" }}>
        {tab === "overview" && <Overview />}
        {tab === "macro" && <MacroTab />}
        {tab === "crypto" && <CryptoTab />}
        {tab === "energy" && <OilEnergyTab />}
        {tab === "metals" && <MetalsTab />}
        {tab === "ai" && <AITechTab isPriv={priv} />}
        {tab === "re" && <RETab isPriv={priv} />}
        {tab === "invest" && <InvestTab />}
        {tab === "prio" && priv && <PrioTab />}
        {tab === "track" && priv && <TrackTab />}
      </main>
      {/* FOOTER */}
      <footer style={{ marginTop: 36 }}>
        <div style={{ height: 1, background: ink, marginBottom: 24 }} />
        <div style={{ fontSize: 12.5, color: mt, lineHeight: 1.85, fontWeight: 300, fontStyle: "italic" }}>
          <p>This economic briefing was compiled using Claude (Anthropic) and Perplexity AI for data gathering and analysis. It does not constitute financial, investment, or real estate advice. The information presented reflects publicly available data and AI-assisted interpretation at the time of publication. Always consult a licensed financial advisor, CPA, or attorney before making investment or real estate decisions. Past performance does not guarantee future results.</p>
          <p style={{ marginTop: 14, color: wh }}>Next check-in: {D.meta.next}</p>
        </div>
        <div style={{ display: "flex", justifyContent: "space-between", marginTop: 24, paddingTop: 14, borderTop: "1px solid #e8e4de", fontSize: 11, color: wh }}><span>© 2026 Maysoon Salah</span><span style={{ fontStyle: "italic" }}>Real Estate + Design + AI</span></div>
      </footer>
    </div>
  );
}
ReactDOM.createRoot(document.getElementById('root')).render(<App />);
